190 lines
5.8 KiB
TypeScript
190 lines
5.8 KiB
TypeScript
import { Component, inject, computed } from '@angular/core';
|
|
import { PlaylistService } from '../../services/playlist.service';
|
|
import { CantiService } from '../../services/canti.service';
|
|
import { ComunitaService } from '../../services/comunita.service';
|
|
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
|
|
import { AlertController, ToastController, ModalController } from '@ionic/angular';
|
|
import { Router } from '@angular/router';
|
|
|
|
@Component({
|
|
selector: 'app-playlist',
|
|
templateUrl: './playlist.page.html',
|
|
styleUrls: ['./playlist.page.scss'],
|
|
standalone: false
|
|
})
|
|
export class PlaylistPage {
|
|
public playlistService = inject(PlaylistService);
|
|
public cantiService = inject(CantiService);
|
|
public comunitaService = inject(ComunitaService);
|
|
private alertCtrl = inject(AlertController);
|
|
private toastCtrl = inject(ToastController);
|
|
private router = inject(Router);
|
|
|
|
public selectedSongs = computed(() => {
|
|
const ids = Array.from(this.playlistService.selectedIds());
|
|
return ids.map(id => this.cantiService.canti().find(c => c.id === id)).filter(c => !!c);
|
|
});
|
|
|
|
public localSongs: any[] = [];
|
|
public qrCodeImage: string | null = null;
|
|
public savedPlaylistName: string | null = null;
|
|
|
|
constructor() {
|
|
// Initial copy to allow local reordering
|
|
this.localSongs = [...this.selectedSongs()];
|
|
}
|
|
|
|
drop(event: CdkDragDrop<string[]>) {
|
|
moveItemInArray(this.localSongs, event.previousIndex, event.currentIndex);
|
|
}
|
|
|
|
async savePlaylist() {
|
|
const alert = await this.alertCtrl.create({
|
|
header: 'Salva Playlist',
|
|
inputs: [
|
|
{
|
|
name: 'name',
|
|
type: 'text',
|
|
placeholder: 'Nome della playlist',
|
|
value: this.savedPlaylistName || ''
|
|
}
|
|
],
|
|
buttons: [
|
|
{
|
|
text: 'Annulla',
|
|
role: 'cancel'
|
|
},
|
|
{
|
|
text: 'Salva',
|
|
handler: (data) => {
|
|
if (data.name) {
|
|
this.savedPlaylistName = data.name;
|
|
this.playlistService.savePlaylist(data.name, this.localSongs.map(s => s.id));
|
|
this.showToast('Playlist salvata!');
|
|
this.router.navigate(['/settings']);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
]
|
|
});
|
|
await alert.present();
|
|
}
|
|
|
|
async saveAndExport() {
|
|
const alert = await this.alertCtrl.create({
|
|
header: 'Salva ed Esporta QR',
|
|
message: 'Inserisci un nome per la playlist. Verrà salvata e generato il QR Code.',
|
|
inputs: [
|
|
{
|
|
name: 'name',
|
|
type: 'text',
|
|
placeholder: 'Nome della playlist',
|
|
value: this.savedPlaylistName || ''
|
|
}
|
|
],
|
|
buttons: [
|
|
{
|
|
text: 'Annulla',
|
|
role: 'cancel'
|
|
},
|
|
{
|
|
text: 'Salva ed Esporta',
|
|
handler: async (data) => {
|
|
if (data.name) {
|
|
this.savedPlaylistName = data.name;
|
|
const ids = this.localSongs.map(s => s.id);
|
|
await this.playlistService.savePlaylist(data.name, ids);
|
|
this.qrCodeImage = await this.playlistService.generateQR(ids, data.name);
|
|
this.showToast('Playlist salvata!');
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
]
|
|
});
|
|
await alert.present();
|
|
}
|
|
|
|
async sharePlaylist() {
|
|
if (this.localSongs.length === 0) return;
|
|
|
|
const ids = this.localSongs.map(s => s.id);
|
|
const name = this.savedPlaylistName || 'Playlist Condivisa';
|
|
this.qrCodeImage = await this.playlistService.generateQR(ids, name);
|
|
}
|
|
|
|
downloadQR() {
|
|
if (!this.qrCodeImage) return;
|
|
|
|
const name = this.savedPlaylistName || 'playlist';
|
|
const fileName = `${name.toLowerCase().replace(/\s+/g, '_')}_qr.png`;
|
|
|
|
const link = document.createElement('a');
|
|
link.href = this.qrCodeImage;
|
|
link.download = fileName;
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
|
|
this.showToast('Immagine scaricata!');
|
|
}
|
|
|
|
async shareQR() {
|
|
if (!this.qrCodeImage) return;
|
|
const name = this.savedPlaylistName || 'playlist';
|
|
const shareLink = this.playlistService.getShareLink(this.localSongs.map(s => s.id), name);
|
|
const fileName = `${name.toLowerCase().replace(/\s+/g, '_')}_qr.png`;
|
|
|
|
try {
|
|
// Convert base64 to blob/file for sharing
|
|
const res = await fetch(this.qrCodeImage);
|
|
const blob = await res.blob();
|
|
const file = new File([blob], fileName, { type: 'image/png' });
|
|
|
|
if (navigator.share && navigator.canShare && navigator.canShare({ files: [file] })) {
|
|
await navigator.share({
|
|
files: [file],
|
|
title: 'Playlist CantiCristiani',
|
|
text: `Ecco la playlist: ${name}\n\nClicca qui per aprirla subito: ${shareLink}`
|
|
});
|
|
} else {
|
|
// Fallback to simple share text or download
|
|
if (navigator.share) {
|
|
await navigator.share({
|
|
title: 'Playlist CantiCristiani',
|
|
text: `Ecco la playlist: ${name}\n\nClicca qui per aprirla: ${shareLink}`
|
|
});
|
|
} else {
|
|
this.downloadQR();
|
|
}
|
|
}
|
|
} catch (err) {
|
|
console.error('Share failed', err);
|
|
this.downloadQR();
|
|
}
|
|
}
|
|
|
|
closeQR() {
|
|
this.qrCodeImage = null;
|
|
}
|
|
|
|
async showToast(message: string) {
|
|
const toast = await this.toastCtrl.create({
|
|
message,
|
|
duration: 2000,
|
|
color: 'success'
|
|
});
|
|
await toast.present();
|
|
}
|
|
|
|
getCommunitySongNumber(song: any): string | null {
|
|
if (!this.comunitaService.comunitaCode() || !this.comunitaService.isFilterActive()) return null;
|
|
const cantiInfo = this.comunitaService.comunitaCantiInfo();
|
|
const info = cantiInfo.find(x => x.id_canti === song.id_canti || x.id_canti === Number(song.id));
|
|
return info && info.num_canto ? info.num_canto.toString() : null;
|
|
}
|
|
}
|