mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-01-23 13:34:54 +03:00
feat: display upload speed during seeding
This commit is contained in:
parent
8ec52bf193
commit
56687948bf
@ -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) {
|
||||
|
@ -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),
|
||||
|
4
src/renderer/src/declaration.d.ts
vendored
4
src/renderer/src/declaration.d.ts
vendored
@ -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[]>;
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user