Skip to content

Commit 2741dcd

Browse files
committed
Merge branch '@mlodyjesienin/example-app-ui' remote with local
2 parents 9bc6d65 + cd6c900 commit 2741dcd

14 files changed

Lines changed: 337 additions & 128 deletions

File tree

Lines changed: 122 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,133 @@
11
import { Drawer } from 'expo-router/drawer';
22
import ColorPalette from '../colors';
3-
import React from 'react';
3+
import React, { useState } from 'react';
4+
import { Text, StyleSheet, View } from 'react-native';
5+
6+
import {
7+
DrawerContentComponentProps,
8+
DrawerContentScrollView,
9+
DrawerItemList,
10+
} from '@react-navigation/drawer';
11+
import { GeneratingContext } from '../context';
12+
13+
interface CustomDrawerProps extends DrawerContentComponentProps {
14+
isGenerating: boolean;
15+
}
16+
17+
function CustomDrawerContent(props: CustomDrawerProps) {
18+
const { isGenerating, ...otherProps } = props;
19+
return (
20+
<DrawerContentScrollView {...otherProps}>
21+
{!isGenerating ? (
22+
<DrawerItemList {...otherProps} />
23+
) : (
24+
<View style={styles.centerContent}>
25+
<Text style={styles.mainText}>Model is generating...</Text>
26+
<Text style={styles.subText}>Interrupt before switching model</Text>
27+
</View>
28+
)}
29+
</DrawerContentScrollView>
30+
);
31+
}
432

