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:
icarus 2025-10-11 16:37:39 +08:00
parent 0f14b1625f
commit 45bdea5301
3 changed files with 94 additions and 1 deletions

View File

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

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

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