Skip to content

Commit cb049ec

Browse files
authored
fix: handle user.delete event [WPB-18869] (#19424)
* fix: handle user.delete event [WPB-18869] (#19440) * fix: handle user.delete event build user.delete event message inject memberleave event when a user is deleted add localisation string for user deleted event revert user event message changes revert user event message changes emit user.delete event * display user deleted message if other member leave messages are not valid * remove DE localization string * replace buildMemberDelete with existing buildMember leave builder * runfix: extend UserDeleteEvent type * correct typo, add german localization
1 parent 11df6b9 commit cb049ec

File tree

8 files changed

+66
-4
lines changed

8 files changed

+66
-4
lines changed

src/i18n/de-DE.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,7 @@
548548
"conversationLikesCaptionSingular": "[bold]{userName}[/bold]",
549549
"conversationLocationLink": "Standort anzeigen",
550550
"conversationMLSMigrationFinalisationOngoingCall": "Aufgrund der Umstellung auf MLS haben Sie möglicherweise Probleme mit Ihrem aktuellen Anruf. Wenn das der Fall ist, legen Sie auf und rufen Sie erneut an.",
551+
"conversationMemberDeleted": "Dieser Benutzer ist nicht mehr verfügbar",
551552
"conversationMemberJoined": "[bold]{name}[/bold] hat {users} hinzugefügt",
552553
"conversationMemberJoinedMore": "[bold]{name}[/bold] hat {users} und [showmore]{count} andere[/showmore] hinzugefügt",
553554
"conversationMemberJoinedSelf": "[bold]{name}[/bold] ist beigetreten",

src/i18n/en-US.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@
551551
"conversationLikesCaptionSingular": "[bold]{userName}[/bold]",
552552
"conversationLocationLink": "Open Map",
553553
"conversationMLSMigrationFinalisationOngoingCall": "Due to migration to MLS, you might have issues with your current call. If that's the case, hang up and call again.",
554+
"conversationMemberDeleted": "This user is no longer available",
554555
"conversationMemberJoined": "[bold]{name}[/bold] added {users} to the conversation",
555556
"conversationMemberJoinedMore": "[bold]{name}[/bold] added {users}, and [showmore]{count} more[/showmore] to the conversation",
556557
"conversationMemberJoinedSelf": "[bold]{name}[/bold] joined",

src/script/components/MessagesList/Message/MemberMessage/MessageContent.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ function getContent(message: MemberMessageEntity) {
184184
if (!actor.id) {
185185
return t('conversationMemberWereRemoved', {users: allUsers}, {}, true);
186186
}
187+
188+
if (message.reason === MemberLeaveReason.USER_DELETED) {
189+
return t('conversationMemberDeleted');
190+
}
191+
187192
return actor.isMe
188193
? t('conversationMemberRemovedYou', {users: allUsers}, {}, true)
189194
: t('conversationMemberRemoved', {name, users: allUsers}, {}, true);

src/script/conversation/ConversationRepository.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,7 @@ export class ConversationRepository {
383383

384384
this.selfRepository.on('selfSupportedProtocolsUpdated', this.initAllLocal1To1Conversations);
385385
this.userRepository.on('supportedProtocolsUpdated', this.onUserSupportedProtocolsUpdated);
386+
this.userRepository.on('userDeleted', this.onUserDeleted);
386387
}
387388

388389
public initMLSConversationRecoveredListener() {
@@ -2439,6 +2440,29 @@ export class ConversationRepository {
24392440
return this.eventRepository.injectEvent(event, EventRepository.SOURCE.INJECTED);
24402441
}
24412442

2443+
/**
2444+
* Will inject a member deleted event in 1:1 conversations with that user.
2445+
* This will be used to notify the other user that the user was deleted.
2446+
*
2447+
* @param userId User ID of the user that was deleted
2448+
*/
2449+
2450+
private readonly onUserDeleted = async (userId: QualifiedId) => {
2451+
const found1to1Conversation = this.conversationState.get1to1ConversationWithUser(userId);
2452+
if (!found1to1Conversation) {
2453+
return;
2454+
}
2455+
2456+
const deletedEvent = EventBuilder.buildMemberLeave(
2457+
found1to1Conversation,
2458+
[userId],
2459+
'',
2460+
this.serverTimeHandler.toServerTimestamp(),
2461+
MemberLeaveReason.USER_DELETED,
2462+
);
2463+
await this.eventRepository.injectEvent(deletedEvent, EventRepository.SOURCE.INJECTED);
2464+
};
2465+
24422466
/**
24432467
* Add service to conversation.
24442468
*

src/script/conversation/ConversationState.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,23 @@ export class ConversationState {
227227
return mlsConversation || null;
228228
}
229229

230+
/**
231+
* Get a 1:1 conversation with a user.
232+
* @param userId User ID
233+
* @returns Conversation with the user or undefined if not found
234+
*/
235+
get1to1ConversationWithUser(userId: QualifiedId): Conversation | undefined {
236+
const foundMLSConversation = this.findMLS1to1Conversation(userId);
237+
if (foundMLSConversation) {
238+
return foundMLSConversation;
239+
}
240+
const foundProteusConversations = this.findProteus1to1Conversations(userId);
241+
if (foundProteusConversations && foundProteusConversations.length > 0) {
242+
return foundProteusConversations[0];
243+
}
244+
return undefined;
245+
}
246+
230247
has1to1ConversationWithUser(userId: QualifiedId): boolean {
231248
const foundMLSConversation = this.findMLS1to1Conversation(userId);
232249
if (foundMLSConversation) {

src/script/conversation/EventBuilder.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,12 +533,14 @@ export const EventBuilder = {
533533
userIds: QualifiedId[],
534534
from: string,
535535
currentTimestamp: number,
536+
reason?: MemberLeaveReason,
536537
): MemberLeaveEvent {
537538
return {
538539
...buildQualifiedId(conversationEntity),
539540
data: {
540541
qualified_user_ids: userIds,
541542
user_ids: userIds.map(({id}) => id),
543+
reason,
542544
},
543545
from: from,
544546
time: conversationEntity.getNextIsoDate(currentTimestamp),

src/script/user/UserRepository.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,16 @@ interface UserAvailabilityEvent {
105105
type: USER.AVAILABILITY;
106106
}
107107

108-
type Events = {supportedProtocolsUpdated: {user: User; supportedProtocols: ConversationProtocol[]}};
108+
type Events = {
109+
supportedProtocolsUpdated: {user: User; supportedProtocols: ConversationProtocol[]};
110+
userDeleted: QualifiedId;
111+
};
112+
113+
type UserDeleteEventWithQualifiedId = {
114+
id: string;
115+
qualified_id: QualifiedId;
116+
type: USER_EVENT.DELETE;
117+
};
109118
export class UserRepository extends TypedEventEmitter<Events> {
110119
private readonly logger: Logger;
111120
public readonly userMapper: UserMapper;
@@ -155,7 +164,8 @@ export class UserRepository extends TypedEventEmitter<Events> {
155164

156165
switch (eventJson.type) {
157166
case USER_EVENT.DELETE:
158-
this.userDelete(eventJson);
167+
const userDeleteEvent = eventJson as UserDeleteEventWithQualifiedId;
168+
this.userDelete(userDeleteEvent);
159169
break;
160170
case USER_EVENT.UPDATE:
161171
await this.onUserUpdate(eventJson, source);
@@ -283,9 +293,9 @@ export class UserRepository extends TypedEventEmitter<Events> {
283293
/**
284294
* Event to delete the matching user.
285295
*/
286-
private userDelete({id}: {id: string}): void {
296+
private userDelete({qualified_id}: {qualified_id: QualifiedId}): void {
287297
// @todo Add user deletion cases for other users
288-
const isSelfUser = id === this.userState.self().id;
298+
const isSelfUser = matchQualifiedIds(qualified_id, this.userState.self()?.qualifiedId);
289299
if (isSelfUser) {
290300
// Info: Deletion of the user causes a database deletion which may interrupt currently running database operations.
291301
// That's why we added a timeout, to leave some time for the database to finish running reads/writes before the
@@ -294,6 +304,7 @@ export class UserRepository extends TypedEventEmitter<Events> {
294304
amplify.publish(WebAppEvents.LIFECYCLE.SIGN_OUT, SIGN_OUT_REASON.ACCOUNT_DELETED, true);
295305
}, 100);
296306
}
307+
this.emit('userDeleted', qualified_id);
297308
}
298309

299310
private async onUserUpdate(eventJson: UserUpdateEvent, source: EventSource): Promise<void> {

src/types/i18n.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,7 @@ declare module 'I18n/en-US.json' {
555555
'conversationLikesCaptionSingular': `[bold]{userName}[/bold]`;
556556
'conversationLocationLink': `Open Map`;
557557
'conversationMLSMigrationFinalisationOngoingCall': `Due to migration to MLS, you might have issues with your current call. If that\'s the case, hang up and call again.`;
558+
'conversationMemberDeleted': `This user is no longer available`;
558559
'conversationMemberJoined': `[bold]{name}[/bold] added {users} to the conversation`;
559560
'conversationMemberJoinedMore': `[bold]{name}[/bold] added {users}, and [showmore]{count} more[/showmore] to the conversation`;
560561
'conversationMemberJoinedSelf': `[bold]{name}[/bold] joined`;

0 commit comments

Comments
 (0)