add new session button
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# AiChatComposer 输入框
|
||||
|
||||
对话输入框,按状态在发送、停止与重试之间切换。
|
||||
对话输入框,按状态在发送、停止、重试与新开会话之间切换。
|
||||
|
||||
## 基础用法
|
||||
|
||||
@@ -18,17 +18,19 @@ demo-preview=../demos/ai-chat-composer/basic.vue
|
||||
|
||||
| 状态 | 按钮 |
|
||||
| --- | --- |
|
||||
| 空闲且未禁用 | 新开会话(`chat-add`) |
|
||||
| 默认 | 发送(`sendText`) |
|
||||
| `isGenerating` 为真 | 停止(`stopText`,危险色) |
|
||||
| 有 `lastError` 且 `canRetry` | 错误条 + 重试(`retryText`) |
|
||||
|
||||
生成中或 `disabled` 为真时输入框不可编辑,`send` 事件也不会抛出。
|
||||
生成中或 `disabled` 为真时输入框不可编辑,新开会话和 `send` 事件也不会触发。
|
||||
|
||||
## 事件
|
||||
|
||||
- `send`:抛出**去除首尾空白后**的内容,抛完自动清空输入框;空内容不抛
|
||||
- `stop`:点停止按钮
|
||||
- `retry`:点错误条上的重试
|
||||
- `new-conversation`:清空输入框并请求业务侧开始一个新会话
|
||||
|
||||
输入框内容用 `v-model` 绑定,`maxLength` 默认 2000。
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import { AiChatPanel, useAiChat } from "timi-tdesign-mobile";
|
||||
|
||||
const {
|
||||
messages, isGenerating, activeToolStatus, lastError, canRetry,
|
||||
sendMessage, stopGeneration, retryLastMessage
|
||||
sendMessage, stopGeneration, retryLastMessage, resetConversation
|
||||
} = useAiChat({
|
||||
request: ({ message, signal }) => fetchReply(message, signal)
|
||||
});
|
||||
@@ -40,6 +40,7 @@ const {
|
||||
@send="sendMessage"
|
||||
@stop="stopGeneration"
|
||||
@retry="retryLastMessage"
|
||||
@new-conversation="resetConversation"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
@@ -63,7 +64,7 @@ const {
|
||||
|
||||
## 自定义
|
||||
|
||||
`welcome`、`composer`、`tool-status`、`message` 等插槽可以替换对应区域。`composer` 插槽会拿到 `draft`、`on-send`、`on-stop`、`on-retry` 等,便于接入自定义输入框。
|
||||
`welcome`、`composer`、`tool-status`、`message` 等插槽可以替换对应区域。`composer` 插槽会拿到 `draft`、`on-send`、`on-stop`、`on-retry`、`on-new-conversation` 等,便于接入自定义输入框。
|
||||
|
||||
## API
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
@send="onSend"
|
||||
@stop="onStop"
|
||||
@retry="onRetry"
|
||||
@new-conversation="onNewConversation"
|
||||
/>
|
||||
|
||||
<div class="bar">
|
||||
@@ -53,6 +54,11 @@ function onRetry() {
|
||||
error.value = "";
|
||||
push("retry()");
|
||||
}
|
||||
|
||||
function onNewConversation() {
|
||||
error.value = "";
|
||||
push("new-conversation()");
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
@send="sendMessage"
|
||||
@stop="stopGeneration"
|
||||
@retry="retryLastMessage"
|
||||
@new-conversation="resetConversation"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -33,7 +34,8 @@ const {
|
||||
canRetry,
|
||||
sendMessage,
|
||||
stopGeneration,
|
||||
retryLastMessage
|
||||
retryLastMessage,
|
||||
resetConversation
|
||||
} = useAiChat({
|
||||
request: async ({ message, signal }) => createMockReply(message, signal)
|
||||
});
|
||||
|
||||
@@ -12,10 +12,23 @@
|
||||
/>
|
||||
</slot>
|
||||
</div>
|
||||
<t-form class="input-wrap" @submit="submitMessage">
|
||||
<div class="input-wrap">
|
||||
<t-button
|
||||
type="button"
|
||||
theme="primary"
|
||||
shape="circle"
|
||||
aria-label="新开会话"
|
||||
:disabled="props.isGenerating || props.disabled"
|
||||
@click="startNewConversation"
|
||||
>
|
||||
<template #icon>
|
||||
<t-icon name="chat-add" />
|
||||
</template>
|
||||
</t-button>
|
||||
<t-form class="form glass-white" @submit="submitMessage">
|
||||
<t-input
|
||||
v-model="draft"
|
||||
class="input"
|
||||
class="input bg-transparent"
|
||||
borderless
|
||||
:disabled="props.isGenerating || props.disabled"
|
||||
:maxlength="props.maxLength"
|
||||
@@ -53,6 +66,7 @@
|
||||
</slot>
|
||||
</t-form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -88,8 +102,17 @@ const emit = defineEmits<{
|
||||
send: [message: string];
|
||||
stop: [];
|
||||
retry: [];
|
||||
"new-conversation": [];
|
||||
}>();
|
||||
|
||||
function startNewConversation(): void {
|
||||
if (props.disabled || props.isGenerating) {
|
||||
return;
|
||||
}
|
||||
draft.value = "";
|
||||
emit("new-conversation");
|
||||
}
|
||||
|
||||
function submitMessage(): void {
|
||||
if (props.disabled || props.isGenerating) {
|
||||
return;
|
||||
@@ -130,12 +153,20 @@ function submitMessage(): void {
|
||||
}
|
||||
|
||||
.input-wrap {
|
||||
|
||||
gap: .75rem;
|
||||
margin: .5rem 0 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.form {
|
||||
--td-input-bg-color: transparent;
|
||||
--td-button-border-radius: 1rem;
|
||||
|
||||
gap: .5rem;
|
||||
flex: 1;
|
||||
border: 1px solid var(--td-component-border);
|
||||
margin: .5rem 0 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
padding: .25rem .25rem .25rem .75rem;
|
||||
box-shadow: 0 .5rem 1.5rem rgba(15, 23, 42, .12);
|
||||
@@ -143,8 +174,8 @@ function submitMessage(): void {
|
||||
border-radius: 1.25rem;
|
||||
|
||||
.input {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.send {
|
||||
@@ -153,6 +184,7 @@ function submitMessage(): void {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:global(html.theme-dark) {
|
||||
.error-bar {
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
:on-send="submitMessage"
|
||||
:on-stop="() => emit('stop')"
|
||||
:on-retry="() => emit('retry')"
|
||||
:on-new-conversation="() => emit('new-conversation')"
|
||||
>
|
||||
<ai-chat-composer
|
||||
v-model="draft"
|
||||
@@ -72,6 +73,7 @@
|
||||
@send="submitMessage"
|
||||
@stop="emit('stop')"
|
||||
@retry="emit('retry')"
|
||||
@new-conversation="emit('new-conversation')"
|
||||
/>
|
||||
</slot>
|
||||
</div>
|
||||
@@ -141,6 +143,7 @@ const emit = defineEmits<{
|
||||
send: [message: string];
|
||||
stop: [];
|
||||
retry: [];
|
||||
"new-conversation": [];
|
||||
}>();
|
||||
|
||||
const messageListRef = useTemplateRef<{ scrollToBottom: () => Promise<void> }>("messageList");
|
||||
|
||||
Reference in New Issue
Block a user