mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-01-24 03:11:03 +00:00
Merge branch 'feature/add-download-sources' into feature/game-options-modal
This commit is contained in:
@@ -24,6 +24,9 @@ export class DownloadSource {
|
||||
@Column("text", { nullable: true })
|
||||
etag: string | null;
|
||||
|
||||
@Column("int", { default: 0 })
|
||||
downloadCount: number;
|
||||
|
||||
@Column("text", { default: DownloadSourceStatus.UpToDate })
|
||||
status: DownloadSourceStatus;
|
||||
|
||||
|
||||
@@ -18,7 +18,11 @@ const addDownloadSource = async (
|
||||
async (transactionalEntityManager) => {
|
||||
const downloadSource = await transactionalEntityManager
|
||||
.getRepository(DownloadSource)
|
||||
.save({ url, name: source.name });
|
||||
.save({
|
||||
url,
|
||||
name: source.name,
|
||||
downloadCount: source.downloads.length,
|
||||
});
|
||||
|
||||
await insertDownloadsFromSource(
|
||||
transactionalEntityManager,
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { registerEvent } from "../register-event";
|
||||
import { fetchDownloadSourcesAndUpdate } from "@main/helpers";
|
||||
|
||||
const syncDownloadSources = async (_event: Electron.IpcMainInvokeEvent) =>
|
||||
fetchDownloadSourcesAndUpdate();
|
||||
|
||||
registerEvent("syncDownloadSources", syncDownloadSources);
|
||||
@@ -37,6 +37,7 @@ import "./download-sources/get-download-sources";
|
||||
import "./download-sources/validate-download-source";
|
||||
import "./download-sources/add-download-source";
|
||||
import "./download-sources/remove-download-source";
|
||||
import "./download-sources/sync-download-sources";
|
||||
|
||||
ipcMain.handle("ping", () => "pong");
|
||||
ipcMain.handle("getVersion", () => app.getVersion());
|
||||
|
||||
@@ -52,19 +52,22 @@ export const fetchDownloadSourcesAndUpdate = async () => {
|
||||
|
||||
await dataSource.transaction(async (transactionalEntityManager) => {
|
||||
for (const result of results) {
|
||||
await transactionalEntityManager.getRepository(DownloadSource).update(
|
||||
{ id: result.id },
|
||||
{
|
||||
etag: result.etag,
|
||||
status: result.status,
|
||||
}
|
||||
);
|
||||
if (result.etag !== null) {
|
||||
await transactionalEntityManager.getRepository(DownloadSource).update(
|
||||
{ id: result.id },
|
||||
{
|
||||
etag: result.etag,
|
||||
status: result.status,
|
||||
downloadCount: result.downloads.length,
|
||||
}
|
||||
);
|
||||
|
||||
await insertDownloadsFromSource(
|
||||
transactionalEntityManager,
|
||||
result,
|
||||
result.downloads
|
||||
);
|
||||
await insertDownloadsFromSource(
|
||||
transactionalEntityManager,
|
||||
result,
|
||||
result.downloads
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
await RepacksManager.updateRepacks();
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
import { UserPreferences } from "./entity";
|
||||
import { RealDebridClient } from "./services/real-debrid";
|
||||
import { fetchDownloadSourcesAndUpdate } from "./helpers";
|
||||
import { publishNewRepacksNotifications } from "./services/notifications";
|
||||
|
||||
startMainLoop();
|
||||
|
||||
@@ -29,7 +30,9 @@ const loadState = async (userPreferences: UserPreferences | null) => {
|
||||
if (nextQueueItem?.game.status === "active")
|
||||
DownloadManager.startDownload(nextQueueItem.game);
|
||||
|
||||
fetchDownloadSourcesAndUpdate();
|
||||
fetchDownloadSourcesAndUpdate().then(() => {
|
||||
publishNewRepacksNotifications(300);
|
||||
});
|
||||
};
|
||||
|
||||
userPreferencesRepository
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
import Aria2, { StatusResponse } from "aria2";
|
||||
|
||||
import {
|
||||
downloadQueueRepository,
|
||||
gameRepository,
|
||||
userPreferencesRepository,
|
||||
} from "@main/repository";
|
||||
import { downloadQueueRepository, gameRepository } from "@main/repository";
|
||||
|
||||
import { WindowManager } from "./window-manager";
|
||||
import { RealDebridClient } from "./real-debrid";
|
||||
import { Notification } from "electron";
|
||||
import { t } from "i18next";
|
||||
|
||||
import { Downloader } from "@shared";
|
||||
import { DownloadProgress } from "@types";
|
||||
import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity";
|
||||
@@ -18,6 +13,7 @@ import { startAria2 } from "./aria2c";
|
||||
import { sleep } from "@main/helpers";
|
||||
import { logger } from "./logger";
|
||||
import type { ChildProcess } from "node:child_process";
|
||||
import { publishDownloadCompleteNotification } from "./notifications";
|
||||
|
||||
export class DownloadManager {
|
||||
private static downloads = new Map<number, string>();
|
||||
@@ -69,26 +65,6 @@ export class DownloadManager {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static async publishNotification() {
|
||||
const userPreferences = await userPreferencesRepository.findOne({
|
||||
where: { id: 1 },
|
||||
});
|
||||
|
||||
if (userPreferences?.downloadNotificationsEnabled && this.game) {
|
||||
new Notification({
|
||||
title: t("download_complete", {
|
||||
ns: "notifications",
|
||||
lng: userPreferences.language,
|
||||
}),
|
||||
body: t("game_ready_to_install", {
|
||||
ns: "notifications",
|
||||
lng: userPreferences.language,
|
||||
title: this.game.title,
|
||||
}),
|
||||
}).show();
|
||||
}
|
||||
}
|
||||
|
||||
private static getFolderName(status: StatusResponse) {
|
||||
if (status.bittorrent?.info) return status.bittorrent.info.name;
|
||||
return "";
|
||||
@@ -222,7 +198,7 @@ export class DownloadManager {
|
||||
}
|
||||
|
||||
if (progress === 1 && this.game && !isDownloadingMetadata) {
|
||||
await this.publishNotification();
|
||||
await publishDownloadCompleteNotification(this.game);
|
||||
|
||||
await downloadQueueRepository.delete({ game: this.game });
|
||||
|
||||
|
||||
44
src/main/services/notifications.ts
Normal file
44
src/main/services/notifications.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { Notification } from "electron";
|
||||
import { t } from "i18next";
|
||||
import { Game } from "@main/entity";
|
||||
import { userPreferencesRepository } from "@main/repository";
|
||||
|
||||
export const publishDownloadCompleteNotification = async (game: Game) => {
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
export const publishNewRepacksNotifications = async (count: number) => {
|
||||
const userPreferences = await userPreferencesRepository.findOne({
|
||||
where: { id: 1 },
|
||||
});
|
||||
|
||||
if (count > 0 && userPreferences?.repackUpdatesNotificationsEnabled) {
|
||||
new Notification({
|
||||
title: t("repack_list_updated", {
|
||||
ns: "notifications",
|
||||
lng: userPreferences?.language || "en",
|
||||
}),
|
||||
body: t("repack_count", {
|
||||
ns: "notifications",
|
||||
lng: userPreferences?.language || "en",
|
||||
count: count,
|
||||
}),
|
||||
}).show();
|
||||
}
|
||||
};
|
||||
@@ -38,6 +38,7 @@ export const getUpdatedRepacks = async (downloadSources: DownloadSource[]) => {
|
||||
results.push({
|
||||
...downloadSource,
|
||||
downloads: [],
|
||||
etag: null,
|
||||
status: isNotModified
|
||||
? DownloadSourceStatus.UpToDate
|
||||
: DownloadSourceStatus.Errored,
|
||||
|
||||
Reference in New Issue
Block a user