import { MarkdownView, Platform, Plugin, WorkspaceLeaf } from "obsidian"; import { VIEW_TYPE_PROJECTS, VIEW_TYPE_OVERVIEW, VIEW_TYPE_DETAILS, RIBBON_ICON, } from "./src/const"; import { ProjectsView } from "./src/views/ProjectsView"; import { OverviewView } from "./src/views/OverviewView"; import { DetailsView } from "./src/views/DetailsView"; import { parseProjectFilePath } from "./src/fs"; import { BreadcrumbSegment, injectMobileBreadcrumb } from "./src/ui"; export default class ProjektkontextPlugin extends Plugin { async onload(): Promise { this.registerView(VIEW_TYPE_PROJECTS, (leaf) => new ProjectsView(leaf)); this.registerView(VIEW_TYPE_OVERVIEW, (leaf) => new OverviewView(leaf)); this.registerView(VIEW_TYPE_DETAILS, (leaf) => new DetailsView(leaf)); this.addRibbonIcon(RIBBON_ICON, "Projekte", () => { void this.activateProjectsView(); }); this.addCommand({ id: "open-projects", name: "Projekte öffnen", callback: () => void this.activateProjectsView(), }); 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 activateProjectsView(): Promise { const { workspace } = this.app; let leaf: WorkspaceLeaf | null = workspace.getLeavesOfType(VIEW_TYPE_PROJECTS)[0] ?? null; if (!leaf) { leaf = workspace.getLeaf(false); await leaf.setViewState({ type: VIEW_TYPE_PROJECTS, 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_PROJECTS, active: true }), }, { label: loc.project, onClick: () => void leaf.setViewState({ type: VIEW_TYPE_OVERVIEW, active: true, state: { project: loc.project }, }), }, ]; if (loc.area) { segments.push({ label: loc.area, onClick: () => void leaf.setViewState({ type: VIEW_TYPE_DETAILS, active: true, state: { project: loc.project, area: loc.area }, }), }); } segments.push({ label: file.basename }); injectMobileBreadcrumb(view, segments); } }