Make timestamps relative in frontend

This commit is contained in:
Karina Kwiatek 2023-02-16 22:28:26 +01:00
parent 2de6ed9bf9
commit a373f2016b
4 changed files with 50 additions and 3 deletions

View file

@ -0,0 +1,43 @@
import {Controller} from "@hotwired/stimulus";
const INTERVALS = {
"year": 86_400_000 * 365,
"month": 86_400_000 * 30,
"week": 86_400_000 * 7,
"day": 86_400_000,
"hour": 3_600_000,
"minute": 60_000,
"second": 1_000,
};
export default class extends Controller<HTMLTimeElement> {
private formatter: Intl.RelativeTimeFormat;
initialize(): void {
const locale = Intl.RelativeTimeFormat.supportedLocalesOf([document.documentElement.lang, 'en'], { localeMatcher: "lookup" });
this.formatter = new Intl.RelativeTimeFormat(locale, { numeric: 'auto', style: 'long'});
}
connect(): void {
const date = new Date(this.element.dateTime);
// convert date to timestamp by casting to number
const now = +new Date();
const then = +date;
const delta = then - now;
this.element.innerText = this.formatTime(delta);
}
formatTime(delta: number): string {
for (const unit in INTERVALS) {
const duration = INTERVALS[unit];
const count = Math.floor(delta / duration);
if (count < -1) {
return this.formatter.format(count, unit as Intl.RelativeTimeFormatUnitSingular);
}
}
return this.formatter.format(0, 'second');
}
}

View file

@ -9,6 +9,7 @@ import ThemeController from "retrospring/controllers/theme_controller";
import CapabilitiesController from "retrospring/controllers/capabilities_controller";
import CropperController from "retrospring/controllers/cropper_controller";
import InboxSharingController from "retrospring/controllers/inbox_sharing_controller";
import TimestampController from "retrospring/controllers/timestamp_controller";
import ToastController from "retrospring/controllers/toast_controller";
/**
@ -30,5 +31,6 @@ export default function (): void {
window['Stimulus'].register('format-popup', FormatPopupController);
window['Stimulus'].register('inbox-sharing', InboxSharingController);
window['Stimulus'].register('theme', ThemeController);
window['Stimulus'].register('timestamp', TimestampController);
window['Stimulus'].register('toast', ToastController);
}

View file

@ -19,14 +19,16 @@
%h6.answerbox__answer-user
= raw t(".answered", hide: hidespan(t(".hide"), "d-none d-sm-inline"), user: user_screen_name(a.user))
.answerbox__answer-date
= link_to(raw(t("time.distance_ago", time: time_tooltip(a))), answer_path(a.user.screen_name, a.id))
= link_to(answer_path(a.user.screen_name, a.id)) do
%time{ datetime: a.created_at.iso8601, data: { controller: "timestamp" } }= a.created_at
.col-md-6.d-flex.d-md-block.answerbox__actions
= render "answerbox/actions", a: a, display_all: display_all
- else
.row
.col-md-6.text-start.text-muted
%i.fa.fa-clock-o
= link_to(raw(t("time.distance_ago", time: time_tooltip(a))), answer_path(a.user.screen_name, a.id), class: "answerbox__permalink")
= link_to(answer_path(a.user.screen_name, a.id), class: "answerbox__permalink") do
%time{ datetime: a.created_at.iso8601, data: { controller: "timestamp" } }= a.created_at
- if a.pinned_at.present?
%span.answerbox__pinned
·

View file

@ -4,7 +4,7 @@
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"lib": ["es6", "dom"],
"lib": ["es6", "es2020", "dom"],
"module": "es6",
"moduleResolution": "node",
"resolveJsonModule": true,