From 007c68714583ede1d7fc8f1cbc173954335511d6 Mon Sep 17 00:00:00 2001 From: Shaurya Gupta Date: Sat, 19 Oct 2024 22:05:50 +0530 Subject: [PATCH 1/5] Fix: Permission Handling Issues in Microphone and Camera Capture Dialogs --- src/Components/Files/AudioCaptureDialog.tsx | 19 +++++++++++--- src/Components/Files/CameraCaptureDialog.tsx | 27 +++++++++++++++++--- src/Locale/en.json | 1 + 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/Components/Files/AudioCaptureDialog.tsx b/src/Components/Files/AudioCaptureDialog.tsx index 097de0088aa..ea447f9e192 100644 --- a/src/Components/Files/AudioCaptureDialog.tsx +++ b/src/Components/Files/AudioCaptureDialog.tsx @@ -4,6 +4,7 @@ import { Link } from "raviger"; import CareIcon from "../../CAREUI/icons/CareIcon"; import { useTimer } from "../../Utils/useTimer"; import { t } from "i18next"; +import * as Notify from "../../Utils/Notifications"; export interface AudioCaptureDialogProps { show: 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: "Please grant microphone permission to record audio.", + }); + 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 96de547eebe..ba96214d4a2 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 "../Common/Dialog"; import ButtonV2, { Submit } from "../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(); diff --git a/src/Locale/en.json b/src/Locale/en.json index 08f9ded2130..19fd40c3f98 100644 --- a/src/Locale/en.json +++ b/src/Locale/en.json @@ -999,6 +999,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", From a203aa27bafb52582ffec524f309dcdf33c28791 Mon Sep 17 00:00:00 2001 From: Shaurya Gupta Date: Tue, 22 Oct 2024 23:22:45 +0530 Subject: [PATCH 2/5] Added i18n --- src/Locale/en.json | 1 + src/Utils/useRecorder.js | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Locale/en.json b/src/Locale/en.json index 19fd40c3f98..53f09037e42 100644 --- a/src/Locale/en.json +++ b/src/Locale/en.json @@ -275,6 +275,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", 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); From a6c5aa95feebd859146fd520b23f956ee58d4679 Mon Sep 17 00:00:00 2001 From: Shaurya Gupta Date: Tue, 22 Oct 2024 23:30:29 +0530 Subject: [PATCH 3/5] resolved comments --- src/Components/Files/AudioCaptureDialog.tsx | 6 +++--- src/Utils/useSegmentedRecorder.ts | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Components/Files/AudioCaptureDialog.tsx b/src/Components/Files/AudioCaptureDialog.tsx index ea447f9e192..f84fc01c28b 100644 --- a/src/Components/Files/AudioCaptureDialog.tsx +++ b/src/Components/Files/AudioCaptureDialog.tsx @@ -3,7 +3,7 @@ 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 { @@ -21,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) => { @@ -45,7 +45,7 @@ export default function AudioCaptureDialog(props: AudioCaptureDialogProps) { }) .catch(() => { Notify.Error({ - msg: "Please grant microphone permission to record audio.", + msg: t("audio__permission_message"), }); setStatus("PERMISSION_DENIED"); }); 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); }, From 3191e6202ef68ff71f875856dbc1849e7f558061 Mon Sep 17 00:00:00 2001 From: Shaurya Gupta Date: Sat, 26 Oct 2024 20:24:28 +0530 Subject: [PATCH 4/5] Fix: Correct import path for useWindowDimensions in CameraCaptureDialog.tsx --- src/components/Files/CameraCaptureDialog.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Files/CameraCaptureDialog.tsx b/src/components/Files/CameraCaptureDialog.tsx index ba96214d4a2..96635919af2 100644 --- a/src/components/Files/CameraCaptureDialog.tsx +++ b/src/components/Files/CameraCaptureDialog.tsx @@ -4,7 +4,7 @@ import DialogModal from "../Common/Dialog"; import ButtonV2, { Submit } from "../Common/components/ButtonV2"; import { t } from "i18next"; import { useCallback, useEffect, useRef, useState } from "react"; -import useWindowDimensions from "../../Common/hooks/useWindowDimensions"; +import useWindowDimensions from "@/common/hooks/useWindowDimensions"; import * as Notify from "../../Utils/Notifications"; export interface CameraCaptureDialogProps { From 72b7861c56c8cc78b8c5fc6e987ecff04e784ec7 Mon Sep 17 00:00:00 2001 From: Bodhish Thomas Date: Sun, 27 Oct 2024 15:11:39 -0700 Subject: [PATCH 5/5] Use @ for loading files --- src/components/Files/CameraCaptureDialog.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Files/CameraCaptureDialog.tsx b/src/components/Files/CameraCaptureDialog.tsx index 96635919af2..81981c9bf3a 100644 --- a/src/components/Files/CameraCaptureDialog.tsx +++ b/src/components/Files/CameraCaptureDialog.tsx @@ -1,7 +1,7 @@ import Webcam from "react-webcam"; import CareIcon from "../../CAREUI/icons/CareIcon"; -import DialogModal from "../Common/Dialog"; -import ButtonV2, { Submit } from "../Common/components/ButtonV2"; +import DialogModal from "@/components/Common/Dialog"; +import ButtonV2, { Submit } from "@/components/Common/components/ButtonV2"; import { t } from "i18next"; import { useCallback, useEffect, useRef, useState } from "react"; import useWindowDimensions from "@/common/hooks/useWindowDimensions";