Merge branch 'add-background-timer' into 'main'

feat: add timer in background

See merge request torpenn/boxons!7
merge-requests/10/head
Torpenn 2024-10-20 08:19:20 +00:00
commit 47f3237e50
4 changed files with 137 additions and 27 deletions

View File

@ -22,7 +22,10 @@ export default {
"foregroundImage": "./assets/images/adaptive-icon.png",
"backgroundColor": "#ffffff"
},
"package": "com.torpenn.boxons"
"package": "com.torpenn.boxons",
"permissions": [
"FOREGROUND_SERVICE"
]
},
"web": {
"bundler": "metro",

View File

@ -10,6 +10,7 @@ import { Audio } from 'expo-av';
import { Sound } from 'expo-av/build/Audio';
import { activateKeepAwakeAsync, deactivateKeepAwake } from 'expo-keep-awake';
import { loadUserSettings } from '@/components/shared/business/AsyncStorage';
import BackgroundTimer from 'react-native-background-timer';
interface TimerProps {
reps: number;
@ -57,36 +58,24 @@ export default function Timer() {
}, [navigation]);
useEffect(() => {
let timer: NodeJS.Timeout;
let timerId: number | null = null;
if (isRunning && timeLeft > 0) {
timer = setTimeout(() => {
setTimeLeft(timeLeft - 1);
}, 1000);
// Utilisation de BackgroundTimer pour gérer le timer même en arrière-plan
timerId = BackgroundTimer.setInterval(() => {
setTimeLeft((prevTime) => prevTime - 1);
}, 1000); // Timer d'une seconde
} else if (isRunning && timeLeft === 0) {
if (currentRep < reps) {
if (isWorkPhase) {
// If the work phase is over, move on to the rest phase
playSound()
setIsWorkPhase(false);
setTimeLeft(restTime);
} else {
// If the rest phase is complete, move on to the next work phase
playSound()
setIsWorkPhase(true);
setTimeLeft(workTime);
setCurrentRep(currentRep + 1);
}
} else {
// Done
playSound();
setIsRunning(false);
setIsFinish(true);
}
nextRep(); // Passe à la répétition suivante
}
return () => clearTimeout(timer);
}, [isRunning, timeLeft, currentRep, isWorkPhase, reps, workTime, restTime]);
return () => {
// Nettoyage du timer lorsqu'il est arrêté ou que le composant est démonté
if (timerId !== null) {
BackgroundTimer.clearInterval(timerId);
}
};
}, [isRunning, timeLeft]);
const handleStart = () => {
setCurrentRep(1);
@ -126,14 +115,17 @@ export default function Timer() {
const nextRep = () => {
if (currentRep < reps) {
if (isWorkPhase) {
playSound();
setIsWorkPhase(false);
setTimeLeft(restTime);
} else {
playSound();
setIsWorkPhase(true);
setTimeLeft(workTime);
setCurrentRep((prevRep) => prevRep + 1);
}
} else {
playSound();
setIsFinish(true);
setIsRunning(false);
}

114
package-lock.json generated
View File

@ -17,6 +17,7 @@
"@testing-library/react-native": "^12.7.2",
"expo": "~51.0.37",
"expo-av": "~14.0.7",
"expo-dev-client": "~4.0.28",
"expo-font": "~12.0.9",
"expo-keep-awake": "~13.0.2",
"expo-linking": "~6.3.1",
@ -30,6 +31,7 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"react-native": "0.74.5",
"react-native-background-timer": "^2.4.1",
"react-native-dropdown-picker": "^5.4.6",
"react-native-linear-gradient": "^2.8.3",
"react-native-reanimated": "~3.10.1",
@ -42,6 +44,7 @@
"@babel/core": "^7.20.0",
"@testing-library/jest-native": "^5.4.3",
"@types/react": "~18.2.45",
"@types/react-native-background-timer": "^2.0.2",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0",
"dotenv": "^16.4.5",
@ -7957,6 +7960,13 @@
"csstype": "^3.0.2"
}
},
"node_modules/@types/react-native-background-timer": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@types/react-native-background-timer/-/react-native-background-timer-2.0.2.tgz",
"integrity": "sha512-cMAep0M5yqUHjiiRPvGiviqiJYdI45KSjbI5ufsIFSQGFwHwrHJC/8yawNhy0G3Gix6fufWLsEj6jC5niUNHiQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/semver": {
"version": "7.5.8",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
@ -12019,6 +12029,100 @@
"expo": "*"
}
},
"node_modules/expo-dev-client": {
"version": "4.0.28",
"resolved": "https://registry.npmjs.org/expo-dev-client/-/expo-dev-client-4.0.28.tgz",
"integrity": "sha512-wz5G4vY3Gbk5GuQTyijdqY4Hwr/NDt5OUTErbOu1vd4XRIAsI+8IkK5hsBUhGmqrdkYnP5NxxOxC/soFzX/9+w==",
"license": "MIT",
"dependencies": {
"expo-dev-launcher": "4.0.28",
"expo-dev-menu": "5.0.22",
"expo-dev-menu-interface": "1.8.3",
"expo-manifests": "~0.14.0",
"expo-updates-interface": "~0.16.2"
},
"peerDependencies": {
"expo": "*"
}
},
"node_modules/expo-dev-launcher": {
"version": "4.0.28",
"resolved": "https://registry.npmjs.org/expo-dev-launcher/-/expo-dev-launcher-4.0.28.tgz",
"integrity": "sha512-goE7jcaGVA2zu4gV3/hQ9RXqGhUZZAu339VYNLbwPdaNCzFaG6A8MZHg18gytCUnZ5QkRJsYi4q/8YcwUCASlQ==",
"license": "MIT",
"dependencies": {
"ajv": "8.11.0",
"expo-dev-menu": "5.0.22",
"expo-manifests": "~0.14.0",
"resolve-from": "^5.0.0",
"semver": "^7.6.0"
},
"peerDependencies": {
"expo": "*"
}
},
"node_modules/expo-dev-launcher/node_modules/ajv": {
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
"integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/expo-dev-launcher/node_modules/semver": {
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/expo-dev-menu": {
"version": "5.0.22",
"resolved": "https://registry.npmjs.org/expo-dev-menu/-/expo-dev-menu-5.0.22.tgz",
"integrity": "sha512-VzpdQReAtjbI1qIuwOf0sUzf91HsfGThojgJD9Ez0eca12qY5tTGYzHa1EM9V+zIcNuNZ7+A8bHJJdmZ4zvU6g==",
"license": "MIT",
"dependencies": {
"expo-dev-menu-interface": "1.8.3",
"semver": "^7.5.4"
},
"peerDependencies": {
"expo": "*"
}
},
"node_modules/expo-dev-menu-interface": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/expo-dev-menu-interface/-/expo-dev-menu-interface-1.8.3.tgz",
"integrity": "sha512-QM0LRozeFT5Ek0N7XpV93M+HMdEKRLEOXn0aW5M3uoUlnqC1+PLtF3HMy3k3hMKTTE/kJ1y1Z7akH07T0lunCQ==",
"license": "MIT",
"peerDependencies": {
"expo": "*"
}
},
"node_modules/expo-dev-menu/node_modules/semver": {
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/expo-eas-client": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/expo-eas-client/-/expo-eas-client-0.12.0.tgz",
@ -19878,6 +19982,15 @@
}
}
},
"node_modules/react-native-background-timer": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/react-native-background-timer/-/react-native-background-timer-2.4.1.tgz",
"integrity": "sha512-TE4Kiy7jUyv+hugxDxitzu38sW1NqjCk4uE5IgU2WevLv7sZacaBc6PZKOShNRPGirLl1NWkaG3LDEkdb9Um5g==",
"license": "MIT",
"peerDependencies": {
"react-native": ">=0.47.0"
}
},
"node_modules/react-native-dropdown-picker": {
"version": "5.4.6",
"resolved": "https://registry.npmjs.org/react-native-dropdown-picker/-/react-native-dropdown-picker-5.4.6.tgz",
@ -22401,7 +22514,6 @@
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"punycode": "^2.1.0"

View File

@ -33,6 +33,7 @@
"@testing-library/react-native": "^12.7.2",
"expo": "~51.0.37",
"expo-av": "~14.0.7",
"expo-dev-client": "~4.0.28",
"expo-font": "~12.0.9",
"expo-keep-awake": "~13.0.2",
"expo-linking": "~6.3.1",
@ -46,6 +47,7 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"react-native": "0.74.5",
"react-native-background-timer": "^2.4.1",
"react-native-dropdown-picker": "^5.4.6",
"react-native-linear-gradient": "^2.8.3",
"react-native-reanimated": "~3.10.1",
@ -58,6 +60,7 @@
"@babel/core": "^7.20.0",
"@testing-library/jest-native": "^5.4.3",
"@types/react": "~18.2.45",
"@types/react-native-background-timer": "^2.0.2",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0",
"dotenv": "^16.4.5",