mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-23 10:00:08 +08:00
feat: replace n8n icon with SVG version and update references
* removed the old n8n.ico file * added new n8n.svg file * updated references in minapps configuration and app components to use the new SVG logo * changed file handling from 'customMiniAPP' to 'custom-minapps.json' for consistency
This commit is contained in:
parent
6708efdbe1
commit
c0cb1693da
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
1
src/renderer/src/assets/images/apps/n8n.svg
Normal file
1
src/renderer/src/assets/images/apps/n8n.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>n8n</title><path clip-rule="evenodd" d="M24 8.4c0 1.325-1.102 2.4-2.462 2.4-1.146 0-2.11-.765-2.384-1.8h-3.436c-.602 0-1.115.424-1.214 1.003l-.101.592a2.38 2.38 0 01-.8 1.405c.412.354.704.844.8 1.405l.1.592A1.222 1.222 0 0015.719 15h.975c.273-1.035 1.237-1.8 2.384-1.8 1.36 0 2.461 1.075 2.461 2.4S20.436 18 19.078 18c-1.147 0-2.11-.765-2.384-1.8h-.975c-1.204 0-2.23-.848-2.428-2.005l-.101-.592a1.222 1.222 0 00-1.214-1.003H10.97c-.308.984-1.246 1.7-2.356 1.7-1.11 0-2.048-.716-2.355-1.7H4.817c-.308.984-1.246 1.7-2.355 1.7C1.102 14.3 0 13.225 0 11.9s1.102-2.4 2.462-2.4c1.183 0 2.172.815 2.408 1.9h1.337c.236-1.085 1.225-1.9 2.408-1.9 1.184 0 2.172.815 2.408 1.9h.952c.601 0 1.115-.424 1.213-1.003l.102-.592c.198-1.157 1.225-2.005 2.428-2.005h3.436c.274-1.035 1.238-1.8 2.384-1.8C22.898 6 24 7.075 24 8.4zm-1.23 0c0 .663-.552 1.2-1.232 1.2-.68 0-1.23-.537-1.23-1.2 0-.663.55-1.2 1.23-1.2.68 0 1.231.537 1.231 1.2zM2.461 13.1c.68 0 1.23-.537 1.23-1.2 0-.663-.55-1.2-1.23-1.2-.68 0-1.231.537-1.231 1.2 0 .663.55 1.2 1.23 1.2zm6.153 0c.68 0 1.231-.537 1.231-1.2 0-.663-.55-1.2-1.23-1.2-.68 0-1.231.537-1.231 1.2 0 .663.55 1.2 1.23 1.2zm10.462 3.7c.68 0 1.23-.537 1.23-1.2 0-.663-.55-1.2-1.23-1.2-.68 0-1.23.537-1.23 1.2 0 .663.55 1.2 1.23 1.2z" fill="#EA4B71" fill-rule="evenodd"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@ -1,8 +1,7 @@
|
||||
import n8nLogo from '@renderer/assets/images/apps/n8n.ico?url'
|
||||
import ApplicationLogo from '@renderer/assets/images/apps/application.png?url'
|
||||
import ThreeMinTopAppLogo from '@renderer/assets/images/apps/3mintop.png?url'
|
||||
import AbacusLogo from '@renderer/assets/images/apps/abacus.webp?url'
|
||||
import AIStudioLogo from '@renderer/assets/images/apps/aistudio.svg?url'
|
||||
import ApplicationLogo from '@renderer/assets/images/apps/application.png?url'
|
||||
import BaiduAiAppLogo from '@renderer/assets/images/apps/baidu-ai.png?url'
|
||||
import BaiduAiSearchLogo from '@renderer/assets/images/apps/baidu-ai-search.webp?url'
|
||||
import BaicuanAppLogo from '@renderer/assets/images/apps/baixiaoying.webp?url'
|
||||
@ -28,6 +27,7 @@ import LambdaChatLogo from '@renderer/assets/images/apps/lambdachat.webp?url'
|
||||
import LeChatLogo from '@renderer/assets/images/apps/lechat.png?url'
|
||||
import MetasoAppLogo from '@renderer/assets/images/apps/metaso.webp?url'
|
||||
import MonicaLogo from '@renderer/assets/images/apps/monica.webp?url'
|
||||
import n8nLogo from '@renderer/assets/images/apps/n8n.svg?url'
|
||||
import NamiAiLogo from '@renderer/assets/images/apps/nm.png?url'
|
||||
import NamiAiSearchLogo from '@renderer/assets/images/apps/nm-search.webp?url'
|
||||
import NotebookLMAppLogo from '@renderer/assets/images/apps/notebooklm.svg?url'
|
||||
@ -61,11 +61,11 @@ const loadCustomMiniApp = async (): Promise<MinAppType[]> => {
|
||||
try {
|
||||
let content: string
|
||||
try {
|
||||
content = await window.api.file.read('customMiniAPP')
|
||||
content = await window.api.file.read('custom-minapps.json')
|
||||
} catch (error) {
|
||||
// 如果文件不存在,创建一个空的 JSON 数组
|
||||
content = '[]'
|
||||
await window.api.file.writeWithId('customMiniAPP', content)
|
||||
await window.api.file.writeWithId('custom-minapps.json', content)
|
||||
}
|
||||
|
||||
const customApps = JSON.parse(content)
|
||||
@ -455,7 +455,10 @@ const ORIGIN_DEFAULT_MIN_APPS: MinAppType[] = [
|
||||
name: 'n8n',
|
||||
logo: n8nLogo,
|
||||
url: 'https://app.n8n.cloud/',
|
||||
bodered: true
|
||||
bodered: true,
|
||||
style: {
|
||||
padding: 5
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ const App: FC<Props> = ({ app, onClick, size = 60, isLast }) => {
|
||||
|
||||
const handleAddCustomApp = async (values: any) => {
|
||||
try {
|
||||
const content = await window.api.file.read('customMiniAPP')
|
||||
const content = await window.api.file.read('custom-minapps.json')
|
||||
const customApps = JSON.parse(content)
|
||||
|
||||
// Check for duplicate ID
|
||||
@ -62,7 +62,7 @@ const App: FC<Props> = ({ app, onClick, size = 60, isLast }) => {
|
||||
addTime: new Date().toISOString()
|
||||
}
|
||||
customApps.push(newApp)
|
||||
await window.api.file.writeWithId('customMiniAPP', JSON.stringify(customApps, null, 2))
|
||||
await window.api.file.writeWithId('custom-minapps.json', JSON.stringify(customApps, null, 2))
|
||||
message.success(t('settings.miniapps.custom.save_success'))
|
||||
setIsModalVisible(false)
|
||||
form.resetFields()
|
||||
@ -138,10 +138,10 @@ const App: FC<Props> = ({ app, onClick, size = 60, isLast }) => {
|
||||
danger: true,
|
||||
onClick: async () => {
|
||||
try {
|
||||
const content = await window.api.file.read('customMiniAPP')
|
||||
const content = await window.api.file.read('custom-minapps.json')
|
||||
const customApps = JSON.parse(content)
|
||||
const updatedApps = customApps.filter((customApp: MinAppType) => customApp.id !== app.id)
|
||||
await window.api.file.writeWithId('customMiniAPP', JSON.stringify(updatedApps, null, 2))
|
||||
await window.api.file.writeWithId('custom-minapps.json', JSON.stringify(updatedApps, null, 2))
|
||||
message.success(t('settings.miniapps.custom.remove_success'))
|
||||
const reloadedApps = [...ORIGIN_DEFAULT_MIN_APPS, ...(await loadCustomMiniApp())]
|
||||
updateDefaultMinApps(reloadedApps)
|
||||
|
||||
@ -1,10 +1,5 @@
|
||||
import { UndoOutlined } from '@ant-design/icons' // 导入重置图标
|
||||
import {
|
||||
DEFAULT_MIN_APPS,
|
||||
loadCustomMiniApp,
|
||||
ORIGIN_DEFAULT_MIN_APPS,
|
||||
updateDefaultMinApps
|
||||
} from '@renderer/config/minapps'
|
||||
import { DEFAULT_MIN_APPS } from '@renderer/config/minapps'
|
||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||
import { useMinapps } from '@renderer/hooks/useMinapps'
|
||||
import { useSettings } from '@renderer/hooks/useSettings'
|
||||
@ -14,7 +9,7 @@ import {
|
||||
setMinappsOpenLinkExternal,
|
||||
setShowOpenedMinappsInSidebar
|
||||
} from '@renderer/store/settings'
|
||||
import { Button, Input, message, Slider, Switch, Tooltip } from 'antd'
|
||||
import { Button, message, Slider, Switch, Tooltip } from 'antd'
|
||||
import { FC, useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled from 'styled-components'
|
||||
@ -36,92 +31,6 @@ const MiniAppSettings: FC = () => {
|
||||
const [disabledMiniApps, setDisabledMiniApps] = useState(disabled || [])
|
||||
const [messageApi, contextHolder] = message.useMessage()
|
||||
const debounceTimerRef = useRef<NodeJS.Timeout | null>(null)
|
||||
const [customMiniAppContent, setCustomMiniAppContent] = useState('[]')
|
||||
|
||||
// 加载自定义小应用配置
|
||||
useEffect(() => {
|
||||
const loadCustomMiniApp = async () => {
|
||||
try {
|
||||
const content = await window.api.file.read('customMiniAPP')
|
||||
let validContent = '[]'
|
||||
try {
|
||||
const parsed = JSON.parse(content)
|
||||
validContent = JSON.stringify(parsed)
|
||||
} catch (e) {
|
||||
console.error('Invalid JSON format in custom mini app config:', e)
|
||||
}
|
||||
setCustomMiniAppContent(validContent)
|
||||
} catch (error) {
|
||||
console.error('Failed to load custom mini app config:', error)
|
||||
setCustomMiniAppContent('[]')
|
||||
}
|
||||
}
|
||||
loadCustomMiniApp()
|
||||
}, [])
|
||||
|
||||
// 保存自定义小应用配置
|
||||
const handleSaveCustomMiniApp = useCallback(async () => {
|
||||
try {
|
||||
// 验证 JSON 格式
|
||||
if (customMiniAppContent === '') {
|
||||
setCustomMiniAppContent('[]')
|
||||
}
|
||||
const parsedContent = JSON.parse(customMiniAppContent)
|
||||
// 确保是数组
|
||||
if (!Array.isArray(parsedContent)) {
|
||||
throw new Error('Content must be an array')
|
||||
}
|
||||
|
||||
// 检查自定义应用中的重复ID
|
||||
const customIds = new Set<string>()
|
||||
const duplicateIds = new Set<string>()
|
||||
parsedContent.forEach((app: any) => {
|
||||
if (app.id) {
|
||||
if (customIds.has(app.id)) {
|
||||
duplicateIds.add(app.id)
|
||||
}
|
||||
customIds.add(app.id)
|
||||
}
|
||||
})
|
||||
|
||||
// 检查与默认应用的ID重复
|
||||
const defaultIds = new Set(ORIGIN_DEFAULT_MIN_APPS.map((app) => app.id))
|
||||
const conflictingIds = new Set<string>()
|
||||
customIds.forEach((id) => {
|
||||
if (defaultIds.has(id)) {
|
||||
conflictingIds.add(id)
|
||||
}
|
||||
})
|
||||
|
||||
// 如果有重复ID,显示错误信息
|
||||
if (duplicateIds.size > 0 || conflictingIds.size > 0) {
|
||||
let errorMessage = ''
|
||||
if (duplicateIds.size > 0) {
|
||||
errorMessage += t('settings.miniapps.custom.duplicate_ids', { ids: Array.from(duplicateIds).join(', ') })
|
||||
}
|
||||
if (conflictingIds.size > 0) {
|
||||
console.log('conflictingIds', Array.from(conflictingIds))
|
||||
if (errorMessage) errorMessage += '\n'
|
||||
errorMessage += t('settings.miniapps.custom.conflicting_ids', { ids: Array.from(conflictingIds).join(', ') })
|
||||
}
|
||||
messageApi.error(errorMessage)
|
||||
return
|
||||
}
|
||||
|
||||
// 保存文件
|
||||
await window.api.file.writeWithId('customMiniAPP', customMiniAppContent)
|
||||
messageApi.success(t('settings.miniapps.custom.save_success'))
|
||||
// 重新加载应用列表
|
||||
console.log('Reloading mini app list...')
|
||||
const reloadedApps = [...ORIGIN_DEFAULT_MIN_APPS, ...(await loadCustomMiniApp())]
|
||||
updateDefaultMinApps(reloadedApps)
|
||||
console.log('Reloaded mini app list:', reloadedApps)
|
||||
updateMinapps(reloadedApps)
|
||||
} catch (error) {
|
||||
messageApi.error(t('settings.miniapps.custom.save_error'))
|
||||
console.error('Failed to save custom mini app config:', error)
|
||||
}
|
||||
}, [customMiniAppContent, messageApi, t, updateMinapps])
|
||||
|
||||
const handleResetMinApps = useCallback(() => {
|
||||
setVisibleMiniApps(DEFAULT_MIN_APPS)
|
||||
@ -235,30 +144,6 @@ const MiniAppSettings: FC = () => {
|
||||
onChange={(checked) => dispatch(setShowOpenedMinappsInSidebar(checked))}
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingDivider />
|
||||
<SettingRow>
|
||||
<SettingLabelGroup>
|
||||
<SettingRowTitle>{t('settings.miniapps.custom.edit_title')}</SettingRowTitle>
|
||||
<SettingDescription>{t('settings.miniapps.custom.edit_description')}</SettingDescription>
|
||||
</SettingLabelGroup>
|
||||
</SettingRow>
|
||||
<CustomEditorContainer>
|
||||
<Input.TextArea
|
||||
value={customMiniAppContent}
|
||||
onChange={(e) => setCustomMiniAppContent(e.target.value)}
|
||||
placeholder={t('settings.miniapps.custom.placeholder')}
|
||||
style={{
|
||||
minHeight: 200,
|
||||
fontFamily: 'monospace',
|
||||
backgroundColor: 'var(--color-bg-2)',
|
||||
color: 'var(--color-text)',
|
||||
borderColor: 'var(--color-border)'
|
||||
}}
|
||||
/>
|
||||
<Button type="primary" onClick={handleSaveCustomMiniApp} style={{ marginTop: 8 }}>
|
||||
{t('settings.miniapps.custom.save')}
|
||||
</Button>
|
||||
</CustomEditorContainer>
|
||||
</SettingGroup>
|
||||
</SettingContainer>
|
||||
)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user