feat: display upload speed during seeding

This commit is contained in:
Hachi-R 2024-11-09 12:45:48 -03:00
parent 8ec52bf193
commit 56687948bf
6 changed files with 54 additions and 7 deletions

View File

@ -76,8 +76,6 @@ export class DownloadManager {
const seedStatus = await PythonInstance.getSeedStatus();
console.log(seedStatus);
if (seedStatus.length === 0) {
for (const game of gamesToSeed) {
if (game.uri && game.downloadPath) {
@ -102,6 +100,11 @@ export class DownloadManager {
{ status: "seeding" }
);
}
WindowManager.mainWindow?.webContents.send(
"on-seeding-status",
JSON.parse(JSON.stringify(seedStatus))
);
}
static async pauseSeeding(gameId: number) {

View File

@ -11,6 +11,7 @@ import type {
GameRunning,
FriendRequestAction,
UpdateProfileRequest,
SeedingStatus,
} from "@types";
import type { CatalogueCategory } from "@shared";
import type { AxiosProgressEvent } from "axios";
@ -38,6 +39,14 @@ contextBridge.exposeInMainWorld("electron", {
ipcRenderer.on("on-download-progress", listener);
return () => ipcRenderer.removeListener("on-download-progress", listener);
},
onSeedingStatus: (cb: (value: SeedingStatus[]) => void) => {
const listener = (
_event: Electron.IpcRendererEvent,
value: SeedingStatus[]
) => cb(value);
ipcRenderer.on("on-seeding-status", listener);
return () => ipcRenderer.removeListener("on-seeding-status", listener);
},
/* Catalogue */
searchGames: (query: string) => ipcRenderer.invoke("searchGames", query),

View File

@ -10,6 +10,7 @@ import type {
ShopDetails,
Steam250Game,
DownloadProgress,
SeedingStatus,
UserPreferences,
StartGameDownloadPayload,
RealDebridUser,
@ -51,6 +52,9 @@ declare global {
onDownloadProgress: (
cb: (value: DownloadProgress) => void
) => () => Electron.IpcRenderer;
onSeedingStatus: (
cb: (value: SeedingStatus[]) => void
) => () => Electron.IpcRenderer;
/* Catalogue */
searchGames: (query: string) => Promise<CatalogueEntry[]>;

View File

@ -1,6 +1,6 @@
import { useNavigate } from "react-router-dom";
import type { LibraryGame } from "@types";
import type { LibraryGame, SeedingStatus } from "@types";
import { Badge, Button } from "@renderer/components";
import {
@ -16,12 +16,14 @@ import * as styles from "./download-group.css";
import { useTranslation } from "react-i18next";
import { SPACING_UNIT, vars } from "@renderer/theme.css";
import { XCircleIcon } from "@primer/octicons-react";
import { useMemo } from "react";
export interface DownloadGroupProps {
library: LibraryGame[];
title: string;
openDeleteGameModal: (gameId: number) => void;
openGameInstaller: (gameId: number) => void;
seedingStatus: SeedingStatus[];
}
export function DownloadGroup({
@ -29,6 +31,7 @@ export function DownloadGroup({
title,
openDeleteGameModal,
openGameInstaller,
seedingStatus,
}: DownloadGroupProps) {
const navigate = useNavigate();
@ -60,9 +63,21 @@ export function DownloadGroup({
return "N/A";
};
const seedingMap = useMemo(() => {
if (!Array.isArray(seedingStatus) || seedingStatus.length === 0) {
return new Map<number, SeedingStatus>();
}
const map = new Map<number, SeedingStatus>();
seedingStatus.forEach((seed) => {
map.set(seed.gameId, seed);
});
return map;
}, [seedingStatus]);
const getGameInfo = (game: LibraryGame) => {
const isGameDownloading = lastPacket?.game.id === game.id;
const finalDownloadSize = getFinalDownloadSize(game);
const seedingStatus = seedingMap.get(game.id);
if (isGameDeleting(game.id)) {
return <p>{t("deleting")}</p>;
@ -101,10 +116,13 @@ export function DownloadGroup({
}
if (game.progress === 1) {
// return <p>{t("completed")}</p>;
const uploadSpeed = formatBytes(seedingStatus?.uploadSpeed ?? 0);
return game.status === "seeding" ? (
<p>{t("seeding")}</p>
<>
<p>{t("seeding")}</p>
{uploadSpeed && <p>{uploadSpeed}/s</p>}
</>
) : (
<p>{t("completed")}</p>
);

View File

@ -2,12 +2,12 @@ import { useTranslation } from "react-i18next";
import { useDownload, useLibrary } from "@renderer/hooks";
import { useMemo, useRef, useState } from "react";
import { useEffect, useMemo, useRef, useState } from "react";
import { BinaryNotFoundModal } from "../shared-modals/binary-not-found-modal";
import * as styles from "./downloads.css";
import { DeleteGameModal } from "./delete-game-modal";
import { DownloadGroup } from "./download-group";
import type { LibraryGame } from "@types";
import type { LibraryGame, SeedingStatus } from "@types";
import { orderBy } from "lodash-es";
import { ArrowDownIcon } from "@primer/octicons-react";
@ -30,6 +30,12 @@ export default function Downloads() {
const { lastPacket } = useDownload();
const [seedingStatus, setSeedingStatus] = useState<SeedingStatus[]>([]);
useEffect(() => {
window.electron.onSeedingStatus((value) => setSeedingStatus(value));
}, []);
const handleOpenGameInstaller = (gameId: number) =>
window.electron.openGameInstaller(gameId).then((isBinaryInPath) => {
if (!isBinaryInPath) setShowBinaryNotFoundModal(true);
@ -122,6 +128,7 @@ export default function Downloads() {
library={group.library}
openDeleteGameModal={handleOpenDeleteGameModal}
openGameInstaller={handleOpenGameInstaller}
seedingStatus={seedingStatus}
/>
))}
</div>

View File

@ -153,6 +153,12 @@ export interface DownloadProgress {
game: LibraryGame;
}
export interface SeedingStatus {
gameId: number;
status: GameStatus;
uploadSpeed: number;
}
export interface UserPreferences {
downloadsPath: string | null;
language: string;