Code refactoring (es5 -> es2015)

This commit is contained in:
RainLoop Team 2016-07-07 00:03:30 +03:00
parent fb2e492ce8
commit 38a1041a73
42 changed files with 3081 additions and 3690 deletions

View file

@ -46,11 +46,11 @@ import {checkTimestamp} from 'Storage/RainLoop';
import Remote from 'Remote/User/Ajax';
import Promises from 'Promises/User/Ajax';
import EmailModel from 'Model/Email';
import AccountModel from 'Model/Account';
import IdentityModel from 'Model/Identity';
import TemplateModel from 'Model/Template';
import OpenPgpKeyModel from 'Model/OpenPgpKey';
import {EmailModel} from 'Model/Email';
import {AccountModel} from 'Model/Account';
import {IdentityModel} from 'Model/Identity';
import {TemplateModel} from 'Model/Template';
import {OpenPgpKeyModel} from 'Model/OpenPgpKey';
import kn from 'Knoin/Knoin';

View file

@ -1593,7 +1593,7 @@ export function mailToHelper(mailToUrl, PopupComposeVoreModel)
const
email = mailToUrl.replace(/\?.+$/, ''),
query = mailToUrl.replace(/^[^\?]*\?/, ''),
EmailModel = require('Model/Email'),
EmailModel = require('Model/Email').default,
emailObj = new EmailModel(),
fParseEmailLine = (line) => (line ? _.compact(_.map(decodeURIComponent(line).split(/[,]/), (item) => {
emailObj.clear();

2
dev/External/ko.js vendored
View file

@ -838,7 +838,7 @@ ko.bindingHandlers.emailsTags = {
var
Utils = require('Common/Utils'),
EmailModel = require('Model/Email'),
EmailModel = require('Model/Email').default,
$oEl = $(oElement),
fValue = fValueAccessor(),

View file

@ -1,100 +1,95 @@
import {isNonEmptyArray, isUnd} from 'Common/Utils';
import EmailModel from 'Model/Email';
import {EmailModel} from 'Model/Email';
class MessageHelper
{
/**
* @param {Array.<EmailModel>} emails
* @param {boolean=} friendlyView = false
* @param {boolean=} wrapWithLink = false
* @returns {string}
*/
emailArrayToString(emails, friendlyView = false, wrapWithLink = false) {
/**
* @param {Array.<EmailModel>} emails
* @param {boolean=} friendlyView = false
* @param {boolean=} wrapWithLink = false
* @returns {string}
*/
export function emailArrayToString(emails, friendlyView = false, wrapWithLink = false) {
let index = 0, len = 0;
const result = [];
let index = 0, len = 0;
const result = [];
if (isNonEmptyArray(emails))
if (isNonEmptyArray(emails))
{
for (len = emails.length; index < len; index++)
{
for (len = emails.length; index < len; index++)
{
result.push(emails[index].toLine(friendlyView, wrapWithLink));
}
result.push(emails[index].toLine(friendlyView, wrapWithLink));
}
return result.join(', ');
}
/**
* @param {Array.<EmailModel>} emails
* @returns {string}
*/
emailArrayToStringClear(emails) {
return result.join(', ');
}
let index = 0, len = 0;
const result = [];
/**
* @param {Array.<EmailModel>} emails
* @returns {string}
*/
export function emailArrayToStringClear(emails) {
if (isNonEmptyArray(emails))
let index = 0, len = 0;
const result = [];
if (isNonEmptyArray(emails))
{
for (len = emails.length; index < len; index++)
{
for (len = emails.length; index < len; index++)
if (emails[index] && emails[index].email && '' !== emails[index].name)
{
if (emails[index] && emails[index].email && '' !== emails[index].name)
{
result.push(emails[index].email);
}
result.push(emails[index].email);
}
}
return result.join(', ');
}
/**
* @param {?Array} json
* @returns {Array.<EmailModel>}
*/
emailArrayFromJson(json) {
return result.join(', ');
}
let index = 0, len = 0, email = null;
const result = [];
/**
* @param {?Array} json
* @returns {Array.<EmailModel>}
*/
export function emailArrayFromJson(json) {
if (isNonEmptyArray(json))
let index = 0, len = 0, email = null;
const result = [];
if (isNonEmptyArray(json))
{
for (index = 0, len = json.length; index < len; index++)
{
for (index = 0, len = json.length; index < len; index++)
email = EmailModel.newInstanceFromJson(json[index]);
if (email)
{
email = EmailModel.newInstanceFromJson(json[index]);
if (email)
{
result.push(email);
}
result.push(email);
}
}
return result;
}
/**
* @param {Array.<EmailModel>} inputEmails
* @param {Object} unic
* @param {Array} localEmails
*/
replyHelper(inputEmails, unic, localEmails) {
return result;
}
if (inputEmails && 0 < inputEmails.length)
/**
* @param {Array.<EmailModel>} inputEmails
* @param {Object} unic
* @param {Array} localEmails
*/
export function replyHelper(inputEmails, unic, localEmails) {
if (inputEmails && 0 < inputEmails.length)
{
let index = 0;
const len = inputEmails.length;
for (; index < len; index++)
{
let index = 0;
const len = inputEmails.length;
for (; index < len; index++)
if (isUnd(unic[inputEmails[index].email]))
{
if (isUnd(unic[inputEmails[index].email]))
{
unic[inputEmails[index].email] = true;
localEmails.push(inputEmails[index]);
}
unic[inputEmails[index].email] = true;
localEmails.push(inputEmails[index]);
}
}
}
}
export default new MessageHelper();

View file

@ -1,41 +0,0 @@
var
_ = require('_'),
Utils = require('Common/Utils');
/**
* @constructor
*
* @param {string} sModelName
*/
function AbstractModel(sModelName)
{
this.sModelName = sModelName || '';
this.disposables = [];
}
/**
* @param {Array|Object} mInputValue
*/
AbstractModel.prototype.regDisposables = function(mInputValue)
{
if (Utils.isArray(mInputValue))
{
_.each(mInputValue, function(mValue) {
this.disposables.push(mValue);
}, this);
}
else if (mInputValue)
{
this.disposables.push(mInputValue);
}
};
AbstractModel.prototype.onDestroy = function()
{
Utils.disposeObject(this);
};
module.exports = AbstractModel;

View file

@ -0,0 +1,34 @@
import _ from '_';
import {isArray, disposeObject} from 'Common/Utils';
class AbstractModel
{
/**
* @param {string} modelName
*/
constructor(modelName)
{
this.sModelName = modelName || '';
this.disposables = [];
}
regDisposables(value) {
if (isArray(value))
{
_.each(value, (item) => {
this.disposables.push(item);
});
}
else if (value)
{
this.disposables.push(value);
}
}
onDestroy() {
disposeObject(this);
}
}
export {AbstractModel, AbstractModel as default};

View file

@ -1,45 +0,0 @@
var
_ = require('_'),
ko = require('ko'),
Utils = require('Common/Utils'),
AbstractModel = require('Knoin/AbstractModel');
/**
* @constructor
*
* @param {string} sEmail
* @param {boolean=} bCanBeDelete = true
* @param {number=} iCount = 0
*/
function AccountModel(sEmail, bCanBeDelete, iCount)
{
AbstractModel.call(this, 'AccountModel');
this.email = sEmail;
this.count = ko.observable(iCount || 0);
this.deleteAccess = ko.observable(false);
this.canBeDeleted = ko.observable(Utils.isUnd(bCanBeDelete) ? true : !!bCanBeDelete);
this.canBeEdit = this.canBeDeleted;
}
_.extend(AccountModel.prototype, AbstractModel.prototype);
/**
* @type {string}
*/
AccountModel.prototype.email = '';
/**
* @returns {string}
*/
AccountModel.prototype.changeAccountLink = function()
{
return require('Common/Links').change(this.email);
};
module.exports = AccountModel;

36
dev/Model/Account.jsx Normal file
View file

@ -0,0 +1,36 @@
import ko from 'ko';
import {change} from 'Common/Links';
import {AbstractModel} from 'Knoin/AbstractModel';
class AccountModel extends AbstractModel
{
/**
* @param {string} email
* @param {boolean=} canBeDelete = true
* @param {number=} count = 0
*/
constructor(email, canBeDelete = true, count = 0)
{
super('AccountModel');
this.email = email;
this.count = ko.observable(count);
this.deleteAccess = ko.observable(false);
this.canBeDeleted = ko.observable(!!canBeDelete);
this.canBeEdit = this.canBeDeleted;
}
/**
* @returns {string}
*/
changeAccountLink() {
return change(this.email);
}
}
export {AccountModel, AccountModel as default};

View file

@ -1,545 +0,0 @@
var
window = require('window'),
_ = require('_'),
ko = require('ko'),
Enums = require('Common/Enums'),
Globals = require('Common/Globals'),
Utils = require('Common/Utils'),
Links = require('Common/Links'),
Audio = require('Common/Audio'),
AbstractModel = require('Knoin/AbstractModel');
/**
* @constructor
*/
function AttachmentModel()
{
AbstractModel.call(this, 'AttachmentModel');
this.checked = ko.observable(false);
this.mimeType = '';
this.fileName = '';
this.fileNameExt = '';
this.fileType = Enums.FileType.Unknown;
this.estimatedSize = 0;
this.friendlySize = '';
this.isInline = false;
this.isLinked = false;
this.isThumbnail = false;
this.cid = '';
this.cidWithOutTags = '';
this.contentLocation = '';
this.download = '';
this.folder = '';
this.uid = '';
this.mimeIndex = '';
this.framed = false;
}
_.extend(AttachmentModel.prototype, AbstractModel.prototype);
/**
* @static
* @param {AjaxJsonAttachment} oJsonAttachment
* @returns {?AttachmentModel}
*/
AttachmentModel.newInstanceFromJson = function(oJsonAttachment)
{
var oAttachmentModel = new AttachmentModel();
return oAttachmentModel.initByJson(oJsonAttachment) ? oAttachmentModel : null;
};
AttachmentModel.prototype.mimeType = '';
AttachmentModel.prototype.fileName = '';
AttachmentModel.prototype.fileType = '';
AttachmentModel.prototype.fileNameExt = '';
AttachmentModel.prototype.estimatedSize = 0;
AttachmentModel.prototype.friendlySize = '';
AttachmentModel.prototype.isInline = false;
AttachmentModel.prototype.isLinked = false;
AttachmentModel.prototype.isThumbnail = false;
AttachmentModel.prototype.cid = '';
AttachmentModel.prototype.cidWithOutTags = '';
AttachmentModel.prototype.contentLocation = '';
AttachmentModel.prototype.download = '';
AttachmentModel.prototype.folder = '';
AttachmentModel.prototype.uid = '';
AttachmentModel.prototype.mimeIndex = '';
AttachmentModel.prototype.framed = false;
/**
* @param {AjaxJsonAttachment} oJsonAttachment
*/
AttachmentModel.prototype.initByJson = function(oJsonAttachment)
{
var bResult = false;
if (oJsonAttachment && 'Object/Attachment' === oJsonAttachment['@Object'])
{
this.mimeType = Utils.trim((oJsonAttachment.MimeType || '').toLowerCase());
this.fileName = Utils.trim(oJsonAttachment.FileName);
this.estimatedSize = Utils.pInt(oJsonAttachment.EstimatedSize);
this.isInline = !!oJsonAttachment.IsInline;
this.isLinked = !!oJsonAttachment.IsLinked;
this.isThumbnail = !!oJsonAttachment.IsThumbnail;
this.cid = oJsonAttachment.CID;
this.contentLocation = oJsonAttachment.ContentLocation;
this.download = oJsonAttachment.Download;
this.folder = oJsonAttachment.Folder;
this.uid = oJsonAttachment.Uid;
this.mimeIndex = oJsonAttachment.MimeIndex;
this.framed = !!oJsonAttachment.Framed;
this.friendlySize = Utils.friendlySize(this.estimatedSize);
this.cidWithOutTags = this.cid.replace(/^<+/, '').replace(/>+$/, '');
this.fileNameExt = Utils.getFileExtension(this.fileName);
this.fileType = AttachmentModel.staticFileType(this.fileNameExt, this.mimeType);
bResult = true;
}
return bResult;
};
/**
* @returns {boolean}
*/
AttachmentModel.prototype.isImage = function()
{
return Enums.FileType.Image === this.fileType;
};
/**
* @returns {boolean}
*/
AttachmentModel.prototype.isMp3 = function()
{
return Enums.FileType.Audio === this.fileType &&
'mp3' === this.fileNameExt;
};
/**
* @returns {boolean}
*/
AttachmentModel.prototype.isOgg = function()
{
return Enums.FileType.Audio === this.fileType &&
('oga' === this.fileNameExt || 'ogg' === this.fileNameExt);
};
/**
* @returns {boolean}
*/
AttachmentModel.prototype.isWav = function()
{
return Enums.FileType.Audio === this.fileType &&
'wav' === this.fileNameExt;
};
/**
* @returns {boolean}
*/
AttachmentModel.prototype.hasThumbnail = function()
{
return this.isThumbnail;
};
/**
* @returns {boolean}
*/
AttachmentModel.prototype.isText = function()
{
return Enums.FileType.Text === this.fileType ||
Enums.FileType.Eml === this.fileType ||
Enums.FileType.Certificate === this.fileType ||
Enums.FileType.Html === this.fileType ||
Enums.FileType.Code === this.fileType;
};
/**
* @returns {boolean}
*/
AttachmentModel.prototype.isPdf = function()
{
return Enums.FileType.Pdf === this.fileType;
};
/**
* @returns {boolean}
*/
AttachmentModel.prototype.isFramed = function()
{
return this.framed && (Globals.data.__APP__ && Globals.data.__APP__.googlePreviewSupported()) &&
!(this.isPdf() && Globals.bAllowPdfPreview) && !this.isText() && !this.isImage();
};
/**
* @returns {boolean}
*/
AttachmentModel.prototype.hasPreview = function()
{
return this.isImage() || (this.isPdf() && Globals.bAllowPdfPreview) ||
this.isText() || this.isFramed();
};
/**
* @returns {boolean}
*/
AttachmentModel.prototype.hasPreplay = function()
{
return (Audio.supportedMp3 && this.isMp3()) ||
(Audio.supportedOgg && this.isOgg()) ||
(Audio.supportedWav && this.isWav());
};
/**
* @returns {string}
*/
AttachmentModel.prototype.linkDownload = function()
{
return Links.attachmentDownload(this.download);
};
/**
* @returns {string}
*/
AttachmentModel.prototype.linkPreview = function()
{
return Links.attachmentPreview(this.download);
};
/**
* @returns {string}
*/
AttachmentModel.prototype.linkThumbnail = function()
{
return this.hasThumbnail() ? Links.attachmentThumbnailPreview(this.download) : '';
};
/**
* @returns {string}
*/
AttachmentModel.prototype.linkThumbnailPreviewStyle = function()
{
var sLink = this.linkThumbnail();
return '' === sLink ? '' : 'background:url(' + sLink + ')';
};
/**
* @returns {string}
*/
AttachmentModel.prototype.linkFramed = function()
{
return Links.attachmentFramed(this.download);
};
/**
* @returns {string}
*/
AttachmentModel.prototype.linkPreviewAsPlain = function()
{
return Links.attachmentPreviewAsPlain(this.download);
};
/**
* @returns {string}
*/
AttachmentModel.prototype.linkPreviewMain = function()
{
var sResult = '';
switch (true)
{
case this.isImage():
case this.isPdf() && Globals.bAllowPdfPreview:
sResult = this.linkPreview();
break;
case this.isText():
sResult = this.linkPreviewAsPlain();
break;
case this.isFramed():
sResult = this.linkFramed();
break;
// no default
}
return sResult;
};
/**
* @returns {string}
*/
AttachmentModel.prototype.generateTransferDownloadUrl = function()
{
var sLink = this.linkDownload();
if ('http' !== sLink.substr(0, 4))
{
sLink = window.location.protocol + '//' + window.location.host + window.location.pathname + sLink;
}
return this.mimeType + ':' + this.fileName + ':' + sLink;
};
/**
* @param {AttachmentModel} oAttachment
* @param {*} oEvent
* @returns {boolean}
*/
AttachmentModel.prototype.eventDragStart = function(oAttachment, oEvent)
{
var oLocalEvent = oEvent.originalEvent || oEvent;
if (oAttachment && oLocalEvent && oLocalEvent.dataTransfer && oLocalEvent.dataTransfer.setData)
{
oLocalEvent.dataTransfer.setData('DownloadURL', this.generateTransferDownloadUrl());
}
return true;
};
/**
* @param {string} sExt
* @param {string} sMimeType
* @returns {string}
*/
AttachmentModel.staticFileType = _.memoize(function(sExt, sMimeType)
{
sExt = Utils.trim(sExt).toLowerCase();
sMimeType = Utils.trim(sMimeType).toLowerCase();
var
sResult = Enums.FileType.Unknown,
aMimeTypeParts = sMimeType.split('/');
switch (true)
{
case 'image' === aMimeTypeParts[0] || -1 < Utils.inArray(sExt, [
'png', 'jpg', 'jpeg', 'gif', 'bmp'
]):
sResult = Enums.FileType.Image;
break;
case 'audio' === aMimeTypeParts[0] || -1 < Utils.inArray(sExt, [
'mp3', 'ogg', 'oga', 'wav'
]):
sResult = Enums.FileType.Audio;
break;
case 'video' === aMimeTypeParts[0] || -1 < Utils.inArray(sExt, [
'mkv', 'avi'
]):
sResult = Enums.FileType.Video;
break;
case -1 < Utils.inArray(sExt, [
'php', 'js', 'css'
]):
sResult = Enums.FileType.Code;
break;
case 'eml' === sExt || -1 < Utils.inArray(sMimeType, [
'message/delivery-status', 'message/rfc822'
]):
sResult = Enums.FileType.Eml;
break;
case ('text' === aMimeTypeParts[0] && 'html' !== aMimeTypeParts[1]) || -1 < Utils.inArray(sExt, [
'txt', 'log'
]):
sResult = Enums.FileType.Text;
break;
case ('text/html' === sMimeType) || -1 < Utils.inArray(sExt, [
'html'
]):
sResult = Enums.FileType.Html;
break;
case -1 < Utils.inArray(aMimeTypeParts[1], [
'zip', '7z', 'tar', 'rar', 'gzip', 'bzip', 'bzip2', 'x-zip', 'x-7z', 'x-rar', 'x-tar', 'x-gzip', 'x-bzip', 'x-bzip2', 'x-zip-compressed', 'x-7z-compressed', 'x-rar-compressed'
]) || -1 < Utils.inArray(sExt, [
'zip', '7z', 'tar', 'rar', 'gzip', 'bzip', 'bzip2'
]):
sResult = Enums.FileType.Archive;
break;
case -1 < Utils.inArray(aMimeTypeParts[1], ['pdf', 'x-pdf']) || -1 < Utils.inArray(sExt, [
'pdf'
]):
sResult = Enums.FileType.Pdf;
break;
case -1 < Utils.inArray(sMimeType, [
'application/pgp-signature', 'application/pgp-keys'
]) || -1 < Utils.inArray(sExt, [
'asc', 'pem', 'ppk'
]):
sResult = Enums.FileType.Certificate;
break;
case -1 < Utils.inArray(sMimeType, ['application/pkcs7-signature']) ||
-1 < Utils.inArray(sExt, ['p7s']):
sResult = Enums.FileType.CertificateBin;
break;
case -1 < Utils.inArray(aMimeTypeParts[1], [
'rtf', 'msword', 'vnd.msword', 'vnd.openxmlformats-officedocument.wordprocessingml.document',
'vnd.openxmlformats-officedocument.wordprocessingml.template',
'vnd.ms-word.document.macroEnabled.12',
'vnd.ms-word.template.macroEnabled.12'
]):
sResult = Enums.FileType.WordText;
break;
case -1 < Utils.inArray(aMimeTypeParts[1], [
'excel', 'ms-excel', 'vnd.ms-excel',
'vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'vnd.openxmlformats-officedocument.spreadsheetml.template',
'vnd.ms-excel.sheet.macroEnabled.12',
'vnd.ms-excel.template.macroEnabled.12',
'vnd.ms-excel.addin.macroEnabled.12',
'vnd.ms-excel.sheet.binary.macroEnabled.12'
]):
sResult = Enums.FileType.Sheet;
break;
case -1 < Utils.inArray(aMimeTypeParts[1], [
'powerpoint', 'ms-powerpoint', 'vnd.ms-powerpoint',
'vnd.openxmlformats-officedocument.presentationml.presentation',
'vnd.openxmlformats-officedocument.presentationml.template',
'vnd.openxmlformats-officedocument.presentationml.slideshow',
'vnd.ms-powerpoint.addin.macroEnabled.12',
'vnd.ms-powerpoint.presentation.macroEnabled.12',
'vnd.ms-powerpoint.template.macroEnabled.12',
'vnd.ms-powerpoint.slideshow.macroEnabled.12'
]):
sResult = Enums.FileType.Presentation;
break;
// no default
}
return sResult;
});
/**
* @param {string} sFileType
* @returns {string}
*/
AttachmentModel.staticIconClass = _.memoize(function(sFileType)
{
var
sText = '',
sClass = 'icon-file';
switch (sFileType)
{
case Enums.FileType.Text:
case Enums.FileType.Eml:
case Enums.FileType.WordText:
sClass = 'icon-file-text';
break;
case Enums.FileType.Html:
case Enums.FileType.Code:
sClass = 'icon-file-code';
break;
case Enums.FileType.Image:
sClass = 'icon-file-image';
break;
case Enums.FileType.Audio:
sClass = 'icon-file-music';
break;
case Enums.FileType.Video:
sClass = 'icon-file-movie';
break;
case Enums.FileType.Archive:
sClass = 'icon-file-zip';
break;
case Enums.FileType.Certificate:
case Enums.FileType.CertificateBin:
sClass = 'icon-file-certificate';
break;
case Enums.FileType.Sheet:
sClass = 'icon-file-excel';
break;
case Enums.FileType.Presentation:
sClass = 'icon-file-chart-graph';
break;
case Enums.FileType.Pdf:
sText = 'pdf';
sClass = 'icon-none';
break;
// no default
}
return [sClass, sText];
});
/**
* @param {string} sFileType
* @returns {string}
*/
AttachmentModel.staticCombinedIconClass = function(aData)
{
var
sClass = '',
aTypes = [];
if (Utils.isNonEmptyArray(aData))
{
sClass = 'icon-attachment';
aTypes = _.uniq(_.compact(_.map(aData, function(aItem) {
return aItem ? AttachmentModel.staticFileType(
Utils.getFileExtension(aItem[0]), aItem[1]) : '';
})));
if (aTypes && 1 === aTypes.length && aTypes[0])
{
switch (aTypes[0])
{
case Enums.FileType.Text:
case Enums.FileType.WordText:
sClass = 'icon-file-text';
break;
case Enums.FileType.Html:
case Enums.FileType.Code:
sClass = 'icon-file-code';
break;
case Enums.FileType.Image:
sClass = 'icon-file-image';
break;
case Enums.FileType.Audio:
sClass = 'icon-file-music';
break;
case Enums.FileType.Video:
sClass = 'icon-file-movie';
break;
case Enums.FileType.Archive:
sClass = 'icon-file-zip';
break;
case Enums.FileType.Certificate:
case Enums.FileType.CertificateBin:
sClass = 'icon-file-certificate';
break;
case Enums.FileType.Sheet:
sClass = 'icon-file-excel';
break;
case Enums.FileType.Presentation:
sClass = 'icon-file-chart-graph';
break;
// no default
}
}
}
return sClass;
};
/**
* @returns {string}
*/
AttachmentModel.prototype.iconClass = function()
{
return AttachmentModel.staticIconClass(this.fileType)[0];
};
/**
* @returns {string}
*/
AttachmentModel.prototype.iconText = function()
{
return AttachmentModel.staticIconClass(this.fileType)[1];
};
module.exports = AttachmentModel;

487
dev/Model/Attachment.jsx Normal file
View file

@ -0,0 +1,487 @@
import window from 'window';
import _ from '_';
import ko from 'ko';
import {FileType} from 'Common/Enums';
import {bAllowPdfPreview, data as GlobalsData} from 'Common/Globals';
import {trim, pInt, inArray, isNonEmptyArray, getFileExtension, friendlySize} from 'Common/Utils';
import {attachmentDownload, attachmentPreview, attachmentFramed, attachmentPreviewAsPlain, attachmentThumbnailPreview} from 'Common/Links';
import {AbstractModel} from 'Knoin/AbstractModel';
import Audio from 'Common/Audio';
/**
* @param {string} sExt
* @param {string} sMimeType
* @returns {string}
*/
export const staticFileType = _.memoize((ext, mimeType) => {
ext = trim(ext).toLowerCase();
mimeType = trim(mimeType).toLowerCase();
let result = FileType.Unknown;
const mimeTypeParts = mimeType.split('/');
switch (true)
{
case 'image' === mimeTypeParts[0] || -1 < inArray(ext, [
'png', 'jpg', 'jpeg', 'gif', 'bmp'
]):
result = FileType.Image;
break;
case 'audio' === mimeTypeParts[0] || -1 < inArray(ext, [
'mp3', 'ogg', 'oga', 'wav'
]):
result = FileType.Audio;
break;
case 'video' === mimeTypeParts[0] || -1 < inArray(ext, [
'mkv', 'avi'
]):
result = FileType.Video;
break;
case -1 < inArray(ext, [
'php', 'js', 'css'
]):
result = FileType.Code;
break;
case 'eml' === ext || -1 < inArray(mimeType, [
'message/delivery-status', 'message/rfc822'
]):
result = FileType.Eml;
break;
case ('text' === mimeTypeParts[0] && 'html' !== mimeTypeParts[1]) || -1 < inArray(ext, [
'txt', 'log'
]):
result = FileType.Text;
break;
case ('text/html' === mimeType) || -1 < inArray(ext, [
'html'
]):
result = FileType.Html;
break;
case -1 < inArray(mimeTypeParts[1], [
'zip', '7z', 'tar', 'rar', 'gzip', 'bzip', 'bzip2', 'x-zip', 'x-7z', 'x-rar', 'x-tar', 'x-gzip', 'x-bzip', 'x-bzip2', 'x-zip-compressed', 'x-7z-compressed', 'x-rar-compressed'
]) || -1 < inArray(ext, [
'zip', '7z', 'tar', 'rar', 'gzip', 'bzip', 'bzip2'
]):
result = FileType.Archive;
break;
case -1 < inArray(mimeTypeParts[1], ['pdf', 'x-pdf']) || -1 < inArray(ext, [
'pdf'
]):
result = FileType.Pdf;
break;
case -1 < inArray(mimeType, [
'application/pgp-signature', 'application/pgp-keys'
]) || -1 < inArray(ext, [
'asc', 'pem', 'ppk'
]):
result = FileType.Certificate;
break;
case -1 < inArray(mimeType, ['application/pkcs7-signature']) ||
-1 < inArray(ext, ['p7s']):
result = FileType.CertificateBin;
break;
case -1 < inArray(mimeTypeParts[1], [
'rtf', 'msword', 'vnd.msword', 'vnd.openxmlformats-officedocument.wordprocessingml.document',
'vnd.openxmlformats-officedocument.wordprocessingml.template',
'vnd.ms-word.document.macroEnabled.12',
'vnd.ms-word.template.macroEnabled.12'
]):
result = FileType.WordText;
break;
case -1 < inArray(mimeTypeParts[1], [
'excel', 'ms-excel', 'vnd.ms-excel',
'vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'vnd.openxmlformats-officedocument.spreadsheetml.template',
'vnd.ms-excel.sheet.macroEnabled.12',
'vnd.ms-excel.template.macroEnabled.12',
'vnd.ms-excel.addin.macroEnabled.12',
'vnd.ms-excel.sheet.binary.macroEnabled.12'
]):
result = FileType.Sheet;
break;
case -1 < inArray(mimeTypeParts[1], [
'powerpoint', 'ms-powerpoint', 'vnd.ms-powerpoint',
'vnd.openxmlformats-officedocument.presentationml.presentation',
'vnd.openxmlformats-officedocument.presentationml.template',
'vnd.openxmlformats-officedocument.presentationml.slideshow',
'vnd.ms-powerpoint.addin.macroEnabled.12',
'vnd.ms-powerpoint.presentation.macroEnabled.12',
'vnd.ms-powerpoint.template.macroEnabled.12',
'vnd.ms-powerpoint.slideshow.macroEnabled.12'
]):
result = FileType.Presentation;
break;
// no default
}
return result;
});
/**
* @param {string} sFileType
* @returns {string}
*/
export const staticIconClass = _.memoize((fileType) => {
let
resultText = '',
resultClass = 'icon-file';
switch (fileType)
{
case FileType.Text:
case FileType.Eml:
case FileType.WordText:
resultClass = 'icon-file-text';
break;
case FileType.Html:
case FileType.Code:
resultClass = 'icon-file-code';
break;
case FileType.Image:
resultClass = 'icon-file-image';
break;
case FileType.Audio:
resultClass = 'icon-file-music';
break;
case FileType.Video:
resultClass = 'icon-file-movie';
break;
case FileType.Archive:
resultClass = 'icon-file-zip';
break;
case FileType.Certificate:
case FileType.CertificateBin:
resultClass = 'icon-file-certificate';
break;
case FileType.Sheet:
resultClass = 'icon-file-excel';
break;
case FileType.Presentation:
resultClass = 'icon-file-chart-graph';
break;
case FileType.Pdf:
resultText = 'pdf';
resultClass = 'icon-none';
break;
// no default
}
return [resultClass, resultText];
});
/**
* @static
* @param {string} sFileType
* @returns {string}
*/
export const staticCombinedIconClass = (data) => {
let
result = '',
types = [];
if (isNonEmptyArray(data))
{
result = 'icon-attachment';
types = _.uniq(_.compact(_.map(data, (item) => (item ? staticFileType(getFileExtension(item[0]), item[1]) : ''))));
if (types && 1 === types.length && types[0])
{
switch (types[0])
{
case FileType.Text:
case FileType.WordText:
result = 'icon-file-text';
break;
case FileType.Html:
case FileType.Code:
result = 'icon-file-code';
break;
case FileType.Image:
result = 'icon-file-image';
break;
case FileType.Audio:
result = 'icon-file-music';
break;
case FileType.Video:
result = 'icon-file-movie';
break;
case FileType.Archive:
result = 'icon-file-zip';
break;
case FileType.Certificate:
case FileType.CertificateBin:
result = 'icon-file-certificate';
break;
case FileType.Sheet:
result = 'icon-file-excel';
break;
case FileType.Presentation:
result = 'icon-file-chart-graph';
break;
// no default
}
}
}
return result;
};
class AttachmentModel extends AbstractModel
{
constructor()
{
super('AttachmentModel');
this.checked = ko.observable(false);
this.mimeType = '';
this.fileName = '';
this.fileNameExt = '';
this.fileType = FileType.Unknown;
this.estimatedSize = 0;
this.friendlySize = '';
this.isInline = false;
this.isLinked = false;
this.isThumbnail = false;
this.cid = '';
this.cidWithOutTags = '';
this.contentLocation = '';
this.download = '';
this.folder = '';
this.uid = '';
this.mimeIndex = '';
this.framed = false;
}
/**
* @static
* @param {AjaxJsonAttachment} json
* @returns {?AttachmentModel}
*/
static newInstanceFromJson(json) {
const attachment = new AttachmentModel();
return attachment.initByJson(json) ? attachment : null;
}
/**
* @param {AjaxJsonAttachment} json
* @returns {boolean}
*/
initByJson(json) {
let bResult = false;
if (json && 'Object/Attachment' === json['@Object'])
{
this.mimeType = trim((json.MimeType || '').toLowerCase());
this.fileName = trim(json.FileName);
this.estimatedSize = pInt(json.EstimatedSize);
this.isInline = !!json.IsInline;
this.isLinked = !!json.IsLinked;
this.isThumbnail = !!json.IsThumbnail;
this.cid = json.CID;
this.contentLocation = json.ContentLocation;
this.download = json.Download;
this.folder = json.Folder;
this.uid = json.Uid;
this.mimeIndex = json.MimeIndex;
this.framed = !!json.Framed;
this.friendlySize = friendlySize(this.estimatedSize);
this.cidWithOutTags = this.cid.replace(/^<+/, '').replace(/>+$/, '');
this.fileNameExt = getFileExtension(this.fileName);
this.fileType = staticFileType(this.fileNameExt, this.mimeType);
bResult = true;
}
return bResult;
}
/**
* @returns {boolean}
*/
isImage() {
return FileType.Image === this.fileType;
}
/**
* @returns {boolean}
*/
isMp3() {
return FileType.Audio === this.fileType && 'mp3' === this.fileNameExt;
}
/**
* @returns {boolean}
*/
isOgg() {
return FileType.Audio === this.fileType && ('oga' === this.fileNameExt || 'ogg' === this.fileNameExt);
}
/**
* @returns {boolean}
*/
isWav() {
return FileType.Audio === this.fileType && 'wav' === this.fileNameExt;
}
/**
* @returns {boolean}
*/
hasThumbnail() {
return this.isThumbnail;
}
/**
* @returns {boolean}
*/
isText() {
return FileType.Text === this.fileType || FileType.Eml === this.fileType ||
FileType.Certificate === this.fileType || FileType.Html === this.fileType || FileType.Code === this.fileType;
}
/**
* @returns {boolean}
*/
isPdf() {
return FileType.Pdf === this.fileType;
}
/**
* @returns {boolean}
*/
isFramed() {
return this.framed && (GlobalsData.__APP__ && GlobalsData.__APP__.googlePreviewSupported()) &&
!(this.isPdf() && bAllowPdfPreview) && !this.isText() && !this.isImage();
}
/**
* @returns {boolean}
*/
hasPreview() {
return this.isImage() || (this.isPdf() && bAllowPdfPreview) || this.isText() || this.isFramed();
}
/**
* @returns {boolean}
*/
hasPreplay() {
return (Audio.supportedMp3 && this.isMp3()) || (Audio.supportedOgg && this.isOgg()) || (Audio.supportedWav && this.isWav());
}
/**
* @returns {string}
*/
linkDownload() {
return attachmentDownload(this.download);
}
/**
* @returns {string}
*/
linkPreview() {
return attachmentPreview(this.download);
}
/**
* @returns {string}
*/
linkThumbnail() {
return this.hasThumbnail() ? attachmentThumbnailPreview(this.download) : '';
}
/**
* @returns {string}
*/
linkThumbnailPreviewStyle() {
const link = this.linkThumbnail();
return '' === link ? '' : 'background:url(' + link + ')';
}
/**
* @returns {string}
*/
linkFramed() {
return attachmentFramed(this.download);
}
/**
* @returns {string}
*/
linkPreviewAsPlain() {
return attachmentPreviewAsPlain(this.download);
}
/**
* @returns {string}
*/
linkPreviewMain() {
let result = '';
switch (true)
{
case this.isImage():
case this.isPdf() && bAllowPdfPreview:
result = this.linkPreview();
break;
case this.isText():
result = this.linkPreviewAsPlain();
break;
case this.isFramed():
result = this.linkFramed();
break;
// no default
}
return result;
}
/**
* @returns {string}
*/
generateTransferDownloadUrl() {
let link = this.linkDownload();
if ('http' !== link.substr(0, 4))
{
link = window.location.protocol + '//' + window.location.host + window.location.pathname + link;
}
return this.mimeType + ':' + this.fileName + ':' + link;
}
/**
* @param {AttachmentModel} attachment
* @param {*} event
* @returns {boolean}
*/
eventDragStart(attachment, event) {
const localEvent = event.originalEvent || event;
if (attachment && localEvent && localEvent.dataTransfer && localEvent.dataTransfer.setData)
{
localEvent.dataTransfer.setData('DownloadURL', this.generateTransferDownloadUrl());
}
return true;
}
/**
* @returns {string}
*/
iconClass() {
return staticIconClass(this.fileType)[0];
}
/**
* @returns {string}
*/
iconText() {
return staticIconClass(this.fileType)[1];
}
}
export {AttachmentModel, AttachmentModel as default};

View file

@ -1,123 +0,0 @@
var
_ = require('_'),
ko = require('ko'),
Utils = require('Common/Utils'),
AttachmentModel = require('Model/Attachment'),
AbstractModel = require('Knoin/AbstractModel');
/**
* @constructor
* @param {string} sId
* @param {string} sFileName
* @param {?number=} nSize
* @param {boolean=} bInline
* @param {boolean=} bLinked
* @param {string=} sCID
* @param {string=} sContentLocation
*/
function ComposeAttachmentModel(sId, sFileName, nSize, bInline, bLinked, sCID, sContentLocation)
{
AbstractModel.call(this, 'ComposeAttachmentModel');
this.id = sId;
this.isInline = Utils.isUnd(bInline) ? false : !!bInline;
this.isLinked = Utils.isUnd(bLinked) ? false : !!bLinked;
this.CID = Utils.isUnd(sCID) ? '' : sCID;
this.contentLocation = Utils.isUnd(sContentLocation) ? '' : sContentLocation;
this.fromMessage = false;
this.fileName = ko.observable(sFileName);
this.size = ko.observable(Utils.isUnd(nSize) ? null : nSize);
this.tempName = ko.observable('');
this.progress = ko.observable(0);
this.error = ko.observable('');
this.waiting = ko.observable(true);
this.uploading = ko.observable(false);
this.enabled = ko.observable(true);
this.complete = ko.observable(false);
this.progressText = ko.computed(function() {
var iP = this.progress();
return 0 === iP ? '' : '' + (98 < iP ? 100 : iP) + '%';
}, this);
this.progressStyle = ko.computed(function() {
var iP = this.progress();
return 0 === iP ? '' : 'width:' + (98 < iP ? 100 : iP) + '%';
}, this);
this.title = ko.computed(function() {
var sError = this.error();
return '' !== sError ? sError : this.fileName();
}, this);
this.friendlySize = ko.computed(function() {
var mSize = this.size();
return null === mSize ? '' : Utils.friendlySize(this.size());
}, this);
this.mimeType = ko.computed(function() {
return Utils.mimeContentType(this.fileName());
}, this);
this.fileExt = ko.computed(function() {
return Utils.getFileExtension(this.fileName());
}, this);
this.regDisposables([this.progressText, this.progressStyle, this.title, this.friendlySize, this.mimeType, this.fileExt]);
}
_.extend(ComposeAttachmentModel.prototype, AbstractModel.prototype);
ComposeAttachmentModel.prototype.id = '';
ComposeAttachmentModel.prototype.isInline = false;
ComposeAttachmentModel.prototype.isLinked = false;
ComposeAttachmentModel.prototype.CID = '';
ComposeAttachmentModel.prototype.contentLocation = '';
ComposeAttachmentModel.prototype.fromMessage = false;
ComposeAttachmentModel.prototype.cancel = Utils.noop;
/**
* @param {AjaxJsonComposeAttachment} oJsonAttachment
* @returns {boolean}
*/
ComposeAttachmentModel.prototype.initByUploadJson = function(oJsonAttachment)
{
var bResult = false;
if (oJsonAttachment)
{
this.fileName(oJsonAttachment.Name);
this.size(Utils.isUnd(oJsonAttachment.Size) ? 0 : Utils.pInt(oJsonAttachment.Size));
this.tempName(Utils.isUnd(oJsonAttachment.TempName) ? '' : oJsonAttachment.TempName);
this.isInline = false;
bResult = true;
}
return bResult;
};
/**
* @returns {string}
*/
ComposeAttachmentModel.prototype.iconClass = function()
{
return AttachmentModel.staticIconClass(
AttachmentModel.staticFileType(this.fileExt(), this.mimeType()))[0];
};
/**
* @returns {string}
*/
ComposeAttachmentModel.prototype.iconText = function()
{
return AttachmentModel.staticIconClass(
AttachmentModel.staticFileType(this.fileExt(), this.mimeType()))[1];
};
module.exports = ComposeAttachmentModel;

View file

@ -0,0 +1,101 @@
import ko from 'ko';
import {isUnd, pInt, friendlySize, mimeContentType, getFileExtension} from 'Common/Utils';
import {staticIconClass, staticFileType} from 'Model/Attachment';
import {AbstractModel} from 'Knoin/AbstractModel';
class ComposeAttachmentModel extends AbstractModel
{
/**
* @param {string} id
* @param {string} fileName
* @param {?number=} size = null
* @param {boolean=} isInline = false
* @param {boolean=} isLinked = false
* @param {string=} CID = ''
* @param {string=} contentLocation = ''
*/
constructor(id, fileName, size = null, isInline = false, isLinked = false, CID = '', contentLocation = '')
{
super('ComposeAttachmentModel');
this.id = id;
this.isInline = !!isInline;
this.isLinked = !!isLinked;
this.CID = CID;
this.contentLocation = contentLocation;
this.fromMessage = false;
this.fileName = ko.observable(fileName);
this.size = ko.observable(size);
this.tempName = ko.observable('');
this.progress = ko.observable(0);
this.error = ko.observable('');
this.waiting = ko.observable(true);
this.uploading = ko.observable(false);
this.enabled = ko.observable(true);
this.complete = ko.observable(false);
this.progressText = ko.computed(() => {
const p = this.progress();
return 0 === p ? '' : '' + (98 < p ? 100 : p) + '%';
});
this.progressStyle = ko.computed(() => {
const p = this.progress();
return 0 === p ? '' : 'width:' + (98 < p ? 100 : p) + '%';
});
this.title = ko.computed(() => {
const error = this.error();
return '' !== error ? error : this.fileName();
});
this.friendlySize = ko.computed(() => {
const localSize = this.size();
return null === localSize ? '' : friendlySize(localSize);
});
this.mimeType = ko.computed(() => mimeContentType(this.fileName()));
this.fileExt = ko.computed(() => getFileExtension(this.fileName()));
this.regDisposables([this.progressText, this.progressStyle, this.title, this.friendlySize, this.mimeType, this.fileExt]);
}
/**
* @param {AjaxJsonComposeAttachment} json
* @returns {boolean}
*/
initByUploadJson(json) {
let bResult = false;
if (json)
{
this.fileName(json.Name);
this.size(isUnd(json.Size) ? 0 : pInt(json.Size));
this.tempName(isUnd(json.TempName) ? '' : json.TempName);
this.isInline = false;
bResult = true;
}
return bResult;
}
/**
* @returns {string}
*/
iconClass() {
return staticIconClass(staticFileType(this.fileExt(), this.mimeType()))[0];
}
/**
* @returns {string}
*/
iconText() {
return staticIconClass(staticFileType(this.fileExt(), this.mimeType()))[1];
}
}
export {ComposeAttachmentModel, ComposeAttachmentModel as default};

View file

@ -1,132 +0,0 @@
var
_ = require('_'),
ko = require('ko'),
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
Links = require('Common/Links'),
AbstractModel = require('Knoin/AbstractModel');
/**
* @constructor
*/
function ContactModel()
{
AbstractModel.call(this, 'ContactModel');
this.idContact = 0;
this.display = '';
this.properties = [];
this.readOnly = false;
this.focused = ko.observable(false);
this.selected = ko.observable(false);
this.checked = ko.observable(false);
this.deleted = ko.observable(false);
}
_.extend(ContactModel.prototype, AbstractModel.prototype);
/**
* @returns {Array|null}
*/
ContactModel.prototype.getNameAndEmailHelper = function()
{
var
sName = '',
sEmail = '';
if (Utils.isNonEmptyArray(this.properties))
{
_.each(this.properties, function(aProperty) {
if (aProperty)
{
if (Enums.ContactPropertyType.FirstName === aProperty[0])
{
sName = Utils.trim(aProperty[1] + ' ' + sName);
}
else if (Enums.ContactPropertyType.LastName === aProperty[0])
{
sName = Utils.trim(sName + ' ' + aProperty[1]);
}
else if ('' === sEmail && Enums.ContactPropertyType.Email === aProperty[0])
{
sEmail = aProperty[1];
}
}
}, this);
}
return '' === sEmail ? null : [sEmail, sName];
};
ContactModel.prototype.parse = function(oItem)
{
var bResult = false;
if (oItem && 'Object/Contact' === oItem['@Object'])
{
this.idContact = Utils.pInt(oItem.IdContact);
this.display = Utils.pString(oItem.Display);
this.readOnly = !!oItem.ReadOnly;
if (Utils.isNonEmptyArray(oItem.Properties))
{
_.each(oItem.Properties, function(oProperty) {
if (oProperty && oProperty.Type && Utils.isNormal(oProperty.Value) && Utils.isNormal(oProperty.TypeStr))
{
this.properties.push([Utils.pInt(oProperty.Type), Utils.pString(oProperty.Value), Utils.pString(oProperty.TypeStr)]);
}
}, this);
}
bResult = true;
}
return bResult;
};
/**
* @returns {string}
*/
ContactModel.prototype.srcAttr = function()
{
return Links.emptyContactPic();
};
/**
* @returns {string}
*/
ContactModel.prototype.generateUid = function()
{
return '' + this.idContact;
};
/**
* @return string
*/
ContactModel.prototype.lineAsCss = function()
{
var aResult = [];
if (this.deleted())
{
aResult.push('deleted');
}
if (this.selected())
{
aResult.push('selected');
}
if (this.checked())
{
aResult.push('checked');
}
if (this.focused())
{
aResult.push('focused');
}
return aResult.join(' ');
};
module.exports = ContactModel;

128
dev/Model/Contact.jsx Normal file
View file

@ -0,0 +1,128 @@
import _ from '_';
import ko from 'ko';
import {ContactPropertyType} from 'Common/Enums';
import {trim, isNonEmptyArray, isNormal, pInt, pString} from 'Common/Utils';
import {emptyContactPic} from 'Common/Links';
import {AbstractModel} from 'Knoin/AbstractModel';
class ContactModel extends AbstractModel
{
constructor()
{
super('ContactModel');
this.idContact = 0;
this.display = '';
this.properties = [];
this.readOnly = false;
this.focused = ko.observable(false);
this.selected = ko.observable(false);
this.checked = ko.observable(false);
this.deleted = ko.observable(false);
}
/**
* @returns {Array|null}
*/
getNameAndEmailHelper() {
let
name = '',
email = '';
if (isNonEmptyArray(this.properties))
{
_.each(this.properties, (property) => {
if (property)
{
if (ContactPropertyType.FirstName === property[0])
{
name = trim(property[1] + ' ' + name);
}
else if (ContactPropertyType.LastName === property[0])
{
name = trim(name + ' ' + property[1]);
}
else if ('' === email && ContactPropertyType.Email === property[0])
{
email = property[1];
}
}
});
}
return '' === email ? null : [email, name];
}
/**
* @param {Object} oItem
* @returns {boolean}
*/
parse(json) {
let result = false;
if (json && 'Object/Contact' === json['@Object'])
{
this.idContact = pInt(json.IdContact);
this.display = pString(json.Display);
this.readOnly = !!json.ReadOnly;
if (isNonEmptyArray(json.Properties))
{
_.each(json.Properties, (property) => {
if (property && property.Type && isNormal(property.Value) && isNormal(property.TypeStr))
{
this.properties.push([pInt(property.Type), pString(property.Value), pString(property.TypeStr)]);
}
});
}
result = true;
}
return result;
}
/**
* @returns {string}
*/
srcAttr() {
return emptyContactPic();
}
/**
* @returns {string}
*/
generateUid() {
return pString(this.idContact);
}
/**
* @return string
*/
lineAsCss() {
const result = [];
if (this.deleted())
{
result.push('deleted');
}
if (this.selected())
{
result.push('selected');
}
if (this.checked())
{
result.push('checked');
}
if (this.focused())
{
result.push('focused');
}
return result.join(' ');
}
}
export {ContactModel, ContactModel as default};

View file

@ -1,45 +0,0 @@
var
_ = require('_'),
ko = require('ko'),
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
Translator = require('Common/Translator'),
AbstractModel = require('Knoin/AbstractModel');
/**
* @constructor
* @param {number=} iType = Enums.ContactPropertyType.Unknown
* @param {string=} sTypeStr = ''
* @param {string=} sValue = ''
* @param {boolean=} bFocused = false
* @param {string=} sPlaceholder = ''
*/
function ContactPropertyModel(iType, sTypeStr, sValue, bFocused, sPlaceholder)
{
AbstractModel.call(this, 'ContactPropertyModel');
this.type = ko.observable(Utils.isUnd(iType) ? Enums.ContactPropertyType.Unknown : iType);
this.typeStr = ko.observable(Utils.isUnd(sTypeStr) ? '' : sTypeStr);
this.focused = ko.observable(Utils.isUnd(bFocused) ? false : !!bFocused);
this.value = ko.observable(Utils.pString(sValue));
this.placeholder = ko.observable(sPlaceholder || '');
this.placeholderValue = ko.computed(function() {
var value = this.placeholder();
return value ? Translator.i18n(value) : '';
}, this);
this.largeValue = ko.computed(function() {
return Enums.ContactPropertyType.Note === this.type();
}, this);
this.regDisposables([this.placeholderValue, this.largeValue]);
}
_.extend(ContactPropertyModel.prototype, AbstractModel.prototype);
module.exports = ContactPropertyModel;

View file

@ -0,0 +1,41 @@
import ko from 'ko';
import {ContactPropertyType} from 'Common/Enums';
import {pInt, pString} from 'Common/Utils';
import {i18n} from 'Common/Translator';
import {AbstractModel} from 'Knoin/AbstractModel';
class ContactPropertyModel extends AbstractModel
{
/**
* @param {number=} type = Enums.ContactPropertyType.Unknown
* @param {string=} typeStr = ''
* @param {string=} value = ''
* @param {boolean=} focused = false
* @param {string=} placeholder = ''
*/
constructor(type = ContactPropertyType.Unknown, typeStr = '', value = '', focused = false, placeholder = '')
{
super('ContactPropertyModel');
this.type = ko.observable(pInt(type));
this.typeStr = ko.observable(pString(typeStr));
this.focused = ko.observable(!!focused);
this.value = ko.observable(pString(value));
this.placeholder = ko.observable(placeholder);
this.placeholderValue = ko.computed(() => {
const v = this.placeholder();
return v ? i18n(v) : '';
});
this.largeValue = ko.computed(() => ContactPropertyType.Note === this.type());
this.regDisposables([this.placeholderValue, this.largeValue]);
}
}
export {ContactPropertyModel, ContactPropertyModel as default};

View file

@ -1,401 +0,0 @@
var Utils = require('Common/Utils');
/**
* @constructor
* @param {string=} sEmail
* @param {string=} sName
* @param {string=} sDkimStatus
* @param {string=} sDkimValue
*/
function EmailModel(sEmail, sName, sDkimStatus, sDkimValue)
{
this.email = sEmail || '';
this.name = sName || '';
this.dkimStatus = sDkimStatus || 'none';
this.dkimValue = sDkimValue || '';
this.clearDuplicateName();
}
/**
* @static
* @param {AjaxJsonEmail} oJsonEmail
* @returns {?EmailModel}
*/
EmailModel.newInstanceFromJson = function(oJsonEmail)
{
var oEmailModel = new EmailModel();
return oEmailModel.initByJson(oJsonEmail) ? oEmailModel : null;
};
/**
* @static
* @param {string} sLine
* @param {string=} sDelimiter = ';'
* @returns {Array}
*/
EmailModel.splitHelper = function(sLine, sDelimiter)
{
sDelimiter = sDelimiter || ';';
sLine = sLine.replace(/[\r\n]+/g, '; ').replace(/[\s]+/g, ' ');
var
iIndex = 0,
iLen = sLine.length,
bAt = false,
sChar = '',
sResult = '';
for (; iIndex < iLen; iIndex++)
{
sChar = sLine.charAt(iIndex);
switch (sChar)
{
case '@':
bAt = true;
break;
case ' ':
if (bAt)
{
bAt = false;
sResult += sDelimiter;
}
break;
// no default
}
sResult += sChar;
}
return sResult.split(sDelimiter);
};
/**
* @type {string}
*/
EmailModel.prototype.name = '';
/**
* @type {string}
*/
EmailModel.prototype.email = '';
/**
* @type {string}
*/
EmailModel.prototype.dkimStatus = 'none';
/**
* @type {string}
*/
EmailModel.prototype.dkimValue = '';
EmailModel.prototype.clear = function()
{
this.email = '';
this.name = '';
this.dkimStatus = 'none';
this.dkimValue = '';
};
/**
* @returns {boolean}
*/
EmailModel.prototype.validate = function()
{
return '' !== this.name || '' !== this.email;
};
/**
* @param {boolean} bWithoutName = false
* @returns {string}
*/
EmailModel.prototype.hash = function(bWithoutName)
{
return '#' + (bWithoutName ? '' : this.name) + '#' + this.email + '#';
};
EmailModel.prototype.clearDuplicateName = function()
{
if (this.name === this.email)
{
this.name = '';
}
};
/**
* @param {string} sQuery
* @returns {boolean}
*/
EmailModel.prototype.search = function(sQuery)
{
return -1 < (this.name + ' ' + this.email).toLowerCase().indexOf(sQuery.toLowerCase());
};
/**
* @param {string} sString
*/
EmailModel.prototype.parse = function(sString)
{
this.clear();
sString = Utils.trim(sString);
var
mRegex = /(?:"([^"]+)")? ?[<]?(.*?@[^>,]+)>?,? ?/g,
mMatch = mRegex.exec(sString);
if (mMatch)
{
this.name = mMatch[1] || '';
this.email = mMatch[2] || '';
this.clearDuplicateName();
}
else if ((/^[^@]+@[^@]+$/).test(sString))
{
this.name = '';
this.email = sString;
}
};
/**
* @param {AjaxJsonEmail} oJsonEmail
* @returns {boolean}
*/
EmailModel.prototype.initByJson = function(oJsonEmail)
{
var bResult = false;
if (oJsonEmail && 'Object/Email' === oJsonEmail['@Object'])
{
this.name = Utils.trim(oJsonEmail.Name);
this.email = Utils.trim(oJsonEmail.Email);
this.dkimStatus = Utils.trim(oJsonEmail.DkimStatus || '');
this.dkimValue = Utils.trim(oJsonEmail.DkimValue || '');
bResult = '' !== this.email;
this.clearDuplicateName();
}
return bResult;
};
/**
* @param {boolean} bFriendlyView
* @param {boolean=} bWrapWithLink = false
* @param {boolean=} bEncodeHtml = false
* @returns {string}
*/
EmailModel.prototype.toLine = function(bFriendlyView, bWrapWithLink, bEncodeHtml)
{
var sResult = '';
if ('' !== this.email)
{
bWrapWithLink = Utils.isUnd(bWrapWithLink) ? false : !!bWrapWithLink;
bEncodeHtml = Utils.isUnd(bEncodeHtml) ? false : !!bEncodeHtml;
if (bFriendlyView && '' !== this.name)
{
sResult = bWrapWithLink ? '<a href="mailto:' + Utils.encodeHtml('"' + this.name + '" <' + this.email + '>') +
'" target="_blank" tabindex="-1">' + Utils.encodeHtml(this.name) + '</a>' :
(bEncodeHtml ? Utils.encodeHtml(this.name) : this.name);
}
else
{
sResult = this.email;
if ('' !== this.name)
{
if (bWrapWithLink)
{
sResult = Utils.encodeHtml('"' + this.name + '" <') + '<a href="mailto:' +
Utils.encodeHtml('"' + this.name + '" <' + this.email + '>') +
'" target="_blank" tabindex="-1">' +
Utils.encodeHtml(sResult) +
'</a>' +
Utils.encodeHtml('>');
}
else
{
sResult = '"' + this.name + '" <' + sResult + '>';
if (bEncodeHtml)
{
sResult = Utils.encodeHtml(sResult);
}
}
}
else if (bWrapWithLink)
{
sResult = '<a href="mailto:' + Utils.encodeHtml(this.email) + '" target="_blank" tabindex="-1">' + Utils.encodeHtml(this.email) + '</a>';
}
}
}
return sResult;
};
/**
* @param {string} $sEmailAddress
* @returns {boolean}
*/
EmailModel.prototype.mailsoParse = function($sEmailAddress)
{
$sEmailAddress = Utils.trim($sEmailAddress);
if ('' === $sEmailAddress)
{
return false;
}
var
substr = function(str, start, len) {
str = Utils.pString(str);
var end = str.length;
if (0 > start)
{
start += end;
}
end = 'undefined' === typeof len ? end : (0 > len ? len + end : len + start);
return start >= str.length || 0 > start || start > end ? false : str.slice(start, end);
},
substrReplace = function(str, replace, start, length) {
str = Utils.pString(str);
if (0 > start)
{
start += str.length;
}
length = 'undefined' !== typeof length ? length : str.length;
if (0 > length)
{
length = length + str.length - start;
}
return str.slice(0, start) + replace.substr(0, length) + replace.slice(length) + str.slice(start + length);
},
$sName = '',
$sEmail = '',
$sComment = '',
$bInName = false,
$bInAddress = false,
$bInComment = false,
$aRegs = null,
$iStartIndex = 0,
$iEndIndex = 0,
$iCurrentIndex = 0;
while ($iCurrentIndex < $sEmailAddress.length)
{
switch ($sEmailAddress.substr($iCurrentIndex, 1))
{
case '"':
if ((!$bInName) && (!$bInAddress) && (!$bInComment))
{
$bInName = true;
$iStartIndex = $iCurrentIndex;
}
else if ((!$bInAddress) && (!$bInComment))
{
$iEndIndex = $iCurrentIndex;
$sName = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
$sEmailAddress = substrReplace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
$iEndIndex = 0;
$iCurrentIndex = 0;
$iStartIndex = 0;
$bInName = false;
}
break;
case '<':
if ((!$bInName) && (!$bInAddress) && (!$bInComment))
{
if (0 < $iCurrentIndex && 0 === $sName.length)
{
$sName = substr($sEmailAddress, 0, $iCurrentIndex);
}
$bInAddress = true;
$iStartIndex = $iCurrentIndex;
}
break;
case '>':
if ($bInAddress)
{
$iEndIndex = $iCurrentIndex;
$sEmail = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
$sEmailAddress = substrReplace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
$iEndIndex = 0;
$iCurrentIndex = 0;
$iStartIndex = 0;
$bInAddress = false;
}
break;
case '(':
if ((!$bInName) && (!$bInAddress) && (!$bInComment))
{
$bInComment = true;
$iStartIndex = $iCurrentIndex;
}
break;
case ')':
if ($bInComment)
{
$iEndIndex = $iCurrentIndex;
$sComment = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
$sEmailAddress = substrReplace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
$iEndIndex = 0;
$iCurrentIndex = 0;
$iStartIndex = 0;
$bInComment = false;
}
break;
case '\\':
$iCurrentIndex += 1;
break;
// no default
}
$iCurrentIndex += 1;
}
if (0 === $sEmail.length)
{
$aRegs = $sEmailAddress.match(/[^@\s]+@\S+/i);
if ($aRegs && $aRegs[0])
{
$sEmail = $aRegs[0];
}
else
{
$sName = $sEmailAddress;
}
}
if (0 < $sEmail.length && 0 === $sName.length && 0 === $sComment.length)
{
$sName = $sEmailAddress.replace($sEmail, '');
}
$sEmail = Utils.trim($sEmail).replace(/^[<]+/, '').replace(/[>]+$/, '');
$sName = Utils.trim($sName).replace(/^["']+/, '').replace(/["']+$/, '');
$sComment = Utils.trim($sComment).replace(/^[(]+/, '').replace(/[)]+$/, '');
// Remove backslash
$sName = $sName.replace(/\\\\(.)/g, '$1');
$sComment = $sComment.replace(/\\\\(.)/g, '$1');
this.name = $sName;
this.email = $sEmail;
this.clearDuplicateName();
return true;
};
module.exports = EmailModel;

372
dev/Model/Email.jsx Normal file
View file

@ -0,0 +1,372 @@
import {trim, pString, encodeHtml} from 'Common/Utils';
class EmailModel
{
/**
* @param {string=} email = ''
* @param {string=} name = ''
* @param {string=} dkimStatus = 'none'
* @param {string=} dkimValue = ''
*/
constructor(email = '', name = '', dkimStatus = 'none', dkimValue = '')
{
this.email = email;
this.name = name;
this.dkimStatus = dkimStatus;
this.dkimValue = dkimValue;
this.clearDuplicateName();
}
/**
* @static
* @param {AjaxJsonEmail} json
* @returns {?EmailModel}
*/
static newInstanceFromJson(json) {
const email = new EmailModel();
return email.initByJson(json) ? email : null;
}
/**
* @static
* @param {string} line
* @param {string=} delimiter = ';'
* @returns {Array}
*/
static splitHelper(line, delimiter = ';') {
line = line.replace(/[\r\n]+/g, '; ').replace(/[\s]+/g, ' ');
let
index = 0,
len = 0,
at = false,
char = '',
result = '';
for (len = line.length; index < len; index++)
{
char = line.charAt(index);
switch (char)
{
case '@':
at = true;
break;
case ' ':
if (at)
{
at = false;
result += delimiter;
}
break;
// no default
}
result += char;
}
return result.split(delimiter);
}
/**
* @returns {void}
*/
clear() {
this.email = '';
this.name = '';
this.dkimStatus = 'none';
this.dkimValue = '';
}
/**
* @returns {boolean}
*/
validate() {
return '' !== this.name || '' !== this.email;
}
/**
* @param {boolean} withoutName = false
* @returns {string}
*/
hash(withoutName = false) {
return '#' + (withoutName ? '' : this.name) + '#' + this.email + '#';
}
/**
* @returns {void}
*/
clearDuplicateName() {
if (this.name === this.email)
{
this.name = '';
}
}
/**
* @param {string} query
* @returns {boolean}
*/
search(query) {
return -1 < (this.name + ' ' + this.email).toLowerCase().indexOf(query.toLowerCase());
}
/**
* @param {string} str
*/
parse(str) {
this.clear();
str = trim(str);
const
regex = /(?:"([^"]+)")? ?[<]?(.*?@[^>,]+)>?,? ?/g,
match = regex.exec(str);
if (match)
{
this.name = match[1] || '';
this.email = match[2] || '';
this.clearDuplicateName();
}
else if ((/^[^@]+@[^@]+$/).test(str))
{
this.name = '';
this.email = str;
}
}
/**
* @param {AjaxJsonEmail} oJsonEmail
* @returns {boolean}
*/
initByJson(json) {
let result = false;
if (json && 'Object/Email' === json['@Object'])
{
this.name = trim(json.Name);
this.email = trim(json.Email);
this.dkimStatus = trim(json.DkimStatus || '');
this.dkimValue = trim(json.DkimValue || '');
result = '' !== this.email;
this.clearDuplicateName();
}
return result;
}
/**
* @param {boolean} friendlyView
* @param {boolean=} wrapWithLink = false
* @param {boolean=} useEncodeHtml = false
* @returns {string}
*/
toLine(friendlyView, wrapWithLink = false, useEncodeHtml = false) {
let result = '';
if ('' !== this.email)
{
if (friendlyView && '' !== this.name)
{
result = wrapWithLink ? '<a href="mailto:' + encodeHtml('"' + this.name + '" <' + this.email + '>') +
'" target="_blank" tabindex="-1">' + encodeHtml(this.name) + '</a>' : (encodeHtml ? encodeHtml(this.name) : this.name);
}
else
{
result = this.email;
if ('' !== this.name)
{
if (wrapWithLink)
{
result = encodeHtml('"' + this.name + '" <') + '<a href="mailto:' +
encodeHtml('"' + this.name + '" <' + this.email + '>') +
'" target="_blank" tabindex="-1">' +
encodeHtml(result) +
'</a>' +
encodeHtml('>');
}
else
{
result = '"' + this.name + '" <' + result + '>';
if (useEncodeHtml)
{
result = encodeHtml(result);
}
}
}
else if (wrapWithLink)
{
result = '<a href="mailto:' + encodeHtml(this.email) + '" target="_blank" tabindex="-1">' + encodeHtml(this.email) + '</a>';
}
}
}
return result;
}
/**
* @param {string} $sEmailAddress
* @returns {boolean}
*/
mailsoParse($sEmailAddress) {
$sEmailAddress = trim($sEmailAddress);
if ('' === $sEmailAddress)
{
return false;
}
var
substr = function(str, start, len) {
str = pString(str);
var end = str.length;
if (0 > start)
{
start += end;
}
end = 'undefined' === typeof len ? end : (0 > len ? len + end : len + start);
return start >= str.length || 0 > start || start > end ? false : str.slice(start, end);
},
substrReplace = function(str, replace, start, length) {
str = pString(str);
if (0 > start)
{
start += str.length;
}
length = 'undefined' !== typeof length ? length : str.length;
if (0 > length)
{
length = length + str.length - start;
}
return str.slice(0, start) + replace.substr(0, length) + replace.slice(length) + str.slice(start + length);
},
$sName = '',
$sEmail = '',
$sComment = '',
$bInName = false,
$bInAddress = false,
$bInComment = false,
$aRegs = null,
$iStartIndex = 0,
$iEndIndex = 0,
$iCurrentIndex = 0;
while ($iCurrentIndex < $sEmailAddress.length)
{
switch ($sEmailAddress.substr($iCurrentIndex, 1))
{
case '"':
if ((!$bInName) && (!$bInAddress) && (!$bInComment))
{
$bInName = true;
$iStartIndex = $iCurrentIndex;
}
else if ((!$bInAddress) && (!$bInComment))
{
$iEndIndex = $iCurrentIndex;
$sName = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
$sEmailAddress = substrReplace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
$iEndIndex = 0;
$iCurrentIndex = 0;
$iStartIndex = 0;
$bInName = false;
}
break;
case '<':
if ((!$bInName) && (!$bInAddress) && (!$bInComment))
{
if (0 < $iCurrentIndex && 0 === $sName.length)
{
$sName = substr($sEmailAddress, 0, $iCurrentIndex);
}
$bInAddress = true;
$iStartIndex = $iCurrentIndex;
}
break;
case '>':
if ($bInAddress)
{
$iEndIndex = $iCurrentIndex;
$sEmail = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
$sEmailAddress = substrReplace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
$iEndIndex = 0;
$iCurrentIndex = 0;
$iStartIndex = 0;
$bInAddress = false;
}
break;
case '(':
if ((!$bInName) && (!$bInAddress) && (!$bInComment))
{
$bInComment = true;
$iStartIndex = $iCurrentIndex;
}
break;
case ')':
if ($bInComment)
{
$iEndIndex = $iCurrentIndex;
$sComment = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
$sEmailAddress = substrReplace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
$iEndIndex = 0;
$iCurrentIndex = 0;
$iStartIndex = 0;
$bInComment = false;
}
break;
case '\\':
$iCurrentIndex += 1;
break;
// no default
}
$iCurrentIndex += 1;
}
if (0 === $sEmail.length)
{
$aRegs = $sEmailAddress.match(/[^@\s]+@\S+/i);
if ($aRegs && $aRegs[0])
{
$sEmail = $aRegs[0];
}
else
{
$sName = $sEmailAddress;
}
}
if (0 < $sEmail.length && 0 === $sName.length && 0 === $sComment.length)
{
$sName = $sEmailAddress.replace($sEmail, '');
}
$sEmail = trim($sEmail).replace(/^[<]+/, '').replace(/[>]+$/, '');
$sName = trim($sName).replace(/^["']+/, '').replace(/["']+$/, '');
$sComment = trim($sComment).replace(/^[(]+/, '').replace(/[)]+$/, '');
// Remove backslash
$sName = $sName.replace(/\\\\(.)/g, '$1');
$sComment = $sComment.replace(/\\\\(.)/g, '$1');
this.name = $sName;
this.email = $sEmail;
this.clearDuplicateName();
return true;
}
}
export {EmailModel, EmailModel as default};

View file

@ -1,318 +0,0 @@
var
_ = require('_'),
ko = require('ko'),
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
Translator = require('Common/Translator'),
Cache = require('Common/Cache'),
FilterConditionModel = require('Model/FilterCondition'),
AbstractModel = require('Knoin/AbstractModel');
/**
* @constructor
*/
function FilterModel()
{
AbstractModel.call(this, 'FilterModel');
this.enabled = ko.observable(true);
this.id = '';
this.name = ko.observable('');
this.name.error = ko.observable(false);
this.name.focused = ko.observable(false);
this.conditions = ko.observableArray([]);
this.conditionsType = ko.observable(Enums.FilterRulesType.Any);
// Actions
this.actionValue = ko.observable('');
this.actionValue.error = ko.observable(false);
this.actionValueSecond = ko.observable('');
this.actionValueThird = ko.observable('');
this.actionValueFourth = ko.observable('');
this.actionValueFourth.error = ko.observable(false);
this.actionMarkAsRead = ko.observable(false);
this.actionKeep = ko.observable(true);
this.actionNoStop = ko.observable(false);
this.actionType = ko.observable(Enums.FiltersAction.MoveTo);
this.actionType.subscribe(function() {
this.actionValue('');
this.actionValue.error(false);
this.actionValueSecond('');
this.actionValueThird('');
this.actionValueFourth('');
this.actionValueFourth.error(false);
}, this);
var fGetRealFolderName = function(sFolderFullNameRaw) {
var oFolder = Cache.getFolderFromCacheList(sFolderFullNameRaw);
return oFolder ? oFolder.fullName.replace(
'.' === oFolder.delimiter ? /\./ : /[\\\/]+/, ' / ') : sFolderFullNameRaw;
};
this.nameSub = ko.computed(function() {
var
sResult = '',
sActionValue = this.actionValue();
switch (this.actionType())
{
case Enums.FiltersAction.MoveTo:
sResult = Translator.i18n('SETTINGS_FILTERS/SUBNAME_MOVE_TO', {
FOLDER: fGetRealFolderName(sActionValue)
});
break;
case Enums.FiltersAction.Forward:
sResult = Translator.i18n('SETTINGS_FILTERS/SUBNAME_FORWARD_TO', {
EMAIL: sActionValue
});
break;
case Enums.FiltersAction.Vacation:
sResult = Translator.i18n('SETTINGS_FILTERS/SUBNAME_VACATION_MESSAGE');
break;
case Enums.FiltersAction.Reject:
sResult = Translator.i18n('SETTINGS_FILTERS/SUBNAME_REJECT');
break;
case Enums.FiltersAction.Discard:
sResult = Translator.i18n('SETTINGS_FILTERS/SUBNAME_DISCARD');
break;
// no default
}
return sResult ? '(' + sResult + ')' : '';
}, this);
this.actionTemplate = ko.computed(function() {
var sTemplate = '';
switch (this.actionType())
{
case Enums.FiltersAction.Forward:
sTemplate = 'SettingsFiltersActionForward';
break;
case Enums.FiltersAction.Vacation:
sTemplate = 'SettingsFiltersActionVacation';
break;
case Enums.FiltersAction.Reject:
sTemplate = 'SettingsFiltersActionReject';
break;
case Enums.FiltersAction.None:
sTemplate = 'SettingsFiltersActionNone';
break;
case Enums.FiltersAction.Discard:
sTemplate = 'SettingsFiltersActionDiscard';
break;
case Enums.FiltersAction.MoveTo:
default:
sTemplate = 'SettingsFiltersActionMoveToFolder';
break;
}
return sTemplate;
}, this);
this.regDisposables(this.conditions.subscribe(Utils.windowResizeCallback));
this.regDisposables(this.name.subscribe(function(sValue) {
this.name.error('' === sValue);
}, this));
this.regDisposables(this.actionValue.subscribe(function(sValue) {
this.actionValue.error('' === sValue);
}, this));
this.regDisposables([this.actionNoStop, this.actionTemplate]);
this.deleteAccess = ko.observable(false);
this.canBeDeleted = ko.observable(true);
}
_.extend(FilterModel.prototype, AbstractModel.prototype);
FilterModel.prototype.generateID = function()
{
this.id = Utils.fakeMd5();
};
FilterModel.prototype.verify = function()
{
if ('' === this.name())
{
this.name.error(true);
return false;
}
if (0 < this.conditions().length)
{
if (_.find(this.conditions(), function(oCond) {
return oCond && !oCond.verify();
}))
{
return false;
}
}
if ('' === this.actionValue())
{
if (-1 < Utils.inArray(this.actionType(), [
Enums.FiltersAction.MoveTo,
Enums.FiltersAction.Forward,
Enums.FiltersAction.Reject,
Enums.FiltersAction.Vacation
]))
{
this.actionValue.error(true);
return false;
}
}
if (Enums.FiltersAction.Forward === this.actionType() &&
-1 === this.actionValue().indexOf('@'))
{
this.actionValue.error(true);
return false;
}
if (Enums.FiltersAction.Vacation === this.actionType() &&
'' !== this.actionValueFourth() && -1 === this.actionValueFourth().indexOf('@')
)
{
this.actionValueFourth.error(true);
return false;
}
this.name.error(false);
this.actionValue.error(false);
return true;
};
FilterModel.prototype.toJson = function()
{
return {
ID: this.id,
Enabled: this.enabled() ? '1' : '0',
Name: this.name(),
ConditionsType: this.conditionsType(),
Conditions: _.map(this.conditions(), function(oItem) {
return oItem.toJson();
}),
ActionValue: this.actionValue(),
ActionValueSecond: this.actionValueSecond(),
ActionValueThird: this.actionValueThird(),
ActionValueFourth: this.actionValueFourth(),
ActionType: this.actionType(),
Stop: this.actionNoStop() ? '0' : '1',
Keep: this.actionKeep() ? '1' : '0',
MarkAsRead: this.actionMarkAsRead() ? '1' : '0'
};
};
FilterModel.prototype.addCondition = function()
{
this.conditions.push(new FilterConditionModel());
};
FilterModel.prototype.removeCondition = function(oConditionToDelete)
{
this.conditions.remove(oConditionToDelete);
Utils.delegateRunOnDestroy(oConditionToDelete);
};
FilterModel.prototype.setRecipients = function()
{
this.actionValueFourth(require('Stores/User/Account').accountsEmails().join(', '));
};
FilterModel.prototype.parse = function(oItem)
{
var bResult = false;
if (oItem && 'Object/Filter' === oItem['@Object'])
{
this.id = Utils.pString(oItem.ID);
this.name(Utils.pString(oItem.Name));
this.enabled(!!oItem.Enabled);
this.conditionsType(Utils.pString(oItem.ConditionsType));
this.conditions([]);
if (Utils.isNonEmptyArray(oItem.Conditions))
{
this.conditions(_.compact(_.map(oItem.Conditions, function(aData) {
var oFilterCondition = new FilterConditionModel();
return oFilterCondition && oFilterCondition.parse(aData) ?
oFilterCondition : null;
})));
}
this.actionType(Utils.pString(oItem.ActionType));
this.actionValue(Utils.pString(oItem.ActionValue));
this.actionValueSecond(Utils.pString(oItem.ActionValueSecond));
this.actionValueThird(Utils.pString(oItem.ActionValueThird));
this.actionValueFourth(Utils.pString(oItem.ActionValueFourth));
this.actionNoStop(!oItem.Stop);
this.actionKeep(!!oItem.Keep);
this.actionMarkAsRead(!!oItem.MarkAsRead);
bResult = true;
}
return bResult;
};
FilterModel.prototype.cloneSelf = function()
{
var oClone = new FilterModel();
oClone.id = this.id;
oClone.enabled(this.enabled());
oClone.name(this.name());
oClone.name.error(this.name.error());
oClone.conditionsType(this.conditionsType());
oClone.actionMarkAsRead(this.actionMarkAsRead());
oClone.actionType(this.actionType());
oClone.actionValue(this.actionValue());
oClone.actionValue.error(this.actionValue.error());
oClone.actionValueSecond(this.actionValueSecond());
oClone.actionValueThird(this.actionValueThird());
oClone.actionValueFourth(this.actionValueFourth());
oClone.actionKeep(this.actionKeep());
oClone.actionNoStop(this.actionNoStop());
oClone.conditions(_.map(this.conditions(), function(oCondition) {
return oCondition.cloneSelf();
}));
return oClone;
};
module.exports = FilterModel;

292
dev/Model/Filter.jsx Normal file
View file

@ -0,0 +1,292 @@
import _ from '_';
import ko from 'ko';
import {FilterRulesType, FiltersAction} from 'Common/Enums';
import {pString, inArray, isNonEmptyArray, fakeMd5, delegateRunOnDestroy, windowResizeCallback} from 'Common/Utils';
import {i18n} from 'Common/Translator';
import {getFolderFromCacheList} from 'Common/Cache';
import {FilterConditionModel} from 'Model/FilterCondition';
import {AbstractModel} from 'Knoin/AbstractModel';
class FilterModel extends AbstractModel
{
constructor()
{
super('FilterModel');
this.enabled = ko.observable(true);
this.id = '';
this.name = ko.observable('');
this.name.error = ko.observable(false);
this.name.focused = ko.observable(false);
this.conditions = ko.observableArray([]);
this.conditionsType = ko.observable(FilterRulesType.Any);
// Actions
this.actionValue = ko.observable('');
this.actionValue.error = ko.observable(false);
this.actionValueSecond = ko.observable('');
this.actionValueThird = ko.observable('');
this.actionValueFourth = ko.observable('');
this.actionValueFourth.error = ko.observable(false);
this.actionMarkAsRead = ko.observable(false);
this.actionKeep = ko.observable(true);
this.actionNoStop = ko.observable(false);
this.actionType = ko.observable(FiltersAction.MoveTo);
this.actionType.subscribe(() => {
this.actionValue('');
this.actionValue.error(false);
this.actionValueSecond('');
this.actionValueThird('');
this.actionValueFourth('');
this.actionValueFourth.error(false);
});
const fGetRealFolderName = (folderFullNameRaw) => {
const folder = getFolderFromCacheList(folderFullNameRaw);
return folder ? folder.fullName.replace('.' === folder.delimiter ? /\./ : /[\\\/]+/, ' / ') : folderFullNameRaw;
};
this.nameSub = ko.computed(() => {
let result = '';
const actionValue = this.actionValue();
switch (this.actionType())
{
case FiltersAction.MoveTo:
result = i18n('SETTINGS_FILTERS/SUBNAME_MOVE_TO', {
FOLDER: fGetRealFolderName(actionValue)
});
break;
case FiltersAction.Forward:
result = i18n('SETTINGS_FILTERS/SUBNAME_FORWARD_TO', {
EMAIL: actionValue
});
break;
case FiltersAction.Vacation:
result = i18n('SETTINGS_FILTERS/SUBNAME_VACATION_MESSAGE');
break;
case FiltersAction.Reject:
result = i18n('SETTINGS_FILTERS/SUBNAME_REJECT');
break;
case FiltersAction.Discard:
result = i18n('SETTINGS_FILTERS/SUBNAME_DISCARD');
break;
// no default
}
return result ? '(' + result + ')' : '';
});
this.actionTemplate = ko.computed(() => {
let result = '';
switch (this.actionType())
{
case FiltersAction.Forward:
result = 'SettingsFiltersActionForward';
break;
case FiltersAction.Vacation:
result = 'SettingsFiltersActionVacation';
break;
case FiltersAction.Reject:
result = 'SettingsFiltersActionReject';
break;
case FiltersAction.None:
result = 'SettingsFiltersActionNone';
break;
case FiltersAction.Discard:
result = 'SettingsFiltersActionDiscard';
break;
case FiltersAction.MoveTo:
default:
result = 'SettingsFiltersActionMoveToFolder';
break;
}
return result;
});
this.regDisposables(this.conditions.subscribe(windowResizeCallback));
this.regDisposables(this.name.subscribe((sValue) => {
this.name.error('' === sValue);
}));
this.regDisposables(this.actionValue.subscribe((sValue) => {
this.actionValue.error('' === sValue);
}));
this.regDisposables([this.actionNoStop, this.actionTemplate]);
this.deleteAccess = ko.observable(false);
this.canBeDeleted = ko.observable(true);
}
generateID() {
this.id = fakeMd5();
}
verify() {
if ('' === this.name())
{
this.name.error(true);
return false;
}
if (0 < this.conditions().length)
{
if (_.find(this.conditions(), (cond) => cond && !cond.verify()))
{
return false;
}
}
if ('' === this.actionValue())
{
if (-1 < inArray(this.actionType(), [
FiltersAction.MoveTo, FiltersAction.Forward, FiltersAction.Reject, FiltersAction.Vacation
]))
{
this.actionValue.error(true);
return false;
}
}
if (FiltersAction.Forward === this.actionType() &&
-1 === this.actionValue().indexOf('@'))
{
this.actionValue.error(true);
return false;
}
if (FiltersAction.Vacation === this.actionType() &&
'' !== this.actionValueFourth() && -1 === this.actionValueFourth().indexOf('@')
)
{
this.actionValueFourth.error(true);
return false;
}
this.name.error(false);
this.actionValue.error(false);
return true;
}
toJson() {
return {
ID: this.id,
Enabled: this.enabled() ? '1' : '0',
Name: this.name(),
ConditionsType: this.conditionsType(),
Conditions: _.map(this.conditions(), function(oItem) {
return oItem.toJson();
}),
ActionValue: this.actionValue(),
ActionValueSecond: this.actionValueSecond(),
ActionValueThird: this.actionValueThird(),
ActionValueFourth: this.actionValueFourth(),
ActionType: this.actionType(),
Stop: this.actionNoStop() ? '0' : '1',
Keep: this.actionKeep() ? '1' : '0',
MarkAsRead: this.actionMarkAsRead() ? '1' : '0'
};
}
addCondition() {
this.conditions.push(new FilterConditionModel());
}
removeCondition(oConditionToDelete) {
this.conditions.remove(oConditionToDelete);
delegateRunOnDestroy(oConditionToDelete);
}
setRecipients() {
this.actionValueFourth(require('Stores/User/Account').accountsEmails().join(', '));
}
parse(json) {
let result = false;
if (json && 'Object/Filter' === json['@Object'])
{
this.id = pString(json.ID);
this.name(pString(json.Name));
this.enabled(!!json.Enabled);
this.conditionsType(pString(json.ConditionsType));
this.conditions([]);
if (isNonEmptyArray(json.Conditions))
{
this.conditions(_.compact(_.map(json.Conditions, (aData) => {
const filterCondition = new FilterConditionModel();
return filterCondition && filterCondition.parse(aData) ? filterCondition : null;
})));
}
this.actionType(pString(json.ActionType));
this.actionValue(pString(json.ActionValue));
this.actionValueSecond(pString(json.ActionValueSecond));
this.actionValueThird(pString(json.ActionValueThird));
this.actionValueFourth(pString(json.ActionValueFourth));
this.actionNoStop(!json.Stop);
this.actionKeep(!!json.Keep);
this.actionMarkAsRead(!!json.MarkAsRead);
result = true;
}
return result;
}
cloneSelf() {
var filter = new FilterModel();
filter.id = this.id;
filter.enabled(this.enabled());
filter.name(this.name());
filter.name.error(this.name.error());
filter.conditionsType(this.conditionsType());
filter.actionMarkAsRead(this.actionMarkAsRead());
filter.actionType(this.actionType());
filter.actionValue(this.actionValue());
filter.actionValue.error(this.actionValue.error());
filter.actionValueSecond(this.actionValueSecond());
filter.actionValueThird(this.actionValueThird());
filter.actionValueFourth(this.actionValueFourth());
filter.actionKeep(this.actionKeep());
filter.actionNoStop(this.actionNoStop());
filter.conditions(_.map(this.conditions(), (item) => item.cloneSelf()));
return filter;
}
}
export {FilterModel, FilterModel as default};

View file

@ -1,110 +0,0 @@
var
_ = require('_'),
ko = require('ko'),
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
AbstractModel = require('Knoin/AbstractModel');
/**
* @constructor
*/
function FilterConditionModel()
{
AbstractModel.call(this, 'FilterConditionModel');
this.field = ko.observable(Enums.FilterConditionField.From);
this.type = ko.observable(Enums.FilterConditionType.Contains);
this.value = ko.observable('');
this.value.error = ko.observable(false);
this.valueSecond = ko.observable('');
this.valueSecond.error = ko.observable(false);
this.template = ko.computed(function() {
var sTemplate = '';
switch (this.field())
{
case Enums.FilterConditionField.Size:
sTemplate = 'SettingsFiltersConditionSize';
break;
case Enums.FilterConditionField.Header:
sTemplate = 'SettingsFiltersConditionMore';
break;
default:
sTemplate = 'SettingsFiltersConditionDefault';
break;
}
return sTemplate;
}, this);
this.field.subscribe(function() {
this.value('');
this.valueSecond('');
}, this);
this.regDisposables([this.template]);
}
_.extend(FilterConditionModel.prototype, AbstractModel.prototype);
FilterConditionModel.prototype.verify = function()
{
if ('' === this.value())
{
this.value.error(true);
return false;
}
if (Enums.FilterConditionField.Header === this.field() && '' === this.valueSecond())
{
this.valueSecond.error(true);
return false;
}
return true;
};
FilterConditionModel.prototype.parse = function(oItem)
{
if (oItem && oItem.Field && oItem.Type)
{
this.field(Utils.pString(oItem.Field));
this.type(Utils.pString(oItem.Type));
this.value(Utils.pString(oItem.Value));
this.valueSecond(Utils.pString(oItem.ValueSecond));
return true;
}
return false;
};
FilterConditionModel.prototype.toJson = function()
{
return {
Field: this.field(),
Type: this.type(),
Value: this.value(),
ValueSecond: this.valueSecond()
};
};
FilterConditionModel.prototype.cloneSelf = function()
{
var oClone = new FilterConditionModel();
oClone.field(this.field());
oClone.type(this.type());
oClone.value(this.value());
oClone.valueSecond(this.valueSecond());
return oClone;
};
module.exports = FilterConditionModel;

View file

@ -0,0 +1,102 @@
import ko from 'ko';
import {FilterConditionField, FilterConditionType} from 'Common/Enums';
import {pString} from 'Common/Utils';
import {AbstractModel} from 'Knoin/AbstractModel';
class FilterConditionModel extends AbstractModel
{
constructor()
{
super('FilterConditionModel');
this.field = ko.observable(FilterConditionField.From);
this.type = ko.observable(FilterConditionType.Contains);
this.value = ko.observable('');
this.value.error = ko.observable(false);
this.valueSecond = ko.observable('');
this.valueSecond.error = ko.observable(false);
this.template = ko.computed(function() {
var sTemplate = '';
switch (this.field())
{
case FilterConditionField.Size:
sTemplate = 'SettingsFiltersConditionSize';
break;
case FilterConditionField.Header:
sTemplate = 'SettingsFiltersConditionMore';
break;
default:
sTemplate = 'SettingsFiltersConditionDefault';
break;
}
return sTemplate;
}, this);
this.field.subscribe(function() {
this.value('');
this.valueSecond('');
}, this);
this.regDisposables([this.template]);
}
verify() {
if ('' === this.value())
{
this.value.error(true);
return false;
}
if (FilterConditionField.Header === this.field() && '' === this.valueSecond())
{
this.valueSecond.error(true);
return false;
}
return true;
}
parse(json) {
if (json && json.Field && json.Type)
{
this.field(pString(json.Field));
this.type(pString(json.Type));
this.value(pString(json.Value));
this.valueSecond(pString(json.ValueSecond));
return true;
}
return false;
}
toJson() {
return {
Field: this.field(),
Type: this.type(),
Value: this.value(),
ValueSecond: this.valueSecond()
};
}
cloneSelf() {
const filterCond = new FilterConditionModel();
filterCond.field(this.field());
filterCond.type(this.type());
filterCond.value(this.value());
filterCond.valueSecond(this.valueSecond());
return filterCond;
}
}
export {FilterConditionModel, FilterConditionModel as default};

View file

@ -1,367 +0,0 @@
var
_ = require('_'),
ko = require('ko'),
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
Events = require('Common/Events'),
Translator = require('Common/Translator'),
Cache = require('Common/Cache'),
AbstractModel = require('Knoin/AbstractModel');
/**
* @constructor
*/
function FolderModel()
{
AbstractModel.call(this, 'FolderModel');
this.name = ko.observable('');
this.fullName = '';
this.fullNameRaw = '';
this.fullNameHash = '';
this.delimiter = '';
this.namespace = '';
this.deep = 0;
this.interval = 0;
this.selectable = false;
this.existen = true;
this.type = ko.observable(Enums.FolderType.User);
this.focused = ko.observable(false);
this.selected = ko.observable(false);
this.edited = ko.observable(false);
this.collapsed = ko.observable(true);
this.subScribed = ko.observable(true);
this.checkable = ko.observable(false);
this.subFolders = ko.observableArray([]);
this.deleteAccess = ko.observable(false);
this.actionBlink = ko.observable(false).extend({'falseTimeout': 1000});
this.nameForEdit = ko.observable('');
this.privateMessageCountAll = ko.observable(0);
this.privateMessageCountUnread = ko.observable(0);
this.collapsedPrivate = ko.observable(true);
}
_.extend(FolderModel.prototype, AbstractModel.prototype);
/**
* @static
* @param {AjaxJsonFolder} oJsonFolder
* @returns {?FolderModel}
*/
FolderModel.newInstanceFromJson = function(oJsonFolder)
{
var oFolderModel = new FolderModel();
return oFolderModel.initByJson(oJsonFolder) ? oFolderModel.initComputed() : null;
};
/**
* @returns {FolderModel}
*/
FolderModel.prototype.initComputed = function()
{
var sInboxFolderName = Cache.getFolderInboxName();
this.isInbox = ko.computed(function() {
return Enums.FolderType.Inbox === this.type();
}, this);
this.hasSubScribedSubfolders = ko.computed(function() {
return !!_.find(this.subFolders(), function(oFolder) {
return (oFolder.subScribed() || oFolder.hasSubScribedSubfolders()) && !oFolder.isSystemFolder();
});
}, this);
this.canBeEdited = ko.computed(function() {
return Enums.FolderType.User === this.type() && this.existen && this.selectable;
}, this);
this.visible = ko.computed(function() {
var
bSubScribed = this.subScribed(),
bSubFolders = this.hasSubScribedSubfolders();
return (bSubScribed || (bSubFolders && (!this.existen || !this.selectable)));
}, this);
this.isSystemFolder = ko.computed(function() {
return Enums.FolderType.User !== this.type();
}, this);
this.hidden = ko.computed(function() {
var
bSystem = this.isSystemFolder(),
bSubFolders = this.hasSubScribedSubfolders();
return (bSystem && !bSubFolders) || (!this.selectable && !bSubFolders);
}, this);
this.selectableForFolderList = ko.computed(function() {
return !this.isSystemFolder() && this.selectable;
}, this);
this.messageCountAll = ko.computed({
'read': this.privateMessageCountAll,
'write': function(iValue) {
if (Utils.isPosNumeric(iValue, true))
{
this.privateMessageCountAll(iValue);
}
else
{
this.privateMessageCountAll.valueHasMutated();
}
},
'owner': this
}).extend({'notify': 'always'});
this.messageCountUnread = ko.computed({
'read': this.privateMessageCountUnread,
'write': function(iValue) {
if (Utils.isPosNumeric(iValue, true))
{
this.privateMessageCountUnread(iValue);
}
else
{
this.privateMessageCountUnread.valueHasMutated();
}
},
'owner': this
}).extend({'notify': 'always'});
this.printableUnreadCount = ko.computed(function() {
var
iCount = this.messageCountAll(),
iUnread = this.messageCountUnread(),
iType = this.type();
if (0 < iCount)
{
if (Enums.FolderType.Draft === iType)
{
return '' + iCount;
}
else if (0 < iUnread && Enums.FolderType.Trash !== iType && Enums.FolderType.Archive !== iType && Enums.FolderType.SentItems !== iType)
{
return '' + iUnread;
}
}
return '';
}, this);
this.canBeDeleted = ko.computed(function() {
var
bSystem = this.isSystemFolder();
return !bSystem && 0 === this.subFolders().length && sInboxFolderName !== this.fullNameRaw;
}, this);
this.canBeSubScribed = ko.computed(function() {
return !this.isSystemFolder() && this.selectable && sInboxFolderName !== this.fullNameRaw;
}, this);
this.canBeChecked = this.canBeSubScribed;
// this.visible.subscribe(function() {
// Utils.timeOutAction('folder-list-folder-visibility-change', function() {
// Globals.$win.trigger('folder-list-folder-visibility-change');
// }, 100);
// });
this.localName = ko.computed(function() {
Translator.trigger();
var
iType = this.type(),
sName = this.name();
if (this.isSystemFolder())
{
switch (iType)
{
case Enums.FolderType.Inbox:
sName = Translator.i18n('FOLDER_LIST/INBOX_NAME');
break;
case Enums.FolderType.SentItems:
sName = Translator.i18n('FOLDER_LIST/SENT_NAME');
break;
case Enums.FolderType.Draft:
sName = Translator.i18n('FOLDER_LIST/DRAFTS_NAME');
break;
case Enums.FolderType.Spam:
sName = Translator.i18n('FOLDER_LIST/SPAM_NAME');
break;
case Enums.FolderType.Trash:
sName = Translator.i18n('FOLDER_LIST/TRASH_NAME');
break;
case Enums.FolderType.Archive:
sName = Translator.i18n('FOLDER_LIST/ARCHIVE_NAME');
break;
// no default
}
}
return sName;
}, this);
this.manageFolderSystemName = ko.computed(function() {
Translator.trigger();
var
sSuffix = '',
iType = this.type(),
sName = this.name();
if (this.isSystemFolder())
{
switch (iType)
{
case Enums.FolderType.Inbox:
sSuffix = '(' + Translator.i18n('FOLDER_LIST/INBOX_NAME') + ')';
break;
case Enums.FolderType.SentItems:
sSuffix = '(' + Translator.i18n('FOLDER_LIST/SENT_NAME') + ')';
break;
case Enums.FolderType.Draft:
sSuffix = '(' + Translator.i18n('FOLDER_LIST/DRAFTS_NAME') + ')';
break;
case Enums.FolderType.Spam:
sSuffix = '(' + Translator.i18n('FOLDER_LIST/SPAM_NAME') + ')';
break;
case Enums.FolderType.Trash:
sSuffix = '(' + Translator.i18n('FOLDER_LIST/TRASH_NAME') + ')';
break;
case Enums.FolderType.Archive:
sSuffix = '(' + Translator.i18n('FOLDER_LIST/ARCHIVE_NAME') + ')';
break;
// no default
}
}
if ('' !== sSuffix && '(' + sName + ')' === sSuffix || '(inbox)' === sSuffix.toLowerCase())
{
sSuffix = '';
}
return sSuffix;
}, this);
this.collapsed = ko.computed({
'read': function() {
return !this.hidden() && this.collapsedPrivate();
},
'write': function(mValue) {
this.collapsedPrivate(mValue);
},
'owner': this
});
this.hasUnreadMessages = ko.computed(function() {
return 0 < this.messageCountUnread() && '' !== this.printableUnreadCount();
}, this);
this.hasSubScribedUnreadMessagesSubfolders = ko.computed(function() {
return !!_.find(this.subFolders(), function(oFolder) {
return oFolder.hasUnreadMessages() || oFolder.hasSubScribedUnreadMessagesSubfolders();
});
}, this);
// subscribe
this.name.subscribe(function(sValue) {
this.nameForEdit(sValue);
}, this);
this.edited.subscribe(function(bValue) {
if (bValue)
{
this.nameForEdit(this.name());
}
}, this);
this.messageCountUnread.subscribe(function(iUnread) {
if (Enums.FolderType.Inbox === this.type())
{
Events.pub('mailbox.inbox-unread-count', [iUnread]);
}
}, this);
return this;
};
FolderModel.prototype.fullName = '';
FolderModel.prototype.fullNameRaw = '';
FolderModel.prototype.fullNameHash = '';
FolderModel.prototype.delimiter = '';
FolderModel.prototype.namespace = '';
FolderModel.prototype.deep = 0;
FolderModel.prototype.interval = 0;
/**
* @returns {string}
*/
FolderModel.prototype.collapsedCss = function()
{
return this.hasSubScribedSubfolders() ?
(this.collapsed() ? 'icon-right-mini e-collapsed-sign' : 'icon-down-mini e-collapsed-sign') : 'icon-none e-collapsed-sign';
};
/**
* @param {AjaxJsonFolder} oJsonFolder
* @returns {boolean}
*/
FolderModel.prototype.initByJson = function(oJsonFolder)
{
var
bResult = false,
sInboxFolderName = Cache.getFolderInboxName();
if (oJsonFolder && 'Object/Folder' === oJsonFolder['@Object'])
{
this.name(oJsonFolder.Name);
this.delimiter = oJsonFolder.Delimiter;
this.fullName = oJsonFolder.FullName;
this.fullNameRaw = oJsonFolder.FullNameRaw;
this.fullNameHash = oJsonFolder.FullNameHash;
this.deep = oJsonFolder.FullNameRaw.split(this.delimiter).length - 1;
this.selectable = !!oJsonFolder.IsSelectable;
this.existen = !!oJsonFolder.IsExists;
this.subScribed(!!oJsonFolder.IsSubscribed);
this.checkable(!!oJsonFolder.Checkable);
this.type(sInboxFolderName === this.fullNameRaw ? Enums.FolderType.Inbox : Enums.FolderType.User);
bResult = true;
}
return bResult;
};
/**
* @returns {string}
*/
FolderModel.prototype.printableFullName = function()
{
return this.fullName.split(this.delimiter).join(' / ');
};
module.exports = FolderModel;

313
dev/Model/Folder.jsx Normal file
View file

@ -0,0 +1,313 @@
import _ from '_';
import ko from 'ko';
import {FolderType} from 'Common/Enums';
import {isPosNumeric} from 'Common/Utils';
import {i18n, trigger as translatorTrigger} from 'Common/Translator';
import {getFolderInboxName} from 'Common/Cache';
import * as Events from 'Common/Events';
import {AbstractModel} from 'Knoin/AbstractModel';
class FolderModel extends AbstractModel
{
constructor()
{
super('FolderModel');
this.name = ko.observable('');
this.fullName = '';
this.fullNameRaw = '';
this.fullNameHash = '';
this.delimiter = '';
this.namespace = '';
this.deep = 0;
this.interval = 0;
this.selectable = false;
this.existen = true;
this.type = ko.observable(FolderType.User);
this.focused = ko.observable(false);
this.selected = ko.observable(false);
this.edited = ko.observable(false);
this.collapsed = ko.observable(true);
this.subScribed = ko.observable(true);
this.checkable = ko.observable(false);
this.subFolders = ko.observableArray([]);
this.deleteAccess = ko.observable(false);
this.actionBlink = ko.observable(false).extend({falseTimeout: 1000});
this.nameForEdit = ko.observable('');
this.privateMessageCountAll = ko.observable(0);
this.privateMessageCountUnread = ko.observable(0);
this.collapsedPrivate = ko.observable(true);
}
/**
* @static
* @param {AjaxJsonFolder} json
* @returns {?FolderModel}
*/
static newInstanceFromJson(json) {
const folder = new FolderModel();
return folder.initByJson(json) ? folder.initComputed() : null;
}
/**
* @returns {FolderModel}
*/
initComputed() {
const inboxFolderName = getFolderInboxName();
this.isInbox = ko.computed(() => FolderType.Inbox === this.type());
this.hasSubScribedSubfolders = ko.computed(function() {
return !!_.find(this.subFolders(), (oFolder) => (oFolder.subScribed() || oFolder.hasSubScribedSubfolders()) && !oFolder.isSystemFolder());
}, this);
this.canBeEdited = ko.computed(() => FolderType.User === this.type() && this.existen && this.selectable);
this.visible = ko.computed(() => {
const
isSubScribed = this.subScribed(),
isSubFolders = this.hasSubScribedSubfolders();
return (isSubScribed || (isSubFolders && (!this.existen || !this.selectable)));
});
this.isSystemFolder = ko.computed(() => FolderType.User !== this.type());
this.hidden = ko.computed(() => {
const
isSystem = this.isSystemFolder(),
isSubFolders = this.hasSubScribedSubfolders();
return (isSystem && !isSubFolders) || (!this.selectable && !isSubFolders);
});
this.selectableForFolderList = ko.computed(() => !this.isSystemFolder() && this.selectable);
this.messageCountAll = ko.computed({
read: this.privateMessageCountAll,
write: (iValue) => {
if (isPosNumeric(iValue, true))
{
this.privateMessageCountAll(iValue);
}
else
{
this.privateMessageCountAll.valueHasMutated();
}
}
}).extend({notify: 'always'});
this.messageCountUnread = ko.computed({
read: this.privateMessageCountUnread,
write: (value) => {
if (isPosNumeric(value, true))
{
this.privateMessageCountUnread(value);
}
else
{
this.privateMessageCountUnread.valueHasMutated();
}
}
}).extend({notify: 'always'});
this.printableUnreadCount = ko.computed(() => {
const
count = this.messageCountAll(),
unread = this.messageCountUnread(),
type = this.type();
if (0 < count)
{
if (FolderType.Draft === type)
{
return '' + count;
}
else if (0 < unread && FolderType.Trash !== type && FolderType.Archive !== type && FolderType.SentItems !== type)
{
return '' + unread;
}
}
return '';
});
this.canBeDeleted = ko.computed(() => {
const bSystem = this.isSystemFolder();
return !bSystem && 0 === this.subFolders().length && inboxFolderName !== this.fullNameRaw;
});
this.canBeSubScribed = ko.computed(() => !this.isSystemFolder() && this.selectable && inboxFolderName !== this.fullNameRaw);
this.canBeChecked = this.canBeSubScribed;
this.localName = ko.computed(() => {
translatorTrigger();
let name = this.name();
const type = this.type();
if (this.isSystemFolder())
{
switch (type)
{
case FolderType.Inbox:
name = i18n('FOLDER_LIST/INBOX_NAME');
break;
case FolderType.SentItems:
name = i18n('FOLDER_LIST/SENT_NAME');
break;
case FolderType.Draft:
name = i18n('FOLDER_LIST/DRAFTS_NAME');
break;
case FolderType.Spam:
name = i18n('FOLDER_LIST/SPAM_NAME');
break;
case FolderType.Trash:
name = i18n('FOLDER_LIST/TRASH_NAME');
break;
case FolderType.Archive:
name = i18n('FOLDER_LIST/ARCHIVE_NAME');
break;
// no default
}
}
return name;
});
this.manageFolderSystemName = ko.computed(() => {
translatorTrigger();
let suffix = '';
const
type = this.type(),
name = this.name();
if (this.isSystemFolder())
{
switch (type)
{
case FolderType.Inbox:
suffix = '(' + i18n('FOLDER_LIST/INBOX_NAME') + ')';
break;
case FolderType.SentItems:
suffix = '(' + i18n('FOLDER_LIST/SENT_NAME') + ')';
break;
case FolderType.Draft:
suffix = '(' + i18n('FOLDER_LIST/DRAFTS_NAME') + ')';
break;
case FolderType.Spam:
suffix = '(' + i18n('FOLDER_LIST/SPAM_NAME') + ')';
break;
case FolderType.Trash:
suffix = '(' + i18n('FOLDER_LIST/TRASH_NAME') + ')';
break;
case FolderType.Archive:
suffix = '(' + i18n('FOLDER_LIST/ARCHIVE_NAME') + ')';
break;
// no default
}
}
if ('' !== suffix && '(' + name + ')' === suffix || '(inbox)' === suffix.toLowerCase())
{
suffix = '';
}
return suffix;
});
this.collapsed = ko.computed({
read: () => !this.hidden() && this.collapsedPrivate(),
write: (value) => {
this.collapsedPrivate(value);
}
});
this.hasUnreadMessages = ko.computed(() => 0 < this.messageCountUnread() && '' !== this.printableUnreadCount());
this.hasSubScribedUnreadMessagesSubfolders = ko.computed(function() {
return !!_.find(this.subFolders(), (folder) => folder.hasUnreadMessages() || folder.hasSubScribedUnreadMessagesSubfolders());
}, this);
// subscribe
this.name.subscribe((value) => {
this.nameForEdit(value);
});
this.edited.subscribe((value) => {
if (value)
{
this.nameForEdit(this.name());
}
});
this.messageCountUnread.subscribe((unread) => {
if (FolderType.Inbox === this.type())
{
Events.pub('mailbox.inbox-unread-count', [unread]);
}
});
return this;
}
/**
* @returns {string}
*/
collapsedCss() {
return this.hasSubScribedSubfolders() ?
(this.collapsed() ? 'icon-right-mini e-collapsed-sign' : 'icon-down-mini e-collapsed-sign') : 'icon-none e-collapsed-sign';
}
/**
* @param {AjaxJsonFolder} json
* @returns {boolean}
*/
initByJson(json) {
let bResult = false;
const sInboxFolderName = getFolderInboxName();
if (json && 'Object/Folder' === json['@Object'])
{
this.name(json.Name);
this.delimiter = json.Delimiter;
this.fullName = json.FullName;
this.fullNameRaw = json.FullNameRaw;
this.fullNameHash = json.FullNameHash;
this.deep = json.FullNameRaw.split(this.delimiter).length - 1;
this.selectable = !!json.IsSelectable;
this.existen = !!json.IsExists;
this.subScribed(!!json.IsSubscribed);
this.checkable(!!json.Checkable);
this.type(sInboxFolderName === this.fullNameRaw ? FolderType.Inbox : FolderType.User);
bResult = true;
}
return bResult;
}
/**
* @returns {string}
*/
printableFullName() {
return this.fullName.split(this.delimiter).join(' / ');
}
}
export {FolderModel, FolderModel as default};

View file

@ -1,44 +0,0 @@
var
_ = require('_'),
ko = require('ko'),
AbstractModel = require('Knoin/AbstractModel');
/**
* @constructor
* @param {string} sId
* @param {string} sEmail
*/
function IdentityModel(sId, sEmail)
{
AbstractModel.call(this, 'IdentityModel');
this.id = ko.observable(sId || '');
this.email = ko.observable(sEmail);
this.name = ko.observable('');
this.replyTo = ko.observable('');
this.bcc = ko.observable('');
this.signature = ko.observable('');
this.signatureInsertBefore = ko.observable(false);
this.deleteAccess = ko.observable(false);
this.canBeDeleted = ko.computed(function() {
return '' !== this.id();
}, this);
}
_.extend(IdentityModel.prototype, AbstractModel.prototype);
IdentityModel.prototype.formattedName = function()
{
var
sName = this.name(),
sEmail = this.email();
return ('' !== sName) ? sName + ' (' + sEmail + ')' : sEmail;
};
module.exports = IdentityModel;

42
dev/Model/Identity.jsx Normal file
View file

@ -0,0 +1,42 @@
import ko from 'ko';
import {AbstractModel} from 'Knoin/AbstractModel';
class IdentityModel extends AbstractModel
{
/**
* @param {string} id
* @param {string} email
*/
constructor(id, email)
{
super('IdentityModel');
this.id = ko.observable(id || '');
this.email = ko.observable(email);
this.name = ko.observable('');
this.replyTo = ko.observable('');
this.bcc = ko.observable('');
this.signature = ko.observable('');
this.signatureInsertBefore = ko.observable(false);
this.deleteAccess = ko.observable(false);
this.canBeDeleted = ko.computed(() => '' !== this.id());
}
/**
* @returns {string}
*/
formattedName() {
const
name = this.name(),
email = this.email();
return '' !== name ? name + ' (' + email + ')' : email;
}
}
export {IdentityModel, IdentityModel as default};

File diff suppressed because it is too large Load diff

918
dev/Model/Message.jsx Normal file
View file

@ -0,0 +1,918 @@
import _ from '_';
import $ from '$';
import ko from 'ko';
import {MessagePriority, SignedVerifyStatus} from 'Common/Enums';
import {
pInt, inArray, isArray, isUnd, trim,
previewMessage, windowResize, friendlySize, isNonEmptyArray
} from 'Common/Utils';
import {$win} from 'Common/Globals';
import {messageViewLink, messageDownloadLink} from 'Common/Links';
import {emailArrayFromJson, emailArrayToStringClear, emailArrayToString, replyHelper} from 'Helper/Message';
import {AttachmentModel, staticCombinedIconClass} from 'Model/Attachment';
import {AbstractModel} from 'Knoin/AbstractModel';
class MessageModel extends AbstractModel
{
constructor()
{
super('MessageModel');
this.folderFullNameRaw = '';
this.uid = '';
this.hash = '';
this.requestHash = '';
this.subject = ko.observable('');
this.subjectPrefix = ko.observable('');
this.subjectSuffix = ko.observable('');
this.size = ko.observable(0);
this.dateTimeStampInUTC = ko.observable(0);
this.priority = ko.observable(MessagePriority.Normal);
this.proxy = false;
this.fromEmailString = ko.observable('');
this.fromClearEmailString = ko.observable('');
this.toEmailsString = ko.observable('');
this.toClearEmailsString = ko.observable('');
this.senderEmailsString = ko.observable('');
this.senderClearEmailsString = ko.observable('');
this.emails = [];
this.from = [];
this.to = [];
this.cc = [];
this.bcc = [];
this.replyTo = [];
this.deliveredTo = [];
this.newForAnimation = ko.observable(false);
this.deleted = ko.observable(false);
this.deletedMark = ko.observable(false);
this.unseen = ko.observable(false);
this.flagged = ko.observable(false);
this.answered = ko.observable(false);
this.forwarded = ko.observable(false);
this.isReadReceipt = ko.observable(false);
this.focused = ko.observable(false);
this.selected = ko.observable(false);
this.checked = ko.observable(false);
this.hasAttachments = ko.observable(false);
this.attachmentsSpecData = ko.observableArray([]);
this.attachmentIconClass = ko.computed(() => staticCombinedIconClass(this.hasAttachments() ? this.attachmentsSpecData() : []));
this.body = null;
this.isHtml = ko.observable(false);
this.hasImages = ko.observable(false);
this.attachments = ko.observableArray([]);
this.isPgpSigned = ko.observable(false);
this.isPgpEncrypted = ko.observable(false);
this.pgpSignedVerifyStatus = ko.observable(SignedVerifyStatus.None);
this.pgpSignedVerifyUser = ko.observable('');
this.priority = ko.observable(MessagePriority.Normal);
this.readReceipt = ko.observable('');
this.aDraftInfo = [];
this.sMessageId = '';
this.sInReplyTo = '';
this.sReferences = '';
this.hasUnseenSubMessage = ko.observable(false);
this.hasFlaggedSubMessage = ko.observable(false);
this.threads = ko.observableArray([]);
this.threadsLen = ko.computed(() => this.threads().length);
this.isImportant = ko.computed(() => MessagePriority.High === this.priority());
this.regDisposables([this.attachmentIconClass, this.threadsLen, this.isImportant]);
}
/**
* @static
* @param {AjaxJsonMessage} oJsonMessage
* @returns {?MessageModel}
*/
static newInstanceFromJson(json) {
const oMessageModel = new MessageModel();
return oMessageModel.initByJson(json) ? oMessageModel : null;
}
clear() {
this.folderFullNameRaw = '';
this.uid = '';
this.hash = '';
this.requestHash = '';
this.subject('');
this.subjectPrefix('');
this.subjectSuffix('');
this.size(0);
this.dateTimeStampInUTC(0);
this.priority(MessagePriority.Normal);
this.proxy = false;
this.fromEmailString('');
this.fromClearEmailString('');
this.toEmailsString('');
this.toClearEmailsString('');
this.senderEmailsString('');
this.senderClearEmailsString('');
this.emails = [];
this.from = [];
this.to = [];
this.cc = [];
this.bcc = [];
this.replyTo = [];
this.deliveredTo = [];
this.newForAnimation(false);
this.deleted(false);
this.deletedMark(false);
this.unseen(false);
this.flagged(false);
this.answered(false);
this.forwarded(false);
this.isReadReceipt(false);
this.selected(false);
this.checked(false);
this.hasAttachments(false);
this.attachmentsSpecData([]);
this.body = null;
this.isHtml(false);
this.hasImages(false);
this.attachments([]);
this.isPgpSigned(false);
this.isPgpEncrypted(false);
this.pgpSignedVerifyStatus(SignedVerifyStatus.None);
this.pgpSignedVerifyUser('');
this.priority(MessagePriority.Normal);
this.readReceipt('');
this.aDraftInfo = [];
this.sMessageId = '';
this.sInReplyTo = '';
this.sReferences = '';
this.threads([]);
this.hasUnseenSubMessage(false);
this.hasFlaggedSubMessage(false);
}
/**
* @param {Array} properties
* @returns {Array}
*/
getEmails(properties) {
return _.compact(_.uniq(_.map(
_.reduce(properties, (carry, property) => carry.concat(this[property]), []),
(oItem) => (oItem ? oItem.email : '')
)));
}
/**
* @returns {Array}
*/
getRecipientsEmails() {
return this.getEmails(['to', 'cc']);
}
/**
* @returns {string}
*/
friendlySize() {
return friendlySize(this.size());
}
computeSenderEmail() {
const
sentFolder = require('Stores/User/Folder').sentFolder(),
draftFolder = require('Stores/User/Folder').draftFolder();
this.senderEmailsString(this.folderFullNameRaw === sentFolder || this.folderFullNameRaw === draftFolder ?
this.toEmailsString() : this.fromEmailString());
this.senderClearEmailsString(this.folderFullNameRaw === sentFolder || this.folderFullNameRaw === draftFolder ?
this.toClearEmailsString() : this.fromClearEmailString());
}
/**
* @param {AjaxJsonMessage} json
* @returns {boolean}
*/
initByJson(json) {
let
result = false,
priority = MessagePriority.Normal;
if (json && 'Object/Message' === json['@Object'])
{
priority = pInt(json.Priority);
this.priority(-1 < inArray(priority, [MessagePriority.High, MessagePriority.Low]) ? priority : MessagePriority.Normal);
this.folderFullNameRaw = json.Folder;
this.uid = json.Uid;
this.hash = json.Hash;
this.requestHash = json.RequestHash;
this.proxy = !!json.ExternalProxy;
this.size(pInt(json.Size));
this.from = emailArrayFromJson(json.From);
this.to = emailArrayFromJson(json.To);
this.cc = emailArrayFromJson(json.Cc);
this.bcc = emailArrayFromJson(json.Bcc);
this.replyTo = emailArrayFromJson(json.ReplyTo);
this.deliveredTo = emailArrayFromJson(json.DeliveredTo);
this.subject(json.Subject);
if (isArray(json.SubjectParts))
{
this.subjectPrefix(json.SubjectParts[0]);
this.subjectSuffix(json.SubjectParts[1]);
}
else
{
this.subjectPrefix('');
this.subjectSuffix(this.subject());
}
this.dateTimeStampInUTC(pInt(json.DateTimeStampInUTC));
this.hasAttachments(!!json.HasAttachments);
this.attachmentsSpecData(isArray(json.AttachmentsSpecData) ? json.AttachmentsSpecData : []);
this.fromEmailString(emailArrayToString(this.from, true));
this.fromClearEmailString(emailArrayToStringClear(this.from));
this.toEmailsString(emailArrayToString(this.to, true));
this.toClearEmailsString(emailArrayToStringClear(this.to));
this.threads(isArray(json.Threads) ? json.Threads : []);
this.initFlagsByJson(json);
this.computeSenderEmail();
result = true;
}
return result;
}
/**
* @param {AjaxJsonMessage} json
* @returns {boolean}
*/
initUpdateByMessageJson(json) {
let
result = false,
priority = MessagePriority.Normal;
if (json && 'Object/Message' === json['@Object'])
{
priority = pInt(json.Priority);
this.priority(-1 < inArray(priority, [MessagePriority.High, MessagePriority.Low]) ?
priority : MessagePriority.Normal);
this.aDraftInfo = json.DraftInfo;
this.sMessageId = json.MessageId;
this.sInReplyTo = json.InReplyTo;
this.sReferences = json.References;
this.proxy = !!json.ExternalProxy;
if (require('Stores/User/Pgp').capaOpenPGP())
{
this.isPgpSigned(!!json.PgpSigned);
this.isPgpEncrypted(!!json.PgpEncrypted);
}
this.hasAttachments(!!json.HasAttachments);
this.attachmentsSpecData(isArray(json.AttachmentsSpecData) ? json.AttachmentsSpecData : []);
this.foundedCIDs = isArray(json.FoundedCIDs) ? json.FoundedCIDs : [];
this.attachments(this.initAttachmentsFromJson(json.Attachments));
this.readReceipt(json.ReadReceipt || '');
this.computeSenderEmail();
result = true;
}
return result;
}
/**
* @param {(AjaxJsonAttachment|null)} oJsonAttachments
* @returns {Array}
*/
initAttachmentsFromJson(json) {
let
index = 0,
len = 0,
attachment = null;
const result = [];
if (json && 'Collection/AttachmentCollection' === json['@Object'] && isNonEmptyArray(json['@Collection']))
{
for (index = 0, len = json['@Collection'].length; index < len; index++)
{
attachment = AttachmentModel.newInstanceFromJson(json['@Collection'][index]);
if (attachment)
{
if ('' !== attachment.cidWithOutTags && 0 < this.foundedCIDs.length &&
0 <= inArray(attachment.cidWithOutTags, this.foundedCIDs))
{
attachment.isLinked = true;
}
result.push(attachment);
}
}
}
return result;
}
/**
* @param {AjaxJsonMessage} json
* @returns {boolean}
*/
initFlagsByJson(json) {
let result = false;
if (json && 'Object/Message' === json['@Object'])
{
this.unseen(!json.IsSeen);
this.flagged(!!json.IsFlagged);
this.answered(!!json.IsAnswered);
this.forwarded(!!json.IsForwarded);
this.isReadReceipt(!!json.IsReadReceipt);
this.deletedMark(!!json.IsDeleted);
result = true;
}
return result;
}
/**
* @param {boolean} friendlyView
* @param {boolean=} wrapWithLink = false
* @returns {string}
*/
fromToLine(friendlyView, wrapWithLink = false) {
return emailArrayToString(this.from, friendlyView, wrapWithLink);
}
/**
* @returns {string}
*/
fromDkimData() {
let result = ['none', ''];
if (isNonEmptyArray(this.from) && 1 === this.from.length && this.from[0] && this.from[0].dkimStatus)
{
result = [this.from[0].dkimStatus, this.from[0].dkimValue || ''];
}
return result;
}
/**
* @param {boolean} friendlyView
* @param {boolean=} wrapWithLink = false
* @returns {string}
*/
toToLine(friendlyView, wrapWithLink = false) {
return emailArrayToString(this.to, friendlyView, wrapWithLink);
}
/**
* @param {boolean} friendlyView
* @param {boolean=} wrapWithLink = false
* @returns {string}
*/
ccToLine(friendlyView, wrapWithLink = false) {
return emailArrayToString(this.cc, friendlyView, wrapWithLink);
}
/**
* @param {boolean} friendlyView
* @param {boolean=} wrapWithLink = false
* @returns {string}
*/
bccToLine(friendlyView, wrapWithLink = false) {
return emailArrayToString(this.bcc, friendlyView, wrapWithLink);
}
/**
* @param {boolean} friendlyView
* @param {boolean=} wrapWithLink = false
* @returns {string}
*/
replyToToLine(friendlyView, wrapWithLink = false) {
return emailArrayToString(this.replyTo, friendlyView, wrapWithLink);
}
/**
* @return string
*/
lineAsCss() {
const result = [];
if (this.deleted())
{
result.push('deleted');
}
if (this.deletedMark())
{
result.push('deleted-mark');
}
if (this.selected())
{
result.push('selected');
}
if (this.checked())
{
result.push('checked');
}
if (this.flagged())
{
result.push('flagged');
}
if (this.unseen())
{
result.push('unseen');
}
if (this.answered())
{
result.push('answered');
}
if (this.forwarded())
{
result.push('forwarded');
}
if (this.focused())
{
result.push('focused');
}
if (this.isImportant())
{
result.push('important');
}
if (this.hasAttachments())
{
result.push('withAttachments');
}
if (this.newForAnimation())
{
result.push('new');
}
if ('' === this.subject())
{
result.push('emptySubject');
}
// if (1 < this.threadsLen())
// {
// result.push('hasChildrenMessage');
// }
if (this.hasUnseenSubMessage())
{
result.push('hasUnseenSubMessage');
}
if (this.hasFlaggedSubMessage())
{
result.push('hasFlaggedSubMessage');
}
return result.join(' ');
}
/**
* @returns {boolean}
*/
hasVisibleAttachments() {
return !!_.find(this.attachments(), (item) => !item.isLinked);
}
/**
* @param {string} cid
* @returns {*}
*/
findAttachmentByCid(cid) {
let result = null;
const attachments = this.attachments();
if (isNonEmptyArray(attachments))
{
cid = cid.replace(/^<+/, '').replace(/>+$/, '');
result = _.find(attachments, (item) => cid === item.cidWithOutTags);
}
return result || null;
}
/**
* @param {string} contentLocation
* @returns {*}
*/
findAttachmentByContentLocation(contentLocation) {
let result = null;
const attachments = this.attachments();
if (isNonEmptyArray(attachments))
{
result = _.find(attachments, (item) => contentLocation === item.contentLocation);
}
return result || null;
}
/**
* @returns {string}
*/
messageId() {
return this.sMessageId;
}
/**
* @returns {string}
*/
inReplyTo() {
return this.sInReplyTo;
}
/**
* @returns {string}
*/
references() {
return this.sReferences;
}
/**
* @returns {string}
*/
fromAsSingleEmail() {
return isArray(this.from) && this.from[0] ? this.from[0].email : '';
}
/**
* @returns {string}
*/
viewLink() {
return messageViewLink(this.requestHash);
}
/**
* @returns {string}
*/
downloadLink() {
return messageDownloadLink(this.requestHash);
}
/**
* @param {Object} excludeEmails
* @param {boolean=} last = false
* @returns {Array}
*/
replyEmails(excludeEmails, last = false) {
const
result = [],
unic = isUnd(excludeEmails) ? {} : excludeEmails;
replyHelper(this.replyTo, unic, result);
if (0 === result.length)
{
replyHelper(this.from, unic, result);
}
if (0 === result.length && !last)
{
return this.replyEmails({}, true);
}
return result;
}
/**
* @param {Object} excludeEmails
* @param {boolean=} last = false
* @returns {Array.<Array>}
*/
replyAllEmails(excludeEmails, last = false) {
let data = [];
const
toResult = [],
ccResult = [],
unic = isUnd(excludeEmails) ? {} : excludeEmails;
replyHelper(this.replyTo, unic, toResult);
if (0 === toResult.length)
{
replyHelper(this.from, unic, toResult);
}
replyHelper(this.to, unic, toResult);
replyHelper(this.cc, unic, ccResult);
if (0 === toResult.length && !last)
{
data = this.replyAllEmails({}, true);
return [data[0], ccResult];
}
return [toResult, ccResult];
}
/**
* @returns {string}
*/
textBodyToString() {
return this.body ? this.body.html() : '';
}
/**
* @returns {string}
*/
attachmentsToStringLine() {
const attachLines = _.map(this.attachments(), (item) => item.fileName + ' (' + item.friendlySize + ')');
return attachLines && 0 < attachLines.length ? attachLines.join(', ') : '';
}
/**
* @param {boolean=} print = false
*/
viewPopupMessage(print = false) {
this.showLazyExternalImagesInBody();
previewMessage(this.subject(), this.body, this.isHtml(), print);
}
printMessage() {
this.viewPopupMessage(true);
}
/**
* @returns {string}
*/
generateUid() {
return this.folderFullNameRaw + '/' + this.uid;
}
/**
* @param {MessageModel} message
* @returns {MessageModel}
*/
populateByMessageListItem(message) {
if (message)
{
this.folderFullNameRaw = message.folderFullNameRaw;
this.uid = message.uid;
this.hash = message.hash;
this.requestHash = message.requestHash;
this.subject(message.subject());
}
this.subjectPrefix(this.subjectPrefix());
this.subjectSuffix(this.subjectSuffix());
if (message)
{
this.size(message.size());
this.dateTimeStampInUTC(message.dateTimeStampInUTC());
this.priority(message.priority());
this.proxy = message.proxy;
this.fromEmailString(message.fromEmailString());
this.fromClearEmailString(message.fromClearEmailString());
this.toEmailsString(message.toEmailsString());
this.toClearEmailsString(message.toClearEmailsString());
this.emails = message.emails;
this.from = message.from;
this.to = message.to;
this.cc = message.cc;
this.bcc = message.bcc;
this.replyTo = message.replyTo;
this.deliveredTo = message.deliveredTo;
this.unseen(message.unseen());
this.flagged(message.flagged());
this.answered(message.answered());
this.forwarded(message.forwarded());
this.isReadReceipt(message.isReadReceipt());
this.deletedMark(message.deletedMark());
this.priority(message.priority());
this.selected(message.selected());
this.checked(message.checked());
this.hasAttachments(message.hasAttachments());
this.attachmentsSpecData(message.attachmentsSpecData());
}
this.body = null;
this.aDraftInfo = [];
this.sMessageId = '';
this.sInReplyTo = '';
this.sReferences = '';
if (message)
{
this.threads(message.threads());
}
this.computeSenderEmail();
return this;
}
showLazyExternalImagesInBody() {
if (this.body)
{
$('.lazy.lazy-inited[data-original]', this.body).each(function() {
$(this).attr('src', $(this).attr('data-original')).removeAttr('data-original');
});
}
}
showExternalImages(lazy = false) {
if (this.body && this.body.data('rl-has-images'))
{
this.hasImages(false);
this.body.data('rl-has-images', false);
var sAttr = this.proxy ? 'data-x-additional-src' : 'data-x-src';
$('[' + sAttr + ']', this.body).each(function() {
if (lazy && $(this).is('img'))
{
$(this)
.addClass('lazy')
.attr('data-original', $(this).attr(sAttr))
.removeAttr(sAttr);
}
else
{
$(this).attr('src', $(this).attr(sAttr)).removeAttr(sAttr);
}
});
sAttr = this.proxy ? 'data-x-additional-style-url' : 'data-x-style-url';
$('[' + sAttr + ']', this.body).each(function() {
var sStyle = trim($(this).attr('style'));
sStyle = '' === sStyle ? '' : (';' === sStyle.substr(-1) ? sStyle + ' ' : sStyle + '; ');
$(this).attr('style', sStyle + $(this).attr(sAttr)).removeAttr(sAttr);
});
if (lazy)
{
$('img.lazy', this.body).addClass('lazy-inited').lazyload({
'threshold': 400,
'effect': 'fadeIn',
'skip_invisible': false,
'container': $('.RL-MailMessageView .messageView .messageItem .content')[0]
});
$win.resize();
}
windowResize(500);
}
}
showInternalImages(lazy = false) {
if (this.body && !this.body.data('rl-init-internal-images'))
{
this.body.data('rl-init-internal-images', true);
var self = this;
$('[data-x-src-cid]', this.body).each(function() {
const attachment = self.findAttachmentByCid($(this).attr('data-x-src-cid'));
if (attachment && attachment.download)
{
if (lazy && $(this).is('img'))
{
$(this)
.addClass('lazy')
.attr('data-original', attachment.linkPreview());
}
else
{
$(this).attr('src', attachment.linkPreview());
}
}
});
$('[data-x-src-location]', this.body).each(function() {
let attachment = self.findAttachmentByContentLocation($(this).attr('data-x-src-location'));
if (!attachment)
{
attachment = self.findAttachmentByCid($(this).attr('data-x-src-location'));
}
if (attachment && attachment.download)
{
if (lazy && $(this).is('img'))
{
$(this)
.addClass('lazy')
.attr('data-original', attachment.linkPreview());
}
else
{
$(this).attr('src', attachment.linkPreview());
}
}
});
$('[data-x-style-cid]', this.body).each(function() {
let
style = '',
name = '';
const attachment = self.findAttachmentByCid($(this).attr('data-x-style-cid'));
if (attachment && attachment.linkPreview)
{
name = $(this).attr('data-x-style-cid-name');
if ('' !== name)
{
style = trim($(this).attr('style'));
style = '' === style ? '' : (';' === style.substr(-1) ? style + ' ' : style + '; ');
$(this).attr('style', style + name + ': url(\'' + attachment.linkPreview() + '\')');
}
}
});
if (lazy)
{
(function($oImg, oContainer) {
_.delay(() => {
$oImg.addClass('lazy-inited').lazyload({
'threshold': 400,
'effect': 'fadeIn',
'skip_invisible': false,
'container': oContainer
});
}, 300);
}($('img.lazy', self.body), $('.RL-MailMessageView .messageView .messageItem .content')[0]));
}
windowResize(500);
}
}
storeDataInDom() {
if (this.body)
{
this.body.data('rl-is-html', !!this.isHtml());
this.body.data('rl-has-images', !!this.hasImages());
}
}
fetchDataFromDom() {
if (this.body)
{
this.isHtml(!!this.body.data('rl-is-html'));
this.hasImages(!!this.body.data('rl-has-images'));
}
}
replacePlaneTextBody(plain) {
if (this.body)
{
this.body.html(plain).addClass('b-text-part plain');
}
}
/**
* @returns {string}
*/
flagHash() {
return [this.deleted(), this.deletedMark(), this.unseen(), this.flagged(), this.answered(), this.forwarded(), this.isReadReceipt()].join(',');
}
}
export {MessageModel, MessageModel as default};

View file

@ -1,80 +0,0 @@
var
_ = require('_'),
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
MessageSimpleModel = require('Model/MessageSimple');
/**
* @constructor
*/
function MessageFullModel()
{
MessageSimpleModel.call(this, 'MessageFullModel');
}
_.extend(MessageFullModel.prototype, MessageSimpleModel.prototype);
MessageFullModel.prototype.priority = 0;
MessageFullModel.prototype.hash = '';
MessageFullModel.prototype.requestHash = '';
MessageFullModel.prototype.proxy = false;
MessageFullModel.prototype.hasAttachments = false;
MessageFullModel.prototype.clear = function()
{
MessageSimpleModel.prototype.clear.call(this);
this.priority = 0;
this.hash = '';
this.requestHash = '';
this.proxy = false;
this.hasAttachments = false;
};
/**
* @param {AjaxJsonMessage} oJson
* @returns {boolean}
*/
MessageFullModel.prototype.initByJson = function(oJson)
{
var bResult = false;
if (oJson && 'Object/Message' === oJson['@Object'])
{
if (MessageSimpleModel.prototype.initByJson.call(this, oJson))
{
this.priority = Utils.pInt(oJson.Priority);
this.priority = Utils.inArray(this.priority, [Enums.MessagePriority.High, Enums.MessagePriority.Low]) ?
this.priority : Enums.MessagePriority.Normal;
this.hash = Utils.pString(oJson.Hash);
this.requestHash = Utils.pString(oJson.RequestHash);
this.proxy = !!oJson.ExternalProxy;
this.hasAttachments = !!oJson.HasAttachments;
bResult = true;
}
}
return bResult;
};
/**
* @static
* @param {AjaxJsonMessage} oJson
* @returns {?MessageFullModel}
*/
MessageFullModel.newInstanceFromJson = function(oJson)
{
var oItem = oJson ? new MessageFullModel() : null;
return oItem && oItem.initByJson(oJson) ? oItem : null;
};
module.exports = MessageFullModel;

View file

@ -1,167 +0,0 @@
var
_ = require('_'),
ko = require('ko'),
Utils = require('Common/Utils'),
MessageHelper = require('Helper/Message').default,
AbstractModel = require('Knoin/AbstractModel');
/**
* @constructor
* @param {string=} sSuperName
*/
function MessageSimpleModel(sSuperName)
{
AbstractModel.call(this, sSuperName || 'MessageSimpleModel');
this.flagged = ko.observable(false);
this.selected = ko.observable(false);
}
_.extend(MessageSimpleModel.prototype, AbstractModel.prototype);
MessageSimpleModel.prototype.isSimpleMessage = true;
MessageSimpleModel.prototype.folder = '';
MessageSimpleModel.prototype.folderFullNameRaw = '';
MessageSimpleModel.prototype.uid = '';
MessageSimpleModel.prototype.subject = '';
MessageSimpleModel.prototype.to = [];
MessageSimpleModel.prototype.from = [];
MessageSimpleModel.prototype.cc = [];
MessageSimpleModel.prototype.bcc = [];
MessageSimpleModel.prototype.replyTo = [];
MessageSimpleModel.prototype.deliveredTo = [];
MessageSimpleModel.prototype.fromAsString = '';
MessageSimpleModel.prototype.fromAsStringClear = '';
MessageSimpleModel.prototype.toAsString = '';
MessageSimpleModel.prototype.toAsStringClear = '';
MessageSimpleModel.prototype.senderAsString = '';
MessageSimpleModel.prototype.senderAsStringClear = '';
MessageSimpleModel.prototype.size = 0;
MessageSimpleModel.prototype.timestamp = 0;
MessageSimpleModel.prototype.clear = function()
{
this.folder = '';
this.folderFullNameRaw = '';
this.uid = '';
this.subject = '';
this.to = [];
this.from = [];
this.cc = [];
this.bcc = [];
this.replyTo = [];
this.deliveredTo = [];
this.fromAsString = '';
this.fromAsStringClear = '';
this.toAsString = '';
this.toAsStringClear = '';
this.senderAsString = '';
this.senderAsStringClear = '';
this.size = 0;
this.timestamp = 0;
this.flagged(false);
this.selected(false);
};
/**
* @param {Object} oJson
* @returns {boolean}
*/
MessageSimpleModel.prototype.initByJson = function(oJson)
{
var bResult = false;
if (oJson && 'Object/Message' === oJson['@Object'])
{
this.folder = Utils.pString(oJson.Folder);
this.folderFullNameRaw = this.folder;
this.uid = Utils.pString(oJson.Uid);
this.subject = Utils.pString(oJson.Subject);
if (Utils.isArray(oJson.SubjectParts))
{
this.subjectPrefix = Utils.pString(oJson.SubjectParts[0]);
this.subjectSuffix = Utils.pString(oJson.SubjectParts[1]);
}
else
{
this.subjectPrefix = '';
this.subjectSuffix = this.subject;
}
this.from = MessageHelper.emailArrayFromJson(oJson.From);
this.to = MessageHelper.emailArrayFromJson(oJson.To);
this.cc = MessageHelper.emailArrayFromJson(oJson.Cc);
this.bcc = MessageHelper.emailArrayFromJson(oJson.Bcc);
this.replyTo = MessageHelper.emailArrayFromJson(oJson.ReplyTo);
this.deliveredTo = MessageHelper.emailArrayFromJson(oJson.DeliveredTo);
this.size = Utils.pInt(oJson.Size);
this.timestamp = Utils.pInt(oJson.DateTimeStampInUTC);
this.fromAsString = MessageHelper.emailArrayToString(this.from, true);
this.fromAsStringClear = MessageHelper.emailArrayToStringClear(this.from);
this.toAsString = MessageHelper.emailArrayToString(this.to, true);
this.toAsStringClear = MessageHelper.emailArrayToStringClear(this.to);
this.flagged(false);
this.selected(false);
this.populateSenderEmail();
bResult = true;
}
return bResult;
};
MessageSimpleModel.prototype.populateSenderEmail = function(bDraftOrSentFolder)
{
this.senderAsString = this.fromAsString;
this.senderAsStringClear = this.fromAsStringClear;
if (bDraftOrSentFolder)
{
this.senderAsString = this.toAsString;
this.senderAsStringClear = this.toAsStringClear;
}
};
/**
* @returns {Array}
*/
MessageSimpleModel.prototype.threads = function()
{
return [];
};
/**
* @static
* @param {Object} oJson
* @returns {?MessageSimpleModel}
*/
MessageSimpleModel.newInstanceFromJson = function(oJson)
{
var oItem = oJson ? new MessageSimpleModel() : null;
return oItem && oItem.initByJson(oJson) ? oItem : null;
};
module.exports = MessageSimpleModel;

View file

@ -1,103 +0,0 @@
var
_ = require('_'),
ko = require('ko'),
Utils = require('Common/Utils'),
PgpStore = require('Stores/User/Pgp'),
AbstractModel = require('Knoin/AbstractModel');
/**
* @constructor
* @param {string} iIndex
* @param {string} sGuID
* @param {string} sID
* @param {array} aIDs
* @param {array} aUserIDs
* @param {array} aEmails
* @param {boolean} bIsPrivate
* @param {string} sArmor
* @param {string} sUserID
*/
function OpenPgpKeyModel(iIndex, sGuID, sID, aIDs, aUserIDs, aEmails, bIsPrivate, sArmor, sUserID)
{
AbstractModel.call(this, 'OpenPgpKeyModel');
this.index = iIndex;
this.id = sID;
this.ids = Utils.isNonEmptyArray(aIDs) ? aIDs : [sID];
this.guid = sGuID;
this.users = aUserIDs;
this.emails = aEmails;
this.armor = sArmor;
this.isPrivate = !!bIsPrivate;
this.selectUser(sUserID);
this.deleteAccess = ko.observable(false);
}
_.extend(OpenPgpKeyModel.prototype, AbstractModel.prototype);
OpenPgpKeyModel.prototype.index = 0;
OpenPgpKeyModel.prototype.id = '';
OpenPgpKeyModel.prototype.ids = [];
OpenPgpKeyModel.prototype.guid = '';
OpenPgpKeyModel.prototype.user = '';
OpenPgpKeyModel.prototype.users = [];
OpenPgpKeyModel.prototype.email = '';
OpenPgpKeyModel.prototype.emails = [];
OpenPgpKeyModel.prototype.armor = '';
OpenPgpKeyModel.prototype.isPrivate = false;
OpenPgpKeyModel.prototype.getNativeKey = function()
{
var oKey = null;
try
{
oKey = PgpStore.openpgp.key.readArmored(this.armor);
if (oKey && !oKey.err && oKey.keys && oKey.keys[0])
{
return oKey;
}
}
catch (e)
{
Utils.log(e);
}
return null;
};
OpenPgpKeyModel.prototype.getNativeKeys = function()
{
var oKey = this.getNativeKey();
return oKey && oKey.keys ? oKey.keys : null;
};
OpenPgpKeyModel.prototype.select = function(sPattern, sProperty)
{
if (this[sProperty])
{
var index = this[sProperty].indexOf(sPattern);
if (-1 !== index)
{
this.user = this.users[index];
this.email = this.emails[index];
}
}
};
OpenPgpKeyModel.prototype.selectUser = function(sUser)
{
this.select(sUser, 'users');
};
OpenPgpKeyModel.prototype.selectEmail = function(sEmail)
{
this.select(sEmail, 'emails');
};
module.exports = OpenPgpKeyModel;

87
dev/Model/OpenPgpKey.jsx Normal file
View file

@ -0,0 +1,87 @@
import ko from 'ko';
import {isNonEmptyArray, log} from 'Common/Utils';
import {AbstractModel} from 'Knoin/AbstractModel';
import PgpStore from 'Stores/User/Pgp';
class OpenPgpKeyModel extends AbstractModel
{
/**
* @param {string} index
* @param {string} guID
* @param {string} ID
* @param {array} IDs
* @param {array} userIDs
* @param {array} emails
* @param {boolean} isPrivate
* @param {string} armor
* @param {string} userID
*/
constructor(index, guID, ID, IDs, userIDs, emails, isPrivate, armor, userID)
{
super('OpenPgpKeyModel');
this.index = index;
this.id = ID;
this.ids = isNonEmptyArray(IDs) ? IDs : [ID];
this.guid = guID;
this.user = '';
this.users = userIDs;
this.email = '';
this.emails = emails;
this.armor = armor;
this.isPrivate = !!isPrivate;
this.selectUser(userID);
this.deleteAccess = ko.observable(false);
}
getNativeKey() {
let key = null;
try
{
key = PgpStore.openpgp.key.readArmored(this.armor);
if (key && !key.err && key.keys && key.keys[0])
{
return key;
}
}
catch (e)
{
log(e);
}
return null;
}
getNativeKeys() {
const key = this.getNativeKey();
return key && key.keys ? key.keys : null;
}
select(pattern, property) {
if (this[property])
{
const index = this[property].indexOf(pattern);
if (-1 !== index)
{
this.user = this.users[index];
this.email = this.emails[index];
}
}
}
selectUser(user) {
this.select(user, 'users');
}
selectEmail(email) {
this.select(email, 'emails');
}
}
export {OpenPgpKeyModel, OpenPgpKeyModel as default};

View file

@ -1,69 +0,0 @@
var
_ = require('_'),
ko = require('ko'),
Utils = require('Common/Utils'),
AbstractModel = require('Knoin/AbstractModel');
/**
* @constructor
* @param {string} sID
* @param {string} sName
* @param {string} sBody
*/
function TemplateModel(sID, sName, sBody)
{
AbstractModel.call(this, 'TemplateModel');
this.id = sID;
this.name = sName;
this.body = sBody;
this.populated = true;
this.deleteAccess = ko.observable(false);
}
_.extend(TemplateModel.prototype, AbstractModel.prototype);
/**
* @type {string}
*/
TemplateModel.prototype.id = '';
/**
* @type {string}
*/
TemplateModel.prototype.name = '';
/**
* @type {string}
*/
TemplateModel.prototype.body = '';
/**
* @type {boolean}
*/
TemplateModel.prototype.populated = true;
/**
* @type {boolean}
*/
TemplateModel.prototype.parse = function(oItem)
{
var bResult = false;
if (oItem && 'Object/Template' === oItem['@Object'])
{
this.id = Utils.pString(oItem.ID);
this.name = Utils.pString(oItem.Name);
this.body = Utils.pString(oItem.Body);
this.populated = !!oItem.Populated;
bResult = true;
}
return bResult;
};
module.exports = TemplateModel;

46
dev/Model/Template.jsx Normal file
View file

@ -0,0 +1,46 @@
import ko from 'ko';
import {pString} from 'Common/Utils';
import {AbstractModel} from 'Knoin/AbstractModel';
class TemplateModel extends AbstractModel
{
/**
* @param {string} id
* @param {string} name
* @param {string} body
*/
constructor(id, name, body)
{
super('TemplateModel');
this.id = id;
this.name = name;
this.body = body;
this.populated = true;
this.deleteAccess = ko.observable(false);
}
/**
* @returns {boolean}
*/
parse(json) {
let result = false;
if (json && 'Object/Template' === json['@Object'])
{
this.id = pString(json.ID);
this.name = pString(json.Name);
this.body = pString(json.Body);
this.populated = !!json.Populated;
result = true;
}
return result;
}
}
export {TemplateModel, TemplateModel as default};

View file

@ -13,7 +13,7 @@ var
Settings = require('Storage/Settings'),
Local = require('Storage/Client'),
FolderModel = require('Model/Folder'),
FolderModel = require('Model/Folder').default,
AbstractBasicPromises = require('Promises/AbstractBasic');

View file

@ -118,7 +118,7 @@ FiltersUserSettings.prototype.updateList = function()
{
var
self = this,
FilterModel = require('Model/Filter');
FilterModel = require('Model/Filter').default;
if (!this.filters.loading())
{
@ -176,7 +176,7 @@ FiltersUserSettings.prototype.addFilter = function()
{
var
self = this,
FilterModel = require('Model/Filter'),
FilterModel = require('Model/Filter').default,
oNew = new FilterModel();
oNew.generateID();

View file

@ -23,8 +23,8 @@ var
Remote = require('Remote/User/Ajax'),
MessageModel = require('Model/Message'),
MessageHelper = require('Helper/Message').default;
MessageModel = require('Model/Message').default,
MessageHelper = require('Helper/Message');
/**
* @constructor

View file

@ -32,7 +32,7 @@ var
Settings = require('Storage/Settings'),
Remote = require('Remote/User/Ajax'),
ComposeAttachmentModel = require('Model/ComposeAttachment'),
ComposeAttachmentModel = require('Model/ComposeAttachment').default,
kn = require('Knoin/Knoin'),
AbstractView = require('Knoin/AbstractView');

View file

@ -11,7 +11,7 @@ var
PgpStore = require('Stores/User/Pgp'),
EmailModel = require('Model/Email'),
EmailModel = require('Model/Email').default,
kn = require('Knoin/Knoin'),
AbstractView = require('Knoin/AbstractView');

View file

@ -21,9 +21,9 @@ var
Remote = require('Remote/User/Ajax'),
EmailModel = require('Model/Email'),
ContactModel = require('Model/Contact'),
ContactPropertyModel = require('Model/ContactProperty'),
EmailModel = require('Model/Email').default,
ContactModel = require('Model/Contact').default,
ContactPropertyModel = require('Model/ContactProperty').default,
kn = require('Knoin/Knoin'),
AbstractView = require('Knoin/AbstractView');

View file

@ -558,7 +558,7 @@ MessageViewMailBoxUserView.prototype.checkHeaderHeight = function()
// var
// sResult = '',
// aTo = [],
// EmailModel = require('Model/Email'),
// EmailModel = require('Model/Email').default,
// fParseEmailLine = function(sLine) {
// return sLine ? _.compact(_.map([window.decodeURIComponent(sLine)], function(sItem) {
// var oEmailModel = new EmailModel();

View file

@ -6,7 +6,7 @@ import {$win, $html, data as GlobalsData, bMobileDevice} from 'Common/Globals';
import * as Enums from 'Common/Enums';
import * as Plugins from 'Common/Plugins';
import {i18n} from 'Common/Translator';
import EmailModel from 'Model/Email';
import {EmailModel} from 'Model/Email';
export default (App) => {