diff --git a/src/i18n/en-US.json b/src/i18n/en-US.json index 4def5251056..e80ea5bb39b 100644 --- a/src/i18n/en-US.json +++ b/src/i18n/en-US.json @@ -650,7 +650,6 @@ "dataSharingModalDecline": "Decline", "dataSharingModalDescription": "Help to improve Wire by sharing your usage data via a pseudonymous ID. The data is neither linked to your personal information nor shared with third parties besides Wire Group. It includes, for example, when you use a feature, your app version, device type, or your operating system. This data will be deleted at the latest after 365 days.
Find further details in ourĀ [link]Privacy Policy[/link]. You can revoke your consent at any time.", "dataSharingModalTitle": "Consent to share user data", - "deletedUser": "Deleted User", "downloadLatestMLS": "Download the latest MLS Wire version", "enumerationAnd": ", and ", "ephemeralRemaining": "remaining", diff --git a/src/script/user/UserRepository.test.ts b/src/script/user/UserRepository.test.ts index 2854fd27524..30b8d438ec3 100644 --- a/src/script/user/UserRepository.test.ts +++ b/src/script/user/UserRepository.test.ts @@ -252,7 +252,7 @@ describe('UserRepository', () => { beforeEach(async () => { [userRepository, {userState, userService}] = await buildUserRepository(); jest.resetAllMocks(); - jest.spyOn(userService, 'loadUsersFromDb').mockResolvedValue(localUsers); + jest.spyOn(userService, 'loadUserFromDb').mockResolvedValue(localUsers); const selfUser = new User('self'); selfUser.isMe = true; userState.self(selfUser); @@ -290,19 +290,11 @@ describe('UserRepository', () => { const userIds = localUsers.map(user => user.qualified_id!); const connections = createConnections(localUsers); const partialUsers = [ - { - id: userIds[0].id, - availability: Availability.Type.AVAILABLE, - qualified_id: userIds[0], - }, - { - id: userIds[1].id, - availability: Availability.Type.BUSY, - qualified_id: userIds[1], - }, + {id: userIds[0].id, availability: Availability.Type.AVAILABLE}, + {id: userIds[1].id, availability: Availability.Type.BUSY}, ]; - jest.spyOn(userRepository['userService'], 'loadUsersFromDb').mockResolvedValue(partialUsers as any); + jest.spyOn(userRepository['userService'], 'loadUserFromDb').mockResolvedValue(partialUsers as any); const fetchUserSpy = jest.spyOn(userService, 'getUsers').mockResolvedValue({found: localUsers}); await userRepository.loadUsers(new User('self'), connections, [], []); diff --git a/src/script/user/UserRepository.ts b/src/script/user/UserRepository.ts index 5b5aefde731..0053823d01d 100644 --- a/src/script/user/UserRepository.ts +++ b/src/script/user/UserRepository.ts @@ -216,36 +216,26 @@ export class UserRepository extends TypedEventEmitter { // the entries we get back will be used to feed the availabilities of those users const nonQualifiedUsers = await this.userService.clearNonQualifiedUsers(); - const dbUsers = await this.userService.loadUsersFromDb(); + const dbUsers = await this.userService.loadUserFromDb(); // The self user doesn't need to be re-fetched const usersToFetch = users.filter(user => !matchQualifiedIds(selfUser.qualifiedId, user)); const {found, failed} = await this.fetchRawUsers(usersToFetch, selfUser.domain); - const usersWithAvailability = found.map(user => { - const localUser = dbUsers.find( - dbUser => dbUser.id === user.id || matchQualifiedIds(dbUser.qualified_id, user.qualified_id), - ); - - const userWithAvailability = [...dbUsers, ...nonQualifiedUsers].find(userRecord => userRecord.id === user.id); - - const userWithEscapedDefaultName = this.replaceDeletedUserNameWithNameInDb(user, localUser); + const userWithAvailability = found.map(user => { + const availability = [...dbUsers, ...nonQualifiedUsers].find(userRecord => userRecord.id === user.id); - if (userWithAvailability) { - return { - availability: userWithAvailability.availability, - ...userWithEscapedDefaultName, - }; + if (availability) { + return {availability: availability.availability, ...user}; } - - return userWithEscapedDefaultName; + return user; }); // Save all new users to the database - await Promise.all(usersWithAvailability.map(user => this.saveUserInDb(user))); + await Promise.all(userWithAvailability.map(user => this.saveUserInDb(user))); - const mappedUsers = this.mapUserResponse(usersWithAvailability, failed, dbUsers); + const mappedUsers = this.mapUserResponse(userWithAvailability, failed, dbUsers); // Assign connections to users mappedUsers.forEach(user => { @@ -333,14 +323,6 @@ export class UserRepository extends TypedEventEmitter { * Will update the user both in database and in memory. */ private async updateUser(userId: QualifiedId, user: Partial, isWebSocket = false): Promise { - if (user.deleted && user.name) { - const dbUser = await this.userService.loadUserFromDb(userId); - - if (dbUser && dbUser.name) { - user.name = dbUser.name; - } - } - const selfUser = this.userState.self(); const isSelfUser = matchQualifiedIds(userId, selfUser.qualifiedId); const userEntity = isSelfUser ? selfUser : await this.getUserById(userId); @@ -593,19 +575,23 @@ export class UserRepository extends TypedEventEmitter { } // Replaces a deleted user name ("default") with the name from the local database. - private replaceDeletedUserNameWithNameInDb(user: APIClientUser, localUser?: UserRecord): UserRecord { - if (!user.deleted) { - return user; - } + private restoreDeletedUserNames(apiUsers: APIClientUser[], dbUsers: UserRecord[]): UserRecord[] { + return apiUsers.map(user => { + if (!user.deleted) { + return user; + } - if (localUser && localUser.name) { - return { - ...user, - name: localUser.name, - }; - } + const localUser = dbUsers.find(dbUser => dbUser.id === user.id); + + if (localUser && localUser.name) { + return { + ...user, + name: localUser.name, + }; + } - return {...user, name: t('deletedUser')}; + return user; + }); } private mapUserResponse(found: APIClientUser[], failed: QualifiedId[], dbUsers: UserRecord[]): User[] { @@ -629,7 +615,9 @@ export class UserRepository extends TypedEventEmitter { return new User(userId.id, userId.domain); }); - const mappedUsers = this.userMapper.mapUsersFromJson(found, selfDomain).concat(failedToLoad); + const users = this.restoreDeletedUserNames(found, dbUsers); + + const mappedUsers = this.userMapper.mapUsersFromJson(users, selfDomain).concat(failedToLoad); if (this.teamState.isTeam()) { this.mapGuestStatus(mappedUsers); @@ -645,7 +633,7 @@ export class UserRepository extends TypedEventEmitter { */ private async fetchUsers(userIds: QualifiedId[]): Promise { const {found, failed} = await this.fetchRawUsers(userIds, this.userState.self().domain); - const dbUsers = await this.userService.loadUsersFromDb(); + const dbUsers = await this.userService.loadUserFromDb(); const users = this.mapUserResponse(found, failed, dbUsers); let fetchedUserEntities = this.saveUsers(users); @@ -725,7 +713,6 @@ export class UserRepository extends TypedEventEmitter { if (localOnly) { const deletedUser = new User(userId.id, userId.domain); deletedUser.isDeleted = true; - deletedUser.name(t('deletedUser')); return deletedUser; } try { diff --git a/src/script/user/UserService.ts b/src/script/user/UserService.ts index 812edb30aba..9d16b1350b0 100644 --- a/src/script/user/UserService.ts +++ b/src/script/user/UserService.ts @@ -58,20 +58,10 @@ export class UserService { * @todo There might be more keys which are returned by this function * @returns Resolves with all the stored user states */ - loadUsersFromDb(): Promise { + loadUserFromDb(): Promise { return this.storageService.getAll(this.USER_STORE_NAME); } - /** - * Loads user from the local database - * @returns Resolves to the stored user, if it does not exists resolves to undefined - */ - loadUserFromDb(qualifiedId: QualifiedId): Promise { - const primaryKey = constructUserPrimaryKey(qualifiedId); - - return this.storageService.load(this.USER_STORE_NAME, primaryKey); - } - /** * Will remove all the non-qualified entries in the DB */ diff --git a/src/types/i18n.d.ts b/src/types/i18n.d.ts index 2431e8dc617..0cf0f842adf 100644 --- a/src/types/i18n.d.ts +++ b/src/types/i18n.d.ts @@ -443,11 +443,11 @@ declare module 'I18n/en-US.json' { 'conversationDetailsActionConversationParticipants': `Show all ({number})`; 'conversationDetailsActionCreateGroup': `Create group`; 'conversationDetailsActionDelete': `Delete group`; - 'conversationDetailsActionDeleteForMe': `Delete for Me`; 'conversationDetailsActionDevices': `Devices`; 'conversationDetailsActionGuestOptions': `Guests`; 'conversationDetailsActionLeave': `Leave group`; 'conversationDetailsActionNotifications': `Notifications`; + 'conversationDetailsActionDeleteForMe': `Delete for Me`; 'conversationDetailsActionServicesOptions': `Services`; 'conversationDetailsActionTimedMessages': `Self-deleting messages`; 'conversationDetailsActionUnblock': `Unblock`; @@ -654,7 +654,6 @@ declare module 'I18n/en-US.json' { 'dataSharingModalDecline': `Decline`; 'dataSharingModalDescription': `Help to improve Wire by sharing your usage data via a pseudonymous ID. The data is neither linked to your personal information nor shared with third parties besides Wire Group. It includes, for example, when you use a feature, your app version, device type, or your operating system. This data will be deleted at the latest after 365 days.
Find further details in ourĀ [link]Privacy Policy[/link]. You can revoke your consent at any time.`; 'dataSharingModalTitle': `Consent to share user data`; - 'deletedUser': `Deleted User`; 'downloadLatestMLS': `Download the latest MLS Wire version`; 'enumerationAnd': `, and `; 'ephemeralRemaining': `remaining`;