When writing plugins it helps to be able to react to the app’s events, changes to the data, namely the Logseq primitives like blocks and pages. It would be great to subscribe to what blocks get loaded or changed on a page, for example.
It’s one thing if a plugin creates its own UI, but some plugins are designed to interact only with the main page/view. While the iframe isolation prohibits direct actions against the main UI there are still reasonable actions which can be taken. For example, my plugin toggles the visibility of completed to-dos in the main UI.
Basically, if the plugin knows what content has been rendered to the page, it can react to it by adding dynamic styles. This has proven completely workable except for the limitations and timing of what can be observed.
For example, the standard
ready handler is called when logseq is ready but not after the initial page content is rendered. Therefore, if you call
getCurrentPageBlocksTree too early you get null. And if you call this on the journal page, regardless of when, you get null. It should be possible to tap into some event
on("page:blocks:loaded"). This would work similar to
getCurrentPageBlocksTree except that it happens in response to events. And it’s clear some blocks are loaded lazily. Therefore, these events could fire at any time. For example, as you scroll down the journals page and new days scroll into view.
Polling is a wasteful hack because it requires a vigilant plugin which eats resources for no good reason. The app already knows when it’s loading (or updating) data. It should simply share these events and allow interested plugins to react.
Likewise, sometimes the current page gets edited. There is no
on("page:change") hook or
on("journal:change") hook. Likewise, to go finer grained, there could be a
on("block:change") hook. The point is, these things are already happening in the app. All I’m asking is they be shared with a varied set of channels. If everything happens via
on then you don’t need custom methods like
onRouteChanged but rather
on("route:change"). I believe, there is an
emit build somewhere into the api. The pairing of
on along with custom events could make the Logseq plugin core very jQuery like. And this would allow for a lot of hacks (like polling) to be avoided.
Consider my plugin and what would need to be done to dynamically update the styles when updates are made to either a page or the master bottomless journal page. Right now, things seem harder than they need to be.
Likewise, I’m not sure how I would even know what got rendered in the linked references on the page I’m viewing. Again, my plugin has no UI. It merely augments the master UI by knowing what’s been added to the page and then it reacts by adding styles.
I realize that if I kept the plugin targeted to TODOs I could have simplified quite a few things, but the aim of the plugin was to permit some flexibility with what gets selected and how it gets rendered based on two possible states. Hooks to the rescue!
My plugin monitors incoming data and adds styles but tapping directly into the rendering pipeline would be far better.