diff --git a/package.json b/package.json index 8bc3e3e1..b9d4512c 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "frankerfacez", "author": "Dan Salvato LLC", - "version": "4.38.0", + "version": "4.38.1", "description": "FrankerFaceZ is a Twitch enhancement suite.", "private": true, "license": "Apache-2.0", diff --git a/src/modules/chat/actions/index.jsx b/src/modules/chat/actions/index.jsx index 9497e487..b8ac95e1 100644 --- a/src/modules/chat/actions/index.jsx +++ b/src/modules/chat/actions/index.jsx @@ -658,16 +658,17 @@ export default class Actions extends Module { const u = site.getUser(), r = {id: line.props.channelID, login: room}; - const has_replies = line.chatRepliesTreatment ? line.chatRepliesTreatment !== 'control' : false, - can_replies = has_replies && ! msg.deleted && ! line.props.disableReplyClick, - can_reply = can_replies && u.login !== msg.user?.login && ! msg.reply; + const has_replies = !!(line.props.hasReply || line.props.reply || ! line.props.replyRestrictedReason), + can_replies = has_replies && msg.message && ! msg.deleted && ! line.props.disableReplyClick, + can_reply = can_replies && (has_replies || (u && u.login !== msg.user?.login)); msg.roomId = r.id; if ( u ) { u.moderator = line.props.isCurrentUserModerator; u.staff = line.props.isCurrentUserStaff; - u.can_reply = this.parent.context.get('chat.replies.style') === 2 && can_reply; + u.reply_mode = this.parent.context.get('chat.replies.style'), + u.can_reply = can_reply; } const current_level = this.getUserLevel(r, u), @@ -726,17 +727,17 @@ export default class Actions extends Module { (disp.deleted != null && disp.deleted !== !!msg.deleted) ) continue; - if ( maybe_call(act.hidden, this, data, msg, r, u, mod_icons) ) + if ( maybe_call(act.hidden, this, data, msg, r, u, mod_icons, chat_line) ) continue; if ( ap.type === 'dynamic' ) { - const out = act.dynamicAppearance && act.dynamicAppearance.call(this, Object.assign({}, ap), data, msg, r, u, mod_icons); + const out = act.dynamicAppearance && act.dynamicAppearance.call(this, Object.assign({}, ap), data, msg, r, u, mod_icons, chat_line); if ( out ) ap = out; } if ( act.override_appearance ) { - const out = act.override_appearance.call(this, Object.assign({}, ap), data, msg, r, u, mod_icons); + const out = act.override_appearance.call(this, Object.assign({}, ap), data, msg, r, u, mod_icons, chat_line); if ( out ) ap = out; } @@ -746,7 +747,7 @@ export default class Actions extends Module { continue; const has_color = def.colored && ap.color, - disabled = maybe_call(act.disabled, this, data, msg, r, u, mod_icons) || false, + disabled = maybe_call(act.disabled, this, data, msg, r, u, mod_icons, chat_line) || false, color = has_color && (chat && chat.colors ? chat.colors.process(ap.color) : ap.color), contents = def.render.call(this, ap, createElement, color); diff --git a/src/modules/main_menu/components/action-editor.vue b/src/modules/main_menu/components/action-editor.vue index c032782d..3f27334b 100644 --- a/src/modules/main_menu/components/action-editor.vue +++ b/src/modules/main_menu/components/action-editor.vue @@ -557,6 +557,9 @@ export default { if ( this.action.t === 'inherit' ) return this.t('setting.inheritance', 'Inheritance Point'); + if ( this.action.t === 'skip' ) + return this.t('setting.inheritance.skip', 'Not Inheriting'); + else if ( ! this.display ) return this.t('setting.unknown', 'Unknown Value'); @@ -590,7 +593,10 @@ export default { description() { if ( this.action.t === 'inherit' ) - return this.t('setting.inheritance.desc', 'Inherit values from lower priority profiles at this position.'); + return this.t('setting.inheritance.desc', 'Inherit values from lower priority profiles or the default values at this position.'); + + if ( this.action.t === 'skip' ) + return this.t('setting.inheritance.skip.desc', 'This profile does not inherit values from lower priority profiles or the default values, despite having no values of its own.'); const type = this.display && this.display.type; diff --git a/src/modules/main_menu/components/chat-actions.vue b/src/modules/main_menu/components/chat-actions.vue index 82e087e1..56c48475 100644 --- a/src/modules/main_menu/components/chat-actions.vue +++ b/src/modules/main_menu/components/chat-actions.vue @@ -305,7 +305,7 @@ +
x.t !== 'skip'); + }, + val() { if ( ! this.has_value ) return []; @@ -664,8 +690,28 @@ export default { this.set(deep_copy(this.default_value)); }, + addSkip() { + const vals = Array.from(this.val); + if(vals.length > 0) + return; + + vals.push({ + t: 'skip' + }); + + this.set(deep_copy(vals)); + }, + add(val) { const vals = Array.from(this.val); + + // Remove any skip entry. + let i = vals.length; + while(i--) { + if (vals[i]?.t === 'skip') + vals.splice(i, 1); + } + vals.push(val); this.set(deep_copy(vals)); this.add_open = false; diff --git a/src/modules/main_menu/components/filter-editor.vue b/src/modules/main_menu/components/filter-editor.vue index f16ecb20..e8018721 100644 --- a/src/modules/main_menu/components/filter-editor.vue +++ b/src/modules/main_menu/components/filter-editor.vue @@ -80,6 +80,7 @@ export default { data() { return { adding: false, + resetting: false, editing: this.copyValue() } }, @@ -91,9 +92,16 @@ export default { }, watch: { + value() { + this.resetting = true; + this.editing = this.copyValue(); + }, + editing: { handler() { - this.$emit('input', this.editing) + if (!this.resetting) + this.$emit('input', this.editing) + this.resetting = false; }, deep: true } diff --git a/src/modules/main_menu/components/filter-rule-editor.vue b/src/modules/main_menu/components/filter-rule-editor.vue index 2e60acb1..cac4bf61 100644 --- a/src/modules/main_menu/components/filter-rule-editor.vue +++ b/src/modules/main_menu/components/filter-rule-editor.vue @@ -45,23 +45,23 @@ @@ -31,26 +85,42 @@ export default { data() { return { filters: this.item.data(), + maybe_clear: false, test_context: this.item.test_context ? this.item.test_context() : {}, }; }, computed: { + has_default() { + return this.default_value && this.default_value.length + }, + preview() { return this.item.preview || false }, rules() { - if ( ! Array.isArray(this.value) || this.value.length <= 0 ) + if ( ! this.has_value || ! Array.isArray(this.value) ) return []; - return this.value.filter(x => x.v).map(x => x.v); + return this.value.filter(x => x?.v).map(x => x.v); } }, methods: { + doClear() { + this.maybe_clear = false; + this.clear(); + }, + + populate() { + this.set(deep_copy(this.default_value)); + }, + onInput(data) { - const val = deep_copy(data); + const val = deep_copy(data).map(x => ({v: x})); + if (val.length == 0) + val.push({t: 'skip'}); this.set(val); } } diff --git a/src/settings/types.js b/src/settings/types.js index dfed0291..ceef27c5 100644 --- a/src/settings/types.js +++ b/src/settings/types.js @@ -75,7 +75,7 @@ export const array_merge = { default(val) { const values = []; for(const v of val) - if ( v.t !== 'inherit' && v.v ) + if ( v.t !== 'inherit' && v.t !== 'skip' && v.v ) values.push(v.v); return values; @@ -119,6 +119,8 @@ export const array_merge = { had_value = true; if ( val.t === 'inherit' ) is_trailing = true; + else if ( val.t === 'skip' ) + continue; else if ( is_trailing ) trail.push(val.v); else diff --git a/src/sites/twitch-twilight/modules/chat/scroller.js b/src/sites/twitch-twilight/modules/chat/scroller.js index 90a55b83..934716b7 100644 --- a/src/sites/twitch-twilight/modules/chat/scroller.js +++ b/src/sites/twitch-twilight/modules/chat/scroller.js @@ -684,6 +684,16 @@ export default class Scroller extends Module { this.off('tooltips:mousemove', inst.ffzTooltipHover, inst); this.off('tooltips:leave', inst.ffzTooltipLeave, inst); + if ( inst._ffz_hover_timer ) { + clearInterval(inst._ffz_hover_timer); + inst._ffz_hover_timer = null; + } + + if ( inst._ffz_outside_timer ) { + clearTimeout(inst._ffz_outside_timer); + inst._ffz_outside_timer = null; + } + window.removeEventListener('keydown', inst.ffzHandleKey); window.removeEventListener('keyup', inst.ffzHandleKey); }