Files
DndGamePlayer/app/renderer/shared/npcs/useNpcsOverlayState.ts
T
Ivan Fontosh 0f4bb76b41 feat(npcs): inspect cards, Show overlay, and optional external link
Clicking an NPC tile opens description cards (multi-select accordion); Show puts avatars on screen. Optional URL opens a webview tab. Avatar pan in the editor commits on pointer up.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-19 10:42:57 +08:00

41 lines
1.1 KiB
TypeScript

import { useEffect, useState } from 'react';
import { ipcChannels } from '../../../shared/ipc/contracts';
import type { NpcsOverlayEvent, NpcsOverlayState } from '../../../shared/types';
import { getDndApi } from '../dndApi';
export function useNpcsOverlayState(): readonly [
NpcsOverlayState | null,
{ dispatch: (event: NpcsOverlayEvent) => Promise<void> },
] {
const api = getDndApi();
const [state, setState] = useState<NpcsOverlayState | null>(null);
useEffect(() => {
void api.invoke(ipcChannels.npcsOverlay.getState, {}).then((r) => {
const next = r.state;
setState({
...next,
inspectNpcIds: next.inspectNpcIds ?? [],
inspectFocusNpcId: next.inspectFocusNpcId ?? null,
});
});
return api.on(ipcChannels.npcsOverlay.stateChanged, ({ state: next }) => {
setState({
...next,
inspectNpcIds: next.inspectNpcIds ?? [],
inspectFocusNpcId: next.inspectFocusNpcId ?? null,
});
});
}, [api]);
return [
state,
{
dispatch: async (event) => {
await api.invoke(ipcChannels.npcsOverlay.dispatch, { event });
},
},
] as const;
}