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 [clientDialogContainer, setClientDialogContainer] =
|
||||
useState<HTMLDivElement | null>(null);
|
||||
const [messageDialogOpen, setMessageDialogOpen] = useState(false);
|
||||
const inChatView = view === "chat" && (!SHOW_VOICE_VIZ || showTranscript);
|
||||
const idleOrFailed = status === "idle" || status === "failed";
|
||||
const showIdleHub =
|
||||
@@ -812,17 +813,27 @@ function DebugVoicePanel({
|
||||
]);
|
||||
|
||||
return (
|
||||
<div className="flex min-h-0 flex-1 flex-col overflow-hidden">
|
||||
{/* 后端 TTS 音频经 WebRTC 媒体流过来,挂这里播放 */}
|
||||
<audio ref={audioRef} autoPlay playsInline className="hidden" />
|
||||
<div
|
||||
ref={setClientDialogContainer}
|
||||
className="relative isolate flex min-h-0 flex-1 flex-col overflow-hidden"
|
||||
>
|
||||
{/* 后端 TTS 音频经 WebRTC 媒体流过来,挂这里播放 */}
|
||||
<audio ref={audioRef} autoPlay playsInline className="hidden" />
|
||||
<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 ? (
|
||||
<DebugVisionWorkspace
|
||||
view={view}
|
||||
@@ -953,6 +964,9 @@ function DebugVoicePanel({
|
||||
</div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="shrink-0 border-t border-hairline bg-card p-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<div
|
||||
|
||||
@@ -155,10 +155,12 @@ export function ClientMessageDialog({
|
||||
preview,
|
||||
container,
|
||||
contained = false,
|
||||
onOpenChange,
|
||||
}: {
|
||||
preview: VoicePreview;
|
||||
container?: HTMLElement | null;
|
||||
contained?: boolean;
|
||||
onOpenChange?: (open: boolean) => void;
|
||||
}) {
|
||||
const { registerClientTool, status } = preview;
|
||||
const [message, setMessage] = useState<MessageState | null>(null);
|
||||
@@ -203,6 +205,10 @@ export function ClientMessageDialog({
|
||||
setMessage(null);
|
||||
}, [status]);
|
||||
|
||||
useEffect(() => {
|
||||
onOpenChange?.(message !== null);
|
||||
}, [message, onOpenChange]);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
modal={!contained}
|
||||
@@ -215,9 +221,7 @@ export function ClientMessageDialog({
|
||||
className="gap-5 sm:max-w-md"
|
||||
portalContainer={container}
|
||||
contained={contained}
|
||||
overlayClassName={
|
||||
contained ? "bg-black/20 backdrop-blur-md" : undefined
|
||||
}
|
||||
overlayClassName={contained ? "bg-black/25" : undefined}
|
||||
showCloseButton={message?.dismissible ?? true}
|
||||
onEscapeKeyDown={(event) => {
|
||||
if (!message?.dismissible) event.preventDefault();
|
||||
|
||||
Reference in New Issue
Block a user