Skip to content

Commit ea81812

Browse files
committed
[WIP] exchange cloud ID
1 parent 43e4923 commit ea81812

File tree

6 files changed

+278
-3
lines changed

6 files changed

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

src/components/Properties/PropertyText.vue

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@
1414
:icon="propModel.icon"
1515
:readable-name="propModel.readableName" />
1616

17+
<ExchangeInvite
18+
:local-contact="localContact"
19+
:value.sync="localValue"
20+
:prop-name="propName"
21+
:value="value" />
22+
1723
<div class="property__row">
1824
<div class="property__label">
1925
<!-- read-only type -->
@@ -90,6 +96,7 @@
9096
<script>
9197
import { NcSelect, NcTextArea, NcTextField } from '@nextcloud/vue'
9298
import debounce from 'debounce'
99+
import ExchangeInvite from '../CloudIdExchangeInvite.vue'
93100
import PropertyMixin from '../../mixins/PropertyMixin.js'
94101
import PropertyTitle from './PropertyTitle.vue'
95102
import PropertyActions from './PropertyActions.vue'
@@ -99,6 +106,7 @@ export default {
99106
name: 'PropertyText',
100107
101108
components: {
109+
ExchangeInvite,
102110
NcSelect,
103111
NcTextArea,
104112
NcTextField,
@@ -169,15 +177,27 @@ export default {
169177
* @return {string}
170178
*/
171179
placeholder() {
180+
// TODO add check (config?) if there is cloud ID exchange invitation capability
181+
if(this.isNewInvite) {
182+
return t('contacts', '... awaiting invite response')
183+
}
184+
if (this.propName == 'cloud') {
185+
return t('contacts', '... you may use exchange cloud ID option')
186+
}
172187
if (this.localType?.placeholder) {
173188
return this.localType.placeholder
174189
}
175190
return this.propModel.placeholder
176191
},
177192
},
193+
data() {
194+
return {
195+
isNewInvite: false
196+
}
197+
},
178198
179199
mounted() {
180-
this.resizeHeight()
200+
// this.resizeHeight()
181201
},
182202
183203
methods: {
@@ -202,6 +222,17 @@ export default {
202222
this.resizeHeight(e)
203223
this.updateValue(e)
204224
},
225+
setName(name) {
226+
console.log(`received name: ${name}`)
227+
this.localContact.properties.find(p => p.name === 'fn').setValue(name)
228+
// this.propModel.placeholder = '... awaiting response'
229+
// this.$emit('update:value', '... awaiting response')
230+
this.isNewInvite = true
231+
// const i = ref('iets')
232+
// console.log(i)
233+
// this.$forceUpdate()
234+
235+
},
205236
},
206237
}
207238
</script>

src/views/Contacts.vue

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,9 +289,16 @@ export default {
289289
rev.fromUnixTime(Date.now() / 1000)
290290
contact.rev = rev
291291
292-
// itterate over all properties (filter is not usable on objects and we need the key of the property)
292+
// iterate over all properties (filter is not usable on objects and we need the key of the property)
293293
const properties = rfcProps.properties
294294
for (const name in properties) {
295+
// Show cloud ID property if cloud ID exchange capability present
296+
// TODO add check for:
297+
// 1. cloud ID exchange invitation capability present ?
298+
// 2. is it active ?
299+
if(name === 'cloud') {
300+
properties[name].default = true
301+
}
295302
if (properties[name].default) {
296303
const defaultData = properties[name].defaultValue
297304
let defaultValue = defaultData.value

0 commit comments

Comments
 (0)