Skip to content

Commit 59aff41

Browse files
authored
Merge pull request Sofie-Automation#1717 from bbc/justandras/t-timers/prompter-view
feat: t-timers prompter view
2 parents ffcb722 + 1d3c321 commit 59aff41

22 files changed

Lines changed: 477 additions & 473 deletions

packages/webui/src/client/collections/lib.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
PeripheralDevicePubSubCollections,
1111
PeripheralDevicePubSubCollectionsNames,
1212
} from '@sofie-automation/shared-lib/dist/pubsub/peripheralDevice'
13-
import {
13+
import type {
1414
MongoCollection,
1515
MongoReadOnlyCollection,
1616
MongoCursor,
@@ -22,7 +22,20 @@ import {
2222
import { CustomCollectionName as CustomCorelibCollectionName } from '@sofie-automation/corelib/dist/dataModel/Collections'
2323
import { CorelibPubSubCustomCollections } from '@sofie-automation/corelib/dist/pubsub'
2424

25-
export * from '@sofie-automation/meteor-lib/dist/collections/lib'
25+
export type {
26+
FieldNames,
27+
FindOneOptions,
28+
FindOptions,
29+
IndexSpecifier,
30+
MongoCollection,
31+
MongoCursor,
32+
MongoLiveQueryHandle,
33+
MongoReadOnlyCollection,
34+
ObserveCallbacks,
35+
ObserveChangesCallbacks,
36+
UpdateOptions,
37+
UpsertOptions,
38+
} from '@sofie-automation/meteor-lib/dist/collections/lib'
2639

2740
export const ClientCollections = new Map<CollectionName, MongoCollection<any> | WrappedMongoReadOnlyCollection<any>>()
2841
function registerClientCollection(
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
@import '../../styles/colorScheme';
2+
3+
.over-under-chip {
4+
font-family: Roboto Flex;
5+
display: inline-block;
6+
border-radius: 999px;
7+
white-space: nowrap;
8+
letter-spacing: -0.02em;
9+
font-variant-numeric: tabular-nums;
10+
color: #000;
11+
12+
padding: var(--overUnderChipPaddingY, 0.05em) var(--overUnderChipPaddingX, 0.25em);
13+
margin-left: var(--overUnderChipMarginLeft, 0em);
14+
margin-top: var(--overUnderChipMarginTop, 0em);
15+
line-height: var(--overUnderChipLineHeight, 1);
16+
17+
font-variation-settings:
18+
'wdth' var(--overUnderChipWdth, 25),
19+
'wght' var(--overUnderChipWght, 600),
20+
'slnt' var(--overUnderChipSlnt, 0),
21+
'GRAD' var(--overUnderChipGrad, 0),
22+
'opsz' var(--overUnderChipOpsz, 14),
23+
'XOPQ' var(--overUnderChipXopq, 96),
24+
'XTRA' var(--overUnderChipXtra, 468),
25+
'YOPQ' var(--overUnderChipYopq, 79),
26+
'YTAS' var(--overUnderChipYtas, 750),
27+
'YTFI' var(--overUnderChipYtfi, 738),
28+
'YTLC' var(--overUnderChipYtlc, 548),
29+
'YTDE' var(--overUnderChipYtde, -203),
30+
'YTUC' var(--overUnderChipYtuc, 712);
31+
32+
&.over-under-chip--over {
33+
--overUnderChipWght: 700;
34+
background-color: $general-late-color;
35+
}
36+
37+
&.over-under-chip--under {
38+
--overUnderChipWght: 500;
39+
background-color: #ff0; // Should probably be changed to $general-fast-color;
40+
}
41+
}
42+
43+
// Optional preset for when the chip is used as a large screen overlay.
44+
.over-under-chip--overlay {
45+
--overUnderChipWght: 700;
46+
--overUnderChipOpsz: 20;
47+
--overUnderChipYopq: 92;
48+
--overUnderChipYtlc: 514;
49+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { type CSSProperties } from 'react'
2+
import classNames from 'classnames'
3+
import { RundownUtils } from '../rundown.js'
4+
import './OverUnderChip.scss'
5+
import { useTiming } from '../../ui/RundownView/RundownTiming/withTiming.js'
6+
import { getPlaylistTimingDiff } from '../rundownTiming.js'
7+
import { DBRundownPlaylist } from '@sofie-automation/corelib/src/dataModel/RundownPlaylist/RundownPlaylist.js'
8+
9+
export type OverUnderChipFormat = 'playlistDiff' | 'timerPostfix'
10+
11+
type OverUnderChipBaseProps = {
12+
className?: string
13+
style?: CSSProperties
14+
format?: OverUnderChipFormat
15+
}
16+
17+
type OverUnderChipValueProps =
18+
| {
19+
valueMs: number | undefined
20+
rundownPlaylist?: never
21+
}
22+
| {
23+
valueMs?: never
24+
rundownPlaylist: DBRundownPlaylist
25+
}
26+
27+
type OverUnderChipInnerProps = OverUnderChipBaseProps & { valueMs: number | undefined }
28+
29+
/**
30+
* Over/under "chip" display.
31+
* Can either take a direct `valueMs` or a `rundownPlaylist` (requires RundownTiming context).
32+
*/
33+
export function OverUnderChip(props: Readonly<OverUnderChipBaseProps & OverUnderChipValueProps>): JSX.Element | null {
34+
if ('valueMs' in props) {
35+
return <OverUnderChipInner {...props} valueMs={props.valueMs} />
36+
} else {
37+
return <OverUnderChipFromPlaylist {...props} rundownPlaylist={props.rundownPlaylist} />
38+
}
39+
}
40+
41+
function OverUnderChipFromPlaylist(
42+
props: Readonly<OverUnderChipBaseProps & { rundownPlaylist: DBRundownPlaylist }>
43+
): JSX.Element | null {
44+
const timingDurations = useTiming()
45+
const valueMs = getPlaylistTimingDiff(props.rundownPlaylist, timingDurations)
46+
return <OverUnderChipInner {...props} valueMs={valueMs} />
47+
}
48+
49+
function OverUnderChipInner({ valueMs, format = 'playlistDiff', className, style }: Readonly<OverUnderChipInnerProps>) {
50+
if (valueMs === undefined) return null
51+
52+
const isUnder = valueMs <= 0
53+
const timeStr = (() => {
54+
switch (format) {
55+
case 'timerPostfix':
56+
return RundownUtils.formatDiffToTimecode(Math.abs(valueMs), false, false, true, false, true)
57+
case 'playlistDiff':
58+
default:
59+
return RundownUtils.formatDiffToTimecode(Math.abs(valueMs), false, false, true, true, true)
60+
}
61+
})()
62+
63+
return (
64+
<span
65+
className={classNames('over-under-chip', isUnder ? 'over-under-chip--under' : 'over-under-chip--over', className)}
66+
style={style}
67+
>
68+
{isUnder ? '−' : '+'}
69+
{timeStr}
70+
</span>
71+
)
72+
}

packages/webui/src/client/styles/_colorScheme.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ $general-live-remote-color: var(--general-live-remote-color);
1919
$general-live-guest-color: var(--general-live-guest-color);
2020

2121
$general-late-color: var(--general-late-color);
22+
$over-under-over-color: var(--over-under-over-color);
2223
$general-fast-color: var(--general-fast-color);
2324
$general-fast-color--shadow: var(--general-fast-color--shadow);
2425
$general-countdown-to-next-color: var(--general-countdown-to-next-color);

packages/webui/src/client/styles/countdown/director.scss

Lines changed: 23 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ $hold-status-color: $liveline-timecode-color;
1717
font-family: Roboto Flex;
1818
font-style: normal;
1919

20+
// Over/under timer overlay (reuses `screen-timing-clock` from prompter view)
21+
// Ensure it layers above the fixed top bar.
22+
.screen-timing-clock {
23+
z-index: 2000;
24+
font-size: 9vmin;
25+
}
26+
2027
.director-screen__top {
2128
position: fixed;
2229
top: 0;
@@ -35,24 +42,19 @@ $hold-status-color: $liveline-timecode-color;
3542
padding: 0 0.2em;
3643
text-transform: uppercase;
3744

38-
.director-screen__top__planned-end {
39-
text-align: left;
45+
.director-screen__top__spacer {
46+
flex-grow: 4;
4047
}
4148

42-
.director-screen__top__time-to {
43-
text-align: center;
49+
.director-screen__top__planned-end {
50+
flex-grow: 2;
51+
text-align: left;
4452
}
4553

54+
.director-screen__top__center,
4655
.director-screen__top__planned-to {
4756
text-align: center;
4857
}
49-
.director-screen__top__planned-since {
50-
margin-left: -50px;
51-
}
52-
53-
.director-screen__top__over-under {
54-
margin-left: 5vw;
55-
}
5658
}
5759

5860
.director-screen__body {
@@ -208,14 +210,14 @@ $hold-status-color: $liveline-timecode-color;
208210
text-align: center;
209211
width: 100vw;
210212
margin-left: -13vw;
211-
213+
212214
.director-screen__body__part__timeto-name {
213215
color: #888;
214216
font-size: 9.63em;
215217
text-transform: uppercase;
216218
margin-top: -2vh;
217219
}
218-
220+
219221
.director-screen__body__part__timeto-countdown {
220222
margin-top: 4vh;
221223
grid-row: inherit;
@@ -480,75 +482,13 @@ $hold-status-color: $liveline-timecode-color;
480482
.clocks-counter-heavy {
481483
font-weight: 600;
482484
}
483-
484-
.director-screen__body__t-timer {
485-
position: absolute;
486-
bottom: 0;
487-
right: 0;
488-
text-align: right;
489-
font-size: 5vh;
490-
z-index: 10;
491-
line-height: 1;
492-
493-
.t-timer-display {
494-
display: flex;
495-
align-items: stretch;
496-
justify-content: flex-end;
497-
font-weight: 500;
498-
background: #333;
499-
border-radius: 0;
500-
overflow: hidden;
501-
502-
&__label {
503-
display: flex;
504-
align-items: center;
505-
color: #fff;
506-
padding-left: 0.4em;
507-
padding-right: 0.2em;
508-
font-size: 1em;
509-
text-transform: uppercase;
510-
letter-spacing: 0.05em;
511-
font-stretch: condensed;
512-
}
513-
514-
&__value {
515-
display: flex;
516-
align-items: center;
517-
color: #fff;
518-
font-variant-numeric: tabular-nums;
519-
padding: 0 0.2em;
520-
font-size: 1em;
521-
522-
.t-timer-display__part {
523-
&--dimmed {
524-
color: #aaa;
525-
}
526-
}
527-
}
528-
529-
&__over-under {
530-
display: flex;
531-
align-items: center;
532-
justify-content: center;
533-
margin: 0 0 0 0.2em;
534-
font-size: 1em;
535-
font-variant-numeric: tabular-nums;
536-
padding: 0 0.4em;
537-
line-height: 1.1;
538-
min-width: 3.5em;
539-
border-radius: 1em;
540-
541-
&--over {
542-
background-color: $general-late-color;
543-
color: #fff;
544-
}
545-
546-
&--under {
547-
background-color: #ffe900;
548-
color: #000;
549-
}
550-
}
551-
}
552-
}
485+
}
486+
.director-screen__bottom-bar {
487+
position: fixed;
488+
left: 0;
489+
right: 0;
490+
bottom: 0;
491+
z-index: 20;
492+
font-size: 4.58vh;
553493
}
554494
}

0 commit comments

Comments
 (0)