sendNow method
Future<Message>
sendNow(
- Message msg, {
- ChatSilentNotification notification = const ChatSilentNotification(),
- VerifyToSendMessage? verifyToSend,
- OnDeniedToSendMessage? onDeniedToSend,
override
Direct send without queue check. Used by createMessage for online path and by drainOfflineQueue for queued messages.
Implementation
@override
Future<Message> sendNow(
Message msg, {
ChatSilentNotification notification = const ChatSilentNotification(),
VerifyToSendMessage? verifyToSend,
OnDeniedToSendMessage? onDeniedToSend,
}) async {
final failed = msg.copyWith(status: MessageStatus.failed);
if (me.isEmpty || msg.isEmpty) return failed;
final target = room(msg.roomId);
if (verifyToSend != null && !verifyToSend(target)) {
onDeniedToSend?.call(target);
return msg;
}
final body = msg.lastMessage();
final optimistic = target.copyWith(
lastMessage: body,
lastMessageId: msg.id,
lastMessageSenderId: me,
lastMessageDeleted: false,
updatedAt: ChatValueTimestamp.now(),
);
try {
put(optimistic);
final uploaded = await _replace(msg);
if (uploaded.isEmpty) {
put(target);
_trackFailed(msg, notification, verifyToSend, onDeniedToSend);
return failed;
}
final sent = uploaded.copyWith(status: MessageStatus.sent);
final normalizedMsg = n.normalize(sent.source, n.message);
await RetryHelper.run(
operation: () =>
messageDelegate.create(msg.roomId, msg.id, normalizedMsg),
onRetry: (attempt, error) {
managerOrNull(
msg.roomId,
)?.put(uploaded.copyWith(status: MessageStatus.retrying));
errorReporter.report(
error,
source: 'MessageMixin.sendNow.retry',
context: {
'roomId': msg.roomId,
'msgId': msg.id,
'attempt': attempt,
'phase': 'create',
},
);
},
);
await RetryHelper.run(
operation: () => roomDelegate.update(
msg.roomId,
n.normalize(
_roomMessageUpdatePayload(target, msg.id, body),
n.room,
),
),
onRetry: (attempt, error) {
errorReporter.report(
error,
source: 'MessageMixin.sendNow.retry',
context: {
'roomId': msg.roomId,
'msgId': msg.id,
'attempt': attempt,
'phase': 'roomUpdate',
},
);
},
);
await sendNotification(msg, notification);
_failedMessages.remove(msg.id);
return sent;
} catch (e, st) {
errorReporter.report(
e,
stackTrace: st,
source: 'MessageMixin.sendNow',
context: {'roomId': msg.roomId, 'msgId': msg.id, 'type': msg.type.name},
);
put(target);
_trackFailed(msg, notification, verifyToSend, onDeniedToSend);
return failed;
}
}