fix(format): relative time labelled every tier one unit too small
The units table paired each divisor with the NEXT row's label, so the count
came out right and the word wrong, all the way up the scale: minutes rendered
as "Ns ago", hours as "N min ago", days as "N hours ago", months as "N weeks
ago". Most visible on the audit log, where scheduler rows three minutes apart
read "1s / 4s / 7s ago".
Each row now carries its own label and is read whole, so a divisor can no
longer drift from its word. Also guard a non-finite age, which rendered
"NaN mo ago", and drop time.secondsAgo now that nothing emits it.
Present since ea317c0 swapped the hardcoded English strings for i18n keys;
shipped in every release from 0.2.0 on.
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"justNow": "just now",
|
||||
"secondsAgo": "{{count}}s ago",
|
||||
"minutesAgo": "{{count}} min ago",
|
||||
"hoursAgo": "{{count}}h ago",
|
||||
"daysAgo": "{{count}}d ago",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"justNow": "épp most",
|
||||
"secondsAgo": "{{count}} mp-e",
|
||||
"minutesAgo": "{{count}} perce",
|
||||
"hoursAgo": "{{count}} órája",
|
||||
"daysAgo": "{{count}} napja",
|
||||
|
||||
+18
-18
@@ -30,27 +30,27 @@ export function formatSpeed(bps: number | null | undefined): string {
|
||||
* set of `time.*` strings — shared instead of re-implemented per component. */
|
||||
export function relativeFromMs(ms: number): string {
|
||||
const secs = Math.max(0, (Date.now() - ms) / 1000);
|
||||
if (!Number.isFinite(secs)) return ""; // unparseable timestamp — say nothing, not "NaN yr ago"
|
||||
// [seconds-per-unit, label] — each label names what its OWN divisor produces, and a row is read
|
||||
// whole (largest unit that fits). Pairing a divisor with the NEXT row's label is what silently
|
||||
// shifted every tier by one from ea317c0 until this fix: minutes rendered as "Ns ago", hours as
|
||||
// "N min ago", on up the scale.
|
||||
const units: [number, string][] = [
|
||||
[60, "time.secondsAgo"],
|
||||
[3600, "time.minutesAgo"],
|
||||
[86400, "time.hoursAgo"],
|
||||
[604800, "time.daysAgo"],
|
||||
[2592000, "time.weeksAgo"],
|
||||
[31536000, "time.monthsAgo"],
|
||||
[60, "time.minutesAgo"],
|
||||
[3600, "time.hoursAgo"],
|
||||
[86400, "time.daysAgo"],
|
||||
[604800, "time.weeksAgo"],
|
||||
[2592000, "time.monthsAgo"],
|
||||
[31536000, "time.yearsAgo"],
|
||||
];
|
||||
if (secs < 60) return i18n.t("time.justNow");
|
||||
for (let i = 0; i < units.length - 1; i++) {
|
||||
const [, key] = units[i];
|
||||
const next = units[i + 1][0];
|
||||
if (secs < next) {
|
||||
const v = Math.floor(secs / units[i][0]);
|
||||
return i18n.t(key, { count: v });
|
||||
}
|
||||
if (secs < units[0][0]) return i18n.t("time.justNow");
|
||||
let [div, key] = units[0];
|
||||
for (const [unitSecs, unitKey] of units) {
|
||||
if (secs < unitSecs) break;
|
||||
div = unitSecs;
|
||||
key = unitKey;
|
||||
}
|
||||
const years = Math.floor(secs / 31536000);
|
||||
if (years >= 1) return i18n.t("time.yearsAgo", { count: years });
|
||||
const months = Math.floor(secs / 2592000);
|
||||
return i18n.t("time.monthsAgo", { count: months });
|
||||
return i18n.t(key, { count: Math.floor(secs / div) });
|
||||
}
|
||||
|
||||
// The canonical YouTube URL for a channel: its @handle when known (nicer), else the
|
||||
|
||||
Reference in New Issue
Block a user