diff --git a/src/Stores.ts b/src/Stores.ts index b8da47f1..a82e769c 100644 --- a/src/Stores.ts +++ b/src/Stores.ts @@ -41,7 +41,6 @@ export const steamGridDBKey = writable(""); export const needsSteamKey = writable(true); export const steamKey = writable(""); -export const needsSteamInstallPath = writable(true); export const steamInstallPath = writable(""); export const selectedResultPage = writable(0); @@ -107,6 +106,9 @@ export const cleanConflicts: Writable = writable([]); export const showUpdateModal = writable(false); export const updateManifest: Writable = writable(null); +export const showSteamPathModal = writable(false); +export const steamPathModalClose = writable(async () => {}); + export const showDialogModal = writable(false); export const dialogModalTitle = writable(""); export const dialogModalMessage = writable(""); diff --git a/src/components/interactables/FileButton.svelte b/src/components/interactables/FileButton.svelte new file mode 100644 index 00000000..f2204def --- /dev/null +++ b/src/components/interactables/FileButton.svelte @@ -0,0 +1,35 @@ + + + + + + + + + + + diff --git a/src/components/modals/DialogModal.svelte b/src/components/modals/DialogModal.svelte index 37fbdf3f..c5bf8014 100644 --- a/src/components/modals/DialogModal.svelte +++ b/src/components/modals/DialogModal.svelte @@ -45,7 +45,7 @@ {:else} - + {/if} diff --git a/src/components/modals/SteamPathModal.svelte b/src/components/modals/SteamPathModal.svelte new file mode 100644 index 00000000..0b43f312 --- /dev/null +++ b/src/components/modals/SteamPathModal.svelte @@ -0,0 +1,77 @@ + + + +
+ + + C:/Program Files (x86)/Steam and ~/.steam/Steam on Linux.`} + value={steamInstallLocation} + onChange={onInstallLocationChange} + required + /> + +
+
+
+
+ + diff --git a/src/components/modals/settings/SettingsFilePathEntry.svelte b/src/components/modals/settings/SettingsFilePathEntry.svelte new file mode 100644 index 00000000..e71ba7e8 --- /dev/null +++ b/src/components/modals/settings/SettingsFilePathEntry.svelte @@ -0,0 +1,84 @@ + + +
+

{label}

+
+ + + +
+ +
+ Usage:
+ {@html description}
+ + {#if notes != ""} + + Notes:
+ {@html notes} + {/if} + + + Required: {required ? "Yes" : "No"}
+
+
+ + \ No newline at end of file diff --git a/src/components/modals/settings/SettingsModal.svelte b/src/components/modals/settings/SettingsModal.svelte index 9960a633..97b0127f 100644 --- a/src/components/modals/settings/SettingsModal.svelte +++ b/src/components/modals/settings/SettingsModal.svelte @@ -1,5 +1,5 @@
+ + + C:/Program Files (x86)/Steam and ~/.steam/Steam on Linux. You must restart after changing this.`} + value={steamInstallLocation} + onChange={onInstallLocationChange} + required + /> { + return new Promise(async (resolve) => { + const hasSteamInstalled = await DialogController.ask("Steam Not Found", "WARNING", "SARM could not locate Steam. Do you have it installed?", "Yes", "No"); + + if (hasSteamInstalled) { + showSteamPathModal.set(true); + steamPathModalClose.set(async () => resolve()); + } else { + await DialogController.message("SARM Could Not Initialize", "ERROR", "Please install Steam and login once, then restart SARM.", "Ok"); + await exit(0); + resolve() + } + }); +} + +/** + * Handles determining the Steam installation path. + * @param savedInstallPath The current saved install path. + */ async function findSteamPath(savedInstallPath: string): Promise { - const returnedInstallPath = await RustInterop.addSteamToScope(); - - // ! for some reason this is really slow. maybe the fs.exists? May also be that my wifi is shit - // if (savedInstallPath !== "") { - // if (await fs.exists(savedInstallPath)) { - // const steamInstallPathAdded = await RustInterop.addPathToScope(savedInstallPath); - - // if (steamInstallPathAdded) { - // steamInstallPath.set(savedInstallPath); - // } else { - // // TODO: figure out what to do here. path exists but failed to add it to scope - // } - // } else { - // // * show modal and proceed accordingly - // } - // } else { - // const returnedInstallPath = await RustInterop.addSteamToScope(); - - // if (returnedInstallPath === "") { - // // TODO: figure out what to do here. path exists but failed to add it to scope - // } else if (returnedInstallPath === "DNE") { - // // let hit_ok = MessageDialogBuilder::new("SARM Initialization Error", "Steam was not found on your PC. Steam needs to be installed for SARM to work.") - // // .buttons(MessageDialogButtons::Ok) - // // .show(); - - // // if hit_ok { - // // exit(1); - // // } - // // TODO: prompt user saying steam was not found, and ask if steam is installed. if yes, show custom field, otherwise, ask to install then exit app. - // } else { - // steamInstallPath.set(returnedInstallPath); - // await SettingsManager.updateSetting("steamInstallPath", returnedInstallPath); - // } - // } + if (savedInstallPath !== "") { + const steamInstallPathAdded = await RustInterop.addPathToScope(savedInstallPath); + if (steamInstallPathAdded && await fs.exists(savedInstallPath)) { + steamInstallPath.set(savedInstallPath); + } else { + await steamDialogSequence(); + } + } else { + const returnedInstallPath = await RustInterop.addSteamToScope(); + + if (returnedInstallPath === "") { + await DialogController.message("Unrecoverable Error", "ERROR", "A Steam installation was found but could not be added to scope. Please restart, and if the problem persists, open an issue on SARM's GitHub repository.", "Ok"); + await exit(0); + } else if (returnedInstallPath === "DNE") { + await steamDialogSequence(); + } else { + steamInstallPath.set(returnedInstallPath); + await SettingsManager.updateSetting("steamInstallPath", returnedInstallPath); + } + } } /** diff --git a/src/lib/controllers/DialogController.ts b/src/lib/controllers/DialogController.ts index b9bddef0..f7da8e0b 100644 --- a/src/lib/controllers/DialogController.ts +++ b/src/lib/controllers/DialogController.ts @@ -1,10 +1,30 @@ import { dialogModalCancel, dialogModalCancelText, dialogModalConfirm, dialogModalConfirmText, dialogModalMessage, dialogModalTitle, dialogModalType, showDialogModal } from "../../Stores"; +import { LogController } from "./LogController"; /** * Controller class for handling dialog modals. */ export class DialogController { + /** + * Logs the title of a shown dialog based on its type. + * @param type The type of message to log. + * @param title The title of the dialog. + */ + private static async logByType(type: DialogModalType, title: string) { + switch (type) { + case "INFO": + await LogController.log(title); + break; + case "WARNING": + await LogController.warn(title); + break; + case "ERROR": + await LogController.error(title); + break; + } + } + /** * Displays a message with a single button. * @param title The title of the dialog modal. @@ -13,6 +33,7 @@ export class DialogController { * @param confirmText The text displayed in the button. */ static async message(title: string, type: DialogModalType, message: string, confirmText: string): Promise { + await DialogController.logByType(type, title); return new Promise((resolve) => { dialogModalTitle.set(title); dialogModalType.set(type); @@ -35,8 +56,10 @@ export class DialogController { * @param cancelText The text displayed for the cancel action. */ static async ask(title: string, type: DialogModalType, message: string, confirmText: string, cancelText: string): Promise { + await DialogController.logByType(type, title); return new Promise((resolve) => { dialogModalTitle.set(title); + dialogModalType.set(type); dialogModalMessage.set(message); dialogModalConfirmText.set(confirmText); diff --git a/src/stores/AppState.ts b/src/stores/AppState.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/stores/Modals.ts b/src/stores/Modals.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/windows/main/Main.svelte b/src/windows/main/Main.svelte index 3c1c7f88..2f1cb7e2 100644 --- a/src/windows/main/Main.svelte +++ b/src/windows/main/Main.svelte @@ -10,7 +10,7 @@ import Grids from "../../components/core/grids/Grids.svelte"; import { AppController } from "../../lib/controllers/AppController"; import { exit } from "@tauri-apps/api/process"; - import { activeUserId, batchApplyMessage, batchApplyProgress, batchApplyWasCancelled, gridModalInfo, isOnline, showManualGamesModal, showBatchApplyModal, showBatchApplyProgress, showGridModal, showLogoPositionModal, steamUsers, showSettingsModal, showCleanGridsModal, showCleanConflictDialog, showUpdateModal, updateManifest, showDialogModal } from "../../Stores"; + import { activeUserId, batchApplyMessage, batchApplyProgress, batchApplyWasCancelled, gridModalInfo, isOnline, showManualGamesModal, showBatchApplyModal, showBatchApplyProgress, showGridModal, showLogoPositionModal, steamUsers, showSettingsModal, showCleanGridsModal, showCleanConflictDialog, showUpdateModal, updateManifest, showDialogModal, showSteamPathModal } from "../../Stores"; import { WindowController } from "../../lib/controllers/WindowController"; import DropDown from "../../components/interactables/DropDown.svelte"; import type { Unsubscriber } from "svelte/store"; @@ -25,6 +25,7 @@ import CleanConflictDialog from "../../components/modals/clean-grids/CleanConflictDialog.svelte"; import UpdateModal from "../../components/modals/updates/UpdateModal.svelte"; import DialogModal from "../../components/modals/DialogModal.svelte"; + import SteamPathModal from "../../components/modals/SteamPathModal.svelte"; let updateUnsub: any; let activeUserIdUnsub: Unsubscriber; @@ -170,6 +171,9 @@ {#if $showDialogModal} {/if} + {#if $showSteamPathModal} + + {/if} {#if $showGridModal} {/if}