import { CameraRoll } from "@react-native-camera-roll/camera-roll"; import React, { useCallback, useRef, useState } from "react"; import { StyleProp, StyleSheet, TouchableOpacity, View, ViewStyle, } from "react-native"; // @ts-ignore import { Camera } from "react-native-vision-camera/lib/typescript/Camera"; // @ts-ignore import { VideoFile } from "react-native-vision-camera/lib/typescript/VideoFile"; interface RecordingButtonProps { style: StyleProp; camera: React.RefObject; // eslint-disable-next-line no-unused-vars onMediaCaptured: (media: VideoFile, mediaType: string) => void; enabled: boolean; } export const RecordingButton: React.FC = ({ style, camera, onMediaCaptured, enabled, }) => { const isRecording = useRef(false); // UseRef won't trigger a re-render const [, setRecordingState] = useState(false); const onStoppedRecording = useCallback(() => { isRecording.current = false; setRecordingState(false); console.log("stopped recording video!"); }, []); const stopRecording = useCallback(async () => { 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) => { onMediaCaptured(video, "video"); const path = video.path; await CameraRoll.saveAsset(`file://${path}`, { type: "video", }); onStoppedRecording(); }, }); console.log("called startRecording()!"); isRecording.current = true; setRecordingState(true); } catch (e) { console.error("failed to start recording!", e, "camera"); } }, [camera, onMediaCaptured, onStoppedRecording]); const handlePress = () => { if (isRecording.current) { stopRecording(); } else { startRecording(); } }; return ( ); }; 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;