chore: disabling resuming real debrid downloads when real debrid is not set

This commit is contained in:
Chubby Granny Chaser 2024-05-30 00:17:17 +01:00
parent a34a774fb7
commit 50c3503e37
No known key found for this signature in database
4 changed files with 264 additions and 0 deletions

View 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`,
});

View 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>
);
}

View file

@ -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`,
});

View file

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