expo-duooomi-app/app/scan.tsx

64 lines
1.7 KiB
TypeScript

import { Ionicons } from '@expo/vector-icons'
import { CameraView, useCameraPermissions } from 'expo-camera'
import { Stack, useRouter } from 'expo-router'
import { useCallback, useEffect, useRef } from 'react'
import { Pressable, View } from 'react-native'
import { Block } from '@/@share/components'
import { userStore } from '@/stores/userStore'
export default function ScanPage() {
const router = useRouter()
const scannedRef = useRef(false)
const [permission] = useCameraPermissions()
useEffect(() => {
userStore.setScannedQR('')
}, [])
const handleBarcodeScanned = useCallback(
({ data }: { data: string }) => {
if (scannedRef.current) return
scannedRef.current = true
userStore.setScannedQR(data)
setTimeout(() => router.back(), 300)
},
[router],
)
if (!permission?.granted) {
return (
<View className="flex-1 bg-white">
<Stack.Screen options={{ headerShown: false }} />
</View>
)
}
return (
<Block className="flex-1">
<Stack.Screen
options={{
title: '扫描二维码',
headerLeft: () => (
<Pressable onPress={() => router.back()} hitSlop={8}>
<Ionicons name="arrow-back" size={24} color="#0066CC" />
</Pressable>
),
}}
/>
<CameraView
style={{ flex: 1 }}
onBarcodeScanned={scannedRef?.current ? undefined : handleBarcodeScanned}
barcodeScannerSettings={{ barcodeTypes: ['qr'] }}
>
{/* 扫描框 */}
<Block className="absolute inset-0 flex items-center justify-center">
<Block className="size-64 rounded-3xl border-2 border-primary" />
</Block>
</CameraView>
</Block>
)
}