recording and sending thru sockets and back but nothing being recorded
This commit is contained in:
+11
-1
@@ -70,7 +70,17 @@ io.on("connection", function (socket: any) {
|
|||||||
/** User wants to send some update to a particular room */
|
/** User wants to send some update to a particular room */
|
||||||
socket.on(
|
socket.on(
|
||||||
SocketChannels.SEND_AUDIO_CLIP,
|
SocketChannels.SEND_AUDIO_CLIP,
|
||||||
(relationshipId: string, data: any) => {}
|
(relationshipId: string, audioChunks: any) => {
|
||||||
|
console.log(`new audio chunks received..routing to appropriate room!`);
|
||||||
|
console.log(relationshipId);
|
||||||
|
console.log(audioChunks);
|
||||||
|
|
||||||
|
io.in(relationshipId).emit(
|
||||||
|
SocketChannels.SEND_AUDIO_CLIP,
|
||||||
|
relationshipId,
|
||||||
|
audioChunks
|
||||||
|
);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// tell everyone in a room when someone is starting to speak
|
// tell everyone in a room when someone is starting to speak
|
||||||
|
|||||||
@@ -135,83 +135,13 @@ export function useConversationDetails(otherUserGoogleId: string) {
|
|||||||
export function useGetAllContactBasicDetails() {
|
export function useGetAllContactBasicDetails() {
|
||||||
const authTokens = useRecoilValue($authTokens);
|
const authTokens = useRecoilValue($authTokens);
|
||||||
|
|
||||||
// relationshipId's of the conversations where there is someone speaking
|
return useQuery(
|
||||||
const [speakingRooms, setSpeakingRooms] = useState<string[]>([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
socket.on(
|
|
||||||
SocketChannels.SEND_STARTED_SPEAKING,
|
|
||||||
(relationshipId: string) => {
|
|
||||||
console.log(`yayaya someone started speaking in ${relationshipId}!!!!`);
|
|
||||||
|
|
||||||
setSpeakingRooms((prevSpeakingRooms) => [
|
|
||||||
...prevSpeakingRooms,
|
|
||||||
relationshipId,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
socket.on(
|
|
||||||
SocketChannels.SEND_STOPPED_SPEAKING,
|
|
||||||
(relationshipId: string) => {
|
|
||||||
console.log(`stopped speaking in ${relationshipId}!!!!`);
|
|
||||||
|
|
||||||
setSpeakingRooms((prevSpeakingRooms) =>
|
|
||||||
prevSpeakingRooms.filter(
|
|
||||||
(relationshipRoomId) => relationshipRoomId !== relationshipId
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
socket.removeAllListeners(SocketChannels.SEND_STARTED_SPEAKING);
|
|
||||||
socket.removeAllListeners(SocketChannels.SEND_STOPPED_SPEAKING);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const reactQueryRes = useQuery(
|
|
||||||
Querytypes.GET_CONTACTS_RELATIONSHIPS,
|
Querytypes.GET_CONTACTS_RELATIONSHIPS,
|
||||||
() => getContactsBasicDetails(authTokens.idToken),
|
() => getContactsBasicDetails(authTokens.idToken),
|
||||||
{
|
{
|
||||||
refetchOnWindowFocus: false,
|
refetchOnWindowFocus: false,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (reactQueryRes.data) {
|
|
||||||
reactQueryRes.data.contactsDetails.map((contactDet) => {
|
|
||||||
// join the right rooms based on the relevant contacts/conversations returned here
|
|
||||||
socket.emit(
|
|
||||||
SocketChannels.JOIN_ROOM,
|
|
||||||
contactDet.relationship._id.toString()
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [reactQueryRes.isFetched]);
|
|
||||||
|
|
||||||
// go through all conversations and mutate adding in data
|
|
||||||
// on whether or not someone is speaking or not
|
|
||||||
if (reactQueryRes.data) {
|
|
||||||
reactQueryRes.data.contactsDetails.map((contactDet) => {
|
|
||||||
// if this contact/conversation is in the list of speaking ones, then change isSpeaking
|
|
||||||
if (speakingRooms.includes(contactDet.relationship._id.toString())) {
|
|
||||||
contactDet.isSpeaking = true;
|
|
||||||
} else {
|
|
||||||
contactDet.isSpeaking = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// todo: go through all content and add in the socket messages
|
|
||||||
// find out which convos have new content for user
|
|
||||||
// sort and get rid of duplicate messages for the clip timeline
|
|
||||||
// set the latest link for the view component
|
|
||||||
|
|
||||||
// sort the conversations according to this:
|
|
||||||
// live -> new messages -> speaking -> incoming requests
|
|
||||||
}
|
|
||||||
|
|
||||||
return reactQueryRes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========== MUTATIONS
|
// =========== MUTATIONS
|
||||||
|
|||||||
@@ -1,14 +1,81 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
import SocketChannels from "@nirvana/core/sockets/channels";
|
import SocketChannels from "@nirvana/core/sockets/channels";
|
||||||
import { socket } from "../nirvanaApp";
|
import { socket } from "../nirvanaApp";
|
||||||
import { useEffect } from "react";
|
import { useGetAllContactBasicDetails } from "./index";
|
||||||
|
|
||||||
export default function useSocketData() {
|
export default function useSocketData() {
|
||||||
|
// relationshipId's of the conversations where there is someone speaking
|
||||||
|
const [speakingRooms, setSpeakingRooms] = useState<string[]>([]);
|
||||||
|
|
||||||
|
const { data: allConvosDetsResponse, isFetched } =
|
||||||
|
useGetAllContactBasicDetails();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (allConvosDetsResponse) {
|
||||||
|
allConvosDetsResponse.contactsDetails.map((contactDet) => {
|
||||||
|
// join the right rooms based on the relevant contacts/conversations returned here
|
||||||
|
socket.emit(
|
||||||
|
SocketChannels.JOIN_ROOM,
|
||||||
|
contactDet.relationship._id.toString()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [isFetched]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
socket.on(
|
||||||
|
SocketChannels.SEND_STARTED_SPEAKING,
|
||||||
|
(relationshipId: string) => {
|
||||||
|
console.log(`yayaya someone started speaking in ${relationshipId}!!!!`);
|
||||||
|
|
||||||
|
setSpeakingRooms((prevSpeakingRooms) => [
|
||||||
|
...prevSpeakingRooms,
|
||||||
|
relationshipId,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
socket.on(
|
||||||
|
SocketChannels.SEND_STOPPED_SPEAKING,
|
||||||
|
(relationshipId: string) => {
|
||||||
|
console.log(`stopped speaking in ${relationshipId}!!!!`);
|
||||||
|
|
||||||
|
setSpeakingRooms((prevSpeakingRooms) =>
|
||||||
|
prevSpeakingRooms.filter(
|
||||||
|
(relationshipRoomId) => relationshipRoomId !== relationshipId
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
socket.on(
|
socket.on(
|
||||||
SocketChannels.SEND_AUDIO_CLIP,
|
SocketChannels.SEND_AUDIO_CLIP,
|
||||||
(relationshipId: string, audioChunks: any) => {
|
(relationshipId: string, audioChunks: any) => {
|
||||||
console.log(relationshipId);
|
console.log(relationshipId);
|
||||||
console.log(audioChunks);
|
console.log(audioChunks);
|
||||||
|
|
||||||
|
const audioBlob = new Blob(audioChunks);
|
||||||
|
const audioUrl = URL.createObjectURL(audioBlob);
|
||||||
|
const audio = new Audio(audioUrl);
|
||||||
|
audio.play();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
socket.removeAllListeners(SocketChannels.SEND_STARTED_SPEAKING);
|
||||||
|
socket.removeAllListeners(SocketChannels.SEND_STOPPED_SPEAKING);
|
||||||
|
socket.removeAllListeners(SocketChannels.SEND_AUDIO_CLIP);
|
||||||
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// todo: go through all content and add in the socket messages
|
||||||
|
// find out which convos have new content for user
|
||||||
|
// sort and get rid of duplicate messages for the clip timeline
|
||||||
|
// set the latest link for the view component
|
||||||
|
|
||||||
|
// sort the conversations according to this:
|
||||||
|
// live -> new messages -> speaking -> incoming requests
|
||||||
|
|
||||||
|
return { speakingRooms };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ const createWindow = (): void => {
|
|||||||
browserWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY);
|
browserWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY);
|
||||||
|
|
||||||
// Open the DevTools.
|
// Open the DevTools.
|
||||||
browserWindow.webContents.openDevTools({ mode: "right" });
|
browserWindow.webContents.openDevTools({ mode: "detach" });
|
||||||
};
|
};
|
||||||
|
|
||||||
// This method will be called when Electron has finished
|
// This method will be called when Electron has finished
|
||||||
|
|||||||
@@ -9,10 +9,12 @@ import UserAvatarWithStatus from "../../../components/User/userAvatarWithStatus"
|
|||||||
import UserStatusText from "../../../components/User/userStatusText";
|
import UserStatusText from "../../../components/User/userStatusText";
|
||||||
import { useGetAllContactBasicDetails } from "../../../controller";
|
import { useGetAllContactBasicDetails } from "../../../controller";
|
||||||
import { useRecoilState } from "recoil";
|
import { useRecoilState } from "recoil";
|
||||||
|
import useSocketData from "../../../controller/sockets";
|
||||||
|
|
||||||
export default function Conversations() {
|
export default function Conversations() {
|
||||||
const { data: contactDetailsListResponse, isLoading } =
|
const { data: contactDetailsListResponse, isLoading } =
|
||||||
useGetAllContactBasicDetails();
|
useGetAllContactBasicDetails();
|
||||||
|
const { speakingRooms } = useSocketData();
|
||||||
const [selectedConvo, setSelectedConvo] = useRecoilState(
|
const [selectedConvo, setSelectedConvo] = useRecoilState(
|
||||||
$selectedConversation
|
$selectedConversation
|
||||||
);
|
);
|
||||||
@@ -87,7 +89,9 @@ export default function Conversations() {
|
|||||||
<UserStatusText status={contactDetail.otherUser.status} />
|
<UserStatusText status={contactDetail.otherUser.status} />
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{contactDetail.isSpeaking ? (
|
{speakingRooms.includes(
|
||||||
|
contactDetail.relationship._id.toString()
|
||||||
|
) ? (
|
||||||
<span className="ml-auto">speaking...</span>
|
<span className="ml-auto">speaking...</span>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import { socket } from "../../../nirvanaApp";
|
|||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import { useRecoilState } from "recoil";
|
import { useRecoilState } from "recoil";
|
||||||
|
|
||||||
|
var audioChunks: any = [];
|
||||||
|
|
||||||
export default function SelectedConversation() {
|
export default function SelectedConversation() {
|
||||||
const [selectedConvo, setSelectedConvo] = useRecoilState(
|
const [selectedConvo, setSelectedConvo] = useRecoilState(
|
||||||
$selectedConversation
|
$selectedConversation
|
||||||
@@ -33,6 +35,7 @@ export default function SelectedConversation() {
|
|||||||
const [isRecording, setIsRecording] = useState<boolean>(false);
|
const [isRecording, setIsRecording] = useState<boolean>(false);
|
||||||
|
|
||||||
const [hasMicPermissions, sethasMicPermissions] = useState<boolean>(false);
|
const [hasMicPermissions, sethasMicPermissions] = useState<boolean>(false);
|
||||||
|
const [mediaRecorder, setMediaRecorder] = useState<MediaRecorder>();
|
||||||
|
|
||||||
// audio handling
|
// audio handling
|
||||||
// setting up recording permissions
|
// setting up recording permissions
|
||||||
@@ -41,10 +44,12 @@ export default function SelectedConversation() {
|
|||||||
// checking for permissions for recording
|
// checking for permissions for recording
|
||||||
// won't work in https!!!
|
// won't work in https!!!
|
||||||
navigator.mediaDevices
|
navigator.mediaDevices
|
||||||
.getUserMedia({ audio: true })
|
.getUserMedia({
|
||||||
|
audio: true,
|
||||||
|
})
|
||||||
.then((stream) => {
|
.then((stream) => {
|
||||||
// stop playing anything
|
const mediaRecorder = new MediaRecorder(stream);
|
||||||
// stopBothVideoAndAudio(stream);
|
setMediaRecorder(mediaRecorder);
|
||||||
|
|
||||||
console.log("Permission Granted");
|
console.log("Permission Granted");
|
||||||
sethasMicPermissions(true);
|
sethasMicPermissions(true);
|
||||||
@@ -62,6 +67,36 @@ export default function SelectedConversation() {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// todo: hacky way of re-linking event listeners once we have the relationship id
|
||||||
|
useEffect(() => {
|
||||||
|
if (mediaRecorder && convoDetailsResponse) {
|
||||||
|
mediaRecorder.addEventListener(
|
||||||
|
"dataavailable",
|
||||||
|
mediaRecorderDataAvailable
|
||||||
|
);
|
||||||
|
mediaRecorder.addEventListener("stop", mediaRecorderStop);
|
||||||
|
}
|
||||||
|
}, [mediaRecorder, convoDetailsResponse]);
|
||||||
|
|
||||||
|
const mediaRecorderDataAvailable = (event: any) => {
|
||||||
|
audioChunks.push(event.data);
|
||||||
|
};
|
||||||
|
|
||||||
|
const mediaRecorderStop = () => {
|
||||||
|
socket.emit(
|
||||||
|
SocketChannels.SEND_AUDIO_CLIP,
|
||||||
|
convoDetailsResponse.ourRelationship._id.toString(),
|
||||||
|
audioChunks
|
||||||
|
);
|
||||||
|
|
||||||
|
const audioBlob = new Blob(audioChunks);
|
||||||
|
const audioUrl = URL.createObjectURL(audioBlob);
|
||||||
|
const audio = new Audio(audioUrl);
|
||||||
|
audio.play();
|
||||||
|
|
||||||
|
audioChunks = [];
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// if selected, then change the bounds of this window as well
|
// if selected, then change the bounds of this window as well
|
||||||
if (selectedConvo) {
|
if (selectedConvo) {
|
||||||
@@ -163,11 +198,15 @@ export default function SelectedConversation() {
|
|||||||
const startRecording = async () => {
|
const startRecording = async () => {
|
||||||
socketStartedSpeaking();
|
socketStartedSpeaking();
|
||||||
setIsRecording(true);
|
setIsRecording(true);
|
||||||
|
|
||||||
|
mediaRecorder.start();
|
||||||
};
|
};
|
||||||
|
|
||||||
const stopRecording = () => {
|
const stopRecording = () => {
|
||||||
socketStopSpeaking();
|
socketStopSpeaking();
|
||||||
setIsRecording(false);
|
setIsRecording(false);
|
||||||
|
|
||||||
|
mediaRecorder.stop();
|
||||||
};
|
};
|
||||||
|
|
||||||
// emit to room/conversation that someone started speaking
|
// emit to room/conversation that someone started speaking
|
||||||
@@ -251,9 +290,6 @@ export default function SelectedConversation() {
|
|||||||
|
|
||||||
{renderMainContent()}
|
{renderMainContent()}
|
||||||
|
|
||||||
<button onClick={socketStartedSpeaking}>start speaking</button>
|
|
||||||
<button onClick={socketStopSpeaking}>stop speaking</button>
|
|
||||||
|
|
||||||
<span className="flex flex-row my-5 items-center justify-center space-x-5">
|
<span className="flex flex-row my-5 items-center justify-center space-x-5">
|
||||||
<span className="flex flex-row justify-center items-center p-1 rounded shadow-lg h-10 w-10 bg-slate-500 cursor-pointer">
|
<span className="flex flex-row justify-center items-center p-1 rounded shadow-lg h-10 w-10 bg-slate-500 cursor-pointer">
|
||||||
{isRecording ? (
|
{isRecording ? (
|
||||||
|
|||||||
Reference in New Issue
Block a user