From 48baa8c8c64b21b5e2f22bdc340f4eb3493adad4 Mon Sep 17 00:00:00 2001 From: Aditya Pawar Date: Sat, 5 Oct 2024 12:39:41 -0700 Subject: [PATCH 01/12] Finish QR code scanner, still needs some styling changes --- App.tsx | 9 +- app.json | 14 +- package-lock.json | 120 ++++++++---------- package.json | 4 +- .../QRCodeScanner/QRCodeScanner.tsx | 64 ++++++++++ src/components/QRCodeScanner/styles.ts | 50 ++++++++ 6 files changed, 184 insertions(+), 77 deletions(-) create mode 100644 src/components/QRCodeScanner/QRCodeScanner.tsx create mode 100644 src/components/QRCodeScanner/styles.ts diff --git a/App.tsx b/App.tsx index a1acf3d..d942d31 100644 --- a/App.tsx +++ b/App.tsx @@ -1,12 +1,11 @@ -import { StyleSheet, Text, View } from 'react-native'; +import { StyleSheet, View } from 'react-native'; import { StatusBar } from 'expo-status-bar'; -import Logo from '@/components/Logo'; +import QRCodeScanner from '@/components/QRCodeScanner/QRCodeScanner'; -export default function App() { +export default function StartPage() { return ( - - Open up App.tsx to start working on your app! + ); diff --git a/app.json b/app.json index 0be16b6..e4b524e 100644 --- a/app.json +++ b/app.json @@ -1,12 +1,20 @@ { "expo": { - "name": "mobile-app-template", - "slug": "mobile-app-template", - "owner": "mobileapptemplate", + "name": "Our City Forest", + "slug": "Our City Forest", + "owner": "ourcityforest", "version": "1.0.0", "orientation": "portrait", "icon": "./assets/bp-icon.png", "userInterfaceStyle": "light", + "plugins": [ + [ + "expo-camera", + { + "cameraPermission": "Allow Our City Forest to access your camera to scan QR codes." + } + ] + ], "splash": { "image": "./assets/bp-splash.png", "resizeMode": "contain", diff --git a/package-lock.json b/package-lock.json index 0e64512..be3279d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,13 +12,11 @@ "@react-navigation/native": "^6.1.18", "@react-navigation/native-stack": "^6.11.0", "@supabase/supabase-js": "^2.45.4", - "expo": "~51.0.21", + "expo": "~51.0.36", "expo-auth-session": "~5.5.2", - "expo-barcode-scanner": "~13.0.1", "expo-camera": "~15.0.16", "expo-constants": "~16.0.2", "expo-device": "~6.0.2", - "expo-linking": "~6.3.1", "expo-status-bar": "~1.12.1", "react": "18.2.0", "react-native": "^0.74.5", @@ -2285,9 +2283,9 @@ } }, "node_modules/@expo/cli": { - "version": "0.18.29", - "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.18.29.tgz", - "integrity": "sha512-X810C48Ss+67RdZU39YEO1khNYo1RmjouRV+vVe0QhMoTe8R6OA3t+XYEdwaNbJ5p/DJN7szfHfNmX2glpC7xg==", + "version": "0.18.30", + "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.18.30.tgz", + "integrity": "sha512-V90TUJh9Ly8stYo8nwqIqNWCsYjE28GlVFWEhAFCUOp99foiQr8HSTpiiX5GIrprcPoWmlGoY+J5fQA29R4lFg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.20.0", @@ -2302,7 +2300,7 @@ "@expo/osascript": "^2.0.31", "@expo/package-manager": "^1.5.0", "@expo/plist": "^0.1.0", - "@expo/prebuild-config": "7.0.8", + "@expo/prebuild-config": "7.0.9", "@expo/rudder-sdk-node": "1.1.1", "@expo/spawn-async": "^1.7.2", "@expo/xcpretty": "^4.3.0", @@ -2465,13 +2463,14 @@ } }, "node_modules/@expo/config": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/@expo/config/-/config-9.0.3.tgz", - "integrity": "sha512-eOTNM8eOC8gZNHgenySRlc/lwmYY1NOgvjwA8LHuvPT7/eUwD93zrxu3lPD1Cc/P6C/2BcVdfH4hf0tLmDxnsg==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@expo/config/-/config-9.0.4.tgz", + "integrity": "sha512-g5ns5u1JSKudHYhjo1zaSfkJ/iZIcWmUmIQptMJZ6ag1C0ShL2sj8qdfU8MmAMuKLOgcIfSaiWlQnm4X3VJVkg==", + "license": "MIT", "dependencies": { "@babel/code-frame": "~7.10.4", "@expo/config-plugins": "~8.0.8", - "@expo/config-types": "^51.0.0-unreleased", + "@expo/config-types": "^51.0.3", "@expo/json-file": "^8.3.0", "getenv": "^1.0.0", "glob": "7.1.6", @@ -2483,11 +2482,12 @@ } }, "node_modules/@expo/config-plugins": { - "version": "8.0.8", - "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-8.0.8.tgz", - "integrity": "sha512-Fvu6IO13EUw0R9WeqxUO37FkM62YJBNcZb9DyJAOgMz7Ez/vaKQGEjKt9cwT+Q6uirtCATMgaq6VWAW7YW8xXw==", + "version": "8.0.10", + "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-8.0.10.tgz", + "integrity": "sha512-KG1fnSKRmsudPU9BWkl59PyE0byrE2HTnqbOrgwr2FAhqh7tfr9nRs6A9oLS/ntpGzmFxccTEcsV0L4apsuxxg==", + "license": "MIT", "dependencies": { - "@expo/config-types": "^51.0.0-unreleased", + "@expo/config-types": "^51.0.3", "@expo/json-file": "~8.3.0", "@expo/plist": "^0.1.0", "@expo/sdk-runtime-versions": "^1.0.0", @@ -2600,9 +2600,10 @@ } }, "node_modules/@expo/config-types": { - "version": "51.0.2", - "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-51.0.2.tgz", - "integrity": "sha512-IglkIoiDwJMY01lYkF/ZSBoe/5cR+O3+Gx6fpLFjLfgZGBTdyPkKa1g8NWoWQCk+D3cKL2MDbszT2DyRRB0YqQ==" + "version": "51.0.3", + "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-51.0.3.tgz", + "integrity": "sha512-hMfuq++b8VySb+m9uNNrlpbvGxYc8OcFCUX9yTmi9tlx6A4k8SDabWFBgmnr4ao3wEArvWrtUQIfQCVtPRdpKA==", + "license": "MIT" }, "node_modules/@expo/config/node_modules/@babel/code-frame": { "version": "7.10.4", @@ -3260,14 +3261,14 @@ } }, "node_modules/@expo/prebuild-config": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-7.0.8.tgz", - "integrity": "sha512-wH9NVg6HiwF5y9x0TxiMEeBF+ITPGDXy5/i6OUheSrKpPgb0lF1Mwzl/f2fLPXBEpl+ZXOQ8LlLW32b7K9lrNg==", + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-7.0.9.tgz", + "integrity": "sha512-9i6Cg7jInpnGEHN0jxnW0P+0BexnePiBzmbUvzSbRXpdXihYUX2AKMu73jgzxn5P1hXOSkzNS7umaY+BZ+aBag==", "license": "MIT", "dependencies": { "@expo/config": "~9.0.0-beta.0", "@expo/config-plugins": "~8.0.8", - "@expo/config-types": "^51.0.0-unreleased", + "@expo/config-types": "^51.0.3", "@expo/image-utils": "^0.5.0", "@expo/json-file": "^8.3.0", "@react-native/normalize-colors": "0.74.85", @@ -3365,9 +3366,10 @@ } }, "node_modules/@expo/vector-icons": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-14.0.2.tgz", - "integrity": "sha512-70LpmXQu4xa8cMxjp1fydgRPsalefnHaXLzIwaHMEzcZhnyjw2acZz8azRrZOslPVAWlxItOa2Dd7WtD/kI+CA==", + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-14.0.4.tgz", + "integrity": "sha512-+yKshcbpDfbV4zoXOgHxCwh7lkE9VVTT5T03OUlBsqfze1PLy6Hi4jp1vSb1GVbY6eskvMIivGVc9SKzIv0oEQ==", + "license": "MIT", "dependencies": { "prop-types": "^15.8.1" } @@ -6102,6 +6104,7 @@ "version": "0.74.85", "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.74.85.tgz", "integrity": "sha512-gUIhhpsYLUTYWlWw4vGztyHaX/kNlgVspSvKe2XaPA7o3jYKUoNLc3Ov7u70u/MBWfKdcEffWq44eSe3j3s5JQ==", + "license": "BSD-3-Clause", "engines": { "node": ">=18" } @@ -6110,6 +6113,7 @@ "version": "0.74.85", "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.74.85.tgz", "integrity": "sha512-BRmgCK5vnMmHaKRO+h8PKJmHHH3E6JFuerrcfE3wG2eZ1bcSr+QTu8DAlpxsDWvJvHpCi8tRJGauxd+Ssj/c7w==", + "license": "MIT", "dependencies": { "@isaacs/ttlcache": "^1.4.1", "@react-native/debugger-frontend": "0.74.85", @@ -6133,6 +6137,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -6140,12 +6145,14 @@ "node_modules/@react-native/dev-middleware/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/@react-native/dev-middleware/node_modules/open": { "version": "7.4.2", "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "license": "MIT", "dependencies": { "is-docker": "^2.0.0", "is-wsl": "^2.1.1" @@ -6161,6 +6168,7 @@ "version": "6.2.3", "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz", "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==", + "license": "MIT", "dependencies": { "async-limiter": "~1.0.0" } @@ -6201,7 +6209,8 @@ "node_modules/@react-native/normalize-colors": { "version": "0.74.85", "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.85.tgz", - "integrity": "sha512-pcE4i0X7y3hsAE0SpIl7t6dUc0B0NZLd1yv7ssm4FrLhWG+CGyIq4eFDXpmPU1XHmL5PPySxTAjEMiwv6tAmOw==" + "integrity": "sha512-pcE4i0X7y3hsAE0SpIl7t6dUc0B0NZLd1yv7ssm4FrLhWG+CGyIq4eFDXpmPU1XHmL5PPySxTAjEMiwv6tAmOw==", + "license": "MIT" }, "node_modules/@react-native/virtualized-lists": { "version": "0.74.87", @@ -9613,24 +9622,24 @@ } }, "node_modules/expo": { - "version": "51.0.32", - "resolved": "https://registry.npmjs.org/expo/-/expo-51.0.32.tgz", - "integrity": "sha512-6GEhYvHRnyS/6BytQagGkClsaqbuwAtlN3A6oDfnNMRKLmz6NE/r+Rjg9zbQgUO6zigqb60Yj5lAX32DmixRDw==", + "version": "51.0.36", + "resolved": "https://registry.npmjs.org/expo/-/expo-51.0.36.tgz", + "integrity": "sha512-eQIC0l6fz3p4cU/hV8+QcyKSacyROhaoA1oohfCD6I3F09dxmC8b3SESpzGqHfuq8wsgcUc4q8ckX7ec25IV1g==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.20.0", - "@expo/cli": "0.18.29", - "@expo/config": "9.0.3", - "@expo/config-plugins": "8.0.8", + "@expo/cli": "0.18.30", + "@expo/config": "9.0.4", + "@expo/config-plugins": "8.0.10", "@expo/metro-config": "0.18.11", - "@expo/vector-icons": "^14.0.0", + "@expo/vector-icons": "^14.0.3", "babel-preset-expo": "~11.0.14", "expo-asset": "~10.0.10", "expo-file-system": "~17.0.1", "expo-font": "~12.0.10", "expo-keep-awake": "~13.0.2", - "expo-modules-autolinking": "1.11.2", - "expo-modules-core": "1.12.24", + "expo-modules-autolinking": "1.11.3", + "expo-modules-core": "1.12.25", "fbemitter": "^3.0.0", "whatwg-url-without-unicode": "8.0.0-3" }, @@ -9674,18 +9683,6 @@ "invariant": "^2.2.4" } }, - "node_modules/expo-barcode-scanner": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/expo-barcode-scanner/-/expo-barcode-scanner-13.0.1.tgz", - "integrity": "sha512-xBGLT1An2gpAMIQRTLU3oHydKohX8r8F9/ait1Fk9Vgd0GraFZbP4IiT7nHMlaw4H6E7Muucf7vXpGV6u7d4HQ==", - "license": "MIT", - "dependencies": { - "expo-image-loader": "~4.7.0" - }, - "peerDependencies": { - "expo": "*" - } - }, "node_modules/expo-camera": { "version": "15.0.16", "resolved": "https://registry.npmjs.org/expo-camera/-/expo-camera-15.0.16.tgz", @@ -9780,15 +9777,6 @@ "expo": "*" } }, - "node_modules/expo-image-loader": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/expo-image-loader/-/expo-image-loader-4.7.0.tgz", - "integrity": "sha512-cx+MxxsAMGl9AiWnQUzrkJMJH4eNOGlu7XkLGnAXSJrRoIiciGaKqzeaD326IyCTV+Z1fXvIliSgNW+DscvD8g==", - "license": "MIT", - "peerDependencies": { - "expo": "*" - } - }, "node_modules/expo-keep-awake": { "version": "13.0.2", "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-13.0.2.tgz", @@ -9808,9 +9796,9 @@ } }, "node_modules/expo-modules-autolinking": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-1.11.2.tgz", - "integrity": "sha512-fdcaNO8ucHA3yLNY52ZUENBcAG7KEx8QyMmnVNavO1JVBGRMZG8JyVcbrhYQDtVtpxkbai5YzwvLutINvbDZDQ==", + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-1.11.3.tgz", + "integrity": "sha512-oYh8EZEvYF5TYppxEKUTTJmbr8j7eRRnrIxzZtMvxLTXoujThVPMFS/cbnSnf2bFm1lq50TdDNABhmEi7z0ngQ==", "license": "MIT", "dependencies": { "chalk": "^4.1.0", @@ -9932,9 +9920,9 @@ } }, "node_modules/expo-modules-core": { - "version": "1.12.24", - "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-1.12.24.tgz", - "integrity": "sha512-3geIe2ecizlp7l26iY8Nmc59z2d1RUC5nQZtI9iJoi5uHEUV/zut8e4zRLFVnZb8KOcMcEDsrvaBL5DPnqdfpg==", + "version": "1.12.25", + "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-1.12.25.tgz", + "integrity": "sha512-HB2LS2LEM41Xq1bG+Jtzqm6XgPaa+mM9BAvCdX1lDGMQ9Ay9vMTL/GVEs2gpsINPofICopjBRwD+wftyCbVrzg==", "license": "MIT", "dependencies": { "invariant": "^2.2.4" @@ -14120,9 +14108,9 @@ } }, "node_modules/package-json-from-dist": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "license": "BlueOak-1.0.0" }, "node_modules/parent-module": { diff --git a/package.json b/package.json index 191e3ab..5755f60 100644 --- a/package.json +++ b/package.json @@ -19,13 +19,11 @@ "@react-navigation/native": "^6.1.18", "@react-navigation/native-stack": "^6.11.0", "@supabase/supabase-js": "^2.45.4", - "expo": "~51.0.21", + "expo": "~51.0.36", "expo-auth-session": "~5.5.2", - "expo-barcode-scanner": "~13.0.1", "expo-camera": "~15.0.16", "expo-constants": "~16.0.2", "expo-device": "~6.0.2", - "expo-linking": "~6.3.1", "expo-status-bar": "~1.12.1", "react": "18.2.0", "react-native": "^0.74.5", diff --git a/src/components/QRCodeScanner/QRCodeScanner.tsx b/src/components/QRCodeScanner/QRCodeScanner.tsx new file mode 100644 index 0000000..aa3f79d --- /dev/null +++ b/src/components/QRCodeScanner/QRCodeScanner.tsx @@ -0,0 +1,64 @@ +import { useEffect, useState } from 'react'; +import { Alert, Pressable, SafeAreaView, Text, View } from 'react-native'; +import { + BarcodeScanningResult, + CameraView, + useCameraPermissions, +} from 'expo-camera'; +import styles from './styles'; + +export default function QRCodeScanner() { + const [permission, requestPermission] = useCameraPermissions(); + const [disableScanner, setDisableScanner] = useState(false); + + useEffect(() => { + // Request camera permissions if not granted on mount + if (!permission?.granted) { + requestPermission(); + } + }, [permission]); + + const onBarcodeScanned = (data: BarcodeScanningResult) => { + // Disable scanning callback so we don't scan multiple times + setDisableScanner(true); + + Alert.alert('YUHHHHH QR Code Scanned', data.data, [ + { + text: 'OK', + // Enable scanner after 2 seconds of pressing OK + onPress: () => setTimeout(() => setDisableScanner(false), 2000), + }, + ]); + }; + + // Camera permissions are still loading. + if (!permission) { + return ; + } + + // No perms :( + if (!permission.granted) { + return Bruh you didn't enable perms for the camera; + } + + return ( + + + + Align the QR code within the frame to scan + + + + + Cancel + + + ); +} diff --git a/src/components/QRCodeScanner/styles.ts b/src/components/QRCodeScanner/styles.ts new file mode 100644 index 0000000..fb6518b --- /dev/null +++ b/src/components/QRCodeScanner/styles.ts @@ -0,0 +1,50 @@ +import { StyleSheet } from 'react-native'; + +export default StyleSheet.create({ + container: { + flex: 1, + flexDirection: 'column', + justifyContent: 'space-between', + marginHorizontal: 44, + }, + cameraView: { + flexDirection: 'column', + gap: 24, + }, + qrMessage: { + textAlign: 'center', + fontSize: 20, + paddingBottom: 10, + }, + camera: { + aspectRatio: 1, + width: '100%', + height: undefined, // Calculate heigth based on aspect ratio and width + flexDirection: 'row', + }, + buttonContainer: { + flex: 1, + flexDirection: 'row', + backgroundColor: 'transparent', + margin: 64, + }, + cancelButton: { + alignItems: 'center', + justifyContent: 'center', + paddingVertical: 12, + paddingHorizontal: 32, + borderRadius: 4, + elevation: 3, + backgroundColor: 'gray', + marginBottom: 20, + }, + cancelButtonText: { + fontSize: 18, + color: 'white', + }, + text: { + fontSize: 24, + fontWeight: 'bold', + color: 'white', + }, +}); From 88417f4fedc19f48242cc4f02f0ce3201acf6fc3 Mon Sep 17 00:00:00 2001 From: Aditya Pawar Date: Sat, 5 Oct 2024 12:44:04 -0700 Subject: [PATCH 02/12] Install expo router and route to the qr scanner screen --- App.tsx | 50 ++++++++++++++++++++++++++++++++++------------- package-lock.json | 17 ++++++++-------- package.json | 4 +++- src/app/index.tsx | 0 4 files changed, 47 insertions(+), 24 deletions(-) create mode 100644 src/app/index.tsx diff --git a/App.tsx b/App.tsx index d942d31..15311dc 100644 --- a/App.tsx +++ b/App.tsx @@ -1,21 +1,43 @@ -import { StyleSheet, View } from 'react-native'; -import { StatusBar } from 'expo-status-bar'; +// In App.js in a new project + +import * as React from 'react'; +import { Text, View } from 'react-native'; +import { NavigationContainer } from '@react-navigation/native'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import QRCodeScanner from '@/components/QRCodeScanner/QRCodeScanner'; -export default function StartPage() { +function HomeScreen() { return ( - - - + + Home Screen ); } -const styles = StyleSheet.create({ - container: { - flex: 1, - backgroundColor: '#fff', - alignItems: 'center', - justifyContent: 'center', - }, -}); +const Stack = createNativeStackNavigator(); + +function App() { + return ( + + + + + + + + ); +} + +export default App; diff --git a/package-lock.json b/package-lock.json index be3279d..aff3ef1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,8 @@ "react-native-dotenv": "^3.4.11", "react-native-gesture-handler": "^2.20.0", "react-native-reanimated": "^3.15.4", + "react-native-safe-area-context": "4.10.5", + "react-native-screens": "3.31.1", "react-native-svg": "^15.7.1", "react-native-toast-message": "^2.2.1", "react-native-url-polyfill": "^2.0.0", @@ -14753,7 +14755,6 @@ "resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.4.tgz", "integrity": "sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA==", "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -14878,22 +14879,20 @@ } }, "node_modules/react-native-safe-area-context": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.11.0.tgz", - "integrity": "sha512-Bg7bozxEB+ZS+H3tVYs5yY1cvxNXgR6nRQwpSMkYR9IN5CbxohLnSprrOPG/ostTCd4F6iCk0c51pExEhifSKQ==", + "version": "4.10.5", + "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.10.5.tgz", + "integrity": "sha512-Wyb0Nqw2XJ6oZxW/cK8k5q7/UAhg/wbEG6UVf89rQqecDZTDA5ic//P9J6VvJRVZerzGmxWQpVuM7f+PRYUM4g==", "license": "MIT", - "peer": true, "peerDependencies": { "react": "*", "react-native": "*" } }, "node_modules/react-native-screens": { - "version": "3.34.0", - "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.34.0.tgz", - "integrity": "sha512-8ri3Pd9QcpfXnVckOe/Lnto+BXmSPHV/Q0RB0XW0gDKsCv5wi5k7ez7g1SzgiYHl29MSdiqgjH30zUyOOowOaw==", + "version": "3.31.1", + "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.31.1.tgz", + "integrity": "sha512-8fRW362pfZ9y4rS8KY5P3DFScrmwo/vu1RrRMMx0PNHbeC9TLq0Kw1ubD83591yz64gLNHFLTVkTJmWeWCXKtQ==", "license": "MIT", - "peer": true, "dependencies": { "react-freeze": "^1.0.0", "warn-once": "^0.1.0" diff --git a/package.json b/package.json index 5755f60..b1086f7 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,9 @@ "react-native-toast-message": "^2.2.1", "react-native-url-polyfill": "^2.0.0", "zod": "^3.23.8", - "zustand": "^5.0.0-rc.2" + "zustand": "^5.0.0-rc.2", + "react-native-screens": "3.31.1", + "react-native-safe-area-context": "4.10.5" }, "devDependencies": { "@babel/core": "^7.20.0", diff --git a/src/app/index.tsx b/src/app/index.tsx new file mode 100644 index 0000000..e69de29 From 29b7ef4b771aa5f2178ea9352c0343ef9f90ac24 Mon Sep 17 00:00:00 2001 From: Aditya Pawar Date: Sat, 5 Oct 2024 13:01:55 -0700 Subject: [PATCH 03/12] Add react navigation --- App.tsx | 19 ++++--------- src/app/index.tsx | 23 ++++++++++++++++ .../QRCodeScanner/QRCodeScanner.tsx | 27 ++++++++++++------- src/components/TreeInfoPage/TreeInfoPage.tsx | 26 ++++++++++++++++++ src/components/TreeInfoPage/styles.ts | 10 +++++++ src/types.ts | 6 +++++ 6 files changed, 88 insertions(+), 23 deletions(-) create mode 100644 src/components/TreeInfoPage/TreeInfoPage.tsx create mode 100644 src/components/TreeInfoPage/styles.ts create mode 100644 src/types.ts diff --git a/App.tsx b/App.tsx index 15311dc..7f2b58d 100644 --- a/App.tsx +++ b/App.tsx @@ -1,20 +1,11 @@ -// In App.js in a new project - import * as React from 'react'; -import { Text, View } from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; +import HomeScreen from '@/app'; import QRCodeScanner from '@/components/QRCodeScanner/QRCodeScanner'; +import TreeInfoPage from '@/components/TreeInfoPage/TreeInfoPage'; -function HomeScreen() { - return ( - - Home Screen - - ); -} - -const Stack = createNativeStackNavigator(); +const Stack = createNativeStackNavigator(); function App() { return ( @@ -31,8 +22,8 @@ function App() { options={{ headerShown: false }} /> diff --git a/src/app/index.tsx b/src/app/index.tsx index e69de29..2f937ea 100644 --- a/src/app/index.tsx +++ b/src/app/index.tsx @@ -0,0 +1,23 @@ +import { StyleSheet, Text, View } from 'react-native'; +import { StatusBar } from 'expo-status-bar'; +import Logo from '@/components/Logo'; + +// Dummy home screen for now? idk what to put here +export default function HomeScreen() { + return ( + + + Home Screen! + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: '#fff', + alignItems: 'center', + justifyContent: 'center', + }, +}); diff --git a/src/components/QRCodeScanner/QRCodeScanner.tsx b/src/components/QRCodeScanner/QRCodeScanner.tsx index aa3f79d..0fc3be4 100644 --- a/src/components/QRCodeScanner/QRCodeScanner.tsx +++ b/src/components/QRCodeScanner/QRCodeScanner.tsx @@ -5,9 +5,12 @@ import { CameraView, useCameraPermissions, } from 'expo-camera'; +import { NativeStackScreenProps } from '@react-navigation/native-stack'; import styles from './styles'; -export default function QRCodeScanner() { +type QRCodeScannerProps = NativeStackScreenProps; + +export default function QRCodeScanner({ navigation }: QRCodeScannerProps) { const [permission, requestPermission] = useCameraPermissions(); const [disableScanner, setDisableScanner] = useState(false); @@ -22,13 +25,19 @@ export default function QRCodeScanner() { // Disable scanning callback so we don't scan multiple times setDisableScanner(true); - Alert.alert('YUHHHHH QR Code Scanned', data.data, [ - { - text: 'OK', - // Enable scanner after 2 seconds of pressing OK - onPress: () => setTimeout(() => setDisableScanner(false), 2000), - }, - ]); + Alert.alert( + 'YUHHHHH QR Code Scanned', + `Going to tree page with id: ${data.data}`, + [ + { + text: 'OK', + // Enable scanner after 2 seconds of pressing OK + onPress: () => navigation.push('TreeInfoPage', { treeId: data.data }), + }, + ], + ); + + // setTimeout(() => setDisableScanner(false), 2000), }; // Camera permissions are still loading. @@ -38,7 +47,7 @@ export default function QRCodeScanner() { // No perms :( if (!permission.granted) { - return Bruh you didn't enable perms for the camera; + return Permission for camera not granted.; } return ( diff --git a/src/components/TreeInfoPage/TreeInfoPage.tsx b/src/components/TreeInfoPage/TreeInfoPage.tsx new file mode 100644 index 0000000..ea773b7 --- /dev/null +++ b/src/components/TreeInfoPage/TreeInfoPage.tsx @@ -0,0 +1,26 @@ +import { Pressable, Text, View } from 'react-native'; +import { StatusBar } from 'expo-status-bar'; +import { NativeStackScreenProps } from '@react-navigation/native-stack'; +import Logo from '@/components/Logo'; +import styles from './styles'; + +type TreeInfoPageProps = NativeStackScreenProps< + RootStackParamList, + 'TreeInfoPage' +>; + +export default function TreeInfoPage({ route, navigation }: TreeInfoPageProps) { + // Just placeholder text for now to show that the tree ID is being passed + return ( + + + i found a tree + with an id + {route.params.treeId} + navigation.push('Scanner')}> + Back to scanner + + + + ); +} diff --git a/src/components/TreeInfoPage/styles.ts b/src/components/TreeInfoPage/styles.ts new file mode 100644 index 0000000..0cb1df7 --- /dev/null +++ b/src/components/TreeInfoPage/styles.ts @@ -0,0 +1,10 @@ +import { StyleSheet } from 'react-native'; + +export default StyleSheet.create({ + container: { + flex: 1, + backgroundColor: '#fff', + alignItems: 'center', + justifyContent: 'center', + }, +}); diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..a334e1e --- /dev/null +++ b/src/types.ts @@ -0,0 +1,6 @@ +// Not sure where to keep this stuff +type RootStackParamList = { + Home: undefined; + Scanner: undefined; + TreeInfoPage: { treeId: string }; +}; From 03ee9e48241598ab545aa5eaf8a1dcd029ab9f33 Mon Sep 17 00:00:00 2001 From: Aditya Pawar Date: Sat, 5 Oct 2024 13:16:51 -0700 Subject: [PATCH 04/12] Small text changes --- .github/pull_request_template.md | 2 +- src/components/TreeInfoPage/TreeInfoPage.tsx | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 66c2e33..22887b9 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -32,4 +32,4 @@ -CC: @insert pl github username here +CC: @christophertorres1 diff --git a/src/components/TreeInfoPage/TreeInfoPage.tsx b/src/components/TreeInfoPage/TreeInfoPage.tsx index ea773b7..c26facc 100644 --- a/src/components/TreeInfoPage/TreeInfoPage.tsx +++ b/src/components/TreeInfoPage/TreeInfoPage.tsx @@ -1,7 +1,6 @@ import { Pressable, Text, View } from 'react-native'; import { StatusBar } from 'expo-status-bar'; import { NativeStackScreenProps } from '@react-navigation/native-stack'; -import Logo from '@/components/Logo'; import styles from './styles'; type TreeInfoPageProps = NativeStackScreenProps< @@ -13,13 +12,13 @@ export default function TreeInfoPage({ route, navigation }: TreeInfoPageProps) { // Just placeholder text for now to show that the tree ID is being passed return ( - - i found a tree - with an id + Tree Id: {route.params.treeId} + navigation.push('Scanner')}> Back to scanner + ); From 024ecb1baee3b84d13c28553446e61677d07793d Mon Sep 17 00:00:00 2001 From: Aditya Pawar Date: Sat, 5 Oct 2024 13:28:19 -0700 Subject: [PATCH 05/12] Fix eslint errors --- App.tsx | 1 + src/components/QRCodeScanner/QRCodeScanner.tsx | 16 ++++++++++------ src/components/TreeInfoPage/TreeInfoPage.tsx | 1 + src/types.ts | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/App.tsx b/App.tsx index 7f2b58d..c94b086 100644 --- a/App.tsx +++ b/App.tsx @@ -4,6 +4,7 @@ import { createNativeStackNavigator } from '@react-navigation/native-stack'; import HomeScreen from '@/app'; import QRCodeScanner from '@/components/QRCodeScanner/QRCodeScanner'; import TreeInfoPage from '@/components/TreeInfoPage/TreeInfoPage'; +import { RootStackParamList } from '@/types'; const Stack = createNativeStackNavigator(); diff --git a/src/components/QRCodeScanner/QRCodeScanner.tsx b/src/components/QRCodeScanner/QRCodeScanner.tsx index 0fc3be4..855f032 100644 --- a/src/components/QRCodeScanner/QRCodeScanner.tsx +++ b/src/components/QRCodeScanner/QRCodeScanner.tsx @@ -6,6 +6,7 @@ import { useCameraPermissions, } from 'expo-camera'; import { NativeStackScreenProps } from '@react-navigation/native-stack'; +import { RootStackParamList } from '@/types'; import styles from './styles'; type QRCodeScannerProps = NativeStackScreenProps; @@ -19,25 +20,28 @@ export default function QRCodeScanner({ navigation }: QRCodeScannerProps) { if (!permission?.granted) { requestPermission(); } - }, [permission]); + }, [permission, requestPermission]); const onBarcodeScanned = (data: BarcodeScanningResult) => { // Disable scanning callback so we don't scan multiple times setDisableScanner(true); Alert.alert( - 'YUHHHHH QR Code Scanned', - `Going to tree page with id: ${data.data}`, + 'Found Tree QR Code!', + `Would you like to view more information about tree ${data.data}?`, [ + { + text: 'Cancel', + // Enable scanner after 2 seconds of pressing Cancel + onPress: () => setTimeout(() => setDisableScanner(false), 2000), + style: 'cancel', + }, { text: 'OK', - // Enable scanner after 2 seconds of pressing OK onPress: () => navigation.push('TreeInfoPage', { treeId: data.data }), }, ], ); - - // setTimeout(() => setDisableScanner(false), 2000), }; // Camera permissions are still loading. diff --git a/src/components/TreeInfoPage/TreeInfoPage.tsx b/src/components/TreeInfoPage/TreeInfoPage.tsx index c26facc..7c78e4a 100644 --- a/src/components/TreeInfoPage/TreeInfoPage.tsx +++ b/src/components/TreeInfoPage/TreeInfoPage.tsx @@ -1,6 +1,7 @@ import { Pressable, Text, View } from 'react-native'; import { StatusBar } from 'expo-status-bar'; import { NativeStackScreenProps } from '@react-navigation/native-stack'; +import { RootStackParamList } from '@/types'; import styles from './styles'; type TreeInfoPageProps = NativeStackScreenProps< diff --git a/src/types.ts b/src/types.ts index a334e1e..e94f9f5 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,5 @@ // Not sure where to keep this stuff -type RootStackParamList = { +export type RootStackParamList = { Home: undefined; Scanner: undefined; TreeInfoPage: { treeId: string }; From 8057794e8d9c0f81cbcf9a5be6b660fcc136ee0d Mon Sep 17 00:00:00 2001 From: Aditya Pawar Date: Sat, 5 Oct 2024 13:30:07 -0700 Subject: [PATCH 06/12] Update eslint config --- .eslintrc.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.eslintrc.js b/.eslintrc.js index 32f1383..d01e437 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -3,6 +3,9 @@ module.exports = { extends: ['expo', 'prettier', 'eslint:recommended'], plugins: ['prettier', '@typescript-eslint'], parser: '@typescript-eslint/parser', + env: { + node: true, + }, rules: { // add project-specific linting rules here 'prettier/prettier': 'error', From 77128432a086cc279ad42ccb1677fd6d11f92890 Mon Sep 17 00:00:00 2001 From: Aditya Pawar Date: Sat, 5 Oct 2024 13:31:23 -0700 Subject: [PATCH 07/12] Run prettier --- app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.json b/app.json index e4b524e..77cdd90 100644 --- a/app.json +++ b/app.json @@ -7,7 +7,7 @@ "orientation": "portrait", "icon": "./assets/bp-icon.png", "userInterfaceStyle": "light", - "plugins": [ + "plugins": [ [ "expo-camera", { From 2d4b66dcd7656f401d99d71c1c988603b2cce885 Mon Sep 17 00:00:00 2001 From: Aditya Pawar Date: Sat, 5 Oct 2024 13:33:31 -0700 Subject: [PATCH 08/12] Update app.json --- app.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app.json b/app.json index 77cdd90..eb2bfd7 100644 --- a/app.json +++ b/app.json @@ -1,7 +1,7 @@ { "expo": { - "name": "Our City Forest", - "slug": "Our City Forest", + "name": "out-city-forest", + "slug": "out-city-forest", "owner": "ourcityforest", "version": "1.0.0", "orientation": "portrait", From 6619d3073377906e1af56727f9aeb6e9882f3ec7 Mon Sep 17 00:00:00 2001 From: Aditya Pawar Date: Wed, 30 Oct 2024 17:48:25 -0700 Subject: [PATCH 09/12] Fix PR comments --- App.tsx | 6 +++--- src/components/QRCodeScanner/QRCodeScanner.tsx | 2 +- src/{app/index.tsx => screens/Home/Home.tsx} | 1 - .../TreeInfoPage.tsx => screens/TreeInfo/TreeInfo.tsx} | 5 ++--- src/{components/TreeInfoPage => screens/TreeInfo}/styles.ts | 0 src/{types.ts => types/navigation.ts} | 1 - 6 files changed, 6 insertions(+), 9 deletions(-) rename src/{app/index.tsx => screens/Home/Home.tsx} (90%) rename src/{components/TreeInfoPage/TreeInfoPage.tsx => screens/TreeInfo/TreeInfo.tsx} (74%) rename src/{components/TreeInfoPage => screens/TreeInfo}/styles.ts (100%) rename src/{types.ts => types/navigation.ts} (75%) diff --git a/App.tsx b/App.tsx index c94b086..2dd82df 100644 --- a/App.tsx +++ b/App.tsx @@ -1,10 +1,10 @@ import * as React from 'react'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; -import HomeScreen from '@/app'; import QRCodeScanner from '@/components/QRCodeScanner/QRCodeScanner'; -import TreeInfoPage from '@/components/TreeInfoPage/TreeInfoPage'; -import { RootStackParamList } from '@/types'; +import HomeScreen from '@/screens/Home/Home'; +import TreeInfoPage from '@/screens/TreeInfo/TreeInfo'; +import { RootStackParamList } from '@/types/navigation'; const Stack = createNativeStackNavigator(); diff --git a/src/components/QRCodeScanner/QRCodeScanner.tsx b/src/components/QRCodeScanner/QRCodeScanner.tsx index 855f032..0289576 100644 --- a/src/components/QRCodeScanner/QRCodeScanner.tsx +++ b/src/components/QRCodeScanner/QRCodeScanner.tsx @@ -6,7 +6,7 @@ import { useCameraPermissions, } from 'expo-camera'; import { NativeStackScreenProps } from '@react-navigation/native-stack'; -import { RootStackParamList } from '@/types'; +import { RootStackParamList } from '@/types/navigation'; import styles from './styles'; type QRCodeScannerProps = NativeStackScreenProps; diff --git a/src/app/index.tsx b/src/screens/Home/Home.tsx similarity index 90% rename from src/app/index.tsx rename to src/screens/Home/Home.tsx index 2f937ea..87aca35 100644 --- a/src/app/index.tsx +++ b/src/screens/Home/Home.tsx @@ -2,7 +2,6 @@ import { StyleSheet, Text, View } from 'react-native'; import { StatusBar } from 'expo-status-bar'; import Logo from '@/components/Logo'; -// Dummy home screen for now? idk what to put here export default function HomeScreen() { return ( diff --git a/src/components/TreeInfoPage/TreeInfoPage.tsx b/src/screens/TreeInfo/TreeInfo.tsx similarity index 74% rename from src/components/TreeInfoPage/TreeInfoPage.tsx rename to src/screens/TreeInfo/TreeInfo.tsx index 7c78e4a..7f568a9 100644 --- a/src/components/TreeInfoPage/TreeInfoPage.tsx +++ b/src/screens/TreeInfo/TreeInfo.tsx @@ -1,7 +1,7 @@ import { Pressable, Text, View } from 'react-native'; import { StatusBar } from 'expo-status-bar'; import { NativeStackScreenProps } from '@react-navigation/native-stack'; -import { RootStackParamList } from '@/types'; +import { RootStackParamList } from '@/types/navigation'; import styles from './styles'; type TreeInfoPageProps = NativeStackScreenProps< @@ -9,8 +9,7 @@ type TreeInfoPageProps = NativeStackScreenProps< 'TreeInfoPage' >; -export default function TreeInfoPage({ route, navigation }: TreeInfoPageProps) { - // Just placeholder text for now to show that the tree ID is being passed +export default function TreeInfo({ route, navigation }: TreeInfoPageProps) { return ( Tree Id: diff --git a/src/components/TreeInfoPage/styles.ts b/src/screens/TreeInfo/styles.ts similarity index 100% rename from src/components/TreeInfoPage/styles.ts rename to src/screens/TreeInfo/styles.ts diff --git a/src/types.ts b/src/types/navigation.ts similarity index 75% rename from src/types.ts rename to src/types/navigation.ts index e94f9f5..6511bcd 100644 --- a/src/types.ts +++ b/src/types/navigation.ts @@ -1,4 +1,3 @@ -// Not sure where to keep this stuff export type RootStackParamList = { Home: undefined; Scanner: undefined; From 4537d78fe9624b9c1d4454da7e22c3dc9d9ee439 Mon Sep 17 00:00:00 2001 From: Aditya Pawar Date: Sun, 3 Nov 2024 16:00:28 -0800 Subject: [PATCH 10/12] Style QR Code screen --- .../QRCodeScanner/QRCodeScanner.tsx | 86 +++++++++++++------ src/components/QRCodeScanner/styles.ts | 70 +++++++++++---- src/styles/colors.ts | 12 +++ 3 files changed, 124 insertions(+), 44 deletions(-) create mode 100644 src/styles/colors.ts diff --git a/src/components/QRCodeScanner/QRCodeScanner.tsx b/src/components/QRCodeScanner/QRCodeScanner.tsx index 0289576..85e19af 100644 --- a/src/components/QRCodeScanner/QRCodeScanner.tsx +++ b/src/components/QRCodeScanner/QRCodeScanner.tsx @@ -1,5 +1,12 @@ import { useEffect, useState } from 'react'; -import { Alert, Pressable, SafeAreaView, Text, View } from 'react-native'; +import { + Alert, + Pressable, + SafeAreaView, + Text, + TouchableOpacity, + View, +} from 'react-native'; import { BarcodeScanningResult, CameraView, @@ -13,7 +20,19 @@ type QRCodeScannerProps = NativeStackScreenProps; export default function QRCodeScanner({ navigation }: QRCodeScannerProps) { const [permission, requestPermission] = useCameraPermissions(); - const [disableScanner, setDisableScanner] = useState(false); + const [qrCodeFound, setQrCodeFound] = useState(false); + const [qrCodeData, setQrCodeData] = useState(null); + const [flashEnabled, setFlashEnabled] = useState(false); + + const resetQrCodeFound = () => { + setQrCodeFound(false); + setQrCodeData(null); + }; + let qrCodeFoundTimeout: ReturnType | null = null; + + useEffect(() => { + console.log('flash enabled', flashEnabled); + }, [flashEnabled]); useEffect(() => { // Request camera permissions if not granted on mount @@ -23,25 +42,15 @@ export default function QRCodeScanner({ navigation }: QRCodeScannerProps) { }, [permission, requestPermission]); const onBarcodeScanned = (data: BarcodeScanningResult) => { - // Disable scanning callback so we don't scan multiple times - setDisableScanner(true); + if (data.data) { + setQrCodeFound(true); + setQrCodeData(data.data); + } - Alert.alert( - 'Found Tree QR Code!', - `Would you like to view more information about tree ${data.data}?`, - [ - { - text: 'Cancel', - // Enable scanner after 2 seconds of pressing Cancel - onPress: () => setTimeout(() => setDisableScanner(false), 2000), - style: 'cancel', - }, - { - text: 'OK', - onPress: () => navigation.push('TreeInfoPage', { treeId: data.data }), - }, - ], - ); + if (qrCodeFoundTimeout) { + clearTimeout(qrCodeFoundTimeout); + } + qrCodeFoundTimeout = setTimeout(resetQrCodeFound, 1000); }; // Camera permissions are still loading. @@ -56,22 +65,43 @@ export default function QRCodeScanner({ navigation }: QRCodeScannerProps) { return ( + + setFlashEnabled(!flashEnabled)}> + Flash + + navigation.goBack()}> + X + + + - - Align the QR code within the frame to scan - + + Scan QR Code + Aim the camera at the tree's code + + - - Cancel - + + + navigation.push('TreeInfoPage', { treeId: qrCodeData ?? '' }) + } + disabled={!qrCodeFound} + > + Scan + ); } diff --git a/src/components/QRCodeScanner/styles.ts b/src/components/QRCodeScanner/styles.ts index fb6518b..aa19f6d 100644 --- a/src/components/QRCodeScanner/styles.ts +++ b/src/components/QRCodeScanner/styles.ts @@ -1,26 +1,56 @@ import { StyleSheet } from 'react-native'; +import colors from '@/styles/colors'; export default StyleSheet.create({ container: { flex: 1, flexDirection: 'column', justifyContent: 'space-between', - marginHorizontal: 44, + paddingHorizontal: 44, + backgroundColor: colors.primary_green, }, + + iconFlex: { + flex: 0, + width: '100%', + paddingHorizontal: 44, + flexDirection: 'row', + justifyContent: 'space-between', + }, + + icon: { + backgroundColor: colors.white1, + padding: 8, + }, + cameraView: { + flex: 1, + padding: 24, + flexDirection: 'column', + justifyContent: 'flex-start', + gap: 86, + }, + + textFlex: { + flex: 0, flexDirection: 'column', - gap: 24, + gap: 8, }, - qrMessage: { + header: { + textAlign: 'center', + fontSize: 24, + color: colors.white1, + }, + subtext: { textAlign: 'center', fontSize: 20, - paddingBottom: 10, + color: colors.white1, }, + camera: { - aspectRatio: 1, - width: '100%', - height: undefined, // Calculate heigth based on aspect ratio and width - flexDirection: 'row', + alignSelf: 'center', + width: 285, + height: 248, }, buttonContainer: { flex: 1, @@ -28,20 +58,28 @@ export default StyleSheet.create({ backgroundColor: 'transparent', margin: 64, }, - cancelButton: { + scanButton: { alignItems: 'center', justifyContent: 'center', - paddingVertical: 12, - paddingHorizontal: 32, - borderRadius: 4, + paddingVertical: 10, + borderRadius: 10, elevation: 3, - backgroundColor: 'gray', - marginBottom: 20, + marginHorizontal: 44, + marginBottom: 64, }, - cancelButtonText: { + + scanButtonDisabled: { + backgroundColor: colors.gray4, + }, + scanButtonEnabled: { + backgroundColor: colors.primary_yellow, + }, + + scanButtonText: { fontSize: 18, - color: 'white', + color: colors.white1, }, + text: { fontSize: 24, fontWeight: 'bold', diff --git a/src/styles/colors.ts b/src/styles/colors.ts new file mode 100644 index 0000000..23f24bd --- /dev/null +++ b/src/styles/colors.ts @@ -0,0 +1,12 @@ +export default { + primary_green: '#446127', + primary_green_2: '#9BA964', + primary_yellow: '#F9BD24', + white1: '#FFFFFF', + off_white: '#F9F4E8', + pure_black: '#000000', + black3: '#282828', + gray2: '#4F4F4F', + gray4: '#BDBDBD', + gray3: '#828282', +}; From 5bce025fd2e2ea2f255ab95a2c10feaf8c1b1b56 Mon Sep 17 00:00:00 2001 From: Chris Torres <99312117+christophertorres1@users.noreply.github.com> Date: Mon, 4 Nov 2024 11:53:43 -0800 Subject: [PATCH 11/12] fix unused import linting error --- src/components/QRCodeScanner/QRCodeScanner.tsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/components/QRCodeScanner/QRCodeScanner.tsx b/src/components/QRCodeScanner/QRCodeScanner.tsx index 85e19af..7d4e573 100644 --- a/src/components/QRCodeScanner/QRCodeScanner.tsx +++ b/src/components/QRCodeScanner/QRCodeScanner.tsx @@ -1,12 +1,5 @@ import { useEffect, useState } from 'react'; -import { - Alert, - Pressable, - SafeAreaView, - Text, - TouchableOpacity, - View, -} from 'react-native'; +import { SafeAreaView, Text, TouchableOpacity, View } from 'react-native'; import { BarcodeScanningResult, CameraView, From 7cfdf705431a5379215b2ad632b68484c9ef7aa3 Mon Sep 17 00:00:00 2001 From: Aditya Pawar Date: Wed, 6 Nov 2024 18:33:36 -0800 Subject: [PATCH 12/12] Fix scan color flashing --- package-lock.json | 4 +- package.json | 6 +-- .../QRCodeScanner/QRCodeScanner.tsx | 50 +++++++++---------- src/components/QRCodeScanner/styles.ts | 17 ++++++- 4 files changed, 44 insertions(+), 33 deletions(-) diff --git a/package-lock.json b/package-lock.json index aff3ef1..029d93f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "mobile-app-template", + "name": "our-city-forest", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "mobile-app-template", + "name": "our-city-forest", "version": "1.0.0", "dependencies": { "@react-native-async-storage/async-storage": "^2.0.0", diff --git a/package.json b/package.json index 14c32a7..eed76a0 100644 --- a/package.json +++ b/package.json @@ -30,13 +30,13 @@ "react-native-dotenv": "^3.4.11", "react-native-gesture-handler": "^2.20.0", "react-native-reanimated": "^3.15.4", + "react-native-safe-area-context": "4.10.5", + "react-native-screens": "3.31.1", "react-native-svg": "^15.7.1", "react-native-toast-message": "^2.2.1", "react-native-url-polyfill": "^2.0.0", "zod": "^3.23.8", - "zustand": "^5.0.0-rc.2", - "react-native-screens": "3.31.1", - "react-native-safe-area-context": "4.10.5" + "zustand": "^5.0.0-rc.2" }, "devDependencies": { "@babel/core": "^7.20.0", diff --git a/src/components/QRCodeScanner/QRCodeScanner.tsx b/src/components/QRCodeScanner/QRCodeScanner.tsx index 85e19af..93900ea 100644 --- a/src/components/QRCodeScanner/QRCodeScanner.tsx +++ b/src/components/QRCodeScanner/QRCodeScanner.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { Alert, Pressable, @@ -28,11 +28,17 @@ export default function QRCodeScanner({ navigation }: QRCodeScannerProps) { setQrCodeFound(false); setQrCodeData(null); }; - let qrCodeFoundTimeout: ReturnType | null = null; + let qrCodeFoundTimeout = useRef | undefined>( + undefined, + ); - useEffect(() => { - console.log('flash enabled', flashEnabled); - }, [flashEnabled]); + const onBarcodeScanned = (data: BarcodeScanningResult) => { + setQrCodeFound(true); + setQrCodeData(data.data); + + clearTimeout(qrCodeFoundTimeout.current); + qrCodeFoundTimeout.current = setTimeout(resetQrCodeFound, 500); + }; useEffect(() => { // Request camera permissions if not granted on mount @@ -41,18 +47,6 @@ export default function QRCodeScanner({ navigation }: QRCodeScannerProps) { } }, [permission, requestPermission]); - const onBarcodeScanned = (data: BarcodeScanningResult) => { - if (data.data) { - setQrCodeFound(true); - setQrCodeData(data.data); - } - - if (qrCodeFoundTimeout) { - clearTimeout(qrCodeFoundTimeout); - } - qrCodeFoundTimeout = setTimeout(resetQrCodeFound, 1000); - }; - // Camera permissions are still loading. if (!permission) { return ; @@ -74,20 +68,24 @@ export default function QRCodeScanner({ navigation }: QRCodeScannerProps) { - + Scan QR Code Aim the camera at the tree's code - + + +