diff --git a/src/script/main/app.ts b/src/script/main/app.ts index 7580b3e5104..c1eeed579eb 100644 --- a/src/script/main/app.ts +++ b/src/script/main/app.ts @@ -409,7 +409,7 @@ export class App { await conversationRepository.conversationRoleRepository.loadTeamRoles(); - await userRepository.loadUsers(); + await userRepository.loadTeamUserAvailabilities(); await eventRepository.connectWebSocket(this.core, ({done, total}) => { const baseMessage = t('initDecryption'); diff --git a/src/script/user/UserRepository.ts b/src/script/user/UserRepository.ts index 796ca82dc0b..d20983f08a2 100644 --- a/src/script/user/UserRepository.ts +++ b/src/script/user/UserRepository.ts @@ -161,22 +161,32 @@ export class UserRepository { } }; - async loadUsers(): Promise { - if (this.userState.isTeam()) { - const users = await this.userService.loadUserFromDb(); - - if (users.length) { - this.logger.log(`Loaded state of '${users.length}' users from database`, users); + /** + * Will load the availability status to the team users and subscribe to changes. + */ + async loadTeamUserAvailabilities(): Promise { + const users = this.userState.users(); + if (this.userState.isTeam() && users.length) { + const availabilities = await this.userService.loadUserFromDb(); + + this.logger.log(`Loaded state of '${users.length}' users from database`, users); + /** availabilities we have in the DB that are not matching any loaded users */ + const orphanAvailabilities = availabilities.filter( + availability => !users.find(user => matchQualifiedIds(user.qualifiedId, availability)), + ); - await Promise.all( - users.map(async user => { - const userEntity = await this.getUserById({domain: user.domain, id: user.id}); - userEntity.availability(user.availability); - }), - ); - } + // Remove availabilities that are not linked to any loaded users + orphanAvailabilities.forEach(async availability => { + await this.userService.removeUserFromDb({id: availability.id, domain: availability.domain ?? ''}); + }); - this.userState.users().forEach(userEntity => userEntity.subscribeToChanges()); + users.forEach(user => { + const userAvailability = availabilities.find(availability => matchQualifiedIds(availability, user.qualifiedId)); + if (userAvailability) { + user.availability(userAvailability.availability); + } + user.subscribeToChanges(); + }); } } diff --git a/src/script/user/UserService.ts b/src/script/user/UserService.ts index db53bf4ef3b..747909ef311 100644 --- a/src/script/user/UserService.ts +++ b/src/script/user/UserService.ts @@ -28,6 +28,12 @@ import {StorageSchemata} from '../storage/StorageSchemata'; import {StorageService} from '../storage/StorageService'; import {constructUserPrimaryKey} from '../util/StorageUtil'; +type StoredUser = { + availability: number; + id: string; + domain?: string; +}; + export class UserService { private readonly logger: Logger; private readonly USER_STORE_NAME: string; @@ -49,8 +55,14 @@ export class UserService { * @todo There might be more keys which are returned by this function * @returns Resolves with all the stored user states */ - loadUserFromDb(): Promise<{availability: number; domain?: string; id: string}[]> { - return this.storageService.getAll(this.USER_STORE_NAME); + async loadUserFromDb(): Promise<{availability: number; domain: string; id: string}[]> { + const users = await this.storageService.getAll(this.USER_STORE_NAME); + return users.map(user => ({...user, domain: user.domain ?? ''})); + } + + async removeUserFromDb(user: {id: string; domain: string}): Promise { + const primaryKey = constructUserPrimaryKey(user); + await this.storageService.delete(this.USER_STORE_NAME, primaryKey); } /**