mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-27 21:05:53 +00:00
4.20.77
* Changed: The FFZ Control Center's home page now displays a list of new settings when you have new settings, as well as recently updated add-ons. A GitHub link was added as well. The Twitter embed will properly use light theme when appropriate. * Changed: [Add-Ons](~add_ons) now supports sorting by update time, as well as name. * Changed: The FFZ Control Center will now appear larger depending on your window size. * Fixed: The [Add-Ons](~add_ons) list not being properly searchable in the FFZ Control Center. * Fixed: Appearance of unread counters in the FFZ Control Center's navigation. * Fixed: Messages not highlighting correctly when a viewer card is open.
This commit is contained in:
parent
a91907c869
commit
7428781614
12 changed files with 415 additions and 34 deletions
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "frankerfacez",
|
||||
"author": "Dan Salvato LLC",
|
||||
"version": "4.20.76",
|
||||
"version": "4.20.77",
|
||||
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
|
|
|
@ -46,7 +46,7 @@ export default class AddonManager extends Module {
|
|||
title: 'Add-Ons',
|
||||
no_filter: true,
|
||||
|
||||
getExtraSearch: () => Object.values(this.addons).map(addon => addon.search_terms),
|
||||
getExtraTerms: () => Object.values(this.addons).map(addon => addon.search_terms),
|
||||
|
||||
isReady: () => this.enabled,
|
||||
getAddons: () => Object.values(this.addons),
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</h4>
|
||||
|
||||
<button
|
||||
class="tw-button ffz-button--hollow tw-c-text-overlay tw-mg-t-05"
|
||||
class="tw-button tw-button--text tw-c-text-overlay tw-mg-t-05"
|
||||
@click="item.refresh()"
|
||||
>
|
||||
<span class="tw-button__icon tw-button__icon--left">
|
||||
|
@ -18,6 +18,21 @@
|
|||
</button>
|
||||
</div>
|
||||
|
||||
<div class="tw-mg-b-1 tw-flex tw-align-items-center">
|
||||
<div class="tw-flex-grow-1" />
|
||||
<select
|
||||
v-model="sort_by"
|
||||
class="tw-border-radius-medium tw-font-size-6 ffz-select tw-pd-l-1 tw-pd-r-3 tw-pd-y-05 tw-mg-x-05"
|
||||
>
|
||||
<option :value="0">
|
||||
{{ t('addon.sort-name', 'Sort By: Name') }}
|
||||
</option>
|
||||
<option :value="1">
|
||||
{{ t('addon.sort-update', 'Sort By: Updated') }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div v-if="! ready" class="tw-align-center tw-pd-1">
|
||||
<h1 class="tw-mg-5 ffz-i-zreknarf loading" />
|
||||
</div>
|
||||
|
@ -91,6 +106,7 @@ export default {
|
|||
ready: this.item.isReady(),
|
||||
reload: this.item.isReloadRequired(),
|
||||
unlisted: [],
|
||||
sort_by: 0,
|
||||
unlisted_open: false
|
||||
}
|
||||
},
|
||||
|
@ -104,6 +120,11 @@ export default {
|
|||
const addons = this.item.getAddons();
|
||||
|
||||
addons.sort((a, b) => {
|
||||
if ( this.sort_by === 1 ) {
|
||||
if ( a.updated > b.updated ) return -1;
|
||||
if ( b.updated > a.updated ) return 1;
|
||||
}
|
||||
|
||||
if ( a.sort < b.sort ) return -1;
|
||||
if ( b.sort < a.sort ) return 1;
|
||||
|
||||
|
|
|
@ -1,38 +1,53 @@
|
|||
<template lang="html">
|
||||
<div class="ffz--addon-info tw-elevation-1 tw-c-background-base tw-border tw-pd-1 tw-mg-b-1 tw-flex tw-flex-nowrap">
|
||||
<div class="ffz--addon-info tw-elevation-1 tw-c-background-base tw-border tw-border-radius-large tw-pd-1 tw-mg-b-1 tw-flex tw-flex-nowrap">
|
||||
<div class="tw-flex tw-flex-column tw-align-center tw-flex-shrink-0 tw-mg-r-1">
|
||||
<div class="tw-card-img--size-6 tw-overflow-hidden tw-mg-b-1">
|
||||
<img :src="icon" class="tw-image">
|
||||
</div>
|
||||
|
||||
<div v-if="external" class="tw-mg-b-05 tw-pill">
|
||||
<div v-if="external" class="tw-mg-b-05 ffz-pill">
|
||||
{{ t('addon.external', 'External') }}
|
||||
</div>
|
||||
|
||||
<div v-else-if="enabled" class="tw-mg-b-05 tw-pill ffz--pill-enabled">
|
||||
<div v-else-if="enabled" class="tw-mg-b-05 ffz-pill ffz--pill-enabled">
|
||||
{{ t('addon.enabled', 'Enabled') }}
|
||||
</div>
|
||||
|
||||
<div v-if="addon.dev" class="tw-mg-b-05 tw-pill">
|
||||
<div v-if="addon.dev" class="tw-mg-b-05 ffz-pill">
|
||||
{{ t('addon.dev', 'Developer') }}
|
||||
</div>
|
||||
|
||||
<div v-if="addon.unlisted" class="tw-mg-b-05 tw-pill">
|
||||
<div v-if="addon.unlisted" class="tw-mg-b-05 ffz-pill">
|
||||
{{ t('addon.unlisted', 'Unlisted') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tw-flex-grow-1">
|
||||
<div class="tw-border-b tw-mg-b-05">
|
||||
<h4>{{ addon.name_i18n ? t(addon.name_i18n, addon.name) : addon.name }} <span class="tw-c-text-alt-2 tw-font-size-6">({{ addon.id }})</span></h4>
|
||||
<h4>
|
||||
{{ addon.name_i18n ? t(addon.name_i18n, addon.name) : addon.name }}
|
||||
<span
|
||||
v-if="addon.dev || addon.unlisted"
|
||||
class="tw-c-text-alt-2 tw-font-size-6"
|
||||
>
|
||||
({{ addon.id }})
|
||||
</span>
|
||||
</h4>
|
||||
<span class="tw-c-text-alt tw-mg-r-1">
|
||||
{{ t('addon.author', 'By: {author}', {
|
||||
author: addon.author_i18n ? t(addon.author_i18n, addon.author) : addon.author
|
||||
}) }}
|
||||
</span>
|
||||
<span v-if="version" class="tw-c-text-alt">
|
||||
<span v-if="version" class="tw-c-text-alt tw-mg-r-1">
|
||||
{{ t('addon.version', 'Version {version}', {version}) }}
|
||||
</span>
|
||||
<span
|
||||
v-if="addon.updated"
|
||||
:data-title="tDateTime(addon.updated)"
|
||||
class="tw-c-text-alt ffz-tooltip tw-mg-r-1"
|
||||
>
|
||||
{{ t('addon.updated', 'Updated: {when,humantime}', {when: addon.updated}) }}
|
||||
</span>
|
||||
</div>
|
||||
<markdown :source="show_description" />
|
||||
<a
|
||||
|
|
|
@ -13,6 +13,133 @@
|
|||
<section class="tw-pd-t-1 tw-border-t tw-mg-t-1">
|
||||
<markdown :source="t('home.about', md)" />
|
||||
</section>
|
||||
|
||||
<div
|
||||
v-if="unseen"
|
||||
class="tw-pd-t-1 tw-border-t tw-mg-t-1"
|
||||
>
|
||||
<h3 class="tw-pd-b-05">
|
||||
{{ t('home.new-settings', 'New Settings') }}
|
||||
</h3>
|
||||
|
||||
<div class="tw-pd-b-1">
|
||||
{{ t('home.new-settings.desc', 'These are settings that you haven\'t looked at yet.') }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-for="cat of unseen"
|
||||
:key="cat.key"
|
||||
class="tw-mg-b-05"
|
||||
>
|
||||
<a
|
||||
class="tw-strong"
|
||||
href="#"
|
||||
@click.prevent="item.requestPage(cat.key)"
|
||||
>
|
||||
<span
|
||||
v-for="(tk,idx) of cat.tokens"
|
||||
:key="idx"
|
||||
>
|
||||
{{ tk.i18n ? t(tk.i18n, tk.title) : tk.title }}
|
||||
</span>
|
||||
</a>
|
||||
<div
|
||||
v-for="entry of cat.entries"
|
||||
:key="entry.key"
|
||||
class="tw-mg-l-2"
|
||||
>
|
||||
{{ entry.i18n ? t(entry.i18n, entry.title) : entry.title }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="addons"
|
||||
class="tw-pd-t-1 tw-border-t tw-mg-t-1"
|
||||
>
|
||||
<h3 class="tw-pd-b-05">
|
||||
{{ t('home.addon-updates', 'Updated Add-Ons') }}
|
||||
</h3>
|
||||
|
||||
<div class="tw-pd-b-1">
|
||||
<markdown :source="t('home.addon-updates.desc', 'These add-ons have updated within the past seven days. Check the [changelog](~add_ons.changelog) to see what\'s changed.')" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-for="addon of addons"
|
||||
:key="addon.key"
|
||||
class="tw-mg-b-05 tw-flex tw-align-items-center"
|
||||
>
|
||||
<div class="tw-card-img--size-4 tw-overflow-hidden tw-mg-r-1">
|
||||
<img :src="addon.icon" class="tw-image">
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
v-if="addon.enabled && addon.settings"
|
||||
href="#"
|
||||
class="tw-strong tw-link--inherit"
|
||||
@click.prevent="item.requestPage(addon.settings)"
|
||||
>
|
||||
{{ addon.name_i18n ? t(addon.name_i18n, addon.name) : addon.name }}
|
||||
</a>
|
||||
<div v-else class="tw-strong">
|
||||
{{ addon.name_i18n ? t(addon.name_i18n, addon.name) : addon.name }}
|
||||
</div>
|
||||
<div class="tw-c-text-alt">
|
||||
<span class="tw-mg-r-1">
|
||||
{{ t('addon.version', 'Version {version}', addon) }}
|
||||
</span>
|
||||
<span>
|
||||
{{ t('addon.updated', 'Updated: {when,humantime}', {when: addon.updated}) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="new_addons"
|
||||
class="tw-pd-t-1 tw-border-t tw-mg-t-1"
|
||||
>
|
||||
<h3 class="tw-pd-b-05">
|
||||
{{ t('home.addon-new', 'New Add-Ons') }}
|
||||
</h3>
|
||||
|
||||
<div class="tw-pd-b-1">
|
||||
<markdown :source="t('home.addon-new.desc', 'These add-ons were published within the past seven days. Check them out in [Add-Ons](~add_ons).')" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-for="addon of new_addons"
|
||||
:key="addon.key"
|
||||
class="tw-mg-b-05 tw-flex tw-align-items-center"
|
||||
>
|
||||
<div class="tw-card-img--size-4 tw-overflow-hidden tw-mg-r-1">
|
||||
<img :src="addon.icon" class="tw-image">
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
v-if="addon.enabled && addon.settings"
|
||||
href="#"
|
||||
class="tw-strong tw-link--inherit"
|
||||
@click.prevent="item.requestPage(addon.settings)"
|
||||
>
|
||||
{{ addon.name_i18n ? t(addon.name_i18n, addon.name) : addon.name }}
|
||||
</a>
|
||||
<div v-else class="tw-strong">
|
||||
{{ addon.name_i18n ? t(addon.name_i18n, addon.name) : addon.name }}
|
||||
</div>
|
||||
<div class="tw-c-text-alt">
|
||||
<span class="tw-mg-r-1">
|
||||
{{ t('addon.version', 'Version {version}', addon) }}
|
||||
</span>
|
||||
<span>
|
||||
{{ t('addon.updated', 'Updated: {when,humantime}', {when: addon.updated}) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tw-mg-l-1 tw-flex-shrink-0 tweet-column">
|
||||
<div class="tw-flex tw-mg-b-1">
|
||||
|
@ -40,7 +167,7 @@
|
|||
</a>
|
||||
<a
|
||||
:data-title="t('home.twitter', 'Twitter')"
|
||||
class="tw-flex-grow-1 tw-button ffz-tooltip ffz--twitter-button"
|
||||
class="tw-flex-grow-1 tw-button ffz-tooltip ffz--twitter-button tw-mg-r-1"
|
||||
href="https://twitter.com/frankerfacez"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
|
@ -49,9 +176,25 @@
|
|||
<figure class="ffz-i-twitter tw-font-size-3" />
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
:data-title="t('home.github', 'GitHub')"
|
||||
class="tw-flex-grow-1 tw-button ffz-tooltip ffz--github-button"
|
||||
href="https://github.com/FrankerFaceZ/FrankerFaceZ"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<span class="tw-button__icon tw-pd-05">
|
||||
<figure class="ffz-i-github tw-font-size-3" />
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<a class="twitter-timeline" data-width="300" data-theme="dark" href="https://twitter.com/FrankerFaceZ?ref_src=twsrc%5Etfw">
|
||||
<a
|
||||
:data-theme="theme"
|
||||
class="twitter-timeline"
|
||||
data-width="300"
|
||||
href="https://twitter.com/FrankerFaceZ?ref_src=twsrc%5Etfw"
|
||||
>
|
||||
{{ t('home.tweets', 'Tweets by FrankerFaceZ') }}
|
||||
</a>
|
||||
</div>
|
||||
|
@ -70,10 +213,32 @@ export default {
|
|||
|
||||
data() {
|
||||
return {
|
||||
md: HOME_MD
|
||||
md: HOME_MD,
|
||||
theme: '',
|
||||
addons: null,
|
||||
new_addons: null,
|
||||
unseen: this.item.getUnseen()
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.updateAddons();
|
||||
this.updateTheme();
|
||||
this.context.context.on('changed:theme.is-dark', this.updateTheme, this);
|
||||
|
||||
const ffz = this.context.getFFZ();
|
||||
ffz.on('main_menu:update-unseen', this.updateUnseen, this);
|
||||
ffz.on('addons:data-loaded', this.updateAddons, this);
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.context.context.off('changed:theme.is-dark', this.updateTheme, this);
|
||||
|
||||
const ffz = this.context.getFFZ();
|
||||
ffz.off('main_menu:update-unseen', this.updateUnseen, this);
|
||||
ffz.off('addons:data-loaded', this.updateAddons, this);
|
||||
},
|
||||
|
||||
mounted() {
|
||||
let el;
|
||||
document.head.appendChild(el = e('script', {
|
||||
|
@ -83,7 +248,54 @@ export default {
|
|||
src: 'https://platform.twitter.com/widgets.js',
|
||||
onLoad: () => el.remove()
|
||||
}));
|
||||
},
|
||||
|
||||
methods: {
|
||||
updateUnseen() {
|
||||
this.unseen = this.item.getUnseen();
|
||||
},
|
||||
|
||||
updateAddons() {
|
||||
const ffz = this.context.getFFZ(),
|
||||
addon_module = ffz.resolve('addons'),
|
||||
addons = addon_module?.addons;
|
||||
|
||||
const out = [],
|
||||
new_out = [],
|
||||
week_ago = Date.now() - (86400 * 7 * 1000);
|
||||
|
||||
if ( addons )
|
||||
for(const [key, addon] of Object.entries(addons)) {
|
||||
const enabled = addon_module.isAddonEnabled(key),
|
||||
copy = {
|
||||
key,
|
||||
enabled,
|
||||
icon: addon.icon,
|
||||
name: addon.name,
|
||||
name_i18n: addon.name_i18n,
|
||||
updated: addon.updated,
|
||||
settings: addon.settings,
|
||||
version: addon.version
|
||||
};
|
||||
|
||||
if ( addon.created && addon.created >= week_ago )
|
||||
new_out.push(copy);
|
||||
|
||||
if ( addon.updated && addon.updated >= week_ago && enabled ) {
|
||||
out.push(copy);
|
||||
}
|
||||
}
|
||||
|
||||
out.sort((a,b) => b.updated - a.updated);
|
||||
new_out.sort((a,b) => b.created - a.created);
|
||||
|
||||
this.addons = out.length ? out : null;
|
||||
this.new_addons = new_out.length ? new_out : null;
|
||||
},
|
||||
|
||||
updateTheme() {
|
||||
this.theme = this.context.context.get('theme.is-dark') ? 'dark' : 'light'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -110,6 +110,7 @@
|
|||
:context="context"
|
||||
:item="currentItem"
|
||||
:filter="filter"
|
||||
:nav_keys="nav_keys"
|
||||
@change-item="changeItem"
|
||||
@mark-seen="markSeen"
|
||||
@navigate="navigate"
|
||||
|
|
|
@ -82,6 +82,7 @@
|
|||
ref="children"
|
||||
:context="context"
|
||||
:item="i"
|
||||
:nav_keys="nav_keys"
|
||||
:filter="filter"
|
||||
@change-item="changeItem"
|
||||
@mark-seen="markSeen"
|
||||
|
@ -94,7 +95,7 @@
|
|||
<script>
|
||||
|
||||
export default {
|
||||
props: ['item', 'context', 'filter'],
|
||||
props: ['item', 'context', 'filter', 'nav_keys'],
|
||||
|
||||
computed: {
|
||||
breadcrumbs() {
|
||||
|
|
|
@ -35,10 +35,10 @@
|
|||
<span class="tw-flex-grow-1">
|
||||
{{ t(item.i18n_key, item.title) }}
|
||||
</span>
|
||||
<span v-if="item.pill" class="tw-pill">
|
||||
<span v-if="item.pill" class="ffz-pill ffz-pill--overlay">
|
||||
{{ item.pill_i18n_key ? t(item.pill_i18n_key, item.pill) : item.pill }}
|
||||
</span>
|
||||
<span v-else-if="item.unseen" class="tw-pill">
|
||||
<span v-else-if="item.unseen" class="ffz-pill ffz-pill--overlay">
|
||||
{{ item.unseen }}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import Module from 'utilities/module';
|
||||
import {createElement} from 'utilities/dom';
|
||||
import {get, has, deep_copy} from 'utilities/object';
|
||||
import {get, has, deep_copy, set_equals} from 'utilities/object';
|
||||
|
||||
import Dialog from 'utilities/dialog';
|
||||
|
||||
|
@ -19,6 +19,7 @@ function format_term(term) {
|
|||
return term.replace(/<[^>]*>/g, '').toLocaleLowerCase();
|
||||
}
|
||||
|
||||
|
||||
// TODO: Rewrite literally everything about the menu to use a router and further
|
||||
// separate the concept of navigation from visible pages.
|
||||
|
||||
|
@ -76,7 +77,72 @@ export default class MainMenu extends Module {
|
|||
|
||||
this.settings.addUI('home', {
|
||||
path: 'Home @{"sort": -1000, "profile_warning": false}',
|
||||
component: 'home-page'
|
||||
component: 'home-page',
|
||||
requestPage: page => this.requestPage(page),
|
||||
getUnseen: () => {
|
||||
if ( ! this.unseen?.size )
|
||||
return null;
|
||||
|
||||
const categories = {},
|
||||
out = [];
|
||||
|
||||
let i = 0;
|
||||
|
||||
for(const item of this.unseen) {
|
||||
const def = this.settings.definitions.get(item) || this.settings.ui_structures.get(item);
|
||||
if ( ! def || ! def.ui || ! def.ui.path_tokens )
|
||||
continue;
|
||||
|
||||
const path = def.ui.path,
|
||||
title = def.ui.title;
|
||||
|
||||
i++;
|
||||
if ( i > 20 )
|
||||
break;
|
||||
|
||||
if ( ! categories[path] ) {
|
||||
const key = def.ui.path_tokens.map(x => x.key).join('.');
|
||||
const tokens = [];
|
||||
|
||||
let cat = this._settings_tree[key];
|
||||
while ( cat ) {
|
||||
tokens.unshift({
|
||||
i18n: cat.i18n_key,
|
||||
title: cat.title
|
||||
});
|
||||
|
||||
if ( cat.parent ) {
|
||||
if ( cat.page || cat.tab )
|
||||
tokens.unshift({title: '>>'});
|
||||
else
|
||||
tokens.unshift({title: '>'});
|
||||
}
|
||||
|
||||
cat = this._settings_tree[cat.parent];
|
||||
}
|
||||
|
||||
out.push(categories[path] = {
|
||||
key,
|
||||
tokens,
|
||||
entries: []
|
||||
});
|
||||
}
|
||||
|
||||
if ( ! path || ! title )
|
||||
continue;
|
||||
|
||||
categories[path].entries.push({
|
||||
key: item,
|
||||
i18n: def.ui.i18n_key ?? `setting.entry.${item}`,
|
||||
title
|
||||
});
|
||||
}
|
||||
|
||||
if ( ! out.length )
|
||||
return null;
|
||||
|
||||
return out;
|
||||
}
|
||||
});
|
||||
|
||||
this.settings.addUI('faq', {
|
||||
|
@ -484,6 +550,7 @@ export default class MainMenu extends Module {
|
|||
|
||||
const tree = this._settings_tree,
|
||||
settings_seen = this.new_seen ? null : this.settings.provider.get('cfg-seen'),
|
||||
unseen = settings_seen ? new Set : null,
|
||||
new_seen = settings_seen ? null : [],
|
||||
|
||||
collapsed = this.settings.provider.get('cfg-collapsed'),
|
||||
|
@ -569,6 +636,7 @@ export default class MainMenu extends Module {
|
|||
|
||||
if ( settings_seen ) {
|
||||
if ( ! settings_seen.includes(setting_key) && ! tok.force_seen ) {
|
||||
unseen.add(setting_key);
|
||||
let i = tok;
|
||||
while(i) {
|
||||
i.unseen = (i.unseen || 0) + 1;
|
||||
|
@ -660,6 +728,11 @@ export default class MainMenu extends Module {
|
|||
this.settings.provider.set('cfg-collapsed', new_collapsed);
|
||||
}
|
||||
|
||||
if ( ! set_equals(unseen, this.unseen) ) {
|
||||
this.unseen = unseen;
|
||||
this.emit(':update-unseen');
|
||||
}
|
||||
|
||||
this.log.info(`Built Tree in ${(performance.now() - started).toFixed(5)}ms with ${Object.keys(tree).length} structure nodes and ${this._settings_count} settings nodes.`);
|
||||
return items;
|
||||
}
|
||||
|
@ -897,7 +970,9 @@ export default class MainMenu extends Module {
|
|||
}
|
||||
|
||||
markSeen(item, seen) {
|
||||
let had_seen = true;
|
||||
let had_seen = true,
|
||||
changed = false;
|
||||
|
||||
if ( ! seen ) {
|
||||
had_seen = false;
|
||||
seen = this.settings.provider.get('cfg-seen', []);
|
||||
|
@ -905,12 +980,15 @@ export default class MainMenu extends Module {
|
|||
|
||||
if ( Array.isArray(item.contents) ) {
|
||||
for(const child of item.contents)
|
||||
child && this.markSeen(child, seen);
|
||||
|
||||
changed = (child && this.markSeen(child, seen)) || changed;
|
||||
}
|
||||
|
||||
if ( item.setting ) {
|
||||
if ( this.unseen )
|
||||
this.unseen.delete(item.setting);
|
||||
|
||||
if ( ! seen.includes(item.setting) ) {
|
||||
changed = true;
|
||||
seen.push(item.setting);
|
||||
|
||||
let i = item.parent;
|
||||
|
@ -921,8 +999,12 @@ export default class MainMenu extends Module {
|
|||
}
|
||||
}
|
||||
|
||||
if ( ! had_seen )
|
||||
if ( ! had_seen && changed ) {
|
||||
this.settings.provider.set('cfg-seen', seen);
|
||||
this.emit(':update-unseen');
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
markAllSeen(thing, seen) {
|
||||
|
@ -960,8 +1042,11 @@ export default class MainMenu extends Module {
|
|||
if ( thing.unseen )
|
||||
thing.unseen = 0;
|
||||
|
||||
if ( ! had_seen )
|
||||
if ( ! had_seen ) {
|
||||
this.settings.provider.set('cfg-seen', seen);
|
||||
this.unseen = null;
|
||||
this.emit(':update-unseen');
|
||||
}
|
||||
}
|
||||
|
||||
getData() {
|
||||
|
|
|
@ -45,7 +45,7 @@ export default class ViewerCards extends Module {
|
|||
|
||||
this.ViewerCard = this.fine.define(
|
||||
'chat-viewer-card',
|
||||
n => n.trackViewerCardOpen && n.onWhisperButtonClick
|
||||
n => n.props?.targetLogin && n.props?.hideViewerCard
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,15 @@
|
|||
height: 50vh;
|
||||
width: 50vw;
|
||||
|
||||
min-width: 640px;
|
||||
min-height: 300px;
|
||||
min-width: 64rem;
|
||||
min-height: 30rem;
|
||||
|
||||
--width: #{"min(75vw, 128rem)"};
|
||||
width: 75vw;
|
||||
width: var(--width);
|
||||
|
||||
height: 50vh;
|
||||
height: #{"min(75vh, calc(0.75 * var(--width)))"};
|
||||
|
||||
> header {
|
||||
cursor: move;
|
||||
|
|
|
@ -76,16 +76,41 @@ textarea.ffz-input {
|
|||
height: unset;
|
||||
}
|
||||
|
||||
.ffz--widget {
|
||||
.tw-pill {
|
||||
border-radius: 1000px;
|
||||
padding: 0.3rem 0.8em;
|
||||
font-size: 75%;
|
||||
background-color: var(--color-background-pill);
|
||||
color: var(--color-text-overlay);
|
||||
white-space: nowrap;
|
||||
.ffz-pill,
|
||||
.ffz--widget .tw-pill {
|
||||
border-radius: 1000px;
|
||||
padding: 0.3rem 0.8em;
|
||||
font-size: 75%;
|
||||
background-color: var(--color-background-pill);
|
||||
color: var(--color-text-overlay);
|
||||
white-space: nowrap;
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
|
||||
&:empty { display: none }
|
||||
|
||||
&--alt { background-color: var(--color-fill-alt) }
|
||||
&--alt-2 { background-color: var(--color-fill-alt-2) }
|
||||
&--brand { background-color: var(--color-fill-brand) }
|
||||
&--notification { background-color: var(--color-background-pill-notification) }
|
||||
&--live { background-color: var(--color-fill-live) }
|
||||
&--warn { background-color: var(--color-fill-warn) }
|
||||
&--alert { background-color: var(--color-fill-alert) }
|
||||
&--success { background-color: var(--color-fill-success) }
|
||||
&--overlay {
|
||||
background-color: var(--color-background-overlay);
|
||||
box-shadow: 0 0 0 1px var(--color-border-overlay);
|
||||
}
|
||||
|
||||
&--warn,
|
||||
&--alert,
|
||||
&--success {
|
||||
color: var(--color-text-pill);
|
||||
}
|
||||
}
|
||||
|
||||
.ffz--widget {
|
||||
input, select {
|
||||
min-width: 20rem;
|
||||
}
|
||||
|
@ -345,6 +370,20 @@ textarea.ffz-input {
|
|||
}
|
||||
}
|
||||
|
||||
.ffz--github-button {
|
||||
border: 0 !important;
|
||||
background-color: #1e2327 !important;
|
||||
color: #fff !important;
|
||||
|
||||
> * {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&:hover, &:focus {
|
||||
background-color: #3b454d !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.ffz--changelog {
|
||||
ul, p {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue