From 347f333b3e59398016ec665a78bd53b7c7e3b3c1 Mon Sep 17 00:00:00 2001 From: Carlos Valente Date: Fri, 9 Aug 2024 19:59:15 +0200 Subject: [PATCH] refactor: unify progress bar logic --- .../MultiPartProgressBar.tsx | 11 ++++---- .../components/progress-bar/ProgressBar.tsx | 15 ++++++----- apps/client/src/common/hooks/useSocket.ts | 1 - apps/client/src/common/utils/getProgress.ts | 23 ++++++++++++++++ .../cuesheet-progress/CuesheetProgress.tsx | 11 ++++---- .../operator/status-bar/StatusBarProgress.tsx | 5 ++-- .../composite/EventBlockProgressBar.tsx | 25 +++-------------- .../__tests__/EventBlockProgressBar.test.ts | 27 ------------------- .../features/viewers/backstage/Backstage.tsx | 5 ++-- 9 files changed, 49 insertions(+), 74 deletions(-) create mode 100644 apps/client/src/common/utils/getProgress.ts delete mode 100644 apps/client/src/features/rundown/event-block/composite/__tests__/EventBlockProgressBar.test.ts diff --git a/apps/client/src/common/components/multi-part-progress-bar/MultiPartProgressBar.tsx b/apps/client/src/common/components/multi-part-progress-bar/MultiPartProgressBar.tsx index ce750c128..4858aeca1 100644 --- a/apps/client/src/common/components/multi-part-progress-bar/MultiPartProgressBar.tsx +++ b/apps/client/src/common/components/multi-part-progress-bar/MultiPartProgressBar.tsx @@ -1,12 +1,12 @@ import { MaybeNumber } from 'ontime-types'; -import { clamp } from '../../utils/math'; +import { getProgress } from '../../utils/getProgress'; import './MultiPartProgressBar.scss'; interface MultiPartProgressBar { now: MaybeNumber; - complete: number; + complete: MaybeNumber; normalColor: string; warning?: MaybeNumber; warningColor: string; @@ -31,10 +31,9 @@ export default function MultiPartProgressBar(props: MultiPartProgressBar) { className = '', } = props; - const percentRemaining = complete === 0 ? 0 : 100 - clamp(100 - (Math.max(now ?? 0, 0) * 100) / complete, 0, 100); - - const dangerWidth = danger ? clamp((danger / complete) * 100, 0, 100) : 0; - const warningWidth = warning ? clamp((warning / complete) * 100 - dangerWidth, 0, 100) : 0; + const percentRemaining = 100 - getProgress(now, complete); + const dangerWidth = danger ? 100 - getProgress(danger, complete) : 0; + const warningWidth = warning ? 100 - dangerWidth - getProgress(warning, complete) : 0; return (
-
+
); } diff --git a/apps/client/src/common/hooks/useSocket.ts b/apps/client/src/common/hooks/useSocket.ts index 624ea7483..aa4c9b86f 100644 --- a/apps/client/src/common/hooks/useSocket.ts +++ b/apps/client/src/common/hooks/useSocket.ts @@ -150,7 +150,6 @@ export const useClock = () => { /** Used by the progress bar components */ export const useProgressData = () => { const featureSelector = (state: RuntimeStore) => ({ - addedTime: state.timer.addedTime, current: state.timer.current, duration: state.timer.duration, timeWarning: state.eventNow?.timeWarning ?? null, diff --git a/apps/client/src/common/utils/getProgress.ts b/apps/client/src/common/utils/getProgress.ts new file mode 100644 index 000000000..3bf6baf66 --- /dev/null +++ b/apps/client/src/common/utils/getProgress.ts @@ -0,0 +1,23 @@ +import { MaybeNumber } from 'ontime-types'; + +import { clamp } from './math'; + +/** + * Returns completion percentage of a progress bar + * This code assumes the current time and duration have addedTime already applied + */ +export function getProgress(current: MaybeNumber, duration: MaybeNumber) { + if (current === null || duration === null) { + return 0; + } + + if (current <= 0) { + return 100; + } + + if (current >= duration) { + return 0; + } + + return clamp(((duration - current) / duration) * 100, 0, 100); +} diff --git a/apps/client/src/features/cuesheet/cuesheet-progress/CuesheetProgress.tsx b/apps/client/src/features/cuesheet/cuesheet-progress/CuesheetProgress.tsx index 890ab22fa..8a6eb26fc 100644 --- a/apps/client/src/features/cuesheet/cuesheet-progress/CuesheetProgress.tsx +++ b/apps/client/src/features/cuesheet/cuesheet-progress/CuesheetProgress.tsx @@ -6,18 +6,17 @@ import styles from './CuesheetProgress.module.scss'; export default function CuesheetProgress() { const { data } = useViewSettings(); - const { addedTime, current, duration, timeWarning, timeDanger } = useProgressData(); - const totalTime = (duration ?? 0) + (addedTime ?? 0); + const { current, duration, timeWarning, timeDanger } = useProgressData(); return ( diff --git a/apps/client/src/features/operator/status-bar/StatusBarProgress.tsx b/apps/client/src/features/operator/status-bar/StatusBarProgress.tsx index 07b25bc88..74d757c73 100644 --- a/apps/client/src/features/operator/status-bar/StatusBarProgress.tsx +++ b/apps/client/src/features/operator/status-bar/StatusBarProgress.tsx @@ -11,13 +11,12 @@ interface StatusBarProgressProps { export default function StatusBarProgress(props: StatusBarProgressProps) { const { viewSettings } = props; - const { addedTime, current, duration, timeWarning, timeDanger } = useProgressData(); - const totalTime = (duration ?? 0) + (addedTime ?? 0); + const { current, duration, timeWarning, timeDanger } = useProgressData(); return ( ; + const progress = getProgress(timer.current, timer.duration); + + return
; } diff --git a/apps/client/src/features/rundown/event-block/composite/__tests__/EventBlockProgressBar.test.ts b/apps/client/src/features/rundown/event-block/composite/__tests__/EventBlockProgressBar.test.ts deleted file mode 100644 index cf07ab972..000000000 --- a/apps/client/src/features/rundown/event-block/composite/__tests__/EventBlockProgressBar.test.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { dayInMs } from 'ontime-utils'; - -import { getPercentComplete } from '../EventBlockProgressBar'; - -describe('getPercentComplete()', () => { - describe('calculates progress in normal cases', () => { - const testScenarios = [ - { current: 0, duration: 0, expect: 100 }, - { current: 0, duration: 100, expect: 100 }, - { current: 0, duration: dayInMs, expect: 100 }, - { current: 10, duration: 100, expect: 90 }, - { current: 50, duration: 100, expect: 50 }, - { current: 100, duration: 100, expect: 0 }, - ]; - - testScenarios.forEach((testCase) => { - it(`handles ${testCase.current} / ${testCase.duration}`, () => { - const progress = getPercentComplete(testCase.current, testCase.duration); - expect(progress).toBe(testCase.expect); - }); - }); - }); - it('is 0 if we dont have a current or duration', () => { - const progress = getPercentComplete(null, null); - expect(progress).toBe(0); - }); -}); diff --git a/apps/client/src/features/viewers/backstage/Backstage.tsx b/apps/client/src/features/viewers/backstage/Backstage.tsx index dca3a6933..1987232f7 100644 --- a/apps/client/src/features/viewers/backstage/Backstage.tsx +++ b/apps/client/src/features/viewers/backstage/Backstage.tsx @@ -94,7 +94,6 @@ export default function Backstage(props: BackstageProps) { let stageTimer = millisToString(time.current, { fallback: timerPlaceholderMin }); stageTimer = removeLeadingZero(stageTimer); - const totalTime = (time.duration ?? 0) + (time.addedTime ?? 0); const defaultFormat = getDefaultFormat(settings?.timeFormat); const backstageOptions = getBackstageOptions(defaultFormat, customFields); @@ -111,8 +110,8 @@ export default function Backstage(props: BackstageProps) {