feat(chat): preserve message drafts in session temp store
This commit is contained in:
@@ -10,6 +10,71 @@ export const useTempStore = defineStore('temp', () => {
|
||||
const pages = ref({})
|
||||
const settings = ref({})
|
||||
|
||||
// Drafts stay local: temp_config is also returned in tenant profile lists.
|
||||
const chatDrafts = ref({})
|
||||
const sendingChatDrafts = ref({})
|
||||
const loadedChatDrafts = new Set()
|
||||
const draftStoragePrefix = 'fedeo:chat-draft:v1:'
|
||||
const toast = useToast()
|
||||
let draftStorageWarningShown = false
|
||||
|
||||
function getChatDraft(key) {
|
||||
if (!loadedChatDrafts.has(key)) {
|
||||
loadedChatDrafts.add(key)
|
||||
try {
|
||||
const saved = JSON.parse(sessionStorage.getItem(draftStoragePrefix + key) || 'null')
|
||||
if (saved && typeof saved.text === 'string' && typeof saved.clientId === 'string'
|
||||
&& saved.text.length <= 10000 && (!saved.image || (
|
||||
typeof saved.image.name === 'string' && typeof saved.image.dataUrl === 'string'
|
||||
&& saved.image.dataUrl.length <= 480000
|
||||
&& /^data:image\/(jpeg|png|webp);base64,[A-Za-z0-9+/=]+$/.test(saved.image.dataUrl)
|
||||
))) chatDrafts.value[key] = saved
|
||||
} catch { /* Disabled storage or an invalid entry must not block the chat. */ }
|
||||
}
|
||||
return chatDrafts.value[key] || null
|
||||
}
|
||||
|
||||
function setChatDraft(key, draft) {
|
||||
loadedChatDrafts.add(key)
|
||||
if (draft) chatDrafts.value[key] = draft
|
||||
else delete chatDrafts.value[key]
|
||||
try {
|
||||
if (draft) sessionStorage.setItem(draftStoragePrefix + key, JSON.stringify(draft))
|
||||
else sessionStorage.removeItem(draftStoragePrefix + key)
|
||||
} catch {
|
||||
// Do not restore an older version after a failed storage update.
|
||||
try { sessionStorage.removeItem(draftStoragePrefix + key) } catch {}
|
||||
if (!draftStorageWarningShown) {
|
||||
draftStorageWarningShown = true
|
||||
toast.add({ title: 'Entwurf nur vorübergehend gespeichert', description: 'Der Browserspeicher ist voll oder gesperrt. Bis zum Neuladen bleibt dein Entwurf im Chat erhalten.', color: 'warning' })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isChatDraftSending(key) {
|
||||
return !!sendingChatDrafts.value[key]
|
||||
}
|
||||
|
||||
function startChatDraftSend(key, clientId) {
|
||||
sendingChatDrafts.value[key] = clientId
|
||||
}
|
||||
|
||||
function finishChatDraftSend(key, clientId) {
|
||||
if (sendingChatDrafts.value[key] === clientId) delete sendingChatDrafts.value[key]
|
||||
}
|
||||
|
||||
watch(() => auth.user?.id || auth.user?.user_id, (user, previous) => {
|
||||
if (!previous || user === previous) return
|
||||
chatDrafts.value = {}
|
||||
sendingChatDrafts.value = {}
|
||||
loadedChatDrafts.clear()
|
||||
try {
|
||||
for (const key of Object.keys(sessionStorage)) {
|
||||
if (key.startsWith(draftStoragePrefix)) sessionStorage.removeItem(key)
|
||||
}
|
||||
} catch { /* Storage may be unavailable. In-memory drafts are still cleared. */ }
|
||||
}, { flush: 'sync' })
|
||||
|
||||
const storeTempConfig = async () => {
|
||||
const config = {
|
||||
searchStrings: searchStrings.value,
|
||||
@@ -92,6 +157,11 @@ export const useTempStore = defineStore('temp', () => {
|
||||
}
|
||||
|
||||
return {
|
||||
getChatDraft,
|
||||
setChatDraft,
|
||||
isChatDraftSending,
|
||||
startChatDraftSend,
|
||||
finishChatDraftSend,
|
||||
setStoredTempConfig,
|
||||
searchStrings,
|
||||
modifySearchString,
|
||||
|
||||
Reference in New Issue
Block a user