EXP - scrobble anything
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
defmodule MusicLibraryWeb.ScrobbleLive.Show do
|
||||
use MusicLibraryWeb, :live_view
|
||||
|
||||
alias MusicLibrary.ScrobbleActivity
|
||||
|
||||
@impl true
|
||||
def mount(%{"release_id" => release_id}, _session, socket) do
|
||||
{:ok,
|
||||
assign(socket,
|
||||
current_section: :scrobble,
|
||||
release_id: release_id,
|
||||
release: nil,
|
||||
loading: true,
|
||||
can_scrobble: ScrobbleActivity.can_scrobble?(),
|
||||
scrobble_form: %{
|
||||
"type" => "finished_at",
|
||||
"finished_at_date" => Date.utc_today() |> Date.to_string(),
|
||||
"finished_at_time" => Time.utc_now() |> Time.truncate(:second) |> Time.to_string(),
|
||||
"started_at_date" => Date.utc_today() |> Date.to_string(),
|
||||
"started_at_time" => Time.utc_now() |> Time.truncate(:second) |> Time.to_string()
|
||||
},
|
||||
page_title: "Scrobble Release"
|
||||
)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_params(params, _url, socket) do
|
||||
{:noreply, apply_action(socket, socket.assigns.live_action, params)}
|
||||
end
|
||||
|
||||
defp apply_action(socket, :show, _params) do
|
||||
send(self(), :fetch_release)
|
||||
socket
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("update_scrobble_form", %{"scrobble" => scrobble_params}, socket) do
|
||||
{:noreply, assign(socket, scrobble_form: scrobble_params)}
|
||||
end
|
||||
|
||||
def handle_event("scrobble_release", _params, socket) do
|
||||
case perform_scrobble(socket.assigns.release, :all, socket.assigns.scrobble_form) do
|
||||
{:ok, _result} ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:info, "Release scrobbled successfully!")
|
||||
|> push_navigate(to: ~p"/scrobble")}
|
||||
|
||||
{:error, reason} ->
|
||||
{:noreply, put_flash(socket, :error, "Failed to scrobble release: #{inspect(reason)}")}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_event("scrobble_medium", %{"medium_number" => medium_number_str}, socket) do
|
||||
{medium_number, ""} = Integer.parse(medium_number_str)
|
||||
|
||||
case perform_scrobble(
|
||||
socket.assigns.release,
|
||||
{:medium, medium_number},
|
||||
socket.assigns.scrobble_form
|
||||
) do
|
||||
{:ok, _result} ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:info, "Medium scrobbled successfully!")
|
||||
|> push_navigate(to: ~p"/scrobble")}
|
||||
|
||||
{:error, reason} ->
|
||||
{:noreply, put_flash(socket, :error, "Failed to scrobble medium: #{inspect(reason)}")}
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_info(:fetch_release, socket) do
|
||||
case MusicBrainz.get_release(socket.assigns.release_id) do
|
||||
{:ok, release} ->
|
||||
release = MusicBrainz.Release.from_api_response(release)
|
||||
|
||||
{:noreply,
|
||||
assign(socket,
|
||||
release: release,
|
||||
loading: false,
|
||||
page_title: "Scrobble: #{release.title}"
|
||||
)}
|
||||
|
||||
{:error, _reason} ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:error, "Failed to fetch release details")
|
||||
|> push_navigate(to: ~p"/scrobble")}
|
||||
end
|
||||
end
|
||||
|
||||
defp perform_scrobble(release, scope, scrobble_form) do
|
||||
datetime_opts = build_datetime_opts(scrobble_form)
|
||||
|
||||
case scope do
|
||||
:all ->
|
||||
ScrobbleActivity.scrobble_release(release, datetime_opts)
|
||||
|
||||
{:medium, medium_number} ->
|
||||
ScrobbleActivity.scrobble_medium(medium_number, release, datetime_opts)
|
||||
end
|
||||
end
|
||||
|
||||
defp build_datetime_opts(%{
|
||||
"type" => "finished_at",
|
||||
"finished_at_date" => date,
|
||||
"finished_at_time" => time
|
||||
}) do
|
||||
with {:ok, date} <- Date.from_iso8601(date),
|
||||
{:ok, time} <- Time.from_iso8601(time),
|
||||
datetime <- DateTime.new!(date, time, "Etc/UTC") do
|
||||
[finished_at: datetime]
|
||||
else
|
||||
_ -> [finished_at: DateTime.utc_now()]
|
||||
end
|
||||
end
|
||||
|
||||
defp build_datetime_opts(%{
|
||||
"type" => "started_at",
|
||||
"started_at_date" => date,
|
||||
"started_at_time" => time
|
||||
}) do
|
||||
with {:ok, date} <- Date.from_iso8601(date),
|
||||
{:ok, time} <- Time.from_iso8601(time),
|
||||
datetime <- DateTime.new!(date, time, "Etc/UTC") do
|
||||
[started_at: datetime]
|
||||
else
|
||||
_ -> [started_at: DateTime.utc_now()]
|
||||
end
|
||||
end
|
||||
|
||||
defp build_datetime_opts(_), do: [finished_at: DateTime.utc_now()]
|
||||
|
||||
defp format_duration(nil), do: "Unknown"
|
||||
|
||||
defp format_duration(milliseconds) when is_integer(milliseconds) do
|
||||
seconds = div(milliseconds, 1000)
|
||||
minutes = div(seconds, 60)
|
||||
remaining_seconds = rem(seconds, 60)
|
||||
|
||||
"#{minutes}:#{String.pad_leading(Integer.to_string(remaining_seconds), 2, "0")}"
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user