-
Notifications
You must be signed in to change notification settings - Fork 0
/
App.tsx
151 lines (136 loc) · 4.43 KB
/
App.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import React, { useState } from "react";
import { Text, View, TouchableOpacity } from "react-native";
import * as haptics from "expo-haptics";
import * as clipboard from "expo-clipboard";
import * as webBrowser from "expo-web-browser";
import { CameraView, Camera } from "expo-camera";
import { FontAwesome5, Feather, AntDesign } from "@expo/vector-icons";
import { useFonts, Poppins_500Medium } from "@expo-google-fonts/poppins";
export default function App() {
const [hasPermission, setHasPermission] = useState(null);
const [scanned, setScanned] = useState(false);
const [scannedData, setScannedData] = useState(null);
async function requestCameraPermissions() {
const { status } = await Camera.requestCameraPermissionsAsync();
setHasPermission(status === "granted");
}
const [fontsLoaded] = useFonts({
Poppins_500Medium,
});
if (!fontsLoaded) return null;
const handleBarCodeScanned = async ({
type,
data,
}: {
type: string;
data: string;
}) => {
setScanned(true);
console.log({ type, data });
setScannedData(data);
await haptics.notificationAsync(haptics.NotificationFeedbackType.Success);
setScanned(false);
};
return (
<View className="flex-1 flex-col bg-white">
<Header />
<View className="flex-1 flex-col items-center p-10">
<View className="flex-row justify-center">
<View className="flex-row justify-center items-center w-64 h-64 border-4 rounded-md relative">
{!Boolean(hasPermission) || Boolean(scannedData) ? (
<AntDesign name="camera" size={48} color="black" />
) : (
<CameraView
onBarcodeScanned={scanned ? undefined : handleBarCodeScanned}
barcodeScannerSettings={{
barcodeTypes: ["qr"],
}}
style={{
width: 250,
height: 250,
}}
/>
)}
</View>
</View>
<Text className="font-poppins text-gray-500 mt-4">
Align a QR code within the frame to scan
</Text>
</View>
<TouchableOpacity
onPress={async () => {
setScanned(false);
setScannedData(null);
if (!hasPermission) await requestCameraPermissions();
haptics.notificationAsync(haptics.NotificationFeedbackType.Success);
}}
className="bg-gray-800 p-4 rounded-lg shadow-lg m-2"
>
<Text className="font-poppins text-white text-center">
{scanned ? "Scan Again" : "Tap to Scan"}
</Text>
</TouchableOpacity>
<ResultCard data={scannedData} setScannedData={setScannedData} />
</View>
);
}
function Header() {
return (
<View className="flex-row p-6 top-0 bg-gray-800 items-center shadow-lg gap-3 mt-0">
<AntDesign name="qrcode" size={30} color="white" />
<Text className="font-poppins text-white text-3xl font-semibold mt-3">
QR Code Scanner
</Text>
</View>
);
}
function ResultCard({
data,
}: {
data: string | null;
setScannedData?: Function;
}) {
const fallbackMesssage =
"The content of the scanned QR code will be displayed here.";
const scannedData = data ?? fallbackMesssage;
return (
<View className="bg-slate-800 p-4 rounded-lg shadow-lg m-2 mb-5">
<View className="flex-col justify-between">
<Text className="font-poppins text-gray-500 mt-2">{scannedData}</Text>
<IconsSection scannedData={data} />
</View>
</View>
);
}
function IconsSection({ scannedData }: { scannedData: string | null }) {
return (
<View className="flex-row mt-2 gap-3 justify-end">
<TouchableOpacity
disabled={scannedData === null}
onPress={async () => {
await clipboard.setStringAsync(scannedData);
haptics.notificationAsync(haptics.NotificationFeedbackType.Success);
}}
>
<FontAwesome5
name="copy"
size={24}
color={scannedData ? "white" : "gray"}
/>
</TouchableOpacity>
<TouchableOpacity
disabled={scannedData === null}
onPress={async () => {
await webBrowser.openBrowserAsync(scannedData);
haptics.notificationAsync(haptics.NotificationFeedbackType.Success);
}}
>
<Feather
name="external-link"
size={24}
color={scannedData ? "white" : "gray"}
/>
</TouchableOpacity>
</View>
);
}