idleStart method

Future<void> idleStart({
  1. bool waitForContinuation = false,
})

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();
}