type and improve ui/component/timeago

pull/7395/head
Thibault Duplessis 2020-09-30 07:46:55 +02:00
parent aa3e81097c
commit 442da0c86a
7 changed files with 47 additions and 60 deletions

View File

@ -55,12 +55,7 @@ interface Lichess {
defaultParams: Record<string, any>;
}
// timeago.js
timeago: {
render(nodes: HTMLElement | HTMLElement[]): void;
format(date: number | Date): string;
absolute(date: number | Date): string;
}
timeago(date: number | Date): string;
timeagoLocale(a: number, b: number, c: number): any;
// misc

View File

@ -10,7 +10,7 @@ function timer(pov: NowPlaying) {
(vnode.elm as HTMLElement).setAttribute('datetime', '' + date);
}
}
}, lichess.timeago.format(date));
}, lichess.timeago(date));
}
export default function(ctrl: LobbyController) {

View File

@ -37,5 +37,5 @@ function renderDate(msg: LastMsg): VNode {
title: msg.date.toLocaleString(),
datetime: msg.date.getTime()
}
}, lichess.timeago.format(msg.date));
}, lichess.timeago(msg.date));
}

View File

@ -195,7 +195,7 @@ function drawTime(n: Notification) {
title: date.toLocaleString(),
datetime: n.date
}
}, lichess.timeago.format(date));
}, lichess.timeago(date));
}
function userFullName(u?: LightUser) {

View File

@ -1,5 +1,11 @@
type DateLike = Date | number | string;
interface ElementWithDate extends Element {
lichessDate: Date;
}
// divisors for minutes, hours, days, weeks, months, years
const DIVS = [60,
const DIVS = [
60,
60 * 60,
60 * 60 * 24,
60 * 60 * 24 * 7,
@ -10,14 +16,13 @@ const LIMITS = [...DIVS];
LIMITS[2] *= 2; // Show hours up to 2 days.
// format Date / string / timestamp to Date instance.
function toDate(input: any): Date {
return input instanceof Date ? input : (
new Date(isNaN(input) ? input : parseInt(input))
const toDate = (input: DateLike): Date =>
input instanceof Date ? input : (
new Date(isNaN(input as any) ? input : parseInt(input as any))
);
}
// format the diff second to *** time ago
function formatDiff(diff) {
const formatDiff = (diff: number): string => {
let agoin = 0;
if (diff < 0) {
agoin = 1;
@ -36,10 +41,10 @@ function formatDiff(diff) {
return lichess.timeagoLocale(diff, i, totalSec)[agoin].replace('%s', diff);
}
let formatterInst;
let formatterInst: (date: Date) => string;
function formatter() {
return formatterInst = formatterInst || (
const formatter = () =>
formatterInst = formatterInst || (
window.Intl && Intl.DateTimeFormat ?
new Intl.DateTimeFormat(document.documentElement.lang, {
year: 'numeric',
@ -48,48 +53,35 @@ function formatter() {
hour: 'numeric',
minute: 'numeric'
}).format : d => d.toLocaleString()
)
}
function render(nodes: any[]) {
var cl, abs, set, str, diff, now = Date.now();
nodes.forEach(function(node) {
cl = node.classList,
abs = cl.contains('abs'),
set = cl.contains('set');
node.date = node.date || toDate(node.getAttribute('datetime'));
if (!set) {
str = formatter()(node.date);
if (abs) node.textContent = str;
else node.setAttribute('title', str);
cl.add('set');
if (abs || cl.contains('once')) cl.remove('timeago');
}
if (!abs) {
diff = (now - node.date) / 1000;
node.textContent = formatDiff(diff);
if (Math.abs(diff) > 9999) cl.remove('timeago'); // ~3h
}
});
}
const findAndRender = (parent?: HTMLElement) =>
requestAnimationFrame(() =>
render([].slice.call((parent || document).getElementsByClassName('timeago'), 0, 99))
);
const updateRegularly = (interval: number) => {
export const format = (date: DateLike) => formatDiff((Date.now() - toDate(date).getTime()) / 1000);
export const findAndRender = (parent?: HTMLElement) =>
requestAnimationFrame(() => {
const now = Date.now();
const nodes = (parent || document).getElementsByClassName('timeago') as HTMLCollectionOf<ElementWithDate>;
for (let node of nodes) {
const cl = node.classList,
abs = cl.contains('abs'),
set = cl.contains('set');
node.lichessDate = node.lichessDate || toDate(node.getAttribute('datetime')!);
if (!set) {
const str = formatter()(node.lichessDate);
if (abs) node.textContent = str;
else node.setAttribute('title', str);
cl.add('set');
if (abs || cl.contains('once')) cl.remove('timeago');
}
if (!abs) {
const diff = (now - node.lichessDate.getTime()) / 1000;
node.textContent = formatDiff(diff);
if (Math.abs(diff) > 9999) cl.remove('timeago'); // ~3h
}
}
});
export const updateRegularly = (interval: number) => {
findAndRender();
setTimeout(() => updateRegularly(interval * 1.1), interval);
}
const timeago = {
render,
// relative
format: date => formatDiff((Date.now() - toDate(date).getTime()) / 1000),
absolute: date => formatter()(toDate(date)),
findAndRender,
updateRegularly
};
export default timeago;

View File

@ -16,7 +16,7 @@ import trans from "./component/trans";
import sound from "./component/sound";
import * as miniBoard from "./component/mini-board";
import * as miniGame from "./component/mini-game";
import timeago from "./component/timeago";
import { format as timeago } from "./component/timeago";
import watchers from "./component/watchers";
export default function() {

View File

@ -11,7 +11,7 @@ import powertip from "./component/powertip";
import pubsub from "./component/pubsub";
import serviceWorker from "./component/serviceWorker";
import StrongSocket from "./component/socket";
import timeago from "./component/timeago";
import * as timeago from "./component/timeago";
import topBar from "./component/top-bar";
import watchers from "./component/watchers";
import { userComplete } from "./component/assets";