import prettyBytes from "pretty-bytes"; import React, { ReactElement, useEffect, useRef, useState } from "react"; import { useStore } from "../../store"; import type { Socket } from "socket.io-client"; import type { DownloadProgressTickProps } from "../../types"; /** * Shape of the download tick data received over the socket. */ type DownloadTickData = { id: number; name: string; downloaded_bytes: number; size: number; speed: number; seconds_left: number; status: { id: string; str: string; completed: boolean; downloaded: boolean; failed: boolean; hook_error: any; }; sources: { online: number; total: number; str: string; }; target: string; }; export const DownloadProgressTick: React.FC = ({ bundleId, }): ReactElement | null => { const socketRef = useRef(); const [tick, setTick] = useState(null); useEffect(() => { const socket = useStore.getState().getSocket("manual"); socketRef.current = socket; socket.emit("call", "socket.listenFileProgress", { namespace: "/manual", config: { protocol: `ws`, hostname: `192.168.1.119:5600`, username: `admin`, password: `password`, }, }); /** * Handler for each "downloadTick" event. * Only update state if event.id matches bundleId. * * @param {DownloadTickData} data - Payload from the server */ const onDownloadTick = (data: DownloadTickData) => { // Compare numeric data.id to string bundleId if (data.id === parseInt(bundleId, 10)) { setTick(data); } }; socket.on("downloadTick", onDownloadTick); return () => { socket.off("downloadTick", onDownloadTick); }; }, [socketRef, bundleId]); if (!tick) { return <>Nothing detected.; } // Compute human-readable values and percentages const downloaded = prettyBytes(tick.downloaded_bytes); const total = prettyBytes(tick.size); const percent = tick.size > 0 ? Math.round((tick.downloaded_bytes / tick.size) * 100) : 0; const speed = prettyBytes(tick.speed) + "/s"; const minutesLeft = Math.round(tick.seconds_left / 60); return (
{/* Downloaded vs Total */}
{downloaded} of {total}
{/* Progress bar */}
{percent}% complete
{/* Speed and Time Left */}
Speed: {speed} Time left: {minutesLeft} min
); }; export default DownloadProgressTick;