railbird-gql/component/video/camera.tsx

83 lines
2.3 KiB
TypeScript

import React, { useCallback, useRef, useState } from 'react'
import { StyleSheet, Text, View } from 'react-native'
import { Camera, useCameraPermission, useCameraDevice, useCameraFormat, PhotoFile, VideoFile, CameraRuntimeError } from 'react-native-vision-camera'
import { RecordingButton } from './capture-button'
import { useIsForeground } from './is-foreground'
export default function CameraScreen(): React.ReactElement {
const camera = useRef<Camera>(null)
const { hasPermission, requestPermission } = useCameraPermission()
const [isCameraInitialized, setIsCameraInitialized] = useState(false)
const isForeground = useIsForeground()
const isActive = isForeground
const onError = useCallback((error: CameraRuntimeError) => {
console.error(error)
}, [])
const onInitialized = useCallback(() => {
console.log('Camera initialized!')
setIsCameraInitialized(true)
}, [])
const onMediaCaptured = useCallback(
(media: PhotoFile | VideoFile) => {
console.log(`Media captured! ${JSON.stringify(media)}`)
},
[],
)
if (!hasPermission) {
requestPermission()
// Error handling in case they refuse to give permission
}
const device = useCameraDevice('back')
const format = useCameraFormat(device, [
{ videoResolution: { width: 3048, height: 2160 } },
{ fps: 60 }
])
if (device === null) {
return <Text>Camera not available. Does user have permissions: {hasPermission}</Text>
}
return (
hasPermission && (
<View style={styles.container}>
<Camera
ref={camera}
style={StyleSheet.absoluteFill}
device={device}
format={format}
onInitialized={onInitialized}
onError={onError}
video={true}
photo={false}
orientation='portrait' // TODO: #60
isActive={isActive}
/>
<RecordingButton
style={styles.captureButton}
camera={camera}
onMediaCaptured={onMediaCaptured}
enabled={isCameraInitialized}
/>
</View>
)
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'black',
},
captureButton: {
position: 'absolute',
alignSelf: 'center',
bottom: 20, // Should come from SafeAreaProvider
},
})