diff --git a/App.tsx b/App.tsx
index 0329d0c..f8a0251 100644
--- a/App.tsx
+++ b/App.tsx
@@ -1,11 +1,15 @@
import { StatusBar } from 'expo-status-bar';
-import { StyleSheet, Text, View } from 'react-native';
+import { StyleSheet, Text, View, Dimensions } from 'react-native';
+import StopWatch from './src/StopWatch';
+
+const screenHeight = Dimensions.get('window').height;
+const screenWidth = Dimensions.get('window').width;
+
export default function App() {
return (
- Open up App.tsx to start working on your app!
-
+
);
}
@@ -13,7 +17,7 @@ export default function App() {
const styles = StyleSheet.create({
container: {
flex: 1,
- backgroundColor: '#fff',
+ backgroundColor: '#00B09F',
alignItems: 'center',
justifyContent: 'center',
},
diff --git a/assets/fonts/CuteFont-Regular.ttf b/assets/fonts/CuteFont-Regular.ttf
new file mode 100644
index 0000000..d07b849
Binary files /dev/null and b/assets/fonts/CuteFont-Regular.ttf differ
diff --git a/assets/fonts/SingleDay-Regular.ttf b/assets/fonts/SingleDay-Regular.ttf
new file mode 100644
index 0000000..c70da6b
Binary files /dev/null and b/assets/fonts/SingleDay-Regular.ttf differ
diff --git a/package-lock.json b/package-lock.json
index ea36168..2ef206c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,8 +12,10 @@
"expo-status-bar": "~1.6.0",
"jest": "^29.2.1",
"jest-expo": "~49.0.0",
+ "link": "^2.1.0",
"react": "18.2.0",
- "react-native": "0.72.6"
+ "react-native": "^0.72.6",
+ "react-native-triangle": "^0.0.9"
},
"devDependencies": {
"@babel/core": "^7.20.0",
@@ -8571,6 +8573,15 @@
"node": ">=8"
}
},
+ "node_modules/create-react-class": {
+ "version": "15.7.0",
+ "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.7.0.tgz",
+ "integrity": "sha512-QZv4sFWG9S5RUvkTYWbflxeZX+JG7Cz0Tn33rQBJ+WFQTqTfUTjMjiv9tnfXazjsO5r0KhPs+AqCjyrQX6h2ng==",
+ "dependencies": {
+ "loose-envify": "^1.3.1",
+ "object-assign": "^4.1.1"
+ }
+ },
"node_modules/cross-fetch": {
"version": "3.1.8",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz",
@@ -14231,6 +14242,17 @@
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
},
+ "node_modules/link": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/link/-/link-2.1.0.tgz",
+ "integrity": "sha512-6jgX7ejPBOQaKsFY/9aFEg0HW0JyFuMGDoN+KQX1W94t+8Fi5xwlSlGouRMDqDlrE46drqu4PYduAG7tUwdF7Q==",
+ "bin": {
+ "link": "dist/cli.js"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/link?sponsor=1"
+ }
+ },
"node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@@ -16527,6 +16549,15 @@
"react": "18.2.0"
}
},
+ "node_modules/react-native-triangle": {
+ "version": "0.0.9",
+ "resolved": "https://registry.npmjs.org/react-native-triangle/-/react-native-triangle-0.0.9.tgz",
+ "integrity": "sha512-XoZGXXoQ6UDqbRnvsMzFFREBEcta/kKkwCgKqw13cLJvIYQBhvASrn3Un/4aF/jPYLyWtdztiEHuMpx0tMxQrA==",
+ "dependencies": {
+ "create-react-class": "^15.6.0",
+ "prop-types": "^15.5.10"
+ }
+ },
"node_modules/react-native/node_modules/promise": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz",
diff --git a/package.json b/package.json
index bf0f5a3..de725d0 100644
--- a/package.json
+++ b/package.json
@@ -12,10 +12,12 @@
"dependencies": {
"expo": "~49.0.15",
"expo-status-bar": "~1.6.0",
- "react": "18.2.0",
- "react-native": "0.72.6",
+ "jest": "^29.2.1",
"jest-expo": "~49.0.0",
- "jest": "^29.2.1"
+ "link": "^2.1.0",
+ "react": "18.2.0",
+ "react-native": "^0.72.6",
+ "react-native-triangle": "^0.0.9"
},
"devDependencies": {
"@babel/core": "^7.20.0",
diff --git a/react-native.config.js b/react-native.config.js
new file mode 100644
index 0000000..f25a142
--- /dev/null
+++ b/react-native.config.js
@@ -0,0 +1,7 @@
+module.exports = {
+ project: {
+ ios: {},
+ android: {},
+ },
+ assets: ['./assets/fonts'],
+};
\ No newline at end of file
diff --git a/src/StopWatch.tsx b/src/StopWatch.tsx
index 5c7eb74..4828133 100644
--- a/src/StopWatch.tsx
+++ b/src/StopWatch.tsx
@@ -1,8 +1,216 @@
-import { View } from 'react-native';
+import React, { useEffect, useState, useRef } from 'react';
+import { View, Text, Button, ScrollView, StyleSheet, Dimensions } from 'react-native';
+
+const screenHeight = Dimensions.get('window').height;
+const screenWidth = Dimensions.get('window').width;
export default function StopWatch() {
+
+ // formatting for timer 00:00.00
+ const formatTime = (milliseconds: number) => {
+ const minutes = Math.floor(milliseconds / (60 * 1000));
+ const seconds = Math.floor((milliseconds % (60 * 1000)) / 1000);
+ const ms = Math.floor((milliseconds % 1000) / 10);
+
+ return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}:${String(ms).padStart(2, '0')}`;
+ };
+
+ const [intervalId, setIntervalId] = useState(null);
+ const [timer, setTimer] = useState(0);
+ const [time, setTime] = useState(formatTime(timer));
+ const [laps, setLaps] = useState([]);
+ const [buttonName, setButtonName] = useState('START');
+ const timerRef = useRef(timer);
+
+ // for styling
+ const scrollViewRef = useRef();
+ const handleContentSizeChange = (contentWidth?: number, contentHeight?: number) => {
+ scrollViewRef.current?.scrollToEnd({ animated: true });
+ };
+
+
+ const startTimer = () => {
+ if (intervalId === null) {
+ const interval = setInterval(handleTimer, 10);
+ setIntervalId(interval);
+ setButtonName('LAP');
+ } else {
+ setLaps(oldLapTimes => [...oldLapTimes, formatTime(timerRef.current)]);
+ }
+ };
+
+ const handleTimer = () => {
+ timerRef.current += 10;
+ setTime(formatTime(timerRef.current));
+ };
+
+ const stopTimer = () => {
+ if (intervalId !== null) {
+ clearInterval(intervalId);
+ setIntervalId(null);
+ setButtonName('START');
+ }
+ };
+
+ const resetTimer = () => {
+ stopTimer();
+ timerRef.current = 0;
+ setTime(formatTime(timerRef.current));
+ setLaps([]);
+ };
+
return (
-
-
- );
-}
\ No newline at end of file
+
+
+ {time}
+
+
+
+
+
+
+
+
+
+ {laps.map((lap, index) => (
+ {lap}
+ ))}
+
+
+
+
+
+
+
+
+
+
+ SMO
+
+
+
+
+);
+}
+
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ backgroundColor: '#00B09F',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+
+ timerText: {
+ fontSize: 60,
+ },
+
+ timerFace: {
+ width: screenWidth / 1.2,
+ height: screenHeight / 3,
+ backgroundColor: '#AFE0C9',
+ position: 'relative',
+ borderBlockStyle: 'solid black',
+ borderWidth: 6,
+ borderRadius: 25,
+ overflow: 'scroll',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+
+ buttonContainer:{
+ top:'18%',
+ left: 40,
+ },
+
+ startButton: {
+ width: 50,
+ height: 50,
+ backgroundColor: '#43C251',
+ borderRadius: 25,
+ justifyContent: 'center',
+ borderWidth: 3,
+ borderColor: 'black',
+ left: '65%',
+ },
+
+ stopButton: {
+ width: 80,
+ height: 80,
+ backgroundColor: '#FF1A3C',
+ borderRadius: 40,
+ justifyContent: 'center',
+ borderWidth: 3,
+ borderColor: 'black',
+ left: '45%',
+ },
+
+ resetButton: {
+ width: 30,
+ height: 30,
+ backgroundColor: "#00C4E3",
+ justifyContent: 'center',
+ borderWidth: 3,
+ borderColor: 'black',
+ left: '45%',
+ bottom: '55%'
+ },
+
+ lapBar: {
+ width: 130,
+ height: 80,
+ backgroundColor: '#005435',
+ borderRadius: 20,
+ justifyContent: 'center',
+ alignItems:'center',
+ overflow: 'scroll',
+ borderWidth: 3,
+ borderColor: 'black',
+ right: '8%',
+ bottom: '95%',
+ },
+
+ lapText:{
+ fontSize: 20,
+ width: 100,
+ fontStyle: 'italic',
+ textAlign: "center",
+ },
+
+ cross: {
+ width: 0,
+ height: 0,
+ bottom:'18%',
+ left: 60,
+ },
+ crossUp: {
+ backgroundColor: "yellow",
+ height: 100,
+ width: 40,
+ borderWidth: 3,
+ borderColor: 'black',
+ },
+ crossFlat: {
+ backgroundColor: "yellow",
+ height: 40,
+ width: 100,
+ position: "absolute",
+ left: -30,
+ top: 30,
+ borderWidth: 3,
+ borderColor: 'black',
+ },
+
+ label: {
+ height:'auto',
+ width: 'auto',
+ textAlign: 'center',
+ fontSize: 50,
+ fontWeight: '900',
+ marginTop: 40,
+ marginBottom: -30,
+ },
+ }
+
+);
diff --git a/src/StopWatchButton.tsx b/src/StopWatchButton.tsx
index 8768555..e0134f1 100644
--- a/src/StopWatchButton.tsx
+++ b/src/StopWatchButton.tsx
@@ -1,8 +1,21 @@
-import { View } from 'react-native';
+import React from 'react';
+import { View, Button } from 'react-native';
-export default function StopWatchButton() {
+interface StopWatchButtonProps {
+ onPressStart: () => void;
+ onPressStop: () => void;
+ onPressReset: () => void;
+ isRunning: boolean;
+}
+
+const StopWatchButton: React.FC = ({ onPressStart, onPressStop, onPressReset, isRunning }) => {
return (
-
+
+
+
+
);
-}
\ No newline at end of file
+};
+
+export default StopWatchButton;