From 42ea35441c232ad9e818f606c7745e69c48aa8eb Mon Sep 17 00:00:00 2001 From: Chubby Granny Chaser Date: Sun, 18 Aug 2024 01:39:50 +0100 Subject: [PATCH] fix: showing multiple download options --- src/locales/en/translation.json | 9 +- src/main/data-source.ts | 2 +- src/main/entity/repack.entity.ts | 10 ++- .../download-sources/get-download-sources.ts | 17 ++-- .../events/torrenting/start-game-download.ts | 7 +- src/main/helpers/download-source.ts | 2 +- src/main/services/hydra-api.ts | 86 +++++++++---------- src/main/services/repacks-manager.ts | 17 ++-- src/main/services/window-manager.ts | 2 + src/renderer/src/hooks/use-download.ts | 5 +- .../src/pages/game-details/game-details.tsx | 6 +- .../modals/download-settings-modal.tsx | 6 +- .../game-details/modals/repacks-modal.tsx | 11 ++- .../settings/settings-download-sources.css.ts | 7 -- .../settings/settings-download-sources.tsx | 9 -- src/shared/index.ts | 15 +++- src/types/index.ts | 5 ++ 17 files changed, 118 insertions(+), 98 deletions(-) diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 57511227..e2726b79 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -174,12 +174,9 @@ "validate_download_source": "Validate", "remove_download_source": "Remove", "add_download_source": "Add source", - "download_count_zero": "No downloads in list", - "download_count_one": "{{countFormatted}} download in list", - "download_count_other": "{{countFormatted}} downloads in list", - "download_options_zero": "No download available", - "download_options_one": "{{countFormatted}} download available", - "download_options_other": "{{countFormatted}} downloads available", + "download_count_zero": "No download options", + "download_count_one": "{{countFormatted}} download option", + "download_count_other": "{{countFormatted}} download options", "download_source_url": "Download source URL", "add_download_source_description": "Insert the URL containing the .json file", "download_source_up_to_date": "Up-to-date", diff --git a/src/main/data-source.ts b/src/main/data-source.ts index b47ce2c0..a88a8883 100644 --- a/src/main/data-source.ts +++ b/src/main/data-source.ts @@ -6,12 +6,12 @@ import { GameShopCache, Repack, UserPreferences, + UserAuth, } from "@main/entity"; import type { BetterSqlite3ConnectionOptions } from "typeorm/driver/better-sqlite3/BetterSqlite3ConnectionOptions"; import { databasePath } from "./constants"; import migrations from "./migrations"; -import { UserAuth } from "./entity/user-auth"; export const createDataSource = ( options: Partial diff --git a/src/main/entity/repack.entity.ts b/src/main/entity/repack.entity.ts index 1d5259fd..380d7b8c 100644 --- a/src/main/entity/repack.entity.ts +++ b/src/main/entity/repack.entity.ts @@ -16,11 +16,14 @@ export class Repack { @Column("text", { unique: true }) title: string; - @Column("text", { unique: true }) + /** + * @deprecated Use uris instead + */ + @Column("text", { unique: true, nullable: true }) magnet: string; /** - * @deprecated + * @deprecated Direct scraping capability has been removed */ @Column("int", { nullable: true }) page: number; @@ -37,6 +40,9 @@ export class Repack { @ManyToOne(() => DownloadSource, { nullable: true, onDelete: "CASCADE" }) downloadSource: DownloadSource; + @Column("text") + uris: string; + @CreateDateColumn() createdAt: Date; diff --git a/src/main/events/download-sources/get-download-sources.ts b/src/main/events/download-sources/get-download-sources.ts index 8f24caad..b8565645 100644 --- a/src/main/events/download-sources/get-download-sources.ts +++ b/src/main/events/download-sources/get-download-sources.ts @@ -1,16 +1,11 @@ import { downloadSourceRepository } from "@main/repository"; import { registerEvent } from "../register-event"; -const getDownloadSources = async (_event: Electron.IpcMainInvokeEvent) => { - return downloadSourceRepository - .createQueryBuilder("downloadSource") - .leftJoin("downloadSource.repacks", "repacks") - .orderBy("downloadSource.createdAt", "DESC") - .loadRelationCountAndMap( - "downloadSource.repackCount", - "downloadSource.repacks" - ) - .getMany(); -}; +const getDownloadSources = async (_event: Electron.IpcMainInvokeEvent) => + downloadSourceRepository.find({ + order: { + createdAt: "DESC", + }, + }); registerEvent("getDownloadSources", getDownloadSources); diff --git a/src/main/events/torrenting/start-game-download.ts b/src/main/events/torrenting/start-game-download.ts index cea41596..00978abc 100644 --- a/src/main/events/torrenting/start-game-download.ts +++ b/src/main/events/torrenting/start-game-download.ts @@ -18,7 +18,8 @@ const startGameDownload = async ( _event: Electron.IpcMainInvokeEvent, payload: StartGameDownloadPayload ) => { - const { repackId, objectID, title, shop, downloadPath, downloader } = payload; + const { repackId, objectID, title, shop, downloadPath, downloader, uri } = + payload; const [game, repack] = await Promise.all([ gameRepository.findOne({ @@ -54,7 +55,7 @@ const startGameDownload = async ( bytesDownloaded: 0, downloadPath, downloader, - uri: repack.magnet, + uri, isDeleted: false, } ); @@ -76,7 +77,7 @@ const startGameDownload = async ( shop, status: "active", downloadPath, - uri: repack.magnet, + uri, }) .then((result) => { if (iconUrl) { diff --git a/src/main/helpers/download-source.ts b/src/main/helpers/download-source.ts index 012a4d24..0b996fcc 100644 --- a/src/main/helpers/download-source.ts +++ b/src/main/helpers/download-source.ts @@ -17,7 +17,7 @@ export const insertDownloadsFromSource = async ( const repacks: QueryDeepPartialEntity[] = downloads.map( (download) => ({ title: download.title, - magnet: download.uris[0], + uris: JSON.stringify(download.uris), fileSize: download.fileSize, repacker: downloadSource.name, uploadDate: download.uploadDate, diff --git a/src/main/services/hydra-api.ts b/src/main/services/hydra-api.ts index 120d27ac..6f0e1905 100644 --- a/src/main/services/hydra-api.ts +++ b/src/main/services/hydra-api.ts @@ -77,54 +77,54 @@ export class HydraApi { baseURL: import.meta.env.MAIN_VITE_API_URL, }); - this.instance.interceptors.request.use( - (request) => { - logger.log(" ---- REQUEST -----"); - logger.log(request.method, request.url, request.params, request.data); - return request; - }, - (error) => { - logger.error("request error", error); - return Promise.reject(error); - } - ); + // this.instance.interceptors.request.use( + // (request) => { + // logger.log(" ---- REQUEST -----"); + // logger.log(request.method, request.url, request.params, request.data); + // return request; + // }, + // (error) => { + // logger.error("request error", error); + // return Promise.reject(error); + // } + // ); - this.instance.interceptors.response.use( - (response) => { - logger.log(" ---- RESPONSE -----"); - logger.log( - response.status, - response.config.method, - response.config.url, - response.data - ); - return response; - }, - (error) => { - logger.error(" ---- RESPONSE ERROR -----"); + // this.instance.interceptors.response.use( + // (response) => { + // logger.log(" ---- RESPONSE -----"); + // logger.log( + // response.status, + // response.config.method, + // response.config.url, + // response.data + // ); + // return response; + // }, + // (error) => { + // logger.error(" ---- RESPONSE ERROR -----"); - const { config } = error; + // const { config } = error; - logger.error( - config.method, - config.baseURL, - config.url, - config.headers, - config.data - ); + // logger.error( + // config.method, + // config.baseURL, + // config.url, + // config.headers, + // config.data + // ); - if (error.response) { - logger.error("Response", error.response.status, error.response.data); - } else if (error.request) { - logger.error("Request", error.request); - } else { - logger.error("Error", error.message); - } + // if (error.response) { + // logger.error("Response", error.response.status, error.response.data); + // } else if (error.request) { + // logger.error("Request", error.request); + // } else { + // logger.error("Error", error.message); + // } - logger.error(" ----- END RESPONSE ERROR -------"); - return Promise.reject(error); - } - ); + // logger.error(" ----- END RESPONSE ERROR -------"); + // return Promise.reject(error); + // } + // ); const userAuth = await userAuthRepository.findOne({ where: { id: 1 }, diff --git a/src/main/services/repacks-manager.ts b/src/main/services/repacks-manager.ts index 02821127..bfe4bc8a 100644 --- a/src/main/services/repacks-manager.ts +++ b/src/main/services/repacks-manager.ts @@ -8,11 +8,18 @@ export class RepacksManager { private static repacksIndex = new flexSearch.Index(); public static async updateRepacks() { - this.repacks = await repackRepository.find({ - order: { - createdAt: "DESC", - }, - }); + this.repacks = await repackRepository + .find({ + order: { + createdAt: "DESC", + }, + }) + .then((repacks) => + repacks.map((repack) => ({ + ...repack, + uris: JSON.parse(repack.uris), + })) + ); for (let i = 0; i < this.repacks.length; i++) { this.repacksIndex.remove(i); diff --git a/src/main/services/window-manager.ts b/src/main/services/window-manager.ts index 201b13ad..fcef12d6 100644 --- a/src/main/services/window-manager.ts +++ b/src/main/services/window-manager.ts @@ -64,6 +64,8 @@ export class WindowManager { this.loadURL(); this.mainWindow.removeMenu(); + WindowManager.mainWindow?.webContents.openDevTools(); + this.mainWindow.on("ready-to-show", () => { if (!app.isPackaged) WindowManager.mainWindow?.webContents.openDevTools(); WindowManager.mainWindow?.show(); diff --git a/src/renderer/src/hooks/use-download.ts b/src/renderer/src/hooks/use-download.ts index f58a8765..07c885cf 100644 --- a/src/renderer/src/hooks/use-download.ts +++ b/src/renderer/src/hooks/use-download.ts @@ -22,9 +22,10 @@ export function useDownload() { ); const dispatch = useAppDispatch(); - const startDownload = (payload: StartGameDownloadPayload) => { + const startDownload = async (payload: StartGameDownloadPayload) => { dispatch(clearDownload()); - window.electron.startGameDownload(payload).then((game) => { + + return window.electron.startGameDownload(payload).then((game) => { updateLibrary(); return game; diff --git a/src/renderer/src/pages/game-details/game-details.tsx b/src/renderer/src/pages/game-details/game-details.tsx index 5f32965a..5ac9673f 100644 --- a/src/renderer/src/pages/game-details/game-details.tsx +++ b/src/renderer/src/pages/game-details/game-details.tsx @@ -23,7 +23,7 @@ import { } from "@renderer/context"; import { useDownload } from "@renderer/hooks"; import { GameOptionsModal, RepacksModal } from "./modals"; -import { Downloader } from "@shared"; +import { Downloader, getDownloadersForUri } from "@shared"; export function GameDetails() { const [randomGame, setRandomGame] = useState(null); @@ -70,6 +70,9 @@ export function GameDetails() { } }; + const selectRepackUri = (repack: GameRepack, downloader: Downloader) => + repack.uris.find((uri) => getDownloadersForUri(uri).includes(downloader))!; + return ( @@ -96,6 +99,7 @@ export function GameDetails() { downloader, shop: shop as GameShop, downloadPath, + uri: selectRepackUri(repack, downloader), }); await updateGame(); diff --git a/src/renderer/src/pages/game-details/modals/download-settings-modal.tsx b/src/renderer/src/pages/game-details/modals/download-settings-modal.tsx index dff73ea0..3450af24 100644 --- a/src/renderer/src/pages/game-details/modals/download-settings-modal.tsx +++ b/src/renderer/src/pages/game-details/modals/download-settings-modal.tsx @@ -5,7 +5,7 @@ import { DiskSpace } from "check-disk-space"; import * as styles from "./download-settings-modal.css"; import { Button, Link, Modal, TextField } from "@renderer/components"; import { CheckCircleFillIcon, DownloadIcon } from "@primer/octicons-react"; -import { Downloader, formatBytes, getDownloadersForUri } from "@shared"; +import { Downloader, formatBytes, getDownloadersForUris } from "@shared"; import type { GameRepack } from "@types"; import { SPACING_UNIT } from "@renderer/theme.css"; @@ -48,8 +48,8 @@ export function DownloadSettingsModal({ }, [visible, selectedPath]); const downloaders = useMemo(() => { - return getDownloadersForUri(repack?.magnet ?? ""); - }, [repack?.magnet]); + return getDownloadersForUris(repack?.uris ?? []); + }, [repack?.uris]); useEffect(() => { if (userPreferences?.downloadsPath) { diff --git a/src/renderer/src/pages/game-details/modals/repacks-modal.tsx b/src/renderer/src/pages/game-details/modals/repacks-modal.tsx index f9d351af..0d1b9c1d 100644 --- a/src/renderer/src/pages/game-details/modals/repacks-modal.tsx +++ b/src/renderer/src/pages/game-details/modals/repacks-modal.tsx @@ -76,6 +76,13 @@ export function RepacksModal({ ); }; + const checkIfLastDownloadedOption = (repack: GameRepack) => { + if (infoHash) return repack.uris.some((uri) => uri.includes(infoHash)); + if (!game?.uri) return false; + + return repack.uris.some((uri) => uri.includes(game?.uri ?? "")); + }; + return ( <> {filteredRepacks.map((repack) => { - const isLastDownloadedOption = - infoHash !== null && - repack.magnet.toLowerCase().includes(infoHash); + const isLastDownloadedOption = checkIfLastDownloadedOption(repack); return (