mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-03-09 15:40:26 +00:00
fix: fixing tsc errors
This commit is contained in:
parent
13743cd7a5
commit
c29f28dbdd
22 changed files with 79 additions and 100 deletions
|
@ -146,7 +146,8 @@
|
|||
"behavior": "Behavior",
|
||||
"enable_real_debrid": "Enable Real Debrid",
|
||||
"real_debrid": "Real Debrid",
|
||||
"real_debrid_api_token_hint": "You can get your API key <0>here</0>"
|
||||
"real_debrid_api_token_hint": "You can get your API key <0>here</0>.",
|
||||
"save_changes": "Save changes"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Download complete",
|
||||
|
|
|
@ -133,9 +133,14 @@
|
|||
"enable_repack_list_notifications": "Quando a lista de repacks for atualizada",
|
||||
"telemetry": "Telemetria",
|
||||
"telemetry_description": "Habilitar estatísticas de uso anônimas",
|
||||
"behavior": "Comportamento",
|
||||
"quit_app_instead_hiding": "Fechar o aplicativo em vez de minimizá-lo",
|
||||
"launch_with_system": "Iniciar aplicativo na inicialização do sistema"
|
||||
"launch_with_system": "Iniciar aplicativo na inicialização do sistema",
|
||||
"general": "Geral",
|
||||
"behavior": "Comportamento",
|
||||
"enable_real_debrid": "Habilitar Real Debrid",
|
||||
"real_debrid": "Real Debrid",
|
||||
"real_debrid_api_token_hint": "Você pode obter sua chave de API <0>aqui</0>.",
|
||||
"save_changes": "Salvar mudanças"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Download concluído",
|
||||
|
|
|
@ -41,7 +41,5 @@ export const databasePath = path.join(
|
|||
"hydra.db"
|
||||
);
|
||||
|
||||
console.log(databasePath);
|
||||
|
||||
export const INSTALLATION_ID_LENGTH = 6;
|
||||
export const ACTIVATION_KEY_MULTIPLIER = 7;
|
||||
|
|
|
@ -28,8 +28,8 @@ export const generateYML = (game: Game) => {
|
|||
{
|
||||
task: {
|
||||
executable: path.join(
|
||||
game.downloadPath,
|
||||
game.folderName,
|
||||
game.downloadPath!,
|
||||
game.folderName!,
|
||||
"setup.exe"
|
||||
),
|
||||
name: "wineexec",
|
||||
|
|
|
@ -21,7 +21,7 @@ const openGameInstaller = async (
|
|||
|
||||
const gamePath = path.join(
|
||||
game.downloadPath ?? (await getDownloadsPath()),
|
||||
game.folderName
|
||||
game.folderName!
|
||||
);
|
||||
|
||||
if (!fs.existsSync(gamePath)) {
|
||||
|
|
|
@ -38,12 +38,9 @@ export class RealDebridDownloader extends Downloader {
|
|||
|
||||
const updatePayload: QueryDeepPartialEntity<Game> = {
|
||||
status: GameStatus.Finished,
|
||||
progress: 1,
|
||||
};
|
||||
|
||||
await this.updateGameProgress(game.id, updatePayload, {
|
||||
timeRemaining: 0,
|
||||
});
|
||||
await this.updateGameProgress(game.id, updatePayload, {});
|
||||
}
|
||||
|
||||
static destroy() {
|
||||
|
@ -100,7 +97,7 @@ export class RealDebridDownloader extends Downloader {
|
|||
this.download.on("end", async () => {
|
||||
const updatePayload: QueryDeepPartialEntity<Game> = {
|
||||
status: GameStatus.Decompressing,
|
||||
progress: 0.99,
|
||||
progress: 1,
|
||||
};
|
||||
|
||||
await this.updateGameProgress(game.id, updatePayload, {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { Game } from "@main/entity";
|
||||
import type {
|
||||
RealDebridAddMagnet,
|
||||
RealDebridTorrentInfo,
|
||||
|
|
|
@ -33,9 +33,9 @@ const getTorrentDetails = async (path: string) => {
|
|||
|
||||
return {
|
||||
magnet: $a?.href,
|
||||
fileSize: $totalSize.querySelector("span").textContent ?? undefined,
|
||||
fileSize: $totalSize.querySelector("span")!.textContent,
|
||||
uploadDate: formatUploadDate(
|
||||
$dateUploaded.querySelector("span").textContent!
|
||||
$dateUploaded.querySelector("span")!.textContent!
|
||||
),
|
||||
};
|
||||
};
|
||||
|
@ -65,8 +65,7 @@ export const getTorrentListLastPage = async (user: string) => {
|
|||
export const extractTorrentsFromDocument = async (
|
||||
page: number,
|
||||
user: string,
|
||||
document: Document,
|
||||
existingRepacks: Repack[] = []
|
||||
document: Document
|
||||
) => {
|
||||
const $trs = Array.from(document.querySelectorAll("tbody tr"));
|
||||
|
||||
|
@ -78,24 +77,13 @@ export const extractTorrentsFromDocument = async (
|
|||
const url = $name.href;
|
||||
const title = $name.textContent ?? "";
|
||||
|
||||
if (existingRepacks.some((repack) => repack.title === title)) {
|
||||
return {
|
||||
title,
|
||||
magnet: "",
|
||||
fileSize: null,
|
||||
uploadDate: null,
|
||||
repacker: user,
|
||||
page,
|
||||
};
|
||||
}
|
||||
|
||||
const details = await getTorrentDetails(url);
|
||||
|
||||
return {
|
||||
title,
|
||||
magnet: details.magnet,
|
||||
fileSize: details.fileSize ?? null,
|
||||
uploadDate: details.uploadDate ?? null,
|
||||
fileSize: details.fileSize ?? "N/A",
|
||||
uploadDate: details.uploadDate ?? new Date(),
|
||||
repacker: user,
|
||||
page,
|
||||
};
|
||||
|
@ -114,13 +102,11 @@ export const getNewRepacksFromUser = async (
|
|||
const repacks = await extractTorrentsFromDocument(
|
||||
page,
|
||||
user,
|
||||
window.document,
|
||||
existingRepacks
|
||||
window.document
|
||||
);
|
||||
|
||||
const newRepacks = repacks.filter(
|
||||
(repack) =>
|
||||
repack.uploadDate &&
|
||||
!existingRepacks.some(
|
||||
(existingRepack) => existingRepack.title === repack.title
|
||||
)
|
||||
|
|
|
@ -4,6 +4,7 @@ import { Repack } from "@main/entity";
|
|||
|
||||
import { requestWebPage, savePage } from "./helpers";
|
||||
import { logger } from "../logger";
|
||||
import type { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity";
|
||||
|
||||
export const getNewRepacksFromCPG = async (
|
||||
existingRepacks: Repack[] = [],
|
||||
|
@ -13,11 +14,11 @@ export const getNewRepacksFromCPG = async (
|
|||
|
||||
const { window } = new JSDOM(data);
|
||||
|
||||
const repacks = [];
|
||||
const repacks: QueryDeepPartialEntity<Repack>[] = [];
|
||||
|
||||
try {
|
||||
Array.from(window.document.querySelectorAll(".post")).forEach(($post) => {
|
||||
const $title = $post.querySelector(".entry-title");
|
||||
const $title = $post.querySelector(".entry-title")!;
|
||||
const uploadDate = $post.querySelector("time")?.getAttribute("datetime");
|
||||
|
||||
const $downloadInfo = Array.from(
|
||||
|
@ -31,26 +32,25 @@ export const getNewRepacksFromCPG = async (
|
|||
$a.textContent?.startsWith("Magent")
|
||||
);
|
||||
|
||||
const fileSize = $downloadInfo.textContent
|
||||
const fileSize = ($downloadInfo?.textContent ?? "")
|
||||
.split("Download link => ")
|
||||
.at(1);
|
||||
|
||||
repacks.push({
|
||||
title: $title.textContent,
|
||||
title: $title.textContent!,
|
||||
fileSize: fileSize ?? "N/A",
|
||||
magnet: $magnet.href,
|
||||
magnet: $magnet!.href,
|
||||
repacker: "CPG",
|
||||
page,
|
||||
uploadDate: new Date(uploadDate),
|
||||
uploadDate: uploadDate ? new Date(uploadDate) : new Date(),
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
logger.error(err.message, { method: "getNewRepacksFromCPG" });
|
||||
} catch (err: unknown) {
|
||||
logger.error((err as Error).message, { method: "getNewRepacksFromCPG" });
|
||||
}
|
||||
|
||||
const newRepacks = repacks.filter(
|
||||
(repack) =>
|
||||
repack.uploadDate &&
|
||||
!existingRepacks.some(
|
||||
(existingRepack) => existingRepack.title === repack.title
|
||||
)
|
||||
|
|
|
@ -16,14 +16,14 @@ const getGOGGame = async (url: string) => {
|
|||
|
||||
const $em = window.document.querySelector(
|
||||
"p:not(.lightweight-accordion *) em"
|
||||
);
|
||||
const fileSize = $em.textContent.split("Size: ").at(1);
|
||||
)!;
|
||||
const fileSize = $em.textContent!.split("Size: ").at(1);
|
||||
const $downloadButton = window.document.querySelector(
|
||||
".download-btn:not(.lightweight-accordion *)"
|
||||
) as HTMLAnchorElement;
|
||||
|
||||
const { searchParams } = new URL($downloadButton.href);
|
||||
const magnet = Buffer.from(searchParams.get("url"), "base64").toString(
|
||||
const magnet = Buffer.from(searchParams.get("url")!, "base64").toString(
|
||||
"utf-8"
|
||||
);
|
||||
|
||||
|
@ -50,10 +50,10 @@ export const getNewGOGGames = async (existingRepacks: Repack[] = []) => {
|
|||
const $lis = Array.from($ul.querySelectorAll("li"));
|
||||
|
||||
for (const $li of $lis) {
|
||||
const $a = $li.querySelector("a");
|
||||
const $a = $li.querySelector("a")!;
|
||||
const href = $a.href;
|
||||
|
||||
const title = $a.textContent.trim();
|
||||
const title = $a.textContent!.trim();
|
||||
|
||||
const gameExists = existingRepacks.some(
|
||||
(existingRepack) => existingRepack.title === title
|
||||
|
|
|
@ -13,6 +13,9 @@ import { ru } from "date-fns/locale";
|
|||
import { onlinefixFormatter } from "@main/helpers";
|
||||
import makeFetchCookie from "fetch-cookie";
|
||||
import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity";
|
||||
import { formatBytes } from "@shared";
|
||||
|
||||
const ONLINE_FIX_URL = "https://online-fix.me/";
|
||||
|
||||
export const getNewRepacksFromOnlineFix = async (
|
||||
existingRepacks: Repack[] = [],
|
||||
|
@ -27,14 +30,14 @@ export const getNewRepacksFromOnlineFix = async (
|
|||
const http = makeFetchCookie(fetch, cookieJar);
|
||||
|
||||
if (page === 1) {
|
||||
await http("https://online-fix.me/");
|
||||
await http(ONLINE_FIX_URL);
|
||||
|
||||
const preLogin =
|
||||
((await http("https://online-fix.me/engine/ajax/authtoken.php", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
Referer: "https://online-fix.me/",
|
||||
Referer: ONLINE_FIX_URL,
|
||||
},
|
||||
}).then((res) => res.json())) as {
|
||||
field: string;
|
||||
|
@ -50,11 +53,11 @@ export const getNewRepacksFromOnlineFix = async (
|
|||
[preLogin.field]: preLogin.value,
|
||||
});
|
||||
|
||||
await http("https://online-fix.me/", {
|
||||
await http(ONLINE_FIX_URL, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Referer: "https://online-fix.me",
|
||||
Origin: "https://online-fix.me",
|
||||
Referer: ONLINE_FIX_URL,
|
||||
Origin: ONLINE_FIX_URL,
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: params.toString(),
|
||||
|
@ -149,13 +152,8 @@ export const getNewRepacksFromOnlineFix = async (
|
|||
const torrentSizeInBytes = torrent.length;
|
||||
if (!torrentSizeInBytes) return;
|
||||
|
||||
const fileSizeFormatted =
|
||||
torrentSizeInBytes >= 1024 ** 3
|
||||
? `${(torrentSizeInBytes / 1024 ** 3).toFixed(1)}GBs`
|
||||
: `${(torrentSizeInBytes / 1024 ** 2).toFixed(1)}MBs`;
|
||||
|
||||
repacks.push({
|
||||
fileSize: fileSizeFormatted,
|
||||
fileSize: formatBytes(torrentSizeInBytes),
|
||||
magnet: magnetLink,
|
||||
page: 1,
|
||||
repacker: "onlinefix",
|
||||
|
|
|
@ -7,6 +7,8 @@ import { requestWebPage, savePage } from "./helpers";
|
|||
import createWorker from "@main/workers/torrent-parser.worker?nodeWorker";
|
||||
import { toMagnetURI } from "parse-torrent";
|
||||
import type { Instance } from "parse-torrent";
|
||||
import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity";
|
||||
import { formatBytes } from "@shared";
|
||||
|
||||
const worker = createWorker({});
|
||||
|
||||
|
@ -23,10 +25,9 @@ const formatXatabDate = (str: string) => {
|
|||
return date;
|
||||
};
|
||||
|
||||
const formatXatabDownloadSize = (str: string) =>
|
||||
str.replace(",", ".").replace(/Гб/g, "GB").replace(/Мб/g, "MB");
|
||||
|
||||
const getXatabRepack = (url: string) => {
|
||||
const getXatabRepack = (
|
||||
url: string
|
||||
): Promise<{ fileSize: string; magnet: string; uploadDate: Date }> => {
|
||||
return new Promise((resolve) => {
|
||||
(async () => {
|
||||
const data = await requestWebPage(url);
|
||||
|
@ -34,7 +35,6 @@ const getXatabRepack = (url: string) => {
|
|||
const { document } = window;
|
||||
|
||||
const $uploadDate = document.querySelector(".entry__date");
|
||||
const $size = document.querySelector(".entry__info-size");
|
||||
|
||||
const $downloadButton = document.querySelector(
|
||||
".download-torrent"
|
||||
|
@ -42,17 +42,13 @@ const getXatabRepack = (url: string) => {
|
|||
|
||||
if (!$downloadButton) throw new Error("Download button not found");
|
||||
|
||||
const onMessage = (torrent: Instance) => {
|
||||
worker.once("message", (torrent: Instance) => {
|
||||
resolve({
|
||||
fileSize: formatXatabDownloadSize($size.textContent).toUpperCase(),
|
||||
fileSize: formatBytes(torrent.length ?? 0),
|
||||
magnet: toMagnetURI(torrent),
|
||||
uploadDate: formatXatabDate($uploadDate.textContent),
|
||||
uploadDate: formatXatabDate($uploadDate!.textContent!),
|
||||
});
|
||||
|
||||
worker.removeListener("message", onMessage);
|
||||
};
|
||||
|
||||
worker.once("message", onMessage);
|
||||
});
|
||||
})();
|
||||
});
|
||||
};
|
||||
|
@ -65,7 +61,7 @@ export const getNewRepacksFromXatab = async (
|
|||
|
||||
const { window } = new JSDOM(data);
|
||||
|
||||
const repacks = [];
|
||||
const repacks: QueryDeepPartialEntity<Repack>[] = [];
|
||||
|
||||
for (const $a of Array.from(
|
||||
window.document.querySelectorAll(".entry__title a")
|
||||
|
@ -74,7 +70,7 @@ export const getNewRepacksFromXatab = async (
|
|||
const repack = await getXatabRepack(($a as HTMLAnchorElement).href);
|
||||
|
||||
repacks.push({
|
||||
title: $a.textContent,
|
||||
title: $a.textContent!,
|
||||
repacker: "Xatab",
|
||||
...repack,
|
||||
page,
|
||||
|
|
|
@ -1 +1 @@
|
|||
<svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path d="M41.4193 7.30899C41.4193 7.30899 45.3046 5.79399 44.9808 9.47328C44.8729 10.9883 43.9016 16.2908 43.1461 22.0262L40.5559 39.0159C40.5559 39.0159 40.3401 41.5048 38.3974 41.9377C36.4547 42.3705 33.5408 40.4227 33.0011 39.9898C32.5694 39.6652 24.9068 34.7955 22.2086 32.4148C21.4531 31.7655 20.5897 30.4669 22.3165 28.9519L33.6487 18.1305C34.9438 16.8319 36.2389 13.8019 30.8426 17.4812L15.7331 27.7616C15.7331 27.7616 14.0063 28.8437 10.7686 27.8698L3.75342 25.7055C3.75342 25.7055 1.16321 24.0823 5.58815 22.459C16.3807 17.3729 29.6555 12.1786 41.4193 7.30899Z" fill="#6f7279"></path> </g></svg>
|
||||
<svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path d="M41.4193 7.30899C41.4193 7.30899 45.3046 5.79399 44.9808 9.47328C44.8729 10.9883 43.9016 16.2908 43.1461 22.0262L40.5559 39.0159C40.5559 39.0159 40.3401 41.5048 38.3974 41.9377C36.4547 42.3705 33.5408 40.4227 33.0011 39.9898C32.5694 39.6652 24.9068 34.7955 22.2086 32.4148C21.4531 31.7655 20.5897 30.4669 22.3165 28.9519L33.6487 18.1305C34.9438 16.8319 36.2389 13.8019 30.8426 17.4812L15.7331 27.7616C15.7331 27.7616 14.0063 28.8437 10.7686 27.8698L3.75342 25.7055C3.75342 25.7055 1.16321 24.0823 5.58815 22.459C16.3807 17.3729 29.6555 12.1786 41.4193 7.30899Z" fill="currentColor"></path> </g></svg>
|
Before Width: | Height: | Size: 833 B After Width: | Height: | Size: 838 B |
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,256,256" width="16px" height="16px"><g fill="#8e919b" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><g transform="scale(5.12,5.12)"><path d="M5.91992,6l14.66211,21.375l-14.35156,16.625h3.17969l12.57617,-14.57812l10,14.57813h12.01367l-15.31836,-22.33008l13.51758,-15.66992h-3.16992l-11.75391,13.61719l-9.3418,-13.61719zM9.7168,8h7.16406l23.32227,34h-7.16406z"></path></g></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,256,256" width="16px" height="16px"><g fill="currentColor" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><g transform="scale(5.12,5.12)"><path d="M5.91992,6l14.66211,21.375l-14.35156,16.625h3.17969l12.57617,-14.57812l10,14.57813h12.01367l-15.31836,-22.33008l13.51758,-15.66992h-3.16992l-11.75391,13.61719l-9.3418,-13.61719zM9.7168,8h7.16406l23.32227,34h-7.16406z"></path></g></g></svg>
|
Before Width: | Height: | Size: 697 B After Width: | Height: | Size: 702 B |
|
@ -11,8 +11,7 @@ import {
|
|||
} from "@renderer/features";
|
||||
import type { GameShop, TorrentProgress } from "@types";
|
||||
import { useDate } from "./use-date";
|
||||
import { formatBytes } from "@renderer/utils";
|
||||
import { GameStatus, GameStatusHelper } from "@shared";
|
||||
import { GameStatus, GameStatusHelper, formatBytes } from "@shared";
|
||||
|
||||
export function useDownload() {
|
||||
const { updateLibrary } = useLibrary();
|
||||
|
|
|
@ -10,8 +10,7 @@ import { useEffect, useMemo, useRef, useState } from "react";
|
|||
import { BinaryNotFoundModal } from "../shared-modals/binary-not-found-modal";
|
||||
import * as styles from "./downloads.css";
|
||||
import { DeleteModal } from "./delete-modal";
|
||||
import { formatBytes } from "@renderer/utils";
|
||||
import { Downloader, GameStatus, GameStatusHelper } from "@shared";
|
||||
import { Downloader, GameStatus, GameStatusHelper, formatBytes } from "@shared";
|
||||
|
||||
export function Downloads() {
|
||||
const { library, updateLibrary } = useLibrary();
|
||||
|
|
|
@ -6,9 +6,8 @@ import { useDownload } from "@renderer/hooks";
|
|||
import type { Game, ShopDetails } from "@types";
|
||||
|
||||
import { formatDownloadProgress } from "@renderer/helpers";
|
||||
import { formatBytes } from "@renderer/utils";
|
||||
import { HeroPanelActions } from "./hero-panel-actions";
|
||||
import { Downloader, GameStatus, GameStatusHelper } from "@shared";
|
||||
import { Downloader, GameStatus, GameStatusHelper, formatBytes } from "@shared";
|
||||
|
||||
import { BinaryNotFoundModal } from "../../shared-modals/binary-not-found-modal";
|
||||
import * as styles from "./hero-panel.css";
|
||||
|
|
|
@ -3,10 +3,10 @@ import { GameRepack, ShopDetails } from "@types";
|
|||
import { useEffect, useState } from "react";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
|
||||
import { formatBytes } from "@renderer/utils";
|
||||
import { DiskSpace } from "check-disk-space";
|
||||
import * as styles from "./select-folder-modal.css";
|
||||
import { DownloadIcon } from "@primer/octicons-react";
|
||||
import { formatBytes } from "@shared";
|
||||
|
||||
export interface SelectFolderModalProps {
|
||||
visible: boolean;
|
||||
|
@ -74,7 +74,7 @@ export function SelectFolderModal({
|
|||
return (
|
||||
<Modal
|
||||
visible={visible}
|
||||
title={`${gameDetails.name} Installation folder`}
|
||||
title={t("installation_folder", { name: gameDetails.name })}
|
||||
description={t("space_left_on_disk", {
|
||||
space: formatBytes(diskFreeSpace?.free ?? 0),
|
||||
})}
|
||||
|
|
|
@ -78,7 +78,7 @@ export function SettingsRealDebrid({
|
|||
style={{ alignSelf: "flex-end" }}
|
||||
disabled={isButtonDisabled}
|
||||
>
|
||||
Save changes
|
||||
{t("save_changes")}
|
||||
</Button>
|
||||
</form>
|
||||
);
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
const FORMAT = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
||||
|
||||
export const formatBytes = (bytes: number): string => {
|
||||
if (!Number.isFinite(bytes) || isNaN(bytes) || bytes <= 0) {
|
||||
return `0 ${FORMAT[0]}`;
|
||||
}
|
||||
|
||||
const byteKBase = 1024;
|
||||
|
||||
const base = Math.floor(Math.log(bytes) / Math.log(byteKBase));
|
||||
|
||||
const formatedByte = bytes / byteKBase ** base;
|
||||
|
||||
return `${Math.trunc(formatedByte * 10) / 10} ${FORMAT[base]}`;
|
||||
};
|
|
@ -1 +0,0 @@
|
|||
export * from "./format-bytes";
|
|
@ -14,6 +14,22 @@ export enum Downloader {
|
|||
Torrent,
|
||||
}
|
||||
|
||||
const FORMAT = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
||||
|
||||
export const formatBytes = (bytes: number): string => {
|
||||
if (!Number.isFinite(bytes) || isNaN(bytes) || bytes <= 0) {
|
||||
return `0 ${FORMAT[0]}`;
|
||||
}
|
||||
|
||||
const byteKBase = 1024;
|
||||
|
||||
const base = Math.floor(Math.log(bytes) / Math.log(byteKBase));
|
||||
|
||||
const formatedByte = bytes / byteKBase ** base;
|
||||
|
||||
return `${Math.trunc(formatedByte * 10) / 10} ${FORMAT[base]}`;
|
||||
};
|
||||
|
||||
export class GameStatusHelper {
|
||||
public static isDownloading(status: GameStatus | null) {
|
||||
return (
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue