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