2022-07-23 01:44:03 +02:00
|
|
|
defmodule ClaperWeb.EventLive.Presenter do
|
|
|
|
|
use ClaperWeb, :live_view
|
|
|
|
|
|
|
|
|
|
alias ClaperWeb.Presence
|
2024-07-11 12:53:47 +02:00
|
|
|
alias Claper.Embeds.Embed
|
|
|
|
|
alias Claper.Polls.Poll
|
|
|
|
|
alias Claper.Forms.Form
|
2022-07-23 01:44:03 +02:00
|
|
|
|
|
|
|
|
@impl true
|
2024-07-11 12:53:47 +02:00
|
|
|
def mount(%{"code" => code} = params, session, socket) do
|
2022-07-23 01:44:03 +02:00
|
|
|
with %{"locale" => locale} <- session do
|
|
|
|
|
Gettext.put_locale(ClaperWeb.Gettext, locale)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
event =
|
|
|
|
|
Claper.Events.get_event_with_code(code, [
|
|
|
|
|
:user,
|
|
|
|
|
presentation_file: [:polls, :presentation_state]
|
|
|
|
|
])
|
|
|
|
|
|
2024-07-11 16:33:02 +02:00
|
|
|
if is_nil(event) || not leader?(socket, event) do
|
2022-07-23 01:44:03 +02:00
|
|
|
{:ok,
|
|
|
|
|
socket
|
2024-04-06 17:39:42 +02:00
|
|
|
|> put_flash(:error, gettext("Event doesn't exist"))
|
2022-07-23 01:44:03 +02:00
|
|
|
|> redirect(to: "/")}
|
|
|
|
|
else
|
|
|
|
|
if connected?(socket) do
|
|
|
|
|
Claper.Events.Event.subscribe(event.uuid)
|
|
|
|
|
Claper.Presentations.subscribe(event.presentation_file.id)
|
|
|
|
|
|
|
|
|
|
Presence.track(
|
|
|
|
|
self(),
|
|
|
|
|
"event:#{event.uuid}",
|
|
|
|
|
socket.assigns.current_user.id,
|
|
|
|
|
%{}
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
2024-04-18 21:47:02 +02:00
|
|
|
endpoint_config = Application.get_env(:claper, ClaperWeb.Endpoint)[:url]
|
|
|
|
|
port = endpoint_config[:port]
|
|
|
|
|
scheme = endpoint_config[:scheme]
|
|
|
|
|
host = endpoint_config[:host]
|
|
|
|
|
path = endpoint_config[:path]
|
|
|
|
|
|
|
|
|
|
default_ports = [80, 443]
|
|
|
|
|
port_suffix = if port in default_ports, do: "", else: ":" <> Integer.to_string(port)
|
|
|
|
|
|
|
|
|
|
host = "#{scheme}://#{host}#{port_suffix}/#{path}"
|
2023-08-10 20:39:38 +02:00
|
|
|
|
2022-07-23 01:44:03 +02:00
|
|
|
socket =
|
|
|
|
|
socket
|
|
|
|
|
|> assign(:attendees_nb, 1)
|
2024-04-18 21:47:02 +02:00
|
|
|
|> assign(
|
|
|
|
|
:host,
|
|
|
|
|
host
|
|
|
|
|
)
|
2022-07-23 01:44:03 +02:00
|
|
|
|> assign(:event, event)
|
2024-07-11 12:53:47 +02:00
|
|
|
|> assign(:iframe, !is_nil(params["iframe"]))
|
2022-07-23 01:44:03 +02:00
|
|
|
|> assign(:state, event.presentation_file.presentation_state)
|
|
|
|
|
|> assign(:posts, list_posts(socket, event.uuid))
|
2023-11-23 13:58:44 +01:00
|
|
|
|> assign(:pinned_posts, list_pinned_posts(socket, event.uuid))
|
|
|
|
|
|> assign(:show_only_pinned, event.presentation_file.presentation_state.show_only_pinned)
|
2022-07-23 01:44:03 +02:00
|
|
|
|> assign(:reacts, [])
|
|
|
|
|
|> poll_at_position
|
2023-10-07 12:57:46 +02:00
|
|
|
|> form_at_position
|
2023-11-23 16:36:39 +05:30
|
|
|
|> embed_at_position
|
2022-07-23 01:44:03 +02:00
|
|
|
|
2023-11-23 13:58:44 +01:00
|
|
|
{:ok, socket, temporary_assigns: []}
|
2022-07-23 01:44:03 +02:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2023-11-23 13:58:44 +01:00
|
|
|
defp update_post_in_list(posts, updated_post) do
|
|
|
|
|
Enum.map(posts, fn post ->
|
|
|
|
|
if post.id == updated_post.id, do: updated_post, else: post
|
|
|
|
|
end)
|
|
|
|
|
end
|
|
|
|
|
|
2024-07-11 16:33:02 +02:00
|
|
|
defp leader?(%{assigns: %{current_user: current_user}} = _socket, event) do
|
|
|
|
|
Claper.Events.leaded_by?(current_user.email, event) || event.user.id == current_user.id
|
2022-07-23 01:44:03 +02:00
|
|
|
end
|
|
|
|
|
|
2024-07-11 16:33:02 +02:00
|
|
|
defp leader?(_socket, _event), do: false
|
2022-07-23 01:44:03 +02:00
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
|
def handle_info(%{event: "presence_diff"}, %{assigns: %{event: event}} = socket) do
|
|
|
|
|
attendees = Presence.list("event:#{event.uuid}")
|
|
|
|
|
{:noreply, assign(socket, :attendees_nb, Enum.count(attendees))}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
|
def handle_info({:post_created, post}, socket) do
|
|
|
|
|
{:noreply,
|
|
|
|
|
socket
|
2023-11-23 14:15:19 +01:00
|
|
|
|> update(:posts, fn posts -> posts ++ [post] end)}
|
2022-07-23 01:44:03 +02:00
|
|
|
end
|
|
|
|
|
|
2023-11-23 13:58:44 +01:00
|
|
|
@impl true
|
|
|
|
|
def handle_info({:post_pinned, post}, socket) do
|
|
|
|
|
{:noreply,
|
|
|
|
|
socket
|
2023-11-23 14:15:19 +01:00
|
|
|
|> update(:pinned_posts, fn pinned_posts -> pinned_posts ++ [post] end)}
|
2023-11-23 13:58:44 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
|
def handle_info({:post_unpinned, post}, socket) do
|
|
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> update(:pinned_posts, fn pinned_posts ->
|
|
|
|
|
Enum.reject(pinned_posts, fn p -> p.id == post.id end)
|
|
|
|
|
end)}
|
|
|
|
|
end
|
|
|
|
|
|
2022-07-23 01:44:03 +02:00
|
|
|
@impl true
|
|
|
|
|
def handle_info({:state_updated, state}, socket) do
|
|
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> assign(:state, state)
|
|
|
|
|
|> push_event("page", %{current_page: state.position})
|
|
|
|
|
|> push_event("reset-global-react", %{})
|
2023-11-23 16:36:39 +05:30
|
|
|
|> poll_at_position
|
|
|
|
|
|> embed_at_position}
|
2022-07-23 01:44:03 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@impl true
|
2023-11-23 13:58:44 +01:00
|
|
|
def handle_info({:post_updated, updated_post}, socket) do
|
|
|
|
|
updated_posts = update_post_in_list(socket.assigns.posts, updated_post)
|
|
|
|
|
updated_pinned_posts = update_post_in_list(socket.assigns.pinned_posts, updated_post)
|
2022-07-23 01:44:03 +02:00
|
|
|
|
2023-11-23 13:58:44 +01:00
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> assign(:posts, updated_posts)
|
|
|
|
|
|> assign(:pinned_posts, updated_pinned_posts)}
|
2022-07-23 01:44:03 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
|
def handle_info({:post_deleted, post}, socket) do
|
2023-11-23 13:58:44 +01:00
|
|
|
updated_posts = Enum.reject(socket.assigns.posts, fn p -> p.id == post.id end)
|
|
|
|
|
updated_pinned_posts = Enum.reject(socket.assigns.pinned_posts, fn p -> p.id == post.id end)
|
|
|
|
|
|
|
|
|
|
{:noreply,
|
|
|
|
|
socket |> assign(:posts, updated_posts) |> assign(:pinned_posts, updated_pinned_posts)}
|
2022-07-23 01:44:03 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
|
def handle_info({:poll_updated, poll}, socket) do
|
2023-11-23 16:36:39 +05:30
|
|
|
if poll.enabled do
|
|
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> update(:current_poll, fn _current_poll -> poll end)}
|
|
|
|
|
else
|
|
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> update(:current_poll, fn _current_poll -> nil end)}
|
|
|
|
|
end
|
2022-07-23 01:44:03 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
|
def handle_info({:poll_deleted, _poll}, socket) do
|
|
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> update(:current_poll, fn _current_poll -> nil end)}
|
|
|
|
|
end
|
|
|
|
|
|
2023-02-26 22:40:34 +01:00
|
|
|
@impl true
|
|
|
|
|
def handle_info({:form_updated, form}, socket) do
|
2023-11-23 16:36:39 +05:30
|
|
|
if form.active do
|
|
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> update(:current_form, fn _current_form -> form end)}
|
|
|
|
|
else
|
|
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> update(:current_form, fn _current_form -> nil end)}
|
|
|
|
|
end
|
2023-02-26 22:40:34 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
|
def handle_info({:form_deleted, _form}, socket) do
|
|
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> update(:current_form, fn _current_form -> nil end)}
|
|
|
|
|
end
|
|
|
|
|
|
2023-11-23 16:36:39 +05:30
|
|
|
@impl true
|
|
|
|
|
def handle_info({:embed_updated, embed}, socket) do
|
2024-06-12 19:45:18 +02:00
|
|
|
if embed.enabled do
|
2023-11-23 16:36:39 +05:30
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> update(:current_embed, fn _current_embed -> embed end)}
|
|
|
|
|
else
|
|
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> update(:current_embed, fn _current_embed -> nil end)}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
|
def handle_info({:embed_deleted, _embed}, socket) do
|
|
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> update(:current_embed, fn _current_embed -> nil end)}
|
|
|
|
|
end
|
|
|
|
|
|
2022-07-23 01:44:03 +02:00
|
|
|
@impl true
|
|
|
|
|
def handle_info({:chat_visible, value}, socket) do
|
|
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> push_event("chat-visible", %{value: value})
|
|
|
|
|
|> update(:chat_visible, fn _chat_visible -> value end)}
|
|
|
|
|
end
|
|
|
|
|
|
2023-11-23 13:58:44 +01:00
|
|
|
@impl true
|
|
|
|
|
def handle_info({:show_only_pinned, value}, socket) do
|
|
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> push_event("show_only_pinned", %{value: value})
|
|
|
|
|
|> update(:show_only_pinned, fn _show_only_pinned -> value end)}
|
|
|
|
|
end
|
|
|
|
|
|
2022-07-23 01:44:03 +02:00
|
|
|
@impl true
|
|
|
|
|
def handle_info({:poll_visible, value}, socket) do
|
|
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> push_event("poll-visible", %{value: value})
|
|
|
|
|
|> update(:poll_visible, fn _poll_visible -> value end)}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
|
def handle_info({:join_screen_visible, value}, socket) do
|
|
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> push_event("join-screen-visible", %{value: value})
|
|
|
|
|
|> update(:join_screen_visible, fn _join_screen_visible -> value end)}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
|
def handle_info({:react, type}, socket) do
|
|
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> push_event("global-react", %{type: type})}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
|
def handle_info(
|
2024-07-11 12:53:47 +02:00
|
|
|
{:current_interaction, %Poll{} = interaction},
|
2022-07-23 01:44:03 +02:00
|
|
|
socket
|
|
|
|
|
) do
|
2024-08-11 11:16:34 +02:00
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> assign(:current_poll, interaction)
|
|
|
|
|
|> assign(:current_embed, nil)
|
|
|
|
|
|> assign(:current_form, nil)}
|
2022-07-23 01:44:03 +02:00
|
|
|
end
|
|
|
|
|
|
2023-02-26 22:40:34 +01:00
|
|
|
@impl true
|
|
|
|
|
def handle_info(
|
2024-07-11 12:53:47 +02:00
|
|
|
{:current_interaction, %Embed{} = interaction},
|
2023-02-26 22:40:34 +01:00
|
|
|
socket
|
|
|
|
|
) do
|
2024-08-11 11:16:34 +02:00
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> assign(:current_embed, interaction)
|
|
|
|
|
|> assign(:current_poll, nil)
|
|
|
|
|
|> assign(:current_form, nil)}
|
2023-02-26 22:40:34 +01:00
|
|
|
end
|
|
|
|
|
|
2023-11-23 16:36:39 +05:30
|
|
|
@impl true
|
|
|
|
|
def handle_info(
|
2024-07-11 12:53:47 +02:00
|
|
|
{:current_interaction, %Form{} = interaction},
|
2023-11-23 16:36:39 +05:30
|
|
|
socket
|
|
|
|
|
) do
|
2024-08-11 11:16:34 +02:00
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> assign(:current_form, interaction)
|
|
|
|
|
|> assign(:current_poll, nil)
|
|
|
|
|
|> assign(:current_embed, nil)}
|
2024-07-11 12:53:47 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
|
def handle_info(
|
|
|
|
|
{:current_interaction, nil},
|
|
|
|
|
socket
|
|
|
|
|
) do
|
|
|
|
|
{:noreply,
|
|
|
|
|
socket
|
|
|
|
|
|> assign(:current_poll, nil)
|
|
|
|
|
|> assign(:current_embed, nil)
|
|
|
|
|
|> assign(:current_form, nil)}
|
2023-11-23 16:36:39 +05:30
|
|
|
end
|
|
|
|
|
|
2022-07-23 01:44:03 +02:00
|
|
|
@impl true
|
|
|
|
|
def handle_info(_, socket) do
|
|
|
|
|
{:noreply, socket}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
|
def handle_params(params, _url, socket) do
|
|
|
|
|
{:noreply, apply_action(socket, socket.assigns.live_action, params)}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
defp apply_action(socket, :show, _params) do
|
|
|
|
|
socket
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
defp poll_at_position(%{assigns: %{event: event, state: state}} = socket) do
|
|
|
|
|
with poll <-
|
|
|
|
|
Claper.Polls.get_poll_current_position(
|
|
|
|
|
event.presentation_file.id,
|
|
|
|
|
state.position
|
|
|
|
|
) do
|
|
|
|
|
socket |> assign(:current_poll, poll)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2023-10-07 12:57:46 +02:00
|
|
|
defp form_at_position(%{assigns: %{event: event, state: state}} = socket) do
|
|
|
|
|
with form <-
|
|
|
|
|
Claper.Forms.get_form_current_position(
|
|
|
|
|
event.presentation_file.id,
|
|
|
|
|
state.position
|
|
|
|
|
) do
|
|
|
|
|
socket |> assign(:current_form, form)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2023-11-23 16:36:39 +05:30
|
|
|
defp embed_at_position(%{assigns: %{event: event, state: state}} = socket) do
|
|
|
|
|
with embed <-
|
|
|
|
|
Claper.Embeds.get_embed_current_position(
|
|
|
|
|
event.presentation_file.id,
|
|
|
|
|
state.position
|
|
|
|
|
) do
|
|
|
|
|
socket |> assign(:current_embed, embed)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2022-07-23 01:44:03 +02:00
|
|
|
defp list_posts(_socket, event_id) do
|
|
|
|
|
Claper.Posts.list_posts(event_id, [:event, :reactions])
|
|
|
|
|
end
|
2023-11-23 13:58:44 +01:00
|
|
|
|
|
|
|
|
defp list_pinned_posts(_socket, event_id) do
|
|
|
|
|
Claper.Posts.list_pinned_posts(event_id, [:event, :reactions])
|
|
|
|
|
end
|
2022-07-23 01:44:03 +02:00
|
|
|
end
|