editChatMessage method

  1. @override
Future<void> editChatMessage(
  1. ChatMessage message, {
  2. ChatMessageTextInput? text,
  3. ChatMessageAttachmentsInput? attachments,
  4. 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 _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),
    );
  } catch (_) {
    if (item?.value is ChatMessage) {
      item?.update((c) {
        (c as ChatMessage).text = previousText;
        c.attachments = previousAttachments ?? [];
        c.repliesTo = previousReplies ?? [];
      });
    }

    rethrow;
  }
}