diff --git a/dev/Common/HtmlEditor.js b/dev/Common/HtmlEditor.js index 8558ce6d3..cc9f3b632 100644 --- a/dev/Common/HtmlEditor.js +++ b/dev/Common/HtmlEditor.js @@ -138,7 +138,17 @@ return sResult; }; - HtmlEditor.prototype.modeToggle = function (bPlain) + /** + * @param {boolean=} bWrapIsHtml = false + * @param {boolean=} bClearSignatureSigns = false + * @return {string} + */ + HtmlEditor.prototype.getDataWithHtmlMark = function (bWrapIsHtml, bClearSignatureSigns) + { + return (this.isHtml() ? ':HTML:' : '') + this.getData(bWrapIsHtml, bClearSignatureSigns); + }; + + HtmlEditor.prototype.modeToggle = function (bPlain, bResize) { if (this.editor) { @@ -159,7 +169,22 @@ } } catch(e) {} - this.resize(); + if (bResize) + { + this.resize(); + } + } + }; + + HtmlEditor.prototype.setHtmlOrPlain = function (sText, bFocus) + { + if (':HTML:' === sText.substr(0, 6)) + { + this.setHtml(sText.substr(6), bFocus); + } + else + { + this.setPlain(sText, bFocus); } }; @@ -205,7 +230,7 @@ HtmlEditor.prototype.init = function () { - if (this.$element && this.$element[0]) + if (this.$element && this.$element[0] && !this.editor) { var self = this, @@ -332,6 +357,16 @@ } }; + HtmlEditor.prototype.setReadOnly = function (bValue) + { + if (this.editor) + { + try { + this.editor.setReadOnly(!!bValue); + } catch (e) {} + } + }; + HtmlEditor.prototype.clear = function (bFocus) { this.setHtml('', bFocus); diff --git a/dev/Common/Utils.js b/dev/Common/Utils.js index f53db4e5b..2869afecb 100644 --- a/dev/Common/Utils.js +++ b/dev/Common/Utils.js @@ -548,6 +548,7 @@ */ Utils.delegateRun = function (oObject, sMethodName, aParameters, nDelay) { +// window.console.log('->' + sMethodName); // TODO if (oObject && oObject[sMethodName]) { nDelay = Utils.pInt(nDelay); diff --git a/dev/External/ko.js b/dev/External/ko.js index 637963178..2be924d5a 100644 --- a/dev/External/ko.js +++ b/dev/External/ko.js @@ -656,9 +656,9 @@ fAllBindings = fAllBindingsAccessor(), fAutoCompleteSource = fAllBindings['autoCompleteSource'] || null, fFocusCallback = function (bValue) { - if (fValue && fValue.focusTrigger) + if (fValue && fValue.focused) { - fValue.focusTrigger(bValue); + fValue.focused(!!bValue); } } ; @@ -693,14 +693,20 @@ fValue(oEvent.target.value); }, this) }); + + if (fValue && fValue.focused && fValue.focused.subscribe) + { + fValue.focused.subscribe(function (bValue) { + $oEl.inputosaurus(!!bValue ? 'focus' : 'blur'); + }); + } }, - 'update': function (oElement, fValueAccessor, fAllBindingsAccessor) { + 'update': function (oElement, fValueAccessor) { var $oEl = $(oElement), - fAllValueFunc = fAllBindingsAccessor(), - fEmailsTagsFilter = fAllValueFunc['emailsTagsFilter'] || null, - sValue = ko.unwrap(fValueAccessor()) + fValue = fValueAccessor(), + sValue = ko.unwrap(fValue) ; if ($oEl.data('EmailsTagsValue') !== sValue) @@ -709,11 +715,6 @@ $oEl.data('EmailsTagsValue', sValue); $oEl.inputosaurus('refresh'); } - - if (fEmailsTagsFilter && ko.unwrap(fEmailsTagsFilter)) - { - $oEl.inputosaurus('focus'); - } } }; diff --git a/dev/Knoin/Knoin.js b/dev/Knoin/Knoin.js index 455eb20db..69d718667 100644 --- a/dev/Knoin/Knoin.js +++ b/dev/Knoin/Knoin.js @@ -170,11 +170,20 @@ Globals.popupVisibilityNames.push(this.viewModelName); oViewModel.viewModelDom.css('z-index', 3000 + Globals.popupVisibilityNames().length + 10); - Utils.delegateRun(this, 'onFocus', [], 500); +// Utils.delegateRun(this, 'onShow'); // moved to showScreenPopup function (for parameters) + + if (this.onShowTrigger) + { + this.onShowTrigger(!this.onShowTrigger()); + } + + Utils.delegateRun(this, 'onShowWithDelay', [], 500); } else { Utils.delegateRun(this, 'onHide'); + Utils.delegateRun(this, 'onHideWithDelay', [], 500); + if (this.onHideTrigger) { this.onHideTrigger(!this.onHideTrigger()); @@ -251,11 +260,8 @@ if (ViewModelClassToShow.__vm && ViewModelClassToShow.__dom) { ViewModelClassToShow.__vm.modalVisibility(true); + Utils.delegateRun(ViewModelClassToShow.__vm, 'onShow', aParameters || []); - if (ViewModelClassToShow.__vm.onShowTrigger) - { - ViewModelClassToShow.__vm.onShowTrigger(!ViewModelClassToShow.__vm.onShowTrigger()); - } _.each(ViewModelClassToShow.__names, function (sName) { Plugins.runHook('view-model-on-show', [sName, ViewModelClassToShow.__vm, aParameters || []]); @@ -325,6 +331,7 @@ if (self.oCurrentScreen) { Utils.delegateRun(self.oCurrentScreen, 'onHide'); + Utils.delegateRun(self.oCurrentScreen, 'onHideWithDelay', [], 500); if (self.oCurrentScreen.onHideTrigger) { @@ -340,7 +347,9 @@ { ViewModelClass.__dom.hide(); ViewModelClass.__vm.viewModelVisibility(false); + Utils.delegateRun(ViewModelClass.__vm, 'onHide'); + Utils.delegateRun(ViewModelClass.__vm, 'onHideWithDelay', [], 500); if (ViewModelClass.__vm.onHideTrigger) { @@ -382,7 +391,7 @@ ViewModelClass.__vm.onShowTrigger(!ViewModelClass.__vm.onShowTrigger()); } - Utils.delegateRun(ViewModelClass.__vm, 'onFocus', [], 200); + Utils.delegateRun(ViewModelClass.__vm, 'onShowWithDelay', [], 200); _.each(ViewModelClass.__names, function (sName) { Plugins.runHook('view-model-on-show', [sName, ViewModelClass.__vm]); diff --git a/dev/Screen/AbstractSettings.js b/dev/Screen/AbstractSettings.js index ba41b0005..ba436c843 100644 --- a/dev/Screen/AbstractSettings.js +++ b/dev/Screen/AbstractSettings.js @@ -133,7 +133,7 @@ { self.oCurrentSubScreen.viewModelDom.show(); Utils.delegateRun(self.oCurrentSubScreen, 'onShow'); - Utils.delegateRun(self.oCurrentSubScreen, 'onFocus', [], 200); + Utils.delegateRun(self.oCurrentSubScreen, 'onShowWithDelay', [], 200); _.each(self.menu(), function (oItem) { oItem.selected(oSettingsScreen && oSettingsScreen.__rlSettingsData && oItem.route === oSettingsScreen.__rlSettingsData.Route); diff --git a/dev/Settings/User/Security.js b/dev/Settings/User/Security.js index 6658fde85..e8d4cf8a2 100644 --- a/dev/Settings/User/Security.js +++ b/dev/Settings/User/Security.js @@ -24,15 +24,60 @@ this.secreting = ko.observable(false); this.viewUser = ko.observable(''); - this.viewEnable = ko.observable(false); - this.viewEnable.subs = true; this.twoFactorStatus = ko.observable(false); + this.twoFactorTested = ko.observable(false); + this.viewSecret = ko.observable(''); this.viewBackupCodes = ko.observable(''); this.viewUrl = ko.observable(''); - this.bFirst = true; + this.viewEnable_ = ko.observable(false); + + this.viewEnable = ko.computed({ + 'owner': this, + 'read': this.viewEnable_, + 'write': function (bValue) { + + var self = this; + + bValue = !!bValue; + + if (bValue && this.twoFactorTested()) + { + this.viewEnable_(bValue); + + Remote.enableTwoFactor(function (sResult, oData) { + if (Enums.StorageResultType.Success !== sResult || !oData || !oData.Result) + { + self.viewEnable_(false); + } + + }, true); + } + else + { + if (!bValue) + { + this.viewEnable_(bValue); + } + + Remote.enableTwoFactor(function (sResult, oData) { + if (Enums.StorageResultType.Success !== sResult || !oData || !oData.Result) + { + self.viewEnable_(false); + } + + }, false); + } + } + }); + + this.viewTwoFactorEnableTooltip = ko.computed(function () { + Translator.trigger(); + return this.twoFactorTested() || this.viewEnable_() ? '' : + Translator.i18n('SETTINGS_SECURITY/TWO_FACTOR_SECRET_TEST_BEFORE_DESC'); + }, this); this.viewTwoFactorStatus = ko.computed(function () { Translator.trigger(); @@ -43,14 +88,18 @@ ); }, this); + this.twoFactorAllowedEnable = ko.computed(function () { + return this.viewEnable() || this.twoFactorTested(); + }, this); + this.onResult = _.bind(this.onResult, this); - this.onSecretResult = _.bind(this.onSecretResult, this); + this.onShowSecretResult = _.bind(this.onShowSecretResult, this); } SecurityUserSettings.prototype.showSecret = function () { this.secreting(true); - Remote.showTwoFactorSecret(this.onSecretResult); + Remote.showTwoFactorSecret(this.onShowSecretResult); }; SecurityUserSettings.prototype.hideSecret = function () @@ -68,7 +117,7 @@ SecurityUserSettings.prototype.testTwoFactor = function () { - require('Knoin/Knoin').showScreenPopup(require('View/Popup/TwoFactorTest')); + require('Knoin/Knoin').showScreenPopup(require('View/Popup/TwoFactorTest'), [this.twoFactorTested]); }; SecurityUserSettings.prototype.clearTwoFactor = function () @@ -77,6 +126,8 @@ this.viewBackupCodes(''); this.viewUrl(''); + this.twoFactorTested(false); + this.clearing(true); Remote.clearTwoFactor(this.onResult); }; @@ -96,8 +147,9 @@ if (Enums.StorageResultType.Success === sResult && oData && oData.Result) { this.viewUser(Utils.pString(oData.Result.User)); - this.viewEnable(!!oData.Result.Enable); + this.viewEnable_(!!oData.Result.Enable); this.twoFactorStatus(!!oData.Result.IsSet); + this.twoFactorTested(!!oData.Result.Tested); this.viewSecret(Utils.pString(oData.Result.Secret)); this.viewBackupCodes(Utils.pString(oData.Result.BackupCodes).replace(/[\s]+/g, ' ')); @@ -106,36 +158,17 @@ else { this.viewUser(''); - this.viewEnable(false); + this.viewEnable_(false); this.twoFactorStatus(false); + this.twoFactorTested(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); - } }; - SecurityUserSettings.prototype.onSecretResult = function (sResult, oData) + SecurityUserSettings.prototype.onShowSecretResult = function (sResult, oData) { this.secreting(false); diff --git a/dev/Stores/User/Notification.js b/dev/Stores/User/Notification.js index 4b10981d9..f6be376a7 100644 --- a/dev/Stores/User/Notification.js +++ b/dev/Stores/User/Notification.js @@ -23,7 +23,7 @@ this.buzz = null; - this.enableSoundNotification = ko.observable(true); + this.enableSoundNotification = ko.observable(false); this.soundNotificationIsSupported = ko.observable(false); this.allowDesktopNotification = ko.observable(false); diff --git a/dev/Styles/Animations.less b/dev/Styles/Animations.less index 353a5fa68..0136136c7 100644 --- a/dev/Styles/Animations.less +++ b/dev/Styles/Animations.less @@ -108,7 +108,8 @@ html.rl-started-trigger.no-mobile .b-login-content .loginFormWrapper { &.csstransitions .modal.fade { .transition(all 200ms ease-out); - transform: scale(0.95); + /*transform: scale(0.95);*/ + transform: translateY(-20px); &.in { transform: none; diff --git a/dev/Styles/_BootstrapFix.less b/dev/Styles/_BootstrapFix.less index 2c005356a..d902975cf 100644 --- a/dev/Styles/_BootstrapFix.less +++ b/dev/Styles/_BootstrapFix.less @@ -303,6 +303,10 @@ html.no-rgba .modal { top: 0; } +.modal-backdrop { + .g-ui-user-select-none(); +} + .modal.loginContent .modal-body, .modal.loginAdminContent .modal-body { background-color: transparent !important; } diff --git a/dev/Styles/_FontasticToBoot.less b/dev/Styles/_FontasticToBoot.less index 36cfb3c1f..9e61f787a 100644 --- a/dev/Styles/_FontasticToBoot.less +++ b/dev/Styles/_FontasticToBoot.less @@ -154,7 +154,7 @@ margin-left: -2px; } - &.white { + &.white, &.icon-white { border-color: #fff; border-top-color: #999; diff --git a/dev/View/Admin/Settings/Menu.js b/dev/View/Admin/Settings/Menu.js index a9693e246..c77975c4a 100644 --- a/dev/View/Admin/Settings/Menu.js +++ b/dev/View/Admin/Settings/Menu.js @@ -6,6 +6,7 @@ var _ = require('_'), + Enums = require('Common/Enums'), Globals = require('Common/Globals'), kn = require('Knoin/Knoin'), @@ -37,6 +38,39 @@ return '#/' + sRoute; }; + MenuSettingsAdminView.prototype.onBuild = function (oDom) + { + key('up, down', _.throttle(function (event, handler) { + + var + sH = '', + iIndex = -1, + bUp = handler && 'up' === handler.shortcut, + $items = $('.b-admin-menu .e-item', oDom) + ; + + if (event && $items.length) + { + iIndex = $items.index($items.filter('.selected')); + if (bUp && iIndex > 0) + { + iIndex--; + } + else if (!bUp && iIndex < $items.length - 1) + { + iIndex++; + } + + sH = $items.eq(iIndex).attr('href'); + if (sH) + { + kn.setHash(sH, false, true); + } + } + + }, 200)); + }; + module.exports = MenuSettingsAdminView; }()); diff --git a/dev/View/Popup/Account.js b/dev/View/Popup/Account.js index 9bf99562e..403e76d0a 100644 --- a/dev/View/Popup/Account.js +++ b/dev/View/Popup/Account.js @@ -116,7 +116,7 @@ } }; - AccountPopupView.prototype.onFocus = function () + AccountPopupView.prototype.onShowWithDelay = function () { this.emailFocus(true); }; diff --git a/dev/View/Popup/Activate.js b/dev/View/Popup/Activate.js index 5315ecce0..f164dcce8 100644 --- a/dev/View/Popup/Activate.js +++ b/dev/View/Popup/Activate.js @@ -124,7 +124,7 @@ } }; - ActivatePopupView.prototype.onFocus = function () + ActivatePopupView.prototype.onShowWithDelay = function () { if (!this.activateProcess()) { diff --git a/dev/View/Popup/AddOpenPgpKey.js b/dev/View/Popup/AddOpenPgpKey.js index 6422b7f75..a978936d3 100644 --- a/dev/View/Popup/AddOpenPgpKey.js +++ b/dev/View/Popup/AddOpenPgpKey.js @@ -100,7 +100,7 @@ this.clearPopup(); }; - AddOpenPgpKeyPopupView.prototype.onFocus = function () + AddOpenPgpKeyPopupView.prototype.onShowWithDelay = function () { this.key.focus(true); }; diff --git a/dev/View/Popup/AdvancedSearch.js b/dev/View/Popup/AdvancedSearch.js index 62d036538..ed8d00dd5 100644 --- a/dev/View/Popup/AdvancedSearch.js +++ b/dev/View/Popup/AdvancedSearch.js @@ -148,7 +148,7 @@ this.clearPopup(); }; - AdvancedSearchPopupView.prototype.onFocus = function () + AdvancedSearchPopupView.prototype.onShowWithDelay = function () { this.fromFocus(true); }; diff --git a/dev/View/Popup/Ask.js b/dev/View/Popup/Ask.js index 0f95383c6..3d1cb4754 100644 --- a/dev/View/Popup/Ask.js +++ b/dev/View/Popup/Ask.js @@ -106,7 +106,7 @@ this.bFocusYesOnShow = Utils.isUnd(bFocusYesOnShow) ? true : !!bFocusYesOnShow; }; - AskPopupView.prototype.onFocus = function () + AskPopupView.prototype.onShowWithDelay = function () { if (this.bFocusYesOnShow) { diff --git a/dev/View/Popup/Compose.js b/dev/View/Popup/Compose.js index 4d9d92c27..4d18b1701 100644 --- a/dev/View/Popup/Compose.js +++ b/dev/View/Popup/Compose.js @@ -80,6 +80,8 @@ this.bFromDraft = false; this.sReferences = ''; + this.sLastFocusedField = 'to'; + this.resizerTrigger = _.bind(this.resizerTrigger, this); this.allowContacts = !!AppStore.contactsIsAllowed(); @@ -93,10 +95,28 @@ this.identitiesDropdownTrigger = ko.observable(false); this.to = ko.observable(''); - this.to.focusTrigger = ko.observable(false); + this.to.focused = ko.observable(false); this.cc = ko.observable(''); + this.cc.focused = ko.observable(false); this.bcc = ko.observable(''); + this.bcc.focused = ko.observable(false); this.replyTo = ko.observable(''); + this.replyTo.focused = ko.observable(false); + + ko.computed(function () { + switch (true) + { + case this.to.focused(): + this.sLastFocusedField = 'to'; + break; + case this.cc.focused(): + this.sLastFocusedField = 'cc'; + break; + case this.bcc.focused(): + this.sLastFocusedField = 'bcc'; + break; + } + }, this).extend({'notify': 'always'}); this.subject = ko.observable(''); this.isHtml = ko.observable(false); @@ -411,8 +431,13 @@ { this.skipCommand(); + var self = this; + + window.console.log(this.sLastFocusedField); + _.delay(function () { - kn.showScreenPopup(require('View/Popup/Contacts'), [true]); + kn.showScreenPopup(require('View/Popup/Contacts'), + [true, self.sLastFocusedField]); }, 200); } @@ -1233,11 +1258,11 @@ this.resizerTrigger(); }; - ComposePopupView.prototype.onFocus = function () + ComposePopupView.prototype.onShowWithDelay = function () { if ('' === this.to()) { - this.to.focusTrigger(!this.to.focusTrigger()); + this.to.focused(true); } else if (this.oEditor) { diff --git a/dev/View/Popup/ComposeOpenPgp.js b/dev/View/Popup/ComposeOpenPgp.js index 220b0d10d..828c49bad 100644 --- a/dev/View/Popup/ComposeOpenPgp.js +++ b/dev/View/Popup/ComposeOpenPgp.js @@ -198,12 +198,12 @@ }, this)); }; - ComposeOpenPgpPopupView.prototype.onHide = function () + ComposeOpenPgpPopupView.prototype.onHideWithDelay = function () { this.clearPopup(); }; - ComposeOpenPgpPopupView.prototype.onFocus = function () + ComposeOpenPgpPopupView.prototype.onShowWithDelay = function () { if (this.sign()) { diff --git a/dev/View/Popup/Contacts.js b/dev/View/Popup/Contacts.js index 815cc7979..1a61b0c2c 100644 --- a/dev/View/Popup/Contacts.js +++ b/dev/View/Popup/Contacts.js @@ -50,6 +50,7 @@ ; this.bBackToCompose = false; + this.sLastComposeFocusedField = ''; this.allowContactsSync = Data.allowContactsSync; this.enableContactsSync = Data.enableContactsSync; @@ -236,7 +237,15 @@ }); this.newMessageCommand = Utils.createCommand(this, function () { - var aC = this.contactsCheckedOrSelected(), aE = []; + var + aE = [], + aC = this.contactsCheckedOrSelected(), + aToEmails = null, + aCcEmails = null, + aBccEmails = null, + aReplyToEmails = null + ; + if (Utils.isNonEmptyArray(aC)) { aE = _.map(aC, function (oItem) { @@ -265,8 +274,25 @@ kn.hideScreenPopup(require('View/Popup/Contacts')); + switch (self.sLastComposeFocusedField) + { + default: + case 'to': + aToEmails = aE; + break; + case 'cc': + aCcEmails = aE; + break; + case 'bcc': + aBccEmails = aE; + break; + } + + self.sLastComposeFocusedField = ''; + _.delay(function () { - kn.showScreenPopup(require('View/Popup/Compose'), [Enums.ComposeType.Empty, null, aE]); + kn.showScreenPopup(require('View/Popup/Compose'), + [Enums.ComposeType.Empty, null, aToEmails, aCcEmails, aBccEmails]); }, 200); } @@ -721,9 +747,10 @@ this.initUploader(); }; - ContactsPopupView.prototype.onShow = function (bBackToCompose) + ContactsPopupView.prototype.onShow = function (bBackToCompose, sLastComposeFocusedField) { this.bBackToCompose = Utils.isUnd(bBackToCompose) ? false : !!bBackToCompose; + this.sLastComposeFocusedField = Utils.isUnd(sLastComposeFocusedField) ? '' : sLastComposeFocusedField; kn.routeOff(); this.reloadContactList(true); @@ -732,6 +759,7 @@ ContactsPopupView.prototype.onHide = function () { kn.routeOn(); + this.currentContact(null); this.emptySelection(true); this.search(''); @@ -740,6 +768,8 @@ Utils.delegateRunOnDestroy(this.contacts()); this.contacts([]); + this.sLastComposeFocusedField = ''; + if (this.bBackToCompose) { this.bBackToCompose = false; diff --git a/dev/View/Popup/Domain.js b/dev/View/Popup/Domain.js index c6f1b809a..4c5d49c64 100644 --- a/dev/View/Popup/Domain.js +++ b/dev/View/Popup/Domain.js @@ -410,7 +410,7 @@ } }; - DomainPopupView.prototype.onFocus = function () + DomainPopupView.prototype.onShowWithDelay = function () { if ('' === this.name()) { diff --git a/dev/View/Popup/Filter.js b/dev/View/Popup/Filter.js index 7d03ada3a..30ef06e0f 100644 --- a/dev/View/Popup/Filter.js +++ b/dev/View/Popup/Filter.js @@ -184,7 +184,7 @@ } }; - FilterPopupView.prototype.onFocus = function () + FilterPopupView.prototype.onShowWithDelay = function () { if (this.isNew() && this.filter()) { diff --git a/dev/View/Popup/FolderCreate.js b/dev/View/Popup/FolderCreate.js index dcc637e8d..3c65a6056 100644 --- a/dev/View/Popup/FolderCreate.js +++ b/dev/View/Popup/FolderCreate.js @@ -123,7 +123,7 @@ this.clearPopup(); }; - FolderCreateView.prototype.onFocus = function () + FolderCreateView.prototype.onShowWithDelay = function () { this.folderName.focused(true); }; diff --git a/dev/View/Popup/Identity.js b/dev/View/Popup/Identity.js index a513dcb34..c15559edf 100644 --- a/dev/View/Popup/Identity.js +++ b/dev/View/Popup/Identity.js @@ -164,6 +164,31 @@ } }; + IdentityPopupView.prototype.populateSignatureFromEditor = function () + { + if (this.editor) + { + this.signature(this.editor.getDataWithHtmlMark()); + } + }; + + IdentityPopupView.prototype.editorSetSignature = function (sSignature) + { + if (!this.editor && this.signatureDom()) + { + var self = this; + this.editor = new HtmlEditor(self.signatureDom(), function () { + self.populateSignatureFromEditor(); + }, function () { + self.editor.setHtmlOrPlain(sSignature); + }); + } + else + { + this.editor.setHtmlOrPlain(sSignature); + } + }; + /** * @param {?IdentityModel} oIdentity */ @@ -189,60 +214,23 @@ { this.id = Utils.fakeMd5(); } + + this.editorSetSignature(this.signature()); }; - IdentityPopupView.prototype.onHide = function () + IdentityPopupView.prototype.onShowWithDelay = function () { - this.clearPopup(); - }; - - IdentityPopupView.prototype.setSignature = function (sSignature) - { - if (this.editor) - { - if (':HTML:' === sSignature.substr(0, 6)) - { - this.editor.setHtml(sSignature.substr(6), false); - } - else - { - this.editor.setPlain(sSignature, false); - } - } - }; - - IdentityPopupView.prototype.populateSignatureFromEditor = function () - { - if (this.editor) - { - this.signature( - (this.editor.isHtml() ? ':HTML:' : '') + this.editor.getData() - ); - } - }; - - IdentityPopupView.prototype.onFocus = function () - { - if (!this.editor && this.signatureDom()) - { - var self = this; - this.editor = new HtmlEditor(self.signatureDom(), function () { - self.populateSignatureFromEditor(); - }, function () { - self.setSignature(self.signature()); - }); - } - else - { - this.setSignature(this.signature()); - } - if (!this.owner()) { this.email.focused(true); } }; + IdentityPopupView.prototype.onHideWithDelay = function () + { + this.clearPopup(); + }; + module.exports = IdentityPopupView; }()); \ No newline at end of file diff --git a/dev/View/Popup/NewOpenPgpKey.js b/dev/View/Popup/NewOpenPgpKey.js index 8b0a221ab..83e0ac2bf 100644 --- a/dev/View/Popup/NewOpenPgpKey.js +++ b/dev/View/Popup/NewOpenPgpKey.js @@ -104,7 +104,7 @@ this.clearPopup(); }; - NewOpenPgpKeyPopupView.prototype.onFocus = function () + NewOpenPgpKeyPopupView.prototype.onShowWithDelay = function () { this.email.focus(true); }; diff --git a/dev/View/Popup/Template.js b/dev/View/Popup/Template.js index 5b745d4b0..e59f8e0bd 100644 --- a/dev/View/Popup/Template.js +++ b/dev/View/Popup/Template.js @@ -115,22 +115,8 @@ if (this.editor) { - this.setBody(''); - } - }; - - TemplatePopupView.prototype.setBody = function (sBody) - { - if (this.editor) - { - if (':HTML:' === sBody.substr(0, 6)) - { - this.editor.setHtml(sBody.substr(6), false); - } - else - { - this.editor.setPlain(sBody, false); - } + this.editor.setPlain('', false); + this.editor.setReadOnly(true); } }; @@ -138,9 +124,7 @@ { if (this.editor) { - this.body( - (this.editor.isHtml() ? ':HTML:' : '') + this.editor.getData() - ); + this.body(this.editor.getDataWithHtmlMark()); } }; @@ -152,12 +136,12 @@ this.editor = new HtmlEditor(self.signatureDom(), function () { self.populateBodyFromEditor(); }, function () { - self.setBody(sBody); + self.editor.setHtmlOrPlain(sBody); }); } else { - this.setBody(sBody); + this.editor.setHtmlOrPlain(sBody); } }; @@ -212,7 +196,7 @@ } }; - TemplatePopupView.prototype.onFocus = function () + TemplatePopupView.prototype.onShowWithDelay = function () { this.name.focus(true); }; diff --git a/dev/View/Popup/TwoFactorTest.js b/dev/View/Popup/TwoFactorTest.js index a672911f2..431dbbe42 100644 --- a/dev/View/Popup/TwoFactorTest.js +++ b/dev/View/Popup/TwoFactorTest.js @@ -30,6 +30,8 @@ this.code.focused = ko.observable(false); this.code.status = ko.observable(null); + this.koTestedTrigger = null; + this.testing = ko.observable(false); // commands @@ -41,6 +43,11 @@ self.testing(false); self.code.status(Enums.StorageResultType.Success === sResult && oData && oData.Result ? true : false); + if (self.koTestedTrigger && self.code.status()) + { + self.koTestedTrigger(true); + } + }, this.code()); }, function () { @@ -59,14 +66,18 @@ this.code.focused(false); this.code.status(null); this.testing(false); + + this.koTestedTrigger = null; }; - TwoFactorTestPopupView.prototype.onShow = function () + TwoFactorTestPopupView.prototype.onShow = function (koTestedTrigger) { this.clearPopup(); + + this.koTestedTrigger = koTestedTrigger; }; - TwoFactorTestPopupView.prototype.onFocus = function () + TwoFactorTestPopupView.prototype.onShowWithDelay = function () { this.code.focused(true); }; diff --git a/dev/View/User/MailBox/MessageList.js b/dev/View/User/MailBox/MessageList.js index 9f313f809..d3b64bb48 100644 --- a/dev/View/User/MailBox/MessageList.js +++ b/dev/View/User/MailBox/MessageList.js @@ -252,10 +252,19 @@ this.selector.scrollToTop(); }, this); + Data.messageListEndFolder.subscribe(function (sFolder) { + var oMessage = Data.message(); + if (oMessage && sFolder && sFolder !== oMessage.folderFullNameRaw) + { + Data.message(null); + } + }, this); + SettingsStore.layout.subscribe(function (mValue) { this.selector.autoSelect(Enums.Layout.NoPreview !== mValue); }, this); + SettingsStore.layout.valueHasMutated(); Events diff --git a/dev/View/User/Settings/Menu.js b/dev/View/User/Settings/Menu.js index dbcf213a3..aeac72aa7 100644 --- a/dev/View/User/Settings/Menu.js +++ b/dev/View/User/Settings/Menu.js @@ -5,7 +5,9 @@ var _ = require('_'), + key = require('key'), + Enums = require('Common/Enums'), Globals = require('Common/Globals'), Links = require('Common/Links'), @@ -35,6 +37,44 @@ kn.extendAsViewModel(['View/User/Settings/Menu', 'View/App/Settings/Menu', 'SettingsMenuViewModel'], MenuSettingsUserView); _.extend(MenuSettingsUserView.prototype, AbstractView.prototype); + MenuSettingsUserView.prototype.onBuild = function (oDom) + { +// var self = this; +// key('esc', Enums.KeyState.Settings, function () { +// self.backToMailBoxClick(); +// }); + + key('up, down', Enums.KeyState.Settings, _.throttle(function (event, handler) { + + var + sH = '', + iIndex = -1, + bUp = handler && 'up' === handler.shortcut, + $items = $('.b-settings-menu .e-item', oDom) + ; + + if (event && $items.length) + { + iIndex = $items.index($items.filter('.selected')); + if (bUp && iIndex > 0) + { + iIndex--; + } + else if (!bUp && iIndex < $items.length - 1) + { + iIndex++; + } + + sH = $items.eq(iIndex).attr('href'); + if (sH) + { + kn.setHash(sH, false, true); + } + } + + }, 200)); + }; + MenuSettingsUserView.prototype.link = function (sRoute) { return Links.settings(sRoute); diff --git a/dev/View/User/Settings/Pane.js b/dev/View/User/Settings/Pane.js index 6fd8eaf91..129710a83 100644 --- a/dev/View/User/Settings/Pane.js +++ b/dev/View/User/Settings/Pane.js @@ -5,9 +5,7 @@ var _ = require('_'), - key = require('key'), - Enums = require('Common/Enums'), Links = require('Common/Links'), Data = require('Storage/User/Data'), @@ -31,14 +29,6 @@ kn.extendAsViewModel(['View/User/Settings/Pane', 'View/App/Settings/Pane', 'SettingsPaneViewModel'], PaneSettingsUserView); _.extend(PaneSettingsUserView.prototype, AbstractView.prototype); - PaneSettingsUserView.prototype.onBuild = function () - { - var self = this; - key('esc', Enums.KeyState.Settings, function () { - self.backToMailBoxClick(); - }); - }; - PaneSettingsUserView.prototype.onShow = function () { Data.message(null); diff --git a/gulpfile.js b/gulpfile.js index 79fa17b93..e88d86ef6 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -420,6 +420,7 @@ gulp.task('ckeditor', ['ckeditor:copy-plugins'], function () { return gulp.src('rainloop/v/' + cfg.devVersion + '/static/ckeditor/*.js') .pipe(stripbom()) // .pipe(replace("\u200B", "\\u200B")) + .pipe(replace('console.log("Detecting changes using MutationObservers")', 'true')) .pipe(header("\uFEFF")) // BOM .pipe(gulp.dest('rainloop/v/' + cfg.devVersion + '/static/ckeditor')); }); diff --git a/package.json b/package.json index 613447947..e5dcbadbc 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "RainLoop", "title": "RainLoop Webmail", "version": "1.8.1", - "release": "258", + "release": "259", "description": "Simple, modern & fast web-based email client", "homepage": "http://rainloop.net", "main": "gulpfile.js", diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php index 8367cd599..abf36e70b 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php @@ -1288,6 +1288,7 @@ class Actions 'AllowAppendMessage' => (bool) $oConfig->Get('labs', 'allow_message_append', false), 'MaterialDesign' => (bool) $oConfig->Get('labs', 'use_material_design', true), 'PremType' => $this->PremType(), + 'Admin' => array(), 'Capa' => array(), 'Plugins' => array() ); @@ -6420,10 +6421,10 @@ class Actions $aData = $this->getTwoFactorInfo($oAccount); $sSecret = !empty($aData['Secret']) ? $aData['Secret'] : ''; - $this->Logger()->WriteDump(array( - $sCode, $sSecret, $aData, - $this->TwoFactorAuthProvider()->VerifyCode($sSecret, $sCode) - )); +// $this->Logger()->WriteDump(array( +// $sCode, $sSecret, $aData, +// $this->TwoFactorAuthProvider()->VerifyCode($sSecret, $sCode) +// )); \sleep(1); return $this->DefaultResponse(__FUNCTION__, diff --git a/rainloop/v/0.0.0/app/templates/Views/Admin/AdminSettingsAbout.html b/rainloop/v/0.0.0/app/templates/Views/Admin/AdminSettingsAbout.html index f7c9d8d40..cd07c251c 100644 --- a/rainloop/v/0.0.0/app/templates/Views/Admin/AdminSettingsAbout.html +++ b/rainloop/v/0.0.0/app/templates/Views/Admin/AdminSettingsAbout.html @@ -14,7 +14,12 @@

RainLoop

-

+

+ + + ( channel) + +

Simple, modern & fast web-based email client

@@ -27,9 +32,6 @@    New - - () - version is available. () diff --git a/rainloop/v/0.0.0/app/templates/Views/User/PopupsCompose.html b/rainloop/v/0.0.0/app/templates/Views/User/PopupsCompose.html index ac33f802e..60318b591 100644 --- a/rainloop/v/0.0.0/app/templates/Views/User/PopupsCompose.html +++ b/rainloop/v/0.0.0/app/templates/Views/User/PopupsCompose.html @@ -11,7 +11,7 @@    - + × @@ -106,7 +106,7 @@
- + diff --git a/rainloop/v/0.0.0/app/templates/Views/User/PopupsIdentity.html b/rainloop/v/0.0.0/app/templates/Views/User/PopupsIdentity.html index 9ea11e3dd..17e13af12 100644 --- a/rainloop/v/0.0.0/app/templates/Views/User/PopupsIdentity.html +++ b/rainloop/v/0.0.0/app/templates/Views/User/PopupsIdentity.html @@ -1,7 +1,7 @@
-