Skip to content

Commit

Permalink
下書き内容を画面を閉じても保持するように
Browse files Browse the repository at this point in the history
  • Loading branch information
nokhnaton committed Oct 30, 2024
1 parent 3f39fde commit 69f1434
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 26 deletions.
3 changes: 1 addition & 2 deletions src/composables/utils/useIndexedDbValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,8 @@ const useIndexedDbValue = <T extends object>(

watch(
value,
async () => {
async v => {
if (restoring.value) return

// indexedDBにはproxyされたobjectは入らないのでtoRawする
await set(key, toRawDeep(value), store)
},
Expand Down
8 changes: 7 additions & 1 deletion src/lib/basic/reactive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ export const toRawDeep = (value: any, map = new WeakMap()) => {
return map.get(value)
}

if (!Array.isArray(value) && !isPlainObject(value)) {
if (
!Array.isArray(value) &&
!isPlainObject(value) &&
!(value instanceof Map)
) {
return value
}

Expand All @@ -25,6 +29,8 @@ export const toRawDeep = (value: any, map = new WeakMap()) => {
for (let i = 0; i < newValue.length; i++) {
newValue[i] = toRawDeep(newValue[i], map)
}
} else if (newValue instanceof Map) {
newValue.forEach((v, k) => newValue.set(k, toRawDeep(v, map)))
} else {
for (const k of Object.keys(newValue)) {
newValue[k] = toRawDeep(newValue[k], map)
Expand Down
33 changes: 26 additions & 7 deletions src/store/ui/messageInputStateStore.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { defineStore, acceptHMRUpdate } from 'pinia'
import type { Ref } from 'vue'
import { reactive, computed, unref } from 'vue'
import { computed, unref, toRef } from 'vue'
import type { AttachmentType } from '/@/lib/basic/file'
import { convertToRefsStore } from '/@/store/utils/convertToRefsStore'
import type { ChannelId } from '/@/types/entity-ids'
import useIndexedDbValue, { key } from '/@/composables/utils/useIndexedDbValue'
import { promisifyRequest } from 'idb-keyval'

/**
* 基本的に直接利用しないで`/@/composables/messageInputState`を利用する
Expand Down Expand Up @@ -36,24 +38,41 @@ export const createDefaultValue = () => ({ text: '', attachments: [] })
const useMessageInputStateStorePinia = defineStore(
'ui/messageInputStateStore',
() => {
const states = reactive(
new Map<ChannelId | VirtualChannelId, MessageInputState>()
const initialValue = {
messageInputState: new Map<
ChannelId | VirtualChannelId,
MessageInputState
>()
}

const [state, restoring, restoringPromise] = useIndexedDbValue(
'store/ui/messageInputStateStore',
1,
{
1: async getStore => {
const store = getStore()
const setReq = store.put(initialValue, key)
await promisifyRequest(setReq)
}
},
initialValue
)

const states = toRef(() => state.messageInputState)
const inputChannels = computed(() =>
[...states].filter(([id]) => !virtualIds.has(id))
[...states.value].filter(([id]) => !virtualIds.has(id))
)
const hasInputChannel = computed(() => inputChannels.value.length > 0)

const getStore = (cId: MessageInputStateKey) => states.get(unref(cId))
const getStore = (cId: MessageInputStateKey) => states.value.get(unref(cId))
const setStore = (cId: MessageInputStateKey, v: MessageInputState) => {
// 空のときは削除、空でないときはセット
if (v && (v.text !== '' || v.attachments.length > 0)) {
// コピーしないと参照が変わらないから上書きされる
// toRawしちゃうとreactiveで包めなくなるので、そうはしない
states.set(unref(cId), { ...v })
states.value.set(unref(cId), { ...v })
} else {
states.delete(unref(cId))
states.value.delete(unref(cId))
}
}

Expand Down
16 changes: 0 additions & 16 deletions src/views/MainPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ import useMainViewLayout from './composables/useMainViewLayout'
import useRouteWatcher from './composables/useRouteWatcher'
import useInitialFetch from './composables/useInitialFetch'
import { useToastStore } from '/@/store/ui/toast'
import { useMessageInputStateStore } from '/@/store/ui/messageInputStateStore'
import { useCommandPalette } from '/@/store/app/commandPalette'
const useStyles = (
Expand All @@ -73,19 +72,6 @@ const useStyles = (
}))
})
const useDraftConfirmer = () => {
const { hasInputChannel } = useMessageInputStateStore()
window.addEventListener('beforeunload', event => {
if (hasInputChannel.value) {
const unloadMessage =
'このまま終了すると下書きが削除されます。本当に終了しますか?'
event.preventDefault()
event.returnValue = unloadMessage
return unloadMessage
}
})
}
const useCommandPaletteShortcutKey = () => {
const { mode, openCommandPalette, closeCommandPalette } = useCommandPalette()
Expand Down Expand Up @@ -163,8 +149,6 @@ const hideOuter = computed(
() => isMobile.value && isNavCompletelyAppeared.value
)
useDraftConfirmer()
const { routeWatcherState, triggerRouteParamChange } = useRouteWatcher()
useInitialFetch(() => {
connectFirebase(onClick => {
Expand Down

0 comments on commit 69f1434

Please sign in to comment.