crabidy/architecture
Test User 001abcc35c queue: de-duplicate and sort the queue, server-side
Two verbs that rewrite what the queue already holds instead of adding to
it: DedupQueue and SortQueue, on the playback loop, for every client.
Client-side was the tempting shortcut and the wrong one — a
client-computed Remove races the resolve stream, and "sorting" as a
Replace of paths re-resolves everything through providers and restarts
playback at the head.

A duplicate is the same provider item id *scoped to its provider* (the
content store keys content the same way, so unscoped ids let two
providers' numeric ids collide), or the whole path when a provider
reports no id. Deliberately not artist+title: identical metadata is
routinely a different recording, and a wrong merge is unrecoverable
queue state. Within a group the playing entry survives, else the
earliest — "keep the first" stops the music whenever the playing copy is
a later one — and the removal itself goes through remove_tracks, so one
code path maintains play_order.

Sorting permutes `tracks` and then treats the play order by mode: with
shuffle off it rebuilds it as the identity with the cursor on the current
track (the sort decides what plays next), with shuffle on it remaps it
through the permutation so the shuffled sequence and the position in it
survive. Five stable strategies (artist→album, album, title, duration,
reverse), keys built once per track, unknown sorting last in both
directions, and UNSPECIFIED refused as InvalidArgument.

DedupQueue answers with a count, alone among the queue verbs: 0 cannot be
recovered from the new snapshot and is what a user needs to hear. It
crosses as a number — the wording is each client's. TUI: `u` and a modal
`S` sort menu whose unclaimed keys are swallowed, plus the count in the
queue pane title. Web: the same keys, clickable menu rows, toolbar
buttons, count in a toast. CLI: `queue dedup` and `queue sort <key>
[--desc]` with the strategy as a ValueEnum.

Full dev-flow: architecture/queue-order.md, quality/queue-order.md,
plan/queue-order.md, plan/summary.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 21:50:17 +02:00
..
audiobookshelf-provider.md Architecture: audiobookshelf (`/abs`) provider design 2026-07-23 23:09:54 +02:00
bookmarks.md Design the crabidy content store; add wire + fsdy foundations 2026-07-22 10:58:11 +02:00
build-features.md nix, opus: let the packager choose where libopus comes from 2026-07-28 00:24:03 +02:00
capture-deletion.md Design the crabidy content store; add wire + fsdy foundations 2026-07-22 10:58:11 +02:00
captures.md Design the crabidy content store; add wire + fsdy foundations 2026-07-22 10:58:11 +02:00
cbd-bundle.md Give cbd its own config file, separate from cbd-tui 2026-07-21 22:57:43 +02:00
cli.md Design a comprehensive clap-derive CLI (architecture/cli.md) 2026-07-22 11:45:05 +02:00
client-configs.md Give cbd its own config file, separate from cbd-tui 2026-07-21 22:57:43 +02:00
crabidy-store.md Let a same-source W re-capture replace its save in place 2026-07-22 22:35:48 +02:00
fs-provider.md Persist queues as fs-provider folders 2026-07-21 10:41:49 +02:00
fyyd-provider.md Add the fyyd podcast provider (/fyyd) 2026-07-23 17:29:13 +02:00
help-modal.md Add a help modal to cbd-tui behind a declarative binding table 2026-07-20 17:27:12 +02:00
incremental-captures.md Capture local files by copying them; add W to capture the queue 2026-07-22 01:08:29 +02:00
jamendo-provider.md jamendo: send a User-Agent (Jamendo returns empty results without one) 2026-07-24 15:54:31 +02:00
mpris.md cbd-tui: speak MPRIS, so the media keys reach the server 2026-07-28 01:27:28 +02:00
node-editing.md Add rename and delete for modifiable library nodes 2026-07-20 23:34:47 +02:00
orphans.md Add the /orphans provider: a store garbage-collection view 2026-07-22 22:47:23 +02:00
overview.md Document the as-built architecture 2026-07-20 10:34:45 +02:00
progressive-queueing.md Playback: retry the start when a skipped/short head runs the player dry 2026-07-23 19:55:18 +02:00
queue-order.md queue: de-duplicate and sort the queue, server-side 2026-07-29 21:50:17 +02:00
queue-persistence.md Capture library subtrees as bookmarks 2026-07-21 11:11:27 +02:00
queue-register.md cbd-tui: queue marks, visual mode, and a paste register 2026-07-26 10:24:51 +02:00
roles-auth.md Web client: prompt for login on visit when auth is enabled 2026-07-23 17:51:55 +02:00
rss-provider.md architecture: design the /rss subscription provider 2026-07-26 12:19:23 +02:00
search.md Add Tidal search as creatable library nodes 2026-07-20 17:58:44 +02:00
seek.md seek: put seek and track-skip on two keys, and make the web gauge clickable 2026-07-26 14:29:30 +02:00
soundcloud-provider.md soundcloud: prefer the progressive mp3 stream (HLS exchange 404s anonymously) 2026-07-24 02:47:13 +02:00
spectrum.md Add a server-streamed frequency spectrum visualizer 2026-07-21 23:14:03 +02:00
tui-search.md Add a / search filter to the TUI library and queue panes 2026-07-21 22:54:39 +02:00
visual-mode.md cbd-tui: fix visual mode stranding the turnaround row (anchor the range) 2026-07-24 16:29:26 +02:00
web-client.md Web client: prompt for login on visit when auth is enabled 2026-07-23 17:51:55 +02:00
youtube-provider.md Replace the yt-dlp subprocess with the pure-Rust rustypipe client 2026-07-21 17:12:40 +02:00
youtube-rustypipe.md Fetch streams in bounded windows and restore yt-dlp for stream URLs 2026-07-21 18:18:40 +02:00