fix(battery-opti-disable): wip
This commit is contained in:
parent
6c290f21b4
commit
7082161b7f
2 changed files with 161 additions and 27 deletions
|
@ -1,5 +1,12 @@
|
||||||
import React, { useState, useCallback, useEffect } from "react";
|
import React, { useState, useCallback, useEffect } from "react";
|
||||||
import { View, StyleSheet, Image, ScrollView, Platform } from "react-native";
|
import {
|
||||||
|
View,
|
||||||
|
StyleSheet,
|
||||||
|
Image,
|
||||||
|
ScrollView,
|
||||||
|
Platform,
|
||||||
|
AppState,
|
||||||
|
} from "react-native";
|
||||||
import { Title } from "react-native-paper";
|
import { Title } from "react-native-paper";
|
||||||
import { Ionicons, Entypo } from "@expo/vector-icons";
|
import { Ionicons, Entypo } from "@expo/vector-icons";
|
||||||
import {
|
import {
|
||||||
|
@ -37,7 +44,12 @@ const HeroMode = () => {
|
||||||
const [batteryOptimizationEnabled, setBatteryOptimizationEnabled] =
|
const [batteryOptimizationEnabled, setBatteryOptimizationEnabled] =
|
||||||
useState(null);
|
useState(null);
|
||||||
const [batteryOptAttempted, setBatteryOptAttempted] = useState(false);
|
const [batteryOptAttempted, setBatteryOptAttempted] = useState(false);
|
||||||
const permissions = usePermissionsState(["locationBackground", "motion"]);
|
const [batteryOptInProgress, setBatteryOptInProgress] = useState(false);
|
||||||
|
const permissions = usePermissionsState([
|
||||||
|
"locationBackground",
|
||||||
|
"motion",
|
||||||
|
"batteryOptimizationDisabled",
|
||||||
|
]);
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const [skipMessage] = useState(() => {
|
const [skipMessage] = useState(() => {
|
||||||
|
@ -53,47 +65,75 @@ const HeroMode = () => {
|
||||||
permissionWizardActions.setCurrentStep("skipInfo");
|
permissionWizardActions.setCurrentStep("skipInfo");
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handleBatteryOptimization = useCallback(async () => {
|
||||||
|
if (Platform.OS !== "android") {
|
||||||
|
permissionsActions.setBatteryOptimizationDisabled(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
setBatteryOptInProgress(true);
|
||||||
|
const isEnabled = await BatteryOptEnabled();
|
||||||
|
setBatteryOptimizationEnabled(isEnabled);
|
||||||
|
|
||||||
|
if (isEnabled) {
|
||||||
|
console.log(
|
||||||
|
"Battery optimization is enabled, requesting to disable...",
|
||||||
|
);
|
||||||
|
RequestDisableOptimization();
|
||||||
|
setBatteryOptAttempted(true);
|
||||||
|
|
||||||
|
// Give some time for the user to interact with the system dialog
|
||||||
|
// We'll check the status again in the retry flow
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
console.log("Battery optimization already disabled");
|
||||||
|
permissionsActions.setBatteryOptimizationDisabled(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error handling battery optimization:", error);
|
||||||
|
setBatteryOptAttempted(true);
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
setBatteryOptInProgress(false);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
const handleRequestPermissions = useCallback(async () => {
|
const handleRequestPermissions = useCallback(async () => {
|
||||||
setRequesting(true);
|
setRequesting(true);
|
||||||
try {
|
try {
|
||||||
// Set step to tracking before requesting permissions
|
// Don't change step immediately to avoid race conditions
|
||||||
permissionWizardActions.setCurrentStep("tracking");
|
console.log("Starting permission requests...");
|
||||||
|
|
||||||
// Request motion permission first
|
// Request motion permission first
|
||||||
const motionGranted = await requestPermissionMotion.requestPermission();
|
const motionGranted = await requestPermissionMotion.requestPermission();
|
||||||
permissionsActions.setMotion(motionGranted);
|
permissionsActions.setMotion(motionGranted);
|
||||||
|
console.log("Motion permission:", motionGranted);
|
||||||
|
|
||||||
// Then request background location
|
// Then request background location
|
||||||
const locationGranted = await requestPermissionLocationBackground();
|
const locationGranted = await requestPermissionLocationBackground();
|
||||||
permissionsActions.setLocationBackground(locationGranted);
|
permissionsActions.setLocationBackground(locationGranted);
|
||||||
|
console.log("Location background permission:", locationGranted);
|
||||||
|
|
||||||
// Check and request battery optimization disable (Android only)
|
// Handle battery optimization separately to avoid dialog conflicts
|
||||||
let batteryOptDisabled = true;
|
const batteryOptDisabled = await handleBatteryOptimization();
|
||||||
if (Platform.OS === "android") {
|
console.log("Battery optimization disabled:", batteryOptDisabled);
|
||||||
try {
|
|
||||||
const isEnabled = await BatteryOptEnabled();
|
|
||||||
setBatteryOptimizationEnabled(isEnabled);
|
|
||||||
if (isEnabled) {
|
|
||||||
RequestDisableOptimization();
|
|
||||||
batteryOptDisabled = false;
|
|
||||||
}
|
|
||||||
setBatteryOptAttempted(true);
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error checking battery optimization:", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If all permissions granted and battery optimization handled, move to success
|
// Only set step to tracking after all permission requests are complete
|
||||||
|
permissionWizardActions.setCurrentStep("tracking");
|
||||||
|
|
||||||
|
// Check if we should proceed to success immediately
|
||||||
if (locationGranted && motionGranted && batteryOptDisabled) {
|
if (locationGranted && motionGranted && batteryOptDisabled) {
|
||||||
permissionWizardActions.setHeroPermissionsGranted(true);
|
permissionWizardActions.setHeroPermissionsGranted(true);
|
||||||
permissionWizardActions.setCurrentStep("success");
|
// Don't navigate immediately, let the useEffect handle it
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error requesting permissions:", error);
|
console.error("Error requesting permissions:", error);
|
||||||
}
|
}
|
||||||
setRequesting(false);
|
setRequesting(false);
|
||||||
setHasAttempted(true);
|
setHasAttempted(true);
|
||||||
}, []);
|
}, [handleBatteryOptimization]);
|
||||||
|
|
||||||
const handleRetry = useCallback(async () => {
|
const handleRetry = useCallback(async () => {
|
||||||
// Re-check battery optimization status before retrying
|
// Re-check battery optimization status before retrying
|
||||||
|
@ -101,19 +141,97 @@ const HeroMode = () => {
|
||||||
try {
|
try {
|
||||||
const isEnabled = await BatteryOptEnabled();
|
const isEnabled = await BatteryOptEnabled();
|
||||||
setBatteryOptimizationEnabled(isEnabled);
|
setBatteryOptimizationEnabled(isEnabled);
|
||||||
|
|
||||||
|
// If battery optimization is now disabled, update the store
|
||||||
|
if (!isEnabled) {
|
||||||
|
console.log("Battery optimization now disabled after retry");
|
||||||
|
permissionsActions.setBatteryOptimizationDisabled(true);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error re-checking battery optimization:", error);
|
console.error("Error re-checking battery optimization:", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await handleRequestPermissions();
|
|
||||||
|
// Only request permissions again if some are still missing
|
||||||
|
const needsRetry =
|
||||||
|
!permissions.locationBackground ||
|
||||||
|
!permissions.motion ||
|
||||||
|
(Platform.OS === "android" && batteryOptimizationEnabled);
|
||||||
|
|
||||||
|
if (needsRetry) {
|
||||||
|
await handleRequestPermissions();
|
||||||
|
}
|
||||||
|
|
||||||
setHasRetried(true);
|
setHasRetried(true);
|
||||||
}, [handleRequestPermissions]);
|
}, [handleRequestPermissions, permissions, batteryOptimizationEnabled]);
|
||||||
|
|
||||||
const allGranted =
|
const allGranted =
|
||||||
permissions.locationBackground &&
|
permissions.locationBackground &&
|
||||||
permissions.motion &&
|
permissions.motion &&
|
||||||
(Platform.OS === "ios" || !batteryOptimizationEnabled);
|
(Platform.OS === "ios" || !batteryOptimizationEnabled);
|
||||||
|
|
||||||
|
// Check battery optimization status on mount
|
||||||
|
useEffect(() => {
|
||||||
|
const checkInitialBatteryOptimization = async () => {
|
||||||
|
if (Platform.OS === "android") {
|
||||||
|
try {
|
||||||
|
const isEnabled = await BatteryOptEnabled();
|
||||||
|
setBatteryOptimizationEnabled(isEnabled);
|
||||||
|
|
||||||
|
// If already disabled, update the store
|
||||||
|
if (!isEnabled) {
|
||||||
|
permissionsActions.setBatteryOptimizationDisabled(true);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error checking initial battery optimization:", error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// iOS doesn't have battery optimization, so mark as disabled
|
||||||
|
permissionsActions.setBatteryOptimizationDisabled(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
checkInitialBatteryOptimization();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Listen for app state changes to re-check battery optimization when user returns from settings
|
||||||
|
useEffect(() => {
|
||||||
|
const handleAppStateChange = async (nextAppState) => {
|
||||||
|
if (
|
||||||
|
nextAppState === "active" &&
|
||||||
|
Platform.OS === "android" &&
|
||||||
|
batteryOptAttempted
|
||||||
|
) {
|
||||||
|
console.log("App became active, re-checking battery optimization...");
|
||||||
|
try {
|
||||||
|
const isEnabled = await BatteryOptEnabled();
|
||||||
|
setBatteryOptimizationEnabled(isEnabled);
|
||||||
|
|
||||||
|
if (!isEnabled) {
|
||||||
|
console.log(
|
||||||
|
"Battery optimization disabled after returning from settings",
|
||||||
|
);
|
||||||
|
permissionsActions.setBatteryOptimizationDisabled(true);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(
|
||||||
|
"Error re-checking battery optimization on app focus:",
|
||||||
|
error,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const subscription = AppState.addEventListener(
|
||||||
|
"change",
|
||||||
|
handleAppStateChange,
|
||||||
|
);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
subscription?.remove();
|
||||||
|
};
|
||||||
|
}, [batteryOptAttempted]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (hasAttempted && allGranted) {
|
if (hasAttempted && allGranted) {
|
||||||
handleNext();
|
handleNext();
|
||||||
|
@ -271,8 +389,11 @@ const HeroMode = () => {
|
||||||
mode="contained"
|
mode="contained"
|
||||||
onPress={handleRequestPermissions}
|
onPress={handleRequestPermissions}
|
||||||
loading={requesting}
|
loading={requesting}
|
||||||
|
disabled={batteryOptInProgress}
|
||||||
>
|
>
|
||||||
J'accorde les permissions
|
{batteryOptInProgress
|
||||||
|
? "Traitement de l'optimisation de la batterie..."
|
||||||
|
: "J'accorde les permissions"}
|
||||||
</CustomButton>
|
</CustomButton>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -294,8 +415,15 @@ const HeroMode = () => {
|
||||||
>
|
>
|
||||||
{skipMessage}
|
{skipMessage}
|
||||||
</CustomButton>
|
</CustomButton>
|
||||||
<CustomButton mode="contained" onPress={handleRetry}>
|
<CustomButton
|
||||||
Réessayer d'accorder les permissions
|
mode="contained"
|
||||||
|
onPress={handleRetry}
|
||||||
|
loading={requesting}
|
||||||
|
disabled={batteryOptInProgress}
|
||||||
|
>
|
||||||
|
{batteryOptInProgress
|
||||||
|
? "Vérification en cours..."
|
||||||
|
: "Réessayer d'accorder les permissions"}
|
||||||
</CustomButton>
|
</CustomButton>
|
||||||
{hasRetried && (
|
{hasRetried && (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -25,6 +25,10 @@ export default createAtom(({ merge }) => {
|
||||||
merge({ motion });
|
merge({ motion });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const setBatteryOptimizationDisabled = (batteryOptimizationDisabled) => {
|
||||||
|
merge({ batteryOptimizationDisabled });
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
default: {
|
default: {
|
||||||
fcm: false,
|
fcm: false,
|
||||||
|
@ -33,6 +37,7 @@ export default createAtom(({ merge }) => {
|
||||||
readContacts: false,
|
readContacts: false,
|
||||||
phoneCall: false,
|
phoneCall: false,
|
||||||
motion: false,
|
motion: false,
|
||||||
|
batteryOptimizationDisabled: false,
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
setFcm,
|
setFcm,
|
||||||
|
@ -41,6 +46,7 @@ export default createAtom(({ merge }) => {
|
||||||
setReadContacts,
|
setReadContacts,
|
||||||
setPhoneCall,
|
setPhoneCall,
|
||||||
setMotion,
|
setMotion,
|
||||||
|
setBatteryOptimizationDisabled,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue