mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-27 21:05:53 +00:00
4.12.0
Initial wave of fixes for the Twitch redesign. * Fixed: Apollo not loading, breaking many subsystems including chat. * Fixed: Stream up-time not appearing. * Fixed: Stream meta-data being styled and positioned incorrectly. * Fixed: Header styles for the FFZ Control Center. * Fixed: FFZ menu button not being styled correctly in the site header. * Fixed: Alignment of chat minimize button when in portrait mode and/or swapped sidebars mode.
This commit is contained in:
parent
eb5a3a3966
commit
2232934309
12 changed files with 180 additions and 33 deletions
|
@ -36,6 +36,7 @@ module.exports = {
|
|||
"FrankerFaceZ": false
|
||||
},
|
||||
"rules": {
|
||||
"require-atomic-updates": "off",
|
||||
"accessor-pairs": ["error"],
|
||||
"block-scoped-var": ["error"],
|
||||
"class-methods-use-this": ["error"],
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "frankerfacez",
|
||||
"author": "Dan Salvato LLC",
|
||||
"version": "4.11.0",
|
||||
"version": "4.12.0",
|
||||
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
<div class="ffz--home tw-flex tw-flex-nowrap">
|
||||
<div class="tw-flex-grow-1">
|
||||
<div class="tw-align-center">
|
||||
<h1 class="ffz-i-zreknarf ffz-i-pd-1">
|
||||
<h2 class="ffz-i-zreknarf ffz-i-pd-1">
|
||||
FrankerFaceZ
|
||||
</h1>
|
||||
</h2>
|
||||
<span class="tw-c-text-alt">
|
||||
{{ t('home.tag-line', 'The Twitch Enhancement Suite') }}
|
||||
</span>
|
||||
|
|
|
@ -79,8 +79,7 @@ export default class Metadata extends Module {
|
|||
|
||||
setup(data) {
|
||||
const socket = this.resolve('socket'),
|
||||
apollo = this.resolve('site.apollo'),
|
||||
created_at = apollo.getFromQuery(data.legacy ? 'ChannelPage_ChannelHeader' : 'ChannelPage_User', 'data.user.stream.createdAt');
|
||||
created_at = data?.meta?.createdAt;
|
||||
|
||||
if ( ! created_at )
|
||||
return {};
|
||||
|
@ -288,7 +287,7 @@ export default class Metadata extends Module {
|
|||
}
|
||||
|
||||
|
||||
async render(key, data, container, timers, refresh_fn) {
|
||||
/*async render(key, data, container, timers, refresh_fn) {
|
||||
if ( timers[key] )
|
||||
clearTimeout(timers[key]);
|
||||
|
||||
|
@ -613,7 +612,7 @@ export default class Metadata extends Module {
|
|||
this.log.error(`Error rendering metadata for ${key}`, err);
|
||||
return destroy();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
async renderLegacy(key, data, container, timers, refresh_fn) {
|
||||
|
@ -678,17 +677,25 @@ export default class Metadata extends Module {
|
|||
button = true;
|
||||
|
||||
let btn, popup;
|
||||
let cls = maybe_call(def.button, this, data);
|
||||
const border = maybe_call(def.border, this, data);
|
||||
|
||||
/* let cls = maybe_call(def.button, this, data);
|
||||
|
||||
if ( typeof cls !== 'string' )
|
||||
cls = cls ? 'tw-border-t tw-border-l tw-border-b '
|
||||
|
||||
if ( typeof cls !== 'string' )
|
||||
cls = cls ? 'ffz-button--hollow' : 'tw-button--text';
|
||||
|
||||
const fix = cls === 'tw-button--text';
|
||||
const fix = cls === 'tw-button--text';*/
|
||||
|
||||
if ( typeof icon === 'string' )
|
||||
icon = (<span class="tw-button__icon tw-button__icon--left"><figure class={icon} /></span>);
|
||||
icon = (<span class="tw-mg-r-05">
|
||||
<figure class={icon} />
|
||||
</span>);
|
||||
|
||||
if ( def.popup && def.click ) {
|
||||
el = (<span
|
||||
/*el = (<span
|
||||
class={`ffz-stat${fix ? ' ffz-fix-padding--left' : ''} tw-inline-flex tw-align-items-center`}
|
||||
data-key={key}
|
||||
tip_content={tooltip}
|
||||
|
@ -702,10 +709,48 @@ export default class Metadata extends Module {
|
|||
<figure class="ffz-i-down-dir" />
|
||||
</span>
|
||||
</button>)}
|
||||
</span>);
|
||||
</span>);*/
|
||||
|
||||
el = (<div
|
||||
class="tw-align-items-center tw-inline-flex tw-relative tw-tooltip-wrapper ffz-stat tw-stat tw-mg-l-1 ffz-stat--fix-padding"
|
||||
data-key={key}
|
||||
tip_content={tooltip}
|
||||
>
|
||||
{btn = (<button
|
||||
class={`tw-align-items-center tw-align-middle tw-border-bottom-left-radius-medium tw-border-top-left-radius-medium tw-core-button tw-core-button--padded tw-core-button--text tw-c-text-base tw-inline-flex tw-interactive tw-justify-content-center tw-overflow-hidden tw-relative${border ? ' tw-border-l tw-border-t tw-border-b' : ''}`}
|
||||
>
|
||||
<div class="tw-align-items-center tw-flex tw-flex-grow-0 tw-justify-center">
|
||||
{icon}
|
||||
{stat = (<span class="ffz-stat-text" />)}
|
||||
</div>
|
||||
</button>)}
|
||||
{popup = (<button
|
||||
class={`tw-align-items-center tw-align-middle tw-border-bottom-right-radius-medium tw-border-top-right-radius-medium tw-core-button tw-core-button--text tw-c-text-base tw-inline-flex tw-interactive tw-justify-content-center tw-overflow-hidden tw-relative${border ? ' tw-border' : ''}`}
|
||||
>
|
||||
<div class="tw-align-items-center tw-flex tw-flex-grow-0 tw-justify-center">
|
||||
<span>
|
||||
<figure class="ffz-i-down-dir" />
|
||||
</span>
|
||||
</div>
|
||||
</button>)}
|
||||
</div>);
|
||||
|
||||
} else
|
||||
btn = popup = el = (<button
|
||||
class={`ffz-stat tw-align-items-center tw-align-middle tw-border-bottom-left-radius-medium tw-border-top-left-radius-medium tw-border-bottom-right-radius-medium tw-border-top-right-radius-medium tw-core-button tw-core-button--text tw-c-text-base tw-inline-flex tw-interactive tw-justify-content-center tw-overflow-hidden tw-relative tw-mg-l-1 tw-pd-x-05 ffz-stat--fix-padding${border ? ' tw-border' : ''}`}
|
||||
data-key={key}
|
||||
tip_content={tooltip}
|
||||
>
|
||||
<div class="tw-align-items-center tw-flex tw-flex-grow-0 tw-justify-center">
|
||||
{icon}
|
||||
{stat = (<span class="ffz-stat-text" />)}
|
||||
{def.popup && <span class="tw-mg-l-05">
|
||||
<figure class="ffz-i-down-dir" />
|
||||
</span>}
|
||||
</div>
|
||||
</button>);
|
||||
|
||||
/*btn = popup = el = (<button
|
||||
class={`ffz-stat${fix ? ' ffz-fix-padding' : ''} tw-button tw-inline-flex tw-align-items-center ${cls}`}
|
||||
data-key={key}
|
||||
tip_content={tooltip}
|
||||
|
@ -715,7 +760,7 @@ export default class Metadata extends Module {
|
|||
{def.popup && <span class="tw-button__icon tw-button__icon--right">
|
||||
<figure class="ffz-i-down-dir" />
|
||||
</span>}
|
||||
</button>);
|
||||
</button>);*/
|
||||
|
||||
if ( def.click )
|
||||
btn.addEventListener('click', e => {
|
||||
|
@ -802,7 +847,7 @@ export default class Metadata extends Module {
|
|||
icon = (<span class="tw-stat__icon"><figure class={icon} /></span>);
|
||||
|
||||
el = (<div
|
||||
class="tw-inline-flex tw-align-items-center ffz-stat tw-stat"
|
||||
class="tw-align-items-center tw-inline-flex tw-relative tw-tooltip-wrapper ffz-stat tw-stat tw-mg-l-1"
|
||||
data-key={key}
|
||||
tip_content={tooltip}
|
||||
>
|
||||
|
@ -824,12 +869,12 @@ export default class Metadata extends Module {
|
|||
if ( order != null )
|
||||
el.style.order = order;
|
||||
|
||||
let subcontainer;
|
||||
let subcontainer = container;
|
||||
|
||||
if ( button )
|
||||
/*if ( button )
|
||||
subcontainer = container.querySelector('.tw-flex:last-child') || container;
|
||||
else
|
||||
subcontainer = container.querySelector('.tw-flex:first-child') || container;
|
||||
subcontainer = container.querySelector('.tw-flex:first-child') || container;*/
|
||||
|
||||
subcontainer.appendChild(el);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ export default class ChannelBar extends Module {
|
|||
this.inject('site.fine');
|
||||
this.inject('site.web_munch');
|
||||
this.inject('site.apollo');
|
||||
this.inject('site.twitch_data');
|
||||
this.inject('metadata');
|
||||
this.inject('socket');
|
||||
|
||||
|
@ -84,6 +85,7 @@ export default class ChannelBar extends Module {
|
|||
inst._ffz_old_login = login;
|
||||
}
|
||||
|
||||
this.updateUptime(inst);
|
||||
this.updateMetadata(inst);
|
||||
}
|
||||
|
||||
|
@ -103,6 +105,34 @@ export default class ChannelBar extends Module {
|
|||
}
|
||||
|
||||
|
||||
async updateUptime(inst) {
|
||||
const current_id = inst?.props?.channel?.id;
|
||||
if ( current_id === inst._ffz_uptime_id ) {
|
||||
if ( Date.now() - inst._ffz_uptime_saved < 60000 )
|
||||
return;
|
||||
}
|
||||
|
||||
if ( inst._ffz_uptime_updating )
|
||||
return;
|
||||
|
||||
inst._ffz_uptime_updating = true;
|
||||
inst._ffz_uptime_id = current_id;
|
||||
|
||||
try {
|
||||
inst._ffz_meta = await this.twitch_data.getStreamMeta(current_id, inst?.props?.channel?.login);
|
||||
} catch(err) {
|
||||
this.log.capture(err);
|
||||
this.log.error('Error fetching uptime:', err);
|
||||
inst._ffz_meta = null;
|
||||
}
|
||||
|
||||
inst._ffz_uptime_saved = Date.now();
|
||||
inst._ffz_uptime_updating = false;
|
||||
|
||||
this.updateMetadata(inst);
|
||||
}
|
||||
|
||||
|
||||
updateMetadata(inst, keys) {
|
||||
const container = this.fine.getChildNode(inst),
|
||||
metabar = container?.querySelector?.('.channel-info-bar__viewers-count-wrapper > .tw-flex:last-child');
|
||||
|
@ -119,6 +149,7 @@ export default class ChannelBar extends Module {
|
|||
refresh_func = key => this.updateMetadata(inst, key),
|
||||
data = {
|
||||
channel: inst.props.channel,
|
||||
meta: inst._ffz_meta,
|
||||
hosting: false,
|
||||
legacy: true,
|
||||
_inst: inst
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Unnecessarily expressive rule to make it more important.
|
||||
#root .right-column .right-column__toggle-visibility {
|
||||
/*#root .right-column .right-column__toggle-visibility {
|
||||
right: unset !important;
|
||||
left: 0.5rem !important;
|
||||
}
|
||||
}*/
|
|
@ -81,9 +81,9 @@
|
|||
}
|
||||
|
||||
.right-column__toggle-visibility {
|
||||
position: fixed !important;
|
||||
//position: fixed !important;
|
||||
|
||||
body:not(.ffz--portrait-invert) & {
|
||||
/*body:not(.ffz--portrait-invert) & {
|
||||
top: 6.5rem;
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@
|
|||
}
|
||||
|
||||
right: .5rem;
|
||||
left: unset !important;
|
||||
left: unset !important;*/
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,10 +13,24 @@
|
|||
}
|
||||
|
||||
.right-column__toggle-visibility {
|
||||
left: unset !important;
|
||||
right: -2.5rem;
|
||||
z-index: 10 !important;
|
||||
//left: unset !important;
|
||||
//right: -2.5rem;
|
||||
//z-index: 10 !important;
|
||||
svg { transform: rotate(180deg) }
|
||||
|
||||
.right-column--collapsed & {
|
||||
left: unset !important;
|
||||
right: -4rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
.channel-header {
|
||||
padding-left: 4rem !important;
|
||||
|
||||
.tw-sm-pd-r-4 {
|
||||
padding-right: 1rem !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.side-nav__theme-wrapper.tw-border-r {
|
||||
|
|
|
@ -54,6 +54,7 @@ export default class HostButton extends Module {
|
|||
|
||||
this.metadata.definitions.host = {
|
||||
order: 150,
|
||||
border: true,
|
||||
button: true,
|
||||
fade_in: true,
|
||||
|
||||
|
|
|
@ -137,7 +137,42 @@ export default class MenuButton extends SiteModule {
|
|||
|
||||
const pill = this.formatPill();
|
||||
|
||||
el = (<div class="ffz-top-nav tw-align-self-center tw-flex-grow-0 tw-flex-shrink-0 tw-flex-nowrap tw-pd-r-1 tw-pd-l-05">
|
||||
// TODO: Pill.
|
||||
|
||||
el = (<div
|
||||
class="ffz-top-nav tw-align-self-center tw-flex-grow-0 tw-flex-nowrap tw-flex-shrink-0 tw-mg-x-05 tw-relative"
|
||||
>
|
||||
<div class="tw-inline-flex tw-relative tw-tooltip-wrapper">
|
||||
{btn = (<button
|
||||
class="tw-align-items-center tw-align-middle tw-border-bottom-left-radius-medium tw-border-bottom-right-radius-medium tw-border-top-left-radius-medium tw-border-top-right-radius-medium tw-button-icon tw-core-button tw-core-button--border tw-inline-flex tw-interactive tw-justify-content-center tw-overflow-hidden tw-relative"
|
||||
onClick={e => this.emit(':clicked', e, btn)} // eslint-disable-line react/jsx-no-bind
|
||||
>
|
||||
<div class="tw-align-items-center tw-flex tw-flex-grow-0">
|
||||
<span class="tw-button-icon__icon">
|
||||
<figure class="ffz-i-zreknarf" />
|
||||
</span>
|
||||
</div>
|
||||
</button>)}
|
||||
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
|
||||
{this.i18n.t('site.menu_button', 'FrankerFaceZ Control Center')}
|
||||
{this.has_update && (<div class="tw-mg-t-1">
|
||||
{this.i18n.t('site.menu_button.update-desc', 'There is an update available. Please refresh your page.')}
|
||||
</div>)}
|
||||
{this.has_new && (<div class="tw-mg-t-1">
|
||||
{this.i18n.t('site.menu_button.new-desc', 'There {count,plural,one {is one new setting} other {are # new settings}}.', {count: this._new_settings})}
|
||||
</div>)}
|
||||
{DEBUG && (<div class="tw-mg-t-1">
|
||||
{this.i18n.t('site.menu_button.main-dev-desc', 'You are running a developer build of FrankerFaceZ.')}
|
||||
</div>)}
|
||||
{this.addons.has_dev && (<div class="tw-mg-t-1">
|
||||
{this.i18n.t('site.menu_button.addon-dev-desc', 'You have loaded add-on data from a local development server.')}
|
||||
</div>)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>)
|
||||
|
||||
/*el = (<div class="ffz-top-nav tw-align-self-center tw-flex-grow-0 tw-flex-shrink-0 tw-flex-nowrap tw-pd-r-1 tw-pd-l-05">
|
||||
{btn = (<button
|
||||
class="tw-button-icon tw-button-icon--overlay tw-button-icon--large"
|
||||
onClick={e => this.emit(':clicked', e, btn)} //eslint-disable-line react/jsx-no-bind
|
||||
|
@ -195,7 +230,7 @@ export default class MenuButton extends SiteModule {
|
|||
</div>
|
||||
</div>
|
||||
</button>)}
|
||||
</div>);
|
||||
</div>);*/
|
||||
|
||||
container.insertBefore(el, container.lastElementChild);
|
||||
}
|
||||
|
|
|
@ -39,10 +39,15 @@
|
|||
.ffz-stat.tw-button--text {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.ffz-stat {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
.ffz-stat--fix-padding {
|
||||
margin-top: -.7rem !important;
|
||||
margin-bottom: -.7rem !important;
|
||||
}
|
||||
|
||||
.ffz-stat {
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.ffz--fade-in {
|
||||
|
|
|
@ -189,11 +189,26 @@ export default class Apollo extends Module {
|
|||
|
||||
this.old_link = this.client.link;
|
||||
this.old_qm_link = this.client.queryManager.link;
|
||||
this.old_qm_dedup = this.client.queryManager.deduplicator;
|
||||
//this.old_qm_dedup = this.client.queryManager.deduplicator;
|
||||
|
||||
this.client.link = this.link.concat(this.old_link);
|
||||
this.client.link = ApolloLink.from([
|
||||
this.link,
|
||||
this.old_link
|
||||
]);
|
||||
|
||||
this.client.queryManager.link = ApolloLink.from([
|
||||
this.link,
|
||||
this.old_qm_link
|
||||
]);
|
||||
|
||||
/*this.client.queryManager.deduplicator = ApolloLink.from([
|
||||
this.link,
|
||||
this.old_qm_dedup
|
||||
]);*/
|
||||
|
||||
/*this.client.link = this.link.concat(this.old_link);
|
||||
this.client.queryManager.link = this.link.concat(this.old_qm_link);
|
||||
this.client.queryManager.deduplicator = this.link.concat(this.old_qm_dedup);
|
||||
this.client.queryManager.deduplicator = this.link.concat(this.old_qm_dedup);*/
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue