mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-27 21:05:53 +00:00
4.70.0
* Added: Option to prevent Pinned Messages from being displayed. Closes #1470 * Removed: Setting to allow the Golden Kappa Train to appear. This wasn't working correctly, so nothing of value has been lost. * Fixed: Blocking chat users by username worked inconsistently. * Fixed: Hiding channels in the directory by title worked inconsistently. Closes #1473 * API Changed: The `chat:get-tab-commands` event now has a `channel` object with the ID and login of the current channel, as well as a reference to the relevant input component. * API Added: The `chat` module now has `addTabCommandPrefix(prefix: string | string[])` and `removeTabCommandPrefix(prefix: string | string[])` methods. By default, tab-completion for chat commands only triggers with the `/` and `!` prefix for performance reasons. This can be used to add additional prefix characters.
This commit is contained in:
parent
8807e09ea3
commit
10d35468a9
6 changed files with 104 additions and 33 deletions
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "frankerfacez",
|
||||
"author": "Dan Salvato LLC",
|
||||
"version": "4.69.0",
|
||||
"version": "4.70.0",
|
||||
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
||||
"private": true,
|
||||
"license": "Apache-2.0",
|
||||
|
|
|
@ -11,7 +11,7 @@ import Module, { buildAddonProxy } from 'utilities/module';
|
|||
import {Color} from 'utilities/color';
|
||||
import {createElement, ManagedStyle} from 'utilities/dom';
|
||||
import {getFontsList} from 'utilities/fonts';
|
||||
import {timeout, has, addWordSeparators, glob_to_regex, escape_regex, split_chars, makeAddonIdChecker, deep_copy} from 'utilities/object';
|
||||
import {timeout, has, addWordSeparators, glob_to_regex, escape_regex, split_chars, makeAddonIdChecker, deep_copy, SourcedSet} from 'utilities/object';
|
||||
|
||||
import Badges from './badges';
|
||||
import Emotes from './emotes';
|
||||
|
@ -93,6 +93,9 @@ export default class Chat extends Module {
|
|||
|
||||
this.context = this.settings.context({});
|
||||
|
||||
this.CommandPrefixes = new SourcedSet(true);
|
||||
this.CommandPrefixes.set('ffz', ['/', '!']);
|
||||
|
||||
this.rooms = {};
|
||||
this.users = {};
|
||||
|
||||
|
@ -614,7 +617,7 @@ export default class Chat extends Module {
|
|||
if ( ! data.length )
|
||||
return null;
|
||||
|
||||
return new RegExp(`^(?:${data.join('|')})$`, 'gi');
|
||||
return new RegExp(`^(?:${data.join('|')})$`, 'i');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -1414,6 +1417,24 @@ export default class Chat extends Module {
|
|||
);
|
||||
}
|
||||
|
||||
overrides.addTabCommandPrefix = (prefix, provider = null) => {
|
||||
if ( provider == null )
|
||||
provider = addon_id;
|
||||
if ( is_dev && provider !== addon_id )
|
||||
module.log.warn('[DEV-CHECK] Used addTabCommandPrefix with incorrect provider.');
|
||||
|
||||
return this.addTabCommandPrefix(prefix, provider);
|
||||
}
|
||||
|
||||
overrides.removeTabCommandPrefix = (prefix, provider = null) => {
|
||||
if ( provider == null )
|
||||
provider = addon_id;
|
||||
if ( is_dev && provider !== addon_id )
|
||||
module.log.warn('[DEV-CHECK] Used removeTabCommandPrefix with incorrect provider.');
|
||||
|
||||
return this.removeTabCommandPrefix(prefix, provider);
|
||||
}
|
||||
|
||||
overrides.addTokenizer = tokenizer => {
|
||||
if ( tokenizer )
|
||||
tokenizer.__source = addon_id;
|
||||
|
@ -1580,6 +1601,8 @@ export default class Chat extends Module {
|
|||
}
|
||||
}
|
||||
|
||||
this.CommandPrefixes.delete(addon_id);
|
||||
|
||||
for(const item of this.iterateAllRoomsAndUsers())
|
||||
removed += item._unloadAddon(addon_id) ?? 0;
|
||||
|
||||
|
@ -2305,6 +2328,26 @@ export default class Chat extends Module {
|
|||
return Object.values(this._hl_reasons);
|
||||
}
|
||||
|
||||
addTabCommandPrefix(prefix, source = 'ffz') {
|
||||
if ( ! Array.isArray(prefix) )
|
||||
prefix = [prefix];
|
||||
|
||||
for(const item of prefix) {
|
||||
if ( typeof item !== 'string' || item.length !== 1 )
|
||||
throw new Error('Invalid command prefix. Must be string of length 1.');
|
||||
|
||||
this.CommandPrefixes.push(source, item);
|
||||
}
|
||||
}
|
||||
|
||||
removeTabCommandPrefix(prefix, source = 'ffz') {
|
||||
if ( ! Array.isArray(prefix) )
|
||||
prefix = [prefix];
|
||||
|
||||
for(const item of prefix)
|
||||
this.CommandPrefixes.remove(source, item);
|
||||
}
|
||||
|
||||
addTokenizer(tokenizer) {
|
||||
const type = tokenizer.type;
|
||||
if ( has(this.tokenizers, type) ) {
|
||||
|
|
|
@ -461,7 +461,7 @@ export default class ChatHook extends Module {
|
|||
}
|
||||
});
|
||||
|
||||
this.settings.add('chat.banners.kappa-train', {
|
||||
/*this.settings.add('chat.banners.kappa-train', {
|
||||
default: false,
|
||||
ui: {
|
||||
path: 'Chat > Appearance >> Community',
|
||||
|
@ -469,6 +469,15 @@ export default class ChatHook extends Module {
|
|||
description: '**Note**: This setting is currently theoretical and may not work, or may cause non-Kappa hype trains to appear. Due to the infrequent nature of hype trains, and especially the golden kappa hype train, it is very hard to test.',
|
||||
component: 'setting-check-box'
|
||||
}
|
||||
});*/
|
||||
|
||||
this.settings.add('chat.banners.pinned-message', {
|
||||
default: true,
|
||||
ui: {
|
||||
path: 'Chat > Appearance >> Community',
|
||||
title: 'Allow Pinned Messages to be displayed in chat.',
|
||||
component: 'setting-check-box'
|
||||
}
|
||||
});
|
||||
|
||||
this.settings.add('chat.banners.drops', {
|
||||
|
@ -1042,6 +1051,7 @@ export default class ChatHook extends Module {
|
|||
this.chat.context.on('changed:chat.banners.polls', this.cleanHighlights, this);
|
||||
this.chat.context.on('changed:chat.banners.prediction', this.cleanHighlights, this);
|
||||
this.chat.context.on('changed:chat.banners.drops', this.cleanHighlights, this);
|
||||
this.chat.context.on('changed:chat.banners.pinned-message', this.cleanHighlights, this);
|
||||
|
||||
this.chat.context.on('changed:chat.disable-handling', this.updateDisableHandling, this);
|
||||
|
||||
|
@ -1722,6 +1732,7 @@ export default class ChatHook extends Module {
|
|||
'hype_train': this.chat.context.get('chat.banners.hype-train'),
|
||||
'prediction': this.chat.context.get('chat.banners.prediction'),
|
||||
'poll': this.chat.context.get('chat.banners.polls'),
|
||||
'pinned_chat': this.chat.context.get('chat.banners.pinned-message'),
|
||||
'mw-drop-available': this.chat.context.get('chat.banners.drops')
|
||||
};
|
||||
|
||||
|
@ -1736,8 +1747,8 @@ export default class ChatHook extends Module {
|
|||
const type = entry.event.type;
|
||||
if ( type && has(types, type) && ! types[type] ) {
|
||||
// Attempt to allow Golden Kappa hype trains?
|
||||
if ( type === 'hype_train' && entry.event.typeDetails === '0' && this.chat.context.get('chat.banners.kappa-train') )
|
||||
continue;
|
||||
//if ( type === 'hype_train' && entry.event.typeDetails === '0' && this.chat.context.get('chat.banners.kappa-train') )
|
||||
// continue;
|
||||
|
||||
this.log.info('Removing community highlight: ', type, '#', entry.id);
|
||||
this.community_dispatch({
|
||||
|
|
|
@ -7,15 +7,11 @@
|
|||
import Module from 'utilities/module';
|
||||
import { findReactFragment } from 'utilities/dom';
|
||||
|
||||
import { getTwitchEmoteSrcSet } from 'utilities/object';
|
||||
import { SourcedSet, getTwitchEmoteSrcSet } from 'utilities/object';
|
||||
import { TWITCH_POINTS_SETS, TWITCH_GLOBAL_SETS, TWITCH_PRIME_SETS, KNOWN_CODES, REPLACEMENTS, REPLACEMENT_BASE, KEYS } from 'utilities/constants';
|
||||
|
||||
import Twilight from 'site';
|
||||
|
||||
const COMMAND_KEYS = [
|
||||
'!',
|
||||
'/'
|
||||
];
|
||||
|
||||
// Prefer using these statically-allocated collators to String.localeCompare
|
||||
const locale = Intl.Collator();
|
||||
|
@ -75,7 +71,6 @@ export default class Input extends Module {
|
|||
this.inject('site.fine');
|
||||
this.inject('site');
|
||||
|
||||
|
||||
// Settings
|
||||
|
||||
this.settings.add('chat.hype.display-input', {
|
||||
|
@ -783,7 +778,7 @@ export default class Input extends Module {
|
|||
|
||||
inst.getMatches = function(input, unknown, index) {
|
||||
try {
|
||||
return index === 0 && COMMAND_KEYS.includes(input[0])
|
||||
return index === 0 && t.chat.CommandPrefixes.includes(input[0])
|
||||
? inst.getCommands(input) : null;
|
||||
|
||||
} catch(err) {
|
||||
|
@ -797,11 +792,22 @@ export default class Input extends Module {
|
|||
isEditor: inst.props.isCurrentUserEditor
|
||||
});
|
||||
|
||||
// Get the parent-input so we can do stuff.
|
||||
const parent = t.fine.searchParent(inst,
|
||||
n => n?.props?.channelID && n?.props?.setTray, 50);
|
||||
|
||||
const event = t.makeEvent({
|
||||
input,
|
||||
permissionLevel: inst.props.permissionLevel,
|
||||
isEditor: inst.props.isCurrentUserEditor,
|
||||
commands
|
||||
commands,
|
||||
|
||||
// Extra details, if we managed to find our parent.
|
||||
__input: parent,
|
||||
channel: parent ? {
|
||||
id: parent.props.channelID,
|
||||
login: parent.props.channelLogin
|
||||
} : null
|
||||
});
|
||||
|
||||
t.emit('chat:get-tab-commands', event);
|
||||
|
|
|
@ -616,17 +616,17 @@ export default class Directory extends Module {
|
|||
// Are we getting a clip, a video, or a stream?
|
||||
if ( props.slug ) {
|
||||
// Clip
|
||||
console.log('need flags for clip', props.slug);
|
||||
//console.log('need flags for clip', props.slug);
|
||||
el._ffz_flags = [];
|
||||
|
||||
} else if ( props.vodID ) {
|
||||
// Video
|
||||
console.log('need flags for vod', props.vodID);
|
||||
//console.log('need flags for vod', props.vodID);
|
||||
el._ffz_flags = [];
|
||||
|
||||
} else {
|
||||
// Stream?
|
||||
console.log('need flags for stream', props.channelLogin);
|
||||
//console.log('need flags for stream', props.channelLogin);
|
||||
this.twitch_data.getStreamFlags(null, props.channelLogin).then(data => {
|
||||
el._ffz_flags = data ?? [];
|
||||
this.updateCard(el);
|
||||
|
@ -670,11 +670,15 @@ export default class Directory extends Module {
|
|||
}
|
||||
if ( ! should_blur ) {
|
||||
const regexes = this.settings.get('__filter:directory.blur-titles');
|
||||
if ( regexes &&
|
||||
(( regexes[0] && regexes[0].test(props.title) ) ||
|
||||
( regexes[1] && regexes[1].test(props.title) ))
|
||||
)
|
||||
should_blur = true;
|
||||
if ( regexes ) {
|
||||
if ( regexes[0] )
|
||||
regexes[0].lastIndex = -1;
|
||||
if ( regexes[1] )
|
||||
regexes[1].lastIndex = -1;
|
||||
|
||||
if (( regexes[0] && regexes[0].test(props.title) ) || ( regexes[1] && regexes[1].test(props.title) ))
|
||||
should_blur = true;
|
||||
}
|
||||
}
|
||||
|
||||
el.classList.toggle('ffz-hide-thumbnail', should_blur);
|
||||
|
@ -700,11 +704,15 @@ export default class Directory extends Module {
|
|||
|
||||
if ( ! should_hide ) {
|
||||
const regexes = this.settings.get('__filter:directory.block-titles');
|
||||
if ( regexes &&
|
||||
(( regexes[0] && regexes[0].test(props.title) ) ||
|
||||
( regexes[1] && regexes[1].test(props.title) ))
|
||||
)
|
||||
should_hide = true;
|
||||
if ( regexes ) {
|
||||
if ( regexes[0] )
|
||||
regexes[0].lastIndex = -1;
|
||||
if ( regexes[1] )
|
||||
regexes[1].lastIndex = -1;
|
||||
|
||||
if (( regexes[0] && regexes[0].test(props.title) ) || ( regexes[1] && regexes[1].test(props.title) ))
|
||||
should_hide = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -385,11 +385,14 @@ export default class Layout extends Module {
|
|||
else {
|
||||
const regexes = this.settings.get('__filter:directory.block-titles');
|
||||
const title = stream?.broadcaster?.broadcastSettings?.title;
|
||||
if ( regexes && title &&
|
||||
(( regexes[0] && regexes[0].test(title) ) ||
|
||||
( regexes[1] && regexes[1].test(title) ))
|
||||
)
|
||||
should_hide = true;
|
||||
if ( regexes && title ) {
|
||||
if ( regexes[0] )
|
||||
regexes[0].lastIndex = -1;
|
||||
if ( regexes[1] )
|
||||
regexes[1].lastIndex = -1;
|
||||
if ( (regexes[0] && regexes[0].test(title)) || (regexes[1] && regexes[1].test(title)) )
|
||||
should_hide = true;
|
||||
}
|
||||
}
|
||||
|
||||
card.classList.toggle('ffz--side-nav-card-rerun', rerun);
|
||||
|
@ -421,4 +424,4 @@ export default class Layout extends Module {
|
|||
updatePortraitMode() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue