Bladeren bron

more refactors

chase 2 jaren geleden
bovenliggende
commit
a7e0804454

+ 4 - 4
src/presentation/maps/MapNavigator.tsx

@@ -9,10 +9,10 @@ import { Chip } from "react-native-paper"
 import { IconButton } from "../Buttons"
 import IndoorMap from "./indoor/IndoorMap"
 import mapStyles from "./Map.styles"
-import OutdoorMap, { AuthTabsMapRouteProp } from "./outdoor/OutdoorMap"
+import OutdoorMap, { AuthTabsMapRouteProp } from "./outdoor/outdoor-map.view"
 import { useMapState } from "./useMapState"
-import AddLandmarkPanel from "./panels/AddLandmarkPanel/add-landmark-panel."
-import { FilterPanel } from "./panels/FilterPanel/FilterPanel"
+import AddLandmarkPanel from "./panels/add-landmark-panel/add-landmark-panel.view"
+import { FilterPanel } from "./panels/filter-panel/FilterPanel"
 import LandmarkDetails from "./panels/LandmarkDetailsPanel/LandmarkDetails"
 import { useAuth } from "../../state/external/auth-provider"
 import { Landmark, useLandmarks } from '../../state/external/landmarks'
@@ -20,7 +20,7 @@ import { colors, lmTypes } from "../../utils/GlobalUtils"
 import { MainTabsNavigationProp } from "../../navigation/main-tabs-navigator"
 import { Menu, MenuDivider, MenuItem } from 'react-native-material-menu'
 import { navigate } from "../../navigation/root-navigator"
-import { addLandmarkStore } from "./panels/AddLandmarkPanel/add-landmark-panel.store"
+import { addLandmarkStore } from "./panels/add-landmark-panel/add-landmark-panel.store"
 
 
 const MapStackNavigator = createNativeStackNavigator()

+ 2 - 2
src/presentation/maps/indoor/IndoorMap.tsx

@@ -8,8 +8,8 @@ import { Image, Svg } from 'react-native-svg';
 import { Landmark } from '../../../state/external/landmarks';
 import { MapStackNavigationProp } from "../MapNavigator";
 import { colors, lmTypesIndoor } from "../../../utils/GlobalUtils";
