From 58ca40a728b2f44164bf2a5985bf1203edcc0f22 Mon Sep 17 00:00:00 2001 From: chenhang Date: Wed, 15 Jul 2026 13:00:58 +0800 Subject: [PATCH] fix(chat): keep browser hint expanded and readable --- .../__tests__/tailwind-components.test.tsx | 8 +-- .../chat/components/browser-hint-overlay.tsx | 61 +++---------------- 2 files changed, 12 insertions(+), 57 deletions(-) diff --git a/src/app/chat/components/__tests__/tailwind-components.test.tsx b/src/app/chat/components/__tests__/tailwind-components.test.tsx index ff78279c..aa84d35e 100644 --- a/src/app/chat/components/__tests__/tailwind-components.test.tsx +++ b/src/app/chat/components/__tests__/tailwind-components.test.tsx @@ -201,21 +201,21 @@ describe("chat Tailwind components", () => { const html = renderToStaticMarkup( , ); - expect(html).toContain('aria-expanded="true"'); + expect(html).not.toContain("aria-expanded"); expect(html).toContain('aria-label="Open elsewhere. Better experience"'); expect(html).toContain("grid-cols-[auto_minmax(0,1fr)]"); expect(html).toContain( "right-[calc(var(--spacing-md,12px)+var(--responsive-icon-button-size,42px)+var(--spacing-sm,8px))]", ); expect(html).toContain("max-w-[min(58vw,220px)]"); - expect(html).toContain("backdrop-blur-md"); - expect(html).toContain("hover:opacity-94"); + expect(html).toContain("bg-[#17131f]"); + expect(html).toContain("text-[#f3dfe8]"); + expect(html).not.toContain("Show external browser hint"); expect(html).toContain("Open elsewhere"); expect(html).toContain("Better experience"); }); diff --git a/src/app/chat/components/browser-hint-overlay.tsx b/src/app/chat/components/browser-hint-overlay.tsx index f011bf79..1dbbcf38 100644 --- a/src/app/chat/components/browser-hint-overlay.tsx +++ b/src/app/chat/components/browser-hint-overlay.tsx @@ -8,9 +8,8 @@ * 行为: * - 开发环境始终显示(测试方便) * - 生产环境仅在应用内浏览器中显示 - * - 首次完整展示,随后收缩为图标;展开后点击主动打开外部浏览器 + * - 始终完整展示,点击后主动打开外部浏览器 */ -import { useEffect, useState } from "react"; import { ExternalLink } from "lucide-react"; import { openChatInExternalBrowser } from "@/lib/chat/chat_external_browser"; @@ -22,93 +21,49 @@ export interface BrowserHintOverlayProps { description?: string; /** 强制显示(开发模式测试用) */ forceShow?: boolean; - /** 自动收缩延迟,设为 0 可禁用自动收缩 */ - autoCollapseDelayMs?: number; } const DEFAULT_TITLE = "Open in external browser"; const DEFAULT_DESCRIPTION = "Find me more easily"; -const DEFAULT_AUTO_COLLAPSE_DELAY_MS = 3500; -const OVERLAY_BASE_CLASS_NAME = - "pointer-events-auto absolute right-[calc(var(--spacing-md,12px)+var(--responsive-icon-button-size,42px)+var(--spacing-sm,8px))] top-(--spacing-2,8px) z-20 box-border min-h-12 max-w-[min(58vw,220px)] cursor-pointer border border-[rgba(255,255,255,0.18)] bg-[linear-gradient(135deg,rgba(255,255,255,0.14),rgba(255,255,255,0.04)),var(--color-blur-background,rgba(13,11,20,0.86))] text-white shadow-[0_12px_28px_rgba(0,0,0,0.24),inset_0_1px_0_rgba(255,255,255,0.16)] backdrop-blur-md backdrop-saturate-120 transition-[border-color,box-shadow,opacity,padding,transform] duration-180 [-webkit-tap-highlight-color:transparent] hover:-translate-y-px hover:border-[rgba(255,255,255,0.28)] hover:opacity-94 hover:shadow-[0_14px_32px_rgba(0,0,0,0.28),inset_0_1px_0_rgba(255,255,255,0.18)] active:translate-y-px active:scale-99 active:opacity-88 focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-[rgba(255,255,255,0.88)]"; -const OVERLAY_EXPANDED_CLASS_NAME = - "grid w-fit grid-cols-[auto_minmax(0,1fr)] items-center gap-2 rounded-[18px] px-2.5 py-2"; -const OVERLAY_COLLAPSED_CLASS_NAME = - "inline-flex size-10.5 min-h-10.5 min-w-10.5 items-center justify-center rounded-full p-1.25"; +const OVERLAY_CLASS_NAME = + "pointer-events-auto absolute right-[calc(var(--spacing-md,12px)+var(--responsive-icon-button-size,42px)+var(--spacing-sm,8px))] top-(--spacing-2,8px) z-20 grid min-h-12 w-fit max-w-[min(58vw,220px)] cursor-pointer grid-cols-[auto_minmax(0,1fr)] items-center gap-2 rounded-[18px] border border-[rgba(255,255,255,0.3)] bg-[#17131f] px-2.5 py-2 text-white shadow-[0_12px_28px_rgba(0,0,0,0.34),inset_0_1px_0_rgba(255,255,255,0.12)] transition-[border-color,box-shadow,opacity,transform] duration-180 [-webkit-tap-highlight-color:transparent] hover:-translate-y-px hover:border-[rgba(255,255,255,0.46)] hover:bg-[#211925] hover:shadow-[0_14px_32px_rgba(0,0,0,0.38),inset_0_1px_0_rgba(255,255,255,0.16)] active:translate-y-px active:scale-99 active:opacity-90 focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-white"; export function BrowserHintOverlay({ title = DEFAULT_TITLE, description = DEFAULT_DESCRIPTION, forceShow = false, - autoCollapseDelayMs = DEFAULT_AUTO_COLLAPSE_DELAY_MS, }: BrowserHintOverlayProps) { - const [isExpanded, setIsExpanded] = useState(true); - const [hasAutoCollapsed, setHasAutoCollapsed] = useState(false); - // 展示条件由调用方控制;forceShow 保留给开发/测试入口。 const shouldShow = forceShow; - useEffect(() => { - if (!shouldShow || hasAutoCollapsed || autoCollapseDelayMs <= 0) return; - - const timer = window.setTimeout(() => { - setIsExpanded(false); - setHasAutoCollapsed(true); - }, autoCollapseDelayMs); - - return () => { - window.clearTimeout(timer); - }; - }, [autoCollapseDelayMs, hasAutoCollapsed, shouldShow]); - if (!shouldShow) return null; const handleClick = (): void => { - if (!isExpanded) { - setIsExpanded(true); - return; - } - void openChatInExternalBrowser().catch((error) => { console.warn("[chat] Failed to open external browser", error); }); }; - const ariaLabel = isExpanded - ? `${title}. ${description}` - : "Show external browser hint"; - return (