Skip to content

Commit 7c0eaa0

Browse files
committed
[WIP] exchange cloud ID
- create dedicated cloud ID property component
1 parent 43e4923 commit 7c0eaa0

File tree

8 files changed

+521
-3
lines changed

8 files changed

+521
-3
lines changed

package-lock.json

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

@@ -1058,6 +1060,9 @@ export default {
10581060
showError(t('contacts', 'Unable to update contact'))
10591061
}
10601062
},
1063+
setEditMode(value) {
1064+
this.editMode = value
1065+
}
10611066
},
10621067
}
10631068
</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>

src/components/Properties/PropertyActions.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export default {
4747
4848
methods: {
4949
deleteProperty() {
50+
console.log('going to delete property');
5051
this.$emit('delete')
5152
},
5253
},

0 commit comments

Comments
 (0)