import { MarkdownView, Platform, Plugin, WorkspaceLeaf } from "obsidian"; import { VIEW_TYPE_PROJECT_VIEW, VIEW_TYPE_PROJECT_DETAILS_VIEW, VIEW_TYPE_COLLECTION_VIEW, RIBBON_ICON, } from "./src/const"; import { ProjectView } from "./src/views/ProjectView"; import { ProjectDetailsView } from "./src/views/ProjectDetailsView"; import { CollectionView } from "./src/views/CollectionView"; import { parseProjectFilePath } from "./src/fs"; import { BreadcrumbSegment, injectMobileBreadcrumb } from "./src/ui"; export default class ProjektkontextPlugin extends Plugin { async onload(): Promise { this.registerView(VIEW_TYPE_PROJECT_VIEW, (leaf) => new ProjectView(leaf)); this.registerView(VIEW_TYPE_PROJECT_DETAILS_VIEW, (leaf) => new ProjectDetailsView(leaf)); this.registerView(VIEW_TYPE_COLLECTION_VIEW, (leaf) => new CollectionView(leaf)); this.registerObsidianProtocolHandler("projektkontext", async (params) => { const project = params.project; if (!project) { await this.activateProjectView(); return; } const leaf = this.app.workspace.getLeaf(false); await leaf.setViewState({ type: VIEW_TYPE_PROJECT_DETAILS_VIEW, active: true, state: { project }, }); this.app.workspace.revealLeaf(leaf); }); this.addRibbonIcon(RIBBON_ICON, "Projekte", () => { void this.activateProjectView(); }); this.addCommand({ id: "open-projects", name: "Projekte öffnen", callback: () => void this.activateProjectView(), }); if (Platform.isMobile) { const reattach = () => this.reattachMobileBreadcrumbs(); this.registerEvent( this.app.workspace.on("file-open", () => requestAnimationFrame(reattach)), ); this.registerEvent( this.app.workspace.on("active-leaf-change", () => requestAnimationFrame(reattach)), ); this.registerEvent(this.app.workspace.on("layout-change", reattach)); } } async onunload(): Promise {} async activateProjectView(): Promise { const { workspace } = this.app; let leaf: WorkspaceLeaf | null = workspace.getLeavesOfType(VIEW_TYPE_PROJECT_VIEW)[0] ?? null; if (!leaf) { leaf = workspace.getLeaf(false); await leaf.setViewState({ type: VIEW_TYPE_PROJECT_VIEW, active: true }); } workspace.revealLeaf(leaf); } private reattachMobileBreadcrumbs(): void { this.app.workspace.iterateRootLeaves((leaf) => this.applyMobileBreadcrumb(leaf)); } private applyMobileBreadcrumb(leaf: WorkspaceLeaf): void { const view = leaf.view; if (!(view instanceof MarkdownView)) return; const file = view.file; if (!file) { injectMobileBreadcrumb(view, []); return; } const loc = parseProjectFilePath(file.path); if (!loc) { injectMobileBreadcrumb(view, []); return; } const segments: BreadcrumbSegment[] = [ { label: "Projekte", onClick: () => void leaf.setViewState({ type: VIEW_TYPE_PROJECT_VIEW, active: true }), }, { label: loc.project, onClick: () => void leaf.setViewState({ type: VIEW_TYPE_PROJECT_DETAILS_VIEW, active: true, state: { project: loc.project }, }), }, ]; if (loc.collection) { segments.push({ label: loc.collection, onClick: () => void leaf.setViewState({ type: VIEW_TYPE_COLLECTION_VIEW, active: true, state: { project: loc.project, collection: loc.collection, zone: loc.zone }, }), }); } segments.push({ label: file.basename }); injectMobileBreadcrumb(view, segments); } }