sendFileMessage method

FileMessage sendFileMessage(
  1. FileMessageCreateParams params, {
  2. FileMessageHandler? handler,
  3. ProgressHandler? progressHandler,
  4. int? resendMessageId,
})

Sends a file with given file information.

Implementation

FileMessage sendFileMessage(
  FileMessageCreateParams params, {
  FileMessageHandler? handler,
  ProgressHandler? progressHandler,
  int? resendMessageId,
}) {
  sbLog.i(StackTrace.current,
      'params.uploadFile.name: ${params.fileInfo.fileName}');
  checkUnsupportedAction();

  if (params.fileInfo.hasSource == false) {
    throw InvalidParameterException();
  }

  final fileSize = params.fileInfo.file?.lengthSync() ??
      params.fileInfo.fileBytes?.lengthInBytes ??
      0;

  if (fileSize > chat.chatContext.uploadSizeLimit) {
    throw FileSizeLimitExceededException();
  }

  final pendingFileMessage =
      FileMessage.fromParams(params: params, channel: this)..set(chat);

  pendingFileMessage.sendingStatus = SendingStatus.pending;
  pendingFileMessage.sender =
      Sender.fromUser(chat.chatContext.currentUser, this);
  pendingFileMessage.messageCreateParams = params;

  if (this is GroupChannel) {
    pendingFileMessage.messageId =
        resendMessageId ?? DateTime.now().millisecondsSinceEpoch;

    for (final messageCollection
        in chat.collectionManager.baseMessageCollections) {
      if (messageCollection.baseChannel.channelUrl == channelUrl) {
        if (resendMessageId != null) {
          chat.collectionManager.sendEventsToMessageCollection(
            messageCollection: messageCollection,
            baseChannel: this,
            eventSource: CollectionEventSource.localMessageResendStarted,
            sendingStatus: SendingStatus.pending,
            updatedMessages: [pendingFileMessage],
          );
        } else {
          chat.collectionManager.sendEventsToMessageCollection(
            messageCollection: messageCollection,
            baseChannel: this,
            eventSource: CollectionEventSource.localMessagePendingCreated,
            sendingStatus: SendingStatus.pending,
            addedMessages: [pendingFileMessage],
          );
        }
        break;
      }
    }
  }

  bool isCanceled = false;
  runZonedGuarded(() async {
    final queue = chat.getMessageQueue(channelUrl);
    final task = AsyncSimpleTask(
      () async {
        UploadResponse? uploadResponse;

        if (params.fileInfo.hasBinary) {
          uploadResponse = await chat.apiClient
              .send<UploadResponse>(ChannelFileUploadRequest(chat,
                  channelUrl: channelUrl,
                  requestId: pendingFileMessage.requestId!,
                  params: params,
                  progressHandler: progressHandler))
              .timeout(
            Duration(seconds: chat.chatContext.options.fileTransferTimeout),
            onTimeout: () {
              pendingFileMessage.sendingStatus = SendingStatus.failed;

              if (this is GroupChannel) {
                for (final messageCollection
                    in chat.collectionManager.baseMessageCollections) {
                  if (messageCollection.baseChannel.channelUrl ==
                      channelUrl) {
                    chat.collectionManager.sendEventsToMessageCollection(
                      messageCollection: messageCollection,
                      baseChannel: this,
                      eventSource: CollectionEventSource.localMessageFailed,
                      sendingStatus: SendingStatus.failed,
                      updatedMessages: [pendingFileMessage],
                    );
                    break;
                  }
                }
              }

              if (handler != null) {
                handler(
                  pendingFileMessage,
                  SendbirdException(code: SendbirdError.fileUploadTimeout),
                );
              }
              throw SendbirdException(code: SendbirdError.fileUploadTimeout);
            },
          );
        }

        String? fileUrl = uploadResponse?.url;
        int? fileSize = uploadResponse?.fileSize;
        if (fileUrl != null) params.fileInfo.fileUrl = fileUrl;
        if (fileSize != null) params.fileInfo.fileSize = fileSize;

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

        final messageBeforeSent =
            RootMessage.getMessageFromJsonWithChat<FileMessage>(
          chat,
          cmd.payload,
          channelType: channelType,
          commandType: cmd.cmd,
        ) as FileMessage
              ..messageId = pendingFileMessage.messageId;

        if (chat.chatContext.currentUser == null) {
          final error = ConnectionRequiredException();
          messageBeforeSent
            ..errorCode = error.code
            ..sendingStatus = SendingStatus.failed;

          if (this is GroupChannel) {
            for (final messageCollection
                in chat.collectionManager.baseMessageCollections) {
              if (messageCollection.baseChannel.channelUrl == channelUrl) {
                chat.collectionManager.sendEventsToMessageCollection(
                  messageCollection: messageCollection,
                  baseChannel: this,
                  eventSource: CollectionEventSource.localMessageFailed,
                  sendingStatus: SendingStatus.failed,
                  updatedMessages: [messageBeforeSent],
                );
                break;
              }
            }
          }

          if (handler != null) {
            handler(messageBeforeSent, error);
          }
          return messageBeforeSent;
        }

        if (chat.connectionManager.isConnected()) {
          chat.commandManager.sendCommand(cmd).then((result) async {
            if (result == null) return;

            final message =
                RootMessage.getMessageFromJsonWithChat<FileMessage>(
              chat,
              result.payload,
              channelType: channelType,
              commandType: result.cmd,
            ) as FileMessage;

            chat.collectionManager.onMessageSentByMe(
              channel: this,
              pendingMessage: messageBeforeSent,
              sentMessage: message,
            );

            if (handler != null) {
              handler(message, null);
            }
          });
        } else {
          final request = ChannelFileMessageSendRequest(
            chat,
            channelType: channelType,
            channelUrl: channelUrl,
            params: params,
            thumbnails: uploadResponse?.thumbnails,
            requireAuth: uploadResponse?.requireAuth,
          );
          final message = await chat.apiClient.send<FileMessage>(request);

          chat.collectionManager.onMessageSentByMe(
            channel: this,
            pendingMessage: messageBeforeSent,
            sentMessage: message,
          );

          if (handler != null) {
            handler(message, null);
          }
        }
      },
      onCancel: () {
        isCanceled = true;
        pendingFileMessage.sendingStatus = SendingStatus.canceled;

        if (this is GroupChannel) {
          for (final messageCollection
              in chat.collectionManager.baseMessageCollections) {
            if (messageCollection.baseChannel.channelUrl == channelUrl) {
              chat.collectionManager.sendEventsToMessageCollection(
                messageCollection: messageCollection,
                baseChannel: this,
                eventSource: CollectionEventSource.localMessageCanceled,
                sendingStatus: SendingStatus.canceled,
                deletedMessageIds: [pendingFileMessage.rootId],
              );
              break;
            }
          }
        }

        if (handler != null) {
          handler(pendingFileMessage, OperationCanceledException());
        }
      },
    );

    queue.enqueue(task);

    chat.setUploadTask(pendingFileMessage.requestId!, task);
    chat.setMessageQueue(channelUrl, queue);
  }, (e, s) {
    sbLog.e(StackTrace.current, 'e: $e');
    if (isCanceled) return;

    if (e is SendbirdException) {
      pendingFileMessage
        ..errorCode = e.code ?? SendbirdError.unknownError
        ..sendingStatus = SendingStatus.failed;

      if (this is GroupChannel) {
        for (final messageCollection
            in chat.collectionManager.baseMessageCollections) {
          if (messageCollection.baseChannel.channelUrl == channelUrl) {
            chat.collectionManager.sendEventsToMessageCollection(
              messageCollection: messageCollection,
              baseChannel: this,
              eventSource: CollectionEventSource.localMessageFailed,
              sendingStatus: SendingStatus.failed,
              updatedMessages: [pendingFileMessage],
            );
            break;
          }
        }
      }

      if (handler != null) {
        handler(pendingFileMessage, e);
      }
    }
  });

  return pendingFileMessage;
}