editMessage method

void editMessage(
  1. ChatItem item
)

Starts the editing of the specified item, if allowed.

Implementation

void editMessage(ChatItem item) {
  if (!item.isEditable(chat!.chat.value, me!)) {
    MessagePopup.error('err_uneditable_message'.l10n);
    return;
  }

  if (item is ChatMessage) {
    edit.value ??= MessageFieldController(
      _chatService,
      _userService,
      _settingsRepository,
      text: item.text?.val,
      onKeyUp: (key) {
        if (key == LogicalKeyboardKey.escape) {
          final bool hasChanges =
              edit.value!.field.text != item.text?.val ||
              !const ListEquality().equals(
                edit.value!.attachments.map((e) => e.value).toList(),
                item.attachments,
              );

          if (hasChanges) {
            MessagePopup.alert(
              'label_discard_changes_question'.l10n,
              button: (context) => MessagePopup.deleteButton(
                context,
                label: 'btn_discard'.l10n,
              ),
            ).then((e) {
              if (e == true) {
                closeEditing();
              }
            });
          } else {
            closeEditing();
          }

          return true;
        }

        return false;
      },
      onSubmit: () async {
        final ChatMessage item = edit.value?.edited.value as ChatMessage;

        Log.debug(
          'editMessage() -> onSubmit() -> text(${edit.value!.field.text.trim()}) vs send(${send.field.text}), attachments(${edit.value!.attachments}), replies(${edit.value!.replied})',
          '$runtimeType',
        );

        _stopTyping();

        final bool hasText = edit.value!.field.text.trim() != item.text?.val;

        if (hasText ||
            edit.value!.attachments.isNotEmpty ||
            edit.value!.replied.isNotEmpty) {
          try {
            final ChatMessageTextInput text = ChatMessageTextInput(
              ChatMessageText(edit.value!.field.text),
            );

            final ChatMessageAttachmentsInput attachments =
                ChatMessageAttachmentsInput(
                  edit.value!.attachments.map((e) => e.value).toList(),
                );

            final ChatMessageRepliesInput repliesTo = ChatMessageRepliesInput(
              edit.value!.replied.map((e) => e.value.id).toList(),
            );

            closeEditing();

            send.field.focus.requestFocus();

            await _chatService.editChatMessage(
              item,
              text: text,
              attachments: attachments,
              repliesTo: repliesTo,
            );

            // If the message is not sent yet, resend it.
            if (item.status.value == SendingStatus.error) {
              await resendItem(item);
            }
          } on EditChatMessageException catch (e) {
            if (e.code == EditChatMessageErrorCode.blocked) {
              _showBlockedPopup();
            } else {
              MessagePopup.error(e);
            }
          } catch (e) {
            MessagePopup.error('err_data_transfer'.l10n);
            rethrow;
          }
        } else {
          closeEditing();
        }
      },
      onChanged: () {
        if (edit.value?.edited.value == null) {
          closeEditing();
        }
      },
    );

    edit.value?.edited.value = item;
    edit.value?.field.focus.requestFocus();

    // Stop the [_typingSubscription] when the edit field loses its focus.
    edit.value?.field.focus.addListener(_stopTypingOnUnfocus);
  }
}