feat: show instructions when playlist is empty & fix high contrast contrast

This commit is contained in:
David Frassi
2026-06-15 00:24:27 +02:00
parent b4b7e10c5f
commit 1b6e8a1832
12 changed files with 554 additions and 370 deletions
+49 -7
View File
@@ -1,4 +1,4 @@
import { Component, inject, OnInit, signal } from '@angular/core';
import { Component, inject, OnInit, signal, effect } from '@angular/core';
import { ThemeService } from './services/theme.service';
import { CantiService } from './services/canti.service';
import { SettingsService } from './services/settings.service';
@@ -26,12 +26,35 @@ export class AppComponent implements OnInit {
public showRedirectOverlay = signal<boolean>(false);
public showInstallOverlay = signal<boolean>(false);
public redirectFailed = signal<boolean>(false);
public protocolLink = '';
constructor() {
// Gli aggiornamenti automatici e periodici sono stati rimossi.
// L'aggiornamento viene gestito esclusivamente in modo manuale
// tramite il pulsante "Verifica Aggiornamenti App" in SettingsPage.
effect(() => {
this.checkLoaderDismissal();
});
}
checkLoaderDismissal() {
const ready = this.settingsService.isVersionCheckComplete() && this.cantiService.firstLoadCompleted();
if (!ready) {
return;
}
// Se l'overlay di redirect o di installazione è mostrato, NON nascondiamo il loader iniziale
// per rimanere nella welcome page mentre l'utente sceglie.
if (this.showRedirectOverlay() || this.showInstallOverlay()) {
return;
}
// Altrimenti, nascondiamo il loader per far entrare l'utente nell'app
if ((window as any).PwaLoader) {
(window as any).PwaLoader.hide();
}
}
async ngOnInit() {
@@ -50,11 +73,6 @@ export class AppComponent implements OnInit {
// Set signal indicating startup version check is complete
this.settingsService.isVersionCheckComplete.set(true);
// Hide loader if canti are also already loaded
if (this.cantiService.firstLoadCompleted() && (window as any).PwaLoader) {
(window as any).PwaLoader.hide();
}
this.route.queryParams.subscribe(params => {
const protocolUrl = params['url'];
@@ -269,15 +287,26 @@ export class AppComponent implements OnInit {
const skipRedirect = sessionStorage.getItem('skip-pwa-redirect') === 'true';
if (!skipRedirect) {
this.showRedirectOverlay.set(true);
this.redirectFailed.set(false);
// Tentiamo il reindirizzamento automatico
setTimeout(() => {
window.location.href = this.protocolLink;
// Se dopo 2 secondi l'utente è ancora qui, probabilmente l'app non è installata
setTimeout(() => {
if (this.showRedirectOverlay()) {
this.redirectFailed.set(true);
localStorage.setItem('pwa-installed', 'false');
}
}, 2000);
}, 800);
}
} else {
// Se non è installata, proponiamo l'installazione immediata per evitare la cache del browser e avere un'esperienza ottimale
const skipInstall = sessionStorage.getItem('skip-pwa-install') === 'true';
if (!skipInstall && (this.settingsService.isAndroid() || this.settingsService.isIos())) {
const isMobile = this.settingsService.isAndroid() || this.settingsService.isIos();
const hasDesktopPrompt = this.settingsService.showInstallButton() || this.settingsService.deferredPrompt();
if (!skipInstall && (isMobile || hasDesktopPrompt)) {
this.showInstallOverlay.set(true);
}
}
@@ -285,6 +314,13 @@ export class AppComponent implements OnInit {
openPwaManual() {
window.location.href = this.protocolLink;
// Se dopo 2 secondi l'utente è ancora qui, probabilmente l'app non è installata
setTimeout(() => {
if (this.showRedirectOverlay()) {
this.redirectFailed.set(true);
localStorage.setItem('pwa-installed', 'false');
}
}, 2000);
}
stayInBrowser() {
@@ -301,6 +337,12 @@ export class AppComponent implements OnInit {
await this.settingsService.installPwa();
this.closeInstallOverlay();
}
async triggerInstallFromRedirect() {
await this.settingsService.installPwa();
sessionStorage.setItem('skip-pwa-redirect', 'true');
this.showRedirectOverlay.set(false);
}
}
export function showFullscreenUpdateOverlay() {