diff --git a/src/renderer/declaration.d.ts b/src/renderer/declaration.d.ts index 3184940a..f8d1018c 100644 --- a/src/renderer/declaration.d.ts +++ b/src/renderer/declaration.d.ts @@ -76,7 +76,7 @@ declare global { ) => Promise; /* Hardware */ - getDiskFreeSpace: (path: string) => Promise; + getDiskFreeSpace: () => Promise; /* Misc */ getOrCacheImage: (url: string) => Promise; diff --git a/src/renderer/pages/game-details/game-details.tsx b/src/renderer/pages/game-details/game-details.tsx index 9c9178bf..aae3f267 100644 --- a/src/renderer/pages/game-details/game-details.tsx +++ b/src/renderer/pages/game-details/game-details.tsx @@ -51,6 +51,7 @@ export function GameDetails() { const { t, i18n } = useTranslation("game_details"); const [showRepacksModal, setShowRepacksModal] = useState(false); + const [showSelectFolderModal, setShowSelectFolderModal] = useState(false); const randomGameObjectID = useRef(null); @@ -153,6 +154,7 @@ export function GameDetails() { ).then(() => { getGame(); setShowRepacksModal(false); + setShowSelectFolderModal(false); }); }; @@ -177,6 +179,8 @@ export function GameDetails() { visible={showRepacksModal} gameDetails={gameDetails} startDownload={handleStartDownload} + showSelectFolderModal={showSelectFolderModal} + setShowSelectFolderModal={setShowSelectFolderModal} onClose={() => setShowRepacksModal(false)} /> )} diff --git a/src/renderer/pages/game-details/repacks-modal.css.ts b/src/renderer/pages/game-details/repacks-modal.css.ts index 6a1d37f3..c2568594 100644 --- a/src/renderer/pages/game-details/repacks-modal.css.ts +++ b/src/renderer/pages/game-details/repacks-modal.css.ts @@ -16,23 +16,3 @@ export const repackButton = style({ color: vars.color.bodyText, padding: `${SPACING_UNIT * 2}px`, }); - -export const container = style({ - width: "100%", - display: "flex", - flexDirection: "column", - gap: `${SPACING_UNIT * 2}px`, - marginBottom: SPACING_UNIT * 2, - paddingBottom: SPACING_UNIT * 2, - borderBottom: `solid 1px ${vars.color.borderColor}`, -}); - -export const downloadsPathField = style({ - display: "flex", - gap: `${SPACING_UNIT * 2}px`, -}); - -export const hintText = style({ - fontSize: 12, - color: vars.color.bodyText, -}); diff --git a/src/renderer/pages/game-details/repacks-modal.tsx b/src/renderer/pages/game-details/repacks-modal.tsx index c5830de7..7908c486 100644 --- a/src/renderer/pages/game-details/repacks-modal.tsx +++ b/src/renderer/pages/game-details/repacks-modal.tsx @@ -6,16 +6,18 @@ import type { GameRepack, ShopDetails } from "@types"; import * as styles from "./repacks-modal.css"; -import { useAppSelector } from "@renderer/hooks"; -import { SPACING_UNIT } from "@renderer/theme.css"; -import { formatBytes } from "@renderer/utils"; import type { DiskSpace } from "check-disk-space"; import { format } from "date-fns"; -import { Link } from "react-router-dom"; +import { SPACING_UNIT } from "@renderer/theme.css"; +import { formatBytes } from "@renderer/utils"; +import { useAppSelector } from "@renderer/hooks"; +import { SelectFolderModal } from "./select-folder-modal"; export interface RepacksModalProps { visible: boolean; gameDetails: ShopDetails; + showSelectFolderModal: boolean; + setShowSelectFolderModal: (value: boolean) => void; startDownload: (repackId: number, downloadPath: string) => Promise; onClose: () => void; } @@ -23,13 +25,18 @@ export interface RepacksModalProps { export function RepacksModal({ visible, gameDetails, + showSelectFolderModal, + setShowSelectFolderModal, startDownload, onClose, }: RepacksModalProps) { const [diskFreeSpace, setDiskFreeSpace] = useState(null); const [filteredRepacks, setFilteredRepacks] = useState([]); - const [selectedPath, setSelectedPath] = useState(""); - const [downloadStarting, setDownloadStarting] = useState(false); + const [repack, setRepack] = useState(null); + + const repackersFriendlyNames = useAppSelector( + (state) => state.repackersFriendlyNames.value + ); const { t } = useTranslation("game_details"); @@ -37,22 +44,20 @@ export function RepacksModal({ setFilteredRepacks(gameDetails.repacks); }, [gameDetails.repacks]); - useEffect(() => { - visible && getDiskFreeSpace(selectedPath); - }, [selectedPath, visible]); - - useEffect(() => { - Promise.all([ - window.electron.getDefaultDownloadsPath(), - window.electron.getUserPreferences(), - ]).then(([path, userPreferences]) => { - setSelectedPath(userPreferences?.downloadsPath || path); + const getDiskFreeSpace = () => { + window.electron.getDiskFreeSpace().then((result) => { + setDiskFreeSpace(result); }); - }, []); + }; - const repackersFriendlyNames = useAppSelector( - (state) => state.repackersFriendlyNames.value - ); + useEffect(() => { + getDiskFreeSpace(); + }, [visible]); + + const handleRepackClick = (repack: GameRepack) => { + setRepack(repack); + setShowSelectFolderModal(true); + }; const handleFilter: React.ChangeEventHandler = (event) => { setFilteredRepacks( @@ -64,31 +69,6 @@ export function RepacksModal({ ); }; - 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 handleRepackClick = (repack: GameRepack) => { - setDownloadStarting(true); - startDownload(repack.id, selectedPath).finally(() => { - setDownloadStarting(false); - }); - }; - - const getDiskFreeSpace = (path: string) => { - window.electron.getDiskFreeSpace(path).then((result) => { - setDiskFreeSpace(result); - }); - }; - return ( -
-
- - - -
-

- {t("select_folder_hint")}{" "} - - {t("hydra_settings")} - -

-
+ setShowSelectFolderModal(false)} + gameDetails={gameDetails} + startDownload={startDownload} + repack={repack} + />
@@ -140,7 +96,6 @@ export function RepacksModal({ theme="dark" onClick={() => handleRepackClick(repack)} className={styles.repackButton} - disabled={downloadStarting} >

{repack.title}

diff --git a/src/renderer/pages/game-details/select-folder-modal.css.tsx b/src/renderer/pages/game-details/select-folder-modal.css.tsx new file mode 100644 index 00000000..7d32bccc --- /dev/null +++ b/src/renderer/pages/game-details/select-folder-modal.css.tsx @@ -0,0 +1,19 @@ +import { style } from "@vanilla-extract/css"; +import { SPACING_UNIT, vars } from "@renderer/theme.css"; + +export const container = style({ + display: "flex", + flexDirection: "column", + gap: `${SPACING_UNIT * 2}px`, + width: "100%", +}); + +export const downloadsPathField = style({ + display: "flex", + gap: `${SPACING_UNIT * 2}px`, +}); + +export const hintText = style({ + fontSize: 12, + color: vars.color.bodyText, +}); diff --git a/src/renderer/pages/game-details/select-folder-modal.tsx b/src/renderer/pages/game-details/select-folder-modal.tsx new file mode 100644 index 00000000..4edfa6b1 --- /dev/null +++ b/src/renderer/pages/game-details/select-folder-modal.tsx @@ -0,0 +1,99 @@ +import { Button, Modal, TextField } from "@renderer/components"; +import { GameRepack, ShopDetails } from "@types"; +import { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; + +import * as styles from "./select-folder-modal.css"; +import { Link } from "react-router-dom"; + +export interface SelectFolderModalProps { + visible: boolean; + gameDetails: ShopDetails; + onClose: () => void; + startDownload: (repackId: number, downloadPath: string) => Promise; + repack: GameRepack; +} + +export function SelectFolderModal({ + visible, + gameDetails, + onClose, + startDownload, + repack, +}: SelectFolderModalProps) { + const { t } = useTranslation("game_details"); + + const [selectedPath, setSelectedPath] = useState(""); + const [downloadStarting, setDownloadStarting] = useState(false); + + useEffect(() => { + Promise.all([ + window.electron.getDefaultDownloadsPath(), + window.electron.getUserPreferences(), + ]).then(([path, userPreferences]) => { + setSelectedPath(userPreferences?.downloadsPath || path); + }); + }, []); + + 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 = () => { + setDownloadStarting(true); + startDownload(repack.id, selectedPath).finally(() => { + setDownloadStarting(false); + }); + }; + + return ( + +

+
+ + + +
+

+ {t("select_folder_hint")}{" "} + + {t("hydra_settings")} + +

+ +
+
+ ); +}