305 lines
8.3 KiB
JavaScript
305 lines
8.3 KiB
JavaScript
import React, { useState, useCallback, useEffect } from "react";
|
|
import { View, StyleSheet, Image, ScrollView } from "react-native";
|
|
import { Title } from "react-native-paper";
|
|
import { Ionicons } from "@expo/vector-icons";
|
|
import {
|
|
permissionsActions,
|
|
usePermissionsState,
|
|
permissionWizardActions,
|
|
} from "~/stores";
|
|
import { useTheme } from "~/theme";
|
|
import openSettings from "~/lib/native/openSettings";
|
|
|
|
import requestPermissionPhoneCall from "~/permissions/requestPermissionPhoneCall";
|
|
import requestPermissionFcm from "~/permissions/requestPermissionFcm";
|
|
import requestPermissionLocationForeground from "~/permissions/requestPermissionLocationForeground";
|
|
import CustomButton from "~/components/CustomButton";
|
|
import Text from "~/components/Text";
|
|
|
|
const Welcome = () => {
|
|
const [requesting, setRequesting] = useState(false);
|
|
const [hasAttempted, setHasAttempted] = useState(false);
|
|
const [hasRetried, setHasRetried] = useState(false);
|
|
const permissions = usePermissionsState([
|
|
"phoneCall",
|
|
"fcm",
|
|
"locationForeground",
|
|
]);
|
|
const theme = useTheme();
|
|
|
|
const handleNext = useCallback(() => {
|
|
permissionWizardActions.setCurrentStep("hero");
|
|
}, []);
|
|
|
|
const handleRequestPermissions = useCallback(async () => {
|
|
setRequesting(true);
|
|
try {
|
|
const phoneCall = await requestPermissionPhoneCall();
|
|
const fcm = await requestPermissionFcm();
|
|
const location = await requestPermissionLocationForeground();
|
|
|
|
permissionsActions.setPhoneCall(phoneCall);
|
|
permissionsActions.setFcm(fcm);
|
|
permissionsActions.setLocationForeground(location);
|
|
|
|
if (phoneCall && fcm && location) {
|
|
permissionWizardActions.setBasicPermissionsGranted(true);
|
|
permissionWizardActions.setCurrentStep("hero");
|
|
}
|
|
} catch (error) {
|
|
console.error("Error requesting permissions:", error);
|
|
}
|
|
setRequesting(false);
|
|
setHasAttempted(true);
|
|
}, []);
|
|
|
|
const handleRetry = useCallback(async () => {
|
|
await handleRequestPermissions();
|
|
setHasRetried(true);
|
|
}, [handleRequestPermissions]);
|
|
|
|
const allGranted =
|
|
permissions.phoneCall && permissions.fcm && permissions.locationForeground;
|
|
|
|
useEffect(() => {
|
|
if (hasAttempted && allGranted) {
|
|
handleNext();
|
|
}
|
|
}, [hasAttempted, allGranted, handleNext]);
|
|
|
|
const renderWarnings = () => {
|
|
const warnings = [];
|
|
if (!permissions.phoneCall) {
|
|
warnings.push(
|
|
"Sans la permission d'appel téléphonique, vous ne pourrez pas contacter rapidement les secours en cas de besoin.",
|
|
);
|
|
}
|
|
if (!permissions.fcm) {
|
|
warnings.push(
|
|
"Sans les notifications, vous ne serez pas alerté en temps réel des situations d'urgence à proximité ou si vos proches ont besoin d'aide.",
|
|
);
|
|
}
|
|
if (!permissions.locationForeground) {
|
|
warnings.push(
|
|
"Sans la localisation, vous ne pourrez pas être guidé vers les personnes ayant besoin d'aide.",
|
|
);
|
|
}
|
|
return warnings.map((warning, index) => (
|
|
<Text key={index} style={[styles.warning, { color: theme.colors.error }]}>
|
|
<Ionicons name="warning" size={16} /> {warning}
|
|
</Text>
|
|
));
|
|
};
|
|
|
|
const renderButton = () => {
|
|
if (!hasAttempted) {
|
|
return (
|
|
<CustomButton
|
|
mode="contained"
|
|
onPress={handleRequestPermissions}
|
|
loading={requesting}
|
|
>
|
|
J'accorde les permissions
|
|
</CustomButton>
|
|
);
|
|
}
|
|
|
|
if (allGranted) {
|
|
return (
|
|
<CustomButton mode="contained" onPress={handleNext}>
|
|
Suivant
|
|
</CustomButton>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<CustomButton mode="contained" onPress={handleNext}>
|
|
Ignorer
|
|
</CustomButton>
|
|
<CustomButton
|
|
mode="contained"
|
|
onPress={handleRetry}
|
|
color={theme.colors.secondary}
|
|
>
|
|
Réessayer d'accorder les permissions
|
|
</CustomButton>
|
|
{hasRetried && (
|
|
<>
|
|
<Text
|
|
style={[
|
|
styles.settingsHint,
|
|
{ color: theme.colors.onSurfaceVariant },
|
|
]}
|
|
>
|
|
Si les permissions ne sont pas accordées, vous devez les activer
|
|
manuellement dans les paramètres de votre téléphone.
|
|
</Text>
|
|
<CustomButton mode="outlined" onPress={openSettings}>
|
|
Paramètres
|
|
</CustomButton>
|
|
</>
|
|
)}
|
|
</>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<View
|
|
style={[styles.container, { backgroundColor: theme.colors.background }]}
|
|
>
|
|
<ScrollView style={styles.scrollView}>
|
|
<View style={styles.content}>
|
|
<Image
|
|
source={require("~/assets/img/logo.png")}
|
|
style={styles.titleImage}
|
|
/>
|
|
<Title style={[styles.title, { color: theme.colors.primary }]}>
|
|
<Text>Alerte-Secours</Text>
|
|
{"\n"}
|
|
<Text style={styles.subtitle}>Toujours prêts !</Text>
|
|
</Title>
|
|
|
|
<Text
|
|
style={[
|
|
styles.description,
|
|
{ color: theme.colors.onSurfaceVariant },
|
|
]}
|
|
>
|
|
Pour être en mesure de vous aider, l'application nécessite les
|
|
permissions suivantes :
|
|
</Text>
|
|
|
|
<View style={styles.permissionList}>
|
|
<View style={styles.permissionItem}>
|
|
<Ionicons
|
|
name="call"
|
|
size={24}
|
|
color={theme.colors.primary}
|
|
style={styles.icon}
|
|
/>
|
|
<Text
|
|
style={[
|
|
styles.permissionText,
|
|
{ color: theme.colors.onSurfaceVariant },
|
|
]}
|
|
>
|
|
Appels téléphoniques : pour contacter rapidement les secours en
|
|
cas d'urgence
|
|
</Text>
|
|
</View>
|
|
<View style={styles.permissionItem}>
|
|
<Ionicons
|
|
name="notifications"
|
|
size={24}
|
|
color={theme.colors.primary}
|
|
style={styles.icon}
|
|
/>
|
|
<Text
|
|
style={[
|
|
styles.permissionText,
|
|
{ color: theme.colors.onSurfaceVariant },
|
|
]}
|
|
>
|
|
Notifications : pour être alerté des situations d'urgence et
|
|
être informé si vos proches ont besoin d'aide
|
|
</Text>
|
|
</View>
|
|
<View style={styles.permissionItem}>
|
|
<Ionicons
|
|
name="location"
|
|
size={24}
|
|
color={theme.colors.primary}
|
|
style={styles.icon}
|
|
/>
|
|
<Text
|
|
style={[
|
|
styles.permissionText,
|
|
{ color: theme.colors.onSurfaceVariant },
|
|
]}
|
|
>
|
|
Localisation : pour pouvoir transmettre efficacement votre
|
|
position aux secours, à vos proches, et aux personnes autour de
|
|
vous en cas d'urgence
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
|
|
{!allGranted && hasAttempted && renderWarnings()}
|
|
|
|
<View style={styles.buttonContainer}>{renderButton()}</View>
|
|
</View>
|
|
</ScrollView>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
},
|
|
scrollView: {
|
|
flex: 1,
|
|
},
|
|
content: {
|
|
padding: 20,
|
|
},
|
|
titleImage: {
|
|
width: 120,
|
|
height: 120,
|
|
alignSelf: "center",
|
|
marginBottom: 20,
|
|
resizeMode: "contain",
|
|
},
|
|
title: {
|
|
fontSize: 28,
|
|
fontWeight: "bold",
|
|
textAlign: "center",
|
|
marginBottom: 20,
|
|
},
|
|
subtitle: {
|
|
fontSize: 22,
|
|
},
|
|
description: {
|
|
fontSize: 16,
|
|
marginBottom: 20,
|
|
lineHeight: 24,
|
|
textAlign: "left",
|
|
},
|
|
permissionList: {
|
|
marginBottom: 20,
|
|
},
|
|
permissionItem: {
|
|
flexDirection: "row",
|
|
alignItems: "flex-start",
|
|
marginBottom: 15,
|
|
},
|
|
icon: {
|
|
marginRight: 10,
|
|
marginTop: 2,
|
|
},
|
|
permissionText: {
|
|
fontSize: 16,
|
|
flex: 1,
|
|
lineHeight: 22,
|
|
textAlign: "left",
|
|
},
|
|
warning: {
|
|
marginBottom: 10,
|
|
fontSize: 14,
|
|
lineHeight: 20,
|
|
textAlign: "left",
|
|
},
|
|
settingsHint: {
|
|
fontSize: 14,
|
|
lineHeight: 20,
|
|
textAlign: "center",
|
|
marginBottom: 10,
|
|
fontStyle: "italic",
|
|
},
|
|
buttonContainer: {
|
|
marginTop: 20,
|
|
},
|
|
});
|
|
|
|
export default Welcome;
|