mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-27 21:05:53 +00:00
4.23.2
* 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:
parent
2a57ecb8a7
commit
ce38c3c251
10 changed files with 80 additions and 59 deletions
8
package-lock.json
generated
8
package-lock.json
generated
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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.',
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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 = {
|
||||
'#-?[\\\\/]': '#-/',
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue