feat: artifacts add open external (#1812)

* feat: artifacts add open external

* fix: remove modal
This commit is contained in:
Chen Tao 2025-02-18 19:56:39 +08:00 committed by GitHub
parent 6e4be783d7
commit 3da3ee0225
8 changed files with 57 additions and 15 deletions

View File

@ -119,6 +119,9 @@ declare global {
encrypt: (text: string, secretKey: string, iv: string) => Promise<{ iv: string; encryptedData: string }> encrypt: (text: string, secretKey: string, iv: string) => Promise<{ iv: string; encryptedData: string }>
decrypt: (encryptedData: string, iv: string, secretKey: string) => Promise<string> decrypt: (encryptedData: string, iv: string, secretKey: string) => Promise<string>
} }
shell: {
openExternal: (url: string, options?: OpenExternalOptions) => Promise<void>
}
} }
} }
} }

View File

@ -1,6 +1,6 @@
import { electronAPI } from '@electron-toolkit/preload' import { electronAPI } from '@electron-toolkit/preload'
import { FileType, KnowledgeBaseParams, KnowledgeItem, Shortcut, WebDavConfig } from '@types' import { FileType, KnowledgeBaseParams, KnowledgeItem, Shortcut, WebDavConfig } from '@types'
import { contextBridge, ipcRenderer, OpenDialogOptions } from 'electron' import { contextBridge, ipcRenderer, OpenDialogOptions, shell } from 'electron'
// Custom APIs for renderer // Custom APIs for renderer
const api = { const api = {
@ -104,6 +104,9 @@ const api = {
encrypt: (text: string, secretKey: string, iv: string) => ipcRenderer.invoke('aes:encrypt', text, secretKey, iv), encrypt: (text: string, secretKey: string, iv: string) => ipcRenderer.invoke('aes:encrypt', text, secretKey, iv),
decrypt: (encryptedData: string, iv: string, secretKey: string) => decrypt: (encryptedData: string, iv: string, secretKey: string) =>
ipcRenderer.invoke('aes:decrypt', encryptedData, iv, secretKey) ipcRenderer.invoke('aes:decrypt', encryptedData, iv, secretKey)
},
shell: {
openExternal: shell.openExternal
} }
} }

View File

@ -140,7 +140,9 @@
"translate": "Translate", "translate": "Translate",
"topics.prompt": "Topic Prompts", "topics.prompt": "Topic Prompts",
"topics.prompt.tips": "Topic Prompts: Additional supplementary prompts provided for the current topic", "topics.prompt.tips": "Topic Prompts: Additional supplementary prompts provided for the current topic",
"topics.prompt.edit.title": "Edit Topic Prompts" "topics.prompt.edit.title": "Edit Topic Prompts",
"artifacts.button.openExternal": "Open in external browser",
"artifacts.preview.openExternal.error.content": "Error opening the external browser."
}, },
"common": { "common": {
"add": "Add", "add": "Add",

View File

@ -140,7 +140,9 @@
"translate": "翻訳", "translate": "翻訳",
"topics.prompt": "トピック提示語", "topics.prompt": "トピック提示語",
"topics.prompt.tips": "トピック提示語:現在のトピックに対して追加の補足提示語を提供", "topics.prompt.tips": "トピック提示語:現在のトピックに対して追加の補足提示語を提供",
"topics.prompt.edit.title": "トピック提示語を編集する" "topics.prompt.edit.title": "トピック提示語を編集する",
"artifacts.button.openExternal": "外部ブラウザで開く",
"artifacts.preview.openExternal.error.content": "外部ブラウザの起動に失敗しました。"
}, },
"common": { "common": {
"add": "追加", "add": "追加",
@ -808,4 +810,4 @@
"title": "ドキュメント" "title": "ドキュメント"
} }
} }
} }

View File

@ -140,7 +140,9 @@
"translate": "Перевести", "translate": "Перевести",
"topics.prompt": "Тематические подсказки", "topics.prompt": "Тематические подсказки",
"topics.prompt.tips": "Тематические подсказки: Дополнительные подсказки, предоставленные для текущей темы", "topics.prompt.tips": "Тематические подсказки: Дополнительные подсказки, предоставленные для текущей темы",
"topics.prompt.edit.title": "Редактировать подсказки темы" "topics.prompt.edit.title": "Редактировать подсказки темы",
"artifacts.button.openExternal": "Открыть во внешнем браузере",
"artifacts.preview.openExternal.error.content": "Внешний браузер открылся с ошибкой"
}, },
"common": { "common": {
"add": "Добавить", "add": "Добавить",
@ -787,4 +789,4 @@
"title": "Документация" "title": "Документация"
} }
} }
} }

