// =============================== // GALLERY — completa, stile Google Photos // - Ordinamento // - Filtri // - Raggruppamento (auto/giorno/mese/anno) // - Render a sezioni // - Click: openModalFromList(sezione, indice) se disponibile (fallback openModal) // =============================== // ORDINAMENTO function sortByDate(photos, direction = "desc") { return photos.slice().sort((a, b) => { const da = a?.taken_at ? new Date(a.taken_at) : 0; const db = b?.taken_at ? new Date(b.taken_at) : 0; return direction === "asc" ? (da - db) : (db - da); }); } // FILTRI function applyFilters(photos) { if (!window.currentFilter) return photos; switch (window.currentFilter) { case "folder": return photos.filter(p => p.folder || (p.path && p.path.includes('/photos/'))); case "location": return photos.filter(p => p?.gps && p.gps.lat); case "type": return photos.filter(p => p?.mime_type && p.mime_type.startsWith("image/")); default: return photos; } } // RAGGRUPPAMENTO STILE GOOGLE PHOTOS function groupByDate(photos, mode = "auto") { const sections = []; const now = new Date(); function getLabel(photo) { const date = photo?.taken_at ? new Date(photo.taken_at) : null; if (!date || isNaN(+date)) return "Senza data"; const diffDays = Math.floor((now - date) / (1000 * 60 * 60 * 24)); if (mode === "day") return formatDay(date); if (mode === "month") return formatMonth(date); if (mode === "year") return date.getFullYear().toString(); if (diffDays === 0) return "Oggi"; if (diffDays === 1) return "Ieri"; if (diffDays <= 7) return "Questa settimana"; if (diffDays <= 14) return "La settimana scorsa"; if (diffDays <= 30) return "Questo mese"; if (diffDays <= 60) return "Mese scorso"; if (date.getFullYear() === now.getFullYear()) return formatMonth(date); return date.getFullYear().toString(); } photos.forEach(photo => { const label = getLabel(photo); let section = sections.find(s => s.label === label); if (!section) { section = { label, photos: [] }; sections.push(section); } section.photos.push(photo); }); return sections; } // FORMATTATORI function formatDay(date) { return date.toLocaleDateString("it-IT", { weekday: "long", day: "numeric", month: "long" }); } function formatMonth(date) { return date.toLocaleDateString("it-IT", { month: "long", year: "numeric" }); } // RENDER function renderGallery(sections) { const gallery = document.getElementById("gallery"); if (!gallery) return; gallery.innerHTML = ""; sections.forEach(section => { const h = document.createElement("h2"); h.className = "gallery-section-title"; h.textContent = section.label; gallery.appendChild(h); const container = document.createElement("div"); container.className = "gallery-section"; section.photos.forEach((photo, idx) => { const thumbDiv = document.createElement("div"); thumbDiv.className = "thumb"; const th1 = (typeof toAbsoluteUrl === 'function') ? toAbsoluteUrl(photo?.thub1) : photo?.thub1; const th2 = (typeof toAbsoluteUrl === 'function') ? toAbsoluteUrl(photo?.thub2 || photo?.thub1) : (photo?.thub2 || photo?.thub1); const original = (typeof toAbsoluteUrl === 'function') ? toAbsoluteUrl(photo?.path) : photo?.path; const img = document.createElement("img"); img.src = th1 || th2 || original || ""; img.alt = photo?.name || ""; img.loading = "lazy"; thumbDiv.appendChild(img); if (photo?.mime_type && photo.mime_type.startsWith("video/")) { const play = document.createElement("div"); play.className = "play-icon"; play.textContent = "▶"; thumbDiv.appendChild(play); } thumbDiv.addEventListener("click", () => { // Chiudi sempre la strip prima di aprire una nuova foto window.closeBottomSheet?.(); if (typeof window.openModalFromList === "function") { window.openModalFromList(section.photos, idx); } else { window.openModal?.(original, th2, photo); } }); container.appendChild(thumbDiv); }); gallery.appendChild(container); }); } // Esporti su window window.sortByDate = sortByDate; window.applyFilters = applyFilters; window.groupByDate = groupByDate; window.renderGallery = renderGallery;