Skip to content

Commit

Permalink
feat: cache elevation data in client redux slice
Browse files Browse the repository at this point in the history
  • Loading branch information
tm-ruxandra committed Jul 8, 2024
1 parent 1495280 commit faa15a9
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,10 @@
* along with this program. If not, see https://www.gnu.org/licenses/.
*/

import {useMemo, useState} from 'react';

import {Coords} from 'terraso-client-shared/types';

import {getElevation} from 'terraso-mobile-client/services';

export const useElevationData = (coords: Coords): number => {
const [siteElevationValue, setSiteElevationValue] = useState(0);

useMemo(async () => {
const elevation = await getElevation(coords.latitude, coords.longitude);
if (elevation !== undefined) {
setSiteElevationValue(elevation);
}
}, [coords]);
import {ElevationKey} from 'terraso-mobile-client/model/elevation/elevationTypes';

return siteElevationValue;
export const elevationKey = (coords: Coords): ElevationKey => {
return `(${coords.longitude.toFixed(4)}, ${coords.latitude.toFixed(4)})` as ElevationKey;
};
37 changes: 37 additions & 0 deletions dev-client/src/model/elevation/elevationHooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright © 2024 Technology Matters
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/

import {useEffect} from 'react';

import {Coords} from 'terraso-client-shared/types';

import {selectElevation} from 'terraso-mobile-client/model/elevation/elevationSelectors';
import {fetchElevation} from 'terraso-mobile-client/model/elevation/elevationSlice';
import {useDispatch, useSelector} from 'terraso-mobile-client/store';

export const useElevationData = (coords: Coords): number | undefined => {
const dispatch = useDispatch();
const elevation = useSelector(selectElevation(coords));

useEffect(() => {
if (!elevation) {
dispatch(fetchElevation(coords));
}
}, [dispatch, elevation, coords]);

return elevation?.value;
};
24 changes: 24 additions & 0 deletions dev-client/src/model/elevation/elevationSelectors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright © 2024 Technology Matters
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/

import {Coords} from 'terraso-client-shared/types';

import {elevationKey} from 'terraso-mobile-client/model/elevation/elevationFunctions';
import {AppState} from 'terraso-mobile-client/store';

export const selectElevation = (coords: Coords) => (state: AppState) =>
state.elevation.elevation[elevationKey(coords)];
File renamed without changes.
65 changes: 65 additions & 0 deletions dev-client/src/model/elevation/elevationSlice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright © 2024 Technology Matters
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/

import {createAsyncThunk, createSlice} from '@reduxjs/toolkit';

import {Coords} from 'terraso-client-shared/types';

import {elevationKey} from 'terraso-mobile-client/model/elevation/elevationFunctions';
import {getElevation} from 'terraso-mobile-client/model/elevation/elevationService';
import {
ElevationKey,
ElevationRecord,
} from 'terraso-mobile-client/model/elevation/elevationTypes';

export type ElevationState = {
elevation: Record<ElevationKey, ElevationRecord>;
};

const initialState: ElevationState = {
elevation: {},
};

const {reducer} = createSlice({
name: 'elevation',
initialState,
reducers: {},
extraReducers(builder) {
builder
.addCase(fetchElevation.pending, (state, action) => {
state.elevation[elevationKey(action.meta.arg)] = {fetching: true};
})
.addCase(fetchElevation.rejected, (state, action) => {
state.elevation[elevationKey(action.meta.arg)] = {fetching: false};
})
.addCase(fetchElevation.fulfilled, (state, action) => {
state.elevation[elevationKey(action.meta.arg)] = {
fetching: false,
value: action.payload,
};
});
},
});

const fetchElevation = createAsyncThunk(
'elevation/fetchElevation',
async (coords: Coords) => {
return getElevation(coords.latitude, coords.longitude);
},
);

export {fetchElevation, reducer};
22 changes: 22 additions & 0 deletions dev-client/src/model/elevation/elevationTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright © 2024 Technology Matters
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/

export type ElevationKey = `(${number}, ${number})`;
export type ElevationRecord = {
value?: number;
fetching: boolean;
};
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import {
} from 'terraso-mobile-client/components/NativeBaseAdapters';
import {SoilIdStatusDisplay} from 'terraso-mobile-client/components/SoilIdStatusDisplay';
import {renderElevation} from 'terraso-mobile-client/components/util/site';
import {useElevationData} from 'terraso-mobile-client/hooks/useElevationData';
import {useElevationData} from 'terraso-mobile-client/model/elevation/elevationHooks';
import {getTopMatch} from 'terraso-mobile-client/model/soilId/soilIdRanking';
import {useNavigation} from 'terraso-mobile-client/navigation/hooks/useNavigation';
import {CalloutDetail} from 'terraso-mobile-client/screens/HomeScreen/components/CalloutDetail';
Expand Down
7 changes: 6 additions & 1 deletion dev-client/src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,15 @@ import createStoreFactory, {
StateFromStoreFactory,
} from 'terraso-client-shared/store/store';

import {reducer as elevationReducer} from 'terraso-mobile-client/model/elevation/elevationSlice';
import {reducer as mapReducer} from 'terraso-mobile-client/model/map/mapSlice';
import {reducer as preferencesReducer} from 'terraso-mobile-client/model/preferences/preferencesSlice';

const reducers = {map: mapReducer, preferences: preferencesReducer};
const reducers = {
map: mapReducer,
preferences: preferencesReducer,
elevation: elevationReducer,
};

export type AppState = StateFromStoreFactory<typeof createStore> &
StateFromReducersMapObject<typeof reducers>;
Expand Down

0 comments on commit faa15a9

Please sign in to comment.