From e7e5882859e3bf629f64fe94a99d781a49a5ff35 Mon Sep 17 00:00:00 2001 From: Vikeo Date: Sun, 23 Feb 2025 23:42:01 +0100 Subject: [PATCH] add basic timer that always is showing --- package.json | 3 + pnpm-lock.yaml | 236 ++++++++++++++++++ .../Misc/Timer/NegativeStopWatch.tsx | 28 +++ src/Components/Misc/Timer/Time.tsx | 9 + src/Components/Misc/Timer/Timer.tsx | 85 +++++++ src/Components/Players/Players.tsx | 2 + src/Components/Views/Play.tsx | 2 +- src/Utils/formatTime.ts | 17 ++ 8 files changed, 381 insertions(+), 1 deletion(-) create mode 100644 src/Components/Misc/Timer/NegativeStopWatch.tsx create mode 100644 src/Components/Misc/Timer/Time.tsx create mode 100644 src/Components/Misc/Timer/Timer.tsx create mode 100644 src/Utils/formatTime.ts diff --git a/package.json b/package.json index aabd4d8..cadd83c 100644 --- a/package.json +++ b/package.json @@ -17,12 +17,15 @@ "deploy": "bun run build && firebase deploy --only hosting" }, "dependencies": { + "@mui/icons-material": "^6.4.5", + "@mui/material": "^6.4.5", "firebase": "^10.14.1", "ga-4-react": "^0.1.281", "react": "^18.3.1", "react-dom": "^18.3.1", "react-screen-wake-lock": "^3.0.2", "react-swipeable": "^7.0.2", + "react-timer-hook": "^3.0.8", "react-twc": "^1.4.2", "semver": "^7.7.1", "zod": "^3.24.2" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a4036dc..da544a4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,12 @@ importers: .: dependencies: + '@mui/icons-material': + specifier: ^6.4.5 + version: 6.4.5(@mui/material@6.4.5(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.18)(react@18.3.1) + '@mui/material': + specifier: ^6.4.5 + version: 6.4.5(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) firebase: specifier: ^10.14.1 version: 10.14.1 @@ -26,6 +32,9 @@ importers: react-swipeable: specifier: ^7.0.2 version: 7.0.2(react@18.3.1) + react-timer-hook: + specifier: ^3.0.8 + version: 3.0.8(react@18.3.1) react-twc: specifier: ^1.4.2 version: 1.4.2(@types/react@18.3.18)(react@18.3.1) @@ -1113,6 +1122,97 @@ packages: '@jsdevtools/ono@7.1.3': resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} + '@mui/core-downloads-tracker@6.4.5': + resolution: {integrity: sha512-zoXvHU1YuoodgMlPS+epP084Pqv9V+Vg+5IGv9n/7IIFVQ2nkTngYHYxElCq8pdTTbDcgji+nNh0lxri2abWgA==} + + '@mui/icons-material@6.4.5': + resolution: {integrity: sha512-4A//t8Nrc+4u4pbVhGarIFU98zpuB5AV9hTNzgXx1ySZJ1tWtx+i/1SbQ8PtGJxWeXlljhwimZJNPQ3x0CiIFw==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@mui/material': ^6.4.5 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@mui/material@6.4.5': + resolution: {integrity: sha512-5eyEgSXocIeV1JkXs8mYyJXU0aFyXZIWI5kq2g/mCnIgJe594lkOBNAKnCIaGVfQTu2T6TTEHF8/hHIqpiIRGA==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@mui/material-pigment-css': ^6.4.3 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@mui/material-pigment-css': + optional: true + '@types/react': + optional: true + + '@mui/private-theming@6.4.3': + resolution: {integrity: sha512-7x9HaNwDCeoERc4BoEWLieuzKzXu5ZrhRnEM6AUcRXUScQLvF1NFkTlP59+IJfTbEMgcGg1wWHApyoqcksrBpQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@mui/styled-engine@6.4.3': + resolution: {integrity: sha512-OC402VfK+ra2+f12Gef8maY7Y9n7B6CZcoQ9u7mIkh/7PKwW/xH81xwX+yW+Ak1zBT3HYcVjh2X82k5cKMFGoQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@emotion/react': ^11.4.1 + '@emotion/styled': ^11.3.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + + '@mui/system@6.4.3': + resolution: {integrity: sha512-Q0iDwnH3+xoxQ0pqVbt8hFdzhq1g2XzzR4Y5pVcICTNtoCLJmpJS3vI4y/OIM1FHFmpfmiEC2IRIq7YcZ8nsmg==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + + '@mui/types@7.2.21': + resolution: {integrity: sha512-6HstngiUxNqLU+/DPqlUJDIPbzUBxIVHb1MmXP0eTWDIROiCR2viugXpEif0PPe2mLqqakPzzRClWAnK+8UJww==} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@mui/utils@6.4.3': + resolution: {integrity: sha512-jxHRHh3BqVXE9ABxDm+Tc3wlBooYz/4XPa0+4AI+iF38rV1/+btJmSUgG4shDtSWVs/I97aDn5jBCt6SF2Uq2A==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1157,6 +1257,9 @@ packages: resolution: {integrity: sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==} engines: {node: '>=12'} + '@popperjs/core@2.11.8': + resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + '@protobufjs/aspromise@1.1.2': resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} @@ -1562,6 +1665,11 @@ packages: peerDependencies: '@types/react': ^18.0.0 + '@types/react-transition-group@4.4.12': + resolution: {integrity: sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==} + peerDependencies: + '@types/react': '*' + '@types/react@18.3.18': resolution: {integrity: sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==} @@ -2312,6 +2420,9 @@ packages: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} + dom-helpers@5.2.1: + resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} @@ -4005,6 +4116,9 @@ packages: react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + react-is@19.0.0: + resolution: {integrity: sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==} + react-screen-wake-lock@3.0.2: resolution: {integrity: sha512-f88vcfMG1AWYRSIWQ5Qx5YVboH6TSL0F4ZlFLERZp6aKiZRGVRAAJ9wedJdO5jqTMcCDZ4OXJ8PjcSkDmvGSBg==} engines: {node: '>=14.16'} @@ -4016,6 +4130,17 @@ packages: peerDependencies: react: ^16.8.3 || ^17 || ^18 || ^19.0.0 || ^19.0.0-rc + react-timer-hook@3.0.8: + resolution: {integrity: sha512-bi2e7DhPBU1MRPU4ZHaVqBmgM9e2HK0ae8O2AIqwqjcPo4/qR7lVGQonOQLAKOZPQCJSYfV8F5aBWzOLXElzqQ==} + peerDependencies: + react: '>=16.8.0' + + react-transition-group@4.4.5: + resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} + peerDependencies: + react: '>=16.6.0' + react-dom: '>=16.6.0' + react-twc@1.4.2: resolution: {integrity: sha512-ix8Z1dNacL29Vri3rWsQqRYMQXWCNzbI1qhz0yyvcbO057HZwz3rXZDQ7TcOE1hQ7EHornX3ka2reO27RmXiYA==} @@ -6216,6 +6341,91 @@ snapshots: '@jsdevtools/ono@7.1.3': {} + '@mui/core-downloads-tracker@6.4.5': {} + + '@mui/icons-material@6.4.5(@mui/material@6.4.5(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.18)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.9 + '@mui/material': 6.4.5(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.18 + + '@mui/material@6.4.5(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.9 + '@mui/core-downloads-tracker': 6.4.5 + '@mui/system': 6.4.3(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1) + '@mui/types': 7.2.21(@types/react@18.3.18) + '@mui/utils': 6.4.3(@types/react@18.3.18)(react@18.3.1) + '@popperjs/core': 2.11.8 + '@types/react-transition-group': 4.4.12(@types/react@18.3.18) + clsx: 2.1.1 + csstype: 3.1.3 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-is: 19.0.0 + react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + optionalDependencies: + '@emotion/react': 11.14.0(@types/react@18.3.18)(react@18.3.1) + '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + + '@mui/private-theming@6.4.3(@types/react@18.3.18)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.9 + '@mui/utils': 6.4.3(@types/react@18.3.18)(react@18.3.1) + prop-types: 15.8.1 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.18 + + '@mui/styled-engine@6.4.3(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.9 + '@emotion/cache': 11.14.0 + '@emotion/serialize': 1.3.3 + '@emotion/sheet': 1.4.0 + csstype: 3.1.3 + prop-types: 15.8.1 + react: 18.3.1 + optionalDependencies: + '@emotion/react': 11.14.0(@types/react@18.3.18)(react@18.3.1) + '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1) + + '@mui/system@6.4.3(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.9 + '@mui/private-theming': 6.4.3(@types/react@18.3.18)(react@18.3.1) + '@mui/styled-engine': 6.4.3(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1))(react@18.3.1) + '@mui/types': 7.2.21(@types/react@18.3.18) + '@mui/utils': 6.4.3(@types/react@18.3.18)(react@18.3.1) + clsx: 2.1.1 + csstype: 3.1.3 + prop-types: 15.8.1 + react: 18.3.1 + optionalDependencies: + '@emotion/react': 11.14.0(@types/react@18.3.18)(react@18.3.1) + '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1))(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + + '@mui/types@7.2.21(@types/react@18.3.18)': + optionalDependencies: + '@types/react': 18.3.18 + + '@mui/utils@6.4.3(@types/react@18.3.18)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.9 + '@mui/types': 7.2.21(@types/react@18.3.18) + '@types/prop-types': 15.7.14 + clsx: 2.1.1 + prop-types: 15.8.1 + react: 18.3.1 + react-is: 19.0.0 + optionalDependencies: + '@types/react': 18.3.18 + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -6263,6 +6473,8 @@ snapshots: '@pnpm/network.ca-file': 1.0.2 config-chain: 1.1.13 + '@popperjs/core@2.11.8': {} + '@protobufjs/aspromise@1.1.2': {} '@protobufjs/base64@1.1.2': {} @@ -6598,6 +6810,10 @@ snapshots: dependencies: '@types/react': 18.3.18 + '@types/react-transition-group@4.4.12(@types/react@18.3.18)': + dependencies: + '@types/react': 18.3.18 + '@types/react@18.3.18': dependencies: '@types/prop-types': 15.7.14 @@ -7401,6 +7617,11 @@ snapshots: dependencies: esutils: 2.0.3 + dom-helpers@5.2.1: + dependencies: + '@babel/runtime': 7.26.9 + csstype: 3.1.3 + dom-serializer@2.0.0: dependencies: domelementtype: 2.3.0 @@ -9417,6 +9638,8 @@ snapshots: react-is@16.13.1: {} + react-is@19.0.0: {} + react-screen-wake-lock@3.0.2(react@18.3.1): dependencies: react: 18.3.1 @@ -9425,6 +9648,19 @@ snapshots: dependencies: react: 18.3.1 + react-timer-hook@3.0.8(react@18.3.1): + dependencies: + react: 18.3.1 + + react-transition-group@4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.9 + dom-helpers: 5.2.1 + loose-envify: 1.4.0 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-twc@1.4.2(@types/react@18.3.18)(react@18.3.1): dependencies: '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1) diff --git a/src/Components/Misc/Timer/NegativeStopWatch.tsx b/src/Components/Misc/Timer/NegativeStopWatch.tsx new file mode 100644 index 0000000..f7073ef --- /dev/null +++ b/src/Components/Misc/Timer/NegativeStopWatch.tsx @@ -0,0 +1,28 @@ +import { useStopwatch } from 'react-timer-hook'; +import { TimerStyle, TimerWrapper } from './Timer'; +import { Time } from './Time'; + +export const NegativeStopWatch = ({ + autoStart = false, +}: { + autoStart?: boolean; +}) => { + // Initialize the timer using the useTimer hook. + const { seconds, minutes, hours, isRunning, start, pause } = useStopwatch({ + autoStart, + }); + + return ( + + + {'-'} + + + ); +}; diff --git a/src/Components/Misc/Timer/Time.tsx b/src/Components/Misc/Timer/Time.tsx new file mode 100644 index 0000000..f3430fb --- /dev/null +++ b/src/Components/Misc/Timer/Time.tsx @@ -0,0 +1,9 @@ +import { formatTime } from '../../../Utils/formatTime'; + +export const Time = ({ + time, +}: { + time: { hours: number; minutes: number; seconds: number }; +}) => { + return
{formatTime({ time })}
; +}; diff --git a/src/Components/Misc/Timer/Timer.tsx b/src/Components/Misc/Timer/Timer.tsx new file mode 100644 index 0000000..fd30988 --- /dev/null +++ b/src/Components/Misc/Timer/Timer.tsx @@ -0,0 +1,85 @@ +import { useState } from 'react'; +import { useTimer } from 'react-timer-hook'; +import { NegativeStopWatch } from './NegativeStopWatch'; +import { twc } from 'react-twc'; +import PauseIcon from '@mui/icons-material/Pause'; +import RestartAltIcon from '@mui/icons-material/RestartAlt'; +import PlayArrowIcon from '@mui/icons-material/PlayArrow'; +import { Time } from './Time'; + +export const TimerWrapper = twc.div` +absolute z-50 top-0 w-screen flex items-center flex-col +`; + +export const TimerStyle = twc.div` +flex gap-2 bg-interface-recentDifference-background py-1 px-4 rounded-full +`; + +const TIMER_MINUTES = 50; + +export const Timer = () => { + // Set the default expiry time to 50 minutes from now. + const defaultExpiry = new Date(); + defaultExpiry.setMinutes(defaultExpiry.getMinutes() + TIMER_MINUTES); + + const [hasStarted, setHasStarted] = useState(false); + + // Initialize the timer using the useTimer hook. + const { seconds, minutes, hours, isRunning, start, pause, restart } = + useTimer({ + expiryTimestamp: defaultExpiry, + onExpire: () => console.warn('Timer expired'), + autoStart: false, + }); + + // Function to restart the timer for 50 minutes. + const handleRestart = () => { + const time = new Date(); + time.setMinutes(time.getMinutes() + TIMER_MINUTES); + restart(time); + }; + + const handleStart = () => { + setHasStarted(true); + start(); + }; + + const handlePause = () => { + setHasStarted(false); + pause(); + }; + + if (hasStarted && !isRunning) { + return ; + } + + return ( + + + + + ); +}; diff --git a/src/Components/Players/Players.tsx b/src/Components/Players/Players.tsx index 262828e..fbfa16e 100644 --- a/src/Components/Players/Players.tsx +++ b/src/Components/Players/Players.tsx @@ -6,6 +6,7 @@ import { PreStartMode } from '../../Types/Settings'; import LifeCounter from '../LifeCounter/LifeCounter'; import { RoulettePlayerCard } from '../PreStartGame/Games/RandomKing/RoulettePlayerCard'; import { GridLayout } from '../Views/Play'; +import { Timer } from '../Misc/Timer/Timer'; const getGridArea = (player: PlayerType) => { switch (player.index) { @@ -36,6 +37,7 @@ export const Players = ({ gridLayout }: { gridLayout: GridLayout }) => { return (
+ {players.map((player) => { const gridArea = getGridArea(player); return ( diff --git a/src/Components/Views/Play.tsx b/src/Components/Views/Play.tsx index 6b83c97..ac952da 100644 --- a/src/Components/Views/Play.tsx +++ b/src/Components/Views/Play.tsx @@ -19,6 +19,7 @@ export const Play = () => { useGlobalSettings(); let gridLayout: GridLayout; + switch (players.length) { case 1: if (initialGameSettings?.orientation === Orientation.Portrait) { @@ -101,7 +102,6 @@ export const Play = () => { settings.preStartMode !== PreStartMode.None && !playing && settings.showStartingPlayer && } - ); diff --git a/src/Utils/formatTime.ts b/src/Utils/formatTime.ts new file mode 100644 index 0000000..c7b388b --- /dev/null +++ b/src/Utils/formatTime.ts @@ -0,0 +1,17 @@ +export const formatTime = ({ + time, +}: { + time: { hours: number; minutes: number; seconds: number }; +}) => { + const h = time.hours.toString().padStart(2, '0'); + const m = time.minutes.toString().padStart(2, '0'); + const s = time.seconds.toString().padStart(2, '0'); + + if (time.hours > 0) { + return `${h}:${m}:${s}`; + } else if (time.minutes > 0) { + return `${m}:${s}`; + } else { + return s; + } +};