From 9ad895e0b16d31fca945279d5f4cb9bf7ad79794 Mon Sep 17 00:00:00 2001 From: Ariel Juodziukynas Date: Sun, 12 Jun 2022 21:27:31 -0300 Subject: [PATCH 1/3] Fix multiple settings saves --- electron/main.ts | 6 + .../components/AdvancedSettings/index.tsx | 2 +- src/screens/Settings/index.tsx | 249 +++++++++++------- 3 files changed, 164 insertions(+), 93 deletions(-) diff --git a/electron/main.ts b/electron/main.ts index b8f1d3e710..08e57b4430 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -721,6 +721,12 @@ ipcMain.on('toggleVKD3D', (event, [{ winePrefix, winePath }, action]) => { }) ipcMain.handle('writeConfig', (event, [appName, config]) => { + logInfo( + `Writing config for ${appName === 'default' ? 'Heroic' : appName}`, + LogPrefix.Backend + ) + // use 2 spaces for pretty print + logInfo(JSON.stringify(config, null, 2), LogPrefix.Backend) if (appName === 'default') { GlobalConfig.get().config = config GlobalConfig.get().flush() diff --git a/src/screens/Settings/components/AdvancedSettings/index.tsx b/src/screens/Settings/components/AdvancedSettings/index.tsx index ddaa16dfcd..ec0a1bb514 100644 --- a/src/screens/Settings/components/AdvancedSettings/index.tsx +++ b/src/screens/Settings/components/AdvancedSettings/index.tsx @@ -216,7 +216,7 @@ export const AdvancedSettings = ({ isSuccess: isCopiedToClipboard })} onClick={() => { - clipboard.writeText(JSON.stringify({ ...settingsToSave })) + clipboard.writeText(JSON.stringify({ ...settingsToSave }, null, 2)) setCopiedToClipboard(true) }} > diff --git a/src/screens/Settings/index.tsx b/src/screens/Settings/index.tsx index 887c13686b..3419b8bca3 100644 --- a/src/screens/Settings/index.tsx +++ b/src/screens/Settings/index.tsx @@ -181,6 +181,9 @@ function Settings() { const [autoSyncSaves, setAutoSyncSaves] = useState(false) const [altWine, setAltWine] = useState([] as WineInstallation[]) + const [configLoaded, setConfigLoaded] = useState(false) + const [settingsToSave, setSettingsToSave] = useState({}) + const { appName = '', type = '' } = useParams() const isDefault = appName === 'default' const isGeneralSettings = type === 'general' @@ -190,72 +193,154 @@ function Settings() { const isLogSettings = type === 'log' const isAdvancedSetting = type === 'advanced' && isDefault + // Load Heroic's or game's config, only if not loaded already useEffect(() => { const getSettings = async () => { - const config: AppSettings = await ipcRenderer.invoke( - 'requestSettings', - appName - ) - setAutoSyncSaves(config.autoSyncSaves) - setUseGameMode(config.useGameMode) - setShowFps(config.showFps) - setShowOffline(config.offlineMode) - setAudioFix(config.audioFix) - setShowMangoHud(config.showMangohud) - setDefaultInstallPath(config.defaultInstallPath) - setWineVersion(config.wineVersion) - setWinePrefix(config.winePrefix) - setWineCrossoverBottle(config.wineCrossoverBottle) - setOtherOptions(config.otherOptions) - setLauncherArgs(config.launcherArgs) - setUseNvidiaPrime(config.nvidiaPrime) - setEgsLinkedPath(config.egsLinkedPath || '') - setEgsPath(config.egsLinkedPath || '') - setExitToTray(config.exitToTray) - setStartInTray(config.startInTray) - setMinimizeOnLaunch(config.minimizeOnLaunch) - setDarkTrayIcon(config.darkTrayIcon) - setDiscordRPC(config.discordRPC) - setAutoInstallDxvk(config.autoInstallDxvk) - setAutoInstallVkd3d(config.autoInstallVkd3d) - setEnableEsync(config.enableEsync) - setEnableFsync(config.enableFsync) - setEnableFSR(config.enableFSR) - setFsrSharpness(config.maxSharpness || 2) - setResizableBar(config.enableResizableBar) - setSavesPath(config.savesPath || '') - setMaxWorkers(config.maxWorkers ?? 0) - setMaxRecentGames(config.maxRecentGames ?? 5) - setCustomWinePaths(config.customWinePaths || []) - setAddDesktopShortcuts(config.addDesktopShortcuts) - setAddGamesToStartMenu(config.addStartMenuShortcuts) - setCustomWinePaths(config.customWinePaths || []) - setTargetExe(config.targetExe || '') - setAltLegendaryBin(config.altLegendaryBin || '') - setAltGogdlBin(config.altGogdlBin || '') - setShowUnrealMarket(config.showUnrealMarket) - setDefaultWinePrefix(config.defaultWinePrefix) - setUseSteamRuntime(config.useSteamRuntime) - setDisableController(config.disableController || false) + if (!configLoaded) { + const config: AppSettings = await ipcRenderer.invoke( + 'requestSettings', + appName + ) + setAutoSyncSaves(config.autoSyncSaves) + setUseGameMode(config.useGameMode) + setShowFps(config.showFps) + setShowOffline(config.offlineMode) + setAudioFix(config.audioFix) + setShowMangoHud(config.showMangohud) + setDefaultInstallPath(config.defaultInstallPath) + setWineVersion(config.wineVersion) + setWinePrefix(config.winePrefix) + setWineCrossoverBottle(config.wineCrossoverBottle) + setOtherOptions(config.otherOptions) + setLauncherArgs(config.launcherArgs) + setUseNvidiaPrime(config.nvidiaPrime) + setEgsLinkedPath(config.egsLinkedPath || '') + setEgsPath(config.egsLinkedPath || '') + setExitToTray(config.exitToTray) + setStartInTray(config.startInTray) + setMinimizeOnLaunch(config.minimizeOnLaunch) + setDarkTrayIcon(config.darkTrayIcon) + setDiscordRPC(config.discordRPC) + setAutoInstallDxvk(config.autoInstallDxvk) + setAutoInstallVkd3d(config.autoInstallVkd3d) + setEnableEsync(config.enableEsync) + setEnableFsync(config.enableFsync) + setEnableFSR(config.enableFSR) + setFsrSharpness(config.maxSharpness || 2) + setResizableBar(config.enableResizableBar) + setSavesPath(config.savesPath || '') + setMaxWorkers(config.maxWorkers ?? 0) + setMaxRecentGames(config.maxRecentGames ?? 5) + setCustomWinePaths(config.customWinePaths || []) + setAddDesktopShortcuts(config.addDesktopShortcuts) + setAddGamesToStartMenu(config.addStartMenuShortcuts) + setCustomWinePaths(config.customWinePaths || []) + setTargetExe(config.targetExe || '') + setAltLegendaryBin(config.altLegendaryBin || '') + setAltGogdlBin(config.altGogdlBin || '') + setShowUnrealMarket(config.showUnrealMarket) + setDefaultWinePrefix(config.defaultWinePrefix) + setUseSteamRuntime(config.useSteamRuntime) + setDisableController(config.disableController || false) + + if (!isDefault) { + setLanguageCode(config.language) + const { title: gameTitle, canRunOffline: can_run_offline } = + await getGameInfo(appName, runner) + setCanRunOffline(can_run_offline) + setTitle(gameTitle) + } else { + setTitle(t('globalSettings', 'Global Settings')) + } - if (!isDefault) { - setLanguageCode(config.language) - const { title: gameTitle, canRunOffline: can_run_offline } = - await getGameInfo(appName, runner) - setCanRunOffline(can_run_offline) - setTitle(gameTitle) - } else { - setTitle(t('globalSettings', 'Global Settings')) + setSettingsToSaveState() } } getSettings() + }, [appName, type, isDefault, i18n.language]) + + let returnPath = '/' - return () => { - ipcRenderer.removeAllListeners('requestSettings') + if (!fromGameCard) { + returnPath = `/gamepage/${appName}` + if (returnPath === '/gamepage/default') { + returnPath = '/' } - }, [appName, type, isDefault, i18n.language]) + } - const GlobalSettings = { + // Helper function to update the `settingsToSave` state + const setSettingsToSaveState = () => { + const GlobalSettings = { + altLegendaryBin, + altGogdlBin, + addDesktopShortcuts, + addStartMenuShortcuts, + audioFix, + autoInstallDxvk, + autoInstallVkd3d, + customWinePaths, + darkTrayIcon, + defaultInstallPath, + defaultWinePrefix, + disableController, + discordRPC, + egsLinkedPath, + enableEsync, + enableFsync, + exitToTray, + maxRecentGames, + maxWorkers, + minimizeOnLaunch, + nvidiaPrime, + otherOptions, + showFps, + showMangohud, + showUnrealMarket, + startInTray, + useGameMode, + wineCrossoverBottle, + winePrefix, + wineVersion, + enableFSR, + enableResizableBar + } as AppSettings + + const GameSettings = { + audioFix, + autoInstallDxvk, + autoInstallVkd3d, + autoSyncSaves, + enableEsync, + enableFSR, + enableFsync, + maxSharpness, + enableResizableBar, + language: languageCode, + launcherArgs, + nvidiaPrime, + offlineMode, + otherOptions, + savesPath, + showFps, + showMangohud, + targetExe, + useGameMode, + wineCrossoverBottle, + winePrefix, + wineVersion, + useSteamRuntime + } as AppSettings + + setSettingsToSave(isDefault ? GlobalSettings : GameSettings) + } + + // update the settingsToSave state when any of the configurations changes + // but only after the configuration was loaded + useEffect(() => { + if (configLoaded) { + setSettingsToSaveState() + } + }, [ altLegendaryBin, altGogdlBin, addDesktopShortcuts, @@ -263,6 +348,7 @@ function Settings() { audioFix, autoInstallDxvk, autoInstallVkd3d, + autoSyncSaves, customWinePaths, darkTrayIcon, defaultInstallPath, @@ -275,6 +361,7 @@ function Settings() { exitToTray, maxRecentGames, maxWorkers, + maxSharpness, minimizeOnLaunch, nvidiaPrime, otherOptions, @@ -287,48 +374,26 @@ function Settings() { winePrefix, wineVersion, enableFSR, - enableResizableBar - } as AppSettings - - const GameSettings = { - audioFix, - autoInstallDxvk, - autoInstallVkd3d, - autoSyncSaves, - enableEsync, - enableFSR, - enableFsync, - maxSharpness, enableResizableBar, - language: languageCode, + languageCode, launcherArgs, - nvidiaPrime, offlineMode, - otherOptions, savesPath, - showFps, - showMangohud, targetExe, - useGameMode, - wineCrossoverBottle, - winePrefix, - wineVersion, useSteamRuntime - } as AppSettings - - const settingsToSave = isDefault ? GlobalSettings : GameSettings - let returnPath = '/' - - if (!fromGameCard) { - returnPath = `/gamepage/${appName}` - if (returnPath === '/gamepage/default') { - returnPath = '/' - } - } + ]) + // when the settingsToSave state changes: + // - write the config if it completed loading before + // - set the `configLoaded` state to ensure it can only be written after loaded useEffect(() => { - writeConfig([appName, settingsToSave]) - }, [GlobalSettings, GameSettings, appName]) + if (configLoaded) { + writeConfig([appName, settingsToSave]) + } else { + // initial state is {}, consider loaded when the object has keys in it + setConfigLoaded(Object.keys(settingsToSave).length > 0) + } + }, [settingsToSave]) if (!title) { return @@ -478,7 +543,7 @@ function Settings() { setAltLegendaryBin={setAltLegendaryBin} altGogdlBin={altGogdlBin} setAltGogdlBin={setAltGogdlBin} - settingsToSave={settingsToSave} + settingsToSave={settingsToSave as AppSettings} /> )} {isLogSettings && ( From 6fe26066e14290f73e93b9a859399a07a746a377 Mon Sep 17 00:00:00 2001 From: Ariel Juodziukynas Date: Sun, 12 Jun 2022 21:36:02 -0300 Subject: [PATCH 2/3] Fix linter (??) --- electron/launcher.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/electron/launcher.ts b/electron/launcher.ts index 455b8b6b25..50ab1e05e5 100644 --- a/electron/launcher.ts +++ b/electron/launcher.ts @@ -604,7 +604,7 @@ async function callRunner( * @param env Enviroment variables to use * @param wrappers Wrappers to use (gamemode, steam runtime, etc.) * @param runnerPath The full path to the runner executable - * @returns + * @returns */ function getRunnerCallWithoutCredentials( commandParts: string[], From 88caf7c0c3829c66d1121fc9c82d2f7e7cb24375 Mon Sep 17 00:00:00 2001 From: Ariel Juodziukynas Date: Tue, 14 Jun 2022 22:18:16 -0300 Subject: [PATCH 3/3] Move type hint to the state instead of the prop --- src/screens/Settings/index.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/screens/Settings/index.tsx b/src/screens/Settings/index.tsx index 3419b8bca3..bfee1c0898 100644 --- a/src/screens/Settings/index.tsx +++ b/src/screens/Settings/index.tsx @@ -182,7 +182,9 @@ function Settings() { const [altWine, setAltWine] = useState([] as WineInstallation[]) const [configLoaded, setConfigLoaded] = useState(false) - const [settingsToSave, setSettingsToSave] = useState({}) + const [settingsToSave, setSettingsToSave] = useState( + {} as AppSettings + ) const { appName = '', type = '' } = useParams() const isDefault = appName === 'default' @@ -543,7 +545,7 @@ function Settings() { setAltLegendaryBin={setAltLegendaryBin} altGogdlBin={altGogdlBin} setAltGogdlBin={setAltGogdlBin} - settingsToSave={settingsToSave as AppSettings} + settingsToSave={settingsToSave} /> )} {isLogSettings && (