From 513174fad87092501245c3b92b9ee4d2ef55294f Mon Sep 17 00:00:00 2001 From: SirStendec Date: Tue, 28 Aug 2018 09:45:53 -0400 Subject: [PATCH] 4.0.0-rc12.14 Revert to the previous version, 4.0.0-rc12.14, because Twitch rolled back changes to their chat handler. This is probably temporary. --- src/main.js | 2 +- .../modules/chat/emote_menu.jsx | 3 +- .../twitch-twilight/modules/chat/index.js | 311 ++++++------------ .../modules/directory/followed_hosts.gql | 1 + .../modules/directory/followed_index.gql | 12 + .../twitch-twilight/modules/host_button.js | 15 +- src/socket.js | 7 +- 7 files changed, 132 insertions(+), 219 deletions(-) diff --git a/src/main.js b/src/main.js index a77daaf0..520d8836 100644 --- a/src/main.js +++ b/src/main.js @@ -100,7 +100,7 @@ class FrankerFaceZ extends Module { FrankerFaceZ.Logger = Logger; const VER = FrankerFaceZ.version_info = { - major: 4, minor: 0, revision: 0, extra: '-rc12.16', + major: 4, minor: 0, revision: 0, extra: '-rc12.14', commit: __git_commit__, build: __webpack_hash__, toString: () => diff --git a/src/sites/twitch-twilight/modules/chat/emote_menu.jsx b/src/sites/twitch-twilight/modules/chat/emote_menu.jsx index ccf0b487..5dbd37bd 100644 --- a/src/sites/twitch-twilight/modules/chat/emote_menu.jsx +++ b/src/sites/twitch-twilight/modules/chat/emote_menu.jsx @@ -781,8 +781,7 @@ export default class EmoteMenu extends Module { observeSoon() { requestAnimationFrame(() => { - if ( this.observer ) - this.handleObserve(this.observer.takeRecords()); + this.handleObserve(this.observer.takeRecords()); }); } diff --git a/src/sites/twitch-twilight/modules/chat/index.js b/src/sites/twitch-twilight/modules/chat/index.js index 6e9cd147..c08fc861 100644 --- a/src/sites/twitch-twilight/modules/chat/index.js +++ b/src/sites/twitch-twilight/modules/chat/index.js @@ -148,21 +148,10 @@ export default class ChatHook extends Module { this.inject(EmoteMenu); this.inject(TabCompletion); - this.ChatService = this.fine.define( - 'chat-service', - n => n.join && n.part && n.connectHandlers, - Twilight.CHAT_ROUTES - ); - - this.ChatBuffer = this.fine.define( - 'chat-buffer', - n => n.updateHandlers && n.delayedMessageBuffer && n.handleMessage, - Twilight.CHAT_ROUTES - ); this.ChatController = this.fine.define( 'chat-controller', - n => n.hostingHandler && n.onRoomStateUpdated, + n => n.chatService, Twilight.CHAT_ROUTES ); @@ -172,12 +161,6 @@ export default class ChatHook extends Module { Twilight.CHAT_ROUTES ); - this.ChatBufferConnector = this.fine.define( - 'chat-buffer-connector', - n => n.clearBufferHandle && n.syncBufferedMessages, - Twilight.CHAT_ROUTES - ); - this.PinnedCheer = this.fine.define( 'pinned-cheer', n => n.collapseCheer && n.saveRenderedMessageRef, @@ -409,46 +392,6 @@ export default class ChatHook extends Module { this.ChatController.on('unmount', this.chatUmounted, this); this.ChatController.on('receive-props', this.chatUpdated, this); - this.ChatService.ready((cls, instances) => { - this.wrapChatService(cls); - - for(const inst of instances) { - inst.client.events.removeAll(); - inst.connectHandlers(); - } - }); - - this.ChatBuffer.ready((cls, instances) => { - this.wrapChatBuffer(cls); - - for(const inst of instances) { - const handler = inst.props.messageHandlerAPI; - if ( handler ) - handler.removeMessageHandler(inst.handleMessage); - - inst._ffzInstall(); - - if ( handler ) - handler.addMessageHandler(inst.handleMessage); - - inst.props.setMessageBufferAPI({ - addUpdateHandler: inst.addUpdateHandler, - removeUpdateHandler: inst.removeUpdateHandler, - getMessages: inst.getMessages, - _ffz_inst: inst - }); - } - }); - - this.ChatBufferConnector.on('mount', this.connectorMounted, this); - this.ChatBufferConnector.on('receive-props', this.connectorUpdated, this); - this.ChatBufferConnector.on('unmount', this.connectorUnmounted, this); - - this.ChatBufferConnector.ready((cls, instances) => { - for(const inst of instances) - this.connectorMounted(inst); - }) - this.ChatController.ready((cls, instances) => { const t = this, old_catch = cls.prototype.componentDidCatch, @@ -484,8 +427,25 @@ export default class ChatHook extends Module { return old_render.call(this); } - for(const inst of instances) + for(const inst of instances) { + const service = inst.chatService; + if ( ! service._ffz_was_here ) + this.wrapChatService(service.constructor); + + const buffer = inst.chatBuffer; + if ( ! buffer._ffz_was_here ) + this.wrapChatBuffer(buffer.constructor); + + if ( buffer.ffzConsumeChatEvent ) + buffer.consumeChatEvent = buffer.ffzConsumeChatEvent.bind(buffer); + + buffer.ffzController = inst; + + service.client.events.removeAll(); + service.connectHandlers(); + this.chatMounted(inst); + } }); @@ -540,40 +500,23 @@ export default class ChatHook extends Module { wrapChatBuffer(cls) { - if ( cls.prototype._ffz_was_here ) - return; - const t = this, - old_mount = cls.prototype.componentDidMount; + old_consume = cls.prototype.consumeChatEvent; - cls.prototype._ffzInstall = function() { - if ( this._ffz_installed ) - return; + cls.prototype._ffz_was_here = true; - this._ffz_installed = true; - - const inst = this, - old_handle = inst.handleMessage, - old_set = inst.props.setMessageBufferAPI; - - inst.props.setMessageBufferAPI = function(api) { - if ( api ) - api._ffz_inst = inst; - - return old_set(api); - } - - inst.handleMessage = function(msg) { + if ( old_consume ) + cls.prototype.ffzConsumeChatEvent = cls.prototype.consumeChatEvent = function(msg) { if ( msg ) { try { const types = t.chat_types || {}; if ( msg.type === types.Message ) { const m = t.chat.standardizeMessage(msg), - cont = inst._ffz_connector, - room_id = cont && cont.props.channelID; + cont = this.ffzController; - let room = m.roomLogin = m.roomLogin ? m.roomLogin : m.channel ? m.channel.slice(1) : cont && cont.props.channelLogin; + let room = m.roomLogin = m.roomLogin ? m.roomLogin : m.channel ? m.channel.slice(1) : cont && cont.props.channelLogin, + room_id = cont && cont.props.channelID; if ( ! room && room_id ) { const r = t.chat.getRoom(room_id, null, true); @@ -593,8 +536,7 @@ export default class ChatHook extends Module { const event = new FFZEvent({ message: m, - channel: room, - channelID: room_id + channel: room }); t.emit('chat:receive-message', event); @@ -603,7 +545,7 @@ export default class ChatHook extends Module { } else if ( msg.type === types.Moderation ) { const login = msg.userLogin; - if ( inst.moderatedUsers.has(login) ) + if ( this.moderatedUsers.has(login) ) return; const do_remove = t.chat.context.get('chat.filtering.remove-deleted') === 3, @@ -611,80 +553,41 @@ export default class ChatHook extends Module { if ( m.event ) m = m.event; - if ( m.type === types.Message ) { - if ( m.user && m.user.userLogin === login ) - m.deleted = true; - } else if ( m.type === types.Resubscription || m.type === types.Ritual ) { - if ( m.message && m.message.user && m.message.user.userLogin === login ) - m.deleted = true; - } + if ( m.type === types.Message && m.user && m.user.userLogin === login ) + m.deleted = true; }; if ( do_remove ) { - const len = inst.buffer.length; - inst.buffer = inst.buffer.filter(m => m.type !== types.Message || ! m.user || m.user.userLogin !== login); - if ( len !== inst.buffer.length && ! inst.props.isBackground ) - inst.notifySubscribers(); + this.buffer = this.buffer.filter(m => m.type !== types.Message || ! m.user || m.user.userLogin !== login); + this._isDirty = true; + this.onBufferUpdate(); } else - inst.buffer.forEach(do_update); + this.buffer.forEach(do_update); - inst.delayedMessageBuffer.forEach(do_update); + this.delayedMessageBuffer.forEach(do_update); - inst.moderatedUsers.add(login); - setTimeout(inst.unmoderateUser(login), 1000); + this.moderatedUsers.add(login); + setTimeout(this.unmoderateUser(login), 1000); return; } else if ( msg.type === types.Clear ) { if ( t.chat.context.get('chat.filtering.ignore-clear') ) msg = { - types: types.Notice, + type: types.Notice, message: t.i18n.t('chat.ignore-clear', 'An attempt to clear chat was ignored.') } + } } catch(err) { - t.log.error('Error processing chat event.', err); - t.log.capture(err, {extra: {msg}}); + t.log.capture(err, {extra: {msg}}) } } - return old_handle.call(inst, msg); + return old_consume.call(this, msg); } - inst.getMessages = function() { - const buf = inst.buffer, - size = t.chat.context.get('chat.scrollback-length'), - ct = t.chat_types || CHAT_TYPES, - target = buf.length - size; - - if ( target > 0 ) { - let removed = 0, last; - for(let i=0; i < target; i++) - if ( buf[i] && ! NULL_TYPES.includes(ct[buf[i].type]) ) { - removed++; - last = i; - } - - inst.buffer = buf.slice(removed % 2 === 0 ? target : Math.max(target - 10, last)); - } else - // Make a shallow copy of the array because other code expects it to change. - inst.buffer = buf.slice(0); - - return inst.buffer; - } - } - - cls.prototype.componentDidMount = function() { - try { - this._ffzInstall(); - } catch(err) { - t.log.error('Error installing FFZ features onto chat buffer.', err); - } - - return old_mount.call(this); - } - cls.prototype.flushRawMessages = function() { const out = [], now = Date.now(), @@ -708,14 +611,41 @@ export default class ChatHook extends Module { } this.delayedMessageBuffer = out; - if ( changed && ! this.props.isBackground ) - this.notifySubscribers(); + + if ( changed ) { + this._isDirty = true; + this.onBufferUpdate(); + } + } + + cls.prototype.toArray = function() { + const buf = this.buffer, + size = t.chat.context.get('chat.scrollback-length'), + ct = t.chat_types || CHAT_TYPES, + target = buf.length - size; + + if ( target > 0 ) { + let removed = 0, last; + for(let i=0; i < target; i++) + if ( buf[i] && ! NULL_TYPES.includes(ct[buf[i].type]) ) { + removed++; + last = i; + } + + this.buffer = buf.slice(removed % 2 === 0 ? target : Math.max(target - 10, last)); + } else + // Make a shallow copy of the array because other code expects it to change. + this.buffer = buf.slice(0); + + this._isDirty = false; + return this.buffer; } } sendMessage(room, message) { - const service = this.ChatService.first; + const controller = this.ChatController.first, + service = controller && controller.chatService; if ( ! service || ! room ) return null; @@ -723,7 +653,7 @@ export default class ChatHook extends Module { if ( room.startsWith('#') ) room = room.slice(1); - if ( room.toLowerCase() !== service.props.channelLogin.toLowerCase() ) + if ( room.toLowerCase() !== service.channelLogin.toLowerCase() ) return service.client.sendCommand(room, message); service.sendMessage(message); @@ -732,10 +662,38 @@ export default class ChatHook extends Module { wrapChatService(cls) { const t = this, - old_handler = cls.prototype.connectHandlers; + old_handler = cls.prototype.connectHandlers, + old_send = cls.prototype.sendMessage; cls.prototype._ffz_was_here = true; + + cls.prototype.sendMessage = function(raw_msg) { + const msg = raw_msg.replace(/\n/g, ''); + + if ( msg.startsWith('/ffz') ) { + this.postMessage({ + type: t.chat_types.Notice, + message: 'The /ffz command is not yet re-implemented.' + }) + + return false; + } + + const event = new FFZEvent({ + message: msg, + channel: this.channelLogin + }); + + t.emit('chat:pre-send-message', event); + + if ( event.defaultPrevented ) + return; + + return old_send.call(this, msg); + } + + cls.prototype.ffzGetEmotes = function() { const emote_map = this.client && this.client.session && this.client.session.emoteMap; if ( this._ffz_cached_map === emote_map ) @@ -775,32 +733,6 @@ export default class ChatHook extends Module { } } - const old_send = this.sendMessage; - this.sendMessage = function(raw_msg) { - const msg = raw_msg.replace(/\n/g, ''); - - if ( msg.startsWith('/ffz') ) { - this.postMessage({ - type: t.chat_types.Notice, - message: 'The /ffz command is not yet re-implemented.' - }) - - return false; - } - - const event = new FFZEvent({ - message: msg, - channel: this.channelLogin - }); - - t.emit('chat:pre-send-message', event); - - if ( event.defaultPrevented ) - return; - - return old_send.call(this, msg); - } - const old_chat = this.onChatMessageEvent; this.onChatMessageEvent = function(e) { if ( e && e.sentByCurrentUser ) { @@ -880,13 +812,13 @@ export default class ChatHook extends Module { return old_unhost.call(i, e, _t); } - const old_add = this.addMessage; - this.addMessage = function(e) { + const old_post = this.postMessage; + this.postMessage = function(e) { const original = i._wrapped; if ( original && ! e._ffz_checked ) return i.postMessageToCurrentChannel(original, e); - return old_add.call(i, e); + return old_post.call(i, e); } this._ffz_init = true; @@ -903,7 +835,7 @@ export default class ChatHook extends Module { if ( chan.startsWith('#') ) chan = chan.slice(1); - if ( chan !== this.props.channelLogin.toLowerCase() ) + if ( chan !== this.channelLogin.toLowerCase() ) return; message.roomLogin = chan; @@ -920,7 +852,7 @@ export default class ChatHook extends Module { message.message = original.message.body; } - this.addMessage(message); + this.postMessage(message); } } @@ -1081,37 +1013,6 @@ export default class ChatHook extends Module { } - // ======================================================================== - // Chat Buffer Connector - // ======================================================================== - - connectorMounted(inst) { // eslint-disable-line class-methods-use-this - const buffer = inst.props.messageBufferAPI; - if ( buffer && buffer._ffz_inst && buffer._ffz_inst._ffz_connector !== inst ) - buffer._ffz_inst._ffz_connector = inst; - } - - connectorUpdated(inst, props) { // eslint-disable-line class-methods-use-this - const buffer = inst.props.messageBufferAPI, - new_buffer = props.messageBufferAPI; - - if ( buffer === new_buffer ) - return; - - if ( buffer && buffer._ffz_inst && buffer._ffz_inst._ffz_connector === inst ) - buffer._ffz_inst._ffz_connector = null; - - if ( new_buffer && new_buffer._ffz_inst && new_buffer._ffz_inst._ffz_connector !== inst ) - buffer._ffz_inst._ffz_connector = inst; - } - - connectorUnmounted(inst) { // eslint-disable-line class-methods-use-this - const buffer = inst.props.messageBufferAPI; - if ( buffer && buffer._ffz_inst && buffer._ffz_inst._ffz_connector === inst ) - buffer._ffz_inst._ffz_connector = null; - } - - // ======================================================================== // Chat Containers // ======================================================================== diff --git a/src/sites/twitch-twilight/modules/directory/followed_hosts.gql b/src/sites/twitch-twilight/modules/directory/followed_hosts.gql index e6c12ffd..0bd303b1 100644 --- a/src/sites/twitch-twilight/modules/directory/followed_hosts.gql +++ b/src/sites/twitch-twilight/modules/directory/followed_hosts.gql @@ -4,6 +4,7 @@ query { nodes { profileImageURL(width: 50) hosting { + profileImageURL(width: 50) stream { createdAt } diff --git a/src/sites/twitch-twilight/modules/directory/followed_index.gql b/src/sites/twitch-twilight/modules/directory/followed_index.gql index 0dd90430..ef13ca6b 100644 --- a/src/sites/twitch-twilight/modules/directory/followed_index.gql +++ b/src/sites/twitch-twilight/modules/directory/followed_index.gql @@ -7,5 +7,17 @@ query { } } } + followedHosts { + nodes { + profileImageURL(width: 50) + hosting { + profileImageURL(width: 50) + stream { + createdAt + type + } + } + } + } } } \ No newline at end of file diff --git a/src/sites/twitch-twilight/modules/host_button.js b/src/sites/twitch-twilight/modules/host_button.js index 01d92357..c50970c3 100644 --- a/src/sites/twitch-twilight/modules/host_button.js +++ b/src/sites/twitch-twilight/modules/host_button.js @@ -152,7 +152,7 @@ export default class HostButton extends Module { } hookIntoChatConnection(inst) { - const userLogin = inst.props.currentUserLogin; + const userLogin = inst.props.userLogin; if (this._chat_con) { this.joinChannel(userLogin); @@ -181,7 +181,7 @@ export default class HostButton extends Module { this.metadata.updateMetadata('host'); }); - const chatServiceClient = inst.client; + const chatServiceClient = inst.chatService.client; this._chat_con = chatServiceClient; if (this.settings.get('metadata.host-button')) @@ -191,12 +191,13 @@ export default class HostButton extends Module { onEnable() { this.metadata.updateMetadata('host'); - this.chat.ChatService.ready((cls, instances) => { - for(const inst of instances) - this.hookIntoChatConnection(inst); - }) + this.chat.ChatController.ready((cls, instances) => { + for(const inst of instances) { + if (inst && inst.chatService) this.hookIntoChatConnection(inst); + } + }); - this.chat.ChatService.on('mount', this.hookIntoChatConnection, this); + this.chat.ChatController.on('mount', this.hookIntoChatConnection, this); } buildAutoHostMenu(vue, hosts, autoHostSettings, data) { diff --git a/src/socket.js b/src/socket.js index 6b0fcebe..f34e8656 100644 --- a/src/socket.js +++ b/src/socket.js @@ -75,11 +75,10 @@ export default class SocketClient extends Module { // We don't have our own IRC connection yet, so the site's chat has to do. const _chat = this.resolve('site.chat'); - const chat = _chat && _chat.ChatService.first; - const con = chat.client && chat.client.connection; + const chat = _chat && _chat.currentChat; + const con = chat.chatService && chat.chatService.client && chat.chatService.client.connection; - if (con && con.send) - con.send(`PRIVMSG #frankerfacezauthorizer :AUTH ${challenge}`); + if (con && con.send) con.send(`PRIVMSG #frankerfacezauthorizer :AUTH ${challenge}`); });