1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-28 05:15:54 +00:00

4.0.0-rc12.16

Return to version 4.0.0-rc12.16 because Twitch pushed their changes live again. Whee.
This commit is contained in:
SirStendec 2018-08-28 19:13:26 -04:00
parent 513174fad8
commit cf0245204e
7 changed files with 219 additions and 132 deletions

View file

@ -100,7 +100,7 @@ class FrankerFaceZ extends Module {
FrankerFaceZ.Logger = Logger; FrankerFaceZ.Logger = Logger;
const VER = FrankerFaceZ.version_info = { const VER = FrankerFaceZ.version_info = {
major: 4, minor: 0, revision: 0, extra: '-rc12.14', major: 4, minor: 0, revision: 0, extra: '-rc12.16',
commit: __git_commit__, commit: __git_commit__,
build: __webpack_hash__, build: __webpack_hash__,
toString: () => toString: () =>

View file

@ -781,7 +781,8 @@ export default class EmoteMenu extends Module {
observeSoon() { observeSoon() {
requestAnimationFrame(() => { requestAnimationFrame(() => {
this.handleObserve(this.observer.takeRecords()); if ( this.observer )
this.handleObserve(this.observer.takeRecords());
}); });
} }

View file

@ -148,10 +148,21 @@ export default class ChatHook extends Module {
this.inject(EmoteMenu); this.inject(EmoteMenu);
this.inject(TabCompletion); 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( this.ChatController = this.fine.define(
'chat-controller', 'chat-controller',
n => n.chatService, n => n.hostingHandler && n.onRoomStateUpdated,
Twilight.CHAT_ROUTES Twilight.CHAT_ROUTES
); );
@ -161,6 +172,12 @@ export default class ChatHook extends Module {
Twilight.CHAT_ROUTES Twilight.CHAT_ROUTES
); );
this.ChatBufferConnector = this.fine.define(
'chat-buffer-connector',
n => n.clearBufferHandle && n.syncBufferedMessages,
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,
@ -392,6 +409,46 @@ export default class ChatHook extends Module {
this.ChatController.on('unmount', this.chatUmounted, this); this.ChatController.on('unmount', this.chatUmounted, this);
this.ChatController.on('receive-props', this.chatUpdated, 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) => { this.ChatController.ready((cls, instances) => {
const t = this, const t = this,
old_catch = cls.prototype.componentDidCatch, old_catch = cls.prototype.componentDidCatch,
@ -427,25 +484,8 @@ export default class ChatHook extends Module {
return old_render.call(this); 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); this.chatMounted(inst);
}
}); });
@ -500,24 +540,41 @@ export default class ChatHook extends Module {
wrapChatBuffer(cls) { wrapChatBuffer(cls) {
if ( cls.prototype._ffz_was_here )
return;
const t = this, const t = this,
old_consume = cls.prototype.consumeChatEvent; old_mount = cls.prototype.componentDidMount;
cls.prototype._ffz_was_here = true; cls.prototype._ffzInstall = function() {
if ( this._ffz_installed )
return;
if ( old_consume ) this._ffz_installed = true;
cls.prototype.ffzConsumeChatEvent = cls.prototype.consumeChatEvent = function(msg) {
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 ( msg ) { if ( msg ) {
try { try {
const types = t.chat_types || {}; const types = t.chat_types || {};
if ( msg.type === types.Message ) { if ( msg.type === types.Message ) {
const m = t.chat.standardizeMessage(msg), const m = t.chat.standardizeMessage(msg),
cont = this.ffzController; cont = inst._ffz_connector,
let room = m.roomLogin = m.roomLogin ? m.roomLogin : m.channel ? m.channel.slice(1) : cont && cont.props.channelLogin,
room_id = cont && cont.props.channelID; room_id = cont && cont.props.channelID;
let room = m.roomLogin = m.roomLogin ? m.roomLogin : m.channel ? m.channel.slice(1) : cont && cont.props.channelLogin;
if ( ! room && room_id ) { if ( ! room && room_id ) {
const r = t.chat.getRoom(room_id, null, true); const r = t.chat.getRoom(room_id, null, true);
if ( r && r.login ) if ( r && r.login )
@ -536,7 +593,8 @@ export default class ChatHook extends Module {
const event = new FFZEvent({ const event = new FFZEvent({
message: m, message: m,
channel: room channel: room,
channelID: room_id
}); });
t.emit('chat:receive-message', event); t.emit('chat:receive-message', event);
@ -545,7 +603,7 @@ export default class ChatHook extends Module {
} else if ( msg.type === types.Moderation ) { } else if ( msg.type === types.Moderation ) {
const login = msg.userLogin; const login = msg.userLogin;
if ( this.moderatedUsers.has(login) ) if ( inst.moderatedUsers.has(login) )
return; return;
const do_remove = t.chat.context.get('chat.filtering.remove-deleted') === 3, const do_remove = t.chat.context.get('chat.filtering.remove-deleted') === 3,
@ -553,41 +611,80 @@ export default class ChatHook extends Module {
if ( m.event ) if ( m.event )
m = m.event; m = m.event;
if ( m.type === types.Message && m.user && m.user.userLogin === login ) if ( m.type === types.Message ) {
m.deleted = true; 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 ( do_remove ) { if ( do_remove ) {
this.buffer = this.buffer.filter(m => m.type !== types.Message || ! m.user || m.user.userLogin !== login); const len = inst.buffer.length;
this._isDirty = true; inst.buffer = inst.buffer.filter(m => m.type !== types.Message || ! m.user || m.user.userLogin !== login);
this.onBufferUpdate(); if ( len !== inst.buffer.length && ! inst.props.isBackground )
inst.notifySubscribers();
} else } else
this.buffer.forEach(do_update); inst.buffer.forEach(do_update);
this.delayedMessageBuffer.forEach(do_update); inst.delayedMessageBuffer.forEach(do_update);
this.moderatedUsers.add(login); inst.moderatedUsers.add(login);
setTimeout(this.unmoderateUser(login), 1000); setTimeout(inst.unmoderateUser(login), 1000);
return; return;
} else if ( msg.type === types.Clear ) { } else if ( msg.type === types.Clear ) {
if ( t.chat.context.get('chat.filtering.ignore-clear') ) if ( t.chat.context.get('chat.filtering.ignore-clear') )
msg = { msg = {
type: types.Notice, types: types.Notice,
message: t.i18n.t('chat.ignore-clear', 'An attempt to clear chat was ignored.') message: t.i18n.t('chat.ignore-clear', 'An attempt to clear chat was ignored.')
} }
} }
} catch(err) { } catch(err) {
t.log.capture(err, {extra: {msg}}) t.log.error('Error processing chat event.', err);
t.log.capture(err, {extra: {msg}});
} }
} }
return old_consume.call(this, msg); return old_handle.call(inst, 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() { cls.prototype.flushRawMessages = function() {
const out = [], const out = [],
now = Date.now(), now = Date.now(),
@ -611,41 +708,14 @@ export default class ChatHook extends Module {
} }
this.delayedMessageBuffer = out; this.delayedMessageBuffer = out;
if ( changed && ! this.props.isBackground )
if ( changed ) { this.notifySubscribers();
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) { sendMessage(room, message) {
const controller = this.ChatController.first, const service = this.ChatService.first;
service = controller && controller.chatService;
if ( ! service || ! room ) if ( ! service || ! room )
return null; return null;
@ -653,7 +723,7 @@ export default class ChatHook extends Module {
if ( room.startsWith('#') ) if ( room.startsWith('#') )
room = room.slice(1); room = room.slice(1);
if ( room.toLowerCase() !== service.channelLogin.toLowerCase() ) if ( room.toLowerCase() !== service.props.channelLogin.toLowerCase() )
return service.client.sendCommand(room, message); return service.client.sendCommand(room, message);
service.sendMessage(message); service.sendMessage(message);
@ -662,38 +732,10 @@ export default class ChatHook extends Module {
wrapChatService(cls) { wrapChatService(cls) {
const t = this, 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._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() { cls.prototype.ffzGetEmotes = function() {
const emote_map = this.client && this.client.session && this.client.session.emoteMap; const emote_map = this.client && this.client.session && this.client.session.emoteMap;
if ( this._ffz_cached_map === emote_map ) if ( this._ffz_cached_map === emote_map )
@ -733,6 +775,32 @@ 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; const old_chat = this.onChatMessageEvent;
this.onChatMessageEvent = function(e) { this.onChatMessageEvent = function(e) {
if ( e && e.sentByCurrentUser ) { if ( e && e.sentByCurrentUser ) {
@ -812,13 +880,13 @@ export default class ChatHook extends Module {
return old_unhost.call(i, e, _t); return old_unhost.call(i, e, _t);
} }
const old_post = this.postMessage; const old_add = this.addMessage;
this.postMessage = function(e) { this.addMessage = function(e) {
const original = i._wrapped; const original = i._wrapped;
if ( original && ! e._ffz_checked ) if ( original && ! e._ffz_checked )
return i.postMessageToCurrentChannel(original, e); return i.postMessageToCurrentChannel(original, e);
return old_post.call(i, e); return old_add.call(i, e);
} }
this._ffz_init = true; this._ffz_init = true;
@ -835,7 +903,7 @@ export default class ChatHook extends Module {
if ( chan.startsWith('#') ) if ( chan.startsWith('#') )
chan = chan.slice(1); chan = chan.slice(1);
if ( chan !== this.channelLogin.toLowerCase() ) if ( chan !== this.props.channelLogin.toLowerCase() )
return; return;
message.roomLogin = chan; message.roomLogin = chan;
@ -852,7 +920,7 @@ export default class ChatHook extends Module {
message.message = original.message.body; message.message = original.message.body;
} }
this.postMessage(message); this.addMessage(message);
} }
} }
@ -1013,6 +1081,37 @@ 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 // Chat Containers
// ======================================================================== // ========================================================================

View file

@ -4,7 +4,6 @@ query {
nodes { nodes {
profileImageURL(width: 50) profileImageURL(width: 50)
hosting { hosting {
profileImageURL(width: 50)
stream { stream {
createdAt createdAt
} }

View file

@ -7,17 +7,5 @@ query {
} }
} }
} }
followedHosts {
nodes {
profileImageURL(width: 50)
hosting {
profileImageURL(width: 50)
stream {
createdAt
type
}
}
}
}
} }
} }

View file

@ -152,7 +152,7 @@ export default class HostButton extends Module {
} }
hookIntoChatConnection(inst) { hookIntoChatConnection(inst) {
const userLogin = inst.props.userLogin; const userLogin = inst.props.currentUserLogin;
if (this._chat_con) { if (this._chat_con) {
this.joinChannel(userLogin); this.joinChannel(userLogin);
@ -181,7 +181,7 @@ export default class HostButton extends Module {
this.metadata.updateMetadata('host'); this.metadata.updateMetadata('host');
}); });
const chatServiceClient = inst.chatService.client; const chatServiceClient = inst.client;
this._chat_con = chatServiceClient; this._chat_con = chatServiceClient;
if (this.settings.get('metadata.host-button')) if (this.settings.get('metadata.host-button'))
@ -191,13 +191,12 @@ export default class HostButton extends Module {
onEnable() { onEnable() {
this.metadata.updateMetadata('host'); this.metadata.updateMetadata('host');
this.chat.ChatController.ready((cls, instances) => { this.chat.ChatService.ready((cls, instances) => {
for(const inst of instances) { for(const inst of instances)
if (inst && inst.chatService) this.hookIntoChatConnection(inst); this.hookIntoChatConnection(inst);
} })
});
this.chat.ChatController.on('mount', this.hookIntoChatConnection, this); this.chat.ChatService.on('mount', this.hookIntoChatConnection, this);
} }
buildAutoHostMenu(vue, hosts, autoHostSettings, data) { buildAutoHostMenu(vue, hosts, autoHostSettings, data) {

View file

@ -75,10 +75,11 @@ export default class SocketClient extends Module {
// We don't have our own IRC connection yet, so the site's chat has to do. // 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 = this.resolve('site.chat');
const chat = _chat && _chat.currentChat; const chat = _chat && _chat.ChatService.first;
const con = chat.chatService && chat.chatService.client && chat.chatService.client.connection; const con = chat.client && chat.client.connection;
if (con && con.send) con.send(`PRIVMSG #frankerfacezauthorizer :AUTH ${challenge}`); if (con && con.send)
con.send(`PRIVMSG #frankerfacezauthorizer :AUTH ${challenge}`);
}); });