diff --git a/desktop/src/__tests__/generalSettings.test.tsx b/desktop/src/__tests__/generalSettings.test.tsx index 3e36eafb..7a2d5e1d 100644 --- a/desktop/src/__tests__/generalSettings.test.tsx +++ b/desktop/src/__tests__/generalSettings.test.tsx @@ -268,7 +268,7 @@ describe('Settings > General tab', () => { expect((uiZoomHeading.compareDocumentPosition(webFetchHeading) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0).toBe(true) }) - it('applies UI zoom while dragging so the slider and app zoom stay synchronized', async () => { + it('previews UI zoom while dragging and applies it once on release', async () => { render() fireEvent.click(screen.getByText('General')) @@ -278,6 +278,7 @@ describe('Settings > General tab', () => { expect(screen.getByText('0 resets zoom to 100%.')).toBeInTheDocument() const slider = screen.getByLabelText('UI Zoom') + expect(slider).toHaveAttribute('step', '0.01') fireEvent.pointerDown(slider, { pointerId: 1 }) await act(async () => { @@ -287,8 +288,8 @@ describe('Settings > General tab', () => { }) expect(screen.getAllByText('125%')).toHaveLength(2) - expect(useSettingsStore.getState().setUiZoom).toHaveBeenCalledWith(1.25) - expect(useSettingsStore.getState().uiZoom).toBe(1.25) + expect(useSettingsStore.getState().setUiZoom).not.toHaveBeenCalledWith(1.25) + expect(useSettingsStore.getState().uiZoom).toBe(1) expect(slider).toHaveValue('1.25') expect(slider).toHaveClass('settings-zoom-range') expect(slider.closest('.settings-zoom-control')).toHaveClass('is-dragging') diff --git a/desktop/src/lib/appZoom.ts b/desktop/src/lib/appZoom.ts index 3127d42c..23fcb2e4 100644 --- a/desktop/src/lib/appZoom.ts +++ b/desktop/src/lib/appZoom.ts @@ -4,7 +4,7 @@ export const DEFAULT_APP_ZOOM = 1 export const MIN_APP_ZOOM = 0.5 export const MAX_APP_ZOOM = 2 export const APP_ZOOM_STEP = 0.1 -export const APP_ZOOM_CONTROL_STEP = 0.05 +export const APP_ZOOM_CONTROL_STEP = 0.01 export type AppZoomAction = 'in' | 'out' | 'reset' diff --git a/desktop/src/pages/Settings.tsx b/desktop/src/pages/Settings.tsx index 01d07690..ddbaaf44 100644 --- a/desktop/src/pages/Settings.tsx +++ b/desktop/src/pages/Settings.tsx @@ -1394,6 +1394,7 @@ function GeneralSettings() { const [notificationActionRunning, setNotificationActionRunning] = useState(false) const [uiZoomDraft, setUiZoomDraft] = useState(uiZoom) const [isUiZoomDragging, setIsUiZoomDragging] = useState(false) + const isUiZoomDraggingRef = useRef(false) const webSearchDirty = JSON.stringify(webSearchDraft) !== JSON.stringify(webSearch) const uiZoomPercent = Math.round(uiZoomDraft * 100) const uiZoomRangeProgress = `${Math.round(((uiZoomDraft - UI_ZOOM_MIN) / (UI_ZOOM_MAX - UI_ZOOM_MIN)) * 1000) / 10}%` @@ -1523,11 +1524,14 @@ function GeneralSettings() { } } - const commitUiZoom = (value: number, options: { keepDragging?: boolean } = {}) => { + const setUiZoomDraggingState = (dragging: boolean) => { + isUiZoomDraggingRef.current = dragging + setIsUiZoomDragging(dragging) + } + + const commitUiZoom = (value: number) => { const nextZoom = Number.isFinite(value) ? value : UI_ZOOM_DEFAULT - if (!options.keepDragging) { - setIsUiZoomDragging(false) - } + setUiZoomDraggingState(false) setUiZoomDraft(nextZoom) setUiZoom(nextZoom) } @@ -1602,16 +1606,27 @@ function GeneralSettings() { step={UI_ZOOM_STEP} value={uiZoomDraft} onPointerDown={() => { - setIsUiZoomDragging(true) + setUiZoomDraggingState(true) + }} + onPointerUp={(e) => commitUiZoom(e.currentTarget.valueAsNumber)} + onPointerCancel={() => { + setUiZoomDraggingState(false) + setUiZoomDraft(uiZoom) + }} + onChange={(e) => { + const nextZoom = Number.isFinite(e.currentTarget.valueAsNumber) + ? e.currentTarget.valueAsNumber + : UI_ZOOM_DEFAULT + setUiZoomDraft(nextZoom) + if (!isUiZoomDraggingRef.current) { + setUiZoom(nextZoom) + } }} - onPointerUp={() => setIsUiZoomDragging(false)} - onPointerCancel={() => setIsUiZoomDragging(false)} - onChange={(e) => commitUiZoom(e.currentTarget.valueAsNumber, { keepDragging: isUiZoomDragging })} onBlur={(e) => { if (uiZoomDraft !== uiZoom) { commitUiZoom(e.currentTarget.valueAsNumber) } else { - setIsUiZoomDragging(false) + setUiZoomDraggingState(false) } }} className="settings-zoom-range w-full"