Skip to content

Commit 3b511bc

Browse files
authored
Improve event live listing (#185)
* Expand user events PubSub * Improve updates in events LiveView
1 parent ac6f28f commit 3b511bc

File tree

5 files changed

+126
-48
lines changed

5 files changed

+126
-48
lines changed

lib/claper/events.ex

Lines changed: 90 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@ defmodule Claper.Events do
66
"""
77

88
import Ecto.Query, warn: false
9-
alias Claper.Repo
109

11-
alias Claper.Accounts.User
10+
alias Claper.{Accounts, Presentations, Repo}
1211
alias Claper.Events.{Event, ActivityLeader}
13-
alias Claper.Presentations
1412

1513
@default_page_size 5
1614

@@ -142,7 +140,7 @@ defmodule Claper.Events do
142140
"""
143141
def list_managed_events_by(email, preload \\ []) do
144142
from(a in ActivityLeader,
145-
join: u in Claper.Accounts.User,
143+
join: u in Accounts.User,
146144
on: u.email == a.email,
147145
join: e in Event,
148146
on: e.id == a.event_id,
@@ -169,7 +167,7 @@ defmodule Claper.Events do
169167

170168
query =
171169
from(a in ActivityLeader,
172-
join: u in Claper.Accounts.User,
170+
join: u in Accounts.User,
173171
on: u.email == a.email,
174172
join: e in Event,
175173
on: e.id == a.event_id,
@@ -183,7 +181,7 @@ defmodule Claper.Events do
183181

184182
def count_managed_events_by(email) do
185183
from(a in ActivityLeader,
186-
join: u in Claper.Accounts.User,
184+
join: u in Accounts.User,
187185
on: u.email == a.email,
188186
join: e in Event,
189187
on: e.id == a.event_id,
@@ -264,7 +262,7 @@ defmodule Claper.Events do
264262
a in ActivityLeader,
265263
join: e in Event,
266264
on: e.id == a.event_id,
267-
join: u in User,
265+
join: u in Accounts.User,
268266
on: e.user_id == u.id,
269267
where: e.uuid == ^uuid and (u.id == ^user.id or a.email == ^user.email),
270268
select: e
@@ -331,7 +329,7 @@ defmodule Claper.Events do
331329
"""
332330
def led_by?(email, event) do
333331
from(a in ActivityLeader,
334-
join: u in Claper.Accounts.User,
332+
join: u in Accounts.User,
335333
on: u.email == a.email,
336334
join: e in Event,
337335
on: e.id == a.event_id,
@@ -358,7 +356,10 @@ defmodule Claper.Events do
358356
|> validate_unique_event()
359357
|> case do
360358
{:ok, event} ->
361-
Repo.insert(event, returning: [:uuid])
359+
with {:ok, event} <- Repo.insert(event, returning: [:uuid]) do
360+
broadcast_all_users({:created, event})
361+
{:ok, event}
362+
end
362363

363364
{:error, changeset} ->
364365
{:error, %{changeset | action: :insert}}
@@ -406,7 +407,25 @@ defmodule Claper.Events do
406407
|> validate_unique_event()
407408
|> case do
408409
{:ok, event} ->
409-
Repo.update(event, returning: [:uuid])
410+
with {:ok, event} <- Repo.update(event, returning: [:uuid]) do
411+
broadcast_all_users({:updated, event})
412+
413+
deleted_leaders =
414+
attrs
415+
|> Map.get("leaders", %{})
416+
|> Map.values()
417+
|> Enum.filter(fn
418+
%{"delete" => "true"} -> true
419+
_ -> false
420+
end)
421+
422+
for %{"email" => leader_email} <- deleted_leaders do
423+
leader = Accounts.get_user_by_email(leader_email)
424+
broadcast_user_events(leader.id, {:updated, event})
425+
end
426+
427+
{:ok, event}
428+
end
410429

411430
{:error, changeset} ->
412431
{:error, %{changeset | action: :update}}
@@ -428,7 +447,9 @@ defmodule Claper.Events do
428447
|> Repo.update()
429448
|> case do
430449
{:ok, event} ->
431-
broadcast({:ok, event, event.uuid}, :event_terminated)
450+
broadcast_all_users({:updated, event})
451+
broadcast_event(event.uuid, {:event_terminated, event.uuid})
452+
{:ok, event}
432453

433454
{:error, changeset} ->
434455
{:error, %{changeset | action: :update}}
@@ -594,7 +615,7 @@ defmodule Claper.Events do
594615
|> Map.drop([:id, :inserted_at, :updated_at, :presentation_state])
595616
|> Map.put(:event_id, changes.event.id)
596617

597-
Claper.Presentations.create_presentation_file(attrs)
618+
Presentations.create_presentation_file(attrs)
598619

599620
_ ->
600621
{:ok, nil}
@@ -611,7 +632,7 @@ defmodule Claper.Events do
611632
|> Map.put(:position, 0)
612633
|> Map.put(:banned, [])
613634

614-
Claper.Presentations.create_presentation_state(attrs)
635+
Presentations.create_presentation_state(attrs)
615636

616637
_ ->
617638
{:ok, nil}
@@ -742,7 +763,20 @@ defmodule Claper.Events do
742763
743764
"""
744765
def delete_event(%Event{} = event) do
745-
Repo.delete(event)
766+
leaders =
767+
for %{email: email} <- get_activity_leaders_for_event(event.id) do
768+
Accounts.get_user_by_email(email)
769+
end
770+
771+
with {:ok, event} <- Repo.delete(event) do
772+
broadcast_user_events(event.user_id, {:deleted, event})
773+
774+
for leader <- leaders do
775+
broadcast_user_events(leader.id, {:deleted, event})
776+
end
777+
778+
{:ok, event}
779+
end
746780
end
747781

748782
@doc """
@@ -758,8 +792,6 @@ defmodule Claper.Events do
758792
Event.changeset(event, attrs)
759793
end
760794

761-
alias Claper.Events.ActivityLeader
762-
763795
@doc """
764796
Creates a activity leader.
765797
@@ -805,7 +837,7 @@ defmodule Claper.Events do
805837
"""
806838
def get_activity_leaders_for_event(event_id) do
807839
from(a in ActivityLeader,
808-
left_join: u in Claper.Accounts.User,
840+
left_join: u in Accounts.User,
809841
on: u.email == a.email,
810842
where: a.event_id == ^event_id,
811843
select: %{a | user_id: u.id}
@@ -826,13 +858,47 @@ defmodule Claper.Events do
826858
ActivityLeader.changeset(activity_leader, attrs)
827859
end
828860

829-
defp broadcast({:ok, e, event_uuid}, event) do
830-
Phoenix.PubSub.broadcast(
831-
Claper.PubSub,
832-
"event:#{event_uuid}",
833-
{event, event_uuid}
834-
)
861+
@doc """
862+
Subscribes to an event's public `Phoenix.PubSub` topic.
863+
864+
The broadcasted messages match the pattern:
865+
866+
* {:terminated, event_uuid}
867+
868+
"""
869+
def subscribe_event(event_uuid) when is_binary(event_uuid) do
870+
Phoenix.PubSub.subscribe(Claper.PubSub, "event:#{event_uuid}")
871+
end
835872

836-
{:ok, e}
873+
defp broadcast_event(event_uuid, message) when is_binary(event_uuid) do
874+
Phoenix.PubSub.broadcast(Claper.PubSub, "event:#{event_uuid}", message)
875+
end
876+
877+
@doc """
878+
Subscribes to a user's events private `Phoenix.PubSub` topic.
879+
880+
The broadcasted messages match the pattern:
881+
882+
* {:created, %Event{}}
883+
* {:updated, %Event{}}
884+
* {:deleted, %Event{}}
885+
886+
"""
887+
def subscribe_user_events(user_id) when is_integer(user_id) do
888+
Phoenix.PubSub.subscribe(Claper.PubSub, "user:#{user_id}:events")
889+
end
890+
891+
def broadcast_user_events(user_id, message) when is_integer(user_id) do
892+
Phoenix.PubSub.broadcast(Claper.PubSub, "user:#{user_id}:events", message)
893+
end
894+
895+
defp broadcast_all_users({_type, %Event{} = event} = message, _opts \\ []) do
896+
event = Repo.preload(event, [:leaders])
897+
broadcast_user_events(event.user_id, message)
898+
899+
for %{email: leader_email} <- event.leaders do
900+
leader = Accounts.get_user_by_email(leader_email)
901+
broadcast_user_events(leader.id, message)
902+
end
837903
end
838904
end

lib/claper/events/event.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ defmodule Claper.Events.Event do
9191
change(event, expired_at: expiry)
9292
end
9393

94-
def subscribe(event_id) do
95-
Phoenix.PubSub.subscribe(Claper.PubSub, "event:#{event_id}")
94+
def subscribe(event_uuid) do
95+
Phoenix.PubSub.subscribe(Claper.PubSub, "event:#{event_uuid}")
9696
end
9797

9898
def started?(event) do

lib/claper/tasks/converter.ex

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ defmodule Claper.Tasks.Converter do
44
We use a hash to identify the presentation. A new hash is generated when the conversion is finished and the presentation is being uploaded.
55
"""
66

7+
alias Claper.Events
78
alias ExAws.S3
89
alias Porcelain.Result
910

@@ -19,11 +20,7 @@ defmodule Claper.Tasks.Converter do
1920
"status" => "progress"
2021
})
2122

22-
Phoenix.PubSub.broadcast(
23-
Claper.PubSub,
24-
"events:#{user_id}",
25-
{:presentation_file_process_done, presentation}
26-
)
23+
Events.broadcast_user_events(user_id, {:presentation_file_process_done, presentation})
2724

2825
path =
2926
Path.join([
@@ -167,11 +164,7 @@ defmodule Claper.Tasks.Converter do
167164
}) do
168165
if get_presentation_storage() != "local", do: File.rm_rf!(path)
169166

170-
Phoenix.PubSub.broadcast(
171-
Claper.PubSub,
172-
"events:#{user_id}",
173-
{:presentation_file_process_done, presentation}
174-
)
167+
Events.broadcast_user_events(user_id, {:presentation_file_process_done, presentation})
175168
end
176169
end
177170

@@ -182,11 +175,7 @@ defmodule Claper.Tasks.Converter do
182175
}) do
183176
File.rm_rf!(path)
184177

