adding in some boilerplate for comms
This commit is contained in:
@@ -42,7 +42,6 @@ const server = app.listen(PORT, () =>
|
|||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const io = require('socket.io')(server, {
|
const io = require('socket.io')(server, {
|
||||||
// todo: add authentication
|
|
||||||
cors: {
|
cors: {
|
||||||
origin: '*',
|
origin: '*',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -27,6 +27,34 @@ import useAuth from './AuthProvider';
|
|||||||
import { useImmer } from 'use-immer';
|
import { useImmer } from 'use-immer';
|
||||||
import useSockets from './SocketProvider';
|
import useSockets from './SocketProvider';
|
||||||
|
|
||||||
|
// responsible for managing devices, managing streams
|
||||||
|
// initiating calls, managing incoming calls
|
||||||
|
// joining room
|
||||||
|
// leaving room
|
||||||
|
// playing audio
|
||||||
|
// handling device switching
|
||||||
|
// handling muting and unmuting
|
||||||
|
// showing when there are problems
|
||||||
|
function useCommunications() {
|
||||||
|
const { $ws } = useSockets();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// select initial devices and create initial stream
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// go and create connection with everyone already here
|
||||||
|
const handleJoinRoom = useCallback((peopleAlreadyHere: string[]) => {
|
||||||
|
// create n peer objects
|
||||||
|
// for each
|
||||||
|
// - create a signal
|
||||||
|
// - send signal to the other person
|
||||||
|
// - return peer object
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return { handleJoinRoom };
|
||||||
|
}
|
||||||
|
|
||||||
|
// responsible for firing socket events from the local client
|
||||||
function useSocketFire() {
|
function useSocketFire() {
|
||||||
const { $ws } = useSockets();
|
const { $ws } = useSockets();
|
||||||
|
|
||||||
@@ -39,8 +67,6 @@ function useSocketFire() {
|
|||||||
|
|
||||||
const handleTuneIntoLine = useCallback(
|
const handleTuneIntoLine = useCallback(
|
||||||
(lineId: string) => {
|
(lineId: string) => {
|
||||||
// todo: use a connector to call the people in this line as this is me joining this room
|
|
||||||
|
|
||||||
$ws.emit(ServerRequestChannels.TUNE_INTO_LINE, new TuneToLineRequest(lineId));
|
$ws.emit(ServerRequestChannels.TUNE_INTO_LINE, new TuneToLineRequest(lineId));
|
||||||
},
|
},
|
||||||
[$ws],
|
[$ws],
|
||||||
@@ -83,6 +109,12 @@ export function ConversationProvider({ children }: { children: React.ReactNode }
|
|||||||
const { $ws } = useSockets();
|
const { $ws } = useSockets();
|
||||||
const { handleConnectToLine, handleTuneIntoLine, handleUntuneFromLine } = useSocketFire();
|
const { handleConnectToLine, handleTuneIntoLine, handleUntuneFromLine } = useSocketFire();
|
||||||
|
|
||||||
|
// fetch conversations
|
||||||
|
useEffect(() => {
|
||||||
|
doFetch();
|
||||||
|
}, [doFetch]);
|
||||||
|
|
||||||
|
// conversation socket listeners
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
$ws.on(ServerResponseChannels.SOMEONE_CONNECTED_TO_LINE, (res: SomeoneConnectedResponse) => {
|
$ws.on(ServerResponseChannels.SOMEONE_CONNECTED_TO_LINE, (res: SomeoneConnectedResponse) => {
|
||||||
setConversationMap((draft) => {
|
setConversationMap((draft) => {
|
||||||
@@ -123,10 +155,6 @@ export function ConversationProvider({ children }: { children: React.ReactNode }
|
|||||||
);
|
);
|
||||||
}, [$ws, setConversationMap]);
|
}, [$ws, setConversationMap]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
doFetch();
|
|
||||||
}, [doFetch]);
|
|
||||||
|
|
||||||
// add the conversation to the conversation map/client side cache
|
// add the conversation to the conversation map/client side cache
|
||||||
// has implications on realtime listening and also the ui on whether or not it's shown
|
// has implications on realtime listening and also the ui on whether or not it's shown
|
||||||
const handleAddConversationCache = useCallback(
|
const handleAddConversationCache = useCallback(
|
||||||
@@ -141,13 +169,15 @@ export function ConversationProvider({ children }: { children: React.ReactNode }
|
|||||||
|
|
||||||
handleConnectToLine(conversation._id.toString());
|
handleConnectToLine(conversation._id.toString());
|
||||||
|
|
||||||
|
// if it's in my priority list, tune into it automatically
|
||||||
const currMemberForConversation = conversation.members.find(
|
const currMemberForConversation = conversation.members.find(
|
||||||
(mem) => mem.email === user.email,
|
(mem) => mem.email === user.email,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (currMemberForConversation && currMemberForConversation.memberState === 'priority') {
|
if (currMemberForConversation && currMemberForConversation.memberState === 'priority') {
|
||||||
handleTuneIntoLine(conversation._id.toString());
|
handleTuneIntoLine(conversation._id.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo : if it's a
|
||||||
},
|
},
|
||||||
[setConversationMap, handleConnectToLine, handleTuneIntoLine, user],
|
[setConversationMap, handleConnectToLine, handleTuneIntoLine, user],
|
||||||
);
|
);
|
||||||
@@ -232,8 +262,7 @@ export function ConversationProvider({ children }: { children: React.ReactNode }
|
|||||||
handleTuneIntoLine,
|
handleTuneIntoLine,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
// !temporary fix for updated conversation content not being surfaced
|
||||||
// temporary fix for updated conversation content not being surfaced
|
|
||||||
// as the map value updates
|
// as the map value updates
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedConversation) {
|
if (selectedConversation) {
|
||||||
@@ -241,6 +270,7 @@ export function ConversationProvider({ children }: { children: React.ReactNode }
|
|||||||
}
|
}
|
||||||
}, [conversationMap, selectedConversation, setSelectedConversation]);
|
}, [conversationMap, selectedConversation, setSelectedConversation]);
|
||||||
|
|
||||||
|
// handling quick dial or creating a conversation
|
||||||
const handleStartConversation = useCallback(
|
const handleStartConversation = useCallback(
|
||||||
async (otherUsers: User[], conversationName?: string) => {
|
async (otherUsers: User[], conversationName?: string) => {
|
||||||
try {
|
try {
|
||||||
@@ -292,8 +322,47 @@ export function ConversationProvider({ children }: { children: React.ReactNode }
|
|||||||
[selectConversation],
|
[selectConversation],
|
||||||
);
|
);
|
||||||
|
|
||||||
// todo: open up a handler for children
|
// ============== STREAMING ===============
|
||||||
// to refetch all conversatinos or search for a particular conversation and add it to the list of conversations
|
// handle incoming calls and accept calls and create objects for them
|
||||||
|
useEffect(() => {
|
||||||
|
//
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleJoinRoom = useCallback(
|
||||||
|
(roomId: string) => {
|
||||||
|
// call up folks and then have listeners for the peer connection objects that we created
|
||||||
|
// such as when peer connection closes, we want to remove from our list of peers for such conversation
|
||||||
|
// error handler as well for the peer connection
|
||||||
|
// rest endpoint to get all of the folks in a certain room
|
||||||
|
},
|
||||||
|
[setConversationMap, $ws],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleLeaveRoom = useCallback(() => {
|
||||||
|
// untune from line
|
||||||
|
// destroy peer connections
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// share audio to foreground conversation | either push to talk or toggle broadcasting
|
||||||
|
const handleStartTalking = useCallback((record = false) => {
|
||||||
|
// if record, then start recording
|
||||||
|
// add stream if not there for this peer connection or just add track to stream
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleStopTalking = useCallback(() => {
|
||||||
|
// stop recording if was recording
|
||||||
|
// stop sharing audio | maybe stop track to avoid stereo distortion
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleShareVideo = useCallback(() => {
|
||||||
|
// add track and/or stream of video to the peer connections for currently selected room
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleShareScreen = useCallback(() => {
|
||||||
|
// add track and/or stream of screen to the peer connections for currently selected room
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// ============= END OF STREAMING MODULE ========
|
||||||
|
|
||||||
if (fetchState.error) {
|
if (fetchState.error) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ import useTerminal from './Terminal';
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function ConversationList() {
|
export function ConversationList() {
|
||||||
|
const { user } = useAuth();
|
||||||
|
|
||||||
const { omniSearch } = useSearch();
|
const { omniSearch } = useSearch();
|
||||||
|
|
||||||
const { conversationMap } = useConversations();
|
const { conversationMap } = useConversations();
|
||||||
@@ -49,6 +51,25 @@ export function ConversationList() {
|
|||||||
omniSearch(SUPPORT_DISPLAY_NAME);
|
omniSearch(SUPPORT_DISPLAY_NAME);
|
||||||
}, [omniSearch]);
|
}, [omniSearch]);
|
||||||
|
|
||||||
|
const masterConversations = useMemo(() => {
|
||||||
|
const priorityConversations: MasterConversation[] = [];
|
||||||
|
const inboxConversations: MasterConversation[] = [];
|
||||||
|
|
||||||
|
Object.values(conversationMap).forEach((currentMasterConversation) => {
|
||||||
|
const personalConvoMember = currentMasterConversation.members.find(
|
||||||
|
(mem) => mem._id.toString() === user._id.toString(),
|
||||||
|
);
|
||||||
|
if (personalConvoMember && personalConvoMember.memberState === 'priority') {
|
||||||
|
priorityConversations.push(currentMasterConversation);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
inboxConversations.push(currentMasterConversation);
|
||||||
|
});
|
||||||
|
|
||||||
|
return [priorityConversations, inboxConversations];
|
||||||
|
}, [conversationMap, user]);
|
||||||
|
|
||||||
if (Object.keys(conversationMap).length === 0) {
|
if (Object.keys(conversationMap).length === 0) {
|
||||||
return (
|
return (
|
||||||
<Stack direction={'column'} alignItems="center">
|
<Stack direction={'column'} alignItems="center">
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
|
import Conversation, { ConversationMember } from '@nirvana/core/models/conversation.model';
|
||||||
|
|
||||||
import { ContentBlock } from '@nirvana/core/models/content.model';
|
import { ContentBlock } from '@nirvana/core/models/content.model';
|
||||||
import Conversation from '@nirvana/core/models/conversation.model';
|
import Peer from 'simple-peer';
|
||||||
import User from '@nirvana/core/models/user.model';
|
import User from '@nirvana/core/models/user.model';
|
||||||
|
|
||||||
export type MasterConversation = Conversation & {
|
export type MasterConversation = Conversation & {
|
||||||
@@ -9,6 +11,17 @@ export type MasterConversation = Conversation & {
|
|||||||
// allows client side to have this pushed up in the list and can uncheck it once user is done with this
|
// allows client side to have this pushed up in the list and can uncheck it once user is done with this
|
||||||
// if action is take, normal ordering should take place with database upserts
|
// if action is take, normal ordering should take place with database upserts
|
||||||
temporaryOverrideSort?: boolean;
|
temporaryOverrideSort?: boolean;
|
||||||
|
|
||||||
|
room?: {
|
||||||
|
[userId: string]: {
|
||||||
|
peer: Peer;
|
||||||
|
stream?: MediaStream;
|
||||||
|
tracks?: MediaStreamTrack[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// all of audio clips, links, media, etc.
|
||||||
|
content?: ContentBlock[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ConversationMap = {
|
export type ConversationMap = {
|
||||||
|
|||||||
Reference in New Issue
Block a user