1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-27 21:05:53 +00:00
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:
SirStendec 2019-06-20 15:15:54 -04:00
parent 014eb203c3
commit 33e81bc7eb
60 changed files with 238 additions and 209 deletions

View file

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

View file

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

View file

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

View file

@ -14,8 +14,7 @@ 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 => {
transformText = (ast, fn) => ast.map(node => {
if ( typeof node === 'string' )
return fn(node);
@ -26,8 +25,7 @@ const FACES = ['(・`ω´・)', ';;w;;', 'owo', 'ono', 'oAo', 'oxo', 'ovo;', 'Uw
}
return node;
})
},
}),
owo = text => text
.replace(/(?:r|l)/g, 'w')

View file

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

View file

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

View file

@ -1188,6 +1188,8 @@ export default class Chat extends Module {
idx += split_chars(ret).length;
out.push(ret);
}
first = false;
}
if ( ! emotes_only )

View file

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

View file

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

View file

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

View file

@ -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"
/>

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -232,6 +232,8 @@ export default {
for(const val of this.val)
if ( val.t === 'inherit' )
return true;
return false;
},
sample_user() {

View file

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

View file

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

View file

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

View file

@ -6,10 +6,10 @@
<component
:is="component"
v-model="editing"
:type="type"
:filters="filters"
:context="context"
v-model="editing"
/>
<div

View file

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

View file

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

View file

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

View file

@ -57,8 +57,8 @@
:class="{'ffz-unmatched-item': ! shouldShow(i)}"
>
<component
ref="children"
:is="i.component"
ref="children"
:context="context"
:item="i"
:filter="filter"

View file

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

View file

@ -127,9 +127,9 @@
</section>
<filter-editor
v-model="rules"
:filters="filters"
:context="test_context"
v-model="rules"
/>
</div>
</div>

View file

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

View file

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

View file

@ -10,8 +10,8 @@
</label>
<color-picker
ref="control"
:id="item.full_key"
ref="control"
:nullable="true"
:value="color"
@input="onInput"

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -124,7 +124,7 @@ export default {
},
methods: {
displayAction(action) {
displayAction(action) { // eslint-disable-line no-unused-vars
return true;
},

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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';
// ============================================================================

View file

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

View file

@ -29,10 +29,6 @@ export default class CSSTweaks extends Module {
this.chunks_loaded = false;
}
onEnable() {
}
toggleHide(key, val) {
const k = `hide--${key}`;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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" />

View file

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

View file

@ -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 = [];

View file

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