feat(chat): preserve message drafts in session temp store
This commit is contained in:
43
frontend/composables/useChatDraft.js
Normal file
43
frontend/composables/useChatDraft.js
Normal 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 }
|
||||
}
|
||||
Reference in New Issue
Block a user