mirror of
https://github.com/inaturalist/iNaturalistReactNative.git
synced 2025-12-23 22:18:36 -05:00
MOB-925 - new designs for add-obs button sheet
This commit is contained in:
committed by
Abbey Campbell
parent
a564f85ba0
commit
9c2facc680
175
src/components/AddObsBottomSheet/AddObsBottomSheet.tsx
Normal file
175
src/components/AddObsBottomSheet/AddObsBottomSheet.tsx
Normal file
@@ -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 ) => (
|
||||
<TouchableOpacity
|
||||
className={classNames(
|
||||
"bg-white w-1/2 flex-column items-center py-4 rounded-sm flex-1",
|
||||
DROP_SHADOW
|
||||
)}
|
||||
onPress={onPress}
|
||||
accessibilityHint={accessibilityHint}
|
||||
accessibilityLabel={accessibilityLabel}
|
||||
testID={testID}
|
||||
>
|
||||
<INatIconButton
|
||||
className={GREEN_CIRCLE_CLASS}
|
||||
accessibilityHint={accessibilityHint}
|
||||
accessibilityLabel={accessibilityLabel}
|
||||
color={String( colors?.white )}
|
||||
icon={icon}
|
||||
size={icon === "aicamera"
|
||||
? 28
|
||||
: 20}
|
||||
/>
|
||||
<Body3>{text}</Body3>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
|
||||
return (
|
||||
<BottomSheet
|
||||
onPressClose={closeModal}
|
||||
hidden={hidden}
|
||||
insideModal={false}
|
||||
hideCloseButton
|
||||
additionalClasses="bg-lightGray pt-4"
|
||||
>
|
||||
<View className="flex-column gap-y-4 pb-4 px-4">
|
||||
<View className={ROW_CLASS}>
|
||||
{renderAddObsIcon( obsCreateItems.standardCamera )}
|
||||
{renderAddObsIcon( obsCreateItems.photoLibrary )}
|
||||
</View>
|
||||
<View className={ROW_CLASS}>
|
||||
{renderAddObsIcon( obsCreateItems.soundRecorder )}
|
||||
{AI_CAMERA_SUPPORTED && renderAddObsIcon( obsCreateItems.aiCamera )}
|
||||
</View>
|
||||
<View className={ROW_CLASS}>
|
||||
<TouchableOpacity
|
||||
className="bg-mediumGray w-full flex-row items-center py-2 px-4 rounded-sm"
|
||||
onPress={obsCreateItems.noEvidence.onPress}
|
||||
accessibilityHint={obsCreateItems.noEvidence.accessibilityHint}
|
||||
accessibilityLabel={obsCreateItems.noEvidence.accessibilityLabel}
|
||||
testID={obsCreateItems.noEvidence.testID}
|
||||
>
|
||||
<INatIconButton
|
||||
className="h-[36px] w-[36px] mr-2"
|
||||
accessibilityHint={obsCreateItems.noEvidence.accessibilityHint}
|
||||
accessibilityLabel={obsCreateItems.noEvidence.accessibilityLabel}
|
||||
color={String( colors?.darkGray )}
|
||||
icon={obsCreateItems.noEvidence.icon}
|
||||
size={24}
|
||||
/>
|
||||
<Body3>{obsCreateItems.noEvidence.text}</Body3>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</BottomSheet>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddObsBottomSheet;
|
||||
@@ -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 = (
|
||||
<AddObsModal
|
||||
closeModal={closeModal}
|
||||
navAndCloseModal={navAndCloseModal}
|
||||
tooltipIsVisible={tooltipIsVisible}
|
||||
dismissTooltip={( ) => {
|
||||
if ( tooltipIsVisible ) setShownOnce( showKey );
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* match the animation timing on FadeInView.tsx */}
|
||||
<Modal
|
||||
animationIn="fadeIn"
|
||||
animationOut="fadeOut"
|
||||
animationInTiming={250}
|
||||
animationOutTiming={250}
|
||||
showModal={showModal}
|
||||
closeModal={tooltipIsVisible
|
||||
? undefined
|
||||
: closeModal}
|
||||
modal={addObsModal}
|
||||
<AddObsBottomSheet
|
||||
closeModal={closeModal}
|
||||
hidden={!showModal}
|
||||
navAndCloseModal={navAndCloseModal}
|
||||
/>
|
||||
<GradientButton
|
||||
sizeClassName="w-[69px] h-[69px] mb-[5px]"
|
||||
@@ -1,192 +0,0 @@
|
||||
import classnames from "classnames";
|
||||
import {
|
||||
Body2,
|
||||
INatIconButton
|
||||
} from "components/SharedComponents";
|
||||
import GradientButton from "components/SharedComponents/Buttons/GradientButton";
|
||||
import { View } from "components/styledComponents";
|
||||
import React, { useMemo } from "react";
|
||||
import { Platform, StatusBar } from "react-native";
|
||||
import Observation from "realmModels/Observation";
|
||||
import { useTranslation } from "sharedHooks";
|
||||
import useStore from "stores/useStore";
|
||||
import colors from "styles/tailwindColors";
|
||||
|
||||
import AddObsModalHelp, { ObsCreateItem } from "./AddObsModalHelp";
|
||||
|
||||
interface Props {
|
||||
closeModal: ( ) => void;
|
||||
navAndCloseModal: ( screen: string, params?: {
|
||||
camera?: string
|
||||
} ) => void;
|
||||
tooltipIsVisible: boolean;
|
||||
dismissTooltip: () => void;
|
||||
}
|
||||
|
||||
const majorVersionIOS = parseInt( String( Platform.Version ), 10 );
|
||||
const AI_CAMERA_SUPPORTED = ( Platform.OS === "ios" && majorVersionIOS >= 11 )
|
||||
|| ( Platform.OS === "android" && Platform.Version > 21 );
|
||||
|
||||
const GREEN_CIRCLE_CLASS = "bg-inatGreen rounded-full h-[46px] w-[46px]";
|
||||
const ROW_CLASS = "flex-row justify-center";
|
||||
const MARGINS = AI_CAMERA_SUPPORTED
|
||||
? {
|
||||
standardCamera: "mr-[37px] bottom-[1px]",
|
||||
photoLibrary: "ml-[37px] bottom-[1px]",
|
||||
noEvidence: "mr-[26px]",
|
||||
soundRecorder: "ml-[26px]"
|
||||
}
|
||||
: {
|
||||
standardCamera: "mr-[9px]",
|
||||
photoLibrary: "ml-[9px]",
|
||||
noEvidence: "mr-[20px] bottom-[33px]",
|
||||
soundRecorder: "ml-[20px] bottom-[33px]"
|
||||
};
|
||||
|
||||
const AddObsModal = ( {
|
||||
closeModal, navAndCloseModal, tooltipIsVisible, dismissTooltip
|
||||
}: Props ) => {
|
||||
const { t } = useTranslation( );
|
||||
|
||||
const prepareObsEdit = useStore( state => state.prepareObsEdit );
|
||||
|
||||
const obsCreateItems = useMemo( ( ) => ( {
|
||||
aiCamera: {
|
||||
text: t( "Use-iNaturalists-AI-Camera" ),
|
||||
icon: "aicamera",
|
||||
onPress: ( ) => navAndCloseModal( "Camera", { camera: "AI" } ),
|
||||
testID: "aicamera-button",
|
||||
className: classnames( GREEN_CIRCLE_CLASS, "absolute bottom-[26px]" ),
|
||||
accessibilityLabel: t( "AI-Camera" ),
|
||||
accessibilityHint: t( "Navigates-to-AI-camera" )
|
||||
},
|
||||
standardCamera: {
|
||||
text: t( "Take-multiple-photos-of-a-single-organism" ),
|
||||
icon: "camera",
|
||||
onPress: ( ) => navAndCloseModal( "Camera", { camera: "Standard" } ),
|
||||
testID: "camera-button",
|
||||
accessibilityLabel: t( "Camera" ),
|
||||
accessibilityHint: t( "Navigates-to-camera" ),
|
||||
className: classnames( GREEN_CIRCLE_CLASS, MARGINS.standardCamera )
|
||||
},
|
||||
photoLibrary: {
|
||||
text: t( "Upload-photos-from-your-photo-library" ),
|
||||
icon: "photo-library",
|
||||
onPress: ( ) => navAndCloseModal( "PhotoLibrary" ),
|
||||
testID: "import-media-button",
|
||||
className: classnames( GREEN_CIRCLE_CLASS, MARGINS.photoLibrary ),
|
||||
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",
|
||||
className: classnames( GREEN_CIRCLE_CLASS, MARGINS.soundRecorder ),
|
||||
accessibilityLabel: t( "Sound-recorder" ),
|
||||
accessibilityHint: t( "Navigates-to-sound-recorder" )
|
||||
},
|
||||
noEvidence: {
|
||||
text: t( "Create-an-observation-evidence" ),
|
||||
icon: "noevidence",
|
||||
onPress: async ( ) => {
|
||||
const newObservation = await Observation.new( );
|
||||
prepareObsEdit( newObservation );
|
||||
navAndCloseModal( "ObsEdit" );
|
||||
},
|
||||
testID: "observe-without-evidence-button",
|
||||
className: classnames( GREEN_CIRCLE_CLASS, MARGINS.noEvidence ),
|
||||
accessibilityLabel: t( "Observation-with-no-evidence" ),
|
||||
accessibilityHint: t( "Navigates-to-observation-edit-screen" )
|
||||
},
|
||||
closeButton: {
|
||||
testID: "close-camera-options-button",
|
||||
icon: "close",
|
||||
className: classnames( GREEN_CIRCLE_CLASS, "h-[69px] w-[69px]" ),
|
||||
onPress: closeModal,
|
||||
accessibilityLabel: t( "Close" ),
|
||||
accessibilityHint: t( "Closes-new-observation-options" )
|
||||
}
|
||||
} ), [
|
||||
closeModal,
|
||||
navAndCloseModal,
|
||||
prepareObsEdit,
|
||||
t
|
||||
] );
|
||||
|
||||
const renderAddObsIcon = ( {
|
||||
accessibilityHint,
|
||||
accessibilityLabel,
|
||||
className,
|
||||
icon,
|
||||
onPress,
|
||||
testID
|
||||
}: ObsCreateItem ) => (
|
||||
<INatIconButton
|
||||
accessibilityHint={accessibilityHint}
|
||||
accessibilityLabel={accessibilityLabel}
|
||||
className={className}
|
||||
color={String( colors?.white )}
|
||||
icon={icon}
|
||||
onPress={onPress}
|
||||
size={icon === "aicamera"
|
||||
? 38
|
||||
: 30}
|
||||
testID={testID}
|
||||
/>
|
||||
);
|
||||
|
||||
const renderContent = ( ) => {
|
||||
if ( tooltipIsVisible ) {
|
||||
return (
|
||||
<View className="justify-center items-center">
|
||||
<View className="bg-white rounded-2xl px-5 py-4">
|
||||
<Body2>{t( "Press-and-hold-to-view-more-options" )}</Body2>
|
||||
</View>
|
||||
<View
|
||||
className={classnames(
|
||||
// I could not figure out how to use "border-x-transparent",
|
||||
"border-l-[10px] border-r-[10px] border-x-[#00000000]",
|
||||
"border-t-[16px] border-t-white mb-2"
|
||||
)}
|
||||
/>
|
||||
<GradientButton
|
||||
sizeClassName="w-[69px] h-[69px]"
|
||||
onPress={() => {}}
|
||||
onLongPress={() => dismissTooltip( )}
|
||||
accessibilityLabel={t( "Add-observations" )}
|
||||
accessibilityHint={t( "Shows-observation-creation-options" )}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<AddObsModalHelp obsCreateItems={obsCreateItems} />
|
||||
<View className={classnames( ROW_CLASS, {
|
||||
"bottom-[20px]": !AI_CAMERA_SUPPORTED
|
||||
} )}
|
||||
>
|
||||
{renderAddObsIcon( obsCreateItems.standardCamera )}
|
||||
{AI_CAMERA_SUPPORTED && renderAddObsIcon( obsCreateItems.aiCamera )}
|
||||
{renderAddObsIcon( obsCreateItems.photoLibrary )}
|
||||
</View>
|
||||
<View className={classnames( ROW_CLASS, "items-center" )}>
|
||||
{renderAddObsIcon( obsCreateItems.noEvidence )}
|
||||
{renderAddObsIcon( obsCreateItems.closeButton )}
|
||||
{renderAddObsIcon( obsCreateItems.soundRecorder )}
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<StatusBar barStyle="light-content" backgroundColor="black" />
|
||||
{ renderContent( ) }
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddObsModal;
|
||||
@@ -1,116 +0,0 @@
|
||||
import classnames from "classnames";
|
||||
import {
|
||||
Body3,
|
||||
Heading2,
|
||||
INatIcon,
|
||||
INatIconButton
|
||||
} from "components/SharedComponents";
|
||||
import { Pressable, View } from "components/styledComponents";
|
||||
import React, { useState } from "react";
|
||||
import { useDeviceOrientation, useTranslation } from "sharedHooks";
|
||||
import { storage } from "stores/useStore";
|
||||
import colors from "styles/tailwindColors";
|
||||
|
||||
export type ObsCreateItem = {
|
||||
text?: string,
|
||||
icon: string,
|
||||
onPress: ( ) => void,
|
||||
testID: string,
|
||||
className: string,
|
||||
accessibilityLabel: string,
|
||||
accessibilityHint: string
|
||||
}
|
||||
|
||||
type Props = {
|
||||
obsCreateItems: {
|
||||
[addType: string]: ObsCreateItem
|
||||
}
|
||||
};
|
||||
|
||||
const HIDE_ADD_OBS_HELP_TEXT = "hideAddObsHelpText";
|
||||
|
||||
const AddObsModalHelp = ( {
|
||||
obsCreateItems
|
||||
}: Props ) => {
|
||||
const { t } = useTranslation( );
|
||||
const { screenHeight } = useDeviceOrientation( );
|
||||
const [hideHelpText, setHideHelpText] = useState( storage.getBoolean( HIDE_ADD_OBS_HELP_TEXT ) );
|
||||
|
||||
// targeting iPhone SE, which has height of 667
|
||||
const isSmallScreen = screenHeight < 670;
|
||||
|
||||
if ( hideHelpText ) return null;
|
||||
|
||||
return (
|
||||
<View
|
||||
className={classnames( "bg-white rounded-3xl py-[23px] mb-20", {
|
||||
"py-[5px] mb-10": isSmallScreen
|
||||
} )}
|
||||
>
|
||||
<View className={classnames( "flex-row items-center mb-2" )}>
|
||||
<Heading2
|
||||
maxFontSizeMultiplier={1.5}
|
||||
testID="identify-text"
|
||||
className={classnames( "pl-[25px]", {
|
||||
"px-8 -mb-2 mt-2": isSmallScreen
|
||||
} )}
|
||||
>
|
||||
{t( "Identify-an-organism" )}
|
||||
</Heading2>
|
||||
<View className={classnames( "ml-auto pr-[12px]", {
|
||||
"pb-6": isSmallScreen
|
||||
} )}
|
||||
>
|
||||
<INatIconButton
|
||||
icon="close"
|
||||
color={String( colors?.darkGray )}
|
||||
size={19}
|
||||
onPress={async ( ) => {
|
||||
setHideHelpText( true );
|
||||
storage.set( HIDE_ADD_OBS_HELP_TEXT, true );
|
||||
}}
|
||||
accessibilityLabel={t( "Close" )}
|
||||
accessibilityHint={t( "Closes-new-observation-explanation" )}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<View className={classnames( "px-[23px]", {
|
||||
"px-[10px]": isSmallScreen
|
||||
} )}
|
||||
>
|
||||
{Object.keys( obsCreateItems )
|
||||
.filter( k => k !== "closeButton" )
|
||||
.map( k => {
|
||||
const item = obsCreateItems[k];
|
||||
return (
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
className={classnames( "flex-row items-center p-2 my-1", {
|
||||
"p-1": isSmallScreen
|
||||
} )}
|
||||
key={k}
|
||||
onPress={item.onPress}
|
||||
>
|
||||
<INatIcon
|
||||
name={item.icon}
|
||||
size={item.icon === "aicamera"
|
||||
? 30
|
||||
: 26}
|
||||
color={String(
|
||||
item.icon === "aicamera"
|
||||
? colors?.inatGreen
|
||||
: colors?.darkGray
|
||||
)}
|
||||
/>
|
||||
<Body3 maxFontSizeMultiplier={1.5} className="ml-[20px] shrink">
|
||||
{item.text}
|
||||
</Body3>
|
||||
</Pressable>
|
||||
);
|
||||
} )}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddObsModalHelp;
|
||||
@@ -1,4 +1,4 @@
|
||||
import AddObsButton from "components/AddObsModal/AddObsButton";
|
||||
import AddObsButton from "components/AddObsBottomSheet/AddObsButton";
|
||||
import {
|
||||
Body1,
|
||||
Body2,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// @flow
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import AddObsModal from "components/AddObsModal/AddObsModal";
|
||||
import AddObsBottomSheet from "components/AddObsBottomSheet/AddObsBottomSheet";
|
||||
import { AccountCreationCard } from "components/OnboardingModal/PivotCards";
|
||||
import {
|
||||
HeaderUser,
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
ViewWrapper
|
||||
} from "components/SharedComponents";
|
||||
import GradientButton from "components/SharedComponents/Buttons/GradientButton";
|
||||
import Modal from "components/SharedComponents/Modal";
|
||||
import {
|
||||
Pressable, View
|
||||
} from "components/styledComponents";
|
||||
@@ -77,15 +76,10 @@ const MyObservationsEmptySimple = ( { currentUser, isConnected, justFinishedSign
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<Modal
|
||||
showModal={showModal}
|
||||
<AddObsBottomSheet
|
||||
closeModal={( ) => setShowModal( false )}
|
||||
modal={(
|
||||
<AddObsModal
|
||||
closeModal={( ) => setShowModal( false )}
|
||||
navAndCloseModal={navAndCloseModal}
|
||||
/>
|
||||
)}
|
||||
hidden={!showModal}
|
||||
navAndCloseModal={navAndCloseModal}
|
||||
/>
|
||||
</ViewWrapper>
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ const PhotoSharing = ( ) => {
|
||||
const { data } = item;
|
||||
|
||||
// when sharing, we need to reset zustand like we do while
|
||||
// navigating through the AddObsModal
|
||||
// navigating through the AddObsBottomSheet
|
||||
resetObservationFlowSlice( );
|
||||
|
||||
const photoUris = data
|
||||
|
||||
@@ -18,7 +18,10 @@ const { width } = Dimensions.get( "window" );
|
||||
const marginOnWide = {
|
||||
marginHorizontal: width > 500
|
||||
? ( width - 500 ) / 2
|
||||
: 0
|
||||
: 0,
|
||||
borderTopLeftRadius: 24,
|
||||
borderTopRightRadius: 24,
|
||||
overflow: "hidden"
|
||||
};
|
||||
|
||||
// eslint-disable-next-line
|
||||
@@ -29,14 +32,15 @@ interface Props {
|
||||
hidden?: boolean;
|
||||
hideCloseButton?: boolean;
|
||||
headerText?: string;
|
||||
onLayout?: Function;
|
||||
onLayout?: ( event: object ) => void;
|
||||
// Callback when the user presses the close button or backdrop, not whenever the sheet
|
||||
// closes
|
||||
onPressClose?: Function;
|
||||
onPressClose?: () => void;
|
||||
snapPoints?: Array<string>;
|
||||
insideModal?: boolean;
|
||||
keyboardShouldPersistTaps?: string;
|
||||
testID?: string;
|
||||
additionalClasses?: string;
|
||||
}
|
||||
|
||||
const StandardBottomSheet = ( {
|
||||
@@ -49,6 +53,7 @@ const StandardBottomSheet = ( {
|
||||
snapPoints,
|
||||
insideModal,
|
||||
keyboardShouldPersistTaps = "never",
|
||||
additionalClasses,
|
||||
testID
|
||||
}: Props ): Node => {
|
||||
if ( snapPoints ) {
|
||||
@@ -115,21 +120,24 @@ const StandardBottomSheet = ( {
|
||||
"pt-7",
|
||||
insets.bottom > 0
|
||||
? "pb-7"
|
||||
: null
|
||||
: null,
|
||||
additionalClasses
|
||||
)}
|
||||
onLayout={onLayout}
|
||||
// Not ideal, but @gorhom/bottom-sheet components don't support
|
||||
// testID
|
||||
testID={testID}
|
||||
>
|
||||
<View className="mx-12 flex">
|
||||
<Heading4
|
||||
testID="bottom-sheet-header"
|
||||
className="w-full text-center"
|
||||
>
|
||||
{headerText}
|
||||
</Heading4>
|
||||
</View>
|
||||
{headerText && (
|
||||
<View className="mx-12 flex">
|
||||
<Heading4
|
||||
testID="bottom-sheet-header"
|
||||
className="w-full text-center"
|
||||
>
|
||||
{headerText}
|
||||
</Heading4>
|
||||
</View>
|
||||
)}
|
||||
{children}
|
||||
{!hideCloseButton && (
|
||||
<INatIconButton
|
||||
|
||||
@@ -228,9 +228,6 @@ Closes-explanation = Closes explanation
|
||||
# appear when you first install the app
|
||||
Closes-introduction = Closes introduction
|
||||
# Accessibility hint for button that closes the help that
|
||||
# appears when you start a new observation for the first time
|
||||
Closes-new-observation-explanation = Closes new observation explanation.
|
||||
Closes-new-observation-options = Closes new observation options.
|
||||
Closes-withdraw-id-sheet = Closes "Withdraw ID" sheet
|
||||
# Heading for a section that describes people and organizations that
|
||||
# collaborate with iNaturalist
|
||||
@@ -274,7 +271,7 @@ Couldnt-create-comment = Couldn't create comment
|
||||
Couldnt-create-identification-error = Couldn't create identification { $error }
|
||||
Couldnt-create-identification-unknown-error = Couldn't create identification, unknown error.
|
||||
CREATE-AN-ACCOUNT = CREATE AN ACCOUNT
|
||||
Create-an-observation-evidence = Create an observation with no evidence
|
||||
Create-observation-with-no-evidence = Create observation with no evidence
|
||||
DATA-QUALITY = DATA QUALITY
|
||||
DATA-QUALITY-ASSESSMENT = DATA QUALITY ASSESSMENT
|
||||
# Label for button that navigates users to the data quality screen
|
||||
@@ -563,6 +560,7 @@ Iconic-taxon-name = Iconic taxon name: { $iconicTaxon }
|
||||
ID-Suggestions = ID Suggestions
|
||||
# Short for: Identify with AI. Label for a button that will load identifications for a given photo/sound
|
||||
ID-WITH-AI = ID WITH AI
|
||||
ID-with-AI-Camera = ID with AI Camera
|
||||
# Identification Status
|
||||
ID-Withdrawn = ID Withdrawn
|
||||
IDENTIFICATION = IDENTIFICATION
|
||||
@@ -575,7 +573,6 @@ IDENTIFICATIONS-WITHOUT-NUMBER =
|
||||
}
|
||||
Identifiers = Identifiers
|
||||
Identifiers-View = Identifiers View
|
||||
Identify-an-organism = Identify an organism
|
||||
# Title of screen asking for permission to access the camera
|
||||
Identify-organisms-in-real-time-with-your-camera = Identify organisms in real time with your camera
|
||||
# Onboarding slides
|
||||
@@ -925,7 +922,6 @@ POTENTIAL-DISAGREEMENT = POTENTIAL DISAGREEMENT
|
||||
Potential-disagreement-description = <0>Is the evidence enough to confirm this is </0><1></1><0>?<0>
|
||||
Potential-disagreement-disagree = <0>No, but this is a member of </0><1></1>
|
||||
Potential-disagreement-unsure = <0>I don't know but I am sure this is </0><1></1>
|
||||
Press-and-hold-to-view-more-options = Press and hold to view more options
|
||||
Previous-observation = Previous observation
|
||||
# Accessibility label for a button that goes to the previous slide on onboarding cards
|
||||
Previous-slide = Previous slide
|
||||
@@ -1210,8 +1206,8 @@ Switches-to-tab = Switches to { $tab } tab.
|
||||
Sync-observations = Sync observations
|
||||
Syncing = Syncing...
|
||||
# Help text for the button that opens the multi-capture camera
|
||||
Take-multiple-photos-of-a-single-organism = Take multiple photos of a single organism
|
||||
Take-photo = Take photo
|
||||
Take-photos = Take photos
|
||||
# label in project requirements
|
||||
Taxa = Taxa
|
||||
TAXON = TAXON
|
||||
@@ -1279,7 +1275,7 @@ Unreviewed-observations-only = Unreviewed observations only
|
||||
Upload-Complete = Upload Complete
|
||||
Upload-in-progress = Upload in progress
|
||||
UPLOAD-NOW = UPLOAD NOW
|
||||
Upload-photos-from-your-photo-library = Upload multiple photos from your photo library
|
||||
Upload-photos = Upload photos
|
||||
Upload-Progress = Upload { $uploadProgress } percent complete
|
||||
UPLOAD-TO-INATURALIST = UPLOAD TO INATURALIST
|
||||
# Shows the number of observations a user can upload to iNat from my observations page
|
||||
@@ -1301,7 +1297,6 @@ Uploading-x-of-y-observations =
|
||||
*[other] Uploading { $currentUploadCount } of { $total } observations
|
||||
}
|
||||
Use-iNaturalist-to-identify-any-living-thing = Use iNaturalist to identify any living thing
|
||||
Use-iNaturalists-AI-Camera = Use iNaturalist's AI Camera to identify organisms in real time
|
||||
# Text for a button prompting the user to grant access to location
|
||||
USE-LOCATION = USE LOCATION
|
||||
Use-the-devices-other-camera = Use the device's other camera.
|
||||
|
||||
@@ -116,8 +116,6 @@
|
||||
"Close-search": "Close search",
|
||||
"Closes-explanation": "Closes explanation",
|
||||
"Closes-introduction": "Closes introduction",
|
||||
"Closes-new-observation-explanation": "Closes new observation explanation.",
|
||||
"Closes-new-observation-options": "Closes new observation options.",
|
||||
"Closes-withdraw-id-sheet": "Closes \"Withdraw ID\" sheet",
|
||||
"COLLABORATORS": "COLLABORATORS",
|
||||
"Collection-Project": "Collection Project",
|
||||
@@ -144,7 +142,7 @@
|
||||
"Couldnt-create-identification-error": "Couldn't create identification { $error }",
|
||||
"Couldnt-create-identification-unknown-error": "Couldn't create identification, unknown error.",
|
||||
"CREATE-AN-ACCOUNT": "CREATE AN ACCOUNT",
|
||||
"Create-an-observation-evidence": "Create an observation with no evidence",
|
||||
"Create-observation-with-no-evidence": "Create observation with no evidence",
|
||||
"DATA-QUALITY": "DATA QUALITY",
|
||||
"DATA-QUALITY-ASSESSMENT": "DATA QUALITY ASSESSMENT",
|
||||
"Data-Quality-Assessment": "Data Quality Assessment",
|
||||
@@ -315,13 +313,13 @@
|
||||
"Iconic-taxon-name": "Iconic taxon name: { $iconicTaxon }",
|
||||
"ID-Suggestions": "ID Suggestions",
|
||||
"ID-WITH-AI": "ID WITH AI",
|
||||
"ID-with-AI-Camera": "ID with AI Camera",
|
||||
"ID-Withdrawn": "ID Withdrawn",
|
||||
"IDENTIFICATION": "IDENTIFICATION",
|
||||
"Identification-options": "Identification options",
|
||||
"IDENTIFICATIONS-WITHOUT-NUMBER": "{ $count ->\n [one] IDENTIFICATION\n *[other] IDENTIFICATIONS\n}",
|
||||
"Identifiers": "Identifiers",
|
||||
"Identifiers-View": "Identifiers View",
|
||||
"Identify-an-organism": "Identify an organism",
|
||||
"Identify-organisms-in-real-time-with-your-camera": "Identify organisms in real time with your camera",
|
||||
"Identify-species-anywhere": "Identify species anywhere",
|
||||
"If-an-account-with-that-email-exists": "If an account with that email exists, we've sent password reset instructions to your email.",
|
||||
@@ -546,7 +544,6 @@
|
||||
"Potential-disagreement-description": "<0>Is the evidence enough to confirm this is </0><1></1><0>?<0>",
|
||||
"Potential-disagreement-disagree": "<0>No, but this is a member of </0><1></1>",
|
||||
"Potential-disagreement-unsure": "<0>I don't know but I am sure this is </0><1></1>",
|
||||
"Press-and-hold-to-view-more-options": "Press and hold to view more options",
|
||||
"Previous-observation": "Previous observation",
|
||||
"Previous-slide": "Previous slide",
|
||||
"Privacy-Policy": "Privacy Policy",
|
||||
@@ -762,8 +759,8 @@
|
||||
"Switches-to-tab": "Switches to { $tab } tab.",
|
||||
"Sync-observations": "Sync observations",
|
||||
"Syncing": "Syncing...",
|
||||
"Take-multiple-photos-of-a-single-organism": "Take multiple photos of a single organism",
|
||||
"Take-photo": "Take photo",
|
||||
"Take-photos": "Take photos",
|
||||
"Taxa": "Taxa",
|
||||
"TAXON": "TAXON",
|
||||
"TAXON-NAMES-DISPLAY": "TAXON NAMES DISPLAY",
|
||||
@@ -818,7 +815,7 @@
|
||||
"Upload-Complete": "Upload Complete",
|
||||
"Upload-in-progress": "Upload in progress",
|
||||
"UPLOAD-NOW": "UPLOAD NOW",
|
||||
"Upload-photos-from-your-photo-library": "Upload multiple photos from your photo library",
|
||||
"Upload-photos": "Upload photos",
|
||||
"Upload-Progress": "Upload { $uploadProgress } percent complete",
|
||||
"UPLOAD-TO-INATURALIST": "UPLOAD TO INATURALIST",
|
||||
"Upload-x-observations": "Upload { $count ->\n [one] 1 observation\n *[other] { $count } observations\n}",
|
||||
@@ -827,7 +824,6 @@
|
||||
"Uploading-x-of-y": "Uploading { $currentUploadCount } of { $total }",
|
||||
"Uploading-x-of-y-observations": "{ $total ->\n [one] Uploading { $currentUploadCount } observation\n *[other] Uploading { $currentUploadCount } of { $total } observations\n}",
|
||||
"Use-iNaturalist-to-identify-any-living-thing": "Use iNaturalist to identify any living thing",
|
||||
"Use-iNaturalists-AI-Camera": "Use iNaturalist's AI Camera to identify organisms in real time",
|
||||
"USE-LOCATION": "USE LOCATION",
|
||||
"Use-the-devices-other-camera": "Use the device's other camera.",
|
||||
"Use-the-iNaturalist-camera-to-see-real-time-identifications-and-take-photos": "Use the iNaturalist camera to see real-time identifications and take photos!",
|
||||
|
||||
@@ -228,9 +228,6 @@ Closes-explanation = Closes explanation
|
||||
# appear when you first install the app
|
||||
Closes-introduction = Closes introduction
|
||||
# Accessibility hint for button that closes the help that
|
||||
# appears when you start a new observation for the first time
|
||||
Closes-new-observation-explanation = Closes new observation explanation.
|
||||
Closes-new-observation-options = Closes new observation options.
|
||||
Closes-withdraw-id-sheet = Closes "Withdraw ID" sheet
|
||||
# Heading for a section that describes people and organizations that
|
||||
# collaborate with iNaturalist
|
||||
@@ -274,7 +271,7 @@ Couldnt-create-comment = Couldn't create comment
|
||||
Couldnt-create-identification-error = Couldn't create identification { $error }
|
||||
Couldnt-create-identification-unknown-error = Couldn't create identification, unknown error.
|
||||
CREATE-AN-ACCOUNT = CREATE AN ACCOUNT
|
||||
Create-an-observation-evidence = Create an observation with no evidence
|
||||
Create-observation-with-no-evidence = Create observation with no evidence
|
||||
DATA-QUALITY = DATA QUALITY
|
||||
DATA-QUALITY-ASSESSMENT = DATA QUALITY ASSESSMENT
|
||||
# Label for button that navigates users to the data quality screen
|
||||
@@ -563,6 +560,7 @@ Iconic-taxon-name = Iconic taxon name: { $iconicTaxon }
|
||||
ID-Suggestions = ID Suggestions
|
||||
# Short for: Identify with AI. Label for a button that will load identifications for a given photo/sound
|
||||
ID-WITH-AI = ID WITH AI
|
||||
ID-with-AI-Camera = ID with AI Camera
|
||||
# Identification Status
|
||||
ID-Withdrawn = ID Withdrawn
|
||||
IDENTIFICATION = IDENTIFICATION
|
||||
@@ -575,7 +573,6 @@ IDENTIFICATIONS-WITHOUT-NUMBER =
|
||||
}
|
||||
Identifiers = Identifiers
|
||||
Identifiers-View = Identifiers View
|
||||
Identify-an-organism = Identify an organism
|
||||
# Title of screen asking for permission to access the camera
|
||||
Identify-organisms-in-real-time-with-your-camera = Identify organisms in real time with your camera
|
||||
# Onboarding slides
|
||||
@@ -925,7 +922,6 @@ POTENTIAL-DISAGREEMENT = POTENTIAL DISAGREEMENT
|
||||
Potential-disagreement-description = <0>Is the evidence enough to confirm this is </0><1></1><0>?<0>
|
||||
Potential-disagreement-disagree = <0>No, but this is a member of </0><1></1>
|
||||
Potential-disagreement-unsure = <0>I don't know but I am sure this is </0><1></1>
|
||||
Press-and-hold-to-view-more-options = Press and hold to view more options
|
||||
Previous-observation = Previous observation
|
||||
# Accessibility label for a button that goes to the previous slide on onboarding cards
|
||||
Previous-slide = Previous slide
|
||||
@@ -1210,8 +1206,8 @@ Switches-to-tab = Switches to { $tab } tab.
|
||||
Sync-observations = Sync observations
|
||||
Syncing = Syncing...
|
||||
# Help text for the button that opens the multi-capture camera
|
||||
Take-multiple-photos-of-a-single-organism = Take multiple photos of a single organism
|
||||
Take-photo = Take photo
|
||||
Take-photos = Take photos
|
||||
# label in project requirements
|
||||
Taxa = Taxa
|
||||
TAXON = TAXON
|
||||
@@ -1279,7 +1275,7 @@ Unreviewed-observations-only = Unreviewed observations only
|
||||
Upload-Complete = Upload Complete
|
||||
Upload-in-progress = Upload in progress
|
||||
UPLOAD-NOW = UPLOAD NOW
|
||||
Upload-photos-from-your-photo-library = Upload multiple photos from your photo library
|
||||
Upload-photos = Upload photos
|
||||
Upload-Progress = Upload { $uploadProgress } percent complete
|
||||
UPLOAD-TO-INATURALIST = UPLOAD TO INATURALIST
|
||||
# Shows the number of observations a user can upload to iNat from my observations page
|
||||
@@ -1301,7 +1297,6 @@ Uploading-x-of-y-observations =
|
||||
*[other] Uploading { $currentUploadCount } of { $total } observations
|
||||
}
|
||||
Use-iNaturalist-to-identify-any-living-thing = Use iNaturalist to identify any living thing
|
||||
Use-iNaturalists-AI-Camera = Use iNaturalist's AI Camera to identify organisms in real time
|
||||
# Text for a button prompting the user to grant access to location
|
||||
USE-LOCATION = USE LOCATION
|
||||
Use-the-devices-other-camera = Use the device's other camera.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// @flow
|
||||
import classNames from "classnames";
|
||||
import AddObsButton from "components/AddObsModal/AddObsButton";
|
||||
import AddObsButton from "components/AddObsBottomSheet/AddObsButton";
|
||||
import { View } from "components/styledComponents";
|
||||
import type { Node } from "react";
|
||||
import React from "react";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { screen, userEvent } from "@testing-library/react-native";
|
||||
import AddObsButton from "components/AddObsModal/AddObsButton";
|
||||
import AddObsButton from "components/AddObsBottomSheet/AddObsButton";
|
||||
import i18next from "i18next";
|
||||
import React from "react";
|
||||
import { renderComponent } from "tests/helpers/render";
|
||||
@@ -48,8 +48,8 @@ const longPress = async ( ) => {
|
||||
};
|
||||
|
||||
const showNoEvidenceOption = ( ) => {
|
||||
const noEvidenceButton = screen.getByLabelText(
|
||||
i18next.t( "Observation-with-no-evidence" )
|
||||
const noEvidenceButton = screen.getByTestId(
|
||||
i18next.t( "observe-without-evidence-button" )
|
||||
);
|
||||
expect( noEvidenceButton ).toBeTruthy( );
|
||||
return noEvidenceButton;
|
||||
@@ -87,7 +87,7 @@ describe( "with advanced user layout", ( ) => {
|
||||
} );
|
||||
} );
|
||||
|
||||
it( "opens AddObsModal", async ( ) => {
|
||||
it( "opens AddObsBottomSheet", async ( ) => {
|
||||
renderComponent( <AddObsButton /> );
|
||||
await regularPress( );
|
||||
showNoEvidenceOption( );
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import { screen } from "@testing-library/react-native";
|
||||
import AddObsButton from "components/AddObsModal/AddObsButton";
|
||||
import AddObsButton from "components/AddObsBottomSheet/AddObsButton";
|
||||
import React from "react";
|
||||
import * as useCurrentUser from "sharedHooks/useCurrentUser";
|
||||
import { zustandStorage } from "stores/useStore";
|
||||
import factory from "tests/factory";
|
||||
import { renderComponent } from "tests/helpers/render";
|
||||
import setStoreStateLayout from "tests/helpers/setStoreStateLayout";
|
||||
|
||||
// Mock getCurrentRoute to return ObsList
|
||||
jest.mock( "navigation/navigationUtils", () => ( {
|
||||
@@ -14,8 +10,6 @@ jest.mock( "navigation/navigationUtils", () => ( {
|
||||
} )
|
||||
} ) );
|
||||
|
||||
const mockUser = factory( "LocalUser" );
|
||||
|
||||
jest.mock( "sharedHooks/useCurrentUser", () => ( {
|
||||
__esModule: true,
|
||||
default: () => undefined
|
||||
@@ -34,88 +28,4 @@ describe( "AddObsButton", () => {
|
||||
// Snapshot test
|
||||
expect( screen ).toMatchSnapshot();
|
||||
} );
|
||||
|
||||
it( "does not render tooltip in default state", () => {
|
||||
renderComponent( <AddObsButton /> );
|
||||
|
||||
const tooltipText = screen.queryByText(
|
||||
"Press and hold to view more options"
|
||||
);
|
||||
expect( tooltipText ).toBeFalsy();
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( "shows tooltip", () => {
|
||||
it( "to logged out users with 2 observations", async () => {
|
||||
zustandStorage.setItem( "numOfUserObservations", 2 );
|
||||
|
||||
renderComponent( <AddObsButton /> );
|
||||
|
||||
const tooltipText = await screen.findByText(
|
||||
"Press and hold to view more options"
|
||||
);
|
||||
expect( tooltipText ).toBeTruthy();
|
||||
} );
|
||||
|
||||
it( "to logged in users with less than 50 observations", async () => {
|
||||
zustandStorage.setItem( "numOfUserObservations", 2 );
|
||||
jest.spyOn( useCurrentUser, "default" ).mockImplementation( () => mockUser );
|
||||
|
||||
renderComponent( <AddObsButton /> );
|
||||
|
||||
// Temporarily disabled the tooltip for new users, as it is freezing the app in some cases.
|
||||
// const tooltipText = await screen.findByText(
|
||||
// "Press and hold to view more options"
|
||||
// );
|
||||
// expect( tooltipText ).toBeTruthy();
|
||||
} );
|
||||
|
||||
it( "to new users only after they dismissed the account creation card", async () => {
|
||||
zustandStorage.setItem( "numOfUserObservations", 1 );
|
||||
setStoreStateLayout( {
|
||||
justFinishedSignup: true
|
||||
} );
|
||||
|
||||
renderComponent( <AddObsButton /> );
|
||||
|
||||
const tooltipText = screen.queryByText(
|
||||
"Press and hold to view more options"
|
||||
);
|
||||
expect( tooltipText ).toBeFalsy();
|
||||
|
||||
setStoreStateLayout( {
|
||||
shownOnce: {
|
||||
"account-creation": true
|
||||
}
|
||||
} );
|
||||
|
||||
// Temporarily disabled the tooltip for new users, as it is freezing the app in some cases.
|
||||
// const tooltipTextAfter = await screen.findByText(
|
||||
// "Press and hold to view more options"
|
||||
// );
|
||||
// expect( tooltipTextAfter ).toBeTruthy();
|
||||
} );
|
||||
|
||||
it( "to logged in users with more than 50 observations after card dismissal", async () => {
|
||||
zustandStorage.setItem( "numOfUserObservations", 51 );
|
||||
|
||||
renderComponent( <AddObsButton /> );
|
||||
|
||||
const tooltipText = screen.queryByText(
|
||||
"Press and hold to view more options"
|
||||
);
|
||||
expect( tooltipText ).toBeFalsy();
|
||||
|
||||
setStoreStateLayout( {
|
||||
shownOnce: {
|
||||
"fifty-observation": true
|
||||
}
|
||||
} );
|
||||
|
||||
// Temporarily disabled the tooltip for new users, as it is freezing the app in some cases.
|
||||
// const tooltipTextAfter = await screen.findByText(
|
||||
// "Press and hold to view more options"
|
||||
// );
|
||||
// expect( tooltipTextAfter ).toBeTruthy();
|
||||
} );
|
||||
} );
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { render, screen } from "@testing-library/react-native";
|
||||
import AddObsModal from "components/AddObsModal/AddObsModal";
|
||||
import i18next from "i18next";
|
||||
import AddObsBottomSheet from "components/AddObsBottomSheet/AddObsBottomSheet";
|
||||
import React from "react";
|
||||
|
||||
// Make sure the mock is using a recent-ish version
|
||||
@@ -13,11 +12,11 @@ jest.mock( "react-native/Libraries/Utilities/Platform", ( ) => ( {
|
||||
}
|
||||
} ) );
|
||||
|
||||
describe( "AddObsModal", ( ) => {
|
||||
describe( "AddObsBottomSheet", ( ) => {
|
||||
it( "shows the AI camera button", async ( ) => {
|
||||
render( <AddObsModal closeModal={jest.fn( )} /> );
|
||||
const aiCameraButton = screen.getByLabelText(
|
||||
i18next.t( "AI-Camera" )
|
||||
render( <AddObsBottomSheet closeModal={jest.fn( )} /> );
|
||||
const aiCameraButton = screen.getByTestId(
|
||||
"aicamera-button"
|
||||
);
|
||||
expect( aiCameraButton ).toBeOnTheScreen();
|
||||
} );
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Separate tests for iOS 9. AddObsModal sets some OS-specific constants at
|
||||
// Separate tests for iOS 9. AddObsBottomSheet sets some OS-specific constants at
|
||||
// load time that can't be altered at runtime, so we're using a separate test
|
||||
// with a separate mock to control those load time values.
|
||||
import { render, screen } from "@testing-library/react-native";
|
||||
import AddObsModal from "components/AddObsModal/AddObsModal";
|
||||
import AddObsBottomSheet from "components/AddObsBottomSheet/AddObsBottomSheet";
|
||||
import i18next from "i18next";
|
||||
import React from "react";
|
||||
|
||||
@@ -16,9 +16,9 @@ jest.mock( "react-native/Libraries/Utilities/Platform", () => ( {
|
||||
}
|
||||
} ) );
|
||||
|
||||
describe( "AddObsModal in iOS 9", ( ) => {
|
||||
describe( "AddObsBottomSheet in iOS 9", ( ) => {
|
||||
it( "hides AI camera button on older devices", async ( ) => {
|
||||
render( <AddObsModal closeModal={jest.fn( )} /> );
|
||||
render( <AddObsBottomSheet closeModal={jest.fn( )} /> );
|
||||
const arCameraButton = screen.queryByLabelText(
|
||||
i18next.t( "AI-Camera" )
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user