241 lines
6.9 KiB
TypeScript
241 lines
6.9 KiB
TypeScript
import { getAssistantBridge } from "../../services/assistantBridge";
|
|
import {
|
|
type ArtifactRepositoryPort,
|
|
type AutomationRepositoryPort,
|
|
type CaptureRepositoryPort,
|
|
type RendererRepositories,
|
|
type RuntimeRepositoryPort,
|
|
type ReviewSampleRepositoryPort,
|
|
type LearningRepositoryPort,
|
|
type SnapshotRepositoryPort,
|
|
type OverlayRepositoryPort,
|
|
type ScanExportPort,
|
|
} from "./rendererBridgeRepositoryTypes";
|
|
import type { AppSnapshot } from "../../types/domain";
|
|
import type {
|
|
ArtifactStoreLoadResult,
|
|
ArtifactStoreSaveResult,
|
|
LoadScannerLearningRulesResult,
|
|
BooleanResult,
|
|
CaptureSourceInfo,
|
|
FocusGenshinResult,
|
|
RuntimeInfo,
|
|
SaveResultWithPath,
|
|
ScrollResult,
|
|
KeyPressResult,
|
|
AutomationGuard,
|
|
ClickResult,
|
|
ReviewSampleListResult,
|
|
SaveScannerLearningRulesResult,
|
|
GoodImportFileResult,
|
|
} from "../../types/global";
|
|
|
|
const EMPTY_SNAPSHOT: AppSnapshot | null = null;
|
|
const EMPTY_CAPTURE_SOURCE_LIST: CaptureSourceInfo[] = [];
|
|
const EMPTY_SAVE_RESULT: SaveResultWithPath = { ok: false, path: "" };
|
|
const EMPTY_RUNTIME_INFO: RuntimeInfo = {
|
|
ok: false,
|
|
isElevated: false,
|
|
platform: "unknown",
|
|
};
|
|
const EMPTY_ARTIFACT_STORE_LOAD_RESULT: ArtifactStoreLoadResult = {
|
|
ok: false,
|
|
artifacts: [],
|
|
total: 0,
|
|
path: "",
|
|
};
|
|
const EMPTY_ARTIFACT_STORE_SAVE_RESULT: ArtifactStoreSaveResult = {
|
|
ok: false,
|
|
added: 0,
|
|
updated: 0,
|
|
total: 0,
|
|
path: "",
|
|
};
|
|
const EMPTY_REVIEW_SAMPLES_RESULT: ReviewSampleListResult = {
|
|
ok: false,
|
|
samples: [],
|
|
total: 0,
|
|
path: "",
|
|
};
|
|
const EMPTY_SCANNER_LEARNING_RULES_RESULT: LoadScannerLearningRulesResult = {
|
|
ok: false,
|
|
path: "",
|
|
rules: {},
|
|
};
|
|
const EMPTY_SCAN_STATUS_RESULT: SaveResultWithPath = { ok: false, path: "" };
|
|
const EMPTY_SAVE_RULES_RESULT: SaveScannerLearningRulesResult = {
|
|
ok: false,
|
|
path: "",
|
|
rules: {},
|
|
total: 0,
|
|
};
|
|
const EMPTY_GOOD_IMPORT_FILE_RESULT: GoodImportFileResult = {
|
|
ok: false,
|
|
canceled: false,
|
|
path: "",
|
|
error: "Electron bridge unavailable.",
|
|
};
|
|
|
|
async function createBridgeSafeCall<TResult>(
|
|
callback: () => Promise<TResult> | TResult | null | undefined,
|
|
fallback: TResult,
|
|
): Promise<TResult> {
|
|
try {
|
|
const result = await callback();
|
|
return result == null ? fallback : result;
|
|
} catch {
|
|
return fallback;
|
|
}
|
|
}
|
|
|
|
function emptyAutomationGuard(): AutomationGuard {
|
|
return { ok: false, escapePressed: false };
|
|
}
|
|
|
|
function emptyFocusGenshinResult(): FocusGenshinResult {
|
|
return { focused: false, alreadyForeground: false };
|
|
}
|
|
|
|
function emptyClickResult(): ClickResult {
|
|
return {
|
|
ok: false,
|
|
x: 0,
|
|
y: 0,
|
|
clicked: false,
|
|
moved: false,
|
|
focused: false,
|
|
inputBlocked: false,
|
|
};
|
|
}
|
|
|
|
function emptyScrollResult(): ScrollResult {
|
|
return { ok: false, notchesSent: 0, inputBlocked: false };
|
|
}
|
|
|
|
function emptyKeyPressResult(key = ""): KeyPressResult {
|
|
return { ok: false, key, inputBlocked: false, eventsSent: 0 };
|
|
}
|
|
|
|
function emptyBooleanResult(): BooleanResult {
|
|
return { ok: false };
|
|
}
|
|
|
|
export function createRendererRepositories(): RendererRepositories | null {
|
|
const bridge = getAssistantBridge();
|
|
if (!bridge) return null;
|
|
|
|
const artifactRepo: ArtifactRepositoryPort = {
|
|
loadAll: () =>
|
|
createBridgeSafeCall(
|
|
() => bridge.loadArtifacts(),
|
|
EMPTY_ARTIFACT_STORE_LOAD_RESULT,
|
|
),
|
|
saveMany: (records) =>
|
|
createBridgeSafeCall(
|
|
() => bridge.saveArtifacts(records),
|
|
EMPTY_ARTIFACT_STORE_SAVE_RESULT,
|
|
),
|
|
};
|
|
|
|
const captureRepo: CaptureRepositoryPort = {
|
|
listSources: () => createBridgeSafeCall(() => bridge.listCaptureSources(), EMPTY_CAPTURE_SOURCE_LIST),
|
|
captureSource: (sourceId, delayMs, focusGenshin, options) =>
|
|
bridge.captureSource(sourceId, delayMs, focusGenshin, options),
|
|
};
|
|
|
|
const runtimeRepo: RuntimeRepositoryPort = {
|
|
getRuntimeInfo: () =>
|
|
createBridgeSafeCall(
|
|
() => bridge.getRuntimeInfo(),
|
|
EMPTY_RUNTIME_INFO,
|
|
),
|
|
};
|
|
|
|
const reviewSamplesRepo: ReviewSampleRepositoryPort = {
|
|
loadSamples: (limit = 50) =>
|
|
createBridgeSafeCall(
|
|
() => bridge.loadReviewSamples(limit),
|
|
EMPTY_REVIEW_SAMPLES_RESULT,
|
|
),
|
|
saveSample: (sample) =>
|
|
createBridgeSafeCall(
|
|
() => bridge.saveReviewSample(sample),
|
|
EMPTY_SCAN_STATUS_RESULT,
|
|
),
|
|
};
|
|
|
|
const learningRepo: LearningRepositoryPort = {
|
|
loadRules: () =>
|
|
createBridgeSafeCall(
|
|
() => bridge.loadScannerLearningRules(),
|
|
EMPTY_SCANNER_LEARNING_RULES_RESULT,
|
|
),
|
|
saveRules: (rules) =>
|
|
createBridgeSafeCall(
|
|
() => bridge.saveScannerLearningRules(rules),
|
|
EMPTY_SAVE_RULES_RESULT,
|
|
),
|
|
};
|
|
|
|
const snapshotRepo: SnapshotRepositoryPort = {
|
|
load: () => createBridgeSafeCall(() => bridge.loadSnapshot(), EMPTY_SNAPSHOT),
|
|
save: (snapshot) => createBridgeSafeCall(() => bridge.saveSnapshot(snapshot), EMPTY_SAVE_RESULT),
|
|
runMockScan: () => createBridgeSafeCall(() => bridge.runMockScan(), EMPTY_SNAPSHOT),
|
|
publishScannerStatus: (status) =>
|
|
createBridgeSafeCall(() => bridge.publishScannerStatus(status), EMPTY_SCAN_STATUS_RESULT),
|
|
};
|
|
|
|
const automationRepo: AutomationRepositoryPort = {
|
|
getAutomationGuard: () =>
|
|
createBridgeSafeCall(
|
|
() => bridge.getAutomationGuard(),
|
|
emptyAutomationGuard(),
|
|
),
|
|
focusGenshinForScanStart: () =>
|
|
createBridgeSafeCall(
|
|
() =>
|
|
typeof bridge.focusGenshinForScanStart === "function"
|
|
? bridge.focusGenshinForScanStart()
|
|
: bridge.focusGenshin(),
|
|
emptyFocusGenshinResult(),
|
|
),
|
|
focusGenshin: () =>
|
|
createBridgeSafeCall(
|
|
() => bridge.focusGenshin(),
|
|
emptyFocusGenshinResult(),
|
|
),
|
|
focusMainWindow: () => createBridgeSafeCall(() => bridge.focusMainWindow(), emptyBooleanResult()),
|
|
clickScreen: (x, y) => createBridgeSafeCall(() => bridge.clickScreen(x, y), emptyClickResult()),
|
|
scrollScreen: (notches, anchorX, anchorY) =>
|
|
createBridgeSafeCall(() => bridge.scrollScreen(notches, anchorX, anchorY), emptyScrollResult()),
|
|
keyPress: (key) => createBridgeSafeCall(() => bridge.keyPress(key), emptyKeyPressResult(key)),
|
|
onCommand: bridge.onScannerCommand,
|
|
};
|
|
|
|
const overlayRepo: OverlayRepositoryPort = {
|
|
show: () => createBridgeSafeCall(() => bridge.showOverlay(), emptyBooleanResult()),
|
|
};
|
|
|
|
const exportRepo: ScanExportPort = {
|
|
exportGood: (payload) => createBridgeSafeCall(() => bridge.exportGood(payload), EMPTY_SAVE_RESULT),
|
|
importGoodFile: () => createBridgeSafeCall(() => bridge.importGoodFile(), EMPTY_GOOD_IMPORT_FILE_RESULT),
|
|
};
|
|
|
|
return {
|
|
artifacts: artifactRepo,
|
|
capture: captureRepo,
|
|
runtime: runtimeRepo,
|
|
reviewSamples: reviewSamplesRepo,
|
|
learning: learningRepo,
|
|
snapshot: snapshotRepo,
|
|
automation: automationRepo,
|
|
overlay: overlayRepo,
|
|
export: exportRepo,
|
|
canExportGood: bridge.canExportGood,
|
|
canShowOverlay: bridge.canShowOverlay,
|
|
canAutoScan: bridge.canAutoScan,
|
|
canReviewSamples: bridge.canReviewSamples,
|
|
isAvailable: true,
|
|
};
|
|
}
|