Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pterodactyl
GitHub Repository: pterodactyl/panel
Path: blob/1.0-develop/resources/scripts/components/elements/ProgressBar.tsx
7461 views
1
import React, { useEffect, useRef, useState } from 'react';
2
import styled from 'styled-components/macro';
3
import { useStoreActions, useStoreState } from 'easy-peasy';
4
import { randomInt } from '@/helpers';
5
import { CSSTransition } from 'react-transition-group';
6
import tw from 'twin.macro';
7
8
const BarFill = styled.div`
9
${tw`h-full bg-cyan-400`};
10
transition: 250ms ease-in-out;
11
box-shadow: 0 -2px 10px 2px hsl(178, 78%, 57%);
12
`;
13
14
type Timer = ReturnType<typeof setTimeout>;
15
16
export default () => {
17
const interval = useRef<Timer>(null) as React.MutableRefObject<Timer>;
18
const timeout = useRef<Timer>(null) as React.MutableRefObject<Timer>;
19
const [visible, setVisible] = useState(false);
20
const progress = useStoreState((state) => state.progress.progress);
21
const continuous = useStoreState((state) => state.progress.continuous);
22
const setProgress = useStoreActions((actions) => actions.progress.setProgress);
23
24
useEffect(() => {
25
return () => {
26
timeout.current && clearTimeout(timeout.current);
27
interval.current && clearInterval(interval.current);
28
};
29
}, []);
30
31
useEffect(() => {
32
setVisible((progress || 0) > 0);
33
34
if (progress === 100) {
35
timeout.current = setTimeout(() => setProgress(undefined), 500);
36
}
37
}, [progress]);
38
39
useEffect(() => {
40
if (!continuous) {
41
interval.current && clearInterval(interval.current);
42
return;
43
}
44
45
if (!progress || progress === 0) {
46
setProgress(randomInt(20, 30));
47
}
48
}, [continuous]);
49
50
useEffect(() => {
51
if (continuous) {
52
interval.current && clearInterval(interval.current);
53
if ((progress || 0) >= 90) {
54
setProgress(90);
55
} else {
56
interval.current = setTimeout(() => setProgress((progress || 0) + randomInt(1, 5)), 500);
57
}
58
}
59
}, [progress, continuous]);
60
61
return (
62
<div css={tw`w-full fixed`} style={{ height: '2px' }}>
63
<CSSTransition timeout={150} appear in={visible} unmountOnExit classNames={'fade'}>
64
<BarFill style={{ width: progress === undefined ? '100%' : `${progress}%` }} />
65
</CSSTransition>
66
</div>
67
);
68
};
69
70