Skip to content

Commit a0586cd

Browse files
committed
Merge branch 'fix-memory-leaks' into bbc-main-autonext
2 parents e1577ef + 5d316e2 commit a0586cd

5 files changed

Lines changed: 44 additions & 4 deletions

File tree

packages/webui/src/client/ui/SegmentTimeline/Parts/InvalidPartCover.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useContext, useRef } from 'react'
1+
import React, { useContext, useEffect, useRef } from 'react'
22
import type { PartInvalidReason } from '@sofie-automation/corelib/dist/dataModel/Part'
33
import { type IPreviewPopUpSession, PreviewPopUpContext } from '../../PreviewPopUp/PreviewPopUpContext.js'
44

@@ -39,6 +39,15 @@ export function InvalidPartCover({ className, invalidReason }: Readonly<IProps>)
3939
}
4040
}
4141

42+
useEffect(() => {
43+
return () => {
44+
if (previewSession.current) {
45+
previewSession.current.close()
46+
previewSession.current = null
47+
}
48+
}
49+
}, [])
50+
4251
return (
4352
<div className={className} ref={element} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>
4453
{/* TODOD - add back hover with warnings */}

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,8 @@ export class SegmentTimelineClass extends React.Component<Translated<WithTiming<
246246
RundownViewEventBus.on(RundownViewEvents.SEGMENT_ZOOM_ON, this.onRundownEventSegmentZoomOn)
247247
RundownViewEventBus.on(RundownViewEvents.SEGMENT_ZOOM_OFF, this.onRundownEventSegmentZoomOff)
248248

249-
setTimeout(() => {
249+
this.showEntireSegmentTimeout = setTimeout(() => {
250+
this.showEntireSegmentTimeout = undefined
250251
// TODO: This doesn't actually handle having new parts added/removed, which should cause the segment to re-scale!
251252
if (this.props.onShowEntireSegment) {
252253
this.props.onShowEntireSegment(undefined)
@@ -256,6 +257,10 @@ export class SegmentTimelineClass extends React.Component<Translated<WithTiming<
256257

257258
componentWillUnmount(): void {
258259
super.componentWillUnmount?.()
260+
if (this.showEntireSegmentTimeout) {
261+
clearTimeout(this.showEntireSegmentTimeout)
262+
this.showEntireSegmentTimeout = undefined
263+
}
259264
clearTimeout(this.highlightTimeout)
260265
if (this.segmentBlock) {
261266
this.segmentBlock.removeEventListener('wheel', this.onTimelineWheel, { capture: true })
@@ -283,6 +288,7 @@ export class SegmentTimelineClass extends React.Component<Translated<WithTiming<
283288
}
284289

285290
private highlightTimeout: NodeJS.Timeout | undefined
291+
private showEntireSegmentTimeout: NodeJS.Timeout | undefined
286292

287293
private onHighlight = (e: HighlightEvent) => {
288294
if (e.segmentId === this.props.segment._id && !e.partId && !e.pieceId) {

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

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ const SegmentTimelineContainerContent = withResolvedSegment(
144144

145145
isVisible: boolean
146146
visibilityChangeTimeout: NodeJS.Timeout | undefined
147+
initialShowEntireSegmentTimeout: NodeJS.Timeout | undefined
148+
initialShowEntireSegmentRaf: number | undefined
147149
rundownCurrentPartInstanceId: PartInstanceId | null = null
148150
timelineDiv: HTMLDivElement | null = null
149151
intersectionObserver: IntersectionObserver | undefined
@@ -194,8 +196,10 @@ const SegmentTimelineContainerContent = withResolvedSegment(
194196
RundownViewEventBus.on(RundownViewEvents.GO_TO_PART, this.onGoToPart)
195197
RundownViewEventBus.on(RundownViewEvents.GO_TO_PART_INSTANCE, this.onGoToPartInstance)
196198
// Delay is to ensure UI has settled before checking:
197-
setTimeout(() => {
198-
window.requestAnimationFrame(() => {
199+
this.initialShowEntireSegmentTimeout = setTimeout(() => {
200+
this.initialShowEntireSegmentTimeout = undefined
201+
this.initialShowEntireSegmentRaf = window.requestAnimationFrame(() => {
202+
this.initialShowEntireSegmentRaf = undefined
199203
this.mountedTime = Date.now()
200204
if (this.state.isLiveSegment && this.props.followLiveSegments && !this.isVisible) {
201205
scrollToSegment(this.props.segmentId, true).catch((error) => {
@@ -353,6 +357,15 @@ const SegmentTimelineContainerContent = withResolvedSegment(
353357
if (typeof this.props.onSegmentScroll === 'function') this.props.onSegmentScroll()
354358
}
355359

360+
if (this.initialShowEntireSegmentTimeout) {
361+
clearTimeout(this.initialShowEntireSegmentTimeout)
362+
this.initialShowEntireSegmentTimeout = undefined
363+
}
364+
if (this.initialShowEntireSegmentRaf !== undefined) {
365+
window.cancelAnimationFrame(this.initialShowEntireSegmentRaf)
366+
this.initialShowEntireSegmentRaf = undefined
367+
}
368+
356369
if (this.visibilityChangeTimeout) {
357370
clearTimeout(this.visibilityChangeTimeout)
358371
this.visibilityChangeTimeout = undefined

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,14 @@ export const SourceLayerItem = (props: Readonly<ISourceLayerItemProps>): JSX.Ele
166166
useEffect(() => {
167167
return () => {
168168
clearTimeout(highlightTimeout.current)
169+
if (animFrameHandle.current !== undefined) {
170+
cancelAnimationFrame(animFrameHandle.current)
171+
animFrameHandle.current = undefined
172+
}
173+
if (previewSession.current) {
174+
previewSession.current.close()
175+
previewSession.current = null
176+
}
169177
}
170178
}, [])
171179

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,10 @@ export class TimelineGrid extends React.Component<ITimelineGridProps> {
442442
}
443443

444444
componentWillUnmount(): void {
445+
if (typeof this.scheduledRepaint === 'number') {
446+
window.cancelAnimationFrame(this.scheduledRepaint)
447+
this.scheduledRepaint = null
448+
}
445449
if (this._resizeObserver) this._resizeObserver.disconnect()
446450
window.removeEventListener(RundownTiming.Events.timeupdateLowResolution, this.onTimeupdate)
447451
window.removeEventListener(RundownTiming.Events.timeupdateHighResolution, this.onTimeupdate)

0 commit comments

Comments
 (0)