From bc202ba9db01c262e67c5948598830ab7f7efea6 Mon Sep 17 00:00:00 2001 From: talksik Date: Sat, 14 May 2022 09:10:18 -0500 Subject: [PATCH] adding more logic for tuning in and untuning --- packages/api/sockets/index.ts | 1 - packages/core/sockets/channels.ts | 2 +- packages/desktop/src/api/NirvanaApi.tsx | 21 ++++- .../src/providers/RealTimeRoomProvider.tsx | 94 +++++++++++++++++-- .../protected/terminal/panels/SidePanel.tsx | 2 +- 5 files changed, 103 insertions(+), 17 deletions(-) diff --git a/packages/api/sockets/index.ts b/packages/api/sockets/index.ts index 5b4283a..8739490 100644 --- a/packages/api/sockets/index.ts +++ b/packages/api/sockets/index.ts @@ -109,7 +109,6 @@ export default function InitializeWs(io: any) { /** * Notify all connected users when someone UNTUNES from a room - * ?might not be needed, all users' memory of tuned in users is irrelevant? don't need real time? but UI will show # of users tuned in? */ socket.on(ServerRequestChannels.UNTUNE_FROM_LINE, async (req: UntuneFromLineRequest) => { const roomName = `tunedLine:${req.lineId}`; diff --git a/packages/core/sockets/channels.ts b/packages/core/sockets/channels.ts index 7699823..1c8fbac 100644 --- a/packages/core/sockets/channels.ts +++ b/packages/core/sockets/channels.ts @@ -78,7 +78,7 @@ export class SomeoneDisconnectedResponse { constructor(public lineId: string, public userId: string) {} } export class TuneToLineRequest { - constructor(public lineId: string, public keepTunedIn: boolean = false) {} + constructor(public lineId: string) {} } export class SomeoneTunedResponse { constructor(public lineId: string, public userId: string) {} diff --git a/packages/desktop/src/api/NirvanaApi.tsx b/packages/desktop/src/api/NirvanaApi.tsx index 61beebd..8f90a43 100644 --- a/packages/desktop/src/api/NirvanaApi.tsx +++ b/packages/desktop/src/api/NirvanaApi.tsx @@ -3,12 +3,13 @@ import axios, { AxiosRequestConfig, AxiosResponse, Method } from 'axios'; import CreateLineRequest from '@nirvana/core/requests/createLine.request'; import GetUserLinesResponse from '@nirvana/core/responses/getUserLines.response'; import { Line } from '@nirvana/core/models/line.model'; -import LoginResponse from '../../../core/responses/login.response'; +import LoginResponse from '@nirvana/core/responses/login.response'; import MasterLineData from '@nirvana/core/models/masterLineData.model'; -import NirvanaResponse from '../../../core/responses/nirvanaResponse'; +import NirvanaResponse from '@nirvana/core/responses/nirvanaResponse'; import { User } from '@nirvana/core/models'; -import UserDetailsResponse from '../../../core/responses/userDetails.response'; -import UserSearchResponse from '../../../core/responses/userSearch.response'; +import UserDetailsResponse from '@nirvana/core/responses/userDetails.response'; +import UserSearchResponse from '@nirvana/core/responses/userSearch.response'; +import UpdateLineMemberState from '@nirvana/core/requests/updateLineMemberState.request'; // export const localHost = process.env.REACT_APP_API_DOMAIN; @@ -82,6 +83,18 @@ export async function getUserLines(): Promise>(`/lines`, 'GET', true); } +export async function updateLineMemberState( + request: UpdateLineMemberState, + lineId: string, +): Promise> { + return await NirvanaApi.fetch>( + `/lines/${lineId}/state`, + 'POST', + true, + request, + ); +} + export async function getDmByUserId(otherUserId: string): Promise { return await NirvanaApi.fetch(`/lines/dm/${otherUserId}`, 'GET', true); } diff --git a/packages/desktop/src/providers/RealTimeRoomProvider.tsx b/packages/desktop/src/providers/RealTimeRoomProvider.tsx index 09471c3..4f2ec51 100644 --- a/packages/desktop/src/providers/RealTimeRoomProvider.tsx +++ b/packages/desktop/src/providers/RealTimeRoomProvider.tsx @@ -5,16 +5,26 @@ import useSockets from './SocketProvider'; import MasterLineData from '@nirvana/core/models/masterLineData.model'; import { + ServerRequestChannels, ServerResponseChannels, SomeoneConnectedResponse, SomeoneDisconnectedResponse, SomeoneTunedResponse, SomeoneUntunedFromLineResponse, + TuneToLineRequest, UserStartedBroadcastingResponse, UserStoppedBroadcastingResponse, + ConnectToLineRequest, + UntuneFromLineRequest, } from '@nirvana/core/sockets/channels'; import toast from 'react-hot-toast'; import { useImmer } from 'use-immer'; +import { LineMemberState } from '@nirvana/core/models/line.model'; +import { useAsyncFn } from 'react-use'; + +import { updateLineMemberState } from '../api/NirvanaApi'; +import UpdateLineMemberState from '@nirvana/core/requests/updateLineMemberState.request'; +import useAuth from './AuthProvider'; type LineIdToMasterLine = { [lineId: string]: MasterLineData; @@ -24,14 +34,13 @@ interface IRealTimeRoomProvider { roomsMap: LineIdToMasterLine; selectedLineId?: string; - handleSelectLine: (newLineId: string) => void; + handleSelectLine?: (newLineId: string) => void; + + handleUpdateLineMemberState?: (lineId: string, newState: LineMemberState) => void; } const RealTimeRoomContext = React.createContext({ roomsMap: {}, - handleSelectLine: () => { - // - }, }); /** @@ -75,11 +84,14 @@ const RealTimeRoomContext = React.createContext({ export function RealTimeRoomProvider({ children }: { children: React.ReactChild }) { const { rooms } = useRooms(); + const { user } = useAuth(); const { $ws } = useSockets(); const [roomMap, updateRoomMap] = useImmer({}); const [selectedLineId, setSelectedLineId] = useState(); + const [moveLineState, moveLine] = useAsyncFn(updateLineMemberState); + useEffect(() => { // when me or anyone just initially connects to line $ws.on(ServerResponseChannels.SOMEONE_CONNECTED_TO_LINE, (res: SomeoneConnectedResponse) => { @@ -199,9 +211,31 @@ export function RealTimeRoomProvider({ children }: { children: React.ReactChild return () => { // ?perhaps only remove specific ones? + // !this will remove all listeners across the app and we want it to? $ws.removeAllListeners(); }; - }, [roomMap, $ws, updateRoomMap]); + }, [$ws, updateRoomMap]); + + const handleConnectToLine = useCallback( + (lineId: string) => { + $ws.emit(ServerRequestChannels.CONNECT_TO_LINE, new ConnectToLineRequest(lineId)); + }, + [$ws], + ); + + const handleTuneIntoLine = useCallback( + (lineId: string) => { + $ws.emit(ServerRequestChannels.TUNE_INTO_LINE, new TuneToLineRequest(lineId)); + }, + [$ws], + ); + + const handleUntuneFromLine = useCallback( + (lineId: string) => { + $ws.emit(ServerRequestChannels.UNTUNE_FROM_LINE, new UntuneFromLineRequest(lineId)); + }, + [$ws], + ); // converts the initial rooms fetch to a map useEffect(() => { @@ -210,24 +244,64 @@ export function RealTimeRoomProvider({ children }: { children: React.ReactChild rooms.value.data.masterLines.forEach((masterLine) => { const lineId = masterLine.lineDetails._id.toString(); draft[lineId] = masterLine; + + handleConnectToLine(lineId); + if (masterLine.currentUserMember.state === LineMemberState.TUNED) { + handleTuneIntoLine(lineId); + } }); }); } - }, [rooms.value, updateRoomMap]); + }, [rooms.value, updateRoomMap, handleConnectToLine, handleTuneIntoLine]); - /** show user line details on click of one line */ + // persist whether I want it toggle tuned or not + const handleUpdateLineMemberState = useCallback( + (lineId: string, newState: LineMemberState) => { + moveLine(new UpdateLineMemberState(newState), lineId) + .then((_res) => { + updateRoomMap((draft) => { + draft[lineId].currentUserMember.state = newState; + }); + }) + .catch((error) => { + toast.error('problem in updating line member state'); + console.error(error); + }); + }, + [moveLine, updateRoomMap], + ); + + /** + * selection globally + * tune into socket room and tell everyone else + */ const handleSelectLine = useCallback( (newLineIdToSelect: string) => { toast('selecting line!! NOT IMPLEMENTED'); - setSelectedLineId(newLineIdToSelect); + + setSelectedLineId((prevLineId) => { + // untune from the last line if it was just a temporary tuned one + if (roomMap[prevLineId]?.currentUserMember.state === LineMemberState.INBOX) { + handleUntuneFromLine(prevLineId); + } + + return newLineIdToSelect; + }); + + // tune in if not already tuned into this line + if (!roomMap[newLineIdToSelect].tunedInMemberIds.includes(user._id.toString())) { + handleTuneIntoLine(newLineIdToSelect); + } }, - [setSelectedLineId], + [setSelectedLineId, handleUntuneFromLine, roomMap, user, handleTuneIntoLine], ); console.warn(roomMap); return ( - + {children} ); diff --git a/packages/desktop/src/tree/protected/terminal/panels/SidePanel.tsx b/packages/desktop/src/tree/protected/terminal/panels/SidePanel.tsx index 38cab2e..96c5cda 100644 --- a/packages/desktop/src/tree/protected/terminal/panels/SidePanel.tsx +++ b/packages/desktop/src/tree/protected/terminal/panels/SidePanel.tsx @@ -1,7 +1,7 @@ import { LineMemberState } from '@nirvana/core/models/line.model'; import MasterLineData from '@nirvana/core/models/masterLineData.model'; import { Avatar, Skeleton, Tooltip } from 'antd'; -import React, { useMemo } from 'react'; +import React, { useCallback, useMemo, useEffect } from 'react'; import { FaPlus } from 'react-icons/fa'; import { FiActivity, FiSun } from 'react-icons/fi'; import useRealTimeRooms from '../../../../providers/RealTimeRoomProvider';