From c20394f460cf7b4dc300ee9e36aa3eb8a5dae8fb Mon Sep 17 00:00:00 2001 From: icarus Date: Mon, 13 Oct 2025 15:23:48 +0800 Subject: [PATCH] feat(video): add VideoPlayer component with file loading Implement VideoPlayer component that fetches video file path using FileManager and displays it with loading skeleton. This improves video loading reliability by handling file existence checks and error states. --- src/renderer/src/pages/video/VideoViewer.tsx | 46 ++++++++++++++++---- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/src/renderer/src/pages/video/VideoViewer.tsx b/src/renderer/src/pages/video/VideoViewer.tsx index cc40fe3386..8f8624dd6c 100644 --- a/src/renderer/src/pages/video/VideoViewer.tsx +++ b/src/renderer/src/pages/video/VideoViewer.tsx @@ -6,14 +6,17 @@ import { ModalContent, ModalFooter, Progress, + Skeleton, Spinner, useDisclosure } from '@heroui/react' -import { Video, VideoFailed } from '@renderer/types/video' +import FileManager from '@renderer/services/FileManager' +import { Video, VideoDownloaded, VideoFailed } from '@renderer/types/video' import dayjs from 'dayjs' import { CheckCircleIcon, CircleXIcon, Clock9Icon } from 'lucide-react' import { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' +import useSWRImmutable from 'swr/immutable' export type VideoViewerProps = | { @@ -41,13 +44,7 @@ export const VideoViewer = ({ video, onDownload, onRegenerate }: VideoViewerProp )} {video && video.status === 'downloading' && } {video && video.status === 'downloaded' && loadSuccess !== false && ( - + )} {video && video.status === 'failed' && } {video && video.status === 'downloaded' && loadSuccess === false && ( @@ -176,3 +173,36 @@ const LoadFailedVideo = ({ onRedownload }: { onRedownload: () => void }) => { ) } + +const VideoPlayer = ({ + video, + setLoadSuccess +}: { + video: VideoDownloaded + setLoadSuccess: (value: boolean) => void +}) => { + const fetcher = async () => { + const file = await FileManager.getFile(video.fileId) + if (!file) { + throw new Error(`Video file ${video.fileId} not exist.`) + } + return FileManager.getFilePath(file) + } + const { data: src, isLoading, error } = useSWRImmutable(`video/file/${video.id}`, fetcher) + + if (error) { + setLoadSuccess(false) + } + + return ( + + + + ) +}