聊天详情进入后滚动到最新消息
This commit is contained in:
@@ -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 && (
|
||||
|
||||
Reference in New Issue
Block a user