@@ -312,12 +312,251 @@ export class SegmentTimelinePartClass extends React.Component<Translated<WithTim
312312 if ( this . highlightTimeout ) clearTimeout ( this . highlightTimeout )
313313 }
314314
315- shouldComponentUpdate ( nextProps : Readonly < WithTiming < IProps > > , nextState : Readonly < IState > ) : boolean {
316- if ( ! _ . isMatch ( this . props , nextProps ) || ! _ . isMatch ( this . state , nextState ) ) {
317- return true
318- } else {
315+ private static getPlaylistRenderSelector ( playlist : DBRundownPlaylist ) {
316+ const quickLoopStartId =
317+ playlist . quickLoop ?. start && 'id' in playlist . quickLoop . start ? playlist . quickLoop . start . id : undefined
318+ const quickLoopEndId =
319+ playlist . quickLoop ?. end && 'id' in playlist . quickLoop . end ? playlist . quickLoop . end . id : undefined
320+
321+ return {
322+ activationId : playlist . activationId ,
323+ currentPartInstanceId : playlist . currentPartInfo ?. partInstanceId ,
324+ nextPartInstanceId : playlist . nextPartInfo ?. partInstanceId ,
325+ previousPartInstanceId : playlist . previousPartInfo ?. partInstanceId ,
326+ nextTimeOffset : playlist . nextTimeOffset ,
327+ quickLoopRunning : playlist . quickLoop ?. running ,
328+ quickLoopStartType : playlist . quickLoop ?. start ?. type ,
329+ quickLoopStartId,
330+ quickLoopEndType : playlist . quickLoop ?. end ?. type ,
331+ quickLoopEndId,
332+ }
333+ }
334+
335+ private static getPartRenderSelector ( part : PartUi ) {
336+ return {
337+ partId : part . partId ,
338+ startsAt : part . startsAt ,
339+ renderedDuration : part . renderedDuration ,
340+ willProbablyAutoNext : part . willProbablyAutoNext ,
341+ instanceId : part . instance . _id ,
342+ instanceTimings : part . instance . timings ,
343+ instancePart : part . instance . part ,
344+ pieces : part . pieces ,
345+ }
346+ }
347+
348+ private static getSegmentRenderSelector ( segment : SegmentUi ) {
349+ return {
350+ segmentId : segment . _id ,
351+ outputLayers : segment . outputLayers ,
352+ }
353+ }
354+
355+ private static getTimingRenderSelector ( props : Readonly < WithTiming < IProps > > ) {
356+ const timingId = getPartInstanceTimingId ( props . part . instance )
357+ const firstPartTimingId = props . firstPartInSegment
358+ ? getPartInstanceTimingId ( props . firstPartInSegment . instance )
359+ : undefined
360+ const lastPartTimingId = props . lastPartInSegment
361+ ? getPartInstanceTimingId ( props . lastPartInSegment . instance )
362+ : undefined
363+
364+ return {
365+ partDuration : props . timingDurations . partDurations ?. [ timingId ] ,
366+ partDisplayStart : props . timingDurations . partDisplayStartsAt ?. [ timingId ] ,
367+ partDisplayDuration : props . timingDurations . partDisplayDurations ?. [ timingId ] ,
368+ partInQuickLoop : props . timingDurations . partsInQuickLoop ?. [ timingId ] ,
369+ firstPartDisplayStart : firstPartTimingId
370+ ? props . timingDurations . partDisplayStartsAt ?. [ firstPartTimingId ]
371+ : undefined ,
372+ firstPartDisplayDuration : firstPartTimingId
373+ ? props . timingDurations . partDisplayDurations ?. [ firstPartTimingId ]
374+ : undefined ,
375+ lastPartDisplayStart : lastPartTimingId
376+ ? props . timingDurations . partDisplayStartsAt ?. [ lastPartTimingId ]
377+ : undefined ,
378+ lastPartDisplayDuration : lastPartTimingId
379+ ? props . timingDurations . partDisplayDurations ?. [ lastPartTimingId ]
380+ : undefined ,
381+ }
382+ }
383+
384+ private static hasImmediatePropChanges (
385+ prevProps : Readonly < Translated < WithTiming < IProps > > > ,
386+ nextProps : Readonly < Translated < WithTiming < IProps > > >
387+ ) : boolean {
388+ return (
389+ prevProps . timeToPixelRatio !== nextProps . timeToPixelRatio ||
390+ prevProps . scrollLeft !== nextProps . scrollLeft ||
391+ prevProps . scrollWidth !== nextProps . scrollWidth ||
392+ prevProps . followLiveLine !== nextProps . followLiveLine ||
393+ prevProps . autoNextPart !== nextProps . autoNextPart ||
394+ prevProps . liveLineHistorySize !== nextProps . liveLineHistorySize ||
395+ prevProps . livePosition !== nextProps . livePosition ||
396+ prevProps . isCollapsed !== nextProps . isCollapsed ||
397+ prevProps . isLastInSegment !== nextProps . isLastInSegment ||
398+ prevProps . isAfterLastValidInSegmentAndItsLive !== nextProps . isAfterLastValidInSegmentAndItsLive ||
399+ prevProps . isLastSegment !== nextProps . isLastSegment ||
400+ prevProps . isBudgetGap !== nextProps . isBudgetGap ||
401+ prevProps . isPreview !== nextProps . isPreview ||
402+ prevProps . cropDuration !== nextProps . cropDuration ||
403+ prevProps . className !== nextProps . className ||
404+ prevProps . isLiveSegment !== nextProps . isLiveSegment ||
405+ prevProps . anyPriorPartWasLive !== nextProps . anyPriorPartWasLive ||
406+ prevProps . livePartStartsAt !== nextProps . livePartStartsAt ||
407+ prevProps . livePartDisplayDuration !== nextProps . livePartDisplayDuration ||
408+ prevProps . budgetDuration !== nextProps . budgetDuration ||
409+ prevProps . t !== nextProps . t ||
410+ prevProps . i18n ?. language !== nextProps . i18n ?. language ||
411+ prevProps . onScroll !== nextProps . onScroll ||
412+ prevProps . onFollowLiveLine !== nextProps . onFollowLiveLine ||
413+ prevProps . onPieceClick !== nextProps . onPieceClick ||
414+ prevProps . onPieceDoubleClick !== nextProps . onPieceDoubleClick ||
415+ prevProps . onPartTooSmallChanged !== nextProps . onPartTooSmallChanged ||
416+ prevProps . onContextMenu !== nextProps . onContextMenu
417+ )
418+ }
419+
420+ private static hasPlaylistRenderChanges (
421+ prevProps : Readonly < Translated < WithTiming < IProps > > > ,
422+ nextProps : Readonly < Translated < WithTiming < IProps > > >
423+ ) : boolean {
424+ return ! _ . isEqual (
425+ SegmentTimelinePartClass . getPlaylistRenderSelector ( prevProps . playlist ) ,
426+ SegmentTimelinePartClass . getPlaylistRenderSelector ( nextProps . playlist )
427+ )
428+ }
429+
430+ private static hasPartRenderChanges (
431+ prevProps : Readonly < Translated < WithTiming < IProps > > > ,
432+ nextProps : Readonly < Translated < WithTiming < IProps > > >
433+ ) : boolean {
434+ return ! _ . isEqual (
435+ SegmentTimelinePartClass . getPartRenderSelector ( prevProps . part ) ,
436+ SegmentTimelinePartClass . getPartRenderSelector ( nextProps . part )
437+ )
438+ }
439+
440+ private static hasSegmentRenderChanges (
441+ prevProps : Readonly < Translated < WithTiming < IProps > > > ,
442+ nextProps : Readonly < Translated < WithTiming < IProps > > >
443+ ) : boolean {
444+ return ! _ . isEqual (
445+ SegmentTimelinePartClass . getSegmentRenderSelector ( prevProps . segment ) ,
446+ SegmentTimelinePartClass . getSegmentRenderSelector ( nextProps . segment )
447+ )
448+ }
449+
450+ private static hasStudioRenderChanges (
451+ prevProps : Readonly < Translated < WithTiming < IProps > > > ,
452+ nextProps : Readonly < Translated < WithTiming < IProps > > >
453+ ) : boolean {
454+ return (
455+ prevProps . studio . _id !== nextProps . studio . _id ||
456+ ! _ . isEqual ( prevProps . studio . settings , nextProps . studio . settings )
457+ )
458+ }
459+
460+ private static hasCollapsedOutputChanges (
461+ prevProps : Readonly < Translated < WithTiming < IProps > > > ,
462+ nextProps : Readonly < Translated < WithTiming < IProps > > >
463+ ) : boolean {
464+ return ! _ . isEqual ( prevProps . collapsedOutputs , nextProps . collapsedOutputs )
465+ }
466+
467+ private static hasBoundaryPartChanges (
468+ prevProps : Readonly < Translated < WithTiming < IProps > > > ,
469+ nextProps : Readonly < Translated < WithTiming < IProps > > >
470+ ) : boolean {
471+ return (
472+ prevProps . firstPartInSegment ?. instance . _id !== nextProps . firstPartInSegment ?. instance . _id ||
473+ prevProps . lastPartInSegment ?. instance . _id !== nextProps . lastPartInSegment ?. instance . _id
474+ )
475+ }
476+
477+ private static hasDurationSourceLayerChanges (
478+ prevProps : Readonly < Translated < WithTiming < IProps > > > ,
479+ nextProps : Readonly < Translated < WithTiming < IProps > > >
480+ ) : boolean {
481+ return ! _ . isEqual ( prevProps . showDurationSourceLayers , nextProps . showDurationSourceLayers )
482+ }
483+
484+ private static hasTimingRenderChanges (
485+ prevProps : Readonly < Translated < WithTiming < IProps > > > ,
486+ nextProps : Readonly < Translated < WithTiming < IProps > > >
487+ ) : boolean {
488+ return ! _ . isEqual (
489+ SegmentTimelinePartClass . getTimingRenderSelector ( prevProps ) ,
490+ SegmentTimelinePartClass . getTimingRenderSelector ( nextProps )
491+ )
492+ }
493+
494+ private static hasRelevantStateChanges ( prevState : Readonly < IState > , nextState : Readonly < IState > ) : boolean {
495+ return (
496+ prevState . isLive !== nextState . isLive ||
497+ prevState . isNext !== nextState . isNext ||
498+ prevState . isDurationSettling !== nextState . isDurationSettling ||
499+ prevState . durationSettlingStartsAt !== nextState . durationSettlingStartsAt ||
500+ prevState . liveDuration !== nextState . liveDuration ||
501+ prevState . isInQuickLoop !== nextState . isInQuickLoop ||
502+ prevState . isInsideViewport !== nextState . isInsideViewport ||
503+ prevState . isTooSmallForText !== nextState . isTooSmallForText ||
504+ prevState . isTooSmallForDisplay !== nextState . isTooSmallForDisplay ||
505+ prevState . highlight !== nextState . highlight ||
506+ prevState . dropActive !== nextState . dropActive
507+ )
508+ }
509+
510+ private static arePropsEquivalent (
511+ prevProps : Readonly < Translated < WithTiming < IProps > > > ,
512+ nextProps : Readonly < Translated < WithTiming < IProps > > >
513+ ) : boolean {
514+ if ( prevProps === nextProps ) return true
515+
516+ if ( SegmentTimelinePartClass . hasImmediatePropChanges ( prevProps , nextProps ) ) {
517+ return false
518+ }
519+
520+ if ( SegmentTimelinePartClass . hasPlaylistRenderChanges ( prevProps , nextProps ) ) {
521+ return false
522+ }
523+
524+ if ( SegmentTimelinePartClass . hasPartRenderChanges ( prevProps , nextProps ) ) {
525+ return false
526+ }
527+
528+ if ( SegmentTimelinePartClass . hasSegmentRenderChanges ( prevProps , nextProps ) ) {
319529 return false
320530 }
531+
532+ if ( SegmentTimelinePartClass . hasStudioRenderChanges ( prevProps , nextProps ) ) {
533+ return false
534+ }
535+
536+ if ( SegmentTimelinePartClass . hasCollapsedOutputChanges ( prevProps , nextProps ) ) {
537+ return false
538+ }
539+
540+ if ( SegmentTimelinePartClass . hasBoundaryPartChanges ( prevProps , nextProps ) ) {
541+ return false
542+ }
543+
544+ if ( SegmentTimelinePartClass . hasDurationSourceLayerChanges ( prevProps , nextProps ) ) {
545+ return false
546+ }
547+
548+ if ( SegmentTimelinePartClass . hasTimingRenderChanges ( prevProps , nextProps ) ) {
549+ return false
550+ }
551+
552+ return true
553+ }
554+
555+ shouldComponentUpdate ( nextProps : Readonly < Translated < WithTiming < IProps > > > , nextState : Readonly < IState > ) : boolean {
556+ return (
557+ ! SegmentTimelinePartClass . arePropsEquivalent ( this . props , nextProps ) ||
558+ SegmentTimelinePartClass . hasRelevantStateChanges ( this . state , nextState )
559+ )
321560 }
322561
323562 componentDidUpdate ( prevProps : Readonly < Translated < WithTiming < IProps > > > , prevState : IState , snapshot ?: unknown ) : void {
0 commit comments