Skip to content

Commit 47dc009

Browse files
yiloztChanzhaoyu
andauthored
feat: 添加用于显示回复消息原文的选项 (#672)
* feat: 添加显示用于原文的选项 * chore: 修复暗色主题下文本颜色问题 给输入和输出气泡添加了 css 类,用来处理在暗色主题下聊天气泡的文本颜色 * feat: 用户输入不应该被渲染,防止 xss --------- Co-authored-by: ChenZhaoYu <790348264@qq.com>
1 parent f1584b6 commit 47dc009

File tree

6 files changed

+55
-17
lines changed

6 files changed

+55
-17
lines changed

src/locales/en-US.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ export default {
4646
deleteMessageConfirm: 'Are you sure to delete this message?',
4747
deleteHistoryConfirm: 'Are you sure to clear this history?',
4848
clearHistoryConfirm: 'Are you sure to clear chat history?',
49+
preview: 'Preview',
50+
showRawText: 'Show as raw text',
4951
},
5052
setting: {
5153
setting: 'Setting',

src/locales/zh-CN.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ export default {
4646
deleteMessageConfirm: '是否删除此消息?',
4747
deleteHistoryConfirm: '确定删除此记录?',
4848
clearHistoryConfirm: '确定清空聊天记录?',
49+
preview: '预览',
50+
showRawText: '显示原文',
4951
},
5052
setting: {
5153
setting: '设置',

src/locales/zh-TW.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ export default {
4646
deleteMessageConfirm: '是否刪除此訊息?',
4747
deleteHistoryConfirm: '確定刪除此紀錄?',
4848
clearHistoryConfirm: '確定清除紀錄?',
49+
preview: '預覽',
50+
showRawText: '顯示原文',
4951
},
5052
setting: {
5153
setting: '設定',

src/views/chat/components/Message/Text.vue

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ interface Props {
1212
error?: boolean
1313
text?: string
1414
loading?: boolean
15+
asRawText?: boolean
1516
}
1617
1718
const props = defineProps<Props>()
@@ -43,13 +44,14 @@ const wrapClass = computed(() => {
4344
isMobile.value ? 'p-2' : 'px-3 py-2',
4445
props.inversion ? 'bg-[#d2f9d1]' : 'bg-[#f4f6f8]',
4546
props.inversion ? 'dark:bg-[#a1dc95]' : 'dark:bg-[#1e1e20]',
47+
props.inversion ? 'message-request' : 'message-reply',
4648
{ 'text-red-500': props.error },
4749
]
4850
})
4951
5052
const text = computed(() => {
5153
const value = props.text ?? ''
52-
if (!props.inversion)
54+
if (!props.asRawText)
5355
return mdi.render(value)
5456
return value
5557
})
@@ -68,7 +70,10 @@ defineExpose({ textRef })
6870
</template>
6971
<template v-else>
7072
<div ref="textRef" class="leading-relaxed break-words">
71-
<div v-if="!inversion" class="markdown-body" v-html="text" />
73+
<div v-if="!inversion">
74+
<div v-if="!asRawText" class="markdown-body" v-html="text" />
75+
<div v-else class="raw-text" v-text="text" />
76+
</div>
7277
<div v-else class="whitespace-pre-wrap" v-text="text" />
7378
</div>
7479
</template>

src/views/chat/components/Message/index.vue

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang='ts'>
2-
import { ref } from 'vue'
2+
import { computed, ref } from 'vue'
33
import { NDropdown } from 'naive-ui'
44
import AvatarComponent from './Avatar.vue'
55
import TextComponent from './Text.vue'
@@ -29,24 +29,41 @@ const { iconRender } = useIconRender()
2929
3030
const textRef = ref<HTMLElement>()
3131
32-
const options = [
33-
{
34-
label: t('chat.copy'),
35-
key: 'copyText',
36-
icon: iconRender({ icon: 'ri:file-copy-2-line' }),
37-
},
38-
{
39-
label: t('common.delete'),
40-
key: 'delete',
41-
icon: iconRender({ icon: 'ri:delete-bin-line' }),
42-
},
43-
]
32+
const asRawText = ref(props.inversion)
4433
45-
function handleSelect(key: 'copyRaw' | 'copyText' | 'delete') {
34+
const options = computed(() => {
35+
const common = [
36+
{
37+
label: t('chat.copy'),
38+
key: 'copyText',
39+
icon: iconRender({ icon: 'ri:file-copy-2-line' }),
40+
},
41+
{
42+
label: t('common.delete'),
43+
key: 'delete',
44+
icon: iconRender({ icon: 'ri:delete-bin-line' }),
45+
},
46+
]
47+
48+
if (!props.inversion) {
49+
common.unshift({
50+
label: asRawText.value ? t('chat.preview') : t('chat.showRawText'),
51+
key: 'toggleRenderType',
52+
icon: iconRender({ icon: asRawText.value ? 'ic:outline-code-off' : 'ic:outline-code' }),
53+
})
54+
}
55+
56+
return common
57+
})
58+
59+
function handleSelect(key: 'copyText' | 'delete' | 'toggleRenderType') {
4660
switch (key) {
4761
case 'copyText':
4862
copyText({ text: props.text ?? '' })
4963
return
64+
case 'toggleRenderType':
65+
asRawText.value = !asRawText.value
66+
return
5067
case 'delete':
5168
emit('delete')
5269
}
@@ -79,6 +96,7 @@ function handleRegenerate() {
7996
:error="error"
8097
:text="text"
8198
:loading="loading"
99+
:as-raw-text="asRawText"
82100
/>
83101
<div class="flex flex-col">
84102
<button

src/views/chat/components/Message/style.less

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,29 @@
4545
align-items: center;
4646
color: #b3b3b3;
4747

48-
&__copy{
48+
&__copy {
4949
cursor: pointer;
5050
margin-left: 0.5rem;
5151
user-select: none;
52+
5253
&:hover {
5354
color: #65a665;
5455
}
5556
}
5657
}
5758
}
59+
5860
}
5961

6062
html.dark {
6163

64+
.message-reply {
65+
.raw-text {
66+
white-space: pre-wrap;
67+
color: var(--n-text-color);
68+
}
69+
}
70+
6271
.highlight pre,
6372
pre {
6473
background-color: #282c34;

0 commit comments

Comments
 (0)