Jev is offered a brand's icon only when its name is one of the Signal's words (#264)

Font Awesome's Mandalorian icon has "disney plus" among its search terms, the only icon with
"disney" in them, so a search for Disney Parks' words offered it and Jev picked a Star Wars helmet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-16 19:20:34 +00:00
parent 2ed8781604
commit 3e4d67fd2f
2 changed files with 12 additions and 1 deletions

View File

@@ -190,5 +190,12 @@ test('Jev is offered the icons found for each word of a Signal', () => {
]);
const ids = JSON.parse(run(`JSON.stringify(iconCandidates(${all}, 'AI Development', ['programming'], 'The tools', 40).map(c => c[0]))`));
assert.deepEqual(ids, ['solid/robot', 'solid/code'], 'each word its icons, "the" none');
const brands = JSON.stringify([
['brands/mandalorian', 'Mandalorian', 'disney plus helmet star wars'], ['brands/apple', 'Apple', 'fruit ios mac'],
['solid/fort-awesome', 'Fort', 'castle'], ['solid/apple-whole', 'Apple Whole', 'fruit'],
]);
const offered = q => JSON.parse(run(`JSON.stringify(iconCandidates(${brands}, ${JSON.stringify(q)}, [], null, 40).map(c => c[0]))`));
assert.deepEqual(offered('Disney castle'), ['solid/fort-awesome'], 'a brand only by its own name, never its search terms (#264)');
assert.deepEqual(offered('Apple'), ['brands/apple', 'solid/apple-whole']);
assert.equal(run(`signalCounts({items: 12, unread: 1})`), '12 items · 1 unread');
});

View File

@@ -258,8 +258,12 @@ const ICON_STOP=new Set(['the','and','for','not','with','about','their','own','f
function iconCandidates(all: [string,string,string][], name: string, keywords: string[], description: string|null, max=40){
const words=[name,...keywords,description||''].join(' ').toLowerCase().split(/[^a-z0-9]+/).filter(w=>w.length>1&&!ICON_STOP.has(w));
const out=new Map<string,string>();
// A brand's icon stands for that brand, so it is offered only when its name is one of the
// Signal's words: by its search terms, "disney" brought the Mandalorian, a Disney+ show (#264).
const brandFor=(id: string, w: string)=>!id.startsWith('brands/')||id.slice(7).split('-').includes(w);
for(const w of [...new Set(words)])
for(const [id,label,terms] of iconMatches(all,w,6)) if(out.size<max) out.set(id,`${label}: ${terms.split(' ').slice(0,8).join(', ')}`);
for(const [id,label,terms] of iconMatches(all.filter(([id])=>brandFor(id,w)),w,6))
if(out.size<max) out.set(id,`${label}: ${terms.split(' ').slice(0,8).join(', ')}`);
return [...out];
}
/// Jev's pick of an icon, on the server's TypeSafe key, or null with nothing to choose from.