Skip to content

Commit 7351ed1

Browse files
committed
wip: async tracker
1 parent 294c980 commit 7351ed1

File tree

2 files changed

+51
-20
lines changed

2 files changed

+51
-20
lines changed

packages/webui/src/client/lib/ReactMeteorData/ReactMeteorData.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,36 @@ export function useTracker<T, K extends undefined | T = undefined>(
368368
return meteorData
369369
}
370370

371+
/**
372+
* A Meteor Tracker hook that allows using React Functional Components and the Hooks API with Meteor Tracker
373+
*
374+
* This is an alternate implementation which supports promises in the autorun function, and will preserve the previous value until the promise resolves.
375+
*
376+
* @param {() => Promise<T>} autorun The autorun function to be run.
377+
* @param {React.DependencyList} [deps] A required list of dependenices to limit the tracker re-running. Can be left empty, if tracker
378+
* has no external dependencies and should only be rerun when it's invalidated.
379+
* @param {K} [initial] An optional, initial state of the tracker. If not provided, the tracker may return undefined.
380+
* @return {*} {(T | K)}
381+
*/
382+
export function useTrackerAsyncTest<T, K extends undefined | T = undefined>(
383+
autorun: (computation: Tracker.Computation) => Promise<T>,
384+
deps: React.DependencyList,
385+
initial?: K
386+
): T | K {
387+
const [meteorData, setMeteorData] = useState<T | K>(initial as K)
388+
389+
useEffect(() => {
390+
const computation = Tracker.nonreactive(() =>
391+
Tracker.autorun(async (innerComputation) => {
392+
setMeteorData(await autorun(innerComputation))
393+
})
394+
)
395+
return () => computation.stop()
396+
}, deps)
397+
398+
return meteorData
399+
}
400+
371401
/**
372402
* A Meteor Subscription hook that allows using React Functional Components and the Hooks API with Meteor subscriptions.
373403
* Subscriptions will be torn down 1000ms after unmounting the component.

packages/webui/src/client/ui/Settings/components/triggeredActions/TriggeredActionEntry.tsx

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
} from '@sofie-automation/blueprints-integration'
1111
import classNames from 'classnames'
1212
import { DBBlueprintTrigger } from '@sofie-automation/meteor-lib/dist/collections/TriggeredActions'
13-
import { useTracker } from '../../../../lib/ReactMeteorData/ReactMeteorData'
13+
import { useTracker, useTrackerAsyncTest } from '../../../../lib/ReactMeteorData/ReactMeteorData'
1414
import { ActionEditor } from './actionEditors/ActionEditor'
1515
import { OutputLayers, SourceLayers } from '@sofie-automation/corelib/dist/dataModel/ShowStyleBase'
1616
import { flatten, getRandomString } from '../../../../lib/tempLib'
@@ -180,33 +180,34 @@ export const TriggeredActionEntry: React.FC<IProps> = React.memo(function Trigge
180180
[triggeredAction?.actionsWithOverrides]
181181
)
182182

183-
const previewItems = useTracker(
184-
(computation) => {
183+
const previewItems = useTrackerAsyncTest<IWrappedAdLib[], IWrappedAdLib[]>(
184+
async (computation) => {
185185
try {
186+
if (!resolvedActions || !selected || !sourceLayers) return []
187+
186188
const triggerComputation = computation as any as TriggerTrackerComputation
187-
if (resolvedActions && selected && sourceLayers) {
188-
const executableActions = Object.values<SomeAction>(resolvedActions).map((value) =>
189-
createAction(UiTriggersContext, value, sourceLayers)
190-
)
191-
const ctx = previewContext
192-
if (ctx && ctx.rundownPlaylist) {
193-
return flatten(
194-
await Promise.all(
195-
executableActions.map(
196-
async (action): Promise<IWrappedAdLib[]> =>
197-
isPreviewableAction(action) ? action.preview(ctx as any, triggerComputation) : []
198-
)
199-
)
189+
190+
const executableActions = Object.values<SomeAction>(resolvedActions).map((value) =>
191+
createAction(UiTriggersContext, value, sourceLayers)
192+
)
193+
const ctx = previewContext
194+
if (!ctx || !ctx.rundownPlaylist) return []
195+
196+
return flatten(
197+
await Promise.all(
198+
executableActions.map(
199+
async (action): Promise<IWrappedAdLib[]> =>
200+
isPreviewableAction(action) ? action.preview(ctx as any, triggerComputation) : []
200201
)
201-
}
202-
}
202+
)
203+
)
203204
} catch (e) {
204205
catchError('TriggeredActionEntry previewItems')(e)
205206
}
206-
return [] as IWrappedAdLib[]
207+
return []
207208
},
208209
[selected, resolvedActions, sourceLayers],
209-
[] as IWrappedAdLib[]
210+
[]
210211
)
211212

212213
function getType(sourceLayerId: string | undefined): SourceLayerType {

0 commit comments

Comments
 (0)