@@ -21,15 +21,24 @@ import {
2121} from "./svgTools"
2222
2323/**
24+ * Timer component.
2425 *
25- * @param props
26- * @param props.id
27- * @param props.currentTime
28- * @param props.triggerStart
29- * @param props.triggerStop
30- * @param props.onDelete
31- * @param props.notifyWhenFinished
32- * @param props.siblingRunning
26+ * This is the main component for the timer page, it represents a countdown timer
27+ * that may have children timers and enforces some rules about its children.
28+ *
29+ * @param {any } props Component props
30+ * @param {UUID } props.id
31+ * The ID of the timer to display (used to lookup the timer data from local storage)
32+ * @param {DateTime } props.currentTime The current time (used to calculate the time remaining)
33+ * @param {Function } props.triggerStart Callback to inform the parent that the timer has started
34+ * @param {Function } props.triggerStop Callback to inform the parent that the timer has paused
35+ * @param {Function } props.onDelete Callback to inform the parent that the timer has been deleted
36+ * @param {boolean } props.notifyWhenFinished Whether to notify the user when the timer finishes
37+ * @param {UUID } props.siblingRunning
38+ * The ID of the sibling timer that is currently running (may be this timer,
39+ * or a non-existent timer). Used to enforce the rule that only one timer at a level
40+ * can be running at a time.
41+ * @returns {Element } The timer component
3342 */
3443export default function Timer ( props : {
3544 id : UUID ,
@@ -48,10 +57,17 @@ export default function Timer(props: {
4857 } = props
4958
5059 /**
60+ * This is a custom hook to manage the state of the timer and synchronize it
61+ * with local storage by UUID. It is a wrapper around useLocalStorage and
62+ * saves values in the format `<uuid>-<stateName>`.
5163 *
52- * @param stateName
53- * @param defaultValue
54- * @param serializer
64+ * @template T The type of the state to manage
65+ * @param {string } stateName The name of the state to manage (used as a suffix for the key)
66+ * @param {T } defaultValue The default value to use if the state is not found in local storage
67+ * @param {CustomSerializable } serializer
68+ * Serializer to correctly manage the state in local storage
69+ * @returns {[T, (newValue: T) => void, () => void] }
70+ * The state value, a function to update the state, and a function to reset the state
5571 */
5672 function useUUIDStore < T > (
5773 stateName : string ,
@@ -61,16 +77,19 @@ export default function Timer(props: {
6177 return useLocalStorage < T > ( `${ id } -${ stateName } ` , defaultValue , serializer )
6278 }
6379
80+ // TODO: setName and setTotalTime are unused, they'll be put in the edit dialog
81+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
6482 const [ name , setName , clearName ] = useUUIDStore < string > ( "name" , "unnamed" )
83+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
6584 const [ totalTime , setTotalTime , clearTotalTime ] = useUUIDStore < Duration > ( "totalTime" , Duration . fromMillis ( 0 ) , durationSerializer )
66- const [ parentID , setParentID , clearParentID ] = useUUIDStore < UUID | "root" > ( "parentID" , "root" )
6785 const [ childrenIDs , setChildrenIDs , clearChildrenIDs ] = useUUIDStore < UUID [ ] > ( "childrenIDs" , [ ] )
6886
6987 const [ childRunning , setChildRunning , clearChildRunning ] = useUUIDStore < UUID | undefined > ( "childRunning" , undefined )
7088 const [ started , setStarted , clearStarted ] = useUUIDStore < DateTime | undefined > ( "started" , undefined , datetimeMaybeSerializer )
7189 const [ finished , setFinished , clearFinished ] = useUUIDStore < boolean > ( "finished" , false )
7290 const [ elapsed , setElapsed , clearElapsed ] = useUUIDStore < Duration > ( "elapsed" , Duration . fromMillis ( 0 ) , durationSerializer )
7391
92+ // These are the states that are not saved to local storage
7493 const [ expanded , setExpanded ] = useState < boolean > ( false )
7594 const [ addDialogOpen , setAddDialogOpen ] = useState < boolean > ( false )
7695
@@ -79,10 +98,11 @@ export default function Timer(props: {
7998 setChildrenIDs ( [ ...childrenIDs , timer . id ] )
8099 }
81100
101+ // This function cleans up storage on deletion, though it's a bit messy and
102+ // could probably be improved to more easily support adding new states
82103 const clearSelf = ( ) => {
83104 clearName ( )
84105 clearTotalTime ( )
85- clearParentID ( )
86106 clearChildrenIDs ( )
87107 clearChildRunning ( )
88108 clearStarted ( )
@@ -236,14 +256,17 @@ export default function Timer(props: {
236256}
237257
238258/**
259+ * Custom start/pause control for timers that indecates the percent of time remaining
239260 *
240- * @param props
241- * @param props.running
242- * @param props.finished
243- * @param props.startable
244- * @param props.percentRemaining
245- * @param props.onStart
246- * @param props.onStop
261+ * @param {any } props Component props
262+ * @param {boolean } props.running Whether the timer is currently running
263+ * @param {boolean } props.finished Whether the timer has finished
264+ * @param {boolean } props.startable
265+ * Whether the timer can be started (parent timers can't be started if all their time is allocated)
266+ * @param {number } props.percentRemaining The percent of time remaining (0-1)
267+ * @param {Function } props.onStart Callback to start the timer
268+ * @param {Function } props.onStop Callback to pause the timer
269+ * @returns {Element } The component
247270 */
248271function TimerControl ( props : {
249272 running : boolean , finished : boolean , startable : boolean ,
0 commit comments