Changed: Add error handlers for the chat controller and chat container React components to, hopefully, stop chat from breaking entirely when React forgets how to DOM.
+
+
4.0.0-beta1.6@5442f1e095968e230f60
Fixed: Stop displaying empty messages with resub notices that don't have a message.
diff --git a/src/sites/twitch-twilight/modules/chat/index.js b/src/sites/twitch-twilight/modules/chat/index.js
index 1818e368..11020cef 100644
--- a/src/sites/twitch-twilight/modules/chat/index.js
+++ b/src/sites/twitch-twilight/modules/chat/index.js
@@ -335,6 +335,22 @@ export default class ChatHook extends Module {
this.ChatController.on('receive-props', this.chatUpdated, this);
this.ChatController.ready((cls, instances) => {
+ const t = this,
+ old_catch = cls.prototype.componentDidCatch;
+ // Try catching errors. With any luck, maybe we can
+ // recover from the error when we re-build?
+ cls.prototype.componentDidCatch = function(err, info) {
+ // Don't log infinitely if stuff gets super screwed up.
+ const errs = this.state.ffz_errors || 0;
+ if ( errs < 100 ) {
+ this.setState({ffz_errors: errs + 1});
+ t.log.info('Error within Chat', err, info, errs);
+ }
+
+ if ( old_catch )
+ return old_catch.call(this, err, info);
+ }
+
for(const inst of instances) {
const service = inst.chatService;
if ( ! service._ffz_was_here )
@@ -357,6 +373,22 @@ export default class ChatHook extends Module {
this.ChatContainer.on('receive-props', this.containerUpdated, this);
this.ChatContainer.ready((cls, instances) => {
+ const t = this,
+ old_catch = cls.prototype.componentDidCatch;
+ // Try catching errors. With any luck, maybe we can
+ // recover from the error when we re-build?
+ cls.prototype.componentDidCatch = function(err, info) {
+ // Don't log infinitely if stuff gets super screwed up.
+ const errs = this.state.ffz_errors || 0;
+ if ( errs < 100 ) {
+ this.setState({ffz_errors: errs + 1});
+ t.log.info('Error within Chat Container', err, info, errs);
+ }
+
+ if ( old_catch )
+ return old_catch.call(this, err, info);
+ }
+
for(const inst of instances)
this.containerMounted(inst);
});
diff --git a/src/sites/twitch-twilight/modules/chat/line.js b/src/sites/twitch-twilight/modules/chat/line.js
index 6970a6c5..134309f3 100644
--- a/src/sites/twitch-twilight/modules/chat/line.js
+++ b/src/sites/twitch-twilight/modules/chat/line.js
@@ -64,7 +64,6 @@ export default class ChatLine extends Module {
props.showTimestamps !== this.props.showTimestamps;
}
-
cls.prototype.render = function() {
const types = t.parent.chat_types || {},
diff --git a/src/sites/twitch-twilight/modules/compat_emote_menu.js b/src/sites/twitch-twilight/modules/compat_emote_menu.js
index 5ce0dd8e..9f0520d4 100644
--- a/src/sites/twitch-twilight/modules/compat_emote_menu.js
+++ b/src/sites/twitch-twilight/modules/compat_emote_menu.js
@@ -6,7 +6,7 @@
// ============================================================================
import Module from 'utilities/module';
-import {has} from 'utilities/object';
+import {has, sleep} from 'utilities/object';
export default class CompatEmoteMenu extends Module {
constructor(...args) {
@@ -18,7 +18,11 @@ export default class CompatEmoteMenu extends Module {
this.inject('chat.emotes');
}
- async onEnable() {
+ onEnable() {
+ this.hookEmoteMenu();
+ }
+
+ async hookEmoteMenu() {
const em = await this.findEmoteMenu();
if ( ! em )
return this.log.info('Emote Menu for Twitch was not found after 60 seconds.');
@@ -65,8 +69,7 @@ export default class CompatEmoteMenu extends Module {
if ( delay >= 60000 )
return null;
- return new Promise(s => {
- setTimeout(() => this.findEmoteMenu(delay + 100).then(s), 100)
- });
+ await sleep(100);
+ return this.findEmoteMenu(delay + 100);
}
}
\ No newline at end of file
diff --git a/src/utilities/object.js b/src/utilities/object.js
index 4a894fe1..a36f787b 100644
--- a/src/utilities/object.js
+++ b/src/utilities/object.js
@@ -7,6 +7,11 @@ export function has(object, key) {
}
+export function sleep(delay) {
+ return new Promise(s => setTimeout(s, delay));
+}
+
+
export function timeout(promise, delay) {
return new Promise((resolve, reject) => {
let resolved = false;