mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-28 21:42:27 +08:00
refactor(video): rename VideoPlayer to VideoViewer and improve layout
Move status radio group to absolute position and update background colors
This commit is contained in:
parent
dad9425b44
commit
d982c659d3
@ -8,7 +8,7 @@ import { ArrowUp } from 'lucide-react'
|
||||
import { useCallback, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import { VideoPlayer } from './VideoPlayer'
|
||||
import { VideoViewer } from './VideoViewer'
|
||||
|
||||
export type VideoPanelProps = {
|
||||
provider: Provider
|
||||
@ -44,7 +44,7 @@ export const VideoPanel = ({ provider, video }: VideoPanelProps) => {
|
||||
<div className="flex flex-1 flex-col p-2">
|
||||
<div className="m-8 flex-1">
|
||||
<Skeleton className="h-full w-full rounded-2xl" classNames={{ content: 'h-full w-full' }} isLoaded={true}>
|
||||
<VideoPlayer video={video} />
|
||||
<VideoViewer video={video} />
|
||||
</Skeleton>
|
||||
</div>
|
||||
<div className="relative">
|
||||
|
||||
@ -1,80 +0,0 @@
|
||||
import { Progress, Radio, RadioGroup, Spinner } from '@heroui/react'
|
||||
import { Video, VideoStatus } from '@renderer/types/video'
|
||||
import { CheckCircleIcon, CircleXIcon } from 'lucide-react'
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export interface VideoProps {
|
||||
video?: Video
|
||||
}
|
||||
|
||||
export const VideoPlayer = ({ video: _video }: VideoProps) => {
|
||||
const { t } = useTranslation()
|
||||
const [video, setVideo] = useState<Video | undefined>(_video)
|
||||
return (
|
||||
<div className="flex h-full w-full items-center justify-center rounded-2xl bg-foreground-200">
|
||||
{/* For test */}
|
||||
<RadioGroup
|
||||
label="Status"
|
||||
onValueChange={(v) => {
|
||||
if (v) setVideo({ ...video, status: v as VideoStatus } as Video)
|
||||
else setVideo(undefined)
|
||||
}}>
|
||||
<Radio value="undefined">undefined</Radio>
|
||||
<Radio value="queued">queued</Radio>
|
||||
<Radio value="in_progress">in_progress</Radio>
|
||||
<Radio value="completed">completed</Radio>
|
||||
<Radio value="downloading">downloading</Radio>
|
||||
<Radio value="downloaded">downloaded</Radio>
|
||||
<Radio value="failed">failed</Radio>
|
||||
</RadioGroup>
|
||||
{video === undefined && t('video.undefined')}
|
||||
{video && video.status === 'queued' && (
|
||||
<div className="flex h-full w-full flex-col items-center justify-center rounded-2xl">
|
||||
<Spinner variant="dots" />
|
||||
<span>{t('video.status.queued')}</span>
|
||||
</div>
|
||||
)}
|
||||
{video && video.status === 'in_progress' && (
|
||||
<div className="flex h-full w-full flex-col items-center justify-center rounded-2xl">
|
||||
<Progress
|
||||
label={t('video.status.in_progress')}
|
||||
aria-label={t('video.status.in_progress')}
|
||||
className="max-w-md"
|
||||
color="primary"
|
||||
showValueLabel={true}
|
||||
size="md"
|
||||
value={video.progress}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{video && video.status === 'completed' && (
|
||||
<div className="flex h-full w-full flex-col items-center justify-center rounded-2xl bg-success-100">
|
||||
<CheckCircleIcon size={64} className="fill-success text-success-100" />
|
||||
<span className="font-bold text-2xl">{t('video.status.completed')}</span>
|
||||
</div>
|
||||
)}
|
||||
{video && video.status === 'downloading' && (
|
||||
<div className="flex h-full w-full flex-col items-center justify-center rounded-2xl">
|
||||
<Progress
|
||||
label={t('video.status.downloading')}
|
||||
aria-label={t('video.status.downloading')}
|
||||
className="max-w-md"
|
||||
color="primary"
|
||||
showValueLabel={true}
|
||||
size="md"
|
||||
value={video.progress}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{/* TODO: complete video widget */}
|
||||
{video && video.status === 'downloaded' && <video></video>}
|
||||
{video && video.status === 'failed' && (
|
||||
<div className="flex h-full w-full flex-col items-center justify-center rounded-2xl bg-danger-100">
|
||||
<CircleXIcon size={64} className="fill-danger text-danger-100" />
|
||||
<span className="font-bold text-2xl">{t('video.status.failed')}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
85
src/renderer/src/pages/video/VideoViewer.tsx
Normal file
85
src/renderer/src/pages/video/VideoViewer.tsx
Normal file
@ -0,0 +1,85 @@
|
||||
import { Progress, Radio, RadioGroup, Spinner } from '@heroui/react'
|
||||
import { Video, VideoStatus } from '@renderer/types/video'
|
||||
import { CheckCircleIcon, CircleXIcon } from 'lucide-react'
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export interface VideoProps {
|
||||
video?: Video
|
||||
}
|
||||
|
||||
export const VideoViewer = ({ video: _video }: VideoProps) => {
|
||||
const { t } = useTranslation()
|
||||
const [video, setVideo] = useState<Video | undefined>(_video)
|
||||
return (
|
||||
<>
|
||||
{/* For test */}
|
||||
<RadioGroup
|
||||
label="Status"
|
||||
value={video?.status}
|
||||
onValueChange={(v) => {
|
||||
if (v) setVideo({ ...video, status: v as VideoStatus } as Video)
|
||||
else setVideo(undefined)
|
||||
}}
|
||||
orientation="horizontal"
|
||||
className="absolute rounded-2xl bg-foreground-100 p-4">
|
||||
<Radio value="undefined">undefined</Radio>
|
||||
<Radio value="queued">queued</Radio>
|
||||
<Radio value="in_progress">in_progress</Radio>
|
||||
<Radio value="completed">completed</Radio>
|
||||
<Radio value="downloading">downloading</Radio>
|
||||
<Radio value="downloaded">downloaded</Radio>
|
||||
<Radio value="failed">failed</Radio>
|
||||
</RadioGroup>
|
||||
<div className="flex h-full w-full items-center justify-center rounded-2xl bg-foreground-200">
|
||||
{video === undefined && t('video.undefined')}
|
||||
{video && video.status === 'queued' && (
|
||||
<div className="flex h-full w-full flex-col items-center justify-center rounded-2xl">
|
||||
<Spinner variant="dots" />
|
||||
<span>{t('video.status.queued')}</span>
|
||||
</div>
|
||||
)}
|
||||
{video && video.status === 'in_progress' && (
|
||||
<div className="flex h-full w-full flex-col items-center justify-center rounded-2xl">
|
||||
<Progress
|
||||
label={t('video.status.in_progress')}
|
||||
aria-label={t('video.status.in_progress')}
|
||||
className="max-w-md"
|
||||
color="primary"
|
||||
showValueLabel={true}
|
||||
size="md"
|
||||
value={video.progress}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{video && video.status === 'completed' && (
|
||||
<div className="flex h-full w-full flex-col items-center justify-center rounded-2xl bg-success-200">
|
||||
<CheckCircleIcon size={64} className="text-success" />
|
||||
<span className="font-bold text-2xl">{t('video.status.completed')}</span>
|
||||
</div>
|
||||
)}
|
||||
{video && video.status === 'downloading' && (
|
||||
<div className="flex h-full w-full flex-col items-center justify-center rounded-2xl">
|
||||
<Progress
|
||||
label={t('video.status.downloading')}
|
||||
aria-label={t('video.status.downloading')}
|
||||
className="max-w-md"
|
||||
color="primary"
|
||||
showValueLabel={true}
|
||||
size="md"
|
||||
value={video.progress}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{/* TODO: complete video widget */}
|
||||
{video && video.status === 'downloaded' && <video></video>}
|
||||
{video && video.status === 'failed' && (
|
||||
<div className="flex h-full w-full flex-col items-center justify-center rounded-2xl bg-danger-200">
|
||||
<CircleXIcon size={64} className="fill-danger text-danger-200" />
|
||||
<span className="font-bold text-2xl">{t('video.status.failed')}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user