fix styling

This commit is contained in:
2026-04-27 22:02:15 +02:00
parent 8bfbe7b1cc
commit 30115da841
37 changed files with 740 additions and 578 deletions

View File

@@ -1,119 +1,130 @@
@if (show) {
<app-card [closeIcon]="faIcon" [heading]="show.showType | showType" [subheading]="show.date.toDate() | date:'dd.MM.yyyy'" closeLink="/presentation/select">
@if (!progress) {
<div class="song">
@if (show) {
<div class="song-parts">
<div
(click)="onSectionClick('title', -1, show.id)"
(keydown.enter)="onSectionClick('title', -1, show.id)"
(keydown.space)="onSectionClick('title', -1, show.id)"
[class.active]="show.presentationSongId === 'title'"
class="song-part"
role="button"
tabindex="0"
>
<div class="head">Veranstaltung</div>
</div>
<div
(click)="onSectionClick('empty', -1, show.id)"
(keydown.enter)="onSectionClick('empty', -1, show.id)"
(keydown.space)="onSectionClick('empty', -1, show.id)"
[class.active]="show.presentationSongId === 'empty'"
class="song-part"
role="button"
tabindex="0"
>
<div class="head">Leer</div>
</div>
</div>
}
</div>
@for (song of presentationSongs; track trackBy($index, song)) {
<div class="song">
@if (show) {
<div [class.active]="show.presentationSongId === song.id" class="title song-part">
<div
(click)="onSectionClick(song.id, -1, show.id)"
(keydown.enter)="onSectionClick(song.id, -1, show.id)"
(keydown.space)="onSectionClick(song.id, -1, show.id)"
class="head"
role="button"
tabindex="0"
>
{{ song.title }}
</div>
</div>
} @if (show) {
<div class="song-parts">
@for (section of song.sections; track section.type + '-' + section.number + '-' + $index; let i = $index) {
<div
(click)="onSectionClick(song.id, i, show.id)"
(keydown.enter)="onSectionClick(song.id, i, show.id)"
(keydown.space)="onSectionClick(song.id, i, show.id)"
[class.active]="
<app-page-frame title="Präsentation" [withMenu]="false">
@if (show) {
<app-card [closeIcon]="faIcon"
[heading]="show.showType | showType"
[subheading]="show.date.toDate() | date:'dd.MM.yyyy'"
closeLink="/presentation/select"
content>
@if (!progress) {
<div class="song">
@if (show) {
<div class="song-parts">
<div
(click)="onSectionClick('title', -1, show.id)"
(keydown.enter)="onSectionClick('title', -1, show.id)"
(keydown.space)="onSectionClick('title', -1, show.id)"
[class.active]="show.presentationSongId === 'title'"
class="song-part"
role="button"
tabindex="0"
>
<div class="head">Veranstaltung</div>
</div>
<div
(click)="onSectionClick('empty', -1, show.id)"
(keydown.enter)="onSectionClick('empty', -1, show.id)"
(keydown.space)="onSectionClick('empty', -1, show.id)"
[class.active]="show.presentationSongId === 'empty'"
class="song-part"
role="button"
tabindex="0"
>
<div class="head">Leer</div>
</div>
</div>
}
</div>
@for (song of presentationSongs; track trackBy($index, song)) {
<div class="song">
@if (show) {
<div [class.active]="show.presentationSongId === song.id" class="title song-part">
<div
(click)="onSectionClick(song.id, -1, show.id)"
(keydown.enter)="onSectionClick(song.id, -1, show.id)"
(keydown.space)="onSectionClick(song.id, -1, show.id)"
class="head"
role="button"
tabindex="0"
>
{{ song.title }}
</div>
</div>
}
@if (show) {
<div class="song-parts">
@for (section of song.sections; track section.type + '-' + section.number + '-' + $index; let i = $index) {
<div
(click)="onSectionClick(song.id, i, show.id)"
(keydown.enter)="onSectionClick(song.id, i, show.id)"
(keydown.space)="onSectionClick(song.id, i, show.id)"
[class.active]="
show.presentationSongId === song.id &&
show.presentationSection === i
"
class="song-part"
role="button"
tabindex="0"
>
<div class="head">{{ section.type | sectionType }} {{ section.number + 1 }}</div>
<div class="fragment">{{ getFirstLine(section) }}</div>
</div>
class="song-part"
role="button"
tabindex="0"
>
<div class="head">{{ section.type | sectionType }} {{ section.number + 1 }}</div>
<div class="fragment">{{ getFirstLine(section) }}</div>
</div>
}
</div>
}
</div>
}
<div class="song">
@if (show) {
<div [class.active]="show.presentationSongId === 'dynamicText'" class="title song-part">
<div
(click)="onSectionClick('dynamicText', -1, show.id)"
(keydown.enter)="onSectionClick('dynamicText', -1, show.id)"
(keydown.space)="onSectionClick('dynamicText', -1, show.id)"
class="head"
role="button"
tabindex="0"
>
Freier Text
</div>
</div>
}
<mat-form-field appearance="outline">
<mat-label>Überschrift</mat-label>
<input (ngModelChange)="onDynamicCaption($event, show.id)" [ngModel]="show.presentationDynamicCaption"
autocomplete="off" id="dynamic-caption" matInput type="text" />
</mat-form-field>
<mat-form-field appearance="outline">
<mat-label>Text</mat-label>
<textarea (ngModelChange)="onDynamicText($event, show.id)" [ngModel]="show.presentationDynamicText"
autocomplete="off" id="dynamic-text" matInput></textarea>
</mat-form-field>
</div>
@if (show) {
<div class="div-bottom">
<button class="btn-start-presentation" mat-button routerLink="/presentation/monitor">
<fa-icon [icon]="faDesktop"></fa-icon>
Präsentation starten
</button>
<mat-form-field appearance="outline">
<mat-label>Hintergrund</mat-label>
<mat-select (ngModelChange)="onBackground($event, show.id)" [ngModel]="show.presentationBackground">
<mat-option value="none">kein Hintergrund</mat-option>
<mat-option value="blue">Sternenhimmel</mat-option>
<mat-option value="green">Blätter</mat-option>
<mat-option value="leder">Leder</mat-option>
<mat-option value="praise">Lobpreis</mat-option>
<mat-option value="bible">Bibel</mat-option>
</mat-select>
</mat-form-field>
<mat-slider #slider [max]="100" [min]="10" [step]="2" class="zoom-slider" color="primary" ngDefaultControl
><input (ngModelChange)="onZoom($event, show.id)" [ngModel]="show.presentationZoom" matSliderThumb />
</mat-slider>
</div>
}
@if (show) {
<app-add-song [addedLive]="true" [showSongs]="showSongs" [show]="show" [songs]="songs$|async"></app-add-song>
}
}
</div>
}
</div>
</app-card>
}
<div class="song">
@if (show) {
<div [class.active]="show.presentationSongId === 'dynamicText'" class="title song-part">
<div
(click)="onSectionClick('dynamicText', -1, show.id)"
(keydown.enter)="onSectionClick('dynamicText', -1, show.id)"
(keydown.space)="onSectionClick('dynamicText', -1, show.id)"
class="head"
role="button"
tabindex="0"
>
Freier Text
</div>
</div>
}
<mat-form-field appearance="outline">
<mat-label>Überschrift</mat-label>
<input (ngModelChange)="onDynamicCaption($event, show.id)" [ngModel]="show.presentationDynamicCaption" autocomplete="off" id="dynamic-caption" matInput type="text" />
</mat-form-field>
<mat-form-field appearance="outline">
<mat-label>Text</mat-label>
<textarea (ngModelChange)="onDynamicText($event, show.id)" [ngModel]="show.presentationDynamicText" autocomplete="off" id="dynamic-text" matInput></textarea>
</mat-form-field>
</div>
@if (show) {
<div class="div-bottom">
<button class="btn-start-presentation" mat-button routerLink="/presentation/monitor">
<fa-icon [icon]="faDesktop"></fa-icon>
Präsentation starten
</button>
<mat-form-field appearance="outline">
<mat-label>Hintergrund</mat-label>
<mat-select (ngModelChange)="onBackground($event, show.id)" [ngModel]="show.presentationBackground">
<mat-option value="none">kein Hintergrund</mat-option>
<mat-option value="blue">Sternenhimmel</mat-option>
<mat-option value="green">Blätter</mat-option>
<mat-option value="leder">Leder</mat-option>
<mat-option value="praise">Lobpreis</mat-option>
<mat-option value="bible">Bibel</mat-option>
</mat-select>
</mat-form-field>
<mat-slider #slider [max]="100" [min]="10" [step]="2" class="zoom-slider" color="primary" ngDefaultControl
><input (ngModelChange)="onZoom($event, show.id)" [ngModel]="show.presentationZoom" matSliderThumb />
</mat-slider>
</div>
} @if (show) {
<app-add-song [addedLive]="true" [showSongs]="showSongs" [show]="show" [songs]="songs$|async"></app-add-song>
} }
</app-card>
}
</app-page-frame>

View File

@@ -1,4 +1,4 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, inject} from '@angular/core';
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, OnDestroy} from '@angular/core';
import {combineLatest, Subject} from 'rxjs';
import {PresentationBackground, Show} from '../../shows/services/show';
import {ShowSongService} from '../../shows/services/show-song.service';
@@ -26,6 +26,7 @@ import {MatSlider, MatSliderThumb} from '@angular/material/slider';
import {AddSongComponent} from '../../../widget-modules/components/add-song/add-song.component';
import {ShowTypePipe} from '../../../widget-modules/pipes/show-type-translater/show-type.pipe';
import {SectionTypePipe} from '../../../widget-modules/pipes/section-type-translator/section-type.pipe';
import {PageFrameComponent} from '../../../widget-modules/components/sidebar/page-frame.component';
export interface PresentationSong {
id: string;
@@ -58,6 +59,7 @@ export interface PresentationSong {
DatePipe,
ShowTypePipe,
SectionTypePipe,
PageFrameComponent,
],
})
export class RemoteComponent implements OnDestroy {
@@ -87,12 +89,12 @@ export class RemoteComponent implements OnDestroy {
map(_ => _.currentShow),
filter((showId): showId is string => !!showId),
distinctUntilChanged(),
takeUntil(this.destroy$)
takeUntil(this.destroy$),
);
const show$ = currentShowId$.pipe(
switchMap(showId => this.showService.read$(showId)),
takeUntil(this.destroy$)
takeUntil(this.destroy$),
);
const parsedSongs$ = currentShowId$.pipe(
@@ -105,7 +107,7 @@ export class RemoteComponent implements OnDestroy {
sections: this.textRenderingService.parse(song.text, null, false),
})),
})),
takeUntil(this.destroy$)
takeUntil(this.destroy$),
);
combineLatest([show$, parsedSongs$])

View File

@@ -1,20 +1,23 @@
@if (shows$ | async; as shows) {
<div @fade>
@if (visible) {
<app-card heading="Bitte eine Veranstaltung auswählen">
@if (!shows.length) {
<p>Es ist derzeit keine Veranstaltung vorhanden</p>
} @if (shows.length>0) {
<div class="list">
@for (show of shows; track show.id) {
<button (click)="selectShow(show)" mat-stroked-button>
<app-user-name [userId]="show.owner"></app-user-name>
, {{ show.showType | showType }}, {{ show.date.toDate() | date: "dd.MM.yyyy" }}
</button>
<app-page-frame title="Präsentation" [withMenu]="false">
@if (shows$ | async; as shows) {
<div @fade content>
@if (visible) {
<app-card heading="Bitte eine Veranstaltung auswählen">
@if (!shows.length) {
<p>Es ist derzeit keine Veranstaltung vorhanden</p>
}
@if (shows.length > 0) {
<div class="list">
@for (show of shows; track show.id) {
<button (click)="selectShow(show)" mat-stroked-button>
<app-user-name [userId]="show.owner"></app-user-name>
, {{ show.showType | showType }}, {{ show.date.toDate() | date: "dd.MM.yyyy" }}
</button>
}
</div>
}
</app-card>
}
</div>
}
</app-card>
}
</div>
}
</app-page-frame>

View File

@@ -1,4 +1,4 @@
import {Component, OnInit, inject} from '@angular/core';
import {Component, inject, OnInit} from '@angular/core';
import {map} from 'rxjs/operators';
import {ShowService} from '../../shows/services/show.service';
import {Show} from '../../shows/services/show';
@@ -10,13 +10,14 @@ import {CardComponent} from '../../../widget-modules/components/card/card.compon
import {MatButton} from '@angular/material/button';
import {UserNameComponent} from '../../../services/user/user-name/user-name.component';
import {ShowTypePipe} from '../../../widget-modules/pipes/show-type-translater/show-type.pipe';
import {PageFrameComponent} from '../../../widget-modules/components/sidebar/page-frame.component';
@Component({
selector: 'app-select',
templateUrl: './select.component.html',
styleUrls: ['./select.component.less'],
animations: [fade],
imports: [CardComponent, MatButton, UserNameComponent, AsyncPipe, DatePipe, ShowTypePipe],
imports: [CardComponent, MatButton, UserNameComponent, AsyncPipe, DatePipe, ShowTypePipe, PageFrameComponent],
})
export class SelectComponent implements OnInit {
private showService = inject(ShowService);