This commit is contained in:
Fabio 2026-02-21 09:44:33 +01:00
parent 93d56a4725
commit b842692346
3 changed files with 277 additions and 76 deletions

132
app.js
View file

@ -1,16 +1,54 @@
// ===============================
// CONFIG
// ===============================
const API_URL = 'https://prova.patachina.it/photos'; const API_URL = 'https://prova.patachina.it/photos';
let photosData = [];
let currentPhoto = null;
// ===============================
// DEBUG INIZIALE
// ===============================
console.log("app.js caricato correttamente");
// ===============================
// FETCH DELLE FOTO
// ===============================
async function loadPhotos() { async function loadPhotos() {
const res = await fetch(API_URL); console.log("Inizio fetch:", API_URL);
if (!res.ok) {
console.error('Errore nel fetch', res.status); let res;
try {
res = await fetch(API_URL);
} catch (e) {
console.error("Errore fetch:", e);
return; return;
} }
const data = await res.json();
renderGallery(data); console.log("Status fetch:", res.status);
const text = await res.text();
console.log("Risposta grezza (prime 200 chars):", text.substring(0, 200));
try {
photosData = JSON.parse(text);
console.log("JSON parse OK, numero foto:", photosData.length);
} catch (e) {
console.error("Errore nel parse JSON:", e);
return;
}
renderGallery(photosData);
} }
// ===============================
// RENDER GALLERIA
// ===============================
function renderGallery(photos) { function renderGallery(photos) {
console.log("Render gallery, foto:", photos.length);
const gallery = document.getElementById('gallery'); const gallery = document.getElementById('gallery');
gallery.innerHTML = ''; gallery.innerHTML = '';
@ -19,29 +57,48 @@ function renderGallery(photos) {
thumbDiv.className = 'thumb'; thumbDiv.className = 'thumb';
const img = document.createElement('img'); const img = document.createElement('img');
// anteprima
img.src = `https://prova.patachina.it/${photo.thub1}`; img.src = `https://prova.patachina.it/${photo.thub1}`;
img.alt = photo.name || ''; img.alt = photo.name || '';
img.loading = "lazy";
thumbDiv.appendChild(img); thumbDiv.appendChild(img);
// click: apri immagine grande // Fallback se thub2 manca
const preview = photo.thub2
? `https://prova.patachina.it/${photo.thub2}`
: `https://prova.patachina.it/${photo.thub1}`;
thumbDiv.addEventListener('click', () => { thumbDiv.addEventListener('click', () => {
openModal(`https://prova.patachina.it/${photo.path}`); openModal(
`https://prova.patachina.it/${photo.path}`,
preview,
photo
);
}); });
gallery.appendChild(thumbDiv); gallery.appendChild(thumbDiv);
}); });
} }
// Modal
// ===============================
// MODALE IMMAGINE
// ===============================
const modal = document.getElementById('modal'); const modal = document.getElementById('modal');
const modalImg = document.getElementById('modalImage'); const modalImg = document.getElementById('modalImage');
const modalClose = document.getElementById('modalClose'); const modalClose = document.getElementById('modalClose');
function openModal(src) { function openModal(srcOriginal, srcPreview, photo) {
modalImg.src = src; currentPhoto = photo;
modalImg.src = srcPreview;
modal.classList.add('open'); modal.classList.add('open');
const img = new Image();
img.src = srcOriginal;
img.onload = () => {
modalImg.src = srcOriginal;
};
} }
function closeModal() { function closeModal() {
@ -54,5 +111,56 @@ modal.addEventListener('click', (e) => {
if (e.target === modal) closeModal(); if (e.target === modal) closeModal();
}); });
// avvio
// ===============================
// PANNELLO INFO
// ===============================
const infoPanel = document.getElementById('infoPanel');
const infoBtn = document.getElementById('modalInfoBtn');
infoBtn.addEventListener('click', () => {
if (!currentPhoto) return;
// Gestione sicura GPS null
const gps = currentPhoto.gps || { lat: '-', lng: '-', alt: '-' };
// Cartella estratta dal path
const folder = currentPhoto.path.split('/').slice(2, -1).join('/');
infoPanel.innerHTML = `
<h3>Informazioni</h3>
<div class="info-row"><b>Nome:</b> ${currentPhoto.name}</div>
<div class="info-row"><b>Data:</b> ${currentPhoto.taken_at}</div>
<div class="info-row"><b>Latitudine:</b> ${gps.lat}</div>
<div class="info-row"><b>Longitudine:</b> ${gps.lng}</div>
<div class="info-row"><b>Altitudine:</b> ${gps.alt} m</div>
<div class="info-row"><b>Dimensioni:</b> ${currentPhoto.width} × ${currentPhoto.height}</div>
<div class="info-row"><b>Peso:</b> ${(currentPhoto.size_bytes / 1024 / 1024).toFixed(2)} MB</div>
<div class="info-row"><b>Tipo:</b> ${currentPhoto.mime_type}</div>
<div class="info-row"><b>Cartella:</b> ${folder}</div>
`;
infoPanel.classList.add('open');
});
// Chiudi pannello cliccando fuori
document.addEventListener('click', (e) => {
if (!infoPanel.classList.contains('open')) return;
const clickedInsidePanel = infoPanel.contains(e.target);
const clickedInfoBtn = infoBtn.contains(e.target);
if (!clickedInsidePanel && !clickedInfoBtn) {
infoPanel.classList.remove('open');
}
});
// ===============================
// AVVIO
// ===============================
loadPhotos(); loadPhotos();

