From 43930e6a84d11fb00b9ae9ac153c2538e179d538 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 19 Dec 2020 10:55:52 +0900 Subject: [PATCH] Storage improve (#6976) * wip * wip * wip * wip * wip * Update storage.ts * wip * wip * wip * wip * Update storage.ts * Update storage.ts * wip * wip * wip * wip * wip * wip * wip * Update storage.ts * wip * wip * wip * wip * :pizza: * wip * wip * wip * wip * wip * wip * Update deck-storage.ts * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * Update store.ts * wip * wip * wip * wip * Update init.ts * wip * wip * Update pizzax.ts * wip * wip * Update timeline.vue * Update init.ts * wip * wip * Update init.ts --- package.json | 2 - src/client/@types/vuex-shim.d.ts | 12 - src/client/account.ts | 86 ++ src/client/cold-storage.ts | 34 - src/client/components/analog-clock.vue | 10 - src/client/components/autocomplete.vue | 12 +- src/client/components/captcha.vue | 3 +- src/client/components/date-separated-list.vue | 4 +- .../components/drive-file-thumbnail.vue | 5 +- src/client/components/drive.file.vue | 4 +- src/client/components/drive.folder.vue | 14 +- src/client/components/drive.vue | 4 +- src/client/components/emoji-picker.vue | 21 +- src/client/components/form/form.scss | 2 + src/client/components/global/a.vue | 14 +- src/client/components/global/acct.vue | 2 +- src/client/components/global/avatar.vue | 2 +- src/client/components/global/emoji.vue | 6 +- src/client/components/global/error.vue | 2 +- src/client/components/google.vue | 2 +- src/client/components/instance-stats.vue | 2 +- src/client/components/launch-pad.vue | 2 +- src/client/components/media-banner.vue | 5 +- src/client/components/media-image.vue | 10 +- src/client/components/media-video.vue | 2 +- src/client/components/mention.vue | 6 +- src/client/components/mfm.ts | 14 +- src/client/components/note.sub.vue | 2 +- src/client/components/note.vue | 46 +- src/client/components/notes.vue | 2 +- src/client/components/notifications.vue | 8 +- src/client/components/page/page.post.vue | 6 +- src/client/components/page/page.text.vue | 2 +- src/client/components/page/page.vue | 4 +- src/client/components/post-form.vue | 28 +- .../components/reactions-viewer.reaction.vue | 2 +- src/client/components/reactions-viewer.vue | 2 +- src/client/components/sample.vue | 2 +- src/client/components/sidebar.vue | 42 +- src/client/components/signin.vue | 6 +- src/client/components/signup.vue | 6 +- src/client/components/sub-note-content.vue | 2 +- src/client/components/timeline.vue | 10 +- src/client/components/ui/context-menu.vue | 2 +- src/client/components/ui/modal.vue | 4 +- src/client/components/ui/pagination.vue | 2 +- src/client/components/ui/window.vue | 2 +- src/client/components/url-preview.vue | 2 +- src/client/components/user-info.vue | 4 +- src/client/components/user-list.vue | 2 +- src/client/components/user-preview.vue | 4 +- src/client/components/user-select-dialog.vue | 6 +- src/client/components/users-dialog.vue | 2 +- src/client/init.ts | 224 +++--- src/client/instance.ts | 45 ++ src/client/os.ts | 7 +- src/client/pages/_error_.vue | 2 +- src/client/pages/about-misskey.vue | 4 +- src/client/pages/about.vue | 2 +- src/client/pages/announcements.vue | 4 +- src/client/pages/auth.vue | 10 +- src/client/pages/channel.vue | 4 +- src/client/pages/channels.vue | 2 +- src/client/pages/clip.vue | 4 +- src/client/pages/explore.vue | 2 +- src/client/pages/follow-requests.vue | 2 +- src/client/pages/instance/index.metrics.vue | 2 +- src/client/pages/instance/index.vue | 2 +- src/client/pages/instance/instance.vue | 2 +- src/client/pages/instance/queue.chart.vue | 2 +- src/client/pages/instance/settings.vue | 3 +- src/client/pages/instance/user-dialog.vue | 2 +- src/client/pages/messaging/index.vue | 6 +- .../pages/messaging/messaging-room.form.vue | 6 +- .../messaging/messaging-room.message.vue | 4 +- src/client/pages/messaging/messaging-room.vue | 8 +- src/client/pages/mfm-cheat-sheet.vue | 2 +- src/client/pages/miauth.vue | 6 +- src/client/pages/page-editor/page-editor.vue | 2 +- src/client/pages/page.vue | 4 +- src/client/pages/pages.vue | 2 +- src/client/pages/reversi/game.board.vue | 20 +- src/client/pages/reversi/game.setting.vue | 16 +- src/client/pages/reversi/index.vue | 2 +- src/client/pages/room/room.vue | 7 +- src/client/pages/settings/2fa.vue | 22 +- src/client/pages/settings/account-info.vue | 18 +- src/client/pages/settings/deck.vue | 26 +- src/client/pages/settings/drive.vue | 10 +- src/client/pages/settings/email-address.vue | 6 +- src/client/pages/settings/email.vue | 6 +- src/client/pages/settings/general.vue | 99 +-- src/client/pages/settings/index.vue | 8 +- src/client/pages/settings/integration.vue | 6 +- src/client/pages/settings/notifications.vue | 4 +- src/client/pages/settings/other.vue | 2 +- src/client/pages/settings/plugins.vue | 35 +- src/client/pages/settings/privacy.vue | 26 +- src/client/pages/settings/profile.vue | 46 +- src/client/pages/settings/reaction.vue | 22 +- src/client/pages/settings/regedit.vue | 75 -- src/client/pages/settings/sidebar.vue | 17 +- src/client/pages/settings/sounds.vue | 30 +- src/client/pages/settings/theme.install.vue | 9 +- src/client/pages/settings/theme.manage.vue | 14 +- src/client/pages/settings/theme.vue | 134 ++-- src/client/pages/settings/word-mute.vue | 6 +- src/client/pages/test.vue | 2 +- src/client/pages/theme-editor.vue | 9 +- src/client/pages/timeline.tutorial.vue | 4 +- src/client/pages/timeline.vue | 22 +- src/client/pages/user/index.photos.vue | 4 +- src/client/pages/user/index.vue | 18 +- src/client/pages/welcome.setup.vue | 4 +- src/client/pizzax.ts | 124 +++ src/client/router.ts | 4 +- src/client/scripts/aiscript/api.ts | 8 +- src/client/scripts/get-user-menu.ts | 11 +- src/client/scripts/please-login.ts | 4 +- src/client/scripts/sound.ts | 6 +- src/client/sidebar.ts | 40 +- src/client/store.ts | 742 +++++++----------- src/client/tsconfig.json | 2 +- src/client/ui/_common_/common.vue | 6 +- src/client/ui/_common_/header.vue | 2 +- src/client/ui/_common_/stream-indicator.vue | 2 +- src/client/ui/deck.vue | 25 +- src/client/ui/deck/antenna-column.vue | 6 +- src/client/ui/deck/column.vue | 22 +- src/client/ui/deck/deck-store.ts | 223 ++++++ src/client/ui/deck/list-column.vue | 6 +- src/client/ui/deck/notifications-column.vue | 4 +- src/client/ui/deck/tl-column.vue | 14 +- src/client/ui/deck/widgets-column.vue | 30 +- src/client/ui/default.vue | 21 +- src/client/ui/default.widgets.vue | 21 +- src/client/ui/desktop.vue | 7 +- src/client/ui/visitor/a.vue | 11 +- src/client/ui/visitor/b.vue | 9 +- src/client/ui/visitor/kanban.vue | 2 +- src/client/ui/zen.vue | 7 +- src/client/widgets/activity.vue | 2 +- src/client/widgets/define.ts | 9 +- src/client/widgets/memo.vue | 9 +- src/client/widgets/photos.vue | 2 +- yarn.lock | 20 +- 146 files changed, 1458 insertions(+), 1519 deletions(-) delete mode 100644 src/client/@types/vuex-shim.d.ts create mode 100644 src/client/account.ts delete mode 100644 src/client/cold-storage.ts create mode 100644 src/client/instance.ts delete mode 100644 src/client/pages/settings/regedit.vue create mode 100644 src/client/pizzax.ts create mode 100644 src/client/ui/deck/deck-store.ts diff --git a/package.json b/package.json index dbda3bc3d8..785400ec4c 100644 --- a/package.json +++ b/package.json @@ -251,8 +251,6 @@ "vue-router": "4.0.1", "vue-style-loader": "4.1.2", "vuedraggable": "4.0.1", - "vuex": "4.0.0-rc.2", - "vuex-persistedstate": "3.1.0", "web-push": "3.4.4", "webpack": "5.10.1", "webpack-cli": "4.2.0", diff --git a/src/client/@types/vuex-shim.d.ts b/src/client/@types/vuex-shim.d.ts deleted file mode 100644 index 5bcc4c460e..0000000000 --- a/src/client/@types/vuex-shim.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ComponentCustomProperties } from 'vue'; -import { Store } from 'vuex'; - -declare module '@vue/runtime-core' { - // tslint:disable-next-line:no-empty-interface - interface State { - } - - interface ComponentCustomProperties { - $store: Store; - } -} diff --git a/src/client/account.ts b/src/client/account.ts new file mode 100644 index 0000000000..fdf49ee213 --- /dev/null +++ b/src/client/account.ts @@ -0,0 +1,86 @@ +import { reactive } from 'vue'; +import { apiUrl } from '@/config'; +import { waiting } from '@/os'; + +// TODO: 他のタブと永続化されたstateを同期 + +type Account = { + id: string; + token: string; + clientData: Record; +}; + +const data = localStorage.getItem('account'); + +// TODO: 外部からはreadonlyに +export const $i = data ? reactive(JSON.parse(data) as Account) : null; + +export function signout() { + localStorage.removeItem('account'); + document.cookie = `igi=; path=/`; + location.href = '/'; +} + +export function getAccounts() { + const accountsData = localStorage.getItem('accounts'); + const accounts: { id: Account['id'], token: Account['token'] }[] = accountsData ? JSON.parse(accountsData) : []; + return accounts; +} + +export function addAccount(id: Account['id'], token: Account['token']) { + const accounts = getAccounts(); + if (!accounts.some(x => x.id === id)) { + localStorage.setItem('accounts', JSON.stringify(accounts.concat([{ id, token }]))); + } +} + +function fetchAccount(token): Promise { + return new Promise((done, fail) => { + // Fetch user + fetch(`${apiUrl}/i`, { + method: 'POST', + body: JSON.stringify({ + i: token + }) + }) + .then(res => { + // When failed to authenticate user + if (res.status !== 200 && res.status < 500) { + return signout(); + } + + // Parse response + res.json().then(i => { + i.token = token; + done(i); + }); + }) + .catch(fail); + }); +} + +export function updateAccount(data) { + for (const [key, value] of Object.entries(data)) { + $i[key] = value; + } +} + +export function refreshAccount() { + fetchAccount($i.token).then(updateAccount); +} + +export async function login(token: Account['token']) { + waiting(); + if (_DEV_) console.log('logging as token ', token); + const me = await fetchAccount(token); + localStorage.setItem('account', JSON.stringify(me)); + addAccount(me.id, token); + location.reload(); +} + +// このファイルに書きたくないけどここに書かないと何故かVeturが認識しない +declare module '@vue/runtime-core' { + interface ComponentCustomProperties { + $i: typeof $i; + } +} diff --git a/src/client/cold-storage.ts b/src/client/cold-storage.ts deleted file mode 100644 index 1bee2313fa..0000000000 --- a/src/client/cold-storage.ts +++ /dev/null @@ -1,34 +0,0 @@ -// 常にメモリにロードしておく必要がないような設定情報を保管するストレージ - -const PREFIX = 'miux:'; - -export const defaultDeviceSettings = { - sound_masterVolume: 0.3, - sound_note: { type: 'syuilo/down', volume: 1 }, - sound_noteMy: { type: 'syuilo/up', volume: 1 }, - sound_notification: { type: 'syuilo/pope2', volume: 1 }, - sound_chat: { type: 'syuilo/pope1', volume: 1 }, - sound_chatBg: { type: 'syuilo/waon', volume: 1 }, - sound_antenna: { type: 'syuilo/triple', volume: 1 }, - sound_channel: { type: 'syuilo/square-pico', volume: 1 }, - sound_reversiPutBlack: { type: 'syuilo/kick', volume: 0.3 }, - sound_reversiPutWhite: { type: 'syuilo/snare', volume: 0.3 }, -}; - -export const device = { - get(key: T): typeof defaultDeviceSettings[T] { - // TODO: indexedDBにする - // ただしその際はnullチェックではなくキー存在チェックにしないとダメ - // (indexedDBはnullを保存できるため、ユーザーが意図してnullを格納した可能性がある) - const value = localStorage.getItem(PREFIX + key); - if (value == null) { - return defaultDeviceSettings[key]; - } else { - return JSON.parse(value); - } - }, - - set(key: keyof typeof defaultDeviceSettings, value: any): any { - localStorage.setItem(PREFIX + key, JSON.stringify(value)); - }, -}; diff --git a/src/client/components/analog-clock.vue b/src/client/components/analog-clock.vue index b3fb7a515d..04d98508bb 100644 --- a/src/client/components/analog-clock.vue +++ b/src/client/components/analog-clock.vue @@ -116,16 +116,6 @@ export default defineComponent({ } }; update(); - - this.$store.subscribe((mutation, state) => { - if (mutation.type !== 'device/set') return; - - if (mutation?.payload?.key !== 'theme') return; - - setTimeout(() => { - this.computedStyle = getComputedStyle(document.documentElement); - }, 250); - }); }, beforeUnmount() { diff --git a/src/client/components/autocomplete.vue b/src/client/components/autocomplete.vue index 0b81c58727..c3eaa36efb 100644 --- a/src/client/components/autocomplete.vue +++ b/src/client/components/autocomplete.vue @@ -17,8 +17,8 @@
  1. - - + + {{ emoji.emoji }} ({{ emoji.aliasOf }}) @@ -128,12 +128,6 @@ export default defineComponent({ } }, - computed: { - useOsNativeEmojis(): boolean { - return this.$store.state.device.useOsNativeEmojis; - } - }, - watch: { showing() { if (!this.showing) { @@ -151,7 +145,7 @@ export default defineComponent({ this.setPosition(); //#region Construct Emoji DB - const customEmojis = this.$store.state.instance.meta.emojis; + const customEmojis = this.$instance.emojis; const emojiDefinitions: EmojiDef[] = []; for (const x of customEmojis) { diff --git a/src/client/components/captcha.vue b/src/client/components/captcha.vue index 94a13a8b5b..f37f395567 100644 --- a/src/client/components/captcha.vue +++ b/src/client/components/captcha.vue @@ -28,7 +28,6 @@ declare global { interface Window extends CaptchaContainer { } } -import * as os from '@/os'; export default defineComponent({ props: { @@ -101,7 +100,7 @@ export default defineComponent({ if (this.captcha.render && this.$refs.captcha instanceof Element) { this.captcha.render(this.$refs.captcha, { sitekey: this.sitekey, - theme: this.$store.state.device.darkMode ? 'dark' : 'light', + theme: this.$store.state.darkMode ? 'dark' : 'light', callback: this.callback, 'expired-callback': this.callback, 'error-callback': this.callback, diff --git a/src/client/components/date-separated-list.vue b/src/client/components/date-separated-list.vue index c79afb52f3..3336fab9bd 100644 --- a/src/client/components/date-separated-list.vue +++ b/src/client/components/date-separated-list.vue @@ -37,12 +37,14 @@ export default defineComponent({ }); } - return h(this.$store.state.device.animation ? TransitionGroup : 'div', { + return h(this.$store.state.animation ? TransitionGroup : 'div', this.$store.state.animation ? { class: 'sqadhkmv _list_', name: 'list', tag: 'div', 'data-direction': this.direction, 'data-reversed': this.reversed ? 'true' : 'false', + } : { + class: 'sqadhkmv _list_', }, this.items.map((item, i) => { const el = this.$slots.default({ item: item diff --git a/src/client/components/drive-file-thumbnail.vue b/src/client/components/drive-file-thumbnail.vue index 7615014ba9..e669da6a90 100644 --- a/src/client/components/drive-file-thumbnail.vue +++ b/src/client/components/drive-file-thumbnail.vue @@ -27,6 +27,7 @@ import { faFilm } from '@fortawesome/free-solid-svg-icons'; import ImgWithBlurhash from './img-with-blurhash.vue'; +import { ColdDeviceStorage } from '@/store'; export default defineComponent({ components: { @@ -89,12 +90,12 @@ export default defineComponent({ }, mounted() { const audioTag = this.$refs.volumectrl as HTMLAudioElement; - if (audioTag) audioTag.volume = this.$store.state.device.mediaVolume; + if (audioTag) audioTag.volume = ColdDeviceStorage.get('mediaVolume'); }, methods: { volumechange() { const audioTag = this.$refs.volumectrl as HTMLAudioElement; - this.$store.commit('device/set', { key: 'mediaVolume', value: audioTag.volume }); + ColdDeviceStorage.set('mediaVolume', audioTag.volume); } } }); diff --git a/src/client/components/drive.file.vue b/src/client/components/drive.file.vue index 261bbc83ec..81e314a725 100644 --- a/src/client/components/drive.file.vue +++ b/src/client/components/drive.file.vue @@ -8,11 +8,11 @@ @dragend="onDragend" :title="title" > -
    +

    {{ $t('avatar') }}

    -
    +

    {{ $t('banner') }}

    diff --git a/src/client/components/drive.folder.vue b/src/client/components/drive.folder.vue index ab678217b6..79ae789f78 100644 --- a/src/client/components/drive.folder.vue +++ b/src/client/components/drive.folder.vue @@ -19,7 +19,7 @@ {{ folder.name }}

    -

    +

    {{ $t('uploadFolder') }}

    @@ -213,11 +213,8 @@ export default defineComponent({ os.api('drive/folders/delete', { folderId: this.folder.id }).then(() => { - if (this.$store.state.settings.uploadFolder === this.folder.id) { - this.$store.dispatch('settings/set', { - key: 'uploadFolder', - value: null - }); + if (this.$store.state.uploadFolder === this.folder.id) { + this.$store.set('uploadFolder', null); } }).catch(err => { switch(err.id) { @@ -238,10 +235,7 @@ export default defineComponent({ }, setAsUploadFolder() { - this.$store.dispatch('settings/set', { - key: 'uploadFolder', - value: this.folder.id - }); + this.$store.set('uploadFolder', this.folder.id); }, onContextmenu(e) { diff --git a/src/client/components/drive.vue b/src/client/components/drive.vue index f25d25da01..a743249b9d 100644 --- a/src/client/components/drive.vue +++ b/src/client/components/drive.vue @@ -136,7 +136,7 @@ export default defineComponent({ }, mounted() { - if (this.$store.state.device.enableInfiniteScroll && this.$refs.loadMoreFiles) { + if (this.$store.state.enableInfiniteScroll && this.$refs.loadMoreFiles) { this.$nextTick(() => { this.ilFilesObserver.observe((this.$refs.loadMoreFiles as Vue).$el) }); @@ -159,7 +159,7 @@ export default defineComponent({ }, activated() { - if (this.$store.state.device.enableInfiniteScroll) { + if (this.$store.state.enableInfiniteScroll) { this.$nextTick(() => { this.ilFilesObserver.observe((this.$refs.loadMoreFiles as Vue).$el) }); diff --git a/src/client/components/emoji-picker.vue b/src/client/components/emoji-picker.vue index 30d0e060ba..a9fa357086 100644 --- a/src/client/components/emoji-picker.vue +++ b/src/client/components/emoji-picker.vue @@ -13,7 +13,7 @@ tabindex="0" > - +
    @@ -45,7 +45,7 @@
    {{ $t('recentUsed') }}
    -
    @@ -100,6 +100,7 @@ import MkModal from '@/components/ui/modal.vue'; import Particle from '@/components/particle.vue'; import * as os from '@/os'; import { isDeviceTouch } from '../scripts/is-device-touch'; +import { emojiCategories } from '@/instance'; export default defineComponent({ components: { @@ -125,12 +126,12 @@ export default defineComponent({ return { emojilist: markRaw(emojilist), getStaticImageUrl, - pinned: this.$store.state.settings.reactions, - width: this.asReactionPicker ? this.$store.state.device.reactionPickerWidth : 3, - height: this.asReactionPicker ? this.$store.state.device.reactionPickerHeight : 2, + pinned: this.$store.state.reactions, + width: this.asReactionPicker ? this.$store.state.reactionPickerWidth : 3, + height: this.asReactionPicker ? this.$store.state.reactionPickerHeight : 2, big: this.asReactionPicker ? isDeviceTouch : false, - customEmojiCategories: this.$store.getters['instance/emojiCategories'], - customEmojis: this.$store.state.instance.meta.emojis, + customEmojiCategories: emojiCategories, + customEmojis: this.$instance.emojis, visibleCategories: {}, q: null, searchResultCustom: [], @@ -346,10 +347,10 @@ export default defineComponent({ // 最近使った絵文字更新 if (!this.pinned.includes(key)) { - let recents = this.$store.state.device.recentlyUsedEmojis; + let recents = this.$store.state.recentlyUsedEmojis; recents = recents.filter((e: any) => e !== key); recents.unshift(key); - this.$store.commit('device/set', { key: 'recentlyUsedEmojis', value: recents.splice(0, 16) }); + this.$store.set('recentlyUsedEmojis', recents.splice(0, 16)); } }, diff --git a/src/client/components/form/form.scss b/src/client/components/form/form.scss index b541bf826d..b6747bf738 100644 --- a/src/client/components/form/form.scss +++ b/src/client/components/form/form.scss @@ -12,6 +12,7 @@ ._formLabel { font-size: 80%; padding: 0 16px 8px 16px; + opacity: 0.8; &:empty { display: none; @@ -21,6 +22,7 @@ ._formCaption { font-size: 80%; padding: 8px 16px 0 16px; + opacity: 0.8; &:empty { display: none; diff --git a/src/client/components/global/a.vue b/src/client/components/global/a.vue index f6c66257b3..e936003018 100644 --- a/src/client/components/global/a.vue +++ b/src/client/components/global/a.vue @@ -12,6 +12,7 @@ import copyToClipboard from '@/scripts/copy-to-clipboard'; import { router } from '@/router'; import { ui, url } from '@/config'; import { popout } from '@/scripts/popout'; +import { ColdDeviceStorage } from '@/store'; export default defineComponent({ inject: { @@ -98,8 +99,8 @@ export default defineComponent({ nav() { if (this.to.startsWith('/my/messaging')) { - if (this.$store.state.device.chatOpenBehavior === 'window') return this.window(); - if (this.$store.state.device.chatOpenBehavior === 'popout') return this.popout(); + if (ColdDeviceStorage.get('chatOpenBehavior') === 'window') return this.window(); + if (ColdDeviceStorage.get('chatOpenBehavior') === 'popout') return this.popout(); } if (this.behavior) { @@ -111,12 +112,13 @@ export default defineComponent({ if (this.navHook) { this.navHook(this.to); } else { - if (this.$store.state.device.defaultSideView && this.sideViewHook && this.to !== '/') { + if (this.$store.state.defaultSideView && this.sideViewHook && this.to !== '/') { return this.sideViewHook(this.to); } - if (this.$store.state.device.deckNavWindow && (ui === 'deck') && this.to !== '/') { - return this.window(); - } + // TODO: a.vueからdeck-sotreを参照したくないのでなんとかする + //if (deckStore.state.device.deckNavWindow && (ui === 'deck') && this.to !== '/') { + // return this.window(); + //} if (ui === 'desktop') { return this.window(); } diff --git a/src/client/components/global/acct.vue b/src/client/components/global/acct.vue index 9d434de6cd..cad906524e 100644 --- a/src/client/components/global/acct.vue +++ b/src/client/components/global/acct.vue @@ -1,7 +1,7 @@ diff --git a/src/client/components/global/avatar.vue b/src/client/components/global/avatar.vue index 1cfead919d..5723ea04b6 100644 --- a/src/client/components/global/avatar.vue +++ b/src/client/components/global/avatar.vue @@ -38,7 +38,7 @@ export default defineComponent({ return this.user.isCat; }, url(): string { - return this.$store.state.device.disableShowingAnimatedImages + return this.$store.state.disableShowingAnimatedImages ? getStaticImageUrl(this.user.avatarUrl) : this.user.avatarUrl; }, diff --git a/src/client/components/global/emoji.vue b/src/client/components/global/emoji.vue index e93cdb6f3b..5a715fe09a 100644 --- a/src/client/components/global/emoji.vue +++ b/src/client/components/global/emoji.vue @@ -54,13 +54,13 @@ export default defineComponent({ }, useOsNativeEmojis(): boolean { - return this.$store.state.device.useOsNativeEmojis && !this.isReaction; + return this.$store.state.useOsNativeEmojis && !this.isReaction; }, ce() { let ce = []; if (this.customEmojis) ce = ce.concat(this.customEmojis); - if (this.$store.state.instance.meta && this.$store.state.instance.meta.emojis) ce = ce.concat(this.$store.state.instance.meta.emojis); + if (this.$instance && this.$instance.emojis) ce = ce.concat(this.$instance.emojis); return ce; } }, @@ -72,7 +72,7 @@ export default defineComponent({ const customEmoji = this.ce.find(x => x.name === this.emoji.substr(1, this.emoji.length - 2)); if (customEmoji) { this.customEmoji = customEmoji; - this.url = this.$store.state.device.disableShowingAnimatedImages + this.url = this.$store.state.disableShowingAnimatedImages ? getStaticImageUrl(customEmoji.url) : customEmoji.url; } diff --git a/src/client/components/global/error.vue b/src/client/components/global/error.vue index 311093dacf..e4c76faa31 100644 --- a/src/client/components/global/error.vue +++ b/src/client/components/global/error.vue @@ -1,5 +1,5 @@
    -
    diff --git a/src/client/components/timeline.vue b/src/client/components/timeline.vue index 011f22ee17..33e7256325 100644 --- a/src/client/components/timeline.vue +++ b/src/client/components/timeline.vue @@ -1,5 +1,5 @@ diff --git a/src/client/pages/settings/sidebar.vue b/src/client/pages/settings/sidebar.vue index 4138aaf733..d835f57b55 100644 --- a/src/client/pages/settings/sidebar.vue +++ b/src/client/pages/settings/sidebar.vue @@ -26,9 +26,9 @@ import FormRadios from '@/components/form/radios.vue'; import FormBase from '@/components/form/base.vue'; import FormGroup from '@/components/form/group.vue'; import FormButton from '@/components/form/button.vue'; -import { defaultDeviceUserSettings } from '@/store'; import * as os from '@/os'; import { sidebarDef } from '@/sidebar'; +import { defaultStore } from '@/store'; export default defineComponent({ components: { @@ -57,14 +57,11 @@ export default defineComponent({ return this.items.trim().split('\n').filter(x => x.trim() !== ''); }, - sidebarDisplay: { - get() { return this.$store.state.device.sidebarDisplay; }, - set(value) { this.$store.commit('device/set', { key: 'sidebarDisplay', value }); } - }, + sidebarDisplay: defaultStore.makeGetterSetter('sidebarDisplay') }, created() { - this.items = this.$store.state.deviceUser.menu.join('\n'); + this.items = this.$store.state.menu.join('\n'); }, mounted() { @@ -73,7 +70,7 @@ export default defineComponent({ methods: { async addItem() { - const menu = Object.keys(this.menuDef).filter(k => !this.$store.state.deviceUser.menu.includes(k)); + const menu = Object.keys(this.menuDef).filter(k => !this.$store.state.menu.includes(k)); const { canceled, result: item } = await os.dialog({ type: null, title: this.$t('addItem'), @@ -92,12 +89,12 @@ export default defineComponent({ }, save() { - this.$store.commit('deviceUser/setMenu', this.splited); + this.$store.set('menu', this.splited); }, reset() { - this.$store.commit('deviceUser/setMenu', defaultDeviceUserSettings.menu); - this.items = this.$store.state.deviceUser.menu.join('\n'); + this.$store.reset('menu'); + this.items = this.$store.state.menu.join('\n'); }, }, }); diff --git a/src/client/pages/settings/sounds.vue b/src/client/pages/settings/sounds.vue index f19be54e82..d254dc4cfb 100644 --- a/src/client/pages/settings/sounds.vue +++ b/src/client/pages/settings/sounds.vue @@ -26,7 +26,7 @@ import FormBase from '@/components/form/base.vue'; import FormButton from '@/components/form/button.vue'; import FormGroup from '@/components/form/group.vue'; import * as os from '@/os'; -import { device, defaultDeviceSettings } from '@/cold-storage'; +import { ColdDeviceStorage } from '@/store'; import { playFile } from '@/scripts/sound'; const soundsTypes = [ @@ -79,8 +79,8 @@ export default defineComponent({ computed: { masterVolume: { // TODO: (外部)関数にcomputedを使うのはアレなので直す - get() { return device.get('sound_masterVolume'); }, - set(value) { device.set('sound_masterVolume', value); } + get() { return ColdDeviceStorage.get('sound_masterVolume'); }, + set(value) { ColdDeviceStorage.set('sound_masterVolume', value); } }, volumeIcon() { return this.masterVolume === 0 ? faVolumeMute : faVolumeUp; @@ -88,15 +88,15 @@ export default defineComponent({ }, created() { - this.sounds.note = device.get('sound_note'); - this.sounds.noteMy = device.get('sound_noteMy'); - this.sounds.notification = device.get('sound_notification'); - this.sounds.chat = device.get('sound_chat'); - this.sounds.chatBg = device.get('sound_chatBg'); - this.sounds.antenna = device.get('sound_antenna'); - this.sounds.channel = device.get('sound_channel'); - this.sounds.reversiPutBlack = device.get('sound_reversiPutBlack'); - this.sounds.reversiPutWhite = device.get('sound_reversiPutWhite'); + this.sounds.note = ColdDeviceStorage.get('sound_note'); + this.sounds.noteMy = ColdDeviceStorage.get('sound_noteMy'); + this.sounds.notification = ColdDeviceStorage.get('sound_notification'); + this.sounds.chat = ColdDeviceStorage.get('sound_chat'); + this.sounds.chatBg = ColdDeviceStorage.get('sound_chatBg'); + this.sounds.antenna = ColdDeviceStorage.get('sound_antenna'); + this.sounds.channel = ColdDeviceStorage.get('sound_channel'); + this.sounds.reversiPutBlack = ColdDeviceStorage.get('sound_reversiPutBlack'); + this.sounds.reversiPutWhite = ColdDeviceStorage.get('sound_reversiPutWhite'); }, mounted() { @@ -138,14 +138,14 @@ export default defineComponent({ volume: result.volume, }; - device.set('sound_' + type, v); + ColdDeviceStorage.set('sound_' + type, v); this.sounds[type] = v; }, reset() { for (const sound of Object.keys(this.sounds)) { - const v = defaultDeviceSettings['sound_' + sound]; - device.set('sound_' + sound, v); + const v = ColdDeviceStorage.default['sound_' + sound]; + ColdDeviceStorage.set('sound_' + sound, v); this.sounds[sound] = v; } } diff --git a/src/client/pages/settings/theme.install.vue b/src/client/pages/settings/theme.install.vue index c3f2565cca..4ec9764229 100644 --- a/src/client/pages/settings/theme.install.vue +++ b/src/client/pages/settings/theme.install.vue @@ -24,6 +24,7 @@ import FormLink from '@/components/form/link.vue'; import FormButton from '@/components/form/button.vue'; import { applyTheme, validateTheme } from '@/scripts/theme'; import * as os from '@/os'; +import { ColdDeviceStorage } from '@/store'; export default defineComponent({ components: { @@ -73,7 +74,7 @@ export default defineComponent({ }); return false; } - if (this.$store.state.device.themes.some(t => t.id === theme.id)) { + if (ColdDeviceStorage.get('themes').some(t => t.id === theme.id)) { os.dialog({ type: 'info', text: this.$t('_theme.alreadyInstalled') @@ -92,10 +93,8 @@ export default defineComponent({ install(code) { const theme = this.parseThemeCode(code); if (!theme) return; - const themes = this.$store.state.device.themes.concat(theme); - this.$store.commit('device/set', { - key: 'themes', value: themes - }); + const themes = ColdDeviceStorage.get('themes').concat(theme); + ColdDeviceStorage.set('themes', themes); os.dialog({ type: 'success', text: this.$t('_theme.installed', { name: theme.name }) diff --git a/src/client/pages/settings/theme.manage.vue b/src/client/pages/settings/theme.manage.vue index a7bd97a4d5..9fa93aac5f 100644 --- a/src/client/pages/settings/theme.manage.vue +++ b/src/client/pages/settings/theme.manage.vue @@ -34,6 +34,7 @@ import FormButton from '@/components/form/button.vue'; import { Theme, builtinThemes } from '@/scripts/theme'; import copyToClipboard from '@/scripts/copy-to-clipboard'; import * as os from '@/os'; +import { ColdDeviceStorage } from '@/store'; export default defineComponent({ components: { @@ -54,6 +55,7 @@ export default defineComponent({ title: this.$t('_theme.manage'), icon: faFolderOpen }, + installedThemes: ColdDeviceStorage.ref('themes'), builtinThemes, selectedThemeId: null, faPalette, faDownload, faFolderOpen, faCheck, faTrashAlt, faEye @@ -62,11 +64,7 @@ export default defineComponent({ computed: { themes(): Theme[] { - return builtinThemes.concat(this.$store.state.device.themes); - }, - - installedThemes(): Theme[] { - return this.$store.state.device.themes; + return this.builtinThemes.concat(this.installedThemes.value); }, selectedTheme() { @@ -92,10 +90,8 @@ export default defineComponent({ uninstall() { const theme = this.selectedTheme; - const themes = this.$store.state.device.themes.filter(t => t.id != theme.id); - this.$store.commit('device/set', { - key: 'themes', value: themes - }); + const themes = ColdDeviceStorage.get('themes').filter(t => t.id != theme.id); + ColdDeviceStorage.set('themes', themes); os.success(); }, } diff --git a/src/client/pages/settings/theme.vue b/src/client/pages/settings/theme.vue index 50dcf4952c..1536d0cc07 100644 --- a/src/client/pages/settings/theme.vue +++ b/src/client/pages/settings/theme.vue @@ -60,25 +60,25 @@ diff --git a/src/client/pages/settings/word-mute.vue b/src/client/pages/settings/word-mute.vue index 3148c635bc..f02f9bf2f3 100644 --- a/src/client/pages/settings/word-mute.vue +++ b/src/client/pages/settings/word-mute.vue @@ -85,8 +85,8 @@ export default defineComponent({ }, async created() { - this.softMutedWords = this.$store.state.settings.mutedWords.map(x => x.join(' ')).join('\n'); - this.hardMutedWords = this.$store.state.i.mutedWords.map(x => x.join(' ')).join('\n'); + this.softMutedWords = this.$store.state.mutedWords.map(x => x.join(' ')).join('\n'); + this.hardMutedWords = this.$i.mutedWords.map(x => x.join(' ')).join('\n'); this.hardWordMutedNotesCount = (await os.api('i/get-word-muted-notes-count', {})).count; }, @@ -97,7 +97,7 @@ export default defineComponent({ methods: { async save() { - this.$store.dispatch('settings/set', { key: 'mutedWords', value: this.softMutedWords.trim().split('\n').map(x => x.trim().split(' ')) }); + this.$store.set('mutedWords', this.softMutedWords.trim().split('\n').map(x => x.trim().split(' '))); await os.api('i/update', { mutedWords: this.hardMutedWords.trim().split('\n').map(x => x.trim().split(' ')), }); diff --git a/src/client/pages/test.vue b/src/client/pages/test.vue index 77aa264c31..2f890e78a6 100644 --- a/src/client/pages/test.vue +++ b/src/client/pages/test.vue @@ -252,7 +252,7 @@ export default defineComponent({ }, resetTutorial() { - this.$store.dispatch('settings/set', { key: 'tutorial', value: 0 }); + this.$store.set('tutorial', 0); }, } }); diff --git a/src/client/pages/theme-editor.vue b/src/client/pages/theme-editor.vue index 4b1ec59cfe..b2ce1b080e 100644 --- a/src/client/pages/theme-editor.vue +++ b/src/client/pages/theme-editor.vue @@ -107,6 +107,7 @@ import { convertToMisskeyTheme, ThemeValue, convertToViewModel, ThemeViewModel } import { Theme, applyTheme, lightTheme, darkTheme, themeProps, validateTheme } from '@/scripts/theme'; import { host } from '@/config'; import * as os from '@/os'; +import { ColdDeviceStorage } from '@/store'; export default defineComponent({ components: { @@ -128,7 +129,7 @@ export default defineComponent({ name: '', description: '', baseTheme: 'light' as 'dark' | 'light', - author: `@${this.$store.state.i.username}@${toUnicode(host)}`, + author: `@${this.$i.username}@${toUnicode(host)}`, themeToImport: '', changed: false, lightTheme, darkTheme, themeProps, @@ -211,10 +212,8 @@ export default defineComponent({ save() { const theme = convertToMisskeyTheme(this.theme, this.name, this.description, this.author, this.baseTheme); - const themes = this.$store.state.device.themes.concat(theme); - this.$store.commit('device/set', { - key: 'themes', value: themes - }); + const themes = ColdDeviceStorage.get('themes').concat(theme); + ColdDeviceStorage.set('themes', themes); os.dialog({ type: 'success', text: this.$t('_theme.installed', { name: theme.name }) diff --git a/src/client/pages/timeline.tutorial.vue b/src/client/pages/timeline.tutorial.vue index 837915229e..f3347c1463 100644 --- a/src/client/pages/timeline.tutorial.vue +++ b/src/client/pages/timeline.tutorial.vue @@ -83,8 +83,8 @@ export default defineComponent({ computed: { tutorial: { - get() { return this.$store.state.settings.tutorial || 0; }, - set(value) { this.$store.dispatch('settings/set', { key: 'tutorial', value }); } + get() { return this.$store.reactiveState.tutorial.value || 0; }, + set(value) { this.$store.set('tutorial', value); } }, }, }); diff --git a/src/client/pages/timeline.vue b/src/client/pages/timeline.vue index af4de09af0..e0309d46f8 100644 --- a/src/client/pages/timeline.vue +++ b/src/client/pages/timeline.vue @@ -3,8 +3,8 @@
    - - + + this.src === 'home') }]; - if (!this.$store.state.instance.meta.disableLocalTimeline || this.$store.state.i.isModerator || this.$store.state.i.isAdmin) { + if (!this.$instance.disableLocalTimeline || this.$i.isModerator || this.$i.isAdmin) { tabs.push({ id: 'local', title: null, @@ -79,7 +79,7 @@ export default defineComponent({ }); } - if (!this.$store.state.instance.meta.disableGlobalTimeline || this.$store.state.i.isModerator || this.$store.state.i.isAdmin) { + if (!this.$instance.disableGlobalTimeline || this.$i.isModerator || this.$i.isAdmin) { tabs.push({ id: 'global', title: null, @@ -95,7 +95,7 @@ export default defineComponent({ title: null, icon: faEllipsisH, onClick: this.choose, - indicate: computed(() => this.$store.state.i.hasUnreadAntenna || this.$store.state.i.hasUnreadChannel) + indicate: computed(() => this.$i.hasUnreadAntenna || this.$i.hasUnreadChannel) }); return { @@ -118,7 +118,7 @@ export default defineComponent({ }, meta() { - return this.$store.state.instance.meta; + return this.$instance; }, }, @@ -144,13 +144,13 @@ export default defineComponent({ }, created() { - this.src = this.$store.state.deviceUser.tl.src; + this.src = this.$store.state.tl.src; if (this.src === 'list') { - this.list = this.$store.state.deviceUser.tl.arg; + this.list = this.$store.state.tl.arg; } else if (this.src === 'antenna') { - this.antenna = this.$store.state.deviceUser.tl.arg; + this.antenna = this.$store.state.tl.arg; } else if (this.src === 'channel') { - this.channel = this.$store.state.deviceUser.tl.arg; + this.channel = this.$store.state.tl.arg; } }, @@ -218,7 +218,7 @@ export default defineComponent({ }, saveSrc() { - this.$store.commit('deviceUser/setTl', { + this.$store.set('tl', { src: this.src, arg: this.src === 'list' ? this.list : diff --git a/src/client/pages/user/index.photos.vue b/src/client/pages/user/index.photos.vue index 7d498cfb30..8cb72518b2 100644 --- a/src/client/pages/user/index.photos.vue +++ b/src/client/pages/user/index.photos.vue @@ -51,7 +51,7 @@ export default defineComponent({ os.api('users/notes', { userId: this.user.id, fileType: image, - excludeNsfw: this.$store.state.device.nsfw !== 'ignore', + excludeNsfw: this.$store.state.nsfw !== 'ignore', limit: 9, }).then(notes => { for (const note of notes) { @@ -69,7 +69,7 @@ export default defineComponent({ }, methods: { thumbnail(image: any): string { - return this.$store.state.device.disableShowingAnimatedImages + return this.$store.state.disableShowingAnimatedImages ? getStaticImageUrl(image.thumbnailUrl) : image.thumbnailUrl; }, diff --git a/src/client/pages/user/index.vue b/src/client/pages/user/index.vue index ea21f54c64..2efc9b993d 100644 --- a/src/client/pages/user/index.vue +++ b/src/client/pages/user/index.vue @@ -13,7 +13,7 @@
    -
    {{ $t('followsYou') }}
    +
    {{ $t('followsYou') }}
    {{ number(user.notesCount) }} @@ -29,7 +29,7 @@
    - +

    {{ $t('noAccountDescription') }}

    @@ -52,7 +52,7 @@
    - +
    @@ -75,7 +75,7 @@
    - +
    @@ -23,7 +23,7 @@ @@ -56,10 +56,10 @@ export default defineComponent({ computed: { widgets: { get() { - return this.$store.state.deviceUser.widgets; + return this.$store.reactiveState.widgets.value; }, set(value) { - this.$store.commit('deviceUser/setWidgets', value); + this.$store.set('widgets', value); } }, }, @@ -87,20 +87,23 @@ export default defineComponent({ }); if (canceled) return; - this.$store.commit('deviceUser/addWidget', { + this.$store.set('widgets', [...this.$store.state.widgets, { name: widget, id: uuid(), place: null, data: {} - }); + }]); }, removeWidget(widget) { - this.$store.commit('deviceUser/removeWidget', widget); + this.$store.set('widgets', this.$store.state.widgets.filter(w => w.id != widget.id)); }, - saveHome() { - this.$store.commit('deviceUser/setWidgets', this.widgets); + saveWidget(id, data) { + this.$store.set('widgets', this.$store.state.widgets.map(w => w.id === id ? { + ...w, + data: data + } : w)); } } }); diff --git a/src/client/ui/desktop.vue b/src/client/ui/desktop.vue index 6c5159e83f..7c5824c4c0 100644 --- a/src/client/ui/desktop.vue +++ b/src/client/ui/desktop.vue @@ -14,6 +14,7 @@ import XCommon from './_common_/common.vue'; import * as os from '@/os'; import XSidebar from '@/components/sidebar.vue'; import { sidebarDef } from '@/sidebar'; +import { ColdDeviceStorage } from '@/store'; export default defineComponent({ components: { @@ -33,8 +34,8 @@ export default defineComponent({ keymap(): any { return { 'd': () => { - if (this.$store.state.device.syncDeviceDarkMode) return; - this.$store.commit('device/set', { key: 'darkMode', value: !this.$store.state.device.darkMode }); + if (ColdDeviceStorage.get('syncDeviceDarkMode')) return; + this.$store.set('darkMode', !this.$store.state.darkMode); }, 'p': os.post, 'n': os.post, @@ -44,7 +45,7 @@ export default defineComponent({ }, menu(): string[] { - return this.$store.state.deviceUser.menu; + return this.$store.state.menu; }, }, diff --git a/src/client/ui/visitor/a.vue b/src/client/ui/visitor/a.vue index 94866fdff5..6f8c5efd6b 100644 --- a/src/client/ui/visitor/a.vue +++ b/src/client/ui/visitor/a.vue @@ -1,6 +1,6 @@