diff --git a/apps/client/src/features/operator/Operator.tsx b/apps/client/src/features/operator/Operator.tsx index 93a707d53..91b210382 100644 --- a/apps/client/src/features/operator/Operator.tsx +++ b/apps/client/src/features/operator/Operator.tsx @@ -9,6 +9,7 @@ import { getOperatorOptions } from '../../common/components/view-params-editor/c import ViewParamsEditor from '../../common/components/view-params-editor/ViewParamsEditor'; import useFollowComponent from '../../common/hooks/useFollowComponent'; import { useOperator } from '../../common/hooks/useSocket'; +import useEventData from '../../common/hooks-query/useEventData'; import useRundown from '../../common/hooks-query/useRundown'; import useUserFields from '../../common/hooks-query/useUserFields'; import { isStringBoolean } from '../../common/utils/viewUtils'; @@ -25,6 +26,8 @@ const selectedOffset = 50; export default function Operator() { const { data, status } = useRundown(); const { data: userFields, status: userFieldsStatus } = useUserFields(); + const { data: projectData, status: projectDataStatus } = useEventData(); + const featureData = useOperator(); const [searchParams] = useSearchParams(); @@ -69,7 +72,14 @@ export default function Operator() { } }; - if (!data || status === 'loading' || !userFields || userFieldsStatus === 'loading') { + if ( + !data || + status === 'loading' || + !userFields || + userFieldsStatus === 'loading' || + !projectData || + projectDataStatus === 'loading' + ) { return ; } @@ -77,12 +87,14 @@ export default function Operator() { const subscribe = searchParams.get('subscribe') as keyof UserFields | null; const subscribedAlias = subscribe ? userFields[subscribe] : ''; const showSeconds = isStringBoolean(searchParams.get('showseconds')); - const lastEvent = getLastEvent(data); const operatorOptions = getOperatorOptions(userFields); let isPast = Boolean(featureData.selectedEventId); const hidePast = isStringBoolean(searchParams.get('hidepast')); + const firstEvent = getLastEvent(data); + const lastEvent = getLastEvent(data); + return (
@@ -124,7 +136,15 @@ export default function Operator() {
- +
); } diff --git a/apps/client/src/features/operator/status-bar/StatusBar.module.scss b/apps/client/src/features/operator/status-bar/StatusBar.module.scss index 7eb5f072a..d17ee2a62 100644 --- a/apps/client/src/features/operator/status-bar/StatusBar.module.scss +++ b/apps/client/src/features/operator/status-bar/StatusBar.module.scss @@ -1,6 +1,13 @@ @use '../../../../src/theme/ontimeColours' as *; @use '../../../../src/theme/v2Styles' as *; +@mixin column { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; +} + .statusBar { position: absolute; bottom: 0; @@ -9,28 +16,55 @@ z-index: 2; padding: 0.5rem 1rem; - display: flex; - justify-content: space-between; - align-items: center; border-top: 1px solid $white-10; box-shadow: $large-bottom-drawer-shadow; + + display: grid; + grid-template-areas: + "playback timer1B timer2B timer3B"; + grid-template-columns: 1fr auto auto auto; + column-gap: 1.5rem; + align-items: center; } .playbackIcon { + grid-area: playback; font-size: 2rem; color: $gray-700; } -.column { - display: flex; - flex-direction: column; - align-items: center; - text-align: center; +.timeNow { + grid-area: timer1B; + @include column; } -.clock { - display: flex; - gap: 1.5rem; +.elapsedTime { + grid-area: timer2B; + @include column; +} + +.runningTime { + grid-area: timer3B; + @include column; +} + +.title { + grid-area: title; + font-size: 1.5rem; + padding-left: 0.5rem; + display: none; +} + +.startTime { + grid-area: timer2A; + @include column; + display: none; +} + +.endTime { + grid-area: timer3A; + @include column; + display: none; } .label { @@ -44,8 +78,23 @@ // tablet @media (min-width: $min-tablet) { - .clock { + .statusBar { + grid-template-areas: + "playback timer1B timer2B timer3B" + "title timer1A timer2A timer3A"; + row-gap: 0.25rem; + column-gap: 2rem; + } + + .title { + display: block; + } + + .startTime { + display: flex; + } + + .endTime { display: flex; - gap: 1.5rem; } } diff --git a/apps/client/src/features/operator/status-bar/StatusBar.tsx b/apps/client/src/features/operator/status-bar/StatusBar.tsx index 0b6919a97..dc29e2817 100644 --- a/apps/client/src/features/operator/status-bar/StatusBar.tsx +++ b/apps/client/src/features/operator/status-bar/StatusBar.tsx @@ -1,33 +1,52 @@ import { useMemo } from 'react'; -import { OntimeEvent, Playback } from 'ontime-types'; +import { Playback } from 'ontime-types'; import { millisToString } from 'ontime-utils'; import PlaybackIcon from '../../../common/components/playback-icon/PlaybackIcon'; -import useMediaQuery from '../../../common/context/useMediaQuery'; import { useTimer } from '../../../common/hooks/useSocket'; import { formatTime } from '../../../common/utils/time'; import styles from './StatusBar.module.scss'; -export default function StatusBar({ - playback, - lastEvent, - selectedEventId, -}: { +interface StatusBarProps { + projectTitle: string; playback: Playback; - lastEvent: OntimeEvent | null; selectedEventId: string | null; -}) { - const timer = useTimer(); - const isMobile = useMediaQuery('(max-width: 450px)'); + firstStart?: number; + firstId?: string; + lastEnd?: number; + lastId?: string; +} - const getTimeEnd = () => { - if (lastEvent === null) { +export default function StatusBar(props: StatusBarProps) { + const { projectTitle, playback, selectedEventId, firstStart, firstId, lastEnd, lastId } = props; + + const timer = useTimer(); + + const getTimeStart = () => { + if (firstStart === undefined) { return '...'; } - const timeEnd = lastEvent.id === selectedEventId ? timer.expectedFinish : lastEvent.timeEnd; - return millisToString(timeEnd); + if (selectedEventId) { + if (firstId === selectedEventId) { + return millisToString(timer.expectedFinish); + } + } + return millisToString(firstStart); + }; + + const getTimeEnd = () => { + if (lastEnd === undefined) { + return '...'; + } + + if (selectedEventId) { + if (lastId === selectedEventId) { + return millisToString(timer.expectedFinish); + } + } + return millisToString(lastEnd); }; // use user defined format @@ -44,26 +63,28 @@ export default function StatusBar({ return (
+ {projectTitle} +
+ Scheduled start + {getTimeStart()} +
+
+ Scheduled end + {getTimeEnd()} +
+ {PlaybackIconComponent} -
-
- Time now - {timeNow} -
- {!isMobile && ( -
- Last end - {getTimeEnd()} -
- )} -
- Elapsed time - {elapsedTime} -
-
- Running timer - {runningTime} -
+
+ Time now + {timeNow} +
+
+ Elapsed time + {elapsedTime} +
+
+ Running timer + {runningTime}
);