Skip to content

Commit

Permalink
(chore) App Store Release (#154)
Browse files Browse the repository at this point in the history
* moving app.json to a .ts file so we can have build numbers

* updating root package.json to have a postinstall script to help our app with builds

* updating our app package.json to have an eas post install script, make sure we use the right packages, and remove autolinking

* updating workspace versions to a specific version

* reverting work done on app.json file--will auto incrament a different way

* app.json clean up

* automate app version management with EAS Build

* reverting package versions

* reverting package versions and yarn.lock

* fix: remove random images from face detection screen, fix image scaling issue, and clear results when photo is cleared. (#156)

* adding android build type

* adding info.plist text

* docs(changeset): Updating app features for store release.

* some scripts cleanup

* docs and eas

---------

Co-authored-by: Trevor Coleman <[email protected]>, Mazen Chami <[email protected]>
  • Loading branch information
mazenchami and Trevor Coleman <[email protected]>, Mazen Chami authored Jul 31, 2024
1 parent 91cd151 commit 70cd8da
Show file tree
Hide file tree
Showing 20 changed files with 447 additions and 130 deletions.
5 changes: 5 additions & 0 deletions .changeset/little-snakes-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"example-app": major
---

Updating app features for store release.
6 changes: 6 additions & 0 deletions .changeset/silly-ties-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@infinitered/react-native-mlkit-core": minor
"example-app": patch
---

RNMLKitImage will now scale image to fill container by default. scaleFactor no longer accepts numbers.
12 changes: 4 additions & 8 deletions apps/ExampleApp/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import 'ts-node/register'
import "ts-node/register"
import { ExpoConfig, ConfigContext } from "@expo/config"

/**
* Use ts-node here so we can use TypeScript for our Config Plugins
* and not have to compile them to JavaScript
*/
const {withSplashScreen} = require("./plugins/withSplashScreen")
const {withFlipperDisabled} = require("./plugins/withFlipperDisabled")
const { withSplashScreen } = require("./plugins/withSplashScreen")
const { withFlipperDisabled } = require("./plugins/withFlipperDisabled")
/**
* @param config ExpoConfig coming from the static config app.json if it exists
*
Expand All @@ -17,10 +17,6 @@ module.exports = ({ config }: ConfigContext): Partial<ExpoConfig> => {
const existingPlugins = config.plugins ?? []
return {
...config,
plugins: [
...existingPlugins,
withSplashScreen,
withFlipperDisabled,
],
plugins: [...existingPlugins, withSplashScreen, withFlipperDisabled],
}
}
20 changes: 14 additions & 6 deletions apps/ExampleApp/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
"name": "ExampleApp",
"displayName": "ExampleApp",
"expo": {
"name": "ExampleApp",
"slug": "ExampleApp",
"scheme": "exampleapp",
"name": "React Native MLKit",
"slug": "react-native-mlkit",
"owner": "infinitered",
"extra": {
"eas": {
"projectId": "4faa9328-e941-4395-879c-f558bf07e678"
}
},
"scheme": "react-native-mlkit",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/images/app-icon-all.png",
Expand All @@ -17,9 +23,7 @@
"fallbackToCacheTimeout": 0
},
"jsEngine": "hermes",
"assetBundlePatterns": [
"**/*"
],
"assetBundlePatterns": ["**/*"],
"android": {
"icon": "./assets/images/app-icon-android-legacy.png",
"package": "red.infinite.reactnativemlkit.example",
Expand All @@ -43,6 +47,10 @@
"tabletImage": "./assets/images/splash-logo-ios-tablet.png",
"resizeMode": "contain",
"backgroundColor": "#F4F2F1"
},
"infoPlist": {
"NSCameraUsageDescription": "This app uses the camera to help with facial detection.",
"NSPhotoLibraryUsageDescription": "This app uses the photo library to select images for Machine Learning purposes. i.e. Object and Image detection."
}
},
"web": {
Expand Down
47 changes: 18 additions & 29 deletions apps/ExampleApp/app/components/ImageSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react"
import { useEffect } from "react"
import { useEffect, useCallback } from "react"
import { View, ViewStyle, ActivityIndicator, TextStyle } from "react-native"
import { observer } from "mobx-react-lite"
import { Text } from "app/components/Text"
Expand All @@ -12,6 +12,7 @@ import { BoundingBox } from "@infinitered/react-native-mlkit-core"

export interface ImageSelectorProps {
onImageChange(image: SelectedImage): void
onImageClear(): void
onStatusChange(status: UseExampleImageStatus): void
status: "init" | "noPermissions" | "done" | "error" | "loading" | UseExampleImageStatus
statusMessage: string
Expand All @@ -26,6 +27,7 @@ export interface ImageSelectorProps {
export const ImageSelector = observer(function ImageSelector({
images,
onImageChange,
onImageClear,
onStatusChange,
status,
statusMessage,
Expand All @@ -34,13 +36,10 @@ export const ImageSelector = observer(function ImageSelector({
}: ImageSelectorProps) {
const [_status, _setStatus] = React.useState<UseExampleImageStatus>("init")

const { image, takePhoto, selectPhoto, nextPhoto, clearPhoto, categories } = useExampleImage(
_setStatus,
{
filter: images?.filter ?? "all",
groupBy: images?.groupBy ?? "none",
},
)
const { image, takePhoto, selectPhoto, clearPhoto } = useExampleImage({
filter: images?.filter ?? "all",
groupBy: images?.groupBy ?? "none",
})

useEffect(() => {
onStatusChange(_status)
Expand All @@ -50,6 +49,11 @@ export const ImageSelector = observer(function ImageSelector({
onImageChange(image)
}, [image, onImageChange])

const handleClearPhoto = useCallback(() => {
clearPhoto()
onImageClear()
}, [clearPhoto, onImageClear])

return (
<View style={$container}>
{!isLoading ? (
Expand All @@ -75,7 +79,12 @@ export const ImageSelector = observer(function ImageSelector({
</View>
<View>
{image ? (
<Button text={"Clear Photo"} onPress={clearPhoto} style={$button} disabled={isLoading} />
<Button
text={"Clear Photo"}
onPress={handleClearPhoto}
style={$button}
disabled={isLoading}
/>
) : (
<Button
text={"Select Photo"}
Expand All @@ -84,20 +93,6 @@ export const ImageSelector = observer(function ImageSelector({
disabled={isLoading}
/>
)}
<View style={$randomImageButtons}>
{categories.map((type) => (
<Button
disabled={isLoading}
key={`${type}-button`}
text={type}
onPress={async () => {
clearPhoto()
nextPhoto(type)
}}
style={[$button, $rowButton]}
/>
))}
</View>
</View>
</View>
)
Expand Down Expand Up @@ -132,10 +127,4 @@ const $status: ViewStyle = {
alignItems: "center",
}

const $randomImageButtons: ViewStyle = {
display: "flex",
flexDirection: "row",
justifyContent: "space-around",
}
const $button: ViewStyle = { backgroundColor: colors.palette.accent300, marginVertical: 8 }
const $rowButton: ViewStyle = { flexGrow: 1, marginHorizontal: 2 }
1 change: 1 addition & 0 deletions apps/ExampleApp/app/components/RNMLKitImageView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export const RNMLKitImageView = observer(function RNMLKitImageView({
boundingBoxes={boxes}
style={$image}
imageStyle={imageStyle}
contentFit={"contain"}
/>
<View style={$captionContainer}>
<Icon icon={"camera"} size={10} color={"rgba(0,0,0,0.9)"} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ interface FaceDetectionScreenProps
extends NativeStackScreenProps<AppStackScreenProps<"FaceDetection">> {}

const $button: ViewStyle = { backgroundColor: colors.palette.accent300, marginVertical: 8 }
const $rowButton: ViewStyle = { flexGrow: 1, marginHorizontal: 2 }

const $statusMessage: TextStyle = {
color: "rgba(0,0,0,0.6)",
Expand All @@ -30,35 +29,18 @@ const $status: ViewStyle = {
alignItems: "center",
}

const $photoButton: ViewStyle = {
display: "flex",
flexDirection: "row",
justifyContent: "space-around",
}

const FaceDetectionScreenComponent: FC<FaceDetectionScreenProps> = observer(
function FaceDetectionScreen() {
const navigation = useTypedNavigation<"FaceDetection">()

const {
image,
clearPhoto,
takePhoto,
selectPhoto,
nextPhoto,
categories,
// status: imageStatus,
} = useExampleImage({
groupBy: "face",
})
const { image, clearPhoto, takePhoto, selectPhoto } = useExampleImage()

const {
faces,
clearFaces,
status: faceDetectorStatus,
error: faceDetectorError,
} = useFacesInPhoto(image?.uri)

const boxes = useMemo(() => {
return faces.map((face, index) => {
return {
Expand Down Expand Up @@ -97,6 +79,7 @@ const FaceDetectionScreenComponent: FC<FaceDetectionScreenProps> = observer(
}
/>
<RNMLKitImageView image={image} onPress={image ? clearPhoto : takePhoto} boxes={boxes} />

<View style={$status}>
{faceDetectorStatus === "detecting" ? (
<ActivityIndicator />
Expand All @@ -105,24 +88,17 @@ const FaceDetectionScreenComponent: FC<FaceDetectionScreenProps> = observer(
)}
</View>
{image ? (
<Button text={"Clear Photo"} onPress={clearPhoto} style={$button} />
<Button
text={"Clear Photo"}
onPress={() => {
clearFaces()
clearPhoto()
}}
style={$button}
/>
) : (
<Button text={"Select Photo"} onPress={selectPhoto} style={$button} />
)}
<View style={$photoButton}>
{categories.map((category) => (
<Button
key={category}
text={category}
onPress={() => {
clearPhoto()
clearFaces()
nextPhoto(category)
}}
style={[$button, $rowButton]}
/>
))}
</View>
</Screen>
)
},
Expand Down
5 changes: 5 additions & 0 deletions apps/ExampleApp/app/screens/ImageLabelingScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ const ImageLabelingScreenComponent: FC<ImageLabelingScreenProps> = observer(
}
}, [bestGuess, image, status])

const clearResults = useCallback(() => {
setResult(null)
}, [])

return (
<Screen style={$root} preset="scroll" safeAreaEdges={["top", "bottom"]}>
<View>
Expand All @@ -114,6 +118,7 @@ const ImageLabelingScreenComponent: FC<ImageLabelingScreenProps> = observer(
</View>
<ImageSelector
onImageChange={handleImageChange}
onImageClear={clearResults}
onStatusChange={onStatusChange}
statusMessage={statusMessage}
status={status}
Expand Down
5 changes: 5 additions & 0 deletions apps/ExampleApp/app/screens/ObjectDetectionScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ export const ObjectDetectionScreenComponent: FC<ObjectDetectionScreenProps> = ob
detectLicensePlate()
}, [licensePlateModel, image, image?.uri, detectLicensePlate])

const clearResult = useCallback(() => {
setResult([])
}, [])

const statusMessage = React.useMemo(() => {
if (!image && status !== "init") {
setStatus("init")
Expand Down Expand Up @@ -109,6 +113,7 @@ export const ObjectDetectionScreenComponent: FC<ObjectDetectionScreenProps> = ob
<ImageSelector
boundingBoxes={boxes}
onImageChange={handleImageChange}
onImageClear={clearResult}
onStatusChange={onStatusChange}
statusMessage={statusMessage}
status={status}
Expand Down
7 changes: 5 additions & 2 deletions apps/ExampleApp/eas.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"cli": {
"version": ">= 3.15.1"
"version": ">= 3.15.1",
"appVersionSource": "remote"
},
"build": {
"development": {
Expand Down Expand Up @@ -32,7 +33,9 @@
"extends": "preview",
"ios": { "simulator": false }
},
"production": {}
"production": {
"autoIncrement": true
}
},
"submit": {
"production": {}
Expand Down
17 changes: 7 additions & 10 deletions apps/ExampleApp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,16 @@
"web": "npx expo start --web",
"bundle:web": "npx expo export --platform web",
"serve:web": "npx server dist",
"prebuild:clean": "npx expo prebuild --clean"
"prebuild:clean": "npx expo prebuild --clean",
"eas-build-post-install": "yarn -T run ci:build"
},
"dependencies": {
"@expo-google-fonts/space-grotesk": "^0.2.2",
"@expo/metro-runtime": "~3.2.1",
"@infinitered/react-native-mlkit-document-scanner": "^2.0.0",
"@infinitered/react-native-mlkit-face-detection": "^2.0.0",
"@infinitered/react-native-mlkit-image-labeling": "^2.0.0",
"@infinitered/react-native-mlkit-object-detection": "^2.0.0",
"@infinitered/react-native-mlkit-document-scanner": "workspace:^2.0.0",
"@infinitered/react-native-mlkit-face-detection": "workspace:^2.0.0",
"@infinitered/react-native-mlkit-image-labeling": "workspace:^2.0.0",
"@infinitered/react-native-mlkit-object-detection": "workspace:^2.0.0",
"@react-native-async-storage/async-storage": "1.23.1",
"@react-navigation/native": "^6.0.2",
"@react-navigation/native-stack": "^6.0.2",
Expand Down Expand Up @@ -91,6 +92,7 @@
"eslint-plugin-react": "7.30.0",
"eslint-plugin-react-native": "4.0.0",
"eslint-plugin-reactotron": "^0.1.2",
"expo-atlas": "^0.3.0",
"jest": "^29.2.1",
"jest-expo": "~51.0.1",
"patch-package": "6.4.7",
Expand Down Expand Up @@ -186,10 +188,5 @@
"space-before-function-paren": 0,
"reactotron/no-tron-in-production": "error"
}
},
"expo": {
"autolinking": {
"nativeModulesDir": "../../modules"
}
}
}
2 changes: 2 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
sidebar_position: 1
---

# React Native MLKit

<p align="center">
<img src="https://raw.githubusercontent.com/infinitered/react-native-mlkit/main/_art/ir_mlkit_logo.png" alt="IR MLKit Logo" width="400" />
<h2 align="center">RN MLKit Wrapper for Expo</h2>
Expand Down
Loading

0 comments on commit 70cd8da

Please sign in to comment.