sendMessage method
Send a message
to this channel.
If skipPush
is true the message will not send a push notification.
Waits for a _messageAttachmentsUploadCompleter
to complete
before actually sending the message.
Implementation
Future<SendMessageResponse> sendMessage(
Message message, {
bool skipPush = false,
bool skipEnrichUrl = false,
}) async {
_checkInitialized();
// Cancelling previous completer in case it's called again in the process
// Eg. Updating the message while the previous call is in progress.
_messageAttachmentsUploadCompleter
.remove(message.id)
?.completeError(const StreamChatError('Message cancelled'));
final quotedMessage = state!.messages.firstWhereOrNull(
(m) => m.id == message.quotedMessageId,
);
// ignore: parameter_assignments
message = message.copyWith(
localCreatedAt: DateTime.now(),
user: _client.state.currentUser,
quotedMessage: quotedMessage,
state: MessageState.sending,
attachments: message.attachments.map(
(it) {
if (it.uploadState.isSuccess) return it;
return it.copyWith(uploadState: const UploadState.preparing());
},
).toList(),
);
state!.updateMessage(message);
try {
if (message.attachments.any((it) => !it.uploadState.isSuccess)) {
final attachmentsUploadCompleter = Completer<Message>();
_messageAttachmentsUploadCompleter[message.id] =
attachmentsUploadCompleter;
_uploadAttachments(
message.id,
message.attachments.map((it) => it.id),
);
// ignore: parameter_assignments
message = await attachmentsUploadCompleter.future;
}
// Wait for the previous sendMessage call to finish. Otherwise, the order
// of messages will not be maintained.
final response = await _sendMessageLock.synchronized(
() => _client.sendMessage(
message,
id!,
type,
skipPush: skipPush,
skipEnrichUrl: skipEnrichUrl,
),
);
final sentMessage = response.message.syncWith(message).copyWith(
// Update the message state to sent.
state: MessageState.sent,
);
state!.updateMessage(sentMessage);
if (cooldown > 0) cooldownStartedAt = DateTime.now();
return response;
} catch (e) {
if (e is StreamChatNetworkError && e.isRetriable) {
state!._retryQueue.add([
message.copyWith(
// Update the message state to failed.
state: MessageState.sendingFailed,
),
]);
}
rethrow;
}
}