mirror of
https://github.com/the-djmaze/snappymail.git
synced 2025-03-03 18:28:48 +08:00
Code refactoring (es5 -> es2015)
This commit is contained in:
parent
fb2e492ce8
commit
38a1041a73
42 changed files with 3081 additions and 3690 deletions
|
@ -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';
|
||||
|
||||
|
|
|
@ -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
2
dev/External/ko.js
vendored
|
@ -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(),
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
34
dev/Knoin/AbstractModel.jsx
Normal file
34
dev/Knoin/AbstractModel.jsx
Normal 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};
|
|
@ -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
36
dev/Model/Account.jsx
Normal 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};
|
|
@ -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
487
dev/Model/Attachment.jsx
Normal 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};
|
|
@ -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;
|
101
dev/Model/ComposeAttachment.jsx
Normal file
101
dev/Model/ComposeAttachment.jsx
Normal 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};
|
|
@ -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
128
dev/Model/Contact.jsx
Normal 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};
|
|
@ -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;
|
41
dev/Model/ContactProperty.jsx
Normal file
41
dev/Model/ContactProperty.jsx
Normal 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};
|
|
@ -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
372
dev/Model/Email.jsx
Normal 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};
|
|
@ -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
292
dev/Model/Filter.jsx
Normal 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};
|
|
@ -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;
|
102
dev/Model/FilterCondition.jsx
Normal file
102
dev/Model/FilterCondition.jsx
Normal 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};
|
|
@ -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
313
dev/Model/Folder.jsx
Normal 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};
|
|
@ -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
42
dev/Model/Identity.jsx
Normal 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};
|
1013
dev/Model/Message.js
1013
dev/Model/Message.js
File diff suppressed because it is too large
Load diff
918
dev/Model/Message.jsx
Normal file
918
dev/Model/Message.jsx
Normal 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};
|
|
@ -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;
|
|
@ -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;
|
|
@ -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
87
dev/Model/OpenPgpKey.jsx
Normal 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};
|
|
@ -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
46
dev/Model/Template.jsx
Normal 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};
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) => {
|
||||
|
||||
|
|
Loading…
Reference in a new issue