|
@@ -8,7 +8,8 @@ import {
|
|
|
View,
|
|
|
Image,
|
|
|
StatusBar,
|
|
|
- ActivityIndicator
|
|
|
+ ActivityIndicator,
|
|
|
+ ScrollView
|
|
|
} from 'react-native';
|
|
|
import React, { useEffect, useRef, useState, useCallback } from 'react';
|
|
|
|
|
@@ -69,11 +70,18 @@ import MarkerItem from './MarkerItem';
|
|
|
import {
|
|
|
usePostGetSettingsQuery,
|
|
|
usePostGetUsersLocationQuery,
|
|
|
+ usePostIsFeatureActiveQuery,
|
|
|
usePostUpdateLocationMutation
|
|
|
} from '@api/location';
|
|
|
import UserItem from './UserItem';
|
|
|
import { useConnection } from 'src/contexts/ConnectionContext';
|
|
|
|
|
|
+import TravelsIcon from 'assets/icons/bottom-navigation/globe-solid.svg';
|
|
|
+import SeriesIcon from 'assets/icons/travels-section/series.svg';
|
|
|
+import NomadsIcon from 'assets/icons/bottom-navigation/travellers.svg';
|
|
|
+import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
|
|
|
+import MapButton from 'src/components/MapButton';
|
|
|
+
|
|
|
const defaultUserAvatar = require('assets/icon-user-share-location-solid.png');
|
|
|
const logo = require('assets/logo-ua.png');
|
|
|
const defaultSeriesIcon = require('assets/series-default.png');
|
|
@@ -254,6 +262,7 @@ const INITIAL_REGION = {
|
|
|
};
|
|
|
|
|
|
const MapScreen: any = ({ navigation, route }: { navigation: any; route: any }) => {
|
|
|
+ const tabBarHeight = useBottomTabBarHeight();
|
|
|
const userId = storage.get('uid', StoreType.STRING) as string;
|
|
|
const token = storage.get('token', StoreType.STRING) as string;
|
|
|
|
|
@@ -284,7 +293,10 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
|
|
|
const [showNomads, setShowNomads] = useState(
|
|
|
(storage.get('showNomads', StoreType.BOOLEAN) as boolean) ?? false
|
|
|
);
|
|
|
- const { data: locationSettings, refetch } = usePostGetSettingsQuery(token, !!token && isConnected);
|
|
|
+ const { data: locationSettings, refetch } = usePostGetSettingsQuery(
|
|
|
+ token,
|
|
|
+ !!token && isConnected
|
|
|
+ );
|
|
|
const { mutateAsync: updateLocation } = usePostUpdateLocationMutation();
|
|
|
const { data: visitedRegionIds, refetch: refetchVisitedRegions } =
|
|
|
usePostGetVisitedRegionsIdsQuery(
|
|
@@ -307,8 +319,12 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
|
|
|
+userId,
|
|
|
type === 'dare' && !!userId && isConnected
|
|
|
);
|
|
|
- const { data: visitedSeriesIds } = usePostGetVisitedSeriesIdsQuery(token, !!userId && isConnected);
|
|
|
+ const { data: visitedSeriesIds } = usePostGetVisitedSeriesIdsQuery(
|
|
|
+ token,
|
|
|
+ !!userId && isConnected
|
|
|
+ );
|
|
|
const { data: seriesIcons } = useGetIconsQuery(isConnected);
|
|
|
+ const { data: isFeatureActive } = usePostIsFeatureActiveQuery(token, !!token && isConnected);
|
|
|
const userInfo = storage.get('currentUserData', StoreType.STRING) as string;
|
|
|
const { mutateAsync: mutateUserData } = fetchUserData();
|
|
|
const { mutateAsync: mutateUserDataDare } = fetchUserDataDare();
|
|
@@ -328,7 +344,7 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
|
|
|
const [isWarningModalVisible, setIsWarningModalVisible] = useState<boolean>(false);
|
|
|
const [isEditSlowModalVisible, setIsEditSlowModalVisible] = useState<boolean>(false);
|
|
|
const [isEditModalVisible, setIsEditModalVisible] = useState(false);
|
|
|
- const [isFilterVisible, setIsFilterVisible] = useState(false);
|
|
|
+ const [isFilterVisible, setIsFilterVisible] = useState<string | null>(null);
|
|
|
const [isLocationLoading, setIsLocationLoading] = useState(false);
|
|
|
|
|
|
const [modalState, setModalState] = useState({
|
|
@@ -390,7 +406,7 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
|
|
|
}, [showNomads]);
|
|
|
|
|
|
useEffect(() => {
|
|
|
- if (usersLocation) {
|
|
|
+ if (usersLocation && showNomads) {
|
|
|
const filteredNomads: GeoJSON.FeatureCollection = {
|
|
|
type: 'FeatureCollection',
|
|
|
features: usersLocation.geojson.features.filter(
|
|
@@ -400,14 +416,14 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
|
|
|
|
|
|
setNomads(filteredNomads);
|
|
|
}
|
|
|
- }, [usersLocation]);
|
|
|
+ }, [usersLocation, showNomads]);
|
|
|
|
|
|
useEffect(() => {
|
|
|
if (seriesIcons) {
|
|
|
const loadImages = async () => {
|
|
|
const loadedSeriesImages: Record<string, { uri: string }> = {};
|
|
|
const prefetchUrls: string[] = [];
|
|
|
-
|
|
|
+
|
|
|
const promises = seriesIcons.data.map(async (icon) => {
|
|
|
const id = icon.id?.toString();
|
|
|
const img = `${API_HOST}/static/img/series_new2_small/${icon.new_icon_png}`;
|
|
@@ -419,7 +435,6 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
|
|
|
!processedImages.current.has(id) &&
|
|
|
!processedImages.current.has(`${id}v`)
|
|
|
) {
|
|
|
-
|
|
|
processedImages.current.add(id);
|
|
|
processedImages.current.add(`${id}v`);
|
|
|
|
|
@@ -442,7 +457,7 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
|
|
|
ExpoImage.prefetch(prefetchUrls);
|
|
|
}
|
|
|
};
|
|
|
-
|
|
|
+
|
|
|
loadImages();
|
|
|
}
|
|
|
}, [seriesIcons]);
|
|
@@ -1125,17 +1140,20 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
|
|
|
onPress={onMapPress}
|
|
|
onRegionDidChange={handleRegionDidChange}
|
|
|
>
|
|
|
- <MapLibreGL.Images images={images} onImageMissing={(image) => {
|
|
|
- if (processedImages.current.has(image)) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- processedImages.current.add(image);
|
|
|
- setImages((prevImages: any) => ({
|
|
|
- ...prevImages,
|
|
|
- [image]: defaultSeriesIcon,
|
|
|
- }));
|
|
|
- }}>
|
|
|
+ <MapLibreGL.Images
|
|
|
+ images={images}
|
|
|
+ onImageMissing={(image) => {
|
|
|
+ if (processedImages.current.has(image)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ processedImages.current.add(image);
|
|
|
+ setImages((prevImages: any) => ({
|
|
|
+ ...prevImages,
|
|
|
+ [image]: defaultSeriesIcon
|
|
|
+ }));
|
|
|
+ }}
|
|
|
+ >
|
|
|
<View />
|
|
|
</MapLibreGL.Images>
|
|
|
|
|
@@ -1441,7 +1459,12 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
|
|
|
|
|
|
<TouchableOpacity
|
|
|
onPress={handleGetLocation}
|
|
|
- style={[styles.cornerButton, styles.topRightButton, styles.bottomButton]}
|
|
|
+ style={[
|
|
|
+ styles.cornerButton,
|
|
|
+ styles.topRightButton,
|
|
|
+ styles.bottomButton,
|
|
|
+ { bottom: tabBarHeight + 20 }
|
|
|
+ ]}
|
|
|
>
|
|
|
{isLocationLoading ? (
|
|
|
<ActivityIndicator size="small" color={Colors.DARK_BLUE} />
|
|
@@ -1556,19 +1579,49 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
|
|
|
)}
|
|
|
</Animated.View>
|
|
|
|
|
|
- <TouchableOpacity
|
|
|
- style={[styles.cornerButton, styles.bottomButton, styles.bottomLeftButton]}
|
|
|
- onPress={() => {
|
|
|
- setIsFilterVisible(true);
|
|
|
- closeCallout();
|
|
|
- }}
|
|
|
- >
|
|
|
- <FilterIcon />
|
|
|
- </TouchableOpacity>
|
|
|
+ <View style={[styles.tabs, { bottom: tabBarHeight + 20 }]}>
|
|
|
+ <ScrollView
|
|
|
+ horizontal
|
|
|
+ showsHorizontalScrollIndicator={false}
|
|
|
+ contentContainerStyle={{ paddingHorizontal: 12, gap: 12, flexDirection: 'row' }}
|
|
|
+ >
|
|
|
+ <MapButton
|
|
|
+ onPress={() => {
|
|
|
+ setIsFilterVisible('regions');
|
|
|
+ closeCallout();
|
|
|
+ }}
|
|
|
+ icon={TravelsIcon}
|
|
|
+ text="Travels"
|
|
|
+ />
|
|
|
+ <MapButton
|
|
|
+ onPress={() => {
|
|
|
+ setIsFilterVisible('series');
|
|
|
+ closeCallout();
|
|
|
+ }}
|
|
|
+ icon={SeriesIcon}
|
|
|
+ text="Series"
|
|
|
+ />
|
|
|
+ {isFeatureActive && isFeatureActive.active ? (
|
|
|
+ <MapButton
|
|
|
+ onPress={() => {
|
|
|
+ setIsFilterVisible('nomads');
|
|
|
+ closeCallout();
|
|
|
+ }}
|
|
|
+ icon={NomadsIcon}
|
|
|
+ text="Nomads"
|
|
|
+ />
|
|
|
+ ) : null}
|
|
|
+ </ScrollView>
|
|
|
+ </View>
|
|
|
|
|
|
<TouchableOpacity
|
|
|
onPress={handleGetLocation}
|
|
|
- style={[styles.cornerButton, styles.bottomButton, styles.bottomRightButton]}
|
|
|
+ style={[
|
|
|
+ styles.cornerButton,
|
|
|
+ styles.bottomButton,
|
|
|
+ styles.bottomRightButton,
|
|
|
+ { bottom: tabBarHeight + 20 }
|
|
|
+ ]}
|
|
|
>
|
|
|
{isLocationLoading ? (
|
|
|
<ActivityIndicator size="small" color={Colors.DARK_BLUE} />
|