Much better fix for #175

And added some comments to it, to prevent more screw ups
This commit is contained in:
djmaze 2021-12-22 20:16:14 +01:00
parent 11547b575e
commit e244ba01de
6 changed files with 83 additions and 75 deletions

View file

@ -181,19 +181,20 @@ export class MessageFlagsCache
static initMessage(message) { static initMessage(message) {
if (message) { if (message) {
const uid = message.uid, const uid = message.uid,
flags = this.getFor(message.folder, uid); flags = this.getFor(message.folder, uid),
thread = message.threads;
if (isArray(flags)) { if (isArray(flags)) {
message.flags(flags); message.flags(flags);
} }
if (message.threads.length) { if (thread.length) {
const unseenSubUid = message.threads.find(sSubUid => const unseenSubUid = thread.find(iSubUid =>
(uid !== sSubUid) && !this.hasFlag(message.folder, sSubUid, '\\seen') (uid !== iSubUid) && !this.hasFlag(message.folder, iSubUid, '\\seen')
); );
const flaggedSubUid = message.threads.find(sSubUid => const flaggedSubUid = thread.find(iSubUid =>
(uid !== sSubUid) && this.hasFlag(message.folder, sSubUid, '\\flagged') (uid !== iSubUid) && this.hasFlag(message.folder, iSubUid, '\\flagged')
); );
message.hasUnseenSubMessage(!!unseenSubUid); message.hasUnseenSubMessage(!!unseenSubUid);

View file

@ -35,7 +35,7 @@ class RemoteUserFetch extends AbstractFetchRemote {
Offset: 0, Offset: 0,
Limit: SettingsUserStore.messagesPerPage(), Limit: SettingsUserStore.messagesPerPage(),
Search: '', Search: '',
UidNext: getFolderInboxName() === sFolderFullName ? getFolderUidNext(sFolderFullName) : '', UidNext: getFolderUidNext(sFolderFullName), // Used to check for new messages
Sort: FolderUserStore.sortMode(), Sort: FolderUserStore.sortMode(),
Hash: folderHash + SettingsGet('AccountHash') Hash: folderHash + SettingsGet('AccountHash')
}, params); }, params);
@ -104,11 +104,10 @@ class RemoteUserFetch extends AbstractFetchRemote {
* @param {Array=} list = [] * @param {Array=} list = []
*/ */
folderInformation(fCallback, folder, list = []) { folderInformation(fCallback, folder, list = []) {
let request = true; let fetch = !arrayLength(list);
const uids = []; const uids = [];
if (arrayLength(list)) { if (!fetch) {
request = false;
list.forEach(messageListItem => { list.forEach(messageListItem => {
if (!MessageFlagsCache.getFor(messageListItem.folder, messageListItem.uid)) { if (!MessageFlagsCache.getFor(messageListItem.folder, messageListItem.uid)) {
uids.push(messageListItem.uid); uids.push(messageListItem.uid);
@ -122,17 +121,14 @@ class RemoteUserFetch extends AbstractFetchRemote {
}); });
} }
}); });
fetch = uids.length;
if (uids.length) {
request = true;
}
} }
if (request) { if (fetch) {
this.request('FolderInformation', fCallback, { this.request('FolderInformation', fCallback, {
Folder: folder, Folder: folder,
FlagsUids: isArray(uids) ? uids : [], FlagsUids: uids,
UidNext: getFolderInboxName() === folder ? getFolderUidNext(folder) : 0 UidNext: getFolderUidNext(folder) // Used to check for new messages
}); });
} else if (SettingsUserStore.useThreads()) { } else if (SettingsUserStore.useThreads()) {
rl.app.reloadFlagsCurrentMessageListAndMessageFromCache(); rl.app.reloadFlagsCurrentMessageListAndMessageFromCache();

View file

@ -412,7 +412,7 @@ export const MessageUserStore = new class {
message.folder === json.Folder message.folder === json.Folder
) { ) {
const threads = message.threads(); 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); message = oMessage ? null : MessageModel.reviveFromJson(json);
if (message) { if (message) {
message.threads(threads); message.threads(threads);

View file

@ -544,13 +544,13 @@ class MailClient
$aFolderStatus = $this->oImapClient->FolderStatus($sFolderName, $aTypes); $aFolderStatus = $this->oImapClient->FolderStatus($sFolderName, $aTypes);
return [ 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(), $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 private function getFolderNextMessageInformation(string $sFolderName, int $iPrevUidNext, int $iCurrentUidNext) : array
{ {
$aNewMessages = array(); $aNewMessages = array();
if ($iPrevUidNext && $iPrevUidNext != $iCurrentUidNext) if ($iPrevUidNext && $iPrevUidNext != $iCurrentUidNext && 'INBOX' === $sFolderName && \MailSo\Config::$CheckNewMessages)
{ {
$this->oImapClient->FolderSelect($sFolderName); $this->oImapClient->FolderSelect($sFolderName);
@ -611,22 +615,15 @@ class MailClient
\MailSo\Mime\Enumerations\Parameter::CHARSET \MailSo\Mime\Enumerations\Parameter::CHARSET
); );
$sCharset = ''; if ($sContentTypeCharset) {
if (\strlen($sContentTypeCharset)) $oHeaders->SetParentCharset($sContentTypeCharset);
{
$sCharset = $sContentTypeCharset;
}
if (\strlen($sCharset))
{
$oHeaders->SetParentCharset($sCharset);
} }
$aNewMessages[] = array( $aNewMessages[] = array(
'Folder' => $sFolderName, 'Folder' => $sFolderName,
'Uid' => $iUid, 'Uid' => $iUid,
'Subject' => $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::SUBJECT, !\strlen($sCharset)), 'Subject' => $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::SUBJECT, !$sContentTypeCharset),
'From' => $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::FROM_, !\strlen($sCharset)) 'From' => $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::FROM_, !$sContentTypeCharset)
); );
} }
} }
@ -677,8 +674,7 @@ class MailClient
'HighestModSeq' => $iHighestModSeq, 'HighestModSeq' => $iHighestModSeq,
'AppendLimit' => $iAppendLimit, 'AppendLimit' => $iAppendLimit,
'MailboxId' => $sMailboxId, 'MailboxId' => $sMailboxId,
'NewMessages' => 'INBOX' === $sFolderName && \MailSo\Config::$CheckNewMessages ? 'NewMessages' => $this->getFolderNextMessageInformation($sFolderName, $iPrevUidNext, $iUidNext)
$this->getFolderNextMessageInformation($sFolderName, $iPrevUidNext, $iUidNext) : array()
); );
} }
@ -1017,7 +1013,7 @@ class MailClient
$oMessageCollection->UidNext = $iUidNext; $oMessageCollection->UidNext = $iUidNext;
if (!$oParams->iThreadUid && $oParams->iPrevUidNext && 'INBOX' === $oParams->sFolderName) if (!$oParams->iThreadUid)
{ {
$oMessageCollection->NewMessages = $this->getFolderNextMessageInformation( $oMessageCollection->NewMessages = $this->getFolderNextMessageInformation(
$oParams->sFolderName, $oParams->iPrevUidNext, $iUidNext); $oParams->sFolderName, $oParams->iPrevUidNext, $iUidNext);
@ -1033,14 +1029,12 @@ class MailClient
$bUseThreads = false; $bUseThreads = false;
} }
if (0 < $iMessageRealCount && !$bMessageListOptimization) if ($iMessageRealCount && !$bMessageListOptimization)
{ {
$aUids = $this->GetUids($oParams->oCacher, '',
$oMessageCollection->FolderName, $oMessageCollection->FolderHash, $bUseSortIfSupported, $oParams->sSort);
if ($bUseThreads) { if ($bUseThreads) {
$aAllThreads = $this->MessageListThreadsMap($oMessageCollection->FolderName, $oMessageCollection->FolderHash, $oParams->oCacher); $aAllThreads = $this->MessageListThreadsMap($oMessageCollection->FolderName, $oMessageCollection->FolderHash, $oParams->oCacher);
if (0 < $oParams->iThreadUid)
if ($oParams->iThreadUid)
{ {
$aUids = [$oParams->iThreadUid]; $aUids = [$oParams->iThreadUid];
// Only show the selected thread messages // Only show the selected thread messages
@ -1053,13 +1047,20 @@ class MailClient
} }
else else
{ {
// Show all threads $aUids = $this->GetUids($oParams->oCacher, '',
// $aUids = array(); $oMessageCollection->FolderName, $oMessageCollection->FolderHash, $bUseSortIfSupported, $oParams->sSort);
// \array_walk_recursive($aAllThreads, function($a) use (&$aUids) { $aUids[] = $a; }); // 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, $aSearchedUids = $this->GetUids($oParams->oCacher, $sSearch,
$oMessageCollection->FolderName, $oMessageCollection->FolderHash); $oMessageCollection->FolderName, $oMessageCollection->FolderHash);
@ -1084,26 +1085,19 @@ class MailClient
$aUids = \array_unique($aNewUids); $aUids = \array_unique($aNewUids);
unset($aNewUids); unset($aNewUids);
} }
else
{
$aUids = array();
}
} }
if (\is_array($aUids)) $oMessageCollection->MessageCount = $iMessageRealCount;
{ $oMessageCollection->MessageUnseenCount = $iMessageUnseenCount;
$oMessageCollection->MessageCount = $iMessageRealCount; $oMessageCollection->MessageResultCount = \count($aUids);
$oMessageCollection->MessageUnseenCount = $iMessageUnseenCount;
$oMessageCollection->MessageResultCount = \count($aUids);
if (\count($aUids)) if (\count($aUids))
{ {
$aRequestUids = \array_slice($aUids, $oParams->iOffset, $oParams->iLimit); $aRequestUids = \array_slice($aUids, $oParams->iOffset, $oParams->iLimit);
$this->MessageListByRequestIndexOrUids($oMessageCollection, $aRequestUids, true); $this->MessageListByRequestIndexOrUids($oMessageCollection, $aRequestUids, true);
}
} }
} }
else if (0 < $iMessageRealCount) else if ($iMessageRealCount)
{ {
if ($this->oLogger) if ($this->oLogger)
{ {
@ -1148,11 +1142,12 @@ class MailClient
} }
} }
if ($bUseThreads && !$oParams->iThreadUid && $aAllThreads) if ($aAllThreads && !$oParams->iThreadUid)
{ {
foreach ($oMessageCollection as $oMessage) { foreach ($oMessageCollection as $oMessage) {
$iUid = $oMessage->Uid(); $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) { foreach ($aAllThreads as $aMap) {
if (\in_array($iUid, $aMap)) { if (\in_array($iUid, $aMap)) {
$oMessage->SetThreads($aMap); $oMessage->SetThreads($aMap);

View file

@ -15,13 +15,29 @@ class MessageListParams
{ {
public public
$sFolderName, // string $sFolderName, // string
$iOffset = 0, // int
$iLimit = 10, // int
$sSearch = '', // string $sSearch = '', // string
$iPrevUidNext = 0, // int
$oCacher = null, // ?\MailSo\Cache\CacheClient $oCacher = null, // ?\MailSo\Cache\CacheClient
$bUseSortIfSupported = false, // bool $bUseSortIfSupported = false, // bool
$bUseThreads = false, // bool $bUseThreads = false, // bool
$iThreadUid = 0, // int
$sSort = ''; // string $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)
}
} }

View file

@ -26,29 +26,29 @@ trait Messages
// $oParams->sHash = (string) $aValues['Hash']; // $oParams->sHash = (string) $aValues['Hash'];
$oParams->sFolderName = (string) $aValues['Folder']; $oParams->sFolderName = (string) $aValues['Folder'];
$oParams->iLimit = (int) $aValues['Limit']; $oParams->iLimit = $aValues['Limit'];
$oParams->iOffset = (int) $aValues['Offset']; $oParams->iOffset = $aValues['Offset'];
$oParams->sSearch = (string) $aValues['Search']; $oParams->sSearch = (string) $aValues['Search'];
$oParams->sSort = (string) $aValues['Sort']; $oParams->sSort = (string) $aValues['Sort'];
if (isset($aValues['UidNext'])) { if (isset($aValues['UidNext'])) {
$oParams->iPrevUidNext = (int) $aValues['UidNext']; $oParams->iPrevUidNext = $aValues['UidNext'];
} }
$oParams->bUseThreads = !empty($aValues['UseThreads']); $oParams->bUseThreads = !empty($aValues['UseThreads']);
if ($oParams->bUseThreads && isset($aValues['ThreadUid'])) { if ($oParams->bUseThreads && isset($aValues['ThreadUid'])) {
$oParams->iThreadUid = (int) $aValues['ThreadUid']; $oParams->iThreadUid = $aValues['ThreadUid'];
} }
} }
else else
{ {
$oParams->sFolderName = $this->GetActionParam('Folder', ''); $oParams->sFolderName = $this->GetActionParam('Folder', '');
$oParams->iOffset = (int) $this->GetActionParam('Offset', 0); $oParams->iOffset = $this->GetActionParam('Offset', 0);
$oParams->iLimit = (int) $this->GetActionParam('Limit', 10); $oParams->iLimit = $this->GetActionParam('Limit', 10);
$oParams->sSearch = $this->GetActionParam('Search', ''); $oParams->sSearch = $this->GetActionParam('Search', '');
$oParams->sSort = $this->GetActionParam('Sort', ''); $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')); $oParams->bUseThreads = !empty($this->GetActionParam('UseThreads', '0'));
if ($oParams->bUseThreads) { if ($oParams->bUseThreads) {
$oParams->iThreadUid = (int) $this->GetActionParam('ThreadUid', ''); $oParams->iThreadUid = $this->GetActionParam('ThreadUid', '');
} }
} }