Code refactoring

This commit is contained in:
RainLoop Team 2014-08-26 19:24:47 +04:00
parent 4a95dd6195
commit 36329110e5
81 changed files with 3474 additions and 2124 deletions

View file

@ -0,0 +1,103 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
(function (module, require) {
'use strict';
var
window = require('window'),
_ = require('_'),
ko = require('ko'),
Enums = require('Enums'),
Utils = require('Utils'),
LinkBuilder = require('LinkBuilder'),
Data = require('../../Storages/WebMailDataStorage.js'),
Remote = require('../../Storages/WebMailAjaxRemoteStorage.js'),
kn = require('kn'),
PopupsAddAccountViewModel = require('../../ViewModels/Popups/PopupsAddAccountViewModel.js')
;
/**
* @constructor
*/
function SettingsAccounts()
{
this.accounts = Data.accounts;
this.processText = ko.computed(function () {
return Data.accountsLoading() ? Utils.i18n('SETTINGS_ACCOUNTS/LOADING_PROCESS') : '';
}, this);
this.visibility = ko.computed(function () {
return '' === this.processText() ? 'hidden' : 'visible';
}, this);
this.accountForDeletion = ko.observable(null).extend({'falseTimeout': 3000}).extend({'toggleSubscribe': [this,
function (oPrev) {
if (oPrev)
{
oPrev.deleteAccess(false);
}
}, function (oNext) {
if (oNext)
{
oNext.deleteAccess(true);
}
}
]});
}
SettingsAccounts.prototype.addNewAccount = function ()
{
kn.showScreenPopup(PopupsAddAccountViewModel);
};
/**
* @param {AccountModel} oAccountToRemove
*/
SettingsAccounts.prototype.deleteAccount = function (oAccountToRemove)
{
if (oAccountToRemove && oAccountToRemove.deleteAccess())
{
this.accountForDeletion(null);
var
App = require('../../Apps/RainLoopApp.js'),
fRemoveAccount = function (oAccount) {
return oAccountToRemove === oAccount;
}
;
if (oAccountToRemove)
{
this.accounts.remove(fRemoveAccount);
Remote.accountDelete(function (sResult, oData) {
if (Enums.StorageResultType.Success === sResult && oData &&
oData.Result && oData.Reload)
{
kn.routeOff();
kn.setHash(LinkBuilder.root(), true);
kn.routeOff();
_.defer(function () {
window.location.reload();
});
}
else
{
App.accountsAndIdentities();
}
}, oAccountToRemove.email);
}
}
};
module.exports = SettingsAccounts;
}(module, require));

View file

@ -0,0 +1,122 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
(function (module, require) {
'use strict';
var
_ = require('_'),
ko = require('ko'),
Enums = require('Enums'),
Utils = require('Utils'),
Remote = require('../../Storages/WebMailAjaxRemoteStorage.js')
;
/**
* @constructor
*/
function SettingsChangePassword()
{
this.changeProcess = ko.observable(false);
this.errorDescription = ko.observable('');
this.passwordMismatch = ko.observable(false);
this.passwordUpdateError = ko.observable(false);
this.passwordUpdateSuccess = ko.observable(false);
this.currentPassword = ko.observable('');
this.currentPassword.error = ko.observable(false);
this.newPassword = ko.observable('');
this.newPassword2 = ko.observable('');
this.currentPassword.subscribe(function () {
this.passwordUpdateError(false);
this.passwordUpdateSuccess(false);
this.currentPassword.error(false);
}, this);
this.newPassword.subscribe(function () {
this.passwordUpdateError(false);
this.passwordUpdateSuccess(false);
this.passwordMismatch(false);
}, this);
this.newPassword2.subscribe(function () {
this.passwordUpdateError(false);
this.passwordUpdateSuccess(false);
this.passwordMismatch(false);
}, this);
this.saveNewPasswordCommand = Utils.createCommand(this, function () {
if (this.newPassword() !== this.newPassword2())
{
this.passwordMismatch(true);
this.errorDescription(Utils.i18n('SETTINGS_CHANGE_PASSWORD/ERROR_PASSWORD_MISMATCH'));
}
else
{
this.changeProcess(true);
this.passwordUpdateError(false);
this.passwordUpdateSuccess(false);
this.currentPassword.error(false);
this.passwordMismatch(false);
this.errorDescription('');
Remote.changePassword(this.onChangePasswordResponse, this.currentPassword(), this.newPassword());
}
}, function () {
return !this.changeProcess() && '' !== this.currentPassword() &&
'' !== this.newPassword() && '' !== this.newPassword2();
});
this.onChangePasswordResponse = _.bind(this.onChangePasswordResponse, this);
}
SettingsChangePassword.prototype.onHide = function ()
{
this.changeProcess(false);
this.currentPassword('');
this.newPassword('');
this.newPassword2('');
this.errorDescription('');
this.passwordMismatch(false);
this.currentPassword.error(false);
};
SettingsChangePassword.prototype.onChangePasswordResponse = function (sResult, oData)
{
this.changeProcess(false);
this.passwordMismatch(false);
this.errorDescription('');
this.currentPassword.error(false);
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
{
this.currentPassword('');
this.newPassword('');
this.newPassword2('');
this.passwordUpdateSuccess(true);
this.currentPassword.error(false);
}
else
{
if (oData && Enums.Notification.CurrentPasswordIncorrect === oData.ErrorCode)
{
this.currentPassword.error(true);
}
this.passwordUpdateError(true);
this.errorDescription(oData && oData.ErrorCode ? Utils.getNotification(oData.ErrorCode) :
Utils.getNotification(Enums.Notification.CouldNotSaveNewPassword));
}
};
module.exports = SettingsChangePassword;
}(module, require));

View file

@ -0,0 +1,59 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
(function (module, require) {
'use strict';
var
ko = require('ko'),
Utils = require('Utils'),
Remote = require('../../Storages/WebMailAjaxRemoteStorage.js'),
Data = require('../../Storages/WebMailDataStorage.js')
;
/**
* @constructor
*/
function SettingsContacts()
{
this.contactsAutosave = Data.contactsAutosave;
this.allowContactsSync = Data.allowContactsSync;
this.enableContactsSync = Data.enableContactsSync;
this.contactsSyncUrl = Data.contactsSyncUrl;
this.contactsSyncUser = Data.contactsSyncUser;
this.contactsSyncPass = Data.contactsSyncPass;
this.saveTrigger = ko.computed(function () {
return [
this.enableContactsSync() ? '1' : '0',
this.contactsSyncUrl(),
this.contactsSyncUser(),
this.contactsSyncPass()
].join('|');
}, this).extend({'throttle': 500});
this.saveTrigger.subscribe(function () {
Remote.saveContactsSyncData(null,
this.enableContactsSync(),
this.contactsSyncUrl(),
this.contactsSyncUser(),
this.contactsSyncPass()
);
}, this);
}
SettingsContacts.prototype.onBuild = function ()
{
Data.contactsAutosave.subscribe(function (bValue) {
Remote.saveSettings(Utils.emptyFunction, {
'ContactsAutosave': bValue ? '1' : '0'
});
});
};
module.exports = SettingsContacts;
}(module, require));

View file

@ -0,0 +1,43 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
(function (module, require) {
'use strict';
var
ko = require('ko'),
Utils = require('Utils')
;
/**
* @constructor
*/
function SettingsFilters()
{
this.filters = ko.observableArray([]);
this.filters.loading = ko.observable(false);
this.filters.subscribe(function () {
Utils.windowResize();
});
}
SettingsFilters.prototype.deleteFilter = function (oFilter)
{
this.filters.remove(oFilter);
};
SettingsFilters.prototype.addFilter = function ()
{
var
kn = require('kn'),
FilterModel = require('../../Models/FilterModel.js'),
PopupsFilterViewModel = require('../../ViewModels/Popups/PopupsFilterViewModel.js')
;
kn.showScreenPopup(PopupsFilterViewModel, [new FilterModel()]);
};
module.exports = SettingsFilters;
}(module, require));

View file

