@@ -337,6 +337,10 @@ const RundownViewContent = translateWithTracker<IPropsWithReady & ITrackedProps,
337337} ) (
338338 class RundownViewContent extends React . Component < Translated < IPropsWithReady & ITrackedProps > , IState > {
339339 private _hideNotificationsAfterMount : number | undefined
340+ private _goToTopIdleCallback : number | undefined
341+ private _goToLiveSegmentShortTimeout : ReturnType < typeof setTimeout > | undefined
342+ private _goToLiveSegmentLongTimeout : ReturnType < typeof setTimeout > | undefined
343+ private _headerNoteHighlightTimeout : ReturnType < typeof setTimeout > | undefined
340344
341345 constructor ( props : Translated < IPropsWithReady & ITrackedProps > ) {
342346 super ( props )
@@ -610,6 +614,7 @@ const RundownViewContent = translateWithTracker<IPropsWithReady & ITrackedProps,
610614 document . body . classList . remove ( 'dark' , 'vertical-overflow-only' )
611615 document . documentElement . removeAttribute ( 'data-bs-theme' )
612616 window . removeEventListener ( 'beforeunload' , this . onBeforeUnload )
617+ this . clearPendingDeferredCallbacks ( )
613618 resetViewportScrollState ( )
614619
615620 documentTitle . set ( null )
@@ -687,13 +692,37 @@ const RundownViewContent = translateWithTracker<IPropsWithReady & ITrackedProps,
687692 }
688693 }
689694
695+ private clearPendingDeferredCallbacks = ( ) => {
696+ if ( this . _goToTopIdleCallback !== undefined ) {
697+ window . cancelIdleCallback ( this . _goToTopIdleCallback )
698+ this . _goToTopIdleCallback = undefined
699+ }
700+ if ( this . _goToLiveSegmentShortTimeout ) {
701+ clearTimeout ( this . _goToLiveSegmentShortTimeout )
702+ this . _goToLiveSegmentShortTimeout = undefined
703+ }
704+ if ( this . _goToLiveSegmentLongTimeout ) {
705+ clearTimeout ( this . _goToLiveSegmentLongTimeout )
706+ this . _goToLiveSegmentLongTimeout = undefined
707+ }
708+ if ( this . _headerNoteHighlightTimeout ) {
709+ clearTimeout ( this . _headerNoteHighlightTimeout )
710+ this . _headerNoteHighlightTimeout = undefined
711+ }
712+ }
713+
690714 private onGoToTop = ( ) => {
691715 scrollToPosition ( 0 ) . catch ( ( error ) => {
692716 if ( ! error . toString ( ) . match ( / a n o t h e r s c r o l l / ) ) console . warn ( error )
693717 } )
694718
695- window . requestIdleCallback (
719+ if ( this . _goToTopIdleCallback !== undefined ) {
720+ window . cancelIdleCallback ( this . _goToTopIdleCallback )
721+ }
722+
723+ this . _goToTopIdleCallback = window . requestIdleCallback (
696724 ( ) => {
725+ this . _goToTopIdleCallback = undefined
697726 this . setState ( {
698727 followLiveSegments : true ,
699728 } )
@@ -703,6 +732,15 @@ const RundownViewContent = translateWithTracker<IPropsWithReady & ITrackedProps,
703732 }
704733
705734 private onGoToLiveSegment = ( ) => {
735+ if ( this . _goToLiveSegmentShortTimeout ) {
736+ clearTimeout ( this . _goToLiveSegmentShortTimeout )
737+ this . _goToLiveSegmentShortTimeout = undefined
738+ }
739+ if ( this . _goToLiveSegmentLongTimeout ) {
740+ clearTimeout ( this . _goToLiveSegmentLongTimeout )
741+ this . _goToLiveSegmentLongTimeout = undefined
742+ }
743+
706744 if (
707745 this . props . playlist &&
708746 this . props . playlist . activationId &&
@@ -713,14 +751,16 @@ const RundownViewContent = translateWithTracker<IPropsWithReady & ITrackedProps,
713751 followLiveSegments : true ,
714752 } )
715753 // Small delay to ensure the nextPartInfo is available
716- setTimeout ( ( ) => {
754+ this . _goToLiveSegmentShortTimeout = setTimeout ( ( ) => {
755+ this . _goToLiveSegmentShortTimeout = undefined
717756 if ( this . props . playlist && this . props . playlist . nextPartInfo ) {
718757 scrollToPartInstance ( this . props . playlist . nextPartInfo . partInstanceId , true ) . catch ( ( error ) => {
719758 if ( ! error . toString ( ) . match ( / a n o t h e r s c r o l l / ) ) console . warn ( error )
720759 } )
721760 }
722761 } , 120 )
723- setTimeout ( ( ) => {
762+ this . _goToLiveSegmentLongTimeout = setTimeout ( ( ) => {
763+ this . _goToLiveSegmentLongTimeout = undefined
724764 this . setState ( {
725765 followLiveSegments : true ,
726766 } )
@@ -733,7 +773,8 @@ const RundownViewContent = translateWithTracker<IPropsWithReady & ITrackedProps,
733773 scrollToPartInstance ( this . props . playlist . currentPartInfo . partInstanceId , true ) . catch ( ( error ) => {
734774 if ( ! error . toString ( ) . match ( / a n o t h e r s c r o l l / ) ) console . warn ( error )
735775 } )
736- setTimeout ( ( ) => {
776+ this . _goToLiveSegmentLongTimeout = setTimeout ( ( ) => {
777+ this . _goToLiveSegmentLongTimeout = undefined
737778 this . setState ( {
738779 followLiveSegments : true ,
739780 } )
@@ -899,7 +940,11 @@ const RundownViewContent = translateWithTracker<IPropsWithReady & ITrackedProps,
899940 this . setState ( {
900941 isNotificationsCenterOpen : level === NoteSeverity . ERROR ? NoticeLevel . CRITICAL : NoticeLevel . WARNING ,
901942 } )
902- setTimeout (
943+ if ( this . _headerNoteHighlightTimeout ) {
944+ clearTimeout ( this . _headerNoteHighlightTimeout )
945+ this . _headerNoteHighlightTimeout = undefined
946+ }
947+ this . _headerNoteHighlightTimeout = setTimeout (
903948 function ( ) {
904949 NotificationCenter . highlightSource (
905950 segmentId ,
0 commit comments