diff --git a/dev/Common/Cache.js b/dev/Common/Cache.js index 9a56ccbdf..fedaf0ec4 100644 --- a/dev/Common/Cache.js +++ b/dev/Common/Cache.js @@ -34,28 +34,26 @@ export const setFolderInboxName = name => inboxFolderName = name, /** - * @param {string} folderHash + * @param {string} fullNameHash * @returns {string} */ - getFolderFullName = folderHash => (folderHash && FOLDERS_NAME_CACHE[folderHash]) || '', + getFolderFullName = fullNameHash => (fullNameHash && FOLDERS_NAME_CACHE[fullNameHash]) || '', /** - * @param {string} folderHash - * @param {string} folderFullName * @param {?FolderModel} folder */ setFolder = folder => { - folder.hash = ''; + folder.etag = ''; FOLDERS_CACHE[folder.fullName] = folder; FOLDERS_NAME_CACHE[folder.fullNameHash] = folder.fullName; }, /** * @param {string} folderFullName - * @param {string} folderHash + * @param {string} folderETag */ - setFolderHash = (folderFullName, folderHash) => - FOLDERS_CACHE[folderFullName] && (FOLDERS_CACHE[folderFullName].hash = folderHash), + setFolderETag = (folderFullName, folderETag) => + FOLDERS_CACHE[folderFullName] && (FOLDERS_CACHE[folderFullName].etag = folderETag), /** * @param {string} folderFullName diff --git a/dev/Common/Folders.js b/dev/Common/Folders.js index 2802940f0..e255ac1f9 100644 --- a/dev/Common/Folders.js +++ b/dev/Common/Folders.js @@ -1,7 +1,7 @@ import { isArray, arrayLength } from 'Common/Utils'; import { MessageFlagsCache, - setFolderHash, + setFolderETag, getFolderInboxName, getFolderFromCacheList } from 'Common/Cache'; @@ -126,13 +126,13 @@ folderInformation = (folder, list) => { const result = data.Result, folderFromCache = getFolderFromCacheList(result.folder); if (folderFromCache) { - const oldHash = folderFromCache.hash, + const oldHash = folderFromCache.etag, unreadCountChange = (folderFromCache.unreadEmails() !== result.unreadEmails); // folderFromCache.revivePropertiesFromJson(result); folderFromCache.expires = Date.now(); folderFromCache.uidNext = result.uidNext; - folderFromCache.hash = result.hash; + folderFromCache.etag = result.etag; folderFromCache.totalEmails(result.totalEmails); folderFromCache.unreadEmails(result.unreadEmails); @@ -148,7 +148,7 @@ folderInformation = (folder, list) => { MessagelistUserStore.notifyNewMessages(folderFromCache.fullName, result.newMessages); - if (!oldHash || unreadCountChange || result.hash !== oldHash) { + if (!oldHash || unreadCountChange || result.etag !== oldHash) { if (folderFromCache.fullName === FolderUserStore.currentFolderFullName()) { MessagelistUserStore.reload(); /* @@ -181,21 +181,21 @@ folderInformationMultiply = (boot = false) => { if (!iError && arrayLength(oData.Result)) { const utc = Date.now(); oData.Result.forEach(item => { - const folder = getFolderFromCacheList(item.folder); + const folder = getFolderFromCacheList(item.name); if (folder) { - const oldHash = folder.hash, + const oldHash = folder.etag, unreadCountChange = folder.unreadEmails() !== item.unreadEmails; // folder.revivePropertiesFromJson(item); folder.expires = utc; - folder.hash = item.hash; + folder.etag = item.etag; folder.totalEmails(item.totalEmails); folder.unreadEmails(item.unreadEmails); unreadCountChange && MessageFlagsCache.clearFolder(folder.fullName); - if (!oldHash || item.hash !== oldHash) { + if (!oldHash || item.etag !== oldHash) { if (folder.fullName === FolderUserStore.currentFolderFullName()) { MessagelistUserStore.reload(); } @@ -217,13 +217,13 @@ folderInformationMultiply = (boot = false) => { moveOrDeleteResponseHelper = (iError, oData) => { if (iError) { - setFolderHash(FolderUserStore.currentFolderFullName(), ''); + setFolderETag(FolderUserStore.currentFolderFullName(), ''); alert(getNotification(iError)); } else if (FolderUserStore.currentFolder()) { if (2 === arrayLength(oData.Result)) { - setFolderHash(oData.Result[0], oData.Result[1]); + setFolderETag(oData.Result[0], oData.Result[1]); } else { - setFolderHash(FolderUserStore.currentFolderFullName(), ''); + setFolderETag(FolderUserStore.currentFolderFullName(), ''); } MessagelistUserStore.reload(!MessagelistUserStore.length); } diff --git a/dev/Model/FolderCollection.js b/dev/Model/FolderCollection.js index e94de8ff4..badab8798 100644 --- a/dev/Model/FolderCollection.js +++ b/dev/Model/FolderCollection.js @@ -127,8 +127,8 @@ export class FolderCollectionModel extends AbstractCollectionModel let oCacheFolder = getFolderFromCacheList(oFolder.fullName); if (oCacheFolder) { // oCacheFolder.revivePropertiesFromJson(oFolder); - if (oFolder.hash) { - oCacheFolder.hash = oFolder.hash; + if (oFolder.etag) { + oCacheFolder.etag = oFolder.etag; } if (null != oFolder.totalEmails) { oCacheFolder.totalEmails(oFolder.totalEmails); @@ -300,7 +300,7 @@ export class FolderModel extends AbstractModel { this.exists = true; - this.hash = ''; + this.etag = ''; this.id = 0; this.uidNext = 0; diff --git a/dev/Model/MessageCollection.js b/dev/Model/MessageCollection.js index a3be0fb6b..e7127c211 100644 --- a/dev/Model/MessageCollection.js +++ b/dev/Model/MessageCollection.js @@ -13,17 +13,16 @@ export class MessageCollectionModel extends AbstractCollectionModel /* constructor() { super(); - this.Filtered + this.filtered this.folder - this.folderHash - this.folderInfo this.totalEmails - this.unreadEmails + this.totalThreads this.threadUid this.newMessages this.offset this.limit this.search + this.limited } */ diff --git a/dev/Remote/User/Fetch.js b/dev/Remote/User/Fetch.js index e93cd9d19..f9a02143e 100644 --- a/dev/Remote/User/Fetch.js +++ b/dev/Remote/User/Fetch.js @@ -24,7 +24,7 @@ class RemoteUserFetch extends AbstractFetchRemote { const // folder = getFolderFromCacheList(params.folder.fullName), folder = getFolderFromCacheList(params.folder), - folderHash = folder?.hash || ''; + folderETag = folder?.etag || ''; params = Object.assign({ offset: 0, @@ -40,8 +40,8 @@ class RemoteUserFetch extends AbstractFetchRemote { } let sGetAdd = ''; - if (folderHash) { - params.hash = folderHash + '-' + SettingsGet('AccountHash'); + if (folderETag) { + params.hash = folderETag + '-' + SettingsGet('AccountHash'); sGetAdd = 'MessageList/' + SUB_QUERY_PREFIX + '/' + b64EncodeJSONSafe(params); params = {}; } diff --git a/dev/Stores/User/Messagelist.js b/dev/Stores/User/Messagelist.js index 469efeaac..1e7739bc1 100644 --- a/dev/Stores/User/Messagelist.js +++ b/dev/Stores/User/Messagelist.js @@ -10,7 +10,7 @@ import { UNUSED_OPTION_VALUE } from 'Common/Consts'; import { getFolderInboxName, getFolderFromCacheList, - setFolderHash, + setFolderETag, MessageFlagsCache } from 'Common/Cache'; @@ -174,7 +174,7 @@ MessagelistUserStore.reload = (bDropPagePosition = false, bDropCurrentFolderCach let iOffset = (MessagelistUserStore.page() - 1) * SettingsUserStore.messagesPerPage(); if (bDropCurrentFolderCache) { - setFolderHash(FolderUserStore.currentFolderFullName(), ''); + setFolderETag(FolderUserStore.currentFolderFullName(), ''); } if (bDropPagePosition) { @@ -207,13 +207,14 @@ MessagelistUserStore.reload = (bDropPagePosition = false, bDropCurrentFolderCach error = ''; const - folder = getFolderFromCacheList(collection.folder), - folderInfo = collection.folderInfo; + folderInfo = collection.folder, + folder = getFolderFromCacheList(folderInfo.name); + collection.folder = folderInfo.name; if (folder && !bCached) { // folder.revivePropertiesFromJson(result); folder.expires = Date.now(); folder.uidNext = folderInfo.uidNext; - folder.hash = collection.folderHash; + folder.etag = folderInfo.etag; if (null != folderInfo.totalEmails) { folder.totalEmails(folderInfo.totalEmails); @@ -251,14 +252,14 @@ MessagelistUserStore.reload = (bDropPagePosition = false, bDropCurrentFolderCach MessagelistUserStore.threadUid(collection.threadUid); MessagelistUserStore.endHash( - collection.folder + + folderInfo.name + '|' + collection.search + '|' + MessagelistUserStore.threadUid() + '|' + MessagelistUserStore.page() ); MessagelistUserStore.endThreadUid(collection.threadUid); const message = MessageUserStore.message(); - if (message && collection.folder !== message.folder) { + if (message && folderInfo.name !== message.folder) { MessageUserStore.message(null); } @@ -370,7 +371,7 @@ MessagelistUserStore.removeMessagesFromList = ( messages.forEach(item => item?.isUnseen() && ++unseenCount); if (fromFolder) { - fromFolder.hash = ''; + fromFolder.etag = ''; if (!copy) { fromFolder.totalEmails( 0 <= fromFolder.totalEmails() - oUids.size ? fromFolder.totalEmails() - oUids.size : 0 @@ -385,7 +386,7 @@ MessagelistUserStore.removeMessagesFromList = ( } if (toFolder) { - toFolder.hash = ''; + toFolder.etag = ''; if (trashFolder === toFolder.fullName || spamFolder === toFolder.fullName) { unseenCount = 0; diff --git a/dev/View/Popup/Compose.js b/dev/View/Popup/Compose.js index 3e3131e75..4a8850896 100644 --- a/dev/View/Popup/Compose.js +++ b/dev/View/Popup/Compose.js @@ -19,7 +19,7 @@ import { UNUSED_OPTION_VALUE } from 'Common/Consts'; import { folderInformation, messagesDeleteHelper } from 'Common/Folders'; import { serverRequest } from 'Common/Links'; import { i18n, getNotification, getUploadErrorDescByCode, timestampToString } from 'Common/Translator'; -import { MessageFlagsCache, setFolderHash } from 'Common/Cache'; +import { MessageFlagsCache, setFolderETag } from 'Common/Cache'; import { Settings, SettingsCapa, SettingsGet, elementById, addShortcut, createElement } from 'Common/Globals'; //import { exitFullscreen, isFullscreen, toggleFullscreen } from 'Common/Fullscreen'; @@ -72,7 +72,7 @@ const reloadDraftFolder = () => { const draftsFolder = FolderUserStore.draftsFolder(); if (draftsFolder && UNUSED_OPTION_VALUE !== draftsFolder) { - setFolderHash(draftsFolder, ''); + setFolderETag(draftsFolder, ''); if (FolderUserStore.currentFolderFullName() === draftsFolder) { MessagelistUserStore.reload(true); } else { @@ -447,7 +447,7 @@ export class ComposePopupView extends AbstractViewPopup { flagsCache.push(('forward' === this.aDraftInfo[0]) ? '$forwarded' : '\\answered'); MessageFlagsCache.setFor(this.aDraftInfo[2], this.aDraftInfo[1], flagsCache); MessagelistUserStore.reloadFlagsAndCachedMessage(); - setFolderHash(this.aDraftInfo[2], ''); + setFolderETag(this.aDraftInfo[2], ''); } } @@ -469,8 +469,8 @@ export class ComposePopupView extends AbstractViewPopup { } else { this.close(); } - setFolderHash(this.draftsFolder(), ''); - setFolderHash(sSentFolder, ''); + setFolderETag(this.draftsFolder(), ''); + setFolderETag(sSentFolder, ''); reloadDraftFolder(); }, params, @@ -523,9 +523,9 @@ export class ComposePopupView extends AbstractViewPopup { this.savedTime(new Date); if (this.bFromDraft) { - setFolderHash(this.draftsFolder(), ''); + setFolderETag(this.draftsFolder(), ''); } - setFolderHash(FolderUserStore.draftsFolder(), ''); + setFolderETag(FolderUserStore.draftsFolder(), ''); } } diff --git a/dev/View/User/MailBox/FolderList.js b/dev/View/User/MailBox/FolderList.js index 3acab9bd1..e1ebd9cd4 100644 --- a/dev/View/User/MailBox/FolderList.js +++ b/dev/View/User/MailBox/FolderList.js @@ -3,7 +3,7 @@ import ko from 'ko'; import { Scope } from 'Common/Enums'; import { addShortcut } from 'Common/Globals'; import { mailBox, settings } from 'Common/Links'; -//import { setFolderHash } from 'Common/Cache'; +//import { setFolderETag } from 'Common/Cache'; import { addComputablesTo } from 'External/ko'; import { AppUserStore } from 'Stores/User/App'; @@ -105,7 +105,7 @@ export class MailFolderList extends AbstractViewLeft { } /* if (folder.fullName === FolderUserStore.currentFolderFullName()) { - setFolderHash(folder.fullName, ''); + setFolderETag(folder.fullName, ''); } */ let search = ''; diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php index 920150ca5..9037f36ae 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Folder.php @@ -159,7 +159,7 @@ class Folder implements \JsonSerializable public function Hash(string $sClientHash) : ?string { - return $this->getHash($sClientHash); + return $this->getETag($sClientHash); } #[\ReturnTypeWillChange] @@ -172,7 +172,7 @@ class Folder implements \JsonSerializable 'totalEmails' => (int) $this->MESSAGES, 'unreadEmails' => (int) $this->UNSEEN, 'uidNext' => (int) $this->UIDNEXT, -// 'hash' => $this->Hash($this->ImapClient()->Hash()) +// 'etag' => $this->Hash($this->ImapClient()->Hash()) ); } */ diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/FolderInformation.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/FolderInformation.php index a853d191b..db1f902cc 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/FolderInformation.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/FolderInformation.php @@ -19,6 +19,8 @@ class FolderInformation implements \JsonSerializable { use Traits\Status; + public string $etag = ''; + public bool $IsWritable; /** @@ -37,6 +39,11 @@ class FolderInformation implements \JsonSerializable $this->IsWritable = $bIsWritable; } + public function generateETag(ImapClient $oImapClient) : void + { + $this->etag = $this->getETag($oImapClient->Hash()); + } + public function IsFlagSupported(string $sFlag) : bool { return \in_array('\\*', $this->PermanentFlags) || @@ -68,6 +75,9 @@ class FolderInformation implements \JsonSerializable if (isset($this->SIZE)) { $result['size'] = $this->SIZE; } + if (isset($this->etag)) { + $result['etag'] = $this->etag; + } return $result; } } diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Traits/Status.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Traits/Status.php index b7e948468..d2b46d2e2 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Traits/Status.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Traits/Status.php @@ -94,7 +94,7 @@ trait Status */ $SIZE; - public function getHash(string $sClientHash) : ?string + public function getETag(string $sClientHash) : ?string { if (!isset($this->MESSAGES, $this->UIDNEXT)) { return null; 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 3921e5f8e..a907638cc 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 @@ -378,7 +378,7 @@ class MailClient 'mailboxId' => $oInfo->MAILBOXID ?: '', // 'flags' => $oInfo->Flags, // 'permanentFlags' => $oInfo->PermanentFlags, - 'hash' => $oInfo->getHash($this->oImapClient->Hash()), + 'etag' => $oInfo->getETag($this->oImapClient->Hash()), 'messagesFlags' => $aFlags, 'newMessages' => $this->getFolderNextMessageInformation( $sFolderName, @@ -396,7 +396,8 @@ class MailClient */ public function FolderHash(string $sFolderName) : string { - return $this->oImapClient->FolderStatus($sFolderName)->getHash($this->oImapClient->Hash()); + return $this->oImapClient->FolderStatus($sFolderName)->getETag($this->oImapClient->Hash()); +// return $this->oImapClient->FolderStatusAndSelect($sFolderName)->getETag($this->oImapClient->Hash()); } /** @@ -420,8 +421,8 @@ class MailClient $sSerializedHashKey = null; if ($oCacher && $oCacher->IsInited()) { $sSerializedHashKey = - "ThreadsMapSorted/{$sSearch}/{$sFolderName}/{$oMessageCollection->FolderHash}"; -// "ThreadsMapSorted/{$sSearch}/{$iThreadLimit}/{$sFolderName}/{$oMessageCollection->FolderHash}"; + "ThreadsMapSorted/{$sSearch}/{$sFolderName}/{$oMessageCollection->FolderInfo->etag}"; +// "ThreadsMapSorted/{$sSearch}/{$iThreadLimit}/{$sFolderName}/{$oMessageCollection->FolderInfo->etag}"; if ($this->oLogger) { $this->oLogger->Write($sSerializedHashKey); @@ -668,7 +669,7 @@ class MailClient throw new \InvalidArgumentException('THREAD not supported'); } - $oMessageCollection->FolderHash = $oInfo->getHash($this->oImapClient->Hash()); + $oInfo->generateETag($this->oImapClient); if (!$oParams->iThreadUid) { $oMessageCollection->NewMessages = $this->getFolderNextMessageInformation( @@ -692,7 +693,7 @@ class MailClient } if (\strlen($sSearch)) { // Don't use SORT for speed - $aUids = $this->GetUids($oParams, $sSearch, $oMessageCollection->FolderHash/*, $bUseSort*/); + $aUids = $this->GetUids($oParams, $sSearch, $oInfo->etag/*, $bUseSort*/); } else { $bUseSort = $this->oImapClient->hasCapability('SORT'); if (2 > $oInfo->MESSAGES) { @@ -702,7 +703,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, '', $oMessageCollection->FolderHash, $bUseSort); + $aRequestIndexes = $this->GetUids($oParams, '', $oInfo->etag, $bUseSort); // Attempt to get the correct $oParams->iLimit slice $aRequestIndexes = \array_slice($aRequestIndexes, $oParams->iOffset ? $oParams->iLimit : 0, $oParams->iLimit); } else { @@ -716,7 +717,7 @@ class MailClient } else { $aUids = ($bUseThreads && $oParams->iThreadUid) ? [$oParams->iThreadUid] - : $this->GetUids($oParams, '', $oMessageCollection->FolderHash, $bUseSort); + : $this->GetUids($oParams, '', $oInfo->etag, $bUseSort); if ($bUseThreads) { $aAllThreads = $this->MessageListThreadsMap($oMessageCollection, $oParams->oCacher); @@ -745,7 +746,7 @@ class MailClient } if ($aUids && \strlen($sSearch)) { - $aSearchedUids = $this->GetUids($oParams, $sSearch, $oMessageCollection->FolderHash/*, $bUseSort*/); + $aSearchedUids = $this->GetUids($oParams, $sSearch, $oInfo->etag/*, $bUseSort*/); if ($bUseThreads && !$oParams->iThreadUid) { $matchingThreadUids = []; foreach ($aAllThreads as $aMap) { diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MessageCollection.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MessageCollection.php index a461fea33..50587840d 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MessageCollection.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/MessageCollection.php @@ -17,8 +17,6 @@ namespace MailSo\Mail; */ class MessageCollection extends \MailSo\Base\Collection { - public string $FolderHash = ''; - /** * Amount of UIDs in this list (could be less then total messages when using threads) */ @@ -62,16 +60,14 @@ class MessageCollection extends \MailSo\Base\Collection return array_merge(parent::jsonSerialize(), array( 'totalEmails' => $this->totalEmails, 'totalThreads' => $this->totalThreads, - 'folder' => $this->FolderName, - 'folderHash' => $this->FolderHash, - 'folderInfo' => $this->FolderInfo, 'threadUid' => $this->ThreadUid, 'newMessages' => $this->NewMessages, // 'filtered' => $this->Filtered, 'offset' => $this->Offset, 'limit' => $this->Limit, 'search' => $this->Search, - 'limited' => $this->Limited + 'limited' => $this->Limited, + 'folder' => $this->FolderInfo )); } } diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Folders.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Folders.php index d05f31dcb..dbe616acf 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Folders.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Folders.php @@ -304,8 +304,8 @@ trait Folders $aInboxInformation = $this->MailClient()->FolderInformation($sFolder); if (isset($aInboxInformation['folder'])) { $aResult[] = [ - 'folder' => $aInboxInformation['folder'], - 'hash' => $aInboxInformation['hash'], + 'name' => $aInboxInformation['folder'], + 'etag' => $aInboxInformation['etag'], 'totalEmails' => $aInboxInformation['totalEmails'], 'unreadEmails' => $aInboxInformation['unreadEmails'], ]; 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 c06c97fae..76250d996 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 @@ -65,7 +65,7 @@ trait Messages // $oInfo = $this->MailClient()->FolderHash($oParams->sFolderName); $oInfo = $this->ImapClient()->FolderStatusAndSelect($oParams->sFolderName); $aRequestHash = \explode('-', $sHash); - $sFolderHash = $oInfo->getHash($this->ImapClient()->Hash()); + $sFolderHash = $oInfo->getETag($this->ImapClient()->Hash()); $sHash = $oParams->hash() . '-' . $sFolderHash; if ($aRequestHash[1] == $sFolderHash) { $this->verifyCacheByKey($sHash); diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php index 9c8429314..bc1e41497 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Response.php @@ -193,7 +193,7 @@ trait Response $sHash = $mResponse->Hash($this->ImapClient()->Hash()); if ($sHash) { - $aResult['hash'] = $sHash; + $aResult['etag'] = $sHash; } if (null === $this->aCheckableFolder) {