diff --git a/packages/compass-preferences-model/src/preferences-schema.tsx b/packages/compass-preferences-model/src/preferences-schema.tsx index 7e3c2f283bf..19cb9bd3d79 100644 --- a/packages/compass-preferences-model/src/preferences-schema.tsx +++ b/packages/compass-preferences-model/src/preferences-schema.tsx @@ -125,6 +125,7 @@ export type InternalUserPreferences = { // TODO: Remove this as part of COMPASS-8970. enableConnectInNewWindow: boolean; showEndOfLifeConnectionModal: boolean; + zoomLevel?: number; }; // UserPreferences contains all preferences stored to disk. @@ -459,6 +460,17 @@ export const storedUserPreferencesProps: Required<{ ), type: 'boolean', }, + /** + * Zoom level for restoring browser zoom state. + */ + zoomLevel: { + ui: false, + cli: false, + global: false, + description: null, + validator: z.number().optional(), + type: 'number', + }, /** * Enable/disable the AI services. This is currently set * in the atlas-service initialization where we make a request to the diff --git a/packages/compass/src/app/application.tsx b/packages/compass/src/app/application.tsx index 35cb81ed3d9..cdda3a3f485 100644 --- a/packages/compass/src/app/application.tsx +++ b/packages/compass/src/app/application.tsx @@ -367,27 +367,66 @@ class Application { const ZOOM_INCREMENT = 0.5; const ZOOM_MAX = 5; const ZOOM_MIN = -3; + const SAVE_DEBOUNCE_DELAY = 500; // 500ms delay for save operations + + // Debounced save zoom level to preferences + let saveTimeoutId: NodeJS.Timeout | null = null; + const debouncedSaveZoomLevel = (zoomLevel: number) => { + if (saveTimeoutId) { + clearTimeout(saveTimeoutId); + } + + saveTimeoutId = setTimeout(() => { + void defaultPreferencesInstance.savePreferences({ zoomLevel }); + saveTimeoutId = null; + }, SAVE_DEBOUNCE_DELAY); + }; + + const restoreZoomLevel = () => { + try { + const preferences = defaultPreferencesInstance.getPreferences(); + const savedZoomLevel = preferences.zoomLevel ?? ZOOM_DEFAULT; + + // Clamp zoom level to allowed range + const zoomLevel = Math.min( + Math.max(savedZoomLevel, ZOOM_MIN), + ZOOM_MAX + ); + + webFrame.setZoomLevel(zoomLevel); + } catch { + // noop + } + }; const zoomReset = () => { - return webFrame.setZoomLevel(ZOOM_DEFAULT); + webFrame.setZoomLevel(ZOOM_DEFAULT); + debouncedSaveZoomLevel(ZOOM_DEFAULT); }; + const zoomIn = () => { const currentZoomLevel = webFrame.getZoomLevel(); const newZoomLevel = Math.min( currentZoomLevel + ZOOM_INCREMENT, ZOOM_MAX ); - return webFrame.setZoomLevel(newZoomLevel); + webFrame.setZoomLevel(newZoomLevel); + debouncedSaveZoomLevel(newZoomLevel); }; + const zoomOut = () => { const currentZoomLevel = webFrame.getZoomLevel(); const newZoomLevel = Math.max( currentZoomLevel - ZOOM_INCREMENT, ZOOM_MIN ); - return webFrame.setZoomLevel(newZoomLevel); + webFrame.setZoomLevel(newZoomLevel); + debouncedSaveZoomLevel(newZoomLevel); }; + // Restore zoom level on startup + restoreZoomLevel(); + ipcRenderer?.on('window:zoom-reset', zoomReset); ipcRenderer?.on('window:zoom-in', zoomIn); ipcRenderer?.on('window:zoom-out', zoomOut);