diff --git a/src/App.tsx b/src/App.tsx index 4eb405df..db82afcb 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -9,12 +9,9 @@ import StarredChatsPage from "./pages/starred-chat-page"; import { AppContext } from "./utils/app-context"; import { CookiesProvider } from "react-cookie"; import { send } from "./components/websocket"; - import { toast, Toaster } from "react-hot-toast"; - import { socket } from "./socket"; import { map, reduce, uniq } from "lodash"; - import { initialState } from "./utils/initial-states"; import { UserInput } from "./components/UserInput"; import { useDispatch, useSelector } from "react-redux"; diff --git a/src/components/recorder/index.jsx b/src/components/recorder/index.jsx new file mode 100644 index 00000000..8f6ba1f8 --- /dev/null +++ b/src/components/recorder/index.jsx @@ -0,0 +1,141 @@ +import { useState, useEffect } from "react"; +import stop from "./stop2.gif"; +import start from "./start2.svg"; +import styles from "./styles.module.css"; +import toast from "react-hot-toast"; +import axios from "axios"; +import { + logToAndroid, + triggerEventInAndroid, +} from "../../utils/android-events"; +import FullScreenLoader from "../FullScreenLoader"; + +const RenderVoiceRecorder = ({ setInputMsg }) => { + const [mediaRecorder, setMediaRecorder] = useState(null); + const [apiCallStatus, setApiCallStatus] = useState("idle"); + const startRecording = async () => { + try { + const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); + const recorder = new MediaRecorder(stream); + + recorder.ondataavailable = (event) => { + if (event.data.size > 0) { + makeComputeAPICall(event.data); + } + }; + + recorder.start(); + setMediaRecorder(recorder); + } catch (error) { + console.error(error); + setApiCallStatus("error"); + toast.error(`Something went wrong in recording audio`); + } + }; + + const stopRecording = () => { + if (mediaRecorder && mediaRecorder.state === "recording") { + mediaRecorder.stop(); + } + }; + + useEffect(() => { + return () => { + if (mediaRecorder) { + mediaRecorder.stop(); + } + }; + }, [mediaRecorder]); + + + const makeComputeAPICall = async (blob) => { + setApiCallStatus('processing'); + toast.success(`प्रतीक्षा करें ...`); + let data = new FormData(); + data.append("file", blob, "audio.wav"); + data.append("disablePostProcessor", "true"); + + const apiEndpoint = localStorage.getItem('promptUrl') || process.env.REACT_APP_BASE_URL; + const authToken = localStorage.getItem('promptToken'); + let config = { + method: "post", + maxBodyLength: Infinity, + url: `${apiEndpoint}/aitools/asr?language=hi`, + headers: { + 'Authorization': `Bearer ${authToken}`, + }, + data: data, + }; + + function replaceDandaCharacter(inputString) { + const regex = /।/g; + const replacedString = inputString.replace(regex, ""); + return replacedString; + } + + axios + .request(config) + .then((response) => { + setInputMsg(replaceDandaCharacter(response.data.text)); + setApiCallStatus("idle"); + }) + .catch((error) => { + console.log(error); + setApiCallStatus("error"); + toast.error(`Something went wrong :${error.message}`); + }); + }; + + + return ( +
+ {apiCallStatus === "processing" && } +
+ {mediaRecorder && mediaRecorder.state === "recording" ? ( +
+ stopIcon { + stopRecording(); + }} + style={{ cursor: "pointer" }} + /> +
+ ) : ( +
+ startIcon { + ev.preventDefault(); + logToAndroid(`debug isPermissionGranted`); + startRecording() + try { + const isAvailable = await window?.androidInteract?.isPermissionGranted(); + logToAndroid(`debug isPermissionGranted return value:${isAvailable}`); + if(isAvailable){ + logToAndroid(`debug isPermissionGranted available`); + startRecording() + } + else + { + logToAndroid(`debug isPermissionGranted false`); + triggerEventInAndroid("onMicClick");} + } catch (err) { + logToAndroid( + `debug error in getting mic permission:${JSON.stringify(err)}` + ); + } + }} + style={{ cursor: "pointer" }} + /> +
+ )} +
+
+ ); +}; + +export default RenderVoiceRecorder; diff --git a/src/components/recorder/start2.svg b/src/components/recorder/start2.svg new file mode 100644 index 00000000..92804f5f --- /dev/null +++ b/src/components/recorder/start2.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/recorder/stop2.gif b/src/components/recorder/stop2.gif new file mode 100644 index 00000000..9dcfd9aa Binary files /dev/null and b/src/components/recorder/stop2.gif differ diff --git a/src/components/recorder/styles.module.css b/src/components/recorder/styles.module.css new file mode 100644 index 00000000..c55c8061 --- /dev/null +++ b/src/components/recorder/styles.module.css @@ -0,0 +1,12 @@ +.center { + display: block; + height: 100%; + width: 100%; + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} \ No newline at end of file diff --git a/src/components/search/index.tsx b/src/components/search/index.tsx index 6a100281..5e258efd 100644 --- a/src/components/search/index.tsx +++ b/src/components/search/index.tsx @@ -1,6 +1,7 @@ import { useEffect, useRef, useState } from "react"; import styles from "./index.module.css"; -import { FaSearch, FaTimes } from "react-icons/fa"; +import { FaSearch } from "react-icons/fa"; +import RenderVoiceRecorder from "../recorder"; import { Box } from "@chakra-ui/react"; @@ -61,16 +62,7 @@ function SearchBar({ onChange }) { {showSearchInput ? (
- { - setIsFocused(false); - setIsHovered(false); - setValue(""); - setShowSearchInput(false); - }} - /> - +
) : ( { - console.log({session,toUser}) + if (toUser?.number === null || toUser?.number === 'null') { socket?.emit('botRequest', { content: { diff --git a/src/store/actions/fetchHistory.ts b/src/store/actions/fetchHistory.ts index 817f21ff..e661b44d 100644 --- a/src/store/actions/fetchHistory.ts +++ b/src/store/actions/fetchHistory.ts @@ -8,7 +8,6 @@ export const fetchHistory = createAsyncThunk( async (data, thunk) => { try { const url = getConvHistoryUrl(data); - console.log({url}) const response = await axios.get(url); return response?.data?.result?.records; } catch (err) { diff --git a/src/utils/android-events.ts b/src/utils/android-events.ts index 99fe5c83..224d97f2 100644 --- a/src/utils/android-events.ts +++ b/src/utils/android-events.ts @@ -2,7 +2,7 @@ import moment from "moment"; export const logToAndroid = (text: string) => { window && window?.androidInteract?.log(text); - // console.log(text); + }; export const sendEventToAndroid = (key: string, value: any) => { diff --git a/src/utils/normalize-chats.ts b/src/utils/normalize-chats.ts index 6c5b7864..42ff4f21 100644 --- a/src/utils/normalize-chats.ts +++ b/src/utils/normalize-chats.ts @@ -5,7 +5,7 @@ import moment from 'moment'; export const normalizedChat = (chats: any): any => { const sortedChats = sortBy( filter( - chats?.map((chat: any) => {console.log(chat); return { + chats?.map((chat: any) => ( { ...chat, disabled: true, text: chat?.payload?.text === 'This conversation has expired now. Please contact your state admin to seek help with this.' ? "यह फॉर्म समाप्त हो गया है !": chat?.payload?.text, @@ -19,7 +19,7 @@ export const normalizedChat = (chats: any): any => { toUpper(JSON.parse(localStorage.getItem('currentUser'))?.startingMessage), // toUpper(currentUser?.startingMessage), time: moment(chat.sentTimestamp || chat.repliedTimestamp).valueOf() - }}), + })), { isIgnore: false } ), ['time', 'messageState']