From 627cce7ba6c80979dac97e829fba6b9ad7ee4649 Mon Sep 17 00:00:00 2001 From: Carlos Valente <34649812+cpvalente@users.noreply.github.com> Date: Sat, 27 Nov 2021 20:35:06 +0100 Subject: [PATCH] Hotfix/4.0.0 (#48) * validate time string * handle time entered in seconds * fix: id in delays and blocks --- client/src/common/input/EditableTimer.jsx | 32 +++++++++---------- .../common/utils/__tests__/dateConfig.test.js | 30 +++++++++++++++++ client/src/common/utils/dateConfig.js | 25 ++++++++++++++- server/package.json | 5 ++- server/src/app.js | 1 - server/src/utils/parser.js | 8 +++-- 6 files changed, 79 insertions(+), 22 deletions(-) diff --git a/client/src/common/input/EditableTimer.jsx b/client/src/common/input/EditableTimer.jsx index be3ab29f2..d3962c59c 100644 --- a/client/src/common/input/EditableTimer.jsx +++ b/client/src/common/input/EditableTimer.jsx @@ -1,6 +1,10 @@ import { Editable, EditableInput, EditablePreview } from '@chakra-ui/editable'; import { useEffect, useState } from 'react'; -import { stringFromMillis, timeStringToMillis } from '../utils/dateConfig'; +import { + isTimeString, + stringFromMillis, + timeStringToMillis, +} from '../utils/dateConfig'; import { showErrorToast } from '../helpers/toastManager'; import style from './EditableTimer.module.css'; @@ -28,23 +32,23 @@ export default function EditableTimer(props) { // Check if there is anything there if (value === '') return false; - // ensure we have seconds - const val = value.split(':').length === 3 ? value : `${value}:00`; + // check if its valid time string + if (!isTimeString(value)) return false; + + // convert entered value to milliseconds + const newValMillis = timeStringToMillis(value); // Time now and time submitedVal - const original = stringFromMillis(time + delay, true); + const originalMillis = time + delay; // check if time is different from before - if (val === original) return false; - - // convert to millis object - const millis = timeStringToMillis(val); + if (newValMillis === originalMillis) return false; // validate with parent - if (!validate(name, millis)) return false; + if (!validate(name, newValMillis)) return false; // update entry - actionHandler('update', { field: name, value: millis }); + actionHandler('update', { field: name, value: newValMillis }); return true; }; @@ -58,13 +62,7 @@ export default function EditableTimer(props) { className={delay > 0 ? style.delayedEditable : style.editable} > - + ); } diff --git a/client/src/common/utils/__tests__/dateConfig.test.js b/client/src/common/utils/__tests__/dateConfig.test.js index 3595d09ce..d91e2a1c7 100644 --- a/client/src/common/utils/__tests__/dateConfig.test.js +++ b/client/src/common/utils/__tests__/dateConfig.test.js @@ -213,4 +213,34 @@ describe('test timeStringToMillis function', () => { const t = { val: '1:00:00', result: 3600000 }; expect(timeStringToMillis(t.val)).toBe(t.result); }); + + it('test with 1', () => { + const t = { val: '1', result: 1000 }; + expect(timeStringToMillis(t.val)).toBe(t.result); + }); + + it('test with 120', () => { + const t = { val: '120', result: 120000 }; + expect(timeStringToMillis(t.val)).toBe(t.result); + }); + + it('test with 56', () => { + const t = { val: '56', result: 56000 }; + expect(timeStringToMillis(t.val)).toBe(t.result); + }); + + it('test with 2:3', () => { + const t = { val: '2:3', result: 123000 }; + expect(timeStringToMillis(t.val)).toBe(t.result); + }); + + it('test with 02:3', () => { + const t = { val: '02:3', result: 123000 }; + expect(timeStringToMillis(t.val)).toBe(t.result); + }); + + it('test with 2:03', () => { + const t = { val: '2:03', result: 123000 }; + expect(timeStringToMillis(t.val)).toBe(t.result); + }); }); diff --git a/client/src/common/utils/dateConfig.js b/client/src/common/utils/dateConfig.js index 7cc62d4e6..0c95fff74 100644 --- a/client/src/common/utils/dateConfig.js +++ b/client/src/common/utils/dateConfig.js @@ -90,8 +90,31 @@ export const millisToMinutes = (millis) => { export const timeStringToMillis = (string) => { if (typeof string !== 'string') return 0; const time = string.split(':'); - if (time.length === 2) return Math.abs(time[0]) * mth + time[1]; + if (time.length === 1) return Math.abs(time[0] * mts); + if (time.length === 2) return Math.abs(time[0]) * mtm + time[1] * mts; if (time.length === 3) return Math.abs(time[0]) * mth + time[1] * mtm + time[2] * mts; else return 0; }; + +/** + * @description Validates a time string + * @param {string} string - time string "23:00:12" + * @returns {boolean} string represents time + */ + +// isTimeString +export const isTimeString = (string) => { + // ^ # Start of string + // (?: # Try to match... + // (?: # Try to match... + // ([01]?\d|2[0-3]): # HH: + // )? # (optionally). + // ([0-5]?\d): # MM: (required) + // )? # (entire group optional, so either HH:MM:, MM: or nothing) + // ([0-5]?\d) # SS (required) + // $ # End of string + + const regex = /^(?:(?:([01]?\d|2[0-3]):)?([0-5]?\d):)?([0-5]?\d)$/; + return regex.test(string); +}; diff --git a/server/package.json b/server/package.json index cb6c0eae9..dca7b404e 100644 --- a/server/package.json +++ b/server/package.json @@ -1,6 +1,6 @@ { "name": "ontime", - "version": "0.3.2", + "version": "0.4.1", "author": "Carlos Valente", "description": "Time keeping for live events", "repository": "https://github.com/cpvalente/ontime", @@ -25,6 +25,9 @@ }, "scripts": { "nodestart": "NODE_ENV=development node src/app.js", + "setdb": "cp data/db.json src/data/db.json", + "clean": "rm -rf ../client/build/ && rm -rf ../client/node_modules && rm -rf src/node_modules && rm -rf ./node_modules && rm -rf ./dist", + "prep": "yarn clean && yarn prep", "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js", "start": "NODE_ENV=development electron .", "pack": "electron-builder --dir", diff --git a/server/src/app.js b/server/src/app.js index 60570a16a..6be230698 100644 --- a/server/src/app.js +++ b/server/src/app.js @@ -34,7 +34,6 @@ import ua from 'universal-analytics'; let isValid = validateFile(file); if (isValid) { - console.log('reading this'); // Read data from JSON file, this will set db.data content await db.read(); } diff --git a/server/src/utils/parser.js b/server/src/utils/parser.js index c4fc021c4..eca861231 100644 --- a/server/src/utils/parser.js +++ b/server/src/utils/parser.js @@ -227,10 +227,14 @@ export const parseJsonv1 = async (jsonData) => { numEntries++; } } else if (e.type === 'delay') { - events.push({ ...delayDef, duration: e.duration }); + events.push({ + ...delayDef, + duration: e.duration, + id: e.id || generateId(), + }); numEntries++; } else if (e.type === 'block') { - events.push({ ...blockDef }); + events.push({ ...blockDef, id: e.id || generateId() }); numEntries++; } else { console.log('ERROR: undefined event type, skipping');