54 lines
1.5 KiB
TypeScript
54 lines
1.5 KiB
TypeScript
import { useCallback, useRef, useState } from "preact/hooks";
|
|
import type { AgentState } from "../types";
|
|
|
|
export interface PushToTalkState {
|
|
pttPressed: boolean;
|
|
micStream: MediaStream | null;
|
|
beginPTT(): void;
|
|
endPTT(): void;
|
|
}
|
|
|
|
interface UsePushToTalkOptions {
|
|
connected: boolean;
|
|
agentState: AgentState;
|
|
onPttChange(pressed: boolean): void;
|
|
onSetAgentState(state: AgentState): void;
|
|
onShowStatus(text: string, persistMs?: number): void;
|
|
}
|
|
|
|
export function usePushToTalk({
|
|
connected,
|
|
onPttChange,
|
|
onSetAgentState,
|
|
onShowStatus,
|
|
}: UsePushToTalkOptions): PushToTalkState {
|
|
const [pttPressed, setPttPressed] = useState(false);
|
|
const micStreamRef = useRef<MediaStream | null>(null);
|
|
|
|
// Attach mic stream from RTCPeerConnection tracks — caller passes it via micStream prop
|
|
// Here we track from the parent. Mic enable/disable is done by the parent hook.
|
|
|
|
const beginPTT = useCallback(() => {
|
|
if (!connected) return;
|
|
if (pttPressed) return;
|
|
setPttPressed(true);
|
|
onPttChange(true);
|
|
onSetAgentState("listening");
|
|
onShowStatus("Listening...");
|
|
}, [connected, pttPressed, onPttChange, onSetAgentState, onShowStatus]);
|
|
|
|
const endPTT = useCallback(() => {
|
|
if (!pttPressed) return;
|
|
setPttPressed(false);
|
|
onPttChange(false);
|
|
onSetAgentState("idle");
|
|
if (connected) onShowStatus("Hold anywhere to talk", 1800);
|
|
}, [pttPressed, onPttChange, onSetAgentState, onShowStatus, connected]);
|
|
|
|
return {
|
|
pttPressed,
|
|
micStream: micStreamRef.current,
|
|
beginPTT,
|
|
endPTT,
|
|
};
|
|
}
|