From 38672e16729e8e1331176e66cfb7946281f88343 Mon Sep 17 00:00:00 2001 From: RainLoop Team Date: Sun, 26 Jan 2014 18:23:37 +0400 Subject: [PATCH] Simple prefetch functionality (ifvisible.js) config: [labs] allow_prefetch --- .jshintrc | 1 + Gruntfile.js | 14 +- dev/Models/MessageModel.js | 6 - dev/ViewModels/AdminLoginViewModel.js | 2 +- dev/ViewModels/MailBoxMessageListViewModel.js | 46 ++ .../0.0.0/app/libraries/RainLoop/Actions.php | 1 + .../libraries/RainLoop/Config/Application.php | 1 + rainloop/v/0.0.0/static/js/admin.js | 4 +- rainloop/v/0.0.0/static/js/app.js | 58 ++- rainloop/v/0.0.0/static/js/app.min.js | 16 +- rainloop/v/0.0.0/static/js/libs.js | 3 + vendors/ifvisible/.jshintrc | 13 + vendors/ifvisible/README.md | 102 +++++ vendors/ifvisible/component.json | 5 + vendors/ifvisible/ifvisible.min.js | 2 + vendors/ifvisible/src/ifvisible.coffee | 417 ++++++++++++++++++ vendors/ifvisible/src/ifvisible.js | 315 +++++++++++++ vendors/ifvisible/src/ifvisible.map | 10 + 18 files changed, 988 insertions(+), 28 deletions(-) create mode 100644 vendors/ifvisible/.jshintrc create mode 100644 vendors/ifvisible/README.md create mode 100644 vendors/ifvisible/component.json create mode 100644 vendors/ifvisible/ifvisible.min.js create mode 100644 vendors/ifvisible/src/ifvisible.coffee create mode 100644 vendors/ifvisible/src/ifvisible.js create mode 100644 vendors/ifvisible/src/ifvisible.map diff --git a/.jshintrc b/.jshintrc index 284d79045..60ec5d465 100644 --- a/.jshintrc +++ b/.jshintrc @@ -53,6 +53,7 @@ "ko" : true, "ssm" : true, "moment" : true, + "ifvisible" : true, "crossroads" : true, "hasher" : true, "Jua" : true, diff --git a/Gruntfile.js b/Gruntfile.js index a99cbe815..e46768c59 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -45,6 +45,14 @@ module.exports = function (grunt) { src: 'vendors/jquery-cookie/jquery.cookie.js', dest: 'vendors/jquery-cookie/jquery.cookie-1.4.0.min.js' }, + ifvisible: { + options: { + banner: '/*!ifvisible.js v1.0.0 (c) 2013 Serkan Yersen | MIT */\n', + preserveComments: 'false' + }, + src: 'vendors/ifvisible/src/ifvisible.js', + dest: 'vendors/ifvisible/ifvisible.min.js' + }, wakeup: { options: { banner: '/*! jQuery WakeUp plugin (c) 2013 Paul Okopny | MIT */\n', @@ -130,6 +138,7 @@ module.exports = function (grunt) { "vendors/knockout-projections/knockout-projections-1.0.0.min.js", "vendors/ssm/ssm.min.js", "vendors/jua/jua.min.js", + "vendors/ifvisible/ifvisible.min.js", "vendors/jquery-magnific-popup/jquery.magnific-popup.min.js", "vendors/bootstrap/js/bootstrap.min.js", "dev/Common/_LibsEnd.js" @@ -217,8 +226,8 @@ module.exports = function (grunt) { options: { stripBanners: true, banner: '/*! RainLoop Webmail Main Module (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */\n' + - '(function (window, $, ko, crossroads, hasher, moment, Jua, _) {\n', - footer: '\n\n}(window, jQuery, ko, crossroads, hasher, moment, Jua, _));' + '(function (window, $, ko, crossroads, hasher, moment, Jua, _, ifvisible) {\n', + footer: '\n\n}(window, jQuery, ko, crossroads, hasher, moment, Jua, _, ifvisible));' }, src: [ "dev/Common/_Begin.js", @@ -445,6 +454,7 @@ module.exports = function (grunt) { grunt.registerTask('cookie', ['uglify:cookie']); grunt.registerTask('mousewheel', ['uglify:mousewheel']); grunt.registerTask('inputosaurus', ['uglify:inputosaurus']); + grunt.registerTask('ifvisible', ['uglify:ifvisible']); // --- grunt.registerTask('default', ['less', 'concat', 'cssmin', 'jshint', 'rlmin']); diff --git a/dev/Models/MessageModel.js b/dev/Models/MessageModel.js index 1e4f0ba92..f907875b4 100644 --- a/dev/Models/MessageModel.js +++ b/dev/Models/MessageModel.js @@ -17,8 +17,6 @@ function MessageModel() this.toEmailsString = ko.observable(''); this.senderEmailsString = ko.observable(''); - this.prefetched = false; - this.emails = []; this.from = []; @@ -228,8 +226,6 @@ MessageModel.prototype.clear = function () this.toEmailsString(''); this.senderEmailsString(''); - this.prefetched = false; - this.emails = []; this.from = []; @@ -299,8 +295,6 @@ MessageModel.prototype.initByJson = function (oJsonMessage) this.uid = oJsonMessage.Uid; this.requestHash = oJsonMessage.RequestHash; - this.prefetched = false; - this.size(Utils.pInt(oJsonMessage.Size)); this.from = MessageModel.initEmailsFromJson(oJsonMessage.From); diff --git a/dev/ViewModels/AdminLoginViewModel.js b/dev/ViewModels/AdminLoginViewModel.js index 954840669..f9e50df90 100644 --- a/dev/ViewModels/AdminLoginViewModel.js +++ b/dev/ViewModels/AdminLoginViewModel.js @@ -41,7 +41,7 @@ function AdminLoginViewModel() RL.remote().adminLogin(_.bind(function (sResult, oData) { - if (Enums.StorageResultType.Success === sResult && oData&& 'AdminLogin' === oData.Action) + if (Enums.StorageResultType.Success === sResult && oData && 'AdminLogin' === oData.Action) { if (oData.Result) { diff --git a/dev/ViewModels/MailBoxMessageListViewModel.js b/dev/ViewModels/MailBoxMessageListViewModel.js index 9b0a9f0b7..5a9cfa88d 100644 --- a/dev/ViewModels/MailBoxMessageListViewModel.js +++ b/dev/ViewModels/MailBoxMessageListViewModel.js @@ -9,6 +9,7 @@ function MailBoxMessageListViewModel() KnoinAbstractViewModel.call(this, 'Right', 'MailMessageList'); this.sLastUid = null; + this.bPrefetch = false; this.emptySubjectValue = ''; var oData = RL.data(); @@ -796,6 +797,51 @@ MailBoxMessageListViewModel.prototype.onBuild = function (oDom) }, this).extend({'notify': 'always'}); this.initUploaderForAppend(); + + if (!Globals.bMobileDevice && !!RL.settingsGet('AllowPrefetch') && ifvisible) + { + ifvisible.setIdleDuration(10); + + ifvisible.idle(function () { + self.prefetchNextTick(); + }); + } +}; + +MailBoxMessageListViewModel.prototype.prefetchNextTick = function () +{ + if (!this.bPrefetch && !ifvisible.now() && this.viewModelVisibility()) + { + var + self = this, + oCache = RL.cache(), + oMessage = _.find(this.messageList(), function (oMessage) { + return oMessage && + !oCache.hasRequestedMessage(oMessage.folderFullNameRaw, oMessage.uid); + }) + ; + + if (oMessage) + { + this.bPrefetch = true; + + RL.cache().addRequestedMessage(oMessage.folderFullNameRaw, oMessage.uid); + + RL.remote().message(function (sResult, oData) { + + var bNext = !!(Enums.StorageResultType.Success === sResult && oData && oData.Result); + + _.delay(function () { + self.bPrefetch = false; + if (bNext) + { + self.prefetchNextTick(); + } + }, 1000); + + }, oMessage.folderFullNameRaw, oMessage.uid); + } + } }; MailBoxMessageListViewModel.prototype.composeClick = function () 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 b35c6a24e..56155768a 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php @@ -909,6 +909,7 @@ class Actions 'AllowAdditionalAccounts' => (bool) $oConfig->Get('webmail', 'allow_additional_accounts', true), 'AllowIdentities' => (bool) $oConfig->Get('webmail', 'allow_identities', true), 'DetermineUserLanguage' => (bool) $oConfig->Get('labs', 'determine_user_language', false), + 'AllowPrefetch' => (bool) $oConfig->Get('labs', 'allow_prefetch', true), 'AllowCustomLogin' => (bool) $oConfig->Get('login', 'allow_custom_login', false), 'LoginDefaultDomain' => $oConfig->Get('login', 'default_domain', ''), 'AllowThemes' => (bool) $oConfig->Get('webmail', 'allow_themes', true), diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Config/Application.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Config/Application.php index 2c6b2721d..aa12d660c 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Config/Application.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Config/Application.php @@ -229,6 +229,7 @@ Enables caching in the system'), 'imap_forwarded_flag' => array('$Forwarded'), 'imap_read_receipt_flag' => array('$ReadReceipt'), 'smtp_show_server_errors' => array(false), + 'allow_prefetch' => array(true), 'autocreate_system_folders' => array(true), 'repo_type' => array('stable'), 'custom_repo' => array(''), diff --git a/rainloop/v/0.0.0/static/js/admin.js b/rainloop/v/0.0.0/static/js/admin.js index 0fa1035b5..a84bc51f6 100644 --- a/rainloop/v/0.0.0/static/js/admin.js +++ b/rainloop/v/0.0.0/static/js/admin.js @@ -1153,7 +1153,7 @@ Utils.log = function (sDesc) /** * @param {number} iCode - * @param {ыекштп=} mMessage = '' + * @param {*=} mMessage = '' * @return {string} */ Utils.getNotification = function (iCode, mMessage) @@ -5139,7 +5139,7 @@ function AdminLoginViewModel() RL.remote().adminLogin(_.bind(function (sResult, oData) { - if (Enums.StorageResultType.Success === sResult && oData&& 'AdminLogin' === oData.Action) + if (Enums.StorageResultType.Success === sResult && oData && 'AdminLogin' === oData.Action) { if (oData.Result) { diff --git a/rainloop/v/0.0.0/static/js/app.js b/rainloop/v/0.0.0/static/js/app.js index e2b52dbc0..f9789ad81 100644 --- a/rainloop/v/0.0.0/static/js/app.js +++ b/rainloop/v/0.0.0/static/js/app.js @@ -1,5 +1,5 @@ /*! RainLoop Webmail Main Module (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ -(function (window, $, ko, crossroads, hasher, moment, Jua, _) { +(function (window, $, ko, crossroads, hasher, moment, Jua, _, ifvisible) { 'use strict'; @@ -1153,7 +1153,7 @@ Utils.log = function (sDesc) /** * @param {number} iCode - * @param {ыекштп=} mMessage = '' + * @param {*=} mMessage = '' * @return {string} */ Utils.getNotification = function (iCode, mMessage) @@ -6328,8 +6328,6 @@ function MessageModel() this.toEmailsString = ko.observable(''); this.senderEmailsString = ko.observable(''); - this.prefetched = false; - this.emails = []; this.from = []; @@ -6539,8 +6537,6 @@ MessageModel.prototype.clear = function () this.toEmailsString(''); this.senderEmailsString(''); - this.prefetched = false; - this.emails = []; this.from = []; @@ -6610,8 +6606,6 @@ MessageModel.prototype.initByJson = function (oJsonMessage) this.uid = oJsonMessage.Uid; this.requestHash = oJsonMessage.RequestHash; - this.prefetched = false; - this.size(Utils.pInt(oJsonMessage.Size)); this.from = MessageModel.initEmailsFromJson(oJsonMessage.From); @@ -11220,6 +11214,7 @@ function MailBoxMessageListViewModel() KnoinAbstractViewModel.call(this, 'Right', 'MailMessageList'); this.sLastUid = null; + this.bPrefetch = false; this.emptySubjectValue = ''; var oData = RL.data(); @@ -12007,6 +12002,51 @@ MailBoxMessageListViewModel.prototype.onBuild = function (oDom) }, this).extend({'notify': 'always'}); this.initUploaderForAppend(); + + if (!Globals.bMobileDevice && !!RL.settingsGet('AllowPrefetch') && ifvisible) + { + ifvisible.setIdleDuration(10); + + ifvisible.idle(function () { + self.prefetchNextTick(); + }); + } +}; + +MailBoxMessageListViewModel.prototype.prefetchNextTick = function () +{ + if (!this.bPrefetch && !ifvisible.now() && this.viewModelVisibility()) + { + var + self = this, + oCache = RL.cache(), + oMessage = _.find(this.messageList(), function (oMessage) { + return oMessage && + !oCache.hasRequestedMessage(oMessage.folderFullNameRaw, oMessage.uid); + }) + ; + + if (oMessage) + { + this.bPrefetch = true; + + RL.cache().addRequestedMessage(oMessage.folderFullNameRaw, oMessage.uid); + + RL.remote().message(function (sResult, oData) { + + var bNext = !!(Enums.StorageResultType.Success === sResult && oData && oData.Result); + + _.delay(function () { + self.bPrefetch = false; + if (bNext) + { + self.prefetchNextTick(); + } + }, 1000); + + }, oMessage.folderFullNameRaw, oMessage.uid); + } + } }; MailBoxMessageListViewModel.prototype.composeClick = function () @@ -17509,4 +17549,4 @@ if (window.SimplePace) { window.SimplePace.add(10); } -}(window, jQuery, ko, crossroads, hasher, moment, Jua, _)); \ No newline at end of file +}(window, jQuery, ko, crossroads, hasher, moment, Jua, _, ifvisible)); \ No newline at end of file diff --git a/rainloop/v/0.0.0/static/js/app.min.js b/rainloop/v/0.0.0/static/js/app.min.js index 2f7242104..f2904e9f6 100644 --- a/rainloop/v/0.0.0/static/js/app.min.js +++ b/rainloop/v/0.0.0/static/js/app.min.js @@ -1,9 +1,9 @@ /*! RainLoop Webmail Main Module (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ -!function(a,b,c,d,e,f,g,h){"use strict";function i(){this.sBase="#/",this.sCdnStaticDomain=Cb.settingsGet("CdnStaticDomain"),this.sVersion=Cb.settingsGet("Version"),this.sSpecSuffix=Cb.settingsGet("AuthAccountHash")||"0",this.sServer=(Cb.settingsGet("IndexFile")||"./")+"?",this.sCdnStaticDomain=""===this.sCdnStaticDomain?this.sCdnStaticDomain:"/"===this.sCdnStaticDomain.substr(-1)?this.sCdnStaticDomain:this.sCdnStaticDomain+"/"}function j(a,c,d,e){var f={DisableHtml:!1,onSwitch:!1,LangSwitcherConferm:"EDITOR_TEXT_SWITCHER_CONFIRM",LangSwitcherTextLabel:"EDITOR_SWITCHER_TEXT_LABEL",LangSwitcherHtmlLabel:"EDITOR_SWITCHER_HTML_LABEL"};this.bIe=!!/msie/.test(navigator.userAgent.toLowerCase()),e=b.extend(f,qb.isUnd(e)?{}:e),this.oOptions=e,this.bOnlyPlain=!!this.oOptions.DisableHtml,this.fOnSwitch=this.oOptions.onSwitch,this.textarea=b(a).empty().addClass("editorTextArea"),this.htmlarea=b(c).empty().addClass("editorHtmlArea").prop("contentEditable","true"),this.toolbar=b(d).empty().addClass("editorToolbar"),j.htmlInitEditor.apply(this),j.htmlInitToolbar.apply(this),j.htmlAttachEditorEvents.apply(this),this.bOnlyPlain&&this.toolbar.hide()}function k(a,b,c,d,e){this.list=a,this.selectedItem=b,this.selectedItem.extend({toggleSubscribe:[null,function(a){a&&a.selected(!1)},function(a){a&&a.selected(!0)}]}),this.oContentVisible=null,this.oContentScrollable=null,this.sItemSelector=c,this.sItemSelectedSelector=d,this.sItemCheckedSelector=e,this.sLastUid="",this.oCallbacks={},this.iSelectTimer=0,this.bUseKeyboard=!0,this.emptyFunction=function(){},this.useItemSelectCallback=!0,this.throttleSelection=!1,this.selectedItem.subscribe(function(a){this.useItemSelectCallback&&(this.throttleSelection?(this.throttleSelection=!1,this.selectItemCallbacksThrottle(a)):this.selectItemCallbacks(a))},this);var f=this,g=[],i=null;this.list.subscribe(function(){var a=this,b=this.list();qb.isArray(b)&&h.each(b,function(b){b.checked()&&g.push(a.getItemUid(b)),null===i&&b.selected()&&(i=a.getItemUid(b))})},this,"beforeChange"),this.list.subscribe(function(a){if(this.useItemSelectCallback=!1,this.selectedItem(null),qb.isArray(a)){var b=this,c=g.length;h.each(a,function(a){c>0&&-1b?b:a))},this),this.body=null,this.isRtl=c.observable(!1),this.isHtml=c.observable(!1),this.hasImages=c.observable(!1),this.attachments=c.observableArray([]),this.priority=c.observable(ob.MessagePriority.Normal),this.readReceipt=c.observable(""),this.aDraftInfo=[],this.sMessageId="",this.sInReplyTo="",this.sReferences="",this.parentUid=c.observable(0),this.threads=c.observableArray([]),this.threadsLen=c.observable(0),this.hasUnseenSubMessage=c.observable(!1),this.hasFlaggedSubMessage=c.observable(!1),this.lastInCollapsedThread=c.observable(!1),this.lastInCollapsedThreadLoading=c.observable(!1),this.threadsLenResult=c.computed(function(){var a=this.threadsLen();return 0===this.parentUid()&&a>0?a+1:""},this)}function y(){this.name=c.observable(""),this.fullName="",this.fullNameRaw="",this.fullNameHash="",this.delimiter="",this.namespace="",this.deep=0,this.selectable=!1,this.existen=!0,this.isNamespaceFolder=!1,this.isGmailFolder=!1,this.isUnpaddigFolder=!1,this.interval=0,this.type=c.observable(ob.FolderType.User),this.selected=c.observable(!1),this.edited=c.observable(!1),this.collapsed=c.observable(!0),this.subScribed=c.observable(!0),this.subFolders=c.observableArray([]),this.deleteAccess=c.observable(!1),this.actionBlink=c.observable(!1).extend({falseTimeout:1e3}),this.nameForEdit=c.observable(""),this.name.subscribe(function(a){this.nameForEdit(a)},this),this.edited.subscribe(function(a){a&&this.nameForEdit(this.name())},this),this.privateMessageCountAll=c.observable(0),this.privateMessageCountUnread=c.observable(0),this.collapsedPrivate=c.observable(!0)}function z(a,b){this.email=a,this.deleteAccess=c.observable(!1),this.canBeDalete=c.observable(b)}function A(a,b,d){this.id=a,this.email=c.observable(b),this.name=c.observable(""),this.replyTo=c.observable(""),this.bcc=c.observable(""),this.deleteAccess=c.observable(!1),this.canBeDalete=c.observable(d)}function B(){p.call(this,"Popups","PopupsFolderClear"),this.selectedFolder=c.observable(null),this.clearingProcess=c.observable(!1),this.clearingError=c.observable(""),this.folderFullNameForClear=c.computed(function(){var a=this.selectedFolder();return a?a.printableFullName():""},this),this.folderNameForClear=c.computed(function(){var a=this.selectedFolder();return a?a.localName():""},this),this.dangerDescHtml=c.computed(function(){return qb.i18n("POPUPS_CLEAR_FOLDER/DANGER_DESC_HTML_1",{FOLDER:this.folderNameForClear()})},this),this.clearCommand=qb.createCommand(this,function(){var a=this,b=this.selectedFolder();b&&(Cb.data().message(null),Cb.data().messageList([]),this.clearingProcess(!0),Cb.cache().setFolderHash(b.fullNameRaw,""),Cb.remote().folderClear(function(b,c){a.clearingProcess(!1),ob.StorageResultType.Success===b&&c&&c.Result?(Cb.reloadMessageList(!0),a.cancelCommand()):c&&c.ErrorCode?a.clearingError(qb.getNotification(c.ErrorCode)):a.clearingError(qb.getNotification(ob.Notification.MailServerError))},b.fullNameRaw))},function(){var a=this.selectedFolder(),b=this.clearingProcess();return!b&&null!==a}),r.constructorEnd(this)}function C(){p.call(this,"Popups","PopupsFolderCreate"),qb.initOnStartOrLangChange(function(){this.sNoParentText=qb.i18n("POPUPS_CREATE_FOLDER/SELECT_NO_PARENT")},this),this.folderName=c.observable(""),this.folderName.focused=c.observable(!1),this.selectedParentValue=c.observable(nb.Values.UnuseOptionValue),this.parentFolderSelectList=c.computed(function(){var a=Cb.data(),b=[],c=null,d=null,e=a.folderList(),f=function(a){return a?a.isSystemFolder()?a.name()+" "+a.manageFolderSystemName():a.name():""};return b.push(["",this.sNoParentText]),""!==a.namespace&&(c=function(b){return a.namespace!==b.fullNameRaw.substr(0,a.namespace.length)}),Cb.folderListOptionsBuilder([],e,[],b,null,c,d,f)},this),this.createFolder=qb.createCommand(this,function(){var a=Cb.data(),b=this.selectedParentValue();""===b&&1=a?1:a},this),this.contactsPagenator=c.computed(qb.computedPagenatorHelper(this.contactsPage,this.contactsPageCount)),this.emptySelection=c.observable(!0),this.viewClearSearch=c.observable(!1),this.viewID=c.observable(""),this.viewIDStr=c.observable(""),this.viewReadOnly=c.observable(!1),this.viewScopeType=c.observable(ob.ContactScopeType.Default),this.viewProperties=c.observableArray([]),this.viewSaveTrigger=c.observable(ob.SaveSettingsStep.Idle),this.viewPropertiesNames=this.viewProperties.filter(function(a){return-10&&b>0&&a>b},this),this.hasMessages=c.computed(function(){return 0'),e.after(f),e.remove()),f&&f[0]&&f.attr("data-href",g).attr("data-theme",a[0]).text(a[1]),d.themeTrigger(ob.SaveSettingsStep.TrueResult))}).always(function(){d.iTimer=a.setTimeout(function(){d.themeTrigger(ob.SaveSettingsStep.Idle)},1e3),d.oLastAjax=null})),Cb.remote().saveSettings(null,{Theme:c})},this)}function bb(){qb.initDataConstructorBySettings(this)}function cb(){bb.call(this);var a=function(a){return function(){var b=Cb.cache().getFolderFromCacheList(a());b&&b.type(ob.FolderType.User)}},d=function(a){return function(b){var c=Cb.cache().getFolderFromCacheList(b);c&&c.type(a)}};this.devEmail="",this.devLogin="",this.devPassword="",this.accountEmail=c.observable(""),this.accountIncLogin=c.observable(""),this.accountOutLogin=c.observable(""),this.projectHash=c.observable(""),this.threading=c.observable(!1),this.lastFoldersHash="",this.remoteSuggestions=!1,this.sentFolder=c.observable(""),this.draftFolder=c.observable(""),this.spamFolder=c.observable(""),this.trashFolder=c.observable(""),this.sentFolder.subscribe(a(this.sentFolder),this,"beforeChange"),this.draftFolder.subscribe(a(this.draftFolder),this,"beforeChange"),this.spamFolder.subscribe(a(this.spamFolder),this,"beforeChange"),this.trashFolder.subscribe(a(this.trashFolder),this,"beforeChange"),this.sentFolder.subscribe(d(ob.FolderType.SentItems),this),this.draftFolder.subscribe(d(ob.FolderType.Draft),this),this.spamFolder.subscribe(d(ob.FolderType.Spam),this),this.trashFolder.subscribe(d(ob.FolderType.Trash),this),this.draftFolderNotEnabled=c.computed(function(){return""===this.draftFolder()||nb.Values.UnuseOptionValue===this.draftFolder()},this),this.displayName=c.observable(""),this.signature=c.observable(""),this.signatureToAll=c.observable(!1),this.replyTo=c.observable(""),this.accounts=c.observableArray([]),this.accountsLoading=c.observable(!1).extend({throttle:100}),this.identities=c.observableArray([]),this.identitiesLoading=c.observable(!1).extend({throttle:100}),this.namespace="",this.folderList=c.observableArray([]),this.foldersListError=c.observable(""),this.foldersLoading=c.observable(!1),this.foldersCreating=c.observable(!1),this.foldersDeleting=c.observable(!1),this.foldersRenaming=c.observable(!1),this.foldersInboxUnreadCount=c.observable(0),this.currentFolder=c.observable(null).extend({toggleSubscribe:[null,function(a){a&&a.selected(!1)},function(a){a&&a.selected(!0)}]}),this.currentFolderFullNameRaw=c.computed(function(){return this.currentFolder()?this.currentFolder().fullNameRaw:""},this),this.currentFolderFullName=c.computed(function(){return this.currentFolder()?this.currentFolder().fullName:""},this),this.currentFolderFullNameHash=c.computed(function(){return this.currentFolder()?this.currentFolder().fullNameHash:""},this),this.currentFolderName=c.computed(function(){return this.currentFolder()?this.currentFolder().name():""},this),this.folderListSystemNames=c.computed(function(){var a=["INBOX"],b=this.folderList(),c=this.sentFolder(),d=this.draftFolder(),e=this.spamFolder(),f=this.trashFolder();return qb.isArray(b)&&0=a?1:a},this),this.mainMessageListSearch=c.computed({read:this.messageListSearch,write:function(a){vb.setHash(Cb.link().mailBox(this.currentFolderFullNameHash(),1,qb.trim(a.toString())))},owner:this}),this.messageListError=c.observable(""),this.messageListLoading=c.observable(!1),this.messageListIsNotCompleted=c.observable(!1),this.messageListCompleteLoadingThrottle=c.observable(!1).extend({throttle:200}),this.messageListCompleteLoading=c.computed(function(){var a=this.messageListLoading(),b=this.messageListIsNotCompleted();return a||b},this),this.messageListCompleteLoading.subscribe(function(a){this.messageListCompleteLoadingThrottle(a)},this),this.messageList.subscribe(h.debounce(function(a){h.each(a,function(a){a.newForAnimation()&&a.newForAnimation(!1)})},500)),this.staticMessageList=new x,this.message=c.observable(null),this.messageLoading=c.observable(!1),this.messageLoadingThrottle=c.observable(!1).extend({throttle:50}),this.messageLoading.subscribe(function(a){this.messageLoadingThrottle(a)},this),this.messageFullScreenMode=c.observable(!1),this.messageError=c.observable(""),this.messagesBodiesDom=c.observable(null),this.messagesBodiesDom.subscribe(function(a){!a||a instanceof jQuery||this.messagesBodiesDom(b(a))},this),this.messageActiveDom=c.observable(null),this.isMessageSelected=c.computed(function(){return null!==this.message()},this),this.currentMessage=c.observable(null),this.message.subscribe(function(a){null===a&&(this.currentMessage(null),this.hideMessageBodies())},this),this.messageListChecked=c.computed(function(){return h.filter(this.messageList(),function(a){return a.checked()})},this),this.messageListCheckedOrSelected=c.computed(function(){var a=this.messageListChecked(),b=this.currentMessage();return h.union(a,b?[b]:[])},this),this.messageListCheckedUids=c.computed(function(){var a=[];return h.each(this.messageListChecked(),function(b){b&&(a.push(b.uid),00?Math.ceil(b/a*100):0},this),this.useKeyboardShortcuts=c.observable(!0),this.googleActions=c.observable(!1),this.googleLoggined=c.observable(!1),this.googleUserName=c.observable(""),this.facebookActions=c.observable(!1),this.facebookLoggined=c.observable(!1),this.facebookUserName=c.observable(""),this.twitterActions=c.observable(!1),this.twitterLoggined=c.observable(!1),this.twitterUserName=c.observable(""),this.customThemeType=c.observable(ob.CustomThemeType.Light),this.purgeMessageBodyCacheThrottle=h.throttle(this.purgeMessageBodyCache,3e4)}function db(){this.oRequests={}}function eb(){db.call(this),this.oRequests={}}function fb(){this.oEmailsPicsHashes={},this.oServices={}}function gb(){fb.call(this),this.oFoldersCache={},this.oFoldersNamesCache={},this.oFolderHashCache={},this.oFolderUidNextCache={},this.oMessageListHashCache={},this.oMessageFlagsCache={},this.oNewMessage={},this.oRequestedMessage={}}function hb(a){q.call(this,"settings",a),this.menu=c.observableArray([]),this.oCurrentSubScreen=null,this.oViewModelPlace=null}function ib(){q.call(this,"login",[L])}function jb(){q.call(this,"mailbox",[N,P,Q,R]),this.oLastRoute={}}function kb(){hb.call(this,[O,S,T]),qb.initOnStartOrLangChange(function(){this.sSettingsTitle=qb.i18n("TITLES/SETTINGS")},this,function(){Cb.setTitle(this.sSettingsTitle)})}function lb(){o.call(this),this.oSettings=null,this.oPlugins=null,this.oLocal=null,this.oLink=null,this.oSubs={},this.isLocalAutocomplete=!0,this.popupVisibility=c.observable(!1),this.iframe=b('