/** * The content script's decisions, kept apart from its DOM so the specs can * load them (test/chip.spec.js): which state the chip shows, what it says, * and what the Discord Add panel starts out proposing. * * `probe` is /api/extension/probe's answer; `platformName` is the display * name (PLATFORMS[key].name), passed in so this file needs no other lib. */ function chipState(probe) { if (!probe || probe.error) return 'new'; return ({ source_match: 'source-match', artist_match: 'artist-match', new: 'new' })[probe.state] || 'new'; } function chipLabel(probe, platformName) { if (!probe || probe.error) return '+ Add to FabledCurator'; const artist = probe.artist?.name || 'artist'; if (probe.platform === 'discord') { const d = probe.discord || {}; if (probe.state === 'source_match') { return probe.covered_by_server ? `✓ Whole server in FabledCurator · ${artist}` : `✓ In FabledCurator · ${artist}`; } // Every other Discord state opens the panel: the artist is always chosen. return d.channel_id ? `+ Add ${channelLabel(d)} to FabledCurator` : '+ Add server to FabledCurator'; } switch (probe.state) { case 'source_match': return `✓ In FabledCurator · ${platformName}`; case 'artist_match': return `+ Add ${platformName} source to ${artist}`; default: return '+ Add to FabledCurator'; } } /** `#name` when the probe could read it, else a neutral "this channel". */ function channelLabel(d) { return d.channel_name ? `#${d.channel_name}` : 'this channel'; } /** `name` when the probe could read it, else "this server". */ function serverLabel(d) { return d.server_name || 'this server'; } /** * What the Discord Add panel opens with. The channel is the default scope * when there is one: a server source walks every channel the token can read, * which is rarely what a single art channel wants. The artist is the probe's * suggestion (the owner of another source on this server), else a new artist * named after the server. */ function discordPanelDefaults(probe) { const d = probe?.discord || {}; const suggested = probe?.state === 'artist_match' && probe.artist ? probe.artist : null; return { scope: d.channel_id ? 'channel' : 'server', channelUrl: d.channel_url || null, serverUrl: d.server_url || null, artist: suggested ? { id: suggested.id, name: suggested.name } : null, artistName: suggested ? suggested.name : (d.server_name || ''), }; } /** * The quick-add body for the panel's current choice. A picked artist goes by * id — names can collide once slugified — and a typed name creates (or * finds) that artist. null when there is nothing valid to send. */ function discordAddRequest(choice) { const url = choice.scope === 'server' ? choice.serverUrl : choice.channelUrl; if (!url) return null; if (choice.artist && choice.artist.id != null && choice.artist.name === choice.artistName) { return { url, artistId: choice.artist.id }; } const name = (choice.artistName || '').trim(); return name ? { url, artistName: name } : null; }