fix: showing multiple download options

This commit is contained in:
Chubby Granny Chaser 2024-08-18 01:39:50 +01:00
parent c218070463
commit 42ea35441c
No known key found for this signature in database
17 changed files with 118 additions and 98 deletions

View File

@ -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",

View File

@ -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<BetterSqlite3ConnectionOptions>

View File

@ -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;

View File

@ -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);

View File

@ -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) {

View File

@ -17,7 +17,7 @@ export const insertDownloadsFromSource = async (
const repacks: QueryDeepPartialEntity<Repack>[] = downloads.map(
(download) => ({
title: download.title,
magnet: download.uris[0],
uris: JSON.stringify(download.uris),
fileSize: download.fileSize,
repacker: downloadSource.name,
uploadDate: download.uploadDate,

View File

@ -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 },

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -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<Steam250Game | null>(null);
@ -70,6 +70,9 @@ export function GameDetails() {
}
};
const selectRepackUri = (repack: GameRepack, downloader: Downloader) =>
repack.uris.find((uri) => getDownloadersForUri(uri).includes(downloader))!;
return (
<GameDetailsContextProvider>
<GameDetailsContextConsumer>
@ -96,6 +99,7 @@ export function GameDetails() {
downloader,
shop: shop as GameShop,
downloadPath,
uri: selectRepackUri(repack, downloader),
});
await updateGame();

View File

@ -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) {

View File

@ -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 (
<>
<DownloadSettingsModal
@ -97,9 +104,7 @@ export function RepacksModal({
<div className={styles.repacks}>
{filteredRepacks.map((repack) => {
const isLastDownloadedOption =
infoHash !== null &&
repack.magnet.toLowerCase().includes(infoHash);
const isLastDownloadedOption = checkIfLastDownloadedOption(repack);
return (
<Button

View File

@ -42,10 +42,3 @@ export const downloadSourcesHeader = style({
justifyContent: "space-between",
alignItems: "center",
});
export const separator = style({
height: "100%",
width: "1px",
backgroundColor: vars.color.border,
margin: `${SPACING_UNIT}px 0`,
});

View File

@ -134,15 +134,6 @@ export function SettingsDownloadSources() {
downloadSource.downloadCount.toLocaleString(),
})}
</small>
<div className={styles.separator} />
<small>
{t("download_options", {
count: downloadSource.repackCount,
countFormatted: downloadSource.repackCount.toLocaleString(),
})}
</small>
</div>
</div>

View File

@ -73,13 +73,26 @@ const realDebridHosts = ["https://1fichier.com", "https://mediafire.com"];
export const getDownloadersForUri = (uri: string) => {
if (uri.startsWith("https://gofile.io")) return [Downloader.Gofile];
if (uri.startsWith("https://pixeldrain.com")) return [Downloader.PixelDrain];
if (realDebridHosts.some((host) => uri.startsWith(host)))
return [Downloader.RealDebrid];
if (uri.startsWith("magnet:"))
if (uri.startsWith("magnet:")) {
return [Downloader.Torrent, Downloader.RealDebrid];
}
return [];
};
export const getDownloadersForUris = (uris: string[]) => {
const downloadersSet = uris.reduce<Set<Downloader>>((prev, next) => {
const downloaders = getDownloadersForUri(next);
downloaders.forEach((downloader) => prev.add(downloader));
return prev;
}, new Set());
return Array.from(downloadersSet);
};

View File

@ -67,7 +67,11 @@ export interface SteamAppDetails {
export interface GameRepack {
id: number;
title: string;
/**
* @deprecated Use uris instead
*/
magnet: string;
uris: string[];
repacker: string;
fileSize: string | null;
uploadDate: Date | string | null;
@ -194,6 +198,7 @@ export interface StartGameDownloadPayload {
objectID: string;
title: string;
shop: GameShop;
uri: string;
downloadPath: string;
downloader: Downloader;
}