From 4896c43342bc5399db1583338097b7f2c5f339ce Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 13 May 2022 11:45:36 +0200 Subject: [PATCH 1/4] fix(llc, core): fix message pagination parameters --- .../lib/src/core/api/requests.dart | 41 +++++++++++++ .../lib/src/core/api/requests.g.dart | 24 ++++++++ .../core/models/attachment_file.freezed.dart | 59 ++++++++++++++----- .../lib/src/message_list_view.dart | 4 +- .../message_input/stream_message_input.dart | 2 + .../scrollable_positioned_list_test.dart | 2 +- .../lib/src/paged_value_scroll_view.dart | 4 +- .../lib/src/stream_channel.dart | 26 ++++---- .../lib/src/stream_chat_core.dart | 4 +- 9 files changed, 130 insertions(+), 36 deletions(-) diff --git a/packages/stream_chat/lib/src/core/api/requests.dart b/packages/stream_chat/lib/src/core/api/requests.dart index 3f4e79de..fa83ff73 100644 --- a/packages/stream_chat/lib/src/core/api/requests.dart +++ b/packages/stream_chat/lib/src/core/api/requests.dart @@ -1,3 +1,5 @@ +// ignore_for_file: deprecated_member_use_from_same_package + import 'package:equatable/equatable.dart'; import 'package:json_annotation/json_annotation.dart'; @@ -69,6 +71,11 @@ class PaginationParams extends Equatable { this.greaterThanOrEqual, this.lessThan, this.lessThanOrEqual, + this.createdAtAfterOrEqual, + this.createdAtAfter, + this.createdAtBeforeOrEqual, + this.createdAtBefore, + this.createdAtAround, }) : assert( offset == null || offset == 0 || next == null, 'Cannot specify non-zero `offset` with `next` parameter', @@ -82,9 +89,11 @@ class PaginationParams extends Equatable { final int limit; /// The amount of items requested before message ID from the APIs. + @Deprecated('before is deprecated, use limit instead') final int before; /// The amount of items requested after message ID from the APIs. + @Deprecated('after is deprecated, use limit instead') final int after; /// The offset of requesting items. @@ -113,6 +122,26 @@ class PaginationParams extends Equatable { @JsonKey(name: 'id_lte') final String? lessThanOrEqual; + /// Filter on createdAt greater than or equal the given value. + @JsonKey(name: 'created_at_after_or_equal') + final DateTime? createdAtAfterOrEqual; + + /// Filter on createdAt greater than the given value. + @JsonKey(name: 'created_at_after') + final DateTime? createdAtAfter; + + /// Filter on createdAt smaller than or equal the given value. + @JsonKey(name: 'created_at_before_or_equal') + final DateTime? createdAtBeforeOrEqual; + + /// Filter on createdAt smaller than the given value. + @JsonKey(name: 'created_at_before') + final DateTime? createdAtBefore; + + /// Filter on createdAt around the given value. + @JsonKey(name: 'created_at_around') + final DateTime? createdAtAround; + /// Serialize model to json Map toJson() => _$PaginationParamsToJson(this); @@ -128,6 +157,11 @@ class PaginationParams extends Equatable { String? greaterThanOrEqual, String? lessThan, String? lessThanOrEqual, + DateTime? createdAtAfterOrEqual, + DateTime? createdAtAfter, + DateTime? createdAtBeforeOrEqual, + DateTime? createdAtBefore, + DateTime? createdAtAround, }) => PaginationParams( limit: limit ?? this.limit, @@ -140,6 +174,13 @@ class PaginationParams extends Equatable { greaterThanOrEqual: greaterThanOrEqual ?? this.greaterThanOrEqual, lessThan: lessThan ?? this.lessThan, lessThanOrEqual: lessThanOrEqual ?? this.lessThanOrEqual, + createdAtAfterOrEqual: + createdAtAfterOrEqual ?? this.createdAtAfterOrEqual, + createdAtAfter: createdAtAfter ?? this.createdAtAfter, + createdAtBeforeOrEqual: + createdAtBeforeOrEqual ?? this.createdAtBeforeOrEqual, + createdAtBefore: createdAtBefore ?? this.createdAtBefore, + createdAtAround: createdAtAround ?? this.createdAtAround, ); @override diff --git a/packages/stream_chat/lib/src/core/api/requests.g.dart b/packages/stream_chat/lib/src/core/api/requests.g.dart index 62ec12b3..90bd789d 100644 --- a/packages/stream_chat/lib/src/core/api/requests.g.dart +++ b/packages/stream_chat/lib/src/core/api/requests.g.dart @@ -30,6 +30,21 @@ PaginationParams _$PaginationParamsFromJson(Map json) => greaterThanOrEqual: json['id_gte'] as String?, lessThan: json['id_lt'] as String?, lessThanOrEqual: json['id_lte'] as String?, + createdAtAfterOrEqual: json['created_at_after_or_equal'] == null + ? null + : DateTime.parse(json['created_at_after_or_equal'] as String), + createdAtAfter: json['created_at_after'] == null + ? null + : DateTime.parse(json['created_at_after'] as String), + createdAtBeforeOrEqual: json['created_at_before_or_equal'] == null + ? null + : DateTime.parse(json['created_at_before_or_equal'] as String), + createdAtBefore: json['created_at_before'] == null + ? null + : DateTime.parse(json['created_at_before'] as String), + createdAtAround: json['created_at_around'] == null + ? null + : DateTime.parse(json['created_at_around'] as String), ); Map _$PaginationParamsToJson(PaginationParams instance) { @@ -52,6 +67,15 @@ Map _$PaginationParamsToJson(PaginationParams instance) { writeNotNull('id_gte', instance.greaterThanOrEqual); writeNotNull('id_lt', instance.lessThan); writeNotNull('id_lte', instance.lessThanOrEqual); + writeNotNull('created_at_after_or_equal', + instance.createdAtAfterOrEqual?.toIso8601String()); + writeNotNull('created_at_after', instance.createdAtAfter?.toIso8601String()); + writeNotNull('created_at_before_or_equal', + instance.createdAtBeforeOrEqual?.toIso8601String()); + writeNotNull( + 'created_at_before', instance.createdAtBefore?.toIso8601String()); + writeNotNull( + 'created_at_around', instance.createdAtAround?.toIso8601String()); return val; } diff --git a/packages/stream_chat/lib/src/core/models/attachment_file.freezed.dart b/packages/stream_chat/lib/src/core/models/attachment_file.freezed.dart index f6442a53..634af64f 100644 --- a/packages/stream_chat/lib/src/core/models/attachment_file.freezed.dart +++ b/packages/stream_chat/lib/src/core/models/attachment_file.freezed.dart @@ -12,7 +12,7 @@ part of 'attachment_file.dart'; T _$identity(T value) => value; final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); UploadState _$UploadStateFromJson(Map json) { switch (json['runtimeType']) { @@ -31,6 +31,39 @@ UploadState _$UploadStateFromJson(Map json) { } } +/// @nodoc +class _$UploadStateTearOff { + const _$UploadStateTearOff(); + + Preparing preparing() { + return const Preparing(); + } + + InProgress inProgress({required int uploaded, required int total}) { + return InProgress( + uploaded: uploaded, + total: total, + ); + } + + Success success() { + return const Success(); + } + + Failed failed({required String error}) { + return Failed( + error: error, + ); + } + + UploadState fromJson(Map json) { + return UploadState.fromJson(json); + } +} + +/// @nodoc +const $UploadState = _$UploadStateTearOff(); + /// @nodoc mixin _$UploadState { @optionalTypeArgs @@ -121,7 +154,7 @@ class _$PreparingCopyWithImpl<$Res> extends _$UploadStateCopyWithImpl<$Res> /// @nodoc @JsonSerializable() class _$Preparing implements Preparing { - const _$Preparing({final String? $type}) : $type = $type ?? 'preparing'; + const _$Preparing({String? $type}) : $type = $type ?? 'preparing'; factory _$Preparing.fromJson(Map json) => _$$PreparingFromJson(json); @@ -140,7 +173,6 @@ class _$Preparing implements Preparing { (other.runtimeType == runtimeType && other is Preparing); } - @JsonKey(ignore: true) @override int get hashCode => runtimeType.hashCode; @@ -269,7 +301,7 @@ class _$InProgressCopyWithImpl<$Res> extends _$UploadStateCopyWithImpl<$Res> @JsonSerializable() class _$InProgress implements InProgress { const _$InProgress( - {required this.uploaded, required this.total, final String? $type}) + {required this.uploaded, required this.total, String? $type}) : $type = $type ?? 'inProgress'; factory _$InProgress.fromJson(Map json) => @@ -297,7 +329,6 @@ class _$InProgress implements InProgress { const DeepCollectionEquality().equals(other.total, total)); } - @JsonKey(ignore: true) @override int get hashCode => Object.hash( runtimeType, @@ -390,14 +421,14 @@ class _$InProgress implements InProgress { } abstract class InProgress implements UploadState { - const factory InProgress( - {required final int uploaded, required final int total}) = _$InProgress; + const factory InProgress({required int uploaded, required int total}) = + _$InProgress; factory InProgress.fromJson(Map json) = _$InProgress.fromJson; - int get uploaded => throw _privateConstructorUsedError; - int get total => throw _privateConstructorUsedError; + int get uploaded; + int get total; @JsonKey(ignore: true) $InProgressCopyWith get copyWith => throw _privateConstructorUsedError; @@ -422,7 +453,7 @@ class _$SuccessCopyWithImpl<$Res> extends _$UploadStateCopyWithImpl<$Res> /// @nodoc @JsonSerializable() class _$Success implements Success { - const _$Success({final String? $type}) : $type = $type ?? 'success'; + const _$Success({String? $type}) : $type = $type ?? 'success'; factory _$Success.fromJson(Map json) => _$$SuccessFromJson(json); @@ -441,7 +472,6 @@ class _$Success implements Success { (other.runtimeType == runtimeType && other is Success); } - @JsonKey(ignore: true) @override int get hashCode => runtimeType.hashCode; @@ -563,7 +593,7 @@ class _$FailedCopyWithImpl<$Res> extends _$UploadStateCopyWithImpl<$Res> /// @nodoc @JsonSerializable() class _$Failed implements Failed { - const _$Failed({required this.error, final String? $type}) + const _$Failed({required this.error, String? $type}) : $type = $type ?? 'failed'; factory _$Failed.fromJson(Map json) => @@ -588,7 +618,6 @@ class _$Failed implements Failed { const DeepCollectionEquality().equals(other.error, error)); } - @JsonKey(ignore: true) @override int get hashCode => Object.hash(runtimeType, const DeepCollectionEquality().hash(error)); @@ -679,11 +708,11 @@ class _$Failed implements Failed { } abstract class Failed implements UploadState { - const factory Failed({required final String error}) = _$Failed; + const factory Failed({required String error}) = _$Failed; factory Failed.fromJson(Map json) = _$Failed.fromJson; - String get error => throw _privateConstructorUsedError; + String get error; @JsonKey(ignore: true) $FailedCopyWith get copyWith => throw _privateConstructorUsedError; } diff --git a/packages/stream_chat_flutter/lib/src/message_list_view.dart b/packages/stream_chat_flutter/lib/src/message_list_view.dart index 7d77b2ea..b0a1ef8d 100644 --- a/packages/stream_chat_flutter/lib/src/message_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/message_list_view.dart @@ -889,7 +889,7 @@ class _StreamMessageListViewState extends State { initialIndex = 0; await streamChannel!.reloadChannel(); - WidgetsBinding.instance?.addPostFrameCallback((_) { + WidgetsBinding.instance.addPostFrameCallback((_) { _scrollController!.jumpTo(index: 0); }); } else { @@ -1341,7 +1341,7 @@ class _StreamMessageListViewState extends State { if (event.message?.parentId == widget.parentMessage?.id && event.message!.user!.id == streamChannel!.channel.client.state.currentUser!.id) { - WidgetsBinding.instance!.addPostFrameCallback((_) { + WidgetsBinding.instance.addPostFrameCallback((_) { _scrollController?.scrollTo( index: 0, duration: const Duration(seconds: 1), diff --git a/packages/stream_chat_flutter/lib/src/v4/message_input/stream_message_input.dart b/packages/stream_chat_flutter/lib/src/v4/message_input/stream_message_input.dart index 808760c7..227f4e09 100644 --- a/packages/stream_chat_flutter/lib/src/v4/message_input/stream_message_input.dart +++ b/packages/stream_chat_flutter/lib/src/v4/message_input/stream_message_input.dart @@ -1,3 +1,5 @@ +// ignore_for_file: deprecated_member_use_from_same_package + import 'dart:async'; import 'dart:math'; diff --git a/packages/stream_chat_flutter/test/scrollable_positioned_list/scrollable_positioned_list_test.dart b/packages/stream_chat_flutter/test/scrollable_positioned_list/scrollable_positioned_list_test.dart index 79845215..aa1a78ca 100644 --- a/packages/stream_chat_flutter/test/scrollable_positioned_list/scrollable_positioned_list_test.dart +++ b/packages/stream_chat_flutter/test/scrollable_positioned_list/scrollable_positioned_list_test.dart @@ -1317,7 +1317,7 @@ void main() { await setUpWidgetTest(tester, itemPositionsListener: itemPositionsListener); final root = WidgetsBinding - .instance!.pipelineOwner.semanticsOwner!.rootSemanticsNode!; + .instance.pipelineOwner.semanticsOwner!.rootSemanticsNode!; final semanticNodes = [root]; diff --git a/packages/stream_chat_flutter_core/lib/src/paged_value_scroll_view.dart b/packages/stream_chat_flutter_core/lib/src/paged_value_scroll_view.dart index 00d96f56..7b7f56c3 100644 --- a/packages/stream_chat_flutter_core/lib/src/paged_value_scroll_view.dart +++ b/packages/stream_chat_flutter_core/lib/src/paged_value_scroll_view.dart @@ -322,7 +322,7 @@ class _PagedValueListViewState extends State> { index == newPageRequestTriggerIndex; if (nextPageKey != null && isBuildingTriggerIndexItem) { // Schedules the request for the end of this frame. - WidgetsBinding.instance?.addPostFrameCallback((_) async { + WidgetsBinding.instance.addPostFrameCallback((_) async { if (error == null) { await _controller.loadMore(nextPageKey); } @@ -678,7 +678,7 @@ class _PagedValueGridViewState extends State> { index == newPageRequestTriggerIndex; if (nextPageKey != null && isBuildingTriggerIndexItem) { // Schedules the request for the end of this frame. - WidgetsBinding.instance?.addPostFrameCallback((_) async { + WidgetsBinding.instance.addPostFrameCallback((_) async { if (error == null) { await _controller.loadMore(nextPageKey); } diff --git a/packages/stream_chat_flutter_core/lib/src/stream_channel.dart b/packages/stream_chat_flutter_core/lib/src/stream_channel.dart index 47822791..6e096cfa 100644 --- a/packages/stream_chat_flutter_core/lib/src/stream_channel.dart +++ b/packages/stream_chat_flutter_core/lib/src/stream_channel.dart @@ -220,21 +220,20 @@ class StreamChannelState extends State { /// Loads channel at specific message Future loadChannelAtMessage( String? messageId, { - int before = 20, - int after = 20, + @Deprecated('before is deprecated, use limit instead') int before = 20, + @Deprecated('before is deprecated, use limit instead') int after = 20, + int limit = 20, bool preferOffline = false, }) => _queryAtMessage( messageId: messageId, - before: before, - after: after, + limit: limit, preferOffline: preferOffline, ); Future _queryAtMessage({ String? messageId, - int before = 20, - int after = 20, + int limit = 20, bool preferOffline = false, }) async { if (channel.state == null) return null; @@ -244,7 +243,7 @@ class StreamChannelState extends State { if (messageId == null) { await channel.query( messagesPagination: PaginationParams( - limit: before, + limit: limit, ), preferOffline: preferOffline, ); @@ -254,8 +253,7 @@ class StreamChannelState extends State { return queryAroundMessage( messageId, - before: before, - after: after, + limit: limit, preferOffline: preferOffline, ); } @@ -263,15 +261,15 @@ class StreamChannelState extends State { /// Future queryAroundMessage( String messageId, { - int before = 20, - int after = 20, + @Deprecated('before is deprecated, use limit instead') int before = 20, + @Deprecated('after is deprecated, use limit instead') int after = 20, + int limit = 20, bool preferOffline = false, }) => channel.query( messagesPagination: PaginationParams( idAround: messageId, - before: before, - after: after, + limit: limit, ), preferOffline: preferOffline, ); @@ -338,7 +336,7 @@ class StreamChannelState extends State { } /// Reloads the channel with latest message - Future reloadChannel() => _queryAtMessage(before: 30); + Future reloadChannel() => _queryAtMessage(limit: 30); late List> _futures; diff --git a/packages/stream_chat_flutter_core/lib/src/stream_chat_core.dart b/packages/stream_chat_flutter_core/lib/src/stream_chat_core.dart index 82f0a5d6..22d16568 100644 --- a/packages/stream_chat_flutter_core/lib/src/stream_chat_core.dart +++ b/packages/stream_chat_flutter_core/lib/src/stream_chat_core.dart @@ -115,7 +115,7 @@ class StreamChatCoreState extends State @override void initState() { super.initState(); - WidgetsBinding.instance?.addObserver(this); + WidgetsBinding.instance.addObserver(this); _subscribeToConnectivityChange(widget.connectivityStream); } @@ -207,7 +207,7 @@ class StreamChatCoreState extends State @override void dispose() { - WidgetsBinding.instance?.removeObserver(this); + WidgetsBinding.instance.removeObserver(this); _unsubscribeFromConnectivityChange(); _eventSubscription?.cancel(); _disconnectTimer?.cancel(); From 869730ca8f2111fc3c333212ca3323c6ba1d979a Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 13 May 2022 11:52:11 +0200 Subject: [PATCH 2/4] chore(llc,core): update changelog --- packages/stream_chat/CHANGELOG.md | 14 ++++++++++++++ packages/stream_chat_flutter_core/CHANGELOG.md | 7 +++++++ 2 files changed, 21 insertions(+) diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index 7609e0c3..48c4dd4d 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -1,3 +1,17 @@ +## Upcoming + +✅ Added + +- Added `PaginationParams.createdAtAfterOrEqual` for message pagination. +- Added `PaginationParams.createdAtAfter` for message pagination. +- Added `PaginationParams.createdAtBeforeOrEqual` for message pagination. +- Added `PaginationParams.createdAtBefore` for message pagination. +- Added `PaginationParams.createdAtAround` for message pagination. + +🔄 Changed + +- Deprecated `PaginationParams.before` and `PaginationParams.after`. Use `PaginationParams.limit` instead. + ## 4.1.0 ✅ Added diff --git a/packages/stream_chat_flutter_core/CHANGELOG.md b/packages/stream_chat_flutter_core/CHANGELOG.md index 7eb8845a..4ed4e192 100644 --- a/packages/stream_chat_flutter_core/CHANGELOG.md +++ b/packages/stream_chat_flutter_core/CHANGELOG.md @@ -1,3 +1,10 @@ +## Upcoming + +🔄 Changed + +- Deprecated `before` and `after` parameters in `StreamChannel.queryAroundMessage`. Use `limit` instead. +- Deprecated `before` and `after` parameters in `StreamChannel.loadChannelAtMessage`. Use `limit` instead. + ## 4.1.0 - Updated `stream_chat` dependency to [`4.1.0`](https://pub.dev/packages/stream_chat/changelog). From e178b9143f7731792625ef69e60ae13b2f8fb80e Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Mon, 16 May 2022 16:28:19 +0200 Subject: [PATCH 3/4] fix tests --- .../stream_chat_flutter_core/test/stream_channel_test.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/stream_chat_flutter_core/test/stream_channel_test.dart b/packages/stream_chat_flutter_core/test/stream_channel_test.dart index cccea24d..673bd4da 100644 --- a/packages/stream_chat_flutter_core/test/stream_channel_test.dart +++ b/packages/stream_chat_flutter_core/test/stream_channel_test.dart @@ -211,8 +211,7 @@ void main() { final paginationParams = PaginationParams( idAround: initialMessageId, - after: 20, - before: 20, + limit: 20, ); when(() => mockChannel.initialized).thenAnswer((_) async => true); From e054310fa294653107dade9bc606b5fd897c2f62 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Mon, 16 May 2022 16:56:13 +0200 Subject: [PATCH 4/4] fix typo --- packages/stream_chat_flutter_core/lib/src/stream_channel.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter_core/lib/src/stream_channel.dart b/packages/stream_chat_flutter_core/lib/src/stream_channel.dart index 4908c28a..18e494e2 100644 --- a/packages/stream_chat_flutter_core/lib/src/stream_channel.dart +++ b/packages/stream_chat_flutter_core/lib/src/stream_channel.dart @@ -221,7 +221,7 @@ class StreamChannelState extends State { Future loadChannelAtMessage( String? messageId, { @Deprecated('before is deprecated, use limit instead') int before = 20, - @Deprecated('before is deprecated, use limit instead') int after = 20, + @Deprecated('after is deprecated, use limit instead') int after = 20, int limit = 20, bool preferOffline = false, }) =>