Skip to content

Commit f35dc52

Browse files
committed
chore: rework typings of RundownViewEventBus. add useRundownViewEventBusListener helper
1 parent 0a6b4ed commit f35dc52

File tree

7 files changed

+70
-123
lines changed

7 files changed

+70
-123
lines changed

packages/meteor-lib/src/triggers/RundownViewEventBus.ts

Lines changed: 32 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -127,74 +127,38 @@ export interface ItemDroppedEvent extends IEventContext {
127127
ev: any
128128
}
129129

130-
class RundownViewEventBus0 extends EventEmitter {
131-
emit(event: RundownViewEvents.ACTIVATE_RUNDOWN_PLAYLIST, e: ActivateRundownPlaylistEvent): boolean
132-
emit(event: RundownViewEvents.DEACTIVATE_RUNDOWN_PLAYLIST, e: DeactivateRundownPlaylistEvent): boolean
133-
emit(event: RundownViewEvents.RESYNC_RUNDOWN_PLAYLIST, e: BaseEvent): boolean
134-
emit(event: RundownViewEvents.RESET_RUNDOWN_PLAYLIST, e: BaseEvent): boolean
135-
emit(event: RundownViewEvents.TAKE, e: BaseEvent): boolean
136-
emit(event: RundownViewEvents.REWIND_SEGMENTS): boolean
137-
emit(event: RundownViewEvents.GO_TO_LIVE_SEGMENT): boolean
138-
emit(event: RundownViewEvents.GO_TO_TOP): boolean
139-
emit(event: RundownViewEvents.SEGMENT_ZOOM_ON): boolean
140-
emit(event: RundownViewEvents.SEGMENT_ZOOM_OFF): boolean
141-
emit(event: RundownViewEvents.SHELF_STATE, e: ShelfStateEvent): boolean
142-
emit(event: RundownViewEvents.REVEAL_IN_SHELF, e: RevealInShelfEvent): boolean
143-
emit(event: RundownViewEvents.SWITCH_SHELF_TAB, e: SwitchToShelfTabEvent): boolean
144-
emit(event: RundownViewEvents.MINI_SHELF_QUEUE_ADLIB, e: MiniShelfQueueAdLibEvent): boolean
145-
emit(event: RundownViewEvents.GO_TO_PART, e: GoToPartEvent): boolean
146-
emit(event: RundownViewEvents.GO_TO_PART_INSTANCE, e: GoToPartInstanceEvent): boolean
147-
emit(event: RundownViewEvents.SELECT_PIECE, e: SelectPieceEvent): boolean
148-
emit(event: RundownViewEvents.HIGHLIGHT, e: HighlightEvent): boolean
149-
emit(event: RundownViewEvents.TRIGGER_ACTION, e: TriggerActionEvent): boolean
150-
emit(event: RundownViewEvents.EMPTY_BUCKET, e: BucketEvent): boolean
151-
emit(event: RundownViewEvents.DELETE_BUCKET, e: BucketEvent): boolean
152-
emit(event: RundownViewEvents.RENAME_BUCKET, e: BucketEvent): boolean
153-
emit(event: RundownViewEvents.CREATE_BUCKET, e: IEventContext): boolean
154-
emit(event: RundownViewEvents.DELETE_BUCKET_ADLIB, e: BucketAdLibEvent): boolean
155-
emit(event: RundownViewEvents.RENAME_BUCKET_ADLIB, e: BucketAdLibEvent): boolean
156-
emit(event: RundownViewEvents.CREATE_SNAPSHOT_FOR_DEBUG, e: BaseEvent): boolean
157-
emit(event: RundownViewEvents.TOGGLE_SHELF_DROPZONE, e: ToggleShelfDropzoneEvent): boolean
158-
emit(event: RundownViewEvents.ITEM_DROPPED, e: ItemDroppedEvent): boolean
159-
emit(event: string, ...args: any[]) {
160-
return super.emit(event, ...args)
161-
}
162-
163-
on(event: RundownViewEvents.ACTIVATE_RUNDOWN_PLAYLIST, listener: (e: ActivateRundownPlaylistEvent) => void): this
164-
on(
165-
event: RundownViewEvents.DEACTIVATE_RUNDOWN_PLAYLIST,
166-
listener: (e: DeactivateRundownPlaylistEvent) => void
167-
): this
168-
on(event: RundownViewEvents.RESYNC_RUNDOWN_PLAYLIST, listener: (e: BaseEvent) => void): this
169-
on(event: RundownViewEvents.RESET_RUNDOWN_PLAYLIST, listener: (e: BaseEvent) => void): this
170-
on(event: RundownViewEvents.TAKE, listener: (e: BaseEvent) => void): this
171-
on(event: RundownViewEvents.REWIND_SEGMENTS, listener: () => void): this
172-
on(event: RundownViewEvents.GO_TO_LIVE_SEGMENT, listener: () => void): this
173-
on(event: RundownViewEvents.GO_TO_TOP, listener: () => void): this
174-
on(event: RundownViewEvents.SEGMENT_ZOOM_ON, listener: () => void): this
175-
on(event: RundownViewEvents.SEGMENT_ZOOM_OFF, listener: () => void): this
176-
on(event: RundownViewEvents.REVEAL_IN_SHELF, listener: (e: RevealInShelfEvent) => void): this
177-
on(event: RundownViewEvents.SHELF_STATE, listener: (e: ShelfStateEvent) => void): this
178-
on(event: RundownViewEvents.SWITCH_SHELF_TAB, listener: (e: SwitchToShelfTabEvent) => void): this
179-
on(event: RundownViewEvents.MINI_SHELF_QUEUE_ADLIB, listener: (e: MiniShelfQueueAdLibEvent) => void): this
180-
on(event: RundownViewEvents.GO_TO_PART, listener: (e: GoToPartEvent) => void): this
181-
on(event: RundownViewEvents.GO_TO_PART_INSTANCE, listener: (e: GoToPartInstanceEvent) => void): this
182-
on(event: RundownViewEvents.SELECT_PIECE, listener: (e: SelectPieceEvent) => void): this
183-
on(event: RundownViewEvents.HIGHLIGHT, listener: (e: HighlightEvent) => void): this
184-
on(event: RundownViewEvents.TRIGGER_ACTION, listener: (e: TriggerActionEvent) => void): this
185-
on(event: RundownViewEvents.EMPTY_BUCKET, listener: (e: BucketEvent) => void): this
186-
on(event: RundownViewEvents.DELETE_BUCKET, listener: (e: BucketEvent) => void): this
187-
on(event: RundownViewEvents.RENAME_BUCKET, listener: (e: BucketEvent) => void): this
188-
on(event: RundownViewEvents.CREATE_BUCKET, listener: (e: IEventContext) => void): this
189-
on(event: RundownViewEvents.DELETE_BUCKET_ADLIB, listener: (e: BucketAdLibEvent) => void): this
190-
on(event: RundownViewEvents.RENAME_BUCKET_ADLIB, listener: (e: BucketAdLibEvent) => void): this
191-
on(event: RundownViewEvents.CREATE_SNAPSHOT_FOR_DEBUG, listener: (e: BaseEvent) => void): this
192-
on(event: RundownViewEvents.TOGGLE_SHELF_DROPZONE, listener: (e: ToggleShelfDropzoneEvent) => void): this
193-
on(event: RundownViewEvents.ITEM_DROPPED, listener: (e: ItemDroppedEvent) => void): this
194-
on(event: string, listener: (...args: any[]) => void) {
195-
return super.on(event, listener)
196-
}
197-
}
130+
export interface RundownViewEventBusEvents {
131+
[RundownViewEvents.ACTIVATE_RUNDOWN_PLAYLIST]: [e: ActivateRundownPlaylistEvent]
132+
[RundownViewEvents.DEACTIVATE_RUNDOWN_PLAYLIST]: [e: DeactivateRundownPlaylistEvent]
133+
[RundownViewEvents.RESYNC_RUNDOWN_PLAYLIST]: [e: BaseEvent]
134+
[RundownViewEvents.RESET_RUNDOWN_PLAYLIST]: [e: BaseEvent]
135+
[RundownViewEvents.TAKE]: [e: BaseEvent]
136+
[RundownViewEvents.REWIND_SEGMENTS]: []
137+
[RundownViewEvents.GO_TO_LIVE_SEGMENT]: []
138+
[RundownViewEvents.GO_TO_TOP]: []
139+
[RundownViewEvents.SEGMENT_ZOOM_ON]: []
140+
[RundownViewEvents.SEGMENT_ZOOM_OFF]: []
141+
[RundownViewEvents.SHELF_STATE]: [e: ShelfStateEvent]
142+
[RundownViewEvents.REVEAL_IN_SHELF]: [e: RevealInShelfEvent]
143+
[RundownViewEvents.SWITCH_SHELF_TAB]: [e: SwitchToShelfTabEvent]
144+
[RundownViewEvents.MINI_SHELF_QUEUE_ADLIB]: [e: MiniShelfQueueAdLibEvent]
145+
[RundownViewEvents.GO_TO_PART]: [e: GoToPartEvent]
146+
[RundownViewEvents.GO_TO_PART_INSTANCE]: [e: GoToPartInstanceEvent]
147+
[RundownViewEvents.SELECT_PIECE]: [e: SelectPieceEvent]
148+
[RundownViewEvents.HIGHLIGHT]: [e: HighlightEvent]
149+
[RundownViewEvents.TRIGGER_ACTION]: [e: TriggerActionEvent]
150+
[RundownViewEvents.EMPTY_BUCKET]: [e: BucketEvent]
151+
[RundownViewEvents.DELETE_BUCKET]: [e: BucketEvent]
152+
[RundownViewEvents.RENAME_BUCKET]: [e: BucketEvent]
153+
[RundownViewEvents.CREATE_BUCKET]: [e: IEventContext]
154+
[RundownViewEvents.DELETE_BUCKET_ADLIB]: [e: BucketAdLibEvent]
155+
[RundownViewEvents.RENAME_BUCKET_ADLIB]: [e: BucketAdLibEvent]
156+
[RundownViewEvents.CREATE_SNAPSHOT_FOR_DEBUG]: [e: BaseEvent]
157+
[RundownViewEvents.TOGGLE_SHELF_DROPZONE]: [e: ToggleShelfDropzoneEvent]
158+
[RundownViewEvents.ITEM_DROPPED]: [e: ItemDroppedEvent]
159+
}
160+
161+
class RundownViewEventBus0 extends EventEmitter<RundownViewEventBusEvents> {}
198162

