Skip to content

Commit 110d6ee

Browse files
Move description editor to conversation settings
Signed-off-by: Marco Ambrosini <[email protected]>
1 parent 5b4e1a7 commit 110d6ee

File tree

3 files changed

+68
-141
lines changed

3 files changed

+68
-141
lines changed

src/components/ConversationSettings/ConversationSettingsDialog.vue

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,49 +26,61 @@
2626
:open.sync="showSettings"
2727
:show-navigation="true"
2828
container="#content-vue">
29+
<!-- description -->
30+
<AppSettingsSection
31+
:title="t('spreed', 'Description')">
32+
<Description
33+
v-if="showDescription"
34+
:editable="canFullModerate"
35+
:description="description"
36+
:editing="isEditingDescription"
37+
:loading="isDescriptionLoading"
38+
:placeholder="t('spreed', 'Add a description for this conversation')"
39+
@submit:description="handleUpdateDescription"
40+
@update:editing="handleEditDescription" />
41+
</AppSettingsSection>
42+
2943
<!-- Notifications settings -->
3044
<AppSettingsSection
31-
:title="t('spreed', 'Chat notifications')"
32-
class="app-settings-section">
45+
:title="t('spreed', 'Chat notifications')">
3346
<NotificationsSettings :conversation="conversation" />
3447
</AppSettingsSection>
48+
3549
<!-- Guest access -->
3650
<AppSettingsSection
3751
v-if="canFullModerate"
38-
:title="t('spreed', 'Guests access')"
39-
class="app-settings-section">
52+
:title="t('spreed', 'Guests access')">
4053
<LinkShareSettings ref="linkShareSettings" />
4154
</AppSettingsSection>
55+
4256
<!-- TODO sepatate these 2 settings and rename the settings sections
4357
all the settings in this component are conversation settings. Proposal:
4458
move lock conversation in destructive actions and create a separate
4559
section for listablesettings -->
4660
<AppSettingsSection
4761
v-if="canFullModerate"
48-
:title="t('spreed', 'Conversation settings')"
49-
class="app-settings-section">
62+
:title="t('spreed', 'Conversation settings')">
5063
<ListableSettings :token="token" />
5164
<LockingSettings :token="token" />
5265
</AppSettingsSection>
66+
5367
<!-- Meeting settings -->
5468
<AppSettingsSection
5569
v-if="canFullModerate"
56-
:title="t('spreed', 'Meeting settings')"
57-
class="app-settings-section">
70+
:title="t('spreed', 'Meeting settings')">
5871
<LobbySettings :token="token" />
5972
<SipSettings v-if="canUserEnableSIP" />
6073
</AppSettingsSection>
6174
<AppSettingsSection
6275
v-if="canFullModerate && matterbridgeEnabled"
63-
:title="t('spreed', 'Matterbridge')"
64-
class="app-settings-section">
76+
:title="t('spreed', 'Matterbridge')">
6577
<MatterbridgeSettings />
6678
</AppSettingsSection>
79+
6780
<!-- Destructive actions -->
6881
<AppSettingsSection
6982
v-if="canLeaveConversation || canDeleteConversation"
70-
:title="t('spreed', 'Danger zone')"
71-
class="app-settings-section">
83+
:title="t('spreed', 'Danger zone')">
7284
<DangerZone
7385
:conversation="conversation"
7486
:can-leave-conversation="canLeaveConversation"
@@ -79,7 +91,7 @@
7991

8092
<script>
8193
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
82-
import { PARTICIPANT } from '../../constants'
94+
import { PARTICIPANT, CONVERSATION } from '../../constants'
8395
import AppSettingsDialog from '@nextcloud/vue/dist/Components/AppSettingsDialog'
8496
import AppSettingsSection from '@nextcloud/vue/dist/Components/AppSettingsSection'
8597
import LinkShareSettings from './LinkShareSettings'
@@ -91,6 +103,8 @@ import MatterbridgeSettings from './Matterbridge/MatterbridgeSettings'
91103
import { loadState } from '@nextcloud/initial-state'
92104
import DangerZone from './DangerZone'
93105
import NotificationsSettings from './NotificationsSettings'
106+
import { showError } from '@nextcloud/dialogs'
107+
import Description from '../Description/Description'
94108
95109
export default {
96110
name: 'ConversationSettingsDialog',
@@ -106,12 +120,16 @@ export default {
106120
MatterbridgeSettings,
107121
DangerZone,
108122
NotificationsSettings,
123+
Description,
109124
},
110125
111126
data() {
112127
return {
113128
showSettings: false,
114129
matterbridgeEnabled: loadState('spreed', 'enable_matterbridge'),
130+
isEditingDescription: false,
131+
isDescriptionLoading: false,
132+
115133
}
116134
},
117135
@@ -143,6 +161,18 @@ export default {
143161
canLeaveConversation() {
144162
return this.conversation.canLeaveConversation
145163
},
164+
165+
description() {
166+
return this.conversation.description
167+
},
168+
169+
showDescription() {
170+
if (this.canFullModerate) {
171+
return this.conversation.type !== CONVERSATION.TYPE.ONE_TO_ONE
172+
} else {
173+
return this.description !== ''
174+
}
175+
},
146176
},
147177
148178
mounted() {
@@ -166,6 +196,25 @@ export default {
166196
unsubscribe('show-conversation-settings', this.handleShowSettings)
167197
unsubscribe('hide-conversation-settings', this.handleHideSettings)
168198
},
199+
200+
async handleUpdateDescription(description) {
201+
this.isDescriptionLoading = true
202+
try {
203+
await this.$store.dispatch('setConversationDescription', {
204+
token: this.token,
205+
description,
206+
})
207+
this.isEditingDescription = false
208+
} catch (error) {
209+
console.error('Error while setting conversation description', error)
210+
showError(t('spreed', 'Error while updating conversation description'))
211+
}
212+
this.isDescriptionLoading = false
213+
},
214+
215+
handleEditDescription(payload) {
216+
this.isEditingDescription = payload
217+
},
169218
},
170219
}
171220
</script>

src/components/RightSidebar/Description/Description.vue renamed to src/components/Description/Description.vue

Lines changed: 6 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
:key="forceReRenderKey"
2525
v-mousedown-outside="handleMouseDownOutside"
2626
class="description"
27-
:class="{'description--editing': editing, 'description--expanded': expanded}">
27+
:class="{'description--editing': editing}">
2828
<RichContentEditable
2929
ref="contenteditable"
3030
:value.sync="descriptionText"
@@ -75,24 +75,13 @@
7575
</button>
7676
</template>
7777
<div v-if="loading" class="icon-loading-small spinner" />
78-
<button v-if="!editing && overflows && expanded" class="expand-indicator nc-button nc-button__main" @click="handleClick">
79-
<ChevronDown
80-
decorative
81-
title=""
82-
:size="16" />
83-
</button>
84-
<div v-if="showOverlay"
85-
cursor="pointer"
86-
class="overlay"
87-
@click="handleClick" />
8878
</div>
8979
</template>
9080

9181
<script>
9282
import Pencil from 'vue-material-design-icons/Pencil'
9383
import Check from 'vue-material-design-icons/Check'
9484
import Close from 'vue-material-design-icons/Close'
95-
import ChevronDown from 'vue-material-design-icons/ChevronDown'
9685
import RichContentEditable from '@nextcloud/vue/dist/Components/RichContenteditable'
9786
import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip'
9887
@@ -103,7 +92,6 @@ export default {
10392
Check,
10493
Close,
10594
RichContentEditable,
106-
ChevronDown,
10795
},
10896
10997
directives: {
@@ -172,7 +160,6 @@ export default {
172160
return {
173161
descriptionText: this.description,
174162
forceReRenderKey: 0,
175-
expanded: false,
176163
overflows: null,
177164
}
178165
},
@@ -201,39 +188,19 @@ export default {
201188
charactersCount: this.charactersCount,
202189
})
203190
},
204-
205-
showCollapseButton() {
206-
return this.overflows && !this.editing && !this.loading && this.expanded
207-
},
208-
209-
showOverlay() {
210-
return this.overflows && !this.editing && !this.loading && !this.expanded
211-
},
212-
},
213-
214-
mounted() {
215-
this.checkOverflow()
216191
},
217192
218193
watch: {
219194
// Each time the prop changes, reflect the changes in the value stored in this component
220195
description(newValue) {
221196
this.descriptionText = newValue
222-
if (!this.editing) {
223-
this.checkOverflow()
224-
}
225197
},
226198
editing(newValue) {
227199
if (!newValue) {
228200
this.descriptionText = this.description
229201
}
230202
},
231203
},
232-
updated() {
233-
if (!this.editing && !this.expanded) {
234-
this.checkOverflow()
235-
}
236-
},
237204
238205
methods: {
239206
handleEditDescription() {
@@ -269,18 +236,8 @@ export default {
269236
window.getSelection().removeAllRanges()
270237
},
271238
272-
// Expand the description
273-
handleClick() {
274-
if (this.editing || this.loading) {
275-
return
276-
} if (this.overflows) {
277-
this.expanded = !this.expanded
278-
}
279-
},
280-
281239
// Collapse the description or dismiss editing
282240
handleMouseDownOutside(event) {
283-
this.expanded = false
284241
this.$emit('update:editing', false)
285242
},
286243
@@ -295,27 +252,23 @@ export default {
295252
</script>
296253

297254
<style lang="scss" scoped>
298-
@import '../../../assets/variables.scss';
299-
@import '../../../assets/buttons.scss';
255+
@import '../../assets/variables.scss';
256+
@import '../../assets/buttons.scss';
300257
301258
.description {
302-
margin: -20px 0 8px 8px;
303259
display: flex;
304260
width: 100%;
305261
overflow: hidden;
306262
position: relative;
307-
max-height: calc(var(--default-line-height) * 3 + 28px);
263+
min-height: $clickable-area;
264+
align-items: flex-end;
308265
&--editing {
309266
box-shadow: 0 2px var(--color-primary-element);
310267
transition: all 150ms ease-in-out;
311268
max-height: unset;
312269
align-items: flex-end;
313270
}
314-
&--expanded {
315-
max-height: unset;
316-
min-height: $clickable-area * 2;
317-
align-items: flex-end;
318-
}
271+
319272
&__header {
320273
display: flex;
321274
align-items: center;
@@ -350,15 +303,6 @@ export default {
350303
margin: 0 0 4px 0;
351304
}
352305
353-
.expand-indicator {
354-
width: $clickable-area;
355-
height: $clickable-area;
356-
margin: 0 0 4px 0;
357-
position: absolute;
358-
top: 0;
359-
right: 0;
360-
}
361-
362306
.counter {
363307
background-color: var(--color-background-dark);
364308
height: 44px;
@@ -372,21 +316,6 @@ export default {
372316
justify-content: center;
373317
}
374318
375-
.overlay {
376-
background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.5) 75%, rgba(255, 255, 255, 1) 100%);
377-
width: 100%;
378-
height: 100%;
379-
position: absolute;
380-
top: 0;
381-
right: 0;
382-
padding-right: $clickable-area;
383-
cursor: pointer;
384-
385-
body.theme--dark & {
386-
background: linear-gradient(180deg, rgba(24, 24, 24, 0) 0%, rgba(24, 24, 24, 0.5) 75%, rgba(24, 24, 24, 1) 100%);
387-
}
388-
}
389-
390319
// Restyle richContentEditable component from our library.
391320
::v-deep .rich-contenteditable__input {
392321
min-height: var(--default-line-height);

0 commit comments

Comments
 (0)