From 54de13c4280afef9a79b8f2f6f158032077cfe4c Mon Sep 17 00:00:00 2001 From: Vladislav Shturma Date: Fri, 25 Jul 2025 13:59:02 +0400 Subject: [PATCH 1/6] fix(llc): fixed skipPush and skipEnrichUrl not preserving during message send or update retry --- packages/stream_chat/CHANGELOG.md | 6 + .../stream_chat/lib/src/client/channel.dart | 24 +- .../lib/src/client/retry_queue.dart | 4 +- .../lib/src/core/models/message_state.dart | 43 +- .../core/models/message_state.freezed.dart | 161 ++- .../lib/src/core/models/message_state.g.dart | 6 + .../test/src/client/channel_test.dart | 1171 ++++++++++++++++- .../test/src/client/retry_queue_test.dart | 10 +- .../src/core/models/message_state_test.dart | 7 +- .../message_actions_modal_test.dart | 5 +- 10 files changed, 1322 insertions(+), 115 deletions(-) diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index 6e98905bf3..3ce0b4d8a2 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -1,3 +1,9 @@ +## Upcoming + +🐞 Fixed + +- Fixed `skipPush` and `skipEnrichUrl` not preserving during message send or update retry + ## 9.15.0 ✅ Added diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index b3e33eb74e..ebd9079160 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -741,7 +741,10 @@ class Channel { state!._retryQueue.add([ message.copyWith( // Update the message state to failed. - state: MessageState.sendingFailed, + state: MessageState.sendingFailed( + skipPush: skipPush, + skipEnrichUrl: skipEnrichUrl, + ), ), ]); } @@ -824,14 +827,14 @@ class Channel { state!._retryQueue.add([ message.copyWith( // Update the message state to failed. - state: MessageState.updatingFailed, + state: MessageState.updatingFailed(skipEnrichUrl: skipEnrichUrl), ), ]); } else { // Reset the message to original state if the update fails and is not // retriable. state?.updateMessage(originalMessage.copyWith( - state: MessageState.updatingFailed, + state: MessageState.updatingFailed(skipEnrichUrl: skipEnrichUrl), )); } } @@ -894,14 +897,14 @@ class Channel { state!._retryQueue.add([ message.copyWith( // Update the message state to failed. - state: MessageState.updatingFailed, + state: MessageState.updatingFailed(skipEnrichUrl: skipEnrichUrl), ), ]); } else { // Reset the message to original state if the update fails and is not // retriable. state?.updateMessage(originalMessage.copyWith( - state: MessageState.updatingFailed, + state: MessageState.updatingFailed(skipEnrichUrl: skipEnrichUrl), )); } } @@ -998,8 +1001,15 @@ class Channel { return message.state.maybeWhen( failed: (state, _) => state.when( - sendingFailed: () => sendMessage(message), - updatingFailed: () => updateMessage(message), + sendingFailed: (skipPush, skipEnrichUrl) => sendMessage( + message, + skipPush: skipPush, + skipEnrichUrl: skipEnrichUrl, + ), + updatingFailed: (skipEnrichUrl) => updateMessage( + message, + skipEnrichUrl: skipEnrichUrl, + ), deletingFailed: (hard) => deleteMessage(message, hard: hard), ), orElse: () => throw StateError('Message state is not failed'), diff --git a/packages/stream_chat/lib/src/client/retry_queue.dart b/packages/stream_chat/lib/src/client/retry_queue.dart index 8675ee68b7..cc502c119d 100644 --- a/packages/stream_chat/lib/src/client/retry_queue.dart +++ b/packages/stream_chat/lib/src/client/retry_queue.dart @@ -121,8 +121,8 @@ class RetryQueue { static DateTime? _getMessageDate(Message message) { return message.state.maybeWhen( failed: (state, _) => state.when( - sendingFailed: () => message.createdAt, - updatingFailed: () => message.updatedAt, + sendingFailed: (_, __) => message.createdAt, + updatingFailed: (_) => message.updatedAt, deletingFailed: (_) => message.deletedAt, ), orElse: () => null, diff --git a/packages/stream_chat/lib/src/core/models/message_state.dart b/packages/stream_chat/lib/src/core/models/message_state.dart index 0cbefec15b..a28208f758 100644 --- a/packages/stream_chat/lib/src/core/models/message_state.dart +++ b/packages/stream_chat/lib/src/core/models/message_state.dart @@ -182,6 +182,30 @@ sealed class MessageState with _$MessageState { ); } + /// Sending failed state when the message fails to be sent. + factory MessageState.sendingFailed({ + required bool skipPush, + required bool skipEnrichUrl, + }) { + return MessageState.failed( + state: FailedState.sendingFailed( + skipPush: skipPush, + skipEnrichUrl: skipEnrichUrl, + ), + ); + } + + /// Updating failed state when the message fails to be updated. + factory MessageState.updatingFailed({ + required bool skipEnrichUrl, + }) { + return MessageState.failed( + state: FailedState.updatingFailed( + skipEnrichUrl: skipEnrichUrl, + ), + ); + } + /// Sending state when the message is being sent. static const sending = MessageState.outgoing( state: OutgoingState.sending(), @@ -222,16 +246,6 @@ sealed class MessageState with _$MessageState { state: CompletedState.deleted(hard: true), ); - /// Sending failed state when the message fails to be sent. - static const sendingFailed = MessageState.failed( - state: FailedState.sendingFailed(), - ); - - /// Updating failed state when the message fails to be updated. - static const updatingFailed = MessageState.failed( - state: FailedState.updatingFailed(), - ); - /// Deleting failed state when the message fails to be soft deleted. static const softDeletingFailed = MessageState.failed( state: FailedState.deletingFailed(), @@ -285,10 +299,15 @@ sealed class CompletedState with _$CompletedState { @freezed sealed class FailedState with _$FailedState { /// Sending failed state when the message fails to be sent. - const factory FailedState.sendingFailed() = SendingFailed; + const factory FailedState.sendingFailed({ + @Default(false) bool skipPush, + @Default(false) bool skipEnrichUrl, + }) = SendingFailed; /// Updating failed state when the message fails to be updated. - const factory FailedState.updatingFailed() = UpdatingFailed; + const factory FailedState.updatingFailed({ + @Default(false) bool skipEnrichUrl, + }) = UpdatingFailed; /// Deleting failed state when the message fails to be deleted. const factory FailedState.deletingFailed({ diff --git a/packages/stream_chat/lib/src/core/models/message_state.freezed.dart b/packages/stream_chat/lib/src/core/models/message_state.freezed.dart index 584bc54b4c..02f9d4b089 100644 --- a/packages/stream_chat/lib/src/core/models/message_state.freezed.dart +++ b/packages/stream_chat/lib/src/core/models/message_state.freezed.dart @@ -1834,22 +1834,22 @@ FailedState _$FailedStateFromJson(Map json) { mixin _$FailedState { @optionalTypeArgs TResult when({ - required TResult Function() sendingFailed, - required TResult Function() updatingFailed, + required TResult Function(bool skipPush, bool skipEnrichUrl) sendingFailed, + required TResult Function(bool skipEnrichUrl) updatingFailed, required TResult Function(bool hard) deletingFailed, }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult? whenOrNull({ - TResult? Function()? sendingFailed, - TResult? Function()? updatingFailed, + TResult? Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, + TResult? Function(bool skipEnrichUrl)? updatingFailed, TResult? Function(bool hard)? deletingFailed, }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult maybeWhen({ - TResult Function()? sendingFailed, - TResult Function()? updatingFailed, + TResult Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, + TResult Function(bool skipEnrichUrl)? updatingFailed, TResult Function(bool hard)? deletingFailed, required TResult orElse(), }) => @@ -1907,6 +1907,8 @@ abstract class _$$SendingFailedImplCopyWith<$Res> { factory _$$SendingFailedImplCopyWith( _$SendingFailedImpl value, $Res Function(_$SendingFailedImpl) then) = __$$SendingFailedImplCopyWithImpl<$Res>; + @useResult + $Res call({bool skipPush, bool skipEnrichUrl}); } /// @nodoc @@ -1917,6 +1919,24 @@ class __$$SendingFailedImplCopyWithImpl<$Res> _$SendingFailedImpl _value, $Res Function(_$SendingFailedImpl) _then) : super(_value, _then); + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? skipPush = null, + Object? skipEnrichUrl = null, + }) { + return _then(_$SendingFailedImpl( + skipPush: null == skipPush + ? _value.skipPush + : skipPush // ignore: cast_nullable_to_non_nullable + as bool, + skipEnrichUrl: null == skipEnrichUrl + ? _value.skipEnrichUrl + : skipEnrichUrl // ignore: cast_nullable_to_non_nullable + as bool, + )); + } + /// Create a copy of FailedState /// with the given fields replaced by the non-null parameter values. } @@ -1924,60 +1944,79 @@ class __$$SendingFailedImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() class _$SendingFailedImpl implements SendingFailed { - const _$SendingFailedImpl({final String? $type}) + const _$SendingFailedImpl( + {this.skipPush = false, this.skipEnrichUrl = false, final String? $type}) : $type = $type ?? 'sendingFailed'; factory _$SendingFailedImpl.fromJson(Map json) => _$$SendingFailedImplFromJson(json); + @override + @JsonKey() + final bool skipPush; + @override + @JsonKey() + final bool skipEnrichUrl; + @JsonKey(name: 'runtimeType') final String $type; @override String toString() { - return 'FailedState.sendingFailed()'; + return 'FailedState.sendingFailed(skipPush: $skipPush, skipEnrichUrl: $skipEnrichUrl)'; } @override bool operator ==(Object other) { return identical(this, other) || - (other.runtimeType == runtimeType && other is _$SendingFailedImpl); + (other.runtimeType == runtimeType && + other is _$SendingFailedImpl && + (identical(other.skipPush, skipPush) || + other.skipPush == skipPush) && + (identical(other.skipEnrichUrl, skipEnrichUrl) || + other.skipEnrichUrl == skipEnrichUrl)); } @JsonKey(includeFromJson: false, includeToJson: false) @override - int get hashCode => runtimeType.hashCode; + int get hashCode => Object.hash(runtimeType, skipPush, skipEnrichUrl); + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$SendingFailedImplCopyWith<_$SendingFailedImpl> get copyWith => + __$$SendingFailedImplCopyWithImpl<_$SendingFailedImpl>(this, _$identity); @override @optionalTypeArgs TResult when({ - required TResult Function() sendingFailed, - required TResult Function() updatingFailed, + required TResult Function(bool skipPush, bool skipEnrichUrl) sendingFailed, + required TResult Function(bool skipEnrichUrl) updatingFailed, required TResult Function(bool hard) deletingFailed, }) { - return sendingFailed(); + return sendingFailed(skipPush, skipEnrichUrl); } @override @optionalTypeArgs TResult? whenOrNull({ - TResult? Function()? sendingFailed, - TResult? Function()? updatingFailed, + TResult? Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, + TResult? Function(bool skipEnrichUrl)? updatingFailed, TResult? Function(bool hard)? deletingFailed, }) { - return sendingFailed?.call(); + return sendingFailed?.call(skipPush, skipEnrichUrl); } @override @optionalTypeArgs TResult maybeWhen({ - TResult Function()? sendingFailed, - TResult Function()? updatingFailed, + TResult Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, + TResult Function(bool skipEnrichUrl)? updatingFailed, TResult Function(bool hard)? deletingFailed, required TResult orElse(), }) { if (sendingFailed != null) { - return sendingFailed(); + return sendingFailed(skipPush, skipEnrichUrl); } return orElse(); } @@ -2025,10 +2064,17 @@ class _$SendingFailedImpl implements SendingFailed { } abstract class SendingFailed implements FailedState { - const factory SendingFailed() = _$SendingFailedImpl; + const factory SendingFailed({final bool skipPush, final bool skipEnrichUrl}) = + _$SendingFailedImpl; factory SendingFailed.fromJson(Map json) = _$SendingFailedImpl.fromJson; + + bool get skipPush; + bool get skipEnrichUrl; + @JsonKey(includeFromJson: false, includeToJson: false) + _$$SendingFailedImplCopyWith<_$SendingFailedImpl> get copyWith => + throw _privateConstructorUsedError; } /// @nodoc @@ -2036,6 +2082,8 @@ abstract class _$$UpdatingFailedImplCopyWith<$Res> { factory _$$UpdatingFailedImplCopyWith(_$UpdatingFailedImpl value, $Res Function(_$UpdatingFailedImpl) then) = __$$UpdatingFailedImplCopyWithImpl<$Res>; + @useResult + $Res call({bool skipEnrichUrl}); } /// @nodoc @@ -2046,6 +2094,19 @@ class __$$UpdatingFailedImplCopyWithImpl<$Res> _$UpdatingFailedImpl _value, $Res Function(_$UpdatingFailedImpl) _then) : super(_value, _then); + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? skipEnrichUrl = null, + }) { + return _then(_$UpdatingFailedImpl( + skipEnrichUrl: null == skipEnrichUrl + ? _value.skipEnrichUrl + : skipEnrichUrl // ignore: cast_nullable_to_non_nullable + as bool, + )); + } + /// Create a copy of FailedState /// with the given fields replaced by the non-null parameter values. } @@ -2053,60 +2114,74 @@ class __$$UpdatingFailedImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() class _$UpdatingFailedImpl implements UpdatingFailed { - const _$UpdatingFailedImpl({final String? $type}) + const _$UpdatingFailedImpl({this.skipEnrichUrl = false, final String? $type}) : $type = $type ?? 'updatingFailed'; factory _$UpdatingFailedImpl.fromJson(Map json) => _$$UpdatingFailedImplFromJson(json); + @override + @JsonKey() + final bool skipEnrichUrl; + @JsonKey(name: 'runtimeType') final String $type; @override String toString() { - return 'FailedState.updatingFailed()'; + return 'FailedState.updatingFailed(skipEnrichUrl: $skipEnrichUrl)'; } @override bool operator ==(Object other) { return identical(this, other) || - (other.runtimeType == runtimeType && other is _$UpdatingFailedImpl); + (other.runtimeType == runtimeType && + other is _$UpdatingFailedImpl && + (identical(other.skipEnrichUrl, skipEnrichUrl) || + other.skipEnrichUrl == skipEnrichUrl)); } @JsonKey(includeFromJson: false, includeToJson: false) @override - int get hashCode => runtimeType.hashCode; + int get hashCode => Object.hash(runtimeType, skipEnrichUrl); + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$UpdatingFailedImplCopyWith<_$UpdatingFailedImpl> get copyWith => + __$$UpdatingFailedImplCopyWithImpl<_$UpdatingFailedImpl>( + this, _$identity); @override @optionalTypeArgs TResult when({ - required TResult Function() sendingFailed, - required TResult Function() updatingFailed, + required TResult Function(bool skipPush, bool skipEnrichUrl) sendingFailed, + required TResult Function(bool skipEnrichUrl) updatingFailed, required TResult Function(bool hard) deletingFailed, }) { - return updatingFailed(); + return updatingFailed(skipEnrichUrl); } @override @optionalTypeArgs TResult? whenOrNull({ - TResult? Function()? sendingFailed, - TResult? Function()? updatingFailed, + TResult? Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, + TResult? Function(bool skipEnrichUrl)? updatingFailed, TResult? Function(bool hard)? deletingFailed, }) { - return updatingFailed?.call(); + return updatingFailed?.call(skipEnrichUrl); } @override @optionalTypeArgs TResult maybeWhen({ - TResult Function()? sendingFailed, - TResult Function()? updatingFailed, + TResult Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, + TResult Function(bool skipEnrichUrl)? updatingFailed, TResult Function(bool hard)? deletingFailed, required TResult orElse(), }) { if (updatingFailed != null) { - return updatingFailed(); + return updatingFailed(skipEnrichUrl); } return orElse(); } @@ -2154,10 +2229,16 @@ class _$UpdatingFailedImpl implements UpdatingFailed { } abstract class UpdatingFailed implements FailedState { - const factory UpdatingFailed() = _$UpdatingFailedImpl; + const factory UpdatingFailed({final bool skipEnrichUrl}) = + _$UpdatingFailedImpl; factory UpdatingFailed.fromJson(Map json) = _$UpdatingFailedImpl.fromJson; + + bool get skipEnrichUrl; + @JsonKey(includeFromJson: false, includeToJson: false) + _$$UpdatingFailedImplCopyWith<_$UpdatingFailedImpl> get copyWith => + throw _privateConstructorUsedError; } /// @nodoc @@ -2238,8 +2319,8 @@ class _$DeletingFailedImpl implements DeletingFailed { @override @optionalTypeArgs TResult when({ - required TResult Function() sendingFailed, - required TResult Function() updatingFailed, + required TResult Function(bool skipPush, bool skipEnrichUrl) sendingFailed, + required TResult Function(bool skipEnrichUrl) updatingFailed, required TResult Function(bool hard) deletingFailed, }) { return deletingFailed(hard); @@ -2248,8 +2329,8 @@ class _$DeletingFailedImpl implements DeletingFailed { @override @optionalTypeArgs TResult? whenOrNull({ - TResult? Function()? sendingFailed, - TResult? Function()? updatingFailed, + TResult? Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, + TResult? Function(bool skipEnrichUrl)? updatingFailed, TResult? Function(bool hard)? deletingFailed, }) { return deletingFailed?.call(hard); @@ -2258,8 +2339,8 @@ class _$DeletingFailedImpl implements DeletingFailed { @override @optionalTypeArgs TResult maybeWhen({ - TResult Function()? sendingFailed, - TResult Function()? updatingFailed, + TResult Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, + TResult Function(bool skipEnrichUrl)? updatingFailed, TResult Function(bool hard)? deletingFailed, required TResult orElse(), }) { diff --git a/packages/stream_chat/lib/src/core/models/message_state.g.dart b/packages/stream_chat/lib/src/core/models/message_state.g.dart index 7cf2531c89..2e7d43e908 100644 --- a/packages/stream_chat/lib/src/core/models/message_state.g.dart +++ b/packages/stream_chat/lib/src/core/models/message_state.g.dart @@ -124,22 +124,28 @@ Map _$$DeletedImplToJson(_$DeletedImpl instance) => _$SendingFailedImpl _$$SendingFailedImplFromJson(Map json) => _$SendingFailedImpl( + skipPush: json['skip_push'] as bool? ?? false, + skipEnrichUrl: json['skip_enrich_url'] as bool? ?? false, $type: json['runtimeType'] as String?, ); Map _$$SendingFailedImplToJson(_$SendingFailedImpl instance) => { + 'skip_push': instance.skipPush, + 'skip_enrich_url': instance.skipEnrichUrl, 'runtimeType': instance.$type, }; _$UpdatingFailedImpl _$$UpdatingFailedImplFromJson(Map json) => _$UpdatingFailedImpl( + skipEnrichUrl: json['skip_enrich_url'] as bool? ?? false, $type: json['runtimeType'] as String?, ); Map _$$UpdatingFailedImplToJson( _$UpdatingFailedImpl instance) => { + 'skip_enrich_url': instance.skipEnrichUrl, 'runtimeType': instance.$type, }; diff --git a/packages/stream_chat/test/src/client/channel_test.dart b/packages/stream_chat/test/src/client/channel_test.dart index eabb98f7c2..0b852fc7b5 100644 --- a/packages/stream_chat/test/src/client/channel_test.dart +++ b/packages/stream_chat/test/src/client/channel_test.dart @@ -215,6 +215,7 @@ void main() { tearDown(() { channel.dispose(); + clearInteractions(client); }); test('should throw if trying to set `extraData`', () { @@ -288,6 +289,268 @@ void main() { )).called(1); }); + test( + 'should handle StreamChatNetworkError by adding message to retry queue with skipPush: true, skipEnrichUrl: false', + () async { + final message = Message( + id: 'test-message-id', + user: client.state.currentUser, + ); + + when(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + skipPush: true, + )).thenThrow(StreamChatNetworkError(ChatErrorCode.notAllowed)); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.sending), + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.sendingFailed( + skipPush: true, + skipEnrichUrl: false, + ), + ), + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.sendMessage( + message, + skipPush: true, + ); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.notAllowed.code)); + } + }); + + test( + 'should handle StreamChatNetworkError by adding message to retry queue with skipPush: true, skipEnrichUrl: true', + () async { + final message = Message( + id: 'test-message-id-2', + user: client.state.currentUser, + ); + + when(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + skipPush: true, + skipEnrichUrl: true, + )).thenThrow(StreamChatNetworkError(ChatErrorCode.notAllowed)); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.sending), + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.sendingFailed( + skipPush: true, + skipEnrichUrl: true, + ), + ), + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.sendMessage( + message, + skipPush: true, + skipEnrichUrl: true, + ); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.notAllowed.code)); + } + }); + + test( + 'should handle StreamChatNetworkError by adding message to retry queue with skipPush: false, skipEnrichUrl: true', + () async { + final message = Message( + id: 'test-message-id-3', + user: client.state.currentUser, + ); + + when(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + skipEnrichUrl: true, + )).thenThrow(StreamChatNetworkError(ChatErrorCode.notAllowed)); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.sending), + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.sendingFailed( + skipPush: false, + skipEnrichUrl: true, + ), + ), + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.sendMessage( + message, + skipEnrichUrl: true, + ); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.notAllowed.code)); + } + }); + + test( + 'should handle StreamChatNetworkError by adding message to retry queue with skipPush: false, skipEnrichUrl: false', + () async { + final message = Message( + id: 'test-message-id-4', + user: client.state.currentUser, + ); + + when(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + )).thenThrow(StreamChatNetworkError(ChatErrorCode.notAllowed)); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.sending), + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.sendingFailed( + skipPush: false, + skipEnrichUrl: false, + ), + ), + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.sendMessage( + message, + ); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.notAllowed.code)); + } + }); + + test('should not update message state when non-retriable error occurs', + () async { + final message = Message( + id: 'test-message-id', + user: client.state.currentUser, + ); + + when(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + )).thenThrow(StreamChatNetworkError.raw( + code: ChatErrorCode.inputError.code, + message: 'Input error', + data: ErrorResponse() + ..code = ChatErrorCode.inputError.code + ..message = 'Input error' + ..statusCode = 400, + )); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.sending), + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.sendMessage(message); + } catch (e) { + expect(e, isA()); + } + + final updatedMessage = + channel.state!.messages.firstWhere((m) => m.id == message.id); + expect(updatedMessage.state, isA()); + expect( + updatedMessage.state.maybeWhen( + failed: (state, _) => state.when( + sendingFailed: (_, __) => false, + updatingFailed: (_) => false, + deletingFailed: (_) => false, + ), + orElse: () => true, + ), + isTrue); + }); + test('with attachments should work just fine', () async { final attachments = List.generate( 3, @@ -887,64 +1150,592 @@ void main() { any(that: isSameMessageAs(message)), )).called(1); }); - }); - test('`.partialUpdateMessage`', () async { - final message = Message( - id: 'test-message-id', - state: MessageState.sent, - ); + test( + 'should not update message state when error is not StreamChatNetworkError', + () async { + final message = Message( + id: 'test-message-id-error-1', + state: MessageState.sent, + ); - const set = {'text': 'Update Message text'}; - const unset = ['pinExpires']; + when(() => client.updateMessage( + any(that: isSameMessageAs(message)), + skipEnrichUrl: true, + )).thenThrow(ArgumentError('Invalid argument')); - final updateMessageResponse = UpdateMessageResponse() - ..message = message.copyWith(text: set['text'], pinExpires: null); + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.updating), + matchMessageState: true, + ), + ], + ]), + ); - when( - () => client.partialUpdateMessage(message.id, set: set, unset: unset), - ).thenAnswer((_) async => updateMessageResponse); + try { + await channel.updateMessage(message, skipEnrichUrl: true); + } catch (e) { + expect(e, isA()); + } + }); - expectLater( - // skipping first seed message list -> [] messages - channel.state?.messagesStream.skip(1), - emitsInOrder([ - [ - isSameMessageAs( - message.copyWith( - state: MessageState.updating, + test( + 'should add message to retry queue when retriable StreamChatNetworkError occurs with skipEnrichUrl: true', + () async { + final message = Message( + id: 'test-message-id-retry-1', + state: MessageState.sent, + ); + + // Create a retriable error (data == null) + when(() => client.updateMessage( + any(that: isSameMessageAs(message)), + skipEnrichUrl: true, + )).thenThrow(StreamChatNetworkError.raw( + code: ChatErrorCode.requestTimeout.code, + message: 'Request timed out', + )); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.updating), + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updatingFailed(skipEnrichUrl: true), + ), + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.updateMessage(message, skipEnrichUrl: true); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.requestTimeout.code)); + expect(networkError.isRetriable, isTrue); + } + }); + + test( + 'should add message to retry queue when retriable StreamChatNetworkError occurs with skipEnrichUrl: false', + () async { + final message = Message( + id: 'test-message-id-retry-2', + state: MessageState.sent, + ); + + // Create a retriable error (data == null) + when(() => client.updateMessage( + any(that: isSameMessageAs(message)), + )).thenThrow(StreamChatNetworkError.raw( + code: ChatErrorCode.internalSystemError.code, + message: 'Internal system error', + )); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.updating), + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updatingFailed(skipEnrichUrl: false), + ), + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.updateMessage(message); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, + equals(ChatErrorCode.internalSystemError.code)); + expect(networkError.isRetriable, isTrue); + } + }); + + test( + 'should handle non-retriable StreamChatNetworkError with skipEnrichUrl: true', + () async { + final message = Message( + id: 'test-message-id-error-2', + state: MessageState.sent, + ); + + when(() => client.updateMessage( + any(that: isSameMessageAs(message)), + skipEnrichUrl: true, + )).thenThrow(StreamChatNetworkError(ChatErrorCode.notAllowed)); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.updating), + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updatingFailed(skipEnrichUrl: true), + ), + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.updateMessage(message, skipEnrichUrl: true); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.notAllowed.code)); + } + }); + + test( + 'should handle non-retriable StreamChatNetworkError with skipEnrichUrl: false', + () async { + final message = Message( + id: 'test-message-id-error-3', + state: MessageState.sent, + ); + + when(() => client.updateMessage( + any(that: isSameMessageAs(message)), + )).thenThrow(StreamChatNetworkError(ChatErrorCode.notAllowed)); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith(state: MessageState.updating), + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updatingFailed(skipEnrichUrl: false), + ), + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.updateMessage(message); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.notAllowed.code)); + } + }); + }); + + test('`.partialUpdateMessage`', () async { + final message = Message( + id: 'test-message-id', + state: MessageState.sent, + ); + + const set = {'text': 'Update Message text'}; + const unset = ['pinExpires']; + + final updateMessageResponse = UpdateMessageResponse() + ..message = message.copyWith(text: set['text'], pinExpires: null); + + when( + () => client.partialUpdateMessage(message.id, set: set, unset: unset), + ).thenAnswer((_) async => updateMessageResponse); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updating, + ), + matchText: true, + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + updateMessageResponse.message.copyWith( + state: MessageState.updated, + ), + matchText: true, + matchMessageState: true, + ), + ], + ]), + ); + + final res = await channel.partialUpdateMessage( + message, + set: set, + unset: unset, + ); + + expect(res, isNotNull); + expect(res.message.id, message.id); + expect(res.message.id, message.id); + expect(res.message.text, set['text']); + expect(res.message.pinExpires, isNull); + + verify( + () => client.partialUpdateMessage(message.id, set: set, unset: unset), + ).called(1); + }); + + group('`.partialUpdateMessage` error handling', () { + test( + 'should not update message state when error is not StreamChatNetworkError', + () async { + final message = Message( + id: 'test-message-id-error-partial-1', + state: MessageState.sent, + ); + + // Add message to channel state first + channel.state?.updateMessage(message); + + const set = {'text': 'Update Message text'}; + const unset = ['pinExpires']; + + when( + () => client.partialUpdateMessage( + message.id, + set: set, + unset: unset, + ), + ).thenThrow(ArgumentError('Invalid argument')); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updating, + ), + matchText: true, + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.partialUpdateMessage( + message, + set: set, + unset: unset, + ); + } catch (e) { + expect(e, isA()); + } + }); + + test( + 'should add message to retry queue when retriable StreamChatNetworkError occurs with skipEnrichUrl: true', + () async { + final message = Message( + id: 'test-message-id-retry-partial-1', + state: MessageState.sent, + ); + + // Add message to channel state first + channel.state?.updateMessage(message); + + const set = {'text': 'Update Message text'}; + const unset = ['pinExpires']; + + // Create a retriable error (data == null) + when( + () => client.partialUpdateMessage( + message.id, + set: set, + unset: unset, + skipEnrichUrl: true, + ), + ).thenThrow(StreamChatNetworkError.raw( + code: ChatErrorCode.requestTimeout.code, + message: 'Request timed out', + )); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updating, + ), + matchText: true, + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updatingFailed(skipEnrichUrl: true), + ), + matchText: true, + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.partialUpdateMessage( + message, + set: set, + unset: unset, + skipEnrichUrl: true, + ); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.requestTimeout.code)); + expect(networkError.isRetriable, isTrue); + } + }); + + test( + 'should add message to retry queue when retriable StreamChatNetworkError occurs with skipEnrichUrl: false', + () async { + final message = Message( + id: 'test-message-id-retry-partial-2', + state: MessageState.sent, + ); + + // Add message to channel state first + channel.state?.updateMessage(message); + + const set = {'text': 'Update Message text'}; + const unset = ['pinExpires']; + + // Create a retriable error (data == null) + when( + () => client.partialUpdateMessage( + message.id, + set: set, + unset: unset, + ), + ).thenThrow(StreamChatNetworkError.raw( + code: ChatErrorCode.internalSystemError.code, + message: 'Internal system error', + )); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updating, + ), + matchText: true, + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updatingFailed(skipEnrichUrl: false), + ), + matchText: true, + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.partialUpdateMessage( + message, + set: set, + unset: unset, + ); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, + equals(ChatErrorCode.internalSystemError.code)); + expect(networkError.isRetriable, isTrue); + } + }); + + test( + 'should handle non-retriable StreamChatNetworkError with skipEnrichUrl: true', + () async { + final message = Message( + id: 'test-message-id-error-partial-2', + state: MessageState.sent, + ); + + // Add message to channel state first + channel.state?.updateMessage(message); + + const set = {'text': 'Update Message text'}; + const unset = ['pinExpires']; + + when( + () => client.partialUpdateMessage( + message.id, + set: set, + unset: unset, + skipEnrichUrl: true, + ), + ).thenThrow(StreamChatNetworkError(ChatErrorCode.notAllowed)); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updating, + ), + matchText: true, + matchMessageState: true, + ), + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updatingFailed(skipEnrichUrl: true), + ), + matchText: true, + matchMessageState: true, + ), + ], + ]), + ); + + try { + await channel.partialUpdateMessage( + message, + set: set, + unset: unset, + skipEnrichUrl: true, + ); + } catch (e) { + expect(e, isA()); + + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.notAllowed.code)); + } + }); + + test( + 'should handle non-retriable StreamChatNetworkError with skipEnrichUrl: false', + () async { + final message = Message( + id: 'test-message-id-error-partial-3', + state: MessageState.sent, + ); + + // Add message to channel state first + channel.state?.updateMessage(message); + + const set = {'text': 'Update Message text'}; + const unset = ['pinExpires']; + + when( + () => client.partialUpdateMessage( + message.id, + set: set, + unset: unset, + ), + ).thenThrow(StreamChatNetworkError(ChatErrorCode.notAllowed)); + + expectLater( + // skipping first seed message list -> [] messages + channel.state?.messagesStream.skip(1), + emitsInOrder([ + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updating, + ), + matchText: true, + matchMessageState: true, ), - matchText: true, - matchMessageState: true, - ), - ], - [ - isSameMessageAs( - updateMessageResponse.message.copyWith( - state: MessageState.updated, + ], + [ + isSameMessageAs( + message.copyWith( + state: MessageState.updatingFailed(skipEnrichUrl: false), + ), + matchText: true, + matchMessageState: true, ), - matchText: true, - matchMessageState: true, - ), - ], - ]), - ); - - final res = await channel.partialUpdateMessage( - message, - set: set, - unset: unset, - ); + ], + ]), + ); - expect(res, isNotNull); - expect(res.message.id, message.id); - expect(res.message.id, message.id); - expect(res.message.text, set['text']); - expect(res.message.pinExpires, isNull); + try { + await channel.partialUpdateMessage( + message, + set: set, + unset: unset, + ); + } catch (e) { + expect(e, isA()); - verify( - () => client.partialUpdateMessage(message.id, set: set, unset: unset), - ).called(1); + final networkError = e as StreamChatNetworkError; + expect(networkError.code, equals(ChatErrorCode.notAllowed.code)); + } + }); }); group('`.deleteMessage`', () { @@ -5095,4 +5886,286 @@ void main() { expect(channel.canUpdateChannel, false); }); }); + + group('Retry functionality with parameter preservation', () { + late final client = MockStreamChatClient(); + const channelId = 'test-channel-id'; + const channelType = 'test-channel-type'; + late Channel channel; + + setUpAll(() { + registerFallbackValue(FakeMessage()); + registerFallbackValue([]); + registerFallbackValue(FakeAttachmentFile()); + + when(() => client.detachedLogger(any())).thenAnswer((invocation) { + final name = invocation.positionalArguments.first; + return _createLogger(name); + }); + + when(() => client.logger).thenReturn(_createLogger('mock-client-logger')); + + final clientState = FakeClientState(); + when(() => client.state).thenReturn(clientState); + + final retryPolicy = RetryPolicy( + shouldRetry: (_, __, error) { + return error is StreamChatNetworkError && error.isRetriable; + }, + ); + when(() => client.retryPolicy).thenReturn(retryPolicy); + }); + + setUp(() { + final channelState = _generateChannelState(channelId, channelType); + channel = Channel.fromState(client, channelState); + }); + + tearDown(() { + channel.dispose(); + }); + + group('retryMessage method', () { + test( + 'should call sendMessage with preserved skipPush and skipEnrichUrl parameters', + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.sendingFailed( + skipPush: true, + skipEnrichUrl: true, + ), + ); + + final sendMessageResponse = SendMessageResponse() + ..message = message.copyWith(state: MessageState.sent); + + when(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + skipPush: true, + skipEnrichUrl: true, + )).thenAnswer((_) async => sendMessageResponse); + + final result = await channel.retryMessage(message); + + expect(result, isNotNull); + expect(result, isA()); + + verify(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + skipPush: true, + skipEnrichUrl: true, + )).called(1); + }); + + test('should call sendMessage with preserved skipPush parameter', + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.sendingFailed( + skipPush: true, + skipEnrichUrl: false, + ), + ); + + final sendMessageResponse = SendMessageResponse() + ..message = message.copyWith(state: MessageState.sent); + + when(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + skipPush: true, + )).thenAnswer((_) async => sendMessageResponse); + + final result = await channel.retryMessage(message); + + expect(result, isNotNull); + expect(result, isA()); + + verify(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + skipPush: true, + )).called(1); + }); + + test('should call sendMessage with preserved skipEnrichUrl parameter', + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.sendingFailed( + skipPush: false, + skipEnrichUrl: true, + ), + ); + + final sendMessageResponse = SendMessageResponse() + ..message = message.copyWith(state: MessageState.sent); + + when(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + skipEnrichUrl: true, + )).thenAnswer((_) async => sendMessageResponse); + + final result = await channel.retryMessage(message); + + expect(result, isNotNull); + expect(result, isA()); + + verify(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + skipEnrichUrl: true, + )).called(1); + }); + + test( + 'should call sendMessage with preserved false skipPush and skipEnrichUrl parameters', + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.sendingFailed( + skipPush: false, + skipEnrichUrl: false, + ), + ); + + final sendMessageResponse = SendMessageResponse() + ..message = message.copyWith(state: MessageState.sent); + + when(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + )).thenAnswer((_) async => sendMessageResponse); + + final result = await channel.retryMessage(message); + + expect(result, isNotNull); + expect(result, isA()); + + verify(() => client.sendMessage( + any(that: isSameMessageAs(message)), + channelId, + channelType, + )).called(1); + }); + + test('should call updateMessage with preserved skipEnrichUrl parameter', + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.updatingFailed(skipEnrichUrl: true), + ); + + final updateMessageResponse = UpdateMessageResponse() + ..message = message.copyWith(state: MessageState.updated); + + when(() => client.updateMessage( + any(that: isSameMessageAs(message)), + skipEnrichUrl: true, + )).thenAnswer((_) async => updateMessageResponse); + + final result = await channel.retryMessage(message); + + expect(result, isNotNull); + expect(result, isA()); + + verify(() => client.updateMessage( + any(that: isSameMessageAs(message)), + skipEnrichUrl: true, + )).called(1); + }); + + test( + 'should call updateMessage with preserved false skipEnrichUrl parameter', + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.updatingFailed(skipEnrichUrl: false), + ); + + final updateMessageResponse = UpdateMessageResponse() + ..message = message.copyWith(state: MessageState.updated); + + when(() => client.updateMessage( + any(that: isSameMessageAs(message)), + )).thenAnswer((_) async => updateMessageResponse); + + final result = await channel.retryMessage(message); + + expect(result, isNotNull); + expect(result, isA()); + + verify(() => client.updateMessage( + any(that: isSameMessageAs(message)), + )).called(1); + }); + + test('should call deleteMessage with preserved hard parameter', () async { + final message = Message( + id: 'test-message-id', + createdAt: DateTime.now(), + state: MessageState.deletingFailed(hard: true), + ); + + when(() => client.deleteMessage( + message.id, + hard: true, + )).thenAnswer((_) async => EmptyResponse()); + + final result = await channel.retryMessage(message); + + expect(result, isNotNull); + expect(result, isA()); + + verify(() => client.deleteMessage( + message.id, + hard: true, + )).called(1); + }); + + test('should call deleteMessage with preserved false hard parameter', + () async { + final message = Message( + id: 'test-message-id', + createdAt: DateTime.now(), + state: MessageState.deletingFailed(hard: false), + ); + + when(() => client.deleteMessage( + message.id, + )).thenAnswer((_) async => EmptyResponse()); + + final result = await channel.retryMessage(message); + + expect(result, isNotNull); + expect(result, isA()); + + verify(() => client.deleteMessage( + message.id, + )).called(1); + }); + + test('should throw AssertionError when message state is not failed', + () async { + final message = Message( + id: 'test-message-id', + state: MessageState.sent, + ); + + expect(() => channel.retryMessage(message), + throwsA(isA())); + }); + }); + }); } diff --git a/packages/stream_chat/test/src/client/retry_queue_test.dart b/packages/stream_chat/test/src/client/retry_queue_test.dart index 1150c40b85..59e2e51f47 100644 --- a/packages/stream_chat/test/src/client/retry_queue_test.dart +++ b/packages/stream_chat/test/src/client/retry_queue_test.dart @@ -46,7 +46,10 @@ void main() { final message = Message( id: 'test-message-id', text: 'Sample message test', - state: MessageState.sendingFailed, + state: MessageState.sendingFailed( + skipPush: false, + skipEnrichUrl: false, + ), ); retryQueue.add([message]); expect(() => retryQueue.add([message]), returnsNormally); @@ -58,7 +61,10 @@ void main() { final message = Message( id: 'test-message-id', text: 'Sample message test', - state: MessageState.sendingFailed, + state: MessageState.sendingFailed( + skipPush: false, + skipEnrichUrl: false, + ), ); retryQueue.add([message]); expect(retryQueue.hasMessages, isTrue); diff --git a/packages/stream_chat/test/src/core/models/message_state_test.dart b/packages/stream_chat/test/src/core/models/message_state_test.dart index 9bdb250af9..5ec2305f98 100644 --- a/packages/stream_chat/test/src/core/models/message_state_test.dart +++ b/packages/stream_chat/test/src/core/models/message_state_test.dart @@ -270,7 +270,10 @@ void main() { test( 'MessageState.sendingFailed should create a MessageFailed instance with SendingFailed state', () { - const messageState = MessageState.sendingFailed; + final messageState = MessageState.sendingFailed( + skipPush: false, + skipEnrichUrl: false, + ); expect(messageState, isA()); expect((messageState as MessageFailed).state, isA()); }, @@ -279,7 +282,7 @@ void main() { test( 'MessageState.updatingFailed should create a MessageFailed instance with UpdatingFailed state', () { - const messageState = MessageState.updatingFailed; + final messageState = MessageState.updatingFailed(skipEnrichUrl: false); expect(messageState, isA()); expect((messageState as MessageFailed).state, isA()); }, diff --git a/packages/stream_chat_flutter/test/src/message_actions_modal/message_actions_modal_test.dart b/packages/stream_chat_flutter/test/src/message_actions_modal/message_actions_modal_test.dart index 194652b336..fdb8f9c946 100644 --- a/packages/stream_chat_flutter/test/src/message_actions_modal/message_actions_modal_test.dart +++ b/packages/stream_chat_flutter/test/src/message_actions_modal/message_actions_modal_test.dart @@ -543,7 +543,10 @@ void main() { final channel = MockChannel(); final message = Message( - state: MessageState.sendingFailed, + state: MessageState.sendingFailed( + skipPush: false, + skipEnrichUrl: false, + ), text: 'test', user: User( id: 'user-id', From 43fd5cf432c49a1db3b883b86d63fe9b7766dca2 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Tue, 29 Jul 2025 16:18:06 +0200 Subject: [PATCH 2/6] fix(llc): add skipPush to FailedState.updatingFailed The `skipPush` parameter was missing from the `FailedState.updatingFailed` constructor and its associated logic. This commit adds the parameter and updates the relevant code to use it. This change ensures that the `skipPush` option is correctly propagated when a message update fails. --- .../stream_chat/lib/src/client/channel.dart | 23 +- .../lib/src/client/retry_queue.dart | 2 +- .../lib/src/core/models/message_state.dart | 33 +- .../core/models/message_state.freezed.dart | 2315 ++++------------- .../lib/src/core/models/message_state.g.dart | 86 +- .../test/src/client/channel_test.dart | 6 +- 6 files changed, 549 insertions(+), 1916 deletions(-) diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index ebd9079160..653e2e57d0 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -827,14 +827,20 @@ class Channel { state!._retryQueue.add([ message.copyWith( // Update the message state to failed. - state: MessageState.updatingFailed(skipEnrichUrl: skipEnrichUrl), + state: MessageState.updatingFailed( + skipPush: skipPush, + skipEnrichUrl: skipEnrichUrl, + ), ), ]); } else { // Reset the message to original state if the update fails and is not // retriable. state?.updateMessage(originalMessage.copyWith( - state: MessageState.updatingFailed(skipEnrichUrl: skipEnrichUrl), + state: MessageState.updatingFailed( + skipPush: skipPush, + skipEnrichUrl: skipEnrichUrl, + ), )); } } @@ -897,14 +903,20 @@ class Channel { state!._retryQueue.add([ message.copyWith( // Update the message state to failed. - state: MessageState.updatingFailed(skipEnrichUrl: skipEnrichUrl), + state: MessageState.updatingFailed( + skipPush: false, + skipEnrichUrl: skipEnrichUrl, + ), ), ]); } else { // Reset the message to original state if the update fails and is not // retriable. state?.updateMessage(originalMessage.copyWith( - state: MessageState.updatingFailed(skipEnrichUrl: skipEnrichUrl), + state: MessageState.updatingFailed( + skipPush: false, + skipEnrichUrl: skipEnrichUrl, + ), )); } } @@ -1006,8 +1018,9 @@ class Channel { skipPush: skipPush, skipEnrichUrl: skipEnrichUrl, ), - updatingFailed: (skipEnrichUrl) => updateMessage( + updatingFailed: (skipPush, skipEnrichUrl) => updateMessage( message, + skipPush: skipPush, skipEnrichUrl: skipEnrichUrl, ), deletingFailed: (hard) => deleteMessage(message, hard: hard), diff --git a/packages/stream_chat/lib/src/client/retry_queue.dart b/packages/stream_chat/lib/src/client/retry_queue.dart index cc502c119d..78120125d4 100644 --- a/packages/stream_chat/lib/src/client/retry_queue.dart +++ b/packages/stream_chat/lib/src/client/retry_queue.dart @@ -122,7 +122,7 @@ class RetryQueue { return message.state.maybeWhen( failed: (state, _) => state.when( sendingFailed: (_, __) => message.createdAt, - updatingFailed: (_) => message.updatedAt, + updatingFailed: (_, __) => message.updatedAt, deletingFailed: (_) => message.deletedAt, ), orElse: () => null, diff --git a/packages/stream_chat/lib/src/core/models/message_state.dart b/packages/stream_chat/lib/src/core/models/message_state.dart index a28208f758..d5134ea4b1 100644 --- a/packages/stream_chat/lib/src/core/models/message_state.dart +++ b/packages/stream_chat/lib/src/core/models/message_state.dart @@ -197,10 +197,12 @@ sealed class MessageState with _$MessageState { /// Updating failed state when the message fails to be updated. factory MessageState.updatingFailed({ + required bool skipPush, required bool skipEnrichUrl, }) { return MessageState.failed( state: FailedState.updatingFailed( + skipPush: skipPush, skipEnrichUrl: skipEnrichUrl, ), ); @@ -306,6 +308,7 @@ sealed class FailedState with _$FailedState { /// Updating failed state when the message fails to be updated. const factory FailedState.updatingFailed({ + @Default(false) bool skipPush, @Default(false) bool skipEnrichUrl, }) = UpdatingFailed; @@ -635,14 +638,16 @@ extension FailedStatePatternMatching on FailedState { /// @nodoc @optionalTypeArgs TResult when({ - required TResult Function() sendingFailed, - required TResult Function() updatingFailed, + required TResult Function(bool skipPush, bool skipEnrichUrl) sendingFailed, + required TResult Function(bool skipPush, bool skipEnrichUrl) updatingFailed, required TResult Function(bool hard) deletingFailed, }) { final failedState = this; return switch (failedState) { - SendingFailed() => sendingFailed(), - UpdatingFailed() => updatingFailed(), + SendingFailed() => + sendingFailed(failedState.skipPush, failedState.skipEnrichUrl), + UpdatingFailed() => + updatingFailed(failedState.skipPush, failedState.skipEnrichUrl), DeletingFailed() => deletingFailed(failedState.hard), }; } @@ -650,14 +655,16 @@ extension FailedStatePatternMatching on FailedState { /// @nodoc @optionalTypeArgs TResult? whenOrNull({ - TResult? Function()? sendingFailed, - TResult? Function()? updatingFailed, + TResult? Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, + TResult? Function(bool skipPush, bool skipEnrichUrl)? updatingFailed, TResult? Function(bool hard)? deletingFailed, }) { final failedState = this; return switch (failedState) { - SendingFailed() => sendingFailed?.call(), - UpdatingFailed() => updatingFailed?.call(), + SendingFailed() => + sendingFailed?.call(failedState.skipPush, failedState.skipEnrichUrl), + UpdatingFailed() => + updatingFailed?.call(failedState.skipPush, failedState.skipEnrichUrl), DeletingFailed() => deletingFailed?.call(failedState.hard), }; } @@ -665,15 +672,17 @@ extension FailedStatePatternMatching on FailedState { /// @nodoc @optionalTypeArgs TResult maybeWhen({ - TResult Function()? sendingFailed, - TResult Function()? updatingFailed, + TResult Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, + TResult Function(bool skipPush, bool skipEnrichUrl)? updatingFailed, TResult Function(bool hard)? deletingFailed, required TResult orElse(), }) { final failedState = this; final result = switch (failedState) { - SendingFailed() => sendingFailed?.call(), - UpdatingFailed() => updatingFailed?.call(), + SendingFailed() => + sendingFailed?.call(failedState.skipPush, failedState.skipEnrichUrl), + UpdatingFailed() => + updatingFailed?.call(failedState.skipPush, failedState.skipEnrichUrl), DeletingFailed() => deletingFailed?.call(failedState.hard), }; diff --git a/packages/stream_chat/lib/src/core/models/message_state.freezed.dart b/packages/stream_chat/lib/src/core/models/message_state.freezed.dart index 02f9d4b089..ca5bfc80c4 100644 --- a/packages/stream_chat/lib/src/core/models/message_state.freezed.dart +++ b/packages/stream_chat/lib/src/core/models/message_state.freezed.dart @@ -1,3 +1,4 @@ +// dart format width=80 // coverage:ignore-file // GENERATED CODE - DO NOT MODIFY BY HAND // ignore_for_file: type=lint @@ -9,11 +10,8 @@ part of 'message_state.dart'; // FreezedGenerator // ************************************************************************** +// dart format off 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#adding-getters-and-methods-to-our-models'); - MessageState _$MessageStateFromJson(Map json) { switch (json['runtimeType']) { case 'initial': @@ -33,122 +31,51 @@ MessageState _$MessageStateFromJson(Map json) { /// @nodoc mixin _$MessageState { - @optionalTypeArgs - TResult when({ - required TResult Function() initial, - required TResult Function(OutgoingState state) outgoing, - required TResult Function(CompletedState state) completed, - required TResult Function(FailedState state, Object? reason) failed, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function()? initial, - TResult? Function(OutgoingState state)? outgoing, - TResult? Function(CompletedState state)? completed, - TResult? Function(FailedState state, Object? reason)? failed, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? initial, - TResult Function(OutgoingState state)? outgoing, - TResult Function(CompletedState state)? completed, - TResult Function(FailedState state, Object? reason)? failed, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult map({ - required TResult Function(MessageInitial value) initial, - required TResult Function(MessageOutgoing value) outgoing, - required TResult Function(MessageCompleted value) completed, - required TResult Function(MessageFailed value) failed, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(MessageInitial value)? initial, - TResult? Function(MessageOutgoing value)? outgoing, - TResult? Function(MessageCompleted value)? completed, - TResult? Function(MessageFailed value)? failed, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeMap({ - TResult Function(MessageInitial value)? initial, - TResult Function(MessageOutgoing value)? outgoing, - TResult Function(MessageCompleted value)? completed, - TResult Function(MessageFailed value)? failed, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - /// Serializes this MessageState to a JSON map. - Map toJson() => throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $MessageStateCopyWith<$Res> { - factory $MessageStateCopyWith( - MessageState value, $Res Function(MessageState) then) = - _$MessageStateCopyWithImpl<$Res, MessageState>; -} - -/// @nodoc -class _$MessageStateCopyWithImpl<$Res, $Val extends MessageState> - implements $MessageStateCopyWith<$Res> { - _$MessageStateCopyWithImpl(this._value, this._then); + Map toJson(); - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is MessageState); + } - /// Create a copy of MessageState - /// with the given fields replaced by the non-null parameter values. -} + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => runtimeType.hashCode; -/// @nodoc -abstract class _$$MessageInitialImplCopyWith<$Res> { - factory _$$MessageInitialImplCopyWith(_$MessageInitialImpl value, - $Res Function(_$MessageInitialImpl) then) = - __$$MessageInitialImplCopyWithImpl<$Res>; + @override + String toString() { + return 'MessageState()'; + } } /// @nodoc -class __$$MessageInitialImplCopyWithImpl<$Res> - extends _$MessageStateCopyWithImpl<$Res, _$MessageInitialImpl> - implements _$$MessageInitialImplCopyWith<$Res> { - __$$MessageInitialImplCopyWithImpl( - _$MessageInitialImpl _value, $Res Function(_$MessageInitialImpl) _then) - : super(_value, _then); - - /// Create a copy of MessageState - /// with the given fields replaced by the non-null parameter values. +class $MessageStateCopyWith<$Res> { + $MessageStateCopyWith(MessageState _, $Res Function(MessageState) __); } /// @nodoc @JsonSerializable() -class _$MessageInitialImpl implements MessageInitial { - const _$MessageInitialImpl({final String? $type}) - : $type = $type ?? 'initial'; - - factory _$MessageInitialImpl.fromJson(Map json) => - _$$MessageInitialImplFromJson(json); +class MessageInitial implements MessageState { + const MessageInitial({final String? $type}) : $type = $type ?? 'initial'; + factory MessageInitial.fromJson(Map json) => + _$MessageInitialFromJson(json); @JsonKey(name: 'runtimeType') final String $type; @override - String toString() { - return 'MessageState.initial()'; + Map toJson() { + return _$MessageInitialToJson( + this, + ); } @override bool operator ==(Object other) { return identical(this, other) || - (other.runtimeType == runtimeType && other is _$MessageInitialImpl); + (other.runtimeType == runtimeType && other is MessageInitial); } @JsonKey(includeFromJson: false, includeToJson: false) @@ -156,99 +83,62 @@ class _$MessageInitialImpl implements MessageInitial { int get hashCode => runtimeType.hashCode; @override - @optionalTypeArgs - TResult when({ - required TResult Function() initial, - required TResult Function(OutgoingState state) outgoing, - required TResult Function(CompletedState state) completed, - required TResult Function(FailedState state, Object? reason) failed, - }) { - return initial(); + String toString() { + return 'MessageState.initial()'; } +} - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function()? initial, - TResult? Function(OutgoingState state)? outgoing, - TResult? Function(CompletedState state)? completed, - TResult? Function(FailedState state, Object? reason)? failed, - }) { - return initial?.call(); - } +/// @nodoc +@JsonSerializable() +class MessageOutgoing implements MessageState { + const MessageOutgoing({required this.state, final String? $type}) + : $type = $type ?? 'outgoing'; + factory MessageOutgoing.fromJson(Map json) => + _$MessageOutgoingFromJson(json); - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? initial, - TResult Function(OutgoingState state)? outgoing, - TResult Function(CompletedState state)? completed, - TResult Function(FailedState state, Object? reason)? failed, - required TResult orElse(), - }) { - if (initial != null) { - return initial(); - } - return orElse(); - } + final OutgoingState state; + + @JsonKey(name: 'runtimeType') + final String $type; + + /// Create a copy of MessageState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $MessageOutgoingCopyWith get copyWith => + _$MessageOutgoingCopyWithImpl(this, _$identity); @override - @optionalTypeArgs - TResult map({ - required TResult Function(MessageInitial value) initial, - required TResult Function(MessageOutgoing value) outgoing, - required TResult Function(MessageCompleted value) completed, - required TResult Function(MessageFailed value) failed, - }) { - return initial(this); + Map toJson() { + return _$MessageOutgoingToJson( + this, + ); } @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(MessageInitial value)? initial, - TResult? Function(MessageOutgoing value)? outgoing, - TResult? Function(MessageCompleted value)? completed, - TResult? Function(MessageFailed value)? failed, - }) { - return initial?.call(this); + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is MessageOutgoing && + (identical(other.state, state) || other.state == state)); } + @JsonKey(includeFromJson: false, includeToJson: false) @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(MessageInitial value)? initial, - TResult Function(MessageOutgoing value)? outgoing, - TResult Function(MessageCompleted value)? completed, - TResult Function(MessageFailed value)? failed, - required TResult orElse(), - }) { - if (initial != null) { - return initial(this); - } - return orElse(); - } + int get hashCode => Object.hash(runtimeType, state); @override - Map toJson() { - return _$$MessageInitialImplToJson( - this, - ); + String toString() { + return 'MessageState.outgoing(state: $state)'; } } -abstract class MessageInitial implements MessageState { - const factory MessageInitial() = _$MessageInitialImpl; - - factory MessageInitial.fromJson(Map json) = - _$MessageInitialImpl.fromJson; -} - /// @nodoc -abstract class _$$MessageOutgoingImplCopyWith<$Res> { - factory _$$MessageOutgoingImplCopyWith(_$MessageOutgoingImpl value, - $Res Function(_$MessageOutgoingImpl) then) = - __$$MessageOutgoingImplCopyWithImpl<$Res>; +abstract mixin class $MessageOutgoingCopyWith<$Res> + implements $MessageStateCopyWith<$Res> { + factory $MessageOutgoingCopyWith( + MessageOutgoing value, $Res Function(MessageOutgoing) _then) = + _$MessageOutgoingCopyWithImpl; @useResult $Res call({OutgoingState state}); @@ -256,23 +146,22 @@ abstract class _$$MessageOutgoingImplCopyWith<$Res> { } /// @nodoc -class __$$MessageOutgoingImplCopyWithImpl<$Res> - extends _$MessageStateCopyWithImpl<$Res, _$MessageOutgoingImpl> - implements _$$MessageOutgoingImplCopyWith<$Res> { - __$$MessageOutgoingImplCopyWithImpl( - _$MessageOutgoingImpl _value, $Res Function(_$MessageOutgoingImpl) _then) - : super(_value, _then); +class _$MessageOutgoingCopyWithImpl<$Res> + implements $MessageOutgoingCopyWith<$Res> { + _$MessageOutgoingCopyWithImpl(this._self, this._then); + + final MessageOutgoing _self; + final $Res Function(MessageOutgoing) _then; /// Create a copy of MessageState /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') - @override $Res call({ Object? state = null, }) { - return _then(_$MessageOutgoingImpl( + return _then(MessageOutgoing( state: null == state - ? _value.state + ? _self.state : state // ignore: cast_nullable_to_non_nullable as OutgoingState, )); @@ -283,37 +172,44 @@ class __$$MessageOutgoingImplCopyWithImpl<$Res> @override @pragma('vm:prefer-inline') $OutgoingStateCopyWith<$Res> get state { - return $OutgoingStateCopyWith<$Res>(_value.state, (value) { - return _then(_value.copyWith(state: value)); + return $OutgoingStateCopyWith<$Res>(_self.state, (value) { + return _then(_self.copyWith(state: value)); }); } } /// @nodoc @JsonSerializable() -class _$MessageOutgoingImpl implements MessageOutgoing { - const _$MessageOutgoingImpl({required this.state, final String? $type}) - : $type = $type ?? 'outgoing'; - - factory _$MessageOutgoingImpl.fromJson(Map json) => - _$$MessageOutgoingImplFromJson(json); +class MessageCompleted implements MessageState { + const MessageCompleted({required this.state, final String? $type}) + : $type = $type ?? 'completed'; + factory MessageCompleted.fromJson(Map json) => + _$MessageCompletedFromJson(json); - @override - final OutgoingState state; + final CompletedState state; @JsonKey(name: 'runtimeType') final String $type; + /// Create a copy of MessageState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $MessageCompletedCopyWith get copyWith => + _$MessageCompletedCopyWithImpl(this, _$identity); + @override - String toString() { - return 'MessageState.outgoing(state: $state)'; + Map toJson() { + return _$MessageCompletedToJson( + this, + ); } @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$MessageOutgoingImpl && + other is MessageCompleted && (identical(other.state, state) || other.state == state)); } @@ -321,118 +217,18 @@ class _$MessageOutgoingImpl implements MessageOutgoing { @override int get hashCode => Object.hash(runtimeType, state); - /// Create a copy of MessageState - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - @override - @pragma('vm:prefer-inline') - _$$MessageOutgoingImplCopyWith<_$MessageOutgoingImpl> get copyWith => - __$$MessageOutgoingImplCopyWithImpl<_$MessageOutgoingImpl>( - this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function() initial, - required TResult Function(OutgoingState state) outgoing, - required TResult Function(CompletedState state) completed, - required TResult Function(FailedState state, Object? reason) failed, - }) { - return outgoing(state); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function()? initial, - TResult? Function(OutgoingState state)? outgoing, - TResult? Function(CompletedState state)? completed, - TResult? Function(FailedState state, Object? reason)? failed, - }) { - return outgoing?.call(state); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? initial, - TResult Function(OutgoingState state)? outgoing, - TResult Function(CompletedState state)? completed, - TResult Function(FailedState state, Object? reason)? failed, - required TResult orElse(), - }) { - if (outgoing != null) { - return outgoing(state); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(MessageInitial value) initial, - required TResult Function(MessageOutgoing value) outgoing, - required TResult Function(MessageCompleted value) completed, - required TResult Function(MessageFailed value) failed, - }) { - return outgoing(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(MessageInitial value)? initial, - TResult? Function(MessageOutgoing value)? outgoing, - TResult? Function(MessageCompleted value)? completed, - TResult? Function(MessageFailed value)? failed, - }) { - return outgoing?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(MessageInitial value)? initial, - TResult Function(MessageOutgoing value)? outgoing, - TResult Function(MessageCompleted value)? completed, - TResult Function(MessageFailed value)? failed, - required TResult orElse(), - }) { - if (outgoing != null) { - return outgoing(this); - } - return orElse(); - } - @override - Map toJson() { - return _$$MessageOutgoingImplToJson( - this, - ); + String toString() { + return 'MessageState.completed(state: $state)'; } } -abstract class MessageOutgoing implements MessageState { - const factory MessageOutgoing({required final OutgoingState state}) = - _$MessageOutgoingImpl; - - factory MessageOutgoing.fromJson(Map json) = - _$MessageOutgoingImpl.fromJson; - - OutgoingState get state; - - /// Create a copy of MessageState - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - _$$MessageOutgoingImplCopyWith<_$MessageOutgoingImpl> get copyWith => - throw _privateConstructorUsedError; -} - /// @nodoc -abstract class _$$MessageCompletedImplCopyWith<$Res> { - factory _$$MessageCompletedImplCopyWith(_$MessageCompletedImpl value, - $Res Function(_$MessageCompletedImpl) then) = - __$$MessageCompletedImplCopyWithImpl<$Res>; +abstract mixin class $MessageCompletedCopyWith<$Res> + implements $MessageStateCopyWith<$Res> { + factory $MessageCompletedCopyWith( + MessageCompleted value, $Res Function(MessageCompleted) _then) = + _$MessageCompletedCopyWithImpl; @useResult $Res call({CompletedState state}); @@ -440,23 +236,22 @@ abstract class _$$MessageCompletedImplCopyWith<$Res> { } /// @nodoc -class __$$MessageCompletedImplCopyWithImpl<$Res> - extends _$MessageStateCopyWithImpl<$Res, _$MessageCompletedImpl> - implements _$$MessageCompletedImplCopyWith<$Res> { - __$$MessageCompletedImplCopyWithImpl(_$MessageCompletedImpl _value, - $Res Function(_$MessageCompletedImpl) _then) - : super(_value, _then); +class _$MessageCompletedCopyWithImpl<$Res> + implements $MessageCompletedCopyWith<$Res> { + _$MessageCompletedCopyWithImpl(this._self, this._then); + + final MessageCompleted _self; + final $Res Function(MessageCompleted) _then; /// Create a copy of MessageState /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') - @override $Res call({ Object? state = null, }) { - return _then(_$MessageCompletedImpl( + return _then(MessageCompleted( state: null == state - ? _value.state + ? _self.state : state // ignore: cast_nullable_to_non_nullable as CompletedState, )); @@ -467,156 +262,66 @@ class __$$MessageCompletedImplCopyWithImpl<$Res> @override @pragma('vm:prefer-inline') $CompletedStateCopyWith<$Res> get state { - return $CompletedStateCopyWith<$Res>(_value.state, (value) { - return _then(_value.copyWith(state: value)); + return $CompletedStateCopyWith<$Res>(_self.state, (value) { + return _then(_self.copyWith(state: value)); }); } } /// @nodoc @JsonSerializable() -class _$MessageCompletedImpl implements MessageCompleted { - const _$MessageCompletedImpl({required this.state, final String? $type}) - : $type = $type ?? 'completed'; - - factory _$MessageCompletedImpl.fromJson(Map json) => - _$$MessageCompletedImplFromJson(json); +class MessageFailed implements MessageState { + const MessageFailed({required this.state, this.reason, final String? $type}) + : $type = $type ?? 'failed'; + factory MessageFailed.fromJson(Map json) => + _$MessageFailedFromJson(json); - @override - final CompletedState state; + final FailedState state; + final Object? reason; @JsonKey(name: 'runtimeType') final String $type; - @override - String toString() { - return 'MessageState.completed(state: $state)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$MessageCompletedImpl && - (identical(other.state, state) || other.state == state)); - } - - @JsonKey(includeFromJson: false, includeToJson: false) - @override - int get hashCode => Object.hash(runtimeType, state); - /// Create a copy of MessageState /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) - @override @pragma('vm:prefer-inline') - _$$MessageCompletedImplCopyWith<_$MessageCompletedImpl> get copyWith => - __$$MessageCompletedImplCopyWithImpl<_$MessageCompletedImpl>( - this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function() initial, - required TResult Function(OutgoingState state) outgoing, - required TResult Function(CompletedState state) completed, - required TResult Function(FailedState state, Object? reason) failed, - }) { - return completed(state); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function()? initial, - TResult? Function(OutgoingState state)? outgoing, - TResult? Function(CompletedState state)? completed, - TResult? Function(FailedState state, Object? reason)? failed, - }) { - return completed?.call(state); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? initial, - TResult Function(OutgoingState state)? outgoing, - TResult Function(CompletedState state)? completed, - TResult Function(FailedState state, Object? reason)? failed, - required TResult orElse(), - }) { - if (completed != null) { - return completed(state); - } - return orElse(); - } + $MessageFailedCopyWith get copyWith => + _$MessageFailedCopyWithImpl(this, _$identity); @override - @optionalTypeArgs - TResult map({ - required TResult Function(MessageInitial value) initial, - required TResult Function(MessageOutgoing value) outgoing, - required TResult Function(MessageCompleted value) completed, - required TResult Function(MessageFailed value) failed, - }) { - return completed(this); + Map toJson() { + return _$MessageFailedToJson( + this, + ); } @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(MessageInitial value)? initial, - TResult? Function(MessageOutgoing value)? outgoing, - TResult? Function(MessageCompleted value)? completed, - TResult? Function(MessageFailed value)? failed, - }) { - return completed?.call(this); + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is MessageFailed && + (identical(other.state, state) || other.state == state) && + const DeepCollectionEquality().equals(other.reason, reason)); } + @JsonKey(includeFromJson: false, includeToJson: false) @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(MessageInitial value)? initial, - TResult Function(MessageOutgoing value)? outgoing, - TResult Function(MessageCompleted value)? completed, - TResult Function(MessageFailed value)? failed, - required TResult orElse(), - }) { - if (completed != null) { - return completed(this); - } - return orElse(); - } + int get hashCode => Object.hash( + runtimeType, state, const DeepCollectionEquality().hash(reason)); @override - Map toJson() { - return _$$MessageCompletedImplToJson( - this, - ); + String toString() { + return 'MessageState.failed(state: $state, reason: $reason)'; } } -abstract class MessageCompleted implements MessageState { - const factory MessageCompleted({required final CompletedState state}) = - _$MessageCompletedImpl; - - factory MessageCompleted.fromJson(Map json) = - _$MessageCompletedImpl.fromJson; - - CompletedState get state; - - /// Create a copy of MessageState - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - _$$MessageCompletedImplCopyWith<_$MessageCompletedImpl> get copyWith => - throw _privateConstructorUsedError; -} - /// @nodoc -abstract class _$$MessageFailedImplCopyWith<$Res> { - factory _$$MessageFailedImplCopyWith( - _$MessageFailedImpl value, $Res Function(_$MessageFailedImpl) then) = - __$$MessageFailedImplCopyWithImpl<$Res>; +abstract mixin class $MessageFailedCopyWith<$Res> + implements $MessageStateCopyWith<$Res> { + factory $MessageFailedCopyWith( + MessageFailed value, $Res Function(MessageFailed) _then) = + _$MessageFailedCopyWithImpl; @useResult $Res call({FailedState state, Object? reason}); @@ -624,27 +329,26 @@ abstract class _$$MessageFailedImplCopyWith<$Res> { } /// @nodoc -class __$$MessageFailedImplCopyWithImpl<$Res> - extends _$MessageStateCopyWithImpl<$Res, _$MessageFailedImpl> - implements _$$MessageFailedImplCopyWith<$Res> { - __$$MessageFailedImplCopyWithImpl( - _$MessageFailedImpl _value, $Res Function(_$MessageFailedImpl) _then) - : super(_value, _then); +class _$MessageFailedCopyWithImpl<$Res> + implements $MessageFailedCopyWith<$Res> { + _$MessageFailedCopyWithImpl(this._self, this._then); + + final MessageFailed _self; + final $Res Function(MessageFailed) _then; /// Create a copy of MessageState /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') - @override $Res call({ Object? state = null, Object? reason = freezed, }) { - return _then(_$MessageFailedImpl( + return _then(MessageFailed( state: null == state - ? _value.state + ? _self.state : state // ignore: cast_nullable_to_non_nullable as FailedState, - reason: freezed == reason ? _value.reason : reason, + reason: freezed == reason ? _self.reason : reason, )); } @@ -653,283 +357,107 @@ class __$$MessageFailedImplCopyWithImpl<$Res> @override @pragma('vm:prefer-inline') $FailedStateCopyWith<$Res> get state { - return $FailedStateCopyWith<$Res>(_value.state, (value) { - return _then(_value.copyWith(state: value)); + return $FailedStateCopyWith<$Res>(_self.state, (value) { + return _then(_self.copyWith(state: value)); }); } } +OutgoingState _$OutgoingStateFromJson(Map json) { + switch (json['runtimeType']) { + case 'sending': + return Sending.fromJson(json); + case 'updating': + return Updating.fromJson(json); + case 'deleting': + return Deleting.fromJson(json); + + default: + throw CheckedFromJsonException(json, 'runtimeType', 'OutgoingState', + 'Invalid union type "${json['runtimeType']}"!'); + } +} + /// @nodoc -@JsonSerializable() -class _$MessageFailedImpl implements MessageFailed { - const _$MessageFailedImpl( - {required this.state, this.reason, final String? $type}) - : $type = $type ?? 'failed'; +mixin _$OutgoingState { + /// Serializes this OutgoingState to a JSON map. + Map toJson(); - factory _$MessageFailedImpl.fromJson(Map json) => - _$$MessageFailedImplFromJson(json); + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is OutgoingState); + } + @JsonKey(includeFromJson: false, includeToJson: false) @override - final FailedState state; + int get hashCode => runtimeType.hashCode; + @override - final Object? reason; + String toString() { + return 'OutgoingState()'; + } +} + +/// @nodoc +class $OutgoingStateCopyWith<$Res> { + $OutgoingStateCopyWith(OutgoingState _, $Res Function(OutgoingState) __); +} + +/// @nodoc +@JsonSerializable() +class Sending implements OutgoingState { + const Sending({final String? $type}) : $type = $type ?? 'sending'; + factory Sending.fromJson(Map json) => + _$SendingFromJson(json); @JsonKey(name: 'runtimeType') final String $type; @override - String toString() { - return 'MessageState.failed(state: $state, reason: $reason)'; + Map toJson() { + return _$SendingToJson( + this, + ); } @override bool operator ==(Object other) { return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$MessageFailedImpl && - (identical(other.state, state) || other.state == state) && - const DeepCollectionEquality().equals(other.reason, reason)); + (other.runtimeType == runtimeType && other is Sending); } @JsonKey(includeFromJson: false, includeToJson: false) @override - int get hashCode => Object.hash( - runtimeType, state, const DeepCollectionEquality().hash(reason)); - - /// Create a copy of MessageState - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - @override - @pragma('vm:prefer-inline') - _$$MessageFailedImplCopyWith<_$MessageFailedImpl> get copyWith => - __$$MessageFailedImplCopyWithImpl<_$MessageFailedImpl>(this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function() initial, - required TResult Function(OutgoingState state) outgoing, - required TResult Function(CompletedState state) completed, - required TResult Function(FailedState state, Object? reason) failed, - }) { - return failed(state, reason); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function()? initial, - TResult? Function(OutgoingState state)? outgoing, - TResult? Function(CompletedState state)? completed, - TResult? Function(FailedState state, Object? reason)? failed, - }) { - return failed?.call(state, reason); - } + int get hashCode => runtimeType.hashCode; @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? initial, - TResult Function(OutgoingState state)? outgoing, - TResult Function(CompletedState state)? completed, - TResult Function(FailedState state, Object? reason)? failed, - required TResult orElse(), - }) { - if (failed != null) { - return failed(state, reason); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(MessageInitial value) initial, - required TResult Function(MessageOutgoing value) outgoing, - required TResult Function(MessageCompleted value) completed, - required TResult Function(MessageFailed value) failed, - }) { - return failed(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(MessageInitial value)? initial, - TResult? Function(MessageOutgoing value)? outgoing, - TResult? Function(MessageCompleted value)? completed, - TResult? Function(MessageFailed value)? failed, - }) { - return failed?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(MessageInitial value)? initial, - TResult Function(MessageOutgoing value)? outgoing, - TResult Function(MessageCompleted value)? completed, - TResult Function(MessageFailed value)? failed, - required TResult orElse(), - }) { - if (failed != null) { - return failed(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$MessageFailedImplToJson( - this, - ); - } -} - -abstract class MessageFailed implements MessageState { - const factory MessageFailed( - {required final FailedState state, - final Object? reason}) = _$MessageFailedImpl; - - factory MessageFailed.fromJson(Map json) = - _$MessageFailedImpl.fromJson; - - FailedState get state; - Object? get reason; - - /// Create a copy of MessageState - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - _$$MessageFailedImplCopyWith<_$MessageFailedImpl> get copyWith => - throw _privateConstructorUsedError; -} - -OutgoingState _$OutgoingStateFromJson(Map json) { - switch (json['runtimeType']) { - case 'sending': - return Sending.fromJson(json); - case 'updating': - return Updating.fromJson(json); - case 'deleting': - return Deleting.fromJson(json); - - default: - throw CheckedFromJsonException(json, 'runtimeType', 'OutgoingState', - 'Invalid union type "${json['runtimeType']}"!'); + String toString() { + return 'OutgoingState.sending()'; } } -/// @nodoc -mixin _$OutgoingState { - @optionalTypeArgs - TResult when({ - required TResult Function() sending, - required TResult Function() updating, - required TResult Function(bool hard) deleting, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function()? sending, - TResult? Function()? updating, - TResult? Function(bool hard)? deleting, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? sending, - TResult Function()? updating, - TResult Function(bool hard)? deleting, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult map({ - required TResult Function(Sending value) sending, - required TResult Function(Updating value) updating, - required TResult Function(Deleting value) deleting, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(Sending value)? sending, - TResult? Function(Updating value)? updating, - TResult? Function(Deleting value)? deleting, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeMap({ - TResult Function(Sending value)? sending, - TResult Function(Updating value)? updating, - TResult Function(Deleting value)? deleting, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - - /// Serializes this OutgoingState to a JSON map. - Map toJson() => throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $OutgoingStateCopyWith<$Res> { - factory $OutgoingStateCopyWith( - OutgoingState value, $Res Function(OutgoingState) then) = - _$OutgoingStateCopyWithImpl<$Res, OutgoingState>; -} - -/// @nodoc -class _$OutgoingStateCopyWithImpl<$Res, $Val extends OutgoingState> - implements $OutgoingStateCopyWith<$Res> { - _$OutgoingStateCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of OutgoingState - /// with the given fields replaced by the non-null parameter values. -} - -/// @nodoc -abstract class _$$SendingImplCopyWith<$Res> { - factory _$$SendingImplCopyWith( - _$SendingImpl value, $Res Function(_$SendingImpl) then) = - __$$SendingImplCopyWithImpl<$Res>; -} - -/// @nodoc -class __$$SendingImplCopyWithImpl<$Res> - extends _$OutgoingStateCopyWithImpl<$Res, _$SendingImpl> - implements _$$SendingImplCopyWith<$Res> { - __$$SendingImplCopyWithImpl( - _$SendingImpl _value, $Res Function(_$SendingImpl) _then) - : super(_value, _then); - - /// Create a copy of OutgoingState - /// with the given fields replaced by the non-null parameter values. -} - /// @nodoc @JsonSerializable() -class _$SendingImpl implements Sending { - const _$SendingImpl({final String? $type}) : $type = $type ?? 'sending'; - - factory _$SendingImpl.fromJson(Map json) => - _$$SendingImplFromJson(json); +class Updating implements OutgoingState { + const Updating({final String? $type}) : $type = $type ?? 'updating'; + factory Updating.fromJson(Map json) => + _$UpdatingFromJson(json); @JsonKey(name: 'runtimeType') final String $type; @override - String toString() { - return 'OutgoingState.sending()'; + Map toJson() { + return _$UpdatingToJson( + this, + ); } @override bool operator ==(Object other) { return identical(this, other) || - (other.runtimeType == runtimeType && other is _$SendingImpl); + (other.runtimeType == runtimeType && other is Updating); } @JsonKey(includeFromJson: false, includeToJson: false) @@ -937,380 +465,88 @@ class _$SendingImpl implements Sending { int get hashCode => runtimeType.hashCode; @override - @optionalTypeArgs - TResult when({ - required TResult Function() sending, - required TResult Function() updating, - required TResult Function(bool hard) deleting, - }) { - return sending(); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function()? sending, - TResult? Function()? updating, - TResult? Function(bool hard)? deleting, - }) { - return sending?.call(); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? sending, - TResult Function()? updating, - TResult Function(bool hard)? deleting, - required TResult orElse(), - }) { - if (sending != null) { - return sending(); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(Sending value) sending, - required TResult Function(Updating value) updating, - required TResult Function(Deleting value) deleting, - }) { - return sending(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(Sending value)? sending, - TResult? Function(Updating value)? updating, - TResult? Function(Deleting value)? deleting, - }) { - return sending?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(Sending value)? sending, - TResult Function(Updating value)? updating, - TResult Function(Deleting value)? deleting, - required TResult orElse(), - }) { - if (sending != null) { - return sending(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$SendingImplToJson( - this, - ); + String toString() { + return 'OutgoingState.updating()'; } } -abstract class Sending implements OutgoingState { - const factory Sending() = _$SendingImpl; - - factory Sending.fromJson(Map json) = _$SendingImpl.fromJson; -} - -/// @nodoc -abstract class _$$UpdatingImplCopyWith<$Res> { - factory _$$UpdatingImplCopyWith( - _$UpdatingImpl value, $Res Function(_$UpdatingImpl) then) = - __$$UpdatingImplCopyWithImpl<$Res>; -} - -/// @nodoc -class __$$UpdatingImplCopyWithImpl<$Res> - extends _$OutgoingStateCopyWithImpl<$Res, _$UpdatingImpl> - implements _$$UpdatingImplCopyWith<$Res> { - __$$UpdatingImplCopyWithImpl( - _$UpdatingImpl _value, $Res Function(_$UpdatingImpl) _then) - : super(_value, _then); - - /// Create a copy of OutgoingState - /// with the given fields replaced by the non-null parameter values. -} - /// @nodoc @JsonSerializable() -class _$UpdatingImpl implements Updating { - const _$UpdatingImpl({final String? $type}) : $type = $type ?? 'updating'; +class Deleting implements OutgoingState { + const Deleting({this.hard = false, final String? $type}) + : $type = $type ?? 'deleting'; + factory Deleting.fromJson(Map json) => + _$DeletingFromJson(json); - factory _$UpdatingImpl.fromJson(Map json) => - _$$UpdatingImplFromJson(json); + @JsonKey() + final bool hard; @JsonKey(name: 'runtimeType') final String $type; + /// Create a copy of OutgoingState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $DeletingCopyWith get copyWith => + _$DeletingCopyWithImpl(this, _$identity); + @override - String toString() { - return 'OutgoingState.updating()'; + Map toJson() { + return _$DeletingToJson( + this, + ); } @override bool operator ==(Object other) { return identical(this, other) || - (other.runtimeType == runtimeType && other is _$UpdatingImpl); + (other.runtimeType == runtimeType && + other is Deleting && + (identical(other.hard, hard) || other.hard == hard)); } @JsonKey(includeFromJson: false, includeToJson: false) @override - int get hashCode => runtimeType.hashCode; - - @override - @optionalTypeArgs - TResult when({ - required TResult Function() sending, - required TResult Function() updating, - required TResult Function(bool hard) deleting, - }) { - return updating(); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function()? sending, - TResult? Function()? updating, - TResult? Function(bool hard)? deleting, - }) { - return updating?.call(); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? sending, - TResult Function()? updating, - TResult Function(bool hard)? deleting, - required TResult orElse(), - }) { - if (updating != null) { - return updating(); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(Sending value) sending, - required TResult Function(Updating value) updating, - required TResult Function(Deleting value) deleting, - }) { - return updating(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(Sending value)? sending, - TResult? Function(Updating value)? updating, - TResult? Function(Deleting value)? deleting, - }) { - return updating?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(Sending value)? sending, - TResult Function(Updating value)? updating, - TResult Function(Deleting value)? deleting, - required TResult orElse(), - }) { - if (updating != null) { - return updating(this); - } - return orElse(); - } + int get hashCode => Object.hash(runtimeType, hard); @override - Map toJson() { - return _$$UpdatingImplToJson( - this, - ); + String toString() { + return 'OutgoingState.deleting(hard: $hard)'; } } -abstract class Updating implements OutgoingState { - const factory Updating() = _$UpdatingImpl; - - factory Updating.fromJson(Map json) = - _$UpdatingImpl.fromJson; -} - /// @nodoc -abstract class _$$DeletingImplCopyWith<$Res> { - factory _$$DeletingImplCopyWith( - _$DeletingImpl value, $Res Function(_$DeletingImpl) then) = - __$$DeletingImplCopyWithImpl<$Res>; +abstract mixin class $DeletingCopyWith<$Res> + implements $OutgoingStateCopyWith<$Res> { + factory $DeletingCopyWith(Deleting value, $Res Function(Deleting) _then) = + _$DeletingCopyWithImpl; @useResult $Res call({bool hard}); } /// @nodoc -class __$$DeletingImplCopyWithImpl<$Res> - extends _$OutgoingStateCopyWithImpl<$Res, _$DeletingImpl> - implements _$$DeletingImplCopyWith<$Res> { - __$$DeletingImplCopyWithImpl( - _$DeletingImpl _value, $Res Function(_$DeletingImpl) _then) - : super(_value, _then); +class _$DeletingCopyWithImpl<$Res> implements $DeletingCopyWith<$Res> { + _$DeletingCopyWithImpl(this._self, this._then); + + final Deleting _self; + final $Res Function(Deleting) _then; /// Create a copy of OutgoingState /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') - @override $Res call({ Object? hard = null, }) { - return _then(_$DeletingImpl( + return _then(Deleting( hard: null == hard - ? _value.hard + ? _self.hard : hard // ignore: cast_nullable_to_non_nullable as bool, )); } } -/// @nodoc -@JsonSerializable() -class _$DeletingImpl implements Deleting { - const _$DeletingImpl({this.hard = false, final String? $type}) - : $type = $type ?? 'deleting'; - - factory _$DeletingImpl.fromJson(Map json) => - _$$DeletingImplFromJson(json); - - @override - @JsonKey() - final bool hard; - - @JsonKey(name: 'runtimeType') - final String $type; - - @override - String toString() { - return 'OutgoingState.deleting(hard: $hard)'; - } - - @override - bool operator ==(Object other) { - return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$DeletingImpl && - (identical(other.hard, hard) || other.hard == hard)); - } - - @JsonKey(includeFromJson: false, includeToJson: false) - @override - int get hashCode => Object.hash(runtimeType, hard); - - /// Create a copy of OutgoingState - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - @override - @pragma('vm:prefer-inline') - _$$DeletingImplCopyWith<_$DeletingImpl> get copyWith => - __$$DeletingImplCopyWithImpl<_$DeletingImpl>(this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function() sending, - required TResult Function() updating, - required TResult Function(bool hard) deleting, - }) { - return deleting(hard); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function()? sending, - TResult? Function()? updating, - TResult? Function(bool hard)? deleting, - }) { - return deleting?.call(hard); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? sending, - TResult Function()? updating, - TResult Function(bool hard)? deleting, - required TResult orElse(), - }) { - if (deleting != null) { - return deleting(hard); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(Sending value) sending, - required TResult Function(Updating value) updating, - required TResult Function(Deleting value) deleting, - }) { - return deleting(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(Sending value)? sending, - TResult? Function(Updating value)? updating, - TResult? Function(Deleting value)? deleting, - }) { - return deleting?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(Sending value)? sending, - TResult Function(Updating value)? updating, - TResult Function(Deleting value)? deleting, - required TResult orElse(), - }) { - if (deleting != null) { - return deleting(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$DeletingImplToJson( - this, - ); - } -} - -abstract class Deleting implements OutgoingState { - const factory Deleting({final bool hard}) = _$DeletingImpl; - - factory Deleting.fromJson(Map json) = - _$DeletingImpl.fromJson; - - bool get hard; - - /// Create a copy of OutgoingState - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - _$$DeletingImplCopyWith<_$DeletingImpl> get copyWith => - throw _privateConstructorUsedError; -} - CompletedState _$CompletedStateFromJson(Map json) { switch (json['runtimeType']) { case 'sent': @@ -1328,114 +564,13 @@ CompletedState _$CompletedStateFromJson(Map json) { /// @nodoc mixin _$CompletedState { - @optionalTypeArgs - TResult when({ - required TResult Function() sent, - required TResult Function() updated, - required TResult Function(bool hard) deleted, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function()? sent, - TResult? Function()? updated, - TResult? Function(bool hard)? deleted, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? sent, - TResult Function()? updated, - TResult Function(bool hard)? deleted, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult map({ - required TResult Function(Sent value) sent, - required TResult Function(Updated value) updated, - required TResult Function(Deleted value) deleted, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(Sent value)? sent, - TResult? Function(Updated value)? updated, - TResult? Function(Deleted value)? deleted, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeMap({ - TResult Function(Sent value)? sent, - TResult Function(Updated value)? updated, - TResult Function(Deleted value)? deleted, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - /// Serializes this CompletedState to a JSON map. - Map toJson() => throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $CompletedStateCopyWith<$Res> { - factory $CompletedStateCopyWith( - CompletedState value, $Res Function(CompletedState) then) = - _$CompletedStateCopyWithImpl<$Res, CompletedState>; -} - -/// @nodoc -class _$CompletedStateCopyWithImpl<$Res, $Val extends CompletedState> - implements $CompletedStateCopyWith<$Res> { - _$CompletedStateCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of CompletedState - /// with the given fields replaced by the non-null parameter values. -} - -/// @nodoc -abstract class _$$SentImplCopyWith<$Res> { - factory _$$SentImplCopyWith( - _$SentImpl value, $Res Function(_$SentImpl) then) = - __$$SentImplCopyWithImpl<$Res>; -} - -/// @nodoc -class __$$SentImplCopyWithImpl<$Res> - extends _$CompletedStateCopyWithImpl<$Res, _$SentImpl> - implements _$$SentImplCopyWith<$Res> { - __$$SentImplCopyWithImpl(_$SentImpl _value, $Res Function(_$SentImpl) _then) - : super(_value, _then); - - /// Create a copy of CompletedState - /// with the given fields replaced by the non-null parameter values. -} - -/// @nodoc -@JsonSerializable() -class _$SentImpl implements Sent { - const _$SentImpl({final String? $type}) : $type = $type ?? 'sent'; - - factory _$SentImpl.fromJson(Map json) => - _$$SentImplFromJson(json); - - @JsonKey(name: 'runtimeType') - final String $type; - - @override - String toString() { - return 'CompletedState.sent()'; - } + Map toJson(); @override bool operator ==(Object other) { return identical(this, other) || - (other.runtimeType == runtimeType && other is _$SentImpl); + (other.runtimeType == runtimeType && other is CompletedState); } @JsonKey(includeFromJson: false, includeToJson: false) @@ -1443,126 +578,36 @@ class _$SentImpl implements Sent { int get hashCode => runtimeType.hashCode; @override - @optionalTypeArgs - TResult when({ - required TResult Function() sent, - required TResult Function() updated, - required TResult Function(bool hard) deleted, - }) { - return sent(); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function()? sent, - TResult? Function()? updated, - TResult? Function(bool hard)? deleted, - }) { - return sent?.call(); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? sent, - TResult Function()? updated, - TResult Function(bool hard)? deleted, - required TResult orElse(), - }) { - if (sent != null) { - return sent(); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(Sent value) sent, - required TResult Function(Updated value) updated, - required TResult Function(Deleted value) deleted, - }) { - return sent(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(Sent value)? sent, - TResult? Function(Updated value)? updated, - TResult? Function(Deleted value)? deleted, - }) { - return sent?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(Sent value)? sent, - TResult Function(Updated value)? updated, - TResult Function(Deleted value)? deleted, - required TResult orElse(), - }) { - if (sent != null) { - return sent(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$SentImplToJson( - this, - ); + String toString() { + return 'CompletedState()'; } } -abstract class Sent implements CompletedState { - const factory Sent() = _$SentImpl; - - factory Sent.fromJson(Map json) = _$SentImpl.fromJson; -} - -/// @nodoc -abstract class _$$UpdatedImplCopyWith<$Res> { - factory _$$UpdatedImplCopyWith( - _$UpdatedImpl value, $Res Function(_$UpdatedImpl) then) = - __$$UpdatedImplCopyWithImpl<$Res>; -} - /// @nodoc -class __$$UpdatedImplCopyWithImpl<$Res> - extends _$CompletedStateCopyWithImpl<$Res, _$UpdatedImpl> - implements _$$UpdatedImplCopyWith<$Res> { - __$$UpdatedImplCopyWithImpl( - _$UpdatedImpl _value, $Res Function(_$UpdatedImpl) _then) - : super(_value, _then); - - /// Create a copy of CompletedState - /// with the given fields replaced by the non-null parameter values. +class $CompletedStateCopyWith<$Res> { + $CompletedStateCopyWith(CompletedState _, $Res Function(CompletedState) __); } /// @nodoc @JsonSerializable() -class _$UpdatedImpl implements Updated { - const _$UpdatedImpl({final String? $type}) : $type = $type ?? 'updated'; - - factory _$UpdatedImpl.fromJson(Map json) => - _$$UpdatedImplFromJson(json); +class Sent implements CompletedState { + const Sent({final String? $type}) : $type = $type ?? 'sent'; + factory Sent.fromJson(Map json) => _$SentFromJson(json); @JsonKey(name: 'runtimeType') final String $type; @override - String toString() { - return 'CompletedState.updated()'; + Map toJson() { + return _$SentToJson( + this, + ); } @override bool operator ==(Object other) { return identical(this, other) || - (other.runtimeType == runtimeType && other is _$UpdatedImpl); + (other.runtimeType == runtimeType && other is Sent); } @JsonKey(includeFromJson: false, includeToJson: false) @@ -1570,146 +615,77 @@ class _$UpdatedImpl implements Updated { int get hashCode => runtimeType.hashCode; @override - @optionalTypeArgs - TResult when({ - required TResult Function() sent, - required TResult Function() updated, - required TResult Function(bool hard) deleted, - }) { - return updated(); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function()? sent, - TResult? Function()? updated, - TResult? Function(bool hard)? deleted, - }) { - return updated?.call(); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? sent, - TResult Function()? updated, - TResult Function(bool hard)? deleted, - required TResult orElse(), - }) { - if (updated != null) { - return updated(); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(Sent value) sent, - required TResult Function(Updated value) updated, - required TResult Function(Deleted value) deleted, - }) { - return updated(this); + String toString() { + return 'CompletedState.sent()'; } +} - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(Sent value)? sent, - TResult? Function(Updated value)? updated, - TResult? Function(Deleted value)? deleted, - }) { - return updated?.call(this); - } +/// @nodoc +@JsonSerializable() +class Updated implements CompletedState { + const Updated({final String? $type}) : $type = $type ?? 'updated'; + factory Updated.fromJson(Map json) => + _$UpdatedFromJson(json); - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(Sent value)? sent, - TResult Function(Updated value)? updated, - TResult Function(Deleted value)? deleted, - required TResult orElse(), - }) { - if (updated != null) { - return updated(this); - } - return orElse(); - } + @JsonKey(name: 'runtimeType') + final String $type; @override Map toJson() { - return _$$UpdatedImplToJson( + return _$UpdatedToJson( this, ); } -} - -abstract class Updated implements CompletedState { - const factory Updated() = _$UpdatedImpl; - - factory Updated.fromJson(Map json) = _$UpdatedImpl.fromJson; -} -/// @nodoc -abstract class _$$DeletedImplCopyWith<$Res> { - factory _$$DeletedImplCopyWith( - _$DeletedImpl value, $Res Function(_$DeletedImpl) then) = - __$$DeletedImplCopyWithImpl<$Res>; - @useResult - $Res call({bool hard}); -} + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is Updated); + } -/// @nodoc -class __$$DeletedImplCopyWithImpl<$Res> - extends _$CompletedStateCopyWithImpl<$Res, _$DeletedImpl> - implements _$$DeletedImplCopyWith<$Res> { - __$$DeletedImplCopyWithImpl( - _$DeletedImpl _value, $Res Function(_$DeletedImpl) _then) - : super(_value, _then); + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => runtimeType.hashCode; - /// Create a copy of CompletedState - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') @override - $Res call({ - Object? hard = null, - }) { - return _then(_$DeletedImpl( - hard: null == hard - ? _value.hard - : hard // ignore: cast_nullable_to_non_nullable - as bool, - )); + String toString() { + return 'CompletedState.updated()'; } } /// @nodoc @JsonSerializable() -class _$DeletedImpl implements Deleted { - const _$DeletedImpl({this.hard = false, final String? $type}) +class Deleted implements CompletedState { + const Deleted({this.hard = false, final String? $type}) : $type = $type ?? 'deleted'; + factory Deleted.fromJson(Map json) => + _$DeletedFromJson(json); - factory _$DeletedImpl.fromJson(Map json) => - _$$DeletedImplFromJson(json); - - @override @JsonKey() final bool hard; @JsonKey(name: 'runtimeType') final String $type; + /// Create a copy of CompletedState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $DeletedCopyWith get copyWith => + _$DeletedCopyWithImpl(this, _$identity); + @override - String toString() { - return 'CompletedState.deleted(hard: $hard)'; + Map toJson() { + return _$DeletedToJson( + this, + ); } @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$DeletedImpl && + other is Deleted && (identical(other.hard, hard) || other.hard == hard)); } @@ -1717,102 +693,41 @@ class _$DeletedImpl implements Deleted { @override int get hashCode => Object.hash(runtimeType, hard); - /// Create a copy of CompletedState - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - @override - @pragma('vm:prefer-inline') - _$$DeletedImplCopyWith<_$DeletedImpl> get copyWith => - __$$DeletedImplCopyWithImpl<_$DeletedImpl>(this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function() sent, - required TResult Function() updated, - required TResult Function(bool hard) deleted, - }) { - return deleted(hard); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function()? sent, - TResult? Function()? updated, - TResult? Function(bool hard)? deleted, - }) { - return deleted?.call(hard); - } - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? sent, - TResult Function()? updated, - TResult Function(bool hard)? deleted, - required TResult orElse(), - }) { - if (deleted != null) { - return deleted(hard); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(Sent value) sent, - required TResult Function(Updated value) updated, - required TResult Function(Deleted value) deleted, - }) { - return deleted(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(Sent value)? sent, - TResult? Function(Updated value)? updated, - TResult? Function(Deleted value)? deleted, - }) { - return deleted?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(Sent value)? sent, - TResult Function(Updated value)? updated, - TResult Function(Deleted value)? deleted, - required TResult orElse(), - }) { - if (deleted != null) { - return deleted(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$DeletedImplToJson( - this, - ); + String toString() { + return 'CompletedState.deleted(hard: $hard)'; } } -abstract class Deleted implements CompletedState { - const factory Deleted({final bool hard}) = _$DeletedImpl; +/// @nodoc +abstract mixin class $DeletedCopyWith<$Res> + implements $CompletedStateCopyWith<$Res> { + factory $DeletedCopyWith(Deleted value, $Res Function(Deleted) _then) = + _$DeletedCopyWithImpl; + @useResult + $Res call({bool hard}); +} - factory Deleted.fromJson(Map json) = _$DeletedImpl.fromJson; +/// @nodoc +class _$DeletedCopyWithImpl<$Res> implements $DeletedCopyWith<$Res> { + _$DeletedCopyWithImpl(this._self, this._then); - bool get hard; + final Deleted _self; + final $Res Function(Deleted) _then; /// Create a copy of CompletedState /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - _$$DeletedImplCopyWith<_$DeletedImpl> get copyWith => - throw _privateConstructorUsedError; + @pragma('vm:prefer-inline') + $Res call({ + Object? hard = null, + }) { + return _then(Deleted( + hard: null == hard + ? _self.hard + : hard // ignore: cast_nullable_to_non_nullable + as bool, + )); + } } FailedState _$FailedStateFromJson(Map json) { @@ -1832,145 +747,66 @@ FailedState _$FailedStateFromJson(Map json) { /// @nodoc mixin _$FailedState { - @optionalTypeArgs - TResult when({ - required TResult Function(bool skipPush, bool skipEnrichUrl) sendingFailed, - required TResult Function(bool skipEnrichUrl) updatingFailed, - required TResult Function(bool hard) deletingFailed, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, - TResult? Function(bool skipEnrichUrl)? updatingFailed, - TResult? Function(bool hard)? deletingFailed, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeWhen({ - TResult Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, - TResult Function(bool skipEnrichUrl)? updatingFailed, - TResult Function(bool hard)? deletingFailed, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult map({ - required TResult Function(SendingFailed value) sendingFailed, - required TResult Function(UpdatingFailed value) updatingFailed, - required TResult Function(DeletingFailed value) deletingFailed, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(SendingFailed value)? sendingFailed, - TResult? Function(UpdatingFailed value)? updatingFailed, - TResult? Function(DeletingFailed value)? deletingFailed, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeMap({ - TResult Function(SendingFailed value)? sendingFailed, - TResult Function(UpdatingFailed value)? updatingFailed, - TResult Function(DeletingFailed value)? deletingFailed, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - /// Serializes this FailedState to a JSON map. - Map toJson() => throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $FailedStateCopyWith<$Res> { - factory $FailedStateCopyWith( - FailedState value, $Res Function(FailedState) then) = - _$FailedStateCopyWithImpl<$Res, FailedState>; -} - -/// @nodoc -class _$FailedStateCopyWithImpl<$Res, $Val extends FailedState> - implements $FailedStateCopyWith<$Res> { - _$FailedStateCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of FailedState - /// with the given fields replaced by the non-null parameter values. -} + Map toJson(); -/// @nodoc -abstract class _$$SendingFailedImplCopyWith<$Res> { - factory _$$SendingFailedImplCopyWith( - _$SendingFailedImpl value, $Res Function(_$SendingFailedImpl) then) = - __$$SendingFailedImplCopyWithImpl<$Res>; - @useResult - $Res call({bool skipPush, bool skipEnrichUrl}); -} + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && other is FailedState); + } -/// @nodoc -class __$$SendingFailedImplCopyWithImpl<$Res> - extends _$FailedStateCopyWithImpl<$Res, _$SendingFailedImpl> - implements _$$SendingFailedImplCopyWith<$Res> { - __$$SendingFailedImplCopyWithImpl( - _$SendingFailedImpl _value, $Res Function(_$SendingFailedImpl) _then) - : super(_value, _then); + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => runtimeType.hashCode; - @pragma('vm:prefer-inline') @override - $Res call({ - Object? skipPush = null, - Object? skipEnrichUrl = null, - }) { - return _then(_$SendingFailedImpl( - skipPush: null == skipPush - ? _value.skipPush - : skipPush // ignore: cast_nullable_to_non_nullable - as bool, - skipEnrichUrl: null == skipEnrichUrl - ? _value.skipEnrichUrl - : skipEnrichUrl // ignore: cast_nullable_to_non_nullable - as bool, - )); + String toString() { + return 'FailedState()'; } +} - /// Create a copy of FailedState - /// with the given fields replaced by the non-null parameter values. +/// @nodoc +class $FailedStateCopyWith<$Res> { + $FailedStateCopyWith(FailedState _, $Res Function(FailedState) __); } /// @nodoc @JsonSerializable() -class _$SendingFailedImpl implements SendingFailed { - const _$SendingFailedImpl( +class SendingFailed implements FailedState { + const SendingFailed( {this.skipPush = false, this.skipEnrichUrl = false, final String? $type}) : $type = $type ?? 'sendingFailed'; + factory SendingFailed.fromJson(Map json) => + _$SendingFailedFromJson(json); - factory _$SendingFailedImpl.fromJson(Map json) => - _$$SendingFailedImplFromJson(json); - - @override @JsonKey() final bool skipPush; - @override @JsonKey() final bool skipEnrichUrl; @JsonKey(name: 'runtimeType') final String $type; + /// Create a copy of FailedState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $SendingFailedCopyWith get copyWith => + _$SendingFailedCopyWithImpl(this, _$identity); + @override - String toString() { - return 'FailedState.sendingFailed(skipPush: $skipPush, skipEnrichUrl: $skipEnrichUrl)'; + Map toJson() { + return _$SendingFailedToJson( + this, + ); } @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$SendingFailedImpl && + other is SendingFailed && (identical(other.skipPush, skipPush) || other.skipPush == skipPush) && (identical(other.skipEnrichUrl, skipEnrichUrl) || @@ -1981,294 +817,135 @@ class _$SendingFailedImpl implements SendingFailed { @override int get hashCode => Object.hash(runtimeType, skipPush, skipEnrichUrl); - @JsonKey(includeFromJson: false, includeToJson: false) - @override - @pragma('vm:prefer-inline') - _$$SendingFailedImplCopyWith<_$SendingFailedImpl> get copyWith => - __$$SendingFailedImplCopyWithImpl<_$SendingFailedImpl>(this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function(bool skipPush, bool skipEnrichUrl) sendingFailed, - required TResult Function(bool skipEnrichUrl) updatingFailed, - required TResult Function(bool hard) deletingFailed, - }) { - return sendingFailed(skipPush, skipEnrichUrl); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, - TResult? Function(bool skipEnrichUrl)? updatingFailed, - TResult? Function(bool hard)? deletingFailed, - }) { - return sendingFailed?.call(skipPush, skipEnrichUrl); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, - TResult Function(bool skipEnrichUrl)? updatingFailed, - TResult Function(bool hard)? deletingFailed, - required TResult orElse(), - }) { - if (sendingFailed != null) { - return sendingFailed(skipPush, skipEnrichUrl); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(SendingFailed value) sendingFailed, - required TResult Function(UpdatingFailed value) updatingFailed, - required TResult Function(DeletingFailed value) deletingFailed, - }) { - return sendingFailed(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(SendingFailed value)? sendingFailed, - TResult? Function(UpdatingFailed value)? updatingFailed, - TResult? Function(DeletingFailed value)? deletingFailed, - }) { - return sendingFailed?.call(this); - } - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(SendingFailed value)? sendingFailed, - TResult Function(UpdatingFailed value)? updatingFailed, - TResult Function(DeletingFailed value)? deletingFailed, - required TResult orElse(), - }) { - if (sendingFailed != null) { - return sendingFailed(this); - } - return orElse(); - } - - @override - Map toJson() { - return _$$SendingFailedImplToJson( - this, - ); + String toString() { + return 'FailedState.sendingFailed(skipPush: $skipPush, skipEnrichUrl: $skipEnrichUrl)'; } } -abstract class SendingFailed implements FailedState { - const factory SendingFailed({final bool skipPush, final bool skipEnrichUrl}) = - _$SendingFailedImpl; - - factory SendingFailed.fromJson(Map json) = - _$SendingFailedImpl.fromJson; - - bool get skipPush; - bool get skipEnrichUrl; - @JsonKey(includeFromJson: false, includeToJson: false) - _$$SendingFailedImplCopyWith<_$SendingFailedImpl> get copyWith => - throw _privateConstructorUsedError; -} - /// @nodoc -abstract class _$$UpdatingFailedImplCopyWith<$Res> { - factory _$$UpdatingFailedImplCopyWith(_$UpdatingFailedImpl value, - $Res Function(_$UpdatingFailedImpl) then) = - __$$UpdatingFailedImplCopyWithImpl<$Res>; +abstract mixin class $SendingFailedCopyWith<$Res> + implements $FailedStateCopyWith<$Res> { + factory $SendingFailedCopyWith( + SendingFailed value, $Res Function(SendingFailed) _then) = + _$SendingFailedCopyWithImpl; @useResult - $Res call({bool skipEnrichUrl}); + $Res call({bool skipPush, bool skipEnrichUrl}); } /// @nodoc -class __$$UpdatingFailedImplCopyWithImpl<$Res> - extends _$FailedStateCopyWithImpl<$Res, _$UpdatingFailedImpl> - implements _$$UpdatingFailedImplCopyWith<$Res> { - __$$UpdatingFailedImplCopyWithImpl( - _$UpdatingFailedImpl _value, $Res Function(_$UpdatingFailedImpl) _then) - : super(_value, _then); +class _$SendingFailedCopyWithImpl<$Res> + implements $SendingFailedCopyWith<$Res> { + _$SendingFailedCopyWithImpl(this._self, this._then); + final SendingFailed _self; + final $Res Function(SendingFailed) _then; + + /// Create a copy of FailedState + /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') - @override $Res call({ + Object? skipPush = null, Object? skipEnrichUrl = null, }) { - return _then(_$UpdatingFailedImpl( + return _then(SendingFailed( + skipPush: null == skipPush + ? _self.skipPush + : skipPush // ignore: cast_nullable_to_non_nullable + as bool, skipEnrichUrl: null == skipEnrichUrl - ? _value.skipEnrichUrl + ? _self.skipEnrichUrl : skipEnrichUrl // ignore: cast_nullable_to_non_nullable as bool, )); } - - /// Create a copy of FailedState - /// with the given fields replaced by the non-null parameter values. } /// @nodoc @JsonSerializable() -class _$UpdatingFailedImpl implements UpdatingFailed { - const _$UpdatingFailedImpl({this.skipEnrichUrl = false, final String? $type}) +class UpdatingFailed implements FailedState { + const UpdatingFailed( + {this.skipPush = false, this.skipEnrichUrl = false, final String? $type}) : $type = $type ?? 'updatingFailed'; + factory UpdatingFailed.fromJson(Map json) => + _$UpdatingFailedFromJson(json); - factory _$UpdatingFailedImpl.fromJson(Map json) => - _$$UpdatingFailedImplFromJson(json); - - @override + @JsonKey() + final bool skipPush; @JsonKey() final bool skipEnrichUrl; @JsonKey(name: 'runtimeType') final String $type; + /// Create a copy of FailedState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $UpdatingFailedCopyWith get copyWith => + _$UpdatingFailedCopyWithImpl(this, _$identity); + @override - String toString() { - return 'FailedState.updatingFailed(skipEnrichUrl: $skipEnrichUrl)'; + Map toJson() { + return _$UpdatingFailedToJson( + this, + ); } @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$UpdatingFailedImpl && + other is UpdatingFailed && + (identical(other.skipPush, skipPush) || + other.skipPush == skipPush) && (identical(other.skipEnrichUrl, skipEnrichUrl) || other.skipEnrichUrl == skipEnrichUrl)); } @JsonKey(includeFromJson: false, includeToJson: false) @override - int get hashCode => Object.hash(runtimeType, skipEnrichUrl); - - @JsonKey(includeFromJson: false, includeToJson: false) - @override - @pragma('vm:prefer-inline') - _$$UpdatingFailedImplCopyWith<_$UpdatingFailedImpl> get copyWith => - __$$UpdatingFailedImplCopyWithImpl<_$UpdatingFailedImpl>( - this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function(bool skipPush, bool skipEnrichUrl) sendingFailed, - required TResult Function(bool skipEnrichUrl) updatingFailed, - required TResult Function(bool hard) deletingFailed, - }) { - return updatingFailed(skipEnrichUrl); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, - TResult? Function(bool skipEnrichUrl)? updatingFailed, - TResult? Function(bool hard)? deletingFailed, - }) { - return updatingFailed?.call(skipEnrichUrl); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, - TResult Function(bool skipEnrichUrl)? updatingFailed, - TResult Function(bool hard)? deletingFailed, - required TResult orElse(), - }) { - if (updatingFailed != null) { - return updatingFailed(skipEnrichUrl); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(SendingFailed value) sendingFailed, - required TResult Function(UpdatingFailed value) updatingFailed, - required TResult Function(DeletingFailed value) deletingFailed, - }) { - return updatingFailed(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(SendingFailed value)? sendingFailed, - TResult? Function(UpdatingFailed value)? updatingFailed, - TResult? Function(DeletingFailed value)? deletingFailed, - }) { - return updatingFailed?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(SendingFailed value)? sendingFailed, - TResult Function(UpdatingFailed value)? updatingFailed, - TResult Function(DeletingFailed value)? deletingFailed, - required TResult orElse(), - }) { - if (updatingFailed != null) { - return updatingFailed(this); - } - return orElse(); - } + int get hashCode => Object.hash(runtimeType, skipPush, skipEnrichUrl); @override - Map toJson() { - return _$$UpdatingFailedImplToJson( - this, - ); + String toString() { + return 'FailedState.updatingFailed(skipPush: $skipPush, skipEnrichUrl: $skipEnrichUrl)'; } } -abstract class UpdatingFailed implements FailedState { - const factory UpdatingFailed({final bool skipEnrichUrl}) = - _$UpdatingFailedImpl; - - factory UpdatingFailed.fromJson(Map json) = - _$UpdatingFailedImpl.fromJson; - - bool get skipEnrichUrl; - @JsonKey(includeFromJson: false, includeToJson: false) - _$$UpdatingFailedImplCopyWith<_$UpdatingFailedImpl> get copyWith => - throw _privateConstructorUsedError; -} - /// @nodoc -abstract class _$$DeletingFailedImplCopyWith<$Res> { - factory _$$DeletingFailedImplCopyWith(_$DeletingFailedImpl value, - $Res Function(_$DeletingFailedImpl) then) = - __$$DeletingFailedImplCopyWithImpl<$Res>; +abstract mixin class $UpdatingFailedCopyWith<$Res> + implements $FailedStateCopyWith<$Res> { + factory $UpdatingFailedCopyWith( + UpdatingFailed value, $Res Function(UpdatingFailed) _then) = + _$UpdatingFailedCopyWithImpl; @useResult - $Res call({bool hard}); + $Res call({bool skipPush, bool skipEnrichUrl}); } /// @nodoc -class __$$DeletingFailedImplCopyWithImpl<$Res> - extends _$FailedStateCopyWithImpl<$Res, _$DeletingFailedImpl> - implements _$$DeletingFailedImplCopyWith<$Res> { - __$$DeletingFailedImplCopyWithImpl( - _$DeletingFailedImpl _value, $Res Function(_$DeletingFailedImpl) _then) - : super(_value, _then); +class _$UpdatingFailedCopyWithImpl<$Res> + implements $UpdatingFailedCopyWith<$Res> { + _$UpdatingFailedCopyWithImpl(this._self, this._then); + + final UpdatingFailed _self; + final $Res Function(UpdatingFailed) _then; /// Create a copy of FailedState /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') - @override $Res call({ - Object? hard = null, + Object? skipPush = null, + Object? skipEnrichUrl = null, }) { - return _then(_$DeletingFailedImpl( - hard: null == hard - ? _value.hard - : hard // ignore: cast_nullable_to_non_nullable + return _then(UpdatingFailed( + skipPush: null == skipPush + ? _self.skipPush + : skipPush // ignore: cast_nullable_to_non_nullable + as bool, + skipEnrichUrl: null == skipEnrichUrl + ? _self.skipEnrichUrl + : skipEnrichUrl // ignore: cast_nullable_to_non_nullable as bool, )); } @@ -2276,30 +953,37 @@ class __$$DeletingFailedImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$DeletingFailedImpl implements DeletingFailed { - const _$DeletingFailedImpl({this.hard = false, final String? $type}) +class DeletingFailed implements FailedState { + const DeletingFailed({this.hard = false, final String? $type}) : $type = $type ?? 'deletingFailed'; + factory DeletingFailed.fromJson(Map json) => + _$DeletingFailedFromJson(json); - factory _$DeletingFailedImpl.fromJson(Map json) => - _$$DeletingFailedImplFromJson(json); - - @override @JsonKey() final bool hard; @JsonKey(name: 'runtimeType') final String $type; + /// Create a copy of FailedState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $DeletingFailedCopyWith get copyWith => + _$DeletingFailedCopyWithImpl(this, _$identity); + @override - String toString() { - return 'FailedState.deletingFailed(hard: $hard)'; + Map toJson() { + return _$DeletingFailedToJson( + this, + ); } @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$DeletingFailedImpl && + other is DeletingFailed && (identical(other.hard, hard) || other.hard == hard)); } @@ -2307,102 +991,43 @@ class _$DeletingFailedImpl implements DeletingFailed { @override int get hashCode => Object.hash(runtimeType, hard); - /// Create a copy of FailedState - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - @override - @pragma('vm:prefer-inline') - _$$DeletingFailedImplCopyWith<_$DeletingFailedImpl> get copyWith => - __$$DeletingFailedImplCopyWithImpl<_$DeletingFailedImpl>( - this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function(bool skipPush, bool skipEnrichUrl) sendingFailed, - required TResult Function(bool skipEnrichUrl) updatingFailed, - required TResult Function(bool hard) deletingFailed, - }) { - return deletingFailed(hard); - } - - @override - @optionalTypeArgs - TResult? whenOrNull({ - TResult? Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, - TResult? Function(bool skipEnrichUrl)? updatingFailed, - TResult? Function(bool hard)? deletingFailed, - }) { - return deletingFailed?.call(hard); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, - TResult Function(bool skipEnrichUrl)? updatingFailed, - TResult Function(bool hard)? deletingFailed, - required TResult orElse(), - }) { - if (deletingFailed != null) { - return deletingFailed(hard); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(SendingFailed value) sendingFailed, - required TResult Function(UpdatingFailed value) updatingFailed, - required TResult Function(DeletingFailed value) deletingFailed, - }) { - return deletingFailed(this); - } - - @override - @optionalTypeArgs - TResult? mapOrNull({ - TResult? Function(SendingFailed value)? sendingFailed, - TResult? Function(UpdatingFailed value)? updatingFailed, - TResult? Function(DeletingFailed value)? deletingFailed, - }) { - return deletingFailed?.call(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(SendingFailed value)? sendingFailed, - TResult Function(UpdatingFailed value)? updatingFailed, - TResult Function(DeletingFailed value)? deletingFailed, - required TResult orElse(), - }) { - if (deletingFailed != null) { - return deletingFailed(this); - } - return orElse(); - } - @override - Map toJson() { - return _$$DeletingFailedImplToJson( - this, - ); + String toString() { + return 'FailedState.deletingFailed(hard: $hard)'; } } -abstract class DeletingFailed implements FailedState { - const factory DeletingFailed({final bool hard}) = _$DeletingFailedImpl; +/// @nodoc +abstract mixin class $DeletingFailedCopyWith<$Res> + implements $FailedStateCopyWith<$Res> { + factory $DeletingFailedCopyWith( + DeletingFailed value, $Res Function(DeletingFailed) _then) = + _$DeletingFailedCopyWithImpl; + @useResult + $Res call({bool hard}); +} - factory DeletingFailed.fromJson(Map json) = - _$DeletingFailedImpl.fromJson; +/// @nodoc +class _$DeletingFailedCopyWithImpl<$Res> + implements $DeletingFailedCopyWith<$Res> { + _$DeletingFailedCopyWithImpl(this._self, this._then); - bool get hard; + final DeletingFailed _self; + final $Res Function(DeletingFailed) _then; /// Create a copy of FailedState /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - _$$DeletingFailedImplCopyWith<_$DeletingFailedImpl> get copyWith => - throw _privateConstructorUsedError; + @pragma('vm:prefer-inline') + $Res call({ + Object? hard = null, + }) { + return _then(DeletingFailed( + hard: null == hard + ? _self.hard + : hard // ignore: cast_nullable_to_non_nullable + as bool, + )); + } } + +// dart format on diff --git a/packages/stream_chat/lib/src/core/models/message_state.g.dart b/packages/stream_chat/lib/src/core/models/message_state.g.dart index 2e7d43e908..248c29080b 100644 --- a/packages/stream_chat/lib/src/core/models/message_state.g.dart +++ b/packages/stream_chat/lib/src/core/models/message_state.g.dart @@ -6,157 +6,141 @@ part of 'message_state.dart'; // JsonSerializableGenerator // ************************************************************************** -_$MessageInitialImpl _$$MessageInitialImplFromJson(Map json) => - _$MessageInitialImpl( +MessageInitial _$MessageInitialFromJson(Map json) => + MessageInitial( $type: json['runtimeType'] as String?, ); -Map _$$MessageInitialImplToJson( - _$MessageInitialImpl instance) => +Map _$MessageInitialToJson(MessageInitial instance) => { 'runtimeType': instance.$type, }; -_$MessageOutgoingImpl _$$MessageOutgoingImplFromJson( - Map json) => - _$MessageOutgoingImpl( +MessageOutgoing _$MessageOutgoingFromJson(Map json) => + MessageOutgoing( state: OutgoingState.fromJson(json['state'] as Map), $type: json['runtimeType'] as String?, ); -Map _$$MessageOutgoingImplToJson( - _$MessageOutgoingImpl instance) => +Map _$MessageOutgoingToJson(MessageOutgoing instance) => { 'state': instance.state.toJson(), 'runtimeType': instance.$type, }; -_$MessageCompletedImpl _$$MessageCompletedImplFromJson( - Map json) => - _$MessageCompletedImpl( +MessageCompleted _$MessageCompletedFromJson(Map json) => + MessageCompleted( state: CompletedState.fromJson(json['state'] as Map), $type: json['runtimeType'] as String?, ); -Map _$$MessageCompletedImplToJson( - _$MessageCompletedImpl instance) => +Map _$MessageCompletedToJson(MessageCompleted instance) => { 'state': instance.state.toJson(), 'runtimeType': instance.$type, }; -_$MessageFailedImpl _$$MessageFailedImplFromJson(Map json) => - _$MessageFailedImpl( +MessageFailed _$MessageFailedFromJson(Map json) => + MessageFailed( state: FailedState.fromJson(json['state'] as Map), reason: json['reason'], $type: json['runtimeType'] as String?, ); -Map _$$MessageFailedImplToJson(_$MessageFailedImpl instance) => +Map _$MessageFailedToJson(MessageFailed instance) => { 'state': instance.state.toJson(), 'reason': instance.reason, 'runtimeType': instance.$type, }; -_$SendingImpl _$$SendingImplFromJson(Map json) => - _$SendingImpl( +Sending _$SendingFromJson(Map json) => Sending( $type: json['runtimeType'] as String?, ); -Map _$$SendingImplToJson(_$SendingImpl instance) => - { +Map _$SendingToJson(Sending instance) => { 'runtimeType': instance.$type, }; -_$UpdatingImpl _$$UpdatingImplFromJson(Map json) => - _$UpdatingImpl( +Updating _$UpdatingFromJson(Map json) => Updating( $type: json['runtimeType'] as String?, ); -Map _$$UpdatingImplToJson(_$UpdatingImpl instance) => - { +Map _$UpdatingToJson(Updating instance) => { 'runtimeType': instance.$type, }; -_$DeletingImpl _$$DeletingImplFromJson(Map json) => - _$DeletingImpl( +Deleting _$DeletingFromJson(Map json) => Deleting( hard: json['hard'] as bool? ?? false, $type: json['runtimeType'] as String?, ); -Map _$$DeletingImplToJson(_$DeletingImpl instance) => - { +Map _$DeletingToJson(Deleting instance) => { 'hard': instance.hard, 'runtimeType': instance.$type, }; -_$SentImpl _$$SentImplFromJson(Map json) => _$SentImpl( +Sent _$SentFromJson(Map json) => Sent( $type: json['runtimeType'] as String?, ); -Map _$$SentImplToJson(_$SentImpl instance) => - { +Map _$SentToJson(Sent instance) => { 'runtimeType': instance.$type, }; -_$UpdatedImpl _$$UpdatedImplFromJson(Map json) => - _$UpdatedImpl( +Updated _$UpdatedFromJson(Map json) => Updated( $type: json['runtimeType'] as String?, ); -Map _$$UpdatedImplToJson(_$UpdatedImpl instance) => - { +Map _$UpdatedToJson(Updated instance) => { 'runtimeType': instance.$type, }; -_$DeletedImpl _$$DeletedImplFromJson(Map json) => - _$DeletedImpl( +Deleted _$DeletedFromJson(Map json) => Deleted( hard: json['hard'] as bool? ?? false, $type: json['runtimeType'] as String?, ); -Map _$$DeletedImplToJson(_$DeletedImpl instance) => - { +Map _$DeletedToJson(Deleted instance) => { 'hard': instance.hard, 'runtimeType': instance.$type, }; -_$SendingFailedImpl _$$SendingFailedImplFromJson(Map json) => - _$SendingFailedImpl( +SendingFailed _$SendingFailedFromJson(Map json) => + SendingFailed( skipPush: json['skip_push'] as bool? ?? false, skipEnrichUrl: json['skip_enrich_url'] as bool? ?? false, $type: json['runtimeType'] as String?, ); -Map _$$SendingFailedImplToJson(_$SendingFailedImpl instance) => +Map _$SendingFailedToJson(SendingFailed instance) => { 'skip_push': instance.skipPush, 'skip_enrich_url': instance.skipEnrichUrl, 'runtimeType': instance.$type, }; -_$UpdatingFailedImpl _$$UpdatingFailedImplFromJson(Map json) => - _$UpdatingFailedImpl( +UpdatingFailed _$UpdatingFailedFromJson(Map json) => + UpdatingFailed( + skipPush: json['skip_push'] as bool? ?? false, skipEnrichUrl: json['skip_enrich_url'] as bool? ?? false, $type: json['runtimeType'] as String?, ); -Map _$$UpdatingFailedImplToJson( - _$UpdatingFailedImpl instance) => +Map _$UpdatingFailedToJson(UpdatingFailed instance) => { + 'skip_push': instance.skipPush, 'skip_enrich_url': instance.skipEnrichUrl, 'runtimeType': instance.$type, }; -_$DeletingFailedImpl _$$DeletingFailedImplFromJson(Map json) => - _$DeletingFailedImpl( +DeletingFailed _$DeletingFailedFromJson(Map json) => + DeletingFailed( hard: json['hard'] as bool? ?? false, $type: json['runtimeType'] as String?, ); -Map _$$DeletingFailedImplToJson( - _$DeletingFailedImpl instance) => +Map _$DeletingFailedToJson(DeletingFailed instance) => { 'hard': instance.hard, 'runtimeType': instance.$type, diff --git a/packages/stream_chat/test/src/client/channel_test.dart b/packages/stream_chat/test/src/client/channel_test.dart index 0b852fc7b5..3c29bc114c 100644 --- a/packages/stream_chat/test/src/client/channel_test.dart +++ b/packages/stream_chat/test/src/client/channel_test.dart @@ -543,7 +543,7 @@ void main() { updatedMessage.state.maybeWhen( failed: (state, _) => state.when( sendingFailed: (_, __) => false, - updatingFailed: (_) => false, + updatingFailed: (_, __) => false, deletingFailed: (_) => false, ), orElse: () => true, @@ -1214,7 +1214,9 @@ void main() { [ isSameMessageAs( message.copyWith( - state: MessageState.updatingFailed(skipEnrichUrl: true), + state: MessageState.updatingFailed( + skipEnrichUrl: true, + ), ), matchMessageState: true, ), From 93af0422aded3674d5ea8206948a90d90b848b8d Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Wed, 30 Jul 2025 11:43:16 +0200 Subject: [PATCH 3/6] feat(llc): add `partialUpdateFailed` state for `MessageState` This commit introduces a new state, `partialUpdateFailed`, to the `MessageState` enum. This state is used when a partial update of a message fails. The `isUpdatingFailed` getter now also considers `partialUpdateFailed` as a failed update state. Tests have been updated to reflect these changes and ensure correct behavior when handling partial update failures, including retries and error handling. --- .../stream_chat/lib/src/client/channel.dart | 25 +++- .../lib/src/client/retry_queue.dart | 9 +- .../lib/src/core/models/message_state.dart | 51 +++++++- .../core/models/message_state.freezed.dart | 123 ++++++++++++++++++ .../lib/src/core/models/message_state.g.dart | 18 +++ .../test/src/client/channel_test.dart | 61 ++++++--- 6 files changed, 256 insertions(+), 31 deletions(-) diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index 653e2e57d0..5a24de155e 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -903,8 +903,9 @@ class Channel { state!._retryQueue.add([ message.copyWith( // Update the message state to failed. - state: MessageState.updatingFailed( - skipPush: false, + state: MessageState.partialUpdateFailed( + set: set, + unset: unset, skipEnrichUrl: skipEnrichUrl, ), ), @@ -912,12 +913,15 @@ class Channel { } else { // Reset the message to original state if the update fails and is not // retriable. - state?.updateMessage(originalMessage.copyWith( - state: MessageState.updatingFailed( - skipPush: false, - skipEnrichUrl: skipEnrichUrl, + state?.updateMessage( + originalMessage.copyWith( + state: MessageState.partialUpdateFailed( + set: set, + unset: unset, + skipEnrichUrl: skipEnrichUrl, + ), ), - )); + ); } } @@ -1023,6 +1027,13 @@ class Channel { skipPush: skipPush, skipEnrichUrl: skipEnrichUrl, ), + partialUpdateFailed: (set, unset, skipEnrichUrl) => + partialUpdateMessage( + message, + set: set, + unset: unset, + skipEnrichUrl: skipEnrichUrl, + ), deletingFailed: (hard) => deleteMessage(message, hard: hard), ), orElse: () => throw StateError('Message state is not failed'), diff --git a/packages/stream_chat/lib/src/client/retry_queue.dart b/packages/stream_chat/lib/src/client/retry_queue.dart index 78120125d4..d54c398dbf 100644 --- a/packages/stream_chat/lib/src/client/retry_queue.dart +++ b/packages/stream_chat/lib/src/client/retry_queue.dart @@ -119,10 +119,11 @@ class RetryQueue { } static DateTime? _getMessageDate(Message message) { - return message.state.maybeWhen( - failed: (state, _) => state.when( - sendingFailed: (_, __) => message.createdAt, - updatingFailed: (_, __) => message.updatedAt, + return message.state.maybeMap( + failed: (it) => it.state.map( + sendingFailed: (_) => message.createdAt, + updatingFailed: (_) => message.updatedAt, + partialUpdateFailed: (_) => message.updatedAt, deletingFailed: (_) => message.deletedAt, ), orElse: () => null, diff --git a/packages/stream_chat/lib/src/core/models/message_state.dart b/packages/stream_chat/lib/src/core/models/message_state.dart index d5134ea4b1..65fcce2b5e 100644 --- a/packages/stream_chat/lib/src/core/models/message_state.dart +++ b/packages/stream_chat/lib/src/core/models/message_state.dart @@ -103,9 +103,11 @@ extension MessageStateX on MessageState { /// Returns true if the message is in failed updating state. bool get isUpdatingFailed { - final messageState = this; - if (messageState is! MessageFailed) return false; - return messageState.state is UpdatingFailed; + return switch (this) { + MessageFailed(state: UpdatingFailed()) => true, + MessageFailed(state: PartialUpdateFailed()) => true, + _ => false, + }; } /// Returns true if the message is in failed deleting state. @@ -197,7 +199,7 @@ sealed class MessageState with _$MessageState { /// Updating failed state when the message fails to be updated. factory MessageState.updatingFailed({ - required bool skipPush, + bool skipPush = false, required bool skipEnrichUrl, }) { return MessageState.failed( @@ -208,6 +210,20 @@ sealed class MessageState with _$MessageState { ); } + factory MessageState.partialUpdateFailed({ + Map? set, + List? unset, + bool skipEnrichUrl = false, + }) { + return MessageState.failed( + state: FailedState.partialUpdateFailed( + set: set, + unset: unset, + skipEnrichUrl: skipEnrichUrl, + ), + ); + } + /// Sending state when the message is being sent. static const sending = MessageState.outgoing( state: OutgoingState.sending(), @@ -312,6 +328,12 @@ sealed class FailedState with _$FailedState { @Default(false) bool skipEnrichUrl, }) = UpdatingFailed; + const factory FailedState.partialUpdateFailed({ + Map? set, + List? unset, + @Default(false) bool skipEnrichUrl, + }) = PartialUpdateFailed; + /// Deleting failed state when the message fails to be deleted. const factory FailedState.deletingFailed({ @Default(false) bool hard, @@ -640,6 +662,9 @@ extension FailedStatePatternMatching on FailedState { TResult when({ required TResult Function(bool skipPush, bool skipEnrichUrl) sendingFailed, required TResult Function(bool skipPush, bool skipEnrichUrl) updatingFailed, + required TResult Function( + Map? set, List? unset, bool skipEnrichUrl) + partialUpdateFailed, required TResult Function(bool hard) deletingFailed, }) { final failedState = this; @@ -648,6 +673,8 @@ extension FailedStatePatternMatching on FailedState { sendingFailed(failedState.skipPush, failedState.skipEnrichUrl), UpdatingFailed() => updatingFailed(failedState.skipPush, failedState.skipEnrichUrl), + PartialUpdateFailed() => partialUpdateFailed( + failedState.set, failedState.unset, failedState.skipEnrichUrl), DeletingFailed() => deletingFailed(failedState.hard), }; } @@ -657,6 +684,9 @@ extension FailedStatePatternMatching on FailedState { TResult? whenOrNull({ TResult? Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, TResult? Function(bool skipPush, bool skipEnrichUrl)? updatingFailed, + required TResult Function( + Map? set, List? unset, bool skipEnrichUrl) + partialUpdateFailed, TResult? Function(bool hard)? deletingFailed, }) { final failedState = this; @@ -665,6 +695,8 @@ extension FailedStatePatternMatching on FailedState { sendingFailed?.call(failedState.skipPush, failedState.skipEnrichUrl), UpdatingFailed() => updatingFailed?.call(failedState.skipPush, failedState.skipEnrichUrl), + PartialUpdateFailed() => partialUpdateFailed( + failedState.set, failedState.unset, failedState.skipEnrichUrl), DeletingFailed() => deletingFailed?.call(failedState.hard), }; } @@ -674,6 +706,9 @@ extension FailedStatePatternMatching on FailedState { TResult maybeWhen({ TResult Function(bool skipPush, bool skipEnrichUrl)? sendingFailed, TResult Function(bool skipPush, bool skipEnrichUrl)? updatingFailed, + required TResult Function( + Map? set, List? unset, bool skipEnrichUrl) + partialUpdateFailed, TResult Function(bool hard)? deletingFailed, required TResult orElse(), }) { @@ -683,6 +718,8 @@ extension FailedStatePatternMatching on FailedState { sendingFailed?.call(failedState.skipPush, failedState.skipEnrichUrl), UpdatingFailed() => updatingFailed?.call(failedState.skipPush, failedState.skipEnrichUrl), + PartialUpdateFailed() => partialUpdateFailed( + failedState.set, failedState.unset, failedState.skipEnrichUrl), DeletingFailed() => deletingFailed?.call(failedState.hard), }; @@ -694,12 +731,14 @@ extension FailedStatePatternMatching on FailedState { TResult map({ required TResult Function(SendingFailed value) sendingFailed, required TResult Function(UpdatingFailed value) updatingFailed, + required TResult Function(PartialUpdateFailed value) partialUpdateFailed, required TResult Function(DeletingFailed value) deletingFailed, }) { final failedState = this; return switch (failedState) { SendingFailed() => sendingFailed(failedState), UpdatingFailed() => updatingFailed(failedState), + PartialUpdateFailed() => partialUpdateFailed(failedState), DeletingFailed() => deletingFailed(failedState), }; } @@ -709,12 +748,14 @@ extension FailedStatePatternMatching on FailedState { TResult? mapOrNull({ TResult? Function(SendingFailed value)? sendingFailed, TResult? Function(UpdatingFailed value)? updatingFailed, + TResult? Function(PartialUpdateFailed value)? partialUpdateFailed, TResult? Function(DeletingFailed value)? deletingFailed, }) { final failedState = this; return switch (failedState) { SendingFailed() => sendingFailed?.call(failedState), UpdatingFailed() => updatingFailed?.call(failedState), + PartialUpdateFailed() => partialUpdateFailed?.call(failedState), DeletingFailed() => deletingFailed?.call(failedState), }; } @@ -724,6 +765,7 @@ extension FailedStatePatternMatching on FailedState { TResult maybeMap({ TResult Function(SendingFailed value)? sendingFailed, TResult Function(UpdatingFailed value)? updatingFailed, + TResult Function(PartialUpdateFailed value)? partialUpdateFailed, TResult Function(DeletingFailed value)? deletingFailed, required TResult orElse(), }) { @@ -731,6 +773,7 @@ extension FailedStatePatternMatching on FailedState { final result = switch (failedState) { SendingFailed() => sendingFailed?.call(failedState), UpdatingFailed() => updatingFailed?.call(failedState), + PartialUpdateFailed() => partialUpdateFailed?.call(failedState), DeletingFailed() => deletingFailed?.call(failedState), }; diff --git a/packages/stream_chat/lib/src/core/models/message_state.freezed.dart b/packages/stream_chat/lib/src/core/models/message_state.freezed.dart index ca5bfc80c4..10cf219793 100644 --- a/packages/stream_chat/lib/src/core/models/message_state.freezed.dart +++ b/packages/stream_chat/lib/src/core/models/message_state.freezed.dart @@ -736,6 +736,8 @@ FailedState _$FailedStateFromJson(Map json) { return SendingFailed.fromJson(json); case 'updatingFailed': return UpdatingFailed.fromJson(json); + case 'partialUpdateFailed': + return PartialUpdateFailed.fromJson(json); case 'deletingFailed': return DeletingFailed.fromJson(json); @@ -951,6 +953,127 @@ class _$UpdatingFailedCopyWithImpl<$Res> } } +/// @nodoc +@JsonSerializable() +class PartialUpdateFailed implements FailedState { + const PartialUpdateFailed( + {final Map? set, + final List? unset, + this.skipEnrichUrl = false, + final String? $type}) + : _set = set, + _unset = unset, + $type = $type ?? 'partialUpdateFailed'; + factory PartialUpdateFailed.fromJson(Map json) => + _$PartialUpdateFailedFromJson(json); + + final Map? _set; + Map? get set { + final value = _set; + if (value == null) return null; + if (_set is EqualUnmodifiableMapView) return _set; + // ignore: implicit_dynamic_type + return EqualUnmodifiableMapView(value); + } + + final List? _unset; + List? get unset { + final value = _unset; + if (value == null) return null; + if (_unset is EqualUnmodifiableListView) return _unset; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(value); + } + + @JsonKey() + final bool skipEnrichUrl; + + @JsonKey(name: 'runtimeType') + final String $type; + + /// Create a copy of FailedState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $PartialUpdateFailedCopyWith get copyWith => + _$PartialUpdateFailedCopyWithImpl(this, _$identity); + + @override + Map toJson() { + return _$PartialUpdateFailedToJson( + this, + ); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is PartialUpdateFailed && + const DeepCollectionEquality().equals(other._set, _set) && + const DeepCollectionEquality().equals(other._unset, _unset) && + (identical(other.skipEnrichUrl, skipEnrichUrl) || + other.skipEnrichUrl == skipEnrichUrl)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + const DeepCollectionEquality().hash(_set), + const DeepCollectionEquality().hash(_unset), + skipEnrichUrl); + + @override + String toString() { + return 'FailedState.partialUpdateFailed(set: $set, unset: $unset, skipEnrichUrl: $skipEnrichUrl)'; + } +} + +/// @nodoc +abstract mixin class $PartialUpdateFailedCopyWith<$Res> + implements $FailedStateCopyWith<$Res> { + factory $PartialUpdateFailedCopyWith( + PartialUpdateFailed value, $Res Function(PartialUpdateFailed) _then) = + _$PartialUpdateFailedCopyWithImpl; + @useResult + $Res call( + {Map? set, List? unset, bool skipEnrichUrl}); +} + +/// @nodoc +class _$PartialUpdateFailedCopyWithImpl<$Res> + implements $PartialUpdateFailedCopyWith<$Res> { + _$PartialUpdateFailedCopyWithImpl(this._self, this._then); + + final PartialUpdateFailed _self; + final $Res Function(PartialUpdateFailed) _then; + + /// Create a copy of FailedState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + $Res call({ + Object? set = freezed, + Object? unset = freezed, + Object? skipEnrichUrl = null, + }) { + return _then(PartialUpdateFailed( + set: freezed == set + ? _self._set + : set // ignore: cast_nullable_to_non_nullable + as Map?, + unset: freezed == unset + ? _self._unset + : unset // ignore: cast_nullable_to_non_nullable + as List?, + skipEnrichUrl: null == skipEnrichUrl + ? _self.skipEnrichUrl + : skipEnrichUrl // ignore: cast_nullable_to_non_nullable + as bool, + )); + } +} + /// @nodoc @JsonSerializable() class DeletingFailed implements FailedState { diff --git a/packages/stream_chat/lib/src/core/models/message_state.g.dart b/packages/stream_chat/lib/src/core/models/message_state.g.dart index 248c29080b..b88025b7b7 100644 --- a/packages/stream_chat/lib/src/core/models/message_state.g.dart +++ b/packages/stream_chat/lib/src/core/models/message_state.g.dart @@ -134,6 +134,24 @@ Map _$UpdatingFailedToJson(UpdatingFailed instance) => 'runtimeType': instance.$type, }; +PartialUpdateFailed _$PartialUpdateFailedFromJson(Map json) => + PartialUpdateFailed( + set: json['set'] as Map?, + unset: + (json['unset'] as List?)?.map((e) => e as String).toList(), + skipEnrichUrl: json['skip_enrich_url'] as bool? ?? false, + $type: json['runtimeType'] as String?, + ); + +Map _$PartialUpdateFailedToJson( + PartialUpdateFailed instance) => + { + 'set': instance.set, + 'unset': instance.unset, + 'skip_enrich_url': instance.skipEnrichUrl, + 'runtimeType': instance.$type, + }; + DeletingFailed _$DeletingFailedFromJson(Map json) => DeletingFailed( hard: json['hard'] as bool? ?? false, diff --git a/packages/stream_chat/test/src/client/channel_test.dart b/packages/stream_chat/test/src/client/channel_test.dart index 3c29bc114c..66ef95a132 100644 --- a/packages/stream_chat/test/src/client/channel_test.dart +++ b/packages/stream_chat/test/src/client/channel_test.dart @@ -541,9 +541,10 @@ void main() { expect(updatedMessage.state, isA()); expect( updatedMessage.state.maybeWhen( - failed: (state, _) => state.when( - sendingFailed: (_, __) => false, - updatingFailed: (_, __) => false, + failed: (state, _) => state.map( + sendingFailed: (_) => false, + updatingFailed: (_) => false, + partialUpdateFailed: (_) => false, deletingFailed: (_) => false, ), orElse: () => true, @@ -1185,7 +1186,7 @@ void main() { }); test( - 'should add message to retry queue when retriable StreamChatNetworkError occurs with skipEnrichUrl: true', + 'should add message to retry queue when retriable StreamChatNetworkError occurs with skipPush: false, skipEnrichUrl: true', () async { final message = Message( id: 'test-message-id-retry-1', @@ -1236,7 +1237,7 @@ void main() { }); test( - 'should add message to retry queue when retriable StreamChatNetworkError occurs with skipEnrichUrl: false', + 'should add message to retry queue when retriable StreamChatNetworkError occurs with skipPush: true, skipEnrichUrl: false', () async { final message = Message( id: 'test-message-id-retry-2', @@ -1246,6 +1247,7 @@ void main() { // Create a retriable error (data == null) when(() => client.updateMessage( any(that: isSameMessageAs(message)), + skipPush: true, )).thenThrow(StreamChatNetworkError.raw( code: ChatErrorCode.internalSystemError.code, message: 'Internal system error', @@ -1264,7 +1266,10 @@ void main() { [ isSameMessageAs( message.copyWith( - state: MessageState.updatingFailed(skipEnrichUrl: false), + state: MessageState.updatingFailed( + skipPush: true, + skipEnrichUrl: false, + ), ), matchMessageState: true, ), @@ -1273,7 +1278,7 @@ void main() { ); try { - await channel.updateMessage(message); + await channel.updateMessage(message, skipPush: true); } catch (e) { expect(e, isA()); @@ -1285,7 +1290,7 @@ void main() { }); test( - 'should handle non-retriable StreamChatNetworkError with skipEnrichUrl: true', + 'should handle non-retriable StreamChatNetworkError with skipPush: true, skipEnrichUrl: true', () async { final message = Message( id: 'test-message-id-error-2', @@ -1294,6 +1299,7 @@ void main() { when(() => client.updateMessage( any(that: isSameMessageAs(message)), + skipPush: true, skipEnrichUrl: true, )).thenThrow(StreamChatNetworkError(ChatErrorCode.notAllowed)); @@ -1310,7 +1316,10 @@ void main() { [ isSameMessageAs( message.copyWith( - state: MessageState.updatingFailed(skipEnrichUrl: true), + state: MessageState.updatingFailed( + skipPush: true, + skipEnrichUrl: true, + ), ), matchMessageState: true, ), @@ -1319,7 +1328,11 @@ void main() { ); try { - await channel.updateMessage(message, skipEnrichUrl: true); + await channel.updateMessage( + message, + skipPush: true, + skipEnrichUrl: true, + ); } catch (e) { expect(e, isA()); @@ -1329,7 +1342,7 @@ void main() { }); test( - 'should handle non-retriable StreamChatNetworkError with skipEnrichUrl: false', + 'should handle non-retriable StreamChatNetworkError with skipPush: false, skipEnrichUrl: false', () async { final message = Message( id: 'test-message-id-error-3', @@ -1353,7 +1366,9 @@ void main() { [ isSameMessageAs( message.copyWith( - state: MessageState.updatingFailed(skipEnrichUrl: false), + state: MessageState.updatingFailed( + skipEnrichUrl: false, + ), ), matchMessageState: true, ), @@ -1523,7 +1538,11 @@ void main() { [ isSameMessageAs( message.copyWith( - state: MessageState.updatingFailed(skipEnrichUrl: true), + state: MessageState.partialUpdateFailed( + set: set, + unset: unset, + skipEnrichUrl: true, + ), ), matchText: true, matchMessageState: true, @@ -1590,7 +1609,10 @@ void main() { [ isSameMessageAs( message.copyWith( - state: MessageState.updatingFailed(skipEnrichUrl: false), + state: MessageState.partialUpdateFailed( + set: set, + unset: unset, + ), ), matchText: true, matchMessageState: true, @@ -1654,7 +1676,11 @@ void main() { [ isSameMessageAs( message.copyWith( - state: MessageState.updatingFailed(skipEnrichUrl: true), + state: MessageState.partialUpdateFailed( + set: set, + unset: unset, + skipEnrichUrl: true, + ), ), matchText: true, matchMessageState: true, @@ -1716,7 +1742,10 @@ void main() { [ isSameMessageAs( message.copyWith( - state: MessageState.updatingFailed(skipEnrichUrl: false), + state: MessageState.partialUpdateFailed( + set: set, + unset: unset, + ), ), matchText: true, matchMessageState: true, From 7f9cde0ecded84ac2351a532336ffacdf8e9e84c Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Wed, 30 Jul 2025 12:08:20 +0200 Subject: [PATCH 4/6] chore: merge fixes --- .../core/models/message_state.freezed.dart | 252 +++++++++++++++++- .../lib/src/core/models/message_state.g.dart | 26 ++ 2 files changed, 270 insertions(+), 8 deletions(-) diff --git a/packages/stream_chat/lib/src/core/models/message_state.freezed.dart b/packages/stream_chat/lib/src/core/models/message_state.freezed.dart index 079d8b3696..10cf219793 100644 --- a/packages/stream_chat/lib/src/core/models/message_state.freezed.dart +++ b/packages/stream_chat/lib/src/core/models/message_state.freezed.dart @@ -736,6 +736,8 @@ FailedState _$FailedStateFromJson(Map json) { return SendingFailed.fromJson(json); case 'updatingFailed': return UpdatingFailed.fromJson(json); + case 'partialUpdateFailed': + return PartialUpdateFailed.fromJson(json); case 'deletingFailed': return DeletingFailed.fromJson(json); @@ -774,13 +776,27 @@ class $FailedStateCopyWith<$Res> { /// @nodoc @JsonSerializable() class SendingFailed implements FailedState { - const SendingFailed({final String? $type}) : $type = $type ?? 'sendingFailed'; + const SendingFailed( + {this.skipPush = false, this.skipEnrichUrl = false, final String? $type}) + : $type = $type ?? 'sendingFailed'; factory SendingFailed.fromJson(Map json) => _$SendingFailedFromJson(json); + @JsonKey() + final bool skipPush; + @JsonKey() + final bool skipEnrichUrl; + @JsonKey(name: 'runtimeType') final String $type; + /// Create a copy of FailedState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $SendingFailedCopyWith get copyWith => + _$SendingFailedCopyWithImpl(this, _$identity); + @override Map toJson() { return _$SendingFailedToJson( @@ -791,30 +807,86 @@ class SendingFailed implements FailedState { @override bool operator ==(Object other) { return identical(this, other) || - (other.runtimeType == runtimeType && other is SendingFailed); + (other.runtimeType == runtimeType && + other is SendingFailed && + (identical(other.skipPush, skipPush) || + other.skipPush == skipPush) && + (identical(other.skipEnrichUrl, skipEnrichUrl) || + other.skipEnrichUrl == skipEnrichUrl)); } @JsonKey(includeFromJson: false, includeToJson: false) @override - int get hashCode => runtimeType.hashCode; + int get hashCode => Object.hash(runtimeType, skipPush, skipEnrichUrl); @override String toString() { - return 'FailedState.sendingFailed()'; + return 'FailedState.sendingFailed(skipPush: $skipPush, skipEnrichUrl: $skipEnrichUrl)'; + } +} + +/// @nodoc +abstract mixin class $SendingFailedCopyWith<$Res> + implements $FailedStateCopyWith<$Res> { + factory $SendingFailedCopyWith( + SendingFailed value, $Res Function(SendingFailed) _then) = + _$SendingFailedCopyWithImpl; + @useResult + $Res call({bool skipPush, bool skipEnrichUrl}); +} + +/// @nodoc +class _$SendingFailedCopyWithImpl<$Res> + implements $SendingFailedCopyWith<$Res> { + _$SendingFailedCopyWithImpl(this._self, this._then); + + final SendingFailed _self; + final $Res Function(SendingFailed) _then; + + /// Create a copy of FailedState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + $Res call({ + Object? skipPush = null, + Object? skipEnrichUrl = null, + }) { + return _then(SendingFailed( + skipPush: null == skipPush + ? _self.skipPush + : skipPush // ignore: cast_nullable_to_non_nullable + as bool, + skipEnrichUrl: null == skipEnrichUrl + ? _self.skipEnrichUrl + : skipEnrichUrl // ignore: cast_nullable_to_non_nullable + as bool, + )); } } /// @nodoc @JsonSerializable() class UpdatingFailed implements FailedState { - const UpdatingFailed({final String? $type}) + const UpdatingFailed( + {this.skipPush = false, this.skipEnrichUrl = false, final String? $type}) : $type = $type ?? 'updatingFailed'; factory UpdatingFailed.fromJson(Map json) => _$UpdatingFailedFromJson(json); + @JsonKey() + final bool skipPush; + @JsonKey() + final bool skipEnrichUrl; + @JsonKey(name: 'runtimeType') final String $type; + /// Create a copy of FailedState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $UpdatingFailedCopyWith get copyWith => + _$UpdatingFailedCopyWithImpl(this, _$identity); + @override Map toJson() { return _$UpdatingFailedToJson( @@ -825,16 +897,180 @@ class UpdatingFailed implements FailedState { @override bool operator ==(Object other) { return identical(this, other) || - (other.runtimeType == runtimeType && other is UpdatingFailed); + (other.runtimeType == runtimeType && + other is UpdatingFailed && + (identical(other.skipPush, skipPush) || + other.skipPush == skipPush) && + (identical(other.skipEnrichUrl, skipEnrichUrl) || + other.skipEnrichUrl == skipEnrichUrl)); } @JsonKey(includeFromJson: false, includeToJson: false) @override - int get hashCode => runtimeType.hashCode; + int get hashCode => Object.hash(runtimeType, skipPush, skipEnrichUrl); @override String toString() { - return 'FailedState.updatingFailed()'; + return 'FailedState.updatingFailed(skipPush: $skipPush, skipEnrichUrl: $skipEnrichUrl)'; + } +} + +/// @nodoc +abstract mixin class $UpdatingFailedCopyWith<$Res> + implements $FailedStateCopyWith<$Res> { + factory $UpdatingFailedCopyWith( + UpdatingFailed value, $Res Function(UpdatingFailed) _then) = + _$UpdatingFailedCopyWithImpl; + @useResult + $Res call({bool skipPush, bool skipEnrichUrl}); +} + +/// @nodoc +class _$UpdatingFailedCopyWithImpl<$Res> + implements $UpdatingFailedCopyWith<$Res> { + _$UpdatingFailedCopyWithImpl(this._self, this._then); + + final UpdatingFailed _self; + final $Res Function(UpdatingFailed) _then; + + /// Create a copy of FailedState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + $Res call({ + Object? skipPush = null, + Object? skipEnrichUrl = null, + }) { + return _then(UpdatingFailed( + skipPush: null == skipPush + ? _self.skipPush + : skipPush // ignore: cast_nullable_to_non_nullable + as bool, + skipEnrichUrl: null == skipEnrichUrl + ? _self.skipEnrichUrl + : skipEnrichUrl // ignore: cast_nullable_to_non_nullable + as bool, + )); + } +} + +/// @nodoc +@JsonSerializable() +class PartialUpdateFailed implements FailedState { + const PartialUpdateFailed( + {final Map? set, + final List? unset, + this.skipEnrichUrl = false, + final String? $type}) + : _set = set, + _unset = unset, + $type = $type ?? 'partialUpdateFailed'; + factory PartialUpdateFailed.fromJson(Map json) => + _$PartialUpdateFailedFromJson(json); + + final Map? _set; + Map? get set { + final value = _set; + if (value == null) return null; + if (_set is EqualUnmodifiableMapView) return _set; + // ignore: implicit_dynamic_type + return EqualUnmodifiableMapView(value); + } + + final List? _unset; + List? get unset { + final value = _unset; + if (value == null) return null; + if (_unset is EqualUnmodifiableListView) return _unset; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(value); + } + + @JsonKey() + final bool skipEnrichUrl; + + @JsonKey(name: 'runtimeType') + final String $type; + + /// Create a copy of FailedState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $PartialUpdateFailedCopyWith get copyWith => + _$PartialUpdateFailedCopyWithImpl(this, _$identity); + + @override + Map toJson() { + return _$PartialUpdateFailedToJson( + this, + ); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is PartialUpdateFailed && + const DeepCollectionEquality().equals(other._set, _set) && + const DeepCollectionEquality().equals(other._unset, _unset) && + (identical(other.skipEnrichUrl, skipEnrichUrl) || + other.skipEnrichUrl == skipEnrichUrl)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + const DeepCollectionEquality().hash(_set), + const DeepCollectionEquality().hash(_unset), + skipEnrichUrl); + + @override + String toString() { + return 'FailedState.partialUpdateFailed(set: $set, unset: $unset, skipEnrichUrl: $skipEnrichUrl)'; + } +} + +/// @nodoc +abstract mixin class $PartialUpdateFailedCopyWith<$Res> + implements $FailedStateCopyWith<$Res> { + factory $PartialUpdateFailedCopyWith( + PartialUpdateFailed value, $Res Function(PartialUpdateFailed) _then) = + _$PartialUpdateFailedCopyWithImpl; + @useResult + $Res call( + {Map? set, List? unset, bool skipEnrichUrl}); +} + +/// @nodoc +class _$PartialUpdateFailedCopyWithImpl<$Res> + implements $PartialUpdateFailedCopyWith<$Res> { + _$PartialUpdateFailedCopyWithImpl(this._self, this._then); + + final PartialUpdateFailed _self; + final $Res Function(PartialUpdateFailed) _then; + + /// Create a copy of FailedState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + $Res call({ + Object? set = freezed, + Object? unset = freezed, + Object? skipEnrichUrl = null, + }) { + return _then(PartialUpdateFailed( + set: freezed == set + ? _self._set + : set // ignore: cast_nullable_to_non_nullable + as Map?, + unset: freezed == unset + ? _self._unset + : unset // ignore: cast_nullable_to_non_nullable + as List?, + skipEnrichUrl: null == skipEnrichUrl + ? _self.skipEnrichUrl + : skipEnrichUrl // ignore: cast_nullable_to_non_nullable + as bool, + )); } } diff --git a/packages/stream_chat/lib/src/core/models/message_state.g.dart b/packages/stream_chat/lib/src/core/models/message_state.g.dart index e39b40667b..b88025b7b7 100644 --- a/packages/stream_chat/lib/src/core/models/message_state.g.dart +++ b/packages/stream_chat/lib/src/core/models/message_state.g.dart @@ -108,21 +108,47 @@ Map _$DeletedToJson(Deleted instance) => { SendingFailed _$SendingFailedFromJson(Map json) => SendingFailed( + skipPush: json['skip_push'] as bool? ?? false, + skipEnrichUrl: json['skip_enrich_url'] as bool? ?? false, $type: json['runtimeType'] as String?, ); Map _$SendingFailedToJson(SendingFailed instance) => { + 'skip_push': instance.skipPush, + 'skip_enrich_url': instance.skipEnrichUrl, 'runtimeType': instance.$type, }; UpdatingFailed _$UpdatingFailedFromJson(Map json) => UpdatingFailed( + skipPush: json['skip_push'] as bool? ?? false, + skipEnrichUrl: json['skip_enrich_url'] as bool? ?? false, $type: json['runtimeType'] as String?, ); Map _$UpdatingFailedToJson(UpdatingFailed instance) => { + 'skip_push': instance.skipPush, + 'skip_enrich_url': instance.skipEnrichUrl, + 'runtimeType': instance.$type, + }; + +PartialUpdateFailed _$PartialUpdateFailedFromJson(Map json) => + PartialUpdateFailed( + set: json['set'] as Map?, + unset: + (json['unset'] as List?)?.map((e) => e as String).toList(), + skipEnrichUrl: json['skip_enrich_url'] as bool? ?? false, + $type: json['runtimeType'] as String?, + ); + +Map _$PartialUpdateFailedToJson( + PartialUpdateFailed instance) => + { + 'set': instance.set, + 'unset': instance.unset, + 'skip_enrich_url': instance.skipEnrichUrl, 'runtimeType': instance.$type, }; From 6c970908da54be270d3e889c8bd2267850d4f771 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Wed, 30 Jul 2025 12:21:03 +0200 Subject: [PATCH 5/6] refactor(core): rename `partialUpdateFailed` to `partialUpdatingFailed` This commit renames `partialUpdateFailed` and `PartialUpdateFailed` to `partialUpdatingFailed` and `PartialUpdatingFailed` respectively across the codebase. The `skipPush` parameter has also been added as a required parameter to `MessageState.updatingFailed` and its corresponding tests. --- .../stream_chat/lib/src/client/channel.dart | 6 +-- .../lib/src/client/retry_queue.dart | 2 +- .../lib/src/core/models/message_state.dart | 39 ++++++++-------- .../core/models/message_state.freezed.dart | 45 ++++++++++--------- .../lib/src/core/models/message_state.g.dart | 9 ++-- .../test/src/client/channel_test.dart | 29 ++++++++---- .../src/core/models/message_state_test.dart | 19 +++++++- 7 files changed, 90 insertions(+), 59 deletions(-) diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index 5a24de155e..945295164e 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -903,7 +903,7 @@ class Channel { state!._retryQueue.add([ message.copyWith( // Update the message state to failed. - state: MessageState.partialUpdateFailed( + state: MessageState.partialUpdatingFailed( set: set, unset: unset, skipEnrichUrl: skipEnrichUrl, @@ -915,7 +915,7 @@ class Channel { // retriable. state?.updateMessage( originalMessage.copyWith( - state: MessageState.partialUpdateFailed( + state: MessageState.partialUpdatingFailed( set: set, unset: unset, skipEnrichUrl: skipEnrichUrl, @@ -1027,7 +1027,7 @@ class Channel { skipPush: skipPush, skipEnrichUrl: skipEnrichUrl, ), - partialUpdateFailed: (set, unset, skipEnrichUrl) => + partialUpdatingFailed: (set, unset, skipEnrichUrl) => partialUpdateMessage( message, set: set, diff --git a/packages/stream_chat/lib/src/client/retry_queue.dart b/packages/stream_chat/lib/src/client/retry_queue.dart index d54c398dbf..c1f8841406 100644 --- a/packages/stream_chat/lib/src/client/retry_queue.dart +++ b/packages/stream_chat/lib/src/client/retry_queue.dart @@ -123,7 +123,7 @@ class RetryQueue { failed: (it) => it.state.map( sendingFailed: (_) => message.createdAt, updatingFailed: (_) => message.updatedAt, - partialUpdateFailed: (_) => message.updatedAt, + partialUpdatingFailed: (_) => message.updatedAt, deletingFailed: (_) => message.deletedAt, ), orElse: () => null, diff --git a/packages/stream_chat/lib/src/core/models/message_state.dart b/packages/stream_chat/lib/src/core/models/message_state.dart index 65fcce2b5e..cf98096843 100644 --- a/packages/stream_chat/lib/src/core/models/message_state.dart +++ b/packages/stream_chat/lib/src/core/models/message_state.dart @@ -105,7 +105,7 @@ extension MessageStateX on MessageState { bool get isUpdatingFailed { return switch (this) { MessageFailed(state: UpdatingFailed()) => true, - MessageFailed(state: PartialUpdateFailed()) => true, + MessageFailed(state: PartialUpdatingFailed()) => true, _ => false, }; } @@ -199,7 +199,7 @@ sealed class MessageState with _$MessageState { /// Updating failed state when the message fails to be updated. factory MessageState.updatingFailed({ - bool skipPush = false, + required bool skipPush, required bool skipEnrichUrl, }) { return MessageState.failed( @@ -210,13 +210,13 @@ sealed class MessageState with _$MessageState { ); } - factory MessageState.partialUpdateFailed({ + factory MessageState.partialUpdatingFailed({ Map? set, List? unset, - bool skipEnrichUrl = false, + required bool skipEnrichUrl, }) { return MessageState.failed( - state: FailedState.partialUpdateFailed( + state: FailedState.partialUpdatingFailed( set: set, unset: unset, skipEnrichUrl: skipEnrichUrl, @@ -328,11 +328,11 @@ sealed class FailedState with _$FailedState { @Default(false) bool skipEnrichUrl, }) = UpdatingFailed; - const factory FailedState.partialUpdateFailed({ + const factory FailedState.partialUpdatingFailed({ Map? set, List? unset, @Default(false) bool skipEnrichUrl, - }) = PartialUpdateFailed; + }) = PartialUpdatingFailed; /// Deleting failed state when the message fails to be deleted. const factory FailedState.deletingFailed({ @@ -664,7 +664,7 @@ extension FailedStatePatternMatching on FailedState { required TResult Function(bool skipPush, bool skipEnrichUrl) updatingFailed, required TResult Function( Map? set, List? unset, bool skipEnrichUrl) - partialUpdateFailed, + partialUpdatingFailed, required TResult Function(bool hard) deletingFailed, }) { final failedState = this; @@ -673,7 +673,7 @@ extension FailedStatePatternMatching on FailedState { sendingFailed(failedState.skipPush, failedState.skipEnrichUrl), UpdatingFailed() => updatingFailed(failedState.skipPush, failedState.skipEnrichUrl), - PartialUpdateFailed() => partialUpdateFailed( + PartialUpdatingFailed() => partialUpdatingFailed( failedState.set, failedState.unset, failedState.skipEnrichUrl), DeletingFailed() => deletingFailed(failedState.hard), }; @@ -686,7 +686,7 @@ extension FailedStatePatternMatching on FailedState { TResult? Function(bool skipPush, bool skipEnrichUrl)? updatingFailed, required TResult Function( Map? set, List? unset, bool skipEnrichUrl) - partialUpdateFailed, + partialUpdatingFailed, TResult? Function(bool hard)? deletingFailed, }) { final failedState = this; @@ -695,7 +695,7 @@ extension FailedStatePatternMatching on FailedState { sendingFailed?.call(failedState.skipPush, failedState.skipEnrichUrl), UpdatingFailed() => updatingFailed?.call(failedState.skipPush, failedState.skipEnrichUrl), - PartialUpdateFailed() => partialUpdateFailed( + PartialUpdatingFailed() => partialUpdatingFailed( failedState.set, failedState.unset, failedState.skipEnrichUrl), DeletingFailed() => deletingFailed?.call(failedState.hard), }; @@ -708,7 +708,7 @@ extension FailedStatePatternMatching on FailedState { TResult Function(bool skipPush, bool skipEnrichUrl)? updatingFailed, required TResult Function( Map? set, List? unset, bool skipEnrichUrl) - partialUpdateFailed, + partialUpdatingFailed, TResult Function(bool hard)? deletingFailed, required TResult orElse(), }) { @@ -718,7 +718,7 @@ extension FailedStatePatternMatching on FailedState { sendingFailed?.call(failedState.skipPush, failedState.skipEnrichUrl), UpdatingFailed() => updatingFailed?.call(failedState.skipPush, failedState.skipEnrichUrl), - PartialUpdateFailed() => partialUpdateFailed( + PartialUpdatingFailed() => partialUpdatingFailed( failedState.set, failedState.unset, failedState.skipEnrichUrl), DeletingFailed() => deletingFailed?.call(failedState.hard), }; @@ -731,14 +731,15 @@ extension FailedStatePatternMatching on FailedState { TResult map({ required TResult Function(SendingFailed value) sendingFailed, required TResult Function(UpdatingFailed value) updatingFailed, - required TResult Function(PartialUpdateFailed value) partialUpdateFailed, + required TResult Function(PartialUpdatingFailed value) + partialUpdatingFailed, required TResult Function(DeletingFailed value) deletingFailed, }) { final failedState = this; return switch (failedState) { SendingFailed() => sendingFailed(failedState), UpdatingFailed() => updatingFailed(failedState), - PartialUpdateFailed() => partialUpdateFailed(failedState), + PartialUpdatingFailed() => partialUpdatingFailed(failedState), DeletingFailed() => deletingFailed(failedState), }; } @@ -748,14 +749,14 @@ extension FailedStatePatternMatching on FailedState { TResult? mapOrNull({ TResult? Function(SendingFailed value)? sendingFailed, TResult? Function(UpdatingFailed value)? updatingFailed, - TResult? Function(PartialUpdateFailed value)? partialUpdateFailed, + TResult? Function(PartialUpdatingFailed value)? partialUpdatingFailed, TResult? Function(DeletingFailed value)? deletingFailed, }) { final failedState = this; return switch (failedState) { SendingFailed() => sendingFailed?.call(failedState), UpdatingFailed() => updatingFailed?.call(failedState), - PartialUpdateFailed() => partialUpdateFailed?.call(failedState), + PartialUpdatingFailed() => partialUpdatingFailed?.call(failedState), DeletingFailed() => deletingFailed?.call(failedState), }; } @@ -765,7 +766,7 @@ extension FailedStatePatternMatching on FailedState { TResult maybeMap({ TResult Function(SendingFailed value)? sendingFailed, TResult Function(UpdatingFailed value)? updatingFailed, - TResult Function(PartialUpdateFailed value)? partialUpdateFailed, + TResult Function(PartialUpdatingFailed value)? partialUpdatingFailed, TResult Function(DeletingFailed value)? deletingFailed, required TResult orElse(), }) { @@ -773,7 +774,7 @@ extension FailedStatePatternMatching on FailedState { final result = switch (failedState) { SendingFailed() => sendingFailed?.call(failedState), UpdatingFailed() => updatingFailed?.call(failedState), - PartialUpdateFailed() => partialUpdateFailed?.call(failedState), + PartialUpdatingFailed() => partialUpdatingFailed?.call(failedState), DeletingFailed() => deletingFailed?.call(failedState), }; diff --git a/packages/stream_chat/lib/src/core/models/message_state.freezed.dart b/packages/stream_chat/lib/src/core/models/message_state.freezed.dart index 10cf219793..06cb77449e 100644 --- a/packages/stream_chat/lib/src/core/models/message_state.freezed.dart +++ b/packages/stream_chat/lib/src/core/models/message_state.freezed.dart @@ -736,8 +736,8 @@ FailedState _$FailedStateFromJson(Map json) { return SendingFailed.fromJson(json); case 'updatingFailed': return UpdatingFailed.fromJson(json); - case 'partialUpdateFailed': - return PartialUpdateFailed.fromJson(json); + case 'partialUpdatingFailed': + return PartialUpdatingFailed.fromJson(json); case 'deletingFailed': return DeletingFailed.fromJson(json); @@ -955,17 +955,17 @@ class _$UpdatingFailedCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class PartialUpdateFailed implements FailedState { - const PartialUpdateFailed( +class PartialUpdatingFailed implements FailedState { + const PartialUpdatingFailed( {final Map? set, final List? unset, this.skipEnrichUrl = false, final String? $type}) : _set = set, _unset = unset, - $type = $type ?? 'partialUpdateFailed'; - factory PartialUpdateFailed.fromJson(Map json) => - _$PartialUpdateFailedFromJson(json); + $type = $type ?? 'partialUpdatingFailed'; + factory PartialUpdatingFailed.fromJson(Map json) => + _$PartialUpdatingFailedFromJson(json); final Map? _set; Map? get set { @@ -995,12 +995,13 @@ class PartialUpdateFailed implements FailedState { /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @pragma('vm:prefer-inline') - $PartialUpdateFailedCopyWith get copyWith => - _$PartialUpdateFailedCopyWithImpl(this, _$identity); + $PartialUpdatingFailedCopyWith get copyWith => + _$PartialUpdatingFailedCopyWithImpl( + this, _$identity); @override Map toJson() { - return _$PartialUpdateFailedToJson( + return _$PartialUpdatingFailedToJson( this, ); } @@ -1009,7 +1010,7 @@ class PartialUpdateFailed implements FailedState { bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is PartialUpdateFailed && + other is PartialUpdatingFailed && const DeepCollectionEquality().equals(other._set, _set) && const DeepCollectionEquality().equals(other._unset, _unset) && (identical(other.skipEnrichUrl, skipEnrichUrl) || @@ -1026,28 +1027,28 @@ class PartialUpdateFailed implements FailedState { @override String toString() { - return 'FailedState.partialUpdateFailed(set: $set, unset: $unset, skipEnrichUrl: $skipEnrichUrl)'; + return 'FailedState.partialUpdatingFailed(set: $set, unset: $unset, skipEnrichUrl: $skipEnrichUrl)'; } } /// @nodoc -abstract mixin class $PartialUpdateFailedCopyWith<$Res> +abstract mixin class $PartialUpdatingFailedCopyWith<$Res> implements $FailedStateCopyWith<$Res> { - factory $PartialUpdateFailedCopyWith( - PartialUpdateFailed value, $Res Function(PartialUpdateFailed) _then) = - _$PartialUpdateFailedCopyWithImpl; + factory $PartialUpdatingFailedCopyWith(PartialUpdatingFailed value, + $Res Function(PartialUpdatingFailed) _then) = + _$PartialUpdatingFailedCopyWithImpl; @useResult $Res call( {Map? set, List? unset, bool skipEnrichUrl}); } /// @nodoc -class _$PartialUpdateFailedCopyWithImpl<$Res> - implements $PartialUpdateFailedCopyWith<$Res> { - _$PartialUpdateFailedCopyWithImpl(this._self, this._then); +class _$PartialUpdatingFailedCopyWithImpl<$Res> + implements $PartialUpdatingFailedCopyWith<$Res> { + _$PartialUpdatingFailedCopyWithImpl(this._self, this._then); - final PartialUpdateFailed _self; - final $Res Function(PartialUpdateFailed) _then; + final PartialUpdatingFailed _self; + final $Res Function(PartialUpdatingFailed) _then; /// Create a copy of FailedState /// with the given fields replaced by the non-null parameter values. @@ -1057,7 +1058,7 @@ class _$PartialUpdateFailedCopyWithImpl<$Res> Object? unset = freezed, Object? skipEnrichUrl = null, }) { - return _then(PartialUpdateFailed( + return _then(PartialUpdatingFailed( set: freezed == set ? _self._set : set // ignore: cast_nullable_to_non_nullable diff --git a/packages/stream_chat/lib/src/core/models/message_state.g.dart b/packages/stream_chat/lib/src/core/models/message_state.g.dart index b88025b7b7..3161a4f8c2 100644 --- a/packages/stream_chat/lib/src/core/models/message_state.g.dart +++ b/packages/stream_chat/lib/src/core/models/message_state.g.dart @@ -134,8 +134,9 @@ Map _$UpdatingFailedToJson(UpdatingFailed instance) => 'runtimeType': instance.$type, }; -PartialUpdateFailed _$PartialUpdateFailedFromJson(Map json) => - PartialUpdateFailed( +PartialUpdatingFailed _$PartialUpdatingFailedFromJson( + Map json) => + PartialUpdatingFailed( set: json['set'] as Map?, unset: (json['unset'] as List?)?.map((e) => e as String).toList(), @@ -143,8 +144,8 @@ PartialUpdateFailed _$PartialUpdateFailedFromJson(Map json) => $type: json['runtimeType'] as String?, ); -Map _$PartialUpdateFailedToJson( - PartialUpdateFailed instance) => +Map _$PartialUpdatingFailedToJson( + PartialUpdatingFailed instance) => { 'set': instance.set, 'unset': instance.unset, diff --git a/packages/stream_chat/test/src/client/channel_test.dart b/packages/stream_chat/test/src/client/channel_test.dart index 66ef95a132..127e66e87f 100644 --- a/packages/stream_chat/test/src/client/channel_test.dart +++ b/packages/stream_chat/test/src/client/channel_test.dart @@ -544,7 +544,7 @@ void main() { failed: (state, _) => state.map( sendingFailed: (_) => false, updatingFailed: (_) => false, - partialUpdateFailed: (_) => false, + partialUpdatingFailed: (_) => false, deletingFailed: (_) => false, ), orElse: () => true, @@ -1216,6 +1216,7 @@ void main() { isSameMessageAs( message.copyWith( state: MessageState.updatingFailed( + skipPush: false, skipEnrichUrl: true, ), ), @@ -1367,6 +1368,7 @@ void main() { isSameMessageAs( message.copyWith( state: MessageState.updatingFailed( + skipPush: false, skipEnrichUrl: false, ), ), @@ -1538,7 +1540,7 @@ void main() { [ isSameMessageAs( message.copyWith( - state: MessageState.partialUpdateFailed( + state: MessageState.partialUpdatingFailed( set: set, unset: unset, skipEnrichUrl: true, @@ -1609,9 +1611,10 @@ void main() { [ isSameMessageAs( message.copyWith( - state: MessageState.partialUpdateFailed( + state: MessageState.partialUpdatingFailed( set: set, unset: unset, + skipEnrichUrl: false, ), ), matchText: true, @@ -1676,7 +1679,7 @@ void main() { [ isSameMessageAs( message.copyWith( - state: MessageState.partialUpdateFailed( + state: MessageState.partialUpdatingFailed( set: set, unset: unset, skipEnrichUrl: true, @@ -1742,9 +1745,10 @@ void main() { [ isSameMessageAs( message.copyWith( - state: MessageState.partialUpdateFailed( + state: MessageState.partialUpdatingFailed( set: set, unset: unset, + skipEnrichUrl: false, ), ), matchText: true, @@ -6091,11 +6095,15 @@ void main() { )).called(1); }); - test('should call updateMessage with preserved skipEnrichUrl parameter', + test( + 'should call updateMessage with preserved skipPush, skipEnrichUrl parameter', () async { final message = Message( id: 'test-message-id', - state: MessageState.updatingFailed(skipEnrichUrl: true), + state: MessageState.updatingFailed( + skipPush: true, + skipEnrichUrl: true, + ), ); final updateMessageResponse = UpdateMessageResponse() @@ -6118,11 +6126,14 @@ void main() { }); test( - 'should call updateMessage with preserved false skipEnrichUrl parameter', + 'should call updateMessage with preserved false skipPush, skipEnrichUrl parameter', () async { final message = Message( id: 'test-message-id', - state: MessageState.updatingFailed(skipEnrichUrl: false), + state: MessageState.updatingFailed( + skipPush: false, + skipEnrichUrl: false, + ), ); final updateMessageResponse = UpdateMessageResponse() diff --git a/packages/stream_chat/test/src/core/models/message_state_test.dart b/packages/stream_chat/test/src/core/models/message_state_test.dart index 5ec2305f98..4d5ac13a31 100644 --- a/packages/stream_chat/test/src/core/models/message_state_test.dart +++ b/packages/stream_chat/test/src/core/models/message_state_test.dart @@ -282,12 +282,29 @@ void main() { test( 'MessageState.updatingFailed should create a MessageFailed instance with UpdatingFailed state', () { - final messageState = MessageState.updatingFailed(skipEnrichUrl: false); + final messageState = MessageState.updatingFailed( + skipPush: false, + skipEnrichUrl: false, + ); expect(messageState, isA()); expect((messageState as MessageFailed).state, isA()); }, ); + test( + 'MessageState.partialUpdatingFailed should create a MessageFailed instance with UpdatingFailed state', + () { + final messageState = MessageState.partialUpdatingFailed( + skipEnrichUrl: false, + ); + expect(messageState, isA()); + expect( + (messageState as MessageFailed).state, + isA(), + ); + }, + ); + test( 'MessageState.softDeletingFailed should create a MessageFailed instance with DeletingFailed state and not hard deleting', () { From 12a44cb61828f6cd4d45d9528e54a18d2ab79a89 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Wed, 30 Jul 2025 14:41:08 +0200 Subject: [PATCH 6/6] chore: fix test --- packages/stream_chat/test/src/client/channel_test.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/stream_chat/test/src/client/channel_test.dart b/packages/stream_chat/test/src/client/channel_test.dart index f41e66e663..756f6f956a 100644 --- a/packages/stream_chat/test/src/client/channel_test.dart +++ b/packages/stream_chat/test/src/client/channel_test.dart @@ -6578,6 +6578,7 @@ void main() { when(() => client.updateMessage( any(that: isSameMessageAs(message)), + skipPush: true, skipEnrichUrl: true, )).thenAnswer((_) async => updateMessageResponse); @@ -6588,6 +6589,7 @@ void main() { verify(() => client.updateMessage( any(that: isSameMessageAs(message)), + skipPush: true, skipEnrichUrl: true, )).called(1); });