Skip to content
Closed
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
29 changes: 28 additions & 1 deletion webview-ui/src/components/settings/SettingsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -196,17 +196,44 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t

setCachedState((prevCachedState) => ({ ...prevCachedState, ...extensionState }))
prevApiConfigName.current = currentApiConfigName
// Reset change detection when API config changes externally
setChangeDetected(false)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are now three separate places handling similar logic for setChangeDetected(false) (lines 200, 208, and within the new effect). Could we consolidate this logic into a single helper function or custom hook to improve maintainability?

}, [currentApiConfigName, extensionState, isChangeDetected])
}, [currentApiConfigName, extensionState])

// Bust the cache when settings are imported.
useEffect(() => {
if (settingsImportedAt) {
setCachedState((prevCachedState) => ({ ...prevCachedState, ...extensionState }))
// Reset change detection when settings are imported
setChangeDetected(false)
}
}, [settingsImportedAt, extensionState])

// Reset change detection when extensionState changes from outside the settings dialog
// This prevents false positives when mode or API config changes in the main interface
useEffect(() => {
// Check if the changes are coming from outside the settings dialog
// by comparing the extension state with our cached state
const isExternalChange =
extensionState.mode !== cachedState.mode ||
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code only checks for mode and apiConfiguration changes, but other fields could also change externally (e.g., language, experiments). Should we expand this to cover all fields that could change externally, or is there a specific reason to limit it to these two?

JSON.stringify(extensionState.apiConfiguration) !== JSON.stringify(cachedState.apiConfiguration)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using JSON.stringify for deep comparison on every render could be expensive for large API configurations. Could we use a more efficient deep comparison utility like lodash's isEqual or memoize this comparison?

Suggested change
JSON.stringify(extensionState.apiConfiguration) !== JSON.stringify(cachedState.apiConfiguration)
JSON.stringify(extensionState.apiConfiguration) !== JSON.stringify(cachedState.apiConfiguration)


if (isExternalChange && !isChangeDetected) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this intentional? The condition isExternalChange && !isChangeDetected could lead to race conditions if internal changes happen simultaneously with external changes. Consider using a more robust state management approach or a ref to track the source of changes.

// Update cached state to match extension state for external changes
setCachedState((prevCachedState) => ({
...prevCachedState,
mode: extensionState.mode,
apiConfiguration: extensionState.apiConfiguration,
}))
}
}, [
extensionState.mode,
extensionState.apiConfiguration,
cachedState.mode,
cachedState.apiConfiguration,
isChangeDetected,
])

const setCachedStateField: SetCachedStateField<keyof ExtensionStateContextType> = useCallback((field, value) => {
setCachedState((prevState) => {
if (prevState[field] === value) {
Expand Down
Loading