Skip to content

fix(memory-graph): keep node selection when pagination changes the node count#1263

Closed
abhay-codes07 wants to merge 1 commit into
supermemoryai:mainfrom
abhay-codes07:fix/graph-slideshow-selection-wipe
Closed

fix(memory-graph): keep node selection when pagination changes the node count#1263
abhay-codes07 wants to merge 1 commit into
supermemoryai:mainfrom
abhay-codes07:fix/graph-slideshow-selection-wipe

Conversation

@abhay-codes07

Copy link
Copy Markdown
Contributor

What

Pin a node's popover in the memory graph, zoom out far enough for the load-more trigger to fetch the next page, and the popover vanishes mid-read.

The slideshow effect in memory-graph.tsx depends on nodes.length, and its inactive branch unconditionally cleared the selected node:

useEffect(() => {
    if (!isSlideshowActive || nodes.length === 0) {
        if (!isSlideshowActive) {
            setSelectedNode(null)   // runs on every node-count change
            ...

With the slideshow off (the default for every consumer), any change in node count re-ran the effect and wiped the user's selection — pagination appending documents being the common trigger. It also fired a stray coolDown() on the simulation each time.

Fix

Track the previous slideshow state in a ref and only clear the selection on a genuine active → inactive transition. Re-runs caused by nodes.length changing while the slideshow was never active are now no-ops.

Testing

  • bun run test in packages/memory-graph — 188 pass
  • bun run check-types — clean

Behaviour notes for review: the active → inactive transition still clears the selection and cools the simulation exactly as before; the only change is that re-runs where the slideshow was never active no longer touch the selection.

…ount

The slideshow effect depends on nodes.length and its inactive branch
unconditionally cleared the selected node. With the slideshow off (the
default), any change in node count re-ran the effect and wiped the
user's selection: pin a node's popover, zoom out far enough for the
load-more trigger to append a page of documents, and the popover
vanishes mid-read. The reset also fired a stray coolDown() on the
simulation.

Track the previous slideshow state in a ref and only clear the
selection on a real active -> inactive transition.
Copilot AI review requested due to automatic review settings July 12, 2026 18:44

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@ishaanxgupta

Copy link
Copy Markdown
Contributor

I don't think this issue exists in prod, I checked and could not reproduce this closing this for now, if you find this issue in prod, feel free to tag me

@abhay-codes07

Copy link
Copy Markdown
Contributor Author

@ishaanxgupta thanks for checking. Taking you up on the "tag me" offer, because I think this reproduces on the default path rather than through the slideshow.

The trigger is not the slideshow being on, it is the effect re-running while the slideshow is off. On current main, memory-graph.tsx:

useEffect(() => {
    if (!isSlideshowActive || nodes.length === 0) {
        if (!isSlideshowActive) {
            setSelectedNode(null)      // clears selection on *every* re-run
            simulationRef.current?.coolDown()
        }
        return
    }
    // ...
}, [isSlideshowActive, nodes.length])   // re-runs whenever nodes.length changes

isSlideshowActive defaults to false for every consumer, so the effect sits in that top branch. Because nodes.length is a dependency, the effect re-runs any time the node count changes, and each re-run unconditionally calls setSelectedNode(null).

Repro without the slideshow:

  1. Open the graph normally (slideshow off).
  2. Click a node so its popover is pinned (selectedNode is set).
  3. Do anything that appends nodes, the common one being the zoom-out load-more that fetches the next page. nodes.length goes up.
  4. The effect re-runs, hits setSelectedNode(null), and the pinned popover disappears mid-read. It also fires a stray coolDown() on the simulation each time.

It is easy to miss because it only bites when there is a pinned selection and the node count changes in the same session, so a quick click-test without pagination looks fine. The PR keeps the active → inactive transition behaving exactly as before and only stops the no-op re-runs from clearing the selection.

If that repro holds up on your end, would you mind reopening? Happy to rebase onto the latest main first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants