Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fix] multiple settings writes #1464

Merged
merged 4 commits into from
Jun 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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))
arielj marked this conversation as resolved.
Show resolved Hide resolved
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