onTextChanged method

void onTextChanged(
  1. String newText,
  2. BuildContext context
)

Implementation

void onTextChanged(String newText, BuildContext context) {
  String oldText = lastChangedText;
  newText = _syncMentionsWithText(oldText, newText);

  RCKChatProvider chatProvider = context.read<RCKChatProvider>();
  if (isEditing) {
    _scheduleEditedDraft(chatProvider, newText);
    if (newText.isEmpty) {
      unawaited(chatProvider.clearDraft());
    } else {
      unawaited(chatProvider.saveDraft(newText));
    }
  } else if (newText.isEmpty) {
    unawaited(chatProvider.clearDraft());
  } else {
    unawaited(chatProvider.saveDraft(newText));
  }
  // 当文本增加字符且新增加的字符中包含 '@' 时触发
  if (newText.length > oldText.length &&
      chatProvider.conversation.conversationType ==
          RCIMIWConversationType.group) {
    int cursorIndex = controller.selection.baseOffset;
    // 验证 cursorIndex 的有效性
    if (cursorIndex == -1) {
      cursorIndex = newText.length;
    }
    if (cursorIndex > 0 && newText[cursorIndex - 1] == '@') {
      context.read<RCKAudioPlayerProvider>().stopVoiceMessage();
      context.read<RCKVoiceRecordProvider>().cancelRecord();
      // @ 人页返回是跨页面异步回调。记录发起时的编辑、Engine、账号和会话
      // 身份,避免期间切换会话或退出编辑后把结果写入另一份草稿。
      final atPeopleOperationId = _editOperationId;
      final atPeopleEditingMessageUId = _editingMessage?.messageUId;
      final atPeopleWasEditing = isEditing;
      final atPeopleEngineProvider = chatProvider.engineProvider;
      final atPeopleEngine = atPeopleEngineProvider.engine;
      final atPeopleUserId = atPeopleEngineProvider.currentUserId;
      final atPeopleConversationType =
          chatProvider.conversation.conversationType;
      final atPeopleTargetId = chatProvider.conversation.targetId;
      final atPeopleChannelId = chatProvider.conversation.channelId;
      Navigator.pushNamed(
        context,
        '/at_people',
        arguments: {'groupId': chatProvider.conversation.targetId},
      ).then((value) {
        if (!context.mounted) return;
        if (!_isAtPeopleRequestCurrent(
          context,
          chatProvider,
          operationId: atPeopleOperationId,
          editingMessageUId: atPeopleEditingMessageUId,
          wasEditing: atPeopleWasEditing,
          engineProvider: atPeopleEngineProvider,
          engine: atPeopleEngine,
          userId: atPeopleUserId,
          conversationType: atPeopleConversationType,
          targetId: atPeopleTargetId,
          channelId: atPeopleChannelId,
        )) {
          return;
        }
        final atInfo = value is RCKUserAtInfo ? value : null;
        if (atInfo == null) return;
        final currentText = controller.text;
        final selection = controller.selection;
        int cursorIndex = selection.baseOffset;
        // 验证 cursorIndex 的有效性
        if (cursorIndex == -1) {
          cursorIndex = currentText.length;
        }
        // 判断光标前一个字符是否为 '@'
        if (cursorIndex > 0 && currentText[cursorIndex - 1] == '@') {
          final insertedText = '${atInfo.name} ';
          final newText = currentText.replaceRange(
            cursorIndex,
            cursorIndex,
            insertedText,
          );
          if (!atPeopleWasEditing &&
              newText.length > kMessageInputMaxLength) {
            return;
          }
          controller.value = controller.value.copyWith(
            text: newText,
            selection: TextSelection.collapsed(
              offset: cursorIndex + insertedText.length,
            ),
          );
          if (!context.mounted || _disposed) return;
          onTextChanged(controller.text, context);
          final mentionStart = cursorIndex - 1;
          final mentionText = '@${atInfo.name} ';
          if (mentionStart >= 0 &&
              mentionStart + mentionText.length <= controller.text.length &&
              controller.text.substring(
                    mentionStart,
                    mentionStart + mentionText.length,
                  ) ==
                  mentionText) {
            _registerMention(
              RCKMessageEditMention(
                userId: atInfo.userId,
                text: mentionText,
                start: mentionStart,
                end: mentionStart + mentionText.length,
              ),
            );
          }
        }
      });
    }
  }
  lastChangedText = newText;
}