defmodule LiveBeatsWeb.PlayerLive do use LiveBeatsWeb, {:live_view, container: {:div, []}} alias LiveBeats.MediaLibrary alias LiveBeats.MediaLibrary.Song on_mount {LiveBeatsWeb.UserAuth, :current_user} def render(assigns) do ~H"""

<%= if @song, do: @song.title, else: raw(" ") %>

<%= if @song, do: @song.artist, else: raw(" ") %>

<.progress_bar id="player-progress" />
<.modal id="enable-audio" on_confirm={js_listen_now() |> hide_modal("enable-audio")} data-js-show={show_modal("enable-audio")} > <:title>Start Listening now Your browser needs a click event to enable playback <:confirm>Listen Now
""" end def mount(_parmas, _session, socket) do if connected?(socket) and socket.assigns.current_user do MediaLibrary.subscribe(socket.assigns.current_user) send(self(), :play_current) end socket = assign(socket, song: nil, playing: false, current_user_id: socket.assigns.current_user.id, # todo use actual room user id room_user_id: socket.assigns.current_user.id ) {:ok, socket, layout: false, temporary_assigns: [current_user: nil]} end def handle_event("play_pause", _, socket) do %{song: song, playing: playing} = socket.assigns cond do song && playing -> MediaLibrary.pause_song(song) {:noreply, assign(socket, playing: false)} song -> MediaLibrary.play_song(song) {:noreply, assign(socket, playing: true)} true -> {:noreply, assign(socket, playing: false)} end end def handle_event("next-song", _, socket) do if socket.assigns.song do MediaLibrary.play_next_song(socket.assigns.song.user_id) end {:noreply, socket} end def handle_event("prev-song", _, socket) do if socket.assigns.song do MediaLibrary.play_prev_song(socket.assigns.song.user_id) end {:noreply, socket} end def handle_event("next-song-auto", _, socket) do if socket.assigns.song do MediaLibrary.play_next_song_auto(socket.assigns.song.user_id) end {:noreply, socket} end def handle_info(:play_current, socket) do # we raced a pubsub, noop if socket.assigns.song do {:noreply, socket} else {:noreply, play_current_song(socket)} end end def handle_info({:pause, _}, socket) do {:noreply, socket |> push_event("pause", %{}) |> assign(playing: false)} end def handle_info({:play, %Song{} = song, %{elapsed: elapsed}}, socket) do {:noreply, play_song(socket, song, elapsed)} end defp play_song(socket, %Song{} = song, elapsed) do socket |> push_play(song, elapsed) |> assign(song: song, playing: true) end defp js_play_pause(%JS{} = js) do JS.dispatch(js, "js:play_pause", to: "#audio-player") end defp js_listen_now(js \\ %JS{}) do JS.dispatch(js, "js:listen_now", to: "#audio-player") end defp play_current_song(socket) do song = MediaLibrary.get_current_active_song(socket.assigns.room_user_id) cond do song && MediaLibrary.playing?(song) -> play_song(socket, song, MediaLibrary.elapsed_playback(song)) song && MediaLibrary.paused?(song) -> assign(socket, song: song, playing: false) true -> socket end end defp push_play(socket, %Song{} = song, elapsed) do token = Phoenix.Token.sign(socket.endpoint, "file", song.mp3_filename) push_event(socket, "play", %{ paused: Song.paused?(song), elapsed: elapsed, token: token, url: song.mp3_url }) end end