Viktoriia преди 4 месеца
родител
ревизия
46a74d3af6

+ 5 - 0
Route.tsx

@@ -100,6 +100,7 @@ import FullMapScreen from 'src/screens/InAppScreens/MessagesScreen/FullMapScreen
 import EventScreen from 'src/screens/InAppScreens/TravelsScreen/EventScreen';
 import GroupChatScreen from 'src/screens/InAppScreens/MessagesScreen/GroupChatScreen';
 import GroupSettingScreen from 'src/screens/InAppScreens/MessagesScreen/GroupSettingsScreen';
+import MembersListScreen from 'src/screens/InAppScreens/MessagesScreen/MembersListScreen';
 
 enableScreens();
 
@@ -434,6 +435,10 @@ const Route = () => {
               name={NAVIGATION_PAGES.GROUP_SETTINGS}
               component={GroupSettingScreen}
             />
+            <ScreenStack.Screen
+              name={NAVIGATION_PAGES.MEMBERS_LIST}
+              component={MembersListScreen}
+            />
             <ScreenStack.Screen name={NAVIGATION_PAGES.FULL_MAP_VIEW} component={FullMapScreen} />
             <ScreenStack.Screen
               name={NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW}

+ 10 - 0
assets/icons/messages/crossed-user-tie.svg

@@ -0,0 +1,10 @@
+<svg width="20" height="16" viewBox="0 0 20 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_4949_44308)">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M6.92711 6.54893C6.92374 6.54489 6.92036 6.54083 6.91702 6.53677L0.287676 1.3408C-0.0373243 1.08455 -0.0966993 0.612676 0.159551 0.287676C0.415801 -0.0373243 0.887676 -0.0966993 1.21268 0.159551L6.00114 3.91268C6.04836 1.75805 7.83508 0.000175656 10.0002 0.000175656C12.1945 0.000175656 14.0002 1.80583 14.0002 4.00018C14.0002 5.83568 12.7368 7.39921 11.0393 7.86152L19.7127 14.6596C20.0377 14.9158 20.0971 15.3877 19.8408 15.7127C19.5846 16.0377 19.1127 16.0971 18.7877 15.8408L16.961 14.4091C16.9611 14.4106 16.9613 14.4122 16.9615 14.4138L12.5259 10.9371L12.5267 10.9336L11.075 9.79574C11.076 9.79789 11.0769 9.80005 11.0779 9.80224L10.7007 9.50661C10.703 9.50699 10.7053 9.50736 10.7076 9.50777L8.28593 7.60971C8.28121 7.60746 8.27649 7.60518 8.2718 7.60289L6.92711 6.54893ZM16.4418 15.9126C16.3199 15.9688 16.1841 16.0002 16.0408 16.0002H3.95955C3.43143 16.0002 3.00018 15.5721 3.00018 15.0408C3.00018 12.6814 4.62205 10.7002 6.80955 10.1533C7.06268 10.0877 7.30643 10.2533 7.36893 10.5064L8.49393 15.0971L9.53455 11.2252L8.9533 10.2564H8.95643C8.90468 10.1707 8.88243 10.0787 8.88458 9.98943L10.467 11.2297L11.5064 15.0971L12.134 12.5363L16.4418 15.9126Z" fill="#0F3F4F"/>
+</g>
+<defs>
+<clipPath id="clip0_4949_44308">
+<rect width="20" height="16" fill="white"/>
+</clipPath>
+</defs>
+</svg>

+ 3 - 0
assets/icons/messages/dots-vertical.svg

@@ -0,0 +1,3 @@
+<svg width="5" height="16" viewBox="0 0 5 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M2.92461 11.8532C2.37429 11.8532 1.8465 12.0719 1.45736 12.461C1.06822 12.8501 0.849609 13.3779 0.849609 13.9282C0.849609 14.4786 1.06822 15.0063 1.45736 15.3955C1.8465 15.7846 2.37429 16.0032 2.92461 16.0032C3.47493 16.0032 4.00272 15.7846 4.39186 15.3955C4.78099 15.0063 4.99961 14.4786 4.99961 13.9282C4.99961 13.3779 4.78099 12.8501 4.39186 12.461C4.00272 12.0719 3.47493 11.8532 2.92461 11.8532ZM2.92461 5.92467C2.37429 5.92467 1.8465 6.14328 1.45736 6.53242C1.06822 6.92156 0.849609 7.44934 0.849609 7.99967C0.849609 8.54999 1.06822 9.07778 1.45736 9.46691C1.8465 9.85605 2.37429 10.0747 2.92461 10.0747C3.47493 10.0747 4.00272 9.85605 4.39186 9.46691C4.78099 9.07778 4.99961 8.54999 4.99961 7.99967C4.99961 7.44934 4.78099 6.92156 4.39186 6.53242C4.00272 6.14328 3.47493 5.92467 2.92461 5.92467ZM4.99961 2.07109C4.99961 1.52077 4.78099 0.992985 4.39186 0.603847C4.00272 0.214709 3.47493 -0.00390625 2.92461 -0.00390625C2.37429 -0.00390625 1.8465 0.214709 1.45736 0.603847C1.06822 0.992985 0.849609 1.52077 0.849609 2.07109C0.849609 2.62142 1.06822 3.1492 1.45736 3.53834C1.8465 3.92748 2.37429 4.14609 2.92461 4.14609C3.47493 4.14609 4.00272 3.92748 4.39186 3.53834C4.78099 3.1492 4.99961 2.62142 4.99961 2.07109Z" fill="#0F3F4F"/>
+</svg>

+ 10 - 0
assets/icons/messages/user-solid.svg

@@ -0,0 +1,10 @@
+<svg width="14" height="16" viewBox="0 0 14 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_4949_43523)">
+<path d="M7 8C8.06087 8 9.07828 7.57857 9.82843 6.82843C10.5786 6.07828 11 5.06087 11 4C11 2.93913 10.5786 1.92172 9.82843 1.17157C9.07828 0.421427 8.06087 0 7 0C5.93913 0 4.92172 0.421427 4.17157 1.17157C3.42143 1.92172 3 2.93913 3 4C3 5.06087 3.42143 6.07828 4.17157 6.82843C4.92172 7.57857 5.93913 8 7 8ZM5.57188 9.5C2.49375 9.5 0 11.9937 0 15.0719C0 15.5844 0.415625 16 0.928125 16H13.0719C13.5844 16 14 15.5844 14 15.0719C14 11.9937 11.5063 9.5 8.42813 9.5H5.57188Z" fill="#0F3F4F"/>
+</g>
+<defs>
+<clipPath id="clip0_4949_43523">
+<rect width="14" height="16" fill="white"/>
+</clipPath>
+</defs>
+</svg>

+ 10 - 0
assets/icons/messages/user-tie.svg

@@ -0,0 +1,10 @@
+<svg width="14" height="16" viewBox="0 0 14 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_4949_43520)">
+<path d="M3 4C3 5.06087 3.42143 6.07828 4.17157 6.82843C4.92172 7.57857 5.93913 8 7 8C8.06087 8 9.07828 7.57857 9.82843 6.82843C10.5786 6.07828 11 5.06087 11 4C11 2.93913 10.5786 1.92172 9.82843 1.17157C9.07828 0.421427 8.06087 0 7 0C5.93913 0 4.92172 0.421427 4.17157 1.17157C3.42143 1.92172 3 2.93913 3 4ZM5.95312 10.2563L6.53438 11.225L5.49375 15.0969L4.36875 10.5063C4.30625 10.2531 4.0625 10.0875 3.80938 10.1531C1.62188 10.7 0 12.6812 0 15.0406C0 15.5719 0.43125 16 0.959375 16H5.075C5.075 16 5.075 16 5.07812 16H5.25H8.75H8.92188C8.92188 16 8.92188 16 8.925 16H13.0406C13.5719 16 14 15.5687 14 15.0406C14 12.6812 12.3781 10.7 10.1906 10.1531C9.9375 10.0906 9.69375 10.2563 9.63125 10.5063L8.50625 15.0969L7.46562 11.225L8.04688 10.2563C8.24687 9.92188 8.00625 9.5 7.61875 9.5H7H6.38438C5.99688 9.5 5.75625 9.925 5.95625 10.2563H5.95312Z" fill="#0F3F4F"/>
+</g>
+<defs>
+<clipPath id="clip0_4949_43520">
+<rect width="14" height="16" fill="white"/>
+</clipPath>
+</defs>
+</svg>

+ 9 - 6
src/screens/InAppScreens/MessagesScreen/Components/OptionsMenu.tsx

@@ -59,16 +59,19 @@ const OptionsMenu: React.FC<OptionsMenuProps> = ({
         <MaterialCommunityIcons name="content-copy" size={20} color={Colors.DARK_BLUE} />
       </TouchableOpacity>
 
-      <TouchableOpacity style={styles.optionButton} onPress={() => handleOptionPress('delete')}>
-        <Text style={styles.optionText}>Delete</Text>
-        <MaterialCommunityIcons name="delete" size={20} color={Colors.DARK_BLUE} />
-      </TouchableOpacity>
-      {isGroup && (
+      {!isGroup || (isGroup && messagePosition.isMine) ? (
+        <TouchableOpacity style={styles.optionButton} onPress={() => handleOptionPress('delete')}>
+          <Text style={styles.optionText}>Delete</Text>
+          <MaterialCommunityIcons name="delete" size={20} color={Colors.DARK_BLUE} />
+        </TouchableOpacity>
+      ) : null}
+
+      {isGroup && messagePosition.isMine ? (
         <TouchableOpacity style={styles.optionButton} onPress={() => handleOptionPress('info')}>
           <Text style={styles.optionText}>Info</Text>
           <MaterialCommunityIcons name="information-outline" size={20} color={Colors.DARK_BLUE} />
         </TouchableOpacity>
-      )}
+      ) : null}
       {/* <TouchableOpacity style={styles.optionButton} onPress={() => handleOptionPress('pin')}>
         <Text style={styles.optionText}>Pin message</Text>
         <MaterialCommunityIcons name="pin" size={20} color={Colors.DARK_BLUE} />

+ 191 - 0
src/screens/InAppScreens/MessagesScreen/Components/UserOptionsModal.tsx

@@ -0,0 +1,191 @@
+import React, { useState } from 'react';
+import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
+import ActionSheet, { SheetManager } from 'react-native-actions-sheet';
+import { Colors } from 'src/theme';
+import { getFontSize } from 'src/utils';
+import { ChatProps } from '../types';
+import { useNavigation } from '@react-navigation/native';
+import { NAVIGATION_PAGES } from 'src/types';
+import { usePostRemoveFromGroupMutation, usePostSetGroupAdminMutation } from '@api/chat';
+import BanIcon from 'assets/icons/messages/ban.svg';
+import UserTieIcon from 'assets/icons/messages/user-tie.svg';
+import RemoveUserTieIcon from 'assets/icons/messages/crossed-user-tie.svg';
+import UserIcon from 'assets/icons/messages/user-solid.svg';
+
+const UserOptionsModal = () => {
+  const navigation = useNavigation();
+
+  const [userData, setUserData] = useState<any>(null);
+  const { mutateAsync: setAdmin } = usePostSetGroupAdminMutation();
+  const { mutateAsync: removeFromGroup } = usePostRemoveFromGroupMutation();
+
+  const [shouldOpenWarningModal, setShouldOpenWarningModal] = useState<any>(null);
+
+  const handleSheetOpen = (
+    payload:
+      | (ChatProps & {
+          token: string;
+          refetch: () => void;
+          refetchBlocked: () => void;
+        })
+      | null
+  ) => {
+    setUserData(payload);
+  };
+
+  const handleChangeAdmin = async () => {
+    if (!userData) return;
+
+    await setAdmin(
+      {
+        token: userData.token,
+        value: userData.admin === 1 ? 0 : 1,
+        group_token: userData.groupToken,
+        uid: userData.uid
+      },
+      {
+        onSuccess: () => {
+          setUserData({ ...userData, admin: userData.admin === 1 ? 0 : 1 });
+        }
+      }
+    );
+
+    userData.refetchMembers();
+  };
+
+  const handleRemoveFromGroup = async () => {
+    if (!userData) return;
+
+    setShouldOpenWarningModal({
+      title: `Remove ${userData?.name}`,
+      message: `Are you sure you want to remove ${userData?.name} from group chat?`,
+      action: async () => {
+        userData.groupToken &&
+          (await removeFromGroup({
+            token: userData.token,
+            group_token: userData.groupToken,
+            uid: userData.uid
+          }));
+
+        userData.refetch();
+        userData.refetchMembers();
+      },
+      buttonTitle: 'Remove',
+      isWarningVisible: true
+    });
+
+    setTimeout(() => {
+      SheetManager.hide('user-options-modal');
+      setShouldOpenWarningModal(null);
+    }, 300);
+  };
+
+  return (
+    <ActionSheet
+      id="user-options-modal"
+      gestureEnabled={true}
+      onBeforeShow={(sheetRef) => {
+        const payload = sheetRef || null;
+        handleSheetOpen(payload);
+      }}
+      onClose={() => {
+        if (shouldOpenWarningModal) {
+          userData?.setIsWarningVisible(shouldOpenWarningModal);
+        }
+      }}
+      onBeforeClose={() => SheetManager.hide('user-options-modal')}
+      containerStyle={styles.sheetContainer}
+      defaultOverlayOpacity={0.5}
+      indicatorStyle={{ backgroundColor: 'transparent' }}
+    >
+      {userData && (
+        <View style={[styles.container, { paddingBottom: 8 }]}>
+          <View style={styles.optionsContainer}>
+            <TouchableOpacity
+              style={styles.option}
+              onPress={() => {
+                SheetManager.hide('user-options-modal');
+                if (userData?.uid) {
+                  navigation.navigate(
+                    ...([NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW, { userId: userData.uid }] as never)
+                  );
+                }
+              }}
+            >
+              <Text style={styles.optionText}>Profile</Text>
+              <UserIcon fill={Colors.DARK_BLUE} width={20} />
+            </TouchableOpacity>
+            {userData?.canChangeAdmin ? (
+              <>
+                <View style={{ height: 1, backgroundColor: Colors.WHITE }}></View>
+
+                <TouchableOpacity style={styles.option} onPress={handleChangeAdmin}>
+                  <Text style={styles.optionText}>
+                    {userData.admin === 1 ? 'Dismiss as admin' : 'Make group chat admin'}
+                  </Text>
+                  {userData.admin === 1 ? (
+                    <RemoveUserTieIcon fill={Colors.DARK_BLUE} width={20} />
+                  ) : (
+                    <UserTieIcon fill={Colors.DARK_BLUE} width={20} />
+                  )}
+                </TouchableOpacity>
+              </>
+            ) : null}
+          </View>
+
+          {userData?.canChangeAdmin ? (
+            <View style={[styles.optionsContainer, { paddingVertical: 0, gap: 0 }]}>
+              <TouchableOpacity
+                style={[styles.option, styles.dangerOption]}
+                onPress={handleRemoveFromGroup}
+              >
+                <Text style={[styles.optionText, styles.dangerText]}>Remove from group chat</Text>
+                <BanIcon fill={Colors.RED} />
+              </TouchableOpacity>
+            </View>
+          ) : null}
+        </View>
+      )}
+    </ActionSheet>
+  );
+};
+
+const styles = StyleSheet.create({
+  sheetContainer: {
+    borderTopLeftRadius: 15,
+    borderTopRightRadius: 15
+  },
+  container: {
+    backgroundColor: 'white',
+    paddingHorizontal: 16,
+    paddingTop: 8,
+    gap: 16
+  },
+  optionsContainer: {
+    paddingVertical: 10,
+    paddingHorizontal: 8,
+    gap: 8,
+    borderRadius: 8,
+    backgroundColor: Colors.FILL_LIGHT
+  },
+  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
+  }
+});
+
+export default UserOptionsModal;

+ 1 - 1
src/screens/InAppScreens/MessagesScreen/GroupChatScreen/index.tsx

@@ -2012,7 +2012,7 @@ const GroupChatScreen = ({ route }: { route: any }) => {
                 selectedMessage={selectedMessage}
                 handleOptionPress={handleOptionPress}
                 messagePosition={messagePosition}
-                isGroup={selectedMessage?.currentMessage?.user._id === +currentUserId}
+                isGroup={true}
               />
               <EmojiSelectorModal
                 visible={emojiSelectorVisible}

+ 42 - 18
src/screens/InAppScreens/MessagesScreen/GroupSettingsScreen/index.tsx

@@ -32,8 +32,9 @@ import { NAVIGATION_PAGES } from 'src/types';
 import { SheetManager } from 'react-native-actions-sheet';
 import EditGroupModal from '../Components/EditGroupModal';
 import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
-import AllNomadsModal from '../Components/AllNomadsModal';
 import AddNomadsModal from '../Components/AddNomadsModal';
+import DotsIcon from 'assets/icons/messages/dots-vertical.svg';
+import UserOptionsModal from '../Components/UserOptionsModal';
 
 type Props = {
   navigation: NavigationProp<any>;
@@ -42,6 +43,7 @@ type Props = {
 
 const GroupSettingScreen: FC<Props> = ({ navigation, route }) => {
   const token = storage.get('token', StoreType.STRING) as string;
+  const currentUserId = storage.get('uid', StoreType.STRING) as string;
   const groupToken = route.params.groupToken;
   const insets = useSafeAreaInsets();
   const tabBarHeight = useBottomTabBarHeight();
@@ -155,7 +157,7 @@ const GroupSettingScreen: FC<Props> = ({ navigation, route }) => {
         groupToken,
         refetch,
         refetchMembers
-      }
+      } as any
     });
   };
 
@@ -234,7 +236,7 @@ const GroupSettingScreen: FC<Props> = ({ navigation, route }) => {
                   style={{ padding: 6, paddingRight: 0 }}
                   onPress={() =>
                     SheetManager.show('add-nomads-modal', {
-                      payload: { refetchMembers, groupToken, refetch }
+                      payload: { refetchMembers, groupToken, refetch } as any
                     })
                   }
                 >
@@ -249,15 +251,7 @@ const GroupSettingScreen: FC<Props> = ({ navigation, route }) => {
                   ? members.settings.slice(0, 4)
                   : (members.settings ?? [])
                 ).map((member, index) => (
-                  <TouchableOpacity
-                    key={index}
-                    style={styles.userItem}
-                    onPress={() =>
-                      navigation.navigate(
-                        ...([NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW, { userId: member.uid }] as never)
-                      )
-                    }
-                  >
+                  <View key={index} style={styles.userItem}>
                     {member.avatar ? (
                       <Image source={{ uri: API_HOST + member.avatar }} style={styles.avatar} />
                     ) : (
@@ -273,7 +267,12 @@ const GroupSettingScreen: FC<Props> = ({ navigation, route }) => {
                     <View style={{ flex: 1 }}>
                       <Text style={styles.userName}>{member.name}</Text>
                     </View>
-                    <View style={{ justifyContent: 'center', alignItems: 'center' }}>
+                    <View
+                      style={{
+                        justifyContent: 'center',
+                        alignItems: 'center'
+                      }}
+                    >
                       {member.admin === 1 && (
                         <Text
                           style={{
@@ -286,15 +285,40 @@ const GroupSettingScreen: FC<Props> = ({ navigation, route }) => {
                         </Text>
                       )}
                     </View>
-                  </TouchableOpacity>
+                    {member.uid !== +currentUserId && (
+                      <TouchableOpacity
+                        style={{ padding: 6 }}
+                        onPress={() =>
+                          SheetManager.show('user-options-modal', {
+                            payload: {
+                              admin: member.admin,
+                              uid: member.uid,
+                              name: member.name,
+                              canChangeAdmin: data.settings.admin === 1,
+                              token,
+                              groupToken,
+                              refetch,
+                              refetchMembers,
+                              setIsWarningVisible: setModalState
+                            } as any
+                          })
+                        }
+                      >
+                        <DotsIcon />
+                      </TouchableOpacity>
+                    )}
+                  </View>
                 ))}
                 {data.settings.member_count > 4 ? (
                   <TouchableOpacity
                     style={{ padding: 8, alignItems: 'center' }}
                     onPress={() =>
-                      SheetManager.show('all-nomads-modal', {
-                        payload: { members: members.settings }
-                      })
+                      navigation.navigate(
+                        ...([
+                          NAVIGATION_PAGES.MEMBERS_LIST,
+                          { groupToken, canChangeAdmin: data.settings.admin === 1 }
+                        ] as never)
+                      )
                     }
                   >
                     <Text
@@ -361,8 +385,8 @@ const GroupSettingScreen: FC<Props> = ({ navigation, route }) => {
         doubleTapToZoomEnabled={true}
       />
       <EditGroupModal />
-      <AllNomadsModal />
       <AddNomadsModal />
+      <UserOptionsModal />
     </PageWrapper>
   );
 };

+ 90 - 61
src/screens/InAppScreens/MessagesScreen/Components/AllNomadsModal.tsx → src/screens/InAppScreens/MessagesScreen/MembersListScreen/index.tsx

@@ -1,32 +1,64 @@
-import React, { useState } from 'react';
-import { View, StyleSheet, TouchableOpacity, Text, Image } from 'react-native';
-import ActionSheet, { SheetManager } from 'react-native-actions-sheet';
-import { useNavigation } from '@react-navigation/native';
-import { chatStyles } from './styles';
+import React, { FC, useEffect, useState } from 'react';
+import { Text, TouchableOpacity, View, Image, StyleSheet } from 'react-native';
+import { NavigationProp, useFocusEffect } from '@react-navigation/native';
+import { storage, StoreType } from 'src/storage';
+import { PageWrapper, Header, Input, AvatarWithInitials, WarningModal } from 'src/components';
+import { usePostGetGroupMembersQuery, usePostGetGroupSettingsQuery } from '@api/chat';
 import { Colors } from 'src/theme';
-import { AvatarWithInitials, Input } from 'src/components';
 import { API_HOST } from 'src/constants';
-import { NAVIGATION_PAGES } from 'src/types';
+import { getFontSize } from 'src/utils';
+import { SheetManager } from 'react-native-actions-sheet';
+import UserOptionsModal from '../Components/UserOptionsModal';
+import { chatStyles } from '../Components/styles';
 import { FlashList } from '@shopify/flash-list';
 
 import SearchIcon from 'assets/icons/search.svg';
-import { getFontSize } from 'src/utils';
+import DotsIcon from 'assets/icons/messages/dots-vertical.svg';
+
+type Props = {
+  navigation: NavigationProp<any>;
+  route: any;
+};
+
+const MembersListScreen: FC<Props> = ({ navigation, route }) => {
+  const token = storage.get('token', StoreType.STRING) as string;
+  const currentUserId = storage.get('uid', StoreType.STRING) as string;
+  const { groupToken, canChangeAdmin } = route.params;
 
-const AllNomadsModal = () => {
-  const navigation = useNavigation();
+  const [modalState, setModalState] = useState({
+    isWarningVisible: false,
+    title: '',
+    buttonTitle: '',
+    message: '',
+    action: () => {}
+  });
   const [searchQuery, setSearchQuery] = useState('');
-  const [data, setData] = useState<any[]>([]);
   const [filteredData, setFilteredData] = useState<any[]>([]);
+  const { data, refetch } = usePostGetGroupSettingsQuery(token, groupToken, true);
+  const { data: members, refetch: refetchMembers } = usePostGetGroupMembersQuery(
+    token,
+    groupToken,
+    true
+  );
 
-  const handleSheetOpen = (payload: any) => {
-    setData(payload?.members ?? []);
-    setFilteredData(payload?.members ?? []);
-  };
+  useFocusEffect(() => {
+    navigation.getParent()?.setOptions({
+      tabBarStyle: {
+        display: 'none'
+      }
+    });
+  });
+
+  useEffect(() => {
+    if (members && members.settings) {
+      setFilteredData(members.settings);
+    }
+  }, [members]);
 
   const handleSearch = (text: string) => {
-    if (text) {
+    if (text && members) {
       const searchData =
-        data?.filter((item: any) => {
+        members?.settings?.filter((item: any) => {
           const itemData = item.name ? item.name.toLowerCase() : ''.toLowerCase();
           const textData = text.toLowerCase();
           return itemData.indexOf(textData) > -1;
@@ -34,27 +66,13 @@ const AllNomadsModal = () => {
       setFilteredData(searchData);
       setSearchQuery(text);
     } else {
-      setFilteredData(data);
+      setFilteredData(members?.settings ?? []);
       setSearchQuery(text);
     }
   };
 
   const renderItem = ({ item }: { item: any }) => (
-    <TouchableOpacity
-      style={styles.userItem}
-      onPress={() => {
-        SheetManager.hide('all-nomads-modal').then(() => {
-          navigation.navigate(
-            ...([
-              NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW,
-              {
-                userId: item.uid
-              }
-            ] as never)
-          );
-        });
-      }}
-    >
+    <View style={styles.userItem}>
       {item.avatar ? (
         <Image source={{ uri: API_HOST + item.avatar }} style={chatStyles.avatar} />
       ) : (
@@ -82,29 +100,35 @@ const AllNomadsModal = () => {
           Admin
         </Text>
       )}
-    </TouchableOpacity>
-  );
-
-  return (
-    <ActionSheet
-      id="all-nomads-modal"
-      containerStyle={styles.sheetContainer}
-      defaultOverlayOpacity={0.5}
-      closeOnTouchBackdrop={true}
-      keyboardHandlerEnabled={true}
-      onBeforeShow={(sheetRef) => {
-        const payload = sheetRef || null;
-        handleSheetOpen(payload);
-      }}
-    >
-      <View style={styles.container}>
+      {item.uid !== +currentUserId && (
         <TouchableOpacity
-          style={styles.header}
-          onPress={() => SheetManager.hide('all-nomads-modal')}
+          style={{ padding: 6 }}
+          onPress={() =>
+            SheetManager.show('user-options-modal', {
+              payload: {
+                admin: item.admin,
+                uid: item.uid,
+                name: item.name,
+                canChangeAdmin,
+                token,
+                groupToken,
+                refetch,
+                refetchMembers,
+                setIsWarningVisible: setModalState
+              } as any
+            })
+          }
         >
-          <Text style={chatStyles.cancelText}>Cancel</Text>
+          <DotsIcon />
         </TouchableOpacity>
+      )}
+    </View>
+  );
 
+  return (
+    <PageWrapper>
+      <Header label="Nomads" />
+      <View style={styles.container}>
         <Input
           inputMode={'search'}
           placeholder={'Search nomads'}
@@ -128,7 +152,18 @@ const AllNomadsModal = () => {
           contentContainerStyle={{ paddingBottom: 16 }}
         />
       </View>
-    </ActionSheet>
+
+      <WarningModal
+        type={'delete'}
+        isVisible={modalState.isWarningVisible}
+        buttonTitle={modalState.buttonTitle}
+        message={modalState.message}
+        action={modalState.action}
+        onClose={() => setModalState({ ...modalState, isWarningVisible: false })}
+        title={modalState.title}
+      />
+      <UserOptionsModal />
+    </PageWrapper>
   );
 };
 
@@ -136,13 +171,7 @@ const styles = StyleSheet.create({
   container: {
     backgroundColor: 'white',
     gap: 16,
-    height: '100%'
-  },
-  sheetContainer: {
-    height: '95%',
-    borderTopLeftRadius: 15,
-    borderTopRightRadius: 15,
-    paddingHorizontal: 16
+    flex: 1
   },
   avatar: {
     width: 30,
@@ -168,4 +197,4 @@ const styles = StyleSheet.create({
   }
 });
 
-export default AllNomadsModal;
+export default MembersListScreen;

+ 1 - 0
src/types/navigation.ts

@@ -76,4 +76,5 @@ export enum NAVIGATION_PAGES {
   EVENT = 'inAppEvent',
   FULL_MAP_VIEW = 'inAppFullMapView',
   GROUP_SETTINGS = 'inAppGroupSettings',
+  MEMBERS_LIST = 'inAppMembersList'
 }