Skip to content

Commit e7c2604

Browse files
committed
[WIP] exchange cloud ID
- create dedicated cloud ID property component
1 parent 0714ac0 commit e7c2604

File tree

6 files changed

+529
-2
lines changed

6 files changed

+529
-2
lines changed
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
<!--
2+
- SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
3+
- SPDX-License-Identifier: AGPL-3.0-or-later
4+
-->
5+
6+
<template>
7+
<div v-if="displayCloudIdExchangeButton(propName)">
8+
<Actions class="property__actions exchange-cloud-id">
9+
<ActionButton @click="openExchangeInviteModal">
10+
<template #icon>
11+
<IconAccountSwitchOutline :size="20" />
12+
</template>
13+
Invite remote user to exchange cloud IDs. This will add the remote user to your contacts list.
14+
</ActionButton>
15+
</Actions>
16+
17+
<Modal v-if="showInviteModal"
18+
id="invitation-modal"
19+
size="small"
20+
:clear-view-delay="-1"
21+
:close-button-contained="false"
22+
@close="closeExchangeInviteModal"
23+
class="modal-cloud-id-exchange">
24+
25+
<InvitationDetails :local-contact="localContact">
26+
<template #name>
27+
<NcTextField type="text" :placeholder="t('contacts', 'name')" :value="displayName"
28+
@input="setDisplayName" />
29+
</template>
30+
<template #email>
31+
<NcTextField type="text" :placeholder="t('contacts', 'email')" :value="email" @input="setEmail" />
32+
</template>
33+
<template #personal-message>
34+
<NcTextArea id="personal-message" ref="textarea" :placeholder="t('contacts', 'personal message')"
35+
:value="message" :inputmode="inputmode" @input="setMessage" />
36+
</template>
37+
<template #invitation-actions>
38+
<NcButton @click="sendInvitation">
39+
<template #icon>
40+
<IconLoading v-if="loadingUpdate" :size="20" />
41+
<IconCheck v-else :size="20" />
42+
</template>
43+
{{ t('contacts', 'Send') }}
44+
</NcButton>
45+
</template>
46+
</InvitationDetails>
47+
</Modal>
48+
49+
</div>
50+
51+
</template>
52+
53+
<script>
54+
import {
55+
NcActionButton as ActionButton,
56+
NcActions as Actions,
57+
NcButton,
58+
NcLoadingIcon as IconLoading,
59+
NcModal as Modal,
60+
NcTextArea,
61+
NcTextField,
62+
} from '@nextcloud/vue'
63+
import Contact from '../models/contact.js'
64+
import IconAccountSwitchOutline from 'vue-material-design-icons/AccountSwitchOutline.vue'
65+
import IconCheck from 'vue-material-design-icons/Check.vue'
66+
import InvitationDetails from './CloudIdExchangeInviteDetails.vue'
67+
import PropertyMixin from '../mixins/PropertyMixin.js'
68+
69+
export default {
70+
name: 'PropertyText',
71+
72+
components: {
73+
ActionButton,
74+
Actions,
75+
Contact,
76+
IconAccountSwitchOutline,
77+
IconCheck,
78+
IconLoading,
79+
InvitationDetails,
80+
Modal,
81+
NcButton,
82+
NcTextArea,
83+
NcTextField,
84+
},
85+
mixins: [PropertyMixin],
86+
props: {
87+
localContact: {
88+
type: Contact,
89+
default: null,
90+
},
91+
propName: {
92+
type: String,
93+
default: 'text',
94+
required: true,
95+
},
96+
value: {
97+
type: String,
98+
default: '',
99+
required: true,
100+
},
101+
contactFormEditMode: {
102+
type: Boolean,
103+
default: false
104+
}
105+
},
106+
computed: {
107+
displayName() {
108+
return this.localContact.displayName
109+
},
110+
email() {
111+
return this.localContact.email
112+
}
113+
},
114+
emits: [
115+
'setContactFormEditModeEvent:value'
116+
],
117+
methods: {
118+
displayCloudIdExchangeButton(propName) {
119+
// TODO add check for:
120+
// 1. cloud ID exchange invitation capability present ?
121+
// 2. is it active ?
122+
if (propName === 'cloud' && this.localContact && !(typeof this.value === 'string' || this.value instanceof String)) {
123+
console.log(`displayCloudIdExchangeButton(${propName}): true`)
124+
this.isNewContact = false
125+
return true
126+
}
127+
return false
128+
},
129+
closeExchangeInviteModal() {
130+
this.showInviteModal = false
131+
},
132+
openExchangeInviteModal() {
133+
this.showInviteModal = true
134+
},
135+
sendInvitation() {
136+
console.log('contactFormEditMode: ' + this.contactFormEditMode)
137+
this.localContact.properties.find(p => p.name === 'fn').setValue(this.localDisplayName)
138+
this.localContact.properties.find(p => p.name === 'email').setValue(this.localEmail)
139+
this.updateContact()
140+
// TODO on close:
141+
// - display saved contact; like when save button is pressed
142+
// - the cloud ID prop should be displayed saying '... awaiting cloud ID exchange invite response'
143+
this.$emit('setContactFormEditModeEvent:value', false)
144+
this.showInviteModal = false
145+
},
146+
setDisplayName(e) {
147+
this.localDisplayName = e.target.value
148+
},
149+
setEmail(e) {
150+
this.localEmail = e.target.value
151+
},
152+
setMessage(e) {
153+
this.localMessage = e.target.value
154+
},
155+
updateContact() {
156+
this.fixed = false
157+
this.loadingUpdate = true
158+
try {
159+
this.$store.dispatch('updateContact', this.localContact)
160+
} finally {
161+
this.loadingUpdate = false
162+
}
163+
},
164+
},
165+
data() {
166+
return {
167+
showInviteModal: false,
168+
isNewContact: false,
169+
localDisplayName: '',
170+
localEmail: '',
171+
localMessage: '',
172+
loadingUpdate: false,
173+
}
174+
}
175+
}
176+
</script>
177+
178+
<style lang="scss">
179+
div.property.property-cloud {
180+
position: relative;
181+
}
182+
</style>
183+
184+
<style lang="scss" scoped>
185+
#invitation-modal {
186+
background-color: rgba(0, 0, 0, .5);
187+
div.modal-container__content {
188+
margin: 0 1em 1em;
189+
}
190+
}
191+
192+
div.property.property-cloud {
193+
button.exchange-cloud-id {
194+
position: absolute;
195+
top: 0;
196+
right: 4em;
197+
}
198+
}
199+
200+
</style>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!--
2+
- SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
3+
- SPDX-License-Identifier: AGPL-3.0-or-later
4+
-->
5+
6+
<template>
7+
<div class="contact-header__infos">
8+
<h5 class="">
9+
{{ t('contacts', 'Invitation to exchange cloud IDs') }}
10+
</h5>
11+
<div class="invitation-name">
12+
<label>Name</label>
13+
<slot name="name" />
14+
</div>
15+
<div class="invitation-email">
16+
<label>Email</label>
17+
<slot name="email" />
18+
</div>
19+
<div class="invitation-personal-message">
20+
<label>Message</label>
21+
<slot name="personal-message" />
22+
</div>
23+
<div class="actions">
24+
<slot name="invitation-actions" />
25+
</div>
26+
</div>
27+
28+
</template>
29+
30+
<script>
31+
32+
export default {
33+
name: 'InvitationDetails',
34+
}
35+
</script>

