diff --git a/src/components/Camera/StandardCamera/StandardCamera.js b/src/components/Camera/StandardCamera/StandardCamera.js index 4cea3aaa5..b48ddabfb 100644 --- a/src/components/Camera/StandardCamera/StandardCamera.js +++ b/src/components/Camera/StandardCamera/StandardCamera.js @@ -7,6 +7,7 @@ import FadeInOutView from "components/Camera/FadeInOutView"; import useRotation from "components/Camera/hooks/useRotation"; import useTakePhoto from "components/Camera/hooks/useTakePhoto"; import useZoom from "components/Camera/hooks/useZoom"; +import navigateToObsDetails from "components/ObsDetails/helpers/navigateToObsDetails"; import { View } from "components/styledComponents"; import { getCurrentRoute } from "navigation/navigationUtils"; import type { Node } from "react"; @@ -80,20 +81,17 @@ const StandardCamera = ( { const previousScreen = params && params.previousScreen ? params.previousScreen : null; - const screenParams = previousScreen && previousScreen.name === "ObsDetails" - ? { - navToObsDetails: true, - uuid: previousScreen.params.uuid - } - : {}; - navigation.navigate( "TabNavigator", { - screen: "ObservationsStackNavigator", - params: { - screen: "ObsList", - params: screenParams - } - } ); + if ( previousScreen && previousScreen.name === "ObsDetails" ) { + navigateToObsDetails( navigation, previousScreen.params.uuid ); + } else { + navigation.navigate( "TabNavigator", { + screen: "ObservationsStackNavigator", + params: { + screen: "ObsList" + } + } ); + } } }; const { diff --git a/src/components/MyObservations/MyObservationsContainer.js b/src/components/MyObservations/MyObservationsContainer.js index e1b31d5be..d0ded8f24 100644 --- a/src/components/MyObservations/MyObservationsContainer.js +++ b/src/components/MyObservations/MyObservationsContainer.js @@ -7,7 +7,6 @@ import { } from "api/observations"; import { getJWT } from "components/LoginSignUp/AuthenticationService"; import { format } from "date-fns"; -import { navigationRef } from "navigation/navigationUtils"; import { RealmContext } from "providers/contexts"; import type { Node } from "react"; import React, { @@ -136,7 +135,6 @@ const { useRealm } = RealmContext; const MyObservationsContainer = ( ): Node => { const navigation = useNavigation( ); - const { params } = useRoute( ); const { t } = useTranslation( ); const realm = useRealm( ); const allObsToUpload = Observation.filterUnsyncedObservations( realm ); @@ -206,18 +204,6 @@ const MyObservationsContainer = ( ): Node => { : "grid" ); }; - useEffect( () => { - if ( navigationRef && navigationRef.isReady() ) { - if ( params && params.navToObsDetails ) { - // We wrap this in a setTimeout, since otherwise this routing doesn't work immediately - // when loading this screen - setTimeout( () => { - navigation.navigate( "ObsDetails", { uuid: params.uuid } ); - }, 100 ); - } - } - }, [navigation, params] ); - useEffect( ( ) => { // show progress in toolbar for observations uploaded on ObsEdit if ( navParams?.uuid && !state.uploadInProgress && currentUser ) { diff --git a/src/components/ObsDetails/ObsDetails.js b/src/components/ObsDetails/ObsDetails.js index 2f8ff3f63..57002e2fc 100644 --- a/src/components/ObsDetails/ObsDetails.js +++ b/src/components/ObsDetails/ObsDetails.js @@ -14,9 +14,12 @@ import { View } from "components/styledComponents"; import type { Node } from "react"; -import React from "react"; -import { Platform, StatusBar } from "react-native"; +import React, { useMemo } from "react"; +import { Platform } from "react-native"; import DeviceInfo from "react-native-device-info"; +import { + useSafeAreaInsets +} from "react-native-safe-area-context"; import { useTranslation } from "sharedHooks"; @@ -83,10 +86,19 @@ const ObsDetails = ( { tabs, taxonForAgreement }: Props ): Node => { + const insets = useSafeAreaInsets(); const { params } = useRoute( ); const { uuid } = params; const { t } = useTranslation( ); + const dynamicInsets = useMemo( () => ( { + backgroundColor: "#ffffff", + paddingTop: insets.top, + paddingBottom: insets.bottom, + paddingLeft: insets.left, + paddingRight: insets.right + } ), [insets] ); + const textInputStyle = Platform.OS === "android" && { height: 125 }; @@ -222,8 +234,10 @@ const ObsDetails = ( { ); return ( - - + {!isTablet ? renderPhone() : renderTablet()} diff --git a/src/components/ObsDetails/ObsDetailsHeader.js b/src/components/ObsDetails/ObsDetailsHeader.js index 351565115..aa24d5734 100644 --- a/src/components/ObsDetails/ObsDetailsHeader.js +++ b/src/components/ObsDetails/ObsDetailsHeader.js @@ -61,7 +61,9 @@ const ObsDetailsHeader = ( { testID="ObsDetail.editButton" onPress={() => { setObservations( [observation] ); - navigation.navigate( "ObsEdit" ); + navigation.navigate( "CameraNavigator", { + screen: "ObsEdit" + } ); }} icon="pencil" color={!rightIconBlack diff --git a/src/components/ObsDetails/helpers/navigateToObsDetails.js b/src/components/ObsDetails/helpers/navigateToObsDetails.js new file mode 100644 index 000000000..924b10eb9 --- /dev/null +++ b/src/components/ObsDetails/helpers/navigateToObsDetails.js @@ -0,0 +1,33 @@ +import { CommonActions } from "@react-navigation/native"; + +// Creates a navigation tree that navigates to the ObsDetails screen with a specific obs UUID, +// and when navigating back from the ObsDetails screen, it'll go back to ObsList screen +export default function navigateToObsDetails( navigation, uuid ) { + navigation.dispatch( + CommonActions.reset( { + index: 1, + routes: [ + { + name: "TabNavigator", + state: { + routes: [ + { + name: "ObservationsStackNavigator", + state: { + index: 0, + routes: [ + { name: "ObsList" }, + { + name: "ObsDetails", + params: { uuid } + } + ] + } + } + ] + } + } + ] + } ) + ); +} diff --git a/src/components/ObsEdit/Header.js b/src/components/ObsEdit/Header.js index aa7050560..45c071fa5 100644 --- a/src/components/ObsEdit/Header.js +++ b/src/components/ObsEdit/Header.js @@ -1,6 +1,7 @@ // @flow -import { useFocusEffect, useNavigation } from "@react-navigation/native"; +import { useFocusEffect, useNavigation, useRoute } from "@react-navigation/native"; +import navigateToObsDetails from "components/ObsDetails/helpers/navigateToObsDetails"; import { BackButton, Heading2, KebabMenu } from "components/SharedComponents"; import { View } from "components/styledComponents"; import type { Node } from "react"; @@ -29,11 +30,12 @@ const Header = ( { const updateObservations = useStore( state => state.updateObservations ); const { t } = useTranslation( ); const navigation = useNavigation( ); + const { params } = useRoute( ); const [deleteSheetVisible, setDeleteSheetVisible] = useState( false ); const [kebabMenuVisible, setKebabMenuVisible] = useState( false ); const [discardObservationSheetVisible, setDiscardObservationSheetVisible] = useState( false ); const [discardChangesSheetVisible, setDiscardChangesSheetVisible] = useState( false ); - + const unsynced = !currentObservation?._synced_at; const savedLocally = currentObservation?._created_at; const navToObsList = useCallback( ( ) => { @@ -47,8 +49,8 @@ const Header = ( { const discardChanges = useCallback( ( ) => { setDiscardChangesSheetVisible( false ); - navigation.goBack( ); - }, [navigation] ); + navigateToObsDetails( navigation, currentObservation?.uuid ); + }, [currentObservation?.uuid, navigation] ); const discardObservation = useCallback( ( ) => { setDiscardObservationSheetVisible( false ); @@ -76,15 +78,20 @@ const Header = ( { }, [observations, t, savedLocally] ); const handleBackButtonPress = useCallback( ( ) => { - if ( unsavedChanges && savedLocally ) { + if ( params?.lastScreen === "GroupPhotos" + || ( unsynced && savedLocally ) + || ( unsynced && !unsavedChanges ) + ) { + navigation.goBack( ); + } else if ( !savedLocally ) { + setDiscardObservationSheetVisible( true ); + } else if ( unsavedChanges ) { setDiscardChangesSheetVisible( true ); } else { - navigation.goBack( ); + navigateToObsDetails( navigation, currentObservation?.uuid ); } }, [ - savedLocally, - navigation, - unsavedChanges + params?.lastScreen, unsynced, savedLocally, unsavedChanges, navigation, currentObservation?.uuid ] ); const renderBackButton = useCallback( ( ) => { diff --git a/src/components/PhotoImporter/PhotoGallery.js b/src/components/PhotoImporter/PhotoGallery.js index 07d778661..e614c34d8 100644 --- a/src/components/PhotoImporter/PhotoGallery.js +++ b/src/components/PhotoImporter/PhotoGallery.js @@ -1,4 +1,5 @@ import { useFocusEffect, useNavigation, useRoute } from "@react-navigation/native"; +import navigateToObsDetails from "components/ObsDetails/helpers/navigateToObsDetails"; import { ActivityAnimation, ViewWrapper } from "components/SharedComponents"; import PermissionGateContainer, { READ_MEDIA_PERMISSIONS } from "components/SharedComponents/PermissionGateContainer"; @@ -53,18 +54,6 @@ const PhotoGallery = ( ): Node => { } ); }, [navigation] ); - const navToObsDetails = useCallback( uuid => navigation.navigate( "TabNavigator", { - screen: "ObservationsStackNavigator", - params: { - // Need to return to ObsDetails but with a navigation stack that goes back to ObsList - screen: "ObsList", - params: { - navToObsDetails: true, - uuid - } - } - } ), [navigation] ); - const navToObsEdit = useCallback( ( ) => navigation.navigate( "ObsEdit", { lastScreen: "PhotoGallery" } ), [navigation] ); @@ -107,7 +96,7 @@ const PhotoGallery = ( ): Node => { // Determine if we need to go back to ObsList or ObsDetails screen } else if ( params && params.previousScreen && params.previousScreen.name === "ObsDetails" ) { - navToObsDetails( params.previousScreen.params.uuid ); + navigateToObsDetails( navigation, params.previousScreen.params.uuid ); } else { navToObsList(); } @@ -177,7 +166,7 @@ const PhotoGallery = ( ): Node => { navToObsEdit, navToObsList, photoGalleryShown, numOfObsPhotos, setPhotoImporterState, evidenceToAdd, galleryUris, navigation, setGroupedPhotos, fromGroupPhotos, skipGroupPhotos, groupedPhotos, currentObservation, updateObservations, observations, currentObservationIndex, - navToObsDetails, params + params ] ); const onPermissionGranted = () => { diff --git a/src/components/SharedComponents/ObservationsFlashList/MyObservationsPressable.js b/src/components/SharedComponents/ObservationsFlashList/MyObservationsPressable.js index 4d9c07fae..e9a39e6f1 100644 --- a/src/components/SharedComponents/ObservationsFlashList/MyObservationsPressable.js +++ b/src/components/SharedComponents/ObservationsFlashList/MyObservationsPressable.js @@ -24,7 +24,9 @@ const MyObservationsPressable = ( { observation, testID, children }: Props ): No const { uuid } = observation; if ( unsynced ) { setObservations( [observation] ); - navigation.navigate( "ObsEdit" ); + navigation.navigate( "CameraNavigator", { + screen: "ObsEdit" + } ); } else { navigation.navigate( "ObsDetails", { uuid } ); }