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) {