support attach
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
<section class="ai-chat-panel" :aria-label="props.ariaLabel">
|
||||
<ai-chat-message-list
|
||||
ref="messageList"
|
||||
:style="messageListStyle"
|
||||
:messages="props.messages"
|
||||
:is-generating="props.isGenerating"
|
||||
:loading="props.isLoading"
|
||||
@@ -40,7 +41,7 @@
|
||||
</template>
|
||||
</ai-chat-message-list>
|
||||
|
||||
<div class="bottom-area">
|
||||
<div ref="bottomArea" class="bottom-area">
|
||||
<slot name="tool-status" :status="props.activeToolStatus">
|
||||
<div v-if="props.activeToolStatus" class="tool-status">
|
||||
<t-icon name="loading" size="1rem" />
|
||||
@@ -58,6 +59,7 @@
|
||||
:on-stop="() => emit('stop')"
|
||||
:on-retry="() => emit('retry')"
|
||||
:on-new-conversation="() => emit('new-conversation')"
|
||||
:on-add-attachment="() => emit('add-attachment')"
|
||||
>
|
||||
<ai-chat-composer
|
||||
v-model="draft"
|
||||
@@ -74,6 +76,7 @@
|
||||
@stop="emit('stop')"
|
||||
@retry="emit('retry')"
|
||||
@new-conversation="emit('new-conversation')"
|
||||
@add-attachment="emit('add-attachment')"
|
||||
/>
|
||||
</slot>
|
||||
</div>
|
||||
@@ -81,7 +84,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { shallowRef, useTemplateRef } from "vue";
|
||||
import { computed, onBeforeUnmount, onMounted, ref, shallowRef, useTemplateRef } from "vue";
|
||||
import type {
|
||||
AiChatMessage,
|
||||
AiChatMessageStatusFormatter,
|
||||
@@ -144,10 +147,23 @@ const emit = defineEmits<{
|
||||
stop: [];
|
||||
retry: [];
|
||||
"new-conversation": [];
|
||||
"add-attachment": [];
|
||||
}>();
|
||||
|
||||
const messageListRef = useTemplateRef<{ scrollToBottom: () => Promise<void> }>("messageList");
|
||||
const bottomAreaRef = useTemplateRef<HTMLElement>("bottomArea");
|
||||
const bottomAreaHeight = ref<number>();
|
||||
const draft = shallowRef("");
|
||||
let bottomAreaObserver: ResizeObserver | undefined;
|
||||
|
||||
const messageListStyle = computed(() => {
|
||||
if (bottomAreaHeight.value === undefined) {
|
||||
return {};
|
||||
}
|
||||
return {
|
||||
"--ai-chat-bottom-area-height": `${bottomAreaHeight.value}px`
|
||||
};
|
||||
});
|
||||
|
||||
function submitMessage(message: string): void {
|
||||
emit("send", message);
|
||||
@@ -157,6 +173,23 @@ async function scrollToBottom(): Promise<void> {
|
||||
await messageListRef.value?.scrollToBottom();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const bottomArea = bottomAreaRef.value;
|
||||
if (!bottomArea) {
|
||||
return;
|
||||
}
|
||||
const updateBottomAreaHeight = () => {
|
||||
bottomAreaHeight.value = Math.ceil(bottomArea.getBoundingClientRect().height);
|
||||
};
|
||||
updateBottomAreaHeight();
|
||||
bottomAreaObserver = new ResizeObserver(updateBottomAreaHeight);
|
||||
bottomAreaObserver.observe(bottomArea);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
bottomAreaObserver?.disconnect();
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
scrollToBottom
|
||||
});
|
||||
@@ -188,6 +221,8 @@ defineExpose({
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
max-width: 40rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.tool-status {
|
||||
gap: .375rem;
|
||||
|
||||
Reference in New Issue
Block a user