Added pinch/zoom/drag for the photo viewer using @use-gesture/react + @react-spring/web, with swipe navigation only

when not zoomed and double‑tap/double‑click to toggle zoom. I also added a guest haptics toggle in settings (sheet
  + /settings) backed by localStorage.
This commit is contained in:
Codex Agent
2025-12-27 14:11:13 +01:00
parent fa5a1fa367
commit 1a48c9458e
3 changed files with 268 additions and 47 deletions

View File

@@ -0,0 +1,56 @@
import React from 'react';
import { fireEvent, render, screen } from '@testing-library/react';
import { beforeAll, vi } from 'vitest';
import { MemoryRouter } from 'react-router-dom';
import PhotoLightbox from '../PhotoLightbox';
import { EventBrandingProvider } from '../../context/EventBrandingContext';
import { LocaleProvider } from '../../i18n/LocaleContext';
import { ToastProvider } from '../../components/ToastHost';
const photo = {
id: 1,
file_path: '/test.jpg',
likes_count: 0,
};
describe('PhotoLightbox zoom gestures', () => {
beforeAll(() => {
if (!window.matchMedia) {
Object.defineProperty(window, 'matchMedia', {
configurable: true,
value: vi.fn().mockReturnValue({
matches: false,
addListener: vi.fn(),
removeListener: vi.fn(),
addEventListener: vi.fn(),
removeEventListener: vi.fn(),
dispatchEvent: vi.fn(),
}),
});
}
});
it('toggles zoom state on double click', () => {
render(
<MemoryRouter>
<LocaleProvider>
<EventBrandingProvider>
<ToastProvider>
<PhotoLightbox photos={[photo]} currentIndex={0} token="event-token" />
</ToastProvider>
</EventBrandingProvider>
</LocaleProvider>
</MemoryRouter>
);
const zoomSurface = screen.getByTestId('lightbox-zoom');
const container = zoomSurface.closest('[data-zoomed]');
expect(container).toHaveAttribute('data-zoomed', 'false');
fireEvent.doubleClick(zoomSurface);
expect(container).toHaveAttribute('data-zoomed', 'true');
fireEvent.doubleClick(zoomSurface);
expect(container).toHaveAttribute('data-zoomed', 'false');
});
});