mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-27 21:05:53 +00:00
4.38.1
* Fixed: Certain chat actions (Pin, Reply) not working correctly when assigned as a User Context action. * Fixed: When editing a setting using the filter editor, settings are saved correctly. * Changed: When editing chat actions, you can now choose to have a profile not inherit values from other profiles or the default values.
This commit is contained in:
parent
92ff27f3fb
commit
1914b055ce
9 changed files with 168 additions and 25 deletions
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -305,7 +305,7 @@
|
|||
</balloon>
|
||||
</div>
|
||||
<button
|
||||
v-if="! maybe_clear && val.length"
|
||||
v-if="! maybe_clear && strip_skip_val.length"
|
||||
class="tw-mg-l-1 tw-button tw-button--text ffz-il-tooltip__container"
|
||||
@click="maybe_clear = true"
|
||||
>
|
||||
|
@ -338,7 +338,7 @@
|
|||
</span>
|
||||
</button>
|
||||
<button
|
||||
v-if="! val.length && has_default"
|
||||
v-if="! strip_skip_val.length && has_default"
|
||||
class="tw-mg-l-1 tw-button tw-button--text ffz-il-tooltip__container"
|
||||
@click="populate"
|
||||
>
|
||||
|
@ -354,6 +354,20 @@
|
|||
<div ref="list" class="ffz--action-list">
|
||||
<div v-if="! val.length" class="tw-c-text-alt-2 tw-font-size-4 tw-align-center tw-c-text-alt-2 tw-pd-1">
|
||||
{{ t('setting.actions.no-actions', 'no actions are defined in this profile') }}
|
||||
|
||||
<div class="tw-mg-t-1">
|
||||
<button
|
||||
class="tw-button tw-button--text ffz-il-tooltip__container"
|
||||
@click="addSkip"
|
||||
>
|
||||
<span class="tw-button__text ffz-i-block">
|
||||
{{ t('setting.actions.do-not-inherit', 'Do Not Inherit') }}
|
||||
</span>
|
||||
<span class="ffz-il-tooltip ffz-il-tooltip--down ffz-il-tooltip--align-center">
|
||||
{{ t('setting.actions.do-not-inherit.desc', 'Do not inherit values from lower priority profiles or the defaults.') }}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<section v-for="act in val" :key="act.id">
|
||||
<action-editor
|
||||
|
@ -416,6 +430,14 @@ export default {
|
|||
return false;
|
||||
},
|
||||
|
||||
hasSkip() {
|
||||
for(const val of this.val)
|
||||
if ( val.t === 'skip' )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
sample_user() {
|
||||
return this.has_user ? {
|
||||
displayName: 'SirStendec',
|
||||
|
@ -567,6 +589,10 @@ export default {
|
|||
return out;
|
||||
},
|
||||
|
||||
strip_skip_val() {
|
||||
return this.val.filter(x => 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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -45,23 +45,23 @@
|
|||
</div>
|
||||
|
||||
<template v-if="deleting">
|
||||
<button class="tw-button tw-button--text tw-relative ffz-il-tooltip__container" @click="$emit('delete')">
|
||||
<span class="tw-button__text ffz-i-trash" />
|
||||
<div class="ffz-il-tooltip ffz-il-tooltip--down ffz-il-tooltip--align-right">
|
||||
{{ t('setting.delete', 'Delete') }}
|
||||
</div>
|
||||
</button>
|
||||
<button class="tw-button tw-button--text tw-relative ffz-il-tooltip__container" @click="deleting = false">
|
||||
<span class="tw-button__text ffz-i-cancel" />
|
||||
<div class="ffz-il-tooltip ffz-il-tooltip--down ffz-il-tooltip--align-right">
|
||||
<div class="ffz-il-tooltip ffz-il-tooltip--up ffz-il-tooltip--align-right">
|
||||
{{ t('setting.cancel', 'Cancel') }}
|
||||
</div>
|
||||
</button>
|
||||
<button class="tw-button tw-button--text tw-relative ffz-il-tooltip__container" @click="$emit('delete')">
|
||||
<span class="tw-button__text ffz-i-trash" />
|
||||
<div class="ffz-il-tooltip ffz-il-tooltip--up ffz-il-tooltip--align-right">
|
||||
{{ t('setting.delete', 'Delete') }}
|
||||
</div>
|
||||
</button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<button class="tw-button tw-button--text tw-relative ffz-il-tooltip__container" @click="deleting = true">
|
||||
<span class="tw-button__text ffz-i-trash" />
|
||||
<div class="ffz-il-tooltip ffz-il-tooltip--down ffz-il-tooltip--align-right">
|
||||
<div class="ffz-il-tooltip ffz-il-tooltip--up ffz-il-tooltip--align-right">
|
||||
{{ t('setting.delete', 'Delete') }}
|
||||
</div>
|
||||
</button>
|
||||
|
|
|
@ -8,6 +8,59 @@
|
|||
{{ t('setting.warn-inheritence', 'These values are being overridden by another profile and may not take effect.') }}
|
||||
</div>
|
||||
|
||||
<div class="tw-flex tw-align-items-center tw-pd-b-05">
|
||||
<div class="tw-flex-grow-1">
|
||||
{{ t('setting.filter.drag', 'Drag entries to re-order them.') }}
|
||||
</div>
|
||||
|
||||
<button
|
||||
v-if="! maybe_clear && rules.length"
|
||||
class="tw-mg-l-1 tw-button tw-button--text ffz-il-tooltip__container"
|
||||
@click="maybe_clear = true"
|
||||
>
|
||||
<span class="tw-button__text ffz-i-trash">
|
||||
{{ t('setting.delete-all', 'Delete All') }}
|
||||
</span>
|
||||
<span class="ffz-il-tooltip ffz-il-tooltip--down ffz-il-tooltip--align-right">
|
||||
{{ t('setting.filter.delete-all', "Delete all of this profile's entries.") }}
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
v-if="maybe_clear"
|
||||
class="tw-mg-l-1 tw-button tw-button--text ffz-il-tooltip__container"
|
||||
@click="doClear"
|
||||
>
|
||||
<span class="tw-button__text ffz-i-trash">
|
||||
{{ t('setting.delete-all', 'Delete All') }}
|
||||
</span>
|
||||
<span class="ffz-il-tooltip ffz-il-tooltip--down ffz-il-tooltip--align-right">
|
||||
{{ t('setting.filter.delete-all', "Delete all of this profile's entries.") }}
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
v-if="maybe_clear"
|
||||
class="tw-mg-l-1 tw-button tw-button--text ffz-il-tooltip__container"
|
||||
@click="maybe_clear = false"
|
||||
>
|
||||
<span class="tw-button__text ffz-i-cancel">
|
||||
{{ t('setting.cancel', 'Cancel') }}
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
v-if="! rules.length && has_default"
|
||||
class="tw-mg-l-1 tw-button tw-button--text ffz-il-tooltip__container"
|
||||
@click="populate"
|
||||
>
|
||||
<span class="tw-button__text ffz-i-trash">
|
||||
{{ t('setting.filter.add-default', 'Add Defaults') }}
|
||||
</span>
|
||||
<span class="ffz-il-tooltip ffz-il-tooltip--down ffz-il-tooltip--align-right">
|
||||
{{ t('setting.filter.add-default-tip', 'Add all of the default values to this profile.') }}
|
||||
</span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
<filter-editor
|
||||
:value="rules"
|
||||
:filters="filters"
|
||||
|
@ -15,6 +68,7 @@
|
|||
:preview="preview"
|
||||
@input="onInput"
|
||||
/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue