Merge pull request #558 from GetStream/feat/messageListPaginationLimit

feat(ui, core): message list pagination limit [CDS-352]
This commit is contained in:
Salvatore Giordano
2021-07-22 12:01:34 +02:00
committed by GitHub
6 changed files with 53 additions and 13 deletions
@@ -2,6 +2,7 @@
✅ Added ✅ Added
- Added `MessageListView.paginationLimit`
- Allow the various ListView widgets to be themed via ThemeData classes - Allow the various ListView widgets to be themed via ThemeData classes
🐞 Fixed 🐞 Fixed
@@ -166,11 +166,15 @@ class MessageListView extends StatefulWidget {
this.showFloatingDateDivider = true, this.showFloatingDateDivider = true,
this.threadSeparatorBuilder, this.threadSeparatorBuilder,
this.messageListController, this.messageListController,
this.paginationLimit = 20,
}) : super(key: key); }) : super(key: key);
/// Function used to build a custom message widget /// Function used to build a custom message widget
final MessageBuilder? messageBuilder; final MessageBuilder? messageBuilder;
/// Limit used during pagination
final int paginationLimit;
/// Function used to build a custom system message widget /// Function used to build a custom system message widget
final SystemMessageBuilder? systemMessageBuilder; final SystemMessageBuilder? systemMessageBuilder;
@@ -328,6 +332,7 @@ class _MessageListViewState extends State<MessageListView> {
@override @override
Widget build(BuildContext context) => MessageListCore( Widget build(BuildContext context) => MessageListCore(
paginationLimit: widget.paginationLimit,
messageFilter: widget.messageFilter, messageFilter: widget.messageFilter,
loadingBuilder: widget.loadingBuilder ?? loadingBuilder: widget.loadingBuilder ??
(context) => const Center( (context) => const Center(
@@ -655,7 +660,9 @@ class _MessageListViewState extends State<MessageListView> {
); );
Future<void> _paginateData( Future<void> _paginateData(
StreamChannelState? channel, QueryDirection direction) => StreamChannelState? channel,
QueryDirection direction,
) =>
_messageListController.paginateData!(direction: direction); _messageListController.paginateData!(direction: direction);
int? _getTopElementIndex(Iterable<ItemPosition> values) { int? _getTopElementIndex(Iterable<ItemPosition> values) {
@@ -1,3 +1,8 @@
## Upcoming
✅ Added
- Added `MessageListCore.paginationLimit`
## 2.0.0 ## 2.0.0
🛑️ Breaking Changes from `1.5.3` 🛑️ Breaking Changes from `1.5.3`
@@ -71,6 +71,7 @@ class MessageListCore extends StatefulWidget {
this.parentMessage, this.parentMessage,
this.messageListController, this.messageListController,
this.messageFilter, this.messageFilter,
this.paginationLimit = 20,
}) : super(key: key); }) : super(key: key);
/// A [MessageListController] allows pagination. /// A [MessageListController] allows pagination.
@@ -86,6 +87,9 @@ class MessageListCore extends StatefulWidget {
/// Function used to build an empty widget /// Function used to build an empty widget
final WidgetBuilder emptyBuilder; final WidgetBuilder emptyBuilder;
/// Limit used to paginate messages
final int paginationLimit;
/// Callback triggered when an error occurs while performing the given /// Callback triggered when an error occurs while performing the given
/// request. /// request.
/// ///
@@ -163,13 +167,20 @@ class MessageListCoreState extends State<MessageListCore> {
/// Fetches more messages with updated pagination and updates the widget. /// Fetches more messages with updated pagination and updates the widget.
/// ///
/// Optionally pass the fetch direction, defaults to [QueryDirection.top] /// Optionally pass the fetch direction, defaults to [QueryDirection.top]
/// Optionally pass a limit, defaults to 20
Future<void> paginateData({ Future<void> paginateData({
QueryDirection direction = QueryDirection.top, QueryDirection direction = QueryDirection.top,
}) { }) {
if (!_isThreadConversation) { if (!_isThreadConversation) {
return _streamChannel!.queryMessages(direction: direction); return _streamChannel!.queryMessages(
direction: direction,
limit: widget.paginationLimit,
);
} else { } else {
return _streamChannel!.getReplies(widget.parentMessage!.id); return _streamChannel!.getReplies(
widget.parentMessage!.id,
limit: widget.paginationLimit,
);
} }
} }
@@ -179,7 +190,10 @@ class MessageListCoreState extends State<MessageListCore> {
if (newStreamChannel != _streamChannel) { if (newStreamChannel != _streamChannel) {
if (_streamChannel == null /*only first time*/ && _isThreadConversation) { if (_streamChannel == null /*only first time*/ && _isThreadConversation) {
newStreamChannel.getReplies(widget.parentMessage!.id); newStreamChannel.getReplies(
widget.parentMessage!.id,
limit: widget.paginationLimit,
);
} }
_streamChannel = newStreamChannel; _streamChannel = newStreamChannel;
} }
@@ -197,7 +211,10 @@ class MessageListCoreState extends State<MessageListCore> {
if (widget.parentMessage?.id != widget.parentMessage?.id) { if (widget.parentMessage?.id != widget.parentMessage?.id) {
if (_isThreadConversation) { if (_isThreadConversation) {
_streamChannel!.getReplies(widget.parentMessage!.id); _streamChannel!.getReplies(
widget.parentMessage!.id,
limit: widget.paginationLimit,
);
} }
} }
} }
@@ -147,9 +147,18 @@ class StreamChannelState extends State<StreamChannel> {
} }
/// Calls [channel.query] updating [queryMessage] stream /// Calls [channel.query] updating [queryMessage] stream
Future<void> queryMessages({QueryDirection? direction = QueryDirection.top}) { Future<void> queryMessages({
if (direction == QueryDirection.top) return _queryTopMessages(); QueryDirection? direction = QueryDirection.top,
return _queryBottomMessages(); int limit = 20,
}) {
if (direction == QueryDirection.top) {
return _queryTopMessages(
limit: limit,
);
}
return _queryBottomMessages(
limit: limit,
);
} }
/// Calls [channel.getReplies] updating [queryMessage] stream /// Calls [channel.getReplies] updating [queryMessage] stream
@@ -151,7 +151,9 @@ void main() {
(tester) async { (tester) async {
const messageListCoreKey = Key('messageListCore'); const messageListCoreKey = Key('messageListCore');
final controller = MessageListController(); final controller = MessageListController();
const paginationLimit = 10;
final messageListCore = MessageListCore( final messageListCore = MessageListCore(
paginationLimit: paginationLimit,
key: messageListCoreKey, key: messageListCoreKey,
messageListBuilder: (_, __) => const Offstage(), messageListBuilder: (_, __) => const Offstage(),
loadingBuilder: (BuildContext context) => const Offstage(), loadingBuilder: (BuildContext context) => const Offstage(),
@@ -165,10 +167,6 @@ void main() {
final mockChannel = MockChannel(); final mockChannel = MockChannel();
when(() => mockChannel.state.isUpToDate).thenReturn(true); when(() => mockChannel.state.isUpToDate).thenReturn(true);
// when(() => mockChannel.query(
// messagesPagination: any(named: 'messagesPagination'),
// preferOffline: any(named: 'preferOffline'),
// )).thenAnswer((_) => mockChannel.state);
final messages = _generateMessages(); final messages = _generateMessages();
when(() => mockChannel.state.messages).thenReturn(messages); when(() => mockChannel.state.messages).thenReturn(messages);
when(() => mockChannel.state.messagesStream) when(() => mockChannel.state.messagesStream)
@@ -191,7 +189,10 @@ void main() {
await coreState.paginateData(); await coreState.paginateData();
verify(() => mockChannel.query( verify(() => mockChannel.query(
messagesPagination: any(named: 'messagesPagination'), messagesPagination: any(
named: 'messagesPagination',
that: wrapMatcher((it) => it.limit == paginationLimit),
),
preferOffline: any(named: 'preferOffline'), preferOffline: any(named: 'preferOffline'),
)).called(1); )).called(1);
}, },