summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>2019-05-16 17:04:43 +0200
committerJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>2019-05-16 17:04:43 +0200
commitf6b7dc45acd690225b92ceed8dc688263cae8958 (patch)
tree90a851a56ade7cbc449f99c857402cb2f1a6ba6c
parent5c0dd7d7d6d0f6f461dd909d399e31f4cc662819 (diff)
Fix avatar errors, and migrate settings menu to Actions
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
-rw-r--r--css/ContactDetailsAvatar.scss2
-rw-r--r--package-lock.json10
-rw-r--r--package.json2
-rw-r--r--src/components/ContactDetails/ContactDetailsAvatar.vue6
-rw-r--r--src/components/Settings/SettingsAddressbook.vue240
-rw-r--r--webpack.common.js2
6 files changed, 133 insertions, 129 deletions
diff --git a/css/ContactDetailsAvatar.scss b/css/ContactDetailsAvatar.scss
index f86c1709..6ec6cfe8 100644
--- a/css/ContactDetailsAvatar.scss
+++ b/css/ContactDetailsAvatar.scss
@@ -76,7 +76,7 @@
&__popovermenu {
// center
margin: calc((100% - 44px) / 2);
- & /deep/ .action-item__menutoggle {
+ & .action-item__menutoggle {
// hide three dot menu, in favour of icon-picture-force-white
z-index: -1;
&::before {
diff --git a/package-lock.json b/package-lock.json
index 67eed9d2..28987fff 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2319,8 +2319,8 @@
"dev": true
},
"cdav-library": {
- "version": "github:nextcloud/cdav-library#18b38778637386424dff1acf7f9a41b4ca757721",
- "from": "github:nextcloud/cdav-library#18b38778637386424dff1acf7f9a41b4ca757721",
+ "version": "github:nextcloud/cdav-library#3e3fae357ccbc427d6e44df9cd572285caa71d9c",
+ "from": "github:nextcloud/cdav-library",
"requires": {
"@babel/polyfill": "^7.4.4"
}
@@ -7015,9 +7015,9 @@
}
},
"nextcloud-vue": {
- "version": "0.11.1",
- "resolved": "https://registry.npmjs.org/nextcloud-vue/-/nextcloud-vue-0.11.1.tgz",
- "integrity": "sha512-gQnAyTyIjgSOPMLrTMfmVldjwP3lz+xWU6gynDj3InGl4EgjoRp+7fQfgvanPAoDJWLHYh/cmxm4O9AaVZCSSg==",
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/nextcloud-vue/-/nextcloud-vue-0.11.2.tgz",
+ "integrity": "sha512-N65Wi+J5sI8dh8RnZxBFvePiyeeMhOXlkc8A2v3vsurpiIIQQyt8VHVjYo1FKfGUhvTWG1HQog8FERimZucJlQ==",
"requires": {
"hammerjs": "^2.0.8",
"md5": "^2.2.1",
diff --git a/package.json b/package.json
index 436bd2e2..92006aaf 100644
--- a/package.json
+++ b/package.json
@@ -42,7 +42,7 @@
"ical.js": "^1.3.0",
"moment": "^2.24.0",
"nextcloud-server": "^0.15.9",
- "nextcloud-vue": "^0.11.1",
+ "nextcloud-vue": "^0.11.2",
"p-limit": "^2.2.0",
"p-queue": "^5.0.0",
"qr-image": "^3.2.0",
diff --git a/src/components/ContactDetails/ContactDetailsAvatar.vue b/src/components/ContactDetails/ContactDetailsAvatar.vue
index fb54cd89..cbccfdc9 100644
--- a/src/components/ContactDetails/ContactDetailsAvatar.vue
+++ b/src/components/ContactDetails/ContactDetailsAvatar.vue
@@ -108,8 +108,8 @@ export default {
},
computed: {
photo() {
- const type = this.contact.vCard.getFirstProperty('photo').type
- if (!this.contact.photo.startsWith('data') && type === 'binary') {
+ const photo = this.contact.vCard.getFirstProperty('photo')
+ if (photo && !this.contact.photo.startsWith('data') && photo.type === 'binary') {
// split on coma in case of any leftover base64 data and retrieve last part
// usually we come to this part when the base64 image type is unknown
return `data:image;base64,${this.contact.photo.split(',').pop()}`
@@ -242,7 +242,7 @@ export default {
},
updateImgSize() {
- if (this.contact.photo) {
+ if (this.contact.photo && this.$refs.img) {
this.updateHeightWidth(this.$refs.img.naturalHeight, this.$refs.img.naturalWidth)
}
},
diff --git a/src/components/Settings/SettingsAddressbook.vue b/src/components/Settings/SettingsAddressbook.vue
index e831b387..9e39cb8f 100644
--- a/src/components/Settings/SettingsAddressbook.vue
+++ b/src/components/Settings/SettingsAddressbook.vue
@@ -34,12 +34,55 @@
class="addressbook__share icon-shared" @click="toggleShare" />
<!-- popovermenu -->
- <a v-click-outside="closeMenu" href="#" class="addressbook__menu">
- <div class="icon-more" @click="toggleMenu" />
- <div :class="{open: menuOpen}" class="popovermenu">
- <popover-menu :menu="menu" />
- </div>
- </a>
+ <Actions class="addressbook__menu" menu-align="right">
+ <!-- copy addressbook link -->
+ <ActionLink
+ :href="addressbook.url"
+ :icon="copyLoading ? 'icon-loading-small' : 'icon-public'"
+ @click.stop.prevent="copyLink">
+ {{ copyButtonText }}
+ </ActionLink>
+
+ <!-- download addressbook -->
+ <ActionLink
+ :href="addressbook.url + '?export'"
+ icon="icon-download">
+ {{ t('contacts', 'Download') }}
+ </ActionLink>
+
+ <template v-if="!addressbook.readOnly">
+ <!-- rename addressbook -->
+ <ActionButton v-if="!editingName"
+ icon="icon-rename"
+ @click.stop.prevent="renameAddressbook">
+ {{ t('contacts', 'Rename') }}
+ </ActionButton>
+ <ActionInput v-else
+ ref="renameInput"
+ :disabled="renameLoading"
+ :icon="renameLoading ? 'icon-loading-small' : 'icon-rename'"
+ :value="addressbook.displayName"
+ @submit="updateAddressbookName" />
+
+ <!-- enable/disable addressbook -->
+ <ActionCheckbox v-if="!toggleEnabledLoading"
+ :checked="enabled"
+ @change.stop.prevent="toggleAddressbookEnabled">
+ {{ enabled ? t('contacts', 'Enabled') : t('contacts', 'Disabled') }}
+ </ActionCheckbox>
+ <ActionButton v-else
+ icon="icon-loading-small">
+ {{ enabled ? t('contacts', 'Enabled') : t('contacts', 'Disabled') }}
+ </ActionButton>
+ </template>
+
+ <!-- delete addressbook -->
+ <ActionButton v-if="hasMultipleAddressbooks"
+ :icon="deleteAddressbookLoading ? 'icon-loading-small' : 'icon-delete'"
+ @click="confirmDeletion">
+ {{ t('contacts', 'Delete') }}
+ </ActionButton>
+ </Actions>
<!-- sharing input -->
<ShareAddressBook v-if="shareOpen && !addressbook.readOnly" :addressbook="addressbook" />
@@ -47,13 +90,18 @@
</template>
<script>
+import { ActionLink, ActionButton, ActionInput, ActionCheckbox } from 'nextcloud-vue'
import ShareAddressBook from './SettingsAddressbookShare'
export default {
name: 'SettingsAddressbook',
components: {
- ShareAddressBook
+ ShareAddressBook,
+ ActionLink,
+ ActionButton,
+ ActionInput,
+ ActionCheckbox
},
props: {
@@ -84,6 +132,12 @@ export default {
hasShares() {
return this.addressbook.shares.length > 0
},
+ addressbooks() {
+ return this.$store.getters.getAddressbooks
+ },
+ hasMultipleAddressbooks() {
+ return this.addressbooks.length > 1
+ },
// info tooltip about number of shares
sharedWithTooltip() {
return this.hasShares
@@ -95,56 +149,13 @@ export default {
})
: '' // disable the tooltip
},
- // building the popover menu
- menu() {
- let menu = [
- {
- href: this.addressbook.url,
- icon: this.copyLoading ? 'icon-loading-small' : 'icon-public',
- text: !this.copied
- ? t('contacts', 'Copy link')
- : this.copySuccess
- ? t('contacts', 'Copied')
- : t('contacts', 'Can not copy'),
- action: this.copyLink
- },
- {
- href: this.addressbook.url + '?export',
- icon: 'icon-download',
- text: t('contacts', 'Download')
- }
- ]
-
- // check if addressbook is readonly
- if (!this.addressbook.readOnly) {
- menu.push({
- icon: this.renameLoading ? 'icon-loading-small' : 'icon-rename',
- // check if editing name
- input: this.editingName ? 'text' : null,
- text: !this.editingName ? t('contacts', 'Rename') : '',
- action: !this.editingName ? this.renameAddressbook : this.updateAddressbookName,
- value: this.addressbook.displayName,
- placeholder: this.addressbook.displayName
- },
- {
- text: this.enabled ? t('contacts', 'Enabled') : t('contacts', 'Disabled'),
- icon: this.toggleEnabledLoading ? 'icon-loading-small' : null,
- input: this.toggleEnabledLoading ? null : 'checkbox',
- key: 'enableAddressbook',
- model: this.enabled,
- action: this.toggleAddressbookEnabled
- })
-
- // check to ensure last addressbook is not deleted.
- if (this.$store.getters.getAddressbooks.length > 1) {
- menu.push({
- icon: this.deleteAddressbookLoading ? 'icon-loading-small' : 'icon-delete',
- text: t('contacts', 'Delete'),
- action: this.confirmDeletion
- })
- }
+ copyButtonText() {
+ if (this.copied) {
+ return this.copySuccess
+ ? t('contacts', 'Copied')
+ : t('contacts', 'Can not copy')
}
- return menu
+ return t('contacts', 'Copy link')
}
},
watch: {
@@ -168,21 +179,19 @@ export default {
toggleShare() {
this.shareOpen = !this.shareOpen
},
- toggleAddressbookEnabled() {
+ async toggleAddressbookEnabled() {
// change to loading status
this.toggleEnabledLoading = true
- setTimeout(() => {
- try {
- this.$store.dispatch('toggleAddressbookEnabled', this.addressbook)
- } catch (err) {
- // error handling
- console.error(err)
- OC.Notification.showTemporary(t('contacts', 'Enabled toggle of addressbook was not successful.'))
- } finally {
- // stop loading status regardless of outcome
- this.toggleEnabledLoading = false
- }
- }, 500)
+ try {
+ await this.$store.dispatch('toggleAddressbookEnabled', this.addressbook)
+ } catch (err) {
+ // error handling
+ console.error(err)
+ OC.Notification.showTemporary(t('contacts', 'Enabled toggle of addressbook was not successful.'))
+ } finally {
+ // stop loading status regardless of outcome
+ this.toggleEnabledLoading = false
+ }
},
confirmDeletion() {
@@ -194,73 +203,68 @@ export default {
)
},
- deleteAddressbook(confirm) {
+ async deleteAddressbook(confirm) {
if (confirm) {
// change to loading status
this.deleteAddressbookLoading = true
- setTimeout(() => {
- try {
- this.$store.dispatch('deleteAddressbook', this.addressbook)
- } catch (err) {
- // error handling
- console.error(err)
- OC.Notification.showTemporary(t('contacts', 'Deletion of addressbook was not successful.'))
- } finally {
- // stop loading status regardless of outcome
- this.deleteAddressbookLoading = false
- }
- }, 500)
+ try {
+ await this.$store.dispatch('deleteAddressbook', this.addressbook)
+ } catch (err) {
+ // error handling
+ console.error(err)
+ OC.Notification.showTemporary(t('contacts', 'Deletion of addressbook was not successful.'))
+ } finally {
+ // stop loading status regardless of outcome
+ this.deleteAddressbookLoading = false
+ }
}
},
renameAddressbook() {
this.editingName = true
},
- updateAddressbookName(e) {
+ async updateAddressbookName(e) {
let addressbook = this.addressbook
// New name for addressbook - inputed value from form
- let newName = e.target[0].value
+ let newName = this.$refs.renameInput.$el.querySelector('input[type="text"]').value
// change to loading status
this.renameLoading = true
- setTimeout(() => {
- try {
- this.$store.dispatch('renameAddressbook', { addressbook, newName })
- } catch (err) {
- // error handling
- console.error(err)
- OC.Notification.showTemporary(t('contacts', 'Renaming of addressbook was not successful.'))
- } finally {
- this.editingName = false
- // stop loading status regardless of outcome
- this.renameLoading = false
- // close popover menu
- this.menuOpen = false
- }
- }, 500)
+ try {
+ await this.$store.dispatch('renameAddressbook', { addressbook, newName })
+ } catch (err) {
+ // error handling
+ console.error(err)
+ OC.Notification.showTemporary(t('contacts', 'Renaming of addressbook was not successful.'))
+ } finally {
+ this.editingName = false
+ // stop loading status regardless of outcome
+ this.renameLoading = false
+ // close popover menu
+ this.menuOpen = false
+ }
},
- copyLink(event) {
+ async copyLink(event) {
// change to loading status
this.copyLoading = true
- event.stopPropagation()
// copy link for addressbook to clipboard
- this.$copyText(window.location.origin + this.addressbook.url)
- .then(e => {
- event.preventDefault()
- this.copySuccess = true
- this.copied = true
- // Notify addressbook was copied
- OC.Notification.showTemporary(t('contacts', 'Addressbook copied to clipboard'))
- }, e => {
+ try {
+ await this.$copyText(window.location.origin + this.addressbook.url)
+ this.copySuccess = true
+ this.copied = true
+ // Notify addressbook was copied
+ OC.Notification.showTemporary(t('contacts', 'Addressbook copied to clipboard'))
+ } catch (error) {
+ this.copySuccess = false
+ this.copied = true
+ OC.Notification.showTemporary(t('contacts', 'Addressbook was not copied to clipboard.'))
+ } finally {
+ this.copyLoading = false
+ setTimeout(() => {
+ // stop loading status regardless of outcome
+ this.copied = false
this.copySuccess = false
- this.copied = true
- OC.Notification.showTemporary(t('contacts', 'Addressbook was not copied to clipboard.'))
- }).then(() => {
- this.copyLoading = false
- setTimeout(() => {
- // stop loading status regardless of outcome
- this.copied = false
- }, 2000)
- })
+ }, 2000)
+ }
}
}
}
diff --git a/webpack.common.js b/webpack.common.js
index da9cc0e9..af5d6759 100644
--- a/webpack.common.js
+++ b/webpack.common.js
@@ -9,7 +9,7 @@ module.exports = {
path: path.resolve(__dirname, './js'),
publicPath: '/js/',
filename: 'contacts.js',
- chunkFilename: 'chunks/[name].js'
+ chunkFilename: 'chunks/contacts.[name].[contenthash].js'
},
module: {
rules: [