TrySound / TrySound/libras

Add synchronized server-backed playlists

Open
#16 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
9
Forks
0
Avg merge
12h 12m
Merged PRs (30d)
24

Description

Goal

Add server-backed playlists synchronized through the Subsonic-compatible API, with account-scoped local caching and offline browsing.

Favorites are explicitly out of scope.

Initial scope

  • List accessible playlists and show playlist metadata and ordered tracks.
  • Create, rename, and delete editable playlists.
  • Add/remove track occurrences and reorder tracks, preserving duplicates.
  • Play a playlist or add its tracks to the playback queue.
  • Cache playlist summaries and previously loaded playlist contents for offline browsing; only downloaded tracks are playable offline. Fetch details on opening a playlist. Distinguish contents not fetched from an empty playlist; fetching all playlist contents for comprehensive offline availability is outside the initial scope.
  • Require connectivity for edits in the initial version. Durable offline editing is a follow-up, not an implied guarantee.
  • Refresh on startup, manual refresh, and playlist opening as appropriate. Surface loading, save failures, and stale data without discarding cached content.

Server API and capabilities

Use the portable Subsonic baseline:

  • getPlaylists: list accessible playlists.
  • getPlaylist: read metadata and ordered entries.
  • createPlaylist: create a playlist, or replace an existing sequence using playlistId and repeated songId parameters.
  • updatePlaylist: rename/change metadata, append with songIdToAdd, remove occurrences with songIndexToRemove.
  • deletePlaylist: delete a playlist.

There is no portable move operation; reorder by replacing the full sequence. Accessible/public playlists are not necessarily editable. Respect ownership and server permissions, handle unsupported actions, and verify behavior against Navidrome and supported Subsonic/OpenSubsonic implementations. Public visibility is separate from anonymous share links.

Smart-playlist rule editing, provider-specific collaboration, and share-link management are out of scope. Server-generated playlists may be readable without editable membership; do not assume all exposed playlists support writes.

Architecture

  • src/subsonic-client.ts: endpoint methods and response validation, including repeated parameters.
  • src/network.svelte.ts: normalized playlist operations and connection-scoped capabilities; keep protocol mapping here.
  • src/schema.ts: playlist metadata and ordered entry types. Entries represent occurrences rather than using track IDs as unique row identities.
  • src/cache.svelte.ts: use the current memory-first CheckpointStore for an independent account-scoped playlist document, separate from library and queue data. Include it in load(), flush(), dirty, and aggregated errors; do not introduce persist-before-publish semantics.
  • New playlist engine: independent refresh, serialized server-confirmed online editing, reconciliation, and errors. Show pending mutations, then publish confirmed results into the memory-first cache; avoid optimistic rollback/outbox machinery in v1.
  • src/session.svelte.ts: restoration, capability attachment/detachment, cancellation, and refresh coordination.
  • UI: playlist index/detail, management actions, add-to-playlist actions, reorder controls, and save/error states.

Extend the existing on-demand CoverEngine to resolve playlist artwork; do not persist artwork candidate indexes.

Cache playlist summaries separately from loaded details within the playlist domain. Preserve ordered track IDs and lightweight entry descriptions when library lookup fails. Do not feed playlist entries through whole-library normalization, which currently expects matching albums.

Playlist refresh is independent of the paginated search3 library traversal: the getIndexes library timestamp cannot establish playlist freshness.

Playing a playlist copies its sequence into the queue; later playlist edits must not unexpectedly change active playback. Preserve missing/unavailable track IDs rather than uploading a filtered sequence. Playlist sync must remain separate from downloading audio.

Synchronization safety

Subsonic does not provide a portable change stream, atomic conditional revision check, or idempotency keys for playlist creation/appends.

  • Serialize writes per playlist and protect local edits from stale responses.
  • Re-fetch/reconcile before writes where appropriate. Before destructive sequence replacement, detect changed remote contents and ask the user to reload or explicitly overwrite. Full merge/save-as-copy recovery can follow. A read-before-write check cannot eliminate all server races.
  • Separate server mutation success from local durability: an OPFS checkpoint failure after server success is a cache failure, not a reason to repeat creation/appending.
  • After an uncertain timeout, reconcile before retrying creation or append operations to avoid duplicates.
  • Abort obsolete work on disconnect/account switch and prevent late responses from updating another account cache.
  • Keep playlist failures independent from library refresh and playback.

Follow-up: durable offline editing

If offline edits are added, persist local mutations and a durable outbox together, retain a last-synchronized baseline, and support pending/error/conflict states, restart-safe retries, deletion records, and local-to-server ID mapping for new playlists.

Do not reuse the playback queue upload policy unchanged: its pending uploads are connection-scoped and lose eligibility on disconnect.

Acceptance criteria

  • CRUD and track ordering synchronize with the server and are visible in another compatible client after refresh.
  • Duplicate occurrences can be independently removed and reordered.
  • Read-only/unsupported actions fail gracefully without losing cached data.
  • Cached summaries and previously loaded playlist contents restore after a successful checkpoint and remain browsable offline. Unloaded contents are explicitly distinguished from empty playlists; offline editing is clearly unavailable in the initial version.
  • Playing/enqueuing a playlist preserves existing playback semantics.
  • Unavailable tracks are not silently deleted from playlists.
  • Tests cover protocol mapping, persistence failures, stale responses, account isolation, cancellation, conflicting edits, and uncertain write outcomes.
  • Verify playlist behavior against Navidrome and document any provider limitations.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the playlist-related responsibilities in src/subsonic-client.ts, src/network.svelte.ts, src/schema.ts, src/cache.svelte.ts, and src/session.svelte.ts, then trace the existing CheckpointStore and CoverEngine. Use the acceptance criteria to define coverage for protocol mapping, persistence failures, stale responses, account isolation, cancellation, conflicting edits, and uncertain writes. Done means CRUD, ordering, caching, offline browsing, playback, and graceful unsupported actions work across compatible servers without losing unavailable tracks.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, full-stack
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.