set change detection on push

This commit is contained in:
2023-03-26 23:34:49 +02:00
parent 138b0b42b3
commit 383d2a533b
13 changed files with 76 additions and 46 deletions

View File

@@ -32,7 +32,7 @@ export const fader = trigger('fader', [
':enter', ':enter',
[ [
animate( animate(
'200ms ease', '300ms ease',
style({ style({
opacity: 1, opacity: 1,
transform: 'scale(1) translateY(0)', transform: 'scale(1) translateY(0)',

View File

@@ -1,4 +1,4 @@
import {Component, OnInit, ViewChild} from '@angular/core'; import {ChangeDetectionStrategy, Component, OnInit, ViewChild} from '@angular/core';
import {fader} from './animations'; import {fader} from './animations';
import {ScrollService} from './services/scroll.service'; import {ScrollService} from './services/scroll.service';
import {PerfectScrollbarComponent} from 'ngx-perfect-scrollbar'; import {PerfectScrollbarComponent} from 'ngx-perfect-scrollbar';
@@ -8,6 +8,7 @@ import {PerfectScrollbarComponent} from 'ngx-perfect-scrollbar';
templateUrl: './app.component.html', templateUrl: './app.component.html',
styleUrls: ['./app.component.less'], styleUrls: ['./app.component.less'],
animations: [fader], animations: [fader],
changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class AppComponent implements OnInit { export class AppComponent implements OnInit {
@ViewChild('scrollbar', {static: false}) public scrollbar: PerfectScrollbarComponent | null = null; @ViewChild('scrollbar', {static: false}) public scrollbar: PerfectScrollbarComponent | null = null;

View File

@@ -1,4 +1,4 @@
<div class="brand"> <div class="brand">
<app-logo></app-logo> <app-logo></app-logo>
<div class="copyright">© 2022 - Benjamin Ifland</div> <div class="copyright">© 2019 - 2023 - Benjamin Ifland</div>
</div> </div>

View File

@@ -2,7 +2,7 @@
color: #fff; color: #fff;
opacity: 0.7; opacity: 0.7;
font-size: 20px; font-size: 20px;
transform: translate(173px, -40px); transform: translate(116px, -40px);
} }
.brand { .brand {

View File

@@ -1,4 +1,4 @@
import {Component, OnInit} from '@angular/core'; import {ChangeDetectorRef, Component, OnInit} from '@angular/core';
import {debounceTime, distinctUntilChanged, filter, map, switchMap, tap} from 'rxjs/operators'; import {debounceTime, distinctUntilChanged, filter, map, switchMap, tap} from 'rxjs/operators';
import {ShowService} from '../../shows/services/show.service'; import {ShowService} from '../../shows/services/show.service';
import {SongService} from '../../songs/services/song.service'; import {SongService} from '../../songs/services/song.service';
@@ -38,7 +38,8 @@ export class MonitorComponent implements OnInit {
private songService: SongService, private songService: SongService,
private textRenderingService: TextRenderingService, private textRenderingService: TextRenderingService,
private globalSettingsService: GlobalSettingsService, private globalSettingsService: GlobalSettingsService,
private configService: ConfigService private configService: ConfigService,
private cRef: ChangeDetectorRef
) { ) {
this.config$ = configService.get$(); this.config$ = configService.get$();
} }
@@ -66,7 +67,10 @@ export class MonitorComponent implements OnInit {
this.presentationDynamicText = _.presentationDynamicText; this.presentationDynamicText = _.presentationDynamicText;
this.zoom = _.presentationZoom ?? 30; this.zoom = _.presentationZoom ?? 30;
if (this.songId !== _.presentationSongId) this.songId = 'empty'; if (this.songId !== _.presentationSongId) this.songId = 'empty';
setTimeout(() => (this.songId = _.presentationSongId), 600); setTimeout(() => {
this.songId = _.presentationSongId;
this.cRef.markForCheck();
}, 600);
}), }),
switchMap((_: Show) => this.showSongService.read$(_.id, _.presentationSongId)), switchMap((_: Show) => this.showSongService.read$(_.id, _.presentationSongId)),
filter(_ => !!_), filter(_ => !!_),
@@ -74,6 +78,7 @@ export class MonitorComponent implements OnInit {
) )
.subscribe(_ => { .subscribe(_ => {
this.song = _; this.song = _;
this.cRef.markForCheck();
}); });
} }
} }

View File

@@ -19,6 +19,7 @@ import {AddSongModule} from '../../widget-modules/components/add-song/add-song.m
import {LogoComponent} from './monitor/logo/logo.component'; import {LogoComponent} from './monitor/logo/logo.component';
import {SelectComponent} from './select/select.component'; import {SelectComponent} from './select/select.component';
import {MatInputModule} from '@angular/material/input'; import {MatInputModule} from '@angular/material/input';
import {UserNameModule} from '../../services/user/user-name/user-name.module';
@NgModule({ @NgModule({
declarations: [MonitorComponent, RemoteComponent, LegalComponent, LogoComponent, SelectComponent], declarations: [MonitorComponent, RemoteComponent, LegalComponent, LogoComponent, SelectComponent],
@@ -39,6 +40,7 @@ import {MatInputModule} from '@angular/material/input';
AddSongModule, AddSongModule,
ReactiveFormsModule, ReactiveFormsModule,
MatInputModule, MatInputModule,
UserNameModule,
], ],
}) })
export class PresentationModule {} export class PresentationModule {}

View File

@@ -6,6 +6,8 @@
<div *ngIf="shows.length>0" class="list"> <div *ngIf="shows.length>0" class="list">
<button mat-stroked-button *ngFor="let show of shows" (click)="selectShow(show)"> <button mat-stroked-button *ngFor="let show of shows" (click)="selectShow(show)">
<app-user-name [userId]="show.owner"></app-user-name>
,
{{ show.showType | showType }}, {{ show.showType | showType }},
{{ show.date.toDate() | date: "dd.MM.yyyy" }} {{ show.date.toDate() | date: "dd.MM.yyyy" }}
</button> </button>

View File

@@ -1,5 +1,5 @@
.list { .list {
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 10px; gap: 10px;
} }

View File

@@ -1,8 +1,8 @@
import {Component, OnInit} from '@angular/core'; import {ChangeDetectorRef, Component, OnDestroy, OnInit} from '@angular/core';
import {filter, map, switchMap, tap} from 'rxjs/operators'; import {filter, map, switchMap, tap} from 'rxjs/operators';
import {ActivatedRoute, Router} from '@angular/router'; import {ActivatedRoute, Router} from '@angular/router';
import {ShowService} from '../services/show.service'; import {ShowService} from '../services/show.service';
import {Observable} from 'rxjs'; import {Observable, Subscription} from 'rxjs';
import {Show} from '../services/show'; import {Show} from '../services/show';
import {SongService} from '../../songs/services/song.service'; import {SongService} from '../../songs/services/song.service';
import {Song} from '../../songs/services/song'; import {Song} from '../../songs/services/song';
@@ -30,7 +30,7 @@ import {fade} from '../../../animations';
styleUrls: ['./show.component.less'], styleUrls: ['./show.component.less'],
animations: [fade], animations: [fade],
}) })
export class ShowComponent implements OnInit { export class ShowComponent implements OnInit, OnDestroy {
public show$: Observable<Show | null> | null = null; public show$: Observable<Show | null> | null = null;
public songs: Song[] | null = null; public songs: Song[] | null = null;
public showSongs: ShowSong[] | null = null; public showSongs: ShowSong[] | null = null;
@@ -47,6 +47,7 @@ export class ShowComponent implements OnInit {
public faUsers = faUsers; public faUsers = faUsers;
public faZoomIn = faMagnifyingGlassPlus; public faZoomIn = faMagnifyingGlassPlus;
public faZoomOut = faMagnifyingGlassMinus; public faZoomOut = faMagnifyingGlassMinus;
private subs: Subscription[] = [];
public constructor( public constructor(
private activatedRoute: ActivatedRoute, private activatedRoute: ActivatedRoute,
@@ -54,7 +55,8 @@ export class ShowComponent implements OnInit {
private songService: SongService, private songService: SongService,
private showSongService: ShowSongService, private showSongService: ShowSongService,
private docxService: DocxService, private docxService: DocxService,
private router: Router private router: Router,
private cRef: ChangeDetectorRef
) {} ) {}
public ngOnInit(): void { public ngOnInit(): void {
@@ -64,19 +66,30 @@ export class ShowComponent implements OnInit {
tap((_: string) => (this.showId = _)), tap((_: string) => (this.showId = _)),
switchMap((showId: string) => this.showService.read$(showId)) switchMap((showId: string) => this.showService.read$(showId))
); );
this.activatedRoute.params this.subs.push(
.pipe( this.activatedRoute.params
map(param => param as {showId: string}), .pipe(
map(param => param.showId), map(param => param as {showId: string}),
switchMap(showId => this.showSongService.list$(showId)), map(param => param.showId),
tap(_ => console.log(_)), switchMap(showId => this.showSongService.list$(showId)),
filter(_ => !!_ && _.length > 0) filter(_ => !!_ && _.length > 0)
) )
.subscribe(_ => (this.showSongs = _)); .subscribe(_ => {
this.songService this.showSongs = _;
.list$() this.cRef.markForCheck();
.pipe(filter(_ => !!_)) }),
.subscribe(_ => (this.songs = _)); this.songService
.list$()
.pipe(filter(_ => !!_))
.subscribe(_ => {
this.songs = _;
this.cRef.markForCheck();
})
);
}
public ngOnDestroy(): void {
this.subs.forEach(_ => _.unsubscribe());
} }
public textSize = 1; public textSize = 1;
@@ -89,12 +102,6 @@ export class ShowComponent implements OnInit {
this.textSize -= 0.1; this.textSize -= 0.1;
} }
public getSong(songId: string): Song | null {
if (!this.songs) return null;
const filtered = this.songs.filter(_ => _.id === songId);
return filtered.length > 0 ? filtered[0] : null;
}
public async onArchive(archived: boolean): Promise<void> { public async onArchive(archived: boolean): Promise<void> {
if (this.showId != null) await this.showService.update$(this.showId, {archived}); if (this.showId != null) await this.showService.update$(this.showId, {archived});
} }

View File

@@ -1,9 +1,12 @@
<div *ngIf="iSong && iSong && show"> <div *ngIf="iSong && iSong && show">
<div @fade *ngIf="show.published" class="title published">{{ iSong.key }} - {{ iSong.title }}</div> <div *ngIf="show.published" class="title published">
<div class="key">{{ iSong.key }}</div>
<div>{{ iSong.title }}</div>
</div>
<div @fade *ngIf="!show.published" class="song"> <div *ngIf="!show.published" class="song">
<span class="title">{{ iSong.title }}</span> <span class="title">{{ iSong.title }}</span>
<span @fade class="keys" *ngIf="!edit"> <span *ngIf="!edit" class="keys">
<span *ngIf="iSong.keyOriginal !== iSong.key">{{ iSong.keyOriginal }}&nbsp;&nbsp;</span> <span *ngIf="iSong.keyOriginal !== iSong.key">{{ iSong.keyOriginal }}&nbsp;&nbsp;</span>
<mat-form-field *ngIf="keys" appearance="standard" class="keys"> <mat-form-field *ngIf="keys" appearance="standard" class="keys">
<mat-select [formControl]="keyFormControl"> <mat-select [formControl]="keyFormControl">
@@ -11,26 +14,27 @@
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
</span> </span>
<app-menu-button @fade *ngIf="!edit" (click)="onEdit()" [icon]="faEdit" class="btn-edit btn-icon" matTooltip="Lied für diese Veranstaltung bearbeiten"> </app-menu-button> <app-menu-button (click)="onEdit()" *ngIf="!edit" [icon]="faEdit" class="btn-edit btn-icon"
<app-menu-button @fade *ngIf="!edit" (click)="onDelete()" [icon]="faDelete" class="btn-delete btn-icon" matTooltip="Lied aus Veranstaltung entfernen"></app-menu-button> matTooltip="Lied für diese Veranstaltung bearbeiten"></app-menu-button>
<app-menu-button (click)="onDelete()" *ngIf="!edit" [icon]="faDelete" class="btn-delete btn-icon"
matTooltip="Lied aus Veranstaltung entfernen"></app-menu-button>
</div> </div>
<mat-form-field @fade appearance="outline" *ngIf="edit" > <mat-form-field *ngIf="edit" appearance="outline">
<mat-label>Songtext</mat-label> <mat-label>Songtext</mat-label>
<textarea matTooltip="Tonart ändern" <textarea matTooltip="Tonart ändern"
[cdkTextareaAutosize]="true" [cdkTextareaAutosize]="true"
[formControl]="editSongControl" [formControl]="editSongControl"
matInput matInput
></textarea> ></textarea>
</mat-form-field> </mat-form-field>
<div @fade *ngIf="edit">Es wird nur der Liedtext für dieser Veranstaltung geändert.</div> <div *ngIf="edit">Es wird nur der Liedtext für dieser Veranstaltung geändert.</div>
<app-button-row @fade *ngIf="edit"> <app-button-row *ngIf="edit">
<app-button (click)="onSave()" [icon]="faSave">Speichern</app-button> <app-button (click)="onSave()" [icon]="faSave">Speichern</app-button>
<app-button (click)="onDiscard()" [icon]="faEraser">Verwerfen</app-button> <app-button (click)="onDiscard()" [icon]="faEraser">Verwerfen</app-button>
</app-button-row> </app-button-row>
<app-song-text <app-song-text
@fade
(chordModeChanged)="onChordModeChanged($event)" (chordModeChanged)="onChordModeChanged($event)"
*ngIf="!edit && (showText )" *ngIf="!edit && (showText )"
[chordMode]="iSong.chordMode" [chordMode]="iSong.chordMode"

View File

@@ -35,6 +35,13 @@
&.published { &.published {
margin: 10px 0; margin: 10px 0;
font-weight: bold; font-weight: bold;
display: grid;
grid-template-columns: 1em auto;
.key {
color: #00b;
text-shadow: 0 0 1px #00b;
}
} }
} }

