Files
music_library/backlog/archive/tasks/ml-142.1 - Port-Finished-at-picker-and-selection-bar-to-ScrobbleLive.Show.md
2026-05-04 21:22:27 +01:00

4.6 KiB

id, title, status, assignee, created_date, labels, dependencies, references, parent_task_id, priority
id title status assignee created_date labels dependencies references parent_task_id priority
ML-142.1 Port Finished at picker and selection bar to ScrobbleLive.Show To Do
2026-04-22 16:30
ui
scrobble
lib/music_library_web/live/scrobble_live/show.ex
lib/music_library_web/components/release.ex
backlog/ml-142/plan.md
ML-142 medium

Description

Bring the /scrobble/:release_id page (MusicLibraryWeb.ScrobbleLive.Show) up to ML-142 parity for the two affordances that affect scrobbling outcomes: the Finished at date/time picker and the pinned selection-bar footer.

Today the page imports medium/1 and scrobble_button_label/1 from MusicLibraryWeb.Components.Release — so the per-medium UI stays visually consistent — but reimplements its own scrobble_release, scrobble_medium, and scrobble_selected_tracks handlers, each hard-coding DateTime.utc_now/0. There is no picker (users cannot back-date or forward-date a scrobble) and no selection bar (when tracks are selected, the user sees no count/duration summary and the only scrobble affordance is an icon-only header button whose behaviour depends on hidden selection state via scrobble_button_label/1).

ScrobbleLive.Show was explicitly called out as out-of-scope in ML-142 — see backlog/ml-142/plan.md: "A full sticky-bar + picker port to ScrobbleLive.Show. That page uses its own layout (not the sheet) and can be iterated on separately once the LiveComponent pattern is settled." That deferred work is the subject of this task.

Out of scope

  • overflow menu on this page (Print tracklist for release + per-medium).
  • Connect Last.fm dropdown entry — the page already has a top-of-page alert banner for that state.
  • Extracting a shared function component or LiveHelper is an implementation decision, not a requirement. Implementer may duplicate or refactor; the acceptance criteria are outcome-based.

Reusable pieces the implementer can draw on

  • MusicLibraryWeb.Components.Release.apply_form_params/3 — already public, already used by this LiveView.
  • MusicLibraryWeb.Components.Release.medium/1 — already imported.
  • MusicLibrary.ScrobbleActivity.scrobble_release/3, scrobble_medium/4, scrobble_tracks/4 — already used.
  • Private helpers in Release that may need to be promoted (implementer's choice): parse_finished_at/1, selection_bar/1, selected_tracks_summary/2.
  • scrobble_button_label/1 will likely become unused after AC#8 — remove if so.
  • lib/music_library_web/live_helpers/ pattern (e.g. record_actions.ex) is a possible refactor target but not required.

Acceptance Criteria

  • #1 The page renders a Finished at date/time picker in the tracks section header when Last.fm is connected, initialised to the current time at mount
  • #2 The picker has a Now reset affordance that resets the value back to the current time
  • #3 Scrobble release uses the picker value; no longer calls DateTime.utc_now/0 directly inside the handler
  • #4 Per-medium Scrobble disc/Scrobble side uses the picker value; no longer calls DateTime.utc_now/0 directly inside the handler
  • #5 Scrobble selected tracks uses the picker value; no longer calls DateTime.utc_now/0 directly inside the handler
  • #6 A selection bar renders at the bottom of the tracks section whenever MapSet.size(@selected_tracks) > 0, showing track count, medium count (when > 1), aggregate duration, and a Scrobble selected button
  • #7 The selection bar is not rendered when no tracks are selected
  • #8 The selection bar stays visible while the tracks list is scrolled on narrow viewports (position: sticky or equivalent layout — implementer's choice given this page sits inside Layouts.app, not the sheet)
  • #9 The icon-only header scrobble button (which currently toggles via scrobble_button_label/1) is replaced by a solid Scrobble release button; the selection bar owns the scrobble-selected role
  • #10 All new user-facing strings wrapped in gettext; .pot/.po files regenerated via mix gettext.extract --merge
  • #11 LiveView tests cover: picker default state initialised to utc_now, picker value propagating to all three scrobble handlers, reset_to_now event, selection-bar hidden when no tracks selected, selection-bar shown with correct copy when tracks selected
  • #12 The existing AC#14 regression test (per-medium scrobble works with cross-medium tracks selected, at test/music_library_web/live/scrobble_live/show_test.exs:115) continues to pass