View File

@ -74,6 +74,8 @@
"add.assistant.title": "添加助手", "add.assistant.title": "添加助手",
"artifacts.button.download": "下载", "artifacts.button.download": "下载",
"artifacts.button.preview": "预览", "artifacts.button.preview": "预览",
"artifacts.button.openExternal": "外部浏览器打开",
"artifacts.preview.openExternal.error.content": "外部浏览器打开出错",
"assistant.search.placeholder": "搜索", "assistant.search.placeholder": "搜索",
"deeply_thought": "已深度思考(用时 {{secounds}} 秒)", "deeply_thought": "已深度思考(用时 {{secounds}} 秒)",
"default.description": "你好,我是默认助手。你可以立刻开始跟我聊天。", "default.description": "你好,我是默认助手。你可以立刻开始跟我聊天。",

View File

@ -140,7 +140,9 @@
"translate": "翻譯", "translate": "翻譯",
"topics.prompt": "話題提示詞", "topics.prompt": "話題提示詞",
"topics.prompt.tips": "話題提示詞:針對目前話題提供額外的補充提示詞", "topics.prompt.tips": "話題提示詞:針對目前話題提供額外的補充提示詞",
"topics.prompt.edit.title": "編輯話題提示詞" "topics.prompt.edit.title": "編輯話題提示詞",
"artifacts.button.openExternal": "外部瀏覽器打開",
"artifacts.preview.openExternal.error.content": "外部瀏覽器打開出錯"
}, },
"common": { "common": {
"add": "添加", "add": "添加",
@ -789,4 +791,4 @@
"title": "幫助文件" "title": "幫助文件"
} }
} }
} }

View File

@ -1,4 +1,4 @@
import { DownloadOutlined, ExpandOutlined } from '@ant-design/icons' import { DownloadOutlined, ExpandOutlined, LinkOutlined } from '@ant-design/icons'
import MinApp from '@renderer/components/MinApp' import MinApp from '@renderer/components/MinApp'
import { AppLogo } from '@renderer/config/env' import { AppLogo } from '@renderer/config/env'
import { extractTitle } from '@renderer/utils/formats' import { extractTitle } from '@renderer/utils/formats'
@ -13,29 +13,55 @@ interface Props {
const Artifacts: FC<Props> = ({ html }) => { const Artifacts: FC<Props> = ({ html }) => {
const { t } = useTranslation() const { t } = useTranslation()
const title = extractTitle(html) || 'Artifacts' + ' ' + t('chat.artifacts.button.preview') const title = extractTitle(html) || 'Artifacts ' + t('chat.artifacts.button.preview')
const onPreview = async () => { /**
*
*/
const handleOpenInApp = async () => {
const path = await window.api.file.create('artifacts-preview.html') const path = await window.api.file.create('artifacts-preview.html')
await window.api.file.write(path, html) await window.api.file.write(path, html)
const filePath = `file://${path}`
MinApp.start({ MinApp.start({
name: title, name: title,
logo: AppLogo, logo: AppLogo,
url: `file://${path}` url: filePath
}) })
} }
/**
*
*/
const handleOpenExternal = async () => {
const path = await window.api.file.create('artifacts-preview.html')
await window.api.file.write(path, html)
const filePath = `file://${path}`
if (window.api.shell && window.api.shell.openExternal) {
window.api.shell.openExternal(filePath)
} else {
console.error(t('artifacts.preview.openExternal.error.content'))
}
}
/**
*
*/
const onDownload = () => { const onDownload = () => {
window.api.file.save(`${title}.html`, html) window.api.file.save(`${title}.html`, html)
} }
return ( return (
<Container> <Container>
<Button type="primary" icon={<ExpandOutlined />} onClick={onPreview} size="small"> <Button icon={<ExpandOutlined />} onClick={handleOpenInApp}>
{t('chat.artifacts.button.preview')} {t('chat.artifacts.button.preview')}
</Button> </Button>
<Button icon={<DownloadOutlined />} onClick={onDownload} size="small">
<Button icon={<LinkOutlined />} onClick={handleOpenExternal}>
{t('chat.artifacts.button.openExternal')}
</Button>
<Button icon={<DownloadOutlined />} onClick={onDownload}>
{t('chat.artifacts.button.download')} {t('chat.artifacts.button.download')}
</Button> </Button>
</Container> </Container>