VulpesOS/gaia/shared/js/contacts/multi_contact.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

182 lines
4.9 KiB
JavaScript
Executable file

'use strict';
/* exported MultiContact */
/* globals Promise, LazyLoader, contacts */
// ATTENTION: This library lazy loads contacts_merger.js
var MultiContact = (function() {
var datastores = Object.create(null);
var datastoresLoading = false;
var DS_READY_EVENT = 'ds_ready';
var MOZ_CONTACTS_OWNER = 'app://communications.gaiamobile.org';
function getDatastore(owner) {
if (datastores[owner]) {
return Promise.resolve(datastores[owner]);
}
return new Promise(function(resolve, reject) {
if (datastoresLoading === true) {
document.addEventListener(DS_READY_EVENT, function handler() {
document.removeEventListener(DS_READY_EVENT, handler);
resolve(datastores[owner]);
});
}
else {
datastoresLoading = true;
navigator.getDataStores('contacts').then(function success(dsList) {
dsList.forEach(function(aDs) {
datastores[aDs.owner] = aDs;
});
// This is needed because mozContact DB is not exposed as a Datastore
// Once bug 1016838 lands this will not be needed
datastores[MOZ_CONTACTS_OWNER] = new MozContactsDatastore();
resolve(datastores[owner]);
datastoresLoading = false;
document.dispatchEvent(new CustomEvent(DS_READY_EVENT));
}, function err(error) {
console.error('Error while obtaining datastores: ', error.name);
});
}
});
}
// Adapter object to obtain data from the mozContacts as if it were a DS
// Once bug 1016838 lands this will not be needed
function MozContactsDatastore() {
}
MozContactsDatastore.prototype = {
get: function(id) {
return new Promise(function(resolve, reject) {
var options = {
filterBy: ['id'],
filterOp: 'equals',
filterValue: id
};
var req = navigator.mozContacts.find(options);
req.onsuccess = function() {
resolve(JSON.parse(JSON.stringify(req.result[0])));
};
req.onerror = function() {
reject(req.error);
};
});
},
get name() {
return 'mozContacts';
}
};
function getData(entry) {
if (!entry || !entry.id || !Array.isArray(entry.entryData)) {
return Promise.reject({
name: 'InvalidEntry'
});
}
return new Promise(function(resolve, reject) {
var operations = [];
var entryData = entry.entryData;
var mozContactId;
entryData.forEach(function fetchEntry(aEntry) {
var owner = aEntry.origin;
if (owner === MOZ_CONTACTS_OWNER) {
mozContactId = aEntry.uid;
}
getDatastore(owner).then(function success(datastore) {
operations.push(datastore.get(aEntry.uid));
// It is needed to wait to have all operations ready
if (operations.length === entryData.length) {
execute(operations, resolve, reject, {
targetId: entry.id,
mozContactId: mozContactId
});
}
}, function error(err) {
console.error('Error while obtaining datastore: ', err.name);
reject(err);
});
});
});
}
function execute(operations, resolve, reject, options) {
Promise.all(operations).then(function success(results) {
if (results.length === 1) {
results[0].id = options.targetId;
resolve(results[0]);
return;
}
if (options.mozContactId) {
results = reorderResults(results, options.mozContactId);
}
LazyLoader.load('/shared/js/contacts/contacts_merger.js',
function() {
var matchings = createMatchingContacts(results);
contacts.Merger.inMemoryMerge(results[0], matchings).then(
function success(mergedResult) {
mergedResult.id = options.targetId;
resolve(mergedResult);
}, function error(err) {
console.log('Error while merging: ', err);
reject(err);
});
});
}, function error(err) {
console.error('Error while getting data: ', err.name);
reject(err);
});
}
// This function reorders the contact data results array in order to
// put the mozContact in the first position, as mozContact data will be taken
// precedence over other datastore data
function reorderResults(results, mozContactId) {
var out = [];
for (var j = 0; j < results.length; j++) {
if (results[j].id === mozContactId) {
out.unshift(results[j]);
}
else {
out.push(results[j]);
}
}
return out;
}
// This function adapts the result array to the input object expected by
// the contacts_merger module
function createMatchingContacts(results) {
var out = [];
for (var j = 1; j < results.length; j++) {
out.push({
matchingContact: results[j]
});
}
return out;
}
return {
'getData': getData
};
})();