+# called by PublicInbox::InboxIdle
+sub on_inbox_unlock {
+ my ($self, $ibx) = @_;
+ my $new = ($ibx->mm->minmax)[1];
+ defined(my $old = $self->{-idle_max}) or die 'BUG: -idle_max unset';
+ if ($new > $old) {
+ $self->{-idle_max} = $new;
+ $self->msg_more("* $_ EXISTS\r\n") for (($old + 1)..($new - 1));
+ $self->write(\"* $new EXISTS\r\n");
+ }
+}
+
+sub cmd_idle ($$) {
+ my ($self, $tag) = @_;
+ # IDLE seems allowed by dovecot w/o a mailbox selected *shrug*
+ my $ibx = $self->{ibx} or return "$tag BAD no mailbox selected\r\n";
+ $ibx->subscribe_unlock(fileno($self->{sock}), $self);
+ $self->{-idle_tag} = $tag;
+ $self->{-idle_max} = ($ibx->mm->minmax)[1] // 0;
+ "+ idling\r\n"
+}
+
+sub cmd_done ($$) {
+ my ($self, $tag) = @_; # $tag is "DONE" (case-insensitive)
+ defined(my $idle_tag = delete $self->{-idle_tag}) or
+ return "$tag BAD not idle\r\n";
+ my $ibx = $self->{ibx} or do {
+ warn "BUG: idle_tag set w/o inbox";
+ return "$tag BAD internal bug\r\n";
+ };
+ $ibx->unsubscribe_unlock(fileno($self->{sock}));
+ "$idle_tag OK Idle completed\r\n";
+}
+