mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-27 21:05:53 +00:00
4.18.3
* Changed: Remove the word `Enable` from the tool-tip for the Audio Compressor button, bringing it in line with how other player buttons work. (Example: `Fullscreen` and not `Enter Fullscreen`) * Changed: Sort the available languages into Supported Languages and Joke Languages, in preparation for listing translations intended to be humorous. * Fixed: Display of check-boxes in various places throughout FrankerFaceZ's UI. * Fixed: The Reset All Players button not working. * Fixed: Resetting the player with the compressor enabled resetting the volume to 100% until manually changed.
This commit is contained in:
parent
1cb4128478
commit
42a48c56c6
13 changed files with 210 additions and 82 deletions
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "frankerfacez",
|
||||
"author": "Dan Salvato LLC",
|
||||
"version": "4.18.2",
|
||||
"version": "4.18.3",
|
||||
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
|
|
53
src/i18n.js
53
src/i18n.js
|
@ -176,11 +176,12 @@ export class TranslationManager extends Module {
|
|||
if( val === undefined )
|
||||
val = this.settings.get('i18n.locale');
|
||||
|
||||
const out = this.availableLocales.map(l => {
|
||||
const data = this.localeData[l];
|
||||
let title = data?.native_name;
|
||||
if ( ! title )
|
||||
title = data?.name || l;
|
||||
const normal_out = [],
|
||||
joke_out = [];
|
||||
|
||||
for(const locale of this.availableLocales) {
|
||||
const data = this.localeData[locale];
|
||||
let title = data?.native_name || data?.name || locale;
|
||||
|
||||
if ( data?.coverage != null && data?.coverage < 100 )
|
||||
title = this.t('i18n.locale-coverage', '{name} ({coverage,number,percent} Complete)', {
|
||||
|
@ -188,23 +189,47 @@ export class TranslationManager extends Module {
|
|||
coverage: data.coverage / 100
|
||||
});
|
||||
|
||||
return {
|
||||
selected: val === l,
|
||||
value: l,
|
||||
const entry = {
|
||||
selected: val === locale,
|
||||
value: locale,
|
||||
title
|
||||
};
|
||||
});
|
||||
|
||||
out.sort((a, b) => {
|
||||
return a.title.localeCompare(b.title)
|
||||
});
|
||||
if ( data?.joke )
|
||||
joke_out.push(entry);
|
||||
else
|
||||
normal_out.push(entry);
|
||||
}
|
||||
|
||||
out.unshift({
|
||||
normal_out.sort((a, b) => a.title.localeCompare(b.title));
|
||||
joke_out.sort((a, b) => a.title.localeCompare(b.title));
|
||||
|
||||
let out = [{
|
||||
selected: val === -1,
|
||||
value: -1,
|
||||
i18n_key: 'setting.appearance.localization.general.language.twitch',
|
||||
title: "Use Twitch's Language"
|
||||
});
|
||||
}];
|
||||
|
||||
if ( normal_out.length ) {
|
||||
out.push({
|
||||
separator: true,
|
||||
i18n_key: 'setting.appearance.localization.general.language.languages',
|
||||
title: 'Supported Languages'
|
||||
});
|
||||
|
||||
out = out.concat(normal_out);
|
||||
}
|
||||
|
||||
if ( joke_out.length ) {
|
||||
out.push({
|
||||
separator: true,
|
||||
i18n_key: 'setting.appearance.localization.general.language.joke',
|
||||
title: 'Joke Languages'
|
||||
});
|
||||
|
||||
out = out.concat(joke_out);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,9 @@
|
|||
>
|
||||
|
||||
<label :for="'chat-paste$' + id" class="tw-checkbox__label">
|
||||
{{ t('setting.actions.set-chat', 'Paste this message into chat rather than sending it directly.') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('setting.actions.set-chat', 'Paste this message into chat rather than sending it directly.') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -267,7 +267,9 @@
|
|||
@change="onChangeKeys"
|
||||
>
|
||||
<label :for="'key_ctrl$' + id" class="tw-checkbox__label">
|
||||
{{ t('setting.key.ctrl', 'Ctrl') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('setting.key.ctrl', 'Ctrl') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
@ -281,7 +283,9 @@
|
|||
@change="onChangeKeys"
|
||||
>
|
||||
<label :for="'key_shift$' + id" class="tw-checkbox__label">
|
||||
{{ t('setting.key.shift', 'Shift') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('setting.key.shift', 'Shift') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
@ -295,7 +299,9 @@
|
|||
@change="onChangeKeys"
|
||||
>
|
||||
<label :for="'key_alt$' + id" class="tw-checkbox__label">
|
||||
{{ t('setting.key.alt', 'Alt') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('setting.key.alt', 'Alt') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
@ -309,7 +315,9 @@
|
|||
@change="onChangeKeys"
|
||||
>
|
||||
<label :for="'key_meta$' + id" class="tw-checkbox__label">
|
||||
{{ t('setting.key.meta', 'Meta') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('setting.key.meta', 'Meta') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -48,7 +48,9 @@
|
|||
class="tw-checkbox__label"
|
||||
@contextmenu.prevent="reset(sec.id)"
|
||||
>
|
||||
{{ sec.title }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ sec.title }}
|
||||
</span>
|
||||
</label>
|
||||
</header>
|
||||
<header v-else>
|
||||
|
@ -69,35 +71,37 @@
|
|||
@click="onChange(i.id, $event)"
|
||||
>
|
||||
|
||||
<label :for="i.id" class="tw-checkbox__label tw-flex">
|
||||
<div
|
||||
:style="{backgroundColor: i.color, backgroundImage: i.styleImage }"
|
||||
class="preview-image ffz-badge tw-mg-r-1 tw-flex-shrink-0"
|
||||
/>
|
||||
<div>
|
||||
<h5>{{ i.name }}</h5>
|
||||
<section
|
||||
v-if="i.versions && i.versions.length > 1"
|
||||
class="tw-mg-t-05"
|
||||
>
|
||||
<span
|
||||
v-for="v in i.versions"
|
||||
:key="`badge-${i.id}-${v.version}`"
|
||||
:title="v.name"
|
||||
:style="{backgroundColor: i.color, backgroundImage: v.styleImage}"
|
||||
data-tooltip-type="html"
|
||||
class="ffz-badge ffz-tooltip"
|
||||
/>
|
||||
</section>
|
||||
<button
|
||||
class="tw-mg-t-05 tw-button ffz-button--hollow tw-tooltip-wrapper"
|
||||
@click="reset(i.id)"
|
||||
>
|
||||
<span class="tw-button__text">Reset</span>
|
||||
<span class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
|
||||
{{ t('setting.reset', 'Reset to Default') }}
|
||||
</span>
|
||||
</button>
|
||||
<label :for="i.id" class="tw-checkbox__label">
|
||||
<div class="tw-mg-l-1 tw-flex">
|
||||
<div
|
||||
:style="{backgroundColor: i.color, backgroundImage: i.styleImage }"
|
||||
class="preview-image ffz-badge tw-mg-r-1 tw-flex-shrink-0"
|
||||
/>
|
||||
<div>
|
||||
<h5>{{ i.name }}</h5>
|
||||
<section
|
||||
v-if="i.versions && i.versions.length > 1"
|
||||
class="tw-mg-t-05"
|
||||
>
|
||||
<span
|
||||
v-for="v in i.versions"
|
||||
:key="`badge-${i.id}-${v.version}`"
|
||||
:title="v.name"
|
||||
:style="{backgroundColor: i.color, backgroundImage: v.styleImage}"
|
||||
data-tooltip-type="html"
|
||||
class="ffz-badge ffz-tooltip"
|
||||
/>
|
||||
</section>
|
||||
<button
|
||||
class="tw-mg-t-05 tw-button ffz-button--hollow tw-tooltip-wrapper"
|
||||
@click="reset(i.id)"
|
||||
>
|
||||
<span class="tw-button__text">Reset</span>
|
||||
<span class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
|
||||
{{ t('setting.reset', 'Reset to Default') }}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</li>
|
||||
|
|
|
@ -21,7 +21,9 @@
|
|||
>
|
||||
|
||||
<label for="nonversioned" class="tw-checkbox__label">
|
||||
{{ t('home.changelog.show-nonversioned', 'Include non-versioned commits.') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('home.changelog.show-nonversioned', 'Include non-versioned commits.') }}
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<div class="tw-tooltip tw-balloon--md tw-tooltip--wrap tw-tooltip--down tw-tooltip--align-right">
|
||||
|
|
|
@ -23,7 +23,9 @@
|
|||
>
|
||||
|
||||
<label for="as_mod" class="tw-checkbox__label">
|
||||
{{ t('setting.actions.preview.mod', 'As Moderator') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('setting.actions.preview.mod', 'As Moderator') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
@ -38,7 +40,9 @@
|
|||
>
|
||||
|
||||
<label for="is_deleted" class="tw-checkbox__label">
|
||||
{{ t('setting.actions.preview.deleted', 'Deleted Message') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('setting.actions.preview.deleted', 'Deleted Message') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
@ -53,7 +57,9 @@
|
|||
>
|
||||
|
||||
<label for="with_mod_icons" class="tw-checkbox__label">
|
||||
{{ t('setting.actions.preview.mod_icons', 'With Mod Icons') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('setting.actions.preview.mod_icons', 'With Mod Icons') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
@ -68,7 +74,9 @@
|
|||
>
|
||||
|
||||
<label for="with_slow" class="tw-checkbox__label">
|
||||
{{ t('setting.actions.preview.slow', 'Slow Mode') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('setting.actions.preview.slow', 'Slow Mode') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
@ -83,7 +91,9 @@
|
|||
>
|
||||
|
||||
<label for="with_emote" class="tw-checkbox__label">
|
||||
{{ t('setting.actions.preview.emote-only', 'Emote-Only') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('setting.actions.preview.emote-only', 'Emote-Only') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
@ -98,7 +108,9 @@
|
|||
>
|
||||
|
||||
<label for="with_subs" class="tw-checkbox__label">
|
||||
{{ t('setting.actions.preview.subs', 'Subs Only') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('setting.actions.preview.subs', 'Subs Only') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
@ -113,7 +125,9 @@
|
|||
>
|
||||
|
||||
<label for="with_followers" class="tw-checkbox__label">
|
||||
{{ t('setting.actions.preview.followers', 'Followers-Only') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('setting.actions.preview.followers', 'Followers-Only') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
@ -128,7 +142,9 @@
|
|||
>
|
||||
|
||||
<label for="with_r9k" class="tw-checkbox__label">
|
||||
{{ t('setting.actions.preview.r9k', 'R9k Mode') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('setting.actions.preview.r9k', 'R9k Mode') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
@ -143,7 +159,9 @@
|
|||
>
|
||||
|
||||
<label for="show_all" class="tw-checkbox__label">
|
||||
{{ t('setting.actions.preview.all', 'Show All') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('setting.actions.preview.all', 'Show All') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -14,8 +14,10 @@
|
|||
>
|
||||
|
||||
<label :for="item.full_key" class="tw-checkbox__label">
|
||||
{{ t(item.i18n_key, item.title) }}
|
||||
<span v-if="unseen" class="tw-pill">{{ t('setting.new', 'New') }}</span>
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t(item.i18n_key, item.title) }}
|
||||
<span v-if="unseen" class="tw-pill">{{ t('setting.new', 'New') }}</span>
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<component
|
||||
|
|
|
@ -15,13 +15,29 @@
|
|||
class="tw-border-radius-medium tw-font-size-6 tw-select tw-pd-l-1 tw-pd-r-3 tw-pd-y-05 tw-mg-05"
|
||||
@change="onChange"
|
||||
>
|
||||
<option
|
||||
v-for="i in data"
|
||||
:key="i.value"
|
||||
:selected="i.value === value"
|
||||
>
|
||||
{{ i.i18n_key ? t(i.i18n_key, i.title, i) : i.title }}
|
||||
</option>
|
||||
<template v-for="i in nested_data">
|
||||
<optgroup
|
||||
v-if="i.entries"
|
||||
:key="i.key"
|
||||
:disabled="i.disabled"
|
||||
:label="i.i18n_key ? t(i.i18n_key, i.title, i) : i.title"
|
||||
>
|
||||
<option
|
||||
v-for="j in i.entries"
|
||||
:key="j.value"
|
||||
:selected="j.value === value"
|
||||
>
|
||||
{{ j.i18n_key ? t(j.i18n_key, j.title, j) : j.title }}
|
||||
</option>
|
||||
</optgroup>
|
||||
<option
|
||||
v-else
|
||||
:key="i.value"
|
||||
:selected="i.value === value"
|
||||
>
|
||||
{{ i.i18n_key ? t(i.i18n_key, i.title, i) : i.title }}
|
||||
</option>
|
||||
</template>
|
||||
</select>
|
||||
|
||||
<component
|
||||
|
@ -69,6 +85,36 @@ export default {
|
|||
mixins: [SettingMixin],
|
||||
props: ['item', 'context'],
|
||||
|
||||
computed: {
|
||||
nested_data() {
|
||||
const out = [];
|
||||
let current_group = null;
|
||||
let i = 0;
|
||||
|
||||
for(const entry of this.data) {
|
||||
if ( entry.separator ) {
|
||||
current_group = {
|
||||
key: entry.key ?? i,
|
||||
entries: [],
|
||||
i18n_key: entry.i18n_key,
|
||||
title: entry.title,
|
||||
disabled: entry.disabled
|
||||
};
|
||||
|
||||
out.push(current_group);
|
||||
|
||||
} else if ( current_group != null )
|
||||
current_group.entries.push(entry);
|
||||
else
|
||||
out.push(entry);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onChange() {
|
||||
const idx = this.$refs.control.selectedIndex,
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
class="tw-checkbox__input"
|
||||
>
|
||||
<label :for="'enabled$' + value.id" class="tw-checkbox__label">
|
||||
{{ t(type.i18n, type.title) }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t(type.i18n, type.title) }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
@ -51,10 +51,12 @@
|
|||
class="ffz-min-width-unset tw-checkbox__input"
|
||||
>
|
||||
<label :for="'sensitive$' + id" class="tw-checkbox__label tw-relative tw-tooltip-wrapper">
|
||||
Aa
|
||||
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
|
||||
{{ t('settings.filter.title.sensitive', 'Case Sensitive') }}
|
||||
</div>
|
||||
<span class="tw-mg-l-05">
|
||||
Aa
|
||||
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
|
||||
{{ t('settings.filter.title.sensitive', 'Case Sensitive') }}
|
||||
</div>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -78,7 +78,9 @@
|
|||
@change="updateCheckbox"
|
||||
>
|
||||
<label for="autoHostSettings:enabled" class="tw-checkbox__label">
|
||||
{{ t('metadata.host.setting.auto-hosting.title', 'Auto Hosting') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('metadata.host.setting.auto-hosting.title', 'Auto Hosting') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<section class="tw-c-text-alt-2 ffz-checkbox-description">
|
||||
|
@ -97,7 +99,9 @@
|
|||
@change="updateCheckbox"
|
||||
>
|
||||
<label for="autoHostSettings:team_host" class="tw-checkbox__label">
|
||||
{{ t('metadata.host.setting.team-hosting.title', 'Team Hosting') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('metadata.host.setting.team-hosting.title', 'Team Hosting') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<section class="tw-c-text-alt-2 ffz-checkbox-description">
|
||||
|
@ -117,7 +121,9 @@
|
|||
@change="updateCheckbox"
|
||||
>
|
||||
<label for="autoHostSettings:vodcast_hosting" class="tw-checkbox__label">
|
||||
{{ t('metadata.host.setting.vodcast-hosting.title', 'Vodcast Hosting') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('metadata.host.setting.vodcast-hosting.title', 'Vodcast Hosting') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<section class="tw-c-text-alt-2 ffz-checkbox-description">
|
||||
|
@ -136,7 +142,9 @@
|
|||
@change="updateCheckbox"
|
||||
>
|
||||
<label for="autoHostSettings:recommended_host" class="tw-checkbox__label">
|
||||
{{ t('metadata.host.setting.recommended-hosting.title', 'Auto Host Channels Similar To Yours') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('metadata.host.setting.recommended-hosting.title', 'Auto Host Channels Similar To Yours') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<section class="tw-c-text-alt-2 ffz-checkbox-description">
|
||||
|
@ -154,7 +162,9 @@
|
|||
@change="updateCheckbox"
|
||||
>
|
||||
<label for="autoHostSettings:strategy" class="tw-checkbox__label">
|
||||
{{ t('metadata.host.setting.strategy.title', 'Randomize Host Order') }}
|
||||
<span class="tw-mg-l-1">
|
||||
{{ t('metadata.host.setting.strategy.title', 'Randomize Host Order') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<section class="tw-c-text-alt-2 ffz-checkbox-description">
|
||||
|
|
|
@ -519,7 +519,7 @@ export default class Player extends Module {
|
|||
this.updateHideExtensions();
|
||||
this.installVisibilityHook();
|
||||
|
||||
this.on(':reset', () => this.resetPlayer());
|
||||
this.on(':reset', this.resetAllPlayers, this);
|
||||
|
||||
const t = this;
|
||||
|
||||
|
@ -940,7 +940,7 @@ export default class Player extends Module {
|
|||
updateGUI(inst) {
|
||||
this.addPiPButton(inst);
|
||||
this.addResetButton(inst);
|
||||
this.addCompressorButton(inst, true);
|
||||
this.addCompressorButton(inst, false);
|
||||
|
||||
const player = inst?.props?.mediaPlayerInstance;
|
||||
if ( player && ! this.settings.get('player.allow-catchup') ) {
|
||||
|
@ -1010,7 +1010,7 @@ export default class Player extends Module {
|
|||
label = can_apply ?
|
||||
comp_active ?
|
||||
this.i18n.t('player.comp_button.off', 'Disable Audio Compressor') :
|
||||
this.i18n.t('player.comp_button.on', 'Enable Audio Compressor')
|
||||
this.i18n.t('player.comp_button.on', 'Audio Compressor')
|
||||
: this.i18n.t('player.comp_button.disabled', 'Audio Compressor cannot be enabled when viewing Clips.');
|
||||
|
||||
extra.textContent = this.i18n.t('player.comp_button.help', 'See the FFZ Control Center for details. If audio breaks, please reset the player.');
|
||||
|
@ -1364,6 +1364,12 @@ export default class Player extends Module {
|
|||
}
|
||||
|
||||
|
||||
resetAllPlayers() {
|
||||
for(const inst of this.Player.instances)
|
||||
this.resetPlayer(inst);
|
||||
}
|
||||
|
||||
|
||||
resetPlayer(inst, e) {
|
||||
const player = inst ? (inst.mediaSinkManager ? inst : inst?.props?.mediaPlayerInstance) : null;
|
||||
|
||||
|
@ -1390,6 +1396,7 @@ export default class Player extends Module {
|
|||
const video = player.mediaSinkManager?.video;
|
||||
if ( video?._ffz_compressor && player.attachHTMLVideoElement ) {
|
||||
const new_vid = createElement('video');
|
||||
new_vid.volume = player.getVolume();
|
||||
new_vid.playsInline = true;
|
||||
video.replaceWith(new_vid);
|
||||
player.attachHTMLVideoElement(new_vid);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue