import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Keyboard, StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native'
import { RNCamera } from 'react-native-camera'
import DeviceInfo from 'react-native-device-info'
import { useSafeAreaFrame, useSafeAreaInsets } from 'react-native-safe-area-context'
import { Defs, Mask, Rect, Svg } from 'react-native-svg'
import Modal from 'src/components/Modal'
import TextButton from 'src/components/TextButton'
import NotAuthorizedView from 'src/qrcode/NotAuthorizedView'
import { QrCode } from 'src/send/types'
import colors from 'src/styles/colors'
import { typeScale } from 'src/styles/fonts'
interface QRScannerProps {
onQRCodeDetected: (qrCode: QrCode) => void
}
const SeeThroughOverlay = () => {
const { width, height } = useSafeAreaFrame()
const margin = 40
const centerBoxSize = width - margin * 2
const centerBoxBorderRadius = 8
// TODO(jeanregisser): Investigate why the mask is pixelated on iOS.
// It's visible on the rounded corners but since they are small, I'm ignoring it for now.
// Node that the Mask component is using hard coded color values solely to
// create the "cutout" effect.
return (
)
}
export default function QRScanner({ onQRCodeDetected }: QRScannerProps) {
const { t } = useTranslation()
const inset = useSafeAreaInsets()
// eslint-disable-next-line react-hooks/rules-of-hooks
const isEmulator = DeviceInfo.useIsEmulator ? DeviceInfo.useIsEmulator().result : false
/**
* Emulator only. When in the emulator we want to be able
* to enter QR codes manually.
*/
const [value, setValue] = useState('')
const [displayEntryModal, setDisplayEntryModal] = useState(false)
const openModal = () => {
setDisplayEntryModal(true)
}
const closeModal = () => {
setDisplayEntryModal(false)
setValue('')
}
const submitModal = () => {
Keyboard.dismiss()
closeModal()
// add a delay to allow modal to close before calling onQRCodeDetected,
// otherwise nothing is clickable in the next screen this navigates to. A
// better solution is to use onModalHide prop of Modal, but this is an
// emulator only feature, so this is good enough.
setTimeout(() => {
onQRCodeDetected({ type: '', data: value })
}, 500)
}
const onModalTextChange = (text: string) => {
setValue(text)
}
const cameraScanInfo = (
{t('cameraScanInfo')}
)
return (
}
testID={'Camera'}
>
{isEmulator ? (
{cameraScanInfo}
) : (
cameraScanInfo
)}
{t('enterQRCode')}
{t('cancel')}
{t('submit')}
)
}
const styles = StyleSheet.create({
camera: {
flex: 1,
overflow: 'hidden',
},
infoText: {
position: 'absolute',
left: 9,
right: 9,
bottom: 32,
...typeScale.labelSemiBoldSmall,
lineHeight: undefined,
color: colors.qrTabBarSecondary,
textAlign: 'center',
paddingHorizontal: 30,
},
manualInput: {
...typeScale.bodyMedium,
marginBottom: 12,
paddingHorizontal: 12,
paddingVertical: 0,
marginTop: 8,
alignItems: 'flex-start',
borderColor: colors.contentSecondary,
borderRadius: 4,
borderWidth: 1.5,
height: 80,
maxHeight: 150,
},
manualTitle: {
marginBottom: 6,
...typeScale.titleSmall,
},
actions: {
flexDirection: 'row',
justifyContent: 'space-around',
maxWidth: '100%',
flexWrap: 'wrap',
},
cancelButton: {
color: colors.contentSecondary,
},
})