diff --git a/dev/Common/Cache.js b/dev/Common/Cache.js index 445e12988..c41c197b3 100644 --- a/dev/Common/Cache.js +++ b/dev/Common/Cache.js @@ -181,19 +181,20 @@ export class MessageFlagsCache static initMessage(message) { if (message) { const uid = message.uid, - flags = this.getFor(message.folder, uid); + flags = this.getFor(message.folder, uid), + thread = message.threads; if (isArray(flags)) { message.flags(flags); } - if (message.threads.length) { - const unseenSubUid = message.threads.find(sSubUid => - (uid !== sSubUid) && !this.hasFlag(message.folder, sSubUid, '\\seen') + if (thread.length) { + const unseenSubUid = thread.find(iSubUid => + (uid !== iSubUid) && !this.hasFlag(message.folder, iSubUid, '\\seen') ); - const flaggedSubUid = message.threads.find(sSubUid => - (uid !== sSubUid) && this.hasFlag(message.folder, sSubUid, '\\flagged') + const flaggedSubUid = thread.find(iSubUid => + (uid !== iSubUid) && this.hasFlag(message.folder, iSubUid, '\\flagged') ); message.hasUnseenSubMessage(!!unseenSubUid); diff --git a/dev/Remote/User/Fetch.js b/dev/Remote/User/Fetch.js index 00360e9d1..2a5524e95 100644 --- a/dev/Remote/User/Fetch.js +++ b/dev/Remote/User/Fetch.js @@ -35,7 +35,7 @@ class RemoteUserFetch extends AbstractFetchRemote { Offset: 0, Limit: SettingsUserStore.messagesPerPage(), Search: '', - UidNext: getFolderInboxName() === sFolderFullName ? getFolderUidNext(sFolderFullName) : '', + UidNext: getFolderUidNext(sFolderFullName), // Used to check for new messages Sort: FolderUserStore.sortMode(), Hash: folderHash + SettingsGet('AccountHash') }, params); @@ -104,11 +104,10 @@ class RemoteUserFetch extends AbstractFetchRemote { * @param {Array=} list = [] */ folderInformation(fCallback, folder, list = []) { - let request = true; + let fetch = !arrayLength(list); const uids = []; - if (arrayLength(list)) { - request = false; + if (!fetch) { list.forEach(messageListItem => { if (!MessageFlagsCache.getFor(messageListItem.folder, messageListItem.uid)) { uids.push(messageListItem.uid); @@ -122,17 +121,14 @@ class RemoteUserFetch extends AbstractFetchRemote { }); } }); - - if (uids.length) { - request = true; - } + fetch = uids.length; } - if (request) { + if (fetch) { this.request('FolderInformation', fCallback, { Folder: folder, - FlagsUids: isArray(uids) ? uids : [], - UidNext: getFolderInboxName() === folder ? getFolderUidNext(folder) : 0 + FlagsUids: uids, + UidNext: getFolderUidNext(folder) // Used to check for new messages }); } else if (SettingsUserStore.useThreads()) { rl.app.reloadFlagsCurrentMessageListAndMessageFromCache(); diff --git a/dev/Stores/User/Message.js b/dev/Stores/User/Message.js index 222da55ba..7699958de 100644 --- a/dev/Stores/User/Message.js +++ b/dev/Stores/User/Message.js @@ -412,7 +412,7 @@ export const MessageUserStore = new class { message.folder === json.Folder ) { const threads = message.threads(); - if (message.uid != json.Uid && 1 < threads.length && threads.includes(json.Uid)) { + if (message.uid != json.Uid && threads.includes(json.Uid)) { message = oMessage ? null : MessageModel.reviveFromJson(json); if (message) { message.threads(threads); 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 c7758dd51..f5091025d 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 @@ -544,13 +544,13 @@ class MailClient $aFolderStatus = $this->oImapClient->FolderStatus($sFolderName, $aTypes); return [ - $aFolderStatus[FolderResponseStatus::MESSAGES] ?: 0, + \max(0, $aFolderStatus[FolderResponseStatus::MESSAGES] ?: 0), - $aFolderStatus[FolderResponseStatus::UNSEEN] ?: 0, + \max(0, $aFolderStatus[FolderResponseStatus::UNSEEN] ?: 0), - $aFolderStatus[FolderResponseStatus::UIDNEXT] ?: 0, + \max(0, $aFolderStatus[FolderResponseStatus::UIDNEXT] ?: 0), - $aFolderStatus[FolderResponseStatus::HIGHESTMODSEQ] ?: 0, + \max(0, $aFolderStatus[FolderResponseStatus::HIGHESTMODSEQ] ?: 0), $aFolderStatus[FolderResponseStatus::APPENDLIMIT] ?: $this->oImapClient->AppendLimit(), @@ -575,11 +575,15 @@ class MailClient ); } + /** + * Returns list of new messages since $iPrevUidNext + * Currently only for INBOX + */ private function getFolderNextMessageInformation(string $sFolderName, int $iPrevUidNext, int $iCurrentUidNext) : array { $aNewMessages = array(); - if ($iPrevUidNext && $iPrevUidNext != $iCurrentUidNext) + if ($iPrevUidNext && $iPrevUidNext != $iCurrentUidNext && 'INBOX' === $sFolderName && \MailSo\Config::$CheckNewMessages) { $this->oImapClient->FolderSelect($sFolderName); @@ -611,22 +615,15 @@ class MailClient \MailSo\Mime\Enumerations\Parameter::CHARSET ); - $sCharset = ''; - if (\strlen($sContentTypeCharset)) - { - $sCharset = $sContentTypeCharset; - } - - if (\strlen($sCharset)) - { - $oHeaders->SetParentCharset($sCharset); + if ($sContentTypeCharset) { + $oHeaders->SetParentCharset($sContentTypeCharset); } $aNewMessages[] = array( 'Folder' => $sFolderName, 'Uid' => $iUid, - 'Subject' => $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::SUBJECT, !\strlen($sCharset)), - 'From' => $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::FROM_, !\strlen($sCharset)) + 'Subject' => $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::SUBJECT, !$sContentTypeCharset), + 'From' => $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::FROM_, !$sContentTypeCharset) ); } } @@ -677,8 +674,7 @@ class MailClient 'HighestModSeq' => $iHighestModSeq, 'AppendLimit' => $iAppendLimit, 'MailboxId' => $sMailboxId, - 'NewMessages' => 'INBOX' === $sFolderName && \MailSo\Config::$CheckNewMessages ? - $this->getFolderNextMessageInformation($sFolderName, $iPrevUidNext, $iUidNext) : array() + 'NewMessages' => $this->getFolderNextMessageInformation($sFolderName, $iPrevUidNext, $iUidNext) ); } @@ -1017,7 +1013,7 @@ class MailClient $oMessageCollection->UidNext = $iUidNext; - if (!$oParams->iThreadUid && $oParams->iPrevUidNext && 'INBOX' === $oParams->sFolderName) + if (!$oParams->iThreadUid) { $oMessageCollection->NewMessages = $this->getFolderNextMessageInformation( $oParams->sFolderName, $oParams->iPrevUidNext, $iUidNext); @@ -1033,14 +1029,12 @@ class MailClient $bUseThreads = false; } - if (0 < $iMessageRealCount && !$bMessageListOptimization) + if ($iMessageRealCount && !$bMessageListOptimization) { - $aUids = $this->GetUids($oParams->oCacher, '', - $oMessageCollection->FolderName, $oMessageCollection->FolderHash, $bUseSortIfSupported, $oParams->sSort); - if ($bUseThreads) { $aAllThreads = $this->MessageListThreadsMap($oMessageCollection->FolderName, $oMessageCollection->FolderHash, $oParams->oCacher); - if (0 < $oParams->iThreadUid) + + if ($oParams->iThreadUid) { $aUids = [$oParams->iThreadUid]; // Only show the selected thread messages @@ -1053,13 +1047,20 @@ class MailClient } else { - // Show all threads -// $aUids = array(); -// \array_walk_recursive($aAllThreads, function($a) use (&$aUids) { $aUids[] = $a; }); + $aUids = $this->GetUids($oParams->oCacher, '', + $oMessageCollection->FolderName, $oMessageCollection->FolderHash, $bUseSortIfSupported, $oParams->sSort); + // Remove all threaded UID's except the most recent of each thread + foreach ($aAllThreads as $aMap) { + unset($aMap[\array_key_last($aMap)]); + $aUids = \array_diff($aUids, $aMap); + } } + } else { + $aUids = $this->GetUids($oParams->oCacher, '', + $oMessageCollection->FolderName, $oMessageCollection->FolderHash, $bUseSortIfSupported, $oParams->sSort); } - if (\strlen($sSearch) && \is_array($aUids)) + if ($aUids && \strlen($sSearch)) { $aSearchedUids = $this->GetUids($oParams->oCacher, $sSearch, $oMessageCollection->FolderName, $oMessageCollection->FolderHash); @@ -1084,26 +1085,19 @@ class MailClient $aUids = \array_unique($aNewUids); unset($aNewUids); } - else - { - $aUids = array(); - } } - if (\is_array($aUids)) - { - $oMessageCollection->MessageCount = $iMessageRealCount; - $oMessageCollection->MessageUnseenCount = $iMessageUnseenCount; - $oMessageCollection->MessageResultCount = \count($aUids); + $oMessageCollection->MessageCount = $iMessageRealCount; + $oMessageCollection->MessageUnseenCount = $iMessageUnseenCount; + $oMessageCollection->MessageResultCount = \count($aUids); - if (\count($aUids)) - { - $aRequestUids = \array_slice($aUids, $oParams->iOffset, $oParams->iLimit); - $this->MessageListByRequestIndexOrUids($oMessageCollection, $aRequestUids, true); - } + if (\count($aUids)) + { + $aRequestUids = \array_slice($aUids, $oParams->iOffset, $oParams->iLimit); + $this->MessageListByRequestIndexOrUids($oMessageCollection, $aRequestUids, true); } } - else if (0 < $iMessageRealCount) + else if ($iMessageRealCount) { if ($this->oLogger) { @@ -1148,11 +1142,12 @@ class MailClient } } - if ($bUseThreads && !$oParams->iThreadUid && $aAllThreads) + if ($aAllThreads && !$oParams->iThreadUid) { foreach ($oMessageCollection as $oMessage) { $iUid = $oMessage->Uid(); - // Find thread + // Find thread and set it. + // Used by GUI to delete/move the whole thread or other features foreach ($aAllThreads as $aMap) { if (\in_array($iUid, $aMap)) { $oMessage->SetThreads($aMap); diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MessageListParams.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MessageListParams.php index b7845cb2d..016fc47e9 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MessageListParams.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MessageListParams.php @@ -15,13 +15,29 @@ class MessageListParams { public $sFolderName, // string - $iOffset = 0, // int - $iLimit = 10, // int $sSearch = '', // string - $iPrevUidNext = 0, // int $oCacher = null, // ?\MailSo\Cache\CacheClient $bUseSortIfSupported = false, // bool $bUseThreads = false, // bool - $iThreadUid = 0, // int $sSort = ''; // string + + protected + $iOffset = 0, + $iLimit = 10, + $iPrevUidNext = 0, // used to check for new messages + $iThreadUid = 0; + + public function __get($k) + { + return \property_exists($this, $k) ? $this->$k : null; + } + + public function __set($k, $v) + { + if ('i' === $k[0]) { + $this->$k = \max(0, (int) $v); + } +// \MailSo\Base\Validator::RangeInt($oParams->iOffset, 0) +// \MailSo\Base\Validator::RangeInt($oParams->iLimit, 0, 999) + } } diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Messages.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Messages.php index ef925f26a..b471abcfa 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Messages.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Messages.php @@ -26,29 +26,29 @@ trait Messages // $oParams->sHash = (string) $aValues['Hash']; $oParams->sFolderName = (string) $aValues['Folder']; - $oParams->iLimit = (int) $aValues['Limit']; - $oParams->iOffset = (int) $aValues['Offset']; + $oParams->iLimit = $aValues['Limit']; + $oParams->iOffset = $aValues['Offset']; $oParams->sSearch = (string) $aValues['Search']; $oParams->sSort = (string) $aValues['Sort']; if (isset($aValues['UidNext'])) { - $oParams->iPrevUidNext = (int) $aValues['UidNext']; + $oParams->iPrevUidNext = $aValues['UidNext']; } $oParams->bUseThreads = !empty($aValues['UseThreads']); if ($oParams->bUseThreads && isset($aValues['ThreadUid'])) { - $oParams->iThreadUid = (int) $aValues['ThreadUid']; + $oParams->iThreadUid = $aValues['ThreadUid']; } } else { $oParams->sFolderName = $this->GetActionParam('Folder', ''); - $oParams->iOffset = (int) $this->GetActionParam('Offset', 0); - $oParams->iLimit = (int) $this->GetActionParam('Limit', 10); + $oParams->iOffset = $this->GetActionParam('Offset', 0); + $oParams->iLimit = $this->GetActionParam('Limit', 10); $oParams->sSearch = $this->GetActionParam('Search', ''); $oParams->sSort = $this->GetActionParam('Sort', ''); - $oParams->iPrevUidNext = (int) $this->GetActionParam('UidNext', 0); + $oParams->iPrevUidNext = $this->GetActionParam('UidNext', 0); $oParams->bUseThreads = !empty($this->GetActionParam('UseThreads', '0')); if ($oParams->bUseThreads) { - $oParams->iThreadUid = (int) $this->GetActionParam('ThreadUid', ''); + $oParams->iThreadUid = $this->GetActionParam('ThreadUid', ''); } }