From 47932534ec1947524bcb0a100a41ea43550addf1 Mon Sep 17 00:00:00 2001
From: Heather Houde <114454164+hhoude36@users.noreply.github.com>
Date: Tue, 23 May 2023 20:17:32 -0400
Subject: [PATCH] =?UTF-8?q?closest=20tap=20function=20added=20on=20mobile?=
=?UTF-8?q?=20and=20desktop=20version=20(=20no=20button=20=E2=80=A6=20(#31?=
=?UTF-8?q?5)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* closest tap function added on mobile and desktop version ( no button on desktop). The water resources work fine, but the rest of the resources will show the closest food org because the component does not have access to the foraging/bathroom data.
* Switches setClosest behavior to use switch statement and adds defaults for foraging and bathroom state data
---------
Co-authored-by: Gabriel Cardona <2278918+gcardonag@users.noreply.github.com>
---
src/actions/actions.js | 2 +-
src/components/ClosestTap/ClosestTap.js | 2 +-
src/components/Foot/Foot.js | 2 +-
src/components/SelectedTap/SelectedTap.js | 55 ++++++------
src/components/Toolbar/Toolbar.js | 103 +++++++++++++++-------
src/reducers/filterMarkers.js | 6 ++
6 files changed, 110 insertions(+), 60 deletions(-)
diff --git a/src/actions/actions.js b/src/actions/actions.js
index 8f089cb4..622e476c 100644
--- a/src/actions/actions.js
+++ b/src/actions/actions.js
@@ -106,7 +106,7 @@ export const getBathroomTaps = () => dispatch => {
return onValue(ref(database, '/'), snapshot => {
const snapshotVal = snapshot.val();
- dispatch(getForagingSuccess(snapshotVal));
+ dispatch(getBathroomSuccess(snapshotVal));
});
};
diff --git a/src/components/ClosestTap/ClosestTap.js b/src/components/ClosestTap/ClosestTap.js
index 22e7f6cd..e272244c 100644
--- a/src/components/ClosestTap/ClosestTap.js
+++ b/src/components/ClosestTap/ClosestTap.js
@@ -47,8 +47,8 @@ function getClosest(data, v) {
closestTap.address = distances[i].address;
}
}
-
return closestTap;
+
}
function getCoordinates() {
diff --git a/src/components/Foot/Foot.js b/src/components/Foot/Foot.js
index 6cf11239..709ebe76 100644
--- a/src/components/Foot/Foot.js
+++ b/src/components/Foot/Foot.js
@@ -1,5 +1,5 @@
import React, { Component } from 'react';
-
+import ClosestTap from '../ClosestTap/ClosestTap';
export class Foot extends Component {
render() {
return (
diff --git a/src/components/SelectedTap/SelectedTap.js b/src/components/SelectedTap/SelectedTap.js
index 651c25da..f669b9cf 100644
--- a/src/components/SelectedTap/SelectedTap.js
+++ b/src/components/SelectedTap/SelectedTap.js
@@ -59,10 +59,11 @@ class SelectedTap extends React.Component {
};
getWalkingDurationAndTimes = () => {
+ if (!this.props.selectedPlace) return;
const orsAPIKey =
'5b3ce3597851110001cf6248ac903cdbe0364ca9850aa85cb64d8dfc';
fetch(`https://api.openrouteservice.org/v2/directions/foot-walking?api_key=${orsAPIKey}&start=${this.props.userLocation.lng},
- ${this.props.userLocation.lat}&end=${this.props.selectedPlace.lon},${this.props.selectedPlace.lat}`)
+ ${this.props.userLocation?.lat}&end=${this.props.selectedPlace?.lon},${this.props.selectedPlace?.lat}`)
.then(response => response.json())
.then(data => {
// duration is returned in seconds
@@ -165,7 +166,7 @@ class SelectedTap extends React.Component {
ReactGA.event({
category: `Tap - ${this.props.phlaskType}`,
action: 'InfoShown',
- label: `${this.props.selectedPlace.organization}, ${this.props.selectedPlace.address}`
+ label: `${this.props.selectedPlace?.organization}, ${this.props.selectedPlace?.address}`
});
}
@@ -175,13 +176,13 @@ class SelectedTap extends React.Component {
const selectedPlace = this.props.selectedPlace;
this.setState({
- organization: selectedPlace.organization,
- address: selectedPlace.address,
- tapDescription: selectedPlace.description
- ? selectedPlace.description
+ organization: selectedPlace?.organization,
+ address: selectedPlace?.address,
+ tapDescription: selectedPlace?.description
+ ? selectedPlace?.description
: 'Happy PHLasking',
- tapStatement: selectedPlace.statement,
- tapNormsAndRules: selectedPlace.norms_rules
+ tapStatement: selectedPlace?.statement,
+ tapNormsAndRules: selectedPlace?.norms_rules
});
}
@@ -213,24 +214,26 @@ class SelectedTap extends React.Component {
{isMobile && (
- this.toggleInfoWindow(true)}
- onClose={() => this.toggleInfoWindow(false)}
- PaperProps={{ square: false }}
- >
- this.toggleInfoWindow(true)}
+ onClose={() => this.toggleInfoWindow(false)}
+ PaperProps={{ square: false }}
>
-
-
-
+ >
+
+
+
+ )}
)}
{!isMobile && (
@@ -287,11 +290,11 @@ class SelectedTap extends React.Component {
{this.props.phlaskType === PHLASK_TYPE_WATER ? (
) : (
- this.props.selectedPlace.infoIcon
+ this.props.selectedPlace?.infoIcon
)}
diff --git a/src/components/Toolbar/Toolbar.js b/src/components/Toolbar/Toolbar.js
index 876002b3..5d419051 100644
--- a/src/components/Toolbar/Toolbar.js
+++ b/src/components/Toolbar/Toolbar.js
@@ -7,6 +7,7 @@ import {
PHLASK_TYPE_FORAGING,
PHLASK_TYPE_BATHROOM,
setMapCenter,
+ setUserLocation,
setSelectedPlace,
toggleInfoWindow,
togglePhlaskType,
@@ -16,6 +17,7 @@ import FoodFilter from '../FoodFilter/FoodFilter';
import phlaskImg from '../images/PHLASK Button.png';
import Filter from '../ResourceMenu/Filter';
import styles from './Toolbar.module.scss';
+import ClosestTap from '../ClosestTap/ClosestTap';
import { isMobile } from 'react-device-detect';
import AddResourceModalV2 from '../AddResourceModal/AddResourceModalV2';
@@ -56,24 +58,29 @@ function distance(lat1, lon1, lat2, lon2) {
// Takes an array of objects with lat and lon properties as well as a single object with lat and lon
// properties and finds the closest point (by shortest distance).
-function getClosest(data, userLocation) {
- var distances = data.map((org, index) => {
- return {
- lat: org['lat'],
- lon: org['lon'],
- organization: org['organization'],
- address: org['address'],
- distance: distance(
- userLocation['lat'],
- userLocation['lon'],
- org['lat'],
- org['lon']
- ),
- id: index
- };
- });
- var minDistance = Math.min(...distances.map(d => d.distance));
+//looping through data to get list of locations
+ function getClosest(data, userLocation) {
+ var distances = data.map((org, index) => {
+ //i added this terniary
+ if(org?.lat && org?.lon){
+ return {
+ lat: org['lat'],
+ lon: org['lon'],
+ organization: org['organization'],
+ address: org['address'],
+ distance: distance(
+ userLocation['lat'],
+ userLocation['lon'],
+ org['lat'],
+ org['lon']
+ ),
+ id: index
+ };
+ }
+ }).filter(Boolean)
+
+ var minDistance = Math.min(...distances.map(d => d.distance));
var closestTap = {
organization: '',
address: '',
@@ -91,21 +98,26 @@ function getClosest(data, userLocation) {
closestTap.id = distances[i].id;
}
}
-
return closestTap;
+
}
+
+
function getCoordinates() {
return new Promise(function (resolve, reject) {
navigator.geolocation.getCurrentPosition(resolve, reject);
});
}
+
function Toolbar(props) {
const [value, setValue] = React.useState(0);
const [openResourceModal, setOpenResourceModal] = React.useState(false);
const phlaskType = useSelector(phlaskTypeSelector);
-
+ const dispatch = useDispatch();
+ const property_name = useSelector(state => state)
+
const selectedResourceIcon = {
[PHLASK_TYPE_WATER]: WaterIcon,
[PHLASK_TYPE_FOOD]: FoodIcon,
@@ -129,18 +141,38 @@ function Toolbar(props) {
});
}
- function setClosest() {
- const data =
- props.phlaskType === PHLASK_TYPE_WATER
- ? props.allTaps
- : props.allFoodOrgs;
+ async function setClosest() {
+ // If the user clicks very fast, it crashes.
+ // NOTE: This was left as an acceptable scenario for now,
+ // as it is difficult for a user to do this reliably due to the popup of the location panel.
+ // This may be reproducible on Desktop.
+ let data;
+ switch (props.phlaskType){
+ case (PHLASK_TYPE_WATER):
+ data = props?.allTaps;
+ break;
+ case (PHLASK_TYPE_FOOD):
+ data = props?.allFoodOrgs
+ break;
+ case (PHLASK_TYPE_FORAGING):
+ data = props?.allForagingTaps;
+ break;
+ case (PHLASK_TYPE_BATHROOM):
+ data = props?.allBathroomTaps;
+ break;
+ default:
+ data = props?.allTaps
+ }
+
const closest = getClosest(data, {
lat: props.userLocation.lat,
lon: props.userLocation.lng
});
+
const place = new Promise(() => {
props.setSelectedPlace(closest.id);
});
+
place
.then(
props.setMapCenter({
@@ -151,6 +183,10 @@ function Toolbar(props) {
.then(props.toggleInfoWindow(true));
}
+ function closestButtonClicked(){
+ setClosest();
+ }
+
return (
<>
$
@@ -162,14 +198,15 @@ function Toolbar(props) {
>
{!isMobile && (
{props.phlaskType === PHLASK_TYPE_WATER
? 'Water Map'
@@ -255,6 +292,7 @@ function Toolbar(props) {
component={selectedResourceIcon}
sx={{ fontSize: 90 }}
inheritViewBox={true}
+ onClick={closestButtonClicked}
/>
}
/>
@@ -277,6 +315,8 @@ const mapStateToProps = state => ({
phlaskType: state.phlaskType,
allTaps: state.allTaps,
allFoodOrgs: state.allFoodOrgs,
+ allBathroomTaps: state.allBathroomTaps,
+ allForagingTaps: state.allForagingTaps,
userLocation: state.userLocation,
isResourceMenuShown: state.isResourceMenuShown
});
@@ -288,6 +328,7 @@ const mapDispatchToProps = {
setSelectedPlace,
toggleInfoWindow,
setMapCenter,
+ setUserLocation,
toggleResourceMenu
};
diff --git a/src/reducers/filterMarkers.js b/src/reducers/filterMarkers.js
index 4fca6f0a..aec2d6b9 100644
--- a/src/reducers/filterMarkers.js
+++ b/src/reducers/filterMarkers.js
@@ -32,6 +32,8 @@ const initialState = {
},
allTaps: [],
allFoodOrgs: [],
+ allBathroomTaps: [],
+ allForagingTaps: [],
selectedPlace: {},
phlaskType: actions.PHLASK_TYPE_WATER
};
@@ -97,6 +99,10 @@ export default (state = initialState, act) => {
allFoodOrgs: act.allFoodOrgs,
filteredOrgs: act.allFoodOrgs
};
+
+ case actions.GET_BATHROOM_SUCCESS:
+ return { ...state, allBathroomTaps: act.allBathroomTaps };
+
case actions.SET_FILTER_FUNCTION:
// console.log('set filter func');