Skip to content

Commit 6380915

Browse files
authored
Merge pull request #47 from ve1ld/chore/player-improvements
Support playback seeking by clicking on the verse
2 parents aeb7b8f + 2594481 commit 6380915

File tree

3 files changed

+62
-21
lines changed

3 files changed

+62
-21
lines changed

lib/vyasa_web/live/media_live/player_live.ex

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,12 @@ defmodule VyasaWeb.MediaLive.Player do
4141

4242
@impl true
4343
def handle_event("seekToMs", %{"position_ms" => position_ms} = _payload, socket) do
44-
IO.puts("[handleEvent] seekToMs #{position_ms} is_integer? #{is_integer(position_ms)} is string? #{is_binary(position_ms)}")
44+
IO.puts("[handleEvent] seekToMs #{position_ms}")
45+
socket
46+
|> handle_seek(position_ms)
47+
end
4548

49+
defp handle_seek(socket, position_ms) do
4650
%{playback: %Playback{
4751
medium: %Voice{} = _voice,
4852
playing?: playing?,
@@ -58,12 +62,12 @@ defmodule VyasaWeb.MediaLive.Player do
5862

5963
{:noreply, socket
6064
|> push_event("seekTo", %{positionS: position_s})
61-
|> assign(playback: %{playback | played_at: played_at, elapsed: position_s})
65+
|> assign(playback: %{playback | played_at: played_at, elapsed: position_s}) #modifies the socket after emitting client-side event
6266
}
63-
end
67+
end
6468

6569
@impl true
66-
@doc"""
70+
@doc """
6771
On receiving a voice_ack, the written and player contexts are now synced.
6872
A playback struct is created that represents this synced-state and the client-side hook is triggerred
6973
to register the associated events timeline.
@@ -72,11 +76,10 @@ defmodule VyasaWeb.MediaLive.Player do
7276
%Playback{
7377
medium: %Voice{events: events},
7478
} = playback = voice |> Playback.create_playback()
75-
# } = playback = voice |> MediaLibrary.gen_voice_playback()
79+
# } = playback = voice |> MediaLibrary.gen_voice_playback() # TODO: example of where the media bridge can be introduced
7680

7781
socket = socket
7882
|> assign(playback: playback)
79-
# Registers Events Timeline on Client-Side:
8083
|> push_event("registerEventsTimeline", %{voice_events: events |> create_events_payload()})
8184

8285
{:noreply, socket}
@@ -87,6 +90,26 @@ defmodule VyasaWeb.MediaLive.Player do
8790
{:noreply, socket}
8891
end
8992

93+
# Handles playback sync relative to a particular verse id. In this case, the playback state is expected
94+
# to get updated to the start of the event corresponding to that particular verse.
95+
@impl true
96+
def handle_info({_, :playback_sync, %{verse_id: verse_id} = _inner_msg} = _msg, socket) do
97+
%{playback: %Playback{
98+
medium: %Voice{
99+
events: events,
100+
} = _voice,
101+
} = _playback} = socket.assigns
102+
103+
%Event{
104+
origin: target_ms
105+
} = _target_event = events
106+
|> get_target_event(verse_id)
107+
108+
109+
socket
110+
|> handle_seek(target_ms)
111+
end
112+
90113
def handle_info(msg, socket) do
91114
IO.inspect(msg, label: "unexpected message in @player_live")
92115
{:noreply, socket}
@@ -97,6 +120,10 @@ defp create_events_payload([%Event{} | _] = events) do
97120
events|> Enum.map(&(&1 |> Map.take([:origin, :duration, :phase, :fragments, :verse_id])))
98121
end
99122

123+
defp get_target_event([%Event{} | _] = events, verse_id) do
124+
events
125+
|> Enum.find(fn e -> e.verse_id === verse_id end)
126+
end
100127

101128

102129
defp play_voice(socket, %Playback{

lib/vyasa_web/live/source_live/chapter/index.ex

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,18 @@ defmodule VyasaWeb.SourceLive.Chapter.Index do
5858
|> assign_meta()
5959
end
6060

61+
@impl true
62+
@doc """
63+
Handles the action of clicking to seek by emitting the verse_id to the live player
64+
via the pubsub system.
65+
"""
66+
def handle_event("clickVerseToSeek",
67+
%{"verse_id" => verse_id} = _payload,
68+
%{assigns: %{session: %{"id" => sess_id}}} = socket) do
69+
Vyasa.PubSub.publish(%{verse_id: verse_id}, :playback_sync, "media:session:" <> sess_id)
70+
{:noreply, socket}
71+
end
72+
6173
@doc """
6274
Upon rcv of :media_handshake, which indicates an intention to sync by the player,
6375
returns a message containing %Voice{} info that can be used to generate a playback.
@@ -79,8 +91,7 @@ defmodule VyasaWeb.SourceLive.Chapter.Index do
7991
{:noreply, socket}
8092
end
8193

82-
def handle_info(msg, socket) do
83-
IO.inspect(msg, label: "unexpected message in @chapter")
94+
def handle_info(msg, socket) do IO.inspect(msg, label: "unexpected message in @chapter")
8495
{:noreply, socket}
8596
end
8697

@@ -96,35 +107,36 @@ defmodule VyasaWeb.SourceLive.Chapter.Index do
96107
end
97108

98109
@doc """
99-
Renders a clickable verse list.
110+
Renders a clickable verse display.
100111
101112
## Examples
102-
<.verse_list>
113+
<.verse_display>
103114
<:item title="Title" navigate={~p"/myPath"}><%= @post.title %></:item>
104-
</.list>
115+
</.verse_display>
105116
"""
106117
attr :id, :string, required: false
107118
slot :item, required: true do
108119
attr :title, :string
120+
attr :verse_id, :string, required: false
109121
attr :navigate, :any, required: false
110122
end
111-
def verse_list(assigns) do
123+
def verse_display(assigns) do
112124
~H"""
113125
<div class="mt-14" id={@id}>
114126
<dl class="-my-4 divide-y divide-zinc-100">
115127
<div :for={item <- @item} class="flex gap-4 py-4 text-sm leading-6 sm:gap-8">
116128
<dt
117-
:if={Map.has_key?(item, :title) && Map.has_key?(item, :navigate)}
129+
:if={Map.has_key?(item, :title) && Map.has_key?(item, :verse_id)}
118130
class="w-1/6 flex-none text-zinc-500"
119131
>
120-
<.link
121-
navigate={item[:navigate]}
132+
<button
133+
phx-click={JS.push("clickVerseToSeek", value: %{verse_id: item.verse_id})}
122134
class="text-sm font-semibold leading-6 text-zinc-900 hover:text-zinc-700"
123135
>
124136
<div class="font-dn text-2xl mb-4">
125137
<%= item.title %>
126138
</div>
127-
</.link>
139+
</button>
128140
</dt>
129141
<dd class="text-zinc-700"><%= render_slot(item) %></dd>
130142
</div>
@@ -133,4 +145,4 @@ defmodule VyasaWeb.SourceLive.Chapter.Index do
133145
"""
134146
end
135147

136-
end
148+
end

lib/vyasa_web/live/source_live/chapter/index.html.heex

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
</:subtitle>
1414
</.header>
1515

16-
<.verse_list id={dom_id} :for={{dom_id, verse} <- @streams.verses}>
17-
<:item title={"#{verse.chapter_no}.#{verse.no}"}
18-
navigate={~p"/explore/#{@source_title}/#{@chap.no}/#{verse.no}"} >
16+
<.verse_display id={dom_id} :for={{dom_id, verse} <- @streams.verses}>
17+
<:item
18+
title={"#{verse.chapter_no}.#{verse.no}"}
19+
verse_id={verse.id}
20+
>
1921

2022
<p class="font-dn text-xl">
2123
<%= verse.body |> String.split("।।") |> List.first() %>
@@ -36,7 +38,7 @@
3638
<%= verse && Enum.any?(verse.translations) && hd(verse.translations).target.body %>
3739
</p>
3840
</:item>
39-
</.verse_list>
41+
</.verse_display>
4042

4143
<.back navigate={~p"/explore/#{@source_title}"}>Back to <%= @source_title %> Chapters</.back>
4244
</div>

0 commit comments

Comments
 (0)