diff options
Diffstat (limited to 'src/components/ContactDetails/ContactDetailsAvatar.vue')
-rw-r--r-- | src/components/ContactDetails/ContactDetailsAvatar.vue | 86 |
1 files changed, 78 insertions, 8 deletions
diff --git a/src/components/ContactDetails/ContactDetailsAvatar.vue b/src/components/ContactDetails/ContactDetailsAvatar.vue index 7b211c8c..3fc6f1ec 100644 --- a/src/components/ContactDetails/ContactDetailsAvatar.vue +++ b/src/components/ContactDetails/ContactDetailsAvatar.vue @@ -3,6 +3,7 @@ - - @author Team Popcorn <teampopcornberlin@gmail.com> - @author John Molakvoæ <skjnldsv@protonmail.com> + - @author Matthias Heinisch <nextcloud@matthiasheinisch.de> - - @license GNU AGPL version 3 or any later version - @@ -25,6 +26,7 @@ <div class="contact-header-avatar"> <div class="contact-header-avatar__wrapper"> <div class="contact-header-avatar__background" @click="toggleModal" /> + <div v-if="contact.photo" :style="{ 'backgroundImage': `url(${contact.photoUrl})` }" class="contact-header-avatar__photo" @@ -73,13 +75,20 @@ </Modal> <!-- out of the avatar__options because of the overflow hidden --> - <Actions :open="opened" class="contact-avatar-options__popovermenu"> - <ActionButton v-if="!isReadOnly" icon="icon-upload" @click="selectFileInput"> + <Actions v-if="!isReadOnly" :open="opened" class="contact-avatar-options__popovermenu"> + <ActionButton icon="icon-upload" @click="selectFileInput"> {{ t('contacts', 'Upload a new picture') }} </ActionButton> - <ActionButton v-if="!isReadOnly" icon="icon-picture" @click="selectFilePicker"> + <ActionButton icon="icon-picture" @click="selectFilePicker"> {{ t('contacts', 'Choose from files') }} </ActionButton> + <ActionButton + v-for="network in supportedSocial" + :key="network" + :icon="'icon-' + network.toLowerCase()" + @click="getSocialAvatar(network)"> + {{ t('contacts', 'Get from ' + network) }} + </ActionButton> </Actions> </div> </div> @@ -93,11 +102,14 @@ import ActionButton from '@nextcloud/vue/dist/Components/ActionButton' import Modal from '@nextcloud/vue/dist/Components/Modal' import { getFilePickerBuilder } from '@nextcloud/dialogs' -import { generateRemoteUrl } from '@nextcloud/router' +import { generateUrl, generateRemoteUrl } from '@nextcloud/router' import { getCurrentUser } from '@nextcloud/auth' +import { loadState } from '@nextcloud/initial-state' import sanitizeSVG from '@mattkrick/sanitize-svg' -const axios = () => import('axios') +import axios from '@nextcloud/axios' + +const supportedNetworks = loadState('contacts', 'supportedNetworks') export default { name: 'ContactDetailsAvatar', @@ -133,6 +145,16 @@ export default { } return false }, + supportedSocial() { + // get social networks set for the current contact + const available = this.contact.vCard.getAllProperties('x-socialprofile') + .map(a => a.jCal[1].type.toString().toLowerCase()) + // get list of social networks that allow for avatar download + const supported = supportedNetworks.map(v => v.toLowerCase()) + // return supported social networks which are set + return supported.filter(i => available.includes(i)) + .map(j => this.capitalize(j)) + }, }, mounted() { // update image size on window resize @@ -215,7 +237,15 @@ export default { this.$refs.uploadInput.value = '' this.loading = false }, - + /** + * Return the word with (only) the first letter capitalized + * + * @param {string} word the word to handle + * @returns {string} the word with the first letter capitalized + */ + capitalize(word) { + return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase() + }, /** * Return the mimetype based on the first magix byte * @@ -314,8 +344,7 @@ export default { if (file) { this.loading = true try { - const { get } = await axios() - const response = await get(`${this.root}${file}`, { + const response = await axios.get(`${this.root}${file}`, { responseType: 'arraybuffer', }) const type = response.headers['content-type'] @@ -331,6 +360,47 @@ export default { }, /** + * Downloads the Avatar from social media + * + * @param {String} network the social network to use (or 'any' for first match) + */ + async getSocialAvatar(network) { + + if (!this.loading) { + + this.loading = true + try { + const response = await axios.put(generateUrl('/apps/contacts/api/v1/social/avatar/{network}/{id}/{uid}', { + network: network.toLowerCase(), + id: this.contact.addressbook.id, + uid: this.contact.uid, + })) + if (response.status !== 200) { + throw new URIError('Download of social profile avatar failed') + } + + // Fetch newly updated contact + await this.$store.dispatch('fetchFullContact', { contact: this.contact, forceReFetch: true }) + + // Update local clone + const contact = this.$store.getters.getContact(this.contact.key) + await this.$emit('updateLocalContact', contact) + + // Notify user + OC.Notification.showTemporary(t('contacts', 'Avatar downloaded from social network')) + } catch (error) { + if (error.response.status === 304) { + OC.Notification.showTemporary(t('contacts', 'Avatar already up to date')) + } else { + OC.Notification.showTemporary(t('contacts', 'Avatar download failed')) + console.debug(error) + } + } + } + this.loading = false + }, + + /** * Menu handling */ toggleMenu() { |