聊天详情进入后滚动到最新消息

This commit is contained in:
stu2not
2026-05-27 17:45:43 +08:00
parent eebc5a14d8
commit 38fef3d2af

View File

@@ -104,6 +104,8 @@ const FALLBACK_RUNTIME_INFO: VoiceRuntimeInfo = {
supportsMp3Record: true,
}
const CHAT_BOTTOM_ANCHOR_ID = 'chat-bottom'
function compareVersion(left: string, right: string): number {
const leftParts = left.split('.').map((item) => Number(item) || 0)
const rightParts = right.split('.').map((item) => Number(item) || 0)
@@ -224,6 +226,7 @@ export default function ChatDetail() {
const [recording, setRecording] = useState(false)
const [playingMessageId, setPlayingMessageId] = useState<number | null>(null)
const [recordHint, setRecordHint] = useState('长按开始留言')
const [scrollTarget, setScrollTarget] = useState('')
const audioContextRef = useRef<Taro.InnerAudioContext | null>(null)
const recorderManagerRef = useRef<Taro.RecorderManager | null>(null)
const activeConversationIdRef = useRef(initialConversationId)
@@ -233,6 +236,18 @@ export default function ChatDetail() {
const runtimeInfoRef = useRef<VoiceRuntimeInfo>(FALLBACK_RUNTIME_INFO)
const recordStartedAtRef = useRef<number>(0)
const playingMessageIdRef = useRef<number | null>(null)
const scrollTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
const scrollToBottom = () => {
if (scrollTimerRef.current) {
clearTimeout(scrollTimerRef.current)
}
setScrollTarget('')
scrollTimerRef.current = setTimeout(() => {
setScrollTarget(CHAT_BOTTOM_ANCHOR_ID)
scrollTimerRef.current = null
}, 80)
}
useEffect(() => {
runtimeInfoRef.current = readVoiceRuntimeInfo()
@@ -290,6 +305,15 @@ export default function ChatDetail() {
}
}, [])
useEffect(() => {
return () => {
if (scrollTimerRef.current) {
clearTimeout(scrollTimerRef.current)
scrollTimerRef.current = null
}
}
}, [])
useEffect(() => {
activeConversationIdRef.current = activeConversationId
}, [activeConversationId])
@@ -325,6 +349,9 @@ export default function ChatDetail() {
}
const msgs = await getMessages(conversationId, conversationSource, decodedConversationTypeName)
setMessages(msgs)
if (msgs.length > 0) {
scrollToBottom()
}
} catch (error: any) {
console.error('[chat-detail] load failed:', error)
Taro.showToast({
@@ -621,7 +648,7 @@ export default function ChatDetail() {
</View>
</View>
<ScrollView className='chat-list' scrollY scrollWithAnimation>
<ScrollView className='chat-list' scrollY scrollWithAnimation scrollIntoView={scrollTarget}>
{loading ? (
<View className='empty-chat'>
<Text className='empty-chat-text'>...</Text>
@@ -669,6 +696,7 @@ export default function ChatDetail() {
</View>
))
)}
<View id={CHAT_BOTTOM_ANCHOR_ID} />
</ScrollView>
{character.canSend && character.childId && (