displaying "years" correcty in abyss for old items

This commit is contained in:
2026-05-06 05:28:13 +02:00
parent c9296af0b4
commit b05f0d1d24
6 changed files with 71 additions and 59 deletions

View File

@@ -212,21 +212,21 @@
function timeAgo(iso) { function timeAgo(iso) {
const s = Math.floor((Date.now() - new Date(iso)) / 1000); const s = Math.floor((Date.now() - new Date(iso)) / 1000);
const i = window.f0ckI18n || {}; const i = window.f0ckI18n || {};
const fmt = (tpl, n) => (tpl || '{n}').replace('{n}', n); const fmt = (tpl, n, unit) => (tpl || `{n} ${unit}${n !== 1 ? 's' : ''}`).replace('{n}', n);
const ago = (t) => (i.ta_ago || '{t} ago').replace('{t}', t); const ago = (t) => (i.ta_ago || '{t} ago').replace('{t}', t);
if (s < 60) return i.ta_just_now || i.just_now || 'just now'; if (s < 60) return i.ta_just_now || 'just now';
const m = Math.floor(s / 60); const m = Math.floor(s / 60);
if (m < 60) return ago(fmt(m === 1 ? i.ta_minute : i.ta_minutes, m)); if (m < 60) return ago(fmt(m === 1 ? i.ta_minute : i.ta_minutes, m, 'minute'));
const h = Math.floor(s / 3600); const h = Math.floor(s / 3600);
if (h < 24) return ago(fmt(h === 1 ? i.ta_hour : i.ta_hours, h)); if (h < 24) return ago(fmt(h === 1 ? i.ta_hour : i.ta_hours, h, 'hour'));
const d = Math.floor(s / 86400); const d = Math.floor(s / 86400);
if (d < 7) return ago(fmt(d === 1 ? i.ta_day : i.ta_days, d)); if (d < 7) return ago(fmt(d === 1 ? i.ta_day : i.ta_days, d, 'day'));
const w = Math.floor(d / 7); const w = Math.floor(d / 7);
if (d < 30) return ago(fmt(w === 1 ? i.ta_week : i.ta_weeks, w)); if (d < 30) return ago(fmt(w === 1 ? i.ta_week : i.ta_weeks, w, 'week'));
const mo = Math.floor(d / 30); const mo = Math.floor(d / 30);
if (d < 365) return ago(fmt(mo === 1 ? i.ta_month : i.ta_months, mo)); if (d < 365) return ago(fmt(mo === 1 ? i.ta_month : i.ta_months, mo, 'month'));
const y = Math.floor(d / 365); const y = Math.floor(d / 365);
return ago(fmt(y === 1 ? i.ta_year : i.ta_years, y)); return ago(fmt(y === 1 ? i.ta_year : i.ta_years, y, 'year'));
} }
function hashId() { function hashId() {
// Strip the leading '#' and allow numeric IDs or board/postid format // Strip the leading '#' and allow numeric IDs or board/postid format

View File

@@ -3,6 +3,7 @@ import util from "util";
import db from "./sql.mjs"; import db from "./sql.mjs";
import cfg from "./config.mjs"; import cfg from "./config.mjs";
import { createI18n } from "./i18n.mjs";
@@ -43,11 +44,14 @@ export default new class {
calcSpeed(b, s) { calcSpeed(b, s) {
return (Math.round((b * 8 / s / 1e6) * 1e4) / 1e4); return (Math.round((b * 8 / s / 1e6) * 1e4) / 1e4);
}; };
timeAgo(date) { timeAgo(date, lang = 'en') {
const { t } = createI18n(lang);
const duration = getDuration(~~((new Date() - new Date(date)) / 1e3)); const duration = getDuration(~~((new Date() - new Date(date)) / 1e3));
if (!duration) return "just now"; if (!duration) return t('timeago.just_now');
const { interval, epoch } = duration; const { interval, epoch } = duration;
return `${interval} ${epoch}${interval === 1 ? "" : "s"} ago`; const unitKey = interval === 1 ? `timeago.${epoch}` : `timeago.${epoch}s`;
const timeStr = t(unitKey, { n: interval });
return t('timeago.ago', { t: timeStr });
}; };
md5(str) { md5(str) {
return crypto.createHash('md5').update(str).digest("hex"); return crypto.createHash('md5').update(str).digest("hex");

View File

@@ -290,7 +290,7 @@ export default {
view_mode: fav ? 'favs' : 'uploads' view_mode: fav ? 'favs' : 'uploads'
}; };
}, },
getf0ck: async ({ user: rawUser, tag: rawTag, hall: rawHall, mime: rawMime, itemid: rawItemid, mode, session, strict, exclude, user_id, fav, random, userHall: rawUserHall, userHallOwner: rawUserHallOwner } = {}) => { getf0ck: async ({ user: rawUser, tag: rawTag, hall: rawHall, mime: rawMime, itemid: rawItemid, mode, session, strict, exclude, user_id, fav, random, userHall: rawUserHall, userHallOwner: rawUserHallOwner, lang } = {}) => {
const user = rawUser ? lib.escapeLike(decodeURI(rawUser)) : null; const user = rawUser ? lib.escapeLike(decodeURI(rawUser)) : null;
const tag = lib.parseTag(rawTag ?? null); const tag = lib.parseTag(rawTag ?? null);
let hall = rawHall ?? null; let hall = rawHall ?? null;
@@ -614,7 +614,7 @@ export default {
mime: actitem.mime, mime: actitem.mime,
size: lib.formatSize(actitem.size), size: lib.formatSize(actitem.size),
timestamp: { timestamp: {
timeago: lib.timeAgo(new Date(actitem.stamp * 1e3).toISOString()), timeago: lib.timeAgo(new Date(actitem.stamp * 1e3).toISOString(), lang),
timefull: new Date(actitem.stamp * 1e3).toISOString() timefull: new Date(actitem.stamp * 1e3).toISOString()
}, },
favorites: favorites, favorites: favorites,

View File

@@ -136,7 +136,7 @@ export default (router, tpl) => {
} }
userData.timestamp = { userData.timestamp = {
timeago: lib.timeAgo(userData.created_at), timeago: lib.timeAgo(userData.created_at, req.lang),
timefull: userData.created_at timefull: userData.created_at
}; };
userData.age_days = Math.floor((Date.now() - new Date(userData.created_at).getTime()) / 86400000); userData.age_days = Math.floor((Date.now() - new Date(userData.created_at).getTime()) / 86400000);
@@ -228,7 +228,8 @@ export default (router, tpl) => {
strict: !!(req.query?.strict || req.url.qs?.strict || req.session?.strict_mode), strict: !!(req.query?.strict || req.url.qs?.strict || req.session?.strict_mode),
explicitStrict: !!(req.query?.strict || req.url.qs?.strict), explicitStrict: !!(req.query?.strict || req.url.qs?.strict),
random: req.cookies.random_mode === '1', random: req.cookies.random_mode === '1',
minXdScore: req.params.itemid ? 0 : (req.url.qs?.min_xd !== undefined ? +req.url.qs.min_xd : (req.session?.min_xd_score || 0)) minXdScore: req.params.itemid ? 0 : (req.url.qs?.min_xd !== undefined ? +req.url.qs.min_xd : (req.session?.min_xd_score || 0)),
lang: req.lang
}); });
console.log(`[DEBUG] Checking strict mode: query=${req.query?.strict}, session=${req.session?.strict_mode}, effective=${!!(req.query?.strict || req.url.qs?.strict || req.session?.strict_mode)}`); console.log(`[DEBUG] Checking strict mode: query=${req.query?.strict}, session=${req.session?.strict_mode}, effective=${!!(req.query?.strict || req.url.qs?.strict || req.session?.strict_mode)}`);
console.log(`[${new Date().toISOString()}] [ROUTE] Data fetch complete in ${Date.now() - tRouteStart}ms`); console.log(`[${new Date().toISOString()}] [ROUTE] Data fetch complete in ${Date.now() - tRouteStart}ms`);

View File

@@ -285,7 +285,7 @@ export default (router, tpl) => {
avatar: row.avatar_file ? `/a/${row.avatar_file}` : (row.avatar ? `/t/${row.avatar}.webp` : '/a/default.png'), avatar: row.avatar_file ? `/a/${row.avatar_file}` : (row.avatar ? `/t/${row.avatar}.webp` : '/a/default.png'),
username_color: row.username_color || null, username_color: row.username_color || null,
stamp: row.stamp, stamp: row.stamp,
timeago: lib.timeAgo(new Date(row.stamp * 1e3).toISOString()), timeago: lib.timeAgo(new Date(row.stamp * 1e3).toISOString(), req.lang),
tags: row.tag_list || '', tags: row.tag_list || '',
is_oc: row.is_oc || false, is_oc: row.is_oc || false,
is_faved: row.is_faved || false, is_faved: row.is_faved || false,

View File

@@ -923,49 +923,8 @@
window.f0ckAllowedImages = {{ allowed_comment_images_json }}; window.f0ckAllowedImages = {{ allowed_comment_images_json }};
window.scrollerPublic = {{ private_society ? 'false' : 'true' }}; window.scrollerPublic = {{ private_society ? 'false' : 'true' }};
window.scrollerMimeCats = {{ JSON.stringify(scroller_mime_cats) }}; window.scrollerMimeCats = {{ JSON.stringify(scroller_mime_cats) }};
@if(typeof session !== 'undefined' && session)
window.scrollerUsername = "{{ session.user || '' }}";
window.scrollerDisplayName = "{{ session.display_name || session.user || '' }}";
window.scrollerUserAvatar = "{{ session.avatar_file ? '/a/' + session.avatar_file : (session.avatar ? '/t/' + session.avatar + '.webp' : '/a/default.png') }}";
window.f0ckI18n = { window.f0ckI18n = {
// notifications lang: "{{ lang }}",
notif_upload_approved: "{{ t('notifications.upload_approved_short') }}",
notif_upload_pending: "{{ t('notifications.upload_pending_short') }}",
notif_new_report: "{{ t('notifications.new_report_short') }}",
notif_upload_denied: "{{ t('notifications.upload_denied_short') }}",
notif_upload_deleted: "{{ t('notifications.upload_deleted_short') }}",
notif_upload_success: "{{ t('notifications.upload_success') }}",
notif_upload_error: "{{ t('notifications.upload_error') }}",
notif_replied: "{{ t('notifications.replied_short') }}",
notif_subscribed: "{{ t('notifications.subscribed_short') }}",
notif_mentioned: "{{ t('notifications.mentioned_short') }}",
notif_commented: "{{ t('notifications.commented') }}",
notif_system: "{{ t('notifications.system') }}",
notif_admin: "{{ t('notifications.admin') }}",
notif_moderation: "{{ t('notifications.moderation') }}",
notif_tab_user: "{{ t('nav.notif_tab_user') }}",
notif_tab_system: "{{ t('nav.notif_tab_system') }}",
no_notifications: "{{ t('nav.no_notifications') }}",
// scroller
just_now: "{{ t('scroller.just_now') }}",
add: "{{ t('scroller.add') }}",
update_preset: "{{ t('scroller.update_preset') }}",
update_preset_sub: "{{ t('scroller.update_preset_sub') }}",
no_presets: "{{ t('scroller.no_presets') }}",
copy_clipboard: "{{ t('scroller.copy_clipboard') }}",
copied: "{{ t('scroller.copied') }}",
recent: "{{ t('scroller.recent') }}",
nothing_found: "{{ t('scroller.nothing_found') }}",
adjust_filters: "{{ t('scroller.adjust_filters') }}",
failed_load_comments: "{{ t('scroller.failed_load_comments') }}",
no_custom_emojis: "{{ t('scroller.no_custom_emojis') }}",
login_required: "{{ t('scroller.login_required') }}",
rehost_failed: "{{ t('scroller.rehost_failed') }}",
chan_load_failed: "{{ t('scroller.chan_load_failed') }}",
fetch_failed: "{{ t('scroller.fetch_failed') }}",
invalid_chan_url: "{{ t('scroller.invalid_chan_url') }}",
chan_catalog_failed: "{{ t('scroller.chan_catalog_failed') }}",
anonymous: "{{ t('scroller.anonymous') }}",
// timeago // timeago
ta_just_now: "{{ t('timeago.just_now') }}", ta_just_now: "{{ t('timeago.just_now') }}",
ta_second: "{{ t('timeago.second') }}", ta_second: "{{ t('timeago.second') }}",
@@ -997,8 +956,56 @@
add_to_site_first: "{{ t('scroller.add_to_site_first') }}", add_to_site_first: "{{ t('scroller.add_to_site_first') }}",
// reply // reply
replying_to: "{{ t('scroller.replying_to') }}", replying_to: "{{ t('scroller.replying_to') }}",
reply: "{{ t('scroller.reply') }}" reply: "{{ t('scroller.reply') }}",
// scroller labels
just_now: "{{ t('scroller.just_now') }}",
failed_load_comments: "{{ t('scroller.failed_load_comments') }}",
no_comments: "{{ t('scroller.no_comments') }}",
write_comment: "{{ t('scroller.write_comment') }}",
login_required: "{{ t('scroller.login_required') }}",
login_to_comment: "{{ t('scroller.login_to_comment') }}"
}; };
@if(typeof session !== 'undefined' && session)
window.scrollerUsername = "{{ session.user || '' }}";
window.scrollerDisplayName = "{{ session.display_name || session.user || '' }}";
window.scrollerUserAvatar = "{{ session.avatar_file ? '/a/' + session.avatar_file : (session.avatar ? '/t/' + session.avatar + '.webp' : '/a/default.png') }}";
Object.assign(window.f0ckI18n, {
// notifications
notif_upload_approved: "{{ t('notifications.upload_approved_short') }}",
notif_upload_pending: "{{ t('notifications.upload_pending_short') }}",
notif_new_report: "{{ t('notifications.new_report_short') }}",
notif_upload_denied: "{{ t('notifications.upload_denied_short') }}",
notif_upload_deleted: "{{ t('notifications.upload_deleted_short') }}",
notif_upload_success: "{{ t('notifications.upload_success') }}",
notif_upload_error: "{{ t('notifications.upload_error') }}",
notif_replied: "{{ t('notifications.replied_short') }}",
notif_subscribed: "{{ t('notifications.subscribed_short') }}",
notif_mentioned: "{{ t('notifications.mentioned_short') }}",
notif_commented: "{{ t('notifications.commented') }}",
notif_system: "{{ t('notifications.system') }}",
notif_admin: "{{ t('notifications.admin') }}",
notif_moderation: "{{ t('notifications.moderation') }}",
notif_tab_user: "{{ t('nav.notif_tab_user') }}",
notif_tab_system: "{{ t('nav.notif_tab_system') }}",
no_notifications: "{{ t('nav.no_notifications') }}",
// scroller
add: "{{ t('scroller.add') }}",
update_preset: "{{ t('scroller.update_preset') }}",
update_preset_sub: "{{ t('scroller.update_preset_sub') }}",
no_presets: "{{ t('scroller.no_presets') }}",
copy_clipboard: "{{ t('scroller.copy_clipboard') }}",
copied: "{{ t('scroller.copied') }}",
recent: "{{ t('scroller.recent') }}",
nothing_found: "{{ t('scroller.nothing_found') }}",
adjust_filters: "{{ t('scroller.adjust_filters') }}",
no_custom_emojis: "{{ t('scroller.no_custom_emojis') }}",
rehost_failed: "{{ t('scroller.rehost_failed') }}",
chan_load_failed: "{{ t('scroller.chan_load_failed') }}",
fetch_failed: "{{ t('scroller.fetch_failed') }}",
invalid_chan_url: "{{ t('scroller.invalid_chan_url') }}",
chan_catalog_failed: "{{ t('scroller.chan_catalog_failed') }}",
anonymous: "{{ t('scroller.anonymous') }}"
});
@endif @endif
</script> </script>