diff --git a/lib/music_library/scrobble_activity.ex b/lib/music_library/scrobble_activity.ex index 6196e3b8..ebc58005 100644 --- a/lib/music_library/scrobble_activity.ex +++ b/lib/music_library/scrobble_activity.ex @@ -328,18 +328,23 @@ defmodule MusicLibrary.ScrobbleActivity do end @doc """ - Gets top albums for multiple time periods (30, 90, 365 days) and all time. - Returns a map with the results for each period, along with collected and - wishlisted releases. + Gets top albums for the specified time periods (30, 90, 365 days) and all + time. Returns a map with the results, along with collected and wishlisted + releases. """ - def get_top_albums_by_periods(opts) do - last_30_days = get_top_albums_by_days(30, opts) - last_90_days = get_top_albums_by_days(90, opts) - last_365_days = get_top_albums_by_days(365, opts) - all_time = get_top_albums(opts) + def get_top_albums_by_period(opts) do + period = Keyword.get(opts, :period, :last_30_days) + + albums = + case period do + :all_time -> get_top_albums(opts) + :last_30_days -> get_top_albums_by_days(30, opts) + :last_90_days -> get_top_albums_by_days(90, opts) + :last_365_days -> get_top_albums_by_days(365, opts) + end all_album_ids = - (last_30_days ++ last_90_days ++ last_365_days ++ all_time) + albums |> Enum.map(fn t -> t.album_musicbrainz_id end) |> Enum.uniq() |> Enum.reject(fn musicbrainz_id -> musicbrainz_id == "" end) @@ -350,10 +355,7 @@ defmodule MusicLibrary.ScrobbleActivity do %{ collected_releases: collected_releases, wishlisted_releases: wishlisted_releases, - last_30_days: last_30_days, - last_90_days: last_90_days, - last_365_days: last_365_days, - all_time: all_time + albums: albums } end diff --git a/lib/music_library_web/live/stats_live/top_albums.ex b/lib/music_library_web/live/stats_live/top_albums.ex index 4d2e5ec0..db914339 100644 --- a/lib/music_library_web/live/stats_live/top_albums.ex +++ b/lib/music_library_web/live/stats_live/top_albums.ex @@ -18,53 +18,67 @@ defmodule MusicLibraryWeb.StatsLive.TopAlbums do

{gettext("Top Albums")}

- <.async_result :let={top_albums} assign={@top_albums}> - <:loading> -
- <.loading /> -
- - <.tabs class="mt-4"> - <.tabs_list active_tab="top_albums_last_30_days" variant="segmented"> - <:tab class="flex-1" name="top_albums_last_30_days">{gettext("Last 30 days")} - <:tab class="flex-1" name="top_albums_last_90_days">{gettext("Last 90 days")} - <:tab class="flex-1" name="top_albums_last_365_days">{gettext("Last year")} - <:tab class="flex-1" name="top_albums_all_time">{gettext("All time")} - - <.tabs_panel active name="top_albums_last_30_days"> - <.top_albums_by_period - albums={top_albums.last_30_days} - collected_releases={top_albums.collected_releases} - wishlisted_releases={top_albums.wishlisted_releases} - /> - - <.tabs_panel name="top_albums_last_90_days"> - <.top_albums_by_period - albums={top_albums.last_90_days} - collected_releases={top_albums.collected_releases} - wishlisted_releases={top_albums.wishlisted_releases} - /> - - <.tabs_panel name="top_albums_last_365_days"> - <.top_albums_by_period - albums={top_albums.last_365_days} - collected_releases={top_albums.collected_releases} - wishlisted_releases={top_albums.wishlisted_releases} - /> - - <.tabs_panel name="top_albums_all_time"> - <.top_albums_by_period - albums={top_albums.all_time} - collected_releases={top_albums.collected_releases} - wishlisted_releases={top_albums.wishlisted_releases} - /> - - - + <.tabs class="mt-4"> + <.tabs_list active_tab={name_from_period(@period)} variant="segmented"> + <:tab + class="flex-1" + name="top_albums_last_30_days" + phx-click={JS.push("set_period", value: %{period: "last_30_days"})} + phx-target={@myself} + > + {gettext("Last 30 days")} + + <:tab + class="flex-1" + name="top_albums_last_90_days" + phx-click={JS.push("set_period", value: %{period: "last_90_days"})} + phx-target={@myself} + > + {gettext("Last 90 days")} + + <:tab + class="flex-1" + name="top_albums_last_365_days" + phx-click={JS.push("set_period", value: %{period: "last_365_days"})} + phx-target={@myself} + > + {gettext("Last year")} + + <:tab + class="flex-1" + name="top_albums_all_time" + phx-click={JS.push("set_period", value: %{period: "all_time"})} + phx-target={@myself} + > + {gettext("All time")} + + + <.async_result :let={top_albums} assign={@top_albums}> + <:loading> +
+ <.loading /> +
+ + <.top_albums_by_period + albums={top_albums.albums} + collected_releases={top_albums.collected_releases} + wishlisted_releases={top_albums.wishlisted_releases} + /> + + """ end + defp name_from_period(period), do: "top_albums_#{period}" + + @impl true + def mount(socket) do + {:ok, + socket + |> assign(:period, :last_30_days)} + end + @impl true def update(assigns, socket) do {:ok, @@ -73,6 +87,14 @@ defmodule MusicLibraryWeb.StatsLive.TopAlbums do |> assign_top_albums()} end + @impl true + def handle_event("set_period", %{"period" => period}, socket) do + {:noreply, + socket + |> assign(:period, String.to_existing_atom(period)) + |> assign_top_albums()} + end + attr :albums, :list, required: true attr :collected_releases, :list, required: true attr :wishlisted_releases, :list, required: true @@ -136,19 +158,25 @@ defmodule MusicLibraryWeb.StatsLive.TopAlbums do end defp assign_top_albums(socket) do - timezone = socket.assigns.timezone + %{timezone: timezone, period: period} = socket.assigns current_time = DateTime.utc_now() - assign_async(socket, :top_albums, fn -> - top_albums = - ScrobbleActivity.get_top_albums_by_periods( - limit: 10, - current_time: current_time, - timezone: timezone - ) + assign_async( + socket, + :top_albums, + fn -> + top_albums = + ScrobbleActivity.get_top_albums_by_period( + limit: 10, + current_time: current_time, + timezone: timezone, + period: period + ) - {:ok, %{top_albums: top_albums}} - end) + {:ok, %{top_albums: top_albums}} + end, + reset: true + ) end defp navigate_to_record(collected_releases, wishlisted_releases, musicbrainz_id) do