-import IndoorFloor from './IndoorFloor';
-import ArrowButton from './ArrowButton';
+import IndoorFloor from './indoor-floor';
+import ArrowButton from './arrow-button';
 
 interface IndoorMapProps {
   navigation: MapStackNavigationProp;

+ 381 - 0
src/presentation/maps/map-outdoor/outdoor-map.tsx

@@ -0,0 +1,381 @@
+/* Copyright (C) Click & Push Accessibility, Inc - All Rights Reserved
+ * Unauthorized copying of this file, via any medium is strictly prohibited
+ * Proprietary and confidential
+ * Written and maintained by the Click & Push Development team 
+ * <dev@clicknpush.ca>, January 2022
+ */
+
+import { FontAwesome } from "@expo/vector-icons";
+import { RouteProp, useNavigationState } from "@react-navigation/native";
+import { booleanPointInPolygon, circle } from '@turf/turf';
+import * as Notifications from 'expo-notifications';
+import { observer } from "mobx-react";
+import React, { useEffect, useState } from "react";
+import { ActivityIndicator, Alert, Image, Keyboard, Modal, Text, TouchableOpacity, TouchableWithoutFeedback, View } from "react-native";
+import MapView, { LatLng, Marker, Polygon, Polyline } from "react-native-maps";
+import { openSettings } from "react-native-permissions";
+import Spokestack from 'react-native-spokestack';
+import { useAuth } from "../../../state/external/auth-provider";
+import { Landmark } from '../../../state/external/landmarks';
+import { NotifType } from "../../../state/external/notifications";
+import { usePermissions } from "../../../state/external/PermissionsContext";
+import { MainTabsNavigationProp, MainTabsParamList } from "../../../navigation/main-tabs-navigator";
+import { colors, lmTypes } from "../../../utils/GlobalUtils";
+import Badge from "../../Badge";
+import { IconButton } from "../../Buttons";
+import mapStyles from "../Map.styles";
+import { MapStackNavigationProp, MapStackParamList } from "../MapNavigator";
+import { addLandmarkStore } from "../panels/add-landmark-panel/add-landmark-panel.store";
+import NearbyLandmarksPanel from "../panels/NearbyLandmarksPanel";
+import { VoicePanel } from "../panels/VoicePanel";
+import { useOutdoorMapState } from "../useMapState";
+
+/**
+ * An interface representing the user location retrieved from [expo-location]{@link https://docs.expo.dev/versions/latest/sdk/location/}.
+ * @category Map
+ */
+export interface UserLocation {
+    latitude: number;
+    longitude: number;
+    heading?: number;
+}
+
+export type MapStackRouteProp = RouteProp<MapStackParamList, 'Outdoor'>;
+
+export type AuthTabsMapRouteProp = RouteProp<MainTabsParamList, 'Map'>;
+
+/**
+ * The screen component containing the Map and all related functionality. Uses [react-native-maps]{@link https://github.com/react-native-maps/react-native-maps}
+ * @category Map
+ * @component
+ */
+
+interface OutdoorMapProps {
+    mapNavigation: MapStackNavigationProp,
+    authNavigation: MainTabsNavigationProp,
+    authNavIndex: number,
+    route: AuthTabsMapRouteProp,
+    focusLandmark: (landmark: Landmark) => void,
+    setSelectedLandmarkId: (id: string) => void,
+    selectedLandmarkId: string,
+    toggleLmDetails: (state: boolean) => void,
+    toggleLmAdd: (state: boolean) => void,
+    landmarks: Landmark[]
+    applyFilters: (landmarks: Landmark[]) => Landmark[]
+    promptAddLandmark: (longitude: number, latitude: number) => void
+}
+
+const OutdoorMap: React.FC<OutdoorMapProps> = (props) => {
+    const {locationPermissionsGranted, voicePermissionsGranted} = usePermissions();
+    const {setAlert} = useAuth()
+    const mapState = useOutdoorMapState()
+
+    // used to determine previous screens and decide if the map should be refreshed
+    const {index: mapNavigationIndex} = useNavigationState(state => state)
+
+    const [coordinates] = useState([
+        { latitude: 53.527086340019856, longitude: -113.52358410971608, }, // Cameron library
+        { latitude: 53.52516024715472, longitude: -113.52154139033108, }, // University station
+    ]);
+    const [size, setSize] = useState(0.052344);
+
+    // TODO: define this effect better and define an interface for the incoming route params
+    // when switching to this component, check if incoming navstate contains incoming selected landmarks, display them if there are. this will be triggered by incoming notifcations 
+    useEffect(() => {
+        console.log(props.route?.params?.selectedLandmark)
+        if (props.route?.params?.selectedLandmark) {
+            props.setSelectedLandmarkId(props.route?.params?.selectedLandmark)
+        }
+        if (props.route?.params?.nearbyLandmarks) {
+            mapState.toggleNearbyLmPanel(true)
+        }
+    }, [props.route])
+
+    // when either the map navigation state or main navigation state changes, check to see if we are coming from a different screen. if so, refresh the map to prevent map lag
+    useEffect(() => {
+        const toMap = mapNavigationIndex == 0 && props.authNavIndex == 0
+
+        if (toMap) mapState.setLoading(true)
+
+        setTimeout(() => {
+            mapState.setLoading(false)
+        }, 500);
+
+    }, [mapNavigationIndex, props.authNavIndex])
+
+    // Toggle the lm details panel when a new selected landmark is detected (triggered by pressing on a map marker, or from the list of nearby landmarks)
+    useEffect(() => {
+        console.log("[LandmarkDetails]: Landmark selected - " + props.selectedLandmarkId)
+        if (props.selectedLandmarkId) {
+            const landmark = props.landmarks.find(lm => lm.id == props.selectedLandmarkId)
+            mapState.mapRef.current.animateToRegion({ latitude: landmark.latitude, longitude: landmark.longitude, latitudeDelta: 0.01, longitudeDelta: 0.01 })
+            props.toggleLmDetails(true)
+        }
+    }, [props.selectedLandmarkId])
+
+    
+    // Move to pressed location when newlandmark changes
+    useEffect(() => {
+        if (props.selectedLandmarkId) {
+            mapState.mapRef.current.animateToRegion({ latitude: addLandmarkStore.pendingLandmark?.latitude, longitude: addLandmarkStore.pendingLandmark?.longitude, latitudeDelta: 0.01, longitudeDelta: 0.01 })
+        }
+    }, [addLandmarkStore.pendingLandmark])
+    /**
+     * Animates the map to fly over to and focus on the user's location.
+     */
+    const flyToUser = () => {
+
+        console.log('[Map]: Centering on user')
+        if (mapState.userLocation) {
+            mapState.mapRef.current?.animateToRegion({ latitude: mapState.userLocation.latitude, longitude: mapState.userLocation.longitude, latitudeDelta: 0.01, longitudeDelta: 0.01 })
+        }
+    }
+
+    /**
+     * Activates speech recognition and opens the voice panel
+     */
+    const startSpeech = async () => {
+        if (!(voicePermissionsGranted && locationPermissionsGranted)) {
+            setAlert({
+                title: "Permissions",
+                message: "Please enable location and voice permissions in the settings menu",
+                type: "warning",
+                callback: () => openSettings(),
+                callbackButtonText: 'Open settings'
+            })
+            return
+        }
+        props.toggleLmDetails(false);
+        props.toggleLmAdd(false);
+        const spokestackInitialized = await Spokestack.isInitialized()
+        const spokestackStarted = await Spokestack.isStarted()
+
+        if (spokestackInitialized && spokestackStarted) {
+            addLandmarkStore.stageNewLandmarkWithLocation({latitude: mapState.userLocation.latitude, longitude: mapState.userLocation.longitude})
+            mapState.toggleVoiceVisible(true)
+            Spokestack.activate()
+        }
+    }
+
+    /**
+     * Gets initial region that map should zoom into from current user location
+     */
+    const getInitialRegion = () => {
+        if (mapState.userLocation) {
+            return { latitude: mapState.userLocation.latitude, longitude: mapState.userLocation.longitude, latitudeDelta: 0.01, longitudeDelta: 0.01 }
+        }
+    }
+
+    /**
+     * Method that runs every time user location changes, updates user location state in memory and checks if any landmarks are nearby
+     */
+    const updateLocation = async (coord: LatLng) => {
+
+        mapState.setUserLocation(coord)
+        // get 10m radius around user
+        const userAlertRadius = circle([coord.longitude, coord.latitude], 10, { units: 'meters' })
+
+        // check each landmark to see if its inside user radius. if it is, and it isn't already in the list of notified landmarks, add it
+        const newLandmarksNearUser = props.landmarks?.filter(lm => {
+            const landmarkNearUser = booleanPointInPolygon([lm.longitude, lm.latitude], userAlertRadius)
+            return landmarkNearUser
+        })
+
+        // to prevent duplicate notifications make a list of landmarks that weren't previously near the user. 
+        // these are the only ones that the user will be notified of
+        const newLandmarksNotPreviouslyNearUser = newLandmarksNearUser?.filter(lm => mapState.landmarksNearUser.some(origLm => lm == origLm.id))
+
+        // update list
+        mapState.setLandmarksNearUser(newLandmarksNearUser)
+
+        // if there are any new landmarks near user, create a notification for them and send it
+        if (newLandmarksNotPreviouslyNearUser?.length > 0) {
+            const body = newLandmarksNotPreviouslyNearUser.length > 1 ? "There are new landmarks near by. Tap here to view" : "There is a new landmark close by. Tap here to view"
+            const notifType: NotifType = newLandmarksNotPreviouslyNearUser.length > 1 ? 'near-landmarks' : 'near-landmark'
+            const data = { notif_type: notifType, landmarks: newLandmarksNotPreviouslyNearUser.length == 1 ? newLandmarksNearUser : null }
+            await Notifications.scheduleNotificationAsync({
+                content: {
+                    title: "⚠ Landmarks close by ⚠",
+                    body: body,
+                    data: data
+                },
+                trigger: { seconds: 2 },
+            });
+        }
+    }
+
+    const focusNearbyLandmarks = () => {
+        if (mapState.landmarksNearUser?.length > 1) {
+            mapState.toggleNearbyLmPanel(true)
+        }
+        else if (mapState.landmarksNearUser?.length === 1) {
+            props.setSelectedLandmarkId(mapState.landmarksNearUser[0].id)
+        }
+    }
+
+    return (
+        <TouchableWithoutFeedback>
+            <>
+                {/*Main map component*/}
+                <Modal transparent={true} animationType="fade" visible={mapState.loading}>
+                    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: 'rgba(0,0,0,0.3)' }}>
+                        <View style={{ width: '60%', height: '30%', backgroundColor: colors.red, justifyContent: 'center', alignItems: 'center', borderRadius: 20 }}>
+                            <ActivityIndicator size="large" color="white" style={{ marginBottom: 20 }} />
+                            <Text style={{ fontSize: 15, color: 'white' }}>Refreshing</Text>
+                        </View>
+                    </View>
+                </Modal>
+                <MapView
+                    key={mapState.refreshKey}
+                    toolbarEnabled={false}
+                    onPress={() => Keyboard.dismiss()}
+                    testID="mapView"
+                    ref={mapState.mapRef}
+                    style={{ width: '100%', height: '100%' }}
+                    initialRegion={getInitialRegion()}
+                    onLongPress={async (e) => await props.promptAddLandmark(e.nativeEvent.coordinate.longitude, e.nativeEvent.coordinate.latitude)}
+                    showsUserLocation={locationPermissionsGranted}
+                    onUserLocationChange={e => updateLocation(e.nativeEvent.coordinate)}
+                    followsUserLocation={mapState.followUser}
+                    showsMyLocationButton={false}
+                    
+                    onRegionChangeComplete={(Region) => {
+                        console.log("size is " + size)
+                        console.log(Region.latitudeDelta)
+                        setSize(Region.latitudeDelta) 
+                      }}
+                    >
+                    <Polygon // polygon for cameron library
+                        coordinates={[
+                            { latitude: 53.527190, longitude: -113.524205 },
+                            { latitude: 53.526510, longitude: -113.524205 },
+                            { latitude: 53.526510, longitude: -113.523452 },
+                            { latitude: 53.527190, longitude: -113.523452 },
+                        ]}
+                        fillColor={`rgba(100,100,200,0.3)`}
+                        strokeWidth={2.5}
+                        tappable={true}
+                        onPress={() => props.mapNavigation.navigate("Indoor")}
+                    />
+
+                    {props.applyFilters(props.landmarks)?.map((landmark) => {
+                        if (landmark.floor == null) {
+                            let trackChanges = false;
+                            if (landmark?.id == props.selectedLandmarkId) {
+                                trackChanges = true;
+                            }
+                            return (
+                                <Marker
+                                    tracksViewChanges={trackChanges}
+                                    onPress={() => props.focusLandmark(landmark)}
+                                    key={landmark.id}
+                                    coordinate={{ latitude: landmark.latitude as number, longitude: landmark.longitude as number }} >
+                                    {landmark.landmark_type ? <Image style={{ height: 35, width: 25 }} source={lmTypes[landmark.landmark_type]?.image} /> : null}
+                                </Marker>)
+                        }
+                    }
+                    )}
+
+                    <Polyline
+                        coordinates={[
+                            {
+                                latitude: 53.527192,
+                                longitude: -113.523583, //Cameron
+                            },
+                            {
+                                latitude: 53.527189,
+                                longitude: -113.5233285,
+                            },
+                            {
+                                latitude: 53.526942,
+                                longitude: -113.523338,
+                            },
+                            {
+                                latitude: 53.526934,
+                                longitude: -113.523263,
+                            },
+                            {
+                                latitude: 53.5264874,
+                                longitude: -113.5232654,
+                            },
+                            {
+                                latitude: 53.526492,
+                                longitude: -113.522827,
+                            },
+                            {
+                                latitude: 53.52620959999999,
+                                longitude: -113.5228282,
+                            },
+                            {
+                                latitude: 53.5259882,
+                                longitude: -113.5222835,
+                            },
+                            {
+                                latitude: 53.5254566,
+                                longitude: -113.5222824,
+                            },
+                            {
+                                latitude: 53.525456,
+                                longitude: -113.522155,
+                            },
+                            {
+                                latitude: 53.5251288,
+                                longitude: -113.5216083, // University station
+                            },
+                        ]}
+                        strokeColor="black"
+                        strokeWidth={3}
+                        onPress={() => Alert.alert("This is a route from University Station to Cameron Library")}
+                        tappable={true}
+                    >
+                    </Polyline>
+                    {/* <MapViewDirections
+                        origin={coordinates[0]}
+                        destination={coordinates[1]}
+                        apikey={"xxxxxxxxxxxxxxx"} // insert your API Key here
+                        strokeWidth={4}
+                        strokeColor="#111111"
+                        mode="WALKING"
+                    /> */}
+                    <Marker coordinate={coordinates[1]} pinColor={colors.red}/>
+
+                    <Marker coordinate={{  latitude: 53.527189,longitude: -113.5233285, }} pinColor={colors.red}>
+                        {/* <Image source={require('../../../../assets/accessibleEntrance.png')} /> */}
+                        <Text style={{ fontSize: size>0.00327 ? 0 : 0.05/size , maxWidth:200, }}>Route from University Station to Cameron Library</Text>
+                    </Marker>
+
+
+
+
+
+                </MapView>
+                {/*Map buttons*/}
+                {mapState.landmarksNearUser?.length > 0 ?
+                    <TouchableOpacity style={[mapStyles.lowerMapButton, mapStyles.alertButton]} onPress={focusNearbyLandmarks}>
+                        <FontAwesome name='exclamation-triangle' size={20} color='white' />
+                        <Badge positioning={{ bottom: 7, right: 4 }} value={mapState.landmarksNearUser.length} />
+                    </TouchableOpacity> : null}
+                {locationPermissionsGranted && voicePermissionsGranted ?<IconButton size={20} color='white' style={[mapStyles.lowerMapButton, mapStyles.voiceButton]} icon="microphone" onPress={async () => await startSpeech()} /> : null}
+                <IconButton size={20} color='white' style={[mapStyles.lowerMapButton, mapStyles.addLandmarkButton]} icon="plus" onPress={async () => await props.promptAddLandmark(mapState.userLocation.longitude, mapState.userLocation.latitude)} />
+                <IconButton size={20} color='white' style={[mapStyles.lowerMapButton, mapStyles.userLocationButton]} icon="location-arrow" onPress={flyToUser} />
+                <NearbyLandmarksPanel
+                    focusLandmark={props.focusLandmark}
+                    nearbyLmPanelVisible={mapState.nearbyLmPanelVisible}
+                    toggleAlertedLmPanel={mapState.toggleNearbyLmPanel}
+                    nearbyLandmarks={mapState.landmarksNearUser} />
+                {/*Map Panels*/}
+                {locationPermissionsGranted && voicePermissionsGranted ?
+                    <VoicePanel
+                        landmarksNearby={mapState.landmarksNearUser?.length > 0}
+                        toggleAlertedLandmarksVisible={mapState.toggleNearbyLmPanel}
+                        navigation={props.authNavigation}
+                        userCoords={{ longitude: mapState.userLocation?.longitude, latitude: mapState.userLocation?.latitude }}
+                        toggleVoiceVisible={mapState.toggleVoiceVisible}
+                        toggleLmDetails={props.toggleLmDetails}
+                        voiceVisible={mapState.voiceVisible}
+                    /> : null}
+            </>
+        </TouchableWithoutFeedback>)
+}
+
+export default observer(OutdoorMap);

+ 3 - 145
src/presentation/maps/outdoor/outdoor-map.view.tsx

@@ -25,7 +25,7 @@ import Badge from "../../Badge";
 import { IconButton } from "../../Buttons";
 import mapStyles from "../Map.styles";
 import { MapStackNavigationProp, MapStackParamList } from "../MapNavigator";
-import { addLandmarkStore } from "../panels/AddLandmarkPanel/add-landmark-panel.store";
+import { addLandmarkStore } from "../panels/add-landmark-panel/add-landmark-panel.store";
 import NearbyLandmarksPanel from "../panels/NearbyLandmarksPanel";
 import { VoicePanel } from "../panels/VoicePanel";
 import { useOutdoorMapState } from "../useMapState";
@@ -66,152 +66,10 @@ interface OutdoorMapProps {
 }
 
 const OutdoorMap: React.FC<OutdoorMapProps> = (props) => {
-    const {locationPermissionsGranted, voicePermissionsGranted} = usePermissions();
-    const {setAlert} = useAuth()
-    const mapState = useOutdoorMapState()
-
-    // used to determine previous screens and decide if the map should be refreshed
-    const {index: mapNavigationIndex} = useNavigationState(state => state)
-
-    const [coordinates] = useState([
+    const coordinates = [
         { latitude: 53.527086340019856, longitude: -113.52358410971608, }, // Cameron library
         { latitude: 53.52516024715472, longitude: -113.52154139033108, }, // University station
-    ]);
-    const [size, setSize] = useState(0.052344);
-
-    // TODO: define this effect better and define an interface for the incoming route params
-    // when switching to this component, check if incoming navstate contains incoming selected landmarks, display them if there are. this will be triggered by incoming notifcations 
-    useEffect(() => {
-        console.log(props.route?.params?.selectedLandmark)
-        if (props.route?.params?.selectedLandmark) {
-            props.setSelectedLandmarkId(props.route?.params?.selectedLandmark)
-        }
-        if (props.route?.params?.nearbyLandmarks) {
-            mapState.toggleNearbyLmPanel(true)
-        }
-    }, [props.route])
-
-    // when either the map navigation state or main navigation state changes, check to see if we are coming from a different screen. if so, refresh the map to prevent map lag
-    useEffect(() => {
-        const toMap = mapNavigationIndex == 0 && props.authNavIndex == 0
-
-        if (toMap) mapState.setLoading(true)
-
-        setTimeout(() => {
-            mapState.setLoading(false)
-        }, 500);
-
-    }, [mapNavigationIndex, props.authNavIndex])
-
-    // Toggle the lm details panel when a new selected landmark is detected (triggered by pressing on a map marker, or from the list of nearby landmarks)
-    useEffect(() => {
-        console.log("[LandmarkDetails]: Landmark selected - " + props.selectedLandmarkId)
-        if (props.selectedLandmarkId) {
-            const landmark = props.landmarks.find(lm => lm.id == props.selectedLandmarkId)
-            mapState.mapRef.current.animateToRegion({ latitude: landmark.latitude, longitude: landmark.longitude, latitudeDelta: 0.01, longitudeDelta: 0.01 })
-            props.toggleLmDetails(true)
-        }
-    }, [props.selectedLandmarkId])
-
-    
-    // Move to pressed location when newlandmark changes
-    useEffect(() => {
-        if (props.selectedLandmarkId) {
-            mapState.mapRef.current.animateToRegion({ latitude: addLandmarkStore.pendingLandmark?.latitude, longitude: addLandmarkStore.pendingLandmark?.longitude, latitudeDelta: 0.01, longitudeDelta: 0.01 })
-        }
-    }, [addLandmarkStore.pendingLandmark])
-    /**
-     * Animates the map to fly over to and focus on the user's location.
-     */
-    const flyToUser = () => {
-
-        console.log('[Map]: Centering on user')
-        if (mapState.userLocation) {
-            mapState.mapRef.current?.animateToRegion({ latitude: mapState.userLocation.latitude, longitude: mapState.userLocation.longitude, latitudeDelta: 0.01, longitudeDelta: 0.01 })
-        }
-    }
-
-    /**
-     * Activates speech recognition and opens the voice panel
-     */
-    const startSpeech = async () => {
-        if (!(voicePermissionsGranted && locationPermissionsGranted)) {
-            setAlert({
-                title: "Permissions",
-                message: "Please enable location and voice permissions in the settings menu",
-                type: "warning",
-                callback: () => openSettings(),
-                callbackButtonText: 'Open settings'
-            })
-            return
-        }
-        props.toggleLmDetails(false);
-        props.toggleLmAdd(false);
-        const spokestackInitialized = await Spokestack.isInitialized()
-        const spokestackStarted = await Spokestack.isStarted()
-
-        if (spokestackInitialized && spokestackStarted) {
-            addLandmarkStore.stageNewLandmarkWithLocation({latitude: mapState.userLocation.latitude, longitude: mapState.userLocation.longitude})
-            mapState.toggleVoiceVisible(true)
-            Spokestack.activate()
-        }
-    }
-
-    /**
-     * Gets initial region that map should zoom into from current user location
-     */
-    const getInitialRegion = () => {
-        if (mapState.userLocation) {
-            return { latitude: mapState.userLocation.latitude, longitude: mapState.userLocation.longitude, latitudeDelta: 0.01, longitudeDelta: 0.01 }
-        }
-    }
-
-    /**
-     * Method that runs every time user location changes, updates user location state in memory and checks if any landmarks are nearby
-     */
-    const updateLocation = async (coord: LatLng) => {
-
-        mapState.setUserLocation(coord)
-        // get 10m radius around user
-        const userAlertRadius = circle([coord.longitude, coord.latitude], 10, { units: 'meters' })
-
-        // check each landmark to see if its inside user radius. if it is, and it isn't already in the list of notified landmarks, add it
-        const newLandmarksNearUser = props.landmarks?.filter(lm => {
-            const landmarkNearUser = booleanPointInPolygon([lm.longitude, lm.latitude], userAlertRadius)
-            return landmarkNearUser
-        })
-
-        // to prevent duplicate notifications make a list of landmarks that weren't previously near the user. 
-        // these are the only ones that the user will be notified of
-        const newLandmarksNotPreviouslyNearUser = newLandmarksNearUser?.filter(lm => mapState.landmarksNearUser.some(origLm => lm == origLm.id))
-
-        // update list
-        mapState.setLandmarksNearUser(newLandmarksNearUser)
-
-        // if there are any new landmarks near user, create a notification for them and send it
-        if (newLandmarksNotPreviouslyNearUser?.length > 0) {
-            const body = newLandmarksNotPreviouslyNearUser.length > 1 ? "There are new landmarks near by. Tap here to view" : "There is a new landmark close by. Tap here to view"
-            const notifType: NotifType = newLandmarksNotPreviouslyNearUser.length > 1 ? 'near-landmarks' : 'near-landmark'
-            const data = { notif_type: notifType, landmarks: newLandmarksNotPreviouslyNearUser.length == 1 ? newLandmarksNearUser : null }
-            await Notifications.scheduleNotificationAsync({
-                content: {
-                    title: "⚠ Landmarks close by ⚠",
-                    body: body,
-                    data: data
-                },
-                trigger: { seconds: 2 },
-            });
-        }
-    }
-
-    const focusNearbyLandmarks = () => {
-        if (mapState.landmarksNearUser?.length > 1) {
-            mapState.toggleNearbyLmPanel(true)
-        }
-        else if (mapState.landmarksNearUser?.length === 1) {
-            props.setSelectedLandmarkId(mapState.landmarksNearUser[0].id)
-        }
-    }
+    ];
 
     return (
         <TouchableWithoutFeedback>

+ 1 - 1
src/presentation/maps/panels/VoicePanel.tsx

@@ -19,7 +19,7 @@ import { usePermissions } from '../../../state/external/PermissionsContext';
 import { MainTabsNavigationProp } from '../../../navigation/main-tabs-navigator';
 import { colors, GlobalStyles, lmTypes } from '../../../utils/GlobalUtils';
 import { Separator } from '../../Separator';
-import { addLandmarkStore } from './AddLandmarkPanel/add-landmark-panel.store';
+import { addLandmarkStore } from './add-landmark-panel/add-landmark-panel.store';
 
 export interface VoicePanelProps {
     voiceVisible: boolean,

+ 1 - 1
src/presentation/maps/useMapState.ts

@@ -6,7 +6,7 @@
  */
 
 import { useRef, useState } from "react";
-import { UserLocation } from "./outdoor/OutdoorMap";
+import { UserLocation } from "./outdoor/outdoor-map.view";
 import MapView from "react-native-maps";
 import { Landmark } from "../../state/external/landmarks";