@ -0,0 +1,222 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
(function (module, require) {
'use strict';
var
ko = require('ko'),
Enums = require('Enums'),
Utils = require('Utils'),
kn = require('kn'),
AppSettings = require('../../Storages/AppSettings.js'),
LocalStorage = require('../../Storages/LocalStorage.js'),
Data = require('../../Storages/WebMailDataStorage.js'),
Cache = require('../../Storages/WebMailCacheStorage.js'),
Remote = require('../../Storages/WebMailAjaxRemoteStorage.js'),
PopupsFolderCreateViewModel = require('../../ViewModels/Popups/PopupsFolderCreateViewModel.js'),
PopupsFolderSystemViewModel = require('../../ViewModels/Popups/PopupsFolderSystemViewModel.js')
;
/**
* @constructor
*/
function SettingsFolders()
{
this.foldersListError = Data.foldersListError;
this.folderList = Data.folderList;
this.processText = ko.computed(function () {
var
bLoading = Data.foldersLoading(),
bCreating = Data.foldersCreating(),
bDeleting = Data.foldersDeleting(),
bRenaming = Data.foldersRenaming()
;
if (bCreating)
{
return Utils.i18n('SETTINGS_FOLDERS/CREATING_PROCESS');
}
else if (bDeleting)
{
return Utils.i18n('SETTINGS_FOLDERS/DELETING_PROCESS');
}
else if (bRenaming)
{
return Utils.i18n('SETTINGS_FOLDERS/RENAMING_PROCESS');
}
else if (bLoading)
{
return Utils.i18n('SETTINGS_FOLDERS/LOADING_PROCESS');
}
return '';
}, this);
this.visibility = ko.computed(function () {
return '' === this.processText() ? 'hidden' : 'visible';
}, this);
this.folderForDeletion = ko.observable(null).extend({'falseTimeout': 3000}).extend({'toggleSubscribe': [this,
function (oPrev) {
if (oPrev)
{
oPrev.deleteAccess(false);
}
}, function (oNext) {
if (oNext)
{
oNext.deleteAccess(true);
}
}
]});
this.folderForEdit = ko.observable(null).extend({'toggleSubscribe': [this,
function (oPrev) {
if (oPrev)
{
oPrev.edited(false);
}
}, function (oNext) {
if (oNext && oNext.canBeEdited())
{
oNext.edited(true);
}
}
]});
this.useImapSubscribe = !!AppSettings.settingsGet('UseImapSubscribe');
}
SettingsFolders.prototype.folderEditOnEnter = function (oFolder)
{
var
App = require('../../Apps/RainLoopApp.js'),
sEditName = oFolder ? Utils.trim(oFolder.nameForEdit()) : ''
;
if ('' !== sEditName && oFolder.name() !== sEditName)
{
LocalStorage.set(Enums.ClientSideKeyName.FoldersLashHash, '');
Data.foldersRenaming(true);
Remote.folderRename(function (sResult, oData) {
Data.foldersRenaming(false);
if (Enums.StorageResultType.Success !== sResult || !oData || !oData.Result)
{
Data.foldersListError(
oData && oData.ErrorCode ? Utils.getNotification(oData.ErrorCode) : Utils.i18n('NOTIFICATIONS/CANT_RENAME_FOLDER'));
}
App.folders();
}, oFolder.fullNameRaw, sEditName);
Cache.removeFolderFromCacheList(oFolder.fullNameRaw);
oFolder.name(sEditName);
}
oFolder.edited(false);
};
SettingsFolders.prototype.folderEditOnEsc = function (oFolder)
{
if (oFolder)
{
oFolder.edited(false);
}
};
SettingsFolders.prototype.onShow = function ()
{
Data.foldersListError('');
};
SettingsFolders.prototype.createFolder = function ()
{
kn.showScreenPopup(PopupsFolderCreateViewModel);
};
SettingsFolders.prototype.systemFolder = function ()
{
kn.showScreenPopup(PopupsFolderSystemViewModel);
};
SettingsFolders.prototype.deleteFolder = function (oFolderToRemove)
{
if (oFolderToRemove && oFolderToRemove.canBeDeleted() && oFolderToRemove.deleteAccess() &&
0 === oFolderToRemove.privateMessageCountAll())
{
this.folderForDeletion(null);
var
App = require('../../Apps/RainLoopApp.js'),
fRemoveFolder = function (oFolder) {
if (oFolderToRemove === oFolder)
{
return true;
}
oFolder.subFolders.remove(fRemoveFolder);
return false;
}
;
if (oFolderToRemove)
{
LocalStorage.set(Enums.ClientSideKeyName.FoldersLashHash, '');
Data.folderList.remove(fRemoveFolder);
Data.foldersDeleting(true);
Remote.folderDelete(function (sResult, oData) {
Data.foldersDeleting(false);
if (Enums.StorageResultType.Success !== sResult || !oData || !oData.Result)
{
Data.foldersListError(
oData && oData.ErrorCode ? Utils.getNotification(oData.ErrorCode) : Utils.i18n('NOTIFICATIONS/CANT_DELETE_FOLDER'));
}
App.folders();
}, oFolderToRemove.fullNameRaw);
Cache.removeFolderFromCacheList(oFolderToRemove.fullNameRaw);
}
}
else if (0 < oFolderToRemove.privateMessageCountAll())
{
Data.foldersListError(Utils.getNotification(Enums.Notification.CantDeleteNonEmptyFolder));
}
};
SettingsFolders.prototype.subscribeFolder = function (oFolder)
{
LocalStorage.set(Enums.ClientSideKeyName.FoldersLashHash, '');
Remote.folderSetSubscribe(Utils.emptyFunction, oFolder.fullNameRaw, true);
oFolder.subScribed(true);
};
SettingsFolders.prototype.unSubscribeFolder = function (oFolder)
{
LocalStorage.set(Enums.ClientSideKeyName.FoldersLashHash, '');
Remote.folderSetSubscribe(Utils.emptyFunction, oFolder.fullNameRaw, false);
oFolder.subScribed(false);
};
module.exports = SettingsFolders;
}(module, require));

View file

