56 lines
1.8 KiB
TypeScript
56 lines
1.8 KiB
TypeScript
import { useEffect } from "react";
|
||
|
||
import {
|
||
editSessionHandle,
|
||
useScriptWorkspaceStore,
|
||
} from "../state/scriptWorkspaceStore";
|
||
|
||
type ActivePage = "home" | "scripts" | "schedules" | "operations" | "system";
|
||
|
||
/**
|
||
* 必须在 layout 层挂载,不能放在 ScriptsPage。
|
||
* 原因:cleanup / beforeunload 需要在用户切到 /schedules 时仍运行,否则跨页
|
||
* 浏览 10 分钟以上再回来时,sessionCache 里塞的全是陈旧的本地锁。
|
||
* 心跳已删除——本地锁没有过期概念,存不存在 15s 定时器都一样。
|
||
*/
|
||
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) 本地缓存回收(60s 检查一次,10 分钟无活动的本地锁清掉)
|
||
useEffect(() => {
|
||
let cleanupRunning = false;
|
||
const cleanupTimer = window.setInterval(() => {
|
||
if (cleanupRunning) return;
|
||
cleanupRunning = true;
|
||
try {
|
||
useScriptWorkspaceStore.getState().tickCleanup();
|
||
} finally {
|
||
cleanupRunning = false;
|
||
}
|
||
}, 60 * 1000);
|
||
return () => {
|
||
window.clearInterval(cleanupTimer);
|
||
};
|
||
}, []);
|
||
|
||
// 3) 卸载前清理本地锁引用(详见 store.releaseActiveOnUnload)
|
||
useEffect(() => {
|
||
const handleUnload = () => {
|
||
useScriptWorkspaceStore.getState().releaseActiveOnUnload();
|
||
};
|
||
window.addEventListener("beforeunload", handleUnload);
|
||
return () => window.removeEventListener("beforeunload", handleUnload);
|
||
}, []);
|
||
}
|