| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- import { CameraView, useCameraPermissions } from 'expo-camera';
- import { useEffect, useRef, useState } from 'react';
- import {
- Dimensions,
- Pressable,
- ScrollView,
- StyleSheet,
- Text,
- View
- } from 'react-native';
- import ChooseCarForChargingRow from '../../../../component/global/chooseCarForChargingRow';
- import {
- CrossLogoWhiteSvg,
- QuestionSvg
- } from '../../../../component/global/SVG';
- import { router } from 'expo-router';
- const ScanQrPage = () => {
- const [permission, requestPermission] = useCameraPermissions();
- const [scanned, setScanned] = useState(false);
- const viewRef = useRef(null);
- useEffect(() => {
- (async () => {
- const { status } = await requestPermission();
- if (status !== 'granted') {
- alert('Please grant camera permission to use the QR scanner');
- }
- })();
- }, []);
- if (!permission) {
- return <View />;
- }
- if (!permission.granted) {
- return (
- <View className="flex-1 justify-center items-center">
- <Text style={{ textAlign: 'center' }}>
- We need your permission to access the camera QR code
- function. Please go to your device settings and enable
- camera permissions for this application.
- </Text>
- </View>
- );
- }
- const { width: screenWidth, height: screenHeight } =
- Dimensions.get('window');
- const handleBarCodeScanned = ({ bounds, data, type }) => {
- const { origin, size } = bounds;
- // Calculate the size of the square transparent area
- const transparentAreaSize = Math.min(
- screenWidth * 0.6,
- screenHeight * 0.3
- );
- const transparentAreaX = (screenWidth - transparentAreaSize) / 2;
- const transparentAreaY = (screenHeight - transparentAreaSize) / 2;
- // Check if the barcode is within the transparent area
- if (
- origin.x >= transparentAreaX &&
- origin.y >= transparentAreaY &&
- origin.x + size.width <= transparentAreaX + transparentAreaSize &&
- origin.y + size.height <= transparentAreaY + transparentAreaSize
- ) {
- setScanned(true);
- console.log(` type: ${type} data: ${data} `);
- if (type === 'qr') {
- console.log('QR Code link:', data);
- }
- setTimeout(() => {
- setScanned(false);
- }, 5000);
- }
- };
- const dummyDataChooseCarForCharging = [
- {
- imageUrl: require('../../../../assets/car1.png'),
- VehicleName: 'TESLA - Model 3',
- isDefault: true
- },
- { VehicleName: 'TESLA - Model Y', isDefault: false },
- {
- imageUrl: require('../../../../assets/car1.png'),
- VehicleName: 'TESLA - Model X',
- isDefault: false
- },
- { VehicleName: 'TESLA - Model 3', isDefault: false }
- ];
- const ChooseCar = () => {
- const isLargeScreen = screenHeight >= 800;
- return (
- <View
- style={{
- ...(isLargeScreen
- ? {
- marginTop: '10%',
- marginBottom: '12%',
- paddingBottom: 12,
- backgroundColor: 'rgba(0,0,0,0.7)'
- }
- : {
- // marginVertical: '5%',
- // paddingBottom: 12,
- flex: 1,
- alignItems: 'center',
- justifyContent: 'center'
- })
- }}
- >
- <View className=" justify-center items-center flex-1">
- {/* <View className="flex-row items-center justify-between w-full">
- <View className="pt-2">
- <Pressable
- className=""
- onPress={() => {
- if (router.canGoBack()) {
- router.back();
- } else {
- router.replace('mainPage');
- }
- }}
- >
- <CrossLogoWhiteSvg />
- </Pressable>
- </View>
- <Text className="text-base text-white pt-2">
- 選擇充電車輛
- </Text>
- <Text className="text-xl text-white pt-2"></Text>
- </View> */}
- <View
- style={{
- ...(isLargeScreen
- ? {}
- : {
- backgroundColor: 'rgba(0,0,0,0.7)',
-
- })
- }}
- >
- <View className="w-full">
- <View className="flex-row items-center justify-between mx-[5%] ">
- <Pressable
- className="pt-4 "
- onPress={() => {
- if (router.canGoBack()) {
- router.back();
- } else {
- router.replace('mainPage');
- }
- }}
- >
- <CrossLogoWhiteSvg />
- </Pressable>
- <Text className="text-base text-white pt-2">
- 選擇充電車輛
- </Text>
- <Text className="text-xl text-white pt-2"></Text>
- </View>
- <ScrollView
- horizontal={true}
- showsHorizontalScrollIndicator={false}
- contentContainerStyle={{
- alignItems: 'center',
- flexDirection: 'row',
- marginVertical: 12
- }}
- className="space-x-2 mx-[5%]"
- >
- {dummyDataChooseCarForCharging.map(
- (car, index) => (
- <ChooseCarForChargingRow
- onPress={() =>
- router.push(
- '/(auth)/(tabs)/(charging)/chargingPage'
- )
- }
- imageUrl={car.imageUrl}
- key={`${car.VehicleName}+${index}`}
- VehicleName={car.VehicleName}
- isDefault={car.isDefault}
- />
- )
- )}
- </ScrollView>
- </View>
- {/* <ScrollView
- horizontal={true}
- showsHorizontalScrollIndicator={false}
- contentContainerStyle={
- {
- alignItems: 'center',
- flexDirection: 'row',
- marginVertical: 8
- }
- }
- className="space-x-2"
- >
- {dummyDataChooseCarForCharging.map((car, index) => (
- <ChooseCarForChargingRow
- onPress={() =>
- router.push(
- '/(auth)/(tabs)/(charging)/chargingPage'
- )
- }
- imageUrl={car.imageUrl}
- key={`${car.VehicleName}+${index}`}
- VehicleName={car.VehicleName}
- isDefault={car.isDefault}
- />
- ))}
- </ScrollView> */}
- {/* <Text className='text-2xl'>Hello</Text> */}
- </View>
- </View>
- </View>
- );
- };
- return (
- <View style={styles.container} ref={viewRef}>
- <CameraView
- style={styles.camera}
- facing="back"
- barcodeScannerSettings={{
- barcodeTypes: ['qr']
- }}
- onBarcodeScanned={scanned ? undefined : handleBarCodeScanned}
- responsiveOrientationWhenOrientationLocked={true}
- >
- <View style={styles.overlay}>
- <View style={styles.topOverlay}>
- <ChooseCar />
- </View>
- <View style={styles.centerRow}>
- <View style={styles.leftOverlay}></View>
- <View style={styles.transparentArea}></View>
- <View style={styles.rightOverlay} />
- </View>
- <View
- className="items-center justify-between"
- style={styles.bottomOverlay}
- >
- <View>
- <Text className="text-white text-lg font-bold mt-2 ">
- 請掃瞄充電座上的二維碼
- </Text>
- </View>
- <View className="flex-row space-x-2 items-center ">
- <QuestionSvg />
- <Pressable onPress={() => console.log('需要協助?')}>
- <Text className="text-white text-base">
- 需要協助?
- </Text>
- </Pressable>
- </View>
- <View />
- </View>
- </View>
- </CameraView>
- </View>
- );
- };
- const styles = StyleSheet.create({
- container: {
- flex: 1
- },
- camera: {
- flex: 1
- },
- overlay: {
- flex: 1
- },
- topOverlay: {
- flex: 35,
- alignItems: 'center',
- backgroundColor: 'rgba(0,0,0,0.5)'
- },
- centerRow: {
- flex: 30,
- flexDirection: 'row'
- },
- leftOverlay: {
- flex: 20,
- backgroundColor: 'rgba(0,0,0,0.5)'
- },
- transparentArea: {
- flex: 60,
- aspectRatio: 1,
- position: 'relative'
- },
- rightOverlay: {
- flex: 20,
- backgroundColor: 'rgba(0,0,0,0.5)'
- },
- bottomOverlay: {
- flex: 35,
- backgroundColor: 'rgba(0,0,0,0.5)'
- }
- });
- export default ScanQrPage;
|