@ -0,0 +1,182 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
(function (module, require) {
'use strict';
var
$ = require('$'),
ko = require('ko'),
_ = require('_'),
Enums = require('Enums'),
Consts = require('Consts'),
Globals = require('Globals'),
Utils = require('Utils'),
LinkBuilder = require('LinkBuilder'),
Data = require('../../Storages/WebMailDataStorage.js'),
Remote = require('../../Storages/WebMailAjaxRemoteStorage.js'),
kn = require('kn'),
PopupsLanguagesViewModel = require('../../ViewModels/Popups/PopupsLanguagesViewModel.js')
;
/**
* @constructor
*/
function SettingsGeneral()
{
this.mainLanguage = Data.mainLanguage;
this.mainMessagesPerPage = Data.mainMessagesPerPage;
this.mainMessagesPerPageArray = Consts.Defaults.MessagesPerPageArray;
this.editorDefaultType = Data.editorDefaultType;
this.showImages = Data.showImages;
this.interfaceAnimation = Data.interfaceAnimation;
this.useDesktopNotifications = Data.useDesktopNotifications;
this.threading = Data.threading;
this.useThreads = Data.useThreads;
this.replySameFolder = Data.replySameFolder;
this.layout = Data.layout;
this.usePreviewPane = Data.usePreviewPane;
this.useCheckboxesInList = Data.useCheckboxesInList;
this.allowLanguagesOnSettings = Data.allowLanguagesOnSettings;
this.isDesktopNotificationsSupported = ko.computed(function () {
return Enums.DesktopNotifications.NotSupported !== Data.desktopNotificationsPermisions();
});
this.isDesktopNotificationsDenied = ko.computed(function () {
return Enums.DesktopNotifications.NotSupported === Data.desktopNotificationsPermisions() ||
Enums.DesktopNotifications.Denied === Data.desktopNotificationsPermisions();
});
this.mainLanguageFullName = ko.computed(function () {
return Utils.convertLangName(this.mainLanguage());
}, this);
this.languageTrigger = ko.observable(Enums.SaveSettingsStep.Idle).extend({'throttle': 100});
this.mppTrigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.isAnimationSupported = Globals.bAnimationSupported;
}
SettingsGeneral.prototype.toggleLayout = function ()
{
this.layout(Enums.Layout.NoPreview === this.layout() ? Enums.Layout.SidePreview : Enums.Layout.NoPreview);
};
SettingsGeneral.prototype.onBuild = function ()
{
var self = this;
_.delay(function () {
var
f1 = Utils.settingsSaveHelperSimpleFunction(self.mppTrigger, self)
;
Data.language.subscribe(function (sValue) {
self.languageTrigger(Enums.SaveSettingsStep.Animate);
$.ajax({
'url': LinkBuilder.langLink(sValue),
'dataType': 'script',
'cache': true
}).done(function() {
Utils.i18nReload();
self.languageTrigger(Enums.SaveSettingsStep.TrueResult);
}).fail(function() {
self.languageTrigger(Enums.SaveSettingsStep.FalseResult);
}).always(function() {
_.delay(function () {
self.languageTrigger(Enums.SaveSettingsStep.Idle);
}, 1000);
});
Remote.saveSettings(Utils.emptyFunction, {
'Language': sValue
});
});
Data.editorDefaultType.subscribe(function (sValue) {
Remote.saveSettings(Utils.emptyFunction, {
'EditorDefaultType': sValue
});
});
Data.messagesPerPage.subscribe(function (iValue) {
Remote.saveSettings(f1, {
'MPP': iValue
});
});
Data.showImages.subscribe(function (bValue) {
Remote.saveSettings(Utils.emptyFunction, {
'ShowImages': bValue ? '1' : '0'
});
});
Data.interfaceAnimation.subscribe(function (sValue) {
Remote.saveSettings(Utils.emptyFunction, {
'InterfaceAnimation': sValue
});
});
Data.useDesktopNotifications.subscribe(function (bValue) {
Utils.timeOutAction('SaveDesktopNotifications', function () {
Remote.saveSettings(Utils.emptyFunction, {
'DesktopNotifications': bValue ? '1' : '0'
});
}, 3000);
});
Data.replySameFolder.subscribe(function (bValue) {
Utils.timeOutAction('SaveReplySameFolder', function () {
Remote.saveSettings(Utils.emptyFunction, {
'ReplySameFolder': bValue ? '1' : '0'
});
}, 3000);
});
Data.useThreads.subscribe(function (bValue) {
Data.messageList([]);
Remote.saveSettings(Utils.emptyFunction, {
'UseThreads': bValue ? '1' : '0'
});
});
Data.layout.subscribe(function (nValue) {
Data.messageList([]);
Remote.saveSettings(Utils.emptyFunction, {
'Layout': nValue
});
});
Data.useCheckboxesInList.subscribe(function (bValue) {
Remote.saveSettings(Utils.emptyFunction, {
'UseCheckboxesInList': bValue ? '1' : '0'
});
});
}, 50);
};
SettingsGeneral.prototype.onShow = function ()
{
Data.desktopNotifications.valueHasMutated();
};
SettingsGeneral.prototype.selectLanguage = function ()
{
kn.showScreenPopup(PopupsLanguagesViewModel);
};
module.exports = SettingsGeneral;
}(module, require));

View file

@ -0,0 +1,238 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
(function (module, require) {
'use strict';
var
ko = require('ko'),
_ = require('_'),
Enums = require('Enums'),
Utils = require('Utils'),
NewHtmlEditorWrapper = require('NewHtmlEditorWrapper'),
Data = require('../../Storages/WebMailDataStorage.js'),
Remote = require('../../Storages/WebMailAjaxRemoteStorage.js'),
kn = require('kn'),
PopupsIdentityViewModel = require('../../ViewModels/Popups/PopupsIdentityViewModel.js')
;
/**
* @constructor
*/
function SettingsIdentities()
{
this.editor = null;
this.defautOptionsAfterRender = Utils.defautOptionsAfterRender;
this.accountEmail = Data.accountEmail;
this.displayName = Data.displayName;
this.signature = Data.signature;
this.signatureToAll = Data.signatureToAll;
this.replyTo = Data.replyTo;
this.signatureDom = ko.observable(null);
this.defaultIdentityIDTrigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.displayNameTrigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.replyTrigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.signatureTrigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.identities = Data.identities;
this.defaultIdentityID = Data.defaultIdentityID;
this.identitiesOptions = ko.computed(function () {
var
aList = this.identities(),
aResult = []
;
if (0 < aList.length)
{
aResult.push({
'id': this.accountEmail.peek(),
'name': this.formattedAccountIdentity(),
'seporator': false
});
aResult.push({
'id': '---',
'name': '---',
'seporator': true,
'disabled': true
});
_.each(aList, function (oItem) {
aResult.push({
'id': oItem.id,
'name': oItem.formattedNameForEmail(),
'seporator': false
});
});
}
return aResult;
}, this);
this.processText = ko.computed(function () {
return Data.identitiesLoading() ? Utils.i18n('SETTINGS_IDENTITIES/LOADING_PROCESS') : '';
}, this);
this.visibility = ko.computed(function () {
return '' === this.processText() ? 'hidden' : 'visible';
}, this);
this.identityForDeletion = ko.observable(null).extend({'falseTimeout': 3000}).extend({'toggleSubscribe': [this,
function (oPrev) {
if (oPrev)
{
oPrev.deleteAccess(false);
}
}, function (oNext) {
if (oNext)
{
oNext.deleteAccess(true);
}
}
]});
}
/**
*
* @return {string}
*/
SettingsIdentities.prototype.formattedAccountIdentity = function ()
{
var
sDisplayName = this.displayName.peek(),
sEmail = this.accountEmail.peek()
;
return '' === sDisplayName ? sEmail : '"' + Utils.quoteName(sDisplayName) + '" <' + sEmail + '>';
};
SettingsIdentities.prototype.addNewIdentity = function ()
{
kn.showScreenPopup(PopupsIdentityViewModel);
};
SettingsIdentities.prototype.editIdentity = function (oIdentity)
{
kn.showScreenPopup(PopupsIdentityViewModel, [oIdentity]);
};
/**
* @param {IdentityModel} oIdentityToRemove
*/
SettingsIdentities.prototype.deleteIdentity = function (oIdentityToRemove)
{
if (oIdentityToRemove && oIdentityToRemove.deleteAccess())
{
this.identityForDeletion(null);
var
App = require('../../Apps/RainLoopApp.js'),
fRemoveFolder = function (oIdentity) {
return oIdentityToRemove === oIdentity;
}
;
if (oIdentityToRemove)
{
this.identities.remove(fRemoveFolder);
Remote.identityDelete(function () {
App.accountsAndIdentities();
}, oIdentityToRemove.id);
}
}
};
SettingsIdentities.prototype.onFocus = function ()
{
if (!this.editor && this.signatureDom())
{
var
self = this,
sSignature = Data.signature()
;
this.editor = new NewHtmlEditorWrapper(self.signatureDom(), function () {
Data.signature(
(self.editor.isHtml() ? ':HTML:' : '') + self.editor.getData()
);
}, function () {
if (':HTML:' === sSignature.substr(0, 6))
{
self.editor.setHtml(sSignature.substr(6), false);
}
else
{
self.editor.setPlain(sSignature, false);
}
});
}
};
SettingsIdentities.prototype.onBuild = function (oDom)
{
var self = this;
oDom
.on('click', '.identity-item .e-action', function () {
var oIdentityItem = ko.dataFor(this);
if (oIdentityItem)
{
self.editIdentity(oIdentityItem);
}
})
;
_.delay(function () {
var
f1 = Utils.settingsSaveHelperSimpleFunction(self.displayNameTrigger, self),
f2 = Utils.settingsSaveHelperSimpleFunction(self.replyTrigger, self),
f3 = Utils.settingsSaveHelperSimpleFunction(self.signatureTrigger, self),
f4 = Utils.settingsSaveHelperSimpleFunction(self.defaultIdentityIDTrigger, self)
;
Data.defaultIdentityID.subscribe(function (sValue) {
Remote.saveSettings(f4, {
'DefaultIdentityID': sValue
});
});
Data.displayName.subscribe(function (sValue) {
Remote.saveSettings(f1, {
'DisplayName': sValue
});
});
Data.replyTo.subscribe(function (sValue) {
Remote.saveSettings(f2, {
'ReplyTo': sValue
});
});
Data.signature.subscribe(function (sValue) {
Remote.saveSettings(f3, {
'Signature': sValue
});
});
Data.signatureToAll.subscribe(function (bValue) {
Remote.saveSettings(null, {
'SignatureToAll': bValue ? '1' : '0'
});
});
}, 50);
};
module.exports = SettingsIdentities;
}(module, require));

