import React, { useEffect, useRef, useState } from 'react'; import {Image, StyleSheet, View, TouchableOpacity, ScrollView, Text, Alert} from 'react-native'; import MapboxGL from '@react-native-mapbox-gl/maps'; import 'react-native-get-random-values' import { seedLandmarkData, useMockState } from '../contexts/MockContext'; import Modal from 'react-native-modalbox'; import LandmarkDetails from '../components/LandmarkDetails'; import {Icons} from '../globals.js'; import Icon from 'react-native-vector-icons/FontAwesome'; import VoiceView from '../components/VoiceView'; import RNLocation from 'react-native-location'; import { polygon, point, booleanPointInPolygon } from '@turf/turf'; import ModalDropdown from 'react-native-modal-dropdown'; MapboxGL.setAccessToken('pk.eyJ1IjoiY2Rtb3NzIiwiYSI6ImNrbmhuOXJzcDIyd20ycW1pYm8xaGI0aGUifQ.j04Sp636N9Wg4N9j9t2tXw'); RNLocation.configure({ distanceFilter: 1 }); const places = { type: 'FeatureCollection', features: [ { type: 'Feature', id: 'test1', properties: { name: 'University of Alberta' }, geometry: { "type": "Polygon", "coordinates": [ [ [ -113.53271484375, 53.517705925148846 ], [ -113.52018356323242, 53.515511461129655 ], [ -113.52044105529785, 53.52311504872178 ], [ -113.51529121398926, 53.522757863745845 ], [ -113.5151195526123, 53.52576832854355 ], [ -113.53134155273438, 53.53143150445749 ], [ -113.53271484375, 53.517705925148846 ] ] ] } } ] } const Map = ({navigation, route}) => { const { dispatch, state } = useMockState(); //const [center, setCenter] = useState([-113.4982408198804, 53.56484760459073]); const [center, setCenter] = useState([]); const [tempPoint, setTempPoint] = useState(null); const [selectedPlaces, setPlaces] = useState([]); const [voiceActive, setVoice] = useState(false); const landmarkAddModal = useRef(); const mapMenuModal = useRef(); const landmarkDetailsModal = useRef(); const voiceModal = useRef(); const map = useRef(); useEffect(() => { // const unsubscribePermission = RNLocation.subscribeToPermissionUpdates(currentPermission => { // dispatch({ type:"UPDATE_LOCATION_PERMISSION", payload: currentPermission }); // }); // const unsubscribeLocation = RNLocation.subscribeToLocationUpdates(locations => { // dispatch({ type:"UPDATE_LOCATION", payload: locations }); // }); async function handleLocation() { if (state.landmarks == null) { const landmarks = seedLandmarkData(); dispatch({ type:"UPDATE_LANDMARKS", payload: landmarks }); } if (state.location == null && !state.locationPermission) { dispatch({type: 'UPDATE_LOCATION_PERMISSION', payload: await RNLocation.requestPermission({ ios: "whenInUse", android: { detail: "fine", rationale: { title: "We need to access your location", message: "We use your location to provide convenient features such as geo-activated notifications and adding landmarks via voice", buttonPositive: "Grant permission", buttonNegative: "No thanks" } } })}) } } handleLocation(); return() => { // unsubscribePermission(); // unsubscribeLocation(); } },[state]); const changeSelectedLandmark = (landmark) => { dispatch({ type:"UPDATE_SELECTED_LANDMARK", payload: landmark}); } const showLandmarkDetails = (landmark) => { changeSelectedLandmark(landmark); landmarkDetailsModal.current.open(); } const openVoiceModal = () => { if (!state.locationPermission) { Alert.alert('You need to provide location permission to use this feature.') } else { RNLocation.getLatestLocation({timeout: 100}).then(location => { dispatch({ type:"UPDATE_LOCATION", payload: location}); voiceModal.current.open(); setVoice(true); }) } } const handleMapTouch = (e) => { setTempPoint(e.geometry.coordinates); changeSelectedLandmark({ longitude: e.geometry.coordinates[0], latitude: e.geometry.coordinates[1], icon: 'barrier', title: '', desc: '' }) landmarkAddModal.current.open(); } const handlePlaceTouch = (e) => { setTempPoint([e.coordinates.longitude, e.coordinates.latitude]); const touchedPlaces = e.features.filter(f => { return booleanPointInPolygon(point([e.coordinates.longitude, e.coordinates.latitude]), polygon(f.geometry.coordinates)); }); if (touchedPlaces.length == 0) { changeSelectedLandmark({ longitude: e.coordinates.longitude, latitude: e.coordinates.latitude, icon: 'barrier', title: '', desc: '' }); landmarkAddModal.current.open(); } else { setPlaces(touchedPlaces); mapMenuModal.current.open(); } } const addLandmark = () => { landmarkAddModal.current.close(); navigation.navigate("LandmarkForm"); } const removeTempPoint = () => { setTempPoint(null); } const editLandmark = () => { navigation.navigate("LandmarkForm"); } const closeModal = (message) => { landmarkDetailsModal.current.close(); if (message != null) { Alert.alert(message); } }; const clearModals = () => { landmarkDetailsModal.current.close(); voiceModal.current.close(); landmarkAddModal.current.close(); }; return( {clearModals(); navigation.jumpTo('Account');}}> atlas handleMapTouch(e)} // onLongPress={p => promptAddPlace(p.geometry.coordinates)} > {tempPoint && } {state.landmarks.map(landmark => { return ( showLandmarkDetails(landmark)} > )})} handlePlaceTouch(e)} id="test" shape={places}> {state.locationPermission ? : null} What would you like to do? Add landmark p.properties.name)[0]} defaultIndex={0} options={selectedPlaces.map(p => p.properties.name)}/> landmarkAddModal.current.close()}> Cancel Add landmark here? landmarkAddModal.current.close()}> Cancel Add ) } const styles = StyleSheet.create({ container: { flex: 1 }, mapHeader: { justifyContent: 'space-between', flexDirection: 'row', alignItems: 'center', height: '9%', zIndex: 5, backgroundColor: '#df3f3f', }, mapContainer: { height: '100%', width: '100%', backgroundColor: 'white', }, markerContainer: { height: 50, width: 50, backgroundColor: 'white', }, markerImg: { height: 25, width: 25 }, mapbox: { flex: 1, }, micBtn: { position: 'absolute', backgroundColor: '#df3f3f', justifyContent: 'center', alignItems: 'center', borderRadius: 40, bottom: 70, right: 20, zIndex: 5, width: 60, height: 60, }, menuModal: { backgroundColor: '#df3f3f', height: 200, }, addModal: { backgroundColor: '#df3f3f', height: 100, }, voiceModal: { backgroundColor: '#df3f3f', height: 200, }, addTitle: { color: 'white', fontSize: 20, marginTop: 20, marginLeft: 20 } }) export default Map;