/** * CameraUpload - Kamera-Foto oder Galerie-Auswahl * * Ermoeglicht das Aufnehmen eines Fotos mit der Geraetekamera * oder die Auswahl aus der Galerie, mit Vorschau vor dem Senden. */ import React, { useState } from 'react'; import { View, Text, TouchableOpacity, Image, StyleSheet, ActivityIndicator, Platform, PermissionsAndroid, } from 'react-native'; import { launchCamera, launchImageLibrary, ImagePickerResponse } from 'react-native-image-picker'; // --- Typen --- export interface PhotoData { base64: string; width: number; height: number; fileName: string; type: string; uri: string; } interface CameraUploadProps { onPhotoSelected: (photo: PhotoData) => void; onCancel: () => void; } // Komprimierungsoptionen const IMAGE_OPTIONS = { mediaType: 'photo' as const, maxWidth: 1920, maxHeight: 1920, quality: 0.8 as const, includeBase64: true, }; // --- Komponente --- const CameraUpload: React.FC = ({ onPhotoSelected, onCancel }) => { const [preview, setPreview] = useState(null); const [loading, setLoading] = useState(false); /** Kamera-Berechtigung pruefen (Android) */ const requestCameraPermission = async (): Promise => { if (Platform.OS !== 'android') return true; try { const granted = await PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.CAMERA, { title: 'ARIA Cockpit - Kamera', message: 'ARIA ben\u00F6tigt Zugriff auf die Kamera.', buttonPositive: 'Erlauben', buttonNegative: 'Ablehnen', }, ); return granted === PermissionsAndroid.RESULTS.GRANTED; } catch { return false; } }; /** Foto mit Kamera aufnehmen */ const takePhoto = async () => { const hasPermission = await requestCameraPermission(); if (!hasPermission) return; launchCamera(IMAGE_OPTIONS, (response) => { if (response.didCancel) { // Benutzer hat abgebrochen return; } if (response.errorCode) { console.error('[CameraUpload] Kamera-Fehler:', response.errorMessage); return; } setPreview(response); }); }; /** Foto aus Galerie auswaehlen */ const pickFromGallery = async () => { launchImageLibrary(IMAGE_OPTIONS, (response) => { if (response.didCancel) return; if (response.errorCode) { console.error('[CameraUpload] Galerie-Fehler:', response.errorMessage); return; } setPreview(response); }); }; /** Ausgewaehltes Foto senden */ const sendPhoto = () => { const asset = preview?.assets?.[0]; if (!asset) return; setLoading(true); const photoData: PhotoData = { base64: asset.base64 || '', width: asset.width || 0, height: asset.height || 0, fileName: asset.fileName || `foto_${Date.now()}.jpg`, type: asset.type || 'image/jpeg', uri: asset.uri || '', }; onPhotoSelected(photoData); setLoading(false); }; const previewUri = preview?.assets?.[0]?.uri; return ( {!preview ? ( // Auswahl: Kamera oder Galerie {'\uD83D\uDCF7'} Foto aufnehmen {'\uD83D\uDDBC\uFE0F'} Aus Galerie Abbrechen ) : ( // Vorschau {previewUri && ( )} setPreview(null)} > Neu {loading ? ( ) : ( Senden )} )} ); }; // --- Styles --- const styles = StyleSheet.create({ container: { backgroundColor: '#1A1A2E', borderRadius: 16, padding: 20, margin: 12, }, optionsContainer: { alignItems: 'center', gap: 12, }, optionButton: { flexDirection: 'row', alignItems: 'center', backgroundColor: '#2A2A3E', borderRadius: 12, padding: 16, width: '100%', }, optionIcon: { fontSize: 28, marginRight: 14, }, optionText: { color: '#FFFFFF', fontSize: 16, fontWeight: '500', }, cancelLink: { marginTop: 8, padding: 8, }, cancelLinkText: { color: '#666680', fontSize: 14, }, previewContainer: { alignItems: 'center', }, imagePreview: { width: '100%', height: 280, borderRadius: 12, resizeMode: 'contain', marginBottom: 16, }, buttonRow: { flexDirection: 'row', gap: 12, }, retakeButton: { paddingHorizontal: 24, paddingVertical: 12, borderRadius: 8, backgroundColor: '#2A2A3E', }, retakeText: { color: '#8888AA', fontSize: 14, fontWeight: '600', }, sendButton: { paddingHorizontal: 32, paddingVertical: 12, borderRadius: 8, backgroundColor: '#0096FF', minWidth: 100, alignItems: 'center', }, sendText: { color: '#FFFFFF', fontSize: 14, fontWeight: '700', }, }); export default CameraUpload;