diff options
Diffstat (limited to 'packages/frontend/src')
| -rw-r--r-- | packages/frontend/src/pages/timeline.vue | 20 | ||||
| -rw-r--r-- | packages/frontend/src/pizzax.ts | 19 |
2 files changed, 24 insertions, 15 deletions
diff --git a/packages/frontend/src/pages/timeline.vue b/packages/frontend/src/pages/timeline.vue index 3481113f87..5a71b18afe 100644 --- a/packages/frontend/src/pages/timeline.vue +++ b/packages/frontend/src/pages/timeline.vue @@ -71,9 +71,8 @@ const src = computed({ set: (x) => saveSrc(x), }); const withRenotes = computed({ - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - get: () => (defaultStore.reactiveState.tl.value.filter?.withRenotes ?? saveTlFilter('withRenotes', true)), - set: (x) => saveTlFilter('withRenotes', x), + get: () => defaultStore.reactiveState.tl.value.filter.withRenotes, + set: (x: boolean) => saveTlFilter('withRenotes', x), }); const withReplies = computed({ get: () => { @@ -81,27 +80,24 @@ const withReplies = computed({ if (['local', 'social'].includes(src.value) && onlyFiles.value) { return false; } else { - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - return defaultStore.reactiveState.tl.value.filter?.withReplies ?? saveTlFilter('withReplies', true); + return defaultStore.reactiveState.tl.value.filter.withReplies; } }, - set: (x) => saveTlFilter('withReplies', x), + set: (x: boolean) => saveTlFilter('withReplies', x), }); const onlyFiles = computed({ get: () => { if (['local', 'social'].includes(src.value) && withReplies.value) { return false; } else { - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - return defaultStore.reactiveState.tl.value.filter?.onlyFiles ?? saveTlFilter('onlyFiles', false); + return defaultStore.reactiveState.tl.value.filter.onlyFiles; } }, - set: (x) => saveTlFilter('onlyFiles', x), + set: (x: boolean) => saveTlFilter('onlyFiles', x), }); const withSensitive = computed({ - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - get: () => (defaultStore.reactiveState.tl.value.filter?.withSensitive ?? saveTlFilter('withSensitive', true)), - set: (x) => { + get: () => defaultStore.reactiveState.tl.value.filter.withSensitive, + set: (x: boolean) => { saveTlFilter('withSensitive', x); // これだけはクライアント側で完結する処理なので手動でリロード diff --git a/packages/frontend/src/pizzax.ts b/packages/frontend/src/pizzax.ts index 8723110b08..b3d2374899 100644 --- a/packages/frontend/src/pizzax.ts +++ b/packages/frontend/src/pizzax.ts @@ -7,6 +7,7 @@ import { onUnmounted, Ref, ref, watch } from 'vue'; import { BroadcastChannel } from 'broadcast-channel'; +import { defu } from 'defu'; import { $i } from '@/account.js'; import { misskeyApi } from '@/scripts/misskey-api.js'; import { get, set } from '@/scripts/idb-proxy.js'; @@ -80,6 +81,18 @@ export class Storage<T extends StateDef> { this.loaded = this.ready.then(() => this.load()); } + private isPureObject(value: unknown): value is Record<string, unknown> { + return typeof value === 'object' && value !== null && !Array.isArray(value); + } + + private mergeState<T>(value: T, def: T): T { + if (this.isPureObject(value) && this.isPureObject(def)) { + if (_DEV_) console.log('Merging state. Incoming: ', value, ' Default: ', def); + return defu(value, def) as T; + } + return value; + } + private async init(): Promise<void> { await this.migrate(); @@ -89,11 +102,11 @@ export class Storage<T extends StateDef> { for (const [k, v] of Object.entries(this.def) as [keyof T, T[keyof T]['default']][]) { if (v.where === 'device' && Object.prototype.hasOwnProperty.call(deviceState, k)) { - this.reactiveState[k].value = this.state[k] = deviceState[k]; + this.reactiveState[k].value = this.state[k] = this.mergeState<T[keyof T]['default']>(deviceState[k], v.default); } else if (v.where === 'account' && $i && Object.prototype.hasOwnProperty.call(registryCache, k)) { - this.reactiveState[k].value = this.state[k] = registryCache[k]; + this.reactiveState[k].value = this.state[k] = this.mergeState<T[keyof T]['default']>(registryCache[k], v.default); } else if (v.where === 'deviceAccount' && Object.prototype.hasOwnProperty.call(deviceAccountState, k)) { - this.reactiveState[k].value = this.state[k] = deviceAccountState[k]; + this.reactiveState[k].value = this.state[k] = this.mergeState<T[keyof T]['default']>(deviceAccountState[k], v.default); } else { this.reactiveState[k].value = this.state[k] = v.default; if (_DEV_) console.log('Use default value', k, v.default); |