mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-07-03 17:48:30 +00:00
Use ref-counting with socket topic subscriptions to make it easy to tell when we should and shouldn't actually unsubscribe. Add route awareness to FineWrapper so that we can unregister the MutationObserver when we know we won't be suddenly finding an instance that we're looking for. Have the channel bar register for the channel pubsub topic. Fix minimize navigation showing the navigation bar over top of theater mode.
This commit is contained in:
parent
c559790f87
commit
254d297f79
17 changed files with 160 additions and 71 deletions
|
@ -65,7 +65,7 @@ export default class Room {
|
||||||
if ( this.manager.rooms[this._login] === this )
|
if ( this.manager.rooms[this._login] === this )
|
||||||
this.manager.rooms[this._login] = null;
|
this.manager.rooms[this._login] = null;
|
||||||
|
|
||||||
this.manager.socket.unsubscribe(`room.${this.login}`);
|
this.manager.socket.unsubscribe(this, `room.${this.login}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( this.manager.room_ids[this.id] === this )
|
if ( this.manager.room_ids[this.id] === this )
|
||||||
|
@ -89,7 +89,7 @@ export default class Room {
|
||||||
const old_room = this.manager.rooms[this._login];
|
const old_room = this.manager.rooms[this._login];
|
||||||
if ( old_room === this ) {
|
if ( old_room === this ) {
|
||||||
this.manager.rooms[this._login] = null;
|
this.manager.rooms[this._login] = null;
|
||||||
this.manager.socket.unsubscribe(`room.${this.login}`);
|
this.manager.socket.unsubscribe(this, `room.${this.login}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ export default class Room {
|
||||||
old_room.login = null;
|
old_room.login = null;
|
||||||
|
|
||||||
this.manager.rooms[val] = this;
|
this.manager.rooms[val] = this;
|
||||||
this.manager.socket.subscribe(`room.${val}`);
|
this.manager.socket.subscribe(this, `room.${val}`);
|
||||||
this.manager.emit(':room-update-login', this, val);
|
this.manager.emit(':room-update-login', this, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,12 @@ export default class Twilight extends BaseSite {
|
||||||
|
|
||||||
this.router.on(':route', (route, match) => {
|
this.router.on(':route', (route, match) => {
|
||||||
this.log.info('Navigation', route && route.name, match && match[0]);
|
this.log.info('Navigation', route && route.name, match && match[0]);
|
||||||
|
this.fine.route(route && route.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const current = this.router.current;
|
||||||
|
this.fine.route(current && current.name);
|
||||||
|
|
||||||
document.head.appendChild(e('link', {
|
document.head.appendChild(e('link', {
|
||||||
href: MAIN_URL,
|
href: MAIN_URL,
|
||||||
rel: 'stylesheet',
|
rel: 'stylesheet',
|
||||||
|
@ -95,6 +99,19 @@ Twilight.KNOWN_MODULES = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Twilight.CHAT_ROUTES = [
|
||||||
|
'collection',
|
||||||
|
'popout',
|
||||||
|
'video',
|
||||||
|
'user-videos',
|
||||||
|
'user-clips',
|
||||||
|
'user-events',
|
||||||
|
'user-followers',
|
||||||
|
'user-following',
|
||||||
|
'user'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
Twilight.ROUTES = {
|
Twilight.ROUTES = {
|
||||||
'front-page': '/',
|
'front-page': '/',
|
||||||
'collection': '/collections/:collectionID',
|
'collection': '/collections/:collectionID',
|
||||||
|
@ -110,10 +127,13 @@ Twilight.ROUTES = {
|
||||||
'dir-all': '/directory/all/:filter?',
|
'dir-all': '/directory/all/:filter?',
|
||||||
'dir-category': '/directory/:category?',
|
'dir-category': '/directory/:category?',
|
||||||
'event': '/event/:eventName',
|
'event': '/event/:eventName',
|
||||||
'following': '/following',
|
'popout': '/popout/:userName/chat',
|
||||||
'popout': '/popout',
|
|
||||||
'video': '/videos/:videoID',
|
'video': '/videos/:videoID',
|
||||||
'user-videos': '/:userName/videos/:filter?',
|
'user-videos': '/:userName/videos/:filter?',
|
||||||
'user-clips': '/:userName/manager/clips',
|
'user-clips': '/:userName/clips',
|
||||||
|
'user-collections': '/:userName/collections',
|
||||||
|
'user-events': '/:userName/events',
|
||||||
|
'user-followers': '/:userName/followers',
|
||||||
|
'user-following': '/:userName/following',
|
||||||
'user': '/:userName'
|
'user': '/:userName'
|
||||||
}
|
}
|
|
@ -19,6 +19,7 @@ export default class ChannelBar extends Module {
|
||||||
this.inject('site.fine');
|
this.inject('site.fine');
|
||||||
this.inject('site.apollo');
|
this.inject('site.apollo');
|
||||||
this.inject('metadata');
|
this.inject('metadata');
|
||||||
|
this.inject('socket');
|
||||||
|
|
||||||
this.apollo.registerModifier('ChannelPage_ChannelInfoBar_User', CHANNEL_QUERY);
|
this.apollo.registerModifier('ChannelPage_ChannelInfoBar_User', CHANNEL_QUERY);
|
||||||
this.apollo.registerModifier('ChannelPage_ChannelInfoBar_User', data => {
|
this.apollo.registerModifier('ChannelPage_ChannelInfoBar_User', data => {
|
||||||
|
@ -32,39 +33,60 @@ export default class ChannelBar extends Module {
|
||||||
|
|
||||||
this.ChannelBar = this.fine.define(
|
this.ChannelBar = this.fine.define(
|
||||||
'channel-bar',
|
'channel-bar',
|
||||||
n => n.getTitle && n.getGame && n.renderGame
|
n => n.getTitle && n.getGame && n.renderGame,
|
||||||
|
['user']
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
this.HostBar = this.fine.define(
|
this.HostBar = this.fine.define(
|
||||||
'host-container',
|
'host-container',
|
||||||
n => n.handleReportHosterClick
|
n => n.handleReportHosterClick,
|
||||||
|
['user']
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
onEnable() {
|
onEnable() {
|
||||||
|
this.ChannelBar.on('unmount', this.unmountChannelBar, this);
|
||||||
|
this.ChannelBar.on('mount', this.updateChannelBar, this);
|
||||||
|
this.ChannelBar.on('update', this.updateChannelBar, this);
|
||||||
|
|
||||||
this.ChannelBar.ready((cls, instances) => {
|
this.ChannelBar.ready((cls, instances) => {
|
||||||
for(const inst of instances)
|
for(const inst of instances)
|
||||||
this.updateChannelBar(inst);
|
this.updateChannelBar(inst);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.ChannelBar.on('unmount', this.unmountChannelBar, this);
|
|
||||||
this.ChannelBar.on('mount', this.updateChannelBar, this);
|
|
||||||
this.ChannelBar.on('update', this.updateChannelBar, this);
|
|
||||||
|
|
||||||
/*this.HostBar.on('mount', inst => {
|
/*this.HostBar.on('unmount', this.unmountHostBar, this);
|
||||||
this.log.info('host-mount', inst, this.fine.getChildNode(inst));
|
this.HostBar.on('mount', this.updateHostBar, this);
|
||||||
});
|
this.HostBar.on('update', this.updateHostBar, this);
|
||||||
|
|
||||||
this.HostBar.ready((cls, instances) => {
|
this.HostBar.ready((cls, instances) => {
|
||||||
for(const inst of instances)
|
for(const inst of instances)
|
||||||
this.log.info('host-found', inst, this.fine.getChildNode(inst));
|
this.updateHostBar(inst);
|
||||||
})*/
|
});*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unmountChannelBar(inst) { // eslint-disable-line class-methods-use-this
|
updateChannelBar(inst) {
|
||||||
|
const login = inst.props.channelLogin;
|
||||||
|
if ( login !== inst._ffz_old_login ) {
|
||||||
|
if ( inst._ffz_old_login )
|
||||||
|
this.socket.unsubscribe(inst, `channel.${inst._ffz_old_login}`);
|
||||||
|
|
||||||
|
if ( login )
|
||||||
|
this.socket.subscribe(inst, `channel.${login}`);
|
||||||
|
inst._ffz_old_login = login;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateMetadata(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
unmountChannelBar(inst) {
|
||||||
|
if ( inst._ffz_old_login ) {
|
||||||
|
this.socket.unsubscribe(inst, `channel.${inst._ffz_old_login}`);
|
||||||
|
inst._ffz_old_login = null;
|
||||||
|
}
|
||||||
|
|
||||||
const timers = inst._ffz_meta_timers;
|
const timers = inst._ffz_meta_timers;
|
||||||
if ( timers )
|
if ( timers )
|
||||||
for(const key in timers)
|
for(const key in timers)
|
||||||
|
@ -75,11 +97,6 @@ export default class ChannelBar extends Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
updateChannelBar(inst) {
|
|
||||||
this.updateMetadata(inst);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
updateMetadata(inst, keys) {
|
updateMetadata(inst, keys) {
|
||||||
const container = this.fine.getChildNode(inst),
|
const container = this.fine.getChildNode(inst),
|
||||||
metabar = container && container.querySelector && container.querySelector('.channel-info-bar__action-container > .tw-flex');
|
metabar = container && container.querySelector && container.querySelector('.channel-info-bar__action-container > .tw-flex');
|
||||||
|
|
|
@ -10,6 +10,8 @@ import {has, split_chars} from 'utilities/object';
|
||||||
|
|
||||||
import Module from 'utilities/module';
|
import Module from 'utilities/module';
|
||||||
|
|
||||||
|
import Twilight from 'site';
|
||||||
|
|
||||||
import Scroller from './scroller';
|
import Scroller from './scroller';
|
||||||
import ChatLine from './line';
|
import ChatLine from './line';
|
||||||
import SettingsMenu from './settings_menu';
|
import SettingsMenu from './settings_menu';
|
||||||
|
@ -114,17 +116,20 @@ export default class ChatHook extends Module {
|
||||||
|
|
||||||
this.ChatController = this.fine.define(
|
this.ChatController = this.fine.define(
|
||||||
'chat-controller',
|
'chat-controller',
|
||||||
n => n.chatService
|
n => n.chatService,
|
||||||
|
Twilight.CHAT_ROUTES
|
||||||
);
|
);
|
||||||
|
|
||||||
this.ChatContainer = this.fine.define(
|
this.ChatContainer = this.fine.define(
|
||||||
'chat-container',
|
'chat-container',
|
||||||
n => n.showViewersList && n.onChatInputFocus
|
n => n.showViewersList && n.onChatInputFocus,
|
||||||
|
Twilight.CHAT_ROUTES
|
||||||
);
|
);
|
||||||
|
|
||||||
this.PinnedCheer = this.fine.define(
|
this.PinnedCheer = this.fine.define(
|
||||||
'pinned-cheer',
|
'pinned-cheer',
|
||||||
n => n.collapseCheer && n.saveRenderedMessageRef
|
n => n.collapseCheer && n.saveRenderedMessageRef,
|
||||||
|
Twilight.CHAT_ROUTES
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
// Chat Line
|
// Chat Line
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
|
import Twilight from 'site';
|
||||||
import Module from 'utilities/module';
|
import Module from 'utilities/module';
|
||||||
//import {Color} from 'utilities/color';
|
//import {Color} from 'utilities/color';
|
||||||
|
|
||||||
|
@ -25,12 +26,14 @@ export default class ChatLine extends Module {
|
||||||
|
|
||||||
this.ChatLine = this.fine.define(
|
this.ChatLine = this.fine.define(
|
||||||
'chat-line',
|
'chat-line',
|
||||||
n => n.renderMessageBody && ! n.getMessageParts
|
n => n.renderMessageBody && ! n.getMessageParts,
|
||||||
|
Twilight.CHAT_ROUTES
|
||||||
);
|
);
|
||||||
|
|
||||||
this.ChatRoomLine = this.fine.define(
|
this.ChatRoomLine = this.fine.define(
|
||||||
'chat-room-line',
|
'chat-room-line',
|
||||||
n => n.renderMessageBody && n.getMessageParts
|
n => n.renderMessageBody && n.getMessageParts,
|
||||||
|
Twilight.CHAT_ROUTES
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +49,7 @@ export default class ChatLine extends Module {
|
||||||
|
|
||||||
const e = React.createElement;
|
const e = React.createElement;
|
||||||
|
|
||||||
this.ChatLine.ready((cls, instances) => {
|
this.ChatLine.ready(cls => {
|
||||||
cls.prototype.shouldComponentUpdate = function(props, state) {
|
cls.prototype.shouldComponentUpdate = function(props, state) {
|
||||||
const show = state.alwaysShowMessage || ! props.message.deleted,
|
const show = state.alwaysShowMessage || ! props.message.deleted,
|
||||||
old_show = this._ffz_show;
|
old_show = this._ffz_show;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
import {createElement as e} from 'utilities/dom';
|
import {createElement as e} from 'utilities/dom';
|
||||||
|
import Twilight from 'site';
|
||||||
import Module from 'utilities/module';
|
import Module from 'utilities/module';
|
||||||
|
|
||||||
export default class Scroller extends Module {
|
export default class Scroller extends Module {
|
||||||
|
@ -19,7 +20,8 @@ export default class Scroller extends Module {
|
||||||
|
|
||||||
this.ChatScroller = this.fine.define(
|
this.ChatScroller = this.fine.define(
|
||||||
'chat-scroller',
|
'chat-scroller',
|
||||||
n => n.saveScrollRef && n.handleScrollEvent
|
n => n.saveScrollRef && n.handleScrollEvent,
|
||||||
|
Twilight.CHAT_ROUTES
|
||||||
);
|
);
|
||||||
|
|
||||||
this.settings.add('chat.scroller.freeze', {
|
this.settings.add('chat.scroller.freeze', {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
// Chat Settings Menu
|
// Chat Settings Menu
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
import {createElement as e} from 'utilities/dom';
|
import Twilight from 'site';
|
||||||
import Module from 'utilities/module';
|
import Module from 'utilities/module';
|
||||||
|
|
||||||
export default class SettingsMenu extends Module {
|
export default class SettingsMenu extends Module {
|
||||||
|
@ -19,7 +19,8 @@ export default class SettingsMenu extends Module {
|
||||||
|
|
||||||
this.SettingsMenu = this.fine.define(
|
this.SettingsMenu = this.fine.define(
|
||||||
'chat-settings',
|
'chat-settings',
|
||||||
n => n.renderUniversalOptions && n.dismissRaidsTooltip
|
n => n.renderUniversalOptions && n.dismissRaidsTooltip,
|
||||||
|
Twilight.CHAT_ROUTES
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
.twilight-root {
|
.twilight-root {
|
||||||
.top-nav {
|
.top-nav {
|
||||||
z-index: 9999;
|
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
height: 5rem !important;
|
height: 5rem !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,8 @@ export default class BrowsePopular extends SiteModule {
|
||||||
|
|
||||||
this.ChannelCard = this.fine.define(
|
this.ChannelCard = this.fine.define(
|
||||||
'browse-all-channel-card',
|
'browse-all-channel-card',
|
||||||
n => n.props && n.props.channelName && n.props.linkTo && n.props.linkTo.state && n.props.linkTo.state.medium === 'twitch_browse_directory'
|
n => n.props && n.props.channelName && n.props.linkTo && n.props.linkTo.state && n.props.linkTo.state.medium === 'twitch_browse_directory',
|
||||||
|
['dir-all']
|
||||||
);
|
);
|
||||||
|
|
||||||
this.apollo.registerModifier('BrowsePage_Popular', res => this.modifyStreams(res), false);
|
this.apollo.registerModifier('BrowsePage_Popular', res => this.modifyStreams(res), false);
|
||||||
|
|
|
@ -70,7 +70,8 @@ export default class Following extends SiteModule {
|
||||||
|
|
||||||
this.ChannelCard = this.fine.define(
|
this.ChannelCard = this.fine.define(
|
||||||
'following-channel-card',
|
'following-channel-card',
|
||||||
n => n.renderGameBoxArt && n.renderContentType
|
n => n.renderGameBoxArt && n.renderContentType,
|
||||||
|
['dir-following']
|
||||||
);
|
);
|
||||||
|
|
||||||
this.apollo.registerModifier('FollowedIndex_CurrentUser', res => {
|
this.apollo.registerModifier('FollowedIndex_CurrentUser', res => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
query {
|
query {
|
||||||
directory {
|
directory {
|
||||||
... on Game {
|
... on Community {
|
||||||
streams {
|
streams {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
|
@ -13,7 +13,7 @@ query {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
... on Community {
|
... on Game {
|
||||||
streams {
|
streams {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
|
|
|
@ -21,7 +21,8 @@ export default class Game extends SiteModule {
|
||||||
|
|
||||||
this.GameHeader = this.fine.define(
|
this.GameHeader = this.fine.define(
|
||||||
'game-header',
|
'game-header',
|
||||||
n => n.renderFollowButton && n.renderGameDetailsTab
|
n => n.renderFollowButton && n.renderGameDetailsTab,
|
||||||
|
['dir-game-index', 'dir-community']
|
||||||
);
|
);
|
||||||
|
|
||||||
this.apollo.registerModifier('GamePage_Game', GAME_QUERY);
|
this.apollo.registerModifier('GamePage_Game', GAME_QUERY);
|
||||||
|
|
|
@ -35,7 +35,8 @@ export default class Directory extends SiteModule {
|
||||||
|
|
||||||
this.ChannelCard = this.fine.define(
|
this.ChannelCard = this.fine.define(
|
||||||
'channel-card',
|
'channel-card',
|
||||||
n => n.props && n.props.streamNode
|
n => n.props && n.props.streamNode,
|
||||||
|
['dir-community', 'dir-game-index']
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,8 @@ export default class Player extends Module {
|
||||||
|
|
||||||
this.Player = this.fine.define(
|
this.Player = this.fine.define(
|
||||||
'twitch-player',
|
'twitch-player',
|
||||||
n => n.player && n.onPlayerReady
|
n => n.player && n.onPlayerReady,
|
||||||
|
['front-page', 'user', 'video']
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,8 @@ export default class SubButton extends Module {
|
||||||
|
|
||||||
this.SubButton = this.fine.define(
|
this.SubButton = this.fine.define(
|
||||||
'sub-button',
|
'sub-button',
|
||||||
n => n.reportSubMenuAction && n.isUserDataReady
|
n => n.reportSubMenuAction && n.isUserDataReady,
|
||||||
|
['user', 'video']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ export default class SocketClient extends Module {
|
||||||
|
|
||||||
this._want_connected = false;
|
this._want_connected = false;
|
||||||
|
|
||||||
this._topics = new Set;
|
this._topics = new Map;
|
||||||
this._pending = [];
|
this._pending = [];
|
||||||
this._awaiting = new Map;
|
this._awaiting = new Map;
|
||||||
|
|
||||||
|
@ -426,30 +426,42 @@ export default class SocketClient extends Module {
|
||||||
// Topics
|
// Topics
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
|
|
||||||
subscribe(...topics) {
|
subscribe(referrer, ...topics) {
|
||||||
const t = this._topics;
|
const t = this._topics;
|
||||||
for(const topic of topics) {
|
for(const topic of topics) {
|
||||||
if ( this.connected && ! t.has(topic) )
|
if ( ! t.has(topic) ) {
|
||||||
|
if ( this.connected )
|
||||||
this._send('sub', topic);
|
this._send('sub', topic);
|
||||||
|
|
||||||
t.add(topic);
|
t.set(topic, new Set);
|
||||||
|
}
|
||||||
|
|
||||||
|
const tp = t.get(topic);
|
||||||
|
tp.add(referrer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsubscribe(...topics) {
|
unsubscribe(referrer, ...topics) {
|
||||||
const t = this._topics;
|
const t = this._topics;
|
||||||
for(const topic of topics) {
|
for(const topic of topics) {
|
||||||
if ( this.connected && t.has(topic) )
|
if ( ! t.has(topic) )
|
||||||
this._send('unsub', topic);
|
continue;
|
||||||
|
|
||||||
|
const tp = t.get(topic);
|
||||||
|
tp.delete(referrer);
|
||||||
|
|
||||||
|
if ( ! tp.size ) {
|
||||||
t.delete(topic);
|
t.delete(topic);
|
||||||
|
if ( this.connected )
|
||||||
|
this._send('unsub', topic);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
get topics() {
|
get topics() {
|
||||||
return Array.from(this._topics);
|
return Array.from(this._topics.keys());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,8 @@ export default class Fine extends Module {
|
||||||
this._wrappers = new Map;
|
this._wrappers = new Map;
|
||||||
this._known_classes = new Map;
|
this._known_classes = new Map;
|
||||||
this._observer = null;
|
this._observer = null;
|
||||||
this._waiting = null;
|
this._waiting = [];
|
||||||
|
this._live_waiting = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -250,14 +251,39 @@ export default class Fine extends Module {
|
||||||
// Class Wrapping
|
// Class Wrapping
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
|
|
||||||
define(key, criteria) {
|
route(route) {
|
||||||
|
this._route = route;
|
||||||
|
this._updateLiveWaiting();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_updateLiveWaiting() {
|
||||||
|
const lw = this._live_waiting = [],
|
||||||
|
crt = this._waiting_crit = [],
|
||||||
|
route = this._route;
|
||||||
|
|
||||||
|
if ( this._waiting )
|
||||||
|
for(const waiter of this._waiting)
|
||||||
|
if ( ! route || ! waiter.routes.length || waiter.routes.includes(route) ) {
|
||||||
|
lw.push(waiter);
|
||||||
|
crt.push(waiter.criteria);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! this._live_waiting.length )
|
||||||
|
this._stopWaiting();
|
||||||
|
else if ( ! this._waiting_timer )
|
||||||
|
this._startWaiting();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
define(key, criteria, routes) {
|
||||||
if ( this._wrappers.has(key) )
|
if ( this._wrappers.has(key) )
|
||||||
return this._wrappers.get(key);
|
return this._wrappers.get(key);
|
||||||
|
|
||||||
if ( ! criteria )
|
if ( ! criteria )
|
||||||
throw new Error('cannot find definition and no criteria provided');
|
throw new Error('cannot find definition and no criteria provided');
|
||||||
|
|
||||||
const wrapper = new FineWrapper(key, criteria, this);
|
const wrapper = new FineWrapper(key, criteria, routes, this);
|
||||||
this._wrappers.set(key, wrapper);
|
this._wrappers.set(key, wrapper);
|
||||||
|
|
||||||
const data = this.searchAll(this.react, [criteria], 1000)[0];
|
const data = this.searchAll(this.react, [criteria], 1000)[0];
|
||||||
|
@ -266,11 +292,8 @@ export default class Fine extends Module {
|
||||||
this._known_classes.set(data.cls, wrapper);
|
this._known_classes.set(data.cls, wrapper);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if ( ! this._waiting )
|
|
||||||
this._startWaiting();
|
|
||||||
|
|
||||||
this._waiting.push(wrapper);
|
this._waiting.push(wrapper);
|
||||||
this._waiting_crit.push(criteria);
|
this._updateLiveWaiting();
|
||||||
}
|
}
|
||||||
|
|
||||||
return wrapper;
|
return wrapper;
|
||||||
|
@ -278,7 +301,7 @@ export default class Fine extends Module {
|
||||||
|
|
||||||
|
|
||||||
_checkWaiters(nodes) {
|
_checkWaiters(nodes) {
|
||||||
if ( ! this._waiting )
|
if ( ! this._live_waiting )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( ! Array.isArray(nodes) )
|
if ( ! Array.isArray(nodes) )
|
||||||
|
@ -287,12 +310,12 @@ export default class Fine extends Module {
|
||||||
for(let node of nodes) {
|
for(let node of nodes) {
|
||||||
if ( ! node )
|
if ( ! node )
|
||||||
node = this.react;
|
node = this.react;
|
||||||
else if ( node._reactInternalInstance )
|
else if ( node._reactInternalFiber )
|
||||||
node = node._reactInternalInstance;
|
node = node._reactInternalFiber;
|
||||||
else if ( node instanceof Node )
|
else if ( node instanceof Node )
|
||||||
node = this.getReactInstance(node);
|
node = this.getReactInstance(node);
|
||||||
|
|
||||||
if ( ! node || ! this._waiting.length )
|
if ( ! node || ! this._live_waiting.length )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const data = this.searchAll(node, this._waiting_crit, 1000);
|
const data = this.searchAll(node, this._waiting_crit, 1000);
|
||||||
|
@ -300,26 +323,27 @@ export default class Fine extends Module {
|
||||||
while(i-- > 0) {
|
while(i-- > 0) {
|
||||||
if ( data[i].cls ) {
|
if ( data[i].cls ) {
|
||||||
const d = data[i],
|
const d = data[i],
|
||||||
w = this._waiting.splice(i, 1)[0];
|
w = this._live_waiting.splice(i, 1)[0];
|
||||||
|
|
||||||
this._waiting_crit.splice(i, 1);
|
this._waiting_crit.splice(i, 1);
|
||||||
this.log.info(`Found class for "${w.name}" at depth ${d.depth}`, d);
|
|
||||||
|
|
||||||
|
const idx = this._waiting.indexOf(w);
|
||||||
|
if ( idx !== -1 )
|
||||||
|
this._waiting.splice(idx, 1);
|
||||||
|
|
||||||
|
this.log.info(`Found class for "${w.name}" at depth ${d.depth}`, d);
|
||||||
w._set(d.cls, d.instances);
|
w._set(d.cls, d.instances);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! this._waiting.length )
|
if ( ! this._live_waiting.length )
|
||||||
this._stopWaiting();
|
this._stopWaiting();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_startWaiting() {
|
_startWaiting() {
|
||||||
this.log.info('Installing MutationObserver.');
|
this.log.info('Installing MutationObserver.');
|
||||||
|
|
||||||
this._waiting = [];
|
|
||||||
this._waiting_crit = [];
|
|
||||||
this._waiting_timer = setInterval(() => this._checkWaiters(), 500);
|
this._waiting_timer = setInterval(() => this._checkWaiters(), 500);
|
||||||
|
|
||||||
if ( ! this._observer )
|
if ( ! this._observer )
|
||||||
|
@ -343,7 +367,7 @@ export default class Fine extends Module {
|
||||||
if ( this._waiting_timer )
|
if ( this._waiting_timer )
|
||||||
clearInterval(this._waiting_timer);
|
clearInterval(this._waiting_timer);
|
||||||
|
|
||||||
this._waiting = null;
|
this._live_waiting = null;
|
||||||
this._waiting_crit = null;
|
this._waiting_crit = null;
|
||||||
this._waiting_timer = null;
|
this._waiting_timer = null;
|
||||||
}
|
}
|
||||||
|
@ -364,7 +388,7 @@ const EVENTS = {
|
||||||
|
|
||||||
|
|
||||||
export class FineWrapper extends EventEmitter {
|
export class FineWrapper extends EventEmitter {
|
||||||
constructor(name, criteria, fine) {
|
constructor(name, criteria, routes, fine) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -372,6 +396,7 @@ export class FineWrapper extends EventEmitter {
|
||||||
this.fine = fine;
|
this.fine = fine;
|
||||||
|
|
||||||
this.instances = new Set;
|
this.instances = new Set;
|
||||||
|
this.routes = routes || [];
|
||||||
|
|
||||||
this._wrapped = new Set;
|
this._wrapped = new Set;
|
||||||
this._class = null;
|
this._class = null;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue