Viktoriia 1 неделя назад
Родитель
Сommit
dee2de89e1

+ 4 - 1
src/components/RegionPopup/index.tsx

@@ -68,12 +68,15 @@ const RegionPopup: React.FC<RegionPopupProps> = ({
   const { regionTitle, regionSubtitle } = splitRegionName(region.name);
   const regionImg = JSON.parse(region.region_photos)[0];
 
-  function formatNumber(number: number) {
+  function formatNumber(value?: number | null) {
+    const number = typeof value === 'number' && !isNaN(value) ? value : 0;
+
     if (number >= 1000 && number < 10000) {
       return (number / 1000).toFixed(1) + 'k';
     } else if (number >= 10000) {
       return (number / 1000).toFixed(0) + 'k';
     }
+
     return number.toString();
   }
 

+ 33 - 24
src/contexts/PushNotificationContext.tsx

@@ -54,14 +54,23 @@ export const PushNotificationProvider = ({ children }: { children: React.ReactNo
               let groupToken;
               let messageId;
               let fromUser;
-              const parsedData =
-                JSON.parse(
-                  (notification.request.trigger as Notifications.PushNotificationTrigger)?.payload
-                    ?.params as string
-                ) ?? {};
+
+              const trigger = notification.request
+                .trigger as Notifications.PushNotificationTrigger;
+              const rawParams = trigger?.payload?.params as string | undefined;
+              let parsedData: any = {};
+
+              if (rawParams && typeof rawParams === 'string') {
+                try {
+                  parsedData = JSON.parse(rawParams) ?? {};
+                } catch (error) {
+                  console.error('Error parsing notification params:', error, rawParams);
+                  parsedData = {};
+                }
+              }
+
               groupToken = parsedData?.group_token;
-              messageId = (notification.request.trigger as Notifications.PushNotificationTrigger)
-                ?.payload?.message_id as number;
+              messageId = trigger?.payload?.message_id as number;
               fromUser = parsedData?.id;
 
               handleNotificationData(groupToken, messageId, fromUser);
@@ -89,26 +98,26 @@ export const PushNotificationProvider = ({ children }: { children: React.ReactNo
       let parentScreen;
       let params;
       if (Platform.OS === 'ios') {
-        parentScreen = (
-          lastNotificationResponse.notification.request
-            .trigger as Notifications.PushNotificationTrigger
-        )?.payload?.parentScreen;
-        screenName = (
-          lastNotificationResponse.notification.request
-            .trigger as Notifications.PushNotificationTrigger
-        )?.payload?.screen;
-        params = (
-          lastNotificationResponse.notification.request
-            .trigger as Notifications.PushNotificationTrigger
-        )?.payload?.params;
-        url = (
-          lastNotificationResponse.notification.request
-            .trigger as Notifications.PushNotificationTrigger
-        )?.payload?.url;
+        const trigger = lastNotificationResponse.notification.request
+          .trigger as Notifications.PushNotificationTrigger;
+
+        parentScreen = trigger?.payload?.parentScreen;
+        screenName = trigger?.payload?.screen;
+        params = trigger?.payload?.params;
+        url = trigger?.payload?.url;
 
         if (screenName && parentScreen) {
           if (params) {
-            const parsedParams = JSON.parse(params as string) ?? {};
+            let parsedParams: any = {};
+
+            if (typeof params === 'string') {
+              try {
+                parsedParams = JSON.parse(params) ?? {};
+              } catch (error) {
+                console.error('Error parsing notification response params:', error, params);
+                parsedParams = {};
+              }
+            }
 
             navigation.dispatch(
               CommonActions.reset({

+ 4 - 1
src/screens/InAppScreens/MapScreen/MarkerItem/index.tsx

@@ -25,12 +25,15 @@ const MarkerItem = ({
 }) => {
   const navigation = useNavigation();
 
-  function formatNumber(number: number) {
+  function formatNumber(value?: number | null) {
+    const number = typeof value === 'number' && !isNaN(value) ? value : 0;
+
     if (number >= 1000 && number < 10000) {
       return (number / 1000).toFixed(1) + 'k';
     } else if (number >= 10000) {
       return (number / 1000).toFixed(0) + 'k';
     }
+
     return number.toString();
   }
   const formattedCount = formatNumber(marker.no_visited);

+ 4 - 1
src/screens/InAppScreens/MapScreen/MultipleSeriesModal/index.tsx

@@ -18,12 +18,15 @@ const MultipleSeriesModal = () => {
   const shouldOpenWarningModalRef = useRef(false);
   const shouldOpenPremiumWarningModalRef = useRef(false);
 
-  function formatNumber(number: number) {
+  function formatNumber(value?: number | null) {
+    const number = typeof value === 'number' && !isNaN(value) ? value : 0;
+
     if (number >= 1000 && number < 10000) {
       return (number / 1000).toFixed(1) + 'k';
     } else if (number >= 10000) {
       return (number / 1000).toFixed(0) + 'k';
     }
+
     return number.toString();
   }
 

+ 38 - 5
src/screens/InAppScreens/MapScreen/index.tsx

@@ -110,6 +110,30 @@ const defaultSeriesIcon = require('assets/series-default.png');
 
 MapLibreRN.Logger.setLogLevel('error');
 
+const sanitizeNomadsGeoJSON = (
+  collection: GeoJSON.FeatureCollection
+): GeoJSON.FeatureCollection => {
+  const validFeatures = collection.features.filter((feature) => {
+    if (!feature || !feature.geometry || !feature.properties) return false;
+
+    const geom = feature.geometry;
+    if (geom.type !== 'Point') return false;
+
+    const coords = (geom as GeoJSON.Point).coordinates;
+    if (!Array.isArray(coords) || coords.length < 2) return false;
+
+    const [lng, lat] = coords;
+    if (lng == null || lat == null) return false;
+    if (typeof lng !== 'number' || typeof lat !== 'number') return false;
+    if (isNaN(lng) || isNaN(lat)) return false;
+    if (lng < -180 || lng > 180 || lat < -90 || lat > 90) return false;
+
+    return true;
+  });
+
+  return { type: 'FeatureCollection', features: validFeatures };
+};
+
 const generateFilter = (ids: number[]) => {
   return ids?.length ? ['any', ...ids.map((id) => ['==', 'id', id])] : ['==', 'id', -1];
 };
@@ -470,12 +494,13 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
 
   useEffect(() => {
     if (usersLocation && usersLocation.geojson && showNomads) {
-      const filteredNomads: GeoJSON.FeatureCollection = {
+      const rawFiltered: GeoJSON.FeatureCollection = {
         type: 'FeatureCollection',
         features: usersLocation.geojson.features.filter(
           (feature: GeoJSON.Feature) => feature.properties?.id !== +userId
         )
       };
+      const filteredNomads = sanitizeNomadsGeoJSON(rawFiltered);
 
       if (!nomads || JSON.stringify(filteredNomads) !== JSON.stringify(nomads)) {
         setNomads(filteredNomads);
@@ -612,7 +637,7 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
       setNomadsFilter({
         friends: filterSettings.nomadsFilter ? filterSettings.nomadsFilter.friends : 0,
         trusted: filterSettings.nomadsFilter ? filterSettings.nomadsFilter.trusted : 0,
-        countries: filterSettings.nomadsFilter ? filterSettings.nomadsFilter.countries : undefined
+        countries: filterSettings.nomadsFilter?.countries ?? []
       });
       setSeriesFilter(filterSettings.seriesFilter);
     }
@@ -720,12 +745,13 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
         onSuccess: (data) => {
           if (data && data?.geojson) {
             setUsersCount(data.geojson.features?.length);
-            const filteredNomads: GeoJSON.FeatureCollection = {
+            const rawFiltered: GeoJSON.FeatureCollection = {
               type: 'FeatureCollection',
               features: data.geojson.features.filter(
                 (feature: GeoJSON.Feature) => feature.properties?.id !== +userId
               )
             };
+            const filteredNomads = sanitizeNomadsGeoJSON(rawFiltered);
 
             if (!nomads || JSON.stringify(filteredNomads) !== JSON.stringify(nomads)) {
               setNomads(filteredNomads);
@@ -788,8 +814,14 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
         ]);
       }
     } else {
-      setSeriesVisitedFilter(['any', ...seriesVisited.map((id) => ['==', 'id', id])]);
-      setSeriesNotVisitedFilter(['all', ...seriesVisited.map((id) => ['!=', 'id', id])]);
+      setSeriesVisitedFilter(
+        seriesVisited.length
+          ? ['any', ...seriesVisited.map((id) => ['==', 'id', id])]
+          : generateFilter([])
+      );
+      setSeriesNotVisitedFilter(
+        seriesVisited.length ? ['all', ...seriesVisited.map((id) => ['!=', 'id', id])] : ['all']
+      );
     }
   }, [seriesVisited, seriesFilter]);
 
@@ -1586,6 +1618,7 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
               no_visited: f.properties.no_visited
             };
           })
+          .filter(Boolean)
           .sort((a: any, b: any) => a.visited - b.visited);
 
         SheetManager.show('multiple-series-modal', {

+ 1 - 1
src/screens/InAppScreens/TravelsScreen/Components/MyRegionsItems/NmRegionItem.tsx

@@ -38,7 +38,7 @@ export const NmRegionItem = React.memo(
     const { regionData, avatars } = useRegionData(item.id);
 
     const regionImg = regionData ? JSON.parse(regionData?.region_photos)[0] : '';
-    const formattedCount = regionData ? formatNumber(regionData?.visitors_count) : 0;
+    const formattedCount = formatNumber(regionData?.visitors_count ?? 0);
 
     return (
       <View style={styles.regionItem}>

+ 1 - 1
src/screens/InAppScreens/TravelsScreen/Components/MyRegionsItems/RegionItem.tsx

@@ -26,7 +26,7 @@ export const RegionItem = React.memo(
     const { regionData, avatars } = useRegionData(item.id, dare);
 
     const regionImg = regionData ? JSON.parse(regionData?.region_photos)[0] : '';
-    const formattedCount = regionData ? formatNumber(regionData?.visitors_count) : 0;
+    const formattedCount = formatNumber(regionData?.visitors_count ?? 0);
 
     return (
       <View style={styles.regionItem}>

+ 4 - 1
src/screens/InAppScreens/TravelsScreen/utils/formatNumber.ts

@@ -1,9 +1,12 @@
-function formatNumber(number: number) {
+function formatNumber(value?: number | null) {
+  const number = typeof value === 'number' && !isNaN(value) ? value : 0;
+
   if (number >= 1000 && number < 10000) {
     return (number / 1000).toFixed(1) + 'k';
   } else if (number >= 10000) {
     return (number / 1000).toFixed(0) + 'k';
   }
+
   return number.toString();
 }
 

+ 0 - 2
src/screens/OfflineMapsScreen/SelectOwnMapScreen/index.tsx

@@ -80,8 +80,6 @@ export default function SelectOwnMapScreen({ navigation, route }) {
     }
 
     checkConnectionType();
-
-    MapLibreGL.setAccessToken(null);
   }, [updateMap]);
 
   useEffect(() => {