import React, { useState } from 'react'; import { View, StyleSheet, ScrollView, TouchableOpacity, ActivityIndicator, Text, Image } from 'react-native'; import ActionSheet, { SheetManager } from 'react-native-actions-sheet'; import * as yup from 'yup'; import * as ImagePicker from 'expo-image-picker'; import { chatStyles } from './styles'; import { Colors } from 'src/theme'; import { AvatarWithInitials, Input } from 'src/components'; import Checkbox from 'expo-checkbox'; import CameraIcon from 'assets/icons/messages/camera.svg'; import { API_HOST } from 'src/constants'; import { FlashList } from '@shopify/flash-list'; import { Formik } from 'formik'; import { useNavigation } from '@react-navigation/native'; import { usePostUpdateGroupSettingsMutation, usePostRemoveFromGroupMutation } from '@api/chat'; import { getFontSize } from 'src/utils'; import CheckSvg from 'assets/icons/travels-screens/circle-check.svg'; import { StoreType, storage } from 'src/storage'; const SettingsSchema = yup.object({ name: yup .string() .required('name is required') .min(3, 'group name should be at least 3 characters'), description: yup.string().optional().max(8000, 'description should not exceed 8000 characters') }); const SearchModal = () => { const currentUserId = storage.get('uid', StoreType.STRING) as number; const [isSubmitting, setIsSubmitting] = useState(false); const [data, setData] = useState(null); const [image, setImage] = useState(null); const { mutateAsync: editGroup } = usePostUpdateGroupSettingsMutation(); const { mutateAsync: removeFromGroup } = usePostRemoveFromGroupMutation(); const [canEdit, setCanEdit] = useState(false); const [canSend, setCanSend] = useState(false); const [canAdd, setCanAdd] = useState(false); const [canSee, setCanSee] = useState(false); const [filteredUsers, setFilteredUsers] = useState([]); const handleSheetOpen = (payload: any) => { setData(payload); setCanEdit(payload?.settings.members_can_edit_settings === 1); setCanSend(payload?.settings.members_can_send_messages === 1); setCanAdd(payload?.settings.members_can_add_new_members === 1); setCanSee(payload?.settings.members_can_see_members === 1); setFilteredUsers(payload?.members ?? []); }; const pickImage = async () => { let result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.Images, allowsEditing: true, aspect: [4, 4], quality: 1 }); if (!result.canceled) { setImage(result.assets[0]); } }; const toggleUserSelection = (user: any) => { const isSelected = filteredUsers.some((selected) => selected.uid === user.uid); if (isSelected) { setFilteredUsers((prev) => prev.filter((selected) => selected.uid !== user.uid)); } else { setFilteredUsers((prev) => [...prev, user]); } }; const renderUserItem = ({ item }: { item: any }) => { const isSelected = filteredUsers.some((selected) => selected.uid === item.uid); return ( toggleUserSelection(item)} > {item.avatar ? ( ) : ( )} {item.name} {item.admin === 1 && ( Admin )} {item.uid !== +currentUserId && ( {isSelected && } )} ); }; return ( { const payload = sheetRef || null; handleSheetOpen(payload); }} onClose={() => { setImage(null); data && data.refetch(); }} > { if (!data) return; setIsSubmitting(true); const removedUsers = data?.members ?.filter((member: any) => !filteredUsers.some((user) => user.uid === member.uid)) ?.map((member: any) => member.uid); const groupData: any = { token: data.token, group_token: data.groupToken, name: values.name, description: values.description, members_can_edit_settings: canEdit ? 1 : 0, members_can_send_messages: canSend ? 1 : 0, members_can_add_new_members: canAdd ? 1 : 0, members_can_see_members: canSee ? 1 : 0 }; if (image && image.uri) { groupData.group_avatar = { type: image.type || 'image', uri: image.uri, name: image.uri.split('/').pop()! }; } if (removedUsers.length > 0) { await Promise.all( removedUsers.map( async (userId: number) => await removeFromGroup( { token: data.token, group_token: data.groupToken, uid: userId }, { onSuccess: () => { data && data.refetchMembers(); } } ) ) ); } await editGroup(groupData, { onSuccess: () => { setIsSubmitting(false); setTimeout(() => { data && data.setCacheKey(Date.now()); }, 2500); SheetManager.hide('edit-group-modal'); }, onError: () => { setIsSubmitting(false); } }); }} > {(props) => { return ( SheetManager.hide('edit-group-modal')} style={styles.backButton} > Back {isSubmitting ? ( ) : ( props.handleSubmit()} style={styles.saveButton}> Save )} {image || data?.settings?.avatar ? ( <> Change photo ) : ( <> Add photo )} Members can setCanEdit(!canEdit)} > Edit group settings setCanEdit(!canEdit)} /> setCanSend(!canSend)} > Send messages setCanSend(!canSend)} /> setCanAdd(!canAdd)}> Add new members setCanAdd(!canAdd)} /> setCanSee(!canSee)}> See members setCanSee(!canSee)} /> {data?.settings?.admin === 1 ? ( Members: {data?.members?.length} {data?.members?.length > 0 && ( item.uid.toString()} estimatedItemSize={100} extraData={filteredUsers} showsVerticalScrollIndicator={false} contentContainerStyle={{ paddingBottom: 16 }} /> )} ) : null} ); }} ); }; const styles = StyleSheet.create({ sheetContainer: { height: '95%', borderTopLeftRadius: 15, borderTopRightRadius: 15, paddingHorizontal: 16 }, backButton: { paddingVertical: 16, paddingHorizontal: 6 }, saveButton: { paddingVertical: 16, paddingHorizontal: 6 }, loader: { padding: 10 }, groupPhotoImage: { width: 80, height: 80, borderRadius: 40, borderWidth: 1, borderColor: Colors.FILL_LIGHT }, errorBorder: { borderColor: Colors.RED, borderWidth: 1 }, photoContainer: { alignItems: 'center', gap: 8 }, userDetails: { flex: 1 }, userName: { color: Colors.DARK_BLUE, fontSize: getFontSize(14), fontFamily: 'montserrat-700' }, userSubtitle: { color: Colors.DARK_BLUE, fontSize: 14, fontFamily: 'montserrat-500' }, userItem: { flexDirection: 'row', alignItems: 'center', paddingVertical: 8, paddingHorizontal: 12, backgroundColor: Colors.FILL_LIGHT, gap: 8, borderRadius: 8, marginBottom: 6 }, avatar: { width: 36, height: 36, borderRadius: 18, borderWidth: 1, borderColor: Colors.LIGHT_GRAY }, unselectedCircle: { width: 20, height: 20, borderRadius: 10, borderWidth: 1, borderColor: Colors.LIGHT_GRAY, justifyContent: 'center', alignItems: 'center' } }); export default SearchModal;