View file

@ -0,0 +1,104 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
(function (module, require) {
'use strict';
var
ko = require('ko'),
_ = require('_'),
Enums = require('Enums'),
Utils = require('Utils'),
NewHtmlEditorWrapper = require('NewHtmlEditorWrapper'),
Data = require('../../Storages/WebMailDataStorage.js'),
Remote = require('../../Storages/WebMailAjaxRemoteStorage.js')
;
/**
* @constructor
*/
function SettingsIdentity()
{
this.editor = null;
this.displayName = Data.displayName;
this.signature = Data.signature;
this.signatureToAll = Data.signatureToAll;
this.replyTo = Data.replyTo;
this.signatureDom = ko.observable(null);
this.displayNameTrigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.replyTrigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.signatureTrigger = ko.observable(Enums.SaveSettingsStep.Idle);
}
SettingsIdentity.prototype.onFocus = function ()
{
if (!this.editor && this.signatureDom())
{
var
self = this,
sSignature = Data.signature()
;
this.editor = new NewHtmlEditorWrapper(self.signatureDom(), function () {
Data.signature(
(self.editor.isHtml() ? ':HTML:' : '') + self.editor.getData()
);
}, function () {
if (':HTML:' === sSignature.substr(0, 6))
{
self.editor.setHtml(sSignature.substr(6), false);
}
else
{
self.editor.setPlain(sSignature, false);
}
});
}
};
SettingsIdentity.prototype.onBuild = function ()
{
var self = this;
_.delay(function () {
var
f1 = Utils.settingsSaveHelperSimpleFunction(self.displayNameTrigger, self),
f2 = Utils.settingsSaveHelperSimpleFunction(self.replyTrigger, self),
f3 = Utils.settingsSaveHelperSimpleFunction(self.signatureTrigger, self)
;
Data.displayName.subscribe(function (sValue) {
Remote.saveSettings(f1, {
'DisplayName': sValue
});
});
Data.replyTo.subscribe(function (sValue) {
Remote.saveSettings(f2, {
'ReplyTo': sValue
});
});
Data.signature.subscribe(function (sValue) {
Remote.saveSettings(f3, {
'Signature': sValue
});
});
Data.signatureToAll.subscribe(function (bValue) {
Remote.saveSettings(null, {
'SignatureToAll': bValue ? '1' : '0'
});
});
}, 50);
};
module.exports = SettingsIdentity;
}(module, require));

View file

@ -0,0 +1,89 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
(function (module, require) {
'use strict';
var
ko = require('ko'),
kn = require('kn'),
Data = require('../../Storages/WebMailDataStorage.js'),
PopupsAddOpenPgpKeyViewModel = require('../../ViewModels/Popups/PopupsAddOpenPgpKeyViewModel.js'),
PopupsGenerateNewOpenPgpKeyViewModel = require('../../ViewModels/Popups/PopupsGenerateNewOpenPgpKeyViewModel.js'),
PopupsViewOpenPgpKeyViewModel = require('../../ViewModels/Popups/PopupsViewOpenPgpKeyViewModel.js')
;
/**
* @constructor
*/
function SettingsOpenPGP()
{
this.openpgpkeys = Data.openpgpkeys;
this.openpgpkeysPublic = Data.openpgpkeysPublic;
this.openpgpkeysPrivate = Data.openpgpkeysPrivate;
this.openPgpKeyForDeletion = ko.observable(null).extend({'falseTimeout': 3000}).extend({'toggleSubscribe': [this,
function (oPrev) {
if (oPrev)
{
oPrev.deleteAccess(false);
}
}, function (oNext) {
if (oNext)
{
oNext.deleteAccess(true);
}
}
]});
}
SettingsOpenPGP.prototype.addOpenPgpKey = function ()
{
kn.showScreenPopup(PopupsAddOpenPgpKeyViewModel);
};
SettingsOpenPGP.prototype.generateOpenPgpKey = function ()
{
kn.showScreenPopup(PopupsGenerateNewOpenPgpKeyViewModel);
};
SettingsOpenPGP.prototype.viewOpenPgpKey = function (oOpenPgpKey)
{
if (oOpenPgpKey)
{
kn.showScreenPopup(PopupsViewOpenPgpKeyViewModel, [oOpenPgpKey]);
}
};
/**
* @param {OpenPgpKeyModel} oOpenPgpKeyToRemove
*/
SettingsOpenPGP.prototype.deleteOpenPgpKey = function (oOpenPgpKeyToRemove)
{
if (oOpenPgpKeyToRemove && oOpenPgpKeyToRemove.deleteAccess())
{
this.openPgpKeyForDeletion(null);
if (oOpenPgpKeyToRemove && Data.openpgpKeyring)
{
this.openpgpkeys.remove(function (oOpenPgpKey) {
return oOpenPgpKeyToRemove === oOpenPgpKey;
});
Data.openpgpKeyring[oOpenPgpKeyToRemove.isPrivate ? 'privateKeys' : 'publicKeys']
.removeForId(oOpenPgpKeyToRemove.guid);
Data.openpgpKeyring.store();
var App = require('../../Apps/RainLoopApp.js');
App.reloadOpenPgpKeys();
}
}
};
module.exports = SettingsOpenPGP;
}(module, require));

