summaryrefslogtreecommitdiffstats
path: root/src/store
diff options
context:
space:
mode:
authorJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>2018-09-28 12:44:09 +0200
committerJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>2018-09-28 12:44:09 +0200
commit1d47e704b1db4abe38c8f4ccdaed7474a972a2a8 (patch)
tree6b104504799cb009c79e0472b15b802df7b77923 /src/store
parent2f63616f5d43253f491e77ecdb7dabcbf220367f (diff)
Conflict management
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
Diffstat (limited to 'src/store')
-rw-r--r--src/store/addressbooks.js5
-rw-r--r--src/store/contacts.js56
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)
})