fix(frontend): blur debug drawer chat and video behind message dialog
Use a contained dialog portal scoped to the workspace and apply direct filter blur so show_message prompts dim transcript and video reliably. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -775,6 +775,7 @@ function DebugVoicePanel({
|
|||||||
const [inputMode, setInputMode] = useState<DebugInputMode>("mic");
|
const [inputMode, setInputMode] = useState<DebugInputMode>("mic");
|
||||||
const [clientDialogContainer, setClientDialogContainer] =
|
const [clientDialogContainer, setClientDialogContainer] =
|
||||||
useState<HTMLDivElement | null>(null);
|
useState<HTMLDivElement | null>(null);
|
||||||
|
const [messageDialogOpen, setMessageDialogOpen] = useState(false);
|
||||||
const inChatView = view === "chat" && (!SHOW_VOICE_VIZ || showTranscript);
|
const inChatView = view === "chat" && (!SHOW_VOICE_VIZ || showTranscript);
|
||||||
const idleOrFailed = status === "idle" || status === "failed";
|
const idleOrFailed = status === "idle" || status === "failed";
|
||||||
const showIdleHub =
|
const showIdleHub =
|
||||||
@@ -812,17 +813,27 @@ function DebugVoicePanel({
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="flex min-h-0 flex-1 flex-col overflow-hidden">
|
||||||
ref={setClientDialogContainer}
|
|
||||||
className="relative isolate flex min-h-0 flex-1 flex-col overflow-hidden"
|
|
||||||
>
|
|
||||||
{/* 后端 TTS 音频经 WebRTC 媒体流过来,挂这里播放 */}
|
{/* 后端 TTS 音频经 WebRTC 媒体流过来,挂这里播放 */}
|
||||||
<audio ref={audioRef} autoPlay playsInline className="hidden" />
|
<audio ref={audioRef} autoPlay playsInline className="hidden" />
|
||||||
<ClientMessageDialog
|
<div
|
||||||
preview={preview}
|
ref={setClientDialogContainer}
|
||||||
container={clientDialogContainer}
|
className="relative isolate flex min-h-0 flex-1 flex-col overflow-hidden"
|
||||||
contained
|
>
|
||||||
/>
|
<ClientMessageDialog
|
||||||
|
preview={preview}
|
||||||
|
container={clientDialogContainer}
|
||||||
|
contained
|
||||||
|
onOpenChange={setMessageDialogOpen}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className={[
|
||||||
|
"flex min-h-0 flex-1 flex-col overflow-hidden transition-[filter] duration-200",
|
||||||
|
messageDialogOpen
|
||||||
|
? "pointer-events-none blur-md brightness-[0.92]"
|
||||||
|
: "",
|
||||||
|
].join(" ")}
|
||||||
|
>
|
||||||
{vision && !showIdleHub ? (
|
{vision && !showIdleHub ? (
|
||||||
<DebugVisionWorkspace
|
<DebugVisionWorkspace
|
||||||
view={view}
|
view={view}
|
||||||
@@ -953,6 +964,9 @@ function DebugVoicePanel({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="shrink-0 border-t border-hairline bg-card p-3">
|
<div className="shrink-0 border-t border-hairline bg-card p-3">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -155,10 +155,12 @@ export function ClientMessageDialog({
|
|||||||
preview,
|
preview,
|
||||||
container,
|
container,
|
||||||
contained = false,
|
contained = false,
|
||||||
|
onOpenChange,
|
||||||
}: {
|
}: {
|
||||||
preview: VoicePreview;
|
preview: VoicePreview;
|
||||||
container?: HTMLElement | null;
|
container?: HTMLElement | null;
|
||||||
contained?: boolean;
|
contained?: boolean;
|
||||||
|
onOpenChange?: (open: boolean) => void;
|
||||||
}) {
|
}) {
|
||||||
const { registerClientTool, status } = preview;
|
const { registerClientTool, status } = preview;
|
||||||
const [message, setMessage] = useState<MessageState | null>(null);
|
const [message, setMessage] = useState<MessageState | null>(null);
|
||||||
@@ -203,6 +205,10 @@ export function ClientMessageDialog({
|
|||||||
setMessage(null);
|
setMessage(null);
|
||||||
}, [status]);
|
}, [status]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
onOpenChange?.(message !== null);
|
||||||
|
}, [message, onOpenChange]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
modal={!contained}
|
modal={!contained}
|
||||||
@@ -215,9 +221,7 @@ export function ClientMessageDialog({
|
|||||||
className="gap-5 sm:max-w-md"
|
className="gap-5 sm:max-w-md"
|
||||||
portalContainer={container}
|
portalContainer={container}
|
||||||
contained={contained}
|
contained={contained}
|
||||||
overlayClassName={
|
overlayClassName={contained ? "bg-black/25" : undefined}
|
||||||
contained ? "bg-black/20 backdrop-blur-md" : undefined
|
|
||||||
}
|
|
||||||
showCloseButton={message?.dismissible ?? true}
|
showCloseButton={message?.dismissible ?? true}
|
||||||
onEscapeKeyDown={(event) => {
|
onEscapeKeyDown={(event) => {
|
||||||
if (!message?.dismissible) event.preventDefault();
|
if (!message?.dismissible) event.preventDefault();
|
||||||
|
|||||||
Reference in New Issue
Block a user