From 83114ee0c13225258b256d57b28f39c8138a0aa1 Mon Sep 17 00:00:00 2001 From: icarus Date: Sun, 12 Oct 2025 07:44:43 +0800 Subject: [PATCH] feat(video): add active video selection to VideoList - Introduce activeVideoId state to track selected video - Update VideoList to highlight active video with border - Pass click handler to set active video --- src/renderer/src/pages/video/VideoList.tsx | 35 ++++++++++++++-------- src/renderer/src/pages/video/VideoPage.tsx | 4 ++- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/renderer/src/pages/video/VideoList.tsx b/src/renderer/src/pages/video/VideoList.tsx index 93c92f68f4..11bd58d5b8 100644 --- a/src/renderer/src/pages/video/VideoList.tsx +++ b/src/renderer/src/pages/video/VideoList.tsx @@ -1,12 +1,12 @@ -import { Progress, Spinner } from '@heroui/react' +import { cn, Progress, Spinner } from '@heroui/react' import { useVideos } from '@renderer/hooks/video/useVideos' import { Video } from '@renderer/types/video' import { CheckCircleIcon, CircleXIcon, ClockIcon, DownloadIcon } from 'lucide-react' import { useTranslation } from 'react-i18next' -export type VideoListProps = { providerId: string } +export type VideoListProps = { providerId: string; activeVideoId?: string; setActiveVideoId: (id: string) => void } -export const VideoList = ({ providerId }: VideoListProps) => { +export const VideoList = ({ providerId, activeVideoId, setActiveVideoId }: VideoListProps) => { const { videos } = useVideos(providerId) // Mock data for testing @@ -146,13 +146,18 @@ export const VideoList = ({ providerId }: VideoListProps) => { return (
{displayVideos.map((video) => ( - + setActiveVideoId(video.id)} + /> ))}
) } -const VideoListItem = ({ video }: { video: Video }) => { +const VideoListItem = ({ video, isActive, onClick }: { video: Video; isActive: boolean; onClick: () => void }) => { const { t } = useTranslation() const getStatusIcon = () => { @@ -177,19 +182,19 @@ const VideoListItem = ({ video }: { video: Video }) => { const getStatusColor = () => { switch (video.status) { case 'queued': - return 'border-default-300 bg-default-100' + return 'bg-default-100' case 'in_progress': - return 'border-primary-300 bg-primary-50' + return 'bg-primary-50' case 'completed': - return 'border-success-300 bg-success-50' + return 'bg-success-50' case 'downloading': - return 'border-primary-300 bg-primary-50' + return 'bg-primary-50' case 'downloaded': - return 'border-success-300 bg-success-50' + return 'bg-success-50' case 'failed': - return 'border-danger-300 bg-danger-50' + return 'bg-danger-50' default: - return 'border-default-200 bg-default-50' + return 'bg-default-50' } } @@ -198,7 +203,11 @@ const VideoListItem = ({ video }: { video: Video }) => { return (
+ className={cn( + `group relative aspect-square cursor-pointer overflow-hidden rounded-xl border-2 transition-all hover:scale-105 hover:shadow-lg ${getStatusColor()}`, + isActive ? 'border-primary' : undefined + )} + onClick={onClick}> {/* Thumbnail placeholder */}
{showThumbnail ? ( diff --git a/src/renderer/src/pages/video/VideoPage.tsx b/src/renderer/src/pages/video/VideoPage.tsx index 041bf10ee8..7d64822822 100644 --- a/src/renderer/src/pages/video/VideoPage.tsx +++ b/src/renderer/src/pages/video/VideoPage.tsx @@ -31,6 +31,7 @@ export const VideoPage = () => { }, options: {} }) + const [activeVideoId, setActiveVideoId] = useState() const updateParams = useCallback((update: DeepPartial>) => { setParams((prev) => deepUpdate(prev, update)) @@ -64,10 +65,11 @@ export const VideoPage = () => { {provider.type === 'openai-response' && }
+ {/* TODO: pass video prop. retrieve correct video by swr */} {/* Video list */} - +
)