From 590e953ae64d37dd1ed8df35d9b935fa7b501473 Mon Sep 17 00:00:00 2001 From: shrouxm Date: Wed, 3 Jul 2024 17:09:32 -0700 Subject: [PATCH 1/7] feat: improve UX of location permission requests --- dev-client/package-lock.json | 9 +++++ dev-client/package.json | 1 + dev-client/src/App.tsx | 9 ----- .../src/native/checkAndroidPermissions.ts | 40 ------------------- .../src/screens/HomeScreen/HomeScreen.tsx | 10 +++++ .../HomeScreen/components/MapSearch.tsx | 27 +++++++++---- 6 files changed, 39 insertions(+), 57 deletions(-) delete mode 100644 dev-client/src/native/checkAndroidPermissions.ts diff --git a/dev-client/package-lock.json b/dev-client/package-lock.json index 49b928f49..49a8ace33 100644 --- a/dev-client/package-lock.json +++ b/dev-client/package-lock.json @@ -30,6 +30,7 @@ "expo-dev-client": "~4.0.19", "expo-image-manipulator": "~12.0.5", "expo-image-picker": "~15.0.7", + "expo-location": "~17.0.1", "expo-media-library": "~16.0.4", "expo-screen-orientation": "~7.0.5", "expo-sensors": "~13.0.9", @@ -14512,6 +14513,14 @@ "invariant": "^2.2.4" } }, + "node_modules/expo-location": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/expo-location/-/expo-location-17.0.1.tgz", + "integrity": "sha512-m+OzotzlAXO3ZZ1uqW5GC25nXW868zN+ROyBA1V4VF6jGay1ZEs4URPglCVUDzZby2F5wt24cMzqDKw2IX6nRw==", + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-manifests": { "version": "0.14.3", "resolved": "https://registry.npmjs.org/expo-manifests/-/expo-manifests-0.14.3.tgz", diff --git a/dev-client/package.json b/dev-client/package.json index aaeb1e47d..1cd351c16 100644 --- a/dev-client/package.json +++ b/dev-client/package.json @@ -39,6 +39,7 @@ "expo-dev-client": "~4.0.19", "expo-image-manipulator": "~12.0.5", "expo-image-picker": "~15.0.7", + "expo-location": "~17.0.1", "expo-media-library": "~16.0.4", "expo-screen-orientation": "~7.0.5", "expo-sensors": "~13.0.9", diff --git a/dev-client/src/App.tsx b/dev-client/src/App.tsx index b4d11b347..2dbe17b14 100644 --- a/dev-client/src/App.tsx +++ b/dev-client/src/App.tsx @@ -48,7 +48,6 @@ import {APP_CONFIG} from 'terraso-mobile-client/config'; import {GeospatialProvider} from 'terraso-mobile-client/context/GeospatialContext'; import {HeaderHeightContext} from 'terraso-mobile-client/context/HeaderHeightContext'; import {HomeScreenContextProvider} from 'terraso-mobile-client/context/HomeScreenContext'; -import {checkAndroidPermissions} from 'terraso-mobile-client/native/checkAndroidPermissions'; import {RootNavigator} from 'terraso-mobile-client/navigation/navigators/RootNavigator'; import {Toasts} from 'terraso-mobile-client/screens/Toasts'; import {createStore} from 'terraso-mobile-client/store'; @@ -75,14 +74,6 @@ LogBox.ignoreLogs([ const store = createStore(); function App(): React.JSX.Element { - useEffect(() => - checkAndroidPermissions( - PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, - ), - ); - - const [headerHeight, setHeaderHeight] = useState(0); - return ( diff --git a/dev-client/src/native/checkAndroidPermissions.ts b/dev-client/src/native/checkAndroidPermissions.ts deleted file mode 100644 index 013c9c794..000000000 --- a/dev-client/src/native/checkAndroidPermissions.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright © 2023 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 {Permission, PermissionsAndroid, Platform} from 'react-native'; - -// Android requires user to approve certain key permissions manually -// see documentation: https://reactnative.dev/docs/permissionsandroid -export function checkAndroidPermissions(permission: Permission) { - if (Platform.OS !== 'android') { - return; - } - - PermissionsAndroid.request(permission) - .then(granted => { - if (granted) { - console.log(permission, 'granted'); - } else { - // TODO: What to do on rejection - console.log(permission, 'rejected'); - } - }) - .catch(err => { - // TODO: What to do on error? - console.error(err); - }); -} diff --git a/dev-client/src/screens/HomeScreen/HomeScreen.tsx b/dev-client/src/screens/HomeScreen/HomeScreen.tsx index 08cb64553..b281c82fd 100644 --- a/dev-client/src/screens/HomeScreen/HomeScreen.tsx +++ b/dev-client/src/screens/HomeScreen/HomeScreen.tsx @@ -26,6 +26,8 @@ import { useState, } from 'react'; +import {useForegroundPermissions} from 'expo-location'; + import BottomSheet, {BottomSheetModal} from '@gorhom/bottom-sheet'; import Mapbox from '@rnmapbox/maps'; @@ -58,6 +60,14 @@ import {ScreenScaffold} from 'terraso-mobile-client/screens/ScreenScaffold'; import {useDispatch, useSelector} from 'terraso-mobile-client/store'; export const HomeScreen = memo(() => { + const [locationPermission, requestLocationPermission] = + useForegroundPermissions(); + useEffect(() => { + if (!locationPermission?.granted) { + requestLocationPermission(); + } + }, []); + const infoBottomSheetRef = useRef(null); const siteListBottomSheetRef = useRef(null); const [mapStyleURL, setMapStyleURL] = useState(Mapbox.StyleURL.Street); diff --git a/dev-client/src/screens/HomeScreen/components/MapSearch.tsx b/dev-client/src/screens/HomeScreen/components/MapSearch.tsx index 4b59bb6f4..fb1015861 100644 --- a/dev-client/src/screens/HomeScreen/components/MapSearch.tsx +++ b/dev-client/src/screens/HomeScreen/components/MapSearch.tsx @@ -21,12 +21,15 @@ import {Keyboard} from 'react-native'; import Autocomplete from 'react-native-autocomplete-input'; import {Searchbar} from 'react-native-paper'; +import {useForegroundPermissions} from 'expo-location'; + import {Pressable} from 'native-base'; import {Coords} from 'terraso-client-shared/types'; import {IconButton} from 'terraso-mobile-client/components/icons/IconButton'; import {searchBarStyles} from 'terraso-mobile-client/components/ListFilter'; +import {PermissionsRequestModal} from 'terraso-mobile-client/components/modals/PermissionsRequestModal'; import { Box, Column, @@ -211,14 +214,22 @@ export default function MapSearch({zoomTo, zoomToUser, toggleMapLayer}: Props) { padding={2} onPress={toggleMapLayer} /> - + + {onRequest => ( + + )} + From d7c0b81eaae0da396abed62024c62bbe3b6452b9 Mon Sep 17 00:00:00 2001 From: Paul Schreiber Date: Fri, 5 Jul 2024 09:40:57 -0400 Subject: [PATCH 2/7] fix: remove unused imports --- dev-client/src/App.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dev-client/src/App.tsx b/dev-client/src/App.tsx index 2dbe17b14..bc750592b 100644 --- a/dev-client/src/App.tsx +++ b/dev-client/src/App.tsx @@ -25,8 +25,7 @@ // react-native-get-random-values needed for uuid - https://github.com/uuidjs/uuid#react-native--expo import 'react-native-get-random-values'; -import {useEffect, useState} from 'react'; -import {LogBox, PermissionsAndroid} from 'react-native'; +import {LogBox} from 'react-native'; import {GestureHandlerRootView} from 'react-native-gesture-handler'; import {Provider} from 'react-redux'; From cff4922bc40d0d0db08d5f38a416af3d98e76588 Mon Sep 17 00:00:00 2001 From: shrouxm Date: Wed, 10 Jul 2024 13:21:23 -0700 Subject: [PATCH 3/7] feat: add translation strings --- dev-client/src/translations/en.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dev-client/src/translations/en.json b/dev-client/src/translations/en.json index 5821c588d..701108606 100644 --- a/dev-client/src/translations/en.json +++ b/dev-client/src/translations/en.json @@ -451,7 +451,9 @@ "camera_title": "LandPKS Soil ID needs to access your camera", "camera_body": "To use {{feature}}, grant LandPKS Soil ID access to your camera in device settings.", "gallery_title": "LandPKS Soil ID needs to access your photo gallery", - "gallery_body": "To use {{feature}}, grant LandPKS Soil ID access to your photo gallery in device settings." + "gallery_body": "To use {{feature}}, grant LandPKS Soil ID access to your photo gallery in device settings.", + "location_title": "LandPKS Soil ID needs to access your location", + "location_body": "For the best map experience, grant LandPKS Soil ID access to your location in device settings." }, "errors": { "generic": "Error saving soil ID information." From 863aa365831ada4b6dabad7cbfff8418ca097521 Mon Sep 17 00:00:00 2001 From: shrouxm Date: Wed, 10 Jul 2024 14:09:09 -0700 Subject: [PATCH 4/7] chore: disable spurious lint warning --- dev-client/src/screens/HomeScreen/HomeScreen.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev-client/src/screens/HomeScreen/HomeScreen.tsx b/dev-client/src/screens/HomeScreen/HomeScreen.tsx index b281c82fd..0d1394c3a 100644 --- a/dev-client/src/screens/HomeScreen/HomeScreen.tsx +++ b/dev-client/src/screens/HomeScreen/HomeScreen.tsx @@ -66,6 +66,8 @@ export const HomeScreen = memo(() => { if (!locationPermission?.granted) { requestLocationPermission(); } + // disable depcheck because we only want to run on mount + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const infoBottomSheetRef = useRef(null); From 42f093b9757db50c3392d597a07b1b580bfc8a89 Mon Sep 17 00:00:00 2001 From: Paul Schreiber Date: Wed, 10 Jul 2024 21:24:52 -0400 Subject: [PATCH 5/7] fix: restore lines lost in rebase/merge --- dev-client/src/App.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dev-client/src/App.tsx b/dev-client/src/App.tsx index bc750592b..2adf23321 100644 --- a/dev-client/src/App.tsx +++ b/dev-client/src/App.tsx @@ -36,6 +36,7 @@ import {NativeBaseProvider} from 'native-base'; import 'terraso-mobile-client/translations'; import 'terraso-mobile-client/config'; +import {useState} from 'react'; import {PaperProvider, Portal} from 'react-native-paper'; import {enableFreeze} from 'react-native-screens'; @@ -73,6 +74,8 @@ LogBox.ignoreLogs([ const store = createStore(); function App(): React.JSX.Element { + const [headerHeight, setHeaderHeight] = useState(0); + return ( From 4f4fd76d5d675d3d232d3f12a4037f471934f362 Mon Sep 17 00:00:00 2001 From: shrouxm Date: Thu, 11 Jul 2024 12:10:49 -0700 Subject: [PATCH 6/7] refactor: rename PermissionsRequest{Modal,Wrapper} --- .../components/inputs/image/ImagePicker.tsx | 26 +++++++++++-------- ...odal.tsx => PermissionsRequestWrapper.tsx} | 18 ++++++------- .../HomeScreen/components/MapSearch.tsx | 12 ++++----- .../screens/SlopeScreen/SlopeMeterScreen.tsx | 12 ++++----- 4 files changed, 36 insertions(+), 32 deletions(-) rename dev-client/src/components/modals/{PermissionsRequestModal.tsx => PermissionsRequestWrapper.tsx} (88%) diff --git a/dev-client/src/components/inputs/image/ImagePicker.tsx b/dev-client/src/components/inputs/image/ImagePicker.tsx index 7ae5e86d6..f061f4d22 100644 --- a/dev-client/src/components/inputs/image/ImagePicker.tsx +++ b/dev-client/src/components/inputs/image/ImagePicker.tsx @@ -37,7 +37,7 @@ import { ModalHandle, ModalTrigger, } from 'terraso-mobile-client/components/modals/Modal'; -import {PermissionsRequestModal} from 'terraso-mobile-client/components/modals/PermissionsRequestModal'; +import {PermissionsRequestWrapper} from 'terraso-mobile-client/components/modals/PermissionsRequestContext'; import {Column} from 'terraso-mobile-client/components/NativeBaseAdapters'; import {OverlaySheet} from 'terraso-mobile-client/components/sheets/OverlaySheet'; @@ -100,10 +100,12 @@ export const ImagePicker = ({ return ( - {onRequestAction => ( )} - + )} From b5224ec43f64b6db549a74d3455a00adc35f2b3e Mon Sep 17 00:00:00 2001 From: shrouxm Date: Thu, 11 Jul 2024 15:26:12 -0700 Subject: [PATCH 7/7] fix: types --- dev-client/src/components/inputs/image/ImagePicker.tsx | 2 +- dev-client/src/screens/HomeScreen/components/MapSearch.tsx | 2 +- dev-client/src/screens/SlopeScreen/SlopeMeterScreen.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dev-client/src/components/inputs/image/ImagePicker.tsx b/dev-client/src/components/inputs/image/ImagePicker.tsx index f061f4d22..3c39f46d6 100644 --- a/dev-client/src/components/inputs/image/ImagePicker.tsx +++ b/dev-client/src/components/inputs/image/ImagePicker.tsx @@ -37,7 +37,7 @@ import { ModalHandle, ModalTrigger, } from 'terraso-mobile-client/components/modals/Modal'; -import {PermissionsRequestWrapper} from 'terraso-mobile-client/components/modals/PermissionsRequestContext'; +import {PermissionsRequestWrapper} from 'terraso-mobile-client/components/modals/PermissionsRequestWrapper'; import {Column} from 'terraso-mobile-client/components/NativeBaseAdapters'; import {OverlaySheet} from 'terraso-mobile-client/components/sheets/OverlaySheet'; diff --git a/dev-client/src/screens/HomeScreen/components/MapSearch.tsx b/dev-client/src/screens/HomeScreen/components/MapSearch.tsx index 7af735afd..0f539d697 100644 --- a/dev-client/src/screens/HomeScreen/components/MapSearch.tsx +++ b/dev-client/src/screens/HomeScreen/components/MapSearch.tsx @@ -29,7 +29,7 @@ import {Coords} from 'terraso-client-shared/types'; import {IconButton} from 'terraso-mobile-client/components/icons/IconButton'; import {searchBarStyles} from 'terraso-mobile-client/components/ListFilter'; -import {PermissionsRequestWrapper} from 'terraso-mobile-client/components/modals/PermissionsRequestContext'; +import {PermissionsRequestWrapper} from 'terraso-mobile-client/components/modals/PermissionsRequestWrapper'; import { Box, Column, diff --git a/dev-client/src/screens/SlopeScreen/SlopeMeterScreen.tsx b/dev-client/src/screens/SlopeScreen/SlopeMeterScreen.tsx index 826ef794e..7577e17e6 100644 --- a/dev-client/src/screens/SlopeScreen/SlopeMeterScreen.tsx +++ b/dev-client/src/screens/SlopeScreen/SlopeMeterScreen.tsx @@ -28,7 +28,7 @@ import {updateSoilData} from 'terraso-client-shared/soilId/soilIdSlice'; import {BigCloseButton} from 'terraso-mobile-client/components/buttons/BigCloseButton'; import {Icon} from 'terraso-mobile-client/components/icons/Icon'; -import {PermissionsRequestWrapper} from 'terraso-mobile-client/components/modals/PermissionsRequestContext'; +import {PermissionsRequestWrapper} from 'terraso-mobile-client/components/modals/PermissionsRequestWrapper'; import { Box, Column,