diff options
author | John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> | 2018-09-28 12:44:09 +0200 |
---|---|---|
committer | John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> | 2018-09-28 12:44:09 +0200 |
commit | 1d47e704b1db4abe38c8f4ccdaed7474a972a2a8 (patch) | |
tree | 6b104504799cb009c79e0472b15b802df7b77923 /src/store | |
parent | 2f63616f5d43253f491e77ecdb7dabcbf220367f (diff) |
Conflict management
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
Diffstat (limited to 'src/store')
-rw-r--r-- | src/store/addressbooks.js | 5 | ||||
-rw-r--r-- | src/store/contacts.js | 56 |
2 files changed, 50 insertions, 11 deletions
diff --git a/src/store/addressbooks.js b/src/store/addressbooks.js index d6ca8a1d..b7828f4b 100644 --- a/src/store/addressbooks.js +++ b/src/store/addressbooks.js @@ -306,7 +306,7 @@ const actions = { // so we need to parse one by one const contacts = response.map(item => { let contact = new Contact(item.data, addressbook, item.url, item.etag) - contact.dav = item + Vue.set(contact, 'dav', item) return contact }) context.commit('appendContactsToAddressbook', { addressbook, contacts }) @@ -345,6 +345,9 @@ const actions = { // push contact to server and use limit requests.push(limit(() => contact.addressbook.dav.createVCard(vData) .then((response) => { + // setting the contact dav property + Vue.set(contact, 'dav', response) + // success, update store context.commit('addContact', contact) context.commit('addContactToAddressbook', contact) diff --git a/src/store/contacts.js b/src/store/contacts.js index aa0805f0..60e2c6bf 100644 --- a/src/store/contacts.js +++ b/src/store/contacts.js @@ -38,7 +38,7 @@ const mutations = { * Store contacts into state * * @param {Object} state Default state - * @param {Array} contacts Contacts + * @param {Array<Contact>} contacts Contacts */ appendContacts(state, contacts = []) { state.contacts = contacts.reduce(function(list, contact) { @@ -143,14 +143,15 @@ const mutations = { }, /** - * Update a contact + * Update a contact addressbook * * @param {Object} state the store data + * @param {Object} data destructuring object * @param {Contact} contact the contact to update + * @param {Object} addressbook the addressbook to set */ updateContactAddressbook(state, { contact, addressbook }) { if (state.contacts[contact.key] && contact instanceof Contact) { - // replace contact object data state.contacts[contact.key].updateAddressbook(addressbook) @@ -160,6 +161,24 @@ const mutations = { }, /** + * Update a contact etag + * + * @param {Object} state the store data + * @param {Object} data destructuring object + * @param {Contact} contact the contact to update + * @param {string} etag the contact etag + */ + updateContactEtag(state, { contact, etag }) { + if (state.contacts[contact.key] && contact instanceof Contact) { + // replace contact object data + state.contacts[contact.key].dav.etag = etag + + } else { + console.error('Error while replacing the etag of following contact', contact) + } + }, + + /** * Order the contacts list. Filters have terrible performances. * We do not want to run the sorting function every time. * Let's only run it on additions and create an index @@ -254,22 +273,39 @@ const actions = { .catch((error) => { throw error }) } - contact.dav.data = vData - return contact.dav.update() - .then((response) => context.commit('updateContact', contact)) - .catch((error) => { throw error }) + if (!contact.conflict) { + contact.dav.data = vData + return contact.dav.update() + .then((response) => { + // wrong etag, we most likely have a conflict + if (response.status === 412) { + contact.conflict = response.xhr.getResponseHeader('etag') + } else { + // all clear, let's update the store + context.commit('updateContact', contact) + } + }) + .catch((error) => { throw error }) + } else { + console.error('This contact is outdated, refusing to push', contact) + } }, /** * Fetch the full vCard from the dav server * * @param {Object} context the store mutations - * @param {Contact} contact the contact to fetch + * @param {Object} data destructuring object + * @param {Contact} data.contact the contact to fetch + * @param {string} data.etag the contact etag * @returns {Promise} */ - async fetchFullContact(context, contact) { + async fetchFullContact(context, { contact, etag = '' }) { + if (etag !== '') { + await context.commit('updateContactEtag', { contact, etag }) + } return contact.dav.fetchCompleteData() - .then(() => { + .then((response) => { let newContact = new Contact(contact.dav.data, contact.addressbook, contact.dav.url, contact.dav.etag) context.commit('updateContact', newContact) }) |