Skip to content

Commit 2d50ee2

Browse files
jstarplJulusian
authored andcommitted
chore: add useTiming as a hook to listen to changes in the Timing context
1 parent 8a50457 commit 2d50ee2

File tree

1 file changed

+61
-1
lines changed

1 file changed

+61
-1
lines changed

packages/webui/src/client/ui/RundownView/RundownTiming/withTiming.tsx

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as React from 'react'
1+
import React, { useCallback, useContext, useEffect, useRef, useState } from 'react'
22
import _ from 'underscore'
33
import { RundownTiming } from './RundownTiming.js'
44
import { RundownTimingContext } from '../../../lib/rundownTiming.js'
@@ -155,6 +155,66 @@ export function withTiming<IProps, IState>(
155155
}
156156
}
157157

158+
function getFilterFunction(
159+
filter: TimingFilterFunction | string | (string | number)[] | undefined
160+
): TimingFilterFunction | undefined {
161+
if (typeof filter === 'function') {
162+
return filter
163+
} else if (filter) {
164+
return _.property(filter as string)
165+
}
166+
return undefined
167+
}
168+
169+
export function useTiming({
170+
tickResolution,
171+
dataResolution,
172+
filter,
173+
}: {
174+
tickResolution: TimingTickResolution
175+
dataResolution: TimingDataResolution
176+
filter?: TimingFilterFunction | string | (string | number)[]
177+
}): RundownTimingContext {
178+
const [_0, setForceUpdate] = useState(0)
179+
180+
const context = useContext(RundownTimingProviderContext)
181+
182+
const highResDurations: RundownTimingContext = context.durations
183+
const syncedDurations: RundownTimingContext = context.syncedDurations
184+
185+
const isDirty = useRef(false)
186+
const previousValue = useRef<RundownTimingContext | null>(null)
187+
188+
const filterGetter = useRef(getFilterFunction(filter))
189+
190+
const refreshComponent = useCallback(() => {
191+
if (!filterGetter.current) {
192+
setForceUpdate(Date.now())
193+
} else {
194+
const buf = filterGetter.current?.(context.durations || {})
195+
if (isDirty.current || !_.isEqual(buf, previousValue.current)) {
196+
previousValue.current = buf
197+
isDirty.current = false
198+
setForceUpdate(Date.now())
199+
}
200+
}
201+
}, [filter])
202+
203+
useEffect(() => {
204+
window.addEventListener(rundownTimingEventFromTickResolution(tickResolution), refreshComponent)
205+
206+
return () => {
207+
window.removeEventListener(rundownTimingEventFromTickResolution(tickResolution), refreshComponent)
208+
}
209+
}, [tickResolution, refreshComponent])
210+
211+
if (componentIsDirty(filterGetter.current, highResDurations, dataResolution)) {
212+
isDirty.current = true
213+
}
214+
215+
return rundownTimingDataFromDataResolution(dataResolution, highResDurations, syncedDurations)
216+
}
217+
158218
function componentIsDirty(
159219
filterGetter: ((...args: any[]) => any) | undefined,
160220
highResDurations: RundownTimingContext,

0 commit comments

Comments
 (0)