mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-27 21:05:53 +00:00
4.77.1
* Fixed: Add support for a new React router Twitch is testing in an A/B experiment.
This commit is contained in:
parent
850c4d53fd
commit
43c80713e9
8 changed files with 114 additions and 22 deletions
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "frankerfacez",
|
"name": "frankerfacez",
|
||||||
"author": "Dan Salvato LLC",
|
"author": "Dan Salvato LLC",
|
||||||
"version": "4.77.0",
|
"version": "4.77.1",
|
||||||
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
|
|
@ -140,10 +140,10 @@ export default class ClipsSite extends BaseSite {
|
||||||
updateContext() {
|
updateContext() {
|
||||||
try {
|
try {
|
||||||
const state = this.store.getState(),
|
const state = this.store.getState(),
|
||||||
history = this.router && this.router.history;
|
location = this.router?.reactLocation;
|
||||||
|
|
||||||
this.settings.updateContext({
|
this.settings.updateContext({
|
||||||
location: history?.location,
|
location,
|
||||||
ui: state?.ui,
|
ui: state?.ui,
|
||||||
session: state?.session
|
session: state?.session
|
||||||
});
|
});
|
||||||
|
@ -223,4 +223,8 @@ ClipsSite.CLIP_ROUTES = {
|
||||||
'clip-page': '/:slug'
|
'clip-page': '/:slug'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ClipsSite.CHAT_ROUTES = [
|
||||||
|
'clip-page'
|
||||||
|
];
|
||||||
|
|
||||||
ClipsSite.DIALOG_SELECTOR = '#root > div';
|
ClipsSite.DIALOG_SELECTOR = '#root > div';
|
||||||
|
|
|
@ -211,3 +211,6 @@ export default class PlayerSite extends BaseSite {
|
||||||
ver.textContent = this.resolve('core').constructor.version_info.toString();
|
ver.textContent = this.resolve('core').constructor.version_info.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PlayerSite.CHAT_ROUTES = [];
|
||||||
|
|
|
@ -165,14 +165,15 @@ export default class Twilight extends BaseSite {
|
||||||
updateContext() {
|
updateContext() {
|
||||||
try {
|
try {
|
||||||
const state = this.store.getState(),
|
const state = this.store.getState(),
|
||||||
history = this.router && this.router.history;
|
location = this.router?.reactLocation;
|
||||||
|
|
||||||
this.settings.updateContext({
|
this.settings.updateContext({
|
||||||
location: history && history.location,
|
location,
|
||||||
ui: state && state.ui,
|
ui: state && state.ui,
|
||||||
session: state && state.session,
|
session: state && state.session,
|
||||||
chat: state && state.chat
|
chat: state && state.chat
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
this.log.error('Error updating context.', err);
|
this.log.error('Error updating context.', err);
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,7 +247,7 @@ export default class Channel extends Module {
|
||||||
if ( this.router.old_location === this.router.location )
|
if ( this.router.old_location === this.router.location )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.router.history.replace(this.router.location, {channelView: 'Watch'});
|
this.router.replace(this.router.location, {channelView: 'Watch'});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateLinks() {
|
updateLinks() {
|
||||||
|
|
|
@ -621,7 +621,7 @@ export default class Directory extends Module {
|
||||||
link.props.onClick();
|
link.props.onClick();
|
||||||
|
|
||||||
// And follow the generated link.
|
// And follow the generated link.
|
||||||
this.router.history.push(link.props.linkTo);
|
this.router.push(link.props.linkTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateGameCard(el) {
|
updateGameCard(el) {
|
||||||
|
@ -1029,7 +1029,7 @@ export default class Directory extends Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( url )
|
if ( url )
|
||||||
this.router.history.push(url);
|
this.router.push(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import Module, { GenericModule } from 'utilities/module';
|
||||||
import {has, deep_equals, sleep} from 'utilities/object';
|
import {has, deep_equals, sleep} from 'utilities/object';
|
||||||
import type Fine from './fine';
|
import type Fine from './fine';
|
||||||
import type { OptionalPromise } from 'utilities/types';
|
import type { OptionalPromise } from 'utilities/types';
|
||||||
|
import { ReactNode, ReactStateNode } from './react-types';
|
||||||
|
|
||||||
declare module 'utilities/types' {
|
declare module 'utilities/types' {
|
||||||
interface ModuleEventMap {
|
interface ModuleEventMap {
|
||||||
|
@ -34,6 +35,36 @@ export type RouteInfo = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
type ReactLocation = Location & {
|
||||||
|
state: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type HistoryObject = {
|
||||||
|
listen(fn: (location: ReactLocation) => void): void;
|
||||||
|
push(url: string, state: unknown): void;
|
||||||
|
replace(url: string, state: unknown): void;
|
||||||
|
location: ReactLocation;
|
||||||
|
};
|
||||||
|
|
||||||
|
type RouterState = {
|
||||||
|
historyAction: string;
|
||||||
|
location: ReactLocation;
|
||||||
|
};
|
||||||
|
|
||||||
|
type RouterObject = {
|
||||||
|
subscribe(fn: (state: RouterState) => void): void;
|
||||||
|
router: {
|
||||||
|
state: RouterState
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
type NavigationObject = {
|
||||||
|
push(url: string, state: unknown): void;
|
||||||
|
replace(url: string, state: unknown): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export default class FineRouter extends Module<'site.router', FineRouterEvents> {
|
export default class FineRouter extends Module<'site.router', FineRouterEvents> {
|
||||||
|
|
||||||
// Dependencies
|
// Dependencies
|
||||||
|
@ -51,6 +82,10 @@ export default class FineRouter extends Module<'site.router', FineRouterEvents>
|
||||||
match: unknown | null;
|
match: unknown | null;
|
||||||
location: unknown | null;
|
location: unknown | null;
|
||||||
|
|
||||||
|
// Things
|
||||||
|
history?: HistoryObject | null;
|
||||||
|
router?: RouterObject | null;
|
||||||
|
navigator?: NavigationObject | null;
|
||||||
|
|
||||||
|
|
||||||
constructor(name?: string, parent?: GenericModule) {
|
constructor(name?: string, parent?: GenericModule) {
|
||||||
|
@ -69,26 +104,75 @@ export default class FineRouter extends Module<'site.router', FineRouterEvents>
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
onEnable(): OptionalPromise<void> {
|
onEnable(tries = 0): OptionalPromise<void> {
|
||||||
const thing = this.fine.searchTree(null, n => n.props && n.props.history),
|
const thing = this.fine.searchTree<ReactStateNode<{history: HistoryObject}>>(null, n => n?.props?.history);
|
||||||
history = this.history = thing && thing.props && thing.props.history;
|
this.history = thing?.props?.history;
|
||||||
|
|
||||||
if ( ! history )
|
if ( this.history ) {
|
||||||
return sleep(50).then(() => this.onEnable());
|
this.history.listen(location => {
|
||||||
|
|
||||||
history.listen(location => {
|
|
||||||
if ( this.enabled )
|
if ( this.enabled )
|
||||||
this._navigateTo(location);
|
this._navigateTo(location);
|
||||||
});
|
});
|
||||||
|
|
||||||
this._navigateTo(history.location);
|
this._navigateTo(this.history.location);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const other = this.fine.searchNode(null, n => n?.pendingProps?.router?.subscribe);
|
||||||
|
this.router = other?.pendingProps?.router;
|
||||||
|
|
||||||
|
const nav = this.fine.searchNode(null, n => n?.pendingProps?.navigator?.push);
|
||||||
|
this.navigator = nav?.pendingProps?.navigator;
|
||||||
|
|
||||||
|
if ( ! this.router || ! this.navigator ) {
|
||||||
|
if (tries > 100) {
|
||||||
|
this.log.warn('Finding React\'s router is taking a long time.');
|
||||||
|
tries = -500;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sleep(50).then(() => this.onEnable(tries + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.router.subscribe(evt => {
|
||||||
|
if ( this.enabled && evt?.location )
|
||||||
|
this._navigateTo(evt.location);
|
||||||
|
});
|
||||||
|
|
||||||
|
this._navigateTo(this.router.router.state.location);
|
||||||
}
|
}
|
||||||
|
|
||||||
navigate(route, data, opts, state) {
|
navigate(route, data, opts, state) {
|
||||||
this.history.push(this.getURL(route, data, opts), state);
|
const url = this.getURL(route, data, opts);
|
||||||
|
this.push(url, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _navigateTo(location) {
|
get reactLocation() {
|
||||||
|
if (this.history)
|
||||||
|
return this.history.location;
|
||||||
|
else if (this.router)
|
||||||
|
return this.router.router.state.location;
|
||||||
|
}
|
||||||
|
|
||||||
|
push(url: string, state: unknown) {
|
||||||
|
if (this.history)
|
||||||
|
this.history.push(url, state);
|
||||||
|
else if (this.navigator)
|
||||||
|
this.navigator.push(url, state);
|
||||||
|
else
|
||||||
|
throw new Error('unable to push new route');
|
||||||
|
}
|
||||||
|
|
||||||
|
replace(url: string, state: unknown) {
|
||||||
|
if (this.history)
|
||||||
|
this.history.replace(url, state);
|
||||||
|
else if (this.navigator)
|
||||||
|
this.navigator.replace(url, state);
|
||||||
|
else
|
||||||
|
throw new Error('unable to replace route');
|
||||||
|
}
|
||||||
|
|
||||||
|
private _navigateTo(location: ReactLocation) {
|
||||||
this.log.debug('New Location', location);
|
this.log.debug('New Location', location);
|
||||||
const host = window.location.host,
|
const host = window.location.host,
|
||||||
path = location.pathname,
|
path = location.pathname,
|
||||||
|
|
|
@ -218,16 +218,16 @@ export class VueModule extends Module<'vue'> {
|
||||||
methods: {
|
methods: {
|
||||||
reactNavigate(url, event, state) {
|
reactNavigate(url, event, state) {
|
||||||
const router = t.resolve('site.router');
|
const router = t.resolve('site.router');
|
||||||
if ( router && router.history ) {
|
if ( router ) {
|
||||||
if ( event ) {
|
if ( event ) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
}
|
||||||
router.history.push(url, state ?? undefined);
|
router.push(url, state ?? undefined);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getReactURL(route, data, opts, ...args) {
|
getReactURL(route, data, opts, ...args) {
|
||||||
const router = t.resolve('site.router');
|
const router = t.resolve('site.router')!;
|
||||||
return router.getURL(route, data, opts, ...args);
|
return router.getURL(route, data, opts, ...args);
|
||||||
},
|
},
|
||||||
getI18n() {
|
getI18n() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue