-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathApp.tsx
90 lines (77 loc) · 2.49 KB
/
App.tsx
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import { useCallback, useEffect, useState } from 'react';
const params = Object.fromEntries(new URLSearchParams(window.location.search));
const safeParseNumber = (value: string) => {
const parsed = Number(value);
return isNaN(parsed) ? 0 : parsed;
};
const now = new Date().getTime();
let seconds = safeParseNumber(params.seconds);
let fontSize = '20vw';
if (params.time) {
seconds = safeArray.from(params.time.matchAll(/(\d+[hms])/g)).reduce((sum, [raw]) => {
const [n, x] = [raw.slice(0, -1), raw.at(-1)];
return sum + (n * (x == "h" ? 3600 : (x == "m" ? 60 : 1)))
}, 0);
}
if (params.hours) {
seconds += safeParseNumber(params.hours) * 60 * 60;
}
if (params.minutes) {
seconds += safeParseNumber(params.minutes) * 60;
}
let color = params.color ? `#${params.color}` : 'rgb(214 211 209)';
let backgroundColor = params.bgcolor ? `#${params.bgcolor}` : '';
const endTime = now + seconds * 1000;
const secondsLeft = Math.floor((endTime - now) / 1000);
const padNumber = (value: number) => value.toString().padStart(2, '0');
let numParts = 3;
const getParts = (value: number) => {
const hours = Math.floor(value / 60 / 60);
const minutes = Math.floor((value / 60) % 60);
const seconds = Math.floor(value % 60);
if (numParts === 3) return [hours, minutes, seconds];
if (numParts === 2) return [minutes, seconds];
return [seconds];
};
const parts = getParts(secondsLeft);
if (parts[0] === 0 && parts[1] === 0) {
fontSize = '40vw';
numParts = 1;
} else if (parts[0] === 0) {
fontSize = '30vw';
numParts = 2;
}
function App() {
const [secondsLeft, setSecondsLeft] = useState('');
useEffect(() => {
let intervalId = setInterval(() => {
const left = Math.floor((endTime - new Date().getTime()) / 1000);
const parts = getParts(left);
const timeString = parts.map(padNumber).join(':');
setSecondsLeft(timeString);
document.title = timeString;
if (left <= 0) {
const timesUP = getParts(0).map(padNumber).join(':');
setSecondsLeft(timesUP);
document.title = timesUP;
return clearInterval(intervalId);
}
}, 200);
return () => clearInterval(intervalId);
}, []);
return (
<div className="flex h-full w-full items-center justify-center font-['GlacialIndifferenceBold']">
<p
style={{
color,
fontSize,
backgroundColor,
}}
className="rounded-[100px] bg-slate-900 px-10 text-center"
>
{secondsLeft}
</p>
</div>
);
}
export default App;