feat(chat): preserve message drafts in session temp store

This commit is contained in:
2026-10-15 17:45:17 +02:00
parent e933782731
commit 697f538b6e
8 changed files with 426 additions and 16 deletions

View File

@@ -0,0 +1,43 @@
export function useChatDraft(roomKey, { persist = true } = {}) {
const auth = useAuthStore()
const temp = useTempStore()
const apiBase = useRuntimeConfig().public.apiBase
const localDraft = ref(null)
const key = computed(() => {
const room = toValue(roomKey), user = auth.user?.id || auth.user?.user_id
return toValue(persist) && room && user && auth.activeTenant
? JSON.stringify([apiBase, user, String(auth.activeTenant), auth.profile?.id || '', room])
: null
})
watch([key, () => toValue(roomKey), () => auth.user?.id || auth.user?.user_id,
() => auth.activeTenant, () => auth.profile?.id], () => { localDraft.value = null }, { flush: 'sync' })
const current = () => key.value ? temp.getChatDraft(key.value) : localDraft.value
function update(patch) {
const value = { text: '', image: null, ...current(), ...patch, clientId: crypto.randomUUID() }
const next = value.text || value.image ? value : null
if (key.value) temp.setChatDraft(key.value, next)
else localDraft.value = next
}
const draft = computed({ get: () => current()?.text || '', set: text => update({ text }) })
const draftImage = computed({ get: () => current()?.image || null, set: image => update({ image }) })
const draftSending = computed(() => !!key.value && temp.isChatDraftSending(key.value))
const captureDraft = () => ({ key: key.value, value: current() })
function startDraftSend() {
if (draftSending.value) return null
const snapshot = captureDraft()
if (!snapshot.value) return null
if (snapshot.key) temp.startChatDraftSend(snapshot.key, snapshot.value.clientId)
return snapshot
}
function finishDraftSend(snapshot) {
if (snapshot.key) temp.finishChatDraftSend(snapshot.key, snapshot.value.clientId)
}
function clearDraft(snapshot) {
const saved = snapshot.key ? temp.getChatDraft(snapshot.key) : localDraft.value
// A late send response must only remove the draft that was actually sent.
if (!snapshot.value || saved?.clientId !== snapshot.value.clientId) return
if (snapshot.key) temp.setChatDraft(snapshot.key, null)
else localDraft.value = null
}
return { draft, draftImage, draftSending, captureDraft, clearDraft, startDraftSend, finishDraftSend }
}