set change detection on push
This commit is contained in:
@@ -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)',
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 }} → </span>
|
<span *ngIf="iSong.keyOriginal !== iSong.key">{{ iSong.keyOriginal }} → </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"
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user