mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-08-06 06:10:54 +00:00
4.20.23
* Added: Accent Color customization, in `Appearance > Theme`. * Added: Previews for custom date/time formats in `Appearance > Localization`. * Changed: Assume Twitch clip and video thumbnails are Safe-For-Work. * Fixed: Changelog dates not using i18n formatting. (Closes #873) * Fixed: Icon picker string not localizing properly. * Removed `Gray (no Purple)` legacy CSS. It's been breaking more and more over time, and it's not necessary at all with the new Accent Color setting.
This commit is contained in:
parent
6310a2ed49
commit
a5e2dd9ef2
10 changed files with 198 additions and 114 deletions
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "frankerfacez",
|
"name": "frankerfacez",
|
||||||
"author": "Dan Salvato LLC",
|
"author": "Dan Salvato LLC",
|
||||||
"version": "4.20.22",
|
"version": "4.20.23",
|
||||||
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
21
src/i18n.js
21
src/i18n.js
|
@ -180,8 +180,13 @@ export class TranslationManager extends Module {
|
||||||
ui: {
|
ui: {
|
||||||
path: 'Appearance > Localization >> Formatting',
|
path: 'Appearance > Localization >> Formatting',
|
||||||
title: 'Date Format',
|
title: 'Date Format',
|
||||||
description: 'The default date format. Custom date formats are formated using the [Day.js](https://github.com/iamkun/dayjs#readme) library.',
|
description: 'The default date format. Custom date formats are formated using the [Day.js](https://day.js.org/docs/en/display/format) library.',
|
||||||
component: 'setting-combo-box',
|
component: 'setting-combo-box',
|
||||||
|
extra: {
|
||||||
|
before: true,
|
||||||
|
mode: 'date',
|
||||||
|
component: 'format-preview'
|
||||||
|
},
|
||||||
data: () => {
|
data: () => {
|
||||||
const out = [], now = new Date;
|
const out = [], now = new Date;
|
||||||
for (const [key,fmt] of Object.entries(this._.formats.date)) {
|
for (const [key,fmt] of Object.entries(this._.formats.date)) {
|
||||||
|
@ -205,8 +210,13 @@ export class TranslationManager extends Module {
|
||||||
ui: {
|
ui: {
|
||||||
path: 'Appearance > Localization >> Formatting',
|
path: 'Appearance > Localization >> Formatting',
|
||||||
title: 'Time Format',
|
title: 'Time Format',
|
||||||
description: 'The default time format. Custom time formats are formated using the [Day.js](https://github.com/iamkun/dayjs#readme) library.',
|
description: 'The default time format. Custom time formats are formated using the [Day.js](https://day.js.org/docs/en/display/format) library.',
|
||||||
component: 'setting-combo-box',
|
component: 'setting-combo-box',
|
||||||
|
extra: {
|
||||||
|
before: true,
|
||||||
|
mode: 'time',
|
||||||
|
component: 'format-preview'
|
||||||
|
},
|
||||||
data: () => {
|
data: () => {
|
||||||
const out = [], now = new Date;
|
const out = [], now = new Date;
|
||||||
for (const [key,fmt] of Object.entries(this._.formats.time)) {
|
for (const [key,fmt] of Object.entries(this._.formats.time)) {
|
||||||
|
@ -230,8 +240,13 @@ export class TranslationManager extends Module {
|
||||||
ui: {
|
ui: {
|
||||||
path: 'Appearance > Localization >> Formatting',
|
path: 'Appearance > Localization >> Formatting',
|
||||||
title: 'Date-Time Format',
|
title: 'Date-Time Format',
|
||||||
description: 'The default combined date-time format. Custom time formats are formated using the [Day.js](https://github.com/iamkun/dayjs#readme) library.',
|
description: 'The default combined date-time format. Custom time formats are formated using the [Day.js](https://day.js.org/docs/en/display/format) library.',
|
||||||
component: 'setting-combo-box',
|
component: 'setting-combo-box',
|
||||||
|
extra: {
|
||||||
|
before: true,
|
||||||
|
mode: 'datetime',
|
||||||
|
component: 'format-preview'
|
||||||
|
},
|
||||||
data: () => {
|
data: () => {
|
||||||
const out = [], now = new Date;
|
const out = [], now = new Date;
|
||||||
for (const [key,fmt] of Object.entries(this._.formats.datetime)) {
|
for (const [key,fmt] of Object.entries(this._.formats.datetime)) {
|
||||||
|
|
|
@ -261,7 +261,7 @@ export const Clips = {
|
||||||
|
|
||||||
short: {
|
short: {
|
||||||
type: 'header',
|
type: 'header',
|
||||||
image: {type: 'image', url: clip.thumbnailURL, sfw: false, aspect: 16/9},
|
image: {type: 'image', url: clip.thumbnailURL, sfw: true, aspect: 16/9},
|
||||||
title: clip.title,
|
title: clip.title,
|
||||||
subtitle,
|
subtitle,
|
||||||
extra
|
extra
|
||||||
|
@ -332,7 +332,7 @@ export const Videos = {
|
||||||
url: token.url,
|
url: token.url,
|
||||||
short: {
|
short: {
|
||||||
type: 'header',
|
type: 'header',
|
||||||
image: {type: 'image', url: video.previewThumbnailURL, sfw: false, aspect: 16/9},
|
image: {type: 'image', url: video.previewThumbnailURL, sfw: true, aspect: 16/9},
|
||||||
title: video.title,
|
title: video.title,
|
||||||
subtitle,
|
subtitle,
|
||||||
extra
|
extra
|
||||||
|
|
|
@ -186,9 +186,9 @@ export default {
|
||||||
is_today = date.toDateString() === today.toDateString();
|
is_today = date.toDateString() === today.toDateString();
|
||||||
|
|
||||||
if ( is_today )
|
if ( is_today )
|
||||||
return date.toLocaleTimeString();
|
return this.tTime(date);
|
||||||
|
|
||||||
return date.toLocaleDateString();
|
return this.tDate(date);
|
||||||
},
|
},
|
||||||
|
|
||||||
async fetchMore() {
|
async fetchMore() {
|
||||||
|
|
40
src/modules/main_menu/components/format-preview.vue
Normal file
40
src/modules/main_menu/components/format-preview.vue
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<template>
|
||||||
|
<div class="tw-flex tw-align-items-start">
|
||||||
|
<label />
|
||||||
|
<div class="tw-c-text-alt tw-mg-b-05 tw-mg-x-05">
|
||||||
|
<code v-if="mode === 'date'">
|
||||||
|
{{ tDate(now, value) }}
|
||||||
|
</code>
|
||||||
|
<code v-else-if="mode === 'time'">
|
||||||
|
{{ tTime(now, value) }}
|
||||||
|
</code>
|
||||||
|
<code v-else>
|
||||||
|
{{ tDateTime(now, value) }}
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: ['context', 'item', 'value'],
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
mode: this.item.extra.mode,
|
||||||
|
now: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.now = new Date;
|
||||||
|
this.timer = setInterval(() => this.now = new Date, 1000);
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
clearInterval(this.timer);
|
||||||
|
this.timer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -62,14 +62,18 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<section v-if="item.extra && item.extra.component && item.extra.before">
|
||||||
|
<component :is="item.extra.component" :context="context" :item="item" :value="value" />
|
||||||
|
</section>
|
||||||
|
|
||||||
<section
|
<section
|
||||||
v-if="item.description"
|
v-if="item.description"
|
||||||
class="tw-c-text-alt-2"
|
class="tw-c-text-alt-2"
|
||||||
>
|
>
|
||||||
<markdown :source="t(item.desc_i18n_key || `${item.i18n_key}.description`, item.description)" />
|
<markdown :source="t(item.desc_i18n_key || `${item.i18n_key}.description`, item.description)" />
|
||||||
</section>
|
</section>
|
||||||
<section v-if="item.extra">
|
<section v-if="item.extra && item.extra.component && ! item.extra.before">
|
||||||
<component :is="item.extra.component" :context="context" :item="item" />
|
<component :is="item.extra.component" :context="context" :item="item" :value="value" />
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,89 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<error-tab v-if="errored" />
|
|
||||||
<loading-tab v-else-if="loading" />
|
|
||||||
<template v-else>
|
|
||||||
<ul>
|
|
||||||
<li
|
|
||||||
v-for="(entry, idx) in data"
|
|
||||||
:key="entry[1]"
|
|
||||||
:class="idx === 0 ? '' : 'tw-border-t'"
|
|
||||||
class="tw-pd-x-1 tw-pd-y-05"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
:data-title="fullTime(entry[0])"
|
|
||||||
data-tooltip-type="text"
|
|
||||||
class="ffz-tooltip tw-pd-r-1"
|
|
||||||
>{{ formatTime(entry[0]) }}: </span>
|
|
||||||
{{ entry[1] }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
import LoadingTab from './loading-tab.vue';
|
|
||||||
import ErrorTab from './error-tab.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
'loading-tab': LoadingTab,
|
|
||||||
'error-tab': ErrorTab
|
|
||||||
},
|
|
||||||
|
|
||||||
props: ['tab', 'channel', 'user', 'self', 'getFFZ'],
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: true,
|
|
||||||
errored: false,
|
|
||||||
|
|
||||||
data: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
mounted() {
|
|
||||||
const socket = this.getFFZ().resolve('socket');
|
|
||||||
if ( ! socket ) {
|
|
||||||
this.errored = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
socket.call('get_name_history', this.user.login).then(data => {
|
|
||||||
this.loading = false;
|
|
||||||
|
|
||||||
if ( Array.isArray(data) )
|
|
||||||
data = data.reverse();
|
|
||||||
|
|
||||||
this.data = data;
|
|
||||||
|
|
||||||
}).catch(err => {
|
|
||||||
this.getFFZ().log.error('Error loading name history.', err);
|
|
||||||
this.errored = true;
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
fullTime(time) {
|
|
||||||
try {
|
|
||||||
const date = new Date(time);
|
|
||||||
return date.toLocaleString();
|
|
||||||
} catch(err) {
|
|
||||||
return 'Unknown'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
formatTime(time) {
|
|
||||||
try {
|
|
||||||
const date = new Date(time);
|
|
||||||
return date.toLocaleDateString();
|
|
||||||
} catch(err) {
|
|
||||||
return 'Unknown'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
|
@ -8,11 +8,24 @@ import Module from 'utilities/module';
|
||||||
import {createElement} from 'utilities/dom';
|
import {createElement} from 'utilities/dom';
|
||||||
import {Color} from 'utilities/color';
|
import {Color} from 'utilities/color';
|
||||||
|
|
||||||
import THEME_CSS from 'site/styles/theme.scss';
|
//import THEME_CSS from 'site/styles/theme.scss';
|
||||||
import NORMALIZER_CSS_URL from 'site/styles/color_normalizer.scss';
|
import NORMALIZER_CSS_URL from 'site/styles/color_normalizer.scss';
|
||||||
|
|
||||||
const BAD_ROUTES = ['product', 'prime', 'turbo'];
|
const BAD_ROUTES = ['product', 'prime', 'turbo'];
|
||||||
|
|
||||||
|
const COLORS = [
|
||||||
|
-.4, -.35, -.3, -.25, -.2, -.15, -.1, -.05, // 1-8
|
||||||
|
0, // 9
|
||||||
|
.05, .1, .15, .2, .25, .3 // 10-15
|
||||||
|
];
|
||||||
|
|
||||||
|
const ACCENT_COLORS = {
|
||||||
|
dark: {'c':{'accent': 9,'background-accent':8,'background-accent-alt':7,'background-accent-alt-2':6,'background-button':7,'background-button-active':7,'background-button-focus':8,'background-button-hover':8,'background-button-primary-active':7,'background-button-primary-default':9,'background-button-primary-hover':8,'background-graph':2,'background-graph-fill':8,'background-input-checkbox-checked':9,'background-input-checked':8,'background-interactable-active':9,'background-interactable-hover':8,'background-progress-countdown-status':9,'background-progress-status':9,'background-range-fill':9,'background-subscriber-stream-tag-active':4,'background-subscriber-stream-tag-default':4,'background-subscriber-stream-tag-hover':3,'background-toggle-checked':9,/*'background-tooltip':1,*/'background-top-nav':6,'border-brand':9,'border-button':7,'border-button-active':8,'border-button-focus':9,'border-button-hover':8,'border-input-checkbox-checked':9,'border-input-checkbox-focus':9,'border-input-focus':9,'border-interactable-selected':10,'border-subscriber-stream-tag':5,'border-tab-active':11,'border-tab-focus':11,'border-tab-hover':11,'border-toggle-focus':7,'border-toggle-hover':7,'border-whisper-incoming':10/*,'fill-brand':9*/,'text-button-text':8,'text-button-text-focus':'o1','text-button-text-hover':'o1','text-link':10,'text-link-active':10,'text-link-focus':10,'text-link-hover':10,'text-link-visited':10,'text-overlay-link-active':13,'text-overlay-link-focus':13,'text-overlay-link-hover':13,'text-tab-active':11,'background-chat':1,'background-chat-alt':3,'background-chat-header':2,'background-modal':3,'text-button-text-active':'o2'/*,'text-tooltip':1*/},'s':{'button-active':[8,'0 0 6px 0',''],'button-focus':[8,'0 0 6px 0',''],'input-focus':[8,'0 0 10px -2px',''],'interactable-focus':[8,'0 0 6px 0',''],'tab-focus':[11,'0 4px 6px -4px',''],'input':[5,'inset 0 0 0 1px','']}},
|
||||||
|
light: {'c':{'accent': 9,'background-accent':8,'background-accent-alt':7,'background-accent-alt-2':6,'background-button':7,'background-button-active':7,'background-button-focus':8,'background-button-hover':8,'background-button-primary-active':7,'background-button-primary-default':9,'background-button-primary-hover':8,'background-graph':15,'background-graph-fill':9,'background-input-checkbox-checked':9,'background-input-checked':8,'background-interactable-active':9,'background-interactable-hover':8,'background-progress-countdown-status':8,'background-progress-status':8,'background-range-fill':9,'background-subscriber-stream-tag-active':13,'background-subscriber-stream-tag-default':13,'background-subscriber-stream-tag-hover':14,'background-toggle-checked':9,/*'background-tooltip':1,*/'background-top-nav':7,'border-brand':9,'border-button':7,'border-button-active':8,'border-button-focus':9,'border-button-hover':8,'border-input-checkbox-checked':9,'border-input-checkbox-focus':9,'border-input-focus':9,'border-interactable-selected':9,'border-subscriber-stream-tag':10,'border-tab-active':8,'border-tab-focus':8,'border-tab-hover':8,'border-toggle-focus':8,'border-toggle-hover':8,'border-whisper-incoming':10/*,'fill-brand':9*/,'text-button-text':8,'text-button-text-focus':'o1','text-button-text-hover':'o1','text-link':8,'text-link-active':9,'text-link-focus':9,'text-link-hover':9,'text-link-visited':9,'text-overlay-link-active':13,'text-overlay-link-focus':13,'text-overlay-link-hover':13,'text-tab-active':8},'s':{'button-active':[8,'0 0 6px 0',''],'button-focus':[8,'0 0 6px 0',''],'input-focus':[10,'0 0 10px -2px',''],'interactable-focus':[8,'0 0 6px 1px',''],'tab-focus':[8,'0 4px 6px -4px','']}},
|
||||||
|
accent_dark: {'c':{'accent-hover':10,'accent':9,'accent-primary-1':1,'accent-primary-2':5,'accent-primary-3':6,'accent-primary-4':7,'accent-primary-5':8},'s':{}},
|
||||||
|
accent_light: {'c':{'accent-hover':10,'accent':9,'accent-primary-1':1,'accent-primary-2':5,'accent-primary-3':6,'accent-primary-4':7,'accent-primary-5':8},'s':{}}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export default class ThemeEngine extends Module {
|
export default class ThemeEngine extends Module {
|
||||||
constructor(...args) {
|
constructor(...args) {
|
||||||
|
@ -37,6 +50,7 @@ export default class ThemeEngine extends Module {
|
||||||
title: 'Background',
|
title: 'Background',
|
||||||
description: 'Try `#0E0C13` for something close to the old dark theme, or `#0E0E0E` for a nice dark gray. Transparent colors not allowed.',
|
description: 'Try `#0E0C13` for something close to the old dark theme, or `#0E0E0E` for a nice dark gray. Transparent colors not allowed.',
|
||||||
component: 'setting-color-box',
|
component: 'setting-color-box',
|
||||||
|
sort: 0,
|
||||||
alpha: false
|
alpha: false
|
||||||
},
|
},
|
||||||
changed: () => this.updateCSS()
|
changed: () => this.updateCSS()
|
||||||
|
@ -48,7 +62,21 @@ export default class ThemeEngine extends Module {
|
||||||
path: 'Appearance > Theme >> Colors',
|
path: 'Appearance > Theme >> Colors',
|
||||||
title: 'Text',
|
title: 'Text',
|
||||||
description: 'If not set, this will automatically be set to white or black based on the brightness of the background.',
|
description: 'If not set, this will automatically be set to white or black based on the brightness of the background.',
|
||||||
component: 'setting-color-box'
|
component: 'setting-color-box',
|
||||||
|
sort: 1
|
||||||
|
},
|
||||||
|
changed: () => this.updateCSS()
|
||||||
|
});
|
||||||
|
|
||||||
|
this.settings.add('theme.color.accent', {
|
||||||
|
default: '',
|
||||||
|
ui: {
|
||||||
|
path: 'Appearance > Theme >> Colors',
|
||||||
|
title: 'Accent',
|
||||||
|
description: 'The accent color is used for buttons, links, etc.',
|
||||||
|
component: 'setting-color-box',
|
||||||
|
alpha: false,
|
||||||
|
sort: 2
|
||||||
},
|
},
|
||||||
changed: () => this.updateCSS()
|
changed: () => this.updateCSS()
|
||||||
});
|
});
|
||||||
|
@ -60,7 +88,8 @@ export default class ThemeEngine extends Module {
|
||||||
title: 'Tooltip Background',
|
title: 'Tooltip Background',
|
||||||
description: 'If not set, the tooltip settings will be automatically adjusted based on the brightness of the background.',
|
description: 'If not set, the tooltip settings will be automatically adjusted based on the brightness of the background.',
|
||||||
component: 'setting-color-box',
|
component: 'setting-color-box',
|
||||||
alpha: true
|
alpha: true,
|
||||||
|
sort: 10
|
||||||
},
|
},
|
||||||
changed: () => this.updateCSS()
|
changed: () => this.updateCSS()
|
||||||
});
|
});
|
||||||
|
@ -70,12 +99,13 @@ export default class ThemeEngine extends Module {
|
||||||
ui: {
|
ui: {
|
||||||
path: 'Appearance > Theme >> Colors',
|
path: 'Appearance > Theme >> Colors',
|
||||||
title: 'Tooltip Text',
|
title: 'Tooltip Text',
|
||||||
component: 'setting-color-box'
|
component: 'setting-color-box',
|
||||||
|
sort: 11
|
||||||
},
|
},
|
||||||
changed: () => this.updateCSS()
|
changed: () => this.updateCSS()
|
||||||
});
|
});
|
||||||
|
|
||||||
this.settings.add('theme.dark', {
|
/*this.settings.add('theme.dark', {
|
||||||
requires: ['theme.is-dark'],
|
requires: ['theme.is-dark'],
|
||||||
default: false,
|
default: false,
|
||||||
process(ctx, val) {
|
process(ctx, val) {
|
||||||
|
@ -93,7 +123,7 @@ The CSS loaded by this setting is far too heavy and can cause performance issues
|
||||||
},
|
},
|
||||||
|
|
||||||
changed: val => this.updateSetting(val)
|
changed: val => this.updateSetting(val)
|
||||||
});
|
});*/
|
||||||
|
|
||||||
this.settings.add('theme.can-dark', {
|
this.settings.add('theme.can-dark', {
|
||||||
requires: ['context.route.name'],
|
requires: ['context.route.name'],
|
||||||
|
@ -128,7 +158,7 @@ The CSS loaded by this setting is far too heavy and can cause performance issues
|
||||||
this._normalizer = null;
|
this._normalizer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateOldCSS() {
|
/*updateOldCSS() {
|
||||||
const dark = this.settings.get('theme.is-dark'),
|
const dark = this.settings.get('theme.is-dark'),
|
||||||
gray = this.settings.get('theme.dark');
|
gray = this.settings.get('theme.dark');
|
||||||
|
|
||||||
|
@ -136,19 +166,22 @@ The CSS loaded by this setting is far too heavy and can cause performance issues
|
||||||
document.body.classList.toggle('tw-root--theme-ffz', gray);
|
document.body.classList.toggle('tw-root--theme-ffz', gray);
|
||||||
|
|
||||||
this.css_tweaks.setVariable('border-color', dark ? (gray ? '#2a2a2a' : '#2c2541') : '#dad8de');
|
this.css_tweaks.setVariable('border-color', dark ? (gray ? '#2a2a2a' : '#2c2541') : '#dad8de');
|
||||||
}
|
}*/
|
||||||
|
|
||||||
updateCSS() {
|
updateCSS() {
|
||||||
this.updateOldCSS();
|
//this.updateOldCSS();
|
||||||
|
|
||||||
|
this.css_tweaks.setVariable('border-color', 'var(--color-border-base)');
|
||||||
|
|
||||||
if ( ! this.settings.get('theme.can-dark') ) {
|
if ( ! this.settings.get('theme.can-dark') ) {
|
||||||
this.toggleNormalizer(false);
|
this.toggleNormalizer(false);
|
||||||
|
this.toggleAccentNormal(true);
|
||||||
this.css_tweaks.delete('colors');
|
this.css_tweaks.delete('colors');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let dark = this.settings.get('theme.is-dark');
|
let dark = this.settings.get('theme.is-dark');
|
||||||
const bits = [];
|
const bits = [], accent_bits = [];
|
||||||
|
|
||||||
const background = Color.RGBA.fromCSS(this.settings.get('theme.color.background'));
|
const background = Color.RGBA.fromCSS(this.settings.get('theme.color.background'));
|
||||||
if ( background ) {
|
if ( background ) {
|
||||||
|
@ -198,6 +231,46 @@ The CSS loaded by this setting is far too heavy and can cause performance issues
|
||||||
bits.push(`--color-text-alt-2: ${hsla._a(alpha - 0.4).toCSS()};`);
|
bits.push(`--color-text-alt-2: ${hsla._a(alpha - 0.4).toCSS()};`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Accent
|
||||||
|
const accent = Color.RGBA.fromCSS(this.settings.get('theme.color.accent'));
|
||||||
|
this.toggleAccentNormal(! accent);
|
||||||
|
if ( accent ) {
|
||||||
|
accent.a = 1;
|
||||||
|
|
||||||
|
const hsla = accent.toHSLA(),
|
||||||
|
luma = hsla.l;
|
||||||
|
|
||||||
|
const colors = COLORS.map(x => {
|
||||||
|
if ( x === 0 )
|
||||||
|
return accent.toCSS();
|
||||||
|
|
||||||
|
return hsla._l(luma + x).toCSS()
|
||||||
|
});
|
||||||
|
|
||||||
|
for(let i=0; i < colors.length; i++) {
|
||||||
|
bits.push(`--ffz-color-accent-${i+1}:${colors[i]};`);
|
||||||
|
}
|
||||||
|
|
||||||
|
let source = dark ? ACCENT_COLORS.dark : ACCENT_COLORS.light;
|
||||||
|
|
||||||
|
for(const [key,val] of Object.entries(source.c)) {
|
||||||
|
if ( typeof val !== 'number' )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bits.push(`--color-${key}:${colors[val-1]};`);
|
||||||
|
}
|
||||||
|
|
||||||
|
source = dark ? ACCENT_COLORS.accent_dark : ACCENT_COLORS.accent_light;
|
||||||
|
|
||||||
|
for(const [key,val] of Object.entries(source.c)) {
|
||||||
|
if ( typeof val !== 'number' )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
accent_bits.push(`--color-${key}:${colors[val-1]} !important;`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Tooltips
|
// Tooltips
|
||||||
let tooltip_bg = Color.RGBA.fromCSS(this.settings.get('theme.color.tooltip.background')),
|
let tooltip_bg = Color.RGBA.fromCSS(this.settings.get('theme.color.tooltip.background')),
|
||||||
tooltip_dark;
|
tooltip_dark;
|
||||||
|
@ -231,7 +304,7 @@ The CSS loaded by this setting is far too heavy and can cause performance issues
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( bits.length ) {
|
if ( bits.length ) {
|
||||||
this.css_tweaks.set('colors', `body {${bits.join('\n')}}`);
|
this.css_tweaks.set('colors', `body {${bits.join('\n')}}.channel-info-content .tw-accent-region{${accent_bits.join('\n')}}`);
|
||||||
this.toggleNormalizer(true);
|
this.toggleNormalizer(true);
|
||||||
} else {
|
} else {
|
||||||
this.css_tweaks.delete('colors');
|
this.css_tweaks.delete('colors');
|
||||||
|
@ -239,6 +312,17 @@ The CSS loaded by this setting is far too heavy and can cause performance issues
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleAccentNormal(enable) {
|
||||||
|
if ( enable ) {
|
||||||
|
const bits = [];
|
||||||
|
for(let i=0; i < 15; i++)
|
||||||
|
bits.push(`--ffz-color-accent-${i+1}:var(--color-twitch-purple-${i+1});`);
|
||||||
|
|
||||||
|
this.css_tweaks.set('accent-normal', `body {${bits.join('\n')}}`);
|
||||||
|
} else
|
||||||
|
this.css_tweaks.delete('accent-normal');
|
||||||
|
}
|
||||||
|
|
||||||
toggleNormalizer(enable) {
|
toggleNormalizer(enable) {
|
||||||
if ( ! this._normalizer ) {
|
if ( ! this._normalizer ) {
|
||||||
if ( ! enable )
|
if ( ! enable )
|
||||||
|
@ -258,7 +342,7 @@ The CSS loaded by this setting is far too heavy and can cause performance issues
|
||||||
document.head.appendChild(this._normalizer)
|
document.head.appendChild(this._normalizer)
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleStyle(enable) {
|
/*toggleStyle(enable) {
|
||||||
if ( ! this._style ) {
|
if ( ! this._style ) {
|
||||||
if ( ! enable )
|
if ( ! enable )
|
||||||
return;
|
return;
|
||||||
|
@ -280,10 +364,10 @@ The CSS loaded by this setting is far too heavy and can cause performance issues
|
||||||
updateSetting(enable) {
|
updateSetting(enable) {
|
||||||
this.toggleStyle(enable);
|
this.toggleStyle(enable);
|
||||||
this.updateCSS();
|
this.updateCSS();
|
||||||
}
|
}*/
|
||||||
|
|
||||||
onEnable() {
|
onEnable() {
|
||||||
this.updateSetting(this.settings.get('theme.dark'));
|
//this.updateSetting(this.settings.get('theme.dark'));
|
||||||
this.updateCSS();
|
this.updateCSS();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -35,4 +35,34 @@
|
||||||
.chat-line__status {
|
.chat-line__status {
|
||||||
color: var(--color-text-alt-2) !important;
|
color: var(--color-text-alt-2) !important;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
.navigation-link.active, .navigation-link:hover {
|
||||||
|
color: var(--ffz-color-accent-9) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-result-verified-badge,
|
||||||
|
.search-item__history {
|
||||||
|
color: var(--ffz-color-accent-8) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navigation-link__active-indicator {
|
||||||
|
background-color: var(--ffz-color-accent-8) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tw-root--theme-dark, .dark-theme {
|
||||||
|
.navigation-link.active, .navigation-link:hover {
|
||||||
|
color: var(--ffz-color-accent-10) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-result-verified-badge,
|
||||||
|
.search-item__history {
|
||||||
|
color: var(--ffz-color-accent-10) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navigation-link__active-indicator {
|
||||||
|
color: var(--ffz-color-accent-10) !important;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -9,7 +9,7 @@
|
||||||
<input
|
<input
|
||||||
:id="'icon-search$' + id"
|
:id="'icon-search$' + id"
|
||||||
ref="input"
|
ref="input"
|
||||||
:placeholder="('setting.icon.search', 'Search for Icon')"
|
:placeholder="t('setting.icon.search', 'Search for Icon')"
|
||||||
:value="isOpen ? search : val"
|
:value="isOpen ? search : val"
|
||||||
:class="[clearable ? 'tw-pd-r-5' : 'tw-pd-r-1']"
|
:class="[clearable ? 'tw-pd-r-5' : 'tw-pd-r-1']"
|
||||||
type="text"
|
type="text"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue