From c3e857eb5c8ee60de07b3fdefa7c38beb24d0d8b Mon Sep 17 00:00:00 2001 From: Marcin Kulik Date: Sun, 21 Apr 2024 21:46:07 +0200 Subject: [PATCH] Update live stream card in real-time --- lib/asciinema/streaming/live_stream_server.ex | 23 ++++++++++----- .../controllers/live_stream/card.html.heex | 1 - .../controllers/user/show.html.heex | 4 ++- lib/asciinema_web/controllers/user_html.ex | 2 +- .../live/live_stream_card_live.ex | 28 +++++++++++++++++++ 5 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 lib/asciinema_web/live/live_stream_card_live.ex diff --git a/lib/asciinema/streaming/live_stream_server.ex b/lib/asciinema/streaming/live_stream_server.ex index f45290454..f48c88523 100644 --- a/lib/asciinema/streaming/live_stream_server.ex +++ b/lib/asciinema/streaming/live_stream_server.ex @@ -31,7 +31,7 @@ defmodule Asciinema.Streaming.LiveStreamServer do GenServer.call(via_tuple(stream_id), :heartbeat) end - def subscribe(stream_id, type) when type in [:reset, :feed, :offline] do + def subscribe(stream_id, type) when type in [:reset, :feed, :offline, :metadata] do PubSub.subscribe(topic_name(stream_id, type)) end @@ -165,12 +165,21 @@ defmodule Asciinema.Streaming.LiveStreamServer do stream = case state.vt_size do {cols, rows} -> - Streaming.update_live_stream(state.stream, - current_viewer_count: state.viewer_count, - cols: cols, - rows: rows, - snapshot: generate_snapshot(state.vt) - ) + stream = + Streaming.update_live_stream(state.stream, + current_viewer_count: state.viewer_count, + cols: cols, + rows: rows, + snapshot: generate_snapshot(state.vt) + ) + + publish(state.stream_id, %Update{ + stream_id: state.stream_id, + event: :metadata, + data: stream + }) + + stream nil -> state.stream diff --git a/lib/asciinema_web/controllers/live_stream/card.html.heex b/lib/asciinema_web/controllers/live_stream/card.html.heex index 2b6081b9e..88428b574 100644 --- a/lib/asciinema_web/controllers/live_stream/card.html.heex +++ b/lib/asciinema_web/controllers/live_stream/card.html.heex @@ -26,7 +26,6 @@ by <.link href={author_profile_path(@stream)}><%= author_username(@stream) %> - <%= time_ago_tag(@stream.last_started_at) %> diff --git a/lib/asciinema_web/controllers/user/show.html.heex b/lib/asciinema_web/controllers/user/show.html.heex index 5b7432684..9ebabc133 100644 --- a/lib/asciinema_web/controllers/user/show.html.heex +++ b/lib/asciinema_web/controllers/user/show.html.heex @@ -41,7 +41,9 @@
- + <%= live_render(@conn, AsciinemaWeb.LiveStreamCardLive, + session: %{"stream_id" => stream.id} + ) %>
diff --git a/lib/asciinema_web/controllers/user_html.ex b/lib/asciinema_web/controllers/user_html.ex index 99cd9f252..d56cd3255 100644 --- a/lib/asciinema_web/controllers/user_html.ex +++ b/lib/asciinema_web/controllers/user_html.ex @@ -3,7 +3,7 @@ defmodule AsciinemaWeb.UserHTML do import AsciinemaWeb.ErrorHelpers import Scrivener.HTML alias Asciinema.{Fonts, Gravatar} - alias AsciinemaWeb.{LiveStreamHTML, MediaView, RecordingHTML} + alias AsciinemaWeb.{MediaView, RecordingHTML} embed_templates "user/*" diff --git a/lib/asciinema_web/live/live_stream_card_live.ex b/lib/asciinema_web/live/live_stream_card_live.ex new file mode 100644 index 000000000..4a9f5fef9 --- /dev/null +++ b/lib/asciinema_web/live/live_stream_card_live.ex @@ -0,0 +1,28 @@ +defmodule AsciinemaWeb.LiveStreamCardLive do + use AsciinemaWeb, :live_view + alias Asciinema.Streaming + alias Asciinema.Streaming.LiveStreamServer + + @impl true + def render(assigns) do + ~H""" + + """ + end + + @impl true + def mount(_params, %{"stream_id" => stream_id}, socket) do + socket = assign(socket, :stream, Streaming.get_live_stream(stream_id)) + + if connected?(socket) do + LiveStreamServer.subscribe(stream_id, :metadata) + end + + {:ok, socket} + end + + @impl true + def handle_info(%LiveStreamServer.Update{event: :metadata} = update, socket) do + {:noreply, assign(socket, stream: update.data)} + end +end