adding more logic for tuning in and untuning
This commit is contained in:
@@ -109,7 +109,6 @@ export default function InitializeWs(io: any) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify all connected users when someone UNTUNES from a room
|
* 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) => {
|
socket.on(ServerRequestChannels.UNTUNE_FROM_LINE, async (req: UntuneFromLineRequest) => {
|
||||||
const roomName = `tunedLine:${req.lineId}`;
|
const roomName = `tunedLine:${req.lineId}`;
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ export class SomeoneDisconnectedResponse {
|
|||||||
constructor(public lineId: string, public userId: string) {}
|
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) {}
|
||||||
}
|
}
|
||||||
export class SomeoneTunedResponse {
|
export class SomeoneTunedResponse {
|
||||||
constructor(public lineId: string, public userId: string) {}
|
constructor(public lineId: string, public userId: string) {}
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ import axios, { AxiosRequestConfig, AxiosResponse, Method } from 'axios';
|
|||||||
import CreateLineRequest from '@nirvana/core/requests/createLine.request';
|
import CreateLineRequest from '@nirvana/core/requests/createLine.request';
|
||||||
import GetUserLinesResponse from '@nirvana/core/responses/getUserLines.response';
|
import GetUserLinesResponse from '@nirvana/core/responses/getUserLines.response';
|
||||||
import { Line } from '@nirvana/core/models/line.model';
|
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 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 { User } from '@nirvana/core/models';
|
||||||
import UserDetailsResponse from '../../../core/responses/userDetails.response';
|
import UserDetailsResponse from '@nirvana/core/responses/userDetails.response';
|
||||||
import UserSearchResponse from '../../../core/responses/userSearch.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;
|
// export const localHost = process.env.REACT_APP_API_DOMAIN;
|
||||||
|
|
||||||
@@ -82,6 +83,18 @@ export async function getUserLines(): Promise<NirvanaResponse<GetUserLinesRespon
|
|||||||
return await NirvanaApi.fetch<NirvanaResponse<GetUserLinesResponse>>(`/lines`, 'GET', true);
|
return await NirvanaApi.fetch<NirvanaResponse<GetUserLinesResponse>>(`/lines`, 'GET', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function updateLineMemberState(
|
||||||
|
request: UpdateLineMemberState,
|
||||||
|
lineId: string,
|
||||||
|
): Promise<NirvanaResponse<GetUserLinesResponse>> {
|
||||||
|
return await NirvanaApi.fetch<NirvanaResponse<GetUserLinesResponse>>(
|
||||||
|
`/lines/${lineId}/state`,
|
||||||
|
'POST',
|
||||||
|
true,
|
||||||
|
request,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export async function getDmByUserId(otherUserId: string): Promise<Line> {
|
export async function getDmByUserId(otherUserId: string): Promise<Line> {
|
||||||
return await NirvanaApi.fetch(`/lines/dm/${otherUserId}`, 'GET', true);
|
return await NirvanaApi.fetch(`/lines/dm/${otherUserId}`, 'GET', true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,16 +5,26 @@ import useSockets from './SocketProvider';
|
|||||||
import MasterLineData from '@nirvana/core/models/masterLineData.model';
|
import MasterLineData from '@nirvana/core/models/masterLineData.model';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
ServerRequestChannels,
|
||||||
ServerResponseChannels,
|
ServerResponseChannels,
|
||||||
SomeoneConnectedResponse,
|
SomeoneConnectedResponse,
|
||||||
SomeoneDisconnectedResponse,
|
SomeoneDisconnectedResponse,
|
||||||
SomeoneTunedResponse,
|
SomeoneTunedResponse,
|
||||||
SomeoneUntunedFromLineResponse,
|
SomeoneUntunedFromLineResponse,
|
||||||
|
TuneToLineRequest,
|
||||||
UserStartedBroadcastingResponse,
|
UserStartedBroadcastingResponse,
|
||||||
UserStoppedBroadcastingResponse,
|
UserStoppedBroadcastingResponse,
|
||||||
|
ConnectToLineRequest,
|
||||||
|
UntuneFromLineRequest,
|
||||||
} from '@nirvana/core/sockets/channels';
|
} from '@nirvana/core/sockets/channels';
|
||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
import { useImmer } from 'use-immer';
|
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 = {
|
type LineIdToMasterLine = {
|
||||||
[lineId: string]: MasterLineData;
|
[lineId: string]: MasterLineData;
|
||||||
@@ -24,14 +34,13 @@ interface IRealTimeRoomProvider {
|
|||||||
roomsMap: LineIdToMasterLine;
|
roomsMap: LineIdToMasterLine;
|
||||||
|
|
||||||
selectedLineId?: string;
|
selectedLineId?: string;
|
||||||
handleSelectLine: (newLineId: string) => void;
|
handleSelectLine?: (newLineId: string) => void;
|
||||||
|
|
||||||
|
handleUpdateLineMemberState?: (lineId: string, newState: LineMemberState) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const RealTimeRoomContext = React.createContext<IRealTimeRoomProvider>({
|
const RealTimeRoomContext = React.createContext<IRealTimeRoomProvider>({
|
||||||
roomsMap: {},
|
roomsMap: {},
|
||||||
handleSelectLine: () => {
|
|
||||||
//
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,11 +84,14 @@ const RealTimeRoomContext = React.createContext<IRealTimeRoomProvider>({
|
|||||||
|
|
||||||
export function RealTimeRoomProvider({ children }: { children: React.ReactChild }) {
|
export function RealTimeRoomProvider({ children }: { children: React.ReactChild }) {
|
||||||
const { rooms } = useRooms();
|
const { rooms } = useRooms();
|
||||||
|
const { user } = useAuth();
|
||||||
const { $ws } = useSockets();
|
const { $ws } = useSockets();
|
||||||
const [roomMap, updateRoomMap] = useImmer<LineIdToMasterLine>({});
|
const [roomMap, updateRoomMap] = useImmer<LineIdToMasterLine>({});
|
||||||
|
|
||||||
const [selectedLineId, setSelectedLineId] = useState<string>();
|
const [selectedLineId, setSelectedLineId] = useState<string>();
|
||||||
|
|
||||||
|
const [moveLineState, moveLine] = useAsyncFn(updateLineMemberState);
|
||||||
|
|
||||||
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) => {
|
||||||
@@ -199,9 +211,31 @@ export function RealTimeRoomProvider({ children }: { children: React.ReactChild
|
|||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
// ?perhaps only remove specific ones?
|
// ?perhaps only remove specific ones?
|
||||||
|
// !this will remove all listeners across the app and we want it to?
|
||||||
$ws.removeAllListeners();
|
$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
|
// converts the initial rooms fetch to a map
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -210,24 +244,64 @@ 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();
|
||||||
draft[lineId] = masterLine;
|
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(
|
const handleSelectLine = useCallback(
|
||||||
(newLineIdToSelect: string) => {
|
(newLineIdToSelect: string) => {
|
||||||
toast('selecting line!! NOT IMPLEMENTED');
|
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);
|
console.warn(roomMap);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RealTimeRoomContext.Provider value={{ roomsMap: roomMap, handleSelectLine, selectedLineId }}>
|
<RealTimeRoomContext.Provider
|
||||||
|
value={{ roomsMap: roomMap, handleSelectLine, selectedLineId, handleUpdateLineMemberState }}
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
</RealTimeRoomContext.Provider>
|
</RealTimeRoomContext.Provider>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { LineMemberState } from '@nirvana/core/models/line.model';
|
import { LineMemberState } from '@nirvana/core/models/line.model';
|
||||||
import MasterLineData from '@nirvana/core/models/masterLineData.model';
|
import MasterLineData from '@nirvana/core/models/masterLineData.model';
|
||||||
import { Avatar, Skeleton, Tooltip } from 'antd';
|
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 { FaPlus } from 'react-icons/fa';
|
||||||
import { FiActivity, FiSun } from 'react-icons/fi';
|
import { FiActivity, FiSun } from 'react-icons/fi';
|
||||||
import useRealTimeRooms from '../../../../providers/RealTimeRoomProvider';
|
import useRealTimeRooms from '../../../../providers/RealTimeRoomProvider';
|
||||||
|
|||||||
Reference in New Issue
Block a user