Skip to content

Scroll next page trigger#1587

Merged
simo6529 merged 7 commits intomainfrom
scroll-next-page-trigger
Oct 31, 2025
Merged

Scroll next page trigger#1587
simo6529 merged 7 commits intomainfrom
scroll-next-page-trigger

Conversation

@simo6529
Copy link
Copy Markdown
Collaborator

@simo6529 simo6529 commented Oct 31, 2025

Summary by CodeRabbit

  • Improvements

    • Virtualized wave messages now auto-expand to reveal newly arrived drops, making new content visible without manual scrolling.
    • Smoother, more reliable reveal and loading of messages for a consistent browsing experience.
    • Improved scroll detection to maintain view stability as new drops appear.
  • Bug Fixes

    • More reliable home tab selection and initialization (respects URL/tab state and updates consistently).

Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Oct 31, 2025

Warning

Rate limit exceeded

@simo6529 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 17 minutes and 4 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between c2d6889 and 8592b12.

📒 Files selected for processing (1)
  • FooterWrapper.tsx (1 hunks)

Walkthrough

Replaces a literal rootMargin with a TOP_SENTINEL_ROOT_MARGIN constant for the top sentinel IntersectionObserver; refactors virtualization state to track previous drop counts and auto-advance virtualLimit when total drops increase; and streamlines home tab state/event handling to use typed HomeTab values and a stored-tab initializer.

Changes

Cohort / File(s) Summary
Intersection Observer
components/waves/drops/WaveDropsReverseContainer.tsx
Introduces TOP_SENTINEL_ROOT_MARGIN constant and uses it for the top sentinel's rootMargin; minor cleanup (removed inline comment). No behavior change beyond replacing the literal.
Virtualized messages / auto-advance
hooks/useVirtualizedWaveMessages.ts
Adds previousDropsCountRef, introduces activeMessages abstraction, conditions hasMoreLocal on message source, updates loadMoreLocally to respect source/pageSize, and auto-advances virtualLimit in pageSize increments when observed total drops increase. Adjusts effects and deps; no public API signature changes.
Home tab state & events
components/footer/FooterWrapper.tsx
Switches homeActiveTab state from string to typed HomeTab with lazy init via getStoredHomeTab; adds HOME_TAB_EVENT, HOME_TAB_QUERY_PARAM, and isHomeTab guard; validates query param and event detail as HomeTab before applying; simplifies event handling and storage logic.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Data as Server/Data
  participant Hook as useVirtualizedWaveMessages
  participant UI as Wave UI

  Note over Data,Hook: totalDrops increases (new drops arrive)
  Data->>Hook: totalDrops updated
  Hook->>Hook: compare totalDrops vs previousDropsCountRef
  alt initialized AND totalDrops > previous
    Hook->>Hook: virtualLimit = min(virtualLimit + pageSize, totalDrops)
    Hook->>UI: expose updated virtualLimit / activeMessages slice
    UI->>UI: render newly revealed drops
  else not initialized or no increase
    Hook--xUI: no auto-advance
  end
  Hook->>Hook: previousDropsCountRef = totalDrops
Loading
sequenceDiagram
  autonumber
  participant URL as Browser URL
  participant Footer as FooterWrapper
  participant Evt as External Event

  Note over URL,Footer: on mount
  URL->>Footer: read query param `tab`
  Footer->>Footer: isHomeTab(query) ? nextTab = query : nextTab = getStoredHomeTab()
  Footer->>Footer: setState(nextTab) if differs

  Note over Evt,Footer: on HOME_TAB_EVENT
  Evt->>Footer: dispatch(HomeTab detail)
  Footer->>Footer: isHomeTab(detail) ? setState(detail) : ignore
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Inspect the new effect in hooks/useVirtualizedWaveMessages.ts for potential rerender loops, race conditions, or edge cases when virtualLimit advances near totalDrops.
  • Verify correctness of activeMessages switching between per-drop and global sources and that hasMoreLocal is computed properly.
  • Confirm TOP_SENTINEL_ROOT_MARGIN value and that the sentinel behavior remains unchanged.
  • Check FooterWrapper.tsx event type narrowing and lazy init don't regress route/query scenarios.

