@@ -5,8 +5,13 @@ import { setNextPart } from '../playout/setNext.js'
55import { isPartPlayable } from '@sofie-automation/corelib/dist/dataModel/Part'
66
77/**
8- * Make sure that the nextPartInstance for the current Playlist is still correct
9- * This will often change the nextPartInstance
8+ * Make sure that the nextPartInstance for the current Playlist is still correct.
9+ * This will often change the nextPartInstance.
10+ *
11+ * If the selected next part has been deleted by ingest, the default behavior is to
12+ * drop it and autoselect a replacement. If the show-style blueprint defines
13+ * `syncIngestUpdateToPartInstance`, the deleted next part is kept selected here so
14+ * the blueprint can decide whether to remove it or preserve it.
1015 * @param context Context of the job being run
1116 * @param playoutModel Playout Model to operate on
1217 * @returns Whether the timeline should be updated following this operation
@@ -43,14 +48,22 @@ export async function ensureNextPartIsValid(context: JobContext, playoutModel: P
4348
4449 const orderedSegments = playoutModel . getAllOrderedSegments ( )
4550 const orderedParts = playoutModel . getAllOrderedParts ( )
51+ const nextPartIsDeleted = nextPartInstance ?. partInstance . orphaned === 'deleted'
4652
47- if ( ! nextPartInstance || nextPartInstance . partInstance . orphaned === 'deleted' ) {
48- // Don't have a nextPart or it has been deleted, so autoselect something
53+ if ( nextPartIsDeleted && ( await hasSyncIngestUpdateToPartInstance ( context , playoutModel , nextPartInstance ) ) ) {
54+ // Source has deleted this part, but it is selected as next.
55+ // Keep it selected, and let blueprint function `syncIngestUpdateToPartInstance` decide what to do with it.
56+ span ?. end ( )
57+ return false
58+ }
59+
60+ if ( ! nextPartInstance || nextPartIsDeleted ) {
61+ // Don't have a nextPart, so autoselect something
4962 const newNextPart = selectNextPart (
5063 context ,
5164 playlist ,
5265 currentPartInstance ?. partInstance ?? null ,
53- nextPartInstance ?. partInstance ?? null ,
66+ null ,
5467 orderedSegments ,
5568 orderedParts ,
5669 { ignoreUnplayable : true , ignoreQuickLoop : false }
@@ -97,3 +110,26 @@ export async function ensureNextPartIsValid(context: JobContext, playoutModel: P
97110 span ?. end ( )
98111 return false
99112}
113+
114+ async function hasSyncIngestUpdateToPartInstance (
115+ context : JobContext ,
116+ playoutModel : PlayoutModel ,
117+ nextPartInstance : PlayoutModel [ 'nextPartInstance' ]
118+ ) : Promise < boolean > {
119+ if ( ! nextPartInstance ) return false
120+ const rundown = playoutModel . getRundown ( nextPartInstance . partInstance . part . rundownId )
121+ if ( ! rundown ) return false
122+ if ( ! rundown . rundown . showStyleVariantId ) return false
123+
124+ try {
125+ const showStyle = await context . getShowStyleCompound (
126+ rundown . rundown . showStyleVariantId ,
127+ rundown . rundown . showStyleBaseId
128+ )
129+ const blueprint = await context . getShowStyleBlueprint ( showStyle . _id )
130+
131+ return ! ! blueprint . blueprint . syncIngestUpdateToPartInstance
132+ } catch {
133+ return false
134+ }
135+ }
0 commit comments