mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-27 21:05:53 +00:00
4.5.3
The Great Maintenance Update. No new features here. Instead, we've updated the build system to webpack 4, updated all our dependencies, and cleaned up a lot of linting issues.
This commit is contained in:
parent
014eb203c3
commit
33e81bc7eb
60 changed files with 238 additions and 209 deletions
|
@ -138,7 +138,6 @@ module.exports = {
|
|||
"react/jsx-no-bind": "error",
|
||||
"react/jsx-no-comment-textnodes": "error",
|
||||
"react/jsx-no-duplicate-props": "error",
|
||||
"react/jsx-no-literals": ["warn"],
|
||||
"react/jsx-no-target-blank": "error",
|
||||
"react/jsx-sort-props": ["error", {
|
||||
"callbacksLast": true,
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
"build:all": "npm run build && npm run build:clips",
|
||||
"build": "npm run build:prod",
|
||||
"build:clips": "cross-env NODE_ENV=production webpack --config webpack.clips.prod.js",
|
||||
"build:clips:dev": "npm run clean && webpack --config webpack.clips.dev.js",
|
||||
"build:stats": "cross-env NODE_ENV=production webpack --config webpack.web.prod.js --json > stats.json",
|
||||
"build:prod": "cross-env NODE_ENV=production webpack --config webpack.web.prod.js",
|
||||
"build:dev": "npm run clean && webpack --config webpack.web.dev.js"
|
||||
|
@ -70,7 +71,7 @@
|
|||
"raven-js": "^3.24.2",
|
||||
"react": "^16.4.1",
|
||||
"safe-regex": "^2.0.2",
|
||||
"sortablejs": "^1.10.0-rc2",
|
||||
"sortablejs": "^1.10.0-rc1",
|
||||
"vue": "^2.6.10",
|
||||
"vue-clickaway": "^2.2.2",
|
||||
"vue-color": "^2.4.6",
|
||||
|
|
|
@ -10,9 +10,7 @@ import { createElement } from 'utilities/dom';
|
|||
import { timeout, has } from 'utilities/object';
|
||||
import { getBuster } from 'utilities/time';
|
||||
|
||||
const fetchJSON = (url, options) => {
|
||||
return fetch(url, options).then(r => r.ok ? r.json() : null).catch(() => null);
|
||||
}
|
||||
const fetchJSON = (url, options) => fetch(url, options).then(r => r.ok ? r.json() : null).catch(() => null);
|
||||
|
||||
// ============================================================================
|
||||
// AddonManager
|
||||
|
|
22
src/i18n.js
22
src/i18n.js
|
@ -14,20 +14,18 @@ import NewTransCore from 'utilities/translation-core';
|
|||
|
||||
const FACES = ['(・`ω´・)', ';;w;;', 'owo', 'ono', 'oAo', 'oxo', 'ovo;', 'UwU', '>w<', '^w^', '> w >', 'v.v'],
|
||||
|
||||
transformText = (ast, fn) => {
|
||||
return ast.map(node => {
|
||||
if ( typeof node === 'string' )
|
||||
return fn(node);
|
||||
transformText = (ast, fn) => ast.map(node => {
|
||||
if ( typeof node === 'string' )
|
||||
return fn(node);
|
||||
|
||||
else if ( typeof node === 'object' && node.o ) {
|
||||
const out = Object.assign(node, {o: {}});
|
||||
for(const key of Object.keys(node.o))
|
||||
out.o[key] = transformText(node.o[key], fn)
|
||||
}
|
||||
else if ( typeof node === 'object' && node.o ) {
|
||||
const out = Object.assign(node, {o: {}});
|
||||
for(const key of Object.keys(node.o))
|
||||
out.o[key] = transformText(node.o[key], fn)
|
||||
}
|
||||
|
||||
return node;
|
||||
})
|
||||
},
|
||||
return node;
|
||||
}),
|
||||
|
||||
owo = text => text
|
||||
.replace(/(?:r|l)/g, 'w')
|
||||
|
|
|
@ -115,11 +115,9 @@ class FrankerFaceZ extends Module {
|
|||
out.unshift(['initialization', logs.join('\n')]);
|
||||
}
|
||||
|
||||
return out.map(x => {
|
||||
return `${x[0]}
|
||||
return out.map(x => `${x[0]}
|
||||
-------------------------------------------------------------------------------
|
||||
${typeof x[1] === 'string' ? x[1] : JSON.stringify(x[1], null, 4)}`
|
||||
}).join('\n\n');
|
||||
${typeof x[1] === 'string' ? x[1] : JSON.stringify(x[1], null, 4)}`).join('\n\n');
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -255,8 +255,8 @@ export default class Actions extends Module {
|
|||
reason_elements.push(<li class="tw-full-width tw-relative">
|
||||
<a
|
||||
href="#"
|
||||
onClick={click_fn(text)}
|
||||
class="tw-block tw-full-width tw-interactable tw-interactable--inverted tw-interactive tw-pd-05"
|
||||
onClick={click_fn(text)}
|
||||
>
|
||||
{text}
|
||||
</a>
|
||||
|
@ -272,8 +272,8 @@ export default class Actions extends Module {
|
|||
reason_elements.push(<li class="tw-full-width tw-relative">
|
||||
<a
|
||||
href="#"
|
||||
onClick={click_fn(rule)}
|
||||
class="tw-block tw-full-width tw-interactable tw-interactable--inverted tw-interactive tw-pd-05"
|
||||
onClick={click_fn(rule)}
|
||||
>
|
||||
{rule}
|
||||
</a>
|
||||
|
|
|
@ -1188,6 +1188,8 @@ export default class Chat extends Module {
|
|||
idx += split_chars(ret).length;
|
||||
out.push(ret);
|
||||
}
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
if ( ! emotes_only )
|
||||
|
|
|
@ -1006,8 +1006,9 @@ export const AddonEmotes = {
|
|||
modifiers = ds.modifierInfo;
|
||||
|
||||
let name, preview, source, owner, mods, fav_source, emote_id,
|
||||
plain_name = false,
|
||||
hide_source = ds.noSource === 'true';
|
||||
plain_name = false;
|
||||
|
||||
const hide_source = ds.noSource === 'true';
|
||||
|
||||
if ( modifiers && modifiers !== 'null' ) {
|
||||
mods = JSON.parse(modifiers).map(([set_id, emote_id]) => {
|
||||
|
|
|
@ -27,6 +27,8 @@ export default class Logviewer extends Module {
|
|||
const token = this._token;
|
||||
if ( token && token.token && token.expires > ((Date.now() / 1000) + 300) )
|
||||
return token.token;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
<div class="tw-flex-grow-1">
|
||||
<template v-if="! editing">
|
||||
<h4>{{ title }}</h4>
|
||||
<div class="description">{{ description }}</div>
|
||||
<div class="description">
|
||||
{{ description }}
|
||||
</div>
|
||||
<div v-if="canEdit" class="visibility tw-c-text-alt">
|
||||
{{ t('setting.actions.visible', 'visible: {list}', {list: visibility}) }}
|
||||
</div>
|
||||
|
@ -63,8 +65,8 @@
|
|||
</div>
|
||||
|
||||
<component
|
||||
v-if="renderer"
|
||||
:is="renderer.editor"
|
||||
v-if="renderer"
|
||||
v-model="edit_data.appearance"
|
||||
/>
|
||||
</section>
|
||||
|
@ -82,9 +84,15 @@
|
|||
v-model="edit_data.display.mod"
|
||||
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>
|
||||
<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>
|
||||
|
||||
|
@ -98,9 +106,15 @@
|
|||
v-model="edit_data.display.mod_icons"
|
||||
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.visible', 'Visible') }}</option>
|
||||
<option :value="false">{{ t('setting.hidden', 'Hidden') }}</option>
|
||||
<option :value="undefined" selected>
|
||||
{{ t('setting.unset', 'Unset') }}
|
||||
</option>
|
||||
<option :value="true">
|
||||
{{ t('setting.visible', 'Visible') }}
|
||||
</option>
|
||||
<option :value="false">
|
||||
{{ t('setting.hidden', 'Hidden') }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
@ -114,9 +128,15 @@
|
|||
v-model="edit_data.display.deleted"
|
||||
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>
|
||||
<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>
|
||||
|
||||
|
@ -129,8 +149,8 @@
|
|||
<div class="ffz--inline tw-flex">
|
||||
<div class="tw-pd-r-1 tw-checkbox">
|
||||
<input
|
||||
ref="key_ctrl"
|
||||
:id="'key_ctrl$' + id"
|
||||
ref="key_ctrl"
|
||||
:checked="edit_data.display.keys & 1"
|
||||
type="checkbox"
|
||||
class="tw-checkbox__input"
|
||||
|
@ -143,8 +163,8 @@
|
|||
|
||||
<div class="tw-pd-r-1 tw-checkbox">
|
||||
<input
|
||||
ref="key_shift"
|
||||
:id="'key_shift$' + id"
|
||||
ref="key_shift"
|
||||
:checked="edit_data.display.keys & 2"
|
||||
type="checkbox"
|
||||
class="tw-checkbox__input"
|
||||
|
@ -157,8 +177,8 @@
|
|||
|
||||
<div class="tw-pd-r-1 tw-checkbox">
|
||||
<input
|
||||
ref="key_alt"
|
||||
:id="'key_alt$' + id"
|
||||
ref="key_alt"
|
||||
:checked="edit_data.display.keys & 4"
|
||||
type="checkbox"
|
||||
class="tw-checkbox__input"
|
||||
|
@ -171,8 +191,8 @@
|
|||
|
||||
<div class="tw-pd-r-1 tw-checkbox">
|
||||
<input
|
||||
ref="key_meta"
|
||||
:id="'key_meta$' + id"
|
||||
ref="key_meta"
|
||||
:checked="edit_data.display.keys & 8"
|
||||
type="checkbox"
|
||||
class="tw-checkbox__input"
|
||||
|
@ -183,10 +203,6 @@
|
|||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tw-pd-t-05">
|
||||
Note: This currently requires Chat > Behavior > Freeze Chat Scrolling to be enabled.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
@ -215,14 +231,13 @@
|
|||
</div>
|
||||
|
||||
<component
|
||||
v-if="action_def && action_def.editor"
|
||||
:is="action_def.editor"
|
||||
v-if="action_def && action_def.editor"
|
||||
:value="edit_data.options"
|
||||
:defaults="action_def.defaults"
|
||||
:vars="vars"
|
||||
@input="onChangeAction($event)"
|
||||
/>
|
||||
|
||||
</section>
|
||||
</template>
|
||||
</div>
|
||||
|
@ -406,7 +421,7 @@ export default {
|
|||
|
||||
const def = this.display && this.data.actions[this.display.action];
|
||||
if ( ! def || ! def.description )
|
||||
return;
|
||||
return null;
|
||||
|
||||
const data = this.getData(),
|
||||
out = maybe_call(def.description, this, data, def),
|
||||
|
@ -414,6 +429,8 @@ export default {
|
|||
|
||||
if ( out )
|
||||
return this.t(i18n, out, data);
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
visibility() {
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
class="ffz-mod-icon mod-icon tw-c-text-alt-2 tw-font-size-4"
|
||||
>
|
||||
<component
|
||||
v-if="renderer && renderer.component"
|
||||
:is="renderer.component"
|
||||
v-if="renderer && renderer.component"
|
||||
:data="act.appearance"
|
||||
:color="color"
|
||||
/>
|
||||
|
|
|
@ -23,10 +23,9 @@
|
|||
</div>
|
||||
<div v-else>
|
||||
<addon
|
||||
v-for="addon in sorted_addons"
|
||||
v-if="shouldShow(addon)"
|
||||
:key="addon.id"
|
||||
v-for="addon in visible_addons"
|
||||
:id="addon.id"
|
||||
:key="addon.id"
|
||||
:addon="addon"
|
||||
:item="item"
|
||||
@navigate="navigate"
|
||||
|
@ -97,6 +96,10 @@ export default {
|
|||
},
|
||||
|
||||
computed: {
|
||||
visible_addons() {
|
||||
return this.sorted_addons.filter(addon => this.shouldShow(addon));
|
||||
},
|
||||
|
||||
sorted_addons() {
|
||||
const addons = this.item.getAddons();
|
||||
|
||||
|
|
|
@ -13,8 +13,7 @@
|
|||
</div>
|
||||
<ul v-else class="ffz--term-list tw-mg-t-05">
|
||||
<badge-term-editor
|
||||
v-for="term in val"
|
||||
v-if="term.t !== 'inherit'"
|
||||
v-for="term in terms"
|
||||
:key="term.id"
|
||||
:term="term.v"
|
||||
:badges="data"
|
||||
|
@ -53,6 +52,19 @@ export default {
|
|||
for(const val of this.val)
|
||||
if ( val.t === 'inherit' )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
terms() {
|
||||
const out = [];
|
||||
|
||||
if ( Array.isArray(this.val) )
|
||||
for(const term of this.val)
|
||||
if ( term && term.t !== 'inherit' )
|
||||
out.push(term);
|
||||
|
||||
return out;
|
||||
},
|
||||
|
||||
val() {
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
<select
|
||||
v-if="editing"
|
||||
v-model="edit_data.v"
|
||||
class="tw-block tw-full-width tw-border-radius-medium tw-font-size-6 tw-full-width tw-select tw-pd-x-1 tw-pd-y-05 tw-mg-y-05">
|
||||
class="tw-block tw-full-width tw-border-radius-medium tw-font-size-6 tw-full-width tw-select tw-pd-x-1 tw-pd-y-05 tw-mg-y-05"
|
||||
>
|
||||
<optgroup
|
||||
v-for="section in badges"
|
||||
:key="section.title"
|
||||
|
@ -180,6 +181,8 @@ export default {
|
|||
if ( badge.id === v )
|
||||
return badge;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -38,8 +38,8 @@
|
|||
class="ffz--badge-info tw-pd-y-1 tw-pd-r-1 tw-flex tw-checkbox"
|
||||
>
|
||||
<input
|
||||
:checked="badgeChecked(i.id)"
|
||||
:id="i.id"
|
||||
:checked="badgeChecked(i.id)"
|
||||
type="checkbox"
|
||||
class="tw-checkbox__input"
|
||||
@click="onChange(i.id, $event)"
|
||||
|
|
|
@ -13,8 +13,7 @@
|
|||
</div>
|
||||
<ul v-else class="ffz--term-list tw-mg-t-05">
|
||||
<term-editor
|
||||
v-for="term in val"
|
||||
v-if="term.t !== 'inherit'"
|
||||
v-for="term in terms"
|
||||
:key="term.id"
|
||||
:term="term.v"
|
||||
:colored="item.colored"
|
||||
|
@ -54,6 +53,19 @@ export default {
|
|||
for(const val of this.val)
|
||||
if ( val.t === 'inherit' )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
terms() {
|
||||
const out = [];
|
||||
|
||||
if ( Array.isArray(this.val) )
|
||||
for(const term of this.val)
|
||||
if ( term && term.t !== 'inherit' )
|
||||
out.push(term);
|
||||
|
||||
return out;
|
||||
},
|
||||
|
||||
val() {
|
||||
|
|
|
@ -232,6 +232,8 @@ export default {
|
|||
for(const val of this.val)
|
||||
if ( val.t === 'inherit' )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
sample_user() {
|
||||
|
|
|
@ -39,8 +39,7 @@
|
|||
</div>
|
||||
<ul v-else class="ffz--term-list tw-mg-t-05">
|
||||
<reason-editor
|
||||
v-for="reason in val"
|
||||
v-if="reason.t !== 'inherit'"
|
||||
v-for="reason in reasons"
|
||||
:key="reason.id"
|
||||
:reason="reason.v"
|
||||
@remove="remove(reason)"
|
||||
|
@ -74,10 +73,22 @@ export default {
|
|||
return ! this.val.length || this.val.length === 1 && this.hasInheritance;
|
||||
},
|
||||
|
||||
reasons() {
|
||||
const out = [];
|
||||
if ( Array.isArray(this.val) )
|
||||
for(const reason of this.val)
|
||||
if ( reason.t !== 'inherit' )
|
||||
out.push(reason);
|
||||
|
||||
return out;
|
||||
},
|
||||
|
||||
hasInheritance() {
|
||||
for(const val of this.val)
|
||||
if ( val.t === 'inherit' )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
val() {
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
<input
|
||||
v-if="showInput"
|
||||
ref="input"
|
||||
v-bind="$attrs"
|
||||
v-model="color"
|
||||
v-bind="$attrs"
|
||||
type="text"
|
||||
class="tw-block tw-border-radius-medium tw-font-size-6 tw-full-width tw-input tw-pd-l-1 tw-pd-r-3 tw-pd-y-05 tw-mg-y-05"
|
||||
autocapitalize="off"
|
||||
|
@ -22,7 +22,7 @@
|
|||
<figure v-else-if="color" :style="`background-color: ${color}`" />
|
||||
<figure v-else class="ffz-i-eyedropper" />
|
||||
</button>
|
||||
<div v-on-clickaway="closePicker" v-if="open" class="tw-absolute tw-z-default tw-right-0">
|
||||
<div v-if="open" v-on-clickaway="closePicker" class="tw-absolute tw-z-default tw-right-0">
|
||||
<chrome-picker :value="colors" @input="onPick" />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -39,8 +39,8 @@
|
|||
<figure v-else class="ffz-i-eyedropper" />
|
||||
</button>
|
||||
<div
|
||||
v-on-clickaway="closePicker"
|
||||
v-if="open"
|
||||
v-on-clickaway="closePicker"
|
||||
:class="{'ffz-bottom-100': openUp}"
|
||||
class="tw-absolute tw-z-default tw-balloon--up tw-balloon--right"
|
||||
>
|
||||
|
|
|
@ -13,8 +13,12 @@
|
|||
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>
|
||||
<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>
|
||||
|
||||
|
@ -29,7 +33,6 @@
|
|||
: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">
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
|
||||
<component
|
||||
:is="component"
|
||||
v-model="editing"
|
||||
:type="type"
|
||||
:filters="filters"
|
||||
:context="context"
|
||||
v-model="editing"
|
||||
/>
|
||||
|
||||
<div
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
<div class="ffz--home tw-flex tw-flex-nowrap">
|
||||
<div class="tw-flex-grow-1">
|
||||
<div class="tw-align-center">
|
||||
<h1 class="ffz-i-zreknarf ffz-i-pd-1">FrankerFaceZ</h1>
|
||||
<h1 class="ffz-i-zreknarf ffz-i-pd-1">
|
||||
FrankerFaceZ
|
||||
</h1>
|
||||
<span class="tw-c-text-alt">
|
||||
{{ t('home.tag-line', 'The Twitch Enhancement Suite') }}
|
||||
</span>
|
||||
|
@ -11,8 +13,6 @@
|
|||
<section class="tw-pd-t-1 tw-border-t tw-mg-t-1">
|
||||
<markdown :source="t('home.about', md)" />
|
||||
</section>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="tw-mg-l-1 tw-flex-shrink-0 tweet-column">
|
||||
<div class="tw-flex tw-mg-b-1">
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
class="ffz-dialog ffz-main-menu tw-elevation-3 tw-c-background-alt tw-c-text-base tw-border tw-flex tw-flex-nowrap tw-flex-column"
|
||||
>
|
||||
<header ref="header" class="tw-c-background-base tw-full-width tw-align-items-center tw-flex tw-flex-nowrap" @dblclick="maybeResize($event)">
|
||||
<h3 class="ffz-i-zreknarf ffz-i-pd-1">FrankerFaceZ</h3>
|
||||
<h3 class="ffz-i-zreknarf ffz-i-pd-1">
|
||||
FrankerFaceZ
|
||||
</h3>
|
||||
<div class="tw-flex-grow-1 tw-pd-x-2">
|
||||
<div class="tw-search-input">
|
||||
<label for="ffz-main-menu.search" class="tw-hide-accessible">{{ t('main-menu.search', 'Search Settings') }}</label>
|
||||
|
|
|
@ -6,8 +6,9 @@
|
|||
<section
|
||||
v-if="item.description"
|
||||
class="tw-pd-b-1"
|
||||
v-html="t(item.desc_i18n_key, item.description, item)"
|
||||
/>
|
||||
>
|
||||
<markdown :source="t(item.desc_i18n_key, item.description, item)" />
|
||||
</section>
|
||||
<div
|
||||
v-for="i in item.contents"
|
||||
:key="i.full_key"
|
||||
|
|
|
@ -57,8 +57,8 @@
|
|||
:class="{'ffz-unmatched-item': ! shouldShow(i)}"
|
||||
>
|
||||
<component
|
||||
ref="children"
|
||||
:is="i.component"
|
||||
ref="children"
|
||||
:context="context"
|
||||
:item="i"
|
||||
:filter="filter"
|
||||
|
|
|
@ -11,8 +11,7 @@
|
|||
@keyup.*="expandAll"
|
||||
>
|
||||
<li
|
||||
v-for="item in modal"
|
||||
v-if="shouldShow(item)"
|
||||
v-for="item in displayed"
|
||||
:key="item.full_key"
|
||||
:class="[currentItem === item ? 'active' : '']"
|
||||
role="presentation"
|
||||
|
@ -99,6 +98,10 @@ export default {
|
|||
computed: {
|
||||
tabIndex() {
|
||||
return this.root ? undefined : 0;
|
||||
},
|
||||
|
||||
displayed() {
|
||||
return this.modal.filter(item => this.shouldShow(item));
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -127,9 +127,9 @@
|
|||
</section>
|
||||
|
||||
<filter-editor
|
||||
v-model="rules"
|
||||
:filters="filters"
|
||||
:context="test_context"
|
||||
v-model="rules"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
{{ t(context.currentProfile.i18n_key, context.currentProfile.title, context.currentProfile) }}
|
||||
</div>
|
||||
<div
|
||||
v-on-clickaway="hide"
|
||||
v-if="opened"
|
||||
v-on-clickaway="hide"
|
||||
class="tw-balloon tw-block tw-balloon--lg tw-balloon--down tw-balloon--left"
|
||||
>
|
||||
<div
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
>
|
||||
<div class="tw-flex tw-align-items-center tw-checkbox">
|
||||
<input
|
||||
ref="control"
|
||||
:id="item.full_key"
|
||||
ref="control"
|
||||
:checked="value"
|
||||
type="checkbox"
|
||||
class="tw-checkbox__input"
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
</label>
|
||||
|
||||
<color-picker
|
||||
ref="control"
|
||||
:id="item.full_key"
|
||||
ref="control"
|
||||
:nullable="true"
|
||||
:value="color"
|
||||
@input="onInput"
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
|
||||
<div class="tw-flex tw-flex-column tw-mg-05">
|
||||
<select
|
||||
ref="control"
|
||||
:id="item.full_key"
|
||||
ref="control"
|
||||
class="tw-border-radius-medium tw-font-size-6 tw-select tw-pd-l-1 tw-pd-r-3 tw-pd-y-05"
|
||||
@change="onChange"
|
||||
>
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
<template lang="html">
|
||||
<div class="ffz--widget ffz--hotkey-input">
|
||||
<label
|
||||
:for="item.full_key"
|
||||
v-html="t(item.i18n_key, item.title, item)"
|
||||
/>
|
||||
<label :for="item.full_key">
|
||||
{{ t(item.i18n_key, item.title, item) }}
|
||||
</label>
|
||||
<div class="tw-relative">
|
||||
<div class="tw-input__icon-group tw-input__icon-group--right">
|
||||
<div class="tw-input__icon">
|
||||
|
@ -11,8 +10,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<div
|
||||
ref="display"
|
||||
:id="item.full_key"
|
||||
ref="display"
|
||||
type="text"
|
||||
class="tw-mg-05 tw-input tw-input--icon-right"
|
||||
tabindex="0"
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
</section>
|
||||
<div v-for="(i, idx) in data" :key="idx" class="tw-mg-l-1">
|
||||
<input
|
||||
:name="item.full_key"
|
||||
:id="item.full_key + idx"
|
||||
:name="item.full_key"
|
||||
:value="i.value"
|
||||
type="radio"
|
||||
class="tw-radio__input"
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
</label>
|
||||
|
||||
<select
|
||||
ref="control"
|
||||
:id="item.full_key"
|
||||
ref="control"
|
||||
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"
|
||||
>
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
</label>
|
||||
|
||||
<input
|
||||
ref="control"
|
||||
:id="item.full_key"
|
||||
ref="control"
|
||||
:value="value"
|
||||
class="tw-border-radius-medium tw-font-size-6 tw-pd-x-1 tw-pd-y-05 tw-mg-05 tw-input"
|
||||
@change="onChange"
|
||||
|
|
|
@ -42,10 +42,18 @@
|
|||
v-model="edit_data.t"
|
||||
class="tw-block tw-border-radius-medium tw-font-size-6 tw-select tw-pd-l-1 tw-pd-r-3 tw-pd-y-05 ffz-min-width-unset"
|
||||
>
|
||||
<option value="text">{{ t('setting.terms.type.text', 'Text') }}</option>
|
||||
<option value="glob">{{ t('setting.terms.type.glob', 'Glob') }}</option>
|
||||
<option v-if="words" value="regex">{{ t('setting.terms.type.regex-word', 'Regex (Word)') }}</option>
|
||||
<option value="raw">{{ t('setting.terms.type.regex', 'Regex') }}</option>
|
||||
<option value="text">
|
||||
{{ t('setting.terms.type.text', 'Text') }}
|
||||
</option>
|
||||
<option value="glob">
|
||||
{{ t('setting.terms.type.glob', 'Glob') }}
|
||||
</option>
|
||||
<option v-if="words" value="regex">
|
||||
{{ t('setting.terms.type.regex-word', 'Regex (Word)') }}
|
||||
</option>
|
||||
<option value="raw">
|
||||
{{ t('setting.terms.type.regex', 'Regex') }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div v-if="removable" class="tw-flex-shrink-0 tw-mg-r-05 tw-tooltip-wrapper">
|
||||
|
|
|
@ -172,7 +172,7 @@ export default class Metadata extends Module {
|
|||
return `${delayed}${data.delay.toFixed(2)}s`;
|
||||
},
|
||||
|
||||
click(data) {
|
||||
click() {
|
||||
const Player = this.resolve('site.player'),
|
||||
internal = Player.getInternalPlayer();
|
||||
|
||||
|
|
|
@ -60,8 +60,8 @@ export default class TooltipProvider extends Module {
|
|||
}
|
||||
|
||||
onEnable() {
|
||||
const container = document.querySelector('#root>div') || document.querySelector('#root') || document.querySelector('.clips-root') || document.body,
|
||||
is_minimal = false; //container && container.classList.contains('twilight-minimal-root');
|
||||
const container = document.querySelector('#root>div') || document.querySelector('#root') || document.querySelector('.clips-root') || document.body;
|
||||
// is_minimal = false; //container && container.classList.contains('twilight-minimal-root');
|
||||
|
||||
this.tips = new Tooltip(container, 'ffz-tooltip', {
|
||||
html: true,
|
||||
|
|
|
@ -124,7 +124,7 @@ export default {
|
|||
},
|
||||
|
||||
methods: {
|
||||
displayAction(action) {
|
||||
displayAction(action) { // eslint-disable-line no-unused-vars
|
||||
return true;
|
||||
},
|
||||
|
||||
|
|
|
@ -41,7 +41,9 @@
|
|||
</aspect>
|
||||
</div>
|
||||
<div class="tw-card-body tw-overflow-hidden tw-relative">
|
||||
<p class="tw-pd-x-1">{{ slot.item.displayName }}</p>
|
||||
<p class="tw-pd-x-1">
|
||||
{{ slot.item.displayName }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
</header>
|
||||
|
||||
<filter-editor
|
||||
v-model="value.data"
|
||||
:filters="filters"
|
||||
:context="context"
|
||||
:max-rules="type.maxRules"
|
||||
v-model="value.data"
|
||||
/>
|
||||
</section>
|
||||
</template>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
class="tw-flex-grow-1 tw-mg-l-1 tw-border-radius-medium tw-font-size-6 tw-pd-x-1 tw-pd-y-05 tw-select"
|
||||
>
|
||||
<option
|
||||
v-for="(route, key) in routes"
|
||||
v-for="(_, key) in routes"
|
||||
v-once
|
||||
:key="key"
|
||||
:value="key"
|
||||
|
@ -88,8 +88,7 @@ export default {
|
|||
try {
|
||||
return decodeURI(new URL(this.route.url(parts), location));
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
return null;
|
||||
return '(unable to render url)';
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
// ============================================================================
|
||||
|
||||
import {EventEmitter} from 'utilities/events';
|
||||
import {has, get as getter, array_equals, set_equals, map_equals, deep_copy} from 'utilities/object';
|
||||
import {has, get as getter, array_equals, set_equals, map_equals} from 'utilities/object';
|
||||
|
||||
import * as DEFINITIONS from './types';
|
||||
|
||||
|
|
|
@ -8,9 +8,7 @@ import {EventEmitter} from 'utilities/events';
|
|||
import {has} from 'utilities/object';
|
||||
import {createTester} from 'utilities/filtering';
|
||||
|
||||
const fetchJSON = (url, options) => {
|
||||
return fetch(url, options).then(r => r.ok ? r.json() : null).catch(() => null);
|
||||
}
|
||||
const fetchJSON = (url, options) => fetch(url, options).then(r => r.ok ? r.json() : null).catch(() => null);
|
||||
|
||||
/**
|
||||
* Instances of SettingsProfile are used for getting and setting raw settings
|
||||
|
@ -88,7 +86,7 @@ export default class SettingsProfile extends EventEmitter {
|
|||
if ( ! this.url )
|
||||
return false;
|
||||
|
||||
const data = fetchJSON(this.url);
|
||||
const data = await fetchJSON(this.url);
|
||||
if ( ! data || ! data.type === 'profile' || ! data.profile || ! data.values )
|
||||
return false;
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ import {createElement} from 'utilities/dom';
|
|||
|
||||
import MAIN_URL from 'site/styles/main.scss';
|
||||
|
||||
import Switchboard from './switchboard';
|
||||
//import Switchboard from './switchboard';
|
||||
|
||||
|
||||
// ============================================================================
|
||||
|
|
|
@ -41,7 +41,7 @@ export default class Line extends Module {
|
|||
this.chat.context.on('changed:tooltip.link-images', this.maybeUpdateLines, this);
|
||||
this.chat.context.on('changed:tooltip.link-nsfw-images', this.maybeUpdateLines, this);
|
||||
|
||||
this.ChatLine.ready((cls, instances) => {
|
||||
this.ChatLine.ready(cls => {
|
||||
const t = this,
|
||||
old_render = cls.prototype.render;
|
||||
|
||||
|
|
|
@ -29,10 +29,6 @@ export default class CSSTweaks extends Module {
|
|||
this.chunks_loaded = false;
|
||||
}
|
||||
|
||||
onEnable() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
toggleHide(key, val) {
|
||||
const k = `hide--${key}`;
|
||||
|
|
|
@ -38,7 +38,7 @@ export default class ThemeEngine extends Module {
|
|||
|
||||
this.settings.add('theme.can-dark', {
|
||||
requires: ['context.route.name'],
|
||||
process(ctx) {
|
||||
process() {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -59,15 +59,7 @@ export default class ChannelBar extends Module {
|
|||
)
|
||||
}
|
||||
|
||||
async onEnable() {
|
||||
/*const t = this,
|
||||
React = await this.web_munch.findModule('react');
|
||||
|
||||
if ( ! React )
|
||||
return;
|
||||
|
||||
//const createElement = React.createElement;*/
|
||||
|
||||
onEnable() {
|
||||
this.css_tweaks.toggle('channel-metadata-top', this.settings.get('channel.metadata.force-above'));
|
||||
|
||||
this.ChannelBar.on('unmount', this.unmountChannelBar, this);
|
||||
|
@ -75,59 +67,9 @@ export default class ChannelBar extends Module {
|
|||
this.ChannelBar.on('update', this.updateChannelBar, this);
|
||||
|
||||
this.ChannelBar.ready((cls, instances) => {
|
||||
/*const old_render = cls.prototype.render;
|
||||
|
||||
cls.prototype.render = function() {
|
||||
if ( this.props.channelIsHosting )
|
||||
return null;
|
||||
|
||||
const title = this.getTitle();
|
||||
|
||||
return (<div
|
||||
data-test-selector="channel-info-bar-wrapper"
|
||||
class="channel-info-bar tw-border-b tw-border-bottom-left-radius-large tw-border-bottom-right-radius-large tw-border-l tw-border-r tw-border-t tw-flex tw-flex-wrap tw-justify-content-between tw-lg-pd-b-0 tw-lg-pd-t-1 tw-lg-pd-x-1 tw-pd-1"
|
||||
>
|
||||
<div class="channel-info-bar__content-container tw-flex tw-full-width tw-justify-content-between tw-mg-b-1">
|
||||
<div class="tw-full-width">
|
||||
<div class="tw-flex">
|
||||
<div class="tw-flex tw-mg-t-05">
|
||||
{this.renderGameBoxArt()}
|
||||
</div>
|
||||
<div class="channel-info-bar__content-right tw-full-width">
|
||||
<div class="tw-flex tw-justify-content-between">
|
||||
<div class="tw-ellipsis tw-mg-b-05 tw-mg-r-2">
|
||||
<span
|
||||
class="tw-font-size-4"
|
||||
data-a-target="stream-title"
|
||||
data-test-selector="channel-info-bar-title-text"
|
||||
title={title}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>);
|
||||
}*/
|
||||
|
||||
for(const inst of instances) {
|
||||
//inst.forceUpdate();
|
||||
this.updateChannelBar(inst);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/*this.HostBar.on('unmount', this.unmountHostBar, this);
|
||||
this.HostBar.on('mount', this.updateHostBar, this);
|
||||
this.HostBar.on('update', this.updateHostBar, this);
|
||||
|
||||
this.HostBar.ready((cls, instances) => {
|
||||
for(const inst of instances)
|
||||
this.updateHostBar(inst);
|
||||
});*/
|
||||
this.updateChannelBar(inst);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -285,13 +285,13 @@ export default class EmoteMenu extends Module {
|
|||
<t.MenuComponent
|
||||
visible={this.props.visible}
|
||||
toggleVisibility={this.props.toggleVisibility}
|
||||
onClickEmote={this.props.onClickEmote}
|
||||
channel_data={this.props.channelData}
|
||||
emote_data={this.props.emoteSetsData}
|
||||
user_id={this.props.currentUserID}
|
||||
channel_id={this.props.channelOwnerID}
|
||||
loading={this.state.gqlLoading}
|
||||
error={this.state.gqlError}
|
||||
onClickEmote={this.props.onClickEmote}
|
||||
/>
|
||||
</t.MenuErrorWrapper>)
|
||||
}
|
||||
|
@ -575,7 +575,7 @@ export default class EmoteMenu extends Module {
|
|||
}
|
||||
}
|
||||
|
||||
return (<section ref={this.saveRef} onMouseEnter={this.mouseEnter} data-key={data.key} class={filtered ? 'filtered' : ''}>
|
||||
return (<section ref={this.saveRef} data-key={data.key} class={filtered ? 'filtered' : ''} onMouseEnter={this.mouseEnter}>
|
||||
{show_heading ? (<heading class="tw-pd-1 tw-border-b tw-flex tw-flex-nowrap" onClick={this.clickHeading}>
|
||||
{image}
|
||||
<div class="tw-pd-l-05">
|
||||
|
@ -1690,8 +1690,6 @@ export default class EmoteMenu extends Module {
|
|||
<input
|
||||
type="text"
|
||||
class="tw-block tw-border-radius-medium tw-font-size-6 tw-full-width tw-input tw-pd-x-1 tw-pd-y-05"
|
||||
onChange={this.handleFilterChange}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
placeholder={
|
||||
is_emoji ?
|
||||
t.i18n.t('emote-menu.search-emoji', 'Search for Emoji') :
|
||||
|
@ -1701,6 +1699,8 @@ export default class EmoteMenu extends Module {
|
|||
autoFocus
|
||||
autoCapitalize="off"
|
||||
autoCorrect="off"
|
||||
onChange={this.handleFilterChange}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
/>
|
||||
{is_emoji && <t.EmojiTonePicker
|
||||
tone={this.state.tone}
|
||||
|
|
|
@ -383,6 +383,8 @@ export default class ChatHook extends Module {
|
|||
for(const inst of this.ChatController.instances)
|
||||
if ( inst && inst.chatService )
|
||||
return inst;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ export default class ChatLine extends Module {
|
|||
if ( ! this.ffz_user_click_handler )
|
||||
this.ffz_user_click_handler = this.props.onUsernameClick;
|
||||
|
||||
let cls = `chat-line__message${show_class ? ' ffz--deleted-message' : ''}`,
|
||||
const cls = `chat-line__message${show_class ? ' ffz--deleted-message' : ''}`,
|
||||
out = (tokens.length || ! msg.ffz_type) ? [
|
||||
this.props.showTimestamps && e('span', {
|
||||
className: 'chat-line__timestamp'
|
||||
|
|
|
@ -21,13 +21,13 @@ export default class BrowsePopular extends SiteModule {
|
|||
this.apollo.registerModifier('BrowsePage_Popular', res => this.modifyStreams(res), false);
|
||||
}
|
||||
|
||||
onEnable() {
|
||||
/*onEnable() {
|
||||
// Popular Directory Channel Cards
|
||||
/*this.apollo.ensureQuery(
|
||||
this.apollo.ensureQuery(
|
||||
'BrowsePage_Popular',
|
||||
'data.streams.edges.0.node.createdAt'
|
||||
);*/
|
||||
}
|
||||
);
|
||||
}*/
|
||||
|
||||
modifyStreams(res) { // eslint-disable-line class-methods-use-this
|
||||
const edges = get('data.streams.edges', res);
|
||||
|
|
|
@ -233,11 +233,11 @@ export default class Directory extends SiteModule {
|
|||
channel_url = `/${channel.login}`,
|
||||
game_url = game && `/directory/game/${stream.game.name}`,
|
||||
|
||||
user_link = <a href={channel_url} data-href={channel_url} onClick={t.routeClick} title={channel.displayName} class="tw-link tw-link--inherit">{channel.displayName}</a>,
|
||||
game_link = game && <a href={game_url} data-href={game_url} onClick={t.routeClick} title={game.name} class="tw-link tw-link--inherit">{game.name}</a>;
|
||||
user_link = <a href={channel_url} data-href={channel_url} title={channel.displayName} class="tw-link tw-link--inherit" onClick={t.routeClick}>{channel.displayName}</a>,
|
||||
game_link = game && <a href={game_url} data-href={game_url} title={game.name} class="tw-link tw-link--inherit" onClick={t.routeClick}>{game.name}</a>;
|
||||
|
||||
return (<div>
|
||||
<a href={channel_url} data-href={channel_url} onClick={t.routeClick} class="tw-link tw-link--inherit" data-test-selector="preview-card-titles__primary-link">
|
||||
<a href={channel_url} data-href={channel_url} class="tw-link tw-link--inherit" data-test-selector="preview-card-titles__primary-link" onClick={t.routeClick}>
|
||||
<h3 class="tw-ellipsis tw-font-size-5 tw-strong" title={stream.title}>{stream.title}</h3>
|
||||
</a>
|
||||
<div class="preview-card-titles__subtitle-wrapper">
|
||||
|
@ -261,7 +261,7 @@ export default class Directory extends SiteModule {
|
|||
nodes.length > 1 ?
|
||||
t.i18n.t('directory.hosted.by-many', 'Hosted by {count,number} channel{count,en_plural}', nodes.length) :
|
||||
t.i18n.tList('directory.hosted.by-one', 'Hosted by {user}', {
|
||||
user: <a href={`/${nodes[0].login}`} data-href={`/${nodes[0].login}`} onClick={t.routeClick} title={nodes[0].displayName} class="tw-link tw-link--inherit">{nodes[0].displayName}</a>
|
||||
user: <a href={`/${nodes[0].login}`} data-href={`/${nodes[0].login}`} title={nodes[0].displayName} class="tw-link tw-link--inherit" onClick={t.routeClick}>{nodes[0].displayName}</a>
|
||||
})
|
||||
}</p>
|
||||
</div>
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
<header class="tw-full-width tw-align-items-center tw-flex tw-flex-nowrap">
|
||||
<h4>{{ t('metadata.featured-follow.title', 'Featured Channels') }}</h4>
|
||||
|
||||
<div class="tw-flex-grow-1 tw-pd-x-2"/>
|
||||
<div class="tw-flex-grow-1 tw-pd-x-2" />
|
||||
<button
|
||||
v-if="hasUpdate"
|
||||
class="ffz--featured-follow-update tw-button tw-button--hollow"
|
||||
@click="refresh"
|
||||
>
|
||||
<span class="tw-button__icon tw-button__icon--left">
|
||||
<figure class="ffz-i-arrows-cw"/>
|
||||
<figure class="ffz-i-arrows-cw" />
|
||||
</span>
|
||||
<span class="tw-button__text tw-pd-l-0">
|
||||
Refresh
|
||||
|
@ -27,7 +27,7 @@
|
|||
<a :href="'/' + user.login" :title="user.login" @click.prevent="route(user.login)"><img :src="user.avatar"></a>
|
||||
</div>
|
||||
<a :href="'/' + user.login" :title="user.login" @click.prevent="route(user.login)"><p class="tw-ellipsis tw-flex-grow-1 tw-mg-l-1 tw-font-size-5">{{ user.displayName }}</p></a>
|
||||
<div class="tw-flex-grow-1 tw-pd-x-2"/>
|
||||
<div class="tw-flex-grow-1 tw-pd-x-2" />
|
||||
|
||||
<div v-if="user.error">
|
||||
{{ t('featured-follow.error', 'An error occured.') }}
|
||||
|
@ -43,7 +43,7 @@
|
|||
@click="clickWithTip($event, unfollowUser, user.id)"
|
||||
>
|
||||
<span class="tw-button__icon tw-button__icon--status tw-flex">
|
||||
<figure class="ffz-i-heart ffz--featured-button-unfollow-button"/>
|
||||
<figure class="ffz-i-heart ffz--featured-button-unfollow-button" />
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
|
@ -56,7 +56,7 @@
|
|||
@click="clickWithTip($event, updateNotificationStatus, user.id, user.disableNotifications)"
|
||||
>
|
||||
<span class="tw-button__icon tw-flex">
|
||||
<figure :class="{ 'ffz-i-bell': !user.disableNotifications, 'ffz-i-bell-off': user.disableNotifications }"/>
|
||||
<figure :class="{ 'ffz-i-bell': !user.disableNotifications, 'ffz-i-bell-off': user.disableNotifications }" />
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
|
@ -67,7 +67,7 @@
|
|||
@click="followUser(user.id)"
|
||||
>
|
||||
<span class="tw-button__icon tw-button__icon--left">
|
||||
<figure class="ffz-i-heart"/>
|
||||
<figure class="ffz-i-heart" />
|
||||
</span>
|
||||
<span class="tw-button__text">
|
||||
{{ t('featured-follow.button.follow', 'Follow') }}
|
||||
|
|
|
@ -32,7 +32,9 @@
|
|||
<div class="ffz-channel-avatar">
|
||||
<img :src="host.logo" :alt="host.display_name + '(' + host.name + ')'">
|
||||
</div>
|
||||
<p class="tw-ellipsis tw-flex-grow-1 tw-mg-l-1 tw-font-size-5">{{ host.name }}</p>
|
||||
<p class="tw-ellipsis tw-flex-grow-1 tw-mg-l-1 tw-font-size-5">
|
||||
{{ host.name }}
|
||||
</p>
|
||||
<div class="tw-flex-grow-1 tw-pd-x-2" />
|
||||
<button class="tw-button-icon tw-mg-x-05 ffz--host-remove-user" @click="removeFromHosts">
|
||||
<figure class="ffz-i-trash" />
|
||||
|
@ -101,7 +103,7 @@
|
|||
<section class="tw-c-text-alt-2 ffz-checkbox-description">
|
||||
{{ t('metadata.host.setting.team-hosting.description',
|
||||
"Automatically host random channels from your team when you're not live. " +
|
||||
'Team channels will be hosted before any channels in your host list.') }}
|
||||
'Team channels will be hosted before any channels in your host list.') }}
|
||||
</section>
|
||||
</div>
|
||||
<div class="ffz--widget ffz--checkbox">
|
||||
|
@ -158,7 +160,7 @@
|
|||
<section class="tw-c-text-alt-2 ffz-checkbox-description">
|
||||
{{ t('metadata.host.setting.strategy.description',
|
||||
'If enabled, auto-hosts will be picked at random. ' +
|
||||
"Otherwise they're picked in order.") }}
|
||||
"Otherwise they're picked in order.") }}
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -777,5 +777,7 @@ export default class Player extends Module {
|
|||
for(const inst of this.Player.instances)
|
||||
if ( inst && inst.player )
|
||||
return inst.player;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -8,9 +8,9 @@
|
|||
</div>
|
||||
<input
|
||||
:id="_id"
|
||||
v-model="search"
|
||||
:placeholder="placeholder"
|
||||
:class="[hasIcon ? 'tw-pd-l-3' : 'tw-pd-l-1']"
|
||||
v-model="search"
|
||||
type="search"
|
||||
class="tw-block tw-border-radius-medium tw-font-size-6 tw-full-width tw-input tw-pd-r-1 tw-pd-y-05"
|
||||
autocapitalize="off"
|
||||
|
@ -43,8 +43,8 @@
|
|||
</div>
|
||||
<button
|
||||
v-for="(item, idx) of filteredItems"
|
||||
:key="has(item, 'id') ? item.id : idx"
|
||||
:id="'ffz-autocomplete-item-' + id + '-' + idx"
|
||||
:key="has(item, 'id') ? item.id : idx"
|
||||
:class="{'tw-interactable--hover' : idx === index}"
|
||||
class="tw-block tw-full-width tw-interactable tw-interactable--inverted tw-interactive"
|
||||
tabindex="-1"
|
||||
|
@ -125,6 +125,10 @@ export default {
|
|||
type: String,
|
||||
required: false,
|
||||
default: 'down'
|
||||
},
|
||||
logger: {
|
||||
type: Object,
|
||||
required: false
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -227,7 +231,10 @@ export default {
|
|||
try {
|
||||
result = this.items(this.search);
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
if ( this.logger )
|
||||
this.logger.capture(err);
|
||||
else
|
||||
console.error(err); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
if ( result instanceof Promise ) {
|
||||
|
@ -236,7 +243,11 @@ export default {
|
|||
this.loading = false;
|
||||
this.cachedItems = items;
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
if ( this.logger )
|
||||
this.logger.capture(err);
|
||||
else
|
||||
console.error(err); // eslint-disable-line no-console
|
||||
|
||||
this.loading = false;
|
||||
this.errored = true;
|
||||
this.cachedItems = [];
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
>
|
||||
<div
|
||||
v-for="(i, idx) in item.tabs"
|
||||
:key="i.full_key"
|
||||
:id="'tab-for-' + i.full_key"
|
||||
:key="i.full_key"
|
||||
:aria-selected="selected === idx"
|
||||
:aria-controls="'tab-panel-' + i.full_key"
|
||||
:class="{'active': selected === idx, 'ffz-unmatched-item': showing && ! shouldShow(i)}"
|
||||
|
|
|
@ -7,16 +7,16 @@ export function generateUUID(input) {
|
|||
return input // if the placeholder was passed, return
|
||||
? ( // a random number from 0 to 15
|
||||
input ^ // unless b is 8,
|
||||
Math.random() // in which case
|
||||
* 16 // a random number from
|
||||
>> input/4 // 8 to 11
|
||||
Math.random() // in which case
|
||||
* 16 // a random number from
|
||||
>> input/4 // 8 to 11
|
||||
).toString(16) // in hexadecimal
|
||||
: ( // or otherwise a concatenated string:
|
||||
[1e7] + // 10000000 +
|
||||
-1e3 + // -1000 +
|
||||
-4e3 + // -4000 +
|
||||
-8e3 + // -80000000 +
|
||||
-1e11 // -100000000000,
|
||||
[1e7] + // 10000000 +
|
||||
-1e3 + // -1000 +
|
||||
-4e3 + // -4000 +
|
||||
-8e3 + // -80000000 +
|
||||
-1e11 // -100000000000,
|
||||
).replace( // replacing
|
||||
/[018]/g, // zeroes, ones, and eights with
|
||||
generateUUID // random hex digits
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue