tuto-react-native-expo/app/home.tsx
2026-05-07 12:55:15 +02:00

219 lines
No EOL
4.8 KiB
TypeScript

//npx expo install expo-location expo-camera
import {
CameraView,
useCameraPermissions,
} from "expo-camera";
import React, { useRef, useState } from "react";
import {
ActivityIndicator,
Alert,
Image,
Linking,
StyleSheet,
Text,
TouchableOpacity,
View,
} from "react-native";
export default function App() {
const cameraRef = useRef(null);
const [statusText, setStatusText] = useState("Permission non demandée");
const [loading, setLoading] = useState(false);
const [cameraVisible, setCameraVisible] = useState(false);
const [photoUri, setPhotoUri] = useState(null);
const [permission, requestPermission] =
useCameraPermissions();
const openSettings = () => {
Linking.openSettings();
};
const openCamera = async () => {
try {
setLoading(true);
setStatusText("Demande de permission caméra...");
const result = await requestPermission();
if (!result.granted) {
if (result.canAskAgain === false) {
Alert.alert(
"Permission bloquée",
"La caméra doit être activée dans les paramètres.",
[
{ text: "Annuler", style: "cancel" },
{ text: "Paramètres", onPress: openSettings },
]
);
} else {
Alert.alert(
"Permission refusée",
"Impossible d'utiliser la caméra."
);
}
setStatusText("Permission caméra refusée");
return;
}
setPhotoUri(null);
setCameraVisible(true);
setStatusText("Caméra autorisée");
} catch (e) {
setStatusText("Erreur lors de la demande caméra");
} finally {
setLoading(false);
}
};
const takePhoto = async () => {
try {
if (!cameraRef.current) {
Alert.alert("Erreur", "La caméra n'est pas encore prête.");
return;
}
setLoading(true);
setStatusText("Prise de photo...");
const photo = await cameraRef.current.takePictureAsync();
if (!photo || !photo.uri) {
Alert.alert("Erreur", "Aucune photo obtenue.");
return;
}
setPhotoUri(photo.uri);
setCameraVisible(false);
setStatusText("Photo prise");
} catch (e) {
setStatusText("Erreur lors de la prise de photo");
} finally {
setLoading(false);
}
};
const closeCamera = () => {
setCameraVisible(false);
setStatusText("Caméra fermée");
};
if (cameraVisible) {
return (
<View style={styles.cameraContainer}>
<CameraView
ref={cameraRef}
style={styles.camera}
facing="back"
/>
<View style={styles.cameraControls}>
<TouchableOpacity style={styles.secondaryButton} onPress={closeCamera}>
<Text style={styles.buttonText}>Fermer</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={takePhoto}>
<Text style={styles.buttonText}>Prendre une photo</Text>
</TouchableOpacity>
</View>
</View>
);
}
return (
<View style={styles.container}>
<Text style={styles.title}>TP permissions Expo</Text>
<TouchableOpacity style={styles.button} onPress={openCamera}>
<Text style={styles.buttonText}>Ouvrir la caméra</Text>
</TouchableOpacity>
{loading ? <ActivityIndicator size="large" /> : null}
<Text style={styles.status}>{statusText}</Text>
{photoUri ? (
<View style={styles.photoBox}>
<Text style={styles.subtitle}>Photo prise :</Text>
<Image source={{ uri: photoUri }} style={styles.photo} />
</View>
) : null}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
padding: 20,
backgroundColor: "#fff",
},
title: {
fontSize: 24,
fontWeight: "bold",
marginBottom: 20,
textAlign: "center",
},
subtitle: {
fontWeight: "bold",
marginBottom: 10,
},
button: {
backgroundColor: "#2563eb",
padding: 14,
borderRadius: 8,
marginBottom: 12,
},
secondaryButton: {
backgroundColor: "#666",
padding: 14,
borderRadius: 8,
marginBottom: 12,
},
buttonText: {
color: "#fff",
textAlign: "center",
fontWeight: "bold",
},
status: {
textAlign: "center",
marginVertical: 20,
},
box: {
padding: 16,
borderWidth: 1,
borderColor: "#ccc",
borderRadius: 8,
marginBottom: 20,
},
photoBox: {
marginTop: 10,
alignItems: "center",
},
photo: {
width: 250,
height: 250,
borderRadius: 8,
borderWidth: 1,
borderColor: "#ccc",
},
cameraContainer: {
flex: 1,
backgroundColor: "#000",
},
camera: {
flex: 1,
},
cameraControls: {
position: "absolute",
bottom: 40,
left: 20,
right: 20,
},
});