diff --git a/package.json b/package.json
index 0f479ec2..4df08c37 100755
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "frankerfacez",
"author": "Dan Salvato LLC",
- "version": "4.23.0",
+ "version": "4.23.1",
"description": "FrankerFaceZ is a Twitch enhancement suite.",
"private": true,
"license": "Apache-2.0",
diff --git a/src/modules/chat/badges.jsx b/src/modules/chat/badges.jsx
index d6d1fbbe..586093ea 100644
--- a/src/modules/chat/badges.jsx
+++ b/src/modules/chat/badges.jsx
@@ -294,6 +294,7 @@ export default class Badges extends Module {
getSettingsBadges(include_addons, callback) {
const twitch = [],
+ other = [],
owl = [],
tcon = [],
game = [],
@@ -333,7 +334,9 @@ export default class Badges extends Module {
if ( v ) {
let cat;
- if ( badge.__cat === 'm-owl' )
+ if ( badge.__cat === 'm-other' )
+ cat = other;
+ else if ( badge.__cat === 'm-owl' )
cat = owl;
else if ( badge.__cat === 'm-tcon' )
cat = tcon;
@@ -382,6 +385,7 @@ export default class Badges extends Module {
return [
{title: 'Twitch', id: 'm-twitch', badges: twitch},
{title: 'Twitch: TwitchCon', id: 'm-tcon', badges: tcon},
+ {title: 'Twitch: Other', id: 'm-other', badges: other},
{title: 'Twitch: Overwatch League', id: 'm-owl', badges: owl},
{title: 'Twitch: Game', id: 'm-game', key: 'game', badges: game},
{title: 'FrankerFaceZ', id: 'm-ffz', badges: ffz},
@@ -1148,10 +1152,22 @@ export default class Badges extends Module {
}
+const OTHER_BADGES = [
+ 'vga-champ-2017',
+ 'warcraft',
+ 'samusoffer_beta',
+ 'power-rangers',
+ 'bits-charity',
+ 'glhf-pledge'
+];
+
+
export function getBadgeCategory(key) {
- if ( key.startsWith('overwatch-league') )
+ if ( OTHER_BADGES.includes(key) )
+ return 'm-other';
+ else if ( key.startsWith('overwatch-league') )
return 'm-owl';
- else if ( key.startsWith('twitchcon') )
+ else if ( key.startsWith('twitchcon') || key.startsWith('glitchcon') )
return 'm-tcon';
else if ( /_\d+$/.test(key) )
return 'm-game';
diff --git a/src/modules/chat/emoji.js b/src/modules/chat/emoji.js
index 89888ec1..f8520c0c 100644
--- a/src/modules/chat/emoji.js
+++ b/src/modules/chat/emoji.js
@@ -100,6 +100,8 @@ export default class Emoji extends Module {
// For some reason, splitter is a function.
this.splitter = splitter();
+ this.categories = CATEGORIES;
+
this.emoji = {};
this.names = {};
this.chars = new Map;
diff --git a/src/modules/chat/emotes.js b/src/modules/chat/emotes.js
index 377bec14..0bbfa1f6 100644
--- a/src/modules/chat/emotes.js
+++ b/src/modules/chat/emotes.js
@@ -57,7 +57,6 @@ const MODIFIERS = {
};
-
export default class Emotes extends Module {
constructor(...args) {
super(...args);
@@ -636,30 +635,42 @@ export default class Emotes extends Module {
// ========================================================================
addDefaultSet(provider, set_id, data) {
- let changed = false;
+ if ( typeof set_id === 'number' )
+ set_id = `${set_id}`;
+
+ let changed = false, added = false;
if ( ! this.default_sets.sourceIncludes(provider, set_id) ) {
+ changed = ! this.default_sets.includes(set_id);
this.default_sets.push(provider, set_id);
- this.refSet(set_id);
- changed = true;
+ added = true;
}
if ( data )
this.loadSetData(set_id, data);
- if ( changed )
+ if ( changed ) {
+ this.refSet(set_id);
this.emit(':update-default-sets', provider, set_id, true);
+ }
+
+ return added;
}
removeDefaultSet(provider, set_id) {
- let changed = false;
+ if ( typeof set_id === 'number' )
+ set_id = `${set_id}`;
+
if ( this.default_sets.sourceIncludes(provider, set_id) ) {
this.default_sets.remove(provider, set_id);
- this.unrefSet(set_id);
- changed = true;
+ if ( ! this.default_sets.includes(set_id) ) {
+ this.unrefSet(set_id);
+ this.emit(':update-default-sets', provider, set_id, false);
+ }
+
+ return true;
}
- if ( changed )
- this.emit(':update-default-sets', provider, set_id, false);
+ return false;
}
refSet(set_id) {
@@ -668,7 +679,6 @@ export default class Emotes extends Module {
clearTimeout(this._set_timers[set_id]);
this._set_timers[set_id] = null;
}
-
}
unrefSet(set_id) {
@@ -885,6 +895,11 @@ export default class Emotes extends Module {
this.log.info(`Loaded emote set #${set_id}: ${data.title} (${count} emotes)`);
this.emit(':loaded', set_id, data);
+
+ // Don't let people endlessly load unused sets.
+ const refs = this._set_refs[set_id] || 0;
+ if ( refs <= 0 && ! this._set_timers[set_id] )
+ this._set_timers[set_id] = setTimeout(() => this.unloadSet(set_id), 5000);
}
@@ -904,6 +919,11 @@ export default class Emotes extends Module {
if ( ! suppress_log )
this.log.info(`Unloaded emote set #${set_id}: ${old_set.title}`);
+ if ( this._set_timers[set_id] ) {
+ clearTimeout(this._set_timers[set_id]);
+ this._set_timers[set_id] = null;
+ }
+
this.emit(':unloaded', set_id, old_set);
this.emote_sets[set_id] = null;
}
diff --git a/src/modules/chat/room.js b/src/modules/chat/room.js
index 9340c509..59b6eb4d 100644
--- a/src/modules/chat/room.js
+++ b/src/modules/chat/room.js
@@ -306,13 +306,10 @@ export default class Room {
this.data = d;
- if ( d.set ) {
- if ( ! this.emote_sets )
- this.emote_sets = new SourcedSet;
- this.emote_sets.set('main', d.set);
- } else if ( this.emote_sets )
- this.emote_sets.delete('main');
-
+ if ( d.set )
+ this.addSet('main', d.set);
+ else
+ this.removeAllSets('main');
if ( data.sets )
for(const set_id in data.sets)
@@ -349,29 +346,59 @@ export default class Room {
if ( ! this.emote_sets )
this.emote_sets = new SourcedSet;
- let changed = false;
+ if ( typeof set_id === 'number' )
+ set_id = `${set_id}`;
+
+ let changed = false, added = false;
if ( ! this.emote_sets.sourceIncludes(provider, set_id) ) {
+ changed = ! this.emote_sets.includes(set_id);
this.emote_sets.push(provider, set_id);
- this.manager.emotes.refSet(set_id);
- changed = true;
+ added = true;
}
if ( data )
this.manager.emotes.loadSetData(set_id, data);
- if ( changed )
+ if ( changed ) {
+ this.manager.emotes.refSet(set_id);
this.manager.emotes.emit(':update-room-sets', this, provider, set_id, true);
+ }
+
+ return added;
+ }
+
+ removeAllSets(provider) {
+ if ( this.destroyed || ! this.emote_sets )
+ return false;
+
+ const sets = this.emote_sets.get(provider);
+ if ( ! Array.isArray(sets) || ! sets.length )
+ return false;
+
+ for(const set_id of sets)
+ this.removeSet(provider, set_id);
+
+ return true;
}
removeSet(provider, set_id) {
if ( this.destroyed || ! this.emote_sets )
return;
+ if ( typeof set_id === 'number' )
+ set_id = `${set_id}`;
+
if ( this.emote_sets.sourceIncludes(provider, set_id) ) {
this.emote_sets.remove(provider, set_id);
- this.manager.emotes.unrefSet(set_id);
- this.manager.emotes.emit(':update-room-sets', this, provider, set_id, false);
+ if ( ! this.emote_sets.includes(set_id) ) {
+ this.manager.emotes.unrefSet(set_id);
+ this.manager.emotes.emit(':update-room-sets', this, provider, set_id, false);
+ }
+
+ return true;
}
+
+ return false;
}
diff --git a/src/modules/chat/user.js b/src/modules/chat/user.js
index 6f71b40c..5a1569a2 100644
--- a/src/modules/chat/user.js
+++ b/src/modules/chat/user.js
@@ -106,6 +106,9 @@ export default class User {
if ( this.destroyed )
return;
+ if ( typeof badge_id === 'number' )
+ badge_id = `${badge_id}`;
+
if ( data )
data.id = badge_id;
else
@@ -132,7 +135,7 @@ export default class User {
return null;
for(const badge of this.badges._cache)
- if ( badge.id == badge_id )
+ if ( badge.id == badge_id )
return badge;
}
@@ -155,29 +158,64 @@ export default class User {
// Emote Sets
// ========================================================================
- addSet(provider, set_id) {
+ addSet(provider, set_id, data) {
if ( this.destroyed )
return;
if ( ! this.emote_sets )
this.emote_sets = new SourcedSet;
+ if ( typeof set_id === 'number' )
+ set_id = `${set_id}`;
+
+ let changed = false, added = false;
if ( ! this.emote_sets.sourceIncludes(provider, set_id) ) {
+ changed = ! this.emote_sets.includes(set_id);
this.emote_sets.push(provider, set_id);
+ added = true;
+ }
+
+ if ( data )
+ this.manager.emotes.loadSetData(set_id, data);
+
+ if ( changed ) {
this.manager.emotes.refSet(set_id);
this.manager.emotes.emit(':update-user-sets', this, provider, set_id, true);
- return true;
}
+
+ return added;
+ }
+
+ removeAllSets(provider) {
+ if ( this.destroyed || ! this.emote_sets )
+ return false;
+
+ const sets = this.emote_sets.get(provider);
+ if ( ! Array.isArray(sets) || ! sets.length )
+ return false;
+
+ for(const set_id of sets)
+ this.removeSet(provider, set_id);
+
+ return true;
}
removeSet(provider, set_id) {
if ( this.destroyed || ! this.emote_sets )
return;
+ if ( typeof set_id === 'number' )
+ set_id = `${set_id}`;
+
if ( this.emote_sets.sourceIncludes(provider, set_id) ) {
this.emote_sets.remove(provider, set_id);
- this.manager.emotes.unrefSet(set_id);
- this.manager.emotes.emit(':update-user-sets', this, provider, set_id, false);
+ if ( ! this.emote_sets.includes(set_id) ) {
+ this.manager.emotes.unrefSet(set_id);
+ this.manager.emotes.emit(':update-user-sets', this, provider, set_id, false);
+ }
+ return true;
}
+
+ return false;
}
}
\ No newline at end of file
diff --git a/src/modules/main_menu/components/badge-visibility.vue b/src/modules/main_menu/components/badge-visibility.vue
index 2af08f72..49b53203 100644
--- a/src/modules/main_menu/components/badge-visibility.vue
+++ b/src/modules/main_menu/components/badge-visibility.vue
@@ -32,7 +32,7 @@