Skip to content

Use scroll offset for loading more content in channel and message list #838

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: develop
Choose a base branch
from

Conversation

laevandus
Copy link
Contributor

@laevandus laevandus commented May 27, 2025

🔗 Issue Links

Resolves: IOS-793

🎯 Goal

If channel list is scrolled very quickly while it is loading a new page it stops loading additional pages

📝 Summary

  • Add a new view modifier for easy pagination handling: onScrollPaginationChanged(in:flipped:threshold:onBottomThreshold:onTopThreshold:)
  • Use the view modifier in MessageList and ChannelList
  • Adds backwards compatibility through usesContentOffsetBasedLoadMore (since public init methods get additional arguments)

🛠 Implementation

The new modifier adds GeometryReader to the background of the view which gives us scrolled offset and the content size. Based on the threshold, it calls one of the closures which in turn has to be hooked up the view model for loading new pages.

🎨 Showcase

Before After
img img

🧪 Manual Testing Notes

Explain how this change can be tested manually, if applicable.

☑️ Contributor Checklist

  • I have signed the Stream CLA (required)
  • This change should be manually QAed
  • Changelog is updated with client-facing changes
  • Changelog is updated with new localization keys
  • New code is covered by unit tests
  • Documentation has been updated in the docs-content repo

@laevandus laevandus requested a review from a team as a code owner May 27, 2025 07:58
@laevandus laevandus marked this pull request as draft May 27, 2025 07:58
@Stream-SDK-Bot
Copy link
Collaborator

Stream-SDK-Bot commented May 27, 2025

SDK Size

title develop branch diff status
StreamChatSwiftUI 8.25 MB 8.27 MB +18 KB 🟢

@laevandus laevandus force-pushed the feature/offset-based-load-more branch from ac9bc95 to cc0353f Compare May 27, 2025 08:33
@laevandus laevandus added the ✅ Feature An issue or PR related to a feature label May 27, 2025
func onScrollPaginationChanged(
in coordinateSpace: CoordinateSpace = .global,
flipped: Bool = false,
threshold: CGFloat = 400,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

From UIKit SDK

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Might need some fine-tuning

Comment on lines +27 to +36
func handleGeometryChanged(_ geometry: GeometryProxy) {
let frame = geometry.frame(in: coordinateSpace)
guard frame.size.height > 0 else { return }
let offset = -frame.minY
if offset + UIScreen.main.bounds.height + threshold > frame.height {
flipped ? onTopThreshold?() : onBottomThreshold()
} else if offset < threshold {
flipped ? onBottomThreshold() : onTopThreshold?()
}
}
Copy link
Contributor Author

@laevandus laevandus May 27, 2025

Choose a reason for hiding this comment

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

It is way too difficult to get the height of the visible rect for precise calculations. Therefore, using inaccurate screen height here for simplifying it.
Geometry gives the height of the whole content view.

Copy link
Contributor

Choose a reason for hiding this comment

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

this might slow things down though, wdyt?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah overall, it feels like on develop, things load faster and are bit smoother. 🤔

@laevandus laevandus force-pushed the feature/offset-based-load-more branch from cc0353f to a2fc6a8 Compare May 27, 2025 08:40
Copy link

@laevandus laevandus marked this pull request as ready for review May 30, 2025 06:49
Copy link
Contributor

@martinmitrevski martinmitrevski left a comment

Choose a reason for hiding this comment

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

Let's wait before merging this one until I'm back - I want to check it in more details and test it.

Comment on lines +27 to +36
func handleGeometryChanged(_ geometry: GeometryProxy) {
let frame = geometry.frame(in: coordinateSpace)
guard frame.size.height > 0 else { return }
let offset = -frame.minY
if offset + UIScreen.main.bounds.height + threshold > frame.height {
flipped ? onTopThreshold?() : onBottomThreshold()
} else if offset < threshold {
flipped ? onBottomThreshold() : onTopThreshold?()
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

this might slow things down though, wdyt?

@laevandus laevandus marked this pull request as draft May 30, 2025 13:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐞 Bug ✅ Feature An issue or PR related to a feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants