Skip to content

Commit

Permalink
use maps API when fetching locations
Browse files Browse the repository at this point in the history
Include a separate fetch after map has loaded
  • Loading branch information
wbazant committed Jul 19, 2024
1 parent d77484b commit 90a700f
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 58 deletions.
5 changes: 4 additions & 1 deletion src/components/map/MapPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import {
MIN_GEOLOCATION_ZOOM,
VISIBLE_CLUSTER_ZOOM_LIMIT,
} from '../../constants/map'
import { fetchFilterCounts } from '../../redux/filterSlice'
import { updatePosition } from '../../redux/locationSlice'
import { setGoogle } from '../../redux/mapSlice'
import { useTypesById } from '../../redux/useTypesById'
import { viewChangeAndFetch } from '../../redux/viewChange'
import { fetchLocations, viewChangeAndFetch } from '../../redux/viewChange'
import { bootstrapURLKeys } from '../../utils/bootstrapURLKeys'
import { useAppHistory } from '../../utils/useAppHistory'
import AddLocationButton from '../ui/AddLocationButton'
Expand Down Expand Up @@ -123,6 +124,8 @@ const MapPage = ({ isDesktop }) => {
* Something breaks when storing maps in redux so pass a reference to it
*/
dispatch(setGoogle({ googleMap: map, getGoogleMaps: () => maps }))
dispatch(fetchLocations())
dispatch(fetchFilterCounts())
}

