Skip to content

Commit

Permalink
[Fix] multiple settings writes (#1464)
Browse files Browse the repository at this point in the history
* Fix multiple settings saves

* Fix linter (??)

* Move type hint to the state instead of the prop
  • Loading branch information
arielj authored Jun 15, 2022
1 parent 35af57f commit c919402
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 92 deletions.
6 changes: 6 additions & 0 deletions electron/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
2 changes: 1 addition & 1 deletion src/screens/Settings/components/AdvancedSettings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ export const AdvancedSettings = ({
isSuccess: isCopiedToClipboard
})}
onClick={() => {
clipboard.writeText(JSON.stringify({ ...settingsToSave }))
clipboard.writeText(JSON.stringify({ ...settingsToSave }, null, 2))
setCopiedToClipboard(true)
}}
>
Expand Down
249 changes: 158 additions & 91 deletions src/screens/Settings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ function Settings() {
const [autoSyncSaves, setAutoSyncSaves] = useState(false)
const [altWine, setAltWine] = useState([] as WineInstallation[])

const [configLoaded, setConfigLoaded] = useState(false)
const [settingsToSave, setSettingsToSave] = useState<AppSettings>(
{} as AppSettings
)

const { appName = '', type = '' } = useParams()
const isDefault = appName === 'default'
const isGeneralSettings = type === 'general'
Expand All @@ -190,79 +195,162 @@ 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])
}

// 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

const GlobalSettings = {
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,
addStartMenuShortcuts,
audioFix,
autoInstallDxvk,
autoInstallVkd3d,
autoSyncSaves,
customWinePaths,
darkTrayIcon,
defaultInstallPath,
Expand All @@ -275,6 +363,7 @@ function Settings() {
exitToTray,
maxRecentGames,
maxWorkers,
maxSharpness,
minimizeOnLaunch,
nvidiaPrime,
otherOptions,
Expand All @@ -287,48 +376,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 <UpdateComponent />
Expand Down

0 comments on commit c919402

Please sign in to comment.