recallMessage method

Future<void> recallMessage(
  1. RCIMIWMessage recallMessage,
  2. BuildContext context
)

Implementation

Future<void> recallMessage(
    RCIMIWMessage recallMessage, BuildContext context) async {
  stopPlayVoiceAndReference([recallMessage], context);
  final targetEngine = _sessionEngine;
  if (targetEngine == null || !_isSessionEngineCurrent(targetEngine)) return;
  final operationConversationType = _con.conversationType;
  final operationTargetId = _con.targetId;
  final operationChannelId = _con.channelId;

  bool isCurrentOperation() {
    return _isSessionEngineCurrent(targetEngine) &&
        _con.conversationType == operationConversationType &&
        _con.targetId == operationTargetId &&
        _sameChannelId(_con.channelId, operationChannelId);
  }

  void applyRecallResult(RCIMIWMessage? result) {
    // recallMessageWithOption(..., false) 保留消息、只改变撤回状态。
    // 若平台仍回调旧的普通消息对象,按接口语义合成撤回通知,不能把
    // 这次普通消息回调误判成“撤回并删除”。
    final effective = result is RCIMIWRecallNotificationMessage
        ? result
        : _createRecallNotificationMessage(recallMessage);
    final status = effective.deleted == true
        ? RCIMIWReferenceMessageStatus.deleted
        : RCIMIWReferenceMessageStatus.recalled;
    // 页面可能已经退出,但成功回调仍要把终态交给 Engine 级缓存,
    // 让下一次进入页面直接显示正确的引用状态。
    if (_isSessionCurrent() && identical(targetEngine, _sessionEngine)) {
      _rememberTerminalStateForMessages(
        [effective, recallMessage],
        status,
        conversationType: operationConversationType,
        targetId: operationTargetId,
        channelId: operationChannelId,
      );
    }
    if (!isCurrentOperation()) return;
    if (_applyRecallOrDeleteEvent(
      effective,
      statusOverride: status,
      conversationTypeHint: operationConversationType,
      targetIdHint: operationTargetId,
      channelIdHint: operationChannelId,
    )) {
      notifyListeners();
    }
  }

  // 5.44 的新接口直接在成功回调中返回撤回后的消息。旧 recallMessage
  // 在 Android/iOS 都会成功后再按 messageId 二次查库,查询窗口内可能
  // 返回空或旧消息,导致当前页不刷新、重进后才从数据库看到撤回通知。
  final immediateCode = await targetEngine.recallMessageWithOption(
    recallMessage,
    false,
    callback: IRCIMIWRecallMessageCallback(
      onMessageRecalled: (code, message) {
        if (code == 0) applyRecallResult(message);
        RCIMWrapperPlatform.instance.writeLog('RCKChatProvider recallMessage',
            '', code ?? 0, 'onMessageRecalled: ${message?.messageId}');
      },
    ),
  );
  RCIMWrapperPlatform.instance.writeLog(
    'RCKChatProvider recallMessage',
    '',
    immediateCode,
    'recallMessageWithOption immediate result',
  );
}