View File

@@ -1,4 +1,4 @@
import {Component, Input} from '@angular/core'; import {ChangeDetectionStrategy, Component, Input} from '@angular/core';
import {UntypedFormControl} from '@angular/forms'; import {UntypedFormControl} from '@angular/forms';
import {filterSong} from '../../../services/filter.helper'; import {filterSong} from '../../../services/filter.helper';
import {MatSelectChange} from '@angular/material/select'; import {MatSelectChange} from '@angular/material/select';
@@ -12,6 +12,7 @@ import {ShowService} from '../../../modules/shows/services/show.service';
selector: 'app-add-song', selector: 'app-add-song',
templateUrl: './add-song.component.html', templateUrl: './add-song.component.html',
styleUrls: ['./add-song.component.less'], styleUrls: ['./add-song.component.less'],
changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class AddSongComponent { export class AddSongComponent {
@Input() public songs: Song[] | null = null; @Input() public songs: Song[] | null = null;

View File

@@ -3,16 +3,17 @@
.card { .card {
margin: 20px; margin: 20px;
border-radius: 8px; border-radius: 8px;
background: #fffe; background: #fffc;
backdrop-filter: blur(12px); backdrop-filter: blur(12px);
overflow: hidden; overflow: hidden;
width: 800px; width: 800px;
position: relative; position: relative;
transition: all 150ms ease-in-out;
@media screen and (max-width: 860px) { @media screen and (max-width: 860px) {
width: 100vw; width: 100vw;
border-radius: 0; border-radius: 0;
background: #fffe; background: #ffff;
margin: 0; margin: 0;
} }