misc_pterodactyl-panel/resources/scripts/components/elements/ProgressBar.tsx
2022-06-26 15:30:05 -04:00

68 lines
2.2 KiB
TypeScript

import React, { useEffect, useRef, useState } from 'react';
import styled from 'styled-components/macro';
import { useStoreActions, useStoreState } from 'easy-peasy';
import { randomInt } from '@/helpers';
import { CSSTransition } from 'react-transition-group';
import tw from 'twin.macro';
const BarFill = styled.div`
${tw`h-full bg-cyan-400`};
transition: 250ms ease-in-out;
box-shadow: 0 -2px 10px 2px hsl(178, 78%, 57%);
`;
type Timer = ReturnType<typeof setTimeout>;
export default () => {
const interval = useRef<Timer>(null) as React.MutableRefObject<Timer>;
const timeout = useRef<Timer>(null) as React.MutableRefObject<Timer>;
const [visible, setVisible] = useState(false);
const progress = useStoreState((state) => state.progress.progress);
const continuous = useStoreState((state) => state.progress.continuous);
const setProgress = useStoreActions((actions) => actions.progress.setProgress);
useEffect(() => {
return () => {
timeout.current && clearTimeout(timeout.current);
interval.current && clearInterval(interval.current);
};
}, []);
useEffect(() => {
setVisible((progress || 0) > 0);
if (progress === 100) {
timeout.current = setTimeout(() => setProgress(undefined), 500);
}
}, [progress]);
useEffect(() => {
if (!continuous) {
interval.current && clearInterval(interval.current);
return;
}
if (!progress || progress === 0) {
setProgress(randomInt(20, 30));
}
}, [continuous]);
useEffect(() => {
if (continuous) {
interval.current && clearInterval(interval.current);
if ((progress || 0) >= 90) {
setProgress(90);
} else {
interval.current = setTimeout(() => setProgress((progress || 0) + randomInt(1, 5)), 500);
}
}
}, [progress, continuous]);
return (
<div css={tw`w-full fixed`} style={{ height: '2px' }}>
<CSSTransition timeout={150} appear in={visible} unmountOnExit classNames={'fade'}>
<BarFill style={{ width: progress === undefined ? '100%' : `${progress}%` }} />
</CSSTransition>
</div>
);
};