diff --git a/dev/Common/Enums.js b/dev/Common/Enums.js index fc4477725..2505e0c99 100644 --- a/dev/Common/Enums.js +++ b/dev/Common/Enums.js @@ -330,7 +330,7 @@ export const ContactPropertyType = { FirstName: 15, LastName: 16, - MiddleName: 16, + MiddleName: 17, Nick: 18, NamePrefix: 20, diff --git a/dev/Model/Contact.js b/dev/Model/Contact.js index 5080c60de..91aac574e 100644 --- a/dev/Model/Contact.js +++ b/dev/Model/Contact.js @@ -1,5 +1,6 @@ import ko from 'ko'; +import { ContactPropertyModel } from 'Model/ContactProperty'; import { ContactPropertyType } from 'Common/Enums'; import { pInt, pString } from 'Common/Utils'; @@ -56,17 +57,48 @@ class ContactModel extends AbstractModel { contact.display = pString(json.display); contact.readOnly = !!json.readOnly; + let list = []; if (Array.isNotEmpty(json.properties)) { json.Properties.forEach(property => { - if (property && property.Type && null != property.Value && null != property.TypeStr) { - contact.properties.push([pInt(property.Type), pString(property.Value), pString(property.TypeStr)]); - } + property = ContactPropertyModel.reviveFromJson(property); + property && list.push(property); }); } + contact.properties = list; + contact.initDefaultProperties(); } return contact; } + initDefaultProperties() { + let list = this.properties; + list.sort((p1,p2) =>{ + if (p2.type() == ContactPropertyType.FirstName) { + return 1; + } + if (p1.type() == ContactPropertyType.FirstName || p1.type() == ContactPropertyType.LastName) { + return -1; + } + if (p2.type() == ContactPropertyType.LastName) { + return 1; + } + return 0; + }); + let found = list.find(prop => prop.type() == ContactPropertyType.LastName); + if (!found) { + found = new ContactPropertyModel(ContactPropertyType.LastName); + list.unshift(found); + } + found.placeholder('CONTACTS/PLACEHOLDER_ENTER_LAST_NAME'); + found = list.find(prop => prop.type() == ContactPropertyType.FirstName); + if (!found) { + found = new ContactPropertyModel(ContactPropertyType.FirstName); + list.unshift(found); + } + found.placeholder('CONTACTS/PLACEHOLDER_ENTER_FIRST_NAME'); + this.properties = list; + } + /** * @returns {string} */ diff --git a/dev/Model/ContactProperty.js b/dev/Model/ContactProperty.js index 12d1f8f4e..7856bc224 100644 --- a/dev/Model/ContactProperty.js +++ b/dev/Model/ContactProperty.js @@ -33,6 +33,17 @@ class ContactPropertyModel extends AbstractModel { this.regDisposables([this.placeholderValue, this.largeValue]); } + + static reviveFromJson(json) { + const property = super.reviveFromJson(json); + if (property) { + property.type(pInt(property.type)); + property.typeStr(pInt(property.typeStr)); + property.value(pString(json.value)); + return property; + } + return null; + } } export { ContactPropertyModel, ContactPropertyModel as default }; diff --git a/dev/Model/Email.js b/dev/Model/Email.js index 167b9712c..434a78b4b 100644 --- a/dev/Model/Email.js +++ b/dev/Model/Email.js @@ -289,15 +289,14 @@ class EmailModel extends AbstractModel { */ 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(); + if (email) { + email.name = json.Name; + email.email = json.Email; + email.dkimStatus = (json.DkimStatus || ''); + email.dkimValue = (json.DkimValue || ''); email.clearDuplicateName(); - return email; } - return null; + return email; } /** diff --git a/dev/Model/Filter.js b/dev/Model/Filter.js index 4ae6374f3..81b26116a 100644 --- a/dev/Model/Filter.js +++ b/dev/Model/Filter.js @@ -225,10 +225,7 @@ class FilterModel extends AbstractModel { if (Array.isNotEmpty(json.Conditions)) { filter.conditions( - json.Conditions.map(aData => { - const filterCondition = new FilterConditionModel(); - return filterCondition && filterCondition.parse(aData) ? filterCondition : null; - }).filter(v => v) + json.Conditions.map(aData => FilterConditionModel.reviveFromJson(aData)).filter(v => v) ); } diff --git a/dev/Model/FilterCondition.js b/dev/Model/FilterCondition.js index ddd53c71e..80e78cfcf 100644 --- a/dev/Model/FilterCondition.js +++ b/dev/Model/FilterCondition.js @@ -56,17 +56,15 @@ class FilterConditionModel extends AbstractModel { return true; } - parse(json) { - if (json && json.Field && json.Type) { - this.field(pString(json.Field)); - this.type(pString(json.Type)); - this.value(pString(json.Value)); - this.valueSecond(pString(json.ValueSecond)); - - return true; + static reviveFromJson(json) { + const filter = super.reviveFromJson(json); + if (filter) { + this.field(pString(json.field)); + this.type(pString(json.type)); + this.value(pString(json.value)); + this.valueSecond(pString(json.valueSecond)); } - - return false; + return filter; } toJson() { diff --git a/dev/View/Popup/Contacts.js b/dev/View/Popup/Contacts.js index f8db23177..b2dd75619 100644 --- a/dev/View/Popup/Contacts.js +++ b/dev/View/Popup/Contacts.js @@ -489,10 +489,7 @@ class ContactsPopupView extends AbstractViewNext { * @param {?ContactModel} contact */ populateViewContact(contact) { - let id = '', - lastName = '', - firstName = ''; - const list = []; + let id = ''; this.watchHash(false); @@ -501,49 +498,18 @@ class ContactsPopupView extends AbstractViewNext { if (contact) { id = contact.id; - if (Array.isNotEmpty(contact.properties)) { - contact.properties.forEach(property => { - if (property && property[0]) { - if (ContactPropertyType.LastName === property[0]) { - lastName = property[1]; - } else if (ContactPropertyType.FirstName === property[0]) { - firstName = property[1]; - } else { - list.push(new ContactPropertyModel(property[0], property[2] || '', property[1])); - } - } - }); - } - this.viewReadOnly(!!contact.readOnly); + } else { + contact = new ContactModel; + contact.initDefaultProperties(); } - list.unshift( - new ContactPropertyModel( - ContactPropertyType.LastName, - '', - lastName, - false, - this.getPropertyPlaceholder(ContactPropertyType.LastName) - ) - ); - - list.unshift( - new ContactPropertyModel( - ContactPropertyType.FirstName, - '', - firstName, - !contact, - this.getPropertyPlaceholder(ContactPropertyType.FirstName) - ) - ); - this.viewID(id); delegateRunOnDestroy(this.viewProperties()); this.viewProperties([]); - this.viewProperties(list); + this.viewProperties(contact.properties); this.watchDirty(false); this.watchHash(true); diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/Classes/Property.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/Classes/Property.php index 316421c82..01f9a3666 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/Classes/Property.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/Classes/Property.php @@ -151,14 +151,14 @@ class Property implements \JsonSerializable // Simple hack if ($this && $this->IsWeb()) { - $this->Value = \preg_replace('/(skype|ftp|http[s]?)\\\:\/\//i', '$1://', $this->Value); + $this->Value = \preg_replace('#(https?)\\\://#i', '$1://', $this->Value); } return array( - '@Object' => 'Object/Property', - 'IdProperty' => $this->IdProperty, - 'Type' => $this->Type, - 'TypeStr' => $this->TypeStr, - 'Value' => \MailSo\Base\Utils::Utf8Clear($this->Value) + '@Object' => 'Object/ContactProperty', + 'id' => $this->IdProperty, + 'type' => $this->Type, + 'typeStr' => $this->TypeStr, + 'value' => \MailSo\Base\Utils::Utf8Clear($this->Value) )); } } diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/Filters/Classes/FilterCondition.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/Filters/Classes/FilterCondition.php index 396d4f913..6f27aabf9 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/Filters/Classes/FilterCondition.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/Filters/Classes/FilterCondition.php @@ -91,11 +91,11 @@ class FilterCondition implements \JsonSerializable public function jsonSerialize() { return array( -// '@Object' => 'Object/FilterCondition', - 'Field' => $this->Field(), - 'Type' => $this->Type(), - 'Value' => $this->Value(), - 'ValueSecond' => $this->ValueSecond() + '@Object' => 'Object/FilterCondition', + 'field' => $this->Field(), + 'type' => $this->Type(), + 'value' => $this->Value(), + 'valueSecond' => $this->ValueSecond() ); } }