merge all Model JSON @Object parsers into a reviveFromJson()

This commit is contained in:
djmaze 2020-10-18 19:46:47 +02:00
parent 76648f04ae
commit 15e07a73e9
18 changed files with 378 additions and 411 deletions

View file

@ -528,10 +528,9 @@ class AppUser extends AbstractApp {
delegateRunOnDestroy(TemplateStore.templates());
TemplateStore.templates(
data.Result.Templates.map(templateData => {
const template = new TemplateModel();
return template.parse(templateData) ? template : null;
}).filter(v => v)
data.Result.Templates.map(templateData =>
TemplateModel.reviveFromJson(templateData)
).filter(v => v)
);
}
});

View file

@ -12,7 +12,14 @@ export class AbstractModel {
* @param {string} modelName = ''
*/
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) {
@ -29,4 +36,30 @@ export class AbstractModel {
}
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;
}
}

View file

@ -41,48 +41,36 @@ class AttachmentModel extends AbstractModel {
/**
* @static
* @param {AjaxJsonAttachment} json
* @param {FetchJsonAttachment} 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 = ((json.MimeType || '').toLowerCase()).trim();
this.fileName = json.FileName.trim();
static reviveFromJson(json) {
const attachment = super.reviveFromJson(json);
if (attachment) {
attachment.mimeType = ((json.MimeType || '').toLowerCase()).trim();
attachment.fileName = json.FileName.trim();
// if it is inline
this.isInline = !!json.IsInline;
attachment.isInline = !!json.IsInline;
// if inline image is linked with CID in html
// and 'src="cid:' or background-image:url(cid:)
this.isLinked = !!json.IsLinked;
this.isThumbnail = !!json.IsThumbnail;
this.cid = json.CID;
this.contentLocation = json.ContentLocation;
this.download = json.Download;
attachment.isLinked = !!json.IsLinked;
attachment.isThumbnail = !!json.IsThumbnail;
attachment.cid = json.CID;
attachment.contentLocation = json.ContentLocation;
attachment.download = json.Download;
this.folder = json.Folder;
this.uid = json.Uid;
this.mimeIndex = json.MimeIndex;
this.framed = !!json.Framed;
attachment.folder = json.Folder;
attachment.uid = json.Uid;
attachment.mimeIndex = json.MimeIndex;
attachment.framed = !!json.Framed;
this.friendlySize = File.friendlySize(json.EstimatedSize);
this.cidWithoutTags = this.cid.replace(/^<+/, '').replace(/>+$/, '');
attachment.friendlySize = File.friendlySize(json.EstimatedSize);
attachment.cidWithoutTags = attachment.cid.replace(/^<+/, '').replace(/>+$/, '');
this.fileNameExt = File.getExtension(this.fileName);
this.fileType = File.getType(this.fileNameExt, this.mimeType);
bResult = true;
attachment.fileNameExt = File.getExtension(attachment.fileName);
attachment.fileType = File.getType(attachment.fileNameExt, attachment.mimeType);
}
return bResult;
return attachment;
}
/**

View file

@ -10,7 +10,7 @@ export class AttachmentCollectionModel extends AbstractCollectionModel
* @returns {AttachmentCollectionModel}
*/
static reviveFromJson(items) {
let cb = attachment => AttachmentModel.newInstanceFromJson(attachment),
let cb = attachment => AttachmentModel.reviveFromJson(attachment),
result = super.reviveFromJson(items, cb);
if (!result) {
result = new AttachmentCollectionModel;

View file

@ -83,7 +83,7 @@ class ComposeAttachmentModel extends AbstractModel {
}
/**
* @param {AjaxJsonComposeAttachment} json
* @param {FetchJsonComposeAttachment} json
* @returns {boolean}
*/
initByUploadJson(json) {

View file

@ -46,28 +46,26 @@ class ContactModel extends AbstractModel {
}
/**
* @param {Object} oItem
* @returns {boolean}
* @static
* @param {FetchJsonContact} json
* @returns {?ContactModel}
*/
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;
static reviveFromJson(json) {
const contact = super.reviveFromJson(json);
if (contact) {
contact.idContact = pInt(json.IdContact);
contact.display = pString(json.Display);
contact.readOnly = !!json.ReadOnly;
if (Array.isNotEmpty(json.Properties)) {
json.Properties.forEach(property => {
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 result;
return contact;
}
/**

View file

@ -1,5 +1,7 @@
import { encodeHtml } from 'Common/UtilsUser';
import { AbstractModel } from 'Knoin/AbstractModel';
'use strict';
/**
@ -258,7 +260,7 @@ class Tokenizer
}
}
class EmailModel {
class EmailModel extends AbstractModel {
email = '';
name = '';
dkimStatus = '';
@ -271,6 +273,7 @@ class EmailModel {
* @param {string=} dkimValue = ''
*/
constructor(email = '', name = '', dkimStatus = 'none', dkimValue = '') {
super();
this.email = email;
this.name = name;
this.dkimStatus = dkimStatus;
@ -281,12 +284,20 @@ class EmailModel {
/**
* @static
* @param {AjaxJsonEmail} json
* @param {FetchJsonEmail} json
* @returns {?EmailModel}
*/
static newInstanceFromJson(json) {
const email = new EmailModel();
return email.initByJson(json) ? email : null;
static reviveFromJson(json) {
const email = super.reviveFromJson(json);
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());
}
/**
* @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=} wrapWithLink = false

View file

@ -12,7 +12,7 @@ export class EmailCollectionModel extends AbstractCollectionModel
static reviveFromJson(items) {
let result = new EmailCollectionModel;
Array.isArray(items) && items.forEach(email => {
email = EmailModel.newInstanceFromJson(email);
email = EmailModel.reviveFromJson(email);
email && result.push(email);
});
return result;

View file

@ -207,19 +207,24 @@ class FilterModel extends AbstractModel {
this.actionValueFourth(AccountStore.getEmailAddresses().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);
/**
* @static
* @param {FetchJsonFilter} json
* @returns {?FilterModel}
*/
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)) {
this.conditions(
filter.conditions(
json.Conditions.map(aData => {
const filterCondition = new FilterConditionModel();
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));
this.actionValueSecond(pString(json.ActionValueSecond));
this.actionValueThird(pString(json.ActionValueThird));
this.actionValueFourth(pString(json.ActionValueFourth));
filter.actionValue(pString(json.ActionValue));
filter.actionValueSecond(pString(json.ActionValueSecond));
filter.actionValueThird(pString(json.ActionValueThird));
filter.actionValueFourth(pString(json.ActionValueFourth));
this.actionNoStop(!json.Stop);
this.actionKeep(!!json.Keep);
this.actionMarkAsRead(!!json.MarkAsRead);
result = true;
filter.actionNoStop(!json.Stop);
filter.actionKeep(!!json.Keep);
filter.actionMarkAsRead(!!json.MarkAsRead);
}
return result;
return filter;
}
cloneSelf() {

View file

@ -43,82 +43,89 @@ class FolderModel extends AbstractModel {
/**
* @static
* @param {AjaxJsonFolder} json
* @param {FetchJsonFolder} json
* @returns {?FolderModel}
*/
static newInstanceFromJson(json) {
const folder = new FolderModel();
return folder.initByJson(json) ? folder.initComputed() : null;
}
static reviveFromJson(json) {
const folder = super.reviveFromJson(json);
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;
/**
* @returns {FolderModel}
*/
initComputed() {
this.isInbox = ko.computed(() => FolderType.Inbox === this.type());
folder.subScribed(!!json.IsSubscribed);
folder.checkable(!!json.Checkable);
this.hasSubScribedSubfolders = ko.computed(
folder.isInbox = ko.computed(() => FolderType.Inbox === folder.type());
folder.hasSubScribedSubfolders = ko.computed(
() =>
!!this.subFolders().find(
!!folder.subFolders().find(
oFolder => (oFolder.subScribed() || oFolder.hasSubScribedSubfolders()) && !oFolder.isSystemFolder()
)
);
this.canBeEdited = ko.computed(() => FolderType.User === this.type() && this.existen && this.selectable);
folder.canBeEdited = ko.computed(() => FolderType.User === folder.type() && folder.existen && folder.selectable);
this.visible = ko.computed(() => {
const isSubScribed = this.subScribed(),
isSubFolders = this.hasSubScribedSubfolders();
folder.visible = ko.computed(() => {
const isSubScribed = folder.subScribed(),
isSubFolders = folder.hasSubScribedSubfolders();
return isSubScribed || (isSubFolders && (!this.existen || !this.selectable));
return isSubScribed || (isSubFolders && (!folder.existen || !folder.selectable));
});
this.isSystemFolder = ko.computed(() => FolderType.User !== this.type());
folder.isSystemFolder = ko.computed(() => FolderType.User !== folder.type());
this.hidden = ko.computed(() => {
const isSystem = this.isSystemFolder(),
isSubFolders = this.hasSubScribedSubfolders();
folder.hidden = ko.computed(() => {
const isSystem = folder.isSystemFolder(),
isSubFolders = folder.hasSubScribedSubfolders();
return (isSystem && !isSubFolders) || (!this.selectable && !isSubFolders);
return (isSystem && !isSubFolders) || (!folder.selectable && !isSubFolders);
});
this.selectableForFolderList = ko.computed(() => !this.isSystemFolder() && this.selectable);
folder.selectableForFolderList = ko.computed(() => !folder.isSystemFolder() && folder.selectable);
this.messageCountAll = ko
folder.messageCountAll = ko
.computed({
read: this.privateMessageCountAll,
read: folder.privateMessageCountAll,
write: (iValue) => {
if (isPosNumeric(iValue, true)) {
this.privateMessageCountAll(iValue);
folder.privateMessageCountAll(iValue);
} else {
this.privateMessageCountAll.valueHasMutated();
folder.privateMessageCountAll.valueHasMutated();
}
}
})
.extend({ notify: 'always' });
this.messageCountUnread = ko
folder.messageCountUnread = ko
.computed({
read: this.privateMessageCountUnread,
read: folder.privateMessageCountUnread,
write: (value) => {
if (isPosNumeric(value, true)) {
this.privateMessageCountUnread(value);
folder.privateMessageCountUnread(value);
} else {
this.privateMessageCountUnread.valueHasMutated();
folder.privateMessageCountUnread.valueHasMutated();
}
}
})
.extend({ notify: 'always' });
this.printableUnreadCount = ko.computed(() => {
const count = this.messageCountAll(),
unread = this.messageCountUnread(),
type = this.type();
folder.printableUnreadCount = ko.computed(() => {
const count = folder.messageCountAll(),
unread = folder.messageCountUnread(),
type = folder.type();
if (0 < count) {
if (FolderType.Draft === type) {
return '' + count;
} else if (
}
if (
0 < unread &&
FolderType.Trash !== type &&
FolderType.Archive !== type &&
@ -131,24 +138,23 @@ class FolderModel extends AbstractModel {
return '';
});
this.canBeDeleted = ko.computed(() => {
const bSystem = this.isSystemFolder();
return !bSystem && !this.subFolders().length;
});
this.canBeSubScribed = ko.computed(
() => !this.isSystemFolder() && this.selectable
folder.canBeDeleted = ko.computed(
() => !folder.isSystemFolder() && !folder.subFolders().length
);
this.canBeChecked = this.canBeSubScribed;
folder.canBeSubScribed = ko.computed(
() => !folder.isSystemFolder() && folder.selectable
);
this.localName = ko.computed(() => {
folder.canBeChecked = folder.canBeSubScribed;
folder.localName = ko.computed(() => {
translatorTrigger();
let name = this.name();
const type = this.type();
let name = folder.name();
const type = folder.type();
if (this.isSystemFolder()) {
if (folder.isSystemFolder()) {
switch (type) {
case FolderType.Inbox:
name = i18n('FOLDER_LIST/INBOX_NAME');
@ -175,14 +181,14 @@ class FolderModel extends AbstractModel {
return name;
});
this.manageFolderSystemName = ko.computed(() => {
folder.manageFolderSystemName = ko.computed(() => {
translatorTrigger();
let suffix = '';
const type = this.type(),
name = this.name();
const type = folder.type(),
name = folder.name();
if (this.isSystemFolder()) {
if (folder.isSystemFolder()) {
switch (type) {
case FolderType.Inbox:
suffix = '(' + i18n('FOLDER_LIST/INBOX_NAME') + ')';
@ -213,71 +219,44 @@ class FolderModel extends AbstractModel {
return suffix;
});
this.collapsed = ko.computed({
read: () => !this.hidden() && this.collapsedPrivate(),
folder.collapsed = ko.computed({
read: () => !folder.hidden() && folder.collapsedPrivate(),
write: (value) => {
this.collapsedPrivate(value);
folder.collapsedPrivate(value);
}
});
this.hasUnreadMessages = ko.computed(() => 0 < this.messageCountUnread() && this.printableUnreadCount());
folder.hasUnreadMessages = ko.computed(() => 0 < folder.messageCountUnread() && folder.printableUnreadCount());
this.hasSubScribedUnreadMessagesSubfolders = ko.computed(
folder.hasSubScribedUnreadMessagesSubfolders = ko.computed(
() =>
!!this.subFolders().find(
!!folder.subFolders().find(
folder => folder.hasUnreadMessages() || folder.hasSubScribedUnreadMessagesSubfolders()
)
);
// subscribe
this.name.subscribe(value => this.nameForEdit(value));
folder.name.subscribe(value => folder.nameForEdit(value));
this.edited.subscribe(value => value && this.nameForEdit(this.name()));
folder.edited.subscribe(value => value && folder.nameForEdit(folder.name()));
this.messageCountUnread.subscribe((unread) => {
if (FolderType.Inbox === this.type()) {
folder.messageCountUnread.subscribe((unread) => {
if (FolderType.Inbox === folder.type()) {
dispatchEvent(new CustomEvent('mailbox.inbox-unread-count', {detail:unread}));
}
});
return this;
}
return folder;
}
/**
* @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;
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;
return 'e-collapsed-sign ' + (this.hasSubScribedSubfolders()
? (this.collapsed() ? 'icon-right-mini' : 'icon-down-mini')
: 'icon-none'
);
}
/**

View file

@ -47,7 +47,7 @@ export class FolderCollectionModel extends AbstractCollectionModel
bDisplaySpecSetting = FolderStore.displaySpecSetting();
return super.reviveFromJson(object, (oFolder, self) => {
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]) {
oCacheFolder.type(FolderType.Inbox);
Cache.setFolderInboxName(oFolder.FullNameRaw);

View file

@ -93,12 +93,49 @@ class MessageModel extends AbstractModel {
/**
* @static
* @param {AjaxJsonMessage} oJsonMessage
* @param {FetchJsonMessage} json
* @returns {?MessageModel}
*/
static newInstanceFromJson(json) {
const oMessageModel = new MessageModel();
return oMessageModel.initByJson(json) ? oMessageModel : null;
static reviveFromJson(json) {
const oMessageModel = super.reviveFromJson(json);
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() {
@ -206,7 +243,8 @@ class MessageModel extends AbstractModel {
}
setFromJson(json) {
if (json && 'Object/Message' === json['@Object']) {
let result = MessageModel.validJson(json);
if (result) {
let priority = pInt(json.Priority);
this.priority(
[MessagePriority.High, MessagePriority.Low].includes(priority) ? priority : MessagePriority.Normal
@ -216,62 +254,12 @@ class MessageModel extends AbstractModel {
this.hasAttachments(!!json.HasAttachments);
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;
}
/**
* @param {AjaxJsonMessage} json
* @param {FetchJsonMessage} json
* @returns {boolean}
*/
initUpdateByMessageJson(json) {
@ -314,22 +302,19 @@ class MessageModel extends AbstractModel {
}
/**
* @param {AjaxJsonMessage} json
* @param {FetchJsonMessage} json
* @returns {boolean}
*/
initFlagsByJson(json) {
let result = false;
if (json && 'Object/Message' === json['@Object']) {
let result = MessageModel.validJson(json);
if (result) {
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;
}

View file

@ -36,8 +36,7 @@ export class MessageCollectionModel extends AbstractCollectionModel
static reviveFromJson(object, cached) {
let newCount = 0;
return super.reviveFromJson(object, message => {
if (message && 'Object/Message' === message['@Object']) {
message = MessageModel.newInstanceFromJson(message);
message = MessageModel.reviveFromJson(message);
if (message) {
if (hasNewMessageAndRemoveFromCache(message.folderFullNameRaw, message.uid) && 5 >= newCount) {
++newCount;
@ -49,7 +48,6 @@ export class MessageCollectionModel extends AbstractCollectionModel
cached ? initMessageFlagsFromCache(message) : storeMessageFlagsToCache(message);
return message;
}
}
});
}
}

View file

@ -22,20 +22,19 @@ class TemplateModel extends AbstractModel {
}
/**
* @returns {boolean}
* @static
* @param {FetchJsonTemplate} json
* @returns {?TemplateModel}
*/
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;
static reviveFromJson(json) {
const template = super.reviveFromJson(json);
if (template) {
template.id = pString(json.ID);
template.name = pString(json.Name);
template.body = pString(json.Body);
template.populated = !!json.Populated;
}
return result;
return template;
}
}

View file

@ -102,10 +102,7 @@ class FiltersUserSettings {
this.serverError(false);
this.filters(
data.Result.Filters.map(aItem => {
const filter = new FilterModel();
return filter && filter.parse(aItem) ? filter : null;
}).filter(v => v)
data.Result.Filters.map(aItem => FilterModel.reviveFromJson(aItem)).filter(v => v)
);
this.modules(data.Result.Modules ? data.Result.Modules : {});

View file

@ -452,14 +452,13 @@ class MessageUserStore {
if (
data &&
MessageModel.validJson(data.Result) &&
message &&
data.Result &&
'Object/Message' === data.Result['@Object'] &&
message.folderFullNameRaw === data.Result.Folder
) {
const threads = message.threads();
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) {
message.threads(threads);
initMessageFlagsFromCache(message);
@ -641,7 +640,7 @@ class MessageUserStore {
/**
* @param {string} sResult
* @param {AjaxJsonDefaultResponse} oData
* @param {FetchJsonDefaultResponse} oData
* @param {boolean} bCached
*/
onMessageResponse(sResult, oData, bCached) {

View file

@ -468,7 +468,7 @@ class ContactsPopupView extends AbstractViewNext {
/**
* @param {string} sResult
* @param {AjaxJsonDefaultResponse} oData
* @param {FetchJsonDefaultResponse} oData
*/
deleteResponse(sResult, oData) {
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 (Array.isNotEmpty(data.Result.List)) {
list = data.Result.List.map(item => {
const contact = new ContactModel();
return contact.parse(item) ? contact : null;
data.Result.List.forEach(item => {
item = ContactModel.reviveFromJson(item);
item && list.push(item);
});
list = list.filter(v => v);
count = pInt(data.Result.Count);
count = 0 < count ? count : 0;
}

View file

@ -8,6 +8,7 @@ import Remote from 'Remote/User/Fetch';
import { popup, command } from 'Knoin/Knoin';
import { AbstractViewNext } from 'Knoin/AbstractViewNext';
import { TemplateModel } from 'Model/Template';
@popup({
name: 'View/Popup/Template',
@ -133,8 +134,7 @@ class TemplatePopupView extends AbstractViewNext {
if (
StorageResultType.Success === result &&
data &&
data.Result &&
'Object/Template' === data.Result['@Object'] &&
TemplateModel.validJson(data.Result) &&
null != data.Result.Body
) {
template.body = data.Result.Body;