import { create } from "zustand"; export type SyncProjectProgress = { projectId: string; total: number; completed: number; phase: "pending" | "uploading" | "saving" | "reconciling" | "done" | "error" | "conflict"; message?: string; draftCount?: number; }; type SyncProgressStore = { syncingProjects: Record; setProjectProgress: (projectId: string, patch: Partial | null) => void; incrementProjectCompleted: (projectId: string) => void; clearAll: () => void; isAnySyncing: () => boolean; }; export const useSyncProgressStore = create((set, get) => ({ syncingProjects: {}, setProjectProgress: (projectId, patch) => set((state) => { if (!patch) { const next = { ...state.syncingProjects }; delete next[projectId]; return { syncingProjects: next }; } const current = state.syncingProjects[projectId] || { projectId, total: 0, completed: 0, phase: "uploading", }; return { syncingProjects: { ...state.syncingProjects, [projectId]: { ...current, ...patch }, }, }; }), incrementProjectCompleted: (projectId) => set((state) => { const current = state.syncingProjects[projectId]; if (!current) return state; return { syncingProjects: { ...state.syncingProjects, [projectId]: { ...current, completed: Math.min(current.total, current.completed + 1), }, }, }; }), clearAll: () => set({ syncingProjects: {} }), isAnySyncing: () => { const list = Object.values(get().syncingProjects); return list.some((item) => item.phase !== "done"); }, })); if (typeof window !== "undefined") { window.addEventListener("beforeunload", (event) => { if (useSyncProgressStore.getState().isAnySyncing()) { event.preventDefault(); event.returnValue = "画布正在同步至云端,请勿关闭页面。"; return "画布正在同步至云端,请勿关闭页面。"; } }); }