+
+
+
+
+
+
+
+
@@ -72,6 +72,9 @@
{{ t('setting.experiments.none', 'There are no current experiments.') }}
+
+ {{ t('setting.experiments.none-filter', 'There are no matching experiments.') }}
+
@@ -80,7 +83,7 @@
@@ -146,6 +149,9 @@
{{ t('setting.experiments.none', 'There are no current experiments.') }}
+
+ {{ t('setting.experiments.none-filter', 'There are no matching experiments.') }}
+
@@ -154,8 +160,16 @@
import {has} from 'utilities/object';
+function matches(exp, filter) {
+ return (exp.key && exp.key.toLowerCase().includes(filter)) ||
+ (exp.exp && (
+ (exp.exp.name && exp.exp.name.toLowerCase().includes(filter)) ||
+ (exp.exp.description && exp.exp.description.toLowerCase().includes(filter))
+ ));
+}
+
export default {
- props: ['item'],
+ props: ['item', 'filter'],
data() {
return {
@@ -166,6 +180,34 @@ export default {
}
},
+ computed: {
+ sorted_ffz() {
+ return this.sorted(this.ffz_data);
+ },
+
+ visible_ffz() {
+ const items = this.sorted_ffz,
+ f = this.filter && this.filter.toLowerCase();
+ if ( ! f )
+ return items;
+
+ return items.filter(x => matches(x, f));
+ },
+
+ sorted_twitch() {
+ return this.sorted(this.twitch_data);
+ },
+
+ visible_twitch() {
+ const items = this.sorted_twitch,
+ f = this.filter && this.filter.toLowerCase();
+ if ( ! f )
+ return items;
+
+ return items.filter(x => matches(x, f));
+ }
+ },
+
created() {
for(const key in this.ffz_data)
if ( has(this.ffz_data, key) ) {
diff --git a/src/modules/main_menu/index.js b/src/modules/main_menu/index.js
index d3bf7bbf..9d20afe3 100644
--- a/src/modules/main_menu/index.js
+++ b/src/modules/main_menu/index.js
@@ -160,6 +160,7 @@ export default class MainMenu extends Module {
await this.site.awaitElement(Dialog.EXCLUSIVE);
this.on('addons:added', this.scheduleUpdate, this);
+ this.on('experiments:enabled', this.scheduleUpdate, this);
this.on('i18n:update', this.scheduleUpdate, this);
this.dialog.on('show', () => {
diff --git a/src/settings/types.js b/src/settings/types.js
index af5bfe4b..cd847f6e 100644
--- a/src/settings/types.js
+++ b/src/settings/types.js
@@ -54,14 +54,15 @@ export const array_merge = {
get(key, profiles, definition, log) {
const values = [],
- trailing = [],
sources = [];
-
+ let trailing = [];
let had_value = false;
for(const profile of profiles)
if ( profile.has(key) ) {
- const value = profile.get(key);
+ const value = profile.get(key),
+ trail = [];
+
if ( ! Array.isArray(value) ) {
log.warn(`Profile #${profile.id} has an invalid value for "${key}" of type ${typeof value}. Skipping.`);
continue;
@@ -74,11 +75,13 @@ export const array_merge = {
if ( val.t === 'inherit' )
is_trailing = true;
else if ( is_trailing )
- trailing.unshift(val.v);
+ trail.push(val.v);
else
values.push(val.v);
}
+ trailing = trail.concat(trailing);
+
// If we didn't run into an inherit, don't inherit.
if ( ! is_trailing && ! definition.always_inherit )
break;
diff --git a/src/sites/twitch-twilight/modules/chat/index.js b/src/sites/twitch-twilight/modules/chat/index.js
index b5b7980c..752667db 100644
--- a/src/sites/twitch-twilight/modules/chat/index.js
+++ b/src/sites/twitch-twilight/modules/chat/index.js
@@ -375,9 +375,9 @@ export default class ChatHook extends Module {
},
ui: {
- path: 'Chat > Bits and Cheering >> Appearance',
- title: 'Display Top Cheerers',
- description: 'By default, this inherits its value from Display Bits.',
+ path: 'Chat > Appearance >> Community',
+ title: 'Display Leaderboard',
+ description: 'The leaderboard shows the top cheerers and sub gifters in a channel.\n\nBy default due to a previous implementation, this inherits its value from Chat > Bits and Cheering > Display Bits.',
component: 'setting-check-box'
}
});
@@ -550,6 +550,7 @@ export default class ChatHook extends Module {
this.css_tweaks.setVariable('chat-line-height', `${lh/10}rem`);
this.css_tweaks.setVariable('chat-font-family', font);
this.css_tweaks.setVariable('chat-width', `${width/10}rem`);
+ this.css_tweaks.setVariable('negative-chat-width', `${-width/10}rem`);
this.css_tweaks.toggle('chat-font', size !== 12 || font);
this.css_tweaks.toggle('chat-width', this.settings.get('chat.use-width'));
@@ -558,6 +559,7 @@ export default class ChatHook extends Module {
this.css_tweaks.toggle('emote-alignment-baseline', emote_alignment === 2);
this.emit(':update-chat-css');
+ this.emit('site.player:fix-player');
}
updateLineBorders() {
diff --git a/src/sites/twitch-twilight/modules/css_tweaks/index.js b/src/sites/twitch-twilight/modules/css_tweaks/index.js
index 3191bd97..c0accc14 100644
--- a/src/sites/twitch-twilight/modules/css_tweaks/index.js
+++ b/src/sites/twitch-twilight/modules/css_tweaks/index.js
@@ -18,7 +18,7 @@ const CLASSES = {
'side-friends': '.side-nav .online-friends',
'side-closed-friends': '.side-nav--collapsed .online-friends',
'side-closed-rec-channels': '.side-nav--collapsed .recommended-channels',
- 'side-offline-channels': '.side-nav-card__link[href*="/videos/"],.side-nav-card[href*="/videos/"]',
+ //'side-offline-channels': '.side-nav-card__link[href*="/videos/"],.side-nav-card[href*="/videos/"]',
'side-rerun-channels': '.side-nav .ffz--side-nav-card-rerun',
'community-highlights': '.community-highlight-stack__card',
@@ -59,6 +59,17 @@ export default class CSSTweaks extends Module {
// Layout
+ this.settings.add('layout.use-chat-fix', {
+ requires: ['layout.swap-sidebars', 'layout.use-portrait', 'chat.use-width'],
+ process(ctx) {
+ return ctx.get('layout.swap-sidebars') || ctx.get('layout.use-portrait') || ctx.get('chat.use-width')
+ },
+ changed: val => {
+ this.toggle('chat-fix', val);
+ this.emit('site.player:fix-player');
+ }
+ });
+
this.settings.add('layout.side-nav.show', {
default: true,
ui: {
@@ -127,7 +138,7 @@ export default class CSSTweaks extends Module {
changed: val => this.toggleHide('side-rec-friends', !val)
});
- this.settings.add('layout.side-nav.hide-offline', {
+ /*this.settings.add('layout.side-nav.hide-offline', {
default: false,
ui: {
path: 'Appearance > Layout >> Side Navigation',
@@ -135,7 +146,7 @@ export default class CSSTweaks extends Module {
component: 'setting-check-box'
},
changed: val => this.toggleHide('side-offline-channels', val)
- });
+ });*/
this.settings.add('layout.side-nav.rerun-style', {
default: 1,
@@ -307,6 +318,7 @@ export default class CSSTweaks extends Module {
}
onEnable() {
+ this.toggle('chat-fix', this.settings.get('layout.use-chat-fix'));
this.toggle('swap-sidebars', this.settings.get('layout.swap-sidebars'));
this.toggle('minimal-navigation', this.settings.get('layout.minimal-navigation'));
this.toggle('theatre-nav', this.settings.get('layout.theatre-navigation'));
@@ -314,7 +326,7 @@ export default class CSSTweaks extends Module {
this.toggle('hide-side-nav-avatars', ! this.settings.get('layout.side-nav.show-avatars'));
this.toggle('hide-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-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('prime-offers', !this.settings.get('layout.prime-offers'));
this.toggleHide('top-discover', !this.settings.get('layout.discover'));
@@ -339,6 +351,8 @@ export default class CSSTweaks extends Module {
this.updateFont();
this.updateTopNav();
+
+ this.emit('site.player:fix-player');
}
updateTopNav() {
diff --git a/src/sites/twitch-twilight/modules/css_tweaks/styles/chat-fix.scss b/src/sites/twitch-twilight/modules/css_tweaks/styles/chat-fix.scss
new file mode 100644
index 00000000..fd96aa3a
--- /dev/null
+++ b/src/sites/twitch-twilight/modules/css_tweaks/styles/chat-fix.scss
@@ -0,0 +1,25 @@
+body .video-watch-page__right-column,
+body .clips-watch-page__right-column,
+body .channel-page__right-column,
+body .right-column:not(.right-column--collapsed),
+body .channel-videos__right-column,
+body .channel-clips__sidebar,
+body .channel-events__sidebar,
+body .channel-follow-listing__right-column,
+body .channel-follow-listing__right-column,
+body .channel-root__right-column {
+ width: 34rem;
+}
+
+.channel-root__right-column--expanded {
+ position: initial;
+ transform: none !important;
+}
+
+.toggle-visibility__right-column--expanded {
+ transform: none !important;
+}
+
+.channel-root--hold-chat+.persistent-player, .channel-root--watch-chat+.persistent-player, .channel-root__info--with-chat .channel-info-content, .channel-root__player--with-chat {
+ width: 100% !important;
+}
\ No newline at end of file
diff --git a/src/sites/twitch-twilight/modules/css_tweaks/styles/portrait.scss b/src/sites/twitch-twilight/modules/css_tweaks/styles/portrait.scss
index e713f33b..d05de6f8 100644
--- a/src/sites/twitch-twilight/modules/css_tweaks/styles/portrait.scss
+++ b/src/sites/twitch-twilight/modules/css_tweaks/styles/portrait.scss
@@ -50,6 +50,10 @@
right: 0 !important;
}
+ .channel-root__right-column--expanded {
+ min-height: unset !important;
+ }
+
.right-column {
display: unset !important;
position: fixed !important;
diff --git a/src/sites/twitch-twilight/modules/css_tweaks/styles/square-avatars.scss b/src/sites/twitch-twilight/modules/css_tweaks/styles/square-avatars.scss
index 94743c52..dad1efee 100644
--- a/src/sites/twitch-twilight/modules/css_tweaks/styles/square-avatars.scss
+++ b/src/sites/twitch-twilight/modules/css_tweaks/styles/square-avatars.scss
@@ -1,3 +1,4 @@
+.user-avatar-animated,
.search-result-card,
.tw-avatar {
--border-radius-rounded: 0 !important;
@@ -9,4 +10,8 @@
.bits-leaderboard-medal .tw-avatar {
--border-radius-rounded: 9000px !important;
+}
+
+.user-avatar-animated .user-avatar-animated__halo {
+ visibility: hidden;
}
\ No newline at end of file
diff --git a/src/sites/twitch-twilight/modules/player.jsx b/src/sites/twitch-twilight/modules/player.jsx
index 834ffac4..634fb7b7 100644
--- a/src/sites/twitch-twilight/modules/player.jsx
+++ b/src/sites/twitch-twilight/modules/player.jsx
@@ -59,6 +59,11 @@ export default class Player extends Module {
PLAYER_ROUTES
);
+ this.PersistentPlayer = this.fine.define(
+ 'persistent-player',
+ n => n.state && n.state.playerStyles
+ );
+
this.Player = this.fine.define(
'highwind-player',
n => n.setPlayerActive && n.props?.playerEvents && n.props?.mediaPlayerInstance,
@@ -522,10 +527,10 @@ export default class Player extends Module {
this.installVisibilityHook();
this.on(':reset', this.resetAllPlayers, this);
+ this.on(':fix-player', () => this.PersistentPlayer.forceUpdate(), this);
const t = this;
-
this.SquadStreamBar.ready(cls => {
const old_should_render = cls.prototype.shouldRenderSquadBanner;
@@ -1097,7 +1102,8 @@ export default class Player extends Module {
const url = new URL(video.src);
if ( url.protocol !== 'blob:' )
return false;
- }
+ } else
+ return false;
/*this.PlayerSource.check();
for(const si of this.PlayerSource.instances) {