From e5abb8fffe444f989c541a04d3d5d2564ef7448e Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 26 Nov 2021 10:36:57 +0100 Subject: [PATCH 1/6] fix(llc): ChannelEvent.membersCount default to 0 --- .../core/models/attachment_file.freezed.dart | 74 +++++++++++-------- .../src/core/models/attachment_file.g.dart | 21 ++++-- .../lib/src/core/models/event.dart | 2 +- .../lib/src/core/models/event.g.dart | 2 +- .../stream_chat/lib/src/ws/websocket.dart | 5 +- packages/stream_chat/pubspec.yaml | 2 +- 6 files changed, 66 insertions(+), 40 deletions(-) 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 4956274a..6b7b00cf 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 @@ -14,7 +14,7 @@ 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 informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); UploadState _$UploadStateFromJson(Map json) { - switch (json['runtimeType'] as String?) { + switch (json['type']) { case 'preparing': return Preparing.fromJson(json); case 'inProgress': @@ -25,8 +25,8 @@ UploadState _$UploadStateFromJson(Map json) { return Failed.fromJson(json); default: - throw CheckedFromJsonException(json, 'runtimeType', 'UploadState', - 'Invalid union type "${json['runtimeType']}"!'); + throw CheckedFromJsonException( + json, 'type', 'UploadState', 'Invalid union type "${json['type']}"!'); } } @@ -55,7 +55,7 @@ class _$UploadStateTearOff { ); } - UploadState fromJson(Map json) { + UploadState fromJson(Map json) { return UploadState.fromJson(json); } } @@ -153,11 +153,14 @@ class _$PreparingCopyWithImpl<$Res> extends _$UploadStateCopyWithImpl<$Res> /// @nodoc @JsonSerializable() class _$Preparing implements Preparing { - const _$Preparing(); + const _$Preparing({String? $type}) : $type = $type ?? 'preparing'; factory _$Preparing.fromJson(Map json) => _$$PreparingFromJson(json); + @JsonKey(name: 'type') + final String $type; + @override String toString() { return 'UploadState.preparing()'; @@ -165,7 +168,8 @@ class _$Preparing implements Preparing { @override bool operator ==(dynamic other) { - return identical(this, other) || (other is Preparing); + return identical(this, other) || + (other.runtimeType == runtimeType && other is Preparing); } @override @@ -247,7 +251,7 @@ class _$Preparing implements Preparing { @override Map toJson() { - return _$$PreparingToJson(this)..['runtimeType'] = 'preparing'; + return _$$PreparingToJson(this); } } @@ -295,7 +299,9 @@ class _$InProgressCopyWithImpl<$Res> extends _$UploadStateCopyWithImpl<$Res> /// @nodoc @JsonSerializable() class _$InProgress implements InProgress { - const _$InProgress({required this.uploaded, required this.total}); + const _$InProgress( + {required this.uploaded, required this.total, String? $type}) + : $type = $type ?? 'inProgress'; factory _$InProgress.fromJson(Map json) => _$$InProgressFromJson(json); @@ -305,6 +311,9 @@ class _$InProgress implements InProgress { @override final int total; + @JsonKey(name: 'type') + final String $type; + @override String toString() { return 'UploadState.inProgress(uploaded: $uploaded, total: $total)'; @@ -313,19 +322,15 @@ class _$InProgress implements InProgress { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is InProgress && + (other.runtimeType == runtimeType && + other is InProgress && (identical(other.uploaded, uploaded) || - const DeepCollectionEquality() - .equals(other.uploaded, uploaded)) && - (identical(other.total, total) || - const DeepCollectionEquality().equals(other.total, total))); + other.uploaded == uploaded) && + (identical(other.total, total) || other.total == total)); } @override - int get hashCode => - runtimeType.hashCode ^ - const DeepCollectionEquality().hash(uploaded) ^ - const DeepCollectionEquality().hash(total); + int get hashCode => Object.hash(runtimeType, uploaded, total); @JsonKey(ignore: true) @override @@ -408,7 +413,7 @@ class _$InProgress implements InProgress { @override Map toJson() { - return _$$InProgressToJson(this)..['runtimeType'] = 'inProgress'; + return _$$InProgressToJson(this); } } @@ -419,8 +424,8 @@ abstract class InProgress implements UploadState { 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; @@ -445,11 +450,14 @@ class _$SuccessCopyWithImpl<$Res> extends _$UploadStateCopyWithImpl<$Res> /// @nodoc @JsonSerializable() class _$Success implements Success { - const _$Success(); + const _$Success({String? $type}) : $type = $type ?? 'success'; factory _$Success.fromJson(Map json) => _$$SuccessFromJson(json); + @JsonKey(name: 'type') + final String $type; + @override String toString() { return 'UploadState.success()'; @@ -457,7 +465,8 @@ class _$Success implements Success { @override bool operator ==(dynamic other) { - return identical(this, other) || (other is Success); + return identical(this, other) || + (other.runtimeType == runtimeType && other is Success); } @override @@ -539,7 +548,7 @@ class _$Success implements Success { @override Map toJson() { - return _$$SuccessToJson(this)..['runtimeType'] = 'success'; + return _$$SuccessToJson(this); } } @@ -581,7 +590,8 @@ class _$FailedCopyWithImpl<$Res> extends _$UploadStateCopyWithImpl<$Res> /// @nodoc @JsonSerializable() class _$Failed implements Failed { - const _$Failed({required this.error}); + const _$Failed({required this.error, String? $type}) + : $type = $type ?? 'failed'; factory _$Failed.fromJson(Map json) => _$$FailedFromJson(json); @@ -589,6 +599,9 @@ class _$Failed implements Failed { @override final String error; + @JsonKey(name: 'type') + final String $type; + @override String toString() { return 'UploadState.failed(error: $error)'; @@ -597,14 +610,13 @@ class _$Failed implements Failed { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is Failed && - (identical(other.error, error) || - const DeepCollectionEquality().equals(other.error, error))); + (other.runtimeType == runtimeType && + other is Failed && + (identical(other.error, error) || other.error == error)); } @override - int get hashCode => - runtimeType.hashCode ^ const DeepCollectionEquality().hash(error); + int get hashCode => Object.hash(runtimeType, error); @JsonKey(ignore: true) @override @@ -687,7 +699,7 @@ class _$Failed implements Failed { @override Map toJson() { - return _$$FailedToJson(this)..['runtimeType'] = 'failed'; + return _$$FailedToJson(this); } } @@ -696,7 +708,7 @@ abstract class Failed implements UploadState { 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/lib/src/core/models/attachment_file.g.dart b/packages/stream_chat/lib/src/core/models/attachment_file.g.dart index f36c269d..8324482d 100644 --- a/packages/stream_chat/lib/src/core/models/attachment_file.g.dart +++ b/packages/stream_chat/lib/src/core/models/attachment_file.g.dart @@ -22,31 +22,42 @@ Map _$AttachmentFileToJson(AttachmentFile instance) => 'size': instance.size, }; -_$Preparing _$$PreparingFromJson(Map json) => _$Preparing(); +_$Preparing _$$PreparingFromJson(Map json) => _$Preparing( + $type: json['type'] as String?, + ); Map _$$PreparingToJson(_$Preparing instance) => - {}; + { + 'type': instance.$type, + }; _$InProgress _$$InProgressFromJson(Map json) => _$InProgress( uploaded: json['uploaded'] as int, total: json['total'] as int, + $type: json['type'] as String?, ); Map _$$InProgressToJson(_$InProgress instance) => { 'uploaded': instance.uploaded, 'total': instance.total, + 'type': instance.$type, }; -_$Success _$$SuccessFromJson(Map json) => _$Success(); +_$Success _$$SuccessFromJson(Map json) => _$Success( + $type: json['type'] as String?, + ); -Map _$$SuccessToJson(_$Success instance) => - {}; +Map _$$SuccessToJson(_$Success instance) => { + 'type': instance.$type, + }; _$Failed _$$FailedFromJson(Map json) => _$Failed( error: json['error'] as String, + $type: json['type'] as String?, ); Map _$$FailedToJson(_$Failed instance) => { 'error': instance.error, + 'type': instance.$type, }; diff --git a/packages/stream_chat/lib/src/core/models/event.dart b/packages/stream_chat/lib/src/core/models/event.dart index aed35696..094207e8 100644 --- a/packages/stream_chat/lib/src/core/models/event.dart +++ b/packages/stream_chat/lib/src/core/models/event.dart @@ -181,7 +181,7 @@ class EventChannel extends ChannelModel { required DateTime createdAt, required DateTime updatedAt, DateTime? deletedAt, - required int memberCount, + int memberCount = 0, Map? extraData, int cooldown = 0, String? team, diff --git a/packages/stream_chat/lib/src/core/models/event.g.dart b/packages/stream_chat/lib/src/core/models/event.g.dart index 29a4482b..87c92d5d 100644 --- a/packages/stream_chat/lib/src/core/models/event.g.dart +++ b/packages/stream_chat/lib/src/core/models/event.g.dart @@ -82,7 +82,7 @@ EventChannel _$EventChannelFromJson(Map json) => EventChannel( deletedAt: json['deleted_at'] == null ? null : DateTime.parse(json['deleted_at'] as String), - memberCount: json['member_count'] as int, + memberCount: json['member_count'] as int? ?? 0, extraData: json['extra_data'] as Map?, cooldown: json['cooldown'] as int? ?? 0, team: json['team'] as String?, diff --git a/packages/stream_chat/lib/src/ws/websocket.dart b/packages/stream_chat/lib/src/ws/websocket.dart index a95eae70..82c7d7c1 100644 --- a/packages/stream_chat/lib/src/ws/websocket.dart +++ b/packages/stream_chat/lib/src/ws/websocket.dart @@ -310,7 +310,10 @@ class WebSocket with TimerHelper { Event? event; try { event = Event.fromJson(jsonData); - } catch (_) {} + } catch (e, stk) { + _logger?.warning('Error parsing an event: $e'); + _logger?.warning('Stack trace: $stk'); + } if (event == null) return; diff --git a/packages/stream_chat/pubspec.yaml b/packages/stream_chat/pubspec.yaml index 96096fd3..ff8d5356 100644 --- a/packages/stream_chat/pubspec.yaml +++ b/packages/stream_chat/pubspec.yaml @@ -16,7 +16,7 @@ dependencies: freezed_annotation: ^0.15.0 http_parser: ^4.0.0 jose: ^0.3.2 - json_annotation: ^4.0.1 + json_annotation: ^4.3.0 logging: ^1.0.1 meta: ^1.3.0 mime: ^1.0.0 From eb186a92fb1911a985725dd8dd764663930e6de4 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 26 Nov 2021 10:37:51 +0100 Subject: [PATCH 2/6] chore(llc): update changelog --- packages/stream_chat/CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index 3b6578f5..4788b232 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -7,8 +7,9 @@ 🐞 Fixed - `closeConnection()` now uses `normalClosure` status when closing websocket. -- Fixed local unread count indicator increasing for thread replies -- Fixed user presence indicator not updating correctly +- Fixed local unread count indicator increasing for thread replies. +- Fixed user presence indicator not updating correctly. +- `ChannelEvent.membersCount` defaults to 0 avoiding parsing errors due to missing `members_count` field. ## 3.2.0 From e9d148ef490fdf048fa23fad9a452f5134d8db99 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 26 Nov 2021 10:47:48 +0100 Subject: [PATCH 3/6] fix models --- .../src/core/models/attachment_file.freezed.dart | 14 +++++++------- .../lib/src/core/models/attachment_file.g.dart | 16 ++++++++-------- packages/stream_chat/pubspec.yaml | 4 ++-- 3 files changed, 17 insertions(+), 17 deletions(-) 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 6b7b00cf..c524a742 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 @@ -14,7 +14,7 @@ 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 informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); UploadState _$UploadStateFromJson(Map json) { - switch (json['type']) { + switch (json['runtimeType']) { case 'preparing': return Preparing.fromJson(json); case 'inProgress': @@ -25,8 +25,8 @@ UploadState _$UploadStateFromJson(Map json) { return Failed.fromJson(json); default: - throw CheckedFromJsonException( - json, 'type', 'UploadState', 'Invalid union type "${json['type']}"!'); + throw CheckedFromJsonException(json, 'runtimeType', 'UploadState', + 'Invalid union type "${json['runtimeType']}"!'); } } @@ -158,7 +158,7 @@ class _$Preparing implements Preparing { factory _$Preparing.fromJson(Map json) => _$$PreparingFromJson(json); - @JsonKey(name: 'type') + @JsonKey(name: 'runtimeType') final String $type; @override @@ -311,7 +311,7 @@ class _$InProgress implements InProgress { @override final int total; - @JsonKey(name: 'type') + @JsonKey(name: 'runtimeType') final String $type; @override @@ -455,7 +455,7 @@ class _$Success implements Success { factory _$Success.fromJson(Map json) => _$$SuccessFromJson(json); - @JsonKey(name: 'type') + @JsonKey(name: 'runtimeType') final String $type; @override @@ -599,7 +599,7 @@ class _$Failed implements Failed { @override final String error; - @JsonKey(name: 'type') + @JsonKey(name: 'runtimeType') final String $type; @override diff --git a/packages/stream_chat/lib/src/core/models/attachment_file.g.dart b/packages/stream_chat/lib/src/core/models/attachment_file.g.dart index 8324482d..6b657c2a 100644 --- a/packages/stream_chat/lib/src/core/models/attachment_file.g.dart +++ b/packages/stream_chat/lib/src/core/models/attachment_file.g.dart @@ -23,41 +23,41 @@ Map _$AttachmentFileToJson(AttachmentFile instance) => }; _$Preparing _$$PreparingFromJson(Map json) => _$Preparing( - $type: json['type'] as String?, + $type: json['runtimeType'] as String?, ); Map _$$PreparingToJson(_$Preparing instance) => { - 'type': instance.$type, + 'runtimeType': instance.$type, }; _$InProgress _$$InProgressFromJson(Map json) => _$InProgress( uploaded: json['uploaded'] as int, total: json['total'] as int, - $type: json['type'] as String?, + $type: json['runtimeType'] as String?, ); Map _$$InProgressToJson(_$InProgress instance) => { 'uploaded': instance.uploaded, 'total': instance.total, - 'type': instance.$type, + 'runtimeType': instance.$type, }; _$Success _$$SuccessFromJson(Map json) => _$Success( - $type: json['type'] as String?, + $type: json['runtimeType'] as String?, ); Map _$$SuccessToJson(_$Success instance) => { - 'type': instance.$type, + 'runtimeType': instance.$type, }; _$Failed _$$FailedFromJson(Map json) => _$Failed( error: json['error'] as String, - $type: json['type'] as String?, + $type: json['runtimeType'] as String?, ); Map _$$FailedToJson(_$Failed instance) => { 'error': instance.error, - 'type': instance.$type, + 'runtimeType': instance.$type, }; diff --git a/packages/stream_chat/pubspec.yaml b/packages/stream_chat/pubspec.yaml index ff8d5356..a723e77b 100644 --- a/packages/stream_chat/pubspec.yaml +++ b/packages/stream_chat/pubspec.yaml @@ -13,7 +13,7 @@ dependencies: collection: ^1.15.0 dio: ^4.0.0 equatable: ^2.0.0 - freezed_annotation: ^0.15.0 + freezed_annotation: ^1.0.0 http_parser: ^4.0.0 jose: ^0.3.2 json_annotation: ^4.3.0 @@ -28,7 +28,7 @@ dependencies: dev_dependencies: build_runner: ^2.0.1 dart_code_metrics: ^4.4.0 - freezed: ^0.15.0+1 + freezed: ^1.0.0 json_serializable: ^6.0.1 mocktail: ^0.2.0 test: ^1.17.12 \ No newline at end of file From 0dd9af0906b142eed71c0be92d06d6bfd52aa37b Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 26 Nov 2021 11:46:02 +0100 Subject: [PATCH 4/6] fix(llc): dispose channel on deletion --- packages/stream_chat/lib/src/client/channel.dart | 8 ++++++++ .../lib/src/channel_list_core.dart | 5 ++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index c219a120..95eddab7 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -1462,6 +1462,8 @@ class ChannelClientState { _listenChannelUpdated(); + _listenChannelDeleted(); + _listenMemberAdded(); _listenMemberRemoved(); @@ -1563,6 +1565,12 @@ class ChannelClientState { })); } + void _listenChannelDeleted() { + _subscriptions.add(_channel.on(EventType.channelDeleted).listen((Event e) { + _channel.dispose(); + })); + } + void _listenChannelTruncated() { _subscriptions.add(_channel .on(EventType.channelTruncated, EventType.notificationChannelTruncated) diff --git a/packages/stream_chat_flutter_core/lib/src/channel_list_core.dart b/packages/stream_chat_flutter_core/lib/src/channel_list_core.dart index 8ac28e76..51467ca3 100644 --- a/packages/stream_chat_flutter_core/lib/src/channel_list_core.dart +++ b/packages/stream_chat_flutter_core/lib/src/channel_list_core.dart @@ -157,7 +157,10 @@ class ChannelListCoreState extends State { presence: widget.presence, memberLimit: widget.memberLimit, messageLimit: widget.messageLimit, - paginationParams: PaginationParams(limit: widget.limit), + paginationParams: PaginationParams( + limit: widget.limit, + offset: 0, + ), ); /// Fetches more channels with updated pagination and updates the widget From 577b7317683bd084d7c196c51235c8f270c7f7b0 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 26 Nov 2021 12:33:31 +0100 Subject: [PATCH 5/6] remove listener from channel --- packages/stream_chat/lib/src/client/channel.dart | 8 -------- packages/stream_chat/lib/src/client/client.dart | 2 ++ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index 95eddab7..c219a120 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -1462,8 +1462,6 @@ class ChannelClientState { _listenChannelUpdated(); - _listenChannelDeleted(); - _listenMemberAdded(); _listenMemberRemoved(); @@ -1565,12 +1563,6 @@ class ChannelClientState { })); } - void _listenChannelDeleted() { - _subscriptions.add(_channel.on(EventType.channelDeleted).listen((Event e) { - _channel.dispose(); - })); - } - void _listenChannelTruncated() { _subscriptions.add(_channel .on(EventType.channelTruncated, EventType.notificationChannelTruncated) diff --git a/packages/stream_chat/lib/src/client/client.dart b/packages/stream_chat/lib/src/client/client.dart index c9bdebc1..334b60c2 100644 --- a/packages/stream_chat/lib/src/client/client.dart +++ b/packages/stream_chat/lib/src/client/client.dart @@ -1432,6 +1432,8 @@ class ClientState { .listen((Event event) async { final eventChannel = event.channel!; await _client.chatPersistenceClient?.deleteChannels([eventChannel.cid]); + final channel = channels[eventChannel.cid]; + channel?.dispose(); channels = channels..remove(eventChannel.cid); })); } From f951be82f73a5fb821f2239c5b56f07da192af67 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 26 Nov 2021 12:56:21 +0100 Subject: [PATCH 6/6] Apply suggestions from code review Co-authored-by: Deven Joshi --- packages/stream_chat/lib/src/client/client.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/stream_chat/lib/src/client/client.dart b/packages/stream_chat/lib/src/client/client.dart index 334b60c2..b0de2e57 100644 --- a/packages/stream_chat/lib/src/client/client.dart +++ b/packages/stream_chat/lib/src/client/client.dart @@ -1432,8 +1432,7 @@ class ClientState { .listen((Event event) async { final eventChannel = event.channel!; await _client.chatPersistenceClient?.deleteChannels([eventChannel.cid]); - final channel = channels[eventChannel.cid]; - channel?.dispose(); + channels[eventChannel.cid]?.dispose(); channels = channels..remove(eventChannel.cid); })); }