Files
management/main.ts
2026-05-01 18:37:24 +02:00

101 lines
3.1 KiB
TypeScript

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<void> {
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<void> {}
async activateProjectsView(): Promise<void> {
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);
}
}