feat: 添加 favicon.svg 文件并在 index.html 中引用
This commit is contained in:
parent
f470affb2f
commit
3f9bb22097
@ -4,6 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>PicoBot</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
3
web/public/favicon.svg
Normal file
3
web/public/favicon.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#22d3ee" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 247 B |
@ -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<number>(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(() => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user