mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-30 20:49:20 +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
227
dev/Boots/AbstractApp.js
Normal file
227
dev/Boots/AbstractApp.js
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends KnoinAbstractBoot
|
||||
*/
|
||||
function AbstractApp()
|
||||
{
|
||||
KnoinAbstractBoot.call(this);
|
||||
|
||||
this.oSettings = null;
|
||||
this.oPlugins = null;
|
||||
this.oLink = null;
|
||||
this.oLocal = null;
|
||||
|
||||
this.isLocalAutocomplete = true;
|
||||
|
||||
this.popupVisibility = ko.observable(false);
|
||||
|
||||
this.iframe = $('<iframe style="display:none" src="javascript:;" />').appendTo('body');
|
||||
|
||||
$window.on('error', function (oEvent) {
|
||||
if (RL && oEvent && oEvent.originalEvent && oEvent.originalEvent.message &&
|
||||
-1 === Utils.inArray(oEvent.originalEvent.message, [
|
||||
'Script error.', 'Uncaught Error: Error calling method on NPObject.'
|
||||
]))
|
||||
{
|
||||
RL.remote().jsError(
|
||||
Utils.emptyFunction,
|
||||
oEvent.originalEvent.message,
|
||||
oEvent.originalEvent.filename,
|
||||
oEvent.originalEvent.lineno,
|
||||
location && location.toString ? location.toString() : '',
|
||||
$html.attr('class'),
|
||||
Utils.microtime() - Globals.now
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_.extend(AbstractApp.prototype, KnoinAbstractBoot.prototype);
|
||||
|
||||
AbstractApp.prototype.oSettings = null;
|
||||
AbstractApp.prototype.oLink = null;
|
||||
|
||||
/**
|
||||
* @param {string} sLink
|
||||
* @return {boolean}
|
||||
*/
|
||||
AbstractApp.prototype.download = function (sLink)
|
||||
{
|
||||
var
|
||||
oLink = null,
|
||||
oE = null,
|
||||
sUserAgent = navigator.userAgent.toLowerCase()
|
||||
;
|
||||
|
||||
if (sUserAgent && (sUserAgent.indexOf('chrome') > -1 || sUserAgent.indexOf('chrome') > -1))
|
||||
{
|
||||
oLink = document.createElement('a');
|
||||
oLink['href'] = sLink;
|
||||
|
||||
if (document['createEvent'])
|
||||
{
|
||||
oE = document['createEvent']('MouseEvents');
|
||||
if (oE && oE['initEvent'] && oLink['dispatchEvent'])
|
||||
{
|
||||
oE['initEvent']('click', true, true);
|
||||
oLink['dispatchEvent'](oE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Globals.bMobileDevice)
|
||||
{
|
||||
window.open(sLink, '_self');
|
||||
window.focus();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.iframe.attr('src', sLink);
|
||||
// window.document.location.href = sLink;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {LinkBuilder}
|
||||
*/
|
||||
AbstractApp.prototype.link = function ()
|
||||
{
|
||||
if (null === this.oLink)
|
||||
{
|
||||
this.oLink = new LinkBuilder();
|
||||
}
|
||||
|
||||
return this.oLink;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {LocalStorage}
|
||||
*/
|
||||
AbstractApp.prototype.local = function ()
|
||||
{
|
||||
if (null === this.oLocal)
|
||||
{
|
||||
this.oLocal = new LocalStorage();
|
||||
}
|
||||
|
||||
return this.oLocal;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sName
|
||||
* @return {?}
|
||||
*/
|
||||
AbstractApp.prototype.settingsGet = function (sName)
|
||||
{
|
||||
if (null === this.oSettings)
|
||||
{
|
||||
this.oSettings = Utils.isNormal(AppData) ? AppData : {};
|
||||
}
|
||||
|
||||
return Utils.isUnd(this.oSettings[sName]) ? null : this.oSettings[sName];
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sName
|
||||
* @param {?} mValue
|
||||
*/
|
||||
AbstractApp.prototype.settingsSet = function (sName, mValue)
|
||||
{
|
||||
if (null === this.oSettings)
|
||||
{
|
||||
this.oSettings = Utils.isNormal(AppData) ? AppData : {};
|
||||
}
|
||||
|
||||
this.oSettings[sName] = mValue;
|
||||
};
|
||||
|
||||
AbstractApp.prototype.setTitle = function (sTitle)
|
||||
{
|
||||
sTitle = ((0 < sTitle.length) ? sTitle + ' - ' : '') +
|
||||
this.settingsGet('Title') || '';
|
||||
|
||||
if (sTitle !== window.document.title)
|
||||
{
|
||||
window.document.title = sTitle;
|
||||
_.delay(function () {
|
||||
window.document.title = sTitle;
|
||||
}, 5);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean=} bLogout = false
|
||||
* @param {boolean=} bClose = false
|
||||
*/
|
||||
AbstractApp.prototype.loginAndLogoutReload = function (bLogout, bClose)
|
||||
{
|
||||
var
|
||||
sCustomLogoutLink = Utils.pString(this.settingsGet('CustomLogoutLink')),
|
||||
bInIframe = !!this.settingsGet('InIframe')
|
||||
;
|
||||
|
||||
bLogout = Utils.isUnd(bLogout) ? false : !!bLogout;
|
||||
bClose = Utils.isUnd(bClose) ? false : !!bClose;
|
||||
|
||||
if (bLogout && bClose && window.close)
|
||||
{
|
||||
window.close();
|
||||
}
|
||||
|
||||
if (bLogout && '' !== sCustomLogoutLink && window.location.href !== sCustomLogoutLink)
|
||||
{
|
||||
_.delay(function () {
|
||||
if (bInIframe && window.parent)
|
||||
{
|
||||
window.parent.location.href = sCustomLogoutLink;
|
||||
}
|
||||
else
|
||||
{
|
||||
window.location.href = sCustomLogoutLink;
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
kn.routeOff();
|
||||
kn.setHash(RL.link().root(), true);
|
||||
kn.routeOff();
|
||||
|
||||
_.delay(function () {
|
||||
if (bInIframe && window.parent)
|
||||
{
|
||||
window.parent.location.reload();
|
||||
}
|
||||
else
|
||||
{
|
||||
window.location.reload();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sQuery
|
||||
* @param {number} iPage
|
||||
* @param {Function} fCallback
|
||||
*/
|
||||
AbstractApp.prototype.getAutocomplete = function (sQuery, iPage, fCallback)
|
||||
{
|
||||
fCallback([], sQuery);
|
||||
};
|
||||
|
||||
AbstractApp.prototype.bootstart = function ()
|
||||
{
|
||||
Utils.initOnStartOrLangChange(function () {
|
||||
Utils.initNotificationLanguage();
|
||||
}, null);
|
||||
|
||||
_.delay(function () {
|
||||
Utils.windowResize();
|
||||
}, 1000);
|
||||
};
|
||||
248
dev/Boots/AdminApp.js
Normal file
248
dev/Boots/AdminApp.js
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends AbstractApp
|
||||
*/
|
||||
function AdminApp()
|
||||
{
|
||||
AbstractApp.call(this);
|
||||
|
||||
this.oData = null;
|
||||
this.oRemote = null;
|
||||
this.oCache = null;
|
||||
}
|
||||
|
||||
_.extend(AdminApp.prototype, AbstractApp.prototype);
|
||||
|
||||
AdminApp.prototype.oData = null;
|
||||
AdminApp.prototype.oRemote = null;
|
||||
AdminApp.prototype.oCache = null;
|
||||
|
||||
/**
|
||||
* @return {AdminDataStorage}
|
||||
*/
|
||||
AdminApp.prototype.data = function ()
|
||||
{
|
||||
if (null === this.oData)
|
||||
{
|
||||
this.oData = new AdminDataStorage();
|
||||
}
|
||||
|
||||
return this.oData;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {AdminAjaxRemoteStorage}
|
||||
*/
|
||||
AdminApp.prototype.remote = function ()
|
||||
{
|
||||
if (null === this.oRemote)
|
||||
{
|
||||
this.oRemote = new AdminAjaxRemoteStorage();
|
||||
}
|
||||
|
||||
return this.oRemote;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {AdminCacheStorage}
|
||||
*/
|
||||
AdminApp.prototype.cache = function ()
|
||||
{
|
||||
if (null === this.oCache)
|
||||
{
|
||||
this.oCache = new AdminCacheStorage();
|
||||
}
|
||||
|
||||
return this.oCache;
|
||||
};
|
||||
|
||||
AdminApp.prototype.reloadDomainList = function ()
|
||||
{
|
||||
RL.data().domainsLoading(true);
|
||||
RL.remote().domainList(function (sResult, oData) {
|
||||
RL.data().domainsLoading(false);
|
||||
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
|
||||
{
|
||||
var aList = _.map(oData.Result, function (bEnabled, sName) {
|
||||
return {
|
||||
'name': sName,
|
||||
'disabled': ko.observable(!bEnabled),
|
||||
'deleteAccess': ko.observable(false)
|
||||
};
|
||||
}, this);
|
||||
|
||||
RL.data().domains(aList);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
AdminApp.prototype.reloadPluginList = function ()
|
||||
{
|
||||
RL.data().pluginsLoading(true);
|
||||
RL.remote().pluginList(function (sResult, oData) {
|
||||
RL.data().pluginsLoading(false);
|
||||
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
|
||||
{
|
||||
var aList = _.map(oData.Result, function (oItem) {
|
||||
return {
|
||||
'name': oItem['Name'],
|
||||
'disabled': ko.observable(!oItem['Enabled']),
|
||||
'configured': ko.observable(!!oItem['Configured'])
|
||||
};
|
||||
}, this);
|
||||
|
||||
RL.data().plugins(aList);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
AdminApp.prototype.reloadPackagesList = function ()
|
||||
{
|
||||
RL.data().packagesLoading(true);
|
||||
RL.data().packagesReal(true);
|
||||
|
||||
RL.remote().packagesList(function (sResult, oData) {
|
||||
|
||||
RL.data().packagesLoading(false);
|
||||
|
||||
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
|
||||
{
|
||||
RL.data().packagesReal(!!oData.Result.Real);
|
||||
RL.data().packagesMainUpdatable(!!oData.Result.MainUpdatable);
|
||||
|
||||
var
|
||||
aList = [],
|
||||
aLoading = {}
|
||||
;
|
||||
|
||||
_.each(RL.data().packages(), function (oItem) {
|
||||
if (oItem && oItem['loading']())
|
||||
{
|
||||
aLoading[oItem['file']] = oItem;
|
||||
}
|
||||
});
|
||||
|
||||
if (Utils.isArray(oData.Result.List))
|
||||
{
|
||||
aList = _.compact(_.map(oData.Result.List, function (oItem) {
|
||||
if (oItem)
|
||||
{
|
||||
oItem['loading'] = ko.observable(!Utils.isUnd(aLoading[oItem['file']]));
|
||||
return 'core' === oItem['type'] && !oItem['canBeInstalled'] ? null : oItem;
|
||||
}
|
||||
return null;
|
||||
}));
|
||||
}
|
||||
|
||||
RL.data().packages(aList);
|
||||
}
|
||||
else
|
||||
{
|
||||
RL.data().packagesReal(false);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {boolean=} bForce = false
|
||||
*/
|
||||
AdminApp.prototype.reloadLicensing = function (bForce)
|
||||
{
|
||||
bForce = Utils.isUnd(bForce) ? false : !!bForce;
|
||||
|
||||
RL.data().licensingProcess(true);
|
||||
RL.data().licenseError('');
|
||||
|
||||
RL.remote().licensing(function (sResult, oData) {
|
||||
RL.data().licensingProcess(false);
|
||||
if (Enums.StorageResultType.Success === sResult && oData && oData.Result && Utils.isNormal(oData.Result['Expired']))
|
||||
{
|
||||
RL.data().licenseValid(true);
|
||||
RL.data().licenseExpired(Utils.pInt(oData.Result['Expired']));
|
||||
RL.data().licenseError('');
|
||||
|
||||
RL.data().licensing(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (oData && oData.ErrorCode && -1 < Utils.inArray(Utils.pInt(oData.ErrorCode), [
|
||||
Enums.Notification.LicensingServerIsUnavailable,
|
||||
Enums.Notification.LicensingExpired
|
||||
]))
|
||||
{
|
||||
RL.data().licenseError(Utils.getNotification(Utils.pInt(oData.ErrorCode)));
|
||||
RL.data().licensing(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Enums.StorageResultType.Abort === sResult)
|
||||
{
|
||||
RL.data().licenseError(Utils.getNotification(Enums.Notification.LicensingServerIsUnavailable));
|
||||
RL.data().licensing(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
RL.data().licensing(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, bForce);
|
||||
};
|
||||
|
||||
AdminApp.prototype.bootstart = function ()
|
||||
{
|
||||
AbstractApp.prototype.bootstart.call(this);
|
||||
|
||||
RL.data().populateDataOnStart();
|
||||
|
||||
kn.hideLoading();
|
||||
|
||||
if (!this.settingsGet('AllowAdminPanel'))
|
||||
{
|
||||
kn.routeOff();
|
||||
kn.setHash(RL.link().root(), true);
|
||||
kn.routeOff();
|
||||
|
||||
_.defer(function () {
|
||||
window.location.href = '/';
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!!this.settingsGet('Auth'))
|
||||
{
|
||||
// TODO
|
||||
// if (!this.settingsGet('AllowPackages') && AdminPackages)
|
||||
// {
|
||||
// Utils.disableSettingsViewModel(AdminPackages);
|
||||
// }
|
||||
|
||||
kn.startScreens([AdminSettingsScreen]);
|
||||
|
||||
if (!Globals.bMobileDevice)
|
||||
{
|
||||
_.defer(function () {
|
||||
Utils.initLayoutResizer('#rl-top-resizer-left', '#rl-top-resizer-right', '#rl-center',
|
||||
120, 300, 200, 600, Enums.ClientSideKeyName.FolderListSize);
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
kn.startScreens([AdminLoginScreen]);
|
||||
}
|
||||
}
|
||||
|
||||
if (window.SimplePace)
|
||||
{
|
||||
window.SimplePace.set(100);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @type {AdminApp}
|
||||
*/
|
||||
RL = new AdminApp();
|
||||
750
dev/Boots/RainLoopApp.js
Normal file
750
dev/Boots/RainLoopApp.js
Normal file
|
|
@ -0,0 +1,750 @@
|
|||
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends AbstractApp
|
||||
*/
|
||||
function RainLoopApp()
|
||||
{
|
||||
AbstractApp.call(this);
|
||||
|
||||
this.oData = null;
|
||||
this.oRemote = null;
|
||||
this.oCache = null;
|
||||
|
||||
this.iSuggestionsLimit = Utils.pInt(this.settingsGet('SuggestionsLimit'));
|
||||
this.iSuggestionsLimit = 0 === this.iSuggestionsLimit ? 20 : this.iSuggestionsLimit;
|
||||
|
||||
this.quotaDebounce = _.debounce(this.quota, 1000 * 30);
|
||||
}
|
||||
|
||||
_.extend(RainLoopApp.prototype, AbstractApp.prototype);
|
||||
|
||||
RainLoopApp.prototype.oData = null;
|
||||
RainLoopApp.prototype.oRemote = null;
|
||||
RainLoopApp.prototype.oCache = null;
|
||||
|
||||
/**
|
||||
* @return {WebMailDataStorage}
|
||||
*/
|
||||
RainLoopApp.prototype.data = function ()
|
||||
{
|
||||
if (null === this.oData)
|
||||
{
|
||||
this.oData = new WebMailDataStorage();
|
||||
}
|
||||
|
||||
return this.oData;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {WebMailAjaxRemoteStorage}
|
||||
*/
|
||||
RainLoopApp.prototype.remote = function ()
|
||||
{
|
||||
if (null === this.oRemote)
|
||||
{
|
||||
this.oRemote = new WebMailAjaxRemoteStorage();
|
||||
}
|
||||
|
||||
return this.oRemote;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {WebMailCacheStorage}
|
||||
*/
|
||||
RainLoopApp.prototype.cache = function ()
|
||||
{
|
||||
if (null === this.oCache)
|
||||
{
|
||||
this.oCache = new WebMailCacheStorage();
|
||||
}
|
||||
|
||||
return this.oCache;
|
||||
};
|
||||
|
||||
RainLoopApp.prototype.reloadFlagsCurrentMessageListAndMessageFromCache = function ()
|
||||
{
|
||||
var oCache = RL.cache();
|
||||
_.each(RL.data().messageList(), function (oMessage) {
|
||||
oCache.initMessageFlagsFromCache(oMessage);
|
||||
});
|
||||
|
||||
oCache.initMessageFlagsFromCache(RL.data().message());
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean=} bDropPagePosition = false
|
||||
* @param {boolean=} bDropCurrenFolderCache = false
|
||||
*/
|
||||
RainLoopApp.prototype.reloadMessageList = function (bDropPagePosition, bDropCurrenFolderCache)
|
||||
{
|
||||
var
|
||||
oRLData = RL.data(),
|
||||
iOffset = (oRLData.messageListPage() - 1) * oRLData.messagesPerPage()
|
||||
;
|
||||
|
||||
if (Utils.isUnd(bDropCurrenFolderCache) ? false : !!bDropCurrenFolderCache)
|
||||
{
|
||||
RL.cache().setFolderHash(oRLData.currentFolderFullNameRaw(), '');
|
||||
}
|
||||
|
||||
if (Utils.isUnd(bDropPagePosition) ? false : !!bDropPagePosition)
|
||||
{
|
||||
oRLData.messageListPage(1);
|
||||
iOffset = 0;
|
||||
}
|
||||
|
||||
oRLData.messageListLoading(true);
|
||||
RL.remote().messageList(function (sResult, oData, bCached) {
|
||||
|
||||
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
|
||||
{
|
||||
oRLData.messageListError('');
|
||||
oRLData.messageListLoading(false);
|
||||
oRLData.setMessageList(oData, bCached);
|
||||
}
|
||||
else if (Enums.StorageResultType.Unload === sResult)
|
||||
{
|
||||
oRLData.messageListError('');
|
||||
oRLData.messageListLoading(false);
|
||||
}
|
||||
else if (Enums.StorageResultType.Abort !== sResult)
|
||||
{
|
||||
oRLData.messageList([]);
|
||||
oRLData.messageListLoading(false);
|
||||
oRLData.messageListError(oData && oData.ErrorCode ?
|
||||
Utils.getNotification(oData.ErrorCode) : Utils.i18n('NOTIFICATIONS/CANT_GET_MESSAGE_LIST')
|
||||
);
|
||||
}
|
||||
|
||||
}, oRLData.currentFolderFullNameRaw(), iOffset, oRLData.messagesPerPage(), oRLData.messageListSearch());
|
||||
};
|
||||
|
||||
RainLoopApp.prototype.recacheInboxMessageList = function ()
|
||||
{
|
||||
RL.remote().messageList(Utils.emptyFunction, 'INBOX', 0, RL.data().messagesPerPage(), '', true);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean=} bUseCache = true
|
||||
* @param {Function=} fCallback
|
||||
*/
|
||||
RainLoopApp.prototype.folders = function (bUseCache, fCallback)
|
||||
{
|
||||
this.data().foldersLoading(true);
|
||||
this.remote().folders(_.bind(function (sResult, oData, bCached) {
|
||||
|
||||
RL.data().foldersLoading(false);
|
||||
if (Enums.StorageResultType.Success === sResult)
|
||||
{
|
||||
this.data().setFolders(oData, bCached);
|
||||
if (fCallback)
|
||||
{
|
||||
fCallback(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fCallback)
|
||||
{
|
||||
fCallback(false);
|
||||
}
|
||||
}
|
||||
}, this), bUseCache);
|
||||
};
|
||||
|
||||
RainLoopApp.prototype.accountsAndIdentities = function ()
|
||||
{
|
||||
var oRainLoopData = RL.data();
|
||||
|
||||
oRainLoopData.accountsLoading(true);
|
||||
oRainLoopData.identitiesLoading(true);
|
||||
|
||||
RL.remote().accountsAndIdentities(function (sResult, oData) {
|
||||
|
||||
oRainLoopData.accountsLoading(false);
|
||||
oRainLoopData.identitiesLoading(false);
|
||||
|
||||
if (Enums.StorageResultType.Success === sResult && oData.Result)
|
||||
{
|
||||
var
|
||||
sParentEmail = RL.settingsGet('ParentEmail'),
|
||||
sAccountEmail = oRainLoopData.accountEmail()
|
||||
;
|
||||
|
||||
sParentEmail = '' === sParentEmail ? sAccountEmail : sParentEmail;
|
||||
|
||||
if (Utils.isArray(oData.Result['Accounts']))
|
||||
{
|
||||
oRainLoopData.accounts(_.map(oData.Result['Accounts'], function (sValue) {
|
||||
return new AccountModel(sValue, sValue !== sParentEmail);
|
||||
}));
|
||||
}
|
||||
|
||||
if (Utils.isArray(oData.Result['Identities']))
|
||||
{
|
||||
oRainLoopData.identities(_.map(oData.Result['Identities'], function (oIdentityData) {
|
||||
|
||||
var
|
||||
sId = Utils.pString(oIdentityData['Id']),
|
||||
sEmail = Utils.pString(oIdentityData['Email']),
|
||||
oIdentity = new IdentityModel(sId, sEmail, sId !== sAccountEmail)
|
||||
;
|
||||
|
||||
oIdentity.name(Utils.pString(oIdentityData['Name']));
|
||||
oIdentity.replyTo(Utils.pString(oIdentityData['ReplyTo']));
|
||||
oIdentity.bcc(Utils.pString(oIdentityData['Bcc']));
|
||||
|
||||
return oIdentity;
|
||||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
RainLoopApp.prototype.quota = function ()
|
||||
{
|
||||
this.remote().quota(function (sResult, oData) {
|
||||
if (Enums.StorageResultType.Success === sResult && oData && oData.Result &&
|
||||
Utils.isArray(oData.Result) && 2 === oData.Result.length &&
|
||||
Utils.isPosNumeric(oData.Result[0], true) && Utils.isPosNumeric(oData.Result[1], true))
|
||||
{
|
||||
RL.data().userQuota(Utils.pInt(oData.Result[1]) * 1024);
|
||||
RL.data().userUsageSize(Utils.pInt(oData.Result[0]) * 1024);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sFolder
|
||||
* @param {Array=} aList = []
|
||||
*/
|
||||
RainLoopApp.prototype.folderInformation = function (sFolder, aList)
|
||||
{
|
||||
this.remote().folderInformation(function (sResult, oData) {
|
||||
if (Enums.StorageResultType.Success === sResult)
|
||||
{
|
||||
if (oData && oData.Result && oData.Result.Hash && oData.Result.Folder)
|
||||
{
|
||||
var
|
||||
sHash = RL.cache().getFolderHash(oData.Result.Folder),
|
||||
oFolder = RL.cache().getFolderFromCacheList(oData.Result.Folder),
|
||||
bCheck = false,
|
||||
sUid = '',
|
||||
aList = [],
|
||||
bUnreadCountChange = false,
|
||||
oFlags = null
|
||||
;
|
||||
|
||||
if (oFolder)
|
||||
{
|
||||
if (oData.Result.Hash)
|
||||
{
|
||||
RL.cache().setFolderHash(oData.Result.Folder, oData.Result.Hash);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (bUnreadCountChange)
|
||||
{
|
||||
RL.cache().clearMessageFlagsFromCacheByFolder(oFolder.fullNameRaw);
|
||||
}
|
||||
|
||||
if (oData.Result.Flags)
|
||||
{
|
||||
for (sUid in oData.Result.Flags)
|
||||
{
|
||||
if (oData.Result.Flags.hasOwnProperty(sUid))
|
||||
{
|
||||
bCheck = true;
|
||||
oFlags = oData.Result.Flags[sUid];
|
||||
RL.cache().storeMessageFlagsToCacheByFolderAndUid(oFolder.fullNameRaw, sUid.toString(), [
|
||||
!oFlags['IsSeen'], !!oFlags['IsFlagged'], !!oFlags['IsAnswered'], !!oFlags['IsForwarded']
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if (bCheck)
|
||||
{
|
||||
RL.reloadFlagsCurrentMessageListAndMessageFromCache();
|
||||
}
|
||||
}
|
||||
|
||||
RL.data().initUidNextAndNewMessages(oFolder.fullNameRaw, oData.Result.UidNext, oData.Result.NewMessages);
|
||||
|
||||
if (oData.Result.Hash !== sHash || '' === sHash)
|
||||
{
|
||||
if (oFolder.fullNameRaw === RL.data().currentFolderFullNameRaw())
|
||||
{
|
||||
RL.reloadMessageList();
|
||||
}
|
||||
else if ('INBOX' === oFolder.fullNameRaw)
|
||||
{
|
||||
RL.recacheInboxMessageList();
|
||||
}
|
||||
}
|
||||
else if (bUnreadCountChange)
|
||||
{
|
||||
if (oFolder.fullNameRaw === RL.data().currentFolderFullNameRaw())
|
||||
{
|
||||
aList = RL.data().messageList();
|
||||
if (Utils.isNonEmptyArray(aList))
|
||||
{
|
||||
RL.folderInformation(oFolder.fullNameRaw, aList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, sFolder, aList);
|
||||
};
|
||||
|
||||
RainLoopApp.prototype.setMessageSeen = function (oMessage)
|
||||
{
|
||||
if (oMessage.unseen())
|
||||
{
|
||||
oMessage.unseen(false);
|
||||
|
||||
var oFolder = RL.cache().getFolderFromCacheList(oMessage.folderFullNameRaw);
|
||||
if (oFolder)
|
||||
{
|
||||
oFolder.messageCountUnread(0 <= oFolder.messageCountUnread() - 1 ?
|
||||
oFolder.messageCountUnread() - 1 : 0);
|
||||
}
|
||||
|
||||
RL.cache().storeMessageFlagsToCache(oMessage);
|
||||
RL.reloadFlagsCurrentMessageListAndMessageFromCache();
|
||||
}
|
||||
|
||||
RL.remote().messageSetSeen(Utils.emptyFunction, oMessage.folderFullNameRaw, [oMessage.uid], true);
|
||||
};
|
||||
|
||||
RainLoopApp.prototype.googleConnect = function ()
|
||||
{
|
||||
window.open(RL.link().socialGoogle(), 'Google', 'left=200,top=100,width=650,height=600,menubar=no,status=no,resizable=yes,scrollbars=yes');
|
||||
};
|
||||
|
||||
RainLoopApp.prototype.twitterConnect = function ()
|
||||
{
|
||||
window.open(RL.link().socialTwitter(), 'Twitter', 'left=200,top=100,width=650,height=350,menubar=no,status=no,resizable=yes,scrollbars=yes');
|
||||
};
|
||||
|
||||
RainLoopApp.prototype.facebookConnect = function ()
|
||||
{
|
||||
window.open(RL.link().socialFacebook(), 'Facebook', 'left=200,top=100,width=650,height=335,menubar=no,status=no,resizable=yes,scrollbars=yes');
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean=} bFireAllActions
|
||||
*/
|
||||
RainLoopApp.prototype.socialUsers = function (bFireAllActions)
|
||||
{
|
||||
var oRainLoopData = RL.data();
|
||||
|
||||
if (bFireAllActions)
|
||||
{
|
||||
oRainLoopData.googleActions(true);
|
||||
oRainLoopData.facebookActions(true);
|
||||
oRainLoopData.twitterActions(true);
|
||||
}
|
||||
|
||||
RL.remote().socialUsers(function (sResult, oData) {
|
||||
|
||||
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
|
||||
{
|
||||
oRainLoopData.googleUserName(oData.Result['Google'] || '');
|
||||
oRainLoopData.facebookUserName(oData.Result['Facebook'] || '');
|
||||
oRainLoopData.twitterUserName(oData.Result['Twitter'] || '');
|
||||
}
|
||||
else
|
||||
{
|
||||
oRainLoopData.googleUserName('');
|
||||
oRainLoopData.facebookUserName('');
|
||||
oRainLoopData.twitterUserName('');
|
||||
}
|
||||
|
||||
oRainLoopData.googleLoggined('' !== oRainLoopData.googleUserName());
|
||||
oRainLoopData.facebookLoggined('' !== oRainLoopData.facebookUserName());
|
||||
oRainLoopData.twitterLoggined('' !== oRainLoopData.twitterUserName());
|
||||
|
||||
oRainLoopData.googleActions(false);
|
||||
oRainLoopData.facebookActions(false);
|
||||
oRainLoopData.twitterActions(false);
|
||||
});
|
||||
};
|
||||
|
||||
RainLoopApp.prototype.googleDisconnect = function ()
|
||||
{
|
||||
RL.data().googleActions(true);
|
||||
RL.remote().googleDisconnect(function () {
|
||||
RL.socialUsers();
|
||||
});
|
||||
};
|
||||
|
||||
RainLoopApp.prototype.facebookDisconnect = function ()
|
||||
{
|
||||
RL.data().facebookActions(true);
|
||||
RL.remote().facebookDisconnect(function () {
|
||||
RL.socialUsers();
|
||||
});
|
||||
};
|
||||
|
||||
RainLoopApp.prototype.twitterDisconnect = function ()
|
||||
{
|
||||
RL.data().twitterActions(true);
|
||||
RL.remote().twitterDisconnect(function () {
|
||||
RL.socialUsers();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Array} aSystem
|
||||
* @param {Array} aList
|
||||
* @param {Array=} aDisabled
|
||||
* @param {Array=} aHeaderLines
|
||||
* @param {?number=} iUnDeep
|
||||
* @param {Function=} fDisableCallback
|
||||
* @param {Function=} fVisibleCallback
|
||||
* @param {Function=} fRenameCallback
|
||||
* @param {boolean=} bSystem
|
||||
* @param {boolean=} bBuildUnvisible
|
||||
* @return {Array}
|
||||
*/
|
||||
RainLoopApp.prototype.folderListOptionsBuilder = function (aSystem, aList, aDisabled, aHeaderLines, iUnDeep, fDisableCallback, fVisibleCallback, fRenameCallback, bSystem, bBuildUnvisible)
|
||||
{
|
||||
var
|
||||
iIndex = 0,
|
||||
iLen = 0,
|
||||
/**
|
||||
* @type {?FolderModel}
|
||||
*/
|
||||
oItem = null,
|
||||
sDeepPrefix = '\u00A0\u00A0\u00A0',
|
||||
aResult = []
|
||||
;
|
||||
|
||||
bSystem = !Utils.isNormal(bSystem) ? 0 < aSystem.length : bSystem;
|
||||
bBuildUnvisible = Utils.isUnd(bBuildUnvisible) ? false : !!bBuildUnvisible;
|
||||
iUnDeep = !Utils.isNormal(iUnDeep) ? 0 : iUnDeep;
|
||||
fDisableCallback = Utils.isNormal(fDisableCallback) ? fDisableCallback : null;
|
||||
fVisibleCallback = Utils.isNormal(fVisibleCallback) ? fVisibleCallback : null;
|
||||
fRenameCallback = Utils.isNormal(fRenameCallback) ? fRenameCallback : null;
|
||||
|
||||
if (!Utils.isArray(aDisabled))
|
||||
{
|
||||
aDisabled = [];
|
||||
}
|
||||
|
||||
if (!Utils.isArray(aHeaderLines))
|
||||
{
|
||||
aHeaderLines = [];
|
||||
}
|
||||
|
||||
for (iIndex = 0, iLen = aHeaderLines.length; iIndex < iLen; iIndex++)
|
||||
{
|
||||
aResult.push({
|
||||
'id': aHeaderLines[iIndex][0],
|
||||
'name': aHeaderLines[iIndex][1],
|
||||
'disable': false
|
||||
});
|
||||
}
|
||||
|
||||
for (iIndex = 0, iLen = aSystem.length; iIndex < iLen; iIndex++)
|
||||
{
|
||||
oItem = aSystem[iIndex];
|
||||
if (fVisibleCallback ? fVisibleCallback.call(null, oItem) : true)
|
||||
{
|
||||
aResult.push({
|
||||
'id': oItem.fullNameRaw,
|
||||
'system': true,
|
||||
'name': fRenameCallback ? fRenameCallback.call(null, oItem) : oItem.name(),
|
||||
'disable': !oItem.selectable || -1 < Utils.inArray(oItem.fullNameRaw, aDisabled) ||
|
||||
(fDisableCallback ? fDisableCallback.call(null, oItem) : false)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (iIndex = 0, iLen = aList.length; iIndex < iLen; iIndex++)
|
||||
{
|
||||
oItem = aList[iIndex];
|
||||
if (!oItem.isGmailFolder && (oItem.subScribed() || !oItem.existen))
|
||||
{
|
||||
if (fVisibleCallback ? fVisibleCallback.call(null, oItem) : true)
|
||||
{
|
||||
if (Enums.FolderType.User === oItem.type() || !bSystem || (!oItem.isNamespaceFolder && 0 < oItem.subFolders().length))
|
||||
{
|
||||
aResult.push({
|
||||
'id': oItem.fullNameRaw,
|
||||
'system': false,
|
||||
'name': (new window.Array(oItem.deep + 1 - iUnDeep)).join(sDeepPrefix) +
|
||||
(fRenameCallback ? fRenameCallback.call(null, oItem) : oItem.name()),
|
||||
'disable': !oItem.selectable || -1 < Utils.inArray(oItem.fullNameRaw, aDisabled) ||
|
||||
(Enums.FolderType.User !== oItem.type()) ||
|
||||
(fDisableCallback ? fDisableCallback.call(null, oItem) : false)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (oItem.subScribed() && 0 < oItem.subFolders().length)
|
||||
{
|
||||
aResult = aResult.concat(RL.folderListOptionsBuilder([], oItem.subFolders(), aDisabled, [],
|
||||
oItem.isUnpaddigFolder ? iUnDeep + 1 : iUnDeep,
|
||||
fDisableCallback, fVisibleCallback, fRenameCallback, bSystem, bBuildUnvisible));
|
||||
}
|
||||
}
|
||||
|
||||
return aResult;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} sQuery
|
||||
* @param {number} iPage
|
||||
* @param {Function} fCallback
|
||||
*/
|
||||
RainLoopApp.prototype.getAutocomplete = function (sQuery, iPage, fCallback)
|
||||
{
|
||||
var
|
||||
aData = []
|
||||
;
|
||||
|
||||
RL.remote().suggestions(function (sResult, oData) {
|
||||
if (Enums.StorageResultType.Success === sResult && oData && oData.Result && Utils.isArray(oData.Result.List))
|
||||
{
|
||||
aData = _.map(oData.Result.List, function (aItem) {
|
||||
return aItem && aItem[0] ? new EmailModel(aItem[0], aItem[1]) : null;
|
||||
});
|
||||
|
||||
fCallback(_.compact(aData), !!oData.Result.More);
|
||||
}
|
||||
else if (Enums.StorageResultType.Abort !== sResult)
|
||||
{
|
||||
fCallback([], false);
|
||||
}
|
||||
}, sQuery, iPage);
|
||||
};
|
||||
|
||||
RainLoopApp.prototype.emailsPicsHashes = function ()
|
||||
{
|
||||
RL.remote().emailsPicsHashes(function (sResult, oData) {
|
||||
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
|
||||
{
|
||||
RL.cache().setEmailsPicsHashesData(oData.Result);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
RainLoopApp.prototype.bootstart = function ()
|
||||
{
|
||||
AbstractApp.prototype.bootstart.call(this);
|
||||
|
||||
RL.data().populateDataOnStart();
|
||||
|
||||
var
|
||||
sCustomLoginLink = '',
|
||||
sJsHash = this.settingsGet('JsHash'),
|
||||
bGoogle = this.settingsGet('AllowGoogleSocial'),
|
||||
bFacebook = this.settingsGet('AllowFacebookSocial'),
|
||||
bTwitter = this.settingsGet('AllowTwitterSocial')
|
||||
;
|
||||
|
||||
if (!this.settingsGet('RemoteChangePassword'))
|
||||
{
|
||||
Utils.removeSettingsViewModel(SettingsChangePasswordScreen);
|
||||
}
|
||||
|
||||
if (!this.settingsGet('AllowAdditionalAccounts'))
|
||||
{
|
||||
Utils.removeSettingsViewModel(SettingsAccounts);
|
||||
}
|
||||
|
||||
if (this.settingsGet('AllowIdentities'))
|
||||
{
|
||||
Utils.removeSettingsViewModel(SettingsPersonal);
|
||||
}
|
||||
else
|
||||
{
|
||||
Utils.removeSettingsViewModel(SettingsIdentities);
|
||||
}
|
||||
|
||||
if (!bGoogle && !bFacebook && !bTwitter)
|
||||
{
|
||||
Utils.removeSettingsViewModel(SettingsSocialScreen);
|
||||
}
|
||||
|
||||
if (!this.settingsGet('AllowThemes'))
|
||||
{
|
||||
Utils.removeSettingsViewModel(SettingsThemes);
|
||||
}
|
||||
|
||||
Utils.initOnStartOrLangChange(function () {
|
||||
|
||||
$.extend(true, $.magnificPopup.defaults, {
|
||||
'tClose': Utils.i18n('MAGNIFIC_POPUP/CLOSE'),
|
||||
'tLoading': Utils.i18n('MAGNIFIC_POPUP/LOADING'),
|
||||
'gallery': {
|
||||
'tPrev': Utils.i18n('MAGNIFIC_POPUP/GALLERY_PREV'),
|
||||
'tNext': Utils.i18n('MAGNIFIC_POPUP/GALLERY_NEXT'),
|
||||
'tCounter': Utils.i18n('MAGNIFIC_POPUP/GALLERY_COUNTER')
|
||||
},
|
||||
'image': {
|
||||
'tError': Utils.i18n('MAGNIFIC_POPUP/IMAGE_ERROR')
|
||||
},
|
||||
'ajax': {
|
||||
'tError': Utils.i18n('MAGNIFIC_POPUP/AJAX_ERROR')
|
||||
}
|
||||
});
|
||||
|
||||
}, this);
|
||||
|
||||
if (window.SimplePace)
|
||||
{
|
||||
window.SimplePace.set(70);
|
||||
window.SimplePace.sleep();
|
||||
}
|
||||
|
||||
if (!!this.settingsGet('Auth'))
|
||||
{
|
||||
this.setTitle(Utils.i18n('TITLES/LOADING'));
|
||||
|
||||
this.folders(true, _.bind(function (bValue) {
|
||||
|
||||
kn.hideLoading();
|
||||
|
||||
if (bValue)
|
||||
{
|
||||
kn.startScreens([MailBoxScreen, SettingsScreen]);
|
||||
|
||||
// setup maito protocol
|
||||
$document.on('mousedown', '#rl-center a', function (oEvent) {
|
||||
if (oEvent && 3 !== oEvent['which'])
|
||||
{
|
||||
var oEmailModel = null, sHref = $(this).attr('href');
|
||||
if (sHref && 'mailto:' === sHref.toString().toLowerCase().substr(0, 7))
|
||||
{
|
||||
oEmailModel = new EmailModel();
|
||||
oEmailModel.parse(window.decodeURI(sHref.toString().substr(7)));
|
||||
if (oEmailModel && oEmailModel.email)
|
||||
{
|
||||
kn.showScreenPopup(PopupsComposeViewModel, [Enums.ComposeType.Empty, null, [oEmailModel]]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (bGoogle || bFacebook || bTwitter)
|
||||
{
|
||||
RL.socialUsers(true);
|
||||
}
|
||||
|
||||
_.delay(function () {
|
||||
|
||||
RL.emailsPicsHashes();
|
||||
|
||||
RL.remote().servicesPics(function (sResult, oData) {
|
||||
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
|
||||
{
|
||||
RL.cache().setServicesData(oData.Result);
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
Plugins.runHook('rl-start-user-screens');
|
||||
}
|
||||
else
|
||||
{
|
||||
kn.startScreens([LoginScreen]);
|
||||
Plugins.runHook('rl-start-login-screens');
|
||||
}
|
||||
|
||||
if (window.SimplePace)
|
||||
{
|
||||
window.SimplePace.set(100);
|
||||
}
|
||||
|
||||
if (!Globals.bMobileDevice)
|
||||
{
|
||||
_.defer(function () {
|
||||
Utils.initLayoutResizer('#rl-top-resizer-left', '#rl-top-resizer-right', '#rl-center',
|
||||
120, 300, 200, 600, Enums.ClientSideKeyName.FolderListSize);
|
||||
});
|
||||
}
|
||||
|
||||
}, this));
|
||||
}
|
||||
else
|
||||
{
|
||||
sCustomLoginLink = Utils.pString(this.settingsGet('CustomLoginLink'));
|
||||
if (!sCustomLoginLink)
|
||||
{
|
||||
kn.hideLoading();
|
||||
kn.startScreens([LoginScreen]);
|
||||
|
||||
Plugins.runHook('rl-start-login-screens');
|
||||
|
||||
if (window.SimplePace)
|
||||
{
|
||||
window.SimplePace.set(100);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
kn.routeOff();
|
||||
kn.setHash(RL.link().root(), true);
|
||||
kn.routeOff();
|
||||
|
||||
_.defer(function () {
|
||||
window.location.href = sCustomLoginLink;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (bGoogle)
|
||||
{
|
||||
window['rl_' + sJsHash + '_google_service'] = function () {
|
||||
RL.data().googleActions(true);
|
||||
RL.socialUsers();
|
||||
};
|
||||
}
|
||||
|
||||
if (bFacebook)
|
||||
{
|
||||
window['rl_' + sJsHash + '_facebook_service'] = function () {
|
||||
RL.data().facebookActions(true);
|
||||
RL.socialUsers();
|
||||
};
|
||||
}
|
||||
|
||||
if (bTwitter)
|
||||
{
|
||||
window['rl_' + sJsHash + '_twitter_service'] = function () {
|
||||
RL.data().twitterActions(true);
|
||||
RL.socialUsers();
|
||||
};
|
||||
}
|
||||
|
||||
Plugins.runHook('rl-start-screens');
|
||||
};
|
||||
|
||||
/**
|
||||
* @type {RainLoopApp}
|
||||
*/
|
||||
RL = new RainLoopApp();
|
||||
Loading…
Add table
Add a link
Reference in a new issue