62 lines
2.2 KiB
TypeScript
62 lines
2.2 KiB
TypeScript
|
|
import { useCallback, useEffect } from "preact/hooks";
|
||
|
|
import { AgentIndicator } from "./components/AgentIndicator";
|
||
|
|
import { ControlBar, VoiceStatus } from "./components/Controls";
|
||
|
|
import { LogPanel } from "./components/LogPanel";
|
||
|
|
import { ToastContainer } from "./components/Toast";
|
||
|
|
import { useAudioMeter } from "./hooks/useAudioMeter";
|
||
|
|
import { usePTT } from "./hooks/usePTT";
|
||
|
|
import { useWebRTC } from "./hooks/useWebRTC";
|
||
|
|
|
||
|
|
export function App() {
|
||
|
|
const rtc = useWebRTC();
|
||
|
|
const audioLevel = useAudioMeter(rtc.remoteStream);
|
||
|
|
|
||
|
|
const { agentStateOverride, handlePointerDown, handlePointerUp } = usePTT({
|
||
|
|
connected: rtc.connected,
|
||
|
|
onSendPtt: (pressed) => rtc.sendJson({ type: "voice-ptt", pressed }),
|
||
|
|
onBootstrap: rtc.connect,
|
||
|
|
});
|
||
|
|
|
||
|
|
const effectiveAgentState = agentStateOverride ?? rtc.agentState;
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
document.addEventListener("pointerdown", handlePointerDown, { passive: false });
|
||
|
|
document.addEventListener("pointerup", handlePointerUp, { passive: false });
|
||
|
|
document.addEventListener("pointercancel", handlePointerUp, { passive: false });
|
||
|
|
return () => {
|
||
|
|
document.removeEventListener("pointerdown", handlePointerDown);
|
||
|
|
document.removeEventListener("pointerup", handlePointerUp);
|
||
|
|
document.removeEventListener("pointercancel", handlePointerUp);
|
||
|
|
};
|
||
|
|
}, [handlePointerDown, handlePointerUp]);
|
||
|
|
|
||
|
|
const handleReset = useCallback(async () => {
|
||
|
|
await rtc.connect();
|
||
|
|
rtc.sendJson({ type: "command", command: "reset" });
|
||
|
|
}, [rtc]);
|
||
|
|
|
||
|
|
const handleChoice = useCallback(
|
||
|
|
(requestId: string, value: string) => {
|
||
|
|
rtc.sendJson({ type: "ui-response", request_id: requestId, value });
|
||
|
|
},
|
||
|
|
[rtc],
|
||
|
|
);
|
||
|
|
|
||
|
|
return (
|
||
|
|
<>
|
||
|
|
<ControlBar onReset={handleReset} />
|
||
|
|
<LogPanel lines={rtc.logLines} />
|
||
|
|
<AgentIndicator
|
||
|
|
state={effectiveAgentState}
|
||
|
|
connected={rtc.connected}
|
||
|
|
connecting={rtc.connecting}
|
||
|
|
audioLevel={audioLevel}
|
||
|
|
onPointerDown={() => {}}
|
||
|
|
onPointerUp={() => {}}
|
||
|
|
/>
|
||
|
|
<VoiceStatus text={rtc.voiceStatus} visible={rtc.statusVisible} />
|
||
|
|
<ToastContainer toasts={rtc.toasts} onDismiss={rtc.dismissToast} onChoice={handleChoice} />
|
||
|
|
</>
|
||
|
|
);
|
||
|
|
}
|