auto-save 2026-05-21 02:30 (~2)

This commit is contained in:
2026-05-21 02:30:46 +08:00
parent 7524b3caf1
commit 9520d9328c
2 changed files with 52 additions and 0 deletions

View File

@@ -1881,6 +1881,13 @@
"message": "auto-save 2026-05-21 02:19 (~2)",
"hash": "da12ed0",
"files_changed": 2
},
{
"ts": "2026-05-21T02:25:21+08:00",
"type": "commit",
"message": "auto-save 2026-05-21 02:25 (~2)",
"hash": "7524b3c",
"files_changed": 2
}
]
}

View File

@@ -58,6 +58,51 @@ const PACK_BRIEF_DESCRIPTIONS: Record<PackKind, string> = {
marketing: '白底商品图 · 场景图 · 细节图 · 社媒图',
};
const DEFAULT_ASSET_PANEL = 'pack-patent';
const VALID_ASSET_PANELS = new Set([
...PACK_ORDER.map(kind => `pack-${kind}`),
'pack-text',
'pack-video',
]);
const LAST_SESSION_STORAGE_KEY = 'ai-toy:last-session-id';
const LAST_PANEL_STORAGE_KEY = 'ai-toy:last-asset-panel';
function normalizeAssetPanel(panel?: string | null) {
return panel && VALID_ASSET_PANELS.has(panel) ? panel : DEFAULT_ASSET_PANEL;
}
function readPersistedProjectState() {
if (typeof window === 'undefined') {
return { sessionId: null as string | null, panel: DEFAULT_ASSET_PANEL };
}
const params = new URLSearchParams(window.location.search);
return {
sessionId: params.get('session') || window.localStorage.getItem(LAST_SESSION_STORAGE_KEY),
panel: normalizeAssetPanel(params.get('panel') || window.localStorage.getItem(LAST_PANEL_STORAGE_KEY)),
};
}
function writePersistedProjectState(sessionId: string, panel: string) {
if (typeof window === 'undefined') return;
const normalizedPanel = normalizeAssetPanel(panel);
window.localStorage.setItem(LAST_SESSION_STORAGE_KEY, sessionId);
window.localStorage.setItem(LAST_PANEL_STORAGE_KEY, normalizedPanel);
const url = new URL(window.location.href);
url.searchParams.set('session', sessionId);
url.searchParams.set('panel', normalizedPanel);
window.history.replaceState(null, '', `${url.pathname}${url.search}${url.hash}`);
}
function clearPersistedProjectState() {
if (typeof window === 'undefined') return;
window.localStorage.removeItem(LAST_SESSION_STORAGE_KEY);
window.localStorage.removeItem(LAST_PANEL_STORAGE_KEY);
const url = new URL(window.location.href);
url.searchParams.delete('session');
url.searchParams.delete('panel');
window.history.replaceState(null, '', `${url.pathname}${url.search}${url.hash}`);
}
function ProjectStat({ label, value, tone }: { label: string; value: string | number; tone?: 'accent' | 'soft' }) {
return (
<div className={`project-stat ${tone === 'accent' ? 'project-stat--accent' : ''}`}>