mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-30 12:39:20 +03:00
Improved new AddressBook system
This commit is contained in:
parent
497193750b
commit
c9ad0ef170
53 changed files with 589 additions and 459 deletions
|
|
@ -79,12 +79,12 @@ export class JCard {
|
|||
* @param arg the field, or a VCardProperty object
|
||||
* @param value the value for the VCardProperty object
|
||||
* @param params the parameters for the VCardProperty object
|
||||
* @param group the group for the VCardProperty object
|
||||
* @param type the type for the VCardProperty object
|
||||
*/
|
||||
set(arg, value, params, group)
|
||||
set(arg, value, params, type)
|
||||
{
|
||||
if (typeof arg === 'string') {
|
||||
arg = new VCardProperty(String(arg), value, params, group);
|
||||
arg = new VCardProperty(String(arg), value, params, type);
|
||||
}
|
||||
if (!(arg instanceof VCardProperty)) {
|
||||
throw new Error('invalid argument of VCard.set(), expects string arguments or a VCardProperty');
|
||||
|
|
@ -94,11 +94,11 @@ export class JCard {
|
|||
return arg;
|
||||
}
|
||||
|
||||
add(arg, value, params, group)
|
||||
add(arg, value, params, type)
|
||||
{
|
||||
// string arguments
|
||||
if (typeof arg === 'string') {
|
||||
arg = new VCardProperty(String(arg), value, params, group);
|
||||
arg = new VCardProperty(String(arg), value, params, type);
|
||||
}
|
||||
if (!(arg instanceof VCardProperty)) {
|
||||
throw new Error('invalid argument of VCard.add(), expects string arguments or a VCardProperty');
|
||||
|
|
|
|||
|
|
@ -108,12 +108,16 @@ export class ContactModel extends AbstractModel {
|
|||
middleName: '', // MiddleName
|
||||
namePrefix: '', // NamePrefix
|
||||
nameSuffix: '', // NameSuffix
|
||||
nickname: null
|
||||
nickname: null,
|
||||
|
||||
encryptpref: '',
|
||||
signpref: ''
|
||||
});
|
||||
// this.email = koArrayWithDestroy();
|
||||
this.email = ko.observableArray();
|
||||
this.tel = ko.observableArray();
|
||||
this.url = ko.observableArray();
|
||||
this.adr = ko.observableArray();
|
||||
|
||||
this.addComputables({
|
||||
hasValidName: () => !!(this.givenName() || this.surName()),
|
||||
|
|
@ -156,7 +160,7 @@ export class ContactModel extends AbstractModel {
|
|||
|
||||
/**
|
||||
* @static
|
||||
* @param {FetchJsonContact} json
|
||||
* @param {jCard} json
|
||||
* @returns {?ContactModel}
|
||||
*/
|
||||
static reviveFromJson(json) {
|
||||
|
|
@ -181,6 +185,26 @@ export class ContactModel extends AbstractModel {
|
|||
});
|
||||
});
|
||||
|
||||
props = jCard.get('adr');
|
||||
props && props.forEach(prop => {
|
||||
contact.adr.push({
|
||||
street: ko.observable(prop.value[2]),
|
||||
street_ext: ko.observable(prop.value[1]),
|
||||
locality: ko.observable(prop.value[3]),
|
||||
region: ko.observable(prop.value[4]),
|
||||
postcode: ko.observable(prop.value[5]),
|
||||
pobox: ko.observable(prop.value[0]),
|
||||
country: ko.observable(prop.value[6]),
|
||||
preferred: ko.observable(prop.params.pref),
|
||||
type: ko.observable(prop.params.type) // HOME | WORK
|
||||
});
|
||||
});
|
||||
|
||||
props = jCard.getOne('x-Crypto');
|
||||
contact.signpref(props?.params.signpref || 'Ask');
|
||||
contact.encryptpref(props?.params.encryptpref || 'Ask');
|
||||
// contact.encryptpref(props?.params.allowed || 'PGP/INLINE,PGP/MIME,S/MIME,S/MIMEOpaque');
|
||||
|
||||
contact.jCard = jCard;
|
||||
}
|
||||
return contact;
|
||||
|
|
@ -249,6 +273,12 @@ export class ContactModel extends AbstractModel {
|
|||
values.forEach(value => value && jCard.add(field, value));
|
||||
});
|
||||
|
||||
jCard.set('x-Crypto', '', {
|
||||
allowed: 'PGP/INLINE,PGP/MIME,S/MIME,S/MIMEOpaque',
|
||||
signpref: this.signpref(),
|
||||
encryptpref: this.encryptpref()
|
||||
}, 'x-crypto');
|
||||
|
||||
// Done by server
|
||||
// jCard.set('rev', '2022-05-21T10:59:52Z')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,86 +0,0 @@
|
|||
import { pInt, pString } from 'Common/Utils';
|
||||
import { i18n } from 'Common/Translator';
|
||||
|
||||
import { AbstractModel } from 'Knoin/AbstractModel';
|
||||
|
||||
const trim = text => null == text ? "" : (text + "").trim();
|
||||
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
export const ContactPropertyType = {
|
||||
Unknown: 0,
|
||||
|
||||
FullName: 10,
|
||||
|
||||
FirstName: 15,
|
||||
LastName: 16,
|
||||
MiddleName: 17,
|
||||
Nick: 18,
|
||||
|
||||
NamePrefix: 20,
|
||||
NameSuffix: 21,
|
||||
|
||||
Email: 30,
|
||||
Phone: 31,
|
||||
Web: 32,
|
||||
|
||||
Birthday: 40,
|
||||
|
||||
Facebook: 90,
|
||||
Skype: 91,
|
||||
GitHub: 92,
|
||||
|
||||
Note: 110,
|
||||
|
||||
Custom: 250
|
||||
};
|
||||
|
||||
export class ContactPropertyModel extends AbstractModel {
|
||||
/**
|
||||
* @param {number=} type = Enums.ContactPropertyType.Unknown
|
||||
* @param {string=} typeStr = ''
|
||||
* @param {string=} value = ''
|
||||
* @param {boolean=} focused = false
|
||||
* @param {string=} placeholder = ''
|
||||
*/
|
||||
constructor(type = ContactPropertyType.Unknown, typeStr = '', value = '', focused = false, placeholder = '') {
|
||||
super();
|
||||
|
||||
this.addObservables({
|
||||
type: pInt(type),
|
||||
typeStr: pString(typeStr),
|
||||
focused: !!focused,
|
||||
value: pString(value),
|
||||
|
||||
placeholder: placeholder
|
||||
});
|
||||
|
||||
this.addComputables({
|
||||
placeholderValue: () => {
|
||||
const v = this.placeholder();
|
||||
return v ? i18n(v) : '';
|
||||
},
|
||||
|
||||
largeValue: () => ContactPropertyType.Note === this.type()
|
||||
});
|
||||
}
|
||||
|
||||
isType(type) {
|
||||
return this.type && type === this.type();
|
||||
}
|
||||
|
||||
isValid() {
|
||||
return this.value && !!trim(this.value());
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
type: this.type(),
|
||||
typeStr: this.typeStr(),
|
||||
value: this.value()
|
||||
};
|
||||
}
|
||||
|
||||
// static reviveFromJson(json) {}
|
||||
}
|
||||
|
|
@ -99,9 +99,10 @@ tr:hover .drag-handle {
|
|||
|
||||
.tabs {
|
||||
display: grid;
|
||||
grid-auto-columns: minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.tabs input[type="radio"] {
|
||||
.tabs > input[type="radio"] {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -9999px;
|
||||
|
|
@ -109,7 +110,7 @@ tr:hover .drag-handle {
|
|||
}
|
||||
|
||||
// Actual tabs
|
||||
.tabs label {
|
||||
.tabs > label {
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px 4px 0 0;
|
||||
cursor: pointer;
|
||||
|
|
@ -124,9 +125,9 @@ tr:hover .drag-handle {
|
|||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
.tabs [id^="tab"]:checked + label {
|
||||
.tabs > [id^="tab"]:checked + label {
|
||||
background-color: @white;
|
||||
border-color: #ddd #ddd transparent #ddd;
|
||||
border-color: rgba(128,128,128,.5) rgba(128,128,128,.5) transparent rgba(128,128,128,.5);
|
||||
opacity: 1;
|
||||
z-index: 1;
|
||||
}
|
||||
|
|
@ -140,6 +141,6 @@ tr:hover .drag-handle {
|
|||
visibility: hidden;
|
||||
}
|
||||
|
||||
.tabs [id^="tab"]:checked + label + .tab-content {
|
||||
.tabs > [id^="tab"]:checked + label + .tab-content {
|
||||
visibility: visible;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
max-height: 700px;
|
||||
|
||||
.control-group {
|
||||
label {
|
||||
label.iconsize24 {
|
||||
padding-top: 0;
|
||||
width: 50px;
|
||||
}
|
||||
|
|
@ -135,12 +135,12 @@
|
|||
.b-view-content-toolbar {
|
||||
padding: 7px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: @contacts-popup-left-width;
|
||||
height: 30px;
|
||||
text-align: right;
|
||||
border-bottom: 1px solid rgba(128,128,128,0.4);
|
||||
border-top: 1px solid rgba(128,128,128,0.4);
|
||||
|
||||
.button-save-contact {
|
||||
&.dirty:enabled {
|
||||
|
|
@ -148,12 +148,17 @@
|
|||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu.right-edge {
|
||||
top: auto;
|
||||
bottom: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.b-view-content {
|
||||
position: absolute;
|
||||
top: 45px;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
bottom: 45px;
|
||||
left: @contacts-popup-left-width;
|
||||
right: 0;
|
||||
overflow: auto;
|
||||
|
|
@ -176,19 +181,10 @@
|
|||
color: #999;
|
||||
}
|
||||
|
||||
.top-part {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.property-line {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.top-row {
|
||||
padding: 10px 0;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
input, textarea {
|
||||
box-shadow: none;
|
||||
border-color: #fff;
|
||||
|
|
@ -206,43 +202,28 @@
|
|||
border-color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hasError {
|
||||
input {
|
||||
color: #ee5f5b;
|
||||
border-color: #ee5f5b;
|
||||
}
|
||||
.read-only-sign {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 40px;
|
||||
}
|
||||
|
||||
.read-only {
|
||||
span, .e-read-only-sign {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.e-save-trigger {
|
||||
position: absolute;
|
||||
top: 25px;
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
.e-read-only-sign {
|
||||
input, textarea {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.e-share-sign {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.read-only {
|
||||
span, .e-read-only-sign {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
input, textarea, .e-share-sign {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.tab-content {
|
||||
grid-column-end: 3;
|
||||
padding-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,6 @@
|
|||
}
|
||||
|
||||
.tab-content {
|
||||
grid-column-end: 6;
|
||||
grid-column-end: 5;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ export class ContactsPopupView extends AbstractViewPopup {
|
|||
}
|
||||
|
||||
newContact() {
|
||||
this.populateViewContact(null);
|
||||
this.populateViewContact();
|
||||
this.selectorContact(null);
|
||||
}
|
||||
|
||||
|
|
@ -252,11 +252,7 @@ export class ContactsPopupView extends AbstractViewPopup {
|
|||
* @param {?ContactModel} contact
|
||||
*/
|
||||
populateViewContact(contact) {
|
||||
if (!contact) {
|
||||
contact = new ContactModel;
|
||||
}
|
||||
this.contact(contact);
|
||||
|
||||
this.contact(contact || new ContactModel);
|
||||
this.hasChanges(false);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue