1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-28 05:15:54 +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:
SirStendec 2018-03-30 17:58:56 -04:00
parent 8dbcf434cd
commit f9f5f0affa
23 changed files with 1114 additions and 971 deletions

View file

@ -3,9 +3,13 @@ module.exports = {
"browser": true, "browser": true,
"es6": true "es6": true
}, },
"extends": "eslint:recommended", "extends": [
"parser": "babel-eslint", "eslint:recommended",
"plugin:vue/recommended"
],
"plugins": ["vue"],
"parserOptions": { "parserOptions": {
"parser": "babel-eslint",
"ecmaVersion": 8, "ecmaVersion": 8,
"sourceType": "module" "sourceType": "module"
}, },
@ -62,6 +66,7 @@ module.exports = {
"no-useless-constructor": ["error"], "no-useless-constructor": ["error"],
"no-useless-rename": ["error"], "no-useless-rename": ["error"],
"no-var": ["error"], "no-var": ["error"],
"no-cond-assign": ["warn"],
"object-shorthand": ["warn"], "object-shorthand": ["warn"],
"prefer-arrow-callback": ["warn", {"allowUnboundThis": true}], "prefer-arrow-callback": ["warn", {"allowUnboundThis": true}],
"prefer-const": ["warn", {"ignoreReadBeforeAssign": true}], "prefer-const": ["warn", {"ignoreReadBeforeAssign": true}],
@ -72,7 +77,7 @@ module.exports = {
"yield-star-spacing": ["warn"], "yield-star-spacing": ["warn"],
"indent": [ "indent": [
"error", "warn",
"tab", "tab",
{ {
"SwitchCase": 1 "SwitchCase": 1
@ -89,6 +94,20 @@ module.exports = {
"avoidEscape": true, "avoidEscape": true,
"allowTemplateLiterals": 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"
}
] ]
} }
}; };

View file

@ -1,7 +1,7 @@
FrankerFaceZ FrankerFaceZ
============ ============
Copyright (c) 2017 Dan Salvato LLC Copyright (c) 2018 Dan Salvato LLC
Licensed under the Apache License, Version 2.0. See LICENSE. 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: server for development. To get everything you need:
1. Install node.js and npm 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 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 running `npm run build`. For development, you can instruct gulp to watch
the source files for changes and re-build automatically with ```npm start``` the source files for changes and re-build automatically with `npm start`
FrankerFaceZ comes with a local development server that listens on port 8000 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 and it serves up local development copies of files, falling back to the CDN
when a local copy of a file isn't present. when a local copy of a file isn't present.
To make FrankerFaceZ load from your local development server, you must set To make FrankerFaceZ load from your local development server, you must set
the local storage variable ```ffzDebugMode``` to true. Just run the following the local storage variable `ffzDebugMode` to true. Just run the following
in your console on Twitch: ```localStorage.ffzDebugMode = true;``` 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
View file

