refactor: uiStore.ts

This commit is contained in:
tao.chen
2026-08-07 12:23:50 +08:00
parent 2272e1f390
commit d7934a42ab
10 changed files with 1405 additions and 989 deletions
@@ -0,0 +1,71 @@
import { useEffect } from "react";
import {
bindScriptWorkspaceApi,
editSessionHandle,
useScriptWorkspaceStore,
} from "../state/scriptWorkspaceStore";
type ActivePage = "home" | "scripts" | "schedules" | "system";
/**
* 必须在 layout 层挂载,不能放在 ScriptsPage。
* 原因:心跳 / cleanup / beforeunload 需要在用户切到 /schedules 时仍运行,
* 否则其他 tab 中的编辑会话锁会过期。
*/
export function useEditSessionLifecycle({
activePage,
}: {
activePage: ActivePage;
}) {
// 1) 切到非 scripts 页时,如果当前有 active session,结束编辑
useEffect(() => {
if (activePage === "scripts") return;
const editBusy = useScriptWorkspaceStore.getState().editBusy;
if (editBusy) return;
if (!editSessionHandle.current) return;
void useScriptWorkspaceStore.getState().endEditing(true, false);
}, [activePage]);
// 2) 心跳 + cleanup 定时器(15s 心跳,60s 检查 cleanup
useEffect(() => {
let heartbeatRunning = false;
let cleanupRunning = false;
const heartbeatTimer = window.setInterval(() => {
if (heartbeatRunning) return;
heartbeatRunning = true;
void useScriptWorkspaceStore.getState().tickHeartbeats().finally(() => {
heartbeatRunning = false;
});
}, 15 * 1000);
const cleanupTimer = window.setInterval(() => {
if (cleanupRunning) return;
cleanupRunning = true;
try {
useScriptWorkspaceStore.getState().tickCleanup();
} finally {
cleanupRunning = false;
}
}, 60 * 1000);
return () => {
window.clearInterval(heartbeatTimer);
window.clearInterval(cleanupTimer);
};
}, []);
// 3) 卸载前释放编辑锁
useEffect(() => {
const handleUnload = () => {
useScriptWorkspaceStore.getState().releaseActiveOnUnload();
};
window.addEventListener("beforeunload", handleUnload);
return () => window.removeEventListener("beforeunload", handleUnload);
}, []);
// 4) layout 卸载时解绑 api
useEffect(() => {
return () => {
bindScriptWorkspaceApi(null);
};
}, []);
}