railbird-gql/component/video/capture-button.tsx

110 lines
2.9 KiB
TypeScript

import React, { useCallback, useRef, useState } from 'react';
import { TouchableOpacity, StyleSheet, View } from 'react-native';
import { CameraRoll } from "@react-native-camera-roll/camera-roll";
export const RecordingButton = ({ style, camera, onMediaCaptured, enabled, setIsPressingButton }) => {
const isRecording = useRef(false)
// UseRef won't trigger a re-render
const [, setRecordingState] = useState(false);
const onStoppedRecording = useCallback(() => {
console.log(' on stopped recording called')
isRecording.current = false
setRecordingState(false)
console.log('stopped recording video!')
}, [])
const stopRecording = useCallback(async () => {
console.log(' stop recording called')
try {
if (camera.current === null) {
throw new Error('Camera ref is null!') // Error handling could be more graceful
}
console.log('calling stopRecording()...')
await camera.current.stopRecording()
console.log('called stopRecording()!')
} catch (e) {
console.error('failed to stop recording!', e)
}
}, [camera])
const startRecording = useCallback(() => {
try {
if (camera.current === null) {
throw new Error('Camera ref is null!') // Error handling could be more graceful
}
console.log('calling startRecording()...')
camera.current.startRecording({
onRecordingError: (error) => {
console.error('Recording failed!', error)
onStoppedRecording()
},
onRecordingFinished: async (video) => {
console.log(`Recording successfully finished! ${video.path}`)
onMediaCaptured(video, 'video')
const path = video.path
await CameraRoll.saveAsset(`file://${path}`, {
type: 'video',
})
onStoppedRecording()
},
})
// TODO: wait until startRecording returns to actually find out if the recording has successfully started
console.log('called startRecording()!')
isRecording.current = true
console.log('after setting isRecording ref')
setRecordingState(true)
} catch (e) {
console.error('failed to start recording!', e, 'camera')
}
}, [camera, onMediaCaptured, onStoppedRecording])
const handlePress = () => {
if (isRecording.current) {
stopRecording();
} else {
startRecording();
}
};
// console.log('ref', isRecording.current)
return (
<TouchableOpacity
style={[styles.captureButton, style]}
onPress={handlePress}
disabled={!enabled}
>
<View style={isRecording.current ? styles.recordingSquare : styles.innerCircle} />
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
captureButton: {
height: 80,
width: 80,
borderRadius: 40,
borderWidth: 3,
borderColor: 'white',
backgroundColor: 'transparent',
justifyContent: 'center',
alignItems: 'center',
},
innerCircle: {
height: 70,
width: 70,
borderRadius: 35,
backgroundColor: '#FF3B30',
},
recordingSquare: {
height: 40,
width: 40,
borderRadius: 10,
backgroundColor: '#FF3B30',
},
});
export default RecordingButton;