diff --git a/src/components/Explore/Modals/FilterModal.tsx b/src/components/Explore/Modals/FilterModal.tsx index a86420dc5..e213acfdd 100644 --- a/src/components/Explore/Modals/FilterModal.tsx +++ b/src/components/Explore/Modals/FilterModal.tsx @@ -82,7 +82,7 @@ const FilterModal = ( { discardChanges, isNotInitialState, numberOfFilters, - setExploreLocation + defaultExploreLocation } = useExplore(); const { taxon, @@ -661,7 +661,7 @@ const FilterModal = ( { { - const exploreLocation = await setExploreLocation( ); + const exploreLocation = await defaultExploreLocation( ); dispatch( { type: EXPLORE_ACTION.RESET, exploreLocation } ); }} > diff --git a/src/components/Explore/RootExploreContainer.js b/src/components/Explore/RootExploreContainer.js index cd6f5f2eb..f634d1be0 100644 --- a/src/components/Explore/RootExploreContainer.js +++ b/src/components/Explore/RootExploreContainer.js @@ -8,7 +8,11 @@ import { useExplore } from "providers/ExploreContext.tsx"; import type { Node } from "react"; -import React, { useEffect, useState } from "react"; +import React, { + useCallback, + useEffect, + useState +} from "react"; import { useCurrentUser, useIsConnected, useTranslation } from "sharedHooks"; import useStore from "stores/useStore"; @@ -27,7 +31,7 @@ const RootExploreContainerWithContext = ( ): Node => { const worldwidePlaceText = t( "Worldwide" ); const { - state, dispatch, makeSnapshot, setExploreLocation + state, dispatch, makeSnapshot, defaultExploreLocation } = useExplore( ); const [showFiltersModal, setShowFiltersModal] = useState( false ); @@ -95,30 +99,23 @@ const RootExploreContainerWithContext = ( ): Node => { makeSnapshot( ); }; - const onPermissionGranted = async ( ) => { - if ( state.place_guess ) { return; } - const exploreLocation = await setExploreLocation( ); + const onPermissionGranted = useCallback( async ( ) => { + const exploreLocation = await defaultExploreLocation( ); dispatch( { type: EXPLORE_ACTION.SET_EXPLORE_LOCATION, exploreLocation } ); - }; + }, [ + defaultExploreLocation, + dispatch + ] ); - const onPermissionDenied = ( ) => { - if ( state.place_guess ) { return; } + const resetToWorldWide = useCallback( ( ) => { dispatch( { type: EXPLORE_ACTION.SET_PLACE, - placeGuess: t( "Worldwide" ) + placeGuess: worldwidePlaceText } ); - }; - - const onPermissionBlocked = ( ) => { - if ( state.place_guess ) { return; } - dispatch( { - type: EXPLORE_ACTION.SET_PLACE, - placeGuess: t( "Worldwide" ) - } ); - }; + }, [dispatch, worldwidePlaceText] ); useEffect( ( ) => { navigation.addListener( "focus", ( ) => { @@ -154,8 +151,8 @@ const RootExploreContainerWithContext = ( ): Node => { diff --git a/src/components/Explore/SearchScreens/ExploreLocationSearch.js b/src/components/Explore/SearchScreens/ExploreLocationSearch.js index a128e4310..7ee9a9e81 100644 --- a/src/components/Explore/SearchScreens/ExploreLocationSearch.js +++ b/src/components/Explore/SearchScreens/ExploreLocationSearch.js @@ -37,7 +37,7 @@ type Props = { const ExploreLocationSearch = ( { closeModal, updateLocation }: Props ): Node => { const { t } = useTranslation( ); - const { dispatch, setExploreLocation } = useExplore( ); + const { dispatch, defaultExploreLocation } = useExplore( ); const [locationName, setLocationName] = useState( "" ); const [permissionNeeded, setPermissionNeeded] = useState( false ); @@ -146,7 +146,7 @@ const ExploreLocationSearch = ( { closeModal, updateLocation }: Props ): Node => withoutNavigation onPermissionGranted={async ( ) => { setPermissionNeeded( false ); - const exploreLocation = await setExploreLocation( ); + const exploreLocation = await defaultExploreLocation( ); dispatch( { type: EXPLORE_ACTION.SET_EXPLORE_LOCATION, exploreLocation } ); closeModal(); }} diff --git a/src/components/Explore/hooks/useMapLocation.js b/src/components/Explore/hooks/useMapLocation.js index 9da564433..1df109af6 100644 --- a/src/components/Explore/hooks/useMapLocation.js +++ b/src/components/Explore/hooks/useMapLocation.js @@ -50,13 +50,11 @@ const useMapLocation = ( ): Object => { }; setMapBoundaries( boundaryAPIParams ); - logger.info( "setting map region based on user pan/zoom" ); setMapRegion( newRegion ); return boundaryAPIParams; }, [t, setMapBoundaries, setMapRegion] ); const redoSearchInMapArea = ( ) => { - logger.info( "searching for observations with map boundaries: ", mapBoundaries ); setShowMapBoundaryButton( false ); dispatch( { type: EXPLORE_ACTION.SET_MAP_BOUNDARIES, mapBoundaries } ); }; diff --git a/src/components/Explore/hooks/useParams.js b/src/components/Explore/hooks/useParams.js index dc390f740..5950cd0d9 100644 --- a/src/components/Explore/hooks/useParams.js +++ b/src/components/Explore/hooks/useParams.js @@ -12,7 +12,7 @@ import useStore from "stores/useStore"; const useParams = ( ): Object => { const { t } = useTranslation( ); const { params } = useRoute( ); - const { dispatch, setExploreLocation } = useExplore( ); + const { dispatch, defaultExploreLocation } = useExplore( ); const storedParams = useStore( state => state.storedParams ); const worldwidePlaceText = t( "Worldwide" ); @@ -32,7 +32,7 @@ const useParams = ( ): Object => { setWorldwide( ); } if ( params?.nearby ) { - const exploreLocation = await setExploreLocation( ); + const exploreLocation = await defaultExploreLocation( ); dispatch( { type: EXPLORE_ACTION.SET_EXPLORE_LOCATION, exploreLocation @@ -75,7 +75,7 @@ const useParams = ( ): Object => { }, [ dispatch, params, - setExploreLocation, + defaultExploreLocation, worldwidePlaceText ] ); diff --git a/src/providers/ExploreContext.tsx b/src/providers/ExploreContext.tsx index f676179c1..eede834fc 100644 --- a/src/providers/ExploreContext.tsx +++ b/src/providers/ExploreContext.tsx @@ -6,34 +6,34 @@ import { LatLng } from "react-native-maps"; import fetchUserLocation from "sharedHelpers/fetchUserLocation"; export enum EXPLORE_ACTION { + CHANGE_SORT_BY = "CHANGE_SORT_BY", + CHANGE_TAXON = "CHANGE_TAXON", DISCARD = "DISCARD", RESET = "RESET", - CHANGE_TAXON = "CHANGE_TAXON", - SET_TAXON_NAME = "SET_TAXON_NAME", - SET_EXPLORE_LOCATION = "SET_EXPLORE_LOCATION", - SET_PLACE = "SET_PLACE", - SET_USER = "SET_USER", - SET_PROJECT = "SET_PROJECT", - CHANGE_SORT_BY = "CHANGE_SORT_BY", - TOGGLE_RESEARCH_GRADE = "TOGGLE_RESEARCH_GRADE", - TOGGLE_NEEDS_ID = "TOGGLE_NEEDS_ID", - TOGGLE_CASUAL = "TOGGLE_CASUAL", - SET_HIGHEST_TAXONOMIC_RANK = "SET_HIGHEST_TAXONOMIC_RANK", - SET_LOWEST_TAXONOMIC_RANK = "SET_LOWEST_TAXONOMIC_RANK", - SET_DATE_OBSERVED_MONTHS = "SET_DATE_OBSERVED_MONTHS", - SET_DATE_OBSERVED_EXACT = "SET_DATE_OBSERVED_EXACT", - SET_DATE_OBSERVED_RANGE = "SET_DATE_OBSERVED_RANGE", SET_DATE_OBSERVED_ALL = "SET_DATE_OBSERVED_ALL", + SET_DATE_OBSERVED_EXACT = "SET_DATE_OBSERVED_EXACT", + SET_DATE_OBSERVED_MONTHS = "SET_DATE_OBSERVED_MONTHS", + SET_DATE_OBSERVED_RANGE = "SET_DATE_OBSERVED_RANGE", + SET_DATE_UPLOADED_ALL = "SET_DATE_UPLOADED_ALL", SET_DATE_UPLOADED_EXACT = "SET_DATE_UPLOADED_EXACT", SET_DATE_UPLOADED_RANGE = "SET_DATE_UPLOADED_RANGE", - SET_DATE_UPLOADED_ALL = "SET_DATE_UPLOADED_ALL", - SET_MEDIA = "SET_MEDIA", SET_ESTABLISHMENT_MEAN = "SET_ESTABLISHMENT_MEAN", - SET_WILD_STATUS = "SET_WILD_STATUS", - SET_REVIEWED = "SET_REVIEWED", - SET_PHOTO_LICENSE = "SET_PHOTO_LICENSE", + SET_EXPLORE_LOCATION = "SET_EXPLORE_LOCATION", + SET_HIGHEST_TAXONOMIC_RANK = "SET_HIGHEST_TAXONOMIC_RANK", + SET_LOWEST_TAXONOMIC_RANK = "SET_LOWEST_TAXONOMIC_RANK", SET_MAP_BOUNDARIES = "SET_MAP_BOUNDARIES", - USE_STORED_STATE = "USE_STORED_STATE", + SET_MEDIA = "SET_MEDIA", + SET_PHOTO_LICENSE = "SET_PHOTO_LICENSE", + SET_PLACE = "SET_PLACE", + SET_PROJECT = "SET_PROJECT", + SET_REVIEWED = "SET_REVIEWED", + SET_TAXON_NAME = "SET_TAXON_NAME", + SET_USER = "SET_USER", + SET_WILD_STATUS = "SET_WILD_STATUS", + TOGGLE_CASUAL = "TOGGLE_CASUAL", + TOGGLE_NEEDS_ID = "TOGGLE_NEEDS_ID", + TOGGLE_RESEARCH_GRADE = "TOGGLE_RESEARCH_GRADE", + USE_STORED_STATE = "USE_STORED_STATE" } export enum SORT_BY { @@ -293,7 +293,7 @@ function isValidDateFormat( date: string ): boolean { return regex.test( date ); } -async function setExploreLocation( ) { +async function defaultExploreLocation( ) { const location = await fetchUserLocation( ); if ( !location || !location.latitude ) { return { @@ -496,14 +496,17 @@ function exploreReducer( state: State, action: Action ) { ...state, reviewedFilter: action.reviewedFilter }; - case EXPLORE_ACTION.SET_MAP_BOUNDARIES: - // eslint-disable-next-line no-case-declarations - const boundState = { + case EXPLORE_ACTION.SET_MAP_BOUNDARIES: { + const newState = { ...state, ...action.mapBoundaries }; - delete boundState.place_id; - return boundState; + delete newState.place_id; + delete newState.lat; + delete newState.lng; + delete newState.radius; + return newState; + } case EXPLORE_ACTION.USE_STORED_STATE: return { ...action.storedState @@ -559,7 +562,7 @@ const ExploreProvider = ( { children }: ExploreProviderProps ) => { const value = { state, dispatch, - setExploreLocation, + defaultExploreLocation, isNotInitialState, numberOfFilters, makeSnapshot, @@ -579,4 +582,8 @@ function useExplore() { return context; } -export { ExploreProvider, useExplore }; +export { + ExploreProvider, + exploreReducer, + useExplore +}; diff --git a/tests/unit/providers/ExploreContext.test.js b/tests/unit/providers/ExploreContext.test.js new file mode 100644 index 000000000..d70208fe8 --- /dev/null +++ b/tests/unit/providers/ExploreContext.test.js @@ -0,0 +1,44 @@ +import { + EXPLORE_ACTION, + exploreReducer +} from "providers/ExploreContext.tsx"; +import factory from "tests/factory"; + +describe( "ExploreContext", ( ) => { + describe( "exploreReducer", ( ) => { + describe( EXPLORE_ACTION.SET_PLACE, ( ) => { + it( "should remove lat and lng when place set", ( ) => { + const initialState = { lat: 1, lng: 1 }; + const reducedState = exploreReducer( initialState, { + type: EXPLORE_ACTION.SET_PLACE, + place: factory( "RemotePlace" ) + } ); + expect( initialState.lat ).not.toBeUndefined( ); + expect( initialState.lng ).not.toBeUndefined( ); + expect( reducedState.lat ).toBeUndefined( ); + expect( reducedState.lng ).toBeUndefined( ); + } ); + } ); + describe( EXPLORE_ACTION.SET_MAP_BOUNDARIES, ( ) => { + it( "should remove lat, lng, and radius", ( ) => { + const initialState = { lat: 1, lng: 1, radius: 50 }; + const reducedState = exploreReducer( initialState, { + type: EXPLORE_ACTION.SET_MAP_BOUNDARIES, + mapBoundaries: { + swlat: 0, + swlng: 0, + nelat: 1, + nelng: 1, + place_guess: "somwhere" + } + } ); + expect( initialState.lat ).not.toBeUndefined( ); + expect( initialState.lng ).not.toBeUndefined( ); + expect( initialState.radius ).not.toBeUndefined( ); + expect( reducedState.lat ).toBeUndefined( ); + expect( reducedState.lng ).toBeUndefined( ); + expect( reducedState.radius ).toBeUndefined( ); + } ); + } ); + } ); +} );