Possibly related PRs

  • New desktop layout #1395 — Modifies FooterWrapper.tsx similarly (HOME_TAB_EVENT/getStoredHomeTab and typed tab state); likely directly related.

Suggested reviewers

  • ragnep

Poem

🐰
I hop through code with tiny taps,
Sentinels peek and drop maps snap.
Limits grow as new crumbs fall,
Tabs align and heed the call.
Hoppy deploys — carrots for all! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "Scroll next page trigger" refers to a real and relevant aspect of the changeset. The most substantial changes involve progressive virtualized loading in useVirtualizedWaveMessages.ts, which automatically expands the virtualization limit as the user scrolls and observes additional drops. The title captures this core concept of scroll-triggered pagination loading, though it doesn't fully convey the extensive state management refactoring with the new activeMessages abstraction and previousDropsCountRef tracking. The title is concise and readable, avoiding vague terms, and clearly indicates the primary mechanism being improved.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown

@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: 0

Caution

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

⚠️ Outside diff range comments (3)
components/waves/drops/WaveDropsReverseContainer.tsx (2)

67-77: Remove comments per coding guidelines.

As per coding guidelines for TypeScript files, comments should not be included in the code.

Apply this diff to remove the comments:

         const { scrollTop } = container;
-        // In a flex-col-reverse container, we're at the visual bottom when scrollTop is near 0
         const currentIsAtBottom = scrollTop > -5;
         isAtBottom.current = currentIsAtBottom;
-        // In a flex-col-reverse container, scrolling "up" means the scrollTop is increasing
-        // and scrolling "down" means the scrollTop is decreasing
         const direction = scrollTop < lastScrollTop.current ? "up" : "down";

79-86: Remove comment per coding guidelines.

As per coding guidelines for TypeScript files, comments should not be included in the code.

Apply this diff:

-    // Cleanup for any pending animation frames
     useEffect(() => {
hooks/useVirtualizedWaveMessages.ts (1)

1-270: Remove comments per coding guidelines.

As per coding guidelines for TypeScript files, comments should not be included in the code. The file contains multiple comments including:

  • JSDoc block comment at lines 40-47
  • Inline comments at lines 24, 75-78, 92-93, 106-107, 203, 214-216, 231, and others

These should be removed to comply with the coding guidelines.

🧹 Nitpick comments (1)
hooks/useVirtualizedWaveMessages.ts (1)

128-153: Auto-scroll logic looks good; minor simplification possible.

The effect correctly detects drop count increases and auto-advances the virtual limit. The implementation properly guards against edge cases.

Optional simplification: Line 148's ternary is redundant since nextLimit will always be greater than currentLimit at that point (you've already verified currentLimit < totalDrops at line 143).

Consider simplifying:

         const nextLimit = Math.min(totalDrops, currentLimit + pageSize);
-        return nextLimit > currentLimit ? nextLimit : currentLimit;
+        return nextLimit;
       });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ac2e2f8 and ad5d471.

📒 Files selected for processing (2)
  • components/waves/drops/WaveDropsReverseContainer.tsx (2 hunks)
  • hooks/useVirtualizedWaveMessages.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Do not include any comments in the code
Use react-query for data fetching
Always add readonly before props

Files:

  • components/waves/drops/WaveDropsReverseContainer.tsx
  • hooks/useVirtualizedWaveMessages.ts
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use FontAwesome for icons
Use TailwindCSS for styling

Files:

  • components/waves/drops/WaveDropsReverseContainer.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (3)
components/waves/drops/WaveDropsReverseContainer.tsx (1)

6-6: LGTM! The constant improves maintainability.

Extracting the root margin as a named constant makes the trigger threshold more explicit and easier to adjust. The increased margin from 1px to 200px will trigger the intersection observer earlier, supporting the auto-scroll behavior.

Also applies to: 52-52

hooks/useVirtualizedWaveMessages.ts (2)

83-83: LGTM! Proper use of ref for tracking previous state.

The ref correctly tracks the drop count across renders to detect increases.


125-125: LGTM! Correct reset on wave/drop change.

Resetting the previous count when the wave or drop changes prevents incorrect comparisons with stale data.

Signed-off-by: Simo <simo@6529.io>
Copy link
Copy Markdown

@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: 0

🧹 Nitpick comments (1)
hooks/useVirtualizedWaveMessages.ts (1)

97-102: [Pre-existing] Remove fullWaveMessagesRef.current from dependency arrays.

Including fullWaveMessagesRef.current in dependency arrays at lines 99, 152, 173, and 199 is incorrect. Ref objects themselves never change, so mutating .current won't trigger re-runs. This pattern can lead to stale closures.

The ref is updated in the effect at line 56, but effects/callbacks depending on it won't re-run when .current changes. Consider either:

  1. Using fullWaveMessages directly in the effect/callback bodies, or
  2. Omitting these dependencies if stale values are intentional for your use case

Note: This is a pre-existing issue, not introduced by this PR.

Also applies to: 151-157, 173-173, 199-199

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ad5d471 and 7766f2f.

📒 Files selected for processing (2)
  • components/waves/drops/WaveDropsReverseContainer.tsx (2 hunks)
  • hooks/useVirtualizedWaveMessages.ts (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/waves/drops/WaveDropsReverseContainer.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Do not include any comments in the code
Use react-query for data fetching
Always add readonly before props

Files:

  • hooks/useVirtualizedWaveMessages.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (5)
hooks/useVirtualizedWaveMessages.ts (5)

12-14: LGTM! Interface properly updated with readonly modifiers.

The interface changes correctly add allDropsCount and use readonly modifiers as per coding guidelines.


69-69: LGTM! Ref properly initialized for tracking drop count.

The previousDropsCountRef is correctly added to track the previous total drops count across renders.


104-108: LGTM! Reset logic correctly reinitializes state.

The effect properly resets virtualization state when wave, page size, or drop context changes.


110-136: Verify the previousTotal > 0 condition is intentional.

The auto-advance logic looks correct overall. However, the condition hasInitialized.current && previousTotal > 0 && totalDrops > previousTotal on line 123 will prevent auto-advancing when:

  • Initial load: 0 drops → 50 drops (previousTotal = 0)
  • Data cleared then reloaded: 0 drops → new drops (previousTotal = 0)

This appears intentional to avoid auto-advancing on initial load, but consider whether you want to auto-advance when data is cleared and reloaded.

Scenario trace:

  1. Initial load with 50 drops: previousTotal = 0, condition false, no auto-advance ✓
  2. New drops arrive (60 total): previousTotal = 50, condition true, auto-advances ✓
  3. Data cleared (0 drops): previousTotal = 0 after effect runs
  4. Data reloads (50 drops): previousTotal = 0, condition false, no auto-advance

If step 4 should auto-advance, consider removing the previousTotal > 0 check or adjusting the logic.


230-232: LGTM! allDropsCount correctly computed.

The calculation properly handles both drop-specific and general wave message contexts.

Copy link
Copy Markdown

@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: 0

🧹 Nitpick comments (2)
hooks/useVirtualizedWaveMessages.ts (2)

71-105: Consider refactoring duplicated initialization logic.

The dropId branch (lines 72-84) and non-dropId branch (lines 86-99) contain similar logic for updating hasMoreLocal and hasInitialized. This duplication could be reduced by extracting common logic.

Example refactor:

  useEffect(() => {
+   const activeMessages = dropId ? fullWaveMessagesForDrop : (fullWaveMessages ?? fullWaveMessagesRef.current);
+   
+   if (activeMessages) {
+     const totalDrops = activeMessages.drops.length;
+     setHasMoreLocal(totalDrops > virtualLimit);
+     
+     if (!hasInitialized.current && totalDrops > 0) {
+       hasInitialized.current = true;
+     }
+   } else {
+     setHasMoreLocal(false);
+     hasInitialized.current = false;
+   }
-   if (dropId) {
-     if (fullWaveMessagesForDrop) {
-       const totalDrops = fullWaveMessagesForDrop.drops.length;
-       setHasMoreLocal(totalDrops > virtualLimit);
-
-       if (!hasInitialized.current && totalDrops > 0) {
-         hasInitialized.current = true;
-       }
-     } else {
-       setHasMoreLocal(false);
-       hasInitialized.current = false;
-     }
-   }
-
-   const currentFullWaveMessages =
-     fullWaveMessages ?? fullWaveMessagesRef.current;
-
-   if (currentFullWaveMessages) {
-     const totalDrops = currentFullWaveMessages.drops.length;
-     setHasMoreLocal(totalDrops > virtualLimit);
-
-     if (!hasInitialized.current && totalDrops > 0) {
-       hasInitialized.current = true;
-     }
-   } else {
-     setHasMoreLocal(false);
-     hasInitialized.current = false;
-   }
  }, [
    dropId,
    fullWaveMessages,
    virtualLimit,
    fullWaveMessagesForDrop,
  ]);

140-154: Consider optimizing callback stability.

Including virtualLimit in the dependency array causes loadMoreLocally to be recreated frequently (every time the limit changes due to auto-advancement or manual loads). This may trigger unnecessary re-renders in components that depend on this callback.

Refactor to move the comparison inside the state updater:

  const loadMoreLocally = useCallback(() => {
-   if (dropId) {
-     if (
-       fullWaveMessagesForDrop &&
-       fullWaveMessagesForDrop.drops.length > virtualLimit
-     ) {
-       setVirtualLimit((prevLimit) => prevLimit + pageSize);
-     }
-   } else if (
-     fullWaveMessagesRef.current &&
-     fullWaveMessagesRef.current.drops.length > virtualLimit
-   ) {
-     setVirtualLimit((prevLimit) => prevLimit + pageSize);
-   }
- }, [virtualLimit, pageSize, fullWaveMessagesForDrop, dropId]);
+   setVirtualLimit((prevLimit) => {
+     const messages = dropId ? fullWaveMessagesForDrop : fullWaveMessagesRef.current;
+     const totalDrops = messages?.drops.length ?? 0;
+     return totalDrops > prevLimit ? prevLimit + pageSize : prevLimit;
+   });
+ }, [pageSize, fullWaveMessagesForDrop, dropId]);

This keeps the callback stable while virtualLimit changes, reducing re-renders of dependent components.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7766f2f and e980d57.

📒 Files selected for processing (1)
  • hooks/useVirtualizedWaveMessages.ts (8 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Do not include any comments in the code
Use react-query for data fetching
Always add readonly before props

Files:

  • hooks/useVirtualizedWaveMessages.ts
🔇 Additional comments (6)
hooks/useVirtualizedWaveMessages.ts (6)

10-21: LGTM!

The interface definition correctly uses readonly modifiers as required by the coding guidelines.


69-69: LGTM!

The previousDropsCountRef is properly introduced to track drop count changes for the auto-advancement feature.


107-111: LGTM!

The reset effect properly clears all state and refs when waveId, pageSize, or dropId changes, ensuring clean initialization.


113-138: LGTM! Core auto-advancement feature implemented correctly.

The effect properly:

  • Detects increases in total drops after initialization
  • Auto-advances virtualLimit by pageSize increments
  • Bounds advancement to not exceed totalDrops
  • Handles both dropId and non-dropId scenarios

The logic ensures advancement only occurs after initialization and when drops genuinely increase, which aligns with the PR objective.


156-171: LGTM!

The revealDrop callback correctly uses an empty dependency array since it only references the stable ref and state setter.


173-197: LGTM!

Good refactor to reuse revealDrop instead of duplicating logic. The dependency array is correct.

Signed-off-by: Simo <simo@6529.io>
Copy link
Copy Markdown

@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: 0

🧹 Nitpick comments (1)
FooterWrapper.tsx (1)

39-45: Consider typing the event parameter more precisely.

The event is typed as Event then immediately cast to CustomEvent<{ tab?: HomeTab }>. This can be improved by typing the parameter correctly from the start.

Apply this diff to improve type safety:

-    const handleTabChange = (event: Event) => {
-      const detail = (event as CustomEvent<{ tab?: HomeTab }>).detail;
+    const handleTabChange = (event: CustomEvent<{ tab?: HomeTab }>) => {
+      const detail = event.detail;
       if (!detail?.tab || !isHomeTab(detail.tab)) {
         return;
       }
       setHomeActiveTab(detail.tab);
     };

Then update the listener registration:

-    win.addEventListener(HOME_TAB_EVENT, handleTabChange as EventListener);
+    win.addEventListener(HOME_TAB_EVENT, handleTabChange as EventListener);

Note: The as EventListener cast is still needed due to TypeScript's built-in event listener types, but the handler function itself is now properly typed.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e980d57 and c2d6889.

📒 Files selected for processing (2)
  • FooterWrapper.tsx (1 hunks)
  • hooks/useVirtualizedWaveMessages.ts (6 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Do not include any comments in the code
Use react-query for data fetching
Always add readonly before props

Files:

  • FooterWrapper.tsx
  • hooks/useVirtualizedWaveMessages.ts
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use FontAwesome for icons
Use TailwindCSS for styling

Files:

  • FooterWrapper.tsx
🧬 Code graph analysis (1)
FooterWrapper.tsx (1)
hooks/useDeviceInfo.ts (1)
  • useDeviceInfo (22-78)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (14)
FooterWrapper.tsx (6)

4-8: LGTM!

The imports are well-structured and use proper TypeScript import syntax for both values and types.


13-14: LGTM!

Good practice to define the query parameter name as a constant for maintainability.


21-23: LGTM!

Proper use of lazy state initialization with explicit type annotation. This ensures getStoredHomeTab() is only called once during component mount.


30-37: LGTM!

Excellent defensive coding with type validation and fallback strategy. The functional state update pattern correctly prevents unnecessary re-renders when the computed tab matches the current state.


47-51: LGTM!

Proper event listener lifecycle management with symmetric registration and cleanup in the effect's return function.


15-16: Type guard is correctly synchronized with HomeTab type definition.

Verification confirms the type guard at lines 15-16 checks for "feed" | "latest", which matches the HomeTab type definition in components/home/useHomeTabs.ts (line 5). The code is currently in sync and correct.

hooks/useVirtualizedWaveMessages.ts (8)

12-14: LGTM! Readonly modifiers correctly applied.

The readonly modifiers align with the coding guidelines.


69-69: LGTM! Ref correctly tracks previous drop count.

The ref enables the auto-advance logic to detect when new drops arrive without triggering unnecessary re-renders.


71-92: LGTM! activeMessages abstraction simplifies message source handling.

The fallback to fullWaveMessagesRef.current prevents transient undefined states during transitions, and the initialization tracking correctly identifies when data becomes available.


94-98: LGTM! Clean state reset when key dependencies change.

Resetting all virtualization state (virtualLimit, hasInitialized, previousDropsCountRef) when waveId, pageSize, or dropId changes ensures correct behavior for the new context.


100-125: Verify the intentional design: activeWaveMessages without ref fallback.

The auto-advance logic uses activeWaveMessages = dropId ? fullWaveMessagesForDrop : fullWaveMessages (lines 101-103) without the ref fallback that the previous effect uses (line 74: fullWaveMessages ?? fullWaveMessagesRef.current). This appears intentional—the auto-advance should only trigger on fresh data from the hooks, not stale ref data—but confirm this design choice is correct.

Otherwise, the auto-advance implementation is sound:

  • Correctly prevents expansion on initial load (requires previousTotal > 0)
  • Safely handles decreasing drop counts (slice on line 191 is bounded)
  • Uses functional state update to avoid stale closures

127-136: LGTM! loadMoreLocally correctly refactored with functional state update.

The callback appropriately uses fullWaveMessagesRef.current for the non-dropId path and includes the correct dependencies. The functional update form prevents stale closure issues.


138-153: LGTM! Empty dependency array is correct for revealDrop.

The callback only references fullWaveMessagesRef.current (a ref) and setVirtualLimit (a state setter), both of which are stable across renders, so an empty dependency array is appropriate.


155-179: LGTM! waitAndRevealDrop correctly refactored with proper dependencies.

The callback appropriately delegates to revealDrop and includes both revealDrop and waveId in its dependency array, ensuring correct behavior when either changes.

@sonarqubecloud
Copy link
Copy Markdown

@simo6529 simo6529 merged commit b27cf01 into main Oct 31, 2025
8 checks passed
@simo6529 simo6529 deleted the scroll-next-page-trigger branch October 31, 2025 11:16
@coderabbitai coderabbitai Bot mentioned this pull request Jan 9, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Feb 5, 2026
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.

2 participants