fix user cache
This commit is contained in:
parent
bdc86eb26c
commit
d8fd5028dd
@ -1,6 +1,7 @@
|
|||||||
import { Component, EventEmitter, OnChanges, OnInit, Output } from '@angular/core';
|
import { Component, EventEmitter, OnChanges, OnDestroy, OnInit, Output } from '@angular/core';
|
||||||
import { Channel } from '../../../models/channel';
|
import { Channel } from '../../../models/channel';
|
||||||
import { ChatService } from '../../../services/chat.service';
|
import { ChatService } from '../../../services/chat.service';
|
||||||
|
import { Subject, takeUntil } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-channel-list',
|
selector: 'app-channel-list',
|
||||||
@ -8,22 +9,30 @@ import { ChatService } from '../../../services/chat.service';
|
|||||||
templateUrl: './channel-list.component.html',
|
templateUrl: './channel-list.component.html',
|
||||||
styleUrl: './channel-list.component.scss'
|
styleUrl: './channel-list.component.scss'
|
||||||
})
|
})
|
||||||
export class ChannelListComponent implements OnInit {
|
export class ChannelListComponent implements OnInit, OnDestroy {
|
||||||
@Output("select") selectEmitter: EventEmitter<Channel> = new EventEmitter<Channel>();
|
@Output("select") selectEmitter: EventEmitter<Channel> = new EventEmitter<Channel>();
|
||||||
|
|
||||||
public channels!: Channel[];
|
public channels!: Channel[];
|
||||||
public selectedChannel?: Channel;
|
public selectedChannel?: Channel;
|
||||||
|
|
||||||
|
private destroy = new Subject<void>();
|
||||||
|
|
||||||
constructor(private chatService: ChatService) { }
|
constructor(private chatService: ChatService) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.chatService.ListChannels()
|
this.chatService.ListChannels()
|
||||||
|
.pipe(takeUntil(this.destroy))
|
||||||
.subscribe(channels => {
|
.subscribe(channels => {
|
||||||
this.channels = channels;
|
this.channels = channels;
|
||||||
this.selectedChannel = this.channels[0];
|
this.selectedChannel = this.channels[0];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.destroy.next();
|
||||||
|
this.destroy.complete();
|
||||||
|
}
|
||||||
|
|
||||||
public Select(index: number): void {
|
public Select(index: number): void {
|
||||||
this.selectEmitter.emit(this.selectedChannel = this.channels[index]);
|
this.selectEmitter.emit(this.selectedChannel = this.channels[index]);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, Input, OnChanges, OnInit } from '@angular/core';
|
import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Message } from '../../../models/message';
|
import { Message } from '../../../models/message';
|
||||||
import { ChatService } from '../../../services/chat.service';
|
import { ChatService } from '../../../services/chat.service';
|
||||||
import { UserService } from '../../../services/user.service';
|
import { UserService } from '../../../services/user.service';
|
||||||
@ -11,7 +11,7 @@ import { Subscription } from 'rxjs';
|
|||||||
templateUrl: './feed.component.html',
|
templateUrl: './feed.component.html',
|
||||||
styleUrl: './feed.component.scss'
|
styleUrl: './feed.component.scss'
|
||||||
})
|
})
|
||||||
export class FeedComponent implements OnChanges {
|
export class FeedComponent implements OnChanges, OnDestroy {
|
||||||
private readonly DEFAULT_CHANNEL_ID: number = 1;
|
private readonly DEFAULT_CHANNEL_ID: number = 1;
|
||||||
|
|
||||||
@Input('channel') public channel?: Channel;
|
@Input('channel') public channel?: Channel;
|
||||||
@ -19,7 +19,7 @@ export class FeedComponent implements OnChanges {
|
|||||||
|
|
||||||
public subscription?: Subscription;
|
public subscription?: Subscription;
|
||||||
|
|
||||||
constructor(private chatService: ChatService, private userService: UserService) { }
|
constructor(private chatService: ChatService) { }
|
||||||
|
|
||||||
ngOnChanges() {
|
ngOnChanges() {
|
||||||
if (this.subscription) {
|
if (this.subscription) {
|
||||||
@ -31,4 +31,10 @@ export class FeedComponent implements OnChanges {
|
|||||||
this.chatService.GetMessages(this.channel?.id ?? this.DEFAULT_CHANNEL_ID)
|
this.chatService.GetMessages(this.channel?.id ?? this.DEFAULT_CHANNEL_ID)
|
||||||
.subscribe(message => this.messages.push(message));
|
.subscribe(message => this.messages.push(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
if (this.subscription) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { UserService } from '../../../../../services/user.service';
|
import { UserService } from '../../../../../services/user.service';
|
||||||
import { ToastrService } from 'ngx-toastr';
|
import { ToastrService } from 'ngx-toastr';
|
||||||
|
import { Subject, takeUntil } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-profile-picture',
|
selector: 'app-profile-picture',
|
||||||
@ -8,14 +9,17 @@ import { ToastrService } from 'ngx-toastr';
|
|||||||
templateUrl: './profile-picture.component.html',
|
templateUrl: './profile-picture.component.html',
|
||||||
styleUrl: './profile-picture.component.scss'
|
styleUrl: './profile-picture.component.scss'
|
||||||
})
|
})
|
||||||
export class ProfilePictureComponent implements OnInit {
|
export class ProfilePictureComponent implements OnInit, OnDestroy {
|
||||||
@Input("username") public username!: string;
|
@Input("username") public username!: string;
|
||||||
public url?: string;
|
public url?: string;
|
||||||
|
|
||||||
|
private destroy: Subject<void> = new Subject<void>();
|
||||||
|
|
||||||
constructor(private userService: UserService, private toastrService: ToastrService) { }
|
constructor(private userService: UserService, private toastrService: ToastrService) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.userService.GetProfilePictureURL(this.username)
|
this.userService.GetProfilePictureURL(this.username)
|
||||||
|
.pipe(takeUntil(this.destroy))
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: url => this.url = url,
|
next: url => this.url = url,
|
||||||
error: _ => {
|
error: _ => {
|
||||||
@ -23,4 +27,9 @@ export class ProfilePictureComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.destroy.next();
|
||||||
|
this.destroy.complete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { catchError, map, Observable, throwError } from 'rxjs';
|
import { catchError, map, Observable, shareReplay, tap, throwError } from 'rxjs';
|
||||||
import { User } from '../models/user';
|
import { User } from '../models/user';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { UserInfoResponse } from './responses/user';
|
import { UserInfoResponse } from './responses/user';
|
||||||
@ -9,44 +9,38 @@ import { environment } from '../../environment/environment';
|
|||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class UserService {
|
export class UserService {
|
||||||
private users: Map<string, User> = new Map<string, User>();
|
private users: Map<string, Observable<User>> = new Map<string, Observable<User>>();
|
||||||
|
|
||||||
constructor(private http: HttpClient) { }
|
constructor(private http: HttpClient) { }
|
||||||
|
|
||||||
public GetUser(username: string): Observable<User> {
|
public GetUser(username: string): Observable<User> {
|
||||||
if (this.users.has(username)) {
|
let user = this.users.get(username);
|
||||||
return new Observable<User>(subscriber => {
|
if (user) {
|
||||||
subscriber.next(this.users.get(username)!);
|
return user;
|
||||||
subscriber.complete();
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
let url = `${environment.apiBase}/user/info/${username}`
|
let url = `${environment.apiBase}/user/info/${username}`
|
||||||
return this.http.get<UserInfoResponse>(url, { withCredentials: true }).pipe(
|
let observable = this.http.get<UserInfoResponse>(url, { withCredentials: true })
|
||||||
|
.pipe(
|
||||||
map(response => {
|
map(response => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
throw new Error(response.error);
|
throw new Error(response.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.user) {
|
if (response.user) {
|
||||||
this.users.set(username, response.user);
|
|
||||||
return response.user;
|
return response.user;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error("bad API response, missing user with no error");
|
throw new Error("bad API response, missing user with no error");
|
||||||
}),
|
}),
|
||||||
catchError(error => throwError(() => new Error(error.error.message)))
|
catchError(error => throwError(() => new Error(error.error.message))),
|
||||||
|
shareReplay({ bufferSize: 1, refCount: true })
|
||||||
);
|
);
|
||||||
|
this.users.set(username, observable);
|
||||||
|
return observable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public GetProfilePictureURL(username: string): Observable<string> {
|
public GetProfilePictureURL(username: string): Observable<string> {
|
||||||
if (this.users.has(username)) {
|
|
||||||
return new Observable<string>(subscriber => {
|
|
||||||
subscriber.next(this.users.get(username)!.picture);
|
|
||||||
subscriber.complete();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return this.GetUser(username).pipe(map(user => user.picture));
|
return this.GetUser(username).pipe(map(user => user.picture));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user