fix: artist page resolved "Flay!" to the far more popular "K.FLAY"
The Deezer artist match required only that every query word appear in the candidate name, so
"Flay!" (query word: flay) matched "K.FLAY" (words: k, flay). Sorted by fan count, K.FLAY
(54,822 fans) buried the real "Flay!" (39 fans) — the page showed K.FLAY's fans + top tracks.
Now prefer an EXACT normalized-name match ("flay" == "flay", not "kflay"), falling back to the
loose match only when there's no exact one. Web (detail.js) + Android (ArtistViewModel).
Verified against Deezer: exact match selects the real Flay! (id 12242284, whose top tracks
are actually Flay!). SW ns-v60.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
b3cf01dd3b
commit
e4f030c98d
3 files changed
+17
-8
No files matched your search
+8
-2
@@ -142,14 +142,20 @@ export async function loadArtistDetail(artist) {
|
||||
const [infoRes, topRes, iArtistRes, eventsRes] = await Promise.allSettled([infoP, topP, iArtistP, eventsP]);
|
||||
|
||||
const _normWords = s => new Set((s || '').toLowerCase().replace(/[^a-z0-9]/g, ' ').split(/\s+/).filter(Boolean));
|
||||
const _normName = s => (s || '').toLowerCase().replace(/[^a-z0-9]/g, '');
|
||||
const _queryWords = _normWords(artist.name);
|
||||
const _qNorm = _normName(artist.name);
|
||||
const iArtistResults = iArtistRes.status === 'fulfilled' ? (iArtistRes.value || []) : [];
|
||||
// Name-matching candidates, already ordered by fanCount (itunesSearch sorts musicArtist by nb_fan).
|
||||
const nameMatches = iArtistResults.filter(r => {
|
||||
// Prefer EXACT normalized-name matches. "Flay!" must not resolve to the far more popular "K.FLAY"
|
||||
// (whose name merely contains the word "flay") — exact "flay" == "flay" wins over "kflay". Only fall
|
||||
// back to the looser word-subset match when there's no exact match. Both lists are fan-sorted already.
|
||||
const exactMatches = iArtistResults.filter(r => _normName(r.artistName) === _qNorm);
|
||||
const looseMatches = iArtistResults.filter(r => {
|
||||
if (_queryWords.size === 0) return true;
|
||||
const rw = _normWords(r.artistName);
|
||||
return [..._queryWords].every(w => rw.has(w));
|
||||
});
|
||||
const nameMatches = exactMatches.length ? exactMatches : looseMatches;
|
||||
// Default pick = most popular name match (fixes "5× Joji": Deezer's order buries the real one).
|
||||
let iArtistMatch = nameMatches[0] || null;
|
||||
|
||||
|
||||
Reference in new issue
Block a user