1
0
mirror of https://github.com/algora-io/tv.git synced 2024-11-26 01:00:20 +02:00
algora-tv/lib/algora/chat.ex
2024-05-23 14:03:57 +03:00

116 lines
2.9 KiB
Elixir

defmodule Algora.Chat do
@moduledoc """
The Chat context.
"""
import Ecto.Query, warn: false
alias Algora.Library.Video
alias Algora.Accounts.{User, Entity}
alias Algora.{Repo, Accounts}
alias Algora.Chat.{Message, Events}
@pubsub Algora.PubSub
def subscribe_to_room(%Video{} = video) do
Phoenix.PubSub.subscribe(@pubsub, topic(video.id))
end
def list_messages(%Video{} = video) do
# TODO: add limit
from(m in Message,
join: e in Entity,
on: m.entity_id == e.id,
left_join: u in User,
on: m.user_id == u.id,
join: v in Video,
on: m.video_id == v.id,
join: c in User,
on: c.id == v.user_id,
select_merge: %{
platform: e.platform,
sender_handle: coalesce(u.handle, e.handle),
channel_id: c.id
},
where: m.video_id == ^video.id
)
|> order_by_inserted(:asc)
|> Repo.all()
end
defp order_by_inserted(%Ecto.Query{} = query, direction) when direction in [:asc, :desc] do
from(s in query, order_by: [{^direction, s.inserted_at}])
end
def can_delete?(%User{} = user, %Message{} = message) do
user.id == message.channel_id or user.id == message.user_id or Accounts.admin?(user)
end
def get_message!(id) do
from(m in Message,
join: e in Entity,
on: m.entity_id == e.id,
left_join: u in User,
on: m.user_id == u.id,
join: v in Video,
on: m.video_id == v.id,
join: c in User,
on: c.id == v.user_id,
select_merge: %{
platform: e.platform,
sender_handle: coalesce(u.handle, e.handle),
channel_id: c.id
},
where: m.id == ^id
)
|> Repo.one!()
end
def create_message(%User{} = user, %Video{} = video, attrs) do
entity = Accounts.get_or_create_entity!(user)
%Message{}
|> Message.changeset(attrs)
|> Message.put_entity(entity)
|> Message.put_user(user)
|> Message.put_video(video)
|> Repo.insert()
end
def create_message(%Entity{} = entity, %Video{} = video, attrs) do
%Message{}
|> Message.changeset(attrs)
|> Message.put_entity(entity)
|> Message.put_video(video)
|> Repo.insert()
end
def update_message(%Message{} = message, attrs) do
message
|> Message.changeset(attrs)
|> Repo.update()
end
def delete_message(%Message{} = message) do
Repo.delete(message)
end
def change_message(%Message{} = message, attrs \\ %{}) do
Message.changeset(message, attrs)
end
defp topic(video_id) when is_integer(video_id), do: "room:#{video_id}"
defp broadcast!(topic, msg) do
Phoenix.PubSub.broadcast!(@pubsub, topic, {__MODULE__, msg})
end
def broadcast_message_deleted!(message) do
broadcast!(topic(message.video_id), %Events.MessageDeleted{message: message})
end
def broadcast_message_sent!(message) do
broadcast!(topic(message.video_id), %Events.MessageSent{message: message})
end
end