Tracker made in React for keeping track of HP and MP and so on.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
fabula-ultima-react/src/ui/TurnTimer.tsx

56 lines
2.2 KiB

import {ReactElement, useCallback, useRef, useState} from "react";
import {ProgressBar, Stack} from "react-bootstrap";
import {useAnimationFrame} from "./AnimationHook";
import {isDefined} from "../types/type_check";
import "./TurnTimer.css";
import formatDuration from "format-duration";
export interface TurnTimerArgs {
readonly title?: string
readonly startTime?: number
readonly endTime?: number
readonly displayedTime?: number
readonly resolutionMs?: number
}
const DEFAULT_RESOLUTION_MS = 100;
export function TurnTimer({title, startTime, endTime, displayedTime, resolutionMs = DEFAULT_RESOLUTION_MS}: TurnTimerArgs): ReactElement {
const [currentTime, setCurrentTime] = useState(() => displayedTime ?? Date.now())
const accumulatedTime = useRef(0)
const animationCallback = useCallback(isDefined(displayedTime)
? () => null
: (delta: number) => {
accumulatedTime.current += delta
if (accumulatedTime.current > resolutionMs) {
accumulatedTime.current %= resolutionMs
setCurrentTime(Date.now())
}
}, [displayedTime, setCurrentTime, accumulatedTime])
useAnimationFrame(animationCallback)
if (isDefined(displayedTime) && displayedTime !== currentTime) {
setCurrentTime(displayedTime)
accumulatedTime.current = resolutionMs
}
let totalTime: number|null = null
let timeRemaining: number|null = null
let timeElapsed: number|null = null
if (isDefined(startTime)) {
if (isDefined(endTime)) {
totalTime = endTime - startTime
timeRemaining = endTime - currentTime
} else {
timeElapsed = currentTime - startTime
}
} else if (isDefined(endTime)) {
timeRemaining = endTime - currentTime
}
return <Stack className={"turnTimer"} direction="vertical">
<h2 className={"turnTimerTitle"}>{title}</h2>
{(timeRemaining !== null || timeElapsed !== null) && <div className={"turnTimerTime"}>{formatDuration(timeRemaining ?? timeElapsed ?? 0)}</div>}
{timeRemaining !== null && totalTime !== null && <ProgressBar className={"turnTimerBar"} now={timeRemaining} max={totalTime} />}
</Stack>
}