Skip to content

Commit

Permalink
add edit chat
Browse files Browse the repository at this point in the history
  • Loading branch information
hyf-github-user committed Aug 13, 2024
1 parent 61af618 commit d1e47d2
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 14 deletions.
146 changes: 132 additions & 14 deletions src/components/chat/Message.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,45 @@
</div>
<div v-if="!errorText" class="main">
<div class="content">
<markdown-renderer v-if="!Array.isArray(message.content)" :content="message?.content" />
<div v-else>
<div v-for="(item, index) in message.content" :key="index">
<img
v-if="item.type === 'image_url'"
:src="typeof item?.image_url === 'string' ? item.image_url : item.image_url?.url"
fit="cover"
class="image"
/>
<markdown-renderer v-if="item.type === 'text'" :key="index" :content="item.text" />
<div class="edit-left">
<el-tooltip
v-if="message.role === 'user' && !isEditing"
effect="dark"
:content="$t('chat.button.edit')"
placement="bottom"
>
<font-awesome-icon icon="fa-solid fa-edit" class="icon icon-edit" @click="startEditing" />
</el-tooltip>
</div>
<div v-if="!isEditing" class="message-content">
<markdown-renderer v-if="!Array.isArray(message.content)" :content="message?.content" />
<div v-else>
<div v-for="(item, index) in message.content" :key="index">
<img
v-if="item.type === 'image_url'"
:src="typeof item?.image_url === 'string' ? item.image_url : item.image_url?.url"
fit="cover"
class="image"
/>
<markdown-renderer v-if="item.type === 'text'" :key="index" :content="item.text" />
</div>
</div>
</div>
<div v-else class="chat-container">
<el-input
v-model="questionValue"
type="textarea"
class="chat-input"
@keydown.enter.exact.prevent="sendEdit"
></el-input>
<div class="button-group">
<el-button size="small" class="cancel-button" @click="cancelEdit">取消</el-button>
<el-button type="primary" size="small" class="send-button" @click="sendEdit">发送</el-button>
</div>
</div>
<answering-mark v-if="message.state === messageState.PENDING" />
</div>
<div class="operations">
<copy-to-clipboard v-if="!Array.isArray(message.content)" :content="message.content!" class="btn-copy" />
</div>
Expand All @@ -45,8 +70,9 @@
import { defineComponent } from 'vue';
import AnsweringMark from './AnsweringMark.vue';
import copy from 'copy-to-clipboard';
import { ElAlert, ElButton, ElImage } from 'element-plus';
import { ElAlert, ElButton, ElImage, ElTooltip, ElInput } from 'element-plus';
import MarkdownRenderer from '@/components/common/MarkdownRenderer.vue';
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
import { IApplication, IChatMessage, IChatMessageState } from '@/models';
import CopyToClipboard from '../common/CopyToClipboard.vue';
import {
Expand All @@ -64,6 +90,8 @@ import { ROUTE_CONSOLE_APPLICATION_BUY } from '@/router';
interface IData {
copied: boolean;
isEditing: boolean;
questionValue: string;
messageState: typeof IChatMessageState;
}
Expand All @@ -75,9 +103,16 @@ export default defineComponent({
MarkdownRenderer,
ElAlert,
ElButton,
ElImage
ElImage,
ElTooltip,
FontAwesomeIcon,
ElInput
},
props: {
question: {
type: String,
required: true
},
message: {
type: Object as () => IChatMessage,
required: true
Expand All @@ -87,10 +122,12 @@ export default defineComponent({
required: true
}
},
emits: ['stop'],
emits: ['stop', 'update:question', 'submit'],
data(): IData {
return {
copied: false,
isEditing: false,
questionValue: this.message.content as string,
messageState: IChatMessageState
};
},
Expand Down Expand Up @@ -123,7 +160,35 @@ export default defineComponent({
return this.message.role === ROLE_ASSISTANT && this.message.error?.code === ERROR_CODE_USED_UP;
}
},
watch: {
questionValue(val: string) {
this.$emit('update:question', val);
},
question(val: string) {
if (val !== this.questionValue) {
this.questionValue = val;
}
}
},
methods: {
startEditing() {
this.isEditing = true;
this.questionValue = this.message.content as string;
},
cancelEdit() {
this.isEditing = false;
},
sendEdit() {
// Implement the logic to save the edited content
this.isEditing = false;
this.onSubmit();
},
onSubmit() {
if (!this.question) {
return;
}
this.$emit('submit');
},
onCopy() {
copy(this.message.content!.toString(), {
debug: true
Expand Down Expand Up @@ -209,7 +274,48 @@ export default defineComponent({
width: fit-content;
text-align: left;
max-width: 100%;
padding: 8px 15px;
position: relative;
.edit-left {
position: absolute;
left: -25px; /* Adjust as needed */
top: 50%;
transform: translateY(-50%);
}
.chat-container {
// background-color: var(--el-bg-color-page);
// color: var(--el-text-color-primary);
padding: 10px;
width: 100%;
height: 100%;
.chat-input {
// background-color: var(--el-bg-color-page);
// color: var(--el-text-color-primary);
padding-bottom: 30px; /* 为按钮预留空间 */
}
.button-group {
position: absolute;
bottom: 10px;
right: 10px;
.cancel-button {
// background-color: #333;
// color: white;
background-color: var(--el-bg-color-page);
color: var(--el-text-color-primary);
border-radius: 20px;
// border: none;
}
.send-button {
// background-color: white;
// color: black;
background-color: var(--el-bg-color-page);
color: var(--el-text-color-primary);
border-radius: 20px;
// border: none;
}
}
}
}
}
.content {
Expand All @@ -223,6 +329,18 @@ export default defineComponent({
margin: 5px 0;
border-radius: 10px;
}
.edit-area {
width: 100%;
min-height: 100px;
border-radius: 10px;
padding: 8px;
margin-bottom: 10px;
}
.edit-buttons {
display: flex;
justify-content: flex-end;
gap: 10px;
}
}
.operations {
Expand Down
4 changes: 4 additions & 0 deletions src/i18n/zh-CN/chat.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
{
"button.edit": {
"message": "编辑消息",
"description": "编辑发送的消息"
},
"model.35Standard": {
"message": "3.5 标准",
"description": "服务的模型名称,即 GPT 3.5 基础"
Expand Down
4 changes: 4 additions & 0 deletions src/pages/chat/Conversation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@
v-for="(message, messageIndex) in messages"
:key="messageIndex"
:message="message"
:question="question"
:application="application"
class="message"
@update:question="question = $event"
@submit="onSubmit"
/>
</div>
</div>
Expand Down Expand Up @@ -163,6 +166,7 @@ export default defineComponent({
await this.onCreateNewConversation();
await this.$store.dispatch('chat/getApplication');
},
// Send a message
async onSubmit() {
if (this.references.length > 0) {
let content = [];
Expand Down

0 comments on commit d1e47d2

Please sign in to comment.