Files
veridian/app/components/Message/Agent/ReasoningBody.vue

66 lines
1.7 KiB
Vue

<script setup lang="ts">
import type { MessagePart } from '~/composables/useChat';
import { nextTick, onMounted, ref, watch, type Ref } from 'vue';
const props = defineProps<{
part: Readonly<MessagePart>;
}>();
const containerRef: Ref<HTMLDivElement | null> = ref(null);
const scrollState = ref('');
const { scrollToBottom } = useAutoScroll(containerRef);
const handleScroll = () => {
if (!containerRef.value) {
return;
}
const container = containerRef.value;
const scrollTop = container.scrollTop;
const scrollHeight = container.scrollHeight;
const clientHeight = container.clientHeight;
if (scrollHeight <= clientHeight) {
scrollState.value = '';
return;
}
const threshold = Math.max(6, 0.02 * clientHeight);
if (scrollTop <= threshold) {
scrollState.value = 'top';
} else if (scrollTop >= scrollHeight - clientHeight - threshold) {
scrollState.value = 'bottom';
} else {
scrollState.value = 'middle';
}
};
onMounted(() => {
nextTick(() => {
handleScroll();
});
});
watch(
() => props.part.content,
() => {
nextTick(() => {
handleScroll();
});
},
);
defineExpose({ scrollToBottom, handleScroll });
</script>
<template>
<div ref="containerRef" @scroll="handleScroll"
:class="['reasoning-container max-h-[min(40vh,320px)] overflow-y-auto [scrollbar-width:thin] [scrollbar-color:#888_transparent] [scrollbar-gutter:stable]', scrollState]">
<div class="p-2">
<MarkdownRenderer :finished="props.part.finished" :id="props.part.id" :content="props.part.content!" />
</div>
</div>
</template>