From 1889ed4379fdd3c0a2015a31edac3bc071d9952f Mon Sep 17 00:00:00 2001 From: Jason Date: Fri, 13 Sep 2024 18:28:50 -0500 Subject: [PATCH] add zoom, removed invalid qrcode check, remove auto navigate, and add button --- src/screens/events/QRCodeScanningScreen.tsx | 174 ++++++++++++++------ 1 file changed, 123 insertions(+), 51 deletions(-) diff --git a/src/screens/events/QRCodeScanningScreen.tsx b/src/screens/events/QRCodeScanningScreen.tsx index ff153ecc..9287c570 100644 --- a/src/screens/events/QRCodeScanningScreen.tsx +++ b/src/screens/events/QRCodeScanningScreen.tsx @@ -1,15 +1,21 @@ -import { View, Text, Button, StyleSheet, TouchableHighlight, TouchableOpacity, Alert, Animated, Easing } from 'react-native'; +import { View, Text, TouchableOpacity, Alert, Animated, Easing } from 'react-native'; import React, { useEffect, useRef, useState } from 'react'; import { CameraView, Camera } from 'expo-camera'; import { SafeAreaView } from 'react-native-safe-area-context'; +import { GestureHandlerRootView, PinchGestureHandler, PinchGestureHandlerGestureEvent, State } from 'react-native-gesture-handler'; import { MainStackParams } from '../../types/navigation'; import { Octicons } from '@expo/vector-icons'; import { NativeStackScreenProps } from '@react-navigation/native-stack'; const QRCodeScanningScreen = ({ navigation }: NativeStackScreenProps) => { const [hasCameraPermissions, setHasCameraPermissions] = useState(null); - const [scanned, setScanned] = useState(false); const pulseAnim = useRef(new Animated.Value(1)).current; + const [zoom, setZoom] = useState(0); + const [qrData, setQrData] = useState<{ id: string; mode: string } | null>(null); + const cameraRef = useRef(null); + const lastScale = useRef(1); + const maxZoom = 0.05; + const timeoutRef = useRef(null); useEffect(() => { const getBarCodeScannerPermissions = async () => { @@ -42,29 +48,60 @@ const QRCodeScanningScreen = ({ navigation }: NativeStackScreenProps { - console.log('Data Received', `Bar code with type ${type} and data ${data} has been scanned!`); - setScanned(true); const dataRegex: RegExp = /^tamu-shpe:\/\/event\?id=[a-zA-z0-9]+&mode=(sign-in|sign-out)$/i; - if (!dataRegex.test(data)) { - Alert.alert("Invalid QR Code", "Either this QR Code is invalid or was misscanned. Please try again.", [ - { - text: 'ok', - onPress: () => { - setScanned(false); - } - } - ]); - } - else { + + if (dataRegex.test(data)) { const linkVariables = data.split('?')[1].split('&'); const id = linkVariables[0].split('=')[1]; const mode = linkVariables[1].split('=')[1]; - if (id && mode === 'sign-in' || mode === 'sign-out') { - navigation.navigate("EventVerificationScreen", { id, mode }); + if (id && (mode === 'sign-in' || mode === 'sign-out')) { + setQrData({ id, mode }); + + // Clear any existing timeout when valid data is found + if (timeoutRef.current) { + clearTimeout(timeoutRef.current); + } + + // Set a timeout to clear qrData after 3 seconds if no new valid QR codes are detected + timeoutRef.current = setTimeout(() => { + setQrData(null); + }, 5000); } } }; + useEffect(() => { + return () => { + if (timeoutRef.current) { + clearTimeout(timeoutRef.current); + } + }; + }, []); + + const handleConfirm = () => { + if (qrData) { + navigation.navigate("EventVerificationScreen", { id: qrData.id, mode: qrData.mode as "sign-in" | "sign-out" }); + setQrData(null); + } + }; + + const handlePinchGestureEvent = ({ nativeEvent }: PinchGestureHandlerGestureEvent) => { + if (nativeEvent.scale !== 0) { + const baseZoomFactor = 0.0004; + const zoomSensitivity = 0.1; + const dynamicFactor = zoom * zoomSensitivity + baseZoomFactor; + const scaleChange = (nativeEvent.scale - 1) * dynamicFactor * (nativeEvent.scale > 1 ? 1 : 2); + const newZoom = Math.min(Math.max(zoom + scaleChange, 0), maxZoom); + setZoom(newZoom); + } + }; + + const handlePinchStateChange = ({ nativeEvent }: PinchGestureHandlerGestureEvent) => { + if (nativeEvent.state === State.END || nativeEvent.state === State.CANCELLED) { + lastScale.current = 1; + } + }; + if (hasCameraPermissions === null) { return Requesting for camera permission; } @@ -73,43 +110,78 @@ const QRCodeScanningScreen = ({ navigation }: NativeStackScreenProps - {/* Header */} - - - Scanner + + + {/* Header */} + + + Scanner + + navigation.goBack()}> + + - navigation.goBack()} > - - - - - - {/* Pulsing Effect */} - - - - - - - + + + + {/* Pulsing Effect */} + + + + + + + + + - - - - - Using Scanner - Scan the QRCode provided by the event host. - - + + {(1 + zoom * 100).toFixed(1)}x + + + {/* Button for Sign In/Sign Out */} + {qrData && ( + + + + {qrData.mode === 'sign-in' ? 'Sign in to the event' : 'Sign out of the event'} + + + + )} + + + + + Using Scanner + Scan the QRCode provided by the event host. + + + ); }; -export default QRCodeScanningScreen; \ No newline at end of file +export default QRCodeScanningScreen;