mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
merge all Model JSON @Object parsers into a reviveFromJson()
This commit is contained in:
parent
76648f04ae
commit
15e07a73e9
18 changed files with 378 additions and 411 deletions
|
|
@ -528,10 +528,9 @@ class AppUser extends AbstractApp {
|
||||||
delegateRunOnDestroy(TemplateStore.templates());
|
delegateRunOnDestroy(TemplateStore.templates());
|
||||||
|
|
||||||
TemplateStore.templates(
|
TemplateStore.templates(
|
||||||
data.Result.Templates.map(templateData => {
|
data.Result.Templates.map(templateData =>
|
||||||
const template = new TemplateModel();
|
TemplateModel.reviveFromJson(templateData)
|
||||||
return template.parse(templateData) ? template : null;
|
).filter(v => v)
|
||||||
}).filter(v => v)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,14 @@ export class AbstractModel {
|
||||||
* @param {string} modelName = ''
|
* @param {string} modelName = ''
|
||||||
*/
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
// this.sModelName = new.target.name;
|
/*
|
||||||
|
constructor(props) {
|
||||||
|
if (new.target === Parent) {
|
||||||
|
throw new Error("Can't instantiate abstract class!");
|
||||||
|
}
|
||||||
|
this.sModelName = new.target.name;
|
||||||
|
props && Object.entries(props).forEach(([key, value]) => '@' !== key[0] && (this[key] = value));
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
regDisposables(value) {
|
regDisposables(value) {
|
||||||
|
|
@ -29,4 +36,30 @@ export class AbstractModel {
|
||||||
}
|
}
|
||||||
Object.values(this).forEach(disposeOne);
|
Object.values(this).forEach(disposeOne);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @static
|
||||||
|
* @param {FetchJson} json
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
static validJson(json) {
|
||||||
|
return !!(json && ('Object/'+this.name.replace('Model', '') === json['@Object']));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @static
|
||||||
|
* @param {FetchJson} json
|
||||||
|
* @returns {*Model}
|
||||||
|
*/
|
||||||
|
static reviveFromJson(json) {
|
||||||
|
// Object/Attachment
|
||||||
|
// Object/Contact
|
||||||
|
// Object/Email
|
||||||
|
// Object/Filter
|
||||||
|
// Object/Folder
|
||||||
|
// Object/Message
|
||||||
|
// Object/Template
|
||||||
|
return this.validJson(json) ? new this(json) : null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,48 +41,36 @@ class AttachmentModel extends AbstractModel {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @static
|
* @static
|
||||||
* @param {AjaxJsonAttachment} json
|
* @param {FetchJsonAttachment} json
|
||||||
* @returns {?AttachmentModel}
|
* @returns {?AttachmentModel}
|
||||||
*/
|
*/
|
||||||
static newInstanceFromJson(json) {
|
static reviveFromJson(json) {
|
||||||
const attachment = new AttachmentModel();
|
const attachment = super.reviveFromJson(json);
|
||||||
return attachment.initByJson(json) ? attachment : null;
|
if (attachment) {
|
||||||
}
|
attachment.mimeType = ((json.MimeType || '').toLowerCase()).trim();
|
||||||
|
attachment.fileName = json.FileName.trim();
|
||||||
/**
|
|
||||||
* @param {AjaxJsonAttachment} json
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
initByJson(json) {
|
|
||||||
let bResult = false;
|
|
||||||
if (json && 'Object/Attachment' === json['@Object']) {
|
|
||||||
this.mimeType = ((json.MimeType || '').toLowerCase()).trim();
|
|
||||||
this.fileName = json.FileName.trim();
|
|
||||||
// if it is inline
|
// if it is inline
|
||||||
this.isInline = !!json.IsInline;
|
attachment.isInline = !!json.IsInline;
|
||||||
// if inline image is linked with CID in html
|
// if inline image is linked with CID in html
|
||||||
// and 'src="cid:' or background-image:url(cid:)
|
// and 'src="cid:' or background-image:url(cid:)
|
||||||
this.isLinked = !!json.IsLinked;
|
attachment.isLinked = !!json.IsLinked;
|
||||||
this.isThumbnail = !!json.IsThumbnail;
|
attachment.isThumbnail = !!json.IsThumbnail;
|
||||||
this.cid = json.CID;
|
attachment.cid = json.CID;
|
||||||
this.contentLocation = json.ContentLocation;
|
attachment.contentLocation = json.ContentLocation;
|
||||||
this.download = json.Download;
|
attachment.download = json.Download;
|
||||||
|
|
||||||
this.folder = json.Folder;
|
attachment.folder = json.Folder;
|
||||||
this.uid = json.Uid;
|
attachment.uid = json.Uid;
|
||||||
this.mimeIndex = json.MimeIndex;
|
attachment.mimeIndex = json.MimeIndex;
|
||||||
this.framed = !!json.Framed;
|
attachment.framed = !!json.Framed;
|
||||||
|
|
||||||
this.friendlySize = File.friendlySize(json.EstimatedSize);
|
attachment.friendlySize = File.friendlySize(json.EstimatedSize);
|
||||||
this.cidWithoutTags = this.cid.replace(/^<+/, '').replace(/>+$/, '');
|
attachment.cidWithoutTags = attachment.cid.replace(/^<+/, '').replace(/>+$/, '');
|
||||||
|
|
||||||
this.fileNameExt = File.getExtension(this.fileName);
|
attachment.fileNameExt = File.getExtension(attachment.fileName);
|
||||||
this.fileType = File.getType(this.fileNameExt, this.mimeType);
|
attachment.fileType = File.getType(attachment.fileNameExt, attachment.mimeType);
|
||||||
|
|
||||||
bResult = true;
|
|
||||||
}
|
}
|
||||||
|
return attachment;
|
||||||
return bResult;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ export class AttachmentCollectionModel extends AbstractCollectionModel
|
||||||
* @returns {AttachmentCollectionModel}
|
* @returns {AttachmentCollectionModel}
|
||||||
*/
|
*/
|
||||||
static reviveFromJson(items) {
|
static reviveFromJson(items) {
|
||||||
let cb = attachment => AttachmentModel.newInstanceFromJson(attachment),
|
let cb = attachment => AttachmentModel.reviveFromJson(attachment),
|
||||||
result = super.reviveFromJson(items, cb);
|
result = super.reviveFromJson(items, cb);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
result = new AttachmentCollectionModel;
|
result = new AttachmentCollectionModel;
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ class ComposeAttachmentModel extends AbstractModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {AjaxJsonComposeAttachment} json
|
* @param {FetchJsonComposeAttachment} json
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
initByUploadJson(json) {
|
initByUploadJson(json) {
|
||||||
|
|
|
||||||
|
|
@ -46,28 +46,26 @@ class ContactModel extends AbstractModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} oItem
|
* @static
|
||||||
* @returns {boolean}
|
* @param {FetchJsonContact} json
|
||||||
|
* @returns {?ContactModel}
|
||||||
*/
|
*/
|
||||||
parse(json) {
|
static reviveFromJson(json) {
|
||||||
let result = false;
|
const contact = super.reviveFromJson(json);
|
||||||
if (json && 'Object/Contact' === json['@Object']) {
|
if (contact) {
|
||||||
this.idContact = pInt(json.IdContact);
|
contact.idContact = pInt(json.IdContact);
|
||||||
this.display = pString(json.Display);
|
contact.display = pString(json.Display);
|
||||||
this.readOnly = !!json.ReadOnly;
|
contact.readOnly = !!json.ReadOnly;
|
||||||
|
|
||||||
if (Array.isNotEmpty(json.Properties)) {
|
if (Array.isNotEmpty(json.Properties)) {
|
||||||
json.Properties.forEach(property => {
|
json.Properties.forEach(property => {
|
||||||
if (property && property.Type && null != property.Value && null != property.TypeStr) {
|
if (property && property.Type && null != property.Value && null != property.TypeStr) {
|
||||||
this.properties.push([pInt(property.Type), pString(property.Value), pString(property.TypeStr)]);
|
contact.properties.push([pInt(property.Type), pString(property.Value), pString(property.TypeStr)]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
result = true;
|
|
||||||
}
|
}
|
||||||
|
return contact;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
import { encodeHtml } from 'Common/UtilsUser';
|
import { encodeHtml } from 'Common/UtilsUser';
|
||||||
|
|
||||||
|
import { AbstractModel } from 'Knoin/AbstractModel';
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -258,7 +260,7 @@ class Tokenizer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EmailModel {
|
class EmailModel extends AbstractModel {
|
||||||
email = '';
|
email = '';
|
||||||
name = '';
|
name = '';
|
||||||
dkimStatus = '';
|
dkimStatus = '';
|
||||||
|
|
@ -271,6 +273,7 @@ class EmailModel {
|
||||||
* @param {string=} dkimValue = ''
|
* @param {string=} dkimValue = ''
|
||||||
*/
|
*/
|
||||||
constructor(email = '', name = '', dkimStatus = 'none', dkimValue = '') {
|
constructor(email = '', name = '', dkimStatus = 'none', dkimValue = '') {
|
||||||
|
super();
|
||||||
this.email = email;
|
this.email = email;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.dkimStatus = dkimStatus;
|
this.dkimStatus = dkimStatus;
|
||||||
|
|
@ -281,12 +284,20 @@ class EmailModel {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @static
|
* @static
|
||||||
* @param {AjaxJsonEmail} json
|
* @param {FetchJsonEmail} json
|
||||||
* @returns {?EmailModel}
|
* @returns {?EmailModel}
|
||||||
*/
|
*/
|
||||||
static newInstanceFromJson(json) {
|
static reviveFromJson(json) {
|
||||||
const email = new EmailModel();
|
const email = super.reviveFromJson(json);
|
||||||
return email.initByJson(json) ? email : null;
|
if (email && email.email) {
|
||||||
|
email.name = json.Name.trim();
|
||||||
|
email.email = json.Email.trim();
|
||||||
|
email.dkimStatus = (json.DkimStatus || '').trim();
|
||||||
|
email.dkimValue = (json.DkimValue || '').trim();
|
||||||
|
email.clearDuplicateName();
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -332,25 +343,6 @@ class EmailModel {
|
||||||
return (this.name + ' ' + this.email).toLowerCase().includes(query.toLowerCase());
|
return (this.name + ' ' + this.email).toLowerCase().includes(query.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {AjaxJsonEmail} oJsonEmail
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
initByJson(json) {
|
|
||||||
let result = false;
|
|
||||||
if (json && 'Object/Email' === json['@Object']) {
|
|
||||||
this.name = json.Name.trim();
|
|
||||||
this.email = json.Email.trim();
|
|
||||||
this.dkimStatus = (json.DkimStatus || '').trim();
|
|
||||||
this.dkimValue = (json.DkimValue || '').trim();
|
|
||||||
|
|
||||||
result = !!this.email;
|
|
||||||
this.clearDuplicateName();
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {boolean} friendlyView = false
|
* @param {boolean} friendlyView = false
|
||||||
* @param {boolean=} wrapWithLink = false
|
* @param {boolean=} wrapWithLink = false
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ export class EmailCollectionModel extends AbstractCollectionModel
|
||||||
static reviveFromJson(items) {
|
static reviveFromJson(items) {
|
||||||
let result = new EmailCollectionModel;
|
let result = new EmailCollectionModel;
|
||||||
Array.isArray(items) && items.forEach(email => {
|
Array.isArray(items) && items.forEach(email => {
|
||||||
email = EmailModel.newInstanceFromJson(email);
|
email = EmailModel.reviveFromJson(email);
|
||||||
email && result.push(email);
|
email && result.push(email);
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -207,19 +207,24 @@ class FilterModel extends AbstractModel {
|
||||||
this.actionValueFourth(AccountStore.getEmailAddresses().join(', '));
|
this.actionValueFourth(AccountStore.getEmailAddresses().join(', '));
|
||||||
}
|
}
|
||||||
|
|
||||||
parse(json) {
|
/**
|
||||||
let result = false;
|
* @static
|
||||||
if (json && 'Object/Filter' === json['@Object']) {
|
* @param {FetchJsonFilter} json
|
||||||
this.id = pString(json.ID);
|
* @returns {?FilterModel}
|
||||||
this.name(pString(json.Name));
|
*/
|
||||||
this.enabled(!!json.Enabled);
|
static reviveFromJson(json) {
|
||||||
|
const filter = super.reviveFromJson(json);
|
||||||
|
if (filter) {
|
||||||
|
filter.id = pString(json.ID);
|
||||||
|
filter.name(pString(json.Name));
|
||||||
|
filter.enabled(!!json.Enabled);
|
||||||
|
|
||||||
this.conditionsType(pString(json.ConditionsType));
|
filter.conditionsType(pString(json.ConditionsType));
|
||||||
|
|
||||||
this.conditions([]);
|
filter.conditions([]);
|
||||||
|
|
||||||
if (Array.isNotEmpty(json.Conditions)) {
|
if (Array.isNotEmpty(json.Conditions)) {
|
||||||
this.conditions(
|
filter.conditions(
|
||||||
json.Conditions.map(aData => {
|
json.Conditions.map(aData => {
|
||||||
const filterCondition = new FilterConditionModel();
|
const filterCondition = new FilterConditionModel();
|
||||||
return filterCondition && filterCondition.parse(aData) ? filterCondition : null;
|
return filterCondition && filterCondition.parse(aData) ? filterCondition : null;
|
||||||
|
|
@ -227,21 +232,18 @@ class FilterModel extends AbstractModel {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.actionType(pString(json.ActionType));
|
filter.actionType(pString(json.ActionType));
|
||||||
|
|
||||||
this.actionValue(pString(json.ActionValue));
|
filter.actionValue(pString(json.ActionValue));
|
||||||
this.actionValueSecond(pString(json.ActionValueSecond));
|
filter.actionValueSecond(pString(json.ActionValueSecond));
|
||||||
this.actionValueThird(pString(json.ActionValueThird));
|
filter.actionValueThird(pString(json.ActionValueThird));
|
||||||
this.actionValueFourth(pString(json.ActionValueFourth));
|
filter.actionValueFourth(pString(json.ActionValueFourth));
|
||||||
|
|
||||||
this.actionNoStop(!json.Stop);
|
filter.actionNoStop(!json.Stop);
|
||||||
this.actionKeep(!!json.Keep);
|
filter.actionKeep(!!json.Keep);
|
||||||
this.actionMarkAsRead(!!json.MarkAsRead);
|
filter.actionMarkAsRead(!!json.MarkAsRead);
|
||||||
|
|
||||||
result = true;
|
|
||||||
}
|
}
|
||||||
|
return filter;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cloneSelf() {
|
cloneSelf() {
|
||||||
|
|
|
||||||
|
|
@ -43,241 +43,220 @@ class FolderModel extends AbstractModel {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @static
|
* @static
|
||||||
* @param {AjaxJsonFolder} json
|
* @param {FetchJsonFolder} json
|
||||||
* @returns {?FolderModel}
|
* @returns {?FolderModel}
|
||||||
*/
|
*/
|
||||||
static newInstanceFromJson(json) {
|
static reviveFromJson(json) {
|
||||||
const folder = new FolderModel();
|
const folder = super.reviveFromJson(json);
|
||||||
return folder.initByJson(json) ? folder.initComputed() : null;
|
if (folder) {
|
||||||
}
|
folder.name(json.Name);
|
||||||
|
folder.delimiter = json.Delimiter;
|
||||||
|
folder.fullName = json.FullName;
|
||||||
|
folder.fullNameRaw = json.FullNameRaw;
|
||||||
|
folder.fullNameHash = json.FullNameHash;
|
||||||
|
folder.deep = json.FullNameRaw.split(folder.delimiter).length - 1;
|
||||||
|
folder.selectable = !!json.IsSelectable;
|
||||||
|
folder.existen = !!json.IsExists;
|
||||||
|
|
||||||
/**
|
folder.subScribed(!!json.IsSubscribed);
|
||||||
* @returns {FolderModel}
|
folder.checkable(!!json.Checkable);
|
||||||
*/
|
|
||||||
initComputed() {
|
|
||||||
this.isInbox = ko.computed(() => FolderType.Inbox === this.type());
|
|
||||||
|
|
||||||
this.hasSubScribedSubfolders = ko.computed(
|
folder.isInbox = ko.computed(() => FolderType.Inbox === folder.type());
|
||||||
() =>
|
|
||||||
!!this.subFolders().find(
|
|
||||||
oFolder => (oFolder.subScribed() || oFolder.hasSubScribedSubfolders()) && !oFolder.isSystemFolder()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
this.canBeEdited = ko.computed(() => FolderType.User === this.type() && this.existen && this.selectable);
|
folder.hasSubScribedSubfolders = ko.computed(
|
||||||
|
() =>
|
||||||
|
!!folder.subFolders().find(
|
||||||
|
oFolder => (oFolder.subScribed() || oFolder.hasSubScribedSubfolders()) && !oFolder.isSystemFolder()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
this.visible = ko.computed(() => {
|
folder.canBeEdited = ko.computed(() => FolderType.User === folder.type() && folder.existen && folder.selectable);
|
||||||
const isSubScribed = this.subScribed(),
|
|
||||||
isSubFolders = this.hasSubScribedSubfolders();
|
|
||||||
|
|
||||||
return isSubScribed || (isSubFolders && (!this.existen || !this.selectable));
|
folder.visible = ko.computed(() => {
|
||||||
});
|
const isSubScribed = folder.subScribed(),
|
||||||
|
isSubFolders = folder.hasSubScribedSubfolders();
|
||||||
|
|
||||||
this.isSystemFolder = ko.computed(() => FolderType.User !== this.type());
|
return isSubScribed || (isSubFolders && (!folder.existen || !folder.selectable));
|
||||||
|
});
|
||||||
|
|
||||||
this.hidden = ko.computed(() => {
|
folder.isSystemFolder = ko.computed(() => FolderType.User !== folder.type());
|
||||||
const isSystem = this.isSystemFolder(),
|
|
||||||
isSubFolders = this.hasSubScribedSubfolders();
|
|
||||||
|
|
||||||
return (isSystem && !isSubFolders) || (!this.selectable && !isSubFolders);
|
folder.hidden = ko.computed(() => {
|
||||||
});
|
const isSystem = folder.isSystemFolder(),
|
||||||
|
isSubFolders = folder.hasSubScribedSubfolders();
|
||||||
|
|
||||||
this.selectableForFolderList = ko.computed(() => !this.isSystemFolder() && this.selectable);
|
return (isSystem && !isSubFolders) || (!folder.selectable && !isSubFolders);
|
||||||
|
});
|
||||||
|
|
||||||
this.messageCountAll = ko
|
folder.selectableForFolderList = ko.computed(() => !folder.isSystemFolder() && folder.selectable);
|
||||||
.computed({
|
|
||||||
read: this.privateMessageCountAll,
|
folder.messageCountAll = ko
|
||||||
write: (iValue) => {
|
.computed({
|
||||||
if (isPosNumeric(iValue, true)) {
|
read: folder.privateMessageCountAll,
|
||||||
this.privateMessageCountAll(iValue);
|
write: (iValue) => {
|
||||||
} else {
|
if (isPosNumeric(iValue, true)) {
|
||||||
this.privateMessageCountAll.valueHasMutated();
|
folder.privateMessageCountAll(iValue);
|
||||||
|
} else {
|
||||||
|
folder.privateMessageCountAll.valueHasMutated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.extend({ notify: 'always' });
|
||||||
|
|
||||||
|
folder.messageCountUnread = ko
|
||||||
|
.computed({
|
||||||
|
read: folder.privateMessageCountUnread,
|
||||||
|
write: (value) => {
|
||||||
|
if (isPosNumeric(value, true)) {
|
||||||
|
folder.privateMessageCountUnread(value);
|
||||||
|
} else {
|
||||||
|
folder.privateMessageCountUnread.valueHasMutated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.extend({ notify: 'always' });
|
||||||
|
|
||||||
|
folder.printableUnreadCount = ko.computed(() => {
|
||||||
|
const count = folder.messageCountAll(),
|
||||||
|
unread = folder.messageCountUnread(),
|
||||||
|
type = folder.type();
|
||||||
|
|
||||||
|
if (0 < count) {
|
||||||
|
if (FolderType.Draft === type) {
|
||||||
|
return '' + count;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
0 < unread &&
|
||||||
|
FolderType.Trash !== type &&
|
||||||
|
FolderType.Archive !== type &&
|
||||||
|
FolderType.SentItems !== type
|
||||||
|
) {
|
||||||
|
return '' + unread;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.extend({ notify: 'always' });
|
|
||||||
|
|
||||||
this.messageCountUnread = ko
|
return '';
|
||||||
.computed({
|
});
|
||||||
read: this.privateMessageCountUnread,
|
|
||||||
|
folder.canBeDeleted = ko.computed(
|
||||||
|
() => !folder.isSystemFolder() && !folder.subFolders().length
|
||||||
|
);
|
||||||
|
|
||||||
|
folder.canBeSubScribed = ko.computed(
|
||||||
|
() => !folder.isSystemFolder() && folder.selectable
|
||||||
|
);
|
||||||
|
|
||||||
|
folder.canBeChecked = folder.canBeSubScribed;
|
||||||
|
|
||||||
|
folder.localName = ko.computed(() => {
|
||||||
|
translatorTrigger();
|
||||||
|
|
||||||
|
let name = folder.name();
|
||||||
|
const type = folder.type();
|
||||||
|
|
||||||
|
if (folder.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;
|
||||||
|
});
|
||||||
|
|
||||||
|
folder.manageFolderSystemName = ko.computed(() => {
|
||||||
|
translatorTrigger();
|
||||||
|
|
||||||
|
let suffix = '';
|
||||||
|
const type = folder.type(),
|
||||||
|
name = folder.name();
|
||||||
|
|
||||||
|
if (folder.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;
|
||||||
|
});
|
||||||
|
|
||||||
|
folder.collapsed = ko.computed({
|
||||||
|
read: () => !folder.hidden() && folder.collapsedPrivate(),
|
||||||
write: (value) => {
|
write: (value) => {
|
||||||
if (isPosNumeric(value, true)) {
|
folder.collapsedPrivate(value);
|
||||||
this.privateMessageCountUnread(value);
|
|
||||||
} else {
|
|
||||||
this.privateMessageCountUnread.valueHasMutated();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.extend({ notify: 'always' });
|
|
||||||
|
|
||||||
this.printableUnreadCount = ko.computed(() => {
|
folder.hasUnreadMessages = ko.computed(() => 0 < folder.messageCountUnread() && folder.printableUnreadCount());
|
||||||
const count = this.messageCountAll(),
|
|
||||||
unread = this.messageCountUnread(),
|
|
||||||
type = this.type();
|
|
||||||
|
|
||||||
if (0 < count) {
|
folder.hasSubScribedUnreadMessagesSubfolders = ko.computed(
|
||||||
if (FolderType.Draft === type) {
|
() =>
|
||||||
return '' + count;
|
!!folder.subFolders().find(
|
||||||
} else if (
|
folder => folder.hasUnreadMessages() || folder.hasSubScribedUnreadMessagesSubfolders()
|
||||||
0 < unread &&
|
)
|
||||||
FolderType.Trash !== type &&
|
);
|
||||||
FolderType.Archive !== type &&
|
|
||||||
FolderType.SentItems !== type
|
// subscribe
|
||||||
) {
|
folder.name.subscribe(value => folder.nameForEdit(value));
|
||||||
return '' + unread;
|
|
||||||
|
folder.edited.subscribe(value => value && folder.nameForEdit(folder.name()));
|
||||||
|
|
||||||
|
folder.messageCountUnread.subscribe((unread) => {
|
||||||
|
if (FolderType.Inbox === folder.type()) {
|
||||||
|
dispatchEvent(new CustomEvent('mailbox.inbox-unread-count', {detail:unread}));
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
}
|
||||||
return '';
|
return folder;
|
||||||
});
|
|
||||||
|
|
||||||
this.canBeDeleted = ko.computed(() => {
|
|
||||||
const bSystem = this.isSystemFolder();
|
|
||||||
return !bSystem && !this.subFolders().length;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.canBeSubScribed = ko.computed(
|
|
||||||
() => !this.isSystemFolder() && this.selectable
|
|
||||||
);
|
|
||||||
|
|
||||||
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(
|
|
||||||
() =>
|
|
||||||
!!this.subFolders().find(
|
|
||||||
folder => folder.hasUnreadMessages() || folder.hasSubScribedUnreadMessagesSubfolders()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// subscribe
|
|
||||||
this.name.subscribe(value => this.nameForEdit(value));
|
|
||||||
|
|
||||||
this.edited.subscribe(value => value && this.nameForEdit(this.name()));
|
|
||||||
|
|
||||||
this.messageCountUnread.subscribe((unread) => {
|
|
||||||
if (FolderType.Inbox === this.type()) {
|
|
||||||
dispatchEvent(new CustomEvent('mailbox.inbox-unread-count', {detail:unread}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
collapsedCss() {
|
collapsedCss() {
|
||||||
return this.hasSubScribedSubfolders()
|
return 'e-collapsed-sign ' + (this.hasSubScribedSubfolders()
|
||||||
? this.collapsed()
|
? (this.collapsed() ? 'icon-right-mini' : 'icon-down-mini')
|
||||||
? 'icon-right-mini e-collapsed-sign'
|
: 'icon-none'
|
||||||
: 'icon-down-mini e-collapsed-sign'
|
);
|
||||||
: 'icon-none e-collapsed-sign';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {AjaxJsonFolder} json
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
initByJson(json) {
|
|
||||||
let bResult = false;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
bResult = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bResult;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ export class FolderCollectionModel extends AbstractCollectionModel
|
||||||
bDisplaySpecSetting = FolderStore.displaySpecSetting();
|
bDisplaySpecSetting = FolderStore.displaySpecSetting();
|
||||||
return super.reviveFromJson(object, (oFolder, self) => {
|
return super.reviveFromJson(object, (oFolder, self) => {
|
||||||
let oCacheFolder = Cache.getFolderFromCacheList(oFolder.FullNameRaw);
|
let oCacheFolder = Cache.getFolderFromCacheList(oFolder.FullNameRaw);
|
||||||
if (!oCacheFolder && (oCacheFolder = FolderModel.newInstanceFromJson(oFolder))) {
|
if (!oCacheFolder && (oCacheFolder = FolderModel.reviveFromJson(oFolder))) {
|
||||||
if (oFolder.FullNameRaw == self.SystemFolders[ServerFolderType.INBOX]) {
|
if (oFolder.FullNameRaw == self.SystemFolders[ServerFolderType.INBOX]) {
|
||||||
oCacheFolder.type(FolderType.Inbox);
|
oCacheFolder.type(FolderType.Inbox);
|
||||||
Cache.setFolderInboxName(oFolder.FullNameRaw);
|
Cache.setFolderInboxName(oFolder.FullNameRaw);
|
||||||
|
|
|
||||||
|
|
@ -93,12 +93,49 @@ class MessageModel extends AbstractModel {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @static
|
* @static
|
||||||
* @param {AjaxJsonMessage} oJsonMessage
|
* @param {FetchJsonMessage} json
|
||||||
* @returns {?MessageModel}
|
* @returns {?MessageModel}
|
||||||
*/
|
*/
|
||||||
static newInstanceFromJson(json) {
|
static reviveFromJson(json) {
|
||||||
const oMessageModel = new MessageModel();
|
const oMessageModel = super.reviveFromJson(json);
|
||||||
return oMessageModel.initByJson(json) ? oMessageModel : null;
|
if (oMessageModel) {
|
||||||
|
oMessageModel.folderFullNameRaw = json.Folder;
|
||||||
|
oMessageModel.uid = json.Uid;
|
||||||
|
oMessageModel.hash = json.Hash;
|
||||||
|
oMessageModel.requestHash = json.RequestHash;
|
||||||
|
|
||||||
|
oMessageModel.size(pInt(json.Size));
|
||||||
|
|
||||||
|
oMessageModel.from = EmailCollectionModel.reviveFromJson(json.From);
|
||||||
|
oMessageModel.to = EmailCollectionModel.reviveFromJson(json.To);
|
||||||
|
oMessageModel.cc = EmailCollectionModel.reviveFromJson(json.Cc);
|
||||||
|
oMessageModel.bcc = EmailCollectionModel.reviveFromJson(json.Bcc);
|
||||||
|
oMessageModel.replyTo = EmailCollectionModel.reviveFromJson(json.ReplyTo);
|
||||||
|
oMessageModel.deliveredTo = EmailCollectionModel.reviveFromJson(json.DeliveredTo);
|
||||||
|
oMessageModel.unsubsribeLinks = Array.isNotEmpty(json.UnsubsribeLinks) ? json.UnsubsribeLinks : [];
|
||||||
|
|
||||||
|
oMessageModel.subject(json.Subject);
|
||||||
|
if (isArray(json.SubjectParts)) {
|
||||||
|
oMessageModel.subjectPrefix(json.SubjectParts[0]);
|
||||||
|
oMessageModel.subjectSuffix(json.SubjectParts[1]);
|
||||||
|
} else {
|
||||||
|
oMessageModel.subjectPrefix('');
|
||||||
|
oMessageModel.subjectSuffix(oMessageModel.subject());
|
||||||
|
}
|
||||||
|
|
||||||
|
oMessageModel.dateTimeStampInUTC(pInt(json.DateTimeStampInUTC));
|
||||||
|
|
||||||
|
oMessageModel.fromEmailString(oMessageModel.from.toString(true));
|
||||||
|
oMessageModel.fromClearEmailString(oMessageModel.from.toStringClear());
|
||||||
|
oMessageModel.toEmailsString(oMessageModel.to.toString(true));
|
||||||
|
oMessageModel.toClearEmailsString(oMessageModel.to.toStringClear());
|
||||||
|
|
||||||
|
oMessageModel.threads(isArray(json.Threads) ? json.Threads : []);
|
||||||
|
|
||||||
|
oMessageModel.initFlagsByJson(json);
|
||||||
|
oMessageModel.computeSenderEmail();
|
||||||
|
}
|
||||||
|
return oMessageModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
_reset() {
|
_reset() {
|
||||||
|
|
@ -206,7 +243,8 @@ class MessageModel extends AbstractModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
setFromJson(json) {
|
setFromJson(json) {
|
||||||
if (json && 'Object/Message' === json['@Object']) {
|
let result = MessageModel.validJson(json);
|
||||||
|
if (result) {
|
||||||
let priority = pInt(json.Priority);
|
let priority = pInt(json.Priority);
|
||||||
this.priority(
|
this.priority(
|
||||||
[MessagePriority.High, MessagePriority.Low].includes(priority) ? priority : MessagePriority.Normal
|
[MessagePriority.High, MessagePriority.Low].includes(priority) ? priority : MessagePriority.Normal
|
||||||
|
|
@ -216,62 +254,12 @@ class MessageModel extends AbstractModel {
|
||||||
|
|
||||||
this.hasAttachments(!!json.HasAttachments);
|
this.hasAttachments(!!json.HasAttachments);
|
||||||
this.attachmentsSpecData(isArray(json.AttachmentsSpecData) ? json.AttachmentsSpecData : []);
|
this.attachmentsSpecData(isArray(json.AttachmentsSpecData) ? json.AttachmentsSpecData : []);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {AjaxJsonMessage} json
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
initByJson(json) {
|
|
||||||
let result = this.setFromJson(json);
|
|
||||||
if (result) {
|
|
||||||
this.folderFullNameRaw = json.Folder;
|
|
||||||
this.uid = json.Uid;
|
|
||||||
this.hash = json.Hash;
|
|
||||||
this.requestHash = json.RequestHash;
|
|
||||||
|
|
||||||
this.size(pInt(json.Size));
|
|
||||||
|
|
||||||
this.from = EmailCollectionModel.reviveFromJson(json.From);
|
|
||||||
this.to = EmailCollectionModel.reviveFromJson(json.To);
|
|
||||||
this.cc = EmailCollectionModel.reviveFromJson(json.Cc);
|
|
||||||
this.bcc = EmailCollectionModel.reviveFromJson(json.Bcc);
|
|
||||||
this.replyTo = EmailCollectionModel.reviveFromJson(json.ReplyTo);
|
|
||||||
this.deliveredTo = EmailCollectionModel.reviveFromJson(json.DeliveredTo);
|
|
||||||
this.unsubsribeLinks = Array.isNotEmpty(json.UnsubsribeLinks) ? json.UnsubsribeLinks : [];
|
|
||||||
|
|
||||||
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.fromEmailString(this.from.toString(true));
|
|
||||||
this.fromClearEmailString(this.from.toStringClear());
|
|
||||||
this.toEmailsString(this.to.toString(true));
|
|
||||||
this.toClearEmailsString(this.to.toStringClear());
|
|
||||||
|
|
||||||
this.threads(isArray(json.Threads) ? json.Threads : []);
|
|
||||||
|
|
||||||
this.initFlagsByJson(json);
|
|
||||||
this.computeSenderEmail();
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {AjaxJsonMessage} json
|
* @param {FetchJsonMessage} json
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
initUpdateByMessageJson(json) {
|
initUpdateByMessageJson(json) {
|
||||||
|
|
@ -314,22 +302,19 @@ class MessageModel extends AbstractModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {AjaxJsonMessage} json
|
* @param {FetchJsonMessage} json
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
initFlagsByJson(json) {
|
initFlagsByJson(json) {
|
||||||
let result = false;
|
let result = MessageModel.validJson(json);
|
||||||
if (json && 'Object/Message' === json['@Object']) {
|
if (result) {
|
||||||
this.unseen(!json.IsSeen);
|
this.unseen(!json.IsSeen);
|
||||||
this.flagged(!!json.IsFlagged);
|
this.flagged(!!json.IsFlagged);
|
||||||
this.answered(!!json.IsAnswered);
|
this.answered(!!json.IsAnswered);
|
||||||
this.forwarded(!!json.IsForwarded);
|
this.forwarded(!!json.IsForwarded);
|
||||||
this.isReadReceipt(!!json.IsReadReceipt);
|
this.isReadReceipt(!!json.IsReadReceipt);
|
||||||
this.deletedMark(!!json.IsDeleted);
|
this.deletedMark(!!json.IsDeleted);
|
||||||
|
|
||||||
result = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,19 +36,17 @@ export class MessageCollectionModel extends AbstractCollectionModel
|
||||||
static reviveFromJson(object, cached) {
|
static reviveFromJson(object, cached) {
|
||||||
let newCount = 0;
|
let newCount = 0;
|
||||||
return super.reviveFromJson(object, message => {
|
return super.reviveFromJson(object, message => {
|
||||||
if (message && 'Object/Message' === message['@Object']) {
|
message = MessageModel.reviveFromJson(message);
|
||||||
message = MessageModel.newInstanceFromJson(message);
|
if (message) {
|
||||||
if (message) {
|
if (hasNewMessageAndRemoveFromCache(message.folderFullNameRaw, message.uid) && 5 >= newCount) {
|
||||||
if (hasNewMessageAndRemoveFromCache(message.folderFullNameRaw, message.uid) && 5 >= newCount) {
|
++newCount;
|
||||||
++newCount;
|
message.newForAnimation(true);
|
||||||
message.newForAnimation(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
message.deleted(false);
|
|
||||||
|
|
||||||
cached ? initMessageFlagsFromCache(message) : storeMessageFlagsToCache(message);
|
|
||||||
return message;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message.deleted(false);
|
||||||
|
|
||||||
|
cached ? initMessageFlagsFromCache(message) : storeMessageFlagsToCache(message);
|
||||||
|
return message;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,20 +22,19 @@ class TemplateModel extends AbstractModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {boolean}
|
* @static
|
||||||
|
* @param {FetchJsonTemplate} json
|
||||||
|
* @returns {?TemplateModel}
|
||||||
*/
|
*/
|
||||||
parse(json) {
|
static reviveFromJson(json) {
|
||||||
let result = false;
|
const template = super.reviveFromJson(json);
|
||||||
if (json && 'Object/Template' === json['@Object']) {
|
if (template) {
|
||||||
this.id = pString(json.ID);
|
template.id = pString(json.ID);
|
||||||
this.name = pString(json.Name);
|
template.name = pString(json.Name);
|
||||||
this.body = pString(json.Body);
|
template.body = pString(json.Body);
|
||||||
this.populated = !!json.Populated;
|
template.populated = !!json.Populated;
|
||||||
|
|
||||||
result = true;
|
|
||||||
}
|
}
|
||||||
|
return template;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,10 +102,7 @@ class FiltersUserSettings {
|
||||||
this.serverError(false);
|
this.serverError(false);
|
||||||
|
|
||||||
this.filters(
|
this.filters(
|
||||||
data.Result.Filters.map(aItem => {
|
data.Result.Filters.map(aItem => FilterModel.reviveFromJson(aItem)).filter(v => v)
|
||||||
const filter = new FilterModel();
|
|
||||||
return filter && filter.parse(aItem) ? filter : null;
|
|
||||||
}).filter(v => v)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
this.modules(data.Result.Modules ? data.Result.Modules : {});
|
this.modules(data.Result.Modules ? data.Result.Modules : {});
|
||||||
|
|
|
||||||
|
|
@ -452,14 +452,13 @@ class MessageUserStore {
|
||||||
|
|
||||||
if (
|
if (
|
||||||
data &&
|
data &&
|
||||||
|
MessageModel.validJson(data.Result) &&
|
||||||
message &&
|
message &&
|
||||||
data.Result &&
|
|
||||||
'Object/Message' === data.Result['@Object'] &&
|
|
||||||
message.folderFullNameRaw === data.Result.Folder
|
message.folderFullNameRaw === data.Result.Folder
|
||||||
) {
|
) {
|
||||||
const threads = message.threads();
|
const threads = message.threads();
|
||||||
if (message.uid !== data.Result.Uid && 1 < threads.length && threads.includes(data.Result.Uid)) {
|
if (message.uid !== data.Result.Uid && 1 < threads.length && threads.includes(data.Result.Uid)) {
|
||||||
message = MessageModel.newInstanceFromJson(data.Result);
|
message = MessageModel.reviveFromJson(data.Result);
|
||||||
if (message) {
|
if (message) {
|
||||||
message.threads(threads);
|
message.threads(threads);
|
||||||
initMessageFlagsFromCache(message);
|
initMessageFlagsFromCache(message);
|
||||||
|
|
@ -641,7 +640,7 @@ class MessageUserStore {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} sResult
|
* @param {string} sResult
|
||||||
* @param {AjaxJsonDefaultResponse} oData
|
* @param {FetchJsonDefaultResponse} oData
|
||||||
* @param {boolean} bCached
|
* @param {boolean} bCached
|
||||||
*/
|
*/
|
||||||
onMessageResponse(sResult, oData, bCached) {
|
onMessageResponse(sResult, oData, bCached) {
|
||||||
|
|
|
||||||
|
|
@ -468,7 +468,7 @@ class ContactsPopupView extends AbstractViewNext {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} sResult
|
* @param {string} sResult
|
||||||
* @param {AjaxJsonDefaultResponse} oData
|
* @param {FetchJsonDefaultResponse} oData
|
||||||
*/
|
*/
|
||||||
deleteResponse(sResult, oData) {
|
deleteResponse(sResult, oData) {
|
||||||
if (500 < (StorageResultType.Success === sResult && oData && oData.Time ? pInt(oData.Time) : 0)) {
|
if (500 < (StorageResultType.Success === sResult && oData && oData.Time ? pInt(oData.Time) : 0)) {
|
||||||
|
|
@ -570,13 +570,11 @@ class ContactsPopupView extends AbstractViewNext {
|
||||||
|
|
||||||
if (StorageResultType.Success === result && data && data.Result && data.Result.List) {
|
if (StorageResultType.Success === result && data && data.Result && data.Result.List) {
|
||||||
if (Array.isNotEmpty(data.Result.List)) {
|
if (Array.isNotEmpty(data.Result.List)) {
|
||||||
list = data.Result.List.map(item => {
|
data.Result.List.forEach(item => {
|
||||||
const contact = new ContactModel();
|
item = ContactModel.reviveFromJson(item);
|
||||||
return contact.parse(item) ? contact : null;
|
item && list.push(item);
|
||||||
});
|
});
|
||||||
|
|
||||||
list = list.filter(v => v);
|
|
||||||
|
|
||||||
count = pInt(data.Result.Count);
|
count = pInt(data.Result.Count);
|
||||||
count = 0 < count ? count : 0;
|
count = 0 < count ? count : 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import Remote from 'Remote/User/Fetch';
|
||||||
|
|
||||||
import { popup, command } from 'Knoin/Knoin';
|
import { popup, command } from 'Knoin/Knoin';
|
||||||
import { AbstractViewNext } from 'Knoin/AbstractViewNext';
|
import { AbstractViewNext } from 'Knoin/AbstractViewNext';
|
||||||
|
import { TemplateModel } from 'Model/Template';
|
||||||
|
|
||||||
@popup({
|
@popup({
|
||||||
name: 'View/Popup/Template',
|
name: 'View/Popup/Template',
|
||||||
|
|
@ -133,8 +134,7 @@ class TemplatePopupView extends AbstractViewNext {
|
||||||
if (
|
if (
|
||||||
StorageResultType.Success === result &&
|
StorageResultType.Success === result &&
|
||||||
data &&
|
data &&
|
||||||
data.Result &&
|
TemplateModel.validJson(data.Result) &&
|
||||||
'Object/Template' === data.Result['@Object'] &&
|
|
||||||
null != data.Result.Body
|
null != data.Result.Body
|
||||||
) {
|
) {
|
||||||
template.body = data.Result.Body;
|
template.body = data.Result.Body;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue