From 3f9bb220975292c033db35f8caea7e9e1b9500d8 Mon Sep 17 00:00:00 2001
From: oudecheng <13802883547@139.com>
Date: Mon, 8 Jun 2026 14:43:47 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20favicon.svg=20?=
=?UTF-8?q?=E6=96=87=E4=BB=B6=E5=B9=B6=E5=9C=A8=20index.html=20=E4=B8=AD?=
=?UTF-8?q?=E5=BC=95=E7=94=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
web/index.html | 1 +
web/public/favicon.svg | 3 ++
web/src/components/Chat/MessageList.tsx | 38 ++++++++++++++++++++++++-
3 files changed, 41 insertions(+), 1 deletion(-)
create mode 100644 web/public/favicon.svg
diff --git a/web/index.html b/web/index.html
index 78b3465..c596841 100644
--- a/web/index.html
+++ b/web/index.html
@@ -4,6 +4,7 @@
PicoBot
+
diff --git a/web/public/favicon.svg b/web/public/favicon.svg
new file mode 100644
index 0000000..db7bc7a
--- /dev/null
+++ b/web/public/favicon.svg
@@ -0,0 +1,3 @@
+
diff --git a/web/src/components/Chat/MessageList.tsx b/web/src/components/Chat/MessageList.tsx
index 3f5ddb4..fcef3f3 100644
--- a/web/src/components/Chat/MessageList.tsx
+++ b/web/src/components/Chat/MessageList.tsx
@@ -15,6 +15,8 @@ export function MessageList({ messages, onNavigateToSubAgent }: MessageListProps
const prevShowBottomRef = useRef(false)
const prevShowTopRef = useRef(false)
const lastMessageCountRef = useRef(0)
+ const prevMessageCountRef = useRef(0)
+ const stickyLockUntilRef = useRef(0)
const isProgrammaticScrollRef = useRef(false)
const scrollTimerRef = useRef(0)
@@ -28,6 +30,12 @@ export function MessageList({ messages, onNavigateToSubAgent }: MessageListProps
const el = containerRef.current
if (!el) return
+ // sticky lock 期间:防止中间 DOM 状态的 scroll 事件打断历史加载
+ if (Date.now() < stickyLockUntilRef.current) {
+ isStickyRef.current = true
+ return
+ }
+
const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight
const nearBottom = distanceFromBottom < 120
@@ -81,13 +89,31 @@ export function MessageList({ messages, onNavigateToSubAgent }: MessageListProps
// ---- auto-scroll effect ----
useEffect(() => {
- if (messages.length === 0) return
+ // 消息清空 → 重置所有追踪状态(话题/会话切换)
+ if (messages.length === 0) {
+ prevMessageCountRef.current = 0
+ lastMessageCountRef.current = 0
+ isStickyRef.current = true
+ return
+ }
const lastMessage = messages[messages.length - 1]
+ const isFreshLoad = prevMessageCountRef.current === 0 && messages.length > 0
// 用户自己发的消息 → 始终滚到底部
if (lastMessage.role === 'user') {
scrollToBottom('instant')
+ prevMessageCountRef.current = messages.length
+ return
+ }
+
+ // 新加载(话题切换后首次收到消息)→ 强制滚到底部
+ if (isFreshLoad) {
+ isStickyRef.current = true
+ lastMessageCountRef.current = 0
+ stickyLockUntilRef.current = Date.now() + 1500
+ scrollToBottom('instant')
+ prevMessageCountRef.current = messages.length
return
}
@@ -102,6 +128,7 @@ export function MessageList({ messages, onNavigateToSubAgent }: MessageListProps
}
lastMessageCountRef.current = messages.length
+ prevMessageCountRef.current = messages.length
}, [messages, scrollToBottom])
// ---- ResizeObserver: 窗口大小变化时保持底部对齐 ----
@@ -119,6 +146,15 @@ export function MessageList({ messages, onNavigateToSubAgent }: MessageListProps
return () => observer.disconnect()
}, [])
+ // ---- 组件挂载时滚动到底部 ----
+
+ useEffect(() => {
+ if (messages.length > 0) {
+ scrollToBottom('instant')
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [])
+
// ---- 清理定时器 ----
useEffect(() => {