Skip to content

Commit

Permalink
Rename duplicate emotes with a ~N number suffix (#597)
Browse files Browse the repository at this point in the history
* Rename duplicate emotes with a ~N number suffix

* Merge exact duplicates

* Fix dupe check
  • Loading branch information
goto-bus-stop committed Dec 1, 2023
1 parent 8029e95 commit 5deba04
Showing 1 changed file with 39 additions and 8 deletions.
47 changes: 39 additions & 8 deletions src/plugins/emotes.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,33 @@ const schema = JSON.parse(
* @typedef {{ name: string, url: URL }} Emote
*/

/**
* A Map of emote names to URLs.
*
* @augments {Map<string, URL>}
*/
class EmoteMap extends Map {
/**
* Add an emote to the map. If an emote with the same name already exists,
* this tries to add a numeric suffix to distinguish them.
*
* @param {Emote} emote
*/
insert(emote) {
const prevUrl = this.get(emote.name);
if (prevUrl && prevUrl.href !== emote.url.href) {
for (let i = 1; i < 20; i += 1) {
if (!this.has(`${emote.name}~${i}`)) {
this.set(`${emote.name}~${i}`, emote.url);
break;
}
}
} else {
this.set(emote.name, emote.url);
}
}
}

/**
* @template {object} T
* @param {URL|string} url
Expand Down Expand Up @@ -220,8 +247,7 @@ class Emotes {

#logger;

/** @type {Record<string, URL>} */
#emotes = Object.create(null);
#emotes = new EmoteMap();

#ready = Promise.resolve();

Expand All @@ -244,19 +270,25 @@ class Emotes {
this.#ready = this.#reloadEmotes();
}

/** Get all known emotes as an array. */
async getEmotes() {
await this.#ready;

return Object.entries(this.#emotes).map(([name, url]) => ({ name, url: url.toString() }));
const emotes = [];
for (const [name, url] of this.#emotes) {
emotes.push({ name, url: url.toString() });
}

return emotes;
}

/**
* @param {TwitchSettings} options
* @returns {Promise<Record<string, URL>>}
* @returns {Promise<EmoteMap>}
*/
async #loadTTVEmotes(options) {
if (!options.clientId || !options.clientSecret) {
return {};
return new EmoteMap();
}

const client = new ApiClient({
Expand Down Expand Up @@ -292,14 +324,13 @@ class Emotes {
promises.push(getSevenTVEmotes(channels));
}

/** @type {Record<string, URL>} */
const emotes = {};
const emotes = new EmoteMap();

const results = await Promise.allSettled(promises);
for (const result of results) {
if (result.status === 'fulfilled') {
for (const emote of result.value) {
emotes[emote.name] = emote.url;
emotes.insert(emote);
}
} else {
this.#logger.warn(result.reason);
Expand Down

0 comments on commit 5deba04

Please sign in to comment.