const handleClusterClick = (cluster) => {
Expand Down
29 changes: 3 additions & 26 deletions src/redux/listSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'

import { getLocations, getLocationsCount } from '../utils/api'
import { setView } from './mapSlice'
import { selectPlace } from './placeSlice'
import { selectParams } from './selectParams'
import { updateSelection } from './updateSelection'

Expand Down Expand Up @@ -30,32 +29,12 @@ export const listSlice = createSlice({
isLoading: false,
totalCount: null,
offset: 0,
view: null, // Represents what view is used for the list
isViewSearched: false,
shouldFetchNewLocations: false,
updateOnMapMove: true,
shouldFetchNewLocations: true,
locations: [],
},
reducers: {
setUpdateOnMapMove: (state, action) => {
state.updateOnMapMove = action.payload
},
clearListLocations: (state) => {
state.locations = []
},
},
extraReducers: {
[setView.type]: (state, action) => {
if (state.updateOnMapMove || state.isViewSearched) {
// If updateOnMapMove flag/checkbox is unchecked, then the list view is only updated when a new location is "searched"
state.view = action.payload
state.shouldFetchNewLocations = true
}
state.isViewSearched = false
},

[selectPlace]: (state) => {
state.isViewSearched = true
[setView.type]: (state) => {
state.shouldFetchNewLocations = true
},

[fetchListLocations.pending]: (state) => {
Expand Down Expand Up @@ -85,6 +64,4 @@ export const listSlice = createSlice({
},
})

export const { setUpdateOnMapMove, clearListLocations } = listSlice.actions

export default listSlice.reducer
33 changes: 24 additions & 9 deletions src/redux/mapSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,31 @@ export const updateReducer = (key) => (state, action) => ({

export const fetchMapLocations = createAsyncThunk(
'map/fetchMapLocations',
async (_, { getState }) =>
await getLocations(selectParams(getState(), { limit: 250 })),
async (_, { getState }) => {
const state = getState()
const googleMap = state.map.googleMap
if (googleMap) {
return await getLocations(selectParams(getState(), { limit: 250 }))
} else {
return []
}
},
)

export const fetchMapClusters = createAsyncThunk(
'map/fetchMapClusters',
async (_, { getState }) => {
const state = getState()
return await getClusters(
selectParams(state, {
zoom: state.map.view?.zoom ? state.map.view.zoom + 1 : null,
}),
)
const googleMap = state.map.googleMap
if (googleMap) {
return await getClusters(
selectParams(state, {
zoom: googleMap.getZoom() + 1,
}),
)
} else {
return []
}
},
)

Expand Down Expand Up @@ -64,7 +76,10 @@ export const mapSlice = createSlice({
state.isLoading = true
},
[fetchMapLocations.fulfilled]: (state, action) => {
const { ne, sw } = state.view.bounds
if (!state.googleMap) {
return
}
const { north, east, south, west } = state.googleMap.getBounds().toJSON()

if (state.isFilterUpdated) {
state.locations = action.payload
Expand All @@ -73,7 +88,7 @@ export const mapSlice = createSlice({
// Drop locations out of bounds
const locationsInBounds = state.locations.filter(
({ lat, lng }) =>
lat <= ne.lat && lng <= ne.lng && lat >= sw.lat && lng >= sw.lng,
lat <= north && lng <= east && lat >= south && lng >= west,
)
// Combine with new locations in bounds
// If IDs are equal, prioritise the payload
Expand Down
18 changes: 11 additions & 7 deletions src/redux/selectParams.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,29 @@ const normalizeLongitude = (longitude) => {
}

const convertBounds = (bounds) => ({
bounds: `${bounds.sw.lat},${normalizeLongitude(bounds.sw.lng)}|${
bounds.ne.lat
},${normalizeLongitude(bounds.ne.lng)}`,
bounds: `${bounds.south},${normalizeLongitude(bounds.west)}|${
bounds.north
},${normalizeLongitude(bounds.east)}`,
})

const convertCenter = (center) => ({
center: `${center.lat},${center.lng}`,
})

export const selectParams = (state, extraParams = {}, isMap = true) => {
export const selectParams = (state, extraParams = {}) => {
const { types, muni, invasive } = state.filter
const { view } = isMap ? state.map : state.list
const { googleMap } = state.map
const bounds = googleMap.getBounds().toJSON()
const zoom = googleMap.getZoom()
const center = googleMap.getCenter().toJSON()

const params = {
types: types && types.join(','),
muni,
invasive,
...convertBounds(view.bounds),
...(!isMap && convertCenter(view.center)),
zoom,
...convertBounds(bounds),
...convertCenter(center),
...extraParams,
}

Expand Down
29 changes: 14 additions & 15 deletions src/redux/viewChange.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,23 @@ import { VISIBLE_CLUSTER_ZOOM_LIMIT } from '../constants/map'
import { currentPathWithView } from '../utils/appUrl'
import { fetchFilterCounts } from './filterSlice'
import { disableGeolocation } from './geolocationSlice'
import { clearListLocations } from './listSlice'
import { fetchMapClusters, fetchMapLocations, setView } from './mapSlice'

export const getIsShowingClusters = (state) =>
state.map.view.zoom <= VISIBLE_CLUSTER_ZOOM_LIMIT
export const getIsShowingClusters = (state) => {
const map = state.map.googleMap
if (map) {
return map.getZoom() <= VISIBLE_CLUSTER_ZOOM_LIMIT
} else {
return false
}
}

export const fetchLocations = () => (dispatch, getState) => {
const state = getState()
const { zoom, bounds } = state.map.view

if (bounds?.ne.lat != null && zoom > 1) {
// Map has received real bounds

if (getIsShowingClusters(state)) {
dispatch(fetchMapClusters())
dispatch(clearListLocations())
} else {
dispatch(fetchMapLocations())
}
if (getIsShowingClusters(state)) {
dispatch(fetchMapClusters())
} else {
dispatch(fetchMapLocations())
}
}

Expand Down Expand Up @@ -73,7 +71,8 @@ export const viewChangeAndFetch = (newView) => (dispatch, getState) => {
}

dispatch(setView(newView))
dispatch(fetchLocations()) // TODO: don't fetch new locations if is adding location

dispatch(fetchLocations())

if (state.filter.isOpen || state.misc.isDesktop) {
dispatch(fetchFilterCounts())
Expand Down

0 comments on commit 90a700f

Please sign in to comment.