/** * FileUpload - Datei-Auswahl und -Versand * * Oeffnet den Dateimanager des Geraets, zeigt eine Vorschau * und konvertiert die Datei zu Base64 fuer die Uebertragung. */ import React, { useState } from 'react'; import { View, Text, TouchableOpacity, Image, StyleSheet, ActivityIndicator, } from 'react-native'; import DocumentPicker, { DocumentPickerResponse, } from 'react-native-document-picker'; import RNFS from 'react-native-fs'; // --- Typen --- export interface FileData { name: string; type: string; size: number; base64: string; uri: string; } interface FileUploadProps { onFileSelected: (file: FileData) => void; onCancel: () => void; } // Unterstuetzte Dateitypen const SUPPORTED_TYPES = [ DocumentPicker.types.images, DocumentPicker.types.pdf, DocumentPicker.types.docx, DocumentPicker.types.plainText, ]; // --- Komponente --- const FileUpload: React.FC = ({ onFileSelected, onCancel }) => { const [selectedFile, setSelectedFile] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const pickFile = async () => { setError(null); try { const result = await DocumentPicker.pick({ type: SUPPORTED_TYPES, copyTo: 'cachesDirectory', }); if (result.length > 0) { setSelectedFile(result[0]); } } catch (err) { if (DocumentPicker.isCancel(err)) { onCancel(); } else { setError('Fehler beim Auswaehlen der Datei'); console.error('[FileUpload] Fehler:', err); } } }; const sendFile = async () => { if (!selectedFile) return; setLoading(true); try { // Datei lesen und zu Base64 konvertieren const filePath = selectedFile.fileCopyUri || selectedFile.uri; // URI-Schema entfernen fuer RNFS (file:// → absoluter Pfad) const cleanPath = filePath.replace('file://', ''); const base64 = await RNFS.readFile(cleanPath, 'base64'); const fileData: FileData = { name: selectedFile.name || 'unbenannt', type: selectedFile.type || 'application/octet-stream', size: selectedFile.size || 0, base64, uri: selectedFile.uri, }; onFileSelected(fileData); } catch (err) { setError('Fehler beim Verarbeiten der Datei'); console.error('[FileUpload] Verarbeitungsfehler:', err); } finally { setLoading(false); } }; const isImage = selectedFile?.type?.startsWith('image/'); const fileSizeFormatted = selectedFile?.size ? selectedFile.size > 1024 * 1024 ? `${(selectedFile.size / (1024 * 1024)).toFixed(1)} MB` : `${(selectedFile.size / 1024).toFixed(0)} KB` : ''; return ( {!selectedFile ? ( // Datei auswaehlen {'\uD83D\uDCC1'} Datei ausw\u00E4hlen JPG, PNG, PDF, DOCX, TXT ) : ( // Vorschau und Senden {isImage ? ( ) : ( {'\uD83D\uDCC4'} )} {selectedFile.name} {fileSizeFormatted} {error && {error}} setSelectedFile(null)} > Andere Datei {loading ? ( ) : ( Senden )} )} ); }; // --- Styles --- const styles = StyleSheet.create({ container: { backgroundColor: '#1A1A2E', borderRadius: 16, padding: 20, margin: 12, }, pickButton: { alignItems: 'center', padding: 30, borderWidth: 2, borderColor: '#2A2A3E', borderStyle: 'dashed', borderRadius: 12, }, pickIcon: { fontSize: 40, marginBottom: 10, }, pickText: { color: '#FFFFFF', fontSize: 16, fontWeight: '600', }, pickHint: { color: '#666680', fontSize: 12, marginTop: 4, }, previewContainer: { alignItems: 'center', }, imagePreview: { width: 200, height: 200, borderRadius: 12, marginBottom: 12, resizeMode: 'cover', }, filePreview: { width: 80, height: 80, borderRadius: 12, backgroundColor: '#2A2A3E', alignItems: 'center', justifyContent: 'center', marginBottom: 12, }, fileIcon: { fontSize: 36, }, fileName: { color: '#FFFFFF', fontSize: 14, fontWeight: '500', maxWidth: 250, }, fileSize: { color: '#666680', fontSize: 12, marginTop: 2, }, errorText: { color: '#FF3B30', fontSize: 12, marginTop: 8, }, buttonRow: { flexDirection: 'row', marginTop: 16, gap: 12, }, cancelButton: { paddingHorizontal: 20, paddingVertical: 10, borderRadius: 8, backgroundColor: '#2A2A3E', }, cancelButtonText: { color: '#8888AA', fontSize: 14, fontWeight: '600', }, sendButton: { paddingHorizontal: 28, paddingVertical: 10, borderRadius: 8, backgroundColor: '#0096FF', minWidth: 90, alignItems: 'center', }, sendButtonText: { color: '#FFFFFF', fontSize: 14, fontWeight: '700', }, }); export default FileUpload;