better timestamps

This commit is contained in:
2026-05-31 18:10:35 +02:00
parent 52a18acf40
commit 235f1b6d14
4 changed files with 55 additions and 11 deletions

View File

@@ -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}
</div>
<a href="#c${comment.id}" class="comment-time timeago" tooltip="${fullDate}" data-id="${comment.id}" data-username="${comment.username}" data-display="${this.escapeHtml(comment.display_name || '')}">${timeAgo}</a>
<a href="#c${comment.id}" class="comment-time timeago" tooltip="${fullDate}" data-iso="${isoDate}" data-id="${comment.id}" data-username="${comment.username}" data-display="${this.escapeHtml(comment.display_name || '')}">${timeAgo}</a>
</div>
<div class="comment-content" data-raw="${this.escapeHtml(comment.content)}">${content}</div>
${this.renderCommentAttachments(comment.files, comment.content)}

View File

@@ -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);
}
}
});
};

View File

@@ -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);

View File

@@ -30,7 +30,7 @@
@else
<div class="stat-id">ID: {{ user.user_id || user.id }}</div>
<div class="stat-joined" title="{{ user.timestamp.timefull }}">{{ t('profile.age_days', { n: user.age_days }) }}</div>
<div class="stat-joined" tooltip="{{ user.timestamp.timefull }}" data-iso="{{ user.timestamp.timefull }}">{{ t('profile.age_days', { n: user.age_days }) }}</div>
@if(!user.is_ghost)
<div class="stat-comments">{{ t('profile.stat_comments') }} <a href="/user/{!! user.user !!}/comments">{{ count.comments }}</a></div>
<div class="stat-tags">{{ t('profile.stat_tags') }} {{ count.tags }}</div>