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:
AzuTear
2026-07-05 20:31:01 +02:00
commit e76d88e0c7
147 changed files with 26220 additions and 0 deletions
@@ -0,0 +1,143 @@
import { useCallback, useMemo } from "react";
import type { ChangeEvent } from "react";
import type { ScanTopControlsSectionProps } from "../types";
export interface ScanTopControlsModel {
shouldShowGenshinSourceButton: boolean;
bridgeDisabled: boolean;
canStartAutoScan: boolean;
canStartManualScan: boolean;
canCaptureSingle: boolean;
handleSourceChange: (event: ChangeEvent<HTMLSelectElement>) => void;
selectGenshinSource: () => void;
openSettings: () => void;
openDiagnostics: () => void;
captureSingleArtifact: () => void;
stopScan: () => void;
runVisibleGridScan: () => void;
runAutoReviewScan: () => void;
bridgeStatusText: string;
bridgePillClass: string;
runtimeStatusText: string;
runtimePillClass: string;
playerStatusText: string;
autoScanButtonTitle: string;
autoScanButtonLabel: string;
manualScanButtonTitle: string;
captureSingleButtonTitle: string;
refreshCaptureSourcesTitle: string;
diagnosticsButtonTitle: string;
scanSetupButtonTitle: string;
showPlayerProgress: boolean;
progressWidth: number;
progressStats: Array<{ label: string; value: number | string; extraClass?: string }>;
}
export function useScanTopControlsModel({
captureSources,
selectedSourceId,
setSelectedSourceId,
captureSelectedSource,
bridgeReady,
isScanning,
controller,
}: ScanTopControlsSectionProps): ScanTopControlsModel {
const {
setSettingsOpen,
setDiagnosticsOpen,
requestScanStop,
runVisibleGridScan,
runAutoReviewScan,
autoScanRunning,
canCaptureSource,
canAutoScan,
hasSourceSelected,
requiresAdminForAutoScan,
reviewStatus,
runtimeInfo,
autoScanStats,
storedTotal,
scanProgressPercent,
genshinSource,
} = controller;
const handleSourceChange = useCallback(
(event: ChangeEvent<HTMLSelectElement>) => setSelectedSourceId(event.target.value),
[setSelectedSourceId],
);
const selectGenshinSource = useCallback(() => {
if (genshinSource) {
setSelectedSourceId(genshinSource.id);
}
}, [genshinSource, setSelectedSourceId]);
const openSettings = useCallback(() => setSettingsOpen(true), [setSettingsOpen]);
const openDiagnostics = useCallback(() => setDiagnosticsOpen(true), [setDiagnosticsOpen]);
const captureSingleArtifact = useCallback(() => captureSelectedSource(0, true), [captureSelectedSource]);
const stopScan = useCallback(() => requestScanStop("Stop-Button gedrueckt."), [requestScanStop]);
const bridgeStatusText = bridgeReady ? "Bridge verbunden" : "Bridge fehlt";
const bridgePillClass = bridgeReady ? "elevated" : "standard";
const runtimeStatusText = runtimeInfo?.isElevated ? "Admin bereit" : "Standard";
const runtimePillClass = runtimeInfo?.isElevated ? "elevated" : "standard";
const playerStatusText = reviewStatus
|| (runtimeInfo?.isElevated
? "App laeuft als Administrator. Oeffne in Genshin das Artifact-Inventar und starte den Auto-Scan."
: "App laeuft im Standard-Modus - Auto-Scan braucht Administrator-Rechte. Bitte die App schliessen und als Administrator neu starten.");
const autoScanButtonTitle = requiresAdminForAutoScan
? "App laeuft nicht als Administrator. Bitte die App als Administrator neu starten."
: "Klickt und scrollt automatisch durch das sichtbare Artifact-Inventar.";
const autoScanButtonLabel = autoScanRunning ? "Scan laeuft..." : "Auto-Scan starten";
const manualScanButtonTitle = "Du klickst die Artifacts in Genshin selbst an; die App liest nur mit. Kein Auto-Klick, kein Scrollen.";
const captureSingleButtonTitle = "Liest das gerade in Genshin geoeffnete Artifact einmalig.";
const refreshCaptureSourcesTitle = "Fenster- und Bildschirmquellen neu suchen";
const diagnosticsButtonTitle = bridgeReady
? "Scanner Diagnose oeffnen: Rechte, Grid-Erkennung und Logs."
: "Scanner Diagnose ist nur in der Electron-App vollstaendig nutzbar.";
const scanSetupButtonTitle = bridgeReady
? "Scan-Ziel, Skip-Zeilen und Operator-Optionen anpassen."
: "Scan-Setup ist nur in der Electron-App vollstaendig nutzbar.";
const showPlayerProgress = autoScanRunning || autoScanStats.clicked > 0 || autoScanStats.parsed > 0;
const progressStats = useMemo(
() => [
{ label: "Klicks", value: autoScanStats.clicked },
{ label: "Positionen", value: autoScanStats.attempted },
{ label: "Verifiziert", value: autoScanStats.verified },
{ label: "Gespeichert", value: autoScanStats.stored },
{ label: "Review", value: autoScanStats.review },
{ label: "Sammlung", value: storedTotal ?? "-", extraClass: "collection" },
],
[autoScanStats.clicked, autoScanStats.attempted, autoScanStats.verified, autoScanStats.stored, autoScanStats.review, storedTotal],
);
return {
shouldShowGenshinSourceButton: Boolean(genshinSource && selectedSourceId !== genshinSource.id),
bridgeDisabled: !bridgeReady || captureSources.length === 0,
canStartAutoScan: hasSourceSelected && !isScanning && !autoScanRunning && canAutoScan && !requiresAdminForAutoScan,
canStartManualScan: hasSourceSelected && !isScanning && !autoScanRunning && canCaptureSource,
canCaptureSingle: hasSourceSelected && !isScanning && !autoScanRunning && canCaptureSource,
handleSourceChange,
selectGenshinSource,
openSettings,
openDiagnostics,
captureSingleArtifact,
stopScan,
runVisibleGridScan,
runAutoReviewScan,
bridgeStatusText,
bridgePillClass,
runtimeStatusText,
runtimePillClass,
playerStatusText,
autoScanButtonTitle,
autoScanButtonLabel,
manualScanButtonTitle,
captureSingleButtonTitle,
refreshCaptureSourcesTitle,
diagnosticsButtonTitle,
scanSetupButtonTitle,
showPlayerProgress,
progressWidth: scanProgressPercent,
progressStats,
};
}