mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-08-03 00:18:31 +00:00
4.9.0
Added: Chat Room Actions can now be filtered by a room being in emote-only mode, subs-only mode, or slow mode. Added: Option to hide Latest Videos in the Following directory. Added: Option to display the current stream delay in a warning color if it exceeds a certain value. Fixed: Emote previews not appearing correctly in tool-tips. Fixed: Option to hide Rerun bar not functioning correctly. Fixed: Favorite emotes from add-ons and other extensions not being sorted correctly for tab-completion.
This commit is contained in:
parent
f32b2efd1a
commit
c39f6799d3
10 changed files with 231 additions and 30 deletions
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "frankerfacez",
|
||||
"author": "Dan Salvato LLC",
|
||||
"version": "4.8.2",
|
||||
"version": "4.9.0",
|
||||
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
|
|
|
@ -133,7 +133,7 @@ export default class Actions extends Module {
|
|||
ui: {
|
||||
path: 'Chat > Actions > Room @{"description": "Here, you can define custom actions that will appear above the chat input box."}',
|
||||
component: 'chat-actions',
|
||||
context: ['room'],
|
||||
context: ['room', 'room-mode'],
|
||||
inline: true,
|
||||
|
||||
data: () => {
|
||||
|
@ -436,7 +436,10 @@ export default class Actions extends Module {
|
|||
if ( ! def || disp.disabled ||
|
||||
(disp.mod_icons != null && disp.mod_icons !== !!mod_icons) ||
|
||||
(disp.mod != null && disp.mod !== (current_user ? !!current_user.mod : false)) ||
|
||||
(disp.staff != null && disp.staff !== (current_user ? !!current_user.staff : false)) )
|
||||
(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) )
|
||||
continue;
|
||||
|
||||
const has_color = def.colored && ap.color,
|
||||
|
|
|
@ -5,8 +5,6 @@ query FFZ_GetEmoteInfo($id: ID!) {
|
|||
text
|
||||
subscriptionProduct {
|
||||
id
|
||||
displayName
|
||||
state
|
||||
owner {
|
||||
id
|
||||
login
|
||||
|
@ -14,12 +12,6 @@ query FFZ_GetEmoteInfo($id: ID!) {
|
|||
}
|
||||
tier
|
||||
url
|
||||
self {
|
||||
benefit {
|
||||
id
|
||||
endsAt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -798,6 +798,41 @@ export default class Emotes extends Module {
|
|||
return tes.get(emote_id);
|
||||
|
||||
tes.set(emote_id, null);
|
||||
|
||||
/*const apollo = this.resolve('site.apollo');
|
||||
if ( apollo?.client ) {
|
||||
timeout(apollo.client.query({
|
||||
query: GET_EMOTE,
|
||||
variables: {
|
||||
id: `${emote_id}`
|
||||
}
|
||||
}), 1000).then(result => {
|
||||
const emote = result?.data?.emote;
|
||||
|
||||
if ( ! emote ) {
|
||||
tes.delete(emote_id);
|
||||
return;
|
||||
}
|
||||
|
||||
const set_id = parseInt(emote.setID, 10),
|
||||
channel = emote?.subscriptionProduct?.owner;
|
||||
|
||||
this.__twitch_set_to_channel.set(set_id, {
|
||||
s_id: set_id,
|
||||
c_id: channel ? channel.id : null,
|
||||
c_name: channel ? channel.login : null,
|
||||
c_title: channel ? channel.displayName : null
|
||||
});
|
||||
|
||||
tes.set(emote_id, set_id);
|
||||
if ( callback )
|
||||
callback(set_id);
|
||||
|
||||
}).catch(() => tes.delete(emote_id));
|
||||
|
||||
return;
|
||||
}*/
|
||||
|
||||
timeout(this.socket.call('get_emote', emote_id), 1000).then(data => {
|
||||
const set_id = data['s_id'];
|
||||
tes.set(emote_id, set_id);
|
||||
|
@ -827,6 +862,7 @@ export default class Emotes extends Module {
|
|||
return null;
|
||||
|
||||
tes.set(set_id, null);
|
||||
|
||||
try {
|
||||
const data = await timeout(this.socket.call('get_emote_set', set_id), 1000);
|
||||
tes.set(set_id, data);
|
||||
|
|
|
@ -1028,7 +1028,7 @@ export const AddonEmotes = {
|
|||
const set_id = this.emotes.getTwitchEmoteSet(emote_id, tip.rerender),
|
||||
emote_set = set_id != null && this.emotes.getTwitchSetChannel(set_id, tip.rerender);
|
||||
|
||||
preview = `//static-cdn.jtvnw.net/emoticons/v1/${emote_id}/4.0?_=preview`;
|
||||
preview = `//static-cdn.jtvnw.net/emoticons/v1/${emote_id}/3.0?_=preview`;
|
||||
fav_source = 'twitch';
|
||||
|
||||
if ( emote_set ) {
|
||||
|
|
|
@ -140,6 +140,72 @@
|
|||
</select>
|
||||
</div>
|
||||
|
||||
<div v-if="has_mode" class="tw-flex tw-align-items-center">
|
||||
<label for="vis_emote">
|
||||
{{ t('setting.actions.edit-visible.emote-only', 'Emote-Only Mode') }}
|
||||
</label>
|
||||
|
||||
<select
|
||||
id="vis_emote"
|
||||
v-model="edit_data.display.emoteOnly"
|
||||
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_slow">
|
||||
{{ t('setting.actions.edit-visible.slow', 'Slow Mode') }}
|
||||
</label>
|
||||
|
||||
<select
|
||||
id="vis_slow"
|
||||
v-model="edit_data.display.slowMode"
|
||||
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') }}
|
||||
</label>
|
||||
|
||||
<select
|
||||
id="vis_subs"
|
||||
v-model="edit_data.display.subsMode"
|
||||
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') }}
|
||||
|
@ -325,6 +391,10 @@ export default {
|
|||
return this.context && this.context.includes('message')
|
||||
},
|
||||
|
||||
has_mode() {
|
||||
return this.context && this.context.includes('room-mode')
|
||||
},
|
||||
|
||||
has_modifiers() {
|
||||
return this.modifiers
|
||||
},
|
||||
|
@ -467,6 +537,23 @@ export default {
|
|||
else if ( disp.deleted === false )
|
||||
out.push(this.t('setting.actions.visible.undeleted', 'if message not deleted'));
|
||||
|
||||
if ( this.has_mode ) {
|
||||
if ( disp.emoteOnly === true )
|
||||
out.push(this.t('setting.actions.visible.emote-only', 'when emote-only mode'));
|
||||
else if ( disp.emoteOnly === false )
|
||||
out.push(this.t('setting.actions.visible.no-emote', 'when not emote-only mode'));
|
||||
|
||||
if ( disp.slowMode === true )
|
||||
out.push(this.t('setting.actions.visible.slow', 'when slow mode'));
|
||||
else if ( disp.slowMode === false )
|
||||
out.push(this.t('setting.actions.visible.no-slow', 'when not slow mode'));
|
||||
|
||||
if ( disp.subsMode === true )
|
||||
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.keys ) {
|
||||
const key_out = [];
|
||||
if ( disp.keys & 1 )
|
||||
|
|
|
@ -57,6 +57,51 @@
|
|||
</label>
|
||||
</div>
|
||||
|
||||
<div v-if="has_mode" class="tw-pd-x-1 tw-checkbox">
|
||||
<input
|
||||
id="with_slow"
|
||||
ref="with_slow"
|
||||
:checked="with_slow"
|
||||
type="checkbox"
|
||||
class="tw-checkbox__input"
|
||||
@change="onPreview"
|
||||
>
|
||||
|
||||
<label for="with_slow" class="tw-checkbox__label">
|
||||
{{ t('setting.actions.preview.slow', 'Slow Mode') }}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div v-if="has_mode" class="tw-pd-x-1 tw-checkbox">
|
||||
<input
|
||||
id="with_emote"
|
||||
ref="with_emote"
|
||||
:checked="with_emote"
|
||||
type="checkbox"
|
||||
class="tw-checkbox__input"
|
||||
@change="onPreview"
|
||||
>
|
||||
|
||||
<label for="with_emote" class="tw-checkbox__label">
|
||||
{{ t('setting.actions.preview.emote-only', 'Emote-Only') }}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div v-if="has_mode" class="tw-pd-x-1 tw-checkbox">
|
||||
<input
|
||||
id="with_subs"
|
||||
ref="with_subs"
|
||||
:checked="with_subs"
|
||||
type="checkbox"
|
||||
class="tw-checkbox__input"
|
||||
@change="onPreview"
|
||||
>
|
||||
|
||||
<label for="with_subs" class="tw-checkbox__label">
|
||||
{{ t('setting.actions.preview.subs', 'Subs Only') }}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="tw-pd-x-1 tw-checkbox">
|
||||
<input
|
||||
id="show_all"
|
||||
|
@ -242,6 +287,11 @@ export default {
|
|||
return {
|
||||
is_moderator: true,
|
||||
with_mod_icons: true,
|
||||
|
||||
with_emote: false,
|
||||
with_subs: false,
|
||||
with_slow: false,
|
||||
|
||||
is_staff: false,
|
||||
is_deleted: false,
|
||||
show_all: false,
|
||||
|
@ -300,6 +350,10 @@ export default {
|
|||
return this.item.context && this.item.context.includes('room')
|
||||
},
|
||||
|
||||
has_mode() {
|
||||
return this.item.context && this.item.context.includes('room-mode')
|
||||
},
|
||||
|
||||
has_msg() {
|
||||
return this.item.context && this.item.context.includes('message')
|
||||
},
|
||||
|
@ -485,6 +539,10 @@ export default {
|
|||
this.is_staff = false; //this.$refs.as_staff.checked;
|
||||
this.with_mod_icons = this.has_icons && this.$refs.with_mod_icons.checked;
|
||||
this.is_deleted = this.has_msg && this.$refs.is_deleted.checked;
|
||||
|
||||
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;
|
||||
},
|
||||
|
||||
displayAction(action) {
|
||||
|
@ -510,6 +568,17 @@ export default {
|
|||
if ( disp.deleted != null && disp.deleted !== this.is_deleted )
|
||||
return false;
|
||||
|
||||
if ( this.has_mode ) {
|
||||
if ( disp.emoteOnly != null && disp.emoteOnly !== this.with_emote )
|
||||
return false;
|
||||
|
||||
if ( disp.slowMode != null && disp.slowMode !== this.with_slow )
|
||||
return false;
|
||||
|
||||
if ( disp.subsMode != null && disp.subsMode !== this.with_subs )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ export default class Metadata extends Module {
|
|||
ui: {
|
||||
path: 'Channel > Metadata >> Player',
|
||||
title: 'Stream Delay Warning',
|
||||
description: 'Define a maximum delay in seconds after which the indicator will be shown in warning colors. (0 for no warning colors)',
|
||||
description: 'When the current stream delay exceeds this number of seconds, display the stream delay in a warning color to draw attention to the large delay. Set to zero to disable.',
|
||||
|
||||
component: 'setting-text-box',
|
||||
process(val) {
|
||||
|
|
|
@ -171,12 +171,24 @@ export default class Input extends Module {
|
|||
r = {
|
||||
id: props.channelID,
|
||||
login: props.channelLogin,
|
||||
displayName: props.channelDisplayName
|
||||
displayName: props.channelDisplayName,
|
||||
emoteOnly: props.emoteOnlyMode,
|
||||
slowMode: props.slowMode,
|
||||
slowDuration: props.slowModeDuration,
|
||||
subsMode: props.subsOnlyMode
|
||||
}
|
||||
|
||||
const actions = t.actions.renderRoom(t.chat.context.get('context.chat.showModIcons'), u, r, createElement);
|
||||
|
||||
// TODO: Instead of putting actions above the chat input,
|
||||
// put them next to the settings menu. This involves going
|
||||
// exploring in the React render output, which is a mess.
|
||||
//t.log.info('chat-input-render', out);
|
||||
|
||||
if ( actions )
|
||||
out.props.children.unshift(actions);
|
||||
else
|
||||
out.props.children.unshift(null);
|
||||
|
||||
} catch(err) {
|
||||
t.log.error(err);
|
||||
|
@ -527,22 +539,24 @@ export default class Input extends Module {
|
|||
channel_login
|
||||
);
|
||||
|
||||
for(const set of sets)
|
||||
for(const emote of Object.values(set.emotes))
|
||||
if ( inst.doesEmoteMatchTerm(emote, search) ) {
|
||||
const favorite = this.emotes.isFavorite(set.source || 'ffz', emote.id);
|
||||
results.push({
|
||||
current: input,
|
||||
replacement: emote.name,
|
||||
element: inst.renderEmoteSuggestion({
|
||||
token: emote.name,
|
||||
id: `${set.source}-${emote.id}`,
|
||||
srcSet: emote.srcSet,
|
||||
for(const set of sets) {
|
||||
if ( set && set.emotes )
|
||||
for(const emote of Object.values(set.emotes))
|
||||
if ( inst.doesEmoteMatchTerm(emote, search) ) {
|
||||
const favorite = this.emotes.isFavorite(set.source || 'ffz', emote.id);
|
||||
results.push({
|
||||
current: input,
|
||||
replacement: emote.name,
|
||||
element: inst.renderEmoteSuggestion({
|
||||
token: emote.name,
|
||||
id: `${set.source}-${emote.id}`,
|
||||
srcSet: emote.srcSet,
|
||||
favorite
|
||||
}),
|
||||
favorite
|
||||
}),
|
||||
favorite
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ const CLASSES = {
|
|||
'player-ext-hover': '.player:not([data-controls="true"]) .extension-container,.player:not([data-controls="true"]) .extensions-dock__layout,.player:not([data-controls="true"]) .extensions-notifications,.player:not([data-controls="true"]) .extensions-video-overlay-size-container',
|
||||
|
||||
'player-event-bar': '.channel-root .live-event-banner-ui__header',
|
||||
'player-rerun-bar': '.channel-root__player_container div.tw-c-text-overlay:not([data-a-target="hosting-ui-header"])',
|
||||
'player-rerun-bar': '.channel-root__player-container div.tw-c-text-overlay:not([data-a-target="hosting-ui-header"])',
|
||||
|
||||
'pinned-cheer': '.pinned-cheer,.pinned-cheer-v2',
|
||||
'whispers': 'body .whispers',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue