61 lines
1.5 KiB
TypeScript
61 lines
1.5 KiB
TypeScript
|
|
import type {
|
||
|
|
EcommerceVideoStage,
|
||
|
|
EcommerceVideoSceneTask,
|
||
|
|
EcommerceVideoPlanResult,
|
||
|
|
PlanStep,
|
||
|
|
} from "./ecommerceVideoTypes";
|
||
|
|
|
||
|
|
const KEEPALIVE_KEY = "omniai:ecommerce-video-workspace";
|
||
|
|
|
||
|
|
interface EcommerceVideoKeepalive {
|
||
|
|
stage: EcommerceVideoStage;
|
||
|
|
completedSteps: PlanStep[];
|
||
|
|
planResult: EcommerceVideoPlanResult | null;
|
||
|
|
scenes: EcommerceVideoSceneTask[];
|
||
|
|
sourceImageUrls: string[];
|
||
|
|
savedAt: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function saveEcommerceVideoState(state: {
|
||
|
|
stage: EcommerceVideoStage;
|
||
|
|
completedSteps: PlanStep[];
|
||
|
|
planResult: EcommerceVideoPlanResult | null;
|
||
|
|
scenes: EcommerceVideoSceneTask[];
|
||
|
|
sourceImageUrls?: string[];
|
||
|
|
}): void {
|
||
|
|
try {
|
||
|
|
const entry: EcommerceVideoKeepalive = {
|
||
|
|
...state,
|
||
|
|
sourceImageUrls: state.sourceImageUrls || [],
|
||
|
|
savedAt: Date.now(),
|
||
|
|
};
|
||
|
|
window.localStorage.setItem(KEEPALIVE_KEY, JSON.stringify(entry));
|
||
|
|
} catch {
|
||
|
|
// quota exceeded — silently drop
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export function loadEcommerceVideoState(): EcommerceVideoKeepalive | null {
|
||
|
|
try {
|
||
|
|
const raw = window.localStorage.getItem(KEEPALIVE_KEY);
|
||
|
|
if (!raw) return null;
|
||
|
|
const parsed = JSON.parse(raw) as EcommerceVideoKeepalive;
|
||
|
|
// Discard entries older than 2 hours
|
||
|
|
if (Date.now() - (parsed.savedAt || 0) > 2 * 60 * 60 * 1000) {
|
||
|
|
clearEcommerceVideoState();
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
return parsed;
|
||
|
|
} catch {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export function clearEcommerceVideoState(): void {
|
||
|
|
try {
|
||
|
|
window.localStorage.removeItem(KEEPALIVE_KEY);
|
||
|
|
} catch {
|
||
|
|
// ignore
|
||
|
|
}
|
||
|
|
}
|