diff --git a/dev/App/Admin.js b/dev/App/Admin.js index 8995d0448..872b165af 100644 --- a/dev/App/Admin.js +++ b/dev/App/Admin.js @@ -21,7 +21,7 @@ LicenseStore = require('Stores/Admin/License'), PackageStore = require('Stores/Admin/Package'), CoreStore = require('Stores/Admin/Core'), - Remote = require('Storage/Admin/Remote'), + Remote = require('Remote/Admin/Ajax'), kn = require('Knoin/Knoin'), AbstractApp = require('App/Abstract') diff --git a/dev/App/User.js b/dev/App/User.js index 2e0892ea6..f0eb9cb8c 100644 --- a/dev/App/User.js +++ b/dev/App/User.js @@ -21,6 +21,8 @@ kn = require('Knoin/Knoin'), + Cache = require('Common/Cache'), + SocialStore = require('Stores/Social'), AppStore = require('Stores/User/App'), SettingsStore = require('Stores/User/Settings'), @@ -29,16 +31,16 @@ TemplateStore = require('Stores/User/Template'), FolderStore = require('Stores/User/Folder'), PgpStore = require('Stores/User/Pgp'), + MessageStore = require('Stores/User/Message'), + ContactStore = require('Stores/User/Contact'), Local = require('Storage/Client'), Settings = require('Storage/Settings'), - Data = require('Storage/User/Data'), - Cache = require('Storage/User/Cache'), - Remote = require('Storage/User/Remote'), + + Remote = require('Remote/User/Ajax'), EmailModel = require('Model/Email'), FolderModel = require('Model/Folder'), - MessageModel = require('Model/Message'), AccountModel = require('Model/Account'), IdentityModel = require('Model/Identity'), TemplateModel = require('Model/Template'), @@ -146,11 +148,11 @@ AppUser.prototype.reloadFlagsCurrentMessageListAndMessageFromCache = function () { - _.each(Data.messageList(), function (oMessage) { + _.each(MessageStore.messageList(), function (oMessage) { Cache.initMessageFlagsFromCache(oMessage); }); - Cache.initMessageFlagsFromCache(Data.message()); + Cache.initMessageFlagsFromCache(MessageStore.message()); }; /** @@ -160,45 +162,45 @@ AppUser.prototype.reloadMessageList = function (bDropPagePosition, bDropCurrenFolderCache) { var - self = this, - iOffset = (Data.messageListPage() - 1) * SettingsStore.messagesPerPage() + iOffset = (MessageStore.messageListPage() - 1) * SettingsStore.messagesPerPage() ; if (Utils.isUnd(bDropCurrenFolderCache) ? false : !!bDropCurrenFolderCache) { - Cache.setFolderHash(Data.currentFolderFullNameRaw(), ''); + Cache.setFolderHash(FolderStore.currentFolderFullNameRaw(), ''); } if (Utils.isUnd(bDropPagePosition) ? false : !!bDropPagePosition) { - Data.messageListPage(1); + MessageStore.messageListPage(1); iOffset = 0; } - Data.messageListLoading(true); + MessageStore.messageListLoading(true); Remote.messageList(function (sResult, oData, bCached) { if (Enums.StorageResultType.Success === sResult && oData && oData.Result) { - Data.messageListError(''); - Data.messageListLoading(false); - self.setMessageList(oData, bCached); + MessageStore.messageListError(''); + MessageStore.messageListLoading(false); + + MessageStore.setMessageList(oData, bCached); } else if (Enums.StorageResultType.Unload === sResult) { - Data.messageListError(''); - Data.messageListLoading(false); + MessageStore.messageListError(''); + MessageStore.messageListLoading(false); } else if (Enums.StorageResultType.Abort !== sResult) { - Data.messageList([]); - Data.messageListLoading(false); - Data.messageListError(oData && oData.ErrorCode ? + MessageStore.messageList([]); + MessageStore.messageListLoading(false); + MessageStore.messageListError(oData && oData.ErrorCode ? Translator.getNotification(oData.ErrorCode) : Translator.i18n('NOTIFICATIONS/CANT_GET_MESSAGE_LIST') ); } - }, Data.currentFolderFullNameRaw(), iOffset, SettingsStore.messagesPerPage(), Data.messageListSearch()); + }, FolderStore.currentFolderFullNameRaw(), iOffset, SettingsStore.messagesPerPage(), MessageStore.messageListSearch()); }; AppUser.prototype.recacheInboxMessageList = function () @@ -217,8 +219,8 @@ */ AppUser.prototype.contactsSync = function (fResultFunc) { - var oContacts = Data.contacts; - if (oContacts.importing() || oContacts.syncing() || !Data.enableContactsSync() || !Data.allowContactsSync()) + var oContacts = ContactStore.contacts; + if (oContacts.importing() || oContacts.syncing() || !ContactStore.enableContactsSync() || !ContactStore.allowContactsSync()) { return false; } @@ -296,7 +298,7 @@ AppUser.prototype.moveOrDeleteResponseHelper = function (sResult, oData) { - if (Enums.StorageResultType.Success === sResult && Data.currentFolder()) + if (Enums.StorageResultType.Success === sResult && FolderStore.currentFolder()) { if (oData && Utils.isArray(oData.Result) && 2 === oData.Result.length) { @@ -304,7 +306,7 @@ } else { - Cache.setFolderHash(Data.currentFolderFullNameRaw(), ''); + Cache.setFolderHash(FolderStore.currentFolderFullNameRaw(), ''); if (oData && -1 < Utils.inArray(oData.ErrorCode, [Enums.Notification.CantMoveMessage, Enums.Notification.CantCopyMessage])) @@ -313,7 +315,7 @@ } } - this.reloadMessageListHelper(0 === Data.messageList().length); + this.reloadMessageListHelper(0 === MessageStore.messageList().length); this.quotaDebounce(); } }; @@ -325,7 +327,7 @@ AppUser.prototype.deleteMessagesFromFolderWithoutCheck = function (sFromFolderFullNameRaw, aUidForRemove) { this.messagesDeleteHelper(sFromFolderFullNameRaw, aUidForRemove); - Data.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove); + MessageStore.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove); }; /** @@ -382,14 +384,14 @@ kn.showScreenPopup(require('View/Popup/Ask'), [Translator.i18n('POPUPS_ASK/DESC_WANT_DELETE_MESSAGES'), function () { self.messagesDeleteHelper(sFromFolderFullNameRaw, aUidForRemove); - Data.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove); + MessageStore.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove); }]); } else if (oMoveFolder) { this.messagesMoveHelper(sFromFolderFullNameRaw, oMoveFolder.fullNameRaw, aUidForRemove); - Data.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove, oMoveFolder.fullNameRaw); + MessageStore.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove, oMoveFolder.fullNameRaw); } }; @@ -419,7 +421,7 @@ this.messagesMoveHelper(oFromFolder.fullNameRaw, oToFolder.fullNameRaw, aUidForMove); } - Data.removeMessagesFromList(oFromFolder.fullNameRaw, aUidForMove, oToFolder.fullNameRaw, bCopy); + MessageStore.removeMessagesFromList(oFromFolder.fullNameRaw, aUidForMove, oToFolder.fullNameRaw, bCopy); return true; } } @@ -432,12 +434,12 @@ */ AppUser.prototype.folders = function (fCallback) { - Data.foldersLoading(true); + FolderStore.foldersLoading(true); Remote.folders(_.bind(function (sResult, oData) { var bResult = false; - Data.foldersLoading(false); + FolderStore.foldersLoading(false); if (Enums.StorageResultType.Success === sResult && oData && oData.Result) { @@ -707,11 +709,11 @@ } } - Data.initUidNextAndNewMessages(oFolder.fullNameRaw, oData.Result.UidNext, oData.Result.NewMessages); + MessageStore.initUidNextAndNewMessages(oFolder.fullNameRaw, oData.Result.UidNext, oData.Result.NewMessages); if (oData.Result.Hash !== sHash || '' === sHash) { - if (oFolder.fullNameRaw === Data.currentFolderFullNameRaw()) + if (oFolder.fullNameRaw === FolderStore.currentFolderFullNameRaw()) { self.reloadMessageList(); } @@ -722,9 +724,9 @@ } else if (bUnreadCountChange) { - if (oFolder.fullNameRaw === Data.currentFolderFullNameRaw()) + if (oFolder.fullNameRaw === FolderStore.currentFolderFullNameRaw()) { - aList = Data.messageList(); + aList = MessageStore.messageList(); if (Utils.isNonEmptyArray(aList)) { self.folderInformation(oFolder.fullNameRaw, aList); @@ -748,7 +750,7 @@ var self = this, iUtc = moment().unix(), - aFolders = Data.getNextFolderNames(bBoot) + aFolders = FolderStore.getNextFolderNames(bBoot) ; if (Utils.isNonEmptyArray(aFolders)) @@ -798,16 +800,16 @@ if (oItem.Hash !== sHash || '' === sHash) { - if (oFolder.fullNameRaw === Data.currentFolderFullNameRaw()) + if (oFolder.fullNameRaw === FolderStore.currentFolderFullNameRaw()) { self.reloadMessageList(); } } else if (bUnreadCountChange) { - if (oFolder.fullNameRaw === Data.currentFolderFullNameRaw()) + if (oFolder.fullNameRaw === FolderStore.currentFolderFullNameRaw()) { - aList = Data.messageList(); + aList = MessageStore.messageList(); if (Utils.isNonEmptyArray(aList)) { self.folderInformation(oFolder.fullNameRaw, aList); @@ -941,136 +943,6 @@ }, sQuery); }; - AppUser.prototype.setMessageList = function (oData, bCached) - { - if (oData && oData.Result && 'Collection/MessageCollection' === oData.Result['@Object'] && - oData.Result['@Collection'] && Utils.isArray(oData.Result['@Collection'])) - { - var - mLastCollapsedThreadUids = null, - iIndex = 0, - iLen = 0, - iCount = 0, - iOffset = 0, - aList = [], - iUtc = moment().unix(), - aStaticList = Data.staticMessageList, - oJsonMessage = null, - oMessage = null, - oFolder = null, - iNewCount = 0, - bUnreadCountChange = false - ; - - iCount = Utils.pInt(oData.Result.MessageResultCount); - iOffset = Utils.pInt(oData.Result.Offset); - - if (Utils.isNonEmptyArray(oData.Result.LastCollapsedThreadUids)) - { - mLastCollapsedThreadUids = oData.Result.LastCollapsedThreadUids; - } - - oFolder = Cache.getFolderFromCacheList( - Utils.isNormal(oData.Result.Folder) ? oData.Result.Folder : ''); - - if (oFolder && !bCached) - { - oFolder.interval = iUtc; - - Cache.setFolderHash(oData.Result.Folder, oData.Result.FolderHash); - - if (Utils.isNormal(oData.Result.MessageCount)) - { - oFolder.messageCountAll(oData.Result.MessageCount); - } - - if (Utils.isNormal(oData.Result.MessageUnseenCount)) - { - if (Utils.pInt(oFolder.messageCountUnread()) !== Utils.pInt(oData.Result.MessageUnseenCount)) - { - bUnreadCountChange = true; - } - - oFolder.messageCountUnread(oData.Result.MessageUnseenCount); - } - - Data.initUidNextAndNewMessages(oFolder.fullNameRaw, oData.Result.UidNext, oData.Result.NewMessages); - } - - if (bUnreadCountChange && oFolder) - { - Cache.clearMessageFlagsFromCacheByFolder(oFolder.fullNameRaw); - } - - for (iIndex = 0, iLen = oData.Result['@Collection'].length; iIndex < iLen; iIndex++) - { - oJsonMessage = oData.Result['@Collection'][iIndex]; - if (oJsonMessage && 'Object/Message' === oJsonMessage['@Object']) - { - oMessage = aStaticList[iIndex]; - if (!oMessage || !oMessage.initByJson(oJsonMessage)) - { - oMessage = MessageModel.newInstanceFromJson(oJsonMessage); - } - - if (oMessage) - { - if (Cache.hasNewMessageAndRemoveFromCache(oMessage.folderFullNameRaw, oMessage.uid) && 5 >= iNewCount) - { - iNewCount++; - oMessage.newForAnimation(true); - } - - oMessage.deleted(false); - - if (bCached) - { - Cache.initMessageFlagsFromCache(oMessage); - } - else - { - Cache.storeMessageFlagsToCache(oMessage); - } - - oMessage.lastInCollapsedThread(mLastCollapsedThreadUids && -1 < Utils.inArray(Utils.pInt(oMessage.uid), mLastCollapsedThreadUids) ? true : false); - - aList.push(oMessage); - } - } - } - - Data.messageListCount(iCount); - Data.messageListSearch(Utils.isNormal(oData.Result.Search) ? oData.Result.Search : ''); - Data.messageListPage(window.Math.ceil((iOffset / SettingsStore.messagesPerPage()) + 1)); - Data.messageListEndFolder(Utils.isNormal(oData.Result.Folder) ? oData.Result.Folder : ''); - Data.messageListEndSearch(Utils.isNormal(oData.Result.Search) ? oData.Result.Search : ''); - Data.messageListEndPage(Data.messageListPage()); - - Data.messageList(aList); - Data.messageListIsNotCompleted(false); - - if (aStaticList.length < aList.length) - { - Data.staticMessageList = aList; - } - - Cache.clearNewMessageCache(); - - if (oFolder && (bCached || bUnreadCountChange || SettingsStore.useThreads())) - { - this.folderInformation(oFolder.fullNameRaw, aList); - } - } - else - { - Data.messageListCount(0); - Data.messageList([]); - Data.messageListError(Translator.getNotification( - oData && oData.ErrorCode ? oData.ErrorCode : Enums.Notification.CantGetMessageList - )); - } - }; - /** * @param {string} sNamespace * @param {Array} aFolders @@ -1163,13 +1035,13 @@ { if (!Utils.isUnd(oData.Result.Namespace)) { - Data.namespace = oData.Result.Namespace; + FolderStore.namespace = oData.Result.Namespace; } AppStore.threadsAllowed(!!Settings.settingsGet('UseImapThread') && oData.Result.IsThreadsSupported && true); - Data.folderList(this.folderResponseParseRec(Data.namespace, oData.Result['@Collection'])); + FolderStore.folderList(this.folderResponseParseRec(FolderStore.namespace, oData.Result['@Collection'])); if (oData.Result['SystemFolders'] && '' === '' + Settings.settingsGet('SentFolder') + @@ -1525,7 +1397,7 @@ }); Events.sub('interval.3m', function () { - var sF = Data.currentFolderFullNameRaw(); + var sF = FolderStore.currentFolderFullNameRaw(); if (Cache.getFolderInboxName() !== sF) { self.folderInformation(sF); @@ -1562,7 +1434,7 @@ self.accountsAndIdentities(true); _.delay(function () { - var sF = Data.currentFolderFullNameRaw(); + var sF = FolderStore.currentFolderFullNameRaw(); if (Cache.getFolderInboxName() !== sF) { self.folderInformation(sF); diff --git a/dev/Storage/User/Cache.js b/dev/Common/Cache.js similarity index 100% rename from dev/Storage/User/Cache.js rename to dev/Common/Cache.js diff --git a/dev/Common/Globals.js b/dev/Common/Globals.js index cf5e999b1..c70e1839b 100644 --- a/dev/Common/Globals.js +++ b/dev/Common/Globals.js @@ -129,7 +129,15 @@ 'removeDialogTabs': 'link:advanced;link:target;image:advanced;images:advanced', 'extraPlugins': 'plain,signature', + 'allowedContent': true, + 'extraAllowedContent': true, + + 'forceEnterMode': true, + + 'autoParagraph': false, + 'fillEmptyBlocks': false, + 'ignoreEmptyParagraph': true, 'font_defaultLabel': 'Arial', 'fontSize_defaultLabel': '13', diff --git a/dev/Common/HtmlEditor.js b/dev/Common/HtmlEditor.js index 7a4bf479a..73e3fa328 100644 --- a/dev/Common/HtmlEditor.js +++ b/dev/Common/HtmlEditor.js @@ -267,6 +267,19 @@ window.CKEDITOR.env.isCompatible = true; } +// oConfig.allowedContent = { +// $1: { +// elements: window.CKEDITOR.dtd, +// attributes: true, +// styles: true, +// classes: true +// } +// }; +// +// oConfig.disallowedContent = 'script; style; iframe; frame; *[on*]'; + + window.CKEDITOR.dtd.$removeEmpty['p'] = 1; + self.editor = window.CKEDITOR.appendTo(self.$element[0], oConfig); self.editor.on('key', function(oEvent) { diff --git a/dev/Model/Filter.js b/dev/Model/Filter.js index e72a0f1f8..e919427d0 100644 --- a/dev/Model/Filter.js +++ b/dev/Model/Filter.js @@ -11,7 +11,7 @@ Utils = require('Common/Utils'), Translator = require('Common/Translator'), - Cache = require('Storage/User/Cache'), + Cache = require('Common/Cache'), FilterConditionModel = require('Model/FilterCondition'), diff --git a/dev/Model/Folder.js b/dev/Model/Folder.js index abd6b489f..668fec202 100644 --- a/dev/Model/Folder.js +++ b/dev/Model/Folder.js @@ -12,7 +12,7 @@ Events = require('Common/Events'), Translator = require('Common/Translator'), - Cache = require('Storage/User/Cache'), + Cache = require('Common/Cache'), AbstractModel = require('Knoin/AbstractModel') ; diff --git a/dev/Model/Message.js b/dev/Model/Message.js index 30a01c860..e1f960f5a 100644 --- a/dev/Model/Message.js +++ b/dev/Model/Message.js @@ -1205,9 +1205,8 @@ var aRes = [], mPgpMessage = null, - Data = require('Storage/User/Data'), sFrom = this.from && this.from[0] && this.from[0].email ? this.from[0].email : '', - aPublicKeys = Data.findPublicKeysByEmail(sFrom), + aPublicKeys = PgpStore.findPublicKeysByEmail(sFrom), oValidKey = null, oValidSysKey = null, sPlain = '' @@ -1233,7 +1232,7 @@ if (oValidKey) { - oValidSysKey = Data.findPublicKeyByHex(oValidKey.keyid.toHex()); + oValidSysKey = PgpStore.findPublicKeyByHex(oValidKey.keyid.toHex()); if (oValidSysKey) { sPlain = mPgpMessage.getText(); @@ -1269,10 +1268,9 @@ aRes = [], mPgpMessage = null, mPgpMessageDecrypted = null, - Data = require('Storage/User/Data'), sFrom = this.from && this.from[0] && this.from[0].email ? this.from[0].email : '', - aPublicKey = Data.findPublicKeysByEmail(sFrom), - oPrivateKey = Data.findSelfPrivateKey(sPassword), + aPublicKey = PgpStore.findPublicKeysByEmail(sFrom), + oPrivateKey = PgpStore.findSelfPrivateKey(sPassword), oValidKey = null, oValidSysKey = null, sPlain = '' @@ -1305,7 +1303,7 @@ if (oValidKey) { - oValidSysKey = Data.findPublicKeyByHex(oValidKey.keyid.toHex()); + oValidSysKey = PgpStore.findPublicKeyByHex(oValidKey.keyid.toHex()); if (oValidSysKey) { this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.Success); diff --git a/dev/Storage/AbstractRemote.js b/dev/Remote/AbstractAjax.js similarity index 87% rename from dev/Storage/AbstractRemote.js rename to dev/Remote/AbstractAjax.js index eacf1a39f..b4a22123f 100644 --- a/dev/Storage/AbstractRemote.js +++ b/dev/Remote/AbstractAjax.js @@ -21,12 +21,12 @@ /** * @constructor */ - function AbstractRemoteStorage() + function AbstractAjaxRemote() { this.oRequests = {}; } - AbstractRemoteStorage.prototype.oRequests = {}; + AbstractAjaxRemote.prototype.oRequests = {}; /** * @param {?Function} fCallback @@ -36,7 +36,7 @@ * @param {boolean} bCached * @param {*=} oRequestParameters */ - AbstractRemoteStorage.prototype.defaultResponse = function (fCallback, sRequestAction, sType, oData, bCached, oRequestParameters) + AbstractAjaxRemote.prototype.defaultResponse = function (fCallback, sRequestAction, sType, oData, bCached, oRequestParameters) { var fCall = function () { @@ -134,7 +134,7 @@ * @param {Array=} aAbortActions = [] * @return {jQuery.jqXHR} */ - AbstractRemoteStorage.prototype.ajaxRequest = function (fResultCallback, oParameters, iTimeOut, sGetAdd, aAbortActions) + AbstractAjaxRemote.prototype.ajaxRequest = function (fResultCallback, oParameters, iTimeOut, sGetAdd, aAbortActions) { var self = this, @@ -230,7 +230,7 @@ * @param {string=} sGetAdd = '' * @param {Array=} aAbortActions = [] */ - AbstractRemoteStorage.prototype.defaultRequest = function (fCallback, sAction, oParameters, iTimeout, sGetAdd, aAbortActions) + AbstractAjaxRemote.prototype.defaultRequest = function (fCallback, sAction, oParameters, iTimeout, sGetAdd, aAbortActions) { oParameters = oParameters || {}; oParameters.Action = sAction; @@ -246,7 +246,7 @@ /** * @param {?Function} fCallback */ - AbstractRemoteStorage.prototype.noop = function (fCallback) + AbstractAjaxRemote.prototype.noop = function (fCallback) { this.defaultRequest(fCallback, 'Noop'); }; @@ -260,7 +260,7 @@ * @param {string} sHtmlCapa * @param {number} iTime */ - AbstractRemoteStorage.prototype.jsError = function (fCallback, sMessage, sFileName, iLineNo, sLocation, sHtmlCapa, iTime) + AbstractAjaxRemote.prototype.jsError = function (fCallback, sMessage, sFileName, iLineNo, sLocation, sHtmlCapa, iTime) { this.defaultRequest(fCallback, 'JsError', { 'Message': sMessage, @@ -278,7 +278,7 @@ * @param {Array=} mData = null * @param {boolean=} bIsError = false */ - AbstractRemoteStorage.prototype.jsInfo = function (fCallback, sType, mData, bIsError) + AbstractAjaxRemote.prototype.jsInfo = function (fCallback, sType, mData, bIsError) { this.defaultRequest(fCallback, 'JsInfo', { 'Type': sType, @@ -290,7 +290,7 @@ /** * @param {?Function} fCallback */ - AbstractRemoteStorage.prototype.getPublicKey = function (fCallback) + AbstractAjaxRemote.prototype.getPublicKey = function (fCallback) { this.defaultRequest(fCallback, 'GetPublicKey'); }; @@ -299,13 +299,13 @@ * @param {?Function} fCallback * @param {string} sVersion */ - AbstractRemoteStorage.prototype.jsVersion = function (fCallback, sVersion) + AbstractAjaxRemote.prototype.jsVersion = function (fCallback, sVersion) { this.defaultRequest(fCallback, 'Version', { 'Version': sVersion }); }; - module.exports = AbstractRemoteStorage; + module.exports = AbstractAjaxRemote; }()); \ No newline at end of file diff --git a/dev/Storage/Admin/Remote.js b/dev/Remote/Admin/Ajax.js similarity index 96% rename from dev/Storage/Admin/Remote.js rename to dev/Remote/Admin/Ajax.js index 9c987b30c..5173daeb0 100644 --- a/dev/Storage/Admin/Remote.js +++ b/dev/Remote/Admin/Ajax.js @@ -6,21 +6,21 @@ var _ = require('_'), - AbstractRemoteStorage = require('Storage/AbstractRemote') + AbstractAjaxRemote = require('Remote/AbstractAjax') ; /** * @constructor - * @extends AbstractRemoteStorage + * @extends AbstractAjaxRemote */ function RemoteAdminStorage() { - AbstractRemoteStorage.call(this); + AbstractAjaxRemote.call(this); this.oRequests = {}; } - _.extend(RemoteAdminStorage.prototype, AbstractRemoteStorage.prototype); + _.extend(RemoteAdminStorage.prototype, AbstractAjaxRemote.prototype); /** * @param {?Function} fCallback diff --git a/dev/Storage/User/Remote.js b/dev/Remote/User/Ajax.js similarity index 97% rename from dev/Storage/User/Remote.js rename to dev/Remote/User/Ajax.js index 005cfea8b..2819f569c 100644 --- a/dev/Storage/User/Remote.js +++ b/dev/Remote/User/Ajax.js @@ -10,14 +10,15 @@ Consts = require('Common/Consts'), Base64 = require('Common/Base64'), - AppStore = require('Stores/User/App'), - SettingsStore = require('Stores/User/Settings'), + Cache = require('Common/Cache'), Settings = require('Storage/Settings'), - Cache = require('Storage/User/Cache'), - Data = require('Storage/User/Data'), - AbstractRemoteStorage = require('Storage/AbstractRemote') + AppStore = require('Stores/User/App'), + SettingsStore = require('Stores/User/Settings'), + MessageStore = require('Stores/User/Message'), + + AbstractAjaxRemote = require('Remote/AbstractAjax') ; /** @@ -26,14 +27,14 @@ */ function RemoteUserStorage() { - AbstractRemoteStorage.call(this); + AbstractAjaxRemote.call(this); this.oRequests = {}; this.sSubSubQuery = '&ss=/'; } - _.extend(RemoteUserStorage.prototype, AbstractRemoteStorage.prototype); + _.extend(RemoteUserStorage.prototype, AbstractAjaxRemote.prototype); /** * @param {?Function} fCallback @@ -348,7 +349,7 @@ sFolderHash, Cache.getFolderInboxName() === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '', AppStore.threadsAllowed() && SettingsStore.useThreads() ? '1' : '0', - AppStore.threadsAllowed() && sFolderFullNameRaw === Data.messageListThreadFolder() ? Data.messageListThreadUids().join(',') : '' + AppStore.threadsAllowed() && sFolderFullNameRaw === MessageStore.messageListThreadFolder() ? MessageStore.messageListThreadUids().join(',') : '' ].join(String.fromCharCode(0))), bSilent ? [] : ['MessageList']); } else @@ -360,7 +361,7 @@ 'Search': sSearch, 'UidNext': Cache.getFolderInboxName() === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '', 'UseThreads': AppStore.threadsAllowed() && SettingsStore.useThreads() ? '1' : '0', - 'ExpandedThreadUid': AppStore.threadsAllowed() && sFolderFullNameRaw === Data.messageListThreadFolder() ? Data.messageListThreadUids().join(',') : '' + 'ExpandedThreadUid': AppStore.threadsAllowed() && sFolderFullNameRaw === MessageStore.messageListThreadFolder() ? MessageStore.messageListThreadUids().join(',') : '' }, '' === sSearch ? Consts.Defaults.DefaultAjaxTimeout : Consts.Defaults.SearchAjaxTimeout, '', bSilent ? [] : ['MessageList']); } }; @@ -619,12 +620,13 @@ * @param {(Array|null)} aDraftInfo * @param {string} sInReplyTo * @param {string} sReferences + * @param {boolean} bRequestDsn * @param {boolean} bRequestReadReceipt * @param {boolean} bMarkAsImportant */ RemoteUserStorage.prototype.sendMessage = function (fCallback, sIdentityID, sMessageFolder, sMessageUid, sSentFolder, sTo, sCc, sBcc, sReplyTo, sSubject, bTextIsHtml, sText, aAttachments, aDraftInfo, sInReplyTo, sReferences, - bRequestReadReceipt, bMarkAsImportant) + bRequestDsn, bRequestReadReceipt, bMarkAsImportant) { this.defaultRequest(fCallback, 'SendMessage', { 'IdentityID': sIdentityID, @@ -641,6 +643,7 @@ 'DraftInfo': aDraftInfo, 'InReplyTo': sInReplyTo, 'References': sReferences, + 'Dsn': bRequestDsn ? '1' : '0', 'ReadReceiptRequest': bRequestReadReceipt ? '1' : '0', 'MarkAsImportant': bMarkAsImportant ? '1' : '0', 'Attachments': aAttachments diff --git a/dev/Screen/User/MailBox.js b/dev/Screen/User/MailBox.js index 7a8d073c5..50f20bcaf 100644 --- a/dev/Screen/User/MailBox.js +++ b/dev/Screen/User/MailBox.js @@ -12,11 +12,12 @@ Events = require('Common/Events'), Translator = require('Common/Translator'), + Cache = require('Common/Cache'), + AccountStore = require('Stores/User/Account'), SettingsStore = require('Stores/User/Settings'), - - Data = require('Storage/User/Data'), - Cache = require('Storage/User/Cache'), + FolderStore = require('Stores/User/Folder'), + MessageStore = require('Stores/User/Message'), AbstractScreen = require('Knoin/AbstractScreen') ; @@ -48,7 +49,7 @@ { var sEmail = AccountStore.email(), - nFoldersInboxUnreadCount = Data.foldersInboxUnreadCount() + nFoldersInboxUnreadCount = FolderStore.foldersInboxUnreadCount() ; require('App/User').setTitle(('' === sEmail ? '' : @@ -72,7 +73,7 @@ { if (Utils.isUnd(bPreview) ? false : !!bPreview) { - if (Enums.Layout.NoPreview === SettingsStore.layout() && !Data.message()) + if (Enums.Layout.NoPreview === SettingsStore.layout() && !MessageStore.message()) { require('App/User').historyBack(); } @@ -86,15 +87,13 @@ if (oFolder) { - Data - .currentFolder(oFolder) - .messageListPage(iPage) - .messageListSearch(sSearch) - ; + FolderStore.currentFolder(oFolder); + MessageStore.messageListPage(iPage); + MessageStore.messageListSearch(sSearch); - if (Enums.Layout.NoPreview === SettingsStore.layout() && Data.message()) + if (Enums.Layout.NoPreview === SettingsStore.layout() && MessageStore.message()) { - Data.message(null); + MessageStore.message(null); } require('App/User').reloadMessageList(); @@ -104,9 +103,10 @@ MailBoxUserScreen.prototype.onStart = function () { - Data.folderList.subscribe(Utils.windowResizeCallback); - Data.messageList.subscribe(Utils.windowResizeCallback); - Data.message.subscribe(Utils.windowResizeCallback); + FolderStore.folderList.subscribe(Utils.windowResizeCallback); + + MessageStore.messageList.subscribe(Utils.windowResizeCallback); + MessageStore.message.subscribe(Utils.windowResizeCallback); _.delay(function () { SettingsStore.layout.valueHasMutated(); @@ -114,7 +114,7 @@ Events.sub('mailbox.inbox-unread-count', function (iCount) { - Data.foldersInboxUnreadCount(iCount); + FolderStore.foldersInboxUnreadCount(iCount); var sEmail = AccountStore.email(); @@ -126,7 +126,7 @@ }); }); - Data.foldersInboxUnreadCount.subscribe(function () { + FolderStore.foldersInboxUnreadCount.subscribe(function () { this.setNewTitle(); }, this); diff --git a/dev/Settings/Admin/Branding.js b/dev/Settings/Admin/Branding.js index 68f8d3d77..91c0a4ee1 100644 --- a/dev/Settings/Admin/Branding.js +++ b/dev/Settings/Admin/Branding.js @@ -56,7 +56,7 @@ { var self = this, - Remote = require('Storage/Admin/Remote') + Remote = require('Remote/Admin/Ajax') ; _.delay(function () { diff --git a/dev/Settings/Admin/Contacts.js b/dev/Settings/Admin/Contacts.js index 9b82d14e6..8d0313d09 100644 --- a/dev/Settings/Admin/Contacts.js +++ b/dev/Settings/Admin/Contacts.js @@ -19,7 +19,7 @@ function ContactsAdminSettings() { var - Remote = require('Storage/Admin/Remote') + Remote = require('Remote/Admin/Ajax') ; this.defautOptionsAfterRender = Utils.defautOptionsAfterRender; @@ -178,7 +178,7 @@ { var self = this, - Remote = require('Storage/Admin/Remote') + Remote = require('Remote/Admin/Ajax') ; _.delay(function () { diff --git a/dev/Settings/Admin/Domains.js b/dev/Settings/Admin/Domains.js index 352c90cc1..6fe36c033 100644 --- a/dev/Settings/Admin/Domains.js +++ b/dev/Settings/Admin/Domains.js @@ -10,7 +10,7 @@ Enums = require('Common/Enums'), DomainStore = require('Stores/Admin/Domain'), - Remote = require('Storage/Admin/Remote') + Remote = require('Remote/Admin/Ajax') ; /** diff --git a/dev/Settings/Admin/General.js b/dev/Settings/Admin/General.js index 5e80bfb4b..5268d8559 100644 --- a/dev/Settings/Admin/General.js +++ b/dev/Settings/Admin/General.js @@ -68,7 +68,7 @@ { var self = this, - Remote = require('Storage/Admin/Remote') + Remote = require('Remote/Admin/Ajax') ; _.delay(function () { diff --git a/dev/Settings/Admin/Login.js b/dev/Settings/Admin/Login.js index 908aecfdb..c98fc3b1c 100644 --- a/dev/Settings/Admin/Login.js +++ b/dev/Settings/Admin/Login.js @@ -35,7 +35,7 @@ { var self = this, - Remote = require('Storage/Admin/Remote') + Remote = require('Remote/Admin/Ajax') ; _.delay(function () { diff --git a/dev/Settings/Admin/Packages.js b/dev/Settings/Admin/Packages.js index 8947f357b..f901f3b01 100644 --- a/dev/Settings/Admin/Packages.js +++ b/dev/Settings/Admin/Packages.js @@ -12,7 +12,7 @@ Translator = require('Common/Translator'), PackageStore = require('Stores/Admin/Package'), - Remote = require('Storage/Admin/Remote') + Remote = require('Remote/Admin/Ajax') ; /** diff --git a/dev/Settings/Admin/Plugins.js b/dev/Settings/Admin/Plugins.js index a83db3c9c..f15c7637c 100644 --- a/dev/Settings/Admin/Plugins.js +++ b/dev/Settings/Admin/Plugins.js @@ -13,7 +13,7 @@ Settings = require('Storage/Settings'), PluginStore = require('Stores/Admin/Plugin'), - Remote = require('Storage/Admin/Remote') + Remote = require('Remote/Admin/Ajax') ; /** diff --git a/dev/Settings/Admin/Security.js b/dev/Settings/Admin/Security.js index 5f7d43b6e..9d0ac8cd0 100644 --- a/dev/Settings/Admin/Security.js +++ b/dev/Settings/Admin/Security.js @@ -15,7 +15,7 @@ CapaAdminStore = require('Stores/Admin/Capa'), Settings = require('Storage/Settings'), - Remote = require('Storage/Admin/Remote') + Remote = require('Remote/Admin/Ajax') ; /** @@ -114,10 +114,6 @@ SecurityAdminSettings.prototype.onBuild = function () { - var - Remote = require('Storage/Admin/Remote') - ; - this.capaOpenPGP.subscribe(function (bValue) { Remote.saveAdminConfig(Utils.emptyFunction, { 'CapaOpenPGP': bValue ? '1' : '0' diff --git a/dev/Settings/Admin/Social.js b/dev/Settings/Admin/Social.js index 4faf782d8..ca2d2ad84 100644 --- a/dev/Settings/Admin/Social.js +++ b/dev/Settings/Admin/Social.js @@ -59,7 +59,7 @@ { var self = this, - Remote = require('Storage/Admin/Remote') + Remote = require('Remote/Admin/Ajax') ; _.delay(function () { diff --git a/dev/Settings/User/Accounts.js b/dev/Settings/User/Accounts.js index d7856ee61..3b79644cd 100644 --- a/dev/Settings/User/Accounts.js +++ b/dev/Settings/User/Accounts.js @@ -15,7 +15,7 @@ IdentityStore = require('Stores/User/Identity'), Settings = require('Storage/Settings'), - Remote = require('Storage/User/Remote') + Remote = require('Remote/User/Ajax') ; /** diff --git a/dev/Settings/User/ChangePassword.js b/dev/Settings/User/ChangePassword.js index 7d011015d..8a53619c4 100644 --- a/dev/Settings/User/ChangePassword.js +++ b/dev/Settings/User/ChangePassword.js @@ -11,7 +11,7 @@ Utils = require('Common/Utils'), Translator = require('Common/Translator'), - Remote = require('Storage/User/Remote') + Remote = require('Remote/User/Ajax') ; /** diff --git a/dev/Settings/User/Contacts.js b/dev/Settings/User/Contacts.js index 523a5deb2..a20d76156 100644 --- a/dev/Settings/User/Contacts.js +++ b/dev/Settings/User/Contacts.js @@ -7,9 +7,9 @@ ko = require('ko'), AppStore = require('Stores/User/App'), + ContactStore = require('Stores/User/Contact'), - Remote = require('Storage/User/Remote'), - Data = require('Storage/User/Data') + Remote = require('Remote/User/Ajax') ; /** @@ -19,11 +19,11 @@ { this.contactsAutosave = AppStore.contactsAutosave; - this.allowContactsSync = Data.allowContactsSync; - this.enableContactsSync = Data.enableContactsSync; - this.contactsSyncUrl = Data.contactsSyncUrl; - this.contactsSyncUser = Data.contactsSyncUser; - this.contactsSyncPass = Data.contactsSyncPass; + this.allowContactsSync = ContactStore.allowContactsSync; + this.enableContactsSync = ContactStore.enableContactsSync; + this.contactsSyncUrl = ContactStore.contactsSyncUrl; + this.contactsSyncUser = ContactStore.contactsSyncUser; + this.contactsSyncPass = ContactStore.contactsSyncPass; this.saveTrigger = ko.computed(function () { return [ diff --git a/dev/Settings/User/Filters.js b/dev/Settings/User/Filters.js index dc305c9f1..b3ed0292f 100644 --- a/dev/Settings/User/Filters.js +++ b/dev/Settings/User/Filters.js @@ -13,7 +13,7 @@ FilterStore = require('Stores/User/Filter'), - Remote = require('Storage/User/Remote') + Remote = require('Remote/User/Ajax') ; /** diff --git a/dev/Settings/User/Folders.js b/dev/Settings/User/Folders.js index 7a131ba08..207c456c6 100644 --- a/dev/Settings/User/Folders.js +++ b/dev/Settings/User/Folders.js @@ -10,11 +10,14 @@ Utils = require('Common/Utils'), Translator = require('Common/Translator'), + Cache = require('Common/Cache'), + Settings = require('Storage/Settings'), - Data = require('Storage/User/Data'), - Cache = require('Storage/User/Cache'), - Remote = require('Storage/User/Remote'), - Local = require('Storage/Client') + Local = require('Storage/Client'), + + FolderStore = require('Stores/User/Folder'), + + Remote = require('Remote/User/Ajax') ; /** @@ -22,15 +25,15 @@ */ function FoldersUserSettings() { - this.folderList = Data.folderList; + this.folderList = FolderStore.folderList; this.loading = ko.computed(function () { var - bLoading = Data.foldersLoading(), - bCreating = Data.foldersCreating(), - bDeleting = Data.foldersDeleting(), - bRenaming = Data.foldersRenaming() + bLoading = FolderStore.foldersLoading(), + bCreating = FolderStore.foldersCreating(), + bDeleting = FolderStore.foldersDeleting(), + bRenaming = FolderStore.foldersRenaming() ; return bLoading || bCreating || bDeleting || bRenaming; @@ -66,13 +69,13 @@ { Local.set(Enums.ClientSideKeyName.FoldersLashHash, ''); - Data.foldersRenaming(true); + FolderStore.foldersRenaming(true); Remote.folderRename(function (sResult, oData) { - Data.foldersRenaming(false); + FolderStore.foldersRenaming(false); if (Enums.StorageResultType.Success !== sResult || !oData || !oData.Result) { - Data.folderList.error( + FolderStore.folderList.error( oData && oData.ErrorCode ? Translator.getNotification(oData.ErrorCode) : Translator.i18n('NOTIFICATIONS/CANT_RENAME_FOLDER')); } @@ -98,7 +101,7 @@ FoldersUserSettings.prototype.onShow = function () { - Data.folderList.error(''); + FolderStore.folderList.error(''); }; FoldersUserSettings.prototype.createFolder = function () @@ -135,15 +138,15 @@ { Local.set(Enums.ClientSideKeyName.FoldersLashHash, ''); - Data.folderList.remove(fRemoveFolder); + FolderStore.folderList.remove(fRemoveFolder); - Data.foldersDeleting(true); + FolderStore.foldersDeleting(true); Remote.folderDelete(function (sResult, oData) { - Data.foldersDeleting(false); + FolderStore.foldersDeleting(false); if (Enums.StorageResultType.Success !== sResult || !oData || !oData.Result) { - Data.folderList.error( + FolderStore.folderList.error( oData && oData.ErrorCode ? Translator.getNotification(oData.ErrorCode) : Translator.i18n('NOTIFICATIONS/CANT_DELETE_FOLDER')); } @@ -156,7 +159,7 @@ } else if (0 < oFolderToRemove.privateMessageCountAll()) { - Data.folderList.error(Translator.getNotification(Enums.Notification.CantDeleteNonEmptyFolder)); + FolderStore.folderList.error(Translator.getNotification(Enums.Notification.CantDeleteNonEmptyFolder)); } }; diff --git a/dev/Settings/User/General.js b/dev/Settings/User/General.js index 9739a2679..186066d1b 100644 --- a/dev/Settings/User/General.js +++ b/dev/Settings/User/General.js @@ -17,9 +17,9 @@ LanguageStore = require('Stores/Language'), SettingsStore = require('Stores/User/Settings'), NotificationStore = require('Stores/User/Notification'), + MessageStore = require('Stores/User/Message'), - Data = require('Storage/User/Data'), - Remote = require('Storage/User/Remote') + Remote = require('Remote/User/Ajax') ; /** @@ -163,7 +163,7 @@ self.useThreads.subscribe(function (bValue) { - Data.messageList([]); + MessageStore.messageList([]); Remote.saveSettings(null, { 'UseThreads': bValue ? '1' : '0' @@ -172,7 +172,7 @@ self.layout.subscribe(function (nValue) { - Data.messageList([]); + MessageStore.messageList([]); Remote.saveSettings(f2, { 'Layout': nValue diff --git a/dev/Settings/User/Security.js b/dev/Settings/User/Security.js index e5da546da..7e87765a3 100644 --- a/dev/Settings/User/Security.js +++ b/dev/Settings/User/Security.js @@ -15,7 +15,7 @@ Settings = require('Storage/Settings'), - Remote = require('Storage/User/Remote') + Remote = require('Remote/User/Ajax') ; /** diff --git a/dev/Settings/User/Templates.js b/dev/Settings/User/Templates.js index c0b1e8e9a..db6991f7c 100644 --- a/dev/Settings/User/Templates.js +++ b/dev/Settings/User/Templates.js @@ -10,7 +10,7 @@ TemplateStore = require('Stores/User/Template'), - Remote = require('Storage/User/Remote') + Remote = require('Remote/User/Ajax') ; /** diff --git a/dev/Settings/User/Themes.js b/dev/Settings/User/Themes.js index 4c305f707..cbdeee8c6 100644 --- a/dev/Settings/User/Themes.js +++ b/dev/Settings/User/Themes.js @@ -18,7 +18,8 @@ ThemeStore = require('Stores/Theme'), Settings = require('Storage/Settings'), - Remote = require('Storage/User/Remote') + + Remote = require('Remote/User/Ajax') ; /** diff --git a/dev/Stores/User/App.js b/dev/Stores/User/App.js index 74f31df59..71e25c390 100644 --- a/dev/Stores/User/App.js +++ b/dev/Stores/User/App.js @@ -21,6 +21,8 @@ this.projectHash = ko.observable(''); this.threadsAllowed = ko.observable(false); + this.composeInEdit = ko.observable(false); + this.contactsAutosave = ko.observable(false); this.useLocalProxyForExternalImages = ko.observable(false); diff --git a/dev/Stores/User/Contact.js b/dev/Stores/User/Contact.js new file mode 100644 index 000000000..7af3fd388 --- /dev/null +++ b/dev/Stores/User/Contact.js @@ -0,0 +1,43 @@ + +(function () { + + 'use strict'; + + var + ko = require('ko'), + + Settings = require('Storage/Settings') + ; + + /** + * @constructor + */ + function ContactUserStore() + { + this.contacts = ko.observableArray([]); + this.contacts.loading = ko.observable(false).extend({'throttle': 200}); + this.contacts.importing = ko.observable(false).extend({'throttle': 200}); + this.contacts.syncing = ko.observable(false).extend({'throttle': 200}); + this.contacts.exportingVcf = ko.observable(false).extend({'throttle': 200}); + this.contacts.exportingCsv = ko.observable(false).extend({'throttle': 200}); + + this.allowContactsSync = ko.observable(false); + this.enableContactsSync = ko.observable(false); + this.contactsSyncUrl = ko.observable(''); + this.contactsSyncUser = ko.observable(''); + this.contactsSyncPass = ko.observable(''); + } + + ContactUserStore.prototype.populate = function () + { + this.allowContactsSync(!!Settings.settingsGet('ContactsSyncIsAllowed')); + this.enableContactsSync(!!Settings.settingsGet('EnableContactsSync')); + + this.contactsSyncUrl(Settings.settingsGet('ContactsSyncUrl')); + this.contactsSyncUser(Settings.settingsGet('ContactsSyncUser')); + this.contactsSyncPass(Settings.settingsGet('ContactsSyncPassword')); + }; + + module.exports = new ContactUserStore(); + +}()); \ No newline at end of file diff --git a/dev/Stores/User/Folder.js b/dev/Stores/User/Folder.js index 6c6fa5894..35e9deedc 100644 --- a/dev/Stores/User/Folder.js +++ b/dev/Stores/User/Folder.js @@ -4,12 +4,16 @@ 'use strict'; var + _ = require('_'), ko = require('ko'), + moment = require('moment'), Enums = require('Common/Enums'), Consts = require('Common/Consts'), + Globals = require('Common/Globals'), + Utils = require('Common/Utils'), - Cache = require('Storage/User/Cache') + Cache = require('Common/Cache') ; /** @@ -23,6 +27,25 @@ this.trashFolder = ko.observable(''); this.archiveFolder = ko.observable(''); + this.namespace = ''; + + this.folderList = ko.observableArray([]); + this.folderList.focused = ko.observable(false); + this.folderList.optimized = ko.observable(false); + this.folderList.error = ko.observable(''); + + this.foldersLoading = ko.observable(false); + this.foldersCreating = ko.observable(false); + this.foldersDeleting = ko.observable(false); + this.foldersRenaming = ko.observable(false); + + this.foldersInboxUnreadCount = ko.observable(0); + + this.currentFolder = ko.observable(null).extend({'toggleSubscribe': [null, + function (oPrev) { if (oPrev) { oPrev.selected(false); }}, + function (oNext) { if (oNext) { oNext.selected(true); }} + ]}); + this.computers(); this.subscribers(); } @@ -32,6 +55,96 @@ this.draftFolderNotEnabled = ko.computed(function () { return '' === this.draftFolder() || Consts.Values.UnuseOptionValue === this.draftFolder(); }, this); + + this.foldersListWithSingleInboxRootFolder = ko.computed(function () { + return !_.find(this.folderList(), function (oFolder) { + return oFolder && !oFolder.isSystemFolder() && oFolder.visible(); + }); + }, this); + + this.currentFolderFullNameRaw = ko.computed(function () { + return this.currentFolder() ? this.currentFolder().fullNameRaw : ''; + }, this); + + this.currentFolderFullName = ko.computed(function () { + return this.currentFolder() ? this.currentFolder().fullName : ''; + }, this); + + this.currentFolderFullNameHash = ko.computed(function () { + return this.currentFolder() ? this.currentFolder().fullNameHash : ''; + }, this); + + this.foldersChanging = ko.computed(function () { + var + bLoading = this.foldersLoading(), + bCreating = this.foldersCreating(), + bDeleting = this.foldersDeleting(), + bRenaming = this.foldersRenaming() + ; + return bLoading || bCreating || bDeleting || bRenaming; + }, this); + + this.folderListSystemNames = ko.computed(function () { + + var + aList = [Cache.getFolderInboxName()], + aFolders = this.folderList(), + sSentFolder = this.sentFolder(), + sDraftFolder = this.draftFolder(), + sSpamFolder = this.spamFolder(), + sTrashFolder = this.trashFolder(), + sArchiveFolder = this.archiveFolder() + ; + + if (Utils.isArray(aFolders) && 0 < aFolders.length) + { + if ('' !== sSentFolder && Consts.Values.UnuseOptionValue !== sSentFolder) + { + aList.push(sSentFolder); + } + if ('' !== sDraftFolder && Consts.Values.UnuseOptionValue !== sDraftFolder) + { + aList.push(sDraftFolder); + } + if ('' !== sSpamFolder && Consts.Values.UnuseOptionValue !== sSpamFolder) + { + aList.push(sSpamFolder); + } + if ('' !== sTrashFolder && Consts.Values.UnuseOptionValue !== sTrashFolder) + { + aList.push(sTrashFolder); + } + if ('' !== sArchiveFolder && Consts.Values.UnuseOptionValue !== sArchiveFolder) + { + aList.push(sArchiveFolder); + } + } + + return aList; + + }, this); + + this.folderListSystem = ko.computed(function () { + return _.compact(_.map(this.folderListSystemNames(), function (sName) { + return Cache.getFolderFromCacheList(sName); + })); + }, this); + + this.folderMenuForMove = ko.computed(function () { + return Utils.folderListOptionsBuilder(this.folderListSystem(), this.folderList(), [ + this.currentFolderFullNameRaw() + ], null, null, null, null, function (oItem) { + return oItem ? oItem.localName() : ''; + }); + }, this); + + this.folderMenuForFilters = ko.computed(function () { + return Utils.folderListOptionsBuilder(this.folderListSystem(), this.folderList(), + ['INBOX'], [['', '']], null, null, null, function (oItem) { + return oItem ? oItem.localName() : ''; + } + ); + }, this); }; FolderUserStore.prototype.subscribers = function () @@ -68,6 +181,76 @@ this.spamFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Spam), this); this.trashFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Trash), this); this.archiveFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Archive), this); + + this.folderList.focused.subscribe(function (bValue) { + if (bValue) + { + Globals.keyScope(Enums.KeyState.FolderList); + } + else if (Enums.KeyState.FolderList === Globals.keyScope()) + { + Globals.keyScope(Enums.KeyState.MessageList); + } + }); + }; + + /** + * @param {boolean=} bBoot = false + * @returns {Array} + */ + FolderUserStore.prototype.getNextFolderNames = function (bBoot) + { + bBoot = Utils.isUnd(bBoot) ? false : !!bBoot; + + var + aResult = [], + iLimit = 5, + iUtc = moment().unix(), + iTimeout = iUtc - 60 * 5, + aTimeouts = [], + sInboxFolderName = Cache.getFolderInboxName(), + fSearchFunction = function (aList) { + _.each(aList, function (oFolder) { + if (oFolder && sInboxFolderName !== oFolder.fullNameRaw && + oFolder.selectable && oFolder.existen && + iTimeout > oFolder.interval && + (!bBoot || oFolder.subScribed())) + { + aTimeouts.push([oFolder.interval, oFolder.fullNameRaw]); + } + + if (oFolder && 0 < oFolder.subFolders().length) + { + fSearchFunction(oFolder.subFolders()); + } + }); + } + ; + + fSearchFunction(this.folderList()); + + aTimeouts.sort(function(a, b) { + if (a[0] < b[0]) { + return -1; + } else if (a[0] > b[0]) { + return 1; + } + + return 0; + }); + + _.find(aTimeouts, function (aItem) { + var oFolder = Cache.getFolderFromCacheList(aItem[1]); + if (oFolder) + { + oFolder.interval = iUtc; + aResult.push(aItem[1]); + } + + return iLimit <= aResult.length; + }); + + return _.uniq(aResult); }; module.exports = new FolderUserStore(); diff --git a/dev/Storage/User/Data.js b/dev/Stores/User/Message.js similarity index 62% rename from dev/Storage/User/Data.js rename to dev/Stores/User/Message.js index 363836b68..bca89535f 100644 --- a/dev/Storage/User/Data.js +++ b/dev/Stores/User/Message.js @@ -4,180 +4,35 @@ 'use strict'; var - window = require('window'), _ = require('_'), - $ = require('$'), ko = require('ko'), + window = require('window'), moment = require('moment'), + $ = require('$'), + + kn = require('Knoin/Knoin'), - Consts = require('Common/Consts'), Enums = require('Common/Enums'), + Consts = require('Common/Consts'), Globals = require('Common/Globals'), Utils = require('Common/Utils'), Links = require('Common/Links'), Translator = require('Common/Translator'), + Cache = require('Common/Cache'), + + FolderStore = require('Stores/User/Folder'), SettingsStore = require('Stores/User/Settings'), - Settings = require('Storage/Settings'), - Cache = require('Storage/User/Cache'), - - kn = require('Knoin/Knoin'), - MessageModel = require('Model/Message') ; /** * @constructor */ - function DataUserStorage() + function MessageUserStore() { - // contacts - this.contacts = ko.observableArray([]); - this.contacts.loading = ko.observable(false).extend({'throttle': 200}); - this.contacts.importing = ko.observable(false).extend({'throttle': 200}); - this.contacts.syncing = ko.observable(false).extend({'throttle': 200}); - this.contacts.exportingVcf = ko.observable(false).extend({'throttle': 200}); - this.contacts.exportingCsv = ko.observable(false).extend({'throttle': 200}); - - this.allowContactsSync = ko.observable(false); - this.enableContactsSync = ko.observable(false); - this.contactsSyncUrl = ko.observable(''); - this.contactsSyncUser = ko.observable(''); - this.contactsSyncPass = ko.observable(''); - - this.allowContactsSync = ko.observable(!!Settings.settingsGet('ContactsSyncIsAllowed')); - this.enableContactsSync = ko.observable(!!Settings.settingsGet('EnableContactsSync')); - this.contactsSyncUrl = ko.observable(Settings.settingsGet('ContactsSyncUrl')); - this.contactsSyncUser = ko.observable(Settings.settingsGet('ContactsSyncUser')); - this.contactsSyncPass = ko.observable(Settings.settingsGet('ContactsSyncPassword')); - - // folders - this.namespace = ''; - this.folderList = ko.observableArray([]); - this.folderList.focused = ko.observable(false); - this.folderList.optimized = ko.observable(false); - this.folderList.error = ko.observable(''); - - this.foldersLoading = ko.observable(false); - this.foldersCreating = ko.observable(false); - this.foldersDeleting = ko.observable(false); - this.foldersRenaming = ko.observable(false); - - this.foldersListWithSingleInboxRootFolder = ko.computed(function () { - var aList = this.folderList(); - return !_.find(aList, function (oFolder) { - return oFolder && !oFolder.isSystemFolder() && oFolder.visible(); - }); - }, this); - - this.foldersChanging = ko.computed(function () { - var - bLoading = this.foldersLoading(), - bCreating = this.foldersCreating(), - bDeleting = this.foldersDeleting(), - bRenaming = this.foldersRenaming() - ; - return bLoading || bCreating || bDeleting || bRenaming; - }, this); - - this.foldersInboxUnreadCount = ko.observable(0); - - this.currentFolder = ko.observable(null).extend({'toggleSubscribe': [null, - function (oPrev) { - if (oPrev) - { - oPrev.selected(false); - } - }, function (oNext) { - if (oNext) - { - oNext.selected(true); - } - } - ]}); - - this.currentFolderFullNameRaw = ko.computed(function () { - return this.currentFolder() ? this.currentFolder().fullNameRaw : ''; - }, this); - - this.currentFolderFullName = ko.computed(function () { - return this.currentFolder() ? this.currentFolder().fullName : ''; - }, this); - - this.currentFolderFullNameHash = ko.computed(function () { - return this.currentFolder() ? this.currentFolder().fullNameHash : ''; - }, this); - - this.currentFolderName = ko.computed(function () { - return this.currentFolder() ? this.currentFolder().name() : ''; - }, this); - - this.folderListSystemNames = ko.computed(function () { - - var - FolderStore = require('Stores/User/Folder'), - - aList = [Cache.getFolderInboxName()], - aFolders = this.folderList(), - sSentFolder = FolderStore.sentFolder(), - sDraftFolder = FolderStore.draftFolder(), - sSpamFolder = FolderStore.spamFolder(), - sTrashFolder = FolderStore.trashFolder(), - sArchiveFolder = FolderStore.archiveFolder() - ; - - if (Utils.isArray(aFolders) && 0 < aFolders.length) - { - if ('' !== sSentFolder && Consts.Values.UnuseOptionValue !== sSentFolder) - { - aList.push(sSentFolder); - } - if ('' !== sDraftFolder && Consts.Values.UnuseOptionValue !== sDraftFolder) - { - aList.push(sDraftFolder); - } - if ('' !== sSpamFolder && Consts.Values.UnuseOptionValue !== sSpamFolder) - { - aList.push(sSpamFolder); - } - if ('' !== sTrashFolder && Consts.Values.UnuseOptionValue !== sTrashFolder) - { - aList.push(sTrashFolder); - } - if ('' !== sArchiveFolder && Consts.Values.UnuseOptionValue !== sArchiveFolder) - { - aList.push(sArchiveFolder); - } - } - - return aList; - - }, this); - - this.folderListSystem = ko.computed(function () { - return _.compact(_.map(this.folderListSystemNames(), function (sName) { - return Cache.getFolderFromCacheList(sName); - })); - }, this); - - this.folderMenuForMove = ko.computed(function () { - return Utils.folderListOptionsBuilder(this.folderListSystem(), this.folderList(), [ - this.currentFolderFullNameRaw() - ], null, null, null, null, function (oItem) { - return oItem ? oItem.localName() : ''; - }); - }, this); - - this.folderMenuForFilters = ko.computed(function () { - return Utils.folderListOptionsBuilder(this.folderListSystem(), this.folderList(), - ['INBOX'], [['', '']], null, null, null, function (oItem) { - return oItem ? oItem.localName() : ''; - } - ); - }, this); - - // message list + this.staticMessage = new MessageModel(); this.staticMessageList = []; this.messageList = ko.observableArray([]).extend({'rateLimit': 0}); @@ -185,147 +40,34 @@ this.messageListCount = ko.observable(0); this.messageListSearch = ko.observable(''); this.messageListPage = ko.observable(1); + this.messageListError = ko.observable(''); this.messageListThreadFolder = ko.observable(''); this.messageListThreadUids = ko.observableArray([]); - this.messageListThreadFolder.subscribe(function () { - this.messageListThreadUids([]); - }, this); - this.messageListEndFolder = ko.observable(''); this.messageListEndSearch = ko.observable(''); this.messageListEndPage = ko.observable(1); - this.messageListEndHash = ko.computed(function () { - return this.messageListEndFolder() + '|' + this.messageListEndSearch() + '|' + this.messageListEndPage(); - }, this); - - this.messageListPageCount = ko.computed(function () { - var iPage = window.Math.ceil(this.messageListCount() / - SettingsStore.messagesPerPage()); - return 0 >= iPage ? 1 : iPage; - }, this); - - this.mainMessageListSearch = ko.computed({ - 'read': this.messageListSearch, - 'write': function (sValue) { - kn.setHash(Links.mailBox( - this.currentFolderFullNameHash(), 1, Utils.trim(sValue.toString()) - )); - }, - 'owner': this - }); - - this.messageListError = ko.observable(''); - this.messageListLoading = ko.observable(false); this.messageListIsNotCompleted = ko.observable(false); this.messageListCompleteLoadingThrottle = ko.observable(false).extend({'throttle': 200}); - this.messageListCompleteLoading = ko.computed(function () { - var - bOne = this.messageListLoading(), - bTwo = this.messageListIsNotCompleted() - ; - return bOne || bTwo; - }, this); - - this.messageListCompleteLoading.subscribe(function (bValue) { - this.messageListCompleteLoadingThrottle(bValue); - }, this); - - this.messageList.subscribe(_.debounce(function (aList) { - _.each(aList, function (oItem) { - if (oItem.newForAnimation()) - { - oItem.newForAnimation(false); - } - }); - }, 500)); - - // message preview - this.staticMessageList = new MessageModel(); + // message viewer this.message = ko.observable(null); - this.messageLoading = ko.observable(false); - this.messageLoadingThrottle = ko.observable(false).extend({'throttle': 50}); + this.currentMessage = ko.observable(null); this.message.focused = ko.observable(false); - this.message.subscribe(function (oMessage) { - if (!oMessage) - { - this.message.focused(false); - this.messageFullScreenMode(false); - this.hideMessageBodies(); - - if (Enums.Layout.NoPreview === SettingsStore.layout() && - -1 < window.location.hash.indexOf('message-preview')) - { - require('App/User').historyBack(); - } - } - else if (Enums.Layout.NoPreview === SettingsStore.layout()) - { - this.message.focused(true); - } - }, this); - - this.message.focused.subscribe(function (bValue) { - if (bValue) - { - this.folderList.focused(false); - Globals.keyScope(Enums.KeyState.MessageView); - } - else if (Enums.KeyState.MessageView === Globals.keyScope()) - { - if (Enums.Layout.NoPreview === SettingsStore.layout() && this.message()) - { - Globals.keyScope(Enums.KeyState.MessageView); - } - else - { - Globals.keyScope(Enums.KeyState.MessageList); - } - } - }, this); - - this.folderList.focused.subscribe(function (bValue) { - if (bValue) - { - Globals.keyScope(Enums.KeyState.FolderList); - } - else if (Enums.KeyState.FolderList === Globals.keyScope()) - { - Globals.keyScope(Enums.KeyState.MessageList); - } - }); - - this.messageLoading.subscribe(function (bValue) { - this.messageLoadingThrottle(bValue); - }, this); + this.messageError = ko.observable(''); + this.messageLoading = ko.observable(false); + this.messageLoadingThrottle = ko.observable(false).extend({'throttle': 50}); this.messageFullScreenMode = ko.observable(false); - this.messageError = ko.observable(''); - this.messagesBodiesDom = ko.observable(null); - - this.messagesBodiesDom.subscribe(function (oDom) { - if (oDom && !(oDom instanceof $)) - { - this.messagesBodiesDom($(oDom)); - } - }, this); - this.messageActiveDom = ko.observable(null); - this.isMessageSelected = ko.computed(function () { - return null !== this.message(); - }, this); - - this.currentMessage = ko.observable(null); - this.messageListChecked = ko.computed(function () { return _.filter(this.messageList(), function (oItem) { return oItem.checked(); @@ -362,13 +104,126 @@ return aList; }, this); - // other - this.composeInEdit = ko.observable(false); + + this.computers(); + this.subscribers(); this.purgeMessageBodyCacheThrottle = _.throttle(this.purgeMessageBodyCache, 1000 * 30); } - DataUserStorage.prototype.purgeMessageBodyCache = function() + MessageUserStore.prototype.computers = function () + { + this.messageListEndHash = ko.computed(function () { + return this.messageListEndFolder() + '|' + this.messageListEndSearch() + '|' + this.messageListEndPage(); + }, this); + + this.messageListPageCount = ko.computed(function () { + var iPage = window.Math.ceil(this.messageListCount() / + SettingsStore.messagesPerPage()); + return 0 >= iPage ? 1 : iPage; + }, this); + + this.mainMessageListSearch = ko.computed({ + 'read': this.messageListSearch, + 'write': function (sValue) { + kn.setHash(Links.mailBox( + FolderStore.currentFolderFullNameHash(), 1, Utils.trim(sValue.toString()) + )); + }, + 'owner': this + }); + + this.messageListCompleteLoading = ko.computed(function () { + var + bOne = this.messageListLoading(), + bTwo = this.messageListIsNotCompleted() + ; + return bOne || bTwo; + }, this); + + this.isMessageSelected = ko.computed(function () { + return null !== this.message(); + }, this); + }; + + MessageUserStore.prototype.subscribers = function () + { + this.messageListThreadFolder.subscribe(function () { + this.messageListThreadUids([]); + }, this); + + this.messageListCompleteLoading.subscribe(function (bValue) { + this.messageListCompleteLoadingThrottle(bValue); + }, this); + + this.messageList.subscribe(_.debounce(function (aList) { + _.each(aList, function (oItem) { + if (oItem && oItem.newForAnimation()) + { + oItem.newForAnimation(false); + } + }); + }, 500)); + + this.message.subscribe(function (oMessage) { + if (!oMessage) + { + this.message.focused(false); + this.messageFullScreenMode(false); + this.hideMessageBodies(); + + if (Enums.Layout.NoPreview === SettingsStore.layout() && + -1 < window.location.hash.indexOf('message-preview')) + { + require('App/User').historyBack(); + } + } + else if (Enums.Layout.NoPreview === SettingsStore.layout()) + { + this.message.focused(true); + } + }, this); + + this.message.focused.subscribe(function (bValue) { + if (bValue) + { + FolderStore.folderList.focused(false); + Globals.keyScope(Enums.KeyState.MessageView); + } + else if (Enums.KeyState.MessageView === Globals.keyScope()) + { + if (Enums.Layout.NoPreview === SettingsStore.layout() && this.message()) + { + Globals.keyScope(Enums.KeyState.MessageView); + } + else + { + Globals.keyScope(Enums.KeyState.MessageList); + } + } + }, this); + + this.messageLoading.subscribe(function (bValue) { + this.messageLoadingThrottle(bValue); + }, this); + + this.messagesBodiesDom.subscribe(function (oDom) { + if (oDom && !(oDom instanceof $)) + { + this.messagesBodiesDom($(oDom)); + } + }, this); + + this.messageListEndFolder.subscribe(function (sFolder) { + var oMessage = this.message(); + if (oMessage && sFolder && sFolder !== oMessage.folderFullNameRaw) + { + this.message(null); + } + }, this); + }; + + MessageUserStore.prototype.purgeMessageBodyCache = function() { var iCount = 0, @@ -400,7 +255,7 @@ } }; - DataUserStorage.prototype.initUidNextAndNewMessages = function (sFolder, sUidNext, aNewMessages) + MessageUserStore.prototype.initUidNextAndNewMessages = function (sFolder, sUidNext, aNewMessages) { if (Cache.getFolderInboxName() === sFolder && Utils.isNormal(sUidNext) && sUidNext !== '') { @@ -445,7 +300,7 @@ } }; - DataUserStorage.prototype.hideMessageBodies = function () + MessageUserStore.prototype.hideMessageBodies = function () { var oMessagesBodiesDom = this.messagesBodiesDom(); if (oMessagesBodiesDom) @@ -454,72 +309,13 @@ } }; - /** - * @param {boolean=} bBoot = false - * @returns {Array} - */ - DataUserStorage.prototype.getNextFolderNames = function (bBoot) - { - bBoot = Utils.isUnd(bBoot) ? false : !!bBoot; - - var - aResult = [], - iLimit = 5, - iUtc = moment().unix(), - iTimeout = iUtc - 60 * 5, - aTimeouts = [], - sInboxFolderName = Cache.getFolderInboxName(), - fSearchFunction = function (aList) { - _.each(aList, function (oFolder) { - if (oFolder && sInboxFolderName !== oFolder.fullNameRaw && - oFolder.selectable && oFolder.existen && - iTimeout > oFolder.interval && - (!bBoot || oFolder.subScribed())) - { - aTimeouts.push([oFolder.interval, oFolder.fullNameRaw]); - } - - if (oFolder && 0 < oFolder.subFolders().length) - { - fSearchFunction(oFolder.subFolders()); - } - }); - } - ; - - fSearchFunction(this.folderList()); - - aTimeouts.sort(function(a, b) { - if (a[0] < b[0]) { - return -1; - } else if (a[0] > b[0]) { - return 1; - } - - return 0; - }); - - _.find(aTimeouts, function (aItem) { - var oFolder = Cache.getFolderFromCacheList(aItem[1]); - if (oFolder) - { - oFolder.interval = iUtc; - aResult.push(aItem[1]); - } - - return iLimit <= aResult.length; - }); - - return _.uniq(aResult); - }; - /** * @param {string} sFromFolderFullNameRaw * @param {Array} aUidForRemove * @param {string=} sToFolderFullNameRaw = '' * @param {bCopy=} bCopy = false */ - DataUserStorage.prototype.removeMessagesFromList = function ( + MessageUserStore.prototype.removeMessagesFromList = function ( sFromFolderFullNameRaw, aUidForRemove, sToFolderFullNameRaw, bCopy) { sToFolderFullNameRaw = Utils.isNormal(sToFolderFullNameRaw) ? sToFolderFullNameRaw : ''; @@ -535,7 +331,7 @@ aMessageList = this.messageList(), oFromFolder = Cache.getFolderFromCacheList(sFromFolderFullNameRaw), oToFolder = '' === sToFolderFullNameRaw ? null : Cache.getFolderFromCacheList(sToFolderFullNameRaw || ''), - sCurrentFolderFullNameRaw = this.currentFolderFullNameRaw(), + sCurrentFolderFullNameRaw = FolderStore.currentFolderFullNameRaw(), oCurrentMessage = this.message(), aMessages = sCurrentFolderFullNameRaw === sFromFolderFullNameRaw ? _.filter(aMessageList, function (oMessage) { return oMessage && -1 < Utils.inArray(Utils.pInt(oMessage.uid), aUidForRemove); @@ -616,7 +412,7 @@ /** * @param {Object} oMessageTextBody */ - DataUserStorage.prototype.initBlockquoteSwitcher = function (oMessageTextBody) + MessageUserStore.prototype.initBlockquoteSwitcher = function (oMessageTextBody) { if (oMessageTextBody) { @@ -648,7 +444,7 @@ } }; - DataUserStorage.prototype.setMessage = function (oData, bCached) + MessageUserStore.prototype.setMessage = function (oData, bCached) { var bIsHtml = false, @@ -805,92 +601,145 @@ * @param {Array} aList * @returns {string} */ - DataUserStorage.prototype.calculateMessageListHash = function (aList) + MessageUserStore.prototype.calculateMessageListHash = function (aList) { return _.map(aList, function (oMessage) { return '' + oMessage.hash + '_' + oMessage.threadsLen() + '_' + oMessage.flagHash(); }).join('|'); }; - DataUserStorage.prototype.findPublicKeyByHex = function (sHash) + MessageUserStore.prototype.setMessageList = function (oData, bCached) { - return _.find(require('Stores/User/Pgp').openpgpkeysPublic(), function (oItem) { - return oItem && sHash === oItem.id; - }); - }; + if (oData && oData.Result && 'Collection/MessageCollection' === oData.Result['@Object'] && + oData.Result['@Collection'] && Utils.isArray(oData.Result['@Collection'])) + { + var + mLastCollapsedThreadUids = null, + iIndex = 0, + iLen = 0, + iCount = 0, + iOffset = 0, + aList = [], + iUtc = moment().unix(), + aStaticList = this.staticMessageList, + oJsonMessage = null, + oMessage = null, + oFolder = null, + iNewCount = 0, + bUnreadCountChange = false + ; - DataUserStorage.prototype.findPublicKeysByEmail = function (sEmail) - { - var PgpStore = require('Stores/User/Pgp'); - return _.compact(_.map(PgpStore.openpgpkeysPublic(), function (oItem) { + iCount = Utils.pInt(oData.Result.MessageResultCount); + iOffset = Utils.pInt(oData.Result.Offset); - var oKey = null; - if (oItem && sEmail === oItem.email) + if (Utils.isNonEmptyArray(oData.Result.LastCollapsedThreadUids)) { - try + mLastCollapsedThreadUids = oData.Result.LastCollapsedThreadUids; + } + + oFolder = Cache.getFolderFromCacheList( + Utils.isNormal(oData.Result.Folder) ? oData.Result.Folder : ''); + + if (oFolder && !bCached) + { + oFolder.interval = iUtc; + + Cache.setFolderHash(oData.Result.Folder, oData.Result.FolderHash); + + if (Utils.isNormal(oData.Result.MessageCount)) { - oKey = PgpStore.openpgp.key.readArmored(oItem.armor); - if (oKey && !oKey.err && oKey.keys && oKey.keys[0]) + oFolder.messageCountAll(oData.Result.MessageCount); + } + + if (Utils.isNormal(oData.Result.MessageUnseenCount)) + { + if (Utils.pInt(oFolder.messageCountUnread()) !== Utils.pInt(oData.Result.MessageUnseenCount)) { - return oKey.keys[0]; + bUnreadCountChange = true; + } + + oFolder.messageCountUnread(oData.Result.MessageUnseenCount); + } + + this.initUidNextAndNewMessages(oFolder.fullNameRaw, oData.Result.UidNext, oData.Result.NewMessages); + } + + if (bUnreadCountChange && oFolder) + { + Cache.clearMessageFlagsFromCacheByFolder(oFolder.fullNameRaw); + } + + for (iIndex = 0, iLen = oData.Result['@Collection'].length; iIndex < iLen; iIndex++) + { + oJsonMessage = oData.Result['@Collection'][iIndex]; + if (oJsonMessage && 'Object/Message' === oJsonMessage['@Object']) + { + oMessage = aStaticList[iIndex]; + if (!oMessage || !oMessage.initByJson(oJsonMessage)) + { + oMessage = MessageModel.newInstanceFromJson(oJsonMessage); + } + + if (oMessage) + { + if (Cache.hasNewMessageAndRemoveFromCache(oMessage.folderFullNameRaw, oMessage.uid) && 5 >= iNewCount) + { + iNewCount++; + oMessage.newForAnimation(true); + } + + oMessage.deleted(false); + + if (bCached) + { + Cache.initMessageFlagsFromCache(oMessage); + } + else + { + Cache.storeMessageFlagsToCache(oMessage); + } + + oMessage.lastInCollapsedThread(mLastCollapsedThreadUids && -1 < Utils.inArray(Utils.pInt(oMessage.uid), mLastCollapsedThreadUids) ? true : false); + + aList.push(oMessage); } } - catch (e) {} } - return null; + this.messageListCount(iCount); + this.messageListSearch(Utils.isNormal(oData.Result.Search) ? oData.Result.Search : ''); + this.messageListPage(window.Math.ceil((iOffset / SettingsStore.messagesPerPage()) + 1)); - })); - }; + this.messageListEndFolder(Utils.isNormal(oData.Result.Folder) ? oData.Result.Folder : ''); + this.messageListEndSearch(Utils.isNormal(oData.Result.Search) ? oData.Result.Search : ''); + this.messageListEndPage(this.messageListPage()); - /** - * @param {string} sEmail - * @param {string=} sPassword - * @returns {?} - */ - DataUserStorage.prototype.findPrivateKeyByEmail = function (sEmail, sPassword) - { - var - PgpStore = require('Stores/User/Pgp'), - oPrivateKey = null, - oKey = _.find(PgpStore.openpgpkeysPrivate(), function (oItem) { - return oItem && sEmail === oItem.email; - }) - ; + this.messageList(aList); + this.messageListIsNotCompleted(false); - if (oKey) - { - try + if (aStaticList.length < aList.length) { - oPrivateKey = PgpStore.openpgp.key.readArmored(oKey.armor); - if (oPrivateKey && !oPrivateKey.err && oPrivateKey.keys && oPrivateKey.keys[0]) - { - oPrivateKey = oPrivateKey.keys[0]; - oPrivateKey.decrypt(Utils.pString(sPassword)); - } - else - { - oPrivateKey = null; - } + this.staticMessageList = aList; } - catch (e) + + Cache.clearNewMessageCache(); + + if (oFolder && (bCached || bUnreadCountChange || SettingsStore.useThreads())) { - oPrivateKey = null; + require('App/User').folderInformation(oFolder.fullNameRaw, aList); } } - - return oPrivateKey; + else + { + this.messageListCount(0); + this.messageList([]); + this.messageListError(Translator.getNotification( + oData && oData.ErrorCode ? oData.ErrorCode : Enums.Notification.CantGetMessageList + )); + } }; - /** - * @param {string=} sPassword - * @returns {?} - */ - DataUserStorage.prototype.findSelfPrivateKey = function (sPassword) - { - return this.findPrivateKeyByEmail(require('Stores/User/Account').email(), sPassword); - }; - - module.exports = new DataUserStorage(); + module.exports = new MessageUserStore(); }()); + diff --git a/dev/Stores/User/Pgp.js b/dev/Stores/User/Pgp.js index a910e1641..979ab8976 100644 --- a/dev/Stores/User/Pgp.js +++ b/dev/Stores/User/Pgp.js @@ -3,7 +3,10 @@ 'use strict'; var - ko = require('ko') + _ = require('_'), + ko = require('ko'), + + Utils = require('Common/Utils') ; /** @@ -35,6 +38,84 @@ return !!this.openpgp; }; + PgpUserStore.prototype.findPublicKeyByHex = function (sHash) + { + return _.find(this.openpgpkeysPublic(), function (oItem) { + return oItem && sHash === oItem.id; + }); + }; + + PgpUserStore.prototype.findPublicKeysByEmail = function (sEmail) + { + var self = this; + return _.compact(_.map(this.openpgpkeysPublic(), function (oItem) { + + var oKey = null; + if (oItem && sEmail === oItem.email) + { + try + { + oKey = self.openpgp.key.readArmored(oItem.armor); + if (oKey && !oKey.err && oKey.keys && oKey.keys[0]) + { + return oKey.keys[0]; + } + } + catch (e) {} + } + + return null; + + })); + }; + + /** + * @param {string} sEmail + * @param {string=} sPassword + * @returns {?} + */ + PgpUserStore.prototype.findPrivateKeyByEmail = function (sEmail, sPassword) + { + var + oPrivateKey = null, + oKey = _.find(this.openpgpkeysPrivate(), function (oItem) { + return oItem && sEmail === oItem.email; + }) + ; + + if (oKey) + { + try + { + oPrivateKey = this.openpgp.key.readArmored(oKey.armor); + if (oPrivateKey && !oPrivateKey.err && oPrivateKey.keys && oPrivateKey.keys[0]) + { + oPrivateKey = oPrivateKey.keys[0]; + oPrivateKey.decrypt(Utils.pString(sPassword)); + } + else + { + oPrivateKey = null; + } + } + catch (e) + { + oPrivateKey = null; + } + } + + return oPrivateKey; + }; + + /** + * @param {string=} sPassword + * @returns {?} + */ + PgpUserStore.prototype.findSelfPrivateKey = function (sPassword) + { + return this.findPrivateKeyByEmail(require('Stores/User/Account').email(), sPassword); + }; + module.exports = new PgpUserStore(); }()); diff --git a/dev/Stores/User/Template.js b/dev/Stores/User/Template.js index 0e123a0ea..315fe1e1e 100644 --- a/dev/Stores/User/Template.js +++ b/dev/Stores/User/Template.js @@ -7,7 +7,7 @@ _ = require('_'), ko = require('ko') -// Remote = require('Storage/User/Remote') +// Remote = require('Remote/User/Ajax') ; /** diff --git a/dev/Styles/Compose.less b/dev/Styles/Compose.less index 94106d0ae..647ba6570 100644 --- a/dev/Styles/Compose.less +++ b/dev/Styles/Compose.less @@ -56,6 +56,9 @@ opacity: 1; color: #fff; border-color: #eee; + + font-size: 28px; + line-height: 28px; } .btn.disabled { diff --git a/dev/Styles/Layout.less b/dev/Styles/Layout.less index 59ccf85be..d183aded1 100644 --- a/dev/Styles/Layout.less +++ b/dev/Styles/Layout.less @@ -139,7 +139,7 @@ html.ssm-state-tablet, html.ssm-state-mobile { } .b-compose.modal { - width: 700px; + width: 720px; } .b-contacts-content.modal { @@ -156,7 +156,7 @@ html.ssm-state-tablet, html.ssm-state-mobile { html.ssm-state-tablet { .b-compose.modal { - width: 700px; + width: 720px; } .b-contacts-content.modal { diff --git a/dev/Styles/_BootstrapFix.less b/dev/Styles/_BootstrapFix.less index b6dcd6c9a..395a998fd 100644 --- a/dev/Styles/_BootstrapFix.less +++ b/dev/Styles/_BootstrapFix.less @@ -74,7 +74,7 @@ select { } .btn.btn-thin { - padding: 3px 9px; + padding: 4px 9px; } .btn.btn-ellipsis { diff --git a/dev/Styles/_CkeFix.less b/dev/Styles/_CkeFix.less index 158f07624..d022d8a71 100644 --- a/dev/Styles/_CkeFix.less +++ b/dev/Styles/_CkeFix.less @@ -108,11 +108,10 @@ padding-left: 5px; } - blockquote * { - font-family: arial,sans-serif; - font-size: 13px; - line-height: 16px; - color: #333; + blockquote p { + margin: 0 0 10px; + font-size: 14px; + line-height: 20px; } img { diff --git a/dev/View/Admin/Login.js b/dev/View/Admin/Login.js index 782a22373..1c6ca20f2 100644 --- a/dev/View/Admin/Login.js +++ b/dev/View/Admin/Login.js @@ -12,7 +12,7 @@ Translator = require('Common/Translator'), Settings = require('Storage/Settings'), - Remote = require('Storage/Admin/Remote'), + Remote = require('Remote/Admin/Ajax'), kn = require('Knoin/Knoin'), AbstractView = require('Knoin/AbstractView') diff --git a/dev/View/Admin/Settings/Pane.js b/dev/View/Admin/Settings/Pane.js index d40a156f0..b6884adb0 100644 --- a/dev/View/Admin/Settings/Pane.js +++ b/dev/View/Admin/Settings/Pane.js @@ -8,7 +8,7 @@ ko = require('ko'), Settings = require('Storage/Settings'), - Remote = require('Storage/Admin/Remote'), + Remote = require('Remote/Admin/Ajax'), kn = require('Knoin/Knoin'), AbstractView = require('Knoin/AbstractView') diff --git a/dev/View/Popup/Account.js b/dev/View/Popup/Account.js index 403e76d0a..c8ddaa296 100644 --- a/dev/View/Popup/Account.js +++ b/dev/View/Popup/Account.js @@ -11,7 +11,7 @@ Utils = require('Common/Utils'), Translator = require('Common/Translator'), - Remote = require('Storage/User/Remote'), + Remote = require('Remote/User/Ajax'), kn = require('Knoin/Knoin'), AbstractView = require('Knoin/AbstractView') diff --git a/dev/View/Popup/Activate.js b/dev/View/Popup/Activate.js index f164dcce8..5a072f5b2 100644 --- a/dev/View/Popup/Activate.js +++ b/dev/View/Popup/Activate.js @@ -13,7 +13,7 @@ Translator = require('Common/Translator'), Settings = require('Storage/Settings'), - Remote = require('Storage/Admin/Remote'), + Remote = require('Remote/Admin/Ajax'), LicenseStore = require('Stores/Admin/License'), diff --git a/dev/View/Popup/AdvancedSearch.js b/dev/View/Popup/AdvancedSearch.js index ed8d00dd5..6bf1f0921 100644 --- a/dev/View/Popup/AdvancedSearch.js +++ b/dev/View/Popup/AdvancedSearch.js @@ -10,7 +10,7 @@ Utils = require('Common/Utils'), - Data = require('Storage/User/Data'), + MessageStore = require('Stores/User/Message'), kn = require('Knoin/Knoin'), AbstractView = require('Knoin/AbstractView') @@ -41,7 +41,7 @@ var sSearch = this.buildSearchString(); if ('' !== sSearch) { - Data.mainMessageListSearch(sSearch); + MessageStore.mainMessageListSearch(sSearch); } this.cancelCommand(); diff --git a/dev/View/Popup/Compose.js b/dev/View/Popup/Compose.js index c72aec14b..5cb13da4d 100644 --- a/dev/View/Popup/Compose.js +++ b/dev/View/Popup/Compose.js @@ -21,18 +21,19 @@ HtmlEditor = require('Common/HtmlEditor'), Translator = require('Common/Translator'), + Cache = require('Common/Cache'), + AppStore = require('Stores/User/App'), SettingsStore = require('Stores/User/Settings'), IdentityStore = require('Stores/User/Identity'), AccountStore = require('Stores/User/Account'), FolderStore = require('Stores/User/Folder'), PgpStore = require('Stores/User/Pgp'), + MessageStore = require('Stores/User/Message'), SocialStore = require('Stores/Social'), Settings = require('Storage/Settings'), - Data = require('Storage/User/Data'), - Cache = require('Storage/User/Cache'), - Remote = require('Storage/User/Remote'), + Remote = require('Remote/User/Ajax'), ComposeAttachmentModel = require('Model/ComposeAttachment'), @@ -87,7 +88,7 @@ this.allowContacts = !!AppStore.contactsIsAllowed(); this.bSkipNextHide = false; - this.composeInEdit = Data.composeInEdit; + this.composeInEdit = AppStore.composeInEdit; this.editorDefaultType = SettingsStore.editorDefaultType; this.capaOpenPGP = PgpStore.capaOpenPGP; @@ -121,6 +122,7 @@ this.subject = ko.observable(''); this.isHtml = ko.observable(false); + this.requestDsn = ko.observable(false); this.requestReadReceipt = ko.observable(false); this.markAsImportant = ko.observable(false); @@ -366,6 +368,7 @@ this.aDraftInfo, this.sInReplyTo, this.sReferences, + this.requestDsn(), this.requestReadReceipt(), this.markAsImportant() ); @@ -433,8 +436,6 @@ var self = this; - window.console.log(this.sLastFocusedField); - _.delay(function () { kn.showScreenPopup(require('View/Popup/Contacts'), [true, self.sLastFocusedField]); @@ -578,7 +579,7 @@ if ('' !== sDraftFolder) { Cache.setFolderHash(sDraftFolder, ''); - if (Data.currentFolderFullNameRaw() === sDraftFolder) + if (FolderStore.currentFolderFullNameRaw() === sDraftFolder) { require('App/User').reloadMessageList(true); } @@ -701,10 +702,10 @@ if (this.bFromDraft) { - oMessage = Data.message(); + oMessage = MessageStore.message(); if (oMessage && this.draftFolder() === oMessage.folderFullNameRaw && this.draftUid() === oMessage.uid) { - Data.message(null); + MessageStore.message(null); } } @@ -741,7 +742,7 @@ if (!this.bSkipNextHide) { - this.composeInEdit(false); + AppStore.composeInEdit(false); this.reset(); } @@ -883,7 +884,7 @@ this.autosaveStart(); - if (this.composeInEdit()) + if (AppStore.composeInEdit()) { sType = sType || Enums.ComposeType.Empty; @@ -969,7 +970,7 @@ ComposePopupView.prototype.initOnShow = function (sType, oMessageOrArray, aToEmails, aCcEmails, aBccEmails, sCustomSubject, sCustomPlainText) { - this.composeInEdit(true); + AppStore.composeInEdit(true); var self = this, @@ -2012,6 +2013,7 @@ this.replyTo(''); this.subject(''); + this.requestDsn(false); this.requestReadReceipt(false); this.markAsImportant(false); diff --git a/dev/View/Popup/ComposeOpenPgp.js b/dev/View/Popup/ComposeOpenPgp.js index 828c49bad..e77a82f18 100644 --- a/dev/View/Popup/ComposeOpenPgp.js +++ b/dev/View/Popup/ComposeOpenPgp.js @@ -12,7 +12,6 @@ Enums = require('Common/Enums'), Translator = require('Common/Translator'), - Data = require('Storage/User/Data'), PgpStore = require('Stores/User/Pgp'), EmailModel = require('Model/Email'), @@ -66,7 +65,7 @@ if (bResult && this.sign()) { - oPrivateKey = Data.findPrivateKeyByEmail(this.from(), this.password()); + oPrivateKey = PgpStore.findPrivateKeyByEmail(this.from(), this.password()); if (!oPrivateKey) { this.notification(Translator.i18n('PGP_NOTIFICATIONS/NO_PRIVATE_KEY_FOUND_FOR', { @@ -87,7 +86,7 @@ { aPublicKeys = []; _.each(this.to(), function (sEmail) { - var aKeys = Data.findPublicKeysByEmail(sEmail); + var aKeys = PgpStore.findPublicKeysByEmail(sEmail); if (0 === aKeys.length && bResult) { self.notification(Translator.i18n('PGP_NOTIFICATIONS/NO_PUBLIC_KEYS_FOUND_FOR', { diff --git a/dev/View/Popup/Contacts.js b/dev/View/Popup/Contacts.js index 5ba47fcd5..42844cfd3 100644 --- a/dev/View/Popup/Contacts.js +++ b/dev/View/Popup/Contacts.js @@ -19,9 +19,9 @@ Translator = require('Common/Translator'), SettingsStore = require('Stores/User/Settings'), + ContactStore = require('Stores/User/Contact'), - Data = require('Storage/User/Data'), - Remote = require('Storage/User/Remote'), + Remote = require('Remote/User/Ajax'), EmailModel = require('Model/Email'), ContactModel = require('Model/Contact'), @@ -52,13 +52,13 @@ this.bBackToCompose = false; this.sLastComposeFocusedField = ''; - this.allowContactsSync = Data.allowContactsSync; - this.enableContactsSync = Data.enableContactsSync; + this.allowContactsSync = ContactStore.allowContactsSync; + this.enableContactsSync = ContactStore.enableContactsSync; this.allowExport = !Globals.bMobileDevice; this.search = ko.observable(''); this.contactsCount = ko.observable(0); - this.contacts = Data.contacts; + this.contacts = ContactStore.contacts; this.currentContact = ko.observable(null); diff --git a/dev/View/Popup/Domain.js b/dev/View/Popup/Domain.js index 88f661bd9..800343878 100644 --- a/dev/View/Popup/Domain.js +++ b/dev/View/Popup/Domain.js @@ -14,7 +14,7 @@ CapaAdminStore = require('Stores/Admin/Capa'), - Remote = require('Storage/Admin/Remote'), + Remote = require('Remote/Admin/Ajax'), kn = require('Knoin/Knoin'), AbstractView = require('Knoin/AbstractView') diff --git a/dev/View/Popup/Filter.js b/dev/View/Popup/Filter.js index 44dc15353..c5f5ad428 100644 --- a/dev/View/Popup/Filter.js +++ b/dev/View/Popup/Filter.js @@ -12,9 +12,8 @@ Utils = require('Common/Utils'), Translator = require('Common/Translator'), - Data = require('Storage/User/Data'), - FilterStore = require('Stores/User/Filter'), + FolderStore = require('Stores/User/Folder'), kn = require('Knoin/Knoin'), AbstractView = require('Knoin/AbstractView') @@ -38,7 +37,7 @@ this.allowMarkAsRead = ko.observable(false); this.defautOptionsAfterRender = Utils.defautOptionsAfterRender; - this.folderSelectList = Data.folderMenuForFilters; + this.folderSelectList = FolderStore.folderMenuForFilters; this.selectedFolderValue = ko.observable(''); this.selectedFolderValue.subscribe(function() { diff --git a/dev/View/Popup/FolderClear.js b/dev/View/Popup/FolderClear.js index c842cbd53..d3dea40de 100644 --- a/dev/View/Popup/FolderClear.js +++ b/dev/View/Popup/FolderClear.js @@ -11,9 +11,11 @@ Utils = require('Common/Utils'), Translator = require('Common/Translator'), - Data = require('Storage/User/Data'), - Cache = require('Storage/User/Cache'), - Remote = require('Storage/User/Remote'), + Cache = require('Common/Cache'), + + MessageStore = require('Stores/User/Message'), + + Remote = require('Remote/User/Ajax'), kn = require('Knoin/Knoin'), AbstractView = require('Knoin/AbstractView') @@ -56,8 +58,8 @@ if (oFolderToClear) { - Data.message(null); - Data.messageList([]); + MessageStore.message(null); + MessageStore.messageList([]); this.clearingProcess(true); diff --git a/dev/View/Popup/FolderCreate.js b/dev/View/Popup/FolderCreate.js index 500f032df..74eccde79 100644 --- a/dev/View/Popup/FolderCreate.js +++ b/dev/View/Popup/FolderCreate.js @@ -13,8 +13,9 @@ Utils = require('Common/Utils'), Translator = require('Common/Translator'), - Data = require('Storage/User/Data'), - Remote = require('Storage/User/Remote'), + FolderStore = require('Stores/User/Folder'), + + Remote = require('Remote/User/Ajax'), kn = require('Knoin/Knoin'), AbstractView = require('Knoin/AbstractView') @@ -43,7 +44,7 @@ aTop = [], fDisableCallback = null, fVisibleCallback = null, - aList = Data.folderList(), + aList = FolderStore.folderList(), fRenameCallback = function (oItem) { return oItem ? (oItem.isSystemFolder() ? oItem.name() + ' ' + oItem.manageFolderSystemName() : oItem.name()) : ''; } @@ -51,11 +52,11 @@ aTop.push(['', this.sNoParentText]); - if ('' !== Data.namespace) + if ('' !== FolderStore.namespace) { fDisableCallback = function (oItem) { - return Data.namespace !== oItem.fullNameRaw.substr(0, Data.namespace.length); + return FolderStore.namespace !== oItem.fullNameRaw.substr(0, FolderStore.namespace.length); }; } @@ -70,22 +71,22 @@ sParentFolderName = this.selectedParentValue() ; - if ('' === sParentFolderName && 1 < Data.namespace.length) + if ('' === sParentFolderName && 1 < FolderStore.namespace.length) { - sParentFolderName = Data.namespace.substr(0, Data.namespace.length - 1); + sParentFolderName = FolderStore.namespace.substr(0, FolderStore.namespace.length - 1); } - Data.foldersCreating(true); + FolderStore.foldersCreating(true); Remote.folderCreate(function (sResult, oData) { - Data.foldersCreating(false); + FolderStore.foldersCreating(false); if (Enums.StorageResultType.Success === sResult && oData && oData.Result) { require('App/User').folders(); } else { - Data.folderList.error( + FolderStore.folderList.error( oData && oData.ErrorCode ? Translator.getNotification(oData.ErrorCode) : Translator.i18n('NOTIFICATIONS/CANT_CREATE_FOLDER')); } diff --git a/dev/View/Popup/FolderSystem.js b/dev/View/Popup/FolderSystem.js index b39f806a5..1f4742de8 100644 --- a/dev/View/Popup/FolderSystem.js +++ b/dev/View/Popup/FolderSystem.js @@ -15,8 +15,7 @@ FolderStore = require('Stores/User/Folder'), Settings = require('Storage/Settings'), - Data = require('Storage/User/Data'), - Remote = require('Storage/User/Remote'), + Remote = require('Remote/User/Ajax'), kn = require('Knoin/Knoin'), AbstractView = require('Knoin/AbstractView') @@ -38,7 +37,7 @@ this.notification = ko.observable(''); this.folderSelectList = ko.computed(function () { - return Utils.folderListOptionsBuilder([], Data.folderList(), Data.folderListSystemNames(), [ + return Utils.folderListOptionsBuilder([], FolderStore.folderList(), FolderStore.folderListSystemNames(), [ ['', this.sChooseOnText], [Consts.Values.UnuseOptionValue, this.sUnuseText] ], null, null, null, null, null, true); diff --git a/dev/View/Popup/Identity.js b/dev/View/Popup/Identity.js index e4930fffc..dbfe4ff15 100644 --- a/dev/View/Popup/Identity.js +++ b/dev/View/Popup/Identity.js @@ -13,7 +13,7 @@ Translator = require('Common/Translator'), HtmlEditor = require('Common/HtmlEditor'), - Remote = require('Storage/User/Remote'), + Remote = require('Remote/User/Ajax'), kn = require('Knoin/Knoin'), AbstractView = require('Knoin/AbstractView') diff --git a/dev/View/Popup/Plugin.js b/dev/View/Popup/Plugin.js index 433d77aa0..1f0631a06 100644 --- a/dev/View/Popup/Plugin.js +++ b/dev/View/Popup/Plugin.js @@ -12,7 +12,7 @@ Utils = require('Common/Utils'), Translator = require('Common/Translator'), - Remote = require('Storage/Admin/Remote'), + Remote = require('Remote/Admin/Ajax'), kn = require('Knoin/Knoin'), AbstractView = require('Knoin/AbstractView') diff --git a/dev/View/Popup/Template.js b/dev/View/Popup/Template.js index 315b5bde9..4c4551e5a 100644 --- a/dev/View/Popup/Template.js +++ b/dev/View/Popup/Template.js @@ -12,7 +12,7 @@ Translator = require('Common/Translator'), HtmlEditor = require('Common/HtmlEditor'), - Remote = require('Storage/User/Remote'), + Remote = require('Remote/User/Ajax'), kn = require('Knoin/Knoin'), AbstractView = require('Knoin/AbstractView') diff --git a/dev/View/Popup/TwoFactorTest.js b/dev/View/Popup/TwoFactorTest.js index 1a6153fdc..465f2fe9a 100644 --- a/dev/View/Popup/TwoFactorTest.js +++ b/dev/View/Popup/TwoFactorTest.js @@ -11,7 +11,7 @@ Globals = require('Common/Globals'), Utils = require('Common/Utils'), - Remote = require('Storage/User/Remote'), + Remote = require('Remote/User/Ajax'), kn = require('Knoin/Knoin'), AbstractView = require('Knoin/AbstractView') diff --git a/dev/View/User/Login.js b/dev/View/User/Login.js index d549cd141..225c52bf5 100644 --- a/dev/View/User/Login.js +++ b/dev/View/User/Login.js @@ -22,7 +22,8 @@ Local = require('Storage/Client'), Settings = require('Storage/Settings'), - Remote = require('Storage/User/Remote'), + + Remote = require('Remote/User/Ajax'), kn = require('Knoin/Knoin'), AbstractView = require('Knoin/AbstractView') @@ -351,7 +352,7 @@ { case Enums.LoginSignMeTypeAsString.DefaultOff: case Enums.LoginSignMeTypeAsString.DefaultOn: - + this.signMeType(Enums.LoginSignMeTypeAsString.DefaultOn === sSignMe ? Enums.LoginSignMeType.DefaultOn : Enums.LoginSignMeType.DefaultOff); diff --git a/dev/View/User/MailBox/FolderList.js b/dev/View/User/MailBox/FolderList.js index bf4060b92..4c644bd51 100644 --- a/dev/View/User/MailBox/FolderList.js +++ b/dev/View/User/MailBox/FolderList.js @@ -15,11 +15,12 @@ Globals = require('Common/Globals'), Links = require('Common/Links'), + Cache = require('Common/Cache'), + AppStore = require('Stores/User/App'), SettingsStore = require('Stores/User/Settings'), - - Cache = require('Storage/User/Cache'), - Data = require('Storage/User/Data'), + FolderStore = require('Stores/User/Folder'), + MessageStore = require('Stores/User/Message'), kn = require('Knoin/Knoin'), AbstractView = require('Knoin/AbstractView') @@ -36,14 +37,14 @@ this.oContentVisible = null; this.oContentScrollable = null; - this.composeInEdit = Data.composeInEdit; + this.composeInEdit = AppStore.composeInEdit; - this.messageList = Data.messageList; - this.folderList = Data.folderList; - this.folderListSystem = Data.folderListSystem; - this.foldersChanging = Data.foldersChanging; + this.messageList = MessageStore.messageList; + this.folderList = FolderStore.folderList; + this.folderListSystem = FolderStore.folderListSystem; + this.foldersChanging = FolderStore.foldersChanging; - this.foldersListWithSingleInboxRootFolder = Data.foldersListWithSingleInboxRootFolder; + this.foldersListWithSingleInboxRootFolder = FolderStore.foldersListWithSingleInboxRootFolder; this.leftPanelDisabled = Globals.leftPanelDisabled; @@ -94,10 +95,10 @@ { if (Enums.Layout.NoPreview === SettingsStore.layout()) { - Data.message(null); + MessageStore.message(null); } - if (oFolder.fullNameRaw === Data.currentFolderFullNameRaw()) + if (oFolder.fullNameRaw === FolderStore.currentFolderFullNameRaw()) { Cache.setFolderHash(oFolder.fullNameRaw, ''); } @@ -143,7 +144,7 @@ var $items = $('.b-folders .e-item .e-link:not(.hidden).focused', oDom); if ($items.length && $items[0]) { - self.folderList.focused(false); + FolderStore.folderList.focused(false); $items.click(); } @@ -167,11 +168,11 @@ }); key('esc, tab, shift+tab, right', Enums.KeyState.FolderList, function () { - self.folderList.focused(false); + FolderStore.folderList.focused(false); return false; }); - self.folderList.focused.subscribe(function (bValue) { + FolderStore.folderList.focused.subscribe(function (bValue) { $('.b-folders .e-item .e-link.focused', oDom).removeClass('focused'); if (bValue) { diff --git a/dev/View/User/MailBox/MessageList.js b/dev/View/User/MailBox/MessageList.js index 8a9ab8ccd..fff46919e 100644 --- a/dev/View/User/MailBox/MessageList.js +++ b/dev/View/User/MailBox/MessageList.js @@ -20,14 +20,15 @@ Selector = require('Common/Selector'), Translator = require('Common/Translator'), + Cache = require('Common/Cache'), + QuotaStore = require('Stores/User/Quota'), SettingsStore = require('Stores/User/Settings'), FolderStore = require('Stores/User/Folder'), + MessageStore = require('Stores/User/Message'), Settings = require('Storage/Settings'), - Cache = require('Storage/User/Cache'), - Data = require('Storage/User/Data'), - Remote = require('Storage/User/Remote'), + Remote = require('Remote/User/Ajax'), kn = require('Knoin/Knoin'), AbstractView = require('Knoin/AbstractView') @@ -49,24 +50,24 @@ this.popupVisibility = Globals.popupVisibility; - this.message = Data.message; - this.messageList = Data.messageList; - this.folderList = Data.folderList; - this.currentMessage = Data.currentMessage; - this.isMessageSelected = Data.isMessageSelected; - this.messageListSearch = Data.messageListSearch; - this.messageListError = Data.messageListError; - this.folderMenuForMove = Data.folderMenuForMove; + this.message = MessageStore.message; + this.messageList = MessageStore.messageList; + this.folderList = FolderStore.folderList; + this.currentMessage = MessageStore.currentMessage; + this.isMessageSelected = MessageStore.isMessageSelected; + this.messageListSearch = MessageStore.messageListSearch; + this.messageListError = MessageStore.messageListError; + this.folderMenuForMove = FolderStore.folderMenuForMove; this.useCheckboxesInList = SettingsStore.useCheckboxesInList; - this.mainMessageListSearch = Data.mainMessageListSearch; - this.messageListEndFolder = Data.messageListEndFolder; + this.mainMessageListSearch = MessageStore.mainMessageListSearch; + this.messageListEndFolder = MessageStore.messageListEndFolder; - this.messageListChecked = Data.messageListChecked; - this.messageListCheckedOrSelected = Data.messageListCheckedOrSelected; - this.messageListCheckedOrSelectedUidsWithSubMails = Data.messageListCheckedOrSelectedUidsWithSubMails; - this.messageListCompleteLoadingThrottle = Data.messageListCompleteLoadingThrottle; + this.messageListChecked = MessageStore.messageListChecked; + this.messageListCheckedOrSelected = MessageStore.messageListCheckedOrSelected; + this.messageListCheckedOrSelectedUidsWithSubMails = MessageStore.messageListCheckedOrSelectedUidsWithSubMails; + this.messageListCompleteLoadingThrottle = MessageStore.messageListCompleteLoadingThrottle; Translator.initOnStartOrLangChange(function () { this.emptySubjectValue = Translator.i18n('MESSAGE_LIST/EMPTY_SUBJECT_TEXT'); @@ -91,20 +92,21 @@ }); this.messageListSearchDesc = ko.computed(function () { - var sValue = Data.messageListEndSearch(); + var sValue = MessageStore.messageListEndSearch(); return '' === sValue ? '' : Translator.i18n('MESSAGE_LIST/SEARCH_RESULT_FOR', {'SEARCH': sValue}); }); - this.messageListPagenator = ko.computed(Utils.computedPagenatorHelper(Data.messageListPage, Data.messageListPageCount)); + this.messageListPagenator = ko.computed(Utils.computedPagenatorHelper( + MessageStore.messageListPage, MessageStore.messageListPageCount)); this.checkAll = ko.computed({ 'read': function () { - return 0 < Data.messageListChecked().length; + return 0 < MessageStore.messageListChecked().length; }, 'write': function (bValue) { bValue = !!bValue; - _.each(Data.messageList(), function (oMessage) { + _.each(MessageStore.messageList(), function (oMessage) { oMessage.checked(bValue); }); } @@ -123,8 +125,8 @@ this.isIncompleteChecked = ko.computed(function () { var - iM = Data.messageList().length, - iC = Data.messageListChecked().length + iM = MessageStore.messageList().length, + iC = MessageStore.messageListChecked().length ; return 0 < iM && 0 < iC && iM > iC; }, this); @@ -173,48 +175,48 @@ this.canBeMoved = this.hasCheckedOrSelectedLines; this.clearCommand = Utils.createCommand(this, function () { - kn.showScreenPopup(require('View/Popup/FolderClear'), [Data.currentFolder()]); + kn.showScreenPopup(require('View/Popup/FolderClear'), [FolderStore.currentFolder()]); }); this.multyForwardCommand = Utils.createCommand(this, function () { kn.showScreenPopup(require('View/Popup/Compose'), [ - Enums.ComposeType.ForwardAsAttachment, Data.messageListCheckedOrSelected()]); + Enums.ComposeType.ForwardAsAttachment, MessageStore.messageListCheckedOrSelected()]); }, this.canBeMoved); this.deleteWithoutMoveCommand = Utils.createCommand(this, function () { require('App/User').deleteMessagesFromFolder(Enums.FolderType.Trash, - Data.currentFolderFullNameRaw(), - Data.messageListCheckedOrSelectedUidsWithSubMails(), false); + FolderStore.currentFolderFullNameRaw(), + MessageStore.messageListCheckedOrSelectedUidsWithSubMails(), false); }, this.canBeMoved); this.deleteCommand = Utils.createCommand(this, function () { require('App/User').deleteMessagesFromFolder(Enums.FolderType.Trash, - Data.currentFolderFullNameRaw(), - Data.messageListCheckedOrSelectedUidsWithSubMails(), true); + FolderStore.currentFolderFullNameRaw(), + MessageStore.messageListCheckedOrSelectedUidsWithSubMails(), true); }, this.canBeMoved); this.archiveCommand = Utils.createCommand(this, function () { require('App/User').deleteMessagesFromFolder(Enums.FolderType.Archive, - Data.currentFolderFullNameRaw(), - Data.messageListCheckedOrSelectedUidsWithSubMails(), true); + FolderStore.currentFolderFullNameRaw(), + MessageStore.messageListCheckedOrSelectedUidsWithSubMails(), true); }, this.canBeMoved); this.spamCommand = Utils.createCommand(this, function () { require('App/User').deleteMessagesFromFolder(Enums.FolderType.Spam, - Data.currentFolderFullNameRaw(), - Data.messageListCheckedOrSelectedUidsWithSubMails(), true); + FolderStore.currentFolderFullNameRaw(), + MessageStore.messageListCheckedOrSelectedUidsWithSubMails(), true); }, this.canBeMoved); this.notSpamCommand = Utils.createCommand(this, function () { require('App/User').deleteMessagesFromFolder(Enums.FolderType.NotSpam, - Data.currentFolderFullNameRaw(), - Data.messageListCheckedOrSelectedUidsWithSubMails(), true); + FolderStore.currentFolderFullNameRaw(), + MessageStore.messageListCheckedOrSelectedUidsWithSubMails(), true); }, this.canBeMoved); this.moveCommand = Utils.createCommand(this, Utils.emptyFunction, this.canBeMoved); this.reloadCommand = Utils.createCommand(this, function () { - if (!Data.messageListCompleteLoadingThrottle()) + if (!MessageStore.messageListCompleteLoadingThrottle()) { require('App/User').reloadMessageList(false, true); } @@ -229,18 +231,19 @@ this.selector.on('onItemSelect', _.bind(function (oMessage) { if (oMessage) { - Data.message(Data.staticMessageList.populateByMessageListItem(oMessage)); - this.populateMessageBody(Data.message()); + MessageStore.message(MessageStore.staticMessage.populateByMessageListItem(oMessage)); + + this.populateMessageBody(MessageStore.message()); if (Enums.Layout.NoPreview === SettingsStore.layout()) { kn.setHash(Links.messagePreview(), true); - Data.message.focused(true); + MessageStore.message.focused(true); } } else { - Data.message(null); + MessageStore.message(null); } }, this)); @@ -248,23 +251,14 @@ return oMessage ? oMessage.generateUid() : ''; }); - Data.messageListEndHash.subscribe(function () { + MessageStore.messageListEndHash.subscribe(function () { this.selector.scrollToTop(); }, this); - Data.messageListEndFolder.subscribe(function (sFolder) { - var oMessage = Data.message(); - if (oMessage && sFolder && sFolder !== oMessage.folderFullNameRaw) - { - Data.message(null); - } - }, this); - SettingsStore.layout.subscribe(function (mValue) { this.selector.autoSelect(Enums.Layout.NoPreview !== mValue); }, this); - SettingsStore.layout.valueHasMutated(); Events @@ -318,8 +312,8 @@ if (this.canBeMoved()) { require('App/User').moveMessagesToFolder( - Data.currentFolderFullNameRaw(), - Data.messageListCheckedOrSelectedUidsWithSubMails(), sToFolderFullNameRaw, bCopy); + FolderStore.currentFolderFullNameRaw(), + MessageStore.messageListCheckedOrSelectedUidsWithSubMails(), sToFolderFullNameRaw, bCopy); } return false; @@ -334,15 +328,15 @@ var oEl = Utils.draggablePlace(), - aUids = Data.messageListCheckedOrSelectedUidsWithSubMails() + aUids = MessageStore.messageListCheckedOrSelectedUidsWithSubMails() ; - oEl.data('rl-folder', Data.currentFolderFullNameRaw()); + oEl.data('rl-folder', FolderStore.currentFolderFullNameRaw()); oEl.data('rl-uids', aUids); oEl.find('.text').text('' + aUids.length); _.defer(function () { - var aUids = Data.messageListCheckedOrSelectedUidsWithSubMails(); + var aUids = MessageStore.messageListCheckedOrSelectedUidsWithSubMails(); oEl.data('rl-uids', aUids); oEl.find('.text').text('' + aUids.length); @@ -358,22 +352,22 @@ */ MessageListMailBoxUserView.prototype.onMessageResponse = function (sResult, oData, bCached) { - Data.hideMessageBodies(); - Data.messageLoading(false); + MessageStore.hideMessageBodies(); + MessageStore.messageLoading(false); if (Enums.StorageResultType.Success === sResult && oData && oData.Result) { - Data.setMessage(oData, bCached); + MessageStore.setMessage(oData, bCached); } else if (Enums.StorageResultType.Unload === sResult) { - Data.message(null); - Data.messageError(''); + MessageStore.message(null); + MessageStore.messageError(''); } else if (Enums.StorageResultType.Abort !== sResult) { - Data.message(null); - Data.messageError((oData && oData.ErrorCode ? + MessageStore.message(null); + MessageStore.messageError((oData && oData.ErrorCode ? Translator.getNotification(oData.ErrorCode) : Translator.getNotification(Enums.Notification.UnknownError))); } @@ -385,7 +379,7 @@ { if (Remote.message(this.onMessageResponse, oMessage.folderFullNameRaw, oMessage.uid)) { - Data.messageLoading(true); + MessageStore.messageLoading(true); } else { @@ -409,7 +403,7 @@ if (Utils.isUnd(aMessages)) { - aMessages = Data.messageListChecked(); + aMessages = MessageStore.messageListChecked(); } aUids = _.map(aMessages, function (oMessage) { @@ -484,7 +478,7 @@ { var oFolder = null, - aMessages = Data.messageList() + aMessages = MessageStore.messageList() ; if ('' !== sFolderFullNameRaw) @@ -530,27 +524,31 @@ MessageListMailBoxUserView.prototype.listSetSeen = function () { - this.setAction(Data.currentFolderFullNameRaw(), Enums.MessageSetAction.SetSeen, Data.messageListCheckedOrSelected()); + this.setAction(FolderStore.currentFolderFullNameRaw(), Enums.MessageSetAction.SetSeen, + MessageStore.messageListCheckedOrSelected()); }; MessageListMailBoxUserView.prototype.listSetAllSeen = function () { - this.setActionForAll(Data.currentFolderFullNameRaw(), Enums.MessageSetAction.SetSeen); + this.setActionForAll(FolderStore.currentFolderFullNameRaw(), Enums.MessageSetAction.SetSeen); }; MessageListMailBoxUserView.prototype.listUnsetSeen = function () { - this.setAction(Data.currentFolderFullNameRaw(), Enums.MessageSetAction.UnsetSeen, Data.messageListCheckedOrSelected()); + this.setAction(FolderStore.currentFolderFullNameRaw(), Enums.MessageSetAction.UnsetSeen, + MessageStore.messageListCheckedOrSelected()); }; MessageListMailBoxUserView.prototype.listSetFlags = function () { - this.setAction(Data.currentFolderFullNameRaw(), Enums.MessageSetAction.SetFlag, Data.messageListCheckedOrSelected()); + this.setAction(FolderStore.currentFolderFullNameRaw(), Enums.MessageSetAction.SetFlag, + MessageStore.messageListCheckedOrSelected()); }; MessageListMailBoxUserView.prototype.listUnsetFlags = function () { - this.setAction(Data.currentFolderFullNameRaw(), Enums.MessageSetAction.UnsetFlag, Data.messageListCheckedOrSelected()); + this.setAction(FolderStore.currentFolderFullNameRaw(), Enums.MessageSetAction.UnsetFlag, + MessageStore.messageListCheckedOrSelected()); }; MessageListMailBoxUserView.prototype.flagMessages = function (oCurrentMessage) @@ -649,9 +647,9 @@ if (oMessage && !oMessage.lastInCollapsedThreadLoading()) { - Data.messageListThreadFolder(oMessage.folderFullNameRaw); + MessageStore.messageListThreadFolder(oMessage.folderFullNameRaw); - aList = Data.messageListThreadUids(); + aList = MessageStore.messageListThreadUids(); if (oMessage.lastInCollapsedThread()) { @@ -662,7 +660,7 @@ aList = _.without(aList, 0 < oMessage.parentUid() ? oMessage.parentUid() : oMessage.uid); } - Data.messageListThreadUids(_.uniq(aList)); + MessageStore.messageListThreadUids(_.uniq(aList)); oMessage.lastInCollapsedThreadLoading(true); oMessage.lastInCollapsedThread(!oMessage.lastInCollapsedThread()); @@ -687,9 +685,9 @@ if (oPage) { kn.setHash(Links.mailBox( - Data.currentFolderFullNameHash(), + FolderStore.currentFolderFullNameHash(), oPage.value, - Data.messageListSearch() + MessageStore.messageListSearch() )); } }) @@ -733,7 +731,7 @@ key('delete, shift+delete, shift+3', Enums.KeyState.MessageList, function (event, handler) { if (event) { - if (0 < Data.messageListCheckedOrSelected().length) + if (0 < MessageStore.messageListCheckedOrSelected().length) { if (handler && 'shift+delete' === handler.shortcut) { @@ -815,7 +813,7 @@ key('tab, shift+tab, left, right', Enums.KeyState.MessageList, function (event, handler) { if (event && handler && ('shift+tab' === handler.shortcut || 'left' === handler.shortcut)) { - self.folderList.focused(true); + FolderStore.folderList.focused(true); } else if (self.message()) { @@ -904,7 +902,7 @@ 'disableFolderDragAndDrop': true, 'hidden': { 'Folder': function () { - return Data.currentFolderFullNameRaw(); + return FolderStore.currentFolderFullNameRaw(); } }, 'dragAndDropElement': this.dragOverArea(), @@ -933,13 +931,15 @@ this.dragOver(false); }, this)) .on('onSelect', _.bind(function (sUid, oData) { + if (sUid && oData && 'message/rfc822' === oData['Type']) { - Data.messageListLoading(true); + MessageStore.messageListLoading(true); return true; } return false; + }, this)) .on('onComplete', _.bind(function () { require('App/User').reloadMessageList(true, true); diff --git a/dev/View/User/MailBox/MessageView.js b/dev/View/User/MailBox/MessageView.js index 980f7ada8..921b14cf4 100644 --- a/dev/View/User/MailBox/MessageView.js +++ b/dev/View/User/MailBox/MessageView.js @@ -19,14 +19,15 @@ Events = require('Common/Events'), Translator = require('Common/Translator'), + Cache = require('Common/Cache'), + SettingsStore = require('Stores/User/Settings'), AccountStore = require('Stores/User/Account'), FolderStore = require('Stores/User/Folder'), + MessageStore = require('Stores/User/Message'), Local = require('Storage/Client'), - Cache = require('Storage/User/Cache'), - Data = require('Storage/User/Data'), - Remote = require('Storage/User/Remote'), + Remote = require('Remote/User/Ajax'), kn = require('Knoin/Knoin'), AbstractView = require('Knoin/AbstractView') @@ -56,23 +57,23 @@ this.pswp = null; - this.message = Data.message; - this.currentMessage = Data.currentMessage; - this.messageListChecked = Data.messageListChecked; - this.hasCheckedMessages = Data.hasCheckedMessages; - this.messageListCheckedOrSelectedUidsWithSubMails = Data.messageListCheckedOrSelectedUidsWithSubMails; - this.messageLoading = Data.messageLoading; - this.messageLoadingThrottle = Data.messageLoadingThrottle; - this.messagesBodiesDom = Data.messagesBodiesDom; + this.message = MessageStore.message; + this.currentMessage = MessageStore.currentMessage; + this.messageListChecked = MessageStore.messageListChecked; + this.hasCheckedMessages = MessageStore.hasCheckedMessages; + this.messageListCheckedOrSelectedUidsWithSubMails = MessageStore.messageListCheckedOrSelectedUidsWithSubMails; + this.messageLoading = MessageStore.messageLoading; + this.messageLoadingThrottle = MessageStore.messageLoadingThrottle; + this.messagesBodiesDom = MessageStore.messagesBodiesDom; this.useThreads = SettingsStore.useThreads; this.replySameFolder = SettingsStore.replySameFolder; this.layout = SettingsStore.layout; this.usePreviewPane = SettingsStore.usePreviewPane; - this.isMessageSelected = Data.isMessageSelected; - this.messageActiveDom = Data.messageActiveDom; - this.messageError = Data.messageError; + this.isMessageSelected = MessageStore.isMessageSelected; + this.messageActiveDom = MessageStore.messageActiveDom; + this.messageError = MessageStore.messageError; - this.fullScreenMode = Data.messageFullScreenMode; + this.fullScreenMode = MessageStore.messageFullScreenMode; this.lastReplyAction_ = ko.observable(''); this.lastReplyAction = ko.computed({ @@ -113,7 +114,7 @@ // commands this.closeMessage = Utils.createCommand(this, function () { - Data.message(null); + MessageStore.message(null); }); this.replyCommand = createCommandHelper(Enums.ComposeType.Reply); @@ -141,7 +142,7 @@ if (this.message()) { require('App/User').deleteMessagesFromFolder(Enums.FolderType.Trash, - Data.currentFolderFullNameRaw(), + FolderStore.currentFolderFullNameRaw(), [this.message().uid], false); } }, this.messageVisibility); @@ -395,7 +396,7 @@ */ MessageViewMailBoxUserView.prototype.replyOrforward = function (sType) { - kn.showScreenPopup(require('View/Popup/Compose'), [sType, Data.message()]); + kn.showScreenPopup(require('View/Popup/Compose'), [sType, MessageStore.message()]); }; MessageViewMailBoxUserView.prototype.onBuild = function (oDom) @@ -619,7 +620,7 @@ // reply key('r', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () { - if (Data.message()) + if (MessageStore.message()) { self.replyCommand(); return false; @@ -628,7 +629,7 @@ // replaAll key('a', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () { - if (Data.message()) + if (MessageStore.message()) { self.replyAllCommand(); return false; @@ -637,7 +638,7 @@ // forward key('f', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () { - if (Data.message()) + if (MessageStore.message()) { self.forwardCommand(); return false; @@ -646,7 +647,7 @@ // message information // key('i', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () { - // if (oData.message()) + // if (MessageStore.message()) // { // self.showFullInfo(!self.showFullInfo()); // return false; @@ -655,9 +656,9 @@ // toggle message blockquotes key('b', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () { - if (Data.message() && Data.message().body) + if (MessageStore.message() && MessageStore.message().body) { - Data.message().body.find('.rlBlockquoteSwitcher').click(); + MessageStore.message().body.find('.rlBlockquoteSwitcher').click(); return false; } }); @@ -731,7 +732,7 @@ */ MessageViewMailBoxUserView.prototype.isDraftFolder = function () { - return Data.message() && FolderStore.draftFolder() === Data.message().folderFullNameRaw; + return MessageStore.message() && FolderStore.draftFolder() === MessageStore.message().folderFullNameRaw; }; /** @@ -739,7 +740,7 @@ */ MessageViewMailBoxUserView.prototype.isSentFolder = function () { - return Data.message() && FolderStore.sentFolder() === Data.message().folderFullNameRaw; + return MessageStore.message() && FolderStore.sentFolder() === MessageStore.message().folderFullNameRaw; }; /** @@ -747,7 +748,7 @@ */ MessageViewMailBoxUserView.prototype.isSpamFolder = function () { - return Data.message() && FolderStore.spamFolder() === Data.message().folderFullNameRaw; + return MessageStore.message() && FolderStore.spamFolder() === MessageStore.message().folderFullNameRaw; }; /** @@ -755,7 +756,7 @@ */ MessageViewMailBoxUserView.prototype.isSpamDisabled = function () { - return Data.message() && FolderStore.spamFolder() === Consts.Values.UnuseOptionValue; + return MessageStore.message() && FolderStore.spamFolder() === Consts.Values.UnuseOptionValue; }; /** @@ -763,7 +764,7 @@ */ MessageViewMailBoxUserView.prototype.isArchiveFolder = function () { - return Data.message() && FolderStore.archiveFolder() === Data.message().folderFullNameRaw; + return MessageStore.message() && FolderStore.archiveFolder() === MessageStore.message().folderFullNameRaw; }; /** @@ -771,7 +772,7 @@ */ MessageViewMailBoxUserView.prototype.isArchiveDisabled = function () { - return Data.message() && FolderStore.archiveFolder() === Consts.Values.UnuseOptionValue; + return MessageStore.message() && FolderStore.archiveFolder() === Consts.Values.UnuseOptionValue; }; /** @@ -789,9 +790,9 @@ MessageViewMailBoxUserView.prototype.editMessage = function () { - if (Data.message()) + if (MessageStore.message()) { - kn.showScreenPopup(require('View/Popup/Compose'), [Enums.ComposeType.Draft, Data.message()]); + kn.showScreenPopup(require('View/Popup/Compose'), [Enums.ComposeType.Draft, MessageStore.message()]); } }; diff --git a/dev/View/User/Settings/Menu.js b/dev/View/User/Settings/Menu.js index aeac72aa7..e642fdeb2 100644 --- a/dev/View/User/Settings/Menu.js +++ b/dev/View/User/Settings/Menu.js @@ -11,7 +11,7 @@ Globals = require('Common/Globals'), Links = require('Common/Links'), - Cache = require('Storage/User/Cache'), + Cache = require('Common/Cache'), kn = require('Knoin/Knoin'), AbstractView = require('Knoin/AbstractView') diff --git a/dev/View/User/Settings/Pane.js b/dev/View/User/Settings/Pane.js index 129710a83..dff7f0fe3 100644 --- a/dev/View/User/Settings/Pane.js +++ b/dev/View/User/Settings/Pane.js @@ -6,11 +6,6 @@ var _ = require('_'), - Links = require('Common/Links'), - - Data = require('Storage/User/Data'), - Cache = require('Storage/User/Cache'), - kn = require('Knoin/Knoin'), AbstractView = require('Knoin/AbstractView') ; @@ -31,12 +26,13 @@ PaneSettingsUserView.prototype.onShow = function () { - Data.message(null); + require('Stores/User/Message').message(null); }; PaneSettingsUserView.prototype.backToMailBoxClick = function () { - kn.setHash(Links.inbox(Cache.getFolderInboxName())); + kn.setHash(require('Common/Links').inbox( + require('Common/Cache').getFolderInboxName())); }; module.exports = PaneSettingsUserView; diff --git a/gulpfile.js b/gulpfile.js index 86c1507d3..ff5587109 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -160,7 +160,7 @@ cfg.paths.js = { 'vendors/routes/signals.min.js', 'vendors/routes/hasher.min.js', 'vendors/routes/crossroads.min.js', - 'vendors/knockout/knockout-3.2.0.js', + 'vendors/knockout/knockout-3.3.0.js', // 'vendors/knockout-punches/knockout.punches.min.js', 'vendors/knockout-projections/knockout-projections-1.0.0.min.js', 'vendors/knockout-sortable/knockout-sortable.min.js', diff --git a/package.json b/package.json index f318da47c..57485768b 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "RainLoop", "title": "RainLoop Webmail", "version": "1.8.1", - "release": "266", + "release": "267", "description": "Simple, modern & fast web-based email client", "homepage": "http://rainloop.net", "main": "gulpfile.js", diff --git a/rainloop/v/0.0.0/app/libraries/MailSo/Smtp/SmtpClient.php b/rainloop/v/0.0.0/app/libraries/MailSo/Smtp/SmtpClient.php index 0758c0079..846f5df1a 100644 --- a/rainloop/v/0.0.0/app/libraries/MailSo/Smtp/SmtpClient.php +++ b/rainloop/v/0.0.0/app/libraries/MailSo/Smtp/SmtpClient.php @@ -306,13 +306,14 @@ class SmtpClient extends \MailSo\Net\NetClient /** * @param string $sFrom * @param string $sSizeIfSupported = '' + * @param bool $bDsn = false * * @return \MailSo\Smtp\SmtpClient * * @throws \MailSo\Net\Exceptions\Exception * @throws \MailSo\Smtp\Exceptions\Exception */ - public function MailFrom($sFrom, $sSizeIfSupported = '') + public function MailFrom($sFrom, $sSizeIfSupported = '', $bDsn = false) { $sFrom = \MailSo\Base\Utils::IdnToAscii($sFrom, true); $sCmd = 'FROM:<'.$sFrom.'>'; @@ -323,6 +324,11 @@ class SmtpClient extends \MailSo\Net\NetClient $sCmd .= ' SIZE='.$sSizeIfSupported; } + if ($bDsn && $this->IsSupported('DSN')) + { + $sCmd .= ' RET=HDRS'; + } + $this->sendRequestWithCheck('MAIL', 250, $sCmd); $this->bMail = true; @@ -334,13 +340,14 @@ class SmtpClient extends \MailSo\Net\NetClient /** * @param string $sTo + * @param bool $bDsn = false * * @return \MailSo\Smtp\SmtpClient * * @throws \MailSo\Net\Exceptions\Exception * @throws \MailSo\Smtp\Exceptions\Exception */ - public function Rcpt($sTo) + public function Rcpt($sTo, $bDsn = false) { if (!$this->bMail) { @@ -350,7 +357,14 @@ class SmtpClient extends \MailSo\Net\NetClient } $sTo = \MailSo\Base\Utils::IdnToAscii($sTo, true); - $this->sendRequestWithCheck('RCPT', array(250, 251), 'TO:<'.$sTo.'>'); + $sCmd = 'TO:<'.$sTo.'>'; + + if ($bDsn && $this->IsSupported('DSN')) + { + $sCmd .= ' NOTIFY=SUCCESS,FAILURE'; + } + + $this->sendRequestWithCheck('RCPT', array(250, 251), $sCmd); $this->bRcpt = true; diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php index 532e4b534..ea52cd200 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php @@ -5752,12 +5752,14 @@ class Actions * @param \RainLoop\Model\Account $oAccount * @param \MailSo\Mime\Message $oMessage * @param resource $rMessageStream + * @param bool $bDsn = false * @param bool $bAddHiddenRcpt = true * * @throws \RainLoop\Exceptions\ClientException * @throws \MailSo\Net\Exceptions\ConnectionException */ - private function smtpSendMessage($oAccount, $oMessage, &$rMessageStream, &$iMessageStreamSize, $bAddHiddenRcpt = true) + private function smtpSendMessage($oAccount, $oMessage, + &$rMessageStream, &$iMessageStreamSize, $bDsn = false, $bAddHiddenRcpt = true) { $oRcpt = $oMessage->GetRcpt(); if ($oRcpt && 0 < $oRcpt->Count()) @@ -5773,9 +5775,9 @@ class Actions $sFrom = $oFrom instanceof \MailSo\Mime\Email ? $oFrom->GetEmail() : ''; $sFrom = empty($sFrom) ? $oAccount->Email() : $sFrom; - $aHiddenRcpt = array(); $this->Plugins()->RunHook('filter.smtp-from', array($oAccount, $oMessage, &$sFrom)); + $aHiddenRcpt = array(); if ($bAddHiddenRcpt) { $this->Plugins()->RunHook('filter.smtp-hidden-rcpt', array($oAccount, $oMessage, &$aHiddenRcpt)); @@ -5806,9 +5808,9 @@ class Actions list($sMailHeaders, $sMailBody) = \explode("\r\n\r\n", $sRawBody, 2); unset($sRawBody); - $this->Logger()->WriteDump(array( - $sMailTo, $sMailSubject, $sMailBody, $sMailHeaders - )); +// $this->Logger()->WriteDump(array( +// $sMailTo, $sMailSubject, $sMailBody, $sMailHeaders +// )); if (!\mail($sMailTo, $sMailSubject, $sMailBody, $sMailHeaders/*, '-f'.$oFrom->GetEmail()*/)) { @@ -5826,13 +5828,13 @@ class Actions { if (!empty($sFrom)) { - $oSmtpClient->MailFrom($sFrom); + $oSmtpClient->MailFrom($sFrom, '', $bDsn); } $aRcpt =& $oRcpt->GetAsArray(); foreach ($aRcpt as /* @var $oEmail \MailSo\Mime\Email */ $oEmail) { - $oSmtpClient->Rcpt($oEmail->GetEmail()); + $oSmtpClient->Rcpt($oEmail->GetEmail(), $bDsn); } if ($bAddHiddenRcpt && \is_array($aHiddenRcpt) && 0 < \count($aHiddenRcpt)) @@ -5902,6 +5904,7 @@ class Actions $sDraftUid = $this->GetActionParam('MessageUid', ''); $sSentFolder = $this->GetActionParam('SentFolder', ''); $aDraftInfo = $this->GetActionParam('DraftInfo', null); + $bDsn = '1' === (string) $this->GetActionParam('Dsn', '0'); $oMessage = $this->buildMessage($oAccount, false); @@ -5922,7 +5925,7 @@ class Actions if (false !== $iMessageStreamSize) { - $this->smtpSendMessage($oAccount, $oMessage, $rMessageStream, $iMessageStreamSize); + $this->smtpSendMessage($oAccount, $oMessage, $rMessageStream, $iMessageStreamSize, $bDsn, true); $this->deleteMessageAttachmnets($oAccount); @@ -6096,7 +6099,7 @@ class Actions if (false !== $iMessageStreamSize) { - $this->smtpSendMessage($oAccount, $oMessage, $rMessageStream, $iMessageStreamSize); + $this->smtpSendMessage($oAccount, $oMessage, $rMessageStream, $iMessageStreamSize, false, false); if (\is_resource($rMessageStream)) { diff --git a/rainloop/v/0.0.0/app/templates/Views/User/MailMessageView.html b/rainloop/v/0.0.0/app/templates/Views/User/MailMessageView.html index 98bdb2f20..a7ce09233 100644 --- a/rainloop/v/0.0.0/app/templates/Views/User/MailMessageView.html +++ b/rainloop/v/0.0.0/app/templates/Views/User/MailMessageView.html @@ -182,7 +182,7 @@ - + diff --git a/rainloop/v/0.0.0/app/templates/Views/User/PopupsCompose.html b/rainloop/v/0.0.0/app/templates/Views/User/PopupsCompose.html index 60318b591..d314406e7 100644 --- a/rainloop/v/0.0.0/app/templates/Views/User/PopupsCompose.html +++ b/rainloop/v/0.0.0/app/templates/Views/User/PopupsCompose.html @@ -60,6 +60,13 @@ +
  • + + +    + + +
  • @@ -192,7 +199,7 @@ -
    +
      @@ -204,7 +211,7 @@
      + data-bind="visible: !attachmentsPlace(), initDom: composeEditorArea, initResizeTrigger: [resizer(), 200, 40]">
      diff --git a/rainloop/v/0.0.0/app/templates/Views/User/SettingsFilters.html b/rainloop/v/0.0.0/app/templates/Views/User/SettingsFilters.html index 03c72b1d6..967d1563d 100644 --- a/rainloop/v/0.0.0/app/templates/Views/User/SettingsFilters.html +++ b/rainloop/v/0.0.0/app/templates/Views/User/SettingsFilters.html @@ -7,7 +7,7 @@
      -
      + -
      +
      diff --git a/rainloop/v/0.0.0/langs/bg.ini b/rainloop/v/0.0.0/langs/bg.ini index 420eb4f19..1cb63c361 100644 --- a/rainloop/v/0.0.0/langs/bg.ini +++ b/rainloop/v/0.0.0/langs/bg.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Все още не са качени всичк BUTTON_REQUEST_READ_RECEIPT = "Поискайте разписка за прочитане на съобщението" BUTTON_MARK_AS_IMPORTANT = "Mark as important" BUTTON_OPEN_PGP = "OpenPGP (Plain Text Only)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Да" diff --git a/rainloop/v/0.0.0/langs/cs.ini b/rainloop/v/0.0.0/langs/cs.ini index b1f86ddff..8347ca547 100644 --- a/rainloop/v/0.0.0/langs/cs.ini +++ b/rainloop/v/0.0.0/langs/cs.ini @@ -232,6 +232,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Některé přílohy ještě nebyly nahrány" BUTTON_REQUEST_READ_RECEIPT = "Vyžádat si potvrzení o příjetí" BUTTON_MARK_AS_IMPORTANT = "Označit jako důležité" BUTTON_OPEN_PGP = "OpenPGP (jen Plain Text)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Ano" diff --git a/rainloop/v/0.0.0/langs/de.ini b/rainloop/v/0.0.0/langs/de.ini index 86d563024..5c3612c64 100644 --- a/rainloop/v/0.0.0/langs/de.ini +++ b/rainloop/v/0.0.0/langs/de.ini @@ -5,7 +5,7 @@ LABEL_LOGIN = "Login" LABEL_PASSWORD = "Passwort" LABEL_SIGN_ME = "Anmeldung merken" LABEL_VERIFICATION_CODE = "Verifizierungscode" -LABEL_DONT_ASK_VERIFICATION_CODE = "Für 2 Wochen nicht nach dem Code fragen" +LABEL_DONT_ASK_VERIFICATION_CODE = "Für zwei Wochen nicht nach dem Code fragen" BUTTON_SIGN_IN = "Anmelden" TITLE_SIGN_IN_GOOGLE = "Mit Google anmelden" TITLE_SIGN_IN_FACEBOOK = "Mit Facebook anmelden" @@ -45,7 +45,7 @@ FULLSCREEN = "Vollbild umschalten" ZOOM = "Herein-/Herauszoomen" CLOSE = "Schließen (Esc)" LOADING = "Wird geladen ..." -GALLERY_PREV = "Vorher (Linke Pfeil-Taste)" +GALLERY_PREV = "Zurück (Linke Pfeil-Taste)" GALLERY_NEXT = "Weiter (Rechte Pfeil-Taste)" GALLERY_COUNTER = "%curr% von %total%" IMAGE_ERROR = "Die Grafikdatei konnte nicht geladen werden." @@ -62,7 +62,7 @@ TRASH_NAME = "Papierkorb" ARCHIVE_NAME = "Archiv" [QUOTA] -TITLE = "Speicherplatz-Verbrauch" +TITLE = "Speicherplatz-Nutzung" [MESSAGE_LIST] BUTTON_RELOAD = "Nachrichtenliste neu laden" @@ -119,7 +119,7 @@ BUTTON_NOTIFY_READ_RECEIPT = "Der Absender hat darum gebeten, benachrichtigt zu BUTTON_IN_NEW_WINDOW = "In neuem Fenster anzeigen" MENU_HEADERS = "Kopfzeilen anzeigen" MENU_VIEW_ORIGINAL = "Original anzeigen" -MENU_DOWNLOAD_ORIGINAL = "Als .eml - Datei herunterladen" +MENU_DOWNLOAD_ORIGINAL = "Als .eml-Datei herunterladen" MENU_FILTER_SIMILAR = "Ähnliche Nachrichten" MENU_PRINT = "Drucken" EMPTY_SUBJECT_TEXT = "(Kein Betreff)" @@ -131,20 +131,20 @@ LABEL_TO = "An" LABEL_TO_SHORT = "an" LABEL_CC = "CC" LABEL_BCC = "BCC" -LABEL_REPLY_TO = "Reply-To" +LABEL_REPLY_TO = "Antwort an" PRINT_LABEL_FROM = "Von" PRINT_LABEL_TO = "An" PRINT_LABEL_CC = "CC" PRINT_LABEL_BCC = "BCC" -PRINT_LABEL_REPLY_TO = "Reply-To" +PRINT_LABEL_REPLY_TO = "Antwort an" PRINT_LABEL_DATE = "Datum" PRINT_LABEL_SUBJECT = "Betreff" PRINT_LABEL_ATTACHMENTS = "Anhänge" MESSAGE_LOADING = "Nachricht wird geladen" MESSAGE_VIEW_DESC = "Wählen Sie eine Nachricht aus der Liste aus, um sie anzuzeigen." PGP_PASSWORD_INPUT_PLACEHOLDER = "Passwort" -PGP_SIGNED_MESSAGE_DESC = "OpenPGP signierte Nachricht (Klicken, um zu überprüfen)" -PGP_ENCRYPTED_MESSAGE_DESC = "OpenPGP verschlüsselte Nachricht (Klicken, um zu entschlüsseln)" +PGP_SIGNED_MESSAGE_DESC = "OpenPGP-signierte Nachricht (klicken, um zu überprüfen)" +PGP_ENCRYPTED_MESSAGE_DESC = "OpenPGP-verschlüsselte Nachricht (klicken, um zu entschlüsseln)" [READ_RECEIPT] SUBJECT = "Empfangsbestätigung (angezeigt) - %SUBJECT%" @@ -165,7 +165,7 @@ BUTTON_UPDATE_CONTACT = "Kontakt aktualisieren" BUTTON_IMPORT = "Import (csv, vcf, vCard)" BUTTON_EXPORT_VCARD = "Export (vcf, vCard)" BUTTON_EXPORT_CSV = "Export (csv)" -ERROR_IMPORT_FILE = "Import-Fehler (ungültiges Dateiformat)" +ERROR_IMPORT_FILE = "Importfehler (ungültiges Dateiformat)" LIST_LOADING = "Kontakte werden geladen" EMPTY_LIST = "Keine Kontakte" EMPTY_SEARCH = "Keine Kontakte gefunden" @@ -212,7 +212,7 @@ BUTTON_DELETE = "Löschen" BUTTON_CANCEL = "Abbrechen" BUTTON_MINIMIZE = "Minimieren" SAVED_TIME = "Gespeichert um %TIME%" -SAVED_ERROR_ON_SEND = "Die Nachricht wurde gesendet, konnte aber nicht im Ordner gespeichert werden." +SAVED_ERROR_ON_SEND = "Die Nachricht wurde gesendet, konnte aber nicht im Gesendet-Ordner gespeichert werden." DISCARD_UNSAVED_DATA = "Nicht gespeicherte Daten löschen?" ATTACH_FILES = "Dateien anhängen" ATTACH_DROP_FILES_DESC = "Fügen Sie hier Dateien ein" @@ -227,12 +227,13 @@ FORWARD_MESSAGE_TOP_CC = "CC" FORWARD_MESSAGE_TOP_SENT = "Gesendet" FORWARD_MESSAGE_TOP_SUBJECT = "Betreff" EMPTY_TO_ERROR_DESC = "Geben Sie bitte mindestens einen Empfänger an" -NO_ATTACHMENTS_HERE_DESC = "No attachments here." +NO_ATTACHMENTS_HERE_DESC = "Keine Anhänge vorhanden." ATTACHMENTS_ERROR_DESC = "Warnung! Nicht alle Anhänge wurden hochgeladen." ATTACHMENTS_UPLOAD_ERROR_DESC = "Es wurden noch nicht alle Anhänge hochgeladen." BUTTON_REQUEST_READ_RECEIPT = "Empfangsbestätigung anfordern" BUTTON_MARK_AS_IMPORTANT = "Als Wichtig markieren" -BUTTON_OPEN_PGP = "OpenPGP (Nur Text)" +BUTTON_OPEN_PGP = "OpenPGP (nur bei unformatiertem Text)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Ja" @@ -257,15 +258,15 @@ BUTTON_UPDATE_IDENTITY = "Aktualisieren" LABEL_EMAIL = "E-Mail" LABEL_NAME = "Name" LABEL_REPLY_TO = "Antwort an" -LABEL_SIGNATURE = "Signature" -LABEL_CC = "Cc" +LABEL_SIGNATURE = "Signatur" +LABEL_CC = "CC" LABEL_BCC = "BCC" -LABEL_SIGNATURE_INSERT_BEFORE = "Insert this signature before quoted text in replies" +LABEL_SIGNATURE_INSERT_BEFORE = "Diese Signatur in Antworten vor dem zitierten Text einfügen" [POPUPS_CREATE_FOLDER] TITLE_CREATE_FOLDER = "Ordner anlegen?" SELECT_NO_PARENT = "" -LABEL_NAME = "Ordner-Name" +LABEL_NAME = "Ordnername" LABEL_PARENT = "Übergeordneter Ordner" BUTTON_CREATE = "Anlegen" BUTTON_CANCEL = "Abbrechen" @@ -283,16 +284,16 @@ DANGER_DESC_HTML_2 = "Einmal begonnen, kann dieser Vorgang nicht mehr abgebroche TITLE_CLEARING_PROCESS = "Ordner wird gelöscht ..." [POPUPS_IMPORT_OPEN_PGP_KEY] -TITLE_IMPORT_OPEN_PGP_KEY = "Import OpenPGP Schlüssel" -BUTTON_IMPORT_OPEN_PGP_KEY = "Import" +TITLE_IMPORT_OPEN_PGP_KEY = "OpenPGP-Schlüssel importieren" +BUTTON_IMPORT_OPEN_PGP_KEY = "Importieren" [POPUPS_VIEW_OPEN_PGP_KEY] -TITLE_VIEW_OPEN_PGP_KEY = "OpenPGP Schlüssel anzeigen" +TITLE_VIEW_OPEN_PGP_KEY = "OpenPGP-Schlüssel anzeigen" BUTTON_SELECT = "Auswählen" BUTTON_CLOSE = "Schließen" [POPUPS_GENERATE_OPEN_PGP_KEYS] -TITLE_GENERATE_OPEN_PGP_KEYS = "OpenPGP Schlüssel generieren" +TITLE_GENERATE_OPEN_PGP_KEYS = "OpenPGP-Schlüssel generieren" LABEL_EMAIL = "E-Mail" LABEL_NAME = "Name" LABEL_PASSWORD = "Passwort" @@ -309,7 +310,7 @@ BUTTON_ENCRYPT = "Verschlüsseln" BUTTON_SIGN_AND_ENCRYPT = "Unterschreiben und verschlüsseln" [POPUPS_TWO_FACTOR_TEST] -TITLE_TEST_CODE = "Zwei-Faktor-Autehntifizierung" +TITLE_TEST_CODE = "Zwei-Faktor-Authentifizierung" LABEL_CODE = "Code" BUTTON_TEST = "Testen" @@ -330,7 +331,7 @@ SELECT_ACTION_DISCARD = "Verwerfen" SELECT_FIELD_FROM = "Von" SELECT_FIELD_RECIPIENTS = "Empfänger (An oder CC)" SELECT_FIELD_SUBJECT = "Betreff" -SELECT_FIELD_HEADER = "Header" +SELECT_FIELD_HEADER = "Nachrichtenkopf" SELECT_FIELD_SIZE = "Größe" SELECT_TYPE_CONTAINS = "Enthält" SELECT_TYPE_NOT_CONTAINS = "Enthält nicht" @@ -350,10 +351,10 @@ EMAIL_LABEL = "E-Mail" VACATION_SUBJECT_LABEL = "Betreff (optional)" VACATION_MESSAGE_LABEL = "Nachricht" REJECT_MESSAGE_LABEL = "Ablehnnachricht" -ALL_INCOMING_MESSAGES_DESC = "Alle ankommende E-Mails" +ALL_INCOMING_MESSAGES_DESC = "Alle eingehenden Nachrichten" [POPUPS_SYSTEM_FOLDERS] -TITLE_SYSTEM_FOLDERS = "Wählen Sie den System-Ordner aus" +TITLE_SYSTEM_FOLDERS = "Wählen Sie die Systemordner aus" SELECT_CHOOSE_ONE = "Wählen Sie einen aus" SELECT_UNUSE_NAME = "Nicht anwenden" LABEL_SENT = "Gesendet" @@ -363,29 +364,29 @@ LABEL_TRASH = "Papierkorb" LABEL_ARCHIVE = "Archiv" BUTTON_CANCEL = "Abbrechen" BUTTON_CLOSE = "Schließen" -NOTIFICATION_SENT = "Sie haben keinen \"Gesendet\" System-Ordner gewählt, in dem Nachrichten nach dem Versenden gespeichert werden. +NOTIFICATION_SENT = "Sie haben keinen \"Gesendet\"-Systemordner gewählt, in dem Nachrichten nach dem Versenden gespeichert werden. Falls Sie versandte Nachrichten nicht speichern möchten, wählen Sie die Option \"Nicht anwenden\"." -NOTIFICATION_DRAFTS = "Sie haben keinen \"Entwürfe\" System-Ordner, in dem Nachrichten beim Erstellen gespeichert werden, gewählt." -NOTIFICATION_SPAM = "Sie haben keinen \"Spam\" System-Ordner gewählt, in dem die Spam-Nachrichten landen. -Falls Sie diese Nachrichten endgültig löschen möchten, wählen Sie die Option \"Nicht anwenden\"." -NOTIFICATION_TRASH = "Sie haben keinen \"Papierkorb\" System-Ordner gewählt, in dem die gelöschten Nachrichten abgelegt werden. +NOTIFICATION_DRAFTS = "Sie haben keinen \"Entwürfe\"-Systemordner gewählt, in dem Nachrichten beim Erstellen gespeichert werden." +NOTIFICATION_SPAM = "Sie haben keinen \"Spam\"-Systemordner gewählt, in dem die Spam-Nachrichten abgelegt werden. +Falls Sie Spam-Nachrichten endgültig löschen möchten, wählen Sie die Option \"Nicht anwenden\"." +NOTIFICATION_TRASH = "Sie haben keinen \"Papierkorb\"-Systemordner gewählt, in dem die gelöschten Nachrichten abgelegt werden. Falls Sie gelöschte Nachrichten endgültig löschen möchten, wählen Sie die Option \"Nicht anwenden\"." -NOTIFICATION_ARCHIVE = "Sie haben keinen \"Archiv\" System-Ordner gewählt, in dem die archivierten Nachrichten landen." +NOTIFICATION_ARCHIVE = "Sie haben keinen \"Archiv\"-Systemordner gewählt, in dem die archivierten Nachrichten abgelegt werden." [TITLES] LOADING = "Wird geladen" -LOGIN = "Login" +LOGIN = "Anmeldung" MAILBOX = "Postfach" SETTINGS = "Einstellungen" COMPOSE = "Erstellen" [UPLOAD] ERROR_FILE_IS_TOO_BIG = "Datei ist zu groß" -ERROR_FILE_PARTIALLY_UPLOADED = "Die Datei wurde aus einem nicht bekannten Grund unvollständig hochgeladen." +ERROR_FILE_PARTIALLY_UPLOADED = "Die Datei wurde aus einem unbekannten Grund unvollständig hochgeladen." ERROR_NO_FILE_UPLOADED = "Keine Datei hochgeladen" ERROR_MISSING_TEMP_FOLDER = "Die temporäre Datei fehlt" -ERROR_ON_SAVING_FILE = "Ein unbekannter Fehler trat beim Speichern auf" -ERROR_FILE_TYPE = "Ungültiger Datei-Typ" +ERROR_ON_SAVING_FILE = "Ein unbekannter Fehler trat beim Hochladen auf" +ERROR_FILE_TYPE = "Ungültiger Dateityp" ERROR_UNKNOWN = "Ein unbekannter Fehler trat beim Hochladen auf" [EDITOR] @@ -401,11 +402,11 @@ LABEL_FOLDERS_NAME = "Ordner" LABEL_ACCOUNTS_NAME = "Konten" LABEL_IDENTITY_NAME = "Identität" LABEL_IDENTITIES_NAME = "Identitäten" -LABEL_FILTERS_NAME = "Filters" -LABEL_TEMPLATES_NAME = "Templates" +LABEL_FILTERS_NAME = "Filter" +LABEL_TEMPLATES_NAME = "Vorlagen" LABEL_SECURITY_NAME = "Sicherheit" -LABEL_SOCIAL_NAME = "Sozial" -LABEL_THEMES_NAME = "Vorlagen" +LABEL_SOCIAL_NAME = "Social" +LABEL_THEMES_NAME = "Themen" LABEL_CHANGE_PASSWORD_NAME = "Passwort" LABEL_OPEN_PGP_NAME = "OpenPGP" BUTTON_BACK = "Zurück" @@ -415,7 +416,7 @@ LEGEND_FILTERS = "Filter" BUTTON_SAVE = "Speichern" BUTTON_ADD_FILTER = "Filter hinzufügen" BUTTON_DELETE = "Löschen" -BUTTON_RAW_SCRIPT = "Benutzerdefiniertes Script verwenden" +BUTTON_RAW_SCRIPT = "Benutzerdefiniertes Skript verwenden" SUBNAME_NONE = "Keine" SUBNAME_MOVE_TO = "Verschieben nach \"%FOLDER%\"" SUBNAME_FORWARD_TO = "Weiterleiten nach \"%EMAIL%\"" @@ -435,16 +436,16 @@ LABEL_SIGNATURE = "Signatur" LABEL_ADD_SIGNATURE_TO_ALL = "Signatur zu allen ausgehenden Nachrichten hinzufügen" [SETTINGS_SECURITY] -LEGEND_SECURITY = "Security" -LEGEND_TWO_FACTOR_AUTH = "2-Faktor-Authentifizierung" -LABEL_ENABLE_TWO_FACTOR = "2-Faktor-Authentifizierung aktivieren" +LEGEND_SECURITY = "Sicherheit" +LEGEND_TWO_FACTOR_AUTH = "Zwei-Faktor-Authentifizierung" +LABEL_ENABLE_TWO_FACTOR = "Zwei-Faktor-Authentifizierung aktivieren" LABEL_TWO_FACTOR_USER = "Benutzer" LABEL_TWO_FACTOR_STATUS = "Status" LABEL_TWO_FACTOR_SECRET = "Secret" LABEL_TWO_FACTOR_BACKUP_CODES = "Backup-Codes" -LABEL_AUTOLOGOUT = "Auto Logout" -AUTOLOGIN_NEVER_OPTION_NAME = "Never" -AUTOLOGIN_MINUTES_OPTION_NAME = "%MINUTES% minute(s)" +LABEL_AUTOLOGOUT = "Automatische Abmeldung" +AUTOLOGIN_NEVER_OPTION_NAME = "Nie" +AUTOLOGIN_MINUTES_OPTION_NAME = "%MINUTES% Minute(n)" BUTTON_CREATE = "Neuen Secret erstellen" BUTTON_CLEAR = "Zurücksetzen" BUTTON_TEST = "Testen" @@ -452,9 +453,9 @@ BUTTON_SHOW_SECRET = "Secret anzeigen" BUTTON_HIDE_SECRET = "Secret verbergen" TWO_FACTOR_SECRET_CONFIGURED_DESC = "Konfiguriert" TWO_FACTOR_SECRET_NOT_CONFIGURED_DESC = "Nicht konfiguriert" -TWO_FACTOR_SECRET_DESC = "Importieren Sie diese Informationen in Ihren Google Authenticator-Client (oder andere TOTP-Clienten) mit Hilfe des mitgelieferten QR-Code unten oder durch manuelle Eingabe des Codes." +TWO_FACTOR_SECRET_DESC = "Importieren Sie diese Informationen in Ihren Google-Authenticator-Client (oder andere TOTP-Clients) mit Hilfe des mitgelieferten QR-Codes unten oder durch manuelle Eingabe des Codes." TWO_FACTOR_BACKUP_CODES_DESC = "Wenn Sie keine Codes via Google Authenticator erhalten können, können Sie Backup-Codes für die Anmeldung verwenden. Nachdem Sie einen Backup-Code verwendet haben, um sich anzumelden, wird dieser inaktiv." -TWO_FACTOR_SECRET_TEST_BEFORE_DESC = "You can't change this setting before test." +TWO_FACTOR_SECRET_TEST_BEFORE_DESC = "Sie können diese Einstellung nicht vor einer Prüfung ändern." [SETTINGS_GENERAL] LEGEND_GENERAL = "Allgemein" @@ -463,19 +464,19 @@ LABEL_LAYOUT = "Layout" LABEL_LAYOUT_NO_SPLIT = "Keine Aufteilung" LABEL_LAYOUT_VERTICAL_SPLIT = "Vertikale Aufteilung" LABEL_LAYOUT_HORIZONTAL_SPLIT = "Horizontale Aufteilung" -LABEL_EDITOR = "Standard-Text-Editor" +LABEL_EDITOR = "Standard-Texteditor" LABEL_EDITOR_HTML = "HTML" -LABEL_EDITOR_PLAIN = "Text" +LABEL_EDITOR_PLAIN = "Unformatierter Text" LABEL_EDITOR_HTML_FORCED = "HTML (erzwungen)" -LABEL_EDITOR_PLAIN_FORCED = "Text (erzwungen)" +LABEL_EDITOR_PLAIN_FORCED = "Unformatierter Text (erzwungen)" LABEL_ANIMATION = "Interface-Animation" LABEL_ANIMATION_FULL = "Komplett" LABEL_ANIMATION_NORMAL = "Normal" LABEL_ANIMATION_NONE = "Keine" LABEL_VIEW_OPTIONS = "Optionen anzeigen" -LABEL_USE_PREVIEW_PANE = "Vorschau-Fenster nutzen" +LABEL_USE_PREVIEW_PANE = "Vorschaufenster nutzen" LABEL_USE_CHECKBOXES_IN_LIST = "Kontrollkästchen in der Liste anzeigen" -LABEL_USE_THREADS = "Thread-förmig anzeigen" +LABEL_USE_THREADS = "Als Unterhaltungen anzeigen" LABEL_REPLY_SAME_FOLDER = "Antworten im gleichen Ordner wie die Nachricht, auf die geantwortet wurde, abspeichern" LABEL_SHOW_IMAGES = "In der Nachricht enthaltene Bilder immer anzeigen" LABEL_SHOW_ANIMATION = "Animation anzeigen" @@ -487,65 +488,65 @@ LABEL_CHROME_NOTIFICATION_DESC_DENIED = "(Vom Browser blockiert.)" [SETTINGS_CONTACTS] LEGEND_CONTACTS = "Kontakte" -LABEL_CONTACTS_AUTOSAVE = "Automatisch Empfänger zu Ihrem Adressbuch hinzuzufügen" +LABEL_CONTACTS_AUTOSAVE = "Empfänger automatisch zu Ihrem Adressbuch hinzuzufügen" LEGEND_CONTACTS_SYNC = "Remote-Synchronisierung (CardDAV)" LABEL_CONTACTS_SYNC_ENABLE = "Remote-Synchronisierung aktivieren" LABEL_CONTACTS_SYNC_SERVER = "Server" -LABEL_CONTACTS_SYNC_AB_URL = "Adressbuch URL" +LABEL_CONTACTS_SYNC_AB_URL = "Adressbuch-URL" LABEL_CONTACTS_SYNC_USER = "Benutzer" LABEL_CONTACTS_SYNC_PASSWORD = "Passwort" [SETTINGS_THEMES] -LEGEND_THEMES = "Vorlagen" -LEGEND_THEMES_CUSTOM = "Konfiguration der selbst-definierten Vorlagen" +LEGEND_THEMES = "Themen" +LEGEND_THEMES_CUSTOM = "Konfiguration der selbsterstellten Themen" LABEL_CUSTOM_TYPE = "Typ" LABEL_CUSTOM_TYPE_LIGHT = "Hell" LABEL_CUSTOM_TYPE_DARK = "Dunkel" LABEL_CUSTOM_BACKGROUND_IMAGE = "Hintergrund" -BUTTON_UPLOAD_BACKGROUND_IMAGE = "Hintergrundvild hochladen(JPG, PNG)" +BUTTON_UPLOAD_BACKGROUND_IMAGE = "Hintergrundbild hochladen (JPG, PNG)" ERROR_FILE_IS_TOO_BIG = "Datei ist zu groß" -ERROR_FILE_TYPE_ERROR = "Ungültiger Datei-Typ! (nur JPG und PNG)" +ERROR_FILE_TYPE_ERROR = "Ungültiger Dateityp (nur JPG und PNG)" ERROR_UNKNOWN = "Ein unbekannter Fehler trat beim Hochladen auf" [SETTINGS_SOCIAL] LEGEND_GOOGLE = "Google" BUTTON_GOOGLE_CONNECT = "Mit Google verbinden" BUTTON_GOOGLE_DISCONNECT = "Von Google abmelden" -MAIN_GOOGLE_DESC = "Nach der Aktivierung der Anmeldung per Google können Sie sich hier mit dem Google-Button im Anmelde-Dialog anmelden." +MAIN_GOOGLE_DESC = "Nach der Aktivierung der Anmeldung per Google können Sie sich hier mit dem Google-Button im Anmeldedialog anmelden." LEGEND_FACEBOOK = "Facebook" BUTTON_FACEBOOK_CONNECT = "Mit Facebook verbinden" BUTTON_FACEBOOK_DISCONNECT = "Von Facebook abmelden" -MAIN_FACEBOOK_DESC = "Nach der Aktivierung der Anmeldung per Facebook können Sie sich hier mit dem Facebook-Button im Anmelde-Dialog anmelden." +MAIN_FACEBOOK_DESC = "Nach der Aktivierung der Anmeldung per Facebook können Sie sich hier mit dem Facebook-Button im Anmeldedialog anmelden." LEGEND_TWITTER = "Twitter" BUTTON_TWITTER_CONNECT = "Mit Twitter verbinden" BUTTON_TWITTER_DISCONNECT = "Von Twitter abmelden" -MAIN_TWITTER_DESC = "Nach der Aktivierung der Anmeldung per Twitter können Sie sich hier mit dem Twitter-Button im Anmelde-Dialog anmelden." +MAIN_TWITTER_DESC = "Nach der Aktivierung der Anmeldung per Twitter können Sie sich hier mit dem Twitter-Button im Anmeldedialog anmelden." [SETTINGS_FOLDERS] -LEGEND_FOLDERS = "Ordner-Liste" +LEGEND_FOLDERS = "Ordnerliste" BUTTON_CREATE = "Ordner anlegen" -BUTTON_SYSTEM = "System-Ordner wählen" +BUTTON_SYSTEM = "Systemordner wählen" BUTTON_DELETE = "Löschen" BUTTON_SUBSCRIBE = "Abonnieren" BUTTON_UNSUBSCRIBE = "Abonnement beenden" -LOADING_PROCESS = "Ordner-Liste wird geladen" +LOADING_PROCESS = "Ordnerliste wird geladen" CREATING_PROCESS = "Ordner wird angelegt" DELETING_PROCESS = "Ordner wird gelöscht" RENAMING_PROCESS = "Ordner wird umbenannt" DELETING_ASK = "Sind Sie sicher?" TO_MANY_FOLDERS_DESC_1 = "Sie haben zu viele Ordner!" -TO_MANY_FOLDERS_DESC_2 = "Wir zeigen aus Leistungsgründen nur einen Teil von ihnen." +TO_MANY_FOLDERS_DESC_2 = "Aus Leistungsgründen zeigen wir nur einen Teil davon an." [SETTINGS_ACCOUNTS] -LEGEND_ACCOUNTS = "Liste der Konten" -LEGEND_IDENTITIES = "Identities" -LEGEND_ACCOUNTS_AND_IDENTITIES = "Accounts and Identities" +LEGEND_ACCOUNTS = "Konten" +LEGEND_IDENTITIES = "Identitäten" +LEGEND_ACCOUNTS_AND_IDENTITIES = "Konten und Identitäten" BUTTON_ADD_ACCOUNT = "Konto hinzufügen" -BUTTON_ADD_IDENTITY = "Add an Identity" +BUTTON_ADD_IDENTITY = "Identität hinzufügen" BUTTON_DELETE = "Löschen" -LOADING_PROCESS = "Liste der Konten wird geladen" +LOADING_PROCESS = "Aktualisiere Kontenliste" DELETING_ASK = "Sind Sie sicher?" -DEFAULT_IDENTITY_LABEL = "default" +DEFAULT_IDENTITY_LABEL = "Standard" [SETTINGS_IDENTITIES] LEGEND_IDENTITY = "Identität" @@ -564,65 +565,65 @@ DELETING_ASK = "Sind Sie sicher?" LEGEND_CHANGE_PASSWORD = "Passwort ändern" LABEL_CURRENT_PASSWORD = "Aktuelles Passwort" LABEL_NEW_PASSWORD = "Neues Passwort" -LABEL_REPEAT_PASSWORD = "Neues Passwort wiederholen" +LABEL_REPEAT_PASSWORD = "Neues Passwort bestätigen" BUTTON_UPDATE_PASSWORD = "Neues Passwort setzen" -ERROR_PASSWORD_MISMATCH = "Passwörter stimmen nicht überein. Versuchen Sie es bitte erneut." +ERROR_PASSWORD_MISMATCH = "Passwörter stimmen nicht überein; versuchen Sie es bitte erneut" [SETTINGS_OPEN_PGP] LEGEND_OPEN_PGP = "OpenPGP" -BUTTON_ADD_OPEN_PGP_KEY = "Import OpenPGP Schlüssel" -BUTTON_GENERATE_OPEN_PGP_KEYS = "OpenPGP Schlüssel generieren" +BUTTON_ADD_OPEN_PGP_KEY = "OpenPGP-Schlüssel importieren" +BUTTON_GENERATE_OPEN_PGP_KEYS = "OpenPGP-Schlüssel generieren" TITLE_PRIVATE = "Privat" TITLE_PUBLIC = "Öffentlich" DELETING_ASK = "Sind Sie sicher?" [SHORTCUTS_HELP] -LEGEND_SHORTCUTS_HELP = "Tastaturkürzel Hilfe" +LEGEND_SHORTCUTS_HELP = "Tastaturkürzel-Hilfe" TAB_MAILBOX = "Postfach" TAB_MESSAGE_LIST = "Nachrichtenliste" TAB_MESSAGE_VIEW = "Nachrichtenansicht" TAB_COMPOSE = "Nachricht schreiben" -LABEL_OPEN_USER_DROPDOWN = "Benutzer-Auswahl öffnen" +LABEL_OPEN_USER_DROPDOWN = "Benutzerauswahl öffnen" LABEL_REPLY = "Antworten" LABEL_REPLY_ALL = "Allen Antworten" LABEL_FORWARD = "Weiterleiten" -LABEL_FORWARD_MULTIPLY = "Weiterleiten (mehrfach)" +LABEL_FORWARD_MULTIPLY = "Als Anhang/Anhänge weiterleiten" LABEL_HELP = "Hilfe" LABEL_CHECK_ALL = "Alle Nachrichten auswählen" LABEL_ARCHIVE = "Archivieren" LABEL_DELETE = "Löschen" LABEL_MOVE = "Verschieben" -LABEL_READ = "Ausgewählte Nachrichten gelesen" -LABEL_UNREAD = "Ausgewählte Nachrichten ungelesen" -LABEL_IMPORTANT = "Wichtig, Markiere ausgewählte Nachrichten" +LABEL_READ = "Ausgewählte Nachrichten als gelesen markieren" +LABEL_UNREAD = "Ausgewählte Nachrichten als ungelesen markieren" +LABEL_IMPORTANT = "Wichtig, ausgewählte Nachrichten markieren" LABEL_SEARCH = "Suchen" LABEL_CANCEL_SEARCH = "Suche abbrechen" LABEL_FULLSCREEN_ENTER = "Vollbild (Vorschaubereich-Layout)" -LABEL_VIEW_MESSAGE_ENTER = "Nachricht anzeigen (Kein Vorschaubereich-Layout)" +LABEL_VIEW_MESSAGE_ENTER = "Nachricht anzeigen (kein Vorschaubereich-Layout)" LABEL_SWITCH_TO_MESSAGE = "Fokus auf ausgewählte Nachricht schalten" -LABEL_SWITCH_TO_FOLDER_LIST = "Fokus auf Ordner-Liste schalten" +LABEL_SWITCH_TO_FOLDER_LIST = "Fokus auf Ordnerliste schalten" LABEL_FULLSCREEN_TOGGLE = "Vollbildmodus umschalten" -LABEL_BLOCKQUOTES_TOGGLE = "Nachricht-Blockzitate umschalten" +LABEL_BLOCKQUOTES_TOGGLE = "Nachrichten-Blockzitate umschalten" LABEL_PRINT = "Drucken" LABEL_EXIT_FULLSCREEN = "Vollbildmodus verlassen" -LABEL_CLOSE_MESSAGE = "Nachricht schließen (Kein Vorschaubereich-Layout)" +LABEL_CLOSE_MESSAGE = "Nachricht schließen (kein Vorschaubereich-Layout)" LABEL_SWITCH_TO_LIST = "Fokus auf Nachrichtenliste zurückschalten" -LABEL_OPEN_COMPOSE_POPUP = "Öffne Erstellen Popup" -LABEL_OPEN_IDENTITIES_DROPDOWN = "Öffne Identitätenauswahl" +LABEL_OPEN_COMPOSE_POPUP = "Erstellen-Popup öffnen" +LABEL_OPEN_IDENTITIES_DROPDOWN = "Identitätsauswahl öffnen" LABEL_SAVE_MESSAGE = "Nachricht speichern" LABEL_SEND_MESSAGE = "Nachricht senden" LABEL_CLOSE_COMPOSE = "Popup schließen" [PGP_NOTIFICATIONS] NO_PUBLIC_KEYS_FOUND = "Keine öffentlichen Schlüssel gefunden" -NO_PUBLIC_KEYS_FOUND_FOR = "Keine öffentlichen Schlüssel für E-Mail \"%EMAIL%\" gefunden" +NO_PUBLIC_KEYS_FOUND_FOR = "Keine öffentlichen Schlüssel für die E-Mail \"%EMAIL%\" gefunden" NO_PRIVATE_KEY_FOUND = "Keine privaten Schlüssel gefunden" -NO_PRIVATE_KEY_FOUND_FOR = "Keine privaten Schlüssel für E-Mail \"%EMAIL%\" gefunden" -UNVERIFIRED_SIGNATURE = "Unverifizierte Unterschrift" -DECRYPTION_ERROR = "OpenPGP Entschlüsselungsfehler" +NO_PRIVATE_KEY_FOUND_FOR = "Keine privaten Schlüssel für die E-Mail \"%EMAIL%\" gefunden" +UNVERIFIRED_SIGNATURE = "Nich verifizierte Unterschrift" +DECRYPTION_ERROR = "OpenPGP-Entschlüsselungsfehler" GOOD_SIGNATURE = "Gültige Unterschrift von %USER%" -PGP_ERROR = "OpenPGP Fehler: %ERROR%" -SPECIFY_FROM_EMAIL = "Bitte VON E-Mail-Adresse angeben" +PGP_ERROR = "OpenPGP-Fehler: %ERROR%" +SPECIFY_FROM_EMAIL = "Bitte die VON-E-Mail-Adresse angeben" SPECIFY_AT_LEAST_ONE_RECIPIENT = "Bitte geben Sie mindestens einen Empfänger an" [NOTIFICATIONS] @@ -631,26 +632,26 @@ AUTH_ERROR = "Authentifizierung fehlgeschlagen" ACCESS_ERROR = "Zugriffsfehler" CONNECTION_ERROR = "Kann nicht mit dem Server verbinden" CAPTCHA_ERROR = "Falsche CAPTCHA-Eingabe." -SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE = "Diese Social ID ist bisher mit keinem E-Mail-Konto verbunden. Melden Sie sich mit Ihren E-Mail-Daten an und aktivieren Sie dieses Feature in Ihren Konten-Einstellungen." -SOCIAL_TWITTER_LOGIN_ACCESS_DISABLE = "Diese Social ID ist bisher mit keinem E-Mail-Konto verbunden. Melden Sie sich mit Ihren E-Mail-Daten an und aktivieren Sie dieses Feature in Ihren Konten-Einstellungen." -SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE = "Diese Social ID ist bisher mit keinem E-Mail-Konto verbunden. Melden Sie sich mit Ihren E-Mail-Daten an und aktivieren Sie dieses Feature in Ihren Konten-Einstellungen." +SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE = "Diese Social-ID ist bisher mit keinem E-Mail-Konto verbunden. Melden Sie sich mit Ihren E-Mail-Anmeldedaten an und aktivieren Sie diese Funktion in Ihren Konteneinstellungen." +SOCIAL_TWITTER_LOGIN_ACCESS_DISABLE = "Diese Social-ID ist bisher mit keinem E-Mail-Konto verbunden. Melden Sie sich mit Ihren E-Mail-Anmeldedaten an und aktivieren Sie diese Funktion in Ihren Konteneinstellungen." +SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE = "Diese Social-ID ist bisher mit keinem E-Mail-Konto verbunden. Melden Sie sich mit Ihren E-Mail-Anmeldedaten an und aktivieren Sie diese Funktion in Ihren Konteneinstellungen." DOMAIN_NOT_ALLOWED = "Diese Domain ist nicht zugelassen." ACCOUNT_NOT_ALLOWED = "Konto ist nicht zugelassen." ACCOUNT_TWO_FACTOR_AUTH_REQUIRED = "Zwei-Faktor-Authentifizierung erforderlich" -ACCOUNT_TWO_FACTOR_AUTH_ERROR = "Zwei-Faktor-Authentifizierung Fehler" +ACCOUNT_TWO_FACTOR_AUTH_ERROR = "Fehler bei Zwei-Faktor-Authentifizierung" COULD_NOT_SAVE_NEW_PASSWORD = "Neues Passwort konnte nicht gespeichert werden" -CURRENT_PASSWORD_INCORRECT = "Aktuelles Passwort inkorrekt" +CURRENT_PASSWORD_INCORRECT = "Aktuelles Passwort falsch" NEW_PASSWORD_SHORT = "Passwort ist zu kurz" NEW_PASSWORD_WEAK = "Passwort ist zu einfach" -NEW_PASSWORD_FORBIDDENT = "Passwort enthält verbotene Zeichen" -CONTACTS_SYNC_ERROR = "Kontakte Synchronisationsfehler" +NEW_PASSWORD_FORBIDDENT = "Passwort enthält unzulässige Zeichen" +CONTACTS_SYNC_ERROR = "Fehler bei Kontakte-Synchronisierung" CANT_GET_MESSAGE_LIST = "Die Nachrichtenliste ist nicht verfügbar" CANT_GET_MESSAGE = "Diese Nachricht ist nicht verfügbar" CANT_DELETE_MESSAGE = "Diese Nachricht kann nicht gelöscht werden" CANT_MOVE_MESSAGE = "Diese Nachricht kann nicht verschoben werden" CANT_SAVE_MESSAGE = "Diese Nachricht kann nicht gespeichert werden" CANT_SEND_MESSAGE = "Diese Nachricht kann nicht gesendet werden" -INVALID_RECIPIENTS = "Ungültige Empfänger-Adresse" +INVALID_RECIPIENTS = "Ungültige Empfängeradressen" CANT_SAVE_FILTERS = "Die Filter können nicht gespeichert werden" CANT_GET_FILTERS = "Die Filter sind nicht verfügbar" FILTERS_ARE_NOT_CORRECT = "Die Filter sind fehlerhaft" @@ -662,19 +663,19 @@ CANT_SUBSCRIBE_FOLDER = "Dieser Ordner kann nicht abonniert werden" CANT_UNSUBSCRIBE_FOLDER = "Das Abonnement dieses Ordners kann nicht gelöscht werden" CANT_SAVE_SETTINGS = "Einstellungen können nicht gespeichert werden" CANT_SAVE_PLUGIN_SETTINGS = "Einstellungen können nicht gespeichert werden" -DOMAIN_ALREADY_EXISTS = "Diese Domain gibt es schon" -CANT_INSTALL_PACKAGE = "Package konnte nicht installiert werden" -CANT_DELETE_PACKAGE = "Package konnte nicht entfernt werden" -INVALID_PLUGIN_PACKAGE = "Plugin-Package ist ungültig" -UNSUPPORTED_PLUGIN_PACKAGE = "Plugin-Package wird nicht unterstützt" -LICENSING_SERVER_IS_UNAVAILABLE = "Abonnement-Server kann nicht erreicht werden" -LICENSING_DOMAIN_EXPIRED = "Das Abonnement dieser Domain ist ausgelaufen" -LICENSING_DOMAIN_BANNED = "Das Abonnement dieser Domain ist gesperrt." -DEMO_SEND_MESSAGE_ERROR = "Dieser Demo-Account darf aus Sicherheitsgründen keine Nachrichten an externe E-Mail-Adressen versenden!" +DOMAIN_ALREADY_EXISTS = "Diese Domain existiert bereits" +CANT_INSTALL_PACKAGE = "Paket konnte nicht installiert werden" +CANT_DELETE_PACKAGE = "Paket konnte nicht entfernt werden" +INVALID_PLUGIN_PACKAGE = "Plugin-Paket ist ungültig" +UNSUPPORTED_PLUGIN_PACKAGE = "Plugin-Paket wird nicht unterstützt" +LICENSING_SERVER_IS_UNAVAILABLE = "Subscription-Server kann nicht erreicht werden" +LICENSING_DOMAIN_EXPIRED = "Die Subscription dieser Domain ist ausgelaufen." +LICENSING_DOMAIN_BANNED = "Die Subscription dieser Domain ist gesperrt." +DEMO_SEND_MESSAGE_ERROR = "Dieses Demokonto darf aus Sicherheitsgründen keine Nachrichten an externe E-Mail-Adressen versenden!" DEMO_ACCOUNT_ERROR = "Aus Sicherheitsgründen ist dieses Konto nicht zu dieser Aktion berechtigt!" -ACCOUNT_ALREADY_EXISTS = "Dieses Konto gibt es schon." +ACCOUNT_ALREADY_EXISTS = "Dieses Konto existiert bereits" MAIL_SERVER_ERROR = "Beim Zugriff auf den E-Mail-Server trat ein Fehler auf." -INVALID_INPUT_ARGUMENT = "Fehlerhafte Eingabe" +INVALID_INPUT_ARGUMENT = "Ungültige Eingabe" UNKNOWN_ERROR = "Unbekannter Fehler" [STATIC] @@ -684,10 +685,10 @@ PHP_EXSTENSIONS_ERROR_DESC = "Notwendige PHP-Erweiterungen sind in Ihrer PHP-Kon PHP_VERSION_ERROR_DESC = "Ihre PHP Version (%VERSION%) ist älter als die notwendige Version: 5.3.0!" NO_SCRIPT_TITLE = "Diese Anwendung benötigt JavaScript." NO_SCRIPT_DESC = "Ihr Browser unterstützt JavaScript nicht. -Aktivieren Sie bitte die Javascript-Unterstützung in Ihrem Browser und versuchen Sie es noch einmal." +Aktivieren Sie bitte die JavaScript-Unterstützung in Ihrem Browser und versuchen Sie es erneut." NO_COOKIE_TITLE = "Diese Anwendung benötigt Cookies." NO_COOKIE_DESC = "Ihr Browser unterstützt Cookies nicht. -Aktivieren Sie bitte die Cookie-Unterstützung in Ihrem Browser und versuchen Sie es noch einmal." +Aktivieren Sie bitte die Cookie-Unterstützung in Ihrem Browser und versuchen Sie es erneut." BAD_BROWSER_TITLE = "Ihr Browser ist veraltet." -BAD_BROWSER_DESC = "Um alle Features dieser Anwendung nutzen zu können, -sollten Sie einen aktuellen Browser installieren!" \ No newline at end of file +BAD_BROWSER_DESC = "Um alle Funktionen dieser Anwendung nutzen zu können, +sollten Sie einen der folgenden Browser herunterladen und installieren:" \ No newline at end of file diff --git a/rainloop/v/0.0.0/langs/en.ini b/rainloop/v/0.0.0/langs/en.ini index bd5f6f0e8..928b4287e 100644 --- a/rainloop/v/0.0.0/langs/en.ini +++ b/rainloop/v/0.0.0/langs/en.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Not all attachments have been uploaded yet." BUTTON_REQUEST_READ_RECEIPT = "Request a read receipt" BUTTON_MARK_AS_IMPORTANT = "Mark as important" BUTTON_OPEN_PGP = "OpenPGP (Plain Text Only)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Yes" diff --git a/rainloop/v/0.0.0/langs/es.ini b/rainloop/v/0.0.0/langs/es.ini index ac29ce797..e9ab620ed 100644 --- a/rainloop/v/0.0.0/langs/es.ini +++ b/rainloop/v/0.0.0/langs/es.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Not all attachments have been uploaded yet" BUTTON_REQUEST_READ_RECEIPT = "Solicitar confirmación de lectura" BUTTON_MARK_AS_IMPORTANT = "Mark as important" BUTTON_OPEN_PGP = "OpenPGP (Plain Text Only)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Sí" diff --git a/rainloop/v/0.0.0/langs/fr.ini b/rainloop/v/0.0.0/langs/fr.ini index 82d89319f..3d1f6b4ee 100644 --- a/rainloop/v/0.0.0/langs/fr.ini +++ b/rainloop/v/0.0.0/langs/fr.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Not all attachments have been uploaded yet" BUTTON_REQUEST_READ_RECEIPT = "Demander une confirmation de lecture" BUTTON_MARK_AS_IMPORTANT = "Mark as important" BUTTON_OPEN_PGP = "OpenPGP (Plain Text Only)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Oui" diff --git a/rainloop/v/0.0.0/langs/hu.ini b/rainloop/v/0.0.0/langs/hu.ini index 89403f6b3..5b43b8def 100644 --- a/rainloop/v/0.0.0/langs/hu.ini +++ b/rainloop/v/0.0.0/langs/hu.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Not all attachments have been uploaded yet" BUTTON_REQUEST_READ_RECEIPT = "Request a read receipt" BUTTON_MARK_AS_IMPORTANT = "Mark as important" BUTTON_OPEN_PGP = "OpenPGP (Plain Text Only)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Igen" diff --git a/rainloop/v/0.0.0/langs/is.ini b/rainloop/v/0.0.0/langs/is.ini index 0886e84f2..e40222b5f 100644 --- a/rainloop/v/0.0.0/langs/is.ini +++ b/rainloop/v/0.0.0/langs/is.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Not all attachments have been uploaded yet" BUTTON_REQUEST_READ_RECEIPT = "Request a read receipt" BUTTON_MARK_AS_IMPORTANT = "Mark as important" BUTTON_OPEN_PGP = "OpenPGP (Plain Text Only)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Yes" diff --git a/rainloop/v/0.0.0/langs/it.ini b/rainloop/v/0.0.0/langs/it.ini index 73aafbf3a..13512b381 100644 --- a/rainloop/v/0.0.0/langs/it.ini +++ b/rainloop/v/0.0.0/langs/it.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Non tutti gli allegati sono stati caricati al m BUTTON_REQUEST_READ_RECEIPT = "Richiedi conferma di lettura" BUTTON_MARK_AS_IMPORTANT = "Marca come importante" BUTTON_OPEN_PGP = "OpenPGP (Solo testo semplice)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Si" diff --git a/rainloop/v/0.0.0/langs/ja-jp.ini b/rainloop/v/0.0.0/langs/ja-jp.ini index 110e52d48..536d2cba8 100644 --- a/rainloop/v/0.0.0/langs/ja-jp.ini +++ b/rainloop/v/0.0.0/langs/ja-jp.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Not all attachments have been uploaded yet" BUTTON_REQUEST_READ_RECEIPT = "開封確認を要求しますか?" BUTTON_MARK_AS_IMPORTANT = "Mark as important" BUTTON_OPEN_PGP = "OpenPGP (Plain Text Only)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "はい" diff --git a/rainloop/v/0.0.0/langs/ko-kr.ini b/rainloop/v/0.0.0/langs/ko-kr.ini index 2c29b5e92..5edd63c97 100644 --- a/rainloop/v/0.0.0/langs/ko-kr.ini +++ b/rainloop/v/0.0.0/langs/ko-kr.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Not all attachments have been uploaded yet" BUTTON_REQUEST_READ_RECEIPT = "Request a read receipt" BUTTON_MARK_AS_IMPORTANT = "Mark as important" BUTTON_OPEN_PGP = "OpenPGP (Plain Text Only)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Yes" diff --git a/rainloop/v/0.0.0/langs/lt.ini b/rainloop/v/0.0.0/langs/lt.ini index 757675779..dbb61994a 100644 --- a/rainloop/v/0.0.0/langs/lt.ini +++ b/rainloop/v/0.0.0/langs/lt.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Dar ne visi priedai buvo įkelti" BUTTON_REQUEST_READ_RECEIPT = "Prašyti pranešti kada bus perskaitytas" BUTTON_MARK_AS_IMPORTANT = "Žymėti svarbiu" BUTTON_OPEN_PGP = "OpenPGP (Tik paprastas tekstas)" +BUTTON_REQUEST_DSN = "Prašyti laiško gavimo pažymos" [POPUPS_ASK] BUTTON_YES = "Taip" diff --git a/rainloop/v/0.0.0/langs/lv.ini b/rainloop/v/0.0.0/langs/lv.ini index bcafcab22..cd721996a 100644 --- a/rainloop/v/0.0.0/langs/lv.ini +++ b/rainloop/v/0.0.0/langs/lv.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Not all attachments have been uploaded yet" BUTTON_REQUEST_READ_RECEIPT = "Request a read receipt" BUTTON_MARK_AS_IMPORTANT = "Mark as important" BUTTON_OPEN_PGP = "OpenPGP (Plain Text Only)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Yes" diff --git a/rainloop/v/0.0.0/langs/nl.ini b/rainloop/v/0.0.0/langs/nl.ini index 36a6cfb12..35d632d9f 100644 --- a/rainloop/v/0.0.0/langs/nl.ini +++ b/rainloop/v/0.0.0/langs/nl.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Toevoegen van bijlage(n) is nog niet gereed" BUTTON_REQUEST_READ_RECEIPT = "Leesbevestiging vragen" BUTTON_MARK_AS_IMPORTANT = "Marker als belangrijk" BUTTON_OPEN_PGP = "OpenPGP (allen bij Platte Tekst)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Ja" @@ -690,4 +691,4 @@ NO_COOKIE_DESC = "Cookies ondersteuning is niet beschikbaar in uw browser. Gelieve Cookies in te schakelen en opnieuw te proberen." BAD_BROWSER_TITLE = "Uw browser is verouderd" BAD_BROWSER_DESC = "Om alle functies van deze applicatie te gebruiken, -download en installeer een van de volgende browsers:" +download en installeer een van de volgende browsers:" \ No newline at end of file diff --git a/rainloop/v/0.0.0/langs/no.ini b/rainloop/v/0.0.0/langs/no.ini index edd134ed2..b229a1e68 100644 --- a/rainloop/v/0.0.0/langs/no.ini +++ b/rainloop/v/0.0.0/langs/no.ini @@ -232,6 +232,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Alle vedleggene er ikke lastet opp ennå" BUTTON_REQUEST_READ_RECEIPT = "Be om en lesebekreftelse når meldingen er lest" BUTTON_MARK_AS_IMPORTANT = "Mark as important" BUTTON_OPEN_PGP = "OpenPGP (Plain Text Only)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Ja" diff --git a/rainloop/v/0.0.0/langs/pl.ini b/rainloop/v/0.0.0/langs/pl.ini index 602255db4..54b95bdba 100644 --- a/rainloop/v/0.0.0/langs/pl.ini +++ b/rainloop/v/0.0.0/langs/pl.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Nie przesłano jeszcze wszystkich załącznikó BUTTON_REQUEST_READ_RECEIPT = "Żądaj potwierdzenia odbioru" BUTTON_MARK_AS_IMPORTANT = "Oznacz jako ważną" BUTTON_OPEN_PGP = "OpenPGP (Tylko zwykły tekst)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Tak" @@ -690,4 +691,4 @@ NO_COOKIE_DESC = "Obsługa Cookies jest wyłączona w twojej przeglądarce Proszę o umożliwienie obsługi plików Cookie w przeglądarce oraz ponowne uruchomienie tej strony." BAD_BROWSER_TITLE = "Twoja przeglądarka jest przestarzała!" BAD_BROWSER_DESC = "W celu wykorzystania wszystkich funkcji tej aplikacji, -zaktualizuj aktualnie używaną lub pobierz i zainstaluj jedną z poniższych przeglądarek:" +zaktualizuj aktualnie używaną lub pobierz i zainstaluj jedną z poniższych przeglądarek:" \ No newline at end of file diff --git a/rainloop/v/0.0.0/langs/pt-br.ini b/rainloop/v/0.0.0/langs/pt-br.ini index 1011c8433..bfd365fcb 100644 --- a/rainloop/v/0.0.0/langs/pt-br.ini +++ b/rainloop/v/0.0.0/langs/pt-br.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Alguns anexos ainda não foram completamente en BUTTON_REQUEST_READ_RECEIPT = "Pedir recibo de leitura" BUTTON_MARK_AS_IMPORTANT = "Marcar como importante" BUTTON_OPEN_PGP = "OpenPGP (Somente Texto)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Sim" @@ -690,4 +691,4 @@ NO_COOKIE_DESC = "Os Cookies não estão disponíveis em seu navegador. Por favor ative o suporte a Cookies nas configurações do seu navegador e tente novamente." BAD_BROWSER_TITLE = "Seu navegador está desatualizado." BAD_BROWSER_DESC = "Para usar todos os recursos do aplicativo, -baixe e instale um desses navegadores:" +baixe e instale um desses navegadores:" \ No newline at end of file diff --git a/rainloop/v/0.0.0/langs/pt-pt.ini b/rainloop/v/0.0.0/langs/pt-pt.ini index 71e06b003..5cd07f42c 100644 --- a/rainloop/v/0.0.0/langs/pt-pt.ini +++ b/rainloop/v/0.0.0/langs/pt-pt.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Ainda não foram carregados todos os anexos" BUTTON_REQUEST_READ_RECEIPT = "Pedir um recibo de leitura" BUTTON_MARK_AS_IMPORTANT = "Marcar como importante" BUTTON_OPEN_PGP = "OpenPGP (apenas texto simples)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Sim" @@ -690,4 +691,4 @@ NO_COOKIE_DESC = "O suport de Cookies não está disponível no seu navegador. Por favor ative o suporte de Cookies nas definições do seu navegador e tente novamente." BAD_BROWSER_TITLE = "O seu navegador está desatualizado." BAD_BROWSER_DESC = "Para usar todas as funções da aplicação, -transfira e instale um destes navegadores:" +transfira e instale um destes navegadores:" \ No newline at end of file diff --git a/rainloop/v/0.0.0/langs/ro.ini b/rainloop/v/0.0.0/langs/ro.ini index 5512a49da..5ae302fd0 100644 --- a/rainloop/v/0.0.0/langs/ro.ini +++ b/rainloop/v/0.0.0/langs/ro.ini @@ -232,6 +232,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Not all attachments have been uploaded yet" BUTTON_REQUEST_READ_RECEIPT = "Cere confirmare de citire" BUTTON_MARK_AS_IMPORTANT = "Mark as important" BUTTON_OPEN_PGP = "OpenPGP (Plain Text Only)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Da" diff --git a/rainloop/v/0.0.0/langs/ru.ini b/rainloop/v/0.0.0/langs/ru.ini index 2e396d375..a6b3cc970 100644 --- a/rainloop/v/0.0.0/langs/ru.ini +++ b/rainloop/v/0.0.0/langs/ru.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Not all attachments have been uploaded yet" BUTTON_REQUEST_READ_RECEIPT = "Запрос о прочтении письма" BUTTON_MARK_AS_IMPORTANT = "Mark as important" BUTTON_OPEN_PGP = "OpenPGP (Plain Text Only)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Да" diff --git a/rainloop/v/0.0.0/langs/sk.ini b/rainloop/v/0.0.0/langs/sk.ini index a569113f7..baf616c33 100644 --- a/rainloop/v/0.0.0/langs/sk.ini +++ b/rainloop/v/0.0.0/langs/sk.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Not all attachments have been uploaded yet" BUTTON_REQUEST_READ_RECEIPT = "Vyžiadať potvrdenie o prečítaní" BUTTON_MARK_AS_IMPORTANT = "Mark as important" BUTTON_OPEN_PGP = "OpenPGP (Plain Text Only)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Áno" diff --git a/rainloop/v/0.0.0/langs/sv.ini b/rainloop/v/0.0.0/langs/sv.ini index 1022efdd8..9e14a374d 100644 --- a/rainloop/v/0.0.0/langs/sv.ini +++ b/rainloop/v/0.0.0/langs/sv.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Alla bilagor är inte uppladddade än" BUTTON_REQUEST_READ_RECEIPT = "Begär mottagningskvitto" BUTTON_MARK_AS_IMPORTANT = "Markera som viktigt" BUTTON_OPEN_PGP = "OpenPGP (Endast enkel text)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Ja" diff --git a/rainloop/v/0.0.0/langs/tr.ini b/rainloop/v/0.0.0/langs/tr.ini index 76602a764..4790831fa 100644 --- a/rainloop/v/0.0.0/langs/tr.ini +++ b/rainloop/v/0.0.0/langs/tr.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Not all attachments have been uploaded yet" BUTTON_REQUEST_READ_RECEIPT = "Okundu bilgisi iste" BUTTON_MARK_AS_IMPORTANT = "Mark as important" BUTTON_OPEN_PGP = "OpenPGP (Plain Text Only)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Evet" diff --git a/rainloop/v/0.0.0/langs/ua.ini b/rainloop/v/0.0.0/langs/ua.ini index ccc94604f..17ba1e3b8 100644 --- a/rainloop/v/0.0.0/langs/ua.ini +++ b/rainloop/v/0.0.0/langs/ua.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Not all attachments have been uploaded yet" BUTTON_REQUEST_READ_RECEIPT = "Запит про прочитання листа" BUTTON_MARK_AS_IMPORTANT = "Mark as important" BUTTON_OPEN_PGP = "OpenPGP (Plain Text Only)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "Так" diff --git a/rainloop/v/0.0.0/langs/zh-cn.ini b/rainloop/v/0.0.0/langs/zh-cn.ini index 591716304..9c4c35be3 100644 --- a/rainloop/v/0.0.0/langs/zh-cn.ini +++ b/rainloop/v/0.0.0/langs/zh-cn.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Not all attachments have been uploaded yet" BUTTON_REQUEST_READ_RECEIPT = "Request a read receipt" BUTTON_MARK_AS_IMPORTANT = "Mark as important" BUTTON_OPEN_PGP = "OpenPGP (Plain Text Only)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "是" diff --git a/rainloop/v/0.0.0/langs/zh-tw.ini b/rainloop/v/0.0.0/langs/zh-tw.ini index bbd7c3757..7ca72a5fc 100644 --- a/rainloop/v/0.0.0/langs/zh-tw.ini +++ b/rainloop/v/0.0.0/langs/zh-tw.ini @@ -233,6 +233,7 @@ ATTACHMENTS_UPLOAD_ERROR_DESC = "Not all attachments have been uploaded yet" BUTTON_REQUEST_READ_RECEIPT = "Request a read receipt" BUTTON_MARK_AS_IMPORTANT = "Mark as important" BUTTON_OPEN_PGP = "OpenPGP (Plain Text Only)" +BUTTON_REQUEST_DSN = "Request a delivery receipt" [POPUPS_ASK] BUTTON_YES = "是" diff --git a/vendors/knockout/knockout-3.3.0.js b/vendors/knockout/knockout-3.3.0.js new file mode 100644 index 000000000..d1af860cd --- /dev/null +++ b/vendors/knockout/knockout-3.3.0.js @@ -0,0 +1,115 @@ +/*! + * Knockout JavaScript library v3.3.0 + * (c) Steven Sanderson - http://knockoutjs.com/ + * License: MIT (http://www.opensource.org/licenses/mit-license.php) + */ + +(function() {(function(p){var y=this||(0,eval)("this"),w=y.document,M=y.navigator,u=y.jQuery,E=y.JSON;(function(p){"function"===typeof define&&define.amd?define(["exports","require"],p):"function"===typeof require&&"object"===typeof exports&&"object"===typeof module?p(module.exports||exports):p(y.ko={})})(function(N,O){function J(a,d){return null===a||typeof a in Q?a===d:!1}function R(a,d){var c;return function(){c||(c=setTimeout(function(){c=p;a()},d))}}function S(a,d){var c;return function(){clearTimeout(c); +c=setTimeout(a,d)}}function K(b,d,c,e){a.d[b]={init:function(b,k,h,l,g){var m,x;a.w(function(){var q=a.a.c(k()),n=!c!==!q,r=!x;if(r||d||n!==m)r&&a.Z.oa()&&(x=a.a.la(a.e.childNodes(b),!0)),n?(r||a.e.T(b,a.a.la(x)),a.Ja(e?e(g,q):g,b)):a.e.ma(b),m=n},null,{q:b});return{controlsDescendantBindings:!0}}};a.h.ka[b]=!1;a.e.R[b]=!0}var a="undefined"!==typeof N?N:{};a.b=function(b,d){for(var c=b.split("."),e=a,f=0;fa.a.m(c,b[g])&&c.push(b[g]);return c},Ka:function(a,b){a=a||[];for(var c=[],g=0,d=a.length;gd?g&&b.push(c):g||b.splice(d,1)},za:f,extend:d,Fa:c,Ga:f?c:d,A:b,pa:function(a,b){if(!a)return a;var c={},g;for(g in a)a.hasOwnProperty(g)&&(c[g]=b(a[g],g,a));return c},Ra:function(b){for(;b.firstChild;)a.removeNode(b.firstChild)},Jb:function(b){b=a.a.O(b);for(var c=(b[0]&&b[0].ownerDocument||w).createElement("div"),g=0,d=b.length;g< +d;g++)c.appendChild(a.S(b[g]));return c},la:function(b,c){for(var g=0,d=b.length,e=[];gg?a.setAttribute("selected",b):a.selected=b},ib:function(a){return null===a||a===p?"":a.trim?a.trim():a.toString().replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")},Dc:function(a,b){a=a||"";return b.length>a.length?!1:a.substring(0,b.length)===b},jc:function(a,b){if(a===b)return!0;if(11===a.nodeType)return!1;if(b.contains)return b.contains(3===a.nodeType? +a.parentNode:a);if(b.compareDocumentPosition)return 16==(b.compareDocumentPosition(a)&16);for(;a&&a!=b;)a=a.parentNode;return!!a},Qa:function(b){return a.a.jc(b,b.ownerDocument.documentElement)},tb:function(b){return!!a.a.vb(b,a.a.Qa)},v:function(a){return a&&a.tagName&&a.tagName.toLowerCase()},n:function(b,c,d){var m=g&&l[c];if(!m&&u)u(b).bind(c,d);else if(m||"function"!=typeof b.addEventListener)if("undefined"!=typeof b.attachEvent){var e=function(a){d.call(b,a)},f="on"+c;b.attachEvent(f,e);a.a.C.fa(b, +function(){b.detachEvent(f,e)})}else throw Error("Browser doesn't support addEventListener or attachEvent");else b.addEventListener(c,d,!1)},qa:function(b,c){if(!b||!b.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var g;"input"===a.a.v(b)&&b.type&&"click"==c.toLowerCase()?(g=b.type,g="checkbox"==g||"radio"==g):g=!1;if(u&&!g)u(b).trigger(c);else if("function"==typeof w.createEvent)if("function"==typeof b.dispatchEvent)g=w.createEvent(h[c]||"HTMLEvents"),g.initEvent(c, +!0,!0,y,0,0,0,0,0,!1,!1,!1,!1,0,b),b.dispatchEvent(g);else throw Error("The supplied element doesn't support dispatchEvent");else if(g&&b.click)b.click();else if("undefined"!=typeof b.fireEvent)b.fireEvent("on"+c);else throw Error("Browser doesn't support triggering events");},c:function(b){return a.F(b)?b():b},cb:function(b){return a.F(b)?b.B():b},Ia:function(b,c,g){var d;c&&("object"===typeof b.classList?(d=b.classList[g?"add":"remove"],a.a.o(c.match(m),function(a){d.call(b.classList,a)})):"string"=== +typeof b.className.baseVal?e(b.className,"baseVal",c,g):e(b,"className",c,g))},Ha:function(b,c){var g=a.a.c(c);if(null===g||g===p)g="";var d=a.e.firstChild(b);!d||3!=d.nodeType||a.e.nextSibling(d)?a.e.T(b,[b.ownerDocument.createTextNode(g)]):d.data=g;a.a.mc(b)},Rb:function(a,b){a.name=b;if(7>=g)try{a.mergeAttributes(w.createElement(""),!1)}catch(c){}},mc:function(a){9<=g&&(a=1==a.nodeType?a:a.parentNode,a.style&&(a.style.zoom=a.style.zoom))},kc:function(a){if(g){var b=a.style.width; +a.style.width=0;a.style.width=b}},Bc:function(b,c){b=a.a.c(b);c=a.a.c(c);for(var g=[],d=b;d<=c;d++)g.push(d);return g},O:function(a){for(var b=[],c=0,g=a.length;c",""]||!f.indexOf("", +""]||(!f.indexOf("",""]||[0,"",""],k="ignored
      "+f[1]+b+f[2]+"
      ";for("function"==typeof c.innerShiv?e.appendChild(c.innerShiv(k)):e.innerHTML=k;f[0]--;)e=e.lastChild;c=a.a.O(e.lastChild.childNodes)}return c};a.a.gb=function(b,d){a.a.Ra(b);d=a.a.c(d);if(null!==d&&d!==p)if("string"!=typeof d&&(d=d.toString()),u)u(b).html(d);else for(var c=a.a.ca(d,b.ownerDocument),e=0;ef[0]?r+f[0]:f[0]),r);for(var r=1===v?r:Math.min(d+(f[1]||0),r),v=d+v-2,t=Math.max(r,v),G=[],A=[],p=2;dc;c++)b=b();return b})};a.toJSON=function(b,c,d){b=a.Vb(b);return a.a.jb(b,c,d)};c.prototype={save:function(b,c){var d=a.a.m(this.keys,b);0<=d?this.mb[d]=c:(this.keys.push(b),this.mb.push(c))},get:function(b){b=a.a.m(this.keys,b);return 0<=b?this.mb[b]:p}}})();a.b("toJS",a.Vb);a.b("toJSON",a.toJSON);(function(){a.i={s:function(b){switch(a.a.v(b)){case "option":return!0===b.__ko__hasDomDataOptionValue__?a.a.f.get(b,a.d.options.ab):7>=a.a.M?b.getAttributeNode("value")&&b.getAttributeNode("value").specified? +b.value:b.text:b.value;case "select":return 0<=b.selectedIndex?a.i.s(b.options[b.selectedIndex]):p;default:return b.value}},Y:function(b,d,c){switch(a.a.v(b)){case "option":switch(typeof d){case "string":a.a.f.set(b,a.d.options.ab,p);"__ko__hasDomDataOptionValue__"in b&&delete b.__ko__hasDomDataOptionValue__;b.value=d;break;default:a.a.f.set(b,a.d.options.ab,d),b.__ko__hasDomDataOptionValue__=!0,b.value="number"===typeof d?d:""}break;case "select":if(""===d||null===d)d=p;for(var e=-1,f=0,k=b.options.length, +h;f=n){c.push(x&&h.length?{key:x, +value:h.join("")}:{unknown:x||h.join("")});x=n=0;h=[];continue}}else if(58===t){if(!n&&!x&&1===h.length){x=h.pop();continue}}else 47===t&&r&&1a.a.M&&(a.g.register=function(a){return function(b){w.createElement(b); +return a.apply(this,arguments)}}(a.g.register),w.createDocumentFragment=function(b){return function(){var d=b(),f=a.g.$b,k;for(k in f)f.hasOwnProperty(k)&&d.createElement(k);return d}}(w.createDocumentFragment))})();(function(b){function d(b,c,d){c=c.template;if(!c)throw Error("Component '"+b+"' has no template");b=a.a.la(c);a.e.T(d,b)}function c(a,b,c,d){var e=a.createViewModel;return e?e.call(a,d,{element:b,templateNodes:c}):d}var e=0;a.d.component={init:function(f,k,h,l,g){function m(){var a=x&& +x.dispose;"function"===typeof a&&a.call(x);q=null}var x,q,n=a.a.O(a.e.childNodes(f));a.a.C.fa(f,m);a.w(function(){var l=a.a.c(k()),h,t;"string"===typeof l?h=l:(h=a.a.c(l.name),t=a.a.c(l.params));if(!h)throw Error("No component name specified");var p=q=++e;a.g.get(h,function(e){if(q===p){m();if(!e)throw Error("Unknown component '"+h+"'");d(h,e,f);var l=c(e,f,n,t);e=g.createChildContext(l,b,function(a){a.$component=l;a.$componentTemplateNodes=n});x=l;a.Ja(e,f)}})},null,{q:f});return{controlsDescendantBindings:!0}}}; +a.e.R.component=!0})();var P={"class":"className","for":"htmlFor"};a.d.attr={update:function(b,d){var c=a.a.c(d())||{};a.a.A(c,function(c,d){d=a.a.c(d);var k=!1===d||null===d||d===p;k&&b.removeAttribute(c);8>=a.a.M&&c in P?(c=P[c],k?b.removeAttribute(c):b[c]=d):k||b.setAttribute(c,d.toString());"name"===c&&a.a.Rb(b,k?"":d.toString())})}};(function(){a.d.checked={after:["value","attr"],init:function(b,d,c){function e(){var e=b.checked,f=x?k():e;if(!a.Z.Ca()&&(!l||e)){var h=a.k.u(d);g?m!==f?(e&&(a.a.ga(h, +f,!0),a.a.ga(h,m,!1)),m=f):a.a.ga(h,f,e):a.h.ra(h,c,"checked",f,!0)}}function f(){var c=a.a.c(d());b.checked=g?0<=a.a.m(c,k()):h?c:k()===c}var k=a.Nb(function(){return c.has("checkedValue")?a.a.c(c.get("checkedValue")):c.has("value")?a.a.c(c.get("value")):b.value}),h="checkbox"==b.type,l="radio"==b.type;if(h||l){var g=h&&a.a.c(d())instanceof Array,m=g?k():p,x=l||g;l&&!b.name&&a.d.uniqueName.init(b,function(){return!0});a.w(e,null,{q:b});a.a.n(b,"click",e);a.w(f,null,{q:b})}}};a.h.V.checked=!0;a.d.checkedValue= +{update:function(b,d){b.value=a.a.c(d())}}})();a.d.css={update:function(b,d){var c=a.a.c(d());null!==c&&"object"==typeof c?a.a.A(c,function(c,d){d=a.a.c(d);a.a.Ia(b,c,d)}):(c=String(c||""),a.a.Ia(b,b.__ko__cssValue,!1),b.__ko__cssValue=c,a.a.Ia(b,c,!0))}};a.d.enable={update:function(b,d){var c=a.a.c(d());c&&b.disabled?b.removeAttribute("disabled"):c||b.disabled||(b.disabled=!0)}};a.d.disable={update:function(b,d){a.d.enable.update(b,function(){return!a.a.c(d())})}};a.d.event={init:function(b,d,c, +e,f){var k=d()||{};a.a.A(k,function(h){"string"==typeof h&&a.a.n(b,h,function(b){var g,m=d()[h];if(m){try{var k=a.a.O(arguments);e=f.$data;k.unshift(e);g=m.apply(e,k)}finally{!0!==g&&(b.preventDefault?b.preventDefault():b.returnValue=!1)}!1===c.get(h+"Bubble")&&(b.cancelBubble=!0,b.stopPropagation&&b.stopPropagation())}})})}};a.d.foreach={Ib:function(b){return function(){var d=b(),c=a.a.cb(d);if(!c||"number"==typeof c.length)return{foreach:d,templateEngine:a.P.Va};a.a.c(d);return{foreach:c.data,as:c.as, +includeDestroyed:c.includeDestroyed,afterAdd:c.afterAdd,beforeRemove:c.beforeRemove,afterRender:c.afterRender,beforeMove:c.beforeMove,afterMove:c.afterMove,templateEngine:a.P.Va}}},init:function(b,d){return a.d.template.init(b,a.d.foreach.Ib(d))},update:function(b,d,c,e,f){return a.d.template.update(b,a.d.foreach.Ib(d),c,e,f)}};a.h.ka.foreach=!1;a.e.R.foreach=!0;a.d.hasfocus={init:function(b,d,c){function e(e){b.__ko_hasfocusUpdating=!0;var f=b.ownerDocument;if("activeElement"in f){var g;try{g=f.activeElement}catch(m){g= +f.body}e=g===b}f=d();a.h.ra(f,c,"hasfocus",e,!0);b.__ko_hasfocusLastValue=e;b.__ko_hasfocusUpdating=!1}var f=e.bind(null,!0),k=e.bind(null,!1);a.a.n(b,"focus",f);a.a.n(b,"focusin",f);a.a.n(b,"blur",k);a.a.n(b,"focusout",k)},update:function(b,d){var c=!!a.a.c(d());b.__ko_hasfocusUpdating||b.__ko_hasfocusLastValue===c||(c?b.focus():b.blur(),a.k.u(a.a.qa,null,[b,c?"focusin":"focusout"]))}};a.h.V.hasfocus=!0;a.d.hasFocus=a.d.hasfocus;a.h.V.hasFocus=!0;a.d.html={init:function(){return{controlsDescendantBindings:!0}}, +update:function(b,d){a.a.gb(b,d())}};K("if");K("ifnot",!1,!0);K("with",!0,!1,function(a,d){return a.createChildContext(d)});var L={};a.d.options={init:function(b){if("select"!==a.a.v(b))throw Error("options binding applies only to SELECT elements");for(;0a.a.M)var k=a.a.f.I(),h=a.a.f.I(),l=function(b){var c=this.activeElement;(c=c&&a.a.f.get(c,h))&&c(b)},g=function(b,c){var d=b.ownerDocument;a.a.f.get(d,k)||(a.a.f.set(d,k,!0),a.a.n(d,"selectionchange",l));a.a.f.set(b,h,c)};a.d.textInput={init:function(b,c,l){function h(c,d){a.a.n(b,c,d)}function k(){var d=a.a.c(c());if(null===d||d===p)d="";w!==p&&d===w?setTimeout(k,4):b.value!==d&&(u=d,b.value=d)}function v(){A|| +(w=b.value,A=setTimeout(t,4))}function t(){clearTimeout(A);w=A=p;var d=b.value;u!==d&&(u=d,a.h.ra(c(),l,"textInput",d))}var u=b.value,A,w;10>a.a.M?(h("propertychange",function(a){"value"===a.propertyName&&t()}),8==a.a.M&&(h("keyup",t),h("keydown",t)),8<=a.a.M&&(g(b,t),h("dragend",v))):(h("input",t),5>e&&"textarea"===a.a.v(b)?(h("keydown",v),h("paste",v),h("cut",v)):11>d?h("keydown",v):4>f&&(h("DOMAutoComplete",t),h("dragdrop",t),h("drop",t)));h("change",t);a.w(k,null,{q:b})}};a.h.V.textInput=!0;a.d.textinput= +{preprocess:function(a,b,c){c("textInput",a)}}})();a.d.uniqueName={init:function(b,d){if(d()){var c="ko_unique_"+ ++a.d.uniqueName.fc;a.a.Rb(b,c)}}};a.d.uniqueName.fc=0;a.d.value={after:["options","foreach"],init:function(b,d,c){if("input"!=b.tagName.toLowerCase()||"checkbox"!=b.type&&"radio"!=b.type){var e=["change"],f=c.get("valueUpdate"),k=!1,h=null;f&&("string"==typeof f&&(f=[f]),a.a.ia(e,f),e=a.a.wb(e));var l=function(){h=null;k=!1;var e=d(),g=a.i.s(b);a.h.ra(e,c,"value",g)};!a.a.M||"input"!= +b.tagName.toLowerCase()||"text"!=b.type||"off"==b.autocomplete||b.form&&"off"==b.form.autocomplete||-1!=a.a.m(e,"propertychange")||(a.a.n(b,"propertychange",function(){k=!0}),a.a.n(b,"focus",function(){k=!1}),a.a.n(b,"blur",function(){k&&l()}));a.a.o(e,function(c){var d=l;a.a.Dc(c,"after")&&(d=function(){h=a.i.s(b);setTimeout(l,0)},c=c.substring(5));a.a.n(b,c,d)});var g=function(){var e=a.a.c(d()),f=a.i.s(b);if(null!==h&&e===h)setTimeout(g,0);else if(e!==f)if("select"===a.a.v(b)){var l=c.get("valueAllowUnset"), +f=function(){a.i.Y(b,e,l)};f();l||e===a.i.s(b)?setTimeout(f,0):a.k.u(a.a.qa,null,[b,"change"])}else a.i.Y(b,e)};a.w(g,null,{q:b})}else a.va(b,{checkedValue:d})},update:function(){}};a.h.V.value=!0;a.d.visible={update:function(b,d){var c=a.a.c(d()),e="none"!=b.style.display;c&&!e?b.style.display="":!c&&e&&(b.style.display="none")}};(function(b){a.d[b]={init:function(d,c,e,f,k){return a.d.event.init.call(this,d,function(){var a={};a[b]=c();return a},e,f,k)}}})("click");a.J=function(){};a.J.prototype.renderTemplateSource= +function(){throw Error("Override renderTemplateSource");};a.J.prototype.createJavaScriptEvaluatorBlock=function(){throw Error("Override createJavaScriptEvaluatorBlock");};a.J.prototype.makeTemplateSource=function(b,d){if("string"==typeof b){d=d||w;var c=d.getElementById(b);if(!c)throw Error("Cannot find template with ID "+b);return new a.t.l(c)}if(1==b.nodeType||8==b.nodeType)return new a.t.ha(b);throw Error("Unknown template type: "+b);};a.J.prototype.renderTemplate=function(a,d,c,e){a=this.makeTemplateSource(a, +e);return this.renderTemplateSource(a,d,c,e)};a.J.prototype.isTemplateRewritten=function(a,d){return!1===this.allowTemplateRewriting?!0:this.makeTemplateSource(a,d).data("isRewritten")};a.J.prototype.rewriteTemplate=function(a,d,c){a=this.makeTemplateSource(a,c);d=d(a.text());a.text(d);a.data("isRewritten",!0)};a.b("templateEngine",a.J);a.kb=function(){function b(b,c,d,h){b=a.h.bb(b);for(var l=a.h.ka,g=0;g]*))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,c=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g;return{lc:function(b, +c,d){c.isTemplateRewritten(b,d)||c.rewriteTemplate(b,function(b){return a.kb.xc(b,c)},d)},xc:function(a,f){return a.replace(d,function(a,c,d,e,m){return b(m,c,d,f)}).replace(c,function(a,c){return b(c,"\x3c!-- ko --\x3e","#comment",f)})},dc:function(b,c){return a.H.$a(function(d,h){var l=d.nextSibling;l&&l.nodeName.toLowerCase()===c&&a.va(l,b,h)})}}}();a.b("__tr_ambtns",a.kb.dc);(function(){a.t={};a.t.l=function(a){this.l=a};a.t.l.prototype.text=function(){var b=a.a.v(this.l),b="script"===b?"text": +"textarea"===b?"value":"innerHTML";if(0==arguments.length)return this.l[b];var d=arguments[0];"innerHTML"===b?a.a.gb(this.l,d):this.l[b]=d};var b=a.a.f.I()+"_";a.t.l.prototype.data=function(c){if(1===arguments.length)return a.a.f.get(this.l,b+c);a.a.f.set(this.l,b+c,arguments[1])};var d=a.a.f.I();a.t.ha=function(a){this.l=a};a.t.ha.prototype=new a.t.l;a.t.ha.prototype.text=function(){if(0==arguments.length){var b=a.a.f.get(this.l,d)||{};b.lb===p&&b.Na&&(b.lb=b.Na.innerHTML);return b.lb}a.a.f.set(this.l, +d,{lb:arguments[0]})};a.t.l.prototype.nodes=function(){if(0==arguments.length)return(a.a.f.get(this.l,d)||{}).Na;a.a.f.set(this.l,d,{Na:arguments[0]})};a.b("templateSources",a.t);a.b("templateSources.domElement",a.t.l);a.b("templateSources.anonymousTemplate",a.t.ha)})();(function(){function b(b,c,d){var e;for(c=a.e.nextSibling(c);b&&(e=b)!==c;)b=a.e.nextSibling(e),d(e,b)}function d(c,d){if(c.length){var e=c[0],f=c[c.length-1],h=e.parentNode,k=a.L.instance,r=k.preprocessNode;if(r){b(e,f,function(a, +b){var c=a.previousSibling,d=r.call(k,a);d&&(a===e&&(e=d[0]||b),a===f&&(f=d[d.length-1]||c))});c.length=0;if(!e)return;e===f?c.push(e):(c.push(e,f),a.a.na(c,h))}b(e,f,function(b){1!==b.nodeType&&8!==b.nodeType||a.ub(d,b)});b(e,f,function(b){1!==b.nodeType&&8!==b.nodeType||a.H.Xb(b,[d])});a.a.na(c,h)}}function c(a){return a.nodeType?a:0a.a.M?0:b.nodes)?b.nodes():null)return a.a.O(d.cloneNode(!0).childNodes);b=b.text();return a.a.ca(b,e)};a.P.Va=new a.P;a.hb(a.P.Va);a.b("nativeTemplateEngine",a.P);(function(){a.Ya=function(){var a=this.uc=function(){if(!u||!u.tmpl)return 0;try{if(0<=u.tmpl.tag.tmpl.open.toString().indexOf("__"))return 2}catch(a){}return 1}();this.renderTemplateSource=function(b, +e,f,k){k=k||w;f=f||{};if(2>a)throw Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later.");var h=b.data("precompiled");h||(h=b.text()||"",h=u.template(null,"{{ko_with $item.koBindingContext}}"+h+"{{/ko_with}}"),b.data("precompiled",h));b=[e.$data];e=u.extend({koBindingContext:e},f.templateOptions);e=u.tmpl(h,b,e);e.appendTo(k.createElement("div"));u.fragments={};return e};this.createJavaScriptEvaluatorBlock=function(a){return"{{ko_code ((function() { return "+ +a+" })()) }}"};this.addTemplate=function(a,b){w.write("