feat: audio recording permission handling in MicOrSendButton component (#5515)
This commit is contained in:
parent
7b73eac895
commit
39f8a92059
|
@ -1,14 +1,18 @@
|
||||||
import React, { useContext } from 'react';
|
|
||||||
import { Audio } from 'expo-av';
|
import { Audio } from 'expo-av';
|
||||||
|
import React, { useContext } from 'react';
|
||||||
|
import { Alert } from 'react-native';
|
||||||
|
import { PermissionStatus } from 'expo-camera';
|
||||||
|
|
||||||
import { BaseButton } from './BaseButton';
|
import i18n from '../../../../i18n';
|
||||||
import { MessageInnerContext, useMessageComposerApi, useMicOrSend } from '../../context';
|
|
||||||
import { useTheme } from '../../../../theme';
|
|
||||||
import { useAppSelector } from '../../../../lib/hooks';
|
import { useAppSelector } from '../../../../lib/hooks';
|
||||||
import { useCanUploadFile } from '../../hooks';
|
import { openAppSettings } from '../../../../lib/methods/helpers/openAppSettings';
|
||||||
|
import { useTheme } from '../../../../theme';
|
||||||
import { useRoomContext } from '../../../../views/RoomView/context';
|
import { useRoomContext } from '../../../../views/RoomView/context';
|
||||||
|
import { MessageInnerContext, useMessageComposerApi, useMicOrSend } from '../../context';
|
||||||
|
import { useCanUploadFile } from '../../hooks';
|
||||||
|
import { BaseButton } from './BaseButton';
|
||||||
|
|
||||||
export const MicOrSendButton = () => {
|
export const MicOrSendButton = (): React.ReactElement | null => {
|
||||||
const { rid, sharing } = useRoomContext();
|
const { rid, sharing } = useRoomContext();
|
||||||
const micOrSend = useMicOrSend();
|
const micOrSend = useMicOrSend();
|
||||||
const { sendMessage } = useContext(MessageInnerContext);
|
const { sendMessage } = useContext(MessageInnerContext);
|
||||||
|
@ -17,11 +21,32 @@ export const MicOrSendButton = () => {
|
||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
const { setRecordingAudio } = useMessageComposerApi();
|
const { setRecordingAudio } = useMessageComposerApi();
|
||||||
|
|
||||||
|
const requestPermissionAndStartToRecordAudio = () =>
|
||||||
|
Audio.requestPermissionsAsync()
|
||||||
|
.then(({ granted }) => setRecordingAudio(granted))
|
||||||
|
.catch(() => {});
|
||||||
|
|
||||||
const startRecording = async () => {
|
const startRecording = async () => {
|
||||||
const permission = await Audio.requestPermissionsAsync();
|
const { status, granted, canAskAgain } = await Audio.getPermissionsAsync();
|
||||||
if (permission.granted) {
|
if (granted) return setRecordingAudio(true);
|
||||||
setRecordingAudio(true);
|
if (status === PermissionStatus.UNDETERMINED) return requestPermissionAndStartToRecordAudio();
|
||||||
|
if (canAskAgain) return requestPermissionAndStartToRecordAudio();
|
||||||
|
|
||||||
|
Alert.alert(
|
||||||
|
i18n.t('Microphone_access_needed_to_record_audio'),
|
||||||
|
i18n.t('Go_to_your_device_settings_and_allow_microphone'),
|
||||||
|
[
|
||||||
|
{
|
||||||
|
text: i18n.t('Cancel'),
|
||||||
|
style: 'cancel'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: i18n.t('Settings'),
|
||||||
|
onPress: openAppSettings
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
{ cancelable: false }
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (micOrSend === 'send' || sharing) {
|
if (micOrSend === 'send' || sharing) {
|
||||||
|
|
|
@ -27,6 +27,7 @@ export const RecordAudio = (): ReactElement | null => {
|
||||||
const [styles, colors] = useStyle();
|
const [styles, colors] = useStyle();
|
||||||
const recordingRef = useRef<Audio.Recording>();
|
const recordingRef = useRef<Audio.Recording>();
|
||||||
const durationRef = useRef<IDurationRef>({} as IDurationRef);
|
const durationRef = useRef<IDurationRef>({} as IDurationRef);
|
||||||
|
const numberOfTriesRef = useRef(0);
|
||||||
const [status, setStatus] = React.useState<'recording' | 'reviewing'>('recording');
|
const [status, setStatus] = React.useState<'recording' | 'reviewing'>('recording');
|
||||||
const { setRecordingAudio } = useMessageComposerApi();
|
const { setRecordingAudio } = useMessageComposerApi();
|
||||||
const { rid, tmid } = useRoomContext();
|
const { rid, tmid } = useRoomContext();
|
||||||
|
@ -43,9 +44,22 @@ export const RecordAudio = (): ReactElement | null => {
|
||||||
await recordingRef.current.prepareToRecordAsync(RECORDING_SETTINGS);
|
await recordingRef.current.prepareToRecordAsync(RECORDING_SETTINGS);
|
||||||
recordingRef.current.setOnRecordingStatusUpdate(durationRef.current.onRecordingStatusUpdate);
|
recordingRef.current.setOnRecordingStatusUpdate(durationRef.current.onRecordingStatusUpdate);
|
||||||
await recordingRef.current.startAsync();
|
await recordingRef.current.startAsync();
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
|
// error only occurs on iOS devices
|
||||||
|
if (error?.code === 'E_AUDIO_RECORDERNOTCREATED') {
|
||||||
|
if (numberOfTriesRef.current <= 5) {
|
||||||
|
recordingRef.current = undefined;
|
||||||
|
numberOfTriesRef.current += 1;
|
||||||
|
setTimeout(() => {
|
||||||
|
record();
|
||||||
|
}, 100);
|
||||||
|
} else {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
record();
|
record();
|
||||||
|
|
||||||
|
|
|
@ -803,5 +803,7 @@
|
||||||
"Inline_code": "Inline code",
|
"Inline_code": "Inline code",
|
||||||
"Code_block": "Code block",
|
"Code_block": "Code block",
|
||||||
"Add_thread_reply": "Add thread reply",
|
"Add_thread_reply": "Add thread reply",
|
||||||
"Message_roomname": "Message {{roomName}}"
|
"Message_roomname": "Message {{roomName}}",
|
||||||
|
"Microphone_access_needed_to_record_audio": "Microphone access needed to record audio",
|
||||||
|
"Go_to_your_device_settings_and_allow_microphone": "Go to your device settings and allow microphone access for Rocket.Chat"
|
||||||
}
|
}
|
|
@ -794,6 +794,8 @@
|
||||||
"You_dont_have_permission_to_perform_this_action": "Você não tem permissão para realizar esta ação. Verifique com um administrador do espaço de trabalho.",
|
"You_dont_have_permission_to_perform_this_action": "Você não tem permissão para realizar esta ação. Verifique com um administrador do espaço de trabalho.",
|
||||||
"Jump_to_message": "Ir para mensagem",
|
"Jump_to_message": "Ir para mensagem",
|
||||||
"Missed_call": "Chamada perdida",
|
"Missed_call": "Chamada perdida",
|
||||||
|
"Microphone_access_needed_to_record_audio": "Acesso ao microfone necessário para gravar áudio",
|
||||||
|
"Go_to_your_device_settings_and_allow_microphone": "Vá para as configurações do seu dispositivo e permita o acesso ao microfone pelo aplicativo Rocket.Chat",
|
||||||
"In_app_message_notifications": "Notificações de mensagens in-app",
|
"In_app_message_notifications": "Notificações de mensagens in-app",
|
||||||
"Vibrate": "Vibrar"
|
"Vibrate": "Vibrar"
|
||||||
}
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { Linking } from 'react-native';
|
||||||
|
|
||||||
|
import { isIOS } from './deviceInfo';
|
||||||
|
|
||||||
|
export const openAppSettings = (): void => {
|
||||||
|
if (isIOS) {
|
||||||
|
Linking.openURL('app-settings:');
|
||||||
|
} else {
|
||||||
|
Linking.openSettings();
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in New Issue