chore: initialize repository baseline
Import the existing Electron + React + TypeScript app as the version-control baseline before the scanner rework (C# input/capture sidecar, resolution-anchored layout profiles, OCR preprocessing, eval harness, rescan-merge, GOOD interop). Housekeeping in this commit: - Remove orphaned temp_inputhelper_block.ts (duplicate of the input-helper script). - Ignore .claude/scheduled_tasks.lock local session state. - Add .gitattributes to normalize line endings (LF in repo). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
import { detailFingerprint } from "../../../../lib/autoScanLoop";
|
||||
import { sourceVersion } from "../../../../lib/genshinData";
|
||||
import { useCallback, useMemo, type MouseEvent } from "react";
|
||||
import type { ScanDiagnosticsModalProps } from "../types";
|
||||
|
||||
export interface ScanDiagnosticsModelProgress {
|
||||
width: number;
|
||||
show: boolean;
|
||||
}
|
||||
|
||||
export interface ScanDiagnosticsModalModel {
|
||||
closeDiagnostics: () => void;
|
||||
openDetails: () => void;
|
||||
handleSaveReviewSample: () => void;
|
||||
stopPropagation: (event: MouseEvent<HTMLDivElement>) => void;
|
||||
canOpenDetails: boolean;
|
||||
statusTitle: string;
|
||||
rightsClassName: string;
|
||||
rightsValue: string;
|
||||
genshinClassName: string;
|
||||
genshinValue: string;
|
||||
shouldShowAdminBanner: boolean;
|
||||
gridSourceClass: string;
|
||||
gridMainValue: string;
|
||||
gridMetaValue: string;
|
||||
learningRulesText: string;
|
||||
learningRulesSubtext: string;
|
||||
autoScanModeLabel: string;
|
||||
fingerprintText: string;
|
||||
runtimeRows: string[];
|
||||
scanLimitText: string;
|
||||
scanTipText: string;
|
||||
autoScanStatsLines: Array<{ label: string; value: number }>;
|
||||
playerProgress: ScanDiagnosticsModelProgress;
|
||||
autoScanRunning: boolean;
|
||||
showDevRows: boolean;
|
||||
reviewStatus: string;
|
||||
automationLogLines: string[];
|
||||
canSaveReviewSample: boolean;
|
||||
}
|
||||
|
||||
interface UseScanDiagnosticsModalModelInput extends Pick<
|
||||
ScanDiagnosticsModalProps,
|
||||
| "setDetailsOpen"
|
||||
| "setDiagnosticsOpen"
|
||||
| "saveReviewSample"
|
||||
| "canSaveReviewSample"
|
||||
| "latestCapture"
|
||||
| "controller"
|
||||
> {
|
||||
captureStatus: string;
|
||||
}
|
||||
|
||||
export function useScanDiagnosticsModalModel({
|
||||
setDetailsOpen,
|
||||
setDiagnosticsOpen,
|
||||
saveReviewSample,
|
||||
canSaveReviewSample,
|
||||
latestCapture,
|
||||
controller,
|
||||
captureStatus,
|
||||
}: UseScanDiagnosticsModalModelInput): ScanDiagnosticsModalModel {
|
||||
const closeDiagnostics = useCallback(() => setDiagnosticsOpen(false), [setDiagnosticsOpen]);
|
||||
const openDetails = useCallback(() => setDetailsOpen(true), [setDetailsOpen]);
|
||||
const handleSaveReviewSample = useCallback(() => {
|
||||
if (canSaveReviewSample && controller.parsedArtifact) {
|
||||
void saveReviewSample();
|
||||
}
|
||||
}, [canSaveReviewSample, controller.parsedArtifact, saveReviewSample]);
|
||||
const stopPropagation = useCallback((event: MouseEvent<HTMLDivElement>) => {
|
||||
event.stopPropagation();
|
||||
}, []);
|
||||
|
||||
const canOpenDetails = Boolean(latestCapture?.crops?.length || latestCapture?.ocr?.length);
|
||||
const shouldShowAdminBanner = !controller.runtimeInfo?.isElevated;
|
||||
const rightsClassName = controller.runtimeInfo?.isElevated ? "ok" : "blocked";
|
||||
const rightsValue = controller.runtimeInfo?.isElevated ? "Admin" : "Standard";
|
||||
const genshinClassName = controller.runtimeInfo?.genshinFound ? "ok" : "neutral";
|
||||
const genshinValue = controller.runtimeInfo?.genshinFound ? "Gefunden" : "Nicht gefunden";
|
||||
const statusTitle = controller.devMode ? "Dev-Ausgabe kompakt" : "Dev-Ausgabe erweitern";
|
||||
const autoScanModeLabel = controller.autoScanRunning ? "Scan active" : "Last scan";
|
||||
|
||||
const inventoryGrid = latestCapture?.inventoryGrid;
|
||||
const gridSourceClass = inventoryGrid?.source ?? "missing";
|
||||
const gridMainValue = inventoryGrid
|
||||
? inventoryGrid?.source === "missing"
|
||||
? "not detected"
|
||||
: `${inventoryGrid?.cols} x ${inventoryGrid?.rows}`
|
||||
: "waiting";
|
||||
const gridMetaValue = inventoryGrid
|
||||
? `${inventoryGrid?.confidence}% confidence - ${inventoryGrid?.centers.length} click targets`
|
||||
: "Run a capture once while the artifact inventory is visible.";
|
||||
|
||||
const learningRulesText = controller.learningRulesLoaded ? `${controller.learningRuleCount} local rules` : "loading";
|
||||
const learningRulesSubtext = `Review samples feed deterministic OCR fixes before each new parse. Data package: ${sourceVersion}`;
|
||||
|
||||
const playerProgress = useMemo(() => {
|
||||
const width = Math.min(
|
||||
100,
|
||||
controller.autoScanStats.attempted > 0
|
||||
? Math.round((controller.autoScanStats.verified / Math.max(1, controller.autoScanStats.attempted)) * 100)
|
||||
: 0,
|
||||
);
|
||||
const show = controller.autoScanRunning || controller.autoScanStats.clicked > 0 || controller.autoScanStats.parsed > 0;
|
||||
return { width, show };
|
||||
}, [
|
||||
controller.autoScanRunning,
|
||||
controller.autoScanStats.attempted,
|
||||
controller.autoScanStats.clicked,
|
||||
controller.autoScanStats.parsed,
|
||||
controller.autoScanStats.verified,
|
||||
]);
|
||||
|
||||
const autoScanStatsLines = useMemo(
|
||||
() => [
|
||||
{ label: "clicked", value: controller.autoScanStats.clicked },
|
||||
{ label: "attempted", value: controller.autoScanStats.attempted },
|
||||
{ label: "verified", value: controller.autoScanStats.verified },
|
||||
{ label: "parsed", value: controller.autoScanStats.parsed },
|
||||
{ label: "stored", value: controller.autoScanStats.stored },
|
||||
{ label: "review", value: controller.autoScanStats.review },
|
||||
{ label: "duplicates", value: controller.autoScanStats.duplicates },
|
||||
{ label: "misses", value: controller.autoScanStats.misses },
|
||||
{ label: "pages", value: controller.autoScanStats.pages },
|
||||
],
|
||||
[
|
||||
controller.autoScanStats.clicked,
|
||||
controller.autoScanStats.attempted,
|
||||
controller.autoScanStats.verified,
|
||||
controller.autoScanStats.parsed,
|
||||
controller.autoScanStats.stored,
|
||||
controller.autoScanStats.review,
|
||||
controller.autoScanStats.duplicates,
|
||||
controller.autoScanStats.misses,
|
||||
controller.autoScanStats.pages,
|
||||
],
|
||||
);
|
||||
|
||||
const runtimeRows = useMemo(() => {
|
||||
const selectedSourceLabel = controller.selectedSource
|
||||
? `Selected: ${controller.selectedSource.name}`
|
||||
: "No source selected";
|
||||
const storedTotalLabel = controller.storedTotal !== null ? `DB: ${controller.storedTotal} Artifacts` : "DB: -";
|
||||
const runtime = controller.runtimeInfo
|
||||
? `${controller.runtimeInfo?.isElevated ? "admin" : "standard"} - target ${controller.runtimeInfo?.genshinFound ? controller.runtimeInfo?.targetProcess || "Genshin" : "missing"} - fg ${controller.runtimeInfo?.foregroundProcess || "unknown"}`
|
||||
: "unknown";
|
||||
|
||||
return [selectedSourceLabel, storedTotalLabel, runtime, captureStatus, controller.reviewStatus].filter(Boolean);
|
||||
}, [controller.selectedSource, controller.storedTotal, controller.runtimeInfo, captureStatus, controller.reviewStatus]);
|
||||
|
||||
const fingerprintText = latestCapture ? detailFingerprint(latestCapture) : "--";
|
||||
const scanLimitText = controller.scanLimit ? `Scan-Limit: ${controller.scanLimit}` : "Keine Limitinfo.";
|
||||
const scanTipText = "Tip: Die Auto-Scan Logik bleibt aktivierbar, aber Dev-Ansicht ist rein informativ.";
|
||||
|
||||
return {
|
||||
closeDiagnostics,
|
||||
openDetails,
|
||||
handleSaveReviewSample,
|
||||
stopPropagation,
|
||||
canOpenDetails,
|
||||
statusTitle,
|
||||
rightsClassName,
|
||||
rightsValue,
|
||||
genshinClassName,
|
||||
genshinValue,
|
||||
shouldShowAdminBanner,
|
||||
gridSourceClass,
|
||||
gridMainValue,
|
||||
gridMetaValue,
|
||||
learningRulesText,
|
||||
learningRulesSubtext,
|
||||
autoScanModeLabel,
|
||||
fingerprintText,
|
||||
runtimeRows,
|
||||
scanLimitText,
|
||||
scanTipText,
|
||||
autoScanStatsLines,
|
||||
playerProgress,
|
||||
autoScanRunning: controller.autoScanRunning,
|
||||
showDevRows: controller.devMode,
|
||||
reviewStatus: controller.reviewStatus,
|
||||
automationLogLines: controller.automationLog,
|
||||
canSaveReviewSample: canSaveReviewSample && Boolean(controller.parsedArtifact),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user