import React, { useRef, useState } from 'react'; import { StyleSheet, TouchableOpacity, View, Text } from 'react-native'; import ActionSheet, { Route, SheetManager, useSheetRouter } from 'react-native-actions-sheet'; import { getFontSize } from 'src/utils'; import { Colors } from 'src/theme'; import { WarningProps } from '../types'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { usePostReportConversationMutation } from '@api/chat'; import * as ImagePicker from 'expo-image-picker'; import * as DocumentPicker from 'react-native-document-picker'; import { MaterialCommunityIcons } from '@expo/vector-icons'; import RouteB from './RouteB'; import MegaphoneIcon from 'assets/icons/messages/megaphone.svg'; import LocationIcon from 'assets/icons/messages/location.svg'; import CameraIcon from 'assets/icons/messages/camera.svg'; import ImagesIcon from 'assets/icons/messages/images.svg'; import { storage, StoreType } from 'src/storage'; const AttachmentsModal = () => { const insets = useSafeAreaInsets(); const token = storage.get('token', StoreType.STRING) as string; const [shouldOpenWarningModal, setShouldOpenWarningModal] = useState(null); const { mutateAsync: reportUser } = usePostReportConversationMutation(); const [data, setData] = useState(null); const chatDataRef = useRef(null); const handleSheetOpen = (payload: any) => { chatDataRef.current = payload; setData(payload); }; const handleReport = async () => { const chatData = chatDataRef.current; if (!chatData) return; setShouldOpenWarningModal({ title: `Report ${chatData.name}`, buttonTitle: 'Report', message: `Are you sure you want to report ${chatData.name}?\nIf you proceed, the chat history with ${chatData.name} will become visible to NomadMania admins for investigation.`, action: async () => { await reportUser({ token, reported_user_id: chatData.uid }); } }); setTimeout(() => { SheetManager.hide('chat-attachments'); setShouldOpenWarningModal(null); }, 300); }; const handleOpenGallery = async () => { const chatData = chatDataRef.current; if (!chatData) return; try { const perm = await ImagePicker.requestMediaLibraryPermissionsAsync(); if (!perm.granted) { console.warn('Permission for gallery not granted'); return; } const result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.All, allowsMultipleSelection: true, quality: 1, selectionLimit: 4 }); if (!result.canceled && result.assets) { const files = result.assets.map((asset) => ({ uri: asset.uri, type: asset.type === 'video' ? 'video' : 'image' })); chatData.onSendMedia(files); } SheetManager.hide('chat-attachments'); } catch (err) { console.warn('Gallery error: ', err); } }; const handleOpenCamera = async () => { const chatData = chatDataRef.current; if (!chatData) return; try { const perm = await ImagePicker.requestCameraPermissionsAsync(); if (!perm.granted) { console.warn('Permission for camera not granted'); return; } const result = await ImagePicker.launchCameraAsync({ mediaTypes: ImagePicker.MediaTypeOptions.Images, quality: 1 }); if (!result.canceled && result.assets) { const files = result.assets.map((asset) => ({ uri: asset.uri, type: asset.type === 'video' ? 'video' : 'image' })); chatData.onSendMedia(files); } SheetManager.hide('chat-attachments'); } catch (err) { console.warn('Camera error: ', err); } }; const handleShareLiveLocation = () => { const chatData = chatDataRef.current; if (!chatData) return; chatData.onShareLiveLocation(); SheetManager.hide('chat-attachments'); }; const handleSendFile = async () => { const chatData = chatDataRef.current; if (!chatData) return; try { const res = await DocumentPicker.pick({ type: [DocumentPicker.types.allFiles], allowMultiSelection: false }); let file = { uri: res[0].uri, name: res[0].name, type: res[0].type }; if ((file.name && !file.name.includes('.')) || !file.type) { file = { ...file, type: file.type || 'application/octet-stream' }; } if (chatData.onSendFile) { chatData.onSendFile([file]); } } catch (err) { if (DocumentPicker.isCancel(err)) { } else { console.warn('DocumentPicker error:', err); } } SheetManager.hide('chat-attachments'); }; const RouteA = () => { const router = useSheetRouter('chat-attachments'); return ( Gallery Camera File { router?.navigate('route-b'); }} > Location {/* Live */} Report ); }; const routes: Route[] = [ { name: 'route-a', component: RouteA }, { name: 'route-b', component: RouteB, params: { onSendLocation: data?.onSendLocation, insetsBottom: insets.bottom } } ]; return ( { const payload = sheetRef || null; handleSheetOpen(payload); }} onClose={() => { if (shouldOpenWarningModal) { chatDataRef.current?.setModalInfo({ visible: true, type: 'delete', title: shouldOpenWarningModal.title, buttonTitle: shouldOpenWarningModal.buttonTitle, message: shouldOpenWarningModal.message, action: shouldOpenWarningModal.action }); } }} /> ); }; const styles = StyleSheet.create({ option: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between' }, optionText: { fontSize: getFontSize(12), fontWeight: '600', color: Colors.DARK_BLUE }, dangerOption: { paddingVertical: 10, borderBottomWidth: 1, borderBlockColor: Colors.WHITE }, dangerText: { color: Colors.RED }, container: { backgroundColor: Colors.WHITE }, optionRow: { flexDirection: 'row', justifyContent: 'space-between', paddingHorizontal: '5%', marginVertical: 20, flexWrap: 'wrap' }, optionItem: { width: '30%', paddingVertical: 8, marginBottom: 12, alignItems: 'center' }, optionLabel: { marginTop: 6, fontSize: 12, color: Colors.DARK_BLUE, fontWeight: '700' } }); export default AttachmentsModal;