diff options
| author | Adam Malczewski <[email protected]> | 2026-07-01 20:40:13 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-07-01 20:41:23 +0900 |
| commit | 7d2ee45ab5ac2a9bfff61125b216a7baef05dca5 (patch) | |
| tree | 387c64212729a7983d582480be0d382c654c1a08 | |
| parent | 8a0ed76b938d05336ae5c4a6232b5f00be00f273 (diff) | |
| download | yt-walkerman-7d2ee45ab5ac2a9bfff61125b216a7baef05dca5.tar.gz yt-walkerman-7d2ee45ab5ac2a9bfff61125b216a7baef05dca5.zip | |
fix: segment editor metadata search sends title-only query (artist hint was YouTube channel name → 0 MB results)
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | yt-music-dl-web/src/features/segment-editor/metadata.test.ts | 30 | ||||
| -rw-r--r-- | yt-music-dl-web/src/features/segment-editor/metadata.ts | 40 |
3 files changed, 39 insertions, 32 deletions
@@ -30,3 +30,4 @@ bin/yt-dlp.exe # Worktrees (per-feature) worktrees/ +.dispatch/ diff --git a/yt-music-dl-web/src/features/segment-editor/metadata.test.ts b/yt-music-dl-web/src/features/segment-editor/metadata.test.ts index 2f76303..b917195 100644 --- a/yt-music-dl-web/src/features/segment-editor/metadata.test.ts +++ b/yt-music-dl-web/src/features/segment-editor/metadata.test.ts @@ -165,25 +165,23 @@ describe("metadata search state machine (pure)", () => { // ─── request builders ──────────────────────────────────────────────────────── describe("buildRecordingSearch (pure)", () => { - it("uses the query when non-blank, segment artist as the hint", () => { + it("uses the query when non-blank; sends a title-only request (no artist hint)", () => { const s = seg("s1", "Chapter Title", "Seg Artist"); const req = buildRecordingSearch(s, "user query", "Global Artist"); - expect(req).toEqual({ query: "user query", artist: "Seg Artist", type: "recording" }); + expect(req).toEqual({ query: "user query", type: "recording" }); }); - it("falls back to the segment title when the query is blank", () => { + it("falls back to the segment title when the query is blank (no artist hint)", () => { const s = seg("s1", "Chapter Title", "Seg Artist"); const req = buildRecordingSearch(s, " ", "Global Artist"); - expect(req.query).toBe("Chapter Title"); - expect(req.artist).toBe("Seg Artist"); - expect(req.type).toBe("recording"); + expect(req).toEqual({ query: "Chapter Title", type: "recording" }); }); - it("falls back to the global artist when the segment artist is blank", () => { - const s = seg("s1", "Chapter Title", ""); + it("omits artist even when a segment artist is set (channel name, not a real artist)", () => { + const s = seg("s1", "Chapter Title", "Seg Artist"); const req = buildRecordingSearch(s, "", "Global Artist"); expect(req.query).toBe("Chapter Title"); - expect(req.artist).toBe("Global Artist"); + expect(req.artist).toBeUndefined(); }); it("omits artist when neither segment nor global artist is set", () => { @@ -202,20 +200,18 @@ describe("buildRecordingSearch (pure)", () => { }); describe("buildReleaseSearch (pure)", () => { - it("uses album + artist inputs when provided", () => { + it("uses the album input; sends an album-only request (no artist hint)", () => { const req = buildReleaseSearch("Dark Side", "Pink Floyd", "Global Album", "Global Artist"); - expect(req).toEqual({ query: "Dark Side", artist: "Pink Floyd", type: "release" }); + expect(req).toEqual({ query: "Dark Side", type: "release" }); }); - it("falls back to global album / global artist when inputs are blank", () => { + it("falls back to the global album when the album input is blank (no artist hint)", () => { const req = buildReleaseSearch(" ", "", "Global Album", "Global Artist"); - expect(req.query).toBe("Global Album"); - expect(req.artist).toBe("Global Artist"); - expect(req.type).toBe("release"); + expect(req).toEqual({ query: "Global Album", type: "release" }); }); - it("omits artist when neither input nor global artist is set", () => { - const req = buildReleaseSearch("Some Album", "", "", ""); + it("omits artist even when an artist input / global artist is set (channel name, not a real artist)", () => { + const req = buildReleaseSearch("Some Album", "Pink Floyd", "Global Album", "Global Artist"); expect(req.query).toBe("Some Album"); expect(req.artist).toBeUndefined(); expect(req.type).toBe("release"); diff --git a/yt-music-dl-web/src/features/segment-editor/metadata.ts b/yt-music-dl-web/src/features/segment-editor/metadata.ts index 914a28a..530893a 100644 --- a/yt-music-dl-web/src/features/segment-editor/metadata.ts +++ b/yt-music-dl-web/src/features/segment-editor/metadata.ts @@ -74,39 +74,49 @@ export function reduceSearch(state: SearchState, event: SearchEvent): SearchStat /** * Build the recording-search request for a segment's sidebar. `query` is the - * search-box text (falling back to the segment title when blank); `artist` is - * the segment's artist (falling back to the draft's global artist), omitted when - * neither is set. Mirrors the backend's `MetadataSearchRequest`. + * search-box text (falling back to the segment title when blank). The search is + * title-only — no artist hint is sent. For YouTube downloads the segment/global + * artist is the channel name (e.g. 'Official YouTube Channel'), which MusicBrainz + * has no artist for, so a Lucene `artist:"…" AND recording:"…"` query returns + * zero results. Mirrors the backend's `MetadataSearchRequest`. * - * Pure: (segment, query, globalArtist) → request. + * `globalArtist` is retained in the signature for backward compatibility (the + * caller still passes it) but is now unused. Pure: (segment, query, globalArtist) → request. */ export function buildRecordingSearch( segment: SegmentDraft, query: string, - globalArtist: string, + // Prefixed `_` to satisfy Biome's noUnusedFunctionParameters: retained in the + // signature for backward compatibility (the caller still passes it) but the + // artist hint is no longer sent — see the doc comment above. + _globalArtist: string, ): MetadataSearchRequest { const q = query.trim() || segment.title.trim(); - const artist = segment.artist.trim() || globalArtist.trim(); - // exactOptionalPropertyTypes: omit `artist` rather than set undefined. - return artist ? { query: q, artist, type: "recording" } : { query: q, type: "recording" }; + return { query: q, type: "recording" }; } /** * Build the release-search request for the "Match Album" dialog. `album` is the - * album-name search text (falling back to the global album); `artist` is the - * artist search text (falling back to the global artist), omitted when blank. + * album-name search text (falling back to the global album). The search is + * album-only — no artist hint is sent. For YouTube downloads the draft's global + * artist is the channel name, and the dialog prefills its artist box with it, so + * sending it as a Lucene `artist:"…"` hint yields zero MB release results. + * + * `artist` and `globalArtist` are retained in the signature for backward + * compatibility (the caller still passes them) but are now unused. * Pure: (album, artist, globalAlbum, globalArtist) → request. */ export function buildReleaseSearch( album: string, - artist: string, + // Prefixed `_` to satisfy Biome's noUnusedFunctionParameters: retained in the + // signature for backward compatibility (the caller still passes them) but the + // artist hint is no longer sent — see the doc comment above. + _artist: string, globalAlbum: string, - globalArtist: string, + _globalArtist: string, ): MetadataSearchRequest { const q = album.trim() || globalAlbum.trim(); - const a = artist.trim() || globalArtist.trim(); - // exactOptionalPropertyTypes: omit `artist` rather than set undefined. - return a ? { query: q, artist: a, type: "release" } : { query: q, type: "release" }; + return { query: q, type: "release" }; } // ─── Sidebar view-model (pure) ─────────────────────────────────────────────── |
