waitFor method
Wait for any message from the user.
Possibly returns null
if the listener has been cancelled before
it completes. Otherwise, returns a Context object with the incoming update.
Implementation
Future<Context?> waitFor({
required ID chatId,
Duration? timeout,
bool clearUnfulfilled = true,
required bool Function(Update update) filter,
String? handlerName,
}) async {
final scopeName =
handlerName == null ? "$name+${_getRandomID()}" : "$name+$handlerName";
if (clearUnfulfilled) {
await clear(chatId);
}
// Check if there's a listener already with the same name.
if (_bot._handlerScopes.any((scope) {
return scope.name == scopeName && scope.chatId == chatId;
})) {
// Cancel the previous listener.
final prev = _subscriptionsList.firstWhere(
(sub) => sub.scope == scopeName,
);
await prev.cancel();
_subscriptionsList.remove(prev);
_bot._handlerScopes.removeWhere((scope) => scope.name == scopeName);
print('[Televerse] Warning: Conversation listener with the same name '
'already exists. It has been removed.');
}
final completer = Completer<Context?>();
StreamSubscription<Update>? subscription;
subscription = _bot.updatesStream.listen((update) {
final sameChat = _isSameChat(update, chatId);
if (sameChat && filter(update)) {
completer.complete(Context(_bot, update: update));
}
});
_subscriptionsList.add(
_ISubHelper(subscription, scopeName, completer),
);
_bot._handlerScopes.add(
HandlerScope(
isConversation: true,
options: ScopeOptions(name: scopeName),
predicate: (ctx) =>
_isSameChat(ctx.update, chatId) && filter(ctx.update),
types: UpdateType.values,
chatId: chatId,
),
);
if (timeout != null) {
Future.delayed(timeout, () {
if (!completer.isCompleted) {
completer.completeError(
ConversationException(
"Conversation request timed out.",
ConversationExceptionType.timeout,
),
);
subscription?.cancel();
_bot._handlerScopes.removeWhere((scope) => scope.name == scopeName);
}
});
}
final ctx = await completer.future;
final s = _subscriptionsList.firstWhere(
(sub) => sub.scope == scopeName,
);
_subscriptionsList.remove(s);
subscription.cancel();
_bot._handlerScopes.removeWhere((scope) => scope.name == scopeName);
return ctx;
}