@ -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": { "eslint-scope": {
"version": "3.7.1", "version": "3.7.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
@ -9358,6 +9367,20 @@
"loose-envify": "1.3.1" "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": { "vue-hot-reload-api": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.0.tgz", "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.0.tgz",

View file

@ -6,6 +6,7 @@
"main": "script.js", "main": "script.js",
"scripts": { "scripts": {
"start": "webpack-dev-server --config webpack.web.dev.js", "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": "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: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'", "build:prod": "webpack --config webpack.web.prod.js --define process.env.NODE_ENV='production'",
@ -22,6 +23,7 @@
"copy-webpack-plugin": "^4.5.1", "copy-webpack-plugin": "^4.5.1",
"css-loader": "^0.28.10", "css-loader": "^0.28.10",
"eslint": "^4.18.2", "eslint": "^4.18.2",
"eslint-plugin-vue": "^4.4.0",
"extract-loader": "^1.0.2", "extract-loader": "^1.0.2",
"file-loader": "^1.1.11", "file-loader": "^1.1.11",
"less": "^2.7.3", "less": "^2.7.3",

View file

@ -1,8 +1,8 @@
<template lang="html"> <template lang="html">
<div class="ffz--badge-visibility tw-pd-t-05"> <div class="ffz--badge-visibility tw-pd-t-05">
<div <div
class="tw-c-background-accent tw-c-text-overlay tw-pd-1 tw-mg-b-1"
v-if="source && source !== profile" 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" /> <span class="ffz-i-info" />
{{ t('setting.badge-inheritence', 'These values are being overridden by another profile and may not take effect.') }} {{ 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"> <div class="tw-mg-b-2 tw-align-right">
<button <button
:disabled="! has_value"
class="tw-mg-l-05 tw-button tw-button--hollow tw-tooltip-wrapper" class="tw-mg-l-05 tw-button tw-button--hollow tw-tooltip-wrapper"
@click="clear" @click="clear"
:disabled="! has_value"
> >
<span class="tw-button__icon tw-button__icon--left"> <span class="tw-button__icon tw-button__icon--left">
<figure class="ffz-i-cancel" /> <figure class="ffz-i-cancel" />
@ -23,24 +23,46 @@
</button> </button>
</div> </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> <header>{{ sec.title }}</header>
<ul class="tw-flex tw-flex-wrap tw-align-content-start"> <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 <input
type="checkbox"
class="tw-checkbox__input"
:checked="badgeChecked(i.id)" :checked="badgeChecked(i.id)"
:id="i.id" :id="i.id"
type="checkbox"
class="tw-checkbox__input"
@click="onChange(i.id, $event)" @click="onChange(i.id, $event)"
> >
<label class="tw-checkbox__label tw-flex" :for="i.id"> <label :for="i.id" class="tw-checkbox__label tw-flex">
<div class="preview-image ffz-badge tw-mg-r-1 tw-flex-shrink-0" :style="{backgroundColor: i.color, backgroundImage: i.styleImage }" /> <div
:style="{backgroundColor: i.color, backgroundImage: i.styleImage }"
class="preview-image ffz-badge tw-mg-r-1 tw-flex-shrink-0"
/>
<div> <div>
<h5>{{ i.name }}</h5> <h5>{{ i.name }}</h5>
<section class="tw-mg-t-05" v-if="i.versions && i.versions.length > 1"> <section
<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}" /> 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> </section>
<button <button
class="tw-mg-t-05 tw-button tw-button--hollow tw-tooltip-wrapper" class="tw-mg-t-05 tw-button tw-button--hollow tw-tooltip-wrapper"

View file

@ -5,7 +5,6 @@
</div> </div>
<div ref="changes" /> <div ref="changes" />
</div> </div>
</template> </template>
@ -17,6 +16,10 @@ import {SERVER} from 'utilities/constants';
export default { export default {
props: ['item', 'context'], props: ['item', 'context'],
mounted() {
this.fetch(`${SERVER}/script/changelog.html`, this.$refs.changes);
},
methods: { methods: {
fetch(url, container) { fetch(url, container) {
const done = data => { const done = data => {
@ -38,13 +41,8 @@ export default {
fetch(url) fetch(url)
.then(resp => resp.ok ? resp.text() : null) .then(resp => resp.ok ? resp.text() : null)
.then(done) .then(done)
.catch(err => done(null)); .catch(() => done(null));
} }
},
mounted() {
this.fetch(`${SERVER}/script/changelog.html`, this.$refs.changes);
} }
} }
</script> </script>

View file

@ -21,15 +21,12 @@
When creating a GitHub issue, please check that someone else hasn't When creating a GitHub issue, please check that someone else hasn't
already created one for what you'd like to discuss or report. already created one for what you'd like to discuss or report.
</p> </p>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
props: ['item', 'context'], props: ['item', 'context'],
} }
</script> </script>

View file

@ -26,7 +26,7 @@
type="text" type="text"
class="tw-input" class="tw-input"
value="SirStendec" value="SirStendec"
/> >
</div> </div>
</div> </div>

View file

@ -1,5 +1,8 @@
<template lang="html"> <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"> <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> <h3 class="ffz-i-zreknarf ffz-i-pd-1">FrankerFaceZ</h3>
<div class="tw-flex-grow-1 tw-pd-x-2"> <div class="tw-flex-grow-1 tw-pd-x-2">
@ -15,12 +18,12 @@
</div> </div>
</div--> </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"> <span class="tw-button-icon__icon">
<figure :class="{'ffz-i-window-maximize': !maximized, 'ffz-i-window-restore': maximized}" /> <figure :class="{'ffz-i-window-maximize': !maximized, 'ffz-i-window-restore': maximized}" />
</span> </span>
</button> </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"> <span class="tw-button-icon__icon">
<figure class="ffz-i-window-close" /> <figure class="ffz-i-window-close" />
</span> </span>
@ -39,7 +42,7 @@
<div class="simplebar-scroll-content"> <div class="simplebar-scroll-content">
<div class="simplebar-content"> <div class="simplebar-content">
<menu-tree <menu-tree
:currentItem="currentItem" :current-item="currentItem"
:modal="nav" :modal="nav"
@change-item="changeItem" @change-item="changeItem"
@navigate="navigate" @navigate="navigate"
@ -61,12 +64,12 @@
<div class="simplebar-scroll-content"> <div class="simplebar-scroll-content">
<div class="simplebar-content"> <div class="simplebar-content">
<menu-page <menu-page
v-if="currentItem"
ref="page" ref="page"
:context="context" :context="context"
:item="currentItem" :item="currentItem"
@change-item="changeItem" @change-item="changeItem"
@navigate="navigate" @navigate="navigate"
v-if="currentItem"
/> />
</div> </div>
</div> </div>
@ -84,6 +87,12 @@ export default {
return this.$vnode.data; return this.$vnode.data;
}, },
watch: {
maximized() {
this.updateDrag();
}
},
created() { created() {
this.context.context._add_user(); this.context.context._add_user();
}, },
@ -92,6 +101,22 @@ export default {
this.context.context._remove_user(); 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: { methods: {
changeProfile() { changeProfile() {
const new_id = this.$refs.profiles.value, const new_id = this.$refs.profiles.value,
@ -153,28 +178,6 @@ export default {
this.changeItem(item); 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> </script>

View file

@ -1,16 +1,16 @@
<template lang="html"> <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"> <header v-if="! item.no_header">
{{ t(item.i18n_key, item.title, item) }} {{ t(item.i18n_key, item.title, item) }}
</header> </header>
<section <section
v-if="item.description" v-if="item.description"
v-html="t(item.desc_i18n_key, item.description, item)"
class="tw-pd-b-1" class="tw-pd-b-1"
v-html="t(item.desc_i18n_key, item.description, item)"
/> />
<component <component
v-for="i in item.contents" v-for="i in item.contents"
v-bind:is="i.component" :is="i.component"
:context="context" :context="context"
:item="i" :item="i"
:key="i.full_key" :key="i.full_key"

View file

@ -1,11 +1,11 @@
<template lang="html"> <template lang="html">
<div class="ffz--menu-page"> <div class="ffz--menu-page">
<header class="tw-mg-b-1"> <header class="tw-mg-b-1">
<template v-for="i in breadcrumbs"> <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> <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> <strong v-if="i === item">{{ t(i.i18n_key, i.title, i) }}</strong>
<template v-if="i !== item">&raquo; </template> <template v-if="i !== item">&raquo; </template>
</template> </span>
</header> </header>
<section v-if="! context.currentProfile.live && item.profile_warning !== false" class="tw-border-t tw-pd-t-1 tw-pd-b-2"> <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"> <div class="tw-c-background-accent tw-c-text-overlay tw-pd-1">
@ -13,11 +13,10 @@
{{ t('setting.profiles.inactive', "This profile isn't active.") }} {{ t('setting.profiles.inactive', "This profile isn't active.") }}
</h3> </h3>
{{ t( {{ t('setting.profiles.inactive.description',
'setting.profiles.inactive.description',
"This profile's rules don't match the current context and it therefore isn't currently active, so you " + "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> </div>
</section> </section>
<section <section
@ -25,10 +24,9 @@
class="tw-border-t tw-pd-y-1" class="tw-border-t tw-pd-y-1"
v-html="t(item.desc_i18n_key || item.i18n_key + '.description', item.description, item)" 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"> <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)"> <a href="#" @click="$emit('change-item', i, false)">
{{ t(i.i18n_key, i.title, i) }} {{ t(i.i18n_key, i.title, i) }}
</a> </a>
@ -37,8 +35,8 @@
</template> </template>
<component <component
v-for="i in item.contents" v-for="i in item.contents"
v-bind:is="i.component"
ref="children" ref="children"
:is="i.component"
:context="context" :context="context"
:item="i" :item="i"
:key="i.full_key" :key="i.full_key"

View file

@ -1,9 +1,9 @@
<template lang="html"> <template lang="html">
<ul <ul
v-if="modal" v-if="modal"
class="ffz--menu-tree"
:role="[root ? 'group' : 'tree']" :role="[root ? 'group' : 'tree']"
:tabindex="tabIndex" :tabindex="tabIndex"
class="ffz--menu-tree"
@keyup.up="prevItem" @keyup.up="prevItem"
@keyup.down="nextItem" @keyup.down="nextItem"
@keyup.left="prevLevel" @keyup.left="prevLevel"
@ -17,20 +17,19 @@
role="presentation" role="presentation"
> >
<div <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-expanded="item.expanded"
:aria-selected="currentItem === item" :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)" @click="clickItem(item)"
> >
<span <span
role="presentation"
class="arrow"
:class="[ :class="[
item.items ? '' : 'ffz--invisible', item.items ? '' : 'ffz--invisible',
item.expanded ? 'ffz-i-down-dir' : 'ffz-i-right-dir' item.expanded ? 'ffz-i-down-dir' : 'ffz-i-right-dir'
]" ]"
role="presentation"
class="arrow"
/> />
<span class="tw-flex-grow-1"> <span class="tw-flex-grow-1">
{{ t(item.i18n_key, item.title, item) }} {{ t(item.i18n_key, item.title, item) }}
@ -40,10 +39,10 @@
</span> </span>
</div> </div>
<menu-tree <menu-tree
:root="item"
:currentItem="currentItem"
:modal="item.items"
v-if="item.items && item.expanded" v-if="item.items && item.expanded"
:root="item"
:current-item="currentItem"
:modal="item.items"
@change-item="i => $emit('change-item', i)" @change-item="i => $emit('change-item', i)"
/> />
</li> </li>
@ -120,7 +119,7 @@ export default {
this.$emit('change-item', i.parent); this.$emit('change-item', i.parent);
}, },
nextItem(e) { nextItem() {
if ( this.root ) return; if ( this.root ) return;
const i = this.currentItem; const i = this.currentItem;

View file

@ -1,7 +1,7 @@
<template lang="html"> <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 tw-align-items-center tw-border-t tw-pd-1">
<div class="tw-flex-grow-1"></div> <div class="tw-flex-grow-1" />
<button <button
class="tw-button tw-button--text" class="tw-button tw-button--text"
@click="save" @click="save"
@ -11,8 +11,8 @@
</span> </span>
</button> </button>
<button <button
class="tw-mg-l-1 tw-button tw-button--text"
:disabled="item.profile && context.profiles.length < 2" :disabled="item.profile && context.profiles.length < 2"
class="tw-mg-l-1 tw-button tw-button--text"
@click="del" @click="del"
> >
<span class="tw-button__text ffz-i-trash"> <span class="tw-button__text ffz-i-trash">
@ -37,11 +37,11 @@
</label> </label>
<input <input
class="tw-input"
ref="name"
id="ffz:editor:name" id="ffz:editor:name"
ref="name"
v-model="name" v-model="name"
/> class="tw-input"
>
</div> </div>
<div class="ffz--widget tw-flex tw-flex-nowrap"> <div class="ffz--widget tw-flex tw-flex-nowrap">
@ -50,10 +50,10 @@
</label> </label>
<textarea <textarea
class="tw-input"
ref="desc"
id="ffz:editor:description" id="ffz:editor:description"
ref="desc"
v-model="desc" v-model="desc"
class="tw-input"
/> />
</div> </div>
</div> </div>
@ -63,10 +63,9 @@
{{ t('settings.data_management.profiles.edit.rules', 'Rules') }} {{ t('settings.data_management.profiles.edit.rules', 'Rules') }}
</header> </header>
<section class="tw-pd-b-1"> <section class="tw-pd-b-1">
{{ t( {{ t('settings.data_management.profiles.edit.rules.description',
'settings.data_management.profiles.edit.rules.description', 'Rules allows you to define a series of conditions under which this profile will be active.')
'Rules allows you to define a series of conditions under which this profile will be active.' }}
) }}
</section> </section>
<filter-editor <filter-editor
@ -75,7 +74,6 @@
:context="test_context" :context="test_context"
@change="unsaved = true" @change="unsaved = true"
/> />
</div> </div>
</div> </div>
</template> </template>
@ -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: { watch: {
name() { name() {
if ( this.name !== this.old_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: { methods: {
revert() { revert() {
const profile = this.item.profile; const profile = this.item.profile;
@ -131,7 +128,7 @@ export default {
profile.i18n_key ? profile.i18n_key ?
this.t(profile.i18n_key, profile.title, profile) : this.t(profile.i18n_key, profile.title, profile) :
profile.title : profile.title :
'Unnamed Profile', 'Unnamed Profile';
this.old_desc = this.desc = profile ? this.old_desc = this.desc = profile ?
profile.desc_i18n_key ? profile.desc_i18n_key ?

View file

@ -30,11 +30,11 @@
:data-profile="p.id" :data-profile="p.id"
> >
<div <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="{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" 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" /> <span class="ffz-i-ellipsis-vert" />
</div> </div>
@ -78,6 +78,28 @@ import Sortable from 'sortablejs';
export default { export default {
props: ['item', 'context'], 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: { methods: {
edit(profile) { edit(profile) {
const item = { const item = {
@ -100,30 +122,7 @@ export default {
item.contents[0].parent = item; item.contents[0].parent = item;
this.$emit('change-item', 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> </script>

View file

@ -1,10 +1,10 @@
<template lang="html"> <template lang="html">
<div class="ffz--widget ffz--profile-selector"> <div class="ffz--widget ffz--profile-selector">
<div <div
ref="button"
:class="{active: opened}"
tabindex="0" tabindex="0"
class="tw-select" class="tw-select"
:class="{active: opened}"
ref="button"
@keyup.up.stop.prevent="focusShow" @keyup.up.stop.prevent="focusShow"
@keyup.left.stop.prevent="focusShow" @keyup.left.stop.prevent="focusShow"
@keyup.down.stop.prevent="focusShow" @keyup.down.stop.prevent="focusShow"
@ -15,7 +15,11 @@
> >
{{ t(context.currentProfile.i18n_key, context.currentProfile.title, context.currentProfile) }} {{ t(context.currentProfile.i18n_key, context.currentProfile.title, context.currentProfile) }}
</div> </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 <div
class="ffz--profile-list tw-elevation-2 tw-c-background-alt" class="ffz--profile-list tw-elevation-2 tw-c-background-alt"
@keyup.escape="focusHide" @keyup.escape="focusHide"
@ -24,15 +28,16 @@
> >
<div class="scrollable-area tw-border-b" data-simplebar> <div class="scrollable-area tw-border-b" data-simplebar>
<div class="simplebar-scroll-content"> <div class="simplebar-scroll-content">
<div class="simplebar-content" ref="popup"> <div ref="popup" class="simplebar-content">
<div <div
v-for="(p, idx) in context.profiles" v-for="p in context.profiles"
tabindex="0" :key="p.id"
class="ffz--profile-row tw-relative tw-border-b tw-pd-y-05 tw-pd-r-3 tw-pd-l-1"
:class="{ :class="{
live: p.live, live: p.live,
current: p === context.currentProfile 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.up.stop.prevent=""
@keydown.down.stop.prevent="" @keydown.down.stop.prevent=""
@keydown.page-up.stop.prevent="" @keydown.page-up.stop.prevent=""

View file

@ -1,16 +1,19 @@
<template lang="html"> <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"> <div class="tw-flex tw-align-items-center">
<input <input
type="checkbox"
class="tw-checkbox__input"
ref="control" ref="control"
:id="item.full_key" :id="item.full_key"
:checked="value" :checked="value"
type="checkbox"
class="tw-checkbox__input"
@change="onChange" @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) }} {{ t(item.i18n_key, item.title, item) }}
</label> </label>
@ -25,7 +28,7 @@
</button> </button>
<button v-if="has_value" class="tw-mg-l-05 tw-button tw-button--text tw-tooltip-wrapper" @click="clear"> <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"> <div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
{{ t('setting.reset', 'Reset to Default') }} {{ t('setting.reset', 'Reset to Default') }}
</div> </div>

View file

@ -11,10 +11,10 @@
</div> </div>
</div> </div>
<div <div
type="text"
class="tw-mg-05 tw-input tw-input--icon-right"
ref="display" ref="display"
:id="item.full_key" :id="item.full_key"
type="text"
class="tw-mg-05 tw-input tw-input--icon-right"
tabindex="0" tabindex="0"
@keyup="onKey" @keyup="onKey"
> >

View file

@ -8,20 +8,29 @@
class="tw-c-text-alt-2" class="tw-c-text-alt-2"
v-html="t(item.desc_i18n_key || item.i18n_key + '.description', item.description, item)" 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"> <div v-for="(i, idx) in data" :key="idx" class="tw-mg-l-1">
<input type="radio" :name="item.full_key" :id="item.full_key + idx" :value="i.value" class="tw-radio__input"> <input
<label :for="item.full_key + idx" class="tw-pd-y-05 tw-radio__label">{{ t(i.i18n_key, i.title, i) }}</label> :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> </div>
</template> </template>
<script> <script>
import SettingMixin from '../setting-mixin'; import SettingMixin from '../setting-mixin';
export default { export default {
mixins: [SettingMixin], mixins: [SettingMixin],
props: ['item', 'context'] props: ['item', 'context']
} }
</script> </script>

View file

@ -1,17 +1,24 @@
<template lang="html"> <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"> <div class="tw-flex tw-align-items-center">
<label :for="item.full_key"> <label :for="item.full_key">
{{ t(item.i18n_key, item.title, item) }} {{ t(item.i18n_key, item.title, item) }}
</label> </label>
<select <select
class="tw-mg-05 tw-select tw-display-inline tw-width-auto"
ref="control" ref="control"
:id="item.full_key" :id="item.full_key"
class="tw-mg-05 tw-select tw-display-inline tw-width-auto"
@change="onChange" @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 }} {{ i.i18n_key ? t(i.i18n_key, i.title, i) : i.title }}
</option> </option>
</select> </select>
@ -27,7 +34,7 @@
</button> </button>
<button v-if="has_value" class="tw-mg-l-05 tw-button tw-button--text tw-tooltip-wrapper" @click="clear"> <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"> <div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
{{ t('setting.reset', 'Reset to Default') }} {{ t('setting.reset', 'Reset to Default') }}
</div> </div>
@ -43,7 +50,6 @@
</template> </template>
<script> <script>
import SettingMixin from '../setting-mixin'; import SettingMixin from '../setting-mixin';
export default { export default {
@ -60,5 +66,4 @@ export default {
} }
} }
} }
</script> </script>

View file

@ -1,17 +1,20 @@
<template lang="html"> <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"> <div class="tw-flex tw-align-items-center">
<label :for="item.full_key"> <label :for="item.full_key">
{{ t(item.i18n_key, item.title, item) }} {{ t(item.i18n_key, item.title, item) }}
</label> </label>
<input <input
class="tw-mg-05 tw-input tw-display-inline tw-width-auto"
ref="control" ref="control"
:id="item.full_key" :id="item.full_key"
@change="onChange"
:value="value" :value="value"
/> class="tw-mg-05 tw-input tw-display-inline tw-width-auto"
@change="onChange"
>
<button <button
v-if="source && source !== profile" v-if="source && source !== profile"
@ -24,7 +27,7 @@
</button> </button>
<button v-if="has_value" class="tw-mg-l-05 tw-button tw-button--text tw-tooltip-wrapper" @click="clear"> <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"> <div class="tw-tooltip tw-tooltip--down tw-tooltip--align-right">
{{ t('setting.reset', 'Reset to Default') }} {{ t('setting.reset', 'Reset to Default') }}
</div> </div>
@ -40,7 +43,6 @@
</template> </template>
<script> <script>
import SettingMixin from '../setting-mixin'; import SettingMixin from '../setting-mixin';
export default { export default {
@ -55,5 +57,4 @@ export default {
} }
} }
} }
</script> </script>

View file

@ -3,27 +3,39 @@
<header class="tw-full-width tw-align-items-center tw-flex tw-flex-nowrap"> <header class="tw-full-width tw-align-items-center tw-flex tw-flex-nowrap">
<h4>{{ t('metadata.host.title', 'Auto Host Management') }}</h4> <h4>{{ t('metadata.host.title', 'Auto Host Management') }}</h4>
</header> </header>
<div class="tab tw-overflow-hidden" <div
v-show="activeTab === 'auto-host'" 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"> <section class="tw-border-t tw-full-width tw-full-height">
<main class="tw-flex-grow-1 scrollable-area" data-simplebar="init"> <main class="tw-flex-grow-1 scrollable-area" data-simplebar="init">
<div class="simplebar-scroll-content"> <div class="simplebar-scroll-content">
<draggable v-model="hosts" class="simplebar-content" :options="{ <draggable
v-model="hosts"
:options="{
draggable: '.ffz--host-user', draggable: '.ffz--host-user',
animation: 150, 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-interactable">
<div class="tw-align-items-center tw-flex tw-flex-row tw-flex-nowrap tw-mg-x-1"> <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"> <div class="ffz-channel-avatar">
<img :src="host.logo" :alt="host.display_name + '(' + host.name + ')'"> <img :src="host.logo" :alt="host.display_name + '(' + host.name + ')'">
</div> </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"></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"> <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> </button>
</div> </div>
</div> </div>
@ -33,15 +45,21 @@
</main> </main>
</section> </section>
<header class="tw-border-t tw-full-width tw-align-items-center tw-flex tw-flex-noxwrap tw-pd-1"> <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> <div class="tw-flex-grow-1 tw-pd-x-2" />
<button class="tw-button tw-button--hollow tw-mg-x-05" :class="{'tw-button--disabled': addedToHosts}" @click="addToAutoHosts"> <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> <span class="tw-button__text">{{ t('metadata.host.add-channel', 'Add To Auto Host') }}</span>
</button> </button>
</header> </header>
</div> </div>
<div class="tab tw-overflow-hidden" <div
v-show="activeTab === 'settings'" 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"> <section class="tw-border-t tw-full-width tw-full-height">
<main class="tw-flex-grow-1 scrollable-area" data-simplebar="init"> <main class="tw-flex-grow-1 scrollable-area" data-simplebar="init">
<div class="simplebar-scroll-content"> <div class="simplebar-scroll-content">
@ -49,11 +67,14 @@
<div class="tw-pd-1"> <div class="tw-pd-1">
<div class="ffz--widget ffz--checkbox"> <div class="ffz--widget ffz--checkbox">
<div class="tw-flex tw-align-items-center"> <div class="tw-flex tw-align-items-center">
<input type="checkbox" class="tw-checkbox__input" <input
id="autoHostSettings:enabled" id="autoHostSettings:enabled"
data-setting="enabled"
:checked="autoHostSettings.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"> <label for="autoHostSettings:enabled" class="tw-checkbox__label">
{{ t('metadata.host.setting.auto-hosting.title', 'Auto Hosting') }} {{ t('metadata.host.setting.auto-hosting.title', 'Auto Hosting') }}
</label> </label>
@ -65,28 +86,34 @@
</div> </div>
<div class="ffz--widget ffz--checkbox"> <div class="ffz--widget ffz--checkbox">
<div class="tw-flex tw-align-items-center"> <div class="tw-flex tw-align-items-center">
<input type="checkbox" class="tw-checkbox__input" <input
id="autoHostSettings:team_host" id="autoHostSettings:team_host"
data-setting="team_host"
:checked="autoHostSettings.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"> <label for="autoHostSettings:team_host" class="tw-checkbox__label">
{{ t('metadata.host.setting.team-hosting.title', 'Team Hosting') }} {{ t('metadata.host.setting.team-hosting.title', 'Team Hosting') }}
</label> </label>
</div> </div>
<section class="tw-c-text-alt-2 ffz-checkbox-description"> <section class="tw-c-text-alt-2 ffz-checkbox-description">
{{ t('metadata.host.setting.team-hosting.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.') }} 'Team channels will be hosted before any channels in your host list.') }}
</section> </section>
</div> </div>
<div class="ffz--widget ffz--checkbox"> <div class="ffz--widget ffz--checkbox">
<div class="tw-flex tw-align-items-center"> <div class="tw-flex tw-align-items-center">
<input type="checkbox" class="tw-checkbox__input" <input
id="autoHostSettings:vodcast_hosting" id="autoHostSettings:vodcast_hosting"
data-setting="deprioritize_vodcast"
:checked="!autoHostSettings.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"> <label for="autoHostSettings:vodcast_hosting" class="tw-checkbox__label">
{{ t('metadata.host.setting.vodcast-hosting.title', 'Vodcast Hosting') }} {{ t('metadata.host.setting.vodcast-hosting.title', 'Vodcast Hosting') }}
</label> </label>
@ -98,11 +125,14 @@
</div> </div>
<div class="ffz--widget ffz--checkbox"> <div class="ffz--widget ffz--checkbox">
<div class="tw-flex tw-align-items-center"> <div class="tw-flex tw-align-items-center">
<input type="checkbox" class="tw-checkbox__input" <input
id="autoHostSettings:recommended_host" id="autoHostSettings:recommended_host"
data-setting="recommended_host"
:checked="autoHostSettings.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"> <label for="autoHostSettings:recommended_host" class="tw-checkbox__label">
{{ t('metadata.host.setting.recommended-hosting.title', 'Auto Host Channels Similar To Yours') }} {{ t('metadata.host.setting.recommended-hosting.title', 'Auto Host Channels Similar To Yours') }}
</label> </label>
@ -113,11 +143,14 @@
</div> </div>
<div class="ffz--widget ffz--checkbox"> <div class="ffz--widget ffz--checkbox">
<div class="tw-flex tw-align-items-center"> <div class="tw-flex tw-align-items-center">
<input type="checkbox" class="tw-checkbox__input" <input
id="autoHostSettings:strategy" id="autoHostSettings:strategy"
data-setting="strategy"
:checked="autoHostSettings.strategy === 'random'" :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"> <label for="autoHostSettings:strategy" class="tw-checkbox__label">
{{ t('metadata.host.setting.strategy.title', 'Randomize Host Order') }} {{ t('metadata.host.setting.strategy.title', 'Randomize Host Order') }}
</label> </label>
@ -125,7 +158,7 @@
<section class="tw-c-text-alt-2 ffz-checkbox-description"> <section class="tw-c-text-alt-2 ffz-checkbox-description">
{{ t('metadata.host.setting.strategy.description', {{ t('metadata.host.setting.strategy.description',
'If enabled, auto-hosts will be picked at random. ' + 'If enabled, auto-hosts will be picked at random. ' +
'Otherwise they\'re picked in order.') }} "Otherwise they're picked in order.") }}
</section> </section>
</div> </div>
</div> </div>
@ -136,14 +169,20 @@
</div> </div>
<footer> <footer>
<div class="host-options__tabs-container tw-border-t"> <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')" @click="setActiveTab('auto-host')"
:class="{active: activeTab === 'auto-host'}"> >
<span>{{ t('metadata.host.tab.auto-host', 'Auto Host') }}</span> <span>{{ t('metadata.host.tab.auto-host', 'Auto Host') }}</span>
</div> </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')" @click="setActiveTab('settings')"
:class="{active: activeTab === 'settings'}"> >
<span>{{ t('metadata.host.tab.settings', 'Settings') }}</span> <span>{{ t('metadata.host.tab.settings', 'Settings') }}</span>
</div> </div>
</div> </div>

View file

@ -20,21 +20,22 @@
> >
<div <div
v-for="(i, idx) in item.tabs" v-for="(i, idx) in item.tabs"
role="tab" :key="i.full_key"
:id="'tab-for-' + i.full_key" :id="'tab-for-' + i.full_key"
:aria-selected="selected === idx" :aria-selected="selected === idx"
:aria-controls="'tab-panel-' + i.full_key" :aria-controls="'tab-panel-' + i.full_key"
class="tab tw-pd-y-05 tw-pd-x-1"
:class="[selected === idx ? 'active' : '']" :class="[selected === idx ? 'active' : '']"
role="tab"
class="tab tw-pd-y-05 tw-pd-x-1"
@click="selected = idx" @click="selected = idx"
> >
{{ t(i.i18n_key, i.title, i) }} {{ t(i.i18n_key, i.title, i) }}
</div> </div>
</header> </header>
<section <section
class="tw-border"
:id="'tab-panel-' + tab.full_key" :id="'tab-panel-' + tab.full_key"
:aria-labelledby="'tab-for-' + tab.full_key" :aria-labelledby="'tab-for-' + tab.full_key"
class="tw-border"
role="tabpanel" role="tabpanel"
aria-hidden="false" aria-hidden="false"
aria-expanded="true" aria-expanded="true"
@ -44,8 +45,8 @@
</section> </section>
<component <component
v-for="i in tab.contents" v-for="i in tab.contents"
v-bind:is="i.component" :is="i.component"
:currentProfile="currentProfile" :current-profile="currentProfile"
:profiles="profiles" :profiles="profiles"
:context="context" :context="context"
:item="i" :item="i"