185-
Phoenix.PubSub.broadcast(
186-
Claper.PubSub,
187-
"events:#{user_id}",
188-
{:presentation_file_process_done, presentation}
189-
)
178+
Events.broadcast_user_events(user_id, {:presentation_file_process_done, presentation})
190179
end
191180
end
192181

lib/claper_web/live/event_live/index.ex

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
defmodule ClaperWeb.EventLive.Index do
22
use ClaperWeb, :live_view
33

4-
alias Claper.Events
4+
alias Claper.{Events, Presentations}
55
alias Claper.Events.Event
66

77
on_mount(ClaperWeb.UserLiveAuth)
@@ -22,7 +22,7 @@ defmodule ClaperWeb.EventLive.Index do
2222
})
2323

2424
if connected?(socket) do
25-
Phoenix.PubSub.subscribe(Claper.PubSub, "events:#{socket.assigns.current_user.id}")
25+
Events.subscribe_user_events(socket.assigns.current_user.id)
2626
end
2727

2828
expired_events_count = Events.count_expired_events(socket.assigns.current_user.id)
@@ -50,11 +50,22 @@ defmodule ClaperWeb.EventLive.Index do
5050
end
5151

5252
@impl true
53-
def handle_info({:presentation_file_process_done, presentation}, socket) do
54-
event = Claper.Events.get_event!(presentation.event.uuid, [:presentation_file])
53+
def handle_info({type, %Events.Event{}}, socket)
54+
when type in [:created, :updated, :deleted] do
55+
{:noreply, refresh_events(socket)}
56+
end
57+
58+
@impl true
59+
def handle_info({type, %Presentations.PresentationFile{}}, socket)
60+
when type in [:presentation_file_process_done] do
61+
{:noreply, refresh_events(socket)}
62+
end
5563

