Skip to content

Commit

Permalink
4.48.0
Browse files Browse the repository at this point in the history
* Fixed: The `/ffz reload` command is now `/ffz:reload` to remove an undesirable behavior with Twitch's completion handling when backspacing.
* Fixed: Spaces being included in links when they shouldn't be.
* Fixed: Previews of emotes in chat when typing their names directly.
* Changed: Initial work on tracking the audio/video de-sync when using audio APIs for the compressor. This appears as a value in the stream latency metadata tool-tip, but currently drifts whenever the player is paused.
* Changed: Initial work on allowing the extension to be loaded from a bundled extension.
* API Changed: The load tracker now returns a list of reported loading keys when firing events.
  • Loading branch information
SirStendec committed May 19, 2023
1 parent 67c64e6 commit 109898a
Show file tree
Hide file tree
Showing 13 changed files with 120 additions and 35 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ module.exports = {
'__version_minor__': false,
'__version_patch__': false,
'__version_prerelease__': false,
'__extension__': false,
'FrankerFaceZ': false
},
'rules': {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "frankerfacez",
"author": "Dan Salvato LLC",
"version": "4.47.1",
"version": "4.48.0",
"description": "FrankerFaceZ is a Twitch enhancement suite.",
"private": true,
"license": "Apache-2.0",
Expand Down
33 changes: 19 additions & 14 deletions src/addons.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// ============================================================================

import Module from 'utilities/module';
import { SERVER } from 'utilities/constants';
import { EXTENSION, SERVER_OR_EXT } from 'utilities/constants';
import { createElement } from 'utilities/dom';
import { timeout, has } from 'utilities/object';
import { getBuster } from 'utilities/time';
Expand Down Expand Up @@ -69,15 +69,16 @@ export default class AddonManager extends Module {
off: (...args) => this.off(...args)
});

this.settings.add('addons.dev.server', {
default: false,
ui: {
path: 'Add-Ons >> Development',
title: 'Use Local Development Server',
description: 'Attempt to load add-ons from local development server on port 8001.',
component: 'setting-check-box'
}
});
if ( ! EXTENSION )
this.settings.add('addons.dev.server', {
default: false,
ui: {
path: 'Add-Ons >> Development',
title: 'Use Local Development Server',
description: 'Attempt to load add-ons from local development server on port 8001.',
component: 'setting-check-box'
}
});

this.on('i18n:update', this.rebuildAddonSearch, this);

