idleStart method
Switches to IDLE mode.
Requires a mailbox to be selected and the mail service to support IDLE.
By default returns immediately after queueing the IDLE command, before
the server has confirmed entering IDLE state with a + idling
continuation response. Set waitForContinuation to true to get a
future that completes only after the server's continuation response is
received — at that point the IDLE mode is truly active per RFC 2177 §3
("as long as an IDLE command is active, the server is now free to send
untagged EXISTS, EXPUNGE, and other messages at any time"). This matters
when the caller plans to disconnect or stop listening right after
idleStart() — without waiting, the command may still be in flight and
the + idling response can arrive into an already-closed socket
buffer, confusing proxies or other intermediaries.
The returned future completes with an error if the connection is closed or an error occurs before the continuation is received.
Compare idleDone
Implementation
Future<void> idleStart({bool waitForContinuation = false}) {
if (!isConnected) {
throw ImapException(this, 'idleStart failed: client is not connected');
}
if (!isLoggedIn) {
throw ImapException(this, 'idleStart failed: user not logged in');
}
if (_selectedMailbox == null) {
print('$logName: idleStart(): ERROR: no mailbox selected');
return Future.value();
}
if (_isInIdleMode) {
logApp('Warning: idleStart() called but client is already in IDLE mode.');
return Future.value();
}
final cmd = Command('IDLE', writeTimeout: defaultWriteTimeout);
final task = CommandTask(cmd, nextId(), NoopParser(this, _selectedMailbox));
_tasks[task.id] = task;
_idleCommandTask = task;
Completer<void>? continuationCompleter;
if (waitForContinuation) {
continuationCompleter = Completer<void>();
_idleContinuationCompleter = continuationCompleter;
}
sendCommandTask(task, returnCompleter: false);
_isInIdleMode = true;
if (continuationCompleter != null) {
return continuationCompleter.future;
}
return Future.value();
}