1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-28 15:27:43 +00:00
* Added: Helper text to `Appearance > Theme` with suggested colors, as well as the previous site fonts.
* Changed: Automatically enable or disable Twitch's Dark Theme when setting a background color, to ensure page elements stay styled correctly.
* Changed: Don't try injecting our script on `brand` or `dev` subdomains.
* Changed: Do not allow setting the alpha value of custom background colors.
* Fixed: Add relative positioning to most of our tool-tip wrapper elements, to ensure tool-tips are positioned correctly.
* Fixed: Stop modifying queries with Apollo. Just send our own queries when we need a bit of extra data. Should prevent loading issues.
* Fixed: Option to hide the Discover link in the top navigation not working.
* Fixed: Option to hide live indicators on channel cards not working.
* Fixed: Add a few more rules to the new theme to ensure all elements are colored correctly.
* Fixed: Do not square avatars within the Bits Leaderboard.
* Known Issue: Light custom themes do not look good in Theater Mode.
This commit is contained in:
SirStendec 2019-09-27 15:44:33 -04:00
parent a1949b0f8e
commit 077a0685ad
26 changed files with 182 additions and 119 deletions

View file

@ -1,7 +1,7 @@
{ {
"name": "frankerfacez", "name": "frankerfacez",
"author": "Dan Salvato LLC", "author": "Dan Salvato LLC",
"version": "4.12.0", "version": "4.12.2",
"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

@ -2,7 +2,7 @@
'use strict'; 'use strict';
(() => { (() => {
// Don't run on certain sub-domains. // Don't run on certain sub-domains.
if ( /^(?:localhost\.rig|blog|player|im|chatdepot|tmi|api|)\./.test(location.hostname) ) if ( /^(?:localhost\.rig|blog|player|im|chatdepot|tmi|api|brand|dev)\./.test(location.hostname) )
return; return;
const DEBUG = localStorage.ffzDebugMode == 'true' && document.body.classList.contains('ffz-dev') && ! window.Ember, const DEBUG = localStorage.ffzDebugMode == 'true' && document.body.classList.contains('ffz-dev') && ! window.Ember,

View file

@ -43,7 +43,7 @@
</figure> </figure>
</div> </div>
</div> </div>
<div v-if="removable" class="tw-flex-shrink-0 tw-mg-r-05 tw-tooltip-wrapper"> <div v-if="removable" class="tw-flex-shrink-0 tw-mg-r-05 tw-relative tw-tooltip-wrapper">
<button <button
v-if="editing" v-if="editing"
:class="{active: edit_data.remove}" :class="{active: edit_data.remove}"

View file

@ -23,7 +23,7 @@
<figure v-else class="ffz-i-eyedropper" /> <figure v-else class="ffz-i-eyedropper" />
</button> </button>
<div v-if="open" v-on-clickaway="closePicker" class="tw-absolute tw-z-above tw-right-0"> <div v-if="open" v-on-clickaway="closePicker" class="tw-absolute tw-z-above tw-right-0">
<chrome-picker :value="colors" @input="onPick" /> <chrome-picker :disable-alpha="! alpha" :value="colors" @input="onPick" />
</div> </div>
</div> </div>
<div v-else class="tw-relative"> <div v-else class="tw-relative">
@ -44,7 +44,7 @@
:class="{'ffz-bottom-100': openUp}" :class="{'ffz-bottom-100': openUp}"
class="tw-absolute tw-z-above tw-balloon--up tw-balloon--right" class="tw-absolute tw-z-above tw-balloon--up tw-balloon--right"
> >
<chrome-picker :value="colors" @input="onPick" /> <chrome-picker :disable-alpha="! alpha" :value="colors" @input="onPick" />
</div> </div>
</div> </div>
</div> </div>
@ -63,6 +63,10 @@ export default {
props: { props: {
value: String, value: String,
alpha: {
type: Boolean,
default: true
},
default: { default: {
type: String, type: String,
default: '#000' default: '#000'

View file

@ -14,7 +14,7 @@
<div <div
v-if="isShort" v-if="isShort"
class="tw-mg-l-1 tw-pd-x-1 tw-border-l tw-flex tw-align-items-center ffz--profile__icon tw-tooltip-wrapper" class="tw-mg-l-1 tw-pd-x-1 tw-border-l tw-flex tw-align-items-center ffz--profile__icon tw-relative tw-tooltip-wrapper"
> >
<figure :class="[passes ? 'ffz-i-ok' : 'ffz-i-cancel']" /> <figure :class="[passes ? 'ffz-i-ok' : 'ffz-i-cancel']" />
<div class="tw-tooltip tw-tooltip--up tw-tooltip--align-right"> <div class="tw-tooltip tw-tooltip--up tw-tooltip--align-right">
@ -31,7 +31,7 @@
:class="[isShort ? '' : 'tw-mg-l-1']" :class="[isShort ? '' : 'tw-mg-l-1']"
class="tw-border-l tw-pd-l-1 tw-flex tw-flex-column tw-flex-wrap tw-justify-content-start tw-align-items-start" class="tw-border-l tw-pd-l-1 tw-flex tw-flex-column tw-flex-wrap tw-justify-content-start tw-align-items-start"
> >
<div v-if="! isShort" class="tw-mg-b-1 tw-border-b tw-pd-b-1 tw-full-width tw-flex tw-justify-content-center ffz--profile__icon tw-tooltip-wrapper"> <div v-if="! isShort" class="tw-mg-b-1 tw-border-b tw-pd-b-1 tw-full-width tw-flex tw-justify-content-center ffz--profile__icon tw-relative tw-tooltip-wrapper">
<figure :class="[passes ? 'ffz-i-ok' : 'ffz-i-cancel']" /> <figure :class="[passes ? 'ffz-i-ok' : 'ffz-i-cancel']" />
<div class="tw-tooltip tw-tooltip--up tw-tooltip--align-right"> <div class="tw-tooltip tw-tooltip--up tw-tooltip--align-right">
<span v-if="passes"> <span v-if="passes">
@ -44,13 +44,13 @@
</div> </div>
<template v-if="deleting"> <template v-if="deleting">
<button class="tw-button tw-button--text tw-tooltip-wrapper" @click="$emit('delete')"> <button class="tw-button tw-button--text tw-relative tw-tooltip-wrapper" @click="$emit('delete')">
<span class="tw-button__text ffz-i-trash" /> <span class="tw-button__text ffz-i-trash" />
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right"> <div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
{{ t('setting.delete', 'Delete') }} {{ t('setting.delete', 'Delete') }}
</div> </div>
</button> </button>
<button class="tw-button tw-button--text tw-tooltip-wrapper" @click="deleting = false"> <button class="tw-button tw-button--text tw-relative tw-tooltip-wrapper" @click="deleting = false">
<span class="tw-button__text ffz-i-cancel" /> <span class="tw-button__text ffz-i-cancel" />
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right"> <div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
{{ t('setting.cancel', 'Cancel') }} {{ t('setting.cancel', 'Cancel') }}
@ -58,7 +58,7 @@
</button> </button>
</template> </template>
<template v-else> <template v-else>
<button class="tw-button tw-button--text tw-tooltip-wrapper" @click="deleting = true"> <button class="tw-button tw-button--text tw-relative tw-tooltip-wrapper" @click="deleting = true">
<span class="tw-button__text ffz-i-trash" /> <span class="tw-button__text ffz-i-trash" />
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right"> <div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
{{ t('setting.delete', 'Delete') }} {{ t('setting.delete', 'Delete') }}

View file

@ -33,7 +33,7 @@
<figure :class="faded ? 'ffz-i-eye-off' : 'ffz-i-eye'" /> <figure :class="faded ? 'ffz-i-eye-off' : 'ffz-i-eye'" />
</span> </span>
</button> </button>
<button v-if="!exclusive" class="tw-button-icon tw-mg-x-05 tw-tooltip-wrapper" @click="popout"> <button v-if="!exclusive" class="tw-button-icon tw-mg-x-05 tw-relative tw-tooltip-wrapper" @click="popout">
<span class="tw-button-icon__icon"> <span class="tw-button-icon__icon">
<figure class="ffz-i-link-ext" /> <figure class="ffz-i-link-ext" />
</span> </span>

View file

@ -42,7 +42,7 @@
</div> </div>
</section> </section>
<button <button
class="tw-button tw-button--text tw-tooltip-wrapper" class="tw-button tw-button--text tw-relative tw-tooltip-wrapper"
@click="resetExport" @click="resetExport"
> >
<span class="tw-button__text ffz-i-cancel" /> <span class="tw-button__text ffz-i-cancel" />
@ -57,7 +57,7 @@
{{ export_message }} {{ export_message }}
</section> </section>
<button <button
class="tw-button tw-button--text tw-tooltip-wrapper" class="tw-button tw-button--text tw-relative tw-tooltip-wrapper"
@click="resetExport" @click="resetExport"
> >
<span class="tw-button__text ffz-i-cancel" /> <span class="tw-button__text ffz-i-cancel" />

View file

@ -32,7 +32,7 @@
</div> </div>
</section> </section>
<button <button
class="tw-button tw-button--text tw-tooltip-wrapper" class="tw-button tw-button--text tw-relative tw-tooltip-wrapper"
@click="resetImport" @click="resetImport"
> >
<span class="tw-button__text ffz-i-cancel" /> <span class="tw-button__text ffz-i-cancel" />
@ -47,7 +47,7 @@
{{ import_message }} {{ import_message }}
</section> </section>
<button <button
class="tw-button tw-button--text tw-tooltip-wrapper" class="tw-button tw-button--text tw-relative tw-tooltip-wrapper"
@click="resetImport" @click="resetImport"
> >
<span class="tw-button__text ffz-i-cancel" /> <span class="tw-button__text ffz-i-cancel" />
@ -66,7 +66,7 @@
<button <button
v-for="(profile, idx) in import_profiles" v-for="(profile, idx) in import_profiles"
:key="idx" :key="idx"
class="tw-block tw-full-width tw-mg-y-05 tw-mg-r-1 tw-pd-05 tw-button ffz-button--hollow tw-c-text-overlay tw-tooltip-wrapper" class="tw-block tw-full-width tw-mg-y-05 tw-mg-r-1 tw-pd-05 tw-button ffz-button--hollow tw-c-text-overlay tw-relative tw-tooltip-wrapper"
@click="importProfile(profile)" @click="importProfile(profile)"
> >
<span class="tw-button__text tw-c-text-overlay"> <span class="tw-button__text tw-c-text-overlay">
@ -78,7 +78,7 @@
</button> </button>
</section> </section>
<button <button
class="tw-button tw-button--text tw-tooltip-wrapper" class="tw-button tw-button--text tw-relative tw-tooltip-wrapper"
@click="resetImport" @click="resetImport"
> >
<span class="tw-button__text ffz-i-cancel" /> <span class="tw-button__text ffz-i-cancel" />
@ -113,7 +113,7 @@
</button> </button>
</section> </section>
<button <button
class="tw-button tw-button--text tw-tooltip-wrapper" class="tw-button tw-button--text tw-relative tw-tooltip-wrapper"
@click="resetImport" @click="resetImport"
> >
<span class="tw-button__text ffz-i-cancel" /> <span class="tw-button__text ffz-i-cancel" />
@ -138,7 +138,7 @@
<span class="ffz-i-ellipsis-vert" /> <span class="ffz-i-ellipsis-vert" />
</div> </div>
<div v-if="p.url" class="tw-flex tw-flex-shrink-0 tw-align-items-center tw-mg-r-1 tw-tooltip-wrapper tw-font-size-4"> <div v-if="p.url" class="tw-flex tw-flex-shrink-0 tw-align-items-center tw-mg-r-1 tw-relative tw-tooltip-wrapper tw-font-size-4">
<span class="ffz-i-download-cloud" /> <span class="ffz-i-download-cloud" />
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-left"> <div class="tw-tooltip tw-tooltip--down tw-tooltip--align-left">
<div class="tw-mg-b-05"> <div class="tw-mg-b-05">
@ -164,12 +164,12 @@
</div> </div>
<div class="tw-flex tw-flex-shrink-0 tw-align-items-center tw-border-l tw-mg-l-1 tw-pd-l-1"> <div class="tw-flex tw-flex-shrink-0 tw-align-items-center tw-border-l tw-mg-l-1 tw-pd-l-1">
<div v-if="p.live" class="ffz--profile__icon ffz-i-ok tw-tooltip-wrapper"> <div v-if="p.live" class="ffz--profile__icon ffz-i-ok tw-relative tw-tooltip-wrapper">
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right"> <div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
{{ t('setting.profiles.active', 'This profile is active.') }} {{ t('setting.profiles.active', 'This profile is active.') }}
</div> </div>
</div> </div>
<div v-if="! p.live" class="ffz--profile__icon ffz-i-cancel tw-tooltip-wrapper"> <div v-if="! p.live" class="ffz--profile__icon ffz-i-cancel tw-relative tw-tooltip-wrapper">
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right"> <div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
{{ t('setting.profiles.inactive', 'This profile is not active.') }} {{ t('setting.profiles.inactive', 'This profile is not active.') }}
</div> </div>

View file

@ -12,6 +12,7 @@
<color-picker <color-picker
:id="item.full_key" :id="item.full_key"
ref="control" ref="control"
:alpha="alpha"
:nullable="true" :nullable="true"
:value="color" :value="color"
@input="onInput" @input="onInput"
@ -62,6 +63,13 @@ export default {
return ''; return '';
return this.value; return this.value;
},
alpha() {
if ( this.item.alpha != null )
return this.item.alpha;
return true;
} }
}, },

View file

@ -1,13 +1,13 @@
<template lang="html"> <template lang="html">
<div class="ffz--term"> <div class="ffz--term">
<div class="tw-align-items-center tw-flex tw-flex-nowrap tw-flex-row tw-full-width"> <div class="tw-align-items-center tw-flex tw-flex-nowrap tw-flex-row tw-full-width">
<div v-if="! is_valid" class="tw-tooltip-wrapper tw-mg-r-05"> <div v-if="! is_valid" class="tw-relative tw-tooltip-wrapper tw-mg-r-05">
<figure class="tw-c-text-error ffz-i-attention" /> <figure class="tw-c-text-error ffz-i-attention" />
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-left"> <div class="tw-tooltip tw-tooltip--down tw-tooltip--align-left">
{{ t('setting.terms.warn-invalid', 'This highlight term is invalid.') }} {{ t('setting.terms.warn-invalid', 'This highlight term is invalid.') }}
</div> </div>
</div> </div>
<div v-if="! is_safe" class="tw-tooltip-wrapper tw-mg-r-05"> <div v-if="! is_safe" class="tw-relative tw-tooltip-wrapper tw-mg-r-05">
<figure class="tw-c-text-hint ffz-i-attention" /> <figure class="tw-c-text-hint ffz-i-attention" />
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-left"> <div class="tw-tooltip tw-tooltip--down tw-tooltip--align-left">
{{ t('setting.terms.warn-complex', 'This highlight term is potentially too complex. It may cause client lag.') }} {{ t('setting.terms.warn-complex', 'This highlight term is potentially too complex. It may cause client lag.') }}
@ -56,7 +56,7 @@
</option> </option>
</select> </select>
</div> </div>
<div v-if="removable" class="tw-flex-shrink-0 tw-mg-r-05 tw-tooltip-wrapper"> <div v-if="removable" class="tw-flex-shrink-0 tw-mg-r-05 tw-relative tw-tooltip-wrapper">
<button <button
v-if="editing" v-if="editing"
:class="{active: edit_data.remove}" :class="{active: edit_data.remove}"

View file

@ -31,7 +31,7 @@
<figure :class="faded ? 'ffz-i-eye-off' : 'ffz-i-eye'" /> <figure :class="faded ? 'ffz-i-eye-off' : 'ffz-i-eye'" />
</span> </span>
</button> </button>
<button v-if="!exclusive" class="tw-button-icon tw-mg-x-05 tw-tooltip-wrapper" @click="popout"> <button v-if="!exclusive" class="tw-button-icon tw-mg-x-05 tw-relative tw-tooltip-wrapper" @click="popout">
<span class="tw-button-icon__icon"> <span class="tw-button-icon__icon">
<figure class="ffz-i-link-ext" /> <figure class="ffz-i-link-ext" />
</span> </span>

View file

@ -5,9 +5,9 @@
// ============================================================================ // ============================================================================
import Module from 'utilities/module'; import Module from 'utilities/module';
import {get, deep_copy} from 'utilities/object'; import {get} from 'utilities/object';
import CHANNEL_QUERY from './channel_header_query.gql'; //import CHANNEL_QUERY from './channel_header_query.gql';
export default class ChannelBar extends Module { export default class ChannelBar extends Module {
@ -25,14 +25,14 @@ export default class ChannelBar extends Module {
this.inject('metadata'); this.inject('metadata');
this.inject('socket'); this.inject('socket');
this.apollo.registerModifier('ChannelPage_ChannelHeader', CHANNEL_QUERY); /*this.apollo.registerModifier('ChannelPage_ChannelHeader', CHANNEL_QUERY);
this.apollo.registerModifier('ChannelPage_ChannelHeader', data => { this.apollo.registerModifier('ChannelPage_ChannelHeader', data => {
const u = data && data.data && data.data.user; const u = data && data.data && data.data.user;
if ( u ) { if ( u ) {
const o = u.profileViewCount = new Number(u.profileViewCount || 0); const o = u.profileViewCount = new Number(u.profileViewCount || 0);
o.data = deep_copy(u); o.data = deep_copy(u);
} }
}, false); }, false);*/
this.settings.add('channel.metadata.force-above', { this.settings.add('channel.metadata.force-above', {

View file

@ -11,7 +11,7 @@ import {has} from 'utilities/object';
const STYLE_VALIDATOR = document.createElement('span'); const STYLE_VALIDATOR = document.createElement('span');
const CLASSES = { const CLASSES = {
'top-discover': '.top-nav__nav-link[data-a-target="discover-link"]', 'top-discover': '.navigation-link[data-a-target="discover-link"]',
'side-nav': '.side-nav', 'side-nav': '.side-nav',
'side-rec-channels': '.side-nav .recommended-channels,.side-nav .ffz--popular-channels', 'side-rec-channels': '.side-nav .recommended-channels,.side-nav .ffz--popular-channels',
'side-rec-friends': '.side-nav .recommended-friends', 'side-rec-friends': '.side-nav .recommended-friends',
@ -31,7 +31,7 @@ const CLASSES = {
'pinned-cheer': '.pinned-cheer,.pinned-cheer-v2,.channel-leaderboard', 'pinned-cheer': '.pinned-cheer,.pinned-cheer-v2,.channel-leaderboard',
'whispers': 'body .whispers', 'whispers': 'body .whispers',
'dir-live-ind': '.live-channel-card:not([data-a-target*="host"]) .stream-type-indicator.stream-type-indicator--live,.stream-thumbnail__card .stream-type-indicator.stream-type-indicator--live,.preview-card .stream-type-indicator.stream-type-indicator--live,.preview-card .preview-card-stat.preview-card-stat--live', 'dir-live-ind': '.preview-card[data-ffz-type="live"] .tw-channel-status-text-indicator,.live-channel-card:not([data-a-target*="host"]) .stream-type-indicator.stream-type-indicator--live,.stream-thumbnail__card .stream-type-indicator.stream-type-indicator--live,.preview-card .stream-type-indicator.stream-type-indicator--live,.preview-card .preview-card-stat.preview-card-stat--live',
'profile-hover': '.preview-card .tw-relative:hover .ffz-channel-avatar', 'profile-hover': '.preview-card .tw-relative:hover .ffz-channel-avatar',
'not-live-bar': 'div[data-test-selector="non-live-video-banner-layout"]', 'not-live-bar': 'div[data-test-selector="non-live-video-banner-layout"]',
'channel-live-ind': '.channel-header__user .tw-channel-status-text-indicator' 'channel-live-ind': '.channel-header__user .tw-channel-status-text-indicator'
@ -228,7 +228,7 @@ export default class CSSTweaks extends Module {
ui: { ui: {
path: 'Appearance > Theme >> Fonts', path: 'Appearance > Theme >> Fonts',
title: 'Font Family', title: 'Font Family',
description: 'Override the font used for the entire Twitch website.', description: 'Override the font used for the entire Twitch website. The old default font was: `"Helvetica Neue",Helvetica,Arial,sans-serif`',
component: 'setting-text-box' component: 'setting-text-box'
}, },
changed: () => this.updateFont() changed: () => this.updateFont()

View file

@ -1,8 +1,7 @@
.player-streaminfo__picture img[src], .tw-avatar {
.side-nav-card__avatar.tw-border-radius-rounded, --border-radius-rounded: 0 !important;
.tw-avatar .tw-border-radius-rounded { }
.tw-root--theme-dark &,
& { .bits-leaderboard-medal .tw-avatar {
border-radius: 0 !important; --border-radius-rounded: 9000px !important;
}
} }

View file

@ -72,7 +72,7 @@
right: 0; right: 0;
} }
body .whispers--theatre-mode.whispers--right-column-expanded { body .whispers--theatre-mode.whispers--right-column-expanded-beside {
left: var(--ffz-chat-width) !important; left: var(--ffz-chat-width) !important;
right: 0 !important; right: 0 !important;
} }

View file

@ -11,12 +11,12 @@ import {get} from 'utilities/object';
import Popper from 'popper.js'; import Popper from 'popper.js';
import {makeReference} from 'utilities/tooltip'; import {makeReference} from 'utilities/tooltip';
import FOLLOWED_INDEX from './followed_index.gql'; /*import FOLLOWED_INDEX from './followed_index.gql';
import FOLLOWED_HOSTS from './followed_hosts.gql'; import FOLLOWED_HOSTS from './followed_hosts.gql';
import FOLLOWED_CHANNELS from './followed_channels.gql'; import FOLLOWED_CHANNELS from './followed_channels.gql';
import FOLLOWED_LIVE from './followed_live.gql'; import FOLLOWED_LIVE from './followed_live.gql';
import SUBSCRIBED_CHANNELS from './sidenav_subscribed.gql'; import SUBSCRIBED_CHANNELS from './sidenav_subscribed.gql';
import RECOMMENDED_CHANNELS from './recommended_channels.gql'; import RECOMMENDED_CHANNELS from './recommended_channels.gql';*/
export default class Following extends SiteModule { export default class Following extends SiteModule {
constructor(...args) { constructor(...args) {
@ -66,7 +66,7 @@ export default class Following extends SiteModule {
changed: () => this.parent.DirectoryCard.forceUpdate() changed: () => this.parent.DirectoryCard.forceUpdate()
}); });
this.apollo.registerModifier('FollowedChannels_RENAME2', FOLLOWED_CHANNELS); /*this.apollo.registerModifier('FollowedChannels_RENAME2', FOLLOWED_CHANNELS);
this.apollo.registerModifier('SideNav_SubscribedChannels', SUBSCRIBED_CHANNELS); this.apollo.registerModifier('SideNav_SubscribedChannels', SUBSCRIBED_CHANNELS);
this.apollo.registerModifier('RecommendedChannels', RECOMMENDED_CHANNELS); this.apollo.registerModifier('RecommendedChannels', RECOMMENDED_CHANNELS);
@ -97,7 +97,7 @@ export default class Following extends SiteModule {
shelf.node.content.edges = this.parent.processNodes(edges); shelf.node.content.edges = this.parent.processNodes(edges);
} }
}, false); }, false);*/
this.hosts = new WeakMap; this.hosts = new WeakMap;
} }
@ -185,7 +185,7 @@ export default class Following extends SiteModule {
'data.currentUser.recommendations.liveRecommendations.nodes.0.createdAt' 'data.currentUser.recommendations.liveRecommendations.nodes.0.createdAt'
);*/ );*/
if ( this.router.current_name !== 'dir-following' ) /*if ( this.router.current_name !== 'dir-following' )
return; return;
const bit = this.router.match[1]; const bit = this.router.match[1];
@ -204,11 +204,11 @@ export default class Following extends SiteModule {
'data.currentUser.followedLiveUsers.nodes.0.stream.createdAt' 'data.currentUser.followedLiveUsers.nodes.0.stream.createdAt'
);*/ );*/
else if ( bit === 'hosts' ) /*else if ( bit === 'hosts' )
this.apollo.ensureQuery( this.apollo.ensureQuery(
'FollowingHosts_CurrentUser', 'FollowingHosts_CurrentUser',
'data.currentUser.followedHosts.nodes.0.hosting.stream.createdAt' 'data.currentUser.followedHosts.nodes.0.hosting.stream.createdAt'
); );*/
} }
onEnable() { onEnable() {

View file

@ -8,7 +8,7 @@ import {SiteModule} from 'utilities/module';
import {createElement} from 'utilities/dom'; import {createElement} from 'utilities/dom';
import { get } from 'utilities/object'; import { get } from 'utilities/object';
import GAME_QUERY from './game.gql'; //import GAME_QUERY from './game.gql';
export default class Game extends SiteModule { export default class Game extends SiteModule {
constructor(...args) { constructor(...args) {
@ -27,16 +27,16 @@ export default class Game extends SiteModule {
['dir-game-index', 'dir-community', 'dir-game-videos', 'dir-game-clips', 'dir-game-details'] ['dir-game-index', 'dir-community', 'dir-game-videos', 'dir-game-clips', 'dir-game-details']
); );
this.apollo.registerModifier('DirectoryPage_Game', GAME_QUERY); /*this.apollo.registerModifier('DirectoryPage_Game', GAME_QUERY);
this.apollo.registerModifier('DirectoryPage_Game', res => { this.apollo.registerModifier('DirectoryPage_Game', res => {
/*setTimeout(() => /*setTimeout(() =>
this.apollo.ensureQuery( this.apollo.ensureQuery(
'DirectoryPage_Game', 'DirectoryPage_Game',
'data.game.streams.edges.0.node.createdAt' 'data.game.streams.edges.0.node.createdAt'
), 500);*/ ), 500);* /
this.modifyStreams(res); this.modifyStreams(res);
}, false); }, false);*/
} }
modifyStreams(res) { // eslint-disable-line class-methods-use-this modifyStreams(res) { // eslint-disable-line class-methods-use-this

View file

@ -11,7 +11,7 @@ import {get} from 'utilities/object';
import Following from './following'; import Following from './following';
import Game from './game'; import Game from './game';
import BrowsePopular from './browse_popular'; //import BrowsePopular from './browse_popular';
export const CARD_CONTEXTS = ((e ={}) => { export const CARD_CONTEXTS = ((e ={}) => {
@ -45,7 +45,7 @@ export default class Directory extends SiteModule {
this.inject(Following); this.inject(Following);
this.inject(Game); this.inject(Game);
this.inject(BrowsePopular); //this.inject(BrowsePopular);
this.DirectoryCard = this.fine.define( this.DirectoryCard = this.fine.define(
'directory-card', 'directory-card',
@ -336,6 +336,7 @@ export default class Directory extends SiteModule {
game = props.gameTitle || props.playerMetadataGame || (props.trackingProps && props.trackingProps.categoryName); game = props.gameTitle || props.playerMetadataGame || (props.trackingProps && props.trackingProps.categoryName);
container.classList.toggle('ffz-hide-thumbnail', this.settings.provider.get('directory.game.hidden-thumbnails', []).includes(game)); container.classList.toggle('ffz-hide-thumbnail', this.settings.provider.get('directory.game.hidden-thumbnails', []).includes(game));
container.dataset.ffzType = props.streamType;
const should_hide = (props.streamType === 'rerun' && this.settings.get('directory.hide-vodcasts')) || const should_hide = (props.streamType === 'rerun' && this.settings.get('directory.hide-vodcasts')) ||
(props.context !== CARD_CONTEXTS.SingleGameList && this.settings.provider.get('directory.game.blocked-games', []).includes(game)); (props.context !== CARD_CONTEXTS.SingleGameList && this.settings.provider.get('directory.game.blocked-games', []).includes(game));
@ -447,7 +448,7 @@ export default class Directory extends SiteModule {
inst.ffz_uptime_el = card.querySelector('.ffz-uptime-element'); inst.ffz_uptime_el = card.querySelector('.ffz-uptime-element');
if ( ! inst.ffz_uptime_el ) if ( ! inst.ffz_uptime_el )
card.appendChild(inst.ffz_uptime_el = (<div class="ffz-uptime-element tw-absolute tw-right-0 tw-top-0 tw-mg-1"> card.appendChild(inst.ffz_uptime_el = (<div class="ffz-uptime-element tw-absolute tw-right-0 tw-top-0 tw-mg-1">
<div class="tw-tooltip-wrapper"> <div class="tw-relative tw-tooltip-wrapper">
<div class="preview-card-stat tw-align-items-center tw-border-radi-us-small tw-c-background-overlay tw-c-text-overlay tw-flex tw-font-size-6 tw-justify-content-center"> <div class="preview-card-stat tw-align-items-center tw-border-radi-us-small tw-c-background-overlay tw-c-text-overlay tw-flex tw-font-size-6 tw-justify-content-center">
<div class="tw-flex tw-c-text-live"> <div class="tw-flex tw-c-text-live">
<figure class="ffz-i-clock" /> <figure class="ffz-i-clock" />

View file

@ -20,11 +20,14 @@ export default class ThemeEngine extends Module {
this.inject('settings'); this.inject('settings');
this.inject('site'); this.inject('site');
this.inject('site.fine');
this.inject('site.css_tweaks'); this.inject('site.css_tweaks');
this.inject('site.router'); this.inject('site.router');
this.should_enable = true; this.should_enable = true;
// Font
// Colors // Colors
this.settings.add('theme.color.background', { this.settings.add('theme.color.background', {
@ -32,7 +35,9 @@ export default class ThemeEngine extends Module {
ui: { ui: {
path: 'Appearance > Theme >> Colors @{"description": "This is a quick preview of a new system coming soon to FrankerFaceZ. Expect heavy changes here, including separate Basic and Advanced modes, and better color selection."}', path: 'Appearance > Theme >> Colors @{"description": "This is a quick preview of a new system coming soon to FrankerFaceZ. Expect heavy changes here, including separate Basic and Advanced modes, and better color selection."}',
title: 'Background', title: 'Background',
component: 'setting-color-box' 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',
alpha: false
}, },
changed: () => this.updateCSS() changed: () => this.updateCSS()
}); });
@ -42,6 +47,7 @@ export default class ThemeEngine extends Module {
ui: { ui: {
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.',
component: 'setting-color-box' component: 'setting-color-box'
}, },
changed: () => this.updateCSS() changed: () => this.updateCSS()
@ -55,13 +61,12 @@ export default class ThemeEngine extends Module {
}, },
ui: { ui: {
path: 'Appearance @{"description": "Personalize the appearance of Twitch. Change the color scheme and fonts and tune the layout to optimize your experience."} > Theme >> General', path: 'Appearance @{"description": "Personalize the appearance of Twitch. Change the color scheme and fonts and tune the layout to optimize your experience."} > Theme >> Legacy',
title: 'Gray (no Purple)', title: 'Gray (no Purple)',
description: `*Requires Dark Theme to be Enabled.* description: `*Requires Dark Theme to be Enabled.*
I see my website and I want it painted black... This setting will be going away very soon, as the new theme system matures.
The CSS loaded by this setting is far too heavy and can cause performance issues.`,
This is a very early feature and will change as there is time.`,
component: 'setting-check-box' component: 'setting-check-box'
}, },
@ -115,12 +120,32 @@ This is a very early feature and will change as there is time.`,
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 ) {
background.a = 1;
bits.push(`--color-background-body: ${background.toCSS()};`); bits.push(`--color-background-body: ${background.toCSS()};`);
const hsla = background.toHSLA(), const hsla = background.toHSLA(),
luma = hsla.l; luma = hsla.l;
dark = luma < 0.5; dark = luma < 0.5;
if ( dark && ! this.settings.get('theme.can-dark') )
return this.css_tweaks.delete('colors');
// Make sure the Twitch theme is set correctly.
try {
const store = this.resolve('site').store,
theme = store.getState().ui.theme,
wanted_theme = dark ? 1 : 0;
if( theme !== wanted_theme )
store.dispatch({
type: 'core.ui.THEME_CHANGED',
theme: wanted_theme
});
} catch(err) {
this.log.warning('Unable to automatically set the Twitch Dark Theme state.', err);
}
bits.push(`--color-background-input-focus: ${background.toCSS()};`);
bits.push(`--color-background-base: ${hsla._l(luma + (dark ? .05 : -.05)).toCSS()};`); bits.push(`--color-background-base: ${hsla._l(luma + (dark ? .05 : -.05)).toCSS()};`);
bits.push(`--color-background-alt: ${hsla._l(luma + (dark ? .1 : -.1)).toCSS()};`); bits.push(`--color-background-alt: ${hsla._l(luma + (dark ? .1 : -.1)).toCSS()};`);
bits.push(`--color-background-alt-2: ${hsla._l(luma + (dark ? .15 : -.15)).toCSS()};`); bits.push(`--color-background-alt-2: ${hsla._l(luma + (dark ? .15 : -.15)).toCSS()};`);
@ -135,10 +160,13 @@ This is a very early feature and will change as there is time.`,
bits.push(`--color-text-base: ${text.toCSS()};`); bits.push(`--color-text-base: ${text.toCSS()};`);
const hsla = text.toHSLA(), const hsla = text.toHSLA(),
luma = hsla.l; alpha = hsla.a;
bits.push(`--color-text-alt: ${hsla._l(luma + (dark ? -.1 : .1)).toRGBA().toCSS()};`); bits.push(`--color-text-label: ${text.toCSS()};`);
bits.push(`--color-text-alt-2: ${hsla._l(luma + (dark ? -.2 : .2)).toRGBA().toCSS()};`); bits.push(`--color-text-label-optional: ${hsla._a(alpha - 0.4).toCSS()};`);
bits.push(`--color-text-alt: ${hsla._a(alpha - 0.2).toCSS()};`);
bits.push(`--color-text-alt-2: ${hsla._a(alpha - 0.4).toCSS()};`);
} }

View file

@ -254,7 +254,7 @@ export default class VideoChatHook extends Module {
<button class="tw-button tw-button--text" data-test-selector="parent-reply-button" onClick={msg._reply_handler}> <button class="tw-button tw-button--text" data-test-selector="parent-reply-button" onClick={msg._reply_handler}>
<span class="tw-button__text tw-pd-0">{ t.i18n.t('video-chat.reply', 'Reply') }</span> <span class="tw-button__text tw-pd-0">{ t.i18n.t('video-chat.reply', 'Reply') }</span>
</button> </button>
<span class="tw-c-text-alt-2 tw-font-size-7 tw-mg-l-05 tw-tooltip-wrapper"> <span class="tw-c-text-alt-2 tw-font-size-7 tw-mg-l-05 tw-relative tw-tooltip-wrapper">
{ t.i18n.t('video-chat.time', '{time,humantime} ago', { { t.i18n.t('video-chat.time', '{time,humantime} ago', {
time: msg.timestamp time: msg.timestamp
}) } }) }
@ -288,7 +288,7 @@ export default class VideoChatHook extends Module {
> >
{this.props.hideTimestamp || (<div data-test-selector="message-timestamp" class="tw-align-right tw-flex tw-flex-shrink-0 vod-message__header"> {this.props.hideTimestamp || (<div data-test-selector="message-timestamp" class="tw-align-right tw-flex tw-flex-shrink-0 vod-message__header">
<div class="tw-mg-r-05"> <div class="tw-mg-r-05">
<div class="tw-inline-flex tw-tooltip-wrapper"> <div class="tw-inline-flex tw-relative tw-tooltip-wrapper">
<button class="tw-block tw-full-width tw-interactable tw-interactable--inverted" onClick={this.onTimestampClickHandler}> <button class="tw-block tw-full-width tw-interactable tw-interactable--inverted" onClick={this.onTimestampClickHandler}>
<div class="tw-pd-x-05"> <div class="tw-pd-x-05">
<p class="tw-font-size-7">{print_duration(context.comment.contentOffset)}</p> <p class="tw-font-size-7">{print_duration(context.comment.contentOffset)}</p>

View file

@ -1,45 +1,37 @@
body { .tw-root--theme-dark, html {
body,
.channel-header,
.channel-root__right-column,
.chat-room,
.carousel-player-nav-arrow__container {
background-color: var(--color-background-body) !important; background-color: var(--color-background-body) !important;
} }
.tw-root--theme-dark .channel-root__right-column, .clmgr-table__row,
.channel-root__right-column { .room-upsell,
background-color: var(--color-background-body) !important; .video-card {
} background-color: var(--color-background-base) !important;
}
.tw-root--theme-dark .chat-room, .side-nav__overlay-wrapper,
.chat-room { .thread-header__title-bar-container--focused {
background-color: var(--color-background-body) !important;
}
.tw-root--theme-dark .carousel-player-nav-arrow__container,
.carousel-player-nav-arrow__container {
background-color: var(--color-background-body) !important;
}
.tw-root--theme-dark .side-nav__overlay-wrapper,
.side-nav__overlay-wrapper {
background-color: var(--color-background-alt) !important; background-color: var(--color-background-alt) !important;
} }
.tw-root--theme-dark .side-nav-card__link:hover, .clmgr-table__row:hover,
.side-nav-card__link:hover { .thread-header__title-bar-container,
.whispers-list-item:hover,
.side-nav-card__link:hover {
background-color: var(--color-background-alt-2) !important; background-color: var(--color-background-alt-2) !important;
} }
.tw-root--theme-dark .channel-header, .channel-header__user {
.channel-header {
background-color: var(--color-background-body) !important;
}
.tw-root--theme-dark .channel-header__user,
.channel-header__user {
color: var(--color-text-base) !important; color: var(--color-text-base) !important;
} }
.tw-root--theme-dark .chat-line__moderation, .chat-line__timestamp,
.tw-root--theme-dark .chat-line__status, .chat-line__moderation,
.chat-line__moderation, .chat-line__status {
.chat-line__status {
color: var(--color-text-alt-2) !important; color: var(--color-text-alt-2) !important;
}
} }

View file

@ -1,5 +1,5 @@
<template functional> <template functional>
<div class="tw-tooltip-wrapper"> <div class="tw-relative tw-tooltip-wrapper">
<slot /> <slot />
<div <div
:class="`tw-tooltip--align-${props.align||'center'} tw-tooltip--${props.above ? 'up' : 'down'}`" :class="`tw-tooltip--align-${props.align||'center'} tw-tooltip--${props.above ? 'up' : 'down'}`"

View file

@ -248,8 +248,12 @@ textarea.tw-input {
p { p {
white-space: pre-line; white-space: pre-line;
} }
}
.ffz--changelog,
.ffz--widget {
code { code {
user-select: all;
padding: 2px 5px; padding: 2px 5px;
border-radius: 2px; border-radius: 2px;
background-color: rgba(0,0,0,0.1); background-color: rgba(0,0,0,0.1);

View file

@ -1,4 +1,4 @@
$color: #dad8de; /*$color: #dad8de;
$bg-color: #17141f; $bg-color: #17141f;
$border-color: #2c2541; $border-color: #2c2541;
@ -8,6 +8,7 @@ $input-border: #392e5c;
$input-active-border: #7d5bbe; $input-active-border: #7d5bbe;
.tw-root--theme-dark { .tw-root--theme-dark {
.vc-sketch { .vc-sketch {
background: $bg-color; background: $bg-color;
@ -93,4 +94,38 @@ $input-active-border: var(--ffz-color-5);
.vc-sketch-presets-color { .vc-sketch-presets-color {
box-shadow: inset 0 0 0 1px $border-color; box-shadow: inset 0 0 0 1px $border-color;
} }
}*/
.vc-sketch {
background-color: var(--color-background-body) !important;
box-shadow: 0 0 0 1px var(--color-border-base) !important;
}
.vc-sketch-active-color {
box-shadow: inset 0 0 0 1px var(--color-border-base) !important;
}
.vc-sketch-field {
.vc-input__input {
background-color: var(--color-background-input) !important;
color: var(--color-text-input) !important;
box-shadow: inset 0 0 0 1px var(--color-border-input) !important;
&:focus {
box-shadow: inset 0 0 0 1px var(--color-border-input-focus),
0 0 6px -2px var(--color-border-input-focus) !important;
}
}
.vc-input__label {
color: var(--color-text-label) !important;
}
}
.vc-sketch-presets {
border-top-color: var(--color-border-base) !important;
}
.vc-sketch-presets-color {
box-shadow: inset 0 0 0 1px var(--color-border-base) !important;
} }

View file

@ -32,7 +32,7 @@
} }
&.current { &.current {
border-left-color: var(--color-twitch-purple-8); border-left-color: var(--color-border-button-active);
} }
.description { .description {
@ -57,11 +57,7 @@
&:focus, &:focus,
&:hover { &:hover {
background: var(--color-opac-p-1); background-color: var(--color-background-alt-2);
.tw-root--theme-dark & {
background: var(--color-opac-p-4);
}
} }
} }

View file

@ -5,8 +5,8 @@
outline: none; outline: none;
.tab.active { .tab.active {
box-shadow: inset 0 0 0 1px var(--color-twitch-purple-8), box-shadow: inset 0 0 0 1px var(--color-border-tab-active),
0 0 6px -2px var(--color-twitch-purple-8); 0 0 6px -2px var(--color-border-tab-active);
} }
} }
@ -18,11 +18,7 @@
border-right: 1px solid; border-right: 1px solid;
&:first-child { border-left-width: 1px; border-left-style: solid } &:first-child { border-left-width: 1px; border-left-style: solid }
border-color: $border-light; border-color: var(--color-border-base);
.tw-root--theme-dark & {
border-color: $border-dark;
}
&.active:after { &.active:after {
position: absolute; position: absolute;
@ -30,7 +26,7 @@
left: 0; left: 0;
right: 0; right: 0;
content: ''; content: '';
border-bottom: 4px solid var(--color-twitch-purple-8); border-bottom: 4px solid var(--color-border-tab-active);
} }
} }