1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-08-01 23:48:31 +00:00
* Added: There is now a button to reset the player in the FFZ menu button's right-click menu, for use when the player GUI is not accessible due to an error.
* Fixed: The pop-up for Stream Uptime not functioning for Firefox users due to an unimplemented permission.
* Fixed: The FFZ menu button not appearing in Squad Streaming mode.
* Fixed: Apply CSS color variables to the background of the Squad Streaming page.
* Fixed: Load chat elements on the Squad Streaming page.
This commit is contained in:
SirStendec 2019-10-19 12:46:36 -04:00
parent 103c68ad10
commit 9c2053bf9b
7 changed files with 74 additions and 20 deletions

View file

@ -1,7 +1,7 @@
{ {
"name": "frankerfacez", "name": "frankerfacez",
"author": "Dan Salvato LLC", "author": "Dan Salvato LLC",
"version": "4.14.8", "version": "4.14.9",
"description": "FrankerFaceZ is a Twitch enhancement suite.", "description": "FrankerFaceZ is a Twitch enhancement suite.",
"license": "Apache-2.0", "license": "Apache-2.0",
"scripts": { "scripts": {

View file

@ -794,7 +794,16 @@ export default class MainMenu extends Module {
this.settings.provider.set('cfg-collapsed', collapsed); this.settings.provider.set('cfg-collapsed', collapsed);
}, },
resize: e => ! this.dialog.exclusive && this.dialog.toggleSize(e), resize: e => {
if ( this.dialog.exclusive || this.site?.router?.current_name === 'squad' )
return;
if ( this.settings.get('context.ui.theatreModeEnabled') )
return;
this.dialog.toggleSize(e);
},
close: e => ! this.dialog.exclusive && this.dialog.toggleVisible(e), close: e => ! this.dialog.exclusive && this.dialog.toggleVisible(e),
popout: e => { popout: e => {

View file

@ -126,7 +126,7 @@ export default class Metadata extends Module {
async popup(data, tip) { async popup(data, tip) {
const [permission, broadcast_id] = await Promise.all([ const [permission, broadcast_id] = await Promise.all([
navigator.permissions.query({name: 'clipboard-write'}), navigator.permissions.query({name: 'clipboard-write'}).then(perm => perm?.state).catch(() => null),
data.getBroadcastID() data.getBroadcastID()
]); ]);
if ( ! broadcast_id ) if ( ! broadcast_id )
@ -135,7 +135,7 @@ export default class Metadata extends Module {
</div>); </div>);
const url = `https://www.twitch.tv/videos/${broadcast_id}${data.uptime > 0 ? `?t=${durationForURL(data.uptime)}` : ''}`, const url = `https://www.twitch.tv/videos/${broadcast_id}${data.uptime > 0 ? `?t=${durationForURL(data.uptime)}` : ''}`,
can_copy = permission?.state === 'granted' || permission?.state === 'prompt'; can_copy = permission === 'granted' || permission === 'prompt';
const copy = can_copy ? e => { const copy = can_copy ? e => {
navigator.clipboard.writeText(url); navigator.clipboard.writeText(url);
@ -954,8 +954,10 @@ export default class Metadata extends Module {
} }
} }
if ( old_color !== color ) if ( old_color !== color ) {
el.dataset.color = el.style.color = color; el.dataset.color = color;
el.style.setProperty('color', color, 'important');
}
el._ffz_data = data; el._ffz_data = data;
stat.innerHTML = label; stat.innerHTML = label;

View file

@ -203,7 +203,8 @@ Twilight.CHAT_ROUTES = [
'user-following', 'user-following',
'user', 'user',
'dash', 'dash',
'embed-chat' 'embed-chat',
'squad'
]; ];

View file

@ -7,7 +7,6 @@
import {DEBUG} from 'utilities/constants'; import {DEBUG} from 'utilities/constants';
import {SiteModule} from 'utilities/module'; import {SiteModule} from 'utilities/module';
import {createElement, ClickOutside, setChildren} from 'utilities/dom'; import {createElement, ClickOutside, setChildren} from 'utilities/dom';
import { timeout, sleep } from 'src/utilities/object';
export default class MenuButton extends SiteModule { export default class MenuButton extends SiteModule {
constructor(...args) { constructor(...args) {
@ -40,6 +39,12 @@ export default class MenuButton extends SiteModule {
'nav-bar', 'nav-bar',
n => n.renderOnsiteNotifications && n.renderTwitchPrimeCrown n => n.renderOnsiteNotifications && n.renderTwitchPrimeCrown
); );
this.SquadBar = this.fine.define(
'squad-nav-bar',
n => n.exitSquadMode && n.props && n.props.squadID,
['squad']
);
} }
get loading() { get loading() {
@ -154,6 +159,9 @@ export default class MenuButton extends SiteModule {
_update() { _update() {
for(const inst of this.NavBar.instances) for(const inst of this.NavBar.instances)
this.updateButton(inst); this.updateButton(inst);
for(const inst of this.SquadBar.instances)
this.updateButton(inst);
} }
@ -163,6 +171,10 @@ export default class MenuButton extends SiteModule {
this.NavBar.on('mount', this.updateButton, this); this.NavBar.on('mount', this.updateButton, this);
this.NavBar.on('update', this.updateButton, this); this.NavBar.on('update', this.updateButton, this);
this.SquadBar.ready(() => this.update());
this.SquadBar.on('mount', this.updateButton, this);
this.SquadBar.on('update', this.updateButton, this);
this.on(':clicked', () => this.important_update = false); this.on(':clicked', () => this.important_update = false);
this.once(':clicked', this.loadMenu); this.once(':clicked', this.loadMenu);
@ -175,20 +187,33 @@ export default class MenuButton extends SiteModule {
updateButton(inst) { updateButton(inst) {
const root = this.fine.getChildNode(inst); const root = this.fine.getChildNode(inst);
let container = root && root.querySelector('.top-nav__menu'); let is_squad = false,
container = root && root.querySelector('.top-nav__menu');
if ( ! container ) {
if ( root && root.classList.contains('squad-stream-top-bar__container') )
container = root;
else
container = root && root.querySelector('.squad-stream-top-bar__container');
if ( container )
is_squad = true;
}
if ( ! container ) if ( ! container )
return; return;
let user_stuff = null; if ( ! is_squad ) {
try { let user_stuff = null;
user_stuff = container.querySelector(':scope > .tw-justify-content-end:last-child'); try {
} catch(err) { /* dumb browsers with no :scope are dumb */ } user_stuff = container.querySelector(':scope > .tw-justify-content-end:last-child');
} catch(err) { /* dumb browsers with no :scope are dumb */ }
if ( user_stuff ) if ( user_stuff )
container = user_stuff; container = user_stuff;
else else
container = container.lastElementChild; container = container.lastElementChild;
}
let btn, el = container.querySelector('.ffz-top-nav'); let btn, el = container.querySelector('.ffz-top-nav');
if ( el ) if ( el )
@ -367,7 +392,21 @@ export default class MenuButton extends SiteModule {
ctx = (<div class="tw-absolute tw-balloon tw-balloon--down tw-balloon--lg tw-balloon--right tw-block ffz--menu-context"> ctx = (<div class="tw-absolute tw-balloon tw-balloon--down tw-balloon--lg tw-balloon--right tw-block ffz--menu-context">
<div class="tw-border-radius-large tw-c-background-base tw-c-text-inherit tw-elevation-4"> <div class="tw-border-radius-large tw-c-background-base tw-c-text-inherit tw-elevation-4">
<div class="tw-c-text-base tw-elevation-1 tw-flex tw-flex-shrink-0 tw-pd-x-1 tw-pd-y-05 tw-popover-header"> <div class="tw-c-text-base tw-elevation-1 tw-flex tw-flex-shrink-0 tw-pd-x-1 tw-pd-y-05 tw-popover-header">
<div class="tw-flex tw-flex-column tw-justify-content-center tw-mg-l-05 tw-popover-header__icon-slot--left" /> <div class="tw-flex tw-flex-column tw-justify-content-center tw-mg-l-05 tw-popover-header__icon-slot--left">
<div class="tw-inline-flex tw-relative tw-tooltip-wrapper">
<button
class="tw-align-items-center tw-align-middle tw-border-radius-medium tw-button-icon tw-button-icon--secondary tw-core-button tw-core-button--border tw-inline-flex tw-interactive tw-justify-content-center tw-overflow-hidden"
onDblClick={() => {this.emit('site.player:reset'); destroy()}} // eslint-disable-line react/jsx-no-bind
>
<span class="tw-button-icon__icon">
<figure class="ffz-i-t-reset" />
</span>
</button>
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-left">
{ this.i18n.t('player.reset_button.all', 'Reset All Players (Double-Click)') }
</div>
</div>
</div>
<div class="tw-align-items-center tw-flex tw-flex-column tw-flex-grow-1 tw-justify-content-center"> <div class="tw-align-items-center tw-flex tw-flex-column tw-flex-grow-1 tw-justify-content-center">
<h5 class="tw-align-center tw-c-text-alt tw-semibold"> <h5 class="tw-align-center tw-c-text-alt tw-semibold">
{ this.i18n.t('site.menu_button.profiles', 'Profiles') } { this.i18n.t('site.menu_button.profiles', 'Profiles') }

View file

@ -373,6 +373,8 @@ export default class Player extends Module {
this.updateHideExtensions(); this.updateHideExtensions();
this.installVisibilityHook(); this.installVisibilityHook();
this.on(':reset', () => this.resetPlayer());
const t = this; const t = this;
@ -775,7 +777,7 @@ export default class Player extends Module {
if ( tries < 5 ) if ( tries < 5 )
return setTimeout(this.addPiPButton.bind(this, inst, (tries || 0) + 1), 250); return setTimeout(this.addPiPButton.bind(this, inst, (tries || 0) + 1), 250);
return this.log.warn('Unable to find container element for PiP button.'); return; // this.log.warn('Unable to find container element for PiP button.');
} }
let icon, tip, btn, cont = container.querySelector('.ffz--player-pip'); let icon, tip, btn, cont = container.querySelector('.ffz--player-pip');
@ -864,7 +866,7 @@ export default class Player extends Module {
if ( tries < 5 ) if ( tries < 5 )
return setTimeout(this.addResetButton.bind(this, inst, (tries || 0) + 1), 250); return setTimeout(this.addResetButton.bind(this, inst, (tries || 0) + 1), 250);
return this.log.warn('Unable to find container element for Reset button.'); return; // this.log.warn('Unable to find container element for Reset button.');
} }
let tip, btn, cont = container.querySelector('.ffz--player-reset'); let tip, btn, cont = container.querySelector('.ffz--player-reset');

View file

@ -3,6 +3,7 @@
.channel-header, .channel-header,
.channel-root__right-column, .channel-root__right-column,
.chat-room, .chat-room,
.multi-stream-player-layout,
.carousel-player-nav-arrow__container { .carousel-player-nav-arrow__container {
background-color: var(--color-background-body) !important; background-color: var(--color-background-body) !important;
} }