aggiunto schermo nero durante il play audio in playlist

This commit is contained in:
David Frassi
2026-06-18 10:01:34 +02:00
parent b0bb5735c8
commit 6ed90ffff1
10 changed files with 407 additions and 19 deletions
+37 -2
View File
@@ -154,14 +154,19 @@
<ion-icon slot="icon-only" [name]="youtubePlayerService.isPlaying() ? 'pause-sharp' : 'play-sharp'"></ion-icon>
</ion-button>
<span class="player-time-label outfit-font" style="font-size: 0.85rem; color: var(--ion-color-secondary); opacity: 0.8; min-width: 38px; text-align: right; margin-left: 4px;">{{ formatSeconds(youtubePlayerService.videoProgress()) }}</span>
<ion-range
[min]="0"
[max]="youtubePlayerService.videoDuration()"
[value]="youtubePlayerService.videoProgress()"
(ionChange)="onSeek($event)"
color="secondary"
class="global-range">
class="global-range"
style="margin: 0; padding: 0 4px;">
</ion-range>
<span class="player-time-label outfit-font" style="font-size: 0.85rem; color: var(--ion-color-secondary); opacity: 0.8; min-width: 38px; text-align: left; margin-right: 4px;">{{ formatSeconds(youtubePlayerService.videoDuration()) }}</span>
</ng-container>
<ng-template #noAudioMsg>
<div class="no-audio-msg outfit-font" style="flex: 1; text-align: center; font-size: 0.85rem; opacity: 0.6; color: var(--ion-color-medium);">
@@ -258,7 +263,37 @@
</ion-footer>
<!-- Black Screen Overlay -->
<div class="black-screen-overlay" *ngIf="isBlackScreen()" (click)="deactivateBlackScreen()"></div>
<div class="black-screen-overlay" *ngIf="isBlackScreen()" (click)="deactivateBlackScreen()">
<div class="black-screen-content" (click)="$event.stopPropagation()">
<div (click)="deactivateBlackScreen()" style="display: flex; flex-direction: column; align-items: center; gap: 8px; cursor: pointer; width: 100%;">
<ion-icon name="car-outline" class="car-mode-icon"></ion-icon>
<p class="car-mode-text outfit-font">Schermo nero attivo</p>
</div>
<div class="car-mode-canto-info" *ngIf="canto()">
<h2 class="car-mode-canto-title outfit-font">{{ canto()?.titolo }}</h2>
<p class="car-mode-canto-author outfit-font">{{ canto()?.autore }}</p>
</div>
<div class="car-mode-progress outfit-font" *ngIf="youtubePlayerService.currentCantoId()">
<span class="car-mode-time">{{ formatSeconds(youtubePlayerService.videoProgress()) }} / {{ formatSeconds(youtubePlayerService.videoDuration()) }}</span>
</div>
<div class="car-mode-controls">
<ion-button fill="clear" (click)="prevSong()" class="car-mode-btn">
<ion-icon slot="icon-only" name="play-skip-back-sharp"></ion-icon>
</ion-button>
<ion-button fill="clear" (click)="toggleAudio()" class="car-mode-btn">
<ion-icon slot="icon-only" [name]="youtubePlayerService.isPlaying() ? 'pause-sharp' : 'play-sharp'"></ion-icon>
</ion-button>
<ion-button fill="clear" (click)="nextSong()" class="car-mode-btn">
<ion-icon slot="icon-only" name="play-skip-forward-sharp"></ion-icon>
</ion-button>
</div>
<p class="car-mode-subtext outfit-font" (click)="deactivateBlackScreen()">Tocca lo sfondo o l'icona per sbloccare</p>
</div>
</div>
<!-- Hidden Camera Video for Head Navigation (needed for face detection API to run) -->
<video *ngIf="enableCameraNavigation()" id="face-preview-video" muted playsinline autoplay style="position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none;"></video>
+90 -4
View File
@@ -891,11 +891,97 @@ ion-content.full-screen-content {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: #000000;
z-index: 99999;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
background-color: #000000 !important;
z-index: 9999999 !important;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
.black-screen-content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: rgba(255, 255, 255, 0.25);
text-align: center;
padding: 20px;
gap: 12px;
.car-mode-icon {
font-size: 3.5rem;
color: rgba(255, 255, 255, 0.2);
}
.car-mode-text {
font-size: 1.2rem;
font-weight: 600;
margin: 0;
}
.car-mode-subtext {
font-size: 0.85rem;
margin: 0;
opacity: 0.8;
}
.car-mode-canto-info {
text-align: center;
margin-top: 10px;
.car-mode-canto-title {
font-size: 1.4rem;
font-weight: 700;
color: rgba(255, 255, 255, 0.3);
margin: 0 0 4px 0;
}
.car-mode-canto-author {
font-size: 0.95rem;
color: rgba(255, 255, 255, 0.2);
margin: 0;
}
}
.car-mode-progress {
margin-top: 8px;
.car-mode-time {
font-size: 1.1rem;
font-weight: 600;
color: rgba(255, 255, 255, 0.25);
}
}
.car-mode-controls {
display: flex;
align-items: center;
gap: 24px;
margin-top: 15px;
.car-mode-btn {
--color: rgba(255, 255, 255, 0.25);
--padding-start: 8px;
--padding-end: 8px;
height: 48px;
width: 48px;
margin: 0;
ion-icon {
font-size: 1.8rem;
}
&:active {
--color: rgba(255, 255, 255, 0.55);
}
}
}
}
}
.landscape-playlist-btn {
+17 -4
View File
@@ -33,12 +33,15 @@ export class PlayerPage implements OnInit, AfterViewInit, OnDestroy {
if (target && (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable)) {
return;
}
if (event.key === 'ArrowUp') {
if (event.key === 'ArrowUp' || event.key === 'MediaTrackPrevious') {
this.prevSong();
event.preventDefault();
} else if (event.key === 'ArrowDown') {
} else if (event.key === 'ArrowDown' || event.key === 'MediaTrackNext') {
this.nextSong();
event.preventDefault();
} else if (event.key === 'MediaPlayPause') {
this.toggleAudio();
event.preventDefault();
}
}
@@ -322,11 +325,12 @@ export class PlayerPage implements OnInit, AfterViewInit, OnDestroy {
}
}, { allowSignalWrites: true });
// Fullscreen control in landscape mode
// Fullscreen control in landscape mode or when black screen is active
effect(() => {
const isLandscape = this.isLandscapeActive();
const isBlack = this.isBlackScreen();
if (isLandscape) {
if (isLandscape || isBlack) {
this.enterFullscreen();
} else {
this.exitFullscreen();
@@ -1279,4 +1283,13 @@ export class PlayerPage implements OnInit, AfterViewInit, OnDestroy {
this.stopCameraNavigation();
this.channel.close();
}
formatSeconds(seconds: number | undefined | null): string {
if (seconds === undefined || seconds === null || isNaN(seconds)) {
return '0:00';
}
const mins = Math.floor(seconds / 60);
const secs = Math.floor(seconds % 60);
return `${mins}:${secs < 10 ? '0' : ''}${secs}`;
}
}
@@ -150,6 +150,14 @@
</ion-label>
<ion-toggle slot="end" [checked]="settingsService.landscapeProjectionEnabled()" (ionChange)="settingsService.toggleLandscapeProjectionEnabled()" color="secondary"></ion-toggle>
</ion-item>
<ion-item class="transparent-item" lines="none" style="border-top: 1px solid rgba(255,255,255,0.03);">
<ion-icon name="car-outline" slot="start" color="secondary"></ion-icon>
<ion-label class="outfit-font">
<h2 class="settings-item-title">Schermo nero durante l'ascolto</h2>
<p class="settings-item-subtitle">Se attiva la riproduzione in home, mostra uno schermo nero per risparmiare batteria. Tocca per disattivare.</p>
</ion-label>
<ion-toggle slot="end" [checked]="settingsService.carModeBlackScreen()" (ionChange)="settingsService.toggleCarModeBlackScreen()" color="secondary"></ion-toggle>
</ion-item>
</div>
<!-- Comunità -->