mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-02-09 03:37:45 +03:00
feat: added a Downloader helper to choose between real debrid and torrent when downloading
This commit is contained in:
parent
6bb22655e8
commit
666b1afcb6
@ -1,9 +1,10 @@
|
|||||||
import { gameRepository } from "@main/repository";
|
import { gameRepository } from "@main/repository";
|
||||||
|
|
||||||
import { registerEvent } from "../register-event";
|
import { registerEvent } from "../register-event";
|
||||||
import { WindowManager, writePipe } from "@main/services";
|
import { WindowManager } from "@main/services";
|
||||||
|
|
||||||
import { In } from "typeorm";
|
import { In } from "typeorm";
|
||||||
|
import { Downloader } from "@main/services/donwloaders/downloader";
|
||||||
import { GameStatus } from "@globals";
|
import { GameStatus } from "@globals";
|
||||||
|
|
||||||
const cancelGameDownload = async (
|
const cancelGameDownload = async (
|
||||||
@ -41,7 +42,7 @@ const cancelGameDownload = async (
|
|||||||
game.status !== GameStatus.Paused &&
|
game.status !== GameStatus.Paused &&
|
||||||
game.status !== GameStatus.Seeding
|
game.status !== GameStatus.Seeding
|
||||||
) {
|
) {
|
||||||
writePipe.write({ action: "cancel" });
|
Downloader.cancelDownload();
|
||||||
if (result.affected) WindowManager.mainWindow.setProgressBar(-1);
|
if (result.affected) WindowManager.mainWindow.setProgressBar(-1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { WindowManager, writePipe } from "@main/services";
|
import { WindowManager } from "@main/services";
|
||||||
|
|
||||||
import { registerEvent } from "../register-event";
|
import { registerEvent } from "../register-event";
|
||||||
import { gameRepository } from "../../repository";
|
import { gameRepository } from "../../repository";
|
||||||
import { In } from "typeorm";
|
import { In } from "typeorm";
|
||||||
|
import { Downloader } from "@main/services/donwloaders/downloader";
|
||||||
import { GameStatus } from "@globals";
|
import { GameStatus } from "@globals";
|
||||||
|
|
||||||
const pauseGameDownload = async (
|
const pauseGameDownload = async (
|
||||||
@ -23,7 +24,7 @@ const pauseGameDownload = async (
|
|||||||
)
|
)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
if (result.affected) {
|
if (result.affected) {
|
||||||
writePipe.write({ action: "pause" });
|
Downloader.pauseDownload();
|
||||||
WindowManager.mainWindow.setProgressBar(-1);
|
WindowManager.mainWindow.setProgressBar(-1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -2,7 +2,7 @@ import { registerEvent } from "../register-event";
|
|||||||
import { gameRepository } from "../../repository";
|
import { gameRepository } from "../../repository";
|
||||||
import { getDownloadsPath } from "../helpers/get-downloads-path";
|
import { getDownloadsPath } from "../helpers/get-downloads-path";
|
||||||
import { In } from "typeorm";
|
import { In } from "typeorm";
|
||||||
import { writePipe } from "@main/services";
|
import { Downloader } from "@main/services/donwloaders/downloader";
|
||||||
import { GameStatus } from "@globals";
|
import { GameStatus } from "@globals";
|
||||||
|
|
||||||
const resumeGameDownload = async (
|
const resumeGameDownload = async (
|
||||||
@ -18,17 +18,12 @@ const resumeGameDownload = async (
|
|||||||
|
|
||||||
if (!game) return;
|
if (!game) return;
|
||||||
|
|
||||||
writePipe.write({ action: "pause" });
|
Downloader.resumeDownload();
|
||||||
|
|
||||||
if (game.status === GameStatus.Paused) {
|
if (game.status === GameStatus.Paused) {
|
||||||
const downloadsPath = game.downloadPath ?? (await getDownloadsPath());
|
const downloadsPath = game.downloadPath ?? (await getDownloadsPath());
|
||||||
|
|
||||||
writePipe.write({
|
Downloader.downloadGame(game, game.repack);
|
||||||
action: "start",
|
|
||||||
game_id: gameId,
|
|
||||||
magnet: game.repack.magnet,
|
|
||||||
save_path: downloadsPath,
|
|
||||||
});
|
|
||||||
|
|
||||||
await gameRepository.update(
|
await gameRepository.update(
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,7 @@ import { registerEvent } from "../register-event";
|
|||||||
import type { GameShop } from "@types";
|
import type { GameShop } from "@types";
|
||||||
import { getImageBase64 } from "@main/helpers";
|
import { getImageBase64 } from "@main/helpers";
|
||||||
import { In } from "typeorm";
|
import { In } from "typeorm";
|
||||||
|
import { Downloader } from "@main/services/donwloaders/downloader";
|
||||||
import { GameStatus } from "@globals";
|
import { GameStatus } from "@globals";
|
||||||
|
|
||||||
const startGameDownload = async (
|
const startGameDownload = async (
|
||||||
@ -35,7 +36,7 @@ const startGameDownload = async (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
writePipe.write({ action: "pause" });
|
Downloader.pauseDownload();
|
||||||
|
|
||||||
await gameRepository.update(
|
await gameRepository.update(
|
||||||
{
|
{
|
||||||
@ -61,12 +62,7 @@ const startGameDownload = async (
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
writePipe.write({
|
Downloader.downloadGame(game, repack);
|
||||||
action: "start",
|
|
||||||
game_id: game.id,
|
|
||||||
magnet: repack.magnet,
|
|
||||||
save_path: downloadPath,
|
|
||||||
});
|
|
||||||
|
|
||||||
game.status = GameStatus.DownloadingMetadata;
|
game.status = GameStatus.DownloadingMetadata;
|
||||||
|
|
||||||
@ -84,12 +80,7 @@ const startGameDownload = async (
|
|||||||
repack: { id: repackId },
|
repack: { id: repackId },
|
||||||
});
|
});
|
||||||
|
|
||||||
writePipe.write({
|
Downloader.downloadGame(createdGame, repack);
|
||||||
action: "start",
|
|
||||||
game_id: createdGame.id,
|
|
||||||
magnet: repack.magnet,
|
|
||||||
save_path: downloadPath,
|
|
||||||
});
|
|
||||||
|
|
||||||
const { repack: _, ...rest } = createdGame;
|
const { repack: _, ...rest } = createdGame;
|
||||||
|
|
||||||
|
@ -17,11 +17,12 @@ import {
|
|||||||
steamGameRepository,
|
steamGameRepository,
|
||||||
userPreferencesRepository,
|
userPreferencesRepository,
|
||||||
} from "./repository";
|
} from "./repository";
|
||||||
import { TorrentClient } from "./services/torrent-client";
|
import { TorrentClient } from "./services/donwloaders/torrent-client";
|
||||||
import { Repack } from "./entity";
|
import { Repack } from "./entity";
|
||||||
import { Notification } from "electron";
|
import { Notification } from "electron";
|
||||||
import { t } from "i18next";
|
import { t } from "i18next";
|
||||||
import { In } from "typeorm";
|
import { In } from "typeorm";
|
||||||
|
import { Downloader } from "./services/donwloaders/downloader";
|
||||||
import { GameStatus } from "@globals";
|
import { GameStatus } from "@globals";
|
||||||
|
|
||||||
startProcessWatcher();
|
startProcessWatcher();
|
||||||
@ -41,12 +42,7 @@ Promise.all([writePipe.createPipe(), readPipe.createPipe()]).then(async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (game) {
|
if (game) {
|
||||||
writePipe.write({
|
Downloader.downloadGame(game, game.repack);
|
||||||
action: "start",
|
|
||||||
game_id: game.id,
|
|
||||||
magnet: game.repack.magnet,
|
|
||||||
save_path: game.downloadPath,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readPipe.socket.on("data", (data) => {
|
readPipe.socket.on("data", (data) => {
|
||||||
|
147
src/main/services/donwloaders/downloader.ts
Normal file
147
src/main/services/donwloaders/downloader.ts
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
import { Game, Repack } from "@main/entity";
|
||||||
|
import { writePipe } from "../fifo";
|
||||||
|
import { gameRepository, userPreferencesRepository } from "@main/repository";
|
||||||
|
import { RealDebridClient } from "./real-debrid";
|
||||||
|
import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity";
|
||||||
|
import { t } from "i18next";
|
||||||
|
import { Notification } from "electron";
|
||||||
|
import { WindowManager } from "../window-manager";
|
||||||
|
import { TorrentUpdate } from "./torrent-client";
|
||||||
|
import { HTTPDownloader } from "./http-downloader";
|
||||||
|
import { Unrar } from "../unrar";
|
||||||
|
import { GameStatus } from "@globals";
|
||||||
|
|
||||||
|
interface DownloadStatus {
|
||||||
|
numPeers: number;
|
||||||
|
numSeeds: number;
|
||||||
|
downloadSpeed: number;
|
||||||
|
timeRemaining: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Downloader {
|
||||||
|
private static lastHttpDownloader: HTTPDownloader | null = null;
|
||||||
|
|
||||||
|
static async usesRealDebrid() {
|
||||||
|
const userPreferences = await userPreferencesRepository.findOne({ where: { id: 1 } });
|
||||||
|
return userPreferences.realDebridApiToken !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async cancelDownload() {
|
||||||
|
if (!await this.usesRealDebrid()) {
|
||||||
|
writePipe.write({ action: "cancel" });
|
||||||
|
} else {
|
||||||
|
if (this.lastHttpDownloader) {
|
||||||
|
this.lastHttpDownloader.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async pauseDownload() {
|
||||||
|
if (!await this.usesRealDebrid()) {
|
||||||
|
writePipe.write({ action: "pause" });
|
||||||
|
} else {
|
||||||
|
if (this.lastHttpDownloader) {
|
||||||
|
this.lastHttpDownloader.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async resumeDownload() {
|
||||||
|
if (!await this.usesRealDebrid()) {
|
||||||
|
writePipe.write({ action: "pause" });
|
||||||
|
} else {
|
||||||
|
if (this.lastHttpDownloader) {
|
||||||
|
this.lastHttpDownloader.resume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async downloadGame(game: Game, repack: Repack) {
|
||||||
|
if (!await this.usesRealDebrid()) {
|
||||||
|
writePipe.write({
|
||||||
|
action: "start",
|
||||||
|
game_id: game.id,
|
||||||
|
magnet: repack.magnet,
|
||||||
|
save_path: game.downloadPath,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
const torrent = await RealDebridClient.addMagnet(repack.magnet);
|
||||||
|
if (torrent && torrent.id) {
|
||||||
|
await RealDebridClient.selectAllFiles(torrent.id);
|
||||||
|
const { links } = await RealDebridClient.getInfo(torrent.id);
|
||||||
|
const { download } = await RealDebridClient.unrestrictLink(links[0]);
|
||||||
|
this.lastHttpDownloader = new HTTPDownloader();
|
||||||
|
this.lastHttpDownloader.download(download, game.downloadPath, game.id);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async updateGameProgress(gameId: number, gameUpdate: QueryDeepPartialEntity<Game>, downloadStatus: DownloadStatus) {
|
||||||
|
await gameRepository.update({ id: gameId }, gameUpdate);
|
||||||
|
|
||||||
|
const game = await gameRepository.findOne({
|
||||||
|
where: { id: gameId },
|
||||||
|
relations: { repack: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (gameUpdate.progress === 1 && gameUpdate.status !== GameStatus.Decompressing) {
|
||||||
|
const userPreferences = await userPreferencesRepository.findOne({
|
||||||
|
where: { id: 1 },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (userPreferences?.downloadNotificationsEnabled) {
|
||||||
|
new Notification({
|
||||||
|
title: t("download_complete", {
|
||||||
|
ns: "notifications",
|
||||||
|
lng: userPreferences.language,
|
||||||
|
}),
|
||||||
|
body: t("game_ready_to_install", {
|
||||||
|
ns: "notifications",
|
||||||
|
lng: userPreferences.language,
|
||||||
|
title: game.title,
|
||||||
|
}),
|
||||||
|
}).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gameUpdate.decompressionProgress === 0 && gameUpdate.status === GameStatus.Decompressing) {
|
||||||
|
const unrar = await Unrar.fromFilePath(game.rarPath, game.downloadPath);
|
||||||
|
unrar.extract();
|
||||||
|
this.updateGameProgress(gameId, {
|
||||||
|
decompressionProgress: 1,
|
||||||
|
status: GameStatus.Finished,
|
||||||
|
}, downloadStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WindowManager.mainWindow) {
|
||||||
|
const progress = this.getGameProgress(game);
|
||||||
|
WindowManager.mainWindow.setProgressBar(progress === 1 ? -1 : progress);
|
||||||
|
|
||||||
|
WindowManager.mainWindow.webContents.send(
|
||||||
|
"on-download-progress",
|
||||||
|
JSON.parse(JSON.stringify({
|
||||||
|
...{
|
||||||
|
progress: gameUpdate.progress,
|
||||||
|
bytesDownloaded: gameUpdate.bytesDownloaded,
|
||||||
|
fileSize: gameUpdate.fileSize,
|
||||||
|
gameId,
|
||||||
|
numPeers: downloadStatus.numPeers,
|
||||||
|
numSeeds: downloadStatus.numSeeds,
|
||||||
|
downloadSpeed: downloadStatus.downloadSpeed,
|
||||||
|
timeRemaining: downloadStatus.timeRemaining,
|
||||||
|
} as TorrentUpdate, game
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getGameProgress(game: Game) {
|
||||||
|
if (game.status === GameStatus.CheckingFiles) return game.fileVerificationProgress;
|
||||||
|
if (game.status === GameStatus.Decompressing) return game.decompressionProgress;
|
||||||
|
return game.progress;
|
||||||
|
}
|
||||||
|
}
|
89
src/main/services/donwloaders/http-downloader.ts
Normal file
89
src/main/services/donwloaders/http-downloader.ts
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import { Game } from '@main/entity';
|
||||||
|
import { ElectronDownloadManager } from 'electron-dl-manager';
|
||||||
|
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
|
||||||
|
import { WindowManager } from '../window-manager';
|
||||||
|
import { Downloader } from './downloader';
|
||||||
|
import { GameStatus } from '@globals';
|
||||||
|
|
||||||
|
export class HTTPDownloader {
|
||||||
|
private downloadManager: ElectronDownloadManager;
|
||||||
|
private downloadId: string | null = null;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.downloadManager = new ElectronDownloadManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
async download(url: string, destination: string, gameId: number) {
|
||||||
|
const window = WindowManager.mainWindow;
|
||||||
|
|
||||||
|
this.downloadId = await this.downloadManager.download({
|
||||||
|
url,
|
||||||
|
window: window,
|
||||||
|
callbacks: {
|
||||||
|
onDownloadStarted: async (ev) => {
|
||||||
|
const updatePayload: QueryDeepPartialEntity<Game> = {
|
||||||
|
status: GameStatus.Downloading,
|
||||||
|
progress: 0,
|
||||||
|
bytesDownloaded: 0,
|
||||||
|
fileSize: ev.item.getTotalBytes(),
|
||||||
|
rarPath: `${destination}/.rd/${ev.resolvedFilename}`,
|
||||||
|
};
|
||||||
|
const downloadStatus = {
|
||||||
|
numPeers: 0,
|
||||||
|
numSeeds: 0,
|
||||||
|
downloadSpeed: 0,
|
||||||
|
timeRemaining: Number.POSITIVE_INFINITY,
|
||||||
|
};
|
||||||
|
await Downloader.updateGameProgress(gameId, updatePayload, downloadStatus);
|
||||||
|
},
|
||||||
|
onDownloadCompleted: async (ev) => {
|
||||||
|
const updatePayload: QueryDeepPartialEntity<Game> = {
|
||||||
|
progress: 1,
|
||||||
|
decompressionProgress: 0,
|
||||||
|
bytesDownloaded: ev.item.getReceivedBytes(),
|
||||||
|
status: GameStatus.Decompressing,
|
||||||
|
};
|
||||||
|
const downloadStatus = {
|
||||||
|
numPeers: 1,
|
||||||
|
numSeeds: 1,
|
||||||
|
downloadSpeed: 0,
|
||||||
|
timeRemaining: 0,
|
||||||
|
};
|
||||||
|
await Downloader.updateGameProgress(gameId, updatePayload, downloadStatus);
|
||||||
|
},
|
||||||
|
onDownloadProgress: async (ev) => {
|
||||||
|
const updatePayload: QueryDeepPartialEntity<Game> = {
|
||||||
|
progress: ev.percentCompleted / 100,
|
||||||
|
bytesDownloaded: ev.item.getReceivedBytes(),
|
||||||
|
};
|
||||||
|
const downloadStatus = {
|
||||||
|
numPeers: 1,
|
||||||
|
numSeeds: 1,
|
||||||
|
downloadSpeed: ev.downloadRateBytesPerSecond,
|
||||||
|
timeRemaining: ev.estimatedTimeRemainingSeconds,
|
||||||
|
};
|
||||||
|
await Downloader.updateGameProgress(gameId, updatePayload, downloadStatus);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
directory: `${destination}/.rd/`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pause() {
|
||||||
|
if (this.downloadId) {
|
||||||
|
this.downloadManager.pauseDownload(this.downloadId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel() {
|
||||||
|
if (this.downloadId) {
|
||||||
|
this.downloadManager.cancelDownload(this.downloadId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resume() {
|
||||||
|
if (this.downloadId) {
|
||||||
|
this.downloadManager.resumeDownload(this.downloadId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,13 +2,12 @@ import path from "node:path";
|
|||||||
import cp from "node:child_process";
|
import cp from "node:child_process";
|
||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import * as Sentry from "@sentry/electron/main";
|
import * as Sentry from "@sentry/electron/main";
|
||||||
import { Notification, app, dialog } from "electron";
|
import { app, dialog } from "electron";
|
||||||
import type { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity";
|
import type { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity";
|
||||||
|
|
||||||
import { Game } from "@main/entity";
|
import { Game } from "@main/entity";
|
||||||
import { gameRepository, userPreferencesRepository } from "@main/repository";
|
import { Downloader } from "./downloader";
|
||||||
import { t } from "i18next";
|
import { GameStatus } from "@globals";
|
||||||
import { WindowManager } from "./window-manager";
|
|
||||||
|
|
||||||
const binaryNameByPlatform: Partial<Record<NodeJS.Platform, string>> = {
|
const binaryNameByPlatform: Partial<Record<NodeJS.Platform, string>> = {
|
||||||
darwin: "hydra-download-manager",
|
darwin: "hydra-download-manager",
|
||||||
@ -75,6 +74,7 @@ export class TorrentClient {
|
|||||||
__dirname,
|
__dirname,
|
||||||
"..",
|
"..",
|
||||||
"..",
|
"..",
|
||||||
|
"..",
|
||||||
"torrent-client",
|
"torrent-client",
|
||||||
"main.py"
|
"main.py"
|
||||||
);
|
);
|
||||||
@ -85,20 +85,15 @@ export class TorrentClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static getTorrentStateName(state: TorrentState) {
|
private static getTorrentStateName(state: TorrentState) {
|
||||||
if (state === TorrentState.CheckingFiles) return "checking_files";
|
if (state === TorrentState.CheckingFiles) return GameStatus.CheckingFiles;
|
||||||
if (state === TorrentState.Downloading) return "downloading";
|
if (state === TorrentState.Downloading) return GameStatus.Downloading;
|
||||||
if (state === TorrentState.DownloadingMetadata)
|
if (state === TorrentState.DownloadingMetadata)
|
||||||
return "downloading_metadata";
|
return GameStatus.DownloadingMetadata;
|
||||||
if (state === TorrentState.Finished) return "finished";
|
if (state === TorrentState.Finished) return GameStatus.Finished;
|
||||||
if (state === TorrentState.Seeding) return "seeding";
|
if (state === TorrentState.Seeding) return GameStatus.Seeding;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static getGameProgress(game: Game) {
|
|
||||||
if (game.status === "checking_files") return game.fileVerificationProgress;
|
|
||||||
return game.progress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async onSocketData(data: Buffer) {
|
public static async onSocketData(data: Buffer) {
|
||||||
const message = Buffer.from(data).toString("utf-8");
|
const message = Buffer.from(data).toString("utf-8");
|
||||||
|
|
||||||
@ -127,44 +122,14 @@ export class TorrentClient {
|
|||||||
updatePayload.progress = payload.progress;
|
updatePayload.progress = payload.progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
await gameRepository.update({ id: payload.gameId }, updatePayload);
|
Downloader.updateGameProgress(payload.gameId, updatePayload, {
|
||||||
|
numPeers: payload.numPeers,
|
||||||
const game = await gameRepository.findOne({
|
numSeeds: payload.numSeeds,
|
||||||
where: { id: payload.gameId },
|
downloadSpeed: payload.downloadSpeed,
|
||||||
relations: { repack: true },
|
timeRemaining: payload.timeRemaining,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (game.progress === 1) {
|
|
||||||
const userPreferences = await userPreferencesRepository.findOne({
|
|
||||||
where: { id: 1 },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (userPreferences?.downloadNotificationsEnabled) {
|
|
||||||
new Notification({
|
|
||||||
title: t("download_complete", {
|
|
||||||
ns: "notifications",
|
|
||||||
lng: userPreferences.language,
|
|
||||||
}),
|
|
||||||
body: t("game_ready_to_install", {
|
|
||||||
ns: "notifications",
|
|
||||||
lng: userPreferences.language,
|
|
||||||
title: game.title,
|
|
||||||
}),
|
|
||||||
}).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (WindowManager.mainWindow) {
|
|
||||||
const progress = this.getGameProgress(game);
|
|
||||||
WindowManager.mainWindow.setProgressBar(progress === 1 ? -1 : progress);
|
|
||||||
|
|
||||||
WindowManager.mainWindow.webContents.send(
|
|
||||||
"on-download-progress",
|
|
||||||
JSON.parse(JSON.stringify({ ...payload, game }))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Sentry.captureException(err);
|
Sentry.captureException(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,6 +6,6 @@ export * from "./steam-grid";
|
|||||||
export * from "./update-resolver";
|
export * from "./update-resolver";
|
||||||
export * from "./window-manager";
|
export * from "./window-manager";
|
||||||
export * from "./fifo";
|
export * from "./fifo";
|
||||||
export * from "./torrent-client";
|
export * from "./donwloaders/torrent-client";
|
||||||
export * from "./how-long-to-beat";
|
export * from "./how-long-to-beat";
|
||||||
export * from "./process-watcher";
|
export * from "./process-watcher";
|
||||||
|
Loading…
Reference in New Issue
Block a user