|
@@ -27,7 +27,7 @@ import { IconButton } from "../../Buttons";
|
|
|
import NearbyLandmarksPanel from "../Panels/NearbyLandmarksPanel";
|
|
|
import { VoicePanel } from "../Panels/VoicePanel";
|
|
|
import mapStyles from "./Map.styles";
|
|
|
-import { useOutdoorMapState } from "./useMapState";
|
|
|
+import { useOutdoorMapState, useMapState } from "./useMapState";
|
|
|
|
|
|
/**
|
|
|
* An interface representing the user location retrieved from [expo-location]{@link https://docs.expo.dev/versions/latest/sdk/location/}.
|
|
@@ -70,7 +70,8 @@ interface OutdoorMapProps {
|
|
|
const OutdoorMap: React.FC<OutdoorMapProps> = (props) => {
|
|
|
const {locationPermissionsGranted, checkLocationPermissions, voicePermissionsGranted, checkVoicePermissions} = usePermissions();
|
|
|
const {setAlert} = useAuth()
|
|
|
- const mapState = useOutdoorMapState()
|
|
|
+ const mapStateOutdoor = useOutdoorMapState()
|
|
|
+ const mapState = useMapState()
|
|
|
|
|
|
const mapNavIndex = useNavigationState(state => state)
|
|
|
|
|
@@ -89,17 +90,17 @@ const OutdoorMap: React.FC<OutdoorMapProps> = (props) => {
|
|
|
props.setSelectedLandmarkId(props.route?.params?.selectedLandmark)
|
|
|
}
|
|
|
if (props.route?.params?.selectedLandmarks) {
|
|
|
- mapState.toggleNearbyLmPanel(true)
|
|
|
+ mapStateOutdoor.toggleNearbyLmPanel(true)
|
|
|
}
|
|
|
}, [props.route])
|
|
|
|
|
|
useEffect(() => {
|
|
|
const toMap = mapNavIndex.index == 0 && props.authNavIndex == 0
|
|
|
|
|
|
- if (toMap) mapState.setLoading(true)
|
|
|
+ if (toMap) mapStateOutdoor.setLoading(true)
|
|
|
|
|
|
setTimeout(() => {
|
|
|
- mapState.setLoading(false)
|
|
|
+ mapStateOutdoor.setLoading(false)
|
|
|
}, 500);
|
|
|
|
|
|
}, [mapNavIndex, props.authNavIndex])
|
|
@@ -111,7 +112,7 @@ const OutdoorMap: React.FC<OutdoorMapProps> = (props) => {
|
|
|
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 })
|
|
|
+ mapStateOutdoor.mapRef.current.animateToRegion({ latitude: landmark.latitude, longitude: landmark.longitude, latitudeDelta: 0.01, longitudeDelta: 0.01 })
|
|
|
props.toggleLmDetails(true)
|
|
|
}
|
|
|
}, [props.selectedLandmarkId])
|
|
@@ -121,7 +122,7 @@ const OutdoorMap: React.FC<OutdoorMapProps> = (props) => {
|
|
|
*/
|
|
|
useEffect(() => {
|
|
|
if (props.selectedLandmarkId) {
|
|
|
- mapState.mapRef.current.animateToRegion({ latitude: props.newLandmark?.latitude, longitude: props.newLandmark?.longitude, latitudeDelta: 0.01, longitudeDelta: 0.01 })
|
|
|
+ mapStateOutdoor.mapRef.current.animateToRegion({ latitude: props.newLandmark?.latitude, longitude: props.newLandmark?.longitude, latitudeDelta: 0.01, longitudeDelta: 0.01 })
|
|
|
}
|
|
|
}, [props.newLandmark])
|
|
|
/**
|
|
@@ -130,8 +131,8 @@ const OutdoorMap: React.FC<OutdoorMapProps> = (props) => {
|
|
|
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 })
|
|
|
+ if (mapStateOutdoor.userLocation) {
|
|
|
+ mapStateOutdoor.mapRef.current?.animateToRegion({ latitude: mapStateOutdoor.userLocation.latitude, longitude: mapStateOutdoor.userLocation.longitude, latitudeDelta: 0.01, longitudeDelta: 0.01 })
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -156,7 +157,7 @@ const OutdoorMap: React.FC<OutdoorMapProps> = (props) => {
|
|
|
|
|
|
if (spokestackInitialized)
|
|
|
if (spokestackStarted) {
|
|
|
- mapState.toggleVoiceVisible(true)
|
|
|
+ mapStateOutdoor.toggleVoiceVisible(true)
|
|
|
Spokestack.activate()
|
|
|
}
|
|
|
}
|
|
@@ -165,8 +166,8 @@ const OutdoorMap: React.FC<OutdoorMapProps> = (props) => {
|
|
|
* 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 }
|
|
|
+ if (mapStateOutdoor.userLocation) {
|
|
|
+ return { latitude: mapStateOutdoor.userLocation.latitude, longitude: mapStateOutdoor.userLocation.longitude, latitudeDelta: 0.01, longitudeDelta: 0.01 }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -175,7 +176,7 @@ const OutdoorMap: React.FC<OutdoorMapProps> = (props) => {
|
|
|
*/
|
|
|
const updateLocation = async (coord: LatLng) => {
|
|
|
|
|
|
- mapState.setUserLocation(coord)
|
|
|
+ mapStateOutdoor.setUserLocation(coord)
|
|
|
// get 10m radius around user
|
|
|
const userAlertRadius = circle([coord.longitude, coord.latitude], 10, { units: 'meters' })
|
|
|
|
|
@@ -187,10 +188,10 @@ const OutdoorMap: React.FC<OutdoorMapProps> = (props) => {
|
|
|
|
|
|
// 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))
|
|
|
+ const newLandmarksNotPreviouslyNearUser = newLandmarksNearUser?.filter(lm => mapStateOutdoor.landmarksNearUser.some(origLm => lm == origLm.id))
|
|
|
|
|
|
// update list
|
|
|
- mapState.setLandmarksNearUser(newLandmarksNearUser)
|
|
|
+ mapStateOutdoor.setLandmarksNearUser(newLandmarksNearUser)
|
|
|
|
|
|
// if there are any new landmarks near user, create a notification for them and send it
|
|
|
if (newLandmarksNotPreviouslyNearUser?.length > 0) {
|
|
@@ -209,11 +210,11 @@ const OutdoorMap: React.FC<OutdoorMapProps> = (props) => {
|
|
|
}
|
|
|
|
|
|
const focusNearbyLandmarks = () => {
|
|
|
- if (mapState.landmarksNearUser?.length > 1) {
|
|
|
- mapState.toggleNearbyLmPanel(true)
|
|
|
+ if (mapStateOutdoor.landmarksNearUser?.length > 1) {
|
|
|
+ mapStateOutdoor.toggleNearbyLmPanel(true)
|
|
|
}
|
|
|
- else if (mapState.landmarksNearUser?.length === 1) {
|
|
|
- props.setSelectedLandmarkId(mapState.landmarksNearUser[0].id)
|
|
|
+ else if (mapStateOutdoor.landmarksNearUser?.length === 1) {
|
|
|
+ props.setSelectedLandmarkId(mapStateOutdoor.landmarksNearUser[0].id)
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -221,7 +222,7 @@ const OutdoorMap: React.FC<OutdoorMapProps> = (props) => {
|
|
|
<TouchableWithoutFeedback>
|
|
|
<>
|
|
|
{/*Main map component*/}
|
|
|
- <Modal transparent={true} animationType="fade" visible={mapState.loading}>
|
|
|
+ <Modal transparent={true} animationType="fade" visible={mapStateOutdoor.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 }} />
|
|
@@ -230,23 +231,23 @@ const OutdoorMap: React.FC<OutdoorMapProps> = (props) => {
|
|
|
</View>
|
|
|
</Modal>
|
|
|
<MapView
|
|
|
- key={mapState.refreshKey}
|
|
|
+ key={mapStateOutdoor.refreshKey}
|
|
|
toolbarEnabled={false}
|
|
|
onPress={() => Keyboard.dismiss()}
|
|
|
testID="mapView"
|
|
|
- ref={mapState.mapRef}
|
|
|
+ ref={mapStateOutdoor.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}
|
|
|
+ followsUserLocation={mapStateOutdoor.followUser}
|
|
|
showsMyLocationButton={false}
|
|
|
|
|
|
onRegionChangeComplete={async (Region) => {
|
|
|
if (props.selectedLandmarkId) {
|
|
|
|
|
|
- const {x, y} = await mapState.mapRef.current.pointForCoordinate({latitude: Region.latitude, longitude: Region.longitude})
|
|
|
+ const {x, y} = await mapStateOutdoor.mapRef.current.pointForCoordinate({latitude: Region.latitude, longitude: Region.longitude})
|
|
|
props.setMarkerWindowPosition({x: x, y: y})
|
|
|
}
|
|
|
setSize(Region.latitudeDelta)
|
|
@@ -262,7 +263,10 @@ const OutdoorMap: React.FC<OutdoorMapProps> = (props) => {
|
|
|
fillColor={`rgba(100,100,200,0.3)`}
|
|
|
strokeWidth={2.5}
|
|
|
tappable={true}
|
|
|
- onPress={() => props.mapNavigation.navigate("Indoor")}
|
|
|
+ onPress={() => {
|
|
|
+ mapState.setPlace("Cameron")
|
|
|
+ props.mapNavigation.navigate("Indoor")}
|
|
|
+ }
|
|
|
/>
|
|
|
|
|
|
{props.applyFilters(props.landmarks)?.map((landmark) => {
|
|
@@ -344,30 +348,30 @@ const OutdoorMap: React.FC<OutdoorMapProps> = (props) => {
|
|
|
</Marker>
|
|
|
</MapView>
|
|
|
{/*Map buttons*/}
|
|
|
- {mapState.landmarksNearUser?.length > 0 ?
|
|
|
+ {mapStateOutdoor.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} />
|
|
|
+ <Badge positioning={{ bottom: 7, right: 4 }} value={mapStateOutdoor.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.addLandmarkButton]} icon="plus" onPress={async () => await props.promptAddLandmark(mapStateOutdoor.userLocation.longitude, mapStateOutdoor.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} />
|
|
|
+ nearbyLmPanelVisible={mapStateOutdoor.nearbyLmPanelVisible}
|
|
|
+ toggleAlertedLmPanel={mapStateOutdoor.toggleNearbyLmPanel}
|
|
|
+ nearbyLandmarks={mapStateOutdoor.landmarksNearUser} />
|
|
|
{/*Map Panels*/}
|
|
|
{locationPermissionsGranted && voicePermissionsGranted ?
|
|
|
<VoicePanel
|
|
|
- landmarksNearby={mapState.landmarksNearUser?.length > 0}
|
|
|
- toggleAlertedLandmarksVisible={mapState.toggleNearbyLmPanel}
|
|
|
+ landmarksNearby={mapStateOutdoor.landmarksNearUser?.length > 0}
|
|
|
+ toggleAlertedLandmarksVisible={mapStateOutdoor.toggleNearbyLmPanel}
|
|
|
navigation={props.authNavigation}
|
|
|
- userCoords={{ longitude: mapState.userLocation?.longitude, latitude: mapState.userLocation?.latitude }}
|
|
|
- toggleVoiceVisible={mapState.toggleVoiceVisible}
|
|
|
+ userCoords={{ longitude: mapStateOutdoor.userLocation?.longitude, latitude: mapStateOutdoor.userLocation?.latitude }}
|
|
|
+ toggleVoiceVisible={mapStateOutdoor.toggleVoiceVisible}
|
|
|
toggleLmDetails={props.toggleLmDetails}
|
|
|
setSelectedLandmarkId={props.setSelectedLandmarkId}
|
|
|
- voiceVisible={mapState.voiceVisible}
|
|
|
+ voiceVisible={mapStateOutdoor.voiceVisible}
|
|
|
newLandmark={props.newLandmark}
|
|
|
setNewLandmark={props.setNewLandmark}
|
|
|
/> : null}
|