View file

@ -0,0 +1,170 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
(function (module, require) {
'use strict';
var
ko = require('ko'),
Enums = require('Enums'),
Globals = require('Globals'),
Utils = require('Utils'),
Remote = require('../../Storages/WebMailAjaxRemoteStorage.js'),
kn = require('kn'),
PopupsTwoFactorTestViewModel = require('../../ViewModels/Popups/PopupsTwoFactorTestViewModel.js')
;
/**
* @constructor
*/
function SettingsSecurity()
{
this.processing = ko.observable(false);
this.clearing = ko.observable(false);
this.secreting = ko.observable(false);
this.viewUser = ko.observable('');
this.viewEnable = ko.observable(false);
this.viewEnable.subs = true;
this.twoFactorStatus = ko.observable(false);
this.viewSecret = ko.observable('');
this.viewBackupCodes = ko.observable('');
this.viewUrl = ko.observable('');
this.bFirst = true;
this.viewTwoFactorStatus = ko.computed(function () {
Globals.langChangeTrigger();
return Utils.i18n(
this.twoFactorStatus() ?
'SETTINGS_SECURITY/TWO_FACTOR_SECRET_CONFIGURED_DESC' :
'SETTINGS_SECURITY/TWO_FACTOR_SECRET_NOT_CONFIGURED_DESC'
);
}, this);
this.onResult = _.bind(this.onResult, this);
this.onSecretResult = _.bind(this.onSecretResult, this);
}
SettingsSecurity.prototype.showSecret = function ()
{
this.secreting(true);
Remote.showTwoFactorSecret(this.onSecretResult);
};
SettingsSecurity.prototype.hideSecret = function ()
{
this.viewSecret('');
this.viewBackupCodes('');
this.viewUrl('');
};
SettingsSecurity.prototype.createTwoFactor = function ()
{
this.processing(true);
Remote.createTwoFactor(this.onResult);
};
SettingsSecurity.prototype.enableTwoFactor = function ()
{
this.processing(true);
Remote.enableTwoFactor(this.onResult, this.viewEnable());
};
SettingsSecurity.prototype.testTwoFactor = function ()
{
kn.showScreenPopup(PopupsTwoFactorTestViewModel);
};
SettingsSecurity.prototype.clearTwoFactor = function ()
{
this.viewSecret('');
this.viewBackupCodes('');
this.viewUrl('');
this.clearing(true);
Remote.clearTwoFactor(this.onResult);
};
SettingsSecurity.prototype.onShow = function ()
{
this.viewSecret('');
this.viewBackupCodes('');
this.viewUrl('');
};
SettingsSecurity.prototype.onResult = function (sResult, oData)
{
this.processing(false);
this.clearing(false);
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
{
this.viewUser(Utils.pString(oData.Result.User));
this.viewEnable(!!oData.Result.Enable);
this.twoFactorStatus(!!oData.Result.IsSet);
this.viewSecret(Utils.pString(oData.Result.Secret));
this.viewBackupCodes(Utils.pString(oData.Result.BackupCodes).replace(/[\s]+/g, ' '));
this.viewUrl(Utils.pString(oData.Result.Url));
}
else
{
this.viewUser('');
this.viewEnable(false);
this.twoFactorStatus(false);
this.viewSecret('');
this.viewBackupCodes('');
this.viewUrl('');
}
if (this.bFirst)
{
this.bFirst = false;
var self = this;
this.viewEnable.subscribe(function (bValue) {
if (this.viewEnable.subs)
{
Remote.enableTwoFactor(function (sResult, oData) {
if (Enums.StorageResultType.Success !== sResult || !oData || !oData.Result)
{
self.viewEnable.subs = false;
self.viewEnable(false);
self.viewEnable.subs = true;
}
}, bValue);
}
}, this);
}
};
SettingsSecurity.prototype.onSecretResult = function (sResult, oData)
{
this.secreting(false);
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
{
this.viewSecret(Utils.pString(oData.Result.Secret));
this.viewUrl(Utils.pString(oData.Result.Url));
}
else
{
this.viewSecret('');
this.viewUrl('');
}
};
SettingsSecurity.prototype.onBuild = function ()
{
this.processing(true);
Remote.getTwoFactor(this.onResult);
};
module.exports = SettingsSecurity;
}(module, require));

View file

