diff --git a/client/src/pages/JourneyDetailPage.tsx b/client/src/pages/JourneyDetailPage.tsx index 56ff67cd0..a8fb00109 100644 --- a/client/src/pages/JourneyDetailPage.tsx +++ b/client/src/pages/JourneyDetailPage.tsx @@ -118,7 +118,11 @@ function JourneyDetailPageDesktop() { const toggleSkeletons = async () => { const next = !hideSkeletons setHideSkeletons(next) - await journeyApi.updatePreferences(current.id, { hide_skeletons: next }) + try { + await journeyApi.updatePreferences(current.id, { hide_skeletons: next }) + } catch { + // A view preference, as on the phone: the local flip stands until the next load. + } } const skeletonLabel = hideSkeletons ? t('journey.skeletons.show') : t('journey.skeletons.hide') const barButton = 'w-10 h-10 flex-shrink-0 rounded-lg bg-surface-elevated backdrop-blur-lg border border-edge shadow-lg text-content-secondary flex items-center justify-center hover:bg-surface-hover active:scale-95 transition-transform' diff --git a/client/src/pages/JourneyDetailPage.wiring.test.tsx b/client/src/pages/JourneyDetailPage.wiring.test.tsx index 34d044c82..b56c6dce1 100644 --- a/client/src/pages/JourneyDetailPage.wiring.test.tsx +++ b/client/src/pages/JourneyDetailPage.wiring.test.tsx @@ -1,4 +1,4 @@ -// FE-JRN-DETWIRE-001 to FE-JRN-DETWIRE-041 +// FE-JRN-DETWIRE-001 to FE-JRN-DETWIRE-042 import { describe, it, expect, beforeEach, vi } from 'vitest'; import { render, screen, fireEvent, waitFor, within } from '../../tests/helpers/render'; import { journeyApi } from '../api/client'; @@ -582,4 +582,23 @@ describe('JourneyDetailPage wiring', () => { expect(screen.queryByText('common.upload')).not.toBeInTheDocument(); expect(screen.queryByText('Immich')).not.toBeInTheDocument(); }); + + it('FE-JRN-DETWIRE-042: a rejected suggestions preference keeps the local flip and rejects nothing', async () => { + const unhandled = vi.fn(); + process.on('unhandledRejection', unhandled); + try { + const update = vi.spyOn(journeyApi, 'updatePreferences').mockRejectedValue(new Error('offline')); + const { hook } = setup({ isMobile: true }); + + fireEvent.click(screen.getByRole('button', { name: 'journey.skeletons.hide' })); + + expect(hook.setHideSkeletons).toHaveBeenCalledWith(true); + await waitFor(() => expect(update).toHaveBeenCalledWith(7, { hide_skeletons: true })); + await new Promise((resolve) => setTimeout(resolve, 0)); + expect(unhandled).not.toHaveBeenCalled(); + expect(toast.error).not.toHaveBeenCalled(); + } finally { + process.off('unhandledRejection', unhandled); + } + }); });