-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathLiveCountdownStore.ts
More file actions
48 lines (35 loc) · 1.29 KB
/
LiveCountdownStore.ts
File metadata and controls
48 lines (35 loc) · 1.29 KB
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
import { computed, observable } from 'mobx';
import { TableCellValue } from 'mobx-lark';
import { CountdownWindow, firstTextOf, resolveCountdownState, timeOf } from './utility';
// Maximum safe delay for setTimeout (max 32-bit signed integer in ms)
const MAX_TIMEOUT_DELAY = 2_147_483_647;
export class LiveCountdownStore<T extends CountdownWindow> {
constructor(
readonly items: T[],
readonly startTime?: TableCellValue,
readonly endTime?: TableCellValue,
) {}
@observable
accessor referenceTime: number | null = null;
@computed
get countdownState() {
const { referenceTime, items, startTime, endTime } = this;
return referenceTime === null
? {
nextItem: undefined as T | undefined,
countdownTo: firstTextOf(startTime) || firstTextOf(endTime) || undefined,
}
: resolveCountdownState(items, referenceTime, startTime, endTime);
}
private timer?: number;
tick = () => {
this.referenceTime = Date.now();
const targetTime = timeOf(this.countdownState.countdownTo);
if (!Number.isFinite(targetTime)) return;
const delay = Math.min(MAX_TIMEOUT_DELAY, Math.max(1000, targetTime - Date.now() + 1000));
this.timer = window.setTimeout(this.tick, delay);
};
dispose() {
window.clearTimeout(this.timer);
}
}