diff --git a/src/components/map/Map.js b/src/components/map/Map.js deleted file mode 100644 index f033067f1..000000000 --- a/src/components/map/Map.js +++ /dev/null @@ -1,208 +0,0 @@ -import GoogleMapReact from 'google-map-react' -import { useEffect, useRef, useState } from 'react' -import { useDispatch, useSelector } from 'react-redux' - -import { updatePosition } from '../../redux/locationSlice' -import { setStreetView } from '../../redux/mapSlice' -import { useTypesById } from '../../redux/useTypesById' -import { viewChangeAndFetch } from '../../redux/viewChange' -import { bootstrapURLKeys } from '../../utils/bootstrapURLKeys' -import { useAppHistory } from '../../utils/useAppHistory' -import { useIsDesktop } from '../../utils/useBreakpoint' -import CloseStreetView from './CloseStreetView' -import Cluster from './Cluster' -import Geolocation from './Geolocation' -import Location from './Location' -import PanoramaHandler from './PanoramaHandler' -import { DraggableMapPin } from './Pins' -import Place from './Place' - -const Map = () => { - const dispatch = useDispatch() - const { getCommonName } = useTypesById() - - const { - view, - geolocation, - place, - locations, - hoveredLocationId, - clusters, - streetView: showStreetView, - } = useSelector((state) => state.map) - const { - locationId, - position, - isBeingEdited: isEditingLocation, - location: selectedLocation, - } = useSelector((state) => state.location) - const { - mapType, - mapLayers: layerTypes, - showLabels, - showBusinesses, - } = useSelector((state) => state.settings) - - //TODO not sure if selectedLocation is ever not in locations - const allLocations = - clusters.length !== 0 - ? [] - : selectedLocation - ? [...locations, selectedLocation].filter( - (loc, index, self) => - index === self.findIndex((t) => t.id === loc.id), - ) - : locations - - const history = useAppHistory() - const activeLocationId = locationId || hoveredLocationId - const editingLocationId = isEditingLocation ? locationId : null - const isAddingLocation = locationId === 'new' - const mapRef = useRef(null) - const isViewingLocation = locationId !== null && locationId !== 'new' - const mapsRef = useRef(null) - const [draggedPosition, setDraggedPosition] = useState(null) - const isDesktop = useIsDesktop() - useEffect(() => { - setDraggedPosition(isDesktop ? position : null) - }, [position, isDesktop]) - const apiIsLoaded = (map, maps) => { - mapRef.current = map - mapsRef.current = maps - } - - const closeStreetView = (event) => { - event.stopPropagation() - dispatch(setStreetView(false)) - } - - const handleGeolocationClick = () => { - dispatch( - viewChangeAndFetch({ - center: { lat: geolocation.latitude, lng: geolocation.longitude }, - zoom: Math.max(view.zoom, 15), - }), - ) - } - - const handleClusterClick = (cluster) => { - dispatch( - viewChangeAndFetch({ - center: { lat: cluster.lat, lng: cluster.lng }, - zoom: view.zoom + 1, - }), - ) - } - - const handleLocationClick = (location) => { - if (!isAddingLocation && !isEditingLocation) { - history.push({ - pathname: `/locations/${location.id}`, - state: { fromPage: '/map' }, - }) - } - } - - const handleNonspecificClick = () => { - if (isViewingLocation) { - history.push('/map') - } - } - return ( - <> - - {showStreetView && } - { - handleNonspecificClick() - event.stopPropagation() - }} - bootstrapURLKeys={bootstrapURLKeys} - options={() => ({ - mapTypeId: mapType, - disableDefaultUI: true, - tilt: 0, - // Toggle all basemap icons - // https://developers.google.com/maps/documentation/javascript/style-reference - styles: [ - { - featureType: 'poi', - elementType: 'labels.icon', - stylers: [{ visibility: showBusinesses ? 'on' : 'off' }], - }, - { - featureType: 'landscape', - elementType: 'labels.icon', - stylers: [{ visibility: showBusinesses ? 'on' : 'off' }], - }, - ], - })} - layerTypes={layerTypes} - center={view.center} - zoom={view.zoom} - onChange={(newView) => dispatch(viewChangeAndFetch(newView))} - resetBoundsOnResize - onGoogleApiLoaded={({ map, maps }) => apiIsLoaded(map, maps)} - yesIWantToUseGoogleMapApiInternals - > - {geolocation && !geolocation.loading && !geolocation.error && ( - - )} - {place && ( - - )} - {clusters.map((cluster) => ( - { - handleClusterClick(cluster) - event.stopPropagation() - }} - count={cluster.count} - lat={cluster.lat} - lng={cluster.lng} - /> - ))} - {allLocations.map((location) => ( - { - handleLocationClick(location) - event.stopPropagation() - } - : undefined - } - lat={location.lat} - lng={location.lng} - selected={location.id === activeLocationId} - editing={location.id === editingLocationId} - label={showLabels ? getCommonName(location.type_ids[0]) : undefined} - /> - ))} - {draggedPosition && ( - dispatch(updatePosition(newPosition))} - isNewLocation={editingLocationId === 'new'} - /> - )} - - - ) -} - -export default Map diff --git a/src/components/map/MapPage.js b/src/components/map/MapPage.js index f9e09e829..95a51d911 100644 --- a/src/components/map/MapPage.js +++ b/src/components/map/MapPage.js @@ -1,18 +1,31 @@ +import GoogleMapReact from 'google-map-react' +import { useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' -import { useSelector } from 'react-redux' +import { useDispatch, useSelector } from 'react-redux' import { toast } from 'react-toastify' import styled from 'styled-components/macro' import { VISIBLE_CLUSTER_ZOOM_LIMIT } from '../../constants/map' +import { updatePosition } from '../../redux/locationSlice' +import { setStreetView } from '../../redux/mapSlice' +import { useTypesById } from '../../redux/useTypesById' +import { viewChangeAndFetch } from '../../redux/viewChange' +import { bootstrapURLKeys } from '../../utils/bootstrapURLKeys' import { useAppHistory } from '../../utils/useAppHistory' import AddLocationButton from '../ui/AddLocationButton' import LoadingIndicator from '../ui/LoadingIndicator' +import CloseStreetView from './CloseStreetView' +import Cluster from './Cluster' import { ConnectedGeolocation } from './ConnectedGeolocation' -import Map from './Map' +import Geolocation from './Geolocation' +import Location from './Location' +import PanoramaHandler from './PanoramaHandler' import { AddLocationCentralUnmovablePin, + DraggableMapPin, EditLocationCentralUnmovablePin, } from './Pins' +import Place from './Place' import TrackLocationButton from './TrackLocationButton' const BottomLeftLoadingIndicator = styled(LoadingIndicator)` @@ -24,14 +37,99 @@ const BottomLeftLoadingIndicator = styled(LoadingIndicator)` const MapPage = ({ isDesktop }) => { const { t } = useTranslation() const history = useAppHistory() + const dispatch = useDispatch() + const { getCommonName } = useTypesById() + + const mapRef = useRef(null) + const mapsRef = useRef(null) + const [draggedPosition, setDraggedPosition] = useState(null) + + const { + view, + geolocation, + place, + locations, + hoveredLocationId, + clusters, + streetView: showStreetView, + locationRequested, + } = useSelector((state) => state.map) const { locationId, - isLoading: locationIsLoading, + position, isBeingEdited: isEditingLocation, + location: selectedLocation, + isLoading: locationIsLoading, } = useSelector((state) => state.location) + const { + mapType, + mapLayers: layerTypes, + showLabels, + showBusinesses, + } = useSelector((state) => state.settings) + + const allLocations = + clusters.length !== 0 + ? [] + : selectedLocation + ? [...locations, selectedLocation].filter( + (loc, index, self) => + index === self.findIndex((t) => t.id === loc.id), + ) + : locations + + const activeLocationId = locationId || hoveredLocationId + const editingLocationId = isEditingLocation ? locationId : null const isAddingLocation = locationId === 'new' + const isViewingLocation = locationId !== null && locationId !== 'new' + + useEffect(() => { + setDraggedPosition(isDesktop ? position : null) + }, [position, isDesktop]) + + const apiIsLoaded = (map, maps) => { + mapRef.current = map + mapsRef.current = maps + } + + const closeStreetView = (event) => { + event.stopPropagation() + dispatch(setStreetView(false)) + } - const { view, locationRequested } = useSelector((state) => state.map) + const handleGeolocationClick = () => { + dispatch( + viewChangeAndFetch({ + center: { lat: geolocation.latitude, lng: geolocation.longitude }, + zoom: Math.max(view.zoom, 15), + }), + ) + } + + const handleClusterClick = (cluster) => { + dispatch( + viewChangeAndFetch({ + center: { lat: cluster.lat, lng: cluster.lng }, + zoom: view.zoom + 1, + }), + ) + } + + const handleLocationClick = (location) => { + if (!isAddingLocation && !isEditingLocation) { + history.push({ + pathname: `/locations/${location.id}`, + state: { fromPage: '/map' }, + }) + } + } + + const handleNonspecificClick = ({ event }) => { + event.stopPropagation() + if (isViewingLocation) { + history.push('/map') + } + } const handleAddLocationClick = () => { if (view.zoom >= VISIBLE_CLUSTER_ZOOM_LIMIT) { @@ -45,7 +143,6 @@ const MapPage = ({ isDesktop }) => { } return (
{ {locationRequested && } - {view && } + + {showStreetView && } + {view && ( + ({ + mapTypeId: mapType, + disableDefaultUI: true, + tilt: 0, + // Toggle all basemap icons + // https://developers.google.com/maps/documentation/javascript/style-reference + styles: [ + { + featureType: 'poi', + elementType: 'labels.icon', + stylers: [{ visibility: showBusinesses ? 'on' : 'off' }], + }, + { + featureType: 'landscape', + elementType: 'labels.icon', + stylers: [{ visibility: showBusinesses ? 'on' : 'off' }], + }, + ], + })} + layerTypes={layerTypes} + center={view.center} + zoom={view.zoom} + onChange={(newView) => dispatch(viewChangeAndFetch(newView))} + resetBoundsOnResize + onGoogleApiLoaded={({ map, maps }) => apiIsLoaded(map, maps)} + yesIWantToUseGoogleMapApiInternals + > + {geolocation && !geolocation.loading && !geolocation.error && ( + + )} + {place && ( + + )} + {clusters.map((cluster) => ( + { + handleClusterClick(cluster) + event.stopPropagation() + }} + count={cluster.count} + lat={cluster.lat} + lng={cluster.lng} + /> + ))} + {allLocations.map((location) => ( + { + handleLocationClick(location) + event.stopPropagation() + } + : undefined + } + lat={location.lat} + lng={location.lng} + selected={location.id === activeLocationId} + editing={location.id === editingLocationId} + label={ + showLabels ? getCommonName(location.type_ids[0]) : undefined + } + /> + ))} + {draggedPosition && ( + dispatch(updatePosition(newPosition))} + isNewLocation={editingLocationId === 'new'} + /> + )} + + )}
) }