mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-01 13:39:22 +03:00
Uploading and preparing the repository to the dev version.
Original unminified source code (dev folder - js, css, less) (fixes #6) Grunt build system Multiple identities correction (fixes #9) Compose html editor (fixes #12) New general settings - Loading Description New warning about default admin password Split general and login screen settings
This commit is contained in:
parent
afad45137e
commit
4cc2207513
846 changed files with 99453 additions and 2123 deletions
249
dev/Storages/AbstractAjaxRemote.js
Normal file
249
dev/Storages/AbstractAjaxRemote.js
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
function AbstractAjaxRemoteStorage()
|
||||
{
|
||||
this.oRequests = {};
|
||||
}
|
||||
|
||||
AbstractAjaxRemoteStorage.prototype.oRequests = {};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sRequestAction
|
||||
* @param {string} sType
|
||||
* @param {?AjaxJsonDefaultResponse} oData
|
||||
* @param {boolean} bCached
|
||||
* @param {*=} oRequestParameters
|
||||
*/
|
||||
AbstractAjaxRemoteStorage.prototype.defaultResponse = function (fCallback, sRequestAction, sType, oData, bCached, oRequestParameters)
|
||||
{
|
||||
var
|
||||
fCall = function () {
|
||||
if (Enums.StorageResultType.Success !== sType && Globals.bUnload)
|
||||
{
|
||||
sType = Enums.StorageResultType.Unload;
|
||||
}
|
||||
|
||||
if (Enums.StorageResultType.Success === sType && oData && !oData.Result)
|
||||
{
|
||||
if (oData && -1 < Utils.inArray(oData.ErrorCode, [
|
||||
Enums.Notification.AuthError, Enums.Notification.AccessError,
|
||||
Enums.Notification.ConnectionError, Enums.Notification.DomainNotAllowed, Enums.Notification.AccountNotAllowed,
|
||||
Enums.Notification.MailServerError, Enums.Notification.UnknownNotification, Enums.Notification.UnknownError
|
||||
]))
|
||||
{
|
||||
Globals.iAjaxErrorCount++;
|
||||
}
|
||||
|
||||
if (oData && Enums.Notification.InvalidToken === oData.ErrorCode)
|
||||
{
|
||||
Globals.iTokenErrorCount++;
|
||||
}
|
||||
|
||||
if (10 < Globals.iTokenErrorCount)
|
||||
{
|
||||
RL.loginAndLogoutReload(true);
|
||||
}
|
||||
|
||||
if (oData.Logout || 7 < Globals.iAjaxErrorCount)
|
||||
{
|
||||
if (window.__rlah_clear)
|
||||
{
|
||||
window.__rlah_clear();
|
||||
}
|
||||
|
||||
RL.loginAndLogoutReload(true);
|
||||
}
|
||||
}
|
||||
else if (Enums.StorageResultType.Success === sType && oData && oData.Result)
|
||||
{
|
||||
Globals.iAjaxErrorCount = 0;
|
||||
Globals.iTokenErrorCount = 0;
|
||||
}
|
||||
|
||||
if (fCallback)
|
||||
{
|
||||
Plugins.runHook('ajax-default-response', [sRequestAction, Enums.StorageResultType.Success === sType ? oData : null, sType, bCached, oRequestParameters]);
|
||||
|
||||
fCallback(
|
||||
sType,
|
||||
Enums.StorageResultType.Success === sType ? oData : null,
|
||||
bCached,
|
||||
sRequestAction,
|
||||
oRequestParameters
|
||||
);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
switch (sType)
|
||||
{
|
||||
case 'success':
|
||||
sType = Enums.StorageResultType.Success;
|
||||
break;
|
||||
case 'abort':
|
||||
sType = Enums.StorageResultType.Abort;
|
||||
break;
|
||||
default:
|
||||
sType = Enums.StorageResultType.Error;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Enums.StorageResultType.Error === sType)
|
||||
{
|
||||
_.delay(fCall, 300);
|
||||
}
|
||||
else
|
||||
{
|
||||
fCall();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fResultCallback
|
||||
* @param {Object} oParameters
|
||||
* @param {?number=} iTimeOut = 20000
|
||||
* @param {string=} sGetAdd = ''
|
||||
* @param {Array=} aAbortActions = []
|
||||
* @return {jQuery.jqXHR}
|
||||
*/
|
||||
AbstractAjaxRemoteStorage.prototype.ajaxRequest = function (fResultCallback, oParameters, iTimeOut, sGetAdd, aAbortActions)
|
||||
{
|
||||
var
|
||||
self = this,
|
||||
bPost = '' === sGetAdd,
|
||||
oHeaders = {},
|
||||
iStart = (new window.Date()).getTime(),
|
||||
oDefAjax = null,
|
||||
sAction = ''
|
||||
;
|
||||
|
||||
oParameters = oParameters || {};
|
||||
iTimeOut = Utils.isNormal(iTimeOut) ? iTimeOut : 20000;
|
||||
sGetAdd = Utils.isUnd(sGetAdd) ? '' : Utils.pString(sGetAdd);
|
||||
aAbortActions = Utils.isArray(aAbortActions) ? aAbortActions : [];
|
||||
|
||||
sAction = oParameters.Action || '';
|
||||
|
||||
if (sAction && 0 < aAbortActions.length)
|
||||
{
|
||||
_.each(aAbortActions, function (sActionToAbort) {
|
||||
if (self.oRequests[sActionToAbort])
|
||||
{
|
||||
self.oRequests[sActionToAbort].__aborted = true;
|
||||
if (self.oRequests[sActionToAbort].abort)
|
||||
{
|
||||
self.oRequests[sActionToAbort].abort();
|
||||
}
|
||||
self.oRequests[sActionToAbort] = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (bPost)
|
||||
{
|
||||
oParameters['XToken'] = RL.settingsGet('Token');
|
||||
}
|
||||
|
||||
oDefAjax = $.ajax({
|
||||
'type': bPost ? 'POST' : 'GET',
|
||||
'url': RL.link().ajax(sGetAdd) ,
|
||||
'async': true,
|
||||
'dataType': 'json',
|
||||
'data': bPost ? oParameters : {},
|
||||
'headers': oHeaders,
|
||||
'timeout': iTimeOut,
|
||||
'global': true
|
||||
});
|
||||
|
||||
oDefAjax.always(function (oData, sType) {
|
||||
|
||||
var bCached = false;
|
||||
if (oData && oData['Time'])
|
||||
{
|
||||
bCached = Utils.pInt(oData['Time']) > (new window.Date()).getTime() - iStart;
|
||||
}
|
||||
|
||||
if (sAction && self.oRequests[sAction])
|
||||
{
|
||||
if (self.oRequests[sAction].__aborted)
|
||||
{
|
||||
sType = 'abort';
|
||||
}
|
||||
|
||||
self.oRequests[sAction] = null;
|
||||
}
|
||||
|
||||
self.defaultResponse(fResultCallback, sAction, sType, oData, bCached, oParameters);
|
||||
});
|
||||
|
||||
if (sAction && 0 < aAbortActions.length && -1 < Utils.inArray(sAction, aAbortActions))
|
||||
{
|
||||
if (this.oRequests[sAction])
|
||||
{
|
||||
this.oRequests[sAction].__aborted = true;
|
||||
if (this.oRequests[sAction].abort)
|
||||
{
|
||||
this.oRequests[sAction].abort();
|
||||
}
|
||||
this.oRequests[sAction] = null;
|
||||
}
|
||||
|
||||
this.oRequests[sAction] = oDefAjax;
|
||||
}
|
||||
|
||||
return oDefAjax;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sAction
|
||||
* @param {Object=} oParameters
|
||||
* @param {?number=} iTimeout
|
||||
* @param {string=} sGetAdd = ''
|
||||
* @param {Array=} aAbortActions = []
|
||||
*/
|
||||
AbstractAjaxRemoteStorage.prototype.defaultRequest = function (fCallback, sAction, oParameters, iTimeout, sGetAdd, aAbortActions)
|
||||
{
|
||||
oParameters = oParameters || {};
|
||||
oParameters.Action = sAction;
|
||||
|
||||
sGetAdd = Utils.pString(sGetAdd);
|
||||
|
||||
Plugins.runHook('ajax-default-request', [sAction, oParameters, sGetAdd]);
|
||||
|
||||
this.ajaxRequest(fCallback, oParameters,
|
||||
Utils.isUnd(iTimeout) ? Consts.Defaults.DefaultAjaxTimeout : Utils.pInt(iTimeout), sGetAdd, aAbortActions);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
AbstractAjaxRemoteStorage.prototype.noop = function (fCallback)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'Noop');
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sMessage
|
||||
* @param {string} sFileName
|
||||
* @param {number} iLineNo
|
||||
* @param {string} sLocation
|
||||
* @param {string} sHtmlCapa
|
||||
* @param {number} iTime
|
||||
*/
|
||||
AbstractAjaxRemoteStorage.prototype.jsError = function (fCallback, sMessage, sFileName, iLineNo, sLocation, sHtmlCapa, iTime)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'JsError', {
|
||||
'Message': sMessage,
|
||||
'FileName': sFileName,
|
||||
'LineNo': iLineNo,
|
||||
'Location': sLocation,
|
||||
'HtmlCapa': sHtmlCapa,
|
||||
'TimeOnPage': iTime
|
||||
});
|
||||
};
|
||||
67
dev/Storages/AbstractCache.js
Normal file
67
dev/Storages/AbstractCache.js
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
function AbstractCacheStorage()
|
||||
{
|
||||
this.oEmailsPicsHashes = {};
|
||||
this.oServices = {};
|
||||
}
|
||||
/**
|
||||
* @type {Object}
|
||||
*/
|
||||
AbstractCacheStorage.prototype.oEmailsPicsHashes = {};
|
||||
|
||||
/**
|
||||
* @type {Object}
|
||||
*/
|
||||
AbstractCacheStorage.prototype.oServices = {};
|
||||
|
||||
AbstractCacheStorage.prototype.clear = function ()
|
||||
{
|
||||
this.oServices = {};
|
||||
this.oEmailsPicsHashes = {};
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sEmail
|
||||
* @return {string}
|
||||
*/
|
||||
AbstractCacheStorage.prototype.getUserPic = function (sEmail)
|
||||
{
|
||||
var
|
||||
sUrl = '',
|
||||
sService = '',
|
||||
sEmailLower = sEmail.toLowerCase(),
|
||||
sPicHash = Utils.isUnd(this.oEmailsPicsHashes[sEmail]) ? '' : this.oEmailsPicsHashes[sEmail]
|
||||
;
|
||||
|
||||
if ('' === sPicHash)
|
||||
{
|
||||
sService = sEmailLower.substr(sEmail.indexOf('@') + 1);
|
||||
sUrl = '' !== sService && this.oServices[sService] ? this.oServices[sService] : '';
|
||||
}
|
||||
else
|
||||
{
|
||||
sUrl = RL.link().getUserPicUrlFromHash(sPicHash);
|
||||
}
|
||||
|
||||
return sUrl;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Object} oData
|
||||
*/
|
||||
AbstractCacheStorage.prototype.setServicesData = function (oData)
|
||||
{
|
||||
this.oServices = oData;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Object} oData
|
||||
*/
|
||||
AbstractCacheStorage.prototype.setEmailsPicsHashesData = function (oData)
|
||||
{
|
||||
this.oEmailsPicsHashes = oData;
|
||||
};
|
||||
70
dev/Storages/AbstractData.js
Normal file
70
dev/Storages/AbstractData.js
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
function AbstractData()
|
||||
{
|
||||
Utils.initDataConstructorBySettings(this);
|
||||
}
|
||||
|
||||
AbstractData.prototype.populateDataOnStart = function()
|
||||
{
|
||||
var
|
||||
aLanguages = RL.settingsGet('Languages'),
|
||||
aThemes = RL.settingsGet('Themes')
|
||||
;
|
||||
|
||||
if (Utils.isArray(aLanguages))
|
||||
{
|
||||
this.languages(aLanguages);
|
||||
}
|
||||
|
||||
if (Utils.isArray(aThemes))
|
||||
{
|
||||
this.themes(aThemes);
|
||||
}
|
||||
|
||||
this.mainLanguage(RL.settingsGet('Language'));
|
||||
this.mainTheme(RL.settingsGet('Theme'));
|
||||
|
||||
this.allowCustomTheme(!!RL.settingsGet('AllowCustomTheme'));
|
||||
this.allowAdditionalAccounts(!!RL.settingsGet('AllowAdditionalAccounts'));
|
||||
this.allowIdentities(!!RL.settingsGet('AllowIdentities'));
|
||||
this.determineUserLanguage(!!RL.settingsGet('DetermineUserLanguage'));
|
||||
|
||||
this.allowThemes(!!RL.settingsGet('AllowThemes'));
|
||||
this.allowCustomLogin(!!RL.settingsGet('AllowCustomLogin'));
|
||||
this.allowLanguagesOnLogin(!!RL.settingsGet('AllowLanguagesOnLogin'));
|
||||
this.allowLanguagesOnSettings(!!RL.settingsGet('AllowLanguagesOnSettings'));
|
||||
|
||||
this.editorDefaultType(RL.settingsGet('EditorDefaultType'));
|
||||
this.showImages(!!RL.settingsGet('ShowImages'));
|
||||
this.interfaceAnimation(RL.settingsGet('InterfaceAnimation'));
|
||||
|
||||
this.mainMessagesPerPage(RL.settingsGet('MPP'));
|
||||
|
||||
this.desktopNotifications(!!RL.settingsGet('DesktopNotifications'));
|
||||
this.useThreads(!!RL.settingsGet('UseThreads'));
|
||||
this.replySameFolder(!!RL.settingsGet('ReplySameFolder'));
|
||||
this.usePreviewPane(!!RL.settingsGet('UsePreviewPane'));
|
||||
this.useCheckboxesInList(!!RL.settingsGet('UseCheckboxesInList'));
|
||||
|
||||
this.facebookEnable(!!RL.settingsGet('AllowFacebookSocial'));
|
||||
this.facebookAppID(RL.settingsGet('FacebookAppID'));
|
||||
this.facebookAppSecret(RL.settingsGet('FacebookAppSecret'));
|
||||
|
||||
this.twitterEnable(!!RL.settingsGet('AllowTwitterSocial'));
|
||||
this.twitterConsumerKey(RL.settingsGet('TwitterConsumerKey'));
|
||||
this.twitterConsumerSecret(RL.settingsGet('TwitterConsumerSecret'));
|
||||
|
||||
this.googleEnable(!!RL.settingsGet('AllowGoogleSocial'));
|
||||
this.googleClientID(RL.settingsGet('GoogleClientID'));
|
||||
this.googleClientSecret(RL.settingsGet('GoogleClientSecret'));
|
||||
|
||||
this.dropboxEnable(!!RL.settingsGet('AllowDropboxSocial'));
|
||||
this.dropboxApiKey(RL.settingsGet('DropboxApiKey'));
|
||||
|
||||
this.contactsIsSupported(!!RL.settingsGet('ContactsIsSupported'));
|
||||
this.contactsIsAllowed(!!RL.settingsGet('ContactsIsAllowed'));
|
||||
};
|
||||
236
dev/Storages/AdminAjaxRemote.js
Normal file
236
dev/Storages/AdminAjaxRemote.js
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends AbstractAjaxRemoteStorage
|
||||
*/
|
||||
function AdminAjaxRemoteStorage()
|
||||
{
|
||||
AbstractAjaxRemoteStorage.call(this);
|
||||
|
||||
this.oRequests = {};
|
||||
}
|
||||
|
||||
_.extend(AdminAjaxRemoteStorage.prototype, AbstractAjaxRemoteStorage.prototype);
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sLogin
|
||||
* @param {string} sPassword
|
||||
*/
|
||||
AdminAjaxRemoteStorage.prototype.adminLogin = function (fCallback, sLogin, sPassword)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'AdminLogin', {
|
||||
'Login': sLogin,
|
||||
'Password': sPassword
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
AdminAjaxRemoteStorage.prototype.adminLogout = function (fCallback)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'AdminLogout');
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {?} oData
|
||||
*/
|
||||
AdminAjaxRemoteStorage.prototype.saveAdminConfig = function (fCallback, oData)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'AdminSettingsUpdate', oData);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
AdminAjaxRemoteStorage.prototype.domainList = function (fCallback)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'AdminDomainList');
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
AdminAjaxRemoteStorage.prototype.pluginList = function (fCallback)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'AdminPluginList');
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
AdminAjaxRemoteStorage.prototype.packagesList = function (fCallback)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'AdminPackagesList');
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {Object} oPackage
|
||||
*/
|
||||
AdminAjaxRemoteStorage.prototype.packageInstall = function (fCallback, oPackage)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'AdminPackageInstall', {
|
||||
'Id': oPackage.id,
|
||||
'Type': oPackage.type,
|
||||
'File': oPackage.file
|
||||
}, 60000);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {Object} oPackage
|
||||
*/
|
||||
AdminAjaxRemoteStorage.prototype.packageDelete = function (fCallback, oPackage)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'AdminPackageDelete', {
|
||||
'Id': oPackage.id
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sName
|
||||
*/
|
||||
AdminAjaxRemoteStorage.prototype.domain = function (fCallback, sName)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'AdminDomainLoad', {
|
||||
'Name': sName
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sName
|
||||
*/
|
||||
AdminAjaxRemoteStorage.prototype.plugin = function (fCallback, sName)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'AdminPluginLoad', {
|
||||
'Name': sName
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sName
|
||||
*/
|
||||
AdminAjaxRemoteStorage.prototype.domainDelete = function (fCallback, sName)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'AdminDomainDelete', {
|
||||
'Name': sName
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sName
|
||||
* @param {boolean} bDisabled
|
||||
*/
|
||||
AdminAjaxRemoteStorage.prototype.domainDisable = function (fCallback, sName, bDisabled)
|
||||
{
|
||||
return this.defaultRequest(fCallback, 'AdminDomainDisable', {
|
||||
'Name': sName,
|
||||
'Disabled': !!bDisabled ? '1' : '0'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {Object} oConfig
|
||||
*/
|
||||
AdminAjaxRemoteStorage.prototype.pluginSettingsUpdate = function (fCallback, oConfig)
|
||||
{
|
||||
return this.defaultRequest(fCallback, 'AdminPluginSettingsUpdate', oConfig);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {boolean} bForce
|
||||
*/
|
||||
AdminAjaxRemoteStorage.prototype.licensing = function (fCallback, bForce)
|
||||
{
|
||||
return this.defaultRequest(fCallback, 'AdminLicensing', {
|
||||
'Force' : bForce ? '1' : '0'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sDomain
|
||||
* @param {string} sKey
|
||||
*/
|
||||
AdminAjaxRemoteStorage.prototype.licensingActivate = function (fCallback, sDomain, sKey)
|
||||
{
|
||||
return this.defaultRequest(fCallback, 'AdminLicensingActivate', {
|
||||
'Domain' : sDomain,
|
||||
'Key' : sKey
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sName
|
||||
* @param {boolean} bDisabled
|
||||
*/
|
||||
AdminAjaxRemoteStorage.prototype.pluginDisable = function (fCallback, sName, bDisabled)
|
||||
{
|
||||
return this.defaultRequest(fCallback, 'AdminPluginDisable', {
|
||||
'Name': sName,
|
||||
'Disabled': !!bDisabled ? '1' : '0'
|
||||
});
|
||||
};
|
||||
|
||||
AdminAjaxRemoteStorage.prototype.createOrUpdateDomain = function (fCallback,
|
||||
bCreate, sName, sIncHost, iIncPort, sIncSecure, bIncShortLogin,
|
||||
sOutHost, iOutPort, sOutSecure, bOutShortLogin, bOutAuth, sWhiteList)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'AdminDomainSave', {
|
||||
'Create': bCreate ? '1' : '0',
|
||||
'Name': sName,
|
||||
'IncHost': sIncHost,
|
||||
'IncPort': iIncPort,
|
||||
'IncSecure': sIncSecure,
|
||||
'IncShortLogin': bIncShortLogin ? '1' : '0',
|
||||
'OutHost': sOutHost,
|
||||
'OutPort': iOutPort,
|
||||
'OutSecure': sOutSecure,
|
||||
'OutShortLogin': bOutShortLogin ? '1' : '0',
|
||||
'OutAuth': bOutAuth ? '1' : '0',
|
||||
'WhiteList': sWhiteList
|
||||
});
|
||||
};
|
||||
|
||||
AdminAjaxRemoteStorage.prototype.testConnectionForDomain = function (fCallback,
|
||||
sIncHost, iIncPort, sIncSecure,
|
||||
sOutHost, iOutPort, sOutSecure, bOutAuth)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'AdminDomainTest', {
|
||||
'IncHost': sIncHost,
|
||||
'IncPort': iIncPort,
|
||||
'IncSecure': sIncSecure,
|
||||
'OutHost': sOutHost,
|
||||
'OutPort': iOutPort,
|
||||
'OutSecure': sOutSecure,
|
||||
'OutAuth': bOutAuth ? '1' : '0'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {?} oData
|
||||
*/
|
||||
AdminAjaxRemoteStorage.prototype.saveNewAdminPassword = function (fCallback, oData)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'AdminPasswordUpdate', oData);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
AdminAjaxRemoteStorage.prototype.adminPing = function (fCallback)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'AdminPing');
|
||||
};
|
||||
12
dev/Storages/AdminCache.js
Normal file
12
dev/Storages/AdminCache.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends AbstractCacheStorage
|
||||
*/
|
||||
function AdminCacheStorage()
|
||||
{
|
||||
AbstractCacheStorage.call(this);
|
||||
}
|
||||
|
||||
_.extend(AdminCacheStorage.prototype, AbstractCacheStorage.prototype);
|
||||
36
dev/Storages/AdminData.js
Normal file
36
dev/Storages/AdminData.js
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends AbstractData
|
||||
*/
|
||||
function AdminDataStorage()
|
||||
{
|
||||
AbstractData.call(this);
|
||||
|
||||
this.domainsLoading = ko.observable(false).extend({'throttle': 100});
|
||||
this.domains = ko.observableArray([]);
|
||||
|
||||
this.pluginsLoading = ko.observable(false).extend({'throttle': 100});
|
||||
this.plugins = ko.observableArray([]);
|
||||
|
||||
this.packagesReal = ko.observable(true);
|
||||
this.packagesMainUpdatable = ko.observable(true);
|
||||
this.packagesLoading = ko.observable(false).extend({'throttle': 100});
|
||||
this.packages = ko.observableArray([]);
|
||||
|
||||
this.licensing = ko.observable(false);
|
||||
this.licensingProcess = ko.observable(false);
|
||||
this.licenseValid = ko.observable(false);
|
||||
this.licenseExpired = ko.observable(0);
|
||||
this.licenseError = ko.observable('');
|
||||
|
||||
this.licenseTrigger = ko.observable(false);
|
||||
}
|
||||
|
||||
_.extend(AdminDataStorage.prototype, AbstractData.prototype);
|
||||
|
||||
AdminDataStorage.prototype.populateDataOnStart = function()
|
||||
{
|
||||
AbstractData.prototype.populateDataOnStart.call(this);
|
||||
};
|
||||
44
dev/Storages/LocalStorage.js
Normal file
44
dev/Storages/LocalStorage.js
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
function LocalStorage()
|
||||
{
|
||||
var
|
||||
sStorages = [
|
||||
LocalStorageDriver,
|
||||
CookieDriver
|
||||
],
|
||||
NextStorageDriver = _.find(sStorages, function (NextStorageDriver) {
|
||||
return NextStorageDriver.supported();
|
||||
})
|
||||
;
|
||||
|
||||
if (NextStorageDriver)
|
||||
{
|
||||
NextStorageDriver = /** @type {?Function} */ NextStorageDriver;
|
||||
this.oDriver = new NextStorageDriver();
|
||||
}
|
||||
}
|
||||
|
||||
LocalStorage.prototype.oDriver = null;
|
||||
|
||||
/**
|
||||
* @param {number} iKey
|
||||
* @param {*} mData
|
||||
* @return {boolean}
|
||||
*/
|
||||
LocalStorage.prototype.set = function (iKey, mData)
|
||||
{
|
||||
return this.oDriver ? this.oDriver.set('p' + iKey, mData) : false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} iKey
|
||||
* @return {*}
|
||||
*/
|
||||
LocalStorage.prototype.get = function (iKey)
|
||||
{
|
||||
return this.oDriver ? this.oDriver.get('p' + iKey) : null;
|
||||
};
|
||||
75
dev/Storages/LocalStorages/CookieDriver.js
Normal file
75
dev/Storages/LocalStorages/CookieDriver.js
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
function CookieDriver()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CookieDriver.supported = function ()
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sKey
|
||||
* @param {*} mData
|
||||
* @returns {boolean}
|
||||
*/
|
||||
CookieDriver.prototype.set = function (sKey, mData)
|
||||
{
|
||||
var
|
||||
mCokieValue = $.cookie(Consts.Values.ClientSideCookieIndexName),
|
||||
bResult = false,
|
||||
mResult = null
|
||||
;
|
||||
|
||||
try
|
||||
{
|
||||
mResult = null === mCokieValue ? null : JSON.parse(mCokieValue);
|
||||
if (!mResult)
|
||||
{
|
||||
mResult = {};
|
||||
}
|
||||
|
||||
mResult[sKey] = mData;
|
||||
$.cookie(Consts.Values.ClientSideCookieIndexName, JSON.stringify(mResult), {
|
||||
'expires': 30
|
||||
});
|
||||
|
||||
bResult = true;
|
||||
}
|
||||
catch (oException) {}
|
||||
|
||||
return bResult;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sKey
|
||||
* @returns {*}
|
||||
*/
|
||||
CookieDriver.prototype.get = function (sKey)
|
||||
{
|
||||
var
|
||||
mCokieValue = $.cookie(Consts.Values.ClientSideCookieIndexName),
|
||||
mResult = null
|
||||
;
|
||||
|
||||
try
|
||||
{
|
||||
mResult = null === mCokieValue ? null : JSON.parse(mCokieValue);
|
||||
if (mResult && !Utils.isUnd(mResult[sKey]))
|
||||
{
|
||||
mResult = mResult[sKey];
|
||||
}
|
||||
else
|
||||
{
|
||||
mResult = null;
|
||||
}
|
||||
}
|
||||
catch (oException) {}
|
||||
|
||||
return mResult;
|
||||
};
|
||||
73
dev/Storages/LocalStorages/LocalStorageDriver.js
Normal file
73
dev/Storages/LocalStorages/LocalStorageDriver.js
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
function LocalStorageDriver()
|
||||
{
|
||||
}
|
||||
|
||||
LocalStorageDriver.supported = function ()
|
||||
{
|
||||
return !!window.localStorage;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} sKey
|
||||
* @param {*} mData
|
||||
* @returns {boolean}
|
||||
*/
|
||||
LocalStorageDriver.prototype.set = function (sKey, mData)
|
||||
{
|
||||
var
|
||||
mCokieValue = window.localStorage[Consts.Values.ClientSideCookieIndexName] || null,
|
||||
bResult = false,
|
||||
mResult = null
|
||||
;
|
||||
|
||||
try
|
||||
{
|
||||
mResult = null === mCokieValue ? null : JSON.parse(mCokieValue);
|
||||
if (!mResult)
|
||||
{
|
||||
mResult = {};
|
||||
}
|
||||
|
||||
mResult[sKey] = mData;
|
||||
window.localStorage[Consts.Values.ClientSideCookieIndexName] = JSON.stringify(mResult);
|
||||
|
||||
bResult = true;
|
||||
}
|
||||
catch (oException) {}
|
||||
|
||||
return bResult;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sKey
|
||||
* @returns {*}
|
||||
*/
|
||||
LocalStorageDriver.prototype.get = function (sKey)
|
||||
{
|
||||
var
|
||||
mCokieValue = window.localStorage[Consts.Values.ClientSideCookieIndexName] || null,
|
||||
mResult = null
|
||||
;
|
||||
|
||||
try
|
||||
{
|
||||
mResult = null === mCokieValue ? null : JSON.parse(mCokieValue);
|
||||
if (mResult && !Utils.isUnd(mResult[sKey]))
|
||||
{
|
||||
mResult = mResult[sKey];
|
||||
}
|
||||
else
|
||||
{
|
||||
mResult = null;
|
||||
}
|
||||
}
|
||||
catch (oException) {}
|
||||
|
||||
return mResult;
|
||||
};
|
||||
660
dev/Storages/WebMailAjaxRemote.js
Normal file
660
dev/Storages/WebMailAjaxRemote.js
Normal file
|
|
@ -0,0 +1,660 @@
|
|||
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends AbstractAjaxRemoteStorage
|
||||
*/
|
||||
function WebMailAjaxRemoteStorage()
|
||||
{
|
||||
AbstractAjaxRemoteStorage.call(this);
|
||||
|
||||
this.oRequests = {};
|
||||
}
|
||||
|
||||
_.extend(WebMailAjaxRemoteStorage.prototype, AbstractAjaxRemoteStorage.prototype);
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {boolean=} bUseCache = true
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.folders = function (fCallback, bUseCache)
|
||||
{
|
||||
var sFoldersHash = RL.data().lastFoldersHash;
|
||||
|
||||
bUseCache = Utils.isUnd(bUseCache) ? false : !!bUseCache;
|
||||
if (bUseCache && '' !== sFoldersHash)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'Folders', {}, null, 'Folders/' + RL.data().projectHash() + '-' + sFoldersHash, ['Folders']);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.defaultRequest(fCallback, 'Folders', {}, null, '', ['Folders']);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sEmail
|
||||
* @param {string} sLogin
|
||||
* @param {string} sPassword
|
||||
* @param {boolean} bSignMe
|
||||
* @param {string=} sLanguage
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.login = function (fCallback, sEmail, sLogin, sPassword, bSignMe, sLanguage)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'Login', {
|
||||
'Email': sEmail,
|
||||
'Login': sLogin,
|
||||
'Password': sPassword,
|
||||
'Language': sLanguage || '',
|
||||
'SignMe': bSignMe ? '1' : '0'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sEmail
|
||||
* @param {string} sLogin
|
||||
* @param {string} sPassword
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.accountAdd = function (fCallback, sEmail, sLogin, sPassword)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'AccountAdd', {
|
||||
'Email': sEmail,
|
||||
'Login': sLogin,
|
||||
'Password': sPassword
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sEmailToDelete
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.accountDelete = function (fCallback, sEmailToDelete)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'AccountDelete', {
|
||||
'EmailToDelete': sEmailToDelete
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sId
|
||||
* @param {string} sEmail
|
||||
* @param {string} sName
|
||||
* @param {string} sReplyTo
|
||||
* @param {string} sBcc
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.identityUpdate = function (fCallback, sId, sEmail, sName, sReplyTo, sBcc)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'IdentityUpdate', {
|
||||
'Id': sId,
|
||||
'Email': sEmail,
|
||||
'Name': sName,
|
||||
'ReplyTo': sReplyTo,
|
||||
'Bcc': sBcc
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sIdToDelete
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.identityDelete = function (fCallback, sIdToDelete)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'IdentityDelete', {
|
||||
'IdToDelete': sIdToDelete
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.accountsAndIdentities = function (fCallback)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'AccountsAndIdentities');
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sFolderFullNameRaw
|
||||
* @param {number=} iOffset = 0
|
||||
* @param {number=} iLimit = 20
|
||||
* @param {string=} sSearch = ''
|
||||
* @param {boolean=} bSilent = false
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.messageList = function (fCallback, sFolderFullNameRaw, iOffset, iLimit, sSearch, bSilent)
|
||||
{
|
||||
sFolderFullNameRaw = Utils.pString(sFolderFullNameRaw);
|
||||
|
||||
var
|
||||
oData = RL.data(),
|
||||
sFolderHash = RL.cache().getFolderHash(sFolderFullNameRaw)
|
||||
;
|
||||
|
||||
bSilent = Utils.isUnd(bSilent) ? false : !!bSilent;
|
||||
iOffset = Utils.isUnd(iOffset) ? 0 : Utils.pInt(iOffset);
|
||||
iLimit = Utils.isUnd(iOffset) ? 20 : Utils.pInt(iLimit);
|
||||
sSearch = Utils.pString(sSearch);
|
||||
|
||||
if ('' !== sFolderHash)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'MessageList', {},
|
||||
'' === sSearch ? Consts.Defaults.DefaultAjaxTimeout : Consts.Defaults.SearchAjaxTimeout,
|
||||
'MessageList/' + Base64.urlsafe_encode([
|
||||
sFolderFullNameRaw,
|
||||
iOffset,
|
||||
iLimit,
|
||||
sSearch,
|
||||
oData.projectHash(),
|
||||
sFolderHash,
|
||||
'INBOX' === sFolderFullNameRaw ? RL.cache().getFolderUidNext(sFolderFullNameRaw) : '',
|
||||
oData.threading() && oData.useThreads() ? '1' : '0',
|
||||
oData.threading() && sFolderFullNameRaw === oData.messageListThreadFolder() ? oData.messageListThreadUids().join(',') : ''
|
||||
].join(String.fromCharCode(0))), bSilent ? [] : ['MessageList']);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.defaultRequest(fCallback, 'MessageList', {
|
||||
'Folder': sFolderFullNameRaw,
|
||||
'Offset': iOffset,
|
||||
'Limit': iLimit,
|
||||
'Search': sSearch,
|
||||
'UidNext': 'INBOX' === sFolderFullNameRaw ? RL.cache().getFolderUidNext(sFolderFullNameRaw) : '',
|
||||
'UseThreads': RL.data().threading() && RL.data().useThreads() ? '1' : '0',
|
||||
'ExpandedThreadUid': oData.threading() && sFolderFullNameRaw === oData.messageListThreadFolder() ? oData.messageListThreadUids().join(',') : ''
|
||||
}, '' === sSearch ? Consts.Defaults.DefaultAjaxTimeout : Consts.Defaults.SearchAjaxTimeout, '', bSilent ? [] : ['MessageList']);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {Array} aDownloads
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.messageUploadAttachments = function (fCallback, aDownloads)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'MessageUploadAttachments', {
|
||||
'Attachments': aDownloads
|
||||
}, 999000);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sFolderFullNameRaw
|
||||
* @param {number} iUid
|
||||
* @return {boolean}
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.message = function (fCallback, sFolderFullNameRaw, iUid)
|
||||
{
|
||||
sFolderFullNameRaw = Utils.pString(sFolderFullNameRaw);
|
||||
iUid = Utils.pInt(iUid);
|
||||
|
||||
if (RL.cache().getFolderFromCacheList(sFolderFullNameRaw) && 0 < iUid)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'Message', {}, null,
|
||||
'Message/' + Base64.urlsafe_encode([
|
||||
sFolderFullNameRaw,
|
||||
iUid,
|
||||
RL.data().projectHash(),
|
||||
RL.data().threading() && RL.data().useThreads() ? '1' : '0'
|
||||
].join(String.fromCharCode(0))), ['Message']);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {Array} aExternals
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.composeUploadExternals = function (fCallback, aExternals)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'ComposeUploadExternals', {
|
||||
'Externals': aExternals
|
||||
}, 999000);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sFolder
|
||||
* @param {Array=} aList = []
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.folderInformation = function (fCallback, sFolder, aList)
|
||||
{
|
||||
var
|
||||
bRequest = true,
|
||||
oCache = RL.cache(),
|
||||
aUids = []
|
||||
;
|
||||
|
||||
if (Utils.isArray(aList) && 0 < aList.length)
|
||||
{
|
||||
bRequest = false;
|
||||
_.each(aList, function (oMessageListItem) {
|
||||
if (!oCache.getMessageFlagsFromCache(oMessageListItem.folderFullNameRaw, oMessageListItem.uid))
|
||||
{
|
||||
aUids.push(oMessageListItem.uid);
|
||||
}
|
||||
|
||||
if (0 < oMessageListItem.threads().length)
|
||||
{
|
||||
_.each(oMessageListItem.threads(), function (sUid) {
|
||||
if (!oCache.getMessageFlagsFromCache(oMessageListItem.folderFullNameRaw, sUid))
|
||||
{
|
||||
aUids.push(sUid);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (0 < aUids.length)
|
||||
{
|
||||
bRequest = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (bRequest)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'FolderInformation', {
|
||||
'Folder': sFolder,
|
||||
'FlagsUids': Utils.isArray(aUids) ? aUids.join(',') : '',
|
||||
'UidNext': 'INBOX' === sFolder ? RL.cache().getFolderUidNext(sFolder) : ''
|
||||
});
|
||||
}
|
||||
else if (RL.data().useThreads())
|
||||
{
|
||||
RL.reloadFlagsCurrentMessageListAndMessageFromCache();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.logout = function (fCallback)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'Logout');
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sFolderFullNameRaw
|
||||
* @param {Array} aUids
|
||||
* @param {boolean} bSetFlagged
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.messageSetFlagged = function (fCallback, sFolderFullNameRaw, aUids, bSetFlagged)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'MessageSetFlagged', {
|
||||
'Folder': sFolderFullNameRaw,
|
||||
'Uids': aUids.join(','),
|
||||
'SetAction': bSetFlagged ? '1' : '0'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sFolderFullNameRaw
|
||||
* @param {Array} aUids
|
||||
* @param {boolean} bSetSeen
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.messageSetSeen = function (fCallback, sFolderFullNameRaw, aUids, bSetSeen)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'MessageSetSeen', {
|
||||
'Folder': sFolderFullNameRaw,
|
||||
'Uids': aUids.join(','),
|
||||
'SetAction': bSetSeen ? '1' : '0'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sFolderFullNameRaw
|
||||
* @param {boolean} bSetSeen
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.messageSetSeenToAll = function (fCallback, sFolderFullNameRaw, bSetSeen)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'MessageSetSeenToAll', {
|
||||
'Folder': sFolderFullNameRaw,
|
||||
'SetAction': bSetSeen ? '1' : '0'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sMessageFolder
|
||||
* @param {string} sMessageUid
|
||||
* @param {string} sMessageID
|
||||
* @param {string} sDraftFolder
|
||||
* @param {string} sFrom
|
||||
* @param {string} sTo
|
||||
* @param {string} sCc
|
||||
* @param {string} sBcc
|
||||
* @param {string} sSubject
|
||||
* @param {boolean} bTextIsHtml
|
||||
* @param {string} sText
|
||||
* @param {Array} aAttachments
|
||||
* @param {(Array|null)} aDraftInfo
|
||||
* @param {string} sInReplyTo
|
||||
* @param {string} sReferences
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.saveMessage = function (fCallback, sMessageFolder, sMessageUid, sMessageID, sDraftFolder,
|
||||
sFrom, sTo, sCc, sBcc, sSubject, bTextIsHtml, sText, aAttachments, aDraftInfo, sInReplyTo, sReferences)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'SaveMessage', {
|
||||
'MessageFolder': sMessageFolder,
|
||||
'MessageUid': sMessageUid,
|
||||
'MessageID': sMessageID,
|
||||
'DraftFolder': sDraftFolder,
|
||||
'From': sFrom,
|
||||
'To': sTo,
|
||||
'Cc': sCc,
|
||||
'Bcc': sBcc,
|
||||
'Subject': sSubject,
|
||||
'TextIsHtml': bTextIsHtml ? '1' : '0',
|
||||
'Text': sText,
|
||||
'DraftInfo': aDraftInfo,
|
||||
'InReplyTo': sInReplyTo,
|
||||
'References': sReferences,
|
||||
'Attachments': aAttachments
|
||||
}, Consts.Defaults.SaveMessageAjaxTimeout);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sMessageFolder
|
||||
* @param {string} sMessageUid
|
||||
* @param {string} sMessageID
|
||||
* @param {string} sSentFolder
|
||||
* @param {string} sFrom
|
||||
* @param {string} sTo
|
||||
* @param {string} sCc
|
||||
* @param {string} sBcc
|
||||
* @param {string} sSubject
|
||||
* @param {boolean} bTextIsHtml
|
||||
* @param {string} sText
|
||||
* @param {Array} aAttachments
|
||||
* @param {(Array|null)} aDraftInfo
|
||||
* @param {string} sInReplyTo
|
||||
* @param {string} sReferences
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.sendMessage = function (fCallback, sMessageFolder, sMessageUid, sMessageID, sSentFolder,
|
||||
sFrom, sTo, sCc, sBcc, sSubject, bTextIsHtml, sText, aAttachments, aDraftInfo, sInReplyTo, sReferences)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'SendMessage', {
|
||||
'MessageFolder': sMessageFolder,
|
||||
'MessageUid': sMessageUid,
|
||||
'MessageID': sMessageID,
|
||||
'SentFolder': sSentFolder,
|
||||
'From': sFrom,
|
||||
'To': sTo,
|
||||
'Cc': sCc,
|
||||
'Bcc': sBcc,
|
||||
'Subject': sSubject,
|
||||
'TextIsHtml': bTextIsHtml ? '1' : '0',
|
||||
'Text': sText,
|
||||
'DraftInfo': aDraftInfo,
|
||||
'InReplyTo': sInReplyTo,
|
||||
'References': sReferences,
|
||||
'Attachments': aAttachments
|
||||
}, Consts.Defaults.SendMessageAjaxTimeout);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {Object} oData
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.saveSystemFolders = function (fCallback, oData)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'SystemFoldersUpdate', oData);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {Object} oData
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.saveSettings = function (fCallback, oData)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'SettingsUpdate', oData);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sPrevPassword
|
||||
* @param {string} sNewPassword
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.changePassword = function (fCallback, sPrevPassword, sNewPassword)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'ChangePassword', {
|
||||
'PrevPassword': sPrevPassword,
|
||||
'NewPassword': sNewPassword
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sNewFolderName
|
||||
* @param {string} sParentName
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.folderCreate = function (fCallback, sNewFolderName, sParentName)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'FolderCreate', {
|
||||
'Folder': sNewFolderName,
|
||||
'Parent': sParentName
|
||||
}, null, '', ['Folders']);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sFolderFullNameRaw
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.folderDelete = function (fCallback, sFolderFullNameRaw)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'FolderDelete', {
|
||||
'Folder': sFolderFullNameRaw
|
||||
}, null, '', ['Folders']);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sPrevFolderFullNameRaw
|
||||
* @param {string} sNewFolderName
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.folderRename = function (fCallback, sPrevFolderFullNameRaw, sNewFolderName)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'FolderRename', {
|
||||
'Folder': sPrevFolderFullNameRaw,
|
||||
'NewFolderName': sNewFolderName
|
||||
}, null, '', ['Folders']);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sFolderFullNameRaw
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.folderClear = function (fCallback, sFolderFullNameRaw)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'FolderClear', {
|
||||
'Folder': sFolderFullNameRaw
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sFolderFullNameRaw
|
||||
* @param {boolean} bSubscribe
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.folderSetSubscribe = function (fCallback, sFolderFullNameRaw, bSubscribe)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'FolderSubscribe', {
|
||||
'Folder': sFolderFullNameRaw,
|
||||
'Subscribe': bSubscribe ? '1' : '0'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sFolder
|
||||
* @param {string} sToFolder
|
||||
* @param {Array} aUids
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.messagesMove = function (fCallback, sFolder, sToFolder, aUids)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'MessageMove', {
|
||||
'FromFolder': sFolder,
|
||||
'ToFolder': sToFolder,
|
||||
'Uids': aUids.join(',')
|
||||
}, null, '', ['MessageList', 'Message']);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sFolder
|
||||
* @param {Array} aUids
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.messagesDelete = function (fCallback, sFolder, aUids)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'MessageDelete', {
|
||||
'Folder': sFolder,
|
||||
'Uids': aUids.join(',')
|
||||
}, null, '', ['MessageList', 'Message']);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.appDelayStart = function (fCallback)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'AppDelayStart');
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.quota = function (fCallback)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'Quota');
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sSearch
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.contacts = function (fCallback, sSearch)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'Contacts', {
|
||||
'Search': sSearch
|
||||
}, null, '', ['Contacts']);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.contactSave = function (fCallback, sRequestUid, sUid, sName, sEmail, sImageData)
|
||||
{
|
||||
sUid = Utils.trim(sUid);
|
||||
this.defaultRequest(fCallback, 'ContactSave', {
|
||||
'RequestUid': sRequestUid,
|
||||
'Uid': sUid,
|
||||
'Name': sName,
|
||||
'Email': sEmail,
|
||||
'ImageData': sImageData
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {Array} aUids
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.contactsDelete = function (fCallback, aUids)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'ContactsDelete', {
|
||||
'Uids': aUids.join(',')
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sQuery
|
||||
* @param {number} iPage
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.suggestions = function (fCallback, sQuery, iPage)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'Suggestions', {
|
||||
'Query': sQuery,
|
||||
'Page': iPage
|
||||
}, null, '', ['Suggestions']);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.servicesPics = function (fCallback)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'ServicesPics');
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.emailsPicsHashes = function (fCallback)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'EmailsPicsHashes');
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.facebookUser = function (fCallback)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'SocialFacebookUserInformation');
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.facebookDisconnect = function (fCallback)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'SocialFacebookDisconnect');
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.twitterUser = function (fCallback)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'SocialTwitterUserInformation');
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.twitterDisconnect = function (fCallback)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'SocialTwitterDisconnect');
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.googleUser = function (fCallback)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'SocialGoogleUserInformation');
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.googleDisconnect = function (fCallback)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'SocialGoogleDisconnect');
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
*/
|
||||
WebMailAjaxRemoteStorage.prototype.socialUsers = function (fCallback)
|
||||
{
|
||||
this.defaultRequest(fCallback, 'SocialUsers');
|
||||
};
|
||||
|
||||
318
dev/Storages/WebMailCache.js
Normal file
318
dev/Storages/WebMailCache.js
Normal file
|
|
@ -0,0 +1,318 @@
|
|||
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends AbstractCacheStorage
|
||||
*/
|
||||
function WebMailCacheStorage()
|
||||
{
|
||||
AbstractCacheStorage.call(this);
|
||||
|
||||
this.oFoldersCache = {};
|
||||
this.oFoldersNamesCache = {};
|
||||
this.oFolderHashCache = {};
|
||||
this.oFolderUidNextCache = {};
|
||||
this.oMessageListHashCache = {};
|
||||
this.oMessageFlagsCache = {};
|
||||
this.oNewMessage = {};
|
||||
this.oRequestedMessage = {};
|
||||
}
|
||||
|
||||
_.extend(WebMailCacheStorage.prototype, AbstractCacheStorage.prototype);
|
||||
|
||||
/**
|
||||
* @type {Object}
|
||||
*/
|
||||
WebMailCacheStorage.prototype.oFoldersCache = {};
|
||||
|
||||
/**
|
||||
* @type {Object}
|
||||
*/
|
||||
WebMailCacheStorage.prototype.oFoldersNamesCache = {};
|
||||
|
||||
/**
|
||||
* @type {Object}
|
||||
*/
|
||||
WebMailCacheStorage.prototype.oFolderHashCache = {};
|
||||
|
||||
/**
|
||||
* @type {Object}
|
||||
*/
|
||||
WebMailCacheStorage.prototype.oFolderUidNextCache = {};
|
||||
|
||||
/**
|
||||
* @type {Object}
|
||||
*/
|
||||
WebMailCacheStorage.prototype.oMessageListHashCache = {};
|
||||
|
||||
/**
|
||||
* @type {Object}
|
||||
*/
|
||||
WebMailCacheStorage.prototype.oMessageFlagsCache = {};
|
||||
|
||||
/**
|
||||
* @type {Object}
|
||||
*/
|
||||
WebMailCacheStorage.prototype.oBodies = {};
|
||||
|
||||
/**
|
||||
* @type {Object}
|
||||
*/
|
||||
WebMailCacheStorage.prototype.oNewMessage = {};
|
||||
|
||||
/**
|
||||
* @type {Object}
|
||||
*/
|
||||
WebMailCacheStorage.prototype.oRequestedMessage = {};
|
||||
|
||||
WebMailCacheStorage.prototype.clear = function ()
|
||||
{
|
||||
AbstractCacheStorage.prototype.clear.call(this);
|
||||
|
||||
this.oFoldersCache = {};
|
||||
this.oFoldersNamesCache = {};
|
||||
this.oFolderHashCache = {};
|
||||
this.oFolderUidNextCache = {};
|
||||
this.oMessageListHashCache = {};
|
||||
this.oMessageFlagsCache = {};
|
||||
this.oBodies = {};
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolderFullNameRaw
|
||||
* @param {string} sUid
|
||||
* @return {string}
|
||||
*/
|
||||
WebMailCacheStorage.prototype.getMessageKey = function (sFolderFullNameRaw, sUid)
|
||||
{
|
||||
return sFolderFullNameRaw + '#' + sUid;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolder
|
||||
* @param {string} sUid
|
||||
*/
|
||||
WebMailCacheStorage.prototype.addRequestedMessage = function (sFolder, sUid)
|
||||
{
|
||||
this.oRequestedMessage[this.getMessageKey(sFolder, sUid)] = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolder
|
||||
* @param {string} sUid
|
||||
* @return {boolean}
|
||||
*/
|
||||
WebMailCacheStorage.prototype.hasRequestedMessage = function (sFolder, sUid)
|
||||
{
|
||||
return true === this.oRequestedMessage[this.getMessageKey(sFolder, sUid)];
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolderFullNameRaw
|
||||
* @param {string} sUid
|
||||
*/
|
||||
WebMailCacheStorage.prototype.addNewMessageCache = function (sFolderFullNameRaw, sUid)
|
||||
{
|
||||
this.oNewMessage[this.getMessageKey(sFolderFullNameRaw, sUid)] = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolderFullNameRaw
|
||||
* @param {string} sUid
|
||||
*/
|
||||
WebMailCacheStorage.prototype.hasNewMessageAndRemoveFromCache = function (sFolderFullNameRaw, sUid)
|
||||
{
|
||||
if (this.oNewMessage[this.getMessageKey(sFolderFullNameRaw, sUid)])
|
||||
{
|
||||
this.oNewMessage[this.getMessageKey(sFolderFullNameRaw, sUid)] = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
WebMailCacheStorage.prototype.clearNewMessageCache = function ()
|
||||
{
|
||||
this.oNewMessage = {};
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolderHash
|
||||
* @return {string}
|
||||
*/
|
||||
WebMailCacheStorage.prototype.getFolderFullNameRaw = function (sFolderHash)
|
||||
{
|
||||
return '' !== sFolderHash && this.oFoldersNamesCache[sFolderHash] ? this.oFoldersNamesCache[sFolderHash] : '';
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolderHash
|
||||
* @param {string} sFolderFullNameRaw
|
||||
*/
|
||||
WebMailCacheStorage.prototype.setFolderFullNameRaw = function (sFolderHash, sFolderFullNameRaw)
|
||||
{
|
||||
this.oFoldersNamesCache[sFolderHash] = sFolderFullNameRaw;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolderFullNameRaw
|
||||
* @return {string}
|
||||
*/
|
||||
WebMailCacheStorage.prototype.getFolderHash = function (sFolderFullNameRaw)
|
||||
{
|
||||
return '' !== sFolderFullNameRaw && this.oFolderHashCache[sFolderFullNameRaw] ? this.oFolderHashCache[sFolderFullNameRaw] : '';
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolderFullNameRaw
|
||||
* @param {string} sFolderHash
|
||||
*/
|
||||
WebMailCacheStorage.prototype.setFolderHash = function (sFolderFullNameRaw, sFolderHash)
|
||||
{
|
||||
this.oFolderHashCache[sFolderFullNameRaw] = sFolderHash;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolderFullNameRaw
|
||||
* @return {string}
|
||||
*/
|
||||
WebMailCacheStorage.prototype.getFolderUidNext = function (sFolderFullNameRaw)
|
||||
{
|
||||
return '' !== sFolderFullNameRaw && this.oFolderUidNextCache[sFolderFullNameRaw] ? this.oFolderUidNextCache[sFolderFullNameRaw] : '';
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolderFullNameRaw
|
||||
* @param {string} sUidNext
|
||||
*/
|
||||
WebMailCacheStorage.prototype.setFolderUidNext = function (sFolderFullNameRaw, sUidNext)
|
||||
{
|
||||
this.oFolderUidNextCache[sFolderFullNameRaw] = sUidNext;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolderFullNameRaw
|
||||
* @return {?FolderModel}
|
||||
*/
|
||||
WebMailCacheStorage.prototype.getFolderFromCacheList = function (sFolderFullNameRaw)
|
||||
{
|
||||
return '' !== sFolderFullNameRaw && this.oFoldersCache[sFolderFullNameRaw] ? this.oFoldersCache[sFolderFullNameRaw] : null;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolderFullNameRaw
|
||||
* @param {?FolderModel} oFolder
|
||||
*/
|
||||
WebMailCacheStorage.prototype.setFolderToCacheList = function (sFolderFullNameRaw, oFolder)
|
||||
{
|
||||
this.oFoldersCache[sFolderFullNameRaw] = oFolder;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolderFullNameRaw
|
||||
*/
|
||||
WebMailCacheStorage.prototype.removeFolderFromCacheList = function (sFolderFullNameRaw)
|
||||
{
|
||||
this.setFolderToCacheList(sFolderFullNameRaw, null);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolderFullName
|
||||
* @param {string} sUid
|
||||
* @return {?Array}
|
||||
*/
|
||||
WebMailCacheStorage.prototype.getMessageFlagsFromCache = function (sFolderFullName, sUid)
|
||||
{
|
||||
return this.oMessageFlagsCache[sFolderFullName] && this.oMessageFlagsCache[sFolderFullName][sUid] ?
|
||||
this.oMessageFlagsCache[sFolderFullName][sUid] : null;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolderFullName
|
||||
* @param {string} sUid
|
||||
* @param {Array} aFlagsCache
|
||||
*/
|
||||
WebMailCacheStorage.prototype.setMessageFlagsToCache = function (sFolderFullName, sUid, aFlagsCache)
|
||||
{
|
||||
if (!this.oMessageFlagsCache[sFolderFullName])
|
||||
{
|
||||
this.oMessageFlagsCache[sFolderFullName] = {};
|
||||
}
|
||||
|
||||
this.oMessageFlagsCache[sFolderFullName][sUid] = aFlagsCache;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolderFullName
|
||||
*/
|
||||
WebMailCacheStorage.prototype.clearMessageFlagsFromCacheByFolder = function (sFolderFullName)
|
||||
{
|
||||
this.oMessageFlagsCache[sFolderFullName] = {};
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {(MessageModel|null)} oMessage
|
||||
*/
|
||||
WebMailCacheStorage.prototype.initMessageFlagsFromCache = function (oMessage)
|
||||
{
|
||||
if (oMessage)
|
||||
{
|
||||
var
|
||||
self = this,
|
||||
aFlags = this.getMessageFlagsFromCache(oMessage.folderFullNameRaw, oMessage.uid),
|
||||
mUnseenSubUid = null,
|
||||
mFlaggedSubUid = null
|
||||
;
|
||||
|
||||
if (aFlags && 4 === aFlags.length)
|
||||
{
|
||||
oMessage.unseen(aFlags[0]);
|
||||
oMessage.flagged(aFlags[1]);
|
||||
oMessage.answered(aFlags[2]);
|
||||
oMessage.forwarded(aFlags[3]);
|
||||
}
|
||||
|
||||
if (0 < oMessage.threads().length)
|
||||
{
|
||||
mUnseenSubUid = _.find(oMessage.threads(), function (iSubUid) {
|
||||
var aFlags = self.getMessageFlagsFromCache(oMessage.folderFullNameRaw, iSubUid);
|
||||
return aFlags && 4 === aFlags.length && !!aFlags[0];
|
||||
});
|
||||
|
||||
mFlaggedSubUid = _.find(oMessage.threads(), function (iSubUid) {
|
||||
var aFlags = self.getMessageFlagsFromCache(oMessage.folderFullNameRaw, iSubUid);
|
||||
return aFlags && 4 === aFlags.length && !!aFlags[1];
|
||||
});
|
||||
|
||||
oMessage.hasUnseenSubMessage(mUnseenSubUid && 0 < Utils.pInt(mUnseenSubUid));
|
||||
oMessage.hasFlaggedSubMessage(mFlaggedSubUid && 0 < Utils.pInt(mFlaggedSubUid));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {(MessageModel|null)} oMessage
|
||||
*/
|
||||
WebMailCacheStorage.prototype.storeMessageFlagsToCache = function (oMessage)
|
||||
{
|
||||
if (oMessage)
|
||||
{
|
||||
this.setMessageFlagsToCache(
|
||||
oMessage.folderFullNameRaw,
|
||||
oMessage.uid,
|
||||
[oMessage.unseen(), oMessage.flagged(), oMessage.answered(), oMessage.forwarded()]
|
||||
);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @param {string} sFolder
|
||||
* @param {string} sUid
|
||||
* @param {Array} aFlags
|
||||
*/
|
||||
WebMailCacheStorage.prototype.storeMessageFlagsToCacheByFolderAndUid = function (sFolder, sUid, aFlags)
|
||||
{
|
||||
if (Utils.isArray(aFlags) && 4 === aFlags.length)
|
||||
{
|
||||
this.setMessageFlagsToCache(sFolder, sUid, aFlags);
|
||||
}
|
||||
};
|
||||
896
dev/Storages/WebMailData.js
Normal file
896
dev/Storages/WebMailData.js
Normal file
|
|
@ -0,0 +1,896 @@
|
|||
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends AbstractData
|
||||
*/
|
||||
function WebMailDataStorage()
|
||||
{
|
||||
AbstractData.call(this);
|
||||
|
||||
var
|
||||
fRemoveSystemFolderType = function (observable) {
|
||||
return function () {
|
||||
var oFolder = RL.cache().getFolderFromCacheList(observable());
|
||||
if (oFolder)
|
||||
{
|
||||
oFolder.type(Enums.FolderType.User);
|
||||
}
|
||||
};
|
||||
},
|
||||
fSetSystemFolderType = function (iType) {
|
||||
return function (sValue) {
|
||||
var oFolder = RL.cache().getFolderFromCacheList(sValue);
|
||||
if (oFolder)
|
||||
{
|
||||
oFolder.type(iType);
|
||||
}
|
||||
};
|
||||
}
|
||||
;
|
||||
|
||||
this.devEmail = '';
|
||||
this.devLogin = '';
|
||||
this.devPassword = '';
|
||||
|
||||
this.accountEmail = ko.observable('');
|
||||
this.accountLogin = ko.observable('');
|
||||
this.projectHash = ko.observable('');
|
||||
|
||||
this.threading = ko.observable(false);
|
||||
this.lastFoldersHash = '';
|
||||
|
||||
this.remoteSuggestions = false;
|
||||
this.remoteChangePassword = false;
|
||||
|
||||
// system folders
|
||||
this.sentFolder = ko.observable('');
|
||||
this.draftFolder = ko.observable('');
|
||||
this.spamFolder = ko.observable('');
|
||||
this.trashFolder = ko.observable('');
|
||||
|
||||
this.sentFolder.subscribe(fRemoveSystemFolderType(this.sentFolder), this, 'beforeChange');
|
||||
this.draftFolder.subscribe(fRemoveSystemFolderType(this.draftFolder), this, 'beforeChange');
|
||||
this.spamFolder.subscribe(fRemoveSystemFolderType(this.spamFolder), this, 'beforeChange');
|
||||
this.trashFolder.subscribe(fRemoveSystemFolderType(this.trashFolder), this, 'beforeChange');
|
||||
|
||||
this.sentFolder.subscribe(fSetSystemFolderType(Enums.FolderType.SentItems), this);
|
||||
this.draftFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Draft), this);
|
||||
this.spamFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Spam), this);
|
||||
this.trashFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Trash), this);
|
||||
|
||||
this.draftFolderNotEnabled = ko.computed(function () {
|
||||
return '' === this.draftFolder() || Consts.Values.UnuseOptionValue === this.draftFolder();
|
||||
}, this);
|
||||
|
||||
// personal
|
||||
this.displayName = ko.observable('');
|
||||
this.signature = ko.observable('');
|
||||
this.replyTo = ko.observable('');
|
||||
|
||||
// accounts
|
||||
this.accounts = ko.observableArray([]);
|
||||
this.accountsLoading = ko.observable(false).extend({'throttle': 100});
|
||||
|
||||
// identities
|
||||
this.identities = ko.observableArray([]);
|
||||
this.identitiesLoading = ko.observable(false).extend({'throttle': 100});
|
||||
|
||||
// folders
|
||||
this.namespace = '';
|
||||
this.folderList = ko.observableArray([]);
|
||||
|
||||
this.foldersListError = ko.observable('');
|
||||
|
||||
this.foldersLoading = ko.observable(false);
|
||||
this.foldersCreating = ko.observable(false);
|
||||
this.foldersDeleting = ko.observable(false);
|
||||
this.foldersRenaming = ko.observable(false);
|
||||
|
||||
this.currentFolder = ko.observable(null).extend({'toggleSubscribe': [null,
|
||||
function (oPrev) {
|
||||
if (oPrev)
|
||||
{
|
||||
oPrev.selected(false);
|
||||
}
|
||||
}, function (oNext) {
|
||||
if (oNext)
|
||||
{
|
||||
oNext.selected(true);
|
||||
}
|
||||
}
|
||||
]});
|
||||
|
||||
this.currentFolderFullNameRaw = ko.computed(function () {
|
||||
return this.currentFolder() ? this.currentFolder().fullNameRaw : '';
|
||||
}, this);
|
||||
|
||||
this.currentFolderFullName = ko.computed(function () {
|
||||
return this.currentFolder() ? this.currentFolder().fullName : '';
|
||||
}, this);
|
||||
|
||||
this.currentFolderFullNameHash = ko.computed(function () {
|
||||
return this.currentFolder() ? this.currentFolder().fullNameHash : '';
|
||||
}, this);
|
||||
|
||||
this.currentFolderName = ko.computed(function () {
|
||||
return this.currentFolder() ? this.currentFolder().name() : '';
|
||||
}, this);
|
||||
|
||||
this.folderListSystemNames = ko.computed(function () {
|
||||
|
||||
var
|
||||
aList = ['INBOX'],
|
||||
aFolders = this.folderList(),
|
||||
sSentFolder = this.sentFolder(),
|
||||
sDraftFolder = this.draftFolder(),
|
||||
sSpamFolder = this.spamFolder(),
|
||||
sTrashFolder = this.trashFolder()
|
||||
;
|
||||
|
||||
if (Utils.isArray(aFolders) && 0 < aFolders.length)
|
||||
{
|
||||
if ('' !== sSentFolder && Consts.Values.UnuseOptionValue !== sSentFolder)
|
||||
{
|
||||
aList.push(sSentFolder);
|
||||
}
|
||||
if ('' !== sDraftFolder && Consts.Values.UnuseOptionValue !== sDraftFolder)
|
||||
{
|
||||
aList.push(sDraftFolder);
|
||||
}
|
||||
if ('' !== sSpamFolder && Consts.Values.UnuseOptionValue !== sSpamFolder)
|
||||
{
|
||||
aList.push(sSpamFolder);
|
||||
}
|
||||
if ('' !== sTrashFolder && Consts.Values.UnuseOptionValue !== sTrashFolder)
|
||||
{
|
||||
aList.push(sTrashFolder);
|
||||
}
|
||||
}
|
||||
|
||||
return aList;
|
||||
|
||||
}, this);
|
||||
|
||||
this.folderListSystem = ko.computed(function () {
|
||||
return _.compact(_.map(this.folderListSystemNames(), function (sName) {
|
||||
return RL.cache().getFolderFromCacheList(sName);
|
||||
}));
|
||||
}, this);
|
||||
|
||||
this.folderMenuForMove = ko.computed(function () {
|
||||
return RL.folderListOptionsBuilder(this.folderListSystem(), this.folderList(), [
|
||||
this.currentFolderFullNameRaw()
|
||||
], null, null, null, null, function (oItem) {
|
||||
return oItem ? oItem.localName() : '';
|
||||
});
|
||||
}, this);
|
||||
|
||||
// message list
|
||||
this.staticMessageList = [];
|
||||
|
||||
this.messageList = ko.observableArray([]);
|
||||
|
||||
this.messageListCount = ko.observable(0);
|
||||
this.messageListSearch = ko.observable('');
|
||||
this.messageListPage = ko.observable(1);
|
||||
|
||||
this.messageListThreadFolder = ko.observable('');
|
||||
this.messageListThreadUids = ko.observableArray([]);
|
||||
|
||||
this.messageListThreadFolder.subscribe(function () {
|
||||
this.messageListThreadUids([]);
|
||||
}, this);
|
||||
|
||||
this.messageListEndSearch = ko.observable('');
|
||||
this.messageListEndFolder = ko.observable('');
|
||||
|
||||
this.messageListPageCount = ko.computed(function () {
|
||||
var iPage = Math.ceil(this.messageListCount() / this.messagesPerPage());
|
||||
return 0 === iPage ? 1 : iPage;
|
||||
}, this);
|
||||
|
||||
this.mainMessageListSearch = ko.computed({
|
||||
'read': this.messageListSearch,
|
||||
'write': function (sValue) {
|
||||
kn.setHash(RL.link().mailBox(
|
||||
this.currentFolderFullNameHash(), 1, Utils.trim(sValue.toString())
|
||||
));
|
||||
},
|
||||
'owner': this
|
||||
});
|
||||
|
||||
this.messageListError = ko.observable('');
|
||||
|
||||
this.messageListLoading = ko.observable(false);
|
||||
this.messageListIsNotCompleted = ko.observable(false);
|
||||
this.messageListCompleteLoadingThrottle = ko.observable(false).extend({'throttle': 200});
|
||||
|
||||
this.messageListCompleteLoading = ko.computed(function () {
|
||||
var
|
||||
bOne = this.messageListLoading(),
|
||||
bTwo = this.messageListIsNotCompleted()
|
||||
;
|
||||
return bOne || bTwo;
|
||||
}, this);
|
||||
|
||||
this.messageListCompleteLoading.subscribe(function (bValue) {
|
||||
this.messageListCompleteLoadingThrottle(bValue);
|
||||
}, this);
|
||||
|
||||
this.messageList.subscribe(_.debounce(function (aList) {
|
||||
_.each(aList, function (oItem) {
|
||||
if (oItem.newForAnimation())
|
||||
{
|
||||
oItem.newForAnimation(false);
|
||||
}
|
||||
});
|
||||
}, 500));
|
||||
|
||||
// message preview
|
||||
this.staticMessageList = new MessageModel();
|
||||
this.message = ko.observable(null);
|
||||
this.messageLoading = ko.observable(false);
|
||||
this.messageLoadingThrottle = ko.observable(false).extend({'throttle': 50});
|
||||
|
||||
this.messageLoading.subscribe(function (bValue) {
|
||||
this.messageLoadingThrottle(bValue);
|
||||
}, this);
|
||||
|
||||
this.messageFullScreenMode = ko.observable(false);
|
||||
|
||||
this.messageError = ko.observable('');
|
||||
|
||||
this.messagesBodiesDom = ko.observable(null);
|
||||
|
||||
this.messagesBodiesDom.subscribe(function (oDom) {
|
||||
if (oDom && !(oDom instanceof jQuery))
|
||||
{
|
||||
this.messagesBodiesDom($(oDom));
|
||||
}
|
||||
}, this);
|
||||
|
||||
this.messageActiveDom = ko.observable(null);
|
||||
|
||||
this.isMessageSelected = ko.computed(function () {
|
||||
return null !== this.message();
|
||||
}, this);
|
||||
|
||||
this.currentMessage = ko.observable(null);
|
||||
|
||||
this.message.subscribe(function (oMessage) {
|
||||
if (null === oMessage)
|
||||
{
|
||||
this.currentMessage(null);
|
||||
this.hideMessageBodies();
|
||||
}
|
||||
}, this);
|
||||
|
||||
this.messageListChecked = ko.computed(function () {
|
||||
return _.filter(this.messageList(), function (oMessage) {
|
||||
return oMessage.checked();
|
||||
});
|
||||
}, this);
|
||||
|
||||
this.messageListCheckedOrSelected = ko.computed(function () {
|
||||
|
||||
var
|
||||
aChecked = this.messageListChecked(),
|
||||
oSelectedMessage = this.currentMessage()
|
||||
;
|
||||
|
||||
return _.union(aChecked, oSelectedMessage ? [oSelectedMessage] : []);
|
||||
|
||||
}, this);
|
||||
|
||||
this.messageListCheckedUids = ko.computed(function () {
|
||||
var aList = [];
|
||||
_.each(this.messageListChecked(), function (oMessage) {
|
||||
if (oMessage)
|
||||
{
|
||||
aList.push(oMessage.uid);
|
||||
if (0 < oMessage.threadsLen() && 0 === oMessage.parentUid() && oMessage.lastInCollapsedThread())
|
||||
{
|
||||
aList = _.union(aList, oMessage.threads());
|
||||
}
|
||||
}
|
||||
});
|
||||
return aList;
|
||||
}, this);
|
||||
|
||||
this.messageListCheckedOrSelectedUidsWithSubMails = ko.computed(function () {
|
||||
var aList = [];
|
||||
_.each(this.messageListCheckedOrSelected(), function (oMessage) {
|
||||
if (oMessage)
|
||||
{
|
||||
aList.push(oMessage.uid);
|
||||
if (0 < oMessage.threadsLen() && 0 === oMessage.parentUid() && oMessage.lastInCollapsedThread())
|
||||
{
|
||||
aList = _.union(aList, oMessage.threads());
|
||||
}
|
||||
}
|
||||
});
|
||||
return aList;
|
||||
}, this);
|
||||
|
||||
// quota
|
||||
this.userQuota = ko.observable(0);
|
||||
this.userUsageSize = ko.observable(0);
|
||||
this.userUsageProc = ko.computed(function () {
|
||||
|
||||
var
|
||||
iQuota = this.userQuota(),
|
||||
iUsed = this.userUsageSize()
|
||||
;
|
||||
|
||||
return 0 < iQuota ? Math.ceil((iUsed / iQuota) * 100) : 0;
|
||||
|
||||
}, this);
|
||||
|
||||
// other
|
||||
this.useKeyboardShortcuts = ko.observable(true);
|
||||
|
||||
// google
|
||||
this.googleActions = ko.observable(false);
|
||||
this.googleLoggined = ko.observable(false);
|
||||
this.googleUserName = ko.observable('');
|
||||
|
||||
// facebook
|
||||
this.facebookActions = ko.observable(false);
|
||||
this.facebookLoggined = ko.observable(false);
|
||||
this.facebookUserName = ko.observable('');
|
||||
|
||||
// twitter
|
||||
this.twitterActions = ko.observable(false);
|
||||
this.twitterLoggined = ko.observable(false);
|
||||
this.twitterUserName = ko.observable('');
|
||||
|
||||
this.customThemeType = ko.observable(Enums.CustomThemeType.Light);
|
||||
|
||||
this.purgeMessageBodyCacheThrottle = _.throttle(this.purgeMessageBodyCache, 1000 * 30);
|
||||
}
|
||||
|
||||
_.extend(WebMailDataStorage.prototype, AbstractData.prototype);
|
||||
|
||||
WebMailDataStorage.prototype.purgeMessageBodyCache = function()
|
||||
{
|
||||
var
|
||||
iCount = 0,
|
||||
oMessagesBodiesDom = null,
|
||||
iEnd = Globals.iMessageBodyCacheCount - Consts.Values.iMessageBodyCacheLimit
|
||||
;
|
||||
|
||||
if (0 < iEnd)
|
||||
{
|
||||
oMessagesBodiesDom = this.messagesBodiesDom();
|
||||
if (oMessagesBodiesDom)
|
||||
{
|
||||
oMessagesBodiesDom.find('.rl-cache-class').each(function () {
|
||||
var oItem = $(this);
|
||||
if (iEnd > oItem.data('rl-cache-count'))
|
||||
{
|
||||
oItem.addClass('rl-cache-purge');
|
||||
iCount++;
|
||||
}
|
||||
});
|
||||
|
||||
if (0 < iCount)
|
||||
{
|
||||
_.delay(function () {
|
||||
oMessagesBodiesDom.find('.rl-cache-purge').remove();
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
WebMailDataStorage.prototype.populateDataOnStart = function()
|
||||
{
|
||||
AbstractData.prototype.populateDataOnStart.call(this);
|
||||
|
||||
this.accountEmail(RL.settingsGet('Email'));
|
||||
this.accountLogin(RL.settingsGet('Login'));
|
||||
this.projectHash(RL.settingsGet('ProjectHash'));
|
||||
|
||||
this.displayName(RL.settingsGet('DisplayName'));
|
||||
this.replyTo(RL.settingsGet('ReplyTo'));
|
||||
this.signature(RL.settingsGet('Signature'));
|
||||
|
||||
this.lastFoldersHash = RL.local().get(Enums.ClientSideKeyName.FoldersLashHash) || '';
|
||||
|
||||
this.remoteSuggestions = !!RL.settingsGet('RemoteSuggestions');
|
||||
this.remoteChangePassword = !!RL.settingsGet('RemoteChangePassword');
|
||||
|
||||
this.devEmail = RL.settingsGet('DevEmail');
|
||||
this.devLogin = RL.settingsGet('DevLogin');
|
||||
this.devPassword = RL.settingsGet('DevPassword');
|
||||
};
|
||||
|
||||
WebMailDataStorage.prototype.initUidNextAndNewMessages = function (sFolder, sUidNext, aNewMessages)
|
||||
{
|
||||
if ('INBOX' === sFolder && Utils.isNormal(sUidNext) && sUidNext !== '')
|
||||
{
|
||||
if (Utils.isArray(aNewMessages) && 0 < aNewMessages.length)
|
||||
{
|
||||
var
|
||||
oCache = RL.cache(),
|
||||
iIndex = 0,
|
||||
iLen = aNewMessages.length,
|
||||
fNotificationHelper = function (sImageSrc, sTitle, sText)
|
||||
{
|
||||
var oNotification = null;
|
||||
if (NotificationClass && RL.data().useDesktopNotifications())
|
||||
{
|
||||
oNotification = new NotificationClass(sTitle, {
|
||||
'body': sText,
|
||||
'icon': sImageSrc
|
||||
});
|
||||
|
||||
if (oNotification)
|
||||
{
|
||||
if (oNotification.show)
|
||||
{
|
||||
oNotification.show();
|
||||
}
|
||||
|
||||
window.setTimeout((function (oLocalNotifications) {
|
||||
return function () {
|
||||
if (oLocalNotifications.cancel)
|
||||
{
|
||||
oLocalNotifications.cancel();
|
||||
}
|
||||
else if (oLocalNotifications.close)
|
||||
{
|
||||
oLocalNotifications.close();
|
||||
}
|
||||
};
|
||||
}(oNotification)), 7000);
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
_.each(aNewMessages, function (oItem) {
|
||||
oCache.addNewMessageCache(sFolder, oItem.Uid);
|
||||
});
|
||||
|
||||
if (3 < iLen)
|
||||
{
|
||||
fNotificationHelper(
|
||||
RL.link().notificationMailIcon(),
|
||||
RL.data().accountEmail(),
|
||||
Utils.i18n('MESSAGE_LIST/NEW_MESSAGE_NOTIFICATION', {
|
||||
'COUNT': iLen
|
||||
})
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; iIndex < iLen; iIndex++)
|
||||
{
|
||||
fNotificationHelper(
|
||||
RL.link().notificationMailIcon(),
|
||||
MessageModel.emailsToLine(MessageModel.initEmailsFromJson(aNewMessages[iIndex].From), false),
|
||||
aNewMessages[iIndex].Subject
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RL.cache().setFolderUidNext(sFolder, sUidNext);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sNamespace
|
||||
* @param {Array} aFolders
|
||||
* @param {boolean} bCached
|
||||
* @return {Array}
|
||||
*/
|
||||
WebMailDataStorage.prototype.folderResponseParseRec = function (sNamespace, aFolders, bCached)
|
||||
{
|
||||
var
|
||||
iIndex = 0,
|
||||
iLen = 0,
|
||||
oFolder = null,
|
||||
oCacheFolder = null,
|
||||
sFolderFullNameRaw = '',
|
||||
aSubFolders = [],
|
||||
aList = []
|
||||
;
|
||||
|
||||
bCached = !!bCached;
|
||||
|
||||
for (iIndex = 0, iLen = aFolders.length; iIndex < iLen; iIndex++)
|
||||
{
|
||||
oFolder = aFolders[iIndex];
|
||||
if (oFolder)
|
||||
{
|
||||
sFolderFullNameRaw = oFolder.FullNameRaw;
|
||||
|
||||
oCacheFolder = RL.cache().getFolderFromCacheList(sFolderFullNameRaw);
|
||||
if (!oCacheFolder)
|
||||
{
|
||||
oCacheFolder = FolderModel.newInstanceFromJson(oFolder);
|
||||
if (oCacheFolder)
|
||||
{
|
||||
RL.cache().setFolderToCacheList(sFolderFullNameRaw, oCacheFolder);
|
||||
RL.cache().setFolderFullNameRaw(oCacheFolder.fullNameHash, sFolderFullNameRaw);
|
||||
|
||||
oCacheFolder.isGmailFolder = Consts.Values.GmailFolderName.toLowerCase() === sFolderFullNameRaw.toLowerCase();
|
||||
if ('' !== sNamespace && sNamespace === oCacheFolder.fullNameRaw + oCacheFolder.delimiter)
|
||||
{
|
||||
oCacheFolder.isNamespaceFolder = true;
|
||||
}
|
||||
|
||||
if (oCacheFolder.isNamespaceFolder || oCacheFolder.isGmailFolder)
|
||||
{
|
||||
oCacheFolder.isUnpaddigFolder = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (oCacheFolder)
|
||||
{
|
||||
oCacheFolder.collapsed(!Utils.isFolderExpanded(oCacheFolder.fullNameHash));
|
||||
|
||||
if (!bCached && oFolder.Extended)
|
||||
{
|
||||
if (oFolder.Extended.Hash)
|
||||
{
|
||||
RL.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'], bCached));
|
||||
}
|
||||
|
||||
aList.push(oCacheFolder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return aList;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {*} oData
|
||||
* @param {boolean=} bCached = false
|
||||
*/
|
||||
WebMailDataStorage.prototype.setFolders = function (oData, bCached)
|
||||
{
|
||||
var
|
||||
aList = [],
|
||||
bUpdate = false,
|
||||
oRLData = RL.data(),
|
||||
aFolders = oRLData.folderList(),
|
||||
bFoldersFirst = 0 === aFolders.length,
|
||||
fNormalizeFolder = function (sFolderFullNameRaw) {
|
||||
return ('' === sFolderFullNameRaw || Consts.Values.UnuseOptionValue === sFolderFullNameRaw ||
|
||||
null !== RL.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))
|
||||
{
|
||||
oRLData.namespace = oData.Result.Namespace;
|
||||
}
|
||||
|
||||
this.threading(!!RL.settingsGet('UseImapThread') && oData.Result.IsThreadsSupported && true);
|
||||
|
||||
aList = this.folderResponseParseRec(oRLData.namespace, oData.Result['@Collection'], !!bCached);
|
||||
oRLData.folderList(aList);
|
||||
|
||||
if (oData.Result['SystemFolders'] &&
|
||||
'' === '' + RL.settingsGet('SentFolder') + RL.settingsGet('DraftFolder') +
|
||||
RL.settingsGet('SpamFolder') + RL.settingsGet('TrashFolder'))
|
||||
{
|
||||
// TODO Magic Numbers
|
||||
RL.settingsSet('SentFolder', oData.Result['SystemFolders'][2] || null);
|
||||
RL.settingsSet('DraftFolder', oData.Result['SystemFolders'][3] || null);
|
||||
RL.settingsSet('SpamFolder', oData.Result['SystemFolders'][4] || null);
|
||||
RL.settingsSet('TrashFolder', oData.Result['SystemFolders'][5] || null);
|
||||
|
||||
bUpdate = true;
|
||||
}
|
||||
|
||||
oRLData.sentFolder(fNormalizeFolder(RL.settingsGet('SentFolder')));
|
||||
oRLData.draftFolder(fNormalizeFolder(RL.settingsGet('DraftFolder')));
|
||||
oRLData.spamFolder(fNormalizeFolder(RL.settingsGet('SpamFolder')));
|
||||
oRLData.trashFolder(fNormalizeFolder(RL.settingsGet('TrashFolder')));
|
||||
|
||||
if (bUpdate)
|
||||
{
|
||||
RL.remote().saveSystemFolders(Utils.emptyFunction, {
|
||||
'SentFolder': oRLData.sentFolder(),
|
||||
'DraftFolder': oRLData.draftFolder(),
|
||||
'SpamFolder': oRLData.spamFolder(),
|
||||
'TrashFolder': oRLData.trashFolder()
|
||||
});
|
||||
}
|
||||
|
||||
if (!bCached)
|
||||
{
|
||||
RL.local().set(Enums.ClientSideKeyName.FoldersLashHash, oData.Result.FoldersHash);
|
||||
}
|
||||
|
||||
if (bFoldersFirst && bCached)
|
||||
{
|
||||
RL.folders(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
WebMailDataStorage.prototype.hideMessageBodies = function ()
|
||||
{
|
||||
var oMessagesBodiesDom = this.messagesBodiesDom();
|
||||
if (oMessagesBodiesDom)
|
||||
{
|
||||
oMessagesBodiesDom.find('.b-text-part').hide();
|
||||
}
|
||||
};
|
||||
|
||||
WebMailDataStorage.prototype.setMessage = function (oData, bCached)
|
||||
{
|
||||
var
|
||||
bIsHtml = false,
|
||||
bHasExternals = false,
|
||||
bHasInternals = false,
|
||||
oBody = null,
|
||||
oTextBody = null,
|
||||
sId = '',
|
||||
oMessagesBodiesDom = this.messagesBodiesDom(),
|
||||
oMessage = this.message()
|
||||
;
|
||||
|
||||
if (oData && oMessage && oData.Result && 'Object/Message' === oData.Result['@Object'] &&
|
||||
oMessage.folderFullNameRaw === oData.Result.Folder && oMessage.uid === oData.Result.Uid)
|
||||
{
|
||||
this.messageError('');
|
||||
|
||||
oMessage.initUpdateByMessageJson(oData.Result);
|
||||
RL.cache().addRequestedMessage(oMessage.folderFullNameRaw, oMessage.uid);
|
||||
|
||||
if (!bCached)
|
||||
{
|
||||
oMessage.initFlagsByJson(oData.Result);
|
||||
}
|
||||
|
||||
oMessagesBodiesDom = oMessagesBodiesDom && oMessagesBodiesDom[0] ? oMessagesBodiesDom : null;
|
||||
if (oMessagesBodiesDom)
|
||||
{
|
||||
sId = 'rl-' + oMessage.requestHash.replace(/[^a-zA-Z0-9]/g, '');
|
||||
oTextBody = oMessagesBodiesDom.find('#' + sId);
|
||||
if (!oTextBody || !oTextBody[0])
|
||||
{
|
||||
bHasExternals = !!oData.Result.HasExternals;
|
||||
bHasInternals = !!oData.Result.HasInternals;
|
||||
|
||||
oBody = $('<div id="' + sId + '" />').hide().addClass('rl-cache-class');
|
||||
oBody.data('rl-cache-count', ++Globals.iMessageBodyCacheCount);
|
||||
|
||||
if (Utils.isNormal(oData.Result.Html) && '' !== oData.Result.Html)
|
||||
{
|
||||
bIsHtml = true;
|
||||
oBody.html(oData.Result.Html.toString()).addClass('b-text-part html');
|
||||
}
|
||||
else if (Utils.isNormal(oData.Result.Plain) && '' !== oData.Result.Plain)
|
||||
{
|
||||
bIsHtml = false;
|
||||
oBody.html(oData.Result.Plain.toString()).addClass('b-text-part plain');
|
||||
}
|
||||
else
|
||||
{
|
||||
bIsHtml = false;
|
||||
}
|
||||
|
||||
if (oData.Result.Rtl)
|
||||
{
|
||||
oBody.data('rl-is-rtl', true);
|
||||
oBody.addClass('rtl-text-part');
|
||||
}
|
||||
|
||||
oMessagesBodiesDom.append(oBody);
|
||||
|
||||
oBody.data('rl-is-html', bIsHtml);
|
||||
oBody.data('rl-has-images', bHasExternals);
|
||||
|
||||
oMessage.isRtl(!!oBody.data('rl-is-rtl'));
|
||||
oMessage.isHtml(!!oBody.data('rl-is-html'));
|
||||
oMessage.hasImages(!!oBody.data('rl-has-images'));
|
||||
oMessage.body = oBody;
|
||||
|
||||
if (bHasInternals)
|
||||
{
|
||||
oMessage.showInternalImages(true);
|
||||
}
|
||||
|
||||
if (oMessage.hasImages() && this.showImages())
|
||||
{
|
||||
oMessage.showExternalImages(true);
|
||||
}
|
||||
|
||||
this.purgeMessageBodyCacheThrottle();
|
||||
}
|
||||
else
|
||||
{
|
||||
oTextBody.data('rl-cache-count', ++Globals.iMessageBodyCacheCount);
|
||||
|
||||
oMessage.isRtl(!!oTextBody.data('rl-is-rtl'));
|
||||
oMessage.isHtml(!!oTextBody.data('rl-is-html'));
|
||||
oMessage.hasImages(!!oTextBody.data('rl-has-images'));
|
||||
oMessage.body = oTextBody;
|
||||
}
|
||||
|
||||
this.messageActiveDom(oMessage.body);
|
||||
|
||||
this.hideMessageBodies();
|
||||
oMessage.body.show();
|
||||
|
||||
if (oBody)
|
||||
{
|
||||
Utils.initBlockquoteSwitcher(oBody);
|
||||
}
|
||||
}
|
||||
|
||||
RL.cache().initMessageFlagsFromCache(oMessage);
|
||||
if (oMessage.unseen())
|
||||
{
|
||||
RL.setMessageSeen(oMessage);
|
||||
}
|
||||
|
||||
Utils.windowResize();
|
||||
}
|
||||
};
|
||||
|
||||
WebMailDataStorage.prototype.setMessageList = function (oData, bCached)
|
||||
{
|
||||
if (oData && oData.Result && 'Collection/MessageCollection' === oData.Result['@Object'] &&
|
||||
oData.Result['@Collection'] && Utils.isArray(oData.Result['@Collection']))
|
||||
{
|
||||
var
|
||||
oRainLoopData = RL.data(),
|
||||
oCache = RL.cache(),
|
||||
mLastCollapsedThreadUids = null,
|
||||
iIndex = 0,
|
||||
iLen = 0,
|
||||
iCount = 0,
|
||||
iOffset = 0,
|
||||
aList = [],
|
||||
aStaticList = oRainLoopData.staticMessageList,
|
||||
oJsonMessage = null,
|
||||
oMessage = null,
|
||||
oFolder = null,
|
||||
iNewCount = 0,
|
||||
bUnreadCountChange = false
|
||||
;
|
||||
|
||||
iCount = Utils.pInt(oData.Result.MessageResultCount);
|
||||
iOffset = Utils.pInt(oData.Result.Offset);
|
||||
|
||||
if (Utils.isNonEmptyArray(oData.Result.LastCollapsedThreadUids))
|
||||
{
|
||||
mLastCollapsedThreadUids = oData.Result.LastCollapsedThreadUids;
|
||||
}
|
||||
|
||||
oFolder = RL.cache().getFolderFromCacheList(
|
||||
Utils.isNormal(oData.Result.Folder) ? oData.Result.Folder : '');
|
||||
|
||||
if (oFolder && !bCached)
|
||||
{
|
||||
RL.cache().setFolderHash(oData.Result.Folder, oData.Result.FolderHash);
|
||||
|
||||
if (Utils.isNormal(oData.Result.MessageCount))
|
||||
{
|
||||
oFolder.messageCountAll(oData.Result.MessageCount);
|
||||
}
|
||||
|
||||
if (Utils.isNormal(oData.Result.MessageUnseenCount))
|
||||
{
|
||||
if (Utils.pInt(oFolder.messageCountUnread()) !== Utils.pInt(oData.Result.MessageUnseenCount))
|
||||
{
|
||||
bUnreadCountChange = true;
|
||||
}
|
||||
|
||||
oFolder.messageCountUnread(oData.Result.MessageUnseenCount);
|
||||
}
|
||||
|
||||
this.initUidNextAndNewMessages(oFolder.fullNameRaw, oData.Result.UidNext, oData.Result.NewMessages);
|
||||
}
|
||||
|
||||
if (bUnreadCountChange && oFolder)
|
||||
{
|
||||
RL.cache().clearMessageFlagsFromCacheByFolder(oFolder.fullNameRaw);
|
||||
}
|
||||
|
||||
for (iIndex = 0, iLen = oData.Result['@Collection'].length; iIndex < iLen; iIndex++)
|
||||
{
|
||||
oJsonMessage = oData.Result['@Collection'][iIndex];
|
||||
if (oJsonMessage && 'Object/Message' === oJsonMessage['@Object'])
|
||||
{
|
||||
oMessage = aStaticList[iIndex];
|
||||
if (!oMessage || !oMessage.initByJson(oJsonMessage))
|
||||
{
|
||||
oMessage = MessageModel.newInstanceFromJson(oJsonMessage);
|
||||
}
|
||||
|
||||
if (oMessage)
|
||||
{
|
||||
if (oCache.hasNewMessageAndRemoveFromCache(oMessage.folderFullNameRaw, oMessage.uid) && 5 >= iNewCount)
|
||||
{
|
||||
iNewCount++;
|
||||
oMessage.newForAnimation(true);
|
||||
}
|
||||
|
||||
oMessage.deleted(false);
|
||||
|
||||
if (bCached)
|
||||
{
|
||||
RL.cache().initMessageFlagsFromCache(oMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
RL.cache().storeMessageFlagsToCache(oMessage);
|
||||
}
|
||||
|
||||
oMessage.lastInCollapsedThread(mLastCollapsedThreadUids && -1 < Utils.inArray(Utils.pInt(oMessage.uid), mLastCollapsedThreadUids) ? true : false);
|
||||
|
||||
aList.push(oMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
oRainLoopData.messageListCount(iCount);
|
||||
oRainLoopData.messageListSearch(Utils.isNormal(oData.Result.Search) ? oData.Result.Search : '');
|
||||
oRainLoopData.messageListEndSearch(Utils.isNormal(oData.Result.Search) ? oData.Result.Search : '');
|
||||
oRainLoopData.messageListEndFolder(Utils.isNormal(oData.Result.Folder) ? oData.Result.Folder : '');
|
||||
oRainLoopData.messageListPage(Math.ceil((iOffset / oRainLoopData.messagesPerPage()) + 1));
|
||||
|
||||
oRainLoopData.messageList(aList);
|
||||
oRainLoopData.messageListIsNotCompleted(false);
|
||||
|
||||
oMessage = oRainLoopData.message();
|
||||
if (oMessage && oRainLoopData.messageList.setSelectedByUid)
|
||||
{
|
||||
oRainLoopData.messageList.setSelectedByUid(oMessage.generateUid());
|
||||
}
|
||||
|
||||
if (aStaticList.length < aList.length)
|
||||
{
|
||||
oRainLoopData.staticMessageList = aList;
|
||||
}
|
||||
|
||||
oCache.clearNewMessageCache();
|
||||
|
||||
if (oFolder && (bCached || bUnreadCountChange || RL.data().useThreads()))
|
||||
{
|
||||
RL.folderInformation(oFolder.fullNameRaw, aList);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RL.data().messageListCount(0);
|
||||
RL.data().messageList([]);
|
||||
RL.data().messageListError(Utils.getNotification(
|
||||
oData && oData.ErrorCode ? oData.ErrorCode : Enums.Notification.CantGetMessageList
|
||||
));
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue