From 26fb2cf9fbdf279669723adc86f5cda3ba0fbdcb Mon Sep 17 00:00:00 2001 From: the-djmaze <> Date: Tue, 30 May 2023 16:02:41 +0200 Subject: [PATCH] Resolve #1028 --- dev/Model/Message.js | 11 ++--- dev/Styles/User/MessageList.less | 13 ++---- .../app/libraries/MailSo/Mail/MailClient.php | 40 ++++++++++++++----- .../app/libraries/MailSo/Mail/Message.php | 21 +++++++--- .../MailSo/Mail/MessageListParams.php | 4 +- .../templates/Views/User/MailMessageList.html | 2 +- 6 files changed, 56 insertions(+), 35 deletions(-) diff --git a/dev/Model/Message.js b/dev/Model/Message.js index a878505b5..0288b6063 100644 --- a/dev/Model/Message.js +++ b/dev/Model/Message.js @@ -113,14 +113,12 @@ export class MessageModel extends AbstractModel { // rfc8621 id: '', -// threadId: '', - - hasUnseenSubMessage: false, - hasFlaggedSubMessage: false +// threadId: '' }); this.attachments = ko.observableArray(new AttachmentCollectionModel); this.threads = ko.observableArray(); + this.threadUnseen = ko.observableArray(); this.unsubsribeLinks = ko.observableArray(); this.flags = ko.observableArray(); @@ -128,6 +126,7 @@ export class MessageModel extends AbstractModel { attachmentIconClass: () => this.encrypted() ? 'icon-lock' : FileInfo.getAttachmentsIconClass(this.attachments()), threadsLen: () => rl.app.messageList.threadUid() ? 0 : this.threads().length, + threadUnseenLen: () => rl.app.messageList.threadUid() ? 0 : this.threadUnseen().length, isUnseen: () => !this.flags().includes('\\seen'), isFlagged: () => this.flags().includes('\\flagged'), @@ -238,9 +237,7 @@ export class MessageModel extends AbstractModel { focused: this.focused(), priorityHigh: this.priority() === 1, withAttachments: !!this.attachments().length, - // hasChildrenMessage: 1 < this.threadsLen(), - hasUnseenSubMessage: this.hasUnseenSubMessage(), - hasFlaggedSubMessage: this.hasFlaggedSubMessage() + // hasChildrenMessage: 1 < this.threadsLen() }, (key, value) => value && classes.push(key)); flags && this.flags().forEach(value => classes.push('msgflag-'+value)); return classes.join(' '); diff --git a/dev/Styles/User/MessageList.less b/dev/Styles/User/MessageList.less index bd41e37a5..76942f4e0 100644 --- a/dev/Styles/User/MessageList.less +++ b/dev/Styles/User/MessageList.less @@ -289,16 +289,6 @@ margin-right: 0.25em; } - &.hasUnseenSubMessage { - background-color: rgba(255, 255, 64, 0.15); - border-left-color: lighten(orange, 30%); - border-right-color: lighten(orange, 30%) !important; - &.focused { - border-left-color: darken(orange, 10%); - border-right-color: darken(orange, 10%) !important; - } - } - &.unseen { background-color: rgba(255, 255, 64, 0.15); border-left-color: orange; @@ -312,6 +302,9 @@ border-right-color: darken(orange, 10%) !important; } } + [data-unseen] { + background-color: rgba(255, 255, 64, 0.15); + } &.checked { border-left-color: lighten(#398CF2, 10%); 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 96143b7d6..64f534bf7 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 @@ -446,7 +446,8 @@ class MailClient * @throws \MailSo\Net\Exceptions\* * @throws \MailSo\Imap\Exceptions\* */ - protected function MessageListByRequestIndexOrUids(MessageCollection $oMessageCollection, SequenceSet $oRange, array &$aAllThreads = []) : void + protected function MessageListByRequestIndexOrUids(MessageCollection $oMessageCollection, SequenceSet $oRange, + array &$aAllThreads = [], array &$aUnseenUIDs = []) : void { if (\count($oRange)) { $aFetchIterator = $this->oImapClient->FetchIterate(array( @@ -472,6 +473,7 @@ class MailClient foreach ($aAllThreads as $aMap) { if (\in_array($iUid, $aMap)) { $oMessage->SetThreads($aMap); + $oMessage->SetThreadUnseen(\array_values(\array_intersect($aUnseenUIDs, $aMap))); break; } } @@ -490,7 +492,7 @@ class MailClient * @throws \MailSo\Imap\Exceptions\* */ private function GetUids(MessageListParams $oParams, string $sSearch, - string $sFolderHash, bool $bUseSort = false) : array + FolderInformation $oInfo, bool $bUseSort = false) : array { $oCacher = $oParams->oCacher; $sFolderName = $oParams->sFolderName; @@ -562,7 +564,7 @@ class MailClient if (!empty($sSerialized)) { $aSerialized = \json_decode($sSerialized, true); if (\is_array($aSerialized) && isset($aSerialized['FolderHash'], $aSerialized['Uids']) && - $sFolderHash === $aSerialized['FolderHash'] && + $oInfo->etag === $aSerialized['FolderHash'] && \is_array($aSerialized['Uids']) ) { $this->logWrite('Get Serialized '.($bReturnUid?'UIDS':'IDS').' from cache ('.$sSerializedLog.') [count:'.\count($aSerialized['Uids']).']'); @@ -594,7 +596,7 @@ class MailClient if ($bUseCacheAfterSearch) { $oCacher->Set($sSerializedHash, \json_encode(array( - 'FolderHash' => $sFolderHash, + 'FolderHash' => $oInfo->etag, 'Uids' => $aResultUids ))); @@ -604,6 +606,23 @@ class MailClient return $aResultUids; } + public function MessageListUnseen(MessageListParams $oParams, FolderInformation $oInfo) : array + { + $oUnseenParams = new MessageListParams; + $oUnseenParams->sFolderName = $oParams->sFolderName; +// $oUnseenParams->sSearch = $oParams->sSearch; +// $oUnseenParams->sSort = $oParams->sSort; + $oUnseenParams->oCacher = $oParams->oCacher; + $oUnseenParams->bUseSort = false; // $oParams->bUseSort + $oUnseenParams->bUseThreads = false; // $oParams->bUseThreads; + $oUnseenParams->bHideDeleted = $oParams->bHideDeleted; +// $oUnseenParams->iOffset = $oParams->iOffset; +// $oUnseenParams->iLimit = $oParams->iLimit; +// $oUnseenParams->iPrevUidNext = $oParams->iPrevUidNext; +// $oUnseenParams->iThreadUid = $oParams->iThreadUid; + return $this->GetUids($oUnseenParams, 'unseen', $oInfo); + } + /** * Runs SORT/SEARCH when $sSearch is provided * @throws \InvalidArgumentException @@ -646,6 +665,7 @@ class MailClient if ($oInfo->MESSAGES) { $bUseSort = $oParams->bUseSort || $oParams->sSort; $aAllThreads = []; + $aUnseenUIDs = []; $aUids = []; $message_list_limit = $this->oImapClient->Settings->message_list_limit; @@ -657,7 +677,7 @@ class MailClient $this->logWrite('List optimization (count: '.$oInfo->MESSAGES.', limit:'.$message_list_limit.')'); if (\strlen($sSearch)) { // Don't use SORT for speed - $aUids = $this->GetUids($oParams, $sSearch, $oInfo->etag/*, $bUseSort*/); + $aUids = $this->GetUids($oParams, $sSearch, $oInfo/*, $bUseSort*/); } else { $bUseSort = $this->oImapClient->hasCapability('SORT'); if (2 > $oInfo->MESSAGES) { @@ -667,7 +687,7 @@ class MailClient $end = \min($oInfo->MESSAGES, \max(1, $oInfo->MESSAGES - $oParams->iOffset + $oParams->iLimit)); $start = \max(1, $end - ($oParams->iLimit * 3) + 1); $oParams->oSequenceSet = new SequenceSet(\range($end, $start), false); - $aRequestIndexes = $this->GetUids($oParams, '', $oInfo->etag, $bUseSort); + $aRequestIndexes = $this->GetUids($oParams, '', $oInfo, $bUseSort); // Attempt to get the correct $oParams->iLimit slice $aRequestIndexes = \array_slice($aRequestIndexes, $oParams->iOffset ? $oParams->iLimit : 0, $oParams->iLimit); } else { @@ -681,7 +701,7 @@ class MailClient } else { $aUids = ($bUseThreads && $oParams->iThreadUid) ? [$oParams->iThreadUid] - : $this->GetUids($oParams, '', $oInfo->etag, $bUseSort); + : $this->GetUids($oParams, '', $oInfo, $bUseSort); if ($bUseThreads) { $aAllThreads = $this->MessageListThreadsMap($oMessageCollection, $oParams->oCacher); @@ -706,11 +726,13 @@ class MailClient $threadedUids = \array_merge($threadedUids, $aMap); } $aUids = \array_diff($aUids, $threadedUids); + // Get all unseen + $aUnseenUIDs = $this->MessageListUnseen($oParams, $oInfo); } } if ($aUids && \strlen($sSearch)) { - $aSearchedUids = $this->GetUids($oParams, $sSearch, $oInfo->etag/*, $bUseSort*/); + $aSearchedUids = $this->GetUids($oParams, $sSearch, $oInfo/*, $bUseSort*/); if ($bUseThreads && !$oParams->iThreadUid) { $matchingThreadUids = []; foreach ($aAllThreads as $aMap) { @@ -732,7 +754,7 @@ class MailClient if (\count($aUids)) { $oMessageCollection->totalEmails = \count($aUids); $aUids = \array_slice($aUids, $oParams->iOffset, $oParams->iLimit); - $this->MessageListByRequestIndexOrUids($oMessageCollection, new SequenceSet($aUids), $aAllThreads); + $this->MessageListByRequestIndexOrUids($oMessageCollection, new SequenceSet($aUids), $aAllThreads, $aUnseenUIDs); } } else { $this->logWrite('No messages in '.$oMessageCollection->FolderName); diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Message.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Message.php index 252438df1..26bece670 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Message.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Message.php @@ -69,7 +69,8 @@ class Message implements \JsonSerializable // $aFlags = [], $aFlagsLowerCase = [], $UnsubsribeLinks = [], - $aThreads = []; + $aThreadUIDs = [], + $aThreadUnseenUIDs = []; private ?array $DraftInfo = null; private ?array $pgpSigned = null; @@ -117,9 +118,14 @@ class Message implements \JsonSerializable $this->SpamScore = \intval(\max(0, \min(100, $value))); } - public function SetThreads(array $aThreads) + public function SetThreads(array $aThreadUIDs) { - $this->aThreads = $aThreads; + $this->aThreadUIDs = $aThreadUIDs; + } + + public function SetThreadUnseen(array $aUnseenUIDs) + { + $this->aThreadUnseenUIDs = $aUnseenUIDs; } public static function fromFetchResponse(string $sFolder, \MailSo\Imap\FetchResponse $oFetchResponse, ?\MailSo\Imap\BodyStructure $oBodyStructure = null) : self @@ -456,7 +462,7 @@ class Message implements \JsonSerializable $this->sFolder, $this->Uid, \implode(',', $this->getFlags()), -// \implode(',', $this->aThreads), +// \implode(',', $this->aThreadUIDs), $sClientHash ])); } @@ -576,8 +582,11 @@ class Message implements \JsonSerializable $result['pgpEncrypted'] = $this->pgpEncrypted; } - if ($this->aThreads) { - $result['threads'] = $this->aThreads; + if ($this->aThreadUIDs) { + $result['threads'] = $this->aThreadUIDs; + } + if ($this->aThreadUnseenUIDs) { + $result['threadUnseen'] = $this->aThreadUnseenUIDs; } return $result; 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 d3b622ff4..14686c83d 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 @@ -27,8 +27,8 @@ class MessageListParams $bHideDeleted = true; protected int - $iOffset, - $iLimit, + $iOffset = 0, + $iLimit = 0, $iPrevUidNext = 0, // used to check for new messages $iThreadUid = 0; diff --git a/snappymail/v/0.0.0/app/templates/Views/User/MailMessageList.html b/snappymail/v/0.0.0/app/templates/Views/User/MailMessageList.html index 913a95ea7..971bdeea1 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/MailMessageList.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/MailMessageList.html @@ -139,7 +139,7 @@
- +