Skip to content

Commit c8b8d5a

Browse files
committed
fix(messages): handle the problem of failure to scroll to the position of custom message item
1 parent 0cfc668 commit c8b8d5a

File tree

2 files changed

+257
-196
lines changed

2 files changed

+257
-196
lines changed

src/runtime/components/ChatMessages.vue

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<!-- eslint-disable vue/block-tag-newline -->
22
<script lang="ts">
3-
import type { ComponentPublicInstance } from 'vue'
43
import type { AppConfig } from '@nuxt/schema'
54
import type { UIMessage, ChatStatus } from 'ai'
65
import theme from '#build/ui/chat-messages'
@@ -120,10 +119,17 @@ const lastMessageSubmitted = ref(false)
120119
const lastScrollTop = ref(0)
121120
const userScrolledUp = ref(false)
122121
123-
function registerMessageRef(id: string, element: ComponentPublicInstance | null) {
124-
const elInstance = element?.$el
125-
if (elInstance) {
126-
messagesRefs.value.set(id, elInstance)
122+
const stableMessageComp = computed(() => {
123+
return typeof slots.message === 'function'
124+
? slots.message
125+
: UChatMessage
126+
})
127+
128+
function registerMessageRef(id: string, element: HTMLDivElement | null) {
129+
if (element) {
130+
messagesRefs.value.set(id, element)
131+
} else {
132+
console.warn('message id', id, 'unregistered dom instance may cause the failure of rolling to the message')
127133
}
128134
}
129135
@@ -299,22 +305,25 @@ onMounted(() => {
299305
:style="{ '--last-message-height': `${lastMessageHeight}px` }"
300306
>
301307
<slot>
302-
<template v-for="message in messages" :key="message.id">
308+
<div
309+
v-for="messageData in messages"
310+
:key="messageData.id"
311+
:ref="(el) => registerMessageRef(messageData.id, el as HTMLDivElement)"
312+
>
303313
<component
304-
:is="$slots.message ? $slots.message : UChatMessage"
314+
:is="stableMessageComp"
315+
:memo="[messageData, compact]"
316+
:compact="compact"
305317
v-bind="{
306-
...message,
307-
...(message.role === 'user' ? userProps : assistantProps),
308-
...($slots.message ? { message, slots: getProxySlots() } : {}),
309-
compact
318+
...messageData,
319+
...messageData.role === 'user' ? userProps : assistantProps
310320
}"
311-
:ref="(el: ComponentPublicInstance) => registerMessageRef(message.id, el)"
312321
>
313322
<template v-for="(_, name) in getProxySlots()" #[name]="slotData">
314-
<slot :name="name" v-bind="slotData" :message="message" />
323+
<slot :name="name" v-bind="slotData" :message="messageData" />
315324
</template>
316325
</component>
317-
</template>
326+
</div>
318327
</slot>
319328
<UChatMessage
320329
v-if="status === 'submitted'"

0 commit comments

Comments
 (0)