mirror of
https://github.com/cpvalente/ontime.git
synced 2026-09-10 08:39:34 +00:00
refactor: fix missed first update (#1031)
This commit is contained in:
@@ -16,12 +16,9 @@ interface TimerDisplayProps {
|
|||||||
export default function TimerDisplay(props: TimerDisplayProps) {
|
export default function TimerDisplay(props: TimerDisplayProps) {
|
||||||
const { time } = props;
|
const { time } = props;
|
||||||
|
|
||||||
if (time == null) {
|
const isNegative = (time ?? 0) < 0;
|
||||||
return <div className={style.timer}>{timerPlaceholder}</div>;
|
const display =
|
||||||
}
|
time == null ? timerPlaceholder : millisToString(time, { fallback: timerPlaceholder }).replace('-', '');
|
||||||
|
|
||||||
const isNegative = time < 0;
|
|
||||||
const display = millisToString(Math.abs(time), { fallback: timerPlaceholder });
|
|
||||||
const classes = cx([style.timer, isNegative ? style.finished : null]);
|
const classes = cx([style.timer, isNegative ? style.finished : null]);
|
||||||
|
|
||||||
return <div className={classes}>{display}</div>;
|
return <div className={classes}>{display}</div>;
|
||||||
|
|||||||
@@ -26,8 +26,7 @@ export function getShouldTimerUpdate(previousValue: number, currentValue: MaybeN
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// we avoid trigger ahead since it can cause duplicate triggers
|
// 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;
|
return shouldUpdateTimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
type MaybeNumber = number | null;
|
import type { MaybeNumber } from 'ontime-types';
|
||||||
|
|
||||||
export const MILLIS_PER_SECOND = 1000;
|
export const MILLIS_PER_SECOND = 1000;
|
||||||
export const MILLIS_PER_MINUTE = 1000 * 60;
|
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 dayInMs = 86400000;
|
||||||
export const maxDuration = dayInMs - MILLIS_PER_SECOND;
|
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) {
|
if (!millis) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for negative times, we want to round up
|
|
||||||
if (millis < 0) {
|
|
||||||
Math.ceil(millis / conversion);
|
|
||||||
}
|
|
||||||
return Math.floor(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);
|
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);
|
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);
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,17 +11,29 @@ describe('millisToString()', () => {
|
|||||||
expect(millisToString(0)).toBe('00:00:00');
|
expect(millisToString(0)).toBe('00:00:00');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows negative timers', () => {
|
test('negative times are rounded up', () => {
|
||||||
const testScenarios = [
|
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: -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: -60000, expected: '-00:01:00' },
|
||||||
|
{ millis: 600000, expected: '00:10: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: -3600000, expected: '-01:00:00' },
|
||||||
|
{ millis: 36000000, expected: '10: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: -86399000, expected: '-23:59:59' },
|
||||||
|
{ millis: 86400000, expected: '24:00:00' },
|
||||||
{ millis: -86400000, expected: '-24:00:00' },
|
{ millis: -86400000, expected: '-24:00:00' },
|
||||||
|
{ millis: 86401000, expected: '24:00:01' },
|
||||||
{ millis: -86401000, expected: '-24:00:01' },
|
{ millis: -86401000, expected: '-24:00:01' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { MaybeNumber } from 'ontime-types';
|
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 {
|
function pad(val: number): string {
|
||||||
return String(val).padStart(2, '0');
|
return String(val).padStart(2, '0');
|
||||||
@@ -21,12 +21,13 @@ export function millisToString(millis?: MaybeNumber, options?: FormatOptions): s
|
|||||||
return options?.fallback ?? '...';
|
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 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(':')}`;
|
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.
|
* Formats a given date into a custom string format based on UTC time.
|
||||||
*
|
*
|
||||||
* @param millis - The number of milliseconds.
|
* @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.
|
* For example, 'ss' will format the millis as '07' seconds.
|
||||||
*
|
*
|
||||||
* @returns The formatted date as a string according to the provided `format` string.
|
* @returns The formatted date as a string according to the provided `format` string.
|
||||||
* If input `millis` is smaller than zero, it returns undefined.
|
* If input `millis` is smaller than zero, it returns undefined.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export function formatFromMillis(millis: number, format: string): string | undefined {
|
export function formatFromMillis(millis: number, format: string): string | undefined {
|
||||||
if (millis < 0) {
|
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 secondPadded = date.getUTCSeconds().toString().padStart(2, '0');
|
||||||
const second = date.getUTCSeconds().toString();
|
const second = date.getUTCSeconds().toString();
|
||||||
const milliseconds = date.getUTCMilliseconds().toString().padStart(3, '0');
|
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 hour12Padded = hour12.padStart(2, '0');
|
||||||
const amPm = date.getUTCHours() >= 12 ? 'PM' : 'AM';
|
const amPm = date.getUTCHours() >= 12 ? 'PM' : 'AM';
|
||||||
|
|
||||||
const replacements: Record<string, string> = {
|
const replacements: Record<string, string> = {
|
||||||
'HH': hour24Padded,
|
HH: hour24Padded,
|
||||||
'H': hour24,
|
H: hour24,
|
||||||
'hh': hour12Padded,
|
hh: hour12Padded,
|
||||||
'h': hour12,
|
h: hour12,
|
||||||
'mm': minutePadded,
|
mm: minutePadded,
|
||||||
'm': minute,
|
m: minute,
|
||||||
'ss': secondPadded,
|
ss: secondPadded,
|
||||||
's': second,
|
s: second,
|
||||||
'S': milliseconds,
|
S: milliseconds,
|
||||||
'a': amPm
|
a: amPm,
|
||||||
};
|
};
|
||||||
|
|
||||||
return applyReplacements(format, replacements);
|
return applyReplacements(format, replacements);
|
||||||
@@ -123,7 +124,7 @@ export function formatFromMillis(millis: number, format: string): string | undef
|
|||||||
*/
|
*/
|
||||||
function applyReplacements(template: string, replacements: Record<string, string>): string {
|
function applyReplacements(template: string, replacements: Record<string, string>): string {
|
||||||
return Object.keys(replacements).reduce((result, token) => {
|
return Object.keys(replacements).reduce((result, token) => {
|
||||||
const regex = new RegExp(`\\b${token}\\b`, 'g');
|
const regex = new RegExp(`\\b${token}\\b`, 'g');
|
||||||
return result.replace(regex, replacements[token]);
|
return result.replace(regex, replacements[token]);
|
||||||
}, template);
|
}, template);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user