diff --git a/apps/client/src/features/viewers/studio/StudioClock.scss b/apps/client/src/features/viewers/studio/StudioClock.scss
index 6e239f915..e9862882d 100644
--- a/apps/client/src/features/viewers/studio/StudioClock.scss
+++ b/apps/client/src/features/viewers/studio/StudioClock.scss
@@ -42,6 +42,11 @@ $orange-active: #f60;
grid-template-areas: 'clock schedule';
text-transform: uppercase;
+ &.hide-right {
+ grid-template-columns: 1fr;
+ grid-template-areas: 'clock';
+ }
+
.clock-container {
grid-area: clock;
display: grid;
diff --git a/apps/client/src/features/viewers/studio/StudioClock.tsx b/apps/client/src/features/viewers/studio/StudioClock.tsx
index b3be821dc..7a435b579 100644
--- a/apps/client/src/features/viewers/studio/StudioClock.tsx
+++ b/apps/client/src/features/viewers/studio/StudioClock.tsx
@@ -1,7 +1,7 @@
import { useSearchParams } from 'react-router-dom';
-import type { OntimeEvent, OntimeRundown, Settings, ViewSettings } from 'ontime-types';
-import { isOntimeEvent, Playback } from 'ontime-types';
-import { millisToString, removeSeconds } from 'ontime-utils';
+import type { MaybeString, OntimeEvent, OntimeRundown, Settings, ViewSettings } from 'ontime-types';
+import { Playback } from 'ontime-types';
+import { millisToString, removeSeconds, secondsInMillis } from 'ontime-utils';
import { overrideStylesURL } from '../../../common/api/constants';
import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
@@ -10,11 +10,10 @@ import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet
import { useWindowTitle } from '../../../common/hooks/useWindowTitle';
import { ViewExtendedTimer } from '../../../common/models/TimeManager.type';
import { formatTime, getDefaultFormat } from '../../../common/utils/time';
-import SuperscriptTime from '../common/superscript-time/SuperscriptTime';
import { isStringBoolean } from '../common/viewUtils';
import { getStudioClockOptions } from './studioClock.options';
-import { secondsInMillis, trimRundown } from './studioClock.utils';
+import StudioClockSchedule from './StudioClockSchedule';
import './StudioClock.scss';
@@ -23,8 +22,8 @@ interface StudioClockProps {
eventNext: OntimeEvent | null;
time: ViewExtendedTimer;
backstageEvents: OntimeRundown;
- selectedId: string | null;
- nextId: string | null;
+ selectedId: MaybeString;
+ nextId: MaybeString;
onAir: boolean;
viewSettings: ViewSettings;
settings: Settings | undefined;
@@ -38,16 +37,13 @@ export default function StudioClock(props: StudioClockProps) {
useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL);
const { fontSize: titleFontSize, ref: titleRef } = useFitText({ minFontSize: 150, maxFontSize: 500 });
- const activeIndicators = [...Array(12).keys()];
- const secondsIndicators = [...Array(60).keys()];
-
- // TODO: fit titles on screen
- const MAX_TITLES = 11;
-
const [searchParams] = useSearchParams();
useWindowTitle('Studio Clock');
+ const activeIndicators = [...Array(12).keys()];
+ const secondsIndicators = [...Array(60).keys()];
+
let clock = formatTime(time.clock);
let hasAmPm = '';
if (clock.includes('AM')) {
@@ -65,8 +61,7 @@ export default function StudioClock(props: StudioClockProps) {
const defaultFormat = getDefaultFormat(settings?.timeFormat);
const studioClockOptions = getStudioClockOptions(defaultFormat);
- const delayed = backstageEvents.filter((event) => isOntimeEvent(event)) as OntimeEvent[];
- const trimmedRundown = trimRundown(delayed, selectedId, MAX_TITLES);
+ const hideRight = isStringBoolean(searchParams.get('hideRight'));
let timer = millisToString(time.current, { fallback: '---' });
const hideSeconds = isStringBoolean(searchParams.get('hideTimerSeconds'));
if (time.current != null && hideSeconds) {
@@ -74,7 +69,10 @@ export default function StudioClock(props: StudioClockProps) {
}
return (
-
+
{hasAmPm &&
{hasAmPm}
}
@@ -114,31 +112,9 @@ export default function StudioClock(props: StudioClockProps) {
))}
-
-
- ON AIR
-
-
- {trimmedRundown.map((event) => {
- const start = formatTime(event.timeStart + (event?.delay ?? 0), { format12: 'h:mm a', format24: 'HH:mm' });
- const isSelected = event.id === selectedId;
- const isNext = event.id === nextId;
- const classes = `schedule__item schedule__item${isSelected ? '--now' : isNext ? '--next' : '--future'}`;
- return (
- -
-
-
-
-
- {event.title}
-
- );
- })}
-
-
+ {!hideRight && (
+
+ )}
);
}
diff --git a/apps/client/src/features/viewers/studio/StudioClockSchedule.tsx b/apps/client/src/features/viewers/studio/StudioClockSchedule.tsx
new file mode 100644
index 000000000..c97f7057b
--- /dev/null
+++ b/apps/client/src/features/viewers/studio/StudioClockSchedule.tsx
@@ -0,0 +1,50 @@
+import { isOntimeEvent, MaybeString, OntimeEvent, OntimeRundown } from 'ontime-types';
+
+import { formatTime } from '../../../common/utils/time';
+import SuperscriptTime from '../common/superscript-time/SuperscriptTime';
+
+import { trimRundown } from './studioClock.utils';
+
+import './StudioClock.scss';
+
+interface StudioClockScheduleProps {
+ rundown: OntimeRundown;
+ selectedId: MaybeString;
+ nextId: MaybeString;
+ onAir: boolean;
+}
+
+// TODO: fit titles on screen
+const MAX_TITLES = 11;
+
+export default function StudioClockSchedule(props: StudioClockScheduleProps) {
+ const { rundown, selectedId, nextId, onAir } = props;
+
+ const delayed = rundown.filter((event) => isOntimeEvent(event)) as OntimeEvent[];
+ const trimmedRundown = trimRundown(delayed, selectedId, MAX_TITLES);
+
+ return (
+
+
+ ON AIR
+
+
+ {trimmedRundown.map((event) => {
+ const start = formatTime(event.timeStart + (event?.delay ?? 0), { format12: 'h:mm a', format24: 'HH:mm' });
+ const isSelected = event.id === selectedId;
+ const isNext = event.id === nextId;
+ const classes = `schedule__item schedule__item${isSelected ? '--now' : isNext ? '--next' : '--future'}`;
+ return (
+ -
+
+
+
+
+ {event.title}
+
+ );
+ })}
+
+
+ );
+}
diff --git a/apps/client/src/features/viewers/studio/__tests__/studioClock.utils.test.ts b/apps/client/src/features/viewers/studio/__tests__/studioClock.utils.test.ts
index e4da735d9..99b6868f4 100644
--- a/apps/client/src/features/viewers/studio/__tests__/studioClock.utils.test.ts
+++ b/apps/client/src/features/viewers/studio/__tests__/studioClock.utils.test.ts
@@ -1,6 +1,6 @@
import { OntimeEvent } from 'ontime-types';
-import { secondsInMillis, trimRundown } from '../studioClock.utils';
+import { trimRundown } from '../studioClock.utils';
describe('test trimEventlist function', () => {
const limit = 8;
@@ -118,14 +118,3 @@ describe('test trimEventlist function', () => {
expect(l).toStrictEqual(expected);
});
});
-
-describe('secondsInMillis()', () => {
- it('return 0 if value is null', () => {
- expect(secondsInMillis(null)).toBe(0);
- });
- it('returns the seconds value of a millis date', () => {
- const date = 1686255053619; // Thu Jun 08 2023 20:10:53
- const seconds = secondsInMillis(date);
- expect(seconds).toBe(53);
- });
-});
\ No newline at end of file
diff --git a/apps/client/src/features/viewers/studio/studioClock.options.ts b/apps/client/src/features/viewers/studio/studioClock.options.ts
index 23ac6c0ac..89bb7170c 100644
--- a/apps/client/src/features/viewers/studio/studioClock.options.ts
+++ b/apps/client/src/features/viewers/studio/studioClock.options.ts
@@ -6,4 +6,12 @@ export const getStudioClockOptions = (timeFormat: string): ViewOption[] => [
getTimeOption(timeFormat),
{ section: 'Timer Options' },
hideTimerSeconds,
+ { section: 'Element visibility' },
+ {
+ id: 'hideRight',
+ title: 'Hide right section',
+ description: 'Hides the right section with On Air indicator and the schedule',
+ type: 'boolean',
+ defaultValue: false,
+ },
];
diff --git a/apps/client/src/features/viewers/studio/studioClock.utils.ts b/apps/client/src/features/viewers/studio/studioClock.utils.ts
index d93a7bfbe..a3d8068b1 100644
--- a/apps/client/src/features/viewers/studio/studioClock.utils.ts
+++ b/apps/client/src/features/viewers/studio/studioClock.utils.ts
@@ -1,5 +1,4 @@
-import { MaybeNumber, OntimeEvent } from 'ontime-types';
-import { MILLIS_PER_MINUTE, MILLIS_PER_SECOND } from 'ontime-utils';
+import { OntimeEvent } from 'ontime-types';
/**
* @description Returns trimmed event list array
@@ -20,15 +19,3 @@ export function trimRundown(rundown: OntimeEvent[], selectedId: string | null, l
const trimmedRundown = rundown.slice(startIndex, endIndex);
return trimmedRundown;
}
-
-/**
- * @description Returns amount of seconds in a date given in milliseconds. For studio clock second indicator
- * @param {MaybeNumber} millis time to format
- * @returns amount of elapsed seconds
- */
-export function secondsInMillis(millis: MaybeNumber): number {
- if (!millis) {
- return 0;
- }
- return Math.floor((millis % MILLIS_PER_MINUTE) / MILLIS_PER_SECOND);
-}
diff --git a/packages/utils/index.ts b/packages/utils/index.ts
index 47fe5d351..7a83511d6 100644
--- a/packages/utils/index.ts
+++ b/packages/utils/index.ts
@@ -42,6 +42,7 @@ export {
millisToHours,
millisToMinutes,
millisToSeconds,
+ secondsInMillis,
} from './src/date-utils/conversionUtils.js';
export { isTimeString } from './src/date-utils/isTimeString.js';
export {
diff --git a/packages/utils/src/date-utils/conversionUtils.test.ts b/packages/utils/src/date-utils/conversionUtils.test.ts
index f78576a4e..5cf99c11d 100644
--- a/packages/utils/src/date-utils/conversionUtils.test.ts
+++ b/packages/utils/src/date-utils/conversionUtils.test.ts
@@ -1,4 +1,4 @@
-import { millisToHours, millisToMinutes, millisToSeconds } from "./conversionUtils";
+import { millisToHours, millisToMinutes, millisToSeconds, secondsInMillis } from './conversionUtils';
describe('millisToSecond()', () => {
test('null values', () => {
@@ -112,3 +112,14 @@ describe('millisToHours()', () => {
expect(millisToHours(t.val)).toBe(t.result);
});
});
+
+describe('secondsInMillis()', () => {
+ it('return 0 if value is null', () => {
+ expect(secondsInMillis(null)).toBe(0);
+ });
+ it('returns the seconds value of a millis date', () => {
+ const date = 1686255053619; // Thu Jun 08 2023 20:10:53
+ const seconds = secondsInMillis(date);
+ expect(seconds).toBe(53);
+ });
+});
diff --git a/packages/utils/src/date-utils/conversionUtils.ts b/packages/utils/src/date-utils/conversionUtils.ts
index 11ca838f9..d245fe1b5 100644
--- a/packages/utils/src/date-utils/conversionUtils.ts
+++ b/packages/utils/src/date-utils/conversionUtils.ts
@@ -64,3 +64,15 @@ export function secondsToMinutes(seconds: number): number {
export function secondsToHours(seconds: number): number {
return Math.floor(seconds / 3600);
}
+
+/**
+ * @description Returns amount of seconds in a date given in milliseconds. For studio clock second indicator
+ * @param {MaybeNumber} millis time to format
+ * @returns amount of elapsed seconds
+ */
+export function secondsInMillis(millis: MaybeNumber): number {
+ if (!millis) {
+ return 0;
+ }
+ return Math.floor((millis % MILLIS_PER_MINUTE) / MILLIS_PER_SECOND);
+}