mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-30 12:39:20 +03:00
Code refactoring (promises for folders management)
This commit is contained in:
parent
9bec1d0a8f
commit
bab64a7cea
19 changed files with 467 additions and 333 deletions
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
var
|
||||
$ = require('$'),
|
||||
_ = require('_'),
|
||||
Q = require('Q'),
|
||||
|
||||
Consts = require('Common/Consts'),
|
||||
|
|
@ -12,7 +13,9 @@
|
|||
Utils = require('Common/Utils'),
|
||||
Links = require('Common/Links'),
|
||||
|
||||
Settings = require('Storage/Settings')
|
||||
Settings = require('Storage/Settings'),
|
||||
|
||||
AbstractBasicPromises = require('Promises/AbstractBasic')
|
||||
;
|
||||
|
||||
/**
|
||||
|
|
@ -20,21 +23,18 @@
|
|||
*/
|
||||
function AbstractAjaxPromises()
|
||||
{
|
||||
this.oRequests = {};
|
||||
AbstractBasicPromises.call(this);
|
||||
|
||||
this.clear();
|
||||
}
|
||||
|
||||
AbstractAjaxPromises.prototype.func = function (fFunc)
|
||||
{
|
||||
fFunc();
|
||||
_.extend(AbstractAjaxPromises.prototype, AbstractBasicPromises.prototype);
|
||||
|
||||
return this;
|
||||
};
|
||||
AbstractAjaxPromises.prototype.oRequests = {};
|
||||
|
||||
AbstractAjaxPromises.prototype.fastResolve = function (mData)
|
||||
AbstractAjaxPromises.prototype.clear = function ()
|
||||
{
|
||||
var oDeferred = Q.defer();
|
||||
oDeferred.resolve(mData);
|
||||
return oDeferred.promise;
|
||||
this.oRequests = {};
|
||||
};
|
||||
|
||||
AbstractAjaxPromises.prototype.abort = function (sAction, bClearOnly)
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
{
|
||||
if (!bClearOnly && this.oRequests[sAction].abort)
|
||||
{
|
||||
this.oRequests[sAction].__aborted = true;
|
||||
this.oRequests[sAction].__aborted__ = true;
|
||||
this.oRequests[sAction].abort();
|
||||
}
|
||||
|
||||
|
|
@ -71,10 +71,7 @@
|
|||
oParameters['XToken'] = Settings.settingsGet('Token');
|
||||
}
|
||||
|
||||
if (fTrigger)
|
||||
{
|
||||
fTrigger(true);
|
||||
}
|
||||
this.setTrigger(fTrigger, true);
|
||||
|
||||
oH = $.ajax({
|
||||
'type': bPost ? 'POST' : 'GET',
|
||||
|
|
@ -96,8 +93,8 @@
|
|||
{
|
||||
if (oData && oData.Result && sAction === oData.Action)
|
||||
{
|
||||
oData.Result.__cached__ = bCached;
|
||||
oDeferred.resolve(oData.Result);
|
||||
oData.__cached__ = bCached;
|
||||
oDeferred.resolve(oData);
|
||||
}
|
||||
else if (oData && oData.Action)
|
||||
{
|
||||
|
|
@ -114,7 +111,7 @@
|
|||
}
|
||||
else if ('abort' === sTextStatus)
|
||||
{
|
||||
if (!oData || !oData.__aborted)
|
||||
if (!oData || !oData.__aborted__)
|
||||
{
|
||||
oDeferred.reject(Enums.Notification.AjaxAbort);
|
||||
}
|
||||
|
|
@ -130,10 +127,7 @@
|
|||
delete self.oRequests[sAction];
|
||||
}
|
||||
|
||||
if (fTrigger)
|
||||
{
|
||||
fTrigger(false);
|
||||
}
|
||||
self.setTrigger(fTrigger, false);
|
||||
});
|
||||
|
||||
if (oH)
|
||||
|
|
|
|||
56
dev/Promises/AbstractBasic.js
Normal file
56
dev/Promises/AbstractBasic.js
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
(function () {
|
||||
|
||||
'use strict';
|
||||
|
||||
var
|
||||
_ = require('_'),
|
||||
Q = require('Q'),
|
||||
|
||||
Utils = require('Common/Utils')
|
||||
;
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
function AbstractBasicPromises()
|
||||
{
|
||||
this.oPromisesStack = {};
|
||||
}
|
||||
|
||||
AbstractBasicPromises.prototype.func = function (fFunc)
|
||||
{
|
||||
fFunc();
|
||||
return this;
|
||||
};
|
||||
|
||||
AbstractBasicPromises.prototype.fastResolve = function (mData)
|
||||
{
|
||||
var oDeferred = Q.defer();
|
||||
oDeferred.resolve(mData);
|
||||
return oDeferred.promise;
|
||||
};
|
||||
|
||||
AbstractBasicPromises.prototype.fastReject = function (mData)
|
||||
{
|
||||
var oDeferred = Q.defer();
|
||||
oDeferred.reject(mData);
|
||||
return oDeferred.promise;
|
||||
};
|
||||
|
||||
AbstractBasicPromises.prototype.setTrigger = function (mTrigger, bValue)
|
||||
{
|
||||
if (mTrigger)
|
||||
{
|
||||
_.each(Utils.isArray(mTrigger) ? mTrigger : [mTrigger], function (fTrigger) {
|
||||
if (fTrigger)
|
||||
{
|
||||
fTrigger(!!bValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = AbstractBasicPromises;
|
||||
|
||||
}());
|
||||
|
|
@ -4,8 +4,20 @@
|
|||
'use strict';
|
||||
|
||||
var
|
||||
window = require('window'),
|
||||
_ = require('_'),
|
||||
|
||||
// Enums = require('Common/Enums'),
|
||||
// Utils = require('Common/Utils'),
|
||||
// Base64 = require('Common/Base64'),
|
||||
// Cache = require('Common/Cache'),
|
||||
//
|
||||
// AppStore = require('Stores/User/App'),
|
||||
// SettingsStore = require('Stores/User/Settings'),
|
||||
|
||||
MessageSimpleModel = require('Model/MessageSimple'),
|
||||
|
||||
PromisesPopulator = require('Promises/User/Populator'),
|
||||
AbstractAjaxPromises = require('Promises/AbstractAjax')
|
||||
;
|
||||
|
||||
|
|
@ -13,17 +25,19 @@
|
|||
* @constructor
|
||||
* @extends AbstractAjaxPromises
|
||||
*/
|
||||
function PromisesUserAjax()
|
||||
function UserAjaxUserPromises()
|
||||
{
|
||||
AbstractAjaxPromises.call(this);
|
||||
|
||||
this.messageListSimpleHash = '';
|
||||
this.messageListSimpleCache = null;
|
||||
|
||||
this.sSubSubQuery = '&ss=/';
|
||||
}
|
||||
|
||||
_.extend(PromisesUserAjax.prototype, AbstractAjaxPromises.prototype);
|
||||
_.extend(UserAjaxUserPromises.prototype, AbstractAjaxPromises.prototype);
|
||||
|
||||
PromisesUserAjax.prototype.messageListSimple = function (sFolder, aUids, fTrigger)
|
||||
UserAjaxUserPromises.prototype.messageListSimple = function (sFolder, aUids, fTrigger)
|
||||
{
|
||||
var self = this, sHash = sFolder + '~' + aUids.join('/');
|
||||
if (sHash === this.messageListSimpleHash && this.messageListSimpleCache)
|
||||
|
|
@ -35,23 +49,93 @@
|
|||
.postRequest('MessageListSimple', fTrigger, {
|
||||
'Folder': sFolder,
|
||||
'Uids': aUids
|
||||
}).then(function (aData) {
|
||||
|
||||
var
|
||||
MessageSimpleModel = require('Model/MessageSimple'),
|
||||
aResult = _.compact(_.map(aData, function (aItem) {
|
||||
return MessageSimpleModel.newInstanceFromJson(aItem);
|
||||
}))
|
||||
;
|
||||
}).then(function (oData) {
|
||||
|
||||
self.messageListSimpleHash = sHash;
|
||||
self.messageListSimpleCache = aResult;
|
||||
self.messageListSimpleCache = _.compact(_.map(oData.Result, function (aItem) {
|
||||
return MessageSimpleModel.newInstanceFromJson(aItem);
|
||||
}));
|
||||
|
||||
return aResult;
|
||||
return self.messageListSimpleCache;
|
||||
|
||||
}, function (iError) {
|
||||
|
||||
self.messageListSimpleHash = '';
|
||||
self.messageListSimpleCache = null;
|
||||
|
||||
return self.fastReject(iError);
|
||||
})
|
||||
;
|
||||
};
|
||||
|
||||
module.exports = new PromisesUserAjax();
|
||||
UserAjaxUserPromises.prototype.foldersReload = function (fTrigger)
|
||||
{
|
||||
return this.abort('Folders')
|
||||
.postRequest('Folders', fTrigger).then(function (oData) {
|
||||
PromisesPopulator.foldersList(oData.Result);
|
||||
PromisesPopulator.foldersAdditionalParameters(oData.Result);
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
UserAjaxUserPromises.prototype._folders_timeout_ = 0;
|
||||
UserAjaxUserPromises.prototype.foldersReloadWithTimeout = function (fTrigger)
|
||||
{
|
||||
this.setTrigger(fTrigger, true);
|
||||
|
||||
var self = this;
|
||||
window.clearTimeout(this._folders_timeout_);
|
||||
this._folders_timeout_ = window.setTimeout(function () {
|
||||
self.foldersReload(fTrigger);
|
||||
}, 500);
|
||||
};
|
||||
|
||||
|
||||
UserAjaxUserPromises.prototype.folderDelete = function (sFolderFullNameRaw, fTrigger)
|
||||
{
|
||||
return this.postRequest('FolderDelete', fTrigger, {
|
||||
'Folder': sFolderFullNameRaw
|
||||
});
|
||||
};
|
||||
|
||||
UserAjaxUserPromises.prototype.folderCreate = function (sNewFolderName, sParentName, fTrigger)
|
||||
{
|
||||
return this.postRequest('FolderCreate', fTrigger, {
|
||||
'Folder': sNewFolderName,
|
||||
'Parent': sParentName
|
||||
});
|
||||
};
|
||||
|
||||
UserAjaxUserPromises.prototype.folderRename = function (sPrevFolderFullNameRaw, sNewFolderName, fTrigger)
|
||||
{
|
||||
return this.postRequest('FolderRename', fTrigger, {
|
||||
'Folder': sPrevFolderFullNameRaw,
|
||||
'NewFolderName': sNewFolderName
|
||||
});
|
||||
};
|
||||
|
||||
// UserAjaxUserPromises.prototype.message = function (sFolderFullNameRaw, iUid, fTrigger)
|
||||
// {
|
||||
// sFolderFullNameRaw = Utils.pString(sFolderFullNameRaw);
|
||||
// iUid = Utils.pInt(iUid);
|
||||
//
|
||||
// if (Cache.getFolderFromCacheList(sFolderFullNameRaw) && 0 >= iUid)
|
||||
// {
|
||||
// return this.abort('Message')
|
||||
// .getRequest('Message', fTrigger,
|
||||
// this.sSubSubQuery + Base64.urlsafe_encode([
|
||||
// sFolderFullNameRaw, iUid,
|
||||
// AppStore.projectHash(),
|
||||
// AppStore.threadsAllowed() && SettingsStore.useThreads() ? '1' : '0'
|
||||
// ].join(String.fromCharCode(0))))
|
||||
// .then(function (oData) {
|
||||
// return oData;
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// return this.fastReject(Enums.Notification.UnknownError);
|
||||
// };
|
||||
|
||||
module.exports = new UserAjaxUserPromises();
|
||||
|
||||
}());
|
||||
199
dev/Promises/User/Populator.js
Normal file
199
dev/Promises/User/Populator.js
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
|
||||
(function () {
|
||||
|
||||
'use strict';
|
||||
|
||||
var
|
||||
_ = require('_'),
|
||||
|
||||
Consts = require('Common/Consts'),
|
||||
Enums = require('Common/Enums'),
|
||||
Utils = require('Common/Utils'),
|
||||
Cache = require('Common/Cache'),
|
||||
|
||||
AppStore = require('Stores/User/App'),
|
||||
FolderStore = require('Stores/User/Folder'),
|
||||
|
||||
Settings = require('Storage/Settings'),
|
||||
Local = require('Storage/Client'),
|
||||
|
||||
FolderModel = require('Model/Folder'),
|
||||
|
||||
AbstractBasicPromises = require('Promises/AbstractBasic')
|
||||
;
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
function PromisesUserPopulator()
|
||||
{
|
||||
AbstractBasicPromises.call(this);
|
||||
}
|
||||
|
||||
_.extend(PromisesUserPopulator.prototype, AbstractBasicPromises.prototype);
|
||||
|
||||
/**
|
||||
* @param {string} sFullNameHash
|
||||
* @return {boolean}
|
||||
*/
|
||||
PromisesUserPopulator.prototype.isFolderExpanded = function (sFullNameHash)
|
||||
{
|
||||
var aExpandedList = Local.get(Enums.ClientSideKeyName.ExpandedFolders);
|
||||
return Utils.isArray(aExpandedList) && -1 !== _.indexOf(aExpandedList, sFullNameHash);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolderFullNameRaw
|
||||
* @return {string}
|
||||
*/
|
||||
PromisesUserPopulator.prototype.normalizeFolder = function (sFolderFullNameRaw)
|
||||
{
|
||||
return ('' === sFolderFullNameRaw || Consts.Values.UnuseOptionValue === sFolderFullNameRaw ||
|
||||
null !== Cache.getFolderFromCacheList(sFolderFullNameRaw)) ? sFolderFullNameRaw : '';
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sNamespace
|
||||
* @param {Array} aFolders
|
||||
* @return {Array}
|
||||
*/
|
||||
PromisesUserPopulator.prototype.folderResponseParseRec = function (sNamespace, aFolders)
|
||||
{
|
||||
var
|
||||
self = this,
|
||||
iIndex = 0,
|
||||
iLen = 0,
|
||||
oFolder = null,
|
||||
oCacheFolder = null,
|
||||
sFolderFullNameRaw = '',
|
||||
aSubFolders = [],
|
||||
aList = []
|
||||
;
|
||||
|
||||
for (iIndex = 0, iLen = aFolders.length; iIndex < iLen; iIndex++)
|
||||
{
|
||||
oFolder = aFolders[iIndex];
|
||||
if (oFolder)
|
||||
{
|
||||
sFolderFullNameRaw = oFolder.FullNameRaw;
|
||||
|
||||
oCacheFolder = Cache.getFolderFromCacheList(sFolderFullNameRaw);
|
||||
if (!oCacheFolder)
|
||||
{
|
||||
oCacheFolder = FolderModel.newInstanceFromJson(oFolder);
|
||||
if (oCacheFolder)
|
||||
{
|
||||
Cache.setFolderToCacheList(sFolderFullNameRaw, oCacheFolder);
|
||||
Cache.setFolderFullNameRaw(oCacheFolder.fullNameHash, sFolderFullNameRaw, oCacheFolder);
|
||||
}
|
||||
}
|
||||
|
||||
if (oCacheFolder)
|
||||
{
|
||||
oCacheFolder.collapsed(!self.isFolderExpanded(oCacheFolder.fullNameHash));
|
||||
|
||||
if (oFolder.Extended)
|
||||
{
|
||||
if (oFolder.Extended.Hash)
|
||||
{
|
||||
Cache.setFolderHash(oCacheFolder.fullNameRaw, oFolder.Extended.Hash);
|
||||
}
|
||||
|
||||
if (Utils.isNormal(oFolder.Extended.MessageCount))
|
||||
{
|
||||
oCacheFolder.messageCountAll(oFolder.Extended.MessageCount);
|
||||
}
|
||||
|
||||
if (Utils.isNormal(oFolder.Extended.MessageUnseenCount))
|
||||
{
|
||||
oCacheFolder.messageCountUnread(oFolder.Extended.MessageUnseenCount);
|
||||
}
|
||||
}
|
||||
|
||||
aSubFolders = oFolder['SubFolders'];
|
||||
if (aSubFolders && 'Collection/FolderCollection' === aSubFolders['@Object'] &&
|
||||
aSubFolders['@Collection'] && Utils.isArray(aSubFolders['@Collection']))
|
||||
{
|
||||
oCacheFolder.subFolders(
|
||||
this.folderResponseParseRec(sNamespace, aSubFolders['@Collection']));
|
||||
}
|
||||
|
||||
aList.push(oCacheFolder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return aList;
|
||||
};
|
||||
|
||||
PromisesUserPopulator.prototype.foldersList = function (oData)
|
||||
{
|
||||
if (oData && 'Collection/FolderCollection' === oData['@Object'] &&
|
||||
oData['@Collection'] && Utils.isArray(oData['@Collection']))
|
||||
{
|
||||
FolderStore.folderList(this.folderResponseParseRec(
|
||||
Utils.isUnd(oData.Namespace) ? '' : oData.Namespace, oData['@Collection']));
|
||||
}
|
||||
};
|
||||
|
||||
PromisesUserPopulator.prototype.foldersAdditionalParameters = function (oData)
|
||||
{
|
||||
if (oData && oData && 'Collection/FolderCollection' === oData['@Object'] &&
|
||||
oData['@Collection'] && Utils.isArray(oData['@Collection']))
|
||||
{
|
||||
if (!Utils.isUnd(oData.Namespace))
|
||||
{
|
||||
FolderStore.namespace = oData.Namespace;
|
||||
}
|
||||
|
||||
AppStore.threadsAllowed(
|
||||
!!Settings.settingsGet('UseImapThread') &&
|
||||
oData.IsThreadsSupported && true);
|
||||
|
||||
FolderStore.folderList.optimized(!!oData.Optimized);
|
||||
|
||||
var bUpdate = false;
|
||||
|
||||
if (oData['SystemFolders'] && '' === '' +
|
||||
Settings.settingsGet('SentFolder') +
|
||||
Settings.settingsGet('DraftFolder') +
|
||||
Settings.settingsGet('SpamFolder') +
|
||||
Settings.settingsGet('TrashFolder') +
|
||||
Settings.settingsGet('ArchiveFolder') +
|
||||
Settings.settingsGet('NullFolder'))
|
||||
{
|
||||
// TODO Magic Numbers
|
||||
Settings.settingsSet('SentFolder', oData['SystemFolders'][2] || null);
|
||||
Settings.settingsSet('DraftFolder', oData['SystemFolders'][3] || null);
|
||||
Settings.settingsSet('SpamFolder', oData['SystemFolders'][4] || null);
|
||||
Settings.settingsSet('TrashFolder', oData['SystemFolders'][5] || null);
|
||||
Settings.settingsSet('ArchiveFolder', oData['SystemFolders'][12] || null);
|
||||
|
||||
bUpdate = true;
|
||||
}
|
||||
|
||||
FolderStore.sentFolder(this.normalizeFolder(Settings.settingsGet('SentFolder')));
|
||||
FolderStore.draftFolder(this.normalizeFolder(Settings.settingsGet('DraftFolder')));
|
||||
FolderStore.spamFolder(this.normalizeFolder(Settings.settingsGet('SpamFolder')));
|
||||
FolderStore.trashFolder(this.normalizeFolder(Settings.settingsGet('TrashFolder')));
|
||||
FolderStore.archiveFolder(this.normalizeFolder(Settings.settingsGet('ArchiveFolder')));
|
||||
|
||||
if (bUpdate)
|
||||
{
|
||||
require('Remote/User/Ajax').saveSystemFolders(Utils.emptyFunction, {
|
||||
'SentFolder': FolderStore.sentFolder(),
|
||||
'DraftFolder': FolderStore.draftFolder(),
|
||||
'SpamFolder': FolderStore.spamFolder(),
|
||||
'TrashFolder': FolderStore.trashFolder(),
|
||||
'ArchiveFolder': FolderStore.archiveFolder(),
|
||||
'NullFolder': 'NullFolder'
|
||||
});
|
||||
}
|
||||
|
||||
Local.set(Enums.ClientSideKeyName.FoldersLashHash, oData.FoldersHash);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = new PromisesUserPopulator();
|
||||
|
||||
}());
|
||||
Loading…
Add table
Add a link
Reference in a new issue