Refactored with a new Camera Library:(react-native-vision-camera). Need fix scanQRCodeFromImage
@@ -1,4 +1,4 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.safeqr.safeqr">
|
||||||
<uses-permission android:name="android.permission.CAMERA"/>
|
<uses-permission android:name="android.permission.CAMERA"/>
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||||
@@ -14,9 +14,11 @@
|
|||||||
</intent>
|
</intent>
|
||||||
</queries>
|
</queries>
|
||||||
<application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:allowBackup="true" android:theme="@style/AppTheme">
|
<application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:allowBackup="true" android:theme="@style/AppTheme">
|
||||||
<meta-data android:name="expo.modules.updates.ENABLED" android:value="false"/>
|
<meta-data android:name="expo.modules.updates.ENABLED" android:value="true"/>
|
||||||
|
<meta-data android:name="expo.modules.updates.EXPO_SDK_VERSION" android:value="51.0.0"/>
|
||||||
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
|
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
|
||||||
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
|
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
|
||||||
|
<meta-data android:name="expo.modules.updates.EXPO_UPDATE_URL" android:value="https://exp.host/@piggyinu/safeqr"/>
|
||||||
<activity android:name=".MainActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:exported="true" android:screenOrientation="portrait">
|
<activity android:name=".MainActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:exported="true" android:screenOrientation="portrait">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 9.2 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 9.2 KiB |
BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 4.7 KiB |
BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 15 KiB |
BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 30 KiB |
BIN
android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 189 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 189 KiB After Width: | Height: | Size: 48 KiB |
BIN
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 49 KiB |
@@ -5,6 +5,7 @@
|
|||||||
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
|
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
|
||||||
<item name="colorPrimary">@color/colorPrimary</item>
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
<item name="android:statusBarColor">#ffffff</item>
|
<item name="android:statusBarColor">#ffffff</item>
|
||||||
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
</style>
|
</style>
|
||||||
<style name="ResetEditText" parent="@android:style/Widget.EditText">
|
<style name="ResetEditText" parent="@android:style/Widget.EditText">
|
||||||
<item name="android:padding">0dp</item>
|
<item name="android:padding">0dp</item>
|
||||||
|
|||||||
@@ -57,3 +57,6 @@ EX_DEV_CLIENT_NETWORK_INSPECTOR=true
|
|||||||
|
|
||||||
# Use legacy packaging to compress native libraries in the resulting APK.
|
# Use legacy packaging to compress native libraries in the resulting APK.
|
||||||
expo.useLegacyPackaging=false
|
expo.useLegacyPackaging=false
|
||||||
|
|
||||||
|
expo.jsEngine=jsc
|
||||||
|
VisionCamera_enableCodeScanner=true
|
||||||
@@ -9,7 +9,10 @@ export default ({ config }) => {
|
|||||||
...config,
|
...config,
|
||||||
extra: {
|
extra: {
|
||||||
API_BASE_URL: process.env.BASE_URL,
|
API_BASE_URL: process.env.BASE_URL,
|
||||||
ENVIRONMENT: process.env.NODE_ENV
|
ENVIRONMENT: process.env.NODE_ENV,
|
||||||
|
eas: {
|
||||||
|
projectId: "88ad983d-5ca3-44e6-bc1b-8a9a941af992"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
11
app.json
@@ -26,6 +26,17 @@
|
|||||||
"projectId": "88ad983d-5ca3-44e6-bc1b-8a9a941af992"
|
"projectId": "88ad983d-5ca3-44e6-bc1b-8a9a941af992"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"plugins": [
|
||||||
|
[
|
||||||
|
"react-native-vision-camera",
|
||||||
|
{
|
||||||
|
"cameraPermissionText": "$(PRODUCT_NAME) needs access to your Camera.",
|
||||||
|
"enableMicrophonePermission": true,
|
||||||
|
"microphonePermissionText": "$(PRODUCT_NAME) needs access to your Microphone.",
|
||||||
|
"enableCodeScanner": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
"owner": "piggyinu"
|
"owner": "piggyinu"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
301
package-lock.json
generated
@@ -20,6 +20,7 @@
|
|||||||
"@react-navigation/native": "^6.1.17",
|
"@react-navigation/native": "^6.1.17",
|
||||||
"@react-navigation/stack": "^6.4.1",
|
"@react-navigation/stack": "^6.4.1",
|
||||||
"@reduxjs/toolkit": "^2.2.6",
|
"@reduxjs/toolkit": "^2.2.6",
|
||||||
|
"@zxing/library": "^0.21.2",
|
||||||
"aws-amplify": "^6.4.2",
|
"aws-amplify": "^6.4.2",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
@@ -31,7 +32,7 @@
|
|||||||
"expo-sharing": "~12.0.1",
|
"expo-sharing": "~12.0.1",
|
||||||
"expo-status-bar": "~1.12.1",
|
"expo-status-bar": "~1.12.1",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-native": "0.74.3",
|
"react-native": "0.74.5",
|
||||||
"react-native-dotenv": "^3.4.11",
|
"react-native-dotenv": "^3.4.11",
|
||||||
"react-native-gesture-handler": "~2.16.1",
|
"react-native-gesture-handler": "~2.16.1",
|
||||||
"react-native-get-random-values": "^1.11.0",
|
"react-native-get-random-values": "^1.11.0",
|
||||||
@@ -40,9 +41,11 @@
|
|||||||
"react-native-safe-area-context": "^4.10.5",
|
"react-native-safe-area-context": "^4.10.5",
|
||||||
"react-native-screens": "3.31.1",
|
"react-native-screens": "3.31.1",
|
||||||
"react-native-svg": "15.2.0",
|
"react-native-svg": "15.2.0",
|
||||||
|
"react-native-vision-camera": "^4.5.1",
|
||||||
"react-native-webview": "^13.8.6",
|
"react-native-webview": "^13.8.6",
|
||||||
"react-redux": "^9.1.2",
|
"react-redux": "^9.1.2",
|
||||||
"redux": "^5.0.1"
|
"redux": "^5.0.1",
|
||||||
|
"safeqr": "file:"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.20.0",
|
"@babel/core": "^7.20.0",
|
||||||
@@ -6841,9 +6844,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-native/assets-registry": {
|
"node_modules/@react-native/assets-registry": {
|
||||||
"version": "0.74.85",
|
"version": "0.74.87",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.74.85.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.74.87.tgz",
|
||||||
"integrity": "sha512-59YmIQxfGDw4aP9S/nAM+sjSFdW8fUP6fsqczCcXgL2YVEjyER9XCaUT0J1K+PdHep8pi05KUgIKUds8P3jbmA==",
|
"integrity": "sha512-1XmRhqQchN+pXPKEKYdpJlwESxVomJOxtEnIkbo7GAlaN2sym84fHEGDXAjLilih5GVPpcpSmFzTy8jx3LtaFg==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
@@ -6936,14 +6939,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-native/community-cli-plugin": {
|
"node_modules/@react-native/community-cli-plugin": {
|
||||||
"version": "0.74.85",
|
"version": "0.74.87",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.74.85.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.74.87.tgz",
|
||||||
"integrity": "sha512-ODzND33eA2owAY3g9jgCdqB+BjAh8qJ7dvmSotXgrgDYr3MJMpd8gvHTIPe2fg4Kab+wk8uipRhrE0i0RYMwtQ==",
|
"integrity": "sha512-EgJG9lSr8x3X67dHQKQvU6EkO+3ksVlJHYIVv6U/AmW9dN80BEFxgYbSJ7icXS4wri7m4kHdgeq2PQ7/3vvrTQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-native-community/cli-server-api": "13.6.9",
|
"@react-native-community/cli-server-api": "13.6.9",
|
||||||
"@react-native-community/cli-tools": "13.6.9",
|
"@react-native-community/cli-tools": "13.6.9",
|
||||||
"@react-native/dev-middleware": "0.74.85",
|
"@react-native/dev-middleware": "0.74.87",
|
||||||
"@react-native/metro-babel-transformer": "0.74.85",
|
"@react-native/metro-babel-transformer": "0.74.87",
|
||||||
"chalk": "^4.0.0",
|
"chalk": "^4.0.0",
|
||||||
"execa": "^5.1.1",
|
"execa": "^5.1.1",
|
||||||
"metro": "^0.80.3",
|
"metro": "^0.80.3",
|
||||||
@@ -6957,6 +6960,37 @@
|
|||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@react-native/community-cli-plugin/node_modules/@react-native/debugger-frontend": {
|
||||||
|
"version": "0.74.87",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.74.87.tgz",
|
||||||
|
"integrity": "sha512-MN95DJLYTv4EqJc+9JajA3AJZSBYJz2QEJ3uWlHrOky2vKrbbRVaW1ityTmaZa2OXIvNc6CZwSRSE7xCoHbXhQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@react-native/community-cli-plugin/node_modules/@react-native/dev-middleware": {
|
||||||
|
"version": "0.74.87",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.74.87.tgz",
|
||||||
|
"integrity": "sha512-7TmZ3hTHwooYgIHqc/z87BMe1ryrIqAUi+AF7vsD+EHCGxHFdMjSpf1BZ2SUPXuLnF2cTiTfV2RwhbPzx0tYIA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@isaacs/ttlcache": "^1.4.1",
|
||||||
|
"@react-native/debugger-frontend": "0.74.87",
|
||||||
|
"@rnx-kit/chromium-edge-launcher": "^1.0.0",
|
||||||
|
"chrome-launcher": "^0.15.2",
|
||||||
|
"connect": "^3.6.5",
|
||||||
|
"debug": "^2.2.0",
|
||||||
|
"node-fetch": "^2.2.0",
|
||||||
|
"nullthrows": "^1.1.1",
|
||||||
|
"open": "^7.0.3",
|
||||||
|
"selfsigned": "^2.4.1",
|
||||||
|
"serve-static": "^1.13.1",
|
||||||
|
"temp-dir": "^2.0.0",
|
||||||
|
"ws": "^6.2.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@react-native/community-cli-plugin/node_modules/ansi-styles": {
|
"node_modules/@react-native/community-cli-plugin/node_modules/ansi-styles": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
@@ -7002,6 +7036,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@react-native/community-cli-plugin/node_modules/debug": {
|
||||||
|
"version": "2.6.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
|
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@react-native/community-cli-plugin/node_modules/execa": {
|
"node_modules/@react-native/community-cli-plugin/node_modules/execa": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
|
||||||
@@ -7062,6 +7104,11 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@react-native/community-cli-plugin/node_modules/ms": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||||
|
},
|
||||||
"node_modules/@react-native/community-cli-plugin/node_modules/npm-run-path": {
|
"node_modules/@react-native/community-cli-plugin/node_modules/npm-run-path": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
|
||||||
@@ -7087,6 +7134,21 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@react-native/community-cli-plugin/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==",
|
||||||
|
"dependencies": {
|
||||||
|
"is-docker": "^2.0.0",
|
||||||
|
"is-wsl": "^2.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@react-native/community-cli-plugin/node_modules/supports-color": {
|
"node_modules/@react-native/community-cli-plugin/node_modules/supports-color": {
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
@@ -7098,6 +7160,14 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@react-native/community-cli-plugin/node_modules/ws": {
|
||||||
|
"version": "6.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz",
|
||||||
|
"integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==",
|
||||||
|
"dependencies": {
|
||||||
|
"async-limiter": "~1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@react-native/debugger-frontend": {
|
"node_modules/@react-native/debugger-frontend": {
|
||||||
"version": "0.74.85",
|
"version": "0.74.85",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.74.85.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.74.85.tgz",
|
||||||
@@ -7166,28 +7236,28 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-native/gradle-plugin": {
|
"node_modules/@react-native/gradle-plugin": {
|
||||||
"version": "0.74.85",
|
"version": "0.74.87",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.74.85.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.74.87.tgz",
|
||||||
"integrity": "sha512-1VQSLukJzaVMn1MYcs8Weo1nUW8xCas2XU1KuoV7OJPk6xPnEBFJmapmEGP5mWeEy7kcTXJmddEgy1wwW0tcig==",
|
"integrity": "sha512-T+VX0N1qP+U9V4oAtn7FTX7pfsoVkd1ocyw9swYXgJqU2fK7hC9famW7b3s3ZiufPGPr1VPJe2TVGtSopBjL6A==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-native/js-polyfills": {
|
"node_modules/@react-native/js-polyfills": {
|
||||||
"version": "0.74.85",
|
"version": "0.74.87",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.74.85.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.74.87.tgz",
|
||||||
"integrity": "sha512-gp4Rg9le3lVZeW7Cie6qLfekvRKZuhJ3LKgi1SFB4N154z1wIclypAJXVXgWBsy8JKJfTwRI+sffC4qZDlvzrg==",
|
"integrity": "sha512-M5Evdn76CuVEF0GsaXiGi95CBZ4IWubHqwXxV9vG9CC9kq0PSkoM2Pn7Lx7dgyp4vT7ccJ8a3IwHbe+5KJRnpw==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-native/metro-babel-transformer": {
|
"node_modules/@react-native/metro-babel-transformer": {
|
||||||
"version": "0.74.85",
|
"version": "0.74.87",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.74.85.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.74.87.tgz",
|
||||||
"integrity": "sha512-JIrXqEwhTvWPtGArgMptIPGstMdXQIkwSjKVYt+7VC4a9Pw1GurIWanIJheEW6ZuCVvTc0VZkwglFz9JVjzDjA==",
|
"integrity": "sha512-UsJCO24sNax2NSPBmV1zLEVVNkS88kcgAiYrZHtYSwSjpl4WZ656tIeedBfiySdJ94Hr3kQmBYLipV5zk0NI1A==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "^7.20.0",
|
"@babel/core": "^7.20.0",
|
||||||
"@react-native/babel-preset": "0.74.85",
|
"@react-native/babel-preset": "0.74.87",
|
||||||
"hermes-parser": "0.19.1",
|
"hermes-parser": "0.19.1",
|
||||||
"nullthrows": "^1.1.1"
|
"nullthrows": "^1.1.1"
|
||||||
},
|
},
|
||||||
@@ -7198,102 +7268,15 @@
|
|||||||
"@babel/core": "*"
|
"@babel/core": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-native/metro-babel-transformer/node_modules/@react-native/babel-plugin-codegen": {
|
|
||||||
"version": "0.74.85",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.74.85.tgz",
|
|
||||||
"integrity": "sha512-48TSDclRB5OMXiImiJkLxyCfRyLsqkCgI8buugCZzvXcYslfV7gCvcyFyQldtcOmerV+CK4RAj7QS4hmB5Mr8Q==",
|
|
||||||
"dependencies": {
|
|
||||||
"@react-native/codegen": "0.74.85"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-native/metro-babel-transformer/node_modules/@react-native/babel-preset": {
|
|
||||||
"version": "0.74.85",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.74.85.tgz",
|
|
||||||
"integrity": "sha512-yMHUlN8INbK5BBwiBuQMftdWkpm1IgCsoJTKcGD2OpSgZhwwm8RUSvGhdRMzB2w7bsqqBmaEMleGtW6aCR7B9w==",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/core": "^7.20.0",
|
|
||||||
"@babel/plugin-proposal-async-generator-functions": "^7.0.0",
|
|
||||||
"@babel/plugin-proposal-class-properties": "^7.18.0",
|
|
||||||
"@babel/plugin-proposal-export-default-from": "^7.0.0",
|
|
||||||
"@babel/plugin-proposal-logical-assignment-operators": "^7.18.0",
|
|
||||||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.0",
|
|
||||||
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
|
|
||||||
"@babel/plugin-proposal-object-rest-spread": "^7.20.0",
|
|
||||||
"@babel/plugin-proposal-optional-catch-binding": "^7.0.0",
|
|
||||||
"@babel/plugin-proposal-optional-chaining": "^7.20.0",
|
|
||||||
"@babel/plugin-syntax-dynamic-import": "^7.8.0",
|
|
||||||
"@babel/plugin-syntax-export-default-from": "^7.0.0",
|
|
||||||
"@babel/plugin-syntax-flow": "^7.18.0",
|
|
||||||
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.0.0",
|
|
||||||
"@babel/plugin-syntax-optional-chaining": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-arrow-functions": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-async-to-generator": "^7.20.0",
|
|
||||||
"@babel/plugin-transform-block-scoping": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-classes": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-computed-properties": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-destructuring": "^7.20.0",
|
|
||||||
"@babel/plugin-transform-flow-strip-types": "^7.20.0",
|
|
||||||
"@babel/plugin-transform-function-name": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-literals": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-modules-commonjs": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-named-capturing-groups-regex": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-parameters": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-private-methods": "^7.22.5",
|
|
||||||
"@babel/plugin-transform-private-property-in-object": "^7.22.11",
|
|
||||||
"@babel/plugin-transform-react-display-name": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-react-jsx": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-react-jsx-self": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-react-jsx-source": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-runtime": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-shorthand-properties": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-spread": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-sticky-regex": "^7.0.0",
|
|
||||||
"@babel/plugin-transform-typescript": "^7.5.0",
|
|
||||||
"@babel/plugin-transform-unicode-regex": "^7.0.0",
|
|
||||||
"@babel/template": "^7.0.0",
|
|
||||||
"@react-native/babel-plugin-codegen": "0.74.85",
|
|
||||||
"babel-plugin-transform-flow-enums": "^0.0.2",
|
|
||||||
"react-refresh": "^0.14.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@babel/core": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-native/metro-babel-transformer/node_modules/@react-native/codegen": {
|
|
||||||
"version": "0.74.85",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.74.85.tgz",
|
|
||||||
"integrity": "sha512-N7QwoS4Hq/uQmoH83Ewedy6D0M7xbQsOU3OMcQf0eY3ltQ7S2hd9/R4UTalQWRn1OUJfXR6OG12QJ4FStKgV6Q==",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/parser": "^7.20.0",
|
|
||||||
"glob": "^7.1.1",
|
|
||||||
"hermes-parser": "0.19.1",
|
|
||||||
"invariant": "^2.2.4",
|
|
||||||
"jscodeshift": "^0.14.0",
|
|
||||||
"mkdirp": "^0.5.1",
|
|
||||||
"nullthrows": "^1.1.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@babel/preset-env": "^7.1.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-native/normalize-colors": {
|
"node_modules/@react-native/normalize-colors": {
|
||||||
"version": "0.74.85",
|
"version": "0.74.85",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.85.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.85.tgz",
|
||||||
"integrity": "sha512-pcE4i0X7y3hsAE0SpIl7t6dUc0B0NZLd1yv7ssm4FrLhWG+CGyIq4eFDXpmPU1XHmL5PPySxTAjEMiwv6tAmOw=="
|
"integrity": "sha512-pcE4i0X7y3hsAE0SpIl7t6dUc0B0NZLd1yv7ssm4FrLhWG+CGyIq4eFDXpmPU1XHmL5PPySxTAjEMiwv6tAmOw=="
|
||||||
},
|
},
|
||||||
"node_modules/@react-native/virtualized-lists": {
|
"node_modules/@react-native/virtualized-lists": {
|
||||||
"version": "0.74.85",
|
"version": "0.74.87",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.74.85.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.74.87.tgz",
|
||||||
"integrity": "sha512-jx2Zw0qlZteoQ+0KxRc7s4drsljLBEP534FaNZ950e9+CN9nVkLsV6rigcTjDR8wjKMSBWhKf0C0C3egYz7Ehg==",
|
"integrity": "sha512-lsGxoFMb0lyK/MiplNKJpD+A1EoEUumkLrCjH4Ht+ZlG8S0BfCxmskLZ6qXn3BiDSkLjfjI/qyZ3pnxNBvkXpQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"invariant": "^2.2.4",
|
"invariant": "^2.2.4",
|
||||||
"nullthrows": "^1.1.1"
|
"nullthrows": "^1.1.1"
|
||||||
@@ -9241,6 +9224,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@zxing/library": {
|
||||||
|
"version": "0.21.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@zxing/library/-/library-0.21.2.tgz",
|
||||||
|
"integrity": "sha512-VMCCSUJSld3tqG6aREJ6XBCxYuoQFcjrF1kowKPFqTA6QG1ixfm6bVfD7gP4jjfM0MX20wVB65DEXtjRsBmV6w==",
|
||||||
|
"dependencies": {
|
||||||
|
"ts-custom-error": "^3.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.4.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@zxing/text-encoding": "~0.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@zxing/text-encoding": {
|
||||||
|
"version": "0.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@zxing/text-encoding/-/text-encoding-0.9.0.tgz",
|
||||||
|
"integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"node_modules/abort-controller": {
|
"node_modules/abort-controller": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||||
@@ -15940,21 +15943,21 @@
|
|||||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||||
},
|
},
|
||||||
"node_modules/react-native": {
|
"node_modules/react-native": {
|
||||||
"version": "0.74.3",
|
"version": "0.74.5",
|
||||||
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.74.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.74.5.tgz",
|
||||||
"integrity": "sha512-UFutCC6WEw6HkxlcpQ2BemKqi0JkwrgDchYB5Svi8Sp4Xwt4HA6LGEjNQgZ+3KM44bjyFRpofQym0uh0jACGng==",
|
"integrity": "sha512-Bgg2WvxaGODukJMTZFTZBNMKVaROHLwSb8VAGEdrlvKwfb1hHg/3aXTUICYk7dwgAnb+INbGMwnF8yeAgIUmqw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jest/create-cache-key-function": "^29.6.3",
|
"@jest/create-cache-key-function": "^29.6.3",
|
||||||
"@react-native-community/cli": "13.6.9",
|
"@react-native-community/cli": "13.6.9",
|
||||||
"@react-native-community/cli-platform-android": "13.6.9",
|
"@react-native-community/cli-platform-android": "13.6.9",
|
||||||
"@react-native-community/cli-platform-ios": "13.6.9",
|
"@react-native-community/cli-platform-ios": "13.6.9",
|
||||||
"@react-native/assets-registry": "0.74.85",
|
"@react-native/assets-registry": "0.74.87",
|
||||||
"@react-native/codegen": "0.74.85",
|
"@react-native/codegen": "0.74.87",
|
||||||
"@react-native/community-cli-plugin": "0.74.85",
|
"@react-native/community-cli-plugin": "0.74.87",
|
||||||
"@react-native/gradle-plugin": "0.74.85",
|
"@react-native/gradle-plugin": "0.74.87",
|
||||||
"@react-native/js-polyfills": "0.74.85",
|
"@react-native/js-polyfills": "0.74.87",
|
||||||
"@react-native/normalize-colors": "0.74.85",
|
"@react-native/normalize-colors": "0.74.87",
|
||||||
"@react-native/virtualized-lists": "0.74.85",
|
"@react-native/virtualized-lists": "0.74.87",
|
||||||
"abort-controller": "^3.0.0",
|
"abort-controller": "^3.0.0",
|
||||||
"anser": "^1.4.9",
|
"anser": "^1.4.9",
|
||||||
"ansi-regex": "^5.0.0",
|
"ansi-regex": "^5.0.0",
|
||||||
@@ -16132,6 +16135,29 @@
|
|||||||
"react-native": "*"
|
"react-native": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-native-vision-camera": {
|
||||||
|
"version": "4.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-native-vision-camera/-/react-native-vision-camera-4.5.1.tgz",
|
||||||
|
"integrity": "sha512-ob7gfBYin4lG2zlzRr5y4rYJN3NCCyJotFX1z3ul8V0N2GwkCGh31cko6hF9DXG4VocSPVYKt+K5W0CWLp3y0g==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@shopify/react-native-skia": "*",
|
||||||
|
"react": "*",
|
||||||
|
"react-native": "*",
|
||||||
|
"react-native-reanimated": "*",
|
||||||
|
"react-native-worklets-core": "*"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@shopify/react-native-skia": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react-native-reanimated": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react-native-worklets-core": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-native-webview": {
|
"node_modules/react-native-webview": {
|
||||||
"version": "13.10.5",
|
"version": "13.10.5",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.10.5.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.10.5.tgz",
|
||||||
@@ -16153,25 +16179,10 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-native/node_modules/@react-native/codegen": {
|
"node_modules/react-native/node_modules/@react-native/normalize-colors": {
|
||||||
"version": "0.74.85",
|
"version": "0.74.87",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.74.85.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.87.tgz",
|
||||||
"integrity": "sha512-N7QwoS4Hq/uQmoH83Ewedy6D0M7xbQsOU3OMcQf0eY3ltQ7S2hd9/R4UTalQWRn1OUJfXR6OG12QJ4FStKgV6Q==",
|
"integrity": "sha512-Xh7Nyk/MPefkb0Itl5Z+3oOobeG9lfLb7ZOY2DKpFnoCE1TzBmib9vMNdFaLdSxLIP+Ec6icgKtdzYg8QUPYzA=="
|
||||||
"dependencies": {
|
|
||||||
"@babel/parser": "^7.20.0",
|
|
||||||
"glob": "^7.1.1",
|
|
||||||
"hermes-parser": "0.19.1",
|
|
||||||
"invariant": "^2.2.4",
|
|
||||||
"jscodeshift": "^0.14.0",
|
|
||||||
"mkdirp": "^0.5.1",
|
|
||||||
"nullthrows": "^1.1.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@babel/preset-env": "^7.1.6"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"node_modules/react-native/node_modules/ansi-styles": {
|
"node_modules/react-native/node_modules/ansi-styles": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
@@ -16629,6 +16640,10 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/safeqr": {
|
||||||
|
"resolved": "",
|
||||||
|
"link": true
|
||||||
|
},
|
||||||
"node_modules/sax": {
|
"node_modules/sax": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
|
||||||
@@ -17880,6 +17895,14 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ts-custom-error": {
|
||||||
|
"version": "3.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ts-custom-error/-/ts-custom-error-3.3.1.tgz",
|
||||||
|
"integrity": "sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ts-interface-checker": {
|
"node_modules/ts-interface-checker": {
|
||||||
"version": "0.1.13",
|
"version": "0.1.13",
|
||||||
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
|
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
"@react-navigation/native": "^6.1.17",
|
"@react-navigation/native": "^6.1.17",
|
||||||
"@react-navigation/stack": "^6.4.1",
|
"@react-navigation/stack": "^6.4.1",
|
||||||
"@reduxjs/toolkit": "^2.2.6",
|
"@reduxjs/toolkit": "^2.2.6",
|
||||||
|
"@zxing/library": "^0.21.2",
|
||||||
"aws-amplify": "^6.4.2",
|
"aws-amplify": "^6.4.2",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
@@ -35,7 +36,7 @@
|
|||||||
"expo-sharing": "~12.0.1",
|
"expo-sharing": "~12.0.1",
|
||||||
"expo-status-bar": "~1.12.1",
|
"expo-status-bar": "~1.12.1",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-native": "0.74.3",
|
"react-native": "0.74.5",
|
||||||
"react-native-dotenv": "^3.4.11",
|
"react-native-dotenv": "^3.4.11",
|
||||||
"react-native-gesture-handler": "~2.16.1",
|
"react-native-gesture-handler": "~2.16.1",
|
||||||
"react-native-get-random-values": "^1.11.0",
|
"react-native-get-random-values": "^1.11.0",
|
||||||
@@ -44,6 +45,7 @@
|
|||||||
"react-native-safe-area-context": "^4.10.5",
|
"react-native-safe-area-context": "^4.10.5",
|
||||||
"react-native-screens": "3.31.1",
|
"react-native-screens": "3.31.1",
|
||||||
"react-native-svg": "15.2.0",
|
"react-native-svg": "15.2.0",
|
||||||
|
"react-native-vision-camera": "^4.5.1",
|
||||||
"react-native-webview": "^13.8.6",
|
"react-native-webview": "^13.8.6",
|
||||||
"react-redux": "^9.1.2",
|
"react-redux": "^9.1.2",
|
||||||
"redux": "^5.0.1",
|
"redux": "^5.0.1",
|
||||||
|
|||||||
@@ -1,68 +1,28 @@
|
|||||||
import React, { useState, useEffect, useCallback } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, Modal, Image, Dimensions } from 'react-native';
|
import { View, Text, StyleSheet, TouchableOpacity, Image, Dimensions, Modal } from 'react-native';
|
||||||
import { Camera, CameraView, scanFromURLAsync } from 'expo-camera';
|
import { Camera, useCameraDevice, useCameraPermission, useCodeScanner } from 'react-native-vision-camera';
|
||||||
import { Ionicons } from '@expo/vector-icons';
|
import { Ionicons } from '@expo/vector-icons';
|
||||||
import { useFocusEffect, useNavigation } from '@react-navigation/native';
|
|
||||||
import * as ImagePicker from 'expo-image-picker';
|
import * as ImagePicker from 'expo-image-picker';
|
||||||
import ScannedDataBox from '../components/ScannedDataBox';
|
import ScannedDataBox from '../components/ScannedDataBox';
|
||||||
import { useDispatch } from 'react-redux';
|
import { scanQRCode } from '../api/qrCodeAPI';
|
||||||
import { AppDispatch } from '../store';
|
|
||||||
import { scanQRCode, getUserInfo } from '../api/qrCodeAPI';
|
|
||||||
import SettingsScreen from './SettingsScreen';
|
import SettingsScreen from './SettingsScreen';
|
||||||
|
|
||||||
const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
|
const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
|
||||||
|
|
||||||
const QRScannerScreen: React.FC<{ clearScanData: () => void }> = ({ clearScanData }) => {
|
const QRScannerScreen: React.FC = () => {
|
||||||
const navigation = useNavigation(); // Navigation hook
|
const [isSettingsModalVisible, setIsSettingsModalVisible] = useState<boolean>(false);
|
||||||
const dispatch = useDispatch<AppDispatch>(); // Use dispatch for Redux actions
|
const [enableTorch, setEnableTorch] = useState<boolean>(false);
|
||||||
|
|
||||||
// State variables
|
|
||||||
const [showSplash, setShowSplash] = useState<boolean>(true); // State for splash screen visibility
|
|
||||||
const [hasPermission, setHasPermission] = useState<boolean | null>(null);
|
|
||||||
const [scanned, setScanned] = useState<boolean>(false);
|
const [scanned, setScanned] = useState<boolean>(false);
|
||||||
const [qrCodeId, setQRCodeId] = useState<string | null>(null); // State for QR code ID
|
const [qrCodeId, setQRCodeId] = useState<string | null>(null); // State for QR code ID
|
||||||
const [enableTorch, setEnableTorch] = useState<boolean>(false); // State for torch
|
const [isScannedDataBoxVisible, setIsScannedDataBoxVisible] = useState<boolean>(false); // State for ScannedDataBox visibility
|
||||||
const [cameraVisible, setCameraVisible] = useState<boolean>(true); // State to control camera visibility
|
|
||||||
const [isScannedDataBoxVisible, setIsScannedDataBoxVisible] = useState<boolean>(false); // State for ScannedDataBox modal visibility
|
const { hasPermission, requestPermission } = useCameraPermission();
|
||||||
const [isSettingsModalVisible, setIsSettingsModalVisible] = useState<boolean>(false); // State for modal visibility
|
const device = useCameraDevice('back');
|
||||||
|
|
||||||
// Request Camera Permission and initialize the app
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const initializeApp = async () => {
|
requestPermission();
|
||||||
const { status } = await Camera.requestCameraPermissionsAsync();
|
|
||||||
setHasPermission(status === 'granted');
|
|
||||||
setShowSplash(false);
|
|
||||||
console.log("Camera permissions initialized");
|
|
||||||
|
|
||||||
// Fetch and log user information
|
|
||||||
fetchUserInformation();
|
|
||||||
};
|
|
||||||
|
|
||||||
initializeApp();
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Focus effect to enable camera and clear data on focus
|
|
||||||
useFocusEffect(
|
|
||||||
useCallback(() => {
|
|
||||||
setCameraVisible(true);
|
|
||||||
clearScanDataInternal();
|
|
||||||
console.log("Screen focused, scan data cleared and camera enabled");
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
setCameraVisible(false);
|
|
||||||
console.log("Screen unfocused, camera disabled");
|
|
||||||
};
|
|
||||||
}, [navigation])
|
|
||||||
);
|
|
||||||
|
|
||||||
// Clear Scan Data
|
|
||||||
const clearScanDataInternal = () => {
|
|
||||||
setScanned(false);
|
|
||||||
setQRCodeId(null);
|
|
||||||
console.log("Scan data cleared");
|
|
||||||
};
|
|
||||||
|
|
||||||
// Handle scanning of payload (QR code data) and get the QR-ID
|
|
||||||
const handlePayload = async (payload: string) => {
|
const handlePayload = async (payload: string) => {
|
||||||
setScanned(true);
|
setScanned(true);
|
||||||
console.info("Decoded QR Code, Payload is: ", payload);
|
console.info("Decoded QR Code, Payload is: ", payload);
|
||||||
@@ -72,48 +32,36 @@ const QRScannerScreen: React.FC<{ clearScanData: () => void }> = ({ clearScanDat
|
|||||||
const qrCodeId = response.qrcode.data.id;
|
const qrCodeId = response.qrcode.data.id;
|
||||||
// Store the QR code ID for later use
|
// Store the QR code ID for later use
|
||||||
setQRCodeId(qrCodeId);
|
setQRCodeId(qrCodeId);
|
||||||
setIsScannedDataBoxVisible(true); // Show ScannedDataBox modal
|
setIsScannedDataBoxVisible(true); // Show ScannedDataBox pop-up
|
||||||
|
|
||||||
// Optionally, show a message or perform another action
|
|
||||||
console.log("QR code scanned successfully, ID:", qrCodeId);
|
console.log("QR code scanned successfully, ID:", qrCodeId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error scanning QR code:", error);
|
console.error("Error scanning QR code:", error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fetch and log user information
|
const codeScanner = useCodeScanner({
|
||||||
const fetchUserInformation = async () => {
|
codeTypes: ['qr'], // Only scan QR codes
|
||||||
try {
|
onCodeScanned: (codes) => {
|
||||||
const userInfo = await getUserInfo();
|
if (!scanned) {
|
||||||
console.log('User Info:', userInfo);
|
handlePayload(codes[0]?.value); // Extract and handle the value only
|
||||||
} catch (error) {
|
|
||||||
console.error('Error fetching user information:', error);
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
});
|
||||||
// Toggle torch (flashlight) on/off
|
|
||||||
const toggleTorch = () => {
|
|
||||||
setEnableTorch((prev) => !prev);
|
|
||||||
console.log("Torch toggled:", enableTorch ? "off" : "on");
|
|
||||||
};
|
|
||||||
|
|
||||||
// Read QR from image
|
|
||||||
const readQRFromImage = async () => {
|
|
||||||
clearScanDataInternal();
|
|
||||||
console.log("Reading QR code from image");
|
|
||||||
|
|
||||||
|
const openImagePicker = async () => {
|
||||||
const result = await ImagePicker.launchImageLibraryAsync({
|
const result = await ImagePicker.launchImageLibraryAsync({
|
||||||
mediaTypes: ImagePicker.MediaTypeOptions.Images,
|
mediaTypes: ImagePicker.MediaTypeOptions.Images,
|
||||||
allowsEditing: false, // Don't ask user to crop images
|
allowsEditing: false,
|
||||||
quality: 1,
|
quality: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result && result.assets && result.assets.length > 0 && result.assets[0].uri) { // Ensure the uri is not empty
|
if (!result.canceled && result.assets.length > 0) {
|
||||||
|
const { uri } = result.assets[0];
|
||||||
try {
|
try {
|
||||||
const scannedResult = await scanFromURLAsync(result.assets[0].uri);
|
// If using expo-camera or similar packages:
|
||||||
if (scannedResult && scannedResult[0] && scannedResult[0].data) {
|
const scannedResult = await scanQRCodeFromURL(uri); // Function to scan QR code from the selected image URL
|
||||||
handlePayload(scannedResult[0].data);
|
if (scannedResult) {
|
||||||
console.log('QR code data from image:', scannedResult[0].data);
|
handlePayload(scannedResult);
|
||||||
} else {
|
} else {
|
||||||
console.log("No QR code found in the selected image");
|
console.log("No QR code found in the selected image");
|
||||||
}
|
}
|
||||||
@@ -123,21 +71,27 @@ const QRScannerScreen: React.FC<{ clearScanData: () => void }> = ({ clearScanDat
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Conditional rendering based on state
|
const scanQRCodeFromURL = async (uri: string) => {
|
||||||
if (showSplash) {
|
// This method can vary depending on the package used for scanning
|
||||||
return (
|
// For example, using expo-camera or other available options to scan QR code from an image URL
|
||||||
<View style={styles.splashContainer}>
|
// Implement scanFromURLAsync if using expo-camera
|
||||||
<ActivityIndicator size="large" color="#ff69b4" />
|
|
||||||
</View>
|
// If using expo-camera
|
||||||
);
|
// const scannedResult = await scanFromURLAsync(uri);
|
||||||
|
// return scannedResult?.[0]?.data;
|
||||||
|
|
||||||
|
// If using other methods, implement them accordingly
|
||||||
|
// Here we simulate scanning with a placeholder result
|
||||||
|
const placeholderResult = "SIMULATED_PAYLOAD"; // Replace with actual scanning logic
|
||||||
|
return placeholderResult;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!hasPermission) {
|
||||||
|
return <Text>Requesting camera permission...</Text>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasPermission === null) {
|
if (!device) {
|
||||||
return <Text>Requesting for camera permission</Text>;
|
return <Text>Loading camera...</Text>;
|
||||||
}
|
|
||||||
|
|
||||||
if (hasPermission === false) {
|
|
||||||
return <Text>No access to camera</Text>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -147,33 +101,44 @@ const QRScannerScreen: React.FC<{ clearScanData: () => void }> = ({ clearScanDat
|
|||||||
<Text style={styles.welcomeText}>Please point the camera at the QR Code</Text>
|
<Text style={styles.welcomeText}>Please point the camera at the QR Code</Text>
|
||||||
|
|
||||||
<View style={styles.cameraContainer}>
|
<View style={styles.cameraContainer}>
|
||||||
{cameraVisible && (
|
{device && (
|
||||||
<CameraView
|
<Camera
|
||||||
onBarcodeScanned={scanned ? undefined : ({ data, type }) => {
|
style={StyleSheet.absoluteFill}
|
||||||
console.log("Barcode Type:", type); // Log the type of barcode scanned
|
device={device}
|
||||||
console.log("Raw Scanned Barcode Data:", data); // Log the raw barcode data
|
isActive={true}
|
||||||
handlePayload(data);
|
torch={enableTorch ? 'on' : 'off'}
|
||||||
}}
|
codeScanner={codeScanner}
|
||||||
style={styles.camera}
|
|
||||||
enableTorch={enableTorch}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<TouchableOpacity onPress={toggleTorch} style={styles.flashButton}>
|
{/* Torch Button */}
|
||||||
<Ionicons name="flashlight" size={screenWidth * 0.06} color="#fff" />
|
<TouchableOpacity
|
||||||
|
onPress={() => device.hasFlash && setEnableTorch((prev) => !prev)}
|
||||||
|
style={styles.flashButton}
|
||||||
|
disabled={!device.hasFlash}
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name={device.hasFlash ? 'flashlight' : 'flashlight-outline'}
|
||||||
|
size={screenWidth * 0.06}
|
||||||
|
color={device.hasFlash ? "#fff" : "#888"}
|
||||||
|
/>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
<TouchableOpacity onPress={readQRFromImage} style={styles.galleryButton}>
|
|
||||||
|
{/* Gallery Button */}
|
||||||
|
<TouchableOpacity onPress={openImagePicker} style={styles.galleryButton}>
|
||||||
<Ionicons name="image" size={screenWidth * 0.06} color="#fff" />
|
<Ionicons name="image" size={screenWidth * 0.06} color="#fff" />
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{/* Scanned Data Box */}
|
{/* Scanned Data Box as a pop-up */}
|
||||||
{isScannedDataBoxVisible && (
|
{isScannedDataBoxVisible && (
|
||||||
<View style={styles.scannedDataBoxPopup}>
|
<View style={styles.scannedDataBoxPopup}>
|
||||||
<ScannedDataBox
|
<ScannedDataBox
|
||||||
qrCodeId={qrCodeId}
|
qrCodeId={qrCodeId!}
|
||||||
clearScanData={() => setIsScannedDataBoxVisible(false)}
|
clearScanData={() => {
|
||||||
|
setScanned(false);
|
||||||
|
setIsScannedDataBoxVisible(false);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
@@ -230,7 +195,7 @@ const styles = StyleSheet.create({
|
|||||||
color: 'black',
|
color: 'black',
|
||||||
},
|
},
|
||||||
cameraContainer: {
|
cameraContainer: {
|
||||||
height: '60%',
|
height: '50%',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
borderRadius: 10,
|
borderRadius: 10,
|
||||||
@@ -286,8 +251,6 @@ const styles = StyleSheet.create({
|
|||||||
padding: screenWidth * 0.025,
|
padding: screenWidth * 0.025,
|
||||||
elevation: 5,
|
elevation: 5,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
settingsModal: {
|
settingsModal: {
|
||||||
backgroundColor: 'rgba(0, 0, 0, 0.5)', // Semi-transparent background
|
backgroundColor: 'rgba(0, 0, 0, 0.5)', // Semi-transparent background
|
||||||
},
|
},
|
||||||
|
|||||||