Skip to content

Commit

Permalink
Merge branch 'main' into mob-336-match-screen-after-ai-camera
Browse files Browse the repository at this point in the history
  • Loading branch information
albullington committed Jan 8, 2025
2 parents c6ed3ce + 7ec14e9 commit 89d264d
Show file tree
Hide file tree
Showing 45 changed files with 1,055 additions and 172 deletions.
5 changes: 5 additions & 0 deletions __mocks__/vision-camera-plugin-inatvision.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
export const getPredictionsForImage = jest.fn( () => Promise.resolve( { predictions: [] } ) );
export const getPredictionsForLocation = jest.fn( () => Promise.resolve( { predictions: [] } ) );
export const removeLogListener = jest.fn( );
export const resetStoredResults = jest.fn( );
export const lookUpLocation = jest.fn( location => ( {
...location,
elevation: 12
} ) );
6 changes: 3 additions & 3 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1204,7 +1204,7 @@ PODS:
- VisionCamera/React (4.0.5):
- React-Core
- VisionCamera/FrameProcessors
- VisionCameraPluginInatVision (4.1.4):
- VisionCameraPluginInatVision (4.2.0):
- React-Core
- Yoga (1.14.0)

Expand Down Expand Up @@ -1526,7 +1526,7 @@ SPEC CHECKSUMS:
MMKV: f7d1d5945c8765f97f39c3d121f353d46735d801
MMKVCore: c04b296010fcb1d1638f2c69405096aac12f6390
Mute: 20135a96076f140cc82bfc8b810e2d6150d8ec7e
RCT-Folly: cd21f1661364f975ae76b3308167ad66b09f53f5
RCT-Folly: 7169b2b1c44399c76a47b5deaaba715eeeb476c0
RCTRequired: 77f73950d15b8c1a2b48ba5b79020c3003d1c9b5
RCTTypeSafety: ede1e2576424d89471ef553b2aed09fbbcc038e3
React: 2ddb437e599df2f1bffa9b248de2de4cfa0227f0
Expand Down Expand Up @@ -1610,7 +1610,7 @@ SPEC CHECKSUMS:
RNVectorIcons: 102cd20472bf0d7cd15443d43cd87f9c97228ac3
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
VisionCamera: f02de0b1b6b1516b327bd8215237a97e7386db8a
VisionCameraPluginInatVision: e9deb91ffd64c01e97b70329ef112a816f897de3
VisionCameraPluginInatVision: fcf3a3da9272def9014735257e065726c2d66d4f
Yoga: c716aea2ee01df6258550c7505fa61b248145ced

