retrieve all resource status

This commit is contained in:
PhilReact 2025-06-27 05:16:45 +03:00
parent cb00d03049
commit 8da43d1fa8
7 changed files with 96 additions and 7 deletions

View File

@ -83,6 +83,8 @@ export interface VideoPlayerProps {
playerRef: any; playerRef: any;
locationRef: RefObject<string | null>; locationRef: RefObject<string | null>;
videoLocationRef: RefObject<string | null>; videoLocationRef: RefObject<string | null>;
filename?:string
path?: string
} }
const videoStyles = { const videoStyles = {
@ -117,6 +119,8 @@ export const VideoPlayer = ({
timelineActions, timelineActions,
locationRef, locationRef,
videoLocationRef, videoLocationRef,
path,
filename
}: VideoPlayerProps) => { }: VideoPlayerProps) => {
const containerRef = useRef<HTMLDivElement | null>(null); const containerRef = useRef<HTMLDivElement | null>(null);
const [videoObjectFit] = useState<StretchVideoType>("contain"); const [videoObjectFit] = useState<StretchVideoType>("contain");
@ -178,6 +182,7 @@ export const VideoPlayer = ({
seekTo, seekTo,
togglePictureInPicture, togglePictureInPicture,
downloadResource, downloadResource,
} = useVideoPlayerController({ } = useVideoPlayerController({
autoPlay, autoPlay,
playerRef, playerRef,
@ -185,6 +190,8 @@ export const VideoPlayer = ({
retryAttempts, retryAttempts,
isMuted, isMuted,
videoRef, videoRef,
filename,
path
}); });
const showControlsMobile = const showControlsMobile =

View File

@ -14,6 +14,8 @@ export interface VideoPlayerParentProps {
autoPlay?: boolean; autoPlay?: boolean;
onEnded?: (e: React.SyntheticEvent<HTMLVideoElement, Event>) => void; onEnded?: (e: React.SyntheticEvent<HTMLVideoElement, Event>) => void;
timelineActions?: TimelineAction[]; timelineActions?: TimelineAction[];
path?: string
filename?: string
} }
export const VideoPlayerParent = ({ export const VideoPlayerParent = ({
videoRef, videoRef,
@ -23,6 +25,8 @@ export const VideoPlayerParent = ({
autoPlay, autoPlay,
onEnded, onEnded,
timelineActions, timelineActions,
path,
filename
}: VideoPlayerParentProps) => { }: VideoPlayerParentProps) => {
const context = useContext(GlobalContext) const context = useContext(GlobalContext)
const playerRef = useRef<Player | null>(null); const playerRef = useRef<Player | null>(null);
@ -91,6 +95,8 @@ export const VideoPlayerParent = ({
playerRef={playerRef} playerRef={playerRef}
locationRef={locationRef} locationRef={locationRef}
videoLocationRef={videoLocationRef} videoLocationRef={videoLocationRef}
filename={filename}
path={path}
/> />
); );
}; };

View File

@ -17,6 +17,8 @@ interface UseVideoControls {
retryAttempts?: number; retryAttempts?: number;
isMuted: boolean; isMuted: boolean;
videoRef: any; videoRef: any;
filename?: string
path?: string
} }
export const useVideoPlayerController = (props: UseVideoControls) => { export const useVideoPlayerController = (props: UseVideoControls) => {
@ -27,6 +29,8 @@ export const useVideoPlayerController = (props: UseVideoControls) => {
qortalVideoResource, qortalVideoResource,
retryAttempts, retryAttempts,
isMuted, isMuted,
filename = "",
path = ""
} = props; } = props;
const [isFullscreen, setIsFullscreen] = useState(false); const [isFullscreen, setIsFullscreen] = useState(false);
@ -43,6 +47,8 @@ export const useVideoPlayerController = (props: UseVideoControls) => {
useResourceStatus({ useResourceStatus({
resource: !startedFetch ? null : qortalVideoResource, resource: !startedFetch ? null : qortalVideoResource,
retryAttempts, retryAttempts,
filename,
path,
}); });
const idleTime = 5000; // Time in milliseconds const idleTime = 5000; // Time in milliseconds

View File

@ -0,0 +1,24 @@
import React from 'react'
import { usePublishStore } from '../state/publishes';
import { Service } from '../types/interfaces/resources';
export const useAllResourceStatus = () =>
usePublishStore((state) =>
Object.entries(state.resourceStatus)
.filter(([_, status]) => status !== null)
.map(([id, status]) => {
const parts = id.split('-');
const service = parts[0] as Service;
const name = parts[1] || '';
const identifier = parts.length > 2 ? parts.slice(2).join('-') : '';
const { path, filename, ...rest } = status!;
return {
id,
metadata: { service, name, identifier },
status: rest,
path,
filename
};
})
);

View File

@ -5,10 +5,14 @@ import { QortalGetMetadata } from "../types/interfaces/resources";
interface PropsUseResourceStatus { interface PropsUseResourceStatus {
resource: QortalGetMetadata | null; resource: QortalGetMetadata | null;
retryAttempts?: number; retryAttempts?: number;
path?: string
filename?:string
} }
export const useResourceStatus = ({ export const useResourceStatus = ({
resource, resource,
retryAttempts = 200, retryAttempts = 200,
path,
filename
}: PropsUseResourceStatus) => { }: PropsUseResourceStatus) => {
const resourceId = !resource ? null : `${resource.service}-${resource.name}-${resource.identifier}`; const resourceId = !resource ? null : `${resource.service}-${resource.name}-${resource.identifier}`;
const status = usePublishStore((state)=> state.getResourceStatus(resourceId)) || null const status = usePublishStore((state)=> state.getResourceStatus(resourceId)) || null
@ -41,7 +45,9 @@ export const useResourceStatus = ({
"status": "SEARCHING", "status": "SEARCHING",
"localChunkCount": 0, "localChunkCount": 0,
"totalChunkCount": 0, "totalChunkCount": 0,
"percentLoaded": 0 "percentLoaded": 0,
path: path || "",
filename: filename || ""
} }
); );
} }

View File

@ -8,6 +8,7 @@ export {TimelineAction} from './components/VideoPlayer/VideoPlayer'
export { useAudioPlayerHotkeys } from './components/AudioPlayer/useAudioPlayerHotkeys'; export { useAudioPlayerHotkeys } from './components/AudioPlayer/useAudioPlayerHotkeys';
export { VideoPlayerParent as VideoPlayer } from './components/VideoPlayer/VideoPlayerParent'; export { VideoPlayerParent as VideoPlayer } from './components/VideoPlayer/VideoPlayerParent';
export { useListReturn } from './hooks/useListData'; export { useListReturn } from './hooks/useListData';
export { useAllResourceStatus } from './hooks/useAllResourceStatus';
import './index.css' import './index.css'
export { executeEvent, subscribeToEvent, unsubscribeFromEvent } from './utils/events'; export { executeEvent, subscribeToEvent, unsubscribeFromEvent } from './utils/events';
export { formatBytes, formatDuration } from './utils/numbers'; export { formatBytes, formatDuration } from './utils/numbers';

View File

@ -1,5 +1,5 @@
import { create } from "zustand"; import { create } from "zustand";
import { QortalGetMetadata } from "../types/interfaces/resources"; import { QortalGetMetadata, Service } from "../types/interfaces/resources";
import { Resource } from "../hooks/useResources"; import { Resource } from "../hooks/useResources";
interface PublishCache { interface PublishCache {
@ -28,7 +28,15 @@ export interface ResourceStatus {
localChunkCount: number localChunkCount: number
totalChunkCount: number totalChunkCount: number
percentLoaded: number percentLoaded: number
path?: string
filename?: string
}
interface ResourceStatusEntry {
id: string;
metadata: QortalGetMetadata;
status: ResourceStatus;
path?: string;
filename?: string;
} }
interface PublishState { interface PublishState {
publishes: Record<string, PublishCache>; publishes: Record<string, PublishCache>;
@ -39,6 +47,8 @@ interface PublishState {
setPublish: (qortalGetMetadata: QortalGetMetadata, data: Resource | null, customExpiry?: number) => void; setPublish: (qortalGetMetadata: QortalGetMetadata, data: Resource | null, customExpiry?: number) => void;
clearExpiredPublishes: () => void; clearExpiredPublishes: () => void;
publishExpiryDuration: number; // Default expiry duration publishExpiryDuration: number; // Default expiry duration
getAllResourceStatus: () => ResourceStatusEntry[];
} }
export const usePublishStore = create<PublishState>((set, get) => ({ export const usePublishStore = create<PublishState>((set, get) => ({
@ -92,10 +102,13 @@ export const usePublishStore = create<PublishState>((set, get) => ({
})); }));
}, },
getResourceStatus: (resourceId) => { getResourceStatus: (resourceId) => {
if(!resourceId) return null; if (!resourceId) return null;
const status = get().resourceStatus[resourceId]; const status = get().resourceStatus[resourceId];
return status || null; if (!status) return null;
},
const { path, filename, ...rest } = status;
return rest;
},
clearExpiredPublishes: () => { clearExpiredPublishes: () => {
set((state) => { set((state) => {
const now = Date.now(); const now = Date.now();
@ -105,4 +118,30 @@ export const usePublishStore = create<PublishState>((set, get) => ({
return { publishes: updatedPublishes }; return { publishes: updatedPublishes };
}); });
}, },
getAllResourceStatus: () => {
const { resourceStatus } = get();
return Object.entries(resourceStatus)
.filter(([_, status]) => status !== null)
.map(([id, status]) => {
const parts = id.split('-');
const service = parts[0] as Service;
const name = parts[1] || '';
const identifier = parts.length > 2 ? parts.slice(2).join('-') : '';
const { path, filename, ...rest } = status!; // extract path from old ResourceStatus
return {
id,
metadata: {
service,
name,
identifier,
},
status: rest,
path,
filename
};
});
}
})); }));