Files
iNaturalistReactNative/src/components/Explore/Header/Header.js
Johannes Klein a52996f535 Changes to the way permissions are asked for (#1793)
* Replace name in permission requests

* TakePhoto TS

* PermissionGate TS

* Type

* PermissionGateContainer TS

* Interface

* Types

* LocationGate TS

* Remove LocationPermissionGate from Camera

* Remove write only permission

* Type

* ObsPhotoSelectionList TS

* Code style

* Show the improve with location button

* Create useLocationPermission.tsx

* Use new hook on suggestions

* Doc comment

* Use new hook in camera view

* Add strings

* Refactor Explore main content

* Use permission hook on RootExplore

* Add no location permission component

* Rename function

* Prop request permissions and use with button

* Default to Nearby label

* Remove Node type

* Projects TS

* Use useLocationPermission hook in projects screen

* Add string

* Prop permission down

* Refactor list render

* Refactor tab id into enum

* Tab type

* On nearby tab if without permission show button to prompt

* Leftovers

* Remove location permission gate from ObsEdit

* Use location permission hook on evidence section

* SearchBar TS

* Do not autoFocus on search bar in location picker.

Closes #1743

* Update type

* LocationSearch TS

* Show location permission gate on location picker's mount

* Add location permission to CurrentLocationButton

* Remove unused props of Map

* Remove unused exports from useMapLocation

* Migration

* Revert "Show location permission gate on location picker's mount"

This reverts commit 30ff75698c53d54d0b14cd2bd629f7155b743bf8.

* Add callbacks to useLocationPermission hook

* Show location permission ask on Obs Edit

* Remove unused string

* Reset explore filters should set location always to worldwide

* Add helper function to show place text in Explore

* Remove unused state of filter modal

* Show place text in filters modal with helper

* Show location permission button only for Nearby explore state

* Add a placeMode state

* Do not send placeMode to API

* Also treat limited permission as yes

* useLocationPermission in ExploreLocationSearch

* Refactor to setting place mode

Instead of logic based on the translated text of the place_guess string that is stored in ExploreContext, we are switching to an enum state that signifies which mode to show on explore:
1.) Nearby: Filters explore results based on the user's location. This also has a state without location permission that does not query the API.
2.) Place: Filtering by a specific place (as retrieved by /places API).
3.) Worldwide: Retrieve worldwide results, i.e. not having a place filter set.
4.) Map area: Filtering explore results precisely to the map rectangle shown on the explore map.

* Remove import from test

* Remove export

* Use blocked title only for blocked permission asks

* Move gallery permission container to Tab navigator as are the others

* Add gallery save title

* Split location permission explanation into two

* Update strings.ftl

* Only nav to location picker if permission was not  granted

* Check permission on app being foregrounded

* The location permission part is handled by useLocationPermission

* Do not store permission result in hook

* Use hasPermission from permissions hook

* Update fetchUserLocation.e2e-mock

* Move hook one higher

* Show user location if permission is given

* PermissionGate callbacks should use useCallback

* Add permission hook to map usage

* Fix test

* Update layout to be asserted

* Add location permission hook to Explore

* Remove console.log

* Few TS fixes

* Indentation

* Remove superficial check

* Update Podfile.lock
2024-07-12 11:00:24 +02:00

151 lines
4.8 KiB
JavaScript

// @flow
import classNames from "classnames";
import ExploreLocationSearchModal from "components/Explore/Modals/ExploreLocationSearchModal.tsx";
import ExploreTaxonSearchModal from "components/Explore/Modals/ExploreTaxonSearchModal.tsx";
import NumberBadge from "components/Explore/NumberBadge.tsx";
import {
BackButton,
Body3,
DisplayTaxon,
INatIcon,
INatIconButton
} from "components/SharedComponents";
import { Pressable, View } from "components/styledComponents";
import { useExplore } from "providers/ExploreContext.tsx";
import type { Node } from "react";
import React, { useState } from "react";
import { Surface, useTheme } from "react-native-paper";
import { useTranslation } from "sharedHooks";
import colors from "styles/tailwindColors";
import placeGuessText from "../helpers/placeGuessText";
import HeaderCount from "./HeaderCount";
type Props = {
count: ?number,
exploreView: string,
exploreViewIcon: string,
hideBackButton: boolean,
loadingStatus: boolean,
onPressCount?: Function,
openFiltersModal: Function,
updateTaxon: Function,
updateLocation: Function
}
const Header = ( {
count,
exploreView,
exploreViewIcon,
hideBackButton,
loadingStatus,
onPressCount,
openFiltersModal,
updateTaxon,
updateLocation
}: Props ): Node => {
const { t } = useTranslation( );
const theme = useTheme( );
const { state, numberOfFilters } = useExplore( );
const { taxon } = state;
const iconicTaxonNames = state.iconic_taxa || [];
const [showTaxonSearch, setShowTaxonSearch] = useState( false );
const [showLocationSearch, setShowLocationSearch] = useState( false );
const placeGuess = placeGuessText( state.placeMode, t, state.place_guess );
const surfaceStyle = {
backgroundColor: theme.colors.primary,
borderBottomLeftRadius: 20,
borderBottomRightRadius: 20,
marginBottom: -40
};
return (
<View className="z-10">
<Surface style={surfaceStyle} elevation={5}>
<View className="bg-white px-6 py-4 flex-row justify-between items-center">
<View className="flex-1 flex-row">
{!hideBackButton && (
<BackButton
inCustomHeader
testID="Explore.BackButton"
/>
) }
<View className="flex-1">
{( taxon || iconicTaxonNames.indexOf( "unknown" ) >= 0 )
? (
<DisplayTaxon
accessibilityLabel={t( "Change-taxon-filter" )}
taxon={taxon || "unknown"}
showInfoButton={false}
showCheckmark={false}
handlePress={() => setShowTaxonSearch( true )}
/>
)
: (
<Pressable
accessibilityRole="button"
className="flex-row items-center"
onPress={() => setShowTaxonSearch( true )}
>
<INatIcon name="label-outline" size={15} />
<Body3 className="ml-3">{t( "All-organisms" )}</Body3>
</Pressable>
)}
<Pressable
accessibilityRole="button"
onPress={( ) => setShowLocationSearch( true )}
className="flex-row items-center pt-3"
>
<INatIcon name="location" size={15} />
<Body3 className="ml-3">{placeGuess}</Body3>
</Pressable>
</View>
</View>
<View>
<INatIconButton
icon="sliders"
color={colors.white}
className={classNames(
numberOfFilters !== 0
? "bg-inatGreen"
: "bg-darkGray",
"rounded-md"
)}
onPress={() => openFiltersModal()}
accessibilityLabel={t( "Filters" )}
accessibilityHint={t( "Navigates-to-explore" )}
/>
{numberOfFilters !== 0 && (
<View className="absolute top-[-10] right-[-10]">
<NumberBadge number={numberOfFilters} light />
</View>
)}
</View>
</View>
<HeaderCount
count={count}
exploreView={exploreView}
exploreViewIcon={exploreViewIcon}
loadingStatus={loadingStatus}
onPress={onPressCount}
/>
</Surface>
<ExploreTaxonSearchModal
showModal={showTaxonSearch}
closeModal={() => { setShowTaxonSearch( false ); }}
updateTaxon={updateTaxon}
/>
<ExploreLocationSearchModal
showModal={showLocationSearch}
closeModal={() => { setShowLocationSearch( false ); }}
updateLocation={updateLocation}
/>
</View>
);
};
export default Header;