1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-27 21:05:53 +00:00
* Changed: Animated Emotes is now set to Enabled by default, to reflect the vanilla Twitch experience.
* Fixed: Native animated emotes not appearing with animation.
* Fixed: Typo in the tooltip for Playback Statistics metadata.
* Maintenance: Update the `@ffz/icu-msgparser` dependency.
This commit is contained in:
SirStendec 2021-06-17 14:27:04 -04:00
parent 2a57ecb8a7
commit ce38c3c251
10 changed files with 80 additions and 59 deletions

8
package-lock.json generated
View file

@ -1,6 +1,6 @@
{
"name": "frankerfacez",
"version": "4.22.9",
"version": "4.23.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -580,9 +580,9 @@
}
},
"@ffz/icu-msgparser": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@ffz/icu-msgparser/-/icu-msgparser-1.0.2.tgz",
"integrity": "sha512-LTtWOQ4fftxcC7Z86u9LTi1eZ4X07hQH5yvcURlYSpVTaY9dXXE/h5BdtJB0TIk7FkSiAuN/3sRkfHD0u3+S7Q=="
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@ffz/icu-msgparser/-/icu-msgparser-2.0.0.tgz",
"integrity": "sha512-VYohS74qsdjZl9KMMlpHIKVGDVFy6kktz/rtvZgfWyngKiqJalHqfdhnQ9meu1hCFQZnTUNi+PUe5xoVAZgYGg=="
},
"@npmcli/move-file": {
"version": "1.0.1",

View file

@ -1,7 +1,7 @@
{
"name": "frankerfacez",
"author": "Dan Salvato LLC",
"version": "4.23.1",
"version": "4.23.2",
"description": "FrankerFaceZ is a Twitch enhancement suite.",
"private": true,
"license": "Apache-2.0",
@ -67,7 +67,7 @@
"url": "https://github.com/FrankerFaceZ/FrankerFaceZ.git"
},
"dependencies": {
"@ffz/icu-msgparser": "^1.0.2",
"@ffz/icu-msgparser": "^2.0.0",
"chartjs": "^0.3.24",
"chartjs-plugin-waterfall": "^1.0.3",
"chartjs-plugin-zoom": "^0.7.7",

View file

@ -1079,30 +1079,12 @@ export default class Chat extends Module {
});
this.settings.add('chat.emotes.animated', {
requires: ['context.bttv.gifs'],
default: null,
process(ctx, val) {
if ( val == null ) {
const temp = ctx.get('ffzap.betterttv.gif_emoticons_mode');
if ( temp == null )
val = ctx.get('context.bttv.gifs') ? 1 : 0;
else
val = temp === 2 ? 1 : 0;
}
return val;
},
default: 1,
ui: {
path: 'Chat > Appearance >> Emotes',
sort: -50,
title: 'Animated Emotes',
default(ctx) {
const temp = ctx.get('ffzap.betterttv.gif_emoticons_mode');
if ( temp == null )
return ctx.get('context.bttv.gifs') ? 1 : 0;
return temp === 2 ? 1 : 0;
},
getExtraTerms: () => GIF_TERMS,
description: 'This controls whether or not animated emotes are allowed to play in chat. When this is `Disabled`, emotes will appear as static images. Setting this to `Enable on Hover` may cause performance issues.',

View file

@ -5,9 +5,9 @@
// ============================================================================
import {sanitize, createElement} from 'utilities/dom';
import {has, split_chars} from 'utilities/object';
import {has, getTwitchEmoteURL, split_chars, getTwitchEmoteSrcSet} from 'utilities/object';
import {TWITCH_EMOTE_BASE, EmoteTypes, REPLACEMENT_BASE, REPLACEMENTS} from 'utilities/constants';
import {EmoteTypes, REPLACEMENT_BASE, REPLACEMENTS} from 'utilities/constants';
import {CATEGORIES} from './emoji';
@ -1328,7 +1328,7 @@ export const AddonEmotes = {
const set_id = hide_source ? null : await this.emotes.getTwitchEmoteSet(emote_id),
emote_set = set_id != null && await this.emotes.getTwitchSetChannel(set_id);
preview = `${TWITCH_EMOTE_BASE}${ds.id}/3.0?_=preview`;
preview = `${getTwitchEmoteURL(ds.id, 4, true, true)}?_=preview`;
fav_source = 'twitch';
if ( emote_set ) {
@ -1641,6 +1641,7 @@ export const TwitchEmotes = {
return tokens;
const data = msg.ffz_emotes,
anim = this.context.get('chat.emotes.animated'),
big = this.context.get('chat.emotes.2x'),
use_replacements = this.context.get('chat.fix-bad-emotes'),
emotes = [];
@ -1713,8 +1714,8 @@ export const TwitchEmotes = {
text: text.slice(idx - t_start, e_start - t_start).join('')
});
let src, srcSet;
let src2, srcSet2;
let src, srcSet, animSrc, animSrcSet;
let src2, srcSet2, animSrc2, animSrcSet2;
let can_big = true;
const replacement = REPLACEMENTS[e_id];
@ -1724,12 +1725,22 @@ export const TwitchEmotes = {
can_big = false;
} else {
src = `${TWITCH_EMOTE_BASE}${e_id}/1.0`;
srcSet = `${TWITCH_EMOTE_BASE}${e_id}/1.0 1x, ${TWITCH_EMOTE_BASE}${e_id}/2.0 2x`;
src = getTwitchEmoteURL(e_id, 1, false);
srcSet = getTwitchEmoteSrcSet(e_id, false);
if ( anim > 0 ) {
animSrc = getTwitchEmoteURL(e_id, 1, true);
animSrcSet = getTwitchEmoteSrcSet(e_id, true);
}
if ( big ) {
src2 = `${TWITCH_EMOTE_BASE}${e_id}/2.0`;
srcSet2 = `${TWITCH_EMOTE_BASE}${e_id}/2.0 1x, ${TWITCH_EMOTE_BASE}${e_id}/3.0 2x`;
src2 = getTwitchEmoteURL(e_id, 2, false);
srcSet2 = getTwitchEmoteSrcSet(e_id, false, true, true);
if ( anim > 0 ) {
animSrc2 = getTwitchEmoteURL(e_id, 2, true);
animSrcSet2 = getTwitchEmoteSrcSet(e_id, true, true, true);
}
}
}
@ -1741,6 +1752,11 @@ export const TwitchEmotes = {
srcSet,
src2,
srcSet2,
animSrc,
animSrc2,
animSrcSet,
animSrcSet2,
anim,
big,
can_big,
height: 28, // Not always accurate but close enough.

View file

@ -461,7 +461,7 @@ export default class Metadata extends Module {
const stats = data.stats,
video_info = this.i18n.t(
'metadata.player-stats.video-info',
'Video: {videoResolution}p{fps}\nPlayback Rate: {playbackRate,number} Kbps\nDropped Frames:{skippedFrames,number}',
'Video: {videoResolution}p{fps}\nPlayback Rate: {playbackRate, number} Kbps\nDropped Frames: {skippedFrames, number}',
stats
);

View file

@ -4,8 +4,8 @@
// Chat Emote Menu
// ============================================================================
import {has, get, once, maybe_call, set_equals} from 'utilities/object';
import {TWITCH_GLOBAL_SETS, EmoteTypes, TWITCH_POINTS_SETS, TWITCH_PRIME_SETS, WEBKIT_CSS as WEBKIT, IS_OSX, KNOWN_CODES, TWITCH_EMOTE_BASE, REPLACEMENT_BASE, REPLACEMENTS, KEYS} from 'utilities/constants';
import {has, get, once, maybe_call, set_equals, getTwitchEmoteURL, getTwitchEmoteSrcSet} from 'utilities/object';
import {TWITCH_GLOBAL_SETS, EmoteTypes, TWITCH_POINTS_SETS, TWITCH_PRIME_SETS, WEBKIT_CSS as WEBKIT, IS_OSX, KNOWN_CODES, REPLACEMENT_BASE, REPLACEMENTS, KEYS} from 'utilities/constants';
import {HIDDEN_CATEGORIES, CATEGORIES, CATEGORY_SORT, IMAGE_PATHS} from 'src/modules/chat/emoji';
import {ClickOutside} from 'utilities/dom';
@ -639,8 +639,8 @@ export default class EmoteMenu extends Module {
this.props.stopObserving(this.ref);
}
keyInteract(code) {
keyInteract(code) { // eslint-disable-line
/* no-op */
}
clickEmote(event) {
@ -1855,14 +1855,16 @@ export default class EmoteMenu extends Module {
overridden = mapped && mapped.id != new_id,
replacement = REPLACEMENTS[new_id];
let src, srcSet;
let src, srcSet, animSrc, animSrcSet;
if ( replacement && t.chat.context.get('chat.fix-bad-emotes') )
src = `${REPLACEMENT_BASE}${replacement}`;
else {
const base = `${TWITCH_EMOTE_BASE}${new_id}`;
src = `${base}/1.0`;
srcSet = `${src} 1x, ${base}/2.0 2x`
src = getTwitchEmoteURL(new_id, 1, false);
srcSet = getTwitchEmoteSrcSet(new_id, false);
animSrc = getTwitchEmoteURL(new_id, 1, true);
animSrcSet = getTwitchEmoteSrcSet(new_id, true);
}
const em = {
@ -1872,6 +1874,8 @@ export default class EmoteMenu extends Module {
name: new_name,
src,
srcSet,
animSrc,
animSrcSet,
order: order++,
overridden: overridden ? mapped.id : null,
misc: ! chan,
@ -1967,7 +1971,6 @@ export default class EmoteMenu extends Module {
continue;
const id = emote.id,
base = `${TWITCH_EMOTE_BASE}${id}`,
name = KNOWN_CODES[emote.token] || emote.token,
seen = twitch_seen.has(id),
is_fav = twitch_favorites.includes(id);
@ -1979,8 +1982,10 @@ export default class EmoteMenu extends Module {
name,
order: order++,
locked: locked && ! seen,
src: `${base}/1.0`,
srcSet: `${base}/1.0 1x, ${base}/2.0 2x`,
src: getTwitchEmoteURL(id, 1, false),
srcSet: getTwitchEmoteSrcSet(id, false),
animSrc: getTwitchEmoteURL(id, 1, true),
animSrcSet: getTwitchEmoteSrcSet(id, true),
favorite: is_fav,
hidden: twitch_hidden.includes(id)
};
@ -2024,8 +2029,7 @@ export default class EmoteMenu extends Module {
emotes: new Set([emote.id])
}
const base = `${TWITCH_EMOTE_BASE}${id}`,
is_fav = twitch_favorites.includes(id);
const is_fav = twitch_favorites.includes(id);
/*if ( Array.isArray(emote.modifiers) && emote.modifiers.length )
modifiers[id] = emote.modifiers;*/
@ -2037,8 +2041,10 @@ export default class EmoteMenu extends Module {
name: emote.token,
locked,
order: order++,
src: `${base}/1.0`,
srcSet: `${base}/1.0 1x, ${base}/2.0 2x`,
src: getTwitchEmoteURL(id, 1, false),
srcSet: getTwitchEmoteSrcSet(id, false),
animSrc: getTwitchEmoteURL(id, 1, true),
animSrcSet: getTwitchEmoteSrcSet(id, true),
bits: true,
bit_value: summary.threshold,
favorite: is_fav,

View file

@ -6,10 +6,11 @@
import Module from 'utilities/module';
import { findReactFragment } from 'utilities/dom';
import { TWITCH_POINTS_SETS, TWITCH_GLOBAL_SETS, TWITCH_PRIME_SETS, KNOWN_CODES, REPLACEMENTS, REPLACEMENT_BASE, TWITCH_EMOTE_BASE, KEYS } from 'utilities/constants';
import { TWITCH_POINTS_SETS, TWITCH_GLOBAL_SETS, TWITCH_PRIME_SETS, KNOWN_CODES, REPLACEMENTS, REPLACEMENT_BASE, KEYS } from 'utilities/constants';
import Twilight from 'site';
import { FFZEvent } from 'src/utilities/events';
import { getTwitchEmoteSrcSet, getTwitchEmoteURL } from 'src/utilities/object';
export default class Input extends Module {
constructor(...args) {
@ -623,15 +624,13 @@ export default class Input extends Module {
continue;
const replacement = REPLACEMENTS[id];
let src, srcSet;
let srcSet, animSrcSet;
if ( replacement && this.chat.context.get('chat.fix-bad-emotes') ) {
src = `${REPLACEMENT_BASE}${replacement}`;
srcSet = `${src} 1x`;
srcSet = `${REPLACEMENT_BASE}${replacement} 1x`;
} else {
const base = `${TWITCH_EMOTE_BASE}${id}`;
src = `${base}/1.0`;
srcSet = `${src} 1x, ${base}/2.0 2x`
srcSet = getTwitchEmoteSrcSet(id, false);
animSrcSet = getTwitchEmoteSrcSet(id, true);
}
out.push({
@ -642,6 +641,7 @@ export default class Input extends Module {
token,
tokenLower: token.toLowerCase(),
srcSet,
animSrcSet,
favorite: favorites.includes(id)
});
}

View file

@ -55,6 +55,7 @@ export const KEYS = {
export const TWITCH_EMOTE_BASE = '//static-cdn.jtvnw.net/emoticons/v1/';
export const TWITCH_EMOTE_V2 = '//static-cdn.jtvnw.net/emoticons/v2';
export const KNOWN_CODES = {
'#-?[\\\\/]': '#-/',

View file

@ -1,9 +1,20 @@
'use strict';
import {BAD_HOTKEYS} from 'utilities/constants';
import {BAD_HOTKEYS, TWITCH_EMOTE_V2} from 'utilities/constants';
const HOP = Object.prototype.hasOwnProperty;
export function getTwitchEmoteURL(id, scale, animated = false, dark = true) {
return `${TWITCH_EMOTE_V2}/${id}/${animated ? 'default' : 'static'}/${dark ? 'dark' : 'light'}/${scale}.0`
}
export function getTwitchEmoteSrcSet(id, animated = false, dark = true, big = false) {
if ( big )
return `${getTwitchEmoteURL(id, 2, animated, dark)} 1x, ${getTwitchEmoteURL(id, 4, animated, dark)} 2x`;
return `${getTwitchEmoteURL(id, 1, animated, dark)} 1x, ${getTwitchEmoteURL(id, 2, animated, dark)} 2x, ${getTwitchEmoteURL(id, 4, animated, dark)} 4x`;
}
export function isValidShortcut(key) {
if ( ! key )
return false;

View file

@ -12,6 +12,11 @@ dayjs.extend(RelativeTime);
import Parser from '@ffz/icu-msgparser';
const DEFAULT_PARSER_OPTIONS = {
allowTags: false,
requireOther: false
};
import {get} from 'utilities/object';
import {duration_to_string} from 'utilities/time';
@ -217,7 +222,7 @@ export default class TranslationCore {
this.formats[key] = Object.assign({}, this.formats[key], options.formats[key]);
this.types = Object.assign({}, DEFAULT_TYPES, options.types || {});
this.parser = new Parser(options.parserOptions);
this.parser = new Parser(Object.assign({}, DEFAULT_PARSER_OPTIONS, options.parserOptions));
if ( options.phrases )
this.extend(options.phrases);