View file

@ -2,79 +2,45 @@
<html lang="it"> <html lang="it">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<title>Galleria foto</title> <title>Galleria Foto</title>
<style> <link rel="stylesheet" href="style.css">
body { font-family: sans-serif; margin: 0; padding: 0; }
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 8px;
padding: 8px;
}
.thumb {
cursor: pointer;
overflow: hidden;
border-radius: 4px;
border: 1px solid #ddd;
}
.thumb img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
/* Modal */
.modal {
position: fixed;
inset: 0;
background: rgba(0,0,0,0.8);
display: none;
align-items: center;
justify-content: center;
z-index: 1000;
}
.modal.open {
display: flex;
}
.modal-content {
max-width: 90vw;
max-height: 90vh;
position: relative;
}
.modal-content img {
max-width: 100%;
max-height: 100%;
display: block;
}
.modal-close {
position: absolute;
top: -10px;
right: -10px;
background: #fff;
border-radius: 50%;
width: 28px;
height: 28px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-weight: bold;
border: 1px solid #ccc;
}
</style>
</head> </head>
<body>
<h1 style="margin: 8px;">Galleria foto</h1>
<div id="gallery" class="gallery"></div>
<!-- Modal --> <body>
<header>
<h1>Galleria Foto</h1>
</header>
<main>
<div id="gallery" class="gallery"></div>
</main>
<!-- Modal Immagine -->
<div id="modal" class="modal"> <div id="modal" class="modal">
<div class="modal-content"> <div class="modal-content">
<div class="modal-close" id="modalClose">×</div> <div class="modal-close" id="modalClose">×</div>
<img id="modalImage" src="" alt=""> <img id="modalImage" src="" alt="">
<div class="modal-info-btn" id="modalInfoBtn"></div>
</div> </div>
</div> </div>
<!-- Pannello Info -->
<div id="infoPanel" class="info-panel"></div>
<!-- Eruda Debug Console -->
<script src="https://cdn.jsdelivr.net/npm/eruda"></script>
<script>
eruda.init();
console.log("Eruda inizializzato");
</script>
<!-- Debug immediato -->
<script>
console.log("Caricamento pagina OK");
</script>
<script src="app.js"></script> <script src="app.js"></script>
</body> </body>
</html> </html>

127
style.css Normal file
View file

@ -0,0 +1,127 @@
body {
font-family: sans-serif;
margin: 0;
padding: 0;
background: #fafafa;
}
header {
padding: 10px 15px;
background: #333;
color: white;
}
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 8px;
padding: 10px;
}
.thumb {
cursor: pointer;
overflow: hidden;
border-radius: 4px;
border: 1px solid #ddd;
background: white;
}
.thumb img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
/* Modal */
.modal {
position: fixed;
inset: 0;
background: rgba(0,0,0,0.8);
display: none;
align-items: center;
justify-content: center;
z-index: 1000;
}
.modal.open {
display: flex;
}
.modal-content {
max-width: 90vw;
max-height: 90vh;
position: relative;
}
.modal-content img {
max-width: 100%;
max-height: 100%;
display: block;
}
.modal-close {
position: absolute;
top: -10px;
right: -10px;
background: #fff;
border-radius: 50%;
width: 28px;
height: 28px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-weight: bold;
border: 1px solid #ccc;
}
/* Info Button */
.modal-info-btn {
position: absolute;
bottom: -10px;
right: 40px;
background: #fff;
border-radius: 50%;
width: 28px;
height: 28px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
border: 1px solid #ccc;
font-size: 16px;
z-index: 1500;
}
/* Info Panel */
.info-panel {
position: fixed;
top: 0;
right: -320px;
width: 320px;
height: 100%;
background: #fff;
padding: 16px;
box-shadow: -2px 0 6px rgba(0,0,0,0.25);
transition: right 0.3s ease;
overflow-y: auto;
z-index: 2000;
}
.info-panel.open {
right: 0;
}
.info-panel h3 {
margin-top: 0;
}
.info-row {
margin-bottom: 10px;
}
.info-row b {
display: inline-block;
width: 110px;
}