1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-07-02 17:18:31 +00:00
* Added: Option to open the emote menu with Ctrl+E, similar to how Discord's works.
* Added: Warning to the Debugging > Experiments list that they are not intended for end-users.
* Changed: Rewrote tab-completion of emotes to fully respect hidden emotes from the emote menu and to cache more useful data.
* Changed: The Experiments list now hides inactive experiments by default.
* Fixed: Updated the Host button's menu to restore functionality after Twitch removed the old API.
* Fixed: Some avatar images remaining rounded despite the square avatars setting.
This commit is contained in:
SirStendec 2020-07-01 19:07:17 -04:00
parent fa5333d462
commit 339b6fdfbb
15 changed files with 490 additions and 212 deletions

View file

@ -4,155 +4,211 @@
{{ t('setting.experiments.about', 'This feature allows you to override experiment values. Please note that, for most experiments, you may have to refresh the page for your changes to take effect.') }}
</div>
<div class="tw-mg-b-2 tw-flex tw-align-items-center">
<div class="tw-flex-grow-1">
{{ t('setting.experiments.unique-id', 'Unique ID: {id}', {id: unique_id}) }}
<section v-if="experiments_locked">
<div class="tw-c-background-accent tw-c-text-overlay tw-pd-1 tw-mg-b-2">
<h3 class="ffz-i-attention">
{{ t('setting.dev-warning', "It's dangerous to go at all.") }}
</h3>
<markdown :source="t('setting.dev-warning.explain', 'Be careful, this is an advanced feature intended for developer use only. Normal users should steer clear. Adjusting your experiments can have unexpected impacts on your Twitch experience. FrankerFaceZ is not responsible for any issues you encounter as a result of tampering with experiments, and we will not provide support.\n\nIf you\'re sure about this, please type `sv_cheats 1` into the box below and hit enter.')" />
</div>
<select
ref="sort_select"
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-x-05"
@change="onSort"
>
<option :selected="sort_by === 0">
{{ t('setting.experiments.sort-name', 'Sort By: Name') }}
</option>
<option :selected="sort_by === 1">
{{ t('setting.experiments.sort-rarity', 'Sort By: Rarity') }}
</option>
</select>
</div>
<h3 class="tw-mg-b-1">
{{ t('setting.experiments.ffz', 'FrankerFaceZ Experiments') }}
</h3>
<div class="ffz--experiment-list">
<section
v-for="({key, exp}) of visible_ffz"
:key="key"
:data-key="key"
>
<div class="tw-elevation-1 tw-c-background-base tw-border tw-pd-y-05 tw-pd-x-1 tw-mg-y-05 tw-flex tw-flex-nowrap">
<div class="tw-flex-grow-1">
<h4>{{ exp.name }}</h4>
<div v-if="exp.description" class="description">
{{ exp.description }}
</div>
</div>
<div class="tw-flex tw-flex-shrink-0 tw-align-items-start">
<select
:data-key="key"
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-x-05"
@change="onChange($event)"
>
<option
v-for="(i, idx) in exp.groups"
:key="idx"
:selected="i.value === exp.value"
>
{{ t('setting.experiments.entry', '{value,tostring} (weight: {weight,tostring})', i) }}
</option>
</select>
<button
:disabled="exp.default"
:class="{'tw-button--disabled': exp.default}"
class="tw-mg-t-05 tw-button tw-button--text tw-tooltip-wrapper"
@click="reset(key)"
>
<span class="tw-button__text ffz-i-cancel" />
<span class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
{{ t('setting.reset', 'Reset to Default') }}
</span>
</button>
</div>
</div>
</section>
<div v-if="! Object.keys(ffz_data).length">
{{ t('setting.experiments.none', 'There are no current experiments.') }}
</div>
<div v-else-if="! visible_ffz.length">
{{ t('setting.experiments.none-filter', 'There are no matching experiments.') }}
</div>
</div>
<h3 class="tw-mg-t-5 tw-mg-b-1">
{{ t('setting.experiments.twitch', 'Twitch Experiments') }}
</h3>
<div class="ffz--experiment-list">
<section
v-for="({key, exp}) of visible_twitch"
:key="key"
:data-key="key"
>
<div
:class="{live: exp.in_use}"
class="ffz--experiment-row tw-elevation-1 tw-c-background-base tw-border tw-pd-y-05 tw-pd-x-1 tw-mg-y-05 tw-flex"
<div class="tw-flex tw-align-items-center">
<input
ref="code"
type="text"
class="tw-block tw-full-width tw-border-radius-medium tw-font-size-6 tw-full-width tw-input tw-pd-x-1 tw-pd-y-05"
autocapitalize="off"
autocorrect="off"
@keydown.enter="enterCode"
>
<div class="tw-flex tw-flex-shrink-0 tw-align-items-center tw-border-r tw-mg-r-1 tw-pd-r-1">
<div v-if="exp.in_use" class="ffz--profile__icon ffz-i-ok tw-tooltip-wrapper">
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-left">
{{ t('setting.experiments.active', 'This experiment is active.') }}
</div>
</div>
<div v-else class="ffz--profile__icon ffz-i-cancel tw-tooltip-wrapper">
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-left">
{{ t('setting.experiments.inactive', 'This experiment is not active.') }}
</div>
</div>
</div>
</div>
</section>
<div class="tw-flex-grow-1">
<h4>{{ exp.name }}</h4>
<div class="description">
{{ exp.remainder }}
</div>
</div>
<div class="tw-flex tw-flex-shrink-0 tw-align-items-start">
<select
:data-key="key"
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-x-05"
@change="onTwitchChange($event)"
>
<option
v-if="exp.in_use === false"
:selected="exp.default"
>
{{ t('setting.experiments.unset', 'unset') }}
</option>
<option
v-for="(i, idx) in exp.groups"
:key="idx"
:selected="i.value === exp.value"
>
{{ t('setting.experiments.entry', '{value,tostring} (weight: {weight,tostring})', i) }}
</option>
</select>
<button
:disabled="exp.default"
:class="{'tw-button--disabled': exp.default}"
class="tw-mg-t-05 tw-button tw-button--text tw-tooltip-wrapper"
@click="resetTwitch(key)"
>
<span class="tw-button__text ffz-i-cancel" />
<span class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
{{ t('setting.reset', 'Reset to Default') }}
</span>
</button>
</div>
<section v-else>
<div class="tw-mg-b-2 tw-flex tw-align-items-center">
<div class="tw-flex-grow-1">
{{ t('setting.experiments.unique-id', 'Unique ID: {id}', {id: unique_id}) }}
</div>
</section>
<div v-if="! Object.keys(twitch_data).length">
{{ t('setting.experiments.none', 'There are no current experiments.') }}
<select
ref="sort_select"
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-x-05"
@change="onSort"
>
<option :selected="sort_by === 0">
{{ t('setting.experiments.sort-name', 'Sort By: Name') }}
</option>
<option :selected="sort_by === 1">
{{ t('setting.experiments.sort-rarity', 'Sort By: Rarity') }}
</option>
</select>
</div>
<div v-else-if="! visible_twitch.length">
{{ t('setting.experiments.none-filter', 'There are no matching experiments.') }}
<div class="tw-mg-b-2 tw-flex tw-align-items-center">
<div class="tw-flex-grow-1" />
<div class="tw-checkbox tw-relative">
<input
id="unused"
ref="unused"
v-model="unused"
type="checkbox"
class="tw-checkbox__input"
>
<label for="unused" class="tw-checkbox__label">
<span class="tw-mg-l-1">
{{ t('setting.experiments.show-unused', 'Display unused experiments.') }}
</span>
</label>
</div>
</div>
</div>
<h3 class="tw-mg-b-1">
<span>
{{ t('setting.experiments.ffz', 'FrankerFaceZ Experiments') }}
</span>
<span v-if="filter" class="tw-mg-l-1 tw-font-size-base tw-regular tw-c-text-alt-2">
{{ t('setting.experiments.visible', '(Showing {visible,number} of {total,number})', {
visible: visible_ffz.length,
total: sorted_ffz.length
}) }}
</span>
</h3>
<div class="ffz--experiment-list">
<section
v-for="({key, exp}) of visible_ffz"
:key="key"
:data-key="key"
>
<div class="tw-elevation-1 tw-c-background-base tw-border tw-pd-y-05 tw-pd-x-1 tw-mg-y-05 tw-flex tw-flex-nowrap">
<div class="tw-flex-grow-1">
<h4>{{ exp.name }}</h4>
<div v-if="exp.description" class="description">
{{ exp.description }}
</div>
</div>
<div class="tw-flex tw-flex-shrink-0 tw-align-items-start">
<select
:data-key="key"
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-x-05"
@change="onChange($event)"
>
<option
v-for="(i, idx) in exp.groups"
:key="idx"
:selected="i.value === exp.value"
>
{{ t('setting.experiments.entry', '{value,tostring} (weight: {weight,tostring})', i) }}
</option>
</select>
<button
:disabled="exp.default"
:class="{'tw-button--disabled': exp.default}"
class="tw-mg-t-05 tw-button tw-button--text tw-tooltip-wrapper"
@click="reset(key)"
>
<span class="tw-button__text ffz-i-cancel" />
<span class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
{{ t('setting.reset', 'Reset to Default') }}
</span>
</button>
</div>
</div>
</section>
<div v-if="! Object.keys(ffz_data).length">
{{ t('setting.experiments.none', 'There are no current experiments.') }}
</div>
<div v-else-if="! visible_ffz.length">
{{ t('setting.experiments.none-filter', 'There are no matching experiments.') }}
</div>
</div>
<h3 class="tw-mg-t-5 tw-mg-b-1">
<span>
{{ t('setting.experiments.twitch', 'Twitch Experiments') }}
</span>
<span v-if="filter" class="tw-mg-l-1 tw-font-size-base tw-regular tw-c-text-alt-2">
{{ t('setting.experiments.visible', '(Showing {visible,number} of {total,number})', {
visible: visible_twitch.length,
total: sorted_twitch.length
}) }}
</span>
</h3>
<div class="ffz--experiment-list">
<section
v-for="({key, exp}) of visible_twitch"
:key="key"
:data-key="key"
>
<div
:class="{live: exp.in_use}"
class="ffz--experiment-row tw-elevation-1 tw-c-background-base tw-border tw-pd-y-05 tw-pd-x-1 tw-mg-y-05 tw-flex"
>
<div v-if="unused" class="tw-flex tw-flex-shrink-0 tw-align-items-center tw-border-r tw-mg-r-1 tw-pd-r-1">
<div v-if="exp.in_use" class="ffz--profile__icon ffz-i-ok tw-tooltip-wrapper">
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-left">
{{ t('setting.experiments.active', 'This experiment is active.') }}
</div>
</div>
<div v-else class="ffz--profile__icon ffz-i-cancel tw-tooltip-wrapper">
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-left">
{{ t('setting.experiments.inactive', 'This experiment is not active.') }}
</div>
</div>
</div>
<div class="tw-flex-grow-1">
<h4>{{ exp.name }}</h4>
<div class="description">
{{ exp.remainder }}
</div>
</div>
<div class="tw-flex tw-flex-shrink-0 tw-align-items-start">
<select
:data-key="key"
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-x-05"
@change="onTwitchChange($event)"
>
<option
v-if="exp.in_use === false"
:selected="exp.default"
>
{{ t('setting.experiments.unset', 'unset') }}
</option>
<option
v-for="(i, idx) in exp.groups"
:key="idx"
:selected="i.value === exp.value"
>
{{ t('setting.experiments.entry', '{value,tostring} (weight: {weight,tostring})', i) }}
</option>
</select>
<button
:disabled="exp.default"
:class="{'tw-button--disabled': exp.default}"
class="tw-mg-t-05 tw-button tw-button--text tw-tooltip-wrapper"
@click="resetTwitch(key)"
>
<span class="tw-button__text ffz-i-cancel" />
<span class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
{{ t('setting.reset', 'Reset to Default') }}
</span>
</button>
</div>
</div>
</section>
<div v-if="! Object.keys(twitch_data).length">
{{ t('setting.experiments.none', 'There are no current experiments.') }}
</div>
<div v-else-if="! visible_twitch.length">
{{ t('setting.experiments.none-filter', 'There are no matching experiments.') }}
</div>
</div>
</section>
</div>
</template>
@ -173,7 +229,9 @@ export default {
data() {
return {
experiments_locked: this.item.is_locked(),
sort_by: 1,
unused: false,
unique_id: this.item.unique_id(),
ffz_data: this.item.ffz_data(),
twitch_data: this.item.twitch_data()
@ -242,6 +300,14 @@ export default {
},
methods: {
enterCode() {
if ( this.$refs.code.value !== 'sv_cheats 1' )
return;
this.experiments_locked = false;
this.item.unlock();
},
calculateRarity(exp) {
let rarity;
for(const group of exp.groups)
@ -254,7 +320,15 @@ export default {
},
sorted(data) {
const out = Object.entries(data).map(x => ({key: x[0], exp: x[1]}));
const out = [];
for(const [k,v] of Object.entries(data)) {
if ( ! this.unused && v.in_use === false )
continue;
out.push({key: k, exp: v});
}
//const out = Object.entries(data).map(x => ({key: x[0], exp: x[1]}));
out.sort((a,b) => {
const a_use = a.exp.in_use,