fix(scanner): satisfy react-hooks/immutability and jsdom ResizeObserver in tests
- Move disambiguation-cancel tracker reset into useCameraScanner's new resetTrackedCard(cardId) (immutable map + setTrackedCards), wired via onTrackerReset — the identification hook no longer mutates state-derived objects, clearing the blocking react-hooks/immutability lint error. - Stub ResizeObserver in test/setup.js so ScannerCamera's workstation tests render under jsdom. - Drop unused eslint-disable directive in CollectionsPageView. npm run lint: 0 problems; vitest 231/231.
This commit is contained in:
parent
6fab22d315
commit
ca3b8a78c2
5 changed files with 24 additions and 5 deletions
|
|
@ -1,4 +1,3 @@
|
|||
/* eslint-disable @next/next/no-img-element -- External or generated image URLs; next/image migration is out of scope. */
|
||||
import Link from 'next/link';
|
||||
import PermissionIndicator from './PermissionIndicator';
|
||||
import { VOCAB, collectionDisplayName } from '../lib/collection-vocabulary.js';
|
||||
|
|
|
|||
|
|
@ -176,6 +176,16 @@ export function useCameraScanner({
|
|||
setTrackedCards(next);
|
||||
}, []);
|
||||
|
||||
const resetTrackedCard = useCallback((cardId) => {
|
||||
const next = trackedCardsRef.current.map((card) => (
|
||||
card.id === cardId
|
||||
? { ...card, status: 'detecting', scanAttempts: 0, negativeAt: undefined }
|
||||
: card
|
||||
));
|
||||
trackedCardsRef.current = next;
|
||||
setTrackedCards(next);
|
||||
}, []);
|
||||
|
||||
const resetScanTrackers = useCallback(() => {
|
||||
trackedCardsRef.current = [];
|
||||
setTrackedCards([]);
|
||||
|
|
@ -429,6 +439,7 @@ export function useCameraScanner({
|
|||
startCamera,
|
||||
stopCamera,
|
||||
removeTrackedCard,
|
||||
resetTrackedCard,
|
||||
resetScanTrackers,
|
||||
triggerManualScan,
|
||||
streamRef,
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ export function useScannerIdentification({
|
|||
onCardScanned,
|
||||
onError,
|
||||
onTrackerComplete,
|
||||
onTrackerReset,
|
||||
videoRef,
|
||||
canvasRef,
|
||||
onVerifyCardRef,
|
||||
|
|
@ -118,10 +119,9 @@ export function useScannerIdentification({
|
|||
};
|
||||
|
||||
const cancelDisambiguation = () => {
|
||||
if (disambiguation?.cardTracker) {
|
||||
disambiguation.cardTracker.status = 'detecting';
|
||||
disambiguation.cardTracker.scanAttempts = 0;
|
||||
disambiguation.cardTracker.negativeAt = undefined;
|
||||
const { cardTracker } = disambiguation ?? {};
|
||||
if (cardTracker) {
|
||||
onTrackerReset?.(cardTracker.id);
|
||||
}
|
||||
setDisambiguation(null);
|
||||
disambiguationRefineRef.current = null;
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ export default function Scanner() {
|
|||
onCardScanned: queue.handleCardScanned,
|
||||
onError: (msg) => console.error('Identification error:', msg),
|
||||
onTrackerComplete: camera.removeTrackedCard,
|
||||
onTrackerReset: camera.resetTrackedCard,
|
||||
videoRef: camera.videoRef,
|
||||
canvasRef: camera.canvasRef,
|
||||
onVerifyCardRef,
|
||||
|
|
|
|||
|
|
@ -1,2 +1,10 @@
|
|||
process.env.JWT_SECRET = 'test-secret-for-vitest-only-do-not-use-in-prod';
|
||||
process.env.NODE_ENV = 'test';
|
||||
|
||||
if (!globalThis.ResizeObserver) {
|
||||
globalThis.ResizeObserver = class ResizeObserver {
|
||||
observe() {}
|
||||
unobserve() {}
|
||||
disconnect() {}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue