fix: permissions screen
This commit is contained in:
parent
41bb6fcd2d
commit
6c8153bdb1
1 changed files with 26 additions and 16 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useEffect, useCallback, useRef } from "react";
|
import React, { useEffect, useCallback, useMemo, useRef } from "react";
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
TouchableOpacity,
|
TouchableOpacity,
|
||||||
|
|
@ -309,8 +309,10 @@ const PermissionItem = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Permissions() {
|
export default function Permissions() {
|
||||||
// Create permissions list based on platform
|
// IMPORTANT: keep a stable permissions list across renders.
|
||||||
const getPermissionsList = () => {
|
// If this array changes identity each render, it re-creates callbacks and can
|
||||||
|
// trigger a re-render loop via permission checks + store updates.
|
||||||
|
const permissionsList = useMemo(() => {
|
||||||
const basePermissions = [
|
const basePermissions = [
|
||||||
"fcm",
|
"fcm",
|
||||||
"phoneCall",
|
"phoneCall",
|
||||||
|
|
@ -319,30 +321,32 @@ export default function Permissions() {
|
||||||
"motion",
|
"motion",
|
||||||
"readContacts",
|
"readContacts",
|
||||||
];
|
];
|
||||||
|
return Platform.OS === "android"
|
||||||
// Add battery optimization only on Android
|
? [...basePermissions, "batteryOptimizationDisabled"]
|
||||||
if (Platform.OS === "android") {
|
: basePermissions;
|
||||||
return [...basePermissions, "batteryOptimizationDisabled"];
|
}, []);
|
||||||
}
|
|
||||||
|
|
||||||
return basePermissions;
|
|
||||||
};
|
|
||||||
|
|
||||||
const permissionsList = getPermissionsList();
|
|
||||||
const permissionsState = usePermissionsState(permissionsList);
|
const permissionsState = usePermissionsState(permissionsList);
|
||||||
|
|
||||||
const titleRef = useRef(null);
|
const titleRef = useRef(null);
|
||||||
const lastAnnouncementRef = useRef({});
|
const lastAnnouncementRef = useRef({});
|
||||||
|
const lastSetPermissionRef = useRef({});
|
||||||
|
const lastBlockedMapRef = useRef(null);
|
||||||
|
|
||||||
// We keep a minimal, best-effort blocked map for a11y/UX.
|
// We keep a minimal, best-effort blocked map for a11y/UX.
|
||||||
const [blockedMap, setBlockedMap] = React.useState({});
|
const [blockedMap, setBlockedMap] = React.useState({});
|
||||||
|
|
||||||
// Memoize the check permissions function
|
// Memoize the check permissions function.
|
||||||
|
// NOTE: Do NOT depend on permissionsState here (it changes on each store update),
|
||||||
|
// or we can re-run effects and create a log spam loop.
|
||||||
const checkAllPermissions = useCallback(async () => {
|
const checkAllPermissions = useCallback(async () => {
|
||||||
|
// Update store only when values actually change, to avoid churn.
|
||||||
for (const permission of permissionsList) {
|
for (const permission of permissionsList) {
|
||||||
const status = await checkPermissionStatus(permission);
|
const status = await checkPermissionStatus(permission);
|
||||||
|
if (lastSetPermissionRef.current[permission] !== status) {
|
||||||
|
lastSetPermissionRef.current[permission] = status;
|
||||||
setPermissions[permission](status);
|
setPermissions[permission](status);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Also refresh "blocked" state used for a11y guidance.
|
// Also refresh "blocked" state used for a11y guidance.
|
||||||
const nextBlocked = {};
|
const nextBlocked = {};
|
||||||
|
|
@ -350,7 +354,13 @@ export default function Permissions() {
|
||||||
const meta = await getPermissionA11yMeta(permission);
|
const meta = await getPermissionA11yMeta(permission);
|
||||||
nextBlocked[permission] = !!meta.blocked;
|
nextBlocked[permission] = !!meta.blocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Avoid re-setting state if unchanged (prevents extra re-renders).
|
||||||
|
const nextBlockedKey = JSON.stringify(nextBlocked);
|
||||||
|
if (lastBlockedMapRef.current !== nextBlockedKey) {
|
||||||
|
lastBlockedMapRef.current = nextBlockedKey;
|
||||||
setBlockedMap(nextBlocked);
|
setBlockedMap(nextBlocked);
|
||||||
|
}
|
||||||
}, [permissionsList]);
|
}, [permissionsList]);
|
||||||
|
|
||||||
// Check all permissions when component mounts
|
// Check all permissions when component mounts
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue