From 235f1b6d14c9f5e31fc5506ab018d55a26de38d5 Mon Sep 17 00:00:00 2001 From: Kibi Kelburton Date: Sun, 31 May 2026 18:10:35 +0200 Subject: [PATCH] better timestamps --- public/s/js/comments.js | 19 +++++++++++++----- public/s/js/f0ckm.js | 43 ++++++++++++++++++++++++++++++++++++---- src/inc/routes/index.mjs | 2 +- views/user-partial.html | 2 +- 4 files changed, 55 insertions(+), 11 deletions(-) diff --git a/public/s/js/comments.js b/public/s/js/comments.js index c3df664..1da9be1 100644 --- a/public/s/js/comments.js +++ b/public/s/js/comments.js @@ -1959,9 +1959,15 @@ class CommentSystem { setInterval(() => { const timestamps = this.container.querySelectorAll('.comment-time.timeago'); timestamps.forEach(el => { - const dateStr = el.getAttribute('tooltip'); - if (dateStr) { - el.textContent = this.timeAgo(dateStr); + // data-iso stores the raw ISO date for timeAgo calculation; + // the tooltip attribute holds the human-readable formatted date. + const isoStr = el.getAttribute('data-iso') || el.getAttribute('tooltip'); + if (isoStr) { + el.textContent = this.timeAgo(isoStr); + // Keep tooltip in human-readable format + if (window.f0ckFormatDateFull) { + el.setAttribute('tooltip', window.f0ckFormatDateFull(isoStr)); + } } }); }, 30000); @@ -2028,7 +2034,10 @@ class CommentSystem { } const timeAgo = this.timeAgo(comment.created_at); - const fullDate = new Date(comment.created_at).toISOString(); + const isoDate = new Date(comment.created_at).toISOString(); + const fullDate = window.f0ckFormatDateFull + ? window.f0ckFormatDateFull(comment.created_at) + : isoDate; // Parent context marker removed (redundant with back-references) let contextMarker = ''; @@ -2056,7 +2065,7 @@ class CommentSystem { ${contextMarker} ${backlinkHtml} - ${timeAgo} + ${timeAgo}
${content}
${this.renderCommentAttachments(comment.files, comment.content)} diff --git a/public/s/js/f0ckm.js b/public/s/js/f0ckm.js index 63673d2..31d4773 100644 --- a/public/s/js/f0ckm.js +++ b/public/s/js/f0ckm.js @@ -8026,15 +8026,50 @@ document.addEventListener('DOMContentLoaded', () => { // Expose globally so comments.js, user_comments.js, messages.js etc. can use the same i18n-aware implementation window.f0ckTimeAgo = timeAgo; + // Format an ISO date string as DD.MM.YYYY - HH:MM:SS in local time + const formatDateFull = (dateStr) => { + const d = new Date(dateStr); + if (isNaN(d.getTime())) return dateStr; + const pad = n => String(n).padStart(2, '0'); + return `${pad(d.getDate())}.${pad(d.getMonth() + 1)}.${d.getFullYear()} - ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`; + }; + window.f0ckFormatDateFull = formatDateFull; + const updateGlobalTimestamps = () => { document.querySelectorAll('.timeago').forEach(el => { - // Check tooltip attr first (item pages), fall back to data-ts (sidebar, no tooltip) - const dateStr = el.getAttribute('tooltip') || el.getAttribute('data-ts'); - if (dateStr) { - const newTime = timeAgo(dateStr); + // On first run, seed data-iso from the server-rendered tooltip (raw ISO string) + // so we always have a reliable source for time calculations even after the + // tooltip is rewritten to the human-readable DD.MM.YYYY format. + if (!el.dataset.iso && el.hasAttribute('tooltip')) { + el.dataset.iso = el.getAttribute('tooltip'); + } + + // Use data-iso (seeded above) → data-ts (sidebar) → tooltip as fallback + const isoStr = el.dataset.iso || el.getAttribute('data-ts'); + if (isoStr) { + const newTime = timeAgo(isoStr); if (el.textContent !== newTime) { el.textContent = newTime; } + // Update tooltip to show nicely formatted local date instead of raw ISO string + if (el.hasAttribute('tooltip')) { + const niceFull = formatDateFull(isoStr); + if (el.getAttribute('tooltip') !== niceFull) { + el.setAttribute('tooltip', niceFull); + } + } + } + }); + + // Also reformat tooltip on static date elements (e.g. .stat-joined on profiles) + // that carry a data-iso attribute but are NOT .timeago (text content not updated). + document.querySelectorAll('[data-iso][tooltip]:not(.timeago)').forEach(el => { + const isoStr = el.dataset.iso; + if (isoStr) { + const niceFull = formatDateFull(isoStr); + if (el.getAttribute('tooltip') !== niceFull) { + el.setAttribute('tooltip', niceFull); + } } }); }; diff --git a/src/inc/routes/index.mjs b/src/inc/routes/index.mjs index 7cc13b1..107ea0c 100644 --- a/src/inc/routes/index.mjs +++ b/src/inc/routes/index.mjs @@ -147,7 +147,7 @@ export default (router, tpl) => { userData.timestamp = { timeago: lib.timeAgo(userData.created_at, req.lang), - timefull: userData.created_at + timefull: new Date(userData.created_at).toISOString() }; userData.age_days = Math.floor((Date.now() - new Date(userData.created_at).getTime()) / 86400000); diff --git a/views/user-partial.html b/views/user-partial.html index efad9e6..860643b 100644 --- a/views/user-partial.html +++ b/views/user-partial.html @@ -30,7 +30,7 @@ @else
ID: {{ user.user_id || user.id }}
-
{{ t('profile.age_days', { n: user.age_days }) }}
+
{{ t('profile.age_days', { n: user.age_days }) }}
@if(!user.is_ghost)
{{ t('profile.stat_comments') }} {{ count.comments }}
{{ t('profile.stat_tags') }} {{ count.tags }}