From a5afb32b8a366aa44ad480d8eb327c2e04088f5b Mon Sep 17 00:00:00 2001 From: Carlos Valente Date: Sun, 16 Feb 2025 22:06:08 +0100 Subject: [PATCH] refactor: show projected time --- apps/client/src/common/hooks/useSocket.ts | 4 + .../src/views/common/schedule/Schedule.scss | 8 ++ .../views/common/schedule/ScheduleItem.tsx | 122 ++++++++++++++---- .../views/common/schedule/schedule.options.ts | 9 ++ 4 files changed, 118 insertions(+), 25 deletions(-) diff --git a/apps/client/src/common/hooks/useSocket.ts b/apps/client/src/common/hooks/useSocket.ts index 6b8c7e19c..741e9f9ef 100644 --- a/apps/client/src/common/hooks/useSocket.ts +++ b/apps/client/src/common/hooks/useSocket.ts @@ -170,6 +170,10 @@ export const useTimelineStatus = createSelector((state: RuntimeStore) => ({ offset: state.runtime.offset, })); +export const useRuntimeOffset = createSelector((state: RuntimeStore) => ({ + offset: state.runtime.offset, +})); + export const usePing = createSelector((state: RuntimeStore) => ({ ping: state.ping, })); diff --git a/apps/client/src/views/common/schedule/Schedule.scss b/apps/client/src/views/common/schedule/Schedule.scss index 0984ddc8e..61ca13327 100644 --- a/apps/client/src/views/common/schedule/Schedule.scss +++ b/apps/client/src/views/common/schedule/Schedule.scss @@ -49,6 +49,14 @@ $indeterminate-width: clamp(32px, 3vw, 48px); &--delay { color: $ontime-delay-text; } + + &--ahead { + color: $green-500; + } + + &--behind { + color: $orange-500; + } } .entry-title { diff --git a/apps/client/src/views/common/schedule/ScheduleItem.tsx b/apps/client/src/views/common/schedule/ScheduleItem.tsx index f2ffb8b2f..b9bc3278b 100644 --- a/apps/client/src/views/common/schedule/ScheduleItem.tsx +++ b/apps/client/src/views/common/schedule/ScheduleItem.tsx @@ -1,7 +1,10 @@ +import { useRuntimeOffset } from '../../../common/hooks/useSocket'; import { cx } from '../../../common/utils/styleUtils'; import { formatTime } from '../../../common/utils/time'; import SuperscriptTime from '../../../features/viewers/common/superscript-time/SuperscriptTime'; +import { useScheduleOptions } from './schedule.options'; + import './Schedule.scss'; const formatOptions = { @@ -21,36 +24,38 @@ interface ScheduleItemProps { export default function ScheduleItem(props: ScheduleItemProps) { const { timeStart, timeEnd, title, backstageEvent, colour, skip, delay } = props; + const { showProjected } = useScheduleOptions(); - const start = formatTime(timeStart, formatOptions); - const end = formatTime(timeEnd, formatOptions); - - if (delay > 0) { - const delayedStart = formatTime(timeStart + delay, formatOptions); - const delayedEnd = formatTime(timeEnd + delay, formatOptions); - + if (showProjected) { return ( -
  • -
    - - - - → - - {backstageEvent && '*'} - - - - → - - {backstageEvent && '*'} - -
    -
    {title}
    -
  • + ); } + if (delay > 0) { + return ( + + ); + } + + const start = formatTime(timeStart, formatOptions); + const end = formatTime(timeEnd, formatOptions); return (
  • @@ -64,3 +69,70 @@ export default function ScheduleItem(props: ScheduleItemProps) {
  • ); } + +function DelayedScheduleItem(props: ScheduleItemProps) { + const { timeStart, timeEnd, title, backstageEvent, colour, skip, delay } = props; + + const start = formatTime(timeStart, formatOptions); + const end = formatTime(timeEnd, formatOptions); + const delayedStart = formatTime(timeStart + delay, formatOptions); + const delayedEnd = formatTime(timeEnd + delay, formatOptions); + + return ( +
  • +
    + + + + → + + {backstageEvent && '*'} + + + + → + + {backstageEvent && '*'} + +
    +
    {title}
    +
  • + ); +} + +function ProjectedScheduleItem(props: ScheduleItemProps) { + const { timeStart, timeEnd, title, backstageEvent, colour, skip, delay } = props; + + return ( +
  • +
    + + + → + + {backstageEvent && '*'} +
    +
    {title}
    +
  • + ); +} + +interface OffsetTimeProps { + time: number; + delay: number; +} + +function ProjectedTime(props: OffsetTimeProps) { + const { time, delay } = props; + const { offset } = useRuntimeOffset(); + + const projectedOffset = offset - delay; + const projectedTime = formatTime(time - offset, formatOptions); + + return ( + 0 && 'entry-times--ahead', projectedOffset < 0 && 'entry-times--behind'])} + time={projectedTime} + /> + ); +} diff --git a/apps/client/src/views/common/schedule/schedule.options.ts b/apps/client/src/views/common/schedule/schedule.options.ts index b70fc15b9..58b3b531d 100644 --- a/apps/client/src/views/common/schedule/schedule.options.ts +++ b/apps/client/src/views/common/schedule/schedule.options.ts @@ -23,18 +23,27 @@ export const scheduleOptions: ViewOption = { type: 'number', defaultValue: 10, }, + { + id: 'showProjected', + title: 'Show projected time', + description: 'Whether scheduled times should account for runtime offset.', + type: 'boolean', + defaultValue: false, + }, ], }; type ScheduleOptions = { cycleInterval: number; stopCycle: boolean; + showProjected: boolean; }; function getScheduleOptionsFromParams(searchParams: URLSearchParams): ScheduleOptions { return { cycleInterval: Number(searchParams.get('cycleInterval')) || 10, stopCycle: isStringBoolean(searchParams.get('stopCycle')), + showProjected: isStringBoolean(searchParams.get('showProjected')), }; }