134 lines
3.6 KiB
JavaScript
134 lines
3.6 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;
|
|
if (!filter) return items;
|
|
|
|
switch (filter) {
|
|
case "folder":
|
|
return items.filter(item => item.cartella);
|
|
case "location":
|
|
return items.filter(item => item?.gps?.lat && item?.gps?.lng);
|
|
case "type":
|
|
return items.filter(item => item?.mime_type?.startsWith("image/"));
|
|
default:
|
|
return items;
|
|
}
|
|
}
|
|
|
|
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) {
|
|
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;
|
|
})();
|