diff options
Diffstat (limited to 'docs/musicbay.md')
| -rw-r--r-- | docs/musicbay.md | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/docs/musicbay.md b/docs/musicbay.md index 2ca8b23..d9794d2 100644 --- a/docs/musicbay.md +++ b/docs/musicbay.md @@ -434,6 +434,40 @@ actually implement (§3.2), not a property the protocol gives for free. | M5 | Gapless playback, crossfade, lyrics, waveform seek preview | Nice-to-haves, no architectural prerequisite from this plan either way | | M6 | Photos app | Out of scope of this document, per `apps.md`'s own list — unaffected by anything here | +## 9b. One album, not two, in the cross-group Search view (2026-09-02) + +Reported against Videos and true here by construction: an operator hosting two +groups that share one directory saw every track listed twice inside one album. +Inside a group it cannot happen (`GroupIndex` is keyed by blake3); the Search +page concatenates *N* indexes, and that is where the duplication is born. + +The fix is `source-merge.js`, applied identically to all three media views — +fold on the content hash, resolve **one source per unit**. For Music the unit +is an album, and a track loose enough to carry no artist at all is a unit of +its own (or it would be dropped from the merge entirely, since +`groupMusicEntries` never puts it in an album bucket). + +**`foldKey` is exported for this**, and the reason is worth keeping. §5.1's +grouping folds case and `&`/`and` for the *key* while keeping the first-seen +spelling for display — and which group is seen first is whichever index +happened to arrive first. Keying a merge unit on the display strings would +therefore let the chosen source change between page loads. The folded key is +the one grouping actually uses, and is stable. + +The units come from `groupMusicEntries` itself, called on the un-merged list +purely to learn them — never a second copy of its keys in the Search page. + +**The player needed no change.** `music-player.js` resolves a connection from +`entry.groupId` (§2.3), and a merged entry carries exactly one. The queue built +in `search-page.js`'s `onPreview` needed none either: it filters by `groupId` +and is reachable only from the Files explorer, which is deliberately *not* +merged — there each group is a folder and merging would remove a track from +one of them. + +Design and the adversary it names: `docs/refactoring-search.md`. +`test_search_media_merge.py` covers the album cases, including a differently- +cased tag not splitting the unit. + ## 10. Acceptance before shipping 1. Tag-coverage measurement against a real local library (not committed — |