From d9b5d10684446a01873810382e501e45cd19da1b Mon Sep 17 00:00:00 2001 From: devthejo Date: Sun, 22 Jun 2025 11:32:51 +0200 Subject: [PATCH] fix(battery-opti-disable): integrate permissions view --- src/scenes/Params/Permissions.js | 120 ++++++++++++++++++++++++++----- 1 file changed, 102 insertions(+), 18 deletions(-) diff --git a/src/scenes/Params/Permissions.js b/src/scenes/Params/Permissions.js index 0708b15..257edfa 100644 --- a/src/scenes/Params/Permissions.js +++ b/src/scenes/Params/Permissions.js @@ -1,8 +1,18 @@ import React, { useEffect, useCallback } from "react"; -import { View, TouchableOpacity, StyleSheet } from "react-native"; +import { + View, + TouchableOpacity, + StyleSheet, + Platform, + AppState, +} from "react-native"; import { Button, Title } from "react-native-paper"; import { usePermissionsState, permissionsActions } from "~/stores"; import { Ionicons } from "@expo/vector-icons"; +import { + RequestDisableOptimization, + BatteryOptEnabled, +} from "react-native-battery-optimization-check"; import openSettings from "~/lib/native/openSettings"; import requestPermissionFcm from "~/permissions/requestPermissionFcm"; @@ -16,6 +26,29 @@ import * as Location from "expo-location"; import * as Notifications from "expo-notifications"; import * as Contacts from "expo-contacts"; +// Battery optimization request handler +const requestBatteryOptimizationDisable = async () => { + if (Platform.OS !== "android") { + return true; // iOS doesn't have battery optimization + } + + try { + const isEnabled = await BatteryOptEnabled(); + if (isEnabled) { + console.log("Battery optimization enabled, requesting to disable..."); + RequestDisableOptimization(); + // Return false as the user needs to interact with the system dialog + return false; + } else { + console.log("Battery optimization already disabled"); + return true; + } + } catch (error) { + console.error("Error handling battery optimization:", error); + return false; + } +}; + const requestPermissions = { fcm: requestPermissionFcm, locationBackground: requestPermissionLocationBackground, @@ -23,6 +56,7 @@ const requestPermissions = { readContacts: requestPermissionReadContacts, phoneCall: requestPermissionPhoneCall, motion: requestPermissionMotion.requestPermission, + batteryOptimizationDisabled: requestBatteryOptimizationDisable, }; const setPermissions = { @@ -32,6 +66,8 @@ const setPermissions = { readContacts: (b) => permissionsActions.setReadContacts(b), phoneCall: (b) => permissionsActions.setPhoneCall(b), motion: (b) => permissionsActions.setMotion(b), + batteryOptimizationDisabled: (b) => + permissionsActions.setBatteryOptimizationDisabled(b), }; const titlePermissions = { @@ -41,6 +77,7 @@ const titlePermissions = { readContacts: "Contacts", phoneCall: "Appels", motion: "Détection de mouvement", + batteryOptimizationDisabled: "Optimisation de la batterie", }; // Function to check current permission status @@ -68,6 +105,17 @@ const checkPermissionStatus = async (permission) => { // Note: Phone call permissions on iOS are determined at build time // and on Android they're requested at runtime return true; // This might need adjustment based on your specific implementation + case "batteryOptimizationDisabled": + if (Platform.OS !== "android") { + return true; // iOS doesn't have battery optimization + } + try { + const isEnabled = await BatteryOptEnabled(); + return !isEnabled; // Return true if optimization is disabled + } catch (error) { + console.error("Error checking battery optimization:", error); + return false; + } default: return false; } @@ -95,18 +143,9 @@ const PermissionItem = ({ permission, status, onRequestPermission }) => ( ); export default function Permissions() { - const permissionsState = usePermissionsState([ - "fcm", - "phoneCall", - "locationForeground", - "locationBackground", - "motion", - "readContacts", - ]); - - // Memoize the check permissions function - const checkAllPermissions = useCallback(async () => { - const permissionKeys = [ + // Create permissions list based on platform + const getPermissionsList = () => { + const basePermissions = [ "fcm", "phoneCall", "locationForeground", @@ -115,25 +154,70 @@ export default function Permissions() { "readContacts", ]; - for (const permission of permissionKeys) { + // Add battery optimization only on Android + if (Platform.OS === "android") { + return [...basePermissions, "batteryOptimizationDisabled"]; + } + + return basePermissions; + }; + + const permissionsList = getPermissionsList(); + const permissionsState = usePermissionsState(permissionsList); + + // Memoize the check permissions function + const checkAllPermissions = useCallback(async () => { + for (const permission of permissionsList) { const status = await checkPermissionStatus(permission); setPermissions[permission](status); } - }, []); + }, [permissionsList]); // Check all permissions when component mounts useEffect(() => { checkAllPermissions(); }, [checkAllPermissions]); + // Listen for app state changes to re-check permissions when user returns from settings + useEffect(() => { + const handleAppStateChange = async (nextAppState) => { + if (nextAppState === "active") { + console.log("App became active, re-checking all permissions..."); + // Re-check all permissions when app becomes active + await checkAllPermissions(); + } + }; + + const subscription = AppState.addEventListener( + "change", + handleAppStateChange, + ); + + return () => { + subscription?.remove(); + }; + }, [checkAllPermissions]); + const handleRequestPermission = async (permission) => { try { const granted = await requestPermissions[permission](); setPermissions[permission](granted); - // Double-check the status to ensure UI is in sync - const actualStatus = await checkPermissionStatus(permission); - setPermissions[permission](actualStatus); + // For battery optimization, we need to handle the async nature differently + if ( + permission === "batteryOptimizationDisabled" && + Platform.OS === "android" + ) { + // Give a short delay for the system dialog to potentially complete + setTimeout(async () => { + const actualStatus = await checkPermissionStatus(permission); + setPermissions[permission](actualStatus); + }, 1000); + } else { + // Double-check the status to ensure UI is in sync + const actualStatus = await checkPermissionStatus(permission); + setPermissions[permission](actualStatus); + } } catch (error) { console.error(`Error requesting ${permission} permission:`, error); }