Skip to content

Commit

Permalink
perf: 优化复制逻辑
Browse files Browse the repository at this point in the history
  • Loading branch information
Kerwin committed Apr 26, 2023
1 parent bc27535 commit 9e2fcf4
Show file tree
Hide file tree
Showing 12 changed files with 130 additions and 183 deletions.
1 change: 0 additions & 1 deletion config/index.ts

This file was deleted.

16 changes: 0 additions & 16 deletions config/proxy.ts

This file was deleted.

3 changes: 3 additions & 0 deletions src/components/common/Setting/About.vue
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ onMounted(() => {
<div class="flex-1">
<NInput :value="config && config.accessToken" placeholder="" @input="(val) => { if (config) config.accessToken = val }" />
</div>
<p>
<a target="_blank" href="https://chat.openai.com/api/auth/session">Get Token</a>
</p>
</div>
<div v-if="!isChatGPTAPI" class="flex items-center space-x-4">
<span class="flex-shrink-0 w-[100px]">{{ $t('setting.reverseProxy') }}</span>
Expand Down
18 changes: 18 additions & 0 deletions src/utils/copy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export function copyToClip(text: string) {
return new Promise((resolve, reject) => {
try {
const input: HTMLTextAreaElement = document.createElement('textarea')
input.setAttribute('readonly', 'readonly')
input.value = text
document.body.appendChild(input)
input.select()
if (document.execCommand('copy'))
document.execCommand('copy')
document.body.removeChild(input)
resolve(text)
}
catch (error) {
reject(error)
}
})
}
18 changes: 0 additions & 18 deletions src/utils/crypto/index.ts

This file was deleted.

44 changes: 0 additions & 44 deletions src/utils/format/index.ts

This file was deleted.

58 changes: 57 additions & 1 deletion src/utils/storage/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,57 @@
export * from './local'
interface StorageData<T = any> {
data: T
expire: number | null
}

export function createLocalStorage(options?: { expire?: number | null }) {
const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7

const { expire } = Object.assign({ expire: DEFAULT_CACHE_TIME }, options)

function set<T = any>(key: string, data: T) {
const storageData: StorageData<T> = {
data,
expire: expire !== null ? new Date().getTime() + expire * 1000 : null,
}

const json = JSON.stringify(storageData)
window.localStorage.setItem(key, json)
}

function get(key: string) {
const json = window.localStorage.getItem(key)
if (json) {
let storageData: StorageData | null = null

try {
storageData = JSON.parse(json)
}
catch {
// Prevent failure
}

if (storageData) {
const { data, expire } = storageData
if (expire === null || expire >= Date.now())
return data
}

remove(key)
return null
}
}

function remove(key: string) {
window.localStorage.removeItem(key)
}

function clear() {
window.localStorage.clear()
}

return { set, get, remove, clear }
}

export const ls = createLocalStorage()

export const ss = createLocalStorage({ expire: null })
70 changes: 0 additions & 70 deletions src/utils/storage/local.ts

This file was deleted.

40 changes: 37 additions & 3 deletions src/views/chat/components/Message/Text.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts" setup>
import { computed, ref } from 'vue'
import { computed, onMounted, onUnmounted, onUpdated, ref } from 'vue'
import MarkdownIt from 'markdown-it'
import mdKatex from '@traptitech/markdown-it-katex'
import mila from 'markdown-it-link-attributes'
Expand All @@ -22,7 +22,7 @@ const { isMobile } = useBasicLayout()
const textRef = ref<HTMLElement>()
const mdi = new MarkdownIt({
html: true,
html: false,
linkify: true,
highlight(code, language) {
const validLang = !!(language && hljs.getLanguage(language))
Expand Down Expand Up @@ -61,7 +61,41 @@ function highlightBlock(str: string, lang?: string) {
return `<pre class="code-block-wrapper"><div class="code-block-header"><span class="code-block-header__lang">${lang}</span><span class="code-block-header__copy">${t('chat.copyCode')}</span></div><code class="hljs code-block-body ${lang}">${str}</code></pre>`
}
defineExpose({ textRef })
function addCopyEvents() {
if (textRef.value) {
const copyBtn = textRef.value.querySelectorAll('.code-block-header__copy')
copyBtn.forEach((btn) => {
btn.addEventListener('click', () => {
const code = btn.parentElement?.nextElementSibling?.textContent
if (code) {
copyToClip(code).then(() => {
btn.textContent = '复制成功'
setTimeout(() => {
btn.textContent = '复制代码'
}, 1000)
})
}
})
})
}
}
function removeCopyEvents() {
if (textRef.value) {
const copyBtn = textRef.value.querySelectorAll('.code-block-header__copy')
copyBtn.forEach((btn) => {
btn.removeEventListener('click', () => { })
})
}
}
onMounted(() => {
addCopyEvents()
})
onUpdated(() => {
addCopyEvents()
})
onUnmounted(() => {
removeCopyEvents()
})
</script>

<template>
Expand Down
18 changes: 15 additions & 3 deletions src/views/chat/components/Message/index.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<script setup lang='ts'>
import { computed, ref } from 'vue'
import { NDropdown, NPopover } from 'naive-ui'
import { NDropdown, NPopover, useMessage } from 'naive-ui'
import AvatarComponent from './Avatar.vue'
import TextComponent from './Text.vue'
import { SvgIcon } from '@/components/common'
import { copyText } from '@/utils/format'
import { useIconRender } from '@/hooks/useIconRender'
import { t } from '@/locales'
import { useBasicLayout } from '@/hooks/useBasicLayout'
import { copyToClip } from '@/utils/copy'
interface Props {
dateTime?: string
Expand Down Expand Up @@ -36,6 +36,8 @@ const { isMobile } = useBasicLayout()
const { iconRender } = useIconRender()
const message = useMessage()
const textRef = ref<HTMLElement>()
const asRawText = ref(props.inversion)
Expand Down Expand Up @@ -72,7 +74,7 @@ const options = computed(() => {
function handleSelect(key: 'copyText' | 'delete' | 'toggleRenderType') {
switch (key) {
case 'copyText':
copyText({ text: props.text ?? '' })
handleCopy()
return
case 'toggleRenderType':
asRawText.value = !asRawText.value
Expand All @@ -86,6 +88,16 @@ function handleRegenerate() {
messageRef.value?.scrollIntoView()
emit('regenerate')
}
async function handleCopy() {
try {
await copyToClip(props.text || '')
message.success('复制成功')
}
catch {
message.error('复制失败')
}
}
</script>

<template>
Expand Down
24 changes: 0 additions & 24 deletions src/views/chat/hooks/useCopyCode.ts

This file was deleted.

3 changes: 0 additions & 3 deletions src/views/chat/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import html2canvas from 'html2canvas'
import { Message } from './components'
import { useScroll } from './hooks/useScroll'
import { useChat } from './hooks/useChat'
import { useCopyCode } from './hooks/useCopyCode'
import { useUsingContext } from './hooks/useUsingContext'
import HeaderComponent from './components/Header/index.vue'
import { HoverButton, SvgIcon } from '@/components/common'
Expand All @@ -32,8 +31,6 @@ const authStore = useAuthStore()
const chatStore = useChatStore()
useCopyCode()
const { isMobile } = useBasicLayout()
const { addChat, updateChat, updateChatSome, getChatByUuidAndIndex } = useChat()
const { scrollRef, scrollToBottom, scrollToBottomIfAtBottom, scrollTo } = useScroll()
Expand Down

0 comments on commit 9e2fcf4

Please sign in to comment.