add swiper view to show
This commit is contained in:
@@ -2,6 +2,7 @@ import {ChangeDetectionStrategy, Component, OnInit, ViewChild} from '@angular/co
|
||||
import {fader} from './animations';
|
||||
import {ScrollService} from './services/scroll.service';
|
||||
import {PerfectScrollbarComponent} from 'ngx-perfect-scrollbar';
|
||||
import {register} from 'swiper/element/bundle';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@@ -17,6 +18,7 @@ export class AppComponent implements OnInit {
|
||||
scrollService.restoreScrollPosition$.subscribe(pos => {
|
||||
if (this.scrollbar && pos) this.scrollbar.directiveRef?.scrollTo(0, pos, 300);
|
||||
});
|
||||
register();
|
||||
}
|
||||
|
||||
public ngOnInit(): void {
|
||||
|
||||
@@ -12,6 +12,7 @@ import {TextRenderingService} from '../../songs/services/text-rendering.service'
|
||||
import {PresentationBackground, Show} from '../../shows/services/show';
|
||||
import {GlobalSettings} from '../../../services/global-settings';
|
||||
import {ShowSongService} from '../../shows/services/show-song.service';
|
||||
import {openFullscreen} from '../../../services/fullscreen';
|
||||
|
||||
@Component({
|
||||
selector: 'app-monitor',
|
||||
@@ -45,6 +46,7 @@ export class MonitorComponent implements OnInit {
|
||||
}
|
||||
|
||||
public ngOnInit(): void {
|
||||
openFullscreen();
|
||||
this.globalSettingsService.get$
|
||||
.pipe(
|
||||
debounceTime(100),
|
||||
|
||||
@@ -30,10 +30,6 @@ export class ShowService {
|
||||
map(s =>
|
||||
s.shows
|
||||
.sort((a, b) => a.date.toMillis() - b.date.toMillis())
|
||||
.map(_ => {
|
||||
console.log(_);
|
||||
return _;
|
||||
})
|
||||
.filter(_ => !_.archived)
|
||||
.filter(show => show.published || (show.owner === s.user?.id && !publishedOnly))
|
||||
)
|
||||
|
||||
@@ -1,23 +1,30 @@
|
||||
<div *ngIf="show$ | async as show">
|
||||
<app-card
|
||||
[fullscreen]="useSwiper"
|
||||
closeLink="../"
|
||||
heading="{{ show.showType | showType }}, {{
|
||||
show.date.toDate() | date: 'dd.MM.yyyy'
|
||||
}} - {{ getStatus(show) }}"
|
||||
>
|
||||
<p>{{show.public ? 'öffentliche' : 'geschlossene'}} Veranstaltung von
|
||||
<p *ngIf="!useSwiper">{{show.public ? 'öffentliche' : 'geschlossene'}} Veranstaltung von
|
||||
<app-user-name [userId]="show.owner"></app-user-name>
|
||||
</p>
|
||||
<div class="head">
|
||||
<mat-checkbox [(ngModel)]="showText">Text anzeigen</mat-checkbox>
|
||||
<div>
|
||||
<mat-checkbox *ngIf="!useSwiper" [(ngModel)]="showText">Text anzeigen</mat-checkbox>
|
||||
</div>
|
||||
<div [class.floating]="useSwiper">
|
||||
<app-menu-button @fade (click)="onZoomOut()" [icon]="faZoomOut" class="btn-delete btn-icon"
|
||||
matTooltip="Vergrößern"></app-menu-button>
|
||||
<app-menu-button @fade (click)="onZoomIn()" [icon]="faZoomIn" class="btn-delete btn-icon"
|
||||
matTooltip="Verkleinern"></app-menu-button>
|
||||
<app-menu-button @fade (click)="onZoomIn()" [icon]="faZoomIn" class="btn-delete btn-icon"
|
||||
matTooltip="Vergrößern"></app-menu-button>
|
||||
<app-menu-button (click)="useSwiper=!useSwiper;fullscreen(useSwiper)" @fade
|
||||
[icon]="useSwiper ? faFileLines : faFile" class="btn-delete btn-icon"
|
||||
matTooltip="Swiper umschalten"></app-menu-button>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="showSongs" class="song-list" cdkDropList [cdkDropListDisabled]="show.published || showText"
|
||||
<div *ngIf="showSongs && !useSwiper" [cdkDropListDisabled]="show.published || showText" cdkDropList
|
||||
class="song-list"
|
||||
[style.cursor]="!(show.published || showText) ? 'drag' : 'inherit'"
|
||||
[style.font-size]="textSize + 'em'"
|
||||
(cdkDropListDropped)="drop($event, show)">
|
||||
@@ -27,19 +34,34 @@
|
||||
[showId]="showId"
|
||||
[showText]="showText"
|
||||
[show]="show"
|
||||
[fullscreen]="useSwiper"
|
||||
[index]="i"
|
||||
></app-song>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<swiper-container *ngIf="useSwiper" scrollbar="true">
|
||||
<swiper-slide *ngFor="let song of orderedShowSongs(show); let i = index; trackBy: trackBy" [style.font-size]="textSize + 'em'"
|
||||
class="song-swipe">
|
||||
<app-song
|
||||
[fullscreen]="true"
|
||||
[index]="i"
|
||||
[showId]="showId"
|
||||
[showSong]="song"
|
||||
[showText]="true"
|
||||
[show]="show"
|
||||
></app-song>
|
||||
</swiper-slide>
|
||||
</swiper-container>
|
||||
|
||||
<app-add-song
|
||||
*ngIf="songs && !show.published"
|
||||
*ngIf="songs && !show.published && !useSwiper"
|
||||
[show]="show"
|
||||
[showSongs]="showSongs"
|
||||
[songs]="songs"
|
||||
></app-add-song>
|
||||
|
||||
<app-button-row>
|
||||
<app-button-row *ngIf="!useSwiper">
|
||||
<ng-container *appRole="['leader']">
|
||||
<ng-container *appOwner="show.owner">
|
||||
<app-button (click)="onArchive(true)" *ngIf="!show.archived" [icon]="faBox">
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
border-bottom: 1px solid #0002;
|
||||
}
|
||||
|
||||
.song-swipe {
|
||||
margin-bottom: 20px;
|
||||
min-height: calc(100vh - 60px);
|
||||
}
|
||||
|
||||
|
||||
.head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -36,3 +42,10 @@
|
||||
.example-list.cdk-drop-list-dragging .song-list:not(.cdk-drag-placeholder) {
|
||||
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.floating {
|
||||
position: fixed;
|
||||
right: 20px;
|
||||
top: 12px;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {ChangeDetectorRef, Component, OnDestroy, OnInit} from '@angular/core';
|
||||
import {ChangeDetectorRef, Component, HostListener, OnDestroy, OnInit} from '@angular/core';
|
||||
import {filter, map, switchMap, tap} from 'rxjs/operators';
|
||||
import {ActivatedRoute, Router} from '@angular/router';
|
||||
import {ShowService} from '../services/show.service';
|
||||
@@ -13,7 +13,9 @@ import {
|
||||
faBox,
|
||||
faBoxOpen,
|
||||
faExternalLinkAlt,
|
||||
faFile,
|
||||
faFileDownload,
|
||||
faFileLines,
|
||||
faLock,
|
||||
faMagnifyingGlassMinus,
|
||||
faMagnifyingGlassPlus,
|
||||
@@ -25,6 +27,7 @@ import {CdkDragDrop, moveItemInArray} from '@angular/cdk/drag-drop';
|
||||
import {fade} from '../../../animations';
|
||||
import {MatDialog} from '@angular/material/dialog';
|
||||
import {ArchiveDialogComponent} from '../dialog/archive-dialog/archive-dialog.component';
|
||||
import {closeFullscreen, openFullscreen} from '../../../services/fullscreen';
|
||||
|
||||
@Component({
|
||||
selector: 'app-show',
|
||||
@@ -49,7 +52,10 @@ export class ShowComponent implements OnInit, OnDestroy {
|
||||
public faUsers = faUsers;
|
||||
public faZoomIn = faMagnifyingGlassPlus;
|
||||
public faZoomOut = faMagnifyingGlassMinus;
|
||||
public faPage = faFile;
|
||||
public faLines = faFileLines;
|
||||
private subs: Subscription[] = [];
|
||||
public useSwiper = false;
|
||||
|
||||
public constructor(
|
||||
private activatedRoute: ActivatedRoute,
|
||||
@@ -161,4 +167,34 @@ export class ShowComponent implements OnInit, OnDestroy {
|
||||
public async onChange(showId: string) {
|
||||
await this.router.navigateByUrl('/shows/' + showId + '/edit');
|
||||
}
|
||||
|
||||
public faFileLines = faFileLines;
|
||||
public faFile = faFile;
|
||||
|
||||
@HostListener('document:keydown', ['$event'])
|
||||
public handleKeyboardEvent(event: KeyboardEvent) {
|
||||
const swiperEl = document.querySelector('swiper-container') as unknown as Swiper;
|
||||
switch (event.code) {
|
||||
case 'ArrowRight':
|
||||
case 'ArrowDown':
|
||||
swiperEl.swiper.slideNext();
|
||||
break;
|
||||
case 'ArrowLeft':
|
||||
case 'ArrowUp':
|
||||
swiperEl.swiper.slidePrev();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public fullscreen(useSwiper: boolean) {
|
||||
if (useSwiper) openFullscreen();
|
||||
else closeFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
export interface Swiper {
|
||||
swiper: {
|
||||
slideNext(): void;
|
||||
slidePrev(): void;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<div *ngIf="iSong && iSong && show">
|
||||
<div *ngIf="show.published" class="title published">
|
||||
<div *ngIf="show.published || fullscreen" class="title published">
|
||||
<div class="key">{{ iSong.key }}</div>
|
||||
<div>{{ iSong.title }}</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!show.published" class="song">
|
||||
<div *ngIf="!show.published && !fullscreen" class="song">
|
||||
<span class="title">{{ iSong.title }}</span>
|
||||
<span *ngIf="!edit" class="keys">
|
||||
<span *ngIf="iSong.keyOriginal !== iSong.key">{{ iSong.keyOriginal }} → </span>
|
||||
|
||||
@@ -19,6 +19,7 @@ export class SongComponent implements OnInit {
|
||||
@Input() public showId: string | null = null;
|
||||
@Input() public showText: boolean | null = null;
|
||||
@Input() public index = -1;
|
||||
@Input() public fullscreen = false;
|
||||
|
||||
public keys: string[] = [];
|
||||
public faDelete = faTrash;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CUSTOM_ELEMENTS_SCHEMA, NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
|
||||
import {ShowsRoutingModule} from './shows-routing.module';
|
||||
@@ -70,5 +70,6 @@ import {MatDialogModule} from '@angular/material/dialog';
|
||||
MatTooltipModule,
|
||||
MatDialogModule,
|
||||
],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
})
|
||||
export class ShowsModule {}
|
||||
|
||||
13
src/app/services/fullscreen.ts
Normal file
13
src/app/services/fullscreen.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
const elem = document.documentElement;
|
||||
|
||||
export const openFullscreen = () => {
|
||||
if (elem.requestFullscreen) {
|
||||
void elem.requestFullscreen();
|
||||
}
|
||||
};
|
||||
|
||||
export const closeFullscreen = () => {
|
||||
if (document.exitFullscreen) {
|
||||
void document.exitFullscreen();
|
||||
}
|
||||
};
|
||||
@@ -1,13 +1,13 @@
|
||||
<div [class.padding]="padding" class="card">
|
||||
<div [class.fullscreen]="fullscreen" [class.padding]="padding" class="card">
|
||||
<button
|
||||
*ngIf="closeLink"
|
||||
*ngIf="closeLink && !fullscreen"
|
||||
[routerLink]="closeLink"
|
||||
class="btn-close"
|
||||
mat-icon-button
|
||||
>
|
||||
<fa-icon [icon]="closeIcon"></fa-icon>
|
||||
</button>
|
||||
<div *ngIf="heading" class="heading">{{ heading }}</div>
|
||||
<div *ngIf="subheading" class="subheading">{{ subheading }}</div>
|
||||
<div *ngIf="heading && !fullscreen" class="heading">{{ heading }}</div>
|
||||
<div *ngIf="subheading && !fullscreen" class="subheading">{{ subheading }}</div>
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
|
||||
@@ -23,6 +23,20 @@
|
||||
}
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
&.fullscreen {
|
||||
border-radius: 0;
|
||||
background: #ffff;
|
||||
margin: 0;
|
||||
color: #000;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: unset;
|
||||
z-index: 10;
|
||||
}
|
||||
}
|
||||
|
||||
.heading {
|
||||
|
||||
@@ -12,4 +12,5 @@ export class CardComponent {
|
||||
@Input() public subheading: string | null = null;
|
||||
@Input() public closeLink: string | null = null;
|
||||
@Input() public closeIcon = faTimes;
|
||||
@Input() public fullscreen = false;
|
||||
}
|
||||
|
||||
@@ -45,9 +45,7 @@
|
||||
@media screen and (max-width: 860px) {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
border-left: 3px solid #0002;
|
||||
padding-left: 5px;
|
||||
margin-left: -8px;
|
||||
|
||||
}
|
||||
|
||||
.chorus {
|
||||
|
||||
Reference in New Issue
Block a user