init
This commit is contained in:
85
src/ui.ts
Normal file
85
src/ui.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import { App, Menu, Platform, TFile, View, WorkspaceLeaf, normalizePath } from "obsidian";
|
||||
|
||||
export function menu(
|
||||
ev: MouseEvent,
|
||||
items: Array<{ title: string; icon?: string; onClick: () => void }>,
|
||||
): void {
|
||||
const m = new Menu();
|
||||
for (const it of items) {
|
||||
m.addItem((i) => {
|
||||
i.setTitle(it.title);
|
||||
if (it.icon) i.setIcon(it.icon);
|
||||
i.onClick(it.onClick);
|
||||
});
|
||||
}
|
||||
m.showAtMouseEvent(ev);
|
||||
}
|
||||
|
||||
export async function openMarkdown(
|
||||
app: App,
|
||||
path: string,
|
||||
leaf?: WorkspaceLeaf,
|
||||
): Promise<void> {
|
||||
const p = normalizePath(path);
|
||||
const f = app.vault.getAbstractFileByPath(p);
|
||||
if (!(f instanceof TFile)) return;
|
||||
if (Platform.isMobile) {
|
||||
const target = leaf ?? app.workspace.getLeaf(false);
|
||||
await target.openFile(f);
|
||||
return;
|
||||
}
|
||||
const existing = app.workspace.getLeavesOfType("markdown");
|
||||
if (existing.length > 0) {
|
||||
const target = existing[existing.length - 1];
|
||||
await target.openFile(f);
|
||||
app.workspace.revealLeaf(target);
|
||||
} else {
|
||||
const target = app.workspace.getLeaf("split", "vertical");
|
||||
await target.openFile(f);
|
||||
}
|
||||
}
|
||||
|
||||
export interface BreadcrumbSegment {
|
||||
label: string;
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
function renderBreadcrumbInto(wrap: HTMLElement, segments: BreadcrumbSegment[]): void {
|
||||
segments.forEach((seg, i) => {
|
||||
if (i > 0) wrap.createSpan({ cls: "pk-breadcrumb-sep", text: " > " });
|
||||
if (seg.onClick) {
|
||||
const a = wrap.createSpan({ cls: "pk-breadcrumb-link", text: seg.label });
|
||||
a.addEventListener("click", seg.onClick);
|
||||
} else {
|
||||
wrap.createSpan({ cls: "pk-breadcrumb-current", text: seg.label });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function breadcrumb(parent: HTMLElement, segments: BreadcrumbSegment[]): HTMLElement {
|
||||
const wrap = parent.createDiv({ cls: "pk-breadcrumb" });
|
||||
renderBreadcrumbInto(wrap, segments);
|
||||
return wrap;
|
||||
}
|
||||
|
||||
export function injectMobileBreadcrumb(
|
||||
view: View & { contentEl?: HTMLElement },
|
||||
segments: BreadcrumbSegment[],
|
||||
): void {
|
||||
const root = view.contentEl ?? view.containerEl.querySelector(".view-content");
|
||||
if (!root) return;
|
||||
root.querySelectorAll(".pk-mobile-breadcrumb").forEach((el) => el.remove());
|
||||
if (segments.length === 0) return;
|
||||
const target =
|
||||
root.querySelector<HTMLElement>(".markdown-source-view .cm-sizer") ??
|
||||
root.querySelector<HTMLElement>(".markdown-reading-view .markdown-preview-sizer");
|
||||
if (!target) return;
|
||||
const wrap = document.createElement("div");
|
||||
wrap.className = "pk-breadcrumb pk-mobile-breadcrumb";
|
||||
target.prepend(wrap);
|
||||
renderBreadcrumbInto(wrap, segments);
|
||||
}
|
||||
|
||||
export function emptyState(parent: HTMLElement, text: string): HTMLElement {
|
||||
return parent.createDiv({ cls: "pk-empty", text });
|
||||
}
|
||||
Reference in New Issue
Block a user