mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-28 15:27:43 +00:00
4.14.12
* Added: Setting to hide re-runs in the site's side navigation, or to display them faded out to more obviously differentiate them from original live content. * Added: The `Changelog` will now only display commits with associated releases, by default. Users can optionally display all commits. * Fixed: The error message when a tool-tip failed to render was not being localized. * Fixed: Padding for certain metadata elements such as the `Host` button. * Fixed: The Stream Uptime metadata pop-up not opening in Safari due to the browser's lack of modern JS features. * Fixed: Tool-tips not working within the FFZ Control Center. * Fixed: Tool-tip positioning when in Portrait Mode. * Fixed: The `Current Category` rule type for profiles not matching on directory pages.
This commit is contained in:
parent
3e653c0381
commit
6e93d712bd
10 changed files with 77 additions and 355 deletions
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "frankerfacez",
|
"name": "frankerfacez",
|
||||||
"author": "Dan Salvato LLC",
|
"author": "Dan Salvato LLC",
|
||||||
"version": "4.14.11",
|
"version": "4.14.12",
|
||||||
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -4,6 +4,27 @@
|
||||||
<h2>{{ t('home.changelog', 'Changelog') }}</h2>
|
<h2>{{ t('home.changelog', 'Changelog') }}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="tw-mg-b-1 tw-flex tw-align-items-center">
|
||||||
|
<div class="tw-flex-grow-1" />
|
||||||
|
<div class="tw-checkbox tw-relative tw-tooltip-wrapper">
|
||||||
|
<input
|
||||||
|
id="nonversioned"
|
||||||
|
ref="nonversioned"
|
||||||
|
v-model="nonversioned"
|
||||||
|
type="checkbox"
|
||||||
|
class="tw-checkbox__input"
|
||||||
|
>
|
||||||
|
|
||||||
|
<label for="nonversioned" class="tw-checkbox__label">
|
||||||
|
{{ t('home.changelog.show-nonversioned', 'Include non-versioned commits.') }}
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="tw-tooltip tw-balloon--md tw-tooltip--wrap tw-tooltip--down tw-tooltip--align-right">
|
||||||
|
{{ t('home.changelog.about-nonversioned', 'Non-versioned commits are commits to the FrankerFaceZ repository not associated with a release build. They typically represent maintenance or contributions from the community that will be included in a subsequent release.') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="commit of display" :key="commit.sha" class="tw-mg-b-2">
|
<li v-for="commit of display" :key="commit.sha" class="tw-mg-b-2">
|
||||||
<div class="tw-flex tw-align-items-center tw-border-b tw-mg-b-05">
|
<div class="tw-flex tw-align-items-center tw-border-b tw-mg-b-05">
|
||||||
|
@ -60,6 +81,7 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
error: false,
|
error: false,
|
||||||
|
nonversioned: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
more: true,
|
more: true,
|
||||||
commits: []
|
commits: []
|
||||||
|
@ -75,14 +97,16 @@ export default {
|
||||||
let message = commit.commit.message,
|
let message = commit.commit.message,
|
||||||
title = old_commit;
|
title = old_commit;
|
||||||
|
|
||||||
const match = TITLE_MATCH.exec(message),
|
const match = TITLE_MATCH.exec(message);
|
||||||
date = new Date(commit.commit.author.date),
|
|
||||||
active = commit.sha === window.FrankerFaceZ.version_info.commit;
|
|
||||||
|
|
||||||
if ( match ) {
|
if ( match ) {
|
||||||
title = match[1];
|
title = match[1];
|
||||||
message = message.slice(match[0].length);
|
message = message.slice(match[0].length);
|
||||||
}
|
} else if ( ! this.nonversioned )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const date = new Date(commit.commit.author.date),
|
||||||
|
active = commit.sha === window.FrankerFaceZ.version_info.commit;
|
||||||
|
|
||||||
out.push({
|
out.push({
|
||||||
title,
|
title,
|
||||||
|
|
|
@ -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'}).then(perm => perm?.state).catch(() => null),
|
navigator?.permissions?.query?.({name: 'clipboard-write'}).then(perm => perm?.state).catch(() => null),
|
||||||
data.getBroadcastID()
|
data.getBroadcastID()
|
||||||
]);
|
]);
|
||||||
if ( ! broadcast_id )
|
if ( ! broadcast_id )
|
||||||
|
@ -351,343 +351,8 @@ export default class Metadata extends Module {
|
||||||
for(const inst of legacy_bar.ChannelBar.instances)
|
for(const inst of legacy_bar.ChannelBar.instances)
|
||||||
legacy_bar.updateMetadata(inst, keys);
|
legacy_bar.updateMetadata(inst, keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*const game_header = this.resolve('site.directory.game');
|
|
||||||
if ( game_header ) {
|
|
||||||
for(const inst of game_header.GameHeader.instances)
|
|
||||||
game_header.updateMetadata(inst, keys);
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*async render(key, data, container, timers, refresh_fn) {
|
|
||||||
if ( timers[key] )
|
|
||||||
clearTimeout(timers[key]);
|
|
||||||
|
|
||||||
let el = container.querySelector(`.ffz-stat[data-key="${key}"]`);
|
|
||||||
|
|
||||||
const def = this.definitions[key],
|
|
||||||
destroy = () => {
|
|
||||||
if ( el ) {
|
|
||||||
if ( el.tooltip )
|
|
||||||
el.tooltip.destroy();
|
|
||||||
|
|
||||||
if ( el.popper )
|
|
||||||
el.popper.destroy();
|
|
||||||
|
|
||||||
if ( el._ffz_destroy )
|
|
||||||
el._ffz_destroy();
|
|
||||||
|
|
||||||
el._ffz_destroy = el.tooltip = el.popper = null;
|
|
||||||
el.remove();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if ( ! def || (data._mt || 'channel') !== (def.type || 'channel') )
|
|
||||||
return destroy();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Process the data if a setup method is defined.
|
|
||||||
if ( def.setup )
|
|
||||||
data = await def.setup.call(this, data);
|
|
||||||
|
|
||||||
// Let's get refresh logic out of the way now.
|
|
||||||
let refresh = maybe_call(def.refresh, this, data);
|
|
||||||
let fade_in = maybe_call(def.fade_in, this, data);
|
|
||||||
|
|
||||||
// Grab the element again in case it changed, somehow.
|
|
||||||
el = container.querySelector(`.ffz-sidebar-stat[data-key="${key}"]`);
|
|
||||||
|
|
||||||
if ( refresh && typeof refresh !== 'number' )
|
|
||||||
refresh = 1000;
|
|
||||||
|
|
||||||
if ( fade_in && typeof fade_in !== 'number' )
|
|
||||||
fade_in = 1500;
|
|
||||||
|
|
||||||
if ( fade_in && el && el._ffz_fading ) {
|
|
||||||
// If we have a fade-in and we're still fading in, make sure to
|
|
||||||
// update the metadata when that completes, if not sooner.
|
|
||||||
const remaining = fade_in - (Date.now() - el._ffz_created);
|
|
||||||
if ( remaining <= 0 ) {
|
|
||||||
el._ffz_fading = false;
|
|
||||||
el.classList.remove('ffz--fade-in');
|
|
||||||
|
|
||||||
} else if ( ! refresh || remaining <= refresh )
|
|
||||||
refresh = remaining;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( refresh )
|
|
||||||
timers[key] = setTimeout(
|
|
||||||
() => refresh_fn(key),
|
|
||||||
typeof refresh === 'number' ? refresh : 1000
|
|
||||||
);
|
|
||||||
|
|
||||||
let stat, old_color, sub_el;
|
|
||||||
|
|
||||||
const label = maybe_call(def.label, this, data);
|
|
||||||
|
|
||||||
if ( ! label )
|
|
||||||
return destroy();
|
|
||||||
|
|
||||||
const tooltip = maybe_call(def.tooltip, this, data),
|
|
||||||
subtitle = maybe_call(def.subtitle, this, data),
|
|
||||||
order = maybe_call(def.order, this, data),
|
|
||||||
color = maybe_call(def.color, this, data) || '';
|
|
||||||
|
|
||||||
if ( ! el ) {
|
|
||||||
let icon = maybe_call(def.icon, this, data);
|
|
||||||
let button = false;
|
|
||||||
|
|
||||||
el = (<div
|
|
||||||
class="ffz-sidebar-stat tw-flex tw-flex-grow-1 tw-flex-column tw-justify-content-center"
|
|
||||||
data-key={key}
|
|
||||||
tip_content={tooltip}
|
|
||||||
/>);
|
|
||||||
|
|
||||||
if ( def.button !== false && (def.popup || def.click) ) {
|
|
||||||
button = true;
|
|
||||||
|
|
||||||
let btn, popup;
|
|
||||||
let cls = maybe_call(def.button, this, data);
|
|
||||||
if ( typeof cls !== 'string' )
|
|
||||||
cls = cls ? 'ffz-button--hollow' : 'tw-button--text';
|
|
||||||
|
|
||||||
if ( typeof icon === 'string' )
|
|
||||||
icon = (<span class="tw-button__icon tw-button__icon--left"><figure class={icon} /></span>);
|
|
||||||
|
|
||||||
if ( def.popup && def.click ) {
|
|
||||||
el.appendChild(<div class="tw-flex tw--full-width tw-flex-no-wrap">
|
|
||||||
{btn = (<button class={`tw-interactive tw-button tw-button--full-width ${cls} ffz-has-stat-arrow`}>
|
|
||||||
{icon}
|
|
||||||
{stat = <div class="tw-button__text ffz-sidebar-stat--label" />}
|
|
||||||
</button>)}
|
|
||||||
{popup = (<button class={`tw-button ${cls} ffz-stat-arrow`}>
|
|
||||||
<span class="tw-button__icon tw-pd-x-0">
|
|
||||||
<figure class="ffz-i-down-dir" />
|
|
||||||
</span>
|
|
||||||
</button>)}
|
|
||||||
</div>);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
el.appendChild(btn = popup = (<button class={`tw-interactive tw-button tw-button--full-width ${cls}`}>
|
|
||||||
{icon}
|
|
||||||
{stat = <div class="tw-button__text ffz-sidebar-stat--label" />}
|
|
||||||
{def.popup && <span class="tw-button__icon tw-button__icon--right">
|
|
||||||
<figure class="ffz-i-down-dir" />
|
|
||||||
</span>}
|
|
||||||
</button>));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( def.click )
|
|
||||||
btn.addEventListener('click', e => {
|
|
||||||
if ( el._ffz_fading || btn.disabled || btn.classList.contains('disabled') || el.disabled || el.classList.contains('disabled') )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
def.click.call(this, el._ffz_data, e, () => refresh_fn(key));
|
|
||||||
});
|
|
||||||
|
|
||||||
if ( def.popup )
|
|
||||||
popup.addEventListener('click', () => {
|
|
||||||
if ( el._ffz_fading || popup.disabled || popup.classList.contains('disabled') || el.disabled || el.classList.contains('disabled') )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if ( el._ffz_popup )
|
|
||||||
return el._ffz_destroy();
|
|
||||||
|
|
||||||
const listeners = [],
|
|
||||||
add_close_listener = cb => listeners.push(cb);
|
|
||||||
|
|
||||||
const destroy = el._ffz_destroy = () => {
|
|
||||||
for(const cb of listeners) {
|
|
||||||
try {
|
|
||||||
cb();
|
|
||||||
} catch(err) {
|
|
||||||
this.log.capture(err, {
|
|
||||||
tags: {
|
|
||||||
metadata: key
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.log.error('Error when running a callback for pop-up destruction for metadata:', key, err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( el._ffz_outside )
|
|
||||||
el._ffz_outside.destroy();
|
|
||||||
|
|
||||||
if ( el._ffz_popup ) {
|
|
||||||
const fp = el._ffz_popup;
|
|
||||||
el._ffz_popup = null;
|
|
||||||
fp.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
el._ffz_destroy = el._ffz_outside = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
const parent = document.body.querySelector('body #root,body'),
|
|
||||||
tt = el._ffz_popup = new Tooltip(parent, el, {
|
|
||||||
logger: this.log,
|
|
||||||
manual: true,
|
|
||||||
html: true,
|
|
||||||
live: false,
|
|
||||||
|
|
||||||
tooltipClass: 'ffz-metadata-balloon tw-balloon tw-block tw-border tw-elevation-1 tw-border-radius-small tw-c-background-base tw-c-text-base',
|
|
||||||
// Hide the arrow for now, until we re-do our CSS to make it render correctly.
|
|
||||||
arrowClass: 'tw-balloon__tail tw-overflow-hidden tw-absolute',
|
|
||||||
arrowInner: 'tw-balloon__tail-symbol tw-border-t tw-border-r tw-border-b tw-border-l tw-border-radius-small tw-c-background-base tw-absolute',
|
|
||||||
innerClass: 'tw-pd-1',
|
|
||||||
|
|
||||||
popper: {
|
|
||||||
placement: 'right-start',
|
|
||||||
modifiers: {
|
|
||||||
preventOverflow: {
|
|
||||||
boundariesElement: parent
|
|
||||||
},
|
|
||||||
flip: {
|
|
||||||
behavior: ['top', 'bottom', 'left', 'right']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
content: (t, tip) => def.popup.call(this, el._ffz_data, tip, () => refresh_fn(key), add_close_listener),
|
|
||||||
onShow: (t, tip) =>
|
|
||||||
setTimeout(() => {
|
|
||||||
el._ffz_outside = new ClickOutside(tip.outer, destroy);
|
|
||||||
}),
|
|
||||||
onHide: destroy
|
|
||||||
});
|
|
||||||
|
|
||||||
tt._enter(el);
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
el.appendChild(<div class="tw-align-items-center tw-flex tw-justify-content-center tw-font-size-4">
|
|
||||||
{stat = <div class="tw-strong ffz-sidebar-stat--label" />}
|
|
||||||
</div>);
|
|
||||||
|
|
||||||
if ( def.click )
|
|
||||||
el.addEventListener('click', e => {
|
|
||||||
if ( el._ffz_fading || el.disabled || el.classList.contains('disabled') )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
def.click.call(this, el._ffz_data, e, () => refresh_fn(key));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
el.appendChild(sub_el = <div class="tw-flex tw-justify-content-center tw-c-text-alt-2 tw-font-size-6 ffz-sidebar-stat--subtitle" />);
|
|
||||||
|
|
||||||
let subcontainer;
|
|
||||||
|
|
||||||
if ( button ) {
|
|
||||||
subcontainer = container.querySelector('.ffz-sidebar-stats--buttons');
|
|
||||||
if ( ! subcontainer )
|
|
||||||
container.appendChild(subcontainer = (<div class="tw-flex tw-flex-wrap tw-justify-content-between ffz-sidebar-stats ffz-sidebar-stats--buttons" />));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
subcontainer = container.querySelector('.ffz-sidebar-stats--stats');
|
|
||||||
if ( ! subcontainer ) {
|
|
||||||
subcontainer = (<div class="tw-flex tw-flex-wrap tw-justify-content-between ffz-sidebar-stats ffz-sidebar-stats--stats" />);
|
|
||||||
const btns = container.querySelector('.ffz-sidebar-stats--buttons');
|
|
||||||
if ( btns )
|
|
||||||
container.insertBefore(subcontainer, btns);
|
|
||||||
else
|
|
||||||
container.appendChild(subcontainer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
el._ffz_order = order;
|
|
||||||
|
|
||||||
if ( order != null )
|
|
||||||
el.style.order = order;
|
|
||||||
|
|
||||||
el._ffz_created = Date.now();
|
|
||||||
|
|
||||||
if ( fade_in ) {
|
|
||||||
el._ffz_fading = true;
|
|
||||||
el.classList.add('ffz--fade-in');
|
|
||||||
el.style.setProperty('--ffz-fade-duration', `${fade_in/1000}s`);
|
|
||||||
}
|
|
||||||
|
|
||||||
subcontainer.appendChild(el);
|
|
||||||
|
|
||||||
if ( def.tooltip ) {
|
|
||||||
const parent = document.body.querySelector('body #root,body');
|
|
||||||
el.tooltip = new Tooltip(parent, el, {
|
|
||||||
logger: this.log,
|
|
||||||
live: false,
|
|
||||||
html: true,
|
|
||||||
content: () => el.tip_content,
|
|
||||||
onShow: (t, tip) => el.tip = tip,
|
|
||||||
onHide: () => el.tip = null,
|
|
||||||
popper: {
|
|
||||||
placement: 'top',
|
|
||||||
modifiers: {
|
|
||||||
flip: {
|
|
||||||
behavior: ['bottom', 'top']
|
|
||||||
},
|
|
||||||
preventOverflow: {
|
|
||||||
boundariesElement: parent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
stat = el.querySelector('.ffz-sidebar-stat--label');
|
|
||||||
sub_el = el.querySelector('.ffz-sidebar-stat--subtitle')
|
|
||||||
old_color = el.dataset.color || '';
|
|
||||||
|
|
||||||
if ( el._ffz_order !== order )
|
|
||||||
el.style.order = el._ffz_order = order;
|
|
||||||
|
|
||||||
if ( el.tip_content !== tooltip ) {
|
|
||||||
el.tip_content = tooltip;
|
|
||||||
if ( el.tip )
|
|
||||||
el.tip.element.innerHTML = tooltip;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( old_color !== color )
|
|
||||||
el.dataset.color = el.style.color = color;
|
|
||||||
|
|
||||||
el._ffz_data = data;
|
|
||||||
|
|
||||||
setChildren(stat, label, true);
|
|
||||||
setChildren(sub_el, subtitle, true);
|
|
||||||
|
|
||||||
if ( def.disabled !== undefined )
|
|
||||||
el.disabled = maybe_call(def.disabled, this, data);
|
|
||||||
|
|
||||||
if ( typeof def.button === 'function' ) {
|
|
||||||
const btn = el.querySelector('button');
|
|
||||||
if ( btn ) {
|
|
||||||
let cls = maybe_call(def.button, this, data);
|
|
||||||
if ( typeof cls !== 'string' )
|
|
||||||
cls = cls ? 'ffz-button--hollow' : 'tw-button--text';
|
|
||||||
|
|
||||||
if ( btn._class !== cls ) {
|
|
||||||
btn._class = cls;
|
|
||||||
|
|
||||||
if ( def.popup && def.click )
|
|
||||||
btn.className = `tw-interactive tw-button tw-button--full-width ${cls} ffz-has-stat-arrow`;
|
|
||||||
else
|
|
||||||
btn.className = `tw-interactive tw-button tw-button--full-width ${cls}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch(err) {
|
|
||||||
this.log.capture(err, {
|
|
||||||
tags: {
|
|
||||||
metadata: key
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.log.error(`Error rendering metadata for ${key}`, err);
|
|
||||||
return destroy();
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
async renderLegacy(key, data, container, timers, refresh_fn) {
|
async renderLegacy(key, data, container, timers, refresh_fn) {
|
||||||
if ( timers[key] )
|
if ( timers[key] )
|
||||||
clearTimeout(timers[key]);
|
clearTimeout(timers[key]);
|
||||||
|
@ -767,7 +432,7 @@ export default class Metadata extends Module {
|
||||||
{btn = (<button
|
{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 ${inherit ? 'ffz-c-text-inherit' : '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' : 'tw-font-size-5 tw-regular'}`}
|
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 ${inherit ? 'ffz-c-text-inherit' : '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' : 'tw-font-size-5 tw-regular'}`}
|
||||||
>
|
>
|
||||||
<div class="tw-align-items-center tw-flex tw-flex-grow-0 tw-justify-center">
|
<div class="tw-align-items-center tw-flex tw-flex-grow-0 tw-justify-center tw-pd-x-1">
|
||||||
{icon}
|
{icon}
|
||||||
{stat = (<span class="ffz-stat-text" />)}
|
{stat = (<span class="ffz-stat-text" />)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -846,6 +511,7 @@ export default class Metadata extends Module {
|
||||||
const parent = document.body.querySelector('#root>div') || document.body,
|
const parent = document.body.querySelector('#root>div') || document.body,
|
||||||
tt = el._ffz_popup = new Tooltip(parent, el, {
|
tt = el._ffz_popup = new Tooltip(parent, el, {
|
||||||
logger: this.log,
|
logger: this.log,
|
||||||
|
i18n: this.i18n,
|
||||||
manual: true,
|
manual: true,
|
||||||
live: false,
|
live: false,
|
||||||
html: true,
|
html: true,
|
||||||
|
|
|
@ -15,6 +15,8 @@ export default class TooltipProvider extends Module {
|
||||||
super(...args);
|
super(...args);
|
||||||
this.types = {};
|
this.types = {};
|
||||||
|
|
||||||
|
this.inject('i18n');
|
||||||
|
|
||||||
this.should_enable = true;
|
this.should_enable = true;
|
||||||
|
|
||||||
this.types.json = target => {
|
this.types.json = target => {
|
||||||
|
@ -66,6 +68,8 @@ export default class TooltipProvider extends Module {
|
||||||
|
|
||||||
this.tips = new Tooltip(container, 'ffz-tooltip', {
|
this.tips = new Tooltip(container, 'ffz-tooltip', {
|
||||||
html: true,
|
html: true,
|
||||||
|
i18n: this.i18n,
|
||||||
|
|
||||||
delayHide: this.checkDelayHide.bind(this),
|
delayHide: this.checkDelayHide.bind(this),
|
||||||
delayShow: this.checkDelayShow.bind(this),
|
delayShow: this.checkDelayShow.bind(this),
|
||||||
content: this.process.bind(this),
|
content: this.process.bind(this),
|
||||||
|
|
|
@ -258,4 +258,4 @@ Twilight.ROUTES = {
|
||||||
|
|
||||||
Twilight.DIALOG_EXCLUSIVE = '.sunlight-root,.twilight-main,.twilight-minimal-root>div,#root>div>.tw-full-height,.clips-root';
|
Twilight.DIALOG_EXCLUSIVE = '.sunlight-root,.twilight-main,.twilight-minimal-root>div,#root>div>.tw-full-height,.clips-root';
|
||||||
Twilight.DIALOG_MAXIMIZED = '.sunlight-page,.twilight-main,.twilight-minimal-root,#root .dashboard-side-nav+.tw-full-height,.clips-root>.tw-full-height .scrollable-area';
|
Twilight.DIALOG_MAXIMIZED = '.sunlight-page,.twilight-main,.twilight-minimal-root,#root .dashboard-side-nav+.tw-full-height,.clips-root>.tw-full-height .scrollable-area';
|
||||||
Twilight.DIALOG_SELECTOR = '.sunlight-root,#root,.twilight-minimal-root>.tw-full-height,.clips-root>.tw-full-height .scrollable-area';
|
Twilight.DIALOG_SELECTOR = '.sunlight-root,#root>div,.twilight-minimal-root>.tw-full-height,.clips-root>.tw-full-height .scrollable-area';
|
|
@ -134,14 +134,22 @@ export default class CSSTweaks extends Module {
|
||||||
changed: val => this.toggleHide('side-offline-channels', val)
|
changed: val => this.toggleHide('side-offline-channels', val)
|
||||||
});
|
});
|
||||||
|
|
||||||
this.settings.add('layout.side-nav.hide-reruns', {
|
this.settings.add('layout.side-nav.rerun-style', {
|
||||||
default: false,
|
default: 1,
|
||||||
ui: {
|
ui: {
|
||||||
path: 'Appearance > Layout >> Side Navigation',
|
path: 'Appearance > Layout >> Side Navigation',
|
||||||
title: 'Hide Reruns',
|
title: 'Display Reruns',
|
||||||
component: 'setting-check-box'
|
component: 'setting-select-box',
|
||||||
|
data: [
|
||||||
|
{value: 0, title: 'Do Not Display'},
|
||||||
|
{value: 1, title: 'Normally'},
|
||||||
|
{value: 2, title: 'Faded (33% Opacity)'}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
changed: val => this.toggleHide('side-rerun-channels', val)
|
changed: val => {
|
||||||
|
this.toggleHide('side-rerun-channels', val === 0);
|
||||||
|
this.toggle('side-rerun-opacity', val === 2);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.settings.add('layout.swap-sidebars', {
|
this.settings.add('layout.swap-sidebars', {
|
||||||
|
@ -293,7 +301,6 @@ export default class CSSTweaks extends Module {
|
||||||
this.toggleHide('side-nav', !this.settings.get('layout.side-nav.show'));
|
this.toggleHide('side-nav', !this.settings.get('layout.side-nav.show'));
|
||||||
this.toggleHide('side-rec-friends', !this.settings.get('layout.side-nav.show-rec-friends'));
|
this.toggleHide('side-rec-friends', !this.settings.get('layout.side-nav.show-rec-friends'));
|
||||||
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('side-rerun-channels', this.settings.get('layout.side-nav.hide-reruns'));
|
|
||||||
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'));
|
||||||
|
|
||||||
|
@ -301,6 +308,10 @@ export default class CSSTweaks extends Module {
|
||||||
this.toggleHide('not-live-bar', this.settings.get('channel.hide-not-live-bar'));
|
this.toggleHide('not-live-bar', this.settings.get('channel.hide-not-live-bar'));
|
||||||
this.toggleHide('channel-live-ind', this.settings.get('channel.hide-live-indicator'));
|
this.toggleHide('channel-live-ind', this.settings.get('channel.hide-live-indicator'));
|
||||||
|
|
||||||
|
const reruns = this.settings.get('layout.side-nav.rerun-style');
|
||||||
|
this.toggleHide('side-rerun-channels', reruns === 0);
|
||||||
|
this.toggle('side-rerun-opacity', reruns === 2);
|
||||||
|
|
||||||
const recs = this.settings.get('layout.side-nav.show-rec-channels');
|
const recs = this.settings.get('layout.side-nav.show-rec-channels');
|
||||||
this.toggleHide('side-rec-channels', recs === 0);
|
this.toggleHide('side-rec-channels', recs === 0);
|
||||||
this.toggleHide('side-closed-rec-channels', recs === 2);
|
this.toggleHide('side-closed-rec-channels', recs === 2);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
--ffz-theater-height: calc(calc(100vw * 0.5625) + var(--ffz-portrait-extra-height));
|
--ffz-theater-height: calc(calc(100vw * 0.5625) + var(--ffz-portrait-extra-height));
|
||||||
--ffz-chat-height: calc(100vh - var(--ffz-player-height));
|
--ffz-chat-height: calc(100vh - var(--ffz-player-height));
|
||||||
|
|
||||||
& > .tw-flex-column {
|
& > .tw-flex-column > .tw-full-height {
|
||||||
.ffz--portrait-invert & {
|
.ffz--portrait-invert & {
|
||||||
top: var(--ffz-chat-height) !important;
|
top: var(--ffz-chat-height) !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
.ffz--side-nav-card-rerun {
|
||||||
|
opacity: 0.33;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.75;
|
||||||
|
}
|
||||||
|
}
|
|
@ -51,6 +51,12 @@ export default class Game extends SiteModule {
|
||||||
onEnable() {
|
onEnable() {
|
||||||
this.GameHeader.on('mount', this.updateGameHeader, this);
|
this.GameHeader.on('mount', this.updateGameHeader, this);
|
||||||
this.GameHeader.on('update', this.updateGameHeader, this);
|
this.GameHeader.on('update', this.updateGameHeader, this);
|
||||||
|
this.GameHeader.on('unmount', () => {
|
||||||
|
this.settings.updateContext({
|
||||||
|
category: null,
|
||||||
|
categoryID: null
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
this.GameHeader.ready((cls, instances) => {
|
this.GameHeader.ready((cls, instances) => {
|
||||||
for(const inst of instances)
|
for(const inst of instances)
|
||||||
|
@ -62,11 +68,12 @@ export default class Game extends SiteModule {
|
||||||
updateGameHeader(inst) {
|
updateGameHeader(inst) {
|
||||||
this.updateButtons(inst);
|
this.updateButtons(inst);
|
||||||
|
|
||||||
/*this.apollo.ensureQuery(
|
const category = inst?.props?.data?.game;
|
||||||
'DirectoryPage_Game',
|
|
||||||
'data.game.streams.edges.0.node.createdAt'
|
|
||||||
);*/
|
|
||||||
|
|
||||||
|
this.settings.updateContext({
|
||||||
|
category: category?.name,
|
||||||
|
categoryID: category?.id
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -329,7 +329,10 @@ export class Tooltip {
|
||||||
if ( this.options.logger )
|
if ( this.options.logger )
|
||||||
this.options.logger.error('Error rendering tooltip content.', err);
|
this.options.logger.error('Error rendering tooltip content.', err);
|
||||||
|
|
||||||
inner.textContent = `There was an error showing this tooltip.\n${err}`;
|
if ( this.options.i18n )
|
||||||
|
inner.textContent = this.options.i18n.t('tooltip.render-error', 'There was an error rendering this tooltip.\n{err}', {err});
|
||||||
|
else
|
||||||
|
inner.textContent = `There was an error rendering this tooltip.\n${err}`;
|
||||||
tip._update();
|
tip._update();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue