diff --git a/src/components/AddObsBottomSheet/AddObsBottomSheet.tsx b/src/components/AddObsBottomSheet/AddObsBottomSheet.tsx new file mode 100644 index 000000000..a3e000de7 --- /dev/null +++ b/src/components/AddObsBottomSheet/AddObsBottomSheet.tsx @@ -0,0 +1,175 @@ +import classNames from "classnames"; +import { + Body3, BottomSheet, INatIconButton +} from "components/SharedComponents"; +import { View } from "components/styledComponents"; +import React, { useMemo } from "react"; +import { Platform, TouchableOpacity } from "react-native"; +import Observation from "realmModels/Observation"; +import { useTranslation } from "sharedHooks"; +import useStore from "stores/useStore"; +import { getShadow } from "styles/global"; +import colors from "styles/tailwindColors"; + +interface Props { + closeModal: ( ) => void; + navAndCloseModal: ( screen: string, params?: { + camera?: string + } ) => void; + hidden: boolean; +} + +export type ObsCreateItem = { + text?: string, + icon: string, + onPress: ( ) => void, + testID: string, + className: string, + accessibilityLabel: string, + accessibilityHint: string +} + +const majorVersionIOS = parseInt( String( Platform.Version ), 10 ); +const AI_CAMERA_SUPPORTED = ( Platform.OS === "ios" && majorVersionIOS >= 11 ) + || ( Platform.OS === "android" && Platform.Version > 21 ); + +const DROP_SHADOW = getShadow( { + offsetHeight: 1, + elevation: 1, + shadowRadius: 1 +} ); +const GREEN_CIRCLE_CLASS = "bg-inatGreen rounded-full h-[36px] w-[36px] mb-2"; +const ROW_CLASS = "flex-row justify-center space-x-4 w-full flex-1"; + +const AddObsBottomSheet = ( { + closeModal, navAndCloseModal, hidden +}: Props ) => { + const { t } = useTranslation( ); + + const prepareObsEdit = useStore( state => state.prepareObsEdit ); + + const obsCreateItems = useMemo( ( ) => ( { + aiCamera: { + text: t( "ID-with-AI-Camera" ), + icon: "aicamera", + onPress: ( ) => navAndCloseModal( "Camera", { camera: "AI" } ), + testID: "aicamera-button", + accessibilityLabel: t( "AI-Camera" ), + accessibilityHint: t( "Navigates-to-AI-camera" ) + }, + standardCamera: { + text: t( "Take-photos" ), + icon: "camera", + onPress: ( ) => navAndCloseModal( "Camera", { camera: "Standard" } ), + testID: "camera-button", + accessibilityLabel: t( "Camera" ), + accessibilityHint: t( "Navigates-to-camera" ) + }, + photoLibrary: { + text: t( "Upload-photos" ), + icon: "photo-library", + onPress: ( ) => navAndCloseModal( "PhotoLibrary" ), + testID: "import-media-button", + accessibilityLabel: t( "Photo-importer" ), + accessibilityHint: t( "Navigates-to-photo-importer" ) + }, + soundRecorder: { + text: t( "Record-a-sound" ), + icon: "microphone", + onPress: ( ) => navAndCloseModal( "SoundRecorder" ), + testID: "record-sound-button", + accessibilityLabel: t( "Sound-recorder" ), + accessibilityHint: t( "Navigates-to-sound-recorder" ) + }, + noEvidence: { + text: t( "Create-observation-with-no-evidence" ), + icon: "noevidence", + onPress: async ( ) => { + const newObservation = await Observation.new( ); + prepareObsEdit( newObservation ); + navAndCloseModal( "ObsEdit" ); + }, + testID: "observe-without-evidence-button", + accessibilityLabel: t( "Observation-with-no-evidence" ), + accessibilityHint: t( "Navigates-to-observation-edit-screen" ) + } + } ), [ + navAndCloseModal, + prepareObsEdit, + t + ] ); + + const renderAddObsIcon = ( { + accessibilityHint, + accessibilityLabel, + icon, + onPress, + testID, + text + }: ObsCreateItem ) => ( + + + {text} + + ); + + return ( + + ); +}; + +export default AddObsBottomSheet; diff --git a/src/components/AddObsModal/AddObsButton.js b/src/components/AddObsBottomSheet/AddObsButton.js similarity index 89% rename from src/components/AddObsModal/AddObsButton.js rename to src/components/AddObsBottomSheet/AddObsButton.js index e4d02ee7e..9c62d3039 100644 --- a/src/components/AddObsModal/AddObsButton.js +++ b/src/components/AddObsBottomSheet/AddObsButton.js @@ -1,8 +1,7 @@ // @flow import { CommonActions, useNavigation } from "@react-navigation/native"; -import AddObsModal from "components/AddObsModal/AddObsModal"; -import { Modal } from "components/SharedComponents"; +import AddObsBottomSheet from "components/AddObsBottomSheet/AddObsBottomSheet"; import GradientButton from "components/SharedComponents/Buttons/GradientButton"; import { t } from "i18next"; import { getCurrentRoute } from "navigation/navigationUtils"; @@ -26,7 +25,6 @@ const AddObsButton = ( ): React.Node => { // Controls whether to show the tooltip, and to show it only once to the user const showKey = "AddObsButtonTooltip"; const shownOnce = useStore( state => state.layout.shownOnce ); - const setShownOnce = useStore( state => state.layout.setShownOnce ); const justFinishedSignup = useStore( state => state.layout.justFinishedSignup ); const numOfUserObservations = zustandStorage.getItem( "numOfUserObservations" ); // Base trigger condition in all cases: @@ -122,30 +120,13 @@ const AddObsButton = ( ): React.Node => { }; const navToARCamera = ( ) => { navAndCloseModal( "Camera", { camera: "AI" } ); }; - const addObsModal = ( - { - if ( tooltipIsVisible ) setShownOnce( showKey ); - }} - /> - ); - return ( <> {/* match the animation timing on FadeInView.tsx */} -