From f54e583f34f0c2ce92755105f08b7069aea5a3b8 Mon Sep 17 00:00:00 2001 From: icarus Date: Mon, 13 Oct 2025 14:03:54 +0800 Subject: [PATCH] refactor(video): extract video status components and fix type names Extract inline video status rendering logic into separate components for better maintainability. Also fix inconsistent type naming (Videodownloaded -> VideoDownloaded, VideoFailed -> VideoFailedBase) and properly type VideoFailed as OpenAIVideoFailed. --- src/renderer/src/pages/video/VideoViewer.tsx | 185 +++++++++++-------- src/renderer/src/types/video.ts | 10 +- 2 files changed, 116 insertions(+), 79 deletions(-) diff --git a/src/renderer/src/pages/video/VideoViewer.tsx b/src/renderer/src/pages/video/VideoViewer.tsx index b9a5047aab..611456260c 100644 --- a/src/renderer/src/pages/video/VideoViewer.tsx +++ b/src/renderer/src/pages/video/VideoViewer.tsx @@ -9,9 +9,9 @@ import { Spinner, useDisclosure } from '@heroui/react' -import { Video } from '@renderer/types/video' +import { Video, VideoFailed } from '@renderer/types/video' import { CheckCircleIcon, CircleXIcon } from 'lucide-react' -import { useState } from 'react' +import { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' export interface VideoViewerProps { @@ -21,49 +21,14 @@ export interface VideoViewerProps { export const VideoViewer = ({ video }: VideoViewerProps) => { const { t } = useTranslation() const [loadSuccess, setLoadSuccess] = useState(undefined) - const { isOpen, onOpen, onClose } = useDisclosure() return ( <>
{video === undefined && t('video.undefined')} - {video && video.status === 'queued' && ( -
- - {t('video.status.queued')} -
- )} - {video && video.status === 'in_progress' && ( -
- -
- )} - {video && video.status === 'completed' && ( -
- - {t('video.status.completed')} -
- )} - {video && video.status === 'downloading' && ( -
- -
- )} + {video && video.status === 'queued' && } + {video && video.status === 'in_progress' && } + {video && video.status === 'completed' && } + {video && video.status === 'downloading' && } {video && video.status === 'downloaded' && loadSuccess !== false && ( )} - {video && video.status === 'failed' && ( -
- - {t('video.status.failed')} -
- - - - -
- {video.error === null ? ( - - ) : ( - - )} -
-
-
- -
- -
-
- )} - {video && video.status === 'downloaded' && loadSuccess === false && ( -
- - {t('video.error.load.message')} - {t('video.error.load.reason')} -
- -
-
- )} + {video && video.status === 'failed' && } + {video && video.status === 'downloaded' && loadSuccess === false && }
) } + +const QueuedVideo = () => { + const { t } = useTranslation() + return ( +
+ + {t('video.status.queued')} +
+ ) +} + +const InProgressVideo = ({ progress }: { progress: number }) => { + const { t } = useTranslation() + return ( +
+ +
+ ) +} + +const CompletedVideo = () => { + const { t } = useTranslation() + return ( +
+ + {t('video.status.completed')} +
+ ) +} + +const DownloadingVideo = ({ progress }: { progress?: number }) => { + const { t } = useTranslation() + return ( +
+ +
+ ) +} + +const FailedVideo = ({ error }: { error: VideoFailed['error'] }) => { + const { t } = useTranslation() + const { isOpen, onOpen, onClose } = useDisclosure() + + const alert = useMemo(() => { + if (error === null) { + return + } else { + return + } + }, [error, t]) + + return ( +
+ + {t('video.status.failed')} +
+ + + + +
{alert}
+
+
+ +
+ +
+
+ ) +} + +const LoadFailedVideo = ({ onRedownload }: { onRedownload?: () => void }) => { + const { t } = useTranslation() + return ( +
+ + {t('video.error.load.message')} + {t('video.error.load.reason')} +
+ +
+
+ ) +} diff --git a/src/renderer/src/types/video.ts b/src/renderer/src/types/video.ts index bb5417b8ff..1f8f420eba 100644 --- a/src/renderer/src/types/video.ts +++ b/src/renderer/src/types/video.ts @@ -49,14 +49,14 @@ export interface VideoDownloading extends VideoBase { /** integer percent */ progress: number } -export interface Videodownloaded extends VideoBase { +export interface VideoDownloaded extends VideoBase { status: 'downloaded' thumbnail: string /** Managed by fileManager */ fileId: string } -export interface VideoFailed extends VideoBase { +export interface VideoFailedBase extends VideoBase { status: 'failed' error: unknown } @@ -65,11 +65,13 @@ export interface OpenAIVideoQueued extends VideoQueued, OpenAIVideoBase {} export interface OpenAIVideoInProgress extends VideoInProgress, OpenAIVideoBase {} export interface OpenAIVideoCompleted extends VideoCompleted, OpenAIVideoBase {} export interface OpenAIVideoDownloading extends VideoDownloading, OpenAIVideoBase {} -export interface OpenAIVideoDownloaded extends Videodownloaded, OpenAIVideoBase {} -export interface OpenAIVideoFailed extends VideoFailed, OpenAIVideoBase { +export interface OpenAIVideoDownloaded extends VideoDownloaded, OpenAIVideoBase {} +export interface OpenAIVideoFailed extends VideoFailedBase, OpenAIVideoBase { error: OpenAI.Videos.Video['error'] } +export type VideoFailed = OpenAIVideoFailed + export type OpenAIVideo = | OpenAIVideoQueued | OpenAIVideoInProgress