mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-03-09 15:40:26 +00:00
chore: disabling resuming real debrid downloads when real debrid is not set
This commit is contained in:
parent
a34a774fb7
commit
50c3503e37
4 changed files with 264 additions and 0 deletions
10
src/renderer/src/pages/downloads/delete-game-modal.css.ts
Normal file
10
src/renderer/src/pages/downloads/delete-game-modal.css.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import { SPACING_UNIT } from "../../theme.css";
|
||||||
|
import { style } from "@vanilla-extract/css";
|
||||||
|
|
||||||
|
export const deleteActionsButtonsCtn = style({
|
||||||
|
display: "flex",
|
||||||
|
width: "100%",
|
||||||
|
justifyContent: "end",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: `${SPACING_UNIT}px`,
|
||||||
|
});
|
43
src/renderer/src/pages/downloads/delete-game-modal.tsx
Normal file
43
src/renderer/src/pages/downloads/delete-game-modal.tsx
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { Button, Modal } from "@renderer/components";
|
||||||
|
|
||||||
|
import * as styles from "./delete-game-modal.css";
|
||||||
|
|
||||||
|
interface DeleteGameModalProps {
|
||||||
|
visible: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
deleteGame: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DeleteGameModal({
|
||||||
|
onClose,
|
||||||
|
visible,
|
||||||
|
deleteGame,
|
||||||
|
}: DeleteGameModalProps) {
|
||||||
|
const { t } = useTranslation("downloads");
|
||||||
|
|
||||||
|
const handleDeleteGame = () => {
|
||||||
|
deleteGame();
|
||||||
|
onClose();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
visible={visible}
|
||||||
|
title={t("delete_modal_title")}
|
||||||
|
description={t("delete_modal_description")}
|
||||||
|
onClose={onClose}
|
||||||
|
>
|
||||||
|
<div className={styles.deleteActionsButtonsCtn}>
|
||||||
|
<Button onClick={handleDeleteGame} theme="outline">
|
||||||
|
{t("delete")}
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button onClick={onClose} theme="primary">
|
||||||
|
{t("cancel")}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
import { style } from "@vanilla-extract/css";
|
||||||
|
import { SPACING_UNIT, vars } from "../../../theme.css";
|
||||||
|
|
||||||
|
export const container = style({
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
gap: `${SPACING_UNIT * 3}px`,
|
||||||
|
width: "100%",
|
||||||
|
});
|
||||||
|
|
||||||
|
export const downloadsPathField = style({
|
||||||
|
display: "flex",
|
||||||
|
gap: `${SPACING_UNIT}px`,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const hintText = style({
|
||||||
|
fontSize: "12px",
|
||||||
|
color: vars.color.body,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const downloaders = style({
|
||||||
|
display: "flex",
|
||||||
|
gap: `${SPACING_UNIT}px`,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const downloaderOption = style({
|
||||||
|
flex: "1",
|
||||||
|
position: "relative",
|
||||||
|
});
|
||||||
|
|
||||||
|
export const downloaderIcon = style({
|
||||||
|
position: "absolute",
|
||||||
|
left: `${SPACING_UNIT * 2}px`,
|
||||||
|
});
|
|
@ -0,0 +1,177 @@
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { Trans, useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
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 } from "@shared";
|
||||||
|
|
||||||
|
import type { GameRepack } from "@types";
|
||||||
|
import { SPACING_UNIT } from "@renderer/theme.css";
|
||||||
|
import { DOWNLOADER_NAME } from "@renderer/constants";
|
||||||
|
import { useAppSelector } from "@renderer/hooks";
|
||||||
|
|
||||||
|
export interface DownloadSettingsModalProps {
|
||||||
|
visible: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
startDownload: (
|
||||||
|
repack: GameRepack,
|
||||||
|
downloader: Downloader,
|
||||||
|
downloadPath: string
|
||||||
|
) => Promise<void>;
|
||||||
|
repack: GameRepack | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const downloaders = [Downloader.Torrent, Downloader.RealDebrid];
|
||||||
|
|
||||||
|
export function DownloadSettingsModal({
|
||||||
|
visible,
|
||||||
|
onClose,
|
||||||
|
startDownload,
|
||||||
|
repack,
|
||||||
|
}: DownloadSettingsModalProps) {
|
||||||
|
const { t } = useTranslation("game_details");
|
||||||
|
|
||||||
|
const [diskFreeSpace, setDiskFreeSpace] = useState<DiskSpace | null>(null);
|
||||||
|
const [selectedPath, setSelectedPath] = useState("");
|
||||||
|
const [downloadStarting, setDownloadStarting] = useState(false);
|
||||||
|
const [selectedDownloader, setSelectedDownloader] = useState(
|
||||||
|
Downloader.Torrent
|
||||||
|
);
|
||||||
|
|
||||||
|
const userPreferences = useAppSelector(
|
||||||
|
(state) => state.userPreferences.value
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (visible) {
|
||||||
|
getDiskFreeSpace(selectedPath);
|
||||||
|
}
|
||||||
|
}, [visible, selectedPath]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (userPreferences?.downloadsPath) {
|
||||||
|
setSelectedPath(userPreferences.downloadsPath);
|
||||||
|
} else {
|
||||||
|
window.electron
|
||||||
|
.getDefaultDownloadsPath()
|
||||||
|
.then((defaultDownloadsPath) => setSelectedPath(defaultDownloadsPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userPreferences?.realDebridApiToken)
|
||||||
|
setSelectedDownloader(Downloader.RealDebrid);
|
||||||
|
}, [userPreferences?.downloadsPath, userPreferences?.realDebridApiToken]);
|
||||||
|
|
||||||
|
const getDiskFreeSpace = (path: string) => {
|
||||||
|
window.electron.getDiskFreeSpace(path).then((result) => {
|
||||||
|
setDiskFreeSpace(result);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChooseDownloadsPath = async () => {
|
||||||
|
const { filePaths } = await window.electron.showOpenDialog({
|
||||||
|
defaultPath: selectedPath,
|
||||||
|
properties: ["openDirectory"],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (filePaths && filePaths.length > 0) {
|
||||||
|
const path = filePaths[0];
|
||||||
|
setSelectedPath(path);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleStartClick = () => {
|
||||||
|
if (repack) {
|
||||||
|
setDownloadStarting(true);
|
||||||
|
|
||||||
|
startDownload(repack, selectedDownloader, selectedPath).finally(() => {
|
||||||
|
setDownloadStarting(false);
|
||||||
|
onClose();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
visible={visible}
|
||||||
|
title={t("download_settings")}
|
||||||
|
description={t("space_left_on_disk", {
|
||||||
|
space: formatBytes(diskFreeSpace?.free ?? 0),
|
||||||
|
})}
|
||||||
|
onClose={onClose}
|
||||||
|
>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
marginBottom: `${SPACING_UNIT}px`,
|
||||||
|
display: "block",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t("downloader")}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div className={styles.downloaders}>
|
||||||
|
{downloaders.map((downloader) => (
|
||||||
|
<Button
|
||||||
|
key={downloader}
|
||||||
|
className={styles.downloaderOption}
|
||||||
|
theme={
|
||||||
|
selectedDownloader === downloader ? "primary" : "outline"
|
||||||
|
}
|
||||||
|
disabled={
|
||||||
|
downloader === Downloader.RealDebrid &&
|
||||||
|
!userPreferences?.realDebridApiToken
|
||||||
|
}
|
||||||
|
onClick={() => setSelectedDownloader(downloader)}
|
||||||
|
>
|
||||||
|
{selectedDownloader === downloader && (
|
||||||
|
<CheckCircleFillIcon className={styles.downloaderIcon} />
|
||||||
|
)}
|
||||||
|
{DOWNLOADER_NAME[downloader]}
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
gap: `${SPACING_UNIT}px`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className={styles.downloadsPathField}>
|
||||||
|
<TextField
|
||||||
|
value={selectedPath}
|
||||||
|
readOnly
|
||||||
|
disabled
|
||||||
|
label={t("download_path")}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style={{ alignSelf: "flex-end" }}
|
||||||
|
theme="outline"
|
||||||
|
onClick={handleChooseDownloadsPath}
|
||||||
|
disabled={downloadStarting}
|
||||||
|
>
|
||||||
|
{t("change")}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p className={styles.hintText}>
|
||||||
|
<Trans i18nKey="select_folder_hint" ns="game_details">
|
||||||
|
<Link to="/settings" />
|
||||||
|
</Trans>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Button onClick={handleStartClick} disabled={downloadStarting}>
|
||||||
|
<DownloadIcon />
|
||||||
|
{t("download_now")}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue