mirror of
https://github.com/algora-io/tv.git
synced 2024-11-26 01:00:20 +02:00
6be4bb1ad9
* remove unused stuff * remove more unused stuff * clean up * remove more unused stuff * render ChatLive on /:channel/chat * handle no video case * simplify * subscribe to new room on new livestream * show flash message on new livestream * add flash with action * handle no existing video case
178 lines
5.6 KiB
Elixir
178 lines
5.6 KiB
Elixir
defmodule AlgoraWeb.ChatLive do
|
|
use AlgoraWeb, :live_view
|
|
require Logger
|
|
|
|
alias Algora.{Accounts, Library, Chat}
|
|
alias AlgoraWeb.{LayoutComponent, RTMPDestinationIconComponent}
|
|
|
|
def render(assigns) do
|
|
~H"""
|
|
<aside id="side-panel" class="w-[400px] rounded ring-1 ring-purple-300 m-1 overflow-hidden">
|
|
<div>
|
|
<div :if={@channel.solving_challenge} class="bg-black px-4 py-4 rounded text-center">
|
|
<div class="font-medium text-base">
|
|
<.link
|
|
href="https://console.algora.io/challenges/tsperf"
|
|
class="font-semibold text-green-300 hover:underline"
|
|
>
|
|
Solving the $15,000 TSPerf Challenge
|
|
</.link>
|
|
</div>
|
|
<div class="pt-1.5 font-medium text-sm">
|
|
sponsored by
|
|
</div>
|
|
<div class="pt-2.5 mx-auto grid max-w-6xl gap-4 text-center grid-cols-3">
|
|
<a
|
|
target="_blank"
|
|
rel="noopener"
|
|
class="flex h-full flex-1 flex-col items-center text-white no-underline hover:no-underline"
|
|
href="https://unkey.com"
|
|
>
|
|
<img
|
|
src="https://console.algora.io/banners/unkey.png"
|
|
alt="Unkey"
|
|
class="-mt-1 h-8 w-auto saturate-0"
|
|
/>
|
|
</a>
|
|
<a
|
|
target="_blank"
|
|
rel="noopener"
|
|
class="flex h-full flex-1 flex-col items-center text-white no-underline hover:no-underline"
|
|
href="https://scalar.com"
|
|
>
|
|
<img
|
|
src="https://console.algora.io/banners/scalar.png"
|
|
alt="Scalar"
|
|
class="h-6 w-auto saturate-0"
|
|
/>
|
|
</a>
|
|
<a
|
|
target="_blank"
|
|
rel="noopener"
|
|
class="flex h-full flex-1 flex-col items-center text-white no-underline hover:no-underline"
|
|
href="https://tigrisdata.com"
|
|
>
|
|
<img
|
|
src="https://assets-global.website-files.com/657988158c7fb30f4d9ef37b/657990b61fd3a5d674cf2298_tigris-logo.svg"
|
|
alt="Tigris"
|
|
class="mt-1 h-6 w-auto saturate-0"
|
|
/>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div id="side-panel-content-chat" class="side-panel-content">
|
|
<div>
|
|
<div
|
|
id="chat-messages"
|
|
phx-hook="Chat"
|
|
phx-update="stream"
|
|
class="text-sm break-words flex-1 scrollbar-thin overflow-y-auto inset-0 h-[400px] py-4"
|
|
>
|
|
<div :for={{id, message} <- @streams.messages} id={id} class="px-4">
|
|
<RTMPDestinationIconComponent.icon
|
|
:if={message.platform != "algora"}
|
|
class="inline-flex w-5 h-5 shrink-0 mr-0.5"
|
|
icon={String.to_atom(message.platform)}
|
|
/>
|
|
<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>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
"""
|
|
end
|
|
|
|
def mount(%{"channel_handle" => channel_handle} = params, _session, socket) do
|
|
user = Accounts.get_user_by!(handle: channel_handle)
|
|
channel = Library.get_channel!(user)
|
|
|
|
video =
|
|
case params["video_id"] do
|
|
nil -> Library.get_latest_video(user)
|
|
id -> Library.get_video!(id)
|
|
end
|
|
|
|
messages =
|
|
case video do
|
|
nil -> []
|
|
video -> Chat.list_messages(video)
|
|
end
|
|
|
|
if connected?(socket) do
|
|
Library.subscribe_to_livestreams()
|
|
Library.subscribe_to_channel(channel)
|
|
if video, do: Chat.subscribe_to_room(video)
|
|
end
|
|
|
|
{:ok,
|
|
socket
|
|
|> assign(:channel, channel)
|
|
|> assign(:video, video)
|
|
|> stream(:messages, messages)}
|
|
end
|
|
|
|
def handle_params(params, _url, socket) do
|
|
LayoutComponent.hide_modal()
|
|
{:noreply, socket |> apply_action(socket.assigns.live_action, params)}
|
|
end
|
|
|
|
def handle_info(
|
|
{Chat, %Chat.Events.MessageDeleted{message: message}},
|
|
socket
|
|
) do
|
|
{:noreply, socket |> stream_delete(:messages, message)}
|
|
end
|
|
|
|
def handle_info(
|
|
{Chat, %Chat.Events.MessageSent{message: message}},
|
|
socket
|
|
) do
|
|
{:noreply, socket |> stream_insert(:messages, message)}
|
|
end
|
|
|
|
def handle_info(
|
|
{Library, %Library.Events.LivestreamStarted{video: video}},
|
|
socket
|
|
) do
|
|
if video.user_id != socket.assigns.channel.user_id do
|
|
{:noreply, socket}
|
|
else
|
|
Chat.unsubscribe_to_room(socket.assigns.video)
|
|
Chat.subscribe_to_room(video)
|
|
{:noreply, socket |> assign(:video, video)}
|
|
end
|
|
end
|
|
|
|
def handle_info(_arg, socket), do: {:noreply, socket}
|
|
|
|
defp system_message?(%Chat.Message{} = message) do
|
|
message.sender_handle == "algora"
|
|
end
|
|
|
|
defp apply_action(socket, :show, params) do
|
|
channel_name = socket.assigns.channel.name || params["channel_handle"]
|
|
|
|
case socket.assigns.video do
|
|
nil ->
|
|
socket
|
|
|> assign(:page_title, channel_name)
|
|
|> assign(:page_description, "Watch #{channel_name} on Algora TV")
|
|
|
|
video ->
|
|
socket
|
|
|> assign(:page_title, channel_name)
|
|
|> assign(:page_description, video.title)
|
|
|> assign(:page_image, Library.get_og_image_url(video))
|
|
end
|
|
end
|
|
end
|