533
export default function _layout() {
34+
const [isGenerating, setIsGenerating] = useState(false);
35+
636
return (
7-
<Drawer
8-
screenOptions={{
9-
drawerActiveTintColor: ColorPalette.primary,
10-
drawerInactiveTintColor: '#888',
11-
headerTintColor: ColorPalette.primary,
12-
headerTitleStyle: { color: ColorPalette.primary },
37+
<GeneratingContext
38+
value={{
39+
setGlobalGenerating: (newState: boolean) => {
40+
setIsGenerating(newState);
41+
},
1342
}}
1443
>
15-
<Drawer.Screen
16-
name="index"
17-
options={{
18-
drawerLabel: 'Menu',
19-
title: 'Main Menu',
44+
<Drawer
45+
drawerContent={(props) => (
46+
<CustomDrawerContent {...props} isGenerating={isGenerating} />
47+
)}
48+
screenOptions={{
49+
drawerActiveTintColor: ColorPalette.primary,
50+
drawerInactiveTintColor: '#888',
51+
headerTintColor: ColorPalette.primary,
2052
headerTitleStyle: { color: ColorPalette.primary },
2153
}}
22-
/>
23-
<Drawer.Screen
24-
name="classification/index"
25-
options={{
26-
drawerLabel: 'Classification',
27-
title: 'Classification',
28-
headerTitleStyle: { color: ColorPalette.primary },
29-
}}
30-
/>
31-
<Drawer.Screen
32-
name="image_segmentation/index"
33-
options={{
34-
drawerLabel: 'Image Segmentation',
35-
title: 'Image Segmentation',
36-
headerTitleStyle: { color: ColorPalette.primary },
37-
}}
38-
/>
39-
<Drawer.Screen
40-
name="object_detection/index"
41-
options={{
42-
drawerLabel: 'Object Detection',
43-
title: 'Object Detection',
44-
headerTitleStyle: { color: ColorPalette.primary },
45-
}}
46-
/>
47-
<Drawer.Screen
48-
name="ocr/index"
49-
options={{
50-
drawerLabel: 'OCR',
51-
title: 'OCR',
52-
headerTitleStyle: { color: ColorPalette.primary },
53-
}}
54-
/>
55-
<Drawer.Screen
56-
name="ocr_vertical/index"
57-
options={{
58-
drawerLabel: 'OCR Vertical',
59-
title: 'Vertical OCR',
60-
headerTitleStyle: { color: ColorPalette.primary },
61-
}}
62-
/>
63-
<Drawer.Screen
64-
name="style_transfer/index"
65-
options={{
66-
drawerLabel: 'Style Transfer',
67-
title: 'Style Transfer',
68-
headerTitleStyle: { color: ColorPalette.primary },
69-
}}
70-
/>
71-
</Drawer>
54+
>
55+
<Drawer.Screen
56+
name="classification/index"
57+
options={{
58+
drawerLabel: 'Classification',
59+
title: 'Classification',
60+
headerTitleStyle: { color: ColorPalette.primary },
61+
}}
62+
/>
63+
<Drawer.Screen
64+
name="image_segmentation/index"
65+
options={{
66+
drawerLabel: 'Image Segmentation',
67+
title: 'Image Segmentation',
68+
headerTitleStyle: { color: ColorPalette.primary },
69+
}}
70+
/>
71+
<Drawer.Screen
72+
name="object_detection/index"
73+
options={{
74+
drawerLabel: 'Object Detection',
75+
title: 'Object Detection',
76+
headerTitleStyle: { color: ColorPalette.primary },
77+
}}
78+
/>
79+
<Drawer.Screen
80+
name="ocr/index"
81+
options={{
82+
drawerLabel: 'OCR',
83+
title: 'OCR',
84+
headerTitleStyle: { color: ColorPalette.primary },
85+
}}
86+
/>
87+
<Drawer.Screen
88+
name="ocr_vertical/index"
89+
options={{
90+
drawerLabel: 'OCR Vertical',
91+
title: 'Vertical OCR',
92+
headerTitleStyle: { color: ColorPalette.primary },
93+
}}
94+
/>
95+
<Drawer.Screen
96+
name="style_transfer/index"
97+
options={{
98+
drawerLabel: 'Style Transfer',
99+
title: 'Style Transfer',
100+
headerTitleStyle: { color: ColorPalette.primary },
101+
}}
102+
/>
103+
<Drawer.Screen
104+
name="index"
105+
options={{
106+
drawerLabel: () => null,
107+
title: 'Main Menu',
108+
drawerItemStyle: { display: 'none' },
109+
}}
110+
/>
111+
</Drawer>
112+
</GeneratingContext>
72113
);
73114
}
115+
116+
const styles = StyleSheet.create({
117+
centerContent: {
118+
flex: 1,
119+
justifyContent: 'center',
120+
alignItems: 'center',
121+
padding: 20,
122+
},
123+
mainText: {
124+
fontSize: 18,
125+
fontWeight: 'bold',
126+
marginBottom: 10,
127+
color: ColorPalette.primary,
128+
},
129+
subText: {
130+
fontSize: 14,
131+
color: ColorPalette.strongPrimary,
132+
},
133+
});

apps/computer-vision/app/classification/index.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
import { useState } from 'react';
21
import Spinner from 'react-native-loading-spinner-overlay';
32
import { getImage } from '../../utils';
43
import { useClassification, EFFICIENTNET_V2_S } from 'react-native-executorch';
54
import { View, StyleSheet, Image, Text, ScrollView } from 'react-native';
65
import { BottomBar } from '../../components/BottomBar';
6+
import React, { useContext, useEffect, useState } from 'react';
7+
import { GeneratingContext } from '../../context';
8+
import ScreenWrapper from '../../screenWrapper';
79

810
export default function ClassificationScreen() {
911
const [results, setResults] = useState<{ label: string; score: number }[]>(
@@ -14,6 +16,10 @@ export default function ClassificationScreen() {
1416
const model = useClassification({
1517
modelSource: EFFICIENTNET_V2_S,
1618
});
19+
const { setGlobalGenerating } = useContext(GeneratingContext);
20+
useEffect(() => {
21+
setGlobalGenerating(model.isGenerating);
22+
}, [model.isGenerating, setGlobalGenerating]);
1723

1824
const handleCameraPress = async (isCamera: boolean) => {
1925
const image = await getImage(isCamera);
@@ -48,7 +54,7 @@ export default function ClassificationScreen() {
4854
);
4955
}
5056
return (
51-
<>
57+
<ScreenWrapper>
5258
<View style={styles.imageContainer}>
5359
<Image
5460
style={styles.image}
@@ -77,7 +83,7 @@ export default function ClassificationScreen() {
7783
handleCameraPress={handleCameraPress}
7884
runForward={runForward}
7985
/>
80-
</>
86+
</ScreenWrapper>
8187
);
8288
}
8389

apps/computer-vision/app/image_segmentation/index.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ import {
1414
ColorType,
1515
} from '@shopify/react-native-skia';
1616
import { View, StyleSheet, Image } from 'react-native';
17-
import { useState } from 'react';
17+
import React, { useContext, useEffect, useState } from 'react';
18+
import { GeneratingContext } from '../../context';
19+
import ScreenWrapper from '../../screenWrapper';
1820

1921
const width = 224;
2022
const height = 224;
@@ -62,6 +64,10 @@ export default function ImageSegmentationScreen() {
6264
const model = useImageSegmentation({
6365
modelSource: DEEPLAB_V3_RESNET50,
6466
});
67+
const { setGlobalGenerating } = useContext(GeneratingContext);
68+
useEffect(() => {
69+
setGlobalGenerating(model.isGenerating);
70+
}, [model.isGenerating, setGlobalGenerating]);
6571
const [imageUri, setImageUri] = useState('');
6672

6773
const handleCameraPress = async (isCamera: boolean) => {
@@ -118,7 +124,7 @@ export default function ImageSegmentationScreen() {
118124
}
119125

120126
return (
121-
<>
127+
<ScreenWrapper>
122128
<View style={styles.imageCanvasContainer}>
123129
<View style={styles.imageContainer}>
124130
<Image
@@ -150,7 +156,7 @@ export default function ImageSegmentationScreen() {
150156
handleCameraPress={handleCameraPress}
151157
runForward={runForward}
152158
/>
153-
</>
159+
</ScreenWrapper>
154160
);
155161
}
156162

apps/computer-vision/app/object_detection/index.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { useState } from 'react';
21
import Spinner from 'react-native-loading-spinner-overlay';
32
import { BottomBar } from '../../components/BottomBar';
43
import { getImage } from '../../utils';
@@ -9,6 +8,9 @@ import {
98
} from 'react-native-executorch';
109
import { View, StyleSheet, Image } from 'react-native';
1110
import ImageWithBboxes from '../../components/ImageWithBboxes';
11+
import React, { useContext, useEffect, useState } from 'react';
12+
import { GeneratingContext } from '../../context';
13+
import ScreenWrapper from '../../screenWrapper';
1214

1315
export default function ObjectDetectionScreen() {
1416
const [imageUri, setImageUri] = useState('');
@@ -21,6 +23,10 @@ export default function ObjectDetectionScreen() {
2123
const ssdLite = useObjectDetection({
2224
modelSource: SSDLITE_320_MOBILENET_V3_LARGE,
2325
});
26+
const { setGlobalGenerating } = useContext(GeneratingContext);
27+
useEffect(() => {
28+
setGlobalGenerating(ssdLite.isGenerating);
29+
}, [ssdLite.isGenerating, setGlobalGenerating]);
2430

2531
const handleCameraPress = async (isCamera: boolean) => {
2632
const image = await getImage(isCamera);
@@ -57,7 +63,7 @@ export default function ObjectDetectionScreen() {
5763
}
5864

5965
return (
60-
<>
66+
<ScreenWrapper>
6167
<View style={styles.imageContainer}>
6268
<View style={styles.image}>
6369
{imageUri && imageDimensions?.width && imageDimensions?.height ? (
@@ -82,7 +88,7 @@ export default function ObjectDetectionScreen() {
8288
handleCameraPress={handleCameraPress}
8389
runForward={runForward}
8490
/>
85-
</>
91+
</ScreenWrapper>
8692
);
8793
}
8894

apps/computer-vision/app/ocr/index.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import {
99
useOCR,
1010
} from 'react-native-executorch';
1111
import { View, StyleSheet, Image, Text, ScrollView } from 'react-native';
12-
import { useState } from 'react';
1312
import ImageWithBboxes2 from '../../components/ImageWithOCRBboxes';
13+
import React, { useContext, useEffect, useState } from 'react';
14+
import { GeneratingContext } from '../../context';
15+
import ScreenWrapper from '../../screenWrapper';
1416

1517
export default function OCRScreen() {
1618
const [imageUri, setImageUri] = useState('');
@@ -29,6 +31,10 @@ export default function OCRScreen() {
2931
},
3032
language: 'en',
3133
});
34+
const { setGlobalGenerating } = useContext(GeneratingContext);
35+
useEffect(() => {
36+
setGlobalGenerating(model.isGenerating);
37+
}, [model.isGenerating, setGlobalGenerating]);
3238

3339
const handleCameraPress = async (isCamera: boolean) => {
3440
const image = await getImage(isCamera);
@@ -62,7 +68,7 @@ export default function OCRScreen() {
6268
}
6369

6470
return (
65-
<>
71+
<ScreenWrapper>
6672
<View style={styles.container}>
6773
<View style={styles.imageContainer}>
6874
{imageUri && imageDimensions?.width && imageDimensions?.height ? (
@@ -100,7 +106,7 @@ export default function OCRScreen() {
100106
handleCameraPress={handleCameraPress}
101107
runForward={runForward}
102108
/>
103-
</>
109+
</ScreenWrapper>
104110
);
105111
}
106112

0 commit comments

Comments
 (0)