diff --git a/.babelrc b/.babelrc
new file mode 100644
index 000000000..86541a0ec
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,3 @@
+{
+ plugins: []
+}
\ No newline at end of file
diff --git a/dev/App/User.js b/dev/App/User.js
index 84fb90d5a..9fce378b7 100644
--- a/dev/App/User.js
+++ b/dev/App/User.js
@@ -35,7 +35,7 @@
MessageStore = require('Stores/User/Message'),
ContactStore = require('Stores/User/Contact'),
- Local = require('Storage/Client'),
+ Local = require('Storage/Client.jsx'),
Settings = require('Storage/Settings'),
Remote = require('Remote/User/Ajax'),
@@ -379,9 +379,9 @@
bUseFolder = Utils.isUnd(bUseFolder) ? true : !!bUseFolder;
if (bUseFolder)
{
- if ((Enums.FolderType.Spam === iDeleteType && Consts.Values.UnuseOptionValue === FolderStore.spamFolder()) ||
- (Enums.FolderType.Trash === iDeleteType && Consts.Values.UnuseOptionValue === FolderStore.trashFolder()) ||
- (Enums.FolderType.Archive === iDeleteType && Consts.Values.UnuseOptionValue === FolderStore.archiveFolder()))
+ if ((Enums.FolderType.Spam === iDeleteType && Consts.UNUSED_OPTION_VALUE === FolderStore.spamFolder()) ||
+ (Enums.FolderType.Trash === iDeleteType && Consts.UNUSED_OPTION_VALUE === FolderStore.trashFolder()) ||
+ (Enums.FolderType.Archive === iDeleteType && Consts.UNUSED_OPTION_VALUE === FolderStore.archiveFolder()))
{
bUseFolder = false;
}
diff --git a/dev/Common/Audio.js b/dev/Common/Audio.js
deleted file mode 100644
index 13863510d..000000000
--- a/dev/Common/Audio.js
+++ /dev/null
@@ -1,184 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- window = require('window'),
- $ = require('$'),
-
- Globals = require('Common/Globals'),
- Utils = require('Common/Utils'),
- Links = require('Common/Links'),
- Events = require('Common/Events')
- ;
-
- /**
- * @constructor
- */
- function Audio()
- {
- var self = this;
-
-// this.userMedia = window.navigator.getUserMedia || window.navigator.webkitGetUserMedia ||
-// window.navigator.mozGetUserMedia || window.navigator.msGetUserMedia;
-//
-// this.audioContext = window.AudioContext || window.webkitAudioContext;
-// if (!this.audioContext || !window.Float32Array)
-// {
-// this.audioContext = null;
-// this.userMedia = null;
-// }
-
- this.player = this.createNewObject();
-
- this.supported = !Globals.bMobileDevice && !Globals.bSafari && !!this.player && !!this.player.play;
- if (this.supported && this.player.canPlayType)
- {
- this.supportedMp3 = '' !== this.player.canPlayType('audio/mpeg;').replace(/no/, '');
- this.supportedWav = '' !== this.player.canPlayType('audio/wav; codecs="1"').replace(/no/, '');
- this.supportedOgg = '' !== this.player.canPlayType('audio/ogg; codecs="vorbis"').replace(/no/, '');
- this.supportedNotification = this.supported && this.supportedMp3;
- }
-
- if (!this.player || (!this.supportedMp3 && !this.supportedOgg && !this.supportedWav))
- {
- this.supported = false;
- this.supportedMp3 = false;
- this.supportedOgg = false;
- this.supportedWav = false;
- this.supportedNotification = false;
- }
-
- if (this.supported)
- {
- $(this.player).on('ended error', function () {
- self.stop();
- });
-
- Events.sub('audio.api.stop', function () {
- self.stop();
- });
- }
- }
-
- Audio.prototype.player = null;
- Audio.prototype.notificator = null;
-
- Audio.prototype.supported = false;
- Audio.prototype.supportedMp3 = false;
- Audio.prototype.supportedOgg = false;
- Audio.prototype.supportedWav = false;
- Audio.prototype.supportedNotification = false;
-
-// Audio.prototype.record = function ()
-// {
-// this.getUserMedia({audio:true}, function () {
-// }, function(oError) {
-// });
-// };
-
- Audio.prototype.createNewObject = function ()
- {
- var player = window.Audio ? new window.Audio() : null;
- if (player && player.canPlayType && player.pause && player.play)
- {
- player.preload = 'none';
- player.loop = false;
- player.autoplay = false;
- player.muted = false;
- }
-
- return player;
- };
-
- Audio.prototype.paused = function ()
- {
- return this.supported ? !!this.player.paused : true;
- };
-
- Audio.prototype.stop = function ()
- {
- if (this.supported && this.player.pause)
- {
- this.player.pause();
- }
-
- Events.pub('audio.stop');
- };
-
- Audio.prototype.pause = Audio.prototype.stop;
-
- Audio.prototype.clearName = function (sName, sExt)
- {
- sExt = sExt || '';
- sName = Utils.isUnd(sName) ? '' : Utils.trim(sName);
- if (sExt && '.' + sExt === sName.toLowerCase().substr((sExt.length + 1) * -1))
- {
- sName = Utils.trim(sName.substr(0, sName.length - 4));
- }
-
- if ('' === sName)
- {
- sName = 'audio';
- }
-
- return sName;
- };
-
- Audio.prototype.playMp3 = function (sUrl, sName)
- {
- if (this.supported && this.supportedMp3)
- {
- this.player.src = sUrl;
- this.player.play();
-
- Events.pub('audio.start', [this.clearName(sName, 'mp3'), 'mp3']);
- }
- };
-
- Audio.prototype.playOgg = function (sUrl, sName)
- {
- if (this.supported && this.supportedOgg)
- {
- this.player.src = sUrl;
- this.player.play();
-
- sName = this.clearName(sName, 'oga');
- sName = this.clearName(sName, 'ogg');
-
- Events.pub('audio.start', [sName, 'ogg']);
- }
- };
-
- Audio.prototype.playWav = function (sUrl, sName)
- {
- if (this.supported && this.supportedWav)
- {
- this.player.src = sUrl;
- this.player.play();
-
- Events.pub('audio.start', [this.clearName(sName, 'wav'), 'wav']);
- }
- };
-
- Audio.prototype.playNotification = function ()
- {
- if (this.supported && this.supportedMp3)
- {
- if (!this.notificator)
- {
- this.notificator = this.createNewObject();
- this.notificator.src = Links.sound('new-mail.mp3');
- }
-
- if (this.notificator && this.notificator.play)
- {
- this.notificator.play();
- }
- }
- };
-
- module.exports = new Audio();
-
-}());
diff --git a/dev/Common/Audio.jsx b/dev/Common/Audio.jsx
new file mode 100644
index 000000000..f14971ba9
--- /dev/null
+++ b/dev/Common/Audio.jsx
@@ -0,0 +1,142 @@
+
+import {window, $} from 'common';
+import Globals from 'Common/Globals';
+import Utils from 'Common/Utils';
+import Links from 'Common/Links';
+import Events from 'Common/Events';
+
+class Audio
+{
+ constructor()
+ {
+ this.notificator = null;
+
+ this.supportedMp3 = false;
+ this.supportedOgg = false;
+ this.supportedWav = false;
+ this.supportedNotification = false;
+
+ this.player = this.createNewObject();
+
+ this.supported = !Globals.bMobileDevice && !Globals.bSafari && !!this.player && !!this.player.play;
+ if (this.supported && this.player.canPlayType)
+ {
+ this.supportedMp3 = '' !== this.player.canPlayType('audio/mpeg;').replace(/no/, '');
+ this.supportedWav = '' !== this.player.canPlayType('audio/wav; codecs="1"').replace(/no/, '');
+ this.supportedOgg = '' !== this.player.canPlayType('audio/ogg; codecs="vorbis"').replace(/no/, '');
+ this.supportedNotification = this.supported && this.supportedMp3;
+ }
+
+ if (!this.player || (!this.supportedMp3 && !this.supportedOgg && !this.supportedWav))
+ {
+ this.supported = false;
+ this.supportedMp3 = false;
+ this.supportedOgg = false;
+ this.supportedWav = false;
+ this.supportedNotification = false;
+ }
+
+ if (this.supported)
+ {
+ $(this.player).on('ended error', () => {
+ this.stop();
+ });
+
+ Events.sub('audio.api.stop', () => {
+ this.stop();
+ });
+ }
+ }
+
+ createNewObject() {
+ const player = window.Audio ? new window.Audio() : null;
+ if (player && player.canPlayType && player.pause && player.play)
+ {
+ player.preload = 'none';
+ player.loop = false;
+ player.autoplay = false;
+ player.muted = false;
+ }
+
+ return player;
+ }
+
+ paused() {
+ return this.supported ? !!this.player.paused : true;
+ }
+
+ stop() {
+ if (this.supported && this.player.pause)
+ {
+ this.player.pause();
+ }
+
+ Events.pub('audio.stop');
+ }
+
+ pause() {
+ this.stop();
+ }
+
+ clearName(name = '', ext = '') {
+
+ name = Utils.trim(name);
+ if (ext && '.' + ext === name.toLowerCase().substr((ext.length + 1) * -1))
+ {
+ name = Utils.trim(name.substr(0, name.length - 4));
+ }
+
+ return '' === name ? 'audio' : name;
+ }
+
+ playMp3(url, name) {
+ if (this.supported && this.supportedMp3)
+ {
+ this.player.src = url;
+ this.player.play();
+
+ Events.pub('audio.start', [this.clearName(name, 'mp3'), 'mp3']);
+ }
+ }
+
+ playOgg(url, name) {
+ if (this.supported && this.supportedOgg)
+ {
+ this.player.src = url;
+ this.player.play();
+
+ name = this.clearName(name, 'oga');
+ name = this.clearName(name, 'ogg');
+
+ Events.pub('audio.start', [name, 'ogg']);
+ }
+ }
+
+ playWav(url, name) {
+ if (this.supported && this.supportedWav)
+ {
+ this.player.src = url;
+ this.player.play();
+
+ Events.pub('audio.start', [this.clearName(name, 'wav'), 'wav']);
+ }
+ }
+
+ playNotification() {
+ if (this.supported && this.supportedMp3)
+ {
+ if (!this.notificator)
+ {
+ this.notificator = this.createNewObject();
+ this.notificator.src = Links.sound('new-mail.mp3');
+ }
+
+ if (this.notificator && this.notificator.play)
+ {
+ this.notificator.play();
+ }
+ }
+ }
+}
+
+module.exports = new Audio();
diff --git a/dev/Common/Base64.js b/dev/Common/Base64.js
deleted file mode 100644
index 322090ae1..000000000
--- a/dev/Common/Base64.js
+++ /dev/null
@@ -1,172 +0,0 @@
-
-// Base64 encode / decode
-// http://www.webtoolkit.info/
-
-(function () {
-
- 'use strict';
-
- /*jslint bitwise: true*/
- var Base64 = {
-
- // private property
- _keyStr : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
-
- // public method for urlsafe encoding
- urlsafe_encode : function (input) {
- return Base64.encode(input).replace(/[+]/g, '-').replace(/[\/]/g, '_').replace(/[=]/g, '.');
- },
-
- // public method for encoding
- encode : function (input) {
- var
- output = '',
- chr1, chr2, chr3, enc1, enc2, enc3, enc4,
- i = 0
- ;
-
- input = Base64._utf8_encode(input);
-
- while (i < input.length)
- {
- chr1 = input.charCodeAt(i++);
- chr2 = input.charCodeAt(i++);
- chr3 = input.charCodeAt(i++);
-
- enc1 = chr1 >> 2;
- enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
- enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
- enc4 = chr3 & 63;
-
- if (isNaN(chr2))
- {
- enc3 = enc4 = 64;
- }
- else if (isNaN(chr3))
- {
- enc4 = 64;
- }
-
- output = output +
- this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
- this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
- }
-
- return output;
- },
-
- // public method for decoding
- decode : function (input) {
- var
- output = '',
- chr1, chr2, chr3, enc1, enc2, enc3, enc4,
- i = 0
- ;
-
- input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
-
- while (i < input.length)
- {
- enc1 = this._keyStr.indexOf(input.charAt(i++));
- enc2 = this._keyStr.indexOf(input.charAt(i++));
- enc3 = this._keyStr.indexOf(input.charAt(i++));
- enc4 = this._keyStr.indexOf(input.charAt(i++));
-
- chr1 = (enc1 << 2) | (enc2 >> 4);
- chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
- chr3 = ((enc3 & 3) << 6) | enc4;
-
- output = output + String.fromCharCode(chr1);
-
- if (enc3 !== 64)
- {
- output = output + String.fromCharCode(chr2);
- }
-
- if (enc4 !== 64)
- {
- output = output + String.fromCharCode(chr3);
- }
- }
-
- return Base64._utf8_decode(output);
- },
-
- // private method for UTF-8 encoding
- _utf8_encode : function (string) {
-
- string = string.replace(/\r\n/g, "\n");
-
- var
- utftext = '',
- n = 0,
- l = string.length,
- c = 0
- ;
-
- for (; n < l; n++) {
-
- c = string.charCodeAt(n);
-
- if (c < 128)
- {
- utftext += String.fromCharCode(c);
- }
- else if ((c > 127) && (c < 2048))
- {
- utftext += String.fromCharCode((c >> 6) | 192);
- utftext += String.fromCharCode((c & 63) | 128);
- }
- else
- {
- utftext += String.fromCharCode((c >> 12) | 224);
- utftext += String.fromCharCode(((c >> 6) & 63) | 128);
- utftext += String.fromCharCode((c & 63) | 128);
- }
- }
-
- return utftext;
- },
-
- // private method for UTF-8 decoding
- _utf8_decode : function (utftext) {
- var
- string = '',
- i = 0,
- c = 0,
- c2 = 0,
- c3 = 0
- ;
-
- while ( i < utftext.length )
- {
- c = utftext.charCodeAt(i);
-
- if (c < 128)
- {
- string += String.fromCharCode(c);
- i++;
- }
- else if((c > 191) && (c < 224))
- {
- c2 = utftext.charCodeAt(i+1);
- string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
- i += 2;
- }
- else
- {
- c2 = utftext.charCodeAt(i+1);
- c3 = utftext.charCodeAt(i+2);
- string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
- i += 3;
- }
- }
-
- return string;
- }
- };
-
- module.exports = Base64;
- /*jslint bitwise: false*/
-
-}());
\ No newline at end of file
diff --git a/dev/Common/Base64.jsx b/dev/Common/Base64.jsx
new file mode 100644
index 000000000..37c15178a
--- /dev/null
+++ b/dev/Common/Base64.jsx
@@ -0,0 +1,168 @@
+
+// Base64 encode / decode
+// http://www.webtoolkit.info/
+
+const BASE_64_CHR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
+
+/*jslint bitwise: true*/
+const Base64 = {
+
+ // public method for urlsafe encoding
+ urlsafe_encode: (input) => {
+ return Base64.encode(input).replace(/[+]/g, '-').replace(/[\/]/g, '_').replace(/[=]/g, '.');
+ },
+
+ // public method for encoding
+ encode: (input) => {
+
+ let
+ output = '',
+ chr1, chr2, chr3, enc1, enc2, enc3, enc4,
+ i = 0
+ ;
+
+ input = Base64._utf8_encode(input);
+
+ while (i < input.length)
+ {
+ chr1 = input.charCodeAt(i++);
+ chr2 = input.charCodeAt(i++);
+ chr3 = input.charCodeAt(i++);
+
+ enc1 = chr1 >> 2;
+ enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
+ enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
+ enc4 = chr3 & 63;
+
+ if (isNaN(chr2))
+ {
+ enc3 = enc4 = 64;
+ }
+ else if (isNaN(chr3))
+ {
+ enc4 = 64;
+ }
+
+ output = output +
+ BASE_64_CHR.charAt(enc1) + BASE_64_CHR.charAt(enc2) +
+ BASE_64_CHR.charAt(enc3) + BASE_64_CHR.charAt(enc4);
+ }
+
+ return output;
+ },
+
+ // public method for decoding
+ decode: (input) => {
+
+ let
+ output = '',
+ chr1, chr2, chr3, enc1, enc2, enc3, enc4,
+ i = 0
+ ;
+
+ input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
+
+ while (i < input.length)
+ {
+ enc1 = BASE_64_CHR.indexOf(input.charAt(i++));
+ enc2 = BASE_64_CHR.indexOf(input.charAt(i++));
+ enc3 = BASE_64_CHR.indexOf(input.charAt(i++));
+ enc4 = BASE_64_CHR.indexOf(input.charAt(i++));
+
+ chr1 = (enc1 << 2) | (enc2 >> 4);
+ chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
+ chr3 = ((enc3 & 3) << 6) | enc4;
+
+ output = output + String.fromCharCode(chr1);
+
+ if (enc3 !== 64)
+ {
+ output = output + String.fromCharCode(chr2);
+ }
+
+ if (enc4 !== 64)
+ {
+ output = output + String.fromCharCode(chr3);
+ }
+ }
+
+ return Base64._utf8_decode(output);
+ },
+
+ // private method for UTF-8 encoding
+ _utf8_encode: (string) => {
+
+ string = string.replace(/\r\n/g, "\n");
+
+ let
+ utftext = '',
+ n = 0,
+ l = string.length,
+ c = 0
+ ;
+
+ for (; n < l; n++) {
+
+ c = string.charCodeAt(n);
+
+ if (c < 128)
+ {
+ utftext += String.fromCharCode(c);
+ }
+ else if ((c > 127) && (c < 2048))
+ {
+ utftext += String.fromCharCode((c >> 6) | 192);
+ utftext += String.fromCharCode((c & 63) | 128);
+ }
+ else
+ {
+ utftext += String.fromCharCode((c >> 12) | 224);
+ utftext += String.fromCharCode(((c >> 6) & 63) | 128);
+ utftext += String.fromCharCode((c & 63) | 128);
+ }
+ }
+
+ return utftext;
+ },
+
+ // private method for UTF-8 decoding
+ _utf8_decode: (utftext) => {
+
+ let
+ string = '',
+ i = 0,
+ c = 0,
+ c2 = 0,
+ c3 = 0
+ ;
+
+ while ( i < utftext.length )
+ {
+ c = utftext.charCodeAt(i);
+
+ if (c < 128)
+ {
+ string += String.fromCharCode(c);
+ i++;
+ }
+ else if((c > 191) && (c < 224))
+ {
+ c2 = utftext.charCodeAt(i+1);
+ string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
+ i += 2;
+ }
+ else
+ {
+ c2 = utftext.charCodeAt(i+1);
+ c3 = utftext.charCodeAt(i+2);
+ string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
+ i += 3;
+ }
+ }
+
+ return string;
+ }
+};
+
+module.exports = Base64;
+/*jslint bitwise: false*/
diff --git a/dev/Common/ClientStorageDriver/Cookie.js b/dev/Common/ClientStorageDriver/Cookie.js
deleted file mode 100644
index db1fe8a30..000000000
--- a/dev/Common/ClientStorageDriver/Cookie.js
+++ /dev/null
@@ -1,99 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- $ = require('$'),
- JSON = require('JSON'),
-
- Consts = require('Common/Consts'),
- Utils = require('Common/Utils')
- ;
-
- /**
- * @constructor
- */
- function CookieDriver()
- {
- }
-
- /**
- * @static
- * @return {boolean}
- */
- CookieDriver.supported = function ()
- {
- return !!(window.navigator && window.navigator.cookieEnabled);
- };
-
- /**
- * @param {string} sKey
- * @param {*} mData
- * @return {boolean}
- */
- CookieDriver.prototype.set = function (sKey, mData)
- {
- var
- mStorageValue = $.cookie(Consts.Values.ClientSideStorageIndexName),
- bResult = false,
- mResult = null
- ;
-
- try
- {
- mResult = null === mStorageValue ? null : JSON.parse(mStorageValue);
- }
- catch (e) {}
-
- if (!mResult)
- {
- mResult = {};
- }
-
- mResult[sKey] = mData;
-
- try
- {
- $.cookie(Consts.Values.ClientSideStorageIndexName, JSON.stringify(mResult), {
- 'expires': 30
- });
-
- bResult = true;
- }
- catch (e) {}
-
- return bResult;
- };
-
- /**
- * @param {string} sKey
- * @return {*}
- */
- CookieDriver.prototype.get = function (sKey)
- {
- var
- mStorageValue = $.cookie(Consts.Values.ClientSideStorageIndexName),
- mResult = null
- ;
-
- try
- {
- mResult = null === mStorageValue ? null : JSON.parse(mStorageValue);
- if (mResult && !Utils.isUnd(mResult[sKey]))
- {
- mResult = mResult[sKey];
- }
- else
- {
- mResult = null;
- }
- }
- catch (e) {}
-
- return mResult;
- };
-
- module.exports = CookieDriver;
-
-}());
\ No newline at end of file
diff --git a/dev/Common/ClientStorageDriver/Cookie.jsx b/dev/Common/ClientStorageDriver/Cookie.jsx
new file mode 100644
index 000000000..631fcebf6
--- /dev/null
+++ b/dev/Common/ClientStorageDriver/Cookie.jsx
@@ -0,0 +1,72 @@
+
+import {window, JSON, $} from 'common';
+import Utils from 'Common/Utils';
+import {CLIENT_SIDE_STORAGE_INDEX_NAME} from 'Common/Consts';
+
+class CookieDriver
+{
+ /**
+ * @param {string} key
+ * @param {*} data
+ * @return {boolean}
+ */
+ set(key, data) {
+
+ let
+ result = false,
+ storageResult = null
+ ;
+
+ try
+ {
+ const storageValue = $.cookie(CLIENT_SIDE_STORAGE_INDEX_NAME);
+ storageResult = null === storageValue ? null : JSON.parse(storageValue);
+ }
+ catch (e) {}
+
+ (storageResult || (storageResult = {}))[key] = data;
+
+ try
+ {
+ $.cookie(CLIENT_SIDE_STORAGE_INDEX_NAME, JSON.stringify(storageResult), {
+ 'expires': 30
+ });
+
+ result = true;
+ }
+ catch (e) {}
+
+ return result;
+ }
+
+ /**
+ * @param {string} key
+ * @return {*}
+ */
+ get(sKey) {
+
+ let result = null;
+
+ try
+ {
+ const
+ storageValue = $.cookie(CLIENT_SIDE_STORAGE_INDEX_NAME),
+ storageResult = null === storageValue ? null : JSON.parse(storageValue)
+ ;
+
+ result = (storageResult && !Utils.isUnd(storageResult[key])) ? storageResult[key] : null;
+ }
+ catch (e) {}
+
+ return mResult;
+ };
+
+ /**
+ * @return {boolean}
+ */
+ static supported() {
+ return !!(window.navigator && window.navigator.cookieEnabled);
+ }
+}
+
+export {CookieDriver, CookieDriver as default};
diff --git a/dev/Common/ClientStorageDriver/LocalStorage.js b/dev/Common/ClientStorageDriver/LocalStorage.js
deleted file mode 100644
index 2d873a383..000000000
--- a/dev/Common/ClientStorageDriver/LocalStorage.js
+++ /dev/null
@@ -1,97 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- window = require('window'),
- JSON = require('JSON'),
-
- Consts = require('Common/Consts'),
- Utils = require('Common/Utils')
- ;
-
- /**
- * @constructor
- */
- function LocalStorageDriver()
- {
- }
-
- /**
- * @static
- * @return {boolean}
- */
- LocalStorageDriver.supported = function ()
- {
- return !!window.localStorage;
- };
-
- /**
- * @param {string} sKey
- * @param {*} mData
- * @return {boolean}
- */
- LocalStorageDriver.prototype.set = function (sKey, mData)
- {
- var
- mStorageValue = window.localStorage[Consts.Values.ClientSideStorageIndexName] || null,
- bResult = false,
- mResult = null
- ;
-
- try
- {
- mResult = null === mStorageValue ? null : JSON.parse(mStorageValue);
- }
- catch (e) {}
-
- if (!mResult)
- {
- mResult = {};
- }
-
- mResult[sKey] = mData;
-
- try
- {
- window.localStorage[Consts.Values.ClientSideStorageIndexName] = JSON.stringify(mResult);
-
- bResult = true;
- }
- catch (e) {}
-
- return bResult;
- };
-
- /**
- * @param {string} sKey
- * @return {*}
- */
- LocalStorageDriver.prototype.get = function (sKey)
- {
- var
- mStorageValue = window.localStorage[Consts.Values.ClientSideStorageIndexName] || null,
- mResult = null
- ;
-
- try
- {
- mResult = null === mStorageValue ? null : JSON.parse(mStorageValue);
- if (mResult && !Utils.isUnd(mResult[sKey]))
- {
- mResult = mResult[sKey];
- }
- else
- {
- mResult = null;
- }
- }
- catch (e) {}
-
- return mResult;
- };
-
- module.exports = LocalStorageDriver;
-
-}());
\ No newline at end of file
diff --git a/dev/Common/ClientStorageDriver/LocalStorage.jsx b/dev/Common/ClientStorageDriver/LocalStorage.jsx
new file mode 100644
index 000000000..16e71fdf0
--- /dev/null
+++ b/dev/Common/ClientStorageDriver/LocalStorage.jsx
@@ -0,0 +1,69 @@
+
+import {window, JSON} from 'common';
+import Utils from 'Common/Utils';
+import {CLIENT_SIDE_STORAGE_INDEX_NAME} from 'Common/Consts';
+
+class LocalStorageDriver
+{
+ /**
+ * @param {string} key
+ * @param {*} data
+ * @return {boolean}
+ */
+ set(key, data) {
+
+ let
+ result = false,
+ storageResult = null
+ ;
+
+ try
+ {
+ const storageValue = window.localStorage[CLIENT_SIDE_STORAGE_INDEX_NAME] || null;
+ storageResult = null === storageValue ? null : JSON.parse(storageValue);
+ }
+ catch (e) {}
+
+ (storageResult || (storageResult = {}))[key] = data;
+
+ try
+ {
+ window.localStorage[CLIENT_SIDE_STORAGE_INDEX_NAME] = JSON.stringify(storageResult);
+ result = true;
+ }
+ catch (e) {}
+
+ return result;
+ }
+
+ /**
+ * @param {string} key
+ * @return {*}
+ */
+ get(key) {
+
+ let result = null;
+
+ try
+ {
+ const
+ storageValue = window.localStorage[CLIENT_SIDE_STORAGE_INDEX_NAME] || null,
+ storageResult = null === storageValue ? null : JSON.parse(storageValue)
+ ;
+
+ result = (storageResult && !Utils.isUnd(storageResult[key])) ? storageResult[key] : null
+ }
+ catch (e) {}
+
+ return result;
+ }
+
+ /**
+ * @return {boolean}
+ */
+ static supported() {
+ return !!window.localStorage;
+ }
+}
+
+export {LocalStorageDriver, LocalStorageDriver as default};
diff --git a/dev/Common/Consts.js b/dev/Common/Consts.js
deleted file mode 100644
index dab47f3cf..000000000
--- a/dev/Common/Consts.js
+++ /dev/null
@@ -1,141 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var Consts = {};
-
- Consts.Values = {};
- Consts.DataImages = {};
- Consts.Defaults = {};
-
- /**
- * @const
- * @type {number}
- */
- Consts.Defaults.MessagesPerPage = 20;
-
- /**
- * @const
- * @type {number}
- */
- Consts.Defaults.ContactsPerPage = 50;
-
- /**
- * @const
- * @type {Array}
- */
- Consts.Defaults.MessagesPerPageArray = [10, 20, 30, 50, 100/*, 150, 200, 300*/];
-
- /**
- * @const
- * @type {number}
- */
- Consts.Defaults.DefaultAjaxTimeout = 30000;
-
- /**
- * @const
- * @type {number}
- */
- Consts.Defaults.SearchAjaxTimeout = 300000;
-
- /**
- * @const
- * @type {number}
- */
- Consts.Defaults.SendMessageAjaxTimeout = 300000;
-
- /**
- * @const
- * @type {number}
- */
- Consts.Defaults.SaveMessageAjaxTimeout = 200000;
-
- /**
- * @const
- * @type {number}
- */
- Consts.Defaults.ContactsSyncAjaxTimeout = 200000;
-
- /**
- * @const
- * @type {string}
- */
- Consts.Values.UnuseOptionValue = '__UNUSE__';
-
- /**
- * @const
- * @type {string}
- */
- Consts.Values.ClientSideStorageIndexName = 'rlcsc';
-
- /**
- * @const
- * @type {number}
- */
- Consts.Values.ImapDefaulPort = 143;
-
- /**
- * @const
- * @type {number}
- */
- Consts.Values.ImapDefaulSecurePort = 993;
-
- /**
- * @const
- * @type {number}
- */
- Consts.Values.SieveDefaulPort = 4190;
-
- /**
- * @const
- * @type {number}
- */
- Consts.Values.SmtpDefaulPort = 25;
-
- /**
- * @const
- * @type {number}
- */
- Consts.Values.SmtpDefaulSecurePort = 465;
-
- /**
- * @const
- * @type {number}
- */
- Consts.Values.MessageBodyCacheLimit = 15;
-
- /**
- * @const
- * @type {number}
- */
- Consts.Values.AjaxErrorLimit = 7;
-
- /**
- * @const
- * @type {number}
- */
- Consts.Values.TokenErrorLimit = 10;
-
- /**
- * @const
- * @type {string}
- */
- Consts.Values.RainLoopTrialKey = 'RAINLOOP-TRIAL-KEY';
-
- /**
- * @const
- * @type {string}
- */
-// Consts.DataImages.UserDotPic = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2P8DwQACgAD/il4QJ8AAAAASUVORK5CYII=';
- Consts.DataImages.UserDotPic = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAuCAYAAABXuSs3AAAHHklEQVRoQ7VZW08bVxCeXRuwIbTGXIwNtBBaqjwgVUiR8lDlbza9qe1DpVZ9aNQ/0KpPeaJK07SpcuEeCEmUAObm21bfrL9lONjexSYrWfbunj37zXdmvpkz9oIgCKTD0Wg0xPd94TDP83Q0zvWa50vzklSrdanVanqf4/D84GBGr+F+Op3S8fqoJxLOdnZgTvsO/nYhenHA+UC7CWF1uXwkb9++ldPTUwVerVbVqFQqpR8YPjQ0JCMjI5LNDijoRgP3PQVu5+5Eor2XGLg7IV4GkIdHJ/LmzRs5ODiIwNbrdR0O0GCcq4Xz4eFhmZyclP7+tDQaIik/BG5XKQn4SwG3zJTLZXn9+rUclI8UHD5YVoDDN8bSzXhONwL48fFxGR4eilzFZT1uFRIB5yT8BqCdnR3Z3d0VP9Un6XRawYJpggVrZBv38ME4XKtUKnLt2jUplUoy1PR/l3U7T6sVSAQcgMAkj8PDQ9ne3pajoyMRL7zeKsYZWHgWYDGmv78/mmdwcFA+mJlSgziHDWrERrsjEXDXegTi1tZW+DLxI2bxIrqFNYTXyDyCFweMAHCwb8e4RnTNuOsqe3t7sra21pTD0Kct666E8XlcZyzw9/RUUXK5nK5oUinUQI6TQ3cynO/v78vq6qrKXCNwlTiJJpyNGc3nZHp6uqV2dwrQWOCtZBDAV1ZWwsQk7f0wiQn5kffbAu/0/KWBYzIC1+XukfGx0RGZmppKlC2tIV0Bh4aDcZW7HhkfH8urLLZL7T2pihvlkMNnz56FiadHxicL41IsFpN41bkxsYxbRdFo9jwB8KdPn14J8KnSpBQKhQs63nPmbCVRcBUAR2Lq1VVmpksyMTFxAXjcEsQybiegESionjx5osCZOeNe1O4+EhCAX7bQSgQcxRHTMgAgcz5+/Dis/hL4uHU3/B4YGNASGHIKxuEql0k+l05AeIAF1vPnz5VxFFmdDlaJrMtZITJeSsXCOTlMunKxjLtMYOKNjQ158eJFuAuKkUOb5sEwgff19SkJUBVkThZUbnXZrtCKBQ6gbnWIkjZpyne3ejAWoGnA7Icz6irvBLgbOMicCM6TkxPx/LAkbXfgWcsazuE2kFRsKD5Z+CiqDumKncpZvieWcS6dDVD8xiYCNflpJdwcdwJOf9airLmVQ7DPzMxIYWLsXGXoVqLt5k0M3K3JUVPDZdbWNzsCp48TPFdvdnZWUz32nDha7bJ63kgAJPzSdRks9/Kf9xMJAQ1gq2NpaUmy2Yz4zar4nQC3xb99AQwCcGzLAAwuhG8YiWvcOKts+r4GOe5nMhm5efOm9lUA3E3vSZJRrKvE0fnPv//Jy5cvo5cTHIPQbSjhOoqq69evS19f6lxDKK4+sVhigZPtKJqbrQeqxd5+WR4+fKgqgT0k2XX3nhiPgETWXFhYkFzuPZ2yVq1GTSOXpE47/VjgNnD4m4GG7/LhsTx69EiwD4Vr2MwIIxgbAH18fKx1yfz8vEogNvGtWnCuhLZa9UTAreVWFsHy/b/+Vrbdl7E5REMQD2jDoUbByty+/ZnU64GkU2HzyJLhktU1cLv8nARgkYS2d3ajAgwG8qU2oLmDZ92CMaOjo7K4uCiZgbDWaRWgnZhPxLhrMUCvr69riwKZk1LHF7XqrWAO9hJxH6ozNzcnCx/PqztZg9mf6SQMscCtm2C5ke4BGMlHWTUp36036AJajDVrFMzBrhhWslQsSrFYiOqVpMriNYIgqFRq2j3FAb/zffT6zuxFXxsNzs3NTXn16lW4gYiW96w1FyedF+83xG/2FNGCRpU4NjamMsn+OZ9xE5RXqdaDdPpib6RWCzuwKF9RxqI2AVNQBwQYJoK0wdBejnqtEikP3pfP51XjUTESl12FqJEKxsEorARYDD44ONTeID7YpsEnrRvQfWAI2e8WfDaTUSIwJ0iBCmFOtOUAHvVMPp/TPwvYFVYFIuP8l+DBgwdaa2Miqwa0GgYwfeMltovbDfh6c1vIgMYcliSsKv4IWFr6VDHxvldvBAH+1sA+cnl5WYOPmmr9ir+1l9I0Cgz0yjhXjfJJ0JROnmezWbl165ayr/5fqwcBNr7IfhjMqKcvESSM4eRcCasQ3bDNObmKPLdGUGpZsN24cUNLBm9zazu4d++e6qpNBFaTuUS26U5dpuR1CxyA7J9ddrMRqlz4pwLLYawymPd++/2PADt2ugcGwq9gCCdhQ96C6xWwa6j1ceuq+I0EhW0i8MAIVJfeL3d/DVD8EKi12P6/2S2jV/EccVB54O/ejz/9HGCpoBBMta5rXMXLu53D1XAwjhXwvvv+h4BAXVe4bOu3O3ChxF08LiZFG3fel199G9CH3fLyqv24NcB44MRhpdK788U3CpyKwsCw590xmfSpzsBt0Fqc3ud3vtZigxWcVZCklVpSiN0w3q5E/h9TGMIUuA3+EQAAAABJRU5ErkJggg==';
-
- /**
- * @const
- * @type {string}
- */
- Consts.DataImages.TranspPic = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2NkAAIAAAoAAggA9GkAAAAASUVORK5CYII=';
-
- module.exports = Consts;
-
-}(module));
\ No newline at end of file
diff --git a/dev/Common/Consts.jsx b/dev/Common/Consts.jsx
new file mode 100644
index 000000000..19fc462e1
--- /dev/null
+++ b/dev/Common/Consts.jsx
@@ -0,0 +1,42 @@
+
+export const MESSAGES_PER_PAGE = 20;
+
+export const MESSAGES_PER_PAGE_VALUES = [10, 20, 30, 50, 100/*, 150, 200, 300*/];
+
+export const CONTACTS_PER_PAGE = 50;
+
+export const DEFAULT_AJAX_TIMEOUT = 30000;
+
+export const SEARCH_AJAX_TIMEOUT = 300000;
+
+export const SEND_MESSAGE_AJAX_TIMEOUT = 300000;
+
+export const SAVE_MESSAGE_AJAX_TIMEOUT = 200000;
+
+export const CONTACTS_SYNC_AJAX_TIMEOUT = 200000;
+
+export const UNUSED_OPTION_VALUE = '__UNUSE__';
+
+export const CLIENT_SIDE_STORAGE_INDEX_NAME = 'rlcsc';
+
+export const IMAP_DEFAULT_PORT = 143;
+
+export const IMAP_DEFAULT_SECURE_PORT = 993;
+
+export const SMTP_DEFAULT_PORT = 25;
+
+export const SMTP_DEFAULT_SECURE_PORT = 465;
+
+export const SIEVE_DEFAULT_PORT = 4190;
+
+export const MESSAGE_BODY_CACHE_LIMIT = 15;
+
+export const AJAX_ERROR_LIMIT = 7;
+
+export const TOKEN_ERROR_LIMIT = 10;
+
+export const RAINLOOP_TRIAL_KEY = 'RAINLOOP-TRIAL-KEY';
+
+export const DATA_IMAGE_USER_DOT_PIC = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAuCAYAAABXuSs3AAAHHklEQVRoQ7VZW08bVxCeXRuwIbTGXIwNtBBaqjwgVUiR8lDlbza9qe1DpVZ9aNQ/0KpPeaJK07SpcuEeCEmUAObm21bfrL9lONjexSYrWfbunj37zXdmvpkz9oIgCKTD0Wg0xPd94TDP83Q0zvWa50vzklSrdanVanqf4/D84GBGr+F+Op3S8fqoJxLOdnZgTvsO/nYhenHA+UC7CWF1uXwkb9++ldPTUwVerVbVqFQqpR8YPjQ0JCMjI5LNDijoRgP3PQVu5+5Eor2XGLg7IV4GkIdHJ/LmzRs5ODiIwNbrdR0O0GCcq4Xz4eFhmZyclP7+tDQaIik/BG5XKQn4SwG3zJTLZXn9+rUclI8UHD5YVoDDN8bSzXhONwL48fFxGR4eilzFZT1uFRIB5yT8BqCdnR3Z3d0VP9Un6XRawYJpggVrZBv38ME4XKtUKnLt2jUplUoy1PR/l3U7T6sVSAQcgMAkj8PDQ9ne3pajoyMRL7zeKsYZWHgWYDGmv78/mmdwcFA+mJlSgziHDWrERrsjEXDXegTi1tZW+DLxI2bxIrqFNYTXyDyCFweMAHCwb8e4RnTNuOsqe3t7sra21pTD0Kct666E8XlcZyzw9/RUUXK5nK5oUinUQI6TQ3cynO/v78vq6qrKXCNwlTiJJpyNGc3nZHp6uqV2dwrQWOCtZBDAV1ZWwsQk7f0wiQn5kffbAu/0/KWBYzIC1+XukfGx0RGZmppKlC2tIV0Bh4aDcZW7HhkfH8urLLZL7T2pihvlkMNnz56FiadHxicL41IsFpN41bkxsYxbRdFo9jwB8KdPn14J8KnSpBQKhQs63nPmbCVRcBUAR2Lq1VVmpksyMTFxAXjcEsQybiegESionjx5osCZOeNe1O4+EhCAX7bQSgQcxRHTMgAgcz5+/Dis/hL4uHU3/B4YGNASGHIKxuEql0k+l05AeIAF1vPnz5VxFFmdDlaJrMtZITJeSsXCOTlMunKxjLtMYOKNjQ158eJFuAuKkUOb5sEwgff19SkJUBVkThZUbnXZrtCKBQ6gbnWIkjZpyne3ejAWoGnA7Icz6irvBLgbOMicCM6TkxPx/LAkbXfgWcsazuE2kFRsKD5Z+CiqDumKncpZvieWcS6dDVD8xiYCNflpJdwcdwJOf9airLmVQ7DPzMxIYWLsXGXoVqLt5k0M3K3JUVPDZdbWNzsCp48TPFdvdnZWUz32nDha7bJ63kgAJPzSdRks9/Kf9xMJAQ1gq2NpaUmy2Yz4zar4nQC3xb99AQwCcGzLAAwuhG8YiWvcOKts+r4GOe5nMhm5efOm9lUA3E3vSZJRrKvE0fnPv//Jy5cvo5cTHIPQbSjhOoqq69evS19f6lxDKK4+sVhigZPtKJqbrQeqxd5+WR4+fKgqgT0k2XX3nhiPgETWXFhYkFzuPZ2yVq1GTSOXpE47/VjgNnD4m4GG7/LhsTx69EiwD4Vr2MwIIxgbAH18fKx1yfz8vEogNvGtWnCuhLZa9UTAreVWFsHy/b/+Vrbdl7E5REMQD2jDoUbByty+/ZnU64GkU2HzyJLhktU1cLv8nARgkYS2d3ajAgwG8qU2oLmDZ92CMaOjo7K4uCiZgbDWaRWgnZhPxLhrMUCvr69riwKZk1LHF7XqrWAO9hJxH6ozNzcnCx/PqztZg9mf6SQMscCtm2C5ke4BGMlHWTUp36036AJajDVrFMzBrhhWslQsSrFYiOqVpMriNYIgqFRq2j3FAb/zffT6zuxFXxsNzs3NTXn16lW4gYiW96w1FyedF+83xG/2FNGCRpU4NjamMsn+OZ9xE5RXqdaDdPpib6RWCzuwKF9RxqI2AVNQBwQYJoK0wdBejnqtEikP3pfP51XjUTESl12FqJEKxsEorARYDD44ONTeID7YpsEnrRvQfWAI2e8WfDaTUSIwJ0iBCmFOtOUAHvVMPp/TPwvYFVYFIuP8l+DBgwdaa2Miqwa0GgYwfeMltovbDfh6c1vIgMYcliSsKv4IWFr6VDHxvldvBAH+1sA+cnl5WYOPmmr9ir+1l9I0Cgz0yjhXjfJJ0JROnmezWbl165ayr/5fqwcBNr7IfhjMqKcvESSM4eRcCasQ3bDNObmKPLdGUGpZsN24cUNLBm9zazu4d++e6qpNBFaTuUS26U5dpuR1CxyA7J9ddrMRqlz4pwLLYawymPd++/2PADt2ugcGwq9gCCdhQ96C6xWwa6j1ceuq+I0EhW0i8MAIVJfeL3d/DVD8EKi12P6/2S2jV/EccVB54O/ejz/9HGCpoBBMta5rXMXLu53D1XAwjhXwvvv+h4BAXVe4bOu3O3ChxF08LiZFG3fel199G9CH3fLyqv24NcB44MRhpdK788U3CpyKwsCw590xmfSpzsBt0Fqc3ud3vtZigxWcVZCklVpSiN0w3q5E/h9TGMIUuA3+EQAAAABJRU5ErkJggg==';
+
+export const DATA_IMAGE_TRANSP_PIC = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2NkAAIAAAoAAggA9GkAAAAASUVORK5CYII=';
diff --git a/dev/Common/Enums.js b/dev/Common/Enums.js
deleted file mode 100644
index b052389e2..000000000
--- a/dev/Common/Enums.js
+++ /dev/null
@@ -1,502 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var Enums = {};
-
- /**
- * @enum {string}
- */
- Enums.FileType = {
- 'Unknown': 'unknown',
- 'Text': 'text',
- 'Html': 'html',
- 'Code': 'code',
- 'Eml': 'eml',
- 'WordText': 'word-text',
- 'Pdf': 'pdf',
- 'Image': 'image',
- 'Audio': 'audio',
- 'Video': 'video',
- 'Sheet': 'sheet',
- 'Presentation': 'presentation',
- 'Certificate': 'certificate',
- 'CertificateBin': 'certificate-bin',
- 'Archive': 'archive'
- };
-
- /**
- * @enum {string}
- */
- Enums.StorageResultType = {
- 'Success': 'success',
- 'Abort': 'abort',
- 'Error': 'error',
- 'Unload': 'unload'
- };
-
- /**
- * @enum {string}
- */
- Enums.Focused = {
- 'None': 'none',
- 'MessageList': 'message-list',
- 'MessageView': 'message-view',
- 'FolderList': 'folder-list'
- };
-
- /**
- * @enum {number}
- */
- Enums.State = {
- 'Empty': 10,
- 'Login': 20,
- 'Auth': 30
- };
-
- /**
- * @enum {number}
- */
- Enums.StateType = {
- 'Webmail': 0,
- 'Admin': 1
- };
-
- /**
- * @enum {string}
- */
- Enums.Capa = {
- 'TwoFactor': 'TWO_FACTOR',
- 'TwoFactorForce': 'TWO_FACTOR_FORCE',
- 'OpenPGP': 'OPEN_PGP',
- 'Prefetch': 'PREFETCH',
- 'Gravatar': 'GRAVATAR',
- 'Folders': 'FOLDERS',
- 'Composer': 'COMPOSER',
- 'Contacts': 'CONTACTS',
- 'Reload': 'RELOAD',
- 'Search': 'SEARCH',
- 'SearchAdv': 'SEARCH_ADV',
- 'MessageActions': 'MESSAGE_ACTIONS',
- 'MessageListActions': 'MESSAGELIST_ACTIONS',
- 'AttachmentsActions': 'ATTACHMENTS_ACTIONS',
- 'DangerousActions': 'DANGEROUS_ACTIONS',
- 'Settings': 'SETTINGS',
- 'Help': 'HELP',
- 'Themes': 'THEMES',
- 'UserBackground': 'USER_BACKGROUND',
- 'Sieve': 'SIEVE',
- 'Filters': 'FILTERS',
- 'AttachmentThumbnails': 'ATTACHMENT_THUMBNAILS',
- 'Templates': 'TEMPLATES',
- 'AutoLogout': 'AUTOLOGOUT',
- 'AdditionalAccounts': 'ADDITIONAL_ACCOUNTS',
- 'Identities': 'IDENTITIES'
- };
-
- /**
- * @enum {string}
- */
- Enums.KeyState = {
- 'All': 'all',
- 'None': 'none',
- 'ContactList': 'contact-list',
- 'MessageList': 'message-list',
- 'FolderList': 'folder-list',
- 'MessageView': 'message-view',
- 'Compose': 'compose',
- 'Settings': 'settings',
- 'Menu': 'menu',
- 'PopupComposeOpenPGP': 'compose-open-pgp',
- 'PopupMessageOpenPGP': 'message-open-pgp',
- 'PopupViewOpenPGP': 'view-open-pgp',
- 'PopupKeyboardShortcutsHelp': 'popup-keyboard-shortcuts-help',
- 'PopupAsk': 'popup-ask'
- };
-
- /**
- * @enum {number}
- */
- Enums.FolderType = {
- 'Inbox': 10,
- 'SentItems': 11,
- 'Draft': 12,
- 'Trash': 13,
- 'Spam': 14,
- 'Archive': 15,
- 'NotSpam': 80,
- 'User': 99
- };
-
- /**
- * @enum {number}
- */
- Enums.ServerFolderType = {
- 'USER': 0,
- 'INBOX': 1,
- 'SENT': 2,
- 'DRAFTS': 3,
- 'JUNK': 4,
- 'TRASH': 5,
- 'IMPORTANT': 10,
- 'FLAGGED': 11,
- 'ALL': 12
- };
-
- /**
- * @enum {string}
- */
- Enums.LoginSignMeTypeAsString = {
- 'DefaultOff': 'defaultoff',
- 'DefaultOn': 'defaulton',
- 'Unused': 'unused'
- };
-
- /**
- * @enum {number}
- */
- Enums.LoginSignMeType = {
- 'DefaultOff': 0,
- 'DefaultOn': 1,
- 'Unused': 2
- };
-
- /**
- * @enum {string}
- */
- Enums.ComposeType = {
- 'Empty': 'empty',
- 'Reply': 'reply',
- 'ReplyAll': 'replyall',
- 'Forward': 'forward',
- 'ForwardAsAttachment': 'forward-as-attachment',
- 'Draft': 'draft',
- 'EditAsNew': 'editasnew'
- };
-
- /**
- * @enum {number}
- */
- Enums.UploadErrorCode = {
- 'Normal': 0,
- 'FileIsTooBig': 1,
- 'FilePartiallyUploaded': 2,
- 'FileNoUploaded': 3,
- 'MissingTempFolder': 4,
- 'FileOnSaveingError': 5,
- 'FileType': 98,
- 'Unknown': 99
- };
-
- /**
- * @enum {number}
- */
- Enums.SetSystemFoldersNotification = {
- 'None': 0,
- 'Sent': 1,
- 'Draft': 2,
- 'Spam': 3,
- 'Trash': 4,
- 'Archive': 5
- };
-
- /**
- * @enum {number}
- */
- Enums.ClientSideKeyName = {
- 'FoldersLashHash': 0,
- 'MessagesInboxLastHash': 1,
- 'MailBoxListSize': 2,
- 'ExpandedFolders': 3,
- 'FolderListSize': 4,
- 'MessageListSize': 5,
- 'LastReplyAction': 6,
- 'LastSignMe': 7,
- 'ComposeLastIdentityID': 8
- };
-
- /**
- * @enum {number}
- */
- Enums.EventKeyCode = {
- 'Backspace': 8,
- 'Tab': 9,
- 'Enter': 13,
- 'Esc': 27,
- 'PageUp': 33,
- 'PageDown': 34,
- 'Left': 37,
- 'Right': 39,
- 'Up': 38,
- 'Down': 40,
- 'End': 35,
- 'Home': 36,
- 'Space': 32,
- 'Insert': 45,
- 'Delete': 46,
- 'A': 65,
- 'S': 83
- };
-
- /**
- * @enum {number}
- */
- Enums.MessageSetAction = {
- 'SetSeen': 0,
- 'UnsetSeen': 1,
- 'SetFlag': 2,
- 'UnsetFlag': 3
- };
-
- /**
- * @enum {number}
- */
- Enums.MessageSelectAction = {
- 'All': 0,
- 'None': 1,
- 'Invert': 2,
- 'Unseen': 3,
- 'Seen': 4,
- 'Flagged': 5,
- 'Unflagged': 6
- };
-
- /**
- * @enum {number}
- */
- Enums.DesktopNotification = {
- 'Allowed': 0,
- 'NotAllowed': 1,
- 'Denied': 2,
- 'NotSupported': 9
- };
-
- /**
- * @enum {number}
- */
- Enums.MessagePriority = {
- 'Low': 5,
- 'Normal': 3,
- 'High': 1
- };
-
- /**
- * @enum {string}
- */
- Enums.EditorDefaultType = {
- 'Html': 'Html',
- 'Plain': 'Plain',
- 'HtmlForced': 'HtmlForced',
- 'PlainForced': 'PlainForced'
- };
-
- /**
- * @enum {number}
- */
- Enums.ServerSecure = {
- 'None': 0,
- 'SSL': 1,
- 'TLS': 2
- };
-
- /**
- * @enum {number}
- */
- Enums.SearchDateType = {
- 'All': -1,
- 'Days3': 3,
- 'Days7': 7,
- 'Month': 30
- };
-
- /**
- * @enum {number}
- */
- Enums.SaveSettingsStep = {
- 'Animate': -2,
- 'Idle': -1,
- 'TrueResult': 1,
- 'FalseResult': 0
- };
-
- /**
- * @enum {number}
- */
- Enums.Layout = {
- 'NoPreview': 0,
- 'SidePreview': 1,
- 'BottomPreview': 2,
- 'Mobile': 3
- };
-
- /**
- * @enum {string}
- */
- Enums.FilterConditionField = {
- 'From': 'From',
- 'Recipient': 'Recipient',
- 'Subject': 'Subject',
- 'Header': 'Header',
- 'Size': 'Size'
- };
-
- /**
- * @enum {string}
- */
- Enums.FilterConditionType = {
- 'Contains': 'Contains',
- 'NotContains': 'NotContains',
- 'EqualTo': 'EqualTo',
- 'NotEqualTo': 'NotEqualTo',
- 'Over': 'Over',
- 'Under': 'Under'
- };
-
- /**
- * @enum {string}
- */
- Enums.FiltersAction = {
- 'None': 'None',
- 'MoveTo': 'MoveTo',
- 'Discard': 'Discard',
- 'Vacation': 'Vacation',
- 'Reject': 'Reject',
- 'Forward': 'Forward'
- };
-
- /**
- * @enum {string}
- */
- Enums.FilterRulesType = {
- 'All': 'All',
- 'Any': 'Any'
- };
-
- /**
- * @enum {number}
- */
- Enums.SignedVerifyStatus = {
- 'UnknownPublicKeys': -4,
- 'UnknownPrivateKey': -3,
- 'Unverified': -2,
- 'Error': -1,
- 'None': 0,
- 'Success': 1
- };
-
- /**
- * @enum {number}
- */
- Enums.ContactPropertyType = {
-
- 'Unknown': 0,
-
- 'FullName': 10,
-
- 'FirstName': 15,
- 'LastName': 16,
- 'MiddleName': 16,
- 'Nick': 18,
-
- 'NamePrefix': 20,
- 'NameSuffix': 21,
-
- 'Email': 30,
- 'Phone': 31,
- 'Web': 32,
-
- 'Birthday': 40,
-
- 'Facebook': 90,
- 'Skype': 91,
- 'GitHub': 92,
-
- 'Note': 110,
-
- 'Custom': 250
- };
-
- /**
- * @enum {number}
- */
- Enums.Notification = {
- 'InvalidToken': 101,
- 'AuthError': 102,
- 'AccessError': 103,
- 'ConnectionError': 104,
- 'CaptchaError': 105,
- 'SocialFacebookLoginAccessDisable': 106,
- 'SocialTwitterLoginAccessDisable': 107,
- 'SocialGoogleLoginAccessDisable': 108,
- 'DomainNotAllowed': 109,
- 'AccountNotAllowed': 110,
-
- 'AccountTwoFactorAuthRequired': 120,
- 'AccountTwoFactorAuthError': 121,
-
- 'CouldNotSaveNewPassword': 130,
- 'CurrentPasswordIncorrect': 131,
- 'NewPasswordShort': 132,
- 'NewPasswordWeak': 133,
- 'NewPasswordForbidden': 134,
-
- 'ContactsSyncError': 140,
-
- 'CantGetMessageList': 201,
- 'CantGetMessage': 202,
- 'CantDeleteMessage': 203,
- 'CantMoveMessage': 204,
- 'CantCopyMessage': 205,
-
- 'CantSaveMessage': 301,
- 'CantSendMessage': 302,
- 'InvalidRecipients': 303,
-
- 'CantSaveFilters': 351,
- 'CantGetFilters': 352,
- 'FiltersAreNotCorrect': 355,
-
- 'CantCreateFolder': 400,
- 'CantRenameFolder': 401,
- 'CantDeleteFolder': 402,
- 'CantSubscribeFolder': 403,
- 'CantUnsubscribeFolder': 404,
- 'CantDeleteNonEmptyFolder': 405,
-
- 'CantSaveSettings': 501,
- 'CantSavePluginSettings': 502,
-
- 'DomainAlreadyExists': 601,
-
- 'CantInstallPackage': 701,
- 'CantDeletePackage': 702,
- 'InvalidPluginPackage': 703,
- 'UnsupportedPluginPackage': 704,
-
- 'LicensingServerIsUnavailable': 710,
- 'LicensingExpired': 711,
- 'LicensingBanned': 712,
-
- 'DemoSendMessageError': 750,
- 'DemoAccountError': 751,
-
- 'AccountAlreadyExists': 801,
- 'AccountDoesNotExist': 802,
-
- 'MailServerError': 901,
- 'ClientViewError': 902,
- 'InvalidInputArgument': 903,
-
- 'AjaxFalse': 950,
- 'AjaxAbort': 951,
- 'AjaxParse': 952,
- 'AjaxTimeout': 953,
-
- 'UnknownNotification': 999,
- 'UnknownError': 999
- };
-
- module.exports = Enums;
-
-}());
\ No newline at end of file
diff --git a/dev/Common/Enums.jsx b/dev/Common/Enums.jsx
new file mode 100644
index 000000000..210315dbe
--- /dev/null
+++ b/dev/Common/Enums.jsx
@@ -0,0 +1,492 @@
+
+/**
+ * @enum {string}
+ */
+export const FileType = {
+ 'Unknown': 'unknown',
+ 'Text': 'text',
+ 'Html': 'html',
+ 'Code': 'code',
+ 'Eml': 'eml',
+ 'WordText': 'word-text',
+ 'Pdf': 'pdf',
+ 'Image': 'image',
+ 'Audio': 'audio',
+ 'Video': 'video',
+ 'Sheet': 'sheet',
+ 'Presentation': 'presentation',
+ 'Certificate': 'certificate',
+ 'CertificateBin': 'certificate-bin',
+ 'Archive': 'archive'
+}
+
+/**
+ * @enum {string}
+ */
+export const StorageResultType = {
+ 'Success': 'success',
+ 'Abort': 'abort',
+ 'Error': 'error',
+ 'Unload': 'unload'
+}
+
+/**
+ * @enum {string}
+ */
+export const Focused = {
+ 'None': 'none',
+ 'MessageList': 'message-list',
+ 'MessageView': 'message-view',
+ 'FolderList': 'folder-list'
+}
+
+/**
+ * @enum {number}
+ */
+export const State = {
+ 'Empty': 10,
+ 'Login': 20,
+ 'Auth': 30
+}
+
+/**
+ * @enum {number}
+ */
+export const StateType = {
+ 'Webmail': 0,
+ 'Admin': 1
+}
+
+/**
+ * @enum {string}
+ */
+export const Capa = {
+ 'TwoFactor': 'TWO_FACTOR',
+ 'TwoFactorForce': 'TWO_FACTOR_FORCE',
+ 'OpenPGP': 'OPEN_PGP',
+ 'Prefetch': 'PREFETCH',
+ 'Gravatar': 'GRAVATAR',
+ 'Folders': 'FOLDERS',
+ 'Composer': 'COMPOSER',
+ 'Contacts': 'CONTACTS',
+ 'Reload': 'RELOAD',
+ 'Search': 'SEARCH',
+ 'SearchAdv': 'SEARCH_ADV',
+ 'MessageActions': 'MESSAGE_ACTIONS',
+ 'MessageListActions': 'MESSAGELIST_ACTIONS',
+ 'AttachmentsActions': 'ATTACHMENTS_ACTIONS',
+ 'DangerousActions': 'DANGEROUS_ACTIONS',
+ 'Settings': 'SETTINGS',
+ 'Help': 'HELP',
+ 'Themes': 'THEMES',
+ 'UserBackground': 'USER_BACKGROUND',
+ 'Sieve': 'SIEVE',
+ 'Filters': 'FILTERS',
+ 'AttachmentThumbnails': 'ATTACHMENT_THUMBNAILS',
+ 'Templates': 'TEMPLATES',
+ 'AutoLogout': 'AUTOLOGOUT',
+ 'AdditionalAccounts': 'ADDITIONAL_ACCOUNTS',
+ 'Identities': 'IDENTITIES'
+}
+
+/**
+ * @enum {string}
+ */
+export const KeyState = {
+ 'All': 'all',
+ 'None': 'none',
+ 'ContactList': 'contact-list',
+ 'MessageList': 'message-list',
+ 'FolderList': 'folder-list',
+ 'MessageView': 'message-view',
+ 'Compose': 'compose',
+ 'Settings': 'settings',
+ 'Menu': 'menu',
+ 'PopupComposeOpenPGP': 'compose-open-pgp',
+ 'PopupMessageOpenPGP': 'message-open-pgp',
+ 'PopupViewOpenPGP': 'view-open-pgp',
+ 'PopupKeyboardShortcutsHelp': 'popup-keyboard-shortcuts-help',
+ 'PopupAsk': 'popup-ask'
+}
+
+/**
+ * @enum {number}
+ */
+export const FolderType = {
+ 'Inbox': 10,
+ 'SentItems': 11,
+ 'Draft': 12,
+ 'Trash': 13,
+ 'Spam': 14,
+ 'Archive': 15,
+ 'NotSpam': 80,
+ 'User': 99
+}
+
+/**
+ * @enum {number}
+ */
+export const ServerFolderType = {
+ 'USER': 0,
+ 'INBOX': 1,
+ 'SENT': 2,
+ 'DRAFTS': 3,
+ 'JUNK': 4,
+ 'TRASH': 5,
+ 'IMPORTANT': 10,
+ 'FLAGGED': 11,
+ 'ALL': 12
+}
+
+/**
+ * @enum {string}
+ */
+export const LoginSignMeTypeAsString = {
+ 'DefaultOff': 'defaultoff',
+ 'DefaultOn': 'defaulton',
+ 'Unused': 'unused'
+}
+
+/**
+ * @enum {number}
+ */
+export const LoginSignMeType = {
+ 'DefaultOff': 0,
+ 'DefaultOn': 1,
+ 'Unused': 2
+}
+
+/**
+ * @enum {string}
+ */
+export const ComposeType = {
+ 'Empty': 'empty',
+ 'Reply': 'reply',
+ 'ReplyAll': 'replyall',
+ 'Forward': 'forward',
+ 'ForwardAsAttachment': 'forward-as-attachment',
+ 'Draft': 'draft',
+ 'EditAsNew': 'editasnew'
+}
+
+/**
+ * @enum {number}
+ */
+export const UploadErrorCode = {
+ 'Normal': 0,
+ 'FileIsTooBig': 1,
+ 'FilePartiallyUploaded': 2,
+ 'FileNoUploaded': 3,
+ 'MissingTempFolder': 4,
+ 'FileOnSaveingError': 5,
+ 'FileType': 98,
+ 'Unknown': 99
+}
+
+/**
+ * @enum {number}
+ */
+export const SetSystemFoldersNotification = {
+ 'None': 0,
+ 'Sent': 1,
+ 'Draft': 2,
+ 'Spam': 3,
+ 'Trash': 4,
+ 'Archive': 5
+}
+
+/**
+ * @enum {number}
+ */
+export const ClientSideKeyName = {
+ 'FoldersLashHash': 0,
+ 'MessagesInboxLastHash': 1,
+ 'MailBoxListSize': 2,
+ 'ExpandedFolders': 3,
+ 'FolderListSize': 4,
+ 'MessageListSize': 5,
+ 'LastReplyAction': 6,
+ 'LastSignMe': 7,
+ 'ComposeLastIdentityID': 8
+}
+
+/**
+ * @enum {number}
+ */
+export const EventKeyCode = {
+ 'Backspace': 8,
+ 'Tab': 9,
+ 'Enter': 13,
+ 'Esc': 27,
+ 'PageUp': 33,
+ 'PageDown': 34,
+ 'Left': 37,
+ 'Right': 39,
+ 'Up': 38,
+ 'Down': 40,
+ 'End': 35,
+ 'Home': 36,
+ 'Space': 32,
+ 'Insert': 45,
+ 'Delete': 46,
+ 'A': 65,
+ 'S': 83
+}
+
+/**
+ * @enum {number}
+ */
+export const MessageSetAction = {
+ 'SetSeen': 0,
+ 'UnsetSeen': 1,
+ 'SetFlag': 2,
+ 'UnsetFlag': 3
+}
+
+/**
+ * @enum {number}
+ */
+export const MessageSelectAction = {
+ 'All': 0,
+ 'None': 1,
+ 'Invert': 2,
+ 'Unseen': 3,
+ 'Seen': 4,
+ 'Flagged': 5,
+ 'Unflagged': 6
+}
+
+/**
+ * @enum {number}
+ */
+export const DesktopNotification = {
+ 'Allowed': 0,
+ 'NotAllowed': 1,
+ 'Denied': 2,
+ 'NotSupported': 9
+}
+
+/**
+ * @enum {number}
+ */
+export const MessagePriority = {
+ 'Low': 5,
+ 'Normal': 3,
+ 'High': 1
+}
+
+/**
+ * @enum {string}
+ */
+export const EditorDefaultType = {
+ 'Html': 'Html',
+ 'Plain': 'Plain',
+ 'HtmlForced': 'HtmlForced',
+ 'PlainForced': 'PlainForced'
+}
+
+/**
+ * @enum {number}
+ */
+export const ServerSecure = {
+ 'None': 0,
+ 'SSL': 1,
+ 'TLS': 2
+}
+
+/**
+ * @enum {number}
+ */
+export const SearchDateType = {
+ 'All': -1,
+ 'Days3': 3,
+ 'Days7': 7,
+ 'Month': 30
+}
+
+/**
+ * @enum {number}
+ */
+export const SaveSettingsStep = {
+ 'Animate': -2,
+ 'Idle': -1,
+ 'TrueResult': 1,
+ 'FalseResult': 0
+}
+
+/**
+ * @enum {number}
+ */
+export const Layout = {
+ 'NoPreview': 0,
+ 'SidePreview': 1,
+ 'BottomPreview': 2,
+ 'Mobile': 3
+}
+
+/**
+ * @enum {string}
+ */
+export const FilterConditionField = {
+ 'From': 'From',
+ 'Recipient': 'Recipient',
+ 'Subject': 'Subject',
+ 'Header': 'Header',
+ 'Size': 'Size'
+}
+
+/**
+ * @enum {string}
+ */
+export const FilterConditionType = {
+ 'Contains': 'Contains',
+ 'NotContains': 'NotContains',
+ 'EqualTo': 'EqualTo',
+ 'NotEqualTo': 'NotEqualTo',
+ 'Over': 'Over',
+ 'Under': 'Under'
+}
+
+/**
+ * @enum {string}
+ */
+export const FiltersAction = {
+ 'None': 'None',
+ 'MoveTo': 'MoveTo',
+ 'Discard': 'Discard',
+ 'Vacation': 'Vacation',
+ 'Reject': 'Reject',
+ 'Forward': 'Forward'
+}
+
+/**
+ * @enum {string}
+ */
+export const FilterRulesType = {
+ 'All': 'All',
+ 'Any': 'Any'
+}
+
+/**
+ * @enum {number}
+ */
+export const SignedVerifyStatus = {
+ 'UnknownPublicKeys': -4,
+ 'UnknownPrivateKey': -3,
+ 'Unverified': -2,
+ 'Error': -1,
+ 'None': 0,
+ 'Success': 1
+}
+
+/**
+ * @enum {number}
+ */
+export const ContactPropertyType = {
+
+ 'Unknown': 0,
+
+ 'FullName': 10,
+
+ 'FirstName': 15,
+ 'LastName': 16,
+ 'MiddleName': 16,
+ 'Nick': 18,
+
+ 'NamePrefix': 20,
+ 'NameSuffix': 21,
+
+ 'Email': 30,
+ 'Phone': 31,
+ 'Web': 32,
+
+ 'Birthday': 40,
+
+ 'Facebook': 90,
+ 'Skype': 91,
+ 'GitHub': 92,
+
+ 'Note': 110,
+
+ 'Custom': 250
+}
+
+/**
+ * @enum {number}
+ */
+export const Notification = {
+ 'InvalidToken': 101,
+ 'AuthError': 102,
+ 'AccessError': 103,
+ 'ConnectionError': 104,
+ 'CaptchaError': 105,
+ 'SocialFacebookLoginAccessDisable': 106,
+ 'SocialTwitterLoginAccessDisable': 107,
+ 'SocialGoogleLoginAccessDisable': 108,
+ 'DomainNotAllowed': 109,
+ 'AccountNotAllowed': 110,
+
+ 'AccountTwoFactorAuthRequired': 120,
+ 'AccountTwoFactorAuthError': 121,
+
+ 'CouldNotSaveNewPassword': 130,
+ 'CurrentPasswordIncorrect': 131,
+ 'NewPasswordShort': 132,
+ 'NewPasswordWeak': 133,
+ 'NewPasswordForbidden': 134,
+
+ 'ContactsSyncError': 140,
+
+ 'CantGetMessageList': 201,
+ 'CantGetMessage': 202,
+ 'CantDeleteMessage': 203,
+ 'CantMoveMessage': 204,
+ 'CantCopyMessage': 205,
+
+ 'CantSaveMessage': 301,
+ 'CantSendMessage': 302,
+ 'InvalidRecipients': 303,
+
+ 'CantSaveFilters': 351,
+ 'CantGetFilters': 352,
+ 'FiltersAreNotCorrect': 355,
+
+ 'CantCreateFolder': 400,
+ 'CantRenameFolder': 401,
+ 'CantDeleteFolder': 402,
+ 'CantSubscribeFolder': 403,
+ 'CantUnsubscribeFolder': 404,
+ 'CantDeleteNonEmptyFolder': 405,
+
+ 'CantSaveSettings': 501,
+ 'CantSavePluginSettings': 502,
+
+ 'DomainAlreadyExists': 601,
+
+ 'CantInstallPackage': 701,
+ 'CantDeletePackage': 702,
+ 'InvalidPluginPackage': 703,
+ 'UnsupportedPluginPackage': 704,
+
+ 'LicensingServerIsUnavailable': 710,
+ 'LicensingExpired': 711,
+ 'LicensingBanned': 712,
+
+ 'DemoSendMessageError': 750,
+ 'DemoAccountError': 751,
+
+ 'AccountAlreadyExists': 801,
+ 'AccountDoesNotExist': 802,
+
+ 'MailServerError': 901,
+ 'ClientViewError': 902,
+ 'InvalidInputArgument': 903,
+
+ 'AjaxFalse': 950,
+ 'AjaxAbort': 951,
+ 'AjaxParse': 952,
+ 'AjaxTimeout': 953,
+
+ 'UnknownNotification': 999,
+ 'UnknownError': 999
+}
\ No newline at end of file
diff --git a/dev/Common/Events.js b/dev/Common/Events.js
deleted file mode 100644
index 14b71d3a0..000000000
--- a/dev/Common/Events.js
+++ /dev/null
@@ -1,77 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- _ = require('_'),
-
- Utils = require('Common/Utils'),
- Plugins = require('Common/Plugins')
- ;
-
- /**
- * @constructor
- */
- function Events()
- {
- this.oSubs = {};
- }
-
- Events.prototype.oSubs = {};
-
- /**
- * @param {string} sName
- * @param {Function} fFunc
- * @param {Object=} oContext
- * @return {Events}
- */
- Events.prototype.sub = function (sName, fFunc, oContext)
- {
- if (Utils.isObject(sName))
- {
- oContext = fFunc || null;
- fFunc = null;
-
- _.each(sName, function (fSubFunc, sSubName) {
- this.sub(sSubName, fSubFunc, oContext);
- }, this);
- }
- else
- {
- if (Utils.isUnd(this.oSubs[sName]))
- {
- this.oSubs[sName] = [];
- }
-
- this.oSubs[sName].push([fFunc, oContext]);
- }
-
- return this;
- };
-
- /**
- * @param {string} sName
- * @param {Array=} aArgs
- * @return {Events}
- */
- Events.prototype.pub = function (sName, aArgs)
- {
- Plugins.runHook('rl-pub', [sName, aArgs]);
-
- if (!Utils.isUnd(this.oSubs[sName]))
- {
- _.each(this.oSubs[sName], function (aItem) {
- if (aItem[0])
- {
- aItem[0].apply(aItem[1] || null, aArgs || []);
- }
- });
- }
-
- return this;
- };
-
- module.exports = new Events();
-
-}());
\ No newline at end of file
diff --git a/dev/Common/Events.jsx b/dev/Common/Events.jsx
new file mode 100644
index 000000000..736266a5d
--- /dev/null
+++ b/dev/Common/Events.jsx
@@ -0,0 +1,65 @@
+
+import {_} from 'common';
+import Utils from 'Common/Utils';
+import Plugins from 'Common/Plugins';
+
+class Events
+{
+ constructor() {
+ this.subs = {};
+ }
+
+ /**
+ * @param {string|Object} name
+ * @param {Function} func
+ * @param {Object=} context
+ * @return {Events}
+ */
+ sub(name, func, context) {
+
+ if (Utils.isObject(name))
+ {
+ context = func || null;
+ func = null;
+
+ _.each(name, (subFunc, subName) => {
+ this.sub(subName, subFunc, context);
+ }, this);
+ }
+ else
+ {
+ if (Utils.isUnd(this.subs[name]))
+ {
+ this.subs[name] = [];
+ }
+
+ this.subs[name].push([func, context]);
+ }
+
+ return this;
+ }
+
+ /**
+ * @param {string} name
+ * @param {Array=} args
+ * @return {Events}
+ */
+ pub(name, args) {
+
+ Plugins.runHook('rl-pub', [name, args]);
+
+ if (!Utils.isUnd(this.subs[name]))
+ {
+ _.each(this.subs[name], (items) => {
+ if (items[0])
+ {
+ items[0].apply(items[1] || null, args || []);
+ }
+ });
+ }
+
+ return this;
+ }
+}
+
+module.exports = new Events();
diff --git a/dev/Common/Globals.js b/dev/Common/Globals.js
index acb582852..ca92e1dd0 100644
--- a/dev/Common/Globals.js
+++ b/dev/Common/Globals.js
@@ -110,8 +110,9 @@
/**
* @type {boolean}
*/
- Globals.bAnimationSupported = !Globals.bMobileDevice && Globals.$html.hasClass('csstransitions') &&
- Globals.$html.hasClass('cssanimations');
+ Globals.bAnimationSupported = !Globals.bMobileDevice &&
+ Globals.$html.hasClass('csstransitions') &&
+ Globals.$html.hasClass('cssanimations');
/**
* @type {boolean}
@@ -164,34 +165,30 @@
* @type {Object}
*/
Globals.oHtmlEditorLangsMap = {
- 'bg': 'bg',
- 'de': 'de',
- 'es': 'es',
- 'fr': 'fr',
- 'hu': 'hu',
- 'is': 'is',
- 'it': 'it',
- 'ja': 'ja',
- 'ja-jp': 'ja',
- 'ko': 'ko',
- 'ko-kr': 'ko',
- 'lt': 'lt',
- 'lv': 'lv',
- 'nl': 'nl',
- 'no': 'no',
- 'pl': 'pl',
- 'pt': 'pt',
- 'pt-pt': 'pt',
- 'pt-br': 'pt-br',
- 'ro': 'ro',
- 'ru': 'ru',
- 'sk': 'sk',
- 'sv': 'sv',
- 'tr': 'tr',
- 'ua': 'ru',
- 'zh': 'zh',
- 'zh-tw': 'zh',
- 'zh-cn': 'zh-cn'
+ 'bg_bg': 'bg',
+ 'de_de': 'de',
+ 'es_es': 'es',
+ 'fr_fr': 'fr',
+ 'hu_hu': 'hu',
+ 'is_is': 'is',
+ 'it_it': 'it',
+ 'ja_jp': 'ja',
+ 'ko_kr': 'ko',
+ 'lt_lt': 'lt',
+ 'lv_lv': 'lv',
+ 'nl_nl': 'nl',
+ 'bg_no': 'no',
+ 'pl_pl': 'pl',
+ 'pt_pt': 'pt',
+ 'pt_br': 'pt-br',
+ 'ro_ro': 'ro',
+ 'ru_ru': 'ru',
+ 'sk_sk': 'sk',
+ 'sv_se': 'sv',
+ 'tr_tr': 'tr',
+ 'uk_ua': 'ru',
+ 'zh_tw': 'zh',
+ 'zh_cn': 'zh-cn'
};
if (Globals.bAllowPdfPreview && window.navigator && window.navigator.mimeTypes)
diff --git a/dev/Common/Links.js b/dev/Common/Links.js
deleted file mode 100644
index 62acbac17..000000000
--- a/dev/Common/Links.js
+++ /dev/null
@@ -1,440 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- window = require('window'),
- Utils = require('Common/Utils')
- ;
-
- /**
- * @constructor
- */
- function Links()
- {
- var Settings = require('Storage/Settings');
-
- this.sBase = '#/';
- this.sServer = './?';
-
- this.sVersion = Settings.settingsGet('Version');
- this.sAuthSuffix = Settings.settingsGet('AuthAccountHash') || '0';
- this.sWebPrefix = Settings.settingsGet('WebPath') || '';
- this.sVersionPrefix = Settings.settingsGet('WebVersionPath') || 'rainloop/v/' + this.sVersion + '/';
- this.sStaticPrefix = this.sVersionPrefix + 'static/';
- }
-
- Links.prototype.populateAuthSuffix = function ()
- {
- this.sAuthSuffix = require('Storage/Settings').settingsGet('AuthAccountHash') || '0';
- };
-
- /**
- * @return {string}
- */
- Links.prototype.subQueryPrefix = function ()
- {
- return '&q[]=';
- };
-
- /**
- * @param {string=} sStartupUrl
- * @return {string}
- */
- Links.prototype.root = function (sStartupUrl)
- {
- return this.sBase + Utils.pString(sStartupUrl);
- };
-
- /**
- * @return {string}
- */
- Links.prototype.rootAdmin = function ()
- {
- return this.sServer + '/Admin/';
- };
-
- /**
- * @return {string}
- */
- Links.prototype.rootUser = function ()
- {
- return './';
- };
-
- /**
- * @param {string} sDownload
- * @param {string=} sCustomSpecSuffix
- * @return {string}
- */
- Links.prototype.attachmentDownload = function (sDownload, sCustomSpecSuffix)
- {
- sCustomSpecSuffix = Utils.isUnd(sCustomSpecSuffix) ? this.sAuthSuffix : sCustomSpecSuffix;
- return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + sCustomSpecSuffix + '/Download/' +
- this.subQueryPrefix() + '/' + sDownload;
- };
-
- /**
- * @param {string} sDownload
- * @param {string=} sCustomSpecSuffix
- * @return {string}
- */
- Links.prototype.attachmentPreview = function (sDownload, sCustomSpecSuffix)
- {
- sCustomSpecSuffix = Utils.isUnd(sCustomSpecSuffix) ? this.sAuthSuffix : sCustomSpecSuffix;
- return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + sCustomSpecSuffix + '/View/' +
- this.subQueryPrefix() + '/' + sDownload;
- };
-
- /**
- * @param {string} sDownload
- * @param {string=} sCustomSpecSuffix
- * @return {string}
- */
- Links.prototype.attachmentThumbnailPreview = function (sDownload, sCustomSpecSuffix)
- {
- sCustomSpecSuffix = Utils.isUnd(sCustomSpecSuffix) ? this.sAuthSuffix : sCustomSpecSuffix;
- return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + sCustomSpecSuffix + '/ViewThumbnail/' +
- this.subQueryPrefix() + '/' + sDownload;
- };
-
- /**
- * @param {string} sDownload
- * @param {string=} sCustomSpecSuffix
- * @return {string}
- */
- Links.prototype.attachmentPreviewAsPlain = function (sDownload, sCustomSpecSuffix)
- {
- sCustomSpecSuffix = Utils.isUnd(sCustomSpecSuffix) ? this.sAuthSuffix : sCustomSpecSuffix;
- return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + sCustomSpecSuffix + '/ViewAsPlain/' +
- this.subQueryPrefix() + '/' + sDownload;
- };
-
- /**
- * @param {string} sDownload
- * @param {string=} sCustomSpecSuffix
- * @return {string}
- */
- Links.prototype.attachmentFramed = function (sDownload, sCustomSpecSuffix)
- {
- sCustomSpecSuffix = Utils.isUnd(sCustomSpecSuffix) ? this.sAuthSuffix : sCustomSpecSuffix;
- return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + sCustomSpecSuffix + '/FramedView/' +
- this.subQueryPrefix() + '/' + sDownload;
- };
-
- /**
- * @return {string}
- */
- Links.prototype.upload = function ()
- {
- return this.sServer + '/Upload/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/';
- };
-
- /**
- * @return {string}
- */
- Links.prototype.uploadContacts = function ()
- {
- return this.sServer + '/UploadContacts/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/';
- };
-
- /**
- * @return {string}
- */
- Links.prototype.uploadBackground = function ()
- {
- return this.sServer + '/UploadBackground/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/';
- };
-
- /**
- * @return {string}
- */
- Links.prototype.append = function ()
- {
- return this.sServer + '/Append/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/';
- };
-
- /**
- * @param {string} sEmail
- * @return {string}
- */
- Links.prototype.change = function (sEmail)
- {
- return this.sServer + '/Change/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' + Utils.encodeURIComponent(sEmail) + '/';
- };
-
- /**
- * @param {string=} sAdd
- * @return {string}
- */
- Links.prototype.ajax = function (sAdd)
- {
- return this.sServer + '/Ajax/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' + sAdd;
- };
-
- /**
- * @param {string} sRequestHash
- * @return {string}
- */
- Links.prototype.messageViewLink = function (sRequestHash)
- {
- return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/ViewAsPlain/' + this.subQueryPrefix() + '/' + sRequestHash;
- };
-
- /**
- * @param {string} sRequestHash
- * @return {string}
- */
- Links.prototype.messageDownloadLink = function (sRequestHash)
- {
- return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/Download/' + this.subQueryPrefix() + '/' + sRequestHash;
- };
-
- /**
- * @param {string} sEmail
- * @return {string}
- */
- Links.prototype.avatarLink = function (sEmail)
- {
- return this.sServer + '/Raw/0/Avatar/' + Utils.encodeURIComponent(sEmail) + '/';
- };
-
- /**
- * @param {string} sHash
- * @return {string}
- */
- Links.prototype.publicLink = function (sHash)
- {
- return this.sServer + '/Raw/0/Public/' + sHash + '/';
- };
-
- /**
- * @param {string} sHash
- * @return {string}
- */
- Links.prototype.userBackground = function (sHash)
- {
- return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix +
- '/UserBackground/' + this.subQueryPrefix() + '/' + sHash;
- };
-
- /**
- * @param {string} sInboxFolderName = 'INBOX'
- * @return {string}
- */
- Links.prototype.inbox = function (sInboxFolderName)
- {
- sInboxFolderName = Utils.isUnd(sInboxFolderName) ? 'INBOX' : sInboxFolderName;
- return this.sBase + 'mailbox/' + sInboxFolderName;
- };
-
- /**
- * @param {string=} sScreenName
- * @return {string}
- */
- Links.prototype.settings = function (sScreenName)
- {
- var sResult = this.sBase + 'settings';
- if (!Utils.isUnd(sScreenName) && '' !== sScreenName)
- {
- sResult += '/' + sScreenName;
- }
-
- return sResult;
- };
-
- /**
- * @return {string}
- */
- Links.prototype.about = function ()
- {
- return this.sBase + 'about';
- };
-
- /**
- * @param {string} sScreenName
- * @return {string}
- */
- Links.prototype.admin = function (sScreenName)
- {
- var sResult = this.sBase;
- switch (sScreenName) {
- case 'AdminDomains':
- sResult += 'domains';
- break;
- case 'AdminSecurity':
- sResult += 'security';
- break;
- case 'AdminLicensing':
- sResult += 'licensing';
- break;
- }
-
- return sResult;
- };
-
- /**
- * @param {string} sFolder
- * @param {number=} iPage = 1
- * @param {string=} sSearch = ''
- * @param {string=} sThreadUid = ''
- * @return {string}
- */
- Links.prototype.mailBox = function (sFolder, iPage, sSearch, sThreadUid)
- {
- iPage = Utils.isNormal(iPage) ? Utils.pInt(iPage) : 1;
- sSearch = Utils.pString(sSearch);
-
- var
- sResult = this.sBase + 'mailbox/',
- iThreadUid = Utils.pInt(sThreadUid)
- ;
-
- if ('' !== sFolder)
- {
- sResult += encodeURI(sFolder) + (0 < iThreadUid ? '~' + iThreadUid : '');
- }
-
- if (1 < iPage)
- {
- sResult = sResult.replace(/[\/]+$/, '');
- sResult += '/p' + iPage;
- }
-
- if ('' !== sSearch)
- {
- sResult = sResult.replace(/[\/]+$/, '');
- sResult += '/' + encodeURI(sSearch);
- }
-
- return sResult;
- };
-
- /**
- * @return {string}
- */
- Links.prototype.phpInfo = function ()
- {
- return this.sServer + 'Info';
- };
-
- /**
- * @param {string} sLang
- * @return {string}
- */
- Links.prototype.langLink = function (sLang, bAdmin)
- {
- return this.sServer + '/Lang/0/' + (bAdmin ? 'Admin' : 'App') + '/' + encodeURI(sLang) + '/' + this.sVersion + '/';
- };
-
- /**
- * @return {string}
- */
- Links.prototype.exportContactsVcf = function ()
- {
- return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/ContactsVcf/';
- };
-
- /**
- * @return {string}
- */
- Links.prototype.exportContactsCsv = function ()
- {
- return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/ContactsCsv/';
- };
-
- /**
- * @return {string}
- */
- Links.prototype.emptyContactPic = function ()
- {
- return this.sStaticPrefix + 'css/images/empty-contact.png';
- };
-
- /**
- * @param {string} sFileName
- * @return {string}
- */
- Links.prototype.sound = function (sFileName)
- {
- return this.sStaticPrefix + 'sounds/' + sFileName;
- };
-
- /**
- * @param {string} sTheme
- * @return {string}
- */
- Links.prototype.themePreviewLink = function (sTheme)
- {
- var sPrefix = this.sVersionPrefix;
- if ('@custom' === sTheme.substr(-7))
- {
- sTheme = Utils.trim(sTheme.substring(0, sTheme.length - 7));
- sPrefix = this.sWebPrefix;
- }
-
- return sPrefix + 'themes/' + window.encodeURI(sTheme) + '/images/preview.png';
- };
-
- /**
- * @return {string}
- */
- Links.prototype.notificationMailIcon = function ()
- {
- return this.sStaticPrefix + 'css/images/icom-message-notification.png';
- };
-
- /**
- * @return {string}
- */
- Links.prototype.openPgpJs = function ()
- {
- return this.sStaticPrefix + 'js/min/openpgp.min.js';
- };
-
- /**
- * @return {string}
- */
- Links.prototype.openPgpWorkerJs = function ()
- {
- return this.sStaticPrefix + 'js/min/openpgp.worker.min.js';
- };
-
- /**
- * @return {string}
- */
- Links.prototype.openPgpWorkerPath = function ()
- {
- return this.sStaticPrefix + 'js/min/';
- };
-
- /**
- * @param {boolean} bXAuth = false
- * @return {string}
- */
- Links.prototype.socialGoogle = function (bXAuth)
- {
- return this.sServer + 'SocialGoogle' + ('' !== this.sAuthSuffix ? '/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' : '') +
- (bXAuth ? '&xauth=1' : '');
- };
-
- /**
- * @return {string}
- */
- Links.prototype.socialTwitter = function ()
- {
- return this.sServer + 'SocialTwitter' + ('' !== this.sAuthSuffix ? '/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' : '');
- };
-
- /**
- * @return {string}
- */
- Links.prototype.socialFacebook = function ()
- {
- return this.sServer + 'SocialFacebook' + ('' !== this.sAuthSuffix ? '/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' : '');
- };
-
- module.exports = new Links();
-
-}());
\ No newline at end of file
diff --git a/dev/Common/Links.jsx b/dev/Common/Links.jsx
new file mode 100644
index 000000000..e00f80ade
--- /dev/null
+++ b/dev/Common/Links.jsx
@@ -0,0 +1,386 @@
+
+import {window} from 'common';
+import Utils from 'Common/Utils';
+import Settings from 'Storage/Settings';
+
+class Links
+{
+ constructor() {
+
+ this.sBase = '#/';
+ this.sServer = './?';
+
+ this.sVersion = Settings.settingsGet('Version');
+ this.sAuthSuffix = Settings.settingsGet('AuthAccountHash') || '0';
+ this.sWebPrefix = Settings.settingsGet('WebPath') || '';
+ this.sVersionPrefix = Settings.settingsGet('WebVersionPath') || 'rainloop/v/' + this.sVersion + '/';
+ this.sStaticPrefix = this.sVersionPrefix + 'static/';
+ }
+
+ populateAuthSuffix() {
+ this.sAuthSuffix = Settings.settingsGet('AuthAccountHash') || '0';
+ }
+
+ /**
+ * @return {string}
+ */
+ subQueryPrefix() {
+ return '&q[]=';
+ }
+
+ /**
+ * @param {string=} startupUrl
+ * @return {string}
+ */
+ root(startupUrl = '') {
+ return this.sBase + Utils.pString(startupUrl);
+ }
+
+ /**
+ * @return {string}
+ */
+ rootAdmin() {
+ return this.sServer + '/Admin/';
+ }
+
+ /**
+ * @return {string}
+ */
+ rootUser() {
+ return './';
+ }
+
+ /**
+ * @param {string} type
+ * @param {string} download
+ * @param {string=} customSpecSuffix
+ * @return {string}
+ */
+ attachmentRaw(type, download, customSpecSuffix) {
+ customSpecSuffix = Utils.isUnd(customSpecSuffix) ? this.sAuthSuffix : customSpecSuffix;
+ return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + customSpecSuffix + '/' + type + '/' +
+ this.subQueryPrefix() + '/' + download;
+ }
+
+ /**
+ * @param {string} download
+ * @param {string=} customSpecSuffix
+ * @return {string}
+ */
+ attachmentDownload(download, customSpecSuffix) {
+ return this.attachmentRaw('Download', download, customSpecSuffix);
+ }
+
+ /**
+ * @param {string} download
+ * @param {string=} customSpecSuffix
+ * @return {string}
+ */
+ attachmentPreview(download, customSpecSuffix) {
+ return this.attachmentRaw('View', download, customSpecSuffix);
+ }
+
+ /**
+ * @param {string} download
+ * @param {string=} customSpecSuffix
+ * @return {string}
+ */
+ attachmentThumbnailPreview(download, customSpecSuffix) {
+ return this.attachmentRaw('ViewThumbnail', download, customSpecSuffix);
+ }
+
+ /**
+ * @param {string} download
+ * @param {string=} customSpecSuffix
+ * @return {string}
+ */
+ attachmentPreviewAsPlain(download, customSpecSuffix) {
+ return this.attachmentRaw('ViewAsPlain', download, customSpecSuffix);
+ }
+
+ /**
+ * @param {string} download
+ * @param {string=} customSpecSuffix
+ * @return {string}
+ */
+ attachmentFramed(download, customSpecSuffix) {
+ return this.attachmentRaw('FramedView', download, customSpecSuffix);
+ }
+
+ /**
+ * @return {string}
+ */
+ upload() {
+ return this.sServer + '/Upload/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/';
+ }
+
+ /**
+ * @return {string}
+ */
+ uploadContacts() {
+ return this.sServer + '/UploadContacts/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/';
+ }
+
+ /**
+ * @return {string}
+ */
+ uploadBackground() {
+ return this.sServer + '/UploadBackground/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/';
+ }
+
+ /**
+ * @return {string}
+ */
+ append() {
+ return this.sServer + '/Append/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/';
+ }
+
+ /**
+ * @param {string} email
+ * @return {string}
+ */
+ change(email) {
+ return this.sServer + '/Change/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' + Utils.encodeURIComponent(email) + '/';
+ }
+
+ /**
+ * @param {string} add
+ * @return {string}
+ */
+ ajax(add) {
+ return this.sServer + '/Ajax/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' + add;
+ }
+
+ /**
+ * @param {string} requestHash
+ * @return {string}
+ */
+ messageViewLink(requestHash) {
+ return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/ViewAsPlain/' + this.subQueryPrefix() + '/' + requestHash;
+ }
+
+ /**
+ * @param {string} requestHash
+ * @return {string}
+ */
+ messageDownloadLink(requestHash) {
+ return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/Download/' + this.subQueryPrefix() + '/' + requestHash;
+ }
+
+ /**
+ * @param {string} email
+ * @return {string}
+ */
+ avatarLink(email) {
+ return this.sServer + '/Raw/0/Avatar/' + Utils.encodeURIComponent(email) + '/';
+ }
+
+ /**
+ * @param {string} hash
+ * @return {string}
+ */
+ publicLink(hash) {
+ return this.sServer + '/Raw/0/Public/' + hash + '/';
+ }
+
+ /**
+ * @param {string} hash
+ * @return {string}
+ */
+ userBackground(hash) {
+ return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix +
+ '/UserBackground/' + this.subQueryPrefix() + '/' + hash;
+ }
+
+ /**
+ * @param {string} inboxFolderName = 'INBOX'
+ * @return {string}
+ */
+ inbox(inboxFolderName = 'INBOX') {
+ return this.sBase + 'mailbox/' + inboxFolderName;
+ }
+
+ /**
+ * @param {string=} screenName
+ * @return {string}
+ */
+ settings(screenName = '') {
+ return this.sBase + 'settings' + (screenName ? '/' + screenName : '');
+ }
+
+ /**
+ * @return {string}
+ */
+ about() {
+ return this.sBase + 'about';
+ }
+
+ /**
+ * @param {string} screenName
+ * @return {string}
+ */
+ admin (screenName) {
+ let result = this.sBase;
+ switch (screenName) {
+ case 'AdminDomains':
+ result += 'domains';
+ break;
+ case 'AdminSecurity':
+ result += 'security';
+ break;
+ case 'AdminLicensing':
+ result += 'licensing';
+ break;
+ }
+
+ return result;
+ }
+
+ /**
+ * @param {string} folder
+ * @param {number=} page = 1
+ * @param {string=} search = ''
+ * @param {string=} threadUid = ''
+ * @return {string}
+ */
+ mailBox(folder, page = 1, search = '', threadUid = '') {
+
+ page = Utils.isNormal(page) ? Utils.pInt(page) : 1;
+ search = Utils.pString(search);
+
+ let result = this.sBase + 'mailbox/';
+
+ if ('' !== folder)
+ {
+ const resultThreadUid = Utils.pInt(threadUid);
+ result += window.encodeURI(folder) + (0 < resultThreadUid ? '~' + resultThreadUid : '');
+ }
+
+ if (1 < page)
+ {
+ result = result.replace(/[\/]+$/, '');
+ result += '/p' + page;
+ }
+
+ if ('' !== search)
+ {
+ result = result.replace(/[\/]+$/, '');
+ result += '/' + window.encodeURI(search);
+ }
+
+ return result;
+ }
+
+ /**
+ * @return {string}
+ */
+ phpInfo() {
+ return this.sServer + 'Info';
+ }
+
+ /**
+ * @param {string} lang
+ * @param {boolean} admin
+ * @return {string}
+ */
+ langLink(lang, admin) {
+ return this.sServer + '/Lang/0/' + (admin ? 'Admin' : 'App') + '/' + window.encodeURI(lang) + '/' + this.sVersion + '/';
+ }
+
+ /**
+ * @return {string}
+ */
+ exportContactsVcf() {
+ return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/ContactsVcf/';
+ }
+
+ /**
+ * @return {string}
+ */
+ exportContactsCsv() {
+ return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/ContactsCsv/';
+ }
+
+ /**
+ * @return {string}
+ */
+ emptyContactPic() {
+ return this.sStaticPrefix + 'css/images/empty-contact.png';
+ }
+
+ /**
+ * @param {string} fileName
+ * @return {string}
+ */
+ sound(fileName) {
+ return this.sStaticPrefix + 'sounds/' + fileName;
+ }
+
+ /**
+ * @param {string} theme
+ * @return {string}
+ */
+ themePreviewLink(theme) {
+ let prefix = this.sVersionPrefix;
+ if ('@custom' === theme.substr(-7))
+ {
+ theme = Utils.trim(theme.substring(0, theme.length - 7));
+ prefix = this.sWebPrefix;
+ }
+
+ return prefix + 'themes/' + window.encodeURI(theme) + '/images/preview.png';
+ }
+
+ /**
+ * @return {string}
+ */
+ notificationMailIcon() {
+ return this.sStaticPrefix + 'css/images/icom-message-notification.png';
+ }
+
+ /**
+ * @return {string}
+ */
+ openPgpJs() {
+ return this.sStaticPrefix + 'js/min/openpgp.min.js';
+ }
+
+ /**
+ * @return {string}
+ */
+ openPgpWorkerJs() {
+ return this.sStaticPrefix + 'js/min/openpgp.worker.min.js';
+ }
+
+ /**
+ * @return {string}
+ */
+ openPgpWorkerPath() {
+ return this.sStaticPrefix + 'js/min/';
+ }
+
+ /**
+ * @param {boolean} xauth = false
+ * @return {string}
+ */
+ socialGoogle(xauth = false) {
+ return this.sServer + 'SocialGoogle' + ('' !== this.sAuthSuffix ? '/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' : '') +
+ (xauth ? '&xauth=1' : '');
+ }
+
+ /**
+ * @return {string}
+ */
+ socialTwitter() {
+ return this.sServer + 'SocialTwitter' + ('' !== this.sAuthSuffix ? '/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' : '');
+ }
+
+ /**
+ * @return {string}
+ */
+ socialFacebook() {
+ return this.sServer + 'SocialFacebook' + ('' !== this.sAuthSuffix ? '/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' : '');
+ }
+}
+
+module.exports = new Links();
diff --git a/dev/Common/Mime.js b/dev/Common/Mime.js
deleted file mode 100644
index a29e3ae36..000000000
--- a/dev/Common/Mime.js
+++ /dev/null
@@ -1,168 +0,0 @@
-(function () {
-
- 'use strict';
-
- module.exports = {
-
- 'eml' : 'message/rfc822',
- 'mime' : 'message/rfc822',
- 'txt' : 'text/plain',
- 'text' : 'text/plain',
- 'def' : 'text/plain',
- 'list' : 'text/plain',
- 'in' : 'text/plain',
- 'ini' : 'text/plain',
- 'log' : 'text/plain',
- 'sql' : 'text/plain',
- 'cfg' : 'text/plain',
- 'conf' : 'text/plain',
- 'asc' : 'text/plain',
- 'rtx' : 'text/richtext',
- 'vcard' : 'text/vcard',
- 'vcf' : 'text/vcard',
- 'htm' : 'text/html',
- 'html' : 'text/html',
- 'csv' : 'text/csv',
- 'ics' : 'text/calendar',
- 'ifb' : 'text/calendar',
- 'xml' : 'text/xml',
- 'json' : 'application/json',
- 'swf' : 'application/x-shockwave-flash',
- 'hlp' : 'application/winhlp',
- 'wgt' : 'application/widget',
- 'chm' : 'application/vnd.ms-htmlhelp',
- 'p10' : 'application/pkcs10',
- 'p7c' : 'application/pkcs7-mime',
- 'p7m' : 'application/pkcs7-mime',
- 'p7s' : 'application/pkcs7-signature',
- 'torrent' : 'application/x-bittorrent',
-
- // scripts
- 'js' : 'application/javascript',
- 'pl' : 'text/perl',
- 'css' : 'text/css',
- 'asp' : 'text/asp',
- 'php' : 'application/x-httpd-php',
- 'php3' : 'application/x-httpd-php',
- 'php4' : 'application/x-httpd-php',
- 'php5' : 'application/x-httpd-php',
- 'phtml' : 'application/x-httpd-php',
-
- // images
- 'png' : 'image/png',
- 'jpg' : 'image/jpeg',
- 'jpeg' : 'image/jpeg',
- 'jpe' : 'image/jpeg',
- 'jfif' : 'image/jpeg',
- 'gif' : 'image/gif',
- 'bmp' : 'image/bmp',
- 'cgm' : 'image/cgm',
- 'ief' : 'image/ief',
- 'ico' : 'image/x-icon',
- 'tif' : 'image/tiff',
- 'tiff' : 'image/tiff',
- 'svg' : 'image/svg+xml',
- 'svgz' : 'image/svg+xml',
- 'djv' : 'image/vnd.djvu',
- 'djvu' : 'image/vnd.djvu',
- 'webp' : 'image/webp',
-
- // archives
- 'zip' : 'application/zip',
- '7z' : 'application/x-7z-compressed',
- 'rar' : 'application/x-rar-compressed',
- 'exe' : 'application/x-msdownload',
- 'dll' : 'application/x-msdownload',
- 'scr' : 'application/x-msdownload',
- 'com' : 'application/x-msdownload',
- 'bat' : 'application/x-msdownload',
- 'msi' : 'application/x-msdownload',
- 'cab' : 'application/vnd.ms-cab-compressed',
- 'gz' : 'application/x-gzip',
- 'tgz' : 'application/x-gzip',
- 'bz' : 'application/x-bzip',
- 'bz2' : 'application/x-bzip2',
- 'deb' : 'application/x-debian-package',
-
- // fonts
- 'psf' : 'application/x-font-linux-psf',
- 'otf' : 'application/x-font-otf',
- 'pcf' : 'application/x-font-pcf',
- 'snf' : 'application/x-font-snf',
- 'ttf' : 'application/x-font-ttf',
- 'ttc' : 'application/x-font-ttf',
-
- // audio
- 'mp3' : 'audio/mpeg',
- 'amr' : 'audio/amr',
- 'aac' : 'audio/x-aac',
- 'aif' : 'audio/x-aiff',
- 'aifc' : 'audio/x-aiff',
- 'aiff' : 'audio/x-aiff',
- 'wav' : 'audio/x-wav',
- 'wma' : 'audio/x-ms-wma',
- 'wax' : 'audio/x-ms-wax',
- 'midi' : 'audio/midi',
- 'mp4a' : 'audio/mp4',
- 'ogg' : 'audio/ogg',
- 'weba' : 'audio/webm',
- 'ra' : 'audio/x-pn-realaudio',
- 'ram' : 'audio/x-pn-realaudio',
- 'rmp' : 'audio/x-pn-realaudio-plugin',
- 'm3u' : 'audio/x-mpegurl',
-
- // video
- 'flv' : 'video/x-flv',
- 'qt' : 'video/quicktime',
- 'mov' : 'video/quicktime',
- 'wmv' : 'video/windows-media',
- 'avi' : 'video/x-msvideo',
- 'mpg' : 'video/mpeg',
- 'mpeg' : 'video/mpeg',
- 'mpe' : 'video/mpeg',
- 'm1v' : 'video/mpeg',
- 'm2v' : 'video/mpeg',
- '3gp' : 'video/3gpp',
- '3g2' : 'video/3gpp2',
- 'h261' : 'video/h261',
- 'h263' : 'video/h263',
- 'h264' : 'video/h264',
- 'jpgv' : 'video/jpgv',
- 'mp4' : 'video/mp4',
- 'mp4v' : 'video/mp4',
- 'mpg4' : 'video/mp4',
- 'ogv' : 'video/ogg',
- 'webm' : 'video/webm',
- 'm4v' : 'video/x-m4v',
- 'asf' : 'video/x-ms-asf',
- 'asx' : 'video/x-ms-asf',
- 'wm' : 'video/x-ms-wm',
- 'wmx' : 'video/x-ms-wmx',
- 'wvx' : 'video/x-ms-wvx',
- 'movie' : 'video/x-sgi-movie',
-
- // adobe
- 'pdf' : 'application/pdf',
- 'psd' : 'image/vnd.adobe.photoshop',
- 'ai' : 'application/postscript',
- 'eps' : 'application/postscript',
- 'ps' : 'application/postscript',
-
- // ms office
- 'doc' : 'application/msword',
- 'dot' : 'application/msword',
- 'rtf' : 'application/rtf',
- 'xls' : 'application/vnd.ms-excel',
- 'ppt' : 'application/vnd.ms-powerpoint',
- 'docx' : 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
- 'xlsx' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
- 'dotx' : 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
- 'pptx' : 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
-
- // open office
- 'odt' : 'application/vnd.oasis.opendocument.text',
- 'ods' : 'application/vnd.oasis.opendocument.spreadsheet'
-
- };
-
-}());
diff --git a/dev/Common/Mime.jsx b/dev/Common/Mime.jsx
new file mode 100644
index 000000000..38b1fa137
--- /dev/null
+++ b/dev/Common/Mime.jsx
@@ -0,0 +1,163 @@
+
+module.exports = {
+
+ 'eml' : 'message/rfc822',
+ 'mime' : 'message/rfc822',
+ 'txt' : 'text/plain',
+ 'text' : 'text/plain',
+ 'def' : 'text/plain',
+ 'list' : 'text/plain',
+ 'in' : 'text/plain',
+ 'ini' : 'text/plain',
+ 'log' : 'text/plain',
+ 'sql' : 'text/plain',
+ 'cfg' : 'text/plain',
+ 'conf' : 'text/plain',
+ 'asc' : 'text/plain',
+ 'rtx' : 'text/richtext',
+ 'vcard' : 'text/vcard',
+ 'vcf' : 'text/vcard',
+ 'htm' : 'text/html',
+ 'html' : 'text/html',
+ 'csv' : 'text/csv',
+ 'ics' : 'text/calendar',
+ 'ifb' : 'text/calendar',
+ 'xml' : 'text/xml',
+ 'json' : 'application/json',
+ 'swf' : 'application/x-shockwave-flash',
+ 'hlp' : 'application/winhlp',
+ 'wgt' : 'application/widget',
+ 'chm' : 'application/vnd.ms-htmlhelp',
+ 'p10' : 'application/pkcs10',
+ 'p7c' : 'application/pkcs7-mime',
+ 'p7m' : 'application/pkcs7-mime',
+ 'p7s' : 'application/pkcs7-signature',
+ 'torrent' : 'application/x-bittorrent',
+
+ // scripts
+ 'js' : 'application/javascript',
+ 'pl' : 'text/perl',
+ 'css' : 'text/css',
+ 'asp' : 'text/asp',
+ 'php' : 'application/x-httpd-php',
+ 'php3' : 'application/x-httpd-php',
+ 'php4' : 'application/x-httpd-php',
+ 'php5' : 'application/x-httpd-php',
+ 'phtml' : 'application/x-httpd-php',
+
+ // images
+ 'png' : 'image/png',
+ 'jpg' : 'image/jpeg',
+ 'jpeg' : 'image/jpeg',
+ 'jpe' : 'image/jpeg',
+ 'jfif' : 'image/jpeg',
+ 'gif' : 'image/gif',
+ 'bmp' : 'image/bmp',
+ 'cgm' : 'image/cgm',
+ 'ief' : 'image/ief',
+ 'ico' : 'image/x-icon',
+ 'tif' : 'image/tiff',
+ 'tiff' : 'image/tiff',
+ 'svg' : 'image/svg+xml',
+ 'svgz' : 'image/svg+xml',
+ 'djv' : 'image/vnd.djvu',
+ 'djvu' : 'image/vnd.djvu',
+ 'webp' : 'image/webp',
+
+ // archives
+ 'zip' : 'application/zip',
+ '7z' : 'application/x-7z-compressed',
+ 'rar' : 'application/x-rar-compressed',
+ 'exe' : 'application/x-msdownload',
+ 'dll' : 'application/x-msdownload',
+ 'scr' : 'application/x-msdownload',
+ 'com' : 'application/x-msdownload',
+ 'bat' : 'application/x-msdownload',
+ 'msi' : 'application/x-msdownload',
+ 'cab' : 'application/vnd.ms-cab-compressed',
+ 'gz' : 'application/x-gzip',
+ 'tgz' : 'application/x-gzip',
+ 'bz' : 'application/x-bzip',
+ 'bz2' : 'application/x-bzip2',
+ 'deb' : 'application/x-debian-package',
+
+ // fonts
+ 'psf' : 'application/x-font-linux-psf',
+ 'otf' : 'application/x-font-otf',
+ 'pcf' : 'application/x-font-pcf',
+ 'snf' : 'application/x-font-snf',
+ 'ttf' : 'application/x-font-ttf',
+ 'ttc' : 'application/x-font-ttf',
+
+ // audio
+ 'mp3' : 'audio/mpeg',
+ 'amr' : 'audio/amr',
+ 'aac' : 'audio/x-aac',
+ 'aif' : 'audio/x-aiff',
+ 'aifc' : 'audio/x-aiff',
+ 'aiff' : 'audio/x-aiff',
+ 'wav' : 'audio/x-wav',
+ 'wma' : 'audio/x-ms-wma',
+ 'wax' : 'audio/x-ms-wax',
+ 'midi' : 'audio/midi',
+ 'mp4a' : 'audio/mp4',
+ 'ogg' : 'audio/ogg',
+ 'weba' : 'audio/webm',
+ 'ra' : 'audio/x-pn-realaudio',
+ 'ram' : 'audio/x-pn-realaudio',
+ 'rmp' : 'audio/x-pn-realaudio-plugin',
+ 'm3u' : 'audio/x-mpegurl',
+
+ // video
+ 'flv' : 'video/x-flv',
+ 'qt' : 'video/quicktime',
+ 'mov' : 'video/quicktime',
+ 'wmv' : 'video/windows-media',
+ 'avi' : 'video/x-msvideo',
+ 'mpg' : 'video/mpeg',
+ 'mpeg' : 'video/mpeg',
+ 'mpe' : 'video/mpeg',
+ 'm1v' : 'video/mpeg',
+ 'm2v' : 'video/mpeg',
+ '3gp' : 'video/3gpp',
+ '3g2' : 'video/3gpp2',
+ 'h261' : 'video/h261',
+ 'h263' : 'video/h263',
+ 'h264' : 'video/h264',
+ 'jpgv' : 'video/jpgv',
+ 'mp4' : 'video/mp4',
+ 'mp4v' : 'video/mp4',
+ 'mpg4' : 'video/mp4',
+ 'ogv' : 'video/ogg',
+ 'webm' : 'video/webm',
+ 'm4v' : 'video/x-m4v',
+ 'asf' : 'video/x-ms-asf',
+ 'asx' : 'video/x-ms-asf',
+ 'wm' : 'video/x-ms-wm',
+ 'wmx' : 'video/x-ms-wmx',
+ 'wvx' : 'video/x-ms-wvx',
+ 'movie' : 'video/x-sgi-movie',
+
+ // adobe
+ 'pdf' : 'application/pdf',
+ 'psd' : 'image/vnd.adobe.photoshop',
+ 'ai' : 'application/postscript',
+ 'eps' : 'application/postscript',
+ 'ps' : 'application/postscript',
+
+ // ms office
+ 'doc' : 'application/msword',
+ 'dot' : 'application/msword',
+ 'rtf' : 'application/rtf',
+ 'xls' : 'application/vnd.ms-excel',
+ 'ppt' : 'application/vnd.ms-powerpoint',
+ 'docx' : 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+ 'xlsx' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ 'dotx' : 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
+ 'pptx' : 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
+
+ // open office
+ 'odt' : 'application/vnd.oasis.opendocument.text',
+ 'ods' : 'application/vnd.oasis.opendocument.spreadsheet'
+
+};
diff --git a/dev/Common/Momentor.js b/dev/Common/Momentor.js
deleted file mode 100644
index 5634f84f8..000000000
--- a/dev/Common/Momentor.js
+++ /dev/null
@@ -1,188 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- window = require('window'),
- $ = require('$'),
- _ = require('_'),
- moment = require('moment'),
-
- Translator = require('Common/Translator')
- ;
-
- /**
- * @constructor
- */
- function Momentor()
- {
- this.format = _.bind(this.format, this);
-
- this.updateMomentNow = _.debounce(_.bind(function () {
- this._moment = moment();
- }, this), 500, true);
-
- this.updateMomentNowUnix = _.debounce(_.bind(function () {
- this._momentNow = moment().unix();
- }, this), 500, true);
- }
-
- Momentor.prototype._moment = null;
- Momentor.prototype._momentNow = 0;
-
- Momentor.prototype.momentNow = function ()
- {
- this.updateMomentNow();
- return this._moment || moment();
- };
-
- Momentor.prototype.momentNowUnix = function ()
- {
- this.updateMomentNowUnix();
- return this._momentNow || 0;
- };
-
- Momentor.prototype.searchSubtractFormatDateHelper = function (iDate)
- {
- var oM = this.momentNow();
- return oM.clone().subtract('days', iDate).format('YYYY.MM.DD');
- };
-
- /**
- * @param {Object} oMoment
- * @return {string}
- */
- Momentor.prototype.formatCustomShortDate = function (oMoment)
- {
- var
- sResult = '',
- oMomentNow = this.momentNow()
- ;
-
- if (oMoment && oMomentNow)
- {
- if (4 >= oMomentNow.diff(oMoment, 'hours'))
- {
- sResult = oMoment.fromNow();
- }
- else if (oMomentNow.format('L') === oMoment.format('L'))
- {
- sResult = Translator.i18n('MESSAGE_LIST/TODAY_AT', {
- 'TIME': oMoment.format('LT')
- });
- }
- else if (oMomentNow.clone().subtract('days', 1).format('L') === oMoment.format('L'))
- {
- sResult = Translator.i18n('MESSAGE_LIST/YESTERDAY_AT', {
- 'TIME': oMoment.format('LT')
- });
- }
- else if (oMomentNow.year() === oMoment.year())
- {
- sResult = oMoment.format('D MMM.');
- }
- else
- {
- sResult = oMoment.format('LL');
- }
- }
-
- return sResult;
- };
-
- /**
- * @param {number} iTimeStampInUTC
- * @param {string} sFormat
- * @return {string}
- */
- Momentor.prototype.format = function (iTimeStampInUTC, sFormat)
- {
- var
- oM = null,
- sResult = '',
- iNow = this.momentNowUnix()
- ;
-
- iTimeStampInUTC = 0 < iTimeStampInUTC ? iTimeStampInUTC : (0 === iTimeStampInUTC ? iNow : 0);
- iTimeStampInUTC = iNow < iTimeStampInUTC ? iNow : iTimeStampInUTC;
-
- oM = 0 < iTimeStampInUTC ? moment.unix(iTimeStampInUTC) : null;
-
- if (oM && 1970 === oM.year())
- {
- oM = null;
- }
-
- if (oM)
- {
- switch (sFormat)
- {
- case 'FROMNOW':
- sResult = oM.fromNow();
- break;
- case 'SHORT':
- sResult = this.formatCustomShortDate(oM);
- break;
- case 'FULL':
- sResult = oM.format('LLL');
- break;
- default:
- sResult = oM.format(sFormat);
- break;
- }
- }
-
- return sResult;
- };
-
- /**
- * @param {Object} oElement
- */
- Momentor.prototype.momentToNode = function (oElement)
- {
- var
- sKey = '',
- iTime = 0,
- $oEl = $(oElement)
- ;
-
- iTime = $oEl.data('moment-time');
- if (iTime)
- {
- sKey = $oEl.data('moment-format');
-
- if (sKey)
- {
- $oEl.text(this.format(iTime, sKey));
- }
-
- sKey = $oEl.data('moment-format-title');
- if (sKey)
- {
- $oEl.attr('title', this.format(iTime, sKey));
- }
- }
- };
-
- /**
- * @param {Object} oElements
- */
- Momentor.prototype.momentToNodes = function (oElements)
- {
- var self = this;
- _.defer(function () {
- $('.moment', oElements).each(function () {
- self.momentToNode(this);
- });
- });
- };
-
- Momentor.prototype.reload = function ()
- {
- this.momentToNodes(window.document);
- };
-
- module.exports = new Momentor();
-
-}());
diff --git a/dev/Common/Momentor.jsx b/dev/Common/Momentor.jsx
new file mode 100644
index 000000000..fb19ffb68
--- /dev/null
+++ b/dev/Common/Momentor.jsx
@@ -0,0 +1,160 @@
+
+import {window, $, _, moment} from 'common';
+import Translator from 'Common/Translator';
+
+class Momentor
+{
+ constructor()
+ {
+ this._moment = null;
+ this._momentNow = 0;
+
+ this.updateMomentNow = _.debounce(() => {
+ this._moment = moment();
+ }, 500, true);
+
+ this.updateMomentNowUnix = _.debounce(() => {
+ this._momentNow = moment().unix();
+ }, 500, true);
+
+ this.format = _.bind(this.format, this);
+ }
+
+ momentNow() {
+ this.updateMomentNow();
+ return this._moment || moment();
+ }
+
+ momentNowUnix() {
+ this.updateMomentNowUnix();
+ return this._momentNow || 0;
+ }
+
+ /**
+ * @param {number} date
+ * @return {string}
+ */
+ searchSubtractFormatDateHelper(date) {
+ return this.momentNow().clone().subtract('days', date).format('YYYY.MM.DD');
+ }
+
+ /**
+ * @param {Object} m
+ * @return {string}
+ */
+ formatCustomShortDate(m) {
+
+ const now = this.momentNow();
+ if (m && now)
+ {
+ switch(true)
+ {
+ case 4 >= now.diff(m, 'hours'):
+ return m.fromNow();
+ case now.format('L') === m.format('L'):
+ return Translator.i18n('MESSAGE_LIST/TODAY_AT', {
+ 'TIME': m.format('LT')
+ });
+ case now.clone().subtract('days', 1).format('L') === m.format('L'):
+ return Translator.i18n('MESSAGE_LIST/YESTERDAY_AT', {
+ 'TIME': m.format('LT')
+ });
+ case now.year() === m.year():
+ return m.format('D MMM.');
+ }
+ }
+
+ return m ? m.format('LL') : '';
+ }
+
+ /**
+ * @param {number} timeStampInUTC
+ * @param {string} format
+ * @return {string}
+ */
+ format(timeStampInUTC, format) {
+
+ let
+ m = null,
+ result = ''
+ ;
+
+ const now = this.momentNowUnix();
+
+ timeStampInUTC = 0 < timeStampInUTC ? timeStampInUTC : (0 === timeStampInUTC ? now : 0);
+ timeStampInUTC = now < timeStampInUTC ? now : timeStampInUTC;
+
+ m = 0 < timeStampInUTC ? moment.unix(timeStampInUTC) : null;
+
+ if (m && 1970 === m.year())
+ {
+ m = null;
+ }
+
+ if (m)
+ {
+ switch (format)
+ {
+ case 'FROMNOW':
+ result = m.fromNow();
+ break;
+ case 'SHORT':
+ result = this.formatCustomShortDate(m);
+ break;
+ case 'FULL':
+ result = m.format('LLL');
+ break;
+ default:
+ result = m.format(format);
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * @param {Object} element
+ */
+ momentToNode(element) {
+
+ var
+ key = '',
+ time = 0,
+ $el = $(element)
+ ;
+
+ time = $el.data('moment-time');
+ if (time)
+ {
+ key = $el.data('moment-format');
+ if (key)
+ {
+ $el.text(this.format(time, key));
+ }
+
+ key = $el.data('moment-format-title');
+ if (key)
+ {
+ $el.attr('title', this.format(time, key));
+ }
+ }
+ }
+
+ /**
+ * @param {Object} elements
+ */
+ momentToNodes(elements) {
+ _.defer(() => {
+ $('.moment', elements).each((index, item) => {
+ this.momentToNode(item);
+ });
+ });
+ }
+
+ reload() {
+ this.momentToNodes(window.document);
+ }
+}
+
+module.exports = new Momentor();
diff --git a/dev/Common/Plugins.js b/dev/Common/Plugins.js
deleted file mode 100644
index 8a24e26b1..000000000
--- a/dev/Common/Plugins.js
+++ /dev/null
@@ -1,144 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- _ = require('_'),
-
- Globals = require('Common/Globals'),
- Utils = require('Common/Utils')
- ;
-
- /**
- * @constructor
- */
- function Plugins()
- {
- this.oSettings = require('Storage/Settings');
- this.oSimpleHooks = {};
-
- this.aUserViewModelsHooks = [];
- this.aAdminViewModelsHooks = [];
- }
-
- /**
- * @type {Object}
- */
- Plugins.prototype.oSettings = {};
-
- /**
- * @type {Array}
- */
- Plugins.prototype.aUserViewModelsHooks = [];
-
- /**
- * @type {Array}
- */
- Plugins.prototype.aAdminViewModelsHooks = [];
-
- /**
- * @type {Object}
- */
- Plugins.prototype.oSimpleHooks = {};
-
- /**
- * @param {string} sName
- * @param {Function} fCallback
- */
- Plugins.prototype.addHook = function (sName, fCallback)
- {
- if (Utils.isFunc(fCallback))
- {
- if (!Utils.isArray(this.oSimpleHooks[sName]))
- {
- this.oSimpleHooks[sName] = [];
- }
-
- this.oSimpleHooks[sName].push(fCallback);
- }
- };
-
- /**
- * @param {string} sName
- * @param {Array=} aArguments
- */
- Plugins.prototype.runHook = function (sName, aArguments)
- {
- if (Utils.isArray(this.oSimpleHooks[sName]))
- {
- aArguments = aArguments || [];
-
- _.each(this.oSimpleHooks[sName], function (fCallback) {
- fCallback.apply(null, aArguments);
- });
- }
- };
-
- /**
- * @param {string} sName
- * @return {?}
- */
- Plugins.prototype.mainSettingsGet = function (sName)
- {
- return this.oSettings.settingsGet(sName);
- };
-
- /**
- * @param {Function} fCallback
- * @param {string} sAction
- * @param {Object=} oParameters
- * @param {?number=} iTimeout
- */
- Plugins.prototype.remoteRequest = function (fCallback, sAction, oParameters, iTimeout)
- {
- if (Globals.__APP__)
- {
- Globals.__APP__.remote().defaultRequest(fCallback, 'Plugin' + sAction, oParameters, iTimeout);
- }
- };
-
- /**
- * @param {Function} SettingsViewModelClass
- * @param {string} sLabelName
- * @param {string} sTemplate
- * @param {string} sRoute
- */
- Plugins.prototype.addSettingsViewModel = function (SettingsViewModelClass, sTemplate, sLabelName, sRoute)
- {
- this.aUserViewModelsHooks.push([SettingsViewModelClass, sTemplate, sLabelName, sRoute]);
- };
-
- /**
- * @param {Function} SettingsViewModelClass
- * @param {string} sLabelName
- * @param {string} sTemplate
- * @param {string} sRoute
- */
- Plugins.prototype.addSettingsViewModelForAdmin = function (SettingsViewModelClass, sTemplate, sLabelName, sRoute)
- {
- this.aAdminViewModelsHooks.push([SettingsViewModelClass, sTemplate, sLabelName, sRoute]);
- };
-
- Plugins.prototype.runSettingsViewModelHooks = function (bAdmin)
- {
- _.each(bAdmin ? this.aAdminViewModelsHooks : this.aUserViewModelsHooks, function (aView) {
- require('Knoin/Knoin').addSettingsViewModel(aView[0], aView[1], aView[2], aView[3]);
- });
- };
-
- /**
- * @param {string} sPluginSection
- * @param {string} sName
- * @return {?}
- */
- Plugins.prototype.settingsGet = function (sPluginSection, sName)
- {
- var oPlugin = this.oSettings.settingsGet('Plugins');
- oPlugin = oPlugin && !Utils.isUnd(oPlugin[sPluginSection]) ? oPlugin[sPluginSection] : null;
- return oPlugin ? (Utils.isUnd(oPlugin[sName]) ? null : oPlugin[sName]) : null;
- };
-
- module.exports = new Plugins();
-
-}());
\ No newline at end of file
diff --git a/dev/Common/Plugins.jsx b/dev/Common/Plugins.jsx
new file mode 100644
index 000000000..def0d1173
--- /dev/null
+++ b/dev/Common/Plugins.jsx
@@ -0,0 +1,107 @@
+
+import {_} from 'common';
+import Utils from 'Common/Utils';
+import Globals from 'Common/Globals';
+import Settings from 'Storage/Settings';
+
+class Plugins
+{
+ constructor() {
+ this.oSimpleHooks = {};
+ this.aUserViewModelsHooks = [];
+ this.aAdminViewModelsHooks = [];
+ }
+
+ /**
+ * @param {string} name
+ * @param {Function} callback
+ */
+ addHook(name, callback) {
+ if (Utils.isFunc(callback))
+ {
+ if (!Utils.isArray(this.oSimpleHooks[name]))
+ {
+ this.oSimpleHooks[name] = [];
+ }
+
+ this.oSimpleHooks[name].push(callback);
+ }
+ }
+
+ /**
+ * @param {string} name
+ * @param {Array=} args
+ */
+ runHook(name, args = []) {
+ if (Utils.isArray(this.oSimpleHooks[name]))
+ {
+ _.each(this.oSimpleHooks[name], (callback) => {
+ callback.apply(null, args);
+ });
+ }
+ }
+
+ /**
+ * @param {string} name
+ * @return {?}
+ */
+ mainSettingsGet(name) {
+ return Settings.settingsGet(name);
+ }
+
+ /**
+ * @param {Function} callback
+ * @param {string} action
+ * @param {Object=} parameters
+ * @param {?number=} timeout
+ */
+ remoteRequest(callback, action, parameters, timeout) {
+ if (Globals.__APP__)
+ {
+ Globals.__APP__.remote().defaultRequest(callback, 'Plugin' + action, parameters, timeout);
+ }
+ }
+
+ /**
+ * @param {Function} SettingsViewModelClass
+ * @param {string} labelName
+ * @param {string} template
+ * @param {string} route
+ */
+ addSettingsViewModel(SettingsViewModelClass, template, labelName, route) {
+ this.aUserViewModelsHooks.push([SettingsViewModelClass, template, labelName, route]);
+ }
+
+ /**
+ * @param {Function} SettingsViewModelClass
+ * @param {string} labelName
+ * @param {string} template
+ * @param {string} route
+ */
+ addSettingsViewModelForAdmin(SettingsViewModelClass, template, labelName, route) {
+ this.aAdminViewModelsHooks.push([SettingsViewModelClass, template, labelName, route]);
+ }
+
+ /**
+ * @param {boolean} admin
+ */
+ runSettingsViewModelHooks(admin) {
+ const Knoin = require('Knoin/Knoin');
+ _.each(admin ? this.aAdminViewModelsHooks : this.aUserViewModelsHooks, (view) => {
+ Knoin.addSettingsViewModel(view[0], view[1], view[2], view[3]);
+ });
+ }
+
+ /**
+ * @param {string} pluginSection
+ * @param {string} name
+ * @return {?}
+ */
+ settingsGet(pluginSection, name) {
+ let plugins = Settings.settingsGet('Plugins');
+ plugins = plugins && !Utils.isUnd(plugins[pluginSection]) ? plugins[pluginSection] : null;
+ return plugins ? (Utils.isUnd(plugins[name]) ? null : plugins[name]) : null;
+ }
+}
+
+module.exports = new Plugins();
diff --git a/dev/Common/Translator.js b/dev/Common/Translator.js
deleted file mode 100644
index 5a5e9d87f..000000000
--- a/dev/Common/Translator.js
+++ /dev/null
@@ -1,336 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- window = require('window'),
- $ = require('$'),
- _ = require('_'),
- ko = require('ko'),
-
- Enums = require('Common/Enums'),
- Utils = require('Common/Utils'),
- Globals = require('Common/Globals')
- ;
-
- /**
- * @constructor
- */
- function Translator()
- {
- this.data = window['rainloopI18N'] || {};
- this.notificationI18N = {};
-
- this.trigger = ko.observable(false);
-
- this.i18n = _.bind(this.i18n, this);
-
- this.init();
- }
-
- Translator.prototype.data = {};
- Translator.prototype.notificationI18N = {};
-
- /**
- * @param {string} sKey
- * @param {Object=} oValueList
- * @param {string=} sDefaulValue
- * @return {string}
- */
- Translator.prototype.i18n = function (sKey, oValueList, sDefaulValue)
- {
- var
- sValueName = '',
- sResult = _.isUndefined(this.data[sKey]) ? (_.isUndefined(sDefaulValue) ? sKey : sDefaulValue) : this.data[sKey]
- ;
-
- if (!_.isUndefined(oValueList) && !_.isNull(oValueList))
- {
- for (sValueName in oValueList)
- {
- if (_.has(oValueList, sValueName))
- {
- sResult = sResult.replace('%' + sValueName + '%', oValueList[sValueName]);
- }
- }
- }
-
- return sResult;
- };
-
- /**
- * @param {Object} oElement
- */
- Translator.prototype.i18nToNode = function (oElement)
- {
- var
- sKey = '',
- $oEl = $(oElement)
- ;
-
- sKey = $oEl.data('i18n');
- if (sKey)
- {
- if ('[' === sKey.substr(0, 1))
- {
- switch (sKey.substr(0, 6))
- {
- case '[html]':
- $oEl.html(this.i18n(sKey.substr(6)));
- break;
- case '[place':
- $oEl.attr('placeholder', this.i18n(sKey.substr(13)));
- break;
- case '[title':
- $oEl.attr('title', this.i18n(sKey.substr(7)));
- break;
- }
- }
- else
- {
- $oEl.text(this.i18n(sKey));
- }
- }
- };
-
- /**
- * @param {Object} oElements
- * @param {boolean=} bAnimate = false
- */
- Translator.prototype.i18nToNodes = function (oElements, bAnimate)
- {
- var self = this;
- _.defer(function () {
-
- $('[data-i18n]', oElements).each(function () {
- self.i18nToNode(this);
- });
-
- if (bAnimate && Globals.bAnimationSupported)
- {
- $('.i18n-animation[data-i18n]', oElements).letterfx({
- 'fx': 'fall fade', 'backwards': false, 'timing': 50, 'fx_duration': '50ms', 'letter_end': 'restore', 'element_end': 'restore'
- });
- }
- });
- };
-
- Translator.prototype.reloadData = function ()
- {
- if (window['rainloopI18N'])
- {
- this.data = window['rainloopI18N'] || {};
-
- this.i18nToNodes(window.document, true);
-
- require('Common/Momentor').reload();
- this.trigger(!this.trigger());
- }
-
- window['rainloopI18N'] = null;
- };
-
- Translator.prototype.initNotificationLanguage = function ()
- {
- var oN = this.notificationI18N || {};
-
- oN[Enums.Notification.InvalidToken] = this.i18n('NOTIFICATIONS/INVALID_TOKEN');
- oN[Enums.Notification.AuthError] = this.i18n('NOTIFICATIONS/AUTH_ERROR');
- oN[Enums.Notification.AccessError] = this.i18n('NOTIFICATIONS/ACCESS_ERROR');
- oN[Enums.Notification.ConnectionError] = this.i18n('NOTIFICATIONS/CONNECTION_ERROR');
- oN[Enums.Notification.CaptchaError] = this.i18n('NOTIFICATIONS/CAPTCHA_ERROR');
- oN[Enums.Notification.SocialFacebookLoginAccessDisable] = this.i18n('NOTIFICATIONS/SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE');
- oN[Enums.Notification.SocialTwitterLoginAccessDisable] = this.i18n('NOTIFICATIONS/SOCIAL_TWITTER_LOGIN_ACCESS_DISABLE');
- oN[Enums.Notification.SocialGoogleLoginAccessDisable] = this.i18n('NOTIFICATIONS/SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE');
- oN[Enums.Notification.DomainNotAllowed] = this.i18n('NOTIFICATIONS/DOMAIN_NOT_ALLOWED');
- oN[Enums.Notification.AccountNotAllowed] = this.i18n('NOTIFICATIONS/ACCOUNT_NOT_ALLOWED');
-
- oN[Enums.Notification.AccountTwoFactorAuthRequired] = this.i18n('NOTIFICATIONS/ACCOUNT_TWO_FACTOR_AUTH_REQUIRED');
- oN[Enums.Notification.AccountTwoFactorAuthError] = this.i18n('NOTIFICATIONS/ACCOUNT_TWO_FACTOR_AUTH_ERROR');
-
- oN[Enums.Notification.CouldNotSaveNewPassword] = this.i18n('NOTIFICATIONS/COULD_NOT_SAVE_NEW_PASSWORD');
- oN[Enums.Notification.CurrentPasswordIncorrect] = this.i18n('NOTIFICATIONS/CURRENT_PASSWORD_INCORRECT');
- oN[Enums.Notification.NewPasswordShort] = this.i18n('NOTIFICATIONS/NEW_PASSWORD_SHORT');
- oN[Enums.Notification.NewPasswordWeak] = this.i18n('NOTIFICATIONS/NEW_PASSWORD_WEAK');
- oN[Enums.Notification.NewPasswordForbidden] = this.i18n('NOTIFICATIONS/NEW_PASSWORD_FORBIDDENT');
-
- oN[Enums.Notification.ContactsSyncError] = this.i18n('NOTIFICATIONS/CONTACTS_SYNC_ERROR');
-
- oN[Enums.Notification.CantGetMessageList] = this.i18n('NOTIFICATIONS/CANT_GET_MESSAGE_LIST');
- oN[Enums.Notification.CantGetMessage] = this.i18n('NOTIFICATIONS/CANT_GET_MESSAGE');
- oN[Enums.Notification.CantDeleteMessage] = this.i18n('NOTIFICATIONS/CANT_DELETE_MESSAGE');
- oN[Enums.Notification.CantMoveMessage] = this.i18n('NOTIFICATIONS/CANT_MOVE_MESSAGE');
- oN[Enums.Notification.CantCopyMessage] = this.i18n('NOTIFICATIONS/CANT_MOVE_MESSAGE');
-
- oN[Enums.Notification.CantSaveMessage] = this.i18n('NOTIFICATIONS/CANT_SAVE_MESSAGE');
- oN[Enums.Notification.CantSendMessage] = this.i18n('NOTIFICATIONS/CANT_SEND_MESSAGE');
- oN[Enums.Notification.InvalidRecipients] = this.i18n('NOTIFICATIONS/INVALID_RECIPIENTS');
-
- oN[Enums.Notification.CantSaveFilters] = this.i18n('NOTIFICATIONS/CANT_SAVE_FILTERS');
- oN[Enums.Notification.CantGetFilters] = this.i18n('NOTIFICATIONS/CANT_GET_FILTERS');
- oN[Enums.Notification.FiltersAreNotCorrect] = this.i18n('NOTIFICATIONS/FILTERS_ARE_NOT_CORRECT');
-
- oN[Enums.Notification.CantCreateFolder] = this.i18n('NOTIFICATIONS/CANT_CREATE_FOLDER');
- oN[Enums.Notification.CantRenameFolder] = this.i18n('NOTIFICATIONS/CANT_RENAME_FOLDER');
- oN[Enums.Notification.CantDeleteFolder] = this.i18n('NOTIFICATIONS/CANT_DELETE_FOLDER');
- oN[Enums.Notification.CantDeleteNonEmptyFolder] = this.i18n('NOTIFICATIONS/CANT_DELETE_NON_EMPTY_FOLDER');
- oN[Enums.Notification.CantSubscribeFolder] = this.i18n('NOTIFICATIONS/CANT_SUBSCRIBE_FOLDER');
- oN[Enums.Notification.CantUnsubscribeFolder] = this.i18n('NOTIFICATIONS/CANT_UNSUBSCRIBE_FOLDER');
-
- oN[Enums.Notification.CantSaveSettings] = this.i18n('NOTIFICATIONS/CANT_SAVE_SETTINGS');
- oN[Enums.Notification.CantSavePluginSettings] = this.i18n('NOTIFICATIONS/CANT_SAVE_PLUGIN_SETTINGS');
-
- oN[Enums.Notification.DomainAlreadyExists] = this.i18n('NOTIFICATIONS/DOMAIN_ALREADY_EXISTS');
-
- oN[Enums.Notification.CantInstallPackage] = this.i18n('NOTIFICATIONS/CANT_INSTALL_PACKAGE');
- oN[Enums.Notification.CantDeletePackage] = this.i18n('NOTIFICATIONS/CANT_DELETE_PACKAGE');
- oN[Enums.Notification.InvalidPluginPackage] = this.i18n('NOTIFICATIONS/INVALID_PLUGIN_PACKAGE');
- oN[Enums.Notification.UnsupportedPluginPackage] = this.i18n('NOTIFICATIONS/UNSUPPORTED_PLUGIN_PACKAGE');
-
- oN[Enums.Notification.LicensingServerIsUnavailable] = this.i18n('NOTIFICATIONS/LICENSING_SERVER_IS_UNAVAILABLE');
- oN[Enums.Notification.LicensingExpired] = this.i18n('NOTIFICATIONS/LICENSING_EXPIRED');
- oN[Enums.Notification.LicensingBanned] = this.i18n('NOTIFICATIONS/LICENSING_BANNED');
-
- oN[Enums.Notification.DemoSendMessageError] = this.i18n('NOTIFICATIONS/DEMO_SEND_MESSAGE_ERROR');
- oN[Enums.Notification.DemoAccountError] = this.i18n('NOTIFICATIONS/DEMO_ACCOUNT_ERROR');
-
- oN[Enums.Notification.AccountAlreadyExists] = this.i18n('NOTIFICATIONS/ACCOUNT_ALREADY_EXISTS');
- oN[Enums.Notification.AccountDoesNotExist] = this.i18n('NOTIFICATIONS/ACCOUNT_DOES_NOT_EXIST');
-
- oN[Enums.Notification.MailServerError] = this.i18n('NOTIFICATIONS/MAIL_SERVER_ERROR');
- oN[Enums.Notification.InvalidInputArgument] = this.i18n('NOTIFICATIONS/INVALID_INPUT_ARGUMENT');
- oN[Enums.Notification.UnknownNotification] = this.i18n('NOTIFICATIONS/UNKNOWN_ERROR');
- oN[Enums.Notification.UnknownError] = this.i18n('NOTIFICATIONS/UNKNOWN_ERROR');
- };
-
- /**
- * @param {Function} fCallback
- * @param {Object} oScope
- * @param {Function=} fLangCallback
- */
- Translator.prototype.initOnStartOrLangChange = function (fCallback, oScope, fLangCallback)
- {
- if (fCallback)
- {
- fCallback.call(oScope);
- }
-
- if (fLangCallback)
- {
- this.trigger.subscribe(function () {
- if (fCallback)
- {
- fCallback.call(oScope);
- }
-
- fLangCallback.call(oScope);
- });
- }
- else if (fCallback)
- {
- this.trigger.subscribe(fCallback, oScope);
- }
- };
-
- /**
- * @param {number} iCode
- * @param {*=} mMessage = ''
- * @param {*=} mDefCode = null
- * @return {string}
- */
- Translator.prototype.getNotification = function (iCode, mMessage, mDefCode)
- {
- iCode = window.parseInt(iCode, 10) || 0;
- if (Enums.Notification.ClientViewError === iCode && mMessage)
- {
- return mMessage;
- }
-
- return _.isUndefined(this.notificationI18N[iCode]) ? (
- mDefCode && _.isUndefined(this.notificationI18N[mDefCode]) ? this.notificationI18N[mDefCode] : ''
- ) : this.notificationI18N[iCode];
- };
-
- /**
- * @param {*} mCode
- * @return {string}
- */
- Translator.prototype.getUploadErrorDescByCode = function (mCode)
- {
- var sResult = '';
- switch (window.parseInt(mCode, 10) || 0) {
- case Enums.UploadErrorCode.FileIsTooBig:
- sResult = this.i18n('UPLOAD/ERROR_FILE_IS_TOO_BIG');
- break;
- case Enums.UploadErrorCode.FilePartiallyUploaded:
- sResult = this.i18n('UPLOAD/ERROR_FILE_PARTIALLY_UPLOADED');
- break;
- case Enums.UploadErrorCode.FileNoUploaded:
- sResult = this.i18n('UPLOAD/ERROR_NO_FILE_UPLOADED');
- break;
- case Enums.UploadErrorCode.MissingTempFolder:
- sResult = this.i18n('UPLOAD/ERROR_MISSING_TEMP_FOLDER');
- break;
- case Enums.UploadErrorCode.FileOnSaveingError:
- sResult = this.i18n('UPLOAD/ERROR_ON_SAVING_FILE');
- break;
- case Enums.UploadErrorCode.FileType:
- sResult = this.i18n('UPLOAD/ERROR_FILE_TYPE');
- break;
- default:
- sResult = this.i18n('UPLOAD/ERROR_UNKNOWN');
- break;
- }
-
- return sResult;
- };
-
- /**
- * @param {boolean} bAdmin
- * @param {string} sLanguage
- * @param {Function=} fDone
- * @param {Function=} fFail
- */
- Translator.prototype.reload = function (bAdmin, sLanguage, fDone, fFail)
- {
- var
- self = this,
- iStart = (new Date()).getTime()
- ;
-
- Globals.$html.addClass('rl-changing-language');
-
- $.ajax({
- 'url': require('Common/Links').langLink(sLanguage, bAdmin),
- 'dataType': 'script',
- 'cache': true
- })
- .fail(fFail || Utils.emptyFunction)
- .done(function () {
- _.delay(function () {
-
- self.reloadData();
-
- (fDone || Utils.emptyFunction)();
-
- Globals.$html
- .removeClass('rl-changing-language')
- .removeClass('rl-rtl rl-ltr')
- .addClass(-1 < Utils.inArray(sLanguage, ['ar', 'he', 'ur']) ? 'rl-rtl' : 'rl-ltr')
-// .attr('dir', -1 < Utils.inArray(sLanguage, ['ar', 'he', 'ur']) ? 'rtl' : 'ltr')
- ;
-
- }, 500 < (new Date()).getTime() - iStart ? 1 : 500);
- })
- ;
- };
-
- Translator.prototype.init = function ()
- {
- Globals.$html.addClass('rl-' + (Globals.$html.attr('dir') || 'ltr'));
- };
-
- module.exports = new Translator();
-
-}());
diff --git a/dev/Common/Translator.jsx b/dev/Common/Translator.jsx
new file mode 100644
index 000000000..81b991aa1
--- /dev/null
+++ b/dev/Common/Translator.jsx
@@ -0,0 +1,319 @@
+
+import {window, $, _} from 'common';
+import ko from 'ko';
+import {Notification, UploadErrorCode} from 'Common/Enums';
+import Utils from 'Common/Utils';
+import Globals from 'Common/Globals';
+
+class Translator
+{
+ constructor() {
+ this.data = window['rainloopI18N'] || {};
+ this.notificationI18N = {};
+ this.trigger = ko.observable(false);
+ this.i18n = _.bind(this.i18n, this);
+ this.init();
+ }
+
+ /**
+ * @param {string} key
+ * @param {Object=} valueList
+ * @param {string=} defaulValue
+ * @return {string}
+ */
+ i18n(key, valueList, defaulValue) {
+
+ let
+ valueName = '',
+ result = _.isUndefined(this.data[key]) ? (_.isUndefined(defaulValue) ? key : defaulValue) : this.data[key]
+ ;
+
+ if (!_.isUndefined(valueList) && !_.isNull(valueList))
+ {
+ for (valueName in valueList)
+ {
+ if (_.has(valueList, valueName))
+ {
+ result = result.replace('%' + valueName + '%', valueList[valueName]);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * @param {Object} element
+ */
+ i18nToNode(element) {
+
+ const
+ $el = $(element),
+ key = $el.data('i18n')
+ ;
+
+ if (key)
+ {
+ if ('[' === key.substr(0, 1))
+ {
+ switch (key.substr(0, 6))
+ {
+ case '[html]':
+ $el.html(this.i18n(key.substr(6)));
+ break;
+ case '[place':
+ $el.attr('placeholder', this.i18n(key.substr(13)));
+ break;
+ case '[title':
+ $el.attr('title', this.i18n(key.substr(7)));
+ break;
+ }
+ }
+ else
+ {
+ $el.text(this.i18n(key));
+ }
+ }
+ }
+
+ /**
+ * @param {Object} elements
+ * @param {boolean=} animate = false
+ */
+ i18nToNodes(elements, animate = false) {
+ _.defer(() => {
+
+ $('[data-i18n]', elements).each((index, item) => {
+ this.i18nToNode(item);
+ });
+
+ if (animate && Globals.bAnimationSupported)
+ {
+ $('.i18n-animation[data-i18n]', elements).letterfx({
+ 'fx': 'fall fade', 'backwards': false, 'timing': 50, 'fx_duration': '50ms', 'letter_end': 'restore', 'element_end': 'restore'
+ });
+ }
+ });
+ }
+
+ reloadData() {
+ if (window['rainloopI18N'])
+ {
+ this.data = window['rainloopI18N'] || {};
+
+ this.i18nToNodes(window.document, true);
+
+ require('Common/Momentor').reload();
+ this.trigger(!this.trigger());
+ }
+
+ window['rainloopI18N'] = null;
+ }
+
+ initNotificationLanguage() {
+
+ const map = [
+ [Notification.InvalidToken, 'NOTIFICATIONS/INVALID_TOKEN'],
+ [Notification.InvalidToken, 'NOTIFICATIONS/INVALID_TOKEN'],
+ [Notification.AuthError, 'NOTIFICATIONS/AUTH_ERROR'],
+ [Notification.AccessError, 'NOTIFICATIONS/ACCESS_ERROR'],
+ [Notification.ConnectionError, 'NOTIFICATIONS/CONNECTION_ERROR'],
+ [Notification.CaptchaError, 'NOTIFICATIONS/CAPTCHA_ERROR'],
+ [Notification.SocialFacebookLoginAccessDisable, 'NOTIFICATIONS/SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE'],
+ [Notification.SocialTwitterLoginAccessDisable, 'NOTIFICATIONS/SOCIAL_TWITTER_LOGIN_ACCESS_DISABLE'],
+ [Notification.SocialGoogleLoginAccessDisable, 'NOTIFICATIONS/SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE'],
+ [Notification.DomainNotAllowed, 'NOTIFICATIONS/DOMAIN_NOT_ALLOWED'],
+ [Notification.AccountNotAllowed, 'NOTIFICATIONS/ACCOUNT_NOT_ALLOWED'],
+
+ [Notification.AccountTwoFactorAuthRequired, 'NOTIFICATIONS/ACCOUNT_TWO_FACTOR_AUTH_REQUIRED'],
+ [Notification.AccountTwoFactorAuthError, 'NOTIFICATIONS/ACCOUNT_TWO_FACTOR_AUTH_ERROR'],
+
+ [Notification.CouldNotSaveNewPassword, 'NOTIFICATIONS/COULD_NOT_SAVE_NEW_PASSWORD'],
+ [Notification.CurrentPasswordIncorrect, 'NOTIFICATIONS/CURRENT_PASSWORD_INCORRECT'],
+ [Notification.NewPasswordShort, 'NOTIFICATIONS/NEW_PASSWORD_SHORT'],
+ [Notification.NewPasswordWeak, 'NOTIFICATIONS/NEW_PASSWORD_WEAK'],
+ [Notification.NewPasswordForbidden, 'NOTIFICATIONS/NEW_PASSWORD_FORBIDDENT'],
+
+ [Notification.ContactsSyncError, 'NOTIFICATIONS/CONTACTS_SYNC_ERROR'],
+
+ [Notification.CantGetMessageList, 'NOTIFICATIONS/CANT_GET_MESSAGE_LIST'],
+ [Notification.CantGetMessage, 'NOTIFICATIONS/CANT_GET_MESSAGE'],
+ [Notification.CantDeleteMessage, 'NOTIFICATIONS/CANT_DELETE_MESSAGE'],
+ [Notification.CantMoveMessage, 'NOTIFICATIONS/CANT_MOVE_MESSAGE'],
+ [Notification.CantCopyMessage, 'NOTIFICATIONS/CANT_MOVE_MESSAGE'],
+
+ [Notification.CantSaveMessage, 'NOTIFICATIONS/CANT_SAVE_MESSAGE'],
+ [Notification.CantSendMessage, 'NOTIFICATIONS/CANT_SEND_MESSAGE'],
+ [Notification.InvalidRecipients, 'NOTIFICATIONS/INVALID_RECIPIENTS'],
+
+ [Notification.CantSaveFilters, 'NOTIFICATIONS/CANT_SAVE_FILTERS'],
+ [Notification.CantGetFilters, 'NOTIFICATIONS/CANT_GET_FILTERS'],
+ [Notification.FiltersAreNotCorrect, 'NOTIFICATIONS/FILTERS_ARE_NOT_CORRECT'],
+
+ [Notification.CantCreateFolder, 'NOTIFICATIONS/CANT_CREATE_FOLDER'],
+ [Notification.CantRenameFolder, 'NOTIFICATIONS/CANT_RENAME_FOLDER'],
+ [Notification.CantDeleteFolder, 'NOTIFICATIONS/CANT_DELETE_FOLDER'],
+ [Notification.CantDeleteNonEmptyFolder, 'NOTIFICATIONS/CANT_DELETE_NON_EMPTY_FOLDER'],
+ [Notification.CantSubscribeFolder, 'NOTIFICATIONS/CANT_SUBSCRIBE_FOLDER'],
+ [Notification.CantUnsubscribeFolder, 'NOTIFICATIONS/CANT_UNSUBSCRIBE_FOLDER'],
+
+ [Notification.CantSaveSettings, 'NOTIFICATIONS/CANT_SAVE_SETTINGS'],
+ [Notification.CantSavePluginSettings, 'NOTIFICATIONS/CANT_SAVE_PLUGIN_SETTINGS'],
+
+ [Notification.DomainAlreadyExists, 'NOTIFICATIONS/DOMAIN_ALREADY_EXISTS'],
+
+ [Notification.CantInstallPackage, 'NOTIFICATIONS/CANT_INSTALL_PACKAGE'],
+ [Notification.CantDeletePackage, 'NOTIFICATIONS/CANT_DELETE_PACKAGE'],
+ [Notification.InvalidPluginPackage, 'NOTIFICATIONS/INVALID_PLUGIN_PACKAGE'],
+ [Notification.UnsupportedPluginPackage, 'NOTIFICATIONS/UNSUPPORTED_PLUGIN_PACKAGE'],
+
+ [Notification.LicensingServerIsUnavailable, 'NOTIFICATIONS/LICENSING_SERVER_IS_UNAVAILABLE'],
+ [Notification.LicensingExpired, 'NOTIFICATIONS/LICENSING_EXPIRED'],
+ [Notification.LicensingBanned, 'NOTIFICATIONS/LICENSING_BANNED'],
+
+ [Notification.DemoSendMessageError, 'NOTIFICATIONS/DEMO_SEND_MESSAGE_ERROR'],
+ [Notification.DemoAccountError, 'NOTIFICATIONS/DEMO_ACCOUNT_ERROR'],
+
+ [Notification.AccountAlreadyExists, 'NOTIFICATIONS/ACCOUNT_ALREADY_EXISTS'],
+ [Notification.AccountDoesNotExist, 'NOTIFICATIONS/ACCOUNT_DOES_NOT_EXIST'],
+
+ [Notification.MailServerError, 'NOTIFICATIONS/MAIL_SERVER_ERROR'],
+ [Notification.InvalidInputArgument, 'NOTIFICATIONS/INVALID_INPUT_ARGUMENT'],
+ [Notification.UnknownNotification, 'NOTIFICATIONS/UNKNOWN_ERROR'],
+ [Notification.UnknownError, 'NOTIFICATIONS/UNKNOWN_ERROR']
+ ];
+
+ this.notificationI18N = this.notificationI18N || {};
+
+ _.each(map, (item) => {
+ this.notificationI18N[item[0]] = this.i18n(item[1]);
+ });
+ }
+
+ /**
+ * @param {Function} callback
+ * @param {Object} scope
+ * @param {Function=} langCallback
+ */
+ initOnStartOrLangChange(callback, scope, langCallback = null) {
+ if (callback)
+ {
+ callback.call(scope);
+ }
+
+ if (langCallback)
+ {
+ this.trigger.subscribe(() => {
+ if (callback)
+ {
+ callback.call(scope);
+ }
+
+ langCallback.call(scope);
+ });
+ }
+ else if (callback)
+ {
+ this.trigger.subscribe(callback, scope);
+ }
+ }
+
+ /**
+ * @param {number} code
+ * @param {*=} message = ''
+ * @param {*=} defCode = null
+ * @return {string}
+ */
+ getNotification(code, message = '', defCode = null) {
+ code = window.parseInt(code, 10) || 0;
+ if (Notification.ClientViewError === code && message)
+ {
+ return message;
+ }
+
+ return _.isUndefined(this.notificationI18N[code]) ? (
+ defCode && _.isUndefined(this.notificationI18N[defCode]) ? this.notificationI18N[defCode] : ''
+ ) : this.notificationI18N[code];
+ }
+
+ /**
+ * @param {*} code
+ * @return {string}
+ */
+ getUploadErrorDescByCode(code) {
+ let result = '';
+ switch (window.parseInt(code, 10) || 0) {
+ case UploadErrorCode.FileIsTooBig:
+ result = this.i18n('UPLOAD/ERROR_FILE_IS_TOO_BIG');
+ break;
+ case UploadErrorCode.FilePartiallyUploaded:
+ result = this.i18n('UPLOAD/ERROR_FILE_PARTIALLY_UPLOADED');
+ break;
+ case UploadErrorCode.FileNoUploaded:
+ result = this.i18n('UPLOAD/ERROR_NO_FILE_UPLOADED');
+ break;
+ case UploadErrorCode.MissingTempFolder:
+ result = this.i18n('UPLOAD/ERROR_MISSING_TEMP_FOLDER');
+ break;
+ case UploadErrorCode.FileOnSaveingError:
+ result = this.i18n('UPLOAD/ERROR_ON_SAVING_FILE');
+ break;
+ case UploadErrorCode.FileType:
+ result = this.i18n('UPLOAD/ERROR_FILE_TYPE');
+ break;
+ default:
+ result = this.i18n('UPLOAD/ERROR_UNKNOWN');
+ break;
+ }
+
+ return result;
+ }
+
+ /**
+ * @param {boolean} admin
+ * @param {string} language
+ * @param {Function=} done
+ * @param {Function=} fail
+ */
+ reload(admin, language, done, fail) {
+
+ const
+ self = this,
+ start = Utils.microtime()
+ ;
+
+ Globals.$html.addClass('rl-changing-language');
+
+ $.ajax({
+ 'url': require('Common/Links').langLink(language, admin),
+ 'dataType': 'script',
+ 'cache': true
+ })
+ .fail(fail || Utils.emptyFunction)
+ .done(function () {
+ _.delay(function () {
+
+ self.reloadData();
+
+ (done || Utils.emptyFunction)();
+
+ const isRtl = -1 < Utils.inArray(language, ['ar', 'ar_sa', 'he', 'he_he', 'ur', 'ur_ir']);
+
+ Globals.$html
+ .removeClass('rl-changing-language')
+ .removeClass('rl-rtl rl-ltr')
+ .addClass(isRtl ? 'rl-rtl' : 'rl-ltr')
+ // .attr('dir', isRtl ? 'rtl' : 'ltr')
+ ;
+
+ }, 500 < Utils.microtime() - start ? 1 : 500);
+ })
+ ;
+ }
+
+ init() {
+ Globals.$html.addClass('rl-' + (Globals.$html.attr('dir') || 'ltr'));
+ }
+}
+
+module.exports = new Translator();
diff --git a/dev/Common/Utils.js b/dev/Common/Utils.js
index b59caddc8..85a6773fd 100644
--- a/dev/Common/Utils.js
+++ b/dev/Common/Utils.js
@@ -28,7 +28,7 @@
Utils.isFunc = _.isFunction;
Utils.isUnd = _.isUndefined;
Utils.isNull = _.isNull;
- Utils.emptyFunction = function () {};
+ Utils.emptyFunction = Utils.noop = function () {};
/**
* @param {*} oValue
diff --git a/dev/Component/AbstracCheckbox.js b/dev/Component/AbstracCheckbox.js
deleted file mode 100644
index de4696b92..000000000
--- a/dev/Component/AbstracCheckbox.js
+++ /dev/null
@@ -1,68 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- _ = require('_'),
- ko = require('ko'),
-
- Utils = require('Common/Utils'),
-
- AbstractComponent = require('Component/Abstract')
- ;
-
- /**
- * @constructor
- *
- * @param {Object} oParams
- *
- * @extends AbstractComponent
- */
- function AbstracCheckbox(oParams)
- {
- AbstractComponent.call(this);
-
- this.value = oParams.value;
- if (Utils.isUnd(this.value) || !this.value.subscribe)
- {
- this.value = ko.observable(Utils.isUnd(this.value) ? false : !!this.value);
- }
-
- this.enable = oParams.enable;
- if (Utils.isUnd(this.enable) || !this.enable.subscribe)
- {
- this.enable = ko.observable(Utils.isUnd(this.enable) ? true : !!this.enable);
- }
-
- this.disable = oParams.disable;
- if (Utils.isUnd(this.disable) || !this.disable.subscribe)
- {
- this.disable = ko.observable(Utils.isUnd(this.disable) ? false : !!this.disable);
- }
-
- this.label = oParams.label || '';
- this.inline = Utils.isUnd(oParams.inline) ? false : oParams.inline;
-
- this.readOnly = Utils.isUnd(oParams.readOnly) ? false : !!oParams.readOnly;
- this.inverted = Utils.isUnd(oParams.inverted) ? false : !!oParams.inverted;
-
- this.labeled = !Utils.isUnd(oParams.label);
- this.labelAnimated = !!oParams.labelAnimated;
- }
-
- _.extend(AbstracCheckbox.prototype, AbstractComponent.prototype);
-
- AbstracCheckbox.prototype.click = function()
- {
- if (!this.readOnly && this.enable() && !this.disable())
- {
- this.value(!this.value());
- }
- };
-
- AbstracCheckbox.componentExportHelper = AbstractComponent.componentExportHelper;
-
- module.exports = AbstracCheckbox;
-
-}());
diff --git a/dev/Component/AbstracCheckbox.jsx b/dev/Component/AbstracCheckbox.jsx
new file mode 100644
index 000000000..f77bb51d2
--- /dev/null
+++ b/dev/Component/AbstracCheckbox.jsx
@@ -0,0 +1,51 @@
+
+import ko from 'ko';
+import Utils from 'Common/Utils';
+import {AbstractComponent} from 'Component/Abstract';
+
+class AbstracCheckbox extends AbstractComponent
+{
+ /**
+ * @param {Object} params
+ */
+ constructor(params) {
+
+ super();
+
+ this.value = params.value;
+ if (Utils.isUnd(this.value) || !this.value.subscribe)
+ {
+ this.value = ko.observable(Utils.isUnd(this.value) ? false : !!this.value);
+ }
+
+ this.enable = params.enable;
+ if (Utils.isUnd(this.enable) || !this.enable.subscribe)
+ {
+ this.enable = ko.observable(Utils.isUnd(this.enable) ? true : !!this.enable);
+ }
+
+ this.disable = params.disable;
+ if (Utils.isUnd(this.disable) || !this.disable.subscribe)
+ {
+ this.disable = ko.observable(Utils.isUnd(this.disable) ? false : !!this.disable);
+ }
+
+ this.label = params.label || '';
+ this.inline = Utils.isUnd(params.inline) ? false : params.inline;
+
+ this.readOnly = Utils.isUnd(params.readOnly) ? false : !!params.readOnly;
+ this.inverted = Utils.isUnd(params.inverted) ? false : !!params.inverted;
+
+ this.labeled = !Utils.isUnd(params.label);
+ this.labelAnimated = !!params.labelAnimated;
+ }
+
+ click() {
+ if (!this.readOnly && this.enable() && !this.disable())
+ {
+ this.value(!this.value());
+ }
+ }
+}
+
+export {AbstracCheckbox, AbstracCheckbox as default};
diff --git a/dev/Component/AbstracRadio.js b/dev/Component/AbstracRadio.js
deleted file mode 100644
index cbe8eefb8..000000000
--- a/dev/Component/AbstracRadio.js
+++ /dev/null
@@ -1,65 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- _ = require('_'),
- ko = require('ko'),
-
- Utils = require('Common/Utils'),
-
- AbstractComponent = require('Component/Abstract')
- ;
-
- /**
- * @constructor
- *
- * @param {Object} oParams
- *
- * @extends AbstractComponent
- */
- function AbstracRadio(oParams)
- {
- AbstractComponent.call(this);
-
- this.values = ko.observableArray([]);
-
- this.value = oParams.value;
- if (Utils.isUnd(this.value) || !this.value.subscribe)
- {
- this.value = ko.observable('');
- }
-
- this.inline = Utils.isUnd(oParams.inline) ? false : oParams.inline;
- this.readOnly = Utils.isUnd(oParams.readOnly) ? false : !!oParams.readOnly;
-
- if (oParams.values)
- {
- var aValues = _.map(oParams.values, function (sLabel, sValue) {
- return {
- 'label': sLabel,
- 'value': sValue
- };
- });
-
- this.values(aValues);
- }
-
- this.click = _.bind(this.click, this);
- }
-
- AbstracRadio.prototype.click = function(oValue) {
- if (!this.readOnly && oValue)
- {
- this.value(oValue.value);
- }
- };
-
- _.extend(AbstracRadio.prototype, AbstractComponent.prototype);
-
- AbstracRadio.componentExportHelper = AbstractComponent.componentExportHelper;
-
- module.exports = AbstracRadio;
-
-}());
diff --git a/dev/Component/AbstracRadio.jsx b/dev/Component/AbstracRadio.jsx
new file mode 100644
index 000000000..a1f5de237
--- /dev/null
+++ b/dev/Component/AbstracRadio.jsx
@@ -0,0 +1,48 @@
+
+import {_} from 'common';
+import ko from 'ko';
+import Utils from 'Common/Utils';
+import {AbstractComponent} from 'Component/Abstract';
+
+class AbstracRadio extends AbstractComponent
+{
+ /**
+ * @param {Object} params
+ */
+ constructor(params) {
+
+ super();
+
+ this.values = ko.observableArray([]);
+
+ this.value = params.value;
+ if (Utils.isUnd(this.value) || !this.value.subscribe)
+ {
+ this.value = ko.observable('');
+ }
+
+ this.inline = Utils.isUnd(params.inline) ? false : params.inline;
+ this.readOnly = Utils.isUnd(params.readOnly) ? false : !!params.readOnly;
+
+ if (params.values)
+ {
+ this.values(_.map(params.values, (label, value) => {
+ return {
+ 'label': label,
+ 'value': value
+ };
+ }));
+ }
+
+ this.click = _.bind(this.click, this);
+ }
+
+ click(value) {
+ if (!this.readOnly && value)
+ {
+ this.value(value.value);
+ }
+ };
+}
+
+export {AbstracRadio, AbstracRadio as default};
diff --git a/dev/Component/Abstract.js b/dev/Component/Abstract.js
deleted file mode 100644
index 4b5dfb91b..000000000
--- a/dev/Component/Abstract.js
+++ /dev/null
@@ -1,76 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- _ = require('_'),
- ko = require('ko'),
-
- Utils = require('Common/Utils')
- ;
-
- /**
- * @constructor
- */
- function AbstractComponent()
- {
- this.disposable = [];
- }
-
- /**
- * @type {Array}
- */
- AbstractComponent.prototype.disposable = [];
-
- AbstractComponent.prototype.dispose = function ()
- {
- _.each(this.disposable, function (fFuncToDispose) {
- if (fFuncToDispose && fFuncToDispose.dispose)
- {
- fFuncToDispose.dispose();
- }
- });
- };
-
- /**
- * @param {*} ClassObject
- * @param {string} sTemplateID
- * @return {Object}
- */
- AbstractComponent.componentExportHelper = function (ClassObject, sTemplateID) {
- var oComponent = {
- viewModel: {
- createViewModel: function(oParams, oComponentInfo) {
-
- oParams = oParams || {};
- oParams.element = null;
-
- if (oComponentInfo.element)
- {
- oParams.component = oComponentInfo;
- oParams.element = $(oComponentInfo.element);
-
- require('Common/Translator').i18nToNodes(oParams.element);
-
- if (!Utils.isUnd(oParams.inline) && ko.unwrap(oParams.inline))
- {
- oParams.element.css('display', 'inline-block');
- }
- }
-
- return new ClassObject(oParams);
- }
- }
- };
-
- oComponent['template'] = sTemplateID ? {
- element: sTemplateID
- } : ' ';
-
- return oComponent;
- };
-
- module.exports = AbstractComponent;
-
-}());
diff --git a/dev/Component/Abstract.jsx b/dev/Component/Abstract.jsx
new file mode 100644
index 000000000..d1547ae2d
--- /dev/null
+++ b/dev/Component/Abstract.jsx
@@ -0,0 +1,55 @@
+
+import {_} from 'common';
+import ko from 'ko';
+import Utils from 'Common/Utils';
+
+class AbstractComponent
+{
+ constructor() {
+ this.disposable = [];
+ }
+
+ dispose() {
+ _.each(this.disposable, (funcToDispose) => {
+ if (funcToDispose && funcToDispose.dispose)
+ {
+ funcToDispose.dispose();
+ }
+ });
+ }
+}
+
+/**
+ * @param {*} ClassObject
+ * @param {string} templateID
+ * @return {Object}
+ */
+const componentExportHelper = (ClassObject, templateID) => {
+ return {
+ template: templateID ? {element: templateID} : ' ',
+ viewModel: {
+ createViewModel: (params, componentInfo) => {
+
+ params = params || {};
+ params.element = null;
+
+ if (componentInfo && componentInfo.element)
+ {
+ params.component = componentInfo;
+ params.element = $(componentInfo.element);
+
+ require('Common/Translator').i18nToNodes(params.element);
+
+ if (!Utils.isUnd(params.inline) && ko.unwrap(params.inline))
+ {
+ params.element.css('display', 'inline-block');
+ }
+ }
+
+ return new ClassObject(params);
+ }
+ }
+ };
+}
+
+export {AbstractComponent, componentExportHelper};
diff --git a/dev/Component/AbstractInput.js b/dev/Component/AbstractInput.js
deleted file mode 100644
index 16e9a82ed..000000000
--- a/dev/Component/AbstractInput.js
+++ /dev/null
@@ -1,92 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- _ = require('_'),
- ko = require('ko'),
-
- Enums = require('Common/Enums'),
- Utils = require('Common/Utils'),
-
- AbstractComponent = require('Component/Abstract')
- ;
-
- /**
- * @constructor
- *
- * @param {Object} oParams
- *
- * @extends AbstractComponent
- */
- function AbstractInput(oParams)
- {
- AbstractComponent.call(this);
-
- this.value = oParams.value || '';
- this.size = oParams.size || 0;
- this.label = oParams.label || '';
- this.preLabel = oParams.preLabel || '';
- this.enable = Utils.isUnd(oParams.enable) ? true : oParams.enable;
- this.trigger = oParams.trigger && oParams.trigger.subscribe ? oParams.trigger : null;
- this.placeholder = oParams.placeholder || '';
-
- this.labeled = !Utils.isUnd(oParams.label);
- this.preLabeled = !Utils.isUnd(oParams.preLabel);
- this.triggered = !Utils.isUnd(oParams.trigger) && !!this.trigger;
-
- this.classForTrigger = ko.observable('');
-
- this.className = ko.computed(function () {
-
- var
- iSize = ko.unwrap(this.size),
- sSuffixValue = this.trigger ?
- ' ' + Utils.trim('settings-saved-trigger-input ' + this.classForTrigger()) : ''
- ;
-
- return (0 < iSize ? 'span' + iSize : '') + sSuffixValue;
-
- }, this);
-
- if (!Utils.isUnd(oParams.width) && oParams.element)
- {
- oParams.element.find('input,select,textarea').css('width', oParams.width);
- }
-
- this.disposable.push(this.className);
-
- if (this.trigger)
- {
- this.setTriggerState(this.trigger());
-
- this.disposable.push(
- this.trigger.subscribe(this.setTriggerState, this)
- );
- }
- }
-
- AbstractInput.prototype.setTriggerState = function (nValue)
- {
- switch (Utils.pInt(nValue))
- {
- case Enums.SaveSettingsStep.TrueResult:
- this.classForTrigger('success');
- break;
- case Enums.SaveSettingsStep.FalseResult:
- this.classForTrigger('error');
- break;
- default:
- this.classForTrigger('');
- break;
- }
- };
-
- _.extend(AbstractInput.prototype, AbstractComponent.prototype);
-
- AbstractInput.componentExportHelper = AbstractComponent.componentExportHelper;
-
- module.exports = AbstractInput;
-
-}());
diff --git a/dev/Component/AbstractInput.jsx b/dev/Component/AbstractInput.jsx
new file mode 100644
index 000000000..6f9a45aa6
--- /dev/null
+++ b/dev/Component/AbstractInput.jsx
@@ -0,0 +1,75 @@
+
+import ko from 'ko';
+import Utils from 'Common/Utils';
+import {SaveSettingsStep} from 'Common/Enums';
+import {AbstractComponent} from 'Component/Abstract';
+
+class AbstractInput extends AbstractComponent
+{
+ /**
+ * @param {Object} params
+ */
+ constructor(params) {
+
+ super();
+
+ this.value = params.value || '';
+ this.size = params.size || 0;
+ this.label = params.label || '';
+ this.preLabel = params.preLabel || '';
+ this.enable = Utils.isUnd(params.enable) ? true : params.enable;
+ this.trigger = params.trigger && params.trigger.subscribe ? params.trigger : null;
+ this.placeholder = params.placeholder || '';
+
+ this.labeled = !Utils.isUnd(params.label);
+ this.preLabeled = !Utils.isUnd(params.preLabel);
+ this.triggered = !Utils.isUnd(params.trigger) && !!this.trigger;
+
+ this.classForTrigger = ko.observable('');
+
+ this.className = ko.computed(() => {
+
+ var
+ size = ko.unwrap(this.size),
+ suffixValue = this.trigger ?
+ ' ' + Utils.trim('settings-saved-trigger-input ' + this.classForTrigger()) : ''
+ ;
+
+ return (0 < size ? 'span' + size : '') + suffixValue;
+
+ }, this);
+
+ if (!Utils.isUnd(params.width) && params.element)
+ {
+ params.element.find('input,select,textarea').css('width', params.width);
+ }
+
+ this.disposable.push(this.className);
+
+ if (this.trigger)
+ {
+ this.setTriggerState(this.trigger());
+
+ this.disposable.push(
+ this.trigger.subscribe(this.setTriggerState, this)
+ );
+ }
+ }
+
+ setTriggerState(value) {
+ switch (Utils.pInt(value))
+ {
+ case SaveSettingsStep.TrueResult:
+ this.classForTrigger('success');
+ break;
+ case SaveSettingsStep.FalseResult:
+ this.classForTrigger('error');
+ break;
+ default:
+ this.classForTrigger('');
+ break;
+ }
+ }
+}
+
+export {AbstractInput, AbstractInput as default};
diff --git a/dev/Component/Checkbox.js b/dev/Component/Checkbox.js
deleted file mode 100644
index 5e1b6e9db..000000000
--- a/dev/Component/Checkbox.js
+++ /dev/null
@@ -1,29 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- _ = require('_'),
-
- AbstracCheckbox = require('Component/AbstracCheckbox')
- ;
-
- /**
- * @constructor
- *
- * @param {Object} oParams
- *
- * @extends AbstracCheckbox
- */
- function CheckboxComponent(oParams)
- {
- AbstracCheckbox.call(this, oParams);
- }
-
- _.extend(CheckboxComponent.prototype, AbstracCheckbox.prototype);
-
- module.exports = AbstracCheckbox.componentExportHelper(
- CheckboxComponent, 'CheckboxComponent');
-
-}());
diff --git a/dev/Component/Checkbox.jsx b/dev/Component/Checkbox.jsx
new file mode 100644
index 000000000..fce2ce496
--- /dev/null
+++ b/dev/Component/Checkbox.jsx
@@ -0,0 +1,7 @@
+
+import {componentExportHelper} from 'Component/Abstract';
+import {AbstracCheckbox} from 'Component/AbstracCheckbox';
+
+class CheckboxComponent extends AbstracCheckbox {}
+
+module.exports = componentExportHelper(CheckboxComponent, 'CheckboxComponent');
diff --git a/dev/Component/Classic/Checkbox.js b/dev/Component/Classic/Checkbox.js
deleted file mode 100644
index 1f9e9ce72..000000000
--- a/dev/Component/Classic/Checkbox.js
+++ /dev/null
@@ -1,29 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- _ = require('_'),
-
- AbstracCheckbox = require('Component/AbstracCheckbox')
- ;
-
- /**
- * @constructor
- *
- * @param {Object} oParams
- *
- * @extends AbstracCheckbox
- */
- function ClassicCheckboxComponent(oParams)
- {
- AbstracCheckbox.call(this, oParams);
- }
-
- _.extend(ClassicCheckboxComponent.prototype, AbstracCheckbox.prototype);
-
- module.exports = AbstracCheckbox.componentExportHelper(
- ClassicCheckboxComponent, 'CheckboxClassicComponent');
-
-}());
diff --git a/dev/Component/Classic/Checkbox.jsx b/dev/Component/Classic/Checkbox.jsx
new file mode 100644
index 000000000..aa8b1fd8e
--- /dev/null
+++ b/dev/Component/Classic/Checkbox.jsx
@@ -0,0 +1,7 @@
+
+import {componentExportHelper} from 'Component/Abstract';
+import {AbstracCheckbox} from 'Component/AbstracCheckbox';
+
+class ClassicCheckboxComponent extends AbstracCheckbox {}
+
+module.exports = componentExportHelper(ClassicCheckboxComponent, 'ClassicCheckboxComponent');
diff --git a/dev/Component/Input.js b/dev/Component/Input.js
deleted file mode 100644
index cb144a9f1..000000000
--- a/dev/Component/Input.js
+++ /dev/null
@@ -1,29 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- _ = require('_'),
-
- AbstractInput = require('Component/AbstractInput')
- ;
-
- /**
- * @constructor
- *
- * @param {Object} oParams
- *
- * @extends AbstractInput
- */
- function InputComponent(oParams)
- {
- AbstractInput.call(this, oParams);
- }
-
- _.extend(InputComponent.prototype, AbstractInput.prototype);
-
- module.exports = AbstractInput.componentExportHelper(
- InputComponent, 'InputComponent');
-
-}());
diff --git a/dev/Component/Input.jsx b/dev/Component/Input.jsx
new file mode 100644
index 000000000..22e2401da
--- /dev/null
+++ b/dev/Component/Input.jsx
@@ -0,0 +1,7 @@
+
+import {componentExportHelper} from 'Component/Abstract';
+import {AbstractInput} from 'Component/AbstractInput';
+
+class InputComponent extends AbstractInput {}
+
+module.exports = componentExportHelper(InputComponent, 'InputComponent');
diff --git a/dev/Component/MaterialDesign/Checkbox.js b/dev/Component/MaterialDesign/Checkbox.js
deleted file mode 100644
index fa48c1274..000000000
--- a/dev/Component/MaterialDesign/Checkbox.js
+++ /dev/null
@@ -1,66 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- _ = require('_'),
- ko = require('ko'),
-
- AbstracCheckbox = require('Component/AbstracCheckbox')
- ;
-
- /**
- * @constructor
- *
- * @param {Object} oParams
- *
- * @extends AbstracCheckbox
- */
- function CheckboxMaterialDesignComponent(oParams)
- {
- AbstracCheckbox.call(this, oParams);
-
- this.animationBox = ko.observable(false).extend({'falseTimeout': 200});
- this.animationCheckmark = ko.observable(false).extend({'falseTimeout': 200});
-
- this.animationBoxSetTrue = _.bind(this.animationBoxSetTrue, this);
- this.animationCheckmarkSetTrue = _.bind(this.animationCheckmarkSetTrue, this);
-
- this.disposable.push(
- this.value.subscribe(function (bValue) {
- this.triggerAnimation(bValue);
- }, this)
- );
- }
-
- _.extend(CheckboxMaterialDesignComponent.prototype, AbstracCheckbox.prototype);
-
- CheckboxMaterialDesignComponent.prototype.animationBoxSetTrue = function()
- {
- this.animationBox(true);
- };
-
- CheckboxMaterialDesignComponent.prototype.animationCheckmarkSetTrue = function()
- {
- this.animationCheckmark(true);
- };
-
- CheckboxMaterialDesignComponent.prototype.triggerAnimation = function(bBox)
- {
- if (bBox)
- {
- this.animationBoxSetTrue();
- _.delay(this.animationCheckmarkSetTrue, 200);
- }
- else
- {
- this.animationCheckmarkSetTrue();
- _.delay(this.animationBoxSetTrue, 200);
- }
- };
-
- module.exports = AbstracCheckbox.componentExportHelper(
- CheckboxMaterialDesignComponent, 'CheckboxMaterialDesignComponent');
-
-}());
diff --git a/dev/Component/MaterialDesign/Checkbox.jsx b/dev/Component/MaterialDesign/Checkbox.jsx
new file mode 100644
index 000000000..da77e0122
--- /dev/null
+++ b/dev/Component/MaterialDesign/Checkbox.jsx
@@ -0,0 +1,48 @@
+
+import {_} from 'common';
+import ko from 'ko';
+import {componentExportHelper} from 'Component/Abstract';
+import {AbstracCheckbox} from 'Component/AbstracCheckbox';
+
+class CheckboxMaterialDesignComponent extends AbstracCheckbox
+{
+ /**
+ * @param {Object} params
+ */
+ constructor(params) {
+
+ super(params);
+
+ this.animationBox = ko.observable(false).extend({'falseTimeout': 200});
+ this.animationCheckmark = ko.observable(false).extend({'falseTimeout': 200});
+
+ this.animationBoxSetTrue = _.bind(this.animationBoxSetTrue, this);
+ this.animationCheckmarkSetTrue = _.bind(this.animationCheckmarkSetTrue, this);
+
+ this.disposable.push(
+ this.value.subscribe((value) => {
+ this.triggerAnimation(value);
+ }, this)
+ );
+ }
+
+ animationBoxSetTrue() {
+ this.animationBox(true);
+ }
+
+ animationCheckmarkSetTrue() {
+ this.animationCheckmark(true);
+ }
+
+ triggerAnimation(box) {
+ if (box) {
+ this.animationBoxSetTrue();
+ _.delay(this.animationCheckmarkSetTrue, 200);
+ } else {
+ this.animationCheckmarkSetTrue();
+ _.delay(this.animationBoxSetTrue, 200);
+ }
+ }
+}
+
+module.exports = componentExportHelper(CheckboxMaterialDesignComponent, 'CheckboxMaterialDesignComponent');
diff --git a/dev/Component/Radio.js b/dev/Component/Radio.js
deleted file mode 100644
index 36fdb9200..000000000
--- a/dev/Component/Radio.js
+++ /dev/null
@@ -1,29 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- _ = require('_'),
-
- AbstracRadio = require('Component/AbstracRadio')
- ;
-
- /**
- * @constructor
- *
- * @param {Object} oParams
- *
- * @extends AbstracRadio
- */
- function RadioComponent(oParams)
- {
- AbstracRadio.call(this, oParams);
- }
-
- _.extend(RadioComponent.prototype, AbstracRadio.prototype);
-
- module.exports = AbstracRadio.componentExportHelper(
- RadioComponent, 'RadioComponent');
-
-}());
diff --git a/dev/Component/Radio.jsx b/dev/Component/Radio.jsx
new file mode 100644
index 000000000..865573be1
--- /dev/null
+++ b/dev/Component/Radio.jsx
@@ -0,0 +1,7 @@
+
+import {componentExportHelper} from 'Component/Abstract';
+import {AbstracRadio} from 'Component/AbstracRadio';
+
+class RadioComponent extends AbstracRadio {}
+
+module.exports = componentExportHelper(RadioComponent, 'RadioComponent');
diff --git a/dev/Component/SaveTrigger.js b/dev/Component/SaveTrigger.js
deleted file mode 100644
index 6a7a1edf9..000000000
--- a/dev/Component/SaveTrigger.js
+++ /dev/null
@@ -1,94 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- _ = require('_'),
-
- Enums = require('Common/Enums'),
- Utils = require('Common/Utils'),
-
- AbstractComponent = require('Component/Abstract')
- ;
-
- /**
- * @constructor
- *
- * @param {Object} oParams
- *
- * @extends AbstractComponent
- */
- function SaveTriggerComponent(oParams)
- {
- AbstractComponent.call(this);
-
- this.element = oParams.element || null;
- this.value = oParams.value && oParams.value.subscribe ? oParams.value : null;
-
- if (this.element)
- {
- if (this.value)
- {
- this.element.css('display', 'inline-block');
-
- if (oParams.verticalAlign)
- {
- this.element.css('vertical-align', oParams.verticalAlign);
- }
-
- this.setState(this.value());
-
- this.disposable.push(
- this.value.subscribe(this.setState, this)
- );
- }
- else
- {
- this.element.hide();
- }
- }
- }
-
- SaveTriggerComponent.prototype.setState = function (nValue)
- {
- switch (Utils.pInt(nValue))
- {
- case Enums.SaveSettingsStep.TrueResult:
- this.element
- .find('.animated,.error').hide().removeClass('visible')
- .end()
- .find('.success').show().addClass('visible')
- ;
- break;
- case Enums.SaveSettingsStep.FalseResult:
- this.element
- .find('.animated,.success').hide().removeClass('visible')
- .end()
- .find('.error').show().addClass('visible')
- ;
- break;
- case Enums.SaveSettingsStep.Animate:
- this.element
- .find('.error,.success').hide().removeClass('visible')
- .end()
- .find('.animated').show().addClass('visible')
- ;
- break;
- default:
- case Enums.SaveSettingsStep.Idle:
- this.element
- .find('.animated').hide()
- .end()
- .find('.error,.success').removeClass('visible')
- ;
- break;
- }
- };
-
- _.extend(SaveTriggerComponent.prototype, AbstractComponent.prototype);
-
- module.exports = AbstractComponent.componentExportHelper(
- SaveTriggerComponent, 'SaveTriggerComponent');
-
-}());
diff --git a/dev/Component/SaveTrigger.jsx b/dev/Component/SaveTrigger.jsx
new file mode 100644
index 000000000..4c6a8da64
--- /dev/null
+++ b/dev/Component/SaveTrigger.jsx
@@ -0,0 +1,79 @@
+
+import Utils from 'Common/Utils';
+import {SaveSettingsStep} from 'Common/Enums';
+import {AbstractComponent, componentExportHelper} from 'Component/Abstract';
+
+class SaveTriggerComponent extends AbstractComponent
+{
+ /**
+ * @param {Object} params
+ */
+ constructor(params) {
+
+ super();
+
+ this.element = params.element || null;
+ this.value = params.value && params.value.subscribe ? params.value : null;
+
+ if (this.element)
+ {
+ if (this.value)
+ {
+ this.element.css('display', 'inline-block');
+
+ if (params.verticalAlign)
+ {
+ this.element.css('vertical-align', params.verticalAlign);
+ }
+
+ this.setState(this.value());
+
+ this.disposable.push(
+ this.value.subscribe(this.setState, this)
+ );
+ }
+ else
+ {
+ this.element.hide();
+ }
+ }
+ }
+
+ setState(value) {
+
+ switch (Utils.pInt(value))
+ {
+ case SaveSettingsStep.TrueResult:
+ this.element
+ .find('.animated,.error').hide().removeClass('visible')
+ .end()
+ .find('.success').show().addClass('visible')
+ ;
+ break;
+ case SaveSettingsStep.FalseResult:
+ this.element
+ .find('.animated,.success').hide().removeClass('visible')
+ .end()
+ .find('.error').show().addClass('visible')
+ ;
+ break;
+ case SaveSettingsStep.Animate:
+ this.element
+ .find('.error,.success').hide().removeClass('visible')
+ .end()
+ .find('.animated').show().addClass('visible')
+ ;
+ break;
+ default:
+ case SaveSettingsStep.Idle:
+ this.element
+ .find('.animated').hide()
+ .end()
+ .find('.error,.success').removeClass('visible')
+ ;
+ break;
+ }
+ };
+}
+
+module.exports = componentExportHelper(SaveTriggerComponent, 'SaveTriggerComponent');
diff --git a/dev/Component/Script.js b/dev/Component/Script.js
deleted file mode 100644
index 9a1b01d33..000000000
--- a/dev/Component/Script.js
+++ /dev/null
@@ -1,52 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- _ = require('_'),
- $ = require('$'),
-
- AbstractComponent = require('Component/Abstract')
- ;
-
- /**
- * @constructor
- *
- * @param {Object} oParams
- *
- * @extends AbstractComponent
- */
- function ScriptComponent(oParams)
- {
- AbstractComponent.call(this);
-
- if (oParams.component && oParams.component.templateNodes && oParams.element &&
- oParams.element[0] && oParams.element[0].outerHTML)
- {
- var sScript = oParams.element[0].outerHTML;
- sScript = sScript
- .replace(/<\/b><\/x-script>/i, '')
- ;
-
- if (sScript)
- {
- oParams.element.text('');
- oParams.element.replaceWith(
- $(sScript).text(oParams.component.templateNodes[0] &&
- oParams.component.templateNodes[0].nodeValue ?
- oParams.component.templateNodes[0].nodeValue : ''));
- }
- else
- {
- oParams.element.remove();
- }
- }
- }
-
- _.extend(ScriptComponent.prototype, AbstractComponent.prototype);
-
- module.exports = AbstractComponent.componentExportHelper(ScriptComponent);
-
-}());
diff --git a/dev/Component/Script.jsx b/dev/Component/Script.jsx
new file mode 100644
index 000000000..3dfa6a576
--- /dev/null
+++ b/dev/Component/Script.jsx
@@ -0,0 +1,39 @@
+
+import {$} from 'common';
+import {AbstractComponent, componentExportHelper} from 'Component/Abstract';
+
+class ScriptComponent extends AbstractComponent
+{
+ /**
+ * @param {Object} params
+ */
+ constructor(params) {
+
+ super();
+
+ if (params.component && params.component.templateNodes && params.element &&
+ params.element[0] && params.element[0].outerHTML)
+ {
+ let script = params.element[0].outerHTML;
+ script = script
+ .replace(/<\/b><\/x-script>/i, '')
+ ;
+
+ if (script)
+ {
+ params.element.text('');
+ params.element.replaceWith(
+ $(script).text(params.component.templateNodes[0] &&
+ params.component.templateNodes[0].nodeValue ?
+ params.component.templateNodes[0].nodeValue : ''));
+ }
+ else
+ {
+ params.element.remove();
+ }
+ }
+ }
+}
+
+module.exports = componentExportHelper(ScriptComponent, 'ScriptComponent');
diff --git a/dev/Component/Select.js b/dev/Component/Select.js
deleted file mode 100644
index 046f7603a..000000000
--- a/dev/Component/Select.js
+++ /dev/null
@@ -1,45 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- _ = require('_'),
-
- Utils = require('Common/Utils'),
- Translator = require('Common/Translator'),
-
- AbstractInput = require('Component/AbstractInput')
- ;
-
- /**
- * @constructor
- *
- * @param {Object} oParams
- *
- * @extends AbstractInput
- */
- function SelectComponent(oParams)
- {
- AbstractInput.call(this, oParams);
-
- this.options = oParams.options || '';
-
- this.optionsText = oParams.optionsText || null;
- this.optionsValue = oParams.optionsValue || null;
- this.optionsCaption = oParams.optionsCaption || null;
-
- if (this.optionsCaption)
- {
- this.optionsCaption = Translator.i18n(this.optionsCaption);
- }
-
- this.defautOptionsAfterRender = Utils.defautOptionsAfterRender;
- }
-
- _.extend(SelectComponent.prototype, AbstractInput.prototype);
-
- module.exports = AbstractInput.componentExportHelper(
- SelectComponent, 'SelectComponent');
-
-}());
diff --git a/dev/Component/Select.jsx b/dev/Component/Select.jsx
new file mode 100644
index 000000000..d0e275e3d
--- /dev/null
+++ b/dev/Component/Select.jsx
@@ -0,0 +1,31 @@
+
+import Utils from 'Common/Utils';
+import Translator from 'Common/Translator';
+import {componentExportHelper} from 'Component/Abstract';
+import {AbstractInput} from 'Component/AbstractInput';
+
+class SelectComponent extends AbstractInput
+{
+ /**
+ * @param {Object} params
+ */
+ constructor(params) {
+
+ super(params);
+
+ this.options = params.options || '';
+
+ this.optionsText = params.optionsText || null;
+ this.optionsValue = params.optionsValue || null;
+ this.optionsCaption = params.optionsCaption || null;
+
+ if (this.optionsCaption)
+ {
+ this.optionsCaption = Translator.i18n(this.optionsCaption);
+ }
+
+ this.defautOptionsAfterRender = Utils.defautOptionsAfterRender;
+ }
+}
+
+module.exports = componentExportHelper(SelectComponent, 'SelectComponent');
diff --git a/dev/Component/SvgIcon.js b/dev/Component/SvgIcon.js
deleted file mode 100644
index 710754c6f..000000000
--- a/dev/Component/SvgIcon.js
+++ /dev/null
@@ -1,35 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- $ = require('$'),
- sUrl = null,
- getUtl = function () {
- if (!sUrl)
- {
- sUrl = 'rainloop/v/' + ($('#rlAppVersion').attr('content') || '0.0.0') + '/static/css/svg/icons.svg';
- }
-
- return sUrl;
- }
- ;
-
- module.exports = {
- viewModel: {
- createViewModel: function(oParams, oComponentInfo) {
- var icon = oParams.icon || 'null';
- if (oComponentInfo.element && oComponentInfo.element)
- {
- $(oComponentInfo.element).replaceWith(
-' ');
- }
- }
- },
- 'template': ' '
- };
-
-}());
-
-
diff --git a/dev/Component/SvgIcon.jsx b/dev/Component/SvgIcon.jsx
new file mode 100644
index 000000000..b653056be
--- /dev/null
+++ b/dev/Component/SvgIcon.jsx
@@ -0,0 +1,30 @@
+
+import {$} from 'common';
+
+let
+ cachedUrl = null,
+ getUtl = () => {
+ if (!cachedUrl)
+ {
+ const version = $('#rlAppVersion').attr('content') || '0.0.0';
+ cachedUrl = `rainloop/v/${version}/static/css/svg/icons.svg`;
+ }
+
+ return cachedUrl;
+ }
+;
+
+module.exports = {
+ template: ' ',
+ viewModel: {
+ createViewModel: (params, componentInfo) => {
+ if (componentInfo && componentInfo.element)
+ {
+ const icon = params.icon || 'null';
+ $(componentInfo.element).replaceWith(
+ ` `
+ );
+ }
+ }
+ }
+};
diff --git a/dev/Component/TextArea.js b/dev/Component/TextArea.js
deleted file mode 100644
index ed86289e2..000000000
--- a/dev/Component/TextArea.js
+++ /dev/null
@@ -1,34 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- _ = require('_'),
-
- Utils = require('Common/Utils'),
-
- AbstractInput = require('Component/AbstractInput')
- ;
-
- /**
- * @constructor
- *
- * @param {Object} oParams
- *
- * @extends AbstractInput
- */
- function TextAreaComponent(oParams)
- {
- AbstractInput.call(this, oParams);
-
- this.rows = oParams.rows || 5;
- this.spellcheck = Utils.isUnd(oParams.spellcheck) ? false : !!oParams.spellcheck;
- }
-
- _.extend(TextAreaComponent.prototype, AbstractInput.prototype);
-
- module.exports = AbstractInput.componentExportHelper(
- TextAreaComponent, 'TextAreaComponent');
-
-}());
diff --git a/dev/Component/TextArea.jsx b/dev/Component/TextArea.jsx
new file mode 100644
index 000000000..d76d24303
--- /dev/null
+++ b/dev/Component/TextArea.jsx
@@ -0,0 +1,20 @@
+
+import Utils from 'Common/Utils';
+import {componentExportHelper} from 'Component/Abstract';
+import {AbstractInput} from 'Component/AbstractInput';
+
+class TextAreaComponent extends AbstractInput
+{
+ /**
+ * @param {Object} params
+ */
+ constructor(params) {
+
+ super(params);
+
+ this.rows = params.rows || 5;
+ this.spellcheck = Utils.isUnd(params.spellcheck) ? false : !!params.spellcheck;
+ }
+}
+
+module.exports = componentExportHelper(TextAreaComponent, 'TextAreaComponent');
diff --git a/dev/External/ko.js b/dev/External/ko.js
index 8ee27f5c6..0fa6e3ca8 100644
--- a/dev/External/ko.js
+++ b/dev/External/ko.js
@@ -12,7 +12,6 @@
fDisposalTooltipHelper = function (oElement) {
ko.utils.domNodeDisposal.addDisposeCallback(oElement, function () {
-
if (oElement && oElement.__opentip)
{
oElement.__opentip.deactivate();
diff --git a/dev/Helper/Message.js b/dev/Helper/Message.js
index 1be2badb3..02e2ee087 100644
--- a/dev/Helper/Message.js
+++ b/dev/Helper/Message.js
@@ -49,7 +49,7 @@
aResult = [],
iIndex = 0,
iLen = 0
- ;
+ ;
if (Utils.isNonEmptyArray(aEmails))
{
diff --git a/dev/Promises/AbstractAjax.js b/dev/Promises/AbstractAjax.js
index 20d51b54d..d5e86742c 100644
--- a/dev/Promises/AbstractAjax.js
+++ b/dev/Promises/AbstractAjax.js
@@ -65,7 +65,7 @@
oDeferred = Q.defer()
;
- iTimeOut = Utils.isNormal(iTimeOut) ? iTimeOut : Consts.Defaults.DefaultAjaxTimeout;
+ iTimeOut = Utils.isNormal(iTimeOut) ? iTimeOut : Consts.DEFAULT_AJAX_TIMEOUT;
sAdditionalGetString = Utils.isUnd(sAdditionalGetString) ? '' : Utils.pString(sAdditionalGetString);
if (bPost)
@@ -167,7 +167,7 @@
Globals.iTokenErrorCount++;
}
- if (Consts.Values.TokenErrorLimit < Globals.iTokenErrorCount)
+ if (Consts.TOKEN_ERROR_LIMIT < Globals.iTokenErrorCount)
{
if (Globals.__APP__ && Globals.__APP__.loginAndLogoutReload)
{
@@ -175,7 +175,7 @@
}
}
- if (oErrorData.ClearAuth || oErrorData.Logout || Consts.Values.AjaxErrorLimit < Globals.iAjaxErrorCount)
+ if (oErrorData.ClearAuth || oErrorData.Logout || Consts.AJAX_ERROR_LIMIT < Globals.iAjaxErrorCount)
{
if (Globals.__APP__ && Globals.__APP__.clearClientSideToken)
{
diff --git a/dev/Promises/User/Ajax.js b/dev/Promises/User/Ajax.js
index 6cc9de4ba..35f4f8477 100644
--- a/dev/Promises/User/Ajax.js
+++ b/dev/Promises/User/Ajax.js
@@ -89,71 +89,6 @@
return this.postRequest('WelcomeClose');
};
-// UserAjaxUserPromises.prototype.messageList = function (sFolderFullNameRaw, iOffset, iLimit, sSearch, fTrigger)
-// {
-// sFolderFullNameRaw = Utils.pString(sFolderFullNameRaw);
-// sSearch = Utils.pString(sSearch);
-// iOffset = Utils.pInt(iOffset);
-// iLimit = Utils.pInt(iLimit);
-//
-// var sFolderHash = Cache.getFolderHash(sFolderFullNameRaw);
-//
-// if ('' !== sFolderHash && ('' === sSearch || -1 === sSearch.indexOf('is:')))
-// {
-// return this.abort('MessageList')
-// .getRequest('MessageList', fTrigger,
-// Links.subQueryPrefix() + '/' + Base64.urlsafe_encode([
-// sFolderFullNameRaw,
-// iOffset,
-// iLimit,
-// sSearch,
-// AppStore.projectHash(),
-// sFolderHash,
-// Cache.getFolderInboxName() === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '',
-// AppStore.threadsAllowed() && SettingsStore.useThreads() ? '1' : '0',
-// ''
-// ].join(String.fromCharCode(0))))
-// .then(PromisesPopulator.messageList);
-// }
-// else
-// {
-// return this.abort('MessageList')
-// .postRequest('MessageList', fTrigger,{
-// 'Folder': sFolderFullNameRaw,
-// 'Offset': iOffset,
-// 'Limit': iLimit,
-// 'Search': sSearch,
-// 'UidNext': Cache.getFolderInboxName() === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '',
-// 'UseThreads': AppStore.threadsAllowed() && SettingsStore.useThreads() ? '1' : '0'
-// })
-// .then(PromisesPopulator.messageList);
-// }
-//
-// return this.fastReject(Enums.Notification.UnknownError);
-// };
-//
-// UserAjaxUserPromises.prototype.message = function (sFolderFullNameRaw, iUid, fTrigger)
-// {
-// sFolderFullNameRaw = Utils.pString(sFolderFullNameRaw);
-// iUid = Utils.pInt(iUid);
-//
-// if (Cache.getFolderFromCacheList(sFolderFullNameRaw) && 0 >= iUid)
-// {
-// return this.abort('Message')
-// .getRequest('Message', fTrigger,
-// Links.subQueryPrefix() + '/' + Base64.urlsafe_encode([
-// sFolderFullNameRaw, iUid,
-// AppStore.projectHash(),
-// AppStore.threadsAllowed() && SettingsStore.useThreads() ? '1' : '0'
-// ].join(String.fromCharCode(0))))
-// .then(function (oData) {
-// return oData;
-// });
-// }
-//
-// return this.fastReject(Enums.Notification.UnknownError);
-// };
-
module.exports = new UserAjaxUserPromises();
}());
\ No newline at end of file
diff --git a/dev/Promises/User/Populator.js b/dev/Promises/User/Populator.js
index 87a41bcf9..b7d78839c 100644
--- a/dev/Promises/User/Populator.js
+++ b/dev/Promises/User/Populator.js
@@ -15,7 +15,7 @@
FolderStore = require('Stores/User/Folder'),
Settings = require('Storage/Settings'),
- Local = require('Storage/Client'),
+ Local = require('Storage/Client.jsx'),
FolderModel = require('Model/Folder'),
@@ -48,7 +48,7 @@
*/
PromisesUserPopulator.prototype.normalizeFolder = function (sFolderFullNameRaw)
{
- return ('' === sFolderFullNameRaw || Consts.Values.UnuseOptionValue === sFolderFullNameRaw ||
+ return ('' === sFolderFullNameRaw || Consts.UNUSED_OPTION_VALUE === sFolderFullNameRaw ||
null !== Cache.getFolderFromCacheList(sFolderFullNameRaw)) ? sFolderFullNameRaw : '';
};
diff --git a/dev/Remote/AbstractAjax.js b/dev/Remote/AbstractAjax.js
index 9329c9db0..28fd8e535 100644
--- a/dev/Remote/AbstractAjax.js
+++ b/dev/Remote/AbstractAjax.js
@@ -61,7 +61,7 @@
Globals.iTokenErrorCount++;
}
- if (Consts.Values.TokenErrorLimit < Globals.iTokenErrorCount)
+ if (Consts.TOKEN_ERROR_LIMIT < Globals.iTokenErrorCount)
{
if (Globals.__APP__ && Globals.__APP__.loginAndLogoutReload)
{
@@ -69,7 +69,7 @@
}
}
- if (oData.ClearAuth || oData.Logout || Consts.Values.AjaxErrorLimit < Globals.iAjaxErrorCount)
+ if (oData.ClearAuth || oData.Logout || Consts.AJAX_ERROR_LIMIT < Globals.iAjaxErrorCount)
{
if (Globals.__APP__ && Globals.__APP__.clearClientSideToken)
{
@@ -240,7 +240,7 @@
Plugins.runHook('ajax-default-request', [sAction, oParameters, sGetAdd]);
return this.ajaxRequest(fCallback, oParameters,
- Utils.isUnd(iTimeout) ? Consts.Defaults.DefaultAjaxTimeout : Utils.pInt(iTimeout), sGetAdd, aAbortActions);
+ Utils.isUnd(iTimeout) ? Consts.DEFAULT_AJAX_TIMEOUT : Utils.pInt(iTimeout), sGetAdd, aAbortActions);
};
/**
diff --git a/dev/Remote/User/Ajax.js b/dev/Remote/User/Ajax.js
index b5a145b25..da49ba1c2 100644
--- a/dev/Remote/User/Ajax.js
+++ b/dev/Remote/User/Ajax.js
@@ -138,7 +138,7 @@
*/
RemoteUserAjax.prototype.contactsSync = function (fCallback)
{
- this.defaultRequest(fCallback, 'ContactsSync', null, Consts.Defaults.ContactsSyncAjaxTimeout);
+ this.defaultRequest(fCallback, 'ContactsSync', null, Consts.CONTACTS_SYNC_AJAX_TIMEOUT);
};
/**
@@ -341,7 +341,7 @@
if ('' !== sFolderHash && ('' === sSearch || -1 === sSearch.indexOf('is:')))
{
return this.defaultRequest(fCallback, 'MessageList', {},
- '' === sSearch ? Consts.Defaults.DefaultAjaxTimeout : Consts.Defaults.SearchAjaxTimeout,
+ '' === sSearch ? Consts.DEFAULT_AJAX_TIMEOUT : Consts.SEARCH_AJAX_TIMEOUT,
'MessageList/' + Links.subQueryPrefix() + '/' + Base64.urlsafe_encode([
sFolderFullNameRaw,
iOffset,
@@ -364,7 +364,7 @@
'UidNext': sInboxUidNext,
'UseThreads': bUseThreads ? '1' : '0',
'ThreadUid': bUseThreads ? sThreadUid : ''
- }, '' === sSearch ? Consts.Defaults.DefaultAjaxTimeout : Consts.Defaults.SearchAjaxTimeout,
+ }, '' === sSearch ? Consts.DEFAULT_AJAX_TIMEOUT : Consts.SEARCH_AJAX_TIMEOUT,
'', bSilent ? [] : ['MessageList']);
}
};
@@ -583,7 +583,7 @@
'References': sReferences,
'MarkAsImportant': bMarkAsImportant ? '1' : '0',
'Attachments': aAttachments
- }, Consts.Defaults.SaveMessageAjaxTimeout);
+ }, Consts.SAVE_MESSAGE_AJAX_TIMEOUT);
};
@@ -650,7 +650,7 @@
'ReadReceiptRequest': bRequestReadReceipt ? '1' : '0',
'MarkAsImportant': bMarkAsImportant ? '1' : '0',
'Attachments': aAttachments
- }, Consts.Defaults.SendMessageAjaxTimeout);
+ }, Consts.SEND_MESSAGE_AJAX_TIMEOUT);
};
/**
diff --git a/dev/Settings/User/Folders.js b/dev/Settings/User/Folders.js
index 9d826f69b..c696f3061 100644
--- a/dev/Settings/User/Folders.js
+++ b/dev/Settings/User/Folders.js
@@ -13,7 +13,7 @@
Cache = require('Common/Cache'),
Settings = require('Storage/Settings'),
- Local = require('Storage/Client'),
+ Local = require('Storage/Client.jsx'),
FolderStore = require('Stores/User/Folder'),
diff --git a/dev/Settings/User/General.js b/dev/Settings/User/General.js
index 7d4dc9d46..ff43bb8d5 100644
--- a/dev/Settings/User/General.js
+++ b/dev/Settings/User/General.js
@@ -31,7 +31,7 @@
this.language = LanguageStore.language;
this.languages = LanguageStore.languages;
this.messagesPerPage = SettingsStore.messagesPerPage;
- this.messagesPerPageArray = Consts.Defaults.MessagesPerPageArray;
+ this.messagesPerPageArray = Consts.MESSAGES_PER_PAGE_VALUES;
this.editorDefaultType = SettingsStore.editorDefaultType;
this.layout = SettingsStore.layout;
diff --git a/dev/Storage/Client.js b/dev/Storage/Client.js
deleted file mode 100644
index e37adaa67..000000000
--- a/dev/Storage/Client.js
+++ /dev/null
@@ -1,54 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- /**
- * @constructor
- */
- function ClientStorage()
- {
- var
- NextStorageDriver = require('_').find([
- require('Common/ClientStorageDriver/LocalStorage'),
- require('Common/ClientStorageDriver/Cookie')
- ], function (NextStorageDriver) {
- return NextStorageDriver && NextStorageDriver.supported();
- })
- ;
-
- this.oDriver = null;
-
- if (NextStorageDriver)
- {
- this.oDriver = new NextStorageDriver();
- }
- }
-
- /**
- * @type {LocalStorageDriver|CookieDriver|null}
- */
- ClientStorage.prototype.oDriver = null;
-
- /**
- * @param {number} iKey
- * @param {*} mData
- * @return {boolean}
- */
- ClientStorage.prototype.set = function (iKey, mData)
- {
- return this.oDriver ? this.oDriver.set('p' + iKey, mData) : false;
- };
-
- /**
- * @param {number} iKey
- * @return {*}
- */
- ClientStorage.prototype.get = function (iKey)
- {
- return this.oDriver ? this.oDriver.get('p' + iKey) : null;
- };
-
- module.exports = new ClientStorage();
-
-}());
\ No newline at end of file
diff --git a/dev/Storage/Client.jsx b/dev/Storage/Client.jsx
new file mode 100644
index 000000000..69e693062
--- /dev/null
+++ b/dev/Storage/Client.jsx
@@ -0,0 +1,31 @@
+
+import {_} from 'common';
+import {Cookie} from 'Common/ClientStorageDriver/Cookie';
+import {LocalStorage} from 'Common/ClientStorageDriver/LocalStorage';
+
+class ClientStorage
+{
+ constructor() {
+ const SupportedStorageDriver = _.find([LocalStorage, Cookie], (StorageDriver) => StorageDriver && StorageDriver.supported());
+ this.driver = SupportedStorageDriver ? new SupportedStorageDriver() : null;
+ }
+
+ /**
+ * @param {number} key
+ * @param {*} data
+ * @return {boolean}
+ */
+ set(key, data) {
+ return this.driver ? this.driver.set('p' + key, data) : false;
+ }
+
+ /**
+ * @param {number} key
+ * @return {*}
+ */
+ get(key) {
+ return this.driver ? this.driver.get('p' + key) : null;
+ }
+}
+
+module.exports = new ClientStorage();
diff --git a/dev/Storage/Settings.js b/dev/Storage/Settings.js
deleted file mode 100644
index 3fecebfc2..000000000
--- a/dev/Storage/Settings.js
+++ /dev/null
@@ -1,54 +0,0 @@
-
-(function () {
-
- 'use strict';
-
- var
- window = require('window'),
-
- Utils = require('Common/Utils')
- ;
-
- /**
- * @constructor
- */
- function SettingsStorage()
- {
- this.oSettings = window['rainloopAppData'] || {};
- this.oSettings = Utils.isNormal(this.oSettings) ? this.oSettings : {};
- }
-
- SettingsStorage.prototype.oSettings = null;
-
- /**
- * @param {string} sName
- * @return {?}
- */
- SettingsStorage.prototype.settingsGet = function (sName)
- {
- return Utils.isUnd(this.oSettings[sName]) ? null : this.oSettings[sName];
- };
-
- /**
- * @param {string} sName
- * @param {?} mValue
- */
- SettingsStorage.prototype.settingsSet = function (sName, mValue)
- {
- this.oSettings[sName] = mValue;
- };
-
- /**
- * @param {string} sName
- * @return {boolean}
- */
- SettingsStorage.prototype.capa = function (sName)
- {
- var mCapa = this.settingsGet('Capa');
- return Utils.isArray(mCapa) && Utils.isNormal(sName) && -1 < Utils.inArray(sName, mCapa);
- };
-
-
- module.exports = new SettingsStorage();
-
-}());
\ No newline at end of file
diff --git a/dev/Storage/Settings.jsx b/dev/Storage/Settings.jsx
new file mode 100644
index 000000000..ba4c35aa7
--- /dev/null
+++ b/dev/Storage/Settings.jsx
@@ -0,0 +1,38 @@
+
+import {window} from 'common';
+import Utils from 'Common/Utils';
+
+class SettingsStorage
+{
+ constructor() {
+ this.settings = window['rainloopAppData'] || {};
+ this.settings = Utils.isNormal(this.settings) ? this.settings : {};
+ }
+
+ /**
+ * @param {string} name
+ * @return {*}
+ */
+ settingsGet(name) {
+ return Utils.isUnd(this.settings[name]) ? null : this.settings[name];
+ }
+
+ /**
+ * @param {string} name
+ * @param {*} value
+ */
+ settingsSet(name, value) {
+ this.settings[name] = value;
+ }
+
+ /**
+ * @param {string} name
+ * @return {boolean}
+ */
+ capa(name) {
+ const values = this.settingsGet('Capa');
+ return Utils.isArray(values) && Utils.isNormal(name) && -1 < Utils.inArray(name, values);
+ };
+}
+
+module.exports = new SettingsStorage();
diff --git a/dev/Stores/User/Folder.js b/dev/Stores/User/Folder.js
index 57081f7b1..acab9cd66 100644
--- a/dev/Stores/User/Folder.js
+++ b/dev/Stores/User/Folder.js
@@ -52,7 +52,7 @@
FolderUserStore.prototype.computers = function ()
{
this.draftFolderNotEnabled = ko.computed(function () {
- return '' === this.draftFolder() || Consts.Values.UnuseOptionValue === this.draftFolder();
+ return '' === this.draftFolder() || Consts.UNUSED_OPTION_VALUE === this.draftFolder();
}, this);
this.foldersListWithSingleInboxRootFolder = ko.computed(function () {
@@ -97,23 +97,23 @@
if (Utils.isArray(aFolders) && 0 < aFolders.length)
{
- if ('' !== sSentFolder && Consts.Values.UnuseOptionValue !== sSentFolder)
+ if ('' !== sSentFolder && Consts.UNUSED_OPTION_VALUE !== sSentFolder)
{
aList.push(sSentFolder);
}
- if ('' !== sDraftFolder && Consts.Values.UnuseOptionValue !== sDraftFolder)
+ if ('' !== sDraftFolder && Consts.UNUSED_OPTION_VALUE !== sDraftFolder)
{
aList.push(sDraftFolder);
}
- if ('' !== sSpamFolder && Consts.Values.UnuseOptionValue !== sSpamFolder)
+ if ('' !== sSpamFolder && Consts.UNUSED_OPTION_VALUE !== sSpamFolder)
{
aList.push(sSpamFolder);
}
- if ('' !== sTrashFolder && Consts.Values.UnuseOptionValue !== sTrashFolder)
+ if ('' !== sTrashFolder && Consts.UNUSED_OPTION_VALUE !== sTrashFolder)
{
aList.push(sTrashFolder);
}
- if ('' !== sArchiveFolder && Consts.Values.UnuseOptionValue !== sArchiveFolder)
+ if ('' !== sArchiveFolder && Consts.UNUSED_OPTION_VALUE !== sArchiveFolder)
{
aList.push(sArchiveFolder);
}
diff --git a/dev/Stores/User/Message.js b/dev/Stores/User/Message.js
index 382b01af5..bc457c9dd 100644
--- a/dev/Stores/User/Message.js
+++ b/dev/Stores/User/Message.js
@@ -227,7 +227,7 @@
var
iCount = 0,
oMessagesDom = null,
- iEnd = Globals.iMessageBodyCacheCount - Consts.Values.MessageBodyCacheLimit
+ iEnd = Globals.iMessageBodyCacheCount - Consts.MESSAGE_BODY_CACHE_LIMIT
;
if (0 < iEnd)
diff --git a/dev/Stores/User/Settings.js b/dev/Stores/User/Settings.js
index 0534f3914..8df29fcd3 100644
--- a/dev/Stores/User/Settings.js
+++ b/dev/Stores/User/Settings.js
@@ -34,8 +34,8 @@
Enums.EditorDefaultType.HtmlForced, Enums.EditorDefaultType.PlainForced
]});
- this.messagesPerPage = ko.observable(Consts.Defaults.MessagesPerPage)
- .extend({'limitedList': Consts.Defaults.MessagesPerPageArray});
+ this.messagesPerPage = ko.observable(Consts.MESSAGES_PER_PAGE)
+ .extend({'limitedList': Consts.MESSAGES_PER_PAGE_VALUES});
this.showImages = ko.observable(false);
this.useCheckboxesInList = ko.observable(true);
diff --git a/dev/Styles/SettingsAccounts.less b/dev/Styles/SettingsAccounts.less
index 04aeaf132..b7840085e 100644
--- a/dev/Styles/SettingsAccounts.less
+++ b/dev/Styles/SettingsAccounts.less
@@ -64,6 +64,7 @@
.drag-handle {
cursor: pointer;
+ cursor: all-scroll;
}
.button-delete {
diff --git a/dev/Styles/SettingsFilters.less b/dev/Styles/SettingsFilters.less
index 501098d52..7e3150517 100644
--- a/dev/Styles/SettingsFilters.less
+++ b/dev/Styles/SettingsFilters.less
@@ -60,6 +60,7 @@
.drag-handle {
cursor: pointer;
+ cursor: all-scroll;
}
.button-delete {
diff --git a/dev/Styles/SettingsTemplates.less b/dev/Styles/SettingsTemplates.less
index 3495173b1..c0f064077 100644
--- a/dev/Styles/SettingsTemplates.less
+++ b/dev/Styles/SettingsTemplates.less
@@ -51,6 +51,7 @@
.drag-handle {
cursor: pointer;
+ cursor: all-scroll;
}
.button-delete {
diff --git a/dev/View/Popup/Activate.js b/dev/View/Popup/Activate.js
index b48f3073a..8087ad5c3 100644
--- a/dev/View/Popup/Activate.js
+++ b/dev/View/Popup/Activate.js
@@ -121,7 +121,7 @@
{
bTrial = Utils.isUnd(bTrial) ? false : !!bTrial;
- this.key(bTrial ? Consts.Values.RainLoopTrialKey : '');
+ this.key(bTrial ? Consts.RAINLOOP_TRIAL_KEY : '');
this.activateText('');
this.activateText.isError(false);
this.activationSuccessed(false);
@@ -142,7 +142,7 @@
ActivatePopupView.prototype.validateSubscriptionKey = function ()
{
var sValue = this.key();
- return '' === sValue || Consts.Values.RainLoopTrialKey === sValue ||
+ return '' === sValue || Consts.RAINLOOP_TRIAL_KEY === sValue ||
!!/^RL[\d]+-[A-Z0-9\-]+Z$/.test(Utils.trim(sValue));
};
diff --git a/dev/View/Popup/Compose.js b/dev/View/Popup/Compose.js
index 0691c5de1..9df74d8b1 100644
--- a/dev/View/Popup/Compose.js
+++ b/dev/View/Popup/Compose.js
@@ -380,7 +380,7 @@
if (!this.allowFolders)
{
- sSentFolder = Consts.Values.UnuseOptionValue;
+ sSentFolder = Consts.UNUSED_OPTION_VALUE;
}
if ('' === sSentFolder)
@@ -412,7 +412,7 @@
}
}
- sSentFolder = Consts.Values.UnuseOptionValue === sSentFolder ? '' : sSentFolder;
+ sSentFolder = Consts.UNUSED_OPTION_VALUE === sSentFolder ? '' : sSentFolder;
Cache.setFolderHash(this.draftFolder(), '');
Cache.setFolderHash(sSentFolder, '');
@@ -649,7 +649,7 @@
sDraftFolder = FolderStore.draftFolder()
;
- if ('' !== sDraftFolder && Consts.Values.UnuseOptionValue !== sDraftFolder)
+ if ('' !== sDraftFolder && Consts.UNUSED_OPTION_VALUE !== sDraftFolder)
{
Cache.setFolderHash(sDraftFolder, '');
if (FolderStore.currentFolderFullNameRaw() === sDraftFolder)
diff --git a/dev/View/Popup/Contacts.js b/dev/View/Popup/Contacts.js
index 98c09ed4f..65e276a8f 100644
--- a/dev/View/Popup/Contacts.js
+++ b/dev/View/Popup/Contacts.js
@@ -68,7 +68,7 @@
this.contactsPage = ko.observable(1);
this.contactsPageCount = ko.computed(function () {
- var iPage = window.Math.ceil(this.contactsCount() / Consts.Defaults.ContactsPerPage);
+ var iPage = window.Math.ceil(this.contactsCount() / Consts.CONTACTS_PER_PAGE);
return 0 >= iPage ? 1 : iPage;
}, this);
@@ -679,7 +679,7 @@
{
var
self = this,
- iOffset = (this.contactsPage() - 1) * Consts.Defaults.ContactsPerPage
+ iOffset = (this.contactsPage() - 1) * Consts.CONTACTS_PER_PAGE
;
this.bDropPageAfterDelete = false;
@@ -722,7 +722,7 @@
self.contacts.loading(false);
self.viewClearSearch('' !== self.search());
- }, iOffset, Consts.Defaults.ContactsPerPage, this.search());
+ }, iOffset, Consts.CONTACTS_PER_PAGE, this.search());
};
ContactsPopupView.prototype.onBuild = function (oDom)
diff --git a/dev/View/Popup/Domain.js b/dev/View/Popup/Domain.js
index b981f7949..b0d8bdc76 100644
--- a/dev/View/Popup/Domain.js
+++ b/dev/View/Popup/Domain.js
@@ -74,16 +74,16 @@
this.name.focused = ko.observable(false);
this.imapServer = ko.observable('');
- this.imapPort = ko.observable('' + Consts.Values.ImapDefaulPort);
+ this.imapPort = ko.observable('' + Consts.IMAP_DEFAULT_PORT);
this.imapSecure = ko.observable(Enums.ServerSecure.None);
this.imapShortLogin = ko.observable(false);
this.useSieve = ko.observable(false);
this.sieveAllowRaw = ko.observable(false);
this.sieveServer = ko.observable('');
- this.sievePort = ko.observable('' + Consts.Values.SieveDefaulPort);
+ this.sievePort = ko.observable('' + Consts.SIEVE_DEFAULT_PORT);
this.sieveSecure = ko.observable(Enums.ServerSecure.None);
this.smtpServer = ko.observable('');
- this.smtpPort = ko.observable('' + Consts.Values.SmtpDefaulPort);
+ this.smtpPort = ko.observable('' + Consts.SMTP_DEFAULT_PORT);
this.smtpSecure = ko.observable(Enums.ServerSecure.None);
this.smtpShortLogin = ko.observable(false);
this.smtpAuth = ko.observable(true);
@@ -441,18 +441,18 @@
this.name.focused(false);
this.imapServer('');
- this.imapPort('' + Consts.Values.ImapDefaulPort);
+ this.imapPort('' + Consts.IMAP_DEFAULT_PORT);
this.imapSecure(Enums.ServerSecure.None);
this.imapShortLogin(false);
this.useSieve(false);
this.sieveAllowRaw(false);
this.sieveServer('');
- this.sievePort('' + Consts.Values.SieveDefaulPort);
+ this.sievePort('' + Consts.SIEVE_DEFAULT_PORT);
this.sieveSecure(Enums.ServerSecure.None);
this.smtpServer('');
- this.smtpPort('' + Consts.Values.SmtpDefaulPort);
+ this.smtpPort('' + Consts.SMTP_DEFAULT_PORT);
this.smtpSecure(Enums.ServerSecure.None);
this.smtpShortLogin(false);
this.smtpAuth(true);
diff --git a/dev/View/Popup/FolderCreate.js b/dev/View/Popup/FolderCreate.js
index 27d2faba5..cc0e3be54 100644
--- a/dev/View/Popup/FolderCreate.js
+++ b/dev/View/Popup/FolderCreate.js
@@ -36,7 +36,7 @@
this.folderName = ko.observable('');
this.folderName.focused = ko.observable(false);
- this.selectedParentValue = ko.observable(Consts.Values.UnuseOptionValue);
+ this.selectedParentValue = ko.observable(Consts.UNUSED_OPTION_VALUE);
this.parentFolderSelectList = ko.computed(function () {
diff --git a/dev/View/Popup/FolderSystem.js b/dev/View/Popup/FolderSystem.js
index 1f4742de8..de879d66c 100644
--- a/dev/View/Popup/FolderSystem.js
+++ b/dev/View/Popup/FolderSystem.js
@@ -39,7 +39,7 @@
this.folderSelectList = ko.computed(function () {
return Utils.folderListOptionsBuilder([], FolderStore.folderList(), FolderStore.folderListSystemNames(), [
['', this.sChooseOnText],
- [Consts.Values.UnuseOptionValue, this.sUnuseText]
+ [Consts.UNUSED_OPTION_VALUE, this.sUnuseText]
], null, null, null, null, null, true);
}, this);
diff --git a/dev/View/User/Login.js b/dev/View/User/Login.js
index db5dc2e79..c2938c28c 100644
--- a/dev/View/User/Login.js
+++ b/dev/View/User/Login.js
@@ -19,7 +19,7 @@
LanguageStore = require('Stores/Language'),
AppStore = require('Stores/User/App'),
- Local = require('Storage/Client'),
+ Local = require('Storage/Client.jsx'),
Settings = require('Storage/Settings'),
Remote = require('Remote/User/Ajax'),
diff --git a/dev/View/User/MailBox/MessageList.js b/dev/View/User/MailBox/MessageList.js
index cc67227a8..1e72d5859 100644
--- a/dev/View/User/MailBox/MessageList.js
+++ b/dev/View/User/MailBox/MessageList.js
@@ -159,7 +159,7 @@
}, this);
this.isSpamDisabled = ko.computed(function () {
- return Consts.Values.UnuseOptionValue === FolderStore.spamFolder();
+ return Consts.UNUSED_OPTION_VALUE === FolderStore.spamFolder();
}, this);
this.isTrashFolder = ko.computed(function () {
@@ -183,7 +183,7 @@
}, this);
this.isArchiveDisabled = ko.computed(function () {
- return Consts.Values.UnuseOptionValue === FolderStore.archiveFolder();
+ return Consts.UNUSED_OPTION_VALUE === FolderStore.archiveFolder();
}, this);
this.isArchiveVisible = ko.computed(function () {
diff --git a/dev/View/User/MailBox/MessageView.js b/dev/View/User/MailBox/MessageView.js
index b86546bf4..46635b4f9 100644
--- a/dev/View/User/MailBox/MessageView.js
+++ b/dev/View/User/MailBox/MessageView.js
@@ -10,9 +10,6 @@
ko = require('ko'),
key = require('key'),
-// PhotoSwipe = require('PhotoSwipe'),
-// PhotoSwipeUI_Default = require('PhotoSwipeUI_Default'),
-
Consts = require('Common/Consts'),
Enums = require('Common/Enums'),
Globals = require('Common/Globals'),
@@ -31,7 +28,7 @@
FolderStore = require('Stores/User/Folder'),
MessageStore = require('Stores/User/Message'),
- Local = require('Storage/Client'),
+ Local = require('Storage/Client.jsx'),
Settings = require('Storage/Settings'),
Remote = require('Remote/User/Ajax'),
@@ -298,7 +295,7 @@
this.viewLineAsCss = ko.observable('');
this.viewViewLink = ko.observable('');
this.viewDownloadLink = ko.observable('');
- this.viewUserPic = ko.observable(Consts.DataImages.UserDotPic);
+ this.viewUserPic = ko.observable(Consts.DATA_IMAGE_USER_DOT_PIC);
this.viewUserPicVisible = ko.observable(false);
this.viewIsImportant = ko.observable(false);
this.viewIsFlagged = ko.observable(false);
@@ -385,7 +382,7 @@
if (sPic !== self.viewUserPic() && sLastEmail === sEmail)
{
self.viewUserPicVisible(false);
- self.viewUserPic(Consts.DataImages.UserDotPic);
+ self.viewUserPic(Consts.DATA_IMAGE_USER_DOT_PIC);
if ('' !== sPic)
{
self.viewUserPicVisible(true);
@@ -691,92 +688,6 @@
this.oHeaderDom = $('.messageItemHeader', oDom);
this.oHeaderDom = this.oHeaderDom[0] ? this.oHeaderDom : null;
-/*
- this.pswpDom = $('.pswp', oDom)[0];
-
- if (this.pswpDom)
- {
- oDom
- .on('click', '.attachmentImagePreview.visible', function (oEvent) {
-
- var
- iIndex = 0,
- oPs = null,
- oEl = oEvent.currentTarget || null,
- aItems = []
-// fThumbBoundsFn = function (index) {
-// var oRes = null, oEl = aItems[index], oPos = null;
-// if (oEl && oEl.el)
-// {
-// oPos = oEl.el.find('.iconBG').offset();
-// oRes = oPos && oPos.top && oPos.left ?
-// {x: oPos.left, y: oPos.top, w: 60} : null;
-// }
-//
-// return oRes;
-// }
- ;
-
- oDom.find('.attachmentImagePreview.visible').each(function (index, oSubElement) {
-
- var
- $oItem = $(oSubElement)
- ;
-
- if (oEl === oSubElement)
- {
- iIndex = index;
- }
-
- aItems.push({
- 'w': 600, 'h': 400,
- 'src': $oItem.attr('href'),
- 'title': $oItem.attr('title') || ''
- });
- });
-
- if (aItems && 0 < aItems.length)
- {
- Globals.useKeyboardShortcuts(false);
-
- oPs = new PhotoSwipe(self.pswpDom, PhotoSwipeUI_Default, aItems, {
- 'index': iIndex,
- 'bgOpacity': 0.85,
- 'loadingIndicatorDelay': 500,
- 'errorMsg': '' + sErrorMessage + '
',
- 'showHideOpacity': true,
- 'tapToToggleControls': false,
-// 'getThumbBoundsFn': fThumbBoundsFn,
- 'timeToIdle': 0,
- 'timeToIdleOutside': 0,
- 'history': false,
- 'arrowEl': 1 < aItems.length,
- 'counterEl': 1 < aItems.length,
- 'shareEl': false
- });
-
- oPs.listen('imageLoadComplete', function(index, item) {
- if (item && item.img && item.img.width && item.img.height)
- {
- item.w = item.img.width;
- item.h = item.img.height;
-
- oPs.updateSize(true);
- }
- });
-
- oPs.listen('close', function() {
- Globals.useKeyboardShortcuts(true);
- });
-
- oPs.init();
- }
-
- return false;
- });
- }
-*/
-
oDom
.on('click', 'a', function (oEvent) {
// setup maito protocol
@@ -1061,7 +972,7 @@
*/
MessageViewMailBoxUserView.prototype.isSpamDisabled = function ()
{
- return MessageStore.message() && FolderStore.spamFolder() === Consts.Values.UnuseOptionValue;
+ return MessageStore.message() && FolderStore.spamFolder() === Consts.UNUSED_OPTION_VALUE;
};
/**
@@ -1077,7 +988,7 @@
*/
MessageViewMailBoxUserView.prototype.isArchiveDisabled = function ()
{
- return MessageStore.message() && FolderStore.archiveFolder() === Consts.Values.UnuseOptionValue;
+ return MessageStore.message() && FolderStore.archiveFolder() === Consts.UNUSED_OPTION_VALUE;
};
/**
diff --git a/dev/common.jsx b/dev/common.jsx
new file mode 100644
index 000000000..9ca1d48e9
--- /dev/null
+++ b/dev/common.jsx
@@ -0,0 +1,10 @@
+
+import window from 'window';
+import $ from '$';
+import JSON from 'JSON';
+import _ from '_';
+import Q from 'Q';
+import moment from 'moment';
+import key from 'key';
+
+export {window, $, JSON, _, Q, moment, key};
diff --git a/gulpfile.js b/gulpfile.js
index 8684f9c9e..200794b1e 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -97,7 +97,9 @@ function copyFile(sFile, sNewFile, callback)
callback();
}
-cfg.paths.globjs = 'dev/**/*.js';
+cfg.paths.globjs = 'dev/**/*.{js,jsx}';
+cfg.paths.globjsonly = 'dev/**/*.js';
+cfg.paths.globjsxonly = 'dev/**/*.jsx';
cfg.paths.static = 'rainloop/v/' + cfg.devVersion + '/static/';
cfg.paths.staticJS = 'rainloop/v/' + cfg.devVersion + '/static/js/';
cfg.paths.staticMinJS = 'rainloop/v/' + cfg.devVersion + '/static/js/min/';
@@ -456,7 +458,7 @@ gulp.task('js:lint', function() {
jshint = require('gulp-jshint')
;
- return gulp.src(cfg.paths.globjs)
+ return gulp.src(cfg.paths.globjsonly)
.pipe(jshint('.jshintrc'))
.pipe(jshint.reporter('jshint-summary', cfg.summary))
.pipe(jshint.reporter('fail'))
@@ -471,6 +473,22 @@ gulp.task('js:lint', function() {
;
});
+gulp.task('js:eslint', function() {
+
+ var eslint = require('gulp-eslint');
+
+ return gulp.src(cfg.paths.globjsxonly)
+ .pipe(eslint({
+ parser: 'babel-eslint',
+ rules: {
+ 'strict': 0
+ }
+ }))
+ .pipe(eslint.format())
+ .pipe(eslint.failAfterError())
+ ;
+});
+
// OTHER
regOtherMinTask('other:cookie', 'vendors/jquery-cookie/', 'jquery.cookie.js', 'jquery.cookie-1.4.0.min.js',
'/*! jquery.cookie v1.4.0 (c) 2013 Klaus Hartl | MIT */\n');
@@ -692,7 +710,7 @@ gulp.task('fast-', ['js:app', 'js:admin', 'js:chunks', 'css:main']);
gulp.task('fast', ['package:community-on', 'fast-']);
gulp.task('fast+', ['package:community-off', 'fast-']);
-gulp.task('rainloop:start', ['js:lint', 'rainloop:copy', 'rainloop:setup']);
+gulp.task('rainloop:start', ['rainloop:copy', 'rainloop:setup']);
gulp.task('rainloop-', ['rainloop:start', 'rainloop:zip', 'rainloop:md5', 'rainloop:clean', 'rainloop:shortname']);
@@ -724,7 +742,6 @@ gulp.task('watch+', ['fast+'], function() {
// ALIASES
gulp.task('build', ['rainloop']);
gulp.task('build+', ['rainloop+']);
-gulp.task('js:hint', ['js:lint']);
gulp.task('w', ['watch']);
gulp.task('w+', ['watch+']);
@@ -736,6 +753,3 @@ gulp.task('b+', ['build+']);
gulp.task('o', ['owncloud']);
gulp.task('o+', ['owncloud+']);
-
-gulp.task('h', ['js:lint']);
-gulp.task('l', ['js:lint']);
diff --git a/package.json b/package.json
index 09357f489..1c7550346 100644
--- a/package.json
+++ b/package.json
@@ -1,8 +1,8 @@
{
"name": "RainLoop",
"title": "RainLoop Webmail",
- "version": "1.9.3",
- "release": "365",
+ "version": "1.9.4",
+ "release": "387",
"description": "Simple, modern & fast web-based email client",
"homepage": "http://rainloop.net",
"main": "gulpfile.js",
@@ -45,35 +45,41 @@
"node": ">= 0.10.0"
},
"devDependencies": {
- "node-fs": "*",
- "rimraf": "*",
- "jshint-summary": "*",
- "webpack": "*",
+ "babel-core": "^6.1.4",
+ "babel-eslint": "^4.1.5",
+ "babel-loader": "^6.1.0",
+ "babel-preset-es2015": "^6.1.4",
+ "eslint": "^1.9.0",
"gulp": "~3.9.0",
- "gulp-util": "*",
- "gulp-uglify": "*",
- "gulp-rimraf": "*",
+ "gulp-autoprefixer": "*",
+ "gulp-beautify": "*",
+ "gulp-closure-compiler": "*",
+ "gulp-concat-util": "*",
+ "gulp-csscomb": "*",
+ "gulp-csslint": "*",
+ "gulp-eol": "*",
+ "gulp-eslint": "^1.1.0",
+ "gulp-header": "*",
+ "gulp-if": "~1.2.5",
"gulp-jshint": "*",
"gulp-less": "1.3.6",
- "gulp-zip": "*",
+ "gulp-livereload": "~3.8.0",
+ "gulp-minify-css": "*",
+ "gulp-notify": "~2.2.0",
+ "gulp-plumber": "*",
"gulp-rename": "*",
"gulp-replace": "*",
- "gulp-header": "*",
- "gulp-eol": "*",
+ "gulp-rimraf": "*",
"gulp-stripbom": "*",
- "gulp-minify-css": "*",
- "gulp-autoprefixer": "*",
- "gulp-csscomb": "*",
- "gulp-closure-compiler": "*",
- "gulp-csslint": "*",
- "gulp-beautify": "*",
- "gulp-plumber": "*",
- "gulp-concat-util": "*",
- "gulp-notify": "~2.2.0",
"gulp-through": "~0.3.0",
+ "gulp-uglify": "*",
+ "gulp-util": "*",
+ "gulp-zip": "*",
+ "jshint-summary": "*",
"lodash": "~3.9.3",
- "gulp-if": "~1.2.5",
+ "node-fs": "*",
"node-notifier": "~4.2.3",
- "gulp-livereload": "~3.8.0"
+ "rimraf": "*",
+ "webpack": "*"
}
}
diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/ServiceActions.php b/rainloop/v/0.0.0/app/libraries/RainLoop/ServiceActions.php
index 1c9abe90e..68a527e7e 100644
--- a/rainloop/v/0.0.0/app/libraries/RainLoop/ServiceActions.php
+++ b/rainloop/v/0.0.0/app/libraries/RainLoop/ServiceActions.php
@@ -1278,12 +1278,8 @@ class ServiceActions
\RainLoop\Utils::ReadAndAddLang(APP_VERSION_ROOT_PATH.'app/localization/langs.yml', $aResultLang);
\RainLoop\Utils::ReadAndAddLang(APP_VERSION_ROOT_PATH.'app/localization/'.
($bAdmin ? 'admin' : 'webmail').'/_source.en.yml', $aResultLang);
-
- if ('en_US' !== $sLanguage)
- {
- \RainLoop\Utils::ReadAndAddLang(APP_VERSION_ROOT_PATH.'app/localization/'.
- ($bAdmin ? 'admin' : 'webmail').'/'.$sLanguage.'.yml', $aResultLang);
- }
+ \RainLoop\Utils::ReadAndAddLang(APP_VERSION_ROOT_PATH.'app/localization/'.
+ ($bAdmin ? 'admin' : 'webmail').'/'.$sLanguage.'.yml', $aResultLang);
$this->Plugins()->ReadLang($sLanguage, $aResultLang);
diff --git a/rainloop/v/0.0.0/app/localization/admin/_source.en.yml b/rainloop/v/0.0.0/app/localization/admin/_source.en.yml
index 7c307684f..8a3917753 100644
--- a/rainloop/v/0.0.0/app/localization/admin/_source.en.yml
+++ b/rainloop/v/0.0.0/app/localization/admin/_source.en.yml
@@ -292,6 +292,7 @@ en:
DEMO_SEND_MESSAGE_ERROR: "For security purposes, this account is not allowed to send messages to external e-mail addresses!"
DEMO_ACCOUNT_ERROR: "For security purposes, this account is not allowed for this action!"
ACCOUNT_ALREADY_EXISTS: "Account already exists"
+ ACCOUNT_DOES_NOT_EXIST: "Account doesn't exist"
MAIL_SERVER_ERROR: "An error has occured while accessing mail server"
INVALID_INPUT_ARGUMENT: "Invalid input argument"
UNKNOWN_ERROR: "Unknown error"
diff --git a/rainloop/v/0.0.0/app/localization/admin/de_DE.yml b/rainloop/v/0.0.0/app/localization/admin/de_DE.yml
index b4cfc5292..5834863fc 100644
--- a/rainloop/v/0.0.0/app/localization/admin/de_DE.yml
+++ b/rainloop/v/0.0.0/app/localization/admin/de_DE.yml
@@ -89,6 +89,10 @@ de_DE:
LEGEND_DOMAINS: "Domains"
BUTTON_ADD_DOMAIN: "Domain hinzufügen"
DELETE_ARE_YOU_SURE: "Sind Sie sicher?"
+ HTML_DOMAINS_HELPER: |
+ Liste der Domains, die Webmail abrufen darf.
+
+ Klicken Sie auf den Namen, um die Domain zu konfigurieren.
TAB_SECURITY:
LEGEND_SECURITY: "Sicherheit"
LABEL_ALLOW_TWO_STEP: "Zwei-Faktor-Authentifizierung erlauben"
@@ -176,6 +180,12 @@ de_DE:
LABEL_ACTIVATED: "Aktiviert"
ERROR_INVALID_SUBS_KEY: "Ungültiger Subscription-Schlüssel"
SUBS_KEY_ACTIVATED: "Subscription-Schlüssel erfolgreich aktiviert"
+ HTML_DESC: |
+ Nach der Aktivierung wird %DOMAIN% um die Premium-Subscription erweitert.
+
+ Beachten Sie, dass ein Subscription-Schlüssel nur für eine einzelne Domain aktiviert werden kann.
+
+ Nach dem Start kann der Aktivierungsprozess nicht unterbrochen oder abgebrochen werden.
POPUPS_DOMAIN:
TITLE_ADD_DOMAIN: "Domain hinzufügen"
TITLE_ADD_DOMAIN_WITH_NAME: "Domain \"%NAME%\" hinzufügen"
diff --git a/rainloop/v/0.0.0/app/localization/admin/it_IT.yml b/rainloop/v/0.0.0/app/localization/admin/it_IT.yml
index 95e731025..678afc4c2 100644
--- a/rainloop/v/0.0.0/app/localization/admin/it_IT.yml
+++ b/rainloop/v/0.0.0/app/localization/admin/it_IT.yml
@@ -90,6 +90,10 @@ it_IT:
LEGEND_DOMAINS: "Domini"
BUTTON_ADD_DOMAIN: "Aggiungi dominio"
DELETE_ARE_YOU_SURE: "Ne sei sicuro?"
+ HTML_DOMAINS_HELPER: |
+ Lista di domini a cui la webmail è abilitata ad accedere.
+
+ Clicca su un nome per configurare quel dominio.
TAB_SECURITY:
LEGEND_SECURITY: "Security"
LABEL_ALLOW_TWO_STEP: "Abilita l'autenticazione a due fattori"
@@ -177,6 +181,12 @@ it_IT:
LABEL_ACTIVATED: "Attivata"
ERROR_INVALID_SUBS_KEY: "Chiave di licenza non valida"
SUBS_KEY_ACTIVATED: "Chiave di licenza attivata correttamente"
+ HTML_DESC: |
+ Dopo l'attivazione, la licenza Premium per %DOMAIN% sarà estesa.
+
+ Una chiave di licenza può essere attivata su un solo dominio.
+
+ Una volta iniziato, il processo di attivazione non potrà essere bloccato od annullato.
POPUPS_DOMAIN:
TITLE_ADD_DOMAIN: "Aggiungi dominio"
TITLE_ADD_DOMAIN_WITH_NAME: "Aggiungi il dominio \"%NAME%\""
diff --git a/rainloop/v/0.0.0/app/localization/admin/nb_NO.yml b/rainloop/v/0.0.0/app/localization/admin/nb_NO.yml
index 754821abf..60a2041a1 100644
--- a/rainloop/v/0.0.0/app/localization/admin/nb_NO.yml
+++ b/rainloop/v/0.0.0/app/localization/admin/nb_NO.yml
@@ -90,6 +90,10 @@ nb_NO:
LEGEND_DOMAINS: "Domener"
BUTTON_ADD_DOMAIN: "Legg til domene"
DELETE_ARE_YOU_SURE: "Er du sikker?"
+ HTML_DOMAINS_HELPER: |
+ Liste over domener som programmet kan få tilgang til.
+
+ Trykk på et navn for å sette opp domenet.
TAB_SECURITY:
LEGEND_SECURITY: "Sikkerhet"
LABEL_ALLOW_TWO_STEP: "Tillat tostegsbekreftelse"
@@ -177,6 +181,12 @@ nb_NO:
LABEL_ACTIVATED: "I bruk"
ERROR_INVALID_SUBS_KEY: "Ugyldig abonnementsnøkkel"
SUBS_KEY_ACTIVATED: "Abonnementsnøkkelen er nå i bruk"
+ HTML_DESC: |
+ Premium-abonnement for %DOMAIN% fonyes.
+
+ Nøkkelen kan bare tas i bruk for ett domene.
+
+ Du kan ikke angre på å ta en nøkkel i bruk.
POPUPS_DOMAIN:
TITLE_ADD_DOMAIN: "Legg til domene"
TITLE_ADD_DOMAIN_WITH_NAME: "Legg til «%NAME%»"
diff --git a/rainloop/v/0.0.0/app/localization/admin/nl_NL.yml b/rainloop/v/0.0.0/app/localization/admin/nl_NL.yml
index 32eddf6ad..f318940a8 100644
--- a/rainloop/v/0.0.0/app/localization/admin/nl_NL.yml
+++ b/rainloop/v/0.0.0/app/localization/admin/nl_NL.yml
@@ -87,6 +87,10 @@ nl_NL:
LEGEND_DOMAINS: "Domeinen"
BUTTON_ADD_DOMAIN: "Domein toevoegen"
DELETE_ARE_YOU_SURE: "Weet u het zeker?"
+ HTML_DOMAINS_HELPER: |
+ Lijst van toegestane domeinen.
+
+ Klik op de domeinnaam om deze te configureren.
TAB_SECURITY:
LEGEND_SECURITY: "Beveiliging"
LABEL_ALLOW_TWO_STEP: "2-Stap verificatie toestaan"
diff --git a/rainloop/v/0.0.0/app/localization/admin/pl_PL.yml b/rainloop/v/0.0.0/app/localization/admin/pl_PL.yml
index a3684fa43..d19fa973f 100644
--- a/rainloop/v/0.0.0/app/localization/admin/pl_PL.yml
+++ b/rainloop/v/0.0.0/app/localization/admin/pl_PL.yml
@@ -90,6 +90,10 @@ pl_PL:
LEGEND_DOMAINS: "Domeny"
BUTTON_ADD_DOMAIN: "Dodaj domenę"
DELETE_ARE_YOU_SURE: "Czy na pewno?"
+ HTML_DOMAINS_HELPER: |
+ Lista domen, do których można uzyskać dostęp poprzez tego klienta.
+
+ Kliknij na nazwę, aby skonfigurować domenę.
TAB_SECURITY:
LEGEND_SECURITY: "Bezpieczeństwo"
LABEL_ALLOW_TWO_STEP: "Zezwól na dwuskładnikową autoryzację"
@@ -177,6 +181,12 @@ pl_PL:
LABEL_ACTIVATED: "Aktywowano"
ERROR_INVALID_SUBS_KEY: "Niepoprawny klucz subskrypcji"
SUBS_KEY_ACTIVATED: "Aktywowano klucz subskrypcji"
+ HTML_DESC: |
+ Subskrypcja premium dla domeny: %DOMAIN% , zostanie przedłużona po aktywacji.
+
+ Zwróc uwagę, że klucz subskrypcji może być aktywowany tylko dla jednej domeny.
+
+ Po uruchomieniu aktywacji, nie można jej przerwac lub anulować.
POPUPS_DOMAIN:
TITLE_ADD_DOMAIN: "Dodawanie domeny"
TITLE_ADD_DOMAIN_WITH_NAME: "Dodawanie domeny: \"%NAME%\""
diff --git a/rainloop/v/0.0.0/app/localization/admin/pt_BR.yml b/rainloop/v/0.0.0/app/localization/admin/pt_BR.yml
index 01748591c..74d745b3d 100644
--- a/rainloop/v/0.0.0/app/localization/admin/pt_BR.yml
+++ b/rainloop/v/0.0.0/app/localization/admin/pt_BR.yml
@@ -90,6 +90,10 @@ pt_BR:
LEGEND_DOMAINS: "Domínios"
BUTTON_ADD_DOMAIN: "Adicionar Domínio"
DELETE_ARE_YOU_SURE: "Você tem certeza?"
+ HTML_DOMAINS_HELPER: |
+ Lista dos domínios com acesso permitido ao webmail.
+
+ Clique no domínio para configurá-lo.
TAB_SECURITY:
LEGEND_SECURITY: "Segurança"
LABEL_ALLOW_TWO_STEP: "Permitir verificação em duas etapas (Login 2-Step)"
@@ -177,6 +181,12 @@ pt_BR:
LABEL_ACTIVATED: "Ativado"
ERROR_INVALID_SUBS_KEY: "Chave de assinatura inválida"
SUBS_KEY_ACTIVATED: "Chave de assinatura ativada com sucesso"
+ HTML_DESC: |
+ Após a ativação, a assinatura premium para %DOMAIN% será extendida.
+
+ Note que chave de assinatura é ativada apenas para um único domínio.
+
+ Uma vez iniciado, o processo de ativação não poderá ser interrompido ou cancelado.
POPUPS_DOMAIN:
TITLE_ADD_DOMAIN: "Adicionar Domínio"
TITLE_ADD_DOMAIN_WITH_NAME: "Adicionar Domínio \"%NAME%\""
diff --git a/rainloop/v/0.0.0/app/localization/admin/ru_RU.yml b/rainloop/v/0.0.0/app/localization/admin/ru_RU.yml
index 72049ecc2..5c0401cc1 100644
--- a/rainloop/v/0.0.0/app/localization/admin/ru_RU.yml
+++ b/rainloop/v/0.0.0/app/localization/admin/ru_RU.yml
@@ -89,6 +89,10 @@ ru_RU:
LEGEND_DOMAINS: "Домены"
BUTTON_ADD_DOMAIN: "Добавить домен"
DELETE_ARE_YOU_SURE: "Вы уверены?"
+ HTML_DOMAINS_HELPER: |
+ Список доменов к которым разрешен доступ.
+
+ Нажмите на имя, чтобы настроить домен.
TAB_SECURITY:
LEGEND_SECURITY: "Безопасность"
LABEL_ALLOW_TWO_STEP: "Разрешить 2-шаговую проверку"
@@ -176,6 +180,12 @@ ru_RU:
LABEL_ACTIVATED: "Активировано"
ERROR_INVALID_SUBS_KEY: "Неверный ключ подписки"
SUBS_KEY_ACTIVATED: "Ключ подписки активирован удачно"
+ HTML_DESC: |
+ После активации премиум подписка для %DOMAIN% будет продлена.
+
+ Обратите внимание, что ключ может быть активирован только один раз.
+
+ После запуска процесс активации не может быть прерван или отменен.
POPUPS_DOMAIN:
TITLE_ADD_DOMAIN: "Добавить домен"
TITLE_ADD_DOMAIN_WITH_NAME: "Добавить домен \"%NAME%\""
diff --git a/rainloop/v/0.0.0/app/localization/webmail/_source.en.yml b/rainloop/v/0.0.0/app/localization/webmail/_source.en.yml
index d94d41d02..057ca2aad 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/_source.en.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/_source.en.yml
@@ -235,6 +235,8 @@ en:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Close"
POPUPS_ASK:
+ BUTTON_YES: "Yes"
+ BUTTON_NO: "No"
DESC_WANT_CLOSE_THIS_WINDOW: "Are you sure you want to close this window?"
DESC_WANT_DELETE_MESSAGES: "Are you sure you want to delete the message(s)?"
POPUPS_LANGUAGES:
@@ -678,6 +680,7 @@ en:
DEMO_SEND_MESSAGE_ERROR: "For security purposes, this account is not allowed to send messages to external e-mail addresses!"
DEMO_ACCOUNT_ERROR: "For security purposes, this account is not allowed for this action!"
ACCOUNT_ALREADY_EXISTS: "Account already exists"
+ ACCOUNT_DOES_NOT_EXIST: "Account doesn't exist"
MAIL_SERVER_ERROR: "An error has occured while accessing mail server"
INVALID_INPUT_ARGUMENT: "Invalid input argument"
UNKNOWN_ERROR: "Unknown error"
diff --git a/rainloop/v/0.0.0/app/localization/webmail/ar_SA.yml b/rainloop/v/0.0.0/app/localization/webmail/ar_SA.yml
index e92c81c05..e5019dd2d 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/ar_SA.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/ar_SA.yml
@@ -232,6 +232,8 @@ ar_SA:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "إغلاق"
POPUPS_ASK:
+ BUTTON_YES: "نعم"
+ BUTTON_NO: "لا"
DESC_WANT_CLOSE_THIS_WINDOW: "هل أنت متأكد من رغبتك باغلاق هذه النافذة؟"
DESC_WANT_DELETE_MESSAGES: "هل أنت متأكد من رغبتك بحذف هذه الرسائل؟"
POPUPS_LANGUAGES:
diff --git a/rainloop/v/0.0.0/app/localization/webmail/bg_BG.yml b/rainloop/v/0.0.0/app/localization/webmail/bg_BG.yml
index 96e6747c8..f558b65c0 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/bg_BG.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/bg_BG.yml
@@ -235,6 +235,8 @@ bg_BG:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Close"
POPUPS_ASK:
+ BUTTON_YES: "Да"
+ BUTTON_NO: "Не"
DESC_WANT_CLOSE_THIS_WINDOW: "Сигурни ли сте, че желаете да затворите този прозорец?"
DESC_WANT_DELETE_MESSAGES: "Сигурни ли сте, че желаете да изтриете съобщението/съобщенията?"
POPUPS_LANGUAGES:
diff --git a/rainloop/v/0.0.0/app/localization/webmail/cs_CZ.yml b/rainloop/v/0.0.0/app/localization/webmail/cs_CZ.yml
index fc5432e7b..603153d4f 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/cs_CZ.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/cs_CZ.yml
@@ -234,6 +234,8 @@ cs_CZ:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Close"
POPUPS_ASK:
+ BUTTON_YES: "Ano"
+ BUTTON_NO: "Ne"
DESC_WANT_CLOSE_THIS_WINDOW: "Opravdu chcete zavřít toto okno?"
DESC_WANT_DELETE_MESSAGES: "Opravdu chcete odstranit tyto zprávy?"
POPUPS_LANGUAGES:
diff --git a/rainloop/v/0.0.0/app/localization/webmail/de_DE.yml b/rainloop/v/0.0.0/app/localization/webmail/de_DE.yml
index efb13a6c2..f124afcc2 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/de_DE.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/de_DE.yml
@@ -148,6 +148,11 @@ de_DE:
LINK_SAVE_TO_DROPBOX: "In Dropbox speichern"
READ_RECEIPT:
SUBJECT: "Empfangsbestätigung (angezeigt) - %SUBJECT%"
+ BODY: |
+ Dies ist eine Empfangsbestätigung für die Nachricht, die Sie an %READ-RECEIPT% gesendet haben.
+
+ Hinweis: Diese Empfangsbestätigung bestätigt nur, dass die Nachricht auf dem Computer des Empfängers angezeigt wurde.
+ Es besteht keine Garantie, dass der Empfänger den Inhalt der Nachricht gelesen oder verstanden hat.
SUGGESTIONS:
SEARCHING_DESC: "Suche läuft..."
CONTACTS:
@@ -230,6 +235,8 @@ de_DE:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Schließen"
POPUPS_ASK:
+ BUTTON_YES: "Ja"
+ BUTTON_NO: "Nein"
DESC_WANT_CLOSE_THIS_WINDOW: "Sind Sie sicher, dass Sie dieses Fenster schließen möchten?"
DESC_WANT_DELETE_MESSAGES: "Sind Sie sicher, dass Sie diese Nachricht(en) löschen möchten?"
POPUPS_LANGUAGES:
@@ -328,6 +335,8 @@ de_DE:
SELECT_TYPE_NOT_EQUAL_TO: "Ungleich"
SELECT_TYPE_OVER: "Über"
SELECT_TYPE_UNDER: "Unter"
+ SELECT_MATCH_ANY: "Eine der folgenden Regeln trifft zu"
+ SELECT_MATCH_ALL: "Alle folgenden Regeln treffen zu"
MARK_AS_READ_LABEL: "Als Gelesen markieren"
REPLY_INTERVAL_LABEL: "Antwortintervall (Tage)"
KEEP_LABEL: "Behalten"
@@ -352,12 +361,14 @@ de_DE:
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\"-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\"-Systemordner gewählt, in dem die archivierten Nachrichten abgelegt werden."
POPUPS_TWO_FACTOR_CFG:
LEGEND_TWO_FACTOR_AUTH: "Zwei-Faktor-Authentifizierung"
LABEL_ENABLE_TWO_FACTOR: "Zwei-Faktor-Authentifizierung aktivieren"
@@ -622,6 +633,18 @@ de_DE:
ACCESS_ERROR: "Zugriffsfehler"
CONNECTION_ERROR: "Serververbindung kann nicht hergestellt werden"
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-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"
diff --git a/rainloop/v/0.0.0/app/localization/webmail/en_GB.yml b/rainloop/v/0.0.0/app/localization/webmail/en_GB.yml
index eba2ba405..640093d69 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/en_GB.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/en_GB.yml
@@ -148,6 +148,11 @@ en_GB:
LINK_SAVE_TO_DROPBOX: "Save to Dropbox"
READ_RECEIPT:
SUBJECT: "Return Receipt (displayed) - %SUBJECT%"
+ BODY: |
+ This is a Return Receipt for the mail that you sent to %READ-RECEIPT%.
+
+ Note: "This Return Receipt only acknowledges that the message was displayed on the recipient's computer."
+ There is no guarantee that the recipient has read or understood the message contents.
SUGGESTIONS:
SEARCHING_DESC: "Searching..."
CONTACTS:
@@ -230,6 +235,8 @@ en_GB:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Close"
POPUPS_ASK:
+ BUTTON_YES: "Yes"
+ BUTTON_NO: "No"
DESC_WANT_CLOSE_THIS_WINDOW: "Are you sure you want to close this window?"
DESC_WANT_DELETE_MESSAGES: "Are you sure you want to delete the message(s)?"
POPUPS_LANGUAGES:
@@ -328,6 +335,8 @@ en_GB:
SELECT_TYPE_NOT_EQUAL_TO: "Not Equal To"
SELECT_TYPE_OVER: "Over"
SELECT_TYPE_UNDER: "Under"
+ SELECT_MATCH_ANY: "Matching ANY of the following rules"
+ SELECT_MATCH_ALL: "Matching ALL of the following rules"
MARK_AS_READ_LABEL: "Mark as read"
REPLY_INTERVAL_LABEL: "Reply interval (days)"
KEEP_LABEL: "Keep"
@@ -352,12 +361,14 @@ en_GB:
NOTIFICATION_SENT: |
You haven't selected "Sent" system folder messages are put to after sending.
If you don't want to save sent message, please select "Do not use" option.
+ NOTIFICATION_DRAFTS: "You haven't selected \"Drafts\" system folder messages are saved to while composing."
NOTIFICATION_SPAM: |
You haven't selected "Spam" system folder spamed messages are placed to.
If you wish to remove messages permanently, please select "Do not use" option.
NOTIFICATION_TRASH: |
You haven't selected "Trash" system folder deleted messages are placed to.
If you wish to remove messages permanently, please select "Do not use" option.
+ NOTIFICATION_ARCHIVE: "You haven't selected \"Archive\" system folder achived messages are placed to."
POPUPS_TWO_FACTOR_CFG:
LEGEND_TWO_FACTOR_AUTH: "2-Step Verification (TOTP)"
LABEL_ENABLE_TWO_FACTOR: "Enable 2-Step verification"
@@ -621,6 +632,15 @@ en_GB:
ACCESS_ERROR: "Access error"
CONNECTION_ERROR: "Can't connect to server"
CAPTCHA_ERROR: "Incorrect CAPTCHA."
+ SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE: >
+ This social ID is not assigned for any email account yet. Log in using email
+ credentials and enable this feature in account settings.
+ SOCIAL_TWITTER_LOGIN_ACCESS_DISABLE: >
+ This social ID is not assigned for any email account yet. Log in using email
+ credentials and enable this feature in account settings.
+ SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE: >
+ This social ID is not assigned for any email account yet. Log in using email
+ credentials and enable this feature in account settings.
DOMAIN_NOT_ALLOWED: "Domain is not allowed"
ACCOUNT_NOT_ALLOWED: "Account is not allowed"
ACCOUNT_TWO_FACTOR_AUTH_REQUIRED: "Two factor verification required"
@@ -660,6 +680,7 @@ en_GB:
DEMO_SEND_MESSAGE_ERROR: "For security purposes, this account is not allowed to send messages to external e-mail addresses!"
DEMO_ACCOUNT_ERROR: "For security purposes, this account is not allowed for this action!"
ACCOUNT_ALREADY_EXISTS: "Account already exists"
+ ACCOUNT_DOES_NOT_EXIST: "Account doesn't exist"
MAIL_SERVER_ERROR: "An error has occured while accessing mail server"
INVALID_INPUT_ARGUMENT: "Invalid input argument"
UNKNOWN_ERROR: "Unknown error"
diff --git a/rainloop/v/0.0.0/app/localization/webmail/en_US.yml b/rainloop/v/0.0.0/app/localization/webmail/en_US.yml
index 74f95b4dc..e7d4c6bb6 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/en_US.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/en_US.yml
@@ -235,6 +235,8 @@ en_US:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Close"
POPUPS_ASK:
+ BUTTON_YES: "Yes"
+ BUTTON_NO: "No"
DESC_WANT_CLOSE_THIS_WINDOW: "Are you sure you want to close this window?"
DESC_WANT_DELETE_MESSAGES: "Are you sure you want to delete the message(s)?"
POPUPS_LANGUAGES:
@@ -678,6 +680,7 @@ en_US:
DEMO_SEND_MESSAGE_ERROR: "For security purposes, this account is not allowed to send messages to external e-mail addresses!"
DEMO_ACCOUNT_ERROR: "For security purposes, this account is not allowed for this action!"
ACCOUNT_ALREADY_EXISTS: "Account already exists"
+ ACCOUNT_DOES_NOT_EXIST: "Account doesn't exist"
MAIL_SERVER_ERROR: "An error has occured while accessing mail server"
INVALID_INPUT_ARGUMENT: "Invalid input argument"
UNKNOWN_ERROR: "Unknown error"
diff --git a/rainloop/v/0.0.0/app/localization/webmail/fr_FR.yml b/rainloop/v/0.0.0/app/localization/webmail/fr_FR.yml
index 9912437dc..290e3dc28 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/fr_FR.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/fr_FR.yml
@@ -235,6 +235,8 @@ fr_FR:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Fermer"
POPUPS_ASK:
+ BUTTON_YES: "Oui"
+ BUTTON_NO: "Non"
DESC_WANT_CLOSE_THIS_WINDOW: "Êtes-vous sûr de vouloir fermer cette fenêtre ?"
DESC_WANT_DELETE_MESSAGES: "Êtes-vous sûr de vouloir supprimer ce(s) message(s) ?"
POPUPS_LANGUAGES:
diff --git a/rainloop/v/0.0.0/app/localization/webmail/hu_HU.yml b/rainloop/v/0.0.0/app/localization/webmail/hu_HU.yml
index ed0725cd5..231afad21 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/hu_HU.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/hu_HU.yml
@@ -235,6 +235,8 @@ hu_HU:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Close"
POPUPS_ASK:
+ BUTTON_YES: "Igen"
+ BUTTON_NO: "Nem"
DESC_WANT_CLOSE_THIS_WINDOW: "Biztos, hogy bezárjuk ezt az ablakot?"
DESC_WANT_DELETE_MESSAGES: "Biztos, hogy töröljük ezt a levelet/leveleket?"
POPUPS_LANGUAGES:
diff --git a/rainloop/v/0.0.0/app/localization/webmail/it_IT.yml b/rainloop/v/0.0.0/app/localization/webmail/it_IT.yml
index cac9aa7cd..eba8d29f7 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/it_IT.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/it_IT.yml
@@ -148,6 +148,11 @@ it_IT:
LINK_SAVE_TO_DROPBOX: "Salva su DropBox"
READ_RECEIPT:
SUBJECT: "Avviso di lettura - %SUBJECT%"
+ BODY: |
+ Questo è un avviso di lettura per la mail che hai inviato a %READ-RECEIPT%.
+
+ Attenzione: questa notifica di lettura significa solo che il messaggio è stato visualizzato nel computer del destinatario.
+ Non c'è alcuna garanzia che il destinatario abbia letto o capito il contenuto del messaggio.
SUGGESTIONS:
SEARCHING_DESC: "Cerca..."
CONTACTS:
@@ -230,6 +235,8 @@ it_IT:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Chiudi"
POPUPS_ASK:
+ BUTTON_YES: "Si"
+ BUTTON_NO: "No"
DESC_WANT_CLOSE_THIS_WINDOW: "Sei sicuro di voler chiudere questa finestra?"
DESC_WANT_DELETE_MESSAGES: "Sei sicuro di voler eliminare il messaggio?"
POPUPS_LANGUAGES:
@@ -328,6 +335,8 @@ it_IT:
SELECT_TYPE_NOT_EQUAL_TO: "Non uguale a"
SELECT_TYPE_OVER: "Maggiore di"
SELECT_TYPE_UNDER: "Minore di"
+ SELECT_MATCH_ANY: "Corrisponde ad una delle seguenti regole"
+ SELECT_MATCH_ALL: "Corrisponde a tutte le seguenti regole"
MARK_AS_READ_LABEL: "Marca come letto"
REPLY_INTERVAL_LABEL: "Intervallo di risposta (giorni)"
KEEP_LABEL: "Mantieni"
@@ -352,12 +361,14 @@ it_IT:
NOTIFICATION_SENT: |
Non hai selezionato una cartella di sistema per la posta inviata.
Se non vuoi salvare i messaggi inviati seleziona "Non usarla".
+ NOTIFICATION_DRAFTS: "Non hai selezionato una cartella di sistema per le bozze."
NOTIFICATION_SPAM: |
Non hai selezionato una cartella di sistema per i messaggi spam.
Se li vuoi eliminare permanentemente seleziona "Non usarla".
NOTIFICATION_TRASH: |
Non hai selezionato una cartella di sistema per il cestino.
Se non lo vuoi usare (e quindi eliminare i messaggi permanentemente) seleziona "Non usarla".
+ NOTIFICATION_ARCHIVE: "Non hai selezionato una cartella di sistema per i messaggi archiviati."
POPUPS_TWO_FACTOR_CFG:
LEGEND_TWO_FACTOR_AUTH: "Autenticazione a due fattori"
LABEL_ENABLE_TWO_FACTOR: "Abilita autenticazione a due fattori"
@@ -621,6 +632,15 @@ it_IT:
ACCESS_ERROR: "Errore di accesso"
CONNECTION_ERROR: "Impossibile connettersi al server"
CAPTCHA_ERROR: "CAPTCHA."
+ SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE: >
+ Questo ID sociale non è collegato ad alcun indirizzo email. Entra utilizzando
+ le credenziali delle email e abilita questa funzionalità nelle impostazioni.
+ SOCIAL_TWITTER_LOGIN_ACCESS_DISABLE: >
+ Questo ID sociale non è collegato ad alcun indirizzo email. Entra utilizzando
+ le credenziali delle email e abilita questa funzionalità nelle impostazioni.
+ SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE: >
+ Questo ID sociale non è collegato ad alcun indirizzo email. Entra utilizzando
+ le credenziali delle email e abilita questa funzionalità nelle impostazioni.
DOMAIN_NOT_ALLOWED: "Il dominio non è autorizzato"
ACCOUNT_NOT_ALLOWED: "L'account non è autorizzato"
ACCOUNT_TWO_FACTOR_AUTH_REQUIRED: "La verifica a due fattori è richiesta"
diff --git a/rainloop/v/0.0.0/app/localization/webmail/ja_JP.yml b/rainloop/v/0.0.0/app/localization/webmail/ja_JP.yml
index 287df2196..a8346c6e1 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/ja_JP.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/ja_JP.yml
@@ -235,6 +235,8 @@ ja_JP:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Close"
POPUPS_ASK:
+ BUTTON_YES: "はい"
+ BUTTON_NO: "いいえ"
DESC_WANT_CLOSE_THIS_WINDOW: "このウインドウを閉じていいですか?"
DESC_WANT_DELETE_MESSAGES: "メッセージを削除していいですか?"
POPUPS_LANGUAGES:
diff --git a/rainloop/v/0.0.0/app/localization/webmail/lt_LT.yml b/rainloop/v/0.0.0/app/localization/webmail/lt_LT.yml
index df004e05f..8b19b3433 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/lt_LT.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/lt_LT.yml
@@ -235,6 +235,8 @@ lt_LT:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Uždaryti"
POPUPS_ASK:
+ BUTTON_YES: "Taip"
+ BUTTON_NO: "Ne"
DESC_WANT_CLOSE_THIS_WINDOW: "Ar tikrai norite uždaryti šį langą??"
DESC_WANT_DELETE_MESSAGES: "Ar tikrai norite ištrinti pranešimą(us)?"
POPUPS_LANGUAGES:
diff --git a/rainloop/v/0.0.0/app/localization/webmail/nb_NO.yml b/rainloop/v/0.0.0/app/localization/webmail/nb_NO.yml
index 42f3eacc5..2da2ac56c 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/nb_NO.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/nb_NO.yml
@@ -148,6 +148,11 @@ nb_NO:
LINK_SAVE_TO_DROPBOX: "Lagre i Dropbox"
READ_RECEIPT:
SUBJECT: "Lesebekreftelse (meldinga er lest) - %SUBJECT%"
+ BODY: |
+ Dette er en lesebekreftelse på e-postmeldinga du sendte til %READ-RECEIPT%.
+
+ Merk: Denne bekreftelsen bekrefter bare at meldinga ble åpnet på mottakerens datamaskin,
+ og er ingen garanti for at mottakeren har lest, forstått eller er enig i innholdet.
SUGGESTIONS:
SEARCHING_DESC: "Søker …"
CONTACTS:
@@ -230,6 +235,8 @@ nb_NO:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Lukk"
POPUPS_ASK:
+ BUTTON_YES: "Ja"
+ BUTTON_NO: "Nei"
DESC_WANT_CLOSE_THIS_WINDOW: "Er du sikker på at du vil lukke dette vinduet?"
DESC_WANT_DELETE_MESSAGES: "Er du sikker på at du vil slette meldingen(e)?"
POPUPS_LANGUAGES:
@@ -328,6 +335,8 @@ nb_NO:
SELECT_TYPE_NOT_EQUAL_TO: "Er ikke lik"
SELECT_TYPE_OVER: "Større enn"
SELECT_TYPE_UNDER: "Mindre enn"
+ SELECT_MATCH_ANY: "Samsvarer med én av følgende regler"
+ SELECT_MATCH_ALL: "Samsvarer med alle følgende regler"
MARK_AS_READ_LABEL: "Merk som lest"
REPLY_INTERVAL_LABEL: "Svar-intervall (dager)"
KEEP_LABEL: "Behold"
@@ -352,12 +361,14 @@ nb_NO:
NOTIFICATION_SENT: |
Du har ikke valgt «Sendt» som mappe for sendte meldinger.
Velg «Ikke bruk» hvis du ikke vil lagre sendte meldinger.
+ NOTIFICATION_DRAFTS: "Du har ikke valgt «Kladd» som mappe hvor meldinger lagres mens du skriver."
NOTIFICATION_SPAM: |
Du har ikke valgt «Søppelpost» som mappe for søppelpost.
Velg «Ikke bruk» hvis du vil slette slike meldinger for godt.
NOTIFICATION_TRASH: |
Du har ikke valgt «Papirkurv» som mappe for slettede meldinger.
Velg «Ikke bruk» hvis du vil slette slike meldinger for godt.
+ NOTIFICATION_ARCHIVE: "Du har ikke valgt «Arkiv» som mappe for arkiverte meldinger."
POPUPS_TWO_FACTOR_CFG:
LEGEND_TWO_FACTOR_AUTH: "To-stegsbekreftelse"
LABEL_ENABLE_TWO_FACTOR: "Slå på to-stegsbekreftelse"
@@ -620,6 +631,15 @@ nb_NO:
ACCESS_ERROR: "Tilgangsfeil"
CONNECTION_ERROR: "Klarte ikke å koble til tjeneren"
CAPTCHA_ERROR: "Feil CAPTCHA"
+ SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE: >
+ Denne kontoen er ikke knyttet til en e-postadresse ennå. Logg inn med e-postadresse
+ og passord, og slå på denne funksjonen i kontoinnstillingene.
+ SOCIAL_TWITTER_LOGIN_ACCESS_DISABLE: >
+ Denne kontoen er ikke knyttet til en e-postadresse ennå. Logg inn med e-postadresse
+ og passord, og slå på denne funksjonen i kontoinnstillingene.
+ SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE: >
+ Denne kontoen er ikke knyttet til en e-postadresse ennå. Logg inn med e-postadresse
+ og passord, og slå på denne funksjonen i kontoinnstillingene.
DOMAIN_NOT_ALLOWED: "Dette domenet tillates ikke"
ACCOUNT_NOT_ALLOWED: "Denne kontoen tillates ikke"
ACCOUNT_TWO_FACTOR_AUTH_REQUIRED: "To-stegsbekreftelse kreves"
diff --git a/rainloop/v/0.0.0/app/localization/webmail/nl_NL.yml b/rainloop/v/0.0.0/app/localization/webmail/nl_NL.yml
index 0309f3ae9..ca3b150d8 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/nl_NL.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/nl_NL.yml
@@ -148,6 +148,11 @@ nl_NL:
LINK_SAVE_TO_DROPBOX: "Sla op in Dropbox"
READ_RECEIPT:
SUBJECT: "Ontvangstbevestiging (weergegeven) - %SUBJECT%"
+ BODY: |
+ Dit is een bevestiging dat uw bericht aan %READ-RECEIPT% is ontvangen.
+
+ Let op: Deze ontvangstbevestiging bevestigd slechts dat uw bericht was weergegeven op het scherm van de ontvanger.
+ Er is geen enkele garantie dat uw bericht is gelezen of begrepen.
SUGGESTIONS:
SEARCHING_DESC: "Zoeken..."
CONTACTS:
@@ -230,6 +235,8 @@ nl_NL:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Close"
POPUPS_ASK:
+ BUTTON_YES: "Ja"
+ BUTTON_NO: "Nee"
DESC_WANT_CLOSE_THIS_WINDOW: "Weet u zeker dat u dit venster wilt sluiten?"
DESC_WANT_DELETE_MESSAGES: "Weet u zeker dat u dit/deze bericht/berichten wilt verwijderen?"
POPUPS_LANGUAGES:
@@ -328,6 +335,8 @@ nl_NL:
SELECT_TYPE_NOT_EQUAL_TO: "Niet gelijk aan"
SELECT_TYPE_OVER: "Meer dan"
SELECT_TYPE_UNDER: "Minder dan"
+ SELECT_MATCH_ANY: "Komt overeen met een van de volgende voorwaarden"
+ SELECT_MATCH_ALL: "Komt overeen met alle voorwaarden"
MARK_AS_READ_LABEL: "Markeer als gelezen"
REPLY_INTERVAL_LABEL: "Antwoord interval (dagen)"
KEEP_LABEL: "Behoud"
@@ -352,12 +361,14 @@ nl_NL:
NOTIFICATION_SENT: |
U heeft nog geen "Verzonden items" folder aangeduid waar de berichten geplaatst worden na het versturen.
Indien u geen verzonden berichten wilt bewaren, kies de "Niet gebruiken" optie.
+ NOTIFICATION_DRAFTS: "U heeft nog geen \"Concepten\" folder aangeduid waar de berichten bewaard worden tijdens het opstellen."
NOTIFICATION_SPAM: |
U heeft nog geen "Ongewenste e-mail" folder aangeduid waar de spam berichten geplaatst worden.
Indien u berichten permanent wilt verwijderen, kies de "Niet gebruiken" optie.
NOTIFICATION_TRASH: |
U heeft nog geen "Verwijderde items" folder aangeduid waar de verwijderde berichten geplaatst worden.
Indien u berichten permanent wilt verwijderen, kies de "Niet gebruiken" optie.
+ NOTIFICATION_ARCHIVE: "U heeft nog geen \"Archief\" map aangeduid waar de gearchiveerde berichten geplaatst worden."
POPUPS_TWO_FACTOR_CFG:
LEGEND_TWO_FACTOR_AUTH: "2-Stap verificatie"
LABEL_ENABLE_TWO_FACTOR: "Gebruik 2-Stap verificatie"
@@ -621,6 +632,15 @@ nl_NL:
ACCESS_ERROR: "Toegangsfout"
CONNECTION_ERROR: "Kan geen verbinding maken met de Server"
CAPTCHA_ERROR: "Onjuiste CAPTCHA"
+ SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE: >
+ Deze social ID is nog niet aan een e-mail account gekoppeld. Log in met e-mail
+ adres en wachtwoord en schakel deze functie in in het account instellingen menu.
+ SOCIAL_TWITTER_LOGIN_ACCESS_DISABLE: >
+ Deze social ID is nog niet aan een e-mail account gekoppeld. Log in met e-mail
+ adres en wachtwoord en schakel deze functie in in het account instellingen menu.
+ SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE: >
+ Deze social ID is nog niet aan een e-mail account gekoppeld. Log in met e-mail
+ adres en wachtwoord en schakel deze functie in in het account instellingen menu.
DOMAIN_NOT_ALLOWED: "Domein is niet toegestaan"
ACCOUNT_NOT_ALLOWED: "Account is niet toegestaan"
ACCOUNT_TWO_FACTOR_AUTH_REQUIRED: "2-Stap verificatie vereist"
diff --git a/rainloop/v/0.0.0/app/localization/webmail/pl_PL.yml b/rainloop/v/0.0.0/app/localization/webmail/pl_PL.yml
index aea6d3e81..db5e5910e 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/pl_PL.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/pl_PL.yml
@@ -148,6 +148,11 @@ pl_PL:
LINK_SAVE_TO_DROPBOX: "Zapisz w Dropbox-ie"
READ_RECEIPT:
SUBJECT: "Potwierdzenie wyświetlenia wiadomości o tytule: %SUBJECT%"
+ BODY: |
+ Potwierdzenie wyświetlenia wiadomości wysłanej na adres: %READ-RECEIPT%.
+
+ Uwaga: Otrzymanie tego potwierdzenia jest dowodem na to, że wiadomość została wyświetlona na komputerze odbiorcy.
+ Nie ma jednak żadnej gwarancji, że odbiorca faktycznie zapoznał się z jej treścią.
SUGGESTIONS:
SEARCHING_DESC: "Wyszukiwanie..."
CONTACTS:
@@ -230,6 +235,8 @@ pl_PL:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Zamknij"
POPUPS_ASK:
+ BUTTON_YES: "Tak"
+ BUTTON_NO: "Nie"
DESC_WANT_CLOSE_THIS_WINDOW: "Na pewno zamknąć to okno?"
DESC_WANT_DELETE_MESSAGES: "Na pewno usunąć wiadomość(-i)?"
POPUPS_LANGUAGES:
@@ -328,6 +335,8 @@ pl_PL:
SELECT_TYPE_NOT_EQUAL_TO: "Nie zawiera:"
SELECT_TYPE_OVER: "powyżej"
SELECT_TYPE_UNDER: "poniżej"
+ SELECT_MATCH_ANY: "Spełnia dowolny z warunków"
+ SELECT_MATCH_ALL: "Spełnia wszystkie warunki"
MARK_AS_READ_LABEL: "Oznacz jako przeczytane"
REPLY_INTERVAL_LABEL: "Liczba dni, po których wysłać odp."
KEEP_LABEL: "Zachowaj"
@@ -352,12 +361,14 @@ pl_PL:
NOTIFICATION_SENT: |
Nie wybrano folderu: "Wysłane", do którego przenoszone są wysłane wiadomości.
Jeżeli wysyłane wiadomości nie mają być przechowywane, proszę zaznaczyć opcję: "Nie używaj".
+ NOTIFICATION_DRAFTS: "Nie wybrano folderu: \"Wersje robocze\", do którego są zapisywane wiadomości w trakcie ich tworzenia."
NOTIFICATION_SPAM: |
Nie wybrano folderu: "Niechciane", do którego przenoszone są niepożadane wiadomości.
Jeżeli niechciane wiadomości mają być usuwane na stałe, proszę o zaznaczenie opcji: "Nie używaj".
NOTIFICATION_TRASH: |
Nie wybrano folderu: "Kosz", do którego przenoszone są wszystkie usunięte wiadomości.
Jeżeli wiadomości mają być usuwane na stałe, proszę o zaznaczenie opcji: "Nie używaj".
+ NOTIFICATION_ARCHIVE: "Nie został wybrany folder \"Archiwum\", zostanie użyty systemowy folder archiwizacji wiadomości."
POPUPS_TWO_FACTOR_CFG:
LEGEND_TWO_FACTOR_AUTH: "Dwuskładnikowa autoryzacja"
LABEL_ENABLE_TWO_FACTOR: "Włącz dwuskładnikową autoryzację"
@@ -620,6 +631,18 @@ pl_PL:
ACCESS_ERROR: "Błąd dostępu"
CONNECTION_ERROR: "Błąd połączenia z serwerem"
CAPTCHA_ERROR: "Nieprawidłowy kod CAPTCHA"
+ SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE: >
+ To społecznościowe ID (Facebooku), nie jest powiązane z żadnym kontem pocztowym.
+ Zaloguj się używając danych swojego konta e-mail i skonfiguruj tę opcję w: Ustawienia
+ > Sieci społecznościowe.
+ SOCIAL_TWITTER_LOGIN_ACCESS_DISABLE: >
+ To społecznościowe ID (Twitter), nie jest powiązane z żadnym kontem pocztowym.
+ Zaloguj się używając danych swojego konta e-mail i skonfiguruj tę opcję w: Ustawienia
+ > Sieci społecznościowe.
+ SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE: >
+ To społecznościowe ID (Konto Google), nie jest powiązane z żadnym kontem pocztowym.
+ Zaloguj się używając danych swojego konta e-mail i skonfiguruj tę opcję w: Ustawienia
+ > Sieci społecznościowe.
DOMAIN_NOT_ALLOWED: "Domena niedozwolona"
ACCOUNT_NOT_ALLOWED: "Konto nie jest dozwolone"
ACCOUNT_TWO_FACTOR_AUTH_REQUIRED: "Wymagana dwuskładnikowa autoryzacja"
diff --git a/rainloop/v/0.0.0/app/localization/webmail/pt_BR.yml b/rainloop/v/0.0.0/app/localization/webmail/pt_BR.yml
index 06ea7fa21..fddc007de 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/pt_BR.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/pt_BR.yml
@@ -148,6 +148,11 @@ pt_BR:
LINK_SAVE_TO_DROPBOX: "Salvar no Dropbox"
READ_RECEIPT:
SUBJECT: "Aviso de recepção (Visualizada) - %SUBJECT%"
+ BODY: |
+ Comprovante de retorno para o e-mail que você enviou para %READ-RECEIPT%.
+
+ Nota: Este comprovante de retorno apenas reconhece que a mensagem foi exibida no computador do destinatário.
+ Não há garantia de que o destinatário tenha lido ou compreendido o conteúdo da mensagem.
SUGGESTIONS:
SEARCHING_DESC: "Procurando..."
CONTACTS:
@@ -230,6 +235,8 @@ pt_BR:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Fechar"
POPUPS_ASK:
+ BUTTON_YES: "Sim"
+ BUTTON_NO: "Não"
DESC_WANT_CLOSE_THIS_WINDOW: "Você tem certeza que deseja fechar esta janela?"
DESC_WANT_DELETE_MESSAGES: "Você tem certeza de que deseja excluir essa(s) mensagem(s)?"
POPUPS_LANGUAGES:
@@ -328,6 +335,8 @@ pt_BR:
SELECT_TYPE_NOT_EQUAL_TO: "Não é igual à"
SELECT_TYPE_OVER: "Maior que"
SELECT_TYPE_UNDER: "Menor que"
+ SELECT_MATCH_ANY: "Corresponde à qualquer regra seguinte"
+ SELECT_MATCH_ALL: "Corresponde à todas as regras seguintes"
MARK_AS_READ_LABEL: "Marcar como Lida"
REPLY_INTERVAL_LABEL: "Responder intervalo (dias)"
KEEP_LABEL: "Manter"
@@ -352,12 +361,14 @@ pt_BR:
NOTIFICATION_SENT: |
Você não selecionou a pasta "Enviadas" do sistema que será colocada as mensagens após o envio.
Se você não quiser salvar a mensagem enviada, por favor selecione a opção"Não usar".
+ NOTIFICATION_DRAFTS: "Você não selecionou a pasta \"Rascunhos\" do sistema que será colocada as mensagens salvas durante a composição."
NOTIFICATION_SPAM: |
Você não selecionou a pasta "Lixo Eletrônico" do sistema que será colocada as mensagens spams.
Se você deseja remover a mensagem permanentemente, por favor selecione a opção"Não usar".
NOTIFICATION_TRASH: |
Você não selecionou a pasta do sistema que serão colocadas as mensagens excluídas.
Se você deseja remover a mensagem permanentemente, por favor selecione a opção"Não usar".
+ NOTIFICATION_ARCHIVE: "Você não selecionou a pasta \"Arquivadas\" do sistema que serão colocadas as mensagens arquivadas."
POPUPS_TWO_FACTOR_CFG:
LEGEND_TWO_FACTOR_AUTH: "Verificação de duas etapas"
LABEL_ENABLE_TWO_FACTOR: "Habilitar verificação de duas etapas"
@@ -621,6 +632,18 @@ pt_BR:
ACCESS_ERROR: "Erro ao acessar"
CONNECTION_ERROR: "Não foi possível conectar-se ao servidor"
CAPTCHA_ERROR: "Verificação CAPTCHA incorreta."
+ SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE: >
+ Esta ID social não é atribuído para qualquer conta de e-mail ainda. Entre usando
+ suas credenciais de e-mail e ative o recursso de logar pelo Facebook em configurações
+ de conta.
+ SOCIAL_TWITTER_LOGIN_ACCESS_DISABLE: >
+ Esta ID social não é atribuído para qualquer conta de e-mail ainda. Entre usando
+ suas credenciais de e-mail e ative o recursso de logar pelo Twitter em configurações
+ de conta.
+ SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE: >
+ Esta ID social não é atribuído para qualquer conta de e-mail ainda. Entre usando
+ suas credenciais de e-mail e ative o recursso de logar pelo Google em configurações
+ de conta.
DOMAIN_NOT_ALLOWED: "Este domínio não é permitido"
ACCOUNT_NOT_ALLOWED: "Conta não permitida"
ACCOUNT_TWO_FACTOR_AUTH_REQUIRED: "Verificação de duas etapas requerida"
diff --git a/rainloop/v/0.0.0/app/localization/webmail/pt_PT.yml b/rainloop/v/0.0.0/app/localization/webmail/pt_PT.yml
index 4dde93aa6..ac47984f4 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/pt_PT.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/pt_PT.yml
@@ -235,6 +235,8 @@ pt_PT:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Close"
POPUPS_ASK:
+ BUTTON_YES: "Sim"
+ BUTTON_NO: "Não"
DESC_WANT_CLOSE_THIS_WINDOW: "Tem a certeza que deseja fechar esta janela?"
DESC_WANT_DELETE_MESSAGES: "Tem a certeza de que deseja eliminar esta(s) mensagem(s)?"
POPUPS_LANGUAGES:
diff --git a/rainloop/v/0.0.0/app/localization/webmail/ro_RO.yml b/rainloop/v/0.0.0/app/localization/webmail/ro_RO.yml
index b1b3e46d6..2b3b5e4bd 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/ro_RO.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/ro_RO.yml
@@ -234,6 +234,8 @@ ro_RO:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Close"
POPUPS_ASK:
+ BUTTON_YES: "Da"
+ BUTTON_NO: "Nu"
DESC_WANT_CLOSE_THIS_WINDOW: "Sigur doriți să închideți această fereastră?"
DESC_WANT_DELETE_MESSAGES: "Sigur doriți să ștergeți mesajul(e)?"
POPUPS_LANGUAGES:
diff --git a/rainloop/v/0.0.0/app/localization/webmail/ru_RU.yml b/rainloop/v/0.0.0/app/localization/webmail/ru_RU.yml
index bb4e82e87..4178d27a0 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/ru_RU.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/ru_RU.yml
@@ -148,6 +148,11 @@ ru_RU:
LINK_SAVE_TO_DROPBOX: "Сохранить в Dropbox"
READ_RECEIPT:
SUBJECT: "Уведомление о прочтении письма - %SUBJECT%"
+ BODY: |
+ Это уведомление о прочтении для сообщения, которое вы отправили в адрес %READ-RECEIPT%.
+
+ Примечание: Это уведомление о прочтении означает лишь то, что сообщение было отображено на машине получателя.
+ Оно не гарантирует того, что получатель прочёл или понял содержимое сообщения.
SUGGESTIONS:
SEARCHING_DESC: "Поиск..."
CONTACTS:
@@ -230,6 +235,8 @@ ru_RU:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Close"
POPUPS_ASK:
+ BUTTON_YES: "Да"
+ BUTTON_NO: "Нет"
DESC_WANT_CLOSE_THIS_WINDOW: "Вы уверены, что хотите закрыть это окно?"
DESC_WANT_DELETE_MESSAGES: "Вы уверены, что хотите удалить сообщение(я)?"
POPUPS_LANGUAGES:
@@ -328,6 +335,8 @@ ru_RU:
SELECT_TYPE_NOT_EQUAL_TO: "Не совпадает с"
SELECT_TYPE_OVER: "Over"
SELECT_TYPE_UNDER: "Under"
+ SELECT_MATCH_ANY: "Подходит под хотя бы одно из нижеперечисленных правил"
+ SELECT_MATCH_ALL: "Подходит под все нижеперечисленные правила"
MARK_AS_READ_LABEL: "Отметить как прочитанное"
REPLY_INTERVAL_LABEL: "Отвечать каждые (в днях)"
KEEP_LABEL: "Сохранить копию"
@@ -352,12 +361,14 @@ ru_RU:
NOTIFICATION_SENT: |
Вы еще не выбрали системную папку "Отправленные", в которую складываются все сообщения после отправки.
Если вы не хотите сохранять отправленные письма, пожалуйста, выберите пункт "Не использовать".
+ NOTIFICATION_DRAFTS: "Вы еще не выбрали системную папку \"Черновики\", в которую складываются все сохраненные сообщения."
NOTIFICATION_SPAM: |
Вы еще не выбрали системную папку "Спам", в которую складываются все спамовые сообщения.
Если же вы хотите удалять письма сразу, пожалуйста, выберите пункт "Не использовать".
NOTIFICATION_TRASH: |
Вы еще не выбрали системную папку "Удаленные", в которую складываются все сообщения после удаления.
Если же вы хотите удалять письма сразу, пожалуйста, выберите пункт "Не использовать".
+ NOTIFICATION_ARCHIVE: "Вы еще не выбрали системную папку \"Архив\", в которую складываются все сообщения после архивации."
POPUPS_TWO_FACTOR_CFG:
LEGEND_TWO_FACTOR_AUTH: "Двухфакторная верификация"
LABEL_ENABLE_TWO_FACTOR: "Включить двухфакторную верификацию"
@@ -621,6 +632,15 @@ ru_RU:
ACCESS_ERROR: "Ошибка доступа"
CONNECTION_ERROR: "Ошибка соединения с сервером."
CAPTCHA_ERROR: "Неправильное проверочное слово."
+ SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE: >
+ К данному социальному пользователю еще не прикреплен почтовый аккаунт. Войдите
+ в систему под своим почтовым аккаунтом и включите эту возможность в настройках.
+ SOCIAL_TWITTER_LOGIN_ACCESS_DISABLE: >
+ К данному социальному пользователю еще не прикреплен почтовый аккаунт. Войдите
+ в систему под своим почтовым аккаунтом и включите эту возможность в настройках.
+ SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE: >
+ К данному социальному пользователю еще не прикреплен почтовый аккаунт. Войдите
+ в систему под своим почтовым аккаунтом и включите эту возможность в настройках.
DOMAIN_NOT_ALLOWED: "Данный домен не разрешен"
ACCOUNT_NOT_ALLOWED: "Данный аккаунт не разрешен"
ACCOUNT_TWO_FACTOR_AUTH_REQUIRED: "Необходима двухфакторная верификация"
@@ -660,6 +680,7 @@ ru_RU:
DEMO_SEND_MESSAGE_ERROR: "Демо аккаунту отправка писем на внешние почтовые адреса запрещена!"
DEMO_ACCOUNT_ERROR: "По соображениям безопасности данный аккаунт не может выполнить это действие."
ACCOUNT_ALREADY_EXISTS: "Аккаунт уже добавлен"
+ ACCOUNT_DOES_NOT_EXIST: "Аккаунт не существует"
MAIL_SERVER_ERROR: "Ошибка доступа к почтовому серверу"
INVALID_INPUT_ARGUMENT: "Неверный параметр"
UNKNOWN_ERROR: "Неизвестная ошибка"
diff --git a/rainloop/v/0.0.0/app/localization/webmail/sk_SK.yml b/rainloop/v/0.0.0/app/localization/webmail/sk_SK.yml
index 85f5ebdad..950a19d31 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/sk_SK.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/sk_SK.yml
@@ -235,6 +235,8 @@ sk_SK:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Close"
POPUPS_ASK:
+ BUTTON_YES: "Áno"
+ BUTTON_NO: "Nie"
DESC_WANT_CLOSE_THIS_WINDOW: "Ste si istý že chcete zatvoriť toto okno?"
DESC_WANT_DELETE_MESSAGES: "Ste si istý že chcete odstrániť tieto správy?"
POPUPS_LANGUAGES:
diff --git a/rainloop/v/0.0.0/app/localization/webmail/sv_SE.yml b/rainloop/v/0.0.0/app/localization/webmail/sv_SE.yml
index 1af5bd01e..63dff1629 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/sv_SE.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/sv_SE.yml
@@ -235,6 +235,8 @@ sv_SE:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Close"
POPUPS_ASK:
+ BUTTON_YES: "Ja"
+ BUTTON_NO: "Nej"
DESC_WANT_CLOSE_THIS_WINDOW: "Vill du stänga detta fönster?"
DESC_WANT_DELETE_MESSAGES: "Är du säker att du vill ta bort meddelandet?"
POPUPS_LANGUAGES:
diff --git a/rainloop/v/0.0.0/app/localization/webmail/tr_TR.yml b/rainloop/v/0.0.0/app/localization/webmail/tr_TR.yml
index 8e6e88843..cd4e60063 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/tr_TR.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/tr_TR.yml
@@ -235,6 +235,8 @@ tr_TR:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Close"
POPUPS_ASK:
+ BUTTON_YES: "Evet"
+ BUTTON_NO: "Hayır"
DESC_WANT_CLOSE_THIS_WINDOW: "Bu pencereyi kapatmak istediğinizden emin misiniz?"
DESC_WANT_DELETE_MESSAGES: "Mesaj(ları) silmek istediğinizden emin misiniz?"
POPUPS_LANGUAGES:
diff --git a/rainloop/v/0.0.0/app/localization/webmail/uk_UA.yml b/rainloop/v/0.0.0/app/localization/webmail/uk_UA.yml
index c583f3b26..ab14ea2eb 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/uk_UA.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/uk_UA.yml
@@ -148,6 +148,11 @@ uk_UA:
LINK_SAVE_TO_DROPBOX: "Зберегти в Dropbox"
READ_RECEIPT:
SUBJECT: "Сповіщення про прочитання цього повідомлення - %SUBJECT%"
+ BODY: |
+ Це сповіщення про прочитання для повідомлення, яке ви надіслали в адресу %READ-RECEIPT%.
+
+ Примітка: Це сповіщення про прочитання означає лише, що повідомлення було відображено на машину отримувача.
+ Воно не гарантує, що отримувач прочитав чи зрозумів зміст повідомлення.
SUGGESTIONS:
SEARCHING_DESC: "Пошук..."
CONTACTS:
@@ -230,6 +235,8 @@ uk_UA:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Закрити"
POPUPS_ASK:
+ BUTTON_YES: "Так"
+ BUTTON_NO: "Ні"
DESC_WANT_CLOSE_THIS_WINDOW: "Ви впевнені, що хочете закрити це вікно?"
DESC_WANT_DELETE_MESSAGES: "Ви впевнені, що хочете видалити повідомлення?"
POPUPS_LANGUAGES:
@@ -328,6 +335,8 @@ uk_UA:
SELECT_TYPE_NOT_EQUAL_TO: "Не дорівнює"
SELECT_TYPE_OVER: "Over"
SELECT_TYPE_UNDER: "Under"
+ SELECT_MATCH_ANY: "Matching any of the following rules"
+ SELECT_MATCH_ALL: "Matching all of the following rules"
MARK_AS_READ_LABEL: "Mark as read"
REPLY_INTERVAL_LABEL: "Reply interval (days)"
KEEP_LABEL: "Keep"
@@ -352,12 +361,14 @@ uk_UA:
NOTIFICATION_SENT: |
Ви ще не обрали системну теку "Вихідні", в яку складаються всі повідомлення післе надсилання.
Якщо ви не хочете зберігати вихідні листи, будь ласка, виберіть пункт "Не використовувати".
+ NOTIFICATION_DRAFTS: "Ви ще не обрали системну теку \"Чорновики\", в яку складаються всі збережені повідомлення."
NOTIFICATION_SPAM: |
Ви ще не обрали системну теку "Спам", в яку складаються всі спам повідомлення.
Якщо ви не хочете видаляти листи одразу, будь ласка, виберіть пункт "Не використовувати".
NOTIFICATION_TRASH: |
Ви ще не обрали системну теку "Удаленные", в яку складаються всі повідомлення після видалення.
Якщо ви не хочете видаляти листи одразу, будь ласка, виберіть пункт "Не використовувати".
+ NOTIFICATION_ARCHIVE: "Ви ще не обрали системну теку \"Архив\", в яку складаються всі повідомлення після архівації."
POPUPS_TWO_FACTOR_CFG:
LEGEND_TWO_FACTOR_AUTH: "Двофакторна верификація"
LABEL_ENABLE_TWO_FACTOR: "Увімкнути двофакторну верифікацію"
@@ -621,6 +632,15 @@ uk_UA:
ACCESS_ERROR: "Помилка доступу"
CONNECTION_ERROR: "Помилка з'єднання з сервером."
CAPTCHA_ERROR: "Неправильне перевірочне слово."
+ SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE: >
+ До даного соціального користувача ще не прикріплений поштовий акаунт. Увійдіть
+ у систему під своїм поштовим акаунтом і включіть цю можливість у налаштуваннях.
+ SOCIAL_TWITTER_LOGIN_ACCESS_DISABLE: >
+ До даного соціального користувача ще не прикріплений поштовий акаунт. Увійдіть
+ у систему під своїм поштовим акаунтом і включіть цю можливість у налаштуваннях.
+ SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE: >
+ До даного соціального користувача ще не прикріплений поштовий акаунт. Увійдіть
+ у систему під своїм поштовим акаунтом і включіть цю можливість у налаштуваннях.
DOMAIN_NOT_ALLOWED: "Цей домен заборонений"
ACCOUNT_NOT_ALLOWED: "Цей акаунт заборонений"
ACCOUNT_TWO_FACTOR_AUTH_REQUIRED: "Необхідна двофакторна верификація"
diff --git a/rainloop/v/0.0.0/app/localization/webmail/zh_CN.yml b/rainloop/v/0.0.0/app/localization/webmail/zh_CN.yml
index 283d2e734..551734a43 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/zh_CN.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/zh_CN.yml
@@ -235,6 +235,8 @@ zh_CN:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Close"
POPUPS_ASK:
+ BUTTON_YES: "是"
+ BUTTON_NO: "否"
DESC_WANT_CLOSE_THIS_WINDOW: "你确定要关闭此窗口吗?"
DESC_WANT_DELETE_MESSAGES: "你确定你要删除这条消息吗?"
POPUPS_LANGUAGES:
diff --git a/rainloop/v/0.0.0/app/localization/webmail/zh_TW.yml b/rainloop/v/0.0.0/app/localization/webmail/zh_TW.yml
index ad927ba15..c26904c4d 100644
--- a/rainloop/v/0.0.0/app/localization/webmail/zh_TW.yml
+++ b/rainloop/v/0.0.0/app/localization/webmail/zh_TW.yml
@@ -235,6 +235,8 @@ zh_TW:
POPUPS_WELCOME_PAGE:
BUTTON_CLOSE: "Close"
POPUPS_ASK:
+ BUTTON_YES: "是"
+ BUTTON_NO: "否"
DESC_WANT_CLOSE_THIS_WINDOW: "你確定要關閉此窗口嗎?"
DESC_WANT_DELETE_MESSAGES: "你確定你要刪除這條消息嗎?"
POPUPS_LANGUAGES:
diff --git a/vendors/progress.js/minified/progress.min.js b/vendors/progress.js/minified/progress.min.js
index f7c5b41be..8b60282c8 100644
--- a/vendors/progress.js/minified/progress.min.js
+++ b/vendors/progress.js/minified/progress.min.js
@@ -1,5 +1,5 @@
(function(l,e){"object"===typeof exports?e(exports):"function"===typeof define&&define.amd?define(["exports"],e):e(l)})(this,function(l){function e(a){this._targetElement="undefined"!=typeof a.length?a:[a];"undefined"===typeof window._progressjsId&&(window._progressjsId=1);"undefined"===typeof window._progressjsIntervals&&(window._progressjsIntervals={});this._options={theme:"blue",overlayMode:!1,considerTransition:!0}}function m(a,c){var d=this;100<=c&&(c=100);a.hasAttribute("data-progressjs")&&
-setTimeout(function(){"undefined"!=typeof d._onProgressCallback&&d._onProgressCallback.call(d,a,c);var b=h(a);b.style.width=parseInt(c)+"%";var b=b.querySelector(".progressjs-percent"),g=parseInt(b.innerHTML.replace("%","")),e=parseInt(c),j=function(a,b,c){var d=Math.abs(b-c);3>d?k=30:20>d?k=20:intervanIn=1;0!=b-c&&(a.innerHTML=(f?++b:--b)+"%",setTimeout(function(){j(a,b,c)},k))},f=!0;g>e&&(f=!1);var k=10;j(b,g,e)},50)}function h(a){a=parseInt(a.getAttribute("data-progressjs"));return document.querySelector('.progressjs-container > .progressjs-progress[data-progressjs="'+
+setTimeout(function(){"undefined"!=typeof d._onProgressCallback&&d._onProgressCallback.call(d,a,c);var b=h(a);if (b){b.style.width=parseInt(c)+"%";}var b=b?b.querySelector(".progressjs-percent"):null,g=b?parseInt(b.innerHTML.replace("%","")):0,e=parseInt(c),j=function(a,b,c){var d=Math.abs(b-c);3>d?k=30:20>d?k=20:intervanIn=1;0!=b-c&&(setTimeout(function(){j(a,b,c)},k))},f=!0;g>e&&(f=!1);var k=10;j(b,g,e)},50)}function h(a){a=parseInt(a.getAttribute("data-progressjs"));return document.querySelector('.progressjs-container > .progressjs-progress[data-progressjs="'+
a+'"] > .progressjs-inner')}function p(a){for(var c=0,d=this._targetElement.length;c