aboutsummaryrefslogtreecommitdiff
path: root/static/js/timeago.ts
diff options
context:
space:
mode:
Diffstat (limited to 'static/js/timeago.ts')
-rw-r--r--static/js/timeago.ts113
1 files changed, 75 insertions, 38 deletions
diff --git a/static/js/timeago.ts b/static/js/timeago.ts
index af974fc..7c1973d 100644
--- a/static/js/timeago.ts
+++ b/static/js/timeago.ts
@@ -8,49 +8,86 @@
style: "long",
});
- const date = () => {
- [...document.querySelectorAll("time")]
- .forEach(
- (element) => {
- try {
- const time: millisecond = new Date(element.dateTime) || new Date();
- const interval: second = ((new Date().getTime() - time.getTime()) / 1000);
-
- const seconds: number = Math.floor(interval);
- const minutes: number = Math.floor(seconds / 60);
- const hours: number = Math.floor(minutes / 60);
- const days: number = Math.floor(hours / 24);
-
- if (Math.sign(seconds) === 1) {
- if (seconds <= 60) { return element.textContent = relative.format(-1 * seconds, "second",); }
- if (minutes <= 120) { return element.textContent = relative.format(-1 * minutes, "minute",); }
- if (hours <= 48) { return element.textContent = relative.format(-1 * hours, "hour",); }
- if (days <= 60) { return element.textContent = relative.format(-1 * days, "day",); }
- }
-
- if (Math.sign(seconds) === -1) {
- if (-1 * days >= 60) { return element.textContent = relative.format(-1 * days, "day",); }
- if (-1 * hours >= 48) { return element.textContent = relative.format(-1 * hours, "hour",); }
- if (-1 * minutes >= 120) { return element.textContent = relative.format(-1 * minutes, "minute",); }
- if (-1 * seconds >= 0) { return element.textContent = relative.format(-1 * seconds, "second",); }
- }
-
- } catch (error) {
- console.error(
- "Error: Unable to resolve relative time format!",
- error,
- );
- }
- },
- );
+ function viewport(element) {
+ const options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : { offset: 250 };
+ const view = element.getBoundingClientRect();
+ return view.top >= -options.offset
+ && view.left >= -options.offset
+ && view.bottom <= (self.innerHeight || document.documentElement.clientHeight) + options.offset
+ && view.right <= (self.innerWidth || document.documentElement.clientWidth) + options.offset;
}
+ const date = function (update) {
+ const elements = document.querySelectorAll("time");
+ for (let i = 0; i < elements.length; ++i) {
+ const offscreen = !viewport(elements[i]);
+ const hidden = elements[i].offsetParent === null;
+ if ((update === "viewport") && (offscreen || hidden)) continue;
+
+ (function (element) {
+ try {
+ if (element.dataset.type === "disabled") return;
+
+ const time: millisecond = new Date(element.dateTime) || new Date();
+ const interval: second = ((new Date().getTime() - time.getTime()) / 1000);
+
+ const seconds: number = Math.round(interval);
+ const minutes: number = Math.round(seconds / 60);
+ const hours: number = Math.round(minutes / 60);
+ const days: number = Math.round(hours / 24);
+
+ const past = Math.sign(seconds) === 1;
+ const future = Math.sign(seconds) === -1;
+
+ let tiny = function (string, place) {
+ return string.split(" ").slice(0, place).join(" ") + string.split(" ")[place].charAt(0);
+ }
+
+ if (element.dataset.type === "default") { tiny = function (string) { return string; }; }
+
+ if (element.dataset.type === "localDate") {
+ return element.textContent = new Intl.DateTimeFormat([], { dateStyle: "medium", }).format(time).replace(",", "");
+ }
+
+ if (element.dataset.type === "localTime") {
+ return element.textContent = new Intl.DateTimeFormat([], {
+ hour12: false,
+ timeStyle: "short",
+ }).format(time) + " " + new Intl.DateTimeFormat([], { timeZoneName: "short" }).format(time).split(" ")[1];
+ }
+
+ if (past) {
+ if (seconds <= 60) { return element.textContent = tiny(relative.format(-1 * seconds, "second",), 1); }
+ if (minutes <= 120) { return element.textContent = tiny(relative.format(-1 * minutes, "minute",), 1); }
+ if (hours <= 48) { return element.textContent = tiny(relative.format(-1 * hours, "hour",), 1); }
+ if (days <= 7) { return element.textContent = tiny(relative.format(-1 * days, "day",), 1); }
+ }
+
+ if (future) {
+ if (-1 * days >= 4) { return element.textContent = tiny(relative.format(-1 * days, "day",), 2); }
+ if (-1 * hours >= 3) { return element.textContent = tiny(relative.format(-1 * hours, "hour",), 2); }
+ if (-1 * minutes >= 2) { return element.textContent = tiny(relative.format(-1 * minutes, "minute",), 2); }
+ if (-1 * seconds >= 1) { return element.textContent = tiny(relative.format(-1 * seconds, "second",), 2); }
+ }
+ } catch (error) {
+ console.error("ERROR: Relative time resolution failed", error);
+ }
+ })(elements[i]);
+ }
+ };
+
const substitution = setInterval(date, 4);
- self.addEventListener("load", () => {
- setTimeout(() => {
+ ["scroll", "URLChangedCustomEvent"].forEach(function (event) {
+ self.addEventListener(event, function () {
+ date("viewport");
+ });
+ });
+
+ self.addEventListener("DOMContentLoaded", function () {
+ setTimeout(function () {
clearInterval(substitution);
- setInterval(date, 1000);
+ setInterval(function () { date("viewport"); }, 1000);
}, 1000);
});
})();