mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-06 21:35:52 +08:00
feat(video): add video page and sidebar integration
- Add new video page component with basic structure - Include video icon in sidebar and launchpad - Update i18n labels for video feature - Increment store version and add migration for video icon
This commit is contained in:
parent
87bac60afc
commit
0f14b1625f
@ -20,6 +20,7 @@ import PaintingsRoutePage from './pages/paintings/PaintingsRoutePage'
|
|||||||
import SettingsPage from './pages/settings/SettingsPage'
|
import SettingsPage from './pages/settings/SettingsPage'
|
||||||
import AssistantPresetsPage from './pages/store/assistants/presets/AssistantPresetsPage'
|
import AssistantPresetsPage from './pages/store/assistants/presets/AssistantPresetsPage'
|
||||||
import TranslatePage from './pages/translate/TranslatePage'
|
import TranslatePage from './pages/translate/TranslatePage'
|
||||||
|
import { VideoPage } from './pages/video/VideoPage'
|
||||||
|
|
||||||
const Router: FC = () => {
|
const Router: FC = () => {
|
||||||
const { navbarPosition } = useNavbarPosition()
|
const { navbarPosition } = useNavbarPosition()
|
||||||
@ -40,6 +41,7 @@ const Router: FC = () => {
|
|||||||
<Route path="/code" element={<CodeToolsPage />} />
|
<Route path="/code" element={<CodeToolsPage />} />
|
||||||
<Route path="/settings/*" element={<SettingsPage />} />
|
<Route path="/settings/*" element={<SettingsPage />} />
|
||||||
<Route path="/launchpad" element={<LaunchpadPage />} />
|
<Route path="/launchpad" element={<LaunchpadPage />} />
|
||||||
|
<Route path="/video" element={<VideoPage />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -32,6 +32,7 @@ import {
|
|||||||
Sparkle,
|
Sparkle,
|
||||||
Sun,
|
Sun,
|
||||||
Terminal,
|
Terminal,
|
||||||
|
Video,
|
||||||
X
|
X
|
||||||
} from 'lucide-react'
|
} from 'lucide-react'
|
||||||
import { useCallback, useEffect, useMemo } from 'react'
|
import { useCallback, useEffect, useMemo } from 'react'
|
||||||
@ -106,6 +107,8 @@ const getTabIcon = (
|
|||||||
return <Settings size={14} />
|
return <Settings size={14} />
|
||||||
case 'code':
|
case 'code':
|
||||||
return <Terminal size={14} />
|
return <Terminal size={14} />
|
||||||
|
case 'video':
|
||||||
|
return <Video size={14} />
|
||||||
default:
|
default:
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,7 +26,8 @@ import {
|
|||||||
Palette,
|
Palette,
|
||||||
Settings,
|
Settings,
|
||||||
Sparkle,
|
Sparkle,
|
||||||
Sun
|
Sun,
|
||||||
|
Video
|
||||||
} from 'lucide-react'
|
} from 'lucide-react'
|
||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
@ -139,7 +140,8 @@ const MainMenus: FC = () => {
|
|||||||
knowledge: <FileSearch size={18} className="icon" />,
|
knowledge: <FileSearch size={18} className="icon" />,
|
||||||
files: <Folder size={18} className="icon" />,
|
files: <Folder size={18} className="icon" />,
|
||||||
notes: <NotepadText size={18} className="icon" />,
|
notes: <NotepadText size={18} className="icon" />,
|
||||||
code_tools: <Code size={18} className="icon" />
|
code_tools: <Code size={18} className="icon" />,
|
||||||
|
video: <Video size={18} className="icon" />
|
||||||
}
|
}
|
||||||
|
|
||||||
const pathMap = {
|
const pathMap = {
|
||||||
@ -151,7 +153,8 @@ const MainMenus: FC = () => {
|
|||||||
knowledge: '/knowledge',
|
knowledge: '/knowledge',
|
||||||
files: '/files',
|
files: '/files',
|
||||||
code_tools: '/code',
|
code_tools: '/code',
|
||||||
notes: '/notes'
|
notes: '/notes',
|
||||||
|
video: '/video'
|
||||||
}
|
}
|
||||||
|
|
||||||
return sidebarIcons.visible.map((icon) => {
|
return sidebarIcons.visible.map((icon) => {
|
||||||
|
|||||||
@ -146,7 +146,8 @@ const titleKeyMap = {
|
|||||||
notes: 'title.notes',
|
notes: 'title.notes',
|
||||||
paintings: 'title.paintings',
|
paintings: 'title.paintings',
|
||||||
settings: 'title.settings',
|
settings: 'title.settings',
|
||||||
translate: 'title.translate'
|
translate: 'title.translate',
|
||||||
|
video: 'title.video'
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
export const getTitleLabel = (key: string): string => {
|
export const getTitleLabel = (key: string): string => {
|
||||||
@ -172,7 +173,8 @@ const sidebarIconKeyMap = {
|
|||||||
knowledge: 'knowledge.title',
|
knowledge: 'knowledge.title',
|
||||||
files: 'files.title',
|
files: 'files.title',
|
||||||
code_tools: 'code.title',
|
code_tools: 'code.title',
|
||||||
notes: 'notes.title'
|
notes: 'notes.title',
|
||||||
|
video: 'video.title'
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
export const getSidebarIconLabel = (key: string): string => {
|
export const getSidebarIconLabel = (key: string): string => {
|
||||||
|
|||||||
@ -4486,7 +4486,8 @@
|
|||||||
"paintings": "Paintings",
|
"paintings": "Paintings",
|
||||||
"settings": "Settings",
|
"settings": "Settings",
|
||||||
"store": "Assistant Library",
|
"store": "Assistant Library",
|
||||||
"translate": "Translate"
|
"translate": "Translate",
|
||||||
|
"video": "Video"
|
||||||
},
|
},
|
||||||
"trace": {
|
"trace": {
|
||||||
"backList": "Back To List",
|
"backList": "Back To List",
|
||||||
@ -4644,6 +4645,9 @@
|
|||||||
"saveDataError": "Failed to save data, please try again.",
|
"saveDataError": "Failed to save data, please try again.",
|
||||||
"title": "Update"
|
"title": "Update"
|
||||||
},
|
},
|
||||||
|
"video": {
|
||||||
|
"title": "Video"
|
||||||
|
},
|
||||||
"warning": {
|
"warning": {
|
||||||
"missing_provider": "The supplier does not exist; reverted to the default supplier {{provider}}. This may cause issues."
|
"missing_provider": "The supplier does not exist; reverted to the default supplier {{provider}}. This may cause issues."
|
||||||
},
|
},
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import App from '@renderer/components/MinApp/MinApp'
|
|||||||
import { useMinapps } from '@renderer/hooks/useMinapps'
|
import { useMinapps } from '@renderer/hooks/useMinapps'
|
||||||
import { useRuntime } from '@renderer/hooks/useRuntime'
|
import { useRuntime } from '@renderer/hooks/useRuntime'
|
||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
import { useSettings } from '@renderer/hooks/useSettings'
|
||||||
import { Code, FileSearch, Folder, Languages, LayoutGrid, NotepadText, Palette, Sparkle } from 'lucide-react'
|
import { Code, FileSearch, Folder, Languages, LayoutGrid, NotepadText, Palette, Sparkle, Video } from 'lucide-react'
|
||||||
import { FC, useMemo } from 'react'
|
import { FC, useMemo } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
@ -63,6 +63,12 @@ const LaunchpadPage: FC = () => {
|
|||||||
text: t('title.notes'),
|
text: t('title.notes'),
|
||||||
path: '/notes',
|
path: '/notes',
|
||||||
bgColor: 'linear-gradient(135deg, #F97316, #FB923C)' // 笔记:橙色,代表活力和清晰思路
|
bgColor: 'linear-gradient(135deg, #F97316, #FB923C)' // 笔记:橙色,代表活力和清晰思路
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <Video size={32} className="icon" />,
|
||||||
|
text: t('title.video'),
|
||||||
|
path: '/video',
|
||||||
|
bgColor: 'linear-gradient(135deg, #7C3AED, #A78BFA)' // Video Generation: deep purple, representing creativity and dynamic media
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,8 @@ import {
|
|||||||
MessageSquareQuote,
|
MessageSquareQuote,
|
||||||
NotepadText,
|
NotepadText,
|
||||||
Palette,
|
Palette,
|
||||||
Sparkle
|
Sparkle,
|
||||||
|
Video
|
||||||
} from 'lucide-react'
|
} from 'lucide-react'
|
||||||
import { FC, useCallback, useMemo } from 'react'
|
import { FC, useCallback, useMemo } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
@ -127,7 +128,8 @@ const SidebarIconsManager: FC<SidebarIconsManagerProps> = ({
|
|||||||
knowledge: <FileSearch size={16} />,
|
knowledge: <FileSearch size={16} />,
|
||||||
files: <Folder size={16} />,
|
files: <Folder size={16} />,
|
||||||
notes: <NotepadText size={16} />,
|
notes: <NotepadText size={16} />,
|
||||||
code_tools: <Code size={16} />
|
code_tools: <Code size={16} />,
|
||||||
|
video: <Video size={16} />
|
||||||
}),
|
}),
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
|
|||||||
16
src/renderer/src/pages/video/VideoPage.tsx
Normal file
16
src/renderer/src/pages/video/VideoPage.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// interface VideoPageProps {}
|
||||||
|
|
||||||
|
import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
export const VideoPage = () => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
return (
|
||||||
|
<div className="flex flex-1 flex-col">
|
||||||
|
<Navbar>
|
||||||
|
<NavbarCenter style={{ borderRight: 'none' }}>{t('video.title')}</NavbarCenter>
|
||||||
|
</Navbar>
|
||||||
|
<div className="flex flex-1">video page</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -65,7 +65,7 @@ const persistedReducer = persistReducer(
|
|||||||
{
|
{
|
||||||
key: 'cherry-studio',
|
key: 'cherry-studio',
|
||||||
storage,
|
storage,
|
||||||
version: 160,
|
version: 161,
|
||||||
blacklist: ['runtime', 'messages', 'messageBlocks', 'tabs'],
|
blacklist: ['runtime', 'messages', 'messageBlocks', 'tabs'],
|
||||||
migrate
|
migrate
|
||||||
},
|
},
|
||||||
|
|||||||
@ -2654,6 +2654,19 @@ const migrateConfig = {
|
|||||||
logger.error('migrate 160 error', error as Error)
|
logger.error('migrate 160 error', error as Error)
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
'161': (state: RootState) => {
|
||||||
|
try {
|
||||||
|
if (state.settings && state.settings.sidebarIcons) {
|
||||||
|
if (!state.settings.sidebarIcons.visible.includes('video')) {
|
||||||
|
state.settings.sidebarIcons.visible = [...state.settings.sidebarIcons.visible, 'video']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return state
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('migrate 161 error', error as Error)
|
||||||
|
return state
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -534,6 +534,7 @@ export type SidebarIcon =
|
|||||||
| 'files'
|
| 'files'
|
||||||
| 'code_tools'
|
| 'code_tools'
|
||||||
| 'notes'
|
| 'notes'
|
||||||
|
| 'video'
|
||||||
|
|
||||||
export type ExternalToolResult = {
|
export type ExternalToolResult = {
|
||||||
mcpTools?: MCPTool[]
|
mcpTools?: MCPTool[]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user