This commit is contained in:
the-djmaze 2023-05-30 16:02:41 +02:00
parent 1f8fddd3f4
commit 26fb2cf9fb
6 changed files with 56 additions and 35 deletions

View file

@ -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(' ');

View file

@ -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%);

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -139,7 +139,7 @@
<div class="flagParent fontastic"></div>
<div class="senderParent actionHandle" data-bind="attr: {'title': senderClearEmailsString}, text: senderEmailsString"></div>
<div class="subjectParent actionHandle" data-bind="text: subject"></div>
<div class="threads-len" data-bind="visible: 1 < threadsLen(), text: threadsLen"></div>
<div class="threads-len" data-bind="visible: 1 < threadsLen(), text: threadsLen, attr: {'data-unseen': threadUnseenLen() || null}"></div>
<div class="attachmentParent actionHandle">
<i data-bind="css: attachmentIconClass"></i>
</div>