import { useEffect, useMemo, useState } from 'react'; import { ipcChannels } from '../../../shared/ipc/contracts'; import type { NpcMapSpawnDragState } from '../../../shared/types'; import { asNpcId } from '../../../shared/types/ids'; import { getDndApi } from '../dndApi'; const EMPTY: NpcMapSpawnDragState = { dragging: false, npcId: null, hoverNx: null, hoverNy: null, }; export function useNpcMapSpawnDrag(): [ NpcMapSpawnDragState, { beginDrag: (npcId: string) => Promise; setHover: (nx: number | null, ny: number | null) => Promise; commit: () => Promise; cancel: () => Promise; }, ] { const api = getDndApi(); const [state, setState] = useState(EMPTY); useEffect(() => { void api.invoke(ipcChannels.npcMapSpawn.getState, {}).then(({ state: s }) => { setState(s); }); return api.on(ipcChannels.npcMapSpawn.stateChanged, ({ state: s }) => { setState(s); }); }, [api]); const apiWrap = useMemo( () => ({ beginDrag: async (npcId: string) => { await api.invoke(ipcChannels.npcMapSpawn.beginDrag, { npcId: asNpcId(npcId) }); }, setHover: async (nx: number | null, ny: number | null) => { await api.invoke(ipcChannels.npcMapSpawn.setHover, { nx, ny }); }, commit: async () => { const res = await api.invoke(ipcChannels.npcMapSpawn.commit, {}); return Boolean(res.spawned); }, cancel: async () => { await api.invoke(ipcChannels.npcMapSpawn.cancel, {}); }, }), [api], ); return [state, apiWrap]; }