You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
2.0 KiB
89 lines
2.0 KiB
<script setup lang="ts">
|
|
import type { AgentMessage } from "~/composables/useAgentChat";
|
|
|
|
const props = defineProps<{
|
|
messages: AgentMessage[];
|
|
isLoading: boolean;
|
|
loggedIn: boolean;
|
|
}>();
|
|
|
|
const emit = defineEmits<{
|
|
approve: [toolCallId: string, approved: boolean];
|
|
feedback: [messageId: string, feedback: "like" | "dislike"];
|
|
edit: [messageId: string, content: string];
|
|
regenerate: [];
|
|
}>();
|
|
|
|
const scrollContainer = ref<HTMLElement | null>(null);
|
|
const isAtBottom = ref(true);
|
|
|
|
function scrollToBottom() {
|
|
if (scrollContainer.value) {
|
|
scrollContainer.value.scrollTop = scrollContainer.value.scrollHeight;
|
|
}
|
|
}
|
|
|
|
function handleScroll() {
|
|
if (!scrollContainer.value) return;
|
|
const { scrollTop, scrollHeight, clientHeight } = scrollContainer.value;
|
|
isAtBottom.value = scrollHeight - scrollTop - clientHeight < 60;
|
|
}
|
|
|
|
watch(
|
|
() => props.messages.length,
|
|
() => {
|
|
nextTick(() => {
|
|
if (isAtBottom.value) scrollToBottom();
|
|
});
|
|
},
|
|
);
|
|
|
|
watch(
|
|
() => props.messages.map((m) => m.content).join(""),
|
|
() => {
|
|
nextTick(() => {
|
|
if (isAtBottom.value) scrollToBottom();
|
|
});
|
|
},
|
|
);
|
|
|
|
onMounted(() => {
|
|
scrollToBottom();
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div ref="scrollContainer" class="agent-message-list" @scroll="handleScroll">
|
|
<div class="message-list-inner">
|
|
<AgentMessageItem
|
|
v-for="(msg, idx) in messages"
|
|
:key="msg.id"
|
|
:message="msg"
|
|
:is-loading="isLoading"
|
|
:is-last="idx === messages.length - 1"
|
|
:logged-in="loggedIn"
|
|
@approve="(id, approved) => emit('approve', id, approved)"
|
|
@feedback="(id, fb) => emit('feedback', id, fb)"
|
|
@edit="(id, content) => emit('edit', id, content)"
|
|
@regenerate="emit('regenerate')"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.agent-message-list {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
scroll-behavior: smooth;
|
|
}
|
|
|
|
.message-list-inner {
|
|
max-width: 800px;
|
|
margin: 0 auto;
|
|
padding: 24px 24px 48px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 20px;
|
|
}
|
|
</style>
|
|
|