diff --git a/dev/Model/FolderCollection.js b/dev/Model/FolderCollection.js index ca58478da..7293a259c 100644 --- a/dev/Model/FolderCollection.js +++ b/dev/Model/FolderCollection.js @@ -16,7 +16,7 @@ import Remote from 'Remote/User/Fetch'; const Settings = rl.settings, -normalizeFolder = sFolderFullNameRaw => (!sFolderFullNameRaw +normalizeFolder = sFolderFullNameRaw => ('' === sFolderFullNameRaw || UNUSED_OPTION_VALUE === sFolderFullNameRaw || null !== Cache.getFolderFromCacheList(sFolderFullNameRaw)) ? sFolderFullNameRaw @@ -28,81 +28,73 @@ class FolderCollectionModel extends Array super(); /* this.CountRec - this.Namespace; + this.FoldersHash this.IsThreadsSupported + this.Namespace; this.Optimized this.SystemFolders - this.FoldersHash */ } /** - * @param {?Array} json + * @param {?Object} json * @returns {FolderCollectionModel} */ - static reviveFromJson(items) { - if (!items || 'Collection/FolderCollection' !== items['@Object'] || !Array.isArray(items['@Collection'])) { - return; - } + static reviveFromJson(collection) { + if (collection && 'Collection/FolderCollection' === collection['@Object'] + && Array.isArray(collection['@Collection'])) { + const result = new FolderCollectionModel, + expandedFolders = Local.get(ClientSideKeyName.ExpandedFolders), + bDisplaySpecSetting = FolderStore.displaySpecSetting(); - const result = new FolderCollectionModel, - expandedFolders = Local.get(ClientSideKeyName.ExpandedFolders), - bDisplaySpecSetting = FolderStore.displaySpecSetting(); + Object.entries(collection).forEach(([key, value]) => '@' !== key[0] && (result[key] = value)); - result.CountRec = items.CountRec; - result.Namespace = items.Namespace; - result.IsThreadsSupported = items.IsThreadsSupported; - result.Optimized = !!items.Optimized; - result.SystemFolders = items.SystemFolders; - result.FoldersHash = items.FoldersHash; + collection['@Collection'].forEach(oFolder => { + if (oFolder) { + let oCacheFolder = Cache.getFolderFromCacheList(oFolder.FullNameRaw); + if (!oCacheFolder) { + oCacheFolder = FolderModel.newInstanceFromJson(oFolder); + if (oCacheFolder) { + Cache.setFolderToCacheList(oFolder.FullNameRaw, oCacheFolder); + Cache.setFolderFullNameRaw(oCacheFolder.fullNameHash, oFolder.FullNameRaw, oCacheFolder); + } + } - items['@Collection'].forEach(oFolder => { - if (oFolder) { - let oCacheFolder = Cache.getFolderFromCacheList(oFolder.FullNameRaw); - if (!oCacheFolder) { - oCacheFolder = FolderModel.newInstanceFromJson(oFolder); if (oCacheFolder) { - Cache.setFolderToCacheList(oFolder.FullNameRaw, oCacheFolder); - Cache.setFolderFullNameRaw(oCacheFolder.fullNameHash, oFolder.FullNameRaw, oCacheFolder); - } - } - - if (oCacheFolder) { - if (bDisplaySpecSetting) { - oCacheFolder.checkable(!!oFolder.Checkable); - } else { - oCacheFolder.checkable(true); - } - - oCacheFolder.collapsed(!expandedFolders - || !Array.isArray(expandedFolders) - || !expandedFolders.includes(oCacheFolder.fullNameHash)); - - if (oFolder.Extended) { - if (oFolder.Extended.Hash) { - Cache.setFolderHash(oCacheFolder.fullNameRaw, oFolder.Extended.Hash); + if (bDisplaySpecSetting) { + oCacheFolder.checkable(!!oFolder.Checkable); + } else { + oCacheFolder.checkable(true); } - if (null != oFolder.Extended.MessageCount) { - oCacheFolder.messageCountAll(oFolder.Extended.MessageCount); + oCacheFolder.collapsed(!expandedFolders + || !Array.isArray(expandedFolders) + || !expandedFolders.includes(oCacheFolder.fullNameHash)); + + if (oFolder.Extended) { + if (oFolder.Extended.Hash) { + Cache.setFolderHash(oCacheFolder.fullNameRaw, oFolder.Extended.Hash); + } + + if (null != oFolder.Extended.MessageCount) { + oCacheFolder.messageCountAll(oFolder.Extended.MessageCount); + } + + if (null != oFolder.Extended.MessageUnseenCount) { + oCacheFolder.messageCountUnread(oFolder.Extended.MessageUnseenCount); + } } - if (null != oFolder.Extended.MessageUnseenCount) { - oCacheFolder.messageCountUnread(oFolder.Extended.MessageUnseenCount); - } - } - - if (oFolder.SubFolders) { oFolder.SubFolders = FolderCollectionModel.reviveFromJson(oFolder.SubFolders); - oCacheFolder.subFolders(oFolder.SubFolders); + oFolder.SubFolders && oCacheFolder.subFolders(oFolder.SubFolders); + + result.push(oCacheFolder); } - - result.push(oCacheFolder); } - } - }); + }); - return result; + return result; + } } storeIt() { @@ -121,7 +113,7 @@ class FolderCollectionModel extends Array AppStore.threadsAllowed(!!(Settings.app('useImapThread') && this.IsThreadsSupported)); - FolderStore.folderList.optimized(this.Optimized); + FolderStore.folderList.optimized(!!this.Optimized); let update = false; diff --git a/dev/Model/MessageCollection.js b/dev/Model/MessageCollection.js new file mode 100644 index 000000000..366de5aff --- /dev/null +++ b/dev/Model/MessageCollection.js @@ -0,0 +1,69 @@ +import { MessageModel } from 'Model/Message'; + +import { + initMessageFlagsFromCache, + storeMessageFlagsToCache, + hasNewMessageAndRemoveFromCache +} from 'Common/Cache'; + +'use strict'; + +class MessageCollectionModel extends Array +{ + constructor() { + super(); +/* + this.Filtered + this.Folder + this.FolderHash + this.Limit + this.MessageCount + this.MessageUnseenCount + this.MessageResultCount + this.NewMessages + this.Offset + this.Search + this.ThreadUid + this.UidNext +*/ + } + + /** + * @param {?Object} json + * @returns {MessageCollectionModel} + */ + static reviveFromJson(collection, cached) { + if (collection + && 'Collection/MessageCollection' === collection['@Object'] + && Array.isArray(collection['@Collection'])) { + const result = new MessageCollectionModel; + + Object.entries(collection).forEach(([key, value]) => '@' !== key[0] && (result[key] = value)); + + let newCount = 0; + collection['@Collection'].forEach(message => { + if (message && 'Object/Message' === message['@Object']) { + message = MessageModel.newInstanceFromJson(message); + if (message) { + if (hasNewMessageAndRemoveFromCache(message.folderFullNameRaw, message.uid) && 5 >= newCount) { + ++newCount; + message.newForAnimation(true); + } + + message.deleted(false); + + cached ? initMessageFlagsFromCache(message) : storeMessageFlagsToCache(message); + + result.push(message); + } + } + }); + +// collection[@Count] == result.length + + return result; + } + } +} + +export { MessageCollectionModel, MessageCollectionModel as default }; diff --git a/dev/Remote/User/Fetch.js b/dev/Remote/User/Fetch.js index 3c09d551d..a520690e0 100644 --- a/dev/Remote/User/Fetch.js +++ b/dev/Remote/User/Fetch.js @@ -308,34 +308,25 @@ class RemoteUserFetch extends AbstractFetchRemote { useThreads = AppStore.threadsAllowed() && SettingsStore.useThreads(), inboxUidNext = getFolderInboxName() === sFolderFullNameRaw ? getFolderUidNext(sFolderFullNameRaw) : ''; - if (folderHash && (!sSearch || !sSearch.includes('is:'))) { - return this.defaultRequest( - fCallback, - 'MessageList', - {}, - sSearch ? SEARCH_AJAX_TIMEOUT : DEFAULT_AJAX_TIMEOUT, - 'MessageList/' + - subQueryPrefix() + - '/' + - urlsafeArray([ - sFolderFullNameRaw, - iOffset, - iLimit, - sSearch, - AppStore.projectHash(), - folderHash, - inboxUidNext, - useThreads ? 1 : 0, - useThreads ? sThreadUid : '' - ]), - bSilent ? [] : ['MessageList'] - ); - } + let params = {}, sGetAdd = ''; - return this.defaultRequest( - fCallback, - 'MessageList', - { + if (folderHash && (!sSearch || !sSearch.includes('is:'))) { + sGetAdd = 'MessageList/' + + subQueryPrefix() + + '/' + + urlsafeArray([ + sFolderFullNameRaw, + iOffset, + iLimit, + sSearch, + AppStore.projectHash(), + folderHash, + inboxUidNext, + useThreads ? 1 : 0, + useThreads ? sThreadUid : '' + ]); + } else { + params = { Folder: sFolderFullNameRaw, Offset: iOffset, Limit: iLimit, @@ -343,9 +334,15 @@ class RemoteUserFetch extends AbstractFetchRemote { UidNext: inboxUidNext, UseThreads: useThreads ? 1 : 0, ThreadUid: useThreads ? sThreadUid : '' - }, + }; + } + + return this.defaultRequest( + fCallback, + 'MessageList', + params, sSearch ? SEARCH_AJAX_TIMEOUT : DEFAULT_AJAX_TIMEOUT, - '', + sGetAdd, bSilent ? [] : ['MessageList'] ); } diff --git a/dev/Stores/User/Message.js b/dev/Stores/User/Message.js index 554305dd4..536f10dbb 100644 --- a/dev/Stores/User/Message.js +++ b/dev/Stores/User/Message.js @@ -18,8 +18,6 @@ import { initMessageFlagsFromCache, addRequestedMessage, clearMessageFlagsFromCacheByFolder, - hasNewMessageAndRemoveFromCache, - storeMessageFlagsToCache, clearNewMessageCache } from 'Common/Cache'; @@ -29,6 +27,7 @@ import { i18n, getNotification } from 'Common/Translator'; import { EmailCollectionModel } from 'Model/EmailCollection'; import { MessageModel } from 'Model/Message'; +import { MessageCollectionModel } from 'Model/MessageCollection'; import { setHash } from 'Knoin/Knoin'; @@ -681,87 +680,54 @@ class MessageUserStore { } setMessageList(data, cached) { - if ( - data && - data.Result && - 'Collection/MessageCollection' === data.Result['@Object'] && - data.Result['@Collection'] && - Array.isArray(data.Result['@Collection']) - ) { - let newCount = 0, - unreadCountChange = false; + const collection = data && MessageCollectionModel.reviveFromJson(data.Result, cached); + if (collection) { + let unreadCountChange = false; - const list = [], - iCount = pInt(data.Result.MessageResultCount), - iOffset = pInt(data.Result.Offset); - - const folder = getFolderFromCacheList(data.Result.Folder); + const iCount = collection.MessageResultCount, + iOffset = collection.Offset, + folder = getFolderFromCacheList(collection.Folder); if (folder && !cached) { folder.interval = Date.now() / 1000; - setFolderHash(data.Result.Folder, data.Result.FolderHash); + setFolderHash(collection.Folder, collection.FolderHash); - if (null != data.Result.MessageCount) { - folder.messageCountAll(data.Result.MessageCount); + if (null != collection.MessageCount) { + folder.messageCountAll(collection.MessageCount); } - if (null != data.Result.MessageUnseenCount) { - if (pInt(folder.messageCountUnread()) !== pInt(data.Result.MessageUnseenCount)) { + if (null != collection.MessageUnseenCount) { + if (pInt(folder.messageCountUnread()) !== pInt(collection.MessageUnseenCount)) { unreadCountChange = true; + clearMessageFlagsFromCacheByFolder(folder.fullNameRaw); } - folder.messageCountUnread(data.Result.MessageUnseenCount); + folder.messageCountUnread(collection.MessageUnseenCount); } - this.initUidNextAndNewMessages(folder.fullNameRaw, data.Result.UidNext, data.Result.NewMessages); + this.initUidNextAndNewMessages(folder.fullNameRaw, collection.UidNext, collection.NewMessages); } - if (unreadCountChange && folder) { - clearMessageFlagsFromCacheByFolder(folder.fullNameRaw); - } - - data.Result['@Collection'].forEach(jsonMessage => { - if (jsonMessage && 'Object/Message' === jsonMessage['@Object']) { - const message = MessageModel.newInstanceFromJson(jsonMessage); - if (message) { - if (hasNewMessageAndRemoveFromCache(message.folderFullNameRaw, message.uid) && 5 >= newCount) { - newCount += 1; - message.newForAnimation(true); - } - - message.deleted(false); - - if (cached) { - initMessageFlagsFromCache(message); - } else { - storeMessageFlagsToCache(message); - } - - list.push(message); - } - } - }); - this.messageListCount(iCount); - this.messageListSearch(null != data.Result.Search ? data.Result.Search : ''); + this.messageListSearch(pString(collection.Search)); this.messageListPage(Math.ceil(iOffset / SettingsStore.messagesPerPage() + 1)); - this.messageListThreadUid(null != data.Result.ThreadUid ? pString(data.Result.ThreadUid) : ''); + this.messageListThreadUid(pString(data.Result.ThreadUid)); - this.messageListEndFolder(null != data.Result.Folder ? data.Result.Folder : ''); + this.messageListEndFolder(collection.Folder); this.messageListEndSearch(this.messageListSearch()); this.messageListEndThreadUid(this.messageListThreadUid()); this.messageListEndPage(this.messageListPage()); this.messageListDisableAutoSelect(true); - this.messageList(list); + this.messageList(collection); this.messageListIsNotCompleted(false); clearNewMessageCache(); if (folder && (cached || unreadCountChange || SettingsStore.useThreads())) { - rl.app.folderInformation(folder.fullNameRaw, list); + rl.app.folderInformation(folder.fullNameRaw, collection); } } else { this.messageListCount(0);