mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +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
198
dev/App/User.js
198
dev/App/User.js
|
|
@ -26,7 +26,6 @@
|
||||||
Cache = require('Common/Cache'),
|
Cache = require('Common/Cache'),
|
||||||
|
|
||||||
SocialStore = require('Stores/Social'),
|
SocialStore = require('Stores/Social'),
|
||||||
AppStore = require('Stores/User/App'),
|
|
||||||
SettingsStore = require('Stores/User/Settings'),
|
SettingsStore = require('Stores/User/Settings'),
|
||||||
AccountStore = require('Stores/User/Account'),
|
AccountStore = require('Stores/User/Account'),
|
||||||
IdentityStore = require('Stores/User/Identity'),
|
IdentityStore = require('Stores/User/Identity'),
|
||||||
|
|
@ -40,9 +39,9 @@
|
||||||
Settings = require('Storage/Settings'),
|
Settings = require('Storage/Settings'),
|
||||||
|
|
||||||
Remote = require('Remote/User/Ajax'),
|
Remote = require('Remote/User/Ajax'),
|
||||||
|
Promises = require('Promises/User/Ajax'),
|
||||||
|
|
||||||
EmailModel = require('Model/Email'),
|
EmailModel = require('Model/Email'),
|
||||||
FolderModel = require('Model/Folder'),
|
|
||||||
AccountModel = require('Model/Account'),
|
AccountModel = require('Model/Account'),
|
||||||
IdentityModel = require('Model/Identity'),
|
IdentityModel = require('Model/Identity'),
|
||||||
TemplateModel = require('Model/Template'),
|
TemplateModel = require('Model/Template'),
|
||||||
|
|
@ -434,27 +433,35 @@
|
||||||
/**
|
/**
|
||||||
* @param {Function=} fCallback
|
* @param {Function=} fCallback
|
||||||
*/
|
*/
|
||||||
AppUser.prototype.folders = function (fCallback)
|
AppUser.prototype.foldersReload = function (fCallback)
|
||||||
{
|
{
|
||||||
FolderStore.foldersLoading(true);
|
Promises.foldersReload(FolderStore.foldersLoading).then(function (bValue) {
|
||||||
|
|
||||||
Remote.folders(_.bind(function (sResult, oData) {
|
|
||||||
|
|
||||||
var bResult = false;
|
|
||||||
FolderStore.foldersLoading(false);
|
|
||||||
|
|
||||||
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
|
|
||||||
{
|
|
||||||
bResult = true;
|
|
||||||
this.setFolders(oData);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fCallback)
|
if (fCallback)
|
||||||
{
|
{
|
||||||
fCallback(bResult);
|
fCallback(!!bValue);
|
||||||
}
|
}
|
||||||
|
}).fail(function () {
|
||||||
|
if (fCallback)
|
||||||
|
{
|
||||||
|
fCallback(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
}, this));
|
AppUser.prototype.foldersPromisesActionHelper = function (oPromise, iErrorDefCode)
|
||||||
|
{
|
||||||
|
Promises
|
||||||
|
.abort('Folders')
|
||||||
|
.fastResolve(true)
|
||||||
|
.then(function () {
|
||||||
|
return oPromise;
|
||||||
|
})
|
||||||
|
.fail(function (iErrorCode) {
|
||||||
|
FolderStore.folderList.error(Translator.getNotification(iErrorCode, '', iErrorDefCode));
|
||||||
|
}).fin(function () {
|
||||||
|
Promises.foldersReloadWithTimeout(FolderStore.foldersLoading);
|
||||||
|
}).done()
|
||||||
|
;
|
||||||
};
|
};
|
||||||
|
|
||||||
AppUser.prototype.reloadOpenPgpKeys = function ()
|
AppUser.prototype.reloadOpenPgpKeys = function ()
|
||||||
|
|
@ -1026,157 +1033,6 @@
|
||||||
}, sQuery);
|
}, sQuery);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} sNamespace
|
|
||||||
* @param {Array} aFolders
|
|
||||||
* @return {Array}
|
|
||||||
*/
|
|
||||||
AppUser.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;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {*} oData
|
|
||||||
*/
|
|
||||||
AppUser.prototype.setFolders = function (oData)
|
|
||||||
{
|
|
||||||
var
|
|
||||||
bUpdate = false,
|
|
||||||
fNormalizeFolder = function (sFolderFullNameRaw) {
|
|
||||||
return ('' === sFolderFullNameRaw || Consts.Values.UnuseOptionValue === sFolderFullNameRaw ||
|
|
||||||
null !== Cache.getFolderFromCacheList(sFolderFullNameRaw)) ? sFolderFullNameRaw : '';
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
if (oData && oData.Result && 'Collection/FolderCollection' === oData.Result['@Object'] &&
|
|
||||||
oData.Result['@Collection'] && Utils.isArray(oData.Result['@Collection']))
|
|
||||||
{
|
|
||||||
if (!Utils.isUnd(oData.Result.Namespace))
|
|
||||||
{
|
|
||||||
FolderStore.namespace = oData.Result.Namespace;
|
|
||||||
}
|
|
||||||
|
|
||||||
AppStore.threadsAllowed(!!Settings.settingsGet('UseImapThread') &&
|
|
||||||
oData.Result.IsThreadsSupported && true);
|
|
||||||
|
|
||||||
FolderStore.folderList(this.folderResponseParseRec(FolderStore.namespace, oData.Result['@Collection']));
|
|
||||||
FolderStore.folderList.optimized(!!oData.Result.Optimized);
|
|
||||||
|
|
||||||
if (oData.Result['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.Result['SystemFolders'][2] || null);
|
|
||||||
Settings.settingsSet('DraftFolder', oData.Result['SystemFolders'][3] || null);
|
|
||||||
Settings.settingsSet('SpamFolder', oData.Result['SystemFolders'][4] || null);
|
|
||||||
Settings.settingsSet('TrashFolder', oData.Result['SystemFolders'][5] || null);
|
|
||||||
Settings.settingsSet('ArchiveFolder', oData.Result['SystemFolders'][12] || null);
|
|
||||||
|
|
||||||
bUpdate = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
FolderStore.sentFolder(fNormalizeFolder(Settings.settingsGet('SentFolder')));
|
|
||||||
FolderStore.draftFolder(fNormalizeFolder(Settings.settingsGet('DraftFolder')));
|
|
||||||
FolderStore.spamFolder(fNormalizeFolder(Settings.settingsGet('SpamFolder')));
|
|
||||||
FolderStore.trashFolder(fNormalizeFolder(Settings.settingsGet('TrashFolder')));
|
|
||||||
FolderStore.archiveFolder(fNormalizeFolder(Settings.settingsGet('ArchiveFolder')));
|
|
||||||
|
|
||||||
if (bUpdate)
|
|
||||||
{
|
|
||||||
Remote.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.Result.FoldersHash);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} sFullNameHash
|
|
||||||
* @return {boolean}
|
|
||||||
*/
|
|
||||||
AppUser.prototype.isFolderExpanded = function (sFullNameHash)
|
|
||||||
{
|
|
||||||
var aExpandedList = Local.get(Enums.ClientSideKeyName.ExpandedFolders);
|
|
||||||
return Utils.isArray(aExpandedList) && -1 !== _.indexOf(aExpandedList, sFullNameHash);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} sFullNameHash
|
* @param {string} sFullNameHash
|
||||||
* @param {boolean} bExpanded
|
* @param {boolean} bExpanded
|
||||||
|
|
@ -1429,7 +1285,7 @@
|
||||||
|
|
||||||
//require.ensure([], function() { // require code splitting
|
//require.ensure([], function() { // require code splitting
|
||||||
|
|
||||||
self.folders(_.bind(function (bValue) {
|
self.foldersReload(_.bind(function (bValue) {
|
||||||
|
|
||||||
kn.hideLoading();
|
kn.hideLoading();
|
||||||
|
|
||||||
|
|
@ -1498,7 +1354,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
Events.sub('interval.20m', function () {
|
Events.sub('interval.20m', function () {
|
||||||
self.folders();
|
self.foldersReload();
|
||||||
});
|
});
|
||||||
|
|
||||||
iContactsSyncInterval = 5 <= iContactsSyncInterval ? iContactsSyncInterval : 20;
|
iContactsSyncInterval = 5 <= iContactsSyncInterval ? iContactsSyncInterval : 20;
|
||||||
|
|
|
||||||
|
|
@ -235,9 +235,10 @@
|
||||||
/**
|
/**
|
||||||
* @param {number} iCode
|
* @param {number} iCode
|
||||||
* @param {*=} mMessage = ''
|
* @param {*=} mMessage = ''
|
||||||
|
* @param {*=} mDefCode = null
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
Translator.prototype.getNotification = function (iCode, mMessage)
|
Translator.prototype.getNotification = function (iCode, mMessage, mDefCode)
|
||||||
{
|
{
|
||||||
iCode = window.parseInt(iCode, 10) || 0;
|
iCode = window.parseInt(iCode, 10) || 0;
|
||||||
if (Enums.Notification.ClientViewError === iCode && mMessage)
|
if (Enums.Notification.ClientViewError === iCode && mMessage)
|
||||||
|
|
@ -245,7 +246,9 @@
|
||||||
return mMessage;
|
return mMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _.isUndefined(this.notificationI18N[iCode]) ? '' : this.notificationI18N[iCode];
|
return _.isUndefined(this.notificationI18N[iCode]) ? (
|
||||||
|
mDefCode && _.isUndefined(this.notificationI18N[mDefCode]) ? this.notificationI18N[mDefCode] : ''
|
||||||
|
) : this.notificationI18N[iCode];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -20,30 +20,18 @@
|
||||||
{
|
{
|
||||||
AbstractModel.call(this, 'MessageSimpleModel');
|
AbstractModel.call(this, 'MessageSimpleModel');
|
||||||
|
|
||||||
this.selected = false;
|
this.clear();
|
||||||
|
|
||||||
this.folderFullNameRaw = '';
|
|
||||||
this.uid = '';
|
|
||||||
this.size = 0;
|
|
||||||
|
|
||||||
this.sender = '';
|
|
||||||
this.subject = '';
|
|
||||||
|
|
||||||
this.dateUTC = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_.extend(MessageSimpleModel.prototype, AbstractModel.prototype);
|
_.extend(MessageSimpleModel.prototype, AbstractModel.prototype);
|
||||||
|
|
||||||
/**
|
MessageSimpleModel.prototype.selected = false;
|
||||||
* @static
|
MessageSimpleModel.prototype.folderFullNameRaw = '';
|
||||||
* @param {AjaxJsonMessage} oJsonMessage
|
MessageSimpleModel.prototype.uid = '';
|
||||||
* @return {?MessageSimpleModel}
|
MessageSimpleModel.prototype.size = 0;
|
||||||
*/
|
MessageSimpleModel.prototype.sender = '';
|
||||||
MessageSimpleModel.newInstanceFromJson = function (oJsonMessage)
|
MessageSimpleModel.prototype.subject = '';
|
||||||
{
|
MessageSimpleModel.prototype.dateInUTC = 0;
|
||||||
var oMessageModel = new MessageSimpleModel();
|
|
||||||
return oMessageModel.initByJson(oJsonMessage) ? oMessageModel : null;
|
|
||||||
};
|
|
||||||
|
|
||||||
MessageSimpleModel.prototype.clear = function ()
|
MessageSimpleModel.prototype.clear = function ()
|
||||||
{
|
{
|
||||||
|
|
@ -56,7 +44,7 @@
|
||||||
this.sender = '';
|
this.sender = '';
|
||||||
this.subject = '';
|
this.subject = '';
|
||||||
|
|
||||||
this.dateUTC = 0;
|
this.dateInUTC = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -80,7 +68,7 @@
|
||||||
|
|
||||||
this.subject = oJsonMessage.Subject;
|
this.subject = oJsonMessage.Subject;
|
||||||
|
|
||||||
this.dateUTC = Utils.pInt(oJsonMessage.DateTimeStampInUTC);
|
this.dateInUTC = Utils.pInt(oJsonMessage.DateTimeStampInUTC);
|
||||||
|
|
||||||
bResult = true;
|
bResult = true;
|
||||||
}
|
}
|
||||||
|
|
@ -88,6 +76,17 @@
|
||||||
return bResult;
|
return bResult;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @static
|
||||||
|
* @param {AjaxJsonMessage} oJsonMessage
|
||||||
|
* @return {?MessageSimpleModel}
|
||||||
|
*/
|
||||||
|
MessageSimpleModel.newInstanceFromJson = function (oJsonMessage)
|
||||||
|
{
|
||||||
|
var oMessageModel = new MessageSimpleModel();
|
||||||
|
return oMessageModel.initByJson(oJsonMessage) ? oMessageModel : null;
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = MessageSimpleModel;
|
module.exports = MessageSimpleModel;
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
var
|
var
|
||||||
$ = require('$'),
|
$ = require('$'),
|
||||||
|
_ = require('_'),
|
||||||
Q = require('Q'),
|
Q = require('Q'),
|
||||||
|
|
||||||
Consts = require('Common/Consts'),
|
Consts = require('Common/Consts'),
|
||||||
|
|
@ -12,7 +13,9 @@
|
||||||
Utils = require('Common/Utils'),
|
Utils = require('Common/Utils'),
|
||||||
Links = require('Common/Links'),
|
Links = require('Common/Links'),
|
||||||
|
|
||||||
Settings = require('Storage/Settings')
|
Settings = require('Storage/Settings'),
|
||||||
|
|
||||||
|
AbstractBasicPromises = require('Promises/AbstractBasic')
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -20,21 +23,18 @@
|
||||||
*/
|
*/
|
||||||
function AbstractAjaxPromises()
|
function AbstractAjaxPromises()
|
||||||
{
|
{
|
||||||
this.oRequests = {};
|
AbstractBasicPromises.call(this);
|
||||||
|
|
||||||
|
this.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractAjaxPromises.prototype.func = function (fFunc)
|
_.extend(AbstractAjaxPromises.prototype, AbstractBasicPromises.prototype);
|
||||||
{
|
|
||||||
fFunc();
|
|
||||||
|
|
||||||
return this;
|
AbstractAjaxPromises.prototype.oRequests = {};
|
||||||
};
|
|
||||||
|
|
||||||
AbstractAjaxPromises.prototype.fastResolve = function (mData)
|
AbstractAjaxPromises.prototype.clear = function ()
|
||||||
{
|
{
|
||||||
var oDeferred = Q.defer();
|
this.oRequests = {};
|
||||||
oDeferred.resolve(mData);
|
|
||||||
return oDeferred.promise;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
AbstractAjaxPromises.prototype.abort = function (sAction, bClearOnly)
|
AbstractAjaxPromises.prototype.abort = function (sAction, bClearOnly)
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
{
|
{
|
||||||
if (!bClearOnly && this.oRequests[sAction].abort)
|
if (!bClearOnly && this.oRequests[sAction].abort)
|
||||||
{
|
{
|
||||||
this.oRequests[sAction].__aborted = true;
|
this.oRequests[sAction].__aborted__ = true;
|
||||||
this.oRequests[sAction].abort();
|
this.oRequests[sAction].abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,10 +71,7 @@
|
||||||
oParameters['XToken'] = Settings.settingsGet('Token');
|
oParameters['XToken'] = Settings.settingsGet('Token');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fTrigger)
|
this.setTrigger(fTrigger, true);
|
||||||
{
|
|
||||||
fTrigger(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
oH = $.ajax({
|
oH = $.ajax({
|
||||||
'type': bPost ? 'POST' : 'GET',
|
'type': bPost ? 'POST' : 'GET',
|
||||||
|
|
@ -96,8 +93,8 @@
|
||||||
{
|
{
|
||||||
if (oData && oData.Result && sAction === oData.Action)
|
if (oData && oData.Result && sAction === oData.Action)
|
||||||
{
|
{
|
||||||
oData.Result.__cached__ = bCached;
|
oData.__cached__ = bCached;
|
||||||
oDeferred.resolve(oData.Result);
|
oDeferred.resolve(oData);
|
||||||
}
|
}
|
||||||
else if (oData && oData.Action)
|
else if (oData && oData.Action)
|
||||||
{
|
{
|
||||||
|
|
@ -114,7 +111,7 @@
|
||||||
}
|
}
|
||||||
else if ('abort' === sTextStatus)
|
else if ('abort' === sTextStatus)
|
||||||
{
|
{
|
||||||
if (!oData || !oData.__aborted)
|
if (!oData || !oData.__aborted__)
|
||||||
{
|
{
|
||||||
oDeferred.reject(Enums.Notification.AjaxAbort);
|
oDeferred.reject(Enums.Notification.AjaxAbort);
|
||||||
}
|
}
|
||||||
|
|
@ -130,10 +127,7 @@
|
||||||
delete self.oRequests[sAction];
|
delete self.oRequests[sAction];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fTrigger)
|
self.setTrigger(fTrigger, false);
|
||||||
{
|
|
||||||
fTrigger(false);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (oH)
|
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';
|
'use strict';
|
||||||
|
|
||||||
var
|
var
|
||||||
|
window = require('window'),
|
||||||
_ = require('_'),
|
_ = 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')
|
AbstractAjaxPromises = require('Promises/AbstractAjax')
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -13,17 +25,19 @@
|
||||||
* @constructor
|
* @constructor
|
||||||
* @extends AbstractAjaxPromises
|
* @extends AbstractAjaxPromises
|
||||||
*/
|
*/
|
||||||
function PromisesUserAjax()
|
function UserAjaxUserPromises()
|
||||||
{
|
{
|
||||||
AbstractAjaxPromises.call(this);
|
AbstractAjaxPromises.call(this);
|
||||||
|
|
||||||
this.messageListSimpleHash = '';
|
this.messageListSimpleHash = '';
|
||||||
this.messageListSimpleCache = null;
|
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('/');
|
var self = this, sHash = sFolder + '~' + aUids.join('/');
|
||||||
if (sHash === this.messageListSimpleHash && this.messageListSimpleCache)
|
if (sHash === this.messageListSimpleHash && this.messageListSimpleCache)
|
||||||
|
|
@ -35,23 +49,93 @@
|
||||||
.postRequest('MessageListSimple', fTrigger, {
|
.postRequest('MessageListSimple', fTrigger, {
|
||||||
'Folder': sFolder,
|
'Folder': sFolder,
|
||||||
'Uids': aUids
|
'Uids': aUids
|
||||||
}).then(function (aData) {
|
}).then(function (oData) {
|
||||||
|
|
||||||
var
|
|
||||||
MessageSimpleModel = require('Model/MessageSimple'),
|
|
||||||
aResult = _.compact(_.map(aData, function (aItem) {
|
|
||||||
return MessageSimpleModel.newInstanceFromJson(aItem);
|
|
||||||
}))
|
|
||||||
;
|
|
||||||
|
|
||||||
self.messageListSimpleHash = sHash;
|
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();
|
||||||
|
|
||||||
|
}());
|
||||||
|
|
@ -721,43 +721,6 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {?Function} fCallback
|
|
||||||
* @param {string} sNewFolderName
|
|
||||||
* @param {string} sParentName
|
|
||||||
*/
|
|
||||||
RemoteUserAjax.prototype.folderCreate = function (fCallback, sNewFolderName, sParentName)
|
|
||||||
{
|
|
||||||
this.defaultRequest(fCallback, 'FolderCreate', {
|
|
||||||
'Folder': sNewFolderName,
|
|
||||||
'Parent': sParentName
|
|
||||||
}, null, '', ['Folders']);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {?Function} fCallback
|
|
||||||
* @param {string} sFolderFullNameRaw
|
|
||||||
*/
|
|
||||||
RemoteUserAjax.prototype.folderDelete = function (fCallback, sFolderFullNameRaw)
|
|
||||||
{
|
|
||||||
this.defaultRequest(fCallback, 'FolderDelete', {
|
|
||||||
'Folder': sFolderFullNameRaw
|
|
||||||
}, null, '', ['Folders']);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {?Function} fCallback
|
|
||||||
* @param {string} sPrevFolderFullNameRaw
|
|
||||||
* @param {string} sNewFolderName
|
|
||||||
*/
|
|
||||||
RemoteUserAjax.prototype.folderRename = function (fCallback, sPrevFolderFullNameRaw, sNewFolderName)
|
|
||||||
{
|
|
||||||
this.defaultRequest(fCallback, 'FolderRename', {
|
|
||||||
'Folder': sPrevFolderFullNameRaw,
|
|
||||||
'NewFolderName': sNewFolderName
|
|
||||||
}, null, '', ['Folders']);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {?Function} fCallback
|
* @param {?Function} fCallback
|
||||||
* @param {string} sFolderFullNameRaw
|
* @param {string} sFolderFullNameRaw
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
FolderStore = require('Stores/User/Folder'),
|
FolderStore = require('Stores/User/Folder'),
|
||||||
|
|
||||||
|
Promises = require('Promises/User/Ajax'),
|
||||||
Remote = require('Remote/User/Ajax')
|
Remote = require('Remote/User/Ajax')
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -69,19 +70,9 @@
|
||||||
{
|
{
|
||||||
Local.set(Enums.ClientSideKeyName.FoldersLashHash, '');
|
Local.set(Enums.ClientSideKeyName.FoldersLashHash, '');
|
||||||
|
|
||||||
FolderStore.foldersRenaming(true);
|
require('App/User').foldersPromisesActionHelper(
|
||||||
Remote.folderRename(function (sResult, oData) {
|
Promises.folderRename(oFolder.fullNameRaw, sEditName, FolderStore.foldersRenaming),
|
||||||
|
Enums.Notification.CantRenameFolder);
|
||||||
FolderStore.foldersRenaming(false);
|
|
||||||
if (Enums.StorageResultType.Success !== sResult || !oData || !oData.Result)
|
|
||||||
{
|
|
||||||
FolderStore.folderList.error(
|
|
||||||
oData && oData.ErrorCode ? Translator.getNotification(oData.ErrorCode) : Translator.i18n('NOTIFICATIONS/CANT_RENAME_FOLDER'));
|
|
||||||
}
|
|
||||||
|
|
||||||
require('App/User').folders();
|
|
||||||
|
|
||||||
}, oFolder.fullNameRaw, sEditName);
|
|
||||||
|
|
||||||
Cache.removeFolderFromCacheList(oFolder.fullNameRaw);
|
Cache.removeFolderFromCacheList(oFolder.fullNameRaw);
|
||||||
|
|
||||||
|
|
@ -140,19 +131,9 @@
|
||||||
|
|
||||||
FolderStore.folderList.remove(fRemoveFolder);
|
FolderStore.folderList.remove(fRemoveFolder);
|
||||||
|
|
||||||
FolderStore.foldersDeleting(true);
|
require('App/User').foldersPromisesActionHelper(
|
||||||
Remote.folderDelete(function (sResult, oData) {
|
Promises.folderDelete(oFolderToRemove.fullNameRaw, FolderStore.foldersDeleting),
|
||||||
|
Enums.Notification.CantDeleteFolder);
|
||||||
FolderStore.foldersDeleting(false);
|
|
||||||
if (Enums.StorageResultType.Success !== sResult || !oData || !oData.Result)
|
|
||||||
{
|
|
||||||
FolderStore.folderList.error(
|
|
||||||
oData && oData.ErrorCode ? Translator.getNotification(oData.ErrorCode) : Translator.i18n('NOTIFICATIONS/CANT_DELETE_FOLDER'));
|
|
||||||
}
|
|
||||||
|
|
||||||
require('App/User').folders();
|
|
||||||
|
|
||||||
}, oFolderToRemove.fullNameRaw);
|
|
||||||
|
|
||||||
Cache.removeFolderFromCacheList(oFolderToRemove.fullNameRaw);
|
Cache.removeFolderFromCacheList(oFolderToRemove.fullNameRaw);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var
|
var
|
||||||
_ = require('_'),
|
|
||||||
ko = require('ko'),
|
ko = require('ko'),
|
||||||
|
|
||||||
Utils = require('Common/Utils'),
|
Utils = require('Common/Utils'),
|
||||||
|
|
|
||||||
|
|
@ -685,10 +685,6 @@
|
||||||
{
|
{
|
||||||
this.messageThreadLoading(true);
|
this.messageThreadLoading(true);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Utils.log('Error: Unknown message request: ' + sFolder + ' ~ ' + sUid + ' [e-102]');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Enums.Layout.NoPreview === SettingsStore.layout())
|
if (Enums.Layout.NoPreview === SettingsStore.layout())
|
||||||
{
|
{
|
||||||
|
|
@ -705,10 +701,6 @@
|
||||||
{
|
{
|
||||||
this.messageCurrentLoading(true);
|
this.messageCurrentLoading(true);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Utils.log('Error: Unknown message request: ' + oMessage.folderFullNameRaw + ' ~ ' + oMessage.uid + ' [e-101]');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -398,7 +398,7 @@ html.rl-no-preview-pane {
|
||||||
background-color: #999;
|
background-color: #999;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
padding: 0px 4px;
|
padding: 1px 6px 1px 5px;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
FolderStore = require('Stores/User/Folder'),
|
FolderStore = require('Stores/User/Folder'),
|
||||||
|
|
||||||
Remote = require('Remote/User/Ajax'),
|
Promises = require('Promises/User/Ajax'),
|
||||||
|
|
||||||
kn = require('Knoin/Knoin'),
|
kn = require('Knoin/Knoin'),
|
||||||
AbstractView = require('Knoin/AbstractView')
|
AbstractView = require('Knoin/AbstractView')
|
||||||
|
|
@ -76,21 +76,9 @@
|
||||||
sParentFolderName = FolderStore.namespace.substr(0, FolderStore.namespace.length - 1);
|
sParentFolderName = FolderStore.namespace.substr(0, FolderStore.namespace.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
FolderStore.foldersCreating(true);
|
require('App/User').foldersPromisesActionHelper(
|
||||||
Remote.folderCreate(function (sResult, oData) {
|
Promises.folderCreate(this.folderName(), sParentFolderName, FolderStore.foldersCreating),
|
||||||
|
Enums.Notification.CantCreateFolder);
|
||||||
FolderStore.foldersCreating(false);
|
|
||||||
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
|
|
||||||
{
|
|
||||||
require('App/User').folders();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FolderStore.folderList.error(
|
|
||||||
oData && oData.ErrorCode ? Translator.getNotification(oData.ErrorCode) : Translator.i18n('NOTIFICATIONS/CANT_CREATE_FOLDER'));
|
|
||||||
}
|
|
||||||
|
|
||||||
}, this.folderName(), sParentFolderName);
|
|
||||||
|
|
||||||
this.cancelCommand();
|
this.cancelCommand();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,11 @@
|
||||||
this.viewThreads.trigger = ko.observable(false);
|
this.viewThreads.trigger = ko.observable(false);
|
||||||
|
|
||||||
this.viewThreadMessages = ko.observableArray([]);
|
this.viewThreadMessages = ko.observableArray([]);
|
||||||
this.viewThreadMessages.hash = '';
|
this.viewThreadMessages.error = ko.observable('');
|
||||||
|
|
||||||
|
this.viewThreadMessages.subscribe(function () {
|
||||||
|
this.viewThreadMessages.error('');
|
||||||
|
}, this);
|
||||||
|
|
||||||
MessageStore.messageLastThreadUidsData.subscribe(function (oData) {
|
MessageStore.messageLastThreadUidsData.subscribe(function (oData) {
|
||||||
if (oData && oData['Uids'])
|
if (oData && oData['Uids'])
|
||||||
|
|
@ -320,11 +324,11 @@
|
||||||
|
|
||||||
self.viewThreadMessages(aList);
|
self.viewThreadMessages(aList);
|
||||||
|
|
||||||
}, function (iErrorCode) {
|
}).fail(function (iErrorCode) {
|
||||||
|
self.viewThreadMessages([]);
|
||||||
window.alert(Translator.getNotification(iErrorCode));
|
self.viewThreadMessages.error(Translator.getNotification(
|
||||||
|
iErrorCode, '', Enums.Notification.CantGetMessageList));
|
||||||
});
|
}).done();
|
||||||
}
|
}
|
||||||
|
|
||||||
}, function () {
|
}, function () {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"name": "RainLoop",
|
"name": "RainLoop",
|
||||||
"title": "RainLoop Webmail",
|
"title": "RainLoop Webmail",
|
||||||
"version": "1.8.2",
|
"version": "1.8.2",
|
||||||
"release": "288",
|
"release": "289",
|
||||||
"description": "Simple, modern & fast web-based email client",
|
"description": "Simple, modern & fast web-based email client",
|
||||||
"homepage": "http://rainloop.net",
|
"homepage": "http://rainloop.net",
|
||||||
"main": "gulpfile.js",
|
"main": "gulpfile.js",
|
||||||
|
|
@ -67,5 +67,9 @@
|
||||||
"gulp-beautify": "*",
|
"gulp-beautify": "*",
|
||||||
"gulp-plumber": "*",
|
"gulp-plumber": "*",
|
||||||
"gulp-concat-util": "*"
|
"gulp-concat-util": "*"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"gulp": "gulp",
|
||||||
|
"w": "gulp w"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5009,6 +5009,9 @@ class Actions
|
||||||
*/
|
*/
|
||||||
public function DoFolders()
|
public function DoFolders()
|
||||||
{
|
{
|
||||||
|
// \sleep(1);
|
||||||
|
// throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::MailServerError);
|
||||||
|
|
||||||
$sRawKey = (string) $this->GetActionParam('RawKey', '');
|
$sRawKey = (string) $this->GetActionParam('RawKey', '');
|
||||||
if (0 < \strlen($sRawKey))
|
if (0 < \strlen($sRawKey))
|
||||||
{
|
{
|
||||||
|
|
@ -5153,6 +5156,9 @@ class Actions
|
||||||
*/
|
*/
|
||||||
public function DoFolderCreate()
|
public function DoFolderCreate()
|
||||||
{
|
{
|
||||||
|
// \sleep(1);
|
||||||
|
// throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantCreateFolder);
|
||||||
|
|
||||||
$this->initMailClientConnection();
|
$this->initMailClientConnection();
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
@ -5232,6 +5238,9 @@ class Actions
|
||||||
*/
|
*/
|
||||||
public function DoFolderDelete()
|
public function DoFolderDelete()
|
||||||
{
|
{
|
||||||
|
// \sleep(1);
|
||||||
|
// throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantRenameFolder);
|
||||||
|
|
||||||
$this->initMailClientConnection();
|
$this->initMailClientConnection();
|
||||||
|
|
||||||
$sFolderFullNameRaw = $this->GetActionParam('Folder', '');
|
$sFolderFullNameRaw = $this->GetActionParam('Folder', '');
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,8 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr><td class="i18n" data-i18n-text="SHORTCUTS_HELP/LABEL_FULLSCREEN_TOGGLE">Toggle fullscreen mode</td><td>Enter</td></tr>
|
<tr><td class="i18n" data-i18n-text="SHORTCUTS_HELP/LABEL_FULLSCREEN_TOGGLE">Toggle fullscreen mode</td><td>Enter</td></tr>
|
||||||
<tr><td class="i18n" data-i18n-text="SHORTCUTS_HELP/LABEL_BLOCKQUOTES_TOGGLE">Toggle message blockquotes</td><td>B</td></tr>
|
<tr><td class="i18n" data-i18n-text="SHORTCUTS_HELP/LABEL_BLOCKQUOTES_TOGGLE">Toggle message blockquotes</td><td>B</td></tr>
|
||||||
|
<tr><td class="i18n" data-i18n-text="SHORTCUTS_HELP/LABEL_THREAD_NEXT">Next message in thread</td><td>Ctrl + ←, Command + ←</td></tr>
|
||||||
|
<tr><td class="i18n" data-i18n-text="SHORTCUTS_HELP/LABEL_THREAD_PREV">Previous message in thread</td><td>Ctrl + →, Command + →</td></tr>
|
||||||
<tr><td class="i18n" data-i18n-text="SHORTCUTS_HELP/LABEL_PRINT">Print</td><td>Ctrl + P, Command + P</td></tr>
|
<tr><td class="i18n" data-i18n-text="SHORTCUTS_HELP/LABEL_PRINT">Print</td><td>Ctrl + P, Command + P</td></tr>
|
||||||
<tr><td class="i18n" data-i18n-text="SHORTCUTS_HELP/LABEL_EXIT_FULLSCREEN">Exit fullscreen mode</td><td>Esc</td></tr>
|
<tr><td class="i18n" data-i18n-text="SHORTCUTS_HELP/LABEL_EXIT_FULLSCREEN">Exit fullscreen mode</td><td>Esc</td></tr>
|
||||||
<tr><td class="i18n" data-i18n-text="SHORTCUTS_HELP/LABEL_CLOSE_MESSAGE">Close message (No preview pane layout)</td><td>Esc</td></tr>
|
<tr><td class="i18n" data-i18n-text="SHORTCUTS_HELP/LABEL_CLOSE_MESSAGE">Close message (No preview pane layout)</td><td>Esc</td></tr>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
<div style="margin: 30px">
|
<div style="margin: 30px">
|
||||||
<h1 style="display: inline; color: #fff; text-shadow: 1px 2px 0px rgba(0, 0, 0, 0.5);">RainLoop Webmail</h1>
|
<h1 style="display: inline; color: #fff; text-shadow: 1px 2px 0px rgba(0, 0, 0, 0.5);">RainLoop Webmail</h1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h3 style="display: inline; color: #fff; text-shadow: 1px 2px 0px rgba(0, 0, 0, 0.5);">(<span data-bind="text: version"></span>)</h3>
|
<h3 style="display: inline; color: #fff; text-shadow: 1px 2px 0px rgba(0, 0, 0, 0.5);">(<span data-bind="text: version"></span>)</h3>
|
||||||
<h3><a href="http://rainloop.net/" target="_blank">http://rainloop.net</a></h3>
|
<h3><a href="http://rainloop.net/" target="_blank">http://rainloop.net</a></h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -206,13 +206,16 @@
|
||||||
</a>
|
</a>
|
||||||
<ul class="dropdown-menu pull-right g-ui-menu thread-list" role="menu" aria-labelledby="thread-list-view-dropdown-id"
|
<ul class="dropdown-menu pull-right g-ui-menu thread-list" role="menu" aria-labelledby="thread-list-view-dropdown-id"
|
||||||
style="min-width: 400px; max-width: 400px; width: 400px;">
|
style="min-width: 400px; max-width: 400px; width: 400px;">
|
||||||
|
<div data-bind="visible: '' !== viewThreadMessages.error()" style="color: red; text-align: center; padding: 10px">
|
||||||
|
<spam data-bind="text: viewThreadMessages.error"></spam>
|
||||||
|
</div >
|
||||||
<div data-bind="visible: messageListOfThreadsLoading" style="text-align: center; padding: 10px">
|
<div data-bind="visible: messageListOfThreadsLoading" style="text-align: center; padding: 10px">
|
||||||
<i class="icon-spinner animated" />
|
<i class="icon-spinner animated" />
|
||||||
</div >
|
</div >
|
||||||
<div data-bind="foreach: viewThreadMessages, visible: !messageListOfThreadsLoading()">
|
<div data-bind="foreach: viewThreadMessages, visible: !messageListOfThreadsLoading()">
|
||||||
<li class="e-item thread-list-message" role="presentation" data-bind="css: {'selected': selected}">
|
<li class="e-item thread-list-message" role="presentation" data-bind="css: {'selected': selected}">
|
||||||
<a class="e-link menuitem" href="#" tabindex="-1" onclick="return false;">
|
<a class="e-link menuitem" href="#" tabindex="-1" onclick="return false;">
|
||||||
<span class="thread-date pull-right" data-moment-format="SHORT" data-bind="moment: dateUTC"></span>
|
<span class="thread-date pull-right" data-moment-format="SHORT" data-bind="moment: dateInUTC"></span>
|
||||||
<div style="text-overflow: ellipsis; overflow: hidden;">
|
<div style="text-overflow: ellipsis; overflow: hidden;">
|
||||||
<span class="thread-from" data-bind="text: sender"></span>
|
<span class="thread-from" data-bind="text: sender"></span>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue