Skip to content

Commit 09fadad

Browse files
authored
Merge pull request #11876 from nextcloud/fix/11484/system-message-grouping
fix(MessagesSystemGroup): collapse `actor removed` messages, collapse previously open groups with unread marker
2 parents 20defcf + 1f82203 commit 09fadad

File tree

4 files changed

+94
-12
lines changed

4 files changed

+94
-12
lines changed

src/components/MessagesList/MessagesGroup/Message/Message.vue

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,17 @@ export default {
232232
type: Boolean,
233233
default: undefined,
234234
},
235+
/**
236+
* Specifies if the message is inside a collapsed group.
237+
*/
238+
isCollapsedSystemMessage: {
239+
type: Boolean,
240+
default: false,
241+
},
242+
lastCollapsedMessageId: {
243+
type: [String, Number],
244+
default: 0,
245+
},
235246
/**
236247
* The type of the message.
237248
*/
@@ -329,8 +340,17 @@ export default {
329340
return !this.nextMessageId || this.id === this.conversation?.lastMessage?.id
330341
},
331342
343+
visualLastLastReadMessageId() {
344+
return this.$store.getters.getVisualLastReadMessageId(this.token)
345+
},
346+
332347
isLastReadMessage() {
333-
return !this.isLastMessage && this.id === this.$store.getters.getVisualLastReadMessageId(this.token)
348+
if (this.isLastMessage) {
349+
return false
350+
}
351+
return (!this.isCollapsedSystemMessage && this.id === this.visualLastLastReadMessageId)
352+
|| (this.isCollapsedSystemMessage && this.id === this.visualLastLastReadMessageId && this.id !== this.lastCollapsedMessageId)
353+
|| (this.isCombinedSystemMessage && this.lastCollapsedMessageId === this.visualLastLastReadMessageId)
334354
},
335355
336356
isSystemMessage() {

src/components/MessagesList/MessagesGroup/MessagesSystemGroup.vue

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
:is-combined-system-message-collapsed="messagesCollapsed.collapsed"
3333
:next-message-id="getNextMessageId(messagesCollapsed.messages.at(-1))"
3434
:previous-message-id="getPrevMessageId(messagesCollapsed.messages.at(0))"
35+
:last-collapsed-message-id="messagesCollapsed.lastId"
3536
@toggle-combined-system-message="toggleCollapsed(messagesCollapsed)" />
3637
</ul>
3738
<ul v-show="messagesCollapsed.messages?.length === 1 || !messagesCollapsed.collapsed"
@@ -41,6 +42,8 @@
4142
:key="message.id"
4243
v-bind="message"
4344
:token="token"
45+
is-collapsed-system-message
46+
:last-collapsed-message-id="messagesCollapsed.lastId"
4447
:next-message-id="getNextMessageId(message)"
4548
:previous-message-id="getPrevMessageId(message)" />
4649
</ul>
@@ -153,6 +156,14 @@ export default {
153156
return 'user_added'
154157
}
155158
159+
// Group users removed by one actor
160+
if (message1.systemMessage === 'user_removed'
161+
&& message1.systemMessage === message2.systemMessage
162+
&& message1.actorId === message2.actorId
163+
&& message1.actorType === message2.actorType) {
164+
return 'user_removed'
165+
}
166+
156167
// Group users reconnected in a minute
157168
if (message1.systemMessage === 'call_joined'
158169
&& message2.systemMessage === 'call_left'
@@ -194,30 +205,30 @@ export default {
194205
let lastMessage = null
195206
let forceNextGroup = false
196207
for (const message of messages) {
197-
const isLastRead = message.id === this.lastReadMessageId
198208
const groupingType = this.messagesShouldBeGrouped(message, lastMessage)
199209
if (!groupingType || forceNextGroup) {
200-
groups.push({ id: message.id, messages: [message], type: '', collapsed: this.groupIsCollapsed[message.id] ?? !isLastRead })
210+
groups.push({ id: message.id, lastId: message.id, messages: [message], type: '', collapsed: this.groupIsCollapsed[message.id] ?? true })
201211
forceNextGroup = false
202212
} else {
203213
if (groupingType === 'call_reconnected') {
204-
groups.push({ id: message.id, messages: [groups.at(-1).messages.pop()], type: '', collapsed: this.groupIsCollapsed[message.id] ?? !isLastRead })
214+
groups.push({ id: message.id, lastId: message.id, messages: [groups.at(-1).messages.pop()], type: '', collapsed: this.groupIsCollapsed[message.id] ?? true })
215+
groups.at(-1).lastId = groups.at(-1).messages.at(-1).id
205216
forceNextGroup = true
206217
}
207218
groups.at(-1).messages.push(message)
219+
groups.at(-1).lastId = message.id
208220
groups.at(-1).type = groupingType
209-
if (isLastRead) {
221+
222+
// Check if last read message is hidden inside the collapsed group, and open it, if so.
223+
// Otherwise, combined system message will show a marker
224+
const isLastReadInsideGroup = this.lastReadMessageId >= groups.at(-1).id && this.lastReadMessageId < groups.at(-1).lastId
225+
if (isLastReadInsideGroup) {
210226
groups.at(-1).collapsed = false
211227
}
212228
}
213229
lastMessage = message
214230
}
215231
216-
groups.forEach(group => {
217-
if (this.groupIsCollapsed[group.id] === undefined) {
218-
this.groupIsCollapsed[group.id] = group.collapsed
219-
}
220-
})
221232
return groups
222233
},
223234

src/components/MessagesList/MessagesList.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,10 +428,10 @@ export default {
428428
},
429429
430430
softUpdateAuthorGroups(oldGroups, newGroups, dateTimestamp) {
431-
const oldKeys = Object.keys(oldGroups)
432431
Object.entries(newGroups).forEach(([id, newGroup]) => {
433432
if (!oldGroups[id]) {
434-
const oldId = oldKeys.find(key => id < key && oldGroups[key].nextMessageId <= newGroup.nextMessageId)
433+
const oldId = Object.keys(oldGroups)
434+
.find(key => id < key && oldGroups[key].nextMessageId <= newGroup.nextMessageId)
435435
if (oldId) {
436436
// newGroup includes oldGroup and more old messages, remove oldGroup
437437
delete this.messagesGroupedByDateByAuthor[dateTimestamp][oldId]

src/composables/useCombinedSystemMessage.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,57 @@ export function useCombinedSystemMessage() {
145145
}
146146
}
147147

148+
// Handle cases when actor removed users from conversation (when remove team/group, for example)
149+
if (type === 'user_removed') {
150+
messages.forEach(message => {
151+
if (checkIfSelfIsOneOfUsers(message)) {
152+
selfIsUser = true
153+
} else {
154+
combinedMessage.messageParameters[`user${referenceIndex}`] = message.messageParameters.user
155+
referenceIndex++
156+
}
157+
usersCounter++
158+
})
159+
160+
if (checkIfSelfIsActor(combinedMessage)) {
161+
if (usersCounter === 2) {
162+
combinedMessage.message = t('spreed', 'You removed {user0} and {user1}')
163+
} else {
164+
combinedMessage.message = n('spreed',
165+
'You removed {user0}, {user1} and %n more participant',
166+
'You removed {user0}, {user1} and %n more participants', usersCounter - 2)
167+
}
168+
} else if (selfIsUser) {
169+
if (usersCounter === 2) {
170+
combinedMessage.message = actorIsAdministrator
171+
? t('spreed', 'An administrator removed you and {user0}')
172+
: t('spreed', '{actor} removed you and {user0}')
173+
} else {
174+
combinedMessage.message = actorIsAdministrator
175+
? n('spreed',
176+
'An administrator removed you, {user0} and %n more participant',
177+
'An administrator removed you, {user0} and %n more participants', usersCounter - 2)
178+
: n('spreed',
179+
'{actor} removed you, {user0} and %n more participant',
180+
'{actor} removed you, {user0} and %n more participants', usersCounter - 2)
181+
}
182+
} else {
183+
if (usersCounter === 2) {
184+
combinedMessage.message = actorIsAdministrator
185+
? t('spreed', 'An administrator removed {user0} and {user1}')
186+
: t('spreed', '{actor} removed {user0} and {user1}')
187+
} else {
188+
combinedMessage.message = actorIsAdministrator
189+
? n('spreed',
190+
'An administrator removed {user0}, {user1} and %n more participant',
191+
'An administrator removed {user0}, {user1} and %n more participants', usersCounter - 2)
192+
: n('spreed',
193+
'{actor} removed {user0}, {user1} and %n more participant',
194+
'{actor} removed {user0}, {user1} and %n more participants', usersCounter - 2)
195+
}
196+
}
197+
}
198+
148199
// Handle cases when users joined or left the call
149200
if (type === 'call_joined' || type === 'call_left') {
150201
const storedUniqueUsers = []

0 commit comments

Comments
 (0)