Skip to content

Commit cfdcf98

Browse files
authored
temp: stash presence
1 parent 4e54542 commit cfdcf98

File tree

10 files changed

+128
-4
lines changed

10 files changed

+128
-4
lines changed

valentine/assets/css/app.css

+15
Original file line numberDiff line numberDiff line change
@@ -464,4 +464,19 @@ table.summary td.inset {
464464
.tabnav-container .markdown ol,
465465
ul {
466466
padding-left: 1.5rem;
467+
}
468+
469+
.presence-list {
470+
display: inline;
471+
}
472+
473+
.presence-list ul {
474+
list-style: none;
475+
padding: 0;
476+
margin: 0;
477+
}
478+
479+
.presence-list li {
480+
display: inline;
481+
margin-right: 0.5rem;
467482
}

valentine/lib/valentine/application.ex

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ defmodule Valentine.Application do
1212
Valentine.Repo,
1313
{DNSCluster, query: Application.get_env(:valentine, :dns_cluster_query) || :ignore},
1414
{Phoenix.PubSub, name: Valentine.PubSub},
15+
ValentineWeb.Presence,
1516
# Start the Finch HTTP client for sending emails
1617
{Finch, name: Valentine.Finch},
1718
# Start a worker by calling: Valentine.Worker.start_link(arg)

valentine/lib/valentine_web/components/layouts/app.html.heex

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
</.link>
77
</:item>
88
<:item is_full_width />
9+
<:item>
10+
<ValentineWeb.WorkspaceLive.Components.PresenceIndicatorComponent.render presence={
11+
@presence
12+
} />
13+
</:item>
914
<:item>
1015
<.button
1116
is_icon_button

valentine/lib/valentine_web/helpers/auth_helper.ex

+12-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,12 @@ defmodule ValentineWeb.Helpers.AuthHelper do
2727
{:cont, Phoenix.Component.assign(socket, :current_user, user_id)}
2828
end
2929
else
30-
{:cont, Phoenix.Component.assign(socket, :current_user, nil)}
30+
user_id =
31+
Valentine.Cache.get({socket.id, :user_id}) || session["user_id"] || generate_user_id()
32+
33+
Valentine.Cache.put({socket.id, :user_id}, user_id, expire: :timer.hours(48))
34+
35+
{:cont, Phoenix.Component.assign(socket, :current_user, user_id)}
3136
end
3237
end
3338

@@ -41,4 +46,10 @@ defmodule ValentineWeb.Helpers.AuthHelper do
4146
_ -> false
4247
end
4348
end
49+
50+
defp generate_user_id() do
51+
:crypto.strong_rand_bytes(16)
52+
|> Base.encode64()
53+
|> String.trim_trailing("=")
54+
end
4455
end

valentine/lib/valentine_web/helpers/nav_helper.ex

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
defmodule ValentineWeb.Helpers.NavHelper do
22
use ValentineWeb, :live_view
3+
alias ValentineWeb.Presence
34

45
def on_mount(:default, _params, _session, socket) do
56
{:cont,
@@ -8,6 +9,8 @@ defmodule ValentineWeb.Helpers.NavHelper do
89
end
910

1011
defp set_active_module(params, _url, socket) do
12+
workspace_id = Map.get(params, "workspace_id", nil)
13+
1114
active_module =
1215
socket.view
1316
|> to_string()
@@ -17,10 +20,16 @@ defmodule ValentineWeb.Helpers.NavHelper do
1720
[name | _] -> name
1821
end
1922

23+
Presence.track(self(), "valentine:presence", socket.assigns.current_user, %{
24+
action: socket.assigns.live_action,
25+
module: active_module,
26+
workspace_id: workspace_id
27+
})
28+
2029
{:cont,
2130
socket
2231
|> assign(active_module: active_module)
2332
|> assign(active_action: socket.assigns.live_action)
24-
|> assign(:workspace_id, if(params["workspace_id"], do: params["workspace_id"], else: nil))}
33+
|> assign(:workspace_id, workspace_id)}
2534
end
2635
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
defmodule ValentineWeb.Helpers.PresenceHelper do
2+
import Phoenix.LiveView
3+
4+
def on_mount(_name, _params, _session, socket) do
5+
if connected?(socket) do
6+
Phoenix.PubSub.subscribe(Valentine.PubSub, "valentine:presence")
7+
end
8+
9+
{:cont,
10+
socket
11+
|> Phoenix.Component.assign(:presence, Valentine.Cache.get("valentine:presence") || %{})
12+
|> attach_hook(:presence_update, :handle_info, &handle_info/2)}
13+
end
14+
15+
defp handle_info(%{event: "presence_diff"}, socket) do
16+
{:halt,
17+
socket
18+
|> Phoenix.Component.assign(:presence, Valentine.Cache.get("valentine:presence") || %{})}
19+
end
20+
21+
defp handle_info(_, socket), do: {:cont, socket}
22+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
defmodule ValentineWeb.WorkspaceLive.Components.PresenceIndicatorComponent do
2+
use Phoenix.Component
3+
use PrimerLive
4+
5+
attr :presence, :map, default: %{}
6+
7+
def render(assigns) do
8+
~H"""
9+
<div class="presence-list">
10+
<ul>
11+
<%= for {{key, _presence}, index} <- @presence |> Enum.with_index() do %>
12+
<li title={key}>
13+
<.counter style={"color: #{get_colour(index)}; background-color: #{get_colour(index)}"}>
14+
{index}
15+
</.counter>
16+
</li>
17+
<% end %>
18+
</ul>
19+
</div>
20+
"""
21+
end
22+
23+
defp get_colour(index) when index > 8, do: get_colour(index - 9)
24+
defp get_colour(index) do
25+
[
26+
"#2cbe4e",
27+
"#f9826c",
28+
"#fbbc05",
29+
"#f96233",
30+
"#f24e1e",
31+
"#dbab09",
32+
"#b08800",
33+
"#735c0f",
34+
"#3f2c00"
35+
]
36+
|> Enum.at(index)
37+
end
38+
end
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
defmodule ValentineWeb.Presence do
2+
use Phoenix.Presence,
3+
otp_app: :my_app,
4+
pubsub_server: Valentine.PubSub
5+
6+
def init(_opts) do
7+
# user-land state
8+
{:ok, %{}}
9+
end
10+
11+
def handle_metas(_topic, %{joins: joins, leaves: leaves}, _presences, state) do
12+
presence =
13+
(Valentine.Cache.get("valentine:presence") || %{})
14+
|> Map.merge(joins)
15+
|> Map.drop(Map.keys(leaves))
16+
17+
Valentine.Cache.put("valentine:presence", presence)
18+
{:ok, state}
19+
end
20+
end

valentine/lib/valentine_web/router.ex

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ defmodule ValentineWeb.Router do
5353
ValentineWeb.Helpers.FlashHelper,
5454
ValentineWeb.Helpers.LocaleHelper,
5555
ValentineWeb.Helpers.NavHelper,
56+
ValentineWeb.Helpers.PresenceHelper,
5657
ValentineWeb.Helpers.ThemeHelper
5758
] do
5859
live "/workspaces", WorkspaceLive.Index, :index

valentine/test/valentine_web/helpers/auth_helper_test.exs

+4-2
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,15 @@ defmodule ValentineWeb.Helpers.AuthHelperTest do
7474
end
7575

7676
describe "on_mount/4" do
77-
test "sets the current_user to nil if GOOGLE env variables are not set", %{socket: socket} do
77+
test "sets the current_user to a random ID if GOOGLE env variables are not set", %{
78+
socket: socket
79+
} do
7880
System.put_env("GOOGLE_CLIENT_ID", "")
7981
System.put_env("GOOGLE_CLIENT_SECRET", "")
8082

8183
{:cont, socket} = AuthHelper.on_mount(:default, %{}, %{}, socket)
8284

83-
assert socket.assigns[:current_user] == nil
85+
assert socket.assigns[:current_user] != nil
8486
end
8587

8688
test "halts and redirects to / if user_id is nil", %{socket: socket} do

0 commit comments

Comments
 (0)