From 7db7d5545b6cff96aa925c9c368b3be72f5bd242 Mon Sep 17 00:00:00 2001 From: djmaze Date: Tue, 27 Oct 2020 11:09:24 +0100 Subject: [PATCH] Improved observables --- dev/App/User.js | 4 +- dev/External/User/ko.js | 11 --- dev/External/ko.js | 4 +- dev/Model/FolderCollection.js | 2 +- dev/Settings/Admin/Contacts.js | 38 ++++++----- dev/Settings/Admin/General.js | 13 ++-- dev/Settings/Admin/Login.js | 11 +-- dev/Settings/Admin/Security.js | 44 ++++++------ dev/Settings/User/Filters.js | 20 +++--- dev/Settings/User/Folders.js | 4 +- dev/Settings/User/General.js | 8 ++- dev/Stores/Admin/Capa.js | 24 ++++--- dev/Stores/Admin/License.js | 15 ---- dev/Stores/Admin/Package.js | 6 +- dev/Stores/Language.js | 6 +- dev/Stores/User/Account.js | 9 +-- dev/Stores/User/App.js | 26 +++---- dev/Stores/User/Contact.js | 12 ++-- dev/Stores/User/Filter.js | 9 +-- dev/Stores/User/Folder.js | 33 +++++---- dev/Stores/User/Message.js | 61 +++++++++-------- dev/Stores/User/Settings.js | 14 ++-- dev/View/Popup/Identity.js | 68 ++++++++++--------- dev/View/User/AbstractSystemDropDown.js | 8 +-- dev/View/User/MailBox/MessageView.js | 2 +- .../Views/Admin/AdminSettingsSecurity.html | 2 +- .../templates/Views/User/PopupsIdentity.html | 6 +- .../templates/Views/User/SettingsFolders.html | 10 +-- 28 files changed, 236 insertions(+), 234 deletions(-) delete mode 100644 dev/Stores/Admin/License.js diff --git a/dev/App/User.js b/dev/App/User.js index f968c5289..f3f83a8f4 100644 --- a/dev/App/User.js +++ b/dev/App/User.js @@ -399,7 +399,7 @@ class AppUser extends AbstractApp { Remote.foldersReloadWithTimeout(FolderStore.foldersLoading); }, (errorCode) => { - FolderStore.folderList.error(getNotification(errorCode, '', errorDefCode)); + FolderStore.folderListError(getNotification(errorCode, '', errorDefCode)); Remote.foldersReloadWithTimeout(FolderStore.foldersLoading); } ); @@ -757,7 +757,7 @@ class AppUser extends AbstractApp { } this.reloadFlagsCurrentMessageListAndMessageFromCache(); - MessageStore.message.viewTrigger(!MessageStore.message.viewTrigger()); + MessageStore.messageViewTrigger(!MessageStore.messageViewTrigger()); } } diff --git a/dev/External/User/ko.js b/dev/External/User/ko.js index f5120a84b..6b7de9e31 100644 --- a/dev/External/User/ko.js +++ b/dev/External/User/ko.js @@ -287,15 +287,4 @@ ko.extenders.specialThrottle = (target, timeout) => { return target; }; -// functions - -ko.observable.fn.validateEmail = function() { - this.hasError = ko.observable(false); - - this.subscribe(value => this.hasError(value && !/^[^@\s]+@[^@\s]+$/.test(value))); - - this.valueHasMutated(); - return this; -}; - export default ko; diff --git a/dev/External/ko.js b/dev/External/ko.js index 530a0983c..c9ef56a8f 100644 --- a/dev/External/ko.js +++ b/dev/External/ko.js @@ -36,7 +36,6 @@ ko.bindingHandlers.tooltip = { ko.bindingHandlers.tooltipErrorTip = { init: element => { doc.addEventListener('click', () => element.removeAttribute('data-rainloopErrorTip')); - ko.utils.domNodeDisposal.addDisposeCallback(element, () => element.removeAttribute('data-rainloopErrorTip')); }, update: (element, fValueAccessor) => { const value = koValue(fValueAccessor()); @@ -258,8 +257,7 @@ ko.extenders.falseTimeout = (target, option) => { // functions ko.observable.fn.deleteAccessHelper = function() { - this.extend({ falseTimeout: 3000 }).extend({ toggleSubscribeProperty: [this, 'deleteAccess'] }); - return this; + return this.extend({ falseTimeout: 3000, toggleSubscribeProperty: [this, 'deleteAccess'] }); }; ko.addObservablesTo = (target, observables) => { diff --git a/dev/Model/FolderCollection.js b/dev/Model/FolderCollection.js index a72a8990a..59ef540ab 100644 --- a/dev/Model/FolderCollection.js +++ b/dev/Model/FolderCollection.js @@ -102,7 +102,7 @@ export class FolderCollectionModel extends AbstractCollectionModel AppStore.threadsAllowed(!!(Settings.app('useImapThread') && this.IsThreadsSupported)); - FolderStore.folderList.optimized(!!this.Optimized); + FolderStore.folderListOptimized(!!this.Optimized); let update = false; diff --git a/dev/Settings/Admin/Contacts.js b/dev/Settings/Admin/Contacts.js index f45e03251..de5f3adca 100644 --- a/dev/Settings/Admin/Contacts.js +++ b/dev/Settings/Admin/Contacts.js @@ -11,8 +11,26 @@ const settingsGet = rl.settings.get; class ContactsAdminSettings { constructor() { this.defaultOptionsAfterRender = defaultOptionsAfterRender; - this.enableContacts = ko.observable(!!settingsGet('ContactsEnable')); - this.contactsSync = ko.observable(!!settingsGet('ContactsSync')); + + ko.addObservablesTo(this, { + enableContacts: !!settingsGet('ContactsEnable'), + contactsSync: !!settingsGet('ContactsSync'), + contactsType: '', + + pdoDsn: settingsGet('ContactsPdoDsn'), + pdoUser: settingsGet('ContactsPdoUser'), + pdoPassword: settingsGet('ContactsPdoPassword'), + + pdoDsnTrigger: SaveSettingsStep.Idle, + pdoUserTrigger: SaveSettingsStep.Idle, + pdoPasswordTrigger: SaveSettingsStep.Idle, + contactsTypeTrigger: SaveSettingsStep.Idle, + + testing: false, + testContactsSuccess: false, + testContactsError: false, + testContactsErrorMessage: '' + }); const supportedTypes = settingsGet('supportedPdoDrivers') || [], types = [{ @@ -30,8 +48,6 @@ class ContactsAdminSettings { this.contactsTypesOptions = types; - this.contactsType = ko.observable(''); - this.mainContactsType = ko .computed({ read: this.contactsType, @@ -55,20 +71,6 @@ class ContactsAdminSettings { this.testContactsErrorMessage(''); }); - this.pdoDsn = ko.observable(settingsGet('ContactsPdoDsn')); - this.pdoUser = ko.observable(settingsGet('ContactsPdoUser')); - this.pdoPassword = ko.observable(settingsGet('ContactsPdoPassword')); - - this.pdoDsnTrigger = ko.observable(SaveSettingsStep.Idle); - this.pdoUserTrigger = ko.observable(SaveSettingsStep.Idle); - this.pdoPasswordTrigger = ko.observable(SaveSettingsStep.Idle); - this.contactsTypeTrigger = ko.observable(SaveSettingsStep.Idle); - - this.testing = ko.observable(false); - this.testContactsSuccess = ko.observable(false); - this.testContactsError = ko.observable(false); - this.testContactsErrorMessage = ko.observable(''); - this.contactsType(settingsGet('ContactsPdoType')); this.onTestContactsResponse = this.onTestContactsResponse.bind(this); diff --git a/dev/Settings/Admin/General.js b/dev/Settings/Admin/General.js index b6ce46ddb..4684fac65 100644 --- a/dev/Settings/Admin/General.js +++ b/dev/Settings/Admin/General.js @@ -39,9 +39,15 @@ class GeneralAdminSettings { this.capaAttachmentThumbnails = CapaAdminStore.attachmentThumbnails; this.capaTemplates = CapaAdminStore.templates; - this.allowLanguagesOnSettings = ko.observable(!!settingsGet('AllowLanguagesOnSettings')); + ko.addObservablesTo(this, { + allowLanguagesOnSettings: !!settingsGet('AllowLanguagesOnSettings'), + newMoveToFolder: !!settingsGet('NewMoveToFolder'), + attachmentLimitTrigger: SaveSettingsStep.Idle, + languageTrigger: SaveSettingsStep.Idle, + themeTrigger: SaveSettingsStep.Idle + }); + this.weakPassword = AppAdminStore.weakPassword; - this.newMoveToFolder = ko.observable(!!settingsGet('NewMoveToFolder')); this.dataFolderAccess = AppAdminStore.dataFolderAccess; @@ -67,10 +73,7 @@ class GeneralAdminSettings { this.languageFullName = ko.computed(() => convertLangName(this.language())); this.languageAdminFullName = ko.computed(() => convertLangName(this.languageAdmin())); - this.attachmentLimitTrigger = ko.observable(SaveSettingsStep.Idle); - this.languageTrigger = ko.observable(SaveSettingsStep.Idle); this.languageAdminTrigger = ko.observable(SaveSettingsStep.Idle).extend({ throttle: 100 }); - this.themeTrigger = ko.observable(SaveSettingsStep.Idle); } onBuild() { diff --git a/dev/Settings/Admin/Login.js b/dev/Settings/Admin/Login.js index d64eeb8d5..17b60a81c 100644 --- a/dev/Settings/Admin/Login.js +++ b/dev/Settings/Admin/Login.js @@ -7,13 +7,14 @@ import Remote from 'Remote/Admin/Fetch'; class LoginAdminSettings { constructor() { const settingsGet = rl.settings.get; - this.determineUserLanguage = ko.observable(!!settingsGet('DetermineUserLanguage')); - this.determineUserDomain = ko.observable(!!settingsGet('DetermineUserDomain')); + ko.addObservablesTo(this, { + determineUserLanguage: !!settingsGet('DetermineUserLanguage'), + determineUserDomain: !!settingsGet('DetermineUserDomain'), + allowLanguagesOnLogin: !!settingsGet('AllowLanguagesOnLogin'), + dummy: false + }); this.defaultDomain = ko.observable(settingsGet('LoginDefaultDomain')).idleTrigger(); - this.allowLanguagesOnLogin = ko.observable(!!settingsGet('AllowLanguagesOnLogin')); - - this.dummy = ko.observable(false); } onBuild() { diff --git a/dev/Settings/Admin/Security.js b/dev/Settings/Admin/Security.js index f6cafb82c..17e1e582c 100644 --- a/dev/Settings/Admin/Security.js +++ b/dev/Settings/Admin/Security.js @@ -13,8 +13,6 @@ const settingsGet = rl.settings.get; class SecurityAdminSettings { constructor() { - this.useLocalProxyForExternalImages = ko.observable(!!rl.settings.get('UseLocalProxyForExternalImages')); - this.weakPassword = AppAdminStore.weakPassword; this.capaOpenPGP = CapaAdminStore.openPGP; @@ -22,35 +20,39 @@ class SecurityAdminSettings { this.capaTwoFactorAuth = CapaAdminStore.twoFactorAuth; this.capaTwoFactorAuthForce = CapaAdminStore.twoFactorAuthForce; + ko.addObservablesTo(this, { + useLocalProxyForExternalImages: !!rl.settings.get('UseLocalProxyForExternalImages'), + + verifySslCertificate: !!settingsGet('VerifySslCertificate'), + allowSelfSigned: !!settingsGet('AllowSelfSigned'), + + isTwoFactorDropperShown: false, + twoFactorDropperUser: '', + twoFactorDropperUserFocused: false, + + adminLogin: settingsGet('AdminLogin'), + adminLoginError: false, + adminPassword: '', + adminPasswordNew: '', + adminPasswordNew2: '', + adminPasswordNewError: false, + + adminPasswordUpdateError: false, + adminPasswordUpdateSuccess: false + }); + this.capaTwoFactorAuth.subscribe(value => { if (!value) { this.capaTwoFactorAuthForce(false); } }); - this.verifySslCertificate = ko.observable(!!settingsGet('VerifySslCertificate')); - this.allowSelfSigned = ko.observable(!!settingsGet('AllowSelfSigned')); - this.verifySslCertificate.subscribe(value => { if (!value) { this.allowSelfSigned(true); } }); - this.isTwoFactorDropperShown = ko.observable(false); - this.twoFactorDropperUser = ko.observable(''); - this.twoFactorDropperUser.focused = ko.observable(false); - - this.adminLogin = ko.observable(settingsGet('AdminLogin')); - this.adminLoginError = ko.observable(false); - this.adminPassword = ko.observable(''); - this.adminPasswordNew = ko.observable(''); - this.adminPasswordNew2 = ko.observable(''); - this.adminPasswordNewError = ko.observable(false); - - this.adminPasswordUpdateError = ko.observable(false); - this.adminPasswordUpdateSuccess = ko.observable(false); - this.adminPassword.subscribe(() => { this.adminPasswordUpdateError(false); this.adminPasswordUpdateSuccess(false); @@ -104,7 +106,7 @@ class SecurityAdminSettings { this.isTwoFactorDropperShown(true); setTimeout(() => { - this.twoFactorDropperUser.focused(true); + this.twoFactorDropperUserFocused(true); }, 50); } @@ -167,7 +169,7 @@ class SecurityAdminSettings { this.isTwoFactorDropperShown(false); this.twoFactorDropperUser(''); - this.twoFactorDropperUser.focused(false); + this.twoFactorDropperUserFocused(false); } } diff --git a/dev/Settings/User/Filters.js b/dev/Settings/User/Filters.js index 3f17b37ee..9d5cd444a 100644 --- a/dev/Settings/User/Filters.js +++ b/dev/Settings/User/Filters.js @@ -16,12 +16,14 @@ class FiltersUserSettings { this.modules = FilterStore.modules; this.filters = FilterStore.filters; - this.inited = ko.observable(false); - this.serverError = ko.observable(false); - this.serverErrorDesc = ko.observable(''); - this.haveChanges = ko.observable(false); + ko.addObservablesTo(this, { + inited: false, + serverError: false, + serverErrorDesc: '', + haveChanges: false, - this.saveErrorText = ko.observable(''); + saveErrorText: '' + }); this.serverError.subscribe((value) => { if (!value) { @@ -37,18 +39,14 @@ class FiltersUserSettings { this.filterForDeletion = ko.observable(null).deleteAccessHelper(); - this.filters.subscribe(() => { - this.haveChanges(true); - }); + this.filters.subscribe(() => this.haveChanges(true)); this.filterRaw.subscribe(() => { this.haveChanges(true); this.filterRaw.error(false); }); - this.haveChanges.subscribe(() => { - this.saveErrorText(''); - }); + this.haveChanges.subscribe(() => this.saveErrorText('')); this.filterRaw.active.subscribe(() => { this.haveChanges(true); diff --git a/dev/Settings/User/Folders.js b/dev/Settings/User/Folders.js index fb48e6ea3..1024403da 100644 --- a/dev/Settings/User/Folders.js +++ b/dev/Settings/User/Folders.js @@ -62,7 +62,7 @@ class FoldersUserSettings { } onShow() { - FolderStore.folderList.error(''); + FolderStore.folderListError(''); } onBuild(oDom) { @@ -113,7 +113,7 @@ class FoldersUserSettings { removeFolderFromCacheList(folderToRemove.fullNameRaw); } } else if (0 < folderToRemove.privateMessageCountAll()) { - FolderStore.folderList.error(getNotification(Notification.CantDeleteNonEmptyFolder)); + FolderStore.folderListError(getNotification(Notification.CantDeleteNonEmptyFolder)); } } diff --git a/dev/Settings/User/General.js b/dev/Settings/User/General.js index 87812a849..ddb13db3c 100644 --- a/dev/Settings/User/General.js +++ b/dev/Settings/User/General.js @@ -47,9 +47,11 @@ class GeneralUserSettings { this.languageFullName = ko.computed(() => convertLangName(this.language())); this.languageTrigger = ko.observable(SaveSettingsStep.Idle).extend({ throttle: 100 }); - this.mppTrigger = ko.observable(SaveSettingsStep.Idle); - this.editorDefaultTypeTrigger = ko.observable(SaveSettingsStep.Idle); - this.layoutTrigger = ko.observable(SaveSettingsStep.Idle); + ko.addObservablesTo(this, { + mppTrigger: SaveSettingsStep.Idle, + editorDefaultTypeTrigger: SaveSettingsStep.Idle, + layoutTrigger: SaveSettingsStep.Idle + }); this.identities = IdentityStore.identities; diff --git a/dev/Stores/Admin/Capa.js b/dev/Stores/Admin/Capa.js index 7202daec4..ce4f4edfb 100644 --- a/dev/Stores/Admin/Capa.js +++ b/dev/Stores/Admin/Capa.js @@ -3,17 +3,19 @@ import { Capa } from 'Common/Enums'; class CapaAdminStore { constructor() { - this.additionalAccounts = ko.observable(false); - this.identities = ko.observable(false); - this.attachmentThumbnails = ko.observable(false); - this.sieve = ko.observable(false); - this.filters = ko.observable(false); - this.themes = ko.observable(true); - this.userBackground = ko.observable(false); - this.openPGP = ko.observable(false); - this.twoFactorAuth = ko.observable(false); - this.twoFactorAuthForce = ko.observable(false); - this.templates = ko.observable(false); + ko.addObservablesTo(this, { + additionalAccounts: false, + identities: false, + attachmentThumbnails: false, + sieve: false, + filters: false, + themes: true, + userBackground: false, + openPGP: false, + twoFactorAuth: false, + twoFactorAuthForce: false, + templates: false + }); } populate() { diff --git a/dev/Stores/Admin/License.js b/dev/Stores/Admin/License.js deleted file mode 100644 index d86abde2d..000000000 --- a/dev/Stores/Admin/License.js +++ /dev/null @@ -1,15 +0,0 @@ -import ko from 'ko'; - -class LicenseAdminStore { - constructor() { - this.licensing = ko.observable(false); - this.licensingProcess = ko.observable(false); - this.licenseValid = ko.observable(false); - this.licenseExpired = ko.observable(0); - this.licenseError = ko.observable(''); - - this.licenseTrigger = ko.observable(false); - } -} - -export default new LicenseAdminStore(); diff --git a/dev/Stores/Admin/Package.js b/dev/Stores/Admin/Package.js index e7b888128..43ec82348 100644 --- a/dev/Stores/Admin/Package.js +++ b/dev/Stores/Admin/Package.js @@ -5,8 +5,10 @@ class PackageAdminStore { this.packages = ko.observableArray([]); this.packages.loading = ko.observable(false).extend({ throttle: 100 }); - this.packagesReal = ko.observable(true); - this.packagesMainUpdatable = ko.observable(true); + ko.addObservablesTo(this, { + packagesReal: true, + packagesMainUpdatable: true + }); } } diff --git a/dev/Stores/Language.js b/dev/Stores/Language.js index eedd46da3..1da16c77b 100644 --- a/dev/Stores/Language.js +++ b/dev/Stores/Language.js @@ -7,13 +7,11 @@ class LanguageStore { this.language = ko .observable('') - .extend({ limitedList: this.languages }) - .extend({ reversible: true }); + .extend({ limitedList: this.languages, reversible: true }); this.languageAdmin = ko .observable('') - .extend({ limitedList: this.languagesAdmin }) - .extend({ reversible: true }); + .extend({ limitedList: this.languagesAdmin, reversible: true }); this.userLanguage = ko.observable(''); this.userLanguageAdmin = ko.observable(''); diff --git a/dev/Stores/User/Account.js b/dev/Stores/User/Account.js index 7d362cd9e..4e0c1ca18 100644 --- a/dev/Stores/User/Account.js +++ b/dev/Stores/User/Account.js @@ -2,10 +2,11 @@ import ko from 'ko'; class AccountUserStore { constructor() { - this.email = ko.observable(''); - this.parentEmail = ko.observable(''); - - this.signature = ko.observable(''); + ko.addObservablesTo(this, { + email: '', + parentEmail: '', + signature: '' + }); this.accounts = ko.observableArray([]); this.accounts.loading = ko.observable(false).extend({ throttle: 100 }); diff --git a/dev/Stores/User/App.js b/dev/Stores/User/App.js index defb30cf3..3504be412 100644 --- a/dev/Stores/User/App.js +++ b/dev/Stores/User/App.js @@ -7,9 +7,21 @@ const Settings = rl.settings; class AppUserStore { constructor() { - this.currentAudio = ko.observable(''); + ko.addObservablesTo(this, { + currentAudio: '', - this.focusedState = ko.observable(Focused.None); + focusedState: Focused.None, + + projectHash: '', + threadsAllowed: false, + + composeInEdit: false, + + contactsAutosave: false, + useLocalProxyForExternalImages: false, + + contactsIsAllowed: false + }); const isMobile = Settings.app('mobile'); @@ -38,16 +50,6 @@ class AppUserStore { } }); - this.projectHash = ko.observable(''); - this.threadsAllowed = ko.observable(false); - - this.composeInEdit = ko.observable(false); - - this.contactsAutosave = ko.observable(false); - this.useLocalProxyForExternalImages = ko.observable(false); - - this.contactsIsAllowed = ko.observable(false); - this.attachmentsActions = ko.observableArray([]); this.devEmail = ''; diff --git a/dev/Stores/User/Contact.js b/dev/Stores/User/Contact.js index 93fefcba8..aaa5cead8 100644 --- a/dev/Stores/User/Contact.js +++ b/dev/Stores/User/Contact.js @@ -9,11 +9,13 @@ class ContactUserStore { this.contacts.exportingVcf = ko.observable(false).extend({ throttle: 200 }); this.contacts.exportingCsv = ko.observable(false).extend({ throttle: 200 }); - this.allowContactsSync = ko.observable(false); - this.enableContactsSync = ko.observable(false); - this.contactsSyncUrl = ko.observable(''); - this.contactsSyncUser = ko.observable(''); - this.contactsSyncPass = ko.observable(''); + ko.addObservablesTo(this, { + allowContactsSync: false, + enableContactsSync: false, + contactsSyncUrl: '', + contactsSyncUser: '', + contactsSyncPass: '' + }); } populate() { diff --git a/dev/Stores/User/Filter.js b/dev/Stores/User/Filter.js index b228f439e..a3a01ed22 100644 --- a/dev/Stores/User/Filter.js +++ b/dev/Stores/User/Filter.js @@ -2,15 +2,16 @@ import ko from 'ko'; class FilterUserStore { constructor() { - this.capa = ko.observable(''); - this.modules = ko.observable({}); + ko.addObservablesTo(this, { + capa: '', + modules: {}, + raw: '' + }); this.filters = ko.observableArray([]); this.filters.loading = ko.observable(false).extend({ throttle: 200 }); this.filters.saving = ko.observable(false).extend({ throttle: 200 }); - - this.raw = ko.observable(''); } } diff --git a/dev/Stores/User/Folder.js b/dev/Stores/User/Folder.js index d6485fa66..6c55e7945 100644 --- a/dev/Stores/User/Folder.js +++ b/dev/Stores/User/Folder.js @@ -7,26 +7,29 @@ import { getFolderInboxName, getFolderFromCacheList } from 'Common/Cache'; class FolderUserStore { constructor() { - this.displaySpecSetting = ko.observable(true); + ko.addObservablesTo(this, { + displaySpecSetting: true, - this.sentFolder = ko.observable(''); - this.draftFolder = ko.observable(''); - this.spamFolder = ko.observable(''); - this.trashFolder = ko.observable(''); - this.archiveFolder = ko.observable(''); + sentFolder: '', + draftFolder: '', + spamFolder: '', + trashFolder: '', + archiveFolder: '', + + folderListOptimized: false, + folderListError: '', + + foldersLoading: false, + foldersCreating: false, + foldersDeleting: false, + foldersRenaming: false, + + foldersInboxUnreadCount: 0 + }); this.namespace = ''; this.folderList = ko.observableArray([]); - this.folderList.optimized = ko.observable(false); - this.folderList.error = ko.observable(''); - - this.foldersLoading = ko.observable(false); - this.foldersCreating = ko.observable(false); - this.foldersDeleting = ko.observable(false); - this.foldersRenaming = ko.observable(false); - - this.foldersInboxUnreadCount = ko.observable(0); this.currentFolder = ko.observable(null).extend({ toggleSubscribeProperty: [this, 'selected'] }); diff --git a/dev/Stores/User/Message.js b/dev/Stores/User/Message.js index 93a32287d..407afcced 100644 --- a/dev/Stores/User/Message.js +++ b/dev/Stores/User/Message.js @@ -59,44 +59,47 @@ class MessageUserStore { this.messageList = ko.observableArray([]).extend({ rateLimit: 0 }); - this.messageListCount = ko.observable(0); - this.messageListSearch = ko.observable(''); - this.messageListThreadUid = ko.observable(''); - this.messageListPage = ko.observable(1); - this.messageListPageBeforeThread = ko.observable(1); - this.messageListError = ko.observable(''); + ko.addObservablesTo(this, { + messageListCount: 0, + messageListSearch: '', + messageListThreadUid: '', + messageListPage: 1, + messageListPageBeforeThread: 1, + messageListError: '', - this.messageListEndFolder = ko.observable(''); - this.messageListEndSearch = ko.observable(''); - this.messageListEndThreadUid = ko.observable(''); - this.messageListEndPage = ko.observable(1); + messageListEndFolder: '', + messageListEndSearch: '', + messageListEndThreadUid: '', + messageListEndPage: 1, + + messageListLoading: false, + messageListIsNotCompleted: false, + + selectorMessageSelected: null, + selectorMessageFocused: null, + + // message viewer + message: null, + + messageViewTrigger: false, + + messageError: '', + + messageCurrentLoading: false, + + messageFullScreenMode: false, + + messagesBodiesDom: null, + messageActiveDom: null + }); - this.messageListLoading = ko.observable(false); - this.messageListIsNotCompleted = ko.observable(false); this.messageListCompleteLoadingThrottle = ko.observable(false).extend({ throttle: 200 }); this.messageListCompleteLoadingThrottleForAnimation = ko.observable(false).extend({ specialThrottle: 700 }); this.messageListDisableAutoSelect = ko.observable(false).extend({ falseTimeout: 500 }); - this.selectorMessageSelected = ko.observable(null); - this.selectorMessageFocused = ko.observable(null); - - // message viewer - this.message = ko.observable(null); - - this.message.viewTrigger = ko.observable(false); - - this.messageError = ko.observable(''); - - this.messageCurrentLoading = ko.observable(false); - this.messageLoadingThrottle = ko.observable(false).extend({ throttle: 50 }); - this.messageFullScreenMode = ko.observable(false); - - this.messagesBodiesDom = ko.observable(null); - this.messageActiveDom = ko.observable(null); - this.messageLoading = ko.computed(() => this.messageCurrentLoading()); this.messageListEndHash = ko.computed( diff --git a/dev/Stores/User/Settings.js b/dev/Stores/User/Settings.js index cc583ef6a..869364a3b 100644 --- a/dev/Stores/User/Settings.js +++ b/dev/Stores/User/Settings.js @@ -23,13 +23,15 @@ class SettingsUserStore { this.messagesPerPage = ko.observable(20).extend({ limitedList: MESSAGES_PER_PAGE_VALUES }); - this.showImages = ko.observable(false); - this.useCheckboxesInList = ko.observable(true); - this.allowDraftAutosave = ko.observable(true); - this.useThreads = ko.observable(false); - this.replySameFolder = ko.observable(false); + ko.addObservablesTo(this, { + showImages: false, + useCheckboxesInList: true, + allowDraftAutosave: true, + useThreads: false, + replySameFolder: false, - this.autoLogout = ko.observable(30); + autoLogout: 30 + }); this.usePreviewPane = ko.computed(() => Layout.NoPreview !== this.layout()); diff --git a/dev/View/Popup/Identity.js b/dev/View/Popup/Identity.js index 822377abc..34d7b0efd 100644 --- a/dev/View/Popup/Identity.js +++ b/dev/View/Popup/Identity.js @@ -1,5 +1,3 @@ -import ko from 'ko'; - import { StorageResultType, Notification } from 'Common/Enums'; import { getNotification } from 'Common/Translator'; @@ -8,14 +6,7 @@ import Remote from 'Remote/User/Fetch'; import { popup, command } from 'Knoin/Knoin'; import { AbstractViewNext } from 'Knoin/AbstractViewNext'; -ko.observable.fn.validateEmail = function() { - this.hasError = ko.observable(false); - - this.subscribe(value => this.hasError(value && !/^[^@\s]+@[^@\s]+$/.test(value))); - - this.valueHasMutated(); - return this; -}; +const reEmail = /^[^@\s]+@[^@\s]+$/; @popup({ name: 'View/Popup/Identity', @@ -29,10 +20,20 @@ class IdentityPopupView extends AbstractViewNext { this.addObservables({ edit: false, owner: false, + + email: '', emailFocused: false, + emailHasError: false, + name: '', + + replyTo: '', replyToFocused: false, + replyToHasError: false, + + bcc: '', bccFocused: false, + bccHasError: false, signature: '', signatureInsertBefore: false, @@ -44,21 +45,26 @@ class IdentityPopupView extends AbstractViewNext { submitError: '' }); - this.email = ko.observable('').validateEmail(); - this.replyTo = ko.observable('').validateEmail(); - this.bcc = ko.observable('').validateEmail(); - - this.bcc.subscribe((value) => { - if (false === this.showBcc() && value.length) { - this.showBcc(true); - } - }); - - this.replyTo.subscribe((value) => { - if (false === this.showReplyTo() && value.length) { - this.showReplyTo(true); + this.addSubscribables({ + email: value => this.emailHasError(value && !reEmail.test(value)), + replyTo: value => { + this.replyToHasError(value && !reEmail.test(value)); + if (false === this.showReplyTo() && value.length) { + this.showReplyTo(true); + } + }, + bcc: value => { + this.bccHasError(value && !reEmail.test(value)); + if (false === this.showBcc() && value.length) { + this.showBcc(true); + } } }); +/* + this.email.valueHasMutated(); + this.replyTo.valueHasMutated(); + this.bcc.valueHasMutated(); +*/ } @command((self) => !self.submitRequest()) @@ -67,11 +73,11 @@ class IdentityPopupView extends AbstractViewNext { this.signature.__fetchEditorValue(); } - if (!this.email.hasError()) { - this.email.hasError(!this.email().trim()); + if (!this.emailHasError()) { + this.emailHasError(!this.email().trim()); } - if (this.email.hasError()) { + if (this.emailHasError()) { if (!this.owner()) { this.emailFocused(true); } @@ -79,12 +85,12 @@ class IdentityPopupView extends AbstractViewNext { return false; } - if (this.replyTo.hasError()) { + if (this.replyToHasError()) { this.replyToFocused(true); return false; } - if (this.bcc.hasError()) { + if (this.bccHasError()) { this.bccFocused(true); return false; } @@ -129,9 +135,9 @@ class IdentityPopupView extends AbstractViewNext { this.signature(''); this.signatureInsertBefore(false); - this.email.hasError(false); - this.replyTo.hasError(false); - this.bcc.hasError(false); + this.emailHasError(false); + this.replyToHasError(false); + this.bccHasError(false); this.showBcc(false); this.showReplyTo(false); diff --git a/dev/View/User/AbstractSystemDropDown.js b/dev/View/User/AbstractSystemDropDown.js index 1d92a7eda..23583820a 100644 --- a/dev/View/User/AbstractSystemDropDown.js +++ b/dev/View/User/AbstractSystemDropDown.js @@ -1,5 +1,3 @@ -import ko from 'ko'; - import AppStore from 'Stores/User/App'; import AccountStore from 'Stores/User/Account'; import MessageStore from 'Stores/User/Message'; @@ -32,8 +30,10 @@ class AbstractSystemDropDownUserView extends AbstractViewNext { this.accounts = AccountStore.accounts; this.accountsUnreadCount = AccountStore.accountsUnreadCount; - this.accountMenuDropdownTrigger = ko.observable(false); - this.capaAdditionalAccounts = ko.observable(Settings.capa(Capa.AdditionalAccounts)); + this.addObservables({ + accountMenuDropdownTrigger: false, + capaAdditionalAccounts: Settings.capa(Capa.AdditionalAccounts) + }); this.addAccountClick = this.addAccountClick.bind(this); diff --git a/dev/View/User/MailBox/MessageView.js b/dev/View/User/MailBox/MessageView.js index 3a23b8327..a3c9bbefe 100644 --- a/dev/View/User/MailBox/MessageView.js +++ b/dev/View/User/MailBox/MessageView.js @@ -264,7 +264,7 @@ class MessageViewMailBoxUserView extends AbstractViewNext { fullScreenMode: value => $htmlCL.toggle('rl-message-fullscreen', value) }); - this.message.viewTrigger.subscribe(() => { + MessageStore.messageViewTrigger.subscribe(() => { const message = this.message(); message ? this.viewIsFlagged(message.isFlagged()) : this.viewIsFlagged(false); }); diff --git a/snappymail/v/0.0.0/app/templates/Views/Admin/AdminSettingsSecurity.html b/snappymail/v/0.0.0/app/templates/Views/Admin/AdminSettingsSecurity.html index 0f10aaa67..47c21d4e7 100644 --- a/snappymail/v/0.0.0/app/templates/Views/Admin/AdminSettingsSecurity.html +++ b/snappymail/v/0.0.0/app/templates/Views/Admin/AdminSettingsSecurity.html @@ -30,7 +30,7 @@
+ data-bind="textInput: twoFactorDropperUser, hasfocus: twoFactorDropperUserFocused" placeholder="Email"/>

-
+
-
+
-
+
-
+

-
- - +
+ +
@@ -42,4 +42,4 @@ - \ No newline at end of file +