feat(drafts): persist chat drafts in localStorage

- load drafts from localStorage on startup
- write drafts to localStorage on update/clear
- keep per-chat draft restore across page reload
This commit is contained in:
2026-03-08 02:53:32 +03:00
parent eef89983e0
commit d74e2c08c1

View File

@@ -2,6 +2,42 @@ import { create } from "zustand";
import { getChats, getMessages, updateMessageStatus } from "../api/chats";
import type { Chat, DeliveryStatus, Message, MessageType } from "../chat/types";
const DRAFTS_STORAGE_KEY = "bm_drafts_v1";
function loadDraftsFromStorage(): Record<number, string> {
if (typeof window === "undefined") {
return {};
}
try {
const raw = window.localStorage.getItem(DRAFTS_STORAGE_KEY);
if (!raw) {
return {};
}
const parsed = JSON.parse(raw) as Record<string, string>;
const result: Record<number, string> = {};
for (const [key, value] of Object.entries(parsed)) {
const chatId = Number(key);
if (Number.isFinite(chatId) && typeof value === "string") {
result[chatId] = value;
}
}
return result;
} catch {
return {};
}
}
function saveDraftsToStorage(drafts: Record<number, string>): void {
if (typeof window === "undefined") {
return;
}
try {
window.localStorage.setItem(DRAFTS_STORAGE_KEY, JSON.stringify(drafts));
} catch {
return;
}
}
interface ChatState {
chats: Chat[];
activeChatId: number | null;
@@ -52,7 +88,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
chats: [],
activeChatId: null,
messagesByChat: {},
draftsByChat: {},
draftsByChat: loadDraftsFromStorage(),
hasMoreByChat: {},
loadingMoreByChat: {},
typingByChat: {},
@@ -331,12 +367,14 @@ export const useChatStore = create<ChatState>((set, get) => ({
})
})),
setDraft: (chatId, text) =>
set((state) => ({
draftsByChat: {
set((state) => {
const nextDrafts = {
...state.draftsByChat,
[chatId]: text
}
})),
};
saveDraftsToStorage(nextDrafts);
return { draftsByChat: nextDrafts };
}),
clearDraft: (chatId) =>
set((state) => {
if (!(chatId in state.draftsByChat)) {
@@ -344,6 +382,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
}
const next = { ...state.draftsByChat };
delete next[chatId];
saveDraftsToStorage(next);
return { draftsByChat: next };
}),
setFocusedMessage: (chatId, messageId) =>