diff --git a/package.json b/package.json index 3daaf7db..0e8d7590 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "frankerfacez", "author": "Dan Salvato LLC", - "version": "4.20.47", + "version": "4.20.48", "description": "FrankerFaceZ is a Twitch enhancement suite.", "license": "Apache-2.0", "scripts": { diff --git a/src/modules/chat/actions/types.jsx b/src/modules/chat/actions/types.jsx index b509da79..ebad2d14 100644 --- a/src/modules/chat/actions/types.jsx +++ b/src/modules/chat/actions/types.jsx @@ -1,5 +1,7 @@ 'use strict'; +import {createElement} from 'utilities/dom'; + // ============================================================================ // Send Reply diff --git a/src/raven.js b/src/raven.js index fb934754..efc60d3f 100644 --- a/src/raven.js +++ b/src/raven.js @@ -168,7 +168,8 @@ export default class RavenLogger extends Module { 'ChunkLoadError', 'SecurityError', 'QuotaExceededError', - 'DataCloneError' + 'DataCloneError', + 'SyntaxError' ], sanitizeKeys: [ /Token$/ @@ -190,6 +191,7 @@ export default class RavenLogger extends Module { return true; }, shouldSendCallback: data => { + debugger; if ( this.settings && ! this.settings.get('reports.error.enable') ) { if ( data.tags && data.tags.example && this.__example_waiter ) { this.__example_waiter(null); @@ -226,6 +228,22 @@ export default class RavenLogger extends Module { if ( data.exception && Array.isArray(data.exception.values) ) data.exception.values = this.rewriteStack(data.exception.values, data); + if ( Array.isArray(data.stacktrace?.frames) ) { + let has_good = false; + for(const frame of data.stacktrace.frames) { + if ( frame.filename ) + frame.filename = fix_url(frame.filename); + + // If a stacktrace is nothing but wrapped/captured/anonymous + // then it's not very useful to us. + if ( frame.function && ! frame.function.includes('captureMessage') && ! frame.function.includes('captureException') && ! frame.function.includes('wrapped') && ! frame.function.includes('') ) + has_good = true; + } + + if ( ! has_good ) + return false; + } + if ( data.culprit ) data.culprit = fix_url(data.culprit); @@ -287,13 +305,16 @@ export default class RavenLogger extends Module { } + rewriteFrames(frames) { // eslint-disable-line class-methods-use-this + for(const frame of frames) + frame.filename = fix_url(frame.filename); + } + + rewriteStack(errors) { // eslint-disable-line class-methods-use-this for(const err of errors) { - if ( ! err || ! err.stacktrace || ! err.stacktrace.frames ) - continue; - - for(const frame of err.stacktrace.frames) - frame.filename = fix_url(frame.filename); + if ( Array.isArray(err?.stacktrace?.frames) ) + this.rewriteFrames(err.stacktrace.frames); } return errors; diff --git a/src/sites/twitch-twilight/modules/channel.jsx b/src/sites/twitch-twilight/modules/channel.jsx index a315638e..2c32066f 100644 --- a/src/sites/twitch-twilight/modules/channel.jsx +++ b/src/sites/twitch-twilight/modules/channel.jsx @@ -197,7 +197,7 @@ export default class Channel extends Module { } removePanelTips(inst) { // eslint-disable-line class-methods-use-this - if ( inst._ffz_tips ) { + if ( inst?._ffz_tips ) { inst._ffz_tips.destroy(); inst._ffz_tips = null; inst._ffz_tip_el = null; diff --git a/src/sites/twitch-twilight/modules/layout.js b/src/sites/twitch-twilight/modules/layout.js index 26bb27c6..ca793934 100644 --- a/src/sites/twitch-twilight/modules/layout.js +++ b/src/sites/twitch-twilight/modules/layout.js @@ -1,5 +1,6 @@ 'use strict'; +import { IS_FIREFOX } from 'src/utilities/constants'; // ============================================================================ // Layout Overrides for Twitch Twilight // ============================================================================ @@ -268,7 +269,7 @@ export default class Layout extends Module { if ( this._resize_timer ) return; - this._resize_timer = setTimeout(() => this._handleResize(), 100); + this._resize_timer = setTimeout(() => this._handleResize(), IS_FIREFOX ? 500 : 100); } _handleResize() { @@ -277,10 +278,13 @@ export default class Layout extends Module { if ( ! this.ResizeDetector.instances.size ) this._needs_resize = true; - else + else { for(const inst of this.ResizeDetector.instances) { inst?.props?.onResize?.(); } + + this.emit('site.player:fix-player'); + } } get is_minimal() { diff --git a/src/sites/twitch-twilight/modules/player.jsx b/src/sites/twitch-twilight/modules/player.jsx index 1c625aa5..7f29ff9f 100644 --- a/src/sites/twitch-twilight/modules/player.jsx +++ b/src/sites/twitch-twilight/modules/player.jsx @@ -516,6 +516,22 @@ export default class Player extends Module { }); } + + repositionPlayer() { + if ( ! this._mover ) { + const el = document.querySelector('.channel-root__player'); + this._mover = this.fine.searchNode( + el, + n => n.memoizedProps?.triggerPlayerReposition, + 50 + ); + } + + if ( this._mover ) + this._mover.memoizedProps.triggerPlayerReposition(); + } + + onEnable() { this.css_tweaks.toggle('player-volume', this.settings.get('player.volume-always-shown')); this.css_tweaks.toggle('player-ext-mouse', !this.settings.get('player.ext-interaction')); @@ -530,7 +546,7 @@ export default class Player extends Module { this.installVisibilityHook(); this.on(':reset', this.resetAllPlayers, this); - //this.on(':fix-player', () => this.PersistentPlayer.forceUpdate(), this); + this.on(':fix-player', this.repositionPlayer, this); const t = this; diff --git a/src/utilities/compat/apollo.js b/src/utilities/compat/apollo.js index 1022ead4..63f48345 100644 --- a/src/utilities/compat/apollo.js +++ b/src/utilities/compat/apollo.js @@ -266,6 +266,9 @@ export default class Apollo extends Module { } apolloPostFlight(response) { + if ( ! response.extensions ) + return; + const operation = response.extensions.operationName, modifiers = this.post_modifiers[operation]; diff --git a/src/utilities/tooltip.js b/src/utilities/tooltip.js index 65f76a5e..6f05a568 100644 --- a/src/utilities/tooltip.js +++ b/src/utilities/tooltip.js @@ -69,7 +69,7 @@ export class Tooltip { this._accessor = `_ffz_tooltip$${last_id++}`; - this._onMouseOut = e => e.target && e.target.dataset.forceOpen !== 'true' && this._exit(e.target); + this._onMouseOut = e => e.target && e.target?.dataset?.forceOpen !== 'true' && this._exit(e.target); if ( this.options.manual ) { // Do nothing~! @@ -164,19 +164,20 @@ export class Tooltip { if ( ! this._shift_af ) this._shift_af = requestAnimationFrame(() => { this._shift_af = null; - for(const el of this.elements) { - const tip = el[this._accessor]; - if ( tip && tip.outer ) { - tip.outer.dataset.shift = this.shift_state; - tip.update(); + if ( this.elements ) + for(const el of this.elements) { + const tip = el[this._accessor]; + if ( tip && tip.outer ) { + tip.outer.dataset.shift = this.shift_state; + tip.update(); + } } - } }); } cleanup() { - if ( this.options.manual ) + if ( this.options.manual || ! this.elements ) return; for(const el of this.elements) {