mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-27 21:05:53 +00:00
4.32.3
* Fixed: The FFZ Control Center button being positioned incorrectly on streamer dashboard pages. * Fixed: Profile rules for the current category/title not working on certain pages. * Fixed: Swap Sidebars causing rendering issues when in theater mode, with the chat below the player, when not using FrankerFaceZ's Portrait Mode option. * Fixed: The placeholder text being positioned wrong when using Twitch's WYSIWYG chat input. * Fixed: The entire extension loading when viewing an embedded clip, causing undue load. * Changed: Add a link to YouTube's Privacy Policy to the legal page.
This commit is contained in:
parent
370a579635
commit
155938f584
15 changed files with 74 additions and 25 deletions
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "frankerfacez",
|
||||
"author": "Dan Salvato LLC",
|
||||
"version": "4.32.2",
|
||||
"version": "4.32.3",
|
||||
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
||||
"private": true,
|
||||
"license": "Apache-2.0",
|
||||
|
|
12
src/entry.js
12
src/entry.js
|
@ -7,14 +7,16 @@
|
|||
|
||||
const DEBUG = localStorage.ffzDebugMode == 'true' && document.body.classList.contains('ffz-dev'),
|
||||
HOST = location.hostname,
|
||||
FLAVOR =
|
||||
SERVER = DEBUG ? '//localhost:8000' : '//cdn.frankerfacez.com',
|
||||
script = document.createElement('script');
|
||||
|
||||
let FLAVOR =
|
||||
HOST.includes('player') ? 'player' :
|
||||
HOST.includes('clips') ? 'clips' :
|
||||
(location.pathname === '/p/ffz_bridge/' ? 'bridge' : 'avalon'),
|
||||
SERVER = DEBUG ? '//localhost:8000' : '//cdn.frankerfacez.com',
|
||||
//CLIPS = /clips\.twitch\.tv/.test(location.hostname) ? 'clips/' : '',
|
||||
(location.pathname === '/p/ffz_bridge/' ? 'bridge' : 'avalon');
|
||||
|
||||
script = document.createElement('script');
|
||||
if (FLAVOR === 'clips' && location.pathname === '/embed')
|
||||
FLAVOR = 'player';
|
||||
|
||||
script.id = 'ffz-script';
|
||||
script.async = true;
|
||||
|
|
|
@ -301,7 +301,12 @@ export default class ExperimentManager extends Module {
|
|||
|
||||
setTwitchOverride(key, value = null) {
|
||||
const overrides = Cookie.getJSON(OVERRIDE_COOKIE) || {};
|
||||
overrides[key] = value;
|
||||
const experiments = overrides.experiments = overrides.experiments || {};
|
||||
const disabled = overrides.disabled = overrides.disabled || [];
|
||||
experiments[key] = value;
|
||||
const idx = disabled.indexOf(key);
|
||||
if (idx != -1)
|
||||
disabled.remove(idx);
|
||||
Cookie.set(OVERRIDE_COOKIE, overrides, COOKIE_OPTIONS);
|
||||
|
||||
const core = this.resolve('site')?.getCore?.();
|
||||
|
@ -312,12 +317,13 @@ export default class ExperimentManager extends Module {
|
|||
}
|
||||
|
||||
deleteTwitchOverride(key) {
|
||||
const overrides = Cookie.getJSON(OVERRIDE_COOKIE);
|
||||
if ( ! overrides || ! has(overrides, key) )
|
||||
const overrides = Cookie.getJSON(OVERRIDE_COOKIE),
|
||||
experiments = overrides?.experiments;
|
||||
if ( ! experiments || ! has(experiments, key) )
|
||||
return;
|
||||
|
||||
const old_val = overrides[key];
|
||||
delete overrides[key];
|
||||
const old_val = experiments[key];
|
||||
delete experiments[key];
|
||||
Cookie.set(OVERRIDE_COOKIE, overrides, COOKIE_OPTIONS);
|
||||
|
||||
const core = this.resolve('site')?.getCore?.();
|
||||
|
@ -328,8 +334,9 @@ export default class ExperimentManager extends Module {
|
|||
}
|
||||
|
||||
hasTwitchOverride(key) { // eslint-disable-line class-methods-use-this
|
||||
const overrides = Cookie.getJSON(OVERRIDE_COOKIE);
|
||||
return overrides && has(overrides, key);
|
||||
const overrides = Cookie.getJSON(OVERRIDE_COOKIE),
|
||||
experiments = overrides?.experiments;
|
||||
return experiments && has(experiments, key);
|
||||
}
|
||||
|
||||
getTwitchAssignment(key, channel = null) {
|
||||
|
|
|
@ -37,7 +37,7 @@ We use the APIs of the following services for scraping link information:
|
|||
* Twitch ([Terms of Service](https://www.twitch.tv/p/legal/terms-of-service/), [Developer Agreement](https://www.twitch.tv/p/legal/developer-agreement/))
|
||||
* Twitter ([Terms of Service](https://twitter.com/en/tos), [Developer Terms](https://developer.twitter.com/en/more/developer-terms.html))
|
||||
* xkcd
|
||||
* YouTube ([Terms of Service](https://www.youtube.com/t/terms), [Developer Terms of Service](https://developers.google.com/youtube/terms/developer-policies))
|
||||
* YouTube ([Terms of Service](https://www.youtube.com/t/terms), [Developer Terms of Service](https://developers.google.com/youtube/terms/developer-policies), [Privacy Policy](https://policies.google.com/privacy))
|
||||
|
||||
In addition to scraping via APIs, our link information reads standard metadata tags from
|
||||
HTML responses to support a wide array of other websites.
|
||||
|
|
|
@ -389,6 +389,30 @@ export default class Channel extends Module {
|
|||
el._ffz_links.innerHTML = '';
|
||||
}
|
||||
|
||||
// This is awful, but it works.
|
||||
let channel = null;
|
||||
this.fine.searchNode(react, node => {
|
||||
let state = node?.memoizedState, i = 0;
|
||||
while(state != null && channel == null && i < 50 ) {
|
||||
state = state?.next;
|
||||
channel = state?.memoizedState?.current?.previous?.result?.data?.user;
|
||||
if (!channel?.lastBroadcast?.game)
|
||||
channel = null;
|
||||
i++;
|
||||
}
|
||||
return channel != null;
|
||||
});
|
||||
|
||||
const game = channel?.lastBroadcast?.game,
|
||||
title = channel?.lastBroadcast?.title;
|
||||
|
||||
if (game?.id !== el._ffz_game_cache || title !== el._ffz_title_cache)
|
||||
this.settings.updateContext({
|
||||
category: game?.displayName,
|
||||
categoryID: game?.id,
|
||||
title
|
||||
});
|
||||
|
||||
// TODO: See if we can read this data directly from Apollo's cache.
|
||||
// Also, test how it works with videos and clips.
|
||||
/*const raw_game = el.querySelector('a[data-a-target="stream-game-link"]')?.textContent;
|
||||
|
@ -405,7 +429,7 @@ export default class Channel extends Module {
|
|||
}).catch(() => {
|
||||
el._ffz_game_cache_updating = false;
|
||||
});
|
||||
}*/
|
||||
}
|
||||
|
||||
const other_props = react.child.child?.child?.child?.child?.child?.child?.child?.child?.child?.memoizedProps,
|
||||
title = other_props?.title;
|
||||
|
@ -415,7 +439,7 @@ export default class Channel extends Module {
|
|||
this.settings.updateContext({
|
||||
title
|
||||
});
|
||||
}
|
||||
}*/
|
||||
|
||||
if ( ! this.settings.get('channel.hosting.enable') && props.hostLogin )
|
||||
this.setHost(props.channelID, props.channelLogin, null, null);
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
.ffz-emoji {
|
||||
width: 3.6rem !important;
|
||||
height: 3.6rem !important;
|
||||
width: calc(var(--ffz-chat-font-size) * 3) !important;
|
||||
height: calc(var(--ffz-chat-font-size) * 3) !important;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
.twitch-emote {
|
||||
max-height: 32px;
|
||||
max-width: 64px;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
.twitch-emote {
|
||||
max-height: 64px;
|
||||
max-width: 128px;
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
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 .right-column:not(.right-column--collapsed):not(.right-column--below),
|
||||
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 {
|
||||
body .channel-follow-listing__right-column/*,
|
||||
body .channel-root__right-column*/ {
|
||||
width: 34rem;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,13 +22,13 @@ body .channel-page__video-player--theatre-mode {
|
|||
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 .right-column:not(.right-column--collapsed):not(.right-column--below),
|
||||
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 {
|
||||
body .channel-follow-listing__right-column
|
||||
/*body .channel-root__right-column*/ {
|
||||
width: var(--ffz-chat-width) !important;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
.chat-input__textarea {
|
||||
.chat-wysiwyg-input__editor,
|
||||
.chat-wysiwyg-input__placeholder,
|
||||
.tw-textarea {
|
||||
padding-left: 1rem !important;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
order: 1;
|
||||
z-index: 2;
|
||||
|
||||
#root &:not(.right-column--collapsed) {
|
||||
#root &:not(.right-column--collapsed):not(.right-column--below) {
|
||||
width: var(--ffz-chat-width);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ export default class MenuButton extends SiteModule {
|
|||
);*/
|
||||
|
||||
this.SunlightNav = this.elemental.define(
|
||||
'sunlight-nav', '.sunlight-top-nav > div > div > div:nth-last-child(2) > div',
|
||||
'sunlight-nav', '.sunlight-top-nav > div > div > div:last-child > div',
|
||||
Twilight.SUNLIGHT_ROUTES,
|
||||
{attributes: true}, 1
|
||||
);
|
||||
|
|
|
@ -216,7 +216,7 @@ export default class ModView extends Module {
|
|||
let channel = null, state = root?.return?.memoizedState, i = 0;
|
||||
while(state != null && channel == null && i < 50 ) {
|
||||
state = state?.next;
|
||||
channel = state?.memoizedState?.current?.previousData?.result?.data?.channel;
|
||||
channel = state?.memoizedState?.current?.previous?.result?.data?.channel;
|
||||
i++;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
.chat-room,
|
||||
.video-chat,
|
||||
.qa-vod-chat,
|
||||
.extensions-popover-view-layout,
|
||||
.video-card {
|
||||
background-color: var(--color-background-base) !important;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue