|
1 | 1 | <!-- eslint-disable vue/block-tag-newline --> |
2 | 2 | <script lang="ts"> |
3 | | -import type { ComponentPublicInstance } from 'vue' |
4 | 3 | import type { AppConfig } from '@nuxt/schema' |
5 | 4 | import type { UIMessage, ChatStatus } from 'ai' |
6 | 5 | import theme from '#build/ui/chat-messages' |
@@ -120,10 +119,17 @@ const lastMessageSubmitted = ref(false) |
120 | 119 | const lastScrollTop = ref(0) |
121 | 120 | const userScrolledUp = ref(false) |
122 | 121 |
|
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') |
127 | 133 | } |
128 | 134 | } |
129 | 135 |
|
@@ -299,22 +305,25 @@ onMounted(() => { |
299 | 305 | :style="{ '--last-message-height': `${lastMessageHeight}px` }" |
300 | 306 | > |
301 | 307 | <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 | + > |
303 | 313 | <component |
304 | | - :is="$slots.message ? $slots.message : UChatMessage" |
| 314 | + :is="stableMessageComp" |
| 315 | + :memo="[messageData, compact]" |
| 316 | + :compact="compact" |
305 | 317 | 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 |
310 | 320 | }" |
311 | | - :ref="(el: ComponentPublicInstance) => registerMessageRef(message.id, el)" |
312 | 321 | > |
313 | 322 | <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" /> |
315 | 324 | </template> |
316 | 325 | </component> |
317 | | - </template> |
| 326 | + </div> |
318 | 327 | </slot> |
319 | 328 | <UChatMessage |
320 | 329 | v-if="status === 'submitted'" |
|
0 commit comments