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:
icarus 2025-10-11 15:39:38 +08:00
parent 87bac60afc
commit 0f14b1625f
11 changed files with 62 additions and 10 deletions

View File

@ -20,6 +20,7 @@ import PaintingsRoutePage from './pages/paintings/PaintingsRoutePage'
import SettingsPage from './pages/settings/SettingsPage'
import AssistantPresetsPage from './pages/store/assistants/presets/AssistantPresetsPage'
import TranslatePage from './pages/translate/TranslatePage'
import { VideoPage } from './pages/video/VideoPage'
const Router: FC = () => {
const { navbarPosition } = useNavbarPosition()
@ -40,6 +41,7 @@ const Router: FC = () => {
<Route path="/code" element={<CodeToolsPage />} />
<Route path="/settings/*" element={<SettingsPage />} />
<Route path="/launchpad" element={<LaunchpadPage />} />
<Route path="/video" element={<VideoPage />} />
</Routes>
</ErrorBoundary>
)

View File

@ -32,6 +32,7 @@ import {
Sparkle,
Sun,
Terminal,
Video,
X
} from 'lucide-react'
import { useCallback, useEffect, useMemo } from 'react'
@ -106,6 +107,8 @@ const getTabIcon = (
return <Settings size={14} />
case 'code':
return <Terminal size={14} />
case 'video':
return <Video size={14} />
default:
return null
}

View File

@ -26,7 +26,8 @@ import {
Palette,
Settings,
Sparkle,
Sun
Sun,
Video
} from 'lucide-react'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
@ -139,7 +140,8 @@ const MainMenus: FC = () => {
knowledge: <FileSearch size={18} className="icon" />,
files: <Folder 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 = {
@ -151,7 +153,8 @@ const MainMenus: FC = () => {
knowledge: '/knowledge',
files: '/files',
code_tools: '/code',
notes: '/notes'
notes: '/notes',
video: '/video'
}
return sidebarIcons.visible.map((icon) => {

View File

@ -146,7 +146,8 @@ const titleKeyMap = {
notes: 'title.notes',
paintings: 'title.paintings',
settings: 'title.settings',
translate: 'title.translate'
translate: 'title.translate',
video: 'title.video'
} as const
export const getTitleLabel = (key: string): string => {
@ -172,7 +173,8 @@ const sidebarIconKeyMap = {
knowledge: 'knowledge.title',
files: 'files.title',
code_tools: 'code.title',
notes: 'notes.title'
notes: 'notes.title',
video: 'video.title'
} as const
export const getSidebarIconLabel = (key: string): string => {

View File

@ -4486,7 +4486,8 @@
"paintings": "Paintings",
"settings": "Settings",
"store": "Assistant Library",
"translate": "Translate"
"translate": "Translate",
"video": "Video"
},
"trace": {
"backList": "Back To List",
@ -4644,6 +4645,9 @@
"saveDataError": "Failed to save data, please try again.",
"title": "Update"
},
"video": {
"title": "Video"
},
"warning": {
"missing_provider": "The supplier does not exist; reverted to the default supplier {{provider}}. This may cause issues."
},

View File

@ -2,7 +2,7 @@ import App from '@renderer/components/MinApp/MinApp'
import { useMinapps } from '@renderer/hooks/useMinapps'
import { useRuntime } from '@renderer/hooks/useRuntime'
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 { useTranslation } from 'react-i18next'
import { useNavigate } from 'react-router-dom'
@ -63,6 +63,12 @@ const LaunchpadPage: FC = () => {
text: t('title.notes'),
path: '/notes',
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
}
]

View File

@ -21,7 +21,8 @@ import {
MessageSquareQuote,
NotepadText,
Palette,
Sparkle
Sparkle,
Video
} from 'lucide-react'
import { FC, useCallback, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
@ -127,7 +128,8 @@ const SidebarIconsManager: FC<SidebarIconsManagerProps> = ({
knowledge: <FileSearch size={16} />,
files: <Folder size={16} />,
notes: <NotepadText size={16} />,
code_tools: <Code size={16} />
code_tools: <Code size={16} />,
video: <Video size={16} />
}),
[]
)

View 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>
)
}

View File

@ -65,7 +65,7 @@ const persistedReducer = persistReducer(
{
key: 'cherry-studio',
storage,
version: 160,
version: 161,
blacklist: ['runtime', 'messages', 'messageBlocks', 'tabs'],
migrate
},

View File

@ -2654,6 +2654,19 @@ const migrateConfig = {
logger.error('migrate 160 error', error as Error)
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
}
}
}

View File

@ -534,6 +534,7 @@ export type SidebarIcon =
| 'files'
| 'code_tools'
| 'notes'
| 'video'
export type ExternalToolResult = {
mcpTools?: MCPTool[]