Skip to content

fix: channels blanking and weird virtua scroll bug#2227

Merged
dev-rb merged 5 commits intomainfrom
rahul/fix-channel-blanking-and-virtua-resize-bug
Mar 26, 2026
Merged

fix: channels blanking and weird virtua scroll bug#2227
dev-rb merged 5 commits intomainfrom
rahul/fix-channel-blanking-and-virtua-resize-bug

Conversation

@dev-rb
Copy link
Copy Markdown
Contributor

@dev-rb dev-rb commented Mar 26, 2026

  • Removes the virtua patch
  • Bumps virtua to latest
  • Updates current/old channel behavior to no longer be reversed
  • Removes custom alignment logic for scrolling to message in current/old channel
  • Adds a scroll to bottom on mount handler to make sure the scroll position starts at the bottom initially

@dev-rb dev-rb requested a review from a team as a code owner March 26, 2026 21:25
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 26, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Improved message-list scrolling and alignment for more reliable navigation and visibility
    • Ensured first-load behavior scrolls to the latest message exactly once when appropriate
    • Restored natural message ordering to avoid reversed visual presentation
  • Chores

    • Updated a dependency version to address stability/compatibility improvements

Walkthrough

Bumped virtua from 0.48.1 to 0.48.8 and removed its patch entry. Refactored MessageList virtualization: use direct indices, replace custom scroll math with native scrollIntoView, add initial mount scroll effect, and remove visual list reversal.

Changes

Cohort / File(s) Summary
Dependency Management
js/app/package.json
Updated virtua dependency from 0.48.10.48.8; removed virtua@0.48.1 from patchedDependencies.
MessageList Virtualization Refactor
js/app/packages/block-channel/component/MessageList/MessageList.tsx
Switched from reversed/normalized index math to direct topLevelIndex; removed custom scrollElementIntoView and offset-based virtualizer scrolling in favor of Element.scrollIntoView({ block }); changed force-bottom scroll to virtualHandle()?.scrollBy(Number.MAX_SAFE_INTEGER); removed .toReversed() usage and flex-direction: column-reverse; adjusted keepMountedIndices calculations; added mount-guarded createEffect to perform a one-time initial forced scroll.
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title follows conventional commits format with 'fix:' prefix and is 50 characters, well under the 72-character limit. It clearly relates to the main changes: fixing channel display issues and virtua scroll behavior.
Description check ✅ Passed The description is directly related to the changeset, providing a clear bullet-point breakdown of the key changes including virtua dependency update, reversal logic removal, and scroll behavior modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 26, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
js/app/packages/block-channel/component/MessageList/MessageList.tsx (1)

511-516: 🧹 Nitpick | 🔵 Trivial

Consider using scrollTo(handle.scrollSize) for clearer intent.

