Make songs temporary assigns

This commit is contained in:
Chris McCord 2021-12-15 21:51:09 -05:00
parent ce1a1fdc5f
commit 8da032fed3
6 changed files with 56 additions and 30 deletions

View file

@ -184,14 +184,16 @@ defmodule LiveBeats.MediaLibrary do
case LiveBeats.Repo.transaction(multi) do case LiveBeats.Repo.transaction(multi) do
{:ok, results} -> {:ok, results} ->
{:ok, songs =
results results
|> Enum.filter(&match?({{:song, _ref}, _}, &1)) |> Enum.filter(&match?({{:song, _ref}, _}, &1))
|> Enum.map(fn {{:song, ref}, song} -> |> Enum.map(fn {{:song, ref}, song} ->
consume_file.(ref, fn tmp_path -> store_mp3(song, tmp_path) end) consume_file.(ref, fn tmp_path -> store_mp3(song, tmp_path) end)
{ref, song} {ref, song}
end) end)
|> Enum.into(%{})} broadcast_imported(user, songs)
{:ok, Enum.into(songs, %{})}
{:error, failed_op, failed_val, _changes} -> {:error, failed_op, failed_val, _changes} ->
failed_op = failed_op =
@ -205,6 +207,11 @@ defmodule LiveBeats.MediaLibrary do
end end
end end
defp broadcast_imported(%Accounts.User{} = user, songs) do
songs = Enum.map(songs, fn {_ref, song} -> song end)
broadcast!(user.id, %Events.SongsImported{user_id: user.id, songs: songs})
end
def parse_file_name(name) do def parse_file_name(name) do
case Regex.split(~r/[-]/, Path.rootname(name), parts: 2) do case Regex.split(~r/[-]/, Path.rootname(name), parts: 2) do
[title] -> %{title: String.trim(title), artist: nil} [title] -> %{title: String.trim(title), artist: nil}

View file

@ -10,4 +10,8 @@ defmodule LiveBeats.MediaLibrary.Events do
defmodule PublicProfileUpdated do defmodule PublicProfileUpdated do
defstruct profile: nil defstruct profile: nil
end end
defmodule SongsImported do
defstruct user_id: nil, songs: []
end
end end

View file

@ -557,7 +557,7 @@ defmodule LiveBeatsWeb.LiveHelpers do
<% end %> <% end %>
</tr> </tr>
</thead> </thead>
<tbody class="bg-white divide-y divide-gray-100"> <tbody id={@id} class="bg-white divide-y divide-gray-100" phx-update="append">
<%= for {row, i} <- Enum.with_index(@rows) do %> <%= for {row, i} <- Enum.with_index(@rows) do %>
<.live_component <.live_component
module={@module} module={@module}

View file

@ -43,18 +43,21 @@ defmodule LiveBeatsWeb.ProfileLive do
<:title let={user}><%= user.username %></:title> <:title let={user}><%= user.username %></:title>
</Presence.listening_now> </Presence.listening_now>
<%= for song <- if(@owns_profile?, do: @songs, else: []), id = "delete-modal-#{song.id}" do %> <div id="dialogs" phx-update="append">
<.modal <%= for song <- if(@owns_profile?, do: @songs, else: []), id = "delete-modal-#{song.id}" do %>
id={id} <.modal
on_confirm={JS.push("delete", value: %{id: song.id}) |> hide_modal(id) |> hide("#song-#{song.id}")} id={id}
> on_confirm={JS.push("delete", value: %{id: song.id}) |> hide_modal(id) |> hide("#song-#{song.id}")}
Are you sure you want to delete "<%= song.title %>"? >
<:cancel>Cancel</:cancel> Are you sure you want to delete "<%= song.title %>"?
<:confirm>Delete</:confirm> <:cancel>Cancel</:cancel>
</.modal> <:confirm>Delete</:confirm>
<% end %> </.modal>
<% end %>
</div>
<.live_table <.live_table
id="songs"
module={SongRowComponent} module={SongRowComponent}
rows={@songs} rows={@songs}
row_id={fn song -> "song-#{song.id}" end} row_id={fn song -> "song-#{song.id}" end}
@ -88,7 +91,7 @@ defmodule LiveBeatsWeb.ProfileLive do
active_song_id = active_song_id =
if song = MediaLibrary.get_current_active_song(profile) do if song = MediaLibrary.get_current_active_song(profile) do
SongRowComponent.send_status(song.id, song.status) SongRowComponent.send_status(song, song.status)
song.id song.id
end end
@ -158,12 +161,17 @@ defmodule LiveBeatsWeb.ProfileLive do
{:noreply, pause_song(socket, song.id)} {:noreply, pause_song(socket, song.id)}
end end
def handle_info({MediaLibrary, %MediaLibrary.Events.SongsImported{songs: songs}}, socket) do
{:noreply, update(socket, :songs, &(&1 ++ songs))}
end
def handle_info({MediaLibrary, _}, socket), do: {:noreply, socket} def handle_info({MediaLibrary, _}, socket), do: {:noreply, socket}
def handle_info({Accounts, _}, socket), do: {:noreply, socket} def handle_info({Accounts, _}, socket), do: {:noreply, socket}
defp stop_song(socket, song_id) do defp stop_song(socket, song_id) do
SongRowComponent.send_status(song_id, :stopped) song = MediaLibrary.get_song!(song_id)
SongRowComponent.send_status(song, :stopped)
if socket.assigns.active_song_id == song_id do if socket.assigns.active_song_id == song_id do
assign(socket, :active_song_id, nil) assign(socket, :active_song_id, nil)
@ -173,7 +181,8 @@ defmodule LiveBeatsWeb.ProfileLive do
end end
defp pause_song(socket, song_id) do defp pause_song(socket, song_id) do
SongRowComponent.send_status(song_id, :paused) song = MediaLibrary.get_song!(song_id)
SongRowComponent.send_status(song, :paused)
socket socket
end end
@ -182,18 +191,18 @@ defmodule LiveBeatsWeb.ProfileLive do
cond do cond do
active_song_id == song.id -> active_song_id == song.id ->
SongRowComponent.send_status(song.id, :playing) SongRowComponent.send_status(song, :playing)
socket socket
active_song_id -> active_song_id ->
SongRowComponent.send_status(song.id, :playing) SongRowComponent.send_status(song, :playing)
socket socket
|> stop_song(active_song_id) |> stop_song(active_song_id)
|> assign(active_song_id: song.id) |> assign(active_song_id: song.id)
true -> true ->
SongRowComponent.send_status(song.id, :playing) SongRowComponent.send_status(song, :playing)
assign(socket, active_song_id: song.id) assign(socket, active_song_id: song.id)
end end
end end

View file

@ -1,8 +1,10 @@
defmodule LiveBeatsWeb.ProfileLive.SongRowComponent do defmodule LiveBeatsWeb.ProfileLive.SongRowComponent do
use LiveBeatsWeb, :live_component use LiveBeatsWeb, :live_component
def send_status(id, status) when status in [:playing, :paused, :stopped] do alias LiveBeats.MediaLibrary.Song
send_update(__MODULE__, id: "song-#{id}", action: :send, status: status)
def send_status(%Song{} = song, status) when status in [:playing, :paused, :stopped] do
send_update(__MODULE__, id: "song-#{song.id}", action: :send, song: song, status: status)
end end
def render(assigns) do def render(assigns) do
@ -42,8 +44,12 @@ defmodule LiveBeatsWeb.ProfileLive.SongRowComponent do
""" """
end end
def update(%{action: :send, status: status}, socket) when status in [:playing, :paused, :stopped] do def mount(socket) do
{:ok, assign(socket, status: status)} {:ok, socket, temporary_assigns: [song: nil]}
end
def update(%{action: :send, status: status, song: song}, socket) when status in [:playing, :paused, :stopped] do
{:ok, assign(socket, status: status, song: song)}
end end
def update(assigns, socket) do def update(assigns, socket) do

View file

@ -54,7 +54,7 @@ defmodule LiveBeatsWeb.ProfileLive.UploadFormComponent do
{:noreply, {:noreply,
socket socket
|> put_flash(:info, "#{map_size(songs)} song(s) uploaded") |> put_flash(:info, "#{map_size(songs)} song(s) uploaded")
|> push_redirect(to: profile_path(current_user))} |> push_patch(to: profile_path(current_user))}
{:error, {failed_op, reason}} -> {:error, {failed_op, reason}} ->
{:noreply, put_error(socket, {failed_op, reason})} {:noreply, put_error(socket, {failed_op, reason})}