optimize remote #2
This commit is contained in:
@@ -83,31 +83,40 @@ export class RemoteComponent implements OnDestroy {
|
||||
globalSettingsService: GlobalSettingsService,
|
||||
private cRef: ChangeDetectorRef
|
||||
) {
|
||||
globalSettingsService.get$
|
||||
const currentShowId$ = globalSettingsService.get$
|
||||
.pipe(
|
||||
filter((settings): settings is NonNullable<typeof settings> => !!settings),
|
||||
map(_ => _.currentShow),
|
||||
filter((showId): showId is string => !!showId),
|
||||
distinctUntilChanged(),
|
||||
switchMap(showId =>
|
||||
combineLatest([this.showService.read$(showId), this.showSongService.list$(showId)]).pipe(
|
||||
map(([show, list]) => {
|
||||
const presentationSongs = list.map(song => ({
|
||||
id: song.id,
|
||||
title: song.title,
|
||||
sections: this.textRenderingService.parse(song.text, null, false),
|
||||
}));
|
||||
return {show, list, presentationSongs};
|
||||
})
|
||||
)
|
||||
),
|
||||
takeUntil(this.destroy$)
|
||||
)
|
||||
.subscribe(({show, list, presentationSongs}) => {
|
||||
this.showSongs = list;
|
||||
);
|
||||
|
||||
const show$ = currentShowId$.pipe(
|
||||
switchMap(showId => this.showService.read$(showId)),
|
||||
takeUntil(this.destroy$)
|
||||
);
|
||||
|
||||
const parsedSongs$ = currentShowId$.pipe(
|
||||
switchMap(showId => this.showSongService.list$(showId)),
|
||||
map(list => ({
|
||||
list,
|
||||
parsed: list.map(song => ({
|
||||
id: song.id,
|
||||
title: song.title,
|
||||
sections: this.textRenderingService.parse(song.text, null, false),
|
||||
})),
|
||||
})),
|
||||
takeUntil(this.destroy$)
|
||||
);
|
||||
|
||||
combineLatest([show$, parsedSongs$])
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe(([show, parsedSongs]) => {
|
||||
this.showSongs = parsedSongs.list;
|
||||
this.show = show;
|
||||
const order = show?.order ?? [];
|
||||
const presentationSongsById = new Map(presentationSongs.map(song => [song.id, song] as const));
|
||||
const presentationSongsById = new Map(parsedSongs.parsed.map(song => [song.id, song] as const));
|
||||
this.presentationSongs = order.map(id => presentationSongsById.get(id) ?? null).filter((s): s is PresentationSong => !!s);
|
||||
this.cRef.markForCheck();
|
||||
});
|
||||
|
||||
@@ -60,12 +60,14 @@
|
||||
</swiper-slide>
|
||||
</swiper-container>
|
||||
|
||||
<app-add-song
|
||||
*ngIf="songs && !show.published && !useSwiper"
|
||||
[showSongs]="showSongs"
|
||||
[show]="show"
|
||||
[songs]="songs"
|
||||
></app-add-song>
|
||||
<ng-container *ngIf="songs$ | async as songs">
|
||||
<app-add-song
|
||||
*ngIf="songs && !show.published && !useSwiper"
|
||||
[showSongs]="showSongs"
|
||||
[show]="show"
|
||||
[songs]="songs"
|
||||
></app-add-song>
|
||||
</ng-container>
|
||||
|
||||
<app-button-row *ngIf="!useSwiper">
|
||||
<ng-container *appRole="['leader']">
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import {ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, HostListener, OnDestroy, OnInit} from '@angular/core';
|
||||
import {filter, map, switchMap, tap} from 'rxjs/operators';
|
||||
import {filter, map, shareReplay, switchMap, tap} from 'rxjs/operators';
|
||||
import {ActivatedRoute, Router} from '@angular/router';
|
||||
import {ShowService} from '../services/show.service';
|
||||
import {Observable, Subscription} from 'rxjs';
|
||||
import {Observable, of, Subscription} from 'rxjs';
|
||||
import {Show} from '../services/show';
|
||||
import {SongService} from '../../songs/services/song.service';
|
||||
import {Song} from '../../songs/services/song';
|
||||
@@ -83,7 +83,7 @@ import {ShowTypePipe} from '../../../widget-modules/pipes/show-type-translater/s
|
||||
})
|
||||
export class ShowComponent implements OnInit, OnDestroy {
|
||||
public show$: Observable<Show | null> | null = null;
|
||||
public songs: Song[] | null = null;
|
||||
public songs$: Observable<Song[] | null> | null = null;
|
||||
public showSongs: ShowSong[] | null = null;
|
||||
public showId: string | null = null;
|
||||
public showText = false;
|
||||
@@ -128,7 +128,11 @@ export class ShowComponent implements OnInit, OnDestroy {
|
||||
map(param => param as {showId: string}),
|
||||
map(param => param.showId),
|
||||
tap((_: string) => (this.showId = _)),
|
||||
switchMap((showId: string) => this.showService.read$(showId))
|
||||
switchMap((showId: string) => this.showService.read$(showId)),
|
||||
shareReplay({
|
||||
bufferSize: 1,
|
||||
refCount: true,
|
||||
})
|
||||
);
|
||||
this.subs.push(
|
||||
this.activatedRoute.params
|
||||
@@ -141,15 +145,16 @@ export class ShowComponent implements OnInit, OnDestroy {
|
||||
.subscribe(_ => {
|
||||
this.showSongs = _;
|
||||
this.cRef.markForCheck();
|
||||
}),
|
||||
this.songService
|
||||
.list$()
|
||||
.pipe(filter(_ => !!_))
|
||||
.subscribe(_ => {
|
||||
this.songs = _;
|
||||
this.cRef.markForCheck();
|
||||
})
|
||||
);
|
||||
|
||||
this.songs$ = this.show$.pipe(
|
||||
switchMap(show => (show && !show.published ? this.songService.list$() : of(null))),
|
||||
shareReplay({
|
||||
bufferSize: 1,
|
||||
refCount: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public ngOnDestroy(): void {
|
||||
@@ -217,7 +222,8 @@ export class ShowComponent implements OnInit, OnDestroy {
|
||||
public orderedShowSongs(show: Show): ShowSong[] {
|
||||
const list = this.showSongs;
|
||||
if (!list) return [];
|
||||
return show.order.map(_ => list.filter(f => f.id === _)[0]);
|
||||
const byId = new Map(list.map(item => [item.id, item] as const));
|
||||
return show.order.map(id => byId.get(id)).filter((song): song is ShowSong => !!song);
|
||||
}
|
||||
|
||||
public trackBy = (_: number, show: ShowSong) => show?.id;
|
||||
|
||||
@@ -5,6 +5,7 @@ import {SongService} from '../../services/song.service';
|
||||
import {Song} from '../../services/song';
|
||||
import {Router} from '@angular/router';
|
||||
import {Subscription} from 'rxjs';
|
||||
import {take} from 'rxjs/operators';
|
||||
import {CardComponent} from '../../../../widget-modules/components/card/card.component';
|
||||
import {MatFormField, MatLabel} from '@angular/material/form-field';
|
||||
import {MatInput} from '@angular/material/input';
|
||||
@@ -34,7 +35,7 @@ export class NewComponent implements OnInit, OnDestroy {
|
||||
this.form.reset();
|
||||
|
||||
this.subs.push(
|
||||
this.songService.list$().subscribe(songs => {
|
||||
this.songService.list$().pipe(take(1)).subscribe(songs => {
|
||||
const freeSongnumber = this.getFreeSongNumber(songs);
|
||||
this.form.controls.number.setValue(freeSongnumber);
|
||||
})
|
||||
|
||||
@@ -23,6 +23,7 @@ export class UserService {
|
||||
public users$ = this.db.col$<User>('users').pipe(shareReplay({bufferSize: 1, refCount: true}));
|
||||
private iUserId$ = new BehaviorSubject<string | null>(null);
|
||||
private iUser$ = new BehaviorSubject<User | null>(null);
|
||||
private userByIdCache = new Map<string, Observable<User | null>>();
|
||||
|
||||
public constructor(
|
||||
private afAuth: AngularFireAuth,
|
||||
@@ -52,7 +53,16 @@ export class UserService {
|
||||
public currentUser = async (): Promise<User | null> => firstValueFrom(this.user$);
|
||||
|
||||
public getUserbyId = (userId: string): Promise<User | null> => firstValueFrom(this.getUserbyId$(userId));
|
||||
public getUserbyId$ = (userId: string): Observable<User | null> => this.users$.pipe(map(_ => _.find(f => f.id === userId) || null));
|
||||
public getUserbyId$ = (userId: string): Observable<User | null> => {
|
||||
const cached = this.userByIdCache.get(userId);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
const user$ = this.db.doc$<User>(`users/${userId}`).pipe(shareReplay({bufferSize: 1, refCount: true}));
|
||||
this.userByIdCache.set(userId, user$);
|
||||
return user$;
|
||||
};
|
||||
|
||||
public async login(user: string, password: string): Promise<string | null> {
|
||||
const aUser = await this.afAuth.signInWithEmailAndPassword(user, password);
|
||||
|
||||
Reference in New Issue
Block a user