80 lines
2.7 kB
1
defmodule BlogWeb.PostLive.Index do
2
use BlogWeb, :live_view
3
alias BlogWeb.Presence
4
alias Blog.Content
5
6
@presence_topic "blog_presence"
7
8
# TODO add meta tags
9
def mount(_params, _session, socket) do
10
if connected?(socket) do
11
reader_id = "reader_#{:crypto.strong_rand_bytes(8) |> Base.encode16()}"
12
13
{:ok, _} = Presence.track(self(), @presence_topic, reader_id, %{
14
page: "index",
15
joined_at: DateTime.utc_now()
16
})
17
18
Phoenix.PubSub.subscribe(Blog.PubSub, @presence_topic)
19
end
20
21
posts = Blog.Content.Post.all()
22
%{tech: tech_posts, non_tech: non_tech_posts} = Content.categorize_posts(posts)
23
total_readers = Presence.list(@presence_topic) |> map_size()
24
25
{:ok, assign(socket,
26
tech_posts: tech_posts,
27
non_tech_posts: non_tech_posts,
28
total_readers: total_readers
29
)}
30
end
31
32
def handle_info(%{event: "presence_diff"}, socket) do
33
total_readers = Presence.list(@presence_topic) |> map_size()
34
{:noreply, assign(socket, total_readers: total_readers)}
35
end
36
37
def render(assigns) do
38
~H"""
39
<div class="px-8 py-12">
40
<div class="max-w-7xl mx-auto">
41
<div class="mb-4 text-sm text-gray-500">
42
<%= @total_readers %> <%= if @total_readers == 1, do: "person", else: "people" %> browsing the blog
43
</div>
44
45
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
46
<%!-- Tech Posts Column --%>
47
<div>
48
<h2 class="text-2xl font-bold mb-6 pb-2 border-b">Tech & Programming</h2>
49
<div class="space-y-6">
50
<div :for={post <- @tech_posts} class="mb-8">
51
<.link navigate={~p"/post/#{post.slug}"}>
52
<h3 class="text-xl font-bold hover:text-blue-600 transition-colors"><%= post.title %></h3>
53
<p class="text-sm text-gray-600 mt-1">
54
<%= post.tags |> Enum.map(& &1.name) |> Enum.join(", ") %>
55
</p>
56
</.link>
57
</div>
58
</div>
59
</div>
60
61
<%!-- Non-Tech Posts Column --%>
62
<div>
63
<h2 class="text-2xl font-bold mb-6 pb-2 border-b">Life & Everything Else</h2>
64
<div class="space-y-6">
65
<div :for={post <- @non_tech_posts} class="mb-8">
66
<.link navigate={~p"/post/#{post.slug}"}>
67
<h3 class="text-xl font-bold hover:text-blue-600 transition-colors"><%= post.title %></h3>
68
<p class="text-sm text-gray-600 mt-1">
69
<%= post.tags |> Enum.map(& &1.name) |> Enum.join(", ") %>
70
</p>
71
</.link>
72
</div>
73
</div>
74
</div>
75
</div>
76
</div>
77
</div>
78
"""
79
end
80
end
81