mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-28 05:11:24 +08:00
feat(video): add provider settings component and layout
Implement provider selection dropdown in video settings panel Add shared setting components for consistent styling Update video page layout to accommodate settings sidebar
This commit is contained in:
parent
0f14b1625f
commit
45bdea5301
@ -1,16 +1,30 @@
|
||||
// interface VideoPageProps {}
|
||||
|
||||
import { Divider } from '@heroui/react'
|
||||
import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar'
|
||||
import { SystemProviderIds } from '@renderer/types'
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import { ProviderSetting } from './settings/ProviderSetting'
|
||||
|
||||
export const VideoPage = () => {
|
||||
const { t } = useTranslation()
|
||||
const [providerId, setProviderId] = useState<string>(SystemProviderIds.openai)
|
||||
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 id="content-container" className="flex flex-1">
|
||||
<div className="flex w-70 flex-col p-2">
|
||||
<ProviderSetting providerId={providerId} setProviderId={setProviderId} />
|
||||
</div>
|
||||
<Divider orientation="vertical" />
|
||||
<div className="flex-1 p-2"></div>
|
||||
<Divider orientation="vertical" />
|
||||
<div className="w-25"></div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
59
src/renderer/src/pages/video/settings/ProviderSetting.tsx
Normal file
59
src/renderer/src/pages/video/settings/ProviderSetting.tsx
Normal file
@ -0,0 +1,59 @@
|
||||
import { Select, SelectItem } from '@heroui/react'
|
||||
import { ProviderAvatar } from '@renderer/components/ProviderAvatar'
|
||||
import { useProviders } from '@renderer/hooks/useProvider'
|
||||
import { Provider, SystemProviderId } from '@renderer/types'
|
||||
import { getFancyProviderName } from '@renderer/utils'
|
||||
import { Dispatch, SetStateAction } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import { SettingItem, SettingTitle } from './shared'
|
||||
|
||||
export interface ProviderSettingProps {
|
||||
providerId: string
|
||||
setProviderId: Dispatch<SetStateAction<string>>
|
||||
}
|
||||
|
||||
interface ProviderSelectItem extends Provider {
|
||||
key: string
|
||||
label: string
|
||||
}
|
||||
|
||||
export const ProviderSetting = ({ providerId, setProviderId }: ProviderSettingProps) => {
|
||||
const { t } = useTranslation()
|
||||
// Support limited providers.
|
||||
const supportedProviderIds = ['openai'] satisfies SystemProviderId[]
|
||||
const { providers } = useProviders()
|
||||
const items: ProviderSelectItem[] = providers
|
||||
.filter((p) => supportedProviderIds.some((id) => id === p.id))
|
||||
.map((p) => ({ ...p, key: p.id, label: getFancyProviderName(p) }))
|
||||
|
||||
return (
|
||||
<SettingItem>
|
||||
<SettingTitle name={t('common.provider')} />
|
||||
<Select
|
||||
selectionMode="single"
|
||||
items={items}
|
||||
defaultSelectedKeys={[providerId]}
|
||||
disallowEmptySelection
|
||||
onSelectionChange={(keys) => {
|
||||
if (keys.currentKey) setProviderId(keys.currentKey)
|
||||
}}
|
||||
renderValue={(items) => {
|
||||
const provider = items[0].data
|
||||
if (!provider) return null
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
<ProviderAvatar provider={provider} size={16} />
|
||||
<span>{provider.label}</span>
|
||||
</div>
|
||||
)
|
||||
}}>
|
||||
{(provider) => (
|
||||
<SelectItem textValue={provider.label} startContent={<ProviderAvatar provider={provider} size={16} />}>
|
||||
<span>{provider.label}</span>
|
||||
</SelectItem>
|
||||
)}
|
||||
</Select>
|
||||
</SettingItem>
|
||||
)
|
||||
}
|
||||
20
src/renderer/src/pages/video/settings/shared.tsx
Normal file
20
src/renderer/src/pages/video/settings/shared.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
import { cn, Divider } from '@heroui/react'
|
||||
import { PropsWithChildren, ReactNode } from 'react'
|
||||
|
||||
export const SettingItem = ({ children, divider = true }: PropsWithChildren<{ divider?: boolean }>) => {
|
||||
return (
|
||||
<>
|
||||
<div className="mb-2">{children}</div>
|
||||
{divider && <Divider className="my-2" />}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export const SettingTitle = ({ name, footer }: { name: string; footer?: ReactNode }) => {
|
||||
return (
|
||||
<div className={cn('mb-2 flex items-center', footer ? 'justify-between' : 'justify-start')}>
|
||||
<span className="font-bold">{name}</span>
|
||||
{footer}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user