Skip to content

Commit 16a4083

Browse files
committed
chore: switch to react-native-vision-camera
1 parent 639fdea commit 16a4083

File tree

7 files changed

+167
-139
lines changed

7 files changed

+167
-139
lines changed

android/app/build.gradle

-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ android {
8686
versionCode 130
8787
versionName "1.0.3"
8888
multiDexEnabled true
89-
missingDimensionStrategy 'react-native-camera', 'general'
9089
testBuildType System.getProperty('testBuildType', 'debug')
9190
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
9291
}

android/gradle.properties

+3
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,6 @@ newArchEnabled=false
3737
# Use this property to enable or disable the Hermes JS engine.
3838
# If set to false, you will be using JSC instead.
3939
hermesEnabled=true
40+
41+
# Include MLKit model for react-native-vision-camera
42+
VisionCamera_enableCodeScanner=true

ios/Podfile.lock

+10-6
Original file line numberDiff line numberDiff line change
@@ -1690,8 +1690,6 @@ PODS:
16901690
- React-logger (= 0.75.2)
16911691
- React-perflogger (= 0.75.2)
16921692
- React-utils (= 0.75.2)
1693-
- ReactNativeCameraKit (14.0.0-beta15):
1694-
- React-Core
16951693
- RNCClipboard (1.14.1):
16961694
- React-Core
16971695
- RNDeviceInfo (11.1.0):
@@ -1858,6 +1856,12 @@ PODS:
18581856
- ReactCommon/turbomodule/core
18591857
- Yoga
18601858
- SSZipArchive (2.4.3)
1859+
- VisionCamera (4.5.3):
1860+
- VisionCamera/Core (= 4.5.3)
1861+
- VisionCamera/React (= 4.5.3)
1862+
- VisionCamera/Core (4.5.3)
1863+
- VisionCamera/React (4.5.3):
1864+
- React-Core
18611865
- Yoga (0.0.0)
18621866
- ZXingObjC (3.6.9):
18631867
- ZXingObjC/All (= 3.6.9)
@@ -1942,7 +1946,6 @@ DEPENDENCIES:
19421946
- React-utils (from `../node_modules/react-native/ReactCommon/react/utils`)
19431947
- ReactCodegen (from `build/generated/ios`)
19441948
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
1945-
- ReactNativeCameraKit (from `../node_modules/react-native-camera-kit`)
19461949
- "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)"
19471950
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
19481951
- RNFS (from `../node_modules/react-native-fs`)
@@ -1960,6 +1963,7 @@ DEPENDENCIES:
19601963
- RNSVG (from `../node_modules/react-native-svg`)
19611964
- RNZipArchive (from `../node_modules/react-native-zip-archive`)
19621965
- sodium-react-native-direct (from `../node_modules/sodium-react-native-direct`)
1966+
- VisionCamera (from `../node_modules/react-native-vision-camera`)
19631967
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
19641968

19651969
SPEC REPOS:
@@ -2125,8 +2129,6 @@ EXTERNAL SOURCES:
21252129
:path: build/generated/ios
21262130
ReactCommon:
21272131
:path: "../node_modules/react-native/ReactCommon"
2128-
ReactNativeCameraKit:
2129-
:path: "../node_modules/react-native-camera-kit"
21302132
RNCClipboard:
21312133
:path: "../node_modules/@react-native-clipboard/clipboard"
21322134
RNDeviceInfo:
@@ -2161,6 +2163,8 @@ EXTERNAL SOURCES:
21612163
:path: "../node_modules/react-native-zip-archive"
21622164
sodium-react-native-direct:
21632165
:path: "../node_modules/sodium-react-native-direct"
2166+
VisionCamera:
2167+
:path: "../node_modules/react-native-vision-camera"
21642168
Yoga:
21652169
:path: "../node_modules/react-native/ReactCommon/yoga"
21662170

@@ -2245,7 +2249,6 @@ SPEC CHECKSUMS:
22452249
React-utils: 81a715d9c0a2a49047e77a86f3a2247408540deb
22462250
ReactCodegen: 60973d382704c793c605b9be0fc7f31cb279442f
22472251
ReactCommon: 6ef348087d250257c44c0204461c03f036650e9b
2248-
ReactNativeCameraKit: 71343efc1256720184ce980f164c7eedb78d5c16
22492252
RNCClipboard: 0a720adef5ec193aa0e3de24c3977222c7e52a37
22502253
RNDeviceInfo: b899ce37a403a4dea52b7cb85e16e49c04a5b88e
22512254
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
@@ -2265,6 +2268,7 @@ SPEC CHECKSUMS:
22652268
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
22662269
sodium-react-native-direct: 8feb9a6d0d88ce65efa305d6cc774c11c62d9a15
22672270
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
2271+
VisionCamera: cb84d0d8485b3e67c91b62931d3aa88f49747c92
22682272
Yoga: a1d7895431387402a674fd0d1c04ec85e87909b8
22692273
ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5
22702274

ios/bitkit.xcodeproj/project.pbxproj

+61-61
Large diffs are not rendered by default.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@
8383
"react-native": "0.75.2",
8484
"react-native-address-generator": "0.3.3",
8585
"react-native-biometrics": "3.0.1",
86-
"react-native-camera-kit": "14.0.0-beta15",
8786
"react-native-device-info": "11.1.0",
8887
"react-native-dotenv": "3.4.11",
8988
"react-native-draggable-flatlist": "4.0.1",
@@ -111,6 +110,7 @@
111110
"react-native-svg": "15.2.0",
112111
"react-native-tcp-socket": "6.0.6",
113112
"react-native-toast-message": "2.2.0",
113+
"react-native-vision-camera": "4.5.3",
114114
"react-native-zip-archive": "6.1.0",
115115
"react-redux": "9.1.2",
116116
"readable-stream": "4.5.2",

src/components/Camera.tsx

+71-59
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,26 @@
1-
import React, { ReactElement, useState, useEffect } from 'react';
2-
import { StyleSheet, Platform, View } from 'react-native';
1+
import React, {
2+
ReactElement,
3+
useState,
4+
useEffect,
5+
useRef,
6+
useCallback,
7+
} from 'react';
8+
import { StyleSheet } from 'react-native';
39
import { useIsFocused } from '@react-navigation/native';
4-
import { check, request, PERMISSIONS, RESULTS } from 'react-native-permissions';
5-
import { Camera as CameraKit, CameraType } from 'react-native-camera-kit';
6-
import { useTranslation } from 'react-i18next';
10+
import {
11+
Camera as VisionCamera,
12+
Point,
13+
useCameraDevice,
14+
useCodeScanner,
15+
useCameraPermission,
16+
} from 'react-native-vision-camera';
717

818
import CameraNoAuth from './CameraNoAuth';
919
import GradientView from './GradientView';
20+
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
21+
import { runOnJS } from 'react-native-reanimated';
1022

11-
enum Status {
23+
enum EAuthStatus {
1224
AUTHORIZED = 'AUTHORIZED',
1325
NOT_AUTHORIZED = 'NOT_AUTHORIZED',
1426
UNKNOWN = 'UNKNOWN',
@@ -25,72 +37,72 @@ const Camera = ({
2537
bottomSheet?: boolean;
2638
onBarCodeRead: (data: string) => void;
2739
}): ReactElement => {
28-
const { t } = useTranslation('other');
40+
const camera = useRef<VisionCamera>(null);
41+
const scannedCode = useRef('');
2942
const isFocused = useIsFocused();
30-
const [_data, setData] = useState('');
31-
const [cameraStatus, setCameraStatus] = useState<Status>(Status.UNKNOWN);
43+
const [authStatus, setAuthStatus] = useState(EAuthStatus.UNKNOWN);
44+
45+
const device = useCameraDevice('back');
46+
const { hasPermission, requestPermission } = useCameraPermission();
3247

3348
useEffect(() => {
34-
(async (): Promise<void> => {
35-
const cameraPermission =
36-
Platform.OS === 'ios'
37-
? PERMISSIONS.IOS.CAMERA
38-
: PERMISSIONS.ANDROID.CAMERA;
39-
const checkResponse = await check(cameraPermission);
40-
switch (checkResponse) {
41-
case RESULTS.UNAVAILABLE:
42-
case RESULTS.BLOCKED:
43-
setCameraStatus(Status.NOT_AUTHORIZED);
44-
break;
45-
case RESULTS.DENIED:
46-
const rationale = {
47-
title: t('camera_ask_title'),
48-
message: t('camera_ask_msg'),
49-
buttonPositive: t('ok'),
50-
buttonNegative: t('cancel'),
51-
};
52-
const requestResponse = await request(cameraPermission, rationale);
53-
setCameraStatus(
54-
requestResponse === RESULTS.GRANTED
55-
? Status.AUTHORIZED
56-
: Status.NOT_AUTHORIZED,
57-
);
58-
break;
59-
case RESULTS.LIMITED:
60-
case RESULTS.GRANTED:
61-
setCameraStatus(Status.AUTHORIZED);
62-
break;
49+
const checkPermission = async (): Promise<void> => {
50+
if (hasPermission) {
51+
setAuthStatus(EAuthStatus.AUTHORIZED);
52+
} else {
53+
const granted = await requestPermission();
54+
if (granted) {
55+
setAuthStatus(EAuthStatus.AUTHORIZED);
56+
} else {
57+
setAuthStatus(EAuthStatus.NOT_AUTHORIZED);
58+
}
59+
}
60+
};
61+
62+
checkPermission();
63+
// eslint-disable-next-line react-hooks/exhaustive-deps
64+
}, []);
65+
66+
const codeScanner = useCodeScanner({
67+
codeTypes: ['qr'],
68+
onCodeScanned: (codes) => {
69+
const code = codes.find((c) => c.value);
70+
if (code?.value && scannedCode.current !== code.value) {
71+
scannedCode.current = code.value;
72+
onBarCodeRead(code.value);
6373
}
64-
})();
65-
}, [t]);
74+
},
75+
});
6676

67-
const handleCodeRead = (event): void => {
68-
const { codeStringValue } = event.nativeEvent;
69-
if (_data !== codeStringValue) {
70-
setData(codeStringValue);
71-
onBarCodeRead(codeStringValue);
72-
}
73-
};
77+
const focus = useCallback((point: Point) => {
78+
camera.current?.focus(point);
79+
}, []);
7480

75-
if (!isFocused) {
76-
return <View style={styles.container} />;
77-
}
81+
const gesture = Gesture.Tap().onEnd(({ x, y }) => {
82+
runOnJS(focus)({ x, y });
83+
});
7884

7985
return (
8086
<GradientView style={styles.container}>
81-
{cameraStatus === Status.AUTHORIZED && (
87+
{authStatus === EAuthStatus.AUTHORIZED && (
8288
<>
83-
<CameraKit
84-
style={styles.camera}
85-
scanBarcode={true}
86-
onReadCode={handleCodeRead}
87-
torchMode={torchMode ? 'on' : 'off'}
88-
cameraType={CameraType.Back}
89-
/>
89+
{device && (
90+
<GestureDetector gesture={gesture}>
91+
<VisionCamera
92+
style={styles.camera}
93+
device={device}
94+
codeScanner={codeScanner}
95+
torch={torchMode ? 'on' : 'off'}
96+
enableZoomGesture={true}
97+
isActive={isFocused}
98+
onError={(error): void => console.error(error)}
99+
/>
100+
</GestureDetector>
101+
)}
90102
{children}
91103
</>
92104
)}
93-
{cameraStatus === Status.NOT_AUTHORIZED && (
105+
{authStatus === EAuthStatus.NOT_AUTHORIZED && (
94106
<CameraNoAuth bottomSheet={bottomSheet} />
95107
)}
96108
</GradientView>

yarn.lock

+21-11
Original file line numberDiff line numberDiff line change
@@ -6637,7 +6637,6 @@ __metadata:
66376637
react-native-address-generator: 0.3.3
66386638
react-native-biometrics: 3.0.1
66396639
react-native-bundle-visualizer: ^3.1.3
6640-
react-native-camera-kit: 14.0.0-beta15
66416640
react-native-device-info: 11.1.0
66426641
react-native-dotenv: 3.4.11
66436642
react-native-draggable-flatlist: 4.0.1
@@ -6667,6 +6666,7 @@ __metadata:
66676666
react-native-svg-transformer: ^1.3.0
66686667
react-native-tcp-socket: 6.0.6
66696668
react-native-toast-message: 2.2.0
6669+
react-native-vision-camera: 4.5.3
66706670
react-native-zip-archive: 6.1.0
66716671
react-redux: 9.1.2
66726672
reactotron-react-native: ^5.1.6
@@ -14083,16 +14083,6 @@ __metadata:
1408314083
languageName: node
1408414084
linkType: hard
1408514085

14086-
"react-native-camera-kit@npm:14.0.0-beta15":
14087-
version: 14.0.0-beta15
14088-
resolution: "react-native-camera-kit@npm:14.0.0-beta15"
14089-
peerDependencies:
14090-
react: "*"
14091-
react-native: "*"
14092-
checksum: 6867d00df53dec159c48898a657628819cd637e7083b20f1ed5b6b93aafff01899642d8a99752faf2cef7b713e0f330327d8c38ca22aabb73c80ce1b42fcead3
14093-
languageName: node
14094-
linkType: hard
14095-
1409614086
"react-native-device-info@npm:11.1.0":
1409714087
version: 11.1.0
1409814088
resolution: "react-native-device-info@npm:11.1.0"
@@ -14462,6 +14452,26 @@ __metadata:
1446214452
languageName: node
1446314453
linkType: hard
1446414454

14455+
"react-native-vision-camera@npm:4.5.3":
14456+
version: 4.5.3
14457+
resolution: "react-native-vision-camera@npm:4.5.3"
14458+
peerDependencies:
14459+
"@shopify/react-native-skia": "*"
14460+
react: "*"
14461+
react-native: "*"
14462+
react-native-reanimated: "*"
14463+
react-native-worklets-core: "*"
14464+
peerDependenciesMeta:
14465+
"@shopify/react-native-skia":
14466+
optional: true
14467+
react-native-reanimated:
14468+
optional: true
14469+
react-native-worklets-core:
14470+
optional: true
14471+
checksum: 99d57a70f93134903ae25ef798947f79804ea00e3b58cbb21131115552e6f2950d2a3be9a6a237232ca6bab7b5031aa12d9ca2df659be39dc607d75997317abc
14472+
languageName: node
14473+
linkType: hard
14474+
1446514475
"react-native-zip-archive@npm:6.1.0":
1446614476
version: 6.1.0
1446714477
resolution: "react-native-zip-archive@npm:6.1.0"

0 commit comments

Comments
 (0)