64 lines
2.2 kB
1
defmodule BlogWeb.VimTweetsLive do
2
use BlogWeb, :live_view
3
import BlogWeb.CoreComponents
4
@meta_attrs [
5
%{name: "title", content: "Browse Bluesky: In Vim Mode!"},
6
%{name: "description", content: "Use j and k to navigate skeets"},
7
%{property: "og:title", content: "Browse Bluesky: In Vim Mode!"},
8
%{property: "og:description", content: "Use j and k to navigate skeets"},
9
%{property: "og:type", content: "website"}
10
]
11
12
@window_size 12
13
def mount(_params, _session, socket) do
14
tweets = Blog.Skeets.Sampler.sample(100) |> Enum.map(& &1.skeet)
15
16
socket = socket
17
|> assign(
18
cursor: 0,
19
tweets: tweets,
20
visible_tweets: Enum.take(tweets, @window_size),
21
page_title: "Thoughts and Tidbits Blog: Bobby Experiment - vim navigation",
22
meta_attrs: @meta_attrs
23
)
24
25
{:ok, socket}
26
end
27
28
def handle_event("keydown", %{"key" => "j"}, socket) do
29
new_cursor = min(socket.assigns.cursor + 1, length(socket.assigns.tweets) - 1)
30
visible_tweets = get_visible_tweets(socket.assigns.tweets, new_cursor)
31
{:noreply, assign(socket, cursor: new_cursor, visible_tweets: visible_tweets)}
32
end
33
34
def handle_event("keydown", %{"key" => "k"}, socket) do
35
new_cursor = max(socket.assigns.cursor - 1, 0)
36
visible_tweets = get_visible_tweets(socket.assigns.tweets, new_cursor)
37
{:noreply, assign(socket, cursor: new_cursor, visible_tweets: visible_tweets)}
38
end
39
40
def handle_event("keydown", _key, socket), do: {:noreply, socket}
41
42
defp get_visible_tweets(tweets, cursor) do
43
start_idx = max(0, cursor - 2)
44
Enum.slice(tweets, start_idx, @window_size)
45
end
46
47
def render(assigns) do
48
~H"""
49
<.head_tags meta_attrs={@meta_attrs} page_title={@page_title} />
50
<div class="mt-4 text-gray-500">
51
Cursor position: <%= @cursor %>
52
</div>
53
<div class="p-4" phx-window-keydown="keydown">
54
<div class="space-y-4">
55
<%= for {tweet, index} <- Enum.with_index(@visible_tweets) do %>
56
<div class={"p-4 border rounded #{if index == 2, do: 'bg-blue-100'}"}>
57
<%= tweet %>
58
</div>
59
<% end %>
60
</div>
61
</div>
62
"""
63
end
64
end
65