summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--css/ContactDetails.scss38
-rw-r--r--css/contact-details-avatar.scss125
-rw-r--r--css/contacts.scss3
-rw-r--r--package-lock.json2
-rw-r--r--src/components/ContactDetails.vue14
-rw-r--r--src/components/ContactDetails/ContactDetailsAvatar.vue86
-rw-r--r--src/models/contact.js21
7 files changed, 241 insertions, 48 deletions
diff --git a/css/ContactDetails.scss b/css/ContactDetails.scss
index baefdb01..07948d3b 100644
--- a/css/ContactDetails.scss
+++ b/css/ContactDetails.scss
@@ -28,44 +28,6 @@
display: flex;
font-weight: bold;
align-items: center;
-
- // AVATAR
- #contact-header-avatar {
- position: relative;
- height: 75px;
- width: 75px;
- border-radius: 50%;
- overflow: hidden;
- flex-shrink: 0;
- margin: 0 22px 0 44px;
- .contact-avatar-background {
- background-color: var(--color-background-dark);
- opacity: .2;
- z-index: 0;
- }
- img {
- z-index: 1;
- }
- label.icon-upload-white {
- opacity: .5;
- z-index: 2;
- &:hover,
- a:active,
- a:focus {
- opacity: .7;
- }
- }
- img + label.icon-upload-white {
- opacity: 0;
- }
- .contact-avatar-background,
- img,
- label.icon-upload-white {
- position: absolute;
- width: 100%;
- height: 100%;
- }
- }
// ORG-TITLE-NAME
#contact-header-infos {
diff --git a/css/contact-details-avatar.scss b/css/contact-details-avatar.scss
new file mode 100644
index 00000000..d2ad4485
--- /dev/null
+++ b/css/contact-details-avatar.scss
@@ -0,0 +1,125 @@
+/**
+ * @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @author John Molakvoæ <skjnldsv@protonmail.com>
+ * @author Team Popcorn <teampopcornberlin@gmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// AVATAR
+.contact-header-avatar {
+ position: relative;
+ height: 75px;
+ width: 75px;
+ border-radius: 50%;
+ overflow: hidden;
+ flex-shrink: 0;
+ margin: 0 22px 0 44px;
+ &__background {
+ opacity: .2;
+ z-index: 0;
+ left: 0;
+ top: 50px;
+ }
+ &__photo {
+ z-index: 10;
+ background-size: cover;
+ width: 100%;
+ height: 100%;
+ background-repeat: no-repeat;
+ background-position: center;
+ cursor: pointer;
+ }
+ label.icon-upload-white {
+ opacity: .5;
+ z-index: 2;
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ &:hover,
+ a:active,
+ a:focus {
+ opacity: .7;
+ }
+ }
+ &__photo + label.icon-upload-white {
+ opacity: 0;
+ }
+ &__options {
+ top: 0;
+ background-color: rgba(0, 0, 0, 0.2);
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ }
+}
+
+.contact-header-avatar.maximised {
+ position: fixed;
+ height: 100%;
+ width: 100%;
+ top: 0;
+ left: 0;
+ border-radius: 0;
+ margin: 0px;
+ background-color: rgba(0, 0, 0, 0.9);
+ display: flex;
+ justify-content: center;
+ z-index: 200;
+ padding-top: $header-height;
+ flex-direction: column;
+ .contact-header-avatar__photo {
+ border-radius: 0;
+ align-self: center;
+ background-size: contain;
+ margin: 50px;
+ }
+ label.icon-upload-white {
+ width: 25%;
+ height: 40px;
+ position: relative;
+ }
+ .contact-header-avatar__options {
+ height: 50px;
+ width: 100%;
+ display: flex;
+ opacity: 1;
+ flex-wrap: wrap;
+ justify-content: space-evenly;
+ }
+ .contact-header-avatar__options > [class^='icon-'] {
+ width: 25%;
+ display: block;
+ cursor: pointer;
+ opacity: 0.5;
+ }
+ .contact-header-avatar__options > [class^='icon-']:hover {
+ opacity: 0.8;
+ }
+}
+
+.contact-header-avatar-options {
+ top: 0;
+ background-color: rgba(0, 0, 0, 0.2);
+ display: flex;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+}
+
+
diff --git a/css/contacts.scss b/css/contacts.scss
index 0087327e..50016148 100644
--- a/css/contacts.scss
+++ b/css/contacts.scss
@@ -43,8 +43,9 @@ $grid-input-height-with-margin: #{$grid-height-unit - $grid-input-margin * 2};
@import 'settings/settings-addressbook-shares';
@import 'settings/settings-addressbook-sharee';
@import 'ContactDetails';
+@import 'contact-details-avatar';
@import 'ContentListItem';
@import 'Properties/Properties';
@import 'Properties/PropertyTitle';
@import 'importScreen';
-@import 'animations'; \ No newline at end of file
+@import 'animations';
diff --git a/package-lock.json b/package-lock.json
index 9a03c67c..2f1c90f9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3418,7 +3418,7 @@
},
"babel-plugin-syntax-object-rest-spread": {
"version": "6.13.0",
- "resolved": "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
"integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
"dev": true
},
diff --git a/src/components/ContactDetails.vue b/src/components/ContactDetails.vue
index e59fb130..83fdc676 100644
--- a/src/components/ContactDetails.vue
+++ b/src/components/ContactDetails.vue
@@ -41,13 +41,9 @@
<header :style="{ 'backgroundColor': colorAvatar }">
<!-- avatar and upload photo -->
- <div id="contact-header-avatar">
- <div class="contact-avatar-background" />
- <img v-if="contact.photo">
- <input id="contact-avatar-upload" type="file" class="hidden"
- accept="image/*">
- <label v-tooltip.auto="t('contacts', 'Upload a new picture')" for="contact-avatar-upload" class="icon-upload-white" />
- </div>
+ <contact-avatar :contact="contact" />
+ <!-- QUESTION: is it better to pass contact as a prop or get it from the store inside
+ contact-avatar ? :avatar="contact.photo"-->
<!-- fullname, org, title -->
<div id="contact-header-infos">
@@ -124,6 +120,7 @@ import ContactProperty from './ContactDetails/ContactDetailsProperty'
import AddNewProp from './ContactDetails/ContactDetailsAddNewProp'
import PropertySelect from './Properties/PropertySelect'
import PropertyGroups from './Properties/PropertyGroups'
+import ContactAvatar from './ContactDetails/ContactDetailsAvatar'
Vue.use(VTooltip)
@@ -135,7 +132,8 @@ export default {
ContactProperty,
PropertySelect,
PropertyGroups,
- AddNewProp
+ AddNewProp,
+ ContactAvatar
},
directives: {
diff --git a/src/components/ContactDetails/ContactDetailsAvatar.vue b/src/components/ContactDetails/ContactDetailsAvatar.vue
new file mode 100644
index 00000000..0a249d4a
--- /dev/null
+++ b/src/components/ContactDetails/ContactDetailsAvatar.vue
@@ -0,0 +1,86 @@
+<!--
+import rfcProps from '../../models/rfcProps';
+ * @copyright Copyright (c) 2018 Team Popcorn <teampopcornberlin@gmail.com>
+ *
+ * @author Team Popcorn <teampopcornberlin@gmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ -
+ - This program is free software: you can redistribute it and/or modify
+ - it under the terms of the GNU Affero General Public License as
+ - published by the Free Software Foundation, either version 3 of the
+ - License, or (at your option) any later version.
+ -
+ - This program is distributed in the hope that it will be useful,
+ - but WITHOUT ANY WARRANTY; without even the implied warranty of
+ - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ - GNU Affero General Public License for more details.
+ -
+ - You should have received a copy of the GNU Affero General Public License
+ - along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -
+ -->
+
+<template>
+ <div :class="{'maximised':maximizeAvatar }" class="contact-header-avatar">
+ <div class="contact-header-avatar__background" @click="toggleSize" />
+ <div v-if="contact.photo" :style="{ 'backgroundImage': `url(${contact.photo})` }"
+ class="contact-header-avatar__photo"
+ @click="toggleSize" />
+ <div class="contact-header-avatar__options">
+ <input id="contact-avatar-upload" type="file" class="hidden"
+ accept="image/*" @change="processFile">
+ <label v-tooltip.auto="t('contacts', 'Upload a new picture')" for="contact-avatar-upload"
+ class="icon-upload-white" @click="processFile" />
+ <div v-if="maximizeAvatar" class="icon-delete-white" @click="removePhoto" />
+ <a v-if="maximizeAvatar" :href="contact.url + '?photo'" class="icon-download-white" />
+ </div>
+ </div>
+</template>
+
+<script>
+
+export default {
+ name: 'ContactAvatar',
+
+ props: {
+ contact: {
+ type: Object,
+ required: true
+ }
+ },
+ data() {
+ return {
+ maximizeAvatar: false
+ }
+ },
+ methods: {
+ processFile(event) {
+ if (event.target.files) {
+ let file = event.target.files[0]
+ let reader = new FileReader()
+ let self = this
+ // check if photo property exists to decide whether to add/update it
+ reader.onload = function(e) {
+ self.contact.photo
+ ? self.contact.photo = reader.result
+ : self.contact.vCard.addPropertyWithValue('photo', reader.result)
+
+ self.$store.dispatch('updateContact', self.contact)
+ }
+ reader.readAsDataURL(file)
+ }
+ },
+ toggleSize() {
+ // maximise or minimise avatar photo
+ this.maximizeAvatar = !this.maximizeAvatar
+ },
+ removePhoto() {
+ this.contact.vCard.removeProperty('photo')
+ this.maximizeAvatar = !this.maximizeAvatar
+ this.$store.dispatch('updateContact', this.contact)
+ }
+ }
+
+}
+</script>
diff --git a/src/models/contact.js b/src/models/contact.js
index 52d713fc..b0eec0a5 100644
--- a/src/models/contact.js
+++ b/src/models/contact.js
@@ -123,6 +123,27 @@ export default class Contact {
}
/**
+ * Return the photo
+ *
+ * @readonly
+ * @memberof Contact
+ */
+ get photo() {
+ return this.vCard.getFirstPropertyValue('photo')
+ }
+
+ /**
+ * Set the photo
+ *
+ * @param {string} photo the photo to set
+ * @memberof Contact
+ */
+ set photo(photo) {
+ this.vCard.updatePropertyWithValue('photo', photo)
+ return true
+ }
+
+ /**
* Return the groups
*
* @readonly