editChatMessage method
- ChatMessage message, {
- ChatMessageTextInput? text,
- ChatMessageAttachmentsInput? attachments,
- ChatMessageRepliesInput? repliesTo,
override
Edits the specified ChatMessage posted by the authenticated MyUser.
Implementation
@override
Future<void> editChatMessage(
ChatMessage message, {
model.ChatMessageTextInput? text,
model.ChatMessageAttachmentsInput? attachments,
model.ChatMessageRepliesInput? repliesTo,
}) async {
Log.debug('editChatMessage($message, $text)', '$runtimeType');
final Rx<ChatItem>? item = chats[message.chatId]?.messages.firstWhereOrNull(
(e) => e.value.id == message.id,
);
ChatMessageText? previousText;
List<Attachment>? previousAttachments;
List<ChatItemQuote>? previousReplies;
if (item?.value is ChatMessage) {
previousText = (item?.value as ChatMessage).text;
previousAttachments = (item?.value as ChatMessage).attachments;
previousReplies = (item?.value as ChatMessage).repliesTo;
item?.update((c) {
(c as ChatMessage).text = text != null ? text.changed : previousText;
c.attachments = attachments?.changed ?? previousAttachments!;
c.repliesTo =
repliesTo?.changed
.map(
(e) =>
c.repliesTo.firstWhereOrNull((a) => a.original?.id == e),
)
.nonNulls
.toList() ??
previousReplies!;
});
}
final List<Future>? uploads = attachments?.changed
.mapIndexed((i, e) {
if (e is LocalAttachment) {
return e.upload.value?.future.then(
(a) {
attachments.changed[i] = a;
(item?.value as ChatMessage).attachments[i] = a;
},
onError: (_) {
// No-op, as failed upload attempts are handled below.
},
);
}
})
.nonNulls
.toList();
await Future.wait(uploads ?? []);
try {
if (attachments?.changed.whereType<LocalAttachment>().isNotEmpty ==
true) {
throw const ConnectionException(
EditChatMessageException(EditChatMessageErrorCode.unknownAttachment),
);
}
await Backoff.run(
() async {
await _graphQlProvider.editChatMessage(
message.id,
text: text == null
? null
: ChatMessageTextInput(kw$new: text.changed),
attachments: attachments == null
? null
: ChatMessageAttachmentsInput(
kw$new: attachments.changed.map((e) => e.id).toList(),
),
repliesTo: repliesTo == null
? null
: ChatMessageRepliesInput(kw$new: repliesTo.changed),
);
},
retryIf: (e) => e.isNetworkRelated,
retries: 10,
);
} on EditChatMessageException catch (e) {
switch (e.code) {
case EditChatMessageErrorCode.uneditable:
case EditChatMessageErrorCode.blocked:
case EditChatMessageErrorCode.unknownAttachment:
case EditChatMessageErrorCode.artemisUnknown:
case EditChatMessageErrorCode.wrongAttachmentsCount:
case EditChatMessageErrorCode.unknownReplyingChatItem:
case EditChatMessageErrorCode.wrongReplyingChatItemsCount:
rethrow;
case EditChatMessageErrorCode.unknownChatItem:
chats[message.chatId]?.remove(message.id);
break;
case EditChatMessageErrorCode.notAuthor:
case EditChatMessageErrorCode.noTextAndNoAttachment:
// No-op.
break;
}
} catch (_) {
if (item?.value is ChatMessage) {
item?.update((c) {
(c as ChatMessage).text = previousText;
c.attachments = previousAttachments ?? [];
c.repliesTo = previousReplies ?? [];
});
}
rethrow;
}
}