Files
bitburner-src/src/ui/React/CinematicLine.tsx
T
2024-11-06 23:09:11 -08:00

47 lines
1006 B
TypeScript

import React, { useState, useEffect } from "react";
import Typography from "@mui/material/Typography";
interface IProps {
text: string;
onDone?: () => void;
}
function sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
export function CinematicLine(props: IProps): React.ReactElement {
const [length, setLength] = useState(0);
const [done, setDone] = useState(false);
function advance(): void {
const newLength = length + 1;
setLength(newLength);
setDone(newLength >= props.text.length);
}
useEffect(() => {
if (done && props.onDone) {
props.onDone();
return;
}
let cancel = false;
sleep(10)
.then(() => !cancel && advance())
.catch((error) => {
console.error(error);
});
return () => {
cancel = true;
};
});
return (
<>
<Typography>
{props.text.slice(0, length)}
{!done && <span>&#9608;</span>}
</Typography>
</>
);
}