diff --git a/packages/app/features/home/TokenBalanceCard.tsx b/packages/app/features/home/TokenBalanceCard.tsx
index 6c3849ff6..e4517177d 100644
--- a/packages/app/features/home/TokenBalanceCard.tsx
+++ b/packages/app/features/home/TokenBalanceCard.tsx
@@ -8,7 +8,6 @@ import {
BigHeading,
styled,
AnimatePresence,
- View,
type XStackProps,
} from '@my/ui'
import { EyeOff, Eye } from '@tamagui/lucide-icons'
@@ -16,6 +15,7 @@ import formatAmount from 'app/utils/formatAmount'
import { useSendAccountBalances } from 'app/utils/useSendAccountBalances'
import AsyncStorage from '@react-native-async-storage/async-storage'
import { useEffect, useState } from 'react'
+import { type Timer, useStopwatch } from 'react-use-precision-timer'
const GreenSquare = styled(Stack, {
name: 'Surface',
@@ -39,7 +39,8 @@ export const TokenBalanceCard = () => {
const formattedBalance = formatAmount(totalBalance, 9, 0)
const { isPriceHidden, toggleIsPriceHidden } = useIsPriceHidden()
- const { isGameVisible, presses, increaseScore, time } = useShowHideGame()
+ const timer = useStopwatch()
+ const { isGameVisible, presses, increaseScore } = useShowHideGame(timer)
const onShowHidePress = () => {
toggleIsPriceHidden()
@@ -77,7 +78,7 @@ export const TokenBalanceCard = () => {
{presses}
-
+
)}
@@ -171,47 +172,35 @@ const useIsPriceHidden = () => {
return { isPriceHidden, toggleIsPriceHidden }
}
-const useShowHideGame = () => {
+const useShowHideGame = (timer: Timer) => {
const countToStop = 100
const countToVisible = 10
const [isGameVisible, setIsGameVisible] = useState(false)
const [presses, setPresses] = useState(0)
- const [isPaused, setIsPaused] = useState(false)
- const [time, setTime] = useState(0)
-
- useEffect(() => {
- if (presses >= countToVisible) {
- setIsGameVisible(true)
- }
- if (presses >= countToStop) {
- setIsPaused(true)
+ const onPress = () => {
+ if (!timer.isRunning() && presses < countToStop) {
+ timer.start()
+ setPresses(presses + 1)
+ return
}
- let interval: NodeJS.Timeout | undefined = undefined
- if (isPaused === false) {
- interval = setInterval(() => {
- setTime((time) => time + 10)
- }, 10)
- } else {
- clearInterval(interval)
- }
- return () => {
- clearInterval(interval)
+ if (presses >= countToStop) {
+ timer.pause()
+ return
}
- }, [presses, isPaused])
-
- const onPress = () => {
- if (isPaused === false) {
- setPresses(presses + 1)
+ if (presses >= countToVisible && !isGameVisible) {
+ setIsGameVisible(true)
}
+ setPresses(presses + 1)
}
- return { isGameVisible, presses, increaseScore: onPress, time }
+ return { isGameVisible, presses, increaseScore: onPress }
}
-const ShowHideGameStopwatch = ({ time, ...props }: XStackProps & { time: number }) => {
+const ShowHideGameStopwatch = ({ timer, ...props }: XStackProps & { timer: Timer }) => {
+ const time = timer.getElapsedRunningTime()
return (
-
- Total Balance
-
+
+
+
+ Total Balance
+
+
+
+
+
+
+
+
+
({
useNav: jest.fn().mockReturnValue([undefined, jest.fn()]),
}))
+jest.mock('@react-native-async-storage/async-storage', () => ({
+ getItem: jest.fn().mockReturnValue(Promise.resolve(null)),
+ setItem: jest.fn().mockReturnValue(Promise.resolve()),
+}))
+
+jest.mock('react-use-precision-timer', () => ({
+ useStopwatch: jest.fn().mockReturnValue({
+ isRunning: jest.fn().mockReturnValue(false),
+ start: jest.fn(),
+ pause: jest.fn(),
+ getElapsedRunningTime: jest.fn().mockReturnValue(0),
+ }),
+}))
+
jest.mock('solito', () => {
// console.log('mock solito')
const mockCreateParam = jest.fn(() => {
diff --git a/packages/app/package.json b/packages/app/package.json
index 778dd0b6c..372960629 100644
--- a/packages/app/package.json
+++ b/packages/app/package.json
@@ -58,6 +58,7 @@
"react-native": "0.74.1",
"react-native-safe-area-context": "4.8.2",
"react-native-svg": "15.2.0",
+ "react-use-precision-timer": "^3.5.5",
"solito": "^4.0.1",
"superjson": "^1.13.1",
"viem": "^2.18.2",
diff --git a/yarn.lock b/yarn.lock
index e00a9899f..7a1f40e2f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -14230,6 +14230,7 @@ __metadata:
react-native-safe-area-context: "npm:4.8.2"
react-native-svg: "npm:15.2.0"
react-test-renderer: "npm:^18.3.1"
+ react-use-precision-timer: "npm:^3.5.5"
solito: "npm:^4.0.1"
superjson: "npm:^1.13.1"
typescript: "npm:^5.5.3"
@@ -30129,6 +30130,16 @@ __metadata:
languageName: node
linkType: hard
+"react-sub-unsub@npm:^2.2.2":
+ version: 2.2.7
+ resolution: "react-sub-unsub@npm:2.2.7"
+ peerDependencies:
+ react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0
+ react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0
+ checksum: 10/684f9ec88af0be9e27c3112480e47ef54060af13e5adb0cf7988ac2599bf29e12fcbeca3e8067270216b1add805a063cbd6abae20f1dd0b65b5d689afd3b66d7
+ languageName: node
+ linkType: hard
+
"react-test-renderer@npm:18.2.0":
version: 18.2.0
resolution: "react-test-renderer@npm:18.2.0"
@@ -30155,6 +30166,18 @@ __metadata:
languageName: node
linkType: hard
+"react-use-precision-timer@npm:^3.5.5":
+ version: 3.5.5
+ resolution: "react-use-precision-timer@npm:3.5.5"
+ dependencies:
+ react-sub-unsub: "npm:^2.2.2"
+ peerDependencies:
+ react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0
+ react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0
+ checksum: 10/e0abf3fc915207ac57b58b7eb2df0ed178b399dc8b082443cbb44177756e2d480193d07c99bc2fe1de6d254deb68d9f08e940f2473069f233b6ac08653041451
+ languageName: node
+ linkType: hard
+
"react@npm:^18.2.0":
version: 18.2.0
resolution: "react@npm:18.2.0"