56-
{:noreply,
57-
socket |> assign(:events, [event | socket.assigns.events]) |> put_flash(:info, nil)}
64+
@impl true
65+
def handle_info(message, socket) do
66+
IO.puts("Received unknown message `#{inspect(message)}` in #{__MODULE__} #{inspect(self())}")
67+
68+
{:noreply, socket}
5869
end
5970

6071
@impl true
@@ -245,4 +256,16 @@ defmodule ClaperWeb.EventLive.Index do
245256
if(socket.assigns.page == 1, do: events, else: socket.assigns.events ++ events)
246257
)
247258
end
259+
260+
defp refresh_events(socket) do
261+
expired_events_count = Events.count_expired_events(socket.assigns.current_user.id)
262+
invited_events_count = Events.count_managed_events_by(socket.assigns.current_user.email)
263+
264+
socket
265+
|> assign(:has_expired_events, expired_events_count > 0)
266+
|> assign(:has_invited_events, invited_events_count > 0)
267+
|> assign(:events, [])
268+
|> assign(:page, 1)
269+
|> load_events()
270+
end
248271
end

lib/claper_web/live/event_live/show.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ defmodule ClaperWeb.EventLive.Show do
187187
end
188188

189189
@impl true
190-
def handle_info({:event_terminated, _event}, socket) do
190+
def handle_info({:event_terminated, _event_uuid}, socket) do
191191
{:noreply,
192192
socket
193193
|> put_flash(:error, gettext("This event has been terminated"))

0 commit comments

Comments
 (0)