1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-27 21:05:53 +00:00
* Added: Setting to hide specific chat token types from rendering in chat, in case you for some reason don't want to see cheers / emotes / whatever.
* Added: Support for the Artist, No Audio, and No Video badges in different badge styles.

* API Added: The `site.player` module now exports CSS rules for the player control containers, so that FS Chat (and maybe other add-ons) won't need updates in the future if the CSS rule changes slightly.
This commit is contained in:
SirStendec 2022-08-02 16:59:50 -04:00
parent 168db52e2b
commit dd248838ad
9 changed files with 125 additions and 13 deletions

View file

@ -1,7 +1,7 @@
{
"name": "frankerfacez",
"author": "Dan Salvato LLC",
"version": "4.35.2",
"version": "4.36.0",
"description": "FrankerFaceZ is a Twitch enhancement suite.",
"private": true,
"license": "Apache-2.0",

View file

@ -44,7 +44,10 @@ const CSS_BADGES = {
turbo: { 1: { color: '#59399A' } },
premium: { 1: { color: '#00A0D6' } },
'anonymous-cheerer': { 1: { color: '#4B367C' } },
'clip-champ': { 1: { color: '#9146FF' } }
'clip-champ': { 1: { color: '#9146FF' } },
'artist-badge': { 1: { color: '#1e69ff' } },
'no_audio': { 1: { color: '#323239' } },
'no_video': { 1: { color: '#323239' } }
}
}

View file

