Files
readest/apps/readest-app/src/__tests__/components/ImageViewer.test.tsx
T
Huang Xin 7128e8964e fix(reader): suppress Android image callout freezing the image viewer (#4425)
Long-pressing an image in the zoom viewer on Android triggers the
WebView's native image callout (context menu / drag / magnifier) at the
same time as the viewer's own pinch/pan/zoom touch handlers, locking up
the whole app until restart. Same root cause as the book-cover freeze
(PR #4345): `-webkit-touch-callout: none` doesn't inherit, so the class
must sit on an ancestor of the `<img>`.

Apply the existing `.no-context-menu` class to the viewer container so
the `.no-context-menu img` rule reaches the zoomed image and disables
the native callout. Harmless on desktop (the property is a no-op there
and right-click-save still works).

Closes #4420

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 17:04:52 +02:00

40 lines
1.4 KiB
TypeScript

import { describe, it, expect, vi, afterEach } from 'vitest';
import { render, cleanup } from '@testing-library/react';
import ImageViewer from '@/app/reader/components/ImageViewer';
vi.mock('@/hooks/useTranslation', () => ({
useTranslation: () => (s: string) => s,
}));
// useKeyDownActions pulls in EnvContext + device store; not under test here.
vi.mock('@/hooks/useKeyDownActions', () => ({
useKeyDownActions: () => {},
}));
// ZoomControls reaches into the theme store and Tauri window APIs; stub it out.
vi.mock('@/app/reader/components/ZoomControls', () => ({
__esModule: true,
default: () => null,
}));
afterEach(cleanup);
const gridInsets = { top: 0, right: 0, bottom: 0, left: 0 };
describe('ImageViewer', () => {
it('suppresses the native image callout on the zoomed image', () => {
// The WebView's native long-press image callout collides with the
// viewer's own pinch/pan handlers on Android and freezes the app. The
// zoomed <img> must live under a `.no-context-menu` ancestor so the
// global `.no-context-menu img { -webkit-touch-callout: none }` rule
// disables that callout. Mirrors the book-cover fix (PR #4345).
const { container } = render(
<ImageViewer src='blob:test-image' onClose={vi.fn()} gridInsets={gridInsets} />,
);
const calloutSafeImage = container.querySelector('.no-context-menu img');
expect(calloutSafeImage).toBeTruthy();
});
});