芝麻web文件管理V1.00
编辑当前文件:/home/pulsehostuk9/www/cloud.pulsehost.co.uk/modules/MailWebclient/js/models/CFolderModel.js
'use strict'; var _ = require('underscore'), $ = require('jquery'), ko = require('knockout'), moment = require('moment'), Logger = require('%PathToCoreWebclientModule%/js/utils/Logger.js'), TextUtils = require('%PathToCoreWebclientModule%/js/utils/Text.js'), Types = require('%PathToCoreWebclientModule%/js/utils/Types.js'), Ajax = require('modules/%ModuleName%/js/Ajax.js'), Api = require('%PathToCoreWebclientModule%/js/Api.js'), App = require('%PathToCoreWebclientModule%/js/App.js'), Routing = require('%PathToCoreWebclientModule%/js/Routing.js'), Storage = require('%PathToCoreWebclientModule%/js/Storage.js'), Popups = require('%PathToCoreWebclientModule%/js/Popups.js'), ConfirmPopup = require('%PathToCoreWebclientModule%/js/popups/ConfirmPopup.js'), LinksUtils = require('modules/%ModuleName%/js/utils/Links.js'), AccountList = require('modules/%ModuleName%/js/AccountList.js'), MailCache = null, MessagesDictionary = require('modules/%ModuleName%/js/MessagesDictionary.js'), Settings = require('modules/%ModuleName%/js/Settings.js'), CMessageModel = require('modules/%ModuleName%/js/models/CMessageModel.js'), CUidListModel = require('modules/%ModuleName%/js/models/CUidListModel.js') ; /** * @constructor * @param {number} iAccountId * @param {boolean} bIsUnifiedInbox */ function CFolderModel(iAccountId, bIsUnifiedInbox) { this.iAccountId = iAccountId; this.bIsUnifiedInbox = !!bIsUnifiedInbox; this.oUnifiedInboxes = {}; this.bNamespace = false; this.iDisplayedLevel = 0; this.bIgnoreImapSubscription = Settings.IgnoreImapSubscription; this.bAllowTemplateFolders = Settings.AllowTemplateFolders; this.isTemplateStorage = ko.observable(false); this.bAllowAlwaysRefreshFolders = Settings.AllowAlwaysRefreshFolders; this.isAlwaysRefresh = ko.observable(false); /** From server **/ this.sDelimiter = ''; this.bExists = true; /** Extended **/ this.sUidNext = ''; this.sHash = ''; this.messageCount = ko.observable(0); this.unseenMessageCount = ko.observable(0); this.iRealUnseenMessageCount = 0; this.hasExtendedInfo = ko.observable(false); /** Extended **/ this.fullName = ko.observable(''); this.fullNameHash = ko.observable(''); this.parentFullName = ko.observable(''); this.parentDisplayFullName = ko.observable(''); this.bSelectable = true; this.subscribed = ko.observable(true); this.name = ko.observable(''); this.nameForEdit = ko.observable(''); this.subfolders = ko.observableArray([]); this.subfoldersMessagesCount = ko.observable(0); this.type = ko.observable(Enums.FolderTypes.User); /** From server **/ this.bVirtual = false; // Indicates if the folder does not exist on mail server and uses as place for filtered message list. // At the moment the application supports only one type of virtual folders - for starred messages. this.selected = ko.observable(false); // Indicates if the folder is selected on mail screen. this.expanded = ko.observable(false); // Indicates if subfolders are shown on mail screen. this.recivedAnim = ko.observable(false).extend({'autoResetToFalse': 500}); // Starts the animation for displaying moving messages to the folder on mail screen. this.edited = ko.observable(false); // Indicates if the folder name is edited now on settings screen. this.aMessagesDictionaryUids = []; this.oUids = {}; this.aResponseHandlers = []; this.aRequestedUids = []; this.aRequestedThreadUids = []; this.requestedLists = []; this.hasChanges = ko.observable(false); this.oRelevantInformationLastMoment = null; this.bSubscribtionsInitialized = false; this.disableMoveTo = ko.observable(this.bVirtual || this.bIsUnifiedInbox); this.disableMoveFrom = ko.observable(this.bIsUnifiedInbox); } CFolderModel.prototype.setDisableMoveTo = function (bDisable) { this.disableMoveTo(this.bVirtual || this.bIsUnifiedInbox || bDisable); }; CFolderModel.prototype.setDisableMoveFrom = function (bDisable) { this.disableMoveFrom(this.bIsUnifiedInbox || bDisable); }; CFolderModel.prototype.requireMailCache = function () { if (MailCache === null) { MailCache = require('modules/%ModuleName%/js/Cache.js'); } }; /** * @param {number} iLevel */ CFolderModel.prototype.setDisplayedLevel = function (iLevel) { this.iDisplayedLevel = iLevel; }; CFolderModel.prototype.getDisplayedLevel = function () { return this.iDisplayedLevel; }; CFolderModel.prototype.getUnifiedInbox = function (iAccountId) { var oInbox = this.oUnifiedInboxes[iAccountId]; if (!oInbox) { this.requireMailCache(); var oFolderList = MailCache.oFolderListItems[iAccountId]; oInbox = oFolderList ? oFolderList.inboxFolder() : null; this.oUnifiedInboxes[iAccountId] = oInbox; } return oInbox; }; /** * @param {string} sUid * @returns {Object} */ CFolderModel.prototype.getMessageByUid = function (sUid) { this.requireMailCache(); var oIdentifiers = MailCache.getMessageActualIdentifiers(this.iAccountId, this.fullName(), sUid); return MessagesDictionary.get([oIdentifiers.iAccountId, oIdentifiers.sFolder, oIdentifiers.sUid]); }; /** * Removes message uid from the dictionary. * @param {string} sUid * @returns {Object} */ CFolderModel.prototype.removeMessageFromDict = function (sUid) { MessagesDictionary.remove([this.iAccountId, this.fullName(), sUid]); this.aMessagesDictionaryUids = _.without(this.aMessagesDictionaryUids, sUid); this.aRequestedUids = _.without(this.aRequestedUids, sUid); this.aRequestedThreadUids = _.without(this.aRequestedThreadUids, sUid); App.broadcastEvent('%ModuleName%::removeMessageFromDict::after', [this.iAccountId, this.fullName(), sUid]); }; /** * Update last access time for messages with specified uids. * @param {array} aUids */ CFolderModel.prototype.updateLastAccessTime = function (aUids) { _.each(aUids, function (sUid) { var oMessage = this.getMessageByUid(sUid); if (oMessage) { oMessage.updateLastAccessTime(); } }, this); }; /** * Executes some function for all uids of messages from the folder in the dictionary. * Removes invalid uids from lists. * @param {function} fDoForAllMessages */ CFolderModel.prototype.doForAllMessages = function (fDoForAllMessages) { var aInvalidUids = []; _.each(this.aMessagesDictionaryUids, function (sUidInDict) { var oMessage = this.getMessageByUid(sUidInDict); if (oMessage) { fDoForAllMessages(oMessage); } else { aInvalidUids.push(sUidInDict); } }, this); if (aInvalidUids.length > 0) { this.aMessagesDictionaryUids = _.difference(this.aMessagesDictionaryUids, aInvalidUids); this.aRequestedUids = _.difference(this.aRequestedUids, aInvalidUids); this.aRequestedThreadUids = _.difference(this.aRequestedThreadUids, aInvalidUids); } }; /** * @returns {Array} */ CFolderModel.prototype.getFlaggedMessageUids = function () { var aUids = []; this.doForAllMessages(function (oMessage) { if (oMessage.flagged()) { aUids.push(oMessage.uid()); } }); return aUids; }; /** * @param {string} sUid */ CFolderModel.prototype.setMessageUnflaggedByUid = function (sUid) { var oMessage = this.getMessageByUid(sUid); if (oMessage) { oMessage.flagged(false); } }; /** * @param {Object} oMessage */ CFolderModel.prototype.hideThreadMessages = function (oMessage) { _.each(oMessage.threadUids(), function (sThreadUid) { var oThreadMessage = this.getMessageByUid(sThreadUid); if (oThreadMessage) { if (!oThreadMessage.deleted()) { oThreadMessage.threadShowAnimation(false); oThreadMessage.threadHideAnimation(true); setTimeout(function () { oThreadMessage.threadHideAnimation(false); }, 1000); } } }, this); }; /** * @param {Object} oMessage */ CFolderModel.prototype.getThreadMessages = function (oMessage) { var aLoadedMessages = [], aUidsForLoad = [], aChangedThreadUids = [], iCount = 0, oLastMessage = null, iShowThrottle = 50 ; _.each(oMessage.threadUids(), function (sThreadUid) { if (iCount < oMessage.threadCountForLoad()) { var oThreadMessage = this.getMessageByUid(sThreadUid); if (oThreadMessage) { if (!oThreadMessage.deleted()) { oThreadMessage.markAsThreadPart(iShowThrottle, oMessage.uid()); aLoadedMessages.push(oThreadMessage); aChangedThreadUids.push(oThreadMessage.uid()); iCount++; oLastMessage = oThreadMessage; } } else { aUidsForLoad.push(sThreadUid); aChangedThreadUids.push(sThreadUid); iCount++; } } else { aChangedThreadUids.push(sThreadUid); } }, this); if (!oMessage.threadLoading()) { this.loadThreadMessages(aUidsForLoad); } oMessage.changeThreadUids(aChangedThreadUids, aLoadedMessages.length); if (oLastMessage && aLoadedMessages.length < oMessage.threadUids().length) { oLastMessage.showNextLoadingLink(_.bind(oMessage.increaseThreadCountForLoad, oMessage)); } return aLoadedMessages; }; /** * @param {Object} oMessage */ CFolderModel.prototype.computeThreadData = function (oMessage) { var iUnreadCount = 0, bPartialFlagged = false, aSenders = [], aEmails = [], sMainEmail = oMessage.oFrom.getFirstEmail() ; _.each(oMessage.threadUids(), function (sThreadUid) { var oInbox = this.bIsUnifiedInbox ? this.getUnifiedInbox(oMessage.accountId()) : null, oThreadMessage = oInbox ? oInbox.getMessageByUid(sThreadUid) : this.getMessageByUid(sThreadUid), sThreadEmail = '' ; if (oThreadMessage && !oThreadMessage.deleted()) { if (!oThreadMessage.seen()) { iUnreadCount++; } if (oThreadMessage.flagged()) { bPartialFlagged = true; } sThreadEmail = oThreadMessage.oFrom.getFirstEmail(); if ((sThreadEmail !== sMainEmail) && (-1 === $.inArray(sThreadEmail, aEmails))) { aEmails.push(sThreadEmail); if (sThreadEmail === AccountList.getEmail()) { aSenders.push(TextUtils.i18n('%MODULENAME%/LABEL_ME_SENDER')); } else { aSenders.push(oThreadMessage.oFrom.getFirstDisplay()); } } } }, this); oMessage.threadUnreadCount(iUnreadCount); oMessage.partialFlagged(bPartialFlagged); }; /** * @param {Array} aUidsForLoad */ CFolderModel.prototype.loadThreadMessages = function (aUidsForLoad) { if (aUidsForLoad.length > 0) { var oParameters = { 'AccountID': this.iAccountId, 'Folder': this.fullName(), 'Uids': aUidsForLoad }; Ajax.send('GetMessagesByUids', oParameters, this.onGetMessagesByUidsResponse, this); } }; /** * @param {Array} aMessages */ CFolderModel.prototype.getThreadCheckedUidsFromList = function (aMessages) { var aThreadUids = []; _.each(aMessages, function (oMessage) { if (oMessage.threadCount() > 0 && !oMessage.threadOpened()) { _.each(oMessage.threadUids(), function (sUid) { var oInbox = this.bIsUnifiedInbox ? this.getUnifiedInbox(oMessage.accountId()) : null, oThreadMessage = oInbox ? oInbox.getMessageByUid(sUid) : this.getMessageByUid(sUid) ; if (oThreadMessage && !oThreadMessage.deleted() && oThreadMessage.checked()) { aThreadUids.push(oThreadMessage.longUid()); } }, this); } }, this); return aThreadUids; }; /** * @param {Object} oRawMessage * @param {boolean} bThreadPart * @param {boolean} bTrustThreadInfo */ CFolderModel.prototype.parseAndCacheMessage = function (oRawMessage, bThreadPart, bTrustThreadInfo) { var sUid = oRawMessage.Uid.toString(), bNewMessage = false, oMessage = this.getMessageByUid(sUid) ; if (!oMessage) { bNewMessage = true; oMessage = new CMessageModel(); } oMessage.parse(oRawMessage, this.iAccountId, bThreadPart, bTrustThreadInfo); if (this.type() === Enums.FolderTypes.Inbox && bNewMessage && oMessage.flagged()) { this.requireMailCache(); MailCache.increaseStarredCount(); } MessagesDictionary.set([oMessage.accountId(), oMessage.folder(), sUid], oMessage); if (bNewMessage) { this.aRequestedUids = _.without(this.aRequestedUids, sUid); if (-1 === _.indexOf(this.aMessagesDictionaryUids, sUid)) { this.aMessagesDictionaryUids.push(sUid); } } return oMessage; }; /** * @param {Object} oResponse * @param {Object} oRequest */ CFolderModel.prototype.onGetMessagesByUidsResponse = function (oResponse, oRequest) { var oResult = oResponse.Result; if (oResult && oResult['@Object'] === 'Collection/MessageCollection') { _.each(oResult['@Collection'], function (oRawMessage) { this.parseAndCacheMessage(oRawMessage, true, true); }, this); this.requireMailCache(); MailCache.showOpenedThreads(this.fullName()); } }; /** * Adds uids of requested messages. * * @param {Array} aUids */ CFolderModel.prototype.addRequestedUids = function (aUids) { this.aRequestedUids = _.union(this.aRequestedUids, aUids); }; /** * @param {string} sUid */ CFolderModel.prototype.hasUidBeenRequested = function (sUid) { return _.indexOf(this.aRequestedUids, sUid) !== -1; }; /** * Adds uids of requested thread message headers. * * @param {Array} aUids */ CFolderModel.prototype.addRequestedThreadUids = function (aUids) { this.aRequestedThreadUids = _.union(this.aRequestedThreadUids, aUids); }; /** * @param {string} sUid */ CFolderModel.prototype.hasThreadUidBeenRequested = function (sUid) { return _.indexOf(this.aRequestedThreadUids, sUid) !== -1; }; /** * @param {Object} oParams */ CFolderModel.prototype.hasListBeenRequested = function (oParams) { var aFoundParams = _.where(this.requestedLists, oParams), bHasParams = aFoundParams.length > 0 ; if (!bHasParams) { this.requestedLists.push(oParams); } return bHasParams; }; /** * @param {string} sUid * @param {string} sReplyType */ CFolderModel.prototype.markMessageReplied = function (sUid, sReplyType) { var oMessage = this.getMessageByUid(sUid), oFolder = oMessage ? MailCache.getFolderByFullName(oMessage.accountId(), oMessage.folder()) : null; ; if (oMessage) { switch (sReplyType) { case Enums.ReplyType.Reply: case Enums.ReplyType.ReplyAll: oMessage.answered(true); if (Settings.MarkMessageSeenWhenAnswerForward && oFolder && !oMessage.seen()) { MailCache.executeGroupOperationForFolder('SetMessagesSeen', oFolder, [oMessage.longUid()], 'seen', true); } break; case Enums.ReplyType.Forward: case Enums.ReplyType.ForwardAsAttach: oMessage.forwarded(true); if (Settings.MarkMessageSeenWhenAnswerForward && oFolder && !oMessage.seen()) { MailCache.executeGroupOperationForFolder('SetMessagesSeen', oFolder, [oMessage.longUid()], 'seen', true); } break; } } }; CFolderModel.prototype.removeAllMessages = function () { var oUidListsToRemove = this.oUids, aMessagesUidsToRemove = this.aMessagesDictionaryUids, oUidList = null ; this.aMessagesDictionaryUids = []; this.aRequestedUids = []; this.aRequestedThreadUids = []; this.requestedLists = []; this.oUids = {}; this.messageCount(0); this.unseenMessageCount(0); this.iRealUnseenMessageCount = 0; oUidList = this.getUidList('', '', Settings.MessagesSortBy.DefaultSortBy, Settings.MessagesSortBy.DefaultSortOrder); oUidList.resultCount(0); if (MailCache.currentMessage() && MailCache.currentMessage().accountId() === this.iAccountId && MailCache.currentMessage().folder() === this.fullName()) { Logger.log('removeAllMessages, the current message is in the list to remove', MailCache.currentMessage() ? {'accountId': MailCache.currentMessage().accountId(),'folder': MailCache.currentMessage().folder(),'uid': MailCache.currentMessage().uid()} : null); aMessagesUidsToRemove = _.without(aMessagesUidsToRemove, MailCache.currentMessage().longUid()); } _.each(aMessagesUidsToRemove, function (sUid) { this.removeMessageFromDict(sUid); }, this); aMessagesUidsToRemove = null; _.each(oUidListsToRemove, function (oUidList) { // clear the UID list because it is outdated // Do not remove it from the cache to prevent the creation of a new oUidList object // because the old oUidList object will remain in the browser's memory oUidList.clearData(); }); oUidListsToRemove = null; }; CFolderModel.prototype.removeAllMessageListsFromCacheIfHasChanges = function () { if (this.hasChanges()) { this.oUids = {}; this.requestedLists = []; this.aRequestedThreadUids = []; this.hasChanges(false); } }; CFolderModel.prototype.removeMultiFoldersMessageListsFromCache = function () { _.each(this.oUids, function (oUidList) { if (MailCache.isSearchInMultiFolders(oUidList.search())) { this.requestedLists = _.filter(this.requestedLists, function (oParams) { return oParams.search !== oUidList.search(); }); // clear the UID list because it is outdated // Do not remove it from the cache to prevent the creation of a new oUidList object // because the old oUidList object will remain in the browser's memory oUidList.clearData(); } }, this); }; CFolderModel.prototype.removeFlaggedMessageListsFromCache = function () { _.each(this.oUids, function (oUidList) { if (oUidList.filters() === Enums.FolderFilter.Flagged) { // clear the UID list because it is outdated // Do not remove it from the cache to prevent the creation of a new oUidList object // because the old oUidList object will remain in the browser's memory oUidList.clearData(); } }, this); }; CFolderModel.prototype.removeUnseenMessageListsFromCache = function () { _.each(this.oUids, function (oUidList) { if (oUidList.filters() === Enums.FolderFilter.Unseen) { // clear the UID list because it is outdated // Do not remove it from the cache to prevent the creation of a new oUidList object // because the old oUidList object will remain in the browser's memory oUidList.clearData(); } }, this); }; /** * @param {string} sUidNext * @param {string} sHash * @param {number} iMsgCount * @param {number} iMsgUnseenCount * @param {boolean} bNotApplyInfoToUI */ CFolderModel.prototype.setRelevantInformation = function (sUidNext, sHash, iMsgCount, iMsgUnseenCount, bNotApplyInfoToUI) { var bHasChanges = this.hasExtendedInfo() && (this.sHash !== sHash || this.iRealUnseenMessageCount !== iMsgUnseenCount || this.unseenMessageCount() !== iMsgUnseenCount); // If different, either new messages appeared or some messages were deleted this.sHash = sHash; this.iRealUnseenMessageCount = iMsgUnseenCount; // New info of the folder shouldn't be applied to UI for current message list before the list is received from the server. if (!this.hasExtendedInfo() || !bNotApplyInfoToUI) { // If sUidNext is always updated, some of desktop notifications are shown twice this.sUidNext = sUidNext; // If messages counts are always updated, new message appears in the list with significant delay this.messageCount(iMsgCount); this.unseenMessageCount(iMsgUnseenCount); // Fix for folder count summing if (iMsgUnseenCount === 0) { this.unseenMessageCount.valueHasMutated(); } } this.hasExtendedInfo(true); if (bHasChanges) { this.markHasChanges(); } // Date and time of last updating of the folder information. this.oRelevantInformationLastMoment = moment(); return bHasChanges; }; CFolderModel.prototype.increaseCountIfHasNotInfo = function () { if (!this.hasExtendedInfo()) { this.messageCount(this.messageCount() + 1); } }; CFolderModel.prototype.markHasChanges = function () { this.hasChanges(true); }; /** * @param {number} iDiff * @param {number} iUnseenDiff */ CFolderModel.prototype.addMessagesCountsDiff = function (iDiff, iUnseenDiff) { var iCount = this.messageCount() + iDiff, iUnseenCount = this.unseenMessageCount() + iUnseenDiff ; if (iCount < 0) { iCount = 0; } this.messageCount(iCount); if (iUnseenCount < 0) { iUnseenCount = 0; } if (iUnseenCount > iCount) { iUnseenCount = iCount; } this.unseenMessageCount(iUnseenCount); }; /** * @param {Array} aUids */ CFolderModel.prototype.markDeletedByUids = function (aUids) { var iMinusDiff = 0, iUnseenMinusDiff = 0 ; _.each(aUids, function (sUid) { var oMessage = this.getMessageByUid(sUid); if (oMessage) { iMinusDiff++; if (!oMessage.seen()) { iUnseenMinusDiff++; } oMessage.deleted(true); } }, this); this.addMessagesCountsDiff(-iMinusDiff, -iUnseenMinusDiff); MailCache.setUnifiedInboxUnseenChanges(this.iAccountId, this.fullName(), -iMinusDiff, -iUnseenMinusDiff); return {MinusDiff: iMinusDiff, UnseenMinusDiff: iUnseenMinusDiff}; }; /** * @param {Array} aUids */ CFolderModel.prototype.revertDeleted = function (aUids) { var iPlusDiff = 0, iUnseenPlusDiff = 0 ; _.each(aUids, function (sUid) { var oMessage = this.getMessageByUid(sUid); if (oMessage && oMessage.deleted()) { iPlusDiff++; if (!oMessage.seen()) { iUnseenPlusDiff++; } oMessage.deleted(false); } }, this); this.addMessagesCountsDiff(iPlusDiff, iUnseenPlusDiff); return {PlusDiff: iPlusDiff, UnseenPlusDiff: iUnseenPlusDiff}; }; /** * @param {Array} aUids */ CFolderModel.prototype.commitDeleted = function (aUids) { _.each(aUids, _.bind(function (sUid) { var bCurrentMessageIsBeingDeleted = MailCache.currentMessage() && MailCache.currentMessage().accountId() === this.iAccountId && MailCache.currentMessage().folder() === this.fullName() && MailCache.currentMessage().uid() === sUid; if (bCurrentMessageIsBeingDeleted) { Logger.log('commitDeleted, the current message is to remove', MailCache.currentMessage() ? {'accountId': MailCache.currentMessage().accountId(),'folder': MailCache.currentMessage().folder(),'uid': MailCache.currentMessage().uid()} : null); } else { this.removeMessageFromDict(sUid); } this.aMessagesDictionaryUids = _.without(this.aMessagesDictionaryUids, sUid); this.aRequestedUids = _.without(this.aRequestedUids, sUid); this.aRequestedThreadUids = _.without(this.aRequestedThreadUids, sUid); }, this)); _.each(this.oUids, function (oUidList) { oUidList.deleteUids(aUids); }); }; /** * @param {string} sSearch * @param {string} sFilters * @param {string} sSortBy * @param {number} iSortOrder */ CFolderModel.prototype.getUidList = function (sSearch, sFilters, sSortBy, iSortOrder) { var sIndex = JSON.stringify([sSearch, sFilters, sSortBy, iSortOrder]), oUidList = null ; if (this.oUids[sIndex] === undefined) { oUidList = new CUidListModel(); oUidList.iAccountId = this.iAccountId; oUidList.sFullName = this.fullName(); oUidList.search(sSearch); oUidList.filters(sFilters); oUidList.sortBy(sSortBy); oUidList.sortOrder(iSortOrder); this.oUids[sIndex] = oUidList; } return this.oUids[sIndex]; }; /** * @param {number} iLevel * @param {string} sFullName */ CFolderModel.prototype.initStarredFolder = function (iLevel, sFullName) { this.bVirtual = true; this.setDisplayedLevel(iLevel); this.fullName(sFullName); this.name(TextUtils.i18n('%MODULENAME%/LABEL_FOLDER_STARRED')); this.type(Enums.FolderTypes.Starred); this.initSubscriptions(''); this.initComputedFields(true); }; /** * @param {Object} oData * @param {string} sParentFullName * @param {string} sNamespaceFolder * @param {string} sParentDisplayFullName */ CFolderModel.prototype.parse = function (oData, sParentFullName, sNamespaceFolder, sParentDisplayFullName) { var sName = '', iType = Enums.FolderTypes.User ; if (oData['@Object'] === 'Object/Folder') { sName = Types.pString(oData.Name); this.name(sName); this.nameForEdit(sName); this.fullName(Types.pString(oData.FullNameRaw)); this.fullNameHash(Types.pString(oData.FullNameHash)); this.parentFullName(Types.pString(sParentFullName)); this.parentDisplayFullName(Types.pString(sParentDisplayFullName)); this.sDelimiter = oData.Delimiter; iType = Types.pInt(oData.Type); if (!Settings.AllowTemplateFolders && iType === Enums.FolderTypes.Template) { iType = Enums.FolderTypes.User; } if (Settings.AllowSpamFolder || iType !== Enums.FolderTypes.Spam) { this.type(iType); } this.isTemplateStorage(this.type() === Enums.FolderTypes.Template); this.bNamespace = (sNamespaceFolder === this.fullName()); this.isAlwaysRefresh(Settings.AllowAlwaysRefreshFolders && !!oData.AlwaysRefresh); this.subscribed(Settings.IgnoreImapSubscription ? true : oData.IsSubscribed); this.bSelectable = oData.IsSelectable; this.bExists = oData.Exists; if (oData.Extended) { this.setRelevantInformation(oData.Extended.UidNext.toString(), oData.Extended.Hash, oData.Extended.MessageCount, oData.Extended.MessageUnseenCount, false); } this.initSubscriptions(sParentFullName); this.initComputedFields(); App.broadcastEvent('%ModuleName%::ParseFolder::after', this); return oData.SubFolders; } return null; }; /** * @param {string} sParentFullName */ CFolderModel.prototype.initSubscriptions = function (sParentFullName) { if (!this.bSubscribtionsInitialized) { this.requireMailCache(); this.unseenMessageCount.subscribe(function () { _.delay(_.bind(function () { MailCache.countMessages(this); },this), 1000); }, this); this.subscribed.subscribe(function () { if (sParentFullName) { var oParentFolder = MailCache.folderList().getFolderByFullName(sParentFullName); if(oParentFolder) { MailCache.countMessages(oParentFolder); } } }, this); this.edited.subscribe(function (bEdited) { if (bEdited === false) { this.nameForEdit(this.name()); } }, this); this.hasChanges.subscribe(function () { this.requestedLists = []; }, this); this.bSubscribtionsInitialized = true; } }; CFolderModel.prototype.initComputedFields = function () { this.routingHash = ko.computed(function () { // At the moment the application supports only one type of virtual folders - for starred messages. if (this.bVirtual) { let search = ''; if (Settings.AllowChangeStarredMessagesSource && Settings.StarredMessagesSource === Enums.StarredMessagesSource.AllFolders) { search = 'folders:all'; } return Routing.buildHashFromArray(LinksUtils.getMailbox(this.fullName(), 1, '', search, Enums.FolderFilter.Flagged)); } else { return Routing.buildHashFromArray(LinksUtils.getMailbox(this.fullName())); } }, this); this.isSystem = ko.computed(function () { return this.type() !== Enums.FolderTypes.User; }, this); this.withoutThreads = ko.computed(function () { return this.type() === Enums.FolderTypes.Drafts || this.type() === Enums.FolderTypes.Spam || this.type() === Enums.FolderTypes.Trash; }, this); this.enableEmptyFolder = ko.computed(function () { return (this.type() === Enums.FolderTypes.Spam || this.type() === Enums.FolderTypes.Trash) && this.messageCount() > 0; }, this); this.virtualEmpty = ko.computed(function () { return this.bVirtual && this.messageCount() === 0; }, this); // indicates if folder has at least one subscribed subfolder this.hasSubscribedSubfolders = ko.computed(function () { return _.any(this.subfolders(), function (oFolder) { return oFolder.subscribed(); }); }, this); // indicates if folder can be expanded, i.e. folder is not namespace and has at least one subscribed subfolder this.canExpand = ko.computed(function () { return !this.bNamespace && this.hasSubscribedSubfolders(); }, this); this.unseenMessagesCountToShow = ko.computed(function () { return (!App.isMobile() && this.canExpand()) ? this.unseenMessageCount() + this.subfoldersMessagesCount() : this.unseenMessageCount(); }, this); this.showTotalInsteadUnseenCount = ko.observable(false); this.showUnseenMessagesCount = ko.computed(function () { return this.unseenMessagesCountToShow() > 0 && this.type() !== Enums.FolderTypes.Drafts && !this.showTotalInsteadUnseenCount(); }, this); this.showMessagesCount = ko.computed(function () { return this.messageCount() > 0 && (this.type() === Enums.FolderTypes.Drafts || this.showTotalInsteadUnseenCount() || Settings.AllowShowMessagesCountInFolderList && Settings.showMessagesCountInFolderList()); }, this); this.visible = ko.computed(function () { return this.subscribed() || this.isSystem() || this.hasSubscribedSubfolders(); }, this); this.canBeSelected = ko.computed(function () { return this.bExists && this.bSelectable && this.subscribed(); }, this); this.canSubscribe = ko.computed(function () { return !Settings.IgnoreImapSubscription && !this.isSystem() && this.bExists && this.bSelectable; }, this); this.canDelete = ko.computed(function () { return (!this.isSystem() && this.hasExtendedInfo() && this.messageCount() === 0 && this.subfolders().length === 0); }, this); this.canRename = ko.computed(function () { return !this.isSystem() && this.bExists; }, this); this.visibleTemplateTrigger = ko.computed(function () { return Settings.AllowTemplateFolders && (this.bSelectable && !this.isSystem() || this.isTemplateStorage()); }, this); this.templateButtonHint = ko.computed(function () { if (this.visibleTemplateTrigger()) { return this.isTemplateStorage() ? TextUtils.i18n('%MODULENAME%/ACTION_TURN_TEMPLATE_FOLDER_OFF') : TextUtils.i18n('%MODULENAME%/ACTION_TURN_TEMPLATE_FOLDER_ON'); } return ''; }, this); this.alwaysRefreshButtonHint = ko.computed(function () { if (Settings.AllowAlwaysRefreshFolders) { return this.isAlwaysRefresh() ? TextUtils.i18n('%MODULENAME%/ACTION_TURN_ALWAYS_REFRESH_OFF') : TextUtils.i18n('%MODULENAME%/ACTION_TURN_ALWAYS_REFRESH_ON'); } return ''; }, this); this.subscribeButtonHint = ko.computed(function () { if (this.canSubscribe()) { return this.subscribed() ? TextUtils.i18n('%MODULENAME%/ACTION_HIDE_FOLDER') : TextUtils.i18n('%MODULENAME%/ACTION_SHOW_FOLDER'); } return ''; }, this); this.deleteButtonHint = ko.computed(function () { return this.canDelete() ? TextUtils.i18n('%MODULENAME%/ACTION_DELETE_FOLDER') : ''; }, this); this.editButtonHint = ko.computed(function () { return !this.isSystem() && this.bSelectable ? TextUtils.i18n('%MODULENAME%/LABEL_EDIT_FOLDER') : ''; }, this); this.usedAs = ko.computed(function () { switch (this.type()) { case Enums.FolderTypes.Inbox: return TextUtils.i18n('%MODULENAME%/LABEL_USED_AS_INBOX'); case Enums.FolderTypes.Sent: return TextUtils.i18n('%MODULENAME%/LABEL_USED_AS_SENT'); case Enums.FolderTypes.Drafts: return TextUtils.i18n('%MODULENAME%/LABEL_USED_AS_DRAFTS'); case Enums.FolderTypes.Trash: return TextUtils.i18n('%MODULENAME%/LABEL_USED_AS_TRASH'); case Enums.FolderTypes.Spam: return TextUtils.i18n('%MODULENAME%/LABEL_USED_AS_SPAM'); } return ''; }, this); this.displayName = ko.computed(function () { if (this.bIsUnifiedInbox) { return TextUtils.i18n('%MODULENAME%/LABEL_FOLDER_ALL_INBOXES'); } switch (this.type()) { case Enums.FolderTypes.Inbox: return TextUtils.i18n('%MODULENAME%/LABEL_FOLDER_INBOX'); case Enums.FolderTypes.Sent: return TextUtils.i18n('%MODULENAME%/LABEL_FOLDER_SENT'); case Enums.FolderTypes.Drafts: return TextUtils.i18n('%MODULENAME%/LABEL_FOLDER_DRAFTS'); case Enums.FolderTypes.Trash: return TextUtils.i18n('%MODULENAME%/LABEL_FOLDER_TRASH'); case Enums.FolderTypes.Spam: return TextUtils.i18n('%MODULENAME%/LABEL_FOLDER_SPAM'); } return this.name(); }, this); this.displayFullName = ko.computed(function () { if (this.parentDisplayFullName() !== '') { return this.parentDisplayFullName() + this.sDelimiter + this.displayName(); } return this.displayName(); }, this); this.setDisableMoveTo(false); this.setDisableMoveFrom(false); }; CFolderModel.prototype.setShowTotalInsteadUnseenCount = function (bShowTotalInsteadUnseenCount) { this.showTotalInsteadUnseenCount(bShowTotalInsteadUnseenCount); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CFolderModel.prototype.onGetMessageResponse = function (oResponse, oRequest) { var oResult = oResponse.Result, oParameters = oRequest.Parameters, oHand = null, sUid = oResult ? oResult.Uid.toString() : oParameters.Uid.toString(), oMessage = this.getMessageByUid(sUid), bSelected = oMessage ? oMessage.selected() : false, bPassResponse = false ; if (!oResult) { if (bSelected) { Api.showErrorByCode(oResponse, TextUtils.i18n('COREWEBCLIENT/ERROR_UNKNOWN')); } if (oMessage) { Routing.replaceHashWithoutMessageUid(oMessage.longUid()); if (!bSelected && !oMessage.deleted()) { this.removeMessageFromDict(sUid); } } oMessage = null; bPassResponse = true; } else { oMessage = this.parseAndCacheMessage(oResult, false, false); } oHand = this.aResponseHandlers[sUid]; if (oHand) { oHand.handler.call(oHand.context, oMessage, sUid, bPassResponse ? oResponse : null); delete this.aResponseHandlers[sUid]; } }; /** * @param {string} sUid * @param {Function} fResponseHandler * @param {Object} oContext * @param {boolean} bForceAjaxRequest */ CFolderModel.prototype.getCompletelyFilledMessage = function (sUid, fResponseHandler, oContext, bForceAjaxRequest) { var oMessage = this.getMessageByUid(sUid), oParameters = { 'AccountID': oMessage ? oMessage.accountId() : 0, 'Folder': this.fullName(), 'Uid': sUid, 'MessageBodyTruncationThreshold': Settings.MessageBodyTruncationThreshold } ; if (sUid.length > 0) { if (!oMessage || !oMessage.completelyFilled() || oMessage.truncated() || bForceAjaxRequest) { if (fResponseHandler && oContext) { this.aResponseHandlers[sUid] = {handler: fResponseHandler, context: oContext}; } Ajax.send('GetMessage', oParameters, this.onGetMessageResponse, this); } else if (fResponseHandler && oContext) { fResponseHandler.call(oContext, oMessage, sUid); } } }; /** * @param {string} sUid */ CFolderModel.prototype.showExternalPictures = function (sUid) { var oMessage = this.getMessageByUid(sUid); if (oMessage !== undefined) { oMessage.showExternalPictures(); } }; /** * @param {string} sEmail */ CFolderModel.prototype.alwaysShowExternalPicturesForSender = function (sEmail) { this.doForAllMessages(function (oMessage) { var aFrom = oMessage.oFrom.aCollection; if (aFrom.length > 0 && aFrom[0].sEmail === sEmail) { oMessage.alwaysShowExternalPicturesForSender(); } }); }; /** * @param {string} sField * @param {Array} aUids * @param {boolean} bSetAction */ CFolderModel.prototype.executeGroupOperation = function (sField, aUids, bSetAction) { var iUnseenDiff = 0; this.doForAllMessages(function (oMessage) { if (aUids.length > 0) { _.each(aUids, function (sUid) { if (oMessage.uid() === sUid && oMessage[sField]() !== bSetAction) { oMessage[sField](bSetAction); iUnseenDiff++; } }); } else { oMessage[sField](bSetAction); } }); if (aUids.length === 0) { iUnseenDiff = (bSetAction) ? this.unseenMessageCount() : this.messageCount() - this.unseenMessageCount(); } if (sField === 'seen' && iUnseenDiff > 0) { if (bSetAction) { this.addMessagesCountsDiff(0, -iUnseenDiff); MailCache.setUnifiedInboxUnseenChanges(this.iAccountId, this.fullName(), 0, -iUnseenDiff); } else { this.addMessagesCountsDiff(0, iUnseenDiff); MailCache.setUnifiedInboxUnseenChanges(this.iAccountId, this.fullName(), 0, iUnseenDiff); } this.markHasChanges(); this.requireMailCache(); } }; CFolderModel.prototype.emptyFolder = function () { var sWarning = TextUtils.i18n('%MODULENAME%/CONFIRM_EMPTY_FOLDER'), fCallBack = _.bind(this.clearFolder, this) ; if (this.enableEmptyFolder()) { Popups.showPopup(ConfirmPopup, [sWarning, fCallBack]); } }; /** * @param {boolean} bOkAnswer */ CFolderModel.prototype.clearFolder = function (bOkAnswer) { if (this.enableEmptyFolder() && bOkAnswer) { Ajax.send('ClearFolder', { 'Folder': this.fullName() }); this.requireMailCache(); MailCache.onClearFolder(this); // remove all messages from cache should be done after clearing current message in MailCache this.removeAllMessages(); } }; /** * @param {Object} oFolder * @param {Object} oEvent */ CFolderModel.prototype.onAccordion = function (oFolder, oEvent) { var expandedFoldersStorageKey = `aurora_mail_account_${this.iAccountId}_expanded-folders`, bExpanded = !this.expanded(), aFolders = Storage.getData(expandedFoldersStorageKey) || [] ; if (bExpanded) { aFolders.push(this.fullName()); } else { // remove current folder from expanded folders aFolders = _.reject(aFolders, function (sFolder) { return sFolder === this.name(); }, this); } Storage.setData(expandedFoldersStorageKey, aFolders); this.expanded(bExpanded); this.requireMailCache(); MailCache.countMessages(this); if (oEvent) { oEvent.stopPropagation(); } }; CFolderModel.prototype.executeUnseenFilter = function () { var bNotChanged = false; if (this.unseenMessagesCountToShow() > this.unseenMessageCount()) { this.onAccordion(); } if (this.unseenMessageCount() > 0) { this.requireMailCache(); MailCache.waitForUnseenMessages(true); bNotChanged = Routing.setHash(LinksUtils.getMailbox(this.fullName(), 1, '', '', Enums.FolderFilter.Unseen)); if (bNotChanged) { MailCache.changeCurrentMessageList(this.fullName(), 1, '', Enums.FolderFilter.Unseen, Settings.MessagesSortBy.DefaultSortBy, Settings.MessagesSortBy.DefaultSortOrder); } return false; } return true; }; CFolderModel.prototype.onDeleteClick = function () { var sWarning = TextUtils.i18n('%MODULENAME%/CONFIRM_DELETE_FOLDER'), fCallBack = _.bind(this.deleteAfterConfirm, this) ; if (this.canDelete()) { Popups.showPopup(ConfirmPopup, [sWarning, fCallBack]); } else { App.broadcastEvent('%ModuleName%::AttemptDeleteNonemptyFolder'); } }; /** * @param {boolean} bOkAnswer */ CFolderModel.prototype.deleteAfterConfirm = function (bOkAnswer) { if (bOkAnswer) { var oFolderList = MailCache.editedFolderList(), sFolderFullName = this.fullName(), fRemoveFolder = function (oFolder) { if (sFolderFullName === oFolder.fullName()) { return true; } oFolder.subfolders.remove(fRemoveFolder); return false; } ; oFolderList.collection.remove(fRemoveFolder); Ajax.send('DeleteFolder', { 'AccountID': AccountList.editedId(), 'Folder': this.fullName() }, function (oResponse) { if (!oResponse.Result) { Api.showErrorByCode(oResponse, TextUtils.i18n('%MODULENAME%/ERROR_DELETE_FOLDER')); MailCache.getFolderList(AccountList.editedId()); } }, this); } }; CFolderModel.prototype.onSubscribeClick = function () { if (this.canSubscribe()) { var oParameters = { 'AccountID': AccountList.editedId(), 'Folder': this.fullName(), 'SetAction': !this.subscribed() } ; this.subscribed(!this.subscribed()); Ajax.send('SubscribeFolder', oParameters, function (oResponse) { if (!oResponse.Result) { if (this.subscribed()) { Api.showErrorByCode(oResponse, TextUtils.i18n('%MODULENAME%/ERROR_SUBSCRIBE_FOLDER')); } else { Api.showErrorByCode(oResponse, TextUtils.i18n('%MODULENAME%/ERROR_UNSUBSCRIBE_FOLDER')); } MailCache.getFolderList(AccountList.editedId()); } }, this); } }; CFolderModel.prototype.afterMove = function (aParents) { _.each(aParents, function (oParent) { if (_.isFunction(oParent.afterMove)) { oParent.afterMove(); } }); }; CFolderModel.prototype.cancelNameEdit = function () { this.edited(false); }; CFolderModel.prototype.applyNameEdit = function () { if (this.name() !== this.nameForEdit()) { var oParameters = { 'AccountID': AccountList.editedId(), 'PrevFolderFullNameRaw': this.fullName(), 'NewFolderNameInUtf8': this.nameForEdit() } ; Ajax.send('RenameFolder', oParameters, _.bind(this.onResponseFolderRename, this), this); this.name(this.nameForEdit()); } this.edited(false); }; CFolderModel.prototype.onResponseFolderRename = function (oResponse, oRequest) { if (!oResponse || !oResponse.Result) { Api.showErrorByCode(oResponse, TextUtils.i18n('%MODULENAME%/ERROR_RENAME_FOLDER')); MailCache.getFolderList(AccountList.editedId()); } else if (oResponse && oResponse.Result && oResponse.Result.FullName) { var oFolderList = MailCache.editedFolderList(); oFolderList.renameFolder(this.fullName(), oResponse.Result.FullName, oResponse.Result.FullNameHash); } }; CFolderModel.prototype.triggerTemplateState = function () { if (this.visibleTemplateTrigger()) { if (this.isTemplateStorage()) { this.type(Enums.FolderTypes.User); this.isTemplateStorage(false); } else { this.type(Enums.FolderTypes.Template); this.isTemplateStorage(true); } MailCache.changeTemplateFolder(this.fullName(), this.isTemplateStorage()); var oParameters = { 'AccountID': this.iAccountId, 'FolderFullName': this.fullName(), 'SetTemplate': this.isTemplateStorage() } ; Ajax.send('SetTemplateFolderType', oParameters, this.onSetTemplateFolderType, this); } }; CFolderModel.prototype.onSetTemplateFolderType = function (oResponse) { if (!oResponse.Result) { Api.showErrorByCode(oResponse, TextUtils.i18n('%MODULENAME%/ERROR_SETUP_SPECIAL_FOLDERS')); MailCache.getFolderList(AccountList.editedId()); } }; CFolderModel.prototype.openEditFolderPopup = function () { if (!this.isSystem() && this.bSelectable) { var EditFolderPopup = require('modules/%ModuleName%/js/popups/EditFolderPopup.js'); Popups.showPopup(EditFolderPopup, [this]); } }; CFolderModel.prototype.triggerAlwaysRefreshState = function () { if (Settings.AllowAlwaysRefreshFolders) { this.isAlwaysRefresh(!this.isAlwaysRefresh()); var oParameters = { 'AccountID': this.iAccountId, 'FolderFullName': this.fullName(), 'AlwaysRefresh': this.isAlwaysRefresh() } ; Ajax.send('SetAlwaysRefreshFolder', oParameters, this.onSetAlwaysRefreshFolder, this); } }; CFolderModel.prototype.onSetAlwaysRefreshFolder = function (oResponse) { if (!oResponse.Result) { Api.showErrorByCode(oResponse); MailCache.getFolderList(AccountList.editedId()); } }; module.exports = CFolderModel;