PODFILE CHECKSUM: eff4b75123af5d6680139a78c055b44ad37c269b
Expand Down
21 changes: 17 additions & 4 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@
"realm": "^12.6.2",
"sanitize-html": "^2.13.0",
"ts-jest": "^29.1.2",
"vision-camera-plugin-inatvision": "github:inaturalist/vision-camera-plugin-inatvision#8788e6d6718a4501056bad1f9ee5dbcfd354be92",
"vision-camera-plugin-inatvision": "github:inaturalist/vision-camera-plugin-inatvision#b905ff2b9ce1cf64797d600c6cd22fc7617b2389",
"zustand": "^4.5.2"
},
"devDependencies": {
Expand Down
5 changes: 0 additions & 5 deletions src/components/Camera/AICamera/AICamera.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ const AICamera = ( {
} = useRotation( );
const {
confidenceThreshold,
taxonomyRollupCutoff,
fps,
handleTaxaDetected,
modelLoaded,
Expand All @@ -97,7 +96,6 @@ const AICamera = ( {
setResult,
cropRatio,
setConfidenceThreshold,
setTaxonomyRollupCutoff,
setFPS,
setNumStoredResults,
setCropRatio
Expand Down Expand Up @@ -187,7 +185,6 @@ const AICamera = ( {
<FrameProcessorCamera
cameraRef={camera}
confidenceThreshold={confidenceThreshold}
taxonomyRollupCutoff={taxonomyRollupCutoff}
device={device}
fps={fps}
numStoredResults={numStoredResults}
Expand Down Expand Up @@ -265,7 +262,6 @@ const AICamera = ( {
<AICameraButtons
handleZoomButtonPress={handleZoomButtonPress}
confidenceThreshold={confidenceThreshold}
taxonomyRollupCutoff={taxonomyRollupCutoff}
cropRatio={cropRatio}
flipCamera={onFlipCamera}
fps={fps}
Expand All @@ -275,7 +271,6 @@ const AICamera = ( {
numStoredResults={numStoredResults}
rotatableAnimatedStyle={rotatableAnimatedStyle}
setConfidenceThreshold={setConfidenceThreshold}
setTaxonomyRollupCutoff={setTaxonomyRollupCutoff}
setCropRatio={setCropRatio}
setFPS={setFPS}
setNumStoredResults={setNumStoredResults}
Expand Down
6 changes: 0 additions & 6 deletions src/components/Camera/AICamera/AICameraButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ const isTablet = DeviceInfo.isTablet();
interface Props {
handleZoomButtonPress: ( _event: GestureResponderEvent ) => void;
confidenceThreshold?: number;
taxonomyRollupCutoff?: number;
cropRatio?: string;
flipCamera: ( _event: GestureResponderEvent ) => void;
fps?: number;
Expand All @@ -29,7 +28,6 @@ interface Props {
rotatableAnimatedStyle: ViewStyle;
// Those four are debug only so I don't bother with types
setConfidenceThreshold?: Function;
setTaxonomyRollupCutoff?: Function;
setCropRatio?: Function,
setFPS?: Function,
setNumStoredResults?: Function,
Expand All @@ -45,7 +43,6 @@ interface Props {
const AICameraButtons = ( {
handleZoomButtonPress,
confidenceThreshold,
taxonomyRollupCutoff,
cropRatio,
flipCamera,
fps,
Expand All @@ -55,7 +52,6 @@ const AICameraButtons = ( {
numStoredResults,
rotatableAnimatedStyle,
setConfidenceThreshold,
setTaxonomyRollupCutoff,
setCropRatio,
setFPS,
setNumStoredResults,
Expand Down Expand Up @@ -100,8 +96,6 @@ const AICameraButtons = ( {
<AIDebugButton
confidenceThreshold={confidenceThreshold}
setConfidenceThreshold={setConfidenceThreshold}
taxonomyRollupCutoff={taxonomyRollupCutoff}
setTaxonomyRollupCutoff={setTaxonomyRollupCutoff}
fps={fps}
setFPS={setFPS}
numStoredResults={numStoredResults}
Expand Down
11 changes: 0 additions & 11 deletions src/components/Camera/AICamera/AIDebugButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ import SliderControl from "./SliderControl";
const AIDebugButton = ( {
confidenceThreshold,
setConfidenceThreshold,
taxonomyRollupCutoff,
setTaxonomyRollupCutoff,
fps,
setFPS,
numStoredResults,
Expand Down Expand Up @@ -81,15 +79,6 @@ const AIDebugButton = ( {
precision={2}
step={0.05}
/>
<SliderControl
name="Taxonomy Rollup Cutoff"
min={0}
max={0.0001}
value={taxonomyRollupCutoff}
setValue={setTaxonomyRollupCutoff}
precision={5}
step={0.00001}
/>
<SliderControl
name="Center Crop Ratio (Android only)"
min={0.5}
Expand Down
24 changes: 14 additions & 10 deletions src/components/Camera/AICamera/FrameProcessorCamera.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,13 @@ type Props = {
onTaxaDetected: Function,
pinchToZoom?: Function,
takingPhoto: boolean,
taxonomyRollupCutoff?: number,
inactive?: boolean,
resetCameraOnFocus: Function,
userLocation?: Object // UserLocation | null
};

const DEFAULT_FPS = 1;
const DEFAULT_CONFIDENCE_THRESHOLD = 0.5;
const DEFAULT_TAXONOMY_CUTOFF_THRESHOLD = 0.0;
const DEFAULT_NUM_STORED_RESULTS = 4;
const DEFAULT_CROP_RATIO = 1.0;

Expand All @@ -73,7 +71,6 @@ const FrameProcessorCamera = ( {
onTaxaDetected,
pinchToZoom,
takingPhoto,
taxonomyRollupCutoff = DEFAULT_TAXONOMY_CUTOFF_THRESHOLD,
inactive,
resetCameraOnFocus,
userLocation
Expand Down Expand Up @@ -134,6 +131,14 @@ const FrameProcessorCamera = ( {

const patchedOrientationAndroid = orientationPatchFrameProcessor( deviceOrientation );
const patchedRunAsync = usePatchedRunAsync( );
const hasUserLocation = userLocation?.latitude != null && userLocation?.longitude != null;
// The vision-plugin has a function to look up the location of the user in a h3 gridded world
// unfortunately, I was not able to run this new function in the worklets directly,
// so we need to do this here before calling the useFrameProcessor hook.
// For predictions from file this function runs in the vision-plugin code directly.
const location = hasUserLocation
? InatVision.lookUpLocation( userLocation )
: null;
const frameProcessor = useFrameProcessor(
frame => {
"worklet";
Expand Down Expand Up @@ -162,16 +167,15 @@ const FrameProcessorCamera = ( {
modelPath,
taxonomyPath,
confidenceThreshold,
taxonomyRollupCutoff,
numStoredResults,
cropRatio,
patchedOrientationAndroid,
useGeomodel: !!userLocation,
useGeomodel: hasUserLocation,
geomodelPath,
location: {
latitude: userLocation?.latitude,
longitude: userLocation?.longitude,
elevation: userLocation?.altitude
latitude: location?.latitude,
longitude: location?.longitude,
elevation: location?.altitude
}
} );
const timeAfter = Date.now();
Expand All @@ -188,13 +192,13 @@ const FrameProcessorCamera = ( {
modelVersion,
confidenceThreshold,
takingPhoto,
taxonomyRollupCutoff,
patchedOrientationAndroid,
numStoredResults,
cropRatio,
lastTimestamp,
fps,
userLocation
hasUserLocation,
location
]
);

Expand Down
3 changes: 0 additions & 3 deletions src/components/Camera/AICamera/hooks/usePredictions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ const usePredictions = ( ) => {
const [resultTimestamp, setResultTimestamp] = useState<number | undefined>( undefined );
const [modelLoaded, setModelLoaded] = useState( false );
const [confidenceThreshold, setConfidenceThreshold] = useState( 0.5 );
const [taxonomyRollupCutoff, setTaxonomyRollupCutoff] = useState( 0.0 );
const [fps, setFPS] = useState( 1 );
const [numStoredResults, setNumStoredResults] = useState( 4 );
const [cropRatio, setCropRatio] = useState( 1 );
Expand Down Expand Up @@ -69,7 +68,6 @@ const usePredictions = ( ) => {

return {
confidenceThreshold,
taxonomyRollupCutoff,
fps,
handleTaxaDetected,
modelLoaded,
Expand All @@ -79,7 +77,6 @@ const usePredictions = ( ) => {
resultTimestamp,
setResult,
setConfidenceThreshold,
setTaxonomyRollupCutoff,
setFPS,
setNumStoredResults,
setCropRatio
Expand Down
26 changes: 16 additions & 10 deletions src/components/ObsEdit/BottomButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
ButtonBar
} from "components/SharedComponents";
import { View } from "components/styledComponents";
import type { Node } from "react";
import React from "react";
import { useTranslation } from "sharedHooks";
import { getShadow } from "styles/global";
Expand All @@ -14,8 +13,13 @@ const DROP_SHADOW = getShadow( {
shadowOpacity: 0.2
} );

export const UPLOAD = "upload";
export const SAVE = "save";

export type ButtonType = typeof SAVE | typeof UPLOAD | null;

type Props = {
buttonPressed: boolean,
buttonPressed: ButtonType,
canSaveOnly: boolean,
handlePress: Function,
loading: boolean,
Expand All @@ -34,16 +38,16 @@ const BottomButtons = ( {
showFocusedUploadButton,
showHalfOpacity,
wasSynced
}: Props ): Node => {
}: Props ) => {
const { t } = useTranslation( );

const isSaving = buttonPressed === "save" && loading;
const isSaving = buttonPressed === SAVE && loading;
const disabled = buttonPressed !== null;

const saveChangesButton = (
<Button
className="px-[25px]"
onPress={( ) => handlePress( "save" )}
onPress={( ) => handlePress( SAVE )}
testID="ObsEdit.saveChangesButton"
text={t( "SAVE-CHANGES" )}
level={showFocusedChangesButton
Expand All @@ -56,22 +60,21 @@ const BottomButtons = ( {

const saveButton = {
title: t( "SAVE" ),
onPress: ( ) => handlePress( "save" ),
onPress: ( ) => handlePress( SAVE ),
isPrimary: false,
testID: "ObsEdit.saveButton",
disabled,
level: "neutral",
loading: isSaving,
isPrimary: false,
className: "px-[25px]"
};

const uploadButton = {
title: t( "UPLOAD-NOW" ),
onPress: ( ) => handlePress( "upload" ),
onPress: ( ) => handlePress( UPLOAD ),
isPrimary: true,
testID: "ObsEdit.uploadButton",
loading: buttonPressed === "upload" && loading,
loading: buttonPressed === UPLOAD && loading,
level: showFocusedUploadButton
? "focus"
: "neutral",
Expand All @@ -84,7 +87,10 @@ const BottomButtons = ( {
const renderButtons = ( ) => {
if ( canSaveOnly ) {
return (
<ButtonBar buttonConfiguration={[saveButton]} />
<ButtonBar
buttonConfiguration={[{ ...saveButton, className: "grow" }]}
containerClass="p-[15px]"
/>
);
}
if ( wasSynced ) {
Expand Down
Loading

0 comments on commit 89d264d

Please sign in to comment.