-
-
Notifications
You must be signed in to change notification settings - Fork 407
/
Copy pathrealtime.ts
71 lines (60 loc) · 1.84 KB
/
realtime.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import { LocaleFunc, Opts, TimerPool } from './interface';
import { getLocale } from './register';
import { diffSec, formatDiff, nextInterval } from './utils/date';
import { getDateAttribute, getTimerId, setTimerId } from './utils/dom';
// all realtime timer
const TIMER_POOL: TimerPool = {};
/**
* clear a timer from pool
* @param tid
*/
const clear = (tid: number): void => {
clearTimeout(tid);
delete TIMER_POOL[tid];
};
// run with timer(setTimeout)
function run(node: HTMLElement, date: string, localeFunc: LocaleFunc, opts: Opts): void {
// clear the node's exist timer
clear(getTimerId(node));
const { relativeDate, minInterval, numberLocale } = opts;
// get diff seconds
const diff = diffSec(date, relativeDate);
// render
node.innerText = formatDiff(diff, localeFunc, numberLocale);
const tid = setTimeout(
() => {
run(node, date, localeFunc, opts);
},
Math.min(Math.max(nextInterval(diff), minInterval || 1) * 1000, 0x7fffffff),
) as unknown as number;
// there is no need to save node in object. Just save the key
TIMER_POOL[tid] = 0;
setTimerId(node, tid);
}
/**
* cancel a timer or all timers
* @param node - node hosting the time string
*/
export function cancel(node?: HTMLElement): void {
// cancel one
if (node) clear(getTimerId(node));
// cancel all
// @ts-ignore
else Object.keys(TIMER_POOL).forEach(clear);
}
/**
* render a dom realtime
* @param nodes
* @param locale
* @param opts
*/
export function render(nodes: HTMLElement | HTMLElement[] | NodeList, locale?: string, opts?: Opts) {
// by .length
// @ts-ignore
// supports empty list of nodes
const nodeList: HTMLElement[] = NodeList.prototype.isPrototypeOf(nodes) ? nodes : [nodes];
nodeList.forEach((node: HTMLElement) => {
run(node, getDateAttribute(node), getLocale(locale), opts || {});
});
return nodeList;
}