more clarity for this layer

This commit is contained in:
talksik
2022-05-13 08:08:53 -05:00
parent 10120bc80e
commit 98b559e972
@@ -26,212 +26,146 @@ type LineIdToMasterLine = {
interface IRealTimeRoomProvider { interface IRealTimeRoomProvider {
roomsMap: LineIdToMasterLine; roomsMap: LineIdToMasterLine;
selectedRoom?: MasterLineData;
// untunes from previous and tunes into new room
handleSelectRoom?: (roomId: string) => void;
} }
const RealTimeRoomContext = React.createContext<IRealTimeRoomProvider>({ roomsMap: {} }); const RealTimeRoomContext = React.createContext<IRealTimeRoomProvider>({ roomsMap: {} });
// handles reads of new data
// does NOT handle sending socket emissions
export function RealTimeRoomProvider({ children }: { children: React.ReactChild }) { export function RealTimeRoomProvider({ children }: { children: React.ReactChild }) {
const { rooms } = useRooms(); const { rooms } = useRooms();
const { $ws } = useSockets(); const { $ws } = useSockets();
const [realTimeRoomMap, setRealTimeRoomMap] = useState<LineIdToMasterLine>({}); const [realTimeRoomMap, setRealTimeRoomMap] = useState<LineIdToMasterLine>({});
useEffect(() => { useEffect(() => {
if (rooms.value) { /**
/** * initiate listeners
* initiate listeners */
*/
/** /**
* TODO: P0 : notified that someone else added me to a line they created * TODO: P0 : notified that someone else added me to a line they created
*/ */
// 1. get the new line from axios or just from the ws itself // 1. get the new line from axios or just from the ws itself
// 2. add it to the lines map with all of the right data // 2. add it to the lines map with all of the right data
// 3. make sure to connect to it as if it's inbox material // 3. make sure to connect to it as if it's inbox material
// when me or anyone just initially connects to line // when me or anyone just initially connects to line
$ws.on(ServerResponseChannels.SOMEONE_CONNECTED_TO_LINE, (res: SomeoneConnectedResponse) => { $ws.on(ServerResponseChannels.SOMEONE_CONNECTED_TO_LINE, (res: SomeoneConnectedResponse) => {
console.log( console.log(
`connected to line...here are all of the updated in the conected line ${res.lineId}...this isn't reliable considering it's not updated later`, `connected to line...here are all of the updated in the conected line ${res.lineId}...this isn't reliable considering it's not updated later`,
res.allConnectedIntoUserIds, res.allConnectedIntoUserIds,
); );
setRealTimeRoomMap((prevLinesMap) => { setRealTimeRoomMap((prevLinesMap) => {
const newMap = { ...prevLinesMap }; const newMap = { ...prevLinesMap };
if (newMap[res.lineId]) if (newMap[res.lineId])
newMap[res.lineId].connectedMemberIds = [ newMap[res.lineId].connectedMemberIds = [
...(newMap[res.lineId]?.connectedMemberIds ?? []), ...(newMap[res.lineId]?.connectedMemberIds ?? []),
res.userId, res.userId,
]; ];
return newMap; return newMap;
});
}); });
});
// someone tuning in, including perhaps me | either toggled in or just temporary // someone tuning in, including perhaps me | either toggled in or just temporary
$ws.on(ServerResponseChannels.SOMEONE_TUNED_INTO_LINE, (res: SomeoneTunedResponse) => { $ws.on(ServerResponseChannels.SOMEONE_TUNED_INTO_LINE, (res: SomeoneTunedResponse) => {
console.log(`here are all of updated users in the tuned in room`, res.allTunedIntoUserIds);
// TODO: if toggled in, make sure to update the current line member in the lines map so that
// we can know to untune if user selects another line
// below, we are setting the list of tuned in folks based on fresh list from the server
// better than just adding and removing? i think so, but have to handle not interrupting existing peer connections as this changes
setRealTimeRoomMap((prevLinesMap) => {
const newMap = { ...prevLinesMap };
if (newMap[res.lineId]) {
newMap[res.lineId].tunedInMemberIds = res.allTunedIntoUserIds;
// if user is me, make sure to show me my updated line member association
if (newMap[res.lineId].currentUserMember?.userId.toString() === res.userId) {
newMap[res.lineId].currentUserMember.lastVisitDate = new Date();
newMap[res.lineId].currentUserMember.state = res.toggledIn
? LineMemberState.TUNED
: LineMemberState.INBOX;
}
// TODO: update the relevant lineMember (based on which userId is given): state and last visit date if current user is joining
// and not just if it's the current user toggling in
// right now, we just want user to know number of folks tuned and no need to expose who is toggle tuned...that lineMember can be stale
}
return newMap;
});
});
$ws.on(
ServerResponseChannels.SOMEONE_UNTUNED_FROM_LINE,
(res: SomeoneUntunedFromLineResponse) => {
console.log(`here are all of updated users in the tuned in room`, res.allTunedIntoUserIds); console.log(`here are all of updated users in the tuned in room`, res.allTunedIntoUserIds);
// TODO: if toggled in, make sure to update the current line member in the lines map so that // TODO: if toggled in, make sure to update the current line member in the lines map so that
// we can know to untune if user selects another line // we can know to untune if user selects another line
// below, we are setting the list of tuned in folks based on fresh list from the server
// better than just adding and removing? i think so, but have to handle not interrupting existing peer connections as this changes
setRealTimeRoomMap((prevLinesMap) => { setRealTimeRoomMap((prevLinesMap) => {
const newMap = { ...prevLinesMap }; const newMap = { ...prevLinesMap };
if (newMap[res.lineId]) { // TODO: update the relevant lineMember (based on which userId is given): state and last visit date if current user is joining
newMap[res.lineId].tunedInMemberIds = res.allTunedIntoUserIds;
// if user is me, make sure to show me my updated line member association if (newMap[res.lineId]) newMap[res.lineId].tunedInMemberIds = res.allTunedIntoUserIds;
if (newMap[res.lineId].currentUserMember?.userId.toString() === res.userId) {
newMap[res.lineId].currentUserMember.lastVisitDate = new Date();
newMap[res.lineId].currentUserMember.state = res.toggledIn
? LineMemberState.TUNED
: LineMemberState.INBOX;
}
// TODO: update the relevant lineMember (based on which userId is given): state and last visit date if current user is joining return newMap;
// and not just if it's the current user toggling in });
// right now, we just want user to know number of folks tuned and no need to expose who is toggle tuned...that lineMember can be stale },
);
$ws.on(
ServerResponseChannels.SOMEONE_STARTED_BROADCASTING,
(res: UserStartedBroadcastingResponse) => {
console.log('someone is starting to broadcast');
setRealTimeRoomMap((prevLinesMap) => {
const newMap = { ...prevLinesMap };
if (newMap[res.lineId])
newMap[res.lineId].currentBroadcastersUserIds = [
...(newMap[res.lineId].currentBroadcastersUserIds ?? []),
res.userId,
];
return newMap;
});
},
);
$ws.on(
ServerResponseChannels.SOMEONE_STOPPED_BROADCASTING,
(res: UserStoppedBroadcastingResponse) => {
setRealTimeRoomMap((prevLinesMap) => {
const newMap = { ...prevLinesMap };
if (newMap[res.lineId]?.currentBroadcastersUserIds) {
newMap[res.lineId].currentBroadcastersUserIds = newMap[
res.lineId
].currentBroadcastersUserIds.filter(
(broadcasterUserId) => broadcasterUserId !== res.userId,
);
} }
return newMap; return newMap;
}); });
}); },
);
$ws.on( return () => {
ServerResponseChannels.SOMEONE_UNTUNED_FROM_LINE, // ?perhaps only remove specific ones?
(res: SomeoneUntunedFromLineResponse) => { $ws.removeAllListeners();
console.log( };
`here are all of updated users in the tuned in room`, }, [realTimeRoomMap, $ws]);
res.allTunedIntoUserIds,
);
// TODO: if toggled in, make sure to update the current line member in the lines map so that
// we can know to untune if user selects another line
setRealTimeRoomMap((prevLinesMap) => {
const newMap = { ...prevLinesMap };
// TODO: update the relevant lineMember (based on which userId is given): state and last visit date if current user is joining
if (newMap[res.lineId]) newMap[res.lineId].tunedInMemberIds = res.allTunedIntoUserIds;
return newMap;
});
},
);
$ws.on(
ServerResponseChannels.SOMEONE_STARTED_BROADCASTING,
(res: UserStartedBroadcastingResponse) => {
console.log('someone is starting to broadcast');
setRealTimeRoomMap((prevLinesMap) => {
const newMap = { ...prevLinesMap };
if (newMap[res.lineId])
newMap[res.lineId].currentBroadcastersUserIds = [
...(newMap[res.lineId].currentBroadcastersUserIds ?? []),
res.userId,
];
return newMap;
});
},
);
$ws.on(
ServerResponseChannels.SOMEONE_STOPPED_BROADCASTING,
(res: UserStoppedBroadcastingResponse) => {
setRealTimeRoomMap((prevLinesMap) => {
const newMap = { ...prevLinesMap };
if (newMap[res.lineId]?.currentBroadcastersUserIds) {
newMap[res.lineId].currentBroadcastersUserIds = newMap[
res.lineId
].currentBroadcastersUserIds.filter(
(broadcasterUserId) => broadcasterUserId !== res.userId,
);
}
return newMap;
});
},
);
}
}, [rooms.value, $ws]);
/** handlers for emitting events to server */
const handleConnectToLine = useCallback(
(lineId: string) => {
$ws.emit(ServerRequestChannels.CONNECT_TO_LINE, new ConnectToLineRequest(lineId));
},
[$ws],
);
/**
* toggle into a specific line
* @param temporary: denotes whether we are just listening in or want to persist "toggling" it on so that it shows up in overlay
* TODO: have loading state for this particular part of context value
*/
const handleTuneToLine = useCallback(
(lineId: string, turnToggleOn = false) => {
// they already are in the socket room for updates including media connections and disconnections
// but set the flag so that the line row can know whether or not to start the webrtc process
// and know when to get out or disconnect from the webrtc when the flag turns off
$ws.emit(ServerRequestChannels.TUNE_INTO_LINE, new TuneToLineRequest(lineId, turnToggleOn));
},
[$ws],
);
const handleUnTuneToLine = useCallback(
(lineId: string) => {
// they already are in the socket room for updates including media connections and disconnections
// but set the flag so that the line row can know whether or not to start the webrtc process
// and know when to get out or disconnect from the webrtc when the flag turns off
$ws.emit(ServerRequestChannels.UNTUNE_FROM_LINE, new UntuneFromLineRequest(lineId));
},
[$ws],
);
/**
* This is when the user wants to tell everyone that they are streaming/broadcasting/buzzing to
* a specific line, whether they are toggle tuned or temporarily tuned in
*
* Note: They could be using push to talk or toggle broadcast
*
* Note: this is handling the data transmission as is the responsibility of this overall context provider
* and not necessarily the aspect of enabling and disabling streaming as webrtc is reliable enough for that
*
* @param lineId the line that the current user is talking into
*/
const handleStartBroadcast = useCallback(
(lineId: string) => {
// emit telling people
$ws.emit(ServerRequestChannels.BROADCAST_TO_LINE, new StartBroadcastingRequest(lineId));
},
[$ws],
);
const handleStopBroadcast = useCallback(
(lineId: string) => {
// emit telling people
$ws.emit(ServerRequestChannels.STOP_BROADCAST_TO_LINE, new StopBroadcastingRequest(lineId));
// ?handle recording here as well? or record the incoming stream instead?
// ?could just take in the audiochunks here and all, but not sure yet
},
[$ws],
);
// converts the initial rooms to a map
useEffect(() => { useEffect(() => {
if (rooms.value?.data?.masterLines?.length > 0) { if (rooms.value?.data?.masterLines?.length > 0) {
setRealTimeRoomMap((prevMappings) => { setRealTimeRoomMap((prevMappings) => {
@@ -247,32 +181,15 @@ export function RealTimeRoomProvider({ children }: { children: React.ReactChild
rooms.value.data.masterLines.forEach((masterLine) => { rooms.value.data.masterLines.forEach((masterLine) => {
const lineId = masterLine.lineDetails._id.toString(); const lineId = masterLine.lineDetails._id.toString();
newMap[lineId] = masterLine; newMap[lineId] = masterLine;
handleConnectToLine(lineId);
// tune into lines that I should be
if (masterLine.currentUserMember.state === LineMemberState.TUNED) {
// don't need to turn toggle on, it's already on
// ! CHANGE PARADIGM TO NOT INCLUDING TOGGLING IN REQUESTS WITH THE SAME AS TUNING IN
// right now, writing just because of later logic
handleTuneToLine(lineId, true);
}
}); });
return newMap; return newMap;
}); });
} }
}, [rooms.value, handleConnectToLine, handleTuneToLine, setRealTimeRoomMap]); }, [rooms.value, setRealTimeRoomMap]);
const handleSelectRoom = useCallback(
(roomId: string) => {
return realTimeRoomMap[roomId];
},
[realTimeRoomMap],
);
return ( return (
<RealTimeRoomContext.Provider value={{ roomsMap: realTimeRoomMap, handleSelectRoom }}> <RealTimeRoomContext.Provider value={{ roomsMap: realTimeRoomMap }}>
{' '} {' '}
</RealTimeRoomContext.Provider> </RealTimeRoomContext.Provider>
); );