Expand Down Expand Up @@ -151,9 +152,13 @@ export default class AddonManager extends Module {

async loadAddonData() {
const [cdn_data, local_data] = await Promise.all([
fetchJSON(`${SERVER}/script/addons.json?_=${getBuster(30)}`),
this.settings.get('addons.dev.server') ?
fetchJSON(`https://localhost:8001/script/addons.json?_=${getBuster()}`) : null
fetchJSON(`${SERVER_OR_EXT}/addons.json?_=${getBuster(30)}`),

// Do not attempt to load local add-ons if using the extension, as
// loading external code is against the policy of basically everyone.
(! EXTENSION && this.settings.get('addons.dev.server'))
? fetchJSON(`https://localhost:8001/script/addons.json?_=${getBuster()}`)
: null
]);

if ( Array.isArray(cdn_data) )
Expand Down Expand Up @@ -469,7 +474,7 @@ export default class AddonManager extends Module {
document.head.appendChild(createElement('script', {
id: `ffz-loaded-addon-${addon.id}`,
type: 'text/javascript',
src: addon.src || `${addon.dev ? 'https://localhost:8001' : SERVER}/script/addons/${addon.id}/script.js?_=${getBuster(30)}`,
src: addon.src || `${addon.dev ? 'https://localhost:8001/script' : SERVER_OR_EXT}/addons/${addon.id}/script.js?_=${getBuster(30)}`,
crossorigin: 'anonymous'
}));

Expand Down
25 changes: 25 additions & 0 deletions src/entry_ext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* eslint strict: off */
'use strict';
(() => {
// Don't run on certain sub-domains.
if ( /^(?:localhost\.rig|blog|im|chatdepot|tmi|api|brand|dev|gql|passport)\./.test(location.hostname) )
return;

const HOST = location.hostname,
SERVER = __EXTENSION_PATH__,
script = document.createElement('script');

let FLAVOR =
HOST.includes('player') ? 'player' :
HOST.includes('clips') ? 'clips' :
(location.pathname === '/p/ffz_bridge/' ? 'bridge' : 'avalon');

if (FLAVOR === 'clips' && location.pathname === '/embed')
FLAVOR = 'player';

script.id = 'ffz-script';
script.async = true;
script.crossOrigin = 'anonymous';
script.src = `${SERVER}/${FLAVOR}.js?_=${Date.now()}`;
document.head.appendChild(script);
})();
6 changes: 4 additions & 2 deletions src/load_tracker.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,11 @@ export default class LoadTracker extends Module {
data.success = true;

if ( ! data.pending.size ) {
this.log.debug('complete', type, Object.keys(data.timers));
const keys = Object.keys(data.timers);

this.log.debug('complete', type, keys);
if ( data.success )
this.emit(`:complete:${type}`);
this.emit(`:complete:${type}`, keys);
this.pending_loads.delete(type);
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/modules/chat/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1271,7 +1271,7 @@ export default class Chat extends Module {

this.on('chat:get-tab-commands', event => {
event.commands.push({
name: 'ffz reload',
name: 'ffz:reload',
description: this.i18n.t('chat.command.reload', 'Reload FFZ and add-on chat data (emotes, badges, etc.)'),
permissionLevel: 0,
ffz_group: 'FrankerFaceZ'
Expand All @@ -1292,11 +1292,11 @@ export default class Chat extends Module {
this.emit('chat:reload-data');
});

this.on('load_tracker:complete:chat-data', () => {
this.on('load_tracker:complete:chat-data', (list) => {
if ( this.triggered_reload ) {
const sc = this.resolve('site.chat');
if ( sc?.addNotice )
sc.addNotice('*', this.i18n.t('chat.command.reload.done', 'FFZ has finished reloading data.'));
sc.addNotice('*', this.i18n.t('chat.command.reload.done', 'FFZ has finished reloading data. (Sources: {list})', {list: list.join(', ')}));
}

this.triggered_reload = false;
Expand Down
2 changes: 1 addition & 1 deletion src/modules/chat/tokenizers.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const SHRINK_X = MODIFIER_FLAGS.ShrinkX,
const EMOTE_CLASS = 'chat-image chat-line__message--emote',
//WHITESPACE = /^\s*$/,
//LINK_REGEX = /([^\w@#%\-+=:~])?((?:(https?:\/\/)?(?:[\w@#%\-+=:~]+\.)+[a-z]{2,6}(?:\/[\w./@#%&()\-+=:?~]*)?))([^\w./@#%&()\-+=:?~]|\s|$)/g,
NEW_LINK_REGEX = /(?:(https?:\/\/)?((?:[\w#%\-+=:~]+\.)+[a-z]{2,10}(?:\/[\w./#%&@()\-+=:?~]*[^\.!,?])?))/g,
NEW_LINK_REGEX = /(?:(https?:\/\/)?((?:[\w#%\-+=:~]+\.)+[a-z]{2,10}(?:\/[\w./#%&@()\-+=:?~]*[^\s\.!,?])?))/g,
//OLD_NEW_LINK_REGEX = /(?:(https?:\/\/)?((?:[\w#%\-+=:~]+\.)+[a-z]{2,10}(?:\/[\w./#%&@()\-+=:?~]*)?))/g,
//MENTION_REGEX = /([^\w@#%\-+=:~])?(@([^\u0000-\u007F]+|\w+)+)([^\w./@#%&()\-+=:?~]|\s|$)/g; // eslint-disable-line no-control-regex
MENTION_REGEX = /^(['"*([{<\\/]*)(@)((?:[^\u0000-\u007F]|[\w-])+)(?:\b|$)/; // eslint-disable-line no-control-regex
Expand Down
16 changes: 16 additions & 0 deletions src/modules/metadata.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,12 @@ export default class Metadata extends Module {
}
}

// Get the video element.
const video = maybe_call(player.getHTMLVideoElement, player);
stats.avOffset = 0;
if ( video?._ffz_context )
stats.avOffset = (video._ffz_context_offset ?? 0) + video._ffz_context.currentTime - video.currentTime;

let tampered = false;
try {
const url = player.core.state.path;
Expand Down Expand Up @@ -493,6 +499,14 @@ export default class Metadata extends Module {
stats
);

const desync = data.avOffset !== 0
? (<div>{this.i18n.t(
'metadata.player-stats.av-offset',
'A/V Offset: {avOffset, number} seconds',
stats
)}</div>)
: null;

if ( data.old )
return [
delayed,
Expand All @@ -510,6 +524,7 @@ export default class Metadata extends Module {
<div class="tw-pd-t-05">
{video_info}
</div>,
desync,
tampered
];

Expand All @@ -522,6 +537,7 @@ export default class Metadata extends Module {
<div class="tw-pd-t-05">
{video_info}
</div>,
desync,
tampered
];
}
Expand Down
4 changes: 2 additions & 2 deletions src/sites/twitch-twilight/modules/chat/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2227,7 +2227,7 @@ export default class ChatHook extends Module {
inst.sendMessage = function(msg, extra) {
msg = msg.replace(/\s+/g, ' ');

if ( msg.startsWith('/ffz') ) {
if ( msg.startsWith('/ffz:') ) {
msg = msg.slice(5).trim();
const idx = msg.indexOf(' ');
let subcmd;
Expand Down Expand Up @@ -2258,7 +2258,7 @@ export default class ChatHook extends Module {
else
inst.addMessage({
type: t.chat_types.Notice,
message: t.i18n.t('chat.ffz-command.invalid', 'No such command: /ffz {subcmd}', {subcmd})
message: t.i18n.t('chat.ffz-command.invalid', 'No such command: /ffz:{subcmd}', {subcmd})
});

return false;
Expand Down
15 changes: 13 additions & 2 deletions src/sites/twitch-twilight/modules/chat/input.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -402,13 +402,24 @@ export default class Input extends Module {
}

checkForPreviews(inst, node) {
for(const el of node.querySelectorAll?.('span[data-a-target="chat-input-emote-preview"][aria-describedby]') ?? []) {
// We can't find the tooltip element directly (without digging into React tree at least)
// So instead just find the relevant images in the document. This shouldn't happen TOO
// frequently, with any luck, so the performance impact should be small.
if ( node.querySelector?.('span[data-a-target="chat-input-emote-preview"]') ) {
for(const target of document.querySelectorAll('.tw-tooltip-layer img.chat-line__message--emote')) {
if ( target && target.src.startsWith('https://static-cdn.jtvnw.net/emoticons/v2/__FFZ__') )
this.updatePreview(inst, target);
}
}

// This no longer works because they removed aria-describedby
/*for(const el of node.querySelectorAll?.('span[data-a-target="chat-input-emote-preview"][aria-describedby]') ?? []) {
const cont = document.getElementById(el.getAttribute('aria-describedby')),
target = cont && cont.querySelector('img.chat-line__message--emote');
if ( target && target.src.startsWith('https://static-cdn.jtvnw.net/emoticons/v2/__FFZ__') )
this.updatePreview(inst, target);
}
}*/

for(const target of node.querySelectorAll?.('img.chat-line__message--emote')) {
if ( target && (target.dataset.ffzId || target.src.startsWith('https://static-cdn.jtvnw.net/emoticons/v2/__FFZ__')) )
Expand Down
4 changes: 4 additions & 0 deletions src/utilities/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import {make_enum} from 'utilities/object';


export const DEBUG = localStorage.ffzDebugMode === 'true' && document.body.classList.contains('ffz-dev');
export const EXTENSION = document.body.classList.contains('ffz-ext') && !!__extension__;
export const SERVER = DEBUG ? '//localhost:8000' : 'https://cdn.frankerfacez.com';
export const SERVER_OR_EXT = EXTENSION
? __extension__
: `${SERVER}/script`;

export const CLIENT_ID = 'a3bc9znoz6vi8ozsoca0inlcr4fcvkl';
export const API_SERVER = '//api.frankerfacez.com';
Expand Down
22 changes: 17 additions & 5 deletions webpack.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const VueLoaderPlugin = require('vue-loader/lib/plugin');

const VERSION = semver.parse(require('./package.json').version);
const PRODUCTION = process.env.NODE_ENV === 'production';
const FOR_EXTENSION = !! process.env.FFZ_EXTENSION;

const ENTRY_POINTS = {
bridge: './src/bridge.js',
Expand Down Expand Up @@ -36,7 +37,9 @@ module.exports = {
}
],
output: {
chunkFilename: '[name].[chunkhash].js',
chunkFilename: FOR_EXTENSION
? '[name].js'
: '[name].[chunkhash].js',
path: path.resolve(__dirname, 'dist'),
jsonpFunction: 'ffzWebpackJsonp',
crossOriginLoading: 'anonymous'
Expand All @@ -58,7 +61,10 @@ module.exports = {
__version_major__: VERSION.major,
__version_minor__: VERSION.minor,
__version_patch__: VERSION.patch,
__version_prerelease__: VERSION.prerelease
__version_prerelease__: VERSION.prerelease,
__extension__: FOR_EXTENSION
? JSON.stringify(process.env.FFZ_EXTENSION)
: false
}),
],
module: {
Expand All @@ -67,7 +73,9 @@ module.exports = {
use: [{
loader: 'file-loader',
options: {
name: PRODUCTION ? '[name].[hash].css' : '[name].css'
name: (! FOR_EXTENSION && PRODUCTION)
? '[name].[hash].css'
: '[name].css'
}
}, {
loader: 'extract-loader'
Expand All @@ -89,7 +97,9 @@ module.exports = {
type: 'javascript/auto',
loader: 'file-loader',
options: {
name: PRODUCTION ? '[name].[hash].json' : '[name].json'
name: (! FOR_EXTENSION && PRODUCTION)
? '[name].[hash].json'
: '[name].json'
}
},
{
Expand Down Expand Up @@ -123,7 +133,9 @@ module.exports = {
use: [{
loader: 'file-loader',
options: {
name: PRODUCTION ? '[name].[hash].[ext]' : '[name].[ext]'
name: (! FOR_EXTENSION && PRODUCTION)
? '[name].[hash].[ext]'
: '[name].[ext]'
}
}]
},
Expand Down
19 changes: 14 additions & 5 deletions webpack.web.prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ const Terser = require('terser');
// Get Git info

const commit_hash = require('child_process').execSync('git rev-parse HEAD').toString().trim();
const FOR_EXTENSION = !! process.env.FFZ_EXTENSION;

/* global module Buffer */

const minifier = content => {
const text = content.toString('utf8');
let text = content.toString('utf8');
if ( FOR_EXTENSION )
text = text.replace('__EXTENSION_PATH__', JSON.stringify(process.env.FFZ_EXTENSION));
const minified = Terser.minify(text);
return (minified && minified.code) ? Buffer.from(minified.code) : content;
return (minified && minified.code) ? Buffer.from(minified.code) : Buffer.from(text);
};

module.exports = merge(common, {
Expand All @@ -45,7 +48,9 @@ module.exports = merge(common, {
}),
new CopyPlugin([
{
from: './src/entry.js',
from: FOR_EXTENSION
? './src/entry_ext.js'
: './src/entry.js',
to: 'script.min.js',
transform: minifier
}
Expand All @@ -62,7 +67,11 @@ module.exports = merge(common, {
],

output: {
publicPath: '//cdn.frankerfacez.com/static/',
filename: '[name].[hash].js'
publicPath: FOR_EXTENSION
? process.env.FFZ_EXTENSION
: '//cdn.frankerfacez.com/static/',
filename: FOR_EXTENSION
? '[name].js'
: '[name].[hash].js'
}
});

0 comments on commit 109898a

Please sign in to comment.