// public/js/galleryUtils.js // Ordinamento, filtri, raggruppamento e formattazione. (() => { "use strict"; function sortByDate(items, direction = "desc") { return items.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; }); } function applyFilters(items) { if (window.state?.mode === "activities") return items; const filter = window.currentFilter || ""; const query = String(window.currentSearch || "") .trim() .toLocaleLowerCase("it-IT"); const selectedYear = window.currentYear ? Number(window.currentYear) : null; const selectedMonth = window.currentMonth ? Number(window.currentMonth) : null; const selectedFolder = String(window.currentFolder || ""); function getFolder(item) { return String(item?.cartella || item?.folder || "").trim(); } function hasGps(item) { const gps = item?.gps; if (!gps) return false; const lat = Number(gps.lat); const lng = Number(gps.lng); return Number.isFinite(lat) && Number.isFinite(lng) && lat >= -90 && lat <= 90 && lng >= -180 && lng <= 180; } function searchableText(item) { return [ item?.name, item?.file_name, item?.filename, item?.originalname, item?.path, item?.relative_path, item?.full_path, item?.cartella, item?.folder ] .filter(value => value !== undefined && value !== null) .join(" ") .toLocaleLowerCase("it-IT"); } return items.filter(item => { const mime = String(item?.mime_type || "").toLowerCase(); if (selectedFolder && getFolder(item) !== selectedFolder) { return false; } switch (filter) { case "folder": if (!(item?.cartella || item?.folder)) return false; break; case "location": if (!hasGps(item)) return false; break; case "type": // Compatibilità con il vecchio pulsante. case "images": if (!mime.startsWith("image/")) return false; break; case "videos": if (!mime.startsWith("video/")) return false; break; } if (query && !searchableText(item).includes(query)) { return false; } if (selectedYear || selectedMonth) { if (!item?.taken_at) return false; const date = new Date(item.taken_at); if (Number.isNaN(date.getTime())) return false; if (selectedYear && date.getFullYear() !== selectedYear) { return false; } if (selectedMonth && date.getMonth() + 1 !== selectedMonth) { return false; } } return true; }); } 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" }); } function groupByDate(items, mode = "auto") { const sections = []; const sectionMap = new Map(); const now = new Date(); function getLabel(item) { if (mode === "folder") { return String(item?.cartella || item?.folder || "").trim() || "Senza cartella"; } const date = item?.taken_at ? new Date(item.taken_at) : null; if (!date || Number.isNaN(date.getTime())) return "Senza data"; const diffDays = Math.floor((now - date) / 86400000); if (mode === "day") return formatDay(date); if (mode === "month") return formatMonth(date); if (mode === "year") return String(date.getFullYear()); 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 String(date.getFullYear()); } for (const item of items) { const label = getLabel(item); let section = sectionMap.get(label); if (!section) { section = { label, items: [] }; sectionMap.set(label, section); sections.push(section); } section.items.push(item); } return sections; } function escapeHtml(value) { return String(value ?? "") .replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll('"', """) .replaceAll("'", "'"); } function formatDurationShort(ms) { const totalSec = Math.round(ms / 1000); const hours = Math.floor(totalSec / 3600); const minutes = Math.floor((totalSec % 3600) / 60); return hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`; } function formatActivityMeta(item) { const parts = []; if (item.sport) parts.push(item.sport); if (Number.isFinite(Number(item.distance_meters))) { parts.push(`${(Number(item.distance_meters) / 1000).toFixed(1)} km`); } if (Number.isFinite(Number(item.duration_millis))) { parts.push(formatDurationShort(Number(item.duration_millis))); } return parts.join(" · "); } window.GalleryUtils = Object.freeze({ sortByDate, applyFilters, groupByDate, formatDay, formatMonth, escapeHtml, formatDurationShort, formatActivityMeta }); // Compatibilità con gli script esistenti. window.sortByDate = sortByDate; window.applyFilters = applyFilters; window.groupByDate = groupByDate; })();