diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2020-08-18 22:44:21 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-08-18 22:44:21 +0900 |
| commit | 9855405b8989713b81709fc1700e2ead97423467 (patch) | |
| tree | 54254d2159378d1903e962f0fb37c799bb0f4464 /src/client/pages | |
| parent | Sign (request-target) Fix #6652 (#6656) (diff) | |
| download | misskey-9855405b8989713b81709fc1700e2ead97423467.tar.gz misskey-9855405b8989713b81709fc1700e2ead97423467.tar.bz2 misskey-9855405b8989713b81709fc1700e2ead97423467.zip | |
Channel (#6621)
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wop
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* add notes
* wip
* wip
* wip
* wip
* sound
* wip
* add kick_gaba2
* wip
Diffstat (limited to 'src/client/pages')
| -rw-r--r-- | src/client/pages/channel-editor.vue | 128 | ||||
| -rw-r--r-- | src/client/pages/channel.vue | 190 | ||||
| -rw-r--r-- | src/client/pages/channels.vue | 86 | ||||
| -rw-r--r-- | src/client/pages/index.home.vue | 66 | ||||
| -rw-r--r-- | src/client/pages/messaging/messaging-room.form.vue | 8 | ||||
| -rw-r--r-- | src/client/pages/my-settings/index.vue | 24 | ||||
| -rw-r--r-- | src/client/pages/preferences/index.vue | 20 |
7 files changed, 481 insertions, 41 deletions
diff --git a/src/client/pages/channel-editor.vue b/src/client/pages/channel-editor.vue new file mode 100644 index 0000000000..0178662119 --- /dev/null +++ b/src/client/pages/channel-editor.vue @@ -0,0 +1,128 @@ +<template> +<div> + <portal to="icon"><fa :icon="faSatelliteDish"/></portal> + <portal to="title">{{ channelId ? $t('_channel.edit') : $t('_channel.create') }}</portal> + + <div class="_card"> + <div class="_content"> + <mk-input v-model="name">{{ $t('name') }}</mk-input> + + <mk-textarea v-model="description">{{ $t('description') }}</mk-textarea> + + <div class="banner"> + <mk-button v-if="bannerId == null" @click="setBannerImage"><fa :icon="faPlus"/> {{ $t('_channel.setBanner') }}</mk-button> + <div v-else-if="bannerUrl"> + <img :src="bannerUrl" style="width: 100%;"/> + <mk-button @click="removeBannerImage()"><fa :icon="faTrashAlt"/> {{ $t('_channel.removeBanner') }}</mk-button> + </div> + </div> + </div> + <div class="_footer"> + <mk-button @click="save()" primary><fa :icon="faSave"/> {{ channelId ? $t('save') : $t('create') }}</mk-button> + </div> + </div> +</div> +</template> + +<script lang="ts"> +import Vue from 'vue'; +import { faPlus, faSatelliteDish } from '@fortawesome/free-solid-svg-icons'; +import { faSave, faTrashAlt } from '@fortawesome/free-regular-svg-icons'; +import MkTextarea from '../components/ui/textarea.vue'; +import MkButton from '../components/ui/button.vue'; +import MkInput from '../components/ui/input.vue'; +import { selectFile } from '../scripts/select-file'; + +export default Vue.extend({ + components: { + MkTextarea, MkButton, MkInput, + }, + + props: { + channelId: { + type: String, + required: false + }, + }, + + data() { + return { + channel: null, + name: null, + description: null, + bannerUrl: null, + bannerId: null, + faSave, faTrashAlt, faPlus,faSatelliteDish, + }; + }, + + watch: { + async bannerId() { + if (this.bannerId == null) { + this.bannerUrl = null; + } else { + this.bannerUrl = (await this.$root.api('drive/files/show', { + fileId: this.bannerId, + })).url; + } + }, + }, + + async created() { + if (this.channelId) { + this.channel = await this.$root.api('channels/show', { + channelId: this.channelId, + }); + + this.name = this.channel.name; + this.description = this.channel.description; + this.bannerId = this.channel.bannerId; + this.bannerUrl = this.channel.bannerUrl; + } + }, + + methods: { + save() { + const params = { + name: this.name, + description: this.description, + bannerId: this.bannerId, + }; + + if (this.channelId) { + params.channelId = this.channelId; + this.$root.api('channels/update', params) + .then(channel => { + this.$root.dialog({ + type: 'success', + iconOnly: true, autoClose: true + }); + }); + } else { + this.$root.api('channels/create', params) + .then(channel => { + this.$root.dialog({ + type: 'success', + iconOnly: true, autoClose: true + }); + this.$router.push(`/channels/${channel.id}`); + }); + } + }, + + setBannerImage(e) { + selectFile(this, e.currentTarget || e.target, null, false).then(file => { + this.bannerId = file.id; + }); + }, + + removeBannerImage() { + this.bannerId = null; + } + } +}); +</script> + +<style lang="scss" scoped> + +</style> diff --git a/src/client/pages/channel.vue b/src/client/pages/channel.vue new file mode 100644 index 0000000000..69631af74b --- /dev/null +++ b/src/client/pages/channel.vue @@ -0,0 +1,190 @@ +<template> +<div v-if="channel"> + <portal to="icon"><fa :icon="faSatelliteDish"/></portal> + <portal to="title">{{ channel.name }}</portal> + + <div class="wpgynlbz _panel _vMargin" :class="{ hide: !showBanner }"> + <x-channel-follow-button :channel="channel" :full="true" class="subscribe"/> + <button class="_button toggle" @click="() => showBanner = !showBanner"> + <template v-if="showBanner"><fa :icon="faAngleUp"/></template> + <template v-else><fa :icon="faAngleDown"/></template> + </button> + <div class="hideOverlay" v-if="!showBanner"> + </div> + <div :style="{ backgroundImage: channel.bannerUrl ? `url(${channel.bannerUrl})` : null }" class="banner"> + <div class="status"> + <div><fa :icon="faUsers" fixed-width/><i18n path="_channel.usersCount" tag="span" style="margin-left: 4px;"><b place="n">{{ channel.usersCount }}</b></i18n></div> + <div><fa :icon="faPencilAlt" fixed-width/><i18n path="_channel.notesCount" tag="span" style="margin-left: 4px;"><b place="n">{{ channel.notesCount }}</b></i18n></div> + </div> + <div class="fade"></div> + </div> + <div class="description" v-if="channel.description"> + <mfm :text="channel.description" :is-note="false" :i="$store.state.i"/> + </div> + </div> + + <x-post-form :channel="channel" class="post-form _panel _vMargin" fixed/> + + <x-timeline class="_vMargin" src="channel" :channel="channelId" @before="before" @after="after"/> +</div> +</template> + +<script lang="ts"> +import Vue from 'vue'; +import { faSatelliteDish, faUsers, faPencilAlt, faAngleUp, faAngleDown } from '@fortawesome/free-solid-svg-icons'; +import { } from '@fortawesome/free-regular-svg-icons'; +import MkContainer from '../components/ui/container.vue'; +import XPostForm from '../components/post-form.vue'; +import XTimeline from '../components/timeline.vue'; +import XChannelFollowButton from '../components/channel-follow-button.vue'; + +export default Vue.extend({ + metaInfo() { + return { + title: this.$t('channel') as string + }; + }, + + components: { + MkContainer, + XPostForm, + XTimeline, + XChannelFollowButton + }, + + props: { + channelId: { + type: String, + required: true + } + }, + + data() { + return { + channel: null, + showBanner: true, + pagination: { + endpoint: 'channels/timeline', + limit: 10, + params: () => ({ + channelId: this.channelId, + }) + }, + faSatelliteDish, faUsers, faPencilAlt, faAngleUp, faAngleDown, + }; + }, + + watch: { + channelId: { + async handler() { + this.channel = await this.$root.api('channels/show', { + channelId: this.channelId, + }); + }, + immediate: true + } + }, + + created() { + + }, +}); +</script> + +<style lang="scss" scoped> +.wpgynlbz { + > .subscribe { + position: absolute; + z-index: 1; + top: 16px; + left: 16px; + } + + > .toggle { + position: absolute; + z-index: 2; + top: 8px; + right: 8px; + font-size: 1.2em; + width: 48px; + height: 48px; + color: #fff; + background: rgba(0, 0, 0, 0.5); + border-radius: 100%; + + > [data-icon] { + vertical-align: middle; + } + } + + > .banner { + position: relative; + height: 200px; + background-position: center; + background-size: cover; + + > .fade { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 64px; + background: linear-gradient(0deg, var(--panel), var(--X15)); + } + + > .status { + position: absolute; + z-index: 1; + bottom: 16px; + right: 16px; + padding: 8px 12px; + font-size: 80%; + background: rgba(0, 0, 0, 0.7); + border-radius: 6px; + color: #fff; + } + } + + > .description { + padding: 16px; + } + + > .hideOverlay { + position: absolute; + z-index: 1; + top: 0; + left: 0; + width: 100%; + height: 100%; + -webkit-backdrop-filter: blur(16px); + backdrop-filter: blur(16px); + background: rgba(0, 0, 0, 0.3); + } + + &.hide { + > .subscribe { + display: none; + } + + > .toggle { + top: 0; + right: 0; + height: 100%; + background: transparent; + } + + > .banner { + height: 42px; + filter: blur(8px); + + > * { + display: none; + } + } + + > .description { + display: none; + } + } +} +</style> diff --git a/src/client/pages/channels.vue b/src/client/pages/channels.vue new file mode 100644 index 0000000000..85804141f1 --- /dev/null +++ b/src/client/pages/channels.vue @@ -0,0 +1,86 @@ +<template> +<div> + <portal to="icon"><fa :icon="faSatelliteDish"/></portal> + <portal to="title">{{ $t('channel') }}</portal> + + <mk-tab v-model="tab" :items="[{ label: $t('_channel.featured'), value: 'featured', icon: faFireAlt }, { label: $t('_channel.following'), value: 'following', icon: faHeart }, { label: $t('_channel.owned'), value: 'owned', icon: faEdit }]"/> + + <div class="grwlizim featured" v-if="tab === 'featured'"> + <mk-pagination :pagination="featuredPagination" #default="{items}"> + <mk-channel-preview v-for="channel in items" class="uveselbe" :channel="channel" :key="channel.id"/> + </mk-pagination> + </div> + + <div class="grwlizim following" v-if="tab === 'following'"> + <mk-pagination :pagination="followingPagination" #default="{items}"> + <mk-channel-preview v-for="channel in items" class="uveselbe" :channel="channel" :key="channel.id"/> + </mk-pagination> + </div> + + <div class="grwlizim owned" v-if="tab === 'owned'"> + <mk-button class="new" @click="create()"><fa :icon="faPlus"/></mk-button> + <mk-pagination :pagination="ownedPagination" #default="{items}"> + <mk-channel-preview v-for="channel in items" class="uveselbe" :channel="channel" :key="channel.id"/> + </mk-pagination> + </div> +</div> +</template> + +<script lang="ts"> +import Vue from 'vue'; +import { faSatelliteDish, faPlus, faEdit, faFireAlt } from '@fortawesome/free-solid-svg-icons'; +import { faHeart } from '@fortawesome/free-regular-svg-icons'; +import MkChannelPreview from '../components/channel-preview.vue'; +import MkPagination from '../components/ui/pagination.vue'; +import MkButton from '../components/ui/button.vue'; +import MkTab from '../components/tab.vue'; + +export default Vue.extend({ + components: { + MkChannelPreview, MkPagination, MkButton, MkTab + }, + data() { + return { + tab: 'featured', + featuredPagination: { + endpoint: 'channels/featured', + limit: 5, + }, + followingPagination: { + endpoint: 'channels/followed', + limit: 5, + }, + ownedPagination: { + endpoint: 'channels/owned', + limit: 5, + }, + faSatelliteDish, faPlus, faEdit, faHeart, faFireAlt + }; + }, + methods: { + create() { + this.$router.push(`/channels/new`); + } + } +}); +</script> + +<style lang="scss" scoped> +.grwlizim { + padding: 16px 0; + + &.my .uveselbe:first-child { + margin-top: 16px; + } + + .uveselbe:not(:last-child) { + margin-bottom: 8px; + } + + @media (min-width: 500px) { + .uveselbe:not(:last-child) { + margin-bottom: 16px; + } + } +} +</style> diff --git a/src/client/pages/index.home.vue b/src/client/pages/index.home.vue index b40086c310..d3f60ea910 100644 --- a/src/client/pages/index.home.vue +++ b/src/client/pages/index.home.vue @@ -2,14 +2,15 @@ <div class="mk-home" v-hotkey.global="keymap"> <portal to="header" v-if="showTitle"> <button @click="choose" class="_button _kjvfvyph_"> - <i><fa v-if="$store.state.i.hasUnreadAntenna" :icon="faCircle"/></i> + <i><fa v-if="$store.state.i.hasUnreadAntenna || $store.state.i.hasUnreadChannel" :icon="faCircle"/></i> <fa v-if="src === 'home'" :icon="faHome"/> <fa v-if="src === 'local'" :icon="faComments"/> <fa v-if="src === 'social'" :icon="faShareAlt"/> <fa v-if="src === 'global'" :icon="faGlobe"/> <fa v-if="src === 'list'" :icon="faListUl"/> <fa v-if="src === 'antenna'" :icon="faSatellite"/> - <span style="margin-left: 8px;">{{ src === 'list' ? list.name : src === 'antenna' ? antenna.name : $t('_timelines.' + src) }}</span> + <fa v-if="src === 'channel'" :icon="faSatelliteDish"/> + <span style="margin-left: 8px;">{{ src === 'list' ? list.name : src === 'antenna' ? antenna.name : src === 'channel' ? channel.name : $t('_timelines.' + src) }}</span> <fa :icon="menuOpened ? faAngleUp : faAngleDown" style="margin-left: 8px;"/> </button> </portal> @@ -19,13 +20,13 @@ <x-tutorial class="tutorial" v-if="$store.state.settings.tutorial != -1"/> <x-post-form class="post-form _panel" fixed v-if="$store.state.device.showFixedPostForm"/> - <x-timeline ref="tl" :key="src === 'list' ? `list:${list.id}` : src === 'antenna' ? `antenna:${antenna.id}` : src" :src="src" :list="list ? list.id : null" :antenna="antenna ? antenna.id : null" :sound="true" @before="before()" @after="after()" @queue="queueUpdated"/> + <x-timeline ref="tl" :key="src === 'list' ? `list:${list.id}` : src === 'antenna' ? `antenna:${antenna.id}` : src === 'channel' ? `channel:${channel.id}` : src" :src="src" :list="list ? list.id : null" :antenna="antenna ? antenna.id : null" :channel="channel ? channel.id : null" :sound="true" @before="before()" @after="after()" @queue="queueUpdated"/> </div> </template> <script lang="ts"> import Vue from 'vue'; -import { faAngleDown, faAngleUp, faHome, faShareAlt, faGlobe, faListUl, faSatellite, faCircle } from '@fortawesome/free-solid-svg-icons'; +import { faAngleDown, faAngleUp, faHome, faShareAlt, faGlobe, faListUl, faSatellite, faSatelliteDish, faCircle } from '@fortawesome/free-solid-svg-icons'; import { faComments } from '@fortawesome/free-regular-svg-icons'; import Progress from '../scripts/loading'; import XTimeline from '../components/timeline.vue'; @@ -57,10 +58,11 @@ export default Vue.extend({ src: 'home', list: null, antenna: null, + channel: null, menuOpened: false, queue: 0, width: 0, - faAngleDown, faAngleUp, faHome, faShareAlt, faGlobe, faComments, faListUl, faSatellite, faCircle + faAngleDown, faAngleUp, faHome, faShareAlt, faGlobe, faComments, faListUl, faSatellite, faSatelliteDish, faCircle }; }, @@ -79,16 +81,20 @@ export default Vue.extend({ watch: { src() { this.showNav = false; - this.saveSrc(); }, list(x) { this.showNav = false; - this.saveSrc(); if (x != null) this.antenna = null; + if (x != null) this.channel = null; }, antenna(x) { this.showNav = false; - this.saveSrc(); + if (x != null) this.list = null; + if (x != null) this.channel = null; + }, + channel(x) { + this.showNav = false; + if (x != null) this.antenna = null; if (x != null) this.list = null; }, }, @@ -99,6 +105,8 @@ export default Vue.extend({ this.list = this.$store.state.deviceUser.tl.arg; } else if (this.src === 'antenna') { this.antenna = this.$store.state.deviceUser.tl.arg; + } else if (this.src === 'channel') { + this.channel = this.$store.state.deviceUser.tl.arg; } }, @@ -127,9 +135,10 @@ export default Vue.extend({ async choose(ev) { if (this.meta == null) return; this.menuOpened = true; - const [antennas, lists] = await Promise.all([ + const [antennas, lists, channels] = await Promise.all([ this.$root.api('antennas/list'), - this.$root.api('users/lists/list') + this.$root.api('users/lists/list'), + this.$root.api('channels/followed'), ]); const antennaItems = antennas.map(antenna => ({ text: antenna.name, @@ -137,7 +146,8 @@ export default Vue.extend({ indicate: antenna.hasUnreadNote, action: () => { this.antenna = antenna; - this.setSrc('antenna'); + this.src = 'antenna'; + this.saveSrc(); } })); const listItems = lists.map(list => ({ @@ -145,27 +155,40 @@ export default Vue.extend({ icon: faListUl, action: () => { this.list = list; - this.setSrc('list'); + this.src = 'list'; + this.saveSrc(); + } + })); + const channelItems = channels.map(channel => ({ + text: channel.name, + icon: faSatelliteDish, + indicate: channel.hasUnreadNote, + action: () => { + // NOTE: チャンネルタイムラインをこのコンポーネントで表示するようにすると投稿フォームはどうするかなどの問題が生じるのでとりあえずページ遷移で + //this.channel = channel; + //this.src = 'channel'; + //this.saveSrc(); + this.$router.push(`/channels/${channel.id}`); } })); this.$root.menu({ items: [{ text: this.$t('_timelines.home'), icon: faHome, - action: () => { this.setSrc('home') } + action: () => { this.src = 'home'; this.saveSrc(); } }, this.meta.disableLocalTimeline && !this.$store.state.i.isModerator && !this.$store.state.i.isAdmin ? undefined : { text: this.$t('_timelines.local'), icon: faComments, - action: () => { this.setSrc('local') } + action: () => { this.src = 'local'; this.saveSrc(); } }, this.meta.disableLocalTimeline && !this.$store.state.i.isModerator && !this.$store.state.i.isAdmin ? undefined : { text: this.$t('_timelines.social'), icon: faShareAlt, - action: () => { this.setSrc('social') } + action: () => { this.src = 'social'; this.saveSrc(); } }, this.meta.disableGlobalTimeline && !this.$store.state.i.isModerator && !this.$store.state.i.isAdmin ? undefined : { text: this.$t('_timelines.global'), icon: faGlobe, - action: () => { this.setSrc('global') } - }, antennaItems.length > 0 ? null : undefined, ...antennaItems, listItems.length > 0 ? null : undefined, ...listItems], + action: () => { this.src = 'global'; this.saveSrc(); } + }, antennaItems.length > 0 ? null : undefined, ...antennaItems, listItems.length > 0 ? null : undefined, ...listItems, channelItems.length > 0 ? null : undefined, ...channelItems], fixed: true, noCenter: true, source: ev.currentTarget || ev.target @@ -174,14 +197,13 @@ export default Vue.extend({ }); }, - setSrc(src) { - this.src = src; - }, - saveSrc() { this.$store.commit('deviceUser/setTl', { src: this.src, - arg: this.src == 'list' ? this.list : this.antenna + arg: + this.src === 'list' ? this.list : + this.src === 'antenna' ? this.antenna : + this.channel }); }, diff --git a/src/client/pages/messaging/messaging-room.form.vue b/src/client/pages/messaging/messaging-room.form.vue index 1c33eaa76e..eda8914c4a 100644 --- a/src/client/pages/messaging/messaging-room.form.vue +++ b/src/client/pages/messaging/messaging-room.form.vue @@ -53,7 +53,7 @@ export default Vue.extend({ }; }, computed: { - draftId(): string { + draftKey(): string { return this.user ? 'user:' + this.user.id : 'group:' + this.group.id; }, canSend(): boolean { @@ -79,7 +79,7 @@ export default Vue.extend({ autosize(this.$refs.text); // 書きかけの投稿を復元 - const draft = JSON.parse(localStorage.getItem('message_drafts') || '{}')[this.draftId]; + const draft = JSON.parse(localStorage.getItem('message_drafts') || '{}')[this.draftKey]; if (draft) { this.text = draft.data.text; this.file = draft.data.file; @@ -199,7 +199,7 @@ export default Vue.extend({ saveDraft() { const data = JSON.parse(localStorage.getItem('message_drafts') || '{}'); - data[this.draftId] = { + data[this.draftKey] = { updatedAt: new Date(), data: { text: this.text, @@ -213,7 +213,7 @@ export default Vue.extend({ deleteDraft() { const data = JSON.parse(localStorage.getItem('message_drafts') || '{}'); - delete data[this.draftId]; + delete data[this.draftKey]; localStorage.setItem('message_drafts', JSON.stringify(data)); }, diff --git a/src/client/pages/my-settings/index.vue b/src/client/pages/my-settings/index.vue index 16e786bfc8..6fb3116912 100644 --- a/src/client/pages/my-settings/index.vue +++ b/src/client/pages/my-settings/index.vue @@ -3,11 +3,11 @@ <portal to="icon"><fa :icon="faCog"/></portal> <portal to="title">{{ $t('accountSettings') }}</portal> - <x-profile-setting/> - <x-privacy-setting/> - <x-reaction-setting/> + <x-profile-setting class="_vMargin"/> + <x-privacy-setting class="_vMargin"/> + <x-reaction-setting class="_vMargin"/> - <section class="_card"> + <section class="_card _vMargin"> <div class="_title"><fa :icon="faCog"/> {{ $t('general') }}</div> <div class="_content"> <mk-switch v-model="$store.state.i.autoWatch" @change="onChangeAutoWatch"> @@ -24,14 +24,14 @@ </div> </section> - <x-import-export/> - <x-drive/> - <x-mute-block/> - <x-word-mute/> - <x-security/> - <x-2fa/> - <x-integration/> - <x-api/> + <x-import-export class="_vMargin"/> + <x-drive class="_vMargin"/> + <x-mute-block class="_vMargin"/> + <x-word-mute class="_vMargin"/> + <x-security class="_vMargin"/> + <x-2fa class="_vMargin"/> + <x-integration class="_vMargin"/> + <x-api class="_vMargin"/> <router-link class="_panel _buttonPrimary" to="/my/apps" style="margin: var(--margin) auto;">{{ $t('installedApps') }}</router-link> diff --git a/src/client/pages/preferences/index.vue b/src/client/pages/preferences/index.vue index a2a5ab80f4..9d3959fcc2 100644 --- a/src/client/pages/preferences/index.vue +++ b/src/client/pages/preferences/index.vue @@ -5,11 +5,11 @@ <router-link v-if="$store.getters.isSignedIn" class="_panel _buttonPrimary" to="/my/settings" style="margin-bottom: var(--margin);">{{ $t('accountSettings') }}</router-link> - <x-theme/> + <x-theme class="_vMargin"/> - <x-sidebar/> + <x-sidebar class="_vMargin"/> - <x-plugins/> + <x-plugins class="_vMargin"/> <section class="_card _vMargin"> <div class="_title"><fa :icon="faMusic"/> {{ $t('sounds') }}</div> @@ -50,6 +50,11 @@ <option v-for="sound in sounds" :value="sound" :key="sound">{{ sound || $t('none') }}</option> <template #text><button class="_textButton" @click="listen(sfxAntenna)" v-if="sfxAntenna"><fa :icon="faPlay"/> {{ $t('listen') }}</button></template> </mk-select> + <mk-select v-model="sfxChannel"> + <template #label>{{ $t('_sfx.channel') }}</template> + <option v-for="sound in sounds" :value="sound" :key="sound">{{ sound || $t('none') }}</option> + <template #text><button class="_textButton" @click="listen(sfxChannel)" v-if="sfxChannel"><fa :icon="faPlay"/> {{ $t('listen') }}</button></template> + </mk-select> </div> </section> @@ -142,10 +147,14 @@ const sounds = [ 'syuilo/pirori', 'syuilo/pirori-wet', 'syuilo/pirori-square-wet', + 'syuilo/square-pico', + 'syuilo/reverved', + 'syuilo/ryukyu', 'aisha/1', 'aisha/2', 'aisha/3', 'noizenecio/kick_gaba', + 'noizenecio/kick_gaba2', ]; export default Vue.extend({ @@ -272,6 +281,11 @@ export default Vue.extend({ set(value) { this.$store.commit('device/set', { key: 'sfxAntenna', value }); } }, + sfxChannel: { + get() { return this.$store.state.device.sfxChannel; }, + set(value) { this.$store.commit('device/set', { key: 'sfxChannel', value }); } + }, + volumeIcon: { get() { return this.sfxVolume === 0 ? faVolumeMute : faVolumeUp; |