From c2039866b4476c1566056f4ca21973b6f68991f6 Mon Sep 17 00:00:00 2001 From: Carlos Valente <34649812+cpvalente@users.noreply.github.com> Date: Mon, 3 Jun 2024 20:27:51 +0200 Subject: [PATCH] refactor: fix missed first update (#1031) --- .../playback/timer-display/TimerDisplay.tsx | 9 ++-- .../runtime-service/rundownService.utils.ts | 3 +- .../utils/src/date-utils/conversionUtils.ts | 54 +++++++++++++++---- .../src/date-utils/timeFormatting.test.ts | 18 +++++-- .../utils/src/date-utils/timeFormatting.ts | 45 ++++++++-------- 5 files changed, 86 insertions(+), 43 deletions(-) diff --git a/apps/client/src/features/control/playback/timer-display/TimerDisplay.tsx b/apps/client/src/features/control/playback/timer-display/TimerDisplay.tsx index 360b39960..5234bad7b 100644 --- a/apps/client/src/features/control/playback/timer-display/TimerDisplay.tsx +++ b/apps/client/src/features/control/playback/timer-display/TimerDisplay.tsx @@ -16,12 +16,9 @@ interface TimerDisplayProps { export default function TimerDisplay(props: TimerDisplayProps) { const { time } = props; - if (time == null) { - return
{timerPlaceholder}
; - } - - const isNegative = time < 0; - const display = millisToString(Math.abs(time), { fallback: timerPlaceholder }); + const isNegative = (time ?? 0) < 0; + const display = + time == null ? timerPlaceholder : millisToString(time, { fallback: timerPlaceholder }).replace('-', ''); const classes = cx([style.timer, isNegative ? style.finished : null]); return
{display}
; diff --git a/apps/server/src/services/runtime-service/rundownService.utils.ts b/apps/server/src/services/runtime-service/rundownService.utils.ts index 6c257ffe0..9e2e5b1f4 100644 --- a/apps/server/src/services/runtime-service/rundownService.utils.ts +++ b/apps/server/src/services/runtime-service/rundownService.utils.ts @@ -26,8 +26,7 @@ export function getShouldTimerUpdate(previousValue: number, currentValue: MaybeN return false; } // we avoid trigger ahead since it can cause duplicate triggers - // we force the timer value to be negative because we need a ceiling reduction - const shouldUpdateTimer = millisToSeconds(-currentValue) !== millisToSeconds(-previousValue); + const shouldUpdateTimer = millisToSeconds(currentValue) !== millisToSeconds(previousValue); return shouldUpdateTimer; } diff --git a/packages/utils/src/date-utils/conversionUtils.ts b/packages/utils/src/date-utils/conversionUtils.ts index 91e2ab2bc..11ca838f9 100644 --- a/packages/utils/src/date-utils/conversionUtils.ts +++ b/packages/utils/src/date-utils/conversionUtils.ts @@ -1,4 +1,4 @@ -type MaybeNumber = number | null; +import type { MaybeNumber } from 'ontime-types'; export const MILLIS_PER_SECOND = 1000; export const MILLIS_PER_MINUTE = 1000 * 60; @@ -7,26 +7,60 @@ export const MILLIS_PER_HOUR = 1000 * 60 * 60; export const dayInMs = 86400000; export const maxDuration = dayInMs - MILLIS_PER_SECOND; -function convertMillis(millis: MaybeNumber, conversion: number) { +/** + * Utility converts milliseconds to a specific unit + * @param millis + * @param conversion + * @returns + */ +function convertMillis(millis: MaybeNumber, conversion: number): number { if (!millis) { return 0; } - - // for negative times, we want to round up - if (millis < 0) { - Math.ceil(millis / conversion); - } return Math.floor(millis / conversion); } -export function millisToSeconds(millis: MaybeNumber) { +/** + * Converts value in milliseconds to seconds + * @param millis + * @returns + */ +export function millisToSeconds(millis: MaybeNumber): number { return convertMillis(millis, MILLIS_PER_SECOND); } -export function millisToMinutes(millis: MaybeNumber) { +/** + * Converts value in milliseconds to minutes + * @param millis + * @returns + */ +export function millisToMinutes(millis: MaybeNumber): number { return convertMillis(millis, MILLIS_PER_MINUTE); } -export function millisToHours(millis: MaybeNumber) { +/** + * Converts value in milliseconds to hours + * @param millis + * @returns + */ +export function millisToHours(millis: MaybeNumber): number { return convertMillis(millis, MILLIS_PER_HOUR); } + +/** + * Converts value in seconds to minutes + * @param seconds + * @returns + */ +export function secondsToMinutes(seconds: number): number { + return Math.floor(seconds / 60); +} + +/** + * Converts value in seconds to hours + * @param seconds + * @returns + */ +export function secondsToHours(seconds: number): number { + return Math.floor(seconds / 3600); +} diff --git a/packages/utils/src/date-utils/timeFormatting.test.ts b/packages/utils/src/date-utils/timeFormatting.test.ts index 3fd4cfd3f..f0b114dec 100644 --- a/packages/utils/src/date-utils/timeFormatting.test.ts +++ b/packages/utils/src/date-utils/timeFormatting.test.ts @@ -11,17 +11,29 @@ describe('millisToString()', () => { expect(millisToString(0)).toBe('00:00:00'); }); - it('shows negative timers', () => { + test('negative times are rounded up', () => { const testScenarios = [ - { millis: -300, expected: '-00:00:00' }, + { millis: 300, expected: '00:00:00' }, + { millis: -300, expected: '-00:00:01' }, + { millis: 1000, expected: '00:00:01' }, { millis: -1000, expected: '-00:00:01' }, - { millis: -1500, expected: '-00:00:01' }, + { millis: 1500, expected: '00:00:01' }, + { millis: -1500, expected: '-00:00:02' }, + { millis: 60000 - 1, expected: '00:00:59' }, + { millis: -(60000 - 1), expected: '-00:01:00' }, + { millis: 60000, expected: '00:01:00' }, { millis: -60000, expected: '-00:01:00' }, + { millis: 600000, expected: '00:10:00' }, { millis: -600000, expected: '-00:10:00' }, + { millis: 3600000, expected: '01:00:00' }, { millis: -3600000, expected: '-01:00:00' }, + { millis: 36000000, expected: '10:00:00' }, { millis: -36000000, expected: '-10:00:00' }, + { millis: 86399000, expected: '23:59:59' }, { millis: -86399000, expected: '-23:59:59' }, + { millis: 86400000, expected: '24:00:00' }, { millis: -86400000, expected: '-24:00:00' }, + { millis: 86401000, expected: '24:00:01' }, { millis: -86401000, expected: '-24:00:01' }, ]; diff --git a/packages/utils/src/date-utils/timeFormatting.ts b/packages/utils/src/date-utils/timeFormatting.ts index 1f1a67737..8a0c9f4cd 100644 --- a/packages/utils/src/date-utils/timeFormatting.ts +++ b/packages/utils/src/date-utils/timeFormatting.ts @@ -1,6 +1,6 @@ import type { MaybeNumber } from 'ontime-types'; -import { millisToHours, millisToMinutes, millisToSeconds } from './conversionUtils.js'; +import { millisToSeconds, secondsToHours, secondsToMinutes } from './conversionUtils.js'; function pad(val: number): string { return String(val).padStart(2, '0'); @@ -21,12 +21,13 @@ export function millisToString(millis?: MaybeNumber, options?: FormatOptions): s return options?.fallback ?? '...'; } - const absoluteMillis = Math.abs(millis); - const seconds = millisToSeconds(absoluteMillis) % 60; - const minutes = millisToMinutes(absoluteMillis) % 60; - const hours = millisToHours(absoluteMillis); const isNegative = millis < 0; + const totalSeconds = Math.abs(millisToSeconds(millis)); + const seconds = totalSeconds % 60; + const minutes = secondsToMinutes(totalSeconds) % 60; + const hours = secondsToHours(totalSeconds); + return `${isNegative ? '-' : ''}${[hours, minutes, seconds].map(pad).join(':')}`; } @@ -71,14 +72,14 @@ export function removeSeconds(timer: string): string { /** * Formats a given date into a custom string format based on UTC time. - * + * * @param millis - The number of milliseconds. - * @param format - A string specifying the desired output format. + * @param format - A string specifying the desired output format. * For example, 'ss' will format the millis as '07' seconds. - * + * * @returns The formatted date as a string according to the provided `format` string. * If input `millis` is smaller than zero, it returns undefined. - * + * */ export function formatFromMillis(millis: number, format: string): string | undefined { if (millis < 0) { @@ -94,21 +95,21 @@ export function formatFromMillis(millis: number, format: string): string | undef const secondPadded = date.getUTCSeconds().toString().padStart(2, '0'); const second = date.getUTCSeconds().toString(); const milliseconds = date.getUTCMilliseconds().toString().padStart(3, '0'); - const hour12 = ((date.getUTCHours() % 12) || 12).toString(); + const hour12 = (date.getUTCHours() % 12 || 12).toString(); const hour12Padded = hour12.padStart(2, '0'); const amPm = date.getUTCHours() >= 12 ? 'PM' : 'AM'; const replacements: Record = { - 'HH': hour24Padded, - 'H': hour24, - 'hh': hour12Padded, - 'h': hour12, - 'mm': minutePadded, - 'm': minute, - 'ss': secondPadded, - 's': second, - 'S': milliseconds, - 'a': amPm + HH: hour24Padded, + H: hour24, + hh: hour12Padded, + h: hour12, + mm: minutePadded, + m: minute, + ss: secondPadded, + s: second, + S: milliseconds, + a: amPm, }; return applyReplacements(format, replacements); @@ -123,7 +124,7 @@ export function formatFromMillis(millis: number, format: string): string | undef */ function applyReplacements(template: string, replacements: Record): string { return Object.keys(replacements).reduce((result, token) => { - const regex = new RegExp(`\\b${token}\\b`, 'g'); - return result.replace(regex, replacements[token]); + const regex = new RegExp(`\\b${token}\\b`, 'g'); + return result.replace(regex, replacements[token]); }, template); }