Update MobileCallPage and useVoicePreview to handle call end state
- Introduce a new state variable `callEnded` in `useVoicePreview` to manage call termination more effectively. - Modify `MobileCallPage` to adjust the `inCall` condition based on `callEnded`, ensuring accurate UI updates during and after calls. - Update rendering logic to display appropriate messages based on call status, enhancing user feedback during call transitions. - Refactor button visibility to only show when in an active call, improving user interface clarity.
This commit is contained in:
@@ -248,6 +248,7 @@ export function MobileCallPage({ assistantId }: { assistantId: string }) {
|
||||
selectOutputDevice,
|
||||
supportsOutputSelection,
|
||||
messages,
|
||||
callEnded,
|
||||
networkQuality,
|
||||
connect,
|
||||
replaceVideoStream,
|
||||
@@ -267,7 +268,7 @@ export function MobileCallPage({ assistantId }: { assistantId: string }) {
|
||||
const videoRef = useRef<HTMLVideoElement>(null);
|
||||
const [view, setView] = useState<CallView>("camera");
|
||||
const connecting = status === "connecting";
|
||||
const inCall = connecting || status === "connected";
|
||||
const inCall = !callEnded && (connecting || status === "connected");
|
||||
|
||||
useEffect(() => {
|
||||
if (videoRef.current) videoRef.current.srcObject = cameraStream;
|
||||
@@ -282,6 +283,7 @@ export function MobileCallPage({ assistantId }: { assistantId: string }) {
|
||||
}, [connect, startCamera]);
|
||||
|
||||
const endCall = useCallback(() => {
|
||||
setView("camera");
|
||||
disconnect();
|
||||
stopCamera();
|
||||
}, [disconnect, stopCamera]);
|
||||
@@ -300,11 +302,10 @@ export function MobileCallPage({ assistantId }: { assistantId: string }) {
|
||||
}, [startCall]);
|
||||
|
||||
useEffect(() => {
|
||||
if (status === "idle" || status === "failed") {
|
||||
if (callEnded || status === "idle" || status === "failed") {
|
||||
stopCamera();
|
||||
setView("camera");
|
||||
}
|
||||
}, [status, stopCamera]);
|
||||
}, [callEnded, status, stopCamera]);
|
||||
|
||||
const error = previewError || cameraError;
|
||||
|
||||
@@ -341,33 +342,39 @@ export function MobileCallPage({ assistantId }: { assistantId: string }) {
|
||||
<span
|
||||
className={[
|
||||
"h-2 w-2 rounded-full",
|
||||
status === "connected"
|
||||
!callEnded && status === "connected"
|
||||
? "animate-pulse bg-emerald-400"
|
||||
: connecting
|
||||
: !callEnded && connecting
|
||||
? "animate-pulse bg-amber-300"
|
||||
: "bg-white/40",
|
||||
].join(" ")}
|
||||
/>
|
||||
{status === "connected"
|
||||
? "通话中"
|
||||
: connecting
|
||||
? "正在连接…"
|
||||
: "通话已结束"}
|
||||
{callEnded
|
||||
? "通话已结束"
|
||||
: status === "connected"
|
||||
? "通话中"
|
||||
: connecting
|
||||
? "正在连接…"
|
||||
: "通话已结束"}
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setView((current) => current === "camera" ? "chat" : "camera")}
|
||||
aria-label={view === "camera" ? "显示聊天记录" : "显示摄像头画面"}
|
||||
title={view === "camera" ? "聊天记录" : "摄像头画面"}
|
||||
className="absolute right-4 top-[max(1rem,env(safe-area-inset-top))] z-10 flex size-9 items-center justify-center rounded-full border border-white/15 bg-black/40 text-white shadow-lg backdrop-blur-md transition-colors hover:bg-black/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/40"
|
||||
>
|
||||
{view === "camera" ? (
|
||||
<MessageSquareText className="size-[18px]" />
|
||||
) : (
|
||||
<Video className="size-[18px]" />
|
||||
)}
|
||||
</button>
|
||||
{inCall && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() =>
|
||||
setView((current) => current === "camera" ? "chat" : "camera")
|
||||
}
|
||||
aria-label={view === "camera" ? "显示聊天记录" : "显示摄像头画面"}
|
||||
title={view === "camera" ? "聊天记录" : "摄像头画面"}
|
||||
className="absolute right-4 top-[max(1rem,env(safe-area-inset-top))] z-10 flex size-9 items-center justify-center rounded-full border border-white/15 bg-black/40 text-white shadow-lg backdrop-blur-md transition-colors hover:bg-black/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/40"
|
||||
>
|
||||
{view === "camera" ? (
|
||||
<MessageSquareText className="size-[18px]" />
|
||||
) : (
|
||||
<Video className="size-[18px]" />
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
|
||||
{!cameraStream && inCall && view === "camera" && (
|
||||
<div className="absolute inset-0 z-[2] flex items-center justify-center px-8 text-center">
|
||||
@@ -391,7 +398,10 @@ export function MobileCallPage({ assistantId }: { assistantId: string }) {
|
||||
<div className="flex max-w-sm flex-col items-center gap-4 text-center">
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => void startCall()}
|
||||
onClick={() => {
|
||||
setView("camera");
|
||||
void startCall();
|
||||
}}
|
||||
className="h-12 gap-2 rounded-full bg-white px-6 text-[#07101a] shadow-2xl hover:bg-white/90"
|
||||
>
|
||||
<Phone size={19} />
|
||||
|
||||
Reference in New Issue
Block a user