Files
TJWaterFrontend_Refine/src/hooks/useChatToolActionHandler.ts
T

59 lines
1.7 KiB
TypeScript

import { useEffect, useRef } from "react";
import {
useChatToolStore,
type ChatToolAction,
} from "@/store/chatToolStore";
/**
* Subscribe to chat tool actions and invoke `handler` for each new action.
*
* Usage (inside a component with map access):
* ```ts
* useChatToolActionHandler((action) => {
* switch (action.type) {
* case "locate_features": handleLocateFeatures(action.ids, action.layer, action.geometryKind); break;
* case "view_history": openHistoryPanel(action.featureInfos, action.dataType); break;
* case "view_scada": openScadaPanel(action.featureInfos); break;
* }
* });
* ```
*/
export function useChatToolActionHandler(
handler: (action: ChatToolAction) => void,
) {
const handlerRef = useRef(handler);
const lastHandledSeqRef = useRef(0);
useEffect(() => {
handlerRef.current = handler;
}, [handler]);
useEffect(() => {
const initialState = useChatToolStore.getState();
if (
initialState.lastAction &&
initialState.actionSeq > lastHandledSeqRef.current &&
Date.now() - initialState.lastActionAt < 5000
) {
lastHandledSeqRef.current = initialState.actionSeq;
handlerRef.current(initialState.lastAction);
} else {
lastHandledSeqRef.current = initialState.actionSeq;
}
const unsubscribe = useChatToolStore.subscribe(
(state, prevState) => {
if (
state.actionSeq !== prevState.actionSeq &&
state.lastAction &&
state.actionSeq > lastHandledSeqRef.current
) {
lastHandledSeqRef.current = state.actionSeq;
handlerRef.current(state.lastAction);
}
},
);
return unsubscribe;
}, []);
}