diff --git a/src/main/angular/src/app/api/User/events/UserLogoutEvent.ts b/src/main/angular/src/app/api/User/events/UserLogoutEvent.ts new file mode 100644 index 0000000..9446d51 --- /dev/null +++ b/src/main/angular/src/app/api/User/events/UserLogoutEvent.ts @@ -0,0 +1,7 @@ +export class UserLogoutEvent { + + static fromJson(_: any): UserLogoutEvent { + return new UserLogoutEvent(); + } + +} diff --git a/src/main/angular/src/app/api/User/user.service.ts b/src/main/angular/src/app/api/User/user.service.ts index 596e915..976cd2e 100644 --- a/src/main/angular/src/app/api/User/user.service.ts +++ b/src/main/angular/src/app/api/User/user.service.ts @@ -3,13 +3,14 @@ import {ApiService} from "../common/api.service"; import {UserPrivate} from "./UserPrivate"; import {Next} from "../common/types"; import {UserPublic} from "./UserPublic"; -import {EventType, Router} from "@angular/router"; -import {BehaviorSubject, filter, map, Subject, Subscription} from "rxjs"; +import {Router} from "@angular/router"; +import {filter, map, Subject, Subscription} from "rxjs"; import {Group} from "../group/Group"; import {StompService} from "@stomp/ng2-stompjs"; import {Numbers} from "../tools/Numbers/Numbers"; import {GroupDeletedEvent} from "../group/events/GroupDeletedEvent"; import {GroupLeftEvent} from "../group/events/GroupLeftEvent"; +import {UserLogoutEvent} from "./events/UserLogoutEvent"; function userPushMessageFromJson(json: any): object { const type = json['_type_']; @@ -18,6 +19,8 @@ function userPushMessageFromJson(json: any): object { return Numbers.fromJson(json['payload']); case 'UserPrivateDto': return UserPrivate.fromJson(json['payload']); + case 'UserLogoutEvent': + return UserLogoutEvent.fromJson(json['payload']); case 'GroupDto': return Group.fromJson(json['payload']); case 'GroupDeletedEvent': @@ -33,14 +36,14 @@ function userPushMessageFromJson(json: any): object { }) export class UserService { - private readonly subject: BehaviorSubject = new BehaviorSubject(null); - private readonly pushSubject: Subject = new Subject(); - private userSubscriptions: Subscription[] = []; + private readonly subs: Subscription[] = []; + + private _user: UserPrivate | null = null; get user(): UserPrivate | null { - return this.subject.value; + return this._user; } constructor( @@ -48,12 +51,26 @@ export class UserService { protected readonly api: ApiService, protected readonly stompService: StompService, ) { - this.router.events.subscribe(e => { - if (e.type === EventType.NavigationEnd || e.type === EventType.NavigationSkipped) { - this.refresh(); + this.stompService.connected$.subscribe(() => this.fetchUser()); + + this.fetchUser() + this.subscribePush(UserPrivate, user => this.setUser(user)); + this.subscribePush(UserLogoutEvent, _ => this.setUser(null)); + } + + private fetchUser() { + this.api.getSingle(['User', 'whoAmI'], UserPrivate.fromJson, user => this.setUser(user)); + } + + private setUser(user: UserPrivate | null) { + if (!this.user?.is(user)) { + this.subs.forEach(sub => sub.unsubscribe()); + this.subs.length = 0; + if (user) { + this.subs.push(this.stompService.subscribe('User/' + user.privateUuid).pipe(map(m => userPushMessageFromJson(JSON.parse(m.body)))).subscribe(m => this.pushSubject.next(m))); } - }); - this.stompService.connected$.subscribe(() => this.refresh()); + } + this._user = user; } getByPublicUuid(publicUuid: any, next: Next) { @@ -76,29 +93,10 @@ export class UserService { this.router.navigate(['User', user.publicUuid]); } - refresh() { - this.api.getSingle(['User', 'whoAmI'], UserPrivate.fromJsonOrNull, user => this.setUser(user)); - } - - subscribe(next: Next): Subscription { - return this.subject.subscribe(next); - } - iOwn(group: Group): boolean { return group.owner.is(this.user); } - private setUser(user: UserPrivate | null) { - if (user === null || this.subject.value?.privateUuid !== user.privateUuid) { - this.userSubscriptions.forEach(subscription => subscription.unsubscribe()); - this.userSubscriptions.length = 0; - if (user) { - this.userSubscriptions.push(this.api.subscribe(["User", user.privateUuid], userPushMessageFromJson, message => this.pushSubject.next(message))); - } - } - this.subject.next(user); - } - iAm(user: UserPublic | UserPrivate | null) { return this.user !== null && this.user.is(user); } @@ -111,5 +109,4 @@ export class UserService { ) .subscribe(next); } - } diff --git a/src/main/angular/src/app/app.component.html b/src/main/angular/src/app/app.component.html index 03e77e6..93f2f76 100644 --- a/src/main/angular/src/app/app.component.html +++ b/src/main/angular/src/app/app.component.html @@ -2,8 +2,8 @@ - - + + diff --git a/src/main/angular/src/app/app.component.ts b/src/main/angular/src/app/app.component.ts index af816fc..5f4563e 100644 --- a/src/main/angular/src/app/app.component.ts +++ b/src/main/angular/src/app/app.component.ts @@ -2,7 +2,6 @@ import {Component, OnDestroy, OnInit} from '@angular/core'; import {Router, RouterLink, RouterLinkActive, RouterOutlet} from '@angular/router'; import {NgIf} from "@angular/common"; import {UserService} from "./api/User/user.service"; -import {UserPrivate} from "./api/User/UserPrivate"; import {Subscription} from "rxjs"; @Component({ @@ -14,12 +13,10 @@ import {Subscription} from "rxjs"; }) export class AppComponent implements OnInit, OnDestroy { - private readonly subscriptions: Subscription[] = []; + private readonly subs: Subscription[] = []; protected menuVisible = true; - protected user: UserPrivate | null = null; - constructor( protected readonly router: Router, protected readonly userService: UserService, @@ -32,16 +29,12 @@ export class AppComponent implements OnInit, OnDestroy { } ngOnInit(): void { - this.subscriptions.push(this.userService.subscribe(user => { - if (this.user !== null && user === null) { - this.router.navigate(['']); - } - this.user = user; - })); + // - } ngOnDestroy(): void { - this.subscriptions.forEach(subscription => subscription.unsubscribe()); + this.subs.forEach(sub => sub.unsubscribe()); + this.subs.length = 0; } } diff --git a/src/main/angular/src/app/pages/group/group/group.component.ts b/src/main/angular/src/app/pages/group/group/group.component.ts index 6945625..4dbdddf 100644 --- a/src/main/angular/src/app/pages/group/group/group.component.ts +++ b/src/main/angular/src/app/pages/group/group/group.component.ts @@ -95,12 +95,16 @@ export class GroupComponent implements OnInit, OnDestroy { ngOnDestroy(): void { this.subs.forEach(sub => sub.unsubscribe()); + this.subs.length=0; + this.userSubs.forEach(sub => sub.unsubscribe()); + this.userSubs.length=0; } private setGroup(group: Group) { this.group = group; this.userSubs.forEach(sub => sub.unsubscribe()); + this.userSubs.length = 0; if (this.group !== null) { this.group.users.forEach(_ => this.userSubs.push(this.userService.subscribePush(UserPublic, u => this.updateUser(u)))); } diff --git a/src/main/angular/src/app/pages/group/groups/groups.component.ts b/src/main/angular/src/app/pages/group/groups/groups.component.ts index 020675e..58c6024 100644 --- a/src/main/angular/src/app/pages/group/groups/groups.component.ts +++ b/src/main/angular/src/app/pages/group/groups/groups.component.ts @@ -42,6 +42,7 @@ export class GroupsComponent implements OnInit, OnDestroy { ngOnDestroy(): void { this.subs.forEach(sub => sub.unsubscribe()); + this.subs.length = 0; } private updateGroups() { diff --git a/src/main/angular/src/app/pages/profile/profile.component.ts b/src/main/angular/src/app/pages/profile/profile.component.ts index 65afe09..2659b69 100644 --- a/src/main/angular/src/app/pages/profile/profile.component.ts +++ b/src/main/angular/src/app/pages/profile/profile.component.ts @@ -7,6 +7,7 @@ import {GroupListComponent} from "../group/shared/group-list/group-list.componen import {Group} from "../../api/group/Group"; import {Subscription} from "rxjs"; import {GroupService} from "../../api/group/group.service"; +import {UserPrivate} from "../../api/User/UserPrivate"; const USER_NAME_MIN_LENGTH = 2; @@ -31,7 +32,7 @@ export class ProfileComponent implements OnInit, OnDestroy { protected readonly USER_PASSWORD_MIN_LENGTH = USER_PASSWORD_MIN_LENGTH; - private readonly subscriptions: Subscription[] = []; + private readonly subs: Subscription[] = []; protected password0: string = ""; @@ -50,13 +51,14 @@ export class ProfileComponent implements OnInit, OnDestroy { } ngOnInit(): void { - this.subscriptions.push(this.userService.subscribe(_ => { + this.subs.push(this.userService.subscribePush(UserPrivate, _ => { this.groupService.findAllJoined(groups => this.groups = groups); })); } ngOnDestroy(): void { - this.subscriptions.forEach(subscription => subscription.unsubscribe()); + this.subs.forEach(sub => sub.unsubscribe()); + this.subs.length = 0; } protected nameValidator(name: string): boolean {