91 lines
2.6 KiB
TypeScript
91 lines
2.6 KiB
TypeScript
export type B03AnalysisStatus = "pending" | "in_progress" | "completed" | "failed";
|
|
|
|
export interface B03StoredFileState {
|
|
slot: string;
|
|
fileName: string;
|
|
fileSize: number;
|
|
status: "completed" | "failed";
|
|
}
|
|
|
|
export interface B03ProjectState {
|
|
projectId: string;
|
|
uploadedAt: number;
|
|
files: B03StoredFileState[];
|
|
analysisStatus: B03AnalysisStatus;
|
|
analysisProgress: number;
|
|
lastCheckedAt: number;
|
|
}
|
|
|
|
function key(projectId: string): string {
|
|
return `b03_project_state_${projectId}`;
|
|
}
|
|
|
|
export function loadB03ProjectState(projectId: string): B03ProjectState | null {
|
|
const raw = localStorage.getItem(key(projectId));
|
|
if (!raw) return null;
|
|
try {
|
|
return JSON.parse(raw) as B03ProjectState;
|
|
} catch {
|
|
localStorage.removeItem(key(projectId));
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export function saveB03UploadedFile(
|
|
projectId: string,
|
|
file: { slot: string; fileName: string; fileSize: number },
|
|
): B03ProjectState {
|
|
const current = loadB03ProjectState(projectId);
|
|
const nextFiles = (current?.files ?? []).filter((item) => item.slot !== file.slot);
|
|
nextFiles.push({ ...file, status: "completed" });
|
|
const next: B03ProjectState = {
|
|
projectId,
|
|
uploadedAt: current?.uploadedAt ?? Date.now(),
|
|
files: nextFiles,
|
|
analysisStatus: "pending",
|
|
analysisProgress: 0,
|
|
lastCheckedAt: Date.now(),
|
|
};
|
|
localStorage.setItem(key(projectId), JSON.stringify(next));
|
|
return next;
|
|
}
|
|
|
|
export function updateB03AnalysisState(
|
|
projectId: string,
|
|
status: B03AnalysisStatus,
|
|
progress: number,
|
|
): B03ProjectState {
|
|
const current = loadB03ProjectState(projectId);
|
|
const next: B03ProjectState = {
|
|
projectId,
|
|
uploadedAt: current?.uploadedAt ?? Date.now(),
|
|
files: current?.files ?? [],
|
|
analysisStatus: status,
|
|
analysisProgress: progress,
|
|
lastCheckedAt: Date.now(),
|
|
};
|
|
localStorage.setItem(key(projectId), JSON.stringify(next));
|
|
return next;
|
|
}
|
|
|
|
export function restoreB03ProjectState(options: {
|
|
projectId: string;
|
|
label: string;
|
|
container: HTMLElement;
|
|
poll: (projectId: string) => Promise<boolean>;
|
|
onComplete: () => void;
|
|
}): void {
|
|
const state = loadB03ProjectState(options.projectId);
|
|
if (!state) return;
|
|
options.container.replaceChildren();
|
|
const message = document.createElement("span");
|
|
message.textContent = `${options.label}: ${state.analysisProgress}%`;
|
|
options.container.append(message);
|
|
options.container.classList.add("is-visible");
|
|
if (state.analysisStatus === "in_progress" || state.analysisStatus === "pending") {
|
|
void options.poll(options.projectId).then((completed) => {
|
|
if (completed) options.onComplete();
|
|
});
|
|
}
|
|
}
|