Skip to content

Commit 302e559

Browse files
authored
Merge pull request #1233 from nrkno/fix/explicit-contentStatus-propogation
2 parents d2e5c31 + 598b932 commit 302e559

30 files changed

+427
-483
lines changed

meteor/client/lib/RundownResolver.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ import {
2424
} from '@sofie-automation/corelib/dist/dataModel/Ids'
2525
import { PieceInstances, Pieces } from '../../lib/collections/libCollections'
2626
import { RundownPlaylistCollectionUtil } from '../../lib/collections/rundownPlaylistUtil'
27-
import { PieceContentStatusObj } from '../../lib/api/pieceContentStatus'
28-
import { ReadonlyDeep } from 'type-fest'
2927
import { PieceInstanceWithTimings } from '@sofie-automation/corelib/dist/playout/processAndPrune'
3028

3129
export interface SegmentExtended extends DBSegment {
@@ -79,8 +77,6 @@ export interface PieceExtended {
7977
maxLabelWidth?: number
8078
/** If this piece has a "buddy" piece in the preceeding part, then it's not neccessary to display it's left label */
8179
hasOriginInPreceedingPart?: boolean
82-
83-
contentStatus?: ReadonlyDeep<PieceContentStatusObj>
8480
}
8581

8682
function fetchPiecesThatMayBeActiveForPart(

meteor/client/lib/shelf.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import { UIShowStyleBase } from '../../lib/api/showStyles'
1313
import { PieceId, SegmentId } from '@sofie-automation/corelib/dist/dataModel/Ids'
1414
import { PieceInstances } from '../collections'
1515
import { ReadonlyDeep } from 'type-fest'
16-
import { PieceContentStatusObj } from '../../lib/api/pieceContentStatus'
1716

1817
export interface ShelfDisplayOptions {
1918
enableBuckets: boolean
@@ -33,8 +32,6 @@ export interface AdLibPieceUi extends Omit<AdLibPiece, 'timelineObjectsString'>
3332
disabled?: boolean
3433
adlibAction?: AdLibAction | RundownBaselineAdLibAction
3534
segmentId?: SegmentId
36-
37-
contentStatus?: ReadonlyDeep<PieceContentStatusObj>
3835
}
3936

4037
export interface AdlibSegmentUi extends DBSegment {

meteor/client/lib/ui/pieceUiClassNames.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ import { PieceStatusCode } from '@sofie-automation/corelib/dist/dataModel/Piece'
44
import classNames from 'classnames'
55
import { PieceUi } from '../../ui/SegmentContainer/withResolvedSegment'
66
import { RundownUtils } from '../rundown'
7+
import { ReadonlyDeep } from 'type-fest'
8+
import { PieceContentStatusObj } from '../../../lib/api/pieceContentStatus'
79

810
export function pieceUiClassNames(
911
pieceInstance: PieceUi,
12+
contentStatus: ReadonlyDeep<PieceContentStatusObj> | undefined,
1013
baseClassName: string,
1114
layerType?: SourceLayerType,
1215
partId?: PartId,
@@ -42,12 +45,12 @@ export function pieceUiClassNames(
4245
'next-is-touching': pieceInstance.cropped,
4346

4447
'source-missing':
45-
pieceInstance.contentStatus?.status === PieceStatusCode.SOURCE_MISSING ||
46-
pieceInstance.contentStatus?.status === PieceStatusCode.SOURCE_NOT_SET,
47-
'source-unknown-state': pieceInstance.contentStatus?.status === PieceStatusCode.SOURCE_UNKNOWN_STATE,
48-
'source-broken': pieceInstance.contentStatus?.status === PieceStatusCode.SOURCE_BROKEN,
49-
'source-not-ready': pieceInstance.contentStatus?.status === PieceStatusCode.SOURCE_NOT_READY,
50-
'unknown-state': pieceInstance.contentStatus?.status === PieceStatusCode.UNKNOWN,
48+
contentStatus?.status === PieceStatusCode.SOURCE_MISSING ||
49+
contentStatus?.status === PieceStatusCode.SOURCE_NOT_SET,
50+
'source-unknown-state': contentStatus?.status === PieceStatusCode.SOURCE_UNKNOWN_STATE,
51+
'source-broken': contentStatus?.status === PieceStatusCode.SOURCE_BROKEN,
52+
'source-not-ready': contentStatus?.status === PieceStatusCode.SOURCE_NOT_READY,
53+
'unknown-state': contentStatus?.status === PieceStatusCode.UNKNOWN,
5154
disabled: pieceInstance.instance.disabled,
5255

5356
'invert-flash': highlight,

meteor/client/ui/SegmentContainer/PieceElement.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { ISourceLayer } from '@sofie-automation/blueprints-integration'
33
import { PieceExtended } from '../../lib/RundownResolver'
44
import { pieceUiClassNames } from '../../lib/ui/pieceUiClassNames'
55
import { PartId } from '@sofie-automation/corelib/dist/dataModel/Ids'
6+
import { useContentStatusForItem } from '../SegmentTimeline/withMediaObjectStatus'
67

78
interface IProps {
89
className: string
@@ -36,9 +37,20 @@ export const PieceElement = React.forwardRef<HTMLDivElement, React.PropsWithChil
3637
}: React.PropsWithChildren<IProps>,
3738
ref
3839
) {
40+
const contentStatus = useContentStatusForItem(piece)
41+
3942
return (
4043
<div
41-
className={pieceUiClassNames(piece, className, layer?.type, partId, highlight, undefined, undefined)}
44+
className={pieceUiClassNames(
45+
piece,
46+
contentStatus,
47+
className,
48+
layer?.type,
49+
partId,
50+
highlight,
51+
undefined,
52+
undefined
53+
)}
4254
data-obj-id={piece.instance._id}
4355
onPointerEnter={onPointerEnter}
4456
onPointerLeave={onPointerLeave}

meteor/client/ui/SegmentContainer/withResolvedSegment.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ import {
3535
} from '@sofie-automation/corelib/dist/dataModel/Ids'
3636
import { PieceInstances, Segments } from '../../collections'
3737
import { RundownPlaylistCollectionUtil } from '../../../lib/collections/rundownPlaylistUtil'
38-
import { ReadonlyDeep } from 'type-fest'
39-
import { PieceContentStatusObj } from '../../../lib/api/pieceContentStatus'
4038
import { SegmentOrphanedReason } from '@sofie-automation/corelib/dist/dataModel/Segment'
4139

4240
export interface SegmentUi extends SegmentExtended {
@@ -58,8 +56,6 @@ export type ISourceLayerUi = ISourceLayerExtended
5856
export interface PieceUi extends PieceExtended {
5957
/** This item has already been linked to the parent item of the spanning item group */
6058
linked?: boolean
61-
62-
contentStatus?: ReadonlyDeep<PieceContentStatusObj>
6359
}
6460

6561
export type MinimalRundown = Pick<Rundown, '_id' | 'name' | 'timing' | 'showStyleBaseId' | 'endOfRundownIsShowBreak'>

meteor/client/ui/SegmentList/LinePartMainPiece/LinePartMainPiece.tsx

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ import { getElementDocumentOffset, OffsetPosition } from '../../../utils/positio
1313
import { getSplitItems } from '../../SegmentContainer/getSplitItems'
1414
import { PieceElement } from '../../SegmentContainer/PieceElement'
1515
import { getPieceSteps, PieceMultistepChevron } from '../../SegmentContainer/PieceMultistepChevron'
16-
import { PieceUi } from '../../SegmentContainer/withResolvedSegment'
17-
import { withMediaObjectStatus } from '../../SegmentTimeline/withMediaObjectStatus'
16+
import { useContentStatusForPieceInstance } from '../../SegmentTimeline/withMediaObjectStatus'
1817
import { PieceHoverInspector } from '../PieceHoverInspector'
1918

2019
interface IProps {
@@ -52,14 +51,16 @@ function widthInBase(pieceMaxDuration: number, timelineBase: number): number {
5251
}
5352

5453
// TODO: Create useMediaObjectStatus that would set up new subscriptions
55-
export const LinePartMainPiece = withMediaObjectStatus<IProps, {}>()(function LinePartMainPiece({
54+
export function LinePartMainPiece({
5655
partId,
5756
piece,
5857
partDuration,
5958
timelineBase,
6059
capToPartDuration,
6160
studio,
62-
}) {
61+
}: IProps): JSX.Element {
62+
const contentStatus = useContentStatusForPieceInstance(piece.instance)
63+
6364
const [hover, setHover] = useState(false)
6465
const [origin, setOrigin] = useState<OffsetPosition>({ left: 0, top: 0 })
6566
const [width, setWidth] = useState(0)
@@ -75,15 +76,13 @@ export const LinePartMainPiece = withMediaObjectStatus<IProps, {}>()(function Li
7576
}
7677
}, [pieceMaxDuration, timelineBase])
7778

78-
const pieceUi = piece as PieceUi
79-
8079
const seek = (piece.instance.piece.content as any).seek ?? 0
8180

8281
const anomalies = useMemo(
8382
() => (
8483
<>
85-
{pieceUi.contentStatus?.scenes &&
86-
pieceUi.contentStatus?.scenes.map(
84+
{contentStatus?.scenes &&
85+
contentStatus?.scenes.map(
8786
(i) =>
8887
i < pieceMaxDuration &&
8988
i - seek >= 0 && (
@@ -94,8 +93,8 @@ export const LinePartMainPiece = withMediaObjectStatus<IProps, {}>()(function Li
9493
></span>
9594
)
9695
)}
97-
{pieceUi.contentStatus?.freezes &&
98-
pieceUi.contentStatus?.freezes.map(
96+
{contentStatus?.freezes &&
97+
contentStatus?.freezes.map(
9998
(i) =>
10099
i.start < pieceMaxDuration &&
101100
i.start - seek >= 0 && (
@@ -109,8 +108,8 @@ export const LinePartMainPiece = withMediaObjectStatus<IProps, {}>()(function Li
109108
></span>
110109
)
111110
)}
112-
{pieceUi.contentStatus?.blacks &&
113-
pieceUi.contentStatus?.blacks.map(
111+
{contentStatus?.blacks &&
112+
contentStatus?.blacks.map(
114113
(i) =>
115114
i.start < pieceMaxDuration &&
116115
i.start - seek >= 0 && (
@@ -126,7 +125,7 @@ export const LinePartMainPiece = withMediaObjectStatus<IProps, {}>()(function Li
126125
)}
127126
</>
128127
),
129-
[pieceUi.contentStatus?.blacks, pieceUi.contentStatus?.freezes, pieceUi.contentStatus?.scenes]
128+
[contentStatus?.blacks, contentStatus?.freezes, contentStatus?.scenes]
130129
)
131130

132131
const onPointerEnter = (e: React.PointerEvent<HTMLDivElement>) => {
@@ -161,7 +160,7 @@ export const LinePartMainPiece = withMediaObjectStatus<IProps, {}>()(function Li
161160
setMousePosition(e.pageX - origin.left)
162161
}
163162

164-
const noticeLevel = getNoticeLevelForPieceStatus(piece.contentStatus?.status)
163+
const noticeLevel = getNoticeLevelForPieceStatus(contentStatus?.status)
165164

166165
const hasStepChevron = getPieceSteps(piece)
167166

@@ -205,6 +204,7 @@ export const LinePartMainPiece = withMediaObjectStatus<IProps, {}>()(function Li
205204
hoverScrubTimePosition={mouseTimePosition * (piece.instance.piece.content.sourceDuration || 0)}
206205
hovering={hover}
207206
pieceInstance={piece}
207+
contentStatus={contentStatus}
208208
layer={piece.sourceLayer}
209209
originPosition={origin}
210210
mousePosition={mousePosition}
@@ -213,7 +213,7 @@ export const LinePartMainPiece = withMediaObjectStatus<IProps, {}>()(function Li
213213
)}
214214
</PieceElement>
215215
)
216-
})
216+
}
217217

218218
const ColoredMark = React.memo(function ColoredMark({ color }: { color: string | undefined }) {
219219
if (!color) return null

meteor/client/ui/SegmentList/LinePartPieceIndicator/LinePartIndicator.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { ISourceLayerExtended } from '../../../lib/RundownResolver'
55
import { RundownUtils } from '../../../lib/rundown'
66
import { AdLibPieceUi } from '../../../lib/shelf'
77
import { PieceUi } from '../../SegmentContainer/withResolvedSegment'
8-
import { withMediaObjectStatus } from '../../SegmentTimeline/withMediaObjectStatus'
98

109
interface IProps {
1110
overlay?: (ref: HTMLDivElement | null, setIsOver: (isOver: boolean) => void) => React.ReactNode
@@ -20,7 +19,7 @@ interface IProps {
2019
onDoubleClick?: React.EventHandler<React.MouseEvent<HTMLDivElement>>
2120
}
2221

23-
export const LinePartIndicator = withMediaObjectStatus<IProps, {}>()(function LinePartIndicator({
22+
export function LinePartIndicator({
2423
overlay,
2524
count,
2625
allSourceLayers,
@@ -29,7 +28,7 @@ export const LinePartIndicator = withMediaObjectStatus<IProps, {}>()(function Li
2928
label,
3029
onClick: onClickExternal,
3130
onDoubleClick,
32-
}) {
31+
}: IProps): JSX.Element {
3332
let typeClass = thisSourceLayer?.type ? RundownUtils.getSourceLayerClassName(thisSourceLayer.type) : undefined
3433
const [element, setElement] = useState<HTMLDivElement | null>(null)
3534
const [isMenuOpen, setIsMenuOpen] = useState(false)
@@ -98,4 +97,4 @@ export const LinePartIndicator = withMediaObjectStatus<IProps, {}>()(function Li
9897
{isMenuOpen && !!overlay && overlay(element, setIsMenuOpen)}
9998
</>
10099
)
101-
})
100+
}

meteor/client/ui/SegmentList/LinePartSecondaryPiece/LinePartSecondaryPiece.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { PieceHoverInspector } from '../PieceHoverInspector'
66
import { getElementDocumentOffset, OffsetPosition } from '../../../utils/positions'
77
import { PieceUi } from '../../SegmentContainer/withResolvedSegment'
88
import StudioContext from '../../RundownView/StudioContext'
9+
import { useContentStatusForPieceInstance } from '../../SegmentTimeline/withMediaObjectStatus'
910

1011
interface IProps {
1112
piece: PieceExtended
@@ -28,6 +29,8 @@ export const LinePartSecondaryPiece: React.FC<IProps> = React.memo(function Line
2829
onClick: incomingOnClick,
2930
onDoubleClick: incomingOnDoubleClick,
3031
}) {
32+
const contentStatus = useContentStatusForPieceInstance(piece.instance)
33+
3134
const pieceEl = useRef<HTMLDivElement>(null)
3235
const [hovering, setHover] = useState(false)
3336
const [origin, setOrigin] = useState<OffsetPosition>({ left: 0, top: 0 })
@@ -109,6 +112,7 @@ export const LinePartSecondaryPiece: React.FC<IProps> = React.memo(function Line
109112
mousePosition={mousePosition}
110113
originPosition={origin}
111114
pieceInstance={piece}
115+
contentStatus={contentStatus}
112116
studio={studio}
113117
/>
114118
)

meteor/client/ui/SegmentList/PieceHoverInspector.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@ import { FloatingInspector } from '../FloatingInspector'
1515
import { L3rdFloatingInspector } from '../FloatingInspectors/L3rdFloatingInspector'
1616
import { VTFloatingInspector } from '../FloatingInspectors/VTFloatingInspector'
1717
import { PieceUi } from '../SegmentContainer/withResolvedSegment'
18+
import { ReadonlyDeep } from 'type-fest'
19+
import { PieceContentStatusObj } from '../../../lib/api/pieceContentStatus'
1820

1921
export function PieceHoverInspector({
2022
studio,
2123
pieceInstance,
24+
contentStatus,
2225
hovering,
2326
hoverScrubTimePosition,
2427
originPosition,
@@ -27,19 +30,18 @@ export function PieceHoverInspector({
2730
}: Readonly<{
2831
studio: UIStudio
2932
pieceInstance: PieceUi
33+
contentStatus: ReadonlyDeep<PieceContentStatusObj> | undefined
3034
hovering: boolean
3135
hoverScrubTimePosition: number
3236
originPosition: OffsetPosition
3337
mousePosition: number
3438
layer: ISourceLayer | undefined
3539
}>): JSX.Element | null {
36-
const status = pieceInstance.contentStatus?.status
37-
3840
const vtContent = pieceInstance.instance.piece.content as VTContent
3941
const graphicsContent = pieceInstance.instance.piece.content as GraphicsContent
4042
const transitionContent = pieceInstance.instance.piece.content as TransitionContent
4143

42-
const noticeLevel = getNoticeLevelForPieceStatus(status)
44+
const noticeLevel = getNoticeLevelForPieceStatus(contentStatus?.status)
4345

4446
switch (layer?.type) {
4547
case SourceLayerType.TRANSITION:
@@ -85,7 +87,7 @@ export function PieceHoverInspector({
8587
case SourceLayerType.LIVE_SPEAK:
8688
return (
8789
<VTFloatingInspector
88-
status={status ?? PieceStatusCode.UNKNOWN}
90+
status={contentStatus?.status ?? PieceStatusCode.UNKNOWN}
8991
showMiniInspector={hovering}
9092
timePosition={hoverScrubTimePosition}
9193
content={vtContent}
@@ -97,10 +99,10 @@ export function PieceHoverInspector({
9799
}}
98100
typeClass={layer && RundownUtils.getSourceLayerClassName(layer.type)}
99101
itemElement={null}
100-
noticeMessages={pieceInstance.contentStatus?.messages ?? null}
102+
noticeMessages={contentStatus?.messages ?? null}
101103
noticeLevel={noticeLevel}
102104
studio={studio}
103-
previewUrl={pieceInstance.contentStatus?.previewUrl}
105+
previewUrl={contentStatus?.previewUrl}
104106
/>
105107
)
106108
}

meteor/client/ui/SegmentStoryboard/StoryboardPartSecondaryPieces/Renderers/VTRenderer.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { IDefaultRendererProps } from './DefaultRenderer'
55
import { getNoticeLevelForPieceStatus } from '../../../../../lib/notifications/notifications'
66
import { PieceStatusCode } from '@sofie-automation/corelib/dist/dataModel/Piece'
77
import { LoopingPieceIcon } from '../../../../lib/ui/icons/looping'
8+
import { useContentStatusForPieceInstance } from '../../../SegmentTimeline/withMediaObjectStatus'
89

910
export function VTRenderer({
1011
piece: pieceInstance,
@@ -13,7 +14,7 @@ export function VTRenderer({
1314
studio,
1415
typeClass,
1516
}: Readonly<IDefaultRendererProps>): JSX.Element {
16-
const status = pieceInstance.contentStatus?.status
17+
const contentStatus = useContentStatusForPieceInstance(pieceInstance.instance)
1718

1819
const vtContent = pieceInstance.instance.piece.content as VTContent
1920

@@ -22,7 +23,7 @@ export function VTRenderer({
2223
return (
2324
<>
2425
<VTFloatingInspector
25-
status={status || PieceStatusCode.UNKNOWN}
26+
status={contentStatus?.status || PieceStatusCode.UNKNOWN}
2627
showMiniInspector={!!hovering}
2728
timePosition={timePosition}
2829
content={vtContent}
@@ -34,10 +35,10 @@ export function VTRenderer({
3435
}}
3536
typeClass={typeClass}
3637
itemElement={null}
37-
noticeMessages={pieceInstance.contentStatus?.messages || null}
38-
noticeLevel={getNoticeLevelForPieceStatus(status)}
38+
noticeMessages={contentStatus?.messages || null}
39+
noticeLevel={getNoticeLevelForPieceStatus(contentStatus?.status)}
3940
studio={studio}
40-
previewUrl={pieceInstance.contentStatus?.previewUrl}
41+
previewUrl={contentStatus?.previewUrl}
4142
/>
4243
{pieceInstance.instance.piece.name}
4344
{pieceInstance.instance.piece.content?.loop && (

0 commit comments

Comments
 (0)