import { Button } from '@/components/ui/button';
import { Camera, CaptureSuccess } from '@/components/ui/camera';
import { Image } from '@/components/ui/image';
import { Text } from '@/components/ui/text';
import { Video } from '@/components/ui/video';
import { View } from '@/components/ui/view';
import { useColor } from '@/hooks/useColor';
import * as MediaLibrary from 'expo-media-library';
import { Download, Upload, X } from 'lucide-react-native';
import { useState } from 'react';
import { Alert, Dimensions, StyleSheet, TouchableOpacity } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
const { width: screenWidth } = Dimensions.get('window');
export function CameraPreview() {
const [showCamera, setShowCamera] = useState(false);
const [cameraHeight, setCameraHeight] = useState((screenWidth * 4) / 3);
const [capturedMedia, setCapturedMedia] = useState<{
uri: string;
type: 'picture' | 'video';
} | null>(null);
const [showPreview, setShowPreview] = useState(false);
const [mediaLibraryPermission, requestMediaLibraryPermission] =
MediaLibrary.usePermissions();
const backgroundColor = useColor('background');
const cardColor = useColor('card');
const textColor = useColor('text');
const handleCapture = (results: CaptureSuccess) => {
setCameraHeight(results.cameraHeight);
setCapturedMedia({ type: results.type, uri: results.uri });
setShowCamera(false);
setShowPreview(true);
};
const handleVideoCapture = (results: CaptureSuccess) => {
setCameraHeight(results.cameraHeight);
setCapturedMedia({ type: results.type, uri: results.uri });
setShowCamera(false);
setShowPreview(true);
};
const handleOpenCamera = () => {
setCapturedMedia(null);
setShowPreview(false);
setShowCamera(true);
};
const handleCloseCamera = () => {
setShowCamera(false);
};
const handleRetakeMedia = () => {
setCapturedMedia(null);
setShowPreview(false);
setShowCamera(true);
};
const handleSaveToAlbum = async () => {
if (!capturedMedia) return;
try {
// Request permission if not granted
if (mediaLibraryPermission?.status !== 'granted') {
const permission = await requestMediaLibraryPermission();
if (!permission.granted) {
Alert.alert(
'Permission Required',
'Please grant permission to save media to your picture library.'
);
return;
}
}
// Save to media library
await MediaLibrary.saveToLibraryAsync(capturedMedia.uri);
Alert.alert(
'Success!',
`${
capturedMedia.type === 'picture' ? 'Photo' : 'Video'
} saved to your picture library.`,
[
{
text: 'OK',
onPress: () => {
setCapturedMedia(null);
setShowPreview(false);
},
},
]
);
} catch (error) {
console.error('Error saving to album:', error);
Alert.alert('Error', 'Failed to save media to your picture library.');
}
};
const handleUploadAction = () => {
if (!capturedMedia) return;
// This is where you would implement your upload logic
// For example: upload to a server, save to database, etc.
const mediaDetails = {
uri: capturedMedia.uri,
type: capturedMedia.type,
timestamp: new Date().toISOString(),
// Add any other metadata you need
};
console.log('Media details for upload/processing:', mediaDetails);
// Example: Call your upload function
// uploadToServer(mediaDetails);
// saveToDatabase(mediaDetails);
Alert.alert(
'Upload Action',
`${
capturedMedia.type === 'picture' ? 'Photo' : 'Video'
} ready for processing.\n\nCheck console for media details.`,
[
{
text: 'Continue',
onPress: () => {
// You might want to keep the preview open or close it
// depending on your use case
},
},
{
text: 'Done',
onPress: () => {
// setCapturedMedia(null);
// setShowPreview(false);
},
},
]
);
};
// Preview Mode
if (showPreview && capturedMedia) {
return (
{capturedMedia.type === 'picture' && capturedMedia.uri ? (
) : (
)}
{/* Top Floating Buttons */}
);
}
// Camera Mode
if (showCamera) {
return (
);
}
// Main Screen
return (
Camera Component
Tap the button below to open the camera and capture photos or videos.
After capturing, you can preview, save, or process your media.
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
content: {
flex: 1,
padding: 20,
justifyContent: 'center',
alignItems: 'center',
},
title: {
marginBottom: 16,
textAlign: 'center',
},
description: {
textAlign: 'center',
marginBottom: 32,
paddingHorizontal: 20,
},
lastCaptureContainer: {
padding: 16,
borderRadius: 12,
marginBottom: 32,
alignItems: 'center',
maxWidth: '100%',
},
lastCaptureTitle: {
marginBottom: 12,
},
thumbnailImage: {
width: 120,
height: 120,
borderRadius: 8,
},
videoThumbnailContainer: {
position: 'relative',
width: 120,
height: 120,
borderRadius: 8,
overflow: 'hidden',
},
playIconOverlay: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgba(0, 0, 0, 0.3)',
},
playIcon: {
fontSize: 24,
},
viewButton: {
paddingHorizontal: 16,
paddingVertical: 8,
borderRadius: 8,
marginTop: 12,
},
viewButtonText: {
color: 'white',
fontWeight: '600',
},
buttonContainer: {
width: '100%',
gap: 16,
alignItems: 'center',
},
button: {
minWidth: 200,
},
previewContainer: {
width: screenWidth,
borderRadius: 12,
overflow: 'hidden',
position: 'relative',
marginHorizontal: 0,
},
previewMedia: {
width: '100%',
height: '100%',
},
topFloatingButtons: {
position: 'absolute',
bottom: 40,
left: 20,
right: 20,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
floatingButton: {
width: 56,
height: 56,
borderRadius: 28,
justifyContent: 'center',
alignItems: 'center',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 4,
elevation: 5,
},
bottomActionContainer: {
padding: 20,
alignItems: 'center',
},
uploadButton: {
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 32,
paddingVertical: 16,
borderRadius: 12,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.15,
shadowRadius: 4,
elevation: 3,
},
uploadIcon: {
marginRight: 12,
},
uploadButtonText: {
color: 'white',
fontSize: 18,
fontWeight: '600',
},
mediaInfo: {
alignItems: 'center',
paddingHorizontal: 20,
paddingBottom: 20,
},
mediaInfoText: {
fontSize: 16,
fontWeight: '600',
marginBottom: 4,
},
mediaInfoSubtext: {
fontSize: 14,
textAlign: 'center',
},
});