From e6b3c896d6187c0fd139b7dde29989abf4e790f1 Mon Sep 17 00:00:00 2001 From: Ralf Lang Date: Fri, 3 Jul 2026 11:01:12 +0200 Subject: [PATCH] fix(dynamic): make search_refresh actually refresh virtual folders Fixes #86 --- lib/Ajax/Application.php | 13 ++++++++++--- lib/Ajax/Application/Handler/Common.php | 19 ++++++++++++++++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/lib/Ajax/Application.php b/lib/Ajax/Application.php index e9241aa5f..fb95afc51 100644 --- a/lib/Ajax/Application.php +++ b/lib/Ajax/Application.php @@ -269,7 +269,9 @@ public function viewPortData($change) * * Variables used: * - cacheid: (string) The browser (ViewPort) cache identifier. - * - forceUpdate: (integer) If 1, forces an update. + * - forceUpdate: (integer) If 1, forces an update. Accepted at + * either the top level (as sent by IMP.poll()) or + * nested under 'viewport' as 'force'. * * @param boolean $rw Open mailbox as READ+WRITE? * @@ -278,8 +280,13 @@ public function viewPortData($change) */ public function changed($rw = null) { - /* Forced viewport return. */ - if ($this->_vars->viewport->force) { + /* Forced viewport return. Accept both the nested viewport->force + * flag and the top-level forceUpdate flag: the dynamic view sends + * forceUpdate=1 from IMP.poll(true) (e.g. the search_refresh + * toolbar button) and IMP_Ajax_Application_Handler_Common::viewPort() + * sets vars->forceUpdate after a sort change to re-run search + * mailboxes. */ + if ($this->_vars->viewport->force || $this->_vars->forceUpdate) { return true; } diff --git a/lib/Ajax/Application/Handler/Common.php b/lib/Ajax/Application/Handler/Common.php index ea6d041f2..8dd19977a 100644 --- a/lib/Ajax/Application/Handler/Common.php +++ b/lib/Ajax/Application/Handler/Common.php @@ -38,7 +38,24 @@ public function poll() * separate poll action because there are other tasks done when * specifically requesting a poll. */ - $this->_base->queue->quota($this->_base->indices->mailbox, false); + $mailbox = $this->_base->indices->mailbox; + + /* If the user forced a poll on a search mailbox (e.g. clicked the + * search_refresh toolbar button on the Virtual INBOX), the search + * cacheid alone will not advance because it is derived from the + * query generation counter which is only bumped by mutations. + * Invalidate the underlying query and rebuild its mailbox list so + * changed() can see fresh state and the viewport gets repopulated. */ + if (($this->vars->forceUpdate || $this->vars->viewport->force) && + $mailbox->search) { + $imp_search = $GLOBALS['injector']->getInstance('IMP_Search'); + if (isset($imp_search[strval($mailbox)])) { + $imp_search[strval($mailbox)]->invalidateCache(); + $mailbox->list_ob->rebuild(true); + } + } + + $this->_base->queue->quota($mailbox, false); if ($this->_base->changed()) { $this->_base->addTask('viewport', $this->_base->viewPortData(true));