Using scrollBy(Number.MAX_SAFE_INTEGER) works because virtua clamps the value, but it's semantically unclear. If the virtualizer provides a scrollSize property, using scrollTo(handle.scrollSize) would be more explicit about scrolling to the end.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@js/app/packages/block-channel/component/MessageList/MessageList.tsx` around
lines 511 - 516, Replace the semantically-unclear use of
virtualHandle()?.scrollBy(Number.MAX_SAFE_INTEGER) in MessageList.tsx with an
explicit call that scrolls to the virtualizer's total scroll size: obtain the
virtual handle via virtualHandle() and call its scrollTo method with the
handle's scrollSize (i.e., use scrollTo(handle.scrollSize) instead of
scrollBy(Number.MAX_SAFE_INTEGER)); update the branch in which forceBottom /
isNearBottom() triggers the scroll so it uses
virtualHandle().scrollTo(virtualHandle().scrollSize) and keep the early return
behavior intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@js/app/packages/block-channel/component/MessageList/MessageList.tsx`:
- Around line 265-266: Remove the dead/commented-out call and the unused helper:
delete the single-line comment "// scrollElementIntoView(targetEl, align);" near
the call to targetEl.scrollIntoView({ block: align }); and remove the entire
scrollElementIntoView function definition (the function named
scrollElementIntoView) since it is no longer referenced anywhere; ensure no
other references to scrollElementIntoView remain after deletion.

---

Outside diff comments:
In `@js/app/packages/block-channel/component/MessageList/MessageList.tsx`:
- Around line 511-516: Replace the semantically-unclear use of
virtualHandle()?.scrollBy(Number.MAX_SAFE_INTEGER) in MessageList.tsx with an
explicit call that scrolls to the virtualizer's total scroll size: obtain the
virtual handle via virtualHandle() and call its scrollTo method with the
handle's scrollSize (i.e., use scrollTo(handle.scrollSize) instead of
scrollBy(Number.MAX_SAFE_INTEGER)); update the branch in which forceBottom /
isNearBottom() triggers the scroll so it uses
virtualHandle().scrollTo(virtualHandle().scrollSize) and keep the early return
behavior intact.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2eb8ce9e-9b3e-4c09-ba71-ec8f3a093a59

📥 Commits

Reviewing files that changed from the base of the PR and between b92a495 and 39b49fd.

⛔ Files ignored due to path filters (1)
  • js/app/bun.lock is excluded by !**/*.lock, !**/bun.lock
📒 Files selected for processing (2)
  • js/app/package.json
  • js/app/packages/block-channel/component/MessageList/MessageList.tsx

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@js/app/packages/block-channel/component/MessageList/MessageList.tsx`:
- Around line 467-468: Replace the call to
virtualHandle()?.scrollBy(Number.MAX_SAFE_INTEGER) with an index-based scroll
using virtualHandle()?.scrollToIndex(...); specifically call
scrollToIndex(topLevelMessages().length - 1, { align: 'end' }) so the
virtualizer scrolls to the last message reliably; ensure you handle the
empty-list case (only call when topLevelMessages().length > 0) and keep using
the same virtualHandle() reference in the MessageList component/function.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 721973c6-4981-45c1-910b-de8a82beba1a

📥 Commits

Reviewing files that changed from the base of the PR and between 39b49fd and 57babdf.

📒 Files selected for processing (1)
  • js/app/packages/block-channel/component/MessageList/MessageList.tsx

Comment on lines +467 to 468
virtualHandle()?.scrollBy(Number.MAX_SAFE_INTEGER);
return;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

virtua scrollBy large value scroll to bottom

💡 Result:

In virtual scrolling implementations (Angular CDK, TanStack Virtual, react-window/react-virtualized), using scrollBy or scrollToOffset/scrollTo with a very large pixel value to reach the bottom often fails due to precision limitations in JavaScript numbers (especially for lists with millions of items where total height exceeds ~1e6-1e15 px depending on browser/engine). Instead, use index-based scrolling methods which internally compute the correct offset. Key solutions: 1. Angular CDK Virtual Scroll (most common context): - Use viewport.scrollToIndex(items.length - 1) to scroll to the last item. - For bottom: viewport.scrollTo({ bottom: 0 }) - call twice with setTimeout if needed due to async rendering. - Example: setTimeout( => { this.viewport.scrollTo({ bottom: 0, behavior: 'auto' }); }, 0); setTimeout( => { this.viewport.scrollTo({ bottom: 0, behavior: 'auto' }); }, 50); 2. TanStack Virtual / react-window: - virtualizer.scrollToIndex(items.length - 1, { align: 'end' }) - For custom scrollToFn, implement smooth scrolling but use index, not raw offset. 3. General pattern for large lists: - Avoid raw pixel offsets >1e6 px; use scrollToIndex(lastIndex) or scrollToItem({index: lastIndex, align: 'end'}). - For dynamic heights, may need iterative refinement: guess offset = index * avgHeight, scroll, check renderedRange, adjust. Issues with large scrollBy values: - JS number precision loss (float64 mantissa ~53 bits). - Browser scroll recalculation errors. - Seen in react-virtualized #1537 (scrollToRow inaccurate for 1B+ items), TanStack issues with dynamic heights. Prefer official docs/methods over manual scrollBy(totalHeight).

Citations:


🏁 Script executed:

# Find the file and examine the context around lines 467-468
find . -name "MessageList.tsx" -path "*/block-channel/component/MessageList/*" | head -5

Repository: macro-inc/macro

Length of output: 128


🏁 Script executed:

# Check virtua package in the repo
fd -e json -e tsx -e ts | xargs rg -l "virtua" | head -10

Repository: macro-inc/macro

Length of output: 661


🏁 Script executed:

# Look for package.json files that might define virtua version
fd -name "package.json" | xargs rg -l "virtua" 2>/dev/null

Repository: macro-inc/macro

Length of output: 3171


🏁 Script executed:

# Read the MessageList.tsx file, focusing on the relevant section
cat -n js/app/packages/block-channel/component/MessageList/MessageList.tsx | sed -n '450,480p'

Repository: macro-inc/macro

Length of output: 1333


🏁 Script executed:

# Check imports at the top of the file to understand virtualHandle
cat -n js/app/packages/block-channel/component/MessageList/MessageList.tsx | head -60

Repository: macro-inc/macro

Length of output: 2503


🏁 Script executed:

# Check the virtua patch to see what's modified
cat js/app/patches/virtua@0.48.1.patch

Repository: macro-inc/macro

Length of output: 6132


🏁 Script executed:

# Look for scrollToIndex usage in the codebase
rg "scrollToIndex" --type ts --type tsx

Repository: macro-inc/macro

Length of output: 86


🏁 Script executed:

# Search for scrollToIndex in the codebase (without -n flag)
rg "scrollToIndex" --type-list

Repository: macro-inc/macro

Length of output: 448


🏁 Script executed:

# Try again with correct syntax
rg "scrollToIndex"

Repository: macro-inc/macro

Length of output: 5041


🏁 Script executed:

# Look at what methods are called on virtualHandle in the file
rg "virtualHandle\(\)" js/app/packages/block-channel/component/MessageList/MessageList.tsx -A 2

Repository: macro-inc/macro

Length of output: 1367


🏁 Script executed:

# Check if scrollToIndex is documented in virtua types
rg "scrollToIndex" js/app/node_modules/virtua 2>/dev/null | head -20

Repository: macro-inc/macro

Length of output: 41


🏁 Script executed:

# Get more context around the commented-out scrollToIndex line
cat -n js/app/packages/block-channel/component/MessageList/MessageList.tsx | sed -n '475,510p'

Repository: macro-inc/macro

Length of output: 1340


🏁 Script executed:

# Check git log to see when/why scrollToIndex was commented out
cd js/app && git log --oneline -p -- packages/block-channel/component/MessageList/MessageList.tsx 2>/dev/null | grep -A 10 -B 10 "scrollToIndex.*commented\|align: 'end'" | head -50

Repository: macro-inc/macro

Length of output: 569


🏁 Script executed:

# Search for any issues or TODOs related to scroll behavior
rg "TODO|FIXME|BUG|ISSUE" js/app/packages/block-channel/component/MessageList/MessageList.tsx -B 2 -A 2

Repository: macro-inc/macro

Length of output: 356


Use scrollToIndex instead of scrollBy(Number.MAX_SAFE_INTEGER) for scrolling to bottom.

In virtua, index-based scrolling is the standard pattern and avoids precision issues with large pixel values. The codebase uses scrollToIndex consistently across 40+ other components. This exact pattern is even present in the same function (commented out with a "TODO"), confirming it's the intended approach:

Suggested replacement
virtualHandle()?.scrollToIndex(topLevelMessages().length - 1, { align: 'end' });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@js/app/packages/block-channel/component/MessageList/MessageList.tsx` around
lines 467 - 468, Replace the call to
virtualHandle()?.scrollBy(Number.MAX_SAFE_INTEGER) with an index-based scroll
using virtualHandle()?.scrollToIndex(...); specifically call
scrollToIndex(topLevelMessages().length - 1, { align: 'end' }) so the
virtualizer scrolls to the last message reliably; ensure you handle the
empty-list case (only call when topLevelMessages().length > 0) and keep using
the same virtualHandle() reference in the MessageList component/function.

@dev-rb dev-rb merged commit f67aa1d into main Mar 26, 2026
21 of 22 checks passed
@dev-rb dev-rb deleted the rahul/fix-channel-blanking-and-virtua-resize-bug branch March 26, 2026 21:44
@coderabbitai coderabbitai bot mentioned this pull request Apr 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants