feat: penultimateCellIndex support, scroll-on-navigation, keyboard scoping, scroll position methods#49
Conversation
|
@christopherwxyz is attempting to deploy a commit to the Vercel Team on Vercel. A member of the Team first needs to authorize it. |
c2cb7e8 to
3cd002e
Compare
|
Hey, this PR looks good. I also fixed this issue in my open PR (#48). Our current solution is to reset that state based on the change of |
| } | ||
| } | ||
|
|
||
| func getFirstVisibleCellInfo() throws -> AixVisibleCellInfo? { |
There was a problem hiding this comment.
getFirstVisibleCellInfo is a hook that saves and restores scroll position when navigating between chats. It:
-
On navigate away: calls
getFirstVisibleCellInfo()to snapshot which message is at the top of the viewport (cell index + pixel offset within that cell + whether near bottom) -
On return: calls
scrollToCellOffset()to restore to that exact position
Without these methods, switching between conversations would lose your scroll position. It's the counterpart to the mainScrollViewID scroll-reset — reset handles the "scroll to bottom for new conversation" case, while this handles "resume where you left off."
|
Like @richardkunkli said, we're migrating to an approach that resets scroll state when Would that satisfy what you did with |
Add ownsKeyboardSession flag and firstResponderIsDescendant() check so stacked screens (e.g. thread pushed over chat detail) don't interfere with each other's scroll/inset state when the keyboard opens. Also extract resetScrollState() helper and remove unused .didShow subscription. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add two new methods to the Aix Nitro spec for scroll position memory: - getFirstVisibleCellInfo(): returns the first visible cell's index, pixel offset, and near-end state - scrollToCellOffset(): scrolls to a specific cell at a given offset These enable saving and restoring scroll positions when switching between conversations. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1355bc4 to
ae7a532
Compare
|
@nandorojo Yes — rebased onto main and adopted the Repurposed this PR to add two new methods we need for scroll position memory:
Also kept the keyboard notification scoping fix ( |
Without this reset, switching conversations where the blank cell has the same size would cause reportBlankViewSizeChange to skip the initial scroll-to-end (didAlreadyUpdate guard), leaving a gap between the last message and the input bar. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Rebased onto
main(v0.6.0) and adopted themainScrollViewID-based scroll reset from #48.penultimateCellIndex support
calculateBlankSizenow respects thepenultimateCellIndexprop:-1): opts out of blank padding entirely — no gap between the last cell and the footerblankView.index - 1nil(default): preserves existing behaviorScroll reset on navigation
When the view leaves the screen (
didMoveToWindowwithwindow == nil),didScrollToEndInitiallyForIdis reset. When returning,handleDidReturnToScreenre-triggers scroll-to-end. This handles Fabric view recycling wheremainScrollViewIDdoesn't change when revisiting the same conversation.Keyboard notification scoping
Adds
ownsKeyboardSessionflag so stacked screens (e.g. thread pushed over chat) don't interfere with each other's scroll/inset state.Scroll position methods
getFirstVisibleCellInfo()— returns the first visible cell's index, pixel offset, and near-end statescrollToCellOffset(cellIndex, offsetInCell, animated?)— scrolls to a specific cell at a given pixel offsetChanges
aix.nitro.ts: AddedAixVisibleCellInfointerface and two new methods toAixMethodsHybridAix.swift:penultimateCellIndexsupport incalculateBlankSize,didMoveToWindowlifecycle for scroll reset,getFirstVisibleCellInfo()+scrollToCellOffset(), keyboard scopingHybridAix.kt: Android stubs for new methodsnitrogen/generated/: Regenerated viabun run codegenTest plan
mainScrollViewIDchangedidMoveToWindowpenultimateCellIndex={-1}→ blank padding is 0, last message sits above composer