Files
genshin-assistant/src/features/scan/components/modals/hooks/useScanDetailsModalModel.ts
T
2026-07-07 22:02:24 +02:00

65 lines
2.1 KiB
TypeScript

import { useCallback, type MouseEvent } from "react";
import type { ScanDetailsModalProps } from "../types";
import type { ParsedArtifactCandidate } from "../../../../../lib/artifactOcrParser";
export interface ScanDetailsModalModel {
closeDetails: () => void;
stopPropagation: (event: MouseEvent<HTMLDivElement>) => void;
parsedNotes: string[];
showParsedNotes: boolean;
cropRows: Array<{ id: string; dataUrl: string; label: string; x: number; y: number; width: number; height: number }>;
ocrRows: Array<{ id: string; label: string; confidence: number; text: string }>;
debugText: string;
showCrops: boolean;
showOcr: boolean;
}
interface UseScanDetailsModalModelInput {
setDetailsOpen: ScanDetailsModalProps["setDetailsOpen"];
parsedArtifact: ScanDetailsModalProps["controller"]["parsedArtifact"];
latestCapture: ScanDetailsModalProps["latestCapture"];
}
export function useScanDetailsModalModel({
setDetailsOpen,
parsedArtifact,
latestCapture,
}: UseScanDetailsModalModelInput): ScanDetailsModalModel {
const closeDetails = useCallback(() => setDetailsOpen(false), [setDetailsOpen]);
const stopPropagation = useCallback((event: MouseEvent<HTMLDivElement>) => {
event.stopPropagation();
}, []);
const parsedNotes = (parsedArtifact?.notes ?? []) as ParsedArtifactCandidate["notes"];
const crops = latestCapture?.crops ?? [];
const ocr = latestCapture?.ocr ?? [];
const cropRows = crops
.filter((crop) => Boolean(crop.dataUrl))
.map((crop) => ({
id: crop.id,
dataUrl: crop.dataUrl ?? "",
label: crop.label,
x: crop.rect.x,
y: crop.rect.y,
width: crop.rect.width,
height: crop.rect.height,
}));
return {
closeDetails,
stopPropagation,
parsedNotes,
showParsedNotes: parsedNotes.length > 0,
cropRows,
ocrRows: ocr.map((entry) => ({
id: entry.id,
label: entry.label,
confidence: entry.confidence,
text: entry.text || "No text detected",
})),
debugText: `Debug: crops ${crops.length} / ocr ${ocr.length}`,
showCrops: cropRows.length > 0,
showOcr: ocr.length > 0,
};
}