From b1081ecce11e140df97de72f2768449d836c1ef8 Mon Sep 17 00:00:00 2001 From: Diptesh Choudhuri Date: Thu, 25 Jul 2024 10:40:27 +0530 Subject: [PATCH] feat(frontend): get timer working --- apps/frontend/app/lib/hooks.ts | 7 +++ .../app/routes/_dashboard.fitness.$action.tsx | 48 ++++++++++--------- apps/frontend/package.json | 1 + yarn.lock | 12 +++++ 4 files changed, 45 insertions(+), 23 deletions(-) diff --git a/apps/frontend/app/lib/hooks.ts b/apps/frontend/app/lib/hooks.ts index 8faebb98b5..d747511e3c 100644 --- a/apps/frontend/app/lib/hooks.ts +++ b/apps/frontend/app/lib/hooks.ts @@ -1,6 +1,7 @@ import type Umami from "@bitprojects/umami-logger-typescript"; import { $path } from "@ignisda/remix-routes"; import { useComputedColorScheme, useMantineTheme } from "@mantine/core"; +import { useForceUpdate } from "@mantine/hooks"; import { useNavigate, useRouteLoaderData, @@ -11,6 +12,7 @@ import type { EntityLot } from "@ryot/generated/graphql/backend/graphql"; import { useQuery } from "@tanstack/react-query"; import Cookies from "js-cookie"; import type { FormEvent } from "react"; +import { useInterval } from "usehooks-ts"; import { CurrentWorkoutKey, getMetadataDetailsQuery, @@ -170,3 +172,8 @@ export const useApplicationEvents = () => { addToCollection, }; }; + +export const forceUpdateEverySecond = () => { + const forceUpdate = useForceUpdate(); + useInterval(forceUpdate, 1000); +}; diff --git a/apps/frontend/app/routes/_dashboard.fitness.$action.tsx b/apps/frontend/app/routes/_dashboard.fitness.$action.tsx index e1e3229c46..1e4b364644 100644 --- a/apps/frontend/app/routes/_dashboard.fitness.$action.tsx +++ b/apps/frontend/app/routes/_dashboard.fitness.$action.tsx @@ -36,7 +36,6 @@ import { useDebouncedState, useDidUpdate, useDisclosure, - useInterval, useListState, useToggle, } from "@mantine/hooks"; @@ -78,7 +77,7 @@ import { Howl } from "howler"; import { produce } from "immer"; import { RESET } from "jotai/utils"; import Cookies from "js-cookie"; -import { useRef, useState } from "react"; +import { useRef } from "react"; import Webcam from "react-webcam"; import { ClientOnly } from "remix-utils/client-only"; import { namedAction } from "remix-utils/named-action"; @@ -100,6 +99,7 @@ import { queryFactory, } from "~/lib/generals"; import { + forceUpdateEverySecond, useApplicationEvents, useCoreDetails, useUserPreferences, @@ -120,6 +120,7 @@ import { redirectWithToast, serverGqlService, } from "~/lib/utilities.server"; +import { useInterval } from "usehooks-ts"; const workoutCookieName = CurrentWorkoutKey; const defaultTimerLocalStorageKey = "DefaultExerciseRestTimer"; @@ -190,7 +191,6 @@ export default function Page() { const events = useApplicationEvents(); const [parent] = useAutoAnimate(); const navigate = useNavigate(); - const [_t, setTime] = useState(0); const [currentWorkout, setCurrentWorkout] = useCurrentWorkout(); const playCompleteTimerSound = () => { const sound = new Howl({ src: ["/timer-completed.mp3"] }); @@ -211,22 +211,17 @@ export default function Page() { const [_, setMeasurementsDrawerOpen] = useMeasurementsDrawerOpen(); const [currentTimer, setCurrentTimer] = useTimerAtom(); - useInterval( - () => { - setTime((s) => s + 1); - const timeRemaining = currentTimer?.endAt.diff(dayjsLib(), "second"); - if (timeRemaining && timeRemaining <= 3) { - if (navigator.vibrate) navigator.vibrate(200); - if (timeRemaining <= 1) { - playCompleteTimerSound(); - timerDrawerClose(); - stopTimer(); - } + useInterval(() => { + const timeRemaining = currentTimer?.endAt.diff(dayjsLib(), "second"); + if (timeRemaining && timeRemaining <= 3) { + if (navigator.vibrate) navigator.vibrate(200); + if (timeRemaining <= 1) { + playCompleteTimerSound(); + timerDrawerClose(); + stopTimer(); } - }, - 1000, - { autoInvoke: true }, - ); + } + }, 1000); const startTimer = ( duration: number, @@ -347,11 +342,7 @@ export default function Page() { onClick={timerDrawerToggle} style={isCreatingTemplate ? { display: "none" } : undefined} > - {currentTimer - ? dayjsLib - .duration(currentTimer.endAt.diff(dayjsLib())) - .format("m:ss") - : "Timer"} + {currentWorkout.exercises.length > 1 ? ( <> @@ -511,7 +502,17 @@ const offsetDate = (startTime?: string) => { return now.diff(dayjsLib(startTime), "seconds"); }; +const RestTimer = () => { + forceUpdateEverySecond(); + const [currentTimer] = useTimerAtom(); + + return currentTimer + ? dayjsLib.duration(currentTimer.endAt.diff(dayjsLib())).format("m:ss") + : "Timer"; +}; + const DurationTimer = () => { + forceUpdateEverySecond(); const [currentWorkout] = useCurrentWorkout(); const seconds = offsetDate(currentWorkout?.startTime); const { isCreatingTemplate } = useLoaderData(); @@ -1362,6 +1363,7 @@ const TimerDrawer = (props: { stopTimer: () => void; startTimer: (duration: number) => void; }) => { + forceUpdateEverySecond(); const [currentTimer, setCurrentTimer] = useTimerAtom(); return ( diff --git a/apps/frontend/package.json b/apps/frontend/package.json index a6c7283b03..d808b11324 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -73,6 +73,7 @@ "postcss-simple-vars": "7.0.1", "ts-essentials": "10.0.1", "typescript-plugin-css-modules": "5.1.0", + "usehooks-ts": "3.1.0", "vite": "5.3.4", "vite-tsconfig-paths": "4.3.2" }, diff --git a/yarn.lock b/yarn.lock index 232dc9b69e..2514e68f46 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3538,6 +3538,7 @@ __metadata: ts-pattern: "npm:5.2.0" typescript-plugin-css-modules: "npm:5.1.0" ufo: "npm:1.5.4" + usehooks-ts: "npm:3.1.0" uuid: "npm:10.0.0" vite: "npm:5.3.4" vite-tsconfig-paths: "npm:4.3.2" @@ -12013,6 +12014,17 @@ __metadata: languageName: node linkType: hard +"usehooks-ts@npm:3.1.0": + version: 3.1.0 + resolution: "usehooks-ts@npm:3.1.0" + dependencies: + lodash.debounce: "npm:^4.0.8" + peerDependencies: + react: ^16.8.0 || ^17 || ^18 + checksum: 10/6aef8affd3c053a3040b7421816dab85eb21601c5203496a705bafc32eb973fb519a2b0ddda527962e361d248f3a1c49df130620efe871c8f89e897451ed1cc7 + languageName: node + linkType: hard + "util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2"