mirror of
https://github.com/algora-io/tv.git
synced 2025-02-04 01:53:25 +02:00
add message deletion (#29)
This commit is contained in:
parent
3f427379a6
commit
71b0d3f218
@ -164,6 +164,9 @@ const Hooks = {
|
||||
|
||||
this.handleEvent("play_video", playVideo);
|
||||
this.handleEvent("join_chat", Chat.join);
|
||||
this.handleEvent("message_deleted", ({ id }) => {
|
||||
document.querySelector(`#message-${id}`)?.remove();
|
||||
});
|
||||
},
|
||||
},
|
||||
NavBar: {
|
||||
|
@ -42,7 +42,7 @@ const init = () => {
|
||||
|
||||
channel.on("new_msg", (payload) => {
|
||||
const messageItem = document.createElement("div");
|
||||
messageItem.className = "px-4";
|
||||
messageItem.className = "group hover:bg-white/5 relative px-4";
|
||||
|
||||
const senderItem = document.createElement("span");
|
||||
senderItem.innerText = `${payload.user.handle}: `;
|
||||
|
@ -8,6 +8,7 @@
|
||||
import Config
|
||||
|
||||
config :algora,
|
||||
admin_emails: ["zafer@algora.io", "ioannis@algora.io"],
|
||||
ecto_repos: [Algora.Repo.Local],
|
||||
rtmp_port: 9006
|
||||
|
||||
|
@ -6,7 +6,7 @@ defmodule Algora.Chat do
|
||||
import Ecto.Query, warn: false
|
||||
alias Algora.Library.Video
|
||||
alias Algora.Accounts.User
|
||||
alias Algora.Repo
|
||||
alias Algora.{Repo, Accounts}
|
||||
|
||||
alias Algora.Chat.Message
|
||||
|
||||
@ -15,8 +15,12 @@ defmodule Algora.Chat do
|
||||
from(m in Message,
|
||||
join: u in User,
|
||||
on: m.user_id == u.id,
|
||||
where: m.video_id == ^video.id,
|
||||
select_merge: %{sender_handle: u.handle}
|
||||
join: v in Video,
|
||||
on: m.video_id == v.id,
|
||||
join: c in User,
|
||||
on: c.id == v.user_id,
|
||||
select_merge: %{sender_handle: u.handle, channel_id: c.id},
|
||||
where: m.video_id == ^video.id
|
||||
)
|
||||
|> order_by_inserted(:asc)
|
||||
|> Repo.all()
|
||||
@ -26,7 +30,23 @@ defmodule Algora.Chat do
|
||||
from(s in query, order_by: [{^direction, s.inserted_at}])
|
||||
end
|
||||
|
||||
def get_message!(id), do: Repo.get!(Message, id)
|
||||
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: 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: %{sender_handle: u.handle, channel_id: c.id},
|
||||
where: m.id == ^id
|
||||
)
|
||||
|> Repo.one!()
|
||||
end
|
||||
|
||||
def create_message(attrs \\ %{}) do
|
||||
%Message{}
|
||||
|
@ -7,6 +7,7 @@ defmodule Algora.Chat.Message do
|
||||
schema "messages" do
|
||||
field :body, :string
|
||||
field :sender_handle, :string, virtual: true
|
||||
field :channel_id, :integer, virtual: true
|
||||
belongs_to :user, Accounts.User
|
||||
belongs_to :video, Library.Video
|
||||
|
||||
|
@ -640,6 +640,10 @@ defmodule Algora.Library do
|
||||
Phoenix.PubSub.broadcast!(@pubsub, topic, {__MODULE__, msg})
|
||||
end
|
||||
|
||||
def broadcast_message_deleted!(%Channel{} = channel, message) do
|
||||
broadcast!(topic(channel.user_id), %Events.MessageDeleted{message: message})
|
||||
end
|
||||
|
||||
def broadcast_processing_progressed!(stage, video, pct) do
|
||||
broadcast!(topic_studio(), %Events.ProcessingProgressed{video: video, stage: stage, pct: pct})
|
||||
end
|
||||
|
@ -26,4 +26,8 @@ defmodule Algora.Library.Events do
|
||||
defmodule ProcessingFailed do
|
||||
defstruct video: nil, attempt: nil, max_attempts: nil
|
||||
end
|
||||
|
||||
defmodule MessageDeleted do
|
||||
defstruct message: nil
|
||||
end
|
||||
end
|
||||
|
@ -139,13 +139,27 @@ defmodule AlgoraWeb.VideoLive do
|
||||
phx-update="ignore"
|
||||
class="text-sm break-words flex-1 scrollbar-thin overflow-y-auto h-[calc(100vh-11rem)]"
|
||||
>
|
||||
<div :for={message <- @messages} id={"message-#{message.id}"} class="px-4">
|
||||
<div
|
||||
:for={message <- @messages}
|
||||
id={"message-#{message.id}"}
|
||||
class="group hover:bg-white/5 relative px-4"
|
||||
>
|
||||
<span class={"font-semibold #{if(system_message?(message), do: "text-emerald-400", else: "text-indigo-400")}"}>
|
||||
<%= message.sender_handle %>:
|
||||
</span>
|
||||
<span class="font-medium text-gray-100">
|
||||
<%= message.body %>
|
||||
</span>
|
||||
<button
|
||||
:if={@current_user && Chat.can_delete?(@current_user, message)}
|
||||
phx-click="delete"
|
||||
phx-value-id={message.id}
|
||||
>
|
||||
<Heroicons.x_mark
|
||||
solid
|
||||
class="absolute top-0.5 right-0.5 h-4 w-4 text-red-400 opacity-0 group-hover:opacity-100"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-4">
|
||||
@ -483,6 +497,13 @@ defmodule AlgoraWeb.VideoLive do
|
||||
end}
|
||||
end
|
||||
|
||||
def handle_info(
|
||||
{Library, %Library.Events.MessageDeleted{message: message}},
|
||||
socket
|
||||
) do
|
||||
{:noreply, socket |> push_event("message_deleted", %{id: message.id})}
|
||||
end
|
||||
|
||||
def handle_info({Library, _}, socket), do: {:noreply, socket}
|
||||
|
||||
defp fmt(num) do
|
||||
@ -504,6 +525,19 @@ defmodule AlgoraWeb.VideoLive do
|
||||
{:noreply, socket |> put_flash(:info, msg)}
|
||||
end
|
||||
|
||||
def handle_event("delete", %{"id" => id}, socket) do
|
||||
%{current_user: current_user} = socket.assigns
|
||||
message = Chat.get_message!(id)
|
||||
|
||||
if current_user && Chat.can_delete?(current_user, message) do
|
||||
{:ok, message} = Chat.delete_message(message)
|
||||
Library.broadcast_message_deleted!(socket.assigns.channel, message)
|
||||
{:noreply, socket}
|
||||
else
|
||||
{:noreply, socket |> put_flash(:error, "You can't do that")}
|
||||
end
|
||||
end
|
||||
|
||||
defp save("naive", subtitles) do
|
||||
Library.save_subtitles(subtitles)
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user