199163
const RundownViewEventBus = new RundownViewEventBus0()
200164
RundownViewEventBus.setMaxListeners(Number.MAX_SAFE_INTEGER)

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import { getCurrentTime, systemTime } from './systemTime.js'
66
import { logger } from './logging.js'
77
import shajs from 'sha.js'
88
import { SINGLE_USE_TOKEN_SALT } from '@sofie-automation/meteor-lib/dist/api/userActions'
9+
import RundownViewEventBus, {
10+
RundownViewEventBusEvents,
11+
RundownViewEvents,
12+
} from '@sofie-automation/meteor-lib/dist/triggers/RundownViewEventBus'
913

1014
export { multilineText, isEventInInputField }
1115

@@ -237,3 +241,16 @@ export function hashSingleUseToken(token: string): string {
237241
.digest('base64')
238242
.replace(/[+/=]/g, '_')
239243
}
244+
245+
export function useRundownViewEventBusListener<TEvent extends RundownViewEvents>(
246+
name: TEvent,
247+
cb: (...args: RundownViewEventBusEvents[TEvent]) => void
248+
): void {
249+
useEffect(() => {
250+
// We need to force the cb type, typescript can't infer this through the generic
251+
RundownViewEventBus.on(name, cb as any)
252+
return () => {
253+
RundownViewEventBus.off(name, cb as any)
254+
}
255+
}, [name, cb])
256+
}

