feat: 增加带格式的复制 (#182)
* feat: 增加带格式的复制 * feat: 移除前端超时设定 * chore: update deps * feat: 添加权限页面 * feat: 设定页面优化 * feat: 更新 chatgpt 以支持 `gpt-3.5-turbo-0301` * chore: version 2.9.0
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
import { marked } from 'marked'
|
||||
import hljs from 'highlight.js'
|
||||
import { useBasicLayout } from '@/hooks/useBasicLayout'
|
||||
@@ -18,6 +18,8 @@ const { isMobile } = useBasicLayout()
|
||||
|
||||
const renderer = new marked.Renderer()
|
||||
|
||||
const textRef = ref<HTMLElement>()
|
||||
|
||||
renderer.html = (html) => {
|
||||
return `<p>${encodeHTML(html)}</p>`
|
||||
}
|
||||
@@ -54,6 +56,8 @@ const text = computed(() => {
|
||||
return marked(value)
|
||||
return value
|
||||
})
|
||||
|
||||
defineExpose({ textRef })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -62,7 +66,7 @@ const text = computed(() => {
|
||||
<span class="dark:text-white w-[4px] h-[20px] block animate-blink" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="leading-relaxed break-all">
|
||||
<div ref="textRef" class="leading-relaxed break-all">
|
||||
<div v-if="!inversion" class="markdown-body" v-html="text" />
|
||||
<div v-else class="whitespace-pre-wrap" v-text="text" />
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script setup lang='ts'>
|
||||
import { ref } from 'vue'
|
||||
import { NDropdown, useMessage } from 'naive-ui'
|
||||
import AvatarComponent from './Avatar.vue'
|
||||
import TextComponent from './Text.vue'
|
||||
@@ -27,32 +28,41 @@ const ms = useMessage()
|
||||
|
||||
const { iconRender } = useIconRender()
|
||||
|
||||
const textRef = ref<HTMLElement>()
|
||||
|
||||
const options = [
|
||||
{
|
||||
label: 'Copy',
|
||||
key: 'copy',
|
||||
label: 'Copy Raw',
|
||||
key: 'copyRaw',
|
||||
icon: iconRender({ icon: 'ri:file-copy-2-line' }),
|
||||
}, {
|
||||
},
|
||||
{
|
||||
label: 'Copy Text',
|
||||
key: 'copyText',
|
||||
icon: iconRender({ icon: 'ri:file-copy-line' }),
|
||||
},
|
||||
{
|
||||
label: 'Delete',
|
||||
key: 'delete',
|
||||
icon: iconRender({ icon: 'ri:delete-bin-line' }),
|
||||
},
|
||||
]
|
||||
|
||||
function handleSelect(key: 'copy' | 'delete') {
|
||||
if (key === 'copy')
|
||||
handleCopy()
|
||||
else
|
||||
handleDelete()
|
||||
}
|
||||
|
||||
function handleDelete() {
|
||||
emit('delete')
|
||||
}
|
||||
|
||||
function handleCopy() {
|
||||
copyText(props.text ?? '')
|
||||
ms.success('Copied')
|
||||
function handleSelect(key: 'copyRaw' | 'copyText' | 'delete') {
|
||||
switch (key) {
|
||||
case 'copyRaw':
|
||||
if (textRef.value && (textRef.value as any).textRef) {
|
||||
copyText({ text: (textRef.value as any).textRef.innerText })
|
||||
ms.success('Copied Raw')
|
||||
}
|
||||
return
|
||||
case 'copyText':
|
||||
copyText({ text: props.text ?? '', origin: false })
|
||||
ms.success('Copied Text')
|
||||
return
|
||||
case 'delete':
|
||||
emit('delete')
|
||||
}
|
||||
}
|
||||
|
||||
function handleRegenerate() {
|
||||
@@ -73,10 +83,11 @@ function handleRegenerate() {
|
||||
{{ dateTime }}
|
||||
</p>
|
||||
<div
|
||||
class="flex items-end gap-2 mt-2"
|
||||
class="flex items-end gap-1 mt-2"
|
||||
:class="[inversion ? 'flex-row-reverse' : 'flex-row']"
|
||||
>
|
||||
<TextComponent
|
||||
ref="textRef"
|
||||
:inversion="inversion"
|
||||
:error="error"
|
||||
:text="text"
|
||||
@@ -85,14 +96,14 @@ function handleRegenerate() {
|
||||
<div class="flex flex-col">
|
||||
<button
|
||||
v-if="!inversion"
|
||||
class="mb-2 transition text-neutral-400 hover:text-neutral-800 dark:hover:text-neutral-200"
|
||||
class="mb-2 transition text-neutral-300 hover:text-neutral-800 dark:hover:text-neutral-300"
|
||||
@click="handleRegenerate"
|
||||
>
|
||||
<SvgIcon icon="ri:restart-line" />
|
||||
</button>
|
||||
<NDropdown :options="options" @select="handleSelect">
|
||||
<NDropdown :placement="!inversion ? 'right' : 'left'" :options="options" @select="handleSelect">
|
||||
<button class="transition text-neutral-300 hover:text-neutral-800 dark:hover:text-neutral-200">
|
||||
<SvgIcon icon="ri:function-line" />
|
||||
<SvgIcon icon="ri:more-2-fill" />
|
||||
</button>
|
||||
</NDropdown>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user