1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-07-01 16:48:32 +00:00
* Added: Room Actions can now be filtered based on the chat being in Followers-Only Mode or R9K Mode.
* Changed: Custom tool-tips for actions now support variables. Time-out and ban reasons do as well. Text labels do not.
* Fixed: Chat messages from Twitch Extensions not displaying.
This commit is contained in:
SirStendec 2019-08-27 16:18:12 -04:00
parent d150b9720d
commit 6cb585d7d4
9 changed files with 154 additions and 9 deletions

View file

@ -1,7 +1,7 @@
{
"name": "frankerfacez",
"author": "Dan Salvato LLC",
"version": "4.9.3",
"version": "4.9.4",
"description": "FrankerFaceZ is a Twitch enhancement suite.",
"license": "Apache-2.0",
"scripts": {

View file

@ -219,7 +219,7 @@ export default class Actions extends Module {
return `Error: The "${data.action}" action provider does not have tooltip support.`;
if ( data.tip && data.tip.length )
return data.tip;
return this.replaceVariables(data.tip, data);
return maybe_call(data.definition.tooltip, this, data, target, tip);
}
@ -448,7 +448,9 @@ export default class Actions extends Module {
(disp.staff != null && disp.staff !== (current_user ? !!current_user.staff : false)) ||
(disp.emoteOnly != null && disp.emoteOnly !== current_room.emoteOnly) ||
(disp.slowMode != null && disp.slowMode !== current_room.slowMode) ||
(disp.subsMode != null && disp.subsMode !== current_room.subsMode) )
(disp.subsMode != null && disp.subsMode !== current_room.subsMode) ||
(disp.r9kMode != null && disp.r9kMode !== current_room.r9kMode) ||
(disp.followersOnly != null && disp.followersOnly !== current_room.followersOnly) )
continue;
const has_color = def.colored && ap.color,
@ -474,7 +476,7 @@ export default class Actions extends Module {
const room = current_room && JSON.stringify(current_room);
return (<div
class={`ffz--room-actions ffz-action-data tw-flex tw-flex-grow-1 tw-align-items-center ${is_above ? 'tw-pd-y-05 tw-border-t' : 'tw-mg-x-05'}`}
class={`ffz--room-actions ffz-action-data tw-flex tw-flex-grow-1 tw-flex-wrap tw-align-items-center ${is_above ? 'tw-pd-y-05 tw-border-t' : 'tw-mg-x-05'}`}
data-room={room}
>
{actions}

View file

@ -159,7 +159,11 @@ export const ban = {
},
click(event, data) {
this.sendMessage(data.room.login, `/ban ${data.user.login} ${data.reason||data.options.reason||''}`);
let reason = data.reason || data.options.reason || '';
if ( reason.length )
reason = this.replaceVariables(reason, data);
this.sendMessage(data.room.login, `/ban ${data.user.login} ${reason}`);
}
}
@ -211,7 +215,11 @@ export const timeout = {
},
click(event, data) {
this.sendMessage(data.room.login, `/timeout ${data.user.login} ${data.options.duration} ${data.reason||data.options.reason||''}`);
let reason = data.reason || data.options.reason || '';
if ( reason.length )
reason = this.replaceVariables(reason, data);
this.sendMessage(data.room.login, `/timeout ${data.user.login} ${data.options.duration} ${reason}`);
}
}

View file

@ -184,6 +184,28 @@
</select>
</div>
<div v-if="has_mode" class="tw-flex tw-align-items-center">
<label for="vis_follows">
{{ t('setting.actions.edit-visible.follows', 'Follower-Only Mode') }}
</label>
<select
id="vis_subs"
v-model="edit_data.display.followersOnly"
class="tw-border-radius-medium tw-font-size-6 tw-full-width tw-select tw-pd-l-1 tw-pd-r-3 tw-pd-y-05 tw-mg-y-05"
>
<option :value="undefined" selected>
{{ t('setting.unset', 'Unset') }}
</option>
<option :value="true">
{{ t('setting.true', 'True') }}
</option>
<option :value="false">
{{ t('setting.false', 'False') }}
</option>
</select>
</div>
<div v-if="has_mode" class="tw-flex tw-align-items-center">
<label for="vis_subs">
{{ t('setting.actions.edit-visible.subs', 'Subs Mode') }}
@ -206,6 +228,28 @@
</select>
</div>
<div v-if="has_mode" class="tw-flex tw-align-items-center">
<label for="vis_r9k">
{{ t('setting.actions.edit-visible.r9k', 'R9k Mode') }}
</label>
<select
id="vis_r9k"
v-model="edit_data.display.r9kMode"
class="tw-border-radius-medium tw-font-size-6 tw-full-width tw-select tw-pd-l-1 tw-pd-r-3 tw-pd-y-05 tw-mg-y-05"
>
<option :value="undefined" selected>
{{ t('setting.unset', 'Unset') }}
</option>
<option :value="true">
{{ t('setting.true', 'True') }}
</option>
<option :value="false">
{{ t('setting.false', 'False') }}
</option>
</select>
</div>
<div v-if="has_modifiers" class="tw-flex tw-align-items-start">
<label for="vis_modifiers">
{{ t('setting.actions.edit-visible.modifier', 'Modifiers') }}
@ -552,6 +596,16 @@ export default {
out.push(this.t('setting.actions.visible.subs', 'when subs mode'));
else if ( disp.subsMode === false )
out.push(this.t('setting.actions.visible.no-subs', 'when not subs mode'));
if ( disp.r9kMode === true )
out.push(this.t('setting.actions.visible.r9k', 'when r9k mode'));
else if ( disp.r9kMode === false )
out.push(this.t('setting.actions.visible.no-r9k', 'when not r9k mode'));
if ( disp.followersOnly === true )
out.push(this.t('setting.actions.visible.followers', 'when followers-only mode'));
else if ( disp.followersOnly === false )
out.push(this.t('setting.actions.visible.no-followers', 'when not followers-only mode'));
}
if ( disp.keys ) {

View file

@ -9,7 +9,7 @@
</div>
<div class="tw-pd-b-1 tw-border-b tw-mg-b-1">
<div class="tw-flex tw-align-items-center ffz--inline">
<div class="tw-flex tw-flex-wrap tw-align-items-center ffz--inline">
{{ t('setting.actions.preview', 'Preview:') }}
<div class="tw-pd-x-1 tw-checkbox">
@ -102,6 +102,36 @@
</label>
</div>
<div v-if="has_mode" class="tw-pd-x-1 tw-checkbox">
<input
id="with_followers"
ref="with_followers"
:checked="with_followers"
type="checkbox"
class="tw-checkbox__input"
@change="onPreview"
>
<label for="with_followers" class="tw-checkbox__label">
{{ t('setting.actions.preview.followers', 'Followers-Only') }}
</label>
</div>
<div v-if="has_mode" class="tw-pd-x-1 tw-checkbox">
<input
id="with_r9k"
ref="with_r9k"
:checked="with_r9k"
type="checkbox"
class="tw-checkbox__input"
@change="onPreview"
>
<label for="with_r9k" class="tw-checkbox__label">
{{ t('setting.actions.preview.r9k', 'R9k Mode') }}
</label>
</div>
<div class="tw-pd-x-1 tw-checkbox">
<input
id="show_all"
@ -291,6 +321,8 @@ export default {
with_emote: false,
with_subs: false,
with_slow: false,
with_followers: false,
with_r9k: false,
is_staff: false,
is_deleted: false,
@ -543,6 +575,8 @@ export default {
this.with_emote = this.has_mode && this.$refs.with_emote.checked;
this.with_subs = this.has_mode && this.$refs.with_subs.checked;
this.with_slow = this.has_mode && this.$refs.with_slow.checked;
this.with_followers = this.has_mode && this.$refs.with_followers.checked;
this.with_r9k = this.has_mode && this.$refs.with_r9k.checked;
},
displayAction(action) {
@ -577,6 +611,12 @@ export default {
if ( disp.subsMode != null && disp.subsMode !== this.with_subs )
return false;
if ( disp.r9kMode != null && disp.r9kMode !== this.with_r9k )
return false;
if ( disp.followersOnly != null && disp.followersOnly !== this.with_followers )
return false;
}
return true;

View file

@ -605,6 +605,21 @@ export default class ChatHook extends Module {
if ( handler )
handler.addMessageHandler(inst.handleMessage);
if ( Array.isArray(inst.buffer) ) {
let i = inst.buffer.length;
const ct = this.chat_types || CHAT_TYPES;
while(i--) {
const msg = inst.buffer[i];
if ( msg && msg.type === ct.RoomState && msg.state ) {
this.chat.context.updateContext({
chat_state: msg.state
});
break;
}
}
}
inst.props.setMessageBufferAPI({
addUpdateHandler: inst.addUpdateHandler,
removeUpdateHandler: inst.removeUpdateHandler,
@ -1313,6 +1328,24 @@ export default class ChatHook extends Module {
}
}
const old_state = this.onRoomStateEvent;
this.onRoomStateEvent = function(e) {
try {
const channel = e.channel,
current = t.chat.context.get('context.channel');
if ( channel && (channel === current || channel === `#${current}`) )
t.chat.context.updateContext({
chat_state: e.state
});
} catch(err) {
t.log.capture(err, {extra: e});
}
return old_state.call(i, e);
}
const old_resub = this.onResubscriptionEvent;
this.onResubscriptionEvent = function(e) {
try {

View file

@ -157,6 +157,7 @@ export default class Input extends Module {
const out = old_render.call(this);
try {
const above = t.chat.context.get('chat.actions.room-above'),
state = t.chat.context.get('context.chat_state') || {},
container = above ? out : findReactFragment(out, n => n.props && n.props.className === 'chat-input__buttons-container');
if ( ! container || ! container.props || ! container.props.children )
return out;
@ -179,7 +180,10 @@ export default class Input extends Module {
emoteOnly: props.emoteOnlyMode,
slowMode: props.slowMode,
slowDuration: props.slowModeDuration,
subsMode: props.subsOnlyMode
subsMode: props.subsOnlyMode,
r9kMode: state.r9k,
followersOnly: state.followersOnly,
followersDuration: state.followersOnlyRequirement
}
const actions = t.actions.renderRoom(t.chat.context.get('context.chat.showModIcons'), u, r, above, createElement);

View file

@ -741,7 +741,7 @@ other {# messages were deleted by a moderator.}
if ( ! this.props.installedExtensions.some(val => {
const e = val.extension;
return e && e.clientID === ext.clientID && e.version === ext.version;
return e && (e.clientId || e.clientID) === (ext.clientId || ext.clientID) && e.version === ext.version;
}) )
return null;

View file

@ -245,6 +245,10 @@ textarea.tw-input {
margin-bottom: 1rem;
}
p {
white-space: pre-line;
}
code {
padding: 2px 5px;
border-radius: 2px;