gallery_server_client_s190js/public/js/galleryUtils.js
2026-10-26 11:00:14 +01:00

219 lines
5.7 KiB
JavaScript

// 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("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll('"', "&quot;")
.replaceAll("'", "&#039;");
}
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;
})();