fix(canvas): 画布导入与云端同步 - 修复解压媒体直传对象存储与本地缓存自愈,支持封面实时上传进度与防误关提示
This commit is contained in:
68
web/src/stores/use-sync-progress-store.ts
Normal file
68
web/src/stores/use-sync-progress-store.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { create } from "zustand";
|
||||
|
||||
export type SyncProjectProgress = {
|
||||
projectId: string;
|
||||
total: number;
|
||||
completed: number;
|
||||
phase: "uploading" | "saving" | "done" | "error";
|
||||
message?: string;
|
||||
};
|
||||
|
||||
type SyncProgressStore = {
|
||||
syncingProjects: Record<string, SyncProjectProgress>;
|
||||
setProjectProgress: (projectId: string, patch: Partial<SyncProjectProgress> | null) => void;
|
||||
incrementProjectCompleted: (projectId: string) => void;
|
||||
isAnySyncing: () => boolean;
|
||||
};
|
||||
|
||||
export const useSyncProgressStore = create<SyncProgressStore>((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),
|
||||
},
|
||||
},
|
||||
};
|
||||
}),
|
||||
isAnySyncing: () => {
|
||||
const list = Object.values(get().syncingProjects);
|
||||
return list.some((item) => item.phase === "uploading" || item.phase === "saving");
|
||||
},
|
||||
}));
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
window.addEventListener("beforeunload", (event) => {
|
||||
if (useSyncProgressStore.getState().isAnySyncing()) {
|
||||
event.preventDefault();
|
||||
event.returnValue = "画布正在同步至云端,请勿关闭页面。";
|
||||
return "画布正在同步至云端,请勿关闭页面。";
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user