src/components/ContactDetails.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,9 @@
277277
:local-contact="localContact"
278278
:contacts="contacts"
279279
:bus="bus"
280-
:is-read-only="isReadOnly" />
280+
:is-read-only="isReadOnly"
281+
:contactFormEditMode="editMode"
282+
@setContactFormEditModeEvent:value="setEditMode" />
281283
</div>
282284
</section>
283285

@@ -1069,6 +1071,9 @@ export default {
10691071
showError(t('contacts', 'Unable to update contact'))
10701072
}
10711073
},
1074+
setEditMode(value) {
1075+
this.editMode = value
1076+
}
10721077
},
10731078
}
10741079
</script>

src/components/ContactDetails/ContactDetailsProperty.vue

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
:is-read-only="isReadOnly"
2525
:bus="bus"
2626
:is-multiple="isMultiple"
27+
:contactFormEditMode="contactFormEditMode"
28+
@setContactFormEditModeEvent:value="setEditMode"
2729
@delete="onDelete" />
2830
</template>
2931

@@ -38,6 +40,7 @@ import PropertyMultipleText from '../Properties/PropertyMultipleText.vue'
3840
import PropertyDateTime from '../Properties/PropertyDateTime.vue'
3941
import PropertySelect from '../Properties/PropertySelect.vue'
4042
import { matchTypes } from '../../utils/matchTypes.ts'
43+
import PropertyCloudId from '../Properties/PropertyCloudId.vue'
4144
4245
export default {
4346
name: 'ContactDetailsProperty',
@@ -99,6 +102,8 @@ export default {
99102
return PropertyDateTime
100103
} else if (this.propType && this.propType === 'select') {
101104
return PropertySelect
105+
} else if (this.propType && this.propName === 'cloud') {
106+
return PropertyCloudId
102107
} else if (this.propType && this.propType !== 'unknown') {
103108
return PropertyText
104109
}
@@ -358,6 +363,14 @@ export default {
358363
this.bus.off('focus-prop', this.onFocusProp)
359364
},
360365
366+
data() {
367+
return {
368+
contactFormEditMode: false,
369+
}
370+
},
371+
emits: [
372+
'setContactFormEditModeEvent:value'
373+
],
361374
methods: {
362375
/**
363376
* Focus first input element of the new prop
@@ -383,6 +396,10 @@ export default {
383396
onDelete() {
384397
this.localContact.vCard.removeProperty(this.property)
385398
},
399+
400+
setEditMode(value) {
401+
this.$emit('setContactFormEditModeEvent:value', value)
402+
}
386403
},
387404
}
388405
</script>

0 commit comments

Comments
 (0)