diff --git a/src/actions/actions.js b/src/actions/actions.js index e8e2d15f..5c8b3917 100644 --- a/src/actions/actions.js +++ b/src/actions/actions.js @@ -18,16 +18,17 @@ export const setToggleStateFood = (toggle, toggleState) => ({ toggleState }); -export const setFilterFunction = createAction('SET_FILTER_FUNCTION') +export const setFilterFunction = createAction('SET_FILTER_FUNCTION'); -export const setEntryFilterFunction = createAction('SET_ENTRY_FILTER_FUNCTION') +export const setEntryFilterFunction = createAction('SET_ENTRY_FILTER_FUNCTION'); -export const removeFilterFunction = createAction('REMOVE_FILTER_FUNCTION') +export const removeFilterFunction = createAction('REMOVE_FILTER_FUNCTION'); -export const removeEntryFilterFunction = createAction('REMOVE_ENTRY_FILTER_FUNCTION') - -export const resetFilterFunction = createAction('RESET_FILTER_FUNCTION') +export const removeEntryFilterFunction = createAction( + 'REMOVE_ENTRY_FILTER_FUNCTION' +); +export const resetFilterFunction = createAction('RESET_FILTER_FUNCTION'); export const getResources = createAsyncThunk( 'fetch-resources', @@ -38,12 +39,10 @@ export const getResources = createAsyncThunk( if (process.env.REACT_APP_CYPRESS_TEST) return testData; const snapshot = await get(ref(database, '/')); const results = snapshot.val(); - return Object.entries(results).map( - ([id, resource]) => ({ - ...resource, - id - }) - ); + return Object.entries(results).map(([id, resource]) => ({ + ...resource, + id + })); } ); @@ -57,17 +56,8 @@ export const pushNewResource = newResource => ({ // Handles the case where an existing resource is updated from the submission form export const updateExistingResource = createAction('UPDATE_EXISTING_RESOURCE'); -export const SET_USER_LOCATION = 'SET_USER_LOCATION'; -export const setUserLocation = coords => ({ - type: SET_USER_LOCATION, - coords -}); - -export const SET_MAP_CENTER = 'SET_MAP_CENTER'; -export const setMapCenter = coords => ({ - type: SET_MAP_CENTER, - coords -}); +export const setUserLocation = createAction('SET_USER_LOCATION'); +export const setLastResourcePan = createAction('SET_LAST_RESOURCE_PAN'); export const toggleInfoWindow = createAction('TOGGLE_INFO_WINDOW'); export const toggleInfoWindowClass = createAction('TOGGLE_INFO_WINDOW_CLASS'); @@ -88,14 +78,12 @@ export const setFilteredFoodTypes = foodType => ({ foodType }); -export const SET_SELECTED_PLACE = 'SET_SELECTED_PLACE'; -export const setSelectedPlace = selectedPlace => ({ - type: SET_SELECTED_PLACE, - selectedPlace -}); +export const setSelectedPlace = createAction('SET_SELECTED_PLACE'); export const setSearchBarMapTintOn = createAction('SET_SEARCH_BAR_MAP_TINT'); -export const setTapInfoOpenedWhileSearchOpen = createAction('SET_TAP_INFO_OPENED_WHILE_SEARCH_OPEN'); +export const setTapInfoOpenedWhileSearchOpen = createAction( + 'SET_TAP_INFO_OPENED_WHILE_SEARCH_OPEN' +); export const setToolbarModal = createAction('SET_TOOLBAR_MODAL'); export const TOOLBAR_MODAL_NONE = 'TOOLBAR_MODAL_NONE'; diff --git a/src/components/ReactGoogleMaps/ReactGoogleMaps.js b/src/components/ReactGoogleMaps/ReactGoogleMaps.js index 1dea00f4..639a143d 100644 --- a/src/components/ReactGoogleMaps/ReactGoogleMaps.js +++ b/src/components/ReactGoogleMaps/ReactGoogleMaps.js @@ -14,7 +14,7 @@ import { resetFilterFunction, setEntryFilterFunction, setFilterFunction, - setMapCenter, + setLastResourcePan, setSelectedPlace, setUserLocation, toggleInfoWindow, @@ -207,16 +207,13 @@ export const ReactGoogleMaps = ({ google }) => { const isMobile = useIsMobile(); const allResources = useSelector(state => state.filterMarkers.allResources); const filteredResources = useSelector(state => selectFilteredResource(state)); - const mapCenter = useSelector(state => state.filterMarkers.mapCenter); + const lastResourcePan = useSelector(state => state.filterMarkers.lastResourcePan); const resourceType = useSelector(state => state.filterMarkers.resourceType); const searchBarMapTintOn = useSelector(state => state.filterMarkers.searchBarMapTintOn); const showingInfoWindow = useSelector( state => state.filterMarkers.showingInfoWindow ); const toolbarModal = useSelector(state => state.filterMarkers.toolbarModal); - - const [currentLat, setCurrentLat] = useState(CITY_HALL_COORDINATES.latitude); - const [currentLon, setCurrentLon] = useState(CITY_HALL_COORDINATES.longitude); const [zoom, setZoom] = useState(16); const [searchedTap, setSearchedTap] = useState(null); const [map, setMap] = useState(null); @@ -237,8 +234,18 @@ export const ReactGoogleMaps = ({ google }) => { const fetchCoordinates = async () => { try { const position = await getCoordinates(); - setCurrentLat(position.coords.latitude); - setCurrentLon(position.coords.longitude); + dispatch( + setUserLocation({ + lat: position.coords.latitude, + lng: position.coords.longitude + }) + ); + dispatch( + setLastResourcePan({ + lat: position.coords.latitude, + lng: position.coords.longitude + }) + ) } catch (error) { // Do nothing } @@ -246,7 +253,7 @@ export const ReactGoogleMaps = ({ google }) => { fetchCoordinates(); }, []); - + //toggle window goes here const onMarkerClick = (resource, markerProps) => { dispatch( @@ -256,10 +263,13 @@ export const ReactGoogleMaps = ({ google }) => { }) ); dispatch(setSelectedPlace(resource)); - setCurrentLat(resource.latitude); - setCurrentLon(resource.longitude); + dispatch( + setLastResourcePan({ + lat: resource.latitude, + lng: resource.longitude + }) + ) markerProps.map.panTo({ lat: resource.latitude, lng: resource.longitude }); - }; const onReady = (_, map) => { @@ -267,8 +277,12 @@ export const ReactGoogleMaps = ({ google }) => { }; const searchForLocation = location => { - setCurrentLat(location.lat); - setCurrentLon(location.lng); + dispatch( + setLastResourcePan({ + lat: location.lat, + lng: location.lng + }) + ) setZoom(16); setSearchedTap({ lat: location.lat, lng: location.lng }); }; @@ -339,8 +353,8 @@ export const ReactGoogleMaps = ({ google }) => { fullscreenControl={false} onReady={onReady} center={{ - lat: currentLat, - lng: currentLon + lat: lastResourcePan.lat, + lng: lastResourcePan.lng }} filterTags={appliedFilterTags} > diff --git a/src/components/SelectedTap/SelectedTap.js b/src/components/SelectedTap/SelectedTap.js index 9f08ef55..685bde43 100644 --- a/src/components/SelectedTap/SelectedTap.js +++ b/src/components/SelectedTap/SelectedTap.js @@ -131,8 +131,8 @@ const SelectedTap = () => { toggleInfoWindow({ isShown, infoWindowClass: isMobile - ? 'info-window-out' - : 'info-window-out-desktop' + ? 'info-window-in' + : 'info-window-in-desktop' }) ); } diff --git a/src/components/Toolbar/Toolbar.js b/src/components/Toolbar/Toolbar.js index 820e6a1a..67e04969 100644 --- a/src/components/Toolbar/Toolbar.js +++ b/src/components/Toolbar/Toolbar.js @@ -6,9 +6,10 @@ import { TOOLBAR_MODAL_NONE, TOOLBAR_MODAL_RESOURCE, TOOLBAR_MODAL_SEARCH, + setLastResourcePan, setSelectedPlace, setToolbarModal, - toggleInfoWindow, + toggleInfoWindow } from '../../actions/actions'; import styles from './Toolbar.module.scss'; @@ -51,7 +52,7 @@ function distance(lat1, lon1, lat2, lon2) { (Math.cos(lat1 * p) * Math.cos(lat2 * p) * (1 - Math.cos((lon2 - lon1) * p))) / - 2; + 2; return 12742 * Math.asin(Math.sqrt(a)); } @@ -112,15 +113,23 @@ function Toolbar({ map }) { }); if (!closest) return; - dispatch(toggleInfoWindow({ - isShown: true, - infoWindowClass: isMobile ? 'info-window-in' : 'info-window-in-desktop' - })); + dispatch( + setLastResourcePan({ + lat: closest.latitude, + lng: closest.longitude + }) + ); dispatch(setSelectedPlace(closest)); map.panTo({ lat: closest.latitude, lng: closest.longitude }); + dispatch( + toggleInfoWindow({ + isShown: true, + infoWindowClass: isMobile ? 'info-window-in' : 'info-window-in-desktop' + }) + ); } function closestButtonClicked() { diff --git a/src/reducers/filterMarkers.js b/src/reducers/filterMarkers.js index b5700af6..049b44bb 100644 --- a/src/reducers/filterMarkers.js +++ b/src/reducers/filterMarkers.js @@ -3,11 +3,12 @@ import * as actions from '../actions/actions'; import { WATER_RESOURCE_TYPE } from '../types/ResourceEntry'; const initialState = { - mapCenter: { + // Captures location when e.g. a pin is clicked or "Near Me" is clicked + lastResourcePan: { lat: parseFloat(CITY_HALL_COORDINATES.latitude), lng: parseFloat(CITY_HALL_COORDINATES.longitude) }, - // Change to reflect user's current location + // Changes to reflect user's current location if location is enabled userLocation: { lat: parseFloat(CITY_HALL_COORDINATES.latitude), lng: parseFloat(CITY_HALL_COORDINATES.longitude) @@ -16,14 +17,14 @@ const initialState = { infoIsExpanded: false, infoWindowClass: 'info-window-out-desktop', filterTags: [], - filterEntry: "", + filterEntry: '', /** @type {ResourceEntry[]} */ allResources: [], selectedPlace: {}, toolbarModal: actions.TOOLBAR_MODAL_NONE, setSearchBarMapTintOn: false, tapInfoOpenedWhileSearchOpen: false, - resourceType: WATER_RESOURCE_TYPE, + resourceType: WATER_RESOURCE_TYPE }; export default (state = initialState, act) => { @@ -72,11 +73,11 @@ export default (state = initialState, act) => { } }; - case actions.SET_USER_LOCATION: - return { ...state, userLocation: act.coords }; + case actions.setUserLocation.type: + return { ...state, userLocation: act.payload }; - case actions.SET_MAP_CENTER: - return { ...state, mapCenter: act.coords }; + case actions.setLastResourcePan.type: + return { ...state, lastResourcePan: act.payload }; case actions.getResources.fulfilled.type: return { ...state, allResources: act.payload }; @@ -88,22 +89,22 @@ export default (state = initialState, act) => { }; case actions.setFilterFunction.type: - return { ...state, filterTags: [...state.filterTags, act.payload.tag] } + return { ...state, filterTags: [...state.filterTags, act.payload.tag] }; case actions.setEntryFilterFunction.type: - return { ...state, filterEntry: act.payload.tag } + return { ...state, filterEntry: act.payload.tag }; case actions.removeFilterFunction.type: return { ...state, filterTags: state.filterTags.filter(x => x !== act.payload.tag) - } + }; case actions.removeEntryFilterFunction.type: return { ...state, filterEntry: '' - } + }; case actions.resetFilterFunction.type: return { @@ -121,25 +122,26 @@ export default (state = initialState, act) => { ) }; - case actions.SET_SELECTED_PLACE: - // if passed Selected Place as an object, set selected place as the object - // if passed an ID, locate the item using ID, then set selected place - return typeof act.selectedPlace === 'object' - ? { ...state, selectedPlace: act.selectedPlace } - : { - ...state, - selectedPlace: state.allResources[act.selectedPlace], - showingInfoWindow: true - }; + case actions.setSelectedPlace.type: + return { + ...state, + selectedPlace: act.payload, + showingInfoWindow: true + }; case actions.toggleInfoWindow.type: return { ...state, showingInfoWindow: act.payload.isShown, infoWindowClass: act.payload.infoWindowClass, - searchBarMapTintOn: act.payload.isShown ? false : state.setSearchBarMapTintOn, + searchBarMapTintOn: act.payload.isShown + ? false + : state.setSearchBarMapTintOn, tapInfoOpenedWhileSearchOpen: - act.payload.isShown && (state.toolbarModal === actions.TOOLBAR_MODAL_SEARCH) ? true : false + act.payload.isShown && + state.toolbarModal === actions.TOOLBAR_MODAL_SEARCH + ? true + : false }; case actions.toggleInfoWindowClass.type: @@ -187,10 +189,10 @@ export default (state = initialState, act) => { } case actions.setSearchBarMapTintOn.type: - return { ...state, searchBarMapTintOn: act.payload } + return { ...state, searchBarMapTintOn: act.payload }; case actions.setTapInfoOpenedWhileSearchOpen.type: - return { ...state, tapInfoOpenedWhileSearchOpen: act.payload } + return { ...state, tapInfoOpenedWhileSearchOpen: act.payload }; case actions.setToolbarModal.type: return { ...state, toolbarModal: act.payload };