mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-30 12:39:20 +03:00
Prevent memory leaks in *Model
This commit is contained in:
parent
48a9a03762
commit
d7a4639d6b
22 changed files with 221 additions and 225 deletions
|
|
@ -1,5 +1,3 @@
|
|||
import ko from 'ko';
|
||||
|
||||
import { change } from 'Common/Links';
|
||||
|
||||
import { AbstractModel } from 'Knoin/AbstractModel';
|
||||
|
|
@ -15,10 +13,11 @@ class AccountModel extends AbstractModel {
|
|||
|
||||
this.email = email;
|
||||
|
||||
this.count = ko.observable(count);
|
||||
|
||||
this.deleteAccess = ko.observable(false);
|
||||
this.canBeDeleted = ko.observable(!!canBeDelete);
|
||||
this.addObservables({
|
||||
count: count,
|
||||
deleteAccess: false,
|
||||
canBeDeleted: !!canBeDelete
|
||||
});
|
||||
this.canBeEdit = this.canBeDeleted;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,16 +24,18 @@ class ComposeAttachmentModel extends AbstractModel {
|
|||
this.contentLocation = contentLocation;
|
||||
this.fromMessage = false;
|
||||
|
||||
this.fileName = ko.observable(fileName);
|
||||
this.size = ko.observable(size);
|
||||
this.tempName = ko.observable('');
|
||||
this.addObservables({
|
||||
fileName: fileName,
|
||||
size: size,
|
||||
tempName: '',
|
||||
|
||||
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);
|
||||
progress: 0,
|
||||
error: '',
|
||||
waiting: true,
|
||||
uploading: false,
|
||||
enabled: true,
|
||||
complete: false
|
||||
});
|
||||
|
||||
this.progressText = ko.computed(() => {
|
||||
const p = this.progress();
|
||||
|
|
@ -56,15 +58,6 @@ class ComposeAttachmentModel extends AbstractModel {
|
|||
|
||||
this.mimeType = ko.computed(() => File.getContentType(this.fileName()));
|
||||
this.fileExt = ko.computed(() => File.getExtension(this.fileName()));
|
||||
|
||||
this.regDisposables([
|
||||
this.progressText,
|
||||
this.progressStyle,
|
||||
this.title,
|
||||
this.friendlySize,
|
||||
this.mimeType,
|
||||
this.fileExt
|
||||
]);
|
||||
}
|
||||
|
||||
static fromAttachment(item)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
import ko from 'ko';
|
||||
|
||||
import { ContactPropertyModel } from 'Model/ContactProperty';
|
||||
import { ContactPropertyType } from 'Common/Enums';
|
||||
|
||||
|
|
@ -14,10 +12,12 @@ class ContactModel extends AbstractModel {
|
|||
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);
|
||||
this.addObservables({
|
||||
focused: false,
|
||||
selected: false,
|
||||
checked: false,
|
||||
deleted: false
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -17,12 +17,14 @@ class ContactPropertyModel extends AbstractModel {
|
|||
constructor(type = ContactPropertyType.Unknown, typeStr = '', value = '', focused = false, placeholder = '') {
|
||||
super();
|
||||
|
||||
this.type = ko.observable(pInt(type));
|
||||
this.typeStr = ko.observable(pString(typeStr));
|
||||
this.focused = ko.observable(!!focused);
|
||||
this.value = ko.observable(pString(value));
|
||||
this.addObservables({
|
||||
type: pInt(type),
|
||||
typeStr: pString(typeStr),
|
||||
focused: !!focused,
|
||||
value: pString(value),
|
||||
|
||||
this.placeholder = ko.observable(placeholder);
|
||||
placeholder: placeholder
|
||||
});
|
||||
|
||||
this.placeholderValue = ko.computed(() => {
|
||||
const v = this.placeholder();
|
||||
|
|
@ -30,8 +32,6 @@ class ContactPropertyModel extends AbstractModel {
|
|||
});
|
||||
|
||||
this.largeValue = ko.computed(() => ContactPropertyType.Note === this.type());
|
||||
|
||||
this.regDisposables([this.placeholderValue, this.largeValue]);
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
|
|
|||
|
|
@ -15,42 +15,38 @@ class FilterModel extends AbstractModel {
|
|||
constructor() {
|
||||
super();
|
||||
|
||||
this.enabled = ko.observable(true);
|
||||
|
||||
this.id = '';
|
||||
|
||||
this.name = ko.observable('');
|
||||
this.name.error = ko.observable(false);
|
||||
this.name.focused = ko.observable(false);
|
||||
this.addObservables({
|
||||
enabled: true,
|
||||
deleteAccess: false,
|
||||
canBeDeleted: true,
|
||||
|
||||
name: '',
|
||||
nameError: false,
|
||||
nameFocused: false,
|
||||
|
||||
conditionsType: FilterRulesType.Any,
|
||||
|
||||
// Actions
|
||||
actionValue: '',
|
||||
actionValueError: false,
|
||||
|
||||
actionValueSecond: '',
|
||||
actionValueThird: '',
|
||||
|
||||
actionValueFourth: '',
|
||||
actionValueFourthError: false,
|
||||
|
||||
actionMarkAsRead: false,
|
||||
|
||||
actionKeep: true,
|
||||
actionNoStop: false,
|
||||
|
||||
actionType: FiltersAction.MoveTo
|
||||
});
|
||||
|
||||
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);
|
||||
|
|
@ -115,14 +111,18 @@ class FilterModel extends AbstractModel {
|
|||
return result;
|
||||
});
|
||||
|
||||
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);
|
||||
this.addSubscribables({
|
||||
name: sValue => this.nameError(!sValue),
|
||||
actionValue: sValue => this.actionValueError(!sValue),
|
||||
actionType: () => {
|
||||
this.actionValue('');
|
||||
this.actionValueError(false);
|
||||
this.actionValueSecond('');
|
||||
this.actionValueThird('');
|
||||
this.actionValueFourth('');
|
||||
this.actionValueFourthError(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
generateID() {
|
||||
|
|
@ -131,14 +131,12 @@ class FilterModel extends AbstractModel {
|
|||
|
||||
verify() {
|
||||
if (!this.name()) {
|
||||
this.name.error(true);
|
||||
this.nameError(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.conditions().length) {
|
||||
if (this.conditions().find(cond => cond && !cond.verify())) {
|
||||
return false;
|
||||
}
|
||||
if (this.conditions().length && this.conditions().find(cond => cond && !cond.verify())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.actionValue()) {
|
||||
|
|
@ -149,13 +147,13 @@ class FilterModel extends AbstractModel {
|
|||
FiltersAction.Vacation
|
||||
].includes(this.actionType())
|
||||
) {
|
||||
this.actionValue.error(true);
|
||||
this.actionValueError(true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (FiltersAction.Forward === this.actionType() && !this.actionValue().includes('@')) {
|
||||
this.actionValue.error(true);
|
||||
this.actionValueError(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -164,12 +162,12 @@ class FilterModel extends AbstractModel {
|
|||
this.actionValueFourth() &&
|
||||
!this.actionValueFourth().includes('@')
|
||||
) {
|
||||
this.actionValueFourth.error(true);
|
||||
this.actionValueFourthError(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
this.name.error(false);
|
||||
this.actionValue.error(false);
|
||||
this.nameError(false);
|
||||
this.actionValueError(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -240,7 +238,7 @@ class FilterModel extends AbstractModel {
|
|||
filter.enabled(this.enabled());
|
||||
|
||||
filter.name(this.name());
|
||||
filter.name.error(this.name.error());
|
||||
filter.nameError(this.nameError());
|
||||
|
||||
filter.conditionsType(this.conditionsType());
|
||||
|
||||
|
|
@ -249,7 +247,7 @@ class FilterModel extends AbstractModel {
|
|||
filter.actionType(this.actionType());
|
||||
|
||||
filter.actionValue(this.actionValue());
|
||||
filter.actionValue.error(this.actionValue.error());
|
||||
filter.actionValueError(this.actionValueError());
|
||||
|
||||
filter.actionValueSecond(this.actionValueSecond());
|
||||
filter.actionValueThird(this.actionValueThird());
|
||||
|
|
|
|||
|
|
@ -8,13 +8,15 @@ class FilterConditionModel extends AbstractModel {
|
|||
constructor() {
|
||||
super();
|
||||
|
||||
this.field = ko.observable(FilterConditionField.From);
|
||||
this.type = ko.observable(FilterConditionType.Contains);
|
||||
this.value = ko.observable('');
|
||||
this.value.error = ko.observable(false);
|
||||
this.addObservables({
|
||||
field: FilterConditionField.From,
|
||||
type: FilterConditionType.Contains,
|
||||
value: '',
|
||||
valueError: false,
|
||||
|
||||
this.valueSecond = ko.observable('');
|
||||
this.valueSecond.error = ko.observable(false);
|
||||
valueSecond: '',
|
||||
valueSecondError: false
|
||||
});
|
||||
|
||||
this.template = ko.computed(() => {
|
||||
let template = '';
|
||||
|
|
@ -33,22 +35,22 @@ class FilterConditionModel extends AbstractModel {
|
|||
return template;
|
||||
}, this);
|
||||
|
||||
this.field.subscribe(() => {
|
||||
this.value('');
|
||||
this.valueSecond('');
|
||||
this.addSubscribables({
|
||||
field: () => {
|
||||
this.value('');
|
||||
this.valueSecond('');
|
||||
}
|
||||
});
|
||||
|
||||
this.regDisposables([this.template]);
|
||||
}
|
||||
|
||||
verify() {
|
||||
if (!this.value()) {
|
||||
this.value.error(true);
|
||||
this.valueError(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FilterConditionField.Header === this.field() && !this.valueSecond()) {
|
||||
this.valueSecond.error(true);
|
||||
this.valueSecondError(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ class FolderModel extends AbstractModel {
|
|||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = ko.observable('');
|
||||
this.fullName = '';
|
||||
this.fullNameRaw = '';
|
||||
this.fullNameHash = '';
|
||||
|
|
@ -23,23 +22,27 @@ class FolderModel extends AbstractModel {
|
|||
this.selectable = false;
|
||||
this.existen = true;
|
||||
|
||||
this.type = ko.observable(FolderType.User);
|
||||
this.addObservables({
|
||||
name: '',
|
||||
type: FolderType.User,
|
||||
|
||||
focused: false,
|
||||
selected: false,
|
||||
edited: false,
|
||||
subScribed: true,
|
||||
checkable: false,
|
||||
deleteAccess: false,
|
||||
|
||||
nameForEdit: '',
|
||||
|
||||
privateMessageCountAll: 0,
|
||||
privateMessageCountUnread: 0,
|
||||
|
||||
collapsedPrivate: true
|
||||
});
|
||||
|
||||
this.focused = ko.observable(false);
|
||||
this.selected = ko.observable(false);
|
||||
this.edited = ko.observable(false);
|
||||
this.subScribed = ko.observable(true);
|
||||
this.checkable = ko.observable(false);
|
||||
this.subFolders = ko.observableArray(new FolderCollectionModel);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -230,14 +233,15 @@ class FolderModel extends AbstractModel {
|
|||
)
|
||||
);
|
||||
|
||||
// subscribe
|
||||
folder.name.subscribe(value => folder.nameForEdit(value));
|
||||
folder.addSubscribables({
|
||||
name: value => folder.nameForEdit(value),
|
||||
|
||||
folder.edited.subscribe(value => value && folder.nameForEdit(folder.name()));
|
||||
edited: value => value && folder.nameForEdit(folder.name()),
|
||||
|
||||
folder.messageCountUnread.subscribe((unread) => {
|
||||
if (FolderType.Inbox === folder.type()) {
|
||||
dispatchEvent(new CustomEvent('mailbox.inbox-unread-count', {detail:unread}));
|
||||
messageCountUnread: unread => {
|
||||
if (FolderType.Inbox === folder.type()) {
|
||||
dispatchEvent(new CustomEvent('mailbox.inbox-unread-count', {detail:unread}));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,17 +10,20 @@ class IdentityModel extends AbstractModel {
|
|||
constructor(id, email) {
|
||||
super();
|
||||
|
||||
this.id = ko.observable(id || '');
|
||||
this.email = ko.observable(email);
|
||||
this.name = ko.observable('');
|
||||
this.addObservables({
|
||||
id: id || '',
|
||||
email: email,
|
||||
name: '',
|
||||
|
||||
this.replyTo = ko.observable('');
|
||||
this.bcc = ko.observable('');
|
||||
replyTo: '',
|
||||
bcc: '',
|
||||
|
||||
this.signature = ko.observable('');
|
||||
this.signatureInsertBefore = ko.observable(false);
|
||||
signature: '',
|
||||
signatureInsertBefore: false,
|
||||
|
||||
deleteAccess: false
|
||||
});
|
||||
|
||||
this.deleteAccess = ko.observable(false);
|
||||
this.canBeDeleted = ko.computed(() => !!this.id());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,57 +31,56 @@ class MessageModel extends AbstractModel {
|
|||
|
||||
this._reset();
|
||||
|
||||
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.addObservables({
|
||||
subject: '',
|
||||
subjectPrefix: '',
|
||||
subjectSuffix: '',
|
||||
size: 0,
|
||||
dateTimeStampInUTC: 0,
|
||||
priority: MessagePriority.Normal,
|
||||
|
||||
this.senderEmailsString = ko.observable('');
|
||||
this.senderClearEmailsString = ko.observable('');
|
||||
senderEmailsString: '',
|
||||
senderClearEmailsString: '',
|
||||
|
||||
this.newForAnimation = ko.observable(false);
|
||||
newForAnimation: false,
|
||||
|
||||
this.deleted = ko.observable(false);
|
||||
this.isDeleted = ko.observable(false);
|
||||
this.isUnseen = ko.observable(false);
|
||||
this.isFlagged = ko.observable(false);
|
||||
this.isAnswered = ko.observable(false);
|
||||
this.isForwarded = ko.observable(false);
|
||||
this.isReadReceipt = ko.observable(false);
|
||||
deleted: false,
|
||||
isDeleted: false,
|
||||
isUnseen: false,
|
||||
isFlagged: false,
|
||||
isAnswered: false,
|
||||
isForwarded: false,
|
||||
isReadReceipt: 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([]);
|
||||
focused: false,
|
||||
selected: false,
|
||||
checked: false,
|
||||
hasAttachments: false,
|
||||
|
||||
isHtml: false,
|
||||
hasImages: false,
|
||||
|
||||
isPgpSigned: false,
|
||||
isPgpEncrypted: false,
|
||||
pgpSignedVerifyStatus: SignedVerifyStatus.None,
|
||||
pgpSignedVerifyUser: '',
|
||||
|
||||
readReceipt: '',
|
||||
|
||||
hasUnseenSubMessage: false,
|
||||
hasFlaggedSubMessage: false
|
||||
});
|
||||
|
||||
this.attachmentIconClass = ko.computed(() =>
|
||||
File.getCombinedIconClass(this.hasAttachments() ? this.attachmentsSpecData() : [])
|
||||
);
|
||||
|
||||
this.isHtml = ko.observable(false);
|
||||
this.hasImages = ko.observable(false);
|
||||
this.attachments = ko.observable(new AttachmentCollectionModel);
|
||||
|
||||
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.hasUnseenSubMessage = ko.observable(false);
|
||||
this.hasFlaggedSubMessage = ko.observable(false);
|
||||
|
||||
this.attachments = ko.observableArray(new AttachmentCollectionModel);
|
||||
this.attachmentsSpecData = ko.observableArray([]);
|
||||
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]);
|
||||
}
|
||||
|
||||
_reset() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue