mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-28 15:27:43 +00:00
4.54.0
* Added: Setting to hide the Turbo button in the Twitch navigation bar. (Closes #1410, #1389) * Added: Setting to automatically expand chat when entering full-screen. (Closes #1377) * Changed: The "Change Name & Color" chat action now has buttons to automatically fill in a user's existing name and color. (Closes #1397) * Fixed: Integration issue with a Twitch chat experiment causing certain features to not work correctly. * Removed: Old setting to hide a "Discover" link in the navigation bar, as that seems to be long since removed.
This commit is contained in:
parent
92fcc853a6
commit
d01f66c6f3
10 changed files with 144 additions and 9 deletions
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "frankerfacez",
|
"name": "frankerfacez",
|
||||||
"author": "Dan Salvato LLC",
|
"author": "Dan Salvato LLC",
|
||||||
"version": "4.53.0",
|
"version": "4.54.0",
|
||||||
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
|
|
@ -25,6 +25,17 @@
|
||||||
@change="updateName"
|
@change="updateName"
|
||||||
>
|
>
|
||||||
|
|
||||||
|
<button
|
||||||
|
v-if="originalName"
|
||||||
|
class="tw-mg-l-05 tw-button tw-button--text ffz-il-tooltip__container"
|
||||||
|
@click="setOriginalName"
|
||||||
|
>
|
||||||
|
<span class="tw-button__text ffz-i-plus" />
|
||||||
|
<div class="ffz-il-tooltip ffz-il-tooltip--down ffz-il-tooltip--align-right">
|
||||||
|
{{ t('setting.set-to-current', 'Set to Current') }}
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="tw-mg-l-05 tw-button tw-button--text ffz-il-tooltip__container"
|
class="tw-mg-l-05 tw-button tw-button--text ffz-il-tooltip__container"
|
||||||
:class="{'tw-button--disabled': name == null}"
|
:class="{'tw-button--disabled': name == null}"
|
||||||
|
@ -51,6 +62,17 @@
|
||||||
@input="updateColor"
|
@input="updateColor"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<button
|
||||||
|
v-if="originalColor"
|
||||||
|
class="tw-mg-l-05 tw-button tw-button--text ffz-il-tooltip__container"
|
||||||
|
@click="setOriginalColor"
|
||||||
|
>
|
||||||
|
<span class="tw-button__text ffz-i-plus" />
|
||||||
|
<div class="ffz-il-tooltip ffz-il-tooltip--down ffz-il-tooltip--align-right">
|
||||||
|
{{ t('setting.set-to-current', 'Set to Current') }}
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="tw-mg-l-05 tw-button tw-button--text ffz-il-tooltip__container"
|
class="tw-mg-l-05 tw-button tw-button--text ffz-il-tooltip__container"
|
||||||
:class="{'tw-button--disabled': color == null}"
|
:class="{'tw-button--disabled': color == null}"
|
||||||
|
@ -93,6 +115,16 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
setOriginalName() {
|
||||||
|
this.name = this.originalName;
|
||||||
|
this.setName(this.name);
|
||||||
|
},
|
||||||
|
|
||||||
|
setOriginalColor() {
|
||||||
|
this.color = this.originalColor;
|
||||||
|
this.setColor(this.color);
|
||||||
|
},
|
||||||
|
|
||||||
clearName() {
|
clearName() {
|
||||||
this.name = null;
|
this.name = null;
|
||||||
this.deleteName();
|
this.deleteName();
|
||||||
|
|
|
@ -99,6 +99,9 @@ export default class Overrides extends Module {
|
||||||
name: this.getName(user.id),
|
name: this.getName(user.id),
|
||||||
color: this.getColor(user.id),
|
color: this.getColor(user.id),
|
||||||
|
|
||||||
|
originalName: user.displayName ?? user.login,
|
||||||
|
originalColor: user.color,
|
||||||
|
|
||||||
updateTip: () => tip.update(),
|
updateTip: () => tip.update(),
|
||||||
setColor: val => this.setColor(user.id, val),
|
setColor: val => this.setColor(user.id, val),
|
||||||
deleteColor: () => this.deleteColor(user.id),
|
deleteColor: () => this.deleteColor(user.id),
|
||||||
|
|
|
@ -106,12 +106,17 @@ export default class Twilight extends BaseSite {
|
||||||
window.addEventListener('resize', update_size);
|
window.addEventListener('resize', update_size);
|
||||||
update_size();
|
update_size();
|
||||||
|
|
||||||
const update_fullscreen = () => this.settings.updateContext({
|
const update_fullscreen = () => {
|
||||||
|
this.settings.updateContext({
|
||||||
fullscreen: !! document.fullscreenElement
|
fullscreen: !! document.fullscreenElement
|
||||||
});
|
});
|
||||||
|
this.emit(':fullscreen');
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener('fullscreenchange', update_fullscreen);
|
document.addEventListener('fullscreenchange', update_fullscreen);
|
||||||
update_fullscreen();
|
this.settings.updateContext({
|
||||||
|
fullscreen: !! document.fullscreenElement
|
||||||
|
});
|
||||||
|
|
||||||
// Share Context
|
// Share Context
|
||||||
store.subscribe(() => this.updateContext());
|
store.subscribe(() => this.updateContext());
|
||||||
|
|
|
@ -1392,7 +1392,10 @@ export default class ChatHook extends Module {
|
||||||
inst.props.setMessageBufferAPI({
|
inst.props.setMessageBufferAPI({
|
||||||
addUpdateHandler: inst.addUpdateHandler,
|
addUpdateHandler: inst.addUpdateHandler,
|
||||||
removeUpdateHandler: inst.removeUpdateHandler,
|
removeUpdateHandler: inst.removeUpdateHandler,
|
||||||
|
getUnreadCount: inst.getUnreadCount,
|
||||||
getMessages: inst.getMessages,
|
getMessages: inst.getMessages,
|
||||||
|
getMessagesForHighlight: inst.getMessagesForHighlight,
|
||||||
|
getMessagesForAllHighlights: inst.getMessagesForAllHighlights,
|
||||||
isPaused: inst.isPaused,
|
isPaused: inst.isPaused,
|
||||||
setPaused: inst.setPaused,
|
setPaused: inst.setPaused,
|
||||||
hasNewerLeft: inst.hasNewerLeft,
|
hasNewerLeft: inst.hasNewerLeft,
|
||||||
|
@ -2307,6 +2310,10 @@ export default class ChatHook extends Module {
|
||||||
this.notifySubscribers();
|
this.notifySubscribers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( this.flushHighlightsBuffer )
|
||||||
|
this.flushHighlightsBuffer();
|
||||||
|
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
t.log.error('Error running flush.', err);
|
t.log.error('Error running flush.', err);
|
||||||
return old_flush.call(this);
|
return old_flush.call(this);
|
||||||
|
|
|
@ -13,7 +13,7 @@ const STYLE_VALIDATOR = document.createElement('span');
|
||||||
|
|
||||||
const CLASSES = {
|
const CLASSES = {
|
||||||
//'unfollow': '.follow-btn__follow-btn--following,.follow-btn--following',
|
//'unfollow': '.follow-btn__follow-btn--following,.follow-btn--following',
|
||||||
'top-discover': '.navigation-link[data-a-target="discover-link"]',
|
//'top-discover': '.navigation-link[data-a-target="discover-link"]',
|
||||||
'side-nav': '.side-nav,#sideNav',
|
'side-nav': '.side-nav,#sideNav',
|
||||||
'side-nav-viewers': '.side-nav-card__live-status',
|
'side-nav-viewers': '.side-nav-card__live-status',
|
||||||
'side-rec-channels': '.side-nav .recommended-channels,.side-nav .side-nav-section + .side-nav-section:not(.online-friends):not(.bd--shelf)',
|
'side-rec-channels': '.side-nav .recommended-channels,.side-nav .side-nav-section + .side-nav-section:not(.online-friends):not(.bd--shelf)',
|
||||||
|
@ -329,7 +329,7 @@ export default class CSSTweaks extends Module {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.settings.add('layout.discover', {
|
/*this.settings.add('layout.discover', {
|
||||||
default: true,
|
default: true,
|
||||||
ui: {
|
ui: {
|
||||||
path: 'Appearance > Layout >> Top Navigation',
|
path: 'Appearance > Layout >> Top Navigation',
|
||||||
|
@ -340,6 +340,15 @@ export default class CSSTweaks extends Module {
|
||||||
this.toggleHide('top-discover', !val);
|
this.toggleHide('top-discover', !val);
|
||||||
this.updateTopNav();
|
this.updateTopNav();
|
||||||
}
|
}
|
||||||
|
});*/
|
||||||
|
|
||||||
|
this.settings.add('layout.turbo-cta', {
|
||||||
|
default: true,
|
||||||
|
ui: {
|
||||||
|
path: 'Appearance > Layout >> Top Navigation',
|
||||||
|
title: 'Allow the Twitch Turbo button to appear.',
|
||||||
|
component: 'setting-check-box'
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.settings.add('layout.prime-offers', {
|
this.settings.add('layout.prime-offers', {
|
||||||
|
@ -486,7 +495,7 @@ export default class CSSTweaks extends Module {
|
||||||
this.toggleHide('side-offline-channels', this.settings.get('layout.side-nav.hide-offline'));
|
this.toggleHide('side-offline-channels', this.settings.get('layout.side-nav.hide-offline'));
|
||||||
this.toggleHide('discover-luna', this.settings.get('layout.hide-discover-luna'));
|
this.toggleHide('discover-luna', this.settings.get('layout.hide-discover-luna'));
|
||||||
this.toggleHide('prime-offers', !this.settings.get('layout.prime-offers'));
|
this.toggleHide('prime-offers', !this.settings.get('layout.prime-offers'));
|
||||||
this.toggleHide('top-discover', !this.settings.get('layout.discover'));
|
//this.toggleHide('top-discover', !this.settings.get('layout.discover'));
|
||||||
this.toggle('hide-unfollow-button', this.settings.get('channel.hide-unfollow'));
|
this.toggle('hide-unfollow-button', this.settings.get('channel.hide-unfollow'));
|
||||||
|
|
||||||
this.toggleHide('pinned-hype-chat', ! this.settings.get('chat.hype.show-pinned'));
|
this.toggleHide('pinned-hype-chat', ! this.settings.get('chat.hype.show-pinned'));
|
||||||
|
|
|
@ -22,6 +22,11 @@ export default class Loadable extends Module {
|
||||||
n => n.props?.component && n.props.loader
|
n => n.props?.component && n.props.loader
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.ErrorBoundaryComponent = this.fine.define(
|
||||||
|
'error-boundary-component',
|
||||||
|
n => n.props?.name && n.props?.onError && n.props?.children && n.onErrorBoundaryTestEmit
|
||||||
|
);
|
||||||
|
|
||||||
this.overrides = new Map();
|
this.overrides = new Map();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -31,6 +36,32 @@ export default class Loadable extends Module {
|
||||||
this.toggle('PaidPinnedChatMessageList', val);
|
this.toggle('PaidPinnedChatMessageList', val);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.settings.getChanges('layout.turbo-cta', val => {
|
||||||
|
this.toggle('TopNav__TurboButton_Available', val);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.ErrorBoundaryComponent.ready((cls, instances) => {
|
||||||
|
this.log.debug('Found Error Boundary component wrapper.');
|
||||||
|
|
||||||
|
const t = this,
|
||||||
|
old_render = cls.prototype.render;
|
||||||
|
|
||||||
|
cls.prototype.render = function() {
|
||||||
|
try {
|
||||||
|
const type = this.props.name;
|
||||||
|
if ( t.overrides.has(type) && ! t.shouldRender(type) )
|
||||||
|
return null;
|
||||||
|
} catch(err) {
|
||||||
|
/* no-op */
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return old_render.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ErrorBoundaryComponent.updateInstances();
|
||||||
|
});
|
||||||
|
|
||||||
this.LoadableComponent.ready((cls, instances) => {
|
this.LoadableComponent.ready((cls, instances) => {
|
||||||
this.log.debug('Found Loadable component wrapper.');
|
this.log.debug('Found Loadable component wrapper.');
|
||||||
|
|
||||||
|
@ -72,6 +103,7 @@ export default class Loadable extends Module {
|
||||||
return old_render.call(this);
|
return old_render.call(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.LoadableComponent.updateInstances();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +123,14 @@ export default class Loadable extends Module {
|
||||||
|
|
||||||
update(cmp) {
|
update(cmp) {
|
||||||
for(const inst of this.LoadableComponent.instances) {
|
for(const inst of this.LoadableComponent.instances) {
|
||||||
if ( inst?.props?.component === cmp )
|
const type = inst?.props?.component;
|
||||||
|
if ( type && type === cmp )
|
||||||
|
inst.forceUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const inst of this.ErrorBoundaryComponent.instances) {
|
||||||
|
const name = inst?.props?.name;
|
||||||
|
if ( name && name === cmp )
|
||||||
inst.forceUpdate();
|
inst.forceUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,6 +138,15 @@ export default class Player extends PlayerBase {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.settings.add('player.fullscreen.auto-chat', {
|
||||||
|
default: false,
|
||||||
|
ui: {
|
||||||
|
path: 'Player > General >> Fullscreen',
|
||||||
|
title: 'Automatically expand chat when entering fullscreen mode.',
|
||||||
|
component: 'setting-check-box'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.settings.add('player.hide-event-bar', {
|
this.settings.add('player.hide-event-bar', {
|
||||||
default: false,
|
default: false,
|
||||||
ui: {
|
ui: {
|
||||||
|
@ -178,6 +187,8 @@ export default class Player extends PlayerBase {
|
||||||
|
|
||||||
this.on(':fix-player', this.repositionPlayer, this);
|
this.on(':fix-player', this.repositionPlayer, this);
|
||||||
|
|
||||||
|
this.on('site:fullscreen', this.maybeOpenChat, this);
|
||||||
|
|
||||||
this.TheatreHost.on('mount', inst => {
|
this.TheatreHost.on('mount', inst => {
|
||||||
inst._ffz_theater_start = Date.now();
|
inst._ffz_theater_start = Date.now();
|
||||||
this.tryTheatreMode(inst);
|
this.tryTheatreMode(inst);
|
||||||
|
@ -195,6 +206,14 @@ export default class Player extends PlayerBase {
|
||||||
this.PlayerSource.on('update', this.checkCarousel, this);
|
this.PlayerSource.on('update', this.checkCarousel, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maybeOpenChat() {
|
||||||
|
if ( ! this.settings.get('player.fullscreen.auto-chat') )
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.parent.awaitElement('.right-column--collapsed .right-column__toggle-visibility button', document.fullscreenElement, 1000)
|
||||||
|
.then(el => el.click());
|
||||||
|
}
|
||||||
|
|
||||||
shouldStopAutoplay() {
|
shouldStopAutoplay() {
|
||||||
return this.settings.get('player.no-autoplay') ||
|
return this.settings.get('player.no-autoplay') ||
|
||||||
(! this.settings.get('player.home.autoplay') && this.router.current?.name === 'front-page');
|
(! this.settings.get('player.home.autoplay') && this.router.current?.name === 'front-page');
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
.tw-root--theme-dark, html {
|
.tw-root--theme-dark, html {
|
||||||
body,
|
body,
|
||||||
|
.creator-chat-stats-carousel,
|
||||||
.channel-header,
|
.channel-header,
|
||||||
.channel-root__right-column,
|
.channel-root__right-column,
|
||||||
.chat-viewers__pane,
|
.chat-viewers__pane,
|
||||||
|
@ -93,6 +94,14 @@
|
||||||
.ach-card--expanded .ach-card__inner {
|
.ach-card--expanded .ach-card__inner {
|
||||||
border-color: var(--color-border-brand) !important;
|
border-color: var(--color-border-brand) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.creator-chat-stats-carousel__right-arrow {
|
||||||
|
background: linear-gradient(270deg, var(--color-background-body) 60%, transparent) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.creator-chat-stats-carousel__left-arrow {
|
||||||
|
background: linear-gradient(90deg, var(--color-background-body) 60%, transparent) !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
|
|
|
@ -611,6 +611,18 @@ export class FineWrapper extends EventEmitter {
|
||||||
fn(inst);
|
fn(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateInstances(node = null, max_depth = 1000) {
|
||||||
|
if ( ! this._class )
|
||||||
|
return;
|
||||||
|
|
||||||
|
const instances = this.fine.findAllMatching(node, n => n.constructor === this._class, max_depth);
|
||||||
|
|
||||||
|
for(const inst of instances) {
|
||||||
|
inst._ffz_mounted = true;
|
||||||
|
this.instances.add(inst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_set(cls, instances) {
|
_set(cls, instances) {
|
||||||
if ( this._class )
|
if ( this._class )
|
||||||
throw new Error('already have a class');
|
throw new Error('already have a class');
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue