nidus-sync/static/js/time-relative.js
Eli Ribble 31947c848a
Move static outside HTML. Start work on TypeScript bundle
It's not strictly HTML, so that's just correct.

This is just worth doing while building the new TypeScript bundle
2026-03-21 03:06:59 +00:00

92 lines
2.4 KiB
JavaScript

/**
* Custom HTML element <time-relative> that displays relative time
* Usage: <time-relative time="2024-01-01T12:00:00Z"></time-relative>
*/
class TimeRelative extends HTMLElement {
constructor() {
super();
this.span = null;
}
static get observedAttributes() {
return ["time"];
}
connectedCallback() {
// Create the span element if it doesn't exist
if (!this.span) {
this.span = document.createElement("span");
this.span.className = "time-relative";
this.appendChild(this.span);
}
this.updateTime();
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === "time" && oldValue !== newValue) {
this.updateTime();
}
}
updateTime() {
if (this.span) {
const timeValue = this.getAttribute("time");
if (timeValue) {
this.span.textContent = this.formatRelativeTime(timeValue);
}
}
}
formatRelativeTime(timestamp) {
const now = new Date();
const date = new Date(timestamp);
const diffInSeconds = Math.floor((now - date) / 1000);
// Time units in seconds
const minute = 60;
const hour = minute * 60;
const day = hour * 24;
const week = day * 7;
const month = day * 30;
const year = day * 365;
if (diffInSeconds < minute) {
return "just now";
} else if (diffInSeconds < hour) {
const minutes = Math.floor(diffInSeconds / minute);
return `${minutes} ${minutes === 1 ? "min" : "min"} ago`;
} else if (diffInSeconds < day) {
const hours = Math.floor(diffInSeconds / hour);
return `${hours} ${hours === 1 ? "hour" : "hours"} ago`;
} else if (diffInSeconds < week) {
const days = Math.floor(diffInSeconds / day);
return `${days} ${days === 1 ? "day" : "days"} ago`;
} else if (diffInSeconds < month) {
const weeks = Math.floor(diffInSeconds / week);
return `${weeks} ${weeks === 1 ? "week" : "weeks"} ago`;
} else if (diffInSeconds < year) {
const months = Math.floor(diffInSeconds / month);
return `${months} ${months === 1 ? "month" : "months"} ago`;
} else {
const years = Math.floor(diffInSeconds / year);
return `${years} ${years === 1 ? "year" : "years"} ago`;
}
}
// Property getter and setter for JavaScript access
get time() {
return this.getAttribute("time");
}
set time(value) {
if (value) {
this.setAttribute("time", value);
} else {
this.removeAttribute("time");
}
}
}
// Register the custom element
customElements.define("time-relative", TimeRelative);