Skip to content

Commit

Permalink
feat: support session export image (#69)
Browse files Browse the repository at this point in the history
  • Loading branch information
ayangweb committed Mar 22, 2023
1 parent b9371d3 commit 6d01959
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 21 deletions.
3 changes: 0 additions & 3 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { useSessionStore, useSettingsStore } from '@/stores'
import { useObserverLink } from '@/hooks'
const { isFix, windowFocused } = storeToRefs(useSettingsStore())
const { chatController } = storeToRefs(useSessionStore())
const isLoading = ref(true)
Expand Down Expand Up @@ -79,8 +78,6 @@ watch(
<!-- 会话信息 -->
<Session />

<a-button @click="chatController?.abort()">stop</a-button>
<div class="flex cursor-default flex-col gap-2 pt-2">
<!-- 功能区域 -->
<Function />
Expand Down
6 changes: 0 additions & 6 deletions src/components/Function/components/HistoryDrawer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@ const { sessionList, currentSession, isThinking } = storeToRefs(sessionStore)
const { switchSession, getSessionList, deleteSession } = sessionStore
const handleClick = (item: SessionPayload) => {
if (isThinking.value) {
Message.info('稍等片刻,AI 正在思考')
return
}
switchSession(item)
props.setVisible()
Expand Down
30 changes: 24 additions & 6 deletions src/components/Function/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,20 @@ import {
IconRefresh,
IconDelete,
IconHistory,
IconSettings
IconSettings,
IconStop,
IconImage
} from '@arco-design/web-vue/es/icon'
import { useRoleStore, useSessionStore } from '@/stores'
import { getAiMessage } from '@/api'
import { saveImage } from '@/utils'
const { currentRole } = storeToRefs(useRoleStore())
const sessionStore = useSessionStore()
const { switchSession, deleteSession } = sessionStore
const { isThinking, sessionDataList } = storeToRefs(sessionStore)
const { switchSession, deleteSession, updateSessionData } = sessionStore
const { isThinking, sessionDataList, chatController } =
storeToRefs(sessionStore)
const disabled = computed(
() => isThinking.value || !sessionDataList.value.length
Expand All @@ -40,10 +44,23 @@ const functions = computed(() => [
handleClick: () => switchSession()
},
{
content: '重新回答',
icon: IconRefresh,
content: isThinking.value ? '停止思考' : '重新回答',
icon: isThinking.value ? IconStop : IconRefresh,
disabled: !sessionDataList.value.length,
handleClick: () => {
if (isThinking.value) {
chatController.value?.abort()
updateSessionData(sessionDataList.value.at(-1)!)
} else {
getAiMessage()
}
}
},
{
content: '导出图片',
icon: IconImage,
disabled: disabled.value,
handleClick: () => getAiMessage()
handleClick: () => saveImage('session-list')
},
{
content: '清空对话',
Expand All @@ -54,6 +71,7 @@ const functions = computed(() => [
{
content: '历史记录',
icon: IconHistory,
disabled: isThinking.value,
handleClick: () => (drawerVisible.value = true)
},
{
Expand Down
2 changes: 1 addition & 1 deletion src/components/Session/index.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.session {
#session-list {
.blink-block::after {
animation: blink 1s infinite;

Expand Down
4 changes: 2 additions & 2 deletions src/components/Session/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ onUpdated(() => {
<template>
<div
ref="sessionElement"
id=""
class="session relative flex-1 cursor-default overflow-auto"
id="session-list"
class="relative flex-1 cursor-default overflow-auto"
>
<template v-if="sessionDataList.length">
<div
Expand Down
19 changes: 16 additions & 3 deletions src/utils/saveImage.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
import { writeBinaryFile, BaseDirectory } from '@tauri-apps/api/fs'
import html2canvas from 'html2canvas'
import { Message } from '@arco-design/web-vue'
import { useSettingsStore } from '@/stores'
import { THEME } from '@/constants'

/**
* 下载图片
* @param nodeRef
*/
export const saveImage = async (nodeId: string) => {
try {
const { themeMode } = useSettingsStore()

const uuid = '_' + nodeId

if (window[uuid]) return

window[uuid] = uuid

const element = document.getElementById(nodeId) as HTMLElement
const element = document.getElementById(nodeId)

if (!element) throw new Error()

const cloneElement = element.cloneNode(true) as HTMLElement

cloneElement.style.padding = '20px'

document.body.appendChild(cloneElement)

const canvas = await html2canvas(element, {
backgroundColor: 'transparent'
const canvas = await html2canvas(cloneElement, {
backgroundColor: themeMode === THEME.light ? '#fff' : '#000'
})

// base64 转 buffer
Expand All @@ -35,6 +47,7 @@ export const saveImage = async (nodeId: string) => {

setTimeout(() => {
window[uuid] = null
document.body.removeChild(cloneElement)
}, 3000)

Message.success('图片导出成功')
Expand Down

0 comments on commit 6d01959

Please sign in to comment.