@ -37,6 +37,10 @@ function sortPriorityColorTerms(list) {
const TERM_FLAGS = ['g', 'gi'];
const UNBLOCKABLE_TOKENS = [
'filter_test'
];
function formatTerms(data) {
const out = [];
@ -441,6 +445,29 @@ export default class Chat extends Module {
}
});
this.settings.add('chat.filtering.hidden-tokens', {
default: [],
type: 'array_merge',
always_inherit: true,
process(ctx, val) {
const out = new Set;
for(const v of val)
if ( v?.v || ! UNBLOCKABLE_TOKENS.includes(v.v) )
out.add(v.v);
return out;
},
ui: {
path: 'Chat > Appearance >> Hidden Token Types @{"description":"This filter allows you to prevent specific content token types from appearing chat messages, such as hiding all cheers or emotes."}',
component: 'blocked-types',
data: () => Object
.keys(this.tokenizers)
.filter(key => ! UNBLOCKABLE_TOKENS.includes(key) && this.tokenizers[key]?.render)
.sort()
}
});
this.settings.add('chat.filtering.highlight-basic-users', {
default: [],
type: 'array_merge',
@ -1978,12 +2005,14 @@ export default class Chat extends Module {
tokenizers = this.tokenizers,
l = tokens.length;
const hidden = this.context.get('chat.filtering.hidden-tokens');
for(let i=0; i < l; i++) {
const token = tokens[i],
type = token.type,
tk = tokenizers[type];
if ( token.hidden )
if ( token.hidden || hidden.has(type) )
continue;
let res;

View file

@ -10,6 +10,7 @@
:key="rule.id"
:value="rule"
:filters="filters"
:preview="preview"
:context="context"
:data-id="rule.id"
@input="updateRule(rule.id, $event)"
@ -61,10 +62,15 @@ export default {
value: Array,
filters: Object,
maxRules: {
tpye: Number,
type: Number,
required: false,
default: 0
},
preview: {
type: Boolean,
required: false,
default: true
},
context: {
type: Object,
required: false

View file

@ -10,10 +10,11 @@
:type="type"
:filters="filters"
:context="context"
:preview="preview"
/>
<div
v-if="isShort"
v-if="isShort && preview"
class="tw-mg-l-1 tw-pd-x-1 tw-border-l tw-flex tw-align-items-center ffz--profile__icon tw-relative ffz-il-tooltip__container"
>
<figure :class="[passes ? 'ffz-i-ok' : 'ffz-i-cancel']" />
@ -31,7 +32,7 @@
:class="[isShort ? '' : 'tw-mg-l-1']"
class="tw-border-l tw-pd-l-1 tw-flex tw-flex-column tw-flex-wrap tw-justify-content-start tw-align-items-start"
>
<div v-if="! isShort" class="tw-mg-b-1 tw-border-b tw-pd-b-1 tw-full-width tw-flex tw-justify-content-center ffz--profile__icon tw-relative ffz-il-tooltip__container">
<div v-if="! isShort && preview" class="tw-mg-b-1 tw-border-b tw-pd-b-1 tw-full-width tw-flex tw-justify-content-center ffz--profile__icon tw-relative ffz-il-tooltip__container">
<figure :class="[passes ? 'ffz-i-ok' : 'ffz-i-cancel']" />
<div class="ffz-il-tooltip ffz-il-tooltip--up ffz-il-tooltip--align-right">
<span v-if="passes">
@ -80,6 +81,11 @@ export default {
context: {
type: Object,
required: false
},
preview: {
type: Boolean,
required: false,
default: true
}
},
@ -93,7 +99,7 @@ export default {
computed: {
passes() {
return this.tester && this.tester(this.context);
return this.preview && this.tester && this.tester(this.context);
},
type() {

View file

@ -176,6 +176,7 @@
v-model="rules"
:filters="filters"
:context="test_context"
:preview="true"
/>
</div>
</div>

View file

@ -0,0 +1,60 @@
<template lang="html">
<div class="ffz--widget ffz--filter-editor tw-border-t tw-pd-y-1">
<div
v-if="source && source !== profile"
class="tw-c-background-accent tw-c-text-overlay tw-pd-1 tw-mg-b-1"
>
<span class="ffz-i-info" />
{{ t('setting.warn-inheritence', 'These values are being overridden by another profile and may not take effect.') }}
</div>
<filter-editor
:value="rules"
:filters="filters"
:context="test_context"
:preview="preview"
@input="onInput"
/>
</div>
</template>
<script>
import {deep_copy} from 'utilities/object';
import SettingMixin from '../setting-mixin';
export default {
mixins: [SettingMixin],
props: ['item', 'context'],
data() {
return {
filters: this.item.data(),
test_context: this.item.test_context ? this.item.test_context() : {},
};
},
computed: {
preview() {
return this.item.preview || false
},
rules() {
if ( ! Array.isArray(this.value) || this.value.length <= 0 )
return [];
return this.value.filter(x => x.v).map(x => x.v);
}
},
methods: {
onInput(data) {
const val = deep_copy(data);
this.set(val);
}
}
}
</script>

View file

@ -13,6 +13,9 @@ import { getFontsList, useFont } from 'utilities/fonts';
const STYLE_VALIDATOR = createElement('span');
const LEFT_CONTROLS = '.video-player__default-player .player-controls__left-control-group';
const RIGHT_CONTROLS = '.video-player__default-player .player-controls__right-control-group';
const HAS_COMPRESSOR = window.AudioContext && window.DynamicsCompressorNode != null,
HAS_GAIN = HAS_COMPRESSOR && window.GainNode != null;
@ -75,6 +78,9 @@ export default class PlayerBase extends Module {
this.onShortcut = this.onShortcut.bind(this);
this.LEFT_CONTROLS = LEFT_CONTROLS;
this.RIGHT_CONTROLS = RIGHT_CONTROLS;
this.registerSettings();
}
@ -1171,7 +1177,7 @@ export default class PlayerBase extends Module {
addGainSlider(inst, visible_only, tries = 0) {
const outer = inst.props.containerRef || this.fine.getChildNode(inst),
video = inst.props.mediaPlayerInstance?.mediaSinkManager?.video || inst.props.mediaPlayerInstance?.core?.mediaSinkManager?.video,
container = outer && outer.querySelector('.video-player__default-player .player-controls__left-control-group');
container = outer && outer.querySelector(LEFT_CONTROLS);
let gain = video != null && video._ffz_compressed && video._ffz_gain;
if ( this.areControlsDisabled(inst) )
@ -1302,7 +1308,7 @@ export default class PlayerBase extends Module {
addCompressorButton(inst, visible_only, tries = 0) {
const outer = inst.props.containerRef || this.fine.getChildNode(inst),
video = inst.props.mediaPlayerInstance?.mediaSinkManager?.video || inst.props.mediaPlayerInstance?.core?.mediaSinkManager?.video,
container = outer && outer.querySelector('.video-player__default-player .player-controls__left-control-group'),
container = outer && outer.querySelector(LEFT_CONTROLS),
has_comp = HAS_COMPRESSOR && video != null && this.settings.get('player.compressor.enable');
if ( ! container ) {
@ -1730,7 +1736,7 @@ export default class PlayerBase extends Module {
const outer = inst.props.containerRef || this.fine.getChildNode(inst),
video = inst.props.mediaPlayerInstance?.mediaSinkManager?.video || inst.props.mediaPlayerInstance?.core?.mediaSinkManager?.video,
is_fs = video && document.fullscreenElement && document.fullscreenElement.contains(video),
container = outer && outer.querySelector('.video-player__default-player .player-controls__right-control-group'),
container = outer && outer.querySelector(RIGHT_CONTROLS),
has_pip = document.pictureInPictureEnabled && this.settings.get('player.button.pip');
if ( ! container ) {
@ -1833,7 +1839,7 @@ export default class PlayerBase extends Module {
addResetButton(inst, tries = 0) {
const outer = inst.props.containerRef || this.fine.getChildNode(inst),
container = outer && outer.querySelector('.video-player__default-player .player-controls__right-control-group'),
container = outer && outer.querySelector(RIGHT_CONTROLS),
has_reset = this.settings.get('player.button.reset');
if ( ! container ) {
@ -2055,7 +2061,7 @@ export default class PlayerBase extends Module {
return;
const outer = inst.props.containerRef || this.fine.getChildNode(inst),
container = outer && outer.querySelector('.video-player__default-player .player-controls__right-control-group');
container = outer && outer.querySelector(RIGHT_CONTROLS);
if ( ! container )
return;

View file

@ -45,7 +45,8 @@ export const RERENDER_SETTINGS = [
'chat.filtering.display-deleted',
'chat.filtering.display-mod-action',
'chat.replies.style',
'chat.bits.cheer-notice'
'chat.bits.cheer-notice',
'chat.filtering.hidden-tokens'
];
export const UPDATE_BADGE_SETTINGS = [