|
@@ -0,0 +1,322 @@
|
|
|
+import { NavigationProp, useFocusEffect } from '@react-navigation/native';
|
|
|
+import React, { FC, useCallback, useEffect, useState } from 'react';
|
|
|
+import { ActivityIndicator } from 'react-native';
|
|
|
+import { Header, HorizontalTabView, Loading, PageWrapper, WarningModal } from 'src/components';
|
|
|
+
|
|
|
+import { Colors } from 'src/theme';
|
|
|
+import { FlashList } from '@shopify/flash-list';
|
|
|
+import { StoreType, storage } from 'src/storage';
|
|
|
+import { FilterButton, FilterModal } from '../../TravellersScreen/Components/FilterModal';
|
|
|
+import { RankingDropdown } from '../../TravellersScreen/utils/types';
|
|
|
+import { dataRanking } from '../../TravellersScreen/utils';
|
|
|
+import {
|
|
|
+ useGetMyFriendsMutation,
|
|
|
+ usePostHideShowRequestMutation,
|
|
|
+ usePostUpdateFriendStatusMutation
|
|
|
+} from '@api/friends';
|
|
|
+import { FriendsProfile } from './FriendsProfile';
|
|
|
+
|
|
|
+type Props = {
|
|
|
+ navigation: NavigationProp<any>;
|
|
|
+ route: any;
|
|
|
+};
|
|
|
+
|
|
|
+type Routes = {
|
|
|
+ key: 'friends' | 'received' | 'sent';
|
|
|
+ title: string;
|
|
|
+};
|
|
|
+
|
|
|
+const MyFriendsScreen: FC<Props> = ({ navigation }) => {
|
|
|
+ const token = storage.get('token', StoreType.STRING) as string;
|
|
|
+
|
|
|
+ const { mutateAsync: getMyFriends } = useGetMyFriendsMutation();
|
|
|
+ const [loading, setLoading] = useState(true);
|
|
|
+ const [isModalVisible, setModalVisible] = useState(false);
|
|
|
+ const [confirmedValueRanking, setConfirmedValueRanking] = useState<RankingDropdown | null>();
|
|
|
+ const [masterCountries, setMasterCountries] = useState<any>([]);
|
|
|
+ const [maxPages, setMaxPages] = useState(1);
|
|
|
+ const [page, setPage] = useState(0);
|
|
|
+ const [isLoadingMore, setIsLoadingMore] = useState(false);
|
|
|
+ const [filter, setFilter] = useState<{
|
|
|
+ age: number | undefined;
|
|
|
+ ranking: string | undefined;
|
|
|
+ country: string | undefined;
|
|
|
+ }>({ age: undefined, ranking: undefined, country: undefined });
|
|
|
+ const [index, setIndex] = useState(0);
|
|
|
+ const routes: Routes[] = [
|
|
|
+ { key: 'friends', title: 'Friends' },
|
|
|
+ { key: 'received', title: 'Requests received' },
|
|
|
+ { key: 'sent', title: 'Requests sent' }
|
|
|
+ ];
|
|
|
+ const [users, setUsers] = useState<{ [key in 'friends' | 'received' | 'sent']: any[] }>({
|
|
|
+ friends: [],
|
|
|
+ received: [],
|
|
|
+ sent: []
|
|
|
+ });
|
|
|
+ const { mutateAsync: updateFriendStatus } = usePostUpdateFriendStatusMutation();
|
|
|
+ const { mutateAsync: hideShowRequest } = usePostHideShowRequestMutation();
|
|
|
+ const [modalInfo, setModalInfo] = useState({
|
|
|
+ type: 'friend',
|
|
|
+ message: '',
|
|
|
+ isVisible: false,
|
|
|
+ action: () => {},
|
|
|
+ title: ''
|
|
|
+ });
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (filter.age || filter.ranking || filter.country) {
|
|
|
+ applySort();
|
|
|
+ }
|
|
|
+ }, [filter]);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ fetchUsers();
|
|
|
+ setFilter({
|
|
|
+ age: undefined,
|
|
|
+ ranking: undefined,
|
|
|
+ country: undefined
|
|
|
+ });
|
|
|
+ }, [index]);
|
|
|
+
|
|
|
+ useFocusEffect(
|
|
|
+ useCallback(() => {
|
|
|
+ fetchUsers();
|
|
|
+ }, [])
|
|
|
+ );
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ const getNextPage = async () => {
|
|
|
+ await getMyFriends(
|
|
|
+ {
|
|
|
+ token,
|
|
|
+ type: routes[index].key,
|
|
|
+ page,
|
|
|
+ sort: filter.ranking,
|
|
|
+ age: filter.age,
|
|
|
+ country: filter.country
|
|
|
+ },
|
|
|
+ {
|
|
|
+ onSuccess: (data) => {
|
|
|
+ setIsLoadingMore(false);
|
|
|
+ setUsers((prevState) => {
|
|
|
+ return {
|
|
|
+ ...prevState,
|
|
|
+ [routes[index].key]: [
|
|
|
+ ...prevState[routes[index].key],
|
|
|
+ ...data[routes[index].key].users
|
|
|
+ ]
|
|
|
+ };
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+ };
|
|
|
+ if (page !== 0) {
|
|
|
+ getNextPage();
|
|
|
+ }
|
|
|
+ }, [page]);
|
|
|
+
|
|
|
+ const fetchUsers = async () => {
|
|
|
+ await getMyFriends(
|
|
|
+ {
|
|
|
+ token,
|
|
|
+ type: '',
|
|
|
+ page: 0,
|
|
|
+ sort: undefined,
|
|
|
+ age: undefined,
|
|
|
+ country: undefined
|
|
|
+ },
|
|
|
+ {
|
|
|
+ onSuccess: (data) => {
|
|
|
+ setUsers({
|
|
|
+ friends: data.friends.users,
|
|
|
+ received: data.received.users,
|
|
|
+ sent: data.sent.users
|
|
|
+ });
|
|
|
+ setMaxPages(data[routes[index].key].max_pages);
|
|
|
+ setMasterCountries(convertData(data[routes[index].key].countries) ?? []);
|
|
|
+ setLoading(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
+ const applySort = async () => {
|
|
|
+ await getMyFriends(
|
|
|
+ {
|
|
|
+ token,
|
|
|
+ type: routes[index].key,
|
|
|
+ page,
|
|
|
+ sort: filter.ranking,
|
|
|
+ age: filter.age,
|
|
|
+ country: filter.country
|
|
|
+ },
|
|
|
+ {
|
|
|
+ onSuccess: (data) => {
|
|
|
+ setUsers((prevState) => {
|
|
|
+ return {
|
|
|
+ ...prevState,
|
|
|
+ [routes[index].key]: data[routes[index].key].users
|
|
|
+ };
|
|
|
+ });
|
|
|
+ setMaxPages(data[routes[index].key].max_pages);
|
|
|
+ setMasterCountries(convertData(data[routes[index].key].countries) ?? []);
|
|
|
+ setLoading(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
+ const convertData = (data: { [key: string]: { country: string; flag: string } }) => {
|
|
|
+ let formatedCountries = [{ two: 'all', name: 'ALL', flag: '' }];
|
|
|
+ formatedCountries.push(
|
|
|
+ ...Object.entries(data).map(([key, value]) => ({
|
|
|
+ two: key,
|
|
|
+ name: value.country,
|
|
|
+ flag: value.flag
|
|
|
+ }))
|
|
|
+ );
|
|
|
+
|
|
|
+ return formatedCountries;
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleEndReached = useCallback(() => {
|
|
|
+ if (users && page < maxPages && !isLoadingMore && maxPages > 1) {
|
|
|
+ setIsLoadingMore(true);
|
|
|
+ setPage((prevPage) => prevPage + 1);
|
|
|
+ }
|
|
|
+ }, [users, page]);
|
|
|
+
|
|
|
+ const handleUpdateFriendStatus = async (status: number, id: number) => {
|
|
|
+ await updateFriendStatus(
|
|
|
+ { token, id, status },
|
|
|
+ {
|
|
|
+ onSuccess: () => {
|
|
|
+ applySort();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleHideRequest = async (id: number) => {
|
|
|
+ await hideShowRequest(
|
|
|
+ { token, id, show: 0 },
|
|
|
+ {
|
|
|
+ onSuccess: () => {
|
|
|
+ applySort();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
+ if (loading) return <Loading />;
|
|
|
+
|
|
|
+ const ListFooter = ({ isLoading }: { isLoading: boolean }) =>
|
|
|
+ isLoading ? <ActivityIndicator size="large" color={Colors.DARK_BLUE} /> : null;
|
|
|
+
|
|
|
+ return (
|
|
|
+ <PageWrapper>
|
|
|
+ <Header
|
|
|
+ label={'Friends'}
|
|
|
+ rightElement={<FilterButton onPress={() => setModalVisible(!isModalVisible)} />}
|
|
|
+ />
|
|
|
+ <HorizontalTabView
|
|
|
+ index={index}
|
|
|
+ setIndex={setIndex}
|
|
|
+ routes={routes}
|
|
|
+ renderScene={({ route }: { route: Routes }) => (
|
|
|
+ <>
|
|
|
+ <FlashList
|
|
|
+ viewabilityConfig={{
|
|
|
+ waitForInteraction: true,
|
|
|
+ itemVisiblePercentThreshold: 50,
|
|
|
+ minimumViewTime: 1000
|
|
|
+ }}
|
|
|
+ estimatedItemSize={50}
|
|
|
+ data={users[route.key]}
|
|
|
+ renderItem={({ item, index }) => (
|
|
|
+ <FriendsProfile
|
|
|
+ userId={item.user_id}
|
|
|
+ key={index}
|
|
|
+ index={index}
|
|
|
+ first_name={item.first_name}
|
|
|
+ last_name={item.last_name}
|
|
|
+ avatar={item.avatar}
|
|
|
+ date_of_birth={item.age}
|
|
|
+ homebase_flag={item.flag1}
|
|
|
+ homebase2_flag={item.flag2}
|
|
|
+ score={[
|
|
|
+ item.score_nm,
|
|
|
+ item.score_dare,
|
|
|
+ item.score_un,
|
|
|
+ item.score_unp,
|
|
|
+ item.score_tcc,
|
|
|
+ item.score_deep,
|
|
|
+ item.score_yes,
|
|
|
+ item.score_slow,
|
|
|
+ item.score_whs,
|
|
|
+ item.score_kye,
|
|
|
+ item.score_tbt
|
|
|
+ ]}
|
|
|
+ active_score={
|
|
|
+ confirmedValueRanking
|
|
|
+ ? confirmedValueRanking.value - 1
|
|
|
+ : dataRanking[0].value - 1
|
|
|
+ }
|
|
|
+ tbt_score={item.score_tbt}
|
|
|
+ tbt_rank={item.rank_tbt}
|
|
|
+ badge_tbt={item.badge_tbt}
|
|
|
+ badge_1281={item.badge_1281}
|
|
|
+ badge_un={item.badge_un}
|
|
|
+ auth={item.auth}
|
|
|
+ type={route.key}
|
|
|
+ updateFriendStatus={handleUpdateFriendStatus}
|
|
|
+ status={item.friend_status}
|
|
|
+ friendDbId={item.friend_db_id}
|
|
|
+ hideRequest={handleHideRequest}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ keyExtractor={(item) => item.user_id.toString()}
|
|
|
+ contentContainerStyle={{ paddingBottom: 52, paddingTop: 8 }}
|
|
|
+ showsVerticalScrollIndicator={false}
|
|
|
+ onEndReached={handleEndReached}
|
|
|
+ onEndReachedThreshold={0.2}
|
|
|
+ ListFooterComponent={<ListFooter isLoading={isLoadingMore} />}
|
|
|
+ />
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ />
|
|
|
+
|
|
|
+ <FilterModal
|
|
|
+ isModalVisible={isModalVisible}
|
|
|
+ setModalVisible={(value) => setModalVisible(value)}
|
|
|
+ applyFilter={(filterAge, filterRanking, filterCountry) => {
|
|
|
+ setConfirmedValueRanking(filterRanking);
|
|
|
+ setPage(0);
|
|
|
+ setFilter({
|
|
|
+ age: filterAge?.value ? +filterAge?.value : undefined,
|
|
|
+ ranking: filterRanking?.name,
|
|
|
+ country:
|
|
|
+ filterCountry?.two && filterCountry?.two !== 'all' ? filterCountry?.two : undefined
|
|
|
+ });
|
|
|
+ if (!filterAge && !filterRanking && !filterCountry) {
|
|
|
+ fetchUsers();
|
|
|
+ }
|
|
|
+ setModalVisible(false);
|
|
|
+ }}
|
|
|
+ countriesData={masterCountries}
|
|
|
+ />
|
|
|
+ <WarningModal
|
|
|
+ type={modalInfo.type}
|
|
|
+ isVisible={modalInfo.isVisible}
|
|
|
+ message={modalInfo.message}
|
|
|
+ action={modalInfo.action}
|
|
|
+ onClose={() => setModalInfo({ ...modalInfo, isVisible: false })}
|
|
|
+ title=""
|
|
|
+ onModalHide={() => setModalInfo({ ...modalInfo, isVisible: false })}
|
|
|
+ />
|
|
|
+ </PageWrapper>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+export default MyFriendsScreen;
|