@ -0,0 +1,78 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
(function (module, require) {
'use strict';
/**
* @constructor
*/
function SettingsSocial()
{
var
Utils = require('Utils'),
App = require('../../Apps/RainLoopApp.js'),
Data = require('../../Storages/WebMailDataStorage.js')
;
this.googleEnable = Data.googleEnable;
this.googleActions = Data.googleActions;
this.googleLoggined = Data.googleLoggined;
this.googleUserName = Data.googleUserName;
this.facebookEnable = Data.facebookEnable;
this.facebookActions = Data.facebookActions;
this.facebookLoggined = Data.facebookLoggined;
this.facebookUserName = Data.facebookUserName;
this.twitterEnable = Data.twitterEnable;
this.twitterActions = Data.twitterActions;
this.twitterLoggined = Data.twitterLoggined;
this.twitterUserName = Data.twitterUserName;
this.connectGoogle = Utils.createCommand(this, function () {
if (!this.googleLoggined())
{
App.googleConnect();
}
}, function () {
return !this.googleLoggined() && !this.googleActions();
});
this.disconnectGoogle = Utils.createCommand(this, function () {
App.googleDisconnect();
});
this.connectFacebook = Utils.createCommand(this, function () {
if (!this.facebookLoggined())
{
App.facebookConnect();
}
}, function () {
return !this.facebookLoggined() && !this.facebookActions();
});
this.disconnectFacebook = Utils.createCommand(this, function () {
App.facebookDisconnect();
});
this.connectTwitter = Utils.createCommand(this, function () {
if (!this.twitterLoggined())
{
App.twitterConnect();
}
}, function () {
return !this.twitterLoggined() && !this.twitterActions();
});
this.disconnectTwitter = Utils.createCommand(this, function () {
App.twitterDisconnect();
});
}
module.exports = SettingsSocial;
}(module, require));

View file

@ -0,0 +1,133 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
(function (module, require) {
'use strict';
var
window = require('window'),
$ = require('$'),
ko = require('ko'),
_ = require('_'),
Enums = require('Enums'),
Utils = require('Utils'),
LinkBuilder = require('LinkBuilder'),
Data = require('../../Storages/WebMailDataStorage.js'),
Remote = require('../../Storages/WebMailAjaxRemoteStorage.js')
;
/**
* @constructor
*/
function SettingsThemes()
{
var self = this;
this.mainTheme = Data.mainTheme;
this.themesObjects = ko.observableArray([]);
this.themeTrigger = ko.observable(Enums.SaveSettingsStep.Idle).extend({'throttle': 100});
this.oLastAjax = null;
this.iTimer = 0;
Data.theme.subscribe(function (sValue) {
_.each(this.themesObjects(), function (oTheme) {
oTheme.selected(sValue === oTheme.name);
});
var
oThemeLink = $('#rlThemeLink'),
oThemeStyle = $('#rlThemeStyle'),
sUrl = oThemeLink.attr('href')
;
if (!sUrl)
{
sUrl = oThemeStyle.attr('data-href');
}
if (sUrl)
{
sUrl = sUrl.toString().replace(/\/-\/[^\/]+\/\-\//, '/-/' + sValue + '/-/');
sUrl = sUrl.toString().replace(/\/Css\/[^\/]+\/User\//, '/Css/0/User/');
if ('Json/' !== sUrl.substring(sUrl.length - 5, sUrl.length))
{
sUrl += 'Json/';
}
window.clearTimeout(self.iTimer);
self.themeTrigger(Enums.SaveSettingsStep.Animate);
if (this.oLastAjax && this.oLastAjax.abort)
{
this.oLastAjax.abort();
}
this.oLastAjax = $.ajax({
'url': sUrl,
'dataType': 'json'
}).done(function(aData) {
if (aData && Utils.isArray(aData) && 2 === aData.length)
{
if (oThemeLink && oThemeLink[0] && (!oThemeStyle || !oThemeStyle[0]))
{
oThemeStyle = $('<style id="rlThemeStyle"></style>');
oThemeLink.after(oThemeStyle);
oThemeLink.remove();
}
if (oThemeStyle && oThemeStyle[0])
{
oThemeStyle.attr('data-href', sUrl).attr('data-theme', aData[0]);
if (oThemeStyle && oThemeStyle[0] && oThemeStyle[0].styleSheet && !Utils.isUnd(oThemeStyle[0].styleSheet.cssText))
{
oThemeStyle[0].styleSheet.cssText = aData[1];
}
else
{
oThemeStyle.text(aData[1]);
}
}
self.themeTrigger(Enums.SaveSettingsStep.TrueResult);
}
}).always(function() {
self.iTimer = window.setTimeout(function () {
self.themeTrigger(Enums.SaveSettingsStep.Idle);
}, 1000);
self.oLastAjax = null;
});
}
Remote.saveSettings(null, {
'Theme': sValue
});
}, this);
}
SettingsThemes.prototype.onBuild = function ()
{
var sCurrentTheme = Data.theme();
this.themesObjects(_.map(Data.themes(), function (sTheme) {
return {
'name': sTheme,
'nameDisplay': Utils.convertThemeName(sTheme),
'selected': ko.observable(sTheme === sCurrentTheme),
'themePreviewSrc': LinkBuilder.themePreviewLink(sTheme)
};
}));
};
module.exports = SettingsThemes;
}(module, require));