chore: save current changes
This commit is contained in:
@@ -412,18 +412,29 @@ export class PlayerPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
const container = document.querySelector('.lyrics-container') as HTMLElement;
|
||||
if (!container) return 3; // Ritorno generico se il contenitore non è pronto
|
||||
|
||||
const containerHeight = container.clientHeight;
|
||||
|
||||
// Calcoliamo la reale altezza visibile sottraendo l'eventuale footer in sovraimpressione
|
||||
let visibleHeight = containerHeight;
|
||||
const containerRect = container.getBoundingClientRect();
|
||||
const visibleTop = Math.max(containerRect.top, 0);
|
||||
let visibleBottom = Math.min(containerRect.bottom, window.innerHeight || document.documentElement.clientHeight);
|
||||
|
||||
const footer = document.querySelector('ion-footer') as HTMLElement;
|
||||
if (footer && footer.offsetHeight > 0) {
|
||||
const computedStyle = window.getComputedStyle(footer);
|
||||
if (computedStyle.display !== 'none') {
|
||||
visibleHeight -= footer.offsetHeight;
|
||||
if (footer) {
|
||||
const footerRect = footer.getBoundingClientRect();
|
||||
if (footerRect.height > 0 && window.getComputedStyle(footer).display !== 'none') {
|
||||
visibleBottom = Math.min(visibleBottom, footerRect.top);
|
||||
}
|
||||
}
|
||||
|
||||
const floatingBar = document.querySelector('.floating-autoscroll-bar') as HTMLElement;
|
||||
if (floatingBar) {
|
||||
const barRect = floatingBar.getBoundingClientRect();
|
||||
if (barRect.height > 0 && window.getComputedStyle(floatingBar).display !== 'none') {
|
||||
visibleBottom = Math.min(visibleBottom, barRect.top);
|
||||
}
|
||||
}
|
||||
|
||||
// Calcoliamo la reale altezza visibile
|
||||
const visibleHeight = Math.max(0, visibleBottom - visibleTop);
|
||||
|
||||
const lineElems = document.querySelectorAll('.lyric-line');
|
||||
|
||||
if (lineElems.length === 0) return 3;
|
||||
@@ -443,7 +454,6 @@ export class PlayerPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
const pageStep = Math.max(1, linesPerPage);
|
||||
|
||||
console.log('[PageScroll] Calcolo dinamico dello scorrimento a pagina (Area visibile depurata):', {
|
||||
containerHeight,
|
||||
visibleHeight,
|
||||
avgLineHeight,
|
||||
linesPerPage,
|
||||
@@ -463,10 +473,10 @@ export class PlayerPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
if (!container) return [];
|
||||
|
||||
const containerRect = container.getBoundingClientRect();
|
||||
const visibleTop = containerRect.top;
|
||||
let visibleBottom = containerRect.bottom;
|
||||
const visibleTop = Math.max(containerRect.top, 0);
|
||||
let visibleBottom = Math.min(containerRect.bottom, window.innerHeight || document.documentElement.clientHeight);
|
||||
|
||||
// Sottrai l'altezza dell'eventuale footer sovrapposto ad alto z-index
|
||||
// Sottrai l'altezza dell'eventuale footer o barra sovrapposti ad alto z-index
|
||||
const footer = document.querySelector('ion-footer') as HTMLElement;
|
||||
if (footer) {
|
||||
const footerRect = footer.getBoundingClientRect();
|
||||
@@ -475,6 +485,14 @@ export class PlayerPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
const floatingBar = document.querySelector('.floating-autoscroll-bar') as HTMLElement;
|
||||
if (floatingBar) {
|
||||
const barRect = floatingBar.getBoundingClientRect();
|
||||
if (barRect.height > 0 && window.getComputedStyle(floatingBar).display !== 'none') {
|
||||
visibleBottom = Math.min(visibleBottom, barRect.top);
|
||||
}
|
||||
}
|
||||
|
||||
const lineElems = document.querySelectorAll('.lyric-line');
|
||||
const visibleIndices: number[] = [];
|
||||
|
||||
@@ -501,7 +519,8 @@ export class PlayerPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
if (!container) return this.currentLineIndex() + 1;
|
||||
|
||||
const containerRect = container.getBoundingClientRect();
|
||||
let visibleBottom = containerRect.bottom;
|
||||
// Assicuriamoci che il limite inferiore non superi l'altezza reale della finestra
|
||||
let visibleBottom = Math.min(containerRect.bottom, window.innerHeight || document.documentElement.clientHeight);
|
||||
|
||||
// Trova la posizione del footer o di qualunque elemento sovrapposto in fondo
|
||||
const footer = document.querySelector('ion-footer') as HTMLElement;
|
||||
@@ -512,8 +531,18 @@ export class PlayerPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
// Sottrai un piccolo margine di tolleranza di 8px
|
||||
const visibleLimitY = visibleBottom - 8;
|
||||
const floatingBar = document.querySelector('.floating-autoscroll-bar') as HTMLElement;
|
||||
if (floatingBar) {
|
||||
const barRect = floatingBar.getBoundingClientRect();
|
||||
if (barRect.height > 0 && window.getComputedStyle(floatingBar).display !== 'none') {
|
||||
visibleBottom = Math.min(visibleBottom, barRect.top);
|
||||
}
|
||||
}
|
||||
|
||||
// Aumentiamo il margine di tolleranza a 24px (o più) per essere sicuri
|
||||
// di non perdere mai una riga parzialmente coperta. Meglio rileggere una riga
|
||||
// in cima alla pagina successiva che perderla completamente a causa dello zoom.
|
||||
const visibleLimitY = visibleBottom - 24;
|
||||
const lineElems = document.querySelectorAll('.lyric-line');
|
||||
|
||||
const totalLines = this.getTotalLines();
|
||||
@@ -546,7 +575,7 @@ export class PlayerPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
next(isAutomatic: boolean = false) {
|
||||
next(isAutomatic: boolean = false, isVisual: boolean = false) {
|
||||
this.lastAdvanceTimestamp = Date.now();
|
||||
|
||||
const totalLines = this.getTotalLines();
|
||||
@@ -571,8 +600,8 @@ export class PlayerPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
nextIdx = this.calculateNextPageStartIndex();
|
||||
}
|
||||
this.lastScrollBlock.set('center');
|
||||
} else if (this.settingsService.karaokePageScrollMode()) {
|
||||
// Modalità manuale a pagine: calcolo analitico preciso per non perdere righe coperte
|
||||
} else if (this.settingsService.karaokePageScrollMode() || isVisual) {
|
||||
// Modalità manuale a pagine (o trigger visuale): calcolo analitico preciso per non perdere righe coperte
|
||||
nextIdx = this.calculateNextPageStartIndex();
|
||||
this.lastScrollBlock.set('start');
|
||||
} else {
|
||||
@@ -588,12 +617,12 @@ export class PlayerPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
|
||||
// Metodi di validazione e freeze rimossi per migliorare affidabilità e prevenire blocchi permanenti
|
||||
|
||||
prev() {
|
||||
prev(isVisual: boolean = false) {
|
||||
this.lastAdvanceTimestamp = Date.now();
|
||||
|
||||
const prevIdx = this.currentLineIndex();
|
||||
if (prevIdx > 0) {
|
||||
const isPageMode = this.settingsService.karaokePageScrollMode();
|
||||
const isPageMode = this.settingsService.karaokePageScrollMode() || isVisual;
|
||||
const stepSize = isPageMode ? this.calculatePageStepSize() : 1;
|
||||
const nextIdx = Math.max(0, prevIdx - stepSize);
|
||||
|
||||
@@ -710,6 +739,36 @@ export class PlayerPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
async editOrCloneCanto() {
|
||||
const c = this.canto();
|
||||
if (!c) return;
|
||||
|
||||
if (
|
||||
this.settingsService.comunitaEnabled() &&
|
||||
this.settingsService.showEditor() &&
|
||||
this.comunitaService.comunitaCode() &&
|
||||
!c.id.startsWith('my_')
|
||||
) {
|
||||
// Clone the song: Title: <original title>
|
||||
const clonedTitle = c.titolo;
|
||||
|
||||
const clonedCanto = await this.myCantiService.saveCanto({
|
||||
titolo: clonedTitle,
|
||||
autore: c.autore,
|
||||
link_youtube: c.link_youtube,
|
||||
testo: c.testo || c.accordi || '',
|
||||
accordi: c.accordi || c.testo || '',
|
||||
id_momenti: c.id_momenti || []
|
||||
});
|
||||
|
||||
// Redirect to the edit page for the newly cloned song
|
||||
this.router.navigate(['/propose-canto'], { queryParams: { editId: clonedCanto.id } });
|
||||
} else {
|
||||
// Standard edit path
|
||||
this.router.navigate(['/propose-canto'], { queryParams: { editId: c.id } });
|
||||
}
|
||||
}
|
||||
|
||||
private initPlayer(id: string) {
|
||||
if (!this.youtubePlayerService.isPlayerSupported()) {
|
||||
return;
|
||||
@@ -757,6 +816,12 @@ export class PlayerPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
return info && info.num_canto ? info.num_canto.toString() : null;
|
||||
}
|
||||
|
||||
getMySongNumber(canto: any): number {
|
||||
if (!canto || !canto.id) return 0;
|
||||
const index = this.myCantiService.myCanti().findIndex(c => c.id === canto.id);
|
||||
return index !== -1 ? index + 1 : 0;
|
||||
}
|
||||
|
||||
toggleAutoscroll() {
|
||||
if (this.isAutoscrolling()) {
|
||||
this.stopAutoscroll();
|
||||
@@ -845,9 +910,9 @@ export class PlayerPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
await this.faceDetector.start(videoEl, (direction) => {
|
||||
console.log(`[PlayerPage] Head tilt trigger received: ${direction}`);
|
||||
if (direction === 'next') {
|
||||
this.next(false);
|
||||
this.next(false, true);
|
||||
} else {
|
||||
this.prev();
|
||||
this.prev(true);
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user