Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: improve UX of location permission requests #1714

Merged
merged 7 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions dev-client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions dev-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
11 changes: 2 additions & 9 deletions dev-client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -37,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';

Expand All @@ -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';
Expand All @@ -75,12 +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 (
Expand Down
26 changes: 15 additions & 11 deletions dev-client/src/components/inputs/image/ImagePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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/PermissionsRequestWrapper';
import {Column} from 'terraso-mobile-client/components/NativeBaseAdapters';
import {OverlaySheet} from 'terraso-mobile-client/components/sheets/OverlaySheet';

Expand Down Expand Up @@ -100,10 +100,12 @@ export const ImagePicker = ({
return (
<OverlaySheet ref={ref} trigger={children} Closer={null} {...modalProps}>
<Column padding="lg" space="md">
<PermissionsRequestModal
title={t('permissions.camera_title')}
body={t('permissions.camera_body', {feature: featureName})}
usePermissions={useCameraPermissions}
<PermissionsRequestWrapper
requestModalTitle={t('permissions.camera_title')}
requestModalBody={t('permissions.camera_body', {
feature: featureName,
})}
permissionHook={useCameraPermissions}
permissionedAction={onUseCamera}>
{onRequestAction => (
<Button
Expand All @@ -113,11 +115,13 @@ export const ImagePicker = ({
{t('image.use_camera')}
</Button>
)}
</PermissionsRequestModal>
<PermissionsRequestModal
title={t('permissions.gallery_title')}
body={t('permissions.gallery_body', {feature: featureName})}
usePermissions={useMediaLibraryPermissions}
</PermissionsRequestWrapper>
<PermissionsRequestWrapper
requestModalTitle={t('permissions.gallery_title')}
requestModalBody={t('permissions.gallery_body', {
feature: featureName,
})}
permissionHook={useMediaLibraryPermissions}
permissionedAction={onUseMediaLibrary}>
{onRequestAction => (
<Button
Expand All @@ -127,7 +131,7 @@ export const ImagePicker = ({
{t('image.choose_from_gallery')}
</Button>
)}
</PermissionsRequestModal>
</PermissionsRequestWrapper>
<Button
_text={{textTransform: 'uppercase'}}
variant="outline"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@ import {ModalHandle} from 'terraso-mobile-client/components/modals/Modal';
type PermissionHook = ReturnType<typeof createPermissionHook>;

type Props = {
title: string;
body: string;
usePermissions: PermissionHook;
requestModalTitle: string;
requestModalBody: string;
permissionHook: PermissionHook;
permissionedAction?: () => void;
children: (onOpen: () => void) => React.ReactNode;
};

export const PermissionsRequestModal = ({
title,
body,
usePermissions,
export const PermissionsRequestWrapper = ({
requestModalTitle,
requestModalBody,
permissionHook: usePermissions,
permissionedAction,
children,
}: Props) => {
Expand Down Expand Up @@ -70,8 +70,8 @@ export const PermissionsRequestModal = ({
ref={ref}
isConfirmError={false}
actionName={t('general.open_settings')}
title={title}
body={body}
title={requestModalTitle}
body={requestModalBody}
handleConfirm={Linking.openSettings}
/>
{children(onRequestAction)}
Expand Down
40 changes: 0 additions & 40 deletions dev-client/src/native/checkAndroidPermissions.ts

This file was deleted.

12 changes: 12 additions & 0 deletions dev-client/src/screens/HomeScreen/HomeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -58,6 +60,16 @@ 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();
}
// disable depcheck because we only want to run on mount
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const infoBottomSheetRef = useRef<BottomSheetModal>(null);
const siteListBottomSheetRef = useRef<BottomSheet>(null);
const [mapStyleURL, setMapStyleURL] = useState(Mapbox.StyleURL.Street);
Expand Down
27 changes: 19 additions & 8 deletions dev-client/src/screens/HomeScreen/components/MapSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 {PermissionsRequestWrapper} from 'terraso-mobile-client/components/modals/PermissionsRequestWrapper';
import {
Box,
Column,
Expand Down Expand Up @@ -211,14 +214,22 @@ export default function MapSearch({zoomTo, zoomToUser, toggleMapLayer}: Props) {
padding={2}
onPress={toggleMapLayer}
/>
<IconButton
name="my-location"
_icon={{color: 'action.active'}}
bgColor="white"
padding={2}
borderRadius={15}
onPress={zoomToUser}
/>
<PermissionsRequestWrapper
requestModalTitle={t('permissions.location_title')}
requestModalBody={t('permissions.location_body')}
permissionHook={useForegroundPermissions}
permissionedAction={zoomToUser}>
{onRequest => (
<IconButton
name="my-location"
_icon={{color: 'action.active'}}
bgColor="white"
padding={2}
borderRadius={15}
onPress={onRequest}
/>
)}
</PermissionsRequestWrapper>
</Column>
</Row>
</Box>
Expand Down
12 changes: 6 additions & 6 deletions dev-client/src/screens/SlopeScreen/SlopeMeterScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 {PermissionsRequestModal} from 'terraso-mobile-client/components/modals/PermissionsRequestModal';
import {PermissionsRequestWrapper} from 'terraso-mobile-client/components/modals/PermissionsRequestWrapper';
import {
Box,
Column,
Expand Down Expand Up @@ -100,18 +100,18 @@ export const SlopeMeterScreen = ({siteId}: {siteId: string}) => {
</Column>
</CameraView>
) : (
<PermissionsRequestModal
title={t('permissions.camera_title')}
body={t('permissions.camera_body', {
<PermissionsRequestWrapper
requestModalTitle={t('permissions.camera_title')}
requestModalBody={t('permissions.camera_body', {
feature: t('slope.steepness.slope_meter'),
})}
usePermissions={useCameraPermissions}>
permissionHook={useCameraPermissions}>
{onRequest => (
<Button size="lg" onPress={onRequest}>
{t('slope.steepness.camera_grant')}
</Button>
)}
</PermissionsRequestModal>
</PermissionsRequestWrapper>
)}
</Box>
<Column alignItems="center">
Expand Down
4 changes: 3 additions & 1 deletion dev-client/src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down
Loading