@@ -10,6 +10,7 @@ import { useUser } from './_context';
1010import { apiService , API_BASE_URL } from '../services/api' ;
1111
1212interface PredictionResult {
13+ success ?: true ;
1314 food_name : string ;
1415 confidence : number ;
1516 calories : number ;
@@ -33,12 +34,21 @@ interface PredictionResult {
3334 has_wheat : boolean ;
3435}
3536
37+ /** Returned when confidence is below threshold (e.g. unclear photo or non-food). */
38+ interface LowConfidenceResponse {
39+ success : false ;
40+ reason : 'low_confidence' ;
41+ confidence : number ;
42+ message : string ;
43+ }
44+
3645export default function ScanScreen ( ) {
3746
3847 const [ loading , setLoading ] = useState ( false ) ;
3948 const [ modalVisible , setModalVisible ] = useState ( false ) ;
4049 const [ selectedImage , setSelectedImage ] = useState < string | null > ( null ) ;
4150 const [ prediction , setPrediction ] = useState < PredictionResult | null > ( null ) ;
51+ const [ lowConfidenceMessage , setLowConfidenceMessage ] = useState < string | null > ( null ) ;
4252 const [ isBackPressed , setIsBackPressed ] = useState ( false ) ;
4353 const [ isLoginLogoutPressed , setIsLoginLogoutPressed ] = useState ( false ) ;
4454 const [ isUploadPhotoPressed , setIsUploadPhotoPressed ] = useState ( false ) ;
@@ -356,8 +366,9 @@ export default function ScanScreen() {
356366 if ( ! result . canceled && result . assets [ 0 ] ) {
357367
358368 setSelectedImage ( result . assets [ 0 ] . uri ) ;
359- // Clear previous prediction
369+ // Clear previous prediction and low-confidence message
360370 setPrediction ( null ) ;
371+ setLowConfidenceMessage ( null ) ;
361372 }
362373 } catch ( err ) {
363374 console . error ( 'Error picking image:' , err ) ;
@@ -387,6 +398,7 @@ export default function ScanScreen() {
387398 if ( ! result . canceled && result . assets [ 0 ] ) {
388399 setSelectedImage ( result . assets [ 0 ] . uri ) ;
389400 setPrediction ( null ) ;
401+ setLowConfidenceMessage ( null ) ;
390402 }
391403 } catch ( err ) {
392404 console . error ( 'Error taking photo:' , err ) ;
@@ -409,7 +421,17 @@ export default function ScanScreen() {
409421 try {
410422 const result = await apiService . predictFood ( selectedImage ) ;
411423 console . log ( 'Prediction result received:' , result ) ;
412- setPrediction ( result ) ;
424+
425+ const lowConf = result as LowConfidenceResponse ;
426+ if ( lowConf . success === false && lowConf . reason === 'low_confidence' ) {
427+ setLowConfidenceMessage ( lowConf . message ) ;
428+ setPrediction ( null ) ;
429+ Alert . alert ( 'Please retake the photo' , lowConf . message , [ { text : 'OK' } ] ) ;
430+ return ;
431+ }
432+
433+ setLowConfidenceMessage ( null ) ;
434+ setPrediction ( result as PredictionResult ) ;
413435 } catch ( err : any ) {
414436 console . error ( 'Prediction error:' , err ) ;
415437 Alert . alert ( 'Error' , err . response ?. data ?. error || 'Failed to predict food. Please try again.' ) ;
@@ -531,6 +553,16 @@ export default function ScanScreen() {
531553 </ Text >
532554 ) }
533555
556+ { /* Display message when confidence was too low (e.g. unclear or non-food image) */ }
557+ { lowConfidenceMessage && (
558+ < View id = "lowConfidenceBanner" style = { styles . lowConfidenceBanner } >
559+ < Text style = { styles . lowConfidenceTitle } > No food detected</ Text >
560+ < Text style = { styles . lowConfidenceMessage } >
561+ We couldn't detect any food in this photo. Please take a clear photo of the food item.
562+ </ Text >
563+ </ View >
564+ ) }
565+
534566 { /* Display information about the selected food item */ }
535567 { prediction && (
536568 < View id = "foodItemOuterView" style = { styles . selectedFoodItemContainer } >
0 commit comments