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 { getChats, getMessages, updateMessageStatus } from "../api/chats";
import type { Chat, DeliveryStatus, Message, MessageType } from "../chat/types"; 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 { interface ChatState {
chats: Chat[]; chats: Chat[];
activeChatId: number | null; activeChatId: number | null;
@@ -52,7 +88,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
chats: [], chats: [],
activeChatId: null, activeChatId: null,
messagesByChat: {}, messagesByChat: {},
draftsByChat: {}, draftsByChat: loadDraftsFromStorage(),
hasMoreByChat: {}, hasMoreByChat: {},
loadingMoreByChat: {}, loadingMoreByChat: {},
typingByChat: {}, typingByChat: {},
@@ -331,12 +367,14 @@ export const useChatStore = create<ChatState>((set, get) => ({
}) })
})), })),
setDraft: (chatId, text) => setDraft: (chatId, text) =>
set((state) => ({ set((state) => {
draftsByChat: { const nextDrafts = {
...state.draftsByChat, ...state.draftsByChat,
[chatId]: text [chatId]: text
} };
})), saveDraftsToStorage(nextDrafts);
return { draftsByChat: nextDrafts };
}),
clearDraft: (chatId) => clearDraft: (chatId) =>
set((state) => { set((state) => {
if (!(chatId in state.draftsByChat)) { if (!(chatId in state.draftsByChat)) {
@@ -344,6 +382,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
} }
const next = { ...state.draftsByChat }; const next = { ...state.draftsByChat };
delete next[chatId]; delete next[chatId];
saveDraftsToStorage(next);
return { draftsByChat: next }; return { draftsByChat: next };
}), }),
setFocusedMessage: (chatId, messageId) => setFocusedMessage: (chatId, messageId) =>