@@ -665,7 +665,7 @@ class Channel {
665665 _checkInitialized ();
666666
667667 // Clean up stale error messages before sending a new message.
668- state! .cleanUpStaleErrorMessages ();
668+ state? .cleanUpStaleErrorMessages ();
669669
670670 // Cancelling previous completer in case it's called again in the process
671671 // Eg. Updating the message while the previous call is in progress.
@@ -690,7 +690,7 @@ class Channel {
690690 ).toList (),
691691 );
692692
693- state! .updateMessage (message);
693+ state? .updateMessage (message);
694694
695695 try {
696696 if (message.attachments.any ((it) => ! it.uploadState.isSuccess)) {
@@ -724,20 +724,22 @@ class Channel {
724724 state: MessageState .sent,
725725 );
726726
727- state! .updateMessage (sentMessage);
727+ state? .updateMessage (sentMessage);
728728
729729 return response;
730730 } catch (e) {
731+ final failedMessage = message.copyWith (
732+ // Update the message state to failed.
733+ state: MessageState .sendingFailed (
734+ skipPush: skipPush,
735+ skipEnrichUrl: skipEnrichUrl,
736+ ),
737+ );
738+
739+ state? .updateMessage (failedMessage);
740+ // If the error is retriable, add it to the retry queue.
731741 if (e is StreamChatNetworkError && e.isRetriable) {
732- state! ._retryQueue.add ([
733- message.copyWith (
734- // Update the message state to failed.
735- state: MessageState .sendingFailed (
736- skipPush: skipPush,
737- skipEnrichUrl: skipEnrichUrl,
738- ),
739- ),
740- ]);
742+ state? ._retryQueue.add ([failedMessage]);
741743 }
742744
743745 rethrow ;
@@ -756,7 +758,6 @@ class Channel {
756758 bool skipEnrichUrl = false ,
757759 }) async {
758760 _checkInitialized ();
759- final originalMessage = message;
760761
761762 // Cancelling previous completer in case it's called again in the process
762763 // Eg. Updating the message while the previous call is in progress.
@@ -813,28 +814,20 @@ class Channel {
813814
814815 return response;
815816 } catch (e) {
816- if (e is StreamChatNetworkError ) {
817- if (e.isRetriable) {
818- state! ._retryQueue.add ([
819- message.copyWith (
820- // Update the message state to failed.
821- state: MessageState .updatingFailed (
822- skipPush: skipPush,
823- skipEnrichUrl: skipEnrichUrl,
824- ),
825- ),
826- ]);
827- } else {
828- // Reset the message to original state if the update fails and is not
829- // retriable.
830- state? .updateMessage (originalMessage.copyWith (
831- state: MessageState .updatingFailed (
832- skipPush: skipPush,
833- skipEnrichUrl: skipEnrichUrl,
834- ),
835- ));
836- }
817+ final failedMessage = message.copyWith (
818+ // Update the message state to failed.
819+ state: MessageState .updatingFailed (
820+ skipPush: skipPush,
821+ skipEnrichUrl: skipEnrichUrl,
822+ ),
823+ );
824+
825+ state? .updateMessage (failedMessage);
826+ // If the error is retriable, add it to the retry queue.
827+ if (e is StreamChatNetworkError && e.isRetriable) {
828+ state? ._retryQueue.add ([failedMessage]);
837829 }
830+
838831 rethrow ;
839832 }
840833 }
@@ -851,7 +844,6 @@ class Channel {
851844 bool skipEnrichUrl = false ,
852845 }) async {
853846 _checkInitialized ();
854- final originalMessage = message;
855847
856848 // Cancelling previous completer in case it's called again in the process
857849 // Eg. Updating the message while the previous call is in progress.
@@ -889,31 +881,19 @@ class Channel {
889881
890882 return response;
891883 } catch (e) {
892- if (e is StreamChatNetworkError ) {
893- if (e.isRetriable) {
894- state! ._retryQueue.add ([
895- message.copyWith (
896- // Update the message state to failed.
897- state: MessageState .partialUpdatingFailed (
898- set : set ,
899- unset: unset,
900- skipEnrichUrl: skipEnrichUrl,
901- ),
902- ),
903- ]);
904- } else {
905- // Reset the message to original state if the update fails and is not
906- // retriable.
907- state? .updateMessage (
908- originalMessage.copyWith (
909- state: MessageState .partialUpdatingFailed (
910- set : set ,
911- unset: unset,
912- skipEnrichUrl: skipEnrichUrl,
913- ),
914- ),
915- );
916- }
884+ final failedMessage = message.copyWith (
885+ // Update the message state to failed.
886+ state: MessageState .partialUpdatingFailed (
887+ set : set ,
888+ unset: unset,
889+ skipEnrichUrl: skipEnrichUrl,
890+ ),
891+ );
892+
893+ state? .updateMessage (failedMessage);
894+ // If the error is retriable, add it to the retry queue.
895+ if (e is StreamChatNetworkError && e.isRetriable) {
896+ state? ._retryQueue.add ([failedMessage]);
917897 }
918898
919899 rethrow ;
@@ -932,7 +912,7 @@ class Channel {
932912 // Directly deleting the local messages and bounced error messages as they
933913 // are not available on the server.
934914 if (message.remoteCreatedAt == null || message.isBouncedWithError) {
935- state! .deleteMessage (
915+ state? .deleteMessage (
936916 message.copyWith (
937917 type: MessageType .deleted,
938918 localDeletedAt: DateTime .now (),
@@ -987,14 +967,17 @@ class Channel {
987967
988968 return response;
989969 } catch (e) {
970+ final failedMessage = message.copyWith (
971+ // Update the message state to failed.
972+ state: MessageState .deletingFailed (hard: hard),
973+ );
974+
975+ state? .deleteMessage (failedMessage, hardDelete: hard);
976+ // If the error is retriable, add it to the retry queue.
990977 if (e is StreamChatNetworkError && e.isRetriable) {
991- state! ._retryQueue.add ([
992- message.copyWith (
993- // Update the message state to failed.
994- state: MessageState .deletingFailed (hard: hard),
995- ),
996- ]);
978+ state? ._retryQueue.add ([failedMessage]);
997979 }
980+
998981 rethrow ;
999982 }
1000983 }
@@ -1005,6 +988,9 @@ class Channel {
1005988 /// retry action:
1006989 /// - For [MessageState.sendingFailed] , it attempts to send the message.
1007990 /// - For [MessageState.updatingFailed] , it attempts to update the message.
991+ /// - For [MessageState.partialUpdatingFailed] , it attempts to partially
992+ /// update the message with the same 'set' and 'unset' parameters that were
993+ /// used in the original request.
1008994 /// - For [MessageState.deletingFailed] , it attempts to delete the message.
1009995 /// with the same 'hard' parameter that was used in the original request
1010996 /// - For messages with [isBouncedWithError] , it attempts to send the message.
@@ -1026,13 +1012,14 @@ class Channel {
10261012 skipPush: skipPush,
10271013 skipEnrichUrl: skipEnrichUrl,
10281014 ),
1029- partialUpdatingFailed: (set , unset, skipEnrichUrl) =>
1030- partialUpdateMessage (
1031- message,
1032- set : set ,
1033- unset: unset,
1034- skipEnrichUrl: skipEnrichUrl,
1035- ),
1015+ partialUpdatingFailed: (set , unset, skipEnrichUrl) {
1016+ return partialUpdateMessage (
1017+ message,
1018+ set : set ,
1019+ unset: unset,
1020+ skipEnrichUrl: skipEnrichUrl,
1021+ );
1022+ },
10361023 deletingFailed: (hard) => deleteMessage (message, hard: hard),
10371024 ),
10381025 orElse: () {
@@ -2516,8 +2503,10 @@ class ChannelClientState {
25162503
25172504 /// Retry failed message.
25182505 Future <void > retryFailedMessages () async {
2519- final failedMessages = [...messages, ...threads.values.expand ((v) => v)]
2520- .where ((it) => it.state.isFailed);
2506+ final allMessages = [...messages, ...threads.values.flattened];
2507+ final failedMessages = allMessages.where ((it) => it.state.isFailed);
2508+
2509+ if (failedMessages.isEmpty) return ;
25212510 _retryQueue.add (failedMessages);
25222511 }
25232512
0 commit comments