Last active
May 30, 2024 11:55
-
-
Save brianrodri/b95ee3d7972f24700dd77769e8a3823c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Component, MarkdownView, Plugin, TFile, WorkspaceLeaf } from "obsidian"; | |
import { render, unmountComponentAtNode } from "preact/compat"; | |
export default class MyPlugin extends Plugin { | |
private components: PreactComponent[] = []; | |
public override onload() { | |
this.app.workspace.onLayoutReady(() => { | |
this.loadAllComponents(); | |
this.registerEvent( | |
this.app.workspace.on("layout-change", () => { | |
// This feels hacky and like the wrong approach. | |
this.unloadAllComponents(); | |
this.loadAllComponents(); | |
}), | |
); | |
}); | |
} | |
public override onunload() { | |
this.unloadAllComponents(); | |
} | |
private loadAllComponents() { | |
this.app.workspace.iterateAllLeaves((leaf: WorkspaceLeaf) => { | |
const { view } = leaf; | |
if (view instanceof MarkdownView && view.file !== null) { | |
// TODO: How do I call `.removeChild()` if I've visited this leaf before? | |
if (view.getMode() === "preview") { | |
const component = new PreactComponent(view.containerEl, view.file); | |
view.addChild(component); | |
this.components.push(component); | |
} | |
} | |
}); | |
} | |
private unloadAllComponents() { | |
this.components.forEach((component) => component.unload()); | |
this.components = []; | |
} | |
} | |
class PreactComponent extends Component { | |
public constructor( | |
private readonly container: HTMLElement, | |
private readonly file: TFile, | |
private readonly className = "ROOT-ELEMENT-CLASS", | |
private readonly classes = [className, "markdown-preview-sizer"], | |
private readonly positionSelector = ".markdown-reading-view > .markdown-preview-view", | |
) { | |
super(); | |
console.log(this.file.path); | |
} | |
public override onload() { | |
const rootElement = this.ensureRootElement(); | |
const position = this.container.querySelector(this.positionSelector); | |
if (position) { | |
position.prepend(rootElement); | |
render(<>Hello World!</>, rootElement); | |
console.log("preact mounted"); | |
} | |
} | |
public override onunload() { | |
const rootElement = this.container.querySelector(`.${this.className}`); | |
if (rootElement) { | |
unmountComponentAtNode(rootElement); | |
rootElement.remove(); | |
console.log("preact unmounted"); | |
} | |
} | |
private ensureRootElement() { | |
return this.container.querySelector(`.${this.className}`) ?? this.container.createDiv({ cls: this.classes }); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment