Skip to content

Conversation

xsahil03x
Copy link
Member

@xsahil03x xsahil03x commented Jun 26, 2025

Description of the pull request

This PR addresses two issues:

  1. Scroll to Bottom: The logic for determining if the last item is fully visible was flawed, causing the "scroll to bottom" button to appear incorrectly in some cases. This has been fixed by checking if the last item's leading edge is greater than or equal to 0.

  2. Floating Date Divider: The floating date divider was not correctly calculating the date for messages in case the message widget exceeds the viewport height. This has been fixed by adjusting the index calculations to account for these items and ensuring that the divider only considers actual message widgets.

Additionally, the isThreadConversation property in FloatingDateDivider has been deprecated as it's no longer used. The utility functions getTopElementIndex and getBottomElementIndex have also been updated to ignore items that are not actually rendering anything in the viewport.

Screenshots / Videos

Before After
Screen.Recording.2025-06-26.at.05.07.03.mov
Screen.Recording.2025-06-26.at.05.05.02.mov

Summary by CodeRabbit

  • Bug Fixes

    • Resolved issues with the date divider and scroll-to-bottom button when the latest message is very large and exceeds the viewport, ensuring correct UI behavior in these scenarios.
  • Documentation

    • Updated the changelog with details on recent bug fixes.
  • Refactor

    • Simplified and clarified the logic for displaying the date divider and determining visible items, improving UI consistency and code maintainability.
  • Tests

    • Expanded and restructured tests for the date divider to cover edge cases, boundary conditions, and custom date divider usage, increasing test coverage and robustness.

This commit addresses two issues:

1.  **Scroll to Bottom:** The logic for determining if the last item is fully visible was flawed, causing the "scroll to bottom" button to appear incorrectly in some cases. This has been fixed by checking if the last item's leading edge is greater than or equal to 0.

2.  **Floating Date Divider:** The floating date divider was not correctly calculating the date for messages in case the message widget exceeds the viewport height. This has been fixed by adjusting the index calculations to account for these items and ensuring that the divider only considers actual message widgets.

Additionally, the `isThreadConversation` property in `FloatingDateDivider` has been deprecated as it's no longer used. The utility functions `getTopElementIndex` and `getBottomElementIndex` have also been updated to ignore items that are not actually rendering anything in the viewport.
Copy link
Contributor

coderabbitai bot commented Jun 26, 2025

Walkthrough

This update refines the message list view logic in the stream_chat_flutter package. It clarifies how the FloatingDateDivider is rendered, updates scroll visibility checks for the "ScrollToBottom" button, and improves utility functions for determining visible elements. Deprecated properties are annotated, and the changelog is updated with these bug fixes.

Changes

File(s) Change Summary
CHANGELOG.md Added "Upcoming" section listing two UI bug fixes related to large messages and viewport behavior.
floating_date_divider.dart Removed deprecated isThreadConversation logic, clarified index checks, improved control flow, deprecated related fields.
message_list_view.dart Removed use of _isThreadConversation, revised logic for checking last item visibility in scroll handling.
mlv_utils.dart Updated element index functions to exclude items with no visible content (leading == trailing edge).
floating_date_divider_test.dart Expanded and restructured tests to cover empty states, valid rendering, reverse mode, boundary cases, and bug fixes related to viewport and zero-height items.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant MessageListView
    participant FloatingDateDivider
    participant ScrollToBottomButton

    User->>MessageListView: Scrolls through messages
    MessageListView->>FloatingDateDivider: Determines if date divider should display
    FloatingDateDivider-->>MessageListView: Returns date divider widget or empty
    MessageListView->>ScrollToBottomButton: Checks if last item is visible
    alt Last item not fully visible
        ScrollToBottomButton-->>User: Show "Scroll to Bottom" button
    else Last item fully visible
        ScrollToBottomButton-->>User: Hide button, call last item visible handler
    end
Loading

Poem

In a meadow of messages, tall and wide,
The date divider now knows where to hide.
No more buttons that stubbornly stay,
When the last chat drifts out of the way.
With clearer code and a changelog bright,
This bunny hops on, making things right! 🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d3fd4b6 and c624230.

📒 Files selected for processing (1)
  • packages/stream_chat_flutter/lib/src/message_list_view/floating_date_divider.dart (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/stream_chat_flutter/lib/src/message_list_view/floating_date_divider.dart
⏰ Context from checks skipped due to timeout of 90000ms (10)
  • GitHub Check: build (android)
  • GitHub Check: test
  • GitHub Check: analyze
  • GitHub Check: format
  • GitHub Check: analyze_legacy_versions
  • GitHub Check: stream_chat_flutter
  • GitHub Check: stream_chat_localizations
  • GitHub Check: stream_chat_flutter_core
  • GitHub Check: stream_chat_persistence
  • GitHub Check: stream_chat

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@xsahil03x xsahil03x requested a review from renefloor June 26, 2025 03:14
Copy link
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: 0

🧹 Nitpick comments (1)
packages/stream_chat_flutter/lib/src/message_list_view/mlv_utils.dart (1)

46-54: Consider combining filter conditions for minor optimization.

The filtering logic works correctly, but you could slightly optimize by combining the conditions into a single filter:

-  final inView = values.where((position) {
-    if (position.itemLeadingEdge == position.itemTrailingEdge) {
-      // If the item's leading and trailing edges are the same, it means the
-      // item isn't actually rendering anything in the viewport.
-      return false;
-    }
-
-    return position.itemTrailingEdge > 0;
-  });
+  final inView = values.where((position) {
+    // Exclude items that aren't rendering anything (zero size) and
+    // items that are not visible in the viewport
+    return position.itemLeadingEdge != position.itemTrailingEdge &&
+           position.itemTrailingEdge > 0;
+  });

Apply the same pattern to getBottomElementIndex. However, the current approach is perfectly fine and more readable.

Also applies to: 64-72

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 344a10d and daba0e7.

📒 Files selected for processing (4)
  • packages/stream_chat_flutter/CHANGELOG.md (1 hunks)
  • packages/stream_chat_flutter/lib/src/message_list_view/floating_date_divider.dart (2 hunks)
  • packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart (1 hunks)
  • packages/stream_chat_flutter/lib/src/message_list_view/mlv_utils.dart (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (11)
  • GitHub Check: analyze_legacy_versions
  • GitHub Check: stream_chat_localizations
  • GitHub Check: stream_chat_flutter_core
  • GitHub Check: stream_chat_flutter
  • GitHub Check: stream_chat_persistence
  • GitHub Check: stream_chat
  • GitHub Check: build (android)
  • GitHub Check: build (ios)
  • GitHub Check: analyze
  • GitHub Check: format
  • GitHub Check: test
🔇 Additional comments (8)
packages/stream_chat_flutter/CHANGELOG.md (1)

1-9: LGTM! Clear and well-documented bug fixes.

The changelog entries accurately document the bug fixes for UI behavior when messages exceed viewport size. The descriptions are specific and follow the established formatting conventions.

packages/stream_chat_flutter/lib/src/message_list_view/mlv_utils.dart (2)

46-54: Good filtering logic to exclude zero-size items.

The addition of the zero-size item filter makes sense and improves the accuracy of viewport visibility calculations. The comment clearly explains the reasoning.


64-72: Consistent filtering logic applied correctly.

The same zero-size filtering logic is properly applied to the bottom element detection, maintaining consistency between the two functions.

packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart (2)

1454-1466: LGTM! Improved scroll-to-bottom visibility logic.

The new logic correctly addresses the issue mentioned in the PR objectives. Using a direct positional comparison with itemLeadingEdge >= 0 is more reliable than the previous helper-based approach for determining if the last item is fully visible.

The hardcoded lastItemIndex = 2 is well-documented and consistent with the item structure described in the comments (lines 649-666).


854-860: Properly removed deprecated parameter.

The removal of the isThreadConversation parameter aligns with its deprecation in the FloatingDateDivider component. This cleanup maintains backward compatibility while moving toward the simplified implementation.

packages/stream_chat_flutter/lib/src/message_list_view/floating_date_divider.dart (3)

19-20: Proper deprecation of unused property.

The isThreadConversation property is correctly marked as deprecated with clear annotation. This provides a smooth transition path while maintaining backward compatibility.

Also applies to: 25-26


52-76: Excellent refactor of index calculation logic.

The new explicit approach for handling special list items is much clearer and more maintainable than the previous conditional logic. Each special item type (parent message, header, loaders, footer) is explicitly handled, and the message index calculation index - 2 properly accounts for the extra non-message items.

This addresses the PR objective of fixing the floating date divider when messages exceed viewport height.


78-82: Simplified and improved date divider builder logic.

The streamlined approach using pattern matching with case is cleaner and more readable than the previous implementation. The direct builder call and fallback to StreamDateDivider is well-structured.

Copy link

codecov bot commented Jun 26, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Please upload report for BASE (master@344a10d). Learn more about missing BASE report.
Report is 2 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff            @@
##             master    #2289   +/-   ##
=========================================
  Coverage          ?   63.51%           
=========================================
  Files             ?      408           
  Lines             ?    25518           
  Branches          ?        0           
=========================================
  Hits              ?    16207           
  Misses            ?     9311           
  Partials          ?        0           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment on lines 57 to 71
if (index == null) return const Empty();

// We can only calculate the date divider if the element is a message
// widget and not one of the special items.

// Parent Message
if (index == itemCount - 1) return const Empty();
// Header Builder
if (index == itemCount - 2) return const Empty();
// Top Loader Builder
if (index == itemCount - 3) return const Empty();
// Bottom Loader Builder
if (index == 1) return const Empty();
// Footer Builder
if (index == 0) return const Empty();
Copy link
Contributor

Choose a reason for hiding this comment

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

I would create a different method for it, this is adding quite some noise

Just like this:

if(!_shouldShowDivider(index)) return const Empty();

with:

bool _shouldShowDivider(int index){
  return index != null &&
    
    // We can only calculate the date divider if the element is a message
    // widget and not one of the special items.

    // Parent Message
    index != itemCount - 1 &&
    // Header Builder
    index != itemCount - 2 &&
    // Top Loader Builder
    index != itemCount - 3 &&
    // Bottom Loader Builder
    index != 1 &&
    // Footer Builder
    index != 0;
}

Copy link
Member Author

Choose a reason for hiding this comment

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

@xsahil03x xsahil03x requested a review from renefloor June 26, 2025 11:20
@xsahil03x xsahil03x merged commit 122a516 into master Jun 27, 2025
22 of 23 checks passed
@xsahil03x xsahil03x deleted the fix/floating-date-divider branch June 27, 2025 09:26
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