Update zanzara.php

This commit is contained in:
gmarco 2026-05-03 19:58:08 +02:00
parent 426faa5212
commit 39fac9c161

View file

@ -12,26 +12,18 @@ $config = [
/** /**
* Scansiona ricorsivamente le directory per trovare i file mp3 * Scansiona ricorsivamente le directory per trovare i file mp3
*
* @param string $dir Directory da scansionare
* @param array $config Configurazione
* @return array Array di date valide (formato YYYYMMDD)
*/ */
function findValidDates($dir, $config) { function findValidDates($dir, $config) {
$validDates = []; $validDates = [];
// Costruisci il percorso completo
$fullPath = $config['base_dir'] . DIRECTORY_SEPARATOR . $dir; $fullPath = $config['base_dir'] . DIRECTORY_SEPARATOR . $dir;
if (!is_dir($fullPath)) { if (!is_dir($fullPath)) {
return $validDates; return $validDates;
} }
// Scansiona tutte le sottodirectory (anni)
$years = scandir($fullPath); $years = scandir($fullPath);
foreach ($years as $year) { foreach ($years as $year) {
// Salta . e .. e verifica che sia una directory anno valida
if ($year === '.' || $year === '..' || !preg_match('/^\d{4}$/', $year)) { if ($year === '.' || $year === '..' || !preg_match('/^\d{4}$/', $year)) {
continue; continue;
} }
@ -42,18 +34,15 @@ function findValidDates($dir, $config) {
continue; continue;
} }
// Scansiona i file nella directory dell'anno
$files = scandir($yearPath); $files = scandir($yearPath);
foreach ($files as $file) { foreach ($files as $file) {
// Verifica se il file corrisponde al pattern
if (preg_match($config['file_pattern'], $file, $matches)) { if (preg_match($config['file_pattern'], $file, $matches)) {
$validDates[] = $matches[1]; $validDates[] = $matches[1];
} }
} }
} }
// Ordina le date in ordine cronologico
sort($validDates); sort($validDates);
return $validDates; return $validDates;
@ -63,7 +52,6 @@ function findValidDates($dir, $config) {
* Ottiene le date valide con cache * Ottiene le date valide con cache
*/ */
function getValidDates($config) { function getValidDates($config) {
// Verifica se usare la cache
$useCache = false; $useCache = false;
if (file_exists($config['cache_file'])) { if (file_exists($config['cache_file'])) {
$cacheAge = time() - filemtime($config['cache_file']); $cacheAge = time() - filemtime($config['cache_file']);
@ -73,13 +61,10 @@ function getValidDates($config) {
} }
if ($useCache) { if ($useCache) {
// Usa i dati dalla cache
return json_decode(file_get_contents($config['cache_file']), true); return json_decode(file_get_contents($config['cache_file']), true);
} else { } else {
// Scansiona le directory
$validDates = findValidDates($config['dirfiles'], $config); $validDates = findValidDates($config['dirfiles'], $config);
// Salva nella cache (se la directory cache esiste)
$cacheDir = dirname($config['cache_file']); $cacheDir = dirname($config['cache_file']);
if (is_dir($cacheDir) || @mkdir($cacheDir, 0755, true)) { if (is_dir($cacheDir) || @mkdir($cacheDir, 0755, true)) {
file_put_contents($config['cache_file'], json_encode($validDates)); file_put_contents($config['cache_file'], json_encode($validDates));
@ -89,9 +74,7 @@ function getValidDates($config) {
} }
} }
// Funzione per validare e formattare la data
function validateDate($date) { function validateDate($date) {
// Verifica se la data è nel formato YYYYMMDD
if (!preg_match('/^\d{8}$/', $date)) { if (!preg_match('/^\d{8}$/', $date)) {
return false; return false;
} }
@ -100,11 +83,9 @@ function validateDate($date) {
$month = substr($date, 4, 2); $month = substr($date, 4, 2);
$day = substr($date, 6, 2); $day = substr($date, 6, 2);
// Verifica se è una data valida
return checkdate($month, $day, $year) ? $date : false; return checkdate($month, $day, $year) ? $date : false;
} }
// Funzione per generare il percorso del file
function generateFilePath($date, $config) { function generateFilePath($date, $config) {
$year = substr($date, 0, 4); $year = substr($date, 0, 4);
@ -168,14 +149,12 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
min-height: 100vh; min-height: 100vh;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
/* Disabilita selezione testo per sicurezza aggiuntiva */
-webkit-user-select: none; -webkit-user-select: none;
-moz-user-select: none; -moz-user-select: none;
-ms-user-select: none; -ms-user-select: none;
user-select: none; user-select: none;
} }
/* Permetti selezione solo negli input */
input[type="text"] { input[type="text"] {
-webkit-user-select: text; -webkit-user-select: text;
-moz-user-select: text; -moz-user-select: text;
@ -256,6 +235,7 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
transform: scale(1.05); transform: scale(1.05);
} }
/* MODIFICA: font più grande e data in evidenza */
.episode-info { .episode-info {
background-color: #e8f4f8; background-color: #e8f4f8;
color: #2c5282; color: #2c5282;
@ -270,10 +250,9 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
min-width: 400px; min-width: 400px;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
font-size: 1.4rem;
} }
input[type="text"] { input[type="text"] {
border: 1px solid #ccc; border: 1px solid #ccc;
border-radius: 4px; border-radius: 4px;
@ -297,7 +276,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
margin-top: 40px; margin-top: 40px;
} }
/* Stili specifici dell'applicazione */
.container { .container {
width: 100%; width: 100%;
max-width: 800px; max-width: 800px;
@ -354,14 +332,12 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
margin-top: 20px; margin-top: 20px;
} }
/* PLAYER AUDIO CUSTOM SEMPLICE */ /* PLAYER AUDIO CUSTOM */
/* Nascondi il player nativo */
audio { audio {
display: none; display: none;
} }
/* Container del player custom */
.custom-audio-player { .custom-audio-player {
background-color: #f8f9fa; background-color: #f8f9fa;
border: 1px solid #dee2e6; border: 1px solid #dee2e6;
@ -373,7 +349,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
box-shadow: 0 2px 4px rgba(0,0,0,0.1); box-shadow: 0 2px 4px rgba(0,0,0,0.1);
} }
/* Layout principale centrato */
.player-layout { .player-layout {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -381,14 +356,12 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
gap: 20px; gap: 20px;
} }
/* Controlli principali con navigazione */
.main-controls { .main-controls {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 15px; gap: 15px;
} }
/* Pulsanti di navigazione */
.nav-btn { .nav-btn {
width: 50px; width: 50px;
height: 50px; height: 50px;
@ -420,7 +393,14 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
pointer-events: none; pointer-events: none;
} }
/* Pulsante Play/Pause */ .seek-btn {
background-color: #4169E1;
}
.seek-btn:hover:not(:disabled) {
background-color: #1E90FF;
}
.play-pause-btn { .play-pause-btn {
width: 70px; width: 70px;
height: 70px; height: 70px;
@ -451,7 +431,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
pointer-events: none; pointer-events: none;
} }
/* Container per barra del progresso e tempi */
.progress-container { .progress-container {
width: 100%; width: 100%;
display: flex; display: flex;
@ -459,7 +438,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
gap: 10px; gap: 10px;
} }
/* Container dei tempi con data */
.time-info { .time-info {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@ -467,7 +445,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
width: 100%; width: 100%;
} }
/* Display del tempo */
.time-display { .time-display {
font-size: 18px; font-size: 18px;
font-weight: 600; font-weight: 600;
@ -475,19 +452,15 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
font-variant-numeric: tabular-nums; font-variant-numeric: tabular-nums;
} }
/* Barra del progresso più alta */
.progress-bar { .progress-bar {
width: 100%; width: 100%;
height: 40px; /* Altezza totale con padding */ height: 40px;
cursor: pointer; cursor: pointer;
position: relative; position: relative;
overflow: visible; overflow: visible;
/* Padding per area cliccabile più grande */
padding: 10px 0; padding: 10px 0;
/* Rimuovo il background dal contenitore principale */
} }
/* Sfondo grigio della barra */
.progress-bar::before { .progress-bar::before {
content: ''; content: '';
position: absolute; position: absolute;
@ -514,12 +487,11 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
width: 0%; width: 0%;
transition: background-color 0.3s ease; transition: background-color 0.3s ease;
position: absolute; position: absolute;
top: 10px; /* Allineato perfettamente con ::before */ top: 10px;
left: 0; left: 0;
pointer-events: none; pointer-events: none;
} }
/* Indicatore sulla barra più grande */
.progress-fill::after { .progress-fill::after {
content: ''; content: '';
position: absolute; position: absolute;
@ -536,29 +508,11 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
pointer-events: none; pointer-events: none;
} }
/* Stato durante il dragging */
.dragging .progress-fill::after { .dragging .progress-fill::after {
transform: translateY(-50%) scale(1.3); transform: translateY(-50%) scale(1.3);
box-shadow: 0 4px 10px rgba(0,0,0,0.4); box-shadow: 0 4px 10px rgba(0,0,0,0.4);
} }
/* Container dei tempi */
.time-info {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
}
/* Display del tempo */
.time-display {
font-size: 18px;
font-weight: 600;
color: #333;
font-variant-numeric: tabular-nums;
}
/* Pulsante Share inline */
.share-btn-inline { .share-btn-inline {
background-color: #6c757d; background-color: #6c757d;
color: white; color: white;
@ -587,7 +541,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
fill: currentColor; fill: currentColor;
} }
/* Messaggio di conferma */
.share-success { .share-success {
position: fixed; position: fixed;
top: 50%; top: 50%;
@ -608,12 +561,10 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
opacity: 0.9; opacity: 0.9;
} }
/* Stato buffering */
.buffering .play-pause-btn { .buffering .play-pause-btn {
animation: pulse 1.5s ease-in-out infinite; animation: pulse 1.5s ease-in-out infinite;
} }
/* Icone play/pause */
.play-icon { .play-icon {
display: block; display: block;
} }
@ -630,9 +581,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
display: block; display: block;
} }
/* Stili per il calendario */
.ui-datepicker td.available a { .ui-datepicker td.available a {
background-color: #90EE90 !important; background-color: #90EE90 !important;
color: #000 !important; color: #000 !important;
@ -643,7 +591,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
color: #999 !important; color: #999 !important;
} }
/* Stili per le statistiche */
.stats { .stats {
margin-top: 40px; margin-top: 40px;
padding: 20px; padding: 20px;
@ -689,7 +636,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
color: #666; color: #666;
} }
/* Tooltip per scorciatoie */
.shortcuts-info { .shortcuts-info {
position: fixed; position: fixed;
bottom: 20px; bottom: 20px;
@ -732,11 +678,9 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
align-items: stretch; align-items: stretch;
min-width: auto; /* Rimuovo min-width su mobile */ min-width: auto;
} }
.form-group button { .form-group button {
width: 100%; width: 100%;
padding: 12px; padding: 12px;
@ -756,12 +700,10 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
order: 2; order: 2;
} }
.episode-info { .episode-info {
padding: 10px 15px; padding: 10px 15px;
font-size: 14px; font-size: 1.2rem;
min-width: auto; /* Rimuovo min-width su mobile */ min-width: auto;
} }
.share-btn-inline { .share-btn-inline {
@ -786,7 +728,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
line-height: 22px; line-height: 22px;
} }
/* Player custom su mobile */
.custom-audio-player { .custom-audio-player {
padding: 20px; padding: 20px;
margin: 15px 0; margin: 15px 0;
@ -867,7 +808,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
} }
} }
/* Media query per schermi molto piccoli */
@media (max-width: 380px) { @media (max-width: 380px) {
h1 { h1 {
font-size: 1.3rem; font-size: 1.3rem;
@ -922,18 +862,15 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
<main> <main>
<?php <?php
// Gestione link condiviso - se c'è un parametro date nel GET, lo uso
if (isset($_GET['date']) && !empty($_GET['date'])) { if (isset($_GET['date']) && !empty($_GET['date'])) {
$_POST['datepicker'] = $_GET['date']; $_POST['datepicker'] = $_GET['date'];
} }
// Salvo il timestamp se presente per usarlo nel player
$startTime = 0; $startTime = 0;
if (isset($_GET['t']) && is_numeric($_GET['t'])) { if (isset($_GET['t']) && is_numeric($_GET['t'])) {
$startTime = intval($_GET['t']); $startTime = intval($_GET['t']);
} }
// Gestione puntata random
if (isset($_POST['random']) && $_POST['random'] == '1') { if (isset($_POST['random']) && $_POST['random'] == '1') {
$validDates = getValidDates($config); $validDates = getValidDates($config);
if (count($validDates) > 0) { if (count($validDates) > 0) {
@ -942,7 +879,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
} }
} }
// Determina il valore da mostrare nell'input
$inputValue = ''; $inputValue = '';
if (isset($_POST['datepicker']) && !empty($_POST['datepicker'])) { if (isset($_POST['datepicker']) && !empty($_POST['datepicker'])) {
$inputValue = $_POST['datepicker']; $inputValue = $_POST['datepicker'];
@ -973,7 +909,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
<?php <?php
// Gestione della richiesta
if (isset($_POST['datepicker']) && !empty($_POST['datepicker'])) { if (isset($_POST['datepicker']) && !empty($_POST['datepicker'])) {
$selectedDate = validateDate($_POST['datepicker']); $selectedDate = validateDate($_POST['datepicker']);
@ -983,27 +918,24 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
echo '<div class="result">'; echo '<div class="result">';
if (file_exists($paths['local_path'])) { if (file_exists($paths['local_path'])) {
// File trovato
$year = substr($selectedDate, 0, 4); $year = substr($selectedDate, 0, 4);
$month = substr($selectedDate, 4, 2); $month = substr($selectedDate, 4, 2);
$day = substr($selectedDate, 6, 2); $day = substr($selectedDate, 6, 2);
$formattedDate = sprintf("%s/%s/%s", $day, $month, $year); $formattedDate = sprintf("%s/%s/%s", $day, $month, $year);
// Ottieni dimensione file
$fileSize = filesize($paths['local_path']); $fileSize = filesize($paths['local_path']);
$fileSizeMB = round($fileSize / 1024 / 1024, 1); $fileSizeMB = round($fileSize / 1024 / 1024, 1);
// Trova puntata precedente e successiva
$validDates = getValidDates($config); $validDates = getValidDates($config);
$currentIndex = array_search($selectedDate, $validDates); $currentIndex = array_search($selectedDate, $validDates);
$prevDate = ($currentIndex > 0) ? $validDates[$currentIndex - 1] : null; $prevDate = ($currentIndex > 0) ? $validDates[$currentIndex - 1] : null;
$nextDate = ($currentIndex < count($validDates) - 1) ? $validDates[$currentIndex + 1] : null; $nextDate = ($currentIndex < count($validDates) - 1) ? $validDates[$currentIndex + 1] : null;
// Mostra se è una puntata random // MODIFICA: data grande e leggibile, MB in piccolo
if (isset($_POST['random']) && $_POST['random'] == '1') { if (isset($_POST['random']) && $_POST['random'] == '1') {
echo '<p class="episode-info">🎲 Random episode • <strong>' . htmlspecialchars($formattedDate) . '</strong> • ' . $fileSizeMB . ' MB</p>'; echo '<p class="episode-info">🎲 <strong>' . htmlspecialchars($formattedDate) . '</strong> <span style="font-size:0.75em;opacity:0.65;">• ' . $fileSizeMB . ' MB</span></p>';
} else { } else {
echo '<p class="episode-info">Selected episode • <strong>' . htmlspecialchars($formattedDate) . '</strong> • ' . $fileSizeMB . ' MB</p>'; echo '<p class="episode-info"><strong>' . htmlspecialchars($formattedDate) . '</strong> <span style="font-size:0.75em;opacity:0.65;">• ' . $fileSizeMB . ' MB</span></p>';
} }
// Audio player custom // Audio player custom
@ -1012,13 +944,10 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
<source src="' . htmlspecialchars($paths['url']) . '" type="audio/mp3"> <source src="' . htmlspecialchars($paths['url']) . '" type="audio/mp3">
</audio>'; </audio>';
// Layout principale
echo '<div class="player-layout">'; echo '<div class="player-layout">';
// Controlli principali con navigazione
echo '<div class="main-controls">'; echo '<div class="main-controls">';
// Pulsante precedente
if ($prevDate) { if ($prevDate) {
echo '<button class="nav-btn prev-btn" id="prevBtn" data-date="' . $prevDate . '" title="Previous day"> echo '<button class="nav-btn prev-btn" id="prevBtn" data-date="' . $prevDate . '" title="Previous day">
<svg viewBox="0 0 24 24"> <svg viewBox="0 0 24 24">
@ -1033,7 +962,13 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
</button>'; </button>';
} }
// Pulsante Play/Pause echo '<button class="nav-btn seek-btn" id="seekBackBtn" title="-30 seconds">
<svg viewBox="0 0 24 24">
<path d="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z"/>
<text x="12" y="15.5" text-anchor="middle" font-size="5.5" font-family="sans-serif" font-weight="bold" fill="white">30</text>
</svg>
</button>';
echo '<button class="play-pause-btn" id="playPauseBtn" title="Play/Pause"> echo '<button class="play-pause-btn" id="playPauseBtn" title="Play/Pause">
<svg class="play-icon" viewBox="0 0 24 24"> <svg class="play-icon" viewBox="0 0 24 24">
<path d="M8 5v14l11-7z"/> <path d="M8 5v14l11-7z"/>
@ -1043,7 +978,13 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
</svg> </svg>
</button>'; </button>';
// Pulsante successivo echo '<button class="nav-btn seek-btn" id="seekFwdBtn" title="+30 seconds">
<svg viewBox="0 0 24 24">
<path d="M12 5V1l5 5-5 5V7c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6h2c0 4.42-3.58 8-8 8s-8-3.58-8-8 3.58-8 8-8z"/>
<text x="12" y="15.5" text-anchor="middle" font-size="5.5" font-family="sans-serif" font-weight="bold" fill="white">30</text>
</svg>
</button>';
if ($nextDate) { if ($nextDate) {
echo '<button class="nav-btn next-btn" id="nextBtn" data-date="' . $nextDate . '" title="Next day"> echo '<button class="nav-btn next-btn" id="nextBtn" data-date="' . $nextDate . '" title="Next day">
<svg viewBox="0 0 24 24"> <svg viewBox="0 0 24 24">
@ -1058,9 +999,8 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
</button>'; </button>';
} }
echo '</div>'; // Chiude main-controls echo '</div>'; // main-controls
// Container progresso
echo '<div class="progress-container">'; echo '<div class="progress-container">';
echo '<div class="progress-bar" id="progressBar"> echo '<div class="progress-bar" id="progressBar">
<div class="progress-fill" id="progressFill"></div> <div class="progress-fill" id="progressFill"></div>
@ -1076,10 +1016,9 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
echo '</div>'; echo '</div>';
echo '</div>'; echo '</div>';
echo '</div>'; // Chiude player-layout echo '</div>'; // player-layout
echo '</div>'; // Chiude custom-audio-player echo '</div>'; // custom-audio-player
// JavaScript per il player
echo '<script> echo '<script>
(function() { (function() {
const audio = document.getElementById("audio"); const audio = document.getElementById("audio");
@ -1091,11 +1030,12 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
const audioPlayer = document.getElementById("audioPlayer"); const audioPlayer = document.getElementById("audioPlayer");
const prevBtn = document.getElementById("prevBtn"); const prevBtn = document.getElementById("prevBtn");
const nextBtn = document.getElementById("nextBtn"); const nextBtn = document.getElementById("nextBtn");
const seekBackBtn = document.getElementById("seekBackBtn");
const seekFwdBtn = document.getElementById("seekFwdBtn");
let isPlaying = false; let isPlaying = false;
let isDragging = false; let isDragging = false;
// Formatta il tempo
function formatTime(seconds) { function formatTime(seconds) {
if (isNaN(seconds)) return "0:00"; if (isNaN(seconds)) return "0:00";
const mins = Math.floor(seconds / 60); const mins = Math.floor(seconds / 60);
@ -1103,20 +1043,15 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
return mins + ":" + (secs < 10 ? "0" : "") + secs; return mins + ":" + (secs < 10 ? "0" : "") + secs;
} }
// Funzione per aggiornare la posizione
function updateProgress(e) { function updateProgress(e) {
const rect = progressBar.getBoundingClientRect(); const rect = progressBar.getBoundingClientRect();
let x; let x;
// Supporto per touch e mouse
if (e.touches) { if (e.touches) {
x = e.touches[0].clientX - rect.left; x = e.touches[0].clientX - rect.left;
} else { } else {
x = e.clientX - rect.left; x = e.clientX - rect.left;
} }
const clickPercent = Math.max(0, Math.min(1, x / rect.width)); const clickPercent = Math.max(0, Math.min(1, x / rect.width));
if (audio.duration) { if (audio.duration) {
audio.currentTime = clickPercent * audio.duration; audio.currentTime = clickPercent * audio.duration;
progressFill.style.width = (clickPercent * 100) + "%"; progressFill.style.width = (clickPercent * 100) + "%";
@ -1124,7 +1059,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
} }
} }
// Play/Pause
playPauseBtn.addEventListener("click", function() { playPauseBtn.addEventListener("click", function() {
if (isPlaying) { if (isPlaying) {
audio.pause(); audio.pause();
@ -1133,7 +1067,14 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
} }
}); });
// Navigazione giorni seekBackBtn.addEventListener("click", function() {
audio.currentTime = Math.max(0, audio.currentTime - 30);
});
seekFwdBtn.addEventListener("click", function() {
audio.currentTime = Math.min(audio.duration || 0, audio.currentTime + 30);
});
if (prevBtn && !prevBtn.disabled) { if (prevBtn && !prevBtn.disabled) {
prevBtn.addEventListener("click", function() { prevBtn.addEventListener("click", function() {
const form = document.createElement("form"); const form = document.createElement("form");
@ -1184,11 +1125,8 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
audioPlayer.classList.remove("playing"); audioPlayer.classList.remove("playing");
}); });
// Aggiorna durata quando disponibile
audio.addEventListener("loadedmetadata", function() { audio.addEventListener("loadedmetadata", function() {
durationDisplay.textContent = formatTime(audio.duration); durationDisplay.textContent = formatTime(audio.duration);
// Se c\'è un timestamp di inizio, posiziona il player
' . (isset($startTime) && $startTime > 0 ? ' ' . (isset($startTime) && $startTime > 0 ? '
audio.currentTime = ' . $startTime . '; audio.currentTime = ' . $startTime . ';
currentTimeDisplay.textContent = formatTime(' . $startTime . '); currentTimeDisplay.textContent = formatTime(' . $startTime . ');
@ -1197,7 +1135,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
' : '') . ' ' : '') . '
}); });
// Aggiorna progresso durante la riproduzione
audio.addEventListener("timeupdate", function() { audio.addEventListener("timeupdate", function() {
if (!isDragging && audio.duration) { if (!isDragging && audio.duration) {
const progress = (audio.currentTime / audio.duration) * 100; const progress = (audio.currentTime / audio.duration) * 100;
@ -1206,7 +1143,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
} }
}); });
// Eventi Mouse
progressBar.addEventListener("mousedown", function(e) { progressBar.addEventListener("mousedown", function(e) {
isDragging = true; isDragging = true;
audioPlayer.classList.add("dragging"); audioPlayer.classList.add("dragging");
@ -1215,9 +1151,7 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
}); });
document.addEventListener("mousemove", function(e) { document.addEventListener("mousemove", function(e) {
if (isDragging) { if (isDragging) { updateProgress(e); }
updateProgress(e);
}
}); });
document.addEventListener("mouseup", function() { document.addEventListener("mouseup", function() {
@ -1227,7 +1161,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
} }
}); });
// Eventi Touch
progressBar.addEventListener("touchstart", function(e) { progressBar.addEventListener("touchstart", function(e) {
isDragging = true; isDragging = true;
audioPlayer.classList.add("dragging"); audioPlayer.classList.add("dragging");
@ -1236,10 +1169,7 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
}); });
document.addEventListener("touchmove", function(e) { document.addEventListener("touchmove", function(e) {
if (isDragging) { if (isDragging) { updateProgress(e); e.preventDefault(); }
updateProgress(e);
e.preventDefault();
}
}); });
document.addEventListener("touchend", function() { document.addEventListener("touchend", function() {
@ -1249,20 +1179,15 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
} }
}); });
// Click semplice sulla barra
progressBar.addEventListener("click", function(e) { progressBar.addEventListener("click", function(e) {
if (!isDragging) { if (!isDragging) { updateProgress(e); }
updateProgress(e);
}
}); });
// Auto-play solo se NON è una navigazione (prev/next)
' . (!isset($_POST['navigation']) ? ' ' . (!isset($_POST['navigation']) ? '
audio.play().catch(function(error) { audio.play().catch(function(error) {
console.log("Autoplay blocked:", error); console.log("Autoplay blocked:", error);
});' : '') . ' });' : '') . '
// Gestione buffering
audio.addEventListener("waiting", function() { audio.addEventListener("waiting", function() {
audioPlayer.classList.add("buffering"); audioPlayer.classList.add("buffering");
}); });
@ -1271,7 +1196,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
audioPlayer.classList.remove("buffering"); audioPlayer.classList.remove("buffering");
}); });
// Fine del file
audio.addEventListener("ended", function() { audio.addEventListener("ended", function() {
isPlaying = false; isPlaying = false;
audioPlayer.classList.remove("playing"); audioPlayer.classList.remove("playing");
@ -1279,7 +1203,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
}); });
})(); })();
// Gestione pulsante Share - solo quando c\'è una puntata caricata
(function() { (function() {
const shareBtn = document.getElementById("shareBtn"); const shareBtn = document.getElementById("shareBtn");
if (shareBtn) { if (shareBtn) {
@ -1289,10 +1212,7 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
const dateValue = "' . htmlspecialchars($selectedDate) . '"; const dateValue = "' . htmlspecialchars($selectedDate) . '";
const currentTime = Math.floor(audio.currentTime); const currentTime = Math.floor(audio.currentTime);
let shareUrl = baseUrl + "?date=" + dateValue; let shareUrl = baseUrl + "?date=" + dateValue;
if (currentTime > 0) { shareUrl += "&t=" + currentTime; }
if (currentTime > 0) {
shareUrl += "&t=" + currentTime;
}
if (navigator.share) { if (navigator.share) {
const shareTime = currentTime > 0 ? " at " + formatTime(currentTime) : ""; const shareTime = currentTime > 0 ? " at " + formatTime(currentTime) : "";
@ -1300,9 +1220,7 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
title: "LaZanzara Episode - ' . htmlspecialchars($formattedDate) . '", title: "LaZanzara Episode - ' . htmlspecialchars($formattedDate) . '",
text: "Listen to LaZanzara episode from ' . htmlspecialchars($formattedDate) . '" + shareTime, text: "Listen to LaZanzara episode from ' . htmlspecialchars($formattedDate) . '" + shareTime,
url: shareUrl url: shareUrl
}).catch((error) => { }).catch((error) => { copyToClipboard(shareUrl); });
copyToClipboard(shareUrl);
});
} else { } else {
copyToClipboard(shareUrl); copyToClipboard(shareUrl);
} }
@ -1319,9 +1237,7 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
if (navigator.clipboard) { if (navigator.clipboard) {
navigator.clipboard.writeText(text).then(function() { navigator.clipboard.writeText(text).then(function() {
showShareSuccess("Link copied to clipboard!"); showShareSuccess("Link copied to clipboard!");
}, function() { }, function() { fallbackCopyToClipboard(text); });
fallbackCopyToClipboard(text);
});
} else { } else {
fallbackCopyToClipboard(text); fallbackCopyToClipboard(text);
} }
@ -1353,14 +1269,11 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
} }
successMsg.textContent = message; successMsg.textContent = message;
successMsg.classList.add("show"); successMsg.classList.add("show");
setTimeout(function() { setTimeout(function() { successMsg.classList.remove("show"); }, 2000);
successMsg.classList.remove("show");
}, 2000);
} }
})(); })();
</script>'; </script>';
// Mostra link download solo se configurato
if ($config['show_download_link']) { if ($config['show_download_link']) {
echo '<p class="download"> echo '<p class="download">
Or download directly: Or download directly:
@ -1369,7 +1282,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
</p>'; </p>';
} }
} else { } else {
// File non trovato
echo '<p class="error">File not found for date: ' . echo '<p class="error">File not found for date: ' .
htmlspecialchars($selectedDate) . '</p>'; htmlspecialchars($selectedDate) . '</p>';
} }
@ -1382,7 +1294,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
} }
} }
// Mostra statistiche
$validDates = getValidDates($config); $validDates = getValidDates($config);
$totalFiles = count($validDates); $totalFiles = count($validDates);
if ($totalFiles > 0) { if ($totalFiles > 0) {
@ -1395,13 +1306,10 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
echo '<p>First episode: <strong>' . substr($firstDate, 6, 2) . '/' . substr($firstDate, 4, 2) . '/' . substr($firstDate, 0, 4) . '</strong></p>'; echo '<p>First episode: <strong>' . substr($firstDate, 6, 2) . '/' . substr($firstDate, 4, 2) . '/' . substr($firstDate, 0, 4) . '</strong></p>';
echo '<p>Last episode: <strong>' . substr($lastDate, 6, 2) . '/' . substr($lastDate, 4, 2) . '/' . substr($lastDate, 0, 4) . '</strong></p>'; echo '<p>Last episode: <strong>' . substr($lastDate, 6, 2) . '/' . substr($lastDate, 4, 2) . '/' . substr($lastDate, 0, 4) . '</strong></p>';
// Conta file per anno
$yearCount = []; $yearCount = [];
foreach ($validDates as $date) { foreach ($validDates as $date) {
$year = substr($date, 0, 4); $year = substr($date, 0, 4);
if (!isset($yearCount[$year])) { if (!isset($yearCount[$year])) { $yearCount[$year] = 0; }
$yearCount[$year] = 0;
}
$yearCount[$year]++; $yearCount[$year]++;
} }
@ -1419,7 +1327,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
</main> </main>
</div> </div>
<!-- Keyboard shortcuts indicator -->
<div class="shortcuts-info"> <div class="shortcuts-info">
<strong>Shortcuts:</strong> to navigate | R for random | Space for play/pause <strong>Shortcuts:</strong> to navigate | R for random | Space for play/pause
</div> </div>
@ -1429,46 +1336,40 @@ if (isset($_GET['action']) && $_GET['action'] === 'get_valid_dates') {
<script src="https://code.jquery.com/ui/1.13.3/jquery-ui.js"></script> <script src="https://code.jquery.com/ui/1.13.3/jquery-ui.js"></script>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
// Disabilita il tasto destro del mouse
$(document).on('contextmenu', function(e) { $(document).on('contextmenu', function(e) {
e.preventDefault(); e.preventDefault();
return false; return false;
}); });
// Disabilita il tasto destro specificamente sull'audio player
$(document).on('contextmenu', 'audio', function(e) { $(document).on('contextmenu', 'audio', function(e) {
e.preventDefault(); e.preventDefault();
return false; return false;
}); });
// Array per memorizzare le date valide
var validDates = []; var validDates = [];
// Funzione per verificare se una data è disponibile
function isDateAvailable(date) { function isDateAvailable(date) {
var year = date.getFullYear(); var year = date.getFullYear();
var month = (date.getMonth() + 1).toString().padStart(2, '0'); var month = (date.getMonth() + 1).toString().padStart(2, '0');
var day = date.getDate().toString().padStart(2, '0'); var day = date.getDate().toString().padStart(2, '0');
var dateString = year + month + day; var dateString = year + month + day;
return validDates.includes(dateString); return validDates.includes(dateString);
} }
// Mostra indicatore di caricamento
$('#loading').show(); $('#loading').show();
// Carica le date valide via AJAX
$.getJSON('<?php echo $_SERVER['PHP_SELF']; ?>?action=get_valid_dates', function(data) { $.getJSON('<?php echo $_SERVER['PHP_SELF']; ?>?action=get_valid_dates', function(data) {
validDates = data; validDates = data;
$('#loading').hide(); $('#loading').hide();
// Inizializza il datepicker dopo aver caricato le date // MODIFICA: defaultDate su oggi + yearRange dinamico
$('#datepicker').datepicker({ $('#datepicker').datepicker({
dateFormat: 'yymmdd', dateFormat: 'yymmdd',
changeMonth: true, changeMonth: true,
changeYear: true, changeYear: true,
yearRange: '2008:2025', yearRange: '2008:' + new Date().getFullYear(),
maxDate: '0', maxDate: '0',
defaultDate: new Date(),
beforeShowDay: function(date) { beforeShowDay: function(date) {
var isAvailable = isDateAvailable(date); var isAvailable = isDateAvailable(date);
return [isAvailable, isAvailable ? 'available' : 'unavailable', return [isAvailable, isAvailable ? 'available' : 'unavailable',
@ -1479,39 +1380,37 @@ $(document).ready(function() {
} }
}); });
// Gestione click sul pulsante di selezione data
$('#selectDateBtn').on('click', function(e) { $('#selectDateBtn').on('click', function(e) {
e.preventDefault(); e.preventDefault();
$('#datepicker').datepicker('show'); $('#datepicker').datepicker('show');
}); });
// Aggiungi scorciatoie da tastiera per navigazione
$(document).keydown(function(e) { $(document).keydown(function(e) {
if ($('input:focus').length === 0) { // Solo se non si sta digitando in un input if ($('input:focus').length === 0) {
if (e.key === 'ArrowLeft' && $('.nav-button:first:not(:disabled)').length) { if (e.key === 'ArrowLeft' && $('.nav-button:first:not(:disabled)').length) {
$('.nav-button:first').closest('form').submit(); $('.nav-button:first').closest('form').submit();
} else if (e.key === 'ArrowRight' && $('.nav-button:last:not(:disabled)').length) { } else if (e.key === 'ArrowRight' && $('.nav-button:last:not(:disabled)').length) {
$('.nav-button:last').closest('form').submit(); $('.nav-button:last').closest('form').submit();
} else if (e.key.toLowerCase() === 'r') { } else if (e.key.toLowerCase() === 'r') {
// Scorciatoia per puntata random
$('.random-button').click(); $('.random-button').click();
} else if (e.key === ' ' && $('#playPauseBtn').length) { } else if (e.key === ' ' && $('#playPauseBtn').length) {
// Spazio per play/pause
e.preventDefault(); e.preventDefault();
$('#playPauseBtn').click(); $('#playPauseBtn').click();
} }
} }
}); });
}).fail(function() { }).fail(function() {
$('#loading').hide(); $('#loading').hide();
console.error('Errore nel caricamento delle date valide'); console.error('Errore nel caricamento delle date valide');
// Fallback: datepicker senza validazione // MODIFICA: fallback aggiornato con stesso fix
$('#datepicker').datepicker({ $('#datepicker').datepicker({
dateFormat: 'yymmdd', dateFormat: 'yymmdd',
changeMonth: true, changeMonth: true,
changeYear: true, changeYear: true,
yearRange: '2008:2025', yearRange: '2008:' + new Date().getFullYear(),
maxDate: '0' maxDate: '0',
defaultDate: new Date()
}); });
}); });
}); });
@ -1526,7 +1425,7 @@ $(document).ready(function() {
🔗 Official LaZanzara page 🔗 Official LaZanzara page
</a> </a>
</p> </p>
<p>- - - Powered by FreeBSD. Developed by Gabry, Claude and Gianmarco - v1.1.1 (14/09/2025) - - -</p> <p>- - - Powered by FreeBSD, Gabry, Claude and Gianmarco - v1.1.2 (03/05/2026) - - -</p>
</footer> </footer>
</body> </body>
</html> </html>