sendFileMessage method Null safety

FileMessage sendFileMessage(
  1. FileMessageParams params,
  2. {OnFileMessageCallback? onCompleted,
  3. OnUploadProgressCallback? progress}
)

Sends FileMessage on this channel with params.

It returns FileMessage with MessageSendingStatus.pending and onCompleted will be invoked once the message has been sent completely. Channel event ChannelEventHandler.onMessageReceived will be invoked on all other members' end.

Implementation

FileMessage sendFileMessage(
  FileMessageParams params, {
  OnFileMessageCallback? onCompleted,
  OnUploadProgressCallback? progress,
}) {
  if (!params.uploadFile.hasSource) {
    throw InvalidParameterError();
  }

  UploadResponse? upload;
  int? fileSize;
  String? url;

  final pending = FileMessage.fromParams(params: params, channel: this);
  pending.sendingStatus = MessageSendingStatus.pending;
  pending.sender = Sender.fromUser(_sdk.state.currentUser, this);

  final queue = _sdk.getMsgQueue(channelUrl);
  final task = AsyncSimpleTask(
    () async {
      if (params.uploadFile.hasBinary) {
        try {
          upload = await _sdk.api
              .uploadFile(
                  channelUrl: channelUrl,
                  requestId: pending.requestId!,
                  params: params,
                  progress: progress)
              .timeout(
            Duration(seconds: _sdk.options.fileTransferTimeout),
            onTimeout: () {
              logger.e('upload timeout');
              if (onCompleted != null) {
                onCompleted(
                  pending..sendingStatus = MessageSendingStatus.failed,
                  SBError(
                    message: 'upload timeout',
                    code: ErrorCode.fileUploadTimeout,
                  ),
                );
              }
              //
              throw SBError(code: ErrorCode.fileUploadTimeout);
            },
          );
          if (upload == null) {
            throw SBError(code: ErrorCode.fileUploadTimeout);
          }
          fileSize = upload?.fileSize;
          url = upload?.url;
        } catch (e) {
          rethrow;
        }
      }

      if (fileSize != null) params.uploadFile.fileSize = fileSize;
      if (url != null) params.uploadFile.url = url;

      final cmd = Command.buildFileMessage(
        channelUrl: channelUrl,
        params: params,
        requestId: pending.requestId,
        requireAuth: upload?.requireAuth,
        thumbnails: upload?.thumbnails,
      );

      final msgFromPayload = BaseMessage.msgFromJson<FileMessage>(
        cmd.payload,
        channelType: channelType,
        type: cmd.cmd,
      )!;

      if (!_sdk.state.hasActiveUser) {
        final error = ConnectionRequiredError();
        msgFromPayload
          ..errorCode = error.code
          ..sendingStatus = MessageSendingStatus.failed;
        if (onCompleted != null) onCompleted(msgFromPayload, error);
        return msgFromPayload;
      }

      _sdk.cmdManager.sendCommand(cmd).then((result) {
        if (result == null) return;
        final msg = BaseMessage.msgFromJson<FileMessage>(
          result.payload,
          type: result.cmd,
        );
        if (onCompleted != null && msg != null) onCompleted(msg, null);
      }).catchError((e) {
        pending
          ..errorCode = e?.code ?? ErrorCode.unknownError
          ..sendingStatus = MessageSendingStatus.failed;
        if (onCompleted != null) onCompleted(pending, e);
      });
    },
    onCancel: () {
      if (onCompleted != null) onCompleted(pending, OperationCancelError());
    },
  );

  queue.enqueue(task);

  _sdk.setUploadTask(pending.requestId!, task);
  _sdk.setMsgQueue(channelUrl, queue);

  return pending;
}