fix: guard settings async state updates (#3532)

This commit is contained in:
Neil
2026-05-30 00:45:39 -07:00
committed by GitHub
parent 3c5831fd51
commit aa60da9cf1
3 changed files with 40 additions and 6 deletions
@@ -128,7 +128,15 @@ export function GeneralPane({ settings, updateSettings }: GeneralPaneProps): Rea
>('loading')
useEffect(() => {
window.api.updater.getVersion().then(setAppVersion)
let cancelled = false
void window.api.updater.getVersion().then((version) => {
if (!cancelled) {
setAppVersion(version)
}
})
return () => {
cancelled = true
}
}, [])
useEffect(() => {
@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react'
import { useEffect, useRef, useState } from 'react'
import type { GlobalSettings } from '../../../../shared/types'
import { getDefaultVoiceSettings } from '../../../../shared/constants'
import type { SpeechModelManifest, SpeechModelState } from '../../../../shared/speech-types'
@@ -32,13 +32,29 @@ export function VoicePane({ settings, updateSettings }: VoicePaneProps): React.J
const shortcutLabel = useShortcutLabel('voice.dictation')
const [catalog, setCatalog] = useState<SpeechModelManifest[]>([])
const [permissionPending, setPermissionPending] = useState(false)
const mountedRef = useRef(true)
useEffect(() => {
mountedRef.current = true
return () => {
mountedRef.current = false
}
}, [])
useEffect(() => {
let cancelled = false
refreshModelStates()
window.api.speech
void window.api.speech
.getCatalog()
.then(setCatalog)
.then((nextCatalog) => {
if (!cancelled) {
setCatalog(nextCatalog)
}
})
.catch(() => {})
return () => {
cancelled = true
}
}, [refreshModelStates])
useEffect(() => {
@@ -84,7 +100,9 @@ export function VoicePane({ settings, updateSettings }: VoicePaneProps): React.J
} catch {
toast.error('Could not request microphone permission. Voice dictation was not enabled.')
} finally {
setPermissionPending(false)
if (mountedRef.current) {
setPermissionPending(false)
}
}
}
@@ -96,12 +96,20 @@ export function useWindowsTerminalCapabilities(
return
}
let cancelled = false
const cached = getCachedWindowsTerminalCapabilities()
setCapabilities(cachedCapabilities ? cached : { ...cached, isLoading: true })
subscribers.add(setCapabilities)
void loadWindowsTerminalCapabilities({ force: forceRefreshOnMount }).then(setCapabilities)
void loadWindowsTerminalCapabilities({ force: forceRefreshOnMount }).then(
(nextCapabilities) => {
if (!cancelled) {
setCapabilities(nextCapabilities)
}
}
)
return () => {
cancelled = true
subscribers.delete(setCapabilities)
}
}, [enabled, forceRefreshOnMount])