guest mode

This commit is contained in:
2024-02-24 22:01:48 +01:00
parent 150e20ccfb
commit 4aeb452434
18 changed files with 601 additions and 55 deletions

View File

@@ -0,0 +1,13 @@
<div mat-dialog-content>
<a [href]="data.url">{{ data.url }}</a>
<div [style.background-image]="'url('+qrCode+')'" alt="qrcode" class="qrcode">
</div>
</div>
<div mat-dialog-actions>
<button [mat-dialog-close]="true" cdkFocusInitial mat-button>
Schließen
</button>
<button (click)="share()" mat-button>
Teilen
</button>
</div>

View File

@@ -0,0 +1,7 @@
.qrcode {
width: 300px;
height: 300px;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}

View File

@@ -0,0 +1,22 @@
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {ShareDialogComponent} from './share-dialog.component';
describe('ShareDialogComponent', () => {
let component: ShareDialogComponent;
let fixture: ComponentFixture<ShareDialogComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ShareDialogComponent],
}).compileComponents();
fixture = TestBed.createComponent(ShareDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,49 @@
import {Component, Inject} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogActions, MatDialogClose, MatDialogContent} from '@angular/material/dialog';
import {MatButton} from '@angular/material/button';
import QRCode from 'qrcode';
import {AsyncPipe} from '@angular/common';
import {ShowTypePipe} from '../../../../widget-modules/pipes/show-type-translater/show-type.pipe';
import {Show} from '../../services/show';
export interface ShareDialogData {
url: string;
show: Show;
}
@Component({
selector: 'app-share-dialog',
standalone: true,
imports: [MatButton, MatDialogActions, MatDialogContent, MatDialogClose, AsyncPipe],
templateUrl: './share-dialog.component.html',
styleUrl: './share-dialog.component.less',
})
export class ShareDialogComponent {
public qrCode: string;
public constructor(@Inject(MAT_DIALOG_DATA) public data: ShareDialogData) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
QRCode.toDataURL(data.url, {
type: 'image/jpeg',
quality: 0.92,
width: 1280,
height: 1280,
color: {
dark: '#010414',
light: '#ffffff',
},
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-return
}).then(_ => (this.qrCode = _));
}
public async share() {
if (navigator.clipboard) await navigator.clipboard.writeText(this.data.url);
if (navigator.share)
await navigator.share({
title: new ShowTypePipe().transform(this.data.show.showType),
text: new ShowTypePipe().transform(this.data.show.showType) + ' am ' + this.data.show.date.toDate().toLocaleString('de'),
url: this.data.url,
});
}
}

View File

@@ -13,6 +13,7 @@ export interface Show {
published: boolean;
archived: boolean;
order: string[];
shareId: string;
presentationSongId: string;
presentationDynamicCaption: string;

View File

@@ -6,7 +6,7 @@
show.date.toDate() | date: 'dd.MM.yyyy'
}} - {{ getStatus(show) }}"
>
<p *ngIf="!useSwiper">{{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">
@@ -41,7 +41,8 @@
</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'"
<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"
@@ -76,6 +77,9 @@
<app-button (click)="onPublish(false)" *ngIf="show.published" [icon]="faUnpublish">
Veröffentlichung zurückziehen
</app-button>
<app-button (click)="onShare(show)" *ngIf="show.published" [icon]="faShare">
Teilen
</app-button>
<app-button (click)="onChange(show.id)" [icon]="faSliders" *ngIf="!show.published">
Ändern
</app-button>

View File

@@ -19,6 +19,7 @@ import {
faLock,
faMagnifyingGlassMinus,
faMagnifyingGlassPlus,
faShare,
faSliders,
faUser,
faUsers,
@@ -28,6 +29,8 @@ 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';
import {GuestShowService} from '../../guest/guest-show.service';
import {ShareDialogComponent} from '../dialog/share-dialog/share-dialog.component';
@Component({
selector: 'app-show',
@@ -46,14 +49,13 @@ export class ShowComponent implements OnInit, OnDestroy {
public faBoxOpen = faBoxOpen;
public faPublish = faExternalLinkAlt;
public faUnpublish = faLock;
public faShare = faShare;
public faDownload = faFileDownload;
public faSliders = faSliders;
public faUser = faUser;
public faUsers = faUsers;
public faZoomIn = faMagnifyingGlassPlus;
public faZoomOut = faMagnifyingGlassMinus;
public faPage = faFile;
public faLines = faFileLines;
private subs: Subscription[] = [];
public useSwiper = false;
@@ -65,7 +67,8 @@ export class ShowComponent implements OnInit, OnDestroy {
private docxService: DocxService,
private router: Router,
private cRef: ChangeDetectorRef,
public dialog: MatDialog
public dialog: MatDialog,
private guestShowService: GuestShowService
) {}
public ngOnInit(): void {
@@ -128,6 +131,11 @@ export class ShowComponent implements OnInit, OnDestroy {
if (this.showId != null) await this.showService.update$(this.showId, {published});
}
public onShare = async (show: Show): Promise<void> => {
const url = await this.guestShowService.share(show, this.orderedShowSongs(show));
this.dialog.open(ShareDialogComponent, {data: {url, show}});
};
public getStatus(show: Show): string {
if (show.published) {
return 'veröffentlicht';
@@ -162,7 +170,7 @@ export class ShowComponent implements OnInit, OnDestroy {
return show.order.map(_ => list.filter(f => f.id === _)[0]);
}
public trackBy = (index: number, show: ShowSong) => show.id;
public trackBy = (_: number, show: ShowSong) => show.id;
public async onChange(showId: string) {
await this.router.navigateByUrl('/shows/' + showId + '/edit');