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;
  }
}