cleaning a bunch and adding in the right handlers for sockets much cleaner
This commit is contained in:
+62
-61
@@ -1,24 +1,21 @@
|
|||||||
import { JwtClaims, authCheck } from "../middleware/auth";
|
import { JwtClaims, authCheck } from '../middleware/auth';
|
||||||
import {
|
import { Line, LineMember, LineMemberState } from '@nirvana/core/models/line.model';
|
||||||
Line,
|
import express, { Application, Request, Response } from 'express';
|
||||||
LineMember,
|
|
||||||
LineMemberState,
|
|
||||||
} from "@nirvana/core/models/line.model";
|
|
||||||
import express, { Application, Request, Response } from "express";
|
|
||||||
|
|
||||||
import Content from "@nirvana/core/models/content.model";
|
import Content from '@nirvana/core/models/content.model';
|
||||||
import CreateLineRequest from "@nirvana/core/requests/createLine.request";
|
import CreateLineRequest from '@nirvana/core/requests/createLine.request';
|
||||||
import GetConversationDetailsResponse from "@nirvana/core/responses/getConversationDetails.response";
|
import GetConversationDetailsResponse from '@nirvana/core/responses/getConversationDetails.response';
|
||||||
import GetDmConversationByOtherUserIdResponse from "@nirvana/core/responses/getDmConversationByOtherUserId.response";
|
import GetDmConversationByOtherUserIdResponse from '@nirvana/core/responses/getDmConversationByOtherUserId.response';
|
||||||
import GetUserLinesResponse from "@nirvana/core/responses/getUserLines.response";
|
import GetUserLinesResponse from '@nirvana/core/responses/getUserLines.response';
|
||||||
import { LineService } from "../services/line.service";
|
import { LineService } from '../services/line.service';
|
||||||
import MasterLineData from "@nirvana/core/models/masterLineData.model";
|
import MasterLineData from '@nirvana/core/models/masterLineData.model';
|
||||||
import NirvanaResponse from "../../core/responses/nirvanaResponse";
|
import NirvanaResponse from '@nirvana/core/responses/nirvanaResponse';
|
||||||
import { ObjectId } from "mongodb";
|
import { ObjectId } from 'mongodb';
|
||||||
import Relationship from "@nirvana/core/models/relationship.model";
|
import Relationship from '@nirvana/core/models/relationship.model';
|
||||||
import { User } from "@nirvana/core/models/user.model";
|
import { User } from '@nirvana/core/models/user.model';
|
||||||
import { UserService } from "../services/user.service";
|
import { UserService } from '../services/user.service';
|
||||||
import { collections } from "../services/database.service";
|
import { collections } from '../services/database.service';
|
||||||
|
import UpdateLineMemberState from '@nirvana/core/requests/updateLineMemberState.request';
|
||||||
|
|
||||||
export default function getLineRoutes() {
|
export default function getLineRoutes() {
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
@@ -29,13 +26,16 @@ export default function getLineRoutes() {
|
|||||||
// router.get("/:otherUserGoogleUserId", authCheck, getConversationDetails);
|
// router.get("/:otherUserGoogleUserId", authCheck, getConversationDetails);
|
||||||
|
|
||||||
// create a line
|
// create a line
|
||||||
router.post("/", authCheck, createLine);
|
router.post('/', authCheck, createLine);
|
||||||
|
|
||||||
// get all of user's lines
|
// get all of user's lines
|
||||||
router.get("/", authCheck, getUserLines);
|
router.get('/', authCheck, getUserLines);
|
||||||
|
|
||||||
|
// toggle tune into a line
|
||||||
|
router.post('/:lineId/state', authCheck, updateLineMemberState);
|
||||||
|
|
||||||
// get conversation between user and other user
|
// get conversation between user and other user
|
||||||
router.get("/dm/:otherUserId", authCheck, getDmByOtherUserId);
|
router.get('/dm/:otherUserId', authCheck, getDmByOtherUserId);
|
||||||
|
|
||||||
return router;
|
return router;
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,7 @@ async function getDmByOtherUserId(req: Request, res: Response) {
|
|||||||
res.status(200).json();
|
res.status(200).json();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
res.status(205).json("no such conversation between you two");
|
res.status(205).json('no such conversation between you two');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).json(error);
|
res.status(500).json(error);
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ async function createLine(req: Request, res: Response) {
|
|||||||
console.log(req.body);
|
console.log(req.body);
|
||||||
|
|
||||||
if (!reqObj?.otherMemberIds.length) {
|
if (!reqObj?.otherMemberIds.length) {
|
||||||
res.status(400).json("must provide member Ids");
|
res.status(400).json('must provide member Ids');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ async function createLine(req: Request, res: Response) {
|
|||||||
reqObj.lineName ?? undefined,
|
reqObj.lineName ?? undefined,
|
||||||
new Date(),
|
new Date(),
|
||||||
new Date(),
|
new Date(),
|
||||||
new ObjectId()
|
new ObjectId(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: validate that users exists before creating line members
|
// TODO: validate that users exists before creating line members
|
||||||
@@ -86,67 +86,74 @@ async function createLine(req: Request, res: Response) {
|
|||||||
const newLineMember = new LineMember(
|
const newLineMember = new LineMember(
|
||||||
newLine._id!,
|
newLine._id!,
|
||||||
new ObjectId(memId),
|
new ObjectId(memId),
|
||||||
LineMemberState.INBOX
|
LineMemberState.INBOX,
|
||||||
);
|
);
|
||||||
|
|
||||||
return newLineMember;
|
return newLineMember;
|
||||||
}) ?? [];
|
}) ?? [];
|
||||||
|
|
||||||
lineMembers.push(
|
lineMembers.push(
|
||||||
new LineMember(
|
new LineMember(newLine._id!, new ObjectId(userInfo.userId), LineMemberState.INBOX),
|
||||||
newLine._id!,
|
|
||||||
new ObjectId(userInfo.userId),
|
|
||||||
LineMemberState.INBOX
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const transactionResult = await LineService.createLine(
|
const transactionResult = await LineService.createLine(newLine, lineMembers);
|
||||||
newLine,
|
|
||||||
lineMembers
|
|
||||||
);
|
|
||||||
|
|
||||||
transactionResult
|
transactionResult
|
||||||
? res.status(200).json(new NirvanaResponse(newLine))
|
? res.status(200).json(new NirvanaResponse(newLine))
|
||||||
: res
|
: res.status(400).json(new NirvanaResponse(undefined, new Error('unable to create line')));
|
||||||
.status(400)
|
|
||||||
.json(
|
|
||||||
new NirvanaResponse(undefined, new Error("unable to create line"))
|
|
||||||
);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
res.status(500).json(error);
|
res.status(500).json(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function updateLineMemberState(req: Request, res: Response) {
|
||||||
|
try {
|
||||||
|
const userInfo = res.locals.userInfo as JwtClaims;
|
||||||
|
const { lineId } = req.params;
|
||||||
|
const request = req.body as UpdateLineMemberState;
|
||||||
|
|
||||||
|
// TODO: validation to check if user is actually a member of the line
|
||||||
|
|
||||||
|
const result = await LineService.updateLineMemberState(
|
||||||
|
lineId,
|
||||||
|
userInfo.userId,
|
||||||
|
request.newState,
|
||||||
|
);
|
||||||
|
|
||||||
|
return result?.ok
|
||||||
|
? res.status(200).json(new NirvanaResponse("successfully updated line member's state"))
|
||||||
|
: res
|
||||||
|
.status(400)
|
||||||
|
.json(new NirvanaResponse(undefined, new Error('not updated...something went wrong')));
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json(new NirvanaResponse(undefined, error as Error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function getUserLines(req: Request, res: Response) {
|
async function getUserLines(req: Request, res: Response) {
|
||||||
try {
|
try {
|
||||||
const userInfo = res.locals.userInfo as JwtClaims;
|
const userInfo = res.locals.userInfo as JwtClaims;
|
||||||
|
|
||||||
// get all of user's lineMember entries
|
// get all of user's lineMember entries
|
||||||
const userLineMembers = await LineService.getLineMembersByUserId(
|
const userLineMembers = await LineService.getLineMembersByUserId(userInfo.userId);
|
||||||
userInfo.userId
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!userLineMembers?.length) {
|
if (!userLineMembers?.length) {
|
||||||
const resObj = new GetUserLinesResponse([]);
|
const resObj = new GetUserLinesResponse([]);
|
||||||
|
|
||||||
res.json(
|
res.json(new NirvanaResponse(resObj, undefined, 'this user is not in any lines'));
|
||||||
new NirvanaResponse(resObj, undefined, "this user is not in any lines")
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lineIds =
|
const lineIds = userLineMembers?.map((lineMember) => lineMember.lineId) ?? [];
|
||||||
userLineMembers?.map((lineMember) => lineMember.lineId) ?? [];
|
|
||||||
|
|
||||||
// this will include the current user lineMember association to the line
|
// this will include the current user lineMember association to the line
|
||||||
const allLineMembers = await LineService.getLineMembersInLines(lineIds);
|
const allLineMembers = await LineService.getLineMembersInLines(lineIds);
|
||||||
|
|
||||||
const allLinesUsersIds: ObjectId[] = [];
|
const allLinesUsersIds: ObjectId[] = [];
|
||||||
allLineMembers?.map((currentLineMember) => {
|
allLineMembers?.map((currentLineMember) => {
|
||||||
if (currentLineMember?.userId)
|
if (currentLineMember?.userId) allLinesUsersIds.push(currentLineMember.userId);
|
||||||
allLinesUsersIds.push(currentLineMember.userId);
|
|
||||||
}) ?? [];
|
}) ?? [];
|
||||||
|
|
||||||
// get all users relevant here
|
// get all users relevant here
|
||||||
@@ -174,34 +181,28 @@ async function getUserLines(req: Request, res: Response) {
|
|||||||
// get the user lineMember assoc out of the list of the lineMembers for this line
|
// get the user lineMember assoc out of the list of the lineMembers for this line
|
||||||
const userLineMember = associatedLineMembersForLine?.find(
|
const userLineMember = associatedLineMembersForLine?.find(
|
||||||
(currentLineMemberForLine) =>
|
(currentLineMemberForLine) =>
|
||||||
currentLineMemberForLine.userId.toString() === userInfo.userId
|
currentLineMemberForLine.userId.toString() === userInfo.userId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (userLineMember) {
|
if (userLineMember) {
|
||||||
// take out the current user from the "other" line members list now
|
// take out the current user from the "other" line members list now
|
||||||
|
|
||||||
associatedLineMembersForLine = associatedLineMembersForLine.filter(
|
associatedLineMembersForLine = associatedLineMembersForLine.filter(
|
||||||
(currentLineMember) =>
|
(currentLineMember) => currentLineMember.userId.toString() !== userInfo.userId,
|
||||||
currentLineMember.userId.toString() !== userInfo.userId
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// get the user objects for all of the other members
|
// get the user objects for all of the other members
|
||||||
const otherUsers: User[] = [];
|
const otherUsers: User[] = [];
|
||||||
associatedLineMembersForLine.forEach((currentLineMember) => {
|
associatedLineMembersForLine.forEach((currentLineMember) => {
|
||||||
const foundUserObject = allRelevantUsers?.find((currentUser) =>
|
const foundUserObject = allRelevantUsers?.find((currentUser) =>
|
||||||
currentUser._id?.equals(currentLineMember.userId)
|
currentUser._id?.equals(currentLineMember.userId),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (foundUserObject) otherUsers.push(foundUserObject);
|
if (foundUserObject) otherUsers.push(foundUserObject);
|
||||||
});
|
});
|
||||||
|
|
||||||
masterLines.push(
|
masterLines.push(
|
||||||
new MasterLineData(
|
new MasterLineData(currentLine, userLineMember, associatedLineMembersForLine, otherUsers),
|
||||||
currentLine,
|
|
||||||
userLineMember,
|
|
||||||
associatedLineMembersForLine,
|
|
||||||
otherUsers
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
+16
-114
@@ -7,6 +7,7 @@ import {
|
|||||||
ServerRequestChannels,
|
ServerRequestChannels,
|
||||||
ServerResponseChannels,
|
ServerResponseChannels,
|
||||||
SomeoneConnectedResponse,
|
SomeoneConnectedResponse,
|
||||||
|
SomeoneDisconnectedResponse,
|
||||||
SomeoneTunedResponse,
|
SomeoneTunedResponse,
|
||||||
SomeoneUntunedFromLineResponse,
|
SomeoneUntunedFromLineResponse,
|
||||||
StartBroadcastingRequest,
|
StartBroadcastingRequest,
|
||||||
@@ -84,23 +85,12 @@ export default function InitializeWs(io: any) {
|
|||||||
const roomName = `connectedLine:${req.lineId}`;
|
const roomName = `connectedLine:${req.lineId}`;
|
||||||
socket.join(roomName);
|
socket.join(roomName);
|
||||||
|
|
||||||
console.log(`${socket.id} now in rooms ${socket.rooms}`);
|
|
||||||
|
|
||||||
const clientUserIdsInRoom = [...(io.sockets.adapter.rooms.get(roomName) ?? [])].map(
|
|
||||||
(otherUserSocketId: string) => socketIdsToUserIds[otherUserSocketId],
|
|
||||||
);
|
|
||||||
|
|
||||||
io.in(roomName).emit(
|
io.in(roomName).emit(
|
||||||
ServerResponseChannels.SOMEONE_CONNECTED_TO_LINE,
|
ServerResponseChannels.SOMEONE_CONNECTED_TO_LINE,
|
||||||
new SomeoneConnectedResponse(req.lineId, userInfo.userId, clientUserIdsInRoom),
|
new SomeoneConnectedResponse(req.lineId, userInfo.userId),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: handle when user wants to completely leave a line (delete or removed from one)
|
|
||||||
*/
|
|
||||||
socket.on(ServerRequestChannels.DISCONNECT_FROM_LINE, () => console.log('not implemented'));
|
|
||||||
|
|
||||||
/** TUNE | User tunes into the line either temporarily or toggled in */
|
/** TUNE | User tunes into the line either temporarily or toggled in */
|
||||||
socket.on(ServerRequestChannels.TUNE_INTO_LINE, async (req: TuneToLineRequest) => {
|
socket.on(ServerRequestChannels.TUNE_INTO_LINE, async (req: TuneToLineRequest) => {
|
||||||
console.log(`${socket.id} user TUNED into room for line ${req.lineId}`);
|
console.log(`${socket.id} user TUNED into room for line ${req.lineId}`);
|
||||||
@@ -108,38 +98,12 @@ export default function InitializeWs(io: any) {
|
|||||||
const roomName = `tunedLine:${req.lineId}`;
|
const roomName = `tunedLine:${req.lineId}`;
|
||||||
socket.join(roomName);
|
socket.join(roomName);
|
||||||
|
|
||||||
console.log(`${socket.id} now in rooms ${Object.keys(socket.rooms)}`);
|
|
||||||
|
|
||||||
// persist tuning in if user is toggle tuning in
|
|
||||||
if (req.keepTunedIn) {
|
|
||||||
await LineService.updateLineMemberState(
|
|
||||||
req.lineId,
|
|
||||||
userInfo.userId,
|
|
||||||
LineMemberState.TUNED,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
await LineService.updateLineMemberState(
|
|
||||||
req.lineId,
|
|
||||||
userInfo.userId,
|
|
||||||
LineMemberState.INBOX,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const clientUserIdsInRoom = [...(io.sockets.adapter.rooms.get(roomName) ?? [])].map(
|
|
||||||
(otherUserSocketId: string) => socketIdsToUserIds[otherUserSocketId],
|
|
||||||
);
|
|
||||||
|
|
||||||
// we want to notify everyone connected to the line even if they are not tuned in
|
// we want to notify everyone connected to the line even if they are not tuned in
|
||||||
const connectedLineRoomName = `connectedLine:${req.lineId}`;
|
const connectedLineRoomName = `connectedLine:${req.lineId}`;
|
||||||
|
|
||||||
io.in(connectedLineRoomName).emit(
|
io.in(connectedLineRoomName).emit(
|
||||||
ServerResponseChannels.SOMEONE_TUNED_INTO_LINE,
|
ServerResponseChannels.SOMEONE_TUNED_INTO_LINE,
|
||||||
new SomeoneTunedResponse(
|
new SomeoneTunedResponse(req.lineId, userInfo.userId),
|
||||||
req.lineId,
|
|
||||||
userInfo.userId,
|
|
||||||
clientUserIdsInRoom,
|
|
||||||
req.keepTunedIn,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -151,18 +115,14 @@ export default function InitializeWs(io: any) {
|
|||||||
const roomName = `tunedLine:${req.lineId}`;
|
const roomName = `tunedLine:${req.lineId}`;
|
||||||
socket.leave(roomName);
|
socket.leave(roomName);
|
||||||
|
|
||||||
console.log('someone left room');
|
console.log(`${userInfo.userId} left room: ${roomName}`);
|
||||||
|
|
||||||
const clientUserIdsInRoom = [...(io.sockets.adapter.rooms.get(roomName) ?? [])].map(
|
|
||||||
(otherUserSocketId: string) => socketIdsToUserIds[otherUserSocketId],
|
|
||||||
);
|
|
||||||
|
|
||||||
// we want to notify everyone connected to the line even if they are not tuned in
|
// we want to notify everyone connected to the line even if they are not tuned in
|
||||||
const connectedLineRoomName = `connectedLine:${req.lineId}`;
|
const connectedLineRoomName = `connectedLine:${req.lineId}`;
|
||||||
|
|
||||||
io.in(connectedLineRoomName).emit(
|
io.in(connectedLineRoomName).emit(
|
||||||
ServerResponseChannels.SOMEONE_UNTUNED_FROM_LINE,
|
ServerResponseChannels.SOMEONE_UNTUNED_FROM_LINE,
|
||||||
new SomeoneUntunedFromLineResponse(req.lineId, userInfo.userId, clientUserIdsInRoom),
|
new SomeoneUntunedFromLineResponse(req.lineId, userInfo.userId),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -186,21 +146,6 @@ export default function InitializeWs(io: any) {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// socket.on(SocketChannels.SEND_SIGNAL, async (payload: SendSignal) => {
|
|
||||||
// console.log(payload);
|
|
||||||
|
|
||||||
// const sendingBackData: ReceiveSignal = {
|
|
||||||
// simplePeerSignal: payload.simplePeerSignal,
|
|
||||||
// senderUserSocketId: socket.id,
|
|
||||||
// isGoingBackToInitiator: payload.isAnswerer ? true : false,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// io.to(payload.userSocketIdToSignal).emit(
|
|
||||||
// SocketChannels.RECEIVE_SIGNAL,
|
|
||||||
// sendingBackData
|
|
||||||
// );
|
|
||||||
// });
|
|
||||||
|
|
||||||
// tell the proper other user to create a local peer object for the one on one mesh connection
|
// tell the proper other user to create a local peer object for the one on one mesh connection
|
||||||
socket.on(ServerRequestChannels.RTC_CALL_REQUEST, (req: RtcCallRequest) => {
|
socket.on(ServerRequestChannels.RTC_CALL_REQUEST, (req: RtcCallRequest) => {
|
||||||
const userSocketId = userIdsToSocketIds[req.userIdToCall];
|
const userSocketId = userIdsToSocketIds[req.userIdToCall];
|
||||||
@@ -220,58 +165,25 @@ export default function InitializeWs(io: any) {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: not complete
|
// tell all people in all my lines that I am disconnecting or untuning
|
||||||
socket.on(ServerRequestChannels.GOING_INTO_FLOW_STATE, () => {
|
|
||||||
// change user object to persist this state
|
|
||||||
|
|
||||||
// get all of the connectedLine rooms of this person, and tell them that user is going into flow state
|
|
||||||
|
|
||||||
for (const roomName of socket.rooms) {
|
|
||||||
if (roomName !== socket.id) {
|
|
||||||
const lineId = roomName.split(':')[1];
|
|
||||||
if (roomName.includes('connectedLine')) {
|
|
||||||
// get fresh list of tuned in folks without me
|
|
||||||
const clientUserIdsInRoom = [...(io.sockets.adapter.rooms.get(roomName) ?? [])]
|
|
||||||
.filter((mappedSocketId) => mappedSocketId !== socket.id)
|
|
||||||
.map((otherUserSocketId: string) => socketIdsToUserIds[otherUserSocketId]);
|
|
||||||
|
|
||||||
// io.in(roomName).emit(
|
|
||||||
// ServerResponseChannels.SOMEONE_GOING_INTO_FLOW_STATE,
|
|
||||||
// new SomeoneGoingIntoFlowState(
|
|
||||||
|
|
||||||
// userInfo.userId
|
|
||||||
|
|
||||||
// )
|
|
||||||
// );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// tell all connected people that I am disconnecting
|
|
||||||
// tell tuned in folks that I am leaving the room
|
|
||||||
// tell the tuned in folks the new list of
|
// tell the tuned in folks the new list of
|
||||||
socket.on('disconnecting', (reason: any) => {
|
socket.on('disconnecting', (reason: any) => {
|
||||||
console.log(reason);
|
console.log(`someone disconnecting: ${reason}`);
|
||||||
|
|
||||||
console.log(socket.rooms);
|
console.log(socket.rooms);
|
||||||
|
|
||||||
for (const roomName of socket.rooms) {
|
for (const roomName of socket.rooms) {
|
||||||
if (roomName !== socket.id) {
|
if (roomName !== socket.id) {
|
||||||
const lineId = roomName.split(':')[1];
|
const lineId = roomName.split(':')[1];
|
||||||
if (roomName.includes('tunedLine')) {
|
|
||||||
// get fresh list of tuned in folks without me
|
|
||||||
const clientUserIdsInRoom = [...(io.sockets.adapter.rooms.get(roomName) ?? [])]
|
|
||||||
.filter((mappedSocketId) => mappedSocketId !== socket.id)
|
|
||||||
.map((otherUserSocketId: string) => socketIdsToUserIds[otherUserSocketId]);
|
|
||||||
|
|
||||||
io.in(roomName).emit(
|
const roomToTell = roomName.includes('tunedLine')
|
||||||
ServerResponseChannels.SOMEONE_UNTUNED_FROM_LINE,
|
? `connectedLine:${lineId}`
|
||||||
new SomeoneUntunedFromLineResponse(lineId, userInfo.userId, clientUserIdsInRoom),
|
: roomName;
|
||||||
);
|
|
||||||
} else if (roomName.includes('connectedLine')) {
|
io.in(roomToTell).emit(
|
||||||
//TODO: p3: client doesn't really to know right now in our flow as this list is not really used
|
ServerResponseChannels.SOMEONE_DISCONNECTED_FROM_LINE,
|
||||||
// io.in(roomName).emit(ServerResponseChannels.SOMEONE_UNTUNED_FROM_LINE, new SomeoneDisconnected(lineId, userInfo.userId, clientUserIdsInRoom));
|
new SomeoneDisconnectedResponse(lineId, userInfo.userId),
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -280,16 +192,6 @@ export default function InitializeWs(io: any) {
|
|||||||
socket.on('disconnect', () => {
|
socket.on('disconnect', () => {
|
||||||
delete socketIdsToUserIds[socket.id];
|
delete socketIdsToUserIds[socket.id];
|
||||||
delete userIdsToSocketIds[userInfo.userId];
|
delete userIdsToSocketIds[userInfo.userId];
|
||||||
|
|
||||||
// get all of the rooms of this socket
|
|
||||||
// notify everyone of this disconnection
|
|
||||||
|
|
||||||
console.log('user disconnected');
|
|
||||||
console.log(`list of sockets mappings in memory: ${socketIdsToUserIds}`);
|
|
||||||
|
|
||||||
console.log(socket.rooms);
|
|
||||||
|
|
||||||
// ! NOTIFY ALL CONNECTED LINES SO THAT THEY CAN REMOVE FROM THEIR SESSION CONNECTED USERS ARRAY AND TUNED IN ARRAY
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import { LineMemberState } from '../models/line.model';
|
||||||
|
export default class UpdateLineMemberState {
|
||||||
|
constructor(public newState: LineMemberState) {}
|
||||||
|
}
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import { ObjectId } from "mongodb";
|
|
||||||
import { RelationshipState } from "../models/relationship.model";
|
|
||||||
|
|
||||||
export default class UpdateRelationshipStateRequest {
|
|
||||||
constructor(
|
|
||||||
public relationshipId: ObjectId,
|
|
||||||
public newState: RelationshipState
|
|
||||||
) {}
|
|
||||||
}
|
|
||||||
@@ -1,68 +1,68 @@
|
|||||||
// ! NOTE: these are legacy and too much thinking in the developers head to understand the flow
|
// ! NOTE: these are legacy and too much thinking in the developers head to understand the flow
|
||||||
enum SocketChannels {
|
enum SocketChannels {
|
||||||
SEND_AUDIO_CLIP = "SEND_AUDIO_CLIP",
|
SEND_AUDIO_CLIP = 'SEND_AUDIO_CLIP',
|
||||||
SEND_USER_STATUS_UPDATE = "SEND_USER_STATUS_UPDATE",
|
SEND_USER_STATUS_UPDATE = 'SEND_USER_STATUS_UPDATE',
|
||||||
|
|
||||||
SEND_STARTED_SPEAKING = "SEND_STARTED_SPEAKING",
|
SEND_STARTED_SPEAKING = 'SEND_STARTED_SPEAKING',
|
||||||
SEND_STOPPED_SPEAKING = "SEND_STOPPED_SPEAKING",
|
SEND_STOPPED_SPEAKING = 'SEND_STOPPED_SPEAKING',
|
||||||
|
|
||||||
JOIN_LIVE_ROOM = "JOIN_LIVE_ROOM",
|
JOIN_LIVE_ROOM = 'JOIN_LIVE_ROOM',
|
||||||
GET_ALL_ACTIVE_SOCKET_IDS = "GET_ALL_ACTIVE_SOCKET_IDS",
|
GET_ALL_ACTIVE_SOCKET_IDS = 'GET_ALL_ACTIVE_SOCKET_IDS',
|
||||||
|
|
||||||
SEND_SIGNAL = "SEND_SIGNAL",
|
SEND_SIGNAL = 'SEND_SIGNAL',
|
||||||
|
|
||||||
RECEIVE_SIGNAL = "RECEIVE_SIGNAL",
|
RECEIVE_SIGNAL = 'RECEIVE_SIGNAL',
|
||||||
|
|
||||||
// v3
|
// v3
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* when someone connects to a line, whether tuned in or not
|
* when someone connects to a line, whether tuned in or not
|
||||||
*/
|
*/
|
||||||
CONNECT_TO_LINE = "CONNECT_TO_LINE",
|
CONNECT_TO_LINE = 'CONNECT_TO_LINE',
|
||||||
SOMEONE_CONNECTED_TO_LINE = "SOMEONE_CONNECTED_TO_LINE",
|
SOMEONE_CONNECTED_TO_LINE = 'SOMEONE_CONNECTED_TO_LINE',
|
||||||
|
|
||||||
TUNE_TO_LINE = "TUNE_TO_LINE",
|
TUNE_TO_LINE = 'TUNE_TO_LINE',
|
||||||
SOMEONE_TUNED_TO_LINE = "SOMEONE_TUNED_TO_LINE",
|
SOMEONE_TUNED_TO_LINE = 'SOMEONE_TUNED_TO_LINE',
|
||||||
|
|
||||||
SOMEONE_UNTUNED_FROM_LINE = "SOMEONE_UNTUNED_FROM_LINE",
|
SOMEONE_UNTUNED_FROM_LINE = 'SOMEONE_UNTUNED_FROM_LINE',
|
||||||
|
|
||||||
USER_BROADCAST_PUSH_PULL = "USER_BROADCAST_PUSH_PULL",
|
USER_BROADCAST_PUSH_PULL = 'USER_BROADCAST_PUSH_PULL',
|
||||||
}
|
}
|
||||||
|
|
||||||
// ! MAKE SURE THAT THE ENUMS BETWEEN REQUEST AND RESPONSE DON'T OVERLAP???
|
// ! MAKE SURE THAT THE ENUMS BETWEEN REQUEST AND RESPONSE DON'T OVERLAP???
|
||||||
// ?maybe won't matter since it's different for server and client?
|
// ?maybe won't matter since it's different for server and client?
|
||||||
export enum ServerRequestChannels {
|
export enum ServerRequestChannels {
|
||||||
CONNECT_TO_LINE = "CONNECT_TO_LINE",
|
CONNECT_TO_LINE = 'CONNECT_TO_LINE',
|
||||||
|
|
||||||
DISCONNECT_FROM_LINE = "DISCONNECT_FROM_LINE", // TODO: not implementing now
|
DISCONNECT_FROM_LINE = 'DISCONNECT_FROM_LINE', // TODO: not implementing now
|
||||||
|
|
||||||
TUNE_INTO_LINE = "TUNE_INTO_LINE", // pass in if user wants to toggle/persist? or is this just temporary?
|
TUNE_INTO_LINE = 'TUNE_INTO_LINE', // pass in if user wants to toggle/persist? or is this just temporary?
|
||||||
UNTUNE_FROM_LINE = "UNTUNE_FROM_LINE",
|
UNTUNE_FROM_LINE = 'UNTUNE_FROM_LINE',
|
||||||
|
|
||||||
BROADCAST_TO_LINE = "BROADCAST_TO_LINE",
|
BROADCAST_TO_LINE = 'BROADCAST_TO_LINE',
|
||||||
STOP_BROADCAST_TO_LINE = "STOP_BROADCAST_TO_LINE",
|
STOP_BROADCAST_TO_LINE = 'STOP_BROADCAST_TO_LINE',
|
||||||
|
|
||||||
RTC_CALL_REQUEST = "RTC_CALL_PREFIX",
|
RTC_CALL_REQUEST = 'RTC_CALL_PREFIX',
|
||||||
RTC_ANSWER_REQUEST = "RTC_ANSWER_REQUEST_PREFIX",
|
RTC_ANSWER_REQUEST = 'RTC_ANSWER_REQUEST_PREFIX',
|
||||||
|
|
||||||
GOING_INTO_FLOW_STATE = "GOING_INTO_FLOW_STATE",
|
GOING_INTO_FLOW_STATE = 'GOING_INTO_FLOW_STATE',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ServerResponseChannels {
|
export enum ServerResponseChannels {
|
||||||
SOMEONE_CONNECTED_TO_LINE = "SOMEONE_CONNECTED_TO_LINE",
|
SOMEONE_CONNECTED_TO_LINE = 'SOMEONE_CONNECTED_TO_LINE',
|
||||||
SOMEONE_DISCONNECTED_FROM_LINE = "SOMEONE_DISCONNECTED_FROM_LINE",
|
SOMEONE_DISCONNECTED_FROM_LINE = 'SOMEONE_DISCONNECTED_FROM_LINE',
|
||||||
|
|
||||||
SOMEONE_TUNED_INTO_LINE = "SOMEONE_TUNED_INTO_LINE", // allows all current tuned in folks to create peer objects
|
SOMEONE_TUNED_INTO_LINE = 'SOMEONE_TUNED_INTO_LINE', // allows all current tuned in folks to create peer objects
|
||||||
SOMEONE_UNTUNED_FROM_LINE = "SOMEONE_UNTUNED_FROM_LINE", // discard peer
|
SOMEONE_UNTUNED_FROM_LINE = 'SOMEONE_UNTUNED_FROM_LINE', // discard peer
|
||||||
|
|
||||||
SOMEONE_STARTED_BROADCASTING = "SOMEONE_STARTED_BROADCASTING", //show their stream tracks
|
SOMEONE_STARTED_BROADCASTING = 'SOMEONE_STARTED_BROADCASTING', //show their stream tracks
|
||||||
SOMEONE_STOPPED_BROADCASTING = "SOMEONE_STOPPED_BROADCASTING", // stop showing their stream tracks
|
SOMEONE_STOPPED_BROADCASTING = 'SOMEONE_STOPPED_BROADCASTING', // stop showing their stream tracks
|
||||||
|
|
||||||
// sending to the correct room of tunedin folks AND also making sure it's the right event handler in the right handler for this component
|
// sending to the correct room of tunedin folks AND also making sure it's the right event handler in the right handler for this component
|
||||||
RTC_NEW_USER_JOINED_RESPONSE_PREFIX = "RTC_NEW_USER_JOINED_RESPONSE_PREFIX",
|
RTC_NEW_USER_JOINED_RESPONSE_PREFIX = 'RTC_NEW_USER_JOINED_RESPONSE_PREFIX',
|
||||||
RTC_RECEIVING_ANSWER_RESPONSE_PREFIX = "RTC_RECEIVING_ANSWER_RESPONSE_PREFIX",
|
RTC_RECEIVING_ANSWER_RESPONSE_PREFIX = 'RTC_RECEIVING_ANSWER_RESPONSE_PREFIX',
|
||||||
|
|
||||||
SOMEONE_GOING_INTO_FLOW_STATE = "SOMEONE_GOING_INTO_FLOW_STATE",
|
SOMEONE_GOING_INTO_FLOW_STATE = 'SOMEONE_GOING_INTO_FLOW_STATE',
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SocketChannels;
|
export default SocketChannels;
|
||||||
@@ -71,33 +71,23 @@ export class ConnectToLineRequest {
|
|||||||
constructor(public lineId: string) {}
|
constructor(public lineId: string) {}
|
||||||
}
|
}
|
||||||
export class SomeoneConnectedResponse {
|
export class SomeoneConnectedResponse {
|
||||||
constructor(
|
constructor(public lineId: string, public userId: string) {}
|
||||||
public lineId: string,
|
|
||||||
public userId: string,
|
|
||||||
public allConnectedIntoUserIds: string[]
|
|
||||||
) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class SomeoneDisconnectedResponse {
|
||||||
|
constructor(public lineId: string, public userId: string) {}
|
||||||
|
}
|
||||||
export class TuneToLineRequest {
|
export class TuneToLineRequest {
|
||||||
constructor(public lineId: string, public keepTunedIn: boolean = false) {}
|
constructor(public lineId: string, public keepTunedIn: boolean = false) {}
|
||||||
}
|
}
|
||||||
export class SomeoneTunedResponse {
|
export class SomeoneTunedResponse {
|
||||||
constructor(
|
constructor(public lineId: string, public userId: string) {}
|
||||||
public lineId: string,
|
|
||||||
public userId: string,
|
|
||||||
public allTunedIntoUserIds: string[],
|
|
||||||
public toggledIn: boolean = false // tell client if this new user toggled in or just temporary so that they can update the right LineMember assoc
|
|
||||||
) {}
|
|
||||||
}
|
}
|
||||||
export class UntuneFromLineRequest {
|
export class UntuneFromLineRequest {
|
||||||
constructor(public lineId: string) {}
|
constructor(public lineId: string) {}
|
||||||
}
|
}
|
||||||
export class SomeoneUntunedFromLineResponse {
|
export class SomeoneUntunedFromLineResponse {
|
||||||
constructor(
|
constructor(public lineId: string, public userId: string) {}
|
||||||
public lineId: string,
|
|
||||||
public userId: string,
|
|
||||||
public allTunedIntoUserIds: string[]
|
|
||||||
) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class StartBroadcastingRequest {
|
export class StartBroadcastingRequest {
|
||||||
@@ -120,11 +110,7 @@ export class SocketEmitter<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class RtcCallRequest {
|
export class RtcCallRequest {
|
||||||
constructor(
|
constructor(public lineId: string, public userIdToCall: string, public simplePeerSignal: any) {}
|
||||||
public lineId: string,
|
|
||||||
public userIdToCall: string,
|
|
||||||
public simplePeerSignal: any
|
|
||||||
) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RtcNewUserResponse {
|
export class RtcNewUserResponse {
|
||||||
@@ -132,11 +118,7 @@ export class RtcNewUserResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class RtcAnswerRequest {
|
export class RtcAnswerRequest {
|
||||||
constructor(
|
constructor(public lineId: string, public userIdToCall: string, public simplePeerSignal: any) {}
|
||||||
public lineId: string,
|
|
||||||
public userIdToCall: string,
|
|
||||||
public simplePeerSignal: any
|
|
||||||
) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RtcReceiveAnswerResponse {
|
export class RtcReceiveAnswerResponse {
|
||||||
|
|||||||
@@ -107,6 +107,7 @@
|
|||||||
"axios": "^0.26.1",
|
"axios": "^0.26.1",
|
||||||
"electron-squirrel-startup": "^1.0.0",
|
"electron-squirrel-startup": "^1.0.0",
|
||||||
"electron-store": "^8.0.1",
|
"electron-store": "^8.0.1",
|
||||||
|
"immer": "^9.0.14",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"mongodb": "^4.4.1",
|
"mongodb": "^4.4.1",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
@@ -119,6 +120,7 @@
|
|||||||
"recoil": "^0.6.1",
|
"recoil": "^0.6.1",
|
||||||
"sass": "^1.51.0",
|
"sass": "^1.51.0",
|
||||||
"simple-peer": "^9.11.1",
|
"simple-peer": "^9.11.1",
|
||||||
"socket.io-client": "^4.4.1"
|
"socket.io-client": "^4.4.1",
|
||||||
|
"use-immer": "^0.7.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,15 @@ import { LineMemberState } from '@nirvana/core/models/line.model';
|
|||||||
import {
|
import {
|
||||||
ServerResponseChannels,
|
ServerResponseChannels,
|
||||||
SomeoneConnectedResponse,
|
SomeoneConnectedResponse,
|
||||||
|
SomeoneDisconnectedResponse,
|
||||||
SomeoneTunedResponse,
|
SomeoneTunedResponse,
|
||||||
SomeoneUntunedFromLineResponse,
|
SomeoneUntunedFromLineResponse,
|
||||||
UserStartedBroadcastingResponse,
|
UserStartedBroadcastingResponse,
|
||||||
UserStoppedBroadcastingResponse,
|
UserStoppedBroadcastingResponse,
|
||||||
} from '@nirvana/core/sockets/channels';
|
} from '@nirvana/core/sockets/channels';
|
||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
|
import { useMap } from 'react-use';
|
||||||
|
import { useImmer } from 'use-immer';
|
||||||
|
|
||||||
type LineIdToMasterLine = {
|
type LineIdToMasterLine = {
|
||||||
[lineId: string]: MasterLineData;
|
[lineId: string]: MasterLineData;
|
||||||
@@ -33,84 +36,125 @@ const RealTimeRoomContext = React.createContext<IRealTimeRoomProvider>({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// handles reads of new data
|
/**
|
||||||
// keeps listening to incoming socket events to make sure that the realtime rooms map is highly available
|
*
|
||||||
|
* handles reads of new data
|
||||||
|
* keeps listening to incoming socket events to make sure that the realtime rooms map is highly available
|
||||||
|
*
|
||||||
|
* on load, we want to grab all of the rooms we are in
|
||||||
|
* put them in a map
|
||||||
|
*
|
||||||
|
* fetch more audio clips, fire off async function to fetch more and add to the room map
|
||||||
|
*
|
||||||
|
* Socket Rooms:
|
||||||
|
* - all people online for a line
|
||||||
|
* - all tuned in folks on a line...have it selected or toggle tuned
|
||||||
|
*
|
||||||
|
* Socket Events:
|
||||||
|
* - someone connected
|
||||||
|
* - someone tuned in
|
||||||
|
* - someone started broadcasting
|
||||||
|
* - someone stopped broadcasting
|
||||||
|
*
|
||||||
|
* - someone disconnected...take them out of the necessary lists
|
||||||
|
* - someone left x room
|
||||||
|
* - someone joined x room
|
||||||
|
*
|
||||||
|
* - someone added me to line
|
||||||
|
*
|
||||||
|
* - someone went into flow state their status
|
||||||
|
*
|
||||||
|
* Socket Emissions:
|
||||||
|
* - join a line
|
||||||
|
* - tune into a line
|
||||||
|
* - send audio clip
|
||||||
|
* - create a line -> send to specific people
|
||||||
|
*
|
||||||
|
* REST endpoints:
|
||||||
|
* - toggle tune or untoggle tune
|
||||||
|
* - fetch content blocks for line history - react query
|
||||||
|
*/
|
||||||
|
|
||||||
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 [roomMap, updateRoomMap] = useImmer<LineIdToMasterLine>({});
|
||||||
|
|
||||||
const [selectedLineId, setSelectedLineId] = useState<string>();
|
const [selectedLineId, setSelectedLineId] = useState<string>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 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(`${res.userId} connected to room ${res.lineId}`);
|
||||||
`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,
|
|
||||||
);
|
|
||||||
|
|
||||||
setRealTimeRoomMap((prevLinesMap) => {
|
updateRoomMap((draft) => {
|
||||||
const newMap = { ...prevLinesMap };
|
if (!draft[res.lineId]) {
|
||||||
|
toast.error('there was a problem updating rooms!!!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (newMap[res.lineId])
|
if (draft[res.lineId].connectedMemberIds) {
|
||||||
newMap[res.lineId].connectedMemberIds = [
|
draft[res.lineId].connectedMemberIds.push(res.userId);
|
||||||
...(newMap[res.lineId]?.connectedMemberIds ?? []),
|
} else {
|
||||||
res.userId,
|
draft[res.lineId].connectedMemberIds = [res.userId];
|
||||||
];
|
}
|
||||||
|
|
||||||
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);
|
console.log(`${res.userId} tuned into line ${res.lineId}`);
|
||||||
|
|
||||||
// TODO: if toggled in, make sure to update the current line member in the lines map so that
|
updateRoomMap((draft) => {
|
||||||
// we can know to untune if user selects another line
|
if (!draft[res.lineId]) {
|
||||||
|
toast.error('there was a problem updating rooms!!!');
|
||||||
// below, we are setting the list of tuned in folks based on fresh list from the server
|
return;
|
||||||
// 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;
|
if (draft[res.lineId].tunedInMemberIds) {
|
||||||
|
draft[res.lineId].tunedInMemberIds.push(res.userId);
|
||||||
|
} else {
|
||||||
|
draft[res.lineId].tunedInMemberIds = [res.userId];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$ws.on(
|
$ws.on(
|
||||||
ServerResponseChannels.SOMEONE_UNTUNED_FROM_LINE,
|
ServerResponseChannels.SOMEONE_UNTUNED_FROM_LINE,
|
||||||
(res: SomeoneUntunedFromLineResponse) => {
|
(res: SomeoneUntunedFromLineResponse) => {
|
||||||
console.log(`here are all of updated users in the tuned in room`, res.allTunedIntoUserIds);
|
console.log(`${res.userId} untuned from ${res.lineId}`);
|
||||||
|
|
||||||
// TODO: if toggled in, make sure to update the current line member in the lines map so that
|
updateRoomMap((draft) => {
|
||||||
// we can know to untune if user selects another line
|
if (!draft[res.lineId]) {
|
||||||
|
toast.error('there was a problem updating rooms!!!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setRealTimeRoomMap((prevLinesMap) => {
|
if (draft[res.lineId].tunedInMemberIds) {
|
||||||
const newMap = { ...prevLinesMap };
|
draft[res.lineId].tunedInMemberIds = draft[res.lineId].tunedInMemberIds.filter(
|
||||||
|
(userId) => userId !== res.userId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// TODO: update the relevant lineMember (based on which userId is given): state and last visit date if current user is joining
|
// remove them from the line connected list and tuned list if they are there
|
||||||
|
$ws.on(
|
||||||
|
ServerResponseChannels.SOMEONE_DISCONNECTED_FROM_LINE,
|
||||||
|
(res: SomeoneDisconnectedResponse) => {
|
||||||
|
updateRoomMap((draft) => {
|
||||||
|
if (!draft[res.lineId]) {
|
||||||
|
toast.error('there was a problem updating rooms!!!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (newMap[res.lineId]) newMap[res.lineId].tunedInMemberIds = res.allTunedIntoUserIds;
|
draft[res.lineId].connectedMemberIds = draft[res.lineId].connectedMemberIds?.filter(
|
||||||
|
(userId) => userId !== res.userId,
|
||||||
return newMap;
|
);
|
||||||
|
draft[res.lineId].tunedInMemberIds = draft[res.lineId].tunedInMemberIds?.filter(
|
||||||
|
(userId) => userId !== res.userId,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -118,18 +162,19 @@ export function RealTimeRoomProvider({ children }: { children: React.ReactChild
|
|||||||
$ws.on(
|
$ws.on(
|
||||||
ServerResponseChannels.SOMEONE_STARTED_BROADCASTING,
|
ServerResponseChannels.SOMEONE_STARTED_BROADCASTING,
|
||||||
(res: UserStartedBroadcastingResponse) => {
|
(res: UserStartedBroadcastingResponse) => {
|
||||||
console.log('someone is starting to broadcast');
|
console.log(`${res.userId} is starting to broadcast in ${res.lineId}`);
|
||||||
|
|
||||||
setRealTimeRoomMap((prevLinesMap) => {
|
updateRoomMap((draft) => {
|
||||||
const newMap = { ...prevLinesMap };
|
if (!draft[res.lineId]) {
|
||||||
|
toast.error('there was a problem updating rooms!!!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (newMap[res.lineId])
|
if (draft[res.lineId].currentBroadcastersUserIds) {
|
||||||
newMap[res.lineId].currentBroadcastersUserIds = [
|
draft[res.lineId].currentBroadcastersUserIds.push(res.userId);
|
||||||
...(newMap[res.lineId].currentBroadcastersUserIds ?? []),
|
} else {
|
||||||
res.userId,
|
draft[res.lineId].currentBroadcastersUserIds = [res.userId];
|
||||||
];
|
}
|
||||||
|
|
||||||
return newMap;
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -137,18 +182,19 @@ export function RealTimeRoomProvider({ children }: { children: React.ReactChild
|
|||||||
$ws.on(
|
$ws.on(
|
||||||
ServerResponseChannels.SOMEONE_STOPPED_BROADCASTING,
|
ServerResponseChannels.SOMEONE_STOPPED_BROADCASTING,
|
||||||
(res: UserStoppedBroadcastingResponse) => {
|
(res: UserStoppedBroadcastingResponse) => {
|
||||||
setRealTimeRoomMap((prevLinesMap) => {
|
console.log(`${res.userId} is STOPPED BROADCASTING in ${res.lineId}`);
|
||||||
const newMap = { ...prevLinesMap };
|
|
||||||
|
|
||||||
if (newMap[res.lineId]?.currentBroadcastersUserIds) {
|
updateRoomMap((draft) => {
|
||||||
newMap[res.lineId].currentBroadcastersUserIds = newMap[
|
if (!draft[res.lineId]) {
|
||||||
res.lineId
|
toast.error('there was a problem updating rooms!!!');
|
||||||
].currentBroadcastersUserIds.filter(
|
return;
|
||||||
(broadcasterUserId) => broadcasterUserId !== res.userId,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return newMap;
|
if (draft[res.lineId].currentBroadcastersUserIds) {
|
||||||
|
draft[res.lineId].currentBroadcastersUserIds = draft[
|
||||||
|
res.lineId
|
||||||
|
].currentBroadcastersUserIds.filter((userId) => userId !== res.userId);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -157,30 +203,19 @@ export function RealTimeRoomProvider({ children }: { children: React.ReactChild
|
|||||||
// ?perhaps only remove specific ones?
|
// ?perhaps only remove specific ones?
|
||||||
$ws.removeAllListeners();
|
$ws.removeAllListeners();
|
||||||
};
|
};
|
||||||
}, [realTimeRoomMap, $ws]);
|
}, [roomMap, $ws, updateRoomMap]);
|
||||||
|
|
||||||
// converts the initial rooms to a map
|
// converts the initial rooms fetch to a map
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (rooms.value?.data?.masterLines?.length > 0) {
|
if (rooms.value?.data?.masterLines?.length > 0) {
|
||||||
setRealTimeRoomMap((prevMappings) => {
|
updateRoomMap((draft) => {
|
||||||
// go through the lines from the persistent store
|
|
||||||
|
|
||||||
// get all of the id's and map assign to the main object
|
|
||||||
|
|
||||||
// ?prolly have no previous at this point...but I'm okay with override since this
|
|
||||||
// ?useeffect is triggered on the refetching of the persistent store so we
|
|
||||||
// ?are prolly looking to do a full app refresh and connection refresh
|
|
||||||
const newMap = { ...prevMappings };
|
|
||||||
|
|
||||||
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;
|
draft[lineId] = masterLine;
|
||||||
});
|
});
|
||||||
|
|
||||||
return newMap;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [rooms.value, setRealTimeRoomMap]);
|
}, [rooms.value, updateRoomMap]);
|
||||||
|
|
||||||
/** show user line details on click of one line */
|
/** show user line details on click of one line */
|
||||||
const handleSelectLine = useCallback(
|
const handleSelectLine = useCallback(
|
||||||
@@ -192,10 +227,10 @@ export function RealTimeRoomProvider({ children }: { children: React.ReactChild
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RealTimeRoomContext.Provider
|
<RealTimeRoomContext.Provider value={{ roomsMap: roomMap, handleSelectLine, selectedLineId }}>
|
||||||
value={{ roomsMap: realTimeRoomMap, handleSelectLine, selectedLineId }}
|
|
||||||
>
|
|
||||||
{children}
|
{children}
|
||||||
|
|
||||||
|
<pre>{JSON.stringify(roomMap)}</pre>
|
||||||
</RealTimeRoomContext.Provider>
|
</RealTimeRoomContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4743,6 +4743,11 @@ image-size@^0.7.4:
|
|||||||
resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.7.5.tgz#269f357cf5797cb44683dfa99790e54c705ead04"
|
resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.7.5.tgz#269f357cf5797cb44683dfa99790e54c705ead04"
|
||||||
integrity sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g==
|
integrity sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g==
|
||||||
|
|
||||||
|
immer@^9.0.14:
|
||||||
|
version "9.0.14"
|
||||||
|
resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.14.tgz#e05b83b63999d26382bb71676c9d827831248a48"
|
||||||
|
integrity sha512-ubBeqQutOSLIFCUBN03jGeOS6a3DoYlSYwYJTa+gSKEZKU5redJIqkIdZ3JVv/4RZpfcXdAWH5zCNLWPRv2WDw==
|
||||||
|
|
||||||
immutable@^4.0.0:
|
immutable@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0.tgz#b86f78de6adef3608395efb269a91462797e2c23"
|
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0.tgz#b86f78de6adef3608395efb269a91462797e2c23"
|
||||||
@@ -8955,6 +8960,11 @@ url-parse-lax@^3.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
prepend-http "^2.0.0"
|
prepend-http "^2.0.0"
|
||||||
|
|
||||||
|
use-immer@^0.7.0:
|
||||||
|
version "0.7.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/use-immer/-/use-immer-0.7.0.tgz#e3bfbb806b5e3ff6e37441be74c306d91c1e0962"
|
||||||
|
integrity sha512-Re4hjrP3a/2ABZjAc0b7AK9s626bnO+H33RO2VUhiDZ2StBz5B663K6WNNlr4QtHWaGUmvLpwt3whFvvWuolQw==
|
||||||
|
|
||||||
username@^5.1.0:
|
username@^5.1.0:
|
||||||
version "5.1.0"
|
version "5.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/username/-/username-5.1.0.tgz#a7f9325adce2d0166448cdd55d4985b1360f2508"
|
resolved "https://registry.yarnpkg.com/username/-/username-5.1.0.tgz#a7f9325adce2d0166448cdd55d4985b1360f2508"
|
||||||
|
|||||||
Reference in New Issue
Block a user