packages/webui/src/client/lib/triggers/TriggersHandler.tsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ import { IWrappedAdLib } from '@sofie-automation/meteor-lib/dist/triggers/action
1717
import { ReactiveVar } from 'meteor/reactive-var'
1818
import { preventDefault } from '../SorensenContext.js'
1919
import { getFinalKey } from './codesToKeyLabels.js'
20-
import RundownViewEventBus, {
21-
RundownViewEvents,
22-
TriggerActionEvent,
23-
} from '@sofie-automation/meteor-lib/dist/triggers/RundownViewEventBus'
20+
import { RundownViewEvents, TriggerActionEvent } from '@sofie-automation/meteor-lib/dist/triggers/RundownViewEventBus'
2421
import { Tracker } from 'meteor/tracker'
2522
import { Settings } from '../../lib/Settings.js'
2623
import { createInMemorySyncMongoCollection } from '../../collections/lib.js'
@@ -42,7 +39,7 @@ import {
4239
} from '@sofie-automation/meteor-lib/dist/api/MountedTriggers'
4340
import { isHotkeyTrigger } from '@sofie-automation/meteor-lib/dist/triggers/triggerTypeSelectors'
4441
import { RundownPlaylistCollectionUtil } from '../../collections/rundownPlaylistUtil.js'
45-
import { catchError } from '../lib.js'
42+
import { catchError, useRundownViewEventBusListener } from '../lib.js'
4643
import { logger } from '../logging.js'
4744
import { CorelibPubSub } from '@sofie-automation/corelib/dist/pubsub'
4845
import { toTriggersComputation, toTriggersReactiveVar, UiTriggersContext } from './triggersContext.js'
@@ -314,12 +311,7 @@ export const TriggersHandler: React.FC<IProps> = function TriggersHandler(
314311
}
315312
}, [initialized]) // run once once Sorensen is initialized
316313

317-
useEffect(() => {
318-
RundownViewEventBus.on(RundownViewEvents.TRIGGER_ACTION, triggerAction)
319-
return () => {
320-
RundownViewEventBus.removeListener(RundownViewEvents.TRIGGER_ACTION, triggerAction)
321-
}
322-
}, [])
314+
useRundownViewEventBusListener(RundownViewEvents.TRIGGER_ACTION, triggerAction)
323315

324316
useEffect(() => {
325317
Tracker.nonreactive(() => {

packages/webui/src/client/ui/SegmentAdlibTesting/SegmentAdlibTesting.tsx

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ import {
1010
} from '../SegmentContainer/withResolvedSegment.js'
1111
import { ContextMenuTrigger } from '@jstarpl/react-contextmenu'
1212
import { CriticalIconSmall, WarningIconSmall } from '../../lib/ui/icons/notifications.js'
13-
import { contextMenuHoldToDisplayTime, useCombinedRefs } from '../../lib/lib.js'
13+
import { contextMenuHoldToDisplayTime, useCombinedRefs, useRundownViewEventBusListener } from '../../lib/lib.js'
1414
import { useTranslation } from 'react-i18next'
1515
import { literal, unprotectString } from '../../lib/tempLib.js'
1616
import { lockPointer, unlockPointer } from '../../lib/viewPort.js'
1717
import { StoryboardPart } from '../SegmentStoryboard/StoryboardPart.js'
1818
import classNames from 'classnames'
19-
import RundownViewEventBus, {
19+
import {
2020
GoToPartEvent,
2121
GoToPartInstanceEvent,
2222
RundownViewEvents,
@@ -236,17 +236,9 @@ export const SegmentAdlibTesting = React.memo(
236236
[renderedParts, props.followLiveLine]
237237
)
238238

239-
useEffect(() => {
240-
RundownViewEventBus.on(RundownViewEvents.REWIND_SEGMENTS, onRewindSegment)
241-
RundownViewEventBus.on(RundownViewEvents.GO_TO_PART, onGoToPart)
242-
RundownViewEventBus.on(RundownViewEvents.GO_TO_PART_INSTANCE, onGoToPartInstance)
243-
244-
return () => {
245-
RundownViewEventBus.off(RundownViewEvents.REWIND_SEGMENTS, onRewindSegment)
246-
RundownViewEventBus.off(RundownViewEvents.GO_TO_PART, onGoToPart)
247-
RundownViewEventBus.off(RundownViewEvents.GO_TO_PART_INSTANCE, onGoToPartInstance)
248-
}
249-
}, [onRewindSegment, onGoToPart, onGoToPartInstance])
239+
useRundownViewEventBusListener(RundownViewEvents.REWIND_SEGMENTS, onRewindSegment)
240+
useRundownViewEventBusListener(RundownViewEvents.GO_TO_PART, onGoToPart)
241+
useRundownViewEventBusListener(RundownViewEvents.GO_TO_PART_INSTANCE, onGoToPartInstance)
250242

251243
useLayoutEffect(() => {
252244
if (!listRef.current) return

packages/webui/src/client/ui/SegmentStoryboard/SegmentStoryboard.tsx

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ import { ContextMenuTrigger } from '@jstarpl/react-contextmenu'
1313
import { CriticalIconSmall, WarningIconSmall } from '../../lib/ui/icons/notifications.js'
1414
import { SegmentDuration } from '../RundownView/RundownTiming/SegmentDuration.js'
1515
import { PartCountdown } from '../RundownView/RundownTiming/PartCountdown.js'
16-
import { contextMenuHoldToDisplayTime, useCombinedRefs } from '../../lib/lib.js'
16+
import { contextMenuHoldToDisplayTime, useCombinedRefs, useRundownViewEventBusListener } from '../../lib/lib.js'
1717
import { isPartPlayable } from '@sofie-automation/corelib/dist/dataModel/Part'
1818
import { useTranslation } from 'react-i18next'
1919
import { UIStateStorage } from '../../lib/UIStateStorage.js'
2020
import { literal, unprotectString } from '../../lib/tempLib.js'
2121
import { lockPointer, scrollToPart, unlockPointer } from '../../lib/viewPort.js'
2222
import { StoryboardPart } from './StoryboardPart.js'
2323
import classNames from 'classnames'
24-
import RundownViewEventBus, {
24+
import {
2525
GoToPartEvent,
2626
GoToPartInstanceEvent,
2727
HighlightEvent,
@@ -329,19 +329,11 @@ export const SegmentStoryboard = React.memo(
329329
if (highlightTimeout.current) Meteor.clearTimeout(highlightTimeout.current)
330330
}
331331
}, [])
332-
useEffect(() => {
333-
RundownViewEventBus.on(RundownViewEvents.REWIND_SEGMENTS, onRewindSegment)
334-
RundownViewEventBus.on(RundownViewEvents.GO_TO_PART, onGoToPart)
335-
RundownViewEventBus.on(RundownViewEvents.GO_TO_PART_INSTANCE, onGoToPartInstance)
336-
RundownViewEventBus.on(RundownViewEvents.HIGHLIGHT, onHighlight)
337332

338-
return () => {
339-
RundownViewEventBus.off(RundownViewEvents.REWIND_SEGMENTS, onRewindSegment)
340-
RundownViewEventBus.off(RundownViewEvents.GO_TO_PART, onGoToPart)
341-
RundownViewEventBus.off(RundownViewEvents.GO_TO_PART_INSTANCE, onGoToPartInstance)
342-
RundownViewEventBus.off(RundownViewEvents.HIGHLIGHT, onHighlight)
343-
}
344-
}, [onRewindSegment, onGoToPart, onGoToPartInstance, onHighlight])
333+
useRundownViewEventBusListener(RundownViewEvents.REWIND_SEGMENTS, onRewindSegment)
334+
useRundownViewEventBusListener(RundownViewEvents.GO_TO_PART, onGoToPart)
335+
useRundownViewEventBusListener(RundownViewEvents.GO_TO_PART_INSTANCE, onGoToPartInstance)
336+
useRundownViewEventBusListener(RundownViewEvents.HIGHLIGHT, onHighlight)
345337

346338
useLayoutEffect(() => {
347339
if (!listRef.current) return

packages/webui/src/client/ui/SegmentStoryboard/StoryboardPart.tsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,14 @@ import { IOutputLayerUi, SegmentUi } from '../SegmentContainer/withResolvedSegme
66
import { StoryboardPartSecondaryPieces } from './StoryboardPartSecondaryPieces/StoryboardPartSecondaryPieces.js'
77
import { StoryboardPartThumbnail } from './StoryboardPartThumbnail/StoryboardPartThumbnail.js'
88
import { ContextMenuTrigger } from '@jstarpl/react-contextmenu'
9-
import { contextMenuHoldToDisplayTime } from '../../lib/lib.js'
9+
import { contextMenuHoldToDisplayTime, useRundownViewEventBusListener } from '../../lib/lib.js'
1010
import { getElementDocumentOffset } from '../../utils/positions.js'
1111
import { IContextMenuContext } from '../RundownView.js'
1212
import { literal } from '../../lib/tempLib.js'
1313
import { SegmentTimelinePartElementId } from '../SegmentTimeline/Parts/SegmentTimelinePart.js'
1414
import { CurrentPartOrSegmentRemaining } from '../RundownView/RundownTiming/CurrentPartOrSegmentRemaining.js'
1515
import { getAllowSpeaking, getAllowVibrating } from '../../lib/localStorage.js'
16-
import RundownViewEventBus, {
17-
HighlightEvent,
18-
RundownViewEvents,
19-
} from '@sofie-automation/meteor-lib/dist/triggers/RundownViewEventBus'
16+
import { HighlightEvent, RundownViewEvents } from '@sofie-automation/meteor-lib/dist/triggers/RundownViewEventBus'
2017
import { Meteor } from 'meteor/meteor'
2118
import { StoryboardPartTransitions } from './StoryboardPartTransitions.js'
2219
import { PartDisplayDuration } from '../RundownView/RundownTiming/PartDuration.js'
@@ -130,13 +127,8 @@ export const StoryboardPart = withTiming<IProps, {}>((props: IProps) => {
130127
if (highlightTimeout.current) Meteor.clearTimeout(highlightTimeout.current)
131128
}
132129
}, [])
133-
useEffect(() => {
134-
RundownViewEventBus.on(RundownViewEvents.HIGHLIGHT, onHighlight)
135130

136-
return () => {
137-
RundownViewEventBus.off(RundownViewEvents.HIGHLIGHT, onHighlight)
138-
}
139-
}, [onHighlight])
131+
useRundownViewEventBusListener(RundownViewEvents.HIGHLIGHT, onHighlight)
140132

141133
const isInvalid = part.instance.part.invalid
142134
const isFloated = part.instance.part.floated

packages/webui/src/client/ui/SegmentTimeline/SourceLayerItem.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@ import { LocalLayerItemRenderer } from './Renderers/LocalLayerItemRenderer.js'
1212
import { DEBUG_MODE } from './SegmentTimelineDebugMode.js'
1313
import { getElementDocumentOffset, OffsetPosition } from '../../utils/positions.js'
1414
import { unprotectString } from '../../lib/tempLib.js'
15-
import RundownViewEventBus, {
16-
RundownViewEvents,
17-
HighlightEvent,
18-
} from '@sofie-automation/meteor-lib/dist/triggers/RundownViewEventBus'
15+
import { RundownViewEvents, HighlightEvent } from '@sofie-automation/meteor-lib/dist/triggers/RundownViewEventBus'
1916
import { pieceUiClassNames } from '../../lib/ui/pieceUiClassNames.js'
2017
import { TransitionSourceRenderer } from './Renderers/TransitionSourceRenderer.js'
2118
import { UIStudio } from '@sofie-automation/meteor-lib/dist/api/studios'
@@ -28,6 +25,7 @@ import {
2825
IPreviewPopUpSession,
2926
PreviewPopUpContext,
3027
} from '../PreviewPopUp/PreviewPopUpContext.js'
28+
import { useRundownViewEventBusListener } from '../../lib/lib.js'
3129
const LEFT_RIGHT_ANCHOR_SPACER = 15
3230
const MARGINAL_ANCHORED_WIDTH = 5
3331

@@ -146,10 +144,10 @@ export const SourceLayerItem = (props: Readonly<ISourceLayerItemProps>): JSX.Ele
146144
},
147145
[part, piece]
148146
)
147+
148+
useRundownViewEventBusListener(RundownViewEvents.HIGHLIGHT, onHighlight)
149149
useEffect(() => {
150-
RundownViewEventBus.on(RundownViewEvents.HIGHLIGHT, onHighlight)
151150
return () => {
152-
RundownViewEventBus.off(RundownViewEvents.HIGHLIGHT, onHighlight)
153151
clearTimeout(highlightTimeout.current)
154152
}
155153
}, [])

0 commit comments

Comments
 (0)