fix: risolto accesso diretto ai singoli canti tramite URL e queryParams

- Aggiunto il caricamento reattivo del canto tramite un 'effect' in PlayerPage e DisplayPage.
- Ora l'applicazione attende che la lista asincrona dei canti sia popolata per caricare la canzone richiesta da URL.
This commit is contained in:
David Frassi
2026-05-20 11:28:22 +02:00
parent 21c9c206e1
commit d83a5db65a
2 changed files with 69 additions and 33 deletions
+16 -6
View File
@@ -1,4 +1,4 @@
import { Component, OnInit, OnDestroy, signal, computed, inject } from '@angular/core';
import { Component, OnInit, OnDestroy, signal, computed, effect, inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { CantiService, Canto } from '../../services/canti.service';
import { LyricsParserService, ParsedSection } from '../../services/lyrics-parser.service';
@@ -11,6 +11,7 @@ import { LyricsParserService, ParsedSection } from '../../services/lyrics-parser
})
export class DisplayPage implements OnInit, OnDestroy {
public canto = signal<Canto | null>(null);
public activeSongId = signal<string | null>(null);
public showChords = signal<boolean>(false);
public fontSize = signal<number>(1.0);
public currentLineIndex = signal<number>(0);
@@ -54,14 +55,24 @@ export class DisplayPage implements OnInit, OnDestroy {
private cantiService = inject(CantiService);
private lyricsParser = inject(LyricsParserService);
constructor() { }
constructor() {
effect(() => {
const id = this.activeSongId();
const allCanti = this.cantiService.canti();
if (id) {
const found = allCanti.find(c => c.id === id);
if (found) {
this.canto.set(found);
}
}
}, { allowSignalWrites: true });
}
ngOnInit() {
this.route.queryParams.subscribe(params => {
const id = params['id'];
if (id) {
const found = this.cantiService.getCantoById(id);
if (found) this.canto.set(found);
this.activeSongId.set(id);
}
});
@@ -70,8 +81,7 @@ export class DisplayPage implements OnInit, OnDestroy {
this.currentLineIndex.set(event.data.index);
}
if (event.data.type === 'SYNC_CANTO') {
const found = this.cantiService.getCantoById(event.data.id);
if (found) this.canto.set(found);
this.activeSongId.set(event.data.id);
}
if (event.data.type === 'SYNC_CHORDS') {
this.showChords.set(event.data.showChords);
+53 -27
View File
@@ -22,6 +22,7 @@ import { StatsService } from '../../services/stats.service';
})
export class PlayerPage implements OnInit, AfterViewInit, OnDestroy {
public canto = signal<Canto | null>(null);
public activeSongId = signal<string | null>(null);
/** true = show chords (accordi mode), false = text only */
public showChords = signal<boolean>(false);
@@ -153,6 +154,45 @@ export class PlayerPage implements OnInit, AfterViewInit, OnDestroy {
}
}
});
// Reactive song loading based on activeSongId and available canti lists
effect(() => {
const id = this.activeSongId();
const allCanti = this.cantiService.canti();
const myCantiList = this.myCantiService.myCanti();
if (id) {
let found = allCanti.find(c => c.id === id);
if (!found) {
found = myCantiList.find(c => c.id === id);
}
if (found) {
const current = this.canto();
// Avoid duplicate triggers for the same song
if (!current || current.id !== found.id) {
this.logPreviousSongTime();
this.canto.set(found);
this.songStartTime = Date.now();
this.cantiService.getStorage()?.set('last_song_id', id);
this.channel.postMessage({ type: 'SYNC_CANTO', id: found.id });
// Set custom community transposition if active
if (this.comunitaService.comunitaCode() && this.comunitaService.isFilterActive()) {
const settings = this.comunitaService.comunitaCantiSettings();
const songSetting = settings.find(s => s.id_canti === found.id_canti || s.id_canti === Number(found.id));
if (songSetting && songSetting.tonalita !== undefined) {
this.transposeAmount.set(songSetting.tonalita);
} else {
this.transposeAmount.set(0);
}
} else {
this.transposeAmount.set(0);
}
}
}
}
}, { allowSignalWrites: true });
}
ngAfterViewInit() {
@@ -197,34 +237,20 @@ export class PlayerPage implements OnInit, AfterViewInit, OnDestroy {
this.initialStartTime = parseInt(params['t'], 10);
}
if (!id) {
id = await this.cantiService.getStorage()?.get('last_song_id');
}
if (id) {
let found: Canto | undefined = this.cantiService.getCantoById(id);
if (!found) {
found = this.myCantiService.myCanti().find(c => c.id === id);
}
if (found) {
this.logPreviousSongTime();
this.canto.set(found);
this.songStartTime = Date.now();
this.cantiService.getStorage()?.set('last_song_id', id);
this.channel.postMessage({ type: 'SYNC_CANTO', id: found.id });
// Set custom community transposition if active
if (this.comunitaService.comunitaCode() && this.comunitaService.isFilterActive()) {
const settings = this.comunitaService.comunitaCantiSettings();
const songSetting = settings.find(s => s.id_canti === found.id_canti || s.id_canti === Number(found.id));
if (songSetting && songSetting.tonalita !== undefined) {
this.transposeAmount.set(songSetting.tonalita);
} else {
this.transposeAmount.set(0);
}
} else {
this.transposeAmount.set(0);
const checkStorage = async () => {
let storage = this.cantiService.getStorage();
while (!storage) {
await new Promise(resolve => setTimeout(resolve, 50));
storage = this.cantiService.getStorage();
}
}
const storedId = await storage.get('last_song_id');
if (storedId && !this.activeSongId()) {
this.activeSongId.set(storedId);
}
};
checkStorage();
} else {
this.activeSongId.set(id);
}
});
}