fix(up-wip): recording permissions
This commit is contained in:
parent
c5ccfa8d08
commit
749a09aa5e
3 changed files with 96 additions and 22 deletions
|
@ -1,5 +1,5 @@
|
|||
import React, { useState, useCallback, useEffect, useRef } from "react";
|
||||
import { View, Text, TouchableOpacity } from "react-native";
|
||||
import { View, Text, TouchableOpacity, Platform, Alert } from "react-native";
|
||||
import { MaterialCommunityIcons } from "@expo/vector-icons";
|
||||
import {
|
||||
useAudioRecorder,
|
||||
|
@ -11,6 +11,14 @@ import {
|
|||
AudioQuality,
|
||||
} from "expo-audio";
|
||||
|
||||
import {
|
||||
check,
|
||||
request,
|
||||
PERMISSIONS,
|
||||
RESULTS,
|
||||
openSettings,
|
||||
} from "react-native-permissions";
|
||||
|
||||
import Countdown from "react-countdown";
|
||||
|
||||
import { useAlertState, getLocationState, useSessionState } from "~/stores";
|
||||
|
@ -74,6 +82,51 @@ const recordingOptionsFallback = {
|
|||
|
||||
const activeOpacity = 0.7;
|
||||
|
||||
const withTimeout = (promise, ms = 10000) =>
|
||||
new Promise((resolve, reject) => {
|
||||
const id = setTimeout(
|
||||
() => reject(new Error("Permission request timeout")),
|
||||
ms,
|
||||
);
|
||||
promise
|
||||
.then((v) => {
|
||||
clearTimeout(id);
|
||||
resolve(v);
|
||||
})
|
||||
.catch((e) => {
|
||||
clearTimeout(id);
|
||||
reject(e);
|
||||
});
|
||||
});
|
||||
|
||||
const ensureMicPermission = async () => {
|
||||
if (Platform.OS !== "android") {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
const status = await check(PERMISSIONS.ANDROID.RECORD_AUDIO);
|
||||
if (status === RESULTS.GRANTED) return true;
|
||||
if (status === RESULTS.BLOCKED) {
|
||||
try {
|
||||
Alert.alert(
|
||||
"Autorisation micro bloquée",
|
||||
"Veuillez autoriser le micro dans les paramètres de l'application.",
|
||||
[
|
||||
{ text: "Annuler", style: "cancel" },
|
||||
{ text: "Ouvrir les paramètres", onPress: openSettings },
|
||||
],
|
||||
);
|
||||
} catch (_) {}
|
||||
return false;
|
||||
}
|
||||
const res = await request(PERMISSIONS.ANDROID.RECORD_AUDIO);
|
||||
return res === RESULTS.GRANTED;
|
||||
} catch (e) {
|
||||
console.log("Mic permission check failed", e);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
export default React.memo(function ChatInput({
|
||||
style,
|
||||
labelStyle,
|
||||
|
@ -146,8 +199,30 @@ export default React.memo(function ChatInput({
|
|||
|
||||
const startRecording = useCallback(async () => {
|
||||
try {
|
||||
console.log("Requesting permissions..");
|
||||
await requestRecordingPermissionsAsync();
|
||||
console.log("Requesting microphone permission..");
|
||||
const grantedPre = await ensureMicPermission();
|
||||
if (!grantedPre) {
|
||||
console.log("Microphone permission not granted or blocked");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await withTimeout(requestRecordingPermissionsAsync(), 10000);
|
||||
} catch (permErr) {
|
||||
console.log("Microphone permission request failed/timed out:", permErr);
|
||||
if (Platform.OS === "android") {
|
||||
try {
|
||||
Alert.alert(
|
||||
"Autorisation micro requise",
|
||||
"Impossible d'obtenir l'autorisation du microphone. Ouvrir les paramètres pour l'accorder.",
|
||||
[
|
||||
{ text: "Annuler", style: "cancel" },
|
||||
{ text: "Ouvrir les paramètres", onPress: openSettings },
|
||||
],
|
||||
);
|
||||
} catch (_) {}
|
||||
}
|
||||
return;
|
||||
}
|
||||
await setAudioModeAsync({
|
||||
allowsRecording: true,
|
||||
interruptionMode: "doNotMix",
|
||||
|
|
|
@ -46,22 +46,27 @@ export default async () => {
|
|||
|
||||
// Handle Android permissions
|
||||
permissionLogger.debug("Requesting Android notification permissions");
|
||||
const { status } = await requestNotifications(["alert"]);
|
||||
const { status } = await requestNotifications(["alert", "sound", "badge"]);
|
||||
|
||||
let postNotifications = RESULTS.UNAVAILABLE;
|
||||
if (Platform.Version >= 33) {
|
||||
permissionLogger.debug(
|
||||
"Requesting POST_NOTIFICATIONS permission (Android 13+)",
|
||||
);
|
||||
const postNotifications = await request(
|
||||
PERMISSIONS.ANDROID.POST_NOTIFICATIONS,
|
||||
);
|
||||
postNotifications = await request(PERMISSIONS.ANDROID.POST_NOTIFICATIONS);
|
||||
}
|
||||
|
||||
// Determine grant state:
|
||||
// - Android 13+ requires POST_NOTIFICATIONS granted
|
||||
// - Below 13, POST_NOTIFICATIONS is unavailable; use requestNotifications result
|
||||
const isGranted =
|
||||
status === RESULTS.GRANTED &&
|
||||
(postNotifications === "granted" || postNotifications === "unavailable");
|
||||
(Platform.Version >= 33 && postNotifications === RESULTS.GRANTED) ||
|
||||
(Platform.Version < 33 && status === RESULTS.GRANTED);
|
||||
|
||||
permissionLogger.info("Android notification permission result", {
|
||||
notificationStatus: status,
|
||||
postNotificationsStatus: postNotifications,
|
||||
osVersion: Platform.Version,
|
||||
granted: isGranted,
|
||||
});
|
||||
|
||||
|
|
|
@ -3,23 +3,17 @@ import { useEffect } from "react";
|
|||
|
||||
import requestPermissionFcm from "./requestPermissionFcm";
|
||||
|
||||
export default async function usePermissionFcm() {
|
||||
export default function usePermissionFcm() {
|
||||
const { fcm } = usePermissionsState(["fcm"]);
|
||||
|
||||
const { setFcm } = permissionsActions;
|
||||
|
||||
useEffect(() => {
|
||||
// if (fcm) {
|
||||
// return;
|
||||
// }
|
||||
if (fcm) {
|
||||
return;
|
||||
}
|
||||
(async () => {
|
||||
// const authStatus = await messaging().requestPermission();
|
||||
// setFcm(
|
||||
// authStatus === AuthorizationStatus.AUTHORIZED ||
|
||||
// authStatus === AuthorizationStatus.PROVISIONAL,
|
||||
// );
|
||||
const granted = await requestPermissionFcm();
|
||||
|
||||
setFcm(granted);
|
||||
})();
|
||||
}, [fcm, setFcm]);
|
||||
|
|
Loading…
Add table
Reference in a new issue