mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-27 21:05:53 +00:00
The Big Linting Commit.
* Add linting for Vue files. * Fix a bunch of linting problems in Vue files. * Update README with notes about configuring editors.
This commit is contained in:
parent
8dbcf434cd
commit
f9f5f0affa
23 changed files with 1114 additions and 971 deletions
25
.eslintrc.js
25
.eslintrc.js
|
@ -3,9 +3,13 @@ module.exports = {
|
|||
"browser": true,
|
||||
"es6": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"parser": "babel-eslint",
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:vue/recommended"
|
||||
],
|
||||
"plugins": ["vue"],
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint",
|
||||
"ecmaVersion": 8,
|
||||
"sourceType": "module"
|
||||
},
|
||||
|
@ -62,6 +66,7 @@ module.exports = {
|
|||
"no-useless-constructor": ["error"],
|
||||
"no-useless-rename": ["error"],
|
||||
"no-var": ["error"],
|
||||
"no-cond-assign": ["warn"],
|
||||
"object-shorthand": ["warn"],
|
||||
"prefer-arrow-callback": ["warn", {"allowUnboundThis": true}],
|
||||
"prefer-const": ["warn", {"ignoreReadBeforeAssign": true}],
|
||||
|
@ -72,7 +77,7 @@ module.exports = {
|
|||
"yield-star-spacing": ["warn"],
|
||||
|
||||
"indent": [
|
||||
"error",
|
||||
"warn",
|
||||
"tab",
|
||||
{
|
||||
"SwitchCase": 1
|
||||
|
@ -89,6 +94,20 @@ module.exports = {
|
|||
"avoidEscape": true,
|
||||
"allowTemplateLiterals": true
|
||||
}
|
||||
],
|
||||
"vue/html-indent": [
|
||||
"warn",
|
||||
"tab"
|
||||
],
|
||||
"vue/max-attributes-per-line": "off",
|
||||
"vue/require-prop-types": "off",
|
||||
"vue/require-default-prop": "off",
|
||||
"vue/html-closing-bracket-newline": [
|
||||
"error",
|
||||
{
|
||||
"singleline": "never",
|
||||
"multiline": "always"
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
37
README.md
37
README.md
|
@ -1,7 +1,7 @@
|
|||
FrankerFaceZ
|
||||
============
|
||||
|
||||
Copyright (c) 2017 Dan Salvato LLC
|
||||
Copyright (c) 2018 Dan Salvato LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0. See LICENSE.
|
||||
|
||||
|
@ -13,17 +13,40 @@ FrankerFaceZ uses node.js to manage development dependencies and to run an HTTP
|
|||
server for development. To get everything you need:
|
||||
|
||||
1. Install node.js and npm
|
||||
2. Run ```npm install``` within the FrankerFaceZ directory.
|
||||
2. Run `npm install` within the FrankerFaceZ directory.
|
||||
|
||||
|
||||
From there, you can use npm to build the extension from source simply by
|
||||
running ```npm run build```. For development, you can instruct gulp to watch
|
||||
the source files for changes and re-build automatically with ```npm start```
|
||||
From there, you can use npm to build FrankerFaceZ from source simply by
|
||||
running `npm run build`. For development, you can instruct gulp to watch
|
||||
the source files for changes and re-build automatically with `npm start`
|
||||
|
||||
FrankerFaceZ comes with a local development server that listens on port 8000
|
||||
and it serves up local development copies of files, falling back to the CDN
|
||||
when a local copy of a file isn't present.
|
||||
|
||||
To make FrankerFaceZ load from your local development server, you must set
|
||||
the local storage variable ```ffzDebugMode``` to true. Just run the following
|
||||
in your console on Twitch: ```localStorage.ffzDebugMode = true;```
|
||||
the local storage variable `ffzDebugMode` to true. Just run the following
|
||||
in your console on Twitch: `localStorage.ffzDebugMode = true;`
|
||||
|
||||
It should be noted that this project is not a browser extension that you
|
||||
would load in your browser's extensions system. You still need the FrankerFaceZ
|
||||
extension or user-script for your browser.
|
||||
|
||||
|
||||
Editor Settings
|
||||
===============
|
||||
|
||||
Please make sure that your editor is configured to use tabs rather than spaces
|
||||
for indentation and that lines are ended with `\n`. It's recommended that you
|
||||
configure linting support for your editor as well.
|
||||
|
||||
If you're using Visual Studio Code, make sure to install the ESLint extension
|
||||
and add the following to your workspace settings:
|
||||
|
||||
```json
|
||||
{
|
||||
"eslint.validate": [
|
||||
"javascript",
|
||||
"vue"
|
||||
]
|
||||
}```
|
23
package-lock.json
generated
23
package-lock.json
generated
|
@ -3037,6 +3037,15 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"eslint-plugin-vue": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-4.4.0.tgz",
|
||||
"integrity": "sha512-UHeE0aTEv9A/9xe8J6X7rDLMbwV6GuQFKAscMyLEv49Y4wK4KwQiifr2X0MsNsVlmccrDUyjI9KO4DuFTkPP9A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"vue-eslint-parser": "2.0.3"
|
||||
}
|
||||
},
|
||||
"eslint-scope": {
|
||||
"version": "3.7.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
|
||||
|
@ -9358,6 +9367,20 @@
|
|||
"loose-envify": "1.3.1"
|
||||
}
|
||||
},
|
||||
"vue-eslint-parser": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-2.0.3.tgz",
|
||||
"integrity": "sha512-ZezcU71Owm84xVF6gfurBQUGg8WQ+WZGxgDEQu1IHFBZNx7BFZg3L1yHxrCBNNwbwFtE1GuvfJKMtb6Xuwc/Bw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "3.1.0",
|
||||
"eslint-scope": "3.7.1",
|
||||
"eslint-visitor-keys": "1.0.0",
|
||||
"espree": "3.5.4",
|
||||
"esquery": "1.0.0",
|
||||
"lodash": "4.17.4"
|
||||
}
|
||||
},
|
||||
"vue-hot-reload-api": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.0.tgz",
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"main": "script.js",
|
||||
"scripts": {
|
||||
"start": "webpack-dev-server --config webpack.web.dev.js",
|
||||
"eslint": "eslint \"src/**/*.{js,vue}\"",
|
||||
"build": "webpack --config webpack.web.prod.js --define process.env.NODE_ENV='production'",
|
||||
"build:babel": "webpack --config webpack.web.babel.js --define process.env.NODE_ENV='production'",
|
||||
"build:prod": "webpack --config webpack.web.prod.js --define process.env.NODE_ENV='production'",
|
||||
|
@ -22,6 +23,7 @@
|
|||
"copy-webpack-plugin": "^4.5.1",
|
||||
"css-loader": "^0.28.10",
|
||||
"eslint": "^4.18.2",
|
||||
"eslint-plugin-vue": "^4.4.0",
|
||||
"extract-loader": "^1.0.2",
|
||||
"file-loader": "^1.1.11",
|
||||
"less": "^2.7.3",
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<template lang="html">
|
||||
<div class="ffz--badge-visibility tw-pd-t-05">
|
||||
<div class="ffz--badge-visibility tw-pd-t-05">
|
||||
<div
|
||||
class="tw-c-background-accent tw-c-text-overlay tw-pd-1 tw-mg-b-1"
|
||||
v-if="source && source !== profile"
|
||||
class="tw-c-background-accent tw-c-text-overlay tw-pd-1 tw-mg-b-1"
|
||||
>
|
||||
<span class="ffz-i-info" />
|
||||
{{ t('setting.badge-inheritence', 'These values are being overridden by another profile and may not take effect.') }}
|
||||
|
@ -10,9 +10,9 @@
|
|||
|
||||
<div class="tw-mg-b-2 tw-align-right">
|
||||
<button
|
||||
:disabled="! has_value"
|
||||
class="tw-mg-l-05 tw-button tw-button--hollow tw-tooltip-wrapper"
|
||||
@click="clear"
|
||||
:disabled="! has_value"
|
||||
>
|
||||
<span class="tw-button__icon tw-button__icon--left">
|
||||
<figure class="ffz-i-cancel" />
|
||||
|
@ -23,24 +23,46 @@
|
|||
</button>
|
||||
</div>
|
||||
|
||||
<section class="ffz--menu-container tw-border-t" v-for="sec in data">
|
||||
<section
|
||||
v-for="sec in data"
|
||||
:key="sec.title"
|
||||
class="ffz--menu-container tw-border-t"
|
||||
>
|
||||
<header>{{ sec.title }}</header>
|
||||
<ul class="tw-flex tw-flex-wrap tw-align-content-start">
|
||||
<li v-for="i in sort(sec.badges)" class="ffz--badge-info tw-pd-y-1 tw-pd-r-1 tw-flex" :class="{default: badgeDefault(i.id)}">
|
||||
<li
|
||||
v-for="i in sort(sec.badges)"
|
||||
:key="i.id"
|
||||
:class="{default: badgeDefault(i.id)}"
|
||||
class="ffz--badge-info tw-pd-y-1 tw-pd-r-1 tw-flex"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
class="tw-checkbox__input"
|
||||
:checked="badgeChecked(i.id)"
|
||||
:id="i.id"
|
||||
type="checkbox"
|
||||
class="tw-checkbox__input"
|
||||
@click="onChange(i.id, $event)"
|
||||
>
|
||||
|
||||
<label class="tw-checkbox__label tw-flex" :for="i.id">
|
||||
<div class="preview-image ffz-badge tw-mg-r-1 tw-flex-shrink-0" :style="{backgroundColor: i.color, backgroundImage: i.styleImage }" />
|
||||
<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 class="tw-mg-t-05" v-if="i.versions && i.versions.length > 1">
|
||||
<span v-for="v in i.versions" data-tooltip-type="html" class="ffz-badge ffz-tooltip" :title="v.name" :style="{backgroundColor: i.color, backgroundImage: v.styleImage}" />
|
||||
<section
|
||||
v-if="i.versions && i.versions.length > 1"
|
||||
class="tw-mg-t-05"
|
||||
>
|
||||
<span
|
||||
v-for="v in i.versions"
|
||||
:key="v.name"
|
||||
: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 tw-button--hollow tw-tooltip-wrapper"
|
||||
|
@ -56,7 +78,7 @@
|
|||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
<template lang="html">
|
||||
<div class="ffz--changelog tw-border-t tw-pd-t-1">
|
||||
<div class="ffz--changelog tw-border-t tw-pd-t-1">
|
||||
<div class="tw-align-center">
|
||||
<h2>{{ t('home.changelog', 'Changelog') }}</h2>
|
||||
</div>
|
||||
|
||||
<div ref="changes" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
|
@ -17,6 +16,10 @@ import {SERVER} from 'utilities/constants';
|
|||
export default {
|
||||
props: ['item', 'context'],
|
||||
|
||||
mounted() {
|
||||
this.fetch(`${SERVER}/script/changelog.html`, this.$refs.changes);
|
||||
},
|
||||
|
||||
methods: {
|
||||
fetch(url, container) {
|
||||
const done = data => {
|
||||
|
@ -38,13 +41,8 @@ export default {
|
|||
fetch(url)
|
||||
.then(resp => resp.ok ? resp.text() : null)
|
||||
.then(done)
|
||||
.catch(err => done(null));
|
||||
.catch(() => done(null));
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.fetch(`${SERVER}/script/changelog.html`, this.$refs.changes);
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
|
@ -1,5 +1,5 @@
|
|||
<template lang="html">
|
||||
<div class="ffz--home tw-border-t tw-pd-t-1">
|
||||
<div class="ffz--home tw-border-t tw-pd-t-1">
|
||||
<h2>Feedback</h2>
|
||||
|
||||
<div class="tw-mg-y-1 tw-c-background-accent tw-c-text-overlay tw-pd-1">
|
||||
|
@ -21,15 +21,12 @@
|
|||
When creating a GitHub issue, please check that someone else hasn't
|
||||
already created one for what you'd like to discuss or report.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
props: ['item', 'context'],
|
||||
|
||||
}
|
||||
</script>
|
|
@ -1,5 +1,5 @@
|
|||
<template lang="html">
|
||||
<div class="ffz--widget ffz--filter-editor">
|
||||
<div class="ffz--widget ffz--filter-editor">
|
||||
<div ref="list" class="ffz--rule-list">
|
||||
<section v-for="(rule, idx) in rules">
|
||||
<div
|
||||
|
@ -26,7 +26,7 @@
|
|||
type="text"
|
||||
class="tw-input"
|
||||
value="SirStendec"
|
||||
/>
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -49,7 +49,7 @@
|
|||
{{ t('', 'Add New Rule') }}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template lang="html">
|
||||
<div class="ffz--home tw-flex tw-flex-nowrap">
|
||||
<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>
|
||||
|
@ -66,7 +66,7 @@
|
|||
Tweets by FrankerFaceZ
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
<template lang="html">
|
||||
<div class="ffz-main-menu tw-elevation-3 tw-c-background-alt tw-c-text tw-border tw-flex tw-flex-nowrap tw-flex-column" :class="{ maximized: maximized || exclusive, exclusive }">
|
||||
<div
|
||||
:class="{ maximized: maximized || exclusive, exclusive }"
|
||||
class="ffz-main-menu tw-elevation-3 tw-c-background-alt tw-c-text tw-border tw-flex tw-flex-nowrap tw-flex-column"
|
||||
>
|
||||
<header class="tw-c-background tw-full-width tw-align-items-center tw-flex tw-flex-nowrap" @dblclick="resize">
|
||||
<h3 class="ffz-i-zreknarf ffz-i-pd-1">FrankerFaceZ</h3>
|
||||
<div class="tw-flex-grow-1 tw-pd-x-2">
|
||||
|
@ -15,12 +18,12 @@
|
|||
</div>
|
||||
</div-->
|
||||
</div>
|
||||
<button class="tw-button-icon tw-mg-x-05" @click="resize" v-if="!exclusive">
|
||||
<button v-if="!exclusive" class="tw-button-icon tw-mg-x-05" @click="resize">
|
||||
<span class="tw-button-icon__icon">
|
||||
<figure :class="{'ffz-i-window-maximize': !maximized, 'ffz-i-window-restore': maximized}" />
|
||||
</span>
|
||||
</button>
|
||||
<button class="tw-button-icon tw-mg-x-05" @click="close" v-if="!exclusive">
|
||||
<button v-if="!exclusive" class="tw-button-icon tw-mg-x-05" @click="close">
|
||||
<span class="tw-button-icon__icon">
|
||||
<figure class="ffz-i-window-close" />
|
||||
</span>
|
||||
|
@ -39,7 +42,7 @@
|
|||
<div class="simplebar-scroll-content">
|
||||
<div class="simplebar-content">
|
||||
<menu-tree
|
||||
:currentItem="currentItem"
|
||||
:current-item="currentItem"
|
||||
:modal="nav"
|
||||
@change-item="changeItem"
|
||||
@navigate="navigate"
|
||||
|
@ -53,7 +56,7 @@
|
|||
{{ t('main-menu.version', 'Version %{version}', {version: version.toString()}) }}
|
||||
</div>
|
||||
<div class="tw-c-text-alt-2">
|
||||
{{version.build}}
|
||||
{{ version.build }}
|
||||
</div>
|
||||
</footer>
|
||||
</nav>
|
||||
|
@ -61,18 +64,18 @@
|
|||
<div class="simplebar-scroll-content">
|
||||
<div class="simplebar-content">
|
||||
<menu-page
|
||||
v-if="currentItem"
|
||||
ref="page"
|
||||
:context="context"
|
||||
:item="currentItem"
|
||||
@change-item="changeItem"
|
||||
@navigate="navigate"
|
||||
v-if="currentItem"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -84,6 +87,12 @@ export default {
|
|||
return this.$vnode.data;
|
||||
},
|
||||
|
||||
watch: {
|
||||
maximized() {
|
||||
this.updateDrag();
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.context.context._add_user();
|
||||
},
|
||||
|
@ -92,6 +101,22 @@ export default {
|
|||
this.context.context._remove_user();
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.updateDrag();
|
||||
|
||||
this._on_resize = this.handleResize.bind(this);
|
||||
window.addEventListener('resize', this._on_resize);
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.destroyDrag();
|
||||
|
||||
if ( this._on_resize ) {
|
||||
window.removeEventListener('resize', this._on_resize);
|
||||
this._on_resize = null;
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
changeProfile() {
|
||||
const new_id = this.$refs.profiles.value,
|
||||
|
@ -153,28 +178,6 @@ export default {
|
|||
|
||||
this.changeItem(item);
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
maximized() {
|
||||
this.updateDrag();
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.updateDrag();
|
||||
|
||||
this._on_resize = this.handleResize.bind(this);
|
||||
window.addEventListener('resize', this._on_resize);
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.destroyDrag();
|
||||
|
||||
if ( this._on_resize ) {
|
||||
window.removeEventListener('resize', this._on_resize);
|
||||
this._on_resize = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,21 +1,21 @@
|
|||
<template lang="html">
|
||||
<div v-bind:class="classes" v-if="item.contents">
|
||||
<div v-if="item.contents" :class="classes">
|
||||
<header v-if="! item.no_header">
|
||||
{{ t(item.i18n_key, item.title, item) }}
|
||||
</header>
|
||||
<section
|
||||
v-if="item.description"
|
||||
v-html="t(item.desc_i18n_key, item.description, item)"
|
||||
class="tw-pd-b-1"
|
||||
v-html="t(item.desc_i18n_key, item.description, item)"
|
||||
/>
|
||||
<component
|
||||
v-for="i in item.contents"
|
||||
v-bind:is="i.component"
|
||||
:is="i.component"
|
||||
:context="context"
|
||||
:item="i"
|
||||
:key="i.full_key"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -1,51 +1,49 @@
|
|||
<template lang="html">
|
||||
<div class="ffz--menu-page">
|
||||
<header class="tw-mg-b-1">
|
||||
<template v-for="i in breadcrumbs">
|
||||
<div class="ffz--menu-page">
|
||||
<header class="tw-mg-b-1">
|
||||
<span v-for="i in breadcrumbs" :key="i.full_key">
|
||||
<a v-if="i !== item" href="#" @click="$emit('change-item', i, false)">{{ t(i.i18n_key, i.title, i) }}</a>
|
||||
<strong v-if="i === item">{{ t(i.i18n_key, i.title, i) }}</strong>
|
||||
<template v-if="i !== item">» </template>
|
||||
</template>
|
||||
</header>
|
||||
<section v-if="! context.currentProfile.live && item.profile_warning !== false" class="tw-border-t tw-pd-t-1 tw-pd-b-2">
|
||||
</span>
|
||||
</header>
|
||||
<section v-if="! context.currentProfile.live && item.profile_warning !== false" class="tw-border-t tw-pd-t-1 tw-pd-b-2">
|
||||
<div class="tw-c-background-accent tw-c-text-overlay tw-pd-1">
|
||||
<h3 class="ffz-i-attention">
|
||||
{{ t('setting.profiles.inactive', "This profile isn't active.") }}
|
||||
</h3>
|
||||
|
||||
{{ t(
|
||||
'setting.profiles.inactive.description',
|
||||
{{ t('setting.profiles.inactive.description',
|
||||
"This profile's rules don't match the current context and it therefore isn't currently active, so you " +
|
||||
"won't see changes you make here reflected on Twitch."
|
||||
) }}
|
||||
"won't see changes you make here reflected on Twitch.")
|
||||
}}
|
||||
</div>
|
||||
</section>
|
||||
<section
|
||||
</section>
|
||||
<section
|
||||
v-if="item.description"
|
||||
class="tw-border-t tw-pd-y-1"
|
||||
v-html="t(item.desc_i18n_key || item.i18n_key + '.description', item.description, item)"
|
||||
/>
|
||||
</section>
|
||||
<template v-if="! item.contents || ! item.contents.length">
|
||||
<template v-if="! item.contents || ! item.contents.length">
|
||||
<ul class="tw-border-t tw-pd-y-1">
|
||||
<li class="tw-pd-x-1" v-for="i in item.items">
|
||||
<li v-for="i in item.items" :key="i.full_key" class="tw-pd-x-1">
|
||||
<a href="#" @click="$emit('change-item', i, false)">
|
||||
{{ t(i.i18n_key, i.title, i) }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<component
|
||||
</template>
|
||||
<component
|
||||
v-for="i in item.contents"
|
||||
v-bind:is="i.component"
|
||||
ref="children"
|
||||
:is="i.component"
|
||||
:context="context"
|
||||
:item="i"
|
||||
:key="i.full_key"
|
||||
@change-item="changeItem"
|
||||
@navigate="navigate"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<template lang="html">
|
||||
<ul
|
||||
<ul
|
||||
v-if="modal"
|
||||
class="ffz--menu-tree"
|
||||
:role="[root ? 'group' : 'tree']"
|
||||
:tabindex="tabIndex"
|
||||
class="ffz--menu-tree"
|
||||
@keyup.up="prevItem"
|
||||
@keyup.down="nextItem"
|
||||
@keyup.left="prevLevel"
|
||||
@keyup.right="nextLevel"
|
||||
@keyup.*="expandAll"
|
||||
>
|
||||
>
|
||||
<li
|
||||
v-for="item in modal"
|
||||
:key="item.full_key"
|
||||
|
@ -17,20 +17,19 @@
|
|||
role="presentation"
|
||||
>
|
||||
<div
|
||||
class="tw-flex__item tw-flex tw-flex-nowrap tw-align-items-center tw-pd-y-05 tw-pd-r-05"
|
||||
|
||||
role="treeitem"
|
||||
:aria-expanded="item.expanded"
|
||||
:aria-selected="currentItem === item"
|
||||
class="tw-flex__item tw-flex tw-flex-nowrap tw-align-items-center tw-pd-y-05 tw-pd-r-05"
|
||||
role="treeitem"
|
||||
@click="clickItem(item)"
|
||||
>
|
||||
<span
|
||||
role="presentation"
|
||||
class="arrow"
|
||||
:class="[
|
||||
item.items ? '' : 'ffz--invisible',
|
||||
item.expanded ? 'ffz-i-down-dir' : 'ffz-i-right-dir'
|
||||
]"
|
||||
role="presentation"
|
||||
class="arrow"
|
||||
/>
|
||||
<span class="tw-flex-grow-1">
|
||||
{{ t(item.i18n_key, item.title, item) }}
|
||||
|
@ -40,14 +39,14 @@
|
|||
</span>
|
||||
</div>
|
||||
<menu-tree
|
||||
:root="item"
|
||||
:currentItem="currentItem"
|
||||
:modal="item.items"
|
||||
v-if="item.items && item.expanded"
|
||||
:root="item"
|
||||
:current-item="currentItem"
|
||||
:modal="item.items"
|
||||
@change-item="i => $emit('change-item', i)"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -120,7 +119,7 @@ export default {
|
|||
this.$emit('change-item', i.parent);
|
||||
},
|
||||
|
||||
nextItem(e) {
|
||||
nextItem() {
|
||||
if ( this.root ) return;
|
||||
|
||||
const i = this.currentItem;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template lang="html">
|
||||
<div class="ffz--profile-editor">
|
||||
<div class="ffz--profile-editor">
|
||||
<div class="tw-flex tw-align-items-center tw-border-t tw-pd-1">
|
||||
<div class="tw-flex-grow-1"></div>
|
||||
<div class="tw-flex-grow-1" />
|
||||
<button
|
||||
class="tw-button tw-button--text"
|
||||
@click="save"
|
||||
|
@ -11,8 +11,8 @@
|
|||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="tw-mg-l-1 tw-button tw-button--text"
|
||||
:disabled="item.profile && context.profiles.length < 2"
|
||||
class="tw-mg-l-1 tw-button tw-button--text"
|
||||
@click="del"
|
||||
>
|
||||
<span class="tw-button__text ffz-i-trash">
|
||||
|
@ -37,11 +37,11 @@
|
|||
</label>
|
||||
|
||||
<input
|
||||
class="tw-input"
|
||||
ref="name"
|
||||
id="ffz:editor:name"
|
||||
ref="name"
|
||||
v-model="name"
|
||||
/>
|
||||
class="tw-input"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="ffz--widget tw-flex tw-flex-nowrap">
|
||||
|
@ -50,10 +50,10 @@
|
|||
</label>
|
||||
|
||||
<textarea
|
||||
class="tw-input"
|
||||
ref="desc"
|
||||
id="ffz:editor:description"
|
||||
ref="desc"
|
||||
v-model="desc"
|
||||
class="tw-input"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -63,10 +63,9 @@
|
|||
{{ t('settings.data_management.profiles.edit.rules', 'Rules') }}
|
||||
</header>
|
||||
<section class="tw-pd-b-1">
|
||||
{{ t(
|
||||
'settings.data_management.profiles.edit.rules.description',
|
||||
'Rules allows you to define a series of conditions under which this profile will be active.'
|
||||
) }}
|
||||
{{ t('settings.data_management.profiles.edit.rules.description',
|
||||
'Rules allows you to define a series of conditions under which this profile will be active.')
|
||||
}}
|
||||
</section>
|
||||
|
||||
<filter-editor
|
||||
|
@ -75,9 +74,8 @@
|
|||
:context="test_context"
|
||||
@change="unsaved = true"
|
||||
/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -100,17 +98,6 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.context.context.on('context_changed', this.updateContext, this);
|
||||
this.updateContext();
|
||||
this.revert();
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.context.context.off('context_changed', this.updateContext, this);
|
||||
},
|
||||
|
||||
|
||||
watch: {
|
||||
name() {
|
||||
if ( this.name !== this.old_name )
|
||||
|
@ -123,6 +110,16 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.context.context.on('context_changed', this.updateContext, this);
|
||||
this.updateContext();
|
||||
this.revert();
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.context.context.off('context_changed', this.updateContext, this);
|
||||
},
|
||||
|
||||
methods: {
|
||||
revert() {
|
||||
const profile = this.item.profile;
|
||||
|
@ -131,7 +128,7 @@ export default {
|
|||
profile.i18n_key ?
|
||||
this.t(profile.i18n_key, profile.title, profile) :
|
||||
profile.title :
|
||||
'Unnamed Profile',
|
||||
'Unnamed Profile';
|
||||
|
||||
this.old_desc = this.desc = profile ?
|
||||
profile.desc_i18n_key ?
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template lang="html">
|
||||
<div class="ffz--widget ffz--profile-manager tw-border-t tw-pd-y-1">
|
||||
<div class="ffz--widget ffz--profile-manager tw-border-t tw-pd-y-1">
|
||||
<div class="tw-c-background-accent tw-c-text-overlay tw-pd-1 tw-mg-b-1">
|
||||
<h3 class="ffz-i-attention">
|
||||
This feature is not yet finished.
|
||||
|
@ -30,11 +30,11 @@
|
|||
:data-profile="p.id"
|
||||
>
|
||||
<div
|
||||
class="ffz--profile tw-elevation-1 tw-c-background tw-border tw-pd-y-05 tw-pd-r-1 tw-mg-y-05 tw-flex tw-flex-nowrap"
|
||||
:class="{live: p.live}"
|
||||
class="ffz--profile tw-elevation-1 tw-c-background tw-border tw-pd-y-05 tw-pd-r-1 tw-mg-y-05 tw-flex tw-flex-nowrap"
|
||||
tabindex="0"
|
||||
>
|
||||
<div class="tw-flex tw-flex-shrink-0 tw-align-items-center tw-handle tw-pd-x-05 tw-pd-t-1 tw-pd-b-05">
|
||||
<div class="tw-flex tw-flex-shrink-0 tw-align-items-center handle tw-pd-x-05 tw-pd-t-1 tw-pd-b-05">
|
||||
<span class="ffz-i-ellipsis-vert" />
|
||||
</div>
|
||||
|
||||
|
@ -68,7 +68,7 @@
|
|||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -78,6 +78,28 @@ import Sortable from 'sortablejs';
|
|||
export default {
|
||||
props: ['item', 'context'],
|
||||
|
||||
mounted() {
|
||||
this._sortable = Sortable.create(this.$refs.list, {
|
||||
draggable: 'section',
|
||||
filter: 'button',
|
||||
|
||||
onUpdate: event => {
|
||||
const id = event.item.dataset.profile,
|
||||
profile = this.context.profile_keys[id];
|
||||
|
||||
if ( profile )
|
||||
profile.move(event.newIndex);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
if ( this._sortable )
|
||||
this._sortable.destroy();
|
||||
|
||||
this._sortable = null;
|
||||
},
|
||||
|
||||
methods: {
|
||||
edit(profile) {
|
||||
const item = {
|
||||
|
@ -100,30 +122,7 @@ export default {
|
|||
item.contents[0].parent = item;
|
||||
this.$emit('change-item', item);
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this._sortable = Sortable.create(this.$refs.list, {
|
||||
draggable: 'section',
|
||||
filter: 'button',
|
||||
|
||||
onUpdate: (event) => {
|
||||
const id = event.item.dataset.profile,
|
||||
profile = this.context.profile_keys[id];
|
||||
|
||||
if ( profile )
|
||||
profile.move(event.newIndex);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
if ( this._sortable )
|
||||
this._sortable.destroy();
|
||||
|
||||
this._sortable = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>
|
|
@ -1,10 +1,10 @@
|
|||
<template lang="html">
|
||||
<div class="ffz--widget ffz--profile-selector">
|
||||
<div class="ffz--widget ffz--profile-selector">
|
||||
<div
|
||||
ref="button"
|
||||
:class="{active: opened}"
|
||||
tabindex="0"
|
||||
class="tw-select"
|
||||
:class="{active: opened}"
|
||||
ref="button"
|
||||
@keyup.up.stop.prevent="focusShow"
|
||||
@keyup.left.stop.prevent="focusShow"
|
||||
@keyup.down.stop.prevent="focusShow"
|
||||
|
@ -15,7 +15,11 @@
|
|||
>
|
||||
{{ t(context.currentProfile.i18n_key, context.currentProfile.title, context.currentProfile) }}
|
||||
</div>
|
||||
<div v-if="opened" v-on-clickaway="hide" class="tw-balloon tw-block tw-balloon--lg tw-balloon--down tw-balloon--left">
|
||||
<div
|
||||
v-on-clickaway="hide"
|
||||
v-if="opened"
|
||||
class="tw-balloon tw-block tw-balloon--lg tw-balloon--down tw-balloon--left"
|
||||
>
|
||||
<div
|
||||
class="ffz--profile-list tw-elevation-2 tw-c-background-alt"
|
||||
@keyup.escape="focusHide"
|
||||
|
@ -24,15 +28,16 @@
|
|||
>
|
||||
<div class="scrollable-area tw-border-b" data-simplebar>
|
||||
<div class="simplebar-scroll-content">
|
||||
<div class="simplebar-content" ref="popup">
|
||||
<div ref="popup" class="simplebar-content">
|
||||
<div
|
||||
v-for="(p, idx) in context.profiles"
|
||||
tabindex="0"
|
||||
class="ffz--profile-row tw-relative tw-border-b tw-pd-y-05 tw-pd-r-3 tw-pd-l-1"
|
||||
v-for="p in context.profiles"
|
||||
:key="p.id"
|
||||
:class="{
|
||||
live: p.live,
|
||||
current: p === context.currentProfile
|
||||
}"
|
||||
tabindex="0"
|
||||
class="ffz--profile-row tw-relative tw-border-b tw-pd-y-05 tw-pd-r-3 tw-pd-l-1"
|
||||
@keydown.up.stop.prevent=""
|
||||
@keydown.down.stop.prevent=""
|
||||
@keydown.page-up.stop.prevent=""
|
||||
|
@ -73,7 +78,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
<template lang="html">
|
||||
<div class="ffz--widget ffz--checkbox" :class="{inherits: isInherited, default: isDefault}">
|
||||
<div
|
||||
:class="{inherits: isInherited, default: isDefault}"
|
||||
class="ffz--widget ffz--checkbox"
|
||||
>
|
||||
<div class="tw-flex tw-align-items-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="tw-checkbox__input"
|
||||
ref="control"
|
||||
:id="item.full_key"
|
||||
:checked="value"
|
||||
type="checkbox"
|
||||
class="tw-checkbox__input"
|
||||
@change="onChange"
|
||||
>
|
||||
|
||||
<label class="tw-checkbox__label" :for="item.full_key">
|
||||
<label :for="item.full_key" class="tw-checkbox__label">
|
||||
{{ t(item.i18n_key, item.title, item) }}
|
||||
</label>
|
||||
|
||||
|
@ -25,7 +28,7 @@
|
|||
</button>
|
||||
|
||||
<button v-if="has_value" class="tw-mg-l-05 tw-button tw-button--text tw-tooltip-wrapper" @click="clear">
|
||||
<span class="tw-button__text ffz-i-cancel"></span>
|
||||
<span class="tw-button__text ffz-i-cancel" />
|
||||
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
|
||||
{{ t('setting.reset', 'Reset to Default') }}
|
||||
</div>
|
||||
|
@ -37,7 +40,7 @@
|
|||
style="padding-left:2.2rem"
|
||||
v-html="t(item.desc_i18n_key || item.i18n_key + '.description', item.description, item)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template lang="html">
|
||||
<div class="ffz--widget ffz--hotkey-input">
|
||||
<div class="ffz--widget ffz--hotkey-input">
|
||||
<label
|
||||
:for="item.full_key"
|
||||
v-html="t(item.i18n_key, item.title, item)"
|
||||
|
@ -11,10 +11,10 @@
|
|||
</div>
|
||||
</div>
|
||||
<div
|
||||
type="text"
|
||||
class="tw-mg-05 tw-input tw-input--icon-right"
|
||||
ref="display"
|
||||
:id="item.full_key"
|
||||
type="text"
|
||||
class="tw-mg-05 tw-input tw-input--icon-right"
|
||||
tabindex="0"
|
||||
@keyup="onKey"
|
||||
>
|
||||
|
@ -25,7 +25,7 @@
|
|||
v-if="item.description"
|
||||
v-html="t(item.desc_i18n_key || item.i18n_key + '.description', item.description, item)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template lang="html">
|
||||
<div class="tw-input">
|
||||
<div class="tw-input">
|
||||
<header>
|
||||
{{ t(item.i18n_key, item.title, item) }}
|
||||
</header>
|
||||
|
@ -8,20 +8,29 @@
|
|||
class="tw-c-text-alt-2"
|
||||
v-html="t(item.desc_i18n_key || item.i18n_key + '.description', item.description, item)"
|
||||
/>
|
||||
<div v-for="(i, idx) in data" class="tw-mg-l-1">
|
||||
<input type="radio" :name="item.full_key" :id="item.full_key + idx" :value="i.value" class="tw-radio__input">
|
||||
<label :for="item.full_key + idx" class="tw-pd-y-05 tw-radio__label">{{ t(i.i18n_key, i.title, i) }}</label>
|
||||
<div v-for="(i, idx) in data" :key="idx" class="tw-mg-l-1">
|
||||
<input
|
||||
:name="item.full_key"
|
||||
:id="item.full_key + idx"
|
||||
:value="i.value"
|
||||
type="radio"
|
||||
class="tw-radio__input"
|
||||
>
|
||||
<label
|
||||
:for="item.full_key + idx"
|
||||
class="tw-pd-y-05 tw-radio__label"
|
||||
>
|
||||
{{ t(i.i18n_key, i.title, i) }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import SettingMixin from '../setting-mixin';
|
||||
|
||||
export default {
|
||||
mixins: [SettingMixin],
|
||||
props: ['item', 'context']
|
||||
}
|
||||
|
||||
</script>
|
|
@ -1,17 +1,24 @@
|
|||
<template lang="html">
|
||||
<div class="ffz--widget ffz--select-box" :class="{inherits: isInherited, default: isDefault}">
|
||||
<div
|
||||
:class="{inherits: isInherited, default: isDefault}"
|
||||
class="ffz--widget ffz--select-box"
|
||||
>
|
||||
<div class="tw-flex tw-align-items-center">
|
||||
<label :for="item.full_key">
|
||||
{{ t(item.i18n_key, item.title, item) }}
|
||||
</label>
|
||||
|
||||
<select
|
||||
class="tw-mg-05 tw-select tw-display-inline tw-width-auto"
|
||||
ref="control"
|
||||
:id="item.full_key"
|
||||
class="tw-mg-05 tw-select tw-display-inline tw-width-auto"
|
||||
@change="onChange"
|
||||
>
|
||||
<option v-for="i in data" :selected="i.value === value">
|
||||
<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>
|
||||
</select>
|
||||
|
@ -27,7 +34,7 @@
|
|||
</button>
|
||||
|
||||
<button v-if="has_value" class="tw-mg-l-05 tw-button tw-button--text tw-tooltip-wrapper" @click="clear">
|
||||
<span class="tw-button__text ffz-i-cancel"></span>
|
||||
<span class="tw-button__text ffz-i-cancel" />
|
||||
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
|
||||
{{ t('setting.reset', 'Reset to Default') }}
|
||||
</div>
|
||||
|
@ -39,11 +46,10 @@
|
|||
class="tw-c-text-alt-2"
|
||||
v-html="t(item.desc_i18n_key || item.i18n_key + '.description', item.description, item)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import SettingMixin from '../setting-mixin';
|
||||
|
||||
export default {
|
||||
|
@ -60,5 +66,4 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
|
@ -1,17 +1,20 @@
|
|||
<template lang="html">
|
||||
<div class="ffz--widget ffz--text-box" :class="{inherits: isInherited, default: isDefault}">
|
||||
<div
|
||||
:class="{inherits: isInherited, default: isDefault}"
|
||||
class="ffz--widget ffz--text-box"
|
||||
>
|
||||
<div class="tw-flex tw-align-items-center">
|
||||
<label :for="item.full_key">
|
||||
{{ t(item.i18n_key, item.title, item) }}
|
||||
</label>
|
||||
|
||||
<input
|
||||
class="tw-mg-05 tw-input tw-display-inline tw-width-auto"
|
||||
ref="control"
|
||||
:id="item.full_key"
|
||||
@change="onChange"
|
||||
:value="value"
|
||||
/>
|
||||
class="tw-mg-05 tw-input tw-display-inline tw-width-auto"
|
||||
@change="onChange"
|
||||
>
|
||||
|
||||
<button
|
||||
v-if="source && source !== profile"
|
||||
|
@ -24,7 +27,7 @@
|
|||
</button>
|
||||
|
||||
<button v-if="has_value" class="tw-mg-l-05 tw-button tw-button--text tw-tooltip-wrapper" @click="clear">
|
||||
<span class="tw-button__text ffz-i-cancel"></span>
|
||||
<span class="tw-button__text ffz-i-cancel" />
|
||||
<div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
|
||||
{{ t('setting.reset', 'Reset to Default') }}
|
||||
</div>
|
||||
|
@ -36,11 +39,10 @@
|
|||
class="tw-c-text-alt-2"
|
||||
v-html="t(item.desc_i18n_key || item.i18n_key + '.description', item.description, item)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import SettingMixin from '../setting-mixin';
|
||||
|
||||
export default {
|
||||
|
@ -55,5 +57,4 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
|
@ -1,29 +1,41 @@
|
|||
<template lang="html">
|
||||
<div class="ffz-auto-host-options tw-c-background">
|
||||
<div class="ffz-auto-host-options tw-c-background">
|
||||
<header class="tw-full-width tw-align-items-center tw-flex tw-flex-nowrap">
|
||||
<h4>{{ t('metadata.host.title', 'Auto Host Management') }}</h4>
|
||||
</header>
|
||||
<div class="tab tw-overflow-hidden"
|
||||
<div
|
||||
v-show="activeTab === 'auto-host'"
|
||||
:class="{ active: activeTab === 'auto-host'}">
|
||||
:class="{ active: activeTab === 'auto-host'}"
|
||||
class="tab tw-overflow-hidden"
|
||||
>
|
||||
<section class="tw-border-t tw-full-width tw-full-height">
|
||||
<main class="tw-flex-grow-1 scrollable-area" data-simplebar="init">
|
||||
<div class="simplebar-scroll-content">
|
||||
<draggable v-model="hosts" class="simplebar-content" :options="{
|
||||
<draggable
|
||||
v-model="hosts"
|
||||
:options="{
|
||||
draggable: '.ffz--host-user',
|
||||
animation: 150,
|
||||
}" @update="rearrangeHosts">
|
||||
<div v-for="host in hosts" class="tw-border-t ffz--host-user" :key="host._id" :data-id="host._id">
|
||||
}"
|
||||
class="simplebar-content"
|
||||
@update="rearrangeHosts"
|
||||
>
|
||||
<div
|
||||
v-for="host in hosts"
|
||||
:key="host._id"
|
||||
:data-id="host._id"
|
||||
class="tw-border-t ffz--host-user"
|
||||
>
|
||||
<div class="tw-interactable">
|
||||
<div class="tw-align-items-center tw-flex tw-flex-row tw-flex-nowrap tw-mg-x-1">
|
||||
<figure class="ffz-i-ellipsis-vert handle"></figure>
|
||||
<figure class="ffz-i-ellipsis-vert handle" />
|
||||
<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>
|
||||
<div class="tw-flex-grow-1 tw-pd-x-2"></div>
|
||||
<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"></figure>
|
||||
<figure class="ffz-i-trash" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -33,15 +45,21 @@
|
|||
</main>
|
||||
</section>
|
||||
<header class="tw-border-t tw-full-width tw-align-items-center tw-flex tw-flex-noxwrap tw-pd-1">
|
||||
<div class="tw-flex-grow-1 tw-pd-x-2"></div>
|
||||
<button class="tw-button tw-button--hollow tw-mg-x-05" :class="{'tw-button--disabled': addedToHosts}" @click="addToAutoHosts">
|
||||
<div class="tw-flex-grow-1 tw-pd-x-2" />
|
||||
<button
|
||||
:class="{'tw-button--disabled': addedToHosts}"
|
||||
class="tw-button tw-button--hollow tw-mg-x-05"
|
||||
@click="addToAutoHosts"
|
||||
>
|
||||
<span class="tw-button__text">{{ t('metadata.host.add-channel', 'Add To Auto Host') }}</span>
|
||||
</button>
|
||||
</header>
|
||||
</div>
|
||||
<div class="tab tw-overflow-hidden"
|
||||
<div
|
||||
v-show="activeTab === 'settings'"
|
||||
:class="{ active: activeTab === 'settings'}">
|
||||
:class="{ active: activeTab === 'settings'}"
|
||||
class="tab tw-overflow-hidden"
|
||||
>
|
||||
<section class="tw-border-t tw-full-width tw-full-height">
|
||||
<main class="tw-flex-grow-1 scrollable-area" data-simplebar="init">
|
||||
<div class="simplebar-scroll-content">
|
||||
|
@ -49,11 +67,14 @@
|
|||
<div class="tw-pd-1">
|
||||
<div class="ffz--widget ffz--checkbox">
|
||||
<div class="tw-flex tw-align-items-center">
|
||||
<input type="checkbox" class="tw-checkbox__input"
|
||||
<input
|
||||
id="autoHostSettings:enabled"
|
||||
data-setting="enabled"
|
||||
:checked="autoHostSettings.enabled"
|
||||
@change="updateCheckbox">
|
||||
type="checkbox"
|
||||
class="tw-checkbox__input"
|
||||
data-setting="enabled"
|
||||
@change="updateCheckbox"
|
||||
>
|
||||
<label for="autoHostSettings:enabled" class="tw-checkbox__label">
|
||||
{{ t('metadata.host.setting.auto-hosting.title', 'Auto Hosting') }}
|
||||
</label>
|
||||
|
@ -65,28 +86,34 @@
|
|||
</div>
|
||||
<div class="ffz--widget ffz--checkbox">
|
||||
<div class="tw-flex tw-align-items-center">
|
||||
<input type="checkbox" class="tw-checkbox__input"
|
||||
<input
|
||||
id="autoHostSettings:team_host"
|
||||
data-setting="team_host"
|
||||
:checked="autoHostSettings.team_host"
|
||||
@change="updateCheckbox">
|
||||
type="checkbox"
|
||||
class="tw-checkbox__input"
|
||||
data-setting="team_host"
|
||||
@change="updateCheckbox"
|
||||
>
|
||||
<label for="autoHostSettings:team_host" class="tw-checkbox__label">
|
||||
{{ t('metadata.host.setting.team-hosting.title', 'Team Hosting') }}
|
||||
</label>
|
||||
</div>
|
||||
<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. ' +
|
||||
"Automatically host random channels from your team when you're not live. " +
|
||||
'Team channels will be hosted before any channels in your host list.') }}
|
||||
</section>
|
||||
</div>
|
||||
<div class="ffz--widget ffz--checkbox">
|
||||
<div class="tw-flex tw-align-items-center">
|
||||
<input type="checkbox" class="tw-checkbox__input"
|
||||
<input
|
||||
id="autoHostSettings:vodcast_hosting"
|
||||
data-setting="deprioritize_vodcast"
|
||||
:checked="!autoHostSettings.deprioritize_vodcast"
|
||||
@change="updateCheckbox">
|
||||
type="checkbox"
|
||||
class="tw-checkbox__input"
|
||||
data-setting="deprioritize_vodcast"
|
||||
@change="updateCheckbox"
|
||||
>
|
||||
<label for="autoHostSettings:vodcast_hosting" class="tw-checkbox__label">
|
||||
{{ t('metadata.host.setting.vodcast-hosting.title', 'Vodcast Hosting') }}
|
||||
</label>
|
||||
|
@ -98,11 +125,14 @@
|
|||
</div>
|
||||
<div class="ffz--widget ffz--checkbox">
|
||||
<div class="tw-flex tw-align-items-center">
|
||||
<input type="checkbox" class="tw-checkbox__input"
|
||||
<input
|
||||
id="autoHostSettings:recommended_host"
|
||||
data-setting="recommended_host"
|
||||
:checked="autoHostSettings.recommended_host"
|
||||
@change="updateCheckbox">
|
||||
type="checkbox"
|
||||
class="tw-checkbox__input"
|
||||
data-setting="recommended_host"
|
||||
@change="updateCheckbox"
|
||||
>
|
||||
<label for="autoHostSettings:recommended_host" class="tw-checkbox__label">
|
||||
{{ t('metadata.host.setting.recommended-hosting.title', 'Auto Host Channels Similar To Yours') }}
|
||||
</label>
|
||||
|
@ -113,11 +143,14 @@
|
|||
</div>
|
||||
<div class="ffz--widget ffz--checkbox">
|
||||
<div class="tw-flex tw-align-items-center">
|
||||
<input type="checkbox" class="tw-checkbox__input"
|
||||
<input
|
||||
id="autoHostSettings:strategy"
|
||||
data-setting="strategy"
|
||||
:checked="autoHostSettings.strategy === 'random'"
|
||||
@change="updateCheckbox">
|
||||
type="checkbox"
|
||||
class="tw-checkbox__input"
|
||||
data-setting="strategy"
|
||||
@change="updateCheckbox"
|
||||
>
|
||||
<label for="autoHostSettings:strategy" class="tw-checkbox__label">
|
||||
{{ t('metadata.host.setting.strategy.title', 'Randomize Host Order') }}
|
||||
</label>
|
||||
|
@ -125,7 +158,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>
|
||||
|
@ -136,19 +169,25 @@
|
|||
</div>
|
||||
<footer>
|
||||
<div class="host-options__tabs-container tw-border-t">
|
||||
<div id="host-options__auto-host" class="host-options__tab tw-pd-x-1"
|
||||
<div
|
||||
id="host-options__auto-host"
|
||||
:class="{active: activeTab === 'auto-host'}"
|
||||
class="host-options__tab tw-pd-x-1"
|
||||
@click="setActiveTab('auto-host')"
|
||||
:class="{active: activeTab === 'auto-host'}">
|
||||
>
|
||||
<span>{{ t('metadata.host.tab.auto-host', 'Auto Host') }}</span>
|
||||
</div>
|
||||
<div id="host-options__settings" class="host-options__tab tw-pd-x-1"
|
||||
<div
|
||||
id="host-options__settings"
|
||||
:class="{active: activeTab === 'settings'}"
|
||||
class="host-options__tab tw-pd-x-1"
|
||||
@click="setActiveTab('settings')"
|
||||
:class="{active: activeTab === 'settings'}">
|
||||
>
|
||||
<span>{{ t('metadata.host.tab.settings', 'Settings') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<template lang="html">
|
||||
<div
|
||||
<div
|
||||
v-if="item.tabs"
|
||||
class="ffz--tab-container"
|
||||
@keyup.alt.page-up.stop="focusPrevTab"
|
||||
@keyup.alt.page-down.stop="focusNextTab"
|
||||
>
|
||||
>
|
||||
<header
|
||||
class="tw-flex"
|
||||
tabindex="0"
|
||||
|
@ -20,21 +20,22 @@
|
|||
>
|
||||
<div
|
||||
v-for="(i, idx) in item.tabs"
|
||||
role="tab"
|
||||
:key="i.full_key"
|
||||
:id="'tab-for-' + i.full_key"
|
||||
:aria-selected="selected === idx"
|
||||
:aria-controls="'tab-panel-' + i.full_key"
|
||||
class="tab tw-pd-y-05 tw-pd-x-1"
|
||||
:class="[selected === idx ? 'active' : '']"
|
||||
role="tab"
|
||||
class="tab tw-pd-y-05 tw-pd-x-1"
|
||||
@click="selected = idx"
|
||||
>
|
||||
{{ t(i.i18n_key, i.title, i) }}
|
||||
</div>
|
||||
</header>
|
||||
<section
|
||||
class="tw-border"
|
||||
:id="'tab-panel-' + tab.full_key"
|
||||
:aria-labelledby="'tab-for-' + tab.full_key"
|
||||
class="tw-border"
|
||||
role="tabpanel"
|
||||
aria-hidden="false"
|
||||
aria-expanded="true"
|
||||
|
@ -44,15 +45,15 @@
|
|||
</section>
|
||||
<component
|
||||
v-for="i in tab.contents"
|
||||
v-bind:is="i.component"
|
||||
:currentProfile="currentProfile"
|
||||
:is="i.component"
|
||||
:current-profile="currentProfile"
|
||||
:profiles="profiles"
|
||||
:context="context"
|
||||
:item="i"
|
||||
:key="i.full_key"
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue