From 23fc11d01ebb19790d8cf04551c34da8b2147957 Mon Sep 17 00:00:00 2001 From: Xiaoyue Hou Date: Mon, 29 Sep 2025 23:12:37 +1000 Subject: [PATCH 1/2] =?UTF-8?q?=E6=8C=87=E5=BC=95chatbot=E7=9A=84=E6=B0=94?= =?UTF-8?q?=E6=B3=A1=E6=A1=86=EF=BC=8Cui=E7=BB=84=E4=BB=B6=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E5=B0=81=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assistant-ui/assistant-modal.tsx | 60 ++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/app/components/assistant-ui/assistant-modal.tsx b/app/components/assistant-ui/assistant-modal.tsx index 43e7b5e..8b9046a 100644 --- a/app/components/assistant-ui/assistant-modal.tsx +++ b/app/components/assistant-ui/assistant-modal.tsx @@ -2,11 +2,17 @@ import { BotIcon, ChevronDownIcon } from "lucide-react"; -import { type FC, forwardRef } from "react"; +import { type FC, forwardRef, useState, useEffect } from "react"; import { AssistantModalPrimitive } from "@assistant-ui/react"; +import { usePathname } from "next/navigation"; import { Thread } from "@/app/components/assistant-ui/thread"; import { TooltipIconButton } from "@/app/components/assistant-ui/tooltip-icon-button"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/app/components/ui/tooltip"; interface AssistantModalProps { errorMessage?: string; @@ -19,9 +25,59 @@ export const AssistantModal: FC = ({ showSettingsAction = false, onClearError, }) => { + const [showBubble, setShowBubble] = useState(false); + + useEffect(() => { + // 检查本次访问是否已关闭过气泡 + const bubbleClosed = sessionStorage.getItem("ai-bubble-closed"); + + if (!bubbleClosed) { + // 页面加载后2秒显示气泡提示 + const showTimer = setTimeout(() => { + setShowBubble(true); + }, 2000); + + // 15秒后自动关闭气泡 + const hideTimer = setTimeout(() => { + setShowBubble(false); + sessionStorage.setItem("ai-bubble-closed", "true"); + }, 17000); // 2秒显示 + 15秒停留 = 17秒 + + return () => { + clearTimeout(showTimer); + clearTimeout(hideTimer); + }; + } + }, []); + + const handleCloseBubble = () => { + setShowBubble(false); + // 记录本次访问已关闭气泡 + sessionStorage.setItem("ai-bubble-closed", "true"); + }; + return ( + {/* 自定义气泡组件 */} + {showBubble && ( +
+
+
+ 有问题可以问我哦~ +
+ {/* 气泡尾巴箭头 - 指向下方按钮 */} +
+
+
+
+
+
+ )} + @@ -54,7 +110,7 @@ const AssistantModalButton = forwardRef< tooltip={tooltip} side="left" {...rest} - className="aui-modal-button size-full rounded-full shadow transition-transform hover:scale-110 active:scale-90" + className="aui-modal-button size-full rounded-full shadow transition-transform hover:scale-110 active:scale-90 cursor-pointer" ref={ref} > Date: Tue, 30 Sep 2025 18:56:00 +1000 Subject: [PATCH 2/2] =?UTF-8?q?chatbot=E7=BB=98=E7=94=BB=E6=B0=94=E6=B3=A1?= =?UTF-8?q?=EF=BC=8C=E9=BC=A0=E6=A0=87=E6=82=AC=E5=81=9C=E6=95=88=E6=9E=9C?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E5=A4=8D=E7=82=B9=E5=87=BBchatbot=E5=90=8E?= =?UTF-8?q?=E6=B0=94=E6=B3=A1=E4=BE=9D=E7=84=B6=E5=AD=98=E5=9C=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assistant-ui/assistant-modal.tsx | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/app/components/assistant-ui/assistant-modal.tsx b/app/components/assistant-ui/assistant-modal.tsx index 8b9046a..621f5a5 100644 --- a/app/components/assistant-ui/assistant-modal.tsx +++ b/app/components/assistant-ui/assistant-modal.tsx @@ -79,7 +79,7 @@ export const AssistantModal: FC = ({ )} - +
= ({ ); }; -type AssistantModalButtonProps = { "data-state"?: "open" | "closed" }; +type AssistantModalButtonProps = { + "data-state"?: "open" | "closed"; + onCloseBubble?: () => void; + onClick?: (e: React.MouseEvent) => void; +}; const AssistantModalButton = forwardRef< HTMLButtonElement, AssistantModalButtonProps ->(({ "data-state": state, ...rest }, ref) => { +>(({ "data-state": state, onCloseBubble, ...rest }, ref) => { const tooltip = state === "open" ? "Close Assistant" : "Open Assistant"; + const handleClick = (e: React.MouseEvent) => { + // 当点击open按钮时,关闭气泡对话 + if (onCloseBubble) { + onCloseBubble(); + } + // 继续执行原有的点击事件 + if (rest.onClick) { + rest.onClick(e); + } + }; + return (