%PDF- %PDF-
Direktori : /www/varak.net/mail2.varak.net_old/static/js/ |
Current File : //www/varak.net/mail2.varak.net_old/static/js/app.js |
/*! * Copyright 2004-2014, AfterLogic Corp. * Licensed under AGPLv3 license or AfterLogic license * if commerical version of the product was purchased. * See the LICENSE file for a full license statement. */ (function ($, window, ko, crossroads, hasher) { 'use strict'; var /** * @type {Object} */ Consts = {}, /** * @type {Object} */ Enums = {}, /** * @type {Object.<Function>} */ Utils = {}, /** * @type {Object} */ I18n = window.pSevenI18N || {}, /** * @type {CApp|Object} */ App = {}, /** * @type {Object.<Function>} */ AfterLogicApi = {}, /** * @type {AjaxAppDataResponse|Object} */ AppData = window.pSevenAppData || {}, /** * @type {boolean} */ bExtApp = false, /** * @type {boolean} */ bMobileApp = false, $html = $('html'), /** * @type {boolean} */ bIsIosDevice = -1 < navigator.userAgent.indexOf('iPhone') || -1 < navigator.userAgent.indexOf('iPod') || -1 < navigator.userAgent.indexOf('iPad'), /** * @type {boolean} */ bIsAndroidDevice = -1 < navigator.userAgent.toLowerCase().indexOf('android'), /** * @type {boolean} */ bMobileDevice = bIsIosDevice || bIsAndroidDevice, aViewMimeTypes = [ 'image/jpeg', 'image/png', 'image/gif', 'text/html', 'text/plain', 'text/css', 'text/rfc822-headers', 'message/delivery-status', 'application/x-httpd-php', 'application/javascript', 'application/pdf' ] ; if (window.Modernizr && navigator) { // v = 15; window.Modernizr.addTest('pdf', function() { var aMimes = navigator.mimeTypes, iIndex = 0, iLen = aMimes.length; for (; iIndex < iLen; iIndex++) { if ('application/pdf' === aMimes[iIndex].type) { return true; } } return false; }); } if (!Date.now) { Date.now = function () { return (new Date()).getTime(); }; } /** * @constructor */ function CBrowser() { this.ie11 = !!navigator.userAgent.match(/Trident.*rv[ :]*11\./); this.ie = (/msie/.test(navigator.userAgent.toLowerCase()) && !window.opera) || this.ie11; this.ieVersion = this.getIeVersion(); this.ie8AndBelow = this.ie && this.ieVersion <= 8; this.ie9AndBelow = this.ie && this.ieVersion <= 9; this.ie10AndAbove = this.ie && this.ieVersion >= 10; this.opera = !!window.opera || /opr/.test(navigator.userAgent.toLowerCase()); this.firefox = /firefox/.test(navigator.userAgent.toLowerCase()); this.chrome = /chrome/.test(navigator.userAgent.toLowerCase()) && !/opr/.test(navigator.userAgent.toLowerCase()); this.chromeIos = /crios/.test(navigator.userAgent.toLowerCase()); this.safari = /safari/.test(navigator.userAgent.toLowerCase()) && !this.chromeIos; } CBrowser.prototype.getIeVersion = function () { var sUa = navigator.userAgent.toLowerCase(), iVersion = Utils.pInt(sUa.slice(sUa.indexOf('msie') + 4, sUa.indexOf(';', sUa.indexOf('msie') + 4))) ; if (this.ie11) { iVersion = 11; } return iVersion; }; /** * @constructor */ function CAjax() { this.sUrl = '?/Ajax/'; this.requests = ko.observableArray([]); // not "computed", because "reguests" is frequently updated this.openedRequestsCount = ko.observable(0); this.requests.subscribe(function () { this.openedRequestsCount(this.requests().length); }, this); } /** * @param {string=} sAction = '' * @returns {Boolean} */ CAjax.prototype.hasOpenedRequests = function (sAction) { sAction = Utils.isUnd(sAction) ? '' : sAction; this.requests(_.filter(this.requests(), function (oReq) { var bComplete = oReq && oReq.Xhr.readyState === 4, bAbort = !oReq || oReq.Xhr.readyState === 0 && oReq.Xhr.statusText === 'abort', bSameAction = (sAction === '') || oReq && (oReq.Parameters.Action === sAction) ; return oReq && !bComplete && !bAbort && bSameAction; })); return this.requests().length > 0; }; /** * @return {boolean} */ CAjax.prototype.isSearchMessages = function () { var bSearchMessages = false; _.each(this.requests(), function (oReq) { if (oReq && oReq.Parameters && oReq.Parameters.Action === 'MessageList' && oReq.Parameters.Search !== '') { bSearchMessages = true; } }, this); return bSearchMessages; }; /** * @param {string} sAction */ CAjax.prototype.isAllowedActionWithoutAuth = function (sAction) { var aActionsWithoutAuth = ['Login', 'LoginLanguageUpdate', 'Logout', 'AccountCreate', 'SetMobile', 'RegisterAccount', 'GetForgotAccountQuestion', 'ValidateForgotAccountQuestion', 'ChangeForgotAccountPassword']; return _.indexOf(aActionsWithoutAuth, sAction) !== -1; }; CAjax.prototype.isAllowedExtAction = function (sAction) { return sAction === 'SocialRegister' || sAction === 'HelpdeskRegister' || sAction === 'HelpdeskForgot' || sAction === 'HelpdeskLogin' || sAction === 'Logout'; }; /** * @param {Object} oParameters * @param {Function=} fResponseHandler * @param {Object=} oContext * @param {Function=} fDone */ CAjax.prototype.doSend = function (oParameters, fResponseHandler, oContext, fDone) { var doneFunc = _.bind((fDone || null), this, oParameters, fResponseHandler, oContext), failFunc = _.bind(this.fail, this, oParameters, fResponseHandler, oContext), alwaysFunc = _.bind(this.always, this, oParameters), oXhr = null ; if (AfterLogicApi.runPluginHook) { AfterLogicApi.runPluginHook('ajax-default-request', [oParameters.Action, oParameters]); } if (AppData.Token) { oParameters.Token = AppData.Token; } this.abortRequests(oParameters); Utils.log('Ajax request send', oParameters.Action, oParameters); oXhr = $.ajax({ url: this.sUrl, type: 'POST', async: true, dataType: 'json', data: oParameters, success: doneFunc, error: failFunc, complete: alwaysFunc }); this.requests().push({Parameters: oParameters, Xhr: oXhr}); }; /** * @param {Object} oParameters * @param {Function=} fResponseHandler * @param {Object=} oContext */ CAjax.prototype.send = function (oParameters, fResponseHandler, oContext) { var bCurrentAccountId = oParameters.AccountID === undefined, bAccountExists = bCurrentAccountId || AppData.Accounts.hasAccountWithId(oParameters.AccountID) ; if (oParameters && (AppData.Auth && bAccountExists || this.isAllowedActionWithoutAuth(oParameters.Action))) { if (bCurrentAccountId && oParameters.Action !== 'Login') { oParameters.AccountID = AppData.Accounts.currentId(); } this.doSend(oParameters, fResponseHandler, oContext, this.done); } }; /** * @param {Object} oParameters * @param {Function=} fResponseHandler * @param {Object=} oContext */ CAjax.prototype.sendExt = function (oParameters, fResponseHandler, oContext) { var aActionsWithoutAuth = [ 'SocialRegister', 'HelpdeskRegister', 'HelpdeskForgot', 'HelpdeskLogin', 'HelpdeskForgotChangePassword', 'Logout', 'CalendarList', 'EventList', 'FilesPub' ], bAllowWithoutAuth = _.indexOf(aActionsWithoutAuth, oParameters.Action) !== -1 ; if (oParameters && (AppData.Auth || bAllowWithoutAuth)) { if (AppData.TenantHash) { oParameters.TenantHash = AppData.TenantHash; } this.doSend(oParameters, fResponseHandler, oContext, this.doneExt); } }; /** * @param {Object} oParameters */ CAjax.prototype.abortRequests = function (oParameters) { switch (oParameters.Action) { case 'MessageMove': case 'MessageDelete': this.abortRequestByActionName('MessageList', {'Folder': oParameters.Folder}); this.abortRequestByActionName('Message'); break; case 'MessageList': case 'MessageSetSeen': this.abortRequestByActionName('MessageList', {'Folder': oParameters.Folder}); break; case 'MessageSetAllSeen': this.abortRequestByActionName('MessageList', {'Folder': oParameters.Folder}); this.abortRequestByActionName('MessageListByUids', {'Folder': oParameters.Folder}); break; case 'FolderClear': this.abortRequestByActionName('MessageList', {'Folder': oParameters.Folder}); // FolderCounts-request aborted during folder cleaning, not to get the wrong information. this.abortRequestByActionName('FolderCounts'); break; case 'ContactList': case 'GlobalContactList': this.abortRequestByActionName('ContactList'); this.abortRequestByActionName('GlobalContactList'); break; case 'Contact': case 'GlobalContact': this.abortRequestByActionName('Contact'); this.abortRequestByActionName('GlobalContact'); break; case 'EventUpdate': this.abortRequestByActionName('EventUpdate', {'calendarId': oParameters.calendarId, 'uid': oParameters.uid}); break; } }; /** * @param {string} sAction * @param {Object=} oParameters */ CAjax.prototype.abortRequestByActionName = function (sAction, oParameters) { var bDoAbort; _.each(this.requests(), function (oReq, iIndex) { bDoAbort = false; if (oReq && oReq.Parameters.Action === sAction) { switch (sAction) { case 'MessageList': if (oParameters.Folder === oReq.Parameters.Folder) { bDoAbort = true; } break; case 'EventUpdate': if (oParameters.calendarId === oReq.Parameters.calendarId && oParameters.uid === oReq.Parameters.uid) { bDoAbort = true; } break; default: bDoAbort = true; break; } } if (bDoAbort) { oReq.Xhr.abort(); this.requests()[iIndex] = undefined; } }, this); this.requests(_.compact(this.requests())); }; CAjax.prototype.abortAllRequests = function () { _.each(this.requests(), function (oReq) { if (oReq) { oReq.Xhr.abort(); } }, this); this.requests([]); }; /** * @param {Object} oParameters * @param {Function} fResponseHandler * @param {Object} oContext * @param {{Result:boolean}} oData * @param {string} sType * @param {Object} oXhr */ CAjax.prototype.done = function (oParameters, fResponseHandler, oContext, oData, sType, oXhr) { var bAllowedActionWithoutAuth = this.isAllowedActionWithoutAuth(oParameters.Action), bAccountExists = AppData.Accounts.hasAccountWithId(oParameters.AccountID), bDefaultAccount = (oParameters.AccountID === AppData.Accounts.defaultId()) ; Utils.log('Ajax request done', oParameters.Action, sType, Utils.getAjaxDataForLog(oParameters.Action, oData), oParameters); if (bAllowedActionWithoutAuth || bAccountExists) { if (oData && !oData.Result) { switch (oData.ErrorCode) { case Enums.Errors.InvalidToken: if (!bAllowedActionWithoutAuth) { App.tokenProblem(); } break; case Enums.Errors.AuthError: if (bDefaultAccount && !bAllowedActionWithoutAuth) { this.abortAllRequests(); App.authProblem(); } break; } } this.executeResponseHandler(fResponseHandler, oContext, oData, oParameters); } }; /** * @param {Object} oParameters * @param {Function} fResponseHandler * @param {Object} oContext * @param {{Result:boolean}} oData * @param {string} sType * @param {Object} oXhr */ CAjax.prototype.doneExt = function (oParameters, fResponseHandler, oContext, oData, sType, oXhr) { this.executeResponseHandler(fResponseHandler, oContext, oData, oParameters); }; /** * @param {Object} oParameters * @param {Function} fResponseHandler * @param {Object} oContext * @param {Object} oXhr * @param {string} sType * @param {string} sErrorText */ CAjax.prototype.fail = function (oParameters, fResponseHandler, oContext, oXhr, sType, sErrorText) { var oData = {'Result': false, 'ErrorCode': 0}; Utils.log('Ajax request fail', oParameters.Action, sType, oParameters); switch (sType) { case 'abort': oData = {'Result': false, 'ErrorCode': Enums.Errors.NotDisplayedError}; break; default: case 'error': case 'parseerror': if (sErrorText === '') { oData = {'Result': false, 'ErrorCode': Enums.Errors.NotDisplayedError}; } else { oData = {'Result': false, 'ErrorCode': Enums.Errors.DataTransferFailed}; } break; } this.executeResponseHandler(fResponseHandler, oContext, oData, oParameters); }; /** * @param {Function} fResponseHandler * @param {Object} oContext * @param {Object} oData * @param {Object} oParameters */ CAjax.prototype.executeResponseHandler = function (fResponseHandler, oContext, oData, oParameters) { if (!oData) { oData = {'Result': false, 'ErrorCode': 0}; } if (AfterLogicApi.runPluginHook) { AfterLogicApi.runPluginHook('ajax-default-response', [oParameters.Action, oData]); } if (typeof fResponseHandler === 'function') { fResponseHandler.apply(oContext, [oData, oParameters]); } }; /** * @param {Object} oXhr * @param {string} sType * @param {{Action:string}} oParameters */ CAjax.prototype.always = function (oParameters, oXhr, sType) { _.each(this.requests(), function (oReq, iIndex) { if (oReq && _.isEqual(oReq.Parameters, oParameters)) { this.requests()[iIndex] = undefined; } }, this); this.requests(_.compact(this.requests())); Utils.checkConnection(oParameters.Action, sType); if (App.Prefetcher && sType !== 'abort' && !this.hasOpenedRequests()) { App.Prefetcher.start(); } }; /** * @enum {string} */ Enums.Screens = { 'Login': 'login', 'Information': 'information', 'Header': 'header', 'Mailbox': 'mailbox', 'SingleMessageView': 'single-message-view', 'Compose': 'compose', 'SingleCompose': 'single-compose', 'Settings': 'settings', 'Contacts': 'contacts', 'Calendar': 'calendar', 'FileStorage': 'files', 'Helpdesk': 'helpdesk', 'SingleHelpdesk': 'single-helpdesk' }; /** * @enum {number} */ Enums.CalendarDefaultTab = { 'Day': 1, 'Week': 2, 'Month': 3 }; /** * @enum {number} */ Enums.TimeFormat = { 'F24': '0', 'F12': '1' }; /** * @enum {number} */ Enums.Errors = { 'InvalidToken': 101, 'AuthError': 102, 'DataBaseError': 104, 'LicenseProblem': 105, 'DemoLimitations': 106, 'Captcha': 107, 'AccessDenied': 108, 'CanNotGetMessage': 202, 'ImapQuota': 205, 'NotSavedInSentItems': 304, 'NoRequestedMailbox': 305, 'CanNotChangePassword': 502, 'AccountOldPasswordNotCorrect': 503, 'FetcherIncServerNotAvailable': 702, 'FetcherLoginNotCorrect': 703, 'HelpdeskThrowInWebmail': 805, 'HelpdeskUserNotExists': 807, 'HelpdeskUserNotActivated': 808, 'MailServerError': 901, 'DataTransferFailed': 1100, 'NotDisplayedError': 1155 }; /** * @enum {number} */ Enums.FolderTypes = { 'Inbox': 1, 'Sent': 2, 'Drafts': 3, 'Spam': 4, 'Trash': 5, 'Virus': 6, 'Starred': 7, 'System': 9, 'User': 10 }; /** * @enum {string} */ Enums.FolderFilter = { 'Flagged': 'flagged', 'Unseen': 'unseen' }; /** * @enum {number} */ Enums.LoginFormType = { 'Email': 0, 'Login': 3, 'Both': 4 }; /** * @enum {number} */ Enums.LoginSignMeType = { 'DefaultOff': 0, 'DefaultOn': 1, 'Unuse': 2 }; /** * @enum {string} */ Enums.ReplyType = { 'Reply': 'reply', 'ReplyAll': 'reply-all', 'Resend': 'resend', 'Forward': 'forward' }; /** * @enum {number} */ Enums.Importance = { 'Low': 5, 'Normal': 3, 'High': 1 }; /** * @enum {number} */ Enums.Sensivity = { 'Nothing': 0, 'Confidential': 1, 'Private': 2, 'Personal': 3 }; /** * @enum {string} */ Enums.ContactEmailType = { 'Personal': 'Personal', 'Business': 'Business', 'Other': 'Other' }; /** * @enum {string} */ Enums.ContactPhoneType = { 'Mobile': 'Mobile', 'Personal': 'Personal', 'Business': 'Business' }; /** * @enum {string} */ Enums.ContactAddressType = { 'Personal': 'Personal', 'Business': 'Business' }; /** * @enum {string} */ Enums.ContactSortType = { 'Email': 'Email', 'Name': 'Name', 'Frequency': 'Frequency' }; /** * @enum {number} */ Enums.SaveMail = { 'Hidden': 0, 'Checked': 1, 'Unchecked': 2 }; /** * @enum {string} */ Enums.SettingsTab = { 'Common': 'common', 'EmailAccounts': 'accounts', 'Calendar': 'calendar', 'MobileSync': 'mobile_sync', 'OutLookSync': 'outlook_sync', 'Helpdesk': 'helpdesk', 'Pgp': 'pgp', 'Services': 'services' }; /** * @enum {string} */ Enums.AccountSettingsTab = { 'Properties': 'properties', 'Signature': 'signature', 'Filters': 'filters', 'Autoresponder': 'autoresponder', 'Forward': 'forward', 'Folders': 'folders', 'FetcherInc': 'fetcher-inc', 'FetcherOut': 'fetcher-out', 'FetcherSig': 'fetcher-sig', 'IdentityProperties': 'identity-properties', 'IdentitySignature': 'identity-signature' }; /** * @enum {number} */ Enums.ContactsGroupListType = { 'Personal': 0, 'SubGroup': 1, 'Global': 2, 'SharedToAll': 3, 'All': 4 }; /** * @enum {string} */ Enums.IcalType = { Request: 'REQUEST', Reply: 'REPLY', Cancel: 'CANCEL', Save: 'SAVE' }; /** * @enum {string} */ Enums.IcalConfig = { Accepted: 'ACCEPTED', Declined: 'DECLINED', Tentative: 'TENTATIVE', NeedsAction: 'NEEDS-ACTION' }; /** * @enum {number} */ Enums.IcalConfigInt = { Accepted: 1, Declined: 2, Tentative: 3, NeedsAction: 0 }; /** * @enum {number} */ Enums.Key = { 'Tab': 9, 'Enter': 13, 'Shift': 16, 'Ctrl': 17, 'Esc': 27, 'Space': 32, 'PageUp': 33, 'PageDown': 34, 'End': 35, 'Home': 36, 'Up': 38, 'Down': 40, 'Left': 37, 'Right': 39, 'Del': 46, 'Six': 54, 'a': 65, 'b': 66, 'c': 67, 'f': 70, 'i': 73, 'k': 75, 'n': 78, 'p': 80, 'q': 81, 'r': 82, 's': 83, 'u': 85, 'v': 86, 'y': 89, 'z': 90, 'F5': 116, 'Comma': 188, 'Dot': 190, 'Dash': 192, 'Apostrophe': 222 }; Enums.MouseKey = { 'Left': 0, 'Middle': 1, 'Right': 2 }; /** * @enum {number} */ Enums.FileStorageType = { 'Personal': 0, 'Corporate': 1, 'Shared': 2, 'GoogleDrive': 3, 'Dropbox': 4 }; /** * @enum {number} */ Enums.FileStorageLinkType = { 'Unknown': 0, 'GoogleDrive': 1, 'Dropbox': 2 }; /** * @enum {number} */ Enums.HelpdeskThreadStates = { 'None': 0, 'Pending': 1, 'Waiting': 2, 'Answered': 3, 'Resolved': 4, 'Deferred': 5 }; /** * @enum {number} */ Enums.HelpdeskPostType = { 'Normal': 0, 'Internal': 1, 'System': 2 }; /** * @enum {number} */ Enums.HelpdeskFilters = { 'All': 0, 'Pending': 1, 'Resolved': 2, 'InWork': 3, 'Open': 4, 'Archived': 9 }; /** * @enum {number} */ Enums.CalendarAccess = { 'Full': 0, 'Write': 1, 'Read': 2 }; /** * @enum {number} */ Enums.CalendarEditRecurrenceEvent = { 'None': 0, 'OnlyThisInstance': 1, 'AllEvents': 2 }; /** * @enum {number} */ Enums.CalendarRepeatPeriod = { 'None': 0, 'Daily': 1, 'Weekly': 2, 'Monthly': 3, 'Yearly': 4 }; Enums.PhoneAction = { 'Offline': 'offline', 'OfflineError': 'offline_error', 'OfflineInit': 'offline_init', 'OfflineActive': 'offline_active', 'Online': 'online', 'OnlineActive': 'online_active', 'Incoming': 'incoming', 'IncomingConnect': 'incoming_connect', 'Outgoing': 'outgoing', 'OutgoingConnect': 'outgoing_connect', 'Settings': 'settings' }; Enums.HtmlEditorImageSizes = { 'Small': 'small', 'Medium': 'medium', 'Large': 'large', 'Original': 'original' }; Enums.MobilePanel = { 'Groups': 1, 'Items': 2, 'View': 3 }; Enums.PgpAction = { 'Import': 'import', 'Generate': 'generate', 'Encrypt': 'encrypt', 'Sign': 'sign', 'EncryptSign': 'encrypt-sign', 'Verify': 'ferify', 'DecryptVerify': 'decrypt-ferify' }; Enums.SocialType = { 'Unknown': 0, 'Google': 1, 'Dropbox': 2, 'Facebook': 3, 'Twitter': 4, 'Vkontakte': 5 }; Enums.notificationPermission = { 'Granted': 'granted', 'Denied': 'denied', 'Default': 'default' }; /** * @type {Function} */ Utils.inArray = $.inArray; /** * @type {Function} */ Utils.isFunc = $.isFunction; /** * @type {Function} */ Utils.trim = $.trim; /** * @type {Function} */ Utils.emptyFunction = function () {}; /** * @param {*} mValue * * @return {boolean} */ Utils.isUnd = function (mValue) { return undefined === mValue; }; /** * @param {*} oValue * * @return {boolean} */ Utils.isNull = function (oValue) { return null === oValue; }; /** * @param {*} oValue * * @return {boolean} */ Utils.isNormal = function (oValue) { return !Utils.isUnd(oValue) && !Utils.isNull(oValue); }; /** * @param {(string|number)} mValue * * @return {boolean} */ Utils.isNumeric = function (mValue) { return Utils.isNormal(mValue) ? (/^[1-9]+[0-9]*$/).test(mValue.toString()) : false; }; /** * @param {*} mValue * * @return {number} */ Utils.pInt = function (mValue) { var iValue = window.parseInt(mValue, 10); if (isNaN(iValue)) { iValue = 0; } return iValue; }; /** * @param {*} mValue * * @return {string} */ Utils.pString = function (mValue) { return Utils.isNormal(mValue) ? mValue.toString() : ''; }; /** * @param {*} aValue * @param {number=} iArrayLen * * @return {boolean} */ Utils.isNonEmptyArray = function (aValue, iArrayLen) { iArrayLen = iArrayLen || 1; return _.isArray(aValue) && iArrayLen <= aValue.length; }; /** * @param {Object} oObject * @param {string} sName * @param {*} mValue */ Utils.pImport = function (oObject, sName, mValue) { oObject[sName] = mValue; }; /** * @param {Object} oObject * @param {string} sName * @param {*} mDefault * @return {*} */ Utils.pExport = function (oObject, sName, mDefault) { return Utils.isUnd(oObject[sName]) ? mDefault : oObject[sName]; }; /** * @param {string} sText * * @return {string} */ Utils.encodeHtml = function (sText) { return (sText) ? sText.toString() .replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>') .replace(/"/g, '"').replace(/'/g, ''') : ''; }; /** * @param {string} sKey * @param {?Object=} oValueList * @param {?string=} sDefaultValue * @param {number=} nPluralCount * * @return {string} */ Utils.i18n = function (sKey, oValueList, sDefaultValue, nPluralCount) { var sValueName = '', sResult = Utils.isUnd(I18n[sKey]) ? (Utils.isNormal(sDefaultValue) ? sDefaultValue : sKey) : I18n[sKey] ; if (!Utils.isUnd(nPluralCount)) { sResult = (function (nPluralCount, sResult) { var nPlural = Utils.getPlural(AppData.User.DefaultLanguage, nPluralCount), aPluralParts = sResult.split('|') ; return (aPluralParts && aPluralParts[nPlural]) ? aPluralParts[nPlural] : ( aPluralParts && aPluralParts[0] ? aPluralParts[0] : sResult); }(nPluralCount, sResult)); } if (Utils.isNormal(oValueList)) { for (sValueName in oValueList) { if (oValueList.hasOwnProperty(sValueName)) { sResult = sResult.replace('%' + sValueName + '%', oValueList[sValueName]); } } } return sResult; }; /** * @param {number} iNum * @param {number} iDec * * @return {number} */ Utils.roundNumber = function (iNum, iDec) { return Math.round(iNum * Math.pow(10, iDec)) / Math.pow(10, iDec); }; /** * @param {(number|string)} iSizeInBytes * * @return {string} */ Utils.friendlySize = function (iSizeInBytes) { var iBytesInKb = 1024, iBytesInMb = iBytesInKb * iBytesInKb, iBytesInGb = iBytesInKb * iBytesInKb * iBytesInKb ; iSizeInBytes = Utils.pInt(iSizeInBytes); if (iSizeInBytes >= iBytesInGb) { return Utils.roundNumber(iSizeInBytes / iBytesInGb, 1) + Utils.i18n('MAIN/GIGABYTES'); } else if (iSizeInBytes >= iBytesInMb) { return Utils.roundNumber(iSizeInBytes / iBytesInMb, 1) + Utils.i18n('MAIN/MEGABYTES'); } else if (iSizeInBytes >= iBytesInKb) { return Utils.roundNumber(iSizeInBytes / iBytesInKb, 0) + Utils.i18n('MAIN/KILOBYTES'); } return iSizeInBytes + Utils.i18n('MAIN/BYTES'); }; Utils.timeOutAction = (function () { var oTimeOuts = {}; return function (sAction, fFunction, iTimeOut) { if (Utils.isUnd(oTimeOuts[sAction])) { oTimeOuts[sAction] = 0; } window.clearTimeout(oTimeOuts[sAction]); oTimeOuts[sAction] = window.setTimeout(fFunction, iTimeOut); }; }()); Utils.$log = null; Utils.aLog = []; Utils.log = function () { if (!AppData || !AppData.ClientDebug || !App.browser || App.browser.ie9AndBelow) { return; } function fCensor(mKey, mValue) { if (typeof(mValue) === 'string' && mValue.length > 50) { return mValue.substring(0, 50); } return mValue; } var $log = Utils.$log || $('<div style="display: none;"></div>').appendTo('body'), aNewRow = [] ; _.each(arguments, function (mArg) { var sRowPart = typeof(mArg) === 'string' ? mArg : JSON.stringify(mArg, fCensor); if (aNewRow.length === 0) { sRowPart = ' *** ' + sRowPart + ' *** '; } aNewRow.push(sRowPart); }); aNewRow.push(moment().format(' *** D MMMM, YYYY, HH:mm:ss *** ')); Utils.$log = $log; if (Utils.aLog.length > 200) { Utils.aLog.shift(); } Utils.aLog.push(Utils.encodeHtml(aNewRow.join(', '))); $log.html(Utils.aLog.join('<br /><br />')); }; /** * @param {string} sAction * @param {Object} oData * * @returns {Object} */ Utils.getAjaxDataForLog = function (sAction, oData) { var oDataForLog = oData; if (oData && oData.Result) { switch (sAction) { case 'MessageList': case 'MessageListByUids': oDataForLog = { 'Result': { 'Uids': oData.Result.Uids, 'UidNext': oData.Result.UidNext, 'FolderHash': oData.Result.FolderHash, 'MessageCount': oData.Result.MessageCount, 'MessageUnseenCount': oData.Result.MessageUnseenCount, 'MessageResultCount': oData.Result.MessageResultCount } }; break; case 'Message': oDataForLog = { 'Result': { 'Folder': oData.Result.Folder, 'Uid': oData.Result.Uid, 'Subject': oData.Result.Subject, 'Size': oData.Result.Size, 'TextSize': oData.Result.TextSize, 'From': oData.Result.From, 'To': oData.Result.To } }; break; case 'Messages': oDataForLog = { 'Result': _.map(oData.Result, function (oMessage) { return { 'Uid': oMessage.Uid, 'Subject': oMessage.Subject }; }) }; break; } } else if (oData) { oDataForLog = { 'Result': oData.Result, 'ErrorCode': oData.ErrorCode }; } return oDataForLog; }; /** * @param {string} sFullEmail * * @return {Object} */ Utils.getEmailParts = function (sFullEmail) { var iQuote1Pos = sFullEmail.indexOf('"'), iQuote2Pos = sFullEmail.indexOf('"', iQuote1Pos + 1), iLeftBrocketPos = sFullEmail.indexOf('<', iQuote2Pos), iPrevLeftBroketPos = -1, iRightBrocketPos = -1, sName = '', sEmail = '' ; while (iLeftBrocketPos !== -1) { iPrevLeftBroketPos = iLeftBrocketPos; iLeftBrocketPos = sFullEmail.indexOf('<', iLeftBrocketPos + 1); } iLeftBrocketPos = iPrevLeftBroketPos; iRightBrocketPos = sFullEmail.indexOf('>', iLeftBrocketPos + 1); if (iLeftBrocketPos === -1) { sEmail = Utils.trim(sFullEmail); } else { sName = (iQuote1Pos === -1) ? Utils.trim(sFullEmail.substring(0, iLeftBrocketPos)) : Utils.trim(sFullEmail.substring(iQuote1Pos + 1, iQuote2Pos)); sEmail = Utils.trim(sFullEmail.substring(iLeftBrocketPos + 1, iRightBrocketPos)); } return { 'name': sName, 'email': sEmail, 'FullEmail': sFullEmail }; }; /** * @param {string} sValue * * @return {boolean} */ Utils.isCorrectEmail = function (sValue) { return !!(sValue.match(/^[A-Z0-9\"!#\$%\^\{\}`~&'\+\-=_\.]+@[A-Z0-9\.\-]+$/i)); }; /** * @param {string} sAddresses * * @return {Array} */ Utils.getIncorrectEmailsFromAddressString = function (sAddresses) { var aEmails = sAddresses.replace(/"[^"]*"/g, '').replace(/;/g, ',').split(','), aIncorrectEmails = [], iIndex = 0, iLen = aEmails.length, sFullEmail = '', oEmailParts = null ; for (; iIndex < iLen; iIndex++) { sFullEmail = Utils.trim(aEmails[iIndex]); if (sFullEmail.length > 0) { oEmailParts = Utils.getEmailParts(Utils.trim(aEmails[iIndex])); if (!Utils.isCorrectEmail(oEmailParts.email)) { aIncorrectEmails.push(oEmailParts.email); } } } return aIncorrectEmails; }; /** * @param {string} sRecipients * * return {Array} */ Utils.getArrayRecipients = function (sRecipients) { if (!sRecipients) { return []; } var aRecipients = [], sWorkingRecipients = Utils.trim(sRecipients) + ' ', emailStartPos = 0, emailEndPos = 0, isInQuotes = false, chQuote = '"', isInAngleBrackets = false, isInBrackets = false, currentPos = 0, sWorkingRecipientsLen = sWorkingRecipients.length, currentChar = '', str = '', oRecipient = null, inList = false, jCount = 0, j = 0 ; while (currentPos < sWorkingRecipientsLen) { currentChar = sWorkingRecipients.substring(currentPos, currentPos+1); switch (currentChar) { case '\'': case '"': if (isInQuotes) { if (chQuote === currentChar) { isInQuotes = false; } } else { if (!isInAngleBrackets && !isInBrackets) { chQuote = currentChar; isInQuotes = true; } } break; case '<': if (!isInQuotes && !isInAngleBrackets && !isInBrackets) { isInAngleBrackets = true; } break; case '>': if (isInAngleBrackets) { isInAngleBrackets = false; } break; case '(': if (!isInQuotes && !isInAngleBrackets && !isInBrackets) { isInBrackets = true; } break; case ')': if (isInBrackets) { isInBrackets = false; } break; default: if (currentChar !== ',' && currentChar !== ';' && currentPos !== (sWorkingRecipientsLen - 1)) { break; } if (!isInAngleBrackets && !isInBrackets && !isInQuotes) { emailEndPos = (currentPos !== (sWorkingRecipientsLen-1)) ? currentPos : sWorkingRecipientsLen; str = sWorkingRecipients.substring(emailStartPos, emailEndPos); if (Utils.trim(str).length > 0) { oRecipient = Utils.getEmailParts(str); inList = false; jCount = aRecipients.length; for (j = 0; j < jCount; j++) { if (aRecipients[j].email === oRecipient.email) { inList = true; } } if (!inList && Utils.isCorrectEmail(oRecipient.email)) { aRecipients.push(oRecipient); } } emailStartPos = currentPos + 1; } break; } currentPos++; } return aRecipients; }; /** * Gets link for contacts inport. * * @return {string} */ Utils.getImportContactsLink = function () { return '?/ImportContacts/'; }; /** * Gets link for contacts export. * * @param {number} iAccountId * @param {string} $sSyncType * @return {string} */ Utils.getExportContactsLink = function ($sSyncType) { return '?/Raw/Contacts' + $sSyncType + '/'; }; /** * Gets link for calendar export by hash. * * @param {number} iAccountId * @param {string} sHash * * @return {string} */ Utils.getExportCalendarLinkByHash = function (iAccountId, sHash) { return '?/Raw/Calendar/' + iAccountId + '/' + sHash; }; /** * Gets link for download by hash. * * @param {number} iAccountId * @param {string} sHash * @param {boolean=} bIsExt = false * @param {string=} sTenatHash = '' * * @return {string} */ Utils.getDownloadLinkByHash = function (iAccountId, sHash, bIsExt, sTenatHash) { bIsExt = Utils.isUnd(bIsExt) ? false : !!bIsExt; sTenatHash = Utils.isUnd(sTenatHash) ? '' : sTenatHash; return '?/Raw/Download/' + iAccountId + '/' + sHash + '/' + (bIsExt ? '1' : '0') + ('' === sTenatHash ? '' : '/' + sTenatHash); }; /** * Gets link for view by hash. * * @param {number} iAccountId * @param {string} sHash * @param {boolean=} bIsExt = false * @param {string=} sTenatHash = '' * * @return {string} */ Utils.getViewLinkByHash = function (iAccountId, sHash, bIsExt, sTenatHash) { bIsExt = Utils.isUnd(bIsExt) ? false : !!bIsExt; sTenatHash = Utils.isUnd(sTenatHash) ? '' : sTenatHash; return '?/Raw/View/' + iAccountId + '/' + sHash + '/' + (bIsExt ? '1' : '0') + ('' === sTenatHash ? '' : '/' + sTenatHash); }; /** * Gets link for view by hash in iframe. * * @param {number} iAccountId * @param {string} sHash * @param {boolean=} bIsExt = false * @param {string=} sTenatHash = '' * * @return {string} */ Utils.getIframeLinkByHash = function (iAccountId, sHash, bIsExt, sTenatHash) { bIsExt = Utils.isUnd(bIsExt) ? false : !!bIsExt; sTenatHash = Utils.isUnd(sTenatHash) ? '' : sTenatHash; return '?/Raw/Iframe/' + iAccountId + '/' + sHash + '/' + (bIsExt ? '1' : '0') + ('' === sTenatHash ? '' : '/' + sTenatHash); }; /** * Gets link for view by hash in iframe. * * @param {number} iAccountId * @param {string} sUrl * * @return {string} */ Utils.getIframeWrappwer = function (iAccountId, sUrl) { return '?/Raw/Iframe/' + iAccountId + '/' + window.encodeURIComponent(sUrl) + '/'; }; /** * Gets link for thumbnail by hash. * * @param {number} iAccountId * @param {string} sHash * @param {boolean=} bIsExt = false * @param {string=} sTenatHash = '' * * @return {string} */ Utils.getViewThumbnailLinkByHash = function (iAccountId, sHash, bIsExt, sTenatHash) { bIsExt = Utils.isUnd(bIsExt) ? false : !!bIsExt; sTenatHash = Utils.isUnd(sTenatHash) ? '' : sTenatHash; return '?/Raw/Thumbnail/' + iAccountId + '/' + sHash + '/' + (bIsExt ? '1' : '0') + ('' === sTenatHash ? '' : '/' + sTenatHash); }; /** * Gets link for download by hash. * * @param {number} iAccountId * @param {string} sHash * @param {string=} sPublicHash * * @return {string} */ Utils.getFilestorageDownloadLinkByHash = function (iAccountId, sHash, sPublicHash) { var sUrl = '?/Raw/FilesDownload/' + iAccountId + '/' + sHash; if (!Utils.isUnd(sPublicHash)) { sUrl = sUrl + '/0/' + sPublicHash; } return sUrl; }; /** * Gets link for download by hash. * * @param {number} iAccountId * @param {string} sHash * @param {string=} sPublicHash * * @return {string} */ Utils.getFilestorageViewLinkByHash = function (iAccountId, sHash, sPublicHash) { var sUrl = '?/Raw/FilesView/' + iAccountId + '/' + sHash; if (!Utils.isUnd(sPublicHash)) { sUrl = sUrl + '/0/' + sPublicHash; } return sUrl; }; /** * Gets link for thumbnail by hash. * * @param {number} iAccountId * @param {string} sHash * @param {string} sPublicHash * * @return {string} */ Utils.getFilestorageViewThumbnailLinkByHash = function (iAccountId, sHash, sPublicHash) { var sUrl = '?/Raw/FilesThumbnail/' + iAccountId + '/' + sHash; if (!Utils.isUnd(sPublicHash)) { sUrl = sUrl + '/0/' + sPublicHash; } return sUrl; }; /** * Gets link for public by hash. * * @param {string} sHash * * @return {string} */ Utils.getFilestoragePublicViewLinkByHash = function (sHash) { return '?/Window/Files/0/' + sHash; }; /** * Gets link for public by hash. * * @param {string} sHash * * @return {string} */ Utils.getFilestoragePublicDownloadLinkByHash = function (sHash) { return '?/Raw/FilesPub/0/' + sHash; }; /** * @param {number} iMonth * @param {number} iYear * * @return {number} */ Utils.daysInMonth = function (iMonth, iYear) { if (0 < iMonth && 13 > iMonth && 0 < iYear) { return new Date(iYear, iMonth, 0).getDate(); } return 31; }; /** * @return {string} */ Utils.getAppPath = function () { return window.location.protocol + '//' + window.location.host + window.location.pathname; }; Utils.WindowOpener = { _iDefaultRatio: 0.8, _aOpenedWins: [], /** * @param {{folder:Function, uid:Function}} oMessage * @param {boolean=} bDrafts */ openMessage: function (oMessage, bDrafts) { if (oMessage) { var sFolder = oMessage.folder(), sUid = oMessage.uid(), sHash = '', oWin = null ; if (bDrafts) { sHash = App.Routing.buildHashFromArray([Enums.Screens.SingleCompose, 'drafts', sFolder, sUid]); } else { sHash = App.Routing.buildHashFromArray([Enums.Screens.SingleMessageView, sFolder, 'msg' + sUid]); } oWin = this.openTab(sHash); } }, /** * @param {string} sUrl * * @return Object */ openTab: function (sUrl) { var oWin = null; oWin = window.open(sUrl, '_blank'); oWin.focus(); oWin.name = AppData.Accounts.currentId(); this._aOpenedWins.push(oWin); return oWin; }, /** * @param {string} sUrl * @param {string} sPopupName * @param {boolean=} bMenubar = false * * @return Object */ open: function (sUrl, sPopupName, bMenubar) { var sMenubar = (bMenubar) ? ',menubar=yes' : ',menubar=no', sParams = 'location=no,toolbar=no,status=no,scrollbars=yes,resizable=yes' + sMenubar, oWin = null ; sPopupName = sPopupName.replace(/\W/g, ''); // forbidden characters in the name of the window for ie sParams += this._getSizeParameters(); oWin = window.open(sUrl, sPopupName, sParams); oWin.focus(); oWin.name = AppData.Accounts.currentId(); this._aOpenedWins.push(oWin); return oWin; }, closeAll: function () { var iLen = this._aOpenedWins.length, iIndex = 0, oWin = null ; for (; iIndex < iLen; iIndex++) { oWin = this._aOpenedWins[iIndex]; if (!oWin.closed) { oWin.close(); } } this._aOpenedWins = []; }, /** * @return string */ _getSizeParameters: function () { var iScreenWidth = window.screen.width, iWidth = Math.ceil(iScreenWidth * this._iDefaultRatio), iLeft = Math.ceil((iScreenWidth - iWidth) / 2), iScreenHeight = window.screen.height, iHeight = Math.ceil(iScreenHeight * this._iDefaultRatio), iTop = Math.ceil((iScreenHeight - iHeight) / 2) ; return ',width=' + iWidth + ',height=' + iHeight + ',top=' + iTop + ',left=' + iLeft; } }; /** * @param {?} oObject * @param {string} sDelegateName * @param {Array=} aParameters */ Utils.delegateRun = function (oObject, sDelegateName, aParameters) { if (oObject && oObject[sDelegateName]) { oObject[sDelegateName].apply(oObject, _.isArray(aParameters) ? aParameters : []); } }; /** * @param {string} input * @param {number} multiplier * @return {string} */ Utils.strRepeat = function (input, multiplier) { return (new Array(multiplier + 1)).join(input); }; Utils.deferredUpdate = function (element, state, duration, callback) { if (!element.__interval && !!state) { element.__state = true; callback(element, true); element.__interval = window.setInterval(function () { if (!element.__state) { callback(element, false); window.clearInterval(element.__interval); element.__interval = null; } }, duration); } else if (!state) { element.__state = false; } }; Utils.draggableMessages = function () { return $('<div class="draggable draggableMessages"><div class="content"><span class="count-text"></span></div></div>').appendTo('#pSevenHidden'); }; Utils.draggableContacts = function () { return $('<div class="draggable draggableContacts"><div class="content"><span class="count-text"></span></div></div>').appendTo('#pSevenHidden'); }; Utils.removeActiveFocus = function () { if (document && document.activeElement && document.activeElement.blur) { var oA = $(document.activeElement); if (oA.is('input') || oA.is('textarea')) { document.activeElement.blur(); } } }; Utils.uiDropHelperAnim = function (oEvent, oUi) { var iLeft = 0, iTop = 0, iNewLeft = 0, iNewTop = 0, iWidth = 0, iHeight = 0, helper = oUi.helper.clone().appendTo('#pSevenHidden'), target = $(oEvent.target).find('.animGoal'), position = null ; target = target[0] ? $(target[0]) : $(oEvent.target); position = target && target[0] ? target.offset() : null; if (position) { iLeft = window.Math.round(position.left); iTop = window.Math.round(position.top); iWidth = target.width(); iHeight = target.height(); iNewLeft = iLeft; if (0 < iWidth) { iNewLeft += window.Math.round(iWidth / 2); } iNewTop = iTop; if (0 < iHeight) { iNewTop += window.Math.round(iHeight / 2); } helper.animate({ 'left': iNewLeft + 'px', 'top': iNewTop + 'px', 'font-size': '0px', 'opacity': 0 }, 800, 'easeOutQuint', function() { $(this).remove(); }); } }; Utils.isTextFieldFocused = function () { var mTag = document && document.activeElement ? document.activeElement : null, mTagName = mTag ? mTag.tagName : null, mTagType = mTag && mTag.type ? mTag.type.toLowerCase() : null, mContentEditable = mTag ? mTag.contentEditable : null ; return ('INPUT' === mTagName && (mTagType === 'text' || mTagType === 'password' || mTagType === 'email')) || 'TEXTAREA' === mTagName || 'IFRAME' === mTagName || mContentEditable === 'true'; }; Utils.removeSelection = function () { if (window.getSelection) { window.getSelection().removeAllRanges(); } else if (document.selection) { document.selection.empty(); } }; Utils.getMonthNamesArray = function () { var aMonthes = Utils.i18n('DATETIME/MONTH_NAMES').split(' '), iLen = 12, iIndex = aMonthes.length ; for (; iIndex < iLen; iIndex++) { aMonthes[iIndex] = ''; } return aMonthes; }; /** * http://docs.translatehouse.org/projects/localization-guide/en/latest/l10n/pluralforms.html?id=l10n/pluralforms * * @param {string} sLang * @param {number} iNumber * * @return {number} */ Utils.getPlural = function (sLang, iNumber) { var iResult = 0; iNumber = Utils.pInt(iNumber); switch (sLang) { case 'Arabic': iResult = (iNumber === 0 ? 0 : iNumber === 1 ? 1 : iNumber === 2 ? 2 : iNumber % 100 >= 3 && iNumber % 100 <= 10 ? 3 : iNumber % 100 >= 11 ? 4 : 5); break; case 'Bulgarian': iResult = (iNumber === 1 ? 0 : 1); break; case 'Chinese-Simplified': iResult = 0; break; case 'Chinese-Traditional': iResult = (iNumber === 1 ? 0 : 1); break; case 'Czech': iResult = (iNumber === 1) ? 0 : (iNumber >= 2 && iNumber <= 4) ? 1 : 2; break; case 'Danish': iResult = (iNumber === 1 ? 0 : 1); break; case 'Dutch': iResult = (iNumber === 1 ? 0 : 1); break; case 'English': iResult = (iNumber === 1 ? 0 : 1); break; case 'Estonian': iResult = (iNumber === 1 ? 0 : 1); break; case 'Finish': iResult = (iNumber === 1 ? 0 : 1); break; case 'French': iResult = (iNumber === 1 ? 0 : 1); break; case 'German': iResult = (iNumber === 1 ? 0 : 1); break; case 'Greek': iResult = (iNumber === 1 ? 0 : 1); break; case 'Hebrew': iResult = (iNumber === 1 ? 0 : 1); break; case 'Hungarian': iResult = (iNumber === 1 ? 0 : 1); break; case 'Italian': iResult = (iNumber === 1 ? 0 : 1); break; case 'Japanese': iResult = 0; break; case 'Korean': iResult = 0; break; case 'Latvian': iResult = (iNumber % 10 === 1 && iNumber % 100 !== 11 ? 0 : iNumber !== 0 ? 1 : 2); break; case 'Lithuanian': iResult = (iNumber % 10 === 1 && iNumber % 100 !== 11 ? 0 : iNumber % 10 >= 2 && (iNumber % 100 < 10 || iNumber % 100 >= 20) ? 1 : 2); break; case 'Norwegian': iResult = (iNumber === 1 ? 0 : 1); break; case 'Persian': iResult = 0; break; case 'Polish': iResult = (iNumber === 1 ? 0 : iNumber % 10 >= 2 && iNumber % 10 <= 4 && (iNumber % 100 < 10 || iNumber % 100 >= 20) ? 1 : 2); break; case 'Portuguese-Portuguese': iResult = (iNumber === 1 ? 0 : 1); break; case 'Portuguese-Brazil': iResult = (iNumber === 1 ? 0 : 1); break; case 'Romanian': iResult = (iNumber === 1 ? 0 : (iNumber === 0 || (iNumber % 100 > 0 && iNumber % 100 < 20)) ? 1 : 2); break; case 'Russian': iResult = (iNumber % 10 === 1 && iNumber % 100 !== 11 ? 0 : iNumber % 10 >= 2 && iNumber % 10 <= 4 && (iNumber % 100 < 10 || iNumber % 100 >= 20) ? 1 : 2); break; case 'Serbian': iResult = (iNumber % 10 === 1 && iNumber % 100 !== 11 ? 0 : iNumber % 10 >= 2 && iNumber % 10 <= 4 && (iNumber % 100 < 10 || iNumber % 100 >= 20) ? 1 : 2); break; case 'Spanish': iResult = (iNumber === 1 ? 0 : 1); break; case 'Swedish': iResult = (iNumber === 1 ? 0 : 1); break; case 'Thai': iResult = 0; break; case 'Turkish': iResult = (iNumber === 1 ? 0 : 1); break; case 'Ukrainian': iResult = (iNumber % 10 === 1 && iNumber % 100 !== 11 ? 0 : iNumber % 10 >= 2 && iNumber % 10 <= 4 && (iNumber % 100 < 10 || iNumber % 100 >= 20) ? 1 : 2); break; default: iResult = 0; break; } return iResult; }; /** * @param {string} sFile * * @return {string} */ Utils.getFileExtension = function (sFile) { var sResult = '', iIndex = sFile.lastIndexOf('.') ; if (iIndex > -1) { sResult = sFile.substr(iIndex + 1); } return sResult; }; /** * @param {string} sFile * * @return {string} */ Utils.getFileNameWithoutExtension = function (sFile) { var sResult = sFile, iIndex = sFile.lastIndexOf('.') ; if (iIndex > -1) { sResult = sFile.substr(0, iIndex); } return sResult; }; /** * @param {Object} oElement * @param {Object} oItem */ Utils.defaultOptionsAfterRender = function (oElement, oItem) { if (oItem) { if (!Utils.isUnd(oItem.disable)) { ko.applyBindingsToNode(oElement, { 'disable': oItem.disable }, oItem); } } }; /** * @param {string} sDateFormat * * @return string */ Utils.getDateFormatForMoment = function (sDateFormat) { var sMomentDateFormat = 'MM/DD/YYYY'; switch (sDateFormat) { case 'MM/DD/YYYY': sMomentDateFormat = 'MM/DD/YYYY'; break; case 'DD/MM/YYYY': sMomentDateFormat = 'DD/MM/YYYY'; break; case 'DD Month YYYY': sMomentDateFormat = 'DD MMMM YYYY'; break; } return sMomentDateFormat; }; /** * @param {string} sDateFormat * * @return string */ Utils.getDateFormatForDatePicker = function (sDateFormat) { var sDatePickerDateFormat = 'mm/dd/yy'; switch (sDateFormat) { case 'MM/DD/YYYY': sDatePickerDateFormat = 'mm/dd/yy'; break; case 'DD/MM/YYYY': sDatePickerDateFormat = 'dd/mm/yy'; break; case 'DD Month YYYY': sDatePickerDateFormat = 'dd MM yy'; break; } return sDatePickerDateFormat; }; /** * @return Array */ Utils.getDateFormatsForSelector = function () { return _.map(AppData.App.DateFormats, function (sDateFormat) { switch (sDateFormat) { case 'MM/DD/YYYY': return {name: Utils.i18n('DATETIME/DATEFORMAT_MMDDYYYY'), value: sDateFormat}; case 'DD/MM/YYYY': return {name: Utils.i18n('DATETIME/DATEFORMAT_DDMMYYYY'), value: sDateFormat}; case 'DD Month YYYY': return {name: Utils.i18n('DATETIME/DATEFORMAT_DDMONTHYYYY'), value: sDateFormat}; default: return {name: sDateFormat, value: sDateFormat}; } }); }; /** * @param {string} sSubject * * @return {string} */ Utils.getTitleForEvent = function (sSubject) { var sTitle = sSubject ? Utils.trim(sSubject.replace(/[\n\r]/, ' ')) : '', iFirstSpacePos = sTitle.indexOf(' ', 180) ; if (iFirstSpacePos >= 0) { sTitle = sTitle.substring(0, iFirstSpacePos) + '...'; } if (sTitle.length > 200) { sTitle = sTitle.substring(0, 200) + '...'; } return sTitle; }; Utils.desktopNotify = (function () { var aNotifications = [], iTimeoutID = 0 ; return function (oData) { if (AppData.User.DesktopNotifications && window.Notification && !App.focused()) { if (oData && oData.action === 'show' && window.Notification.permission !== Enums.notificationPermission.Denied) { // oData - action, body, dir, lang, tag, icon, callback, timeout var oOptions = { //https://developer.mozilla.org/en-US/docs/Web/API/Notification body: oData.body || '', //A string representing an extra content to display within the notification dir: oData.dir || "auto", //The direction of the notification; it can be auto, ltr, or rtl lang: oData.lang || '', //Specify the lang used within the notification. This string must be a valid BCP 47 language tag tag: oData.tag || Math.floor(Math.random() * (1000 - 100) + 100), //An ID for a given notification that allows to retrieve, replace or remove it if necessary icon: oData.icon || false //The URL of an image to be used as an icon by the notification }, oNotification, fShowNotification = function() { oNotification = new window.Notification(oData.title, oOptions); //Firefox and Safari close the notifications automatically after a few moments, e.g. 4 seconds. oNotification.onclick = function (oEv) { if(oData.callback) { oData.callback(); } oNotification.close(); }; oNotification.onshow = function (oEv) {}; oNotification.onclose = function (oEv) {}; oNotification.onerror = function (oEv) {}; if(oData.timeout) { iTimeoutID = setTimeout(function() {oNotification.close();}, oData.timeout); } aNotifications.push(oNotification); } ; if (window.Notification.permission === 'granted') { fShowNotification(); } else if (window.Notification.permission === 'default') { window.Notification.requestPermission(function (sPermission) { if(sPermission === "granted") { fShowNotification(); } }); } } else if (oData && oData.action === 'hide') { _.each(aNotifications, function (oNotifi, ikey) { if (oData.tag === oNotifi.tag) { oNotifi.close(); aNotifications.splice(ikey, 1); } }); } else if (oData && oData.action === 'hideAll') { _.each(aNotifications,function (oNotifi) { oNotifi.close(); }); aNotifications.length = 0; } } }; }()); /** * @return {boolean} */ Utils.isRTL = function () { return $html.hasClass('rtl'); }; /** * @param {string} sName * @return {boolean} */ Utils.validateFileOrFolderName = function (sName) { sName = Utils.trim(sName); return '' !== sName && !/["\/\\*?<>|:]/.test(sName); }; /** * @param {string} sColor * @param {number} iPercent * * @return {string} */ Utils.shadeColor = function (sColor, iPercent) { var usePound = false, num = 0, r = 0, b = 0, g = 0 ; if (sColor[0] === "#") { sColor = sColor.slice(1); usePound = true; } num = window.parseInt(sColor, 16); r = (num >> 16) + iPercent; if (r > 255) { r = 255; } else if (r < 0) { r = 0; } b = ((num >> 8) & 0x00FF) + iPercent; if (b > 255) { b = 255; } else if (b < 0) { b = 0; } g = (num & 0x0000FF) + iPercent; if (g > 255) { g = 255; } else if (g < 0) { g = 0; } return (usePound ? "#" : "") + (g | (b << 8) | (r << 16)).toString(16); }; /** * @param {Object} ChildClass * @param {Object} ParentClass */ Utils.extend = function (ChildClass, ParentClass) { /** * @constructor */ var TmpClass = function(){}; TmpClass.prototype = ParentClass.prototype; ChildClass.prototype = new TmpClass(); ChildClass.prototype.constructor = ChildClass; }; Utils.thumbQueue = (function () { var oImages = {}, oImagesIncrements = {}, iNumberOfImages = 2 ; return function (sSessionUid, sImageSrc, fImageSrcObserver) { if(sImageSrc && fImageSrcObserver) { if(!(sSessionUid in oImagesIncrements) || oImagesIncrements[sSessionUid] > 0) //load first images { if(!(sSessionUid in oImagesIncrements)) //on first image { oImagesIncrements[sSessionUid] = iNumberOfImages; oImages[sSessionUid] = []; } oImagesIncrements[sSessionUid]--; fImageSrcObserver(sImageSrc); //load image } else //create queue { oImages[sSessionUid].push({ imageSrc: sImageSrc, imageSrcObserver: fImageSrcObserver, messageUid: sSessionUid }); } } else //load images from queue (fires load event) { if(oImages[sSessionUid] && oImages[sSessionUid].length) { oImages[sSessionUid][0].imageSrcObserver(oImages[sSessionUid][0].imageSrc); oImages[sSessionUid].shift(); } } }; }()); Utils.checkConnection = (function () { var iTimer = -1, iLastWakeTime = new Date().getTime(), iCurrentTime = 0, bAwoke = false ; setInterval(function() { //fix for sleep mode iCurrentTime = new Date().getTime(); bAwoke = iCurrentTime > (iLastWakeTime + 5000 + 1000); iLastWakeTime = iCurrentTime; if(bAwoke) { App.Api.hideError(true); } }, 5000); return function (sAction, sStatus) { clearTimeout(iTimer); if(sStatus !== 'error') { App.Api.hideError(true); } else { if (sAction === 'Ping') { //if (!bAwoke) { App.Api.showError(Utils.i18n('WARNING/NO_INTERNET_CONNECTION'), false, true, true); iTimer = setTimeout(function () { App.Ajax.send({'Action': 'Ping'}); }, 60000); //} } else { App.Ajax.send({'Action': 'Ping'}); } } }; }()); Utils.loadScript = function (sUrl, fCallback, aParams, sFuncName) { var script = document.createElement('script'); if (!Utils.isUnd(sFuncName) && fCallback) { window[sFuncName] = fCallback; } if (Utils.isUnd(aParams)) { aParams = {}; } _.each(aParams, function(value, key){ script.setAttribute(key, value); }); script.type = 'text/javascript'; script.src = sUrl; document.body.appendChild(script); }; Utils.registerMailto = function (bRegisterOnce) { if (window.navigator && Utils.isFunc(window.navigator.registerProtocolHandler) && (!bRegisterOnce || App.Storage.getData('MailtoAsked') !== 1)) { window.navigator.registerProtocolHandler( 'mailto', Utils.getAppPath() + '#' + Enums.Screens.Compose + '/to/%s', AppData.App.SiteName !== '' ? AppData.App.SiteName : 'WebMail' ); App.Storage.setData('MailtoAsked', 1); } }; Utils.CustomTooltip = { _$Region: null, _$ArrowTop: null, _$Text: null, _$ArrowBottom: null, _iArrowBorderLeft: 0, _iArrowMarginLeft: 0, _iLeftShift: 0, _bInitialized: false, init: function () { if (!this._bInitialized) { this._$Region = $('<span class="custom_tooltip"></span>').appendTo('body').hide(); this._$ArrowTop = $('<span class="custom_tooltip_arrow top"></span>').appendTo(this._$Region); this._$Text = $('<span class="custom_tooltip_text"></span>').appendTo(this._$Region); this._$ArrowBottom = $('<span class="custom_tooltip_arrow bottom"></span>').appendTo(this._$Region); this._iArrowMarginLeft = Utils.pInt(this._$ArrowTop.css('margin-left')); this._iArrowBorderLeft = Utils.pInt(this._$ArrowTop.css('border-left-width')); this._iLeftShift = this._iArrowBorderLeft + this._iArrowMarginLeft + Utils.pInt(this._$Region.css('margin-left')); this._bInitialized = true; } this._$ArrowTop.show(); this._$ArrowBottom.hide(); this._$ArrowTop.css({ 'margin-left': this._iArrowMarginLeft + 'px' }); this._$ArrowBottom.css({ 'margin-left': this._iArrowMarginLeft + 'px' }); }, show: function (sText, $ItemToAlign) { this.init(); var oItemOffset = $ItemToAlign.offset(), iItemHalfWidth = Math.round($ItemToAlign.innerWidth()/2), iLeftShift = this._iLeftShift - iItemHalfWidth ; this._$Text.html(sText); this._$Region.fadeIn().css({ 'top': oItemOffset.top + $ItemToAlign.height(), 'left': oItemOffset.left - iLeftShift, 'right': 'auto' }); if ($('body').height() < this._$Region.height() + this._$Region.offset().top) { this._$ArrowTop.hide(); this._$ArrowBottom.show(); this._$Region.css({ 'top': oItemOffset.top - this._$Region.height() }); } if ($('body').width() < (this._$Region.outerWidth(true) + this._$Region.offset().left)) { this._$Region.css({ 'left': 'auto', 'right': 0 }); this._$ArrowTop.css({ 'margin-left': (iItemHalfWidth + oItemOffset.left - this._$Region.offset().left - this._iArrowBorderLeft) + 'px' }); } }, hide: function () { if (this._bInitialized) { this._$Region.hide(); } } }; ko.bindingHandlers.command = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { var jqElement = $(oElement), oCommand = fValueAccessor() ; if (!oCommand || !oCommand.enabled || !oCommand.canExecute) { throw new Error('You are not using command function'); } jqElement.addClass('command'); ko.bindingHandlers[jqElement.is('form') ? 'submit' : 'click'].init.apply(oViewModel, arguments); }, 'update': function (oElement, fValueAccessor) { var bResult = true, jqElement = $(oElement), oCommand = fValueAccessor() ; bResult = oCommand.enabled(); jqElement.toggleClass('command-not-enabled', !bResult); if (bResult) { bResult = oCommand.canExecute(); jqElement.toggleClass('unavailable', !bResult); } jqElement.toggleClass('command-disabled disable disabled', !bResult); jqElement.toggleClass('command-disabled', !bResult); // if (jqElement.is('input') || jqElement.is('button')) // { // jqElement.prop('disabled', !bResult); // } } }; ko.bindingHandlers.simpleTemplate = { 'init': function (oElement, fValueAccessor) { var sTemplateID = ko.utils.unwrapObservable(fValueAccessor()), oEl = $('#' + sTemplateID) ; if (oEl && oEl[0]) { $(oElement).html(oEl.html().replace(/<script(.*?)>/i, '<script$1>').replace(/<\/script(.*?)>/i, '</script>')); } } }; ko.bindingHandlers.findFocused = { 'init': function (oElement) { var $oEl = $(oElement), $oInp = null ; $oInp = $oEl.find('.catch-focus'); if ($oInp && 1 === $oInp.length && $oInp[0]) { $oInp.on('blur', function () { $oEl.removeClass('focused'); }).on('focus', function () { $oEl.addClass('focused'); }); } } }; ko.bindingHandlers.findFilled = { 'init': function (oElement) { var $oEl = $(oElement), $oInp = null, fFunc = null ; $oInp = $oEl.find('.catch-filled'); if ($oInp && 1 === $oInp.length && $oInp[0]) { fFunc = function () { $oEl.toggleClass('filled', '' !== $oInp.val()); }; fFunc(); _.delay(fFunc, 200); $oInp.on('change', fFunc); } } }; ko.bindingHandlers.alert = { 'init': function (oElement, fValueAccessor) { window.alert(ko.utils.unwrapObservable(fValueAccessor())); }, 'update': function (oElement, fValueAccessor) { window.alert(ko.utils.unwrapObservable(fValueAccessor())); } }; ko.bindingHandlers.onEnter = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { ko.bindingHandlers.event.init(oElement, function () { return { 'keyup': function (oData, oEvent) { if (oEvent && 13 === window.parseInt(oEvent.keyCode, 10)) { $(oElement).trigger('change'); fValueAccessor().call(this, oData); } } }; }, fAllBindingsAccessor, oViewModel); } }; ko.bindingHandlers.onCtrlEnter = { 'init': bMobileApp ? null : function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { ko.bindingHandlers.event.init(oElement, function () { return { 'keydown': function (oData, oEvent) { if (oEvent && 13 === window.parseInt(oEvent.keyCode, 10) && oEvent.ctrlKey) { $(oElement).trigger('change'); fValueAccessor().call(this, oData); return false; } return true; } }; }, fAllBindingsAccessor, oViewModel); } }; ko.bindingHandlers.onEsc = { 'init': bMobileApp ? null : function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { ko.bindingHandlers.event.init(oElement, function () { return { 'keyup': function (oData, oEvent) { if (oEvent && 27 === window.parseInt(oEvent.keyCode, 10)) { $(oElement).trigger('change'); fValueAccessor().call(this, oData); } } }; }, fAllBindingsAccessor, oViewModel); } }; ko.bindingHandlers.onFocusSelect = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { ko.bindingHandlers.event.init(oElement, function () { return { 'focus': function () { oElement.select(); } }; }, fAllBindingsAccessor, oViewModel); } }; ko.bindingHandlers.onEnterChange = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { ko.bindingHandlers.event.init(oElement, function () { return { 'keyup': function (oData, oEvent) { if (oEvent && 13 === window.parseInt(oEvent.keyCode, 10)) { $(oElement).trigger('change'); } } }; }, fAllBindingsAccessor, oViewModel); } }; ko.bindingHandlers.fadeIn = { 'update': function (oElement, fValueAccessor) { if (ko.utils.unwrapObservable(fValueAccessor())) { $(oElement).hide().fadeIn('fast'); } } }; ko.bindingHandlers.fadeOut = { 'update': function (oElement, fValueAccessor) { if (ko.utils.unwrapObservable(fValueAccessor())) { $(oElement).fadeOut(); } } }; ko.bindingHandlers.csstext = { 'init': function (oElement, fValueAccessor) { if (oElement && oElement.styleSheet && !Utils.isUnd(oElement.styleSheet.cssText)) { oElement.styleSheet.cssText = ko.utils.unwrapObservable(fValueAccessor()); } else { $(oElement).text(ko.utils.unwrapObservable(fValueAccessor())); } }, 'update': function (oElement, fValueAccessor) { if (oElement && oElement.styleSheet && !Utils.isUnd(oElement.styleSheet.cssText)) { oElement.styleSheet.cssText = ko.utils.unwrapObservable(fValueAccessor()); } else { $(oElement).text(ko.utils.unwrapObservable(fValueAccessor())); } } }; ko.bindingHandlers.i18n = { 'init': function (oElement, fValueAccessor) { var sKey = $(oElement).data('i18n'), sValue = sKey ? Utils.i18n(sKey) : sKey ; if ('' !== sValue) { switch (fValueAccessor()) { case 'value': $(oElement).val(sValue); break; case 'text': $(oElement).text(sValue); break; case 'html': $(oElement).html(sValue); break; case 'title': $(oElement).attr('title', sValue); break; case 'placeholder': $(oElement).attr({'placeholder': sValue}); break; } } } }; ko.bindingHandlers.link = { 'init': function (oElement, fValueAccessor) { $(oElement).attr('href', ko.utils.unwrapObservable(fValueAccessor())); } }; ko.bindingHandlers.title = { 'init': function (oElement, fValueAccessor) { $(oElement).attr('title', ko.utils.unwrapObservable(fValueAccessor())); }, 'update': function (oElement, fValueAccessor) { $(oElement).attr('title', ko.utils.unwrapObservable(fValueAccessor())); } }; ko.bindingHandlers.initDom = { 'init': function (oElement, fValueAccessor) { if (fValueAccessor()) { if (_.isArray(fValueAccessor())) { var aList = fValueAccessor(), iIndex = aList.length - 1 ; for (; 0 <= iIndex; iIndex--) { aList[iIndex]($(oElement)); } } else { fValueAccessor()($(oElement)); } } } }; ko.bindingHandlers.customScrollbar = { 'init': bMobileApp ? null : function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { if (bMobileDevice) { return; } var jqElement = $(oElement), oCommand = fValueAccessor() ; /*_.delay(_.bind(function () { var jqCustomScrollbar = jqElement.find('.customscroll-scrollbar-vertical'); jqCustomScrollbar.on('click', function (oEv) { oEv.stopPropagation(); }); }, this), 1000);*/ oCommand = /** @type {{scrollToTopTrigger:{subscribe:Function},scrollToBottomTrigger:{subscribe:Function},scrollTo:{subscribe:Function},reset:Function}}*/ oCommand; jqElement.addClass('scroll-wrap').customscroll(oCommand); if (!Utils.isUnd(oCommand.reset)) { oElement._customscroll_reset = _.throttle(function () { jqElement.data('customscroll').reset(); }, 100); } if (!Utils.isUnd(oCommand.scrollToTopTrigger) && Utils.isFunc(oCommand.scrollToTopTrigger.subscribe)) { oCommand.scrollToTopTrigger.subscribe(function () { if (jqElement.data('customscroll')) { jqElement.data('customscroll')['scrollToTop'](); } }); } if (!Utils.isUnd(oCommand.scrollToBottomTrigger) && Utils.isFunc(oCommand.scrollToBottomTrigger.subscribe)) { oCommand.scrollToBottomTrigger.subscribe(function () { if (jqElement.data('customscroll')) { jqElement.data('customscroll')['scrollToBottom'](); } }); } if (!Utils.isUnd(oCommand.scrollTo) && Utils.isFunc(oCommand.scrollTo.subscribe)) { oCommand.scrollTo.subscribe(function () { if (jqElement.data('customscroll')) { jqElement.data('customscroll')['scrollTo'](oCommand.scrollTo()); } }); } }, 'update': bMobileApp ? null : function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { if (bMobileDevice) { return; } if (oElement._customscroll_reset) { oElement._customscroll_reset(); } if (!Utils.isUnd(fValueAccessor().top)) { $(oElement).data('customscroll')['vertical'].set(fValueAccessor().top); } } }; /*jslint vars: true*/ ko.bindingHandlers.customOptions = { 'init': function () { return { 'controlsDescendantBindings': true }; }, 'update': function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { var i = 0, j = 0; var previousSelectedValues = ko.utils.arrayMap(ko.utils.arrayFilter(element.childNodes, function (node) { return node.tagName && node.tagName === 'OPTION' && node.selected; }), function (node) { return ko.selectExtensions.readValue(node) || node.innerText || node.textContent; }); var previousScrollTop = element.scrollTop; var value = ko.utils.unwrapObservable(valueAccessor()); // Remove all existing <option>s. while (element.length > 0) { ko.cleanNode(element.options[0]); element.remove(0); } if (value) { if (typeof value.length !== 'number') { value = [value]; } var optionsBind = allBindingsAccessor()['optionsBind']; for (i = 0, j = value.length; i < j; i++) { var option = document.createElement('OPTION'); var optionValue = ko.utils.unwrapObservable(value[i]); ko.selectExtensions.writeValue(option, optionValue); option.appendChild(document.createTextNode(optionValue)); element.appendChild(option); if (optionsBind) { option.setAttribute('data-bind', optionsBind); ko.applyBindings(bindingContext['createChildContext'](optionValue), option); } } var newOptions = element.getElementsByTagName('OPTION'); var countSelectionsRetained = 0; var isIe = navigator.userAgent.indexOf("MSIE 6") >= 0; for (i = 0, j = newOptions.length; i < j; i++) { if (ko.utils.arrayIndexOf(previousSelectedValues, ko.selectExtensions.readValue(newOptions[i])) >= 0) { if (isIe) { newOptions[i].setAttribute("selected", true); } else { newOptions[i].selected = true; } countSelectionsRetained++; } } element.scrollTop = previousScrollTop; if (countSelectionsRetained < previousSelectedValues.length) { ko.utils.triggerEvent(element, 'change'); } } } }; /*jslint vars: false*/ ko.bindingHandlers.splitter = { 'init': bMobileApp ? null : function (oElement, fValueAccessor) { var jqElement = $(oElement), oCommand = fValueAccessor() //fResizeTo = oCommand.resizeTo ; setTimeout(function(){ jqElement.splitter(_.defaults( oCommand, { //'name': '' //'sizeLeft': 200, //'minLeft': 20, //'minRight': 40 } )); /*if (fResizeTo) { fResizeTo.subscribe(function (nSize) { if (nSize) { jqElement.trigger('resize', [nSize]); } }, this); }*/ }, 1); } }; ko.bindingHandlers.dropdown = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { var jqElement = $(oElement), oCommand = _.defaults( fValueAccessor(), { 'disabled': 'disabled', 'expand': 'expand', 'control': true, 'container': '.dropdown_content', 'scrollToTopContainer': '.scroll-inner', 'passClick': true, 'trueValue': true } ), element = oCommand['control'] ? jqElement.find('.control') : jqElement, jqDropHelper = jqElement.find('.dropdown_helper'), jqDropArrow = jqElement.find('.dropdown_arrow'), oDocument = $(document), bScrollBar = false, oOffset, iLeft, iFitToScreenOffset, fCallback = function () { if (!Utils.isUnd(oCommand['callback'])) { oCommand['callback'].call( oViewModel, jqElement.hasClass(oCommand['expand']) ? oCommand['trueValue'] : false, jqElement ); } }, fStop = function (event) { event.stopPropagation(); }, fScrollToTop = function () { if (oCommand['scrollToTopContainer']) { jqElement.find(oCommand['scrollToTopContainer']).scrollTop(0); } }, fToggleExpand = function (bValue) { if (Utils.isUnd(bValue)) { bValue = !jqElement.hasClass(oCommand['expand']); } if (!bValue && jqElement.hasClass(oCommand['expand'])) { fScrollToTop(); } jqElement.toggleClass(oCommand['expand'], bValue); }, fFitToScreen = function (iOffsetLeft) { oOffset = jqDropHelper.offset(); if (!Utils.isUnd(oOffset)) { iLeft = oOffset.left + 10; iFitToScreenOffset = $(window).width() - (iLeft + jqDropHelper.outerWidth()); if (iFitToScreenOffset > 0) { iFitToScreenOffset = 0; } jqDropHelper.css('left', iOffsetLeft || iFitToScreenOffset + 'px'); jqDropArrow.css('left', iOffsetLeft || Math.abs(iFitToScreenOffset ? iFitToScreenOffset + parseInt(jqDropArrow.css('margin-left')) : 0) + 'px'); } } ; if (!oCommand['passClick']) { jqElement.find(oCommand['container']).click(fStop); element.click(fStop); } fToggleExpand(false); if (oCommand['close'] && oCommand['close']['subscribe']) { oCommand['close'].subscribe(function (bValue) { if (!bValue) { oDocument.unbind('click.dropdown'); fToggleExpand(false); } fCallback(); }); } jqElement.on('mousedown', function(oEv, oEl) { bScrollBar = ($(oEv.target).hasClass('customscroll-scrollbar') || $(oEv.target.parentElement).hasClass('customscroll-scrollbar')); }); //TODO fix data-bind click element.click(function(oEv){ if (!jqElement.hasClass(oCommand['disabled']) && !bScrollBar) { fToggleExpand(); _.defer(function(){ fCallback(); }); if (jqElement.hasClass(oCommand['expand'])) { if (oCommand['close'] && oCommand['close']['subscribe']) { oCommand['close'](true); } _.defer(function(){ oDocument.on('click.dropdown', function (ev) { if((oCommand['passClick'] || ev.button !== Enums.MouseKey.Right) && !bScrollBar) { oDocument.unbind('click.dropdown'); if (oCommand['close'] && oCommand['close']['subscribe']) { oCommand['close'](false); } fToggleExpand(false); fCallback(); fFitToScreen(0); } bScrollBar = false; }); }); fFitToScreen(); } } }); } }; ko.bindingHandlers.customSelect = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { var jqElement = $(oElement), oCommand = _.defaults( fValueAccessor(), { 'disabled': 'disabled', 'selected': 'selected', 'expand': 'expand', 'control': true, 'input': false, 'expandState': function () {} } ), aOptions = [], oControl = oCommand['control'] ? jqElement.find('.control') : jqElement, oContainer = jqElement.find('.dropdown_content'), oText = jqElement.find('.link'), updateField = function (value) { _.each(aOptions, function (item) { item.removeClass(oCommand['selected']); }); var item = _.find(oCommand['options'], function (item) { return item[oCommand['optionsValue']] === value; }); if (Utils.isUnd(item)) { item = oCommand['options'][0]; } else { aOptions[_.indexOf(oCommand['options'], item)].addClass(oCommand['selected']); oText.text($.trim(item[oCommand['optionsText']])); } // aOptions[_.indexOf(oCommand['options'], item)].addClass(oCommand['selected']); // oText.text($.trim(item[oCommand['optionsText']])); return item[oCommand['optionsValue']]; }, updateList = function (aList) { oContainer.empty(); aOptions = []; _.each(aList ? aList : oCommand['options'], function (item) { var oOption = $('<span class="item"></span>') .text(item[oCommand['optionsText']]) .data('value', item[oCommand['optionsValue']]), isDisabled = item['isDisabled'] ; if (isDisabled) { oOption.data('isDisabled', isDisabled).addClass('disabled'); } else { oOption.data('isDisabled', isDisabled).removeClass('disabled'); } aOptions.push(oOption); oContainer.append(oOption); }, this); } ; updateList(); oContainer.on('click', '.item', function () { var jqItem = $(this); if(!jqItem.data('isDisabled')) { oCommand.value(jqItem.data('value')); } }); if (!oCommand.input && oCommand['value'] && oCommand['value'].subscribe) { oCommand['value'].subscribe(function () { var mValue = updateField(oCommand['value']()); if (oCommand['value']() !== mValue) { oCommand['value'](mValue); } }, oViewModel); oCommand['value'].valueHasMutated(); } if (oCommand.input && oCommand['value'] && oCommand['value'].subscribe) { oCommand['value'].subscribe(function () { updateField(oCommand['value']()); }, oViewModel); oCommand['value'].valueHasMutated(); } if (oCommand.input && oCommand['value'] && oCommand['value'].subscribe) { oCommand['value'].subscribe(function () { updateField(oCommand['value']()); }, oViewModel); oCommand['value'].valueHasMutated(); } if(oCommand.alarmOptions) { oCommand.alarmOptions.subscribe(function () { updateList(); }, oViewModel); } if(oCommand.timeOptions) { oCommand.timeOptions.subscribe(function (aList) { updateList(aList); }, oViewModel); } //TODO fix data-bind click jqElement.removeClass(oCommand['expand']); oControl.click(function(ev){ if (!jqElement.hasClass(oCommand['disabled'])) { jqElement.toggleClass(oCommand['expand']); oCommand['expandState'](jqElement.hasClass(oCommand['expand'])); if (jqElement.hasClass(oCommand['expand'])) { var jqContent = jqElement.find('.dropdown_content'), jqSelected = jqContent.find('.selected'); if (jqSelected.position()) { jqContent.scrollTop(0);// need for proper calculation position().top jqContent.scrollTop(jqSelected.position().top - 100);// 100 - hardcoded indent to the element in pixels } _.defer(function(){ $(document).one('click', function () { jqElement.removeClass(oCommand['expand']); oCommand['expandState'](false); }); }); } // else // { // jqElement.addClass(oCommand['expand']); // } } }); } }; ko.bindingHandlers.moveToFolderFilter = { 'init': function (oElement, fValueAccessor, allBindingsAccessor, viewModel, bindingContext) { var jqElement = $(oElement), oCommand = fValueAccessor(), jqContainer = $(oElement).find(oCommand['container']), aOptions = _.isArray(oCommand['options']) ? oCommand['options'] : oCommand['options'](), sFolderName = oCommand['value'] ? oCommand['value']() : '', oFolderOption = _.find(aOptions, function (oOption) { return oOption[oCommand['optionsValue']] === sFolderName; }) ; if (!oFolderOption) { sFolderName = ''; oCommand['value'](''); } jqElement.removeClass('expand'); jqContainer.empty(); _.each(aOptions, function (oOption) { var jqOption = $('<span class="item"></span>') .text(oOption[oCommand['optionsText']]) .data('value', oOption[oCommand['optionsValue']]); if (sFolderName === oOption[oCommand['optionsValue']]) { jqOption.addClass('selected'); } oOption['jq'] = jqOption; jqContainer.append(jqOption); }); jqContainer.on('click', '.item', function () { var sFolderName = $(this).data('value'); oCommand['value'](sFolderName); }); jqElement.click(function () { jqElement.toggleClass('expand'); if (jqElement.hasClass('expand')) { _.defer(function () { $(document).one('click', function () { jqElement.removeClass('expand'); }); }); } }); }, 'update': function (oElement, fValueAccessor) { var jqElement = $(oElement), oCommand = fValueAccessor(), aOptions = _.isArray(oCommand['options']) ? oCommand['options'] : oCommand['options'](), sFolderName = oCommand['value'] ? oCommand['value']() : '', oFolderOption = _.find(aOptions, function (oOption) { return oOption[oCommand['optionsValue']] === sFolderName; }), jqText = jqElement.find('.link') ; _.each(aOptions, function (oOption) { if (oOption['jq']) { oOption['jq'].toggleClass('selected', sFolderName === oOption[oCommand['optionsValue']]); } }); if (oFolderOption) { jqText.text($.trim(oFolderOption[oCommand['optionsText']])); } } }; ko.bindingHandlers.contactcard = { 'init': bMobileApp ? null : function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { var jqElement = $(oElement), bShown = false, oCommand = _.defaults( fValueAccessor(), { 'disabled': 'disabled', 'expand': 'expand', 'control': true } ), element = oCommand['control'] ? jqElement.find('.control') : jqElement ; if (oCommand['trigger'] !== undefined && oCommand['trigger'].subscribe !== undefined) { jqElement.removeClass(oCommand['expand']); element.bind({ 'mouseover': function() { if (!jqElement.hasClass(oCommand['disabled']) && oCommand['trigger']()) { bShown = true; _.delay(function () { if (bShown) { if (oCommand['controlWidth'] !== undefined && oCommand['controlWidth'].subscribe !== undefined) { oCommand['controlWidth'](element.width()); } jqElement.addClass(oCommand['expand']); } }, 200); } }, 'mouseout': function() { if (oCommand['trigger']()) { bShown = false; _.delay(function () { if (!bShown) { jqElement.removeClass(oCommand['expand']); } }, 200); } } }); } } }; ko.bindingHandlers.checkmail = { 'update': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { var oOptions = oElement.oOptions || null, jqElement = oElement.jqElement || null, oIconIE = oElement.oIconIE || null, values = fValueAccessor(), state = values.state ; if (values.state !== undefined) { if (!jqElement) { oElement.jqElement = jqElement = $(oElement); } if (!oOptions) { oElement.oOptions = oOptions = _.defaults( values, { 'activeClass': 'process', 'duration': 800 } ); } Utils.deferredUpdate(jqElement, state, oOptions['duration'], function(element, state){ if (App.browser.ie9AndBelow) { if (!oIconIE) { oElement.oIconIE = oIconIE = jqElement.find('.icon'); } if (!oIconIE.__intervalIE && !!state) { var i = 0, style = '' ; oIconIE.__intervalIE = setInterval(function() { style = '0px -' + (20 * i) + 'px'; i = i < 7 ? i + 1 : 0; oIconIE.css({'background-position': style}); } , 1000/12); } else { oIconIE.css({'background-position': '0px 0px'}); clearInterval(oIconIE.__intervalIE); oIconIE.__intervalIE = null; } } else { element.toggleClass(oOptions['activeClass'], state); } }); } } }; ko.bindingHandlers.heightAdjust = { 'update': function (oElement, fValueAccessor, fAllBindingsAccessor) { var jqElement = oElement.jqElement || null, height = 0, sLocation = fValueAccessor().location, sDelay = fValueAccessor().delay || 400 ; if (!jqElement) { oElement.jqElement = jqElement = $(oElement); } _.delay(function () { _.each(fValueAccessor().elements, function (mItem) { var element = mItem(); if (element) { height += element.is(':visible') ? element.outerHeight() : 0; } }); if (sLocation === 'top' || sLocation === undefined) { jqElement.css({ 'padding-top': height, 'margin-top': -height }); } else if (sLocation === 'bottom') { jqElement.css({ 'padding-bottom': height, 'margin-bottom': -height }); } }, sDelay); } }; ko.bindingHandlers.triggerInview = { 'update': function (oElement, fValueAccessor) { if (fValueAccessor().trigger().length <= 0 ) { return; } _.defer(function () { var $element = $(oElement), frameHeight = $element.height(), oCommand = fValueAccessor(), elements = null, delayedScroll = null ; oCommand = /** @type {{selector:string}}*/ oCommand; elements = $element.find(oCommand.selector); elements.each(function () { this.$el = $(this); this.inviewHeight = this.$el.height(); this.inview = false; }); delayedScroll = _.debounce(function () { elements.each(function () { var inview = this.inview || false, elOffset = this.$el.position().top + parseInt(this.$el.css('margin-top'), 10) ; if (elOffset > 0 && elOffset < frameHeight) { if (!inview) { this.inview = true; this.$el.trigger('inview'); } } else { this.inview = false; } }); }, 2000); $element.scroll(delayedScroll); delayedScroll(); }); } }; ko.bindingHandlers.watchWidth = { 'init': function (oElement, fValueAccessor) { var isTriggered = false; if (!isTriggered) { fValueAccessor().subscribe(function () { fValueAccessor()($(oElement).outerWidth()); isTriggered = true; }, this); } } }; ko.bindingHandlers.columnCalc = { 'init': function (oElement, fValueAccessor) { var $oElement = $(oElement), oProp = fValueAccessor()['prop'], $oItem = null, iWidth = 0 ; $oItem = $oElement.find(fValueAccessor()['itemSelector']); if ($oItem[0] === undefined) { return; } iWidth = $oItem.outerWidth(true); iWidth = 1 >= iWidth ? 1 : iWidth; if (oProp) { $(window).bind('resize', function () { var iW = $oElement.width(); oProp(0 < iW ? Math.floor(iW / iWidth) : 1); }); } } }; ko.bindingHandlers.quickReplyAnim = { 'update': bMobileApp ? null : function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { var jqTextarea = oElement.jqTextarea || null, jqStatus = oElement.jqStatus || null, jqButtons = oElement.jqButtons || null, jqElement = oElement.jqElement || null, oPrevActions = oElement.oPrevActions || null, values = fValueAccessor(), oActions = null ; oActions = _.defaults( values, { 'saveAction': false, 'sendAction': false, 'activeAction': false } ); if (!jqElement) { oElement.jqElement = jqElement = $(oElement); oElement.jqTextarea = jqTextarea = jqElement.find('textarea'); oElement.jqStatus = jqStatus = jqElement.find('.status'); oElement.jqButtons = jqButtons = jqElement.find('.buttons'); oElement.oPrevActions = oPrevActions = { 'saveAction': null, 'sendAction': null, 'activeAction': null }; } if (jqElement.is(':visible')) { if (App.browser.ie9AndBelow) { if (jqTextarea && !jqElement.defualtHeight && !jqTextarea.defualtHeight) { jqElement.defualtHeight = jqElement.outerHeight(); jqTextarea.defualtHeight = jqTextarea.outerHeight(); jqStatus.defualtHeight = jqButtons.outerHeight(); jqButtons.defualtHeight = jqButtons.outerHeight(); } _.defer(function () { var activeChanged = oPrevActions.activeAction !== oActions['activeAction'], sendChanged = oPrevActions.sendAction !== oActions['sendAction'], saveChanged = oPrevActions.saveAction !== oActions['saveAction'] ; if (activeChanged) { if (oActions['activeAction']) { jqTextarea.animate({ 'height': jqTextarea.defualtHeight + 50 }, 300); jqElement.animate({ 'max-height': jqElement.defualtHeight + jqButtons.defualtHeight + 50 }, 300); } else { jqTextarea.animate({ 'height': jqTextarea.defualtHeight }, 300); jqElement.animate({ 'max-height': jqElement.defualtHeight }, 300); } } if (sendChanged || saveChanged) { if (oActions['sendAction']) { jqElement.animate({ 'max-height': '30px' }, 300); jqStatus.animate({ 'max-height': '30px', 'opacity': 1 }, 300); } else if (oActions['saveAction']) { jqElement.animate({ 'max-height': 0 }, 300); } else { jqElement.animate({ 'max-height': jqElement.defualtHeight + jqButtons.defualtHeight + 50 }, 300); jqStatus.animate({ 'max-height': 0, 'opacity': 0 }, 300); } } }); } else { jqElement.toggleClass('saving', oActions['saveAction']); jqElement.toggleClass('sending', oActions['sendAction']); jqElement.toggleClass('active', oActions['activeAction']); } } _.defer(function () { oPrevActions = oActions; }); } }; ko.extenders.reversible = function (oTarget) { var mValue = oTarget(); oTarget.commit = function () { mValue = oTarget(); }; oTarget.revert = function () { oTarget(mValue); }; oTarget.commitedValue = function () { return mValue; }; oTarget.changed = function () { return mValue !== oTarget(); }; return oTarget; }; ko.extenders.autoResetToFalse = function (oTarget, iOption) { oTarget.iTimeout = 0; oTarget.subscribe(function (bValue) { if (bValue) { window.clearTimeout(oTarget.iTimeout); oTarget.iTimeout = window.setTimeout(function () { oTarget.iTimeout = 0; oTarget(false); }, Utils.pInt(iOption)); } }); return oTarget; }; /** * @param {(Object|null|undefined)} oContext * @param {Function} fExecute * @param {(Function|boolean|null)=} fCanExecute * @return {Function} */ Utils.createCommand = function (oContext, fExecute, fCanExecute) { var fResult = fExecute ? function () { if (fResult.canExecute && fResult.canExecute()) { return fExecute.apply(oContext, Array.prototype.slice.call(arguments)); } return false; } : function () {} ; fResult.enabled = ko.observable(true); fCanExecute = Utils.isUnd(fCanExecute) ? true : fCanExecute; if (Utils.isFunc(fCanExecute)) { fResult.canExecute = ko.computed(function () { return fResult.enabled() && fCanExecute.call(oContext); }); } else { fResult.canExecute = ko.computed(function () { return fResult.enabled() && !!fCanExecute; }); } return fResult; }; ko.bindingHandlers.autocomplete = { 'init': function (oElement, fValueAccessor) { function split(val) { return val.split(/,\s*/); } function extractLast(term) { return split(term).pop(); } var fCallback = fValueAccessor(), oJqElement = $(oElement) ; if (fCallback && oJqElement && oJqElement[0]) { oJqElement.autocomplete({ 'minLength': 1, 'autoFocus': true, 'source': function (request, response) { fCallback(extractLast(request['term']), response); }, 'search': function () { var term = extractLast(this.value); if (term.length < 1) { return false; } return true; }, 'focus': function () { return false; }, 'select': function (event, ui) { var terms = split(this.value), moveCursorToEnd = null; terms.pop(); terms.push(ui['item']['value']); terms.push(''); this.value = terms.join(', ').slice(0, -2); oJqElement.trigger('change'); // Move to the end of the input string moveCursorToEnd = function(el) { var endIndex = el.value.length; //Chrome el.blur(); el.focus(); //IE, firefox and Opera if (el.setSelectionRange) { el.setSelectionRange(endIndex, endIndex); } }; moveCursorToEnd(oJqElement[0]); return false; } }); } } }; ko.bindingHandlers.autocompleteSimple = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { var jqEl = $(oElement), oOptions = fValueAccessor(), fCallback = oOptions['callback'], fDataAccessor = oOptions.dataAccessor // fAutocompleteTrigger = oOptions.autocompleteTrigger ; if (fCallback && jqEl && jqEl[0]) { jqEl.autocomplete({ 'minLength': 1, 'autoFocus': true, 'position': { collision: "flip" }, 'source': function (request, response) { fCallback(request['term'], response); }, 'focus': function () { return false; }, 'select': function (oEvent, oItem) { _.delay(function () { jqEl.trigger('change'); }, 5); if (fDataAccessor) { fDataAccessor(oItem.item); } return true; } }); /*if (fAutocompleteTrigger) { fAutocompleteTrigger.subscribe(function() { jqEl.autocomplete( "option", "minLength", 0 );// dirty hack for trigger search jqEl.autocomplete("search"); jqEl.autocomplete( "option", "minLength", 1 ); }, this); }*/ } } }; ko.bindingHandlers.draggablePlace = { 'init': bMobileApp ? null : function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { if (fValueAccessor() === null) { return null; } var oAllBindingsAccessor = fAllBindingsAccessor ? fAllBindingsAccessor() : null; $(oElement).draggable({ 'distance': 20, 'handle': '.dragHandle', 'cursorAt': {'top': 0, 'left': 0}, 'helper': function (oEvent) { return fValueAccessor().call(oViewModel, oEvent && oEvent.target ? ko.dataFor(oEvent.target) : null); }, 'start': (oAllBindingsAccessor && oAllBindingsAccessor['draggableDragStartCallback']) ? oAllBindingsAccessor['draggableDragStartCallback'] : Utils.emptyFunction, 'stop': (oAllBindingsAccessor && oAllBindingsAccessor['draggableDragStopCallback']) ? oAllBindingsAccessor['draggableDragStopCallback'] : Utils.emptyFunction }).on('mousedown', function () { Utils.removeActiveFocus(); }); } }; ko.bindingHandlers.droppable = { 'init': bMobileApp ? null : function (oElement, fValueAccessor) { var oOptions = fValueAccessor(), fValueFunc = oOptions.valueFunc, fSwitchObserv = oOptions.switchObserv ; if (false !== fValueFunc) { $(oElement).droppable({ 'hoverClass': 'droppableHover', 'drop': function (oEvent, oUi) { fValueFunc(oEvent, oUi); } }); } if(fSwitchObserv && fValueFunc !== false) { fSwitchObserv.subscribe(function (bIsSelected) { if($(oElement).data().droppable) { if(bIsSelected) { $(oElement).droppable('disable'); } else { $(oElement).droppable('enable'); } } }, this); fSwitchObserv.valueHasMutated(); } } }; ko.bindingHandlers.draggable = { 'init': bMobileApp ? null : function (oElement, fValueAccessor) { $(oElement).attr('draggable', ko.utils.unwrapObservable(fValueAccessor())); } }; ko.bindingHandlers.autosize = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { var jqEl = $(oElement), oOptions = fValueAccessor(), iHeight = jqEl.height(), iOuterHeight = jqEl.outerHeight(), iInnerHeight = jqEl.innerHeight(), iBorder = iOuterHeight - iInnerHeight, iPaddingTB = iInnerHeight - iHeight, iMinHeight = oOptions.minHeight ? oOptions.minHeight : 0, iMaxHeight = oOptions.maxHeight ? oOptions.maxHeight : 0, iScrollableHeight = oOptions.scrollableHeight ? oOptions.scrollableHeight : 1000,// max-height of .scrollable_field oAutosizeTrigger = oOptions.autosizeTrigger ? oOptions.autosizeTrigger : null, /** * @param {boolean=} bIgnoreScrollableHeight */ fResize = function (bIgnoreScrollableHeight) { var iPadding = 0; if (App.browser.firefox) { iPadding = parseInt(jqEl.css('padding-top'), 10) * 2; } if (iMaxHeight) { /* 0-timeout to get the already changed text */ setTimeout(function () { if (jqEl.prop('scrollHeight') < iMaxHeight) { jqEl.height(iMinHeight - iPaddingTB - iBorder); jqEl.height(jqEl.prop('scrollHeight') + iPadding - iPaddingTB); } else { jqEl.height(iMaxHeight - iPaddingTB - iBorder); } }, 100); } else if (bIgnoreScrollableHeight || jqEl.prop('scrollHeight') < iScrollableHeight) { setTimeout(function () { jqEl.height(iMinHeight - iPaddingTB - iBorder); jqEl.height(jqEl.prop('scrollHeight') + iPadding - iPaddingTB); //$('.calendar_event .scrollable_field').scrollTop(jqEl.height('scrollHeight')) }, 100); } } ; jqEl.on('keydown', function(oEvent, oData) { fResize(); }); jqEl.on('paste', function(oEvent, oData) { fResize(); }); /*jqEl.on('input', function(oEvent, oData) { fResize(); }); ko.bindingHandlers.event.init(oElement, function () { return { 'keydown': function (oData, oEvent) { fResize(); return true; } }; }, fAllBindingsAccessor, oViewModel);*/ if (oAutosizeTrigger) { oAutosizeTrigger.subscribe(function (arg) { fResize(arg); }, this); } fResize(); } }; ko.bindingHandlers.customBind = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { var oOptions = fValueAccessor(), oKeydown = oOptions.onKeydown ? oOptions.onKeydown : null, oKeyup = oOptions.onKeyup ? oOptions.onKeyup : null, oPaste = oOptions.onPaste ? oOptions.onPaste : null, oInput = oOptions.onInput ? oOptions.onInput : null, oValueObserver = oOptions.valueObserver ? oOptions.valueObserver : null ; ko.bindingHandlers.event.init(oElement, function () { return { 'keydown': function (oData, oEvent) { if(oKeydown) { oKeydown.call(this, oElement, oEvent, oValueObserver); } return true; }, 'keyup': function (oData, oEvent) { if(oKeyup) { oKeyup.call(this, oElement, oEvent, oValueObserver); } return true; }, 'paste': function (oData, oEvent) { if(oPaste) { oPaste.call(this, oElement, oEvent, oValueObserver); } return true; }, 'input': function (oData, oEvent) { if(oInput) { oInput.call(this, oElement, oEvent, oValueObserver); } return true; } }; }, fAllBindingsAccessor, oViewModel); } }; ko.bindingHandlers.fade = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { var jqEl = $(oElement), jqElFaded = $('<span class="faded"></span>'), oOptions = _.defaults( fValueAccessor(), { 'color': null, 'css': 'fadeout' } ), oColor = oOptions.color, sCss = oOptions.css, updateColor = function (sColor) { if (sColor === '') { return; } var oHex2Rgb = hex2Rgb(sColor), sRGBColor = "rgba("+oHex2Rgb.r+","+oHex2Rgb.g+","+oHex2Rgb.b ; colorIt(sColor, sRGBColor); }, hex2Rgb = function (sHex) { // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i, result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(sHex) ; sHex = sHex.replace(shorthandRegex, function(m, r, g, b) { return r + r + g + g + b + b; }); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16) } : null; }, colorIt = function (hex, rgb) { if (Utils.isRTL()) { jqElFaded .css("filter", "progid:DXImageTransform.Microsoft.gradient(startColorstr='" + hex + "', endColorstr='" + hex + "',GradientType=1 )") .css("background-image", "-webkit-gradient(linear, left top, right top, color-stop(0%," + rgb + ",1)" + "), color-stop(100%," + rgb + ",0)" + "))") .css("background-image", "-moz-linear-gradient(left, " + rgb + ",1)" + "0%, " + rgb + ",0)" + "100%)") .css("background-image", "-webkit-linear-gradient(left, " + rgb + "1)" + "0%," + rgb + ",0)" + "100%)") .css("background-image", "-o-linear-gradient(left, " + rgb + ",1)" + "0%," + rgb + ",0)" + "100%)") .css("background-image", "-ms-linear-gradient(left, " + rgb + ",1)" + "0%," + rgb + ",0)" + "100%)") .css("background-image", "linear-gradient(left, " + rgb + ",1)" + "0%," + rgb + ",0)" + "100%)"); } else { jqElFaded .css("filter", "progid:DXImageTransform.Microsoft.gradient(startColorstr='" + hex + "', endColorstr='" + hex + "',GradientType=1 )") .css("background-image", "-webkit-gradient(linear, left top, right top, color-stop(0%," + rgb + ",0)" + "), color-stop(100%," + rgb + ",1)" + "))") .css("background-image", "-moz-linear-gradient(left, " + rgb + ",0)" + "0%, " + rgb + ",1)" + "100%)") .css("background-image", "-webkit-linear-gradient(left, " + rgb + ",0)" + "0%," + rgb + ",1)" + "100%)") .css("background-image", "-o-linear-gradient(left, " + rgb + ",0)" + "0%," + rgb + ",1)" + "100%)") .css("background-image", "-ms-linear-gradient(left, " + rgb + ",0)" + "0%," + rgb + ",1)" + "100%)") .css("background-image", "linear-gradient(left, " + rgb + ",0)" + "0%," + rgb + ",1)" + "100%)"); } } ; jqEl.parent().addClass(sCss); jqEl.after(jqElFaded); if (oOptions.color.subscribe !== undefined) { updateColor(oColor()); oColor.subscribe(function (sColor) { updateColor(sColor); }, this); } } }; ko.bindingHandlers.highlighter = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { var jqEl = $(oElement), oOptions = fValueAccessor(), oValueObserver = oOptions.valueObserver ? oOptions.valueObserver : null, oHighlighterValueObserver = oOptions.highlighterValueObserver ? oOptions.highlighterValueObserver : null, oHighlightTrigger = oOptions.highlightTrigger ? oOptions.highlightTrigger : null, aHighlightWords = ['from:', 'to:', 'subject:', 'text:', 'email:', 'has:', 'date:', 'text:', 'body:'], rPattern = (function () { var sPatt = ''; $.each(aHighlightWords, function(i, oEl) { sPatt = (!i) ? (sPatt + '\\b' + oEl) : (sPatt + '|\\b' + oEl); }); return new RegExp('(' + sPatt + ')', 'g'); }()), fClear = function (sStr) { return sStr.replace(/\xC2\xA0/g, ' ').replace(/\xA0/g, ' ').replace(/[\s]+/g, ' '); }, iPrevKeyCode = -1, sUserLanguage = window.navigator.language || window.navigator.userLanguage, aTabooLang = ['zh', 'zh-TW', 'zh-CN', 'zh-HK', 'zh-SG', 'zh-MO', 'ja', 'ja-JP', 'ko', 'ko-KR', 'vi', 'vi-VN', 'th', 'th-TH'],// , 'ru', 'ru-RU' bHighlight = !_.include(aTabooLang, sUserLanguage) ; ko.bindingHandlers.event.init(oElement, function () { return { 'keydown': function (oData, oEvent) { return oEvent.keyCode !== Enums.Key.Enter; }, 'keyup': function (oData, oEvent) { var aMoveKeys = [Enums.Key.Left, Enums.Key.Right, Enums.Key.Home, Enums.Key.End], bMoveKeys = -1 !== Utils.inArray(oEvent.keyCode, aMoveKeys) ; if (!( // oEvent.keyCode === Enums.Key.Enter || oEvent.keyCode === Enums.Key.Shift || oEvent.keyCode === Enums.Key.Ctrl || // for international english ------------------------- oEvent.keyCode === Enums.Key.Dash || oEvent.keyCode === Enums.Key.Apostrophe || oEvent.keyCode === Enums.Key.Six && oEvent.shiftKey || // --------------------------------------------------- bMoveKeys || // ((oEvent.shiftKey || iPrevKeyCode === Enums.Key.Shift) && bMoveKeys) || ((oEvent.ctrlKey || iPrevKeyCode === Enums.Key.Ctrl) && oEvent.keyCode === Enums.Key.a) )) { oValueObserver(fClear(jqEl.text())); highlight(false); } iPrevKeyCode = oEvent.keyCode; return true; }, // firefox fix for html paste 'paste': function (oData, oEvent) { setTimeout(function () { oValueObserver(fClear(jqEl.text())); highlight(false); }, 0); return true; } }; }, fAllBindingsAccessor, oViewModel); // highlight on init setTimeout(function () { highlight(true); }, 0); function highlight(bNotRestoreSel) { if(bHighlight) { var iCaretPos = 0, sContent = jqEl.text(), aContent = sContent.split(rPattern), aDividedContent = [], sReplaceWith = '<span class="search_highlight"' + '>$&</span>' ; $.each(aContent, function (i, sEl) { if (_.any(aHighlightWords, function (oAnyEl) {return oAnyEl === sEl;})) { $.each(sEl, function (i, sElem) { aDividedContent.push($(sElem.replace(/(.)/, sReplaceWith))); }); } else { $.each(sEl, function(i, sElem) { if(sElem === ' ') { // space fix for firefox aDividedContent.push(document.createTextNode('\u00A0')); } else { aDividedContent.push(document.createTextNode(sElem)); } }); } }); if (bNotRestoreSel) { jqEl.empty().append(aDividedContent); } else { iCaretPos = getCaretOffset(); jqEl.empty().append(aDividedContent); setCursor(iCaretPos); } } } function getCaretOffset() { var caretOffset = 0, range, preCaretRange, textRange, preCaretTextRange ; if (typeof window.getSelection !== "undefined") { range = window.getSelection().getRangeAt(0); preCaretRange = range.cloneRange(); preCaretRange.selectNodeContents(oElement); preCaretRange.setEnd(range.endContainer, range.endOffset); caretOffset = preCaretRange.toString().length; } else if (typeof document.selection !== "undefined" && document.selection.type !== "Control") { textRange = document.selection.createRange(); preCaretTextRange = document.body.createTextRange(); preCaretTextRange.moveToElementText(oElement); preCaretTextRange.setEndPoint("EndToEnd", textRange); caretOffset = preCaretTextRange.text.length; } return caretOffset; } function setCursor(iCaretPos) { var range, selection, textRange ; if (!oElement) { return false; } else if(document.createRange) { range = document.createRange(); range.selectNodeContents(oElement); range.setStart(oElement, iCaretPos); range.setEnd(oElement, iCaretPos); selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(range); } else if(oElement.createTextRange) { textRange = oElement.createTextRange(); textRange.collapse(true); textRange.moveEnd(iCaretPos); textRange.moveStart(iCaretPos); textRange.select(); return true; } else if(oElement.setSelectionRange) { oElement.setSelectionRange(iCaretPos, iCaretPos); return true; } return false; } oHighlightTrigger.notifySubscribers(); oHighlightTrigger.subscribe(function (bNotRestoreSel) { setTimeout(function () { highlight(!!bNotRestoreSel); }, 0); }, this); oHighlighterValueObserver.subscribe(function () { jqEl.text(oValueObserver()); }, this); } }; ko.bindingHandlers.quoteText = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { var jqEl = $(oElement), jqButton = $('<span class="button_quote">' + Utils.i18n('HELPDESK/BUTTON_QUOTE') + '</span>'), oOptions = fValueAccessor(), fActionHandler = oOptions.actionHandler, bIsQuoteArea = false, oSelection = null, sText = '' ; $('#pSevenContent').append(jqButton); $(document.body).on('click', function(oEvent) { bIsQuoteArea = !!(($(oEvent.target)).parents('.posts')[0]); if (document.getSelection) { oSelection = document.getSelection(); if (oSelection) { sText = oSelection.toString(); } } else { sText = document.selection.createRange().text; } if(bIsQuoteArea) { if(sText.replace(/[\n\r\s]/, '') !== '') //replace - for dbl click on empty area { jqButton.css({ 'top': oEvent.clientY + 20, //20 - custom indent 'left': oEvent.clientX + 20 }).show(); } else { jqButton.hide(); } } else { jqButton.hide(); } }); jqButton.on('click', function(oEvent) { fActionHandler.call(oViewModel, sText); }); } }; ko.bindingHandlers.adjustHeightToContent = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { var jqEl = $(oElement), jqTargetEl = null, jqParentEl = null, jqNearEl = null ; _.delay(_.bind(function(){ jqTargetEl = $(_.max(jqEl.find('.title .text'), function(domEl){ return domEl.offsetWidth; })); jqParentEl = jqTargetEl.parent(); jqNearEl = jqParentEl.find('.icon'); jqEl.css('min-width', parseInt(jqParentEl.css("margin-left")) + parseInt(jqParentEl.css("padding-left")) + parseInt(jqNearEl.width()) + parseInt(jqNearEl.css("margin-left")) + parseInt(jqNearEl.css("margin-right")) + parseInt(jqNearEl.css("padding-left")) + parseInt(jqNearEl.css("padding-right")) + parseInt(jqTargetEl.width()) + parseInt(jqTargetEl.css("margin-left")) + parseInt(jqTargetEl.css("padding-left")) + 10 ); },this), 1); } }; ko.bindingHandlers.customTooltip = { 'update': bMobileApp ? null : function (oElement, fValueAccessor) { var sTooltipText = Utils.i18n(fValueAccessor()); $(oElement).attr('title', sTooltipText); // var // sTooltipText = Utils.i18n(fValueAccessor()), // oDropdown = $(oElement).find('span.dropdown'), // bShown = false // ; // // if (sTooltipText === '') // { // $(oElement).hover(function () { // }, function () { // }); // } // else // { // $(oElement).hover(function () { // var $ItemToAlign = $(this); // bShown = true; // _.delay(function () { // if (bShown) // { // Utils.CustomTooltip.show(sTooltipText, $ItemToAlign); // } // }, 200); // }, function () { // bShown = false; // Utils.CustomTooltip.hide(); // }); // // if (oDropdown.length > 0) // { // oDropdown.hover(function () { // bShown = false; // Utils.CustomTooltip.hide(); // }, function () {}); // } // } } }; /** * @constructor */ function CRouting() { this.defaultScreen = Enums.Screens.Mailbox; this.currentScreen = Enums.Screens.Mailbox; this.lastMailboxHash = ko.observable(Enums.Screens.Mailbox); this.lastHelpdeskHash = ko.observable(Enums.Screens.Helpdesk); this.lastSettingsHash = ko.observable(Enums.Screens.Settings); this.currentHash = ko.observable(''); this.previousHash = ko.observable(''); } /** * Initializes object. * * @param {string} sDefaultScreen */ CRouting.prototype.init = function (sDefaultScreen) { this.defaultScreen = sDefaultScreen; hasher.initialized.removeAll(); hasher.changed.removeAll(); hasher.initialized.add(this.parseRouting, this); hasher.changed.add(this.parseRouting, this); hasher.init(); hasher.initialized.removeAll(); }; /** * Finalizes the object and puts an empty hash. */ CRouting.prototype.finalize = function () { hasher.dispose(); this.setHashFromString(''); }; /** * Sets a new hash. * * @param {string} sNewHash * * @return {boolean} */ CRouting.prototype.setHashFromString = function (sNewHash) { var bSame = (location.hash === decodeURIComponent(sNewHash)); if (!bSame) { location.hash = sNewHash; } return bSame; }; /** * Sets a new hash without part. * * @param {string} sHashPart */ CRouting.prototype.replaceHashWithoutPart = function (sHashPart) { var sNewHash = location.hash.replace(sHashPart, ''); this.replaceHashFromString(sNewHash); }; /** * Sets a new hash. * * @param {string} sNewHash */ CRouting.prototype.replaceHashFromString = function (sNewHash) { if (location.hash !== sNewHash) { location.replace(sNewHash); } }; /** * Sets a new hash made up of an array. * * @param {Array} aRoutingParts * * @return boolean */ CRouting.prototype.setHash = function (aRoutingParts) { return this.setHashFromString(this.buildHashFromArray(aRoutingParts)); }; /** * @param {Array} aRoutingParts */ CRouting.prototype.replaceHash = function (aRoutingParts) { this.replaceHashFromString(this.buildHashFromArray(aRoutingParts)); }; CRouting.prototype.setPreviousHash = function () { location.hash = this.previousHash(); }; /** * Makes a hash of a string array. * * @param {(string|Array)} aRoutingParts * * @return {string} */ CRouting.prototype.buildHashFromArray = function (aRoutingParts) { var iIndex = 0, iLen = 0, sHash = '' ; if (_.isArray(aRoutingParts)) { for (iLen = aRoutingParts.length; iIndex < iLen; iIndex++) { aRoutingParts[iIndex] = encodeURIComponent(aRoutingParts[iIndex]); } } else { aRoutingParts = [encodeURIComponent(aRoutingParts.toString())]; } sHash = aRoutingParts.join('/'); if (sHash !== '') { sHash = '#' + sHash; } return sHash; }; /** * Returns the value of the hash string of location.href. * location.hash returns the decoded string and location.href - not, so it uses location.href. * * @return {string} */ CRouting.prototype.getHashFromHref = function () { var iPos = location.href.indexOf('#'), sHash = '' ; if (iPos !== -1) { sHash = location.href.substr(iPos + 1); } return sHash; }; CRouting.prototype.isSingleMode = function () { var sScreen = this.getScreenFromHash(), bSingleMode = (sScreen === Enums.Screens.SingleMessageView || sScreen === Enums.Screens.SingleCompose || sScreen === Enums.Screens.SingleHelpdesk) ; this.currentScreen = sScreen; return bSingleMode; }; /** * @param {Array} aRoutingParts * @param {Array} aAddParams */ CRouting.prototype.goDirectly = function (aRoutingParts, aAddParams) { hasher.stop(); this.setHash(aRoutingParts); this.parseRouting(aAddParams); hasher.init(); }; /** * @param {string} sNeedScreen */ CRouting.prototype.historyBackWithoutParsing = function (sNeedScreen) { hasher.stop(); location.hash = this.currentHash(); hasher.init(); }; /** * @returns {String} */ CRouting.prototype.getScreenFromHash = function () { var sHash = this.getHashFromHref(), aHash = sHash.split('/') ; return decodeURIComponent(aHash.shift()) || this.defaultScreen; }; /** * @param {Array} aAddParams */ CRouting.prototype.parseRouting = function (aAddParams) { var oCurrentModel = App.Screens.getCurrentScreenModel(), fContinueScreenChanging = _.bind(this.chooseScreen, this, aAddParams) ; if (oCurrentModel && Utils.isFunc(oCurrentModel.beforeHide)) { oCurrentModel.beforeHide(fContinueScreenChanging); } else { fContinueScreenChanging(); } }; /** * Parses the hash string and opens the corresponding routing screen. * * @param {Array} aAddParams */ CRouting.prototype.chooseScreen = function (aAddParams) { var sHash = this.getHashFromHref(), aHash = sHash.split('/'), sScreen = decodeURIComponent(aHash.shift()) || this.defaultScreen, bScreenInEnum = _.find(Enums.Screens, function (sScreenInEnum) { return sScreenInEnum === sScreen; }, this), iIndex = 0, iLen = aHash.length ; if (sScreen === Enums.Screens.Mailbox) { this.lastMailboxHash(sHash); } if (sScreen === Enums.Screens.Helpdesk) { this.lastHelpdeskHash(sHash); } if (sScreen === Enums.Screens.Settings) { this.lastSettingsHash(sHash); } this.previousHash(this.currentHash()); this.currentHash(sHash); for (; iIndex < iLen; iIndex++) { aHash[iIndex] = decodeURIComponent(aHash[iIndex]); } if ($.isArray(aAddParams)) { aHash = _.union(aHash, aAddParams); } this.currentScreen = sScreen; switch (sScreen) { case Enums.Screens.SingleMessageView: case Enums.Screens.SingleCompose: case Enums.Screens.SingleHelpdesk: AppData.SingleMode = true; App.Screens.showCurrentScreen(sScreen, aHash); break; default: if (!bScreenInEnum) { sScreen = this.defaultScreen; } AppData.SingleMode = false; App.Screens.showNormalScreen(Enums.Screens.Header); App.Screens.showCurrentScreen(sScreen, aHash); break; case Enums.Screens.Mailbox: AppData.SingleMode = false; App.Screens.showNormalScreen(Enums.Screens.Header); App.Screens.showCurrentScreen(Enums.Screens.Mailbox, aHash); break; } }; /** * @constructor */ function CLinkBuilder() { } /** * @param {string=} sFolder = 'INBOX' * @param {number=} iPage = 1 * @param {string=} sUid = '' * @param {string=} sSearch = '' * @param {string=} sFilters = '' * @return {Array} */ CLinkBuilder.prototype.mailbox = function (sFolder, iPage, sUid, sSearch, sFilters) { var aResult = [Enums.Screens.Mailbox]; iPage = Utils.isNormal(iPage) ? Utils.pInt(iPage) : 1; sUid = Utils.isNormal(sUid) ? Utils.pString(sUid) : ''; sSearch = Utils.isNormal(sSearch) ? Utils.pString(sSearch) : ''; sFilters = Utils.isNormal(sFilters) ? Utils.pString(sFilters) : ''; if (sFolder && '' !== sFolder) { aResult.push(sFolder); } if (sFilters && '' !== sFilters) { aResult.push('filter:' + sFilters); } if (1 < iPage) { aResult.push('p' + iPage); } if (sUid && '' !== sUid) { aResult.push('msg' + sUid); } if (sSearch && '' !== sSearch) { aResult.push(sSearch); } return aResult; }; /** * @return {Array} */ CLinkBuilder.prototype.inbox = function () { return this.mailbox(); }; /** * @param {Array} aParams * * @return {Object} */ CLinkBuilder.prototype.parseMailbox = function (aParams) { var sFolder = 'INBOX', iPage = 1, sUid = '', sSearch = '', sFilters = '', sTemp = '', iIndex = 0 ; if (Utils.isNonEmptyArray(aParams)) { sFolder = Utils.pString(aParams[iIndex]); iIndex++; if (aParams.length > iIndex) { sTemp = Utils.pString(aParams[iIndex]); if (sTemp === 'filter:' + Enums.FolderFilter.Flagged) { sFilters = Enums.FolderFilter.Flagged; iIndex++; } if (sTemp === 'filter:' + Enums.FolderFilter.Unseen) { sFilters = Enums.FolderFilter.Unseen; iIndex++; } } if (aParams.length > iIndex) { sTemp = Utils.pString(aParams[iIndex]); if (this.isPageParam(sTemp)) { iPage = Utils.pInt(sTemp.substr(1)); if (iPage <= 0) { iPage = 1; } iIndex++; } } if (aParams.length > iIndex) { sTemp = Utils.pString(aParams[iIndex]); if (this.isMsgParam(sTemp)) { sUid = sTemp.substr(3); iIndex++; } } if (aParams.length > iIndex) { sSearch = Utils.pString(aParams[iIndex]); } } return { 'Folder': sFolder, 'Page': iPage, 'Uid': sUid, 'Search': sSearch, 'Filters': sFilters }; }; /** * @param {number=} iType * @param {string=} sGroupId * @param {string=} sSearch * @param {number=} iPage * @param {string=} sUid * @returns {Array} */ CLinkBuilder.prototype.contacts = function (iType, sGroupId, sSearch, iPage, sUid) { var aParams = [Enums.Screens.Contacts] ; if (typeof iType === 'number') { aParams.push(iType); } if (sGroupId && sGroupId !== '') { aParams.push(sGroupId); } if (sSearch && sSearch !== '') { aParams.push(sSearch); } if (Utils.isNumeric(iPage)) { aParams.push('p' + iPage); } if (sUid && sUid !== '') { aParams.push('cnt' + sUid); } return aParams; }; /** * @param {Array} aParam * * @return {Object} */ CLinkBuilder.prototype.parseContacts = function (aParam) { var iIndex = 0, aGroupTypes = [Enums.ContactsGroupListType.Personal, Enums.ContactsGroupListType.SharedToAll, Enums.ContactsGroupListType.Global, Enums.ContactsGroupListType.All], iType = Enums.ContactsGroupListType.All, sGroupId = '', sSearch = '', iPage = 1, sUid = '' ; if (Utils.isNonEmptyArray(aParam)) { iType = Utils.pInt(aParam[iIndex]); iIndex++; if (-1 === Utils.inArray(iType, aGroupTypes)) { iType = Enums.ContactsGroupListType.SubGroup; } if (iType === Enums.ContactsGroupListType.SubGroup) { if (aParam.length > iIndex) { sGroupId = Utils.pString(aParam[iIndex]); iIndex++; } else { iType = Enums.ContactsGroupListType.Personal; } } if (aParam.length > iIndex && !this.isPageParam(aParam[iIndex]) && !this.isContactParam(aParam[iIndex])) { sSearch = Utils.pString(aParam[iIndex]); iIndex++; } if (aParam.length > iIndex && this.isPageParam(aParam[iIndex])) { iPage = Utils.pInt(aParam[iIndex].substr(1)); iIndex++; if (iPage <= 0) { iPage = 1; } } if (aParam.length > iIndex && this.isContactParam(aParam[iIndex])) { sUid = Utils.pString(aParam[iIndex].substr(3)); iIndex++; } } return { 'Type': iType, 'GroupId': sGroupId, 'Search': sSearch, 'Page': iPage, 'Uid': sUid }; }; /** * @param {string} sTemp * * @return {boolean} */ CLinkBuilder.prototype.isPageParam = function (sTemp) { return ('p' === sTemp.substr(0, 1) && (/^[1-9][\d]*$/).test(sTemp.substr(1))); }; /** * @param {string} sTemp * * @return {boolean} */ CLinkBuilder.prototype.isContactParam = function (sTemp) { return ('cnt' === sTemp.substr(0, 3) && (/^[1-9][\d]*$/).test(sTemp.substr(3))); }; /** * @param {string} sTemp * * @return {boolean} */ CLinkBuilder.prototype.isMsgParam = function (sTemp) { return ('msg' === sTemp.substr(0, 3) && (/^[1-9][\d]*$/).test(sTemp.substr(3))); }; /** * @return {Array} */ CLinkBuilder.prototype.compose = function () { var sScreen = (AppData.SingleMode) ? Enums.Screens.SingleCompose : Enums.Screens.Compose; return [sScreen]; }; /** * @param {string} sType * @param {string} sFolder * @param {string} sUid * * @return {Array} */ CLinkBuilder.prototype.composeFromMessage = function (sType, sFolder, sUid) { var sScreen = (AppData.SingleMode) ? Enums.Screens.SingleCompose : Enums.Screens.Compose; return [sScreen, sType, sFolder, sUid]; }; /** * @param {string} sTo * * @return {Array} */ CLinkBuilder.prototype.composeWithToField = function (sTo) { var sScreen = (AppData.SingleMode) ? Enums.Screens.SingleCompose : Enums.Screens.Compose; return [sScreen, 'to', sTo]; }; /** * @param {?} mToAddr * @returns {Object} */ CLinkBuilder.prototype.parseToAddr = function (mToAddr) { var sToAddr = decodeURI(Utils.pString(mToAddr)), bHasMailTo = sToAddr.indexOf('mailto:') !== -1, aMailto = [], aMessageParts = [], sSubject = '', sCcAddr = '', sBccAddr = '', sBody = '' ; if (bHasMailTo) { aMailto = sToAddr.replace(/^mailto:/, '').split('?'); sToAddr = aMailto[0]; if (aMailto.length === 2) { aMessageParts = aMailto[1].split('&'); _.each(aMessageParts, function (sPart) { var aParts = sPart.split('=') ; if (aParts.length === 2) { switch (aParts[0]) { case 'subject': sSubject = aParts[1]; break; case 'cc': sCcAddr = aParts[1]; break; case 'bcc': sBccAddr = aParts[1]; break; case 'body': sBody = aParts[1]; break; } } }); } } return { 'to': sToAddr, 'hasMailto': bHasMailTo, 'subject': sSubject, 'cc': sCcAddr, 'bcc': sBccAddr, 'body': sBody }; }; /** * @constructor */ function CMessageSender() { this.replyText = ko.observable(''); this.replyDraftUid = ko.observable(''); this.postponedMailData = null; } /** * @param {string} sReplyText * @param {string} sDraftUid */ CMessageSender.prototype.setReplyData = function (sReplyText, sDraftUid) { this.replyText(sReplyText); this.replyDraftUid(sDraftUid); }; /** * @param {string} sAction * @param {Object} oParameters * @param {boolean} bSaveMailInSentItems * @param {boolean} bShowLoading * @param {Function} fMessageSendResponseHandler * @param {Object} oMessageSendResponseContext * @param {boolean=} bPostponedSending = false */ CMessageSender.prototype.send = function (sAction, oParameters, bSaveMailInSentItems, bShowLoading, fMessageSendResponseHandler, oMessageSendResponseContext, bPostponedSending) { var sLoadingMessage = '', sSentFolder = App.MailCache.folderList().sentFolderFullName(), sDraftFolder = App.MailCache.folderList().draftsFolderFullName(), sCurrEmail = AppData.Accounts.getCurrent().email(), bSelfRecipient = (oParameters.To.indexOf(sCurrEmail) > -1 || oParameters.Cc.indexOf(sCurrEmail) > -1 || oParameters.Bcc.indexOf(sCurrEmail) > -1) ; if (AppData.User.SaveRepliedToCurrFolder && !bSelfRecipient && Utils.isNonEmptyArray(oParameters.DraftInfo, 3)) { sSentFolder = oParameters.DraftInfo[2]; } oParameters.Action = sAction; oParameters.ShowReport = bShowLoading; switch (sAction) { case 'MessageSend': sLoadingMessage = Utils.i18n('COMPOSE/INFO_SENDING'); if (bSaveMailInSentItems) { oParameters.SentFolder = sSentFolder; } if (oParameters.DraftUid !== '') { oParameters.DraftFolder = sDraftFolder; } break; case 'MessageSave': sLoadingMessage = Utils.i18n('COMPOSE/INFO_SAVING'); oParameters.DraftFolder = sDraftFolder; break; } if (bShowLoading) { App.Api.showLoading(sLoadingMessage); } if (bPostponedSending) { this.postponedMailData = { 'Parameters': oParameters, 'MessageSendResponseHandler': fMessageSendResponseHandler, 'MessageSendResponseContext': oMessageSendResponseContext }; } else { App.Ajax.send(oParameters, fMessageSendResponseHandler, oMessageSendResponseContext); } }; /** * @param {string} sDraftUid */ CMessageSender.prototype.sendPostponedMail = function (sDraftUid) { var oData = this.postponedMailData, sDraftFolder = App.MailCache.folderList().draftsFolderFullName() ; if (sDraftUid !== '') { oData.Parameters.DraftUid = sDraftUid; oData.Parameters.DraftFolder = sDraftFolder; } if (this.postponedMailData) { App.Ajax.send(oData.Parameters, oData.MessageSendResponseHandler, oData.MessageSendResponseContext); this.postponedMailData = null; } }; /** * @param {string} sAction * @param {string} sText * @param {string} sDraftUid * @param {Function} fMessageSendResponseHandler * @param {Object} oMessageSendResponseContext * @param {boolean} bRequiresPostponedSending */ CMessageSender.prototype.sendReplyMessage = function (sAction, sText, sDraftUid, fMessageSendResponseHandler, oMessageSendResponseContext, bRequiresPostponedSending) { var oParameters = null, oFetcherOrIdentity = null, oMessage = App.MailCache.currentMessage(), bIsFetcherOrIdentitySameAsChiefAccount = false ; if (App.MailCache.currentMessage()) { oParameters = this.getReplyDataFromMessage( App.MailCache.currentMessage(), Enums.ReplyType.ReplyAll, AppData.Accounts.currentId(), App.MessageSender.getFetcherOrIdentityByRecipients(oMessage.oTo.aCollection.concat(oMessage.oCc.aCollection), oMessage.accountId()), false, sText, sDraftUid ); oFetcherOrIdentity = App.MessageSender.getFetcherOrIdentityByRecipients(oMessage.oTo.aCollection.concat(oMessage.oCc.aCollection), oMessage.accountId()); bIsFetcherOrIdentitySameAsChiefAccount = App.MessageSender.isFetcherOrIdentitySameAsChiefAccount(); if (oFetcherOrIdentity && !bIsFetcherOrIdentitySameAsChiefAccount) { oParameters.FetcherID = oFetcherOrIdentity && oFetcherOrIdentity.FETCHER ? oFetcherOrIdentity.id() : ''; oParameters.IdentityID = oFetcherOrIdentity && !oFetcherOrIdentity.FETCHER ? oFetcherOrIdentity.id() : ''; } oParameters.Bcc = ''; oParameters.Importance = Enums.Importance.Normal; oParameters.Sensivity = Enums.Sensivity.Nothing; oParameters.ReadingConfirmation = '0'; oParameters.IsQuickReply = '1'; oParameters.IsHtml = '1'; oParameters.Attachments = this.convertAttachmentsForSending(oParameters.Attachments); this.send(sAction, oParameters, AppData.User.getSaveMailInSentItems(), false, fMessageSendResponseHandler, oMessageSendResponseContext, bRequiresPostponedSending); } }; /** * @param {Array} aAttachments * * @return {Object} */ CMessageSender.prototype.convertAttachmentsForSending = function (aAttachments) { var oAttachments = {}; _.each(aAttachments, function (oAttach) { oAttachments[oAttach.tempName()] = [ oAttach.fileName(), oAttach.cid(), oAttach.inline() ? '1' : '0', oAttach.linked() ? '1' : '0', oAttach.contentLocation() ]; }); return oAttachments; }; /** * @param {Object} oResponse * @param {Object} oRequest * * @return {Object} */ CMessageSender.prototype.onMessageSendOrSaveResponse = function (oResponse, oRequest) { var oParentApp = (AppData.SingleMode) ? window.opener.App : App, bResult = !!oResponse.Result, sFullName, sUid, sReplyType ; App.Api.hideLoading(); switch (oRequest.Action) { case 'MessageSave': if (!bResult) { if (oRequest.ShowReport) { App.Api.showErrorByCode(oResponse, Utils.i18n('COMPOSE/ERROR_MESSAGE_SAVING')); } } else { if (oRequest.ShowReport) { App.Api.showReport(Utils.i18n('COMPOSE/REPORT_MESSAGE_SAVED')); } if (!oResponse.Result.NewUid) { AppData.User.AllowAutosaveInDrafts = false; } } break; case 'MessageSend': if (!bResult && oResponse.ErrorCode !== Enums.Errors.NotSavedInSentItems) { App.Api.showErrorByCode(oResponse, Utils.i18n('COMPOSE/ERROR_MESSAGE_SENDING')); } else { if (!bResult && oResponse.ErrorCode === Enums.Errors.NotSavedInSentItems) { App.Api.showError(Utils.i18n('WARNING/SENT_EMAIL_NOT_SAVED')); } else if (oRequest.IsQuickReply) { App.Api.showReport(Utils.i18n('COMPOSE/REPORT_MESSAGE_SENT')); } else { oParentApp.Api.showReport(Utils.i18n('COMPOSE/REPORT_MESSAGE_SENT')); } if (_.isArray(oRequest.DraftInfo) && oRequest.DraftInfo.length === 3) { sReplyType = oRequest.DraftInfo[0]; sUid = oRequest.DraftInfo[1]; sFullName = oRequest.DraftInfo[2]; App.MailCache.markMessageReplied(oRequest.AccountID, sFullName, sUid, sReplyType); } } if (oRequest.SentFolder) { oParentApp.MailCache.removeMessagesFromCacheForFolder(oRequest.SentFolder); } break; } if (oRequest.DraftFolder) { oParentApp.MailCache.removeMessagesFromCacheForFolder(oRequest.DraftFolder, oRequest.DraftUid); } return {Action: oRequest.Action, Result: bResult, NewUid: oResponse.Result ? oResponse.Result.NewUid : ''}; }; /** * @param {Object} oMessage * @param {string} sReplyType * @param {number} iAccountId * @param {Object} oFetcherOrIdentity * @param {boolean} bPasteSignatureAnchor * @param {string} sText * @param {string} sDraftUid * * @return {Object} */ CMessageSender.prototype.getReplyDataFromMessage = function (oMessage, sReplyType, iAccountId, oFetcherOrIdentity, bPasteSignatureAnchor, sText, sDraftUid) { var oReplyData = { DraftInfo: [], DraftUid: '', To: '', Cc: '', Bcc: '', Subject: '', Attachments: [], InReplyTo: oMessage.messageId(), References: this.getReplyReferences(oMessage) }, aAttachmentsLink = [], sToAddr = oMessage.oReplyTo.getFull(), sTo = oMessage.oTo.getFull() ; if (sToAddr === '' || oMessage.oFrom.getFirstEmail() === oMessage.oReplyTo.getFirstEmail() && oMessage.oReplyTo.getFirstName() === '') { sToAddr = oMessage.oFrom.getFull(); } if (!sText || sText === '') { sText = this.replyText(); this.replyText(''); } if (sReplyType === 'forward') { oReplyData.Text = sText + this.getForwardMessageBody(oMessage, iAccountId, oFetcherOrIdentity); } else if (sReplyType === 'resend') { oReplyData.Text = oMessage.getConvertedHtml(); oReplyData.Cc = oMessage.cc(); oReplyData.Bcc = oMessage.bcc(); } else { oReplyData.Text = sText + this._getReplyMessageBody(oMessage, iAccountId, oFetcherOrIdentity, bPasteSignatureAnchor); } if (sDraftUid) { oReplyData.DraftUid = sDraftUid; } else { oReplyData.DraftUid = this.replyDraftUid(); this.replyDraftUid(''); } switch (sReplyType) { case Enums.ReplyType.Reply: oReplyData.DraftInfo = [Enums.ReplyType.Reply, oMessage.uid(), oMessage.folder()]; oReplyData.To = sToAddr; oReplyData.Subject = this.subjectCompiler(oMessage.subject(), true); aAttachmentsLink = _.filter(oMessage.attachments(), function (oAttach) { return oAttach.linked(); }); break; case Enums.ReplyType.ReplyAll: oReplyData.DraftInfo = [Enums.ReplyType.ReplyAll, oMessage.uid(), oMessage.folder()]; oReplyData.To = sToAddr; oReplyData.Cc = this._getReplyAllCcAddr(oMessage, iAccountId, oFetcherOrIdentity); oReplyData.Subject = this.subjectCompiler(oMessage.subject(), true); aAttachmentsLink = _.filter(oMessage.attachments(), function (oAttach) { return oAttach.linked(); }); break; case Enums.ReplyType.Resend: oReplyData.DraftInfo = [Enums.ReplyType.Resend, oMessage.uid(), oMessage.folder(), oMessage.cc(), oMessage.bcc()]; oReplyData.To = sTo; oReplyData.Subject = oMessage.subject(); aAttachmentsLink = oMessage.attachments(); break; case Enums.ReplyType.Forward: oReplyData.DraftInfo = [Enums.ReplyType.Forward, oMessage.uid(), oMessage.folder()]; oReplyData.Subject = this.subjectCompiler(oMessage.subject(), false); aAttachmentsLink = oMessage.attachments(); break; } _.each(aAttachmentsLink, function (oAttachLink) { if (oAttachLink.getCopy) { var oCopy = oAttachLink.getCopy(), sThumbSessionUid = Date.now().toString() ; oCopy.getInThumbQueue(sThumbSessionUid); oReplyData.Attachments.push(oCopy); } }); return oReplyData; }; /** * Prepares and returns references for reply message. * * @param {Object} oMessage * * @return {string} */ CMessageSender.prototype.getReplyReferences = function (oMessage) { var sRef = oMessage.references(), sInR = oMessage.messageId(), sPos = sRef.indexOf(sInR) ; if (sPos === -1) { sRef += ' ' + sInR; } return sRef; }; /** * @param {Object} oMessage * @param {number} iAccountId * @param {Object} oFetcherOrIdentity * @param {boolean} bPasteSignatureAnchor * * @return {string} */ CMessageSender.prototype._getReplyMessageBody = function (oMessage, iAccountId, oFetcherOrIdentity, bPasteSignatureAnchor) { var sReplyTitle = Utils.i18n('COMPOSE/REPLY_MESSAGE_TITLE', { 'DATE': oMessage.oDateModel.getDate(), 'TIME': oMessage.oDateModel.getTime(), 'SENDER': Utils.encodeHtml(oMessage.oFrom.getFull()) }), sReplyBody = '<br /><br />' + this.getSignatureText(iAccountId, oFetcherOrIdentity, bPasteSignatureAnchor) + '<br /><br />' + '<div data-anchor="reply-title">' + sReplyTitle + '</div><blockquote>' + oMessage.getConvertedHtml() + '</blockquote>' ; return sReplyBody; }; /** * @param {number} iAccountId * @param {Object} oFetcherOrIdentity * * @return {string} */ CMessageSender.prototype.getClearSignature = function (iAccountId, oFetcherOrIdentity) { var oAccount = AppData.Accounts.getAccount(iAccountId), bUseSignature = !!(oFetcherOrIdentity ? (oFetcherOrIdentity.useSignature ? oFetcherOrIdentity.useSignature() : oFetcherOrIdentity.signatureOptions()) : true), sSignature = '' ; if (oAccount) { if (bUseSignature) { if (oFetcherOrIdentity && oFetcherOrIdentity.accountId() === oAccount.id()) { sSignature = oFetcherOrIdentity.signature(); } else { sSignature = (oAccount.signature() && parseInt(oAccount.signature().options())) ? oAccount.signature().signature() : ''; } } } return sSignature; }; /** * @param {number} iAccountId * @param {Object} oFetcherOrIdentity * @param {boolean} bPasteSignatureAnchor * * @return {string} */ CMessageSender.prototype.getSignatureText = function (iAccountId, oFetcherOrIdentity, bPasteSignatureAnchor) { var sSignature = this.getClearSignature(iAccountId, oFetcherOrIdentity); if (bPasteSignatureAnchor) { return '<div data-anchor="signature">' + sSignature + '</div>'; } return '<div>' + sSignature + '</div>'; }; /** * @param {Array} aRecipients * @param {number} iAccountId * * @return Object */ CMessageSender.prototype.getFetcherOrIdentityByRecipients = function (aRecipients, iAccountId) { var oAccount = AppData.Accounts.getAccount(iAccountId), aList = this.getAccountFetchersIdentitiesList(oAccount), bFound = false, oFetcherOrIdentity = null ; _.each(aRecipients, function (oAddr) { if (!bFound) { _.each(aList, function (oItem) { if (!bFound && oAddr.sEmail === oItem.email && oAddr.sName === oItem.name) { bFound = true; oFetcherOrIdentity = oItem.result; } }); } }); if (!bFound) { _.each(aRecipients, function (oAddr) { if (!bFound) { _.each(aList, function (oItem) { if (!bFound && oAddr.sEmail === oItem.email) { bFound = true; oFetcherOrIdentity = oItem.result; } }); } }); } return oFetcherOrIdentity; }; /** * @param {Object} oAccount * @returns {Array} */ CMessageSender.prototype.getAccountFetchersIdentitiesList = function (oAccount) { var aList = []; if (oAccount) { aList.push({ 'email': oAccount.email(), 'name': oAccount.friendlyName(), 'result': null }); if (oAccount.fetchers()) { _.each(oAccount.fetchers().collection(), function (oFtch) { aList.push({ 'email': oFtch.email(), 'name': oFtch.userName(), 'result': oFtch }); }); } _.each(oAccount.identities(), function (oIdnt) { aList.push({ 'email': oIdnt.email(), 'name': oIdnt.friendlyName(), 'result': oIdnt }); }); } return aList; }; /** * @param {Object} oMessage * @param {number} iAccountId * @param {Object} oFetcherOrIdentity * * @return {string} */ CMessageSender.prototype.getForwardMessageBody = function (oMessage, iAccountId, oFetcherOrIdentity) { var sCcAddr = Utils.encodeHtml(oMessage.oCc.getFull()), sCcPart = (sCcAddr !== '') ? Utils.i18n('COMPOSE/FORWARD_MESSAGE_BODY_CC', {'CCADDR': sCcAddr}) : '', sForwardTitle = Utils.i18n('COMPOSE/FORWARD_MESSAGE_TITLE', { 'FROMADDR': Utils.encodeHtml(oMessage.oFrom.getFull()), 'TOADDR': Utils.encodeHtml(oMessage.oTo.getFull()), 'CCPART': sCcPart, 'FULLDATE': oMessage.oDateModel.getFullDate(), 'SUBJECT': oMessage.subject() }), sForwardBody = '<br /><br />' + this.getSignatureText(iAccountId, oFetcherOrIdentity, true) + '<br /><br />' + '<div data-anchor="reply-title">' + sForwardTitle + '</div><br /><br />' + oMessage.getConvertedHtml() ; return sForwardBody; }; /** * Prepares and returns cc address for reply message. * * @param {Object} oMessage * @param {number} iAccountId * @param {Object} oFetcherOrIdentity * * @return {string} */ CMessageSender.prototype._getReplyAllCcAddr = function (oMessage, iAccountId, oFetcherOrIdentity) { var oAddressList = new CAddressListModel(), aAddrCollection = _.union(oMessage.oTo.aCollection, oMessage.oCc.aCollection, oMessage.oBcc.aCollection), oCurrAccount = _.find(AppData.Accounts.collection(), function (oAccount) { return oAccount.id() === iAccountId; }, this), oCurrAccAddress = new CAddressModel(), oFetcherAddress = new CAddressModel() ; oCurrAccAddress.sEmail = oCurrAccount.email(); oFetcherAddress.sEmail = oFetcherOrIdentity ? oFetcherOrIdentity.email() : ''; oAddressList.addCollection(aAddrCollection); oAddressList.excludeCollection(_.union(oMessage.oFrom.aCollection, [oCurrAccAddress, oFetcherAddress])); return oAddressList.getFull(); }; CMessageSender._subjectPrefixes = _.map(_.uniq( [Utils.i18n('COMPOSE/REPLY_PREFIX'), Utils.i18n('COMPOSE/FORWARD_PREFIX'), 'Re', 'Fwd', 'НА', 'HA'] ), function (sName) { return sName.toUpperCase(); }); /** * @param {string} sSubject * @param {boolean} bRe * * @return {string} */ CMessageSender.prototype.subjectCompiler = function (sSubject, bRe) { sSubject = Utils.trim(sSubject.replace(/[\s]+/g, ' ')); var bAddCounts = true, sRePrefix = Utils.i18n('COMPOSE/REPLY_PREFIX'), sFwdPrefix = Utils.i18n('COMPOSE/FORWARD_PREFIX'), sRePrefixUpper = sRePrefix.toUpperCase(), sFwdPrefixUpper = sFwdPrefix.toUpperCase(), bBreak = false, bSubBreak = false, oPrefixParts = {}, aPrefixParts = [], aSubjectParts = [], aPart = sSubject.split(':') ; oPrefixParts[bRe ? sRePrefix : sFwdPrefix] = 1; _.each(aPart, function (sItem) { if (bBreak) { aSubjectParts.push(sItem); } else { sItem = Utils.trim(sItem); var sItemUpper = sItem.toUpperCase(); if (sItem && -1 < _.indexOf(CMessageSender._subjectPrefixes, sItemUpper)) { sItem = sRePrefixUpper === sItemUpper ? sRePrefix : sItem; sItem = sFwdPrefixUpper === sItemUpper ? sFwdPrefix : sItem; oPrefixParts[sItem] = Utils.isUnd(oPrefixParts[sItem]) ? 1 : 0 + oPrefixParts[sItem] + 1; } else { bSubBreak = false; if (sItem && !bBreak) { _.each(CMessageSender._subjectPrefixes, function (sSubjectPrefixes) { if (!bSubBreak) { var sStrippedItem = '', oMatch = (new window.RegExp('^' + sSubjectPrefixes + '\\s?[\\[\\(]([\\d]+)[\\]\\)]$', 'gi')).exec(sItemUpper) ; if (oMatch && oMatch[1]) { sStrippedItem = Utils.trim(sItem.replace(/[\s]*[\[\(][\d]+[\]\)]$/g, '')); bSubBreak = true; sStrippedItem = sRePrefixUpper === sItemUpper ? sRePrefix : sStrippedItem; sStrippedItem = sFwdPrefixUpper === sItemUpper ? sFwdPrefix : sStrippedItem; oPrefixParts[sStrippedItem] = Utils.isUnd(oPrefixParts[sStrippedItem]) ? Utils.pInt(oMatch[1]) : 0 + oPrefixParts[sStrippedItem] + Utils.pInt(oMatch[1]); } } }); } if (!bSubBreak) { bBreak = true; aSubjectParts.push(sItem); } } } }); _.each(oPrefixParts, function (iCount, sPrefix) { if (iCount) { aPrefixParts.push(sPrefix + (bAddCounts && 1 < iCount ? '[' + iCount + ']' : '')); } }); return Utils.trim((aPrefixParts.join(': ') + (aPrefixParts.length ? ': ' : '') + aSubjectParts.join(':')).replace(/[\s]+/g, ' ')); }; /** * @param {string} sPlain * * @return {string} */ CMessageSender.prototype.getHtmlFromText = function (sPlain) { return sPlain .replace(/&/g, '&').replace(/>/g, '>').replace(/</g, '<') .replace(/\r/g, '').replace(/\n/g, '<br />') ; }; CMessageSender.prototype.isFetcherOrIdentitySameAsChiefAccount = function (iAccountId) { var oAccount = AppData.Accounts.getAccount(iAccountId || AppData.Accounts.currentId()), oAccountEmail = oAccount.email(), oAccountFriendlyName = oAccount.friendlyName(), aFetchersAndIdentities = [] ; if (oAccount.identities()) { aFetchersAndIdentities = oAccount.identities(); } if (oAccount.fetchers()) { aFetchersAndIdentities = aFetchersAndIdentities.concat(oAccount.fetchers().collection()); } return _.any(aFetchersAndIdentities, function (oAddr) { return oAddr.email() === oAccountEmail && (oAddr.friendlyName ? oAddr.friendlyName() === oAccountFriendlyName : oAddr.userName() === oAccountFriendlyName); }); }; /** * @constructor */ function CPrefetcher() { this.prefetchStarted = ko.observable(false); this.serverInitializationsDone = ko.observable(false); this.helpdeskInitialized = ko.observable(false); this.fetchersIdentitiesPrefetched = ko.observable(false); this.init(); } CPrefetcher.prototype.init = function () { setInterval(_.bind(function () { this.start(); }, this), 2000); }; CPrefetcher.prototype.start = function () { if (AppData.Auth && !AppData.SingleMode && !App.Ajax.hasOpenedRequests()) { this.prefetchStarted(false); this.prefetchAll(); } }; CPrefetcher.prototype.prefetchAll = function () { this.prefetchFetchersIdentities(); if (AppData.App.AllowPrefetch) { this.startMessagesPrefetch(); this.startThreadListPrefetch(); this.doServerInitializations(); this.startOtherPagesPrefetch(); this.prefetchStarredMessageList(); this.prefetchUnseenMessageList(); this.startOtherFoldersPrefetch(); this.prefetchAccountQuota(); this.prefetchCalendarList(); this.initHelpdesk(); } else { this.doServerInitializations(); this.prefetchStarredMessageList(); this.prefetchAccountQuota(); this.prefetchCalendarList(); this.initHelpdesk(); } }; CPrefetcher.prototype.prefetchCalendarList = function () { if (!this.prefetchStarted()) { this.prefetchStarted(App.CalendarCache.firstRequestCalendarList()); } }; CPrefetcher.prototype.prefetchFetchersIdentities = function () { if (!AppData.SingleMode && !this.fetchersIdentitiesPrefetched() && !this.prefetchStarted() && (AppData.User.AllowFetcher || AppData.AllowIdentities)) { AppData.Accounts.populateFetchersIdentities(); this.fetchersIdentitiesPrefetched(true); this.prefetchStarted(true); } }; CPrefetcher.prototype.initHelpdesk = function () { if (AppData.User.IsHelpdeskSupported && !this.prefetchStarted() && !this.helpdeskInitialized()) { App.Screens.initHelpdesk(); this.helpdeskInitialized(true); this.prefetchStarted(true); } }; CPrefetcher.prototype.doServerInitializations = function () { if (!AppData.SingleMode && !this.prefetchStarted() && !this.serverInitializationsDone()) { App.Ajax.send({'Action': 'DoServerInitializations'}); this.serverInitializationsDone(true); this.prefetchStarted(true); } }; CPrefetcher.prototype.prefetchStarredMessageList = function () { if (!this.prefetchStarted()) { var oFolderList = App.MailCache.folderList(), oInbox = oFolderList ? oFolderList.inboxFolder() : null, oRes = null ; if (oInbox && !oInbox.hasChanges()) { oRes = App.MailCache.requestMessageList(oInbox.fullName(), 1, '', Enums.FolderFilter.Flagged, false, false); if (oRes.RequestStarted) { this.prefetchStarted(true); } } } }; CPrefetcher.prototype.prefetchUnseenMessageList = function () { if (!this.prefetchStarted()) { var oFolderList = App.MailCache.folderList(), oInbox = oFolderList ? oFolderList.inboxFolder() : null, oRes = null ; if (oInbox && !oInbox.hasChanges()) { oRes = App.MailCache.requestMessageList(oInbox.fullName(), 1, '', Enums.FolderFilter.Unseen, false, false); if (oRes.RequestStarted) { this.prefetchStarted(true); } } } }; CPrefetcher.prototype.startOtherPagesPrefetch = function () { if (!this.prefetchStarted()) { this.startPagePrefetch(App.MailCache.page() + 1); } if (!this.prefetchStarted()) { this.startPagePrefetch(App.MailCache.page() - 1); } }; /** * @param {string} sCurrentUid */ CPrefetcher.prototype.prefetchNextPage = function (sCurrentUid) { var oUidList = App.MailCache.uidList(), iIndex = _.indexOf(oUidList.collection(), sCurrentUid), iPage = Math.ceil(iIndex/AppData.User.MailsPerPage) + 1 ; this.startPagePrefetch(iPage - 1); }; /** * @param {string} sCurrentUid */ CPrefetcher.prototype.prefetchPrevPage = function (sCurrentUid) { var oUidList = App.MailCache.uidList(), iIndex = _.indexOf(oUidList.collection(), sCurrentUid), iPage = Math.ceil((iIndex + 1)/AppData.User.MailsPerPage) + 1 ; this.startPagePrefetch(iPage); }; /** * @param {number} iPage */ CPrefetcher.prototype.startPagePrefetch = function (iPage) { var oCurrFolder = App.MailCache.folderList().currentFolder(), oUidList = App.MailCache.uidList(), iOffset = (iPage - 1) * AppData.User.MailsPerPage, bPageExists = iPage > 0 && iOffset < oUidList.resultCount(), oParams = null, oRequestData = null ; if (oCurrFolder && !oCurrFolder.hasChanges() && bPageExists) { oParams = { folder: oCurrFolder.fullName(), page: iPage, search: oUidList.search() }; if (!oCurrFolder.hasListBeenRequested(oParams)) { oRequestData = App.MailCache.requestMessageList(oParams.folder, oParams.page, oParams.search, '', false, false); if (oRequestData && oRequestData.RequestStarted) { this.prefetchStarted(true); } } } }; CPrefetcher.prototype.startOtherFoldersPrefetch = function () { if (!this.prefetchStarted()) { var oFolderList = App.MailCache.folderList(), sCurrFolder = oFolderList.currentFolderFullName(), aFoldersFromAccount = AppData.Accounts.getCurrentFetchersAndFiltersFolderNames(), aSystemFolders = oFolderList ? [oFolderList.inboxFolderFullName(), oFolderList.sentFolderFullName(), oFolderList.draftsFolderFullName(), oFolderList.spamFolderFullName()] : [], aOtherFolders = (aFoldersFromAccount.length < 3) ? this.getOtherFolderNames(3 - aFoldersFromAccount.length) : [], aFolders = _.uniq(_.compact(_.union(aSystemFolders, aFoldersFromAccount, aOtherFolders))) ; _.each(aFolders, _.bind(function (sFolder) { if (sCurrFolder !== sFolder) { this.startFolderPrefetch(oFolderList.getFolderByFullName(sFolder)); } }, this)); } }; /** * @param {number} iCount * @returns {Array} */ CPrefetcher.prototype.getOtherFolderNames = function (iCount) { var oInbox = App.MailCache.folderList().inboxFolder(), aInboxSubFolders = oInbox ? oInbox.subfolders() : [], aOtherFolders = _.filter(App.MailCache.folderList().collection(), function (oFolder) { return !oFolder.isSystem(); }, this), aFolders = _.first(_.union(aInboxSubFolders, aOtherFolders), iCount) ; return _.map(aFolders, function (oFolder) { return oFolder.fullName(); }); }; /** * @param {Object} oFolder */ CPrefetcher.prototype.startFolderPrefetch = function (oFolder) { if (!this.prefetchStarted() && oFolder) { var iPage = 1, sSearch = '', oParams = { folder: oFolder.fullName(), page: iPage, search: sSearch }, oRequestData = null ; if (!oFolder.hasListBeenRequested(oParams)) { oRequestData = App.MailCache.requestMessageList(oParams.folder, oParams.page, oParams.search, '', false, false); if (oRequestData && oRequestData.RequestStarted) { this.prefetchStarted(true); } } } }; CPrefetcher.prototype.startThreadListPrefetch = function () { if (!this.prefetchStarted()) { var aUidsForLoad = [], oCurrFolder = App.MailCache.getCurrentFolder() ; _.each(App.MailCache.messages(), function (oCacheMess) { if (oCacheMess.threadCount() > 0) { _.each(oCacheMess.threadUids(), function (sThreadUid) { var oThreadMess = oCurrFolder.oMessages[sThreadUid]; if (!oThreadMess || !oCurrFolder.hasThreadUidBeenRequested(sThreadUid)) { aUidsForLoad.push(sThreadUid); } }); } }, this); if (aUidsForLoad.length > 0) { aUidsForLoad = aUidsForLoad.slice(0, AppData.User.MailsPerPage); oCurrFolder.addRequestedThreadUids(aUidsForLoad); oCurrFolder.loadThreadMessages(aUidsForLoad); this.prefetchStarted(true); } } }; CPrefetcher.prototype.startMessagesPrefetch = function () { if (!this.prefetchStarted()) { var iAccountId = App.MailCache.currentAccountId(), oCurrFolder = App.MailCache.getCurrentFolder(), iTotalSize = 0, iMaxSize = AppData.App.MaxPrefetchBodiesSize, aUids = [], oParameters = null, iJsonSizeOf1Message = 2048, fFillUids = function (oMsg) { var bNotFilled = (!oMsg.deleted() && !oMsg.completelyFilled()), bUidNotAdded = !_.find(aUids, function (sUid) { return sUid === oMsg.uid(); }, this), bHasNotBeenRequested = !oCurrFolder.hasUidBeenRequested(oMsg.uid()) ; if (iTotalSize < iMaxSize && bNotFilled && bUidNotAdded && bHasNotBeenRequested) { aUids.push(oMsg.uid()); iTotalSize += oMsg.trimmedTextSize() + iJsonSizeOf1Message; } } ; if (oCurrFolder && oCurrFolder.selected()) { _.each(App.MailCache.messages(), fFillUids); _.each(oCurrFolder.oMessages, fFillUids); if (aUids.length > 0) { oCurrFolder.addRequestedUids(aUids); oParameters = { 'AccountID': iAccountId, 'Action': 'Messages', 'Folder': oCurrFolder.fullName(), 'Uids': aUids }; App.Ajax.send(oParameters, this.onPrefetchResponse, this); this.prefetchStarted(true); } } } }; /** * @param {Object} oData * @param {Object} oParameters */ CPrefetcher.prototype.onPrefetchResponse = function (oData, oParameters) { var oFolder = App.MailCache.getFolderByFullName(oParameters.AccountID, oParameters.Folder) ; if (_.isArray(oData.Result)) { _.each(oData.Result, function (oRawMessage) { oFolder.parseAndCacheMessage(oRawMessage, false, false); }); } }; CPrefetcher.prototype.prefetchAccountQuota = function () { var oAccount = AppData.Accounts.getCurrent(), bShowQuotaBar = AppData.App && AppData.App.ShowQuotaBar, bNeedQuotaRequest = oAccount && !oAccount.quotaRecieved() ; if (!this.prefetchStarted() && bShowQuotaBar && bNeedQuotaRequest) { oAccount.updateQuotaParams(); this.prefetchStarted(true); } }; /** * @param {Function} list (knockout) * @param {Function=} fSelectCallback * @param {Function=} fDeleteCallback * @param {Function=} fDblClickCallback * @param {Function=} fEnterCallback * @param {Function=} multiplyLineFactor (knockout) * @param {boolean=} bResetCheckedOnClick = false * @param {boolean=} bCheckOnSelect = false * @param {boolean=} bUnselectOnCtrl = false * @param {boolean=} bDisableMultiplySelection = false * @constructor */ function CSelector(list, fSelectCallback, fDeleteCallback, fDblClickCallback, fEnterCallback, multiplyLineFactor, bResetCheckedOnClick, bCheckOnSelect, bUnselectOnCtrl, bDisableMultiplySelection) { this.fBeforeSelectCallback = null; this.fSelectCallback = fSelectCallback || function() {}; this.fDeleteCallback = fDeleteCallback || function() {}; this.fDblClickCallback = (!bMobileApp && fDblClickCallback) ? fDblClickCallback : function() {}; this.fEnterCallback = fEnterCallback || function() {}; this.bResetCheckedOnClick = Utils.isUnd(bResetCheckedOnClick) ? false : !!bResetCheckedOnClick; this.bCheckOnSelect = Utils.isUnd(bCheckOnSelect) ? false : !!bCheckOnSelect; this.bUnselectOnCtrl = Utils.isUnd(bUnselectOnCtrl) ? false : !!bUnselectOnCtrl; this.bDisableMultiplySelection = Utils.isUnd(bDisableMultiplySelection) ? false : !!bDisableMultiplySelection; this.useKeyboardKeys = ko.observable(false); this.list = ko.observableArray([]); if (list && list['subscribe']) { list['subscribe'](function (mValue) { this.list(mValue); }, this); } this.multiplyLineFactor = multiplyLineFactor; this.oLast = null; this.oListScope = null; this.oScrollScope = null; this.iTimer = 0; this.iFactor = 1; this.KeyUp = Enums.Key.Up; this.KeyDown = Enums.Key.Down; this.KeyLeft = Enums.Key.Up; this.KeyRight = Enums.Key.Down; if (this.multiplyLineFactor) { if (this.multiplyLineFactor.subscribe) { this.multiplyLineFactor.subscribe(function (iValue) { this.iFactor = 0 < iValue ? iValue : 1; }, this); } else { this.iFactor = Utils.pInt(this.multiplyLineFactor); } this.KeyUp = Enums.Key.Up; this.KeyDown = Enums.Key.Down; this.KeyLeft = Enums.Key.Left; this.KeyRight = Enums.Key.Right; if ($('html').hasClass('rtl')) { this.KeyLeft = Enums.Key.Right; this.KeyRight = Enums.Key.Left; } } this.sActionSelector = ''; this.sSelectabelSelector = ''; this.sCheckboxSelector = ''; var self = this; // reading returns a list of checked items. // recording (bool) puts all checked, or unchecked. this.listChecked = ko.computed({ 'read': function () { var aList = _.filter(this.list(), function (oItem) { var bC = oItem.checked(), bS = oItem.selected() ; return bC || (self.bCheckOnSelect && bS); }); return aList; }, 'write': function (bValue) { bValue = !!bValue; _.each(this.list(), function (oItem) { oItem.checked(bValue); }); this.list.valueHasMutated(); }, 'owner': this }); this.checkAll = ko.computed({ 'read': function () { return 0 < this.listChecked().length; }, 'write': function (bValue) { this.listChecked(!!bValue); }, 'owner': this }); this.selectorHook = ko.observable(null); this.selectorHook.subscribe(function () { var oPrev = this.selectorHook(); if (oPrev) { oPrev.selected(false); } }, this, 'beforeChange'); this.selectorHook.subscribe(function (oGroup) { if (oGroup) { oGroup.selected(true); } }, this); this.itemSelected = ko.computed({ 'read': this.selectorHook, 'write': function (oItemToSelect) { this.selectorHook(oItemToSelect); if (oItemToSelect) { // self.scrollToSelected(); this.oLast = oItemToSelect; } }, 'owner': this }); this.list.subscribe(function (aList) { if (_.isArray(aList)) { var oSelected = this.itemSelected(); if (oSelected) { if (!_.find(aList, function (oItem) { return oSelected === oItem; })) { this.itemSelected(null); } } } else { this.itemSelected(null); } }, this); this.listCheckedOrSelected = ko.computed({ 'read': function () { var oSelected = this.itemSelected(), aChecked = this.listChecked() ; return 0 < aChecked.length ? aChecked : (oSelected ? [oSelected] : []); }, 'write': function (bValue) { if (!bValue) { this.itemSelected(null); this.listChecked(false); } else { this.listChecked(true); } }, 'owner': this }); this.listCheckedAndSelected = ko.computed({ 'read': function () { var aResult = [], oSelected = this.itemSelected(), aChecked = this.listChecked() ; if (aChecked) { aResult = aChecked.slice(0); } if (oSelected && _.indexOf(aChecked, oSelected) === -1) { aResult.push(oSelected); } return aResult; }, 'write': function (bValue) { if (!bValue) { this.itemSelected(null); this.listChecked(false); } else { this.listChecked(true); } }, 'owner': this }); this.isIncompleteChecked = ko.computed(function () { var iM = this.list().length, iC = this.listChecked().length ; return 0 < iM && 0 < iC && iM > iC; }, this); this.onKeydownBinded = _.bind(this.onKeydown, this); } CSelector.prototype.iTimer = 0; CSelector.prototype.bResetCheckedOnClick = false; CSelector.prototype.bCheckOnSelect = false; CSelector.prototype.bUnselectOnCtrl = false; CSelector.prototype.bDisableMultiplySelection = false; /** * @param {Function} fBeforeSelectCallback */ CSelector.prototype.setBeforeSelectCallback = function (fBeforeSelectCallback) { this.fBeforeSelectCallback = fBeforeSelectCallback || null; }; CSelector.prototype.getLastOrSelected = function () { var iCheckedCount = 0, oLastSelected = null ; _.each(this.list(), function (oItem) { if (oItem.checked()) { iCheckedCount++; } if (oItem.selected()) { oLastSelected = oItem; } }); return 0 === iCheckedCount && oLastSelected ? oLastSelected : this.oLast; }; /** * @return {boolean} */ /*CSelector.prototype.inFocus = function () { var mTagName = document && document.activeElement ? document.activeElement.tagName : null; return 'INPUT' === mTagName || 'TEXTAREA' === mTagName || 'IFRAME' === mTagName; };*/ /** * @param {string} sActionSelector css-selector for the active for pressing regions of the list * @param {string} sSelectabelSelector css-selector to the item that was selected * @param {string} sCheckboxSelector css-selector to the element that checkbox in the list * @param {*} oListScope * @param {*} oScrollScope */ CSelector.prototype.initOnApplyBindings = function (sActionSelector, sSelectabelSelector, sCheckboxSelector, oListScope, oScrollScope) { $(document).on('keydown', this.onKeydownBinded); this.oListScope = oListScope; this.oScrollScope = oScrollScope; this.sActionSelector = sActionSelector; this.sSelectabelSelector = sSelectabelSelector; this.sCheckboxSelector = sCheckboxSelector; var self = this, fEventClickFunction = function (oLast, oItem, oEvent) { var iIndex = 0, iLength = 0, oListItem = null, bChangeRange = false, bIsInRange = false, aList = [], bChecked = false ; oItem = oItem ? oItem : null; if (oEvent && oEvent.shiftKey) { if (null !== oItem && null !== oLast && oItem !== oLast) { aList = self.list(); bChecked = oItem.checked(); for (iIndex = 0, iLength = aList.length; iIndex < iLength; iIndex++) { oListItem = aList[iIndex]; bChangeRange = false; if (oListItem === oLast || oListItem === oItem) { bChangeRange = true; } if (bChangeRange) { bIsInRange = !bIsInRange; } if (bIsInRange || bChangeRange) { oListItem.checked(bChecked); } } } } if (oItem) { self.oLast = oItem; } } ; $(this.oListScope).on('dblclick', sActionSelector, function (oEvent) { var oItem = ko.dataFor(this); if (oItem && oEvent && !oEvent.ctrlKey && !oEvent.altKey && !oEvent.shiftKey) { self.onDblClick(oItem); } }); if (bMobileDevice) { $(this.oListScope).on('touchstart', sActionSelector, function (e) { if (!e) { return; } var t2 = e.timeStamp, t1 = $(this).data('lastTouch') || t2, dt = t2 - t1, fingers = e.originalEvent && e.originalEvent.touches ? e.originalEvent.touches.length : 0 ; $(this).data('lastTouch', t2); if (!dt || dt > 250 || fingers > 1) { return; } e.preventDefault(); $(this).trigger('dblclick'); }); } $(this.oListScope).on('click', sActionSelector, function (oEvent) { var bClick = true, oSelected = null, oLast = self.getLastOrSelected(), oItem = ko.dataFor(this) ; if (oItem && oEvent) { if (oEvent.shiftKey) { bClick = false; if (!self.bDisableMultiplySelection) { if (null === self.oLast) { self.oLast = oItem; } oItem.checked(!oItem.checked()); fEventClickFunction(oLast, oItem, oEvent); } } else if (oEvent.ctrlKey) { bClick = false; if (!self.bDisableMultiplySelection) { self.oLast = oItem; oSelected = self.itemSelected(); if (oSelected && !oSelected.checked() && !oItem.checked()) { oSelected.checked(true); } if (self.bUnselectOnCtrl && oItem === self.itemSelected()) { oItem.checked(!oItem.selected()); self.itemSelected(null); } else { oItem.checked(!oItem.checked()); } } } if (bClick) { self.onSelect(oItem); self.scrollToSelected(); } } }); $(this.oListScope).on('click', sCheckboxSelector, function (oEvent) { var oItem = ko.dataFor(this); if (oItem && oEvent && !self.bDisableMultiplySelection) { if (oEvent.shiftKey) { if (null === self.oLast) { self.oLast = oItem; } fEventClickFunction(self.getLastOrSelected(), oItem, oEvent); } else { self.oLast = oItem; } } if (oEvent && oEvent.stopPropagation) { oEvent.stopPropagation(); } }); $(this.oListScope).on('dblclick', sCheckboxSelector, function (oEvent) { if (oEvent && oEvent.stopPropagation) { oEvent.stopPropagation(); } }); }; /** * @param {Object} oSelected * @param {number} iEventKeyCode * * @return {Object} */ CSelector.prototype.getResultSelection = function (oSelected, iEventKeyCode) { var self = this, bStop = false, bNext = false, oResult = null, iPageStep = this.iFactor, bMultiply = !!this.multiplyLineFactor, iIndex = 0, iLen = 0, aList = [] ; if (!oSelected && -1 < Utils.inArray(iEventKeyCode, [this.KeyUp, this.KeyDown, this.KeyLeft, this.KeyRight, Enums.Key.PageUp, Enums.Key.PageDown, Enums.Key.Home, Enums.Key.End])) { aList = this.list(); if (aList && 0 < aList.length) { if (-1 < Utils.inArray(iEventKeyCode, [this.KeyDown, this.KeyRight, Enums.Key.PageUp, Enums.Key.Home])) { oResult = aList[0]; } else if (-1 < Utils.inArray(iEventKeyCode, [this.KeyUp, this.KeyLeft, Enums.Key.PageDown, Enums.Key.End])) { oResult = aList[aList.length - 1]; } } } else if (oSelected) { aList = this.list(); iLen = aList ? aList.length : 0; if (0 < iLen) { if ( Enums.Key.Home === iEventKeyCode || Enums.Key.PageUp === iEventKeyCode || Enums.Key.End === iEventKeyCode || Enums.Key.PageDown === iEventKeyCode || (bMultiply && (Enums.Key.Left === iEventKeyCode || Enums.Key.Right === iEventKeyCode)) || (!bMultiply && (Enums.Key.Up === iEventKeyCode || Enums.Key.Down === iEventKeyCode)) ) { _.each(aList, function (oItem) { if (!bStop) { switch (iEventKeyCode) { case self.KeyUp: case self.KeyLeft: if (oSelected === oItem) { bStop = true; } else { oResult = oItem; } break; case Enums.Key.Home: case Enums.Key.PageUp: oResult = oItem; bStop = true; break; case self.KeyDown: case self.KeyRight: if (bNext) { oResult = oItem; bStop = true; } else if (oSelected === oItem) { bNext = true; } break; case Enums.Key.End: case Enums.Key.PageDown: oResult = oItem; break; } } }); } else if (bMultiply && this.KeyDown === iEventKeyCode) { for (; iIndex < iLen; iIndex++) { if (oSelected === aList[iIndex]) { iIndex += iPageStep; if (iLen - 1 < iIndex) { iIndex -= iPageStep; } oResult = aList[iIndex]; break; } } } else if (bMultiply && this.KeyUp === iEventKeyCode) { for (iIndex = iLen; iIndex >= 0; iIndex--) { if (oSelected === aList[iIndex]) { iIndex -= iPageStep; if (0 > iIndex) { iIndex += iPageStep; } oResult = aList[iIndex]; break; } } } } } return oResult; }; /** * @param {Object} oResult * @param {Object} oSelected * @param {number} iEventKeyCode */ CSelector.prototype.shiftClickResult = function (oResult, oSelected, iEventKeyCode) { if (oSelected) { var bMultiply = !!this.multiplyLineFactor, bInRange = false, bSelected = false ; if (-1 < Utils.inArray(iEventKeyCode, bMultiply ? [Enums.Key.Left, Enums.Key.Right] : [Enums.Key.Up, Enums.Key.Down])) { oSelected.checked(!oSelected.checked()); } else if (-1 < Utils.inArray(iEventKeyCode, bMultiply ? [Enums.Key.Up, Enums.Key.Down, Enums.Key.PageUp, Enums.Key.PageDown, Enums.Key.Home, Enums.Key.End] : [Enums.Key.Left, Enums.Key.Right, Enums.Key.PageUp, Enums.Key.PageDown, Enums.Key.Home, Enums.Key.End] )) { bSelected = !oSelected.checked(); _.each(this.list(), function (oItem) { var Add = false; if (oItem === oResult || oSelected === oItem) { bInRange = !bInRange; Add = true; } if (bInRange || Add) { oItem.checked(bSelected); Add = false; } }); if (bMultiply && oResult && (iEventKeyCode === Enums.Key.Up || iEventKeyCode === Enums.Key.Down)) { oResult.checked(!oResult.checked()); } } } }; /** * @param {number} iEventKeyCode * @param {boolean} bShiftKey */ CSelector.prototype.clickNewSelectPosition = function (iEventKeyCode, bShiftKey) { var self = this, iTimeout = 0, oResult = null, oSelected = this.itemSelected() ; oResult = this.getResultSelection(oSelected, iEventKeyCode); if (oResult) { if (bShiftKey) { this.shiftClickResult(oResult, oSelected, iEventKeyCode); } if (oResult && this.fBeforeSelectCallback) { this.fBeforeSelectCallback(oResult, function (bResult) { if (bResult) { self.itemSelected(oResult); iTimeout = 0 === self.iTimer ? 50 : 150; if (0 !== self.iTimer) { window.clearTimeout(self.iTimer); } self.iTimer = window.setTimeout(function () { self.iTimer = 0; self.onSelect(oResult, false); }, iTimeout); this.scrollToSelected(); } }); this.scrollToSelected(); } else { this.itemSelected(oResult); iTimeout = 0 === this.iTimer ? 50 : 150; if (0 !== this.iTimer) { window.clearTimeout(this.iTimer); } this.iTimer = window.setTimeout(function () { self.iTimer = 0; self.onSelect(oResult); }, iTimeout); this.scrollToSelected(); } } else if (oSelected) { if (bShiftKey && (-1 < Utils.inArray(iEventKeyCode, [this.KeyUp, this.KeyDown, this.KeyLeft, this.KeyRight, Enums.Key.PageUp, Enums.Key.PageDown, Enums.Key.Home, Enums.Key.End]))) { oSelected.checked(!oSelected.checked()); } } }; /** * @param {Object} oEvent * * @return {boolean} */ CSelector.prototype.onKeydown = function (oEvent) { var bResult = true, iCode = 0 ; if (this.useKeyboardKeys() && oEvent && !Utils.isTextFieldFocused()) { iCode = oEvent.keyCode; if (!oEvent.ctrlKey && ( this.KeyUp === iCode || this.KeyDown === iCode || this.KeyLeft === iCode || this.KeyRight === iCode || Enums.Key.PageUp === iCode || Enums.Key.PageDown === iCode || Enums.Key.Home === iCode || Enums.Key.End === iCode ) ) { this.clickNewSelectPosition(iCode, oEvent.shiftKey); bResult = false; } else if (Enums.Key.Del === iCode && !oEvent.ctrlKey && !oEvent.shiftKey) { if (0 < this.list().length) { this.onDelete(); bResult = false; } } else if (Enums.Key.Enter === iCode) { if (0 < this.list().length && !oEvent.ctrlKey) { this.onEnter(this.itemSelected()); bResult = false; } } else if (oEvent.ctrlKey && !oEvent.altKey && !oEvent.shiftKey && Enums.Key.a === iCode) { this.checkAll(!(this.checkAll() && !this.isIncompleteChecked())); bResult = false; } } return bResult; }; CSelector.prototype.onDelete = function () { this.fDeleteCallback.call(this, this.listCheckedOrSelected()); }; /** * @param {Object} oItem */ CSelector.prototype.onEnter = function (oItem) { var self = this; if (oItem && this.fBeforeSelectCallback) { this.fBeforeSelectCallback(oItem, function (bResult) { if (bResult) { self.itemSelected(oItem); self.fEnterCallback.call(this, oItem); } }); } else { this.itemSelected(oItem); this.fEnterCallback.call(this, oItem); } }; /** * @param {Object} oItem */ CSelector.prototype.selectionFunc = function (oItem) { this.itemSelected(null); if (this.bResetCheckedOnClick) { this.listChecked(false); } this.itemSelected(oItem); this.fSelectCallback.call(this, oItem); }; /** * @param {Object} oItem * @param {boolean=} bCheckBefore = true */ CSelector.prototype.onSelect = function (oItem, bCheckBefore) { bCheckBefore = Utils.isUnd(bCheckBefore) ? true : !!bCheckBefore; if (this.fBeforeSelectCallback && bCheckBefore) { var self = this; this.fBeforeSelectCallback(oItem, function (bResult) { if (bResult) { self.selectionFunc(oItem); } }); } else { this.selectionFunc(oItem); } }; /** * @param {Object} oItem */ CSelector.prototype.onDblClick = function (oItem) { this.fDblClickCallback.call(this, oItem); }; CSelector.prototype.koCheckAll = function () { return ko.computed({ 'read': this.checkAll, 'write': this.checkAll, 'owner': this }); }; CSelector.prototype.koCheckAllIncomplete = function () { return ko.computed({ 'read': this.isIncompleteChecked, 'write': this.isIncompleteChecked, 'owner': this }); }; /** * @return {boolean} */ CSelector.prototype.scrollToSelected = function () { if (!this.oListScope || !this.oScrollScope) { return false; } var iOffset = 20, oSelected = $(this.sSelectabelSelector, this.oScrollScope), oPos = oSelected.position(), iVisibleHeight = this.oScrollScope.height(), iSelectedHeight = oSelected.outerHeight() ; if (oPos && (oPos.top < 0 || oPos.top + iSelectedHeight > iVisibleHeight)) { if (oPos.top < 0) { this.oScrollScope.scrollTop(this.oScrollScope.scrollTop() + oPos.top - iOffset); } else { this.oScrollScope.scrollTop(this.oScrollScope.scrollTop() + oPos.top - iVisibleHeight + iSelectedHeight + iOffset); } return true; } return false; }; (function ($) { /** * @param {{name:string,resizeFunc:Function}} args */ $.fn.splitter = function(args) { args = args || {}; return this.each(function () { var bIsMouseSplit = false, storageKey = args.name, initPosition = 0, nSize = 0, oLastState = {}, oLastStateReserve = {}, startSplitMouse = function (e) { bIsMouseSplit = true; bar.addClass(opts['activeClass']); opts['_posSplit'] = -((rtl ? splitter._overallWidth - e[opts['eventPos']] : e[opts['eventPos']]) - panes.get(0)[opts['pxSplit']] ); $('body') .attr({'unselectable': "on"}) .addClass('unselectable'); $(document) .bind('mousemove', doSplitMouse) .bind('mouseup', endSplitMouse); }, doSplitMouse = function (e) { var newPos = (rtl ? splitter._overallWidth - e[opts['eventPos']] : e[opts['eventPos']]) + opts['_posSplit']; resplit(newPos); if (Utils.isFunc(args.resizeFunc)) { args.resizeFunc(); } }, endSplitMouse = function endSplitMouse(e) { bar.removeClass(opts['activeClass']); $('body') .attr({'unselectable': 'off'}) .removeClass('unselectable'); // Store 'width' data if (storageKey) { App.Storage.setData(storageKey + 'ResizerWidth', panes.get(0)[opts['pxSplit']]); } $(document) .unbind('mousemove', doSplitMouse) .unbind('mouseup', endSplitMouse); if (Utils.isFunc(args.resizeFunc)) { args.resizeFunc(); } }, resplit = function (newPosition, bIgnoreSizeLimits) { if (!bIgnoreSizeLimits) { // Constrain new splitbar position to fit pane size limits newPosition = window.Math.max( panes.get(0)._min, splitter._overallWidth - panes.get(1)._max, window.Math.min(newPosition, panes.get(0)._max, splitter._overallWidth - panes.get(1)._min) ); } panes.get(0).$.css(opts['split'], newPosition); panes.get(1).$.css(opts['split'], splitter._overallWidth - newPosition); if (!App.browser.ie8AndBelow) { panes.trigger('resize'); } }, dimSum = function (elem, dims) { // Opera returns -1 for missing min/max width, turn into 0 var sum = 0, i = 1; for (; i < arguments.length; i++) { sum += window.Math.max(window.parseInt(elem.css(arguments[i]), 10) || 0, 0); } return sum; }, vh = (args.splitHorizontal ? 'h' : args.splitVertical ? 'v' : args.type) || 'v', opts = $.extend({ 'activeClass': 'active', // class name for active splitter 'pxPerKey': 8, // splitter px moved per keypress 'tabIndex': 0, // tab order indicator 'accessKey': '' // accessKey for splitbar },{ v: { // Vertical splitters: 'keyLeft': 39, 'keyRight': 37, 'type': 'v', 'eventPos': "pageX", 'origin': "left", 'split': "width", 'pxSplit': "offsetWidth", 'side1': "Left", 'side2': "Right", 'fixed': "height", 'pxFixed': "offsetHeight", 'side3': "Top", 'side4': "Bottom" }, h: { // Horizontal splitters: 'keyTop': 40, 'keyBottom': 38, 'type': 'h', 'eventPos': "pageY", 'origin': "top", 'split': "height", 'pxSplit': "offsetHeight", 'side1': "Top", 'side2': "Bottom", 'fixed': "width", 'pxFixed': "offsetWidth", 'side3': "Left", 'side4': "Right" } }[vh], args), splitter = $(this), panes = $(">*:not(css3pie)", splitter).each(function(){this.$ = $(this);}), bar = $('.resize_handler', panes.get(0)) .attr({'unselectable': 'on'}) .bind('mousedown', startSplitMouse), rtl = splitter.css('direction') === 'rtl' ; panes.get(0)._paneName = opts['side1']; panes.get(1)._paneName = opts['side2']; panes.each(function(){ this._min = opts['min' + this._paneName] || dimSum(this.$, 'min-' + opts['split']); this._max = opts['max' + this._paneName] || dimSum(this.$, 'max-' + opts['split']) || 9999; this._init = opts['size' + this._paneName] === undefined ? window.parseInt($.css(this, opts['split']), 10) : opts['size' + this._paneName]; }); // Determine initial position, get from cookie if specified if (storageKey) { initPosition = App.Storage.getData(storageKey + 'ResizerWidth') || panes.get(0)._init; } else { initPosition = panes.get(0)._init; } /*// no need because we store only primary (left or top) panel if (!isNaN(panes.get(1)._init)) // recalc initial B size as an offset from the top or left side { initPosition = splitter[0][opts['pxSplit']] - panes.get(1)._init; }*/ if (isNaN(initPosition)) { initPosition = splitter[0][opts['pxSplit']]; initPosition = window.Math.round(initPosition / panes.length); } // Resize event propagation and splitter sizing if (opts['resizeToWidth'] && !(App.browser.ie8AndBelow)) { $(window).bind('resize', function(e) { if (e.target !== this) { return; } splitter.trigger('resize'); }); } splitter.bind('resize', function (ev, size, sCommand, bIgnoreSizeLimits) { var tKey = ev.target.className + '_' + sCommand; if (bIsMouseSplit) { oLastState = {}; } // Custom events bubble in jQuery 1.3; don't get into a Yo Dawg if (ev.target !== this) { return; } // Determine new width/height of splitter container splitter._overallWidth = splitter[0][opts['pxSplit']]; // Return if splitter isn't visible or content isn't there yet if (splitter._overallWidth <= 0) { return; } if (!(opts['sizeRight'] || opts['sizeBottom'])) { nSize = panes.get(0)[opts['pxSplit']]; } else { nSize = splitter._overallWidth - panes.get(1)[opts['pxSplit']]; } if (isNaN(size)) { size = nSize; } else if (sCommand) { bIsMouseSplit = false; if (oLastState[tKey]) { size = oLastState[tKey]; oLastState[tKey] = null; } else { if (size === nSize) { oLastState[tKey] = null; size = oLastStateReserve[tKey]; } else { oLastState[tKey] = oLastStateReserve[tKey] = nSize; } _.each(oLastState, function(num, key) { if (key !== tKey) { oLastState[key] = null; } }); } } resplit(size, bIgnoreSizeLimits); }).trigger('resize', [initPosition]); }); }; })(jQuery); (function ($) { /** * extend jQuery autocomplete */ // styling results $.ui.autocomplete.prototype._renderItem = function (ul, item) { item.label = Utils.trim(item.label); item.label = item.label.replace(/\([^\)]+\)$/i, function (sMatch) { return '~~1~~' + sMatch + '~~2~~'; }); item.label = item.label.replace(/<[^>]+>$/i, function (sMatch) { return '~~1~~' + sMatch + '~~2~~'; }); item.label = Utils.encodeHtml(item.label); item.label = item.label .replace(/~~1~~/, '<span style="opacity: 0.5">') .replace(/~~2~~/, '</span>') ; return $('<li>') .append('<a>' + item.label + '</a>') .appendTo(ul); }; // add categories $.ui.autocomplete.prototype._renderMenu = function(ul, items) { var self = this, currentCategory = '' ; $.each(items, function(index, item) { if (item && item.category && item.category !== currentCategory) { currentCategory = item.category; ul.append('<li class="ui-autocomplete-category">' + item.category + '</li>'); } self._renderItemData(ul, item); }); }; })(jQuery); /** * @constructor */ function CApi() { this.openPgp = null; this.openPgpCallbacks = []; } /** * @param {string} sToAddresses */ CApi.prototype.openComposeMessage = function (sToAddresses) { App.Routing.setHash(App.Links.composeWithToField(sToAddresses)); }; /** * Downloads by url through iframe or new window. * * @param {string} sUrl */ CApi.prototype.downloadByUrl = function (sUrl) { var oIframe = null; if (bMobileDevice) { window.open(sUrl); } else { oIframe = $('<iframe style="display: none;"></iframe>').appendTo(document.body); oIframe.attr('src', sUrl); setTimeout(function () { oIframe.remove(); }, 60000); } }; /** * @return {boolean} */ CApi.prototype.isPgpSupported = function () { return !!(window.crypto && window.crypto.getRandomValues); }; /** * @param {Function} fCallback * @param {mixed=} sUserUid */ CApi.prototype.pgp = function (fCallback, sUserUid) { if (Utils.isFunc(fCallback)) { if (this.openPgp) { fCallback(this.openPgp); } else if (this.isPgpSupported()) { if (null !== this.openPgpCallbacks) { this.openPgpCallbacks.push(fCallback); } else { fCallback(false); } var self = this; if (!this.openPgpRequest) { this.openPgpRequest = true; $.ajax({ 'url': 'static/js/openpgp.js', 'dataType': 'script', 'cache': true, 'complete': function () { self.openPgp = window.openpgp ? new OpenPgp(window.openpgp, 'user_' + (sUserUid || '0') + '_') : false; if (null !== self.openPgpCallbacks) { _.each(self.openPgpCallbacks, function (fItemCallback) { fItemCallback(self.openPgp); }); } self.openPgpCallbacks = null; } }); } } else { fCallback(false); } } }; /** * @param {string} sLoading */ CApi.prototype.showLoading = function (sLoading) { App.Screens.showLoading(sLoading); }; CApi.prototype.hideLoading = function () { App.Screens.hideLoading(); }; /** * @param {string} sReport * @param {number=} iDelay */ CApi.prototype.showReport = function (sReport, iDelay) { App.Screens.showReport(sReport, iDelay); }; /** * @param {string} sError * @param {boolean=} bHtml = false * @param {boolean=} bNotHide = false * @param {boolean=} bGray = false */ CApi.prototype.showError = function (sError, bHtml, bNotHide, bGray) { App.Screens.showError(sError, bHtml, bNotHide, bGray); }; /** * @param {boolean=} bGray = false */ CApi.prototype.hideError = function (bGray) { App.Screens.hideError(bGray); }; /** * @param {Object} oRes * @param {string} sPgpAction * @param {string=} sDefaultError */ CApi.prototype.showPgpErrorByCode = function (oRes, sPgpAction, sDefaultError) { var aErrors = Utils.isNonEmptyArray(oRes.errors) ? oRes.errors : [], aNotices = Utils.isNonEmptyArray(oRes.notices) ? oRes.notices : [], aEmailsWithoutPublicKey = [], aEmailsWithoutPrivateKey = [], sError = '', bNoSignDataNotice = false, bNotice = true ; _.each(_.union(aErrors, aNotices), function (aError) { if (aError.length === 2) { switch(aError[0]) { case OpenPgpResult.Enum.GenerateKeyError: sError = Utils.i18n('OPENPGP/ERROR_GENERATE_KEY'); break; case OpenPgpResult.Enum.ImportKeyError: sError = Utils.i18n('OPENPGP/ERROR_IMPORT_KEY'); break; case OpenPgpResult.Enum.ImportNoKeysFoundError: sError = Utils.i18n('OPENPGP/ERROR_IMPORT_NO_KEY_FOUNDED'); break; case OpenPgpResult.Enum.PrivateKeyNotFoundError: case OpenPgpResult.Enum.PrivateKeyNotFoundNotice: aEmailsWithoutPrivateKey.push(aError[1]); break; case OpenPgpResult.Enum.PublicKeyNotFoundError: bNotice = false; aEmailsWithoutPublicKey.push(aError[1]); break; case OpenPgpResult.Enum.PublicKeyNotFoundNotice: aEmailsWithoutPublicKey.push(aError[1]); break; case OpenPgpResult.Enum.KeyIsNotDecodedError: if (sPgpAction === Enums.PgpAction.DecryptVerify) { sError = Utils.i18n('OPENPGP/ERROR_DECRYPT') + ' ' + Utils.i18n('OPENPGP/ERROR_KEY_NOT_DECODED', {'USER': aError[1]}); } else if (sPgpAction === Enums.PgpAction.Sign || sPgpAction === Enums.PgpAction.EncryptSign) { sError = Utils.i18n('OPENPGP/ERROR_SIGN') + ' ' + Utils.i18n('OPENPGP/ERROR_KEY_NOT_DECODED', {'USER': aError[1]}); } break; case OpenPgpResult.Enum.SignError: sError = Utils.i18n('OPENPGP/ERROR_SIGN'); break; case OpenPgpResult.Enum.VerifyError: sError = Utils.i18n('OPENPGP/ERROR_VERIFY'); break; case OpenPgpResult.Enum.EncryptError: sError = Utils.i18n('OPENPGP/ERROR_ENCRYPT'); break; case OpenPgpResult.Enum.DecryptError: sError = Utils.i18n('OPENPGP/ERROR_DECRYPT'); break; case OpenPgpResult.Enum.SignAndEncryptError: sError = Utils.i18n('OPENPGP/ERROR_ENCRYPT_OR_SIGN'); break; case OpenPgpResult.Enum.VerifyAndDecryptError: sError = Utils.i18n('OPENPGP/ERROR_DECRYPT_OR_VERIFY'); break; case OpenPgpResult.Enum.DeleteError: sError = Utils.i18n('OPENPGP/ERROR_DELETE_KEY'); break; case OpenPgpResult.Enum.VerifyErrorNotice: sError = Utils.i18n('OPENPGP/ERROR_VERIFY'); break; case OpenPgpResult.Enum.NoSignDataNotice: bNoSignDataNotice = true; break; } } }); if (aEmailsWithoutPublicKey.length > 0) { aEmailsWithoutPublicKey = _.without(aEmailsWithoutPublicKey, ''); if (aEmailsWithoutPublicKey.length > 0) { sError = Utils.i18n('OPENPGP/ERROR_NO_PUBLIC_KEYS_FOR_USERS_PLURAL', {'USERS': aEmailsWithoutPublicKey.join(', ')}, null, aEmailsWithoutPublicKey.length); } else if (sPgpAction === Enums.PgpAction.Verify) { sError = Utils.i18n('OPENPGP/ERROR_NO_PUBLIC_KEY_FOUND_FOR_VERIFY'); } if (bNotice && sError !== '') { sError += ' ' + Utils.i18n('OPENPGP/ERROR_MESSAGE_WAS_NOT_VERIFIED'); } } else if (aEmailsWithoutPrivateKey.length > 0) { aEmailsWithoutPrivateKey = _.without(aEmailsWithoutPrivateKey, ''); if (aEmailsWithoutPrivateKey.length > 0) { sError = Utils.i18n('OPENPGP/ERROR_NO_PRIVATE_KEYS_FOR_USERS_PLURAL', {'USERS': aEmailsWithoutPrivateKey.join(', ')}, null, aEmailsWithoutPrivateKey.length); } else if (sPgpAction === Enums.PgpAction.DecryptVerify) { sError = Utils.i18n('OPENPGP/ERROR_NO_PRIVATE_KEY_FOUND_FOR_DECRYPT'); } } if (sError === '' && !bNoSignDataNotice) { switch (sPgpAction) { case Enums.PgpAction.Generate: sError = Utils.i18n('OPENPGP/ERROR_GENERATE_KEY'); break; case Enums.PgpAction.Import: sError = Utils.i18n('OPENPGP/ERROR_IMPORT_KEY'); break; case Enums.PgpAction.DecryptVerify: sError = Utils.i18n('OPENPGP/ERROR_DECRYPT'); break; case Enums.PgpAction.Verify: sError = Utils.i18n('OPENPGP/ERROR_VERIFY'); break; case Enums.PgpAction.Encrypt: sError = Utils.i18n('OPENPGP/ERROR_ENCRYPT'); break; case Enums.PgpAction.EncryptSign: sError = Utils.i18n('OPENPGP/ERROR_ENCRYPT_OR_SIGN'); break; case Enums.PgpAction.Sign: sError = Utils.i18n('OPENPGP/ERROR_SIGN'); break; } sError = sDefaultError; } if (sError !== '') { App.Api.showError(sError); } return bNoSignDataNotice; }; /** * @param {Object} oResponse * @param {string=} sDefaultError */ CApi.prototype.showErrorByCode = function (oResponse, sDefaultError) { var iErrorCode = oResponse.ErrorCode, sErrorMessage = oResponse.ErrorMessage || '' ; if (sErrorMessage !== '') { sErrorMessage = ' (' + sErrorMessage + ')'; } switch (iErrorCode) { default: if (sDefaultError && sDefaultError.length > 0) { this.showError(sDefaultError + sErrorMessage); } else if (sErrorMessage !== '') { this.showError(sErrorMessage); } break; case Enums.Errors.AuthError: this.showError(Utils.i18n('WARNING/LOGIN_PASS_INCORRECT') + sErrorMessage); break; case Enums.Errors.DemoLimitations: this.showError(Utils.i18n('DEMO/WARNING_THIS_FEATURE_IS_DISABLED') + sErrorMessage); break; case Enums.Errors.Captcha: this.showError(Utils.i18n('WARNING/CAPTCHA_IS_INCORRECT') + sErrorMessage); break; case Enums.Errors.CanNotGetMessage: this.showError(Utils.i18n('MESSAGE/ERROR_MESSAGE_DELETED') + sErrorMessage); break; case Enums.Errors.NoRequestedMailbox: this.showError(sDefaultError + ' ' + Utils.i18n('COMPOSE/ERROR_INVALID_ADDRESS', {'ADDRESS': oResponse.Mailbox}) + sErrorMessage); break; case Enums.Errors.CanNotChangePassword: this.showError(Utils.i18n('WARNING/UNABLE_CHANGE_PASSWORD') + sErrorMessage); break; case Enums.Errors.AccountOldPasswordNotCorrect: this.showError(Utils.i18n('WARNING/CURRENT_PASSWORD_NOT_CORRECT') + sErrorMessage); break; case Enums.Errors.FetcherIncServerNotAvailable: this.showError(Utils.i18n('WARNING/FETCHER_SAVE_ERROR') + sErrorMessage); break; case Enums.Errors.FetcherLoginNotCorrect: this.showError(Utils.i18n('WARNING/FETCHER_SAVE_ERROR') + sErrorMessage); break; case Enums.Errors.HelpdeskUserNotExists: this.showError(Utils.i18n('HELPDESK/ERROR_FORGOT_NO_ACCOUNT') + sErrorMessage); break; case Enums.Errors.MailServerError: this.showError(Utils.i18n('WARNING/CANT_CONNECT_TO_SERVER') + sErrorMessage); break; case Enums.Errors.DataTransferFailed: this.showError(Utils.i18n('WARNING/DATA_TRANSFER_FAILED') + sErrorMessage); break; case Enums.Errors.NotDisplayedError: if (sErrorMessage !== '') { this.showError(sErrorMessage); } break; } }; /** * @param {string} sName * @param {string} sHeaderTitle * @param {string} sDocumentTitle * @param {string} sTemplateName * @param {Object} oViewModelClass */ AfterLogicApi.addScreenToHeader = function (sName, sHeaderTitle, sDocumentTitle, sTemplateName, oViewModelClass) { App.addScreenToHeader(sName, sHeaderTitle, sDocumentTitle, sTemplateName, oViewModelClass, true); }; AfterLogicApi.aSettingsTabs = []; /** * @param {Object} oViewModelClass */ AfterLogicApi.addSettingsTab = function (oViewModelClass) { if (oViewModelClass.prototype.TabName) { Enums.SettingsTab[oViewModelClass.prototype.TabName] = oViewModelClass.prototype.TabName; AfterLogicApi.aSettingsTabs.push(oViewModelClass); } }; /** * @return {Array} */ AfterLogicApi.getPluginsSettingsTabs = function () { return AfterLogicApi.aSettingsTabs; }; /** * @param {string} sSettingName * * @return {string} */ AfterLogicApi.getSetting = function (sSettingName) { return AppData.App[sSettingName]; }; /** * @param {string} sPluginName * * @return {string|null} */ AfterLogicApi.getPluginSettings = function (sPluginName) { if (AppData && AppData.Plugins) { return AppData.Plugins[sPluginName]; } return null; }; AfterLogicApi.oPluginHooks = {}; /** * @param {string} sName * @param {Function} fCallback */ AfterLogicApi.addPluginHook = function (sName, fCallback) { if (Utils.isFunc(fCallback)) { if (!$.isArray(this.oPluginHooks[sName])) { this.oPluginHooks[sName] = []; } this.oPluginHooks[sName].push(fCallback); } }; /** * @param {string} sName * @param {Array=} aArguments */ AfterLogicApi.runPluginHook = function (sName, aArguments) { if ($.isArray(this.oPluginHooks[sName])) { aArguments = aArguments || []; _.each(this.oPluginHooks[sName], function (fCallback) { fCallback.apply(null, aArguments); }); } }; /** * @param {Object} oParameters * @param {Function=} fResponseHandler * @param {Object=} oContext */ AfterLogicApi.sendAjaxRequest = function (oParameters, fResponseHandler, oContext) { App.Ajax.send(oParameters, fResponseHandler, oContext); }; /** * @param {string} sKey * @param {?Object=} oValueList * @param {?string=} sDefaulValue * @param {number=} nPluralCount * * @return {string} */ AfterLogicApi.i18n = Utils.i18n; /** * @param {string} sRecipients * * @return {Array} */ AfterLogicApi.getArrayRecipients = Utils.getArrayRecipients; /** * @param {string} sFullEmail * * @return {Object} */ AfterLogicApi.getEmailParts = Utils.getEmailParts; /** * @param {string} sAlert */ AfterLogicApi.showAlertPopup = function (sAlert) { App.Screens.showPopup(AlertPopup, [sAlert]); }; /** * @param {string} sConfirm * @param {Function} fConfirmCallback */ AfterLogicApi.showConfirmPopup = function (sConfirm, fConfirmCallback) { App.Screens.showPopup(ConfirmPopup, [sConfirm, fConfirmCallback]); }; /** * @param {string} sReport * @param {number=} iDelay */ AfterLogicApi.showReport = function(sReport, iDelay) { App.Screens.showReport(sReport, iDelay); }; /** * @param {string} sError */ AfterLogicApi.showError = function(sError) { App.Screens.showError(sError); }; AfterLogicApi.getPrimaryAccountData = function() { var oDefault = AppData.Accounts.getDefault(); return { 'Id': oDefault.id(), 'Email': oDefault.email(), 'FriendlyName': oDefault.friendlyName() }; }; AfterLogicApi.getCurrentAccountData = function() { var oDefault = AppData.Accounts.getCurrent(); return { 'Id': oDefault.id(), 'Email': oDefault.email(), 'FriendlyName': oDefault.friendlyName() }; }; /** * @return {boolean} */ AfterLogicApi.isMobile = function () { return AppData.IsMobile; }; /** * @constructor */ function CStorage() { Data.init(); } CStorage.prototype.setData = function (key, value) { Data.setVar(key, value); }; CStorage.prototype.removeData = function (key) { Data.setVar(key, ''); }; CStorage.prototype.getData = function (key) { return Data.getVar(key); }; CStorage.prototype.hasData = function (key) { return Data.hasVar(key); }; /** * @constructor */ function CPhone() { this.provider = null; this.report = ko.observable(''); this.missedCalls = ko.observable(false); this.phoneToCall = ko.observable(''); this.action = ko.observable(Enums.PhoneAction.Offline); this.action.subscribe(function(sAction) { switch (sAction) { case Enums.PhoneAction.Offline: this.provider.reconnect(60000); break; case Enums.PhoneAction.OfflineError: this.provider.reconnect(60000); break; case Enums.PhoneAction.OfflineInit: this.provider.init(); break; case Enums.PhoneAction.OfflineActive: break; case Enums.PhoneAction.Online: App.Screens.hidePopup(PhonePopup); App.desktopNotify('hide'); this.missedCalls(false); this.provider.reconnect(); this.provider.hangup(); break; case Enums.PhoneAction.OnlineActive: break; case Enums.PhoneAction.Outgoing: this.provider.call(this.getFormattedPhone(this.phoneToCall())); break; case Enums.PhoneAction.OutgoingConnect: break; case Enums.PhoneAction.Incoming: break; case Enums.PhoneAction.IncomingConnect: App.Screens.hidePopup(PhonePopup); App.desktopNotify('hide'); this.missedCalls(false); this.provider.answer(); break; } }, this); } CPhone.prototype.init = function () { $.ajaxSettings.cache = true; this.provider = AppData.User.VoiceProvider === 'sip' ? new CPhoneWebrtc() : new CPhoneTwilio(); this.action(Enums.PhoneAction.OfflineInit); /*this.provider = new CPhoneTwilio(function (bResult) { self.voiceApp(bResult); });*/ }; CPhone.prototype.log = function () { if (false && window.console && window.console.log) { window.console.log.apply(window.console, arguments); } }; CPhone.prototype.onGetScript = function (sStatus) { if (sStatus && sStatus === 'success') { this.log('*************** gettingScript_success'); } else { this.log('*************** gettingScript_unknownError'); this.action(Enums.PhoneAction.OfflineError); } }; CPhone.prototype.showError = function (iErrCode) { if (1 === Utils.pInt(iErrCode)) { App.Api.showError(Utils.i18n('PHONE/ERROR_SERVER_UNAVAILABLE'), false, true); } }; CPhone.prototype.phoneSupport = function (bIsWebrtc, sFlashVersion) { var fGetFlashVersion = function (){ // version format '00,0,000' try { //ie try { //avoid fp6 minor version lookup issues see: http://blog.deconcept.com/2006/01/11/getvariable-setvariable-crash-internet-explorer-flash-6/ var axo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.6'); try { axo.AllowScriptAccess = 'always'; } catch(eX) { return '6,0,0'; } } catch(eX) {} return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1]; } catch(eX) { //other browsers try { if(navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin){ return (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]).description.replace(/\D+/g, ",").match(/^,?(.+),?$/)[1]; } } catch(eXt) {} } return '0,0,0'; }; if (bIsWebrtc && !App.browser.chrome && !sFlashVersion && !bIsIosDevice) { this.log('*************** Browser not supported'); } else if (bIsIosDevice) { this.log('*************** Device not supported'); } else if (sFlashVersion && fGetFlashVersion() === '0,0,0') { this.log('*************** Please install flash player'); } else if (sFlashVersion && fGetFlashVersion() < sFlashVersion) { this.log('*************** Please reinstall flash player'); } }; CPhone.prototype.incomingCall = function (sNumber) { var self, oParameters, fShowAll ; this.action(Enums.PhoneAction.Incoming); if (sNumber) { self = this; oParameters = { 'Action': 'ContactSuggestions', 'Search': sNumber, 'PhoneOnly': '1' }; fShowAll = function (sText) { self.report(Utils.i18n('PHONE/INCOMING_CALL_FROM') + ' ' + sText); App.Screens.showPopup(PhonePopup, [{ text: sText }]); App.desktopNotify({ action: 'show', title: sText + ' calling...', body: 'Click here to answer.\r\n To drop the call, click End in the web interface.', callback: _.bind(function() { self.action(Enums.PhoneAction.IncomingConnect); }, self), timeout: 60000 }); }; App.Ajax.send(oParameters, function (oData) { if (oData && oData.Result && oData.Result.List && oData.Result.List[0] && oData.Result.List[0].Phones) { var sUser = ''; $.each(oData.Result.List[0].Phones, function (sKey, sUserPhone) { var oUser = oData.Result.List[0], regExp = /[()\s_\-]/g, sCleanedPhone = (sNumber.replace(regExp, '')), sCleanedUserPhone = (sUserPhone.replace(regExp, '')) ; if(sCleanedPhone === sCleanedUserPhone) { sUser = oUser.Name === '' ? oUser.Email + ' ' + sUserPhone : oUser.Name + ' ' + sUserPhone; fShowAll(sUser); return false; } }, this); if(sUser === '') { fShowAll(sNumber); } } else { fShowAll(sNumber); } }, this); this.missedCalls(true); } }; CPhone.prototype.getFormattedPhone = function (sPhone) { sPhone = sPhone.toString(); var oPrefixes = { '8': '7' }, sCleanedPhone = (/#/g).test(sPhone) ? sPhone.split('#')[1] : sPhone.replace(/[()\s_\-+]/g, '') ; _.each(oPrefixes, function(sVal, sKey){ sCleanedPhone = sCleanedPhone.replace(new RegExp('^' + sKey, 'g'), sVal); }); return sCleanedPhone; }; CPhone.prototype.getLogs = function (fResponseHandler, oContext) { this.missedCalls(false); this.provider.getLogs(fResponseHandler, oContext); }; CPhone.prototype.getCleanedPhone = function (sPhone) { sPhone = sPhone ? sPhone : ''; //return sPhone.replace(/client:|default/g, ''); return sPhone.replace('client:', ''); }; /** * @constructor */ function CPhoneWebrtc() { this.phone = App.Phone; this.action = App.Phone.action; this.stack = ko.observable(null); this.registerSession = ko.observable(null); this.callSession = ko.observable(null); this.stackConf = ko.observable(null); this.registerConf = ko.observable(null); this.hangupConf = ko.observable(null); //this.hasFatalError = ko.observable(false); this.isStarted = ko.observable(false); this.eventSessionBinded = this.eventSession.bind(this); //this.eventStackBinded = this.eventStack.bind(this); this.createStackErrorBinded = this.createStackError.bind(this); this.createStackBinded = this.createStack.bind(this); //this.videoLocal = document.getElementById("video_local"); //this.videoRemote = document.getElementById("video_remote"); this.audioRemote = document.getElementById("audio_remote"); this.interval = 0; } CPhoneWebrtc.prototype.init = function () { var self = this; $.getScript("static/js/sipml.js", function(sData, sStatus, jqXHR) { self.phone.onGetScript(sStatus); if (sStatus === 'success') { //self.voiceApp(true); /*tsk_utils_log_info = function (sMsg) { self.phone.log('*************** ***************' + sMsg); };*/ self.setConfigs(); // Supported values: info, warn, error, fatal. SIPml.setDebugLevel('fatal'); SIPml.init(self.createStackBinded, self.createStackErrorBinded); } }); }; CPhoneWebrtc.prototype.setConfigs = function () { this.stackConf({ realm: AppData.User.SipRealm, //realm: '192.168.0.59', impi: AppData.User.SipImpi, //impi: '102', impu: 'sip:' + AppData.User.SipImpi + '@' + AppData.User.SipRealm, //impu: 'sip:102@asterisk.afterlogic.com', password: AppData.User.SipPassword, //password: 'user02', enable_rtcweb_breaker: true, //enable_click2call: true, websocket_proxy_url: AppData.User.SipWebsocketProxyUrl, //websocket_proxy_url: 'ws://192.168.0.59:8088/ws', //outbound_proxy_url: AppData.User.SipOutboundProxyUrl, //ice_servers: [{ url: 'stun:stun.l.google.com:19302'}, { url:'turn:user@numb.viagenie.ca', credential:'myPassword'}], ice_servers: '[{ url: "stun:stun.afterlogic.com:3478"}]', events_listener: { events: '*', listener: this.eventSessionBinded } }); this.registerConf( { audio_remote: this.audioRemote, expires: 3600, events_listener: { events: '*', listener: this.eventSessionBinded }, sip_caps: [ { name: '+g.oma.sip-im', value: null }, { name: '+audio', value: null }, { name: '+sip.ice' }, { name: 'language', value: '\"en,fr\"' } ] }); this.hangupConf({ events_listener: { events: '*', listener: this.eventSessionBinded }}); }; CPhoneWebrtc.prototype.createStack = function () { this.stack(new SIPml.Stack(this.stackConf())); this.stack().start(); /*this.stack().addEventListener('*', function(e){ console.log("************************ *********************'"+e.type+"' event fired"); });*/ }; CPhoneWebrtc.prototype.createStackError = function () { this.phone.log('*************** Failed to initialize the engine'); }; CPhoneWebrtc.prototype.register = function () { this.registerSession(this.stack().newSession('register', this.registerConf())); this.registerSession().register(); }; /** * @param {{newSession,type}} ev */ CPhoneWebrtc.prototype.eventSession = function (ev) { this.phone.log('*************** ' + ev.type + ' (' + ev.description + ')'); var sEvType = ev.type; //http://sipml5.org/docgen/symbols/SIPml.EventTarget.html switch (sEvType) { case 'starting': break; case 'started': App.Api.hideError(); this.isStarted(true); this.register(); break; case 'stopping': case 'stopped': this.isStarted(false); this.createStack(); break; case 'failed_to_stop': break; case 'failed_to_start': this.phone.action(Enums.PhoneAction.OfflineError); this.isStarted(false); this.reconnect(30); break; case 'connecting': break; case 'connected': if(ev.description === 'Connected') { this.phone.action(Enums.PhoneAction.Online); } else if(ev.description === 'In call') { App.desktopNotify('hide'); } break; case 'terminating': case 'terminated': this.phone.action(Enums.PhoneAction.Online); if(ev.description === 'Disconnected') { this.createStack(); } break; case 'i_ao_request': /*if(ev.description === 'Ringing') { var self = this; $('body').on('click', function() { //self.callSession().dtmf('#7002'); //self.callSession().dtmf('7002'); //self.callSession().dtmf('#'); //this.callSession().dtmf('*'); self.callSession().dtmf('7'); self.callSession().dtmf('0'); self.callSession().dtmf('0'); self.callSession().dtmf('2'); }) }*/ break; case 'media_added': break; case 'media_removed': break; case 'm_stream_video_remote_added': break; case 'm_stream_audio_local_added': break; case 'm_stream_audio_remote_added': break; case 'i_request': break; case 'o_request': break; case 'sent_request': break; case 'cancelled_request': break; case 'i_new_call': this.callSession(ev.newSession); this.callSession().setConfiguration(this.registerConf()); this.phone.incomingCall(this.callSession()['getRemoteFriendlyName']()); break; case 'i_new_message': break; case 'm_permission_requested': break; case 'm_permission_accepted': /*if(this.action() === 'incoming') { this.report(Utils.i18n('PHONE/INCOMING_CALL_FROM') + ' ' + this.callSession()['getRemoteFriendlyName']()); } else { this.report(Utils.i18n('PHONE/CALL_IN_PROGRESS')); }*/ break; case 'm_permission_refused': break; case 'transport_error': break; case 'global_error': break; case 'message_error': break; case 'webrtc_error': break; } }; /** * @param {string} sPhone */ CPhoneWebrtc.prototype.call = function (sPhone) { if(!this.isStarted()) { //this.hasFatalError(false); this.createStack(); } else { this.action('outgoing'); this.callSession(this.stack().newSession('call-audio', this.registerConf())); this.callSession().call(sPhone); this.phone.log('*************** ' + this.callSession()['getRemoteFriendlyName']()); } }; CPhoneWebrtc.prototype.answer = function () { if(this.callSession()) { this.callSession().accept(this.registerConf()); } }; CPhoneWebrtc.prototype.hangup = function () { if (this.callSession()) { this.callSession().hangup(this.hangupConf()); this.callSession().hangup({events_listener: {events: '*', listener: this.eventSessionBinded}}); } /*if (this.stack() && this.stack().o_stack.e_state) { //unregister oRegisterSession = this.stack()['newSession']('register', { expires: 0 }); oRegisterSession.register(); } this.stack().stop();*/ }; CPhoneWebrtc.prototype.reconnect = (function () { var iIntervalId = 0; return function (iInterval) { clearInterval(iIntervalId); if (iInterval) { iIntervalId = setInterval(_.bind(function () { }, this), iInterval); } }; }()); CPhoneWebrtc.prototype.getLogs = function (fResponseHandler, oContext) { /*var oParameters = { 'Action': 'GetWebrtcLogs' }; App.Ajax.send(oParameters, fResponseHandler, oContext);*/ fResponseHandler.call(oContext); }; /** * @constructor */ function CPhoneFlash() { this.flash = null; this.jqFlash = null; this.phone = App.Phone; this.voiceApp = App.Phone.voiceApp; this.report = App.Phone.report; this.action = App.Phone.action; this.voiceImpi = AppData.User.VoiceImpi; this.voicePassword = AppData.User.VoicePassword; // this.voiceUrl = AppData.User.VoiceWebsocketProxyUrl; this.sessionid = ko.observable(''); this.callState = ko.observable(''); this.initStatus = ko.observable(false); this.connectStatus = ko.observable(false); this.init(); } CPhoneFlash.prototype.init = function () { var self = this; $.getScript("static/js/swfobject.js", function(sData, sStatus, jqXHR) { if (sStatus === 'success') { self.voiceApp(true); swfobject.embedSWF( "static/freeswitch.swf", //swf url "flash", //id "214", //width "137", //height "9.0.0", //required Flash player version "expressInstall.swf", //express install swf url {rtmp_url: 'rtmp://217.199.220.26/phone'}, //flashvars {allowScriptAccess: 'always', bgcolor: '#ece9e0'}, //params [], //attributes false //callback fn ); self.callbacks(); } }); }; CPhoneFlash.prototype.log = function (sDesc) { }; CPhoneFlash.prototype.showPrivacy = function () { // this.action(Enums.PhoneAction.Settings); App.Screens.showPopup(PhonePopup, [{ Action: Enums.PhoneAction.Settings, Callback: this.launchFlash.bind(this) }]); var fake_flash = $("#fake_flash"), oOffset = fake_flash.offset(), iWidth = fake_flash.width() ; this.jqFlash.css("left", oOffset.left + (iWidth/2) - 107);// 107 - initial width of freeswitch.swf divided in half this.jqFlash.css("top", oOffset.top); this.jqFlash.css("visibility", "visible"); this.flash.showPrivacy(); }; CPhoneFlash.prototype.checkMic = function () { return this.flash.isMuted(); // return true; }; CPhoneFlash.prototype.login = function (sName, sPassword) { this.flash.login(sName, sPassword); }; CPhoneFlash.prototype.newCall = function () { // $("#callout").data('account', account); }; CPhoneFlash.prototype.call = function (sPhone) { // $("#flash")[0].makeCall('sip:' + sPhone + '@217.199.220.26', '7003@217.199.220.26', []); // number@217.199.220.26, 7003@217.199.220.26 ,[] this.flash.makeCall('sip:7002@217.199.220.24', '7003@217.199.220.26', []); }; CPhoneFlash.prototype.answer = function (uuid) { this.flash.answer(uuid); }; CPhoneFlash.prototype.hangup = function (uuid) { this.flash.hangup(uuid); }; CPhoneFlash.prototype.addCall = function (uuid, name, number, account) { }; CPhoneFlash.prototype.launchFlash = function (uuid, name, number, account) { this.jqFlash.css("top", '-200px'); }; CPhoneFlash.prototype.callbacks = function () { var self = this; window.onInit = function () { self.log('**************** onInit'); self.initStatus(true); }; window.onConnected = function (sessionid) { self.log('**************** onConnected ' + '(' + sessionid + ')'); self.connectStatus(true); self.sessionid(sessionid); self.jqFlash = $("#flash"); self.flash = self.jqFlash[0]; if (self.checkMic()) { self.showPrivacy(); } self.login('7003@217.199.220.26', '7003voippassword'); // self.login('7003@217.199.220.24', '7003voippassword'); }; window.onDisconnected = function () { self.log('**************** onDisconnected'); }; window.onEvent = function (data) { self.log('**************** onEvent ' + '(' + data + ')'); }; window.onLogin = function (status, user, domain) { self.log('**************** onLogin ' + '(' + status + ', ' + user + ', ' + domain + ')'); // $("#flash")[0].register('7003@217.199.220.26', user); // $('#flash')[0].setMic(0); // self.showPrivacy(); // self.call(); }; window.onLogout = function (user, domain) { self.log('**************** onLogout ' + '(' + user + ', ' + domain + ')'); }; window.onMakeCall = function (uuid, number, account) { self.log('**************** onMakeCall ' + '(' + uuid + ', ' + number + ', ' + account + ')'); }; window.onHangup = function (uuid, cause) { self.log('**************** onHangup ' + '(' + uuid + ', ' + cause + ')'); }; window.onIncomingCall = function (uuid, name, number, account, evt) { self.log('**************** onIncomingCall ' + '(' + uuid + ', ' + name + ', ' + number + ', ' + account + ', ' + evt + ')'); self.addCall(uuid, name, number); }; window.onDisplayUpdate = function (uuid, name, number) { self.log('**************** onDisplayUpdate ' + '(' + uuid + ', ' + name + ', ' + number + ')'); }; window.onCallState = function (uuid, state) { self.log('**************** onCallState ' + '(' + uuid + ', ' + state + ')'); self.callState(state); }; window.onDebug = function (message) { self.log('**************** onDebug ' + '(' + message + ')'); }; window.onAttach = function (uuid) { self.log('**************** onAttach ' + '(' + uuid + ')'); }; }; /** * @constructor */ function CPhoneTwilio() { this.phone = App.Phone; this.action = App.Phone.action; this.device = null; this.connection = null; this.token = null; this.webSocket = null; } CPhoneTwilio.prototype.init = function () { App.Ajax.send( {'Action': 'GetTwilioToken'}, this.onTokenResponse, this); }; CPhoneTwilio.prototype.onTokenResponse = function (oResult, oRequest) { var self = this; if (oResult && oResult.Result) { this.phone.log('*************** twilioToken_requestTrue'); $.ajaxSettings.cache = true; $.getScript( "//static.twilio.com/libs/twiliojs/1.2/twilio.min.js", function(sData, sStatus, jqXHR) { self.phone.onGetScript(sStatus); if (sStatus === 'success') { self.token = oResult.Result; self.setupDevice(oResult.Result); } } ); } else { self.phone.onGetScript(); } }; CPhoneTwilio.prototype.setupDevice = function (sToken) { var self = this; this.phone.log('*************** setup'); this.phone.phoneSupport(false, '10,1,000'); this.device = Twilio.Device; this.device.setup(sToken, { //rtc: false, //debug: true }); /*************** events ***************/ this.device.ready(function (oDevice) { self.phone.log('*************** ready ', oDevice); self.webSocket = window.socket; self.action(Enums.PhoneAction.Online); }); this.device.offline(function (oDevice) { self.phone.log('*************** offline ', oDevice); self.action(Enums.PhoneAction.Offline); }); this.device.error(function (oError) { self.phone.log('*************** error ', oError); switch (oError.message) { case 'This AccessToken is no longer valid': case 'Cannot register. Token not validated': self.token = null; self.device.destroy(); break; } self.action(Enums.PhoneAction.OfflineError); }); this.device.connect(function (oConnection) { //This is triggered when a connection is opened (incoming||outgoing) self.phone.log('*************** connect ', oConnection); if (oConnection.message.Direction === "outbound") { self.action(Enums.PhoneAction.Outgoing); } else if (oConnection.message.Direction === "inbound") { self.action(Enums.PhoneAction.Incoming); } }); this.device.disconnect(function (oConnection) { self.phone.log('*************** disconnect ', oConnection); self.action(Enums.PhoneAction.Online); }); this.device.incoming(function (oConnection) { self.phone.log('*************** incoming ', oConnection); self.connection = oConnection; self.phone.incomingCall(oConnection.parameters.From); }); // This is triggered when an incoming connection is canceled by the caller before it is accepted by the device. this.device.cancel( function (oConnection) { self.phone.log('*************** cancel ', oConnection); self.action(Enums.PhoneAction.Online); }); // Register a handler function to be called when availability state changes for any client currently associated with your Twilio account. this.device.presence( function ( presenceEvent) { self.phone.log('*************** presence ', presenceEvent); }); }; CPhoneTwilio.prototype.call = function (sPhoneNumber) { this.connection = this.device.connect({ "PhoneNumber": sPhoneNumber, "Direction": 'outbound' }); }; CPhoneTwilio.prototype.answer = function () { this.connection.accept(); }; CPhoneTwilio.prototype.hangup = function () { if (this.connection) { if (this.connection.status && this.connection.status() === 'pending') { // for incoming call this.connection.reject(); } else { this.connection.disconnect(); } // in the first few seconds of the call connection not close if (this.connection.status() !== 'closed') { _.delay(_.bind(function () { this.hangup(); }, this), 1000); } } }; CPhoneTwilio.prototype.reconnect = (function () { var iIntervalId = 0; return function (iInterval) { clearInterval(iIntervalId); if (iInterval) { iIntervalId = setInterval(_.bind(function () { if (this.device && this.token) { this.device.setup(this.token); } else { this.init(); } }, this), iInterval); } }; }()); CPhoneTwilio.prototype.getLogs = function (fResponseHandler, oContext) { var oParameters = { 'Action': 'GetTwilioLogs', //'Status': 'no-answer', 'StartTime': moment().subtract('months', 3).format("YYYY-MM-DD") //subtract 3 months from now }; App.Ajax.send(oParameters, fResponseHandler, oContext); }; /** * @todo * @param {Object} oOpenPgp * @param {string=} sPrefix * @constructor */ function OpenPgp(oOpenPgp, sPrefix) { this.pgp = oOpenPgp; this.pgpKeyring = new this.pgp.Keyring(new this.pgp.Keyring.localstore(sPrefix)); this.keys = ko.observableArray([]); this.reloadKeysFromStorage(); } OpenPgp.prototype.pgp = null; OpenPgp.prototype.pgpKeyring = null; OpenPgp.prototype.keys = []; /** * @return {Array} */ OpenPgp.prototype.getKeys = function () { return this.keys(); }; /** * @return {mixed} */ OpenPgp.prototype.getKeysObservable = function () { return this.keys; }; /** * @private */ OpenPgp.prototype.reloadKeysFromStorage = function () { var aKeys = [], oOpenpgpKeys = this.pgpKeyring.getAllKeys() ; _.each(oOpenpgpKeys, function (oItem) { if (oItem && oItem.primaryKey) { aKeys.push(new OpenPgpKey(oItem)); } }); this.keys(aKeys); }; /** * @private * @param {Array} aKeys * @return {Array} */ OpenPgp.prototype.convertToNativeKeys = function (aKeys) { return _.map(aKeys, function (oItem) { return (oItem && oItem.pgpKey) ? oItem.pgpKey : oItem; }); }; /** * @private */ OpenPgp.prototype.cloneKey = function (oKey) { var oPrivateKey = null; if (oKey) { oPrivateKey = this.pgp.key.readArmored(oKey.armor()); if (oPrivateKey && !oPrivateKey.err && oPrivateKey.keys && oPrivateKey.keys[0]) { oPrivateKey = oPrivateKey.keys[0]; if (!oPrivateKey || !oPrivateKey.primaryKey) { oPrivateKey = null; } } else { oPrivateKey = null; } } return oPrivateKey; }; /** * @private */ OpenPgp.prototype.decryptKeyHelper = function (oResult, oKey, sPassword, sKeyEmail) { if (oKey) { try { oKey.decrypt(Utils.pString(sPassword)); if (!oKey || !oKey.primaryKey || !oKey.primaryKey.isDecrypted) { oResult.addError(OpenPgpResult.Enum.KeyIsNotDecodedError, sKeyEmail || ''); } } catch (e) { oResult.addExceptionMessage(e, OpenPgpResult.Enum.KeyIsNotDecodedError, sKeyEmail || ''); } } else { oResult.addError(OpenPgpResult.Enum.KeyIsNotDecodedError, sKeyEmail || ''); } }; /** * @private */ OpenPgp.prototype.verifyMessageHelper = function (oResult, sFromEmail, oDecryptedMessage) { var bResult = false, oValidKey = null, aVerifyResult = [], aVerifyKeysId = [], aPublicKeys = [] ; if (oDecryptedMessage && oDecryptedMessage.getSigningKeyIds) { aVerifyKeysId = oDecryptedMessage.getSigningKeyIds(); if (aVerifyKeysId && 0 < aVerifyKeysId.length) { aPublicKeys = this.findKeysByEmails([sFromEmail], true); if (!aPublicKeys || 0 === aPublicKeys.length) { oResult.addNotice(OpenPgpResult.Enum.PublicKeyNotFoundNotice, sFromEmail); } else { aVerifyResult = []; try { aVerifyResult = oDecryptedMessage.verify(this.convertToNativeKeys(aPublicKeys)); } catch (e) { oResult.addNotice(OpenPgpResult.Enum.VerifyErrorNotice, sFromEmail); } if (aVerifyResult && 0 < aVerifyResult.length) { oValidKey = _.find(aVerifyResult, function (oItem) { return oItem && oItem.keyid && oItem.valid; }); if (oValidKey && oValidKey.keyid && aPublicKeys && aPublicKeys[0] && oValidKey.keyid.toHex().toLowerCase() === aPublicKeys[0].getId()) { bResult = true; } else { oResult.addNotice(OpenPgpResult.Enum.VerifyErrorNotice, sFromEmail); } } } } else { oResult.addNotice(OpenPgpResult.Enum.NoSignDataNotice); } } else { oResult.addError(OpenPgpResult.Enum.UnknownError); } if (!bResult && !oResult.hasNotices()) { oResult.addNotice(OpenPgpResult.Enum.VerifyErrorNotice); } // window.console.log(oResult); return bResult; }; /** * @param {string} sUserID * @param {string} sPassword * @param {number} nKeyLength * * @return {OpenPgpResult} */ OpenPgp.prototype.generateKey = function (sUserID, sPassword, nKeyLength) { var oResult = new OpenPgpResult(), mKeyPair = null ; try { // mKeyPair = this.pgp.generateKeyPair(1, Utils.pInt(nKeyLength), sUserID, Utils.trim(sPassword)); mKeyPair = this.pgp.generateKeyPair({ 'userId': sUserID, 'numBits': Utils.pInt(nKeyLength), 'passphrase': Utils.trim(sPassword) }); } catch (e) { oResult.addExceptionMessage(e); } if (mKeyPair && mKeyPair.privateKeyArmored) { try { this.pgpKeyring.privateKeys.importKey(mKeyPair.privateKeyArmored); this.pgpKeyring.publicKeys.importKey(mKeyPair.publicKeyArmored); this.pgpKeyring.store(); } catch (e) { oResult.addExceptionMessage(e, OpenPgpResult.Enum.GenerateKeyError); } } else { oResult.addError(OpenPgpResult.Enum.GenerateKeyError); } this.reloadKeysFromStorage(); return oResult; }; /** * @private * @param {string} sArmor * @return {Array} */ OpenPgp.prototype.splitKeys = function (sArmor) { var aResult = [], iCount = 0, iLimit = 30, aMatch = null, sKey = Utils.trim(sArmor), oReg = /[\-]{3,6}BEGIN[\s]PGP[\s](PRIVATE|PUBLIC)[\s]KEY[\s]BLOCK[\-]{3,6}[\s\S]+?[\-]{3,6}END[\s]PGP[\s](PRIVATE|PUBLIC)[\s]KEY[\s]BLOCK[\-]{3,6}/gi ; sKey = sKey.replace(/[\r\n]([a-zA-Z0-9]{2,}:[^\r\n]+)[\r\n]+([a-zA-Z0-9\/\\+=]{10,})/g, '\n$1---xyx---$2') .replace(/[\n\r]+/g, '\n').replace(/---xyx---/g, '\n\n'); do { aMatch = oReg.exec(sKey); if (!aMatch || 0 > iLimit) { break; } if (aMatch[0] && aMatch[1] && aMatch[2] && aMatch[1] === aMatch[2]) { if ('PRIVATE' === aMatch[1] || 'PUBLIC' === aMatch[1]) { aResult.push([aMatch[1], aMatch[0]]); iCount++; } } iLimit--; } while (true); return aResult; }; /** * @param {string} sArmor * @return {OpenPgpResult} */ OpenPgp.prototype.importKeys = function (sArmor) { sArmor = Utils.trim(sArmor); var iIndex = 0, iCount = 0, oResult = new OpenPgpResult(), aData = null, aKeys = [] ; if (!sArmor) { return oResult.addError(OpenPgpResult.Enum.InvalidArgumentErrors); } aKeys = this.splitKeys(sArmor); for (iIndex = 0; iIndex < aKeys.length; iIndex++) { aData = aKeys[iIndex]; if ('PRIVATE' === aData[0]) { try { this.pgpKeyring.privateKeys.importKey(aData[1]); iCount++; } catch (e) { oResult.addExceptionMessage(e, OpenPgpResult.Enum.ImportKeyError, 'private'); } } else if ('PUBLIC' === aData[0]) { try { this.pgpKeyring.publicKeys.importKey(aData[1]); iCount++; } catch (e) { oResult.addExceptionMessage(e, OpenPgpResult.Enum.ImportKeyError, 'public'); } } } if (0 < iCount) { this.pgpKeyring.store(); } else { oResult.addError(OpenPgpResult.Enum.ImportNoKeysFoundError); } this.reloadKeysFromStorage(); return oResult; }; /** * @param {string} sArmor * @return {Array|boolean} */ OpenPgp.prototype.getArmorInfo = function (sArmor) { sArmor = Utils.trim(sArmor); var iIndex = 0, iCount = 0, oKey = null, aResult = [], aData = null, aKeys = [] ; if (!sArmor) { return false; } aKeys = this.splitKeys(sArmor); for (iIndex = 0; iIndex < aKeys.length; iIndex++) { aData = aKeys[iIndex]; if ('PRIVATE' === aData[0]) { try { oKey = this.pgp.key.readArmored(aData[1]); if (oKey && !oKey.err && oKey.keys && oKey.keys[0]) { aResult.push(new OpenPgpKey(oKey.keys[0])); } iCount++; } catch (e) { aResult.push(null); } } else if ('PUBLIC' === aData[0]) { try { oKey = this.pgp.key.readArmored(aData[1]); if (oKey && !oKey.err && oKey.keys && oKey.keys[0]) { aResult.push(new OpenPgpKey(oKey.keys[0])); } iCount++; } catch (e) { aResult.push(null); } } } return aResult; }; /** * @param {string} sID * @param {boolean} bPublic * @return {OpenPgpKey|null} */ OpenPgp.prototype.findKeyByID = function (sID, bPublic) { bPublic = !!bPublic; sID = sID.toLowerCase(); var oKey = _.find(this.keys(), function (oKey) { var oResult = false, aKeys = null ; if (oKey && bPublic === oKey.isPublic()) { aKeys = oKey.pgpKey.getKeyIds(); if (aKeys) { oResult = _.find(aKeys, function (oKey) { return oKey && oKey.toHex && sID === oKey.toHex().toLowerCase(); }); } } return !!oResult; }); return oKey ? oKey : null; }; /** * @param {Array} aEmail * @param {boolean} bIsPublic * @param {OpenPgpResult=} oResult * @return {Array} */ OpenPgp.prototype.findKeysByEmails = function (aEmail, bIsPublic, oResult) { bIsPublic = !!bIsPublic; var aResult = [], aKeys = this.keys() ; _.each(aEmail, function (sEmail) { var oKey = _.find(aKeys, function (oKey) { return oKey && bIsPublic === oKey.isPublic() && sEmail === oKey.getEmail(); }); if (oKey) { aResult.push(oKey); } else { if (oResult) { oResult.addError(bIsPublic ? OpenPgpResult.Enum.PublicKeyNotFoundError : OpenPgpResult.Enum.PrivateKeyNotFoundError, sEmail); } } }); return aResult; }; /** * @param {string} sData * @param {string} sAccountEmail * @param {string} sFromEmail * @param {string=} sPrivateKeyPassword = '' * @return {string} */ OpenPgp.prototype.decryptAndVerify = function (sData, sAccountEmail, sFromEmail, sPrivateKeyPassword) { var self = this, oMessage = null, oPrivateEmailKey = null, oPrivateKey = null, oPrivateKeyClone = null, oMessageDecrypted = null, oResult = new OpenPgpResult(), aEncryptionKeyIds = [] ; oMessage = this.pgp.message.readArmored(sData); if (oMessage && oMessage.decrypt) { aEncryptionKeyIds = oMessage.getEncryptionKeyIds(); if (aEncryptionKeyIds) { oPrivateKey = null; oPrivateEmailKey = null; _.each(aEncryptionKeyIds, function (oKey) { if (!oPrivateEmailKey) { oPrivateEmailKey = self.findKeyByID(oKey.toHex(), false); if (oPrivateEmailKey && sAccountEmail !== oPrivateEmailKey.getEmail()) { oPrivateEmailKey = null; } } }); if (oPrivateEmailKey) { oPrivateKey = oPrivateEmailKey; } if (!oPrivateKey) { _.each(aEncryptionKeyIds, function (oKey) { if (!oPrivateKey) { oPrivateKey = self.findKeyByID(oKey.toHex(), false); } }); } } if (!oPrivateKey) { oResult.addError(OpenPgpResult.Enum.PrivateKeyNotFoundError); } else { oPrivateKeyClone = this.cloneKey(this.convertToNativeKeys([oPrivateKey])[0]); this.decryptKeyHelper(oResult, oPrivateKeyClone, sPrivateKeyPassword, oPrivateKey.getEmail()); if (oPrivateKeyClone && !oResult.hasErrors()) { try { oMessageDecrypted = oMessage.decrypt(oPrivateKeyClone); } catch (e) { oResult.addExceptionMessage(e, OpenPgpResult.Enum.DecryptError); oMessageDecrypted = null; } } if (oMessageDecrypted && !oResult.hasErrors()) { this.verifyMessageHelper(oResult, sFromEmail, oMessageDecrypted); oResult.result = oMessageDecrypted.getText(); } } } return oResult; }; /** * @param {string} sData * @param {string} sFromEmail * @return {string} */ OpenPgp.prototype.verify = function (sData, sFromEmail) { var oMessageDecrypted = null, oResult = new OpenPgpResult() ; oMessageDecrypted = this.pgp.cleartext.readArmored(sData); if (oMessageDecrypted && oMessageDecrypted.getText && oMessageDecrypted.verify) { this.verifyMessageHelper(oResult, sFromEmail, oMessageDecrypted); oResult.result = oMessageDecrypted.getText(); } else { oResult.addError(OpenPgpResult.Enum.CanNotReadMessage); } return oResult; }; /** * @param {string} sData * @param {Array} aPrincipalsEmail * @return {string} */ OpenPgp.prototype.encrypt = function (sData, aPrincipalsEmail) { var oResult = new OpenPgpResult(), aPublicKeys = this.findKeysByEmails(aPrincipalsEmail, true, oResult) ; if (!oResult.hasErrors()) { try { oResult.result = this.pgp.encryptMessage( this.convertToNativeKeys(aPublicKeys), sData); } catch (e) { oResult.addExceptionMessage(e, OpenPgpResult.Enum.EncryptError); } } return oResult; }; /** * @param {string} sData * @param {string} sFromEmail * @param {string=} sPrivateKeyPassword * @return {string} */ OpenPgp.prototype.sign = function (sData, sFromEmail, sPrivateKeyPassword) { var oResult = new OpenPgpResult(), oPrivateKey = null, oPrivateKeyClone = null, aPrivateKeys = this.findKeysByEmails([sFromEmail], false, oResult) ; if (!oResult.hasErrors()) { oPrivateKey = this.convertToNativeKeys(aPrivateKeys)[0]; oPrivateKeyClone = this.cloneKey(oPrivateKey); this.decryptKeyHelper(oResult, oPrivateKeyClone, sPrivateKeyPassword, sFromEmail); if (oPrivateKeyClone && !oResult.hasErrors()) { try { oResult.result = this.pgp.signClearMessage([oPrivateKeyClone], sData); } catch (e) { oResult.addExceptionMessage(e, OpenPgpResult.Enum.SignError, sFromEmail); } } } return oResult; }; /** * @param {string} sData * @param {string} sFromEmail * @param {Array} aPrincipalsEmail * @param {string=} sPrivateKeyPassword * @return {string} */ OpenPgp.prototype.signAndEncrypt = function (sData, sFromEmail, aPrincipalsEmail, sPrivateKeyPassword) { var oPrivateKey = null, oPrivateKeyClone = null, oResult = new OpenPgpResult(), aPrivateKeys = this.findKeysByEmails([sFromEmail], false, oResult), aPublicKeys = this.findKeysByEmails(aPrincipalsEmail, true, oResult) ; if (!oResult.hasErrors()) { oPrivateKey = this.convertToNativeKeys(aPrivateKeys)[0]; oPrivateKeyClone = this.cloneKey(oPrivateKey); this.decryptKeyHelper(oResult, oPrivateKeyClone, sPrivateKeyPassword, sFromEmail); if (oPrivateKeyClone && !oResult.hasErrors()) { try { oResult.result = this.pgp.signAndEncryptMessage( this.convertToNativeKeys(aPublicKeys), oPrivateKeyClone, sData); } catch (e) { oResult.addExceptionMessage(e, OpenPgpResult.Enum.SignAndEncryptError); } } } return oResult; }; /** * @param {OpenPgpKey} oKey */ OpenPgp.prototype.deleteKey = function (oKey) { var oResult = new OpenPgpResult(); if (oKey) { try { this.pgpKeyring[oKey.isPrivate() ? 'privateKeys' : 'publicKeys'].removeForId(oKey.getFingerprint()); this.pgpKeyring.store(); } catch (e) { oResult.addExceptionMessage(e, OpenPgpResult.Enum.DeleteError); } } else { oResult.addError(oKey ? OpenPgpResult.Enum.UnknownError : OpenPgpResult.Enum.InvalidArgumentError); } this.reloadKeysFromStorage(); return oResult; }; /** * @todo * @param {Object} oOpenPgpKey * @constructor */ function OpenPgpKey(oOpenPgpKey) { this.pgpKey = oOpenPgpKey; var oPrimaryUser = this.pgpKey.getPrimaryUser(); this.user = (oPrimaryUser && oPrimaryUser.user) ? oPrimaryUser.user.userId.userid : (this.pgpKey.users && this.pgpKey.users[0] ? this.pgpKey.users[0].userId.userid : ''); this.emailParts = Utils.getEmailParts(this.user); } /** * @type {Object} */ OpenPgpKey.prototype.pgpKey = null; /** * @type {Object} */ OpenPgpKey.prototype.emailParts = null; /** * @type {string} */ OpenPgpKey.prototype.user = ''; /** * @return {string} */ OpenPgpKey.prototype.getId = function () { return this.pgpKey.primaryKey.getKeyId().toHex().toLowerCase(); }; /** * @return {string} */ OpenPgpKey.prototype.getEmail = function () { return this.emailParts['email'] || this.user; }; /** * @return {string} */ OpenPgpKey.prototype.getUser = function () { return this.user; }; /** * @return {string} */ OpenPgpKey.prototype.getFingerprint = function () { return this.pgpKey.primaryKey.getFingerprint(); }; /** * @return {number} */ OpenPgpKey.prototype.getBitSize = function () { return this.pgpKey.primaryKey.getBitSize(); }; /** * @return {string} */ OpenPgpKey.prototype.getArmor = function () { return this.pgpKey.armor(); }; /** * @return {boolean} */ OpenPgpKey.prototype.isPrivate = function () { return !!this.pgpKey.isPrivate(); }; /** * @return {boolean} */ OpenPgpKey.prototype.isPublic = function () { return !this.isPrivate(); }; /** * @todo * @constructor */ function OpenPgpResult() { this.result = true; this.errors = null; this.notices = null; this.exceptions = null; } OpenPgpResult.Enum = { 'UnknownError': 0, 'UnknownNotice': 1, 'InvalidArgumentError': 2, 'GenerateKeyError': 10, 'ImportKeyError': 20, 'ImportNoKeysFoundError': 21, 'PrivateKeyNotFoundError': 30, 'PublicKeyNotFoundError': 31, 'KeyIsNotDecodedError': 32, 'SignError': 40, 'VerifyError': 41, 'EncryptError': 42, 'DecryptError': 43, 'SignAndEncryptError': 44, 'VerifyAndDecryptError': 45, 'CanNotReadMessage': 50, 'CanNotReadKey': 51, 'DeleteError': 60, 'PublicKeyNotFoundNotice': 70, 'PrivateKeyNotFoundNotice': 71, 'VerifyErrorNotice': 72, 'NoSignDataNotice': 73 }; /** * @type {mixed} */ OpenPgpResult.prototype.result = false; /** * @type {Array|null} */ OpenPgpResult.prototype.errors = null; /** * @type {Array|null} */ OpenPgpResult.prototype.notices = null; /** * @param {number} iCode * @param {string} sValue * @return {OpenPgpResult} */ OpenPgpResult.prototype.addError = function (iCode, sValue) { this.result = false; this.errors = this.errors || []; this.errors.push([iCode || OpenPgpResult.Enum.UnknownError, sValue || '']); return this; }; /** * @param {number} iCode * @param {string} sValue * @return {OpenPgpResult} */ OpenPgpResult.prototype.addNotice = function (iCode, sValue) { this.notices = this.notices || []; this.notices.push([iCode || OpenPgpResult.Enum.UnknownNotice, sValue || '']); return this; }; /** * @param {Error} e * @param {number=} iErrorCode * @param {string=} sErrorMessage * @return {OpenPgpResult} */ OpenPgpResult.prototype.addExceptionMessage = function (e, iErrorCode, sErrorMessage) { if (e) { this.result = false; this.exceptions = this.exceptions || []; this.exceptions.push('' + (e.name || 'unknown') + ': ' + (e.message || '')); } if (!Utils.isUnd(iErrorCode)) { this.addError(iErrorCode, sErrorMessage); } return this; }; /** * @return {boolean} */ OpenPgpResult.prototype.hasErrors = function () { return this.errors && 0 < this.errors.length; }; /** * @return {boolean} */ OpenPgpResult.prototype.hasNotices = function () { return this.notices && 0 < this.notices.length; }; /** * @constructor */ function AlertPopup() { this.alertDesc = ko.observable(''); this.closeCallback = null; this.title = ko.observable(''); this.okButtonText = ko.observable(Utils.i18n('MAIN/BUTTON_OK')); } /** * @param {string} sDesc * @param {Function=} fCloseCallback = null * @param {string=} sTitle = '' * @param {string=} sOkButtonText = 'Ok' */ AlertPopup.prototype.onShow = function (sDesc, fCloseCallback, sTitle, sOkButtonText) { this.alertDesc(sDesc); this.closeCallback = fCloseCallback || null; this.title(sTitle || ''); this.okButtonText(sOkButtonText || Utils.i18n('MAIN/BUTTON_OK')); }; /** * @return {string} */ AlertPopup.prototype.popupTemplate = function () { return 'Popups_AlertPopupViewModel'; }; AlertPopup.prototype.onEnterHandler = function () { this.close(); }; AlertPopup.prototype.close = function () { if (Utils.isFunc(this.closeCallback)) { this.closeCallback(); } this.closeCommand(); }; /** * @constructor */ function ConfirmPopup() { this.fConfirmCallback = null; this.confirmDesc = ko.observable(''); this.title = ko.observable(''); this.okButtonText = ko.observable(Utils.i18n('MAIN/BUTTON_OK')); this.cancelButtonText = ko.observable(Utils.i18n('MAIN/BUTTON_CANCEL')); this.shown = false; } /** * @param {string} sDesc * @param {Function} fConfirmCallback * @param {string=} sTitle = '' * @param {string=} sOkButtonText = '' * @param {string=} sCancelButtonText = '' */ ConfirmPopup.prototype.onShow = function (sDesc, fConfirmCallback, sTitle, sOkButtonText, sCancelButtonText) { this.title(sTitle || ''); this.okButtonText(sOkButtonText || Utils.i18n('MAIN/BUTTON_OK')); this.cancelButtonText(sCancelButtonText || Utils.i18n('MAIN/BUTTON_CANCEL')); if (Utils.isFunc(fConfirmCallback)) { this.fConfirmCallback = fConfirmCallback; this.confirmDesc(sDesc); } this.shown = true; }; ConfirmPopup.prototype.onHide = function () { this.shown = false; }; /** * @return {string} */ ConfirmPopup.prototype.popupTemplate = function () { return 'Popups_ConfirmPopupViewModel'; }; ConfirmPopup.prototype.onEnterHandler = function () { this.yesClick(); }; ConfirmPopup.prototype.yesClick = function () { if (this.shown && this.fConfirmCallback) { this.fConfirmCallback(true); } this.closeCommand(); }; ConfirmPopup.prototype.noClick = function () { if (this.fConfirmCallback) { this.fConfirmCallback(false); } this.closeCommand(); }; ConfirmPopup.prototype.onEscHandler = function () { this.noClick(); }; /** * @constructor */ function AccountCreatePopup() { this.editedAccountId = AppData.Accounts.editedId; this.loading = ko.observable(false); this.friendlyName = ko.observable(''); this.email = ko.observable(''); this.incomingMailLogin = ko.observable(''); this.incomingLoginFocused = ko.observable(false); this.incomingMailPassword = ko.observable(''); this.incomingMailPort = ko.observable(143); this.incomingMailServer = ko.observable(''); this.outgoingMailLogin = ko.observable(''); this.outgoingMailPassword = ko.observable(''); this.outgoingMailPort = ko.observable(25); this.outgoingMailServer = ko.observable(''); this.incomingServerFocused = ko.observable(false); this.outServerFocused = ko.observable(false); this.useSmtpAuthentication = ko.observable(true); this.friendlyNameFocus = ko.observable(false); this.emailFocus = ko.observable(false); this.incomingPasswordFocus = ko.observable(false); this.incomingMailFocus = ko.observable(false); this.isFirstStep = ko.observable(true); this.isFirstStep.subscribe(function (bValue) { if (!bValue) { this.clearServers(); } }, this); this.incomingLoginFocused.subscribe(function () { if (this.incomingLoginFocused() && this.incomingMailLogin() === '') { this.incomingMailLogin(this.email()); } }, this); this.outServerFocused.subscribe(function () { if (this.outServerFocused() && this.outgoingMailServer() === '') { this.outgoingMailServer(this.incomingMailServer()); } }, this); } /** * @return {string} */ AccountCreatePopup.prototype.popupTemplate = function () { return 'Popups_AccountCreatePopupViewModel'; }; AccountCreatePopup.prototype.init = function () { this.isFirstStep(true); this.friendlyName(''); this.email(''); this.incomingMailLogin(''); this.incomingLoginFocused(false); this.incomingMailPassword(''); this.outgoingMailLogin(''); this.outgoingMailPassword(''); this.outServerFocused(false); this.clearServers(); }; AccountCreatePopup.prototype.clearServers = function () { this.incomingMailPort(143); this.incomingMailServer(''); this.outgoingMailPort(25); this.outgoingMailServer(''); this.useSmtpAuthentication(true); }; AccountCreatePopup.prototype.onShow = function () { this.emailFocus(true); this.init(); }; AccountCreatePopup.prototype.onFirstSaveClick = function () { if (!this.isEmptyFirstFields()) { var oParameters = { 'Action': 'EmailDomainData', 'Email': this.email() } ; this.loading(true); App.Ajax.send(oParameters, this.onEmailDomainDataResponse, this); } else { this.loading(false); } }; AccountCreatePopup.prototype.onSecondSaveClick = function () { if (!this.isEmptySecondFields()) { var oParameters = { 'Action': 'AccountCreate', 'AccountID': this.editedAccountId(), 'FriendlyName': this.friendlyName(), 'Email': this.email(), 'IncomingMailLogin': this.incomingMailLogin(), 'IncomingMailPassword': this.incomingMailPassword(), 'IncomingMailServer': this.incomingMailServer(), 'IncomingMailPort': parseInt(this.incomingMailPort(), 10), 'OutgoingMailServer': this.outgoingMailServer(), 'OutgoingMailLogin': this.outgoingMailLogin(), 'OutgoingMailPassword': this.outgoingMailPassword(), 'OutgoingMailPort': parseInt(this.outgoingMailPort(), 10), 'OutgoingMailAuth': this.useSmtpAuthentication() ? 2 : 0 } ; this.loading(true); App.Ajax.send(oParameters, this.onAccountCreateResponse, this); } else { this.loading(false); } }; AccountCreatePopup.prototype.onSaveClick = function () { if (!this.loading()) { if (this.isFirstStep()) { this.onFirstSaveClick(); } else { this.onSecondSaveClick(); } } }; AccountCreatePopup.prototype.onCancelClick = function () { this.closeCommand(); this.init(); }; /** * @param {Object} oResponse * @param {Object} oRequest */ AccountCreatePopup.prototype.onEmailDomainDataResponse = function (oResponse, oRequest) { this.incomingMailLogin(this.email()); if (oResponse.Result) { this.incomingMailPort(oResponse.Result.IncomingMailPort); this.incomingMailServer(oResponse.Result.IncomingMailServer); this.outgoingMailPort(oResponse.Result.OutgoingMailPort); this.outgoingMailServer(oResponse.Result.OutgoingMailServer); this.onSecondSaveClick(); } else { this.loading(false); this.isFirstStep(false); this.incomingLoginFocused(true); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ AccountCreatePopup.prototype.onAccountCreateResponse = function (oResponse, oRequest) { this.loading(false); if (!oResponse.Result) { App.Api.showErrorByCode(oResponse, Utils.i18n('WARNING/CREATING_ACCOUNT_ERROR')); } else { var oAccount = new CAccountModel(), iAccountId = parseInt(oResponse.Result.IdAccount, 10) ; oAccount.init(iAccountId, oRequest.Email, oRequest.FriendlyName); oAccount.updateExtended(oRequest); oAccount.setExtensions(oResponse.Result.Extensions); AppData.Accounts.addAccount(oAccount); // AppData.Accounts.changeEditedAccount(iAccountId); // TODO this.closeCommand(); } }; AccountCreatePopup.prototype.isEmptyFirstFields = function () { switch ('') { case this.email(): this.emailFocus(true); return true; case this.incomingMailPassword(): this.incomingMailFocus(true); return true; default: return false; } }; AccountCreatePopup.prototype.isEmptySecondFields = function () { switch ('') { case this.email(): this.emailFocus(true); return true; case this.incomingMailLogin(): this.incomingLoginFocused(true); return true; case this.incomingMailServer(): this.incomingServerFocused(true); return true; case this.outgoingMailServer(): this.outServerFocused(true); return true; default: return false; } }; /** * @constructor */ function CreateIdentityPopup() { this.oIdentityPropertiesViewModel = new CIdentityPropertiesViewModel(this, true); } /** * @return {string} */ CreateIdentityPopup.prototype.popupTemplate = function () { return 'Popups_AccountCreateIdentityPopupViewModel'; }; /** * @param {number} iAccountId */ CreateIdentityPopup.prototype.onShow = function (iAccountId) { var oAccount = AppData.Accounts.getAccount(iAccountId), oIdentity = new CIdentityModel() ; oIdentity.accountId(iAccountId); oIdentity.email(oAccount.email()); this.oIdentityPropertiesViewModel.populate(oIdentity); this.oIdentityPropertiesViewModel.friendlyNameHasFocus(true); }; CreateIdentityPopup.prototype.cancel = function () { this.closeCommand(); }; /** * @constructor */ function FetcherAddPopup() { this.defaultAccountId = AppData.Accounts.defaultId; this.loading = ko.observable(false); this.newFolderCreating = ko.observable(false); this.incomingMailServer = ko.observable(''); this.incomingMailPort = ko.observable(110); this.incomingMailLogin = ko.observable(''); this.incomingMailPassword = ko.observable(''); this.folderList = App.MailCache.folderList; this.folder = ko.observable(''); this.options = ko.observable(this.folderList().getOptions('', true, false, false)); this.folderList.subscribe(function() { this.options(this.folderList().getOptions('', true, false, false)); }, this); this.addNewFolderCommand = Utils.createCommand(this, this.onAddNewFolderClick); this.outgoingMailServer = ko.observable(''); this.outgoingMailPort = ko.observable(25); this.leaveMessagesOnServer = ko.observable(false); this.useSmtpAuthentication = ko.observable(false); this.serverIsSelected = ko.observable(false); this.loginIsSelected = ko.observable(false); this.passwordIsSelected = ko.observable(false); this.defaultOptionsAfterRender = Utils.defaultOptionsAfterRender; } /** * @return {string} */ FetcherAddPopup.prototype.popupTemplate = function () { return 'Popups_FetcherAddPopupViewModel'; }; FetcherAddPopup.prototype.onShow = function () { this.incomingMailServer(''); this.incomingMailPort(110); this.incomingMailLogin(''); this.incomingMailPassword(''); this.folder(''); this.outgoingMailServer(''); this.outgoingMailPort(25); this.leaveMessagesOnServer(true); }; FetcherAddPopup.prototype.onSaveClick = function () { if (this.isEmptyRequiredFields()) { App.Api.showError(Utils.i18n('WARNING/FETCHER_CREATE_ERROR')); } else { var oParameters = { 'Action': 'FetcherCreate', 'AccountID': this.defaultAccountId(), 'Folder': this.folder(), 'IncomingMailServer': this.incomingMailServer(), 'IncomingMailPort': parseInt(this.incomingMailPort(), 10), 'IncomingMailLogin': this.incomingMailLogin(), 'IncomingMailPassword': (this.incomingMailPassword() === '') ? '******' : this.incomingMailPassword(), 'LeaveMessagesOnServer': this.leaveMessagesOnServer() ? 1 : 0 }; this.loading(true); App.Ajax.send(oParameters, this.onAddFetcherResponse, this); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ FetcherAddPopup.prototype.onAddFetcherResponse = function (oResponse, oRequest) { this.loading(false); if (!oResponse.Result) { // App.Api.showErrorByCode(oResponse, Utils.i18n('WARNING/FETCHER_ADDING_ERROR')); App.Api.showErrorByCode(oResponse); } else { AppData.Accounts.populateFetchers(); this.closeCommand(); } }; FetcherAddPopup.prototype.onCancelClick = function () { if (!this.newFolderCreating()) { this.closeCommand(); } }; FetcherAddPopup.prototype.onEscHandler = function () { this.onCancelClick(); }; FetcherAddPopup.prototype.isEmptyRequiredFields = function () { switch ('') { case this.incomingMailServer(): this.serverIsSelected(true); return true; case this.incomingMailLogin(): this.loginIsSelected(true); return true; case this.incomingMailPassword(): this.passwordIsSelected(true); return true; default: return false; } }; FetcherAddPopup.prototype.onAddNewFolderClick = function () { this.newFolderCreating(true); App.Screens.showPopup(FolderCreatePopup, [_.bind(this.chooseFolderInList, this)]); }; /** * @param {string} sFolderName * @param {string} sParentFullName */ FetcherAddPopup.prototype.chooseFolderInList = function (sFolderName, sParentFullName) { var sDelimiter = this.folderList().delimiter(), aFolder = [] ; if (sFolderName !== '' && sParentFullName !== '') { _.each(this.options(), _.bind(function (oOption) { if (sFolderName === oOption.name) { aFolder = oOption.fullName.split(sDelimiter); aFolder.pop(); if (sParentFullName === aFolder.join(sDelimiter)) { this.folder(oOption.fullName); } } }, this)); } this.newFolderCreating(false); }; /** * @constructor */ function SystemFoldersPopup() { this.folders = App.MailCache.editedFolderList; this.sentFolderFullName = ko.observable(this.folders().sentFolderFullName()); this.draftsFolderFullName = ko.observable(this.folders().draftsFolderFullName()); this.spamFolderFullName = ko.observable(this.folders().spamFolderFullName()); this.trashFolderFullName = ko.observable(this.folders().trashFolderFullName()); this.options = ko.observableArray(this.folders().getOptions(Utils.i18n('SETTINGS/ACCOUNT_FOLDERS_NO_USAGE_ASSIGNED'), false, false, false)); this.defaultOptionsAfterRender = Utils.defaultOptionsAfterRender; this.allowSpamFolderEditing = ko.computed(function () { var oAccount = AppData.Accounts.getEdited(), bAllowSpamFolderExtension = oAccount.extensionExists('AllowSpamFolderExtension') ; return bAllowSpamFolderExtension && !AppData.IsMailsuite; }, this); } SystemFoldersPopup.prototype.onShow = function () { var oFolders = App.MailCache.editedFolderList(); this.sentFolderFullName(oFolders.sentFolderFullName()); this.draftsFolderFullName(oFolders.draftsFolderFullName()); if (this.allowSpamFolderEditing()) { this.spamFolderFullName(oFolders.spamFolderFullName()); } this.trashFolderFullName(oFolders.trashFolderFullName()); this.options(this.folders().getOptions(Utils.i18n('SETTINGS/ACCOUNT_FOLDERS_NO_USAGE_ASSIGNED'), false, false, false)); }; /** * @return {string} */ SystemFoldersPopup.prototype.popupTemplate = function () { return 'Popups_FolderSystemPopupViewModel'; }; /** * @param {Object} oResponse * @param {Object} oRequest */ SystemFoldersPopup.prototype.onResponseSetupSystemFolders = function (oResponse, oRequest) { if (oResponse.Result === false) { App.Api.showErrorByCode(oResponse, Utils.i18n('ACCOUNT_FOLDERS_ERROR_SETUP_SPECIAL_FOLDERS')); App.MailCache.getFolderList(AppData.Accounts.editedId()); } }; SystemFoldersPopup.prototype.onOKClick = function () { var oFolders = this.folders(), bHasChanges = false, oParameters = null ; if (this.sentFolderFullName() !== oFolders.sentFolderFullName()) { oFolders.sentFolderFullName(this.sentFolderFullName()); bHasChanges = true; } if (this.draftsFolderFullName() !== oFolders.draftsFolderFullName()) { oFolders.draftsFolderFullName(this.draftsFolderFullName()); bHasChanges = true; } if (this.allowSpamFolderEditing() && this.spamFolderFullName() !== oFolders.spamFolderFullName()) { oFolders.spamFolderFullName(this.spamFolderFullName()); bHasChanges = true; } if (this.trashFolderFullName() !== oFolders.trashFolderFullName()) { oFolders.trashFolderFullName(this.trashFolderFullName()); bHasChanges = true; } if (bHasChanges) { oParameters = { 'Action': 'SetupSystemFolders', 'AccountID': AppData.Accounts.editedId(), 'Sent': oFolders.sentFolderFullName(), 'Drafts': oFolders.draftsFolderFullName(), 'Trash': oFolders.trashFolderFullName(), 'Spam': oFolders.spamFolderFullName() }; App.Ajax.send(oParameters, this.onResponseSetupSystemFolders, this); } this.closeCommand(); }; SystemFoldersPopup.prototype.onCancelClick = function () { this.closeCommand(); }; SystemFoldersPopup.prototype.onEscHandler = function () { this.onCancelClick(); }; /** * @constructor */ function FolderCreatePopup() { this.folders = App.MailCache.editedFolderList; this.loading = ko.observable(false); App.MailCache.folderListLoading.subscribe(function () { if (!App.MailCache.folderListLoading() && this.loading()) { if (this.fCallback) { this.fCallback(this.folderName(), this.parentFolder()); } this.loading(false); this.closeCommand(); } }, this); this.options = ko.computed(function(){ return this.folders().getOptions(Utils.i18n('SETTINGS/ACCOUNT_FOLDERS_NO_PARENT'), true, false, true); }, this); this.namespace = ko.computed(function(){ return this.folders().sNamespaceFolder; }, this); this.parentFolder = ko.observable(''); this.folderName = ko.observable(''); this.folderNameFocus = ko.observable(false); this.fCallback = null; this.defaultOptionsAfterRender = Utils.defaultOptionsAfterRender; } /** * @return {string} */ FolderCreatePopup.prototype.popupTemplate = function () { return 'Popups_FolderCreatePopupViewModel'; }; /** * @param {Function} fCallback */ FolderCreatePopup.prototype.onShow = function (fCallback) { this.fCallback = fCallback; this.folderName(''); this.parentFolder(''); this.folderNameFocus(true); }; /** * @param {Object} oResponse * @param {Object} oRequest */ FolderCreatePopup.prototype.onResponseFolderCreate = function (oResponse, oRequest) { if (!oResponse.Result) { this.loading(false); App.Api.showErrorByCode(oResponse, Utils.i18n('SETTINGS/ACCOUNT_FOLDERS_CANT_CREATE_FOLDER')); } else { App.MailCache.getFolderList(AppData.Accounts.editedId()); } }; FolderCreatePopup.prototype.onOKClick = function () { var parentFolder = (this.parentFolder() === '' ? this.namespace() : this.parentFolder()), oParameters = { 'Action': 'FolderCreate', 'AccountID': AppData.Accounts.editedId(), 'FolderNameInUtf8': this.folderName(), 'FolderParentFullNameRaw': parentFolder, 'Delimiter': this.folders().delimiter() } ; this.loading(true); App.Ajax.send(oParameters, this.onResponseFolderCreate, this); }; FolderCreatePopup.prototype.onCancelClick = function () { if (!this.loading()) { if (this.fCallback) { this.fCallback('', ''); } this.closeCommand(); } }; FolderCreatePopup.prototype.onEscHandler = function () { this.onCancelClick(); }; /** * @constructor */ function ChangePasswordPopup() { this.currentPassword = ko.observable(''); this.newPassword = ko.observable(''); this.confirmPassword = ko.observable(''); this.isHelpdesk = ko.observable(false); } /** * @param {boolean} bHelpdesk */ ChangePasswordPopup.prototype.onShow = function (bHelpdesk) { this.isHelpdesk(bHelpdesk); this.init(); }; /** * @return {string} */ ChangePasswordPopup.prototype.popupTemplate = function () { return 'Popups_ChangePasswordPopupViewModel'; }; ChangePasswordPopup.prototype.init = function () { this.currentPassword(''); this.newPassword(''); this.confirmPassword(''); }; /** * @param {Object} oResponse * @param {Object} oRequest */ ChangePasswordPopup.prototype.onResponse = function (oResponse, oRequest) { if (oResponse.Result === false) { App.Api.showErrorByCode(oResponse, Utils.i18n('SETTINGS/ACCOUNT_PROPERTIES_NEW_PASSWORD_UPDATE_ERROR')); } else { App.Api.showReport(Utils.i18n('SETTINGS/ACCOUNT_PROPERTIES_CHANGE_PASSWORD_SUCCESS')); this.closeCommand(); this.init(); } }; ChangePasswordPopup.prototype.onOKClick = function () { var oParameters = null ; if (this.confirmPassword() !== this.newPassword()) { App.Api.showError(Utils.i18n('WARNING/PASSWORDS_DO_NOT_MATCH')); } else { if (this.newPassword().length < AppData.App.PasswordMinLength) { App.Api.showError(Utils.i18n('WARNING/PASSWORDS_MIN_LENGTH_ERROR')); } else if (AppData.App.PasswordMustBeComplex && (!this.newPassword().match(/([0-9])/) || !this.newPassword().match(/([!,%,&,@,#,$,^,*,?,_,~])/))) { App.Api.showError(Utils.i18n('WARNING/PASSWORD_MUST_BE_COMPLEX')); } else { if (this.isHelpdesk()) { oParameters = { 'Action': 'HelpdeskUpdateUserPassword', 'CurrentPassword': this.currentPassword(), 'NewPassword': this.newPassword() }; App.Ajax.sendExt(oParameters, this.onResponse, this); } else { oParameters = { 'Action': 'UpdateAccountPassword', 'AccountID': AppData.Accounts.editedId(), 'CurrentIncomingMailPassword': this.currentPassword(), 'NewIncomingMailPassword': this.newPassword() }; App.Ajax.send(oParameters, this.onResponse, this); } } } }; ChangePasswordPopup.prototype.onCancelClick = function () { this.closeCommand(); }; /** * @constructor */ function FileStorageFolderCreatePopup() { this.fCallback = null; this.folderName = ko.observable(''); this.folderName.focus = ko.observable(false); this.folderName.error = ko.observable(''); this.folderName.subscribe(function () { this.folderName.error(''); }, this); } /** * @param {Function} fCallback */ FileStorageFolderCreatePopup.prototype.onShow = function (fCallback) { this.folderName(''); this.folderName.focus(true); this.folderName.error(''); if (Utils.isFunc(fCallback)) { this.fCallback = fCallback; } }; /** * @return {string} */ FileStorageFolderCreatePopup.prototype.popupTemplate = function () { return 'Popups_FileStorage_FolderCreatePopupViewModel'; }; FileStorageFolderCreatePopup.prototype.onOKClick = function () { this.folderName.error(''); if (this.fCallback) { var sError = this.fCallback(this.folderName()); if (sError) { this.folderName.error('' + sError); } else { this.closeCommand(); } } else { this.closeCommand(); } }; FileStorageFolderCreatePopup.prototype.onCancelClick = function () { this.closeCommand(); }; /** * @constructor */ function FileStorageLinkCreatePopup() { this.fCallback = null; this.link = ko.observable(''); this.linkPrev = ko.observable(''); this.linkFocus = ko.observable(false); this.checkTimeout = null; this.urlChecked = ko.observable(false); this.saveCommand = Utils.createCommand(this, this.executeSave, function () { return (this.urlChecked()); }); this.fileItem = ko.observable(new CCommonFileModel()); } /** * @param {Function} fCallback */ FileStorageLinkCreatePopup.prototype.onShow = function (fCallback) { this.link(''); this.linkFocus(true); if (Utils.isFunc(fCallback)) { this.fCallback = fCallback; } this.checkTimer = setTimeout(_.bind(this.checkUrl, this), 2000); }; /** * @return {string} */ FileStorageLinkCreatePopup.prototype.popupTemplate = function () { return 'Popups_FileStorage_LinkCreatePopupViewModel'; }; FileStorageLinkCreatePopup.prototype.checkUrl = function () { clearTimeout(this.checkTimer); if (this.link() !== this.linkPrev()) { this.linkPrev(this.link()); App.Ajax.send({ 'Action': 'CheckUrl', 'Url': this.link() }, this.onCheckUrlResponse, this ); } this.checkTimer = setTimeout(_.bind(this.checkUrl, this), 1000); }; FileStorageLinkCreatePopup.prototype.onCheckUrlResponse = function (oData) { var fileItem = new CCommonFileModel(); if (oData.Result) { fileItem.isPopupItem(true); fileItem.linkUrl(this.link()); fileItem.fileName(oData.Result.Name); fileItem.size(oData.Result.Size); fileItem.allowDownload(false); if (oData.Result.Thumb) { fileItem.thumb(true); fileItem.thumbnailSrc(oData.Result.Thumb); } this.fileItem(fileItem); this.urlChecked(true); } else { this.urlChecked(false); } }; FileStorageLinkCreatePopup.prototype.executeSave = function () { if (this.fCallback) { this.fCallback(this.fileItem()); this.link(''); this.linkPrev(''); this.urlChecked(false); } clearTimeout(this.checkTimer); this.closeCommand(); }; FileStorageLinkCreatePopup.prototype.onCancelClick = function () { this.link(''); this.linkPrev(''); this.urlChecked(false); clearTimeout(this.checkTimer); this.closeCommand(); }; FileStorageLinkCreatePopup.prototype.onEscHandler = function () { this.onCancelClick(); }; /** * @constructor */ function FileStorageRenamePopup() { this.fCallback = null; this.item = null; this.name = ko.observable(''); this.name.focus = ko.observable(false); this.name.error = ko.observable(''); this.name.subscribe(function () { this.name.error(''); }, this); } /** * @param {Object} oItem * @param {Function} fCallback */ FileStorageRenamePopup.prototype.onShow = function (oItem, fCallback) { this.item = oItem; this.item.nameForEdit(this.item.fileName()); this.name(this.item.nameForEdit()); this.name.focus(true); this.name.error(''); if (Utils.isFunc(fCallback)) { this.fCallback = fCallback; } }; /** * @return {string} */ FileStorageRenamePopup.prototype.popupTemplate = function () { return 'Popups_FileStorage_RenamePopupViewModel'; }; FileStorageRenamePopup.prototype.onOKClick = function () { this.name.error(''); if (this.fCallback) { this.item.nameForEdit(this.name()); var sError = this.fCallback(this.item); if (sError) { this.name.error('' + sError); } else { this.closeCommand(); } } else { this.closeCommand(); } }; /** * */ FileStorageRenamePopup.prototype.onCancelClick = function () { this.closeCommand(); }; /** * @constructor */ function FileStorageSharePopup() { this.item = null; this.pub = ko.observable(''); this.pubFocus = ko.observable(false); } /** * @param {Object} oItem */ FileStorageSharePopup.prototype.onShow = function (oItem) { this.item = oItem; this.pub(''); App.Ajax.send({ 'Action': 'FilesCreatePublicLink', 'Account': AppData.Accounts.defaultId(), 'Type': oItem.storageType(), 'Path': oItem.path(), 'Name': oItem.fileName(), 'Size': oItem.size(), 'IsFolder': oItem.isFolder() ? '1' : '0' }, this.onFilesCreatePublicLinkResponse, this ); }; /** * @param {Object} oData * @param {Object} oParameters */ FileStorageSharePopup.prototype.onFilesCreatePublicLinkResponse = function (oData, oParameters) { if (oData.Result) { this.pub(oData.Result); this.pubFocus(true); this.item.shared(true); } }; /** * @return {string} */ FileStorageSharePopup.prototype.popupTemplate = function () { return 'Popups_FileStorage_SharePopupViewModel'; }; FileStorageSharePopup.prototype.onOKClick = function () { this.closeCommand(); }; /** * @param {Object} oData * @param {Object} oParameters */ FileStorageSharePopup.prototype.onFilesDeletePublicLinkResponse = function (oData, oParameters) { this.closeCommand(); }; FileStorageSharePopup.prototype.onCancelSharingClick = function () { if (this.item) { App.Ajax.send({ 'Action': 'FilesDeletePublicLink', 'Account': AppData.Accounts.defaultId(), 'Type': this.item.storageType(), 'Path': this.item.path(), 'Name': this.item.fileName() }, this.onFilesDeletePublicLinkResponse, this); this.item.shared(false); } }; /** * @constructor */ function FileStoragePopup() { this.fileStorageViewModel = new CFileStorageViewModel(); this.fileStorageViewModel.isPopup = true; this.fCallback = null; } /** * @param {Object} oItem */ FileStoragePopup.prototype.onShow = function (fCallback) { if (Utils.isFunc(fCallback)) { this.fCallback = fCallback; } this.fileStorageViewModel.onShow(); }; /** * @param {Object} $viewModel */ FileStoragePopup.prototype.onApplyBindings = function ($viewModel) { this.fileStorageViewModel.onApplyBindings($viewModel); }; /** * @return {string} */ FileStoragePopup.prototype.popupTemplate = function () { return 'Popups_FileStorage_FileStoragePopupViewModel'; }; FileStoragePopup.prototype.onSelectClick = function () { var aItems = this.fileStorageViewModel.selector.listCheckedAndSelected(), aFileItems = _.filter(aItems, function (oItem) { return !oItem.isFolder(); }, this) ; if (this.fCallback) { this.fCallback(aFileItems); } this.closeCommand(); }; FileStoragePopup.prototype.onCancelClick = function () { this.closeCommand(); }; /** * @constructor */ function CalendarPopup() { this.fCallback = null; this.calendarId = ko.observable(null); this.calendarName = ko.observable(''); this.calendarDescription = ko.observable(''); this.calendarNameFocus = ko.observable(false); this.calendarDescriptionFocus = ko.observable(false); this.colors = ko.observableArray([]); this.selectedColor = ko.observable(this.colors()[0]); this.popupTitle = ko.observable(''); } CalendarPopup.prototype.clearFields = function () { this.calendarName(''); this.calendarDescription(''); this.selectedColor(this.colors[0]); this.calendarId(null); }; /** * @param {Function} fCallback * @param {Array} aColors * @param {Object} oCalendar */ CalendarPopup.prototype.onShow = function (fCallback, aColors, oCalendar) { this.clearFields(); if (Utils.isFunc(fCallback)) { this.fCallback = fCallback; } if (!Utils.isUnd(aColors)) { this.colors(aColors); this.selectedColor(aColors[0]); } if (!Utils.isUnd(oCalendar)) { this.popupTitle(oCalendar.name() ? Utils.i18n("CALENDAR/TITLE_EDIT_CALENDAR") : Utils.i18n("CALENDAR/TITLE_CREATE_CALENDAR")); this.calendarName(oCalendar.name ? oCalendar.name() : ''); this.calendarDescription(oCalendar.description ? oCalendar.description() : ''); this.selectedColor(oCalendar.color ? oCalendar.color() : ''); this.calendarId(oCalendar.id ? oCalendar.id : null); } else { this.popupTitle(Utils.i18n("CALENDAR/TITLE_CREATE_CALENDAR")); } }; /** * @return {string} */ CalendarPopup.prototype.popupTemplate = function () { return 'Popups_Calendar_CalendarPopupViewModel'; }; CalendarPopup.prototype.onSaveClick = function () { if (this.calendarName() === '') { App.Screens.showPopup(AlertPopup, [Utils.i18n('CALENDAR/WARNING_BLANK_CALENDAR_NAME')]); } else { if (this.fCallback) { this.fCallback(this.calendarName(), this.calendarDescription(), this.selectedColor(), this.calendarId()); this.clearFields(); } this.closeCommand(); } }; CalendarPopup.prototype.onCancelClick = function () { this.closeCommand(); }; /** * @constructor */ function CalendarImportPopup() { this.fCallback = null; this.oJua = null; this.allowDragNDrop = ko.observable(false); this.visibility = ko.observable(false); this.importing = ko.observable(false); this.color = ko.observable(''); this.calendarId = ko.observable(''); } /** * @param {Function} fCallback * @param {Object} oCalendar */ CalendarImportPopup.prototype.onShow = function (fCallback, oCalendar) { if (Utils.isFunc(fCallback)) { this.fCallback = fCallback; } if (!Utils.isUnd(oCalendar)) { this.color(oCalendar.color ? oCalendar.color() : ''); this.calendarId(oCalendar.id ? oCalendar.id : ''); } }; /** * @return {string} */ CalendarImportPopup.prototype.popupTemplate = function () { return 'Popups_Calendar_ImportPopupViewModel'; }; CalendarImportPopup.prototype.onFileImportStart = function () { this.importing(true); }; /** * @param {string} sUid * @param {boolean} bResult * @param {Object} oData */ CalendarImportPopup.prototype.onFileImportComplete = function (sUid, bResult, oData) { this.importing(false); this.fCallback(); this.closeCommand(); }; /** * @param {Object} $oViewModel */ CalendarImportPopup.prototype.onApplyBindings = function ($oViewModel) { var self = this; this.oJua = new Jua({ 'action': '?/Upload/Calendars/', 'name': 'jua-uploader', 'queueSize': 1, 'clickElement': $('#jue_import_button', $oViewModel), 'disableAjaxUpload': false, 'disableDragAndDrop': true, 'disableMultiple': true, 'hidden': { 'Token': function () { return AppData.Token; }, 'AccountID': function () { return AppData.Accounts.currentId(); }, 'AdditionalData': function () { return JSON.stringify({ 'CalendarID': self.calendarId() }); } } }); this.oJua .on('onStart', _.bind(this.onFileImportStart, this)) .on('onComplete', _.bind(this.onFileImportComplete, this)) ; this.allowDragNDrop(this.oJua.isDragAndDropSupported()); }; CalendarImportPopup.prototype.onCancelClick = function () { this.closeCommand(); }; /** * @constructor */ function CalendarSharePopup() { this.defaultAccount = AppData.Accounts.getDefault(); this.fCallback = null; this.calendarId = ko.observable(null); this.selectedColor = ko.observable(''); this.calendarUrl = ko.observable(''); this.exportUrl = ko.observable(''); this.icsLink = ko.observable(''); this.isPublic = ko.observable(false); this.shares = ko.observableArray([]); this.oldShares = ko.observableArray([]); this.owner = ko.observable(''); this.recivedAnim = ko.observable(false).extend({'autoResetToFalse': 500}); this.whomAnimate = ko.observable(''); this.shareAutocompleteItem = ko.observable(null); this.shareAutocompleteItem.subscribe(function (oItem) { if (oItem) { this.setGlobal(oItem.email, this.newShareList()); } }, this); this.newShareList = ko.observableArray([]); this.newShare = ko.observable(''); this.newShareFocus = ko.observable(false); this.newShareAccess = ko.observable(Enums.CalendarAccess.Read); this.sharedToAll = ko.observable(false); this.sharedToAllAccess = ko.observable(Enums.CalendarAccess.Read); this.canAdd = ko.observable(false); this.aAccess = [ {'value': Enums.CalendarAccess.Read, 'display': Utils.i18n('CALENDAR/CALENDAR_ACCESS_READ')}, {'value': Enums.CalendarAccess.Write, 'display': Utils.i18n('CALENDAR/CALENDAR_ACCESS_WRITE')} ]; this.autocompleteCallbackBinded = _.bind(this.autocompleteCallback, this); this.showGlobalContacts = !!AppData.User.ShowGlobalContacts; } /** * @param {Function} fCallback * @param {Object} oCalendar */ CalendarSharePopup.prototype.onShow = function (fCallback, oCalendar) { if (Utils.isFunc(fCallback)) { this.fCallback = fCallback; } if (!Utils.isUnd(oCalendar)) { this.selectedColor(oCalendar.color()); this.calendarId(oCalendar.id); this.calendarUrl(oCalendar.davUrl() + oCalendar.url()); this.exportUrl(oCalendar.exportUrl()); this.icsLink(oCalendar.davUrl() + oCalendar.url() + '?export'); this.isPublic(oCalendar.isPublic()); this.shares(oCalendar.shares().slice(0)); this.oldShares(oCalendar.shares().slice(0)); this.owner(oCalendar.owner()); this.sharedToAll(oCalendar.isSharedToAll()); this.sharedToAllAccess(oCalendar.sharedToAllAccess); } }; /** * @return {string} */ CalendarSharePopup.prototype.popupTemplate = function () { return 'Popups_Calendar_SharePopupViewModel'; }; CalendarSharePopup.prototype.onSaveClick = function () { if (this.fCallback) { //this.addShare(); this.fCallback(this.calendarId(), this.isPublic(), this.shares(), this.sharedToAll(), this.sharedToAllAccess()); } this.closePopup(); }; CalendarSharePopup.prototype.onCancelClick = function () { this.shares(this.oldShares()); this.closePopup(); }; CalendarSharePopup.prototype.onEscHandler = function () { this.onCancelClick(); }; CalendarSharePopup.prototype.closePopup = function () { this.cleanAll(); this.closeCommand(); }; CalendarSharePopup.prototype.cleanAll = function () { this.newShare(''); this.newShareAccess(Enums.CalendarAccess.Read); this.shareToAllAccess = ko.observable(Enums.CalendarAccess.Read); this.shareAutocompleteItem(null); this.canAdd(false); }; CalendarSharePopup.prototype.addShare = function () { var sEmail = this.shareAutocompleteItem() ? this.shareAutocompleteItem().email : this.newShare(); if (this.canAdd()) { this.shares.push( { name: this.shareAutocompleteItem() ? this.shareAutocompleteItem().name : '', email: sEmail, access: this.newShareAccess() }); this.cleanAll(); } else { this.whomAnimate(sEmail); this.recivedAnim(true); } }; /** * @param {Object} oItem */ CalendarSharePopup.prototype.removeShare = function (oItem) { this.shares.remove(oItem); }; /** * @param {string} sTerm * @param {Function} fResponse */ CalendarSharePopup.prototype.autocompleteCallback = function (sTerm, fResponse) { var oParameters = { 'Action': 'ContactSuggestions', 'Search': sTerm, 'GlobalOnly': '1' } ; this.shareAutocompleteItem(null); sTerm = Utils.trim(sTerm); if ('' !== sTerm) { App.Ajax.send(oParameters, function (oData) { var aList = []; if (oData && oData.Result && oData.Result && oData.Result.List) { aList = _.map(oData.Result.List, function (oItem) { return oItem && oItem.Email && oItem.Email !== this.owner() ? (oItem.Name && 0 < Utils.trim(oItem.Name).length ? oItem.ForSharedToAll ? {value: oItem.Name, name: oItem.Name, email: oItem.Email, frequency: oItem.Frequency} : {value:'"' + oItem.Name + '" <' + oItem.Email + '>', name: oItem.Name, email: oItem.Email, frequency: oItem.Frequency} : {value: oItem.Email, name: '', email: oItem.Email, frequency: oItem.Frequency}) : null; }, this); aList = _.sortBy(_.compact(aList), function(num){ return num.frequency; }).reverse(); this.newShareList(aList); this.setGlobal(this.newShare(), aList); } fResponse(aList); }, this); } else { fResponse([]); } }; /** * @param {string} sText * @param {Array} aList */ CalendarSharePopup.prototype.setGlobal = function (sText, aList) { var isInGlobal = _.any(aList, function (sItem) { return sItem.email === sText; }, this), isAlreadyAdded = _.any(this.shares(), function (sItem) { return sItem.email === sText; }, this) ; this.canAdd(isInGlobal && !isAlreadyAdded); }; /** * @param {string} sEmail */ CalendarSharePopup.prototype.itsMe = function (sEmail) { return (sEmail === this.defaultAccount.email()); }; /** * @constructor */ function CalendarGetLinkPopup() { this.fCallback = null; this.calendarId = ko.observable(null); this.selectedColor = ko.observable(''); this.calendarUrl = ko.observable(''); this.exportUrl = ko.observable(''); this.icsLink = ko.observable(''); this.isPublic = ko.observable(false); this.pubUrl = ko.observable(''); } /** * @param {Function} fCallback * @param {Object} oCalendar */ CalendarGetLinkPopup.prototype.onShow = function (fCallback, oCalendar) { if (Utils.isFunc(fCallback)) { this.fCallback = fCallback; } if (!Utils.isUnd(oCalendar)) { this.selectedColor(oCalendar.color()); this.calendarId(oCalendar.id); this.calendarUrl(oCalendar.davUrl() + oCalendar.url()); this.exportUrl(oCalendar.exportUrl()); this.icsLink(oCalendar.davUrl() + oCalendar.url() + '?export'); this.isPublic(oCalendar.isPublic()); this.pubUrl(oCalendar.pubUrl()); this.exportUrl(oCalendar.exportUrl()); } }; /** * @return {string} */ CalendarGetLinkPopup.prototype.popupTemplate = function () { return 'Popups_Calendar_GetLinkPopupViewModel'; }; CalendarGetLinkPopup.prototype.onCancelClick = function () { if (this.fCallback) { this.fCallback(this.calendarId(), this.isPublic()); } this.closeCommand(); }; CalendarGetLinkPopup.prototype.onEscHandler = function () { this.onCancelClick(); }; /** * @constructor */ function CalendarEventPopup() { this.defaultAccount = (AppData.Accounts) ? AppData.Accounts.getDefault() : null; this.modified = false; this.isPublic = bExtApp; this.isEditable = ko.observable(false); this.isEditableReminders = ko.observable(false); this.selectedCalendarIsShared = ko.observable(false); this.selectedCalendarIsEditable = ko.observable(false); this.callbackSave = null; this.callbackDelete = null; this.timeFormatMoment = 'HH:mm'; this.dateFormatMoment = 'MM/DD/YYYY'; this.dateFormatDatePicker = 'mm/dd/yy'; this.ampmTimeFormat = ko.observable(false); this.calendarId = ko.observable(null); this.id = ko.observable(null); this.uid = ko.observable(null); this.recurrenceId = ko.observable(null); this.allEvents = ko.observable(Enums.CalendarEditRecurrenceEvent.AllEvents); this.FCMoment = null; this.isMyEvent = ko.observable(false); this.startDom = ko.observable(null); this.endDom = ko.observable(null); this.repeatEndDom = ko.observable(null); this.yearlyDate = ko.observable(''); this.monthlyDate = ko.observable(''); this.subject = ko.observable(''); this.description = ko.observable(''); this.startDate = ko.observable(''); this.startTime = ko.observable(''); this.startTime.subscribe(function () { this.selectStartDate(); }, this); this.allDay = ko.observable(false); this.allDay.subscribe(function (arg) { if(!arg) { this.setActualTime(); } }, this); this.endDate = ko.observable(''); this.endTime = ko.observable(''); this.endTime.subscribe(function () { this.selectEndDate(); }, this); this.repeatEndDate = ko.observable(''); this.isEvOneDay = ko.observable(true); this.isEvOneTime = ko.observable(true); this.isRepeat = ko.observable(false); this.location = ko.observable(''); this.repeatPeriodOptions = ko.observableArray(this.getDisplayedPeriods()); this.repeatWeekIntervalOptions = ko.observableArray([1, 2, 3, 4]); this.repeatMonthIntervalOptions = ko.observableArray(this.getDisplayedIntervals()); this.defaultAlarms = ko.observableArray([5, 10, 15, 30, 60, 120, 180, 240, 300, 360, 420, 480, 540, 600, 660, 720, 1080, 1440, 2880, 4320, 5760, 10080, 20160]); this.alarmOptions = ko.observableArray([]); this.timeOptions = ko.observableArray(this.getDisplayedTimes((AppData.User.defaultTimeFormat() !== Enums.TimeFormat.F24) ? 'hh:mm A' : 'HH:mm')); AppData.User.defaultTimeFormat.subscribe(function () { this.timeOptions(this.getDisplayedTimes((AppData.User.defaultTimeFormat() !== Enums.TimeFormat.F24) ? 'hh:mm A' : 'HH:mm')); }, this); this.displayedAlarms = ko.observableArray([]); this.displayedAlarms.subscribe(function () { this.disableAlarms(); }, this); this.excluded = ko.observable(false); this.repeatPeriod = ko.observable(0); this.repeatPeriod.subscribe(function (iRepeatPeriod) { this.setDayOfWeek(); this.isRepeat(!!iRepeatPeriod); }, this); this.repeatInterval = ko.observable(1); this.repeatCount = ko.observable(null); this.repeatWeekNum = ko.observable(null); this.weekMO = ko.observable(false); this.weekTU = ko.observable(false); this.weekWE = ko.observable(false); this.weekTH = ko.observable(false); this.weekFR = ko.observable(false); this.weekSA = ko.observable(false); this.weekSU = ko.observable(false); this.appointment = ko.observable(false); this.attendees = ko.observableArray([]); this.attenderStatus = ko.observable(0); this.owner = ko.observable(''); this.ownerName = ko.observable(''); this.ownerDisplay = ko.computed(function(){ return (this.ownerName() !== '') ? this.ownerName() : this.owner(); }, this); this.recivedAnim = ko.observable(false).extend({'autoResetToFalse': 500}); this.whomAnimate = ko.observable(''); this.guestAutocompleteItem = ko.observable(null); this.guestAutocomplete = ko.observable(''); this.guestEmailFocus = ko.observable(false); this.guestAutocomplete.subscribe(function (sItem) { if (sItem === '') { this.guestAutocompleteItem(null); } }, this); this.condition = ko.observable(''); this.autosizeTrigger = ko.observable(true); this.calendars = null; this.calendarsList = ko.observableArray([]); this.calendarColor = ko.observable(''); this.selectedCalendarId = ko.observable(''); this.selectedCalendarName = ko.observable(''); this.selectedCalendarId.subscribe(function (sValue) { if (sValue) { var oCalendar = this.calendars.getCalendarById(sValue); this.selectedCalendarName(oCalendar.name()); this.selectedCalendarIsShared(oCalendar.isShared()); this.selectedCalendarIsEditable(oCalendar.isEditable()); this.changeCalendarColor(sValue); } }, this); this.subjectFocus = ko.observable(false); this.descriptionFocus = ko.observable(false); this.locationFocus = ko.observable(false); this.dateEdit = ko.observable(false); this.repeatEdit = ko.observable(false); this.guestsEdit = ko.observable(false); this.defaultOptionsAfterRender = Utils.defaultOptionsAfterRender; this.isEditForm = ko.computed(function(){ return !!this.id(); }, this); this.callbackAttendeeActionDecline = null; this.calendarAppointments = AppData.User.AllowCalendar && AppData.User.CalendarAppointments; this.allChanges = ko.computed(function() { this.subject(); this.description(); this.location(); this.isRepeat(); this.allDay(); this.repeatPeriod(); this.repeatInterval(); this.repeatCount(); this.repeatWeekNum(); this.startDate(); this.startTime(); this.endDate(); this.endTime(); this.repeatEndDate(); this.displayedAlarms(); this.weekMO(); this.weekTU(); this.weekWE(); this.weekTH(); this.weekFR(); this.weekSA(); this.weekSU(); this.attendees(); this.selectedCalendarId(); this.modified = true; }, this); this.phaseArray = ['']; _.each(Utils.i18n('CALENDAR/REMINDER_PHRASE').split(/\s/), function (sItem) { var iIndex = this.phaseArray.length - 1; if (sItem.substr(0,1) === '%' || this.phaseArray[iIndex].substr(-1,1) === '%') { this.phaseArray.push(sItem); } else { this.phaseArray[iIndex] += ' ' + sItem; } }, this); this.isAppointmentButtonsVisible = ko.observable(false); } /** * @param {Object} oElement * @param {Function} fSelect */ CalendarEventPopup.prototype.createDatePickerObject = function (oElement, fSelect) { $(oElement).datepicker({ showOtherMonths: true, selectOtherMonths: true, monthNames: Utils.getMonthNamesArray(), dayNamesMin: Utils.i18n('DATETIME/DAY_NAMES_MIN').split(' '), firstDay: AppData.User.CalendarWeekStartsOn, showOn: "both", buttonText: "", buttonImage: "skins/Default/images/calendar-icon.png", buttonImageOnly: true, dateFormat: this.dateFormatDatePicker, onSelect: fSelect }); $(oElement).mousedown(function() { $('#ui-datepicker-div').toggle(); }); }; CalendarEventPopup.prototype.initializeDatePickers = function () { this.createDatePickerObject(this.startDom(), this.selectStartDate.bind(this)); this.createDatePickerObject(this.endDom(), this.selectEndDate.bind(this)); this.createDatePickerObject(this.repeatEndDom(), Utils.emptyFunction()); this.startDom().datepicker( "option", "dateFormat", this.dateFormatDatePicker); this.endDom().datepicker( "option", "dateFormat", this.dateFormatDatePicker); this.repeatEndDom().datepicker( "option", "dateFormat", this.dateFormatDatePicker); }; /** * @param {Object} oParameters */ CalendarEventPopup.prototype.onShow = function (oParameters) { var oAccount = this.defaultAccount, owner = (oAccount) ? oAccount.email() : '', ownerName = (oAccount) ? oAccount.friendlyName() : '', oEnd = oParameters.End.clone(), sAttendee = '' ; this.FCMoment = oParameters.FCMoment; this.isMyEvent(owner === (oParameters.Owner || owner)); this.callbackSave = oParameters.CallbackSave; this.callbackDelete = oParameters.CallbackDelete; this.callbackAttendeeActionDecline = oParameters.CallbackAttendeeActionDecline; this.timeFormatMoment = oParameters.TimeFormat; this.dateFormatMoment = Utils.getDateFormatForMoment(oParameters.DateFormat); this.dateFormatDatePicker = Utils.getDateFormatForDatePicker(oParameters.DateFormat); this.ampmTimeFormat(AppData.User.defaultTimeFormat() !== Enums.TimeFormat.F24); this.initializeDatePickers(); this.allDay(oParameters.AllDay); this.startDate(oParameters.Start.format(this.dateFormatMoment)); this.startDom().datepicker("setDate", oParameters.Start.toDate()); this.startTime(oParameters.Start.format(this.timeFormatMoment)); if (oParameters.End && this.allDay()) { oEnd.subtract(1, 'days'); } this.endDate(oEnd ? oEnd.format(this.dateFormatMoment) : this.startDate()); this.endDom().datepicker("setDate", oEnd ? oEnd.toDate() : oParameters.Start.toDate()); this.endTime(oEnd ? oEnd.format(this.timeFormatMoment) : this.startTime()); this.calendars = oParameters.Calendars; if (this.calendars) { this.calendarsList( _.filter( this.calendars.collection(), function(oItem){ return oItem.isEditable(); } ) ); } this.selectedCalendarId(oParameters.SelectedCalendar); this.selectedCalendarId.valueHasMutated(); this.calendarId(oParameters.SelectedCalendar); this.editableSwitch(this.selectedCalendarIsShared(), this.selectedCalendarIsEditable(), this.isMyEvent()); this.changeCalendarColor(this.selectedCalendarId()); // parameters for event editing only (not for creating) this.id(oParameters.ID || null); this.uid(oParameters.Uid || null); this.recurrenceId(oParameters.RecurrenceId || null); this.subject(oParameters.Subject || ''); this.location(oParameters.Location || ''); this.description(oParameters.Description || ''); this.allEvents(oParameters.AllEvents || Enums.CalendarEditRecurrenceEvent.AllEvents); this.populateAlarms(oParameters.Alarms); this.appointment(oParameters.Appointment); this.attendees(oParameters.Attendees || []); if (AppData.Accounts) { sAttendee = AppData.Accounts.getAttendee( _.map(this.attendees(), function (oAttendee) { return oAttendee.email; }, this) ); } this.setCurrentAttenderStatus(sAttendee, oParameters.Attendees || []); this.owner(oParameters.Owner || owner); this.ownerName(oParameters.OwnerName || (this.isMyEvent() ? ownerName : '')); this.guestAutocomplete(''); this.excluded(oParameters.Excluded || false); this.repeatRuleParse(oParameters.RRule || null); if (this.id() === null) { this.subjectFocus(true); } this.autosizeTrigger.notifySubscribers(true); this.modified = false; this.isAppointmentButtonsVisible(this.appointment() && this.selectedCalendarIsEditable() && _.find(this.attendees(), function(oAttendee){ return oAttendee.email === owner; })); }; /** * @return {string} */ CalendarEventPopup.prototype.popupTemplate = function () { return 'Popups_Calendar_EventPopupViewModel'; }; /** * @param {string} sId */ CalendarEventPopup.prototype.changeCalendarColor = function (sId) { if (Utils.isFunc(this.calendars.getCalendarById)) { var oCalendar = this.calendars.getCalendarById(sId); if (oCalendar) { this.calendarColor(''); this.calendarColor(oCalendar.color()); } } }; CalendarEventPopup.prototype.onSaveClick = function () { if (this.subject() === '') { App.Screens.showPopup(AlertPopup, [Utils.i18n('CALENDAR/WARNING_EVENT_BLANK_SUBJECT'), _.bind(function () { this.subjectFocus(true); }, this)]); } else { if (this.callbackSave) { var iPeriod = this.repeatPeriod(), sDate = '', oDate = null, iInterval = 0, iWeekNum = 0, oStart = moment(this.getDateTime(this.startDom(), this.startTime())), oEnd = moment(this.getDateTime(this.endDom(), this.endTime())), oEventData = { calendarId: this.calendarId(), newCalendarId: this.selectedCalendarId(), id: this.id(), uid: this.uid(), recurrenceId: this.recurrenceId(), allEvents: this.allEvents(), subject: this.subject(), title: Utils.getTitleForEvent(this.subject()), start: oStart, allDay: this.allDay(), location: this.location(), description: this.description(), alarms: this.getAlarmsArray(this.displayedAlarms()), attendees: this.attendees(), owner: this.owner(), modified: this.modified } ; if (this.allDay()) { oEnd.add(1, 'days'); } oEventData.end = oEnd; if (iPeriod) { sDate = this.repeatEndDom().datepicker('getDate'); oDate = sDate ? this.getUnixTimestamp(sDate) : null; iInterval = this.repeatInterval(); iWeekNum = this.repeatWeekNum(); if (iPeriod === Enums.CalendarRepeatPeriod.Daily) { oEventData.rrule = { byDays: [], count: null, end: 2, interval: 1, period: iPeriod, until: oDate, weekNum: null }; } else if (iPeriod === Enums.CalendarRepeatPeriod.Weekly) { this.setDayOfWeek(); oEventData.rrule = { byDays: this.getDays(), count: null, end: 2, interval: iInterval, period: iPeriod, until: oDate, weekNum: null }; } else if (iPeriod === Enums.CalendarRepeatPeriod.Monthly) { oEventData.rrule = { byDays: [], count: null, end: 0, interval: 1, period: iPeriod, until: null, weekNum: null }; } else if (iPeriod === Enums.CalendarRepeatPeriod.Yearly) { oEventData.rrule = { byDays: [], count: null, end: 0, interval: 1, period: iPeriod, until: null, weekNum: null }; } } this.callbackSave(oEventData); } this.closePopup(); } }; CalendarEventPopup.prototype.onEscHandler = function () { _.delay(_.bind(this.closePopup, this), 100); }; CalendarEventPopup.prototype.closePopup = function () { this.hideAll(); this.cleanAll(); this.closeCommand(); }; CalendarEventPopup.prototype.hideAll = function () { this.dateEdit(false); this.repeatEdit(false); this.guestsEdit(false); }; CalendarEventPopup.prototype.cleanAll = function () { this.subject(''); this.description(''); this.location(''); this.isRepeat(false); this.allDay(false); this.repeatPeriod(0); this.repeatInterval(1); this.repeatCount(null); this.repeatWeekNum(null); this.startDate(''); this.startTime(''); this.endDate(''); this.endTime(''); this.repeatEndDate(''); this.displayedAlarms([]); this.weekMO(false); this.weekTU(false); this.weekWE(false); this.weekTH(false); this.weekFR(false); this.weekSA(false); this.weekSU(false); this.attendees([]); this.selectedCalendarId(''); this.attendees([]); }; CalendarEventPopup.prototype.onDeleteClick = function () { if (this.callbackDelete) { var oEventData = { calendarId: this.selectedCalendarId(), id: this.id(), uid: this.uid(), recurrenceId: this.recurrenceId(), allEvents: this.allEvents(), subject: this.subject(), title: Utils.getTitleForEvent(this.subject()), start: moment(this.getDateTime(this.startDom(), this.startTime())), end: moment(this.getDateTime(this.endDom(), this.endTime())), allDay: this.allDay(), location: this.location(), description: this.description() } ; this.callbackDelete(oEventData); } this.closePopup(); }; /** * @param {Object} oModel * @param {Object} oEv */ CalendarEventPopup.prototype.showDates = function (oModel, oEv) { oEv.stopPropagation(); this.dateEdit(!this.dateEdit()); }; CalendarEventPopup.prototype.showGuests = function () { if (this.attendees().length > 0) { var sConfirm = Utils.i18n('CALENDAR/CONFIRM_CLOSE_ATTENDEERS'), fAction = _.bind(function (bResult) { if (bResult) { this.guestsEdit(false); this.guestEmailFocus(false); this.attendees([]); } }, this) ; App.Screens.showPopup(ConfirmPopup, [sConfirm, fAction]); } else { this.guestsEdit(!this.guestsEdit()); this.guestEmailFocus(!this.guestEmailFocus()); } }; CalendarEventPopup.prototype.onAddGuestClick = function () { var oGuestAutocompleteItem = this.guestAutocompleteItem(), sGuestAutocomplete = this.guestAutocomplete(), oItem = oGuestAutocompleteItem || {name: '', email: sGuestAutocomplete}, bIsInvited = _.any(this.attendees(), function (oEl) { return oEl.email === oItem.email; }) ; if (oItem.email === '') { App.Api.showError(Utils.i18n('CALENDAR/EVENT_ERROR_ENTER_EMAIL')); } else if (oItem.email === this.owner()) { this.recivedAnim(true); } else if (bIsInvited) { this.recivedAnim(true); } // else if (!(/^([a-z0-9_\-]+\.)*[a-z0-9_\-]+@[a-z0-9_\-]+(\.[a-z0-9_\-]+)*\.[a-z]{2,6}$/).test(oItem.email)) // else if (!(/^([a-z0-9_\-]+\.)*[a-z0-9_\-]+@[a-z0-9_\-]+(\.[a-z0-9_\-]+)*/).test(oItem.email)) // { // App.Api.showError(Utils.i18n('CALENDAR/EVENT_ERROR_CORRECT_EMAIL')); // } else { this.attendees.push( { status: 0, name: oItem.name, email: oItem.email } ); } this.whomAnimate(oItem.email); this.guestAutocomplete(''); }; CalendarEventPopup.prototype.populateAlarms = function (aAlarms) { if (aAlarms) { this.alarmOptions(this.getDisplayedAlarms(_.union(this.defaultAlarms(), aAlarms))); this.displayedAlarms(this.getDisplayedAlarms(aAlarms)); } else { this.alarmOptions(this.getDisplayedAlarms(this.defaultAlarms())); } }; /** * @param {Array} aMinutes */ CalendarEventPopup.prototype.getDisplayedAlarms = function (aMinutes) { var alarm, sText, aDisplayedAlarms = [] ; if (aMinutes) { _.each(aMinutes, function (iMinutes, iIdx) { alarm = this['alarm' + iMinutes] = ko.observable(iMinutes); alarm.subscribe(function () { //alarm observable value not actual this.disableAlarms(); }, this); if (iMinutes > 0 && iMinutes < 60) { sText = (Utils.i18n('CALENDAR/ALARM_MINUTES_PLURAL', { 'COUNT': iMinutes }, null, iMinutes)); } else if (iMinutes >= 60 && iMinutes < 1440) { sText = (Utils.i18n('CALENDAR/ALARM_HOURS_PLURAL', { 'COUNT': iMinutes / 60 }, null, iMinutes / 60)); } else if (iMinutes >= 1440 && iMinutes < 10080) { sText = (Utils.i18n('CALENDAR/ALARM_DAYS_PLURAL', { 'COUNT': iMinutes / 1440 }, null, iMinutes / 1440)); } else { sText = (Utils.i18n('CALENDAR/ALARM_WEEKS_PLURAL', { 'COUNT': iMinutes / 10080 }, null, iMinutes / 10080)); } aDisplayedAlarms.push({ 'value': iMinutes, 'alarm': alarm, 'text': sText, 'isDisabled': false }); }, this); } return _.sortBy(aDisplayedAlarms, function(oAlarm){ return oAlarm.value; }); }; CalendarEventPopup.prototype.getDisplayedPeriods = function () { return [ { label: Utils.i18n('CALENDAR/EVENT_REPEAT_NEVER'), value: 0 }, { label: Utils.i18n('CALENDAR/EVENT_REPEAT_DAILY'), value: 1 }, { label: Utils.i18n('CALENDAR/EVENT_REPEAT_WEEKLY'), value: 2 }, { label: Utils.i18n('CALENDAR/EVENT_REPEAT_MONTHLY'), value: 3 }, { label: Utils.i18n('CALENDAR/EVENT_REPEAT_YEARLY'), value: 4 } ]; }; CalendarEventPopup.prototype.getDisplayedIntervals = function () { var i = 1, aDisplayedIntervals = [] ; for (; i <= 30; i++ ) { aDisplayedIntervals.push( { label: i + Utils.i18n('th'), value: i } ); } return aDisplayedIntervals; }; /** * @param {Array} aDisplayedAlarms */ CalendarEventPopup.prototype.getAlarmsArray = function (aDisplayedAlarms) { var aAlarms = []; _.each(aDisplayedAlarms, function(oAlarm, iIdx) { aAlarms.push(oAlarm.alarm()); }, this); return _.sortBy(aAlarms, function(num){return -num;}); }; CalendarEventPopup.prototype.addFirstAlarm = function () { if(!this.displayedAlarms().length) { this.displayedAlarms(this.getDisplayedAlarms([this.alarmOptions()[0].value])); } else { var sConfirm = Utils.i18n('CALENDAR/CONFIRM_CLOSE_ALARMS'), fAction = _.bind(function (bResult) { if (bResult) { this.displayedAlarms.removeAll(); } }, this) ; App.Screens.showPopup(ConfirmPopup, [sConfirm, fAction]); } }; CalendarEventPopup.prototype.addAlarm = function () { var oDisplayedAlarm, aSortedAlarms, iMinutes = 0 ; aSortedAlarms = _.sortBy(this.displayedAlarms(), function(oAlarm){return oAlarm.alarm();}); _.each(aSortedAlarms, function(oAlarm) { var nAlarmMinutes = oAlarm.alarm(); if (nAlarmMinutes !== 5 && iMinutes <= 5) { iMinutes = 5; } else if (nAlarmMinutes !== 10 && iMinutes <= 10) { iMinutes = 10; } else if (nAlarmMinutes !== 15 && iMinutes <= 15) { iMinutes = 15; } else if (nAlarmMinutes !== 30 && iMinutes <= 30) { iMinutes = 30; } else if (nAlarmMinutes !== 1440 && iMinutes <= 1440) { iMinutes = 1440; } }); oDisplayedAlarm = this.getDisplayedAlarms([iMinutes])[0]; this['alarm' + iMinutes] = ko.observable(iMinutes); this.displayedAlarms.push(oDisplayedAlarm); }; /** * @param {Object} oItem */ CalendarEventPopup.prototype.removeAlarm = function (oItem) { this.displayedAlarms.remove(oItem); }; /** * @param {Object} oItem */ CalendarEventPopup.prototype.removeGuest = function (oItem) { this.attendees.remove(oItem); }; CalendarEventPopup.prototype.disableAlarms = function () { _.each(this.alarmOptions(), function(oAlarm, iIdx) { oAlarm.isDisabled = _.any(this.displayedAlarms(), function(oItem){ return oItem.alarm() === oAlarm.value; }); }, this); this.alarmOptions.valueHasMutated(); }; /** * @param {string} sTerm * @param {Function} fResponse */ CalendarEventPopup.prototype.autocompleteCallback = function (sTerm, fResponse) { var oParameters = { 'Action': 'ContactSuggestions', 'Search': sTerm, 'GlobalOnly': '0' } ; this.guestAutocompleteItem(null); sTerm = Utils.trim(sTerm); if ('' !== sTerm) { App.Ajax.send(oParameters, function (oData) { var aList = []; if (oData && oData.Result && oData.Result && oData.Result.List) { aList = _.map(oData.Result.List, function (oItem) { /*return oItem && oItem.Email ? oItem.Email : '';*/ return oItem && oItem.Email && oItem.Email !== this.owner() ? (oItem.Name && 0 < Utils.trim(oItem.Name).length ? {value:'"' + oItem.Name + '" <' + oItem.Email + '>', name: oItem.Name, email: oItem.Email, frequency: oItem.Frequency} : {value: oItem.Email, name: '', email: oItem.Email, frequency: oItem.Frequency}) : null; }, this); aList = _.sortBy(_.compact(aList), function(num){ return num.frequency; }).reverse(); } fResponse(aList); }, this); } else { fResponse([]); } }; CalendarEventPopup.prototype.repeatRuleParse = function (oRepeatRule) { var allEvents = this.allEvents(); this.repeatEndDom().datepicker("option", "minDate", this.getDateTime(this.endDom())); if(oRepeatRule && allEvents === Enums.CalendarEditRecurrenceEvent.AllEvents) { if (oRepeatRule.until) { this.datepickerSetDate(this.repeatEndDom(), new Date(oRepeatRule.until * 1000)); } if (oRepeatRule.byDays.length) { _.each(oRepeatRule.byDays, function (sItem) { this['week' + sItem](true); }, this); } this.repeatPeriod(oRepeatRule.period); this.repeatInterval(oRepeatRule.interval); this.repeatCount(oRepeatRule.count); this.repeatWeekNum(oRepeatRule.weekNum); } }; CalendarEventPopup.prototype.getDays = function () { var aDays = []; if (this.weekMO()) {aDays.push('MO');} if (this.weekTU()) {aDays.push('TU');} if (this.weekWE()) {aDays.push('WE');} if (this.weekTH()) {aDays.push('TH');} if (this.weekFR()) {aDays.push('FR');} if (this.weekSA()) {aDays.push('SA');} if (this.weekSU()) {aDays.push('SU');} return aDays; }; CalendarEventPopup.prototype.onMainPanelClick = function () { if (this.dateEdit()) { this.dateEdit(false); } }; /** * @param {Object} oEl * @param {Object} oEv */ CalendarEventPopup.prototype.onKeydown = function (oEl, oEv) { if (oEv.keyCode === Enums.Key.Enter || oEv.keyCode === Enums.Key.Esc) { oEv.preventDefault(); } }; /** * @param {Object} oEl * @param {Object} oEv * @param {Function} oValueObserver */ CalendarEventPopup.prototype.onKeyup = function (oEl, oEv, oValueObserver) { if((oEv.target.id === "event_subject" || oEv.target.id === "event_location") && oEv.keyCode === Enums.Key.Enter) { this.onSaveClick(); } // this.autosizeTrigger.notifySubscribers(); }; CalendarEventPopup.prototype.onPaste = function (oEl, oEv, oValueObserver) { var sWithoutLineBreaks = oValueObserver().replace(/[\r\n\t]+/gm, ' '); oValueObserver(sWithoutLineBreaks); }; CalendarEventPopup.prototype.selectStartDate = function () { if (this.startDate() && this.endDate()) { var sDateFormat = this.dateFormatMoment, sTimeFormat = this.timeFormatMoment, fFCMoment = this.FCMoment || moment, oDate = this.getDateTime(this.startDom(), this.startTime()), oCompareDate = this.getDateTime(this.endDom(), this.endTime()), nTimeDate = this.getUnixTimestamp(oDate), nCompareTimeDate = this.getUnixTimestamp(oCompareDate), oMomentDate = fFCMoment(oDate), oMomentCompareDate = fFCMoment(oCompareDate), sDateLoc = oMomentDate.format(sDateFormat), sTimeLoc = oMomentDate.format(sTimeFormat), sCompareDateLoc = oMomentCompareDate.format(sDateFormat), sCompareTimeLoc = oMomentCompareDate.format(sTimeFormat) ; this.isEvOneDay(sDateLoc === sCompareDateLoc); this.isEvOneTime(sTimeLoc === sCompareTimeLoc); if (nTimeDate > nCompareTimeDate) { this.datepickerSetDate(this.endDom(), oDate); this.endDate(sDateLoc); this.endTime(sTimeLoc); this.isEvOneDay(true); this.isEvOneTime(true); } this.startDate(sDateLoc); this.startTime(sTimeLoc); this.yearlyDate(oMomentDate.format(this.getPartOfDate(this.dateFormatMoment.slice(0,-5)))); this.monthlyDate(oMomentDate.format(this.getPartOfDate(this.dateFormatMoment.slice(0,2)))); } }; CalendarEventPopup.prototype.selectEndDate = function () { if (this.endDate() && this.startDate()) { var sDateFormat = this.dateFormatMoment, sTimeFormat = this.timeFormatMoment, fFCMoment = this.FCMoment || moment, oDate = this.getDateTime(this.endDom(), this.endTime()), oCompareDate = this.getDateTime(this.startDom(), this.startTime()), nTimeDate = this.getUnixTimestamp(oDate), nCompareTimeDate = this.getUnixTimestamp(oCompareDate), oMomentDate = fFCMoment(oDate), oMomentCompareDate = fFCMoment(oCompareDate), sDateLoc = oMomentDate.format(sDateFormat), sTimeLoc = oMomentDate.format(sTimeFormat), sCompareDateLoc = oMomentCompareDate.format(sDateFormat), sCompareTimeLoc = oMomentCompareDate.format(sTimeFormat) ; this.isEvOneDay(sDateLoc === sCompareDateLoc); this.isEvOneTime(sTimeLoc === sCompareTimeLoc); if(nTimeDate < nCompareTimeDate) { this.datepickerSetDate(this.startDom(), oDate); this.startDate(sDateLoc); this.startTime(sTimeLoc); this.isEvOneDay(true); this.isEvOneTime(true); } this.endDate(sDateLoc); this.endTime(sTimeLoc); this.repeatEndDom().datepicker('option', 'minDate', oDate); if (!this.isRepeat()) { this.datepickerSetDate(this.repeatEndDom(), oMomentDate.add('days', 7).toDate()); } } }; /** * @param {Object} oDate * @return {number} */ CalendarEventPopup.prototype.getUnixTimestamp = function (oDate) { return moment(oDate).unix(); }; /** * @param {Object} oInput * @param {string} sTime * @return {Date} */ CalendarEventPopup.prototype.getDateTime = function (oInput, sTime) { sTime = moment(sTime, 'h:mm a').format('HH:mm'); var oDate = oInput.datepicker('getDate'), aTime = sTime ? sTime.split(':') : [] ; if (aTime.length === 2) { oDate.setHours(aTime[0]); oDate.setMinutes(aTime[1]); } return oDate; }; /** * @param {Object} oInput * @param {Object} oDate */ CalendarEventPopup.prototype.datepickerSetDate = function (oInput, oDate) { oInput.datepicker('setDate', oDate); }; /** * @param {string} sDate * @param {string} sTime * @return {Date} */ /*CalendarEventPopup.prototype.getDateFromStr = function (sDate, sTime) { return (moment(sDate + ' ' + sTime, this.dateFormatMoment + ' ' + this.timeFormatMoment)).toDate(); };*/ /** * @param {string} sDateFormat * @return {string} */ CalendarEventPopup.prototype.getPartOfDate = function (sDateFormat) { var sMomentDateFormat = 'MM/DD'; switch (sDateFormat) { case 'MM/DD': sMomentDateFormat = 'MM/DD'; break; case 'DD/MM': sMomentDateFormat = 'DD/MM'; break; case 'DD MMMM': sMomentDateFormat = 'DD MMMM'; break; case 'DD': sMomentDateFormat = 'DD'; break; } return sMomentDateFormat; }; CalendarEventPopup.prototype.setActualTime = function () { var oMoment = moment(); if (oMoment.minutes() > 30) { oMoment.minutes(60); } else { oMoment.minutes(30); } oMoment.seconds(0); oMoment.milliseconds(0); this.startTime(oMoment.format(this.timeFormatMoment)); this.endTime(oMoment.add('minutes', 30).format(this.timeFormatMoment)); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CalendarEventPopup.prototype.onAppointmentActionResponse = function (oResponse, oRequest) { if (!oResponse.Result) { App.Api.showErrorByCode(oResponse, Utils.i18n('WARNING/UNKNOWN_ERROR')); } }; /** * @param {atring} sDecision */ CalendarEventPopup.prototype.doAppointmentAction = function (sDecision) { var iDecision = Enums.IcalConfigInt.NeedsAction, aAttendees = this.attendees(), //sEmail = this.defaultAccount ? this.defaultAccount.email() : '', sEmail = AppData.Accounts ? AppData.Accounts.getAttendee(_.map(this.attendees(), function (oAttendee){ return oAttendee.email; }, this)) : '', oAttendee = _.find(this.attendees(), function(oAttendee){ return oAttendee.email === sEmail; }, this), oCalendar = this.calendars.getCalendarById(this.selectedCalendarId()), /*oParameters = { 'Action': 'EventUpdateAppointment', 'actionAppointment': iDecision, 'calendarId': this.selectedCalendarId(), 'uid' : this.uid, 'attendee': sEmail }*/ oParameters = { 'Action': 'AppointmentAction', 'AppointmentAction': sDecision, 'CalendarId': this.selectedCalendarId(), 'EventId': this.uid(), 'Attendee': sEmail } ; if (oAttendee) { switch (sDecision) { case Enums.IcalConfig.Accepted: iDecision = Enums.IcalConfigInt.Accepted; App.CalendarCache.markIcalAccepted(this.uid()); break; case Enums.IcalConfig.Tentative: iDecision = Enums.IcalConfigInt.Tentative; App.CalendarCache.markIcalTentative(this.uid()); break; case Enums.IcalConfig.Declined: iDecision = Enums.IcalConfigInt.Declined; App.CalendarCache.markIcalNonexistent(this.uid()); break; } App.Ajax.send(oParameters, this.onAppointmentActionResponse, this); oAttendee.status = iDecision; this.attendees([]); this.attendees(aAttendees); this.setCurrentAttenderStatus(oAttendee.email, this.attendees()); if (sDecision === Enums.IcalConfig.Declined && oCalendar && this.callbackAttendeeActionDecline && Utils.isFunc(this.callbackAttendeeActionDecline)) { this.callbackAttendeeActionDecline(oCalendar, this.id()); this.closePopup(); } } }; /** * @param {boolean} bShared * @param {boolean} bEditable * @param {boolean} bMyEvent */ CalendarEventPopup.prototype.editableSwitch = function (bShared, bEditable, bMyEvent) { this.isEditable((bShared && bEditable && bMyEvent) || (!bShared && bEditable && bMyEvent) || (bShared && bEditable && !bMyEvent)); this.isEditableReminders(bEditable); }; /** * @param {string} sCurrentEmail * @param {Array} aAttendees */ CalendarEventPopup.prototype.setCurrentAttenderStatus = function (sCurrentEmail, aAttendees) { var oCurrentAttender = _.find(aAttendees, function(oAttender){ return oAttender.email === sCurrentEmail; }); this.attenderStatus(oCurrentAttender ? oCurrentAttender.status : 0); }; CalendarEventPopup.prototype.getAttenderTextStatus = function (sStatus) { switch (sStatus) { case 0: sStatus="pending"; break; case 1: sStatus="accepted"; break; case 2: sStatus="declined"; break; case 3: sStatus="tentative"; break; } return sStatus; }; CalendarEventPopup.prototype.setDayOfWeek = function () { if (this.repeatPeriod() === Enums.CalendarRepeatPeriod.Weekly && !this.getDays().length) { var iDayOfWeek = this.getDateTime(this.startDom()).getUTCDay(); switch (iDayOfWeek) { case 0: this.weekMO(true); break; case 1: this.weekTU(true); break; case 2: this.weekWE(true); break; case 3: this.weekTH(true); break; case 4: this.weekFR(true); break; case 5: this.weekSA(true); break; case 6: this.weekSU(true); break; } } }; /** * @param {string} sTimeFormatMoment * @returns {Array} */ CalendarEventPopup.prototype.getDisplayedTimes = function (sTimeFormatMoment) { var aDisplayedTimes = []; switch (sTimeFormatMoment) { case 'HH:mm': aDisplayedTimes = [ {'text':'00:00', 'value':'00:00'}, {'text':'00:30', 'value':'00:30'}, {'text':'01:00', 'value':'01:00'}, {'text':'01:30', 'value':'01:30'}, {'text':'02:00', 'value':'02:00'}, {'text':'02:30', 'value':'02:30'}, {'text':'03:00', 'value':'03:00'}, {'text':'03:30', 'value':'03:30'}, {'text':'04:00', 'value':'04:00'}, {'text':'04:30', 'value':'04:30'}, {'text':'05:00', 'value':'05:00'}, {'text':'05:30', 'value':'05:30'}, {'text':'06:00', 'value':'06:00'}, {'text':'06:30', 'value':'06:30'}, {'text':'07:00', 'value':'07:00'}, {'text':'07:30', 'value':'07:30'}, {'text':'08:00', 'value':'08:00'}, {'text':'08:30', 'value':'08:30'}, {'text':'09:00', 'value':'09:00'}, {'text':'09:30', 'value':'09:30'}, {'text':'10:00', 'value':'10:00'}, {'text':'10:30', 'value':'10:30'}, {'text':'11:00', 'value':'11:00'}, {'text':'11:30', 'value':'11:30'}, {'text':'12:00', 'value':'12:00'}, {'text':'12:30', 'value':'12:30'}, {'text':'13:00', 'value':'13:00'}, {'text':'13:30', 'value':'13:30'}, {'text':'14:00', 'value':'14:00'}, {'text':'14:30', 'value':'14:30'}, {'text':'15:00', 'value':'15:00'}, {'text':'15:30', 'value':'15:30'}, {'text':'16:00', 'value':'16:00'}, {'text':'16:30', 'value':'16:30'}, {'text':'17:00', 'value':'17:00'}, {'text':'17:30', 'value':'17:30'}, {'text':'18:00', 'value':'18:00'}, {'text':'18:30', 'value':'18:30'}, {'text':'19:00', 'value':'19:00'}, {'text':'19:30', 'value':'19:30'}, {'text':'20:00', 'value':'20:00'}, {'text':'20:30', 'value':'20:30'}, {'text':'21:00', 'value':'21:00'}, {'text':'21:30', 'value':'21:30'}, {'text':'22:00', 'value':'22:00'}, {'text':'22:30', 'value':'22:30'}, {'text':'23:00', 'value':'23:00'}, {'text':'23:30', 'value':'23:30'} ]; break; case 'hh:mm A': aDisplayedTimes = [ {'text':'12:00 AM', 'value':'12:00 AM'}, {'text':'12:30 AM', 'value':'12:30 AM'}, {'text':'01:00 AM', 'value':'01:00 AM'}, {'text':'01:30 AM', 'value':'01:30 AM'}, {'text':'02:00 AM', 'value':'02:00 AM'}, {'text':'02:30 AM', 'value':'02:30 AM'}, {'text':'03:00 AM', 'value':'03:00 AM'}, {'text':'03:30 AM', 'value':'03:30 AM'}, {'text':'04:00 AM', 'value':'04:00 AM'}, {'text':'04:30 AM', 'value':'04:30 AM'}, {'text':'05:00 AM', 'value':'05:00 AM'}, {'text':'05:30 AM', 'value':'05:30 AM'}, {'text':'06:00 AM', 'value':'06:00 AM'}, {'text':'06:30 AM', 'value':'06:30 AM'}, {'text':'07:00 AM', 'value':'07:00 AM'}, {'text':'07:30 AM', 'value':'07:30 AM'}, {'text':'08:00 AM', 'value':'08:00 AM'}, {'text':'08:30 AM', 'value':'08:30 AM'}, {'text':'09:00 AM', 'value':'09:00 AM'}, {'text':'09:30 AM', 'value':'09:30 AM'}, {'text':'10:00 AM', 'value':'10:00 AM'}, {'text':'10:30 AM', 'value':'10:30 AM'}, {'text':'11:00 AM', 'value':'11:00 AM'}, {'text':'11:30 AM', 'value':'11:30 AM'}, {'text':'12:00 PM', 'value':'12:00 PM'}, {'text':'12:30 PM', 'value':'12:30 PM'}, {'text':'01:00 PM', 'value':'01:00 PM'}, {'text':'01:30 PM', 'value':'01:30 PM'}, {'text':'02:00 PM', 'value':'02:00 PM'}, {'text':'02:30 PM', 'value':'02:30 PM'}, {'text':'03:00 PM', 'value':'03:00 PM'}, {'text':'03:30 PM', 'value':'03:30 PM'}, {'text':'04:00 PM', 'value':'04:00 PM'}, {'text':'04:30 PM', 'value':'04:30 PM'}, {'text':'05:00 PM', 'value':'05:00 PM'}, {'text':'05:30 PM', 'value':'05:30 PM'}, {'text':'06:00 PM', 'value':'06:00 PM'}, {'text':'06:30 PM', 'value':'06:30 PM'}, {'text':'07:00 PM', 'value':'07:00 PM'}, {'text':'07:30 PM', 'value':'07:30 PM'}, {'text':'08:00 PM', 'value':'08:00 PM'}, {'text':'08:30 PM', 'value':'08:30 PM'}, {'text':'09:00 PM', 'value':'09:00 PM'}, {'text':'09:30 PM', 'value':'09:30 PM'}, {'text':'10:00 PM', 'value':'10:00 PM'}, {'text':'10:30 PM', 'value':'10:30 PM'}, {'text':'11:00 PM', 'value':'11:00 PM'}, {'text':'11:30 PM', 'value':'11:30 PM'} ]; break; } return aDisplayedTimes; }; CalendarEventPopup.prototype.displayReminderPart = function (sPart, sPrefix) { var sTemplate = ''; if (sPart === '%REMINDERS%') { sTemplate = 'Reminders'; } else { sTemplate = 'Text'; } return sPrefix + sTemplate; }; /** * @constructor */ function CalendarEditRecurrenceEventPopup() { this.fCallback = null; this.confirmDesc = Utils.i18n('CALENDAR/EDIT_RECURRENCE_CONFIRM_DESCRIPTION'); this.onlyThisInstanceButtonText = ko.observable(Utils.i18n('CALENDAR/ONLY_THIS_INSTANCE')); this.allEventsButtonText = ko.observable(Utils.i18n('CALENDAR/ALL_EVENTS_IN_THE_SERIES')); this.cancelButtonText = ko.observable(Utils.i18n('MAIN/BUTTON_CANCEL')); } /** * @param {Function} fCallback */ CalendarEditRecurrenceEventPopup.prototype.onShow = function (fCallback) { if (Utils.isFunc(fCallback)) { this.fCallback = fCallback; } }; /** * @return {string} */ CalendarEditRecurrenceEventPopup.prototype.popupTemplate = function () { return 'Popups_Calendar_EditRecurrenceEventPopupViewModel'; }; CalendarEditRecurrenceEventPopup.prototype.onlyThisInstanceButtonClick = function () { if (this.fCallback) { this.fCallback(Enums.CalendarEditRecurrenceEvent.OnlyThisInstance); } this.closeCommand(); }; CalendarEditRecurrenceEventPopup.prototype.allEventsButtonClick = function () { if (this.fCallback) { this.fCallback(Enums.CalendarEditRecurrenceEvent.AllEvents); } this.closeCommand(); }; CalendarEditRecurrenceEventPopup.prototype.cancelButtonClick = function () { if (this.fCallback) { this.fCallback(Enums.CalendarEditRecurrenceEvent.None); } this.closeCommand(); }; CalendarEditRecurrenceEventPopup.prototype.onEscHandler = function () { this.cancelButtonClick(); }; /** * @constructor */ function CalendarSelectCalendarsPopup() { this.fCallback = null; this.fProceedUploading = null; this.calendars = null; this.calendarsList = ko.observableArray([]); this.calendarColor = ko.observable(''); this.selectedCalendarName = ko.observable(''); this.selectedCalendarId = ko.observable(''); this.selectedCalendarId.subscribe(function (sValue) { if (sValue) { var oCalendar = this.calendars.getCalendarById(sValue); this.selectedCalendarName(oCalendar.name()); this.selectedCalendarIsEditable(oCalendar.isEditable()); this.changeCalendarColor(sValue); } }, this); this.selectedCalendarIsEditable = ko.observable(false); } CalendarSelectCalendarsPopup.prototype.onShow = function (oParameters) { this.fCallback = oParameters.CallbackSave; this.fProceedUploading = oParameters.ProceedUploading; this.calendars = oParameters.Calendars; this.calendarsList(oParameters.EditableCalendars); this.selectedCalendarId(oParameters.DefaultCalendarId); this.changeCalendarColor(this.selectedCalendarId()); }; /** * @return {string} */ CalendarSelectCalendarsPopup.prototype.popupTemplate = function () { return 'Popups_Calendar_CalendarSelectCalendarsPopupViewModel'; }; CalendarSelectCalendarsPopup.prototype.onSaveClick = function () { if (this.fCallback) { this.fCallback(this.selectedCalendarId(), this.fProceedUploading); } this.closeCommand(); }; CalendarSelectCalendarsPopup.prototype.onCancelClick = function () { this.closeCommand(); }; CalendarSelectCalendarsPopup.prototype.changeCalendarColor = function (sId) { if (Utils.isFunc(this.calendars.getCalendarById)) { var oCalendar = this.calendars.getCalendarById(sId); if (oCalendar) { this.calendarColor(''); this.calendarColor(oCalendar.color()); } } }; /** * @constructor */ function PhonePopup() { this.phone = App.Phone; this.action = this.phone.action; this.report = this.phone.report; this.text = ko.observable(''); this.callback = null; } /** * @return {string} */ PhonePopup.prototype.popupTemplate = function () { return 'Popups_PhonePopupViewModel'; }; PhonePopup.prototype.onShow = function (oParameters) { this.text(oParameters.text); this.callback = oParameters.Callback || Utils.emptyFunction; }; PhonePopup.prototype.onCancelClick = function () { this.closeCommand(); }; PhonePopup.prototype.onOKClick = function () { this.closeCommand(); this.callback(); }; PhonePopup.prototype.answer = function () { this.action(Enums.PhoneAction.IncomingConnect); }; PhonePopup.prototype.hangup = function () { this.action(Enums.PhoneAction.Online); }; /** * @constructor */ function CGenerateOpenPgpKeyPopup() { this.pgp = null; this.emails = ko.observableArray([]); this.selectedEmail = ko.observable(''); this.password = ko.observable(''); this.keyLengthOptions = [1024, 2048]; this.selectedKeyLength = ko.observable(1024); this.process = ko.observable(false); } /** * @param {Object} oPgp */ CGenerateOpenPgpKeyPopup.prototype.onShow = function (oPgp) { this.pgp = oPgp; this.emails(AppData.Accounts.getAllFullEmails()); this.selectedEmail(''); this.password(''); this.selectedKeyLength(2048); this.process(false); }; /** * @return {string} */ CGenerateOpenPgpKeyPopup.prototype.popupTemplate = function () { return 'Popups_GenerateOpenPgpKeyPopupViewModel'; }; CGenerateOpenPgpKeyPopup.prototype.generate = function () { if (this.pgp) { this.process(true); _.delay(_.bind(function () { var oRes = this.pgp.generateKey(this.selectedEmail(), this.password(), this.selectedKeyLength()); if (oRes && oRes.result) { App.Api.showReport(Utils.i18n('OPENPGP/REPORT_KEY_SUCCESSFULLY_GENERATED')); } if (oRes && !oRes.result) { this.process(false); App.Api.showPgpErrorByCode(oRes, Enums.PgpAction.Generate); } else { this.closeCommand(); } }, this), 50); } }; /** * @constructor */ function CShowOpenPgpKeyArmorPopup() { this.armor = ko.observable(''); this.htmlArmor = ko.computed(function () { return Utils.encodeHtml(this.armor().replace(/\r/g, '')); }, this); this.user = ko.observable(''); this.private = ko.observable(false); this.titleText = ko.computed(function () { return this.private() ? Utils.i18n('OPENPGP/POPUP_TITLE_VIEW_PRIVATE_KEY', {'USER': this.user()}) : Utils.i18n('OPENPGP/POPUP_TITLE_VIEW_PUBLIC_KEY', {'USER': this.user()}); }, this); this.downloadLinkHref = ko.computed(function() { var sHref = '#', oBlob = null ; window.URL = window.webkitURL || window.URL; if (Blob && window.URL && Utils.isFunc(window.URL.createObjectURL)) { oBlob = new Blob([this.armor()], {type: 'text/plain'}); sHref = window.URL.createObjectURL(oBlob); } return sHref; }, this); this.downloadLinkFilename = ko.computed(function () { var sConvertedUser = this.user().replace(/</g, '').replace(/>/g, ''), sLangKey = this.private() ? 'OPENPGP/PRIVATE_KEY_FILENAME' : 'OPENPGP/PUBLIC_KEY_FILENAME' ; return Utils.i18n(sLangKey, {'USER': sConvertedUser}) + '.asc'; }, this); this.domKey = ko.observable(null); } /** * @param {Object} oKey */ CShowOpenPgpKeyArmorPopup.prototype.onShow = function (oKey) { this.armor(oKey.getArmor()); this.user(oKey.getUser()); this.private(oKey.isPrivate()); }; /** * @return {string} */ CShowOpenPgpKeyArmorPopup.prototype.popupTemplate = function () { return 'Popups_ShowOpenPgpKeyArmorPopupViewModel'; }; CShowOpenPgpKeyArmorPopup.prototype.send = function () { if (this.armor() !== '' && this.downloadLinkFilename() !== '') { App.Routing.goDirectly(App.Links.compose(), ['data-as-file', this.armor(), this.downloadLinkFilename()]); this.closeCommand(); } }; CShowOpenPgpKeyArmorPopup.prototype.select = function () { var oDomKey = (this.domKey() && this.domKey().length === 1) ? this.domKey()[0] : null, oSel = null, oRange = null ; if (oDomKey && window.getSelection && document.createRange) { oRange = document.createRange(); oRange.setStart(oDomKey, 0); oRange.setEnd(oDomKey, 1); oSel = window.getSelection(); oSel.removeAllRanges(); oSel.addRange(oRange); } }; /** * @constructor */ function CImportOpenPgpKeyPopup() { this.pgp = null; this.keyArmor = ko.observable(''); this.keyArmorFocused = ko.observable(false); this.keys = ko.observableArray([]); this.hasExistingKeys = ko.observable(false); this.headlineText = ko.computed(function () { return Utils.i18n('OPENPGP/INFO_TEXT_INCLUDES_KEYS_PLURAL', {}, null, this.keys().length); }, this); } /** * @param {Object} oPgp */ CImportOpenPgpKeyPopup.prototype.onShow = function (oPgp, sArmor) { this.pgp = oPgp; this.keyArmor(sArmor || ''); this.keyArmorFocused(true); this.keys([]); this.hasExistingKeys(false); if (this.keyArmor() !== '') { this.checkArmor(); } }; /** * @return {string} */ CImportOpenPgpKeyPopup.prototype.popupTemplate = function () { return 'Popups_ImportOpenPgpKeyPopupViewModel'; }; CImportOpenPgpKeyPopup.prototype.checkArmor = function () { var aRes = null, aKeys = [], oPgp = this.pgp, bHasExistingKeys = false ; if (this.keyArmor() === '') { this.keyArmorFocused(true); } else if (oPgp) { aRes = oPgp.getArmorInfo(this.keyArmor()); if (Utils.isNonEmptyArray(aRes)) { _.each(aRes, function (oKey) { if (oKey) { var oSameKey = oPgp.findKeyByID(oKey.getId(), oKey.isPublic()), bHasSameKey = (oSameKey !== null), sAddInfoLangKey = oKey.isPublic() ? 'OPENPGP/PUBLIC_KEY_ADD_INFO' : 'OPENPGP/PRIVATE_KEY_ADD_INFO' ; bHasExistingKeys = bHasExistingKeys || bHasSameKey; aKeys.push({ 'armor': oKey.getArmor(), 'email': oKey.user, 'id': oKey.getId(), 'addInfo': Utils.i18n(sAddInfoLangKey, {'LENGTH': oKey.getBitSize()}), 'needToImport': ko.observable(!bHasSameKey), 'disabled': bHasSameKey }); } }); } if (aKeys.length === 0) { App.Api.showError(Utils.i18n('OPENPGP/ERROR_IMPORT_NO_KEY_FOUNDED')); } this.keys(aKeys); this.hasExistingKeys(bHasExistingKeys); } }; CImportOpenPgpKeyPopup.prototype.importKey = function () { var oRes = null, aArmors = [] ; if (this.pgp) { _.each(this.keys(), function (oSimpleKey) { if (oSimpleKey.needToImport()) { aArmors.push(oSimpleKey.armor); } }); if (aArmors.length > 0) { oRes = this.pgp.importKeys(aArmors.join('')); if (oRes && oRes.result) { App.Api.showReport(Utils.i18n('OPENPGP/REPORT_KEY_SUCCESSFULLY_IMPORTED_PLURAL', {}, null, aArmors.length)); } if (oRes && !oRes.result) { App.Api.showPgpErrorByCode(oRes, Enums.PgpAction.Import, Utils.i18n('OPENPGP/ERROR_IMPORT_KEY')); } this.closeCommand(); } else { App.Api.showError(Utils.i18n('OPENPGP/ERROR_IMPORT_NO_KEY_SELECTED')); } } }; /** * @constructor */ function COpenPgpEncryptPopup() { this.data = ko.observable(''); this.fromEmail = ko.observable(''); this.emails = ko.observableArray([]); this.okCallback = null; this.cancelCallback = null; this.sign = ko.observable(true); this.password = ko.observable(''); this.passwordFocused = ko.observable(false); this.encrypt = ko.observable(true); this.signEncryptButtonText = ko.computed(function () { var sText = Utils.i18n('OPENPGP/BUTTON_SIGN_ENCRYPT'); if (this.sign() && !this.encrypt()) { sText = Utils.i18n('OPENPGP/BUTTON_SIGN'); } if (!this.sign() && this.encrypt()) { sText = Utils.i18n('OPENPGP/BUTTON_ENCRYPT'); } return sText; }, this); this.isEnableSignEncrypt = ko.computed(function () { return this.sign() || this.encrypt(); }, this); this.signEncryptCommand = Utils.createCommand(this, this.executeSignEncrypt, this.isEnableSignEncrypt); this.signAndSend = ko.observable(false); } /** * @param {string} sData * @param {string} sFromEmail * @param {Array} aEmails * @param {boolean} bSignAndSend * @param {Function} fOkCallback * @param {Function} fCancelCallback */ COpenPgpEncryptPopup.prototype.onShow = function (sData, sFromEmail, aEmails, bSignAndSend, fOkCallback, fCancelCallback) { this.data(sData); this.fromEmail(sFromEmail); this.emails(aEmails); this.okCallback = fOkCallback; this.cancelCallback = fCancelCallback; this.sign(true); this.password(''); this.encrypt(!bSignAndSend); this.signAndSend(bSignAndSend); }; /** * @return {string} */ COpenPgpEncryptPopup.prototype.popupTemplate = function () { return 'Popups_OpenPgpEncryptPopupViewModel'; }; COpenPgpEncryptPopup.prototype.executeSignEncrypt = function () { var fPgpCallback = _.bind(function (oPgp) { if (oPgp) { this.signEncrypt(oPgp); } }, this); App.Api.pgp(fPgpCallback, AppData.User.IdUser); }; /** * @param {Object} oPgp */ COpenPgpEncryptPopup.prototype.signEncrypt = function (oPgp) { var sData = this.data(), sPrivateEmail = this.sign() ? this.fromEmail() : '', aPrincipalsEmail = this.emails(), sPrivateKeyPassword = this.sign() ? this.password() : '', oRes = null, sOkReport = '', sPgpAction = '' ; if (this.encrypt()) { if (aPrincipalsEmail.length === 0) { App.Api.showError(Utils.i18n('OPENPGP/ERROR_TO_ENCRYPT_SPECIFY_RECIPIENTS')); } else { if (this.sign()) { sPgpAction = Enums.PgpAction.EncryptSign; sOkReport = Utils.i18n('OPENPGP/REPORT_MESSAGE_SIGNED_ENCRYPTED_SUCCSESSFULLY'); oRes = oPgp.signAndEncrypt(sData, sPrivateEmail, aPrincipalsEmail, sPrivateKeyPassword); } else { sPgpAction = Enums.PgpAction.Encrypt; sOkReport = Utils.i18n('OPENPGP/REPORT_MESSAGE_ENCRYPTED_SUCCSESSFULLY'); oRes = oPgp.encrypt(sData, aPrincipalsEmail); } } } else if (this.sign()) { sPgpAction = Enums.PgpAction.Sign; sOkReport = Utils.i18n('OPENPGP/REPORT_MESSAGE_SIGNED_SUCCSESSFULLY'); oRes = oPgp.sign(sData, sPrivateEmail, sPrivateKeyPassword); } if (oRes) { if (oRes.result) { this.closeCommand(); if (this.okCallback) { if (!this.signAndSend()) { App.Api.showReport(sOkReport); } this.okCallback(oRes.result, this.encrypt()); } } else { App.Api.showPgpErrorByCode(oRes, sPgpAction); } } }; COpenPgpEncryptPopup.prototype.cancel = function () { if (this.cancelCallback) { this.cancelCallback(); } this.closeCommand(); }; COpenPgpEncryptPopup.prototype.onEscHandler = function () { this.cancel(); }; /** * @constructor */ function GooglePickerPopup() { this.allowGoogle = AppData.SocialGoogle; this.googleKey = AppData.SocialGoogleApiKey; this.googleClientId = AppData.SocialGoogleId; this.picker = null; this.pickerCreated = false; this.googleApiLoaded = false; this.pickerApiLoaded = false; this.fCallback = null; this.timeOut = null; } /** * @param {Function} fCallback */ GooglePickerPopup.prototype.onShow = function (fCallback) { var oauthToken = null ; if (Utils.isFunc(fCallback)) { this.fCallback = fCallback; } if (this.pickerApiLoaded && this.googleApiLoaded) { oauthToken = window.gapi.auth.getToken(); if (oauthToken && !_.isEmpty(oauthToken) && !oauthToken.error) { this.createPicker(); } else { this.doGoogleAuth(); } } }; /** * Executes after applying bindings. */ GooglePickerPopup.prototype.onApplyBindings = function () { if (this.allowGoogle) { Utils.loadScript('https://apis.google.com/js/api.js?onload=onGoogleApiLoad', _.bind(this.onGoogleApiLoad, this), null, 'onGoogleApiLoad'); } }; /** * @return {string} */ GooglePickerPopup.prototype.popupTemplate = function () { return 'Popups_GooglePickerPopupViewModel'; }; GooglePickerPopup.prototype.onEscHandler = function () { this.onCancelClick(); }; GooglePickerPopup.prototype.onCancelClick = function () { this.closeCommand(); if (this.pickerApiLoaded && this.picker) { this.picker.setVisible(false); } }; GooglePickerPopup.prototype.onGoogleApiLoad = function () { this.googleApiLoaded = true; window.gapi.load('auth', { 'callback': _.bind(this.doGoogleAuth, this) }); window.gapi.load('picker', { 'callback': _.bind(this.onPickerApiLoad, this) }); }; GooglePickerPopup.prototype.doGoogleAuth = function () { var oauthToken = window.gapi.auth.getToken(); if (!oauthToken || _.isEmpty(oauthToken) || oauthToken && oauthToken.error) { window.gapi.auth.init(_.bind(this.checkGoogleAuth, this, true)); } }; GooglePickerPopup.prototype.checkGoogleAuth = function (bImmediate) { this.checkTimer = window.setTimeout(_.bind(this.ckeckPickerCreate, this), 5000); window.gapi.auth.authorize({ 'client_id': this.googleClientId, 'scope': ['https://www.googleapis.com/auth/drive'], 'immediate': !!bImmediate }, _.bind(this.handleGoogleAuthResult, this)); }; GooglePickerPopup.prototype.handleGoogleAuthResult = function (authResult) { if (authResult) { if (!authResult.error) { this.createPicker(); } else if (authResult.error === 'immediate_failed') { window.clearTimeout(this.checkTimer); this.checkGoogleAuth(false); } } }; GooglePickerPopup.prototype.onPickerApiLoad = function () { this.pickerApiLoaded = true; }; GooglePickerPopup.prototype.ckeckPickerCreate = function () { window.clearTimeout(this.checkTimer); if (!this.pickerCreated) { this.closeCommand(); App.Api.showError(Utils.i18n('COMPOSE/ERROR_GOOGLE_PICKER_POPUP')); } }; GooglePickerPopup.prototype.createPicker = function () { var docsView = null, oauthToken = window.gapi.auth.getToken(), self = this ; if (this.pickerApiLoaded && oauthToken && !oauthToken.error) { docsView = new window.google.picker.DocsView() .setIncludeFolders(true); this.picker = new window.google.picker.PickerBuilder() .addView(docsView) .setOAuthToken(oauthToken.access_token) .setDeveloperKey(self.googleKey) .setOrigin(window.location.protocol + '//' + window.location.host) .setCallback(_.bind(self.pickerCallback, self, oauthToken.access_token)) .enableFeature(window.google.picker.Feature.NAV_HIDDEN) .enableFeature(window.google.picker.Feature.MULTISELECT_ENABLED) .setLocale(AppData.User.DefaultLanguageShort) .build(); this.picker.setVisible(true); this.picker.A.style.zIndex = 2000; this.pickerCreated = true; } }; GooglePickerPopup.prototype.pickerCallback = function (sAccessToken, data) { if (data[window.google.picker.Response.ACTION] === window.google.picker.Action.PICKED) { if (this.fCallback) { this.fCallback(data[window.google.picker.Response.DOCUMENTS], sAccessToken); } this.closeCommand(); } else if (data[window.google.picker.Response.ACTION] === window.google.picker.Action.CANCEL) { this.closeCommand(); } }; /** * @constructor * @param {boolean} bAllowOpenPgp */ function CAppSettingsModel(bAllowOpenPgp) { this.AllowWebMail = true; // allows to edit common settings and calendar settings this.AllowUsersChangeInterfaceSettings = true; // allows to delete accounts, allows to change account properties (name and password is always possible to change), // allows to manage special folders, allows to add new accounts this.AllowUsersChangeEmailSettings = true; // allows to add new accounts (if AllowUsersChangeEmailSettings === true) this.AllowUsersAddNewAccounts = true || this.AllowUsersChangeEmailSettings; this.SiteName = ''; // list of available languages this.Languages = [ {name: 'English', value: 'en'} ]; // list of available themes this.Themes = [ 'Default' ]; // list of available date formats this.DateFormats = []; this.DefaultLanguage = 'English'; // maximum size of uploading attachment this.AttachmentSizeLimit = 10240000; this.ImageUploadSizeLimit = 10240000; this.FileSizeLimit = 10240000; // activate autosave this.AutoSave = true; this.AutoSaveIntervalSeconds = 60; this.IdleSessionTimeout = 0; // allows to insert an image to html-text in rich text editor this.AllowInsertImage = true; this.AllowBodySize = false; this.MaxBodySize = 600; this.MaxSubjectSize = 255; this.AllowPrefetch = true; this.MaxPrefetchBodiesSize = 50000; this.LoginFormType = Enums.LoginFormType.Email; this.LoginAtDomainValue = ''; this.AllowRegistration = false; this.AllowPasswordReset = false; this.RegistrationDomains = []; this.RegistrationQuestions = []; this.DemoWebMail = true; this.DemoWebMailLogin = ''; this.DemoWebMailPassword = ''; this.LoginDescription = ''; this.GoogleAnalyticsAccount = ''; this.ShowQuotaBar = false; this.ServerUseUrlRewrite = false; this.AllowLanguageOnLogin = false; this.FlagsLangSelect = false; this.CustomLoginUrl = ''; this.CustomLogoutUrl = ''; this.IosDetectOnLogin = false; this.AllowContactsSharing = false; this.DefaultLanguageShort = 'en'; this.AllowOpenPgp = bAllowOpenPgp; this.DefaultTab = ''; this.AllowIosProfile = true; this.PasswordMinLength = 0; this.PasswordMustBeComplex = false; } /** * Parses the application settings from the server. * * @param {Object} oData */ CAppSettingsModel.prototype.parse = function (oData) { this.AllowWebMail = !!oData.AllowWebMail; this.AllowUsersChangeInterfaceSettings = !!oData.AllowUsersChangeInterfaceSettings; this.AllowUsersChangeEmailSettings = !!oData.AllowUsersChangeEmailSettings; this.AllowUsersAddNewAccounts = Utils.isUnd(oData.AllowUsersAddNewAccounts) ? this.AllowUsersChangeEmailSettings : !!oData.AllowUsersAddNewAccounts; this.SiteName = Utils.pString(oData.SiteName); this.Languages = oData.Languages; this.Themes = oData.Themes; this.DateFormats = oData.DateFormats; this.AttachmentSizeLimit = Utils.pInt(oData.AttachmentSizeLimit); this.ImageUploadSizeLimit = Utils.pInt(oData.ImageUploadSizeLimit); this.FileSizeLimit = Utils.pInt(oData.FileSizeLimit); this.AutoSave = !!oData.AutoSave; this.IdleSessionTimeout = Utils.pInt(oData.IdleSessionTimeout) * 60 * 1000; // converts minutes to milliseconds this.AllowInsertImage = !!oData.AllowInsertImage; this.AllowBodySize = !!oData.AllowBodySize; this.MaxBodySize = Utils.pInt(oData.MaxBodySize); this.MaxSubjectSize = Utils.pInt(oData.MaxSubjectSize); this.AllowPrefetch = !!oData.AllowPrefetch; this.LoginFormType = Utils.pInt(oData.LoginFormType); this.LoginSignMeType = Utils.pInt(oData.LoginSignMeType); this.LoginAtDomainValue = Utils.pString(oData.LoginAtDomainValue); this.AllowRegistration = !!oData.AllowRegistration; this.AllowPasswordReset = !!oData.AllowPasswordReset; this.RegistrationDomains = oData.RegistrationDomains; this.RegistrationQuestions = _.without(oData.RegistrationQuestions, ''); this.DemoWebMail = !!oData.DemoWebMail; this.DemoWebMailLogin = Utils.pString(oData.DemoWebMailLogin); this.DemoWebMailPassword = Utils.pString(oData.DemoWebMailPassword); this.GoogleAnalyticsAccount = oData.GoogleAnalyticsAccount; this.ShowQuotaBar = !!oData.ShowQuotaBar; this.ServerUseUrlRewrite = !!oData.ServerUseUrlRewrite; this.AllowLanguageOnLogin = !bMobileApp && !!oData.AllowLanguageOnLogin; this.FlagsLangSelect = !!oData.FlagsLangSelect; this.DefaultLanguage = Utils.pString(oData.DefaultLanguage); this.LoginDescription = Utils.pString(oData.LoginDescription); this.CustomLoginUrl = Utils.pString(oData.CustomLoginUrl); this.CustomLogoutUrl = Utils.pString(oData.CustomLogoutUrl); this.IosDetectOnLogin = !!oData.IosDetectOnLogin; this.AllowContactsSharing = !!oData.AllowContactsSharing; if (oData.DefaultLanguageShort !== '') { this.DefaultLanguageShort = oData.DefaultLanguageShort; } this.DefaultTab = oData.DefaultTab; this.AllowIosProfile = !!oData.AllowIosProfile; this.PasswordMinLength = oData.PasswordMinLength; this.PasswordMustBeComplex = !!oData.PasswordMustBeComplex; }; /** * @constructor */ function CUserSettingsModel() { this.IdUser = 1; // general settings that can be changed in the settings screen this.MailsPerPage = 20; this.ContactsPerPage = 20; this.iInterval = -1; this.AutoCheckMailInterval = 0; this.DefaultTheme = 'Default'; this.DefaultLanguage = 'English'; this.DefaultLanguageShort = 'en'; this.DefaultDateFormat = 'MM/DD/YYYY'; this.defaultTimeFormat = ko.observable(Enums.TimeFormat.F24); this.ThreadsEnabled = true; this.useThreads = ko.observable(true); this.SaveRepliedToCurrFolder = true; this.AllowChangeInputDirection = false; this.DesktopNotifications = false; // allows the creation of messages this.AllowCompose = true; this.AllowReply = true; this.AllowForward = true; this.SaveMail = Enums.SaveMail.Checked; this.AllowFetcher = false; this.OutlookSyncEnable = true; this.MobileSyncEnable = true; this.ShowPersonalContacts = true; this.ShowGlobalContacts = false; this.IsFilesSupported = false; this.IsHelpdeskSupported = false; this.IsHelpdeskAgent = false; this.HelpdeskIframeUrl = ''; // allows to go to contacts screen and edit their settings this.ShowContacts = this.ShowPersonalContacts || this.ShowGlobalContacts; this.LastLogin = 0; this.IsDemo = false; this.AllowVoice = false; this.SipRealm = ''; this.SipWebsocketProxyUrl = ''; this.SipOutboundProxyUrl = ''; this.SipCallerID = ''; this.SipImpi = ''; this.SipImpu = ''; this.SipPassword = ''; this.VoiceProvider = ''; // this.VoiceAccountSID = ''; // this.VoiceAuthToken = ''; // this.VoiceAppSID = ''; // allows to go to calendar screen and edit its settings this.AllowCalendar = true; this.CalendarSharing = false; this.CalendarAppointments = false; // calendar settings that can be changed in the settings screen this.CalendarShowWeekEnds = false; this.CalendarShowWorkDay = false; this.CalendarWorkDayStarts = 0; this.CalendarWorkDayEnds = 0; this.CalendarWeekStartsOn = 0; this.CalendarDefaultTab = Enums.CalendarDefaultTab.Month; this.mobileSync = ko.observable(null); this.MobileSyncDemoPass = 'demo'; this.outlookSync = ko.observable(null); this.OutlookSyncDemoPass = 'demo'; this.AllowHelpdeskNotifications = false; this.IsCollaborationSupported = false; this.AllowFilesSharing = false; this.DefaultFontName = 'Tahoma'; this.fillDefaultFontName(); this.DefaultFontSize = 3; this.fillDefaultFontSize(); this.enableOpenPgp = ko.observable(false); this.AllowAutosaveInDrafts = true; this.AutosignOutgoingEmails = false; this.filesEnable = ko.observable(true); this.SocialAccounts = ko.observableArray([]); } CUserSettingsModel.prototype.fillDefaultFontName = function () { var sDefaultFontName = Utils.pString(AppData.HtmlEditorDefaultFontName); if (sDefaultFontName !== '') { this.DefaultFontName = sDefaultFontName; } }; CUserSettingsModel.prototype.fillDefaultFontSize = function () { var iDefaultFontSize = Utils.pInt(AppData.HtmlEditorDefaultFontSize); if (Utils.inArray(iDefaultFontSize, [2, 3, 5, 7]) !== -1) { this.DefaultFontSize = iDefaultFontSize; } }; /** * @return {boolean} */ CUserSettingsModel.prototype.getSaveMailInSentItems = function () { var bSaveMailInSentItems = true; switch (this.SaveMail) { case Enums.SaveMail.Unchecked: bSaveMailInSentItems = false; break; case Enums.SaveMail.Checked: case Enums.SaveMail.Hidden: bSaveMailInSentItems = true; break; } return bSaveMailInSentItems; }; /** * @return {boolean} */ CUserSettingsModel.prototype.getUseSaveMailInSentItems = function () { var bUseSaveMailInSentItems = false; switch (this.SaveMail) { case Enums.SaveMail.Unchecked: case Enums.SaveMail.Checked: bUseSaveMailInSentItems = true; break; case Enums.SaveMail.Hidden: bUseSaveMailInSentItems = false; break; } return bUseSaveMailInSentItems; }; /** * @param {AjaxUserSettingsResponse} oData */ CUserSettingsModel.prototype.parse = function (oData) { var oCalendar = null; if (oData !== null) { this.IdUser = Utils.pInt(oData.IdUser); this.MailsPerPage = Utils.pInt(oData.MailsPerPage); this.ContactsPerPage = Utils.pInt(oData.ContactsPerPage); this.AutoCheckMailInterval = Utils.pInt(oData.AutoCheckMailInterval); this.DefaultTheme = Utils.pString(oData.DefaultTheme); this.DefaultLanguage = Utils.pString(oData.DefaultLanguage); this.DefaultLanguageShort = Utils.pString(oData.DefaultLanguageShort); this.DefaultDateFormat = Utils.pString(oData.DefaultDateFormat); this.defaultTimeFormat(Utils.pString(oData.DefaultTimeFormat)); this.ThreadsEnabled = !!oData.ThreadsEnabled; this.useThreads(!!oData.UseThreads); this.SaveRepliedToCurrFolder = !!oData.SaveRepliedMessagesToCurrentFolder; this.DesktopNotifications = !!oData.DesktopNotifications; this.AllowChangeInputDirection = !!oData.AllowChangeInputDirection; this.AllowCompose = !!oData.AllowCompose; this.AllowReply = !!oData.AllowReply; this.AllowForward = !!oData.AllowForward; this.SaveMail = Utils.pInt(oData.SaveMail); this.AllowFetcher = !!oData.AllowFetcher; this.OutlookSyncEnable = !!oData.OutlookSyncEnable; this.MobileSyncEnable = !!oData.MobileSyncEnable; this.ShowPersonalContacts = !!oData.ShowPersonalContacts; this.ShowGlobalContacts = !!oData.ShowGlobalContacts; this.ShowContacts = this.ShowPersonalContacts || this.ShowGlobalContacts; this.IsFilesSupported = !!oData.IsFilesSupported && !bMobileApp; this.IsFilesSupported = !!oData.IsFilesSupported && !bMobileApp; this.filesEnable(!!oData.FilesEnable && !bMobileApp); this.IsHelpdeskSupported = !!oData.IsHelpdeskSupported && !bMobileApp; this.IsHelpdeskAgent = !!oData.IsHelpdeskAgent; this.LastLogin = Utils.pInt(oData.LastLogin); this.AllowCalendar = !!oData.AllowCalendar && !bMobileApp; this.CalendarSharing = !!oData.CalendarSharing; this.CalendarAppointments = !!oData.CalendarAppointments; this.IsDemo = !!oData.IsDemo; this.AllowVoice = !!oData.AllowVoice; this.SipRealm = oData.SipRealm; this.SipWebsocketProxyUrl = oData.SipWebsocketProxyUrl; this.SipOutboundProxyUrl = oData.SipOutboundProxyUrl; this.SipCallerID = oData.SipCallerID; this.SipImpi = oData.SipImpi; this.SipImpu = oData.SipImpu; this.SipPassword = oData.SipPassword; this.VoiceProvider = oData.VoiceProvider; // this.VoiceAccountSID = oData.VoiceRealm; // this.VoiceAuthToken = oData.VoiceAuthToken; // this.VoiceAppSID = oData.VoiceAppSID; this.AllowHelpdeskNotifications = oData.AllowHelpdeskNotifications; this.IsCollaborationSupported = !!oData.IsCollaborationSupported; this.AllowFilesSharing = !!oData.AllowFilesSharing; this.enableOpenPgp(!!oData.EnableOpenPgp); this.AllowAutosaveInDrafts = !!oData.AllowAutosaveInDrafts && (AppData.App ? AppData.App.AutoSave : false); // this.AutosignOutgoingEmails = !!oData.AutosignOutgoingEmails; oCalendar = oData.Calendar; if (oCalendar) { this.CalendarShowWeekEnds = !!oCalendar.ShowWeekEnds; this.CalendarShowWorkDay = !!oCalendar.ShowWorkDay; this.CalendarWorkDayStarts = Utils.pInt(oCalendar.WorkDayStarts); this.CalendarWorkDayEnds = Utils.pInt(oCalendar.WorkDayEnds); this.CalendarWeekStartsOn = Utils.pInt(oCalendar.WeekStartsOn); this.CalendarDefaultTab = Utils.pInt(oCalendar.DefaultTab); } this.SocialAccounts(oData.SocialAccounts); } }; /** * @param {number} iMailsPerPage * @param {number} iContactsPerPage * @param {number} iAutoCheckMailInterval * @param {string} sDefaultTheme * @param {string} sDefaultLanguage * @param {string} sDefaultDateFormat * @param {string} sDefaultTimeFormat * @param {string} sUseThreads * @param {string} sSaveRepliedToCurrFolder * @param {string} sDesktopNotifications * @param {string} sAllowChangeInputDirection */ CUserSettingsModel.prototype.updateCommonSettings = function (iMailsPerPage, iContactsPerPage, iAutoCheckMailInterval, sDefaultTheme, sDefaultLanguage, sDefaultDateFormat, sDefaultTimeFormat, sUseThreads, sSaveRepliedToCurrFolder, sDesktopNotifications, sAllowChangeInputDirection) { var bNeedToUpdateMessageDates = this.defaultTimeFormat() !== sDefaultTimeFormat; this.MailsPerPage = iMailsPerPage; this.ContactsPerPage = iContactsPerPage; this.AutoCheckMailInterval = iAutoCheckMailInterval; App.MailCache.setAutocheckmailTimer(); this.DefaultTheme = sDefaultTheme; this.DefaultLanguage = sDefaultLanguage; this.DefaultDateFormat = sDefaultDateFormat; this.defaultTimeFormat(sDefaultTimeFormat); this.useThreads('1' === sUseThreads); this.SaveRepliedToCurrFolder = '1' === sSaveRepliedToCurrFolder; this.AllowChangeInputDirection = '1' === sAllowChangeInputDirection; this.DesktopNotifications = '1' === sDesktopNotifications; if (bNeedToUpdateMessageDates) { App.nowMoment.valueHasMutated(); } }; /** * @param {string} sEnableOpenPgp * @param {string} sAllowAutosaveInDrafts * @param {string} sAutosignOutgoingEmails */ CUserSettingsModel.prototype.updateOpenPgpSettings = function (sEnableOpenPgp, sAllowAutosaveInDrafts, sAutosignOutgoingEmails) { this.enableOpenPgp('1' === sEnableOpenPgp); this.AllowAutosaveInDrafts = '1' === sAllowAutosaveInDrafts; // this.AutosignOutgoingEmails = '1' === sAutosignOutgoingEmails; }; /** * @param {boolean} bShowWeekEnds * @param {boolean} bShowWorkDay * @param {number} iWorkDayStarts * @param {number} iWorkDayEnds * @param {number} iWeekStartsOn * @param {number} iDefaultTab */ CUserSettingsModel.prototype.updateCalendarSettings = function (bShowWeekEnds, bShowWorkDay, iWorkDayStarts, iWorkDayEnds, iWeekStartsOn, iDefaultTab) { this.CalendarShowWeekEnds = bShowWeekEnds; this.CalendarShowWorkDay = bShowWorkDay; this.CalendarWorkDayStarts = iWorkDayStarts; this.CalendarWorkDayEnds = iWorkDayEnds; this.CalendarWeekStartsOn = iWeekStartsOn; this.CalendarDefaultTab = iDefaultTab; }; /** * @param {boolean} bAllowHelpdeskNotifications */ CUserSettingsModel.prototype.updateHelpdeskSettings = function (bAllowHelpdeskNotifications) { this.AllowHelpdeskNotifications = bAllowHelpdeskNotifications; }; /** * @param {Object} oResponse * @param {Object} oRequest */ CUserSettingsModel.prototype.onSyncSettingsResponse = function (oResponse, oRequest) { if (oResponse.Result) { this.mobileSync(oResponse.Result.Mobile); this.outlookSync(oResponse.Result.Outlook); } else { App.Api.showErrorByCode(oResponse); } }; CUserSettingsModel.prototype.requestSyncSettings = function () { if (this.mobileSync() === null || this.outlookSync() === null) { App.Ajax.send({'Action': 'SyncSettings'}, this.onSyncSettingsResponse, this); } }; /** * @constructor */ function CAccountModel() { this.id = ko.observable(0); this.email = ko.observable(''); this.extensions = ko.observableArray([]); this.fetchers = ko.observable(null); this.identities = ko.observable(null); this.friendlyName = ko.observable(''); this.incomingMailLogin = ko.observable(''); this.incomingMailPort = ko.observable(143); this.incomingMailServer = ko.observable(''); this.isInternal = ko.observable(false); this.isLinked = ko.observable(false); this.isDefault = ko.observable(false); this.outgoingMailAuth = ko.observable(0); this.outgoingMailLogin = ko.observable(''); this.outgoingMailPort = ko.observable(25); this.outgoingMailServer = ko.observable(''); this.isExtended = ko.observable(false); this.signature = ko.observable(null); this.autoresponder = ko.observable(null); this.forward = ko.observable(null); this.filters = ko.observable(null); this.quota = ko.observable(0); this.usedSpace = ko.observable(0); this.quotaRecieved = ko.observable(false); this.fullEmail = ko.computed(function () { if (this.friendlyName() === '') { return this.email(); } else { return this.friendlyName() + ' <' + this.email() + '>'; } }, this); this.isCurrent = ko.observable(false); this.isEdited = ko.observable(false); this.extensionsRequested = ko.observable(false); this.removeHint = ko.computed(function () { var sAndOther = '', sHint = '' ; if (this.isDefault()) { if (AppData.User.AllowCalendar && AppData.User.ShowContacts) { sAndOther = Utils.i18n('SETTINGS/ACCOUNTS_REMOVE_CONTACTS_CALENDARS_HINT'); } else if (AppData.User.AllowCalendar) { sAndOther = Utils.i18n('SETTINGS/ACCOUNTS_REMOVE_CALENDARS_HINT'); } else if (AppData.User.ShowContacts) { sAndOther = Utils.i18n('SETTINGS/ACCOUNTS_REMOVE_CONTACTS_HINT'); } sHint = Utils.i18n('SETTINGS/ACCOUNTS_REMOVE_DEFAULT_HINT', {'AND_OTHER': sAndOther}); if (AppData.Accounts.collection().length > 1) { sHint += Utils.i18n('SETTINGS/ACCOUNTS_REMOVE_DEFAULT_NOTSINGLE_HINT'); } } else { sHint = Utils.i18n('SETTINGS/ACCOUNTS_REMOVE_HINT'); } return sHint; }, this); this.removeConfirmation = ko.computed(function () { if (this.isDefault()) { return this.removeHint() + Utils.i18n('SETTINGS/ACCOUNTS_REMOVE_DEFAULT_CONFIRMATION'); } else { return Utils.i18n('SETTINGS/ACCOUNTS_REMOVE_CONFIRMATION'); } }, this); } /** * @param {number} iId * @param {string} sEmail * @param {string} sFriendlyName */ CAccountModel.prototype.init = function (iId, sEmail, sFriendlyName) { this.id(iId); this.email(sEmail); this.friendlyName(sFriendlyName); }; /** * @param {Object} oData * @param {Object} oParameters */ CAccountModel.prototype.onQuotaParamsResponse = function (oData, oParameters) { if (oData && oData.Result && _.isArray(oData.Result) && 1 < oData.Result.length) { this.quota(Utils.pInt(oData.Result[1])); this.usedSpace(Utils.pInt(oData.Result[0])); App.MailCache.quotaChangeTrigger(!App.MailCache.quotaChangeTrigger()); } this.quotaRecieved(true); }; CAccountModel.prototype.updateQuotaParams = function () { var oParams = { 'Action': 'Quota', 'AccountID': this.id() } ; if (AppData.App && AppData.App.ShowQuotaBar) { App.Ajax.send(oParams, this.onQuotaParamsResponse, this); } }; /** * @param {Object} oData * @param {number} iDefaultId */ CAccountModel.prototype.parse = function (oData, iDefaultId) { var oSignature = new CSignatureModel(); this.init(parseInt(oData.AccountID, 10), Utils.pString(oData.Email), Utils.pString(oData.FriendlyName)); oSignature.parse(this.id(), oData.Signature); this.signature(oSignature); this.isCurrent(iDefaultId === this.id()); this.isEdited(iDefaultId === this.id()); }; CAccountModel.prototype.requestExtensions = function () { if (!this.extensionsRequested() && App.Ajax) { var oTz = window.jstz ? window.jstz.determine() : null; App.Ajax.send({ 'AccountID': this.id(), 'Action': 'IsAuth', 'ClientTimeZone': oTz ? oTz.name() : '' }, this.onIsAuthResponse, this); } }; /** * @param {Object} oResult * @param {Object} oRequest */ CAccountModel.prototype.onIsAuthResponse = function (oResult, oRequest) { var bResult = !!oResult.Result, aExtensions = bResult ? oResult.Result.Extensions : [] ; if (bResult) { this.setExtensions(aExtensions); this.extensionsRequested(true); } }; /** * @param {Array} aExtensions */ CAccountModel.prototype.setExtensions = function(aExtensions) { if (_.isArray(aExtensions)) { this.extensions(aExtensions); } }; /** * @param {string} sExtension * * return {boolean} */ CAccountModel.prototype.extensionExists = function(sExtension) { return (_.indexOf(this.extensions(), sExtension) === -1) ? false : true; }; /** * @param {?} ExtendedData */ CAccountModel.prototype.updateExtended = function (ExtendedData) { if (ExtendedData) { this.isExtended(true); if (Utils.isNormal(ExtendedData.FriendlyName)) { this.friendlyName(ExtendedData.FriendlyName); } if (Utils.isNormal(ExtendedData.IncomingMailLogin)) { this.incomingMailLogin(ExtendedData.IncomingMailLogin); } if (Utils.isNormal(ExtendedData.IncomingMailPort)) { this.incomingMailPort(ExtendedData.IncomingMailPort); } if (Utils.isNormal(ExtendedData.IncomingMailServer)) { this.incomingMailServer(ExtendedData.IncomingMailServer); } if (Utils.isNormal(ExtendedData.IsInternal)) { this.isInternal(ExtendedData.IsInternal); } if (Utils.isNormal(ExtendedData.IsLinked)) { this.isLinked(ExtendedData.IsLinked); } if (Utils.isNormal(ExtendedData.IsDefault)) { this.isDefault(ExtendedData.IsDefault); } if (Utils.isNormal(ExtendedData.OutgoingMailAuth)) { this.outgoingMailAuth(ExtendedData.OutgoingMailAuth); } if (Utils.isNormal(ExtendedData.OutgoingMailLogin)) { this.outgoingMailLogin(ExtendedData.OutgoingMailLogin); } if (Utils.isNormal(ExtendedData.OutgoingMailPort)) { this.outgoingMailPort(ExtendedData.OutgoingMailPort); } if (Utils.isNormal(ExtendedData.OutgoingMailServer)) { this.outgoingMailServer(ExtendedData.OutgoingMailServer); } this.setExtensions(ExtendedData.Extensions); } }; CAccountModel.prototype.changeAccount = function() { AppData.Accounts.changeCurrentAccount(this.id()); }; /** * @param {string} sEmail * * return {?} */ CAccountModel.prototype.getFetcherOrIdentityByEmail = function(sEmail) { var aFetchers = this.fetchers() ? this.fetchers().collection() : [], oFetcherOrIdentity = null ; oFetcherOrIdentity = _.find(aFetchers, function (oFetcher) { return oFetcher.email() === sEmail; }); if (!oFetcherOrIdentity) { oFetcherOrIdentity = _.find(this.identities() || [], function (oIdentity) { return oIdentity.email() === sEmail; }); } return oFetcherOrIdentity; }; /** * @returns {Array} */ CAccountModel.prototype.getFetchersIdentitiesEmails = function() { var aFetchers = this.fetchers() ? this.fetchers().collection() : [], aIdentities = this.identities() || [], aEmails = [] ; _.each(aFetchers, function (oFetcher) { aEmails.push(oFetcher.email()); }); _.each(aIdentities, function (oIdentity) { aEmails.push(oIdentity.email()); }); return aEmails; }; /** * @constructor */ function CAccountListModel() { this.defaultId = ko.observable(0); this.currentId = ko.observable(0); this.editedId = ko.observable(0); this.currentId.subscribe(function(value) { var oCurrentAccount = this.getCurrent(); oCurrentAccount.requestExtensions(); // deferred execution to edited account has changed a bit later and did not make a second request // of the folder list of the same account. _.delay(_.bind(function () { this.editedId(value); }, this), 1000); }, this); this.collection = ko.observableArray([]); } /** * Changes current account. Sets hash to show new account data. * * @param {number} iNewCurrentId */ CAccountListModel.prototype.changeCurrentAccount = function (iNewCurrentId) { var oCurrentAccount = this.getCurrent(), oNewCurrentAccount = this.getAccount(iNewCurrentId) ; if (oNewCurrentAccount && this.currentId() !== iNewCurrentId) { oCurrentAccount.isCurrent(false); this.currentId(iNewCurrentId); oNewCurrentAccount.isCurrent(true); App.Routing.setHash(App.Links.inbox()); } }; /** * Changes editable account. * * @param {number} iNewEditedId */ CAccountListModel.prototype.changeEditedAccount = function (iNewEditedId) { var oEditedAccount = this.getEdited(), oNewEditedAccount = this.getAccount(iNewEditedId) ; if (oNewEditedAccount && this.editedId() !== iNewEditedId) { oEditedAccount.isEdited(false); this.editedId(iNewEditedId); oNewEditedAccount.isEdited(true); } }; /** * Fills the collection of accounts. Checks for default account. If it is not listed, * then assigns a credit default the first account from the list. * * @param {number} iDefaultId * @param {Array} aAccounts */ CAccountListModel.prototype.parse = function (iDefaultId, aAccounts) { var oAccount = null, bHasDefault = false, oDefaultAccount = null ; if (_.isArray(aAccounts)) { this.collection(_.map(aAccounts, function (oRawAccount) { var oAcct = new CAccountModel(); oAcct.parse(oRawAccount, iDefaultId); if (oAcct.id() === iDefaultId) { bHasDefault = true; } return oAcct; })); } if (!bHasDefault && this.collection.length > 0) { oAccount = this.collection()[0]; iDefaultId = oAccount.id(); bHasDefault = true; } if (bHasDefault) { this.defaultId(iDefaultId); this.currentId(iDefaultId); this.editedId(iDefaultId); } oDefaultAccount = this.getDefault(); if (oDefaultAccount) { _.defer(function () { oDefaultAccount.isDefault(true); }); } }; /** * @param {number} iId * * @return {Object|undefined} */ CAccountListModel.prototype.getAccount = function (iId) { var oAccount = _.find(this.collection(), function (oAcct) { return oAcct.id() === iId; }, this); /** @type {Object|undefined} */ return oAccount; }; /** * @return {Object|undefined} */ CAccountListModel.prototype.getCurrent = function () { var oAccount = _.find(this.collection(), function (oAcct) { return oAcct.id() === this.currentId(); }, this); /** @type {Object|undefined} */ return oAccount; }; /** * @return {Object|undefined} */ CAccountListModel.prototype.getDefault = function () { var oAccount = _.find(this.collection(), function (oAcct) { return oAcct.id() === this.defaultId(); }, this); /** @type {Object|undefined} */ return oAccount; }; /** * @return {string} */ CAccountListModel.prototype.getEmail = function () { var sEmail = '', oAccount = AppData.Accounts.getCurrent() ; if (oAccount) { sEmail = oAccount.email(); } return sEmail; }; /** * @return {Object|undefined} */ CAccountListModel.prototype.getEdited = function () { var oAccount = _.find(this.collection(), function (oAcct) { return oAcct.id() === this.editedId(); }, this); /** @type {Object|undefined} */ return oAccount; }; /** * @param {Object} oAccount */ CAccountListModel.prototype.addAccount = function (oAccount) { this.collection.push(oAccount); }; /** * @param {number} iId */ CAccountListModel.prototype.deleteAccount = function (iId) { if (this.currentId() === iId) { this.changeCurrentAccount(this.defaultId()); } if (this.editedId() === iId) { this.changeEditedAccount(this.defaultId()); } this.collection.remove(function (oAcct){return oAcct.id() === iId;}); }; /** * @param {number} iId * * @return {boolean} */ CAccountListModel.prototype.hasAccountWithId = function (iId) { var oAccount = _.find(this.collection(), function (oAcct) { return oAcct.id() === iId; }, this); return !!oAccount; }; CAccountListModel.prototype.populateFetchersIdentities = function () { this.populateFetchers(); this.populateIdentities(); }; CAccountListModel.prototype.populateFetchers = function () { if (AppData.User.AllowFetcher) { App.Ajax.send({ 'Action': 'FetcherList', 'AccountID': AppData.Accounts.defaultId() }, this.onFetcherListResponse, this); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CAccountListModel.prototype.onFetcherListResponse = function (oResponse, oRequest) { var oFetcherList = null, oDefaultAccount = this.getDefault() ; if (Utils.isNonEmptyArray(oResponse.Result)) { oFetcherList = new CFetcherListModel(); oFetcherList.parse(AppData.Accounts.defaultId(), oResponse.Result); } oDefaultAccount.fetchers(oFetcherList); }; CAccountListModel.prototype.populateIdentities = function () { if (AppData.AllowIdentities) { App.Ajax.send({'Action': 'GetIdentities'}, this.onIdentitiesResponse, this); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CAccountListModel.prototype.onIdentitiesResponse = function (oResponse, oRequest) { var oIdentities = {}; if (Utils.isNonEmptyArray(oResponse.Result)) { _.each(oResponse.Result, function (oIdentityData) { var oIdentity = new CIdentityModel(), iAccountId = -1 ; oIdentity.parse(oIdentityData); iAccountId = oIdentity.accountId(); if (!oIdentities[iAccountId]) { oIdentities[iAccountId] = []; } oIdentities[iAccountId].push(oIdentity); }); } _.each(this.collection(), function (oAccount) { var aIdentities = oIdentities[oAccount.id()]; if (!Utils.isNonEmptyArray(aIdentities)) { aIdentities = []; } oAccount.identities(aIdentities); }); }; CAccountListModel.prototype.populateIdentitiesFromSourceAccount = function (oSrcAccounts) { if (oSrcAccounts) { _.each(this.collection(), function (oAccount) { var oSrcAccount = oSrcAccounts.getAccount(oAccount.id()); if (oSrcAccount) { oAccount.fetchers(oSrcAccount.fetchers()); oAccount.identities(oSrcAccount.identities()); oAccount.signature(oSrcAccount.signature()); } }); } }; CAccountListModel.prototype.getAllFullEmails = function () { var aFullEmails = []; _.each(this.collection(), function (oAccount) { if (oAccount) { aFullEmails.push(oAccount.fullEmail()); if (oAccount.fetchers() && Utils.isNonEmptyArray(oAccount.fetchers().collection())) { _.each(oAccount.fetchers().collection(), function (oFetcher) { if (oFetcher.isOutgoingEnabled() && oFetcher.fullEmail() !== '') { aFullEmails.push(oFetcher.fullEmail()); } }); } if (Utils.isNonEmptyArray(oAccount.identities())) { _.each(oAccount.identities(), function (oIdentity) { aFullEmails.push(oIdentity.fullEmail()); }); } } }); return aFullEmails; }; CAccountListModel.prototype.getCurrentFetchersAndFiltersFolderNames = function () { var oAccount = this.getCurrent(), aFolders = [] ; if (oAccount) { if (oAccount.filters()) { _.each(oAccount.filters().collection(), function (oFilter) { aFolders.push(oFilter.folder()); }, this); } if (oAccount.fetchers()) { _.each(oAccount.fetchers().collection(), function (oFetcher) { aFolders.push(oFetcher.folder()); }, this); } } return aFolders; }; /** * @param {Array} aEmails * @returns {string} */ CAccountListModel.prototype.getAttendee = function (aEmails) { var aAccountsEmails = [], sAttendee = '' ; _.each(this.collection(), function (oAccount) { if (oAccount.isCurrent()) { aAccountsEmails = _.union(oAccount.email(), oAccount.getFetchersIdentitiesEmails(), aAccountsEmails); } else { aAccountsEmails = _.union(aAccountsEmails, oAccount.email(), oAccount.getFetchersIdentitiesEmails()); } }); aAccountsEmails = _.uniq(aAccountsEmails); _.each(aAccountsEmails, _.bind(function (sAccountEmail) { if (sAttendee === '') { var sFoundEmail = _.find(aEmails, function (sEmail) { return (sEmail === sAccountEmail); }); if (sFoundEmail === sAccountEmail) { sAttendee = sAccountEmail; } } }, this)); return sAttendee; }; /** * @constructor */ function CAddressModel() { this.sName = ''; /** @type {string} */ this.sEmail = ''; this.sDisplay = ''; this.sFull = ''; this.loaded = ko.observable(false); this.founded = ko.observable(false); } /** * @param {Object} oData */ CAddressModel.prototype.parse = function (oData) { if (oData !== null) { this.sName = Utils.pString(oData.DisplayName); if (typeof this.sName !== 'string') { this.sName = ''; } this.sEmail = Utils.pString(oData.Email); if (typeof this.sEmail !== 'string') { this.sEmail = ''; } this.sDisplay = (this.sName.length > 0) ? this.sName : this.sEmail; this.setFull(); } }; /** * @return {string} */ CAddressModel.prototype.getEmail = function () { return this.sEmail; }; /** * @return {string} */ CAddressModel.prototype.getName = function () { return this.sName; }; /** * @return {string} */ CAddressModel.prototype.getDisplay = function () { return this.sDisplay; }; CAddressModel.prototype.setFull = function () { var sFull = ''; if (this.sEmail.length > 0) { if (this.sName.length > 0) { //sFull = '"' + this.sName + '" <' + this.sEmail + '>'; sFull = this.sName + ' <' + this.sEmail + '>'; } else { sFull = this.sEmail; } } else { sFull = this.sName; } this.sFull = sFull; }; /** * @return {string} */ CAddressModel.prototype.getFull = function () { return this.sFull; }; CAddressModel.prototype.oPopup = null; CAddressModel.prototype.oTitle = null; CAddressModel.prototype.bPopupOpened = false; CAddressModel.prototype.iCloseTimeoutId = 0; CAddressModel.prototype.mouseoverEvent = function (oAddress, oEvent) { if (!this.oPopup || this.oPopup.length === 0) { this.oPopup = $('div.item_viewer[data-email=\'' + this.sEmail + '\']'); if (this.oPopup.length > 0) { this.oPopup .on('mouseenter', _.bind(this.openPopup, this)) .on('mouseleave', _.bind(this.mouseoutEvent, this)); } } this.oTitle = $(oEvent.currentTarget); if (this.oPopup.length > 0) { this.openPopup(oEvent); } }; CAddressModel.prototype.openPopup = function (oEvent) { this.bPopupOpened = true; clearTimeout(this.iCloseTimeoutId); setTimeout(_.bind(function () { var oOffset = this.oTitle.offset(), iLeft, iTop, iFitToScreenOffset; if (this.bPopupOpened && oOffset.left + oOffset.top !== 0) { iLeft = oOffset.left + 10; iTop = oOffset.top + this.oTitle.height() + 6; iFitToScreenOffset = $(window).width() - (iLeft + 396); //396 - popup outer width if (iFitToScreenOffset > 0) { iFitToScreenOffset = 0; } this.oPopup.addClass('expand').css('top', iTop + 'px').css('left', iLeft + iFitToScreenOffset + 'px').appendTo('body'); /*setTimeout(_.bind(function () { console.log(this.oPopup); console.log($(this.oPopup).width()); }, this), 10);*/ } }, this), 180); }; CAddressModel.prototype.mouseoutEvent = function () { if (this.bPopupOpened && this.oPopup && this.oTitle) { this.bPopupOpened = false; this.iCloseTimeoutId = setTimeout(_.bind(function () { if (!this.bPopupOpened) { this.oPopup.removeClass('expand'); } }, this), 200); } }; /** * @constructor */ function CAddressListModel() { this.aCollection = []; } /** * @param {Array} aData */ CAddressListModel.prototype.parse = function (aData) { this.aCollection = _.map(aData, function (oItem) { var oAddress = new CAddressModel(); oAddress.parse(oItem); return oAddress; }); }; /** * @param {Array} aCollection */ CAddressListModel.prototype.addCollection = function (aCollection) { _.each(aCollection, function (oAddress) { var oFoundAddress = _.find(this.aCollection, function (oThisAddress) { return oAddress.sEmail === oThisAddress.sEmail; }); if (!oFoundAddress) { this.aCollection.push(oAddress); } }, this); }; /** * @param {Array} aCollection */ CAddressListModel.prototype.excludeCollection = function (aCollection) { _.each(aCollection, function (oAddress) { this.aCollection = _.filter(this.aCollection, function (oThisAddress) { return oAddress.sEmail !== oThisAddress.sEmail; }); }, this); }; /** * @return {string} */ CAddressListModel.prototype.getFirstEmail = function () { if (this.aCollection.length > 0) { return this.aCollection[0].getEmail(); } return ''; }; /** * @return {string} */ CAddressListModel.prototype.getFirstName = function () { if (this.aCollection.length > 0) { return this.aCollection[0].getName(); } return ''; }; /** * @return {string} */ CAddressListModel.prototype.getFirstDisplay = function () { if (this.aCollection.length > 0) { return this.aCollection[0].getDisplay(); } return ''; }; /** * @param {string=} sMeReplacement * @param {string=} sMyAccountEmail * * @return {string} */ CAddressListModel.prototype.getDisplay = function (sMeReplacement, sMyAccountEmail) { var aAddresses = _.map(this.aCollection, function (oAddress) { if (sMeReplacement && sMyAccountEmail === oAddress.sEmail) { return sMeReplacement; } return oAddress.getDisplay(sMeReplacement); }); return aAddresses.join(', '); }; /** * @return {string} */ CAddressListModel.prototype.getFull = function () { var aAddresses = _.map(this.aCollection, function (oAddress) { return oAddress.getFull(); }); return aAddresses.join(', '); }; /** * @return {Array} */ CAddressListModel.prototype.getEmails = function () { var aEmails = _.map(this.aCollection, function (oAddress) { return oAddress.getEmail(); }); return aEmails; }; /** * @constructor */ function CDateModel() { this.iTimeStampInUTC = 0; this.oMoment = null; } /** * @param {number} iTimeStampInUTC */ CDateModel.prototype.parse = function (iTimeStampInUTC) { this.iTimeStampInUTC = iTimeStampInUTC; this.oMoment = moment.unix(this.iTimeStampInUTC); }; /** * @param {number} iYear * @param {number} iMonth * @param {number} iDay */ CDateModel.prototype.setDate = function (iYear, iMonth, iDay) { this.oMoment = moment([iYear, iMonth, iDay]); }; /** * @return {string} */ CDateModel.prototype.getTimeFormat = function () { return (AppData.User.defaultTimeFormat() === Enums.TimeFormat.F24) ? 'HH:mm' : 'hh:mm A'; }; /** * @return {string} */ CDateModel.prototype.getFullDate = function () { return (this.oMoment) ? this.oMoment.format('ddd, MMM D, YYYY, ' + this.getTimeFormat()) : ''; }; /** * @return {string} */ CDateModel.prototype.getMidDate = function () { return this.getShortDate(true); }; /** * @param {boolean=} bTime = false * * @return {string} */ CDateModel.prototype.getShortDate = function (bTime) { var sResult = '', oMomentNow = null ; if (this.oMoment) { oMomentNow = moment(); if (oMomentNow.format('L') === this.oMoment.format('L')) { sResult = this.oMoment.format(this.getTimeFormat()); } else { if (oMomentNow.clone().subtract('days', 1).format('L') === this.oMoment.format('L')) { sResult = Utils.i18n('DATETIME/YESTERDAY'); } else if (oMomentNow.year() === this.oMoment.year()) { sResult = this.oMoment.format('MMM D'); } else { sResult = this.oMoment.format('MMM D, YYYY'); } if (Utils.isUnd(bTime) ? false : !!bTime) { sResult += ', ' + this.oMoment.format(this.getTimeFormat()); } } } return sResult; }; /** * @return {string} */ CDateModel.prototype.getDate = function () { return (this.oMoment) ? this.oMoment.format('ddd, MMM D, YYYY') : ''; }; /** * @return {string} */ CDateModel.prototype.getTime = function () { return (this.oMoment) ? this.oMoment.format(this.getTimeFormat()): ''; }; /** * @param {string} iDate * * @return {string} */ CDateModel.prototype.convertDate = function (iDate) { var sFormat = Utils.getDateFormatForMoment(AppData.User.DefaultDateFormat) + ' ' + this.getTimeFormat(); return moment(iDate * 1000).format(sFormat); }; /** * @return {number} */ CDateModel.prototype.getTimeStampInUTC = function () { return this.iTimeStampInUTC; }; /** * @constructor */ function CIdentityModel() { this.enabled = ko.observable(true); this.email = ko.observable(''); this.friendlyName = ko.observable(''); this.fullEmail = ko.computed(function () { if (this.friendlyName() !== '') { return this.friendlyName() + ' <' + this.email() + '>'; } else { return this.email(); } }, this); this.accountId = ko.observable(-1); this.id = ko.observable(-1); this.signature = ko.observable(''); this.useSignature = ko.observable(false); } /** * @param {Object} oData */ CIdentityModel.prototype.parse = function (oData) { if (oData['@Object'] === 'Object/CIdentity') { this.enabled(!!oData.Enabled); this.email(Utils.pString(oData.Email)); this.friendlyName(Utils.pString(oData.FriendlyName)); this.accountId(Utils.pInt(oData.IdAccount)); this.id(Utils.pInt(oData.IdIdentity)); this.signature(Utils.pString(oData.Signature)); this.useSignature(!!oData.UseSignature); } }; /** * @constructor */ function CCommonFileModel() { this.isIosDevice = bIsIosDevice; this.isFolder = ko.observable(false); this.isLink = ko.observable(false); this.linkType = ko.observable(Enums.FileStorageLinkType.Unknown); this.linkUrl = ko.observable(''); this.isPopupItem = ko.observable(false); this.id = ko.observable(''); this.fileName = ko.observable(''); this.tempName = ko.observable(''); this.displayName = ko.observable(''); this.extension = ko.observable(''); this.fileName.subscribe(function () { var sName = this.fileName(), iDotPos = sName.lastIndexOf('.') ; this.id(sName); if (!this.isFolder()) { this.displayName(sName.substr(0, iDotPos)); this.extension(sName.substr(iDotPos + 1)); } else { this.displayName(sName); this.extension(''); } }, this); this.size = ko.observable(0); this.friendlySize = ko.computed(function () { return Utils.friendlySize(this.size()); }, this); this.content = ko.observable(''); this.accountId = ko.observable((AppData.Accounts) ? AppData.Accounts.defaultId() : null); this.hash = ko.observable(''); this.thumb = ko.observable(false); this.iframedView = ko.observable(false); this.downloadLink = ko.computed(function () { return Utils.getDownloadLinkByHash(this.accountId(), this.hash()); }, this); this.viewLink = ko.computed(function () { var sUrl = Utils.getViewLinkByHash(this.accountId(), this.hash()); return this.iframedView() ? Utils.getIframeWrappwer(this.accountId(), sUrl) : sUrl; }, this); this.thumbnailSrc = ko.observable(''); this.thumbnailLoaded = ko.observable(false); this.thumbnailSessionUid = ko.observable(''); this.thumbnailLink = ko.computed(function () { return this.thumb() ? Utils.getViewThumbnailLinkByHash(this.accountId(), this.hash()) : ''; }, this); this.type = ko.observable(''); this.uploadUid = ko.observable(''); this.uploaded = ko.observable(false); this.uploadError = ko.observable(false); this.visibleImportLink = ko.computed(function () { return AppData.User.enableOpenPgp() && this.extension().toLowerCase() === 'asc' && this.content() !== '' && !this.isPopupItem(); }, this); this.isViewMimeType = ko.computed(function () { return (-1 !== $.inArray(this.type(), aViewMimeTypes)) || this.iframedView(); }, this); this.isMessageType = ko.observable(false); this.visibleViewLink = ko.computed(function () { return this.isVisibleViewLink() && !this.isPopupItem(); }, this); this.visibleDownloadLink = ko.computed(function () { return !this.isPopupItem(); }, this); this.subFiles = ko.observableArray([]); this.allowExpandSubFiles = ko.observable(false); this.subFilesLoaded = ko.observable(false); this.subFilesCollapsed = ko.observable(false); this.subFilesStartedLoading = ko.observable(false); this.visibleExpandLink = ko.computed(function () { return this.allowExpandSubFiles() && !this.subFilesCollapsed() && !this.subFilesStartedLoading(); }, this); this.visibleExpandingText = ko.computed(function () { return this.allowExpandSubFiles() && !this.subFilesCollapsed() && this.subFilesStartedLoading(); }, this); this.visibleSpinner = ko.observable(false); this.statusText = ko.observable(''); this.progressPercent = ko.observable(0); this.visibleProgress = ko.observable(false); this.uploadStarted = ko.observable(false); this.uploadStarted.subscribe(function () { if (this.uploadStarted()) { this.uploaded(false); this.visibleProgress(true); this.progressPercent(20); } else { this.progressPercent(100); this.visibleProgress(false); this.uploaded(true); } }, this); this.allowDrag = ko.observable(false); this.allowSelect = ko.observable(false); this.allowCheck = ko.observable(false); this.allowDelete = ko.observable(false); this.allowUpload = ko.observable(false); this.allowSharing = ko.observable(false); this.allowHeader = ko.observable(false); this.allowDownload = ko.observable(true); this.downloadTitle = ko.computed(function () { if (this.allowDownload()) { return Utils.i18n('MESSAGE/ATTACHMENT_CLICK_TO_DOWNLOAD', { 'FILENAME': this.fileName(), 'SIZE': this.friendlySize() }); } return ''; }, this); } /** * Can be overridden. */ CCommonFileModel.prototype.dataObjectName = ''; /** * Can be overridden. * * @returns {boolean} */ CCommonFileModel.prototype.isVisibleViewLink = function () { return this.uploaded() && !this.uploadError() && this.isViewMimeType(); }; /** * Parses attachment data from server. * * @param {AjaxAttachmenResponse} oData * @param {number} iAccountId */ CCommonFileModel.prototype.parse = function (oData, iAccountId) { if (oData['@Object'] === this.dataObjectName) { this.fileName(Utils.pString(oData.FileName)); this.tempName(Utils.pString(oData.TempName)); if (this.tempName() === '') { this.tempName(this.fileName()); } this.type(Utils.pString(oData.MimeType)); this.size(oData.EstimatedSize ? parseInt(oData.EstimatedSize, 10) : parseInt(oData.SizeInBytes, 10)); this.content(Utils.pString(oData.Content)); this.thumb(!!oData.Thumb); this.hash(Utils.pString(oData.Hash)); this.accountId(iAccountId); this.allowExpandSubFiles(!!oData.Expand); this.iframedView(!!oData.Iframed); this.uploadUid(this.hash()); this.uploaded(true); if (Utils.isFunc(this.additionalParse)) { this.additionalParse(oData); } } }; CCommonFileModel.prototype.getInThumbQueue = function (sThumbSessionUid) { this.thumbnailSessionUid(sThumbSessionUid); if(this.thumb() && (!this.linked || this.linked && !this.linked())) { Utils.thumbQueue(this.thumbnailSessionUid(), this.thumbnailLink(), this.thumbnailSrc); } }; /** * @param {Object=} oApp * * Starts downloading attachment on click. */ CCommonFileModel.prototype.downloadFile = function (oApp) { if (this.allowDownload()) { if (!oApp || !oApp.Api || !oApp.Api.downloadByUrl) { oApp = App; } if (oApp && this.downloadLink().length > 0 && this.downloadLink() !== '#') { oApp.Api.downloadByUrl(this.downloadLink()); } } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CCommonFileModel.prototype.onExpandAttachmentResponse = function (oResponse, oRequest) { this.subFiles([]); if (Utils.isNonEmptyArray(oResponse.Result)) { _.each(oResponse.Result, _.bind(function (oRawFile) { var oFile = this.getInstance(); oRawFile['@Object'] = this.dataObjectName; oFile.parse(oRawFile, this.accountId()); this.subFiles.push(oFile); }, this)); this.subFilesLoaded(true); this.subFilesCollapsed(true); } this.subFilesStartedLoading(false); }; /** * Starts expanding attachment on click. */ CCommonFileModel.prototype.expandFile = function () { if (!this.subFilesLoaded()) { this.subFilesStartedLoading(true); App.Ajax.send({ 'Action': 'ExpandAttachment', 'RawKey': this.hash() }, this.onExpandAttachmentResponse, this); } else { this.subFilesCollapsed(true); } }; /** * Collapse attachment on click. */ CCommonFileModel.prototype.collapseFile = function () { this.subFilesCollapsed(false); }; /** * @returns {CCommonFileModel} */ CCommonFileModel.prototype.getInstance = function () { return new CCommonFileModel(); }; /** * Starts importing attachment on click. */ CCommonFileModel.prototype.importFile = function () { var sContent = this.content(), fPgpCallback = _.bind(function (oPgp) { if (oPgp) { App.Screens.showPopup(CImportOpenPgpKeyPopup, [oPgp, sContent]); } }, this) ; App.Api.pgp(fPgpCallback, AppData.User.IdUser); }; /** * Can be overridden. * * Starts viewing attachment on click. */ CCommonFileModel.prototype.viewFile = function () { this.viewCommonFile(); }; /** * Starts viewing attachment on click. */ CCommonFileModel.prototype.viewCommonFile = function () { var oWin = null, sUrl = Utils.getAppPath() + this.viewLink() ; if (this.visibleViewLink() && this.viewLink().length > 0 && this.viewLink() !== '#') { if (this.isLink()/* && this.linkType() === Enums.FileStorageLinkType.GoogleDrive*/) { sUrl = this.linkUrl(); } if (this.iframedView()) { oWin = Utils.WindowOpener.openTab(sUrl); } else { oWin = Utils.WindowOpener.open(sUrl, sUrl, false); } if (oWin) { oWin.focus(); } } }; /** * @param {Object} oAttachment * @param {*} oEvent * @return {boolean} */ CCommonFileModel.prototype.eventDragStart = function (oAttachment, oEvent) { var oLocalEvent = oEvent.originalEvent || oEvent; if (oAttachment && oLocalEvent && oLocalEvent.dataTransfer && oLocalEvent.dataTransfer.setData) { oLocalEvent.dataTransfer.setData('DownloadURL', this.generateTransferDownloadUrl()); } return true; }; /** * @return {string} */ CCommonFileModel.prototype.generateTransferDownloadUrl = function () { var sLink = this.downloadLink(); if ('http' !== sLink.substr(0, 4)) { sLink = window.location.protocol + '//' + window.location.host + window.location.pathname + sLink; } return this.type() + ':' + this.fileName() + ':' + sLink; }; /** * Fills attachment data for upload. * * @param {string} sFileUid * @param {Object} oFileData */ CCommonFileModel.prototype.onUploadSelect = function (sFileUid, oFileData) { this.fileName(oFileData['FileName']); this.type(oFileData['Type']); this.size(Utils.pInt(oFileData['Size'])); this.uploadUid(sFileUid); this.uploaded(false); this.visibleSpinner(false); this.statusText(''); this.progressPercent(0); this.visibleProgress(false); }; /** * Starts spinner and progress. */ CCommonFileModel.prototype.onUploadStart = function () { this.visibleSpinner(true); this.visibleProgress(true); }; /** * Fills progress upload data. * * @param {number} iUploadedSize * @param {number} iTotalSize */ CCommonFileModel.prototype.onUploadProgress = function (iUploadedSize, iTotalSize) { if (iTotalSize > 0) { this.progressPercent(Math.ceil(iUploadedSize / iTotalSize * 100)); this.visibleProgress(true); } }; /** * Fills data when upload has completed. * * @param {string} sFileUid * @param {boolean} bResponseReceived * @param {Object} oResult */ CCommonFileModel.prototype.onUploadComplete = function (sFileUid, bResponseReceived, oResult) { var bError = !bResponseReceived || !oResult || oResult.Error || false, sError = (oResult && oResult.Error === 'size') ? Utils.i18n('COMPOSE/UPLOAD_ERROR_SIZE') : Utils.i18n('COMPOSE/UPLOAD_ERROR_UNKNOWN') ; this.visibleSpinner(false); this.progressPercent(0); this.visibleProgress(false); this.uploaded(true); this.uploadError(bError); this.statusText(bError ? sError : Utils.i18n('COMPOSE/UPLOAD_COMPLETE')); if (!bError) { this.fillDataAfterUploadComplete(oResult, sFileUid); setTimeout((function (self) { return function () { self.statusText(''); }; })(this), 3000); } }; /** * Should be overriden. * * @param {Object} oResult * @param {string} sFileUid */ CCommonFileModel.prototype.fillDataAfterUploadComplete = function (oResult, sFileUid) { }; /** * @param {Object} oAttachmentModel * @param {Object} oEvent */ CCommonFileModel.prototype.onImageLoad = function (oAttachmentModel, oEvent) { if(this.thumb() && !this.thumbnailLoaded()) { this.thumbnailLoaded(true); Utils.thumbQueue(this.thumbnailSessionUid()); } }; /** * @constructor * @extends CCommonFileModel */ function CMailAttachmentModel() { this.folderName = ko.observable(''); this.messageUid = ko.observable(''); this.cid = ko.observable(''); this.contentLocation = ko.observable(''); this.inline = ko.observable(false); this.linked = ko.observable(false); this.mimePartIndex = ko.observable(''); this.messagePart = ko.observable(null); CCommonFileModel.call(this); this.isMessageType = ko.computed(function () { this.type(); this.mimePartIndex(); return (this.type() === 'message/rfc822' && this.mimePartIndex() !== ''); }, this); } Utils.extend(CMailAttachmentModel, CCommonFileModel); CMailAttachmentModel.prototype.dataObjectName = 'Object/CApiMailAttachment'; /** * @returns {CMailAttachmentModel} */ CMailAttachmentModel.prototype.getInstance = function () { return new CMailAttachmentModel(); }; CMailAttachmentModel.prototype.getCopy = function () { var oCopy = new CMailAttachmentModel(); oCopy.copyProperties(this); return oCopy; }; CMailAttachmentModel.prototype.copyProperties = function (oSource) { this.fileName(oSource.fileName()); this.tempName(oSource.tempName()); this.size(oSource.size()); this.accountId(oSource.accountId()); this.hash(oSource.hash()); this.type(oSource.type()); this.cid(oSource.cid()); this.contentLocation(oSource.contentLocation()); this.inline(oSource.inline()); this.linked(oSource.linked()); this.thumb(oSource.thumb()); this.thumbnailSrc(oSource.thumbnailSrc()); this.thumbnailLoaded(oSource.thumbnailLoaded()); this.statusText(oSource.statusText()); this.uploaded(oSource.uploaded()); this.iframedView(oSource.iframedView()); }; CMailAttachmentModel.prototype.isVisibleViewLink = function () { return this.uploaded() && !this.uploadError() && (this.isViewMimeType() || this.isMessageType()); }; /** * Parses attachment data from server. * * @param {AjaxAttachmenResponse} oData */ CMailAttachmentModel.prototype.additionalParse = function (oData) { this.mimePartIndex(Utils.pString(oData.MimePartIndex)); this.cid(Utils.pString(oData.CID)); this.contentLocation(Utils.pString(oData.ContentLocation)); this.inline(!!oData.IsInline); this.linked(!!oData.IsLinked); }; /** * @param {string} sFolderName * @param {string} sMessageUid */ CMailAttachmentModel.prototype.setMessageData = function (sFolderName, sMessageUid) { this.folderName(sFolderName); this.messageUid(sMessageUid); }; /** * @param {AjaxDefaultResponse} oData * @param {Object=} oParameters */ CMailAttachmentModel.prototype.onMessageResponse = function (oData, oParameters) { var oResult = oData.Result, oMessage = new CMessageModel() ; if (oResult && this.oNewWindow) { oMessage.parse(oResult, oData.AccountID, false, true); this.messagePart(oMessage); this.messagePart().viewMessage(this.oNewWindow); this.oNewWindow = undefined; } }; /** * Starts viewing attachment on click. */ CMailAttachmentModel.prototype.viewFile = function () { if (this.isMessageType()) { this.viewMessageFile(); } else { this.viewCommonFile(); } }; /** * Starts viewing attachment on click. */ CMailAttachmentModel.prototype.viewMessageFile = function () { var oWin = null, sLoadingText = '<div style="margin: 30px; text-align: center; font: normal 14px Tahoma;">' + Utils.i18n('MAIN/LOADING') + '</div>' ; oWin = Utils.WindowOpener.open('', this.fileName()); if (oWin) { if (this.messagePart()) { this.messagePart().viewMessage(oWin); } else { $(oWin.document.body).html(sLoadingText); this.oNewWindow = oWin; App.Ajax.send({ 'Action': 'Message', 'Folder': this.folderName(), 'Uid': this.messageUid(), 'Rfc822MimeIndex': this.mimePartIndex() }, this.onMessageResponse, this); } oWin.focus(); } }; /** * Starts viewing attachment on click. */ CMailAttachmentModel.prototype.viewCommonFile = function () { var oWin = null, sUrl = Utils.getAppPath() + this.viewLink() ; if (this.visibleViewLink() && this.viewLink().length > 0 && this.viewLink() !== '#') { sUrl = Utils.getAppPath() + this.viewLink(); if (this.iframedView()) { oWin = Utils.WindowOpener.openTab(sUrl); } else { oWin = Utils.WindowOpener.open(sUrl, sUrl, false); } if (oWin) { oWin.focus(); } } }; /** * @param {Object} oResult * @param {string} sFileUid */ CMailAttachmentModel.prototype.fillDataAfterUploadComplete = function (oResult, sFileUid) { this.cid(sFileUid); this.tempName(oResult.Result.Attachment.TempName); this.type(oResult.Result.Attachment.MimeType); this.size(oResult.Result.Attachment.Size); this.hash(oResult.Result.Attachment.Hash); this.iframedView(oResult.Result.Attachment.Iframed); this.accountId(oResult.AccountID); }; /** * Parses contact attachment data from server. * * @param {AjaxFileDataResponse} oData * @param {number} iAccountId */ CMailAttachmentModel.prototype.parseFromUpload = function (oData, iAccountId) { this.fileName(oData.Name.toString()); this.tempName(oData.TempName ? oData.TempName.toString() : this.fileName()); this.type(oData.MimeType.toString()); this.size(parseInt(oData.Size, 10)); this.hash(oData.Hash); this.accountId(iAccountId); this.uploadUid(this.hash()); this.uploaded(true); this.uploadStarted(false); }; CMailAttachmentModel.prototype.errorFromUpload = function () { this.uploaded(true); this.uploadError(true); this.uploadStarted(false); this.statusText(Utils.i18n('COMPOSE/UPLOAD_ERROR_UNKNOWN')); }; /** * @constructor */ function CFolderModel() { this.iAccountId = 0; this.account = ko.computed(function () { return AppData.Accounts.getAccount(this.iAccountId); }, this); this.parentFullName = ko.observable(''); this.level = ko.observable(0); this.name = ko.observable(''); this.nameForEdit = ko.observable(''); this.fullName = ko.observable(''); this.fullNameHash = ko.observable(''); this.uidNext = ko.observable(''); this.hash = ko.observable(''); this.routingHash = ko.observable(''); this.delimiter = ko.observable(''); this.type = ko.observable(Enums.FolderTypes.User); this.showUnseenMessages = ko.computed(function () { return (this.type() !== Enums.FolderTypes.Drafts); }, this); this.withoutThreads = ko.computed(function () { return (this.type() === Enums.FolderTypes.Drafts || this.type() === Enums.FolderTypes.Spam || this.type() === Enums.FolderTypes.Trash); }, this); this.messageCount = ko.observable(0); this.unseenMessageCount = ko.observable(0); this.unseenMessageCount.subscribe(function (iCount) { _.delay(_.bind(function(){ App.MailCache.countMessages(this); },this), 1000); }, this); this.realUnseenMessageCount = ko.observable(0); this.enableEmptyFolder = ko.computed(function () { return (this.messageCount() > 0 && (this.type() === Enums.FolderTypes.Spam || this.type() === Enums.FolderTypes.Trash)); }, this); this.virtual = ko.observable(false); this.virtualEmpty = ko.computed(function () { return this.virtual() && this.messageCount() === 0; }, this); this.hasExtendedInfo = ko.observable(false); this.selectable = ko.observable(true); this.subscribed = ko.observable(true); this.subscribed.subscribe(function (bIsSubscribe) { if(this.parentFullName()) { var oParentFolder = App.MailCache.folderList().getFolderByFullName(this.parentFullName()); if(oParentFolder) { App.MailCache.countMessages(oParentFolder); } } }, this); this.existen = ko.observable(true); this.isNamespace = ko.observable(false); this.subfoldersMessagesCount = ko.observable(0); this.subfolders = ko.observableArray([]); this.subfolders.subscribe(function (aSubFolders) { var canExpand = _.any( _.map(aSubFolders, function(oFolder, key){ return oFolder.subscribed(); }) ); this.canExpand(canExpand); }, this); this.canExpand = ko.observable(true); this.expanded = ko.observable(false); this.isCollapseHandler = ko.computed(function () { return this.subfolders().length !== 0 && !this.isNamespace() && this.canExpand(); }, this); this.messageCountToShow = ko.computed(function () { if(this.canExpand()) { return (this.showUnseenMessages()) ? this.unseenMessageCount() + this.subfoldersMessagesCount() : this.messageCount(); } else { return (this.showUnseenMessages()) ? this.unseenMessageCount() : this.messageCount(); } }, this); this.isSubFolder = ko.computed(function () { return (this.level() > 0); }, this); this.selected = ko.observable(false); this.recivedAnim = ko.observable(false).extend({'autoResetToFalse': 500}); this.hasSubscribedSubfolders = ko.computed(function () { return !!ko.utils.arrayFirst(this.subfolders(), function (oFolder) { return oFolder.subscribed(); }); }, this); this.isSystem = ko.computed(function () { return (this.type() !== Enums.FolderTypes.User ? true : false); }, this); this.visible = ko.computed(function () { var bSubScribed = this.subscribed(), bExisten = this.existen(), bSelectable = this.selectable(), bSubFolders = this.hasSubscribedSubfolders(), bSystem = this.isSystem() ; return bSubScribed || bSystem || (bSubFolders && (!bExisten || !bSelectable)); }, this); this.edited = ko.observable(false); this.edited.subscribe(function (value) { if (value === false) { this.nameForEdit(this.name()); } }, this); this.canBeSelected = ko.computed(function () { var bExisten = this.existen(), bSelectable = this.selectable() ; return bExisten && bSelectable; }, this); this.canSubscribe = ko.computed(function () { var oAccount = this.account(), bDisableManageSubscribe = false ; if (oAccount) { bDisableManageSubscribe = oAccount.extensionExists('DisableManageSubscribe'); } return (!this.isSystem() && this.canBeSelected() && !bDisableManageSubscribe); }, this); this.canDelete = ko.computed(function () { return (!this.isSystem() && this.hasExtendedInfo() && this.messageCount() === 0 && this.subfolders().length === 0); }, this); this.canRename = ko.computed(function () { return (!this.isSystem() && this.canBeSelected()); }, this); this.subscribeButtonHint = ko.computed(function () { if (this.canSubscribe()) { return this.subscribed() ? Utils.i18n('SETTINGS/ACCOUNT_FOLDERS_HIDE_FOLDER_HINT') : Utils.i18n('SETTINGS/ACCOUNT_FOLDERS_SHOW_FOLDER_HINT'); } return ''; }, this); this.deleteButtonHint = ko.computed(function () { return this.canDelete() ? Utils.i18n('SETTINGS/ACCOUNT_FOLDERS_DELETE_FOLDER_HINT') : ''; }, this); this.usedAs = ko.computed(function () { var result = '' ; switch (this.type()) { case Enums.FolderTypes.Inbox: result = Utils.i18n('SETTINGS/ACCOUNT_FOLDERS_USED_AS_INBOX'); break; case Enums.FolderTypes.Sent: result = Utils.i18n('SETTINGS/ACCOUNT_FOLDERS_USED_AS_SENT'); break; case Enums.FolderTypes.Drafts: result = Utils.i18n('SETTINGS/ACCOUNT_FOLDERS_USED_AS_DRAFTS'); break; case Enums.FolderTypes.Trash: result = Utils.i18n('SETTINGS/ACCOUNT_FOLDERS_USED_AS_TRASH'); break; case Enums.FolderTypes.Spam: result = Utils.i18n('SETTINGS/ACCOUNT_FOLDERS_USED_AS_SPAM'); break; default: result = ''; break; } return result; }, this); this.oMessages = {}; this.oUids = {}; this.aResponseHandlers = []; this.displayName = ko.computed(function () { var result = this.name() ; switch (this.type()) { case Enums.FolderTypes.Inbox: result = Utils.i18n('MAIN/FOLDER_INBOX'); break; case Enums.FolderTypes.Sent: result = Utils.i18n('MAIN/FOLDER_SENT'); break; case Enums.FolderTypes.Drafts: result = Utils.i18n('MAIN/FOLDER_DRAFTS'); break; case Enums.FolderTypes.Trash: result = Utils.i18n('MAIN/FOLDER_TRASH'); break; case Enums.FolderTypes.Spam: result = Utils.i18n('MAIN/FOLDER_SPAM'); break; } return result; }, this); this.aRequestedUids = []; this.aRequestedThreadUids = []; this.requestedLists = []; this.hasChanges = ko.observable(false); this.hasChanges.subscribe(function () { this.requestedLists = []; }, this); this.unseenFilterCommand = Utils.createCommand(this, this.executeUnseenFilter, this.showUnseenMessages); this.unseenMessagesTitle = ko.computed(function () { return this.showUnseenMessages() ? Utils.i18n('MAILBOX/TITLE_UNSEEN_MESSAGES_ONLY') : ''; }, this); this.relevantInformationLastMoment = null; } /** * @param {string} sUid * @returns {Object} */ CFolderModel.prototype.getMessageByUid = function (sUid) { return this.oMessages[sUid]; }; /** * @returns {Array} */ CFolderModel.prototype.getFlaggedMessageUids = function () { var aUids = []; _.each(this.oMessages, function (oMessage) { if (oMessage.flagged()) { aUids.push(oMessage.uid()); } }); return aUids; }; /** * @param {string} sUid */ CFolderModel.prototype.setMessageUnflaggedByUid = function (sUid) { var oMessage = this.oMessages[sUid]; if (oMessage) { oMessage.flagged(false); } }; /** * @param {Object} oMessage */ CFolderModel.prototype.hideThreadMessages = function (oMessage) { _.each(oMessage.threadUids(), function (sThreadUid) { var oMess = this.oMessages[sThreadUid]; if (oMess) { if (!oMess.deleted()) { oMess.threadShowAnimation(false); oMess.threadHideAnimation(true); setTimeout(function () { oMess.threadHideAnimation(false); }, 1000); } } }, this); }; /** * @param {Object} oMessage */ CFolderModel.prototype.getThreadMessages = function (oMessage) { var aLoadedMessages = [], aUidsForLoad = [], aChangedThreadUids = [], iCount = 0, oLastMessage = null, iShowThrottle = 50 ; _.each(oMessage.threadUids(), function (sThreadUid) { if (iCount < oMessage.threadCountForLoad()) { var oMess = this.oMessages[sThreadUid]; if (oMess) { if (!oMess.deleted()) { oMess.markAsThreadPart(iShowThrottle, oMessage.uid()); aLoadedMessages.push(oMess); aChangedThreadUids.push(oMess.uid()); iCount++; oLastMessage = oMess; } } else { aUidsForLoad.push(sThreadUid); aChangedThreadUids.push(sThreadUid); iCount++; } } else { aChangedThreadUids.push(sThreadUid); } }, this); if (!oMessage.threadLoading()) { this.loadThreadMessages(aUidsForLoad); } oMessage.changeThreadUids(aChangedThreadUids, aLoadedMessages.length); if (oLastMessage && aLoadedMessages.length < oMessage.threadUids().length) { oLastMessage.showNextLoadingLink(_.bind(oMessage.increaseThreadCountForLoad, oMessage)); } this.addThreadUidsToUidLists(oMessage.uid(), oMessage.threadUids()); return aLoadedMessages; }; /** * @param {Object} oMessage */ CFolderModel.prototype.computeThreadData = function (oMessage) { var iUnreedCount = 0, bPartialFlagged = false, aSenders = [], aEmails = [], sMainEmail = oMessage.oFrom.getFirstEmail() ; _.each(oMessage.threadUids(), function (sThreadUid) { var oThreadMessage = this.oMessages[sThreadUid], sThreadEmail = '' ; if (oThreadMessage && !oThreadMessage.deleted()) { if (!oThreadMessage.seen()) { iUnreedCount++; } if (oThreadMessage.flagged()) { bPartialFlagged = true; } // // *** temporarily disabled *** // sThreadEmail = oThreadMessage.oFrom.getFirstEmail(); // if ((sThreadEmail !== sMainEmail) && (-1 === Utils.inArray(sThreadEmail, aEmails))) // { // aEmails.push(sThreadEmail); // aSenders.push(oThreadMessage.oFrom.getFirstDisplay()); // } } }, this); oMessage.threadUnreedCount(iUnreedCount); oMessage.partialFlagged(bPartialFlagged); oMessage.threadSenders(aSenders); }; /** * * @param {string} sUid * @param {Array} aThreadUids */ CFolderModel.prototype.addThreadUidsToUidLists = function (sUid, aThreadUids) { _.each(this.oUids, function (oUidSearchList) { _.each(oUidSearchList, function (oUidList) { oUidList.addThreadUids(sUid, aThreadUids); }); }); }; /** * @param {Array} aUidsForLoad */ CFolderModel.prototype.loadThreadMessages = function (aUidsForLoad) { if (aUidsForLoad.length > 0) { var oParameters = { 'Action': 'MessageListByUids', 'Folder': this.fullName(), 'Uids': aUidsForLoad } ; App.Ajax.send(oParameters, this.onMessageListByUidsResponse, this); } }; /** * @param {Array} aMessages */ CFolderModel.prototype.getThreadCheckedUidsFromList = function (aMessages) { var oFolder = this, aThreadUids = [] ; _.each(aMessages, function (oMessage) { if (oMessage.threadCount() > 0 && !oMessage.threadOpened()) { _.each(oMessage.threadUids(), function (sUid) { var oThreadMessage = oFolder.oMessages[sUid]; if (oThreadMessage && !oThreadMessage.deleted() && oThreadMessage.checked()) { aThreadUids.push(sUid); } }); } }); return aThreadUids; }; /** * @param {Object} oRawMessage * @param {boolean} bThreadPart * @param {boolean} bTrustThreadInfo */ CFolderModel.prototype.parseAndCacheMessage = function (oRawMessage, bThreadPart, bTrustThreadInfo) { var sUid = oRawMessage.Uid.toString(), oMessage = this.oMessages[sUid] ? this.oMessages[sUid] : new CMessageModel() ; oMessage.parse(oRawMessage, this.iAccountId, bThreadPart, bTrustThreadInfo); this.oMessages[oMessage.uid()] = oMessage; return oMessage; }; /** * @param {Object} oResponse * @param {Object} oRequest */ CFolderModel.prototype.onMessageListByUidsResponse = function (oResponse, oRequest) { var oResult = oResponse.Result; if (oResult && oResult['@Object'] === 'Collection/MessageCollection') { _.each(oResult['@Collection'], function (oRawMessage) { this.parseAndCacheMessage(oRawMessage, true, true); }, this); App.MailCache.showOpenedThreads(this.fullName()); } }; /** * Adds uids of requested messages. * * @param {Array} aUids */ CFolderModel.prototype.addRequestedUids = function (aUids) { this.aRequestedUids = _.union(this.aRequestedUids, aUids); }; /** * @param {string} sUid */ CFolderModel.prototype.hasUidBeenRequested = function (sUid) { return _.indexOf(this.aRequestedUids, sUid) !== -1; }; /** * Adds uids of requested thread message headers. * * @param {Array} aUids */ CFolderModel.prototype.addRequestedThreadUids = function (aUids) { this.aRequestedThreadUids = _.union(this.aRequestedThreadUids, aUids); }; /** * @param {string} sUid */ CFolderModel.prototype.hasThreadUidBeenRequested = function (sUid) { return _.indexOf(this.aRequestedThreadUids, sUid) !== -1; }; /** * @param {Object} oParams */ CFolderModel.prototype.hasListBeenRequested = function (oParams) { var aFindedParams = _.where(this.requestedLists, oParams), bHasParams = aFindedParams.length > 0 ; if (!bHasParams) { this.requestedLists.push(oParams); } return bHasParams; }; /** * @param {string} sUid * @param {string} sReplyType */ CFolderModel.prototype.markMessageReplied = function (sUid, sReplyType) { var oMsg = this.oMessages[sUid]; if (oMsg) { switch (sReplyType) { case Enums.ReplyType.Reply: case Enums.ReplyType.ReplyAll: oMsg.answered(true); break; case Enums.ReplyType.Forward: oMsg.forwarded(true); break; } } }; CFolderModel.prototype.removeAllMessages = function () { var oUidList = null; this.oMessages = {}; this.oUids = {}; this.messageCount(0); this.unseenMessageCount(0); this.realUnseenMessageCount(0); oUidList = this.getUidList('', ''); oUidList.resultCount(0); }; CFolderModel.prototype.removeAllMessageListsFromCacheIfHasChanges = function () { if (this.hasChanges()) { this.oUids = {}; this.requestedLists = []; this.aRequestedThreadUids = []; this.hasChanges(false); } }; CFolderModel.prototype.removeFlaggedMessageListsFromCache = function () { _.each(this.oUids, function (oSearchUids, sSearch) { delete this.oUids[sSearch][Enums.FolderFilter.Flagged]; }, this); }; CFolderModel.prototype.removeUnseenMessageListsFromCache = function () { _.each(this.oUids, function (oSearchUids, sSearch) { delete this.oUids[sSearch][Enums.FolderFilter.Unseen]; }, this); }; /** * @param {string} sUidNext * @param {string} sHash * @param {number} iMsgCount * @param {number} iMsgUnseenCount * @param {boolean} bOnlyRealCount */ CFolderModel.prototype.setRelevantInformation = function (sUidNext, sHash, iMsgCount, iMsgUnseenCount, bOnlyRealCount) { var hasChanges = this.hasExtendedInfo() && (this.hash() !== sHash || this.realUnseenMessageCount() !== iMsgUnseenCount); this.uidNext(sUidNext); this.hash(sHash); // if different, either new messages were appeared, or some messages were deleted if (!this.hasExtendedInfo() || !bOnlyRealCount) { this.messageCount(iMsgCount); this.unseenMessageCount(iMsgUnseenCount); if (iMsgUnseenCount === 0) { this.unseenMessageCount.valueHasMutated(); } //fix for folder count summing } this.realUnseenMessageCount(iMsgUnseenCount); this.hasExtendedInfo(true); if (hasChanges) { this.markHasChanges(); } this.relevantInformationLastMoment = moment(); return hasChanges; }; CFolderModel.prototype.markHasChanges = function () { this.hasChanges(true); }; /** * @param {number} iDiff * @param {number} iUnseenDiff */ CFolderModel.prototype.addMessagesCountsDiff = function (iDiff, iUnseenDiff) { var iCount = this.messageCount() + iDiff, iUnseenCount = this.unseenMessageCount() + iUnseenDiff ; if (iCount < 0) { iCount = 0; } this.messageCount(iCount); if (iUnseenCount < 0) { iUnseenCount = 0; } if (iUnseenCount > iCount) { iUnseenCount = iCount; } this.unseenMessageCount(iUnseenCount); }; /** * @param {Array} aUids */ CFolderModel.prototype.markDeletedByUids = function (aUids) { var iMinusDiff = 0, iUnseenMinusDiff = 0 ; _.each(aUids, function (sUid) { var oMessage = this.oMessages[sUid]; if (oMessage) { iMinusDiff++; if (!oMessage.seen()) { iUnseenMinusDiff++; } oMessage.deleted(true); } }, this); this.addMessagesCountsDiff(-iMinusDiff, -iUnseenMinusDiff); return {MinusDiff: iMinusDiff, UnseenMinusDiff: iUnseenMinusDiff}; }; /** * @param {Array} aUids */ CFolderModel.prototype.revertDeleted = function (aUids) { var iPlusDiff = 0, iUnseenPlusDiff = 0 ; _.each(aUids, function (sUid) { var oMessage = this.oMessages[sUid]; if (oMessage && oMessage.deleted()) { iPlusDiff++; if (!oMessage.seen()) { iUnseenPlusDiff++; } oMessage.deleted(false); } }, this); this.addMessagesCountsDiff(iPlusDiff, iUnseenPlusDiff); return {PlusDiff: iPlusDiff, UnseenPlusDiff: iUnseenPlusDiff}; }; /** * @param {Array} aUids */ CFolderModel.prototype.commitDeleted = function (aUids) { _.each(aUids, _.bind(function (sUid) { delete this.oMessages[sUid]; }, this)); _.each(this.oUids, function (oUidSearchList) { _.each(oUidSearchList, function (oUidList) { oUidList.deleteUids(aUids); }); }); }; /** * @param {string} sSearch * @param {string} sFilters */ CFolderModel.prototype.getUidList = function (sSearch, sFilters) { var oUidList = null ; if (this.oUids[sSearch] === undefined) { this.oUids[sSearch] = {}; } if (this.oUids[sSearch][sFilters] === undefined) { oUidList = new CUidListModel(); oUidList.search(sSearch); oUidList.filters(sFilters); this.oUids[sSearch][sFilters] = oUidList; } return this.oUids[sSearch][sFilters]; }; /** * @param {Object} oResult * @param {string} sParentFullName */ CFolderModel.prototype.parse = function (oResult, sParentFullName) { var sName = '', aFolders = App.Storage.getData('folderAccordion') || []; if (oResult['@Object'] === 'Object/Folder') { this.parentFullName(sParentFullName); sName = Utils.pString(oResult.Name); this.name(sName); this.nameForEdit(sName); this.fullName(Utils.pString(oResult.FullNameRaw)); this.fullNameHash(Utils.pString(oResult.FullNameHash)); this.routingHash(App.Routing.buildHashFromArray([Enums.Screens.Mailbox, this.fullName()])); this.delimiter(oResult.Delimiter); this.type(oResult.Type); this.subscribed(oResult.IsSubscribed); this.selectable(oResult.IsSelectable); this.existen(oResult.IsExists); if (oResult.Extended) { this.setRelevantInformation(oResult.Extended.UidNext.toString(), oResult.Extended.Hash, oResult.Extended.MessageCount, oResult.Extended.MessageUnseenCount, false); } if(_.find(aFolders, function(sFolder){ return sFolder === this.name(); }, this)) { this.expanded(true); } return oResult.SubFolders; } return null; }; /** * @param {Object} oResponse * @param {Object} oRequest */ CFolderModel.prototype.onMessageResponse = function (oResponse, oRequest) { var oResult = oResponse.Result, oHand = null, sUid = oResult ? oResult.Uid.toString() : oRequest.Uid.toString(), oMessage = this.oMessages[sUid], bSelected = oMessage ? oMessage.selected() : false ; if (!oResult) { if (bSelected) { App.Api.showErrorByCode(oResponse, Utils.i18n('WARNING/UNKNOWN_ERROR')); App.Routing.replaceHashWithoutPart('/msg' + sUid); } oMessage = null; } else { oMessage = this.parseAndCacheMessage(oResult, false, false); if (oMessage && oMessage.ical() && oMessage.ical().isReplyType() && App.CalendarCache) { App.CalendarCache.calendarChanged(true); } } oHand = this.aResponseHandlers[sUid]; if (oHand) { oHand.handler.call(oHand.context, oMessage, sUid); delete this.aResponseHandlers[sUid]; } }; /** * @param {string} sUid * @param {Function} fResponseHandler * @param {Object} oContext */ CFolderModel.prototype.getCompletelyFilledMessage = function (sUid, fResponseHandler, oContext) { var oMessage = this.oMessages[sUid], oParameters = { 'Action': 'Message', 'Folder': this.fullName(), 'Uid': sUid } ; if (sUid.length > 0) { if (!oMessage || !oMessage.completelyFilled() || oMessage.trimmed()) { if (fResponseHandler && oContext) { this.aResponseHandlers[sUid] = {handler: fResponseHandler, context: oContext}; } App.Ajax.send(oParameters, this.onMessageResponse, this); } else if (fResponseHandler && oContext) { fResponseHandler.call(oContext, oMessage, sUid); } } }; /** * @param {string} sUid */ CFolderModel.prototype.showExternalPictures = function (sUid) { var oMessage = this.oMessages[sUid]; if (oMessage !== undefined) { oMessage.showExternalPictures(); } }; /** * @param {string} sEmail */ CFolderModel.prototype.alwaysShowExternalPicturesForSender = function (sEmail) { _.each(this.oMessages, function (oMessage) { var aFrom = oMessage.oFrom.aCollection; if (aFrom.length > 0 && aFrom[0].sEmail === sEmail) { oMessage.alwaysShowExternalPicturesForSender(); } }, this); }; /** * @param {string} sField * @param {Array} aUids * @param {boolean} bSetAction */ CFolderModel.prototype.executeGroupOperation = function (sField, aUids, bSetAction) { var iUnseenDiff = 0; _.each(this.oMessages, function (oMessage) { if (aUids.length > 0) { _.each(aUids, function (sUid) { if (oMessage && oMessage.uid() === sUid && oMessage[sField]() !== bSetAction) { oMessage[sField](bSetAction); iUnseenDiff++; } }); } else { oMessage[sField](bSetAction); } }); if (aUids.length === 0) { iUnseenDiff = (bSetAction) ? this.unseenMessageCount() : this.messageCount() - this.unseenMessageCount(); } if (sField === 'seen' && iUnseenDiff > 0) { if (bSetAction) { this.addMessagesCountsDiff(0, -iUnseenDiff); } else { this.addMessagesCountsDiff(0, iUnseenDiff); } this.markHasChanges(); } }; CFolderModel.prototype.emptyFolder = function () { var sWarning = Utils.i18n('MAILBOX/CONFIRM_EMPTY_FOLDER'), fCallBack = _.bind(this.clearFolder, this) ; if (this.enableEmptyFolder()) { App.Screens.showPopup(ConfirmPopup, [sWarning, fCallBack]); } }; /** * @param {boolean} bOkAnswer */ CFolderModel.prototype.clearFolder = function (bOkAnswer) { var oParameters = { 'Action': 'FolderClear', 'Folder': this.fullName() } ; if (this.enableEmptyFolder() && bOkAnswer) { App.Ajax.send(oParameters); this.removeAllMessages(); App.MailCache.onClearFolder(this); } }; CFolderModel.prototype.getNameWhithLevel = function () { var iLevel = this.level(); if (!this.isNamespace() && iLevel > 0) { iLevel--; } return Utils.strRepeat("\u00A0", iLevel * 3) + this.name(); }; /** * @param {Object} oFolder * @param {Object} oEvent */ CFolderModel.prototype.onAccordion = function (oFolder, oEvent) { var bExpanded = !this.expanded(), aFolders = App.Storage.getData('folderAccordion') || []; if (bExpanded) { aFolders.push(this.name()); } else { // remove current folder from expanded folders aFolders = _.reject(aFolders, function(sFolder){ return sFolder === this.name(); }, this); } App.Storage.setData('folderAccordion', aFolders); this.expanded(bExpanded); App.MailCache.countMessages(this); oEvent.stopPropagation(); }; CFolderModel.prototype.executeUnseenFilter = function () { var bNotChanged = false; if (this.showUnseenMessages()) { App.MailCache.waitForUnseenMessages(true); bNotChanged = App.Routing.setHash(App.Links.mailbox(this.fullName(), 1, '', '', Enums.FolderFilter.Unseen)); if (bNotChanged) { App.MailCache.changeCurrentMessageList(this.fullName(), 1, '', Enums.FolderFilter.Unseen); } return false; } return true; }; /** * @constructor */ function CFolderListModel() { this.iAccountId = 0; this.bInitialized = ko.observable(false); this.expandFolders = ko.observable(false); this.expandNames = ko.observableArray([]); this.collection = ko.observableArray([]); this.options = ko.observableArray([]); this.sNamespace = ''; this.sNamespaceFolder = ''; this.oStarredFolder = null; this.oNamedCollection = {}; var self = this, fSetSystemType = function (iType) { return function (oFolder) { if (oFolder) { oFolder.type(iType); } }; }, fFullNameHelper = function (fFolder) { return { 'read': function () { this.collection(); return fFolder() ? fFolder().fullName() : ''; }, 'write': function (sValue) { fFolder(this.getFolderByFullName(sValue)); }, 'owner': self }; } ; this.totalMessageCount = ko.computed(function (){ return this.getRecursivelyMessageCount(this.collection()); }, this); this.currentFolder = ko.observable(null); this.inboxFolder = ko.observable(null); this.sentFolder = ko.observable(null); this.draftsFolder = ko.observable(null); this.spamFolder = ko.observable(null); this.trashFolder = ko.observable(null); this.inboxFolder.subscribe(fSetSystemType(Enums.FolderTypes.User), this, 'beforeChange'); this.sentFolder.subscribe(fSetSystemType(Enums.FolderTypes.User), this, 'beforeChange'); this.draftsFolder.subscribe(fSetSystemType(Enums.FolderTypes.User), this, 'beforeChange'); this.spamFolder.subscribe(fSetSystemType(Enums.FolderTypes.User), this, 'beforeChange'); this.trashFolder.subscribe(fSetSystemType(Enums.FolderTypes.User), this, 'beforeChange'); this.inboxFolder.subscribe(fSetSystemType(Enums.FolderTypes.Inbox)); this.sentFolder.subscribe(fSetSystemType(Enums.FolderTypes.Sent)); this.draftsFolder.subscribe(fSetSystemType(Enums.FolderTypes.Drafts)); this.spamFolder.subscribe(fSetSystemType(Enums.FolderTypes.Spam)); this.trashFolder.subscribe(fSetSystemType(Enums.FolderTypes.Trash)); this.inboxFolderFullName = ko.computed(fFullNameHelper(this.inboxFolder)); this.sentFolderFullName = ko.computed(fFullNameHelper(this.sentFolder)); this.draftsFolderFullName = ko.computed(fFullNameHelper(this.draftsFolder)); this.spamFolderFullName = ko.computed(fFullNameHelper(this.spamFolder)); this.trashFolderFullName = ko.computed(fFullNameHelper(this.trashFolder)); this.currentFolderFullName = ko.computed(fFullNameHelper(this.currentFolder)); this.currentFolderType = ko.computed(function () { return this.currentFolder() ? this.currentFolder().type() : Enums.FolderTypes.User; }, this); this.delimiter = ko.computed(function (){ return this.inboxFolder() ? this.inboxFolder().delimiter() : ''; }, this); } /** * @returns {Array} */ CFolderListModel.prototype.getFoldersWithoutCountInfo = function () { var aFolders = _.compact(_.map(this.oNamedCollection, function(oFolder, sFullName) { if (oFolder.canBeSelected() && !oFolder.hasExtendedInfo()) { return sFullName; } return null; })); return aFolders; }; /** * @param {string} sFolderFullName * @param {string} sFilters */ CFolderListModel.prototype.setCurrentFolder = function (sFolderFullName, sFilters) { var oFolder = this.getFolderByFullName(sFolderFullName) ; if (oFolder === null) { oFolder = this.inboxFolder(); } if (oFolder !== null) { if (this.currentFolder()) { this.currentFolder().selected(false); if (this.oStarredFolder) { this.oStarredFolder.selected(false); } } this.currentFolder(oFolder); if (sFilters === Enums.FolderFilter.Flagged) { if (this.oStarredFolder) { this.oStarredFolder.selected(true); } } else { this.currentFolder().selected(true); } } }; /** * Returns a folder, found by the type. * * @param {number} iType * @returns {CFolderModel|null} */ CFolderListModel.prototype.getFolderByType = function (iType) { switch (iType) { case Enums.FolderTypes.Inbox: return this.inboxFolder(); case Enums.FolderTypes.Sent: return this.sentFolder(); case Enums.FolderTypes.Drafts: return this.draftsFolder(); case Enums.FolderTypes.Trash: return this.trashFolder(); case Enums.FolderTypes.Spam: return this.spamFolder(); } return null; }; /** * Returns a folder, found by the full name. * * @param {string} sFolderFullName * @returns {CFolderModel|null} */ CFolderListModel.prototype.getFolderByFullName = function (sFolderFullName) { var oFolder = this.oNamedCollection[sFolderFullName] ; return oFolder ? oFolder : null; }; /** * Calls a recursive parsing of the folder tree. * * @param {number} iAccountId * @param {Object} oData * @param {Object} oNamedFolderListOld */ CFolderListModel.prototype.parse = function (iAccountId, oData, oNamedFolderListOld) { this.iAccountId = iAccountId; this.sNamespace = Utils.pString(oData.Namespace); this.bInitialized(true); if (this.sNamespace.length > 0) { this.sNamespaceFolder = this.sNamespace.substring(0, this.sNamespace.length - 1); } else { this.sNamespaceFolder = this.sNamespace; } this.expandFolders(AppData['MailExpandFolders'] && !App.Storage.hasData('folderAccordion')); if (!App.Storage.hasData('folderAccordion')) { App.Storage.setData('folderAccordion', []); } this.collection(this.parseRecursively(oData['@Collection'], oNamedFolderListOld)); }; /** * Recursively parses the folder tree. * * @param {Array} aRowCollection * @param {Object} oNamedFolderListOld * @param {number=} iLevel * @param {string=} sParentFullName * @returns {Array} */ CFolderListModel.prototype.parseRecursively = function (aRowCollection, oNamedFolderListOld, iLevel, sParentFullName) { var self = this, aParsedCollection = [], iIndex = 0, iLen = 0, oFolder = null, sFolderFullName = '', oSubFolders = null, aSubfolders = [], bFolderIsNamespace = false, bExpandFolders = this.expandFolders(), oAccount = AppData.Accounts.getAccount(this.iAccountId), fDetectSpamFolder = function () { var oSpamFolder = self.getFolderByType(Enums.FolderTypes.Spam); if (!oAccount || !oAccount.extensionExists('AllowSpamFolderExtension')) { oSpamFolder.type(Enums.FolderTypes.User); self.spamFolder(null); } }, fAccountExtensionsRequestedSubscribe = function () { if (oAccount && oAccount.extensionsRequested()) { fDetectSpamFolder(); oAccount.extensionsRequestedSubscription.dispose(); oAccount.extensionsRequestedSubscription = undefined; } } ; sParentFullName = sParentFullName || ''; if (Utils.isUnd(iLevel)) { iLevel = -1; } iLevel++; if (_.isArray(aRowCollection)) { for (iLen = aRowCollection.length; iIndex < iLen; iIndex++) { sFolderFullName = Utils.pString(aRowCollection[iIndex].FullNameRaw); oFolder = oNamedFolderListOld[sFolderFullName]; if (!oFolder) { oFolder = new CFolderModel(); } oFolder.iAccountId = this.iAccountId; oSubFolders = oFolder.parse(aRowCollection[iIndex], sParentFullName); if (bExpandFolders && oSubFolders !== null) { oFolder.expanded(true); this.expandNames().push(Utils.pString(aRowCollection[iIndex].Name)); } bFolderIsNamespace = (this.sNamespace === oFolder.fullName() + oFolder.delimiter()); oFolder.isNamespace(bFolderIsNamespace); oFolder.level(iLevel); this.oNamedCollection[oFolder.fullName()] = oFolder; switch (oFolder.type()) { case Enums.FolderTypes.Inbox: this.inboxFolder(oFolder); break; case Enums.FolderTypes.Sent: this.sentFolder(oFolder); break; case Enums.FolderTypes.Drafts: this.draftsFolder(oFolder); break; case Enums.FolderTypes.Trash: this.trashFolder(oFolder); break; case Enums.FolderTypes.Spam: this.spamFolder(oFolder); if (oAccount.extensionsRequested()) { fDetectSpamFolder(); } else { oAccount.extensionsRequestedSubscription = oAccount.extensionsRequested.subscribe(fAccountExtensionsRequestedSubscribe); } break; } aParsedCollection.push(oFolder); if (oSubFolders === null && oFolder.type() === Enums.FolderTypes.Inbox) { this.createStarredFolder(oFolder.fullName(), iLevel); if (this.oStarredFolder) { aParsedCollection.push(this.oStarredFolder); } } else if (oSubFolders !== null) { aSubfolders = this.parseRecursively(oSubFolders['@Collection'], oNamedFolderListOld, iLevel, oFolder.fullName()); if(oFolder.type() === Enums.FolderTypes.Inbox) { if (oFolder.isNamespace()) { this.createStarredFolder(oFolder.fullName(), iLevel + 1); if (this.oStarredFolder) { aSubfolders.unshift(this.oStarredFolder); } } else { this.createStarredFolder(oFolder.fullName(), iLevel); if (this.oStarredFolder) { aParsedCollection.push(this.oStarredFolder); } } } oFolder.subfolders(aSubfolders); } } if (bExpandFolders) { App.Storage.setData('folderAccordion', this.expandNames()); } } return aParsedCollection; }; /** * @param {string} sFullName * @param {number} iLevel */ CFolderListModel.prototype.createStarredFolder = function (sFullName, iLevel) { var oStarredFolder = new CFolderModel(); oStarredFolder.iAccountId = this.iAccountId; oStarredFolder.virtual(true); oStarredFolder.level(iLevel); oStarredFolder.fullName(sFullName); oStarredFolder.name(Utils.i18n('MAIN/FOLDER_STARRED')); oStarredFolder.type(Enums.FolderTypes.Starred); oStarredFolder.routingHash(App.Routing.buildHashFromArray(App.Links.mailbox(oStarredFolder.fullName(), 1, '', '', Enums.FolderFilter.Flagged))); this.oStarredFolder = oStarredFolder; }; /** * @param {string} sFirstItem * @param {boolean=} bEnableSystem = false * @param {boolean=} bHideInbox = false * @param {boolean=} bIgnoreCanBeSelected = false * @returns {Array} */ CFolderListModel.prototype.getOptions = function (sFirstItem, bEnableSystem, bHideInbox, bIgnoreCanBeSelected) { var sDeepPrefix = '\u00A0\u00A0\u00A0\u00A0', fGetOptionsFromCollection = function (aOrigCollection) { var iIndex = 0, iLen = 0, oItem = null, aResCollection = [] ; if (Utils.isUnd(bEnableSystem)) { bEnableSystem = false; } if (Utils.isUnd(bHideInbox)) { bHideInbox = false; } if (Utils.isUnd(bIgnoreCanBeSelected)) { bIgnoreCanBeSelected = false; } for (iIndex = 0, iLen = aOrigCollection.length; iIndex < iLen; iIndex++) { oItem = aOrigCollection[iIndex]; if (!oItem.virtual() && (oItem.type() !== Enums.FolderTypes.Inbox && bHideInbox || !bHideInbox)) { aResCollection.push({ 'name': oItem.name(), 'fullName': oItem.fullName(), 'displayName': (new Array(oItem.level() + 1)).join(sDeepPrefix) + oItem.name(), 'translatedDisplayName': (new Array(oItem.level() + 1)).join(sDeepPrefix) + oItem.displayName(), 'disable': ((oItem.isSystem() && !bEnableSystem) || (!bIgnoreCanBeSelected && !oItem.canBeSelected())) }); } aResCollection = aResCollection.concat(fGetOptionsFromCollection(oItem.subfolders())); } return aResCollection; }, aCollection = fGetOptionsFromCollection(this.collection()) ; if (sFirstItem !== '') { aCollection.unshift({ 'name': sFirstItem, 'fullName': '', 'displayName': sFirstItem, 'translatedDisplayName': sFirstItem, 'disable': false }); } return aCollection; }; /** * @param {Array} aList * @returns {Number} */ CFolderListModel.prototype.getRecursivelyMessageCount = function (aList) { var iIndex = 0, iLen = 0, oItem = null, iCount = 0 ; for (iIndex = 0, iLen = aList.length; iIndex < iLen; iIndex++) { oItem = aList[iIndex]; if (!oItem.virtual()) { iCount += oItem.messageCount() + this.getRecursivelyMessageCount(oItem.subfolders()); } } return iCount; }; /** * @param {Object} oFolderToDelete */ CFolderListModel.prototype.deleteFolder = function (oFolderToDelete) { var fRemoveFolder = function (oFolder) { if (oFolderToDelete && oFolderToDelete.fullName() === oFolder.fullName()) { return true; } oFolder.subfolders.remove(fRemoveFolder); return false; } ; this.collection.remove(fRemoveFolder); }; /** * @constructor */ function CMessageModel() { this.accountId = ko.observable(0); this.folder = ko.observable(''); this.uid = ko.observable(''); this.subject = ko.observable(''); this.emptySubject = ko.computed(function () { return (Utils.trim(this.subject()) === ''); }, this); this.subjectForDisplay = ko.computed(function () { return this.emptySubject() ? Utils.i18n('MAILBOX/EMPTY_SUBJECT') : this.subject(); }, this); this.messageId = ko.observable(''); this.size = ko.observable(0); this.friendlySize = ko.computed(function () { return Utils.friendlySize(this.size()); }, this); this.textSize = ko.observable(0); this.oDateModel = new CDateModel(); this.fullDate = ko.observable(''); this.oFrom = new CAddressListModel(); this.fullFrom = ko.observable(''); this.oTo = new CAddressListModel(); this.to = ko.observable(''); this.fromOrToText = ko.observable(''); this.oCc = new CAddressListModel(); this.cc = ko.observable(''); this.oBcc = new CAddressListModel(); this.bcc = ko.observable(''); this.oSender = new CAddressListModel(); this.oReplyTo = new CAddressListModel(); this.seen = ko.observable(false); this.flagged = ko.observable(false); this.partialFlagged = ko.observable(false); this.answered = ko.observable(false); this.forwarded = ko.observable(false); this.hasAttachments = ko.observable(false); this.hasIcalAttachment = ko.observable(false); this.hasVcardAttachment = ko.observable(false); this.showCalendarIcon = ko.computed(function () { return AppData.User.AllowCalendar && this.hasIcalAttachment(); }, this); this.threadsAllowed = ko.computed(function () { var oFolder = App.MailCache.getFolderByFullName(this.accountId(), this.folder()), bFolderWithoutThreads = oFolder && (oFolder.type() === Enums.FolderTypes.Drafts || oFolder.type() === Enums.FolderTypes.Spam || oFolder.type() === Enums.FolderTypes.Trash) ; return AppData.User.useThreads() && !bFolderWithoutThreads; }, this); this.threadPart = ko.observable(false); this.threadPart.subscribe(function () { if (this.threadPart()) { this.partialFlagged(false); } }, this); this.threadParentUid = ko.observable(''); this.threadUids = ko.observableArray([]); this.threadSenders = ko.observableArray([]); this.threadSendersText = ko.computed(function () { var aSenders = this.threadSenders(); if (aSenders.length > 3) { return ', ' + aSenders[0] + Utils.i18n('MAILBOX/THREAD_MORE_SENDERS', {'COUNT': aSenders.length - 1}); } if (aSenders.length > 0) { aSenders.unshift(''); return aSenders.join(', '); } return ''; }, this); this.threadSendersVisible = ko.computed(function () { return this.threadSenders().length > 0; }, this); this.threadCount = ko.computed(function () { return this.threadUids().length; }, this); this.threadUnreedCount = ko.observable(0); this.threadOpened = ko.observable(false); this.threadLoading = ko.observable(false); this.threadLoadingVisible = ko.computed(function () { return this.threadsAllowed() && this.threadOpened() && this.threadLoading(); }, this); this.threadCountVisible = ko.computed(function () { return this.threadsAllowed() && this.threadCount() > 0 && !this.threadLoading(); }, this); this.threadCountForLoad = ko.observable(5); this.threadNextLoadingVisible = ko.observable(false); this.threadNextLoadingLinkVisible = ko.observable(false); this.threadFunctionLoadNext = null; this.threadShowAnimation = ko.observable(false); this.threadHideAnimation = ko.observable(false); this.importance = ko.observable(Enums.Importance.Normal); this.draftInfo = ko.observableArray([]); this.sensitivity = ko.observable(Enums.Sensivity.Nothing); this.hash = ko.observable(''); this.downloadLink = ko.computed(function () { return (this.hash().length > 0) ? Utils.getDownloadLinkByHash(this.accountId(), this.hash()) : ''; }, this); this.completelyFilled = ko.observable(false); this.checked = ko.observable(false); this.checked.subscribe(function (bChecked) { if (!this.threadOpened() && App.MailCache.useThreadsInCurrentList()) { var oFolder = App.MailCache.folderList().getFolderByFullName(this.folder()) ; _.each(this.threadUids(), function (sUid) { var oMessage = oFolder.oMessages[sUid]; if (oMessage) { oMessage.checked(bChecked); } }); } }, this); this.selected = ko.observable(false); this.deleted = ko.observable(false); // temporary removal until it was confirmation from the server to delete this.trimmed = ko.observable(false); this.trimmedTextSize = ko.observable(0); this.inReplyTo = ko.observable(''); this.references = ko.observable(''); this.readingConfirmation = ko.observable(''); this.isPlain = ko.observable(false); this.text = ko.observable(''); this.textBodyForNewWindow = ko.observable(''); this.$text = null; this.rtl = ko.observable(false); this.hasExternals = ko.observable(false); this.isExternalsShown = ko.observable(false); this.isExternalsAlwaysShown = ko.observable(false); this.foundedCids = ko.observableArray([]); this.attachments = ko.observableArray([]); this.usesAttachmentString = false; this.allAttachmentsHash = ''; this.safety = ko.observable(false); this.sourceHeaders = ko.observable(''); this.date = ko.observable(''); this.ical = ko.observable(null); this.vcard = ko.observable(null); this.textRaw = ko.observable(''); this.encryptedMessage = ko.observable(false); this.signedMessage = ko.observable(false); this.domMessageForPrint = ko.observable(null); this.Custom = {}; if (App.nowMoment) { App.nowMoment.subscribe(function () { this.updateMomentDate(); }, this); } } /** * @param {Object} oWin */ CMessageModel.prototype.viewMessage = function (oWin) { var oDomText = this.getDomText(Utils.getAppPath()), sHtml = '' ; this.textBodyForNewWindow(oDomText.html()); sHtml = $(this.domMessageForPrint()).html(); if (oWin) { $(oWin.document.body).html(sHtml); oWin.focus(); _.each(this.attachments(), function (oAttach) { var oLink = $(oWin.document.body).find("[data-hash='download-" + oAttach.hash() + "']"); oLink.on('click', _.bind(oAttach.downloadFile, oAttach, App)); oLink = $(oWin.document.body).find("[data-hash='view-" + oAttach.hash() + "']"); oLink.on('click', _.bind(oAttach.viewFile, oAttach)); }, this); } }; /** * Fields accountId, folder, oTo & oFrom should be filled. */ CMessageModel.prototype.fillFromOrToText = function () { var oFolder = App.MailCache.getFolderByFullName(this.accountId(), this.folder()), oAccount = AppData.Accounts.getAccount(this.accountId()) ; if (oFolder.type() === Enums.FolderTypes.Drafts || oFolder.type() === Enums.FolderTypes.Sent) { this.fromOrToText(this.oTo.getDisplay(Utils.i18n('MESSAGE/ME_RECIPIENT'), oAccount.email())); } else { this.fromOrToText(this.oFrom.getDisplay(Utils.i18n('MESSAGE/ME_SENDER'), oAccount.email())); } }; /** * @param {Array} aChangedThreadUids * @param {number} iLoadedMessagesCount */ CMessageModel.prototype.changeThreadUids = function (aChangedThreadUids, iLoadedMessagesCount) { this.threadUids(aChangedThreadUids); this.threadLoading(iLoadedMessagesCount < Math.min(this.threadUids().length, this.threadCountForLoad())); }; /** * @param {Function} fLoadNext */ CMessageModel.prototype.showNextLoadingLink = function (fLoadNext) { if (this.threadNextLoadingLinkVisible()) { this.threadNextLoadingVisible(true); this.threadFunctionLoadNext = fLoadNext; } }; CMessageModel.prototype.increaseThreadCountForLoad = function () { this.threadCountForLoad(this.threadCountForLoad() + 5); App.MailCache.showOpenedThreads(this.folder()); }; CMessageModel.prototype.loadNextMessages = function () { if (this.threadFunctionLoadNext) { this.threadFunctionLoadNext(); this.threadNextLoadingLinkVisible(false); this.threadFunctionLoadNext = null; } }; /** * @param {number} iShowThrottle * @param {string} sParentUid */ CMessageModel.prototype.markAsThreadPart = function (iShowThrottle, sParentUid) { var self = this; this.threadPart(true); this.threadParentUid(sParentUid); this.threadUids([]); this.threadNextLoadingVisible(false); this.threadNextLoadingLinkVisible(true); this.threadFunctionLoadNext = null; this.threadHideAnimation(false); setTimeout(function () { self.threadShowAnimation(true); }, iShowThrottle); }; /** * @param {AjaxMessageResponse} oData * @param {number} iAccountId * @param {boolean} bThreadPart * @param {boolean} bTrustThreadInfo */ CMessageModel.prototype.parse = function (oData, iAccountId, bThreadPart, bTrustThreadInfo) { var oIcal = null, oVcard = null, sHtml = '', sPlain = '' ; if (bTrustThreadInfo) { this.threadPart(bThreadPart); } if (!this.threadPart()) { this.threadParentUid(''); } if (oData['@Object'] === 'Object/MessageListItem') { this.seen(!!oData.IsSeen); this.flagged(!!oData.IsFlagged); this.answered(!!oData.IsAnswered); this.forwarded(!!oData.IsForwarded); if (oData.Custom) { this.Custom = oData.Custom; } } if (oData['@Object'] === 'Object/Message' || oData['@Object'] === 'Object/MessageListItem') { this.accountId(iAccountId); this.folder(oData.Folder); this.uid(Utils.pString(oData.Uid)); this.subject(Utils.pString(oData.Subject)); this.messageId(Utils.pString(oData.MessageId)); this.size(oData.Size); this.textSize(oData.TextSize); this.oDateModel.parse(oData.TimeStampInUTC); this.oFrom.parse(oData.From); this.oTo.parse(oData.To); this.fillFromOrToText(); this.oCc.parse(oData.Cc); this.oBcc.parse(oData.Bcc); this.oSender.parse(oData.Sender); this.oReplyTo.parse(oData.ReplyTo); this.fullDate(this.oDateModel.getFullDate()); this.fullFrom(this.oFrom.getFull()); this.to(this.oTo.getFull()); this.cc(this.oCc.getFull()); this.bcc(this.oBcc.getFull()); this.hasAttachments(!!oData.HasAttachments); this.hasIcalAttachment(!!oData.HasIcalAttachment); this.hasVcardAttachment(!!oData.HasVcardAttachment); if (oData['@Object'] === 'Object/MessageListItem' && bTrustThreadInfo) { this.threadUids(_.map(oData.Threads, function (iUid) { return iUid.toString(); }, this)); } this.importance(oData.Priority); if (_.isArray(oData.DraftInfo)) { this.draftInfo(oData.DraftInfo); } this.sensitivity(oData.Sensitivity); this.hash(Utils.pString(oData.Hash)); if (oData['@Object'] === 'Object/Message') { this.trimmed(oData.Trimmed); this.trimmedTextSize(oData.TrimmedTextSize); this.inReplyTo(oData.InReplyTo); this.references(oData.References); this.readingConfirmation(oData.ReadingConfirmation); sHtml = Utils.pString(oData.Html); sPlain = Utils.pString(oData.Plain); if (sHtml !== '') { this.text(sHtml); this.isPlain(false); } else { this.textRaw(oData.PlainRaw); if (this.textRaw().indexOf('-----BEGIN PGP MESSAGE-----') !== -1) { this.text('<pre>' + Utils.encodeHtml(this.textRaw()) + '</pre>'); this.encryptedMessage(true); } else if (this.textRaw().indexOf('-----BEGIN PGP SIGNED MESSAGE-----') !== -1) { this.text('<pre>' + Utils.encodeHtml(this.textRaw()) + '</pre>'); this.signedMessage(true); } else { this.text(sPlain !== '' ? '<div>' + sPlain + '</div>' : ''); } this.isPlain(true); } this.$text = null; this.isExternalsShown(false); this.rtl(oData.Rtl); this.hasExternals(!!oData.HasExternals); this.foundedCids(oData.FoundedCIDs); this.parseAttachments(oData.Attachments, iAccountId); this.safety(oData.Safety); this.sourceHeaders(oData.Headers); if (oData.ICAL !== null) { oIcal = new CIcalModel(); oIcal.parse(oData.ICAL, AppData.Accounts.getAttendee(this.oTo.getEmails())); this.ical(oIcal); } if (oData.VCARD !== null) { oVcard = new CVcardModel(); oVcard.parse(oData.VCARD); this.vcard(oVcard); } this.completelyFilled(true); } this.updateMomentDate(); } }; CMessageModel.prototype.updateMomentDate = function () { this.date(this.oDateModel.getShortDate(moment().clone().subtract('days', 1).format('L') === moment.unix(this.oDateModel.getTimeStampInUTC()).format('L'))); }; /** * @param {string=} sAppPath = '' * @param {boolean=} bForcedShowPictures * * return {Object} */ CMessageModel.prototype.getDomText = function (sAppPath, bForcedShowPictures) { var $text = this.$text; sAppPath = sAppPath || ''; if (this.$text === null || sAppPath !== '') { if (this.completelyFilled()) { this.$text = $(this.text()); this.showInlinePictures(sAppPath); if (this.safety() === true) { this.alwaysShowExternalPicturesForSender(); } if (bForcedShowPictures && this.isExternalsShown()) { this.showExternalPictures(); } $text = this.$text; } else { $text = $(''); } } //returns a clone, because it uses both in the parent window and the new return $text.clone(); }; /** * @param {string=} sAppPath = '' * @param {boolean=} bForcedShowPictures * * return {string} */ CMessageModel.prototype.getConvertedHtml = function (sAppPath, bForcedShowPictures) { var oDomText = this.getDomText(sAppPath, bForcedShowPictures); return (oDomText.length > 0) ? oDomText.wrap('<p>').parent().html() : ''; }; /** * Parses attachments. * * @param {Array} aData * @param {number} iAccountId */ CMessageModel.prototype.parseAttachments = function (aData, iAccountId) { if (_.isArray(aData)) { var sThumbSessionUid = Date.now().toString(); this.attachments(_.map(aData, function (oRawAttach) { var oAttachment = new CMailAttachmentModel(); oAttachment.parse(oRawAttach, iAccountId); oAttachment.getInThumbQueue(sThumbSessionUid); oAttachment.setMessageData(this.folder(), this.uid()); return oAttachment; }, this)); } }; /** * Parses an array of email addresses. * * @param {Array} aData * @return {Array} */ CMessageModel.prototype.parseAddressArray = function (aData) { var aAddresses = [] ; if (_.isArray(aData)) { aAddresses = _.map(aData, function (oRawAddress) { var oAddress = new CAddressModel(); oAddress.parse(oRawAddress); return oAddress; }); } return aAddresses; }; /** * Finds and returns the specified Attachment cid. * * @param {string} sCid * @return {*} */ CMessageModel.prototype.findAttachmentByCid = function (sCid) { return _.find(this.attachments(), function (oAttachment) { return oAttachment.cid() === sCid; }); }; /** * Finds and returns the specified Attachment Content Location. * * @param {string} sContentLocation * @return {*} */ CMessageModel.prototype.findAttachmentByContentLocation = function (sContentLocation) { return _.find(this.attachments(), function (oAttachment) { return oAttachment.contentLocation() === sContentLocation; }); }; /** * Displays embedded images, which have cid on the list. * * @param {string} sAppPath */ CMessageModel.prototype.showInlinePictures = function (sAppPath) { var self = this; if (this.foundedCids().length > 0) { $('[data-x-src-cid]', this.$text).each(function () { var sCid = $(this).attr('data-x-src-cid'), oAttachment = self.findAttachmentByCid(sCid) ; if (oAttachment && oAttachment.viewLink().length > 0) { $(this).attr('src', sAppPath + oAttachment.viewLink()); } }); $('[data-x-style-cid]', this.$text).each(function () { var sStyle = '', sName = $(this).attr('data-x-style-cid-name'), sCid = $(this).attr('data-x-style-cid'), oAttachment = self.findAttachmentByCid(sCid) ; if (oAttachment && oAttachment.viewLink().length > 0 && '' !== sName) { sStyle = Utils.trim($(this).attr('style')); sStyle = '' === sStyle ? '' : (';' === sStyle.substr(-1) ? sStyle + ' ' : sStyle + '; '); $(this).attr('style', sStyle + sName + ': url(\'' + oAttachment.viewLink() + '\')'); } }); } $('[data-x-src-location]', this.$text).each(function () { var sLocation = $(this).attr('data-x-src-location'), oAttachment = self.findAttachmentByContentLocation(sLocation) ; if (!oAttachment) { oAttachment = self.findAttachmentByCid(sLocation); } if (oAttachment && oAttachment.viewLink().length > 0) { $(this).attr('src', sAppPath + oAttachment.viewLink()); } }); }; /** * Display external images. */ CMessageModel.prototype.showExternalPictures = function () { $('[data-x-src]', this.$text).each(function () { $(this).attr('src', $(this).attr('data-x-src')).removeAttr('data-x-src'); }); $('[data-x-style-url]', this.$text).each(function () { var sStyle = Utils.trim($(this).attr('style')); sStyle = '' === sStyle ? '' : (';' === sStyle.substr(-1) ? sStyle + ' ' : sStyle + '; '); $(this).attr('style', sStyle + $(this).attr('data-x-style-url')).removeAttr('data-x-style-url'); }); this.isExternalsShown(true); }; /** * Sets a flag that external images are always displayed. */ CMessageModel.prototype.alwaysShowExternalPicturesForSender = function () { if (this.completelyFilled()) { this.isExternalsAlwaysShown(true); if (!this.isExternalsShown()) { this.showExternalPictures(); } } }; CMessageModel.prototype.openThread = function () { if (this.threadCountVisible()) { var sFolder = this.folder(); this.threadOpened(!this.threadOpened()); if (this.threadOpened()) { App.MailCache.showOpenedThreads(sFolder); } else { App.MailCache.hideThreads(this); setTimeout(function () { App.MailCache.showOpenedThreads(sFolder); }, 500); } } }; CMessageModel.prototype.downloadAllAttachments = function () { if (this.allAttachmentsHash !== '') { App.Api.downloadByUrl(Utils.getDownloadLinkByHash(this.accountId(), this.allAttachmentsHash)); } else { var aNotInlineAttachments = _.filter(this.attachments(), function (oAttach) { return !oAttach.linked(); }), aHashes = _.map(aNotInlineAttachments, function (oAttach) { return oAttach.hash(); }) ; App.Ajax.send({ 'Action': 'MessageZipAttachments', 'Hashes': aHashes }, this.onMessageZipAttachments, this); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CMessageModel.prototype.onMessageZipAttachments = function (oResponse, oRequest) { if (oResponse.Result) { this.allAttachmentsHash = oResponse.Result; App.Api.downloadByUrl(Utils.getDownloadLinkByHash(this.accountId(), this.allAttachmentsHash)); } }; CMessageModel.prototype.saveAttachmentsToFiles = function () { var aNotInlineAttachments = _.filter(this.attachments(), function (oAttach) { return !oAttach.linked(); }), aHashes = _.map(aNotInlineAttachments, function (oAttach) { return oAttach.hash(); }) ; App.filesRecievedAnim(true); App.Ajax.send({ 'Action': 'MessageAttachmentsSaveToFiles', 'Attachments': aHashes }, this.onMessageAttachmentsSaveToFilesResponse, this); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CMessageModel.prototype.onMessageAttachmentsSaveToFilesResponse = function (oResponse, oRequest) { var iSavedCount = 0, iTotalCount = oRequest.Attachments.length ; if (oResponse.Result) { _.each(oRequest.Attachments, function (sHash) { if (oResponse.Result[sHash] !== undefined) { iSavedCount++; } }); } if (iSavedCount === 0) { App.Api.showError(Utils.i18n('MESSAGE/ERROR_ATTACHMENTS_SAVED_TO_FILES')); } else if (iSavedCount < iTotalCount) { App.Api.showError(Utils.i18n('MESSAGE/WARNING_ATTACHMENTS_SAVED_TO_FILES', { 'SAVED_COUNT': iSavedCount, 'TOTAL_COUNT': iTotalCount })); } else { App.Api.showReport(Utils.i18n('MESSAGE/REPORT_ATTACHMENTS_SAVED_TO_FILES')); } }; CMessageModel.prototype.downloadAllAttachmentsSeparately = function () { _.each(this.attachments(), function (oAttach) { if (!oAttach.linked()) { oAttach.downloadFile(App); } }); }; /** * Uses for logging. * * @returns {Object} */ CMessageModel.prototype.toJSON = function () { return { uid: this.uid(), accountId: this.accountId(), to: this.to(), subject: this.subject(), threadPart: this.threadPart(), threadUids: this.threadUids(), threadOpened: this.threadOpened() }; }; /** * @constructor * * !!!Attention!!! * It is not used underscore, because the collection may contain undefined-elements. * They have their own importance. But all underscore-functions removes them automatically. */ function CUidListModel() { this.resultCount = ko.observable(-1); this.search = ko.observable(''); this.filters = ko.observable(''); this.collection = ko.observableArray([]); this.threadUids = {}; } /** * @param {string} sUid * @param {Array} aThreadUids */ CUidListModel.prototype.addThreadUids = function (sUid, aThreadUids) { if (-1 !== _.indexOf(this.collection(), sUid)) { this.threadUids[sUid] = aThreadUids; } }; /** * @param {Object} oResult */ CUidListModel.prototype.setUidsAndCount = function (oResult) { if (oResult['@Object'] === 'Collection/MessageCollection') { _.each(oResult.Uids, function (sUid, iIndex) { this.collection()[iIndex + oResult.Offset] = sUid.toString(); }, this); this.resultCount(oResult.MessageResultCount); } }; /** * @param {number} iOffset * @param {Object} oMessages */ CUidListModel.prototype.getUidsForOffset = function (iOffset, oMessages) { var iIndex = 0, iLen = this.collection().length, sUid = '', iExistsCount = 0, aUids = [], oMsg = null ; for(; iIndex < iLen; iIndex++) { if (iIndex >= iOffset && iExistsCount < AppData.User.MailsPerPage) { sUid = this.collection()[iIndex]; oMsg = oMessages[sUid]; if (oMsg && !oMsg.deleted() || sUid === undefined) { iExistsCount++; if (sUid !== undefined) { aUids.push(sUid); } } } } return aUids; }; /** * @param {Array} aUids */ CUidListModel.prototype.deleteUids = function (aUids) { var iIndex = 0, iLen = this.collection().length, sUid = '', aNewCollection = [], iDiff = 0 ; for (; iIndex < iLen; iIndex++) { sUid = this.collection()[iIndex]; if (_.indexOf(aUids, sUid) === -1) { aNewCollection.push(sUid); } else { iDiff++; } } this.collection(aNewCollection); this.resultCount(this.resultCount() - iDiff); }; /** * @constructor */ function CIcalModel() { this.uid = ko.observable(''); this.file = ko.observable(''); this.attendee = ko.observable(''); this.type = ko.observable(''); this.icalType = ko.observable(''); this.icalConfig = ko.observable(''); this.type.subscribe(function () { var aTypeParts = this.type().split('-'), sType = aTypeParts.shift(), sFoundType = _.find(Enums.IcalType, function (sIcalType) { return sType === sIcalType; }, this), sConfig = aTypeParts.join('-'), sFoundConfig = _.find(Enums.IcalConfig, function (sIcalConfig) { return sConfig === sIcalConfig; }, this) ; if (sType !== sFoundType) { sType = Enums.IcalType.Save; } this.icalType(sType); if (sConfig !== sFoundConfig) { sConfig = Enums.IcalConfig.NeedsAction; } this.icalConfig(sConfig); }, this); this.isRequestType = ko.computed(function () { return this.icalType() === Enums.IcalType.Request; }, this); this.isCancelType = ko.computed(function () { return this.icalType() === Enums.IcalType.Cancel; }, this); this.cancelDecision = ko.observable(''); this.isReplyType = ko.computed(function () { return this.icalType() === Enums.IcalType.Reply; }, this); this.replyDecision = ko.observable(''); this.isSaveType = ko.computed(function () { return this.icalType() === Enums.IcalType.Save; }, this); this.isJustSaved = ko.observable(false); this.fillDecisions(); this.isAccepted = ko.computed(function () { return this.icalConfig() === Enums.IcalConfig.Accepted; }, this); this.isDeclined = ko.computed(function () { return this.icalConfig() === Enums.IcalConfig.Declined; }, this); this.isTentative = ko.computed(function () { return this.icalConfig() === Enums.IcalConfig.Tentative; }, this); this.location = ko.observable(''); this.description = ko.observable(''); this.when = ko.observable(''); this.calendarId = ko.observable(''); this.calendars = ko.observableArray([]); if (AppData.SingleMode && window.opener) { this.calendars(window.opener.App.CalendarCache.calendars()); window.opener.App.CalendarCache.calendars.subscribe(function () { this.calendars(window.opener.App.CalendarCache.calendars()); }, this); } else { this.calendars(App.CalendarCache.calendars()); App.CalendarCache.calendars.subscribe(function () { this.calendars(App.CalendarCache.calendars()); }, this); } this.selectedCalendarId = ko.observable(''); this.chosenCalendarName = ko.computed(function () { var oFoundCal = null; if (this.calendarId() !== '') { oFoundCal = _.find(this.calendars(), function (oCal) { return oCal.id === this.calendarId(); }, this); } return oFoundCal ? oFoundCal.name : ''; }, this); this.calendarIsChosen = ko.computed(function () { return this.chosenCalendarName() !== ''; }, this); this.visibleCalendarDropdown = ko.computed(function () { return !this.calendarIsChosen() && this.calendars().length > 1 && (this.isRequestType() || this.isSaveType()); }, this); this.visibleCalendarName = ko.computed(function () { return this.calendarIsChosen(); }, this); this.visibleFirstCalendarName = ko.computed(function () { return this.calendars().length === 1 && !this.calendarIsChosen(); }, this); this.visibleCalendarRow = ko.computed(function () { return this.attendee() !== '' && (this.visibleCalendarDropdown() || this.visibleCalendarName() || this.visibleFirstCalendarName()); }, this); this.visibleRequestButtons = ko.computed(function () { return this.isRequestType() && this.attendee() !== ''; }, this); // animation of buttons turns on with delay // so it does not trigger when placing initial values this.animation = ko.observable(false); } CIcalModel.prototype.fillDecisions = function () { var oAccount = AppData.Accounts.getCurrent(), sSender = oAccount ? oAccount.email() : '' ; this.cancelDecision(Utils.i18n('MESSAGE/APPOINTMENT_CANCELED', {'SENDER': sSender})); switch (this.icalConfig()) { case Enums.IcalConfig.Accepted: this.replyDecision(Utils.i18n('MESSAGE/APPOINTMENT_ACCEPTED', {'SENDER': sSender})); break; case Enums.IcalConfig.Declined: this.replyDecision(Utils.i18n('MESSAGE/APPOINTMENT_DECLINED', {'SENDER': sSender})); break; case Enums.IcalConfig.Tentative: this.replyDecision(Utils.i18n('MESSAGE/APPOINTMENT_TENTATIVELY_ACCEPTED', {'SENDER': sSender})); break; } }; /** * @param {AjaxIcsResponse} oData * @param {string} sAttendee */ CIcalModel.prototype.parse = function (oData, sAttendee) { var sDescription = ''; if (oData && oData['@Object'] === 'Object/CApiMailIcs') { sDescription = Utils.pString(oData.Description); this.uid(Utils.pString(oData.Uid)); this.file(Utils.pString(oData.File)); this.attendee(Utils.pString(oData.Attendee) || sAttendee); this.type(oData.Type); this.location(Utils.pString(oData.Location)); this.description(sDescription.replace(/\r/g, '').replace(/\n/g,"<br />")); this.when(Utils.pString(oData.When)); this.calendarId(Utils.pString(oData.CalendarId)); this.selectedCalendarId(Utils.pString(oData.CalendarId)); App.CalendarCache.addIcal(this); } }; CIcalModel.prototype.acceptAppointment = function () { this.calendarId(this.selectedCalendarId()); this.changeAndSaveConfig(Enums.IcalConfig.Accepted); }; CIcalModel.prototype.tentativeAppointment = function () { this.calendarId(this.selectedCalendarId()); this.changeAndSaveConfig(Enums.IcalConfig.Tentative); }; CIcalModel.prototype.declineAppointment = function () { this.calendarId(''); this.selectedCalendarId(''); this.changeAndSaveConfig(Enums.IcalConfig.Declined); }; /** * @param {string} sConfig */ CIcalModel.prototype.changeAndSaveConfig = function (sConfig) { if (this.icalConfig() !== sConfig) { if (this.icalConfig() !== sConfig && (sConfig !== Enums.IcalConfig.Declined || this.icalConfig() !== Enums.IcalConfig.NeedsAction)) { App.CalendarCache.recivedAnim(true); } this.changeConfig(sConfig); this.doAppointmentAction(); } }; /** * @param {string} sConfig */ CIcalModel.prototype.changeConfig = function (sConfig) { this.type(this.icalType() + '-' + sConfig); if (AppData.SingleMode && window.opener) { window.opener.App.CalendarCache.markIcalTypeByFile(this.file(), this.type(), this.cancelDecision(), this.replyDecision(), this.calendarId(), this.selectedCalendarId()); } else { App.CalendarCache.markIcalTypeByFile(this.file(), this.type(), this.cancelDecision(), this.replyDecision(), this.calendarId(), this.selectedCalendarId()); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CIcalModel.prototype.onAppointmentActionResponse = function (oResponse, oRequest) { if (!oResponse.Result) { App.Api.showErrorByCode(oResponse, Utils.i18n('WARNING/UNKNOWN_ERROR')); } else if (App.CalendarCache) { App.CalendarCache.calendarChanged(true); } }; CIcalModel.prototype.doAppointmentAction = function () { var oParameters = { 'Action': 'AppointmentAction', 'AppointmentAction': this.icalConfig(), 'CalendarId': this.selectedCalendarId(), 'File': this.file(), 'Attendee': this.attendee() } ; App.Ajax.send(oParameters, this.onAppointmentActionResponse, this); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CIcalModel.prototype.onAddEventResponse = function (oResponse, oRequest) { if (!oResponse.Result) { App.Api.showErrorByCode(oResponse); } else { if (oResponse.Result.Uid) { this.uid(oResponse.Result.Uid); } if (App.CalendarCache) { App.CalendarCache.calendarChanged(true); } } }; CIcalModel.prototype.addEvent = function () { var oParameters = { 'Action': 'SaveIcs', 'CalendarId': this.selectedCalendarId(), 'File': this.file() } ; App.Ajax.send(oParameters, this.onAddEventResponse, this); this.isJustSaved(true); this.calendarId(this.selectedCalendarId()); setTimeout(_.bind(function () { this.isJustSaved(false); }, this), 20000); App.CalendarCache.recivedAnim(true); }; CIcalModel.prototype.onEventDelete = function () { this.calendarId(''); this.selectedCalendarId(''); this.changeConfig(Enums.IcalConfig.NeedsAction); }; CIcalModel.prototype.onEventTentative = function () { this.changeConfig(Enums.IcalConfig.Tentative); }; CIcalModel.prototype.onEventAccept = function () { this.changeConfig(Enums.IcalConfig.Accepted); }; CIcalModel.prototype.firstCalendarName = function () { return this.calendars()[0] ? this.calendars()[0].name : ''; }; /** * @param {string} sEmail */ CIcalModel.prototype.updateAttendeeStatus = function (sEmail) { if (this.icalType() === Enums.IcalType.Cancel || this.icalType() === Enums.IcalType.Reply) { var oParameters = { 'Action': 'UpdateAttendeeStatus', 'File': this.file(), 'FromEmail': sEmail } ; App.Ajax.send(oParameters, this.onUpdateAttendeeStatusResponse, this); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CIcalModel.prototype.onUpdateAttendeeStatusResponse = function (oResponse, oRequest) { if (oResponse.Result && App.CalendarCache) { App.CalendarCache.recivedAnim(true); App.CalendarCache.calendarChanged(true); } }; /** * @constructor */ function CVcardModel() { this.uid = ko.observable(''); this.file = ko.observable(''); this.name = ko.observable(''); this.email = ko.observable(''); this.isExists = ko.observable(false); this.isJustSaved = ko.observable(false); } /** * @param {AjaxVCardResponse} oData */ CVcardModel.prototype.parse = function (oData) { if (oData && oData['@Object'] === 'Object/CApiMailVcard') { this.uid(Utils.pString(oData.Uid)); this.file(Utils.pString(oData.File)); this.name(Utils.pString(oData.Name)); this.email(Utils.pString(oData.Email)); this.isExists(!!oData.Exists); App.ContactsCache.addVcard(this); } }; /** * @param {Object} oData * @param {Object} oParameters */ CVcardModel.prototype.onAddContactResponse = function (oData, oParameters) { if (oData && oData.Result && oData.Result.Uid) { this.uid(oData.Result.Uid); } }; CVcardModel.prototype.addContact = function () { var oParameters = { 'Action': 'SaveVcf', 'File': this.file() } ; App.Ajax.send(oParameters, this.onAddContactResponse, this); this.isJustSaved(true); this.isExists(true); setTimeout(_.bind(function () { this.isJustSaved(false); }, this), 20000); App.ContactsCache.recivedAnim(true); if (AppData.SingleMode && window.opener) { window.opener.App.ContactsCache.markVcardExistentByFile(this.file()); } else { App.ContactsCache.markVcardExistentByFile(this.file()); } }; /** * @constructor */ function CContactModel() { this.sEmailDefaultType = Enums.ContactEmailType.Personal; this.sPhoneDefaultType = Enums.ContactPhoneType.Mobile; this.sAddressDefaultType = Enums.ContactAddressType.Personal; this.voiceApp = null; if (App.Phone) { this.voiceApp = App.Phone.voiceApp; } this.idContact = ko.observable(''); this.idUser = ko.observable(''); this.global = ko.observable(false); this.itsMe = ko.observable(false); this.isNew = ko.observable(false); this.readOnly = ko.observable(false); this.edited = ko.observable(false); this.extented = ko.observable(false); this.personalCollapsed = ko.observable(false); this.businessCollapsed = ko.observable(false); this.otherCollapsed = ko.observable(false); this.groupsCollapsed = ko.observable(false); this.displayName = ko.observable(''); this.firstName = ko.observable(''); this.lastName = ko.observable(''); this.nickName = ko.observable(''); this.skype = ko.observable(''); this.facebook = ko.observable(''); this.displayNameFocused = ko.observable(false); this.primaryEmail = ko.observable(this.sEmailDefaultType); this.primaryPhone = ko.observable(this.sPhoneDefaultType); this.primaryAddress = ko.observable(this.sAddressDefaultType); this.mainPrimaryEmail = ko.computed({ 'read': this.primaryEmail, 'write': function (mValue) { if (!Utils.isUnd(mValue) && 0 <= Utils.inArray(mValue, [Enums.ContactEmailType.Personal, Enums.ContactEmailType.Business, Enums.ContactEmailType.Other])) { this.primaryEmail(mValue); } else { this.primaryEmail(Enums.ContactEmailType.Personal); } }, 'owner': this }); this.mainPrimaryPhone = ko.computed({ 'read': this.primaryPhone, 'write': function (mValue) { if (!Utils.isUnd(mValue) && 0 <= Utils.inArray(mValue, [Enums.ContactPhoneType.Mobile, Enums.ContactPhoneType.Personal, Enums.ContactPhoneType.Business])) { this.primaryPhone(mValue); } else { this.primaryPhone(Enums.ContactPhoneType.Mobile); } }, 'owner': this }); this.mainPrimaryAddress = ko.computed({ 'read': this.primaryAddress, 'write': function (mValue) { if (!Utils.isUnd(mValue) && 0 <= Utils.inArray(mValue, [Enums.ContactAddressType.Personal, Enums.ContactAddressType.Business])) { this.primaryAddress(mValue); } else { this.primaryAddress(Enums.ContactAddressType.Personal); } }, 'owner': this }); this.personalEmail = ko.observable(''); this.personalStreetAddress = ko.observable(''); this.personalCity = ko.observable(''); this.personalState = ko.observable(''); this.personalZipCode = ko.observable(''); this.personalCountry = ko.observable(''); this.personalWeb = ko.observable(''); this.personalFax = ko.observable(''); this.personalPhone = ko.observable(''); this.personalMobile = ko.observable(''); this.businessEmail = ko.observable(''); this.businessCompany = ko.observable(''); this.businessDepartment = ko.observable(''); this.businessJob = ko.observable(''); this.businessOffice = ko.observable(''); this.businessStreetAddress = ko.observable(''); this.businessCity = ko.observable(''); this.businessState = ko.observable(''); this.businessZipCode = ko.observable(''); this.businessCountry = ko.observable(''); this.businessWeb = ko.observable(''); this.businessFax = ko.observable(''); this.businessPhone = ko.observable(''); this.otherEmail = ko.observable(''); this.otherBirthdayMonth = ko.observable('0'); this.otherBirthdayDay = ko.observable('0'); this.otherBirthdayYear = ko.observable('0'); this.otherNotes = ko.observable(''); this.etag = ko.observable(''); this.sharedToAll = ko.observable(false); this.birthdayIsEmpty = ko.computed(function () { var bMonthEmpty = '0' === this.otherBirthdayMonth(), bDayEmpty = '0' === this.otherBirthdayDay(), bYearEmpty = '0' === this.otherBirthdayYear() ; return (bMonthEmpty || bDayEmpty || bYearEmpty); }, this); this.otherBirthday = ko.computed(function () { var sBirthday = '', iYear = Utils.pInt(this.otherBirthdayYear()), iMonth = Utils.pInt(this.otherBirthdayMonth()), iDay = Utils.pInt(this.otherBirthdayDay()), oDateModel = new CDateModel() ; if (!this.birthdayIsEmpty()) { oDateModel.setDate(iYear, 0 < iMonth ? iMonth - 1 : 0, iDay); sBirthday = oDateModel.getShortDate(); } return sBirthday; }, this); this.groups = ko.observableArray([]); this.groupsIsEmpty = ko.computed(function () { return 0 === this.groups().length; }, this); this.email = ko.computed({ 'read': function () { var sResult = ''; switch (this.primaryEmail()) { case Enums.ContactEmailType.Personal: sResult = this.personalEmail(); break; case Enums.ContactEmailType.Business: sResult = this.businessEmail(); break; case Enums.ContactEmailType.Other: sResult = this.otherEmail(); break; } return sResult; }, 'write': function (sEmail) { switch (this.primaryEmail()) { case Enums.ContactEmailType.Personal: this.personalEmail(sEmail); break; case Enums.ContactEmailType.Business: this.businessEmail(sEmail); break; case Enums.ContactEmailType.Other: this.otherEmail(sEmail); break; default: this.primaryEmail(this.sEmailDefaultType); this.email(sEmail); break; } }, 'owner': this }); this.personalIsEmpty = ko.computed(function () { var sPersonalEmail = (this.personalEmail() !== this.email()) ? this.personalEmail() : ''; return '' === '' + sPersonalEmail + this.personalStreetAddress() + this.personalCity() + this.personalState() + this.personalZipCode() + this.personalCountry() + this.personalWeb() + this.personalFax() + this.personalPhone() + this.personalMobile() ; }, this); this.businessIsEmpty = ko.computed(function () { var sBusinessEmail = (this.businessEmail() !== this.email()) ? this.businessEmail() : ''; return '' === '' + sBusinessEmail + this.businessCompany() + this.businessDepartment() + this.businessJob() + this.businessOffice() + this.businessStreetAddress() + this.businessCity() + this.businessState() + this.businessZipCode() + this.businessCountry() + this.businessWeb() + this.businessFax() + this.businessPhone() ; }, this); this.otherIsEmpty = ko.computed(function () { var sOtherEmail = (this.otherEmail() !== this.email()) ? this.otherEmail() : ''; return ('' === ('' + sOtherEmail + this.otherNotes())) && this.birthdayIsEmpty(); }, this); this.phone = ko.computed({ 'read': function () { var sResult = ''; switch (this.primaryPhone()) { case Enums.ContactPhoneType.Mobile: sResult = this.personalMobile(); break; case Enums.ContactPhoneType.Personal: sResult = this.personalPhone(); break; case Enums.ContactPhoneType.Business: sResult = this.businessPhone(); break; } return sResult; }, 'write': function (sPhone) { switch (this.primaryPhone()) { case Enums.ContactPhoneType.Mobile: this.personalMobile(sPhone); break; case Enums.ContactPhoneType.Personal: this.personalPhone(sPhone); break; case Enums.ContactPhoneType.Business: this.businessPhone(sPhone); break; default: this.primaryPhone(this.sEmailDefaultType); this.phone(sPhone); break; } }, 'owner': this }); this.address = ko.computed({ 'read': function () { var sResult = ''; switch (this.primaryAddress()) { case Enums.ContactAddressType.Personal: sResult = this.personalStreetAddress(); break; case Enums.ContactAddressType.Business: sResult = this.businessStreetAddress(); break; } return sResult; }, 'write': function (sAddress) { switch (this.primaryAddress()) { case Enums.ContactAddressType.Personal: this.personalStreetAddress(sAddress); break; case Enums.ContactAddressType.Business: this.businessStreetAddress(sAddress); break; default: this.primaryAddress(this.sEmailDefaultType); this.address(sAddress); break; } }, 'owner': this }); this.emails = ko.computed(function () { var aList = []; if ('' !== this.personalEmail()) { aList.push({'text': Utils.i18n('CONTACTS/OPTION_PERSONAL') + ': ' + this.personalEmail(), 'value': Enums.ContactEmailType.Personal}); } if ('' !== this.businessEmail()) { aList.push({'text': Utils.i18n('CONTACTS/OPTION_BUSINESS') + ': ' + this.businessEmail(), 'value': Enums.ContactEmailType.Business}); } if ('' !== this.otherEmail()) { aList.push({'text': Utils.i18n('CONTACTS/OPTION_OTHER') + ': ' + this.otherEmail(), 'value': Enums.ContactEmailType.Other}); } return aList; }, this); this.phones = ko.computed(function () { var aList = []; if ('' !== this.personalMobile()) { aList.push({'text': Utils.i18n('CONTACTS/LABEL_MOBILE') + ': ' + this.personalMobile(), 'value': Enums.ContactPhoneType.Mobile}); } if ('' !== this.personalPhone()) { aList.push({'text': Utils.i18n('CONTACTS/OPTION_PERSONAL') + ': ' + this.personalPhone(), 'value': Enums.ContactPhoneType.Personal}); } if ('' !== this.businessPhone()) { aList.push({'text': Utils.i18n('CONTACTS/OPTION_BUSINESS') + ': ' + this.businessPhone(), 'value': Enums.ContactPhoneType.Business}); } return aList; }, this); this.addresses = ko.computed(function () { var aList = []; if ('' !== this.personalStreetAddress()) { aList.push({'text': Utils.i18n('CONTACTS/OPTION_PERSONAL') + ': ' + this.personalStreetAddress(), 'value': Enums.ContactAddressType.Personal}); } if ('' !== this.businessStreetAddress()) { aList.push({'text': Utils.i18n('CONTACTS/OPTION_BUSINESS') + ': ' + this.businessStreetAddress(), 'value': Enums.ContactAddressType.Business}); } return aList; }, this); this.hasEmails = ko.computed(function () { return 0 < this.emails().length; }, this); this.extented.subscribe(function (bValue) { if (bValue) { this.personalCollapsed(!this.personalIsEmpty()); this.businessCollapsed(!this.businessIsEmpty()); this.otherCollapsed(!this.otherIsEmpty()); this.groupsCollapsed(!this.groupsIsEmpty()); } }, this); this.birthdayMonthSelect = CContactModel.birthdayMonthSelect; this.birthdayYearSelect = CContactModel.birthdayYearSelect; this.birthdayDaySelect = ko.computed(function () { var iIndex = 1, iLen = Utils.pInt(Utils.daysInMonth(this.otherBirthdayMonth(), this.otherBirthdayYear())), sIndex = '', aList = [{'text': Utils.i18n('DATETIME/DAY'), 'value': '0'}] ; for (; iIndex <= iLen; iIndex++) { sIndex = iIndex.toString(); aList.push({'text': sIndex, 'value': sIndex}); } return aList; }, this); for (var oDate = new Date(), sIndex = '', iIndex = oDate.getFullYear(), iLen = 2012 - 80; iIndex >= iLen; iIndex--) { sIndex = iIndex.toString(); this.birthdayYearSelect.push( {'text': sIndex, 'value': sIndex} ); } this.canBeSave = ko.computed(function () { return this.displayName() !== '' || !!this.emails().length; }, this); this.sendMailLink = ko.computed(function () { return this.getSendMailLink(this.email()); }, this); this.sendMailToPersonalLink = ko.computed(function () { return this.getSendMailLink(this.personalEmail()); }, this); this.sendMailToBusinessLink = ko.computed(function () { return this.getSendMailLink(this.businessEmail()); }, this); this.sendMailToOtherLink = ko.computed(function () { return this.getSendMailLink(this.otherEmail()); }, this); } CContactModel.birthdayMonths = Utils.getMonthNamesArray(); CContactModel.birthdayMonthSelect = [ {'text': Utils.i18n('DATETIME/MONTH'), value: '0'}, {'text': CContactModel.birthdayMonths[0], value: '1'}, {'text': CContactModel.birthdayMonths[1], value: '2'}, {'text': CContactModel.birthdayMonths[2], value: '3'}, {'text': CContactModel.birthdayMonths[3], value: '4'}, {'text': CContactModel.birthdayMonths[4], value: '5'}, {'text': CContactModel.birthdayMonths[5], value: '6'}, {'text': CContactModel.birthdayMonths[6], value: '7'}, {'text': CContactModel.birthdayMonths[7], value: '8'}, {'text': CContactModel.birthdayMonths[8], value: '9'}, {'text': CContactModel.birthdayMonths[9], value: '10'}, {'text': CContactModel.birthdayMonths[10], value: '11'}, {'text': CContactModel.birthdayMonths[11], value: '12'} ]; CContactModel.birthdayYearSelect = [ {'text': Utils.i18n('DATETIME/YEAR'), 'value': '0'} ]; /** * @param {string} sEmail * @return {string} */ CContactModel.prototype.getSendMailLink = function (sEmail) { var sFullEmail = this.getFullEmail(sEmail), aLinkParts = App.Links.composeWithToField(sFullEmail), sLink = App.Routing.buildHashFromArray(aLinkParts) ; return sLink; }; CContactModel.prototype.clear = function () { this.isNew(false); this.readOnly(false); this.idContact(''); this.idUser(''); this.global(false); this.itsMe(false); this.edited(false); this.extented(false); this.personalCollapsed(false); this.businessCollapsed(false); this.otherCollapsed(false); this.groupsCollapsed(false); this.displayName(''); this.firstName(''); this.lastName(''); this.nickName(''); this.skype(''); this.facebook(''); this.primaryEmail(this.sEmailDefaultType); this.primaryPhone(this.sPhoneDefaultType); this.primaryAddress(this.sAddressDefaultType); this.personalEmail(''); this.personalStreetAddress(''); this.personalCity(''); this.personalState(''); this.personalZipCode(''); this.personalCountry(''); this.personalWeb(''); this.personalFax(''); this.personalPhone(''); this.personalMobile(''); this.businessEmail(''); this.businessCompany(''); this.businessDepartment(''); this.businessJob(''); this.businessOffice(''); this.businessStreetAddress(''); this.businessCity(''); this.businessState(''); this.businessZipCode(''); this.businessCountry(''); this.businessWeb(''); this.businessFax(''); this.businessPhone(''); this.otherEmail(''); this.otherBirthdayMonth('0'); this.otherBirthdayDay('0'); this.otherBirthdayYear('0'); this.otherNotes(''); this.etag(''); this.sharedToAll(false); this.groups([]); }; CContactModel.prototype.switchToNew = function () { this.clear(); this.edited(true); this.extented(false); this.isNew(true); if (!bMobileApp) { this.displayNameFocused(true); } }; CContactModel.prototype.switchToView = function () { this.edited(false); this.extented(false); }; /** * @return {Object} */ CContactModel.prototype.toObject = function () { var oResult = { 'ContactId': this.idContact(), 'PrimaryEmail': this.primaryEmail(), 'PrimaryPhone': this.primaryPhone(), 'PrimaryAddress': this.primaryAddress(), 'UseFriendlyName': '1', 'Title': '', 'FullName': this.displayName(), 'FirstName': this.firstName(), 'LastName': this.lastName(), 'NickName': this.nickName(), 'Global': this.global() ? '1' : '0', 'ItsMe': this.itsMe() ? '1' : '0', 'Skype': this.skype(), 'Facebook': this.facebook(), 'HomeEmail': this.personalEmail(), 'HomeStreet': this.personalStreetAddress(), 'HomeCity': this.personalCity(), 'HomeState': this.personalState(), 'HomeZip': this.personalZipCode(), 'HomeCountry': this.personalCountry(), 'HomeFax': this.personalFax(), 'HomePhone': this.personalPhone(), 'HomeMobile': this.personalMobile(), 'HomeWeb': this.personalWeb(), 'BusinessEmail': this.businessEmail(), 'BusinessCompany': this.businessCompany(), 'BusinessJobTitle': this.businessJob(), 'BusinessDepartment': this.businessDepartment(), 'BusinessOffice': this.businessOffice(), 'BusinessStreet': this.businessStreetAddress(), 'BusinessCity': this.businessCity(), 'BusinessState': this.businessState(), 'BusinessZip': this.businessZipCode(), 'BusinessCountry': this.businessCountry(), 'BusinessFax': this.businessFax(), 'BusinessPhone': this.businessPhone(), 'BusinessWeb': this.businessWeb(), 'OtherEmail': this.otherEmail(), 'Notes': this.otherNotes(), 'ETag': this.etag(), 'BirthdayDay': this.otherBirthdayDay(), 'BirthdayMonth': this.otherBirthdayMonth(), 'BirthdayYear': this.otherBirthdayYear(), 'SharedToAll': this.sharedToAll() ? '1' : '0', 'GroupsIds': this.groups() }; return oResult; }; /** * @param {Object} oData */ CContactModel.prototype.parse = function (oData) { if (oData && 'Object/CContact' === oData['@Object']) { var iPrimaryEmail = 0, iPrimaryPhone = 0, iPrimaryAddress = 0, aGroupsIds = [] ; this.idContact(Utils.pExport(oData, 'IdContact', '').toString()); this.idUser(Utils.pExport(oData, 'IdUser', '').toString()); this.global(!!Utils.pExport(oData, 'Global', false)); this.itsMe(!!Utils.pExport(oData, 'ItsMe', false)); this.readOnly(!!Utils.pExport(oData, 'ReadOnly', false)); this.displayName(Utils.pExport(oData, 'FullName', '')); this.firstName(Utils.pExport(oData, 'FirstName', '')); this.lastName(Utils.pExport(oData, 'LastName', '')); this.nickName(Utils.pExport(oData, 'NickName', '')); this.skype(Utils.pExport(oData, 'Skype', '')); this.facebook(Utils.pExport(oData, 'Facebook', '')); iPrimaryEmail = Utils.pInt(Utils.pExport(oData, 'PrimaryEmail', 0)); switch (iPrimaryEmail) { case 1: iPrimaryEmail = Enums.ContactEmailType.Business; break; case 2: iPrimaryEmail = Enums.ContactEmailType.Other; break; default: case 0: iPrimaryEmail = Enums.ContactEmailType.Personal; break; } this.primaryEmail(iPrimaryEmail); iPrimaryPhone = Utils.pInt(Utils.pExport(oData, 'PrimaryPhone', 0)); switch (iPrimaryPhone) { case 2: iPrimaryPhone = Enums.ContactPhoneType.Business; break; case 1: iPrimaryPhone = Enums.ContactPhoneType.Personal; break; default: case 0: iPrimaryPhone = Enums.ContactPhoneType.Mobile; break; } this.primaryPhone(iPrimaryPhone); iPrimaryAddress = Utils.pInt(Utils.pExport(oData, 'PrimaryAddress', 0)); switch (iPrimaryAddress) { case 1: iPrimaryAddress = Enums.ContactAddressType.Business; break; default: case 0: iPrimaryAddress = Enums.ContactAddressType.Personal; break; } this.primaryAddress(iPrimaryAddress); this.personalEmail(Utils.pExport(oData, 'HomeEmail', '')); this.personalStreetAddress(Utils.pExport(oData, 'HomeStreet', '')); this.personalCity(Utils.pExport(oData, 'HomeCity', '')); this.personalState(Utils.pExport(oData, 'HomeState', '')); this.personalZipCode(Utils.pExport(oData, 'HomeZip', '')); this.personalCountry(Utils.pExport(oData, 'HomeCountry', '')); this.personalWeb(Utils.pExport(oData, 'HomeWeb', '')); this.personalFax(Utils.pExport(oData, 'HomeFax', '')); this.personalPhone(Utils.pExport(oData, 'HomePhone', '')); this.personalMobile(Utils.pExport(oData, 'HomeMobile', '')); this.businessEmail(Utils.pExport(oData, 'BusinessEmail', '')); this.businessCompany(Utils.pExport(oData, 'BusinessCompany', '')); this.businessDepartment(Utils.pExport(oData, 'BusinessDepartment', '')); this.businessJob(Utils.pExport(oData, 'BusinessJobTitle', '')); this.businessOffice(Utils.pExport(oData, 'BusinessOffice', '')); this.businessStreetAddress(Utils.pExport(oData, 'BusinessStreet', '')); this.businessCity(Utils.pExport(oData, 'BusinessCity', '')); this.businessState(Utils.pExport(oData, 'BusinessState', '')); this.businessZipCode(Utils.pExport(oData, 'BusinessZip', '')); this.businessCountry(Utils.pExport(oData, 'BusinessCountry', '')); this.businessWeb(Utils.pExport(oData, 'BusinessWeb', '')); this.businessFax(Utils.pExport(oData, 'BusinessFax', '')); this.businessPhone(Utils.pExport(oData, 'BusinessPhone', '')); this.otherEmail(Utils.pExport(oData, 'OtherEmail', '')); this.otherBirthdayMonth(Utils.pExport(oData, 'BirthdayMonth', '0').toString()); this.otherBirthdayDay(Utils.pExport(oData, 'BirthdayDay', '0').toString()); this.otherBirthdayYear(Utils.pExport(oData, 'BirthdayYear', '0').toString()); this.otherNotes(Utils.pExport(oData, 'Notes', '')); this.etag(Utils.pExport(oData, 'ETag', '')); this.sharedToAll(!!Utils.pExport(oData, 'SharedToAll', false)); aGroupsIds = Utils.pExport(oData, 'GroupsIds', []); if (_.isArray(aGroupsIds)) { this.groups(aGroupsIds); } } }; /** * @param {string} sEmail * @return {string} */ CContactModel.prototype.getFullEmail = function (sEmail) { var sFullEmail = sEmail; if (this.displayName() !== '') { if (sEmail !== '') { sFullEmail = '"' + this.displayName() + '" <' + sEmail + '>'; } else { sFullEmail = this.displayName(); } } return sFullEmail; }; CContactModel.prototype.getEmailsString = function () { return _.uniq(_.without([this.email(), this.personalEmail(), this.businessEmail(), this.otherEmail()], '')).join(','); }; CContactModel.prototype.viewAllMails = function () { App.MailCache.searchMessagesInInbox('email:' + this.getEmailsString()); }; CContactModel.prototype.sendThisContact = function () { App.Routing.goDirectly(App.Links.compose(), ['vcard', this]); }; /** * @param {?} mLink * @return {boolean} */ CContactModel.prototype.isStrLink = function (mLink) { return (/^http/).test(mLink); }; /** * @param {string} sPhone */ CContactModel.prototype.onCallClick = function (sPhone) { App.Phone.call(sPhone); }; CContactModel.prototype.viewAllMailsWithContact = function () { var sSearch = this.getEmailsString(); if (AppData.SingleMode && window.opener && window.opener.App) { window.opener.App.MailCache.searchMessagesInCurrentFolder('email:' + sSearch); window.opener.focus(); window.close(); } else { App.MailCache.searchMessagesInCurrentFolder('email:' + sSearch); } }; /** * @constructor */ function CGroupModel() { this.isNew = ko.observable(false); this.readOnly = ko.observable(false); this.idGroup = ko.observable(''); this.idUser = ko.observable(''); this.name = ko.observable(''); this.isOrganization = ko.observable(false); this.email = ko.observable(''); this.country = ko.observable(''); this.city = ko.observable(''); this.company = ko.observable(''); this.fax = ko.observable(''); this.phone = ko.observable(''); this.state = ko.observable(''); this.street = ko.observable(''); this.web = ko.observable(''); this.zip = ko.observable(''); this.edited = ko.observable(false); this.nameFocused = ko.observable(false); this.canBeSave = ko.computed(function () { return '' !== this.name(); }, this); this.newContactsInGroupCount = ko.observable(0); this.newContactsInGroupHint = ko.computed(function () { var iCount = this.newContactsInGroupCount(); return this.isNew() && 0 < iCount ? Utils.i18n('CONTACTS/CONTACT_ADD_TO_NEW_HINT_PLURAL', { 'COUNT' : iCount }, null, iCount) : ''; }, this); this.events = ko.observableArray([]); } CGroupModel.prototype.clear = function () { this.isNew(false); this.idGroup(''); this.idUser(''); this.name(''); this.nameFocused(false); this.edited(false); this.isOrganization(false); this.email(''); this.country(''); this.city(''); this.company(''); this.fax(''); this.phone(''); this.state(''); this.street(''); this.web(''); this.zip(''); this.events([]); }; CGroupModel.prototype.populate = function (oGroup) { this.isNew(oGroup.isNew()); this.idGroup(oGroup.idGroup()); this.idUser(oGroup.idUser()); this.name(oGroup.name()); this.nameFocused(oGroup.nameFocused()); this.edited(oGroup.edited()); this.isOrganization(oGroup.isOrganization()); this.email(oGroup.email()); this.country(oGroup.country()); this.city(oGroup.city()); this.company(oGroup.company()); this.fax(oGroup.fax()); this.phone(oGroup.phone()); this.state(oGroup.state()); this.street(oGroup.street()); this.web(oGroup.web()); this.zip(oGroup.zip()); }; CGroupModel.prototype.switchToNew = function () { this.clear(); this.edited(true); this.isNew(true); if (!bMobileApp) { this.nameFocused(true); } }; CGroupModel.prototype.switchToView = function () { this.edited(false); }; /** * @return {Object} */ CGroupModel.prototype.toObject = function () { return { 'GroupId': this.idGroup(), 'Name': this.name(), 'IsOrganization': this.isOrganization() ? '1' : '0', 'Email': this.email(), 'Country': this.country(), 'City': this.city(), 'Company': this.company(), 'Fax': this.fax(), 'Phone': this.phone(), 'State': this.state(), 'Street': this.street(), 'Web': this.web(), 'Zip': this.zip() }; }; /** * @constructor */ function CContactListItemModel() { this.bIsGroup = false; this.bIsOrganization = false; this.bReadOnly = false; this.bItsMe = false; this.bGlobal = false; this.sId = ''; this.sName = ''; this.sEmail = ''; this.bSharedToAll = false; this.deleted = ko.observable(false); this.checked = ko.observable(false); this.selected = ko.observable(false); this.recivedAnim = ko.observable(false).extend({'autoResetToFalse': 500}); } /** * * @param {Object} oData * @param {boolean=} bGlobal */ CContactListItemModel.prototype.parse = function (oData, bGlobal) { if (oData && 'Object/CContactListItem' === Utils.pExport(oData, '@Object', '')) { this.sId = Utils.pString(oData.Id); this.sName = Utils.pString(oData.Name); this.sEmail = Utils.pString(oData.Email); this.bIsGroup = !!oData.IsGroup; this.bIsOrganization = !!oData.IsOrganization; this.bReadOnly = !!oData.ReadOnly; this.bItsMe = !!oData.ItsMe; this.bGlobal = !!oData.Global; this.bSharedToAll = !!oData.SharedToAll; } }; /** * @return {boolean} */ CContactListItemModel.prototype.IsGroup = function () { return this.bIsGroup; }; /** * @return {boolean} */ CContactListItemModel.prototype.Global = function () { return this.bGlobal; }; /** * @return {boolean} */ CContactListItemModel.prototype.ReadOnly = function () { return this.bReadOnly; }; /** * @return {boolean} */ CContactListItemModel.prototype.ItsMe = function () { return this.bItsMe; }; /** * @return {string} */ CContactListItemModel.prototype.Id = function () { return this.sId; }; /** * @return {string} */ CContactListItemModel.prototype.Name = function () { return this.sName; }; /** * @return {string} */ CContactListItemModel.prototype.Email = function () { return this.sEmail; }; /** * @return {string} */ CContactListItemModel.prototype.EmailAndName = function () { return this.sName && this.sEmail && 0 < this.sName.length && 0 < this.sEmail.length ? '"' + this.sName + '" <' + this.sEmail + '>' : this.sEmail; }; /** * @return {boolean} */ CContactListItemModel.prototype.IsSharedToAll = function () { return this.bSharedToAll; }; /** * @return {boolean} */ CContactListItemModel.prototype.IsOrganization = function () { return this.bIsOrganization; }; /** * @constructor */ function CCalendarModel() { this.id = 0; this.cTag = 0; this.name = ko.observable(''); this.description = ko.observable(''); this.owner = ko.observable(''); this.isDefault = false; this.isShared = ko.observable(false); this.isSharedToAll = ko.observable(false); this.sharedToAllAccess = Enums.CalendarAccess.Read; this.isPublic = ko.observable(false); this.url = ko.observable(''); this.davUrl = ko.observable(''); this.exportUrl = ko.observable(''); this.pubUrl = ko.observable(''); this.shares = ko.observableArray([]); this.events = ko.observableArray([]); this.eventsCount = ko.computed(function() { return this.events().length; }, this); this.access = ko.observable(Enums.CalendarAccess.Write); this.control = ko.computed(function() { return !(this.access() === Enums.CalendarAccess.Read && this.isSharedToAll()); }, this); this.color = ko.observable(''); this.color.subscribe(function(){ this.events(_.map(this.events(), function (oEvent) { oEvent.backgroundColor = oEvent.borderColor = this.color(); return oEvent; }, this)); this.name.valueHasMutated(); }, this); this.active = ko.observable(true); this.startDateTime = 0; this.endDateTime = 0; this.account = AppData.Accounts ? AppData.Accounts.getDefault() : null; } /** * @param {AjaxCalendarResponse} oData */ CCalendarModel.prototype.parse = function (oData) { this.id = Utils.pString(oData.Id); this.cTag = oData.CTag; this.name(Utils.pString(oData.Name)); this.description(Utils.pString(oData.Description)); this.owner(Utils.pString(oData.Owner)); this.active(App.Storage.hasData(this.id) ? App.Storage.getData(this.id) : true); this.isDefault = !!oData.IsDefault; this.access(oData.Access); this.isShared(!!oData.Shared); this.isSharedToAll(!!oData.SharedToAll); this.sharedToAllAccess = oData.SharedToAllAccess; this.isPublic(!!oData.IsPublic); var color = Utils.pString(oData.Color); // color = (this.access === Enums.CalendarAccess.Read) ? Utils.shadeColor(color, 30) : color; this.color(color); this.url(Utils.pString(oData.Url)); this.davUrl(Utils.pString(oData.ServerUrl)); this.exportUrl(Utils.getAppPath() + '?/Raw/Calendars/0/' + Utils.pString(oData.ExportHash)); this.pubUrl(Utils.getAppPath() + '?calendar-pub=' + Utils.pString(oData.PubHash)); this.shares(oData.Shares || []); _.each(oData.Events, function (oEvent) { this.addEvent(oEvent); }, this); }; /** * @param {string} sId * * @return {?} */ CCalendarModel.prototype.eventExists = function (sId) { return _.find(this.events(), function(oEvent){ return (sId === oEvent.id); }); }; /** * @param {Object} oEvent */ CCalendarModel.prototype.updateEvent = function (oEvent) { var bResult = false; if (oEvent) { this.removeEvent(oEvent.id); this.addEvent(oEvent); } return bResult; }; /** * @param {Object} oEvent */ CCalendarModel.prototype.addEvent = function (oEvent) { if (oEvent && !this.eventExists(oEvent.id)) { this.events.push(this.parseEvent(oEvent)); } }; /** * @param {string} sId */ CCalendarModel.prototype.getEvent = function (sId) { return _.find(this.events(), function(oEvent){ return oEvent.id === sId; }, this); }; /** * @param {string} sId */ CCalendarModel.prototype.getEvents = function (start, end) { var aResult = _.filter(this.events(), function(oEvent){ return moment.utc(oEvent.start).unix() >= start.unix() && moment.utc(oEvent.end).unix() <= end.unix() || moment.utc(oEvent.start).unix() <= start.unix() && moment.utc(oEvent.end).unix() >= end.unix() ; }, this); if (Utils.isUnd(aResult)) { aResult = []; } return aResult; }; /** * @param {string} sId */ CCalendarModel.prototype.removeEvent = function (sId) { this.events(_.filter(this.events(), function(oEvent){ return oEvent.id !== sId; }, this)); }; /** * @param {string} sUid * @param {boolean} bSkipExcluded */ CCalendarModel.prototype.removeEventByUid = function (sUid, bSkipExcluded) { if (Utils.isUnd(bSkipExcluded)) { bSkipExcluded = false; } this.events(_.filter(this.events(), function(oEvent){ return (oEvent.uid !== sUid && (!bSkipExcluded || !oEvent.excluded)); }, this)); }; CCalendarModel.prototype.removeEvents = function () { this.events([]); }; CCalendarModel.prototype.expungeEvents = function (aEventIds, start, end) { var aEventRemoveIds = []; _.each(this.getEvents(moment.unix(start), moment.unix(end)), function(oEvent) { if (!_.include(aEventIds, oEvent.id)) { aEventRemoveIds.push(oEvent.id); } }, this); this.events(_.filter(this.events(), function(oEvent){ return !_.include(aEventRemoveIds, oEvent.id); },this)); }; /** * @return {boolean} */ CCalendarModel.prototype.isEditable = function () { return this.access() !== Enums.CalendarAccess.Read; }; /** * @return {boolean} */ CCalendarModel.prototype.isOwner = function () { return (this.account && this.account.email() === this.owner()); }; CCalendarModel.prototype.parseEvent = function (oEvent) { /* oEvent.start = moment(oEvent.start); oEvent.end = moment(oEvent.end); */ oEvent.title = Utils.getTitleForEvent(oEvent.subject); oEvent.editable = oEvent.appointment ? false : true; oEvent.backgroundColor = oEvent.borderColor = this.color(); if (!_.isArray(oEvent.className)) { var className = oEvent.className; oEvent.className = [className]; } if (this.access() === Enums.CalendarAccess.Read) { oEvent.className.push('fc-event-readonly'); } else { oEvent.className = _.filter(oEvent.className, function(sItem){ return sItem !== 'fc-event-readonly'; }); } if (oEvent.rrule && !oEvent.excluded) { oEvent.className.push('fc-event-repeat'); } else { oEvent.className = _.filter(oEvent.className, function(sItem){ return sItem !== 'fc-event-repeat'; }); } if (Utils.isNonEmptyArray(oEvent.attendees)) { oEvent.className.push('fc-event-appointment'); } else { oEvent.className = _.filter(oEvent.className, function(sItem){ return sItem !== 'fc-event-appointment'; }); } return oEvent; }; CCalendarModel.prototype.reloadEvents = function () { this.events(_.map(this.events(), function (oEvent) { return this.parseEvent(oEvent); }, this)); }; CCalendarModel.prototype.canShare = function () { return (!this.isShared() || this.isShared() && this.access() === Enums.CalendarAccess.Write || this.isOwner()); }; /** * @param {Object} oParameters * @constructor */ function CCalendarListModel(oParameters) { this.parentOnCalendarActiveChange = oParameters.onCalendarActiveChange; this.parentOnCalendarCollectionChange = oParameters.onCalendarCollectionChange; this.defaultCal = ko.observable(null); this.currentCal = ko.observable(null); this.collection = ko.observableArray([]); this.collection.subscribe(function () { this.pickCurrentCalendar(this.defaultCal()); if (this.parentOnCalendarCollectionChange) { this.parentOnCalendarCollectionChange(); } }, this); this.count = ko.computed(function () { return this.collection().length; }, this); this.own = ko.computed(function () { var calendars = _.filter(this.collection(), function(oItem){ return (!oItem.isShared()); }) ; return calendars; }, this); this.ownCount = ko.computed(function () { return this.own().length; }, this); this.shared = ko.computed(function () { var calendars = _.filter(this.collection(), function(oItem){ return (oItem.isShared() && !oItem.isSharedToAll()); }) ; return calendars; }, this); this.sharedCount = ko.computed(function () { return this.shared().length; }, this); this.sharedToAll = ko.computed(function () { var calendars = _.filter(this.collection(), function(oItem){ return (oItem.isShared() && oItem.isSharedToAll()); }) ; return calendars; }, this); this.sharedToAllCount = ko.computed(function () { return this.sharedToAll().length; }, this); this.ids = ko.computed(function () { return _.map(this.collection(), function (oCalendar){ return oCalendar.id; }, this); }, this); } /** * @param {Object} oPickCalendar */ CCalendarListModel.prototype.pickCurrentCalendar = function (oPickCalendar) { var oFirstActiveCal = _.find(this.collection(), function (oCalendar) { return oCalendar.active() && (oCalendar.access() === Enums.CalendarAccess.Write); }, this) ; if (!this.currentCal() || !this.currentCal().active()) { if (oPickCalendar && oPickCalendar.active()) { this.currentCal(oPickCalendar); } else if (this.defaultCal() && (this.defaultCal().active() || !oFirstActiveCal)) { this.currentCal(this.defaultCal()); } else if (oFirstActiveCal) { this.currentCal(oFirstActiveCal); } } }; /** * @param {number} iCalendarId */ CCalendarListModel.prototype.hideOtherCalendars = function (iCalendarId) { _.each(this.collection(), function (oCalendar) { oCalendar.active(oCalendar.id === iCalendarId); }, this); }; /** * @param {string} sCalendarId */ CCalendarListModel.prototype.getCalendarById = function (sCalendarId) { var oCalendar = _.find(this.collection(), function(oCalendar) { return oCalendar.id === sCalendarId; }, this); return oCalendar; }; /** * @return {Array} */ CCalendarListModel.prototype.getEvents = function (start, end) { var aCalendarsEvents = [], aCalendarEvents = [] ; _.each(this.collection(), function (oCalendar) { if (oCalendar && oCalendar.active()) { if (!Utils.isUnd(start) && !Utils.isUnd(end)) { aCalendarEvents = oCalendar.getEvents(start, end); } else { aCalendarEvents = oCalendar.events(); } aCalendarsEvents = _.union(aCalendarsEvents, aCalendarEvents); } }, this); return aCalendarsEvents; }; /** * @param {AjaxCalendarResponse} oCalendarData * * @return {Object} */ CCalendarListModel.prototype.parseCalendar = function (oCalendarData) { var oCalendar = new CCalendarModel(); oCalendar.parse(oCalendarData); return oCalendar; }; /** * @param {AjaxCalendarResponse} oCalendarData * * @return {Object} */ CCalendarListModel.prototype.parseAndAddCalendar = function (oCalendarData) { var mIndex = 0, oClientCalendar = null, oCalendar = this.parseCalendar(oCalendarData) ; oCalendar.active.subscribe(function (value) { this.parentOnCalendarActiveChange(oCalendar); var oPickCalendar = oCalendar.active() ? oCalendar : this.defaultCal(); this.pickCurrentCalendar(oPickCalendar); App.Storage.setData(oCalendar.id, value); }, this); if (oCalendar.isDefault) { this.defaultCal(oCalendar); } mIndex = this.calendarExists(oCalendar.id); if (mIndex || mIndex === 0) { oClientCalendar = this.getCalendarById(oCalendar.id); oCalendar.events(oClientCalendar.events()); this.collection.splice(mIndex, 1, oCalendar); } else { this.collection.push(oCalendar); } this.sort(); return oCalendar; }; /** * @param {string|number} sId * * @return {?} */ CCalendarListModel.prototype.calendarExists = function (sId) { var iIndex = _.indexOf(_.map(this.collection(), function(oItem){return oItem.id;}), sId); return (iIndex < 0) ? false : iIndex; }; /** * @param {string} sId */ CCalendarListModel.prototype.removeCalendar = function (sId) { this.collection(_.filter(this.collection(), function(oCalendar) { return oCalendar.id !== sId; }, this)); }; CCalendarListModel.prototype.clearCollection = function () { this.collection.removeAll(); }; CCalendarListModel.prototype.getColors = function () { return _.map(this.collection(), function (oCalendar) { return oCalendar.color().toLowerCase(); }, this); }; /** * @param {string} sId */ CCalendarListModel.prototype.setDefault = function (sId) { _.each(this.collection(), function(oCalendar) { if (oCalendar.id !== sId) { oCalendar.isDefault = true; this.defaultCal(oCalendar); } else { oCalendar.isDefault = false; } }, this); }; /** */ CCalendarListModel.prototype.sort = function () { var collection = _.sortBy(this.collection(), function(oCalendar){return oCalendar.name();}); this.collection(_.sortBy(collection, function(oCalendar){return oCalendar.isShared();})); }; CCalendarListModel.prototype.expunge = function (aIds) { this.collection(_.filter(this.collection(), function(oCalendar) { return _.include(aIds, oCalendar.id); }, this)); }; /** * @constructor * @extends CCommonFileModel */ function CFileModel() { this.id = ko.observable(''); this.fileName = ko.observable(''); this.displayName = ko.observable(''); this.nameForEdit = ko.observable(''); this.storageType = ko.observable(Enums.FileStorageType.Personal); this.lastModified = ko.observable(''); this.path = ko.observable(''); this.fullPath = ko.observable(''); this.publicHash = ko.observable(''); this.selected = ko.observable(false); this.checked = ko.observable(false); this.isFolder = ko.observable(false); this.edited = ko.observable(false); this.isExternal = ko.observable(false); this.isLink = ko.observable(false); this.linkType = ko.observable(0); this.linkUrl = ko.observable(''); this.thumbnailExternalLink = ko.observable(''); this.deleted = ko.observable(false); // temporary removal until it was confirmation from the server to delete this.recivedAnim = ko.observable(false).extend({'autoResetToFalse': 500}); this.shared = ko.observable(false); this.owner = ko.observable(''); this.ownerHeaderText = ko.computed(function () { return Utils.i18n('FILESTORAGE/OWNER_HEADER_EMAIL', { 'OWNER': this.owner() }); }, this); this.lastModifiedHeaderText = ko.computed(function () { return Utils.i18n('FILESTORAGE/OWNER_HEADER_LAST_MODIFIED_DATE_TEXT', { 'LASTMODIFIED': this.lastModified() }); }, this); CCommonFileModel.call(this); this.fileName.subscribe(function (value) { this.nameForEdit(value); this.displayName(value); }, this); this.displayName.subscribe(function (value) { if (!this.isFolder()) { this.displayName(Utils.getFileNameWithoutExtension(value)); } }, this); this.type = this.storageType; this.uploaded = ko.observable(true); this.downloadLink = ko.computed(function () { return Utils.getFilestorageDownloadLinkByHash( (AppData.Accounts) ? AppData.Accounts.currentId() : null, this.hash(), this.publicHash() ); }, this); this.viewLink = ko.computed(function () { if (this.isLink()/* && this.linkType() === Enums.FileStorageLinkType.GoogleDrive*/) { return this.linkUrl(); } else { var sUrl = Utils.getFilestorageViewLinkByHash( (AppData.Accounts) ? AppData.Accounts.currentId() : null, this.hash(), this.publicHash() ); return this.iframedView() ? Utils.getIframeWrappwer( (AppData.Accounts) ? AppData.Accounts.currentId() : null, sUrl) : sUrl; } }, this); this.isViewable = ko.computed(function () { var bResult = false, aViewableArray = [ 'JPEG', 'JPG', 'PNG', 'GIF', 'HTM', 'HTML', 'TXT', 'CSS', 'ASC', 'JS', 'PDF' ] ; if (_.indexOf(aViewableArray, this.extension().toUpperCase()) >= 0) { bResult = true; } return (this.iframedView() || bResult || (this.isLink()/* && this.linkType() === Enums.FileStorageLinkType.GoogleDrive*/)) && !this.isPopupItem(); }, this); this.visibleViewLink = this.isViewable; this.thumbnailLink = ko.computed(function () { if (this.isExternal() || (this.isLink() && this.linkType() === Enums.FileStorageLinkType.GoogleDrive)) { return this.thumbnailExternalLink(); } else { return this.thumb() ? Utils.getFilestorageViewThumbnailLinkByHash(this.accountId(), this.hash(), this.publicHash()) : ''; } }, this); this.edited.subscribe(function (value) { if (value === false) { this.nameForEdit(this.fileName()); } }, this); } Utils.extend(CFileModel, CCommonFileModel); /** * @returns {CFileModel} */ CFileModel.prototype.getInstance = function () { return new CFileModel(); }; CFileModel.prototype.parse = function (oData, sPublicHash) { var oDateModel = new CDateModel(); this.isFolder(!!oData.IsFolder); this.isLink(!!oData.IsLink); this.fileName(Utils.pString(oData.Name)); this.id(Utils.pString(oData.Id)); this.path(Utils.pString(oData.Path)); this.fullPath(Utils.pString(oData.FullPath)); this.storageType(Utils.pInt(oData.Type)); this.shared(!!oData.Shared); this.isExternal(!!oData.IsExternal); this.iframedView(!!oData.Iframed); if (this.isLink()) { this.linkUrl(Utils.pString(oData.LinkUrl)); this.linkType(Utils.pInt(oData.LinkType)); } if (!this.isFolder()) { this.size(Utils.pInt(oData.Size)); oDateModel.parse(oData['LastModified']); this.lastModified(oDateModel.getShortDate()); this.owner(Utils.pString(oData.Owner)); this.thumb(!!oData.Thumb); this.thumbnailExternalLink(Utils.pString(oData.ThumbnailLink)); this.hash(Utils.pString(oData.Hash)); this.publicHash(sPublicHash); } if(this.thumb() && this.thumbnailExternalLink() === '') { Utils.thumbQueue(this.thumbnailSessionUid(), this.thumbnailLink(), this.thumbnailSrc); } this.content(Utils.pString(oData.Content)); }; /** * Fills attachment data for upload. * * @param {string} sFileUid * @param {Object} oFileData * @param {string} sFileName * @param {string} sOwner * @param {string} sPath * @param {string} sStorageType */ CFileModel.prototype.onUploadSelectOwn = function (sFileUid, oFileData, sFileName, sOwner, sPath, sStorageType) { var oDateModel = new CDateModel(), oDate = new Date() ; this.onUploadSelect(sFileUid, oFileData); oDateModel.parse(oDate.getTime() /1000); this.fileName(sFileName); this.lastModified(oDateModel.getShortDate()); this.owner(sOwner); this.path(sPath); this.storageType(sStorageType); }; /** * @constructor */ function CPostModel() { this.Id = null; this.IdThread = null; this.IdOwner = null; this.sFrom = ''; this.sDate = ''; this.iType = null; this.bSysType = false; this.bThreadOwner = null; this.sText = ''; this.collapsed = ko.observable(false); this.attachments = ko.observableArray([]); this.allowDownloadAttachmentsLink = true; this.itsMe = ko.observable(false); this.canBeDeleted = this.itsMe; } /** * @param {AjaxPostResponse} oData */ CPostModel.prototype.parse = function (oData) { this.Id = oData.IdHelpdeskPost; this.IdThread = oData.IdHelpdeskThread; this.IdOwner = oData.IdOwner; this.bThreadOwner = oData.IsThreadOwner; this.sFrom = Utils.isNonEmptyArray(oData.Owner) ? oData.Owner[1] || oData.Owner[0] || '' : ''; this.sDate = CDateModel.prototype.convertDate(oData.Created); this.iType = oData.Type; this.bSysType = oData.SystemType; this.sText = Utils.pString(oData.Text); this.itsMe(oData.ItsMe); if (oData.Attachments) { var iIndex = 0, iLen = 0, oObject = null, aList = [], sThumbSessionUid = Date.now().toString() ; for (iLen = oData.Attachments.length; iIndex < iLen; iIndex++) { if (oData.Attachments[iIndex] && 'Object/CHelpdeskAttachment' === Utils.pExport(oData.Attachments[iIndex], '@Object', '')) { oObject = new CHelpdeskAttachmentModel(); oObject.parse(oData.Attachments[iIndex]); oObject.getInThumbQueue(sThumbSessionUid); aList.push(oObject); } } this.attachments(aList); } }; /** * @constructor */ function CThreadListModel() { this.Id = null; this.ThreadHash = ''; this.IdOwner = null; this.ItsMe = false; this.aOwner = []; this.sSubject = ''; this.sEmail = ''; this.sName = ''; this.sFrom = ''; this.sFromFull = ''; this.time = ko.observable(0); this.state = ko.observable(0); this.unseen = ko.observable(false); this.postsCount = ko.observable(0); this.date = ko.computed(function () { return moment(this.time() * 1000).fromNow(false); }, this); this.printableState = ko.computed(function () { var sText = '', sLangSuffix = this.ItsMe ? '_FOR_CLIENT' : '' ; switch (this.state()) { case Enums.HelpdeskThreadStates.Pending: sText = Utils.i18n('HELPDESK/THREAD_STATE_PENDING' + sLangSuffix); break; case Enums.HelpdeskThreadStates.Resolved: sText = Utils.i18n('HELPDESK/THREAD_STATE_RESOLVED' + sLangSuffix); break; case Enums.HelpdeskThreadStates.Waiting: sText = Utils.i18n('HELPDESK/THREAD_STATE_WAITING' + sLangSuffix); break; case Enums.HelpdeskThreadStates.Answered: sText = Utils.i18n('HELPDESK/THREAD_STATE_ANSWERED' + sLangSuffix); break; case Enums.HelpdeskThreadStates.Deferred: sText = Utils.i18n('HELPDESK/THREAD_STATE_DEFERRED' + sLangSuffix); break; } return sText; }, this); this.deleted = ko.observable(false); this.checked = ko.observable(false); this.selected = ko.observable(false); } /** * @param {Object} oData */ CThreadListModel.prototype.parse = function (oData) { this.Id = oData.IdHelpdeskThread; this.ThreadHash = Utils.pString(oData.ThreadHash); this.IdOwner = oData.IdOwner; this.ItsMe = !!oData.ItsMe; this.sSubject = Utils.pString(oData.Subject); this.time(Utils.pInt(oData.Updated)); this.aOwner = Utils.isNonEmptyArray(oData.Owner) ? oData.Owner : ['', '']; this.sEmail = this.aOwner[0] || ''; this.sName = this.aOwner[1] || ''; this.sFrom = this.sName || this.sEmail; this.sFromFull = Utils.trim('' === this.sName ? this.sEmail : (this.sName + ('' !== this.sEmail ? ' (' + this.sEmail + ')' : ''))); this.postsCount(oData.PostCount); this.state(oData.Type); this.unseen(!oData.IsRead); }; /** * @return {string} */ CThreadListModel.prototype.Name = function () { return this.sName; }; /** * @return {string} */ CThreadListModel.prototype.Email = function () { return this.sEmail; }; CThreadListModel.prototype.updateMomentDate = function () { this.time.valueHasMutated(); }; /** * @constructor * @extends CCommonFileModel */ function CHelpdeskAttachmentModel() { CCommonFileModel.call(this); this.downloadLink = ko.computed(function () { var iAccountId = !bExtApp && AppData && AppData.Accounts ? AppData.Accounts.currentId() : 0, sTenantHash = bExtApp && AppData ? AppData.TenantHash : '' ; return Utils.getDownloadLinkByHash(iAccountId, this.hash(), bExtApp, sTenantHash); }, this); this.viewLink = ko.computed(function () { var iAccountId = !bExtApp && AppData && AppData.Accounts ? AppData.Accounts.currentId() : 0, sTenantHash = bExtApp && AppData ? AppData.TenantHash : '' ; return Utils.getViewLinkByHash(iAccountId, this.hash(), bExtApp, sTenantHash); }, this); this.thumbnailLink = ko.computed(function () { var iAccountId = !bExtApp && AppData && AppData.Accounts ? AppData.Accounts.currentId() : 0, sTenantHash = bExtApp && AppData ? AppData.TenantHash : '', sLink = this.thumb() ? Utils.getViewThumbnailLinkByHash(iAccountId, this.hash(), bExtApp, sTenantHash) : '' ; return sLink; }, this); } Utils.extend(CHelpdeskAttachmentModel, CCommonFileModel); CHelpdeskAttachmentModel.prototype.dataObjectName = 'Object/CHelpdeskAttachment'; /** * @returns {CHelpdeskAttachmentModel} */ CHelpdeskAttachmentModel.prototype.getInstance = function () { return new CHelpdeskAttachmentModel(); }; /** * @param {Object} oResult */ CHelpdeskAttachmentModel.prototype.fillDataAfterUploadComplete = function (oResult) { this.tempName(oResult.Result.HelpdeskFile.TempName); this.type(oResult.Result.HelpdeskFile.MimeType); this.hash(oResult.Result.HelpdeskFile.Hash); }; /** * @constructor */ function CSignatureModel() { this.iAccountId = 0; this.type = ko.observable(true); this.options = ko.observable(0); this.signature = ko.observable(''); } /** * Calls a recursive parsing of the folder tree. * * @param {number} iAccountId * @param {Object} oData */ CSignatureModel.prototype.parse = function (iAccountId, oData) { this.iAccountId = iAccountId; // this.type(parseInt(oData.Type, 10) === 1 ? true : false); this.options(parseInt(oData.Options, 10)); this.signature(oData.Signature); }; /** * @constructor */ function CAutoresponderModel() { this.iAccountId = 0; this.enable = false; this.subject = ''; this.message = ''; } /** * @param {number} iAccountId * @param {Object} oData */ CAutoresponderModel.prototype.parse = function (iAccountId, oData) { this.iAccountId = iAccountId; this.enable = !!oData.Enable; this.subject = Utils.pString(oData.Subject); this.message = Utils.pString(oData.Message); }; /** * @constructor */ function CFetcherModel() { this.FETCHER = true; // constant this.id = ko.observable(0); this.accountId = ko.observable(0); this.isEnabled = ko.observable(false); this.isLocked = ko.observable(false); this.email = ko.observable(''); this.userName = ko.observable(''); this.folder = ko.observable(''); this.signatureOptions = ko.observable(false); this.signature = ko.observable(''); this.incomingMailServer = ko.observable(''); this.incomingMailPort = ko.observable(0); this.incomingMailLogin = ko.observable(''); this.leaveMessagesOnServer = ko.observable(''); this.isOutgoingEnabled = ko.observable(false); this.outgoingMailServer = ko.observable(''); this.outgoingMailPort = ko.observable(0); this.outgoingMailAuth = ko.observable(false); this.fullEmail = ko.computed(function () { if (this.userName() === '') { return this.email(); } else { return this.userName() + ' <' + this.email() + '>'; } }, this); } /** * @constructor */ function CFetcherListModel() { this.accountId = 0; this.collection = ko.observableArray([]); } /** * @param {number} iAccountId * @param {Array} aData */ CFetcherListModel.prototype.parse = function (iAccountId, aData) { this.accountId = iAccountId; var aParsedCollection = [], iIndex = 0, iLen = 0, oFetcher = null, oData = null ; if (_.isArray(aData)) { for (iLen = aData.length; iIndex < iLen; iIndex++) { oData = aData[iIndex]; oFetcher = new CFetcherModel(); oFetcher.id(oData['IdFetcher']); oFetcher.accountId(oData['IdAccount']); oFetcher.isEnabled(oData['IsEnabled']); oFetcher.isLocked(oData['IsLocked']); oFetcher.email(oData['Email']); oFetcher.userName(oData['Name']); oFetcher.folder(oData['Folder']); oFetcher.signatureOptions(!!oData['SignatureOptions']); oFetcher.signature(oData['Signature']); oFetcher.incomingMailServer(oData['IncomingMailServer']); oFetcher.incomingMailPort(oData['IncomingMailPort']); oFetcher.incomingMailLogin(oData['IncomingMailLogin']); oFetcher.leaveMessagesOnServer(oData['LeaveMessagesOnServer']); oFetcher.isOutgoingEnabled(oData['IsOutgoingEnabled']); oFetcher.outgoingMailServer(oData['OutgoingMailServer']); oFetcher.outgoingMailPort(oData['OutgoingMailPort']); oFetcher.outgoingMailAuth(oData['OutgoingMailAuth']); aParsedCollection.push(oFetcher); } } this.collection(aParsedCollection); }; /** * @param {number} iFetcherId */ CFetcherListModel.prototype.getFetcher = function (iFetcherId) { var oFetcher = null, iIndex = 0, iLen = 0, collection = this.collection() ; for (iLen = collection.length; iIndex < iLen; iIndex++) { if (collection[iIndex].id() === iFetcherId) { oFetcher = collection[iIndex]; } } return oFetcher; }; /** * @constructor */ function CForwardModel() { this.iAccountId = 0; this.enable = false; this.email = ''; } /** * @param {number} iAccountId * @param {Object} oData */ CForwardModel.prototype.parse = function (iAccountId, oData) { this.iAccountId = iAccountId; this.enable = !!oData.Enable; this.email = Utils.pString(oData.Email); }; /** * @constructor */ function CSieveFiltersModel() { this.iAccountId = 0; this.collection = ko.observableArray([]); } /** * @param {number} iAccountId * @param {Object} oData */ CSieveFiltersModel.prototype.parse = function (iAccountId, oData) { var iIndex = 0, iLen = oData.length, oSieveFilter = null ; this.iAccountId = iAccountId; if (_.isArray(oData)) { for (iLen = oData.length; iIndex < iLen; iIndex++) { oSieveFilter = new CSieveFilterModel(iAccountId); oSieveFilter.parse(oData[iIndex]); this.collection.push(oSieveFilter); } } }; /** * @param {number} iAccountID * @constructor */ function CSieveFilterModel(iAccountID) { this.iAccountId = iAccountID; this.enable = ko.observable(true).extend({'reversible': true}); this.field = ko.observable('').extend({'reversible': true}); //map to Field this.condition = ko.observable('').extend({'reversible': true}); this.filter = ko.observable('').extend({'reversible': true}); this.action = ko.observable('').extend({'reversible': true}); this.folder = ko.observable('').extend({'reversible': true}); } /** * @param {Object} oData */ CSieveFilterModel.prototype.parse = function (oData) { this.enable(!!oData.Enable); this.field(Utils.pInt(oData.Field)); this.condition(Utils.pInt(oData.Condition)); this.filter(Utils.pString(oData.Filter)); this.action(Utils.pInt(oData.Action)); this.folder(Utils.pString(oData.FolderFullName)); this.commit(); }; CSieveFilterModel.prototype.revert = function () { this.enable.revert(); this.field.revert(); this.condition.revert(); this.filter.revert(); this.action.revert(); this.folder.revert(); }; CSieveFilterModel.prototype.commit = function () { this.enable.commit(); this.field.commit(); this.condition.commit(); this.filter.commit(); this.action.commit(); this.folder.commit(); }; CSieveFilterModel.prototype.toString = function () { var aState = [ this.enable(), this.field(), this.condition(), this.filter(), this.action(), this.folder() ]; return aState.join(':'); }; /** * @constructor */ function CInformationViewModel() { this.iAnimationDuration = 500; this.iReportDuration = 5000; this.iErrorDuration = 10000; this.loadingMessage = ko.observable(''); this.loadingHidden = ko.observable(true); this.loadingVisible = ko.observable(false); this.reportMessage = ko.observable(''); this.reportHidden = ko.observable(true); this.reportVisible = ko.observable(false); this.iReportTimeout = -1; this.errorMessage = ko.observable(''); this.errorHidden = ko.observable(true); this.errorVisible = ko.observable(false); this.iErrorTimeout = -1; this.isHtmlError = ko.observable(false); this.gray = ko.observable(false); } /** * @param {string} sMessage */ CInformationViewModel.prototype.showLoading = function (sMessage) { if (sMessage && sMessage !== '') { this.loadingMessage(sMessage); } else { this.loadingMessage(Utils.i18n('MAIN/LOADING')); } this.loadingVisible(true); _.defer(_.bind(function () { this.loadingHidden(false); }, this)); } ; CInformationViewModel.prototype.hideLoading = function () { this.loadingHidden(true); setTimeout(_.bind(function () { if (this.loadingHidden()) { this.loadingVisible(false); } }, this), this.iAnimationDuration); }; /** * Displays a message. Starts a timer for hiding. * * @param {string} sMessage * @param {number} iDelay */ CInformationViewModel.prototype.showReport = function (sMessage, iDelay) { var self = this; iDelay = iDelay || this.iReportDuration; if (sMessage && sMessage !== '') { this.reportMessage(sMessage); this.reportVisible(true); _.defer(function () { self.reportHidden(false); }); clearTimeout(this.iReportTimeout); this.iReportTimeout = setTimeout(function () { self.reportHidden(true); setTimeout(function () { if (self.reportHidden()) { self.reportVisible(false); } }, this.iAnimationDuration); }, iDelay); } else { this.reportHidden(true); this.reportVisible(false); } }; /** * Displays an error message. Starts a timer for hiding. * * @param {string} sMessage * @param {boolean=} bHtml = false * @param {boolean=} bNotHide = false * @param {boolean=} bGray = false */ CInformationViewModel.prototype.showError = function (sMessage, bHtml, bNotHide, bGray) { if (sMessage && sMessage !== '') { this.gray(!!bGray); this.errorMessage(sMessage); this.isHtmlError(bHtml); this.errorVisible(true); _.defer(_.bind(function () { this.errorHidden(false); }, this)); clearTimeout(this.iErrorTimeout); if (!bNotHide) { this.iErrorTimeout = setTimeout(_.bind(function () { this.selfHideError(); }, this), this.iErrorDuration); } } else { this.selfHideError(); } }; CInformationViewModel.prototype.selfHideError = function () { this.errorHidden(true); setTimeout(_.bind(function () { if (this.errorHidden()) { this.errorVisible(false); } }, this), this.iAnimationDuration); }; /** * @param {boolean=} bGray = false */ CInformationViewModel.prototype.hideError = function (bGray) { bGray = Utils.isUnd(bGray) ? false : !!bGray; if (bGray === this.gray()) { this.selfHideError(); } }; /** * @constructor */ function CHeaderBaseViewModel() { this.mobileApp = bMobileApp; this.allowWebMail = AppData.App.AllowWebMail; this.currentAccountId = AppData.Accounts.currentId; this.currentAccountId.subscribe(function () { this.changeCurrentAccount(); }, this); this.tabs = App.headerTabs; this.email = ko.observable(''); this.accounts = AppData.Accounts.collection; this.currentTab = App.Screens.currentScreen; this.isMailboxTab = ko.computed(function () { return this.currentTab() === Enums.Screens.Mailbox; }, this); this.helpdeskUnseenCount = App.helpdeskUnseenCount; this.helpdeskUnseenVisible = ko.computed(function () { return this.currentTab() !== Enums.Screens.Helpdesk && !!this.helpdeskUnseenCount(); }, this); this.mailUnseenCount = App.mailUnseenCount; this.mailUnseenVisible = ko.computed(function () { return this.currentTab() !== Enums.Screens.Mailbox && !!this.mailUnseenCount(); }, this); this.mailboxHash = App.Routing.lastMailboxHash; this.settingsHash = App.Routing.lastSettingsHash; this.contactsRecivedAnim = App.ContactsCache.recivedAnim; this.calendarRecivedAnim = App.CalendarCache.recivedAnim; this.appCustomLogo = ko.observable(AppData['AppStyleImage'] || ''); } CHeaderBaseViewModel.prototype.onRoute = function () { this.changeCurrentAccount(); }; CHeaderBaseViewModel.prototype.changeCurrentAccount = function () { this.email(AppData.Accounts.getEmail()); }; CHeaderBaseViewModel.prototype.logout = function () { App.logout(); }; CHeaderBaseViewModel.prototype.switchToFullVersion = function () { App.Ajax.send({ 'Action': 'SetMobile', 'Mobile': 0 }, function () { window.location.reload(); }, this); }; /** * @constructor */ function CHeaderViewModel() { CHeaderBaseViewModel.call(this); this.oPhone = App.Phone ? new CPhoneViewModel() : null; } _.extend(CHeaderViewModel.prototype, CHeaderBaseViewModel.prototype); /** * @constructor * @param {number} iCount * @param {number} iPerPage */ function CPageSwitcherViewModel(iCount, iPerPage) { this.shown = false; this.currentPage = ko.observable(1); this.count = ko.observable(iCount); this.perPage = ko.observable(iPerPage); this.firstPage = ko.observable(1); this.lastPage = ko.observable(1); this.pagesCount = ko.computed(function () { var iCount = Math.ceil(this.count() / this.perPage()); return (iCount > 0) ? iCount : 1; }, this); ko.computed(function () { var iAllLimit = 20, iLimit = 4, iPagesCount = this.pagesCount(), iCurrentPage = this.currentPage(), iStart = iCurrentPage, iEnd = iCurrentPage ; if (iPagesCount > 1) { while (true) { iAllLimit--; if (1 < iStart) { iStart--; iLimit--; } if (0 === iLimit) { break; } if (iPagesCount > iEnd) { iEnd++; iLimit--; } if (0 === iLimit) { break; } if (0 === iAllLimit) { break; } } } this.firstPage(iStart); this.lastPage(iEnd); }, this); // this.firstPage = ko.computed(function () { // var iValue = this.currentPage() - this.iLimitAround; // return (iValue > 0) ? iValue : 1; // }, this); // // this.lastPage = ko.computed(function () { // var iValue = this.firstPage() + this.iLimitAround * 2; // return (iValue <= this.pagesCount()) ? iValue : this.pagesCount(); // }, this); this.visibleFirst = ko.computed(function () { return (this.firstPage() > 1); }, this); this.visibleLast = ko.computed(function () { return (this.lastPage() < this.pagesCount()); }, this); this.clickPage = _.bind(this.clickPage, this); this.pages = ko.computed(function () { var iIndex = this.firstPage(), aPages = [] ; if (this.firstPage() < this.lastPage()) { for (; iIndex <= this.lastPage(); iIndex++) { aPages.push({ number: iIndex, current: (iIndex === this.currentPage()), clickFunc: this.clickPage }); } } return aPages; }, this); this.hotKeysBind(); } CPageSwitcherViewModel.prototype.hotKeysBind = function () { $(document).on('keydown', $.proxy(function(ev) { if (this.shown && !Utils.isTextFieldFocused()) { var sKey = ev.keyCode; if (ev.ctrlKey && sKey === Enums.Key.Left) { this.clickPreviousPage(); } else if (ev.ctrlKey && sKey === Enums.Key.Right) { this.clickNextPage(); } } },this)); }; CPageSwitcherViewModel.prototype.hide = function () { this.shown = false; }; CPageSwitcherViewModel.prototype.show = function () { this.shown = true; }; CPageSwitcherViewModel.prototype.clear = function () { this.currentPage(1); this.count(0); }; /** * @param {number} iCount */ CPageSwitcherViewModel.prototype.setCount = function (iCount) { this.count(iCount); if (this.currentPage() > this.pagesCount()) { this.currentPage(this.pagesCount()); } }; /** * @param {number} iPage * @param {number} iPerPage */ CPageSwitcherViewModel.prototype.setPage = function (iPage, iPerPage) { this.perPage(iPerPage); if (iPage > this.pagesCount()) { this.currentPage(this.pagesCount()); } else { this.currentPage(iPage); } }; /** * @param {Object} oPage */ CPageSwitcherViewModel.prototype.clickPage = function (oPage) { var iPage = oPage.number; if (iPage < 1) { iPage = 1; } if (iPage > this.pagesCount()) { iPage = this.pagesCount(); } this.currentPage(iPage); }; CPageSwitcherViewModel.prototype.clickFirstPage = function () { this.currentPage(1); }; CPageSwitcherViewModel.prototype.clickPreviousPage = function () { var iPrevPage = this.currentPage() - 1; if (iPrevPage < 1) { iPrevPage = 1; } this.currentPage(iPrevPage); }; CPageSwitcherViewModel.prototype.clickNextPage = function () { var iNextPage = this.currentPage() + 1; if (iNextPage > this.pagesCount()) { iNextPage = this.pagesCount(); } this.currentPage(iNextPage); }; CPageSwitcherViewModel.prototype.clickLastPage = function () { this.currentPage(this.pagesCount()); }; /** * @constructor * @param {boolean} bInsertImageAsBase64 * @param {Object=} oParent */ function CHtmlEditorViewModel(bInsertImageAsBase64, oParent) { this.mobileApp = bMobileApp; this.oParent = oParent; this.creaId = 'creaId' + Math.random().toString().replace('.', ''); this.textFocused = ko.observable(false); this.workareaDom = ko.observable(); this.uploaderAreaDom = ko.observable(); this.editorUploaderBodyDragOver = ko.observable(false); this.editorUploaderProgress = ko.observable(false); this.colorPickerDropdownDom = ko.observable(); this.insertLinkDropdownDom = ko.observable(); this.insertImageDropdownDom = ko.observable(); this.isEnable = ko.observable(true); this.isEnable.subscribe(function () { if (this.oCrea) { this.oCrea.setEditable(this.isEnable()); } }, this); this.bInsertImageAsBase64 = bInsertImageAsBase64; this.bAllowFileUpload = !(bInsertImageAsBase64 && window.File === undefined); this.allowInsertImage = ko.observable(AppData.App.AllowInsertImage); this.lockFontSubscribing = ko.observable(false); this.bAllowImageDragAndDrop = !App.browser.ie10AndAbove; this.aFonts = ['Arial', 'Arial Black', 'Courier New', 'Tahoma', 'Times New Roman', 'Verdana']; this.sDefaultFont = AppData.User.DefaultFontName; this.correctFontFromSettings(); this.selectedFont = ko.observable(''); this.selectedFont.subscribe(function () { if (this.oCrea && !this.lockFontSubscribing() && !this.inactive()) { this.oCrea.fontName(this.selectedFont()); } }, this); this.iDefaultSize = AppData.User.DefaultFontSize; this.selectedSize = ko.observable(0); this.selectedSize.subscribe(function () { if (this.oCrea && !this.lockFontSubscribing() && !this.inactive()) { this.oCrea.fontSize(this.selectedSize()); } }, this); this.visibleInsertLinkPopup = ko.observable(false); this.linkForInsert = ko.observable(''); this.linkFocused = ko.observable(false); this.visibleLinkPopup = ko.observable(false); this.linkPopupTop = ko.observable(0); this.linkPopupLeft = ko.observable(0); this.linkHref = ko.observable(''); this.visibleLinkHref = ko.observable(false); this.visibleImagePopup = ko.observable(false); this.visibleImagePopup.subscribe(function () { this.onImageOut(); }, this); this.imagePopupTop = ko.observable(0); this.imagePopupLeft = ko.observable(0); this.imageSelected = ko.observable(false); this.tooltipText = ko.observable(''); this.tooltipPopupTop = ko.observable(0); this.tooltipPopupLeft = ko.observable(0); this.visibleInsertImagePopup = ko.observable(false); this.imageUploaderButton = ko.observable(null); this.uploadedImagePathes = ko.observableArray([]); this.imagePathFromWeb = ko.observable(''); this.visibleFontColorPopup = ko.observable(false); this.oFontColorPicker = new CColorPickerViewModel(Utils.i18n('HTMLEDITOR/TEXT_COLOR_CAPTION'), this.setTextColorFromPopup, this); this.oBackColorPicker = new CColorPickerViewModel(Utils.i18n('HTMLEDITOR/BACKGROUND_COLOR_CAPTION'), this.setBackColorFromPopup, this); this.activitySource = ko.observable(1); this.activitySourceSubscription = null; this.inactive = ko.observable(false); this.inactive.subscribe(function () { var sText = this.removeAllTags(this.getText()); if (this.inactive()) { if (sText === '' || sText === ' ') { this.setText('<span style="color: #AAAAAA;">' + Utils.i18n('HTMLEDITOR/SIGNATURE_PLACEHOLDER') + '</span>'); if (this.oCrea) { this.oCrea.setBlur(); } } } else { if (sText === Utils.i18n('HTMLEDITOR/SIGNATURE_PLACEHOLDER')) { this.setText(''); } } }, this); this.allowChangeInputDirection = Utils.isRTL() || AppData.User.AllowChangeInputDirection; this.disabled = ko.observable(false); } CHtmlEditorViewModel.prototype.init = function () { $(document.body).on('click', _.bind(function () { this.closeAllPopups(); }, this)); $(this.colorPickerDropdownDom()).on('click', function (oEvent) { oEvent.stopPropagation(); }); $(this.insertLinkDropdownDom()).on('click', function (oEvent) { oEvent.stopPropagation(); }); $(this.insertImageDropdownDom()).on('click', function (oEvent) { oEvent.stopPropagation(); }); this.initEditorUploader(); }; CHtmlEditorViewModel.prototype.correctFontFromSettings = function () { var sDefaultFont = this.sDefaultFont, bFinded = false ; _.each(this.aFonts, function (sFont) { if (sFont.toLowerCase() === sDefaultFont.toLowerCase()) { sDefaultFont = sFont; bFinded = true; } }); if (bFinded) { this.sDefaultFont = sDefaultFont; } else { this.aFonts.push(sDefaultFont); } }; /** * @param {Object} $link */ CHtmlEditorViewModel.prototype.showLinkPopup = function ($link) { var $workarea = $(this.workareaDom()), oWorkareaPos = $workarea.position(), oPos = $link.position(), iHeight = $link.height() ; this.linkHref($link.attr('href') || $link.text()); this.linkPopupLeft(Math.round(oPos.left + oWorkareaPos.left)); this.linkPopupTop(Math.round(oPos.top + iHeight + oWorkareaPos.top)); this.visibleLinkPopup(true); }; CHtmlEditorViewModel.prototype.hideLinkPopup = function () { this.visibleLinkPopup(false); }; CHtmlEditorViewModel.prototype.showChangeLink = function () { this.visibleLinkHref(true); this.hideLinkPopup(); }; CHtmlEditorViewModel.prototype.changeLink = function () { this.oCrea.changeLink(this.linkHref()); this.hideChangeLink(); }; CHtmlEditorViewModel.prototype.hideChangeLink = function () { this.visibleLinkHref(false); }; /** * @param {jQuery} $image * @param {Object} oEvent */ CHtmlEditorViewModel.prototype.showImagePopup = function ($image, oEvent) { var $workarea = $(this.workareaDom()), oWorkareaPos = $workarea.position(), oWorkareaOffset = $workarea.offset() ; this.imagePopupLeft(Math.round(oEvent.pageX + oWorkareaPos.left - oWorkareaOffset.left)); this.imagePopupTop(Math.round(oEvent.pageY + oWorkareaPos.top - oWorkareaOffset.top)); this.visibleImagePopup(true); }; CHtmlEditorViewModel.prototype.hideImagePopup = function () { this.visibleImagePopup(false); }; CHtmlEditorViewModel.prototype.resizeImage = function (sSize) { var oParams = { 'width': 'auto', 'height': 'auto' }; switch (sSize) { case Enums.HtmlEditorImageSizes.Small: oParams.width = '300px'; break; case Enums.HtmlEditorImageSizes.Medium: oParams.width = '600px'; break; case Enums.HtmlEditorImageSizes.Large: oParams.width = '1200px'; break; case Enums.HtmlEditorImageSizes.Original: oParams.width = 'auto'; break; } this.oCrea.changeCurrentImage(oParams); this.visibleImagePopup(false); }; CHtmlEditorViewModel.prototype.onImageOver = function (oEvent) { if (oEvent.target.nodeName === 'IMG' && !this.visibleImagePopup()) { this.imageSelected(true); this.tooltipText(Utils.i18n('HTMLEDITOR/CLICK_TO_EDIT_IMAGE')); var self = this, $workarea = $(this.workareaDom()) ; $workarea.bind('mousemove.image', function (oEvent) { var oWorkareaPos = $workarea.position(), oWorkareaOffset = $workarea.offset() ; self.tooltipPopupTop(Math.round(oEvent.pageY + oWorkareaPos.top - oWorkareaOffset.top)); self.tooltipPopupLeft(Math.round(oEvent.pageX + oWorkareaPos.left - oWorkareaOffset.left)); }); } return true; }; CHtmlEditorViewModel.prototype.onImageOut = function (oEvent) { if (this.imageSelected()) { this.imageSelected(false); var $workarea = $(this.workareaDom()); $workarea.unbind('mousemove.image'); } return true; }; /** * @param {string} sText * @param {boolean} bPlain * @param {string} sTabIndex */ CHtmlEditorViewModel.prototype.initCrea = function (sText, bPlain, sTabIndex) { if (!this.oCrea) { this.init(); this.oCrea = new Crea({ 'creaId': this.creaId, 'fontNameArray': this.aFonts, 'defaultFontName': this.sDefaultFont, 'defaultFontSize': this.iDefaultSize, 'isRtl': Utils.isRTL(), 'enableDrop': false, 'onCursorMove': _.bind(this.setFontValuesFromText, this), 'onFocus': _.bind(this.onCreaFocus, this), 'onBlur': _.bind(this.onCreaBlur, this), 'onUrlIn': _.bind(this.showLinkPopup, this), 'onUrlOut': _.bind(this.hideLinkPopup, this), 'onImageSelect': _.bind(this.showImagePopup, this), 'onImageBlur': _.bind(this.hideImagePopup, this), 'onItemOver': _.bind(this.onImageOver, this), 'onItemOut': _.bind(this.onImageOut, this), 'openInsertLinkDialog': _.bind(this.insertLink, this) }); this.oCrea.start(this.isEnable()); } this.oCrea.setTabIndex(sTabIndex); this.oCrea.clearUndoRedo(); this.setText(sText, bPlain); this.setFontValuesFromText(); this.uploadedImagePathes([]); this.selectedFont(this.sDefaultFont); this.selectedSize(this.iDefaultSize); //this.selectedFont(window.document.queryCommandValue('FontName')); }; CHtmlEditorViewModel.prototype.setFocus = function () { if (this.oCrea) { this.oCrea.setFocus(false); } }; /** * @param {string} sNewSignatureContent * @param {string} sOldSignatureContent */ CHtmlEditorViewModel.prototype.changeSignatureContent = function (sNewSignatureContent, sOldSignatureContent) { if (this.oCrea) { this.oCrea.changeSignatureContent(sNewSignatureContent, sOldSignatureContent); } }; CHtmlEditorViewModel.prototype.setFontValuesFromText = function () { this.lockFontSubscribing(true); this.selectedFont(this.oCrea.getFontName()); this.selectedSize(this.oCrea.getFontSizeInNumber()); this.lockFontSubscribing(false); }; CHtmlEditorViewModel.prototype.isUndoAvailable = function () { if (this.oCrea) { return this.oCrea.isUndoAvailable(); } return false; }; CHtmlEditorViewModel.prototype.getPlainText = function () { if (this.oCrea) { return this.oCrea.getPlainText(); } return ''; }; /** * @param {boolean=} bRemoveSignatureAnchor = false */ CHtmlEditorViewModel.prototype.getText = function (bRemoveSignatureAnchor) { return this.oCrea ? this.oCrea.getText(bRemoveSignatureAnchor) : ''; }; /** * @param {string} sText * @param {boolean} bPlain */ CHtmlEditorViewModel.prototype.setText = function (sText, bPlain) { if (this.oCrea) { if (bPlain) { this.oCrea.setPlainText(sText); } else { this.oCrea.setText(sText); } this.inactive.valueHasMutated(); } }; CHtmlEditorViewModel.prototype.undoAndClearRedo = function () { if (this.oCrea) { this.oCrea.undo(); this.oCrea.clearRedo(); } }; CHtmlEditorViewModel.prototype.getNotDefaultText = function () { var sText = this.getText(); return this.removeAllTags(sText) !== Utils.i18n('HTMLEDITOR/SIGNATURE_PLACEHOLDER') ? sText : ''; }; /** * @param {string} sText */ CHtmlEditorViewModel.prototype.removeAllTags = function (sText) { return sText.replace(/<style>.*<\/style>/g, '').replace(/<[^>]*>/g, ''); }; /** * @param {koProperty} koActivitySource */ CHtmlEditorViewModel.prototype.setActivitySource = function (koActivitySource) { this.activitySource = koActivitySource; if (this.activitySourceSubscription !== null) { this.activitySourceSubscription.dispose(); } this.activitySourceSubscription = this.activitySource.subscribe(function () { this.inactive(Utils.pInt(this.activitySource()) === 0); }, this); this.inactive(Utils.pInt(this.activitySource()) === 0); }; CHtmlEditorViewModel.prototype.onCreaFocus = function () { if (this.oCrea) { this.closeAllPopups(); this.activitySource(1); this.textFocused(true); } }; CHtmlEditorViewModel.prototype.onCreaBlur = function () { if (this.oCrea) { this.textFocused(false); } }; CHtmlEditorViewModel.prototype.closeAllPopups = function () { this.visibleInsertLinkPopup(false); this.visibleInsertImagePopup(false); this.visibleFontColorPopup(false); }; /** * @param {string} sHtml */ CHtmlEditorViewModel.prototype.insertHtml = function (sHtml) { if (this.oCrea) { if (!this.oCrea.isFocused()) { this.oCrea.setFocus(true); } this.oCrea.insertHtml(sHtml, false); } }; CHtmlEditorViewModel.prototype.insertLink = function () { if (!this.visibleInsertLinkPopup()) { this.linkForInsert(this.getMailtoLink(this.oCrea.getSelectedText())); this.closeAllPopups(); this.visibleInsertLinkPopup(true); this.linkFocused(true); } }; /** * @param {Object} oCurrentViewModel * @param {Object} event */ CHtmlEditorViewModel.prototype.insertLinkFromPopup = function (oCurrentViewModel, event) { if (this.linkForInsert().length > 0) { this.linkForInsert(this.getMailtoLink(this.linkForInsert())); this.oCrea.insertLink(this.linkForInsert()); } this.closeInsertLinkPopup(oCurrentViewModel, event); }; /** * @param {Object} oCurrentViewModel * @param {Object} event */ CHtmlEditorViewModel.prototype.closeInsertLinkPopup = function (oCurrentViewModel, event) { this.visibleInsertLinkPopup(false); if (event) { event.stopPropagation(); } }; CHtmlEditorViewModel.prototype.textColor = function () { this.closeAllPopups(); this.visibleFontColorPopup(true); this.oFontColorPicker.onShow(); this.oBackColorPicker.onShow(); }; /** * @param {string} sColor * @return string */ CHtmlEditorViewModel.prototype.colorToHex = function (sColor) { if (sColor.substr(0, 1) === '#') { return sColor; } /*jslint bitwise: true*/ var aDigits = /(.*?)rgb\((\d+), (\d+), (\d+)\)/.exec(sColor), iRed = parseInt(aDigits[2], 10), iGreen = parseInt(aDigits[3], 10), iBlue = parseInt(aDigits[4], 10), iRgb = iBlue | (iGreen << 8) | (iRed << 16), sRgb = iRgb.toString(16) ; /*jslint bitwise: false*/ while (sRgb.length < 6) { sRgb = '0' + sRgb; } return aDigits[1] + '#' + sRgb; }; /** * @param {string} sColor */ CHtmlEditorViewModel.prototype.setTextColorFromPopup = function (sColor) { this.oCrea.textColor(this.colorToHex(sColor)); this.visibleFontColorPopup(false); }; /** * @param {string} sColor */ CHtmlEditorViewModel.prototype.setBackColorFromPopup = function (sColor) { this.oCrea.backgroundColor(this.colorToHex(sColor)); this.visibleFontColorPopup(false); }; CHtmlEditorViewModel.prototype.insertImage = function () { if (this.allowInsertImage() && !this.visibleInsertImagePopup()) { this.imagePathFromWeb(''); this.closeAllPopups(); this.visibleInsertImagePopup(true); this.initUploader(); } return true; }; /** * @param {Object} oCurrentViewModel * @param {Object} event */ CHtmlEditorViewModel.prototype.insertWebImageFromPopup = function (oCurrentViewModel, event) { if (this.allowInsertImage() && this.imagePathFromWeb().length > 0) { this.oCrea.insertImage(this.imagePathFromWeb()); } this.closeInsertImagePopup(oCurrentViewModel, event); }; /** * @param {string} sUid * @param oAttachment */ CHtmlEditorViewModel.prototype.insertComputerImageFromPopup = function (sUid, oAttachment) { var sViewLink = Utils.getViewLinkByHash(AppData.Accounts.currentId(), oAttachment.Hash), bResult = false ; if (this.allowInsertImage() && sViewLink.length > 0) { bResult = this.oCrea.insertImage(sViewLink); if (bResult) { $(this.oCrea.$editableArea) .find('img[src="' + sViewLink + '"]') .attr('data-x-src-cid', sUid) ; oAttachment.CID = sUid; this.uploadedImagePathes.push(oAttachment); } } this.closeInsertImagePopup(); }; /** * @param {?=} oCurrentViewModel * @param {?=} event */ CHtmlEditorViewModel.prototype.closeInsertImagePopup = function (oCurrentViewModel, event) { this.visibleInsertImagePopup(false); if (event) { event.stopPropagation(); } }; /** * Initializes file uploader. */ CHtmlEditorViewModel.prototype.initUploader = function () { if (this.imageUploaderButton() && !this.oJua) { this.oJua = new Jua({ 'action': '?/Upload/Attachment/', 'name': 'jua-uploader', 'queueSize': 2, 'clickElement': this.imageUploaderButton(), 'disableMultiple': true, 'disableAjaxUpload': false, 'disableDragAndDrop': true, 'hidden': { 'Token': function () { return AppData.Token; }, 'AccountID': function () { return AppData.Accounts.currentId(); } } }); if (this.bInsertImageAsBase64) { this.oJua .on('onSelect', _.bind(this.onEditorDrop, this)) ; } else { this.oJua .on('onSelect', _.bind(this.onFileUploadSelect, this)) .on('onComplete', _.bind(this.onFileUploadComplete, this)) ; } } }; /** * Initializes file uploader for editor. */ CHtmlEditorViewModel.prototype.initEditorUploader = function () { if (AppData.App.AllowInsertImage && this.uploaderAreaDom() && !this.editorUploader) { var fBodyDragEnter = null, fBodyDragOver = null ; if (this.oParent && this.oParent.composeUploaderDragOver && this.oParent.onFileUploadProgress && this.oParent.onFileUploadStart && this.oParent.onFileUploadComplete) { fBodyDragEnter = _.bind(function () { this.editorUploaderBodyDragOver(true); this.oParent.composeUploaderDragOver(true); }, this); fBodyDragOver = _.bind(function () { this.editorUploaderBodyDragOver(false); this.oParent.composeUploaderDragOver(false); }, this); this.editorUploader = new Jua({ 'action': '?/Upload/Attachment/', 'name': 'jua-uploader', 'queueSize': 1, 'dragAndDropElement': this.bAllowImageDragAndDrop ? this.uploaderAreaDom() : null, 'disableMultiple': true, 'disableAjaxUpload': false, 'disableDragAndDrop': !this.bAllowImageDragAndDrop, 'hidden': { 'Token': function () { return AppData.Token; }, 'AccountID': function () { return AppData.Accounts.currentId(); } } }); this.editorUploader .on('onDragEnter', _.bind(this.oParent.composeUploaderDragOver, this.oParent, true)) .on('onDragLeave', _.bind(this.oParent.composeUploaderDragOver, this.oParent, false)) .on('onBodyDragEnter', fBodyDragEnter) .on('onBodyDragLeave', fBodyDragOver) .on('onProgress', _.bind(this.oParent.onFileUploadProgress, this.oParent)) .on('onSelect', _.bind(this.onEditorDrop, this)) .on('onStart', _.bind(this.oParent.onFileUploadStart, this.oParent)) .on('onComplete', _.bind(this.oParent.onFileUploadComplete, this.oParent)) ; } else { fBodyDragEnter = _.bind(this.editorUploaderBodyDragOver, this, true); fBodyDragOver = _.bind(this.editorUploaderBodyDragOver, this, false); this.editorUploader = new Jua({ 'queueSize': 1, 'dragAndDropElement': this.bAllowImageDragAndDrop ? this.uploaderAreaDom() : null, 'disableMultiple': true, 'disableAjaxUpload': false, 'disableDragAndDrop': !this.bAllowImageDragAndDrop }); this.editorUploader .on('onBodyDragEnter', fBodyDragEnter) .on('onBodyDragLeave', fBodyDragOver) .on('onSelect', _.bind(this.onEditorDrop, this)) ; } } }; CHtmlEditorViewModel.prototype.onEditorDrop = function (sUid, oData) { var oReader = null, oFile = null, self = this, bCreaFocused = false, hash = Math.random().toString() ; if (oData && oData.File && oData.File.type) { if (AppData.App.AllowInsertImage && 0 === oData.File.type.indexOf('image/')) { oFile = oData.File; if (AppData.App.ImageUploadSizeLimit > 0 && oFile.size > AppData.App.ImageUploadSizeLimit) { App.Screens.showPopup(AlertPopup, [Utils.i18n('COMPOSE/UPLOAD_ERROR_SIZE')]); } else { oReader = new window.FileReader(); bCreaFocused = this.oCrea.isFocused(); if (!bCreaFocused) { this.oCrea.setFocus(true); } this.oCrea.insertHtml('<img id="' + oFile.name + '_' + hash + '" src="skins/Default/images/wait.gif" />', true); if (!bCreaFocused) { this.oCrea.fixFirefoxCursorBug(); } oReader.onload = function (oEvent) { self.oCrea.$editableArea.find('img[id="' + oFile.name + '_' + hash + '"]').attr('src', oEvent.target.result); self.oCrea.editableSave(); }; oReader.readAsDataURL(oFile); } } else { if (this.oParent && this.oParent.onFileUploadSelect) { this.oParent.onFileUploadSelect(sUid, oData); return true; } else if (!App.browser.ie10AndAbove) { App.Screens.showPopup(AlertPopup, [Utils.i18n('HTMLEDITOR/UPLOAD_ERROR_NOT_IMAGE')]); } } } return false; }; /** * @param {Object} oFile */ CHtmlEditorViewModel.prototype.isFileImage = function (oFile) { if (typeof oFile.Type === 'string') { return (-1 !== oFile.Type.indexOf('image')); } else { var iDotPos = oFile.FileName.lastIndexOf('.'), sExt = oFile.FileName.substr(iDotPos + 1), aImageExt = ['jpg', 'jpeg', 'gif', 'tif', 'tiff', 'png'] ; return (-1 !== $.inArray(sExt, aImageExt)); } }; /** * @param {string} sUid * @param {Object} oFile */ CHtmlEditorViewModel.prototype.onFileUploadSelect = function (sUid, oFile) { if (!this.isFileImage(oFile)) { App.Screens.showPopup(AlertPopup, [Utils.i18n('HTMLEDITOR/UPLOAD_ERROR_NOT_IMAGE')]); return false; } this.closeInsertImagePopup(); return true; }; /** * @param {string} sUid * @param {boolean} bResponseReceived * @param {Object} oData */ CHtmlEditorViewModel.prototype.onFileUploadComplete = function (sUid, bResponseReceived, oData) { var sError = ''; if (oData && oData.Result) { if (oData.Result.Error) { sError = oData.Result.Error === 'size' ? Utils.i18n('COMPOSE/UPLOAD_ERROR_SIZE') : Utils.i18n('COMPOSE/UPLOAD_ERROR_UNKNOWN'); App.Screens.showPopup(AlertPopup, [sError]); } else { this.oCrea.setFocus(true); this.insertComputerImageFromPopup(sUid, oData.Result.Attachment); } } else { App.Screens.showPopup(AlertPopup, [Utils.i18n('COMPOSE/UPLOAD_ERROR_UNKNOWN')]); } }; CHtmlEditorViewModel.prototype.getMailtoLink = function (sLink) { return Utils.isCorrectEmail(sLink) ? 'mailto:' + sLink : sLink; }; /** * @constructor * @param {string} sCaption * @param {Function} fPickHandler * @param {Object} oPickContext */ function CColorPickerViewModel(sCaption, fPickHandler, oPickContext) { this.aGreyColors = ['rgb(0, 0, 0)', 'rgb(68, 68, 68)', 'rgb(102, 102, 102)', 'rgb(153, 153, 153)', 'rgb(204, 204, 204)', 'rgb(238, 238, 238)', 'rgb(243, 243, 243)', 'rgb(255, 255, 255)']; this.aBrightColors = ['rgb(255, 0, 0)', 'rgb(255, 153, 0)', 'rgb(255, 255, 0)', 'rgb(0, 255, 0)', 'rgb(0, 255, 255)', 'rgb(0, 0, 255)', 'rgb(153, 0, 255)', 'rgb(255, 0, 255)']; this.aColorLines = [ ['rgb(244, 204, 204)', 'rgb(252, 229, 205)', 'rgb(255, 242, 204)', 'rgb(217, 234, 211)', 'rgb(208, 224, 227)', 'rgb(207, 226, 243)', 'rgb(217, 210, 233)', 'rgb(234, 209, 220)'], ['rgb(234, 153, 153)', 'rgb(249, 203, 156)', 'rgb(255, 229, 153)', 'rgb(182, 215, 168)', 'rgb(162, 196, 201)', 'rgb(159, 197, 232)', 'rgb(180, 167, 214)', 'rgb(213, 166, 189)'], ['rgb(224, 102, 102)', 'rgb(246, 178, 107)', 'rgb(255, 217, 102)', 'rgb(147, 196, 125)', 'rgb(118, 165, 175)', 'rgb(111, 168, 220)', 'rgb(142, 124, 195)', 'rgb(194, 123, 160)'], ['rgb(204, 0, 0)', 'rgb(230, 145, 56)', 'rgb(241, 194, 50)', 'rgb(106, 168, 79)', 'rgb(69, 129, 142)', 'rgb(61, 133, 198)', 'rgb(103, 78, 167)', 'rgb(166, 77, 121)'], ['rgb(153, 0, 0)', 'rgb(180, 95, 6)', 'rgb(191, 144, 0)', 'rgb(56, 118, 29)', 'rgb(19, 79, 92)', 'rgb(11, 83, 148)', 'rgb(53, 28, 117)', 'rgb(116, 27, 71)'], ['rgb(102, 0, 0)', 'rgb(120, 63, 4)', 'rgb(127, 96, 0)', 'rgb(39, 78, 19)', 'rgb(12, 52, 61)', 'rgb(7, 55, 99)', 'rgb(32, 18, 77)', 'rgb(76, 17, 48)'] ]; this.caption = sCaption; this.pickHandler = fPickHandler; this.pickContext = oPickContext; this.colorPickerDom = ko.observable(null); } CColorPickerViewModel.prototype.onShow = function () { $(this.colorPickerDom()).find('span.color-item').on('click', (function (self) { return function () { self.setColorFromPopup($(this).data('color')); }; })(this)); }; /** * @param {string} sColor */ CColorPickerViewModel.prototype.setColorFromPopup = function (sColor) { this.pickHandler.call(this.pickContext, sColor); }; /** * @constructor */ function CPhoneViewModel() { this.phone = App.Phone; this.action = this.phone.action; this.report = this.phone.report; this.logs = ko.observableArray([]); this.logsToShow = ko.observableArray([]); this.spinner = ko.observable(true); this.tooltip = ko.observable(Utils.i18n('PHONE/NOT_CONNECTED')); this.indicator = ko.observable(Utils.i18n('PHONE/MISSED_CALLS')); this.dropdownShow = ko.observable(false); this.input = ko.observable(''); this.input.subscribe(function(sInput) { this.dropdownShow(sInput === '' && this.action() === Enums.PhoneAction.OnlineActive); }, this); this.inputFocus = ko.observable(false); this.inputFocus.subscribe(function(bFocus) { if(bFocus && this.input() === '' && this.action() === Enums.PhoneAction.OnlineActive) { this.dropdownShow(true); } }, this); this.phoneAutocompleteItem = ko.observable(null); this.action.subscribe(function(sAction) { switch (sAction) { case Enums.PhoneAction.Offline: this.tooltip(Utils.i18n('PHONE/NOT_CONNECTED')); break; case Enums.PhoneAction.OfflineError: this.tooltip(Utils.i18n('Connection error')); break; case Enums.PhoneAction.OfflineInit: this.tooltip(Utils.i18n('PHONE/CONNECTING')); break; case Enums.PhoneAction.OfflineActive: break; case Enums.PhoneAction.Online: this.tooltip(Utils.i18n('PHONE/CONNECTED')); this.input(''); this.report(''); this.timer('stop'); break; case Enums.PhoneAction.OnlineActive: break; case Enums.PhoneAction.Outgoing: this.timer('start'); break; case Enums.PhoneAction.OutgoingConnect: this.tooltip(Utils.i18n('In Call')); break; case Enums.PhoneAction.Incoming: break; case Enums.PhoneAction.IncomingConnect: this.tooltip(Utils.i18n('In Call')); this.report(''); this.timer('start'); break; } }, this); $(document).on('click', _.bind(function (e) { if ($(e.target).closest('.item.phone').length === 0) { if (this.action() === Enums.PhoneAction.OnlineActive) { this.action(Enums.PhoneAction.Online); this.dropdownShow(false); } } }, this)); } CPhoneViewModel.prototype.answer = function () { this.action(Enums.PhoneAction.IncomingConnect); }; CPhoneViewModel.prototype.multiAction = function () { var sAction = this.action(); /*if (sAction === Enums.PhoneAction.Offline) { //this.action(Enums.PhoneAction.OfflineActive); } else */ if (sAction === Enums.PhoneAction.OfflineActive) { this.action(Enums.PhoneAction.Offline); } else if (sAction === Enums.PhoneAction.Online) { this.action(Enums.PhoneAction.OnlineActive); this.getLogs(); _.delay(_.bind(function(){ this.inputFocus(true); },this), 500); } else if (sAction === Enums.PhoneAction.OnlineActive && this.validateNumber()) { if (this.phone) { this.phone.phoneToCall(this.input()); this.action(Enums.PhoneAction.Outgoing); } this.inputFocus(false); } else if (sAction === Enums.PhoneAction.OnlineActive && !this.validateNumber()) //online action performed through the loss of focus { this.action(Enums.PhoneAction.Online); this.dropdownShow(false); } else if ( sAction === Enums.PhoneAction.Outgoing || sAction === Enums.PhoneAction.Incoming || sAction === Enums.PhoneAction.OutgoingConnect || sAction === Enums.PhoneAction.IncomingConnect ) { this.action(Enums.PhoneAction.Online); this.dropdownShow(false); } }; CPhoneViewModel.prototype.autocompleteCallback = function (sTerm, fResponse) { var oParameters = { 'Action': 'ContactSuggestions', 'Search': sTerm, 'PhoneOnly': '1' } ; this.phoneAutocompleteItem(null); sTerm = Utils.trim(sTerm); if ('' !== sTerm) { App.Ajax.send(oParameters, function (oData) { var aList = [] //sCategory = '' ; if (oData && oData.Result && oData.Result.List) { _.each(oData.Result.List, function (oItem) { //sCategory = oItem.Name === '' ? oItem.Email : oItem.Name + ' ' + oItem.Email; _.each(oItem.Phones, function (sPhone, sKey) { aList.push({ label: oItem.Name !== '' ? oItem.Name + ' ' + '<' + oItem.Email + '>' : oItem.Email, value: sPhone, frequency: oItem.Frequency //category: sCategory }); }, this); }, this); aList = _.sortBy(_.compact(aList), function(num){ return -(num.frequency); }); } fResponse(aList); }, this); } }; CPhoneViewModel.prototype.validateNumber = function () { return (/^[^a-zA-Z\u00BF-\u1FFF\u2C00-\uD7FF]+$/g).test(this.input()); //Check for letters absence }; CPhoneViewModel.prototype.onLogItem = function (oItem) { this.input(oItem.phoneToCall); this.dropdownShow(false); }; CPhoneViewModel.prototype.getLogs = function () { this.spinner(true); this.logs([]); this.logsToShow([]); this.phone.getLogs(this.onLogsResponse, this); }; CPhoneViewModel.prototype.onLogsResponse = function (oResponse, oRequest) { if (oResponse && oResponse.Result) { this.logs([]); /*_.each(oResponse.Result, function (oStatus) { _.each(oStatus, function (oDirection) { _.each(oDirection, function (oItem) { oItem.phoneToShow = this.phone.getCleanedPhone(oItem.UserDirection === 'incoming' ? oItem.From : oItem.To); if (oItem.phoneToShow) { this.logs.push(oItem); } }, this); }, this); }, this);*/ _.each(oResponse.Result, function (oItem) { oItem.phoneToCall = this.phone.getCleanedPhone(oItem.UserDirection === 'incoming' ? oItem.From : oItem.To); if (oItem.UserDisplayName) { oItem.phoneToShow = oItem.UserDisplayName; } else { oItem.phoneToShow = oItem.phoneToCall; } if (oItem.phoneToShow) { this.logs.push(oItem); } }, this); this.logs(_.sortBy(this.logs(), function(oItem){ return -(Date.parse(oItem.StartTime)); }).slice(0, 100)); this.seeMore(); } this.spinner(false); }; CPhoneViewModel.prototype.seeMore = function () { this.logsToShow(this.logs().slice(0, this.logsToShow().length + 10)); }; CPhoneViewModel.prototype.timer = (function () { var iIntervalId = 0, iSeconds = 0, iMinutes = 0, fAddNull = function (iItem) { var sItem = iItem.toString(); return sItem.length === 1 ? sItem = '0' + sItem : sItem; }; return function (sAction) { if (sAction === 'start') { iSeconds = 0; iMinutes = 0; iIntervalId = setInterval(_.bind(function() { if(iSeconds === 60) { iSeconds = 0; iMinutes++; } this.report(Utils.i18n('PHONE/PASSED_TIME') + ' ' + fAddNull(iMinutes) + ':' + fAddNull(iSeconds)); iSeconds++; }, this), 1000); } else if (sAction === 'stop') { clearInterval(iIntervalId); } }; }()); /** * @constructor */ function CWrapLoginViewModel() { this.rtl = ko.observable(Utils.isRTL()); this.allowRegistration = AppData.App.AllowRegistration; this.allowPasswordReset = AppData.App.AllowPasswordReset; this.oLoginViewModel = new CLoginViewModel(); if (this.allowRegistration) { this.oRegisterViewModel = new CRegisterViewModel(); } if (this.allowPasswordReset) { this.oForgotViewModel = new CForgotViewModel(); } this.gotoForgot = this.allowPasswordReset ? this.oForgotViewModel.gotoForgot : ko.observable(false); this.gotoRegister = ko.observable(false); this.emailVisible = this.oLoginViewModel.emailVisible; this.loginVisible = this.oLoginViewModel.loginVisible; this.loginDescription = ko.observable(AppData.App.LoginDescription || ''); this.aLanguages = AppData.App.Languages; this.currentLanguage = ko.observable(AppData.App.DefaultLanguage); this.allowLanguages = ko.observable(AppData.App.AllowLanguageOnLogin); this.viewLanguagesAsDropdown = ko.observable(!AppData.App.FlagsLangSelect); this.loginCustomLogo = ko.observable(AppData['LoginStyleImage'] || ''); if (AfterLogicApi.runPluginHook) { AfterLogicApi.runPluginHook('view-model-defined', [this.__name, this]); } } CWrapLoginViewModel.prototype.__name = 'CWrapLoginViewModel'; CWrapLoginViewModel.prototype.onShow = function () { if (this.oLoginViewModel.onShow) { this.oLoginViewModel.onShow(); } }; CWrapLoginViewModel.prototype.onApplyBindings = function () { if (this.oLoginViewModel.onApplyBindings) { this.oLoginViewModel.onApplyBindings(); } }; /** * @param {string} sLanguage */ CWrapLoginViewModel.prototype.changeLanguage = function (sLanguage) { if (sLanguage && this.allowLanguages()) { this.currentLanguage(sLanguage); this.oLoginViewModel.changingLanguage(true); App.Ajax.send({ 'Action': 'LoginLanguageUpdate', 'Language': sLanguage }, function () { window.location.reload(); }, this); } }; /** * @constructor */ function CLoginViewModel() { this.allowRegistration = AppData.App.AllowRegistration; this.allowPasswordReset = AppData.App.AllowPasswordReset; this.email = ko.observable(''); this.login = ko.observable(''); this.password = ko.observable(''); this.emailFocus = ko.observable(false); this.loginFocus = ko.observable(false); this.passwordFocus = ko.observable(false); this.loading = ko.observable(false); this.changingLanguage = ko.observable(false); this.loginFocus.subscribe(function (bFocus) { if (bFocus && '' === this.login()) { this.login(this.email()); } }, this); this.loginFormType = ko.observable(AppData.App.LoginFormType); this.loginAtDomainValue = ko.observable(AppData.App.LoginAtDomainValue); this.loginAtDomainValueWithAt = ko.computed(function () { var sV = this.loginAtDomainValue(); return '' === sV ? '' : '@' + sV; }, this); this.emailVisible = ko.computed(function () { return Enums.LoginFormType.Login !== this.loginFormType(); }, this); this.loginVisible = ko.computed(function () { return Enums.LoginFormType.Email !== this.loginFormType(); }, this); this.signMeType = ko.observable(AppData.App.LoginSignMeType); this.signMe = ko.observable(Enums.LoginSignMeType.DefaultOn === this.signMeType()); this.signMeType.subscribe(function () { this.signMe(Enums.LoginSignMeType.DefaultOn === this.signMeType()); }, this); this.signMeFocused = ko.observable(false); this.emailDom = ko.observable(null); this.loginDom = ko.observable(null); this.passwordDom = ko.observable(null); this.focusedField = ''; this.canBeLogin = ko.computed(function () { return !this.loading() && !this.changingLanguage(); }, this); this.signInButtonText = ko.computed(function () { return this.loading() ? Utils.i18n('LOGIN/BUTTON_SIGNING_IN') : Utils.i18n('LOGIN/BUTTON_SIGN_IN'); }, this); this.loginCommand = Utils.createCommand(this, this.signIn, this.canBeLogin); this.email(AppData.App.DemoWebMailLogin || ''); this.password(AppData.App.DemoWebMailPassword || ''); if (AfterLogicApi.runPluginHook) { AfterLogicApi.runPluginHook('view-model-defined', [this.__name, this]); } this.shake = ko.observable(false).extend({'autoResetToFalse': 800}); } CLoginViewModel.prototype.__name = 'CLoginViewModel'; CLoginViewModel.prototype.onApplyBindings = function () { $html.addClass('non-adjustable-valign'); }; CLoginViewModel.prototype.onShow = function () { this.fillFields(); }; CLoginViewModel.prototype.fillFields = function () { _.delay(_.bind(function(){ this.focusFields(); },this), 1); }; CLoginViewModel.prototype.focusFields = function () { if (this.emailVisible() && this.email() === '') { this.emailFocus(true); } else if (this.loginVisible() && this.login() === '') { this.loginFocus(true); } }; CLoginViewModel.prototype.signIn = function () { $('.check_autocomplete_input').trigger('input').trigger('change').trigger('keydown'); var iLoginType = this.loginFormType(), sEmail = this.email(), sLogin = this.login(), sPassword = this.password() ; if (!this.loading() && !this.changingLanguage() && '' !== Utils.trim(sPassword) && ( (Enums.LoginFormType.Login === iLoginType && '' !== Utils.trim(sLogin)) || (Enums.LoginFormType.Email === iLoginType && '' !== Utils.trim(sEmail)) || (Enums.LoginFormType.Both === iLoginType && '' !== Utils.trim(sEmail)) )) { this.sendRequest(); } else { this.shake(true); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CLoginViewModel.prototype.onResponse = function (oResponse, oRequest) { if (false === oResponse.Result) { this.loading(false); this.shake(true); App.Api.showErrorByCode(oResponse, Utils.i18n('WARNING/LOGIN_PASS_INCORRECT')); } else { window.location.reload(); } }; CLoginViewModel.prototype.sendRequest = function () { var oParameters = { 'Action': 'Login', 'Email': this.emailVisible() ? this.email() : '', 'IncLogin': this.loginVisible() ? this.login() : '', 'IncPassword': this.password(), 'SignMe': this.signMe() ? '1' : '0' } ; this.loading(true); App.Ajax.send(oParameters, this.onResponse, this); }; /** * @constructor */ function CForgotViewModel() { this.gotoForgot = ko.observable(false); this.gotoForgot.subscribe(function () { this.visibleEmailForm(true); this.visibleQuestionForm(false); this.visiblePasswordForm(false); }, this); this.visibleEmailForm = ko.observable(true); this.email = ko.observable(''); this.emailFocus = ko.observable(false); this.gettingQuestion = ko.observable(false); this.getQuestionButtonText = ko.computed(function () { return this.gettingQuestion() ? Utils.i18n('LOGIN/BUTTON_GETTING_QUESTION') : Utils.i18n('LOGIN/BUTTON_GET_QUESTION'); }, this); this.allowGetQuestion = ko.computed(function () { return !this.gettingQuestion() && Utils.trim(this.email()) !== ''; }, this); this.getQuestionCommand = Utils.createCommand(this, this.executeGetQuestion, this.allowGetQuestion); this.visibleQuestionForm = ko.observable(false); this.question = ko.observable(''); this.answer = ko.observable(''); this.answerFocus = ko.observable(false); this.validatingAnswer = ko.observable(false); this.validateAnswerButtonText = ko.computed(function () { return this.validatingAnswer() ? Utils.i18n('LOGIN/BUTTON_VALIDATING_ANSWER') : Utils.i18n('LOGIN/BUTTON_VALIDATE_ANSWER'); }, this); this.allowValidatingAnswer = ko.computed(function () { return !this.validatingAnswer() && Utils.trim(this.answer()) !== ''; }, this); this.validateAnswerCommand = Utils.createCommand(this, this.executeValidateAnswer, this.allowValidatingAnswer); this.visiblePasswordForm = ko.observable(false); this.password = ko.observable(''); this.confirmPassword = ko.observable(''); this.passwordFocus = ko.observable(false); this.confirmPasswordFocus = ko.observable(false); this.changingPassword = ko.observable(false); this.changePasswordButtonText = ko.computed(function () { return this.changingPassword() ? Utils.i18n('LOGIN/BUTTON_RESETTING_PASSWORD') : Utils.i18n('LOGIN/BUTTON_RESET_PASSWORD'); }, this); this.allowChangePassword = ko.computed(function () { var sPassword = Utils.trim(this.password()), sConfirmPassword = Utils.trim(this.confirmPassword()), bEmptyFields = (sPassword === '' || sConfirmPassword === '') ; return !this.changingPassword() && !bEmptyFields; }, this); this.changePasswordCommand = Utils.createCommand(this, this.executeChangePassword, this.allowChangePassword); if (AfterLogicApi.runPluginHook) { AfterLogicApi.runPluginHook('view-model-defined', [this.__name, this]); } } CForgotViewModel.prototype.__name = 'CForgotViewModel'; CForgotViewModel.prototype.executeGetQuestion = function () { var oParameters = { 'Action': 'GetForgotAccountQuestion', 'Email': this.email() } ; this.gettingQuestion(true); App.Ajax.send(oParameters, this.onGetQuestionResponse, this); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CForgotViewModel.prototype.onGetQuestionResponse = function (oResponse, oRequest) { var sQuestion = ''; this.gettingQuestion(false); if (false === oResponse.Result) { App.Api.showErrorByCode(oResponse, Utils.i18n('LOGIN/ERROR_GETTING_QUESTION')); } else { sQuestion = Utils.pString(oResponse.Result.Question); if (sQuestion === '') { App.Api.showError(Utils.i18n('LOGIN/ERROR_PASSWORD_RESET_NOT_AVAILABLE')); } else { this.question(sQuestion); this.visibleEmailForm(false); this.visibleQuestionForm(true); this.visiblePasswordForm(false); } } }; CForgotViewModel.prototype.executeValidateAnswer = function () { var oParameters = { 'Action': 'ValidateForgotAccountQuestion', 'Email': this.email(), 'Question': this.question(), 'Answer': this.answer() } ; this.validatingAnswer(true); App.Ajax.send(oParameters, this.onValidateAnswerResponse, this); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CForgotViewModel.prototype.onValidateAnswerResponse = function (oResponse, oRequest) { this.validatingAnswer(false); if (false === oResponse.Result) { App.Api.showErrorByCode(oResponse, Utils.i18n('LOGIN/ERROR_WRONG_ANSWER')); } else { this.visibleEmailForm(false); this.visibleQuestionForm(false); this.visiblePasswordForm(true); } }; CForgotViewModel.prototype.executeChangePassword = function () { if (this.password() !== this.confirmPassword()) { App.Api.showError(Utils.i18n('WARNING/PASSWORDS_DO_NOT_MATCH')); } else { var oParameters = { 'Action': 'ChangeForgotAccountPassword', 'Email': this.email(), 'Question': this.question(), 'Answer': this.answer(), 'Password': this.password() } ; this.changingPassword(true); App.Ajax.send(oParameters, this.onChangePasswordResponse, this); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CForgotViewModel.prototype.onChangePasswordResponse = function (oResponse, oRequest) { this.changingPassword(false); if (false === oResponse.Result) { App.Api.showErrorByCode(oResponse, Utils.i18n('LOGIN/ERROR_RESETTING_PASSWORD')); } else { this.gotoForgot(false); App.Api.showReport(Utils.i18n('LOGIN/REPORT_PASSWORD_CHANGED')); } }; /** * @constructor */ function CRegisterViewModel() { this.name = ko.observable(''); this.login = ko.observable(''); this.password = ko.observable(''); this.confirmPassword = ko.observable(''); this.question = ko.observable(''); this.yourQuestion = ko.observable(''); this.answer = ko.observable(''); this.allowQuestionPart = Utils.isNonEmptyArray(AppData.App.RegistrationQuestions); this.visibleYourQuestion = ko.computed(function () { return (this.question() === Utils.i18n('LOGIN/OPTION_YOUR_QUESTION')); }, this); this.nameFocus = ko.observable(false); this.loginFocus = ko.observable(false); this.passwordFocus = ko.observable(false); this.confirmPasswordFocus = ko.observable(false); this.questionFocus = ko.observable(false); this.answerFocus = ko.observable(false); this.yourQuestionFocus = ko.observable(false); this.domains = ko.observable(Utils.isNonEmptyArray(AppData.App.RegistrationDomains) ? AppData.App.RegistrationDomains : []); this.domain = ko.computed(function () { return (this.domains().length === 1) ? this.domains()[0] : ''; }, this); this.selectedDomain = ko.observable((this.domains().length > 0) ? this.domains()[0] : ''); this.registrationQuestions = []; if (this.allowQuestionPart) { this.registrationQuestions = _.map(_.union('', _.without(AppData.App.RegistrationQuestions, '*')), function (sQuestion) { return {text: (sQuestion !== '') ? sQuestion : Utils.i18n('LOGIN/LABEL_SELECT_QUESTION'), value: sQuestion}; }); if (_.indexOf(AppData.App.RegistrationQuestions, '*') !== -1) { this.registrationQuestions.push({text: Utils.i18n('LOGIN/OPTION_YOUR_QUESTION'), value: Utils.i18n('LOGIN/OPTION_YOUR_QUESTION')}); } } this.loading = ko.observable(false); this.canBeRegister = ko.computed(function () { var sLogin = Utils.trim(this.login()), sPassword = Utils.trim(this.password()), sConfirmPassword = Utils.trim(this.confirmPassword()), sQuestion = Utils.trim(this.visibleYourQuestion() ? this.yourQuestion() : this.question()), sAnswer = Utils.trim(this.answer()), bEmptyFields = (sLogin === '' || sPassword === '' || sConfirmPassword === '' || this.allowQuestionPart && (sQuestion === '' || sAnswer === '')) ; return !this.loading() && !bEmptyFields; }, this); this.registerButtonText = ko.computed(function () { return this.loading() ? Utils.i18n('LOGIN/BUTTON_REGISTERING') : Utils.i18n('LOGIN/BUTTON_REGISTER'); }, this); this.registerCommand = Utils.createCommand(this, this.registerAccount, this.canBeRegister); if (AfterLogicApi.runPluginHook) { AfterLogicApi.runPluginHook('view-model-defined', [this.__name, this]); } } CRegisterViewModel.prototype.__name = 'CRegisterViewModel'; CRegisterViewModel.prototype.registerAccount = function () { if (this.password() !== this.confirmPassword()) { App.Api.showError(Utils.i18n('WARNING/PASSWORDS_DO_NOT_MATCH')); } else { var oParameters = { 'Action': 'RegisterAccount', 'Name': this.name(), 'Email': this.login() + '@' + this.selectedDomain(), 'Password': this.password(), 'Question': this.allowQuestionPart ? (this.visibleYourQuestion() ? this.yourQuestion() : this.question()) : '', 'Answer': this.allowQuestionPart ? this.answer() : '' } ; this.loading(true); App.Ajax.send(oParameters, this.onResponse, this); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CRegisterViewModel.prototype.onResponse = function (oResponse, oRequest) { if (false === oResponse.Result) { this.loading(false); App.Api.showErrorByCode(oResponse, Utils.i18n('WARNING/LOGIN_PASS_INCORRECT')); } else { window.location.reload(); } }; /** * @constructor */ function CFolderListViewModel() { this.accounts = AppData.Accounts.collection; this.mobileApp = bMobileApp; this.folderList = App.MailCache.folderList; this.manageFoldersHash = App.Routing.buildHashFromArray([Enums.Screens.Settings, Enums.SettingsTab.EmailAccounts, Enums.AccountSettingsTab.Folders]); this.quotaProc = ko.observable(-1); this.quotaDesc = ko.observable(''); ko.computed(function () { if (!AppData.App || AppData.App && !AppData.App.ShowQuotaBar) { return true; } App.MailCache.quotaChangeTrigger(); var oAccount = AppData.Accounts.getCurrent(), iQuota = oAccount ? oAccount.quota() : 0, iUsed = oAccount ? oAccount.usedSpace() : 0, iProc = 0 < iQuota ? Math.ceil((iUsed / iQuota) * 100) : -1 ; iProc = 100 < iProc ? 100 : iProc; this.quotaProc(iProc); this.quotaDesc(-1 < iProc ? Utils.i18n('MAILBOX/QUOTA_TOOLTIP', { 'PROC': iProc, 'QUOTA': Utils.friendlySize(iQuota * 1024) }) : ''); return true; }, this); } /** * @constructor * * @param {Function} fOpenMessageInNewWindowBinded */ function CMessageListViewModel(fOpenMessageInNewWindowBinded) { this.isPublic = bExtApp; this.uploaderArea = ko.observable(null); this.bDragActive = ko.observable(false); this.bDragActiveComp = ko.computed(function () { return this.bDragActive(); }, this); this.openMessageInNewWindowBinded = fOpenMessageInNewWindowBinded; this.isFocused = ko.observable(false); this.messagesContainer = ko.observable(null); this.searchInput = ko.observable(''); this.searchInputFrom = ko.observable(''); this.searchInputTo = ko.observable(''); this.searchInputSubject = ko.observable(''); this.searchInputText = ko.observable(''); this.searchSpan = ko.observable(''); this.highlightTrigger = ko.observable(''); this.currentMessage = App.MailCache.currentMessage; this.currentMessage.subscribe(function () { this.isFocused(false); this.selector.itemSelected(this.currentMessage()); }, this); this.folderList = App.MailCache.folderList; this.folderList.subscribe(this.onFolderListSubscribe, this); this.folderFullName = ko.observable(''); this.filters = ko.observable(''); this.uidList = App.MailCache.uidList; this.uidList.subscribe(function () { if (this.uidList().searchCountSubscription) { this.uidList().searchCountSubscription.dispose(); this.uidList().searchCountSubscription = undefined; } this.uidList().searchCountSubscription = this.uidList().resultCount.subscribe(function () { if (this.uidList().resultCount() >= 0) { this.oPageSwitcher.setCount(this.uidList().resultCount()); } }, this); if (this.uidList().resultCount() >= 0) { this.oPageSwitcher.setCount(this.uidList().resultCount()); } }, this); this.useThreads = ko.computed(function () { var oFolder = this.folderList().currentFolder(), bFolderWithoutThreads = oFolder && oFolder.withoutThreads(), bNotSearchOrFilters = this.uidList().search() === '' && this.uidList().filters() === '' ; return AppData.User.useThreads() && !bFolderWithoutThreads && bNotSearchOrFilters; }, this); this.collection = App.MailCache.messages; this._search = ko.observable(''); this.search = ko.computed({ 'read': function () { return Utils.trim(this._search()); }, 'write': this._search, 'owner': this }); this.isEmptyList = ko.computed(function () { return this.collection().length === 0; }, this); this.isNotEmptyList = ko.computed(function () { return this.collection().length !== 0; }, this); this.isSearch = ko.computed(function () { return this.search().length > 0; }, this); this.isUnseenFilter = ko.computed(function () { return this.filters() === Enums.FolderFilter.Unseen; }, this); this.isLoading = App.MailCache.messagesLoading; this.isError = App.MailCache.messagesLoadingError; this.visibleInfoLoading = ko.computed(function () { return !this.isSearch() && this.isLoading(); }, this); this.visibleInfoSearchLoading = ko.computed(function () { return this.isSearch() && this.isLoading(); }, this); this.visibleInfoSearchList = ko.computed(function () { return this.isSearch() && !this.isUnseenFilter() && !this.isLoading() && !this.isEmptyList(); }, this); this.visibleInfoMessageListEmpty = ko.computed(function () { return !this.isLoading() && !this.isSearch() && (this.filters() === '') && this.isEmptyList() && !this.isError(); }, this); this.visibleInfoStarredFolderEmpty = ko.computed(function () { return !this.isLoading() && !this.isSearch() && (this.filters() === Enums.FolderFilter.Flagged) && this.isEmptyList() && !this.isError(); }, this); this.visibleInfoSearchEmpty = ko.computed(function () { return this.isSearch() && !this.isUnseenFilter() && this.isEmptyList() && !this.isError() && !this.isLoading(); }, this); this.visibleInfoMessageListError = ko.computed(function () { return !this.isSearch() && this.isError(); }, this); this.visibleInfoSearchError = ko.computed(function () { return this.isSearch() && this.isError(); }, this); this.visibleInfoUnseenFilterList = ko.computed(function () { return this.isUnseenFilter() && !this.isLoading() && !this.isEmptyList(); }, this); this.visibleInfoUnseenFilterEmpty = ko.computed(function () { return this.isUnseenFilter() && this.isEmptyList() && !this.isError() && !this.isLoading(); }, this); this.searchText = ko.computed(function () { return Utils.i18n('MAILBOX/INFO_SEARCH_RESULT', { 'SEARCH': this.calculateSearchStringForDescription(), 'FOLDER': this.folderList().currentFolder() ? this.folderList().currentFolder().displayName() : '' }); }, this); this.unseenFilterText = ko.computed(function () { if (this.search() === '') { return Utils.i18n('MAILBOX/INFO_UNSEEN_FILTER_RESULT', { 'FOLDER': this.folderList().currentFolder() ? this.folderList().currentFolder().displayName() : '' }); } else { return Utils.i18n('MAILBOX/INFO_SEARCH_UNSEEN_FILTER_RESULT', { 'SEARCH': this.calculateSearchStringForDescription(), 'FOLDER': this.folderList().currentFolder() ? this.folderList().currentFolder().displayName() : '' }); } }, this); this.unseenFilterEmptyText = ko.computed(function () { if (this.search() === '') { return Utils.i18n('MAILBOX/INFO_UNSEEN_FILTER_EMPTY'); } else { return Utils.i18n('MAILBOX/INFO_SEARCH_UNSEEN_FILTER_EMPTY'); } }, this); this.isEnableGroupOperations = ko.observable(false).extend({'throttle': 250}); this.selector = new CSelector( this.collection, _.bind(this.routeForMessage, this), _.bind(this.onDeletePress, this), _.bind(this.onMessageDblClick, this), _.bind(this.onEnterPress, this) ); this.checkedUids = ko.computed(function () { var aChecked = this.selector.listChecked(), aCheckedUids = _.map(aChecked, function (oItem) { return oItem.uid(); }), oFolder = App.MailCache.folderList().currentFolder(), aThreadCheckedUids = oFolder ? oFolder.getThreadCheckedUidsFromList(aChecked) : [], aUids = _.union(aCheckedUids, aThreadCheckedUids) ; return aUids; }, this); this.checkedOrSelectedUids = ko.computed(function () { var aChecked = this.checkedUids(); if (aChecked.length === 0 && App.MailCache.currentMessage() && !App.MailCache.currentMessage().deleted()) { aChecked = [App.MailCache.currentMessage().uid()]; } return aChecked; }, this); ko.computed(function () { this.isEnableGroupOperations(0 < this.selector.listCheckedOrSelected().length); }, this); this.checkAll = this.selector.koCheckAll(); this.checkAllIncomplite = this.selector.koCheckAllIncomplete(); this.pageSwitcherLocked = ko.observable(false); this.oPageSwitcher = new CPageSwitcherViewModel(0, AppData.User.MailsPerPage); this.oPageSwitcher.currentPage.subscribe(function (iPage) { var sFolder = this.folderList().currentFolderFullName(), sUid = !bMobileApp && this.currentMessage() ? this.currentMessage().uid() : '', sSearch = this.search() ; if (!this.pageSwitcherLocked()) { this.changeRoutingForMessageList(sFolder, iPage, sUid, sSearch, this.filters()); } }, this); this.currentPage = ko.observable(0); // to the message list does not twitch if (App.browser.firefox || App.browser.ie) { this.listChangedThrottle = ko.observable(false).extend({'throttle': 10}); } else { this.listChangedThrottle = ko.observable(false); } this.firstCompleteCollection = ko.observable(true); this.collection.subscribe(function () { if (this.collection().length > 0) { this.firstCompleteCollection(false); } }, this); this.currentAccountId = AppData.Accounts.currentId; this.listChanged = ko.computed(function () { return [ this.firstCompleteCollection(), this.currentAccountId(), this.folderFullName(), this.filters(), this.search(), this.oPageSwitcher.currentPage() ]; }, this); this.listChanged.subscribe(function() { this.listChangedThrottle(!this.listChangedThrottle()); }, this); this.bAdvancedSearch = ko.observable(false); this.searchAttachmentsCheckbox = ko.observable(false); this.searchAttachments = ko.observable(''); this.searchAttachments.subscribe(function(sText) { this.searchAttachmentsCheckbox(!!sText); }, this); this.panelTopDom = ko.observable(null); this.extendedDom = ko.observable(null); this.searchAttachmentsFocus = ko.observable(false); this.searchFromFocus = ko.observable(false); this.searchSubjectFocus = ko.observable(false); this.searchToFocus = ko.observable(false); this.searchTextFocus = ko.observable(false); this.searchTrigger = ko.observable(null); this.searchDateStartFocus = ko.observable(false); this.searchDateEndFocus = ko.observable(false); this.searchDateStartDom = ko.observable(null); this.searchDateStart = ko.observable(''); this.searchDateEndDom = ko.observable(null); this.searchDateEnd = ko.observable(''); this.dateFormatDatePicker = 'yy.mm.dd'; this.attachmentsPlaceholder = ko.computed(function () { return Utils.i18n('MAILBOX/SEARCH_FIELD_HAS_ATTACHMENTS'); }, this); _.delay(_.bind(function(){ this.createDatePickerObject(this.searchDateStartDom()); this.createDatePickerObject(this.searchDateEndDom()); }, this), 1000); } CMessageListViewModel.prototype.createDatePickerObject = function (oElement) { $(oElement).datepicker({ showOtherMonths: true, selectOtherMonths: true, monthNames: Utils.getMonthNamesArray(), dayNamesMin: Utils.i18n('DATETIME/DAY_NAMES_MIN').split(' '), firstDay: AppData.User.CalendarWeekStartsOn, showOn: 'focus', dateFormat: this.dateFormatDatePicker }); $(oElement).mousedown(function() { $('#ui-datepicker-div').toggle(); }); }; /** * @param {string} sFolder * @param {number} iPage * @param {string} sUid * @param {string} sSearch * @param {string} sFilters */ CMessageListViewModel.prototype.changeRoutingForMessageList = function (sFolder, iPage, sUid, sSearch, sFilters) { var bSame = App.Routing.setHash(App.Links.mailbox(sFolder, iPage, sUid, sSearch, sFilters)); if (bSame && sSearch.length > 0 && this.search() === sSearch) { this.listChangedThrottle(!this.listChangedThrottle()); } }; /** * @param {CMessageModel} oMessage */ CMessageListViewModel.prototype.onEnterPress = function (oMessage) { oMessage.openThread(); }; /** * @param {CMessageModel} oMessage */ CMessageListViewModel.prototype.onMessageDblClick = function (oMessage) { var oFolder = this.folderList().getFolderByFullName(oMessage.folder()) ; if (oFolder.type() === Enums.FolderTypes.Drafts) { App.Routing.setHash(App.Links.composeFromMessage('drafts', oMessage.folder(), oMessage.uid())); } else { this.openMessageInNewWindowBinded(oMessage); } }; CMessageListViewModel.prototype.onFolderListSubscribe = function () { this.setCurrentFolder(); this.requestMessageList(); }; /** * @param {Array} aParams */ CMessageListViewModel.prototype.onShow = function (aParams) { this.selector.useKeyboardKeys(true); this.oPageSwitcher.show(); if (this.oJua) { this.oJua.setDragAndDropEnabledStatus(true); } }; /** * @param {Array} aParams */ CMessageListViewModel.prototype.onHide = function (aParams) { this.selector.useKeyboardKeys(false); this.oPageSwitcher.hide(); if (this.oJua) { this.oJua.setDragAndDropEnabledStatus(false); } }; /** * @param {Array} aParams */ CMessageListViewModel.prototype.onRoute = function (aParams) { var oParams = App.Links.parseMailbox(aParams), bRouteChanged = this.currentPage() !== oParams.Page || this.folderFullName() !== oParams.Folder || this.filters() !== oParams.Filters || (oParams.Filters === Enums.FolderFilter.Unseen && App.MailCache.waitForUnseenMessages()) || this.search() !== oParams.Search, bMailsPerPageChanged = AppData.User.MailsPerPage !== this.oPageSwitcher.perPage() ; this.pageSwitcherLocked(true); if (this.folderFullName() !== oParams.Folder || this.search() !== oParams.Search || this.filters() !== oParams.Filters) { this.oPageSwitcher.clear(); } else { this.oPageSwitcher.setPage(oParams.Page, AppData.User.MailsPerPage); } this.pageSwitcherLocked(false); if (oParams.Page !== this.oPageSwitcher.currentPage()) { App.Routing.replaceHash(App.Links.mailbox(oParams.Folder, this.oPageSwitcher.currentPage(), oParams.Uid, oParams.Search, oParams.Filters)); } this.currentPage(this.oPageSwitcher.currentPage()); this.folderFullName(oParams.Folder); this.filters(oParams.Filters); this.search(oParams.Search); this.searchInput(this.search()); this.searchSpan.notifySubscribers(); this.setCurrentFolder(); if (bRouteChanged || bMailsPerPageChanged || this.collection().length === 0) { if (oParams.Filters === Enums.FolderFilter.Unseen) { App.MailCache.waitForUnseenMessages(true); } this.requestMessageList(); } this.highlightTrigger.notifySubscribers(true); }; CMessageListViewModel.prototype.setCurrentFolder = function () { this.folderList().setCurrentFolder(this.folderFullName(), this.filters()); }; CMessageListViewModel.prototype.requestMessageList = function () { var sFullName = this.folderList().currentFolderFullName(), iPage = this.oPageSwitcher.currentPage() ; if (sFullName.length > 0) { App.MailCache.changeCurrentMessageList(sFullName, iPage, this.search(), this.filters()); } else { App.MailCache.checkCurrentFolderList(); } }; CMessageListViewModel.prototype.calculateSearchStringFromAdvancedForm = function () { var sFrom = this.searchInputFrom(), sTo = this.searchInputTo(), sSubject = this.searchInputSubject(), sText = this.searchInputText(), bAttachmentsCheckbox = this.searchAttachmentsCheckbox(), sAttachments = this.searchAttachments(), sDateStart = this.searchDateStart(), sDateEnd = this.searchDateEnd(), aOutput = [], fEsc = function (sText) { sText = $.trim(sText).replace(/"/g, '\\"'); if (-1 < sText.indexOf(' ') || -1 < sText.indexOf('"')) { sText = '"' + sText + '"'; } return sText; } ; if (sFrom !== '') { aOutput.push('from:' + fEsc(sFrom)); } if (sTo !== '') { aOutput.push('to:' + fEsc(sTo)); } if (sSubject !== '') { aOutput.push('subject:' + fEsc(sSubject)); } if (sText !== '') { aOutput.push('text:' + fEsc(sText)); } if (bAttachmentsCheckbox) { aOutput.push('has:attachments'); } /*if (sAttachments !== '') { aOutput.push('attachments:' + fEsc(sAttachments)); }*/ if (sDateStart !== '' || sDateEnd !== '') { aOutput.push('date:' + fEsc(sDateStart) + '/' + fEsc(sDateEnd)); } return aOutput.join(' '); }; CMessageListViewModel.prototype.onSearchClick = function () { var sFolder = this.folderList().currentFolderFullName(), //sUid = this.currentMessage() ? this.currentMessage().uid() : '', iPage = 1, sSearch = this.searchInput() ; if (this.bAdvancedSearch()) { sSearch = this.calculateSearchStringFromAdvancedForm(); this.searchInput(sSearch); this.bAdvancedSearch(false); } this.changeRoutingForMessageList(sFolder, iPage, '', sSearch, this.filters()); //this.highlightTrigger.notifySubscribers(); }; CMessageListViewModel.prototype.onRetryClick = function () { this.requestMessageList(); }; CMessageListViewModel.prototype.onClearSearchClick = function () { var sFolder = this.folderList().currentFolderFullName(), sUid = this.currentMessage() ? this.currentMessage().uid() : '', sSearch = '', iPage = 1 ; this.clearAdvancedSearch(); this.changeRoutingForMessageList(sFolder, iPage, sUid, sSearch, this.filters()); }; CMessageListViewModel.prototype.onClearFilterClick = function () { var sFolder = this.folderList().currentFolderFullName(), sUid = this.currentMessage() ? this.currentMessage().uid() : '', sSearch = '', iPage = 1, sFilters = '' ; this.clearAdvancedSearch(); this.changeRoutingForMessageList(sFolder, iPage, sUid, sSearch, sFilters); }; CMessageListViewModel.prototype.onStopSearchClick = function () { this.onClearSearchClick(); }; /** * @param {Object} oMessage */ CMessageListViewModel.prototype.routeForMessage = function (oMessage) { if (oMessage !== null) { var oFolder = this.folderList().currentFolder(), sFolder = this.folderList().currentFolderFullName(), iPage = this.oPageSwitcher.currentPage(), sUid = oMessage.uid(), sSearch = this.search() ; if (sUid !== '') { if (bMobileApp && oFolder.type() === Enums.FolderTypes.Drafts) { App.Routing.setHash(App.Links.composeFromMessage('drafts', oMessage.folder(), oMessage.uid())); } else { this.changeRoutingForMessageList(sFolder, iPage, sUid, sSearch, this.filters()); if (bMobileApp && App.MailCache.currentMessage() && sUid === App.MailCache.currentMessage().uid()) { App.MailCache.currentMessage.valueHasMutated(); } } } } }; /** * @param {Object} $viewModel */ CMessageListViewModel.prototype.onApplyBindings = function ($viewModel) { var self = this, fStopPopagation = _.bind(function (oEvent) { if (oEvent && oEvent.stopPropagation) { oEvent.stopPropagation(); } }, this) ; $('.message_list', $viewModel) .on('click', function () { self.isFocused(false); }) .on('click', '.message_sub_list .item .flag', function (oEvent) { self.onFlagClick(ko.dataFor(this)); if (oEvent && oEvent.stopPropagation) { oEvent.stopPropagation(); } }) .on('dblclick', '.message_sub_list .item .flag', fStopPopagation) .on('click', '.message_sub_list .item .thread', fStopPopagation) .on('dblclick', '.message_sub_list .item .thread', fStopPopagation) ; this.selector.initOnApplyBindings( '.message_sub_list .item', '.message_sub_list .item.selected', '.message_sub_list .item .custom_checkbox', $('.message_list', $viewModel), $('.message_list_scroll.scroll-inner', $viewModel) ); this.initUploader(); }; /** * Puts / removes the message flag by clicking on it. * * @param {Object} oMessage */ CMessageListViewModel.prototype.onFlagClick = function (oMessage) { App.MailCache.executeGroupOperation('MessageSetFlagged', [oMessage.uid()], 'flagged', !oMessage.flagged()); }; /** * Marks the selected messages read. */ CMessageListViewModel.prototype.executeMarkAsRead = function () { App.MailCache.executeGroupOperation('MessageSetSeen', this.checkedOrSelectedUids(), 'seen', true); }; /** * Marks the selected messages unread. */ CMessageListViewModel.prototype.executeMarkAsUnread = function () { App.MailCache.executeGroupOperation('MessageSetSeen', this.checkedOrSelectedUids(), 'seen', false); }; /** * Marks Read all messages in a folder. */ CMessageListViewModel.prototype.executeMarkAllRead = function () { App.MailCache.executeGroupOperation('MessageSetAllSeen', [], 'seen', true); }; /** * Moves the selected messages in the current folder in the specified. * * @param {string} sToFolder */ CMessageListViewModel.prototype.executeMoveToFolder = function (sToFolder) { App.MailCache.moveMessagesToFolder(sToFolder, this.checkedOrSelectedUids()); }; CMessageListViewModel.prototype.executeCopyToFolder = function (sToFolder) { App.MailCache.copyMessagesToFolder(sToFolder, this.checkedOrSelectedUids()); }; /** * Calls for the selected messages delete operation. Called from the keyboard. * * @param {Array} aMessages */ CMessageListViewModel.prototype.onDeletePress = function (aMessages) { var aUids = _.map(aMessages, function (oMessage) { return oMessage.uid(); }); if (aUids.length > 0) { this.deleteMessages(aUids); } }; /** * Calls for the selected messages delete operation. Called by the mouse click on the delete button. */ CMessageListViewModel.prototype.executeDelete = function () { this.deleteMessages(this.checkedOrSelectedUids()); }; /** * Moves the specified messages in the current folder to the Trash or delete permanently * if the current folder is Trash or Spam. * * @param {Array} aUids */ CMessageListViewModel.prototype.deleteMessages = function (aUids) { var sCurrFolder = this.folderList().currentFolderFullName(), oTrash = this.folderList().trashFolder(), bInTrash =(oTrash && sCurrFolder === oTrash.fullName()), oSpam = this.folderList().spamFolder(), bInSpam = (oSpam && sCurrFolder === oSpam.fullName()), fDeleteMessages = function (bResult) { if (bResult) { App.MailCache.deleteMessages(aUids); } } ; if (bInSpam) { App.MailCache.deleteMessages(aUids); } else if (bInTrash) { App.Screens.showPopup(ConfirmPopup, [Utils.i18n('MAILBOX/CONFIRM_MESSAGES_DELETE'), fDeleteMessages]); } else if (oTrash) { App.MailCache.moveMessagesToFolder(oTrash.fullName(), this.checkedOrSelectedUids()); } else if (!oTrash) { App.Screens.showPopup(ConfirmPopup, [Utils.i18n('MAILBOX/CONFIRM_MESSAGES_DELETE_NO_TRASH_FOLDER'), fDeleteMessages]); } }; /** * Moves the selected messages from the current folder to the folder Spam. */ CMessageListViewModel.prototype.executeSpam = function () { var sSpamFullName = this.folderList().spamFolderFullName(); if (this.folderList().currentFolderFullName() !== sSpamFullName) { App.MailCache.moveMessagesToFolder(sSpamFullName, this.checkedOrSelectedUids()); } }; /** * Moves the selected messages from the Spam folder to folder Inbox. */ CMessageListViewModel.prototype.executeNotSpam = function () { var oInbox = this.folderList().inboxFolder(); if (oInbox && this.folderList().currentFolderFullName() !== oInbox.fullName()) { App.MailCache.moveMessagesToFolder(oInbox.fullName(), this.checkedOrSelectedUids()); } }; CMessageListViewModel.prototype.clearAdvancedSearch = function () { this.searchInputFrom(''); this.searchInputTo(''); this.searchInputSubject(''); this.searchInputText(''); this.bAdvancedSearch(false); this.searchAttachmentsCheckbox(false); this.searchAttachments(''); this.searchDateStart(''); this.searchDateEnd(''); }; CMessageListViewModel.prototype.onAdvancedSearchClick = function () { this.bAdvancedSearch(!this.bAdvancedSearch()); }; CMessageListViewModel.prototype.calculateSearchStringForDescription = function () { return '<span class="part">' + Utils.encodeHtml(this.search()) + '</span>'; }; CMessageListViewModel.prototype.initUploader = function () { var self = this; if (this.uploaderArea()) { this.oJua = new Jua({ 'action': '?/Upload/Message/', 'name': 'jua-uploader', 'queueSize': 2, 'dragAndDropElement': this.uploaderArea(), 'disableAjaxUpload': this.isPublic, 'disableFolderDragAndDrop': this.isPublic, 'disableDragAndDrop': this.isPublic, 'hidden': { 'Token': function () { return AppData.Token; }, 'AccountID': function () { return AppData.Accounts.currentId(); }, 'AdditionalData': function (oFile) { return JSON.stringify({ 'Folder': self.folderFullName() }); } } }); this.oJua .on('onDrop', _.bind(this.onMessageDrop, this)) .on('onComplete', _.bind(this.onMessageUploadComplete, this)) .on('onBodyDragEnter', _.bind(this.bDragActive, this, true)) .on('onBodyDragLeave', _.bind(this.bDragActive, this, false)) ; } }; CMessageListViewModel.prototype.onMessageDrop = function (oData) { if (!(oData && oData.File && oData.File.type && oData.File.type.indexOf('message/') === 0)) { App.Api.showError(Utils.i18n('MAILBOX/ERROR_UPLOAD_EML')); } }; CMessageListViewModel.prototype.onMessageUploadComplete = function (sMessageFileUid, bResponseReceived, oResult) { var bError = !bResponseReceived || !oResult || oResult.Error || false; if (!bError) { App.MailCache.executeCheckMail(); } else { App.Api.showError(Utils.i18n('MAILBOX/ERROR_UPLOAD_EML')); } }; /** * @constructor * * @param {Function} fOpenMessageInNewWindowBinded */ function CMessagePaneViewModel(fOpenMessageInNewWindowBinded) { this.openMessageInNewWindowBinded = fOpenMessageInNewWindowBinded; this.singleMode = ko.observable(AppData.SingleMode); this.isLoading = ko.observable(false); this.messages = App.MailCache.messages; this.messages.subscribe(this.onMessagesSubscribe, this); this.currentMessage = App.MailCache.currentMessage; this.currentMessage.subscribe(this.onCurrentMessageSubscribe, this); AppData.User.defaultTimeFormat.subscribe(this.onCurrentMessageSubscribe, this); this.displayedMessageUid = ko.observable(''); this.isCurrentMessage = ko.computed(function () { return !!this.currentMessage(); }, this); this.isCurrentMessageLoaded = ko.computed(function () { return this.isCurrentMessage() && !this.isLoading(); }, this); this.visibleNoMessageSelectedText = ko.computed(function () { return this.messages().length > 0 && !this.isCurrentMessage(); }, this); this.prevMessageUid = App.MailCache.prevMessageUid; this.nextMessageUid = App.MailCache.nextMessageUid; this.isEnablePrevMessage = ko.computed(function () { return typeof this.prevMessageUid() === 'string' && this.prevMessageUid() !== ''; }, this); this.isEnableNextMessage = ko.computed(function () { return typeof this.nextMessageUid() === 'string' && this.nextMessageUid() !== ''; }, this); this.isEnableDelete = this.isCurrentMessage; this.isEnableReply = this.isCurrentMessageLoaded; this.isEnableReplyAll = this.isCurrentMessageLoaded; this.isEnableResend = this.isCurrentMessageLoaded; this.isEnableForward = this.isCurrentMessageLoaded; this.isEnablePrint = this.isCurrentMessageLoaded; this.isEnableSave = this.isCurrentMessage; this.allowSaveAsPdf = ko.observable(!!AppData.AllowSaveAsPdf); this.isEnableSaveAsPdf = ko.computed(function () { return this.isCurrentMessageLoaded() && this.allowSaveAsPdf(); }, this); this.deleteCommand = Utils.createCommand(this, this.executeDeleteMessage, this.isEnableDelete); this.prevMessageCommand = Utils.createCommand(this, this.executePrevMessage, this.isEnablePrevMessage); this.nextMessageCommand = Utils.createCommand(this, this.executeNextMessage, this.isEnableNextMessage); this.replyCommand = Utils.createCommand(this, this.executeReply, this.isEnableReply); this.replyAllCommand = Utils.createCommand(this, this.executeReplyAll, this.isEnableReplyAll); this.resendCommand = Utils.createCommand(this, this.executeResend, this.isEnableResend); this.forwardCommand = Utils.createCommand(this, this.executeForward, this.isEnableForward); this.printCommand = Utils.createCommand(this, this.executePrint, this.isEnablePrint); this.saveCommand = Utils.createCommand(this, this.executeSave, this.isEnableSave); this.saveAsPdfCommand = Utils.createCommand(this, this.executeSaveAsPdf, this.isEnableSaveAsPdf); this.moreCommand = Utils.createCommand(this, null, this.isCurrentMessageLoaded); this.ical = ko.observable(null); this.icalSubscription = this.ical.subscribe(function () { if (this.ical() !== null) { App.CalendarCache.firstRequestCalendarList(); this.icalSubscription.dispose(); } }, this); this.vcard = ko.observable(null); this.processed = ko.observable(false); this.visiblePicturesControl = ko.observable(false); this.visibleShowPicturesLink = ko.observable(false); this.visibleAppointmentInfo = ko.computed(function () { return this.ical() !== null; }, this); this.visibleVcardInfo = ko.computed(function () { return this.vcard() !== null; }, this); this.sensitivityText = ko.computed(function () { var sText = ''; if (this.currentMessage()) { switch (this.currentMessage().sensitivity()) { case Enums.Sensivity.Confidential: sText = Utils.i18n('MESSAGE/SENSIVITY_CONFIDENTIAL'); break; case Enums.Sensivity.Personal: sText = Utils.i18n('MESSAGE/SENSIVITY_PERSONAL'); break; case Enums.Sensivity.Private: sText = Utils.i18n('MESSAGE/SENSIVITY_PRIVATE'); break; } } return sText; }, this); this.visibleConfirmationControl = ko.computed(function () { return (this.currentMessage() && this.currentMessage().readingConfirmation() !== ''); }, this); this.isCurrentNotDraftOrSent = ko.computed(function () { var oCurrFolder = App.MailCache.folderList().currentFolder(); return (oCurrFolder && oCurrFolder.fullName().length > 0 && oCurrFolder.type() !== Enums.FolderTypes.Drafts && oCurrFolder.type() !== Enums.FolderTypes.Sent); }, this); this.isCurrentSentFolder = ko.computed(function () { var oCurrFolder = App.MailCache.folderList().currentFolder(); return oCurrFolder && oCurrFolder.fullName().length > 0 && oCurrFolder.type() === Enums.FolderTypes.Sent; }, this); this.isCurrentNotDraftFolder = ko.computed(function () { var oCurrFolder = App.MailCache.folderList().currentFolder(); return (oCurrFolder && oCurrFolder.fullName().length > 0 && oCurrFolder.type() !== Enums.FolderTypes.Drafts); }, this); this.isVisibleReplyTool = this.isCurrentNotDraftOrSent; this.isVisibleResendTool = this.isCurrentSentFolder; this.isVisibleForwardTool = this.isCurrentNotDraftFolder; this.uid = ko.observable(''); this.folder = ko.observable(''); this.subject = ko.observable(''); this.emptySubject = ko.computed(function () { return (Utils.trim(this.subject()) === ''); }, this); this.subjectForDisplay = ko.computed(function () { return this.emptySubject() ? Utils.i18n('MAILBOX/EMPTY_SUBJECT') : this.subject(); }, this); this.importance = ko.observable(Enums.Importance.Normal); this.oFromAddr = ko.observable(null); this.from = ko.observable(''); this.fromEmail = ko.observable(''); this.fullFrom = ko.observable(''); this.to = ko.observable(''); this.aToAddr = ko.observableArray([]); this.cc = ko.observable(''); this.aCcAddr = ko.observableArray([]); this.bcc = ko.observable(''); this.aBccAddr = ko.observableArray([]); this.allRecipients = ko.observable(''); this.aAllRecipients = ko.observableArray([]); this.recipientsContacts = ko.observableArray([]); this.currentAccountEmail = ko.observable(); this.meSender = Utils.i18n('MESSAGE/ME_SENDER'); this.meRecipient = Utils.i18n('MESSAGE/ME_RECIPIENT'); this.fullDate = ko.observable(''); this.midDate = ko.observable(''); this.textBody = ko.observable(''); this.textBodyForNewWindow = ko.observable(''); this.domTextBody = ko.observable(null); this.rtlMessage = ko.observable(false); this.contentHasFocus = ko.observable(false); this.decryptPassword = ko.observable(''); this.visibleDecryptControl = ko.observable(false); this.visibleVerifyControl = ko.observable(false); this.fakeHeader = ko.computed(function () { return !(this.visiblePicturesControl() || this.visibleConfirmationControl() || this.sensitivityText() !== '' || this.visibleDecryptControl() || this.visibleVerifyControl()); }, this); this.mobileApp = bMobileApp; this.attachments = ko.observableArray([]); this.usesAttachmentString = true; this.attachmentsInString = ko.computed(function () { return _.map(this.attachments(), function (oAttachment) { return oAttachment.fileName(); }, this).join(', '); }, this); this.notInlineAttachments = ko.computed(function () { return _.filter(this.attachments(), function (oAttach) { return !oAttach.linked(); }); }, this); this.visibleDownloadAllAttachments = ko.computed(function () { return AppData.ZipAttachments && this.notInlineAttachments().length > 1; }, this); this.visibleSaveAttachmentsToFiles = AppData.User.IsFilesSupported; this.visibleDownloadAllAttachmentsSeparately = ko.computed(function () { return this.notInlineAttachments().length > 1; }, this); this.visibleExtendedDownload = ko.computed(function () { return !this.mobileApp && (this.visibleDownloadAllAttachments() || this.visibleDownloadAllAttachmentsSeparately() || this.visibleSaveAttachmentsToFiles); }, this); this.detailsVisible = ko.observable(false); this.hasNotInlineAttachments = ko.computed(function () { return this.notInlineAttachments().length > 0; }, this); this.scrollToAttachment = ko.observable('.attachments'); this.hasBodyText = ko.computed(function () { return this.textBody().length > 0; }, this); this.visibleAddMenu = ko.observable(false); // Quick Reply Part this.replyText = ko.observable(''); this.replyTextFocus = ko.observable(false); this.replyPaneVisible = ko.computed(function () { return this.currentMessage() && this.currentMessage().completelyFilled(); }, this); this.replySendingStarted = ko.observable(false); this.replySavingStarted = ko.observable(false); this.replyAutoSavingStarted = ko.observable(false); this.requiresPostponedSending = ko.observable(false); this.replyAutoSavingStarted.subscribe(function () { if (!this.replyAutoSavingStarted() && this.requiresPostponedSending()) { App.MessageSender.sendPostponedMail(this.replyDraftUid()); this.requiresPostponedSending(false); } }, this); ko.computed(function () { if (!this.replyTextFocus() || this.replyAutoSavingStarted() || this.replySavingStarted() || this.replySendingStarted()) { this.stopAutosaveTimer(); } if (this.replyTextFocus() && !this.replyAutoSavingStarted() && !this.replySavingStarted() && !this.replySendingStarted()) { this.startAutosaveTimer(); } }, this); this.saveButtonText = ko.computed(function () { return this.replyAutoSavingStarted() ? Utils.i18n('COMPOSE/TOOL_SAVING') : Utils.i18n('COMPOSE/TOOL_SAVE'); }, this); this.replyDraftUid = ko.observable(''); this.replyLoadingText = ko.computed(function () { if (this.replySendingStarted()) { return Utils.i18n('COMPOSE/INFO_SENDING'); } else if (this.replySavingStarted()) { return Utils.i18n('COMPOSE/INFO_SAVING'); } return ''; }, this); this.isEnableSaveQuickReply = ko.computed(function () { return this.isCurrentMessageLoaded() && this.replyText() !== '' && !this.replySavingStarted() && !this.replyAutoSavingStarted(); }, this); this.isEnableSendQuickReply = ko.computed(function () { return this.isCurrentMessageLoaded() && this.replyText() !== '' && !this.replySendingStarted(); }, this); this.saveQuickReplyCommand = Utils.createCommand(this, this.executeSaveQuickReply, this.isEnableSaveQuickReply); this.sendQuickReplyCommand = Utils.createCommand(this, this.executeSendQuickReplyCommand, this.isEnableSendQuickReply); this.domMessageHeader = ko.observable(null); this.domQuickReply = ko.observable(null); this.domMessageForPrint = ko.observable(null); // to have time to take action "Open full reply form" before the animation starts this.replyTextFocusThrottled = ko.observable(false).extend({'throttle': 50}); this.replyTextFocus.subscribe(function () { this.replyTextFocusThrottled(this.replyTextFocus()); }, this); this.isQuickReplyActive = ko.computed(function () { return this.replyText().length > 0 || this.replyTextFocusThrottled(); }, this); //*** Quick Reply Part this.jqPanelHelper = null; this.visibleAttachments = ko.observable(false); this.showMessage = function () { this.visibleAttachments(false); }; this.showAttachments = function () { this.visibleAttachments(true); }; this.defaultFontName = AppData.User.DefaultFontName; if (App.nowMoment) { App.nowMoment.subscribe(function () { this.updateMomentDate(); }, this); } } CMessagePaneViewModel.prototype.resizeDblClick = function (oData, oEvent) { if (oEvent.target.className !== '' && !!oEvent.target.className.search(/add_contact|icon|link|title|subject|link|date/)) { oEvent.preventDefault(); if (oEvent.stopPropagation) { oEvent.stopPropagation(); } else { oEvent.cancelBubble = true; } Utils.removeSelection(); if (!this.jqPanelHelper) { this.jqPanelHelper = $('.MailLayout .panel_helper'); } this.jqPanelHelper.trigger('resize', [5, 'min', true]); } }; CMessagePaneViewModel.prototype.notifySender = function () { if (this.currentMessage() && this.currentMessage().readingConfirmation() !== '') { App.Ajax.send({ 'Action': 'MessageSendConfirmation', 'Confirmation': this.currentMessage().readingConfirmation(), 'Subject': Utils.i18n('MESSAGE/RETURN_RECEIPT_MAIL_SUBJECT'), 'Text': Utils.i18n('MESSAGE/RETURN_RECEIPT_MAIL_TEXT', { 'EMAIL': AppData.Accounts.getEmail(), 'SUBJECT': this.subject() }), 'ConfirmFolder': this.currentMessage().folder(), 'ConfirmUid': this.currentMessage().uid() }); this.currentMessage().readingConfirmation(''); } }; CMessagePaneViewModel.prototype.onMessagesSubscribe = function () { if (!this.currentMessage() && this.uid().length > 0) { App.MailCache.setCurrentMessage(this.uid(), this.folder()); } }; CMessagePaneViewModel.prototype.onCurrentMessageSubscribe = function () { var oIcal = null, oVcard = null, oMessage = this.currentMessage(), oAccount = oMessage ? AppData.Accounts.getAccount(oMessage.accountId()) : null ; if (this.singleMode() && window.opener && window.opener.oReplyDataFromViewPane) { this.replyText(window.opener.oReplyDataFromViewPane.ReplyText); this.replyDraftUid(window.opener.oReplyDataFromViewPane.ReplyDraftUid); window.opener.oReplyDataFromViewPane = null; } else if (!oMessage || oMessage.uid() !== this.displayedMessageUid()) { this.replyText(''); this.replyDraftUid(''); } if (oMessage && this.uid() === oMessage.uid()) { this.subject(oMessage.subject()); this.importance(oMessage.importance()); this.from(oMessage.oFrom.getDisplay()); this.fromEmail(oMessage.oFrom.getFirstEmail()); this.fullFrom(oMessage.oFrom.getFull()); if (oMessage.oFrom.aCollection.length > 0) { this.oFromAddr(oMessage.oFrom.aCollection[0]); } else { this.oFromAddr(null); } this.to(oMessage.oTo.getFull()); this.aToAddr(oMessage.oTo.aCollection); this.cc(oMessage.oCc.getFull()); this.aCcAddr(oMessage.oCc.aCollection); this.bcc(oMessage.oBcc.getFull()); this.aBccAddr(oMessage.oBcc.aCollection); this.currentAccountEmail(oAccount.email()); this.aAllRecipients(_.uniq(_.union(this.aToAddr(), this.aCcAddr(), this.aBccAddr()))); if (!this.mobileApp) { this.requestContactsByEmail(_.union(oMessage.oFrom.aCollection, this.aAllRecipients())); } this.midDate(oMessage.oDateModel.getMidDate()); this.fullDate(oMessage.oDateModel.getFullDate()); this.isLoading(oMessage.uid() !== '' && !oMessage.completelyFilled()); this.setMessageBody(); this.rtlMessage(oMessage.rtl()); if (this.singleMode()) { /*jshint onevar: false*/ var aAtachments = [], sThumbSessionUid = Date.now().toString() ; /*jshint onevar: true*/ _.each(oMessage.attachments(), _.bind(function (oAttach) { var oCopy = new CMailAttachmentModel(); oCopy.copyProperties(oAttach); oCopy.getInThumbQueue(sThumbSessionUid); aAtachments.push(oCopy); }, this)); this.attachments(aAtachments); } else { this.attachments(oMessage.attachments()); } // animation of buttons turns on with delay // so it does not trigger when placing initial values if (this.ical() !== null) { this.ical().animation(false); } oIcal = oMessage.ical(); if (oIcal && this.singleMode()) { oIcal = this.getIcalCopy(oIcal); } this.ical(oIcal); if (this.ical() !== null) { _.defer(_.bind(function () { if (this.ical() !== null) { this.ical().animation(true); } }, this)); this.ical().updateAttendeeStatus(this.fromEmail()); } oVcard = oMessage.vcard(); if (oVcard && this.singleMode()) { oVcard = this.getVcardCopy(oVcard); } this.vcard(oVcard); if (!oMessage.completelyFilled() || oMessage.trimmed()) { /*jshint onevar: false*/ var oSubscribedField = !oMessage.completelyFilled() ? oMessage.completelyFilled : oMessage.trimmed; /*jshint onevar: true*/ if (this.singleMode()) { oMessage.completelyFilledSingleModeSubscription = oSubscribedField.subscribe(this.onCurrentMessageSubscribe, this); } else { oMessage.completelyFilledSubscription = oSubscribedField.subscribe(this.onCurrentMessageSubscribe, this); } } else if (oMessage.completelyFilledSubscription) { oMessage.completelyFilledSubscription.dispose(); oMessage.completelyFilledSubscription = undefined; } else if (oMessage.completelyFilledSingleModeSubscription) { oMessage.completelyFilledSingleModeSubscription.dispose(); oMessage.completelyFilledSingleModeSubscription = undefined; } } else { this.isLoading(false); $(this.domTextBody()).empty().data('displayed-message-uid', ''); this.displayedMessageUid(''); this.rtlMessage(false); // cannot use removeAll, because the attachments of messages are passed by reference // and the call to removeAll removes attachments from message in the cache too. this.attachments([]); this.visiblePicturesControl(false); this.visibleShowPicturesLink(false); this.ical(null); this.vcard(null); this.decryptPassword(''); this.visibleDecryptControl(false); this.visibleVerifyControl(false); } }; CMessagePaneViewModel.prototype.updateMomentDate = function () { var oMessage = this.currentMessage(); if (oMessage && oMessage.oDateModel) { this.midDate(oMessage.oDateModel.getMidDate()); this.fullDate(oMessage.oDateModel.getFullDate()); } }; /** * @param {Object} oAddress * @param {Object} oEvent */ CMessagePaneViewModel.prototype.fromMouseoverEvent = function (oAddress, oEvent) { if (this.oFromAddr()) { this.oFromAddr().mouseoverEvent(oAddress, oEvent); } }; /** * @param {Object} oAddress * @param {Object} oEvent */ CMessagePaneViewModel.prototype.fromMouseoutEvent = function (oAddress, oEvent) { if (this.oFromAddr()) { this.oFromAddr().mouseoutEvent(oAddress, oEvent); } }; /** * @param {Array} aRecipients */ CMessagePaneViewModel.prototype.requestContactsByEmail = function (aRecipients) { _.each(aRecipients, _.bind(function (oAddress) { App.ContactsCache.getContactByEmail(oAddress.sEmail, this.onContactResponse, this); }, this)); }; /** * @param {Object} oContact * @param {string} sEmail */ CMessagePaneViewModel.prototype.onContactResponse = function (oContact, sEmail) { if (oContact) { this.recipientsContacts.push(oContact); this.recipientsContacts(_.uniq(this.recipientsContacts())); } _.each(_.union([this.oFromAddr()], this.aAllRecipients()), function (oAddress) { if (oAddress && oAddress.sEmail === sEmail) { oAddress.loaded(true); if (oContact) { oAddress.founded(true); } } }); }; CMessagePaneViewModel.prototype.getVcardCopy = function (oVcard) { var oNewVcard = new CVcardModel(); oNewVcard.uid(oVcard.uid()); oNewVcard.file(oVcard.file()); oNewVcard.name(oVcard.name()); oNewVcard.email(oVcard.email()); oNewVcard.isExists(oVcard.isExists()); oNewVcard.isJustSaved(oVcard.isJustSaved()); return oNewVcard; }; CMessagePaneViewModel.prototype.getIcalCopy = function (oIcal) { var oNewIcal = new CIcalModel(); oNewIcal.uid(oIcal.uid()); oNewIcal.file(oIcal.file()); oNewIcal.attendee(oIcal.attendee()); oNewIcal.type(oIcal.type()); oNewIcal.cancelDecision(oIcal.cancelDecision()); oNewIcal.replyDecision(oIcal.replyDecision()); oNewIcal.isJustSaved(oIcal.isJustSaved()); oNewIcal.location(oIcal.location()); oNewIcal.description(oIcal.description()); oNewIcal.when(oIcal.when()); oNewIcal.calendarId(oIcal.calendarId()); oNewIcal.selectedCalendarId(oIcal.selectedCalendarId()); oNewIcal.calendars(oIcal.calendars()); oNewIcal.animation(oIcal.animation()); return oNewIcal; }; CMessagePaneViewModel.prototype.setMessageBody = function () { if (this.currentMessage()) { var oMessage = this.currentMessage(), sText = oMessage.text(), sLen = sText.length, sMaxLen = 5000000, $body = $(this.domTextBody()), aCollapsedStatuses = [] ; this.textBody(sText); _.defer(_.bind(function () { if (this.currentMessage()) { var oMessage = this.currentMessage(); if ($body.data('displayed-message-uid') === oMessage.uid()) { aCollapsedStatuses = this.getBlockquotesStatus(); } $body.empty(); if (oMessage.isPlain() || sLen > sMaxLen) { $body.html(sText); this.visiblePicturesControl(false); } else { //$body.append(oMessage.getDomText()); $body.append(oMessage.getDomText().html()); //fix for single mode in ie this.visiblePicturesControl(oMessage.hasExternals() && !oMessage.isExternalsAlwaysShown()); this.visibleShowPicturesLink(!oMessage.isExternalsShown()); this.doHidingBlockquotes(aCollapsedStatuses); } this.decryptPassword(''); this.visibleDecryptControl(AppData.User.enableOpenPgp() && oMessage.encryptedMessage()); this.visibleVerifyControl(AppData.User.enableOpenPgp() && oMessage.signedMessage()); $body.data('displayed-message-uid', oMessage.uid()); this.displayedMessageUid(oMessage.uid()); } }, this)); } }; CMessagePaneViewModel.prototype.getBlockquotesStatus = function () { var aCollapsedStatuses = []; $($('blockquote', $(this.domTextBody())).get()).each(function () { var $blockquote = $(this) ; if ($blockquote.hasClass('blockquote_before_toggle')) { aCollapsedStatuses.push($blockquote.hasClass('collapsed')); } }); return aCollapsedStatuses; }; CMessagePaneViewModel.prototype.doHidingBlockquotes = function (aCollapsedStatuses) { var iMinHeightForHide = 120, iHiddenHeight = 80, iStatusIndex = 0 ; $($('blockquote', $(this.domTextBody())).get()).each(function () { var $blockquote = $(this), $parentBlockquotes = $blockquote.parents('blockquote'), $switchButton = $('<span class="blockquote_toggle"></span>').html(Utils.i18n('MESSAGE/SHOW_QUOTED_TEXT')), bHidden = true ; if ($parentBlockquotes.length === 0) { if ($blockquote.height() > iMinHeightForHide) { $blockquote .addClass('blockquote_before_toggle') .after($switchButton) .wrapInner('<div class="blockquote_content"></div>') ; $switchButton.bind('click', function () { if (bHidden) { $blockquote.height('auto'); $switchButton.html(Utils.i18n('MESSAGE/HIDE_QUOTED_TEXT')); bHidden = false; } else { $blockquote.height(iHiddenHeight); $switchButton.html(Utils.i18n('MESSAGE/SHOW_QUOTED_TEXT')); bHidden = true; } $blockquote.toggleClass('collapsed', bHidden); }); if (iStatusIndex < aCollapsedStatuses.length) { bHidden = aCollapsedStatuses[iStatusIndex]; iStatusIndex++; } $blockquote.height(bHidden ? iHiddenHeight : 'auto').toggleClass('collapsed', bHidden); } } }); }; /** * @param {Array} aParams */ CMessagePaneViewModel.prototype.onRoute = function (aParams) { var oParams = App.Links.parseMailbox(aParams); if (this.replyText() !== '' && this.uid() !== oParams.Uid) { this.saveReplyMessage(false); } this.uid(oParams.Uid); this.folder(oParams.Folder); App.MailCache.setCurrentMessage(this.uid(), this.folder()); this.contentHasFocus(true); }; CMessagePaneViewModel.prototype.showPictures = function () { App.MailCache.showExternalPictures(false); this.visibleShowPicturesLink(false); this.setMessageBody(); }; CMessagePaneViewModel.prototype.alwaysShowPictures = function () { var sEmail = this.currentMessage() ? this.currentMessage().oFrom.getFirstEmail() : '' ; if (sEmail.length > 0) { App.Ajax.send({ 'Action': 'EmailSafety', 'Email': sEmail }); } App.MailCache.showExternalPictures(true); this.visiblePicturesControl(false); this.setMessageBody(); }; CMessagePaneViewModel.prototype.showDetails = function () { this.detailsVisible(true); }; CMessagePaneViewModel.prototype.hideDetails = function () { this.detailsVisible(false); }; CMessagePaneViewModel.prototype.openInNewWindow = function () { this.openMessageInNewWindowBinded(this.currentMessage()); }; CMessagePaneViewModel.prototype.addToContacts = function (sEmail, sName) { if(!this.processed()) { this.processed(true); App.ContactsCache.addToContacts(sName, sEmail, this.onAddToContactsResponse, this); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CMessagePaneViewModel.prototype.onAddToContactsResponse = function (oResponse, oRequest) { if (oResponse.Result && oRequest.HomeEmail !== '') { App.Api.showReport(Utils.i18n('CONTACTS/REPORT_CONTACT_SUCCESSFULLY_ADDED')); App.ContactsCache.clearInfoAboutEmail(oRequest.HomeEmail); App.ContactsCache.getContactByEmail(oRequest.HomeEmail, this.onContactResponse, this); } this.processed(false); }; CMessagePaneViewModel.prototype.getReplyHtmlText = function () { return '<div style="font-family: ' + this.defaultFontName + '; font-size: 16px">' + App.MessageSender.getHtmlFromText(this.replyText()) + '</div>'; }; /** * @param {string} sReplyType */ CMessagePaneViewModel.prototype.executeReplyOrForward = function (sReplyType) { if (this.currentMessage()) { App.MessageSender.setReplyData(this.getReplyHtmlText(), this.replyDraftUid()); this.replyText(''); this.replyDraftUid(''); App.Routing.setHash(App.Links.composeFromMessage(sReplyType, this.currentMessage().folder(), this.currentMessage().uid())); } }; CMessagePaneViewModel.prototype.executeDeleteMessage = function () { if (this.singleMode() && this.currentMessage() && window.opener && window.opener.App && window.opener.App.MailCache) { window.opener.App.MailCache.deleteMessages([this.currentMessage().uid()]); window.close(); } else if (this.mobileApp && this.currentMessage()) { App.MailCache.deleteMessages([this.currentMessage().uid()]); } }; CMessagePaneViewModel.prototype.executePrevMessage = function () { if (this.isEnablePrevMessage()) { this.moveToSingleMessageView(this.prevMessageUid()); } }; CMessagePaneViewModel.prototype.executeNextMessage = function () { if (this.isEnableNextMessage()) { this.moveToSingleMessageView(this.nextMessageUid()); } }; /** * @param {string} sUid */ CMessagePaneViewModel.prototype.moveToSingleMessageView = function (sUid) { var sFolder = App.MailCache.folderList().currentFolderFullName(), aHash = [Enums.Screens.SingleMessageView, sFolder, 'msg' + sUid] ; App.Routing.setHash(aHash); }; CMessagePaneViewModel.prototype.executeReply = function () { this.executeReplyOrForward(Enums.ReplyType.Reply); }; CMessagePaneViewModel.prototype.executeReplyAll = function () { this.executeReplyOrForward(Enums.ReplyType.ReplyAll); }; CMessagePaneViewModel.prototype.executeResend = function () { this.executeReplyOrForward(Enums.ReplyType.Resend); }; CMessagePaneViewModel.prototype.executeForward = function () { this.executeReplyOrForward(Enums.ReplyType.Forward); }; CMessagePaneViewModel.prototype.executePrint = function () { var oMessage = this.currentMessage(), oWin = oMessage ? Utils.WindowOpener.open('', this.subject() + '-print') : null, sHtml = '' ; if (oMessage && oWin) { this.textBodyForNewWindow(oMessage.getConvertedHtml(Utils.getAppPath(), true)); sHtml = $(this.domMessageForPrint()).html(); $(oWin.document.body).html(sHtml); oWin.print(); } }; CMessagePaneViewModel.prototype.executeSave = function () { if (this.currentMessage()) { App.Api.downloadByUrl(this.currentMessage().downloadLink()); } }; CMessagePaneViewModel.prototype.executeSaveAsPdf = function () { if (this.currentMessage()) { var oBody = this.currentMessage().getDomText(), iAccountId = this.currentMessage().accountId(), fReplaceWithBase64 = function (oImg) { try { var oCanvas = document.createElement('canvas'), oCtx = null ; oCanvas.width = oImg.width; oCanvas.height = oImg.height; oCtx = oCanvas.getContext('2d'); oCtx.drawImage(oImg, 0, 0); oImg.src = oCanvas.toDataURL('image/png'); } catch (e) {} } ; $('img[data-x-src-cid]', oBody).each(function () { fReplaceWithBase64(this); }); App.Ajax.send({ 'Action': 'PdfFromHtml', 'Subject': this.subject(), 'Html': oBody.html() }, function (oData) { if (oData && oData.Result && oData.Result['Hash']) { App.Api.downloadByUrl(Utils.getDownloadLinkByHash(iAccountId, oData.Result['Hash'])); } else { App.Api.showError(Utils.i18n('WARNING/CREATING_PDF_ERROR')); } }, this); } }; CMessagePaneViewModel.prototype.changeAddMenuVisibility = function () { var bVisibility = !this.visibleAddMenu(); this.visibleAddMenu(bVisibility); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CMessagePaneViewModel.prototype.onMessageSendOrSaveResponse = function (oResponse, oRequest) { var oResData = App.MessageSender.onMessageSendOrSaveResponse(oResponse, oRequest); switch (oResData.Action) { case 'MessageSend': this.replySendingStarted(false); if (oResData.Result) { this.replyText(''); } break; case 'MessageSave': if (oResData.Result) { this.replyDraftUid(oResData.NewUid); } this.replySavingStarted(false); this.replyAutoSavingStarted(false); break; } }; CMessagePaneViewModel.prototype.executeSendQuickReplyCommand = function () { if (this.isEnableSendQuickReply()) { this.replySendingStarted(true); this.requiresPostponedSending(this.replyAutoSavingStarted()); App.MessageSender.sendReplyMessage('MessageSend', this.getReplyHtmlText(), this.replyDraftUid(), this.onMessageSendOrSaveResponse, this, this.requiresPostponedSending()); this.replyTextFocus(false); } }; CMessagePaneViewModel.prototype.executeSaveQuickReply = function () { this.saveReplyMessage(false); }; CMessagePaneViewModel.prototype.saveReplyMessage = function (bAutosave) { if (this.isEnableSaveQuickReply()) { if (bAutosave) { this.replyAutoSavingStarted(true); } else { this.replySavingStarted(true); } App.MessageSender.sendReplyMessage('MessageSave', this.getReplyHtmlText(), this.replyDraftUid(), this.onMessageSendOrSaveResponse, this); } }; /** * Stops autosave. */ CMessagePaneViewModel.prototype.stopAutosaveTimer = function () { window.clearTimeout(this.autoSaveTimer); }; /** * Starts autosave. */ CMessagePaneViewModel.prototype.startAutosaveTimer = function () { if (this.isEnableSaveQuickReply()) { var fSave = _.bind(this.saveReplyMessage, this, true); this.stopAutosaveTimer(); if (AppData.User.AllowAutosaveInDrafts) { this.autoSaveTimer = window.setTimeout(fSave, AppData.App.AutoSaveIntervalSeconds * 1000); } } }; CMessagePaneViewModel.prototype.downloadAllAttachments = function () { if (this.currentMessage()) { this.currentMessage().downloadAllAttachments(); } }; CMessagePaneViewModel.prototype.saveAttachmentsToFiles = function () { if (this.currentMessage()) { this.currentMessage().saveAttachmentsToFiles(); } }; CMessagePaneViewModel.prototype.downloadAllAttachmentsSeparately = function () { if (this.currentMessage()) { this.currentMessage().downloadAllAttachmentsSeparately(); } }; CMessagePaneViewModel.prototype.onApplyBindings = function (oMailViewModel) { App.registerSessionTimeoutFunction(_.bind(function () { if (this.replyText() !== '') { this.saveReplyMessage(false); } }, this)); $(oMailViewModel).on('mousedown', 'a', function (oEvent) { if (oEvent && 3 !== oEvent['which']) { var sHref = $(this).attr('href'); if (sHref && 'mailto:' === sHref.toString().toLowerCase().substr(0, 7)) { App.Api.openComposeMessage(sHref.toString().substr(7)); return false; } } return true; }); this.hotKeysBind(); }; CMessagePaneViewModel.prototype.hotKeysBind = function () { $(document).on('keydown', $.proxy(function(ev) { var bComputed = App.Screens.currentScreen() === Enums.Screens.Mailbox && ev && !ev.ctrlKey && !ev.shiftKey && !Utils.isTextFieldFocused() && this.isEnableReply(); if (bComputed && ev.keyCode === Enums.Key.q) { ev.preventDefault(); this.replyTextFocus(true); } else if (bComputed && ev.keyCode === Enums.Key.r) { this.executeReply(); } }, this)); }; CMessagePaneViewModel.prototype.showSourceHeaders = function () { var oMessage = this.currentMessage(), oWin = oMessage && oMessage.completelyFilled() ? Utils.WindowOpener.open('', this.subject() + '-headers') : null ; if (oWin) { $(oWin.document.body).html('<pre>' + Utils.encodeHtml(oMessage.sourceHeaders()) + '</pre>'); } }; CMessagePaneViewModel.prototype.onDecryptMessageClick = function () { if (this.currentMessage() && this.currentMessage().encryptedMessage()) { this.decryptVerifyMessage(false); } }; CMessagePaneViewModel.prototype.onVerifyMessageClick = function () { if (this.currentMessage() && this.currentMessage().signedMessage()) { this.decryptVerifyMessage(true); } }; /** * @param {boolean} bVerifyOnly */ CMessagePaneViewModel.prototype.decryptVerifyMessage = function (bVerifyOnly) { var fPgpCallback = _.bind(function (oPgp) { var oMessage = this.currentMessage(); if (oPgp && oMessage) { if (bVerifyOnly && oMessage.signedMessage()) { this.verifyMessage(oPgp); } else if (oMessage.encryptedMessage()) { this.decryptMessage(oPgp); } } }, this); App.Api.pgp(fPgpCallback, AppData.User.IdUser); }; /** * @param {Object} oPgp */ CMessagePaneViewModel.prototype.decryptMessage = function (oPgp) { var oMessage = this.currentMessage(), sData = oMessage.textRaw(), sAccountEmail = AppData.Accounts.getEmail(), sFromEmail = oMessage.oFrom.getFirstEmail(), sPrivateKeyPassword = this.decryptPassword(), oRes = oPgp.decryptAndVerify(sData, sAccountEmail, sFromEmail, sPrivateKeyPassword), bNoSignDataNotice = false ; if (oRes && oRes.result && !oRes.errors) { oMessage.text('<pre>' + Utils.encodeHtml(oRes.result) + '</pre>'); oMessage.$text = null; oMessage.encryptedMessage(false); this.decryptPassword(''); this.visibleDecryptControl(false); this.setMessageBody(); if (!oRes.notices) { App.Api.showReport(Utils.i18n('OPENPGP/REPORT_MESSAGE_SUCCESSFULLY_DECRYPTED_AND_VERIFIED')); } else { App.Api.showReport(Utils.i18n('OPENPGP/REPORT_MESSAGE_SUCCESSFULLY_DECRYPTED')); } } if (oRes && (oRes.errors || oRes.notices)) { bNoSignDataNotice = App.Api.showPgpErrorByCode(oRes, Enums.PgpAction.DecryptVerify); if (bNoSignDataNotice) { App.Api.showReport(Utils.i18n('OPENPGP/REPORT_MESSAGE_SUCCESSFULLY_DECRYPTED_AND_NOT_SIGNED')); } } }; /** * @param {Object} oPgp */ CMessagePaneViewModel.prototype.verifyMessage = function (oPgp) { var oMessage = this.currentMessage(), sData = oMessage.textRaw(), sFromEmail = oMessage.oFrom.getFirstEmail(), oRes = oPgp.verify(sData, sFromEmail) ; if (oRes && oRes.result && !(oRes.errors || oRes.notices)) { oMessage.text('<pre>' + Utils.encodeHtml(oRes.result) + '</pre>'); oMessage.$text = null; oMessage.signedMessage(false); this.visibleVerifyControl(false); this.setMessageBody(); App.Api.showReport(Utils.i18n('OPENPGP/REPORT_MESSAGE_SUCCESSFULLY_VERIFIED')); } if (oRes && (oRes.errors || oRes.notices)) { App.Api.showPgpErrorByCode(oRes, Enums.PgpAction.Verify); } }; CMessagePaneViewModel.prototype.testFunction = function () { App.Api.pgp(function (oOpenPgp) { // TODO // if (oOpenPgp) // { // } }); }; /** * @constructor */ function CMailViewModel() { this.folderList = App.MailCache.folderList; this.domFolderList = ko.observable(null); this.openMessageInNewWindowBinded = _.bind(this.openMessageInNewWindow, this); this.oFolderList = new CFolderListViewModel(); this.oMessageList = new CMessageListViewModel(this.openMessageInNewWindowBinded); this.oMessagePane = new CMessagePaneViewModel(this.openMessageInNewWindowBinded); this.isEnableGroupOperations = this.oMessageList.isEnableGroupOperations; this.composeLink = ko.observable(App.Routing.buildHashFromArray(App.Links.compose())); this.checkMailCommand = Utils.createCommand(this, this.executeCheckMail); this.checkMailIndicator = ko.computed(function () { return App.MailCache.checkMailStarted() || App.MailCache.messagesLoading(); }, this); this.markAsReadCommand = Utils.createCommand(this.oMessageList, this.oMessageList.executeMarkAsRead, this.isEnableGroupOperations); this.markAsUnreadCommand = Utils.createCommand(this.oMessageList, this.oMessageList.executeMarkAsUnread, this.isEnableGroupOperations); this.markAllReadCommand = Utils.createCommand(this.oMessageList, this.oMessageList.executeMarkAllRead); this.moveToFolderCommand = Utils.createCommand(this, Utils.emptyFunction, this.isEnableGroupOperations); // this.copyToFolderCommand = Utils.createCommand(this, Utils.emptyFunction, this.isEnableGroupOperations); this.deleteCommand = Utils.createCommand(this.oMessageList, this.oMessageList.executeDelete, this.isEnableGroupOperations); this.selectedCount = ko.computed(function () { return this.oMessageList.checkedUids().length; }, this); this.emptyTrashCommand = Utils.createCommand(App.MailCache, App.MailCache.executeEmptyTrash, this.oMessageList.isNotEmptyList); this.emptySpamCommand = Utils.createCommand(App.MailCache, App.MailCache.executeEmptySpam, this.oMessageList.isNotEmptyList); this.spamCommand = Utils.createCommand(this.oMessageList, this.oMessageList.executeSpam, this.isEnableGroupOperations); this.notSpamCommand = Utils.createCommand(this.oMessageList, this.oMessageList.executeNotSpam, this.isEnableGroupOperations); this.bVisibleComposeMessage = AppData.User.AllowCompose; this.isVisibleReplyTool = ko.computed(function () { return (this.folderList().currentFolder() && this.folderList().currentFolderFullName().length > 0 && this.folderList().currentFolderType() !== Enums.FolderTypes.Drafts && this.folderList().currentFolderType() !== Enums.FolderTypes.Sent); }, this); this.isVisibleForwardTool = ko.computed(function () { return (this.folderList().currentFolder() && this.folderList().currentFolderFullName().length > 0 && this.folderList().currentFolderType() !== Enums.FolderTypes.Drafts); }, this); this.isSpamFolder = ko.computed(function () { return this.folderList().currentFolderType() === Enums.FolderTypes.Spam; }, this); this.allowedSpamAction = ko.computed(function () { var oAccount = AppData.Accounts.getCurrent(); return oAccount ? oAccount.extensionExists('AllowSpamFolderExtension') && !this.isSpamFolder() : false; }, this); this.allowedNotSpamAction = ko.computed(function () { var oAccount = AppData.Accounts.getCurrent(); return oAccount ? oAccount.extensionExists('AllowSpamFolderExtension') && this.isSpamFolder() : false; }, this); this.isTrashFolder = ko.computed(function () { return this.folderList().currentFolderType() === Enums.FolderTypes.Trash; }, this); this.jqPanelHelper = null; this.mobileApp = bMobileApp; this.selectedPanel = ko.observable(Enums.MobilePanel.Items); App.MailCache.currentMessage.subscribe(function () { this.gotoMessagePane(); }, this); } CMailViewModel.prototype.executeCheckMail = function () { App.MailCache.checkMessageFlags(); App.MailCache.executeCheckMail(); }; CMailViewModel.prototype.openMessageInNewWindow = function (oMessage) { var oFolder = this.folderList().getFolderByFullName(oMessage.folder()), bDraftFolder = (oFolder.type() === Enums.FolderTypes.Drafts) ; if (this.oMessagePane.currentMessage() && this.oMessagePane.currentMessage().uid() === oMessage.uid() && (this.oMessagePane.replyText() !== '' || this.oMessagePane.replyDraftUid() !== '')) { window.oReplyDataFromViewPane = { 'ReplyText': this.oMessagePane.replyText(), 'ReplyDraftUid': this.oMessagePane.replyDraftUid() }; this.oMessagePane.replyText(''); this.oMessagePane.replyDraftUid(''); } Utils.WindowOpener.openMessage(oMessage, bDraftFolder); }; CMailViewModel.prototype.gotoFolderList = function () { this.changeSelectedPanel(Enums.MobilePanel.Groups); }; CMailViewModel.prototype.gotoMessageList = function () { this.changeSelectedPanel(Enums.MobilePanel.Items); return true; }; CMailViewModel.prototype.gotoMessagePane = function () { if (App.MailCache.currentMessage()) { this.changeSelectedPanel(Enums.MobilePanel.View); } else { this.gotoMessageList(); } }; /** * @param {number} iPanel */ CMailViewModel.prototype.changeSelectedPanel = function (iPanel) { if (this.mobileApp) { if (this.selectedPanel() !== iPanel) { this.selectedPanel(iPanel); } } }; /** * @param {Object} oData * @param {Object} oEvent */ CMailViewModel.prototype.resizeDblClick = function (oData, oEvent) { oEvent.preventDefault(); if (oEvent.stopPropagation) { oEvent.stopPropagation(); } else { oEvent.cancelBubble = true; } Utils.removeSelection(); if (!this.jqPanelHelper) { this.jqPanelHelper = $('.MailLayout .panel_helper'); } this.jqPanelHelper.trigger('resize', [600, 'max']); }; /** * @param {Array} aParams */ CMailViewModel.prototype.onRoute = function (aParams) { this.oMessageList.onRoute(aParams); this.oMessagePane.onRoute(aParams); }; CMailViewModel.prototype.onShow = function () { this.oMessageList.onShow(); }; CMailViewModel.prototype.onHide = function () { this.oMessageList.onHide(); }; CMailViewModel.prototype.onApplyBindings = function () { var self = this; this.oMessageList.onApplyBindings(this.$viewModel); this.oMessagePane.onApplyBindings(this.$viewModel); $(this.domFolderList()).on('click', 'span.folder', function (oEvent) { if(oEvent.ctrlKey) { self.oMessageList.executeCopyToFolder($(this).data('folder')); } else { self.oMessageList.executeMoveToFolder($(this).data('folder')); } }); this.hotKeysBind(); }; CMailViewModel.prototype.hotKeysBind = function () { $(document).on('keydown', $.proxy(function(ev) { var sKey = ev.keyCode, bComputed = ev && !ev.ctrlKey && !ev.altKey && !ev.shiftKey && !Utils.isTextFieldFocused() && App.Screens.currentScreen() === Enums.Screens.Mailbox, oList = this.oMessageList, oFirstMessage = oList.collection()[0], bGotoSearch = oFirstMessage && App.MailCache.currentMessage() && oFirstMessage.uid() === App.MailCache.currentMessage().uid() ; if (bComputed && sKey === Enums.Key.s || bComputed && bGotoSearch && sKey === Enums.Key.Up) { ev.preventDefault(); this.searchFocus(); } else if (oList.isFocused() && ev && sKey === Enums.Key.Down && oFirstMessage) { ev.preventDefault(); oList.isFocused(false); oList.routeForMessage(oFirstMessage); } else if (bComputed && sKey === Enums.Key.n) { window.location.href = '#compose'; } },this)); }; /** * @param {Object} oMessage */ CMailViewModel.prototype.dragAndDropHelper = function (oMessage) { if (oMessage) { oMessage.checked(true); } var oHelper = Utils.draggableMessages(), aUids = this.oMessageList.checkedOrSelectedUids(), iCount = aUids.length ; oHelper.data('p7-message-list-folder', this.folderList().currentFolderFullName()); oHelper.data('p7-message-list-uids', aUids); $('.count-text', oHelper).text(Utils.i18n('MAILBOX/DRAG_TEXT_PLURAL', { 'COUNT': iCount }, null, iCount)); return oHelper; }; /** * @param {Object} oToFolder * @param {Object} oEvent * @param {Object} oUi */ CMailViewModel.prototype.messagesDrop = function (oToFolder, oEvent, oUi) { if (oToFolder) { var oHelper = oUi && oUi.helper ? oUi.helper : null, sFolder = oHelper ? oHelper.data('p7-message-list-folder') : '', aUids = oHelper ? oHelper.data('p7-message-list-uids') : null ; if ('' !== sFolder && null !== aUids) { Utils.uiDropHelperAnim(oEvent, oUi); if(oEvent.ctrlKey) { this.oMessageList.executeCopyToFolder(oToFolder.fullName()); } else { this.oMessageList.executeMoveToFolder(oToFolder.fullName()); } } } }; CMailViewModel.prototype.searchFocus = function () { if (this.oMessageList.selector.useKeyboardKeys() && !Utils.isTextFieldFocused()) { this.oMessageList.isFocused(true); } }; CMailViewModel.prototype.backToList = function () { App.Routing.setPreviousHash(); }; CMailViewModel.prototype.onVolumerClick = function (oVm, oEv) { oEv.stopPropagation(); }; /** * @constructor */ function CComposeViewModel() { var self = this; this.toAddrDom = ko.observable(); this.ccAddrDom = ko.observable(); this.bccAddrDom = ko.observable(); this.folderList = App.MailCache.folderList; this.folderList.subscribe(function () { this.getMessageOnRoute(); }, this); this.singleMode = ko.observable(AppData.SingleMode); this.isDemo = ko.observable(AppData.User.IsDemo); this.sending = ko.observable(false); this.sending.subscribe(this.sendingAndSavingSubscription, this); this.saving = ko.observable(false); this.saving.subscribe(this.sendingAndSavingSubscription, this); this.oHtmlEditor = new CHtmlEditorViewModel(false, this); this.textFocused = this.oHtmlEditor.textFocused; this.visibleBcc = ko.observable(false); this.visibleBcc.subscribe(function () { $html.toggleClass('screen-compose-bcc', this.visibleCc()); _.defer(_.bind(function () { $(this.bccAddrDom()).inputosaurus('resizeInput'); }, this)); }, this); this.visibleCc = ko.observable(false); this.visibleCc.subscribe(function () { $html.toggleClass('screen-compose-cc', this.visibleCc()); _.defer(_.bind(function () { $(this.ccAddrDom()).inputosaurus('resizeInput'); }, this)); }, this); this.visibleCounter = ko.observable(false); this.readingConfirmation = ko.observable(false); this.saveMailInSentItems = ko.observable(true); this.useSaveMailInSentItems = ko.observable(false); this.composeUploaderButton = ko.observable(null); this.composeUploaderDropPlace = ko.observable(null); this.composeUploaderBodyDragOver = ko.observable(false); this.composeUploaderDragOver = ko.observable(false); this.allowDragNDrop = ko.observable(false); this.uploaderBodyDragOver = ko.computed(function () { return this.allowDragNDrop() && this.composeUploaderBodyDragOver(); }, this); this.uploaderDragOver = ko.computed(function () { return this.allowDragNDrop() && this.composeUploaderDragOver(); }, this); this.selectedImportance = ko.observable(Enums.Importance.Normal); this.selectedSensitivity = ko.observable(Enums.Sensivity.Nothing); this.senderList = ko.observableArray([]); this.visibleFrom = ko.computed(function () { return this.senderList().length > 1; }, this); this.selectedSender = ko.observable(''); this.selectedFetcherOrIdentity = ko.observable(null); this.selectedFetcherOrIdentity.subscribe(function () { if (this.selectedFetcherOrIdentity()) { if (this.selectedFetcherOrIdentity().FETCHER === true) { this.selectedSender('fetcher' + this.selectedFetcherOrIdentity().id()); } else { this.selectedSender(Utils.pString(this.selectedFetcherOrIdentity().id())); } } else { this.selectedSender(''); } }, this); this.selectedSender.subscribe(function (sSelectedSenderId) { var oAccount = AppData.Accounts.getAccount(this.senderAccountId()), sId = this.selectedSender(), oFetcherOrIdentity = null ; if (this.oHtmlEditor.oCrea) { this.oHtmlEditor.oCrea.editableSave(); } if (sId.indexOf('fetcher') === 0) { if (oAccount.fetchers()) { sId = sId.replace('fetcher', ''); oFetcherOrIdentity = _.find(oAccount.fetchers().collection(), function (oFtchr) { return oFtchr.id() === Utils.pInt(sId); }); } } else { oFetcherOrIdentity = _.find(oAccount.identities(), function (oIdnt) { return oIdnt.id() === Utils.pInt(sId); }); } this.changeSelectedFetcherOrIdentity(oFetcherOrIdentity); }, this); this.selectedIdentityId = ko.observable(0); this.senderAccountId = ko.observable(AppData.Accounts.currentId()); this.signature = ko.observable(''); this.prevSignature = ko.observable(null); ko.computed(function () { var sSignature = App.MessageSender.getClearSignature(this.senderAccountId(), this.selectedFetcherOrIdentity()); if (this.prevSignature() === null) { this.prevSignature(sSignature); this.signature(sSignature); } else { this.prevSignature(this.signature()); this.signature(sSignature); this.oHtmlEditor.changeSignatureContent(this.signature(), this.prevSignature()); } }, this); this.lockToAddr = ko.observable(false); this.toAddr = ko.observable('').extend({'reversible': true}); this.toAddr.subscribe(function () { if (!this.lockToAddr()) { $(this.toAddrDom()).val(this.toAddr()); $(this.toAddrDom()).inputosaurus('refresh'); } }, this); this.lockCcAddr = ko.observable(false); this.ccAddr = ko.observable('').extend({'reversible': true}); this.ccAddr.subscribe(function () { if (!this.lockCcAddr()) { $(this.ccAddrDom()).val(this.ccAddr()); $(this.ccAddrDom()).inputosaurus('refresh'); } }, this); this.lockBccAddr = ko.observable(false); this.bccAddr = ko.observable('').extend({'reversible': true}); this.bccAddr.subscribe(function () { if (!this.lockBccAddr()) { $(this.bccAddrDom()).val(this.bccAddr()); $(this.bccAddrDom()).inputosaurus('refresh'); } }, this); this.recipientEmails = ko.computed(function () { var aRecip = [this.toAddr(), this.ccAddr(), this.bccAddr()].join(',').split(','), aEmails = [] ; _.each(aRecip, function (sRecip) { var sTrimmedRecip = Utils.trim(sRecip), oRecip = null ; if (sTrimmedRecip !== '') { oRecip = Utils.getEmailParts(sTrimmedRecip); if (oRecip.email) { aEmails.push(oRecip.email); } } }); return aEmails; }, this); this.subject = ko.observable('').extend({'reversible': true}); this.counter = ko.observable(0); this.commitedTextBody = ko.observable(''); this.plainText = ko.observable(false); this.textBody = ko.observable(''); this.textBody.subscribe(function () { this.oHtmlEditor.setText(this.textBody(), this.plainText()); this.commitedTextBody(this.oHtmlEditor.getText()); }, this); this.toAddrFocused = ko.observable(false); this.toAddrFocused.subscribe(function () { if (this.toAddrFocused()) { $(this.toAddrDom()).inputosaurus('focus'); } }, this); this.ccAddrFocused = ko.observable(false); this.ccAddrFocused.subscribe(function () { if (this.ccAddrFocused()) { $(this.ccAddrDom()).inputosaurus('focus'); } }, this); this.bccAddrFocused = ko.observable(false); this.bccAddrFocused.subscribe(function () { if (this.bccAddrFocused()) { $(this.bccAddrDom()).inputosaurus('focus'); } }, this); this.subjectFocused = ko.observable(false); this.draftUid = ko.observable(''); this.draftInfo = ko.observableArray([]); this.routeType = ko.observable(''); this.routeParams = ko.observableArray([]); this.inReplyTo = ko.observable(''); this.references = ko.observable(''); this.bUploadStatus = false; this.iUploadAttachmentsTimer = 0; this.messageUploadAttachmentsStarted = ko.observable(false); this.messageUploadAttachmentsStarted.subscribe(function (bValue) { window.clearTimeout(self.iUploadAttachmentsTimer); if (bValue) { self.iUploadAttachmentsTimer = window.setTimeout(function () { self.bUploadStatus = true; App.Api.showLoading(Utils.i18n('COMPOSE/INFO_ATTACHMENTS_LOADING')); }, 4000); } else { if (self.bUploadStatus) { self.iUploadAttachmentsTimer = window.setTimeout(function () { self.bUploadStatus = false; App.Api.hideLoading(); }, 1000); } else { App.Api.hideLoading(); } } }, this); this.attachments = ko.observableArray([]); this.attachmentsChanged = ko.observable(false); this.attachments.subscribe(function () { this.attachmentsChanged(true); }, this); this.notUploadedAttachments = ko.computed(function () { return _.filter(this.attachments(), function (oAttach) { return !oAttach.uploaded(); }); }, this); this.allAttachmentsUploaded = ko.computed(function () { return this.notUploadedAttachments().length === 0 && !this.messageUploadAttachmentsStarted(); }, this); this.notInlineAttachments = ko.computed(function () { return _.filter(this.attachments(), function (oAttach) { return !oAttach.linked(); }); }, this); this.notInlineAttachments.subscribe(function () { $html.toggleClass('screen-compose-attachments', this.notInlineAttachments().length > 0); }, this); this.allowStartSending = ko.computed(function() { return !this.saving(); }, this); this.allowStartSending.subscribe(function () { if (this.allowStartSending() && this.requiresPostponedSending()) { App.MessageSender.sendPostponedMail(this.draftUid()); this.requiresPostponedSending(false); } }, this); this.requiresPostponedSending = ko.observable(false); // file uploader this.oJua = null; this.isDraftsCleared = ko.observable(false); this.autoSaveTimer = -1; this.shown = ko.observable(false); this.shown.subscribe(function () { if (!this.shown()) { this.stopAutosaveTimer(); } }, this); this.backToListOnSendOrSave = ko.observable(false); this.enableOpenPgp = AppData.User.enableOpenPgp; this.pgpSecured = ko.observable(false); this.pgpSecured.subscribe(function () { this.oHtmlEditor.disabled(this.pgpSecured()); }, this); this.pgpEncrypted = ko.observable(false); this.fromDrafts = ko.observable(false); this.visibleDoPgpButton = ko.computed(function () { return this.enableOpenPgp() && (!this.pgpSecured() || this.pgpEncrypted() && this.fromDrafts()); }, this); this.visibleUndoPgpButton = ko.computed(function () { return this.enableOpenPgp() && this.pgpSecured() && (!this.pgpEncrypted() || !this.fromDrafts()); }, this); this.isEnableOpenPgpCommand = ko.computed(function () { return this.enableOpenPgp() && !this.pgpSecured(); }, this); this.backToListCommand = Utils.createCommand(this, this.executeBackToList); this.sendCommand = Utils.createCommand(this, this.executeSend, this.isEnableSending); this.saveCommand = Utils.createCommand(this, this.executeSaveCommand, this.isEnableSaving); this.openPgpCommand = Utils.createCommand(this, this.confirmOpenPgp, this.isEnableOpenPgpCommand); this.messageFields = ko.observable(null); this.bottomPanel = ko.observable(null); this.editableArea = ko.observable(null); this.mobileApp = bMobileApp; this.allowFiles = ko.observable(false); this.dropboxConnected = ko.observable(false); this.allowDropbox = ko.computed(function () { return AppData.SocialDropbox && this.dropboxConnected(); }, this); this.dropboxKey = AppData.SocialDropboxKey; // this.dropboxSecret = AppData.SocialDropboxSecret; this.googleConnected = ko.observable(false); this.allowGoogle = ko.computed(function () { return AppData.SocialGoogle && this.googleConnected(); }, this); /* this.googleKey = AppData.SocialGoogleApiKey; this.googleClientId = AppData.SocialGoogleId; this.googleApiLoaded = false; this.pickerApiLoaded = false; */ if (window.opener) { // var self = this; setTimeout(function() { window.onbeforeunload = function(){ if ((self.isChanged() && !self.isEmpty()) && !(self.sending() || self.saving())) { self.beforeHide(window.close); return ''; } }; }, 1000); } } CComposeViewModel.prototype.__name = 'CComposeViewModel'; /** * @param {Object} oFetcherOrIdentity */ CComposeViewModel.prototype.changeSelectedFetcherOrIdentity = function (oFetcherOrIdentity) { if (oFetcherOrIdentity) { if (oFetcherOrIdentity.id() !== (this.selectedFetcherOrIdentity() && this.selectedFetcherOrIdentity().id())) { this.selectedFetcherOrIdentity(oFetcherOrIdentity); } } else if (this.selectedFetcherOrIdentity() !== null) { this.selectedFetcherOrIdentity(null); } }; /** * Determines if sending a message is allowed. */ CComposeViewModel.prototype.isEnableSending = function () { var bRecipientIsEmpty = this.toAddr().length === 0 && this.ccAddr().length === 0 && this.bccAddr().length === 0, bFoldersLoaded = this.folderList().iAccountId !== 0 ; return bFoldersLoaded && !this.sending() && !bRecipientIsEmpty && this.allAttachmentsUploaded(); }; /** * Determines if saving a message is allowed. */ CComposeViewModel.prototype.isEnableSaving = function () { var bFoldersLoaded = this.folderList() && this.folderList().iAccountId !== 0; return this.shown() && bFoldersLoaded && !this.sending() && !this.saving(); }; /** * Executes after applying bindings. */ CComposeViewModel.prototype.onApplyBindings = function () { App.registerSessionTimeoutFunction(_.bind(this.executeSave, this, false)); var fAutocompleteCallback = _.bind(function (oData, fResponse) { this.autocompleteCallback(oData.term, fResponse); }, this) ; /* if (this.allowGoogle) { Utils.loadScript('https://apis.google.com/js/api.js?onload=onGoogleApiLoad', _.bind(this.onGoogleApiLoad, this), null, 'onGoogleApiLoad'); } */ if (this.allowDropbox) { Utils.loadScript('https://www.dropbox.com/static/api/2/dropins.js', null, { 'id': 'dropboxjs', 'data-app-key': this.dropboxKey }); } this.initUploader(); $(this.toAddrDom()).inputosaurus({ width: 'auto', parseOnBlur: true, autoCompleteSource: fAutocompleteCallback, change : _.bind(function (ev) { this.lockToAddr(true); this.setRecipient(this.toAddr, ev.target.value); this.lockToAddr(false); }, this), copy: _.bind(function (sVal) { this.inputosaurusBuffer = sVal; }, this), paste: _.bind(function () { var sInputosaurusBuffer = this.inputosaurusBuffer || ''; this.inputosaurusBuffer = ''; return sInputosaurusBuffer; }, this), mobileDevice: bMobileDevice }); $(this.ccAddrDom()).inputosaurus({ width: 'auto', parseOnBlur: true, autoCompleteSource: fAutocompleteCallback, change : _.bind(function (ev) { this.lockCcAddr(true); this.setRecipient(this.ccAddr, ev.target.value); this.lockCcAddr(false); }, this), copy: _.bind(function (sVal) { this.inputosaurusBuffer = sVal; }, this), paste: _.bind(function () { var sInputosaurusBuffer = this.inputosaurusBuffer || ''; this.inputosaurusBuffer = ''; return sInputosaurusBuffer; }, this), mobileDevice: bMobileDevice }); $(this.bccAddrDom()).inputosaurus({ width: 'auto', parseOnBlur: true, autoCompleteSource: fAutocompleteCallback, change : _.bind(function (ev) { this.lockBccAddr(true); this.setRecipient(this.bccAddr, ev.target.value); this.lockBccAddr(false); }, this), copy: _.bind(function (sVal) { this.inputosaurusBuffer = sVal; }, this), paste: _.bind(function () { var sInputosaurusBuffer = this.inputosaurusBuffer || ''; this.inputosaurusBuffer = ''; return sInputosaurusBuffer; }, this), mobileDevice: bMobileDevice }); this.hotKeysBind(); }; CComposeViewModel.prototype.hotKeysBind = function () { $(document).on('keydown', $.proxy(function(ev) { if (ev && ev.ctrlKey && !ev.altKey && !ev.shiftKey) { var nKey = ev.keyCode, sScreen = App.Screens.currentScreen(), bThisScreen = sScreen === Enums.Screens.Compose || sScreen === Enums.Screens.SingleCompose, bComputed = bThisScreen && ev && ev.ctrlKey, oEditableArea = this.editableArea(), oEnumsKey = Enums.Key ; if (!oEditableArea && this.oHtmlEditor.oCrea) { this.editableArea(this.oHtmlEditor.oCrea.$editableArea[0]); } if (bComputed && nKey === oEnumsKey.s) { ev.preventDefault(); ev.returnValue = false; if (this.isEnableSaving()) { this.saveCommand(); } } else if (bComputed && nKey === oEnumsKey.Enter && this.toAddr() !== '') { this.sendCommand(); } } },this)); }; CComposeViewModel.prototype.getMessageOnRoute = function () { var aParams = this.routeParams(), sFolderName = '', sUid = '' ; if (this.routeType() !== '' && aParams.length === 3) { sFolderName = aParams[1]; sUid = aParams[2]; App.MailCache.getMessage(sFolderName, sUid, this.onMessageResponse, this); } this.routeParams([]); }; /** * Executes if the view model shows. Requests a folder list from the server to know the full names * of the folders Drafts and Sent Items. */ CComposeViewModel.prototype.onShow = function () { this.useSaveMailInSentItems(AppData.User.getUseSaveMailInSentItems()); this.saveMailInSentItems(AppData.User.getSaveMailInSentItems()); this.oHtmlEditor.initCrea(this.textBody(), this.plainText(), '7'); this.commitedTextBody(this.oHtmlEditor.getText()); this.shown(true); this.backToListOnSendOrSave(false); this.startAutosaveTimer(); this.focusAfterFilling(); $html.addClass('screen-compose'); if (this.oJua) { this.oJua.setDragAndDropEnabledStatus(true); } this.getSocialAccounts(); }; /** * Executes if routing changed. * * @param {Array} aParams */ CComposeViewModel.prototype.onRoute = function (aParams) { var sSignature = '', oToAddr = {} ; this.plainText(false); this.pgpSecured(false); this.pgpEncrypted(false); this.fromDrafts(false); this.changeSenderAccountId(AppData.Accounts.currentId()); this.bUploadStatus = false; window.clearTimeout(this.iUploadAttachmentsTimer); this.messageUploadAttachmentsStarted(false); this.draftUid(''); this.draftInfo.removeAll(); this.setDataFromMessage(new CMessageModel()); this.isDraftsCleared(false); this.routeType((aParams.length > 0) ? aParams[0] : ''); switch (this.routeType()) { case Enums.ReplyType.Reply: case Enums.ReplyType.ReplyAll: case Enums.ReplyType.Resend: case Enums.ReplyType.Forward: case 'drafts': this.routeParams(aParams); if (this.folderList().iAccountId !== 0) { this.getMessageOnRoute(); } break; default: sSignature = App.MessageSender.getSignatureText(this.senderAccountId(), null, true); if (AppData.SingleMode && window.opener && window.opener.oMessageParametersFromCompose) { this.setMessageDataInSingleMode(window.opener.oMessageParametersFromCompose); window.opener.oMessageParametersFromCompose = undefined; } else if (sSignature !== '') { this.textBody('<br /><br />' + sSignature + '<br />'); } if (this.routeType() === 'to' && aParams.length === 2) { oToAddr = App.Links.parseToAddr(aParams[1]); this.setRecipient(this.toAddr, oToAddr.to); if (oToAddr.hasMailto) { this.subject(oToAddr.subject); this.setRecipient(this.ccAddr, oToAddr.cc); this.setRecipient(this.bccAddr, oToAddr.bcc); this.textBody(oToAddr.body); } } if (this.routeType() === 'vcard' && aParams.length === 2) { this.addContactAsAttachment(aParams[1]); } if (this.routeType() === 'file' && aParams.length === 2) { this.addFilesAsAttachment(aParams[1]); } if (this.routeType() === 'data-as-file' && aParams.length === 3) { this.addDataAsAttachment(aParams[1], aParams[2]); } break; } this.visibleCc(this.ccAddr() !== ''); this.visibleBcc(this.bccAddr() !== ''); this.commit(); this.focusAfterFilling(); this.allowFiles(AppData.User.IsFilesSupported && AppData.User.filesEnable()); }; CComposeViewModel.prototype.focusAfterFilling = function () { if (this.toAddr().length === 0) { this.toAddrFocused(true); this.toAddrFocused.valueHasMutated(); } else if (this.subject().length === 0) { this.subjectFocused(true); } else { this.oHtmlEditor.setFocus(); } }; /** * @param {Function} fContinueScreenChanging */ CComposeViewModel.prototype.beforeHide = function (fContinueScreenChanging) { var sConfirm = Utils.i18n('COMPOSE/CONFIRM_DISCARD_CHANGES'), fOnConfirm = _.bind(function (bOk) { if (bOk && Utils.isFunc(fContinueScreenChanging)) { this.commit(); fContinueScreenChanging(); } else { App.Routing.historyBackWithoutParsing(Enums.Screens.Compose); } }, this) ; if ((this.isChanged() && !this.isEmpty()) && !(this.sending() || this.saving())) { App.Screens.showPopup(ConfirmPopup, [sConfirm, fOnConfirm]); } else if (Utils.isFunc(fContinueScreenChanging)) { fContinueScreenChanging(); } }; /** * Executes if view model was hidden. */ CComposeViewModel.prototype.onHide = function () { if (this.isChanged() && !this.isEmpty()) { this.executeSave(true); } this.shown(false); this.stopAutosaveTimer(); this.toAddrFocused(false); this.ccAddrFocused(false); this.bccAddrFocused(false); this.subjectFocused(false); this.oHtmlEditor.closeAllPopups(); this.oHtmlEditor.visibleLinkPopup(false); this.messageUploadAttachmentsStarted(false); $html.removeClass('screen-compose').removeClass('screen-compose-cc').removeClass('screen-compose-bcc').removeClass('screen-compose-attachments'); if (this.oJua) { this.oJua.setDragAndDropEnabledStatus(false); } }; CComposeViewModel.prototype.sendingAndSavingSubscription = function () { if (this.sending() || this.saving()) { this.stopAutosaveTimer(); } if (!this.sending() && !this.saving()) { this.startAutosaveTimer(); } }; /** * Stops autosave. */ CComposeViewModel.prototype.stopAutosaveTimer = function () { window.clearTimeout(this.autoSaveTimer); }; /** * Starts autosave. */ CComposeViewModel.prototype.startAutosaveTimer = function () { if (this.shown() && !this.pgpSecured()) { var fSave = _.bind(this.executeSave, this, true); this.stopAutosaveTimer(); if (AppData.User.AllowAutosaveInDrafts) { this.autoSaveTimer = window.setTimeout(fSave, AppData.App.AutoSaveIntervalSeconds * 1000); } } }; /** * @param {Object} koRecipient * @param {string} sRecipient */ CComposeViewModel.prototype.setRecipient = function (koRecipient, sRecipient) { if (koRecipient() === sRecipient) { koRecipient.valueHasMutated(); } else { koRecipient(sRecipient); } }; /** * @param {Object} oMessage */ CComposeViewModel.prototype.onMessageResponse = function (oMessage) { var oReplyData = null, oFetcherOrIdentity = null, aRecipients = oMessage.oTo.aCollection.concat(oMessage.oCc.aCollection), bIsFetcherOrIdentitySameAsChiefAccount = false ; if (oMessage === null) { this.setDataFromMessage(new CMessageModel()); } else { oFetcherOrIdentity = App.MessageSender.getFetcherOrIdentityByRecipients(aRecipients, oMessage.accountId()); bIsFetcherOrIdentitySameAsChiefAccount = App.MessageSender.isFetcherOrIdentitySameAsChiefAccount(this.senderAccountId()); switch (this.routeType()) { case Enums.ReplyType.Reply: case Enums.ReplyType.ReplyAll: if (oFetcherOrIdentity && !bIsFetcherOrIdentitySameAsChiefAccount) { this.changeSelectedFetcherOrIdentity(oFetcherOrIdentity); } oReplyData = App.MessageSender.getReplyDataFromMessage(oMessage, this.routeType(), this.senderAccountId(), oFetcherOrIdentity, true); this.draftInfo(oReplyData.DraftInfo); this.draftUid(oReplyData.DraftUid); this.setRecipient(this.toAddr, oReplyData.To); this.setRecipient(this.ccAddr, oReplyData.Cc); this.setRecipient(this.bccAddr, oReplyData.Bcc); this.subject(oReplyData.Subject); this.textBody(oReplyData.Text); this.attachments(oReplyData.Attachments); this.inReplyTo(oReplyData.InReplyTo); this.references(oReplyData.References); break; case Enums.ReplyType.Forward: oReplyData = App.MessageSender.getReplyDataFromMessage(oMessage, this.routeType(), this.senderAccountId(), oFetcherOrIdentity, true); this.draftInfo(oReplyData.DraftInfo); this.draftUid(oReplyData.DraftUid); this.setRecipient(this.toAddr, oReplyData.To); this.setRecipient(this.ccAddr, oReplyData.Cc); this.subject(oReplyData.Subject); this.textBody(oReplyData.Text); this.attachments(oReplyData.Attachments); this.inReplyTo(oReplyData.InReplyTo); this.references(oReplyData.References); break; case Enums.ReplyType.Resend: this.setDataFromMessage(oMessage); break; case 'drafts': if (oMessage.subject().substring(0, 3) !== Utils.i18n('COMPOSE/FORWARD_PREFIX')) { this.changeSelectedFetcherOrIdentity(oFetcherOrIdentity); } this.draftUid(oMessage.uid()); this.setDataFromMessage(oMessage); this.fromDrafts(true); break; } this.routeType(''); } if (this.attachments().length > 0) { this.requestAttachmentsTempName(); } this.visibleCc(this.ccAddr() !== ''); this.visibleBcc(this.bccAddr() !== ''); this.commit(); this.focusAfterFilling(); }; /** * @param {number} iId * @param {string=} sEmail * @param {string=} oFetcherOrIdentity */ CComposeViewModel.prototype.changeSenderAccountId = function (iId, sEmail, oFetcherOrIdentity) { if (AppData.Accounts.hasAccountWithId(iId)) { this.senderAccountId(iId); } else if (!AppData.Accounts.hasAccountWithId(this.senderAccountId())) { this.senderAccountId(AppData.Accounts.currentId()); } this.fillSenderList(sEmail, oFetcherOrIdentity); }; /** * @param {string=} sEmail * @param {string=} oFetcherOrIdentity */ CComposeViewModel.prototype.fillSenderList = function (sEmail, oFetcherOrIdentity) { var aSenderList = [], oAccount = AppData.Accounts.getAccount(this.senderAccountId()) ; if (oAccount) { aSenderList.push({fullEmail: oAccount.fullEmail(), id: ''}); if (oAccount.fetchers()) { _.each(oAccount.fetchers().collection(), function (oFetcher) { var sFullEmail = oFetcher.fullEmail(); if (oFetcher.isOutgoingEnabled() && sFullEmail.length > 0) { aSenderList.push({fullEmail: sFullEmail, id: 'fetcher' + oFetcher.id()}); } }, this); } else if (!oAccount.fetchersSubscribtion) { oAccount.fetchersSubscribtion = oAccount.fetchers.subscribe(function () { this.fillSenderList(sEmail, oFetcherOrIdentity); }, this); } if (_.isArray(oAccount.identities())) { _.each(oAccount.identities(), function (oIdentity) { if (oIdentity.enabled()) { aSenderList.push({fullEmail: oIdentity.fullEmail(), id: Utils.pString(oIdentity.id())}); } }, this); } else if (!oAccount.identitiesSubscribtion) { oAccount.identitiesSubscribtion = oAccount.identities.subscribe(function () { this.fillSenderList(sEmail, oFetcherOrIdentity); }, this); } } this.senderList(aSenderList.length > 0 ? aSenderList : []); if (sEmail && sEmail !== '') { this.changeSelectedSenderByEmail(sEmail); } else { this.changeSelectedFetcherOrIdentity(oFetcherOrIdentity || null); } }; /** * @param {string} sEmail */ CComposeViewModel.prototype.changeSelectedSenderByEmail = function (sEmail) { var oAccount = AppData.Accounts.getAccount(this.senderAccountId()), oFetcherOrIdentity = (oAccount) ? oAccount.getFetcherOrIdentityByEmail(sEmail) : null ; if (oFetcherOrIdentity && oFetcherOrIdentity.id() && oAccount.email() !== sEmail) { this.changeSelectedFetcherOrIdentity(oFetcherOrIdentity); } }; /** * @param {Object} oMessage */ CComposeViewModel.prototype.setDataFromMessage = function (oMessage) { var sTextBody = '', bPgpEncrypted = false, bPgpSigned = false ; if (oMessage.isPlain()) { bPgpEncrypted = oMessage.textRaw().indexOf('-----BEGIN PGP MESSAGE-----') !== -1; bPgpSigned = oMessage.textRaw().indexOf('-----BEGIN PGP SIGNED MESSAGE-----') !== -1; if (bPgpSigned || bPgpEncrypted) { sTextBody = oMessage.textRaw(); this.pgpSecured(true); this.pgpEncrypted(bPgpEncrypted); } else { sTextBody = oMessage.textRaw(); } } else { sTextBody = oMessage.getConvertedHtml(); } this.draftInfo(oMessage.draftInfo()); this.inReplyTo(oMessage.inReplyTo()); this.references(oMessage.references()); this.setRecipient(this.toAddr, oMessage.oTo.getFull()); this.setRecipient(this.ccAddr, oMessage.oCc.getFull()); this.setRecipient(this.bccAddr, oMessage.oBcc.getFull()); this.subject(oMessage.subject()); this.attachments(oMessage.attachments()); this.plainText(oMessage.isPlain()); this.textBody(sTextBody); this.selectedImportance(oMessage.importance()); this.selectedSensitivity(oMessage.sensitivity()); this.readingConfirmation(oMessage.readingConfirmation()); this.changeSenderAccountId(oMessage.accountId(), oMessage.oFrom.getFirstEmail()); }; /** * @param {string} sData * @param {string} sFileName */ CComposeViewModel.prototype.addDataAsAttachment = function (sData, sFileName) { var sHash = 'data-as-attachment-' + Math.random(), oParameters = { 'Action': 'DataAsAttachmentUpload', 'Data': sData, 'FileName': sFileName, 'Hash': sHash }, oAttach = new CMailAttachmentModel() ; this.subject(sFileName.substr(0, sFileName.length - 4)); oAttach.fileName(sFileName); oAttach.hash(sHash); oAttach.uploadStarted(true); this.attachments.push(oAttach); this.messageUploadAttachmentsStarted(true); App.Ajax.send(oParameters, this.onDataAsAttachmentUpload, this); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CComposeViewModel.prototype.onDataAsAttachmentUpload = function (oResponse, oRequest) { var oResult = oResponse.Result, sHash = oRequest.Hash, oAttachment = _.find(this.attachments(), function (oAttach) { return oAttach.hash() === sHash; }) ; this.messageUploadAttachmentsStarted(false); if (oAttachment) { if (oResult && oResult.Attachment) { oAttachment.parseFromUpload(oResult.Attachment, oResponse.AccountID); } else { oAttachment.errorFromUpload(); } } }; /** * @param {Array} aFiles */ CComposeViewModel.prototype.addFilesAsAttachment = function (aFiles) { var oAttach = null, aHashes = [], oParameters = null ; _.each(aFiles, function (oFile) { oAttach = new CMailAttachmentModel(); oAttach.fileName(oFile.fileName()); oAttach.hash(oFile.hash()); oAttach.thumb(oFile.thumb()); oAttach.uploadStarted(true); this.attachments.push(oAttach); aHashes.push(oFile.hash()); }, this); if (aHashes.length > 0) { oParameters = { 'Action': 'FilesUpload', 'Hashes': aHashes }; this.messageUploadAttachmentsStarted(true); App.Ajax.send(oParameters, this.onFilesUpload, this); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CComposeViewModel.prototype.onFilesUpload = function (oResponse, oRequest) { var aResult = oResponse.Result, aHashes = oRequest.Hashes, sThumbSessionUid = Date.now().toString() ; this.messageUploadAttachmentsStarted(false); if ($.isArray(aResult)) { _.each(aResult, function (oFileData) { var oAttachment = _.find(this.attachments(), function (oAttach) { return oAttach.hash() === oFileData.Hash; }); if (oAttachment) { oAttachment.parseFromUpload(oFileData, oResponse.AccountID); oAttachment.hash(oFileData.NewHash); oAttachment.getInThumbQueue(sThumbSessionUid); } }, this); } else { _.each(aHashes, function (sHash) { var oAttachment = _.find(this.attachments(), function (oAttach) { return oAttach.hash() === sHash; }); if (oAttachment) { oAttachment.errorFromUpload(); } }, this); } }; /** * @param {Object} oContact */ CComposeViewModel.prototype.addContactAsAttachment = function (oContact) { var oAttach = new CMailAttachmentModel(), oParameters = null ; if (oContact) { oAttach.fileName('contact-' + oContact.idContact() + '.vcf'); oAttach.uploadStarted(true); this.attachments.push(oAttach); oParameters = { 'Action': 'ContactVCardUpload', 'ContactId': oContact.idContact(), 'Global': oContact.global() ? '1' : '0', 'Name': oAttach.fileName() }; this.messageUploadAttachmentsStarted(true); App.Ajax.send(oParameters, this.onContactVCardUpload, this); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CComposeViewModel.prototype.onContactVCardUpload = function (oResponse, oRequest) { var oResult = oResponse.Result, oAttach = null ; this.messageUploadAttachmentsStarted(false); if (oResult) { oAttach = _.find(this.attachments(), function (oAttach) { return oAttach.fileName() === oResult.Name && oAttach.uploadStarted(); }); if (oAttach) { oAttach.parseFromUpload(oResult, oResponse.AccountID); } } else { oAttach = _.find(this.attachments(), function (oAttach) { return oAttach.fileName() === oRequest.Name && oAttach.uploadStarted(); }); if (oAttach) { oAttach.errorFromUpload(); } } }; CComposeViewModel.prototype.requestAttachmentsTempName = function () { var aHash = _.map(this.attachments(), function (oAttach) { oAttach.uploadUid(oAttach.hash()); oAttach.uploadStarted(true); return oAttach.hash(); }), oParameters = { 'Action': 'MessageUploadAttachments', 'Attachments': aHash } ; if (aHash.length > 0) { this.messageUploadAttachmentsStarted(true); App.Ajax.send(oParameters, this.onMessageUploadAttachmentsResponse, this); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CComposeViewModel.prototype.onMessageUploadAttachmentsResponse = function (oResponse, oRequest) { var aHashes = oRequest.Attachments; this.messageUploadAttachmentsStarted(false); if (oResponse.Result) { _.each(oResponse.Result, _.bind(this.setAttachTepmNameByHash, this)); } else { _.each(aHashes, function (sHash) { var oAttachment = _.find(this.attachments(), function (oAttach) { return oAttach.hash() === sHash; }); if (oAttachment) { oAttachment.errorFromUpload(); } }, this); App.Api.showError(Utils.i18n('COMPOSE/UPLOAD_ERROR_REPLY_ATTACHMENTS')); } }; /** * @param {string} sHash * @param {string} sTempName */ CComposeViewModel.prototype.setAttachTepmNameByHash = function (sHash, sTempName) { _.each(this.attachments(), function (oAttach) { if (oAttach.hash() === sHash) { oAttach.tempName(sTempName); oAttach.uploadStarted(false); } }); }; /** * @param {Object} oParameters */ CComposeViewModel.prototype.setMessageDataInSingleMode = function (oParameters) { this.draftInfo(oParameters.draftInfo); this.draftUid(oParameters.draftUid); this.inReplyTo(oParameters.inReplyTo); this.references(oParameters.references); this.setRecipient(this.toAddr, oParameters.toAddr); this.setRecipient(this.ccAddr, oParameters.ccAddr); this.setRecipient(this.bccAddr, oParameters.bccAddr); this.subject(oParameters.subject); this.attachments(_.map(oParameters.attachments, function (oRawAttach) { var oAttach = new CMailAttachmentModel(); oAttach.parse(oRawAttach, this.senderAccountId()); return oAttach; }, this)); this.textBody(oParameters.textBody); this.selectedImportance(oParameters.selectedImportance); this.selectedSensitivity(oParameters.selectedSensitivity); this.readingConfirmation(oParameters.readingConfirmation); this.changeSenderAccountId(oParameters.senderAccountId, '', oParameters.selectedFetcherOrIdentity); }; CComposeViewModel.prototype.isEmpty = function () { var sTo = Utils.trim(this.toAddr()), sCc = Utils.trim(this.ccAddr()), sBcc = Utils.trim(this.bccAddr()), sSubject = Utils.trim(this.subject()), sText = this.oHtmlEditor.getText(), sTextWithoutNodes = Utils.trim(sText .replace(/<br *\/{0,1}>/gi, '\n') .replace(/<[^>]*>/g, '') .replace(/ /g, ' ')) ; return (sTo === '' && sCc === '' && sBcc === '' && sSubject === '' && this.attachments().length === 0 && sTextWithoutNodes === ''); }; CComposeViewModel.prototype.commit = function () { this.toAddr.commit(); this.ccAddr.commit(); this.bccAddr.commit(); this.subject.commit(); this.commitedTextBody(this.oHtmlEditor.getText()); this.attachmentsChanged(false); }; CComposeViewModel.prototype.isChanged = function () { var bNotParsedToEmpty = $(this.toAddrDom()).inputosaurus('getNotParsedValue') === '', bNotParsedCcEmpty = $(this.ccAddrDom()).inputosaurus('getNotParsedValue') === '', bNotParsedBccEmpty = $(this.bccAddrDom()).inputosaurus('getNotParsedValue') === '' ; return this.toAddr.changed() || !bNotParsedToEmpty || this.ccAddr.changed() || !bNotParsedCcEmpty || this.bccAddr.changed() || !bNotParsedBccEmpty || this.subject.changed() || (this.commitedTextBody() !== this.oHtmlEditor.getText()) || this.attachmentsChanged(); }; CComposeViewModel.prototype.executeBackToList = function () { if (AppData.SingleMode) { window.close(); } else if (this.shown()) { App.Routing.setPreviousHash(); } this.backToListOnSendOrSave(false); }; /** * Creates new attachment for upload. * * @param {string} sFileUid * @param {Object} oFileData */ CComposeViewModel.prototype.onFileUploadSelect = function (sFileUid, oFileData) { var oAttach, sWarning = Utils.i18n('COMPOSE/UPLOAD_ERROR_FILENAME_SIZE', { 'FILENAME': oFileData.FileName, 'MAXSIZE': Utils.friendlySize(AppData.App.AttachmentSizeLimit) }) ; if (AppData.App.AttachmentSizeLimit > 0 && oFileData.Size > AppData.App.AttachmentSizeLimit) { App.Screens.showPopup(AlertPopup, [sWarning]); return false; } oAttach = new CMailAttachmentModel(); oAttach.onUploadSelect(sFileUid, oFileData); this.attachments.push(oAttach); return true; }; /** * Returns attachment found by uid. * * @param {string} sFileUid */ CComposeViewModel.prototype.getAttachmentByUid = function (sFileUid) { return _.find(this.attachments(), function (oAttach) { return oAttach.uploadUid() === sFileUid; }); }; /** * Finds attachment by uid. Calls it's function to start upload. * * @param {string} sFileUid */ CComposeViewModel.prototype.onFileUploadStart = function (sFileUid) { var oAttach = this.getAttachmentByUid(sFileUid); if (oAttach) { oAttach.onUploadStart(); } }; /** * Finds attachment by uid. Calls it's function to progress upload. * * @param {string} sFileUid * @param {number} iUploadedSize * @param {number} iTotalSize */ CComposeViewModel.prototype.onFileUploadProgress = function (sFileUid, iUploadedSize, iTotalSize) { var oAttach = this.getAttachmentByUid(sFileUid); if (oAttach) { oAttach.onUploadProgress(iUploadedSize, iTotalSize); } }; /** * Finds attachment by uid. Calls it's function to complete upload. * * @param {string} sFileUid * @param {boolean} bResponseReceived * @param {Object} oResult */ CComposeViewModel.prototype.onFileUploadComplete = function (sFileUid, bResponseReceived, oResult) { var oAttach = this.getAttachmentByUid(sFileUid), sThumbSessionUid = Date.now().toString() ; if (oAttach) { oAttach.onUploadComplete(sFileUid, bResponseReceived, oResult); if (oAttach.type().substr(0, 5) === 'image') { oAttach.thumb(true); oAttach.getInThumbQueue(sThumbSessionUid); } } }; /** * Finds attachment by uid. Calls it's function to cancel upload. * * @param {string} sFileUid */ CComposeViewModel.prototype.onFileRemove = function (sFileUid) { var oAttach = this.getAttachmentByUid(sFileUid); if (this.oJua) { this.oJua.cancel(sFileUid); } this.attachments.remove(oAttach); }; /** * Initializes file uploader. */ CComposeViewModel.prototype.initUploader = function () { if (this.composeUploaderButton()) { this.oJua = new Jua({ 'action': '?/Upload/Attachment/', 'name': 'jua-uploader', 'queueSize': 2, 'clickElement': this.composeUploaderButton(), 'dragAndDropElement': this.composeUploaderDropPlace(), 'disableAjaxUpload': false, 'disableFolderDragAndDrop': false, 'disableDragAndDrop': false, 'hidden': { 'Token': function () { return AppData.Token; }, 'AccountID': function () { return AppData.Accounts.currentId(); } } }); this.oJua .on('onDragEnter', _.bind(this.composeUploaderDragOver, this, true)) .on('onDragLeave', _.bind(this.composeUploaderDragOver, this, false)) .on('onBodyDragEnter', _.bind(this.composeUploaderBodyDragOver, this, true)) .on('onBodyDragLeave', _.bind(this.composeUploaderBodyDragOver, this, false)) .on('onProgress', _.bind(this.onFileUploadProgress, this)) .on('onSelect', _.bind(this.onFileUploadSelect, this)) .on('onStart', _.bind(this.onFileUploadStart, this)) .on('onComplete', _.bind(this.onFileUploadComplete, this)) ; this.allowDragNDrop(this.oJua.isDragAndDropSupported()); } }; /** * @param {boolean} bRemoveSignatureAnchor */ CComposeViewModel.prototype.getSendSaveParameters = function (bRemoveSignatureAnchor) { var oAttachments = App.MessageSender.convertAttachmentsForSending(this.attachments()) ; _.each(this.oHtmlEditor.uploadedImagePathes(), function (oAttach) { oAttachments[oAttach.TempName] = [oAttach.Name, oAttach.CID, '1', '1']; }); return { 'AccountID': this.senderAccountId(), 'FetcherID': this.selectedFetcherOrIdentity() && this.selectedFetcherOrIdentity().FETCHER ? this.selectedFetcherOrIdentity().id() : '', 'IdentityID': this.selectedFetcherOrIdentity() && !this.selectedFetcherOrIdentity().FETCHER ? this.selectedFetcherOrIdentity().id() : '', 'DraftInfo': this.draftInfo(), 'DraftUid': this.draftUid(), 'To': this.toAddr(), 'Cc': this.ccAddr(), 'Bcc': this.bccAddr(), 'Subject': this.subject(), 'Text': this.plainText() ? this.oHtmlEditor.getPlainText() : this.oHtmlEditor.getText(bRemoveSignatureAnchor), 'IsHtml': this.plainText() ? '0' : '1', 'Importance': this.selectedImportance(), 'Sensivity': this.selectedSensitivity(), 'ReadingConfirmation': this.readingConfirmation() ? '1' : '0', 'Attachments': oAttachments, 'InReplyTo': this.inReplyTo(), 'References': this.references() }; }; /** * @param {Object} oResponse * @param {Object} oRequest */ CComposeViewModel.prototype.onMessageSendOrSaveResponse = function (oResponse, oRequest) { var oResData = App.MessageSender.onMessageSendOrSaveResponse(oResponse, oRequest); this.commit(); switch (oResData.Action) { case 'MessageSave': if (oResData.Result) { if (oResData.NewUid) { this.draftUid(oResData.NewUid); } } this.saving(false); break; case 'MessageSend': if (oResData.Result) { App.MailCache.deletedDraftMessageUid(this.draftUid()); if (this.backToListOnSendOrSave()) { this.executeBackToList(); } } this.sending(false); break; } }; CComposeViewModel.prototype.verifyDataForSending = function () { var aToIncorrect = Utils.getIncorrectEmailsFromAddressString(this.toAddr()), aCcIncorrect = Utils.getIncorrectEmailsFromAddressString(this.ccAddr()), aBccIncorrect = Utils.getIncorrectEmailsFromAddressString(this.bccAddr()), aIncorrect = _.union(aToIncorrect, aCcIncorrect, aBccIncorrect), sWarning = Utils.i18n('COMPOSE/WARNING_INPUT_CORRECT_EMAILS') + aIncorrect.join(', ') ; if (aIncorrect.length > 0) { App.Screens.showPopup(AlertPopup, [sWarning]); return false; } return true; }; /** * @param {mixed} mParam */ CComposeViewModel.prototype.executeSend = function (mParam) { var bAlreadySigned = (mParam === true); if (this.isEnableSending() && this.verifyDataForSending()) { if (!bAlreadySigned && this.enableOpenPgp() && AppData.User.AutosignOutgoingEmails && !this.pgpSecured()) { this.openPgpPopup(true); } else { this.sending(true); this.requiresPostponedSending(!this.allowStartSending()); App.MessageSender.send('MessageSend', this.getSendSaveParameters(true), this.saveMailInSentItems(), true, this.onMessageSendOrSaveResponse, this, this.requiresPostponedSending()); } this.backToListOnSendOrSave(true); } }; CComposeViewModel.prototype.executeSaveCommand = function () { this.executeSave(false); }; /** * @param {boolean=} bAutosave = false */ CComposeViewModel.prototype.executeSave = function (bAutosave) { var sConfirm = Utils.i18n('OPENPGP/CONFIRM_SAVE_ENCRYPTED_DRAFT'), sOkButton = Utils.i18n('COMPOSE/TOOL_SAVE'), fSave = _.bind(function (bSave) { if (bSave) { this.saving(true); App.MessageSender.send('MessageSave', this.getSendSaveParameters(false), this.saveMailInSentItems(), !bAutosave, this.onMessageSendOrSaveResponse, this); } }, this) ; if (this.isEnableSaving()) { if (!bAutosave || this.isChanged()) { if (!bAutosave && this.pgpSecured()) { App.Screens.showPopup(ConfirmPopup, [sConfirm, fSave, '', sOkButton]); } else { fSave(true); } } else if (bAutosave) { this.startAutosaveTimer(); } this.backToListOnSendOrSave(true); } }; /** * Changes visibility of bcc field. */ CComposeViewModel.prototype.changeBccVisibility = function () { this.visibleBcc(!this.visibleBcc()); if (this.visibleBcc()) { this.bccAddrFocused(true); } else { this.toAddrFocused(true); } }; /** * Changes visibility of bcc field. */ CComposeViewModel.prototype.changeCcVisibility = function () { this.visibleCc(!this.visibleCc()); if (this.visibleCc()) { this.ccAddrFocused(true); } else { this.toAddrFocused(true); } }; CComposeViewModel.prototype.getMessageDataForSingleMode = function () { var aAttachments = _.map(this.attachments(), function (oAttach) { return { '@Object': 'Object/CApiMailAttachment', 'FileName': oAttach.fileName(), 'TempName': oAttach.tempName(), 'MimeType': oAttach.type(), 'MimePartIndex': oAttach.mimePartIndex(), 'EstimatedSize': oAttach.size(), 'CID': oAttach.cid(), 'ContentLocation': oAttach.contentLocation(), 'IsInline': oAttach.inline(), 'IsLinked': oAttach.linked(), 'Hash': oAttach.hash() }; }); return { draftInfo: this.draftInfo(), draftUid: this.draftUid(), inReplyTo: this.inReplyTo(), references: this.references(), senderAccountId: this.senderAccountId(), selectedFetcherOrIdentity: this.selectedFetcherOrIdentity(), toAddr: this.toAddr(), ccAddr: this.ccAddr(), bccAddr: this.bccAddr(), subject: this.subject(), attachments: aAttachments, textBody: this.oHtmlEditor.getText(), selectedImportance: this.selectedImportance(), selectedSensitivity: this.selectedSensitivity(), readingConfirmation: this.readingConfirmation() }; }; CComposeViewModel.prototype.openInNewWindow = function () { window.oMessageParametersFromCompose = this.getMessageDataForSingleMode(); Utils.WindowOpener.openTab('#' + Enums.Screens.SingleCompose); this.commit(); this.executeBackToList(); }; /** * @param {string} sTerm * @param {Function} fResponse */ CComposeViewModel.prototype.autocompleteCallback = function (sTerm, fResponse) { var oParameters = { 'Action': 'ContactSuggestions', 'Search': sTerm } ; sTerm = Utils.trim(sTerm); if ('' !== sTerm) { App.Ajax.send(oParameters, function (oResponse) { var aList = []; if (oResponse && oResponse.Result && oResponse.Result && oResponse.Result.List) { aList = _.map(oResponse.Result.List, function (oItem) { var sLabel = '', sValue = oItem.Email ; if (oItem.IsGroup) { if (oItem.Name && 0 < Utils.trim(oItem.Name).length) { sLabel = '"' + oItem.Name + '" (' + oItem.Email + ')'; } else { sLabel = '(' + oItem.Email + ')'; } } else { if (oItem.Name && 0 < Utils.trim(oItem.Name).length) { sLabel = '"' + oItem.Name + '" <' + oItem.Email + '>'; sValue = sLabel; } else { sLabel = oItem.Email; } } return {'label': sLabel, 'value': sValue, 'frequency': oItem.Frequency}; }); aList = _.compact(aList); // aList = _.sortBy(_.compact(aList), function(nNum) { // return nNum['frequency']; // }).reverse(); } fResponse(aList); }, this); } else { fResponse([]); } }; CComposeViewModel.prototype.onShowFilesPopupClick = function () { var fCallBack = _.bind(this.addFilesAsAttachment, this); /*global FileStoragePopup:true */ App.Screens.showPopup(FileStoragePopup, [fCallBack]); /*global FileStoragePopup:false */ }; // Google Drive CComposeViewModel.prototype.onShowGoogleDriveClick = function () { /*global GooglePickerPopup:true */ App.Screens.showPopup(GooglePickerPopup, [_.bind(this.googlePickerCallback, this)]); /*global GooglePickerPopup:false */ }; CComposeViewModel.prototype.googlePickerCallback = function (aPickerItems, sAccessToken) { var oAttach = null, aUrls = [], oParameters = {}, self = this ; _.each(aPickerItems, function (oPickerItem) { oAttach = new CMailAttachmentModel() .fileName(oPickerItem.name) .hash(oPickerItem.id) .size(oPickerItem.sizeBytes) .uploadStarted(true) .type(oPickerItem.mimeType); if (oAttach.type().substr(0, 5) === 'image') { oAttach.thumb(true); } self.attachments.push(oAttach); aUrls.push(oPickerItem.id); }, this); oParameters = { 'Action': 'FilesUploadByLink', 'Links': aUrls, 'LinksAsIds': true, 'AccessToken': sAccessToken }; this.messageUploadAttachmentsStarted(true); App.Ajax.send(oParameters, this.onFilesUpload, this); }; // ---------------- // DropBox CComposeViewModel.prototype.onShowDropBoxClick = function () { var oAttach = null, aUrls = [], oParameters = {}, self = this, options = { success: function(files) { _.each(files, function (oFile) { oAttach = new CMailAttachmentModel() .fileName(oFile.name) .hash(oFile.link) .size(oFile.bytes) .uploadStarted(true) .thumb(!!oFile.thumbnailLink); self.attachments.push(oAttach); aUrls.push(oFile.link); }, self); oParameters = { 'Action': 'FilesUploadByLink', 'Links': aUrls }; self.messageUploadAttachmentsStarted(true); App.Ajax.send(oParameters, self.onFilesUpload, self); }, cancel: function() { }, linkType: "direct", multiselect: true } ; if (this.allowDropbox && window.Dropbox) { window.Dropbox.choose(options); } }; // ---------------- CComposeViewModel.prototype.confirmOpenPgp = function () { var sConfirm = Utils.i18n('OPENPGP/CONFIRM_HTML_TO_PLAIN_FORMATTING'), fOpenPgpEncryptPopup = _.bind(function (bRes) { if (bRes) { this.openPgpPopup(false); } }, this) ; if (this.notInlineAttachments().length > 0) { sConfirm += '\r\n\r\n' + Utils.i18n('OPENPGP/CONFIRM_HTML_TO_PLAIN_ATTACHMENTS'); } App.Screens.showPopup(ConfirmPopup, [sConfirm, fOpenPgpEncryptPopup]); }; /** * @param {boolean} bSignAndSend */ CComposeViewModel.prototype.openPgpPopup = function (bSignAndSend) { var sText = this.oHtmlEditor.getPlainText(), fOkCallback = _.bind(function (oSignedEncryptedText, bEncrypted) { if (!bSignAndSend) { this.stopAutosaveTimer(); this.executeSave(true); } this.plainText(true); this.textBody(oSignedEncryptedText); this.pgpSecured(true); this.pgpEncrypted(bEncrypted); if (bSignAndSend) { this.executeSend(true); } }, this), fCancelCallback = _.bind(function () { if (bSignAndSend) { this.executeSend(true); } }, this) ; /*global COpenPgpEncryptPopup:true */ App.Screens.showPopup(COpenPgpEncryptPopup, [sText, AppData.Accounts.getEmail(), this.recipientEmails(), bSignAndSend, fOkCallback, fCancelCallback]); /*global COpenPgpEncryptPopup:true */ }; CComposeViewModel.prototype.undoPgp = function () { var sText = this.textBody(), aText = [] ; if (this.pgpSecured()) { this.plainText(false); if (this.fromDrafts() && !this.pgpEncrypted()) { aText = sText.split('-----BEGIN PGP SIGNED MESSAGE-----'); if (aText.length === 2) { sText = aText[1]; } aText = sText.split('-----BEGIN PGP SIGNATURE-----'); if (aText.length === 2) { sText = aText[0]; } aText = sText.split('\r\n\r\n'); if (aText.length > 0) { aText.shift(); sText = aText.join('\r\n\r\n'); } sText = '<div>' + sText.replace(/\r\n/gi, '<br />') + '</div>'; this.textBody(sText); } else { this.oHtmlEditor.undoAndClearRedo(); } this.pgpSecured(false); this.pgpEncrypted(false); } }; CComposeViewModel.prototype.getSocialAccounts = function () { this.googleConnected(false); this.dropboxConnected(false); _.each(AppData.User.SocialAccounts(), function (oItem){ if (oItem['@Object'] === 'Object/CSocial') { if (oItem.Type === Enums.SocialType.Google) { this.googleConnected(true); } else if (oItem.Type === Enums.SocialType.Dropbox) { this.dropboxConnected(true); } } }, this); }; /** * @param {CContactsViewModel} oParent * @constructor */ function CContactsImportViewModel(oParent) { this.oJua = null; this.oParent = oParent; this.visibility = ko.observable(false); this.importing = ko.observable(false); } CContactsImportViewModel.prototype.onFileImportStart = function () { this.importing(true); }; /** * @param {string} sUid * @param {boolean} bResult * @param {Object} oData */ CContactsImportViewModel.prototype.onFileImportComplete = function (sUid, bResult, oData) { this.importing(false); this.oParent.requestContactList(); if (bResult && oData && oData.Result) { var iImportedCount = Utils.pInt(oData.Result.ImportedCount); if (0 < iImportedCount) { App.Api.showReport(Utils.i18n('CONTACTS/CONTACT_IMPORT_HINT_PLURAL', { 'NUM': iImportedCount }, null, iImportedCount)); } else { App.Api.showError(Utils.i18n('WARNING/CONTACTS_IMPORT_NO_CONTACTS')); } } else { App.Api.showError(Utils.i18n('WARNING/CONTACTS_IMPORT_ERROR')); } }; /** * @param {Object} $oViewModel */ CContactsImportViewModel.prototype.onApplyBindings = function ($oViewModel) { this.oJua = new Jua({ 'action': '?/Upload/Contacts/', 'name': 'jua-uploader', 'queueSize': 1, 'clickElement': $('#jue_import_button', $oViewModel), 'disableAjaxUpload': false, 'disableDragAndDrop': true, 'disableMultiple': true, 'hidden': { 'Token': function () { return AppData.Token; }, 'AccountID': function () { return AppData.Accounts.currentId(); } } }); this.oJua .on('onStart', _.bind(this.onFileImportStart, this)) .on('onComplete', _.bind(this.onFileImportComplete, this)) ; }; /** * @constructor */ function CContactsViewModel() { this.importingHelpLink = App.getHelpLink('ImportingContacts'); this.allowWebMail = AppData.App.AllowWebMail; this.loadingList = ko.observable(false); this.loadingViewPane = ko.observable(false); this.showPersonalContacts = ko.observable(false); this.showGlobalContacts = ko.observable(false); this.showSharedToAllContacts = ko.observable(false); this.showAllContacts = ko.computed(function () { return 1 < [this.showPersonalContacts() ? '1' : '', this.showGlobalContacts() ? '1' : '', this.showSharedToAllContacts() ? '1' : '' ].join('').length; }, this); this.recivedAnimShare = ko.observable(false).extend({'autoResetToFalse': 500}); this.recivedAnimUnshare = ko.observable(false).extend({'autoResetToFalse': 500}); this.selectedGroupType = ko.observable(Enums.ContactsGroupListType.Personal); this.selectedGroupInList = ko.observable(null); this.selectedGroupInList.subscribe(function () { var oPrev = this.selectedGroupInList(); if (oPrev) { oPrev.selected(false); } }, this, 'beforeChange'); this.selectedGroupInList.subscribe(function (oGroup) { if (oGroup && this.showPersonalContacts()) { oGroup.selected(true); this.selectedGroupType(Enums.ContactsGroupListType.SubGroup); this.requestContactList(); } }, this); this.selectedGroup = ko.observable(null); this.selectedContact = ko.observable(null); this.selectedGroupContactsList = ko.observable(null); this.currentGroupId = ko.observable(''); this.oContactModel = new CContactModel(); this.oGroupModel = new CGroupModel(); this.oContactImportViewModel = new CContactsImportViewModel(this); this.selectedOldItem = ko.observable(null); this.selectedItem = ko.computed({ 'read': function () { return this.selectedContact() || this.selectedGroup() || null; }, 'write': function (oItem) { if (oItem instanceof CContactModel) { this.oContactImportViewModel.visibility(false); this.selectedGroup(null); this.selectedContact(oItem); } else if (oItem instanceof CGroupModel) { this.oContactImportViewModel.visibility(false); this.selectedContact(null); this.selectedGroup(oItem); this.currentGroupId(oItem.idGroup()); } else { this.selectedGroup(null); this.selectedContact(null); } this.loadingViewPane(false); }, 'owner': this }); this.sortOrder = ko.observable(true); this.sortType = ko.observable(Enums.ContactSortType.Name); this.collection = ko.observableArray([]); this.contactUidForRequest = ko.observable(''); this.collection.subscribe(function () { if (this.collection().length > 0 && this.contactUidForRequest() !== '') { this.requestContact(this.contactUidForRequest()); this.contactUidForRequest(''); } }, this); this.isSearchFocused = ko.observable(false); this.searchInput = ko.observable(''); this.search = ko.observable(''); this.groupFullCollection = ko.observableArray([]); this.selectedContact.subscribe(function (oContact) { if (oContact) { var aGroupsId = oContact.groups(); _.each(this.groupFullCollection(), function (oItem) { oItem.checked(oItem && 0 <= Utils.inArray(oItem.Id(), aGroupsId)); }); } }, this); this.selectedGroupType.subscribe(function (iValue) { if (Enums.ContactsGroupListType.All === iValue && !this.showAllContacts()) { this.selectedGroupType(Enums.ContactsGroupListType.Personal); } else if (Enums.ContactsGroupListType.Personal === iValue && !this.showPersonalContacts() && this.showGlobalContacts()) { this.selectedGroupType(Enums.ContactsGroupListType.Global); } else if (Enums.ContactsGroupListType.Global === iValue && !this.showGlobalContacts() && this.showPersonalContacts()) { this.selectedGroupType(Enums.ContactsGroupListType.Personal); } else if (Enums.ContactsGroupListType.Personal === iValue || Enums.ContactsGroupListType.Global === iValue || Enums.ContactsGroupListType.SharedToAll === iValue || Enums.ContactsGroupListType.All === iValue) { this.selectedGroupInList(null); this.selectedItem(null); this.selector.listCheckedOrSelected(false); this.requestContactList(); } }, this); this.pageSwitcherLocked = ko.observable(false); this.oPageSwitcher = new CPageSwitcherViewModel(0, AppData.User.ContactsPerPage); this.oPageSwitcher.currentPage.subscribe(function () { var iType = this.selectedGroupType(), sGroupId = (iType === Enums.ContactsGroupListType.SubGroup) ? this.currentGroupId() : '' ; if (!this.pageSwitcherLocked()) { App.Routing.setHash(App.Links.contacts(iType, sGroupId, this.search(), this.oPageSwitcher.currentPage())); } }, this); this.currentPage = ko.observable(1); this.search.subscribe(function (sValue) { this.searchInput(sValue); }, this); this.searchSubmitCommand = Utils.createCommand(this, function () { var iType = this.selectedGroupType(), sGroupId = (iType === Enums.ContactsGroupListType.SubGroup) ? this.currentGroupId() : '' ; App.Routing.setHash(App.Links.contacts(iType, sGroupId, this.searchInput())); }); this.selector = new CSelector(this.collection, _.bind(function (oItem) { if (oItem) { var iType = this.selectedGroupType(), sGroupId = (iType === Enums.ContactsGroupListType.SubGroup) ? this.currentGroupId() : '' ; App.Routing.setHash(App.Links.contacts(iType, sGroupId, this.search(), this.oPageSwitcher.currentPage(), oItem.sId)); } }, this), _.bind(this.executeDelete, this), _.bind(this.onContactDblClick, this)); this.checkAll = this.selector.koCheckAll(); this.checkAllIncomplite = this.selector.koCheckAllIncomplete(); this.allowContactsSharing = !!AppData.App.AllowContactsSharing; this.isCheckedOrSelected = ko.computed(function () { return 0 < this.selector.listCheckedOrSelected().length; }, this); this.isEnableAddContacts = this.isCheckedOrSelected; this.isEnableRemoveContactsFromGroup = this.isCheckedOrSelected; this.isEnableDeleting = this.isCheckedOrSelected; this.isEnableSharing = this.isCheckedOrSelected; this.visibleShareCommand = ko.computed(function () { return this.showPersonalContacts() && this.showSharedToAllContacts() && (this.selectedGroupType() === Enums.ContactsGroupListType.Personal); }, this); this.visibleUnshareCommand = ko.computed(function () { return this.showPersonalContacts() && this.showSharedToAllContacts() && (this.selectedGroupType() === Enums.ContactsGroupListType.SharedToAll); }, this); this.isSelectedGroupTypeNotGlobal = ko.computed(function () { return this.selectedGroupType() !== Enums.ContactsGroupListType.Global; }, this); /*this.canBeSave = ko.computed(function () { var oItem = this.selectedItem(); return oItem ? oItem.canBeSave() : false; }, this);*/ this.newContactCommand = Utils.createCommand(this, this.executeNewContact, this.isSelectedGroupTypeNotGlobal); this.newGroupCommand = Utils.createCommand(this, this.executeNewGroup); this.addContactsCommand = Utils.createCommand(this, Utils.emptyFunction, this.isEnableAddContacts); this.deleteCommand = Utils.createCommand(this, this.executeDelete, this.isEnableDeleting); this.shareCommand = Utils.createCommand(this, this.executeShare, this.isEnableSharing); this.removeFromGroupCommand = Utils.createCommand(this, this.executeRemoveFromGroup, this.isEnableRemoveContactsFromGroup); this.importCommand = Utils.createCommand(this, this.executeImport); this.exportCSVCommand = Utils.createCommand(this, this.executeCSVExport); this.exportVCFCommand = Utils.createCommand(this, this.executeVCFExport); this.saveCommand = Utils.createCommand(this, this.executeSave); this.updateSharedToAllCommand = Utils.createCommand(this, this.executeUpdateSharedToAll, function () { return (1 === this.selector.listCheckedOrSelected().length); }); this.newMessageCommand = Utils.createCommand(this, function () { var aList = this.selector.listCheckedOrSelected(), aText = [] ; if (_.isArray(aList) && 0 < aList.length) { aText = _.map(aList, function (oItem) { return oItem.EmailAndName(); }); aText = _.compact(aText); App.Api.openComposeMessage(aText.join(', ')); } }, function () { return 0 < this.selector.listCheckedOrSelected().length; }); this.selector.listCheckedOrSelected.subscribe(function (aList) { this.oGroupModel.newContactsInGroupCount(aList.length); }, this); this.isLoading = this.loadingList; this.isSearch = ko.computed(function () { return this.search() !== ''; }, this); this.isEmptyList = ko.computed(function () { return 0 === this.collection().length; }, this); this.inGroup = ko.computed(function () { return Enums.ContactsGroupListType.SubGroup === this.selectedGroupType(); }, this); this.searchText = ko.computed(function () { return Utils.i18n('CONTACTS/INFO_SEARCH_RESULT', { 'SEARCH': this.search() }); }, this); this.mobileApp = bMobileApp; this.selectedPanel = ko.observable(Enums.MobilePanel.Items); this.selectedItem.subscribe(function () { var bViewGroup = this.selectedItem() && this.selectedItem() instanceof CGroupModel && !this.selectedItem().isNew(); if (this.selectedItem() && !bViewGroup) { this.gotoViewPane(); } else { this.gotoContactList(); } }, this); } /** * * @param {?} mValue * @param {Object} oElement */ CContactsViewModel.prototype.groupDropdownToggle = function (mValue, oElement) { this.currentGroupDropdown(mValue); }; CContactsViewModel.prototype.gotoGroupList = function () { this.changeSelectedPanel(Enums.MobilePanel.Groups); }; CContactsViewModel.prototype.gotoContactList = function () { this.changeSelectedPanel(Enums.MobilePanel.Items); return true; }; CContactsViewModel.prototype.gotoViewPane = function () { this.changeSelectedPanel(Enums.MobilePanel.View); }; CContactsViewModel.prototype.backToContactList = function () { var iType = this.selectedGroupType(), sGroupId = (iType === Enums.ContactsGroupListType.SubGroup) ? this.currentGroupId() : '' ; App.Routing.setHash(App.Links.contacts(iType, sGroupId, this.search(), this.oPageSwitcher.currentPage())); }; /** * @param {number} iPanel */ CContactsViewModel.prototype.changeSelectedPanel = function (iPanel) { if (this.mobileApp) { this.selectedPanel(iPanel); } }; /** * @param {Object} oData */ CContactsViewModel.prototype.executeSave = function (oData) { var oResult = {}, aList = [] ; if (oData === this.selectedItem() && this.selectedItem().canBeSave()) { if (oData instanceof CContactModel && !oData.readOnly()) { _.each(this.groupFullCollection(), function (oItem) { if (oItem && oItem.checked()) { aList.push(oItem.Id()); } }); oData.groups(aList); oResult = oData.toObject(); oResult.Action = oData.isNew() ? 'ContactCreate' : 'ContactUpdate'; if (oData.isNew()) { oResult.SharedToAll = (Enums.ContactsGroupListType.SharedToAll === this.selectedGroupType()) ? '1' : '0'; } else { oResult.SharedToAll = oData.sharedToAll() ? '1' : '0'; } if (oData.edited()) { oData.edited(false); } if (oData.isNew()) { this.selectedItem(null); } if (this.selectedGroupType() === Enums.ContactsGroupListType.Global || this.selectedGroupType() === Enums.ContactsGroupListType.All) { this.recivedAnimUnshare(true); } App.Ajax.send(oResult, this.onContactCreateResponse, this); } else if (oData instanceof CGroupModel && !oData.readOnly()) { oResult = oData.toObject(); oResult.Action = oData.isNew() ? 'GroupCreate' : 'GroupUpdate'; this.gotoGroupList(); if (oData.edited()) { oData.edited(false); } if (oData.isNew() && !this.mobileApp) { this.selectedItem(null); } App.Ajax.send(oResult, this.onGroupCreateResponse, this); } } else { App.Api.showError(Utils.i18n('CONTACTS/ERROR_EMPTY_CONTACT')); } }; CContactsViewModel.prototype.executeNewContact = function () { if (this.showPersonalContacts()) { var oGr = this.selectedGroupInList(); this.oContactModel.switchToNew(); this.oContactModel.groups(oGr ? [oGr.Id()] : []); this.selectedItem(this.oContactModel); this.selector.itemSelected(null); this.gotoViewPane(); } }; CContactsViewModel.prototype.executeNewGroup = function () { this.oGroupModel.switchToNew(); this.selectedItem(this.oGroupModel); this.selector.itemSelected(null); this.gotoViewPane(); }; CContactsViewModel.prototype.executeDelete = function () { var aChecked = _.filter(this.selector.listCheckedOrSelected(), function (oItem) { return !oItem.ReadOnly(); }), iCount = aChecked.length, sConfirmText = Utils.i18n('CONTACTS/CONFIRM_DELETE_CONTACT_PLURAL', {}, null, iCount), fDeleteContacts = _.bind(function (bResult) { if (bResult) { this.deleteContacts(aChecked); } }, this) ; App.Screens.showPopup(ConfirmPopup, [sConfirmText, fDeleteContacts]); }; CContactsViewModel.prototype.deleteContacts = function (aChecked) { var self = this, oMainContact = this.selectedContact(), aContactsId = _.map(aChecked, function (oItem) { return oItem.Id(); }) ; if (0 < aContactsId.length) { _.each(aChecked, function (oContact) { if (oContact) { App.ContactsCache.clearInfoAboutEmail(oContact.Email()); if (oMainContact && !oContact.IsGroup() && !oContact.ReadOnly() && !oMainContact.readOnly() && oMainContact.idContact() === oContact.Id()) { oMainContact = null; this.selectedContact(null); } } }, this); _.each(this.collection(), function (oContact) { if (-1 < Utils.inArray(oContact, aChecked)) { oContact.deleted(true); } }); _.delay(function () { self.collection.remove(function (oItem) { return oItem.deleted(); }); }, 500); App.Ajax.send({ 'Action': 'ContactDelete', 'ContactsId': aContactsId.join(','), 'SharedToAll': (Enums.ContactsGroupListType.SharedToAll === this.selectedGroupType()) ? '1' : '0' }, this.requestContactList, this); App.ContactsCache.markVcardsNonexistentByUid(aContactsId); } }; CContactsViewModel.prototype.executeRemoveFromGroup = function () { var self = this, oGroup = this.selectedGroupInList(), aChecked = this.selector.listCheckedOrSelected(), aContactsId = _.map(aChecked, function (oItem) { return oItem.ReadOnly() ? '' : oItem.Id(); }) ; aContactsId = _.compact(aContactsId); if (oGroup && 0 < aContactsId.length) { _.each(this.collection(), function (oContact) { if (-1 < Utils.inArray(oContact, aChecked)) { oContact.deleted(true); } }); _.delay(function () { self.collection.remove(function (oItem) { return oItem.deleted(); }); }, 500); App.Ajax.send({ 'Action': 'RemoveContactsFromGroup', 'GroupId': oGroup.Id(), 'ContactsId': aContactsId.join(',') }, this.requestContactList, this); } }; CContactsViewModel.prototype.executeImport = function () { this.selectedItem(null); this.oContactImportViewModel.visibility(true); this.selector.itemSelected(null); this.selectedGroupType(Enums.ContactsGroupListType.Personal); this.gotoViewPane(); }; CContactsViewModel.prototype.executeCSVExport = function () { App.Api.downloadByUrl(Utils.getExportContactsLink('csv')); }; CContactsViewModel.prototype.executeVCFExport = function () { App.Api.downloadByUrl(Utils.getExportContactsLink('vcf')); }; CContactsViewModel.prototype.executeCancel = function () { var oData = this.selectedItem() ; if (oData) { if (oData instanceof CContactModel && !oData.readOnly()) { if (oData.isNew()) { this.selectedItem(null); } else if (oData.edited()) { oData.edited(false); } } else if (oData instanceof CGroupModel && !oData.readOnly()) { if (oData.isNew()) { this.selectedItem(null); } else if (oData.edited()) { this.selectedItem(this.selectedOldItem()); oData.edited(false); } this.gotoGroupList(); } } this.oContactImportViewModel.visibility(false); }; /** * @param {Object} oGroup * @param {Array} aContactIds */ CContactsViewModel.prototype.executeAddContactsToGroup = function (oGroup, aContactIds) { if (oGroup && _.isArray(aContactIds) && 0 < aContactIds.length) { oGroup.recivedAnim(true); App.Ajax.send({ 'Action': 'AddContactsToGroup', 'GroupId': oGroup.Id(), 'ContactsId': aContactIds }, this.onAddContactsToGroupResponse, this); } }; /** * @param {number} iGroupId * @param {Array} aContactIds * @param {boolean} bGlobal */ CContactsViewModel.prototype.executeAddContactsToGroupId = function (iGroupId, aContactIds) { if (iGroupId && _.isArray(aContactIds) && 0 < aContactIds.length) { App.Ajax.send({ 'Action': 'AddContactsToGroup', 'GroupId': iGroupId, 'ContactsId': aContactIds }, this.onAddContactsToGroupResponse, this); } }; CContactsViewModel.prototype.onAddContactsToGroupResponse = function () { this.requestContactList(); if (this.selector.itemSelected()) { this.requestContact(this.selector.itemSelected().sId); } }; /** * @param {Object} oGroup */ CContactsViewModel.prototype.executeAddSelectedContactsToGroup = function (oGroup) { var aList = this.selector.listCheckedOrSelected(), aContactIds = [] ; if (oGroup && _.isArray(aList) && 0 < aList.length) { _.each(aList, function (oItem) { if (oItem && !oItem.IsGroup()) { aContactIds.push([oItem.Id(), oItem.Global() ? '1' : '0']); } }, this); } this.executeAddContactsToGroup(oGroup, aContactIds); }; /** * @param {Object} oContact */ CContactsViewModel.prototype.groupsInContactView = function (oContact) { var aResult = [], aGroupIds = [] ; if (oContact && !oContact.groupsIsEmpty()) { aGroupIds = oContact.groups(); aResult = _.filter(this.groupFullCollection(), function (oItem) { return 0 <= Utils.inArray(oItem.Id(), aGroupIds); }); } return aResult; }; CContactsViewModel.prototype.onShow = function () { this.selector.useKeyboardKeys(true); this.oPageSwitcher.show(); this.oPageSwitcher.perPage(AppData.User.ContactsPerPage); }; CContactsViewModel.prototype.onHide = function () { this.selector.listCheckedOrSelected(false); this.selector.useKeyboardKeys(false); this.selectedItem(null); this.oPageSwitcher.hide(); }; CContactsViewModel.prototype.onApplyBindings = function () { this.selector.initOnApplyBindings( '.contact_sub_list .item', '.contact_sub_list .selected.item', '.contact_sub_list .item .custom_checkbox', $('.contact_list', this.$viewModel), $('.contact_list_scroll.scroll-inner', this.$viewModel) ); var self = this; this.$viewModel.on('click', '.content .item.add_to .dropdown_helper .item', function () { if ($(this).hasClass('new-group')) { self.executeNewGroup(); } else { self.executeAddSelectedContactsToGroup(ko.dataFor(this)); } }); this.showPersonalContacts(!!AppData.User.ShowPersonalContacts); this.showGlobalContacts(!!AppData.User.ShowGlobalContacts); this.showSharedToAllContacts(!!AppData.App.AllowContactsSharing); this.selectedGroupType.valueHasMutated(); this.oContactImportViewModel.onApplyBindings(this.$viewModel); this.requestGroupFullList(); this.hotKeysBind(); }; CContactsViewModel.prototype.hotKeysBind = function () { var bFirstContactFlag = false; $(document).on('keydown', _.bind(function(ev) { var nKey = ev.keyCode, oFirstContact = this.collection()[0], bListIsFocused = this.isSearchFocused(), bFirstContactSelected = false, bIsContactsScreen = App.Screens.currentScreen() === Enums.Screens.Contacts ; if (bIsContactsScreen && !Utils.isTextFieldFocused() && !bListIsFocused && ev && nKey === Enums.Key.s) { ev.preventDefault(); this.searchFocus(); } else if (oFirstContact) { bFirstContactSelected = oFirstContact.selected(); if (oFirstContact && bListIsFocused && ev && nKey === Enums.Key.Down) { this.isSearchFocused(false); this.selector.itemSelected(oFirstContact); bFirstContactFlag = true; } else if (!bListIsFocused && bFirstContactFlag && bFirstContactSelected && ev && nKey === Enums.Key.Up) { this.isSearchFocused(true); this.selector.itemSelected(false); bFirstContactFlag = false; } else if (bFirstContactSelected) { bFirstContactFlag = true; } else if (!bFirstContactSelected) { bFirstContactFlag = false; } } }, this)); }; CContactsViewModel.prototype.requestContactList = function () { this.loadingList(true); App.Ajax.send({ 'Action': (Enums.ContactsGroupListType.Global === this.selectedGroupType()) ? 'GlobalContactList' : 'ContactList', 'Offset': (this.oPageSwitcher.currentPage() - 1) * AppData.User.ContactsPerPage, 'Limit': AppData.User.ContactsPerPage, 'SortField': this.sortType(), 'SortOrder': this.sortOrder() ? '1' : '0', 'Search': this.search(), 'GroupId': this.selectedGroupInList() ? this.selectedGroupInList().Id() : '', 'SharedToAll': (Enums.ContactsGroupListType.SharedToAll === this.selectedGroupType()) ? '1' : '0', 'All': (Enums.ContactsGroupListType.All === this.selectedGroupType()) ? '1' : '0' }, this.onContactListResponse, this); }; CContactsViewModel.prototype.requestGroupFullList = function () { App.Ajax.send({ 'Action': 'GroupFullList' }, this.onGroupListResponse, this); }; /** * @param {string} sUid */ CContactsViewModel.prototype.requestContact = function (sUid) { this.loadingViewPane(true); var oItem = _.find(this.collection(), function (oItm) { return oItm.sId === sUid; }); if (oItem) { this.selector.itemSelected(oItem); App.Ajax.send({ 'Action': oItem.Global() ? 'GlobalContact' : 'Contact', 'ContactId': oItem.Id(), 'SharedToAll': oItem.IsSharedToAll() ? '1' : '0' }, this.onContactResponse, this); } }; /** * @param {string} sItemId * @param {boolean} bGlobal */ CContactsViewModel.prototype.requestContactById = function (sItemId, bGlobal) { this.loadingViewPane(true); if (sItemId) { App.Ajax.send({ 'Action': bGlobal ? 'GlobalContact' : 'Contact', 'ContactId': sItemId }, this.onContactResponse, this); } }; /** * @param {Object} oData */ CContactsViewModel.prototype.editGroup = function (oData) { var oGroup = new CGroupModel(); oGroup.populate(oData); this.selectedOldItem(oGroup); oData.edited(true); }; /** * @param {number} iType */ CContactsViewModel.prototype.changeGroupType = function (iType) { App.Routing.setHash(App.Links.contacts(iType)); }; /** * @param {Object} oData */ CContactsViewModel.prototype.onViewGroupClick = function (oData) { App.Routing.setHash(App.Links.contacts(Enums.ContactsGroupListType.SubGroup, oData.Id())); }; /** * @param {Array} aParams */ CContactsViewModel.prototype.onRoute = function (aParams) { var oParams = App.Links.parseContacts(aParams), aGroupTypes = [Enums.ContactsGroupListType.Personal, Enums.ContactsGroupListType.SharedToAll, Enums.ContactsGroupListType.Global, Enums.ContactsGroupListType.All], sCurrentGroupId = (this.selectedGroupType() === Enums.ContactsGroupListType.SubGroup) ? this.currentGroupId() : '', bGroupOrSearchChanged = this.selectedGroupType() !== oParams.Type || sCurrentGroupId !== oParams.GroupId || this.search() !== oParams.Search, bGroupFound = true, bRequestContacts = false ; this.pageSwitcherLocked(true); if (bGroupOrSearchChanged) { this.oPageSwitcher.clear(); } else { this.oPageSwitcher.setPage(oParams.Page, AppData.User.ContactsPerPage); } this.pageSwitcherLocked(false); if (oParams.Page !== this.oPageSwitcher.currentPage()) { App.Routing.replaceHash(App.Links.contacts(oParams.Type, oParams.GroupId, oParams.Search, this.oPageSwitcher.currentPage())); } if (this.currentPage() !== oParams.Page) { this.currentPage(oParams.Page); bRequestContacts = true; } if (-1 !== Utils.inArray(oParams.Type, aGroupTypes)) { this.selectedGroupType(oParams.Type); } else if (sCurrentGroupId !== oParams.GroupId) { bGroupFound = this.viewGroup(oParams.GroupId); if (bGroupFound) { bRequestContacts = false; } else { App.Routing.replaceHash(App.Links.contacts()); } } if (this.search() !== oParams.Search) { this.search(oParams.Search); bRequestContacts = true; } this.contactUidForRequest(''); if (oParams.Uid) { if (this.collection().length === 0) { this.contactUidForRequest(oParams.Uid); } else { this.requestContact(oParams.Uid); } } else { this.selector.itemSelected(null); this.gotoContactList(); } if (bRequestContacts) { this.requestContactList(); } }; /** * @param {string} sGroupId */ CContactsViewModel.prototype.viewGroup = function (sGroupId) { var oGroup = _.find(this.groupFullCollection(), function (oItem) { return oItem && oItem.Id() === sGroupId; }) ; if (oGroup) { this.oGroupModel.clear(); if (oGroup.IsOrganization()) { this.requestGroup(oGroup); } else { this.oGroupModel .idGroup(oGroup.Id()) .name(oGroup.Name()) ; } this.selectedGroupInList(oGroup); this.selectedItem(this.oGroupModel); this.selector.itemSelected(null); this.selector.listCheckedOrSelected(false); App.Ajax.send({ 'Action': 'GroupEvents', 'GroupId': sGroupId }, this.onGroupEventsResponse, this); } return !!oGroup; }; /** * @param {string} sGroupId */ CContactsViewModel.prototype.deleteGroup = function (sGroupId) { if (sGroupId) { App.Ajax.send({ 'Action': 'GroupDelete', 'GroupId': sGroupId }, this.requestGroupFullList, this); this.selectedGroupType(Enums.ContactsGroupListType.Personal); this.groupFullCollection.remove(function (oItem) { return oItem && oItem.Id() === sGroupId; }); } }; /** * @param {Object} oGroup */ CContactsViewModel.prototype.mailGroup = function (oGroup) { if (oGroup) { App.Ajax.send({ 'Action': 'ContactList', 'Offset': 0, 'Limit': 99, 'SortField': Enums.ContactSortType.Email, 'SortOrder': true ? '1' : '0', 'GroupId': oGroup.idGroup() }, function (oData) { if (oData && oData['Result'] && oData['Result']['List']) { var iIndex = 0, iLen = 0, aText = [], oObject = null, aList = [], aResultList = oData['Result']['List'] ; for (iLen = aResultList.length; iIndex < iLen; iIndex++) { if (aResultList[iIndex] && 'Object/CContactListItem' === Utils.pExport(aResultList[iIndex], '@Object', '')) { oObject = new CContactListItemModel(); oObject.parse(aResultList[iIndex]); aList.push(oObject); } } aText = _.map(aList, function (oItem) { return oItem.EmailAndName(); }); aText = _.compact(aText); App.Api.openComposeMessage(aText.join(', ')); } }, this); } }; /** * @param {Object} oContact */ CContactsViewModel.prototype.dragAndDropHelper = function (oContact) { if (oContact) { oContact.checked(true); } var oSelected = this.selector.itemSelected(), oHelper = Utils.draggableMessages(), nCount = this.selector.listCheckedOrSelected().length, aUids = 0 < nCount ? _.map(this.selector.listCheckedOrSelected(), function (oItem) { return [oItem.Id(), oItem.Global() ? '1' : '0']; }) : [] ; if (oSelected && !oSelected.checked()) { oSelected.checked(true); } oHelper.data('p7-contatcs-type', this.selectedGroupType()); oHelper.data('p7-contatcs-uids', aUids); $('.count-text', oHelper).text(Utils.i18n('CONTACTS/DRAG_TEXT_PLURAL', { 'COUNT': nCount }, null, nCount)); return oHelper; }; /** * @param {Object} oToGroup * @param {Object} oEvent * @param {Object} oUi */ CContactsViewModel.prototype.contactsDrop = function (oToGroup, oEvent, oUi) { if (oToGroup) { var oHelper = oUi && oUi.helper ? oUi.helper : null, aUids = oHelper ? oHelper.data('p7-contatcs-uids') : null ; if (null !== aUids) { Utils.uiDropHelperAnim(oEvent, oUi); this.executeAddContactsToGroup(oToGroup, aUids); } } }; CContactsViewModel.prototype.contactsDropToGroupType = function (iGroupType, oEvent, oUi) { var oHelper = oUi && oUi.helper ? oUi.helper : null, iType = oHelper ? oHelper.data('p7-contatcs-type') : null, aUids = oHelper ? oHelper.data('p7-contatcs-uids') : null ; if (iGroupType !== iType) { if (null !== iType && null !== aUids) { Utils.uiDropHelperAnim(oEvent, oUi); this.executeShare(); } } }; CContactsViewModel.prototype.searchFocus = function () { if (this.selector.useKeyboardKeys() && !Utils.isTextFieldFocused()) { this.isSearchFocused(true); } }; CContactsViewModel.prototype.onContactDblClick = function () { var oContact = this.selectedContact(); if (oContact) { App.Api.openComposeMessage(oContact.email()); } }; CContactsViewModel.prototype.onClearSearchClick = function () { // initiation empty search this.searchInput(''); this.searchSubmitCommand(); }; /** * @param {type} oResult * @param {type} oRequest * @returns {undefined} */ CContactsViewModel.prototype.onContactResponse = function (oResult, oRequest) { if (oResult && oResult.Action && oResult.Result) { var oObject = new CContactModel(), oSelected = this.selector.itemSelected() ; oObject.parse(oResult.Result); if (oSelected && oSelected.Id() === oObject.idContact()) { this.selectedItem(oObject); } } }; CContactsViewModel.prototype.onContactCreateResponse = function (oResult, oRequest) { if (oResult && oResult.Action && oResult.Result) { App.Api.showReport(oResult.Action === 'ContactCreate' ? Utils.i18n('CONTACTS/REPORT_CONTACT_SUCCESSFULLY_ADDED') : Utils.i18n('CONTACTS/REPORT_CONTACT_SUCCESSFULLY_UPDATED')); this.requestContactList(); } }; CContactsViewModel.prototype.onContactListResponse = function (oResult, oRequest) { if (oResult && oResult.Action && oResult.Result) { var iIndex = 0, iLen = 0, aList = [], bGlobal = 'GlobalContactList' === oResult.Action, oSelected = this.selector.itemSelected(), oSubSelected = null, aChecked = this.selector.listChecked(), aCheckedIds = (aChecked && 0 < aChecked.length) ? _.map(aChecked, function (oItem) { return oItem.Id(); }) : [], oObject = null ; for (iLen = oResult.Result.List.length; iIndex < iLen; iIndex++) { if (oResult.Result.List[iIndex] && 'Object/CContactListItem' === Utils.pExport(oResult.Result.List[iIndex], '@Object', '')) { oObject = new CContactListItemModel(); oObject.parse(oResult.Result.List[iIndex], bGlobal); aList.push(oObject); } } if (oSelected) { oSubSelected = _.find(aList, function (oItem) { return oSelected.Id() === oItem.Id(); }); } if (aCheckedIds && 0 < aCheckedIds.length) { _.each(aList, function (oItem) { oItem.checked(-1 < Utils.inArray(oItem.Id(), aCheckedIds)); }); } this.collection(aList); this.loadingList(false); this.oPageSwitcher.setCount(Utils.pInt(oResult.Result.ContactCount)); if (oSubSelected) { this.selector.itemSelected(oSubSelected); } this.selectedGroupContactsList(oResult.Result.List); } }; CContactsViewModel.prototype.viewAllMails = function () { var aContactsList = this.selectedGroupContactsList(), sSearchRequest = 'email:' ; if (aContactsList) { _.each(aContactsList, function(oContact, iContactKey) { _.each(oContact.Emails, function(sEmail, iEmailKey) { sSearchRequest = sSearchRequest + sEmail + ','; }); }); App.MailCache.searchMessagesInInbox(sSearchRequest); } }; CContactsViewModel.prototype.onGroupListResponse = function (oResult, oRequest) { if (oResult && oResult.Action && oResult.Result) { var iIndex = 0, iLen = 0, aList = [], oSelected = _.find(this.groupFullCollection(), function (oItem) { return oItem.selected(); }), oObject = null ; this.groupFullCollection(aList); for (iLen = oResult.Result.length; iIndex < iLen; iIndex++) { if (oResult.Result[iIndex] && 'Object/CContactListItem' === Utils.pExport(oResult.Result[iIndex], '@Object', '')) { oObject = new CContactListItemModel(); oObject.parse(oResult.Result[iIndex]); if (oObject.IsGroup()) { if (oSelected && oSelected.Id() === oObject.Id()) { this.selectedGroupInList(oObject); } aList.push(oObject); } } } this.groupFullCollection(aList); } }; CContactsViewModel.prototype.onGroupCreateResponse = function (oResult, oRequest) { if (oResult && oResult.Action && oResult.Result) { var aCheckedIds = _.map(this.selector.listChecked(), function (oItem) { return [oItem.Id(), oItem.Global() ? '1' : '0']; }); this.executeAddContactsToGroupId( oResult.Result.IdGroup, aCheckedIds ); if (!this.mobileApp) { this.selectedItem(null); this.selector.itemSelected(null); } App.Api.showReport(Utils.i18n('CONTACTS/REPORT_GROUP_SUCCESSFULLY_ADDED')); this.requestContactList(); this.requestGroupFullList(); } }; CContactsViewModel.prototype.executeShare = function () { var self = this, aChecked = this.selector.listCheckedOrSelected(), oMainContact = this.selectedContact(), aContactsId = _.map(aChecked, function (oItem) { return oItem.ReadOnly() ? '' : oItem.Id(); }) ; aContactsId = _.compact(aContactsId); if (0 < aContactsId.length) { _.each(aChecked, function (oContact) { if (oContact) { App.ContactsCache.clearInfoAboutEmail(oContact.Email()); if (oMainContact && !oContact.IsGroup() && !oContact.ReadOnly() && !oMainContact.readOnly() && oMainContact.idContact() === oContact.Id()) { oMainContact = null; this.selectedContact(null); } } }, this); _.each(this.collection(), function (oContact) { if (-1 < Utils.inArray(oContact, aChecked)) { oContact.deleted(true); } }); _.delay(function () { self.collection.remove(function (oItem) { return oItem.deleted(); }); }, 500); if (Enums.ContactsGroupListType.SharedToAll === this.selectedGroupType()) { this.recivedAnimUnshare(true); } else { this.recivedAnimShare(true); } App.Ajax.send({ 'Action': 'ContactUpdateSharedToAll', 'ContactsId': aContactsId.join(','), 'SharedToAll': (Enums.ContactsGroupListType.SharedToAll === this.selectedGroupType()) ? '1' : '0' }, this.onContactUpdateSharedToAllResponse, this); } }; CContactsViewModel.prototype.onContactUpdateSharedToAllResponse = function (oResult, oRequest) { // TODO: }; /** * @param {Object} oItem */ CContactsViewModel.prototype.requestGroup = function (oItem) { this.loadingViewPane(true); if (oItem) { App.Ajax.send({ 'Action': 'Group', 'GroupId': oItem.Id() }, this.onGroupResponse, this); } }; CContactsViewModel.prototype.onGroupResponse = function (oResult, oRequest) { if (oResult && oResult.Action && oResult.Result) { var oGroup = oResult.Result; this.oGroupModel .idGroup(oGroup.IdGroup) .name(oGroup.Name) .isOrganization(oGroup.IsOrganization) .company(oGroup.Company) .country(oGroup.Country) .state(oGroup.State) .city(oGroup.City) .street(oGroup.Street) .zip(oGroup.Zip) .phone(oGroup.Phone) .fax(oGroup.Fax) .email(oGroup.Email) .web(oGroup.Web) ; } }; CContactsViewModel.prototype.onGroupEventsResponse = function (oResult, oRequest) { if (oResult && oResult.Action && oResult.Result) { var Events = oResult.Result; this.oGroupModel.events(Events); } }; CContactsViewModel.prototype.reload = function () { this.requestContactList(); }; /** * @constructor */ function CSettingsViewModel() { this.aTabs = []; if (AppData.App.AllowUsersChangeInterfaceSettings) { this.aTabs.push(new CCommonSettingsViewModel()); } if (AppData.App.AllowWebMail) { this.aTabs.push(new CEmailAccountsSettingsViewModel()); } if (AppData.App.AllowUsersChangeInterfaceSettings && AppData.User.AllowCalendar) { this.aTabs.push(new CCalendarSettingsViewModel()); } if (AppData.User.IsFilesSupported || (AppData.SocialGoogle && AppData.SocialGoogleApiKey && AppData.SocialGoogleId) || (AppData.SocialDropbox && AppData.SocialDropboxKey) ) { this.aTabs.push(new CServicesSettingsViewModel()); } if (AppData.User.MobileSyncEnable) { this.aTabs.push(new CMobileSyncSettingsViewModel()); } if (AppData.User.OutlookSyncEnable) { this.aTabs.push(new COutLookSyncSettingsViewModel()); } if (AppData.User.IsHelpdeskSupported) { this.aTabs.push(new CHelpdeskSettingsViewModel()); } if (AppData.App.AllowOpenPgp) { this.aTabs.push(new CPgpSettingsViewModel()); } if (AfterLogicApi && AfterLogicApi.getPluginsSettingsTabs) { _.each(AfterLogicApi.getPluginsSettingsTabs(), _.bind(function (ViewModelClass) { this.aTabs.push(new ViewModelClass()); }, this)); } this.tab = ko.observable(Enums.SettingsTab.Common); AppData.Accounts.currentId.subscribe(function () { App.Routing.lastSettingsHash(Enums.Screens.Settings); }, this); this.allowFolderListOrder = ko.computed(function () { var oAccount = AppData.Accounts.getEdited(); return oAccount ? !oAccount.extensionExists('DisableFoldersManualSort') : false; }, this); this.folderListOrderUpdateDebounce = _.debounce(_.bind(this.folderListOrderUpdate, this), 3000); this.afterSortableFolderMoveBinded = _.bind(this.afterSortableFolderMove, this); } /** * @param {Array} aParams */ CSettingsViewModel.prototype.onHide = function (aParams) { var oCurrentViewModel = null, sTab = this.tab() ; this.confirmSaving(sTab); oCurrentViewModel = this.getCurrentViewModel(); if (oCurrentViewModel && Utils.isFunc(oCurrentViewModel.onHide)) { oCurrentViewModel.onHide(aParams); } $html.removeClass('non-adjustable'); }; CSettingsViewModel.prototype.onApplyBindings = function () { _.each(this.aTabs, function(oViewModel){ if (oViewModel && Utils.isFunc(oViewModel.onApplyBindings)) { oViewModel.onApplyBindings(); } }); }; /** * @param {Array} aParams */ CSettingsViewModel.prototype.onShow = function (aParams) { var oCurrentViewModel = this.getCurrentViewModel(); if (oCurrentViewModel && Utils.isFunc(oCurrentViewModel.onShow)) { oCurrentViewModel.onShow(aParams); } $html.addClass('non-adjustable'); }; /** * @param {string} sTab */ CSettingsViewModel.prototype.viewTab = function (sTab) { var oCommonTabModel = this.getViewModel(Enums.SettingsTab.Common), sDefaultTab = (!!oCommonTabModel) ? Enums.SettingsTab.Common : Enums.SettingsTab.EmailAccounts, oNewTab = this.getViewModel(sTab), bExistingTab = (-1 === Utils.inArray(sTab, Enums.SettingsTab)) ; sTab = (oNewTab && bExistingTab) ? sTab : sDefaultTab; this.tab(sTab); }; /** * @param {Array} aParams */ CSettingsViewModel.prototype.onRoute = function (aParams) { var oCurrentViewModel = null, sTab = this.tab() ; if (_.isArray(aParams) && aParams.length > 0) { sTab = aParams[0]; } else { sTab = Enums.SettingsTab.Common; } if (this.tab() !== sTab) { oCurrentViewModel = this.getCurrentViewModel(); if (oCurrentViewModel && Utils.isFunc(oCurrentViewModel.onHide)) { oCurrentViewModel.onHide(aParams); } this.confirmSaving(this.tab()); } this.viewTab(sTab); oCurrentViewModel = this.getCurrentViewModel(); if (oCurrentViewModel && Utils.isFunc(oCurrentViewModel.onRoute)) { oCurrentViewModel.onRoute(aParams); } }; /** * @param {string} sTab */ CSettingsViewModel.prototype.confirmSaving = function (sTab) { var oCurrentViewModel = this.getViewModel(sTab), sConfirm = Utils.i18n('SETTINGS/CONFIRM_SETTINGS_SAVE'), fAction = _.bind(function (bResult) { if (oCurrentViewModel) { if (bResult) { if (oCurrentViewModel.onSaveClick) { oCurrentViewModel.onSaveClick(); } } else { if (oCurrentViewModel.init) { oCurrentViewModel.init(); } } } }, this); if (oCurrentViewModel && Utils.isFunc(oCurrentViewModel.isChanged) && oCurrentViewModel.isChanged()) { App.Screens.showPopup(ConfirmPopup, [sConfirm, fAction]); } }; /** * @param {string} sTab * * @return {*} */ CSettingsViewModel.prototype.getViewModel = function (sTab) { return _.find(this.aTabs, function (oTabModel) { return oTabModel.TabName === sTab; }); }; /** * @return Object */ CSettingsViewModel.prototype.getCurrentViewModel = function () { return this.getViewModel(this.tab()); }; /** * @param {string} sTab */ CSettingsViewModel.prototype.showTab = function (sTab) { App.Routing.setHash([Enums.Screens.Settings, sTab]); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CSettingsViewModel.prototype.onResponseFolderChanges = function (oResponse, oRequest) { if (!oResponse.Result) { App.Api.showErrorByCode(oResponse, Utils.i18n('SETTINGS/ERROR_SETTINGS_SAVING_FAILED')); App.MailCache.getFolderList(AppData.Accounts.editedId()); } }; /** * @param {Object} oInputFolder * @param {Object} oResponse * @param {Object} oRequest */ CSettingsViewModel.prototype.onResponseFolderRename = function (oInputFolder, oResponse, oRequest) { if (!oResponse || !oResponse.Result) { App.Api.showErrorByCode(oResponse, Utils.i18n('SETTINGS/ERROR_SETTINGS_SAVING_FAILED')); App.MailCache.getFolderList(AppData.Accounts.editedId()); } else if (oResponse && oInputFolder && oResponse.Result && !Utils.isUnd(oResponse.Result.FullName)) { oInputFolder.fullName(oResponse.Result.FullName); oInputFolder.fullNameHash(oResponse.Result.FullNameHash); } }; /** * @param {Object} oFolderToDelete * @param {{remove:Function}} koCollection * @param {boolean} bOkAnswer */ CSettingsViewModel.prototype.deleteFolder = function (oFolderToDelete, koCollection, bOkAnswer) { var oParameters = { 'Action': 'FolderDelete', 'AccountID': AppData.Accounts.editedId(), 'Folder': oFolderToDelete.fullName() } ; if (bOkAnswer && koCollection && oFolderToDelete) { koCollection.remove(function (oFolder) { if (oFolderToDelete.fullName() === oFolder.fullName()) { return true; } return false; }); App.Ajax.send(oParameters, this.onResponseFolderChanges, this); } }; /** * @param {Object} oFolder */ CSettingsViewModel.prototype.onSubscribeFolderClick = function (oFolder) { var oParameters = { 'Action': 'FolderSubscribe', 'AccountID': AppData.Accounts.editedId(), 'Folder': oFolder.fullName(), 'SetAction': oFolder.subscribed() ? 0 : 1 } ; if (oFolder && oFolder.canSubscribe()) { oFolder.subscribed(!oFolder.subscribed()); App.Ajax.send(oParameters, this.onResponseFolderChanges, this); } }; /** * @param {Object} oFolder * @param {Object} oParent */ CSettingsViewModel.prototype.onDeleteFolderClick = function (oFolder, oParent) { var sWarning = Utils.i18n('SETTINGS/ACCOUNT_FOLDERS_CONFIRMATION_DELETE'), collection = this.getCollectionFromParent(oParent), fCallBack = _.bind(this.deleteFolder, this, oFolder, collection), oEmailAccountsViewModel = this.getViewModel(Enums.SettingsTab.EmailAccounts) ; if (oFolder && oFolder.canDelete()) { App.Screens.showPopup(ConfirmPopup, [sWarning, fCallBack]); } else if (oEmailAccountsViewModel) { oEmailAccountsViewModel.oAccountFolders.highlighted(true); } }; /** * @param {Object} oFolder */ CSettingsViewModel.prototype.folderEditOnEnter = function (oFolder) { if (oFolder.name() !== oFolder.nameForEdit()) { var oParameters = { 'Action': 'FolderRename', 'AccountID': AppData.Accounts.editedId(), 'PrevFolderFullNameRaw': oFolder.fullName(), 'NewFolderNameInUtf8': oFolder.nameForEdit() } ; App.Ajax.send(oParameters, _.bind(this.onResponseFolderRename, this, oFolder), this); oFolder.name(oFolder.nameForEdit()); } oFolder.edited(false); }; /** * @param {Object} oFolder */ CSettingsViewModel.prototype.folderEditOnEsc = function (oFolder) { oFolder.edited(false); }; /** * @param {Object} oParent * * @return {Function} */ CSettingsViewModel.prototype.getCollectionFromParent = function (oParent) { return (oParent.subfolders) ? oParent.subfolders : oParent.collection; }; /** * @param {Object} oFolder * @param {number} iIndex * @param {Object} oParent * * @return boolean */ CSettingsViewModel.prototype.canMoveFolderUp = function (oFolder, iIndex, oParent) { var collection = this.getCollectionFromParent(oParent), oPrevFolder = collection()[iIndex - 1], oPrevFolderFullName = '' ; if (iIndex > 0 && oPrevFolder) { oPrevFolderFullName = collection()[iIndex - 1].fullName(); } return (iIndex !== 0 && oFolder && oFolder.fullName() !== App.MailCache.editedFolderList().inboxFolderFullName() && App.MailCache.editedFolderList().inboxFolderFullName() !== oPrevFolderFullName); }; /** * @param {Object} oFolder * @param {number} iIndex * @param {Object} oParent * * @return boolean */ CSettingsViewModel.prototype.canMoveFolderDown = function (oFolder, iIndex, oParent) { var collection = this.getCollectionFromParent(oParent); return (iIndex !== collection().length - 1 && oFolder.fullName() !== App.MailCache.editedFolderList().inboxFolderFullName()); }; /** * @param {Object} oFolder * @param {number} iIndex * @param {Object} oParent */ CSettingsViewModel.prototype.moveFolderUp = function (oFolder, iIndex, oParent) { var collection = this.getCollectionFromParent(oParent); if (this.canMoveFolderUp(oFolder, iIndex, oParent) && collection) { collection.splice(iIndex, 1); collection.splice(iIndex - 1, 0, oFolder); this.folderListOrderUpdateDebounce(); } }; /** * @param {Object} oFolder * @param {number} iIndex * @param {Object} oParent */ CSettingsViewModel.prototype.moveFolderDown = function (oFolder, iIndex, oParent) { var collection = this.getCollectionFromParent(oParent); if (this.canMoveFolderDown(oFolder, iIndex, oParent) && collection) { collection.splice(iIndex, 1); collection.splice(iIndex + 1, 0, oFolder); this.folderListOrderUpdateDebounce(); } }; /** * @param {Object} oArguments */ CSettingsViewModel.prototype.afterSortableFolderMove = function (oArguments) { this.folderListOrderUpdateDebounce(); }; CSettingsViewModel.prototype.folderListOrderUpdate = function () { var aOptions = App.MailCache.editedFolderList().getOptions('', false, false, false), oParameters = { 'Action': 'FolderListOrderUpdate', 'AccountID': AppData.Accounts.editedId(), 'FolderList': _.compact(_.map(aOptions, function (oItem) { return (oItem && oItem.fullName)? oItem.fullName : null; })) } ; App.Ajax.send(oParameters, this.onResponseFolderChanges, this); }; /** * @constructor */ function CCommonSettingsViewModel() { this.allowWebMail = AppData.App.AllowWebMail; this.isRtl = Utils.isRTL(); this.aSkins = AppData.App.Themes; this.selectedSkin = ko.observable(AppData.User.DefaultTheme); this.aLanguages = AppData.App.Languages; this.selectedLanguage = ko.observable(AppData.User.DefaultLanguage); this.loading = ko.observable(false); this.rangeOfNumbers = [10, 20, 30, 50, 75, 100, 150, 200]; this.messagesPerPageValues = ko.observableArray(this.rangeOfNumbers); this.messagesPerPage = ko.observable(this.rangeOfNumbers[0]); this.setMessagesPerPage(AppData.User.MailsPerPage); this.contactsPerPageValues = ko.observableArray(this.rangeOfNumbers); this.contactsPerPage = ko.observable(this.rangeOfNumbers[0]); this.setContactsPerPage(AppData.User.ContactsPerPage); this.autocheckmailInterval = ko.observable(AppData.User.AutoCheckMailInterval); this.timeFormat = ko.observable(AppData.User.defaultTimeFormat()); this.aDateFormats = Utils.getDateFormatsForSelector(); this.dateFormat = ko.observable(AppData.User.DefaultDateFormat); this.useThreads = ko.observable(AppData.User.useThreads()); this.saveRepliedToCurrFolder = ko.observable(AppData.User.SaveRepliedToCurrFolder); this.allowChangeInputDirection = ko.observable(AppData.User.AllowChangeInputDirection); this.desktopNotifications = ko.observable(AppData.User.DesktopNotifications); this.desktopNotifications.subscribe(function (bChecked) { var self = this; if (bChecked && window.Notification.permission === 'default') { window.Notification.requestPermission(function (sPermission) { if (sPermission === 'denied') { self.desktopNotifications(false); self.desktopNotificationsIsEnable(false); } }); } }, this); this.desktopNotificationsIsEnable = ko.observable((window.Notification && window.Notification.permission !== 'denied')); this.isMailto = ko.observable(App.browser.firefox || App.browser.chrome); this.bAllowContacts = AppData.User.ShowContacts; this.bAllowCalendar = AppData.User.AllowCalendar; this.bAllowThreads = AppData.User.ThreadsEnabled; this.firstState = this.getState(); } CCommonSettingsViewModel.prototype.TemplateName = 'Settings_CommonSettingsViewModel'; CCommonSettingsViewModel.prototype.TabName = Enums.SettingsTab.Common; CCommonSettingsViewModel.prototype.TabTitle = Utils.i18n('SETTINGS/TAB_COMMON'); CCommonSettingsViewModel.prototype.onApplyBindings = function () { this.init(); this.updateFirstState(); }; /** * @param {number} iMpp */ CCommonSettingsViewModel.prototype.setMessagesPerPage = function (iMpp) { var aValues = this.rangeOfNumbers; if (-1 === _.indexOf(aValues, iMpp)) { aValues = _.sortBy(_.union(aValues, [iMpp]), function (oVal) { return oVal; }, this) ; } this.messagesPerPageValues(aValues); this.messagesPerPage(iMpp); }; /** * @param {number} iCpp */ CCommonSettingsViewModel.prototype.setContactsPerPage = function (iCpp) { var aValues = this.rangeOfNumbers; if (-1 === _.indexOf(aValues, iCpp)) { aValues = _.sortBy(_.union(aValues, [iCpp]), function (oVal) { return oVal; }, this) ; } this.contactsPerPageValues(aValues); this.contactsPerPage(iCpp); }; CCommonSettingsViewModel.prototype.init = function () { this.selectedSkin(AppData.User.DefaultTheme); this.selectedLanguage(AppData.User.DefaultLanguage); this.setMessagesPerPage(AppData.User.MailsPerPage); this.setContactsPerPage(AppData.User.ContactsPerPage); this.autocheckmailInterval(AppData.User.AutoCheckMailInterval); this.timeFormat(AppData.User.defaultTimeFormat()); this.dateFormat(AppData.User.DefaultDateFormat); this.useThreads(AppData.User.useThreads()); this.saveRepliedToCurrFolder(AppData.User.SaveRepliedToCurrFolder); this.allowChangeInputDirection(AppData.User.AllowChangeInputDirection); this.desktopNotifications(AppData.User.DesktopNotifications); }; CCommonSettingsViewModel.prototype.getState = function () { var aState = [ this.selectedSkin(), this.selectedLanguage(), this.messagesPerPage(), this.contactsPerPage(), this.autocheckmailInterval(), this.timeFormat(), this.dateFormat(), this.useThreads(), this.saveRepliedToCurrFolder(), this.allowChangeInputDirection(), this.desktopNotifications() ]; return aState.join(':'); }; CCommonSettingsViewModel.prototype.updateFirstState = function () { this.firstState = this.getState(); }; CCommonSettingsViewModel.prototype.isChanged = function () { if (this.firstState && this.getState() !== this.firstState) { return true; } else { return false; } }; /** * Parses the response from the server. If the settings are normally stored, then updates them. * Otherwise an error message. * * @param {Object} oResponse * @param {Object} oRequest */ CCommonSettingsViewModel.prototype.onResponse = function (oResponse, oRequest) { var bNeedReload = false; this.loading(false); if (oResponse.Result === false) { App.Api.showErrorByCode(oResponse, Utils.i18n('SETTINGS/ERROR_SETTINGS_SAVING_FAILED')); } else { App.CalendarCache.calendarSettingsChanged(true); bNeedReload = (oRequest.DefaultTheme !== AppData.User.DefaultTheme || oRequest.DefaultLanguage !== AppData.User.DefaultLanguage); if (bNeedReload) { window.location.reload(); } else { this.setMessagesPerPage(oRequest.MailsPerPage); this.setContactsPerPage(oRequest.ContactsPerPage); AppData.User.updateCommonSettings(oRequest.MailsPerPage, oRequest.ContactsPerPage, oRequest.AutoCheckMailInterval, oRequest.DefaultTheme, oRequest.DefaultLanguage, oRequest.DefaultDateFormat, oRequest.DefaultTimeFormat, oRequest.UseThreads, oRequest.SaveRepliedMessagesToCurrentFolder, oRequest.DesktopNotifications, oRequest.AllowChangeInputDirection); App.Api.showReport(Utils.i18n('SETTINGS/COMMON_REPORT_UPDATED_SUCCESSFULLY')); } } }; /** * Sends a request to the server to save the settings. */ CCommonSettingsViewModel.prototype.onSaveClick = function () { var oParameters = { 'Action': 'UpdateUserSettings', 'MailsPerPage': Utils.pInt(this.messagesPerPage()), 'ContactsPerPage': Utils.pInt(this.contactsPerPage()), 'AutoCheckMailInterval': Utils.pInt(this.autocheckmailInterval()), 'DefaultTheme': this.selectedSkin(), 'DefaultLanguage': this.selectedLanguage(), 'DefaultDateFormat': this.dateFormat(), 'DefaultTimeFormat': this.timeFormat(), 'UseThreads': this.useThreads() ? '1' : '0', 'SaveRepliedMessagesToCurrentFolder': this.saveRepliedToCurrFolder() ? '1' : '0', 'AllowChangeInputDirection': this.allowChangeInputDirection() ? '1' : '0', 'DesktopNotifications': this.desktopNotifications() ? '1' : '0' } ; this.loading(true); this.updateFirstState(); App.Ajax.send(oParameters, this.onResponse, this); }; CCommonSettingsViewModel.prototype.registerMailto = function () { Utils.registerMailto(); }; /** * @constructor */ function CEmailAccountsSettingsViewModel() { this.accounts = AppData.Accounts.collection; this.onlyOneAccount = ko.computed(function () { var bOnlyOneAccount = this.accounts().length === 1 && !AppData.App.AllowUsersAddNewAccounts; if (bOnlyOneAccount) { this.TabTitle = Utils.i18n('SETTINGS/TAB_EMAIL_ACCOUNT'); } return bOnlyOneAccount; }, this); this.title = ko.computed(function () { return this.onlyOneAccount() ? Utils.i18n('SETTINGS/TITLE_EMAIL_ACCOUNT') : Utils.i18n('SETTINGS/TITLE_EMAIL_ACCOUNTS'); }, this); this.currentAccountId = AppData.Accounts.currentId; this.editedAccountId = AppData.Accounts.editedId; this.defaultAccountId = AppData.Accounts.defaultId; this.defaultAccount = AppData.Accounts.getDefault(); //in future may be internal this.isAllowFetcher = !!AppData.User.AllowFetcher; this.isAllowIdentities = !!AppData.AllowIdentities; this.oAccountProperties = new CAccountPropertiesViewModel(this); this.oAccountSignature = new CAccountSignatureViewModel(this); this.oAccountFilters = new CAccountFiltersViewModel(this); this.oAccountAutoresponder = new CAccountAutoresponderViewModel(this); this.oAccountForward = new CAccountForwardViewModel(this); this.oAccountFolders = new CAccountFoldersViewModel(this); this.oFetcherIncoming = new CFetcherIncomingViewModel(this); this.oFetcherOutgoing = new CFetcherOutgoingViewModel(this); this.oFetcherSignature = new CFetcherSignatureViewModel(this); this.oIdentityProperties = new CIdentityPropertiesViewModel(this, false); this.fetcher = ko.observable(null); this.fetchers = ko.observable(null); this.firstFetcher = ko.observable(null); this.editedFetcherId = ko.observable(null); this.editedIdentityId = ko.observable(null); this.defaultAccount.fetchers.subscribe(function(oList) { if(!oList) { this.changeAccount(this.defaultAccountId()); } else { var oFetchers = this.defaultAccount.fetchers(), oFirstFetcher = oFetchers.collection()[0], nFetcherId = oFirstFetcher.id(), isFetcherTAb = this.isFetcherTab(this.tab()) ; this.fetchers(oFetchers); this.firstFetcher(oFirstFetcher); if(this.editedFetcherId() && isFetcherTAb) { this.onChangeFetcher(this.editedFetcherId()); } else if (isFetcherTAb) { this.editedFetcherId(nFetcherId); this.editedIdentityId(null); this.onChangeFetcher(nFetcherId); } } }, this); this.tab = ko.observable(Enums.AccountSettingsTab.Properties); this.allowUsersAddNewAccounts = AppData.App.AllowUsersAddNewAccounts; this.allowUsersChangeInterfaceSettings = AppData.App.AllowUsersChangeInterfaceSettings; this.allowAutoresponderExtension = ko.observable(false); this.allowForwardExtension = ko.observable(false); this.allowSieveFiltersExtension = ko.observable(false); this.changeAccount(this.editedAccountId()); } CEmailAccountsSettingsViewModel.prototype.TemplateName = 'Settings_EmailAccountsSettingsViewModel'; CEmailAccountsSettingsViewModel.prototype.TabName = Enums.SettingsTab.EmailAccounts; CEmailAccountsSettingsViewModel.prototype.TabTitle = Utils.i18n('SETTINGS/TAB_EMAIL_ACCOUNTS'); CEmailAccountsSettingsViewModel.prototype.isChanged = function () { return false; }; /** * @param {Array} aParams */ CEmailAccountsSettingsViewModel.prototype.onRoute = function (aParams) { var oAccount = AppData.Accounts.getEdited(); if (oAccount) { if (_.isArray(aParams) && aParams.length > 1) { this.changeCurrentTab(aParams[1]); } else { this.changeAccount(this.editedAccountId()); } } }; /** * @param {string} sTab * @param {Function=} fAfterConfirm */ CEmailAccountsSettingsViewModel.prototype.confirmSaving = function (sTab, fAfterConfirm) { var oCurrentViewModel = this.getViewModel(sTab), sConfirm = Utils.i18n('SETTINGS/CONFIRM_SETTINGS_SAVE'), fAction = _.bind(function (bResult) { if (oCurrentViewModel) { if (bResult) { if (Utils.isFunc(oCurrentViewModel.onSaveClick)) { oCurrentViewModel.onSaveClick(); } } else { if (Utils.isFunc(oCurrentViewModel.revert)) { oCurrentViewModel.revert(); } oCurrentViewModel.updateFirstState(); } } if (Utils.isFunc(fAfterConfirm)) { fAfterConfirm(); } }, this) ; if (oCurrentViewModel && Utils.isFunc(oCurrentViewModel.isChanged) && oCurrentViewModel.isChanged()) { App.Screens.showPopup(ConfirmPopup, [sConfirm, fAction]); } else if (Utils.isFunc(fAfterConfirm)) { fAfterConfirm(); } }; /** * @param {Array} aParams */ CEmailAccountsSettingsViewModel.prototype.onHide = function (aParams) { var oCurrentViewModel = this.getCurrentViewModel(); this.confirmSaving(this.tab()); if (oCurrentViewModel && Utils.isFunc(oCurrentViewModel.onHide)) { oCurrentViewModel.onHide(); } }; /** * @param {string} sTab */ CEmailAccountsSettingsViewModel.prototype.changeCurrentTab = function (sTab) { var oAccount = AppData.Accounts.getEdited(), oCurrentViewModel = null, bTabAllowed = this.isTabAllowed(sTab, oAccount), fChangeTabAfterConfirm = _.bind(function () { if (this.tab() !== sTab) { oCurrentViewModel = this.getCurrentViewModel(); if (oCurrentViewModel && Utils.isFunc(oCurrentViewModel.onHide)) { oCurrentViewModel.onHide(); } } this.tab(sTab); oCurrentViewModel = this.getCurrentViewModel(); if (oCurrentViewModel && Utils.isFunc(oCurrentViewModel.onShow)) { oCurrentViewModel.onShow(oAccount); } }, this) ; if (oAccount) { if (bTabAllowed) { this.confirmSaving(this.tab(), fChangeTabAfterConfirm); } else if (this.tab() === sTab) { this.tab(Enums.AccountSettingsTab.Properties); App.Routing.replaceHash([Enums.Screens.Settings, Enums.SettingsTab.EmailAccounts, Enums.AccountSettingsTab.Properties]); this.editedFetcherId(null); this.editedIdentityId(null); } else { App.Routing.replaceHash([Enums.Screens.Settings, Enums.SettingsTab.EmailAccounts, this.tab()]); } } }; /** * @param {string} sTab * @returns {Object} */ CEmailAccountsSettingsViewModel.prototype.allowedChangeTabAfterConfirm = function (sTab) { }; /** * @param {string} sTab * @returns {Object} */ CEmailAccountsSettingsViewModel.prototype.getViewModel = function (sTab) { switch (sTab) { case Enums.AccountSettingsTab.Folders: return this.oAccountFolders; case Enums.AccountSettingsTab.Filters: return this.oAccountFilters; case Enums.AccountSettingsTab.Forward: return this.oAccountForward; case Enums.AccountSettingsTab.Signature: return this.oAccountSignature; case Enums.AccountSettingsTab.Autoresponder: return this.oAccountAutoresponder; case Enums.AccountSettingsTab.FetcherInc: return this.oFetcherIncoming; case Enums.AccountSettingsTab.FetcherOut: return this.oFetcherOutgoing; case Enums.AccountSettingsTab.FetcherSig: return this.oFetcherSignature; case Enums.AccountSettingsTab.IdentityProperties: return this.oIdentityProperties; case Enums.AccountSettingsTab.IdentitySignature: return this.oIdentityProperties; default: case Enums.AccountSettingsTab.Properties: return this.oAccountProperties; } }; CEmailAccountsSettingsViewModel.prototype.getCurrentViewModel = function () { return this.getViewModel(this.tab()); }; /** * @param {string} sTab * @param {Object} oAccount * @returns {Boolean} */ CEmailAccountsSettingsViewModel.prototype.isTabAllowed = function (sTab, oAccount) { var aAllowedTabs = [ Enums.AccountSettingsTab.Properties, Enums.AccountSettingsTab.Signature, Enums.AccountSettingsTab.Folders, Enums.AccountSettingsTab.FetcherInc, Enums.AccountSettingsTab.FetcherOut, Enums.AccountSettingsTab.FetcherSig ] ; if (oAccount.extensionExists('AllowSieveFiltersExtension')) { aAllowedTabs.push(Enums.AccountSettingsTab.Filters); } if (oAccount.extensionExists('AllowForwardExtension')) { aAllowedTabs.push(Enums.AccountSettingsTab.Forward); } if (oAccount.extensionExists('AllowAutoresponderExtension')) { aAllowedTabs.push(Enums.AccountSettingsTab.Autoresponder); } if (AppData.AllowIdentities && this.editedIdentityId()) { aAllowedTabs.push(Enums.AccountSettingsTab.IdentityProperties); aAllowedTabs.push(Enums.AccountSettingsTab.IdentitySignature); } return -1 !== Utils.inArray(sTab, aAllowedTabs); }; /** * @param {string} sTab */ CEmailAccountsSettingsViewModel.prototype.onTabClick = function (sTab) { App.Routing.setHash([Enums.Screens.Settings, Enums.SettingsTab.EmailAccounts, sTab]); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CEmailAccountsSettingsViewModel.prototype.onResponseAccountDelete = function (oResponse, oRequest) { if (!oResponse.Result) { App.Api.showErrorByCode(oResponse, Utils.i18n('SETTINGS/ERROR_SETTINGS_SAVING_FAILED')); } else { AppData.Accounts.deleteAccount(oRequest.AccountIDToDelete); this.changeAccount(this.editedAccountId()); if (this.defaultAccountId() === oRequest.AccountIDToDelete) { // App.logout(); App.Routing.setHash([]); window.location.reload(); } } }; /** * @param {number} iAccountId * @param {boolean} bOkAnswer */ CEmailAccountsSettingsViewModel.prototype.deleteAccount = function (iAccountId, bOkAnswer) { var oParameters = { 'Action': 'AccountDelete', 'AccountIDToDelete': iAccountId } ; if (bOkAnswer) { App.Ajax.send(oParameters, this.onResponseAccountDelete, this); } }; /** * @param {number} iAccountId */ CEmailAccountsSettingsViewModel.prototype.onAccountDelete = function (iAccountId) { var fCallBack = _.bind(this.deleteAccount, this, iAccountId), oAccount = AppData.Accounts.getAccount(iAccountId) ; if (this.allowUsersChangeInterfaceSettings) { App.Screens.showPopup(ConfirmPopup, [oAccount.removeConfirmation(), fCallBack, oAccount.email()]); } }; CEmailAccountsSettingsViewModel.prototype.onEditedAccountDelete = function () { this.onAccountDelete(this.editedAccountId()); }; CEmailAccountsSettingsViewModel.prototype.onAccountAdd = function () { App.Screens.showPopup(AccountCreatePopup, []); }; /** * @param {number} iAccountId */ CEmailAccountsSettingsViewModel.prototype.changeAccount = function (iAccountId) { var oAccount = null, oParameters = { 'Action': 'AccountSettings', 'AccountID': iAccountId } ; if (this.isFetcherTab(this.tab()) || this.isIdentityTab(this.tab())) { this.onTabClick(Enums.AccountSettingsTab.Properties); } this.confirmSaving(this.tab()); oAccount = AppData.Accounts.getAccount(iAccountId); if (!Utils.isUnd(oAccount) && oAccount.isExtended()) { this.populate(oAccount); } else { App.Ajax.send(oParameters, this.onAccountSettingsResponse, this); } this.editedFetcherId(null); this.editedIdentityId(null); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CEmailAccountsSettingsViewModel.prototype.onAccountSettingsResponse = function (oResponse, oRequest) { if (!oResponse.Result) { App.Api.showErrorByCode(oResponse, Utils.i18n('SETTINGS/ERROR_SETTINGS_SAVING_FAILED')); } else { var oAccount = AppData.Accounts.getAccount(oRequest.AccountID); if (!Utils.isUnd(oAccount)) { oAccount.updateExtended(oResponse.Result); this.populate(oAccount); } } }; /** * @param {Object} oAccount */ CEmailAccountsSettingsViewModel.prototype.populate = function (oAccount) { this.allowAutoresponderExtension(oAccount.extensionExists('AllowAutoresponderExtension')); this.allowForwardExtension(oAccount.extensionExists('AllowForwardExtension')); this.allowSieveFiltersExtension(oAccount.extensionExists('AllowSieveFiltersExtension')); AppData.Accounts.changeEditedAccount(oAccount.id()); this.changeCurrentTab(this.tab()); }; /** * @param {number} iId * @param {Object} oEv */ CEmailAccountsSettingsViewModel.prototype.onIdentityAdd = function (iId, oEv) { oEv.stopPropagation(); App.Screens.showPopup(CreateIdentityPopup, [iId]); }; /** * @param {Object} oModel * @param {Object} oEv */ CEmailAccountsSettingsViewModel.prototype.onFetcherAdd = function (oModel, oEv) { // oEv.stopPropagation(); App.Screens.showPopup(FetcherAddPopup, []); }; /** * @param {number} iFetcherId * @param {boolean} bOkAnswer */ CEmailAccountsSettingsViewModel.prototype.fetcherDelete = function (iFetcherId, bOkAnswer) { var oParameters = { 'Action': 'FetcherDelete', 'FetcherID': iFetcherId }; if (bOkAnswer) { App.Ajax.send(oParameters, this.onFetcherDeleteResponse, this); } }; /** * @param {Object} oData */ CEmailAccountsSettingsViewModel.prototype.onFetcherDeleteClick = function (oData) { var sWarning = Utils.i18n('WARNING/FETCHER_DELETE_WARNING'), fCallBack = _.bind(this.fetcherDelete, this, oData.idFetcher()), sTitle = oData.incomingMailServer() ; App.Screens.showPopup(ConfirmPopup, [sWarning, fCallBack, sTitle]); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CEmailAccountsSettingsViewModel.prototype.onFetcherDeleteResponse = function (oResponse, oRequest) { if (!oResponse.Result) { App.Api.showErrorByCode(oResponse.ErrorCode, Utils.i18n('WARNING/FETCHER_DELETING_ERROR')); } else { AppData.Accounts.populateFetchers(); this.editedFetcherId(null); } }; /** * @param {number} iFetcherId */ CEmailAccountsSettingsViewModel.prototype.onChangeFetcher = function (iFetcherId) { var oFetcher = this.defaultAccount.fetchers().getFetcher(iFetcherId); this.fetcher(oFetcher); if (!this.isFetcherTab(this.tab())) { this.onTabClick(Enums.AccountSettingsTab.FetcherInc); } this.confirmSaving(this.tab()); this.oFetcherIncoming.populate(oFetcher); this.oFetcherOutgoing.populate(oFetcher); this.oFetcherSignature.populate(oFetcher); this.editedFetcherId(oFetcher.id()); this.editedIdentityId(null); }; /** * @param {string} sTab */ CEmailAccountsSettingsViewModel.prototype.isFetcherTab = function (sTab) { return -1 !== Utils.inArray(sTab, [Enums.AccountSettingsTab.FetcherInc, Enums.AccountSettingsTab.FetcherOut, Enums.AccountSettingsTab.FetcherSig]); }; /** * @param {Object} oIdentity */ CEmailAccountsSettingsViewModel.prototype.onChangeIdentity = function (oIdentity) { this.onTabClick(Enums.AccountSettingsTab.IdentityProperties); this.confirmSaving(this.tab()); this.oIdentityProperties.populate(oIdentity); this.editedIdentityId(oIdentity.id()); this.editedFetcherId(null); }; /** * @param {string} sTab */ CEmailAccountsSettingsViewModel.prototype.isIdentityTab = function (sTab) { return -1 !== Utils.inArray(sTab, [Enums.AccountSettingsTab.IdentityProperties, Enums.AccountSettingsTab.IdentitySignature]); }; CEmailAccountsSettingsViewModel.prototype.onRemoveIdentity = function () { this.editedIdentityId(null); this.changeCurrentTab(this.tab()); }; /** * @constructor */ function CCalendarSettingsViewModel() { this.showWeekends = ko.observable(AppData.User.CalendarShowWeekEnds); this.loading = ko.observable(false); this.availableTimes = ko.observableArray(this.getDisplayedTimes((AppData.User.defaultTimeFormat() !== Enums.TimeFormat.F24) ? 'hh:mm A' : 'HH:mm')); AppData.User.defaultTimeFormat.subscribe(function () { this.availableTimes(this.getDisplayedTimes((AppData.User.defaultTimeFormat() !== Enums.TimeFormat.F24) ? 'hh:mm A' : 'HH:mm')); }, this); this.selectedWorkdayStarts = ko.observable(AppData.User.CalendarWorkDayStarts); this.selectedWorkdayEnds = ko.observable(AppData.User.CalendarWorkDayEnds); this.showWorkday = ko.observable(AppData.User.CalendarShowWorkDay); this.weekStartsOn = ko.observable(AppData.User.CalendarWeekStartsOn); this.defaultTab = ko.observable(AppData.User.CalendarDefaultTab); this.firstState = this.getState(); } CCalendarSettingsViewModel.prototype.TemplateName = 'Settings_CalendarSettingsViewModel'; CCalendarSettingsViewModel.prototype.TabName = Enums.SettingsTab.Calendar; CCalendarSettingsViewModel.prototype.TabTitle = Utils.i18n('SETTINGS/TAB_CALENDAR'); CCalendarSettingsViewModel.prototype.init = function() { this.showWeekends(AppData.User.CalendarShowWeekEnds); this.selectedWorkdayStarts(AppData.User.CalendarWorkDayStarts); this.selectedWorkdayEnds(AppData.User.CalendarWorkDayEnds); this.showWorkday(AppData.User.CalendarShowWorkDay); this.weekStartsOn(AppData.User.CalendarWeekStartsOn); this.defaultTab(AppData.User.CalendarDefaultTab); }; CCalendarSettingsViewModel.prototype.getState = function() { var sState = [ this.showWeekends(), this.selectedWorkdayStarts(), this.selectedWorkdayEnds(), this.showWorkday(), this.weekStartsOn(), this.defaultTab() ]; return sState.join(':'); }; CCalendarSettingsViewModel.prototype.updateFirstState = function() { this.firstState = this.getState(); }; CCalendarSettingsViewModel.prototype.isChanged = function() { if (this.firstState && this.getState() !== this.firstState) { return true; } else { return false; } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CCalendarSettingsViewModel.prototype.onResponse = function (oResponse, oRequest) { this.loading(false); if (oResponse.Result === false) { App.Api.showErrorByCode(oResponse, Utils.i18n('SETTINGS/ERROR_CALENDAR_SETTINGS_SAVING_FAILED')); } else { App.CalendarCache.calendarSettingsChanged(true); AppData.User.updateCalendarSettings(oRequest.ShowWeekEnds, oRequest.ShowWorkDay, oRequest.WorkDayStarts, oRequest.WorkDayEnds, oRequest.WeekStartsOn, oRequest.DefaultTab); App.Api.showReport(Utils.i18n('SETTINGS/COMMON_REPORT_UPDATED_SUCCESSFULLY')); } }; CCalendarSettingsViewModel.prototype.onSaveClick = function () { var oParameters = { 'Action': 'UpdateUserSettings', 'ShowWeekEnds': this.showWeekends() ? 1 : 0, 'ShowWorkDay': this.showWorkday() ? 1 : 0, 'WorkDayStarts': parseInt(this.selectedWorkdayStarts(), 10), 'WorkDayEnds': parseInt(this.selectedWorkdayEnds(), 10), 'WeekStartsOn': parseInt(this.weekStartsOn(), 10), 'DefaultTab': parseInt(this.defaultTab(), 10) } ; this.loading(true); this.updateFirstState(); App.Ajax.send(oParameters, this.onResponse, this); }; /** * @param {string} sTimeFormatMoment * @returns {Array} */ CCalendarSettingsViewModel.prototype.getDisplayedTimes = function (sTimeFormatMoment) { var aDisplayedTimes = []; switch (sTimeFormatMoment) { case 'HH:mm': aDisplayedTimes = [ {text: '01:00', value: '1'}, {text: '02:00', value: '2'}, {text: '03:00', value: '3'}, {text: '04:00', value: '4'}, {text: '05:00', value: '5'}, {text: '06:00', value: '6'}, {text: '07:00', value: '7'}, {text: '08:00', value: '8'}, {text: '09:00', value: '9'}, {text: '10:00', value: '10'}, {text: '11:00', value: '11'}, {text: '12:00', value: '12'}, {text: '13:00', value: '13'}, {text: '14:00', value: '14'}, {text: '15:00', value: '15'}, {text: '16:00', value: '16'}, {text: '17:00', value: '17'}, {text: '18:00', value: '18'}, {text: '19:00', value: '19'}, {text: '20:00', value: '20'}, {text: '21:00', value: '21'}, {text: '22:00', value: '22'}, {text: '23:00', value: '23'}, {text: '00:00', value: '24'} ]; break; case 'hh:mm A': aDisplayedTimes = [ {text: '01:00 AM', value: '1'}, {text: '02:00 AM', value: '2'}, {text: '03:00 AM', value: '3'}, {text: '04:00 AM', value: '4'}, {text: '05:00 AM', value: '5'}, {text: '06:00 AM', value: '6'}, {text: '07:00 AM', value: '7'}, {text: '08:00 AM', value: '8'}, {text: '09:00 AM', value: '9'}, {text: '10:00 AM', value: '10'}, {text: '11:00 AM', value: '11'}, {text: '12:00 PM', value: '12'}, {text: '01:00 PM', value: '13'}, {text: '02:00 PM', value: '14'}, {text: '03:00 PM', value: '15'}, {text: '04:00 PM', value: '16'}, {text: '05:00 PM', value: '17'}, {text: '06:00 PM', value: '18'}, {text: '07:00 PM', value: '19'}, {text: '08:00 PM', value: '20'}, {text: '09:00 PM', value: '21'}, {text: '10:00 PM', value: '22'}, {text: '11:00 PM', value: '23'}, {text: '12:00 AM', value: '24'} ]; break; } return aDisplayedTimes; }; /** * @constructor */ function CMobileSyncSettingsViewModel() { this.mobileSync = AppData.User.mobileSync; this.mobileSync.subscribe(this.onMobileSyncSubscribe, this); this.enableDav = ko.observable(false); this.davLogin = ko.observable(''); this.davServer = ko.observable(''); this.davCalendars = ko.observable([]); this.visibleCalendars = ko.computed(function () { return this.davCalendars().length > 0; }, this); this.davPersonalContactsUrl = ko.observable(''); this.davCollectedAddressesUrl = ko.observable(''); this.davGlobalAddressBookUrl = ko.observable(''); this.davSharedWithAllUrl = ko.observable(''); this.bVisiblePersonalContacts = AppData.User.ShowPersonalContacts; this.bVisibleGlobalContacts = AppData.User.ShowGlobalContacts; this.bVisibleSharedWithAllContacts = !!AppData.App.AllowContactsSharing; this.bVisibleContacts = AppData.User.ShowContacts; this.bVisibleCalendar = AppData.User.AllowCalendar; this.bVisibleFiles = AppData.User.IsFilesSupported; this.bVisibleIosLink = bIsIosDevice; this.visibleDavViaUrls = ko.computed(function () { return this.visibleCalendars() || this.bVisibleContacts; }, this); this.bChanged = false; this.isDemo = AppData.User.IsDemo; this.credentialsHintText = ko.observable(Utils.i18n('SETTINGS/MOBILE_CREDENTIALS_TITLE', {'EMAIL': AppData.Accounts.getDefault().email()})); } CMobileSyncSettingsViewModel.prototype.TemplateName = 'Settings_MobileSyncSettingsViewModel'; CMobileSyncSettingsViewModel.prototype.TabName = Enums.SettingsTab.MobileSync; CMobileSyncSettingsViewModel.prototype.TabTitle = Utils.i18n('SETTINGS/TAB_MOBILE_SYNC'); CMobileSyncSettingsViewModel.prototype.onRoute = function () { AppData.User.requestSyncSettings(); }; CMobileSyncSettingsViewModel.prototype.onMobileSyncSubscribe = function () { this.enableDav(AppData.User.MobileSyncEnable && this.mobileSync() && this.mobileSync()['EnableDav']); if (this.enableDav()) { this.davLogin(this.mobileSync()['Dav']['Login']); this.davServer(this.mobileSync()['Dav']['Server']); this.davCalendars(this.mobileSync()['Dav']['Calendars']); this.davPersonalContactsUrl(this.mobileSync()['Dav']['PersonalContactsUrl']); this.davCollectedAddressesUrl(this.mobileSync()['Dav']['CollectedAddressesUrl']); this.davGlobalAddressBookUrl(this.mobileSync()['Dav']['GlobalAddressBookUrl']); this.davSharedWithAllUrl(this.mobileSync()['Dav']['SharedWithAllUrl']); } }; /** * @constructor */ function COutLookSyncSettingsViewModel() { this.outlookSync = AppData.User.outlookSync; this.outlookSync.subscribe(this.onOutlookSyncSubscribe, this); this.visibleOutlookSync = ko.observable(false); this.server = ko.observable(''); this.bChanged = false; this.isDemo = AppData.User.IsDemo; this.outlookSyncPlugin32 = App.getHelpLink('OutlookSyncPlugin32'); this.outlookSyncPlugin64 = App.getHelpLink('OutlookSyncPlugin64'); this.outlookSyncPluginReadMore = App.getHelpLink('OutlookSyncPluginReadMore'); this.credentialsHintText = ko.observable(Utils.i18n('SETTINGS/OUTLOOKSYNC_CREDENTIALS_TITLE', {'EMAIL': AppData.Accounts.getDefault().email()})); } COutLookSyncSettingsViewModel.prototype.TemplateName = 'Settings_OutLookSyncSettingsViewModel'; COutLookSyncSettingsViewModel.prototype.TabName = Enums.SettingsTab.OutLookSync; COutLookSyncSettingsViewModel.prototype.TabTitle = Utils.i18n('SETTINGS/TAB_OUTLOOK_SYNC'); COutLookSyncSettingsViewModel.prototype.onRoute = function () { AppData.User.requestSyncSettings(); }; COutLookSyncSettingsViewModel.prototype.onOutlookSyncSubscribe = function () { if (AppData.User.OutlookSyncEnable) { this.visibleOutlookSync(true); if (this.outlookSync()) { this.server(this.outlookSync()['Server']); } } }; /** * @constructor */ function CPgpSettingsViewModel() { this.pgp = null; this.pgpLoaded = ko.observable(false); this.keys = ko.observableArray([]); this.publicKeys = ko.computed(function () { var aPublicKeys = _.filter(this.keys(), function (oKey) { return oKey.isPublic(); }) ; return _.map(aPublicKeys, function (oKey) { return {'user': oKey.getUser(), 'armor': oKey.getArmor(), 'key': oKey, 'private': false}; }); }, this); this.privateKeys = ko.computed(function () { var aPrivateKeys = _.filter(this.keys(), function (oKey) { return oKey.isPrivate(); }) ; return _.map(aPrivateKeys, function (oKey) { return {'user': oKey.getUser(), 'armor': oKey.getArmor(), 'key': oKey}; }); }, this); this.loading = ko.observable(false); this.enableOpenPgp = ko.observable(AppData.User.enableOpenPgp()); this.allowAutosaveInDrafts = ko.observable(AppData.User.AllowAutosaveInDrafts); this.autosignOutgoingEmails = ko.observable(AppData.User.AutosignOutgoingEmails); this.bAllowAutoSave = AppData.App.AutoSave; this.firstState = this.getState(); } CPgpSettingsViewModel.prototype.TemplateName = 'Settings_PgpSettingsViewModel'; CPgpSettingsViewModel.prototype.TabName = Enums.SettingsTab.Pgp; CPgpSettingsViewModel.prototype.TabTitle = Utils.i18n('SETTINGS/TAB_OPENPGP'); CPgpSettingsViewModel.prototype.init = function () { this.enableOpenPgp(AppData.User.enableOpenPgp()); this.allowAutosaveInDrafts(AppData.User.AllowAutosaveInDrafts); this.autosignOutgoingEmails(AppData.User.AutosignOutgoingEmails); }; CPgpSettingsViewModel.prototype.getState = function () { var aState = [ this.enableOpenPgp(), this.allowAutosaveInDrafts(), this.autosignOutgoingEmails() ]; return aState.join(':'); }; CPgpSettingsViewModel.prototype.updateFirstState = function () { this.firstState = this.getState(); }; CPgpSettingsViewModel.prototype.isChanged = function () { if (this.firstState && this.getState() !== this.firstState) { return true; } else { return false; } }; CPgpSettingsViewModel.prototype.onRoute = function () { var fPgpCallback = _.bind(function (oPgp) { if (oPgp) { this.pgp = oPgp; this.keys(this.pgp.getKeys()); this.pgp.getKeysObservable().subscribe(function () { this.keys(this.pgp.getKeys()); }, this); } this.pgpLoaded(true); }, this); App.Api.pgp(fPgpCallback, AppData.User.IdUser); }; CPgpSettingsViewModel.prototype.importKey = function () { if (this.pgp) { App.Screens.showPopup(CImportOpenPgpKeyPopup, [this.pgp]); } }; CPgpSettingsViewModel.prototype.generateNewKey = function () { if (this.pgp) { App.Screens.showPopup(CGenerateOpenPgpKeyPopup, [this.pgp]); } }; /** * @param {Object} oKey */ CPgpSettingsViewModel.prototype.removeOpenPgpKey = function (oKey) { var sConfirm = '', fRemove = _.bind(function (bRemove) { if (bRemove) { var oRes = this.pgp.deleteKey(oKey); if (!oRes.result) { App.Api.showError(Utils.i18n('OPENPGP/ERROR_DELETE_KEY')); } } }, this) ; if (this.pgp && oKey) { sConfirm = Utils.i18n('OPENPGP/CONFIRM_DELETE_KEY', {'KEYEMAIL': oKey.getEmail()}); App.Screens.showPopup(ConfirmPopup, [sConfirm, fRemove]); } }; /** * @param {Object} oKey */ CPgpSettingsViewModel.prototype.showArmor = function (oKey) { if (this.pgp) { App.Screens.showPopup(CShowOpenPgpKeyArmorPopup, [oKey]); } }; /** * Parses the response from the server. If the settings are normally stored, then updates them. * Otherwise an error message. * * @param {Object} oResponse * @param {Object} oRequest */ CPgpSettingsViewModel.prototype.onResponse = function (oResponse, oRequest) { this.loading(false); if (oResponse.Result === false) { App.Api.showErrorByCode(oResponse, Utils.i18n('SETTINGS/ERROR_SETTINGS_SAVING_FAILED')); } else { AppData.User.updateOpenPgpSettings(oRequest.EnableOpenPgp, oRequest.AllowAutosaveInDrafts, oRequest.AutosignOutgoingEmails); App.Api.showReport(Utils.i18n('SETTINGS/COMMON_REPORT_UPDATED_SUCCESSFULLY')); } }; /** * Sends a request to the server to save the settings. */ CPgpSettingsViewModel.prototype.onSaveClick = function () { var oParameters = { 'Action': 'UpdateUserSettings', 'EnableOpenPgp': this.enableOpenPgp() ? '1' : '0', 'AllowAutosaveInDrafts': this.allowAutosaveInDrafts() ? '1' : '0', 'AutosignOutgoingEmails': this.autosignOutgoingEmails() ? '1' : '0' } ; this.loading(true); this.updateFirstState(); App.Ajax.send(oParameters, this.onResponse, this); }; /** * @param {?=} oParent * * @constructor */ function CAccountPropertiesViewModel(oParent) { this.allowUsersChangeInterfaceSettings = AppData.App.AllowUsersChangeInterfaceSettings; this.allowUsersChangeEmailSettings = AppData.App.AllowUsersChangeEmailSettings; this.account = ko.observable(0); this.isInternal = ko.observable(true); this.isLinked = ko.observable(true); this.isDefault = ko.observable(false); this.removeHint = ko.observable(''); this.friendlyName = ko.observable(''); this.email = ko.observable(''); this.incomingMailLogin = ko.observable(''); this.incomingMailPassword = ko.observable(''); this.incomingMailPort = ko.observable(0); this.incomingMailServer = ko.observable(''); this.outgoingMailLogin = ko.observable(''); this.outgoingMailPassword = ko.observable(''); this.outgoingMailPort = ko.observable(0); this.outgoingMailServer = ko.observable(''); this.loading = ko.observable(false); this.allowChangePassword = ko.observable(false); this.useSmtpAuthentication = ko.observable(false); this.incLoginFocused = ko.observable(false); this.incLoginFocused.subscribe(function () { if (this.incLoginFocused() && this.incomingMailLogin() === '') { this.incomingMailLogin(this.email()); } }, this); this.outServerFocused = ko.observable(false); this.outServerFocused.subscribe(function () { if (this.outServerFocused() && this.outgoingMailServer() === '') { this.outgoingMailServer(this.incomingMailServer()); } }, this); this.firstState = null; } /** * @param {Object} oAccount */ CAccountPropertiesViewModel.prototype.onShow = function (oAccount) { this.account(oAccount); this.populate(); }; CAccountPropertiesViewModel.prototype.getState = function () { var aState = [ this.friendlyName(), this.email(), this.incomingMailLogin(), this.incomingMailPort(), this.incomingMailServer(), this.outgoingMailLogin(), this.outgoingMailPort(), this.outgoingMailServer(), this.useSmtpAuthentication() ]; return aState.join(':'); }; CAccountPropertiesViewModel.prototype.updateFirstState = function() { this.firstState = this.getState(); }; CAccountPropertiesViewModel.prototype.isChanged = function() { if (this.firstState && this.getState() !== this.firstState) { return true; } else { return false; } }; CAccountPropertiesViewModel.prototype.populate = function () { var oAccount = this.account(); if (oAccount) { this.allowChangePassword(oAccount.extensionExists('AllowChangePasswordExtension')); // this.allowChangePassword(true); this.isInternal(oAccount.isInternal()); this.isLinked(oAccount.isLinked()); this.isDefault(oAccount.isDefault()); this.removeHint(oAccount.removeHint()); this.useSmtpAuthentication(Utils.pInt(oAccount.outgoingMailAuth()) === 2 ? true : false); this.friendlyName(oAccount.friendlyName()); this.email(oAccount.email()); this.incomingMailLogin(oAccount.incomingMailLogin()); this.incomingMailServer(oAccount.incomingMailServer()); this.incomingMailPort(oAccount.incomingMailPort()); this.outgoingMailServer(oAccount.outgoingMailServer()); this.outgoingMailLogin(oAccount.outgoingMailLogin()); this.outgoingMailPort(oAccount.outgoingMailPort()); this.updateFirstState(); } else { this.allowChangePassword(false); this.isLinked(true); this.useSmtpAuthentication(true); this.friendlyName(''); this.email(''); this.incomingMailLogin(''); this.incomingMailServer(''); this.incomingMailPort(143); this.outgoingMailServer(''); this.outgoingMailLogin(''); this.outgoingMailPort(25); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CAccountPropertiesViewModel.prototype.onResponse = function (oResponse, oRequest) { this.loading(false); if (!oResponse.Result) { App.Api.showErrorByCode(oResponse, Utils.i18n('SETTINGS/ERROR_SETTINGS_SAVING_FAILED')); } else { var iAccountId = Utils.pInt(oResponse.AccountID), oAccount = 0 < iAccountId ? AppData.Accounts.getAccount(iAccountId) : null ; if (oAccount) { oAccount.updateExtended(oRequest); App.Api.showReport(Utils.i18n('SETTINGS/COMMON_REPORT_UPDATED_SUCCESSFULLY')); } } }; /** * @return Object */ CAccountPropertiesViewModel.prototype.prepareParameters = function () { var oParameters = { 'Action': 'UpdateAccountSettings', 'AccountID': this.account().id(), 'FriendlyName': this.friendlyName(), 'Email': this.email(), 'IncomingMailLogin': this.incomingMailLogin(), 'IncomingMailServer': this.incomingMailServer(), 'IncomingMailPort': Utils.pInt(this.incomingMailPort()), 'OutgoingMailServer': this.outgoingMailServer(), 'OutgoingMailLogin': this.outgoingMailLogin(), 'OutgoingMailPort': Utils.pInt(this.outgoingMailPort()), 'OutgoingMailAuth': this.useSmtpAuthentication() ? 2 : 0, 'IncomingMailPassword': this.incomingMailPassword() } ; return oParameters; }; /** * @param {Object} oParameters */ CAccountPropertiesViewModel.prototype.saveData = function (oParameters) { this.updateFirstState(); App.Ajax.send(oParameters, this.onResponse, this); }; /** * Sends a request to the server to save the settings. */ CAccountPropertiesViewModel.prototype.onSaveClick = function () { if (this.account()) { this.loading(true); this.saveData(this.prepareParameters()); } }; CAccountPropertiesViewModel.prototype.onChangePasswordClick = function () { App.Screens.showPopup(ChangePasswordPopup, [false]); }; /** * @param {?=} oParent * * @constructor */ function CAccountFoldersViewModel(oParent) { this.parent = oParent; this.highlighted = ko.observable(false).extend({'autoResetToFalse': 500}); this.collection = ko.observableArray(App.MailCache.editedFolderList().collection()); this.totalMessageCount = ko.computed(function () { return App.MailCache.editedFolderList().totalMessageCount(); }, this); this.enableButtons = ko.computed(function (){ return App.MailCache.editedFolderList().bInitialized(); }, this); App.MailCache.editedFolderList.subscribe(function(value){ this.collection(value.collection()); }, this); this.addNewFolderCommand = Utils.createCommand(this, this.onAddNewFolderClick, this.enableButtons); this.systemFoldersCommand = Utils.createCommand(this, this.onSystemFoldersClick, this.enableButtons); this.showMovedWithMouseItem = ko.computed(function () { var oAccount = AppData.Accounts.getEdited(); return oAccount ? !bMobileDevice && !oAccount.extensionExists('DisableFoldersManualSort') : false; }, this); } CAccountFoldersViewModel.prototype.onHide = function () { var iAccountId = AppData.Accounts.editedId(); _.delay(function () { App.MailCache.getFolderList(iAccountId); }, 3000); }; /** * @return {boolean} */ CAccountFoldersViewModel.prototype.isChanged = function () { return false; }; CAccountFoldersViewModel.prototype.onAddNewFolderClick = function () { App.Screens.showPopup(FolderCreatePopup); }; CAccountFoldersViewModel.prototype.onSystemFoldersClick = function () { App.Screens.showPopup(SystemFoldersPopup); }; /** * @param {?=} oParent * * @constructor */ function CAccountSignatureViewModel(oParent) { this.parent = oParent; this.account = ko.observable(0); this.type = ko.observable(false); this.useSignature = ko.observable(0); this.signature = ko.observable(''); this.loading = ko.observable(false); this.account.subscribe(function () { this.getSignature(); }, this); this.oHtmlEditor = new CHtmlEditorViewModel(true); this.enableImageDragNDrop = ko.observable(false); this.enabled = ko.observable(true); this.signature.subscribe(function () { this.oHtmlEditor.setText(this.signature()); }, this); this.getSignature(); this.firstState = null; } CAccountSignatureViewModel.prototype.__name = 'CAccountSignatureViewModel'; /** * @param {Object} oAccount */ CAccountSignatureViewModel.prototype.onShow = function (oAccount) { this.account(oAccount); this.oHtmlEditor.initCrea(this.signature(), false, ''); this.oHtmlEditor.setActivitySource(this.useSignature); this.enableImageDragNDrop(this.oHtmlEditor.editorUploader.isDragAndDropSupported() && !App.browser.ie10AndAbove); this.updateFirstState(); }; CAccountSignatureViewModel.prototype.getState = function () { var aState = [ this.type(), this.useSignature(), this.oHtmlEditor.getText() ]; return aState.join(':'); }; CAccountSignatureViewModel.prototype.updateFirstState = function () { this.firstState = this.getState(); }; CAccountSignatureViewModel.prototype.isChanged = function () { if (this.firstState && this.getState() !== this.firstState) { return true; } else { return false; } }; CAccountSignatureViewModel.prototype.getSignature = function () { if (this.account()) { if (this.account().signature() !== null) { this.type(this.account().signature().type()); this.useSignature(this.account().signature().options()); this.signature(this.account().signature().signature()); this.updateFirstState(); } else { var oParameters = { 'Action': 'AccountSignature', 'AccountID': this.account().id() } ; App.Ajax.send(oParameters, this.onSignatureResponse, this); } } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CAccountSignatureViewModel.prototype.onSignatureResponse = function (oResponse, oRequest) { var oSignature = null, iAccountId = parseInt(oResponse.AccountID, 10) ; if (!oResponse.Result) { App.Api.showErrorByCode(oResponse); } else { if (this.account() && iAccountId === this.account().id()) { oSignature = new CSignatureModel(); oSignature.parse(iAccountId, oResponse.Result); this.account().signature(oSignature); this.type(this.account().signature().type()); this.useSignature(this.account().signature().options()); this.signature(this.account().signature().signature()); this.updateFirstState(); } } }; CAccountSignatureViewModel.prototype.prepareParameters = function () { var oParameters = { 'Action': 'UpdateAccountSignature', 'AccountID': this.account().id(), 'Type': this.type() ? 1 : 0, 'Options': this.useSignature(), 'Signature': this.signature() } ; return oParameters; }; /** * @param {Object} oParameters */ CAccountSignatureViewModel.prototype.saveData = function (oParameters) { this.updateFirstState(); App.Ajax.send(oParameters, this.onResponse, this); }; CAccountSignatureViewModel.prototype.onSaveClick = function () { if (this.account()) { this.loading(true); this.signature(this.oHtmlEditor.getNotDefaultText()); this.account().signature().type(this.type()); this.account().signature().options(this.useSignature()); this.account().signature().signature(this.signature()); this.saveData(this.prepareParameters()); } }; /** * Parses the response from the server. If the settings are normally stored, then updates them. * Otherwise an error message. * * @param {Object} oResponse * @param {Object} oRequest */ CAccountSignatureViewModel.prototype.onResponse = function (oResponse, oRequest) { this.loading(false); if (oResponse.Result) { App.Api.showReport(Utils.i18n('SETTINGS/COMMON_REPORT_UPDATED_SUCCESSFULLY')); } else { App.Api.showErrorByCode(oResponse, Utils.i18n('SETTINGS/ERROR_SETTINGS_SAVING_FAILED')); } }; /** * @param {?=} oParent * * @constructor */ function CAccountForwardViewModel(oParent) { this.account = ko.observable(0); this.available = ko.computed(function () { var oAccount = this.account(); return oAccount && oAccount.forward(); }, this); this.loading = ko.observable(false); this.enable = ko.observable(false); this.email = ko.observable(''); this.emailFocus = ko.observable(false); this.account.subscribe(function () { this.getForward(); }, this); this.firstState = null; } /** * @param {Object} oAccount */ CAccountForwardViewModel.prototype.onShow = function (oAccount) { this.account(oAccount); }; CAccountForwardViewModel.prototype.getState = function () { return [this.enable(), this.email()].join(':'); }; CAccountForwardViewModel.prototype.updateFirstState = function () { this.firstState = this.getState(); }; CAccountForwardViewModel.prototype.isChanged = function() { return this.firstState && this.getState() !== this.firstState; }; CAccountForwardViewModel.prototype.prepareParameters = function () { return { 'Action': 'UpdateForward', 'AccountID': this.account().id(), 'Enable': this.enable() ? '1' : '0', 'Email': this.email() }; }; /** * @param {Object} oParameters */ CAccountForwardViewModel.prototype.saveData = function (oParameters) { this.updateFirstState(); App.Ajax.send(oParameters, this.onUpdateForwardResponse, this); }; CAccountForwardViewModel.prototype.onSaveClick = function () { if (this.account()) { var self = this, oForward = this.account().forward(), fSaveData = function() { if (oForward) { oForward.enable = self.enable(); oForward.email = self.email(); } self.loading(true); self.saveData(self.prepareParameters()); } ; if (this.enable() && this.email() === '') { this.emailFocus(true); } else if (this.enable() && this.email() !== '') { if (Utils.getIncorrectEmailsFromAddressString(this.email()).length) { App.Screens.showPopup(AlertPopup, [Utils.i18n('COMPOSE/WARNING_INPUT_CORRECT_EMAILS') + ' ' + this.email()]); } else { fSaveData(); } } else { fSaveData(); } } }; CAccountForwardViewModel.prototype.getForward = function() { if (this.account()) { if (this.account().forward() !== null) { this.enable(this.account().forward().enable); this.email(this.account().forward().email); this.firstState = this.getState(); } else { var oParameters = { 'Action': 'GetForward', 'AccountID': this.account().id() }; this.loading(true); this.updateFirstState(); App.Ajax.send(oParameters, this.onGetForwardResponse, this); } } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CAccountForwardViewModel.prototype.onGetForwardResponse = function (oResponse, oRequest) { this.loading(false); if (oRequest && oRequest.Action) { if (oResponse && oResponse.Result && oResponse.AccountID && this.account()) { var oAccount = null, oForward = new CForwardModel(), iAccountId = Utils.pInt(oResponse.AccountID) ; if (iAccountId) { oAccount = AppData.Accounts.getAccount(iAccountId); if (oAccount) { oForward.parse(iAccountId, oResponse.Result); oAccount.forward(oForward); this.enable(oAccount.forward().enable); this.email(oAccount.forward().email); this.updateFirstState(); if (iAccountId === this.account().id()) { this.getForward(); } } } } } else { App.Api.showError(Utils.i18n('WARNING/UNKNOWN_ERROR')); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CAccountForwardViewModel.prototype.onUpdateForwardResponse = function (oResponse, oRequest) { this.loading(false); if (oRequest && oRequest.Action) { if (oResponse && oResponse.Result) { App.Api.showReport(Utils.i18n('SETTINGS/ACCOUNT_FORWARD_SUCCESS_REPORT')); } else { App.Api.showErrorByCode(oResponse, Utils.i18n('SETTINGS/ERROR_SETTINGS_SAVING_FAILED')); } } else { App.Api.showError(Utils.i18n('WARNING/UNKNOWN_ERROR')); } }; /** * @param {?=} oParent * * @constructor */ function CAccountAutoresponderViewModel(oParent) { this.account = ko.observable(0); this.available = ko.computed(function () { var oAccount = this.account(); return oAccount && oAccount.autoresponder(); }, this); this.loading = ko.observable(false); this.enable = ko.observable(false); this.subject = ko.observable(''); this.message = ko.observable(''); this.account.subscribe(function () { this.getAutoresponder(); }, this); this.firstState = null; } /** * @param {Object} oAccount */ CAccountAutoresponderViewModel.prototype.onShow = function (oAccount) { this.account(oAccount); }; CAccountAutoresponderViewModel.prototype.getState = function () { var aState = [ this.enable(), this.subject(), this.message() ]; return aState.join(':'); }; CAccountAutoresponderViewModel.prototype.updateFirstState = function () { this.firstState = this.getState(); }; CAccountAutoresponderViewModel.prototype.isChanged = function() { if (this.firstState && this.getState() !== this.firstState) { return true; } else { return false; } }; CAccountAutoresponderViewModel.prototype.prepareParameters = function () { var oParameters = { 'Action': 'UpdateAutoresponder', 'AccountID': this.account().id(), 'Enable': this.enable() ? '1' : '0', 'Subject': this.subject(), 'Message': this.message() } ; return oParameters; }; /** * @param {Object} oParameters */ CAccountAutoresponderViewModel.prototype.saveData = function (oParameters) { this.updateFirstState(); App.Ajax.send(oParameters, this.onUpdateAutoresponder, this); }; CAccountAutoresponderViewModel.prototype.onSaveClick = function () { if (this.account()) { var oAutoresponder = this.account().autoresponder() ; if (oAutoresponder) { oAutoresponder.enable = this.enable(); oAutoresponder.subject = this.subject(); oAutoresponder.message = this.message(); } this.loading(true); this.saveData(this.prepareParameters()); } }; CAccountAutoresponderViewModel.prototype.getAutoresponder = function() { if (this.account()) { if (this.account().autoresponder() !== null) { this.enable(this.account().autoresponder().enable); this.subject(this.account().autoresponder().subject); this.message(this.account().autoresponder().message); this.updateFirstState(); } else { var oParameters = { 'Action': 'GetAutoresponder', 'AccountID': this.account().id() } ; this.loading(true); App.Ajax.send(oParameters, this.onGetAutoresponderResponse, this); } } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CAccountAutoresponderViewModel.prototype.onGetAutoresponderResponse = function (oResponse, oRequest) { this.loading(false); if (oRequest && oRequest.Action) { if (oResponse && oResponse.Result && oResponse.AccountID && this.account()) { var oAccount = null, oAutoresponder = new CAutoresponderModel(), iAccountId = Utils.pInt(oResponse.AccountID) ; if (iAccountId) { oAccount = AppData.Accounts.getAccount(iAccountId); if (oAccount) { oAutoresponder.parse(iAccountId, oResponse.Result); oAccount.autoresponder(oAutoresponder); if (iAccountId === this.account().id()) { this.getAutoresponder(); } } } } } else { App.Api.showError(Utils.i18n('WARNING/UNKNOWN_ERROR')); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CAccountAutoresponderViewModel.prototype.onUpdateAutoresponder = function (oResponse, oRequest) { this.loading(false); if (oRequest && oRequest.Action) { if (oResponse && oResponse.Result) { App.Api.showReport(Utils.i18n('SETTINGS/ACCOUNT_AUTORESPONDER_SUCCESS_REPORT')); } else { App.Api.showErrorByCode(oResponse, Utils.i18n('SETTINGS/ERROR_SETTINGS_SAVING_FAILED')); } } else { App.Api.showError(Utils.i18n('WARNING/UNKNOWN_ERROR')); } }; /** * @param {?=} oParent * * @constructor */ function CAccountFiltersViewModel(oParent) { this.account = ko.observable(0); this.folderList = ko.observable(App.MailCache.editedFolderList()); App.MailCache.editedFolderList.subscribe(function(oList) { if (oList && oList.iAccountId !== 0) { this.folderList(oList); } }, this); this.foldersOptions = ko.computed(function () { return this.folderList() ? this.folderList().getOptions(Utils.i18n('SETTINGS/ACCOUNT_FOLDERS_NOT_SELECTED'), true, true, false) : []; }, this); this.foldersOptions.subscribe(function () { this.getFilters(); }, this); this.available = ko.computed(function () { var oAccount = this.account(); return !!(oAccount && oAccount.filters()); }, this); this.loading = ko.observable(true); this.saving = ko.observable(false); this.collection = ko.observableArray([]); this.fieldOptions = [ {'text': Utils.i18n('SETTINGS/ACCOUNT_FILTERS_FIELD_FROM'), 'value': 0}, {'text': Utils.i18n('SETTINGS/ACCOUNT_FILTERS_FIELD_TO'), 'value': 1}, {'text': Utils.i18n('SETTINGS/ACCOUNT_FILTERS_FIELD_SUBJECT'), 'value': 2} ]; this.conditionOptions = [ {'text': Utils.i18n('SETTINGS/ACCOUNT_FILTERS_COND_CONTAIN_SUBSTR'), 'value': 0}, {'text': Utils.i18n('SETTINGS/ACCOUNT_FILTERS_COND_EQUAL_TO'), 'value': 1}, {'text': Utils.i18n('SETTINGS/ACCOUNT_FILTERS_COND_NOT_CONTAIN_SUBSTR'), 'value': 2} ]; this.actionOptions = [ {'text': Utils.i18n('SETTINGS/ACCOUNT_FILTERS_ACTION_MOVE'), 'value': 3}, {'text': Utils.i18n('SETTINGS/ACCOUNT_FILTERS_ACTION_DELETE'), 'value': 1} ]; this.phaseArray = ['']; _.each(Utils.i18n('SETTINGS/ACCOUNT_FILTERS_PHRASE').split(/\s/), function (sItem) { var iIndex = this.phaseArray.length - 1; if (sItem.substr(0,1) === '%' || this.phaseArray[iIndex].substr(-1,1) === '%') { this.phaseArray.push(sItem); } else { this.phaseArray[iIndex] += ' ' + sItem; } }, this); this.firstState = null; } /** * @param {Object} oAccount */ CAccountFiltersViewModel.prototype.onShow = function (oAccount) { this.account(oAccount); this.getFilters(); }; CAccountFiltersViewModel.prototype.onHide = function () { this.collection([]); this.updateFirstState(); }; CAccountFiltersViewModel.prototype.revert = function () { _.each(this.collection(), function (oFilter) { oFilter.revert(); }); }; CAccountFiltersViewModel.prototype.commit = function () { _.each(this.collection(), function (oFilter) { oFilter.commit(); }); }; CAccountFiltersViewModel.prototype.getState = function () { var sResult = ':', aState = _.map(this.collection(), function (oFilter) { return oFilter.toString(); }, this) ; if (aState.length > 0) { sResult = aState.join(':'); } return sResult; }; CAccountFiltersViewModel.prototype.updateFirstState = function () { this.firstState = this.getState(); }; CAccountFiltersViewModel.prototype.isChanged = function() { return this.firstState && (this.getState() !== this.firstState); }; CAccountFiltersViewModel.prototype.prepareParameters = function () { var aFilters =_.map(this.collection(), function (oItem) { return { 'Enable': oItem.enable() ? '1' : '0', 'Field': oItem.field(), 'Filter': oItem.filter(), 'Condition': oItem.condition(), 'Action': oItem.action(), 'FolderFullName': oItem.folder() }; }), oParameters = { 'Action': 'UpdateSieveFilters', 'AccountID': this.account().id(), 'Filters': aFilters } ; return oParameters; }; /** * @param {Object} oParameters */ CAccountFiltersViewModel.prototype.saveData = function (oParameters) { var bCantSave =_.some(this.collection(), function (oFilter) { return oFilter.filter() === '' || (Utils.pString(oFilter.action()) === '3' /* Move */ && oFilter.folder() === ''); }); if (bCantSave) { App.Api.showError(Utils.i18n('SETTINGS/ERROR_FILTERS_FIELDS_FILL')); } else { this.saving(true); this.commit(); this.updateFirstState(); App.Ajax.send(oParameters, this.onUpdateFiltersResponse, this); } }; CAccountFiltersViewModel.prototype.onSaveClick = function () { if (this.account()) { this.saveData(this.prepareParameters()); } }; CAccountFiltersViewModel.prototype.getFilters = function() { if (this.account()) { if (this.account().filters() !== null) { if (this.account().id() === this.folderList().iAccountId) { this.collection(this.account().filters().collection()); this.updateFirstState(); this.loading(false); } else { this.loading(true); } } else { var oParameters = { 'Action': 'GetSieveFilters', 'AccountID': this.account().id() } ; this.loading(true); App.Ajax.send(oParameters, this.onGetFiltersResponse, this); } } }; /** * @param {Object} oFilterToDelete */ CAccountFiltersViewModel.prototype.deleteFilter = function (oFilterToDelete) { this.collection.remove(oFilterToDelete); }; CAccountFiltersViewModel.prototype.addFilter = function () { if (this.account()) { var oSieveFilter = new CSieveFilterModel(this.account().id()); this.collection.push(oSieveFilter); } }; /** * @param {string} sPart * @param {string} sPrefix * * @return {string} */ CAccountFiltersViewModel.prototype.displayFilterPart = function (sPart, sPrefix) { var sTemplate = ''; if (sPart === '%FIELD%') { sTemplate = 'Field'; } else if (sPart === '%CONDITION%') { sTemplate = 'Condition'; } else if (sPart === '%STRING%') { sTemplate = 'String'; } else if (sPart === '%ACTION%') { sTemplate = 'Action'; } else if (sPart === '%FOLDER%') { sTemplate = 'Folder'; } else if (sPart.substr(0, 9) === '%DEPENDED') { sTemplate = 'DependedText'; } else { sTemplate = 'Text'; } return sPrefix + sTemplate; }; /** * @param {string} sText */ CAccountFiltersViewModel.prototype.getDependedText = function (sText) { sText = Utils.pString(sText); if (sText) { sText = sText.replace(/%/g, '').split('=')[1] || ''; } return sText; }; /** * @param {string} sText * @param {Object} oParent */ CAccountFiltersViewModel.prototype.getDependedField = function (sText, oParent) { sText = Utils.pString(sText); if (sText) { sText = sText.replace(/[=](.*)/g, '').split('-')[1] || ''; sText = sText.toLowerCase(); } return Utils.isUnd(oParent[sText]) ? false : oParent[sText](); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CAccountFiltersViewModel.prototype.onGetFiltersResponse = function (oResponse, oRequest) { this.loading(false); if (oRequest && oRequest.Action) { if (oResponse && oResponse.Result && oResponse.AccountID && this.account()) { var oAccount = null, oSieveFilters = new CSieveFiltersModel(), iAccountId = Utils.pInt(oResponse.AccountID) ; if (iAccountId) { oAccount = AppData.Accounts.getAccount(iAccountId); if (oAccount) { oSieveFilters.parse(iAccountId, oResponse.Result); oAccount.filters(oSieveFilters); if (iAccountId === this.account().id()) { this.getFilters(); } } } } } else { App.Api.showError(Utils.i18n('WARNING/UNKNOWN_ERROR')); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CAccountFiltersViewModel.prototype.onUpdateFiltersResponse = function (oResponse, oRequest) { this.saving(false); if (oRequest && oRequest.Action) { if (oResponse && oResponse.Result) { App.Api.showReport(Utils.i18n('SETTINGS/ACCOUNT_FILTERS_SUCCESS_REPORT')); } else { App.Api.showError(Utils.i18n('SETTINGS/ERROR_SETTINGS_SAVING_FAILED')); } } else { App.Api.showError(Utils.i18n('WARNING/UNKNOWN_ERROR')); } }; /** * @constructor * * @param {Object} oParent */ function CFetcherIncomingViewModel(oParent) { this.defaultAccountId = AppData.Accounts.defaultId; this.folderList = App.MailCache.folderList; this.loading = ko.observable(false); this.fetcher = ko.observable(null); this.idFetcher = ko.observable(null); this.isEnabled = ko.observable(true); this.incomingMailServer = ko.observable(''); this.incomingMailPort = ko.observable(110); this.incomingMailLogin = ko.observable(''); this.incomingMailPassword = ko.observable(''); this.folder = ko.observable(''); this.options = ko.computed(function(){ return this.folderList().getOptions('', true, false, false); }, this); this.leaveMessagesOnServer = ko.observable(false); this.folderList.subscribe(function () { this.folder((this.fetcher()) ? this.fetcher().folder() : ''); }, this); this.serverIsSelected = ko.observable(false); this.loginIsSelected = ko.observable(false); this.passwordIsSelected = ko.observable(false); this.defaultOptionsAfterRender = Utils.defaultOptionsAfterRender; } CFetcherIncomingViewModel.prototype.onSaveClick = function () { if (this.isEmptyRequiredFields()) { App.Api.showError(Utils.i18n('WARNING/FETCHER_CREATE_ERROR')); } else { var oParameters = { 'Action': "FetcherUpdate", 'AccountID': this.defaultAccountId(), 'FetcherID': this.idFetcher(), 'IsEnabled': this.isEnabled() ? 1 : 0, 'Folder': this.folder(), // 'IncomingMailServer': this.incomingMailServer(), // 'IncomingMailPort': parseInt(this.incomingMailPort(), 10), // 'IncomingMailLogin': this.incomingMailLogin(), 'IncomingMailPassword': (this.incomingMailPassword() === '') ? '******' : this.incomingMailPassword(), 'LeaveMessagesOnServer': this.leaveMessagesOnServer() ? 1 : 0 }; this.loading(true); App.Ajax.send(oParameters, this.onSaveFetcherResponse, this); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CFetcherIncomingViewModel.prototype.onSaveFetcherResponse = function (oResponse, oRequest) { this.loading(false); if (!oResponse.Result) { App.Api.showErrorByCode(oResponse, Utils.i18n('WARNING/UNKNOWN_ERROR')); } else { AppData.Accounts.populateFetchers(); App.Api.showReport(Utils.i18n('SETTINGS/ACCOUNT_FETCHER_SUCCESSFULLY_SAVED')); } }; CFetcherIncomingViewModel.prototype.populate = function (oFetcher) { if (oFetcher) { this.fetcher(oFetcher); this.idFetcher(oFetcher.id()); this.isEnabled(oFetcher.isEnabled()); this.folder(oFetcher.folder()); this.incomingMailServer(oFetcher.incomingMailServer()); this.incomingMailPort(oFetcher.incomingMailPort()); this.incomingMailLogin(oFetcher.incomingMailLogin()); this.incomingMailPassword('******'); this.leaveMessagesOnServer(oFetcher.leaveMessagesOnServer()); } }; CFetcherIncomingViewModel.prototype.isEmptyRequiredFields = function () { switch ('') { case this.incomingMailServer(): this.serverIsSelected(true); return true; case this.incomingMailLogin(): this.loginIsSelected(true); return true; case this.incomingMailPassword(): this.passwordIsSelected(true); return true; default: return false; } }; /** * @constructor */ function CFetcherOutgoingViewModel(oParent) { this.defaultAccountId = AppData.Accounts.defaultId; this.loading = ko.observable(false); this.fetcher = ko.observable(null); this.idFetcher = ko.observable(null); this.isEnabled = ko.observable(true); this.email = ko.observable(''); this.userName = ko.observable(''); this.isOutgoingEnabled = ko.observable(false); this.outgoingMailServer = ko.observable(''); this.outgoingMailPort = ko.observable(25); this.outgoingMailAuth = ko.observable(false); this.serverIsSelected = ko.observable(false); } CFetcherOutgoingViewModel.prototype.onSaveClick = function () { if (this.outgoingMailAuth() && this.isEmptyRequiredFields()) { App.Api.showError(Utils.i18n('WARNING/FETCHER_CREATE_ERROR')); } else { var oParameters = { 'Action': "FetcherUpdate", 'AccountID': this.defaultAccountId(), 'FetcherID': this.idFetcher(), 'Email': this.email(), 'Name': this.userName(), 'IsOutgoingEnabled': this.isOutgoingEnabled() ? 1 : 0, 'OutgoingMailServer': this.outgoingMailServer(), 'OutgoingMailPort': parseInt(this.outgoingMailPort(), 10), 'OutgoingMailAuth': this.outgoingMailAuth() ? 1 : 0 }; this.loading(true); App.Ajax.send(oParameters, this.onSaveFetcherResponse, this); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CFetcherOutgoingViewModel.prototype.onSaveFetcherResponse = function (oResponse, oRequest) { this.loading(false); if (!oResponse.Result) { App.Api.showErrorByCode(oResponse, Utils.i18n('WARNING/UNKNOWN_ERROR')); } else { AppData.Accounts.populateFetchers(); App.Api.showReport(Utils.i18n('SETTINGS/ACCOUNT_FETCHER_SUCCESSFULLY_SAVED')); } }; CFetcherOutgoingViewModel.prototype.populate = function (oFetcher) { if (oFetcher) { this.fetcher(oFetcher); this.idFetcher(oFetcher.id()); this.isEnabled(oFetcher.isEnabled()); this.email(oFetcher.email()); this.userName(oFetcher.userName()); this.isOutgoingEnabled(oFetcher.isOutgoingEnabled()); this.outgoingMailServer(oFetcher.outgoingMailServer()); this.outgoingMailPort(oFetcher.outgoingMailPort()); this.outgoingMailAuth(oFetcher.outgoingMailAuth()); } }; CFetcherOutgoingViewModel.prototype.isEmptyRequiredFields = function () { if (this.isOutgoingEnabled()) { if ('' === this.outgoingMailServer()) { this.serverIsSelected(true); return true; } } return false; }; /** * @param {?=} oParent * * @constructor */ function CFetcherSignatureViewModel(oParent) { this.defaultAccountId = AppData.Accounts.defaultId; this.idFetcher = ko.observable(null); this.fetcher = ko.observable(null); this.signature = ko.observable(''); this.loading = ko.observable(false); this.type = ko.observable(false); this.useSignature = ko.observable(0); this.oHtmlEditor = new CHtmlEditorViewModel(true); this.enableImageDragNDrop = ko.observable(false); this.enabled = oParent.oFetcherIncoming.isEnabled; this.enabled.subscribe(function () { this.oHtmlEditor.isEnable(this.enabled()); }, this); this.signature.subscribe(function () { this.oHtmlEditor.setText(this.signature()); }, this); this.firstState = null; } CFetcherSignatureViewModel.prototype.__name = 'CFetcherSignatureViewModel'; CFetcherSignatureViewModel.prototype.onSaveClick = function () { var oParameters = { 'Action': 'FetcherUpdate', 'AccountID': this.defaultAccountId(), 'FetcherID': this.idFetcher(), 'SignatureOptions': this.useSignature(), 'Signature': this.oHtmlEditor.getText() }; this.loading(true); App.Ajax.send(oParameters, this.onSaveFetcherResponse, this); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CFetcherSignatureViewModel.prototype.onSaveFetcherResponse = function (oResponse, oRequest) { this.loading(false); if (oResponse.Result) { App.Api.showReport(Utils.i18n('SETTINGS/COMMON_REPORT_UPDATED_SUCCESSFULLY')); AppData.Accounts.populateFetchers(); } else { App.Api.showErrorByCode(oResponse, Utils.i18n('SETTINGS/ERROR_SETTINGS_SAVING_FAILED')); } }; /** * @param {Object} oFetcher */ CFetcherSignatureViewModel.prototype.populate = function (oFetcher) { if (oFetcher) { this.fetcher(oFetcher); this.idFetcher(oFetcher.id()); this.signature(oFetcher.signature()); this.useSignature(oFetcher.signatureOptions()); } }; /** * @returns {String} */ CFetcherSignatureViewModel.prototype.getState = function () { var aState = [ this.type(), this.useSignature(), this.oHtmlEditor.getText() ]; return aState.join(':'); }; CFetcherSignatureViewModel.prototype.updateFirstState = function () { this.firstState = this.getState(); }; /** * @param {Array} aParams * @param {Object} oAccount */ CFetcherSignatureViewModel.prototype.onShow = function (aParams, oAccount) { this.oHtmlEditor.initCrea(this.signature(), false, ''); this.oHtmlEditor.setActivitySource(this.useSignature); this.enableImageDragNDrop(this.oHtmlEditor.editorUploader.isDragAndDropSupported() && !App.browser.ie10AndAbove); this.updateFirstState(); }; /** * @constructor */ function CHelpdeskSettingsViewModel() { this.allowNotifications = ko.observable(AppData.User.AllowHelpdeskNotifications); this.loading = ko.observable(false); } CHelpdeskSettingsViewModel.prototype.TemplateName = 'Settings_HelpdeskSettingsViewModel'; CHelpdeskSettingsViewModel.prototype.TabName = Enums.SettingsTab.Helpdesk; CHelpdeskSettingsViewModel.prototype.TabTitle = Utils.i18n('SETTINGS/TAB_HELPDESK'); CHelpdeskSettingsViewModel.prototype.onShow = function () { this.allowNotifications(AppData.User.AllowHelpdeskNotifications); }; /** * Parses the response from the server. If the settings are normally stored, then updates them. * Otherwise an error message. * * @param {Object} oResponse * @param {Object} oRequest */ CHelpdeskSettingsViewModel.prototype.onResponse = function (oResponse, oRequest) { this.loading(false); if (oResponse.Result === false) { App.Api.showErrorByCode(oResponse, Utils.i18n('SETTINGS/ERROR_SETTINGS_SAVING_FAILED')); } else { AppData.User.updateHelpdeskSettings(this.allowNotifications()); App.Api.showReport(Utils.i18n('SETTINGS/COMMON_REPORT_UPDATED_SUCCESSFULLY')); } }; /** * Sends a request to the server to save the settings. */ CHelpdeskSettingsViewModel.prototype.onSaveClick = function () { var oParameters = { 'Action': 'UpdateHelpdeskUserSettings', 'AllowHelpdeskNotifications': this.allowNotifications() ? '1' : '0' } ; this.loading(true); App.Ajax.send(oParameters, this.onResponse, this); }; /** * @constructor */ function CServicesSettingsViewModel() { this.loading = ko.observable(false); this.allowFiles = AppData.User.IsFilesSupported; this.allowGoogle = AppData.SocialGoogle; this.googleKey = AppData.SocialGoogleApiKey; this.googleClientId = AppData.SocialGoogleId; this.allowDropbox = AppData.SocialDropbox; this.googleApiLoaded = ko.observable(false); this.loading = ko.observable(false); this.checkGoogleApiLoadTimeout = null; this.googleConnected = ko.observable(false); this.dropboxConnected = ko.observable(false); this.enableFiles = ko.observable(AppData.User.filesEnable()); this.firstState = this.getState(); } CServicesSettingsViewModel.prototype.TemplateName = 'Settings_ServicesSettingsViewModel'; CServicesSettingsViewModel.prototype.TabName = Enums.SettingsTab.Services; CServicesSettingsViewModel.prototype.TabTitle = Utils.i18n('SETTINGS/TAB_SERVICES'); CServicesSettingsViewModel.prototype.getState = function() { var sState = [ this.enableFiles() ]; return sState.join(':'); }; CServicesSettingsViewModel.prototype.updateFirstState = function() { this.firstState = this.getState(); }; CServicesSettingsViewModel.prototype.isChanged = function() { if (this.firstState && this.getState() !== this.firstState) { return true; } else { return false; } }; CServicesSettingsViewModel.prototype.init = function () { this.enableFiles(AppData.User.filesEnable()); }; CServicesSettingsViewModel.prototype.onApplyBindings = function () { window.servicesSettingsViewModelCallback = _.bind(function (sSocialType, bResult) { if (bResult) { switch (sSocialType) { case 'google': this.getSocialAccount(Enums.SocialType.Google); this.googleConnected(!this.googleConnected()); break; case 'dropbox': this.getSocialAccount(Enums.SocialType.Dropbox); this.dropboxConnected(!this.dropboxConnected()); break; } } }, this); }; CServicesSettingsViewModel.prototype.onGoogleApiLoad = function () { this.googleApiLoaded(true); }; CServicesSettingsViewModel.prototype.onShow = function () { }; CServicesSettingsViewModel.prototype.onRoute = function () { if (this.allowGoogle || this.allowDropbox) { this.getSocialAccounts(); } }; CServicesSettingsViewModel.prototype.onDropboxSignInClick = function () { if (!this.dropboxConnected()) { this.onSocialSignInClick('dropbox'); } else { this.onSocialSignOutClick('dropbox'); } }; CServicesSettingsViewModel.prototype.onGoogleSignInClick = function () { if (!this.googleConnected()) { this.onSocialSignInClick('google'); } else { this.onSocialSignOutClick('google'); } }; CServicesSettingsViewModel.prototype.onSocialSignInClick = function (sSocial) { var oWin = null ; $.cookie('SocialRedirect', 'settings'); oWin = Utils.WindowOpener.open(Utils.getAppPath() + '?' + sSocial, sSocial); }; CServicesSettingsViewModel.prototype.addSocialAccount = function (aData) { AppData.User.SocialAccounts.push(aData); }; CServicesSettingsViewModel.prototype.deleteSocialAccount = function (iType) { AppData.User.SocialAccounts( _.filter(AppData.User.SocialAccounts(), function (oItem){ return (oItem['@Object'] === 'Object/CSocial' && oItem.Type !== iType); }, this) ); }; CServicesSettingsViewModel.prototype.onSocialSignOutClick = function (sSocial) { var iType = 0; switch (sSocial) { case 'google': this.deleteSocialAccount(Enums.SocialType.Google); iType = Enums.SocialType.Google; this.googleConnected(false); break; case 'dropbox': this.deleteSocialAccount(Enums.SocialType.Dropbox); iType = Enums.SocialType.Dropbox; this.dropboxConnected(false); break; } App.Ajax.send({ 'Action': 'SocialAccountDelete', 'Type': iType }, this.onSocialAccountDeleteResponse, this ); }; CServicesSettingsViewModel.prototype.onSocialAccountDeleteResponse = function (oResponse, oRequest) { var oResult = oResponse.Result ; if (oRequest.Type === Enums.SocialType.Google) { if (oResult !== false) { this.googleConnected(false); } else { this.googleConnected(!this.googleConnected()); } } else if (oRequest.Type === Enums.SocialType.Dropbox) { if (oResult !== false) { this.dropboxConnected(false); } else { this.dropboxConnected(!this.dropboxConnected()); } } }; CServicesSettingsViewModel.prototype.onSaveClick = function () { var oParameters = { 'Action': 'UpdateUserSettings', 'FilesEnable': this.enableFiles() ? '1' : '0' } ; this.loading(true); this.updateFirstState(); App.Ajax.send(oParameters, this.onResponse, this); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CServicesSettingsViewModel.prototype.onResponse = function (oResponse, oRequest) { this.loading(false); if (oResponse.Result === false) { App.Api.showErrorByCode(oResponse, Utils.i18n('SETTINGS/ERROR_SETTINGS_SAVING_FAILED')); } else { AppData.User.filesEnable(this.enableFiles()); App.Api.showReport(Utils.i18n('SETTINGS/COMMON_REPORT_UPDATED_SUCCESSFULLY')); } }; CServicesSettingsViewModel.prototype.getSocialAccounts = function () { this.googleConnected(false); this.dropboxConnected(false); _.each(AppData.User.SocialAccounts(), function (oItem){ if (oItem['@Object'] === 'Object/CSocial') { if (oItem.Type === Enums.SocialType.Google) { this.googleConnected(true); } else if (oItem.Type === Enums.SocialType.Dropbox) { this.dropboxConnected(true); } } }, this); }; CServicesSettingsViewModel.prototype.getSocialAccount = function (iType) { App.Ajax.send({ 'Action': 'SocialAccount', 'Type': iType }, this.onSocialAccountResponse, this ); }; CServicesSettingsViewModel.prototype.onSocialAccountResponse = function (oResponse, oRequest) { var oResult = oResponse.Result ; if (oResult && oResult['@Object'] === 'Object/CSocial') { this.deleteSocialAccount(oResult.Type); this.addSocialAccount(oResult); } }; /** * @constructor * * @param {Object} oParent * @param {boolean} bCreate */ function CIdentityPropertiesViewModel(oParent, bCreate) { this.defaultAccountId = AppData.Accounts.defaultId; this.oParent = oParent; this.bCreate = bCreate; this.loading = ko.observable(false); this.identity = ko.observable(null); this.enabled = ko.observable(true); this.email = ko.observable(''); this.friendlyName = ko.observable(''); this.friendlyNameHasFocus = ko.observable(false); this.signature = ko.observable(''); this.useSignature = ko.observable(0); this.oHtmlEditor = new CHtmlEditorViewModel(true); this.enableImageDragNDrop = ko.observable(false); this.signature.subscribe(function () { this.oHtmlEditor.setText(this.signature()); }, this); this.enabled.subscribe(function () { this.oHtmlEditor.isEnable(this.enabled()); }, this); } CIdentityPropertiesViewModel.prototype.__name = 'CIdentityPropertiesViewModel'; /** * @param {Array} aParams * @param {Object} oAccount */ CIdentityPropertiesViewModel.prototype.onShow = function (aParams, oAccount) { this.oHtmlEditor.initCrea(this.signature(), false, ''); this.oHtmlEditor.setActivitySource(this.useSignature); this.enableImageDragNDrop(this.oHtmlEditor.editorUploader.isDragAndDropSupported() && !App.browser.ie10AndAbove); }; CIdentityPropertiesViewModel.prototype.onSaveClick = function () { if (this.email() === '') { App.Api.showError(Utils.i18n('WARNING/IDENTITY_CREATE_ERROR')); } else { this.signature(this.oHtmlEditor.getNotDefaultText()); var sAction = this.bCreate ? 'CreateIdentity' : 'UpdateIdentity', oParameters = { 'Action': sAction, 'AccountID': this.identity().accountId(), 'Enabled': this.enabled() ? 1 : 0, 'Email': this.email(), 'Signature': this.signature(), 'UseSignature': this.useSignature(), 'FriendlyName': this.friendlyName() } ; if (!this.bCreate) { oParameters.IdIdentity = this.identity().id(); } this.loading(true); App.Ajax.send(oParameters, this.onUpdateIdentityResponse, this); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CIdentityPropertiesViewModel.prototype.onUpdateIdentityResponse = function (oResponse, oRequest) { this.loading(false); if (!oResponse.Result) { App.Api.showErrorByCode(oResponse, Utils.i18n('SETTINGS/ACCOUNTS_IDENTITY_ADDING_ERROR')); } else { AppData.Accounts.populateIdentities(); if (this.bCreate) { this.oParent.closeCommand(); } } }; /** * @param {Object} oIdentity */ CIdentityPropertiesViewModel.prototype.populate = function (oIdentity) { if (oIdentity) { this.identity(oIdentity); this.enabled(oIdentity.enabled()); this.email(oIdentity.email()); this.friendlyName(oIdentity.friendlyName()); this.signature(oIdentity.signature()); this.useSignature(oIdentity.useSignature() ? 1 : 0); } }; CIdentityPropertiesViewModel.prototype.remove = function () { var oParameters = { 'Action': 'DeleteIdentity', 'AccountID': this.identity().accountId(), 'IdIdentity': this.identity().id() }; App.Ajax.send(oParameters, this.onDeleteIdentityResponse, this); if (!this.bCreate) { this.oParent.onRemoveIdentity(); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CIdentityPropertiesViewModel.prototype.onDeleteIdentityResponse = function (oResponse, oRequest) { if (!oResponse.Result) { App.Api.showErrorByCode(oResponse, Utils.i18n('SETTINGS/ACCOUNTS_IDENTITY_DELETING_ERROR')); } AppData.Accounts.populateIdentities(); }; CIdentityPropertiesViewModel.prototype.cancel = function () { if (this.bCreate) { this.oParent.cancel(); } }; /** * @constructor */ function CCalendarViewModel() { var self = this; this.initialized = ko.observable(false); this.isPublic = bExtApp; this.uploaderArea = ko.observable(null); this.bDragActive = ko.observable(false); this.bDragActiveComp = ko.computed(function () { return this.bDragActive(); }, this); this.defaultAccount = (AppData.Accounts) ? AppData.Accounts.getDefault() : null; this.todayDate = new Date(); this.aDayNames = Utils.i18n('DATETIME/DAY_NAMES').split(' '); this.publicCalendarId = (this.isPublic) ? AppData.CalendarPubHash : ''; this.publicCalendarName = ko.observable(''); this.timeFormat = (AppData.User.defaultTimeFormat() === Enums.TimeFormat.F24) ? 'HH:mm' : 'hh:mm A'; this.dateFormat = AppData.User.DefaultDateFormat; this.dateTitle = ko.observable(''); this.dateTitleHelper = ko.observableArray(Utils.i18n('DATETIME/MONTH_NAMES').split(' ')); this.selectedView = ko.observable(''); this.visibleWeekdayHeader = ko.computed(function () { return this.selectedView() === 'month'; }, this); this.selectedView.subscribe(function () { this.resize(); }, this); this.$calendarGrid = null; this.calendarGridDom = ko.observable(null); this.$datePicker = null; this.datePickerDom = ko.observable(null); this.calendars = new CCalendarListModel({ onCalendarCollectionChange: function () { self.refreshView(); }, onCalendarActiveChange: function () { self.refreshView(); } }); this.colors = [ '#f09650', '#f68987', '#6fd0ce', '#8fbce2', '#b9a4f5', '#f68dcf', '#d88adc', '#4afdb4', '#9da1ff', '#5cc9c9', '#77ca71', '#aec9c9' ]; this.busyDays = ko.observableArray([]); this.$inlineEditedEvent = null; this.inlineEditedEventText = null; this.checkStarted = ko.observable(false); this.loaded = false; this.startDateTime = 0; this.endDateTime = 0; this.needsToReload = false; this.calendarListClick = function (oItem) { oItem.active(!oItem.active()); }; this.currentCalendarDropdown = ko.observable(false); this.currentCalendarDropdownOffset = ko.observable(0); this.calendarDropdownToggle = function (bValue, oElement) { if (oElement && bValue) { var position = oElement.position(), height = oElement.outerHeight() ; self.currentCalendarDropdownOffset(parseInt(position.top, 10) + height); } self.currentCalendarDropdown(bValue); }; this.dayNamesResizeBinding = _.throttle(_.bind(this.resize, this), 50); this.customscrollTop = ko.observable(0); this.fullcalendarOptions = { eventLimit: 10, header: false, editable: !this.isPublic, selectable: !this.isPublic, allDayText: Utils.i18n('CALENDAR/TITLE_ALLDAY'), dayNames: this.aDayNames, isRTL: Utils.isRTL(), scrollTime: moment.duration(8, 'hours'), forceEventDuration: true, columnFormat: { month: 'dddd', // Monday week: 'dddd D', // Monday 7 day: 'dddd D' // Monday 7 }, titleFormat: { month: 'MMMM YYYY', // September 2009 week: "MMMM D[ YYYY]{ '-'[ MMMM] D YYYY}", // Sep 7 - 13 2009 day: 'MMMM D, YYYY' // Tuesday, Sep 8, 2009 }, displayEventEnd: { month: true, basicWeek: true, 'default': true }, select: _.bind(this.createEventFromGrid, this), eventClick: _.bind(this.eventClickCallback, this), eventDragStart: _.bind(this.onEventDragStart, this), eventDragStop: _.bind(this.onEventDragStop, this), eventResizeStart: _.bind(this.onEventResizeStart, this), eventResizeStop: _.bind(this.onEventResizeStop, this), eventDrop: _.bind(this.moveEvent, this), eventResize: _.bind(this.resizeEvent, this), viewRender: _.bind(this.viewRenderCallback, this), events: _.bind(this.eventsSource, this) }; this.revertFunction = null; this.calendarSharing = AppData.User.AllowCalendar && AppData.User.CalendarSharing; this.defaultViewName = ko.computed(function () { var viewName = 'month' ; switch (AppData.User.CalendarDefaultTab) { case Enums.CalendarDefaultTab.Day: viewName = 'agendaDay'; break; case Enums.CalendarDefaultTab.Week: viewName = 'agendaWeek'; break; case Enums.CalendarDefaultTab.Month: viewName = 'month'; break; } return viewName; }, this); this.iAutoReloadTimer = -1; this.dragEventTrigger = false; this.delayOnEventResult = false; this.delayOnEventResultData = []; this.refreshView = _.throttle(_.bind(this.refreshViewSingle, this), 100); this.defaultCalendarId = ko.computed(function () { var defaultCalendar = this.calendars.defaultCal() ; if (defaultCalendar) { return defaultCalendar.id; } }, this); this.uploadCalendarId = ko.observable(''); this.changeFullCalendarDate = true; } CCalendarViewModel.prototype.getFCObject = function () { return this.$calendarGrid.fullCalendar('getCalendar'); }; CCalendarViewModel.prototype.getDateFromCurrentView = function (sDateType) { var oView = this.$calendarGrid.fullCalendar('getView'), oDate = oView && oView[sDateType] ? oView[sDateType] : null ; if (oDate && sDateType === 'end' && oView.name === 'agendaDay') { oDate.add(1, 'd'); } return (oDate && oDate['unix']) ? oView[sDateType]['unix']() : 0; }; CCalendarViewModel.prototype.eventsSource = function (start, end, timezone, callback) { callback(this.calendars.getEvents(start, end)); }; CCalendarViewModel.prototype.initFullCalendar = function () { this.$calendarGrid.fullCalendar(this.fullcalendarOptions); }; CCalendarViewModel.prototype.applyCalendarSettings = function () { this.timeFormat = (AppData.User.defaultTimeFormat() === Enums.TimeFormat.F24) ? 'HH:mm' : 'hh:mm A'; this.dateFormat = AppData.User.DefaultDateFormat; this.calendarGridDom().removeClass("fc-show-weekends"); if (AppData.User.CalendarShowWeekEnds) { this.calendarGridDom().addClass("fc-show-weekends"); } this.fullcalendarOptions.timeFormat = this.timeFormat; this.fullcalendarOptions.axisFormat = this.timeFormat; this.fullcalendarOptions.defaultView = this.defaultViewName(); this.fullcalendarOptions.lang = moment.lang(); this.applyFirstDay(); this.$calendarGrid.fullCalendar('destroy'); this.$calendarGrid.fullCalendar(this.fullcalendarOptions); this.changeView(this.defaultViewName()); }; CCalendarViewModel.prototype.applyFirstDay = function () { var aDayNames = [], sFirstDay = '', sLastDay = '' ; if (AppData.Auth) { this.fullcalendarOptions.firstDay = AppData.User.CalendarWeekStartsOn; } _.each(this.aDayNames, function (sDayName) { aDayNames.push(sDayName); }); switch (this.fullcalendarOptions.firstDay) { case 1: sLastDay = aDayNames.shift(); aDayNames.push(sLastDay); break; case 6: sFirstDay = aDayNames.pop(); aDayNames.unshift(sFirstDay); break; } this.$datePicker.datepicker('option', 'firstDay', this.fullcalendarOptions.firstDay); }; CCalendarViewModel.prototype.initDatePicker = function () { this.$datePicker.datepicker({ showOtherMonths: true, selectOtherMonths: true, monthNames: Utils.getMonthNamesArray(), dayNamesMin: Utils.i18n('DATETIME/DAY_NAMES_MIN').split(' '), onChangeMonthYear: _.bind(this.changeMonthYearFromDatePicker, this), onSelect: _.bind(this.selectDateFromDatePicker, this), beforeShowDay: _.bind(this.getDayDescription, this) }); }; CCalendarViewModel.prototype.onApplyBindings = function () { this.$calendarGrid = $(this.calendarGridDom()); this.$datePicker = $(this.datePickerDom()); if (!this.isPublic) { this.initUploader(); } }; CCalendarViewModel.prototype.onShow = function () { if (!this.initialized()) { this.initDatePicker(); this.applyCalendarSettings(); this.highlightWeekInDayPicker(); this.initialized(true); } if (App.CalendarCache) { if (App.CalendarCache.calendarSettingsChanged() || App.CalendarCache.calendarChanged()) { if (App.CalendarCache.calendarSettingsChanged()) { this.applyCalendarSettings(); } App.CalendarCache.calendarSettingsChanged(false); App.CalendarCache.calendarChanged(false); this.getCalendars(); } } else if (this.isPublic) { this.$calendarGrid.fullCalendar("render"); } this.refetchEvents(); }; CCalendarViewModel.prototype.setTimeline = function () { var oView = this.$calendarGrid.fullCalendar("getView"), now = new Date(), nowDate = new Date(now.getFullYear(), now.getMonth(), now.getDate()), todayDate = new Date(this.todayDate.getFullYear(), this.todayDate.getMonth(), this.todayDate.getDate()), parentDiv = null, timeline = null, curSeconds = 0, percentOfDay = 0, topLoc = 0 ; if (todayDate < nowDate) {// the day has changed this.execCommand("today"); this.todayDate = this.$calendarGrid.fullCalendar("getDate").toDate(); this.$calendarGrid.fullCalendar("render"); } // render timeline parentDiv = $(".fc-slats:visible").parent(); timeline = parentDiv.children(".timeline"); if (timeline.length === 0) { //if timeline isn't there, add it timeline = $("<hr>").addClass("timeline"); parentDiv.prepend(timeline); } timeline.css('left', $("td .fc-axis").width() + 10); timeline.show(); /* if (oView.start.toDate() < now && oView.end.toDate() > now) { timeline.show(); } else { timeline.hide(); } */ curSeconds = (now.getHours() * 60 * 60) + (now.getMinutes() * 60) + now.getSeconds(); percentOfDay = curSeconds / 86400; //24 * 60 * 60 = 86400, % of seconds in a day topLoc = Math.floor(parentDiv.height() * percentOfDay); timeline.css("top", topLoc + "px"); }; /** * @param {Object} oView * @param {Object} oElement */ CCalendarViewModel.prototype.viewRenderCallback = function (oView, oElement) { var count = 0, prevDate = null, constDate = "01/01/1971 ", timelineInterval ; this.changeDate(); if (!this.loaded) { this.initResizing(); } if(typeof(timelineInterval) !== "undefined") { window.clearInterval(timelineInterval); } timelineInterval = window.setInterval(_.bind(function () { this.setTimeline(); }, this), 60000); try { this.setTimeline(); } catch(err) { } if (oView.name !== 'month' && AppData.User.CalendarShowWorkDay) { $('.fc-slats tr').each(function() { $('tr .fc-time span').each(function() { var theValue = $(this).eq(0).text(), theDate = (theValue !== '') ? Date.parse(constDate + theValue) : prevDate, rangeTimeFrom = Date.parse(constDate + AppData.User.CalendarWorkDayStarts + ':00'), rangeTimeTo = Date.parse(constDate + AppData.User.CalendarWorkDayEnds + ':00') ; prevDate = theDate; if(theDate < rangeTimeFrom || theDate >= rangeTimeTo) { $(this).parent().parent().addClass("fc-non-working-time"); $(this).parent().parent().next().addClass("fc-non-working-time"); } }); }); } this.activateCustomScrollInDayAndWeekView(); }; CCalendarViewModel.prototype.collectBusyDays = function () { var aBusyDays = [], oStart = null, oEnd = null, iDaysDiff = 0, iIndex = 0 ; _.each(this.calendars.getEvents(), function (oEvent) { oStart = moment(oEvent.start); oEnd = oEvent.end ? moment(oEvent.end) : null; if (oEvent.allDay && oEnd) { oEnd.subtract(1, 'days'); } iDaysDiff = oEnd ? oEnd.diff(oStart, 'days') : 0; iIndex = 0; for (; iIndex <= iDaysDiff; iIndex++) { aBusyDays.push(oStart.clone().add('days', iIndex).toDate()); } }, this); this.busyDays(aBusyDays); }; CCalendarViewModel.prototype.refreshDatePicker = function () { var self = this; _.defer(function () { self.collectBusyDays(); self.$datePicker.datepicker('refresh'); self.highlightWeekInDayPicker(); }); }; /** * @param {Object} oDate */ CCalendarViewModel.prototype.getDayDescription = function (oDate) { var bSelectable = true, oFindedBusyDay = _.find(this.busyDays(), function (oBusyDay) { return oBusyDay.getDate() === oDate.getDate() && oBusyDay.getMonth() === oDate.getMonth() && oBusyDay.getYear() === oDate.getYear(); }, this), sDayClass = oFindedBusyDay ? 'day_with_events' : '', sDayTitle = '' ; return [bSelectable, sDayClass, sDayTitle]; }; CCalendarViewModel.prototype.initResizing = function () { var fResize = _.throttle(_.bind(this.resize, this), 50); $(window).bind('resize', function (e) { if (e.target !== this && !App.browser.ie8AndBelow) { return; } fResize(); }); fResize(); }; CCalendarViewModel.prototype.resize = function () { var oParent = this.$calendarGrid.parent(); if (oParent) { this.$calendarGrid.fullCalendar('option', 'height', oParent.height()); } this.dayNamesResize(); }; CCalendarViewModel.prototype.dayNamesResize = function () { if (this.selectedView() === 'month') { var oDayNamesHeaderItem = $('div.weekday-header-item'), oFirstWeek = $('tr.fc-first td.fc-day'), oFirstWeekWidth = $(oFirstWeek[0]).width(), iIndex = 0 ; if (oDayNamesHeaderItem.length === 7 && oFirstWeek.length === 7 && oFirstWeekWidth !== 0) { for(; iIndex < 7; iIndex++) { $(oDayNamesHeaderItem[iIndex]).width(oFirstWeekWidth); } } } }; /** * @param {number} iYear * @param {number} iMonth * @param {Object} oInst */ CCalendarViewModel.prototype.changeMonthYearFromDatePicker = function (iYear, iMonth, oInst) { if (this.changeFullCalendarDate) { var oDate = this.$calendarGrid.fullCalendar('getDate'); // Date object in javascript and fullcalendar use numbers 0,1,2...11 for monthes // datepiker uses numbers 1,2,3...12 for monthes oDate .month(iMonth - 1) .year(iYear); this.$calendarGrid.fullCalendar('gotoDate', oDate); } }; /** * @param {string} sDate * @param {Object} oInst */ CCalendarViewModel.prototype.selectDateFromDatePicker = function (sDate, oInst) { var oDate = this.getFCObject().moment(sDate); this.$calendarGrid.fullCalendar('gotoDate', oDate); _.defer(_.bind(this.highlightWeekInDayPicker, this)); }; CCalendarViewModel.prototype.highlightWeekInDayPicker = function () { var $currentDay = this.$datePicker.find('td.ui-datepicker-current-day'), $currentWeek = $currentDay.parent(), $currentMonth = this.$datePicker.find('table.ui-datepicker-calendar'), oView = this.$calendarGrid.fullCalendar('getView') ; switch (oView.name) { case 'agendaDay': $currentMonth.addClass('highlight_day').removeClass('highlight_week'); break; case 'agendaWeek': $currentMonth.removeClass('highlight_day').addClass('highlight_week'); break; default: $currentMonth.removeClass('highlight_day').removeClass('highlight_week'); break; } $currentWeek.addClass('current_week'); }; CCalendarViewModel.prototype.changeDateTitle = function () { var oDate = this.$calendarGrid.fullCalendar('getDate'), oView = this.$calendarGrid.fullCalendar('getView'), sTitle = oDate.format('MMMM YYYY'), oStart = oView.intervalStart, oEnd = oView.intervalEnd ? oView.intervalEnd.add('days', -1) : null ; switch (oView.name) { case 'agendaDay': sTitle = oDate.format('MMMM D, YYYY'); break; case 'agendaWeek': if (oStart && oEnd) { sTitle = oStart.format('MMMM D, YYYY') + ' - ' + oEnd.format('MMMM D, YYYY'); } break; } this.dateTitle(sTitle); }; CCalendarViewModel.prototype.changeDate = function () { this.changeDateInDatePicker(); this.changeDateTitle(); this.getTimeLimits(); this.getCalendars(); }; CCalendarViewModel.prototype.changeDateInDatePicker = function () { var oDateMoment = this.$calendarGrid.fullCalendar('getDate') ; this.changeFullCalendarDate = false; this.$datePicker.datepicker('setDate', oDateMoment.local().toDate()); this.changeFullCalendarDate = true; this.highlightWeekInDayPicker(); }; CCalendarViewModel.prototype.activateCustomScrollInDayAndWeekView = function () { if (bMobileDevice) { return; } var oView = this.$calendarGrid.fullCalendar('getView'), sGridType = oView.name === 'month' ? 'day' : 'time', oGridContainer = $('.fc-' + sGridType + '-grid-container'), oScrollWrapper = $('<div></div>') ; oGridContainer.parent().append(oScrollWrapper); oGridContainer.appendTo(oScrollWrapper); if (!oScrollWrapper.hasClass('scroll-wrap')) { oScrollWrapper.attr('data-bind', 'customScrollbar: {x: false, y: true}'); oGridContainer.css({'overflow': 'hidden'}).addClass('scroll-inner'); ko.applyBindings({}, oScrollWrapper[0]); } }; /** * @param {string} sCmd * @param {string=} sParam = '' */ CCalendarViewModel.prototype.execCommand = function (sCmd, sParam) { if (sParam) { this.$calendarGrid.fullCalendar(sCmd, sParam); } else { this.$calendarGrid.fullCalendar(sCmd); } }; CCalendarViewModel.prototype.displayToday = function () { this.execCommand('today'); }; CCalendarViewModel.prototype.displayPrev = function () { this.execCommand('prev'); }; CCalendarViewModel.prototype.displayNext = function () { this.execCommand('next'); }; CCalendarViewModel.prototype.changeView = function (viewName) { this.selectedView(viewName); this.$calendarGrid.fullCalendar('changeView', viewName); }; CCalendarViewModel.prototype.setAutoReloadTimer = function () { var self = this; clearTimeout(this.iAutoReloadTimer); if (AppData.User.AutoCheckMailInterval > 0) { this.iAutoReloadTimer = setTimeout(function () { self.getCalendars(); }, AppData.User.AutoCheckMailInterval * 60 * 1000); } }; CCalendarViewModel.prototype.reloadAll = function () { // this.startDateTime = 0; // this.endDateTime = 0; this.needsToReload = true; this.getCalendars(); }; CCalendarViewModel.prototype.getTimeLimits = function () { var iStart = this.getDateFromCurrentView('start'), iEnd = this.getDateFromCurrentView('end') ; this.startDateTime = iStart; this.endDateTime = iEnd; this.needsToReload = true; /* if (this.startDateTime === 0 && this.endDateTime === 0) { this.startDateTime = iStart; this.endDateTime = iEnd; this.needsToReload = true; } else if (iStart < this.startDateTime && iEnd > this.endDateTime) { this.startDateTime = iStart; this.endDateTime = iEnd; this.needsToReload = true; } else if (iStart < this.startDateTime) { iEnd= this.startDateTime; this.startDateTime = iStart; this.needsToReload = true; } else if (iEnd > this.endDateTime) { iStart = this.endDateTime; this.endDateTime = iEnd; this.needsToReload = true; } */ }; CCalendarViewModel.prototype.getCalendars = function () { this.checkStarted(true); this.setCalendarGridVisibility(); App.Ajax.abortRequestByActionName('CalendarList'); App.Ajax.sendExt({ 'Action': 'CalendarList', 'IsPublic': this.isPublic ? 1 : 0, 'PublicCalendarId': this.publicCalendarId }, this.onCalendarsResponse, this ); }; /** * @param {Object} oData * @param {Object} oParameters */ CCalendarViewModel.prototype.onCalendarsResponse = function (oData, oParameters) { var aCalendarIds = [], aNewCalendarIds = [], oCalendar = null, oClientCalendar = null ; if (oData.Result) { this.loaded = true; //sets default calendar aways fist in list oData.Result = _.sortBy(oData.Result, function(oItem){return !oItem.isDefault;}); _.each(oData.Result, function (oCalendarData) { oCalendar = this.calendars.parseCalendar(oCalendarData); aCalendarIds.push(oCalendar.id); oClientCalendar = this.calendars.getCalendarById(oCalendar.id); if (/*this.needsToReload || */!oClientCalendar || (oCalendar && oClientCalendar && oClientCalendar.cTag !== oCalendar.cTag)) { oCalendar = this.calendars.parseAndAddCalendar(oCalendarData); if (oCalendar) { if (this.isPublic) { App.setTitle(oCalendar.name()); this.publicCalendarName(oCalendar.name()); } aNewCalendarIds.push(oCalendar.id); } } }, this); if (this.calendars.count() === 0 && this.isPublic && this.needsToReload) { App.setTitle(Utils.i18n('CALENDAR/NO_CALENDAR_FOUND')); App.Api.showErrorByCode(0, Utils.i18n('CALENDAR/NO_CALENDAR_FOUND')); } this.needsToReload = false; this.calendars.expunge(aCalendarIds); _.each(aCalendarIds, function (sCalendarId){ oCalendar = this.calendars.getCalendarById(sCalendarId); if (oCalendar && oCalendar.eventsCount() > 0) { oCalendar.reloadEvents(); } }, this); this.getEvents(aCalendarIds); } else { this.setCalendarGridVisibility(); this.checkStarted(false); } }; /** * @param {Array} aCalendarIds */ CCalendarViewModel.prototype.getEvents = function (aCalendarIds) { if (aCalendarIds.length > 0) { // this.checkStarted(true); // if (aCalendarIds.length > 1) // { // this.$calendarGrid.find('.fc-view div').first().css('visibility', 'hidden'); // } App.Ajax.abortRequestByActionName('EventList'); App.Ajax.sendExt({ 'Action': 'EventList', 'CalendarIds': JSON.stringify(aCalendarIds), 'Start': this.startDateTime, 'End': this.endDateTime, 'IsPublic': this.isPublic ? 1 : 0, 'TimezoneOffset': moment().zone(), 'Timezone': window.jstz ? window.jstz.determine().name() : '' }, this.onEventsResponse, this); } else { this.setAutoReloadTimer(); this.checkStarted(false); } }; /** * @param {Object} oData * @param {Object} oParameters */ CCalendarViewModel.prototype.onEventsResponse = function (oData, oParameters) { var oCalendar = null, aCalendarIds = oParameters.CalendarIds ? JSON.parse(oParameters.CalendarIds) : [], aEvents = [] ; if (oData.Result) { _.each(oData.Result, function (oEventData) { oCalendar = this.calendars.getCalendarById(oEventData.calendarId); if (oCalendar) { aEvents.push(oEventData.id); var oEvent = oCalendar.eventExists(oEventData.id); if (Utils.isUnd(oEvent)) { oCalendar.addEvent(oEventData); } else if (oEvent.lastModified !== oEventData.lastModified) { oCalendar.updateEvent(oEventData); } } }, this); _.each(aCalendarIds, function (sCalendarId){ oCalendar = this.calendars.getCalendarById(sCalendarId); if (oCalendar && oCalendar.eventsCount() > 0 && oCalendar.active()) { oCalendar.expungeEvents(aEvents, this.startDateTime, this.endDateTime); } }, this); this.refreshView(); } // this.setCalendarGridVisibility(); this.setAutoReloadTimer(); this.checkStarted(false); }; CCalendarViewModel.prototype.setCalendarGridVisibility = function () { this.$calendarGrid .css('visibility', '') .find('.fc-view div') .first() .css('visibility', '') ; }; CCalendarViewModel.prototype.getUnusedColor = function () { var colors = _.difference(this.colors, this.calendars.getColors()) ; return (colors.length > 0) ? colors[0] : this.colors[0]; }; CCalendarViewModel.prototype.openCreateCalendarForm = function () { if (!this.isPublic) { var oCalendar = new CCalendarModel() ; oCalendar.color(this.getUnusedColor()); App.Screens.showPopup(CalendarPopup, [_.bind(this.createCalendar, this), this.colors, oCalendar]); } }; /** * @param {string} sName * @param {string} sDescription * @param {string} sColor */ CCalendarViewModel.prototype.createCalendar = function (sName, sDescription, sColor) { if (!this.isPublic) { App.Ajax.send({ 'Name': sName, 'Description': sDescription, 'Color': sColor, 'Action': 'CalendarCreate' }, this.onCalendarCreateResponse, this ); } }; /** * @param {Object} oData * @param {Object} oParameters */ CCalendarViewModel.prototype.onCalendarCreateResponse = function (oData, oParameters) { if (oData.Result) { this.calendars.parseAndAddCalendar(oData.Result); this.calendars.sort(); } }; /** * @param {Object} oCalendar */ CCalendarViewModel.prototype.openImportCalendarForm = function (oCalendar) { if (!this.isPublic) { App.Screens.showPopup(CalendarImportPopup, [_.bind(this.reloadAll, this), oCalendar]); } }; /** * @param {Object} oCalendar */ CCalendarViewModel.prototype.openUpdateCalendarForm = function (oCalendar) { if (!this.isPublic) { App.Screens.showPopup(CalendarPopup, [_.bind(this.updateCalendar, this), this.colors, oCalendar]); } }; /** * @param {string} sName * @param {string} sDescription * @param {string} sColor * @param {string} sId */ CCalendarViewModel.prototype.updateCalendar = function (sName, sDescription, sColor, sId) { if (!this.isPublic) { App.Ajax.send({ 'Name': sName, 'Description': sDescription, 'Color': sColor, 'Id': sId, 'Action': 'CalendarUpdate' }, this.onCalendarUpdateResponse, this ); } }; /** * @param {Object} oData * @param {Object} oParameters */ CCalendarViewModel.prototype.onCalendarUpdateResponse = function (oData, oParameters) { var oCalendar = null ; if (oData.Result) { oCalendar = this.calendars.getCalendarById(oParameters.Id); if (oCalendar) { oCalendar.name(oParameters.Name); oCalendar.description(oParameters.Description); oCalendar.color(oParameters.Color); this.refetchEvents(); } } }; /** * @param {string} sColor * @param {string} sId */ CCalendarViewModel.prototype.updateCalendarColor = function (sColor, sId) { if (!this.isPublic) { App.Ajax.send({ 'Color': sColor, 'Id': sId, 'Action': 'CalendarUpdateColor' }, this.onCalendarUpdateColorResponse, this ); } }; /** * @param {Object} oData * @param {Object} oParameters */ CCalendarViewModel.prototype.onCalendarUpdateColorResponse = function (oData, oParameters) { if (oData.Result) { var oCalendar = this.calendars.getCalendarById(oParameters.Id); if (oCalendar) { oCalendar.color(oParameters.Color); this.refetchEvents(); } } }; /** * @param {Object} oCalendar */ CCalendarViewModel.prototype.openGetLinkCalendarForm = function (oCalendar) { if (!this.isPublic) { App.Screens.showPopup(CalendarGetLinkPopup, [_.bind(this.publicCalendar, this), oCalendar]); } }; /** * @param {Object} oCalendar */ CCalendarViewModel.prototype.openShareCalendarForm = function (oCalendar) { if (!this.isPublic) { App.Screens.showPopup(CalendarSharePopup, [_.bind(this.shareCalendar, this), oCalendar]); } }; /** * @param {string} sId * @param {boolean} bIsPublic * @param {Array} aShares * @param {boolean} bShareToAll * @param {number} iShareToAllAccess */ CCalendarViewModel.prototype.shareCalendar = function (sId, bIsPublic, aShares, bShareToAll, iShareToAllAccess) { if (!this.isPublic) { App.Ajax.send({ 'Action': 'CalendarShareUpdate', 'Id': sId, 'IsPublic': bIsPublic ? 1 : 0, 'Shares': JSON.stringify(aShares), 'ShareToAll': bShareToAll ? 1 : 0, 'ShareToAllAccess': iShareToAllAccess }, this.onCalendarShareUpdateResponse, this ); } }; /** * @param {Object} oData * @param {Object} oParameters */ CCalendarViewModel.prototype.onCalendarShareUpdateResponse = function (oData, oParameters) { if (oData.Result) { var oCalendar = this.calendars.getCalendarById(oParameters.Id); if (oCalendar) { oCalendar.shares(JSON.parse(oParameters.Shares)); if (oParameters.ShareToAll === 1) { oCalendar.isShared(true); oCalendar.isSharedToAll(true); oCalendar.sharedToAllAccess = oParameters.ShareToAllAccess; } else { // oCalendar.isShared(false); oCalendar.isSharedToAll(false); } } } }; /** * @param {string} sId * @param {boolean} bIsPublic */ CCalendarViewModel.prototype.publicCalendar = function (sId, bIsPublic) { if (!this.isPublic) { App.Ajax.send({ 'Action': 'CalendarPublicUpdate', 'Id': sId, 'IsPublic': bIsPublic ? 1 : 0 }, this.onCalendarPublicUpdateResponse, this ); } }; /** * @param {Object} oData * @param {Object} oParameters */ CCalendarViewModel.prototype.onCalendarPublicUpdateResponse = function (oData, oParameters) { if (oData.Result) { var oCalendar = this.calendars.getCalendarById(oParameters.Id); if (oCalendar) { oCalendar.isPublic(oParameters.IsPublic); } } }; /** * @param {string} sId */ CCalendarViewModel.prototype.deleteCalendar = function (sId) { var oCalendar = this.calendars.getCalendarById(sId), sConfirm = oCalendar ? Utils.i18n('CALENDAR/CONFIRM_REMOVE_CALENDAR', {'CALENDARNAME': oCalendar.name()}) : '', fRemove = _.bind(function (bRemove) { if (bRemove) { App.Ajax.send({ 'Id': sId, 'Action': 'CalendarDelete' }, this.onCalendarDeleteResponse, this ); } }, this) ; if (!this.isPublic && oCalendar) { App.Screens.showPopup(ConfirmPopup, [sConfirm, fRemove]); } }; /** * @param {Object} oData * @param {Object} oParameters */ CCalendarViewModel.prototype.onCalendarDeleteResponse = function (oData, oParameters) { if (oData.Result) { var oCalendar = this.calendars.getCalendarById(oParameters.Id); if (oCalendar && !oCalendar.isDefault) { if (this.calendars.currentCal().id === oCalendar.id) { this.calendars.currentCal(null); } this.calendars.removeCalendar(oCalendar.id); this.refetchEvents(); } } }; CCalendarViewModel.prototype.onEventDragStart = function () { this.dragEventTrigger = true; this.refreshDatePicker(); }; CCalendarViewModel.prototype.onEventDragStop = function () { var self = this; this.dragEventTrigger = false; if (this.delayOnEventResult && this.delayOnEventResultData && 0 < this.delayOnEventResultData.length) { this.delayOnEventResult = false; _.each(this.delayOnEventResultData, function (aData) { self.onEventActionResponse(aData[0], aData[1], false); }); this.delayOnEventResultData = []; this.refreshView(); } else { this.refreshDatePicker(); } }; CCalendarViewModel.prototype.onEventResizeStart = function () { this.dragEventTrigger = true; }; CCalendarViewModel.prototype.onEventResizeStop = function () { var self = this; this.dragEventTrigger = false; if (this.delayOnEventResult && this.delayOnEventResultData && 0 < this.delayOnEventResultData.length) { this.delayOnEventResult = false; _.each(this.delayOnEventResultData, function (aData) { self.onEventActionResponse(aData[0], aData[1], false); }); this.delayOnEventResultData = []; this.refreshView(); } else { this.refreshDatePicker(); } }; CCalendarViewModel.prototype.createEventInCurrentCalendar = function () { this.createEventToday(this.calendars.currentCal()); }; /** * @param {string} sCalendarId */ CCalendarViewModel.prototype.createEventInCalendar = function (sCalendarId) { this.createEventToday(this.calendars.getCalendarById(sCalendarId)); }; /** * @param {Object} oCalendar */ CCalendarViewModel.prototype.createEventToday = function (oCalendar) { var oToday = this.getFCObject().moment(); if (oToday.minutes() > 30) { oToday.add('minutes', 60 - oToday.minutes()); } else { oToday.minutes(30); } oToday .seconds(0) .milliseconds(0); this.openEventPopup(oCalendar, oToday, oToday.clone().add('minutes', 30), false); }; /** * @param {Object} oEventData */ CCalendarViewModel.prototype.getParamsFromEventData = function (oEventData) { return { id: oEventData.id, uid: oEventData.uid, calendarId: oEventData.calendarId, newCalendarId: !Utils.isUnd(oEventData.newCalendarId) ? oEventData.newCalendarId : oEventData.calendarId, subject: oEventData.subject, allDay: oEventData.allDay ? 1 : 0, location: oEventData.location, description: oEventData.description, alarms: oEventData.alarms ? JSON.stringify(oEventData.alarms) : '[]', attendees: oEventData.attendees ? JSON.stringify(oEventData.attendees) : '[]', owner: oEventData.owner, recurrenceId: oEventData.recurrenceId, excluded: oEventData.excluded, allEvents: oEventData.allEvents, modified: oEventData.modified ? 1 : 0, start: oEventData.start.local().toDate(), end: oEventData.end.local().toDate(), startTS: oEventData.start.unix(), endTS: oEventData.end ? oEventData.end.unix() : oEventData.end.unix(), rrule: oEventData.rrule ? JSON.stringify(oEventData.rrule) : null }; }; /** * @param {Array} aParameters */ CCalendarViewModel.prototype.getEventDataFromParams = function (aParameters) { var oEventData = aParameters; oEventData.alarms = aParameters.alarms ? JSON.parse(aParameters.alarms) : []; oEventData.attendees = aParameters.attendees ? JSON.parse(aParameters.attendees) : []; if(aParameters.rrule) { oEventData.rrule = JSON.parse(aParameters.rrule); } return oEventData; }; /** * @param {Object} oStart * @param {Object} oEnd */ CCalendarViewModel.prototype.createEventFromGrid = function (oStart, oEnd) { var bAllDay = !oStart.hasTime() ; this.openEventPopup(this.calendars.currentCal(), oStart.local(), oEnd.local(), bAllDay); }; /** * @param {Object} oCalendar * @param {Object} oStart * @param {Object} oEnd * @param {boolean} bAllDay */ CCalendarViewModel.prototype.openEventPopup = function (oCalendar, oStart, oEnd, bAllDay) { if (!this.isPublic) { App.Screens.showPopup(CalendarEventPopup, [{ CallbackSave: _.bind(this.createEvent, this), CallbackDelete: _.bind(this.deleteEvent, this), FCMoment: this.getFCObject().moment, Calendars: this.calendars, SelectedCalendar: oCalendar.id, Start: oStart, End: oEnd, AllDay: bAllDay, TimeFormat: this.timeFormat, DateFormat: this.dateFormat, CallbackAttendeeActionDecline: _.bind(this.attendeeActionDecline, this)/*, Owner: oSelectedCalendar.owner()*/ }]); } }; /** * @param {Object} oEventData */ CCalendarViewModel.prototype.createEvent = function (oEventData) { var aParameters = this.getParamsFromEventData(oEventData) ; if (!this.isPublic) { aParameters.calendarId = oEventData.newCalendarId; aParameters.selectStart = this.getDateFromCurrentView('start'); aParameters.selectEnd = this.getDateFromCurrentView('end'); aParameters.Action = 'EventCreate'; App.Ajax.send(aParameters, this.onEventActionResponseWithSubThrottle, this); } }; /** * @param {Object} oEventData */ CCalendarViewModel.prototype.eventClickCallback = function (oEventData) { var /** * @param {number} iResult */ fCallback = _.bind(function (iResult) { var oParams = { ID: oEventData.id, Uid: oEventData.uid, RecurrenceId: oEventData.recurrenceId, Calendars: this.calendars, SelectedCalendar: oEventData.calendarId, AllDay: oEventData.allDay, Location: oEventData.location, Description: oEventData.description, Subject: oEventData.subject, Alarms: oEventData.alarms, Attendees: oEventData.attendees, RRule: oEventData.rrule ? oEventData.rrule : null, Excluded: oEventData.excluded ? oEventData.excluded : false, Owner: oEventData.owner, Appointment: oEventData.appointment, OwnerName: oEventData.ownerName, TimeFormat: this.timeFormat, DateFormat: this.dateFormat, AllEvents: iResult, CallbackSave: _.bind(this.updateEvent, this), CallbackDelete: _.bind(this.deleteEvent, this), CallbackAttendeeActionDecline: _.bind(this.attendeeActionDecline, this) } ; if (iResult !== Enums.CalendarEditRecurrenceEvent.None) { if (iResult === Enums.CalendarEditRecurrenceEvent.AllEvents && oEventData.rrule) { oParams.Start = moment.unix(oEventData.rrule.startBase); oParams.End = moment.unix(oEventData.rrule.endBase); } else { oParams.Start = oEventData.start.clone(); oParams.Start = oParams.Start.local(); oParams.End = oEventData.end.clone(); oParams.End = oParams.End.local(); } App.Screens.showPopup(CalendarEventPopup, [oParams]); } }, this) ; if (oEventData.rrule) { if (oEventData.excluded) { fCallback(Enums.CalendarEditRecurrenceEvent.OnlyThisInstance); } else { App.Screens.showPopup(CalendarEditRecurrenceEventPopup, [fCallback]); } } else { fCallback(Enums.CalendarEditRecurrenceEvent.AllEvents); } }; /** * @param {string} sAction * @param {Object} oParameters * @param {Function=} fRevertFunc = undefined */ CCalendarViewModel.prototype.eventAction = function (sAction, oParameters, fRevertFunc) { var oCalendar = this.calendars.getCalendarById(oParameters.calendarId); if (oCalendar.access() === Enums.CalendarAccess.Read) { if (fRevertFunc) { fRevertFunc(); } } else { if (!this.isPublic) { if (fRevertFunc) { this.revertFunction = fRevertFunc; } oParameters.Action = sAction; App.Ajax.send( oParameters, this.onEventActionResponseWithSubThrottle, this ); } } }; /** * @param {Object} oEventData */ CCalendarViewModel.prototype.updateEvent = function (oEventData) { var oParameters = this.getParamsFromEventData(oEventData) ; oParameters.selectStart = this.getDateFromCurrentView('start'); oParameters.selectEnd = this.getDateFromCurrentView('end'); if (oEventData.modified) { this.calendars.setDefault(oEventData.newCalendarId); this.eventAction('EventUpdate', oParameters); } }; /** * @param {Object} oEventData * @param {number} dayDelta * @param {number} minuteDelta * @param {boolean} allDay * @param {Function} revertFunc */ CCalendarViewModel.prototype.moveEvent = function (oEventData, delta, revertFunc) { /* oEventData.dayDelta = dayDelta ? dayDelta : 0; oEventData.minuteDelta = minuteDelta ? minuteDelta : 0; */ var oParameters = this.getParamsFromEventData(oEventData) // iNewStart = oParameters.startTimestamp, // iAllEvStart, // iAllEvEnd, // sConfirm = Utils.i18n('With drag-n-drop you can change the date of this single instance only. To alter the entire series, open the event and change its date.'), // fConfirm = _.bind(function (bConfirm) { // if (bConfirm) // { // oParameters.allEvents = Enums.CalendarEditRecurrenceEvent.OnlyThisInstance; // this.eventAction('EventUpdate', oParameters, revertFunc); // } // else if (revertFunc) // { // revertFunc(); // } // }, this) ; oParameters.selectStart = this.getDateFromCurrentView('start'); oParameters.selectEnd = this.getDateFromCurrentView('end'); if (!this.isPublic) { if (oParameters.rrule) { revertFunc(false); /* iAllEvStart = JSON.parse(oParameters.rrule).startBase; iAllEvEnd = JSON.parse(oParameters.rrule).until; if (iAllEvStart <= iNewStart && iNewStart <= iAllEvEnd) { if (oParameters.excluded) { oParameters.allEvents = Enums.CalendarEditRecurrenceEvent.OnlyThisInstance; this.eventAction('EventUpdate', oParameters, revertFunc); } else { App.Screens.showPopup(ConfirmPopup, [sConfirm, fConfirm, '', 'Update this instance']); } } else { revertFunc(false); } */ } else { oParameters.allEvents = Enums.CalendarEditRecurrenceEvent.AllEvents; this.eventAction('EventUpdate', oParameters, revertFunc); } } }; /** * @param {Object} oEventData * @param {number} dayDelta, * @param {number} minuteDelta, * @param {Function} revertFunc */ CCalendarViewModel.prototype.resizeEvent = function (oEventData, delta, revertFunc) { var oParameters = this.getParamsFromEventData(oEventData), /** * @param {number} iResult */ fCallback = _.bind(function (iResult) { if (iResult !== Enums.CalendarEditRecurrenceEvent.None) { // if (iResult === Enums.CalendarEditRecurrenceEvent.AllEvents) // { // // } oParameters.allEvents = iResult; this.eventAction('EventUpdate', oParameters, revertFunc); } else { revertFunc(); } }, this) ; oParameters.selectStart = this.getDateFromCurrentView('start'); oParameters.selectEnd = this.getDateFromCurrentView('end'); if (oEventData.rrule) { if (oParameters.excluded) { fCallback(Enums.CalendarEditRecurrenceEvent.OnlyThisInstance); } else { App.Screens.showPopup(CalendarEditRecurrenceEventPopup, [fCallback]); } } else { fCallback(Enums.CalendarEditRecurrenceEvent.AllEvents); } }; /** * @param {Object} oEventData */ CCalendarViewModel.prototype.deleteEvent = function (oEventData) { this.eventAction('EventDelete', this.getParamsFromEventData(oEventData)); }; /** * @param {Object} oData * @param {Object} oParameters */ CCalendarViewModel.prototype.onEventActionResponseWithSubThrottle = function (oData, oParameters) { if (this.dragEventTrigger) { this.delayOnEventResult = true; this.delayOnEventResultData.push([oData, oParameters]); } else { this.onEventActionResponse(oData, oParameters); } }; /** * @param {Object} oData * @param {Object} oParameters * @param {boolean=} bDoRefresh */ CCalendarViewModel.prototype.onEventActionResponse = function (oData, oParameters, bDoRefresh) { var oCalendar = this.calendars.getCalendarById(oParameters.calendarId), oEventData = null, oEvent = null ; bDoRefresh = Utils.isUnd(bDoRefresh) ? true : !!bDoRefresh; if (oData && oData.Result && !Utils.isUnd(oCalendar)) { if (oParameters.Action === 'EventCreate' || oParameters.Action === 'EventUpdate') { this.customscrollTop(parseInt($('.calendar .scroll-inner').scrollTop(), 10)); oEvent = oCalendar.getEvent(oParameters.id); if (((!Utils.isUnd(oEvent) && !Utils.isUnd(oEvent.rrule)) || oParameters.rrule) && oParameters.allEvents === Enums.CalendarEditRecurrenceEvent.AllEvents) { oCalendar.removeEventByUid(oParameters.uid, true); } else { oCalendar.removeEvent(oParameters.id); } if (oParameters.newCalendarId && oParameters.newCalendarId !== oParameters.calendarId) { oCalendar = this.calendars.getCalendarById(oParameters.newCalendarId); } _.each(oData.Result.Events, function (oEventData) { oCalendar.addEvent(oEventData); }, this); oCalendar.cTag = oData.Result.CTag; if (!oCalendar.active()) { oCalendar.active(true); } if (bDoRefresh) { this.refreshView(); } this.customscrollTop.valueHasMutated(); this.calendars.currentCal(oCalendar); } else if (oParameters.Action === 'EventDelete') { oCalendar.cTag = oData.Result; if(oParameters.allEvents === Enums.CalendarEditRecurrenceEvent.OnlyThisInstance) { oCalendar.removeEvent(oParameters.id); } else { oCalendar.removeEventByUid(oParameters.uid); } if (bDoRefresh) { this.refreshView(); } } else if (oParameters.Action === 'EventBase') { oEventData = oData.Result; App.Screens.showPopup(CalendarEventPopup, [{ CallbackSave: _.bind(this.updateEvent, this), CallbackDelete: _.bind(this.deleteEvent, this), ID: oEventData.id, Uid: oEventData.uid, RecurrenceId: oEventData.recurrenceId, Calendars: this.calendars, SelectedCalendar: oEventData.calendarId, Start: moment(oEventData.start * 1000), End: moment(oEventData.end * 1000), AllDay: oEventData.allDay, Location: oEventData.location, Description: oEventData.description, Subject: oEventData.subject, Alarms: oEventData.alarms, Attendees: oEventData.attendees, RRule: oEventData.rrule ? oEventData.rrule : null, Excluded: oEventData.excluded ? oEventData.excluded : false, Owner: oEventData.owner, Appointment: oEventData.appointment, TimeFormat: this.timeFormat, DateFormat: this.dateFormat, AllEvents: Enums.CalendarEditRecurrenceEvent.AllEvents }]); } } else if (oParameters.Action === 'EventUpdate' && !oData.Result && 1155 === Utils.pInt(oData.ErrorCode)) { this.revertFunction = null; } else if (this.revertFunction) { this.revertFunction(); } this.revertFunction = null; }; /** * @param {Object} oCalendar * @param {string} sId */ CCalendarViewModel.prototype.attendeeActionDecline = function (oCalendar, sId) { oCalendar.removeEvent(sId); this.refreshView(); }; CCalendarViewModel.prototype.refetchEvents = function () { this.$calendarGrid.fullCalendar('refetchEvents'); }; CCalendarViewModel.prototype.refreshViewSingle = function () { this.refetchEvents(); this.refreshDatePicker(); }; CCalendarViewModel.prototype.refreshView = function () {}; CCalendarViewModel.prototype.onDrop = function (oFile, oEvent, fProceedUploading) { var aEditableCalendars = _.filter( this.calendars.collection(), function(oItem){ return oItem.isEditable(); } ); if (aEditableCalendars.length > 1) { App.Screens.showPopup(CalendarSelectCalendarsPopup, [{ CallbackSave: _.bind(this.uploadToSelectedCalendar, this), ProceedUploading: fProceedUploading, Calendars: this.calendars, EditableCalendars: aEditableCalendars, DefaultCalendarId: this.defaultCalendarId() }]); } else { this.uploadToSelectedCalendar(this.defaultCalendarId(), fProceedUploading); } }; CCalendarViewModel.prototype.onUploadComplete = function () { this.reloadAll(); }; /** * Initializes file uploader. */ CCalendarViewModel.prototype.initUploader = function () { var self = this ; if (this.uploaderArea()) { this.oJua = new Jua({ 'action': '?/Upload/Calendars/', 'name': 'jua-uploader', 'queueSize': 2, 'dragAndDropElement': this.uploaderArea(), 'disableAjaxUpload': false, 'disableFolderDragAndDrop': false, 'disableDragAndDrop': false, 'disableAutoUploadOnDrop': true, 'hidden': { 'Token': function () { return AppData.Token; }, 'AccountID': function () { return AppData.Accounts.currentId(); }, 'AdditionalData': function () { return JSON.stringify({ 'CalendarID': self.uploadCalendarId() }); } } }); this.oJua .on('onDrop', _.bind(this.onDrop, this)) .on('onBodyDragEnter', _.bind(this.bDragActive, this, true)) .on('onBodyDragLeave', _.bind(this.bDragActive, this, false)) .on('onComplete', _.bind(this.onUploadComplete, this)) ; } }; CCalendarViewModel.prototype.uploadToSelectedCalendar = function (selectedCalendarId, fProceedUploading) { this.uploadCalendarId(selectedCalendarId); this.checkStarted(true); fProceedUploading(); }; /** * @constructor */ function CFileStorageViewModel() { this.allowWebMail = !!(AppData.App && AppData.App.AllowWebMail); this.loaded = ko.observable(false); this.isPublic = bExtApp; this.publicHash = bExtApp ? AppData.FileStoragePubHash : ''; this.IsCollaborationSupported = AppData.User.IsCollaborationSupported; this.AllowFilesSharing = AppData.User.AllowFilesSharing; this.storages = ko.observableArray(); this.folders = ko.observableArray(); this.files = ko.observableArray(); this.uploadingFiles = ko.observableArray(); this.selected = ko.observable(false); this.rootPath = ko.observable(Utils.i18n('FILESTORAGE/TAB_PERSONAL_FILES')); this.storageType = ko.observable(Enums.FileStorageType.Personal); this.storageType.subscribe(function () { var oStorage = null ; if (this.isPublic) { this.rootPath(AppData.FileStoragePubParams.Name); } else { oStorage = this.getStorageByType(this.storageType()); if (oStorage) { this.rootPath(oStorage.displayName()); } } this.selector.listCheckedAndSelected(false); }, this); this.iPathIndex = ko.observable(-1); this.pathItems = ko.observableArray(); this.dropPath = ko.observable(''); this.path = ko.computed(function () { var aPath = _.map(this.pathItems(), function (oItem) { return oItem.id(); }); return aPath.join('/'); }, this); this.path.subscribe(function (value) { this.dropPath(value); }, this); this.collection = ko.computed(function () { var files = _.union(this.files(), this.getUploadingFiles()); files.sort(function(left, right) { return left.fileName() === right.fileName() ? 0 : (left.fileName() < right.fileName() ? -1 : 1); }); return _.union(this.folders(), files); }, this); this.columnCount = ko.observable(1); this.selector = new CSelector(this.collection, null, _.bind(this.onItemDelete, this), _.bind(this.onItemDblClick, this), _.bind(this.onEnter, this), this.columnCount, true, true, true); this.searchPattern = ko.observable(''); this.isSearchFocused = ko.observable(false); this.renameCommand = Utils.createCommand(this, this.executeRename, function () { var items = this.selector.listCheckedAndSelected(); return (1 === items.length && !items[0].isLink()); }); this.deleteCommand = Utils.createCommand(this, this.executeDelete, function () { var items = this.selector.listCheckedAndSelected(); return (0 < items.length); }); this.downloadCommand = Utils.createCommand(this, this.executeDownload, function () { var items = this.selector.listCheckedAndSelected(); return (1 === items.length && !items[0].isFolder()); }); this.shareCommand = Utils.createCommand(this, this.executeShare, function () { var items = this.selector.listCheckedAndSelected(); return (1 === items.length && !items[0].isLink()); }); this.sendCommand = Utils.createCommand(this, this.executeSend, function () { var aItems = this.selector.listCheckedAndSelected(), aFileItems = _.filter(aItems, function (oItem) { return !oItem.isFolder(); }, this) ; return (aFileItems.length > 0); }); this.uploaderButton = ko.observable(null); this.uploaderArea = ko.observable(null); this.bDragActive = ko.observable(false);//.extend({'throttle': 1}); // this.bDragActive.subscribe(function () { // if (this.searchPattern() !== '') // { // this.bDragActive(false); // } // }, this); this.bDragActiveComp = ko.computed(function () { var bDrag = this.bDragActive(); return bDrag && this.searchPattern() === ''; }, this); this.uploadError = ko.observable(false); this.quota = ko.observable(0); this.used = ko.observable(0); this.quotaDesc = ko.observable(''); this.quotaProc = ko.observable(-1); ko.computed(function () { if (!AppData.App || AppData.App && !AppData.App.ShowQuotaBar) { return true; } var iQuota = this.quota(), iUsed = this.used(), iProc = 0 < iQuota ? Math.ceil((iUsed / iQuota) * 100) : -1; iProc = 100 < iProc ? 100 : iProc; this.quotaProc(iProc); this.quotaDesc(-1 < iProc ? Utils.i18n('MAILBOX/QUOTA_TOOLTIP', { 'PROC': iProc, 'QUOTA': Utils.friendlySize(iQuota) }) : ''); return true; }, this); this.dragover = ko.observable(false); this.loading = ko.observable(false); this.loadedFiles = ko.observable(false); this.fileListInfoText = ko.computed(function () { var infoText = ''; if (this.loading()) { infoText = Utils.i18n('FILESTORAGE/INFO_LOADING'); } else if (this.loadedFiles()) { if (this.collection().length === 0) { if (this.isPublic) { infoText = Utils.i18n('FILESTORAGE/INFO_PUBLIC_FOLDER_NOT_EXIST'); } else { if (this.searchPattern() !== '' || this.isPublic) { infoText = Utils.i18n('FILESTORAGE/INFO_NO_ITEMS_FOUND'); } else { if (this.path() !== '' || this.isPopup) { infoText = Utils.i18n('FILESTORAGE/INFO_FOLDER_IS_EMPY'); } else { infoText = Utils.i18n('FILESTORAGE/INFO_FILESTORAGE_IS_EMTY'); } } } } } return infoText; }, this); this.dragAndDropHelperBinded = _.bind(this.dragAndDropHelper, this); this.isPopup = false; this.isCurrentStorageExternal = ko.computed(function () { var oStorage = this.getStorageByType(this.storageType()); return (oStorage && oStorage.isExternal()); }, this); this.timerId = null; } CFileStorageViewModel.prototype.__name = 'CFileStorageViewModel'; /** * @param {Object} $viewModel */ CFileStorageViewModel.prototype.onApplyBindings = function ($viewModel) { this.selector.initOnApplyBindings( '.items_sub_list .item', '.items_sub_list .selected.item', '.items_sub_list .item .custom_checkbox', $('.panel.files .items_list', $viewModel), $('.panel.files .items_list .files_scroll.scroll-inner', $viewModel) ); this.initUploader(); this.hotKeysBind(); }; CFileStorageViewModel.prototype.hotKeysBind = function () { var bIsFileStorageScreen = App.Screens.currentScreen() === Enums.Screens.FileStorage; $(document).on('keydown', _.bind(function(ev) { if (bIsFileStorageScreen && ev && ev.keyCode === Enums.Key.s && this.selector.useKeyboardKeys() && !Utils.isTextFieldFocused()) { ev.preventDefault(); this.isSearchFocused(true); } }, this)); }; /** * Initializes file uploader. */ CFileStorageViewModel.prototype.initUploader = function () { var self = this; if (this.uploaderButton() && this.uploaderArea()) { this.oJua = new Jua({ 'action': '?/Upload/File/', 'name': 'jua-uploader', 'queueSize': 2, 'clickElement': this.uploaderButton(), 'dragAndDropElement': this.uploaderArea(), 'disableAjaxUpload': this.isPublic ? true : false, 'disableFolderDragAndDrop': this.isPublic ? true : false, 'disableDragAndDrop': this.isPublic ? true : false, 'hidden': { 'Token': function () { return AppData.Token; }, 'AccountID': function () { return AppData.Accounts.currentId(); }, 'AdditionalData': function (oFile) { return JSON.stringify({ 'Type': self.storageType(), 'SubPath': oFile && !Utils.isUnd(oFile['Folder']) ? oFile['Folder'] : '', 'Path': self.dropPath() }); } } }); this.oJua .on('onProgress', _.bind(this.onFileUploadProgress, this)) .on('onSelect', _.bind(this.onFileUploadSelect, this)) .on('onStart', _.bind(this.onFileUploadStart, this)) .on('onDrop', _.bind(this.onDrop, this)) .on('onComplete', _.bind(this.onFileUploadComplete, this)) .on('onBodyDragEnter', _.bind(this.bDragActive, this, true)) .on('onBodyDragLeave', _.bind(this.bDragActive, this, false)) ; } }; /** * Creates new attachment for upload. * * @param {string} sFileUid * @param {Object} oFileData */ CFileStorageViewModel.prototype.onFileUploadSelect = function (sFileUid, oFileData) { if (AppData.App.FileSizeLimit > 0 && oFileData.Size/(1024*1024) > AppData.App.FileSizeLimit) { App.Screens.showPopup(AlertPopup, [ Utils.i18n('FILESTORAGE/ERROR_SIZE_LIMIT', {'SIZE': AppData.App.FileSizeLimit}) ]); return false; } if (this.searchPattern() === '') { var oFile = new CFileModel(), sFileName = oFileData.FileName, sFileNameExt = Utils.getFileExtension(sFileName), sFileNameWoExt = Utils.getFileNameWithoutExtension(sFileName), iIndex = 0, oAccount = AppData.Accounts.getDefault() ; if (sFileNameExt !== '') { sFileNameExt = '.' + sFileNameExt; } while (!Utils.isUnd(this.getFileByName(sFileName))) { sFileName = sFileNameWoExt + '_' + iIndex + sFileNameExt; iIndex++; } oFile.onUploadSelectOwn(sFileUid, oFileData, sFileName, oAccount.email(), this.path(), this.storageType()); this.uploadingFiles.push(oFile); } }; /** * Finds attachment by uid. Calls it's function to start upload. * * @param {string} sFileUid */ CFileStorageViewModel.prototype.onFileUploadStart = function (sFileUid) { var oFile = this.getUploadFileByUid(sFileUid); if (oFile) { oFile.onUploadStart(); } }; /** * Finds attachment by uid. Calls it's function to progress upload. * * @param {string} sFileUid * @param {number} iUploadedSize * @param {number} iTotalSize */ CFileStorageViewModel.prototype.onFileUploadProgress = function (sFileUid, iUploadedSize, iTotalSize) { if (this.searchPattern() === '') { var oFile = this.getUploadFileByUid(sFileUid); if (oFile) { oFile.onUploadProgress(iUploadedSize, iTotalSize); } } }; /** * Finds attachment by uid. Calls it's function to complete upload. * * @param {string} sFileUid * @param {boolean} bResponseReceived * @param {Object} oResult */ CFileStorageViewModel.prototype.onFileUploadComplete = function (sFileUid, bResponseReceived, oResult) { if (this.searchPattern() === '') { var oFile = this.getUploadFileByUid(sFileUid) ; if (oFile) { oFile.onUploadComplete(sFileUid, bResponseReceived, oResult); this.deleteUploadFileByUid(sFileUid); if (oFile.uploadError()) { this.uploadError(true); App.Api.showError(oFile.statusText()); } else { this.files.push(oFile); if (this.uploadingFiles().length === 0) { App.Api.showReport(Utils.i18n('COMPOSE/UPLOAD_COMPLETE')); } } } this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex()), this.searchPattern(), false); } }; /** * @param {Object} oFile * @param {Object} oEvent */ CFileStorageViewModel.prototype.onDrop = function (oFile, oEvent) { if (this.isPublic) { return; } if (oEvent && oEvent.target && this.searchPattern() === '') { var oFolder = ko.dataFor(oEvent.target); if (oFolder && oFolder instanceof CFileModel && oFolder.isFolder()) { this.dropPath(oFolder.fullPath()); } } else { App.Api.showReport(Utils.i18n('FILESTORAGE/INFO_CANNOT_UPLOAD_SEARCH_RESULT')); } }; /** * @param {Object} oFolder * @param {Object} oEvent * @param {Object} oUi */ CFileStorageViewModel.prototype.filesDrop = function (oFolder, oEvent, oUi) { if (this.isPublic) { return; } if (oFolder && oEvent) { var self = this, sFromPath = '', sToPath = oFolder.fullPath(), sAction = oEvent.ctrlKey ? 'FilesCopy' : 'FilesMove', aChecked = [], aItems = [] ; if (this.path() !== sToPath && this.storageType() === oFolder.storageType() || this.storageType() !== oFolder.storageType()) { oFolder.recivedAnim(true); Utils.uiDropHelperAnim(oEvent, oUi); aChecked = this.selector.listCheckedAndSelected(); aItems = _.map(aChecked, function (oItem) { if (!oEvent.ctrlKey) { if (!oItem.isFolder()) { self.deleteFileByName(oItem.id()); } else { self.deleteFolderByName(oItem.fileName()); } } sFromPath = oItem.path(); return { 'Name': oItem.id(), 'IsFolder': oItem.isFolder() }; }); App.Ajax.send({ 'Action': sAction, 'FromType': this.storageType(), 'ToType': oFolder.storageType(), 'FromPath': sFromPath, 'ToPath': sToPath, 'Files': JSON.stringify(aItems) }, this.onFilesMoveResponse, this ); } /* else { // TODO } */ } }; /** * @param {Object} oData * @param {Object} oParameters */ CFileStorageViewModel.prototype.onFilesMoveResponse = function (oData, oParameters) { this.getQuota(this.storageType()); }; /** * @param {Object} oFile */ CFileStorageViewModel.prototype.dragAndDropHelper = function (oFile) { if (oFile) { oFile.checked(true); } var oHelper = Utils.draggableMessages(), aItems = this.selector.listCheckedAndSelected(), nCount = aItems.length, nFilesCount = 0, nFoldersCount = 0, sText = ''; _.each(aItems, function (oItem) { if (oItem.isFolder()) { nFoldersCount++; } else { nFilesCount++; } }, this); if (nFilesCount !== 0 && nFoldersCount !== 0) { sText = Utils.i18n('FILESTORAGE/DRAG_ITEMS_TEXT_PLURAL', {'COUNT': nCount}, null, nCount); } else if (nFilesCount === 0) { sText = Utils.i18n('FILESTORAGE/DRAG_FOLDERS_TEXT_PLURAL', {'COUNT': nFoldersCount}, null, nFoldersCount); } else if (nFoldersCount === 0) { sText = Utils.i18n('FILESTORAGE/DRAG_TEXT_PLURAL', {'COUNT': nFilesCount}, null, nFilesCount); } $('.count-text', oHelper).text(sText); return oHelper; }; CFileStorageViewModel.prototype.onItemDelete = function () { this.executeDelete(); }; /** * @param {{isFolder:Function,path:Function,name:Function,isViewable:Function,viewFile:Function,downloadFile:Function}} oItem */ CFileStorageViewModel.prototype.onEnter = function (oItem) { this.onItemDblClick(oItem); }; /** * @param {{isFolder:Function,path:Function,name:Function,isViewable:Function,viewFile:Function,downloadFile:Function}} oItem */ CFileStorageViewModel.prototype.onItemDblClick = function (oItem) { if (oItem) { if (oItem.isFolder()) { this.getFiles(this.storageType(), oItem); } else { if (oItem.isViewable()) { oItem.viewFile(); } else { oItem.downloadFile(); } } } }; /** * @param {AjaxDefaultResponse} oData * @param {Object} oParameters */ CFileStorageViewModel.prototype.onFilesResponse = function (oData, oParameters) { if (oData.Result) { var aFolderList = [], aFileList = [], sThumbSessionUid = Date.now().toString() ; if (oData.Result.Quota) { this.quota(oData.Result.Quota[0] + oData.Result.Quota[1]); this.used(oData.Result.Quota[0]); } _.each(oData.Result.Items, function (oValue) { var oItem = new CFileModel() .allowDrag(true) .allowSelect(true) .allowCheck(true) .allowDelete(true) .allowUpload(true) .allowSharing(true) .allowHeader(true) .allowDownload(false) .isPopupItem(this.isPopup); oItem.parse(oValue, this.publicHash); oItem.getInThumbQueue(sThumbSessionUid); if (oItem.isFolder()) { aFolderList.push(oItem); } else { aFileList.push(oItem); } }, this); if (this.isPublic || oParameters.Type === this.storageType()) { this.folders(aFolderList); this.files(aFileList); } this.loading(false); this.loadedFiles(true); clearTimeout(this.timerId); } }; /** * @param {Object} oData * @param {Object} oParameters */ CFileStorageViewModel.prototype.onQuotaResponse = function (oData, oParameters) { if (oData.Result && oData.Result.Quota) { this.quota(oData.Result.Quota[0] + oData.Result.Quota[1]); this.used(oData.Result.Quota[0]); } }; /** * @param {Object} oData * @param {Object} oParameters */ CFileStorageViewModel.prototype.onFilesDeleteResponse = function (oData, oParameters) { if (oData.Result) { this.expungeFileItems(); } else { this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex()), this.searchPattern()); } }; CFileStorageViewModel.prototype.executeRename = function () { var aChecked = this.selector.listCheckedAndSelected() ; if (!this.isPublic && aChecked[0]) { App.Screens.showPopup(FileStorageRenamePopup, [aChecked[0], _.bind(this.renameItem, this)]); } }; CFileStorageViewModel.prototype.executeDownload = function () { var aChecked = this.selector.listCheckedAndSelected() ; if (aChecked[0] && !aChecked[0].isFolder()) { aChecked[0].downloadFile(); } }; CFileStorageViewModel.prototype.executeShare = function () { var aChecked = this.selector.listCheckedAndSelected() ; if (!this.isPublic && aChecked[0]) { App.Screens.showPopup(FileStorageSharePopup, [aChecked[0]]); } }; CFileStorageViewModel.prototype.executeSend = function () { var aItems = this.selector.listCheckedAndSelected(), aFileItems = _.filter(aItems, function (oItem) { return !oItem.isFolder(); }, this) ; if (aFileItems.length > 0) { App.Routing.goDirectly(App.Links.compose(), ['file', aFileItems]); } }; /** * @param {Object} oItem */ CFileStorageViewModel.prototype.onShareIconClick = function (oItem) { if (oItem) { App.Screens.showPopup(FileStorageSharePopup, [oItem]); } }; /** * @param {Object} oItem * @return {string} */ CFileStorageViewModel.prototype.renameItem = function (oItem) { var sName = Utils.trim(oItem.nameForEdit()); if (!Utils.validateFileOrFolderName(sName)) { return oItem.isFolder() ? Utils.i18n('FILESTORAGE/INVALID_FOLDER_NAME') : Utils.i18n('FILESTORAGE/INVALID_FILE_NAME'); } else { App.Ajax.send({ 'Action': 'FilesRename', 'Type': this.storageType(), 'Path': oItem.path(), 'Name': oItem.id(), 'NewName': sName }, this.onFilesRenameResponse, this ); } return ''; }; /** * @param {Object} oData * @param {Object} oParameters */ CFileStorageViewModel.prototype.onFilesRenameResponse = function (oData, oParameters) { this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex()), this.searchPattern()); }; CFileStorageViewModel.prototype.executeDelete = function () { var aChecked = this.selector.listCheckedAndSelected() ; if (!this.isPublic && aChecked && aChecked.length > 0) { App.Screens.showPopup(ConfirmPopup, [Utils.i18n('FILESTORAGE/CONFIRMATION_DELETE'), _.bind(this.deleteItems, this, aChecked)]); } }; CFileStorageViewModel.prototype.onShow = function () { // if (!this.loaded() || this.isPopup) // { this.loaded(true); this.getStorages(); // } this.selector.useKeyboardKeys(true); if (this.oJua) { this.oJua.setDragAndDropEnabledStatus(true); } }; CFileStorageViewModel.prototype.onHide = function () { this.selector.useKeyboardKeys(false); if (this.oJua) { this.oJua.setDragAndDropEnabledStatus(false); } }; /** * @param {number} iType */ CFileStorageViewModel.prototype.getQuota = function (iType) { App.Ajax.send({ 'Action': 'FilesQuota', 'Type': iType }, this.onQuotaResponse, this ); }; CFileStorageViewModel.prototype.getStorageByType = function (storageType) { return _.find(this.storages(), function(oStorageItem){ return oStorageItem.storageType() === storageType; }); }; CFileStorageViewModel.prototype.getStorages = function () { // this.storages.removeAll(); if (!this.isPublic) { if (!this.getStorageByType(Enums.FileStorageType.Personal)) { this.storages.push( new CFileModel() .isFolder(true) .storageType(Enums.FileStorageType.Personal) .displayName(Utils.i18n('FILESTORAGE/TAB_PERSONAL_FILES')) ); } if (this.IsCollaborationSupported) { if (!this.getStorageByType(Enums.FileStorageType.Corporate)) { this.storages.push( new CFileModel() .isFolder(true) .storageType(Enums.FileStorageType.Corporate) .displayName(Utils.i18n('FILESTORAGE/TAB_CORPORATE_FILES')) ); } if (this.AllowFilesSharing) { if (!this.getStorageByType(Enums.FileStorageType.Shared)) { this.storages.push( new CFileModel() .isFolder(true) .storageType(Enums.FileStorageType.Shared) .displayName(Utils.i18n('FILESTORAGE/TAB_SHARED_FILES')) ); } } } if (!this.isPopup) { this.getExternalFileStorages(); } else { this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex())); } } else { this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex())); } }; CFileStorageViewModel.prototype.getExternalFileStorages = function () { App.Ajax.send({ 'Action': 'ExternalFileStorages' }, this.onExternalStoragesResponse, this ); }; CFileStorageViewModel.prototype.onExternalStoragesResponse = function (oData, oParameters) { if (oData.Result) { _.each(oData.Result, function(oStorage){ if (!this.getStorageByType(oStorage.Type)) { this.storages.push( new CFileModel() .isExternal(true) .isFolder(true) .storageType(oStorage.Type) .displayName(oStorage.DisplayName) ); } }, this); this.expungeExternalStorages(_.map(oData.Result, function(oStorage){ return oStorage.Type; }, this)); } if (!this.getStorageByType(this.storageType())) { this.storageType(Enums.FileStorageType.Personal); } this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex())); }; /** * @param {number} iType * @param {object=} oPath = '' * @param {string=} sPattern = '' * @param {boolean=} bLoading = true */ CFileStorageViewModel.prototype.getFiles = function (iType, oPath, sPattern, bLoading) { var self = this, iTypePrev = this.storageType(), iPathIndex = this.iPathIndex(), oFolder = new CFileModel() .isFolder(true) .storageType(iType) ; if (this.isPublic) { return this.getFilesPub(oPath); } this.storageType(iType); self.loadedFiles(false); if (Utils.isUnd(bLoading) || !Utils.isUnd(bLoading) && bLoading) { this.timerId = setTimeout(function() { if (!self.loadedFiles()) { self.folders([]); self.files([]); self.loading(true); } }, 1500); } this.searchPattern(Utils.isUnd(sPattern) ? '' : Utils.pString(sPattern)); if (Utils.isUnd(oPath) || oPath.id() === '') { this.pathItems.removeAll(); oFolder.displayName(this.rootPath()); } else { oFolder = oPath; } this.pathItems.push(oFolder); this.iPathIndex(this.pathItems().length - 1); if (iPathIndex !== this.iPathIndex() || iTypePrev !== this.storageType()) { this.folders([]); this.files([]); } App.Ajax.sendExt({ 'Action': 'Files', 'Type': iType, 'Path': this.path(), 'Pattern': this.searchPattern() }, this.onFilesResponse, this ); }; /** * @param {string} sHash */ CFileStorageViewModel.prototype.getFilesPub = function (oPath) { var iPathIndex = this.iPathIndex(), oFolder = new CFileModel() .isFolder(true) ; if (Utils.isUnd(oPath) || oPath.id() === '') { this.pathItems.removeAll(); oFolder.displayName(this.rootPath()); } else { oFolder = oPath; } this.pathItems.push(oFolder); this.iPathIndex(this.pathItems().length - 1); if (iPathIndex !== this.iPathIndex()) { this.folders([]); this.files([]); } App.Ajax.sendExt({ 'Action': 'FilesPub', 'Hash': AppData.FileStoragePubHash, 'Path': this.path() }, this.onFilesResponse, this ); }; /** * @param {Array} aChecked * @param {boolean} bOkAnswer */ CFileStorageViewModel.prototype.deleteItems = function (aChecked, bOkAnswer) { if (bOkAnswer && 0 < aChecked.length) { var aItems = _.map(aChecked, function (oItem) { oItem.deleted(true); return { 'Path': oItem.path(), 'Name': oItem.id() }; }); App.Ajax.send({ 'Action': 'FilesDelete', 'Type': this.storageType(), 'Path': this.path(), 'Items': JSON.stringify(aItems) }, this.onFilesDeleteResponse, this ); } }; /** * @param {number} iIndex * * @return {string} */ CFileStorageViewModel.prototype.getPathItemByIndex = function (iIndex) { var oItem = this.pathItems()[iIndex], oResult = new CFileModel().fileName(this.rootPath()).id('') ; this.pathItems(this.pathItems().slice(0, iIndex)); if (oItem && !this.isPublic) { oResult = oItem; } return oResult; }; /** * @param {number} iIndex * * @return {string} */ CFileStorageViewModel.prototype.getFullPathByIndex = function (iIndex) { var aPath = _.map(this.pathItems().slice(0, iIndex), function (oItem){ return oItem.fileName(); }); return aPath.join('/'); }; /** * @param {string} sName * * @return {?} */ CFileStorageViewModel.prototype.getFileByName = function (sName) { return _.find(this.files(), function(oItem){ return oItem.id() === sName; }); }; /** * @param {string} sName */ CFileStorageViewModel.prototype.deleteFileByName = function (sName) { this.files(_.filter(this.files(), function (oItem) { return oItem.id() !== sName; })); }; /** * @param {string} sName */ CFileStorageViewModel.prototype.deleteFolderByName = function (sName) { this.folders(_.filter(this.folders(), function (oItem) { return oItem.fileName() !== sName; })); }; /** * @param {string} sName */ CFileStorageViewModel.prototype.expungeFileItems = function () { this.folders(_.filter(this.folders(), function(oFolder){ return !oFolder.deleted(); }, this)); this.files(_.filter(this.files(), function(oFile){ return !oFile.deleted(); }, this)); }; /** * @param {array} aStorageTypes */ CFileStorageViewModel.prototype.expungeExternalStorages = function (aStorageTypes) { this.storages(_.filter(this.storages(), function(oStorage){ return !oStorage.isExternal() || _.include(aStorageTypes, oStorage.storageType()); },this)); }; /** * @param {int} iType */ CFileStorageViewModel.prototype.deleteStorageByType = function (iType) { this.storages(_.filter(this.storages(), function (oItem) { return oItem.storageType() !== iType; })); }; /** * @param {string} sFileUid * * @return {?} */ CFileStorageViewModel.prototype.getUploadFileByUid = function (sFileUid) { return _.find(this.uploadingFiles(), function(oItem){ return oItem.uploadUid() === sFileUid; }); }; /** * @param {string} sFileUid */ CFileStorageViewModel.prototype.deleteUploadFileByUid = function (sFileUid) { this.uploadingFiles(_.filter(this.uploadingFiles(), function (oItem) { return oItem.uploadUid() !== sFileUid; })); }; /** * @return {Array} */ CFileStorageViewModel.prototype.getUploadingFiles = function () { var aResult = [], uploadingFiles = this.uploadingFiles(), self = this; if (!Utils.isUnd(uploadingFiles)) { aResult = _.filter(uploadingFiles, function(oItem){ return oItem.path() === self.path() && oItem.storageType() === self.storageType(); }); } return aResult; }; /** * @param {string} sFileUid */ CFileStorageViewModel.prototype.onCancelUpload = function (sFileUid) { if (this.oJua) { this.oJua.cancel(sFileUid); } this.deleteUploadFileByUid(sFileUid); }; /** * @param {Object} oData * @param {Object} oParameters */ CFileStorageViewModel.prototype.onCreateFolderResponse = function (oData, oParameters) { this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex())); }; /** * @param {string} sFolderName */ CFileStorageViewModel.prototype.createFolder = function (sFolderName) { sFolderName = Utils.trim(sFolderName); if (!Utils.validateFileOrFolderName(sFolderName)) { return Utils.i18n('FILESTORAGE/INVALID_FOLDER_NAME'); } else { App.Ajax.send({ 'Action': 'FilesFolderCreate', 'Type': this.storageType(), 'Path': this.path(), 'FolderName': sFolderName }, this.onCreateFolderResponse, this ); } return ''; }; CFileStorageViewModel.prototype.onCreateFolderClick = function () { App.Screens.showPopup(FileStorageFolderCreatePopup, [_.bind(this.createFolder, this)]); }; /** * @param {Object} oData * @param {Object} oParameters */ CFileStorageViewModel.prototype.onCreateLinkResponse = function (oData, oParameters) { this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex())); }; /** * @param {string} sFolderName */ CFileStorageViewModel.prototype.createLink = function (oFileItem) { App.Ajax.send({ 'Action': 'FilesLinkCreate', 'Type': this.storageType(), 'Path': this.path(), 'Link': oFileItem.linkUrl(), 'Name': oFileItem.fileName() }, this.onCreateLinkResponse, this ); }; CFileStorageViewModel.prototype.onCreateLinkClick = function () { var fCallBack = _.bind(this.createLink, this); App.Screens.showPopup(FileStorageLinkCreatePopup, [fCallBack]); }; CFileStorageViewModel.prototype.onSearch = function () { this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex()), this.searchPattern()); }; CFileStorageViewModel.prototype.clearSearch = function () { this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex())); }; /** * @constructor */ function CHelpdeskViewModel() { var self = this, fChangeStateHelper = function(state) { return function () { self.executeChangeState(state); self.isQuickReplyHidden(!self.bAgent); if (state === Enums.HelpdeskThreadStates.Resolved) { self.selectedItem(null); } }; } ; //use different ajax functions for different application this.bRtl = Utils.isRTL(); this.iAutoCheckTimer = 0; this.bExtApp = bExtApp; this.ajaxSendFunc = this.bExtApp ? 'sendExt' : 'send'; this.bAgent = AppData.User.IsHelpdeskAgent; this.singleMode = AppData.SingleMode; this.externalUrl = ko.observable(AppData.HelpdeskIframeUrl); this.loadingList = ko.observable(true); this.loadingViewPane = ko.observable(false); this.loadingMoreMessages = ko.observable(false); this.threads = ko.observableArray([]); this.posts = ko.observableArray([]); this.iPingInterval = -1; this.iPingStartTimer = -1; this.selectedItem = ko.observable(null); this.selectedItem.subscribe(function () { this.subject(this.selectedItem() ? (this.bExtApp ? this.selectedItem().sSubject : this.selectedItem().sFromFull) : ''); this.internalNote(false); if (!this.bExtApp && this.selectedItem()) { App.ContactsCache.getContactByEmail(this.selectedItem().sEmail, this.onOwnerContactResponse, this); } clearInterval(this.iPingInterval); clearTimeout(this.iPingStartTimer); this.watchers([]); if (this.selectedItem()) { this.iPingStartTimer = setTimeout(_.bind(function () { this.executeThreadPing(this.selectedItem().Id); clearInterval(this.iPingInterval); this.iPingInterval = setInterval(_.bind(function () { this.executeThreadPing(this.selectedItem().Id); }, this), 180000); }, this), 5000); } }, this); this.listFilter = ko.observable(this.bAgent ? Enums.HelpdeskFilters.Open : Enums.HelpdeskFilters.All); this.listFilter.subscribe(function () { this.requestThreadsList(); // this.selector.itemSelected(null); // this.selectedItem(null); }, this); this.prevListFilter = ko.observable(''); this.hasMorePosts = ko.computed(function () { var oItem = this.selectedItem(); return oItem && oItem.postsCount() > this.posts().length; }, this).extend({ throttle: 1 }); //list selector this.selector = new CSelector( this.threads, _.bind(this.onItemClick, this), _.bind(this.onItemDelete, this), null, null, null, false, false, false, true ); this.checkStarted = ko.observable(false); this.checkAll = this.selector.koCheckAll(); this.checkAllIncomplite = this.selector.koCheckAllIncomplete(); this.ThreadsPerPage = 10; //TODO use own PerPage param this.oPageSwitcher = new CPageSwitcherViewModel(0, this.ThreadsPerPage); this.oPageSwitcher.currentPage.subscribe(function () { this.requestThreadsList(); }, this); //search this.isSearchFocused = ko.observable(false); this.searchPattern = ko.observable(''); this.search = ko.observable(''); this.search.subscribe(function (sValue) { this.searchPattern(sValue); }, this); this.searchText = ko.computed(function () { return Utils.i18n('HELPDESK/INFO_SEARCH_RESULT', { 'SEARCH': this.search() }); }, this); this.searchSubmitCommand = Utils.createCommand(this, function () { this.oPageSwitcher.currentPage(1); this.search(this.searchPattern()); this.requestThreadsList(); }); //commands this.deleteCommand = Utils.createCommand(this, this.executeDelete, this.isEnableListActions); this.openNewWindowCommand = Utils.createCommand(this, this.executeOpenNewWindow, this.isEnableListActions); this.checkCommand = Utils.createCommand(this, function () { this.requestThreadsList(); this.requestPosts(); this.startAutocheckmail(); }); this.closeCommand = Utils.createCommand(this, fChangeStateHelper(Enums.HelpdeskThreadStates.Resolved), this.isEnableListActions); this.waitCommand = Utils.createCommand(this, fChangeStateHelper(Enums.HelpdeskThreadStates.Waiting), this.isEnableListActions); this.pendingCommand = Utils.createCommand(this, fChangeStateHelper(Enums.HelpdeskThreadStates.Pending), this.isEnableListActions); this.deferCommand = Utils.createCommand(this, fChangeStateHelper(Enums.HelpdeskThreadStates.Deferred), this.isEnableListActions); this.answerCommand = Utils.createCommand(this, fChangeStateHelper(Enums.HelpdeskThreadStates.Answered), this.isEnableListActions); this.postCommand = Utils.createCommand(this, this.executePostCreate, function () { return !!this.selectedItem() && // this.posts().length > 0 && this.replyText().length > 0 && this.allAttachmentsUploaded(); }); this.visibleNewThread = ko.observable(false); this.newThreadText = ko.observable(''); this.newThreadCreating = ko.observable(false); this.createThreadCommand = Utils.createCommand(this, this.executeThreadCreate, function () { return this.visibleNewThread() && this.newThreadText().length > 0 && !this.newThreadCreating(); }); this.createThreadButtonText = ko.computed(function () { return this.newThreadCreating() ? Utils.i18n('HELPDESK/BUTTON_SENDING') : Utils.i18n('HELPDESK/BUTTON_CREATE'); }, this); this.showThreadsByOwnerCommand = Utils.createCommand(this, this.executeShowThreadsByOwner); this.commandGetOlderPosts = function () { var aList = this.posts(), iPostId = aList[0] ? aList[0].Id : 0 ; this.requestPosts(null, iPostId); }; this.externalContentUrl = ko.observable(''); if (AppData.HelpdeskIframeUrl) { if (this.bAgent) { this.externalContentUrl = ko.computed(function () { var sEmail = '', oSelected = this.selectedItem() ; if (oSelected) { sEmail = oSelected.Email(); } if (sEmail) { return AppData.HelpdeskIframeUrl.replace(/\[EMAIL\]/g, sEmail); } return ''; }, this); } else if (AppData.User.Email) { this.externalContentUrl = ko.computed(function () { return AppData.HelpdeskIframeUrl.replace(/\[EMAIL\]/g, AppData.User.Email); }, this); } } // view pane this.clientDetailsVisible = ko.observable( App.Storage.hasData('HelpdeskUserDetails') ? App.Storage.getData('HelpdeskUserDetails') : true); this.clientDetailsVisible.subscribe(function (value) { App.Storage.setData('HelpdeskUserDetails', value); }, this); this.subject = ko.observable(''); this.watchers = ko.observableArray([]); this.ownerExistsInContacts = ko.observable(false); this.ownerContactInfoReceived = ko.observable(false); this.ownerContact = ko.observable(!this.bExtApp ? new CContactModel() : null); this.hasOwnerContact = ko.computed(function () { return !this.singleMode && this.ownerContactInfoReceived() && this.ownerExistsInContacts(); }, this); this.visibleAddToContacts = ko.computed(function () { return !this.singleMode && this.ownerContactInfoReceived() && !this.ownerExistsInContacts(); }, this); this.contactCardWidth = ko.observable(0); this.uploadedFiles = ko.observableArray([]); this.allAttachmentsUploaded = ko.computed(function () { var aNotUploadedFiles = _.filter(this.uploadedFiles(), function (oFile) { return !oFile.uploaded(); }) ; return aNotUploadedFiles.length === 0; }, this); this.uploaderButton = ko.observable(null); this.uploaderButtonCompose = ko.observable(null); this.uploaderArea = ko.observable(null); this.bDragActive = ko.observable(false);//.extend({'throttle': 1}); this.internalNote = ko.observable(false); this.isQuickReplyHidden = ko.observable(!this.bAgent); this.domQuickReply = ko.observable(null); this.replySendingStarted = ko.observable(false); this.replyPaneVisible = ko.observable(true); this.replyText = ko.observable(''); this.replyTextFocus = ko.observable(false); this.isQuickReplyActive = ko.observable(false); this.replyTextFocus.subscribe(function () { if (this.replyTextFocus()) { this.isQuickReplyActive(true); } }, this); this.isQuickReplyActive.subscribe(function () { if (this.isQuickReplyActive()) { this.replyTextFocus(true); } }, this); this.isEmptyQuickReplyPane = ko.computed(function () { return this.replyText().length === 0 && !this.internalNote() && this.uploadedFiles().length === 0; }, this); // view pane // this.isSearch = ko.computed(function () { return '' !== this.search(); }, this); this.isEmptyList = ko.computed(function () { return 0 === this.threads().length; }, this); if (this.bAgent) { this.dynamicEmptyListInfo = ko.computed(function () { return this.isEmptyList() && this.isSearch() ? Utils.i18n('HELPDESK/INFO_SEARCH_EMPTY') : Utils.i18n('HELPDESK/INFO_EMPTY_OPEN_THREAD_LIST_AGENT'); }, this); } else { this.dynamicEmptyListInfo = ko.computed(function () { return this.isEmptyList() && this.isSearch() ? Utils.i18n('HELPDESK/INFO_SEARCH_EMPTY') : Utils.i18n('HELPDESK/INFO_EMPTY_THREAD_LIST'); }, this); } this.simplePreviewPane = ko.computed(function () { var oItem = this.selectedItem(); return oItem ? oItem.ItsMe : !this.bAgent; }, this); this.allowInternalNote = ko.computed(function () { return !this.simplePreviewPane(); }, this); this.scrollToTopTrigger = ko.observable(false); this.scrollToBottomTrigger = ko.observable(false); this.allowDownloadAttachmentsLink = false; this.newThreadButtonWidth = ko.observable(0); this.requestFromLogin(); // App.Storage.setData('helpdeskQuestion', 'qwerty'); this.requestThreadsList(); } CHelpdeskViewModel.prototype.requestFromLogin = function () { if(App.Storage.getData('helpdeskQuestion')) { this.newThreadText(App.Storage.getData('helpdeskQuestion')); App.Storage.setData('helpdeskQuestion'); // this.openNewThread(); // this.visibleNewThread(true); // this.newThreadCreating(false); this.executeThreadCreate(); // this.visibleNewThread(false); } }; CHelpdeskViewModel.prototype.clearQuickReply = function () { this.replyText(''); this.replyTextFocus(false); this.internalNote(false); this.uploadedFiles([]); this.isQuickReplyActive(false); }; /** * @param {Object} oContact */ CHelpdeskViewModel.prototype.onOwnerContactResponse = function (oContact) { if (oContact) { this.ownerContact(oContact); this.ownerExistsInContacts(true); } else { this.ownerContact(new CContactModel()); this.ownerExistsInContacts(false); } this.ownerContactInfoReceived(true); }; CHelpdeskViewModel.prototype.updateOpenerWindow = function () { if (this.singleMode && window.opener && window.opener.App) { window.opener.App.updateHelpdesk(); } }; /** * @param {Object} oPost */ CHelpdeskViewModel.prototype.deletePost = function (oPost) { if (oPost && oPost.itsMe()) { var self = this, fAction = function (bResult) { if (bResult) { App.Ajax[self.ajaxSendFunc]({ 'Action': 'HelpdeskPostDelete', 'PostId': oPost.Id, 'ThreadId': oPost.IdThread, 'IsExt': self.bExtApp ? 1 : 0 }, self.onHelpdeskPostDeleteResponse, self); } } ; App.Screens.showPopup(ConfirmPopup, [Utils.i18n('HELPDESK/CONFIRM_DELETE_THIS_POST'), fAction]); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CHelpdeskViewModel.prototype.onHelpdeskPostDeleteResponse = function (oResponse, oRequest) { if (oResponse.Result === false) { App.Api.showErrorByCode(oResponse, Utils.i18n('HELPDESK/ERROR_COULDNT_DELETE_POST')); } else { App.Api.showReport(Utils.i18n('HELPDESK/REPORT_POST_HAS_BEEN_DELETED')); } this.requestPosts(); this.updateOpenerWindow(); }; CHelpdeskViewModel.prototype.addToContacts = function () { if (this.selectedItem()) { App.ContactsCache.addToContacts('', this.selectedItem().sEmail, this.onAddToContactsResponse, this); } }; CHelpdeskViewModel.prototype.iHaveMoreToSay = function () // Del { var self = this; this.isQuickReplyHidden(false); _.delay(function () { self.replyTextFocus(true); }, 300); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CHelpdeskViewModel.prototype.onAddToContactsResponse = function (oResponse, oRequest) { if (oResponse.Result && this.selectedItem() && oRequest.HomeEmail !== '' && oRequest.HomeEmail === this.selectedItem().sEmail) { App.Api.showReport(Utils.i18n('CONTACTS/REPORT_CONTACT_SUCCESSFULLY_ADDED')); App.ContactsCache.clearInfoAboutEmail(this.selectedItem().sEmail); App.ContactsCache.getContactByEmail(this.selectedItem().sEmail, this.onOwnerContactResponse, this); } }; CHelpdeskViewModel.prototype.scrollPostsToBottom = function () { this.scrollToBottomTrigger(!this.scrollToBottomTrigger()); }; CHelpdeskViewModel.prototype.scrollPostsToTop = function () { this.scrollToTopTrigger(!this.scrollToTopTrigger()); }; CHelpdeskViewModel.prototype.showClientDetails = function () { this.clientDetailsVisible(true); }; CHelpdeskViewModel.prototype.hideClientDetails = function () { this.clientDetailsVisible(false); }; CHelpdeskViewModel.prototype.startAutocheckmail = function () { var self = this, iIntervalInMin = AppData && AppData.User ? AppData.User.AutoCheckMailInterval : 1; if (0 < iIntervalInMin) { clearTimeout(this.iAutoCheckTimer); this.iAutoCheckTimer = setTimeout(function () { self.checkCommand(); }, iIntervalInMin * 60 * 1000); } }; /** * @param {Object} $viewModel */ CHelpdeskViewModel.prototype.onApplyBindings = function ($viewModel) { this.selector.initOnApplyBindings( '.items_sub_list .item', '.items_sub_list .selected.item', '.items_sub_list .item .custom_checkbox', $('.items_list', $viewModel), $('.threads_scroll.scroll-inner', $viewModel) ); this.initUploader(); $(this.domQuickReply()).on('click', _.bind(function (oEvent) { this.isQuickReplyActive(true); oEvent.stopPropagation(); }, this)); $(document.body).on('click', _.bind(function () { var bIsCurrentScreen = App.Screens.currentScreen() === Enums.Screens.Helpdesk; if (bIsCurrentScreen) { if (this.isEmptyQuickReplyPane()) { this.isQuickReplyActive(false); } } }, this)); if (App.registerHelpdeskUpdateFunction) { App.registerHelpdeskUpdateFunction(_.bind(this.checkCommand, this)); } this.startAutocheckmail(); this.hotKeysBind(); }; CHelpdeskViewModel.prototype.onShow = function () { this.newThreadButtonWidth.notifySubscribers(); this.selector.useKeyboardKeys(true); this.oPageSwitcher.show(); this.oPageSwitcher.perPage(this.ThreadsPerPage); this.oPageSwitcher.currentPage(1); this.requestThreadsList(); }; CHelpdeskViewModel.prototype.onHide = function () { this.selector.useKeyboardKeys(false); this.selectedItem(null); this.oPageSwitcher.hide(); }; CHelpdeskViewModel.prototype.requestThreadsList = function () { // this.threads([]); this.loadingList(true); this.checkStarted(true); App.Ajax[this.ajaxSendFunc]({ 'Action': 'HelpdeskThreadsList', 'IsExt': this.bExtApp ? 1 : 0, 'Offset': (this.oPageSwitcher.currentPage() - 1) * this.ThreadsPerPage, 'Limit': this.ThreadsPerPage, 'Filter': this.listFilter(), 'Search': this.search() }, this.onHelpdeskThreadsListResponse, this); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CHelpdeskViewModel.prototype.onHelpdeskThreadsListResponse = function (oResponse, oRequest) { var iIndex = 0, iLen = 0, oSelectedItem = this.selectedItem(), sSelectedId = oSelectedItem ? Utils.pString(oSelectedItem.Id) : '', aList = [], oObject = null, oThreadForSelect = null, aThreadList = (oResponse.Result && _.isArray(oResponse.Result.List)) ? oResponse.Result.List : [] ; this.checkStarted(false); if (oResponse.Result === false) { App.Api.showErrorByCode(oResponse); } else { for (iLen = aThreadList.length; iIndex < iLen; iIndex++) { if (aThreadList[iIndex] && 'Object/CHelpdeskThread' === Utils.pExport(aThreadList[iIndex], '@Object', '')) { oObject = new CThreadListModel(); oObject.parse(aThreadList[iIndex]); oObject.OwnerIsMe = Utils.pString(oObject.IdOwner); if (sSelectedId === Utils.pString(oObject.Id)) { oSelectedItem.postsCount(oObject.postsCount()); oObject.selected(true); this.selector.itemSelected(oObject); } aList.push(oObject); } } this.loadingList(false); // this.checkStarted(false); this.threads(aList); App.helpdeskUnseenCount(_.filter(aList, function (oThreadListModel) { return oThreadListModel.unseen(); }, this).length); this.oPageSwitcher.setCount(Utils.pInt(oResponse.Result.ItemsCount)); if (AppData.HelpdeskThreadId) { oThreadForSelect = _.find(aList, function (oThreadItem) { return oThreadItem.Id === AppData.HelpdeskThreadId; }, this); if (oThreadForSelect) { oThreadForSelect = /** @type {Object} */ oThreadForSelect; this.onItemSelect(oThreadForSelect); } } } }; /** * @param {Object=} oItem = undefined * @param {number=} iStartFromId = 0 */ CHelpdeskViewModel.prototype.requestPosts = function (oItem, iStartFromId) { var oSelectedThread = this.selectedItem(), iId = oItem ? oItem.Id : (oSelectedThread ? oSelectedThread.Id : 0), iFromId = iStartFromId ? iStartFromId : 0, oParameters = {} ; if (iId) { oParameters = { 'Action': 'HelpdeskThreadPosts', 'IsExt': this.bExtApp ? 1 : 0, 'ThreadId': iId, 'StartFromId': iFromId, 'Limit': 5 }; if (iFromId) { this.loadingMoreMessages(true); } // else // { // this.posts([]); // this.loadingViewPane(true); // } App.Ajax[this.ajaxSendFunc](oParameters, this.onHelpdeskThreadPostsResponse, this); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CHelpdeskViewModel.prototype.onHelpdeskThreadPostsResponse = function (oResponse, oRequest) { var self = this, bScrollToBottom = false, iIndex = 0, iLen = 0, aList = [], aPosts = [], oObject = null, sStartFromId = '', aPostList = (oResponse.Result && _.isArray(oResponse.Result.List)) ? oResponse.Result.List : [] ; if (oResponse.Result === false) { App.Api.showErrorByCode(oResponse); } else { if (this.selectedItem() && oResponse.Result.ThreadId === this.selectedItem().Id) { this.selectedItem().postsCount(Utils.pInt(oResponse.Result.ItemsCount)); for (iLen = aPostList.length; iIndex < iLen; iIndex++) { if (aPostList[iIndex] && 'Object/CHelpdeskPost' === Utils.pExport(aPostList[iIndex], '@Object', '')) { oObject = new CPostModel(); oObject.parse(aPostList[iIndex]); aList.push(oObject); } } if (oResponse.Result.StartFromId) { aPosts = this.posts(); sStartFromId = oResponse.Result.StartFromId; for (iLen = aPosts.length, iIndex = 0; iIndex < iLen; iIndex++) { if (aPosts.Id === sStartFromId) { break; } } aList = _.union(_.first(aPosts, iIndex).reverse(), aList); this.loadingMoreMessages(false); } else { bScrollToBottom = true; } if (this.selectedItem().unseen()) { this.executeThreadSeen(this.selectedItem().Id); } } // this.loadingViewPane(false); this.posts(aList.reverse()); if (bScrollToBottom) { self.scrollPostsToBottom(); _.delay(function () { self.scrollPostsToBottom(); }, 10); _.delay(function () { self.scrollPostsToBottom(); }, 100); } else { self.scrollPostsToTop(); } } }; /** * @param {Object} oItem */ CHelpdeskViewModel.prototype.onItemClick = function (oItem) { if (!this.selectedItem() || this.selectedItem().ThreadHash !== oItem.ThreadHash) { App.Routing.setHash([Enums.Screens.Helpdesk, oItem.ThreadHash]); oItem.postsCount(0); this.posts([]); } }; /** * @param {Array} aParams */ CHelpdeskViewModel.prototype.onRoute = function (aParams) { var sThreadHash = aParams[0], oItem = _.find(this.threads(), function (oThread) { return oThread.ThreadHash === sThreadHash; }) ; if (oItem) { oItem = /** @type {Object} */ oItem; this.onItemSelect(oItem); } else if (this.threads().length === 0 && this.loadingList() && this.threadSubscription === undefined && !AppData.SingleMode) { this.threadSubscription = this.threads.subscribe(function () { this.onRoute(aParams); this.threadSubscription.dispose(); this.threadSubscription = undefined; }, this); } else if (sThreadHash) { App.Ajax[this.ajaxSendFunc]({ 'Action': 'HelpdeskGetThreadByHash', 'IsExt': this.bExtApp ? 1 : 0, 'ThreadHash': sThreadHash }, this.onHelpdeskGetThreadByHashResponse, this); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CHelpdeskViewModel.prototype.onHelpdeskGetThreadByHashResponse = function (oResponse, oRequest) { var oItem = new CThreadListModel(); if (oResponse.Result) { oItem.parse(oResponse.Result); oItem.OwnerIsMe = Utils.pString(oItem.IdOwner); this.onItemSelect(oItem); } }; /** * @param {Object} oItem */ CHelpdeskViewModel.prototype.onItemSelect = function (oItem) { // store current selection this.visibleNewThread(false); // clear and set previos selection this.selector.listCheckedAndSelected(false); this.selector.itemSelected(this.selectedItem()); if (this.selectedItem() === null || this.selectedItem().Id !== oItem.Id) { if (this.uploadedFiles().length > 0 || this.replyText().length > 0) { var oSelectedItem = this.selectedItem(), sConfirm = Utils.i18n('HELPDESK/CONFIRM_CANCEL_REPLY'), fAction = _.bind(function (bResult) { if (bResult) { this.clearQuickReply(); this.selector.itemSelected(oItem); this.selectedItem(oItem); this.visibleNewThread(false); this.isQuickReplyHidden(oItem.ItsMe || !this.bAgent); this.requestPosts(oItem); this.cleanAll(); } else { this.replyTextFocus(true); this.isQuickReplyHidden(false); this.selector.itemSelected(oSelectedItem); this.selectedItem(oSelectedItem); this.cleanAll(); } }, this) ; App.Screens.showPopup(ConfirmPopup, [sConfirm, fAction]); } else { this.clearQuickReply(); this.selector.itemSelected(oItem); this.selectedItem(oItem); this.isQuickReplyHidden(oItem.ItsMe || !this.bAgent); this.requestPosts(oItem); } } }; CHelpdeskViewModel.prototype.onItemDelete = function () { this.executeDelete(); }; CHelpdeskViewModel.prototype.openNewThread = function () { if (this.uploadedFiles().length > 0 || this.replyText().length > 0) { var sConfirm = Utils.i18n('HELPDESK/CONFIRM_CANCEL_REPLY'), fAction = _.bind(function (bResult) { if (bResult) { this.clearQuickReply(); this.visibleNewThread(true); } else { this.visibleNewThread(false); this.cleanAll(); } }, this) ; App.Screens.showPopup(ConfirmPopup, [sConfirm, fAction]); } else { this.selector.itemSelected(null); this.selectedItem(null); this.visibleNewThread(true); } }; CHelpdeskViewModel.prototype.cancelNewThread = function () { if (this.uploadedFiles().length > 0 || this.newThreadText().length > 0) { var sConfirm = Utils.i18n('HELPDESK/CONFIRM_CANCEL_REPLY'), fAction = _.bind(function (bResult) { if (bResult) { this.newThreadText(''); this.uploadedFiles([]); this.visibleNewThread(false); } }, this) ; App.Screens.showPopup(ConfirmPopup, [sConfirm, fAction]); } else { this.newThreadText(''); this.uploadedFiles([]); this.visibleNewThread(false); this.selector.itemSelected(null); this.selectedItem(null); } }; CHelpdeskViewModel.prototype.onSearch = function () { this.requestThreadsList(); // TODO on error action }; CHelpdeskViewModel.prototype.clearSearch = function () { this.requestThreadsList(); // TODO on error action }; CHelpdeskViewModel.prototype.isEnableListActions = function () { return !!this.selectedItem(); }; CHelpdeskViewModel.prototype.executeDelete = function () { var self = this, oSelectedItem = this.selectedItem() ; if (oSelectedItem) { _.each(this.threads(), function (oItem) { if (oItem === oSelectedItem) { oItem.deleted(true); } }); _.delay(function () { self.threads.remove(function (oItem) { return oItem.deleted(); }); }, 500); this.selectedItem(null); App.Ajax[this.ajaxSendFunc]({ 'Action': 'HelpdeskThreadDelete', 'IsExt': this.bExtApp ? 1 : 0, 'ThreadId': oSelectedItem.Id }, this.onHelpdeskThreadDeleteResponse, this); App.Routing.setHash([Enums.Screens.Helpdesk, '']); } }; CHelpdeskViewModel.prototype.executeOpenNewWindow = function () { var sUrl = App.Routing.buildHashFromArray([Enums.Screens.SingleHelpdesk, this.selectedItem().ThreadHash]); Utils.WindowOpener.openTab(sUrl); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CHelpdeskViewModel.prototype.onHelpdeskThreadDeleteResponse = function (oResponse, oRequest) { this.requestThreadsList(); this.updateOpenerWindow(); }; /** * @param {number} iState */ CHelpdeskViewModel.prototype.executeChangeState = function (iState) { var oSelectedItem = this.selectedItem(); if (iState === undefined) { return; } //TODO can't delete thread with id = 0 if (oSelectedItem) { oSelectedItem.state(iState); App.Ajax[this.ajaxSendFunc]({ 'Action': 'HelpdeskThreadChangeState', 'IsExt': this.bExtApp ? 1 : 0, 'ThreadId': oSelectedItem.Id, 'Type': oSelectedItem.state() }, this.onHelpdeskThreadChangeStateResponse, this); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CHelpdeskViewModel.prototype.onHelpdeskThreadChangeStateResponse = function (oResponse, oRequest) { this.requestThreadsList(); this.updateOpenerWindow(); }; /** * @param {number} iId */ CHelpdeskViewModel.prototype.executeThreadPing = function (iId) { if (iId === undefined) { return; } App.Ajax[this.ajaxSendFunc]({ 'Action': 'HelpdeskThreadPing', 'IsExt': this.bExtApp ? 1 : 0, 'ThreadId': iId }, this.onThreadPingResponse, this); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CHelpdeskViewModel.prototype.onThreadPingResponse = function (oResponse, oRequest) { this.watchers( _.map(oResponse.Result, function (aWatcher) { var sName = (aWatcher.length > 0) ? aWatcher[0] : '', sEmail = (aWatcher.length > 0) ? aWatcher[1] : '', oRes = { name: sName, email: sEmail, text: '', initial: '', icon: '' } ; if (sEmail.length > 0 && sName.length > 0) { oRes.text = '"' + sName + '" <' + sEmail + '>'; if (/\s/g.test(sName)) //check for whitespace { oRes.initial = _.reduce(sName.split(' ', 2), function(sMemo, sNamePath){ return sMemo + sNamePath.substr(0,1); }, ''); //get first letter from each of the two words } else { oRes.initial = sName.substr(0,2); } } else if (sEmail.length > 0) { oRes.text = sEmail; oRes.initial = sEmail.substr(0,2); } return oRes; }, this) ); }; /** * @param {number} iId */ CHelpdeskViewModel.prototype.executeThreadSeen = function (iId) { if (iId === undefined) { return; } App.Ajax[this.ajaxSendFunc]({ 'Action': 'HelpdeskThreadSeen', 'IsExt': this.bExtApp ? 1 : 0, 'ThreadId': iId }, this.onHelpdeskThreadSeenResponse, this); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CHelpdeskViewModel.prototype.onHelpdeskThreadSeenResponse = function (oResponse, oRequest) { var iIndex = 0, iLen = 0, aThreads = [], iSeachId = 0 ; if (oRequest.ThreadId) { aThreads = this.threads(); iSeachId = this.selectedItem() ? this.selectedItem().Id : 0; if (0 < iSeachId) { for (iLen = aThreads.length; iIndex < iLen; iIndex++) { if (iSeachId === oRequest.ThreadId) { App.helpdeskUnseenCount(App.helpdeskUnseenCount() - 1); this.selectedItem().unseen(false); break; } } } } this.updateOpenerWindow(); }; CHelpdeskViewModel.prototype.executeThreadCreate = function () { var sNewThreadSubject = '', iFirstSpacePos = -1 ; // if (this.visibleNewThread()) // { sNewThreadSubject = Utils.trim(this.newThreadText().replace(/[\n\r]/, ' ')); iFirstSpacePos = sNewThreadSubject.indexOf(' ', 40); if (iFirstSpacePos >= 0) { sNewThreadSubject = sNewThreadSubject.substring(0, iFirstSpacePos); } this.newThreadCreating(true); this.sendHelpdeskPostCreate(0, sNewThreadSubject, this.newThreadText(), this.onThreadCreateResponse); // } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CHelpdeskViewModel.prototype.onThreadCreateResponse = function (oResponse, oRequest) { this.newThreadCreating(false); // console.log('-----------------'); // console.log(oResponse); // console.log(oRequest); if (oResponse.Result && oRequest) { App.Api.showReport(Utils.i18n('HELPDESK/REPORT_THREAD_SUCCESSFULLY_CREATED')); this.cleanAll(); this.posts([]); this.visibleNewThread(false); } this.requestThreadsList(); this.updateOpenerWindow(); }; CHelpdeskViewModel.prototype.executePostCreate = function () { if (this.selectedItem()) { this.replySendingStarted(true); this.sendHelpdeskPostCreate(this.selectedItem().Id, '', this.replyText(), this.onPostCreateResponse); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CHelpdeskViewModel.prototype.onPostCreateResponse = function (oResponse, oRequest) { this.replySendingStarted(false); if (oResponse.Result && oRequest) { App.Api.showReport(Utils.i18n('HELPDESK/REPORT_POST_SUCCESSFULLY_ADDED')); this.clearQuickReply(); this.requestPosts(); } this.requestThreadsList(); this.updateOpenerWindow(); }; /** * @param {number} iThreadId * @param {string} sSubject * @param {string} sText * @param {Function} fResponseHandler */ CHelpdeskViewModel.prototype.sendHelpdeskPostCreate = function (iThreadId, sSubject, sText, fResponseHandler) { var aAttachments = {}, oParameters = {} ; _.each(this.uploadedFiles(), function (oItem) { aAttachments[oItem.tempName()] = oItem.hash(); }); oParameters = { 'Action': 'HelpdeskPostCreate', 'IsExt': this.bExtApp ? 1 : 0, 'ThreadId': iThreadId, 'IsInternal': this.internalNote() ? 1 : 0, 'Subject': sSubject, 'Text': sText, 'Attachments': aAttachments }; App.Ajax[this.ajaxSendFunc](oParameters, fResponseHandler, this); }; CHelpdeskViewModel.prototype.executeShowThreadsByOwner = function () { this.search('owner:' + this.selectedItem().aOwner[0]); this.prevListFilter(this.listFilter()); this.listFilter(Enums.HelpdeskFilters.All); }; CHelpdeskViewModel.prototype.onClearSearchClick = function () { // initiation empty search this.search(''); if (this.prevListFilter() !== '') { this.listFilter(this.prevListFilter()); this.prevListFilter(''); } this.searchSubmitCommand(); }; /** * Initializes file uploader. */ CHelpdeskViewModel.prototype.initUploader = function () { this.oJua = this.createJuaObject(this.uploaderButton()); this.oJuaCompose = this.createJuaObject(this.uploaderButtonCompose()); }; /** * @param {Object} oButton */ CHelpdeskViewModel.prototype.createJuaObject = function (oButton) { if (oButton) { var oJua = new Jua({ 'action': '?/Upload/HelpdeskFile/', 'name': 'jua-uploader', 'queueSize': 2, 'clickElement': oButton, 'dragAndDropElement': oButton, 'disableAjaxUpload': false, 'disableFolderDragAndDrop': false, 'disableDragAndDrop': false, 'hidden': { 'IsExt': this.bExtApp ? '1' : '0', 'Token': AppData.Token, 'TenantHash': this.bExtApp && AppData ? AppData.TenantHash : '', 'AccountID': this.bExtApp ? 0 : AppData.Accounts.currentId() } }); oJua .on('onProgress', _.bind(this.onFileUploadProgress, this)) .on('onSelect', _.bind(this.onFileUploadSelect, this)) .on('onStart', _.bind(this.onFileUploadStart, this)) .on('onComplete', _.bind(this.onFileUploadComplete, this)) .on('onBodyDragEnter', _.bind(this.bDragActive, this, true)) .on('onBodyDragLeave', _.bind(this.bDragActive, this, false)) ; return oJua; } else { return null; } }; /** * @param {string} sFileUID */ CHelpdeskViewModel.prototype.onFileRemove = function (sFileUID) { var oAttach = this.getUploadedFileByUID(sFileUID); if (this.oJua) { this.oJua.cancel(sFileUID); } this.uploadedFiles.remove(oAttach); }; /** * @param {string} sFileUID */ CHelpdeskViewModel.prototype.getUploadedFileByUID = function (sFileUID) { return _.find(this.uploadedFiles(), function (oAttach) { return oAttach.uploadUid() === sFileUID; }); }; /** * @param {string} sFileUID * @param {Object} oFileData */ CHelpdeskViewModel.prototype.onFileUploadSelect = function (sFileUID, oFileData) { var oAttach, sWarningSize = Utils.i18n('COMPOSE/UPLOAD_ERROR_FILENAME_SIZE', { 'FILENAME': oFileData.FileName, 'MAXSIZE': Utils.friendlySize(AppData.App.AttachmentSizeLimit) }), sWarningCountLimit = Utils.i18n('HELPDESK/ERROR_UPLOAD_FILES_COUNT'), sButtonCountLimit = Utils.i18n('MAIN/BUTTON_CLOSE'), iAttachCount = this.uploadedFiles().length ; if (iAttachCount >= 5) { App.Screens.showPopup(AlertPopup, [sWarningCountLimit, null, '', sButtonCountLimit]); return false; } if (AppData.App && AppData.App.AttachmentSizeLimit > 0 && oFileData.Size > AppData.App.AttachmentSizeLimit) { App.Screens.showPopup(AlertPopup, [sWarningSize]); return false; } oAttach = new CHelpdeskAttachmentModel(); oAttach.onUploadSelect(sFileUID, oFileData); this.uploadedFiles.push(oAttach); return true; }; /** * @param {string} sFileUID * @param {number} iUploadedSize * @param {number} iTotalSize */ CHelpdeskViewModel.prototype.onFileUploadProgress = function (sFileUID, iUploadedSize, iTotalSize) { var oAttach = this.getUploadedFileByUID(sFileUID); if (oAttach) { oAttach.onUploadProgress(iUploadedSize, iTotalSize); } }; /** * @param {string} sFileUID */ CHelpdeskViewModel.prototype.onFileUploadStart = function (sFileUID) { var oAttach = this.getUploadedFileByUID(sFileUID); if (oAttach) { oAttach.onUploadStart(); } }; /** * @param {string} sFileUID * @param {boolean} bResult * @param {Object} oResult */ CHelpdeskViewModel.prototype.onFileUploadComplete = function (sFileUID, bResult, oResult) { var oAttach = this.getUploadedFileByUID(sFileUID); if (oAttach) { oAttach.onUploadComplete(sFileUID, bResult, oResult); } }; CHelpdeskViewModel.prototype.cleanAll = function () { this.uploadedFiles([]); this.replyText(''); this.newThreadText(''); }; CHelpdeskViewModel.prototype.hotKeysBind = function () { }; CHelpdeskViewModel.prototype.quoteText = function (sText) { var sReplyText = this.replyText(), fDoingQuote = _.bind(function() { this.replyText(sReplyText === '' ? '>' + sText : sReplyText + '\n' + '>' + sText); this.replyTextFocus(true); },this); if(this.isQuickReplyHidden()) { _.delay(function(){ fDoingQuote(); }, 300); } else { fDoingQuote(); } this.isQuickReplyHidden(false); }; /** * @constructor */ function CScreens() { var $win = $(window); this.resizeAll = _.debounce(function () { $win.resize(); }, 100); this.oScreens = {}; this.currentScreen = ko.observable(''); this.popupVisibility = ko.observable(false); this.informationScreen = ko.observable(null); this.popups = []; } CScreens.prototype.initScreens = function () {}; CScreens.prototype.initLayout = function () {}; CScreens.prototype.init = function () { this.initScreens(); this.initLayout(); $('#pSevenContent').addClass('single_mode'); _.defer(function () { if (!AppData.SingleMode) { $('#pSevenContent').removeClass('single_mode'); } }); this.informationScreen(this.showNormalScreen(Enums.Screens.Information)); }; CScreens.prototype.getCurrentScreenModel = function () { var oCurrentScreen = this.oScreens[this.currentScreen()], oCurrentModel = (typeof oCurrentScreen !== 'undefined') ? oCurrentScreen.Model : null ; return oCurrentModel; }; /** * @param {string} sScreen * @param {?=} mParams */ CScreens.prototype.showCurrentScreen = function (sScreen, mParams) { var oCurrentScreen = this.oScreens[this.currentScreen()], oCurrentModel = (typeof oCurrentScreen !== 'undefined') ? oCurrentScreen.Model : null ; if (this.currentScreen() !== sScreen) { if (oCurrentModel && oCurrentScreen.bInitialized) { oCurrentModel.hideViewModel(); } this.currentScreen(sScreen); } this.showNormalScreen(sScreen, mParams); this.resizeAll(); }; /** * @param {string} sScreen * @param {?=} mParams * * @return Object */ CScreens.prototype.showNormalScreen = function (sScreen, mParams) { var sScreenId = sScreen, oScreen = this.oScreens[sScreenId] ; if (oScreen) { oScreen.bInitialized = (typeof oScreen.bInitialized !== 'boolean') ? false : oScreen.bInitialized; if (!oScreen.bInitialized) { oScreen.Model = this.initViewModel(oScreen.Model, oScreen.TemplateName); oScreen.bInitialized = true; } oScreen.Model.showViewModel(mParams); } return oScreen ? oScreen.Model : null; }; /** * @param {?} CViewModel * @param {string} sTemplateId * * @return {Object} */ CScreens.prototype.initViewModel = function (CViewModel, sTemplateId) { var oViewModel = null, $viewModel = null ; oViewModel = new CViewModel(); $viewModel = $('div[data-view-model="' + sTemplateId + '"]') .attr('data-bind', 'template: {name: \'' + sTemplateId + '\'}') .hide(); oViewModel.$viewModel = $viewModel; oViewModel.bShown = false; oViewModel.showViewModel = function (mParams) { this.$viewModel.show(); if (typeof this.onRoute === 'function') { this.onRoute(mParams); } if (!this.bShown) { if (typeof this.onShow === 'function') { this.onShow(mParams); } if (AfterLogicApi.runPluginHook) { if (this.__name) { AfterLogicApi.runPluginHook('view-model-on-show', [this.__name, this]); } } this.bShown = true; } }; oViewModel.hideViewModel = function () { this.$viewModel.hide(); if (typeof this.onHide === 'function') { this.onHide(); } this.bShown = false; }; ko.applyBindings(oViewModel, $viewModel[0]); if (typeof oViewModel.onApplyBindings === 'function') { oViewModel.onApplyBindings($viewModel); } return oViewModel; }; /** * @param {?} CPopupViewModel * @param {Array=} aParameters */ CScreens.prototype.showPopup = function (CPopupViewModel, aParameters) { if (CPopupViewModel) { if (!CPopupViewModel.__builded) { var oViewModelDom = null, oViewModel = new CPopupViewModel(), sTemplate = oViewModel.popupTemplate ? oViewModel.popupTemplate() : '' ; if ('' !== sTemplate) { oViewModelDom = $('div[data-view-model="' + sTemplate + '"]') .attr('data-bind', 'template: {name: \'' + sTemplate + '\'}') .removeClass('visible').hide(); if (oViewModelDom && 1 === oViewModelDom.length) { oViewModel.visibility = ko.observable(false); CPopupViewModel.__builded = true; CPopupViewModel.__vm = oViewModel; oViewModel.$viewModel = oViewModelDom; CPopupViewModel.__dom = oViewModelDom; oViewModel.showViewModel = Utils.createCommand(oViewModel, function () { if (App && App.Screens) { App.Screens.showPopup(CPopupViewModel); } }); oViewModel.closeCommand = Utils.createCommand(oViewModel, function () { if (App && App.Screens) { App.Screens.hidePopup(CPopupViewModel); } }); ko.applyBindings(oViewModel, oViewModelDom[0]); Utils.delegateRun(oViewModel, 'onApplyBindings', [oViewModelDom]); } } } if (CPopupViewModel.__vm && CPopupViewModel.__dom) { CPopupViewModel.__dom.show(); _.delay(function() { CPopupViewModel.__dom.addClass('visible'); }, 50); CPopupViewModel.__vm.visibility(true); Utils.delegateRun(CPopupViewModel.__vm, 'onShow', aParameters); this.popupVisibility(true); this.popups.push(CPopupViewModel); this.keyupPopupBinded = _.bind(this.keyupPopup, this, CPopupViewModel.__vm); $(document).on('keyup', this.keyupPopupBinded); } } }; /** * @param {Object} oViewModel * @param {Object} oEvent */ CScreens.prototype.keyupPopup = function (oViewModel, oEvent) { if (oEvent) { var iKeyCode = window.parseInt(oEvent.keyCode, 10); if (Enums.Key.Esc === iKeyCode) { if (oViewModel.onEscHandler) { oViewModel.onEscHandler(); } else { oViewModel.closeCommand(); } } if ((Enums.Key.Enter === iKeyCode || Enums.Key.Space === iKeyCode) && oViewModel.onEnterHandler) { oViewModel.onEnterHandler(); } } }; /** * @param {?} CPopupViewModel */ CScreens.prototype.hidePopup = function (CPopupViewModel) { if (CPopupViewModel && CPopupViewModel.__vm && CPopupViewModel.__dom) { if (this.keyupPopupBinded) { $(document).off('keyup', this.keyupPopupBinded); this.keyupPopupBinded = undefined; } CPopupViewModel.__dom.removeClass('visible').hide(); CPopupViewModel.__vm.visibility(false); Utils.delegateRun(CPopupViewModel.__vm, 'onHide'); this.popupVisibility(false); this.popups = _.without(this.popups, CPopupViewModel); } }; CScreens.prototype.hideAllPopup = function () { _.each(this.popups, function (oPopup) { this.hidePopup(oPopup); }, this); }; /** * @param {string} sMessage */ CScreens.prototype.showLoading = function (sMessage) { if (this.informationScreen()) { this.informationScreen().showLoading(sMessage); } }; CScreens.prototype.hideLoading = function () { if (this.informationScreen()) { this.informationScreen().hideLoading(); } }; /** * @param {string} sMessage * @param {number} iDelay */ CScreens.prototype.showReport = function (sMessage, iDelay) { if (this.informationScreen()) { this.informationScreen().showReport(sMessage, iDelay); } }; /** * @param {string} sMessage * @param {boolean=} bHtml = false * @param {boolean=} bNotHide = false * @param {boolean=} bGray = false */ CScreens.prototype.showError = function (sMessage, bHtml, bNotHide, bGray) { if (this.informationScreen()) { this.informationScreen().showError(sMessage, bHtml, bNotHide, bGray); } }; /** * @param {boolean=} bGray = false */ CScreens.prototype.hideError = function (bGray) { if (this.informationScreen()) { this.informationScreen().hideError(bGray); } }; CScreens.prototype.initHelpdesk = function () { var oScreen = this.oScreens[Enums.Screens.Helpdesk]; if (AppData.User.IsHelpdeskSupported && oScreen && !oScreen.bInitialized) { oScreen.Model = this.initViewModel(oScreen.Model, oScreen.TemplateName); oScreen.bInitialized = true; } }; CScreens.prototype.initScreens = function () { this.oScreens[Enums.Screens.Information] = { 'Model': CInformationViewModel, 'TemplateName': 'Common_InformationViewModel' }; this.oScreens[Enums.Screens.Login] = { 'Model': CWrapLoginViewModel, 'TemplateName': 'Login_WrapLoginViewModel' }; this.oScreens[Enums.Screens.Header] = { 'Model': CHeaderViewModel, 'TemplateName': 'Common_HeaderViewModel' }; this.oScreens[Enums.Screens.Mailbox] = { 'Model': CMailViewModel, 'TemplateName': 'Mail_LayoutSidePane_MailViewModel' }; this.oScreens[Enums.Screens.SingleMessageView] = { 'Model': CMessagePaneViewModel, 'TemplateName': 'Mail_LayoutSidePane_MessagePaneViewModel' }; this.oScreens[Enums.Screens.Compose] = { 'Model': CComposeViewModel, 'TemplateName': 'Mail_ComposeViewModel' }; this.oScreens[Enums.Screens.SingleCompose] = { 'Model': CComposeViewModel, 'TemplateName': 'Mail_ComposeViewModel' }; this.oScreens[Enums.Screens.Settings] = { 'Model': CSettingsViewModel, 'TemplateName': 'Settings_SettingsViewModel' }; this.oScreens[Enums.Screens.SingleHelpdesk] = { 'Model': CHelpdeskViewModel, 'TemplateName': 'Helpdesk_ViewThreadInNewWindow' }; }; CScreens.prototype.initLayout = function () { $('#pSevenContent').append($('#Layout').html()); }; /** * @constructor */ function CMailCache() { this.currentAccountId = AppData.Accounts.currentId; this.currentAccountId.subscribe(function (iAccountID) { var oAccount = AppData.Accounts.getAccount(iAccountID), oFolderList = this.oFolderListItems[iAccountID], oParameters = { 'Action': 'FolderList', 'AccountID': iAccountID } ; if (oAccount) { oAccount.quotaRecieved(false); this.messagesLoadingError(false); if (oFolderList) { this.folderList(oFolderList); } else { this.messagesLoading(true); this.folderList(new CFolderListModel()); this.messages([]); this.currentMessage(null); App.Ajax.send(oParameters, this.onFolderListResponse, this); } } }, this); this.editedAccountId = AppData.Accounts.editedId; this.editedAccountId.subscribe(function (value) { var oFolderList = this.oFolderListItems[value], oParameters = {} ; if (oFolderList) { this.editedFolderList(oFolderList); } else if (this.currentAccountId() !== value) { this.editedFolderList(new CFolderListModel()); oParameters = { 'Action': 'FolderList', 'AccountID': value }; App.Ajax.send(oParameters, this.onFolderListResponse, this); } }, this); this.oFolderListItems = {}; this.quotaChangeTrigger = ko.observable(false); this.checkMailStarted = ko.observable(false); this.checkMailStartedAccountId = ko.observable(0); this.defaultFolderList = ko.observable(new CFolderListModel()); this.folderList = ko.observable(new CFolderListModel()); this.folderListLoading = ko.observable(false); this.editedFolderList = ko.observable(new CFolderListModel()); this.newMessagesCount = ko.computed(function () { var oInbox = this.folderList().inboxFolder() ; return oInbox ? oInbox.unseenMessageCount() : 0; }, this); this.newMessagesCount.subscribe(function (iMessagesCount) { App.mailUnseenCount(iMessagesCount > 99 ? '99+' : iMessagesCount); }, this); this.messages = ko.observableArray([]); this.messages.subscribe(function () { if (this.messages().length > 0) { this.messagesLoadingError(false); } }, this); this.uidList = ko.observable(new CUidListModel()); this.page = ko.observable(1); this.messagesLoading = ko.observable(true); this.messagesLoadingError = ko.observable(false); this.currentMessage = ko.observable(null); this.currentMessage.subscribe(function () { if (this.currentMessage()) { AfterLogicApi.runPluginHook('view-message', [AppData.Accounts.currentId(), this.currentMessage().folder(), this.currentMessage().uid()]); } }, this); this.nextMessageUid = ko.computed(function () { var sCurrentUid = '', sNextUid = '', oFolder = null, oParentMessage = null, bThreadLevel = false ; if (this.currentMessage() && AppData.SingleMode) { bThreadLevel = this.currentMessage().threadPart() && this.currentMessage().threadParentUid() !== ''; oFolder = this.folderList().getFolderByFullName(this.currentMessage().folder()); sCurrentUid = this.currentMessage().uid(); if (AppData.ThreadLevel || bThreadLevel) { AppData.ThreadLevel = true; if (bThreadLevel) { oParentMessage = oFolder.getMessageByUid(this.currentMessage().threadParentUid()); if (oParentMessage) { _.each(oParentMessage.threadUids(), function (sUid, iIndex, aCollection) { if (sUid === sCurrentUid && iIndex > 0) { sNextUid = aCollection[iIndex - 1]; } }); if (Utils.isUnd(sNextUid) || sNextUid === '') { sNextUid = oParentMessage.uid(); } } } } else { _.each(this.uidList().collection(), function (sUid, iIndex, aCollection) { if (sUid === sCurrentUid && iIndex > 0) { sNextUid = aCollection[iIndex - 1]; } }); if (Utils.isUnd(sNextUid)) { sNextUid = ''; } if (sNextUid === '' && window.opener && window.opener.App && window.opener.App.Prefetcher) { window.opener.App.Prefetcher.prefetchNextPage(sCurrentUid); } } } return sNextUid; }, this); this.prevMessageUid = ko.computed(function () { var sCurrentUid = this.currentMessage() ? this.currentMessage().uid() : '', sPrevUid = '', oFolder = null, oParentMessage = null, bThreadLevel = false ; if (this.currentMessage() && AppData.SingleMode) { bThreadLevel = this.currentMessage().threadPart() && this.currentMessage().threadParentUid() !== ''; oFolder = this.folderList().getFolderByFullName(this.currentMessage().folder()); sCurrentUid = this.currentMessage().uid(); if (AppData.ThreadLevel || bThreadLevel) { AppData.ThreadLevel = true; if (bThreadLevel) { oParentMessage = oFolder.getMessageByUid(this.currentMessage().threadParentUid()); if (oParentMessage) { _.each(oParentMessage.threadUids(), function (sUid, iIndex, aCollection) { if (sUid === sCurrentUid && (iIndex + 1) < aCollection.length) { sPrevUid = aCollection[iIndex + 1]; } }); if (Utils.isUnd(sPrevUid)) { sPrevUid = ''; } } } else if (this.currentMessage().threadCount() > 0) { sPrevUid = this.currentMessage().threadUids()[0]; } } else { _.each(this.uidList().collection(), function (sUid, iIndex, aCollection) { if (sUid === sCurrentUid && (iIndex + 1) < aCollection.length) { sPrevUid = aCollection[iIndex + 1]; } }); if (Utils.isUnd(sPrevUid)) { sPrevUid = ''; } if (sPrevUid === '' && window.opener && window.opener.App && window.opener.App.Prefetcher) { window.opener.App.Prefetcher.prefetchPrevPage(sCurrentUid); } } } return sPrevUid; }, this); this.deletedDraftMessageUid = ko.observable(''); this.aResponseHandlers = []; AppData.User.useThreads.subscribe(function () { _.each(this.oFolderListItems, function (oFolderList) { _.each(oFolderList.collection(), function (oFolder) { oFolder.markHasChanges(); oFolder.removeAllMessageListsFromCacheIfHasChanges(); }, this); }, this); this.messages([]); }, this); this.iAutoCheckMailTimer = -1; this.waitForUnseenMessages = ko.observable(true); this.iMessageSetSeenCount = 0; } /** * @public */ CMailCache.prototype.init = function () { var oMailCache = null; App.Ajax.openedRequestsCount.subscribe(function () { if (App.Ajax.openedRequestsCount() === 0) { // Delay not to reset these flags between two related requests (e.g. 'FolderCounts' and 'MessageList') _.delay(_.bind(function () { if (App.Ajax.openedRequestsCount() === 0) { this.checkMailStarted(false); this.folderListLoading(false); this.messagesLoading(false); } }, this), 10); } }, this); if (AppData.SingleMode && window.opener) { oMailCache = window.opener.App.MailCache; this.oFolderListItems = oMailCache.oFolderListItems; this.uidList(oMailCache.uidList()); oMailCache.uidList.subscribe(_.bind(function () { this.uidList(oMailCache.uidList()); }, this)); if (window.name) { this.currentAccountId(Utils.pInt(window.name)); } } this.currentAccountId.valueHasMutated(); }; CMailCache.prototype.getCurrentFolder = function () { return this.folderList().currentFolder(); }; /** * @param {number} iAccountId * @param {string} sFolderFullName */ CMailCache.prototype.getFolderByFullName = function (iAccountId, sFolderFullName) { var oFolderList = this.oFolderListItems[iAccountId] ; if (oFolderList) { return oFolderList.getFolderByFullName(sFolderFullName); } return null; }; CMailCache.prototype.checkCurrentFolderList = function () { var iCurrAccountId = AppData.Accounts.currentId(), oFolderList = this.oFolderListItems[iCurrAccountId] ; if (!oFolderList && !this.messagesLoading()) { this.messagesLoading(true); this.messagesLoadingError(false); this.getFolderList(iCurrAccountId); } }; /** * @param {number=} iAccountID */ CMailCache.prototype.getFolderList = function (iAccountID) { var oParameters = {'Action': 'FolderList'}; if (!Utils.isUnd(iAccountID)) { oParameters['AccountID'] = iAccountID; } this.folderListLoading(true); App.Ajax.send(oParameters, this.onFolderListResponse, this); }; /** * @param {number} iAccountId * @param {string} sFullName * @param {string} sUid * @param {string} sReplyType */ CMailCache.prototype.markMessageReplied = function (iAccountId, sFullName, sUid, sReplyType) { var oFolderList = this.oFolderListItems[iAccountId], oFolder = null ; if (oFolderList) { oFolder = oFolderList.getFolderByFullName(sFullName); if (oFolder) { oFolder.markMessageReplied(sUid, sReplyType); } } }; /** * @param {Object} oMessage */ CMailCache.prototype.hideThreads = function (oMessage) { if (AppData.User.useThreads() && oMessage.folder() === this.folderList().currentFolderFullName() && !oMessage.threadOpened()) { this.folderList().currentFolder().hideThreadMessages(oMessage); } }; /** * @param {string} sFolderFullName */ CMailCache.prototype.showOpenedThreads = function (sFolderFullName) { this.messages(this.getMessagesWithThreads(sFolderFullName, this.uidList(), this.messages())); }; /** * @param {Object} oUidList * @returns {Boolean} */ CMailCache.prototype.useThreadsInCurrentList = function (oUidList) { oUidList = oUidList || this.uidList(); var oCurrFolder = this.folderList().currentFolder(), bFolderWithoutThreads = oCurrFolder && oCurrFolder.withoutThreads(), bNotSearchOrFilters = oUidList.search() === '' && oUidList.filters() === '' ; return AppData.User.useThreads() && !bFolderWithoutThreads && bNotSearchOrFilters; }; /** * @param {string} sFolderFullName * @param {Object} oUidList * @param {Array} aOrigMessages */ CMailCache.prototype.getMessagesWithThreads = function (sFolderFullName, oUidList, aOrigMessages) { var aExtMessages = [], aMessages = [], oCurrFolder = this.folderList().currentFolder() ; if (oCurrFolder && sFolderFullName === oCurrFolder.fullName() && this.useThreadsInCurrentList(oUidList)) { aMessages = _.filter(aOrigMessages, function (oMess) { return !oMess.threadPart(); }); _.each(aMessages, function (oMess) { var aThreadMessages = []; aExtMessages.push(oMess); if (oMess.threadCount() > 0) { if (oMess.threadOpened()) { aThreadMessages = this.folderList().currentFolder().getThreadMessages(oMess); aExtMessages = _.union(aExtMessages, aThreadMessages); } oCurrFolder.computeThreadData(oMess); } }, this); return aExtMessages; } return aOrigMessages; }; /** * @param {Object} oUidList * @param {number} iOffset * @param {Object} oMessages * @param {boolean} bFillMessages */ CMailCache.prototype.setMessagesFromUidList = function (oUidList, iOffset, oMessages, bFillMessages) { var aUids = oUidList.getUidsForOffset(iOffset, oMessages), aMessages = _.map(aUids, function (sUid) { return oMessages[sUid]; }, this), iMessagesCount = aMessages.length ; if (bFillMessages) { this.messages(this.getMessagesWithThreads(this.folderList().currentFolderFullName(), oUidList, aMessages)); if ((iOffset + iMessagesCount < oUidList.resultCount()) && (iMessagesCount < AppData.User.MailsPerPage) && (oUidList.filters() !== Enums.FolderFilter.Unseen || this.waitForUnseenMessages())) { this.messagesLoading(true); } if (this.currentMessage() && (this.currentMessage().deleted() || this.currentMessage().folder() !== this.folderList().currentFolderFullName())) { this.currentMessage(null); } } return aUids; }; CMailCache.prototype.executeCheckMail = function () { var oFolderList = this.oFolderListItems[this.currentAccountId()], oInbox = oFolderList ? oFolderList.inboxFolder() : null, sInboxUidnext = oInbox ? oInbox.uidNext() : '', aFoldersFromAccount = AppData.Accounts.getCurrentFetchersAndFiltersFolderNames(), aFolders = oFolderList ? [oFolderList.inboxFolderFullName(), oFolderList.spamFolderFullName(), oFolderList.currentFolderFullName()] : [], iAccountID = oFolderList ? oFolderList.iAccountId : 0, bCurrentAccountCheckmailStarted = this.checkMailStarted() && (this.checkMailStartedAccountId() === iAccountID), oParameters = null ; if ((!App.Ajax.hasOpenedRequests('FolderCounts') || !bCurrentAccountCheckmailStarted) && (aFolders.length > 0)) { aFolders = _.uniq(_.compact(_.union(aFolders, aFoldersFromAccount))); oParameters = { 'Action': 'FolderCounts', 'Folders': aFolders, 'AccountID': iAccountID, 'InboxUidnext': sInboxUidnext }; this.checkMailStarted(true); this.checkMailStartedAccountId(iAccountID); App.Ajax.send(oParameters, this.onFolderCountsResponse, this); } }; CMailCache.prototype.setAutocheckmailTimer = function () { clearTimeout(this.iAutoCheckMailTimer); if (!AppData.SingleMode && AppData.User.AutoCheckMailInterval > 0) { this.iAutoCheckMailTimer = setTimeout(function () { if (!App.Ajax.isSearchMessages()) { App.MailCache.executeCheckMail(); } }, AppData.User.AutoCheckMailInterval * 60 * 1000); } }; CMailCache.prototype.checkMessageFlags = function () { var oInbox = this.folderList().inboxFolder(), aUids = oInbox ? oInbox.getFlaggedMessageUids() : [], oParameters = { 'Action': 'MessageFlags', 'Folder': this.folderList().inboxFolderFullName(), 'Uids': aUids } ; if (aUids > 0) { App.Ajax.send(oParameters, this.onMessageFlagsResponse, this); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CMailCache.prototype.onMessageFlagsResponse = function (oResponse, oRequest) { var oInbox = this.folderList().inboxFolder(); if (oResponse.Result) { _.each(oResponse.Result, function (aFlags, sUid) { if (_.indexOf(aFlags, '\\flagged') === -1) { oInbox.setMessageUnflaggedByUid(sUid); } }); } oInbox.removeFlaggedMessageListsFromCache(); App.Prefetcher.prefetchStarredMessageList(); }; /** * @param {string} sFolder * @param {number} iPage * @param {string} sSearch * @param {string=} sFilter */ CMailCache.prototype.changeCurrentMessageList = function (sFolder, iPage, sSearch, sFilter) { this.requestCurrentMessageList(sFolder, iPage, sSearch, sFilter, true); }; /** * @param {string} sFolder * @param {number} iPage * @param {string} sSearch * @param {string=} sFilter * @param {boolean=} bFillMessages */ CMailCache.prototype.requestCurrentMessageList = function (sFolder, iPage, sSearch, sFilter, bFillMessages) { var oRequestData = this.requestMessageList(sFolder, iPage, sSearch, sFilter || '', true, (bFillMessages || false)), iCheckmailIntervalMilliseconds = AppData.User.AutoCheckMailInterval * 60 * 1000, iFolderUpdateDiff = oRequestData.Folder.relevantInformationLastMoment ? moment().diff(oRequestData.Folder.relevantInformationLastMoment) : iCheckmailIntervalMilliseconds + 1 ; this.uidList(oRequestData.UidList); this.page(iPage); this.messagesLoading(oRequestData.DataExpected); this.messagesLoadingError(false); if (!oRequestData.DataExpected && iCheckmailIntervalMilliseconds > 0 && iFolderUpdateDiff > iCheckmailIntervalMilliseconds) { this.executeCheckMail(); } }; /** * @param {string} sFolder * @param {number} iPage * @param {string} sSearch * @param {string} sFilters * @param {boolean} bCurrent * @param {boolean} bFillMessages */ CMailCache.prototype.requestMessageList = function (sFolder, iPage, sSearch, sFilters, bCurrent, bFillMessages) { var oFolderList = this.oFolderListItems[this.currentAccountId()], oFolder = (oFolderList) ? oFolderList.getFolderByFullName(sFolder) : null, bFolderWithoutThreads = oFolder && oFolder.withoutThreads(), bUseThreads = AppData.User.useThreads() && !bFolderWithoutThreads && sSearch === '' && sFilters === '', oUidList = (oFolder) ? oFolder.getUidList(sSearch, sFilters) : null, bCacheIsEmpty = oUidList && oUidList.resultCount() === -1, iOffset = (iPage - 1) * AppData.User.MailsPerPage, oParameters = { 'Action': 'MessageList', 'Folder': sFolder, 'Offset': iOffset, 'Limit': AppData.User.MailsPerPage, 'Search': sSearch, 'Filters': sFilters, 'UseThreads': bUseThreads ? '1' : '0' }, bStartRequest = false, bDataExpected = false, fCallBack = bCurrent ? this.onCurrentMessageListResponse : this.onMessageListResponse, aUids = [] ; if (oFolder.type() === Enums.FolderTypes.Inbox) { oParameters['InboxUidnext'] = oFolder.uidNext(); } if (bCacheIsEmpty && oUidList.search() === this.uidList().search() && oUidList.filters() === this.uidList().filters()) { oUidList = this.uidList(); } if (oUidList) { aUids = this.setMessagesFromUidList(oUidList, iOffset, oFolder.oMessages, bFillMessages); } if (oUidList) { bDataExpected = (bCacheIsEmpty) || ((iOffset + aUids.length < oUidList.resultCount()) && (aUids.length < AppData.User.MailsPerPage)) ; bStartRequest = oFolder.hasChanges() || bDataExpected; } if (bStartRequest) { App.Ajax.send(oParameters, fCallBack, this); } else { this.waitForUnseenMessages(false); } return {UidList: oUidList, RequestStarted: bStartRequest, DataExpected: bDataExpected, Folder: oFolder}; }; CMailCache.prototype.executeEmptyTrash = function () { var oFolder = this.folderList().trashFolder(); if (oFolder) { oFolder.emptyFolder(); } }; CMailCache.prototype.executeEmptySpam = function () { var oFolder = this.folderList().spamFolder(); if (oFolder) { oFolder.emptyFolder(); } }; /** * @param {Object} oFolder */ CMailCache.prototype.onClearFolder = function (oFolder) { if (oFolder && oFolder.selected()) { this.messages.removeAll(); this.currentMessage(null); var oUidList = (oFolder) ? oFolder.getUidList(this.uidList().search(), this.uidList().filters()) : null; if (oUidList) { this.uidList(oUidList); } else { this.uidList(new CUidListModel()); } // FolderCounts-request aborted during folder cleaning, not to get the wrong information. // So here indicates that chekmail is over. this.checkMailStarted(false); this.setAutocheckmailTimer(); } }; /** * @param {string} sToFolderFullName * @param {Array} aUids * @param {boolean} bAnimateRecive */ CMailCache.prototype.moveMessagesToFolder = function (sToFolderFullName, aUids, bAnimateRecive) { if (aUids.length > 0) { var oCurrFolder = this.folderList().currentFolder(), oToFolder = this.folderList().getFolderByFullName(sToFolderFullName), oParameters = { 'Action': 'MessageMove', 'Folder': oCurrFolder ? oCurrFolder.fullName() : '', 'ToFolder': sToFolderFullName, 'Uids': aUids.join(',') }, oDiffs = null ; if (oCurrFolder && oToFolder) { oDiffs = oCurrFolder.markDeletedByUids(aUids); oToFolder.addMessagesCountsDiff(oDiffs.MinusDiff, oDiffs.UnseenMinusDiff); if (Utils.isUnd(bAnimateRecive) ? true : !!bAnimateRecive) { oToFolder.recivedAnim(true); } this.excludeDeletedMessages(); oToFolder.markHasChanges(); App.Ajax.send(oParameters, this.onMoveMessagesResponse, this); if (oToFolder && oToFolder.type() === Enums.FolderTypes.Trash) { AfterLogicApi.runPluginHook('move-messages-to-trash', [AppData.Accounts.currentId(), oParameters.Folder, aUids]); } if (oToFolder && oToFolder.type() === Enums.FolderTypes.Spam) { AfterLogicApi.runPluginHook('move-messages-to-spam', [AppData.Accounts.currentId(), oParameters.Folder, aUids]); } } } }; CMailCache.prototype.copyMessagesToFolder = function (sToFolderFullName, aUids, bAnimateRecive) { if (aUids.length > 0) { var oCurrFolder = this.folderList().currentFolder(), oToFolder = this.folderList().getFolderByFullName(sToFolderFullName), oParameters = { 'Action': 'MessageCopy', 'Folder': oCurrFolder ? oCurrFolder.fullName() : '', 'ToFolder': sToFolderFullName, 'Uids': aUids.join(',') } ; if (oCurrFolder && oToFolder) { if (Utils.isUnd(bAnimateRecive) ? true : !!bAnimateRecive) { oToFolder.recivedAnim(true); } oToFolder.markHasChanges(); App.Ajax.send(oParameters, this.onCopyMessagesResponse, this); if (oToFolder && oToFolder.type() === Enums.FolderTypes.Trash) { AfterLogicApi.runPluginHook('copy-messages-to-trash', [AppData.Accounts.currentId(), oParameters.Folder, aUids]); } if (oToFolder && oToFolder.type() === Enums.FolderTypes.Spam) { AfterLogicApi.runPluginHook('copy-messages-to-spam', [AppData.Accounts.currentId(), oParameters.Folder, aUids]); } } } }; CMailCache.prototype.excludeDeletedMessages = function () { _.delay(_.bind(function () { var oCurrFolder = this.folderList().currentFolder(), iOffset = (this.page() - 1) * AppData.User.MailsPerPage ; this.setMessagesFromUidList(this.uidList(), iOffset, oCurrFolder.oMessages, true); }, this), 500); }; /** * @param {string} sFolderFullName * @param {string} sDraftUid */ CMailCache.prototype.removeMessagesFromCacheForFolder = function (sFolderFullName, sDraftUid) { var oFolder = this.folderList().getFolderByFullName(sFolderFullName), sCurrFolderFullName = this.folderList().currentFolderFullName() ; if (oFolder) { if (oFolder.type() === Enums.FolderTypes.Drafts) { oFolder.markDeletedByUids([sDraftUid]); oFolder.commitDeleted([sDraftUid]); } oFolder.markHasChanges(); if (sFolderFullName === sCurrFolderFullName) { this.requestCurrentMessageList(sCurrFolderFullName, this.page(), this.uidList().search(), '', true); } } }; /** * @param {Array} aUids */ CMailCache.prototype.deleteMessages = function (aUids) { var oCurrFolder = this.folderList().currentFolder() ; if (oCurrFolder) { this.deleteMessagesFromFolder(oCurrFolder, aUids); } }; /** * @param {Object} oFolder * @param {Array} aUids */ CMailCache.prototype.deleteMessagesFromFolder = function (oFolder, aUids) { var oParameters = { 'Action': 'MessageDelete', 'Folder': oFolder.fullName(), 'Uids': aUids.join(',') } ; oFolder.markDeletedByUids(aUids); this.excludeDeletedMessages(); App.Ajax.send(oParameters, this.onMoveMessagesResponse, this); AfterLogicApi.runPluginHook('delete-messages', [AppData.Accounts.currentId(), oParameters.Folder, aUids]); }; /** * @param {boolean} bAlwaysForSender */ CMailCache.prototype.showExternalPictures = function (bAlwaysForSender) { var aFrom = [], oFolder = null ; if (this.currentMessage()) { aFrom = this.currentMessage().oFrom.aCollection; oFolder = this.folderList().getFolderByFullName(this.currentMessage().folder()); if (bAlwaysForSender && aFrom.length > 0) { oFolder.alwaysShowExternalPicturesForSender(aFrom[0].sEmail); } else { oFolder.showExternalPictures(this.currentMessage().uid()); } } }; /** * @param {string|null} sUid * @param {string} sFolder */ CMailCache.prototype.setCurrentMessage = function (sUid, sFolder) { var oCurrFolder = AppData.SingleMode ? this.folderList().getFolderByFullName(sFolder) : this.folderList().currentFolder(), oMessage = oCurrFolder && sUid ? oCurrFolder.oMessages[sUid] : null ; if (oMessage && !oMessage.deleted()) { this.currentMessage(oMessage); if (!this.currentMessage().seen()) { this.executeGroupOperation('MessageSetSeen', [this.currentMessage().uid()], 'seen', true); } oCurrFolder.getCompletelyFilledMessage(sUid, this.onCurrentMessageResponse, this); } else { this.currentMessage(null); } }; /** * @param {Object} oMessage * @param {string} sUid */ CMailCache.prototype.onCurrentMessageResponse = function (oMessage, sUid) { var sCurrentUid = this.currentMessage() ? this.currentMessage().uid() : ''; if (oMessage === null && sCurrentUid === sUid) { this.currentMessage(null); } else if (oMessage && sCurrentUid === sUid) { this.currentMessage.valueHasMutated(); // TODO N } }; /** * @param {string} sFullName * @param {string} sUid * @param {Function} fResponseHandler * @param {Object} oContext */ CMailCache.prototype.getMessage = function (sFullName, sUid, fResponseHandler, oContext) { var oFolder = this.folderList().getFolderByFullName(sFullName) ; if (oFolder) { oFolder.getCompletelyFilledMessage(sUid, fResponseHandler, oContext); } }; /** * @param {string} sAction * @param {Array} aUids * @param {string} sField * @param {boolean} bSetAction */ CMailCache.prototype.executeGroupOperation = function (sAction, aUids, sField, bSetAction) { var oCurrFolder = this.folderList().currentFolder(), oParameters = { 'Action': sAction, 'Folder': oCurrFolder ? oCurrFolder.fullName() : '', 'Uids': aUids.join(','), 'SetAction': bSetAction ? 1 : 0 }, iOffset = (this.page() - 1) * AppData.User.MailsPerPage, iUidsCount = aUids.length, iStarredCount = this.folderList().oStarredFolder ? this.folderList().oStarredFolder.messageCount() : 0, oStarredUidList = oCurrFolder.getUidList('', Enums.FolderFilter.Flagged) ; if (oCurrFolder) { if (oParameters.Action === 'MessageSetSeen') { this.iMessageSetSeenCount++; } App.Ajax.send(oParameters, this.onExecuteGroupOperationResponse, this); oCurrFolder.executeGroupOperation(sField, aUids, bSetAction); if (oCurrFolder.type() === Enums.FolderTypes.Inbox && sField === 'flagged') { if (this.uidList().filters() === Enums.FolderFilter.Flagged) { if (!bSetAction) { this.uidList().deleteUids(aUids); if (this.folderList().oStarredFolder) { this.folderList().oStarredFolder.messageCount(oStarredUidList.resultCount()); } } } else { oCurrFolder.removeFlaggedMessageListsFromCache(); if (this.uidList().search() === '' && this.folderList().oStarredFolder) { if (bSetAction) { this.folderList().oStarredFolder.messageCount(iStarredCount + iUidsCount); } else { this.folderList().oStarredFolder.messageCount((iStarredCount - iUidsCount > 0) ? iStarredCount - iUidsCount : 0); } } } } if (sField === 'seen') { oCurrFolder.removeUnseenMessageListsFromCache(); } if (this.uidList().filters() !== Enums.FolderFilter.Unseen || this.waitForUnseenMessages()) { this.setMessagesFromUidList(this.uidList(), iOffset, oCurrFolder.oMessages, true); } } }; /** * private */ /** * @param {Object} oResponse * @param {Object} oRequest */ CMailCache.prototype.onExecuteGroupOperationResponse = function (oResponse, oRequest) { if (oRequest.Action === 'MessageSetSeen') { this.iMessageSetSeenCount--; if (this.iMessageSetSeenCount < 0) { this.iMessageSetSeenCount = 0; } if (this.folderList().currentFolder() && this.iMessageSetSeenCount === 0 && (this.uidList().filters() !== Enums.FolderFilter.Unseen || this.waitForUnseenMessages())) { this.requestCurrentMessageList(this.folderList().currentFolder().fullName(), this.page(), this.uidList().search(), this.uidList().filters(), false); } } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CMailCache.prototype.onFolderListResponse = function (oResponse, oRequest) { var oFolderList = new CFolderListModel(), iAccountId = parseInt(oResponse.AccountID, 10), oFolderListOld = this.oFolderListItems[iAccountId], oNamedFolderListOld = oFolderListOld ? oFolderListOld.oNamedCollection : {} ; if (oResponse.Result === false) { App.Api.showErrorByCode(oResponse); if (oRequest.AccountID === this.currentAccountId() && this.messages().length === 0) { this.messagesLoading(false); this.messagesLoadingError(true); } } else { oFolderList.parse(iAccountId, oResponse.Result, oNamedFolderListOld); this.oFolderListItems[iAccountId] = oFolderList; setTimeout(_.bind(this.getAllFolderCounts, this, iAccountId), 2000); if (this.currentAccountId() === iAccountId) { this.folderList(oFolderList); } if (this.editedAccountId() === iAccountId) { this.editedFolderList(oFolderList); } if (AppData.Accounts.defaultId() === iAccountId) { this.defaultFolderList(oFolderList); } } this.folderListLoading(false); }; /** * @param {Object} oFolderList */ CMailCache.prototype.setCurrentFolderList = function (oFolderList) { var iAccountId = oFolderList.iAccountId; if (iAccountId === this.currentAccountId() && iAccountId !== this.folderList().iAccountId) { this.folderList(oFolderList); } }; /** * @param {number} iAccountId */ CMailCache.prototype.getAllFolderCounts = function (iAccountId) { var oFolderList = this.oFolderListItems[iAccountId], oInbox = oFolderList.inboxFolder(), sInboxUidnext = oInbox ? oInbox.uidNext() : '', aFolders = oFolderList ? oFolderList.getFoldersWithoutCountInfo() : [], oParameters = { 'Action': 'FolderCounts', 'Folders': aFolders, 'AccountID': iAccountId, 'InboxUidnext': sInboxUidnext } ; if (aFolders.length > 0) { App.Ajax.send(oParameters, this.onFolderCountsResponse, this); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CMailCache.prototype.onFolderCountsResponse = function (oResponse, oRequest) { var bCheckMailStarted = false, iAccountId = oResponse.AccountID, oFolderList = this.oFolderListItems[iAccountId], sCurrentFolderName = this.folderList().currentFolderFullName(), bSameAccount = this.currentAccountId() === iAccountId ; if (oResponse.Result === false) { App.Api.showErrorByCode(oResponse); } else { _.each(oResponse.Result && oResponse.Result.Counts, function(aData, sFullName) { if (_.isArray(aData) && aData.length > 3) { var iCount = aData[0], iUnseenCount = aData[1], sUidNext = aData[2], sHash = aData[3], bFolderHasChanges = false, bSameFolder = false, oFolder = null ; if (oFolderList) { oFolder = oFolderList.getFolderByFullName(sFullName); if (oFolder) { bSameFolder = bSameAccount && oFolder.fullName() === sCurrentFolderName; bFolderHasChanges = oFolder.setRelevantInformation(sUidNext, sHash, iCount, iUnseenCount, bSameFolder); if (bSameFolder && bFolderHasChanges && this.uidList().filters() !== Enums.FolderFilter.Unseen) { this.requestCurrentMessageList(oFolder.fullName(), this.page(), this.uidList().search(), this.uidList().filters(), false); bCheckMailStarted = true; } } } } }, this); this.showNotificationsForNewMessages(oResponse); } this.checkMailStarted(bCheckMailStarted); if (!this.checkMailStarted()) { this.setAutocheckmailTimer(); } }; /** * @param {Object} oResponse */ CMailCache.prototype.showNotificationsForNewMessages = function (oResponse) { var iNewLength = 0, oParameters = {} ; if(oResponse.Result.New && oResponse.Result.New.length) { iNewLength = oResponse.Result.New.length; oParameters = { action:'show', icon: 'skins/wm_logo_140x140.png', title: Utils.i18n('NOTIFICATION/NEW_MESSAGE_PLURAL', { 'COUNT': iNewLength }, null, iNewLength), timeout: 5000 }; if(iNewLength === 1) { oParameters.body = Utils.i18n('MESSAGE/HEADER_SUBJECT') + ': ' + oResponse.Result.New[0].Subject + '\r\n' + Utils.i18n('MESSAGE/HEADER_FROM') + ': ' + (_.map(oResponse.Result.New[0].From, function(oFrom, iKey) { return oFrom.DisplayName !== '' ? oFrom.DisplayName : oFrom.Email; })).join(', '); } App.desktopNotify(oParameters); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CMailCache.prototype.onCurrentMessageListResponse = function (oResponse, oRequest) { this.checkMailStarted(false); if (!oResponse.Result) { App.Api.showErrorByCode(oResponse); if (this.messagesLoading() === true && (this.messages().length === 0 || oResponse.ErrorCode !== Enums.Errors.NotDisplayedError)) { this.messagesLoadingError(true); } this.messagesLoading(false); this.setAutocheckmailTimer(); } else { this.messagesLoadingError(false); this.parseMessageList(oResponse, oRequest); if (this.deletedDraftMessageUid() !== '') { var iDeletedDraftMessageUid = this.deletedDraftMessageUid(), bIsMessageInList = _.find(oResponse.Result['@Collection'], function(oRawMessage) { return oRawMessage.Uid === iDeletedDraftMessageUid; } ) ; if(!bIsMessageInList) { this.setCurrentMessage('', ''); this.deletedDraftMessageUid(''); } } } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CMailCache.prototype.onMessageListResponse = function (oResponse, oRequest) { if (oResponse && oResponse.Result) { this.parseMessageList(oResponse, oRequest); } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CMailCache.prototype.parseMessageList = function (oResponse, oRequest) { var oResult = oResponse.Result, oFolderList = this.oFolderListItems[oResponse.AccountID], oFolder = null, oUidList = null, bTrustThreadInfo = (oRequest.UseThreads === '1'), bHasFolderChanges = false, bCurrentFolder = this.currentAccountId() === oResponse.AccountID && this.folderList().currentFolderFullName() === oResult.FolderName, bCurrentList = bCurrentFolder && this.uidList().search() === oResult.Search && this.uidList().filters() === oResult.Filters, bCurrentPage = this.page() === ((oResult.Offset / AppData.User.MailsPerPage) + 1), aNewFolderMessages = [] ; this.showNotificationsForNewMessages(oResponse); if (oResult !== false && oResult['@Object'] === 'Collection/MessageCollection') { oFolder = oFolderList.getFolderByFullName(oResult.FolderName); // perform before getUidList, because in case of a mismatch the uid list will be pre-cleaned oFolder.setRelevantInformation(oResult.UidNext.toString(), oResult.FolderHash, oResult.MessageCount, oResult.MessageUnseenCount, bCurrentFolder && !bCurrentList); bHasFolderChanges = oFolder.hasChanges(); oFolder.removeAllMessageListsFromCacheIfHasChanges(); oUidList = oFolder.getUidList(oResult.Search, oResult.Filters); oUidList.setUidsAndCount(oResult); _.each(oResult['@Collection'], function (oRawMessage) { var oFolderMessage = oFolder.parseAndCacheMessage(oRawMessage, false, bTrustThreadInfo); aNewFolderMessages.push(oFolderMessage); }, this); AfterLogicApi.runPluginHook('response-custom-messages', [oResponse.AccountID, oFolder.fullName(), aNewFolderMessages]); if (bCurrentList) { this.uidList(oUidList); if (bCurrentPage && (oUidList.filters() !== Enums.FolderFilter.Unseen || this.waitForUnseenMessages())) { this.setMessagesFromUidList(oUidList, oResult.Offset, oFolder.oMessages, true); this.messagesLoading(false); this.waitForUnseenMessages(false); this.setAutocheckmailTimer(); } } if (bHasFolderChanges && bCurrentFolder && (!bCurrentList || !bCurrentPage) && this.uidList().filters() !== Enums.FolderFilter.Unseen) { this.requestCurrentMessageList(this.folderList().currentFolderFullName(), this.page(), this.uidList().search(), this.uidList().filters(), false); } if (oFolder.type() === Enums.FolderTypes.Inbox && oUidList.filters() === Enums.FolderFilter.Flagged && oUidList.search() === '' && this.folderList().oStarredFolder) { this.folderList().oStarredFolder.messageCount(oUidList.resultCount()); } } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CMailCache.prototype.onMoveMessagesResponse = function (oResponse, oRequest) { var oResult = oResponse.Result, oFolder = this.folderList().getFolderByFullName(oRequest.Folder), oToFolder = this.folderList().getFolderByFullName(oRequest.ToFolder), bToFolderTrash = (oToFolder && (oToFolder.type() === Enums.FolderTypes.Trash)), bToFolderSpam = (oToFolder && (oToFolder.type() === Enums.FolderTypes.Spam)), oDiffs = null, sConfirm = bToFolderTrash ? Utils.i18n('MAILBOX/CONFIRM_MESSAGES_DELETE_WITHOUT_TRASH') : Utils.i18n('MAILBOX/CONFIRM_MESSAGES_MARK_SPAM_WITHOUT_SPAM'), fDeleteMessages = _.bind(function (bResult) { if (bResult && oFolder) { this.deleteMessagesFromFolder(oFolder, oRequest.Uids.split(',')); } }, this), oCurrFolder = this.folderList().currentFolder(), sCurrFolderFullName = oCurrFolder.fullName() ; if (oResult === false) { oDiffs = oFolder.revertDeleted(oRequest.Uids.split(',')); if (oToFolder) { oToFolder.addMessagesCountsDiff(-oDiffs.PlusDiff, -oDiffs.UnseenPlusDiff); if (oResponse.ErrorCode === Enums.Errors.ImapQuota && (bToFolderTrash || bToFolderSpam)) { App.Screens.showPopup(ConfirmPopup, [sConfirm, fDeleteMessages]); } else { App.Api.showErrorByCode(oResponse, Utils.i18n('MAILBOX/ERROR_MOVING_MESSAGES')); } } else { App.Api.showErrorByCode(oResponse, Utils.i18n('MAILBOX/ERROR_DELETING_MESSAGES')); } } else { oFolder.commitDeleted(oRequest.Uids.split(',')); } if (sCurrFolderFullName === oFolder.fullName() || oToFolder && sCurrFolderFullName === oToFolder.fullName()) { oCurrFolder.markHasChanges(); if (this.uidList().filters() !== Enums.FolderFilter.Unseen && this.uidList().filters() !== Enums.FolderFilter.Flagged) { this.requestCurrentMessageList(sCurrFolderFullName, this.page(), this.uidList().search(), '', false); } } else if (sCurrFolderFullName !== oFolder.fullName()) { App.Prefetcher.startFolderPrefetch(oFolder); } else if (oToFolder && sCurrFolderFullName !== oToFolder.fullName()) { App.Prefetcher.startFolderPrefetch(oToFolder); } }; CMailCache.prototype.onCopyMessagesResponse = function (oResponse, oRequest) { var oResult = oResponse.Result, oFolder = this.folderList().getFolderByFullName(oRequest.Folder), oToFolder = this.folderList().getFolderByFullName(oRequest.ToFolder), oCurrFolder = this.folderList().currentFolder(), sCurrFolderFullName = oCurrFolder.fullName() ; if (oResult === false) { App.Api.showErrorByCode(oResponse, Utils.i18n('MAILBOX/ERROR_COPYING_MESSAGES')); } if (sCurrFolderFullName === oFolder.fullName() || oToFolder && sCurrFolderFullName === oToFolder.fullName()) { oCurrFolder.markHasChanges(); this.requestCurrentMessageList(sCurrFolderFullName, this.page(), this.uidList().search(), '', false); } else if (sCurrFolderFullName !== oFolder.fullName()) { App.Prefetcher.startFolderPrefetch(oFolder); } else if (oToFolder && sCurrFolderFullName !== oToFolder.fullName()) { App.Prefetcher.startFolderPrefetch(oToFolder); } }; /** * @param {string} sSearch */ CMailCache.prototype.searchMessagesInCurrentFolder = function (sSearch) { var sFolder = this.folderList().currentFolderFullName() || 'INBOX', sUid = this.currentMessage() ? this.currentMessage().uid() : '', sFilters = this.uidList().filters() ; App.Routing.setHash(App.Links.mailbox(sFolder, 1, sUid, sSearch, sFilters)); }; /** * @param {string} sSearch */ CMailCache.prototype.searchMessagesInInbox = function (sSearch) { App.Routing.setHash(App.Links.mailbox(this.folderList().inboxFolderFullName() || 'INBOX', 1, '', sSearch, '')); }; CMailCache.prototype.countMessages = function (oCountedFolder) { var aSubfoldersMessagesCount = [], fCountRecursively = function(oFolder) { _.each(oFolder.subfolders(), function(oSubFolder, iKey) { if(oSubFolder.subscribed()) { aSubfoldersMessagesCount.push(oSubFolder.unseenMessageCount()); if (oSubFolder.subfolders().length && oSubFolder.subscribed()) { fCountRecursively(oSubFolder); } /*else if (!oSubFolder.canExpand()) //for unknown reasons does not work computed in folder model { oSubFolder.subfoldersMessagesCount(0); oSubFolder.subfoldersMessagesCount.valueHasMutated(); }*/ } }, this); } ; if (oCountedFolder.expanded() || oCountedFolder.isNamespace()) { oCountedFolder.subfoldersMessagesCount(0); } else { fCountRecursively(oCountedFolder); oCountedFolder.subfoldersMessagesCount( _.reduce(aSubfoldersMessagesCount, function(memo, num){ return memo + num; }, 0) ); } }; /** * @constructor */ function CContactsCache() { this.contacts = {}; this.responseHandlers = {}; this.vcardAttachments = []; this.recivedAnim = ko.observable(false).extend({'autoResetToFalse': 500}); } /** * @param {string} sEmail */ CContactsCache.prototype.clearInfoAboutEmail = function (sEmail) { this.contacts[sEmail] = undefined; }; /** * @param {string} sEmail * @param {Function} fResponseHandler * @param {Object} oResponseContext */ CContactsCache.prototype.getContactByEmail = function (sEmail, fResponseHandler, oResponseContext) { if (AppData.User.ShowContacts) { var oContact = this.contacts[sEmail], oParameters = { 'Action': 'ContactByEmail', 'Email': sEmail } ; if (oContact !== undefined) { fResponseHandler.apply(oResponseContext, [oContact, sEmail]); } else { this.responseHandlers[sEmail] = { Handler: fResponseHandler, Context: oResponseContext }; App.Ajax.send(oParameters, this.onContactByEmailResponse, this); } } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CContactsCache.prototype.onContactByEmailResponse = function (oResponse, oRequest) { var oContact = null, oResponseData = this.responseHandlers[oRequest.Email] ; if (oResponse.Result) { oContact = new CContactModel(); oContact.parse(oResponse.Result); } this.contacts[oRequest.Email] = oContact; if (oResponseData) { oResponseData.Handler.apply(oResponseData.Context, [oContact, oRequest.Email]); this.responseHandlers[oRequest.Email] = undefined; } }; /** * @param {Object} oVcard */ CContactsCache.prototype.addVcard = function (oVcard) { this.vcardAttachments.push(oVcard); }; /** * @param {Array} aUids */ CContactsCache.prototype.markVcardsNonexistentByUid = function (aUids) { _.each(this.vcardAttachments, function (oVcard) { if (-1 !== _.indexOf(aUids, oVcard.uid())) { oVcard.isExists(false); } }); }; /** * @param {string} sFile */ CContactsCache.prototype.markVcardExistentByFile = function (sFile) { _.each(this.vcardAttachments, function (oVcard) { if (oVcard.file() === sFile) { oVcard.isExists(true); } }); }; /** * @param {string} sName * @param {string} sEmail * @param {Function} fContactCreateResponse * @param {Object} oContactCreateContext */ CContactsCache.prototype.addToContacts = function (sName, sEmail, fContactCreateResponse, oContactCreateContext) { var oParameters = { 'Action': 'ContactCreate', 'PrimaryEmail': 'Home', 'UseFriendlyName': '1', 'FullName': sName, 'HomeEmail': sEmail } ; App.Ajax.send(oParameters, fContactCreateResponse, oContactCreateContext); App.ContactsCache.recivedAnim(true); }; /** * @constructor */ function CCalendarCache() { // uses only for ical-attachments this.calendars = ko.observableArray([]); this.calendarsLoadingStarted = ko.observable(false); this.icalAttachments = []; this.recivedAnim = ko.observable(false).extend({'autoResetToFalse': 500}); this.calendarSettingsChanged = ko.observable(false); this.calendarChanged = ko.observable(false); this.canRequestCalendarList = ko.observable(false); } /** * @param {Object} oIcal */ CCalendarCache.prototype.addIcal = function (oIcal) { this.icalAttachments.push(oIcal); if (this.calendars().length === 0 && this.canRequestCalendarList()) { this.requestCalendarList(); } }; CCalendarCache.prototype.firstRequestCalendarList = function () { this.canRequestCalendarList(true); if (this.icalAttachments.length > 0 && this.calendars().length === 0) { this.requestCalendarList(); } return this.calendarsLoadingStarted(); }; /** * @param {Object} oResponse * @param {Object} oRequest */ CCalendarCache.prototype.onCalendarListResponse = function (oResponse, oRequest) { if (oResponse && oResponse.Result) { var oAccounts = AppData.Accounts, iCurrentId = oAccounts.currentId(), iCurrentEmail = oAccounts.getAccount(iCurrentId).email(), aEditableCalendars = _.filter(oResponse.Result, function (oCalendar) { return oCalendar.Owner === iCurrentEmail || oCalendar.Access === Enums.CalendarAccess.Full || oCalendar.Access === Enums.CalendarAccess.Write; }) ; this.calendars(_.map(aEditableCalendars, function (oCalendar) { return {'name': oCalendar.Name + ' <' + oCalendar.Owner + '>', 'id': oCalendar.Id}; })); } this.calendarsLoadingStarted(false); }; CCalendarCache.prototype.requestCalendarList = function () { if (!this.calendarsLoadingStarted()) { App.Ajax.send({'Action': 'CalendarList'}, this.onCalendarListResponse, this); this.calendarsLoadingStarted(true); } }; /** * @param {string} sUid */ CCalendarCache.prototype.markIcalNonexistent = function (sUid) { _.each(this.icalAttachments, function (oIcal) { if (sUid === oIcal.uid()) { oIcal.onEventDelete(); } }); }; /** * @param {string} sFile * @param {string} sType * @param {string} sCancelDecision * @param {string} sReplyDecision * @param {string} sCalendarId * @param {string} sSelectedCalendar */ CCalendarCache.prototype.markIcalTypeByFile = function (sFile, sType, sCancelDecision, sReplyDecision, sCalendarId, sSelectedCalendar) { _.each(this.icalAttachments, function (oIcal) { if (sFile === oIcal.file()) { oIcal.type(sType); oIcal.cancelDecision(sCancelDecision); oIcal.replyDecision(sReplyDecision); oIcal.calendarId(sCalendarId); oIcal.selectedCalendarId(sSelectedCalendar); } }); }; /** * @param {string} sUid */ CCalendarCache.prototype.markIcalTentative = function (sUid) { _.each(this.icalAttachments, function (oIcal) { if (sUid === oIcal.uid()) { oIcal.onEventTentative(); } }); }; /** * @param {string} sUid */ CCalendarCache.prototype.markIcalAccepted = function (sUid) { _.each(this.icalAttachments, function (oIcal) { if (sUid === oIcal.uid()) { oIcal.onEventAccept(); } }); }; /** * @constructor */ function AbstractApp() { this.browser = new CBrowser(); this.favico = window.Favico ? new window.Favico({ 'animation': 'none' }) : null; this.Ajax = new CAjax(); this.Screens = new CScreens(); this.Api = new CApi(); this.Storage = new CStorage(); this.helpdeskUnseenCount = ko.observable(0); this.mailUnseenCount = ko.observable(0); } AbstractApp.prototype.init = function () { }; AbstractApp.prototype.collectScreensData = function () { }; AbstractApp.prototype.run = function () { }; AbstractApp.prototype.momentDateTriggerCallback = function () { var oItem = ko.dataFor(this); if (oItem && oItem.updateMomentDate) { oItem.updateMomentDate(); } }; AbstractApp.prototype.fastMomentDateTrigger = function () { $('.moment-date-trigger-fast').each(this.momentDateTriggerCallback); }; /** * @param {string=} sTitle */ AbstractApp.prototype.setTitle = function (sTitle) { document.title = '.'; document.title = sTitle || ''; }; /** * @constructor */ function AppBase() { AbstractApp.call(this); this.headerTabs = ko.observableArray([]); this.screensTitle = {}; this.Phone = null; this.Routing = new CRouting(); this.Links = new CLinkBuilder(); this.MessageSender = new CMessageSender(); this.Prefetcher = new CPrefetcher(); this.MailCache = null; this.ContactsCache = new CContactsCache(); this.CalendarCache = new CCalendarCache(); this.currentScreen = this.Screens.currentScreen; this.currentScreen.subscribe(this.setTitle, this); this.focused = ko.observable(true); this.focused.subscribe(function() { if (!AppData.SingleMode && !window.opener) { this.setTitle(); } }, this); this.filesRecievedAnim = ko.observable(false).extend({'autoResetToFalse': 500}); this.init(); this.newMessagesCount = this.MailCache.newMessagesCount; this.newMessagesCount.subscribe(this.setTitle, this); this.currentMessage = this.MailCache.currentMessage; this.currentMessage.subscribe(this.setTitle, this); this.notification = null; this.initHeaderInfo(); this.sessionTimeoutFunctions = []; this.initSessionTimeout(); } _.extend(AppBase.prototype, AbstractApp.prototype); // proto AppBase.prototype.initPhone = function (bAllow) { return null; }; AppBase.prototype.init = function () { var self = this, oRawUserSettings = /** @type {Object} */ AppData['User'], oUserSettings = new CUserSettingsModel(), aRawAccounts = AppData['Accounts'], oAccounts = new CAccountListModel(), oRawAppSettings = /** @type {Object} */ AppData['App'], oAppSettings = new CAppSettingsModel(!!oRawAppSettings.AllowOpenPGP && this.Api.isPgpSupported()) ; oAppSettings.parse(oRawAppSettings); AppData.App = oAppSettings; oUserSettings.parse(oRawUserSettings); AppData.User = oUserSettings; oAccounts.parse(Utils.pInt(AppData['Default']), aRawAccounts); AppData.Accounts = oAccounts; this.MailCache = new CMailCache(); this.Phone = this.initPhone(oUserSettings.AllowVoice && !this.browser.ie && !bMobileApp); this.useGoogleAnalytics(); this.collectScreensData();//*// $(window).unload(function() { Utils.WindowOpener.closeAll(); }); this.nowMoment = ko.observable(moment()); window.setInterval(function () { self.fastMomentDateTrigger(); if (moment().diff(self.nowMoment(), 'days') > 0) { self.nowMoment(moment()); } }, 1000 * 60); }; AppBase.prototype.collectScreensData = function () {}; /** * @param {Function} fHelpdeskUpdate */ AppBase.prototype.registerHelpdeskUpdateFunction = function (fHelpdeskUpdate) { this.fHelpdeskUpdate = fHelpdeskUpdate; }; AppBase.prototype.updateHelpdesk = function () { if (this.fHelpdeskUpdate) { this.fHelpdeskUpdate(); } }; AppBase.prototype.useGoogleAnalytics = function () { var ga = null, s = null ; if (AppData.App.GoogleAnalyticsAccount && 0 < AppData.App.GoogleAnalyticsAccount.length) { window._gaq = window._gaq || []; window._gaq.push(['_setAccount', AppData.App.GoogleAnalyticsAccount]); window._gaq.push(['_trackPageview']); ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' === document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); } }; AppBase.prototype.tokenProblem = function () { var sReloadFunc= 'window.location.reload(); return false;', sHtmlError = Utils.i18n('WARNING/TOKEN_PROBLEM_HTML', {'RELOAD_FUNC': sReloadFunc}) ; AppData.Auth = false; App.Api.showError(sHtmlError, true, true); }; /** * @param {number=} iLastErrorCode */ AppBase.prototype.logout = function (iLastErrorCode) { var oParameters = {'Action': 'Logout'}; if (iLastErrorCode) { oParameters.LastErrorCode = iLastErrorCode; } App.Ajax.send(oParameters, this.onLogout, this); AppData.Auth = false; }; AppBase.prototype.authProblem = function () { this.logout(Enums.Errors.AuthError); }; AppBase.prototype.onLogout = function () { Utils.WindowOpener.closeAll(); App.Routing.finalize(); if (AppData.App.CustomLogoutUrl !== '') { window.location.href = AppData.App.CustomLogoutUrl; } else { window.location.reload(); } }; AppBase.prototype.getAccounts = function () { return AppData.Accounts; }; AppBase.prototype.run = function () { this.Screens.init(); if (bIsIosDevice && AppData && AppData['Auth'] && AppData.App.IosDetectOnLogin && App.browser.safari && AppData.App.AllowIosProfile) { window.location.href = '?ios'; } else if (AppData && AppData['Auth']) { AppData.SingleMode = this.Routing.isSingleMode(); if (AppData.SingleMode && window.opener) { AppData.Accounts.populateIdentitiesFromSourceAccount(window.opener.App.getAccounts()); } if (AppData.App.AllowWebMail) { this.MailCache.init(); } if (AppData.HelpdeskRedirect && this.Routing.currentScreen !== Enums.Screens.Helpdesk) { this.Routing.setHash([Enums.Screens.Helpdesk]); } if (AppData.App.DefaultTab !== '') { this.Routing.init(AppData.App.DefaultTab); } else { if (AppData.App.AllowWebMail) { this.Routing.init(Enums.Screens.Mailbox); } else if (this.headerTabs()[0]) { this.Routing.init(this.headerTabs()[0].name); } } } else if (AppData && AppData.App.CustomLoginUrl !== '') { window.location.href = AppData.App.CustomLoginUrl; } else { this.Screens.showCurrentScreen(Enums.Screens.Login); if (AppData && AppData['LastErrorCode'] === Enums.Errors.AuthError) { this.Api.showError(Utils.i18n('WARNING/AUTH_PROBLEM'), false, true); } } // prevent load phone in other tabs if (this.Phone && window.localStorage) { var self = this; $(window).on('storage', function(e) { if (window.localStorage.getItem('phoneLoad') !== 'false') { window.localStorage.setItem('phoneLoad', 'false');//triggering from other tabs } }); window.localStorage.setItem('phoneLoad', (Math.floor(Math.random() * (1000 - 100) + 100)).toString());// random - storage event triggering only if key has been changed window.setTimeout(function() {// wait until the triggering storage event if (!AppData.SingleMode && self.Phone && (window.localStorage.getItem('phoneLoad') !== 'false' || window.sessionStorage.getItem('phoneTab'))) { self.Phone.init(); window.sessionStorage.setItem('phoneTab', 'true');// for phone tab detection, live only one session } }, 1000); } Utils.registerMailto(this.browser.firefox); }; /** * @param {string} sName * @return {string} */ AppBase.prototype.getHelpLink = function (sName) { return AppData && AppData['Links'] && AppData['Links'][sName] ? AppData['Links'][sName] : ''; }; /** * @param {string} sName * @param {string} sHeaderTitle * @param {string} sDocumentTitle * @param {string} sTemplateName * @param {Object} oViewModelClass * @param {boolean} koVisibleTab = undefined * @param {Object=} koRecivedAnim = undefined */ AppBase.prototype.addScreenToHeader = function (sName, sHeaderTitle, sDocumentTitle, sTemplateName, oViewModelClass, koVisibleTab, koRecivedAnim) { var mHash = this.Routing.buildHashFromArray([sName]), oApp = this ; if (sName === Enums.Screens.Helpdesk) { mHash = ko.computed(function () { return '#' + oApp.Routing.lastHelpdeskHash(); }); } Enums.Screens[sName] = sName; this.Screens.oScreens[sName] = { 'Model': oViewModelClass, 'TemplateName': sTemplateName }; this.headerTabs.push({ 'name': sName, 'title': sHeaderTitle, 'hash': mHash, 'koVisibleTab': koVisibleTab, 'koRecivedAnim': koRecivedAnim }); this.screensTitle[sName] = sDocumentTitle; }; AppBase.prototype.registerSessionTimeoutFunction = function (oSessionTimeoutFunction) { this.sessionTimeoutFunctions.push(oSessionTimeoutFunction); }; AppBase.prototype.initSessionTimeout = function () { this.setSessionTimeout(); $('body') .on('click', _.bind(this.setSessionTimeout, this)) .on('keydown', _.bind(this.setSessionTimeout, this)) ; }; AppBase.prototype.setSessionTimeout = function () { clearTimeout(this.iSessionTimeout); if (AppData && AppData.Auth && AppData.App.IdleSessionTimeout) { this.iSessionTimeout = setTimeout(_.bind(this.logoutBySessionTimeout, this), AppData.App.IdleSessionTimeout); } }; AppBase.prototype.logoutBySessionTimeout = function () { if (AppData.Auth) { _.each(this.sessionTimeoutFunctions, function (oFunc) { oFunc(); }); _.delay(_.bind(this.logout, this), 500); } }; AppBase.prototype.initHeaderInfo = function () { if (this.browser.ie) { $(document) .bind('focusin', _.bind(this.onFocus, this)) .bind('focusout', _.bind(this.onBlur, this)) ; } else { $(window) .bind('focus', _.bind(this.onFocus, this)) .bind('blur', _.bind(this.onBlur, this)) ; } }; AppBase.prototype.onFocus = function () { this.focused(true); }; AppBase.prototype.onBlur = function () { this.focused(false); }; /** * @param {string=} sTitle */ AppBase.prototype.setTitle = function (sTitle) { var sNewMessagesCount = this.newMessagesCount(), sTemp = '' ; sTitle = sTitle || ''; if (this.focused() || sNewMessagesCount === 0 || !AppData.App.AllowWebMail) { sTitle = this.getTitleByScreen(); } else { sTitle = Utils.i18n('TITLE/HAS_UNSEEN_MESSAGES_PLURAL', {'COUNT': sNewMessagesCount}, null, sNewMessagesCount) + ' - ' + AppData.Accounts.getEmail(); } if (this.favico) { sTemp = 99 < sNewMessagesCount ? '99+' : sNewMessagesCount; if (this.favico._cachevalue !== sTemp) { this.favico._cachevalue = sTemp; this.favico.badge(sTemp); } } document.title = '.'; document.title = sTitle; }; AppBase.prototype.getTitleByScreen = function () { var sTitle = '', sSubject = '' ; try { if (this.MailCache.currentMessage()) { sSubject = this.MailCache.currentMessage().subject(); } } catch (oError) {} switch (this.currentScreen()) { case Enums.Screens.Login: sTitle = Utils.i18n('TITLE/LOGIN', null, ''); break; case Enums.Screens.Mailbox: sTitle = AppData.Accounts.getEmail() + ' - ' + Utils.i18n('TITLE/MAILBOX'); break; case Enums.Screens.Compose: case Enums.Screens.SingleCompose: sTitle = AppData.Accounts.getEmail() + ' - ' + Utils.i18n('TITLE/COMPOSE'); break; case Enums.Screens.SingleMessageView: sTitle = AppData.Accounts.getEmail() + ' - ' + Utils.i18n('TITLE/VIEW_MESSAGE'); if (sSubject) { sTitle = sSubject + ' - ' + sTitle; } break; default: if (this.screensTitle[this.currentScreen()]) { sTitle = this.screensTitle[this.currentScreen()]; } break; } if (sTitle === '') { sTitle = AppData.App.SiteName; } else { sTitle += (AppData.App.SiteName && AppData.App.SiteName !== '') ? ' - ' + AppData.App.SiteName : ''; } return sTitle; }; /** * @param {string} sAction * @param {string=} sTitle * @param {string=} sBody * @param {string=} sIcon * @param {Function=} fnCallback * @param {number=} iTimeout */ AppBase.prototype.desktopNotify = function (sAction, sTitle, sBody, sIcon, fnCallback, iTimeout) { Utils.desktopNotify(sAction, sTitle, sBody, sIcon, fnCallback, iTimeout); }; /** * @constructor */ function AppMain() { AppBase.call(this); } _.extend(AppMain.prototype, AppBase.prototype); AppMain.prototype.initPhone = function (bAllow) { return bAllow ? new CPhone() : null; }; AppMain.prototype.collectScreensData = function () { if (AppData.User.ShowContacts) { this.addScreenToHeader('contacts', Utils.i18n('HEADER/CONTACTS'), Utils.i18n('TITLE/CONTACTS'), 'Contacts_ContactsViewModel', CContactsViewModel, true, this.ContactsCache.recivedAnim); } if (AppData.User.AllowCalendar) { this.addScreenToHeader('calendar', Utils.i18n('HEADER/CALENDAR'), Utils.i18n('TITLE/CALENDAR'), 'Calendar_CalendarViewModel', CCalendarViewModel, true, this.CalendarCache.recivedAnim, true); } if (AppData.User.IsFilesSupported) { this.addScreenToHeader('files', Utils.i18n('HEADER/FILESTORAGE'), Utils.i18n('TITLE/FILESTORAGE'), 'FileStorage_FileStorageViewModel', CFileStorageViewModel, AppData.User.filesEnable, this.filesRecievedAnim); } if (AppData.User.IsHelpdeskSupported) { this.addScreenToHeader('helpdesk', Utils.i18n('HEADER/HELPDESK'), Utils.i18n('TITLE/HELPDESK'), 'Helpdesk_HelpdeskViewModel', CHelpdeskViewModel, true); } }; App = new AppMain(); window.App = App; /** * AppData.IsMobile: * -1 - first time, mobile is not determined * 0 - mobile is switched off * 1 - mobile is switched on */ if (AppData.IsMobile === -1) { /*jshint onevar: false*/ var bMobile = !window.matchMedia('all and (min-width: 768px)').matches ? 1 : 0; /*jshint onevar: true*/ window.App.Ajax.send({ 'Action': 'SetMobile', 'Mobile': bMobile }, function () { if (bMobile) { window.location.reload(); } else { $(function () { _.defer(function () { App.run(); }); }); } }, this); } else { $(function () { _.defer(function () { App.run(); }); }); } if (window.Modernizr && navigator) { window.Modernizr.addTest('mobile', function() { return bMobileApp; }); } window.AfterLogicApi = AfterLogicApi; // export window.Enums = Enums; $html.removeClass('no-js').addClass('js'); if ($html.hasClass('pdf')) { aViewMimeTypes.push('application/pdf'); aViewMimeTypes.push('application/x-pdf'); } }(jQuery, window, ko, crossroads, hasher));