fix(battery-opti-disable): wip

This commit is contained in:
devthejo 2025-06-22 11:24:43 +02:00
parent 6c290f21b4
commit 7082161b7f
2 changed files with 161 additions and 27 deletions

View file

@ -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 && (
<> <>

View file

@ -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,
}, },
}; };
}); });