type and improve ui/component/timeago
parent
aa3e81097c
commit
442da0c86a
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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";
|
||||
|
|
Loading…
Reference in New Issue