diff --git a/packages/stream_chat/lib/src/api/channel.dart b/packages/stream_chat/lib/src/api/channel.dart index 2f95be78..a10ec32d 100644 --- a/packages/stream_chat/lib/src/api/channel.dart +++ b/packages/stream_chat/lib/src/api/channel.dart @@ -462,7 +462,7 @@ class Channel { if (error is DioError && error.type != DioErrorType.response) { state?.retryQueue?.add([message]); } else if (error is ApiError) { - if(currentMessage != null) { + if (currentMessage != null) { state?.addMessage(currentMessage); } } @@ -470,6 +470,27 @@ class Channel { } } + /// Partially updates the [message] in this channel. + Future partiallyUpdateMessage( + Message message, Map data) async { + try { + final response = await _client.partiallyUpdateMessage(message.id, data); + + final m = response.message.copyWith( + ownReactions: message.ownReactions, + ); + + state?.addMessage(m); + + return response; + } catch (error) { + if (error is DioError && error.type != DioErrorType.response) { + state?.retryQueue?.add([message]); + } + rethrow; + } + } + /// Deletes the [message] from the channel. Future deleteMessage(Message message) async { // Directly deleting the local messages which are not yet sent to server @@ -533,17 +554,21 @@ class Channel { Duration(seconds: timeoutOrExpirationDate.toInt()), ); } - return updateMessage( - message.copyWith( - pinned: true, - pinExpires: pinExpires, - ), - ); + return partiallyUpdateMessage(message, { + 'set': { + 'pinned': true, + if (pinExpires != null) 'pin_expires': pinExpires.toIso8601String(), + } + }); } /// Unpins provided message Future unpinMessage(Message message) => - updateMessage(message.copyWith(pinned: false)); + partiallyUpdateMessage(message, { + 'set': { + 'pinned': false, + } + }); /// Send a file to this channel Future sendFile( diff --git a/packages/stream_chat/lib/src/client.dart b/packages/stream_chat/lib/src/client.dart index 98b05634..e0e29fff 100644 --- a/packages/stream_chat/lib/src/client.dart +++ b/packages/stream_chat/lib/src/client.dart @@ -1347,6 +1347,18 @@ class StreamChatClient { return decode(response.data, UpdateMessageResponse.fromJson); } + /// Partially update the given message + /// Use 'set' in map to set values + /// User 'unset' in map to unset values + Future partiallyUpdateMessage( + String id, Map data) async { + final response = await put( + '/messages/${id}', + data: data, + ); + return decode(response.data, UpdateMessageResponse.fromJson); + } + /// Deletes the given message Future deleteMessage(Message message) async { final response = await delete('/messages/${message.id}'); @@ -1385,20 +1397,21 @@ class StreamChatClient { ) .toUtc(); } - return updateMessage( - message.copyWith( - pinned: true, - pinExpires: pinExpires, - ), - ); + return partiallyUpdateMessage(message.id, { + 'set': { + 'pinned': true, + if (pinExpires != null) 'pin_expires': pinExpires.toIso8601String(), + } + }); } /// Unpins provided message - Future unpinMessage(Message message) => updateMessage( - message.copyWith( - pinned: false, - ), - ); + Future unpinMessage(Message message) => + partiallyUpdateMessage(message.id, { + 'set': { + 'pinned': false, + } + }); } /// The class that handles the state of the channel listening to the events