And remove some memory cleanup due to issues with the Contacts view
This commit is contained in:
djmaze 2020-10-30 11:49:05 +01:00
parent 4e4ba12770
commit d0bcb5483a
4 changed files with 43 additions and 49 deletions

View file

@ -46,18 +46,20 @@ export class AbstractModel {
/** Called by delegateRunOnDestroy */ /** Called by delegateRunOnDestroy */
onDestroy() { onDestroy() {
/** clear ko.subscribe */ /** dispose ko subscribables */
this.subscribables.forEach(dispose); this.subscribables.forEach(dispose);
/** clear object entries */ /** clear object entries */
Object.entries(this).forEach(([key, value]) => { // Object.entries(this).forEach(([key, value]) => {
Object.values(this).forEach(value => {
/** clear CollectionModel */ /** clear CollectionModel */
let arr = ko.isObservableArray(value) ? value() : value; let arr = ko.isObservableArray(value) ? value() : value;
arr && arr.onDestroy && value.onDestroy(); arr && arr.onDestroy && value.onDestroy();
/** destroy ko.observable/ko.computed? */ /** destroy ko.observable/ko.computed? */
dispose(value); dispose(value);
/** clear object value */ /** clear object value */
this[key] = null; // this[key] = null; // TODO: issue with Contacts view
}); });
// this.subscribables = [];
} }
/** /**

View file

@ -4,6 +4,8 @@ import { i18n } from 'Common/Translator';
import { AbstractModel } from 'Knoin/AbstractModel'; import { AbstractModel } from 'Knoin/AbstractModel';
const trim = text => null == text ? "" : (text + "").trim();
class ContactPropertyModel extends AbstractModel { class ContactPropertyModel extends AbstractModel {
/** /**
* @param {number=} type = Enums.ContactPropertyType.Unknown * @param {number=} type = Enums.ContactPropertyType.Unknown
@ -34,6 +36,14 @@ class ContactPropertyModel extends AbstractModel {
}); });
} }
isType(type) {
return this.type && type === this.type();
}
isValid() {
return this.value && !!trim(this.value());
}
toJSON() { toJSON() {
return { return {
type: this.type(), type: this.type(),

View file

@ -29,8 +29,9 @@ import { ContactPropertyModel } from 'Model/ContactProperty';
import { popup, command, showScreenPopup, hideScreenPopup } from 'Knoin/Knoin'; import { popup, command, showScreenPopup, hideScreenPopup } from 'Knoin/Knoin';
import { AbstractViewNext } from 'Knoin/AbstractViewNext'; import { AbstractViewNext } from 'Knoin/AbstractViewNext';
const trim = text => null == text ? "" : (text + "").trim(), const CONTACTS_PER_PAGE = 50,
CONTACTS_PER_PAGE = 50; propertyIsMail = prop => prop.isType(ContactPropertyType.Email),
propertyIsName = prop => prop.isType(ContactPropertyType.FirstName) || prop.isType(ContactPropertyType.LastName);
@popup({ @popup({
name: 'View/Popup/Contacts', name: 'View/Popup/Contacts',
@ -74,8 +75,6 @@ class ContactsPopupView extends AbstractViewNext {
this.viewProperties = ko.observableArray([]); this.viewProperties = ko.observableArray([]);
const propertyFocused = property => !trim(property.value()) && !property.focused();
/* /*
// Somehow this is broken now when calling addNewProperty // Somehow this is broken now when calling addNewProperty
const fFastClearEmptyListHelper = list => { const fFastClearEmptyListHelper = list => {
@ -119,59 +118,44 @@ class ContactsPopupView extends AbstractViewNext {
this.sDefaultKeyScope = KeyState.ContactList; this.sDefaultKeyScope = KeyState.ContactList;
const
// propertyFocused = property => !property.isValid() && !property.focused(),
pagecount = () => Math.max(1, Math.ceil(this.contactsCount() / CONTACTS_PER_PAGE));
this.addComputables({ this.addComputables({
contactsPageCount: () => Math.max(1, Math.ceil(this.contactsCount() / CONTACTS_PER_PAGE)), contactsPageCount: pagecount,
contactsPaginator: computedPaginatorHelper(this.contactsPage, this.contactsPageCount), contactsPaginator: computedPaginatorHelper(this.contactsPage, pagecount),
viewPropertiesNames: () => viewPropertiesNames: () => this.viewProperties().filter(propertyIsName),
this.viewProperties().filter(
property => [ContactPropertyType.FirstName, ContactPropertyType.LastName].includes(property.type())
),
viewPropertiesOther: () => viewPropertiesEmails: () => this.viewProperties().filter(propertyIsMail),
this.viewProperties().filter(property => [ContactPropertyType.Nick].includes(property.type())),
viewPropertiesEmails: () => viewPropertiesOther: () => this.viewProperties().filter(property => property.isType(ContactPropertyType.Nick)),
this.viewProperties().filter(property => ContactPropertyType.Email === property.type()),
viewPropertiesWeb: () => this.viewProperties().filter(property => ContactPropertyType.Web === property.type()), viewPropertiesWeb: () => this.viewProperties().filter(property => property.isType(ContactPropertyType.Web)),
viewHasNonEmptyRequiredProperties: () => { viewPropertiesPhones: () => this.viewProperties().filter(property => property.isType(ContactPropertyType.Phone)),
const names = this.viewPropertiesNames(),
emails = this.viewPropertiesEmails(),
fFilter = property => !!trim(property.value());
return !!(names.find(fFilter) || emails.find(fFilter));
},
viewPropertiesPhones: () =>
this.viewProperties().filter(property => ContactPropertyType.Phone === property.type()),
viewPropertiesEmailsNonEmpty: () => this.viewPropertiesNames().filter(property => !!trim(property.value())),
contactHasValidName: () => !!this.viewProperties().find(prop => propertyIsName(prop) && prop.isValid()),
/*
viewPropertiesEmailsEmptyAndOnFocused: () => this.viewPropertiesEmails().filter(propertyFocused), viewPropertiesEmailsEmptyAndOnFocused: () => this.viewPropertiesEmails().filter(propertyFocused),
viewPropertiesPhonesEmptyAndOnFocused: () => this.viewPropertiesPhones().filter(propertyFocused), viewPropertiesPhonesEmptyAndOnFocused: () => this.viewPropertiesPhones().filter(propertyFocused),
viewPropertiesWebEmptyAndOnFocused: () => this.viewPropertiesWeb().filter(propertyFocused), viewPropertiesWebEmptyAndOnFocused: () => this.viewPropertiesWeb().filter(propertyFocused),
viewPropertiesOtherEmptyAndOnFocused: () => this.viewPropertiesOther().filter(propertyFocused), viewPropertiesOtherEmptyAndOnFocused: () => this.viewPropertiesOther().filter(propertyFocused),
*/
contactsChecked: () => this.contacts().filter(item => item.checked()),
contactsCheckedOrSelected: () => { contactsCheckedOrSelected: () => {
const checked = this.contactsChecked(), const checked = this.contacts().filter(item => item.checked && item.checked()),
selected = this.currentContact(); selected = this.currentContact();
return selected return selected
? checked.concat([selected]).unique() ? [...checked, selected].unique()
: checked; : checked;
}, },
contactsCheckedOrSelectedUids: () => this.contactsCheckedOrSelected().map(contact => contact.id), contactsCheckedOrSelectedUids: () => this.contactsCheckedOrSelected().map(contact => contact.id),
viewHash: () => '' + this.viewProperties().map(oItem => oItem.value()).join('') viewHash: () => '' + this.viewProperties().map(property => property.value && property.value()).join('')
}); });
this.search.subscribe(() => this.reloadContactList()); this.search.subscribe(() => this.reloadContactList());
@ -257,11 +241,10 @@ class ContactsPopupView extends AbstractViewNext {
this.search(''); this.search('');
} }
@command((self) => { @command(self =>
const bV = self.viewHasNonEmptyRequiredProperties(), !self.viewSaving() && !self.viewReadOnly()
bReadOnly = self.viewReadOnly(); && (self.contactHasValidName() || self.viewProperties().find(prop => propertyIsMail(prop) && prop.isValid()))
return !self.viewSaving() && bV && !bReadOnly; )
})
saveCommand() { saveCommand() {
this.viewSaving(true); this.viewSaving(true);
this.viewSaveTrigger(SaveSettingsStep.Animate); this.viewSaveTrigger(SaveSettingsStep.Animate);
@ -339,7 +322,7 @@ class ContactsPopupView extends AbstractViewNext {
} }
addNewOrFocusProperty(type, typeStr) { addNewOrFocusProperty(type, typeStr) {
const item = this.viewProperties().find(prop => type === prop.type()); const item = this.viewProperties().find(prop => prop.isType(type));
if (item) { if (item) {
item.focused(true); item.focused(true);
} else { } else {
@ -484,9 +467,8 @@ class ContactsPopupView extends AbstractViewNext {
this.viewID(id); this.viewID(id);
delegateRunOnDestroy(this.viewProperties()); // delegateRunOnDestroy(this.viewProperties());
// this.viewProperties([]);
this.viewProperties([]);
this.viewProperties(contact.properties); this.viewProperties(contact.properties);
this.watchDirty(false); this.watchDirty(false);

View file

@ -168,7 +168,7 @@
</div> </div>
<div data-bind="visible: !emptySelection()"> <div data-bind="visible: !emptySelection()">
<div class="form-horizontal top-part"> <div class="form-horizontal top-part">
<div class="control-group" data-bind="visible: !viewReadOnly() || 0 < viewPropertiesEmailsNonEmpty().length"> <div class="control-group" data-bind="visible: !viewReadOnly() || contactHasValidName()">
<label class="control-label remove-padding-top fix-width"> <label class="control-label remove-padding-top fix-width">
<i class="icon-user iconsize24"></i> <i class="icon-user iconsize24"></i>
</label> </label>