2012-10-05 05:05:49 +02:00
|
|
|
OC.Contacts = OC.Contacts || {};
|
2012-02-06 07:32:57 +01:00
|
|
|
|
|
|
|
|
2012-12-11 02:28:22 +01:00
|
|
|
(function(window, $, OC) {
|
|
|
|
'use strict';
|
2012-08-02 01:14:50 +02:00
|
|
|
/**
|
2012-10-05 05:05:49 +02:00
|
|
|
* An item which binds the appropriate html and event handlers
|
|
|
|
* @param parent the parent ContactList
|
|
|
|
* @param id The integer contact id.
|
2013-03-22 14:49:34 +01:00
|
|
|
* @param metadata An metadata object containing and 'owner' string variable and an integer 'permissions' variable.
|
2012-10-05 05:05:49 +02:00
|
|
|
* @param data the data used to populate the contact
|
|
|
|
* @param listtemplate the jquery object used to render the contact list item
|
|
|
|
* @param fulltemplate the jquery object used to render the entire contact
|
|
|
|
* @param detailtemplates A map of jquery objects used to render the contact parts e.g. EMAIL, TEL etc.
|
|
|
|
*/
|
2013-03-22 14:49:34 +01:00
|
|
|
var Contact = function(parent, id, metadata, data, listtemplate, dragtemplate, fulltemplate, detailtemplates) {
|
|
|
|
//console.log('contact:', id, metadata, data); //parent, id, data, listtemplate, fulltemplate);
|
2012-10-22 15:32:32 +02:00
|
|
|
this.parent = parent,
|
2013-03-25 17:08:47 +01:00
|
|
|
this.storage = parent.storage,
|
2012-10-22 15:32:32 +02:00
|
|
|
this.id = id,
|
2013-03-22 14:49:34 +01:00
|
|
|
this.metadata = metadata,
|
2012-10-22 15:32:32 +02:00
|
|
|
this.data = data,
|
2013-03-12 00:28:41 +01:00
|
|
|
this.$dragTemplate = dragtemplate,
|
2012-10-05 05:05:49 +02:00
|
|
|
this.$listTemplate = listtemplate,
|
|
|
|
this.$fullTemplate = fulltemplate;
|
|
|
|
this.detailTemplates = detailtemplates;
|
2012-12-17 16:27:28 +01:00
|
|
|
this.undoQueue = [];
|
2012-10-05 05:05:49 +02:00
|
|
|
this.multi_properties = ['EMAIL', 'TEL', 'IMPP', 'ADR', 'URL'];
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2013-03-30 17:33:58 +01:00
|
|
|
Contact.prototype.metaData = function() {
|
|
|
|
return {
|
|
|
|
contactid: this.id,
|
|
|
|
addressbookid: this.metadata.parent,
|
|
|
|
backend: this.metadata.backend
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-03-30 20:12:12 +01:00
|
|
|
Contact.prototype.getDisplayName = function() {
|
|
|
|
return this.getPreferredValue('FN');
|
|
|
|
};
|
|
|
|
|
2013-03-30 17:33:58 +01:00
|
|
|
Contact.prototype.getId = function() {
|
|
|
|
return this.id;
|
|
|
|
};
|
|
|
|
|
|
|
|
Contact.prototype.getParent = function() {
|
|
|
|
return this.metadata.parent;
|
|
|
|
};
|
|
|
|
|
|
|
|
Contact.prototype.getBackend = function() {
|
|
|
|
return this.metadata.backend;
|
|
|
|
};
|
|
|
|
|
2013-04-01 03:50:42 +02:00
|
|
|
Contact.prototype.merge = function(mergees) {
|
2013-04-03 16:43:18 +02:00
|
|
|
console.log('Contact.merge, mergees', mergees);
|
|
|
|
if(!mergees instanceof Array && !mergees instanceof Contact) {
|
2013-04-01 03:50:42 +02:00
|
|
|
throw new TypeError('BadArgument: Contact.merge() only takes Contacts');
|
2013-04-03 16:43:18 +02:00
|
|
|
} else {
|
|
|
|
if(mergees instanceof Contact) {
|
|
|
|
mergees = [mergees];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// For multi_properties
|
|
|
|
var addIfNotExists = function(name, newproperty) {
|
|
|
|
// If the property isn't set at all just add it and return.
|
|
|
|
if(!self.data[name]) {
|
|
|
|
self.data[name] = [newproperty];
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var found = false;
|
|
|
|
$.each(self.data[name], function(idx, property) {
|
|
|
|
if(name === 'ADR') {
|
|
|
|
// Do a simple string comparison
|
|
|
|
if(property.value.join(';').toLowerCase() === newproperty.value.join(';').toLowerCase()) {
|
|
|
|
found = true;
|
|
|
|
return false; // break loop
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if(property.value.toLowerCase() === newproperty.value.toLowerCase()) {
|
|
|
|
found = true;
|
|
|
|
return false; // break loop
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
if(found) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Not found, so adding it.
|
|
|
|
self.data[name].push(newproperty);
|
2013-04-01 03:50:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
var self = this;
|
|
|
|
$.each(mergees, function(idx, mergee) {
|
2013-04-03 16:43:18 +02:00
|
|
|
console.log('Contact.merge, mergee', mergee);
|
2013-04-01 03:50:42 +02:00
|
|
|
if(!mergee instanceof Contact) {
|
|
|
|
throw new TypeError('BadArgument: Contact.merge() only takes Contacts');
|
|
|
|
}
|
2013-04-03 16:43:18 +02:00
|
|
|
if(mergee === self) {
|
|
|
|
throw new Error('BadArgument: Why should I merge with myself?');
|
|
|
|
}
|
|
|
|
$.each(mergee.data, function(name, properties) {
|
|
|
|
console.log('property', name, properties);
|
|
|
|
if(self.multi_properties.indexOf(name) === -1) {
|
|
|
|
console.log('non-multi', name, properties);
|
|
|
|
if(self.data[name] && self.data[name].length > 0) {
|
|
|
|
// If the property exists don't touch it.
|
|
|
|
return true; // continue
|
|
|
|
} else {
|
|
|
|
// Otherwise add it.
|
|
|
|
self.data[name] = properties;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$.each(properties, function(idx, property) {
|
|
|
|
addIfNotExists(name, property);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
console.log('Merged', self.data);
|
2013-04-01 03:50:42 +02:00
|
|
|
});
|
2013-04-03 16:43:18 +02:00
|
|
|
return true;
|
2013-04-01 03:50:42 +02:00
|
|
|
};
|
|
|
|
|
2012-12-13 02:37:37 +01:00
|
|
|
Contact.prototype.showActions = function(act) {
|
|
|
|
this.$footer.children().hide();
|
|
|
|
if(act && act.length > 0) {
|
|
|
|
this.$footer.children('.'+act.join(',.')).show();
|
|
|
|
}
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-12-13 02:37:37 +01:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
Contact.prototype.setAsSaving = function(obj, state) {
|
|
|
|
if(!obj) {
|
2012-08-02 01:14:50 +02:00
|
|
|
return;
|
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
$(obj).prop('disabled', state);
|
2012-10-24 20:30:41 +02:00
|
|
|
$(obj).toggleClass('loading', state);
|
|
|
|
/*if(state) {
|
2012-08-02 01:14:50 +02:00
|
|
|
$(obj).addClass('loading');
|
|
|
|
} else {
|
|
|
|
$(obj).removeClass('loading');
|
2012-10-24 20:30:41 +02:00
|
|
|
}*/
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-05 05:05:49 +02:00
|
|
|
|
2012-12-17 16:27:28 +01:00
|
|
|
Contact.prototype.pushToUndo = function(params) {
|
|
|
|
// Check if the same property has been changed before
|
|
|
|
// and update it's checksum if so.
|
|
|
|
if(typeof params.oldchecksum !== 'undefined') {
|
|
|
|
$.each(this.undoQueue, function(idx, item) {
|
|
|
|
if(item.checksum === params.oldchecksum) {
|
|
|
|
item.checksum = params.newchecksum;
|
|
|
|
if(params.action === 'delete') {
|
|
|
|
item.action = 'delete';
|
|
|
|
}
|
|
|
|
return false; // Break loop
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
this.undoQueue.push({
|
|
|
|
action:params.action,
|
|
|
|
name: params.name,
|
|
|
|
checksum: params.newchecksum,
|
|
|
|
newvalue: params.newvalue,
|
|
|
|
oldvalue: params.oldvalue
|
|
|
|
});
|
|
|
|
console.log('undoQueue', this.undoQueue);
|
|
|
|
}
|
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
Contact.prototype.addProperty = function($option, name) {
|
|
|
|
console.log('Contact.addProperty', name)
|
2012-12-17 16:27:28 +01:00
|
|
|
var $elem;
|
2012-10-05 05:05:49 +02:00
|
|
|
switch(name) {
|
|
|
|
case 'NICKNAME':
|
|
|
|
case 'TITLE':
|
|
|
|
case 'ORG':
|
|
|
|
case 'BDAY':
|
2012-12-11 02:27:37 +01:00
|
|
|
case 'NOTE':
|
2012-12-10 05:48:22 +01:00
|
|
|
this.$fullelem.find('[data-element="' + name.toLowerCase() + '"]').addClass('new').show();
|
2012-10-05 05:05:49 +02:00
|
|
|
$option.prop('disabled', true);
|
|
|
|
break;
|
|
|
|
case 'TEL':
|
|
|
|
case 'URL':
|
|
|
|
case 'EMAIL':
|
2012-12-11 02:27:37 +01:00
|
|
|
var $elem = this.renderStandardProperty(name.toLowerCase());
|
2012-10-05 05:05:49 +02:00
|
|
|
var $list = this.$fullelem.find('ul.' + name.toLowerCase());
|
|
|
|
$list.show();
|
|
|
|
$list.append($elem);
|
2012-12-10 05:48:22 +01:00
|
|
|
$elem.find('input.value').addClass('new');
|
2012-10-05 05:05:49 +02:00
|
|
|
break;
|
|
|
|
case 'ADR':
|
2012-12-11 02:27:37 +01:00
|
|
|
var $elem = this.renderAddressProperty();
|
2012-10-05 05:05:49 +02:00
|
|
|
var $list = this.$fullelem.find('ul.' + name.toLowerCase());
|
|
|
|
$list.show();
|
|
|
|
$list.append($elem);
|
2012-12-11 06:58:42 +01:00
|
|
|
$elem.find('.display').trigger('click');
|
2012-12-10 05:48:22 +01:00
|
|
|
$elem.find('input.value').addClass('new');
|
2012-10-05 05:05:49 +02:00
|
|
|
break;
|
|
|
|
case 'IMPP':
|
2012-12-11 02:28:22 +01:00
|
|
|
var $elem = this.renderIMProperty();
|
2012-10-05 05:05:49 +02:00
|
|
|
var $list = this.$fullelem.find('ul.' + name.toLowerCase());
|
|
|
|
$list.show();
|
|
|
|
$list.append($elem);
|
2012-12-10 05:48:22 +01:00
|
|
|
$elem.find('input.value').addClass('new');
|
2012-10-05 05:05:49 +02:00
|
|
|
break;
|
2012-08-02 01:14:50 +02:00
|
|
|
}
|
2012-12-17 17:24:06 +01:00
|
|
|
|
2012-12-17 16:27:28 +01:00
|
|
|
if($elem) {
|
2013-01-17 14:48:16 +01:00
|
|
|
// If there's already a property of this type enable setting as preferred.
|
|
|
|
if(this.multi_properties.indexOf(name) !== -1 && this.data[name] && this.data[name].length > 0) {
|
|
|
|
var selector = 'li[data-element="' + name.toLowerCase() + '"]';
|
|
|
|
$.each(this.$fullelem.find(selector), function(idx, elem) {
|
|
|
|
$(elem).find('input.parameter[value="PREF"]').show();
|
|
|
|
});
|
|
|
|
} else if(this.multi_properties.indexOf(name) !== -1) {
|
|
|
|
$elem.find('input.parameter[value="PREF"]').hide();
|
|
|
|
}
|
2012-12-17 16:27:28 +01:00
|
|
|
$elem.find('select.type[name="parameters[TYPE][]"]')
|
|
|
|
.combobox({
|
|
|
|
singleclick: true,
|
|
|
|
classes: ['propertytype', 'float', 'label'],
|
|
|
|
});
|
|
|
|
}
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2012-10-23 06:27:22 +02:00
|
|
|
Contact.prototype.deleteProperty = function(params) {
|
|
|
|
var obj = params.obj;
|
|
|
|
if(!this.enabled) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var element = this.propertyTypeFor(obj);
|
|
|
|
var $container = this.propertyContainerFor(obj);
|
|
|
|
console.log('Contact.deleteProperty, element', element, $container);
|
|
|
|
var params = {
|
|
|
|
name: element,
|
2013-03-25 17:08:47 +01:00
|
|
|
backend: this.metadata.backend,
|
|
|
|
addressbookid: this.metadata.parent,
|
2012-10-23 06:27:22 +02:00
|
|
|
id: this.id
|
|
|
|
};
|
|
|
|
if(this.multi_properties.indexOf(element) !== -1) {
|
|
|
|
params['checksum'] = this.checksumFor(obj);
|
2013-02-12 11:56:09 +01:00
|
|
|
if(params['checksum'] === 'new' && $.trim(this.valueFor(obj)) === '') {
|
2013-01-17 23:46:18 +01:00
|
|
|
// If there's only one property of this type enable setting as preferred.
|
|
|
|
if(this.data[element].length === 1) {
|
|
|
|
var selector = 'li[data-element="' + element.toLowerCase() + '"]';
|
|
|
|
this.$fullelem.find(selector).find('input.parameter[value="PREF"]').hide();
|
|
|
|
}
|
2012-12-10 05:36:24 +01:00
|
|
|
$container.remove();
|
|
|
|
return;
|
|
|
|
}
|
2012-10-23 06:27:22 +02:00
|
|
|
}
|
|
|
|
this.setAsSaving(obj, true);
|
|
|
|
var self = this;
|
2013-03-25 17:08:47 +01:00
|
|
|
$.when(this.storage.deleteProperty(this.metadata.backend, this.metadata.parent, this.id, params))
|
|
|
|
.then(function(response) {
|
2013-03-28 03:19:01 +01:00
|
|
|
if(!response.error) {
|
2012-10-24 20:30:41 +02:00
|
|
|
// TODO: Test if removing from internal data structure works
|
2012-10-23 06:27:22 +02:00
|
|
|
if(self.multi_properties.indexOf(element) !== -1) {
|
2012-10-24 20:30:41 +02:00
|
|
|
// First find out if an existing element by looking for checksum
|
|
|
|
var checksum = self.checksumFor(obj);
|
2012-12-17 16:27:28 +01:00
|
|
|
self.pushToUndo({
|
|
|
|
action:'delete',
|
|
|
|
name: element,
|
|
|
|
oldchecksum: self.checksumFor(obj),
|
|
|
|
newvalue: self.valueFor(obj)
|
|
|
|
});
|
2012-10-24 20:30:41 +02:00
|
|
|
if(checksum) {
|
|
|
|
for(var i in self.data[element]) {
|
|
|
|
if(self.data[element][i].checksum === checksum) {
|
|
|
|
// Found it
|
2012-12-11 02:28:22 +01:00
|
|
|
self.data[element].splice(self.data[element].indexOf(self.data[element][i]), 1);
|
2012-10-24 20:30:41 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-01-17 23:46:18 +01:00
|
|
|
// If there's only one property of this type enable setting as preferred.
|
|
|
|
if(self.data[element].length === 1) {
|
|
|
|
var selector = 'li[data-element="' + element.toLowerCase() + '"]';
|
|
|
|
self.$fullelem.find(selector).find('input.parameter[value="PREF"]').hide();
|
|
|
|
}
|
2012-10-23 06:27:22 +02:00
|
|
|
$container.remove();
|
|
|
|
} else {
|
2012-12-17 16:27:28 +01:00
|
|
|
self.pushToUndo({
|
|
|
|
action:'delete',
|
|
|
|
name: element,
|
|
|
|
newvalue: $container.find('input.value').val()
|
|
|
|
});
|
2012-10-23 06:27:22 +02:00
|
|
|
self.setAsSaving(obj, false);
|
|
|
|
self.$fullelem.find('[data-element="' + element.toLowerCase() + '"]').hide();
|
|
|
|
$container.find('input.value').val('');
|
|
|
|
self.$addMenu.find('option[value="' + element.toUpperCase() + '"]').prop('disabled', false);
|
|
|
|
}
|
2012-12-17 10:23:09 +01:00
|
|
|
$(document).trigger('status.contact.updated', {
|
2012-12-22 00:27:21 +01:00
|
|
|
property: element,
|
2012-12-17 10:23:09 +01:00
|
|
|
contact: self
|
|
|
|
});
|
2012-10-23 06:27:22 +02:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
$(document).trigger('status.contact.error', {
|
2013-03-28 03:19:01 +01:00
|
|
|
message: response.message
|
2012-10-23 06:27:22 +02:00
|
|
|
});
|
|
|
|
self.setAsSaving(obj, false);
|
|
|
|
return false;
|
|
|
|
}
|
2013-03-25 17:08:47 +01:00
|
|
|
})
|
|
|
|
.fail(function(jqxhr, textStatus, error) {
|
|
|
|
var err = textStatus + ', ' + error;
|
|
|
|
console.log( "Request Failed: " + err);
|
|
|
|
$(document).trigger('status.contact.error', {
|
|
|
|
message: t('contacts', 'Failed deleting property: {error}', {error:err})
|
|
|
|
});
|
|
|
|
});
|
|
|
|
;
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-23 06:27:22 +02:00
|
|
|
|
2013-04-03 16:43:18 +02:00
|
|
|
/**
|
|
|
|
* @brief Save all properties. Used for merging contacts.
|
|
|
|
* If this is a new contact it will first be saved to the datastore and a
|
|
|
|
* new datastructure will be added to the object.
|
|
|
|
*/
|
|
|
|
Contact.prototype.saveAll = function(cb) {
|
|
|
|
console.log('Contact.saveAll');
|
|
|
|
if(!this.id) {
|
|
|
|
var self = this;
|
|
|
|
this.add({isnew:true}, function(response) {
|
|
|
|
if(response.error) {
|
|
|
|
console.warn('No response object');
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
self.saveAll();
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var self = this;
|
|
|
|
this.setAsSaving(this.$fullelem, true);
|
|
|
|
var data = JSON.stringify(this.data);
|
|
|
|
console.log('stringified', data);
|
|
|
|
$.when(this.storage.saveAllProperties(this.metadata.backend, this.metadata.parent, this.id, data))
|
|
|
|
.then(function(response) {
|
|
|
|
if(!response.error) {
|
2013-04-04 02:56:20 +02:00
|
|
|
self.data = response.data.data;
|
|
|
|
self.metadata = response.data.metadata;
|
2013-04-03 16:43:18 +02:00
|
|
|
if(typeof cb === 'function') {
|
|
|
|
cb({error:false});
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$(document).trigger('status.contact.error', {
|
|
|
|
message: response.message
|
|
|
|
});
|
|
|
|
if(typeof cb === 'function') {
|
|
|
|
cb({error:true, message:response.message});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.setAsSaving(self.$fullelem, false);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* @brief Act on change of a property.
|
|
|
|
* If this is a new contact it will first be saved to the datastore and a
|
2013-04-03 16:43:18 +02:00
|
|
|
* new datastructure will be added to the object.
|
2012-10-05 05:05:49 +02:00
|
|
|
* If the obj argument is not provided 'name' and 'value' MUST be provided
|
|
|
|
* and this is only allowed for single elements like N, FN, CATEGORIES.
|
|
|
|
* @param obj. The form form field that has changed.
|
|
|
|
* @param name. The optional name of the element.
|
|
|
|
* @param value. The optional value.
|
|
|
|
*/
|
|
|
|
Contact.prototype.saveProperty = function(params) {
|
|
|
|
console.log('Contact.saveProperty', params);
|
2012-11-13 22:42:55 +01:00
|
|
|
if(!this.id) {
|
|
|
|
var self = this;
|
2012-11-16 04:40:35 +01:00
|
|
|
this.add({isnew:true}, function(response) {
|
2012-11-13 22:42:55 +01:00
|
|
|
if(!response || response.status === 'error') {
|
2012-12-09 23:54:16 +01:00
|
|
|
console.warn('No response object');
|
2012-11-13 22:42:55 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
self.saveProperty(params);
|
2012-12-13 02:37:37 +01:00
|
|
|
self.showActions(['close', 'add', 'export', 'delete']);
|
2012-11-13 22:42:55 +01:00
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
var obj = null;
|
|
|
|
var element = null;
|
2013-04-03 16:54:25 +02:00
|
|
|
var args = [];
|
2012-10-05 05:05:49 +02:00
|
|
|
if(params.obj) {
|
|
|
|
obj = params.obj;
|
2013-03-25 17:08:47 +01:00
|
|
|
args = this.argumentsFor(obj);
|
|
|
|
args['parameters'] = this.parametersFor(obj);
|
2012-10-23 06:27:22 +02:00
|
|
|
element = this.propertyTypeFor(obj);
|
2012-10-05 05:05:49 +02:00
|
|
|
} else {
|
2013-03-25 17:08:47 +01:00
|
|
|
args = params;
|
2012-10-05 05:05:49 +02:00
|
|
|
element = params.name;
|
2012-11-22 04:09:52 +01:00
|
|
|
var value = utils.isArray(params.value)
|
|
|
|
? $.param(params.value)
|
|
|
|
: encodeURIComponent(params.value);
|
2012-08-02 01:14:50 +02:00
|
|
|
}
|
2013-03-25 17:08:47 +01:00
|
|
|
console.log('args', args);
|
2012-10-05 05:05:49 +02:00
|
|
|
var self = this;
|
|
|
|
this.setAsSaving(obj, true);
|
2013-03-25 17:08:47 +01:00
|
|
|
$.when(this.storage.saveProperty(this.metadata.backend, this.metadata.parent, this.id, args))
|
|
|
|
.then(function(response) {
|
2013-03-28 03:19:01 +01:00
|
|
|
if(!response.error) {
|
2012-10-23 06:27:22 +02:00
|
|
|
if(!self.data[element]) {
|
|
|
|
self.data[element] = [];
|
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
if(self.multi_properties.indexOf(element) !== -1) {
|
2012-10-24 20:30:41 +02:00
|
|
|
// First find out if an existing element by looking for checksum
|
|
|
|
var checksum = self.checksumFor(obj);
|
2012-12-17 16:27:28 +01:00
|
|
|
var value = self.valueFor(obj);
|
|
|
|
var parameters = self.parametersFor(obj);
|
2012-12-17 10:35:08 +01:00
|
|
|
if(checksum && checksum !== 'new') {
|
2012-12-17 16:27:28 +01:00
|
|
|
self.pushToUndo({
|
|
|
|
action:'save',
|
|
|
|
name: element,
|
2013-03-25 17:08:47 +01:00
|
|
|
newchecksum: response.data.checksum,
|
2012-12-17 16:27:28 +01:00
|
|
|
oldchecksum: checksum,
|
|
|
|
newvalue: value,
|
|
|
|
oldvalue: obj.defaultValue
|
|
|
|
});
|
2012-12-17 10:35:08 +01:00
|
|
|
$.each(self.data[element], function(i, el) {
|
|
|
|
if(el.checksum === checksum) {
|
2012-10-24 20:30:41 +02:00
|
|
|
self.data[element][i] = {
|
|
|
|
name: element,
|
2012-12-17 16:27:28 +01:00
|
|
|
value: value,
|
|
|
|
parameters: parameters,
|
2013-03-25 17:08:47 +01:00
|
|
|
checksum: response.data.checksum
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-12-17 10:35:08 +01:00
|
|
|
return false;
|
2012-10-24 20:30:41 +02:00
|
|
|
}
|
2012-12-17 10:35:08 +01:00
|
|
|
});
|
2012-10-24 20:30:41 +02:00
|
|
|
} else {
|
2012-12-10 05:48:22 +01:00
|
|
|
$(obj).removeClass('new');
|
2012-12-17 16:27:28 +01:00
|
|
|
self.pushToUndo({
|
|
|
|
action:'add',
|
|
|
|
name: element,
|
2013-03-25 17:08:47 +01:00
|
|
|
newchecksum: response.data.checksum,
|
2012-12-17 16:27:28 +01:00
|
|
|
newvalue: value,
|
|
|
|
});
|
2012-10-24 20:30:41 +02:00
|
|
|
self.data[element].push({
|
|
|
|
name: element,
|
2012-12-17 16:27:28 +01:00
|
|
|
value: value,
|
|
|
|
parameters: parameters,
|
2013-03-25 17:08:47 +01:00
|
|
|
checksum: response.data.checksum,
|
2012-10-24 20:30:41 +02:00
|
|
|
});
|
|
|
|
}
|
2013-03-25 17:08:47 +01:00
|
|
|
self.propertyContainerFor(obj).data('checksum', response.data.checksum);
|
2012-10-23 06:27:22 +02:00
|
|
|
} else {
|
2012-10-24 20:30:41 +02:00
|
|
|
// Save value and parameters internally
|
2012-11-22 04:09:52 +01:00
|
|
|
var value = obj ? self.valueFor(obj) : params.value;
|
2012-12-17 16:27:28 +01:00
|
|
|
self.pushToUndo({
|
|
|
|
action: ((obj && obj.defaultValue) || self.data[element].length) ? 'save' : 'add', // FIXME
|
|
|
|
name: element,
|
|
|
|
newvalue: value,
|
|
|
|
});
|
2012-10-24 20:30:41 +02:00
|
|
|
switch(element) {
|
2012-10-30 07:06:37 +01:00
|
|
|
case 'CATEGORIES':
|
|
|
|
// We deal with this in addToGroup()
|
2012-10-24 20:30:41 +02:00
|
|
|
break;
|
2013-03-30 04:04:29 +01:00
|
|
|
case 'BDAY':
|
|
|
|
// reverse order again.
|
|
|
|
value = $.datepicker.formatDate('yy-mm-dd', $.datepicker.parseDate('dd-mm-yy', value));
|
|
|
|
self.data[element][0] = {
|
|
|
|
name: element,
|
|
|
|
value: value,
|
|
|
|
parameters: self.parametersFor(obj),
|
|
|
|
checksum: response.data.checksum
|
|
|
|
};
|
|
|
|
break;
|
2012-10-24 20:30:41 +02:00
|
|
|
case 'FN':
|
2012-12-11 06:20:25 +01:00
|
|
|
if(!self.data.FN || !self.data.FN.length) {
|
2012-12-17 15:19:22 +01:00
|
|
|
self.data.FN = [{name:'FN', value:'', parameters:[]}];
|
2012-12-11 06:20:25 +01:00
|
|
|
}
|
|
|
|
self.data.FN[0]['value'] = value;
|
2012-10-24 20:30:41 +02:00
|
|
|
var nempty = true;
|
|
|
|
if(!self.data.N) {
|
2012-11-16 04:38:58 +01:00
|
|
|
// TODO: Maybe add a method for constructing new elements?
|
|
|
|
self.data.N = [{name:'N',value:['', '', '', '', ''],parameters:[]}];
|
2012-10-24 20:30:41 +02:00
|
|
|
}
|
2012-11-16 04:38:58 +01:00
|
|
|
$.each(self.data.N[0]['value'], function(idx, val) {
|
|
|
|
if(val) {
|
2012-10-24 20:30:41 +02:00
|
|
|
nempty = false;
|
2012-11-16 04:38:58 +01:00
|
|
|
return false;
|
2012-10-24 20:30:41 +02:00
|
|
|
}
|
2012-11-16 04:38:58 +01:00
|
|
|
});
|
2012-10-24 20:30:41 +02:00
|
|
|
if(nempty) {
|
2012-11-16 04:38:58 +01:00
|
|
|
self.data.N[0]['value'] = ['', '', '', '', ''];
|
2012-12-11 06:20:25 +01:00
|
|
|
var nvalue = value.split(' ');
|
2012-11-16 04:38:58 +01:00
|
|
|
// Very basic western style parsing. I'm not gonna implement
|
|
|
|
// https://github.com/android/platform_packages_providers_contactsprovider/blob/master/src/com/android/providers/contacts/NameSplitter.java ;)
|
2012-11-22 00:31:08 +01:00
|
|
|
self.data.N[0]['value'][0] = nvalue.length > 2 && nvalue.slice(nvalue.length-1).toString() || nvalue[1] || '';
|
|
|
|
self.data.N[0]['value'][1] = nvalue[0] || '';
|
|
|
|
self.data.N[0]['value'][2] = nvalue.length > 2 && nvalue.slice(1, nvalue.length-1).join(' ') || '';
|
2012-10-24 20:30:41 +02:00
|
|
|
setTimeout(function() {
|
2012-11-22 04:09:52 +01:00
|
|
|
self.saveProperty({name:'N', value:self.data.N[0].value.join(';')});
|
|
|
|
setTimeout(function() {
|
|
|
|
self.$fullelem.find('.fullname').next('.action.edit').trigger('click');
|
|
|
|
OC.notify({message:t('contacts', 'Is this correct?')});
|
2013-02-26 21:59:38 +01:00
|
|
|
}, 1000);
|
2012-11-22 04:09:52 +01:00
|
|
|
}
|
2012-10-24 20:30:41 +02:00
|
|
|
, 500);
|
|
|
|
}
|
2012-11-27 20:36:34 +01:00
|
|
|
break;
|
|
|
|
case 'N':
|
|
|
|
if(!utils.isArray(value)) {
|
|
|
|
value = value.split(';');
|
|
|
|
// Then it is auto-generated from FN.
|
2012-12-10 20:58:34 +01:00
|
|
|
var $nelems = self.$fullelem.find('.n.editor input');
|
2012-11-27 20:36:34 +01:00
|
|
|
$.each(value, function(idx, val) {
|
|
|
|
self.$fullelem.find('#n_' + idx).val(val);
|
|
|
|
});
|
|
|
|
}
|
2013-02-26 21:59:38 +01:00
|
|
|
var $fullname = self.$fullelem.find('.fullname'), fullname = '';
|
|
|
|
var update_fn = false;
|
|
|
|
if(!self.data.FN) {
|
|
|
|
self.data.FN = [{name:'N', value:'', parameters:[]}];
|
|
|
|
}
|
|
|
|
if(self.data.FN[0]['value'] === '') {
|
|
|
|
self.data.FN[0]['value'] = value[1] + ' ' + value[0];
|
|
|
|
$fullname.val(self.data.FN[0]['value']);
|
|
|
|
update_fn = true;
|
2013-02-26 22:25:57 +01:00
|
|
|
} else if($fullname.val() == value[1] + ' ') {
|
|
|
|
console.log('change', value);
|
|
|
|
self.data.FN[0]['value'] = value[1] + ' ' + value[0];
|
|
|
|
$fullname.val(self.data.FN[0]['value']);
|
|
|
|
update_fn = true;
|
|
|
|
} else if($fullname.val() == ' ' + value[0]) {
|
2013-02-26 21:59:38 +01:00
|
|
|
self.data.FN[0]['value'] = value[1] + ' ' + value[0];
|
|
|
|
$fullname.val(self.data.FN[0]['value']);
|
|
|
|
update_fn = true;
|
|
|
|
}
|
|
|
|
if(update_fn) {
|
|
|
|
setTimeout(function() {
|
|
|
|
self.saveProperty({name:'FN', value:self.data.FN[0]['value']});
|
|
|
|
}, 1000);
|
|
|
|
}
|
2012-10-24 20:30:41 +02:00
|
|
|
case 'NICKNAME':
|
|
|
|
case 'ORG':
|
|
|
|
case 'TITLE':
|
2012-12-11 02:27:37 +01:00
|
|
|
case 'NOTE':
|
2012-10-24 20:30:41 +02:00
|
|
|
self.data[element][0] = {
|
|
|
|
name: element,
|
|
|
|
value: value,
|
|
|
|
parameters: self.parametersFor(obj),
|
2013-03-25 17:08:47 +01:00
|
|
|
checksum: response.data.checksum
|
2012-10-24 20:30:41 +02:00
|
|
|
};
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
}
|
|
|
|
self.setAsSaving(obj, false);
|
2012-12-22 00:27:21 +01:00
|
|
|
$(document).trigger('status.contact.updated', {
|
|
|
|
property: element,
|
|
|
|
contact: self
|
|
|
|
});
|
2012-10-05 05:05:49 +02:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
$(document).trigger('status.contact.error', {
|
2013-03-28 03:19:01 +01:00
|
|
|
message: response.message
|
2012-10-05 05:05:49 +02:00
|
|
|
});
|
|
|
|
self.setAsSaving(obj, false);
|
|
|
|
return false;
|
2012-08-02 01:14:50 +02:00
|
|
|
}
|
2013-03-25 17:08:47 +01:00
|
|
|
});
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2012-11-23 01:20:45 +01:00
|
|
|
/**
|
|
|
|
* Hide contact list element.
|
|
|
|
*/
|
|
|
|
Contact.prototype.hide = function() {
|
|
|
|
this.getListItemElement().hide();
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Remove any open contact from the DOM.
|
|
|
|
*/
|
|
|
|
Contact.prototype.close = function() {
|
2012-10-24 20:30:41 +02:00
|
|
|
console.log('Contact.close', this);
|
2012-10-05 05:05:49 +02:00
|
|
|
if(this.$fullelem) {
|
|
|
|
this.$fullelem.remove();
|
2012-11-01 02:01:00 +01:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
2012-10-05 05:05:49 +02:00
|
|
|
}
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Remove any open contact from the DOM and detach it's list
|
|
|
|
* element from the DOM.
|
2012-11-15 06:43:22 +01:00
|
|
|
* @returns The contact object.
|
2012-10-05 05:05:49 +02:00
|
|
|
*/
|
|
|
|
Contact.prototype.detach = function() {
|
|
|
|
if(this.$fullelem) {
|
|
|
|
this.$fullelem.remove();
|
|
|
|
}
|
|
|
|
if(this.$listelem) {
|
2012-11-15 06:43:22 +01:00
|
|
|
this.$listelem.detach();
|
|
|
|
return this;
|
|
|
|
}
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-11-15 06:43:22 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Set a contacts list element as (un)checked
|
|
|
|
* @returns The contact object.
|
|
|
|
*/
|
|
|
|
Contact.prototype.setChecked = function(checked) {
|
|
|
|
if(this.$listelem) {
|
|
|
|
this.$listelem.find('input:checkbox').prop('checked', checked);
|
|
|
|
return this;
|
2012-10-05 05:05:49 +02:00
|
|
|
}
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Set a contact to en/disabled depending on its permissions.
|
|
|
|
* @param boolean enabled
|
|
|
|
*/
|
|
|
|
Contact.prototype.setEnabled = function(enabled) {
|
|
|
|
if(enabled) {
|
|
|
|
this.$fullelem.find('#addproperty').show();
|
|
|
|
} else {
|
|
|
|
this.$fullelem.find('#addproperty').hide();
|
|
|
|
}
|
|
|
|
this.enabled = enabled;
|
2012-12-10 05:59:43 +01:00
|
|
|
this.$fullelem.find('.value,.action,.parameter').each(function () {
|
2012-10-05 05:05:49 +02:00
|
|
|
$(this).prop('disabled', !enabled);
|
2012-08-02 01:14:50 +02:00
|
|
|
});
|
2012-10-05 05:05:49 +02:00
|
|
|
$(document).trigger('status.contact.enabled', enabled);
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2012-11-13 22:42:55 +01:00
|
|
|
/**
|
2013-01-17 23:24:11 +01:00
|
|
|
* Add a contact to data store.
|
2012-11-13 22:42:55 +01:00
|
|
|
* @params params. An object which can contain the optional properties:
|
2012-12-17 15:19:22 +01:00
|
|
|
* aid: The id of the addressbook to add the contact to. Per default it will be added to the first.
|
|
|
|
* fn: The formatted name of the contact.
|
2012-11-13 22:42:55 +01:00
|
|
|
* @param cb Optional callback function which
|
|
|
|
* @returns The callback gets an object as argument with a variable 'status' of either 'success'
|
|
|
|
* or 'error'. On success the 'data' property of that object contains the contact id as 'id', the
|
|
|
|
* addressbook id as 'aid' and the contact data structure as 'details'.
|
2013-03-25 17:08:47 +01:00
|
|
|
* TODO: Use Storage for adding and make sure to get all metadata.
|
2012-11-13 22:42:55 +01:00
|
|
|
*/
|
|
|
|
Contact.prototype.add = function(params, cb) {
|
|
|
|
var self = this;
|
2013-03-25 17:08:47 +01:00
|
|
|
$.when(this.storage.addContact(this.metadata.backend, this.metadata.parent))
|
|
|
|
.then(function(response) {
|
2013-03-28 03:19:01 +01:00
|
|
|
if(!response.error) {
|
2013-03-25 17:08:47 +01:00
|
|
|
self.id = String(response.data.metadata.id);
|
|
|
|
self.metadata = response.data.metadata;
|
|
|
|
self.data = response.data.data;
|
2013-03-28 04:59:55 +01:00
|
|
|
self.$groupSelect.multiselect('enable');
|
2012-12-14 02:47:51 +01:00
|
|
|
// Add contact to current group
|
2013-01-16 13:34:30 +01:00
|
|
|
if(self.groupprops && self.groupprops.currentgroup.id !== 'all'
|
|
|
|
&& self.groupprops.currentgroup.id !== 'fav') {
|
2012-12-14 02:47:51 +01:00
|
|
|
if(!self.data.CATEGORIES) {
|
2013-01-16 13:34:30 +01:00
|
|
|
self.addToGroup(self.groupprops.currentgroup.name);
|
2012-12-14 02:47:51 +01:00
|
|
|
$(document).trigger('request.contact.addtogroup', {
|
|
|
|
id: self.id,
|
2012-12-17 15:19:22 +01:00
|
|
|
groupid: self.groupprops.currentgroup.id
|
2012-12-14 02:47:51 +01:00
|
|
|
});
|
2013-01-16 13:34:30 +01:00
|
|
|
self.$groupSelect.find('option[value="' + self.groupprops.currentgroup.id + '"]')
|
|
|
|
.attr('selected', 'selected');
|
|
|
|
self.$groupSelect.multiselect('refresh');
|
2012-12-14 02:47:51 +01:00
|
|
|
}
|
|
|
|
}
|
2012-11-13 22:42:55 +01:00
|
|
|
$(document).trigger('status.contact.added', {
|
|
|
|
id: self.id,
|
2012-12-17 15:19:22 +01:00
|
|
|
contact: self
|
2012-11-13 22:42:55 +01:00
|
|
|
});
|
2013-03-28 03:19:01 +01:00
|
|
|
} else {
|
|
|
|
$(document).trigger('status.contact.error', {
|
|
|
|
message: response.message
|
|
|
|
});
|
|
|
|
return false;
|
2012-11-13 22:42:55 +01:00
|
|
|
}
|
|
|
|
if(typeof cb == 'function') {
|
2013-03-25 17:08:47 +01:00
|
|
|
cb(response);
|
2012-11-13 22:42:55 +01:00
|
|
|
}
|
|
|
|
});
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Delete contact from data store and remove it from the DOM
|
|
|
|
* @param cb Optional callback function which
|
|
|
|
* @returns An object with a variable 'status' of either success
|
2012-12-17 15:19:22 +01:00
|
|
|
* or 'error'
|
2012-10-05 05:05:49 +02:00
|
|
|
*/
|
|
|
|
Contact.prototype.destroy = function(cb) {
|
|
|
|
var self = this;
|
2013-03-28 03:19:01 +01:00
|
|
|
$.when(this.storage.deleteContact(
|
|
|
|
this.metadata.backend,
|
|
|
|
this.metadata.parent,
|
|
|
|
this.id)
|
|
|
|
).then(function(response) {
|
|
|
|
//$.post(OC.filePath('contacts', 'ajax', 'contact/delete.php'),
|
|
|
|
// {id: this.id}, function(response) {
|
|
|
|
if(!response.error) {
|
2012-10-05 05:05:49 +02:00
|
|
|
if(self.$listelem) {
|
|
|
|
self.$listelem.remove();
|
|
|
|
}
|
|
|
|
if(self.$fullelem) {
|
|
|
|
self.$fullelem.remove();
|
2012-07-21 16:02:12 +02:00
|
|
|
}
|
2012-07-21 14:24:26 +02:00
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
if(typeof cb == 'function') {
|
2013-03-28 03:19:01 +01:00
|
|
|
if(response.error) {
|
|
|
|
cb(response);
|
2012-10-05 05:05:49 +02:00
|
|
|
} else {
|
2013-03-28 03:19:01 +01:00
|
|
|
cb({id:self.id});
|
2012-10-05 05:05:49 +02:00
|
|
|
}
|
2012-02-06 07:32:57 +01:00
|
|
|
}
|
2012-08-02 01:14:50 +02:00
|
|
|
});
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2013-03-25 17:08:47 +01:00
|
|
|
Contact.prototype.argumentsFor = function(obj) {
|
|
|
|
var args = {};
|
|
|
|
var ptype = this.propertyTypeFor(obj);
|
|
|
|
args['name'] = ptype;
|
|
|
|
|
|
|
|
if(this.multi_properties.indexOf(ptype) !== -1) {
|
|
|
|
args['checksum'] = this.checksumFor(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
if($(obj).hasClass('propertycontainer')) {
|
|
|
|
if($(obj).is('select[data-element="categories"]')) {
|
|
|
|
args['value'] = [];
|
|
|
|
$.each($(obj).find(':selected'), function(idx, e) {
|
|
|
|
args['value'].push($(e).text());
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
args['value'] = $(obj).val();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
var $elements = this.propertyContainerFor(obj)
|
|
|
|
.find('input.value,select.value,textarea.value');
|
|
|
|
if($elements.length > 1) {
|
|
|
|
args['value'] = [];
|
|
|
|
$.each($elements, function(idx, e) {
|
2013-03-29 17:15:20 +01:00
|
|
|
args['value'].push($(e).val());
|
2013-03-25 17:08:47 +01:00
|
|
|
});
|
|
|
|
} else {
|
|
|
|
args['value'] = $elements.val();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return args;
|
|
|
|
};
|
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
Contact.prototype.queryStringFor = function(obj) {
|
|
|
|
var q = 'id=' + this.id;
|
|
|
|
var ptype = this.propertyTypeFor(obj);
|
|
|
|
q += '&name=' + ptype;
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
if(this.multi_properties.indexOf(ptype) !== -1) {
|
|
|
|
q += '&checksum=' + this.checksumFor(obj);
|
|
|
|
}
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
if($(obj).hasClass('propertycontainer')) {
|
2013-01-04 10:27:22 +01:00
|
|
|
if($(obj).is('select[data-element="categories"]')) {
|
|
|
|
$.each($(obj).find(':selected'), function(idx, e) {
|
|
|
|
q += '&value=' + encodeURIComponent($(e).text());
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
q += '&value=' + encodeURIComponent($(obj).val());
|
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
} else {
|
2012-12-11 02:27:37 +01:00
|
|
|
var $elements = this.propertyContainerFor(obj)
|
|
|
|
.find('input.value,select.value,textarea.value,.parameter');
|
|
|
|
if($elements.length > 1) {
|
|
|
|
q += '&' + $elements.serialize();
|
|
|
|
} else {
|
|
|
|
q += '&value=' + encodeURIComponent($elements.val());
|
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
}
|
|
|
|
return q;
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
Contact.prototype.propertyContainerFor = function(obj) {
|
2012-11-13 22:42:55 +01:00
|
|
|
return $(obj).hasClass('propertycontainer')
|
2012-10-22 15:32:32 +02:00
|
|
|
? $(obj)
|
2012-10-05 05:05:49 +02:00
|
|
|
: $(obj).parents('.propertycontainer').first();
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-08-02 01:14:50 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
Contact.prototype.checksumFor = function(obj) {
|
|
|
|
return this.propertyContainerFor(obj).data('checksum');
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2012-10-23 06:26:51 +02:00
|
|
|
Contact.prototype.valueFor = function(obj) {
|
2012-11-13 22:42:55 +01:00
|
|
|
var $container = this.propertyContainerFor(obj);
|
2012-12-17 15:19:22 +01:00
|
|
|
console.assert($container.length > 0, 'Couldn\'t find container for ' + $(obj));
|
2013-03-25 17:08:47 +01:00
|
|
|
return $container.is('input.value')
|
2012-12-17 15:19:22 +01:00
|
|
|
? $container.val()
|
2012-11-22 00:31:08 +01:00
|
|
|
: (function() {
|
2013-01-16 13:34:30 +01:00
|
|
|
var $elem = $container.find('textarea.value,input.value:not(:checkbox)');
|
|
|
|
console.assert($elem.length > 0, 'Couldn\'t find value for ' + $container.data('element'));
|
|
|
|
if($elem.length === 1) {
|
|
|
|
return $elem.val();
|
|
|
|
} else if($elem.length > 1) {
|
|
|
|
var retval = [];
|
|
|
|
$.each($elem, function(idx, e) {
|
2013-02-26 22:24:54 +01:00
|
|
|
retval[parseInt($(e).attr('name').substr(6,1))] = $(e).val();
|
2013-01-04 10:27:22 +01:00
|
|
|
});
|
|
|
|
return retval;
|
2012-11-22 00:31:08 +01:00
|
|
|
}
|
|
|
|
})();
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-23 06:26:51 +02:00
|
|
|
|
2012-11-22 08:17:57 +01:00
|
|
|
Contact.prototype.parametersFor = function(obj, asText) {
|
2012-10-24 20:30:41 +02:00
|
|
|
var parameters = [];
|
2013-03-25 17:08:47 +01:00
|
|
|
$.each(this.propertyContainerFor(obj)
|
|
|
|
.find('select.parameter,input:checkbox:checked.parameter,textarea'), // Why do I look for textarea?
|
|
|
|
function(i, elem) {
|
2012-10-24 20:30:41 +02:00
|
|
|
var $elem = $(elem);
|
|
|
|
var paramname = $elem.data('parameter');
|
|
|
|
if(!parameters[paramname]) {
|
|
|
|
parameters[paramname] = [];
|
|
|
|
}
|
2013-03-25 17:08:47 +01:00
|
|
|
if($elem.is(':checkbox')) {
|
|
|
|
if(asText) {
|
|
|
|
parameters[paramname].push($elem.attr('title'));
|
|
|
|
} else {
|
|
|
|
parameters[paramname].push($elem.attr('value'));
|
2012-11-22 08:17:57 +01:00
|
|
|
}
|
2013-03-25 17:08:47 +01:00
|
|
|
} else if($elem.is('select')) {
|
|
|
|
$.each($elem.find(':selected'), function(idx, e) {
|
|
|
|
if(asText) {
|
|
|
|
parameters[paramname].push($(e).text());
|
|
|
|
} else {
|
|
|
|
parameters[paramname].push($(e).val());
|
|
|
|
}
|
|
|
|
});
|
2012-11-22 08:17:57 +01:00
|
|
|
}
|
2012-10-24 20:30:41 +02:00
|
|
|
});
|
|
|
|
return parameters;
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-24 20:30:41 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
Contact.prototype.propertyTypeFor = function(obj) {
|
|
|
|
var ptype = this.propertyContainerFor(obj).data('element');
|
|
|
|
return ptype ? ptype.toUpperCase() : null;
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2013-03-12 00:28:41 +01:00
|
|
|
/**
|
|
|
|
* Render an element item to be shown during drag.
|
|
|
|
* @return A jquery object
|
|
|
|
*/
|
|
|
|
Contact.prototype.renderDragItem = function() {
|
|
|
|
if(typeof this.$dragelem === 'undefined') {
|
|
|
|
this.$dragelem = this.$dragTemplate.octemplate({
|
|
|
|
id: this.id,
|
2013-03-29 20:09:48 +01:00
|
|
|
name: this.getPreferredValue('FN', '')
|
2013-03-12 00:28:41 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
return this.$dragelem;
|
|
|
|
}
|
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Render the list item
|
|
|
|
* @return A jquery object to be inserted in the DOM
|
|
|
|
*/
|
2013-03-15 15:07:35 +01:00
|
|
|
Contact.prototype.renderListItem = function(isnew) {
|
2012-10-05 05:05:49 +02:00
|
|
|
this.$listelem = this.$listTemplate.octemplate({
|
|
|
|
id: this.id,
|
2013-03-22 14:49:34 +01:00
|
|
|
parent: this.metadata.parent,
|
|
|
|
backend: this.metadata.backend,
|
2013-03-29 20:09:48 +01:00
|
|
|
name: this.getPreferredValue('FN', ''),
|
|
|
|
email: this.getPreferredValue('EMAIL', ''),
|
|
|
|
tel: this.getPreferredValue('TEL', ''),
|
|
|
|
adr: this.getPreferredValue('ADR', []).clean('').join(', '),
|
2012-10-05 05:05:49 +02:00
|
|
|
categories: this.getPreferredValue('CATEGORIES', [])
|
2012-12-17 15:19:22 +01:00
|
|
|
.clean('').join(' / ')
|
2012-08-02 01:14:50 +02:00
|
|
|
});
|
2013-03-22 14:49:34 +01:00
|
|
|
if(this.metadata.owner !== OC.currentUser
|
|
|
|
&& !(this.metadata.permissions & OC.PERMISSION_UPDATE
|
|
|
|
|| this.metadata.permissions & OC.PERMISSION_DELETE)) {
|
2012-10-05 05:05:49 +02:00
|
|
|
this.$listelem.find('input:checkbox').prop('disabled', true).css('opacity', '0');
|
|
|
|
}
|
|
|
|
return this.$listelem;
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-08-02 01:14:50 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Render the full contact
|
|
|
|
* @return A jquery object to be inserted in the DOM
|
|
|
|
*/
|
2012-12-14 02:48:56 +01:00
|
|
|
Contact.prototype.renderContact = function(groupprops) {
|
2012-10-05 05:05:49 +02:00
|
|
|
var self = this;
|
2012-12-22 02:01:08 +01:00
|
|
|
this.groupprops = groupprops;
|
|
|
|
|
2013-01-16 13:34:30 +01:00
|
|
|
var buildGroupSelect = function(availableGroups) {
|
|
|
|
//this.$groupSelect.find('option').remove();
|
2012-12-22 02:01:08 +01:00
|
|
|
$.each(availableGroups, function(idx, group) {
|
|
|
|
var $option = $('<option value="' + group.id + '">' + group.name + '</option>');
|
|
|
|
if(self.inGroup(group.name)) {
|
|
|
|
$option.attr('selected', 'selected');
|
|
|
|
}
|
2013-01-16 13:34:30 +01:00
|
|
|
self.$groupSelect.append($option);
|
|
|
|
});
|
|
|
|
self.$groupSelect.multiselect({
|
|
|
|
header: false,
|
|
|
|
selectedList: 3,
|
|
|
|
noneSelectedText: self.$groupSelect.attr('title'),
|
|
|
|
selectedText: t('contacts', '# groups')
|
|
|
|
});
|
|
|
|
self.$groupSelect.bind('multiselectclick', function(event, ui) {
|
|
|
|
var action = ui.checked ? 'addtogroup' : 'removefromgroup';
|
2013-03-25 17:08:47 +01:00
|
|
|
console.assert(typeof self.id === 'string', 'ID is not a string')
|
2013-01-16 13:34:30 +01:00
|
|
|
$(document).trigger('request.contact.' + action, {
|
|
|
|
id: self.id,
|
|
|
|
groupid: parseInt(ui.value)
|
|
|
|
});
|
|
|
|
if(ui.checked) {
|
|
|
|
self.addToGroup(ui.text);
|
|
|
|
} else {
|
|
|
|
self.removeFromGroup(ui.text);
|
|
|
|
}
|
2012-12-22 02:01:08 +01:00
|
|
|
});
|
2013-02-03 15:25:00 +01:00
|
|
|
if(!self.id) {
|
2013-03-28 04:59:55 +01:00
|
|
|
self.$groupSelect.multiselect('disable');
|
2013-02-03 15:25:00 +01:00
|
|
|
}
|
2012-12-22 02:01:08 +01:00
|
|
|
};
|
|
|
|
|
2013-03-25 17:08:47 +01:00
|
|
|
var buildAddressBookSelect = function(availableAddressBooks) {
|
|
|
|
console.log('address books', availableAddressBooks.length, availableAddressBooks);
|
|
|
|
/* TODO:
|
|
|
|
* - Check address books permissions.
|
|
|
|
* - Add method to change address book.
|
|
|
|
*/
|
|
|
|
$.each(availableAddressBooks, function(idx, addressBook) {
|
|
|
|
console.log('addressBook', idx, addressBook);
|
|
|
|
var $option = $('<option data-backend="'
|
|
|
|
+ addressBook.backend + '" value="' + addressBook.id + '">'
|
|
|
|
+ addressBook.displayname + '(' + addressBook.backend + ')</option>');
|
|
|
|
if(self.metadata.parent === addressBook.id
|
|
|
|
&& self.metadata.backend === addressBook.backend) {
|
|
|
|
$option.attr('selected', 'selected');
|
|
|
|
}
|
|
|
|
self.$addressBookSelect.append($option);
|
|
|
|
});
|
|
|
|
self.$addressBookSelect.multiselect({
|
|
|
|
header: false,
|
|
|
|
selectedList: 3,
|
|
|
|
noneSelectedText: self.$addressBookSelect.attr('title'),
|
|
|
|
selectedText: t('contacts', '# groups')
|
|
|
|
});
|
|
|
|
if(self.id) {
|
2013-03-28 04:59:55 +01:00
|
|
|
self.$addressBookSelect.multiselect('disable');
|
2013-03-25 17:08:47 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-11-22 04:09:52 +01:00
|
|
|
var n = this.getPreferredValue('N', ['', '', '', '', '']);
|
2012-12-10 00:02:06 +01:00
|
|
|
//console.log('Contact.renderContact', this.data);
|
2012-10-05 05:05:49 +02:00
|
|
|
var values = this.data
|
|
|
|
? {
|
|
|
|
id: this.id,
|
2012-12-14 02:48:56 +01:00
|
|
|
favorite:groupprops.favorite ? 'active' : '',
|
2013-03-29 20:09:48 +01:00
|
|
|
name: this.getPreferredValue('FN', ''),
|
2012-12-11 04:06:19 +01:00
|
|
|
n0: n[0]||'', n1: n[1]||'', n2: n[2]||'', n3: n[3]||'', n4: n[4]||'',
|
2013-03-29 20:09:48 +01:00
|
|
|
nickname: this.getPreferredValue('NICKNAME', ''),
|
|
|
|
title: this.getPreferredValue('TITLE', ''),
|
|
|
|
org: this.getPreferredValue('ORG', []).clean('').join(', '), // TODO Add parts if more than one.
|
2012-10-22 15:32:32 +02:00
|
|
|
bday: this.getPreferredValue('BDAY', '').length >= 10
|
2013-03-29 20:09:48 +01:00
|
|
|
? $.datepicker.formatDate('dd-mm-yy',
|
2012-10-22 15:32:32 +02:00
|
|
|
$.datepicker.parseDate('yy-mm-dd',
|
2013-03-29 20:09:48 +01:00
|
|
|
this.getPreferredValue('BDAY', '').substring(0, 10)))
|
2012-10-05 05:05:49 +02:00
|
|
|
: '',
|
2013-03-29 20:09:48 +01:00
|
|
|
note: this.getPreferredValue('NOTE', '')
|
2012-10-05 05:05:49 +02:00
|
|
|
}
|
2012-12-11 02:27:37 +01:00
|
|
|
: {id:'', favorite:'', name:'', nickname:'', title:'', org:'', bday:'', note:'', n0:'', n1:'', n2:'', n3:'', n4:''};
|
2012-10-05 05:05:49 +02:00
|
|
|
this.$fullelem = this.$fullTemplate.octemplate(values).data('contactobject', this);
|
2012-12-13 02:37:37 +01:00
|
|
|
|
|
|
|
this.$footer = this.$fullelem.find('footer');
|
2012-12-17 15:19:22 +01:00
|
|
|
|
2012-12-10 20:58:34 +01:00
|
|
|
this.$fullelem.find('.tooltipped.rightwards.onfocus').tipsy({trigger: 'focus', gravity: 'w'});
|
2012-12-10 00:02:06 +01:00
|
|
|
this.$fullelem.on('submit', function() {
|
|
|
|
return false;
|
|
|
|
});
|
2012-12-22 02:01:08 +01:00
|
|
|
|
|
|
|
this.$groupSelect = this.$fullelem.find('#contactgroups');
|
2013-01-16 13:34:30 +01:00
|
|
|
buildGroupSelect(groupprops.groups);
|
2012-12-22 02:01:08 +01:00
|
|
|
|
2013-03-25 17:08:47 +01:00
|
|
|
if(Object.keys(this.parent.addressbooks).length > 1) {
|
|
|
|
this.$addressBookSelect = this.$fullelem.find('#contactaddressbooks');
|
|
|
|
buildAddressBookSelect(this.parent.addressbooks);
|
|
|
|
}
|
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
this.$addMenu = this.$fullelem.find('#addproperty');
|
|
|
|
this.$addMenu.on('change', function(event) {
|
2012-12-10 00:02:06 +01:00
|
|
|
//console.log('add', $(this).val());
|
2012-10-05 05:05:49 +02:00
|
|
|
var $opt = $(this).find('option:selected');
|
|
|
|
self.addProperty($opt, $(this).val());
|
|
|
|
$(this).val('');
|
2012-08-02 01:14:50 +02:00
|
|
|
});
|
2012-10-24 20:30:41 +02:00
|
|
|
var $fullname = this.$fullelem.find('.fullname');
|
|
|
|
this.$fullelem.find('.singleproperties').on('mouseenter', function() {
|
|
|
|
$fullname.next('.edit').css('opacity', '1');
|
|
|
|
}).on('mouseleave', function() {
|
|
|
|
$fullname.next('.edit').css('opacity', '0');
|
|
|
|
});
|
|
|
|
$fullname.next('.edit').on('click keydown', function(event) {
|
2012-12-09 23:54:16 +01:00
|
|
|
//console.log('edit name', event);
|
2012-10-24 20:30:41 +02:00
|
|
|
$('.tipsy').remove();
|
|
|
|
if(wrongKey(event)) {
|
|
|
|
return;
|
|
|
|
}
|
2012-11-22 04:09:52 +01:00
|
|
|
$(this).css('opacity', '0');
|
2012-12-10 20:58:34 +01:00
|
|
|
var $editor = $(this).next('.n.editor').first();
|
2012-11-22 04:09:52 +01:00
|
|
|
var bodyListener = function(e) {
|
|
|
|
if($editor.find($(e.target)).length == 0) {
|
|
|
|
$editor.toggle('blind');
|
|
|
|
$('body').unbind('click', bodyListener);
|
|
|
|
}
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-11-22 04:09:52 +01:00
|
|
|
$editor.toggle('blind', function() {
|
|
|
|
$('body').bind('click', bodyListener);
|
|
|
|
});
|
2012-10-24 20:30:41 +02:00
|
|
|
});
|
2012-12-17 15:19:22 +01:00
|
|
|
|
2012-10-23 06:27:22 +02:00
|
|
|
this.$fullelem.on('click keydown', '.delete', function(event) {
|
|
|
|
$('.tipsy').remove();
|
|
|
|
if(wrongKey(event)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
self.deleteProperty({obj:event.target});
|
|
|
|
});
|
2012-12-10 00:02:06 +01:00
|
|
|
|
2012-12-13 02:37:37 +01:00
|
|
|
this.$footer.on('click keydown', 'button', function(event) {
|
2012-12-10 00:02:06 +01:00
|
|
|
$('.tipsy').remove();
|
|
|
|
if(wrongKey(event)) {
|
|
|
|
return;
|
|
|
|
}
|
2012-12-13 02:37:37 +01:00
|
|
|
if($(this).is('.close') || $(this).is('.cancel')) {
|
2012-12-11 04:05:34 +01:00
|
|
|
$(document).trigger('request.contact.close', {
|
2012-12-17 15:19:22 +01:00
|
|
|
id: self.id
|
2012-12-11 04:05:34 +01:00
|
|
|
});
|
|
|
|
} else if($(this).is('.export')) {
|
|
|
|
$(document).trigger('request.contact.export', {
|
2013-03-25 17:08:47 +01:00
|
|
|
backend: self.metadata.backend,
|
|
|
|
parent: self.metadata.parent,
|
|
|
|
contactid: self.id
|
2012-12-11 04:05:34 +01:00
|
|
|
});
|
2012-12-13 02:37:37 +01:00
|
|
|
} else if($(this).is('.delete')) {
|
2012-12-11 04:05:34 +01:00
|
|
|
$(document).trigger('request.contact.delete', {
|
2013-03-25 17:08:47 +01:00
|
|
|
backend: self.metadata.backend,
|
|
|
|
parent: self.metadata.parent,
|
|
|
|
contactid: self.id
|
2012-12-11 04:05:34 +01:00
|
|
|
});
|
|
|
|
}
|
2012-12-10 00:02:06 +01:00
|
|
|
return false;
|
|
|
|
});
|
|
|
|
this.$fullelem.on('keypress', '.value,.parameter', function(event) {
|
|
|
|
if(event.keyCode === 13 && $(this).is('input')) {
|
|
|
|
$(this).trigger('change');
|
2012-12-17 02:45:57 +01:00
|
|
|
// Prevent a second save on blur.
|
|
|
|
this.defaultValue = this.value;
|
2012-12-10 00:02:06 +01:00
|
|
|
return false;
|
|
|
|
} else if(event.keyCode === 27) {
|
|
|
|
$(document).trigger('request.contact.close', {
|
2012-12-17 15:19:22 +01:00
|
|
|
id: self.id
|
2012-12-10 00:02:06 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2012-12-17 15:19:22 +01:00
|
|
|
|
2012-10-23 06:27:22 +02:00
|
|
|
this.$fullelem.on('change', '.value,.parameter', function(event) {
|
2013-01-17 14:48:16 +01:00
|
|
|
if($(this).hasClass('value') && this.value === this.defaultValue) {
|
2012-12-17 02:45:57 +01:00
|
|
|
return;
|
|
|
|
}
|
2013-01-02 04:10:07 +01:00
|
|
|
console.log('change', this.defaultValue, this.value);
|
2013-03-25 17:08:47 +01:00
|
|
|
this.defaultValue = this.value;
|
2012-10-05 05:05:49 +02:00
|
|
|
self.saveProperty({obj:event.target});
|
2012-08-02 01:14:50 +02:00
|
|
|
});
|
2012-11-22 05:34:37 +01:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
this.$fullelem.find('[data-element="bday"]')
|
|
|
|
.find('input').datepicker({
|
|
|
|
dateFormat : 'dd-mm-yy'
|
2012-08-02 01:14:50 +02:00
|
|
|
});
|
2012-12-10 00:02:06 +01:00
|
|
|
this.$fullelem.find('.favorite').on('click', function () {
|
|
|
|
var state = $(this).hasClass('active');
|
2012-12-17 21:33:02 +01:00
|
|
|
if(!self.data) {
|
2012-12-14 02:49:23 +01:00
|
|
|
return;
|
|
|
|
}
|
2012-12-10 00:02:06 +01:00
|
|
|
if(state) {
|
|
|
|
$(this).switchClass('active', 'inactive');
|
|
|
|
} else {
|
|
|
|
$(this).switchClass('inactive', 'active');
|
|
|
|
}
|
|
|
|
$(document).trigger('request.contact.setasfavorite', {
|
|
|
|
id: self.id,
|
2012-12-17 15:19:22 +01:00
|
|
|
state: !state
|
2012-12-10 00:02:06 +01:00
|
|
|
});
|
|
|
|
});
|
2012-10-15 21:35:34 +02:00
|
|
|
this.loadPhoto();
|
2012-10-05 05:05:49 +02:00
|
|
|
if(!this.data) {
|
|
|
|
// A new contact
|
|
|
|
this.setEnabled(true);
|
2012-12-13 02:37:37 +01:00
|
|
|
this.showActions(['cancel']);
|
2012-10-05 05:05:49 +02:00
|
|
|
return this.$fullelem;
|
2012-08-02 01:14:50 +02:00
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
// Loop thru all single occurrence values. If not set hide the
|
|
|
|
// element, if set disable the add menu entry.
|
2012-11-27 03:37:00 +01:00
|
|
|
$.each(values, function(name, value) {
|
|
|
|
if(typeof value === 'undefined') {
|
|
|
|
return true; //continue
|
|
|
|
}
|
2012-12-11 06:20:25 +01:00
|
|
|
value = value.toString();
|
2012-11-27 03:37:00 +01:00
|
|
|
if(self.multi_properties.indexOf(value.toUpperCase()) === -1) {
|
|
|
|
if(!value.length) {
|
|
|
|
self.$fullelem.find('[data-element="' + name + '"]').hide();
|
2012-10-05 05:05:49 +02:00
|
|
|
} else {
|
2012-11-27 03:37:00 +01:00
|
|
|
self.$addMenu.find('option[value="' + name.toUpperCase() + '"]').prop('disabled', true);
|
2012-08-02 01:14:50 +02:00
|
|
|
}
|
2012-02-06 07:32:57 +01:00
|
|
|
}
|
2012-11-27 03:37:00 +01:00
|
|
|
});
|
2012-10-05 05:05:49 +02:00
|
|
|
$.each(this.multi_properties, function(idx, name) {
|
|
|
|
if(self.data[name]) {
|
|
|
|
var $list = self.$fullelem.find('ul.' + name.toLowerCase());
|
|
|
|
$list.show();
|
|
|
|
for(var p in self.data[name]) {
|
|
|
|
if(typeof self.data[name][p] === 'object') {
|
|
|
|
var property = self.data[name][p];
|
|
|
|
//console.log(name, p, property);
|
2012-12-11 02:28:22 +01:00
|
|
|
var $property = null;
|
2012-10-05 05:05:49 +02:00
|
|
|
switch(name) {
|
|
|
|
case 'TEL':
|
|
|
|
case 'URL':
|
|
|
|
case 'EMAIL':
|
|
|
|
$property = self.renderStandardProperty(name.toLowerCase(), property);
|
2013-01-17 14:48:16 +01:00
|
|
|
if(self.data[name].length === 1) {
|
2012-11-05 20:52:54 +01:00
|
|
|
$property.find('input:checkbox[value="PREF"]').hide();
|
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
break;
|
|
|
|
case 'ADR':
|
2012-11-22 00:22:12 +01:00
|
|
|
$property = self.renderAddressProperty(idx, property);
|
2012-10-05 05:05:49 +02:00
|
|
|
break;
|
|
|
|
case 'IMPP':
|
|
|
|
$property = self.renderIMProperty(property);
|
2013-01-17 14:48:16 +01:00
|
|
|
if(self.data[name].length === 1) {
|
|
|
|
$property.find('input:checkbox[value="PREF"]').hide();
|
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(!$property) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
//console.log('$property', $property);
|
2012-11-22 08:17:57 +01:00
|
|
|
var meta = [];
|
2012-10-05 05:05:49 +02:00
|
|
|
if(property.label) {
|
|
|
|
if(!property.parameters['TYPE']) {
|
|
|
|
property.parameters['TYPE'] = [];
|
2012-08-02 01:14:50 +02:00
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
property.parameters['TYPE'].push(property.label);
|
2012-11-22 08:17:57 +01:00
|
|
|
meta.push(property.label);
|
2012-08-02 01:14:50 +02:00
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
for(var param in property.parameters) {
|
|
|
|
//console.log('param', param);
|
|
|
|
if(param.toUpperCase() == 'PREF') {
|
2012-11-22 08:17:57 +01:00
|
|
|
var $cb = $property.find('input[type="checkbox"]');
|
2012-12-17 15:19:22 +01:00
|
|
|
$cb.attr('checked', 'checked');
|
2012-11-22 08:17:57 +01:00
|
|
|
meta.push($cb.attr('title'));
|
2012-10-05 05:05:49 +02:00
|
|
|
}
|
|
|
|
else if(param.toUpperCase() == 'TYPE') {
|
2012-12-11 02:28:22 +01:00
|
|
|
for(var etype in property.parameters[param]) {
|
2012-10-05 05:05:49 +02:00
|
|
|
var found = false;
|
|
|
|
var et = property.parameters[param][etype];
|
|
|
|
if(typeof et !== 'string') {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
//console.log('et', et);
|
|
|
|
if(et.toUpperCase() === 'INTERNET') {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$property.find('select.type option').each(function() {
|
|
|
|
if($(this).val().toUpperCase() === et.toUpperCase()) {
|
|
|
|
$(this).attr('selected', 'selected');
|
2012-11-22 08:17:57 +01:00
|
|
|
meta.push($(this).text());
|
2012-10-05 05:05:49 +02:00
|
|
|
found = true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
if(!found) {
|
|
|
|
$property.find('select.type option:last-child').after('<option value="'+et+'" selected="selected">'+et+'</option>');
|
|
|
|
}
|
2012-08-02 01:14:50 +02:00
|
|
|
}
|
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
else if(param.toUpperCase() == 'X-SERVICE-TYPE') {
|
|
|
|
//console.log('setting', $property.find('select.impp'), 'to', property.parameters[param].toLowerCase());
|
|
|
|
$property.find('select.impp').val(property.parameters[param].toLowerCase());
|
2012-08-02 01:14:50 +02:00
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
}
|
2012-11-22 08:17:57 +01:00
|
|
|
var $meta = $property.find('.meta');
|
|
|
|
if($meta.length) {
|
|
|
|
$meta.html(meta.join('/'));
|
|
|
|
}
|
2013-03-22 14:49:34 +01:00
|
|
|
if(self.metadata.owner === OC.currentUser
|
|
|
|
|| self.metadata.permissions & OC.PERMISSION_UPDATE
|
|
|
|
|| self.metadata.permissions & OC.PERMISSION_DELETE) {
|
2012-10-15 21:35:34 +02:00
|
|
|
$property.find('select.type[name="parameters[TYPE][]"]')
|
|
|
|
.combobox({
|
|
|
|
singleclick: true,
|
2012-12-17 15:19:22 +01:00
|
|
|
classes: ['propertytype', 'float', 'label']
|
2012-10-15 21:35:34 +02:00
|
|
|
});
|
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
$list.append($property);
|
2012-08-02 01:14:50 +02:00
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
}
|
2012-05-02 12:10:44 +02:00
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
});
|
2013-03-22 14:49:34 +01:00
|
|
|
if(this.metadata.owner !== OC.currentUser
|
|
|
|
&& !(this.metadata.permissions & OC.PERMISSION_UPDATE
|
|
|
|
|| this.metadata.permissions & OC.PERMISSION_DELETE)) {
|
2012-10-05 05:05:49 +02:00
|
|
|
this.setEnabled(false);
|
2012-12-17 03:20:51 +01:00
|
|
|
this.showActions(['close', 'export']);
|
2012-10-05 05:05:49 +02:00
|
|
|
} else {
|
|
|
|
this.setEnabled(true);
|
2012-12-13 02:37:37 +01:00
|
|
|
this.showActions(['close', 'add', 'export', 'delete']);
|
2012-10-05 05:05:49 +02:00
|
|
|
}
|
|
|
|
return this.$fullelem;
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-07-21 14:26:26 +02:00
|
|
|
|
2012-10-15 21:35:34 +02:00
|
|
|
Contact.prototype.isEditable = function() {
|
2013-03-22 14:49:34 +01:00
|
|
|
return ((this.metadata.owner === OC.currentUser)
|
|
|
|
|| (this.metadata.permissions & OC.PERMISSION_UPDATE
|
|
|
|
|| this.metadata.permissions & OC.PERMISSION_DELETE));
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:33:44 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Render a simple property. Used for EMAIL and TEL.
|
|
|
|
* @return A jquery object to be injected in the DOM
|
|
|
|
*/
|
|
|
|
Contact.prototype.renderStandardProperty = function(name, property) {
|
|
|
|
if(!this.detailTemplates[name]) {
|
2012-12-14 16:35:10 +01:00
|
|
|
console.error('No template for', name);
|
2012-10-05 05:05:49 +02:00
|
|
|
return;
|
|
|
|
}
|
2012-10-22 15:33:44 +02:00
|
|
|
var values = property
|
2013-03-29 20:09:48 +01:00
|
|
|
? { value: property.value, checksum: property.checksum }
|
2012-10-05 05:05:49 +02:00
|
|
|
: { value: '', checksum: 'new' };
|
2012-12-11 02:28:22 +01:00
|
|
|
return this.detailTemplates[name].octemplate(values);
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-07-21 14:26:26 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Render an ADR (address) property.
|
|
|
|
* @return A jquery object to be injected in the DOM
|
|
|
|
*/
|
2012-11-22 00:22:12 +01:00
|
|
|
Contact.prototype.renderAddressProperty = function(idx, property) {
|
2012-10-05 05:05:49 +02:00
|
|
|
if(!this.detailTemplates['adr']) {
|
2012-12-09 23:54:16 +01:00
|
|
|
console.warn('No template for adr', this.detailTemplates);
|
2012-10-05 05:05:49 +02:00
|
|
|
return;
|
|
|
|
}
|
2012-11-22 00:22:12 +01:00
|
|
|
if(typeof idx === 'undefined') {
|
|
|
|
if(this.data && this.data.ADR && this.data.ADR.length > 0) {
|
|
|
|
idx = this.data.ADR.length - 1;
|
|
|
|
} else {
|
|
|
|
idx = 0;
|
|
|
|
}
|
|
|
|
}
|
2012-10-22 15:33:44 +02:00
|
|
|
var values = property ? {
|
2013-03-29 20:09:48 +01:00
|
|
|
value: property.value.clean('').join(', '),
|
2012-10-05 05:05:49 +02:00
|
|
|
checksum: property.checksum,
|
2013-03-29 20:09:48 +01:00
|
|
|
adr0: property.value[0] || '',
|
|
|
|
adr1: property.value[1] || '',
|
|
|
|
adr2: property.value[2] || '',
|
|
|
|
adr3: property.value[3] || '',
|
|
|
|
adr4: property.value[4] || '',
|
|
|
|
adr5: property.value[5] || '',
|
|
|
|
adr6: property.value[6] || '',
|
2012-12-17 15:19:22 +01:00
|
|
|
idx: idx
|
2012-11-22 00:22:12 +01:00
|
|
|
}
|
|
|
|
: {value:'', checksum:'new', adr0:'', adr1:'', adr2:'', adr3:'', adr4:'', adr5:'', adr6:'', idx: idx};
|
|
|
|
var $elem = this.detailTemplates['adr'].octemplate(values);
|
|
|
|
var self = this;
|
2012-12-10 20:58:34 +01:00
|
|
|
$elem.find('.tooltipped.downwards:not(.onfocus)').tipsy({gravity: 'n'});
|
|
|
|
$elem.find('.tooltipped.rightwards.onfocus').tipsy({trigger: 'focus', gravity: 'w'});
|
2012-11-22 08:17:57 +01:00
|
|
|
$elem.find('.display').on('click', function() {
|
2012-11-22 00:22:12 +01:00
|
|
|
$(this).next('.listactions').hide();
|
2012-12-10 20:58:34 +01:00
|
|
|
var $editor = $(this).siblings('.adr.editor').first();
|
2012-11-22 00:22:12 +01:00
|
|
|
var $viewer = $(this);
|
|
|
|
var bodyListener = function(e) {
|
|
|
|
if($editor.find($(e.target)).length == 0) {
|
|
|
|
$editor.toggle('blind');
|
|
|
|
$viewer.slideDown(400, function() {
|
|
|
|
var input = $editor.find('input').first();
|
|
|
|
var val = self.valueFor(input);
|
2012-11-22 08:17:57 +01:00
|
|
|
var params = self.parametersFor(input, true);
|
|
|
|
$(this).find('.meta').html(params['TYPE'].join('/'));
|
2013-03-29 20:09:48 +01:00
|
|
|
$(this).find('.adr').html(self.valueFor($editor.find('input').first()).clean('').join(', '));
|
2012-11-22 00:22:12 +01:00
|
|
|
$(this).next('.listactions').css('display', 'inline-block');
|
|
|
|
$('body').unbind('click', bodyListener);
|
|
|
|
});
|
|
|
|
}
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-11-22 00:22:12 +01:00
|
|
|
$viewer.slideUp();
|
|
|
|
$editor.toggle('blind', function() {
|
|
|
|
$('body').bind('click', bodyListener);
|
|
|
|
});
|
|
|
|
});
|
2012-12-11 06:58:42 +01:00
|
|
|
$elem.find('.value.city')
|
|
|
|
.autocomplete({
|
|
|
|
source: function( request, response ) {
|
|
|
|
$.ajax({
|
|
|
|
url: "http://ws.geonames.org/searchJSON",
|
|
|
|
dataType: "jsonp",
|
|
|
|
data: {
|
|
|
|
featureClass: "P",
|
|
|
|
style: "full",
|
|
|
|
maxRows: 12,
|
2013-01-25 16:22:38 +01:00
|
|
|
lang: $elem.data('lang'),
|
2012-12-11 06:58:42 +01:00
|
|
|
name_startsWith: request.term
|
|
|
|
},
|
|
|
|
success: function( data ) {
|
|
|
|
response( $.map( data.geonames, function( item ) {
|
|
|
|
return {
|
|
|
|
label: item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName,
|
|
|
|
value: item.name,
|
|
|
|
country: item.countryName
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-12-11 06:58:42 +01:00
|
|
|
}));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
minLength: 2,
|
|
|
|
select: function( event, ui ) {
|
2013-02-12 11:56:09 +01:00
|
|
|
if(ui.item && $.trim($elem.find('.value.country').val()).length == 0) {
|
2012-12-11 06:58:42 +01:00
|
|
|
$elem.find('.value.country').val(ui.item.country);
|
|
|
|
}
|
2012-12-17 15:19:22 +01:00
|
|
|
}
|
2012-12-11 06:58:42 +01:00
|
|
|
});
|
|
|
|
$elem.find('.value.country')
|
|
|
|
.autocomplete({
|
|
|
|
source: function( request, response ) {
|
|
|
|
$.ajax({
|
|
|
|
url: "http://ws.geonames.org/searchJSON",
|
|
|
|
dataType: "jsonp",
|
|
|
|
data: {
|
|
|
|
/*featureClass: "A",*/
|
|
|
|
featureCode: "PCLI",
|
|
|
|
/*countryBias: "true",*/
|
|
|
|
/*style: "full",*/
|
|
|
|
lang: lang,
|
|
|
|
maxRows: 12,
|
|
|
|
name_startsWith: request.term
|
|
|
|
},
|
|
|
|
success: function( data ) {
|
|
|
|
response( $.map( data.geonames, function( item ) {
|
|
|
|
return {
|
|
|
|
label: item.name,
|
|
|
|
value: item.name
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-12-11 06:58:42 +01:00
|
|
|
}));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
2012-12-17 15:19:22 +01:00
|
|
|
minLength: 2
|
2012-12-11 06:58:42 +01:00
|
|
|
});
|
2012-10-05 05:05:49 +02:00
|
|
|
return $elem;
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-07-21 14:26:26 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Render an IMPP (Instant Messaging) property.
|
|
|
|
* @return A jquery object to be injected in the DOM
|
|
|
|
*/
|
|
|
|
Contact.prototype.renderIMProperty = function(property) {
|
|
|
|
if(!this.detailTemplates['impp']) {
|
2012-12-09 23:54:16 +01:00
|
|
|
console.warn('No template for impp', this.detailTemplates);
|
2012-10-05 05:05:49 +02:00
|
|
|
return;
|
|
|
|
}
|
2012-10-22 15:33:44 +02:00
|
|
|
var values = property ? {
|
2013-03-29 20:09:48 +01:00
|
|
|
value: property.value,
|
2012-12-17 15:19:22 +01:00
|
|
|
checksum: property.checksum
|
2012-10-05 05:05:49 +02:00
|
|
|
} : {value: '', checksum: 'new'};
|
2012-12-11 14:42:01 +01:00
|
|
|
return this.detailTemplates['impp'].octemplate(values);
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:33:44 +02:00
|
|
|
|
2013-03-25 17:08:47 +01:00
|
|
|
/**
|
|
|
|
* Set a thumbnail for the contact if a PHOTO property exists
|
|
|
|
*/
|
|
|
|
Contact.prototype.setThumbnail = function(refresh) {
|
2013-04-04 17:00:22 +02:00
|
|
|
if(!this.data.thumbnail) {
|
2013-03-25 17:08:47 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
var $elem = this.getListItemElement().find('td.name');
|
2013-04-04 17:00:22 +02:00
|
|
|
if(!$elem.hasClass('thumbnail') && !refresh) {
|
2013-03-25 17:08:47 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
$elem.removeClass('thumbnail');
|
2013-04-04 17:00:22 +02:00
|
|
|
$elem.css('background-image', 'url(data:image/png;base64,' + this.data.thumbnail + ')');
|
2013-03-25 17:08:47 +01:00
|
|
|
}
|
|
|
|
|
2012-10-15 21:35:34 +02:00
|
|
|
/**
|
|
|
|
* Render the PHOTO property.
|
|
|
|
*/
|
|
|
|
Contact.prototype.loadPhoto = function(dontloadhandlers) {
|
|
|
|
var self = this;
|
2013-03-23 02:06:34 +01:00
|
|
|
var id = this.id || 'new',
|
|
|
|
backend = this.metadata.backend,
|
2013-03-25 17:08:47 +01:00
|
|
|
parent = this.metadata.parent,
|
|
|
|
src;
|
|
|
|
if(this.getPreferredValue('PHOTO', null) === null) {
|
|
|
|
src = this.storage.contactPhoto;
|
|
|
|
} else {
|
|
|
|
var refreshstr = '&refresh='+Math.random();
|
|
|
|
src = OC.linkTo('contacts', 'photo.php')+'?backend='+backend+'&parent='+parent+'&id='+id+refreshstr;
|
|
|
|
}
|
2012-10-15 21:35:34 +02:00
|
|
|
this.$photowrapper = this.$fullelem.find('#photowrapper');
|
|
|
|
this.$photowrapper.addClass('loading').addClass('wait');
|
|
|
|
var $phototools = this.$fullelem.find('#phototools');
|
|
|
|
delete this.photo;
|
2012-12-17 15:19:22 +01:00
|
|
|
$('img.contactphoto').remove();
|
2012-10-15 21:35:34 +02:00
|
|
|
this.photo = new Image();
|
|
|
|
$(this.photo).load(function () {
|
|
|
|
$(this).addClass('contactphoto');
|
2012-12-11 14:42:29 +01:00
|
|
|
self.$photowrapper.css({width: $(this).get(0).width + 10, height: $(this).get(0).height + 10});
|
2012-10-15 21:35:34 +02:00
|
|
|
self.$photowrapper.removeClass('loading').removeClass('wait');
|
|
|
|
$(this).insertAfter($phototools).fadeIn();
|
|
|
|
}).error(function () {
|
|
|
|
OC.notify({message:t('contacts','Error loading profile picture.')});
|
2013-03-25 17:08:47 +01:00
|
|
|
}).attr('src', src);
|
2012-10-22 15:33:44 +02:00
|
|
|
|
2012-10-15 21:35:34 +02:00
|
|
|
if(!dontloadhandlers && this.isEditable()) {
|
2012-12-10 00:02:06 +01:00
|
|
|
this.$photowrapper.on('mouseenter', function(event) {
|
2012-12-14 02:49:23 +01:00
|
|
|
if($(event.target).is('.favorite') || !self.data) {
|
2012-12-10 00:02:06 +01:00
|
|
|
return;
|
|
|
|
}
|
2012-10-15 21:35:34 +02:00
|
|
|
$phototools.slideDown(200);
|
|
|
|
}).on('mouseleave', function() {
|
|
|
|
$phototools.slideUp(200);
|
|
|
|
});
|
|
|
|
$phototools.hover( function () {
|
|
|
|
$(this).removeClass('transparent');
|
|
|
|
}, function () {
|
|
|
|
$(this).addClass('transparent');
|
|
|
|
});
|
|
|
|
$phototools.find('li a').tipsy();
|
|
|
|
|
|
|
|
$phototools.find('.edit').on('click', function() {
|
|
|
|
$(document).trigger('request.edit.contactphoto', {
|
2012-12-17 15:19:22 +01:00
|
|
|
id: self.id
|
2012-10-15 21:35:34 +02:00
|
|
|
});
|
|
|
|
});
|
|
|
|
$phototools.find('.cloud').on('click', function() {
|
|
|
|
$(document).trigger('request.select.contactphoto.fromcloud', {
|
2012-12-17 15:19:22 +01:00
|
|
|
id: self.id
|
2012-10-15 21:35:34 +02:00
|
|
|
});
|
|
|
|
});
|
|
|
|
$phototools.find('.upload').on('click', function() {
|
|
|
|
$(document).trigger('request.select.contactphoto.fromlocal', {
|
2012-12-17 15:19:22 +01:00
|
|
|
id: self.id
|
2012-10-15 21:35:34 +02:00
|
|
|
});
|
|
|
|
});
|
2012-11-13 17:00:29 +01:00
|
|
|
if(this.data && this.data.PHOTO) {
|
2012-10-15 21:35:34 +02:00
|
|
|
$phototools.find('.delete').show();
|
|
|
|
$phototools.find('.edit').show();
|
|
|
|
} else {
|
|
|
|
$phototools.find('.delete').hide();
|
|
|
|
$phototools.find('.edit').hide();
|
|
|
|
}
|
|
|
|
$(document).bind('status.contact.photoupdated', function(e, result) {
|
|
|
|
self.loadPhoto(true);
|
|
|
|
var refreshstr = '&refresh='+Math.random();
|
|
|
|
self.getListItemElement().find('td.name')
|
2013-03-23 02:06:34 +01:00
|
|
|
.css('background', 'url(' + OC.filePath('', '', 'remote.php')
|
|
|
|
+'/contactthumbnail?backend='+backend+'&parent='+parent+'id='+id+refreshstr + ')');
|
2012-10-15 21:35:34 +02:00
|
|
|
});
|
|
|
|
}
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-15 21:35:34 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Get the jquery element associated with this object
|
|
|
|
*/
|
|
|
|
Contact.prototype.getListItemElement = function() {
|
|
|
|
if(!this.$listelem) {
|
|
|
|
this.renderListItem();
|
|
|
|
}
|
|
|
|
return this.$listelem;
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:33:44 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Get the preferred value for a property.
|
|
|
|
* If a preferred value is not found the first one will be returned.
|
|
|
|
* @param string name The name of the property like EMAIL, TEL or ADR.
|
|
|
|
* @param def A default value to return if nothing is found.
|
|
|
|
*/
|
|
|
|
Contact.prototype.getPreferredValue = function(name, def) {
|
|
|
|
var pref = def, found = false;
|
2012-11-22 04:09:52 +01:00
|
|
|
if(this.data && this.data[name]) {
|
2012-10-05 05:05:49 +02:00
|
|
|
var props = this.data[name];
|
|
|
|
//console.log('props', props);
|
|
|
|
$.each(props, function( i, prop ) {
|
|
|
|
//console.log('prop:', i, prop);
|
|
|
|
if(i === 0) { // Choose first to start with
|
|
|
|
pref = prop.value;
|
|
|
|
}
|
|
|
|
for(var param in prop.parameters) {
|
|
|
|
if(param.toUpperCase() == 'PREF') {
|
|
|
|
found = true; //
|
|
|
|
break;
|
|
|
|
}
|
2012-08-23 16:39:25 +02:00
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
if(found) {
|
|
|
|
return false; // break out of loop
|
2012-08-23 16:39:25 +02:00
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
return pref;
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:33:44 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Returns true/false depending on the contact being in the
|
|
|
|
* specified group.
|
|
|
|
* @param String name The group name (not case-sensitive)
|
|
|
|
* @returns Boolean
|
|
|
|
*/
|
|
|
|
Contact.prototype.inGroup = function(name) {
|
2013-01-08 05:49:40 +01:00
|
|
|
var categories = this.getPreferredValue('CATEGORIES', []);
|
|
|
|
var found = false;
|
2012-10-22 15:33:44 +02:00
|
|
|
|
2013-01-08 05:49:40 +01:00
|
|
|
$.each(categories, function(idx, category) {
|
2013-02-12 11:56:09 +01:00
|
|
|
if(name.toLowerCase() == $.trim(category).toLowerCase()) {
|
2013-01-08 05:49:40 +01:00
|
|
|
found = true
|
|
|
|
return false;
|
2012-08-23 16:39:25 +02:00
|
|
|
}
|
2013-01-08 05:49:40 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
return found;
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-08-23 16:39:25 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Add this contact to a group
|
|
|
|
* @param String name The group name
|
|
|
|
*/
|
|
|
|
Contact.prototype.addToGroup = function(name) {
|
|
|
|
console.log('addToGroup', name);
|
|
|
|
if(!this.data.CATEGORIES) {
|
2012-12-17 15:19:22 +01:00
|
|
|
this.data.CATEGORIES = [{value:[name]}];
|
2012-10-05 05:05:49 +02:00
|
|
|
} else {
|
2012-12-11 06:23:18 +01:00
|
|
|
if(this.inGroup(name)) {
|
2012-11-23 01:16:46 +01:00
|
|
|
return;
|
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
this.data.CATEGORIES[0].value.push(name);
|
|
|
|
if(this.$listelem) {
|
|
|
|
this.$listelem.find('td.categories')
|
|
|
|
.text(this.getPreferredValue('CATEGORIES', []).clean('').join(' / '));
|
2012-08-23 22:02:38 +02:00
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
}
|
|
|
|
this.saveProperty({name:'CATEGORIES', value:this.data.CATEGORIES[0].value.join(',') });
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-05 05:05:49 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove this contact to a group
|
|
|
|
* @param String name The group name
|
|
|
|
*/
|
|
|
|
Contact.prototype.removeFromGroup = function(name) {
|
|
|
|
console.log('removeFromGroup', name);
|
|
|
|
if(!this.data.CATEGORIES) {
|
|
|
|
return;
|
|
|
|
} else {
|
2012-11-23 01:16:46 +01:00
|
|
|
var found = false;
|
|
|
|
var categories = [];
|
|
|
|
$.each(this.data.CATEGORIES[0].value, function(idx, category) {
|
2012-11-23 04:16:07 +01:00
|
|
|
if(name.toLowerCase() === category.toLowerCase()) {
|
2012-11-23 01:16:46 +01:00
|
|
|
found = true;
|
|
|
|
} else {
|
|
|
|
categories.push(category);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
if(!found) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.data.CATEGORIES[0].value = categories;
|
|
|
|
//this.data.CATEGORIES[0].value.splice(this.data.CATEGORIES[0].value.indexOf(name), 1);
|
2012-10-05 05:05:49 +02:00
|
|
|
if(this.$listelem) {
|
|
|
|
this.$listelem.find('td.categories')
|
2012-11-23 04:16:07 +01:00
|
|
|
.text(categories.join(' / '));
|
2012-08-02 01:14:50 +02:00
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
}
|
|
|
|
this.saveProperty({name:'CATEGORIES', value:this.data.CATEGORIES[0].value.join(',') });
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-05 05:05:49 +02:00
|
|
|
|
|
|
|
Contact.prototype.setCurrent = function(on) {
|
|
|
|
if(on) {
|
|
|
|
this.$listelem.addClass('active');
|
|
|
|
} else {
|
|
|
|
this.$listelem.removeClass('active');
|
|
|
|
}
|
|
|
|
$(document).trigger('status.contact.currentlistitem', {
|
|
|
|
id: this.id,
|
|
|
|
pos: Math.round(this.$listelem.position().top),
|
2012-12-17 15:19:22 +01:00
|
|
|
height: Math.round(this.$listelem.height())
|
2012-10-05 05:05:49 +02:00
|
|
|
});
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-05 05:05:49 +02:00
|
|
|
|
|
|
|
Contact.prototype.next = function() {
|
2013-03-23 02:06:34 +01:00
|
|
|
// This used to work..?
|
|
|
|
//var $next = this.$listelem.next('tr:visible');
|
|
|
|
var $next = this.$listelem.nextAll('tr').filter(':visible').first();
|
2012-10-05 05:05:49 +02:00
|
|
|
if($next.length > 0) {
|
|
|
|
this.$listelem.removeClass('active');
|
|
|
|
$next.addClass('active');
|
|
|
|
$(document).trigger('status.contact.currentlistitem', {
|
2013-03-22 14:49:34 +01:00
|
|
|
id: String($next.data('id')),
|
2012-10-05 05:05:49 +02:00
|
|
|
pos: Math.round($next.position().top),
|
2012-12-17 15:19:22 +01:00
|
|
|
height: Math.round($next.height())
|
2012-05-10 20:43:40 +02:00
|
|
|
});
|
2012-10-05 05:05:49 +02:00
|
|
|
}
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-05-10 20:43:40 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
Contact.prototype.prev = function() {
|
2013-03-23 02:06:34 +01:00
|
|
|
//var $prev = this.$listelem.prev('tr:visible');
|
|
|
|
var $prev = this.$listelem.prevAll('tr').filter(':visible').first();
|
2012-10-05 05:05:49 +02:00
|
|
|
if($prev.length > 0) {
|
|
|
|
this.$listelem.removeClass('active');
|
|
|
|
$prev.addClass('active');
|
|
|
|
$(document).trigger('status.contact.currentlistitem', {
|
2013-03-22 14:49:34 +01:00
|
|
|
id: String($prev.data('id')),
|
2012-10-05 05:05:49 +02:00
|
|
|
pos: Math.round($prev.position().top),
|
2012-12-17 15:19:22 +01:00
|
|
|
height: Math.round($prev.height())
|
2012-10-05 05:05:49 +02:00
|
|
|
});
|
|
|
|
}
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-05 05:05:49 +02:00
|
|
|
|
2013-03-12 00:28:41 +01:00
|
|
|
var ContactList = function(
|
2013-03-22 14:49:34 +01:00
|
|
|
storage,
|
2013-03-12 00:28:41 +01:00
|
|
|
contactlist,
|
|
|
|
contactlistitemtemplate,
|
|
|
|
contactdragitemtemplate,
|
|
|
|
contactfulltemplate,
|
|
|
|
contactdetailtemplates
|
|
|
|
) {
|
2012-10-05 05:05:49 +02:00
|
|
|
//console.log('ContactList', contactlist, contactlistitemtemplate, contactfulltemplate, contactdetailtemplates);
|
|
|
|
var self = this;
|
|
|
|
this.length = 0;
|
|
|
|
this.contacts = {};
|
2013-03-22 14:49:34 +01:00
|
|
|
this.addressbooks = {};
|
2012-10-05 05:05:49 +02:00
|
|
|
this.deletionQueue = [];
|
2013-03-22 14:49:34 +01:00
|
|
|
this.storage = storage;
|
2012-10-05 05:05:49 +02:00
|
|
|
this.$contactList = contactlist;
|
2013-03-12 00:28:41 +01:00
|
|
|
this.$contactDragItemTemplate = contactdragitemtemplate;
|
2012-10-05 05:05:49 +02:00
|
|
|
this.$contactListItemTemplate = contactlistitemtemplate;
|
|
|
|
this.$contactFullTemplate = contactfulltemplate;
|
|
|
|
this.contactDetailTemplates = contactdetailtemplates;
|
|
|
|
this.$contactList.scrollTop(0);
|
2013-03-22 14:49:34 +01:00
|
|
|
this.getAddressBooks();
|
2012-11-13 22:42:55 +01:00
|
|
|
$(document).bind('status.contact.added', function(e, data) {
|
2013-02-16 23:00:11 +01:00
|
|
|
self.length += 1;
|
2013-03-22 14:49:34 +01:00
|
|
|
self.contacts[String(data.id)] = data.contact;
|
2013-03-15 15:07:35 +01:00
|
|
|
self.insertContact(data.contact.renderListItem(true));
|
2012-11-13 22:42:55 +01:00
|
|
|
});
|
2012-10-22 15:33:44 +02:00
|
|
|
|
2012-12-17 10:23:09 +01:00
|
|
|
$(document).bind('status.contact.updated', function(e, data) {
|
2012-12-22 00:27:21 +01:00
|
|
|
if(['FN', 'EMAIL', 'TEL', 'ADR', 'CATEGORIES'].indexOf(data.property) !== -1) {
|
|
|
|
data.contact.getListItemElement().remove();
|
2013-03-22 14:49:34 +01:00
|
|
|
self.insertContact(self.contacts[String(data.contact.id)].renderListItem(true));
|
2012-12-22 00:27:21 +01:00
|
|
|
}
|
2012-11-13 22:42:55 +01:00
|
|
|
});
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-05 05:05:49 +02:00
|
|
|
|
2013-03-25 17:08:47 +01:00
|
|
|
/**
|
|
|
|
* Get the number of contacts in the list
|
|
|
|
* @return integer
|
|
|
|
*/
|
|
|
|
ContactList.prototype.count = function() {
|
|
|
|
return Object.keys(this.contacts.contacts).length
|
|
|
|
}
|
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Show/hide contacts belonging to an addressbook.
|
|
|
|
* @param int aid. Addressbook id.
|
|
|
|
* @param boolean show. Whether to show or hide.
|
2012-10-24 20:30:41 +02:00
|
|
|
* @param boolean hideothers. Used when showing shared addressbook as a group.
|
2012-10-05 05:05:49 +02:00
|
|
|
*/
|
2012-10-24 20:30:41 +02:00
|
|
|
ContactList.prototype.showFromAddressbook = function(aid, show, hideothers) {
|
2012-10-05 05:05:49 +02:00
|
|
|
console.log('ContactList.showFromAddressbook', aid, show);
|
2013-03-22 14:49:34 +01:00
|
|
|
aid = String(aid);
|
2012-10-05 05:05:49 +02:00
|
|
|
for(var contact in this.contacts) {
|
2013-03-22 14:49:34 +01:00
|
|
|
if(this.contacts[contact].metadata.parent === aid) {
|
2012-10-24 20:30:41 +02:00
|
|
|
this.contacts[contact].getListItemElement().toggle(show);
|
|
|
|
} else if(hideothers) {
|
|
|
|
this.contacts[contact].getListItemElement().hide();
|
2012-08-02 01:14:50 +02:00
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
}
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:34:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Show/hide contacts belonging to shared addressbooks.
|
|
|
|
* @param boolean show. Whether to show or hide.
|
|
|
|
*/
|
|
|
|
ContactList.prototype.showSharedAddressbooks = function(show) {
|
|
|
|
console.log('ContactList.showSharedAddressbooks', show);
|
|
|
|
for(var contact in this.contacts) {
|
2013-03-22 14:49:34 +01:00
|
|
|
if(this.contacts[contact].metadata.owner !== OC.currentUser) {
|
2012-10-22 15:34:15 +02:00
|
|
|
if(show) {
|
|
|
|
this.contacts[contact].getListItemElement().show();
|
|
|
|
} else {
|
|
|
|
this.contacts[contact].getListItemElement().hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:34:15 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Show contacts in list
|
|
|
|
* @param Array contacts. A list of contact ids.
|
|
|
|
*/
|
|
|
|
ContactList.prototype.showContacts = function(contacts) {
|
2013-03-22 14:49:34 +01:00
|
|
|
console.log('showContacts', contacts);
|
2013-03-23 01:58:18 +01:00
|
|
|
var self = this;
|
2012-11-23 01:20:45 +01:00
|
|
|
if(contacts.length === 0) {
|
|
|
|
// ~5 times faster
|
|
|
|
$('tr:visible.contact').hide();
|
|
|
|
return;
|
|
|
|
}
|
2012-11-27 03:52:59 +01:00
|
|
|
if(contacts === 'all') {
|
|
|
|
// ~2 times faster
|
2013-03-23 01:58:18 +01:00
|
|
|
var $elems = $('tr.contact:not(:visible)');
|
|
|
|
$elems.show();
|
|
|
|
$.each($elems, function(idx, elem) {
|
|
|
|
try {
|
|
|
|
var id = $(elem).data('id');
|
|
|
|
self.contacts[id].setThumbnail();
|
|
|
|
} catch(e) {
|
|
|
|
console.warn('Failed getting id from', $elem, e);
|
|
|
|
}
|
|
|
|
});
|
2012-11-27 03:52:59 +01:00
|
|
|
return;
|
|
|
|
}
|
2013-02-03 15:40:14 +01:00
|
|
|
for(var id in this.contacts) {
|
|
|
|
var contact = this.findById(id);
|
|
|
|
if(contact === null) {
|
|
|
|
continue;
|
|
|
|
}
|
2013-03-22 14:49:34 +01:00
|
|
|
if(contacts.indexOf(String(id)) === -1) {
|
2013-02-03 15:40:14 +01:00
|
|
|
contact.getListItemElement().hide();
|
2012-10-05 05:05:49 +02:00
|
|
|
} else {
|
2013-02-03 15:40:14 +01:00
|
|
|
contact.getListItemElement().show();
|
2013-03-23 01:58:18 +01:00
|
|
|
contact.setThumbnail();
|
2012-08-02 01:14:50 +02:00
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
}
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-06-27 02:10:50 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
ContactList.prototype.contactPos = function(id) {
|
2013-02-03 15:40:14 +01:00
|
|
|
var contact = this.findById(id);
|
|
|
|
if(contact === null) {
|
|
|
|
return 0;
|
2012-10-05 05:05:49 +02:00
|
|
|
}
|
2013-02-03 15:40:14 +01:00
|
|
|
|
|
|
|
var $elem = contact.getListItemElement();
|
2012-10-05 05:05:49 +02:00
|
|
|
var pos = $elem.offset().top - this.$contactList.offset().top + this.$contactList.scrollTop();
|
|
|
|
return pos;
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2012-11-23 01:20:45 +01:00
|
|
|
ContactList.prototype.hideContact = function(id) {
|
2013-02-03 15:40:14 +01:00
|
|
|
var contact = this.findById(id);
|
|
|
|
if(contact === null) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
contact.hide();
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-11-23 01:20:45 +01:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
ContactList.prototype.closeContact = function(id) {
|
2013-02-03 15:40:14 +01:00
|
|
|
var contact = this.findById(id);
|
|
|
|
if(contact === null) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
contact.close();
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Returns a Contact object by searching for its id
|
|
|
|
* @param id the id of the node
|
|
|
|
* @return the Contact object or undefined if not found.
|
|
|
|
* FIXME: If continious loading is reintroduced this will have
|
2012-11-23 01:20:45 +01:00
|
|
|
* to load the requested contact if not in list.
|
2012-10-05 05:05:49 +02:00
|
|
|
*/
|
|
|
|
ContactList.prototype.findById = function(id) {
|
2013-02-03 15:40:14 +01:00
|
|
|
if(!id) {
|
2013-03-30 17:33:58 +01:00
|
|
|
console.warn('ContactList.findById: id missing');
|
2013-02-03 15:40:14 +01:00
|
|
|
console.trace();
|
|
|
|
return false;
|
|
|
|
}
|
2013-03-22 14:49:34 +01:00
|
|
|
id = String(id);
|
2013-02-03 15:40:14 +01:00
|
|
|
if(typeof this.contacts[id] === 'undefined') {
|
|
|
|
console.warn('Could not find contact with id', id);
|
|
|
|
console.trace();
|
|
|
|
return null;
|
|
|
|
}
|
2013-03-22 14:49:34 +01:00
|
|
|
return this.contacts[String(id)];
|
2012-10-05 05:05:49 +02:00
|
|
|
};
|
|
|
|
|
2013-03-28 03:19:01 +01:00
|
|
|
/**
|
|
|
|
* @param object data An object or array of objects containing contact identification
|
|
|
|
* {
|
|
|
|
* contactid: '1234',
|
|
|
|
* addressbookid: '4321',
|
|
|
|
* backend: 'database'
|
|
|
|
* }
|
|
|
|
*/
|
|
|
|
ContactList.prototype.delayedDelete = function(data) {
|
2013-03-30 17:33:58 +01:00
|
|
|
console.log('delayedDelete, data:', typeof data, data);
|
2012-11-15 06:43:22 +01:00
|
|
|
var self = this;
|
2013-03-30 17:33:58 +01:00
|
|
|
if(!utils.isArray(data)) {
|
2012-11-15 00:28:43 +01:00
|
|
|
this.currentContact = null;
|
2013-03-30 17:33:58 +01:00
|
|
|
//self.$contactList.show();
|
2013-04-03 16:54:25 +02:00
|
|
|
if(data instanceof Contact) {
|
|
|
|
this.deletionQueue.push(data);
|
|
|
|
} else {
|
|
|
|
var contact = this.findById(data.contactid);
|
|
|
|
this.deletionQueue.push(contact);
|
|
|
|
}
|
2013-03-28 03:19:01 +01:00
|
|
|
} else if(utils.isArray(data)) {
|
2013-03-30 17:33:58 +01:00
|
|
|
$.each(data, function(idx, contact) {
|
|
|
|
console.log('delayedDelete, meta:', contact);
|
|
|
|
self.deletionQueue.push(contact);
|
|
|
|
});
|
|
|
|
//$.extend(this.deletionQueue, data);
|
2012-11-15 00:28:43 +01:00
|
|
|
} else {
|
2013-03-28 03:19:01 +01:00
|
|
|
throw { name: 'WrongParameterType', message: 'ContactList.delayedDelete only accept objects or arrays.'};
|
2012-11-15 00:28:43 +01:00
|
|
|
}
|
2013-03-30 17:33:58 +01:00
|
|
|
console.log('delayedDelete, deletionQueue', this.deletionQueue);
|
2013-03-28 03:19:01 +01:00
|
|
|
$.each(this.deletionQueue, function(idx, contact) {
|
2013-03-30 17:33:58 +01:00
|
|
|
console.log('delayedDelete', contact);
|
|
|
|
contact.detach().setChecked(false);
|
2012-11-15 06:43:22 +01:00
|
|
|
});
|
2012-11-15 00:28:43 +01:00
|
|
|
console.log('deletionQueue', this.deletionQueue);
|
2012-10-05 05:05:49 +02:00
|
|
|
if(!window.onbeforeunload) {
|
2012-11-16 04:39:57 +01:00
|
|
|
window.onbeforeunload = function(e) {
|
|
|
|
e = e || window.event;
|
|
|
|
var warn = t('contacts', 'Some contacts are marked for deletion, but not deleted yet. Please wait for them to be deleted.');
|
|
|
|
if (e) {
|
|
|
|
e.returnValue = String(warn);
|
|
|
|
}
|
|
|
|
return warn;
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-05 05:05:49 +02:00
|
|
|
}
|
|
|
|
if(this.$contactList.find('tr:visible').length === 0) {
|
|
|
|
$(document).trigger('status.visiblecontacts');
|
|
|
|
}
|
|
|
|
OC.notify({
|
2012-11-15 00:28:43 +01:00
|
|
|
message:t('contacts','Click to undo deletion of {num} contacts', {num: self.deletionQueue.length}),
|
2012-10-05 05:05:49 +02:00
|
|
|
//timeout:5,
|
2012-11-15 06:43:22 +01:00
|
|
|
timeouthandler:function() {
|
2012-11-15 00:28:43 +01:00
|
|
|
console.log('timeout');
|
2012-11-15 06:43:22 +01:00
|
|
|
// Don't fire all deletes at once
|
2012-12-22 01:50:27 +01:00
|
|
|
self.deletionTimer = setInterval(function() {
|
|
|
|
self.deleteContacts();
|
|
|
|
}, 500);
|
2012-10-05 05:05:49 +02:00
|
|
|
},
|
2012-11-15 06:43:22 +01:00
|
|
|
clickhandler:function() {
|
2012-11-15 00:28:43 +01:00
|
|
|
console.log('clickhandler');
|
2013-03-28 03:19:01 +01:00
|
|
|
$.each(self.deletionQueue, function(idx, contact) {
|
2013-03-30 17:33:58 +01:00
|
|
|
self.insertContact(contact.getListItemElement());
|
2012-11-15 06:43:22 +01:00
|
|
|
});
|
2012-11-15 00:28:43 +01:00
|
|
|
OC.notify({cancel:true});
|
|
|
|
OC.notify({message:t('contacts', 'Cancelled deletion of {num}', {num: self.deletionQueue.length})});
|
|
|
|
self.deletionQueue = [];
|
2012-10-05 05:05:49 +02:00
|
|
|
window.onbeforeunload = null;
|
2012-06-27 02:10:50 +02:00
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
});
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-05 05:05:49 +02:00
|
|
|
|
|
|
|
/**
|
2013-03-28 03:19:01 +01:00
|
|
|
* Delete contacts in the queue
|
2012-10-05 05:05:49 +02:00
|
|
|
*/
|
2012-11-15 00:28:43 +01:00
|
|
|
ContactList.prototype.deleteContacts = function() {
|
2012-10-05 05:05:49 +02:00
|
|
|
var self = this;
|
2012-11-15 00:28:43 +01:00
|
|
|
console.log('ContactList.deleteContacts, deletionQueue', this.deletionQueue);
|
2012-11-15 06:43:22 +01:00
|
|
|
if(typeof this.deletionTimer === 'undefined') {
|
|
|
|
console.log('No deletion timer!');
|
|
|
|
window.onbeforeunload = null;
|
|
|
|
return;
|
2012-10-05 05:05:49 +02:00
|
|
|
}
|
|
|
|
|
2013-03-30 17:33:58 +01:00
|
|
|
var contact = this.deletionQueue.shift();
|
|
|
|
if(typeof contact === 'undefined') {
|
2012-11-15 06:43:22 +01:00
|
|
|
clearInterval(this.deletionTimer);
|
|
|
|
delete this.deletionTimer;
|
|
|
|
window.onbeforeunload = null;
|
|
|
|
return;
|
|
|
|
}
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2012-11-15 06:43:22 +01:00
|
|
|
// Let contact remove itself.
|
2013-03-30 17:33:58 +01:00
|
|
|
var id = contact.getId();
|
2013-02-03 15:40:14 +01:00
|
|
|
contact.destroy(function(response) {
|
2013-02-16 23:00:11 +01:00
|
|
|
console.log('deleteContact', response, self.length);
|
2013-03-28 03:19:01 +01:00
|
|
|
if(!response.error) {
|
2013-03-30 17:33:58 +01:00
|
|
|
delete self.contacts[id];
|
2012-11-15 06:43:22 +01:00
|
|
|
$(document).trigger('status.contact.deleted', {
|
2013-03-30 17:33:58 +01:00
|
|
|
id: id
|
2012-11-15 06:43:22 +01:00
|
|
|
});
|
|
|
|
self.length -= 1;
|
|
|
|
if(self.length === 0) {
|
|
|
|
$(document).trigger('status.nomorecontacts');
|
2012-10-05 05:05:49 +02:00
|
|
|
}
|
2012-11-15 06:43:22 +01:00
|
|
|
} else {
|
|
|
|
OC.notify({message:response.message});
|
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
});
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Opens the contact with this id in edit mode
|
|
|
|
* @param id the id of the contact
|
2012-10-30 07:06:37 +01:00
|
|
|
* @returns A jquery object to be inserted in the DOM.
|
2012-10-05 05:05:49 +02:00
|
|
|
*/
|
2012-12-10 00:02:06 +01:00
|
|
|
ContactList.prototype.showContact = function(id, props) {
|
2013-02-03 15:40:14 +01:00
|
|
|
var contact = this.findById(id);
|
|
|
|
if(contact === null) {
|
|
|
|
return false;
|
|
|
|
}
|
2012-11-15 00:28:43 +01:00
|
|
|
this.currentContact = id;
|
2013-02-03 15:40:14 +01:00
|
|
|
console.log('Contacts.showContact', id, contact, this.contacts);
|
|
|
|
return contact.renderContact(props);
|
2012-10-05 05:05:49 +02:00
|
|
|
};
|
2012-07-22 14:58:57 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Insert a rendered contact list item into the list
|
|
|
|
* @param contact jQuery object.
|
|
|
|
*/
|
2012-11-13 22:42:55 +01:00
|
|
|
ContactList.prototype.insertContact = function($contact) {
|
2013-03-12 00:28:41 +01:00
|
|
|
$contact.find('td.name').draggable({
|
2012-11-13 22:42:55 +01:00
|
|
|
distance: 10,
|
|
|
|
revert: 'invalid',
|
|
|
|
//containment: '#content',
|
2013-03-12 00:28:41 +01:00
|
|
|
helper: function (e,ui) {
|
|
|
|
return $(this).clone().appendTo('body').css('zIndex', 5).show();
|
|
|
|
},
|
|
|
|
opacity: 0.8,
|
|
|
|
scope: 'contacts'
|
2012-11-13 22:42:55 +01:00
|
|
|
});
|
|
|
|
var name = $contact.find('.nametext').text().toLowerCase();
|
2012-12-17 15:19:22 +01:00
|
|
|
var added = false;
|
2012-10-05 05:05:49 +02:00
|
|
|
this.$contactList.find('tr').each(function() {
|
2012-11-13 22:42:55 +01:00
|
|
|
if ($(this).find('.nametext').text().toLowerCase().localeCompare(name) > 0) {
|
|
|
|
$(this).before($contact);
|
2012-10-05 05:05:49 +02:00
|
|
|
added = true;
|
2012-08-16 00:24:38 +02:00
|
|
|
return false;
|
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
});
|
|
|
|
if(!added) {
|
2012-11-13 22:42:55 +01:00
|
|
|
this.$contactList.append($contact);
|
2012-02-06 07:32:57 +01:00
|
|
|
}
|
2012-11-13 22:42:55 +01:00
|
|
|
$contact.show();
|
|
|
|
return $contact;
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Add contact
|
2012-12-10 00:09:51 +01:00
|
|
|
* @param object props
|
2012-10-05 05:05:49 +02:00
|
|
|
*/
|
2012-12-10 00:09:51 +01:00
|
|
|
ContactList.prototype.addContact = function(props) {
|
2013-03-25 17:08:47 +01:00
|
|
|
var addressBook = this.addressbooks[Object.keys(this.addressbooks)[0]]
|
|
|
|
var metadata = {
|
|
|
|
parent: addressBook.id,
|
|
|
|
backend: addressBook.backend,
|
|
|
|
permissions: addressBook.permissions,
|
|
|
|
owner: addressBook.owner
|
|
|
|
};
|
2012-10-05 05:05:49 +02:00
|
|
|
var contact = new Contact(
|
2012-10-22 15:32:32 +02:00
|
|
|
this,
|
|
|
|
null,
|
2013-03-25 17:08:47 +01:00
|
|
|
metadata,
|
2012-10-05 05:05:49 +02:00
|
|
|
null,
|
2012-10-22 15:32:32 +02:00
|
|
|
this.$contactListItemTemplate,
|
2013-03-12 00:28:41 +01:00
|
|
|
this.$contactDragItemTemplate,
|
2012-10-05 05:05:49 +02:00
|
|
|
this.$contactFullTemplate,
|
|
|
|
this.contactDetailTemplates
|
|
|
|
);
|
2013-03-04 17:57:46 +01:00
|
|
|
if(utils.isUInt(this.currentContact)) {
|
2012-11-15 00:28:43 +01:00
|
|
|
console.assert(typeof this.currentContact == 'number', 'this.currentContact is not a number');
|
2012-10-05 05:05:49 +02:00
|
|
|
this.contacts[this.currentContact].close();
|
2012-05-03 11:11:26 +02:00
|
|
|
}
|
2012-12-10 00:09:51 +01:00
|
|
|
return contact.renderContact(props);
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2012-10-30 07:06:37 +01:00
|
|
|
/**
|
|
|
|
* Get contacts selected in list
|
|
|
|
*
|
2013-03-25 17:08:47 +01:00
|
|
|
* @returns array of contact ids.
|
2012-10-30 07:06:37 +01:00
|
|
|
*/
|
2012-10-05 05:05:49 +02:00
|
|
|
ContactList.prototype.getSelectedContacts = function() {
|
|
|
|
var contacts = [];
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2013-03-30 17:33:58 +01:00
|
|
|
var self = this;
|
2012-10-05 05:05:49 +02:00
|
|
|
$.each(this.$contactList.find('tr > td > input:checkbox:visible:checked'), function(a, b) {
|
2013-03-30 17:33:58 +01:00
|
|
|
var id = String($(b).parents('tr').first().data('id'));
|
|
|
|
contacts.push(self.contacts[id]);
|
2012-10-05 05:05:49 +02:00
|
|
|
});
|
|
|
|
return contacts;
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
ContactList.prototype.setCurrent = function(id, deselect_other) {
|
2013-02-24 02:48:43 +01:00
|
|
|
console.log('ContactList.setCurrent', id);
|
2013-01-02 01:14:09 +01:00
|
|
|
if(!id) {
|
|
|
|
return;
|
|
|
|
}
|
2012-12-20 22:59:34 +01:00
|
|
|
var self = this;
|
2012-10-05 05:05:49 +02:00
|
|
|
if(deselect_other === true) {
|
|
|
|
$.each(this.contacts, function(contact) {
|
|
|
|
self.contacts[contact].setCurrent(false);
|
2012-05-10 20:43:40 +02:00
|
|
|
});
|
|
|
|
}
|
2013-03-22 14:49:34 +01:00
|
|
|
this.contacts[String(id)].setCurrent(true);
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
// Should only be neccesary with progressive loading, but it's damn fast, so... ;)
|
|
|
|
ContactList.prototype.doSort = function() {
|
|
|
|
var self = this;
|
|
|
|
var rows = this.$contactList.find('tr').get();
|
2012-02-06 07:32:57 +01:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
rows.sort(function(a, b) {
|
2012-10-30 07:08:00 +01:00
|
|
|
return $(a).find('td.name').text().toUpperCase().localeCompare($(b).find('td.name').text().toUpperCase());
|
2012-10-05 05:05:49 +02:00
|
|
|
});
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2013-03-25 17:08:47 +01:00
|
|
|
// TODO: Test if I couldn't just append rows.
|
2012-12-21 23:46:59 +01:00
|
|
|
var items = [];
|
2012-10-05 05:05:49 +02:00
|
|
|
$.each(rows, function(index, row) {
|
2012-12-21 23:46:59 +01:00
|
|
|
items.push(row);
|
|
|
|
if(items.length === 100) {
|
|
|
|
self.$contactList.append(items);
|
|
|
|
items = [];
|
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
});
|
2012-12-21 23:46:59 +01:00
|
|
|
if(items.length > 0) {
|
|
|
|
self.$contactList.append(items);
|
|
|
|
}
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2012-10-22 15:32:32 +02:00
|
|
|
|
2012-12-07 14:59:28 +01:00
|
|
|
/**
|
|
|
|
* Save addressbook data
|
|
|
|
* @param int id
|
|
|
|
*/
|
|
|
|
ContactList.prototype.unsetAddressbook = function(id) {
|
|
|
|
delete this.addressbooks[id];
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
|
|
|
|
2012-12-07 14:59:28 +01:00
|
|
|
/**
|
|
|
|
* Save addressbook data
|
|
|
|
* @param object book
|
|
|
|
*/
|
|
|
|
ContactList.prototype.setAddressbook = function(book) {
|
2013-03-22 14:49:34 +01:00
|
|
|
console.log('setAddressbook', book.id, this.addressbooks);
|
|
|
|
var id = String(book.id);
|
2013-03-25 17:08:47 +01:00
|
|
|
this.addressbooks[id] = book;
|
2012-12-17 15:19:22 +01:00
|
|
|
};
|
2013-03-22 14:49:34 +01:00
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
/**
|
|
|
|
* Load contacts
|
|
|
|
* @param int offset
|
|
|
|
*/
|
2013-03-22 14:49:34 +01:00
|
|
|
ContactList.prototype.getAddressBooks = function() {
|
2012-10-05 05:05:49 +02:00
|
|
|
var self = this;
|
2013-03-25 17:08:47 +01:00
|
|
|
$.when(this.storage.getAddressBooksForUser()).then(function(response) {
|
2013-03-28 03:19:01 +01:00
|
|
|
console.log('ContactList.getAddressBooks', response);
|
|
|
|
if(!response.error) {
|
|
|
|
var num = response.data.addressbooks.length;
|
|
|
|
$.each(response.data.addressbooks, function(idx, addressBook) {
|
|
|
|
self.setAddressbook(addressBook);
|
|
|
|
self.loadContacts(
|
|
|
|
addressBook['backend'],
|
|
|
|
addressBook['id'],
|
|
|
|
function(cbresponse) {
|
|
|
|
console.log('loaded', idx, cbresponse);
|
|
|
|
num -= 1;
|
2013-03-30 07:25:02 +01:00
|
|
|
if(num === 0) {
|
|
|
|
if(self.length > 0) {
|
|
|
|
setTimeout(function() {
|
|
|
|
self.doSort(); // TODO: Test this
|
|
|
|
self.setCurrent(self.$contactList.find('tr:visible').first().data('id'), false);
|
|
|
|
}
|
|
|
|
, 2000);
|
|
|
|
}
|
|
|
|
$(document).trigger('status.contacts.loaded', {
|
|
|
|
status: true,
|
2013-04-01 03:50:42 +02:00
|
|
|
numcontacts: self.length
|
2013-03-30 07:25:02 +01:00
|
|
|
});
|
|
|
|
if(self.length === 0) {
|
|
|
|
$(document).trigger('status.nomorecontacts');
|
2013-03-28 03:19:01 +01:00
|
|
|
}
|
2013-03-22 14:49:34 +01:00
|
|
|
}
|
2013-03-28 03:19:01 +01:00
|
|
|
if(cbresponse.error) {
|
|
|
|
$(document).trigger('status.contact.error', {
|
|
|
|
message:
|
|
|
|
t('contacts', 'Failed loading contacts from {addressbook}: {error}',
|
|
|
|
{addressbook:addressBook['displayname'], error:err})
|
|
|
|
});
|
2013-03-25 17:08:47 +01:00
|
|
|
}
|
2013-03-28 03:19:01 +01:00
|
|
|
});
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
$(document).trigger('status.contact.error', {
|
|
|
|
message: response.message
|
|
|
|
});
|
|
|
|
return false;
|
|
|
|
}
|
2013-03-25 17:08:47 +01:00
|
|
|
})
|
|
|
|
.fail(function(jqxhr, textStatus, error) {
|
|
|
|
var err = textStatus + ', ' + error;
|
|
|
|
console.log( "Request Failed: " + err);
|
|
|
|
$(document).trigger('status.contact.error', {
|
|
|
|
message: t('contacts', 'Failed loading address books: {error}', {error:err})
|
|
|
|
});
|
|
|
|
});
|
2013-03-22 14:49:34 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Load contacts
|
|
|
|
* @param int offset
|
|
|
|
*/
|
|
|
|
ContactList.prototype.loadContacts = function(backend, addressBookId, cb) {
|
|
|
|
var self = this;
|
2013-03-25 17:08:47 +01:00
|
|
|
$.when(this.storage.getContacts(backend, addressBookId)).then(function(response) {
|
2013-03-28 03:19:01 +01:00
|
|
|
console.log('ContactList.loadContacts', response);
|
|
|
|
if(!response.error) {
|
|
|
|
var items = [];
|
|
|
|
$.each(response.data.contacts, function(c, contact) {
|
|
|
|
var id = String(contact.metadata.id);
|
|
|
|
contact.metadata.backend = backend;
|
|
|
|
self.contacts[id]
|
|
|
|
= new Contact(
|
|
|
|
self,
|
|
|
|
id,
|
|
|
|
contact.metadata,
|
|
|
|
contact.data,
|
|
|
|
self.$contactListItemTemplate,
|
|
|
|
self.$contactDragItemTemplate,
|
|
|
|
self.$contactFullTemplate,
|
|
|
|
self.contactDetailTemplates
|
|
|
|
);
|
|
|
|
self.length +=1;
|
|
|
|
var $item = self.contacts[id].renderListItem();
|
|
|
|
items.push($item.get(0));
|
|
|
|
$item.find('td.name').draggable({
|
|
|
|
cursor: 'move',
|
|
|
|
distance: 10,
|
|
|
|
revert: 'invalid',
|
|
|
|
helper: function (e,ui) {
|
|
|
|
return self.contacts[id].renderDragItem().appendTo('body');
|
|
|
|
},
|
|
|
|
opacity: 1,
|
|
|
|
scope: 'contacts'
|
|
|
|
});
|
|
|
|
if(items.length === 100) {
|
|
|
|
self.$contactList.append(items);
|
|
|
|
items = [];
|
|
|
|
}
|
2012-10-05 05:05:49 +02:00
|
|
|
});
|
2013-03-28 03:19:01 +01:00
|
|
|
if(items.length > 0) {
|
2012-12-21 23:46:59 +01:00
|
|
|
self.$contactList.append(items);
|
|
|
|
}
|
2013-03-28 03:19:01 +01:00
|
|
|
cb({error:false});
|
|
|
|
} else {
|
|
|
|
$(document).trigger('status.contact.error', {
|
|
|
|
message: response.message
|
|
|
|
});
|
|
|
|
cb({
|
|
|
|
error:true,
|
|
|
|
message: response.message
|
|
|
|
});
|
2013-03-25 17:08:47 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.fail(function(jqxhr, textStatus, error) {
|
|
|
|
var err = textStatus + ', ' + error;
|
|
|
|
console.log( "Request Failed: " + err);
|
2013-03-28 03:19:01 +01:00
|
|
|
cb({error: true, message: err});
|
2013-03-25 17:08:47 +01:00
|
|
|
});
|
2013-03-22 14:49:34 +01:00
|
|
|
};
|
|
|
|
|
2012-10-05 05:05:49 +02:00
|
|
|
OC.Contacts.ContactList = ContactList;
|
2012-07-21 14:26:26 +02:00
|
|
|
|
2012-12-11 02:28:22 +01:00
|
|
|
})(window, jQuery, OC);
|