Skip to content

Commit

Permalink
refactor(hierarchy-view): extract renderHierarchy function
Browse files Browse the repository at this point in the history
  • Loading branch information
kdnk committed Dec 25, 2024
1 parent 3a25bb0 commit 19cdd71
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 116 deletions.
110 changes: 110 additions & 0 deletions src/hierarchy-view/render-hierarchy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { MarkdownView, TFile } from "obsidian";
import { createRoot } from "react-dom/client";
import { Hierarchy } from "../ui/hierarchy";
import type HierarchyPlugin from "../main";

const CONTAINER_CLASS = "hierarchy-container";

export function renderHierarchy(
plugin: HierarchyPlugin,
file?: TFile | null,
): void {
const markdownLeaves = plugin.app.workspace.getLeavesOfType("markdown");
markdownLeaves.forEach((leaf) => {
if (!(leaf.view instanceof MarkdownView)) return;
if (!leaf.view.file) return;
if (file && leaf.view.file.path !== file.path) return;

const mainEl = leaf.view.containerEl.querySelector(
".cm-contentContainer",
);
if (!mainEl) return;

const containers = leaf.view.containerEl.querySelectorAll(
"." + CONTAINER_CLASS,
);

if (containers) {
containers.forEach((el) => el.remove());
}

if (!plugin.settings.hierarchyForEditors) return;

const newContainer = createDiv({ cls: CONTAINER_CLASS });
mainEl.after(newContainer);

const root = createRoot(newContainer);

const currentPathName = getCleanPathName(leaf.view.file.path);
const hierarchies = getHierarchies(currentPathName);
const children = getChildren(plugin, currentPathName);

const count = hierarchies.length + children.length;

root.render(
<Hierarchy
hierarchies={hierarchies}
children={children}
count={count}
></Hierarchy>,
);
});
}

function getChildren(plugin: HierarchyPlugin, currentPathName: string) {
const files = plugin.app.metadataCache.getCachedFiles();
if (plugin.childrenCache[currentPathName]) {
return plugin.childrenCache[currentPathName];
}

const children = files
.filter((file) => {
function isSubdirectory(parentDir: string, subDir: string) {
return (
subDir.startsWith(parentDir) &&
(subDir[parentDir.length] === "/" ||
parentDir.length === subDir.length)
);
}

const pathName = getCleanPathName(file);
if (pathName === currentPathName) return false;
if (pathName.includes("/attachments/")) return false;
if (pathName.startsWith("attachments/")) return false;
return isSubdirectory(currentPathName, pathName);
})
.map((file) => {
const pathName = getCleanPathName(file);
return pathName;
});
plugin.childrenCache[currentPathName] = children;
return children;
}

function getHierarchies(pathName: string) {
const dirs = pathName.split("/");

const computePath = (hierarchies: string[]) => {
return hierarchies.reduce((acc, curr, index) => {
return index === 0 ? curr : `${acc}/${curr}`;
}, "");
};
return pathName
.split("/")
.map((_, index) => {
if (index === dirs.length - 1) {
return null;
}
const path = computePath(dirs.slice(0, index + 1));
return path;
})
.filter((path) => path !== null) as string[];
}

function getCleanPathName(path: string) {
let pathName = path.split(".")[0];
if (pathName.startsWith("pages/")) {
pathName = pathName.slice(6);
}
return pathName;
}
122 changes: 6 additions & 116 deletions src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
import {
App,
MarkdownView,
Plugin,
PluginManifest,
TFile,
Platform,
} from "obsidian";
import { App, Plugin, PluginManifest, Platform } from "obsidian";
import {
DEFAULT_SETTINGS,
HierarchySettings,
HierarchyPluginSettingsTab,
} from "./settings";
import { Hierarchy } from "./ui/hierarchy";
import { createRoot } from "react-dom/client";
import { ActiveTabGroup } from "./utils/active-tab-group";
import { patchBacklinks } from "./backlinks/patch-backlinks";
import { renderHierarchy } from "./hierarchy-view/render-hierarchy";

export default class HierarchyPlugin extends Plugin {
settings: HierarchySettings;
Expand All @@ -34,14 +26,14 @@ export default class HierarchyPlugin extends Plugin {
this.registerEvent(
this.app.workspace.on("file-open", async (file) => {
this.setTabTitle();
this.activateHierarchyView(file);
renderHierarchy(this, file);
}),
);

this.registerEvent(
this.app.metadataCache.on("resolved", async () => {
this.resetChildrenCache();
this.activateHierarchyView();
renderHierarchy(this);
}),
);

Expand Down Expand Up @@ -72,121 +64,19 @@ export default class HierarchyPlugin extends Plugin {

async refresh() {
this.setTabTitle();
this.activateHierarchyView();
renderHierarchy(this);
}

private resetChildrenCache() {
this.childrenCache = {};
}

private async activateHierarchyView(file?: TFile | null) {
const CONTAINER_CLASS = "hierarchy-container";
const markdownLeaves = this.app.workspace.getLeavesOfType("markdown");
markdownLeaves.forEach((leaf) => {
if (!(leaf.view instanceof MarkdownView)) return;
if (!leaf.view.file) return;
if (file && leaf.view.file.path !== file.path) return;

const mainEl = leaf.view.containerEl.querySelector(
".cm-contentContainer",
);
if (!mainEl) return;

const containers = leaf.view.containerEl.querySelectorAll(
"." + CONTAINER_CLASS,
);

if (containers) {
containers.forEach((el) => el.remove());
}

if (!this.settings.hierarchyForEditors) return;

const newContainer = createDiv({ cls: CONTAINER_CLASS });
mainEl.after(newContainer);

const root = createRoot(newContainer);

const currentPathName = this.getCleanPathName(leaf.view.file.path);
const hierarchies = this.getHierarchies(currentPathName);
const children = this.getChildren(currentPathName);

const count = hierarchies.length + children.length;

root.render(
<Hierarchy
hierarchies={hierarchies}
children={children}
count={count}
></Hierarchy>,
);
});
}

private getChildren(currentPathName: string) {
const files = this.app.metadataCache.getCachedFiles();
if (this.childrenCache[currentPathName]) {
return this.childrenCache[currentPathName];
}

const children = files
.filter((file) => {
function isSubdirectory(parentDir: string, subDir: string) {
return (
subDir.startsWith(parentDir) &&
(subDir[parentDir.length] === "/" ||
parentDir.length === subDir.length)
);
}

const pathName = this.getCleanPathName(file);
if (pathName === currentPathName) return false;
if (pathName.includes("/attachments/")) return false;
if (pathName.startsWith("attachments/")) return false;
return isSubdirectory(currentPathName, pathName);
})
.map((file) => {
const pathName = this.getCleanPathName(file);
return pathName;
});
this.childrenCache[currentPathName] = children;
return children;
}

private getHierarchies(pathName: string) {
const dirs = pathName.split("/");

const computePath = (hierarchies: string[]) => {
return hierarchies.reduce((acc, curr, index) => {
return index === 0 ? curr : `${acc}/${curr}`;
}, "");
};
return pathName
.split("/")
.map((_, index) => {
if (index === dirs.length - 1) {
return null;
}
const path = computePath(dirs.slice(0, index + 1));
return path;
})
.filter((path) => path !== null) as string[];
}

private getCleanPathName(path: string) {
let pathName = path.split(".")[0];
if (pathName.startsWith("pages/")) {
pathName = pathName.slice(6);
}
return pathName;
}

async onunload() {
this.settings.hierarchyForTabs = false;
this.settings.hierarchyForBacklinks = false;
this.settings.hierarchyForEditors = false;

this.activateHierarchyView();
renderHierarchy(this);
this.setTabTitle();
}

Expand Down

0 comments on commit 19cdd71

Please sign in to comment.