summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>2018-09-27 15:39:12 +0200
committerJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>2018-09-27 15:39:12 +0200
commit5501624f8f45c9427c1942c8674df7a38ed516cd (patch)
tree3a754359117c269c955ace8caec4fe96f6f7a480 /src
parentcf8ff271a418055ddd83e9859cd0e64bd454535d (diff)
Fix import and push vCards to the server
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/components/ImportScreen.vue33
-rw-r--r--src/services/parseVcf.js6
-rw-r--r--src/store/addressbooks.js43
-rw-r--r--src/store/importState.js5
4 files changed, 73 insertions, 14 deletions
diff --git a/src/components/ImportScreen.vue b/src/components/ImportScreen.vue
index bb903442..b58182fa 100644
--- a/src/components/ImportScreen.vue
+++ b/src/components/ImportScreen.vue
@@ -23,19 +23,46 @@
<template>
<div class="emptycontent import-screen">
<p class="icon-upload" />
- <h3 class="import-screen__header">{{ t('contacts', 'Importing into') }} {{ importState.addressbook }}</h3>
- <progress :max="importState.total" :value="importState.accepted" class="import-screen__progress" />
- <p class="import-screen__tracker">{{ Math.floor(importState.accepted/(importState.total + 1)) * 100 }} %</p>
+ <h3 class="import-screen__header">{{ t('contacts', 'Importing {total} contacts into', { total }) }} {{ addressbook }}</h3>
+ <progress :max="total" :value="progress" class="import-screen__progress" />
+ <p class="import-screen__tracker">
+ <span>{{ percentage }} %</span>
+ <span v-tooltip.auto="t('contacts', 'Open your browser console for more details')">{{ denied }} {{ t('contacts', 'failed') }}</span>
+ </p>
</div>
</template>
<script>
+import Vue from 'vue'
+import VTooltip from 'v-tooltip'
+
+Vue.use(VTooltip)
export default {
name: 'ImportScreen',
computed: {
importState() {
return this.$store.getters.getImportState
+ },
+ addressbook() {
+ return this.importState.addressbook
+ },
+ total() {
+ return this.importState.total
+ },
+ accepted() {
+ return this.importState.accepted
+ },
+ denied() {
+ return this.importState.denied
+ },
+ progress() {
+ return this.accepted + this.denied
+ },
+ percentage() {
+ return this.total <= 0
+ ? 0
+ : Math.floor(this.progress / this.total * 100)
}
}
}
diff --git a/src/services/parseVcf.js b/src/services/parseVcf.js
index 65d5f95c..11b1fc49 100644
--- a/src/services/parseVcf.js
+++ b/src/services/parseVcf.js
@@ -26,14 +26,13 @@ import Store from '../store/index'
export default function parseVcf(data = '', addressbook) {
let regexp = /BEGIN:VCARD[\s\S]*?END:VCARD/mgi
let vCards = data.match(regexp)
- let importState = Store.getters.getImportState
if (!vCards) {
console.debug('Error during the parsing of the following vcf file: ', data)
return []
}
- importState.total = vCards.length
+ Store.dispatch('setTotal', vCards.length)
// Not using map because we want to only push valid contacts
// map force to return at least undefined
@@ -41,11 +40,10 @@ export default function parseVcf(data = '', addressbook) {
try {
// console.log(vCards.indexOf(vCard))
let contact = new Contact(vCard, addressbook)
- importState.accepted++
contacts.push(contact)
} catch (e) {
// Parse error! Do not stop here...
- importState.denied++
+ Store.dispatch('incrementDenied')
console.error(e)
}
return contacts
diff --git a/src/store/addressbooks.js b/src/store/addressbooks.js
index 74a47bef..185a6465 100644
--- a/src/store/addressbooks.js
+++ b/src/store/addressbooks.js
@@ -22,9 +22,11 @@
*/
import Vue from 'vue'
+import ICAL from 'ical.js'
import parseVcf from '../services/parseVcf'
import client from '../services/cdav'
import Contact from '../models/contact'
+import pLimit from 'p-limit'
const addressbookModel = {
id: '',
@@ -327,15 +329,42 @@ const actions = {
* @param {Object} context the store mutations
* @param {Object} importDetails = { vcf, addressbook }
*/
- importContactsIntoAddressbook(context, { vcf, addressbook }) {
- let contacts = parseVcf(vcf, addressbook)
+ async importContactsIntoAddressbook(context, { vcf, addressbook }) {
+ const contacts = parseVcf(vcf, addressbook)
context.commit('changeStage', 'importing')
- contacts.forEach(contact => {
- context.commit('addContact', contact)
- context.commit('addContactToAddressbook', contact)
- context.commit('appendGroupsFromContacts', [contact])
+
+ // max simultaneous requests
+ const limit = pLimit(3)
+ const requests = []
+
+ // create the array of requests to send
+ contacts.map(async contact => {
+ // Get vcard string
+ try {
+ let vData = ICAL.stringify(contact.vCard.jCal)
+ // push contact to server and use limit
+ requests.push(limit(() => contact.addressbook.dav.createVCard(vData)
+ .then((response) => {
+ // success, update store
+ context.commit('addContact', contact)
+ context.commit('addContactToAddressbook', contact)
+ context.commit('appendGroupsFromContacts', [contact])
+ context.commit('incrementAccepted')
+ })
+ .catch((error) => {
+ // error
+ context.commit('incrementDenied')
+ console.error(error)
+ })
+ ))
+ } catch (e) {
+ context.commit('incrementDenied')
+ }
+ })
+
+ Promise.all(requests).then(() => {
+ // context.commit('changeStage', 'default')
})
- context.commit('changeStage', 'default')
},
/**
diff --git a/src/store/importState.js b/src/store/importState.js
index 024b0ac0..313c8d6d 100644
--- a/src/store/importState.js
+++ b/src/store/importState.js
@@ -77,6 +77,11 @@ const mutations = {
*/
changeStage(state, stage) {
state.importState.stage = stage
+ if (stage === 'default') {
+ state.accepted = 0
+ state.denied = 0
+ state.total = 0
+ }
}
}