You are browsing as a guest. Sign up (or log in) to start making projects!

Open comments for this post

1h 11m 21s logged

making it actually work (kind of)

so remember how last commit I said “everything is broken”? I spent tonight fixing the worst of it. it’s not done but it’s a lot less broken.


the big fix: drag + layout fighting

the core problem was that when you drag a note, the layout engine keeps running and overwriting your drag position every 16ms. the note jitters back and forth between where you’re dragging it and where the physics wants it.

fix: new SetNodePosition event. when you drag a note, the UI publishes it through the event bus. the layout worker drains these events at the top of each cycle and calls engine.set_position() before stepping. so the layout engine knows where you put the card and computes forces from there instead of fighting you.

also: while any note is being dragged (tracked by dragged_set), the layout event loop skips updating positions entirely. other notes stay still instead of jittering from stale force calculations. once you release, everything syncs up again.


mouse events moved to root div

pan/drag/mouseup handlers were on the canvas element, which meant releasing the mouse over a note card didn’t fire mouseup on the canvas. dragging would “stick.” moved all the move/up/leave handlers to the root div so they fire regardless of what’s under the cursor.


canvas renderer simplified

removed the node drawing code from WebCanvasRenderer entirely. nodes were being drawn twice: once on the canvas in Rust/web-sys, once as DOM cards in Dioxus. the canvas now only draws the dot grid and bezier edges. the DOM handles cards. no more double rendering.

the inline JS RAF loop was also replaced with a standalone canvas-draw.js that gets called explicitly via window.__penumbra_draw() whenever render state changes. no more requestAnimationFrame spinning at 60fps when nothing changed.


spring-animated card positions

cards now spring-animate to their new positions instead of teleporting. each AnimatedCard tracks target x/y and animates via dioxus-motion springs when the target changes. so when the layout engine repositions notes, they glide smoothly. the spring from the ideas issue, basically.


sidebar panels are real now

the floating sidebar buttons actually do things now. four panels:

Search: reactive search input that queries the hybrid search engine as you type. results show title, preview, and similarity score. click a result and the camera drifts to that note.

Tags: shows all tags sorted by count. click a tag to filter the graph view to only notes with that tag. click again to clear the filter. below the tag list, shows the filtered notes.

Pins: lists all pinned notes. click to pan to them.

Settings: just shows note count and link count for now. placeholder.


context menu on right-click

right-click a note card and you get a context menu with “Open in editor,” “Pin to canvas” / “Unpin,” and “Delete note.” the pin toggle calls a new toggle_pin method on AppState that flips the meta flag, persists, and publishes an event.


note cards render markdown

NoteCard preview now runs through markdown_to_html() and uses dangerous_inner_html. (XSS? yes) the editor got a preview toggle button that switches between the textarea and rendered HTML.


real embeddings on init

switched from SimpleEmbedder to CandleEmbedder::load() at startup. downloads the real Snowflake model from HuggingFace on first launch. falls back to SimpleEmbedder if the download fails.


position persistence

the layout event loop now debounce-saves positions to storage every 2 seconds. on next launch, saved positions are fed into the layout engine before the first step so notes start where you left them instead of random positions.


other stuff done as well but i’m eepyyyy

0
0

Comments 0

No comments yet. Be the first!