1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-27 21:05:53 +00:00
* 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:
SirStendec 2022-12-08 16:19:14 -05:00
parent 92ff27f3fb
commit 1914b055ce
9 changed files with 168 additions and 25 deletions

View file

@ -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",

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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
}

View file

@ -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>

View file

@ -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);
}
}

View file

@ -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

View file

@ -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);
}