2026-01-17 10:07:07 +01:00
|
|
|
/**
|
|
|
|
|
* Unresolved link click handler for Reading View and Live Preview.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { App, MarkdownPostProcessorContext, Notice } from "obsidian";
|
|
|
|
|
import type { InterviewConfig } from "../interview/types";
|
|
|
|
|
import { ProfileSelectionModal } from "../ui/ProfileSelectionModal";
|
|
|
|
|
import {
|
|
|
|
|
extractLinkTargetFromAnchor,
|
|
|
|
|
isUnresolvedLink,
|
|
|
|
|
waitForFileModify,
|
|
|
|
|
} from "./linkHelpers";
|
|
|
|
|
import type { MindnetSettings } from "../settings";
|
|
|
|
|
import { TFile } from "obsidian";
|
|
|
|
|
|
|
|
|
|
export interface UnresolvedLinkClickContext {
|
|
|
|
|
mode: "reading" | "live";
|
|
|
|
|
linkText: string;
|
|
|
|
|
sourcePath: string;
|
|
|
|
|
resolved: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Check if bypass modifier is pressed.
|
|
|
|
|
*/
|
|
|
|
|
export function isBypassModifierPressed(
|
|
|
|
|
evt: MouseEvent,
|
|
|
|
|
bypassModifier: "Alt" | "Ctrl" | "Shift" | "None"
|
|
|
|
|
): boolean {
|
|
|
|
|
if (bypassModifier === "None") return false;
|
|
|
|
|
if (bypassModifier === "Alt") return evt.altKey;
|
|
|
|
|
if (bypassModifier === "Ctrl") return evt.ctrlKey || evt.metaKey;
|
|
|
|
|
if (bypassModifier === "Shift") return evt.shiftKey;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Start wizard after note creation, with optional Templater wait.
|
|
|
|
|
*/
|
|
|
|
|
export async function startWizardAfterCreate(
|
|
|
|
|
app: App,
|
|
|
|
|
settings: MindnetSettings,
|
|
|
|
|
file: TFile,
|
|
|
|
|
profile: any,
|
|
|
|
|
content: string,
|
|
|
|
|
isUnresolvedClick: boolean,
|
|
|
|
|
onWizardComplete: (result: any) => void,
|
2026-01-17 10:31:44 +01:00
|
|
|
onWizardSave: (result: any) => void,
|
|
|
|
|
pluginInstance?: { ensureGraphSchemaLoaded?: () => Promise<import("../mapping/graphSchema").GraphSchema | null> }
|
2026-01-17 10:07:07 +01:00
|
|
|
): Promise<void> {
|
|
|
|
|
// Determine if wizard should start
|
|
|
|
|
const shouldStartInterview = isUnresolvedClick
|
|
|
|
|
? (settings.autoStartOnUnresolvedClick || settings.autoStartInterviewOnCreate)
|
|
|
|
|
: settings.autoStartInterviewOnCreate;
|
|
|
|
|
|
|
|
|
|
if (!shouldStartInterview) {
|
|
|
|
|
if (settings.debugLogging) {
|
|
|
|
|
console.log("[Mindnet] Wizard start skipped (settings)");
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Wait for Templater if enabled
|
|
|
|
|
if (settings.waitForFirstModifyAfterCreate) {
|
|
|
|
|
if (settings.debugLogging) {
|
|
|
|
|
console.log(
|
|
|
|
|
`[Mindnet] Waiting for file modify (timeout: ${settings.waitForModifyTimeoutMs}ms)`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const result = await waitForFileModify(
|
|
|
|
|
app,
|
|
|
|
|
file,
|
|
|
|
|
settings.waitForModifyTimeoutMs
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (settings.debugLogging) {
|
|
|
|
|
console.log(`[Mindnet] File modify wait result: ${result}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Reload file content in case Templater modified it
|
|
|
|
|
if (result === "modified") {
|
|
|
|
|
content = await app.vault.read(file);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Start wizard
|
|
|
|
|
try {
|
|
|
|
|
if (settings.debugLogging) {
|
|
|
|
|
console.log("[Mindnet] Starting wizard", {
|
|
|
|
|
profileKey: profile.key,
|
|
|
|
|
file: file.path,
|
|
|
|
|
wizardStartReason: isUnresolvedClick
|
|
|
|
|
? settings.autoStartOnUnresolvedClick
|
|
|
|
|
? "autoStartOnUnresolvedClick"
|
|
|
|
|
: "autoStartInterviewOnCreate"
|
|
|
|
|
: "autoStartInterviewOnCreate",
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const { InterviewWizardModal } = await import("../ui/InterviewWizardModal");
|
|
|
|
|
new InterviewWizardModal(
|
|
|
|
|
app,
|
|
|
|
|
profile,
|
|
|
|
|
file,
|
|
|
|
|
content,
|
|
|
|
|
onWizardComplete,
|
2026-01-17 10:31:44 +01:00
|
|
|
onWizardSave,
|
|
|
|
|
settings, // Pass settings for post-run edging
|
|
|
|
|
pluginInstance // Pass plugin instance for graph schema loading
|
2026-01-17 10:07:07 +01:00
|
|
|
).open();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
const msg = e instanceof Error ? e.message : String(e);
|
|
|
|
|
new Notice(`Failed to start interview wizard: ${msg}`);
|
|
|
|
|
console.error("[Mindnet] Failed to start wizard:", e);
|
|
|
|
|
}
|
|
|
|
|
}
|