1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-08-03 00:18:31 +00:00
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:
SirStendec 2019-08-12 22:52:57 -04:00
parent f32b2efd1a
commit c39f6799d3
10 changed files with 231 additions and 30 deletions

View file

@ -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": {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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