diff --git a/dev/Model/FolderCollection.js b/dev/Model/FolderCollection.js index 0b4112f9d..b781bbc0f 100644 --- a/dev/Model/FolderCollection.js +++ b/dev/Model/FolderCollection.js @@ -100,10 +100,8 @@ export class FolderCollectionModel extends AbstractCollectionModel storeIt() { const cnt = pInt(this.CountRec); - let limit = pInt(Settings.app('folderSpecLimit')); - limit = 100 < limit ? 100 : 10 > limit ? 10 : limit; - - FolderUserStore.displaySpecSetting(0 >= cnt || limit < cnt); + FolderUserStore.displaySpecSetting(0 >= cnt + || Math.max(10, Math.min(100, pInt(Settings.app('folderSpecLimit')))) < cnt); FolderUserStore.folderList(this); diff --git a/dev/Styles/FolderList.less b/dev/Styles/FolderList.less index 7b842df36..836b16bdb 100644 --- a/dev/Styles/FolderList.less +++ b/dev/Styles/FolderList.less @@ -20,7 +20,7 @@ } .b-folders-user { - .e-link.print-count.system .badge { + a.print-count.system .badge { display: none !important; } } @@ -75,7 +75,7 @@ overflow: hidden; white-space: nowrap; - .e-link { + a { display: block; position: relative; z-index: 1; @@ -108,9 +108,7 @@ display: inline; } - padding: 0; - padding-left: @folderItemPadding; - padding-right: @folderItemPadding; + padding: 0 @folderItemPadding; text-decoration: none; @@ -203,21 +201,21 @@ font-weight: bold; } - .b-sub-folders .e-item .e-link { + .b-sub-folders .e-item a { padding-left: @subPadding * 1 + @folderItemPadding; } - .b-sub-folders .b-sub-folders .e-item .e-link { + .b-sub-folders .b-sub-folders .e-item a { padding-left: @subPadding * 2 + @folderItemPadding; } - .b-sub-folders .b-sub-folders .b-sub-folders .e-item .e-link { + .b-sub-folders .b-sub-folders .b-sub-folders .e-item a { padding-left: @subPadding * 3 + @folderItemPadding; } - .b-sub-folders .b-sub-folders .b-sub-folders .b-sub-folders .e-item .e-link { + .b-sub-folders .b-sub-folders .b-sub-folders .b-sub-folders .e-item a { padding-left: @subPadding * 4 + @folderItemPadding; } /**/ - &.single-root-inbox .i-am-inbox.e-link { + &.single-root-inbox a.i-am-inbox { display: none !important; } @@ -228,16 +226,16 @@ } &.single-root-inbox .i-am-inbox-wrapper { - .b-sub-folders .e-item .e-link { + .b-sub-folders .e-item a { padding-left: @folderItemPadding; } - .b-sub-folders .b-sub-folders .e-item .e-link { + .b-sub-folders .b-sub-folders .e-item a { padding-left: @subPadding * 1 + @folderItemPadding; } - .b-sub-folders .b-sub-folders .b-sub-folders .e-item .e-link { + .b-sub-folders .b-sub-folders .b-sub-folders .e-item a { padding-left: @subPadding * 2 + @folderItemPadding; } - .b-sub-folders .b-sub-folders .b-sub-folders .b-sub-folders .e-item .e-link { + .b-sub-folders .b-sub-folders .b-sub-folders .b-sub-folders .e-item a { padding-left: @subPadding * 3 + @folderItemPadding; } } diff --git a/dev/View/User/MailBox/FolderList.js b/dev/View/User/MailBox/FolderList.js index 63f286d3b..cd2d8a60b 100644 --- a/dev/View/User/MailBox/FolderList.js +++ b/dev/View/User/MailBox/FolderList.js @@ -108,16 +108,16 @@ export class FolderListMailBoxUserView extends AbstractViewLeft { } } - el = eqs(event, '.b-folders .e-item .e-link.selectable .inbox-star-icon'); + el = eqs(event, '.b-folders .e-item a.selectable .inbox-star-icon'); el && fSelectFolder(el, event, !this.isInboxStarred()); - el = eqs(event, '.b-folders .e-item .e-link.selectable'); + el = eqs(event, '.b-folders .e-item a.selectable'); el && fSelectFolder(el, event, false); }); shortcuts.add('arrowup,arrowdown', '', Scope.FolderList, event => { let items = [], index = 0; - dom.querySelectorAll('.b-folders .e-item .e-link:not(.hidden)').forEach(node => { + dom.querySelectorAll('.b-folders .e-item a:not(.hidden)').forEach(node => { if (node.offsetHeight || node.getClientRects().length) { items.push(node); if (node.matches('.focused')) { @@ -140,7 +140,7 @@ export class FolderListMailBoxUserView extends AbstractViewLeft { }); shortcuts.add('enter,open', '', Scope.FolderList, () => { - const item = qs('.b-folders .e-item .e-link:not(.hidden).focused'); + const item = qs('.b-folders .e-item a:not(.hidden).focused'); if (item) { AppUserStore.focusedState(Scope.MessageList); item.click(); @@ -150,7 +150,7 @@ export class FolderListMailBoxUserView extends AbstractViewLeft { }); shortcuts.add('space', '', Scope.FolderList, () => { - const item = qs('.b-folders .e-item .e-link:not(.hidden).focused'), + const item = qs('.b-folders .e-item a:not(.hidden).focused'), folder = item && ko.dataFor(item); if (folder) { const collapsed = folder.collapsed(); @@ -169,11 +169,11 @@ export class FolderListMailBoxUserView extends AbstractViewLeft { }); AppUserStore.focusedState.subscribe(value => { - let el = qs('.b-folders .e-item .e-link.focused'); - el && qs('.b-folders .e-item .e-link.focused').classList.remove('focused'); + let el = qs('.b-folders .e-item a.focused'); + el && qs('.b-folders .e-item a.focused').classList.remove('focused'); if (Scope.FolderList === value) { - el = qs('.b-folders .e-item .e-link.selected'); - el && qs('.b-folders .e-item .e-link.selected').classList.add('focused'); + el = qs('.b-folders .e-item a.selected'); + el && qs('.b-folders .e-item a.selected').classList.add('focused'); } }); } @@ -181,7 +181,7 @@ export class FolderListMailBoxUserView extends AbstractViewLeft { scrollToFocused() { const scrollable = this.oContentScrollable; if (scrollable) { - let block, focused = scrollable.querySelector('.e-item .e-link.focused'); + let block, focused = scrollable.querySelector('.e-item a.focused'); if (focused) { const fRect = focused.getBoundingClientRect(), sRect = scrollable.getBoundingClientRect(); diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/FolderCollection.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/FolderCollection.php index a6e0a1044..d821afc78 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/FolderCollection.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/FolderCollection.php @@ -20,44 +20,32 @@ class FolderCollection extends \MailSo\Base\Collection /** * @var string */ - public $Namespace; + public $Namespace = ''; /** * @var string */ - public $FoldersHash; + public $FoldersHash = ''; /** * @var bool */ - public $IsThreadsSupported; + public $IsThreadsSupported = false; /** * @var bool */ - public $IsSortSupported; + public $IsSortSupported = false; /** * @var bool */ - public $Optimized; + public $Optimized = false; /** * @var array */ - public $SystemFolders; - - function __construct($input = array()) - { - parent::__construct($input); - - $this->Namespace = ''; - $this->FoldersHash = ''; - $this->SystemFolders = array(); - $this->IsThreadsSupported = false; - $this->IsSortSupported = false; - $this->Optimized = false; - } + public $SystemFolders = array(); public function append($oFolder, bool $bToTop = false) : void { @@ -118,12 +106,7 @@ class FolderCollection extends \MailSo\Base\Collection $oFolder = $this[0]; } - if ($oFolder) - { - $sDelimiter = $oFolder->Delimiter(); - } - - return $sDelimiter; + return $oFolder ? $oFolder->Delimiter() : '/'; } public function SetNamespace(string $sNamespace) : self @@ -133,92 +116,18 @@ class FolderCollection extends \MailSo\Base\Collection return $this; } - public function InitByUnsortedMailFolderArray(array $aUnsortedMailFolders) : void + public function AddWithPositionSearch(Folder $oMailFolder) : void { - $this->Clear(); - - $aSortedByLenImapFolders = array(); - foreach ($aUnsortedMailFolders as /* @var $oMailFolder Folder */ $oMailFolder) - { - $aSortedByLenImapFolders[$oMailFolder->FullNameRaw()] =& $oMailFolder; - unset($oMailFolder); - } - unset($aUnsortedMailFolders); - - $aAddedFolders = array(); - foreach ($aSortedByLenImapFolders as /* @var $oMailFolder Folder */ $oMailFolder) - { - $sDelimiter = $oMailFolder->Delimiter(); - $aFolderExplode = \explode($sDelimiter, $oMailFolder->FullNameRaw()); - - if (1 < \count($aFolderExplode)) - { - \array_pop($aFolderExplode); - - $sNonExistenFolderFullNameRaw = ''; - foreach ($aFolderExplode as $sFolderExplodeItem) - { - $sNonExistenFolderFullNameRaw .= (0 < \strlen($sNonExistenFolderFullNameRaw)) - ? $sDelimiter.$sFolderExplodeItem : $sFolderExplodeItem; - - if (!isset($aSortedByLenImapFolders[$sNonExistenFolderFullNameRaw])) - { - try - { - $aAddedFolders[$sNonExistenFolderFullNameRaw] = - Folder::NewNonExistenInstance($sNonExistenFolderFullNameRaw, $sDelimiter); - } - catch (\Throwable $oExc) - { - unset($oExc); - } - } - } - } - } - - $aSortedByLenImapFolders = \array_merge($aSortedByLenImapFolders, $aAddedFolders); - unset($aAddedFolders); - - \uasort($aSortedByLenImapFolders, function ($oFolderA, $oFolderB) { - return \strnatcmp($oFolderA->FullNameRaw(), $oFolderB->FullNameRaw()); - }); - - foreach ($aSortedByLenImapFolders as $oMailFolder) - { - $this->AddWithPositionSearch($oMailFolder); - unset($oMailFolder); - } - - unset($aSortedByLenImapFolders); - } - - public function AddWithPositionSearch(Folder $oMailFolder) : bool - { - $oItemFolder = null; - $bIsAdded = false; - foreach ($this as $oItemFolder) { - if ($oMailFolder instanceof Folder && - 0 === \strpos($oMailFolder->FullNameRaw(), $oItemFolder->FullNameRaw().$oItemFolder->Delimiter())) + if (0 === \strpos($oMailFolder->FullNameRaw(), $oItemFolder->FullNameRaw().$oItemFolder->Delimiter())) { - if ($oItemFolder->SubFolders(true)->AddWithPositionSearch($oMailFolder)) - { - $bIsAdded = true; - } - - break; + $oItemFolder->SubFolders(true)->AddWithPositionSearch($oMailFolder); + return; } } - if (!$bIsAdded && $oMailFolder instanceof Folder) - { - $bIsAdded = true; - $this->append($oMailFolder); - } - - return $bIsAdded; + $this->append($oMailFolder); } public function SortByCallback(callable $fCallback) : void @@ -241,7 +150,7 @@ class FolderCollection extends \MailSo\Base\Collection public function jsonSerialize() { - return array_merge(parent::jsonSerialize(), array( + return \array_merge(parent::jsonSerialize(), array( 'Namespace' => $this->GetNamespace(), 'FoldersHash' => $this->FoldersHash ?: '', 'IsThreadsSupported' => $this->IsThreadsSupported, diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php index c32682293..751dbae41 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php @@ -1439,14 +1439,12 @@ class MailClient if (0 < \count($aFetchResponse)) { $aFetchIndexArray = array(); - $oFetchResponseItem = null; foreach ($aFetchResponse as /* @var $oFetchResponseItem \MailSo\Imap\FetchResponse */ $oFetchResponseItem) { - $aFetchIndexArray[($bIndexAsUid) + $aFetchIndexArray[$bIndexAsUid ? $oFetchResponseItem->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::UID) - : $oFetchResponseItem->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::INDEX)] =& $oFetchResponseItem; - - unset($oFetchResponseItem); + : $oFetchResponseItem->GetFetchValue(\MailSo\Imap\Enumerations\FetchType::INDEX) + ] = $oFetchResponseItem; } foreach ($aRequestIndexOrUids as $iFUid) @@ -1979,8 +1977,6 @@ class MailClient public function Folders(string $sParent = '', string $sListPattern = '*', bool $bUseListSubscribeStatus = true, int $iOptimizationLimit = 0) : ?FolderCollection { - $oFolderCollection = null; - $aImapSubscribedFoldersHelper = null; if ($bUseListSubscribeStatus) { @@ -2000,56 +1996,102 @@ class MailClient } $aFolders = $this->oImapClient->FolderList($sParent, $sListPattern); + if (!$aFolders) { + return null; + } - if ($aFolders) + $aMailFoldersHelper = array(); + foreach ($aFolders as /* @var $oImapFolder \MailSo\Imap\Folder */ $oImapFolder) { - $aMailFoldersHelper = array(); + $aMailFoldersHelper[] = new Folder($oImapFolder, + (null === $aImapSubscribedFoldersHelper || \in_array($oImapFolder->FullNameRaw(), $aImapSubscribedFoldersHelper)) || + $oImapFolder->IsInbox() + ); + } - foreach ($aFolders as /* @var $oImapFolder \MailSo\Imap\Folder */ $oImapFolder) + $iCount = \count($aMailFoldersHelper); + $aMailFoldersHelper = $this->folderListOptimization($aMailFoldersHelper, $iOptimizationLimit); + if (!$aMailFoldersHelper) { + return null; + } + + $oFolderCollection = new FolderCollection; + $oFolderCollection->IsThreadsSupported = $this->IsThreadsSupported(); + $oFolderCollection->IsSortSupported = $this->oImapClient->IsSupported('SORT'); + $oFolderCollection->Optimized = $iCount !== \count($aMailFoldersHelper); + + $aSortedByLenImapFolders = array(); + foreach ($aMailFoldersHelper as /* @var $oMailFolder Folder */ $oMailFolder) + { + $aSortedByLenImapFolders[$oMailFolder->FullNameRaw()] = $oMailFolder; + } + unset($aMailFoldersHelper); + + $aAddedFolders = array(); + foreach ($aSortedByLenImapFolders as /* @var $oMailFolder Folder */ $oMailFolder) + { + $sDelimiter = $oMailFolder->Delimiter(); + $aFolderExplode = \explode($sDelimiter, $oMailFolder->FullNameRaw()); + + if (1 < \count($aFolderExplode)) { - $aMailFoldersHelper[] = new Folder($oImapFolder, - (null === $aImapSubscribedFoldersHelper || \in_array($oImapFolder->FullNameRaw(), $aImapSubscribedFoldersHelper)) || - $oImapFolder->IsInbox() - ); - } + \array_pop($aFolderExplode); - $iCount = \count($aMailFoldersHelper); - $aMailFoldersHelper = $this->folderListOptimization($aMailFoldersHelper, $iOptimizationLimit); + $sNonExistenFolderFullNameRaw = ''; + foreach ($aFolderExplode as $sFolderExplodeItem) + { + $sNonExistenFolderFullNameRaw .= (0 < \strlen($sNonExistenFolderFullNameRaw)) + ? $sDelimiter.$sFolderExplodeItem : $sFolderExplodeItem; - if ($aMailFoldersHelper) - { - $oFolderCollection = new FolderCollection; - $oFolderCollection->InitByUnsortedMailFolderArray($aMailFoldersHelper); - - $oFolderCollection->Optimized = $iCount !== \count($aMailFoldersHelper); + if (!isset($aSortedByLenImapFolders[$sNonExistenFolderFullNameRaw])) + { + try + { + $aAddedFolders[$sNonExistenFolderFullNameRaw] = + Folder::NewNonExistenInstance($sNonExistenFolderFullNameRaw, $sDelimiter); + } + catch (\Throwable $oExc) + { + unset($oExc); + } + } + } } } - if ($oFolderCollection) + $aSortedByLenImapFolders = \array_merge($aSortedByLenImapFolders, $aAddedFolders); + unset($aAddedFolders); + + \uasort($aSortedByLenImapFolders, function ($oFolderA, $oFolderB) { + return \strnatcmp($oFolderA->FullNameRaw(), $oFolderB->FullNameRaw()); + }); + + foreach ($aSortedByLenImapFolders as $oMailFolder) { - $oFolderCollection->SortByCallback(function ($oFolderA, $oFolderB) { - $sA = \strtoupper($oFolderA->FullNameRaw()); - $sB = \strtoupper($oFolderB->FullNameRaw()); - switch (true) - { - case 'INBOX' === $sA: - return -1; - case 'INBOX' === $sB: - return 1; - } + $oFolderCollection->AddWithPositionSearch($oMailFolder); + unset($oMailFolder); + } - return \strnatcasecmp($oFolderA->FullName(), $oFolderB->FullName()); - }); + unset($aSortedByLenImapFolders); - $oNamespace = $this->oImapClient->GetNamespace(); - if ($oNamespace) + $oFolderCollection->SortByCallback(function ($oFolderA, $oFolderB) { + $sA = \strtoupper($oFolderA->FullNameRaw()); + $sB = \strtoupper($oFolderB->FullNameRaw()); + switch (true) { - $oFolderCollection->SetNamespace($oNamespace->GetPersonalNamespace()); + case 'INBOX' === $sA: + return -1; + case 'INBOX' === $sB: + return 1; } - $oFolderCollection->IsThreadsSupported = $this->IsThreadsSupported(); + return \strnatcasecmp($oFolderA->FullName(), $oFolderB->FullName()); + }); - $oFolderCollection->IsSortSupported = $this->oImapClient->IsSupported('SORT'); + $oNamespace = $this->oImapClient->GetNamespace(); + if ($oNamespace) + { + $oFolderCollection->SetNamespace($oNamespace->GetPersonalNamespace()); } return $oFolderCollection; diff --git a/snappymail/v/0.0.0/app/templates/Views/User/MailFolderListItem.html b/snappymail/v/0.0.0/app/templates/Views/User/MailFolderListItem.html index 53a07d0c6..44751d758 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/MailFolderListItem.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/MailFolderListItem.html @@ -1,9 +1,11 @@
diff --git a/snappymail/v/0.0.0/app/templates/Views/User/MailFolderListSystemItem.html b/snappymail/v/0.0.0/app/templates/Views/User/MailFolderListSystemItem.html index ee5abc573..1218b5427 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/MailFolderListSystemItem.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/MailFolderListSystemItem.html @@ -1,5 +1,5 @@