Skip to content

Commit 45fa3d2

Browse files
committed
Merge branch 'upstream/studio-settings-for-features' of github.com:bbc/sofie-core into release52
2 parents 3f63362 + ea2cae1 commit 45fa3d2

File tree

18 files changed

+178
-10
lines changed

18 files changed

+178
-10
lines changed

meteor/__mocks__/defaultCollectionObjects.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ export function defaultStudio(_id: StudioId): DBStudio {
110110
mediaPreviewsUrl: '',
111111
minimumTakeSpan: DEFAULT_MINIMUM_TAKE_SPAN,
112112
fallbackPartDuration: DEFAULT_FALLBACK_PART_DURATION,
113+
allowHold: false,
114+
allowPieceDirectPlay: false,
115+
enableBuckets: false,
113116
},
114117
_rundownVersionHash: '',
115118
routeSetsWithOverrides: wrapDefaultObject({}),

meteor/server/api/rest/v1/typeConversion.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
StudioId,
2020
} from '@sofie-automation/corelib/dist/dataModel/Ids'
2121
import { DBStudio, IStudioSettings } from '@sofie-automation/corelib/dist/dataModel/Studio'
22-
import { assertNever, getRandomId, literal } from '@sofie-automation/corelib/dist/lib'
22+
import { assertNever, Complete, getRandomId, literal } from '@sofie-automation/corelib/dist/lib'
2323
import { protectString, unprotectString } from '@sofie-automation/corelib/dist/protectedString'
2424
import {
2525
applyAndValidateOverrides,
@@ -333,7 +333,7 @@ export async function studioFrom(apiStudio: APIStudio, existingId?: StudioId): P
333333
}
334334
}
335335

336-
export async function APIStudioFrom(studio: DBStudio): Promise<APIStudio> {
336+
export async function APIStudioFrom(studio: DBStudio): Promise<Complete<APIStudio>> {
337337
const studioSettings = APIStudioSettingsFrom(studio.settings)
338338

339339
return {
@@ -346,7 +346,7 @@ export async function APIStudioFrom(studio: DBStudio): Promise<APIStudio> {
346346
}
347347
}
348348

349-
export function studioSettingsFrom(apiStudioSettings: APIStudioSettings): IStudioSettings {
349+
export function studioSettingsFrom(apiStudioSettings: APIStudioSettings): Complete<IStudioSettings> {
350350
return {
351351
frameRate: apiStudioSettings.frameRate,
352352
mediaPreviewsUrl: apiStudioSettings.mediaPreviewsUrl,
@@ -362,10 +362,14 @@ export function studioSettingsFrom(apiStudioSettings: APIStudioSettings): IStudi
362362
enableQuickLoop: apiStudioSettings.enableQuickLoop,
363363
forceQuickLoopAutoNext: forceQuickLoopAutoNextFrom(apiStudioSettings.forceQuickLoopAutoNext),
364364
fallbackPartDuration: apiStudioSettings.fallbackPartDuration ?? DEFAULT_FALLBACK_PART_DURATION,
365+
allowAdlibTestingSegment: apiStudioSettings.allowAdlibTestingSegment,
366+
allowHold: apiStudioSettings.allowHold ?? true, // Backwards compatible
367+
allowPieceDirectPlay: apiStudioSettings.allowPieceDirectPlay ?? true, // Backwards compatible
368+
enableBuckets: apiStudioSettings.enableBuckets ?? true, // Backwards compatible
365369
}
366370
}
367371

368-
export function APIStudioSettingsFrom(settings: IStudioSettings): APIStudioSettings {
372+
export function APIStudioSettingsFrom(settings: IStudioSettings): Complete<APIStudioSettings> {
369373
return {
370374
frameRate: settings.frameRate,
371375
mediaPreviewsUrl: settings.mediaPreviewsUrl,
@@ -381,6 +385,10 @@ export function APIStudioSettingsFrom(settings: IStudioSettings): APIStudioSetti
381385
enableQuickLoop: settings.enableQuickLoop,
382386
forceQuickLoopAutoNext: APIForceQuickLoopAutoNextFrom(settings.forceQuickLoopAutoNext),
383387
fallbackPartDuration: settings.fallbackPartDuration,
388+
allowAdlibTestingSegment: settings.allowAdlibTestingSegment,
389+
allowHold: settings.allowHold,
390+
allowPieceDirectPlay: settings.allowPieceDirectPlay,
391+
enableBuckets: settings.enableBuckets,
384392
}
385393
}
386394

meteor/server/api/studio/api.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ export async function insertStudioInner(organizationId: OrganizationId | null, n
4848
frameRate: 25,
4949
mediaPreviewsUrl: '',
5050
minimumTakeSpan: DEFAULT_MINIMUM_TAKE_SPAN,
51+
allowHold: false,
52+
allowPieceDirectPlay: false,
53+
enableBuckets: true,
5154
},
5255
_rundownVersionHash: '',
5356
routeSetsWithOverrides: wrapDefaultObject({}),

meteor/server/lib/rest/v1/studios.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,4 +214,8 @@ export interface APIStudioSettings {
214214
forceQuickLoopAutoNext?: 'disabled' | 'enabled_when_valid_duration' | 'enabled_forcing_min_duration'
215215
minimumTakeSpan?: number
216216
fallbackPartDuration?: number
217+
allowAdlibTestingSegment?: boolean
218+
allowHold?: boolean
219+
allowPieceDirectPlay?: boolean
220+
enableBuckets?: boolean
217221
}

meteor/server/migration/0_1_0.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,9 @@ export const addSteps = addMigrationSteps('0.1.0', [
441441
frameRate: 25,
442442
mediaPreviewsUrl: '',
443443
minimumTakeSpan: DEFAULT_MINIMUM_TAKE_SPAN,
444+
allowHold: false,
445+
allowPieceDirectPlay: false,
446+
enableBuckets: true,
444447
},
445448
mappingsWithOverrides: wrapDefaultObject({}),
446449
blueprintConfigWithOverrides: wrapDefaultObject({}),

meteor/server/migration/X_X_X.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,41 @@ export const addSteps = addMigrationSteps(CURRENT_SYSTEM_VERSION, [
187187
}
188188
},
189189
},
190+
191+
{
192+
id: `add studio settings allowHold & allowPieceDirectPlay`,
193+
canBeRunAutomatically: true,
194+
validate: async () => {
195+
const studios = await Studios.findFetchAsync({
196+
$or: [
197+
{ 'settings.allowHold': { $exists: false } },
198+
{ 'settings.allowPieceDirectPlay': { $exists: false } },
199+
],
200+
})
201+
202+
if (studios.length > 0) {
203+
return 'studios must have settings.allowHold and settings.allowPieceDirectPlay defined'
204+
}
205+
206+
return false
207+
},
208+
migrate: async () => {
209+
const studios = await Studios.findFetchAsync({
210+
$or: [
211+
{ 'settings.allowHold': { $exists: false } },
212+
{ 'settings.allowPieceDirectPlay': { $exists: false } },
213+
],
214+
})
215+
216+
for (const studio of studios) {
217+
// Populate the settings to be backwards compatible
218+
await Studios.updateAsync(studio._id, {
219+
$set: {
220+
'settings.allowHold': true,
221+
'settings.allowPieceDirectPlay': true,
222+
},
223+
})
224+
}
225+
},
226+
},
190227
])

meteor/server/migration/__tests__/migrations.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ describe('Migrations', () => {
126126
mediaPreviewsUrl: '',
127127
frameRate: 25,
128128
minimumTakeSpan: DEFAULT_MINIMUM_TAKE_SPAN,
129+
allowHold: true,
130+
allowPieceDirectPlay: true,
131+
enableBuckets: true,
129132
},
130133
mappingsWithOverrides: wrapDefaultObject({}),
131134
blueprintConfigWithOverrides: wrapDefaultObject({}),
@@ -164,6 +167,9 @@ describe('Migrations', () => {
164167
mediaPreviewsUrl: '',
165168
frameRate: 25,
166169
minimumTakeSpan: DEFAULT_MINIMUM_TAKE_SPAN,
170+
allowHold: true,
171+
allowPieceDirectPlay: true,
172+
enableBuckets: true,
167173
},
168174
mappingsWithOverrides: wrapDefaultObject({}),
169175
blueprintConfigWithOverrides: wrapDefaultObject({}),
@@ -202,6 +208,9 @@ describe('Migrations', () => {
202208
mediaPreviewsUrl: '',
203209
frameRate: 25,
204210
minimumTakeSpan: DEFAULT_MINIMUM_TAKE_SPAN,
211+
allowHold: true,
212+
allowPieceDirectPlay: true,
213+
enableBuckets: true,
205214
},
206215
mappingsWithOverrides: wrapDefaultObject({}),
207216
blueprintConfigWithOverrides: wrapDefaultObject({}),

meteor/server/publications/pieceContentStatusUI/__tests__/checkPieceContentStatus.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,7 @@ describe('lib/mediaObjects', () => {
167167
test('getAcceptedFormats', () => {
168168
const acceptedFormats = getAcceptedFormats({
169169
supportedMediaFormats: '1920x1080i5000, 1280x720, i5000, i5000tff',
170-
mediaPreviewsUrl: '',
171170
frameRate: 25,
172-
minimumTakeSpan: DEFAULT_MINIMUM_TAKE_SPAN,
173171
})
174172
expect(acceptedFormats).toEqual([
175173
['1920', '1080', 'i', '5000', undefined],
@@ -252,6 +250,9 @@ describe('lib/mediaObjects', () => {
252250
supportedAudioStreams: '4',
253251
frameRate: 25,
254252
minimumTakeSpan: DEFAULT_MINIMUM_TAKE_SPAN,
253+
allowHold: false,
254+
allowPieceDirectPlay: false,
255+
enableBuckets: false,
255256
}
256257

257258
const mockDefaultStudio = defaultStudio(protectString('studio0'))

meteor/server/publications/pieceContentStatusUI/checkPieceContentStatus.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,9 @@ export function acceptFormat(format: string, formats: Array<Array<string>>): boo
147147
* [undefined, undefined, i, 5000, tff]
148148
* ]
149149
*/
150-
export function getAcceptedFormats(settings: IStudioSettings | undefined): Array<Array<string>> {
150+
export function getAcceptedFormats(
151+
settings: Pick<IStudioSettings, 'supportedMediaFormats' | 'frameRate'> | undefined
152+
): Array<Array<string>> {
151153
const formatsConfigField = settings ? settings.supportedMediaFormats : ''
152154
const formatsString: string =
153155
(formatsConfigField && formatsConfigField !== '' ? formatsConfigField : '1920x1080i5000') + ''

packages/corelib/src/dataModel/Studio.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,24 @@ export interface IStudioSettings {
8888
* Default: 3000
8989
*/
9090
fallbackPartDuration?: number
91+
92+
/**
93+
* Whether to allow hold operations for Rundowns in this Studio
94+
* When disabled, any action-triggers that would normally trigger a hold operation will be silently ignored
95+
* This should only block entering hold, to ensure Sofie doesn't get stuck if it somehow gets into hold
96+
*/
97+
allowHold: boolean
98+
99+
/**
100+
* Whether to allow direct playing of a piece in the rundown
101+
* This behaviour is usally triggered by double-clicking on a piece in the GUI
102+
*/
103+
allowPieceDirectPlay: boolean
104+
105+
/**
106+
* Enable buckets - the default behavior is to have buckets.
107+
*/
108+
enableBuckets: boolean
91109
}
92110

93111
export type StudioLight = Omit<DBStudio, 'mappingsWithOverrides' | 'blueprintConfigWithOverrides'>

0 commit comments

Comments
 (0)