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