diff --git a/src/Locale/en.json b/src/Locale/en.json index 019ec5f29e7..784dd9d3905 100644 --- a/src/Locale/en.json +++ b/src/Locale/en.json @@ -316,6 +316,7 @@ "audio__allow_permission": "Please allow microphone permission in site settings", "audio__allow_permission_button": "Click here to know how to allow", "audio__allow_permission_helper": "You might have denied microphone access in the past.", + "audio__permission_message": "Please grant microphone permission to record audio.", "audio__record": "Record Audio", "audio__record_helper": "Click the button to start recording", "audio__recorded": "Audio Recorded", @@ -1161,6 +1162,7 @@ "summary": "Summary", "support": "Support", "switch": "Switch", + "switch_camera_is_not_available": "Switch camera is not available.", "systolic": "Systolic", "tachycardia": "Tachycardia", "target_dosage": "Target Dosage", diff --git a/src/Utils/useRecorder.js b/src/Utils/useRecorder.js index 446f824259f..8ad90ebe8cb 100644 --- a/src/Utils/useRecorder.js +++ b/src/Utils/useRecorder.js @@ -2,13 +2,14 @@ import { useEffect, useState } from "react"; import { Error } from "./Notifications"; +import { useTranslation } from "react-i18next"; const useRecorder = (handleMicPermission) => { const [audioURL, setAudioURL] = useState(""); const [isRecording, setIsRecording] = useState(false); const [recorder, setRecorder] = useState(null); const [newBlob, setNewBlob] = useState(null); - + const { t } = useTranslation(); useEffect(() => { if (!isRecording && recorder && audioURL) { setRecorder(null); @@ -26,7 +27,7 @@ const useRecorder = (handleMicPermission) => { }, () => { Error({ - msg: "Please grant microphone permission to record audio.", + msg: t("audio__permission_message"), }); setIsRecording(false); handleMicPermission(false); diff --git a/src/Utils/useSegmentedRecorder.ts b/src/Utils/useSegmentedRecorder.ts index 9434ea8383c..fe38afb3b06 100644 --- a/src/Utils/useSegmentedRecorder.ts +++ b/src/Utils/useSegmentedRecorder.ts @@ -1,11 +1,13 @@ import { useState, useEffect } from "react"; import * as Notify from "./Notifications"; +import { useTranslation } from "react-i18next"; const useSegmentedRecording = () => { const [isRecording, setIsRecording] = useState(false); const [recorder, setRecorder] = useState(null); const [audioBlobs, setAudioBlobs] = useState([]); const [restart, setRestart] = useState(false); + const { t } = useTranslation(); const bufferInterval = 1 * 1000; const splitSizeLimit = 20 * 1000000; // 20MB @@ -28,7 +30,7 @@ const useSegmentedRecording = () => { }, () => { Notify.Error({ - msg: "Please grant microphone permission to record audio.", + msg: t("audio__permission_message"), }); setIsRecording(false); }, diff --git a/src/components/Files/AudioCaptureDialog.tsx b/src/components/Files/AudioCaptureDialog.tsx index 097de0088aa..f84fc01c28b 100644 --- a/src/components/Files/AudioCaptureDialog.tsx +++ b/src/components/Files/AudioCaptureDialog.tsx @@ -3,7 +3,8 @@ import useRecorder from "../../Utils/useRecorder"; import { Link } from "raviger"; import CareIcon from "../../CAREUI/icons/CareIcon"; import { useTimer } from "../../Utils/useTimer"; -import { t } from "i18next"; +import { useTranslation } from "react-i18next"; +import * as Notify from "../../Utils/Notifications"; export interface AudioCaptureDialogProps { show: boolean; @@ -20,8 +21,8 @@ export default function AudioCaptureDialog(props: AudioCaptureDialogProps) { | "RECORDED"; const { show, onHide, onCapture, autoRecord = false } = props; - const [status, setStatus] = useState(null); + const { t } = useTranslation(); const [audioURL, , startRecording, stopRecording, , resetRecording] = useRecorder((permission: boolean) => { @@ -35,9 +36,19 @@ export default function AudioCaptureDialog(props: AudioCaptureDialogProps) { const timer = useTimer(); const handleStartRecording = () => { - setStatus("RECORDING"); - startRecording(); - timer.start(); + navigator.mediaDevices + .getUserMedia({ audio: true }) + .then(() => { + setStatus("RECORDING"); + startRecording(); + timer.start(); + }) + .catch(() => { + Notify.Error({ + msg: t("audio__permission_message"), + }); + setStatus("PERMISSION_DENIED"); + }); }; const handleStopRecording = () => { @@ -87,7 +98,7 @@ export default function AudioCaptureDialog(props: AudioCaptureDialogProps) { }, [show]); useEffect(() => { - if (autoRecord && show && status === "WAITING_TO_RECORD") { + if (autoRecord && show && status === "RECORDING") { handleStartRecording(); } }, [autoRecord, status, show]); diff --git a/src/components/Files/CameraCaptureDialog.tsx b/src/components/Files/CameraCaptureDialog.tsx index b5af6ace8d5..81981c9bf3a 100644 --- a/src/components/Files/CameraCaptureDialog.tsx +++ b/src/components/Files/CameraCaptureDialog.tsx @@ -3,8 +3,9 @@ import CareIcon from "../../CAREUI/icons/CareIcon"; import DialogModal from "@/components/Common/Dialog"; import ButtonV2, { Submit } from "@/components/Common/components/ButtonV2"; import { t } from "i18next"; -import { useCallback, useRef, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import useWindowDimensions from "@/common/hooks/useWindowDimensions"; +import * as Notify from "../../Utils/Notifications"; export interface CameraCaptureDialogProps { show: boolean; @@ -24,9 +25,29 @@ export default function CameraCaptureDialog(props: CameraCaptureDialogProps) { height: { ideal: 2160 }, facingMode: "user", }; - + useEffect(() => { + if (!show) return; + navigator.mediaDevices.getUserMedia({ video: true }).catch(() => { + Notify.Warn({ + msg: t("camera_permission_denied"), + }); + onHide(); + }); + }, [show]); const handleSwitchCamera = useCallback(() => { - setCameraFacingFront((prevState) => !prevState); + const supportedConstraints = + navigator.mediaDevices.getSupportedConstraints(); + if ( + !isLaptopScreen && + typeof supportedConstraints.facingMode === "string" && + (supportedConstraints.facingMode as string).includes("environment") + ) { + setCameraFacingFront((prevState) => !prevState); + } else { + Notify.Warn({ + msg: t("switch_camera_is_not_available"), + }); + } }, []); const { width } = useWindowDimensions();