1- import type { RundownId , PartId } from '@sofie-automation/corelib/dist/dataModel/Ids'
1+ import type { RundownId } from '@sofie-automation/corelib/dist/dataModel/Ids'
22import { NrcsIngestCacheType } from '@sofie-automation/corelib/dist/dataModel/NrcsIngestDataCache'
3- import type { DBPartInstance } from '@sofie-automation/corelib/dist/dataModel/PartInstance'
43import {
54 IngestRundownStatus ,
65 IngestPartPlaybackStatus ,
76 IngestRundownActiveStatus ,
87 IngestPartStatus ,
8+ IngestPartNotifyItemReady ,
99} from '@sofie-automation/shared-lib/dist/ingest/rundownStatus'
1010import type { ReadonlyDeep } from 'type-fest'
1111import _ from 'underscore'
@@ -15,6 +15,7 @@ import { ReactiveCacheCollection } from '../lib/ReactiveCacheCollection'
1515import { PartInstance } from '@sofie-automation/meteor-lib/dist/collections/PartInstances'
1616import { IngestPart } from '@sofie-automation/blueprints-integration'
1717import { DBPart } from '@sofie-automation/corelib/dist/dataModel/Part'
18+ import { unprotectString } from '@sofie-automation/corelib/dist/protectedString'
1819
1920export function createIngestRundownStatus (
2021 cache : ReadonlyDeep < ContentCache > ,
@@ -41,9 +42,6 @@ export function createIngestRundownStatus(
4142 newDoc . active = playlist . rehearsal ? IngestRundownActiveStatus . REHEARSAL : IngestRundownActiveStatus . ACTIVE
4243 }
4344
44- // Find the most important part instance for each part
45- const partInstanceMap = findPartInstanceForEachPart ( playlist , rundownId , cache . PartInstances )
46-
4745 const nrcsSegments = cache . NrcsIngestData . find ( { rundownId, type : NrcsIngestCacheType . SEGMENT } ) . fetch ( )
4846 for ( const nrcsSegment of nrcsSegments ) {
4947 const nrcsParts = cache . NrcsIngestData . find ( {
@@ -58,10 +56,25 @@ export function createIngestRundownStatus(
5856 nrcsParts . map ( ( nrcsPart ) => {
5957 if ( ! nrcsPart . partId || ! nrcsPart . segmentId ) return null
6058
61- const part = cache . Parts . findOne ( { _id : nrcsPart . partId , rundownId } )
62- const partInstance = partInstanceMap . get ( nrcsPart . partId )
63-
64- return createIngestPartStatus ( playlist , partInstance , part , nrcsPart . data as IngestPart )
59+ const parts = cache . Parts . find ( {
60+ rundownId : rundownId ,
61+ $or : [
62+ {
63+ externalId : nrcsPart . data . externalId ,
64+ } ,
65+ {
66+ ingestNotifyPartExternalId : nrcsPart . data . externalId ,
67+ } ,
68+ ] ,
69+ } ) . fetch ( )
70+ const partInstances = findPartInstancesForIngestPart (
71+ playlist ,
72+ rundownId ,
73+ cache . PartInstances ,
74+ nrcsPart . data . externalId
75+ )
76+
77+ return createIngestPartStatus ( playlist , partInstances , parts , nrcsPart . data as IngestPart )
6578 } )
6679 ) ,
6780 } )
@@ -70,64 +83,110 @@ export function createIngestRundownStatus(
7083 return newDoc
7184}
7285
73- function findPartInstanceForEachPart (
86+ function findPartInstancesForIngestPart (
7487 playlist : Pick < DBRundownPlaylist , PlaylistFields > | undefined ,
7588 rundownId : RundownId ,
76- partInstancesCache : ReadonlyDeep < ReactiveCacheCollection < Pick < PartInstance , PartInstanceFields > > >
89+ partInstancesCache : ReadonlyDeep < ReactiveCacheCollection < Pick < PartInstance , PartInstanceFields > > > ,
90+ partExternalId : string
7791) {
78- const partInstanceMap = new Map < PartId , Pick < DBPartInstance , PartInstanceFields > > ( )
79- if ( ! playlist ) return partInstanceMap
92+ const result : Record < string , Pick < PartInstance , PartInstanceFields > > = { }
93+ if ( ! playlist ) return result
94+
95+ const candidatePartInstances = partInstancesCache
96+ . find ( {
97+ rundownId : rundownId ,
98+ $or : [
99+ {
100+ 'part.externalId' : partExternalId ,
101+ } ,
102+ {
103+ 'part.ingestNotifyPartExternalId' : partExternalId ,
104+ } ,
105+ ] ,
106+ } )
107+ . fetch ( )
80108
81- for ( const partInstance of partInstancesCache . find ( { } ) . fetch ( ) ) {
109+ for ( const partInstance of candidatePartInstances ) {
82110 if ( partInstance . rundownId !== rundownId ) continue
83111 // Ignore the next partinstance
84112 if ( partInstance . _id === playlist . nextPartInfo ?. partInstanceId ) continue
85113
114+ const partId = unprotectString ( partInstance . part . _id )
115+
86116 // The current part instance is the most important
87117 if ( partInstance . _id === playlist . currentPartInfo ?. partInstanceId ) {
88- partInstanceMap . set ( partInstance . part . _id , partInstance )
118+ result [ partId ] = partInstance
89119 continue
90120 }
91121
92122 // Take the part with the highest takeCount
93- const existingEntry = partInstanceMap . get ( partInstance . part . _id )
123+ const existingEntry = result [ partId ]
94124 if ( ! existingEntry || existingEntry . takeCount < partInstance . takeCount ) {
95- partInstanceMap . set ( partInstance . part . _id , partInstance )
125+ result [ partId ] = partInstance
96126 }
97127 }
98128
99- return partInstanceMap
129+ return result
100130}
101131
102132function createIngestPartStatus (
103133 playlist : Pick < DBRundownPlaylist , PlaylistFields > | undefined ,
104- partInstance : Pick < PartInstance , PartInstanceFields > | undefined ,
105- part : Pick < DBPart , PartFields > | undefined ,
134+ partInstances : Record < string , Pick < PartInstance , PartInstanceFields > > ,
135+ parts : Pick < DBPart , PartFields > [ ] ,
106136 ingestPart : IngestPart
107137) : IngestPartStatus {
108138 // Determine the playback status from the PartInstance
109139 let playbackStatus = IngestPartPlaybackStatus . UNKNOWN
110- if ( playlist && partInstance && partInstance . part . shouldNotifyCurrentPlayingPart ) {
111- const isCurrentPartInstance = playlist . currentPartInfo ?. partInstanceId === partInstance . _id
112-
113- if ( isCurrentPartInstance ) {
114- // If the current, it is playing
115- playbackStatus = IngestPartPlaybackStatus . PLAY
116- } else {
117- // If not the current, but has been played, it is stopped
118- playbackStatus = IngestPartPlaybackStatus . STOP
140+
141+ let isReady : boolean | null = null // Start off as null, the first value will make this true or false
142+
143+ const itemsReady : IngestPartNotifyItemReady [ ] = [ ]
144+
145+ const updateStatusWithPart = ( part : Pick < DBPart , PartFields > ) => {
146+ // If the part affects the ready status, update it
147+ if ( typeof part . ingestNotifyPartReady === 'boolean' ) {
148+ isReady = ( isReady ?? true ) && part . ingestNotifyPartReady
149+ }
150+
151+ // Include the items
152+ if ( part . ingestNotifyItemsReady ) {
153+ itemsReady . push ( ...part . ingestNotifyItemsReady )
119154 }
120155 }
121156
122- // Determine the ready status from the PartInstance or Part
123- const isReady = partInstance ? partInstance . part . ingestNotifyPartReady : part ?. ingestNotifyPartReady
124- const itemsReady = partInstance ? partInstance . part . ingestNotifyItemsReady : part ?. ingestNotifyItemsReady
157+ // Loop through the partInstances, starting off the state
158+ if ( playlist ) {
159+ for ( const partInstance of Object . values < Pick < PartInstance , PartInstanceFields > > ( partInstances ) ) {
160+ if ( ! partInstance ) continue
161+
162+ if ( partInstance . part . shouldNotifyCurrentPlayingPart ) {
163+ const isCurrentPartInstance = playlist . currentPartInfo ?. partInstanceId === partInstance . _id
164+
165+ if ( isCurrentPartInstance ) {
166+ // If the current, it is playing
167+ playbackStatus = IngestPartPlaybackStatus . PLAY
168+ } else if ( playbackStatus === IngestPartPlaybackStatus . UNKNOWN ) {
169+ // If not the current, but has been played, it is stopped
170+ playbackStatus = IngestPartPlaybackStatus . STOP
171+ }
172+ }
173+
174+ updateStatusWithPart ( partInstance . part )
175+ }
176+ }
177+
178+ for ( const part of parts ) {
179+ // Check if the part has already been handled by a partInstance
180+ if ( partInstances [ unprotectString ( part . _id ) ] ) continue
181+
182+ updateStatusWithPart ( part )
183+ }
125184
126185 return {
127186 externalId : ingestPart . externalId ,
128187
129- isReady : isReady ?? null ,
130- itemsReady : itemsReady ?? [ ] ,
188+ isReady : isReady ,
189+ itemsReady : itemsReady ,
131190
132191 playbackStatus,
133192 }
0 commit comments