Skip to content

feat: Multi-Setlist Management #14

@ElBeh

Description

@ElBeh

Description

Support multiple named setlists per song library. Users can create, switch,
rename, duplicate, and delete setlists via a dropdown in the sidebar setlist
header. Prepares the data model for a future "Gig" grouping layer
(Gig → Setlists → Songs).

Estimated effort: ~6–8h

Requirements

  • Dropdown in sidebar setlist header to switch between saved setlists
  • Create new setlist (inline name input)
  • Rename active setlist
  • Duplicate setlist (copy with "(Copy)" suffix)
  • Delete setlist (with confirmation, prevent deleting the last one)
  • Mark one setlist as default (auto-loaded on app start)
  • Display total duration (sum of song durations + pause durations) in setlist header
  • Context action on song entry: "Copy to Setlist X" / "Move to Setlist X"
  • When deleting a song from the library: warn if referenced in other setlists
  • Songs remain in library; setlists hold references (song IDs + order)
  • Band Sync: sync active setlist selection to viewers (new sync event)

Implementation

  • New IndexedDB store setlists with schema { id, name, items: SetlistItem[], isDefault: boolean }
  • DB version bump (7 → 8) with migration: wrap existing songOrder/setlistEntries config values into a default setlist entry
  • Consider extracting useSetlistStore from useSongStore (currently manages songOrder + setlistEntries)
  • Dropdown component: plain <select> or custom Tailwind dropdown, no external UI library
  • New multi-setlist export format: { setlists: [{ name, items[] }, ...], songs: [...] }
  • Backward-compatible import: detect old single-setlist format and auto-migrate
  • Add setlist:switch event to syncProtocol.ts

Decisions

  • Dedicated IndexedDB store over config key-value: setlists are a first-class entity with their own lifecycle, not a setting
  • Export format designed to be forward-compatible with future Gig-level grouping (Gig wraps multiple setlist IDs) — no breaking change needed later
  • useSetlistStore extraction keeps domain separation clean per CONVENTIONS.md (one store per domain)

Out of Scope

  • Gig-level grouping (separate issue once multi-setlist is stable)
  • Setlist sharing between devices outside of Band Sync
  • Setlist templates/presets

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions