+ {sourceImages.map((avatarSrc, index) => {
+ if (index === 0) {
+ return (
+
+ );
+ } else if (index === 1) {
+ return (
+
+ );
+ }
+
+ // TODO: add third in the frame if we want later
+ return <>>;
+ })}
+
+ ) : (
+ sourceImages?.map((avatarSrc, index) => (
+
+ ))
+ )}
+ >
+ );
+}
+
+export default React.memo(LineIcon);
diff --git a/packages/desktop/src/providers/RealTimeRoomProvider.tsx b/packages/desktop/src/providers/RealTimeRoomProvider.tsx
index 6c28590..95f7319 100644
--- a/packages/desktop/src/providers/RealTimeRoomProvider.tsx
+++ b/packages/desktop/src/providers/RealTimeRoomProvider.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useState, useContext } from 'react';
+import React, { useEffect, useState, useContext, useCallback } from 'react';
import useRooms from './RoomsProvider';
import useSockets from './SocketProvider';
@@ -19,6 +19,7 @@ import {
UserStartedBroadcastingResponse,
UserStoppedBroadcastingResponse,
} from '@nirvana/core/sockets/channels';
+import toast from 'react-hot-toast';
type LineIdToMasterLine = {
[lineId: string]: MasterLineData;
@@ -26,17 +27,27 @@ type LineIdToMasterLine = {
interface IRealTimeRoomProvider {
roomsMap: LineIdToMasterLine;
+
+ selectedLine?: MasterLineData;
+ handleSelectLine: (newLineId: string) => void;
}
-const RealTimeRoomContext = React.createContext({ roomsMap: {} });
+const RealTimeRoomContext = React.createContext({
+ roomsMap: {},
+ handleSelectLine: () => {
+ //
+ },
+});
// handles reads of new data
-// does NOT handle sending socket emissions
+// keeps listening to incoming socket events to make sure that the realtime rooms map is highly available
export function RealTimeRoomProvider({ children }: { children: React.ReactChild }) {
const { rooms } = useRooms();
const { $ws } = useSockets();
const [realTimeRoomMap, setRealTimeRoomMap] = useState({});
+ const [selectedLine, setSelectedLine] = useState();
+
useEffect(() => {
/**
* initiate listeners
@@ -188,8 +199,19 @@ export function RealTimeRoomProvider({ children }: { children: React.ReactChild
}
}, [rooms.value, setRealTimeRoomMap]);
+ /** show user line details on click of one line */
+ const handleSelectLine = useCallback(
+ (newLineIdToSelect: string) => {
+ toast('selecting line!! NOT IMPLEMENTED');
+ setSelectedLine(realTimeRoomMap[newLineIdToSelect]);
+ },
+ [setSelectedLine, realTimeRoomMap],
+ );
+
return (
-
+
{children}
);
diff --git a/packages/desktop/src/tree/protected/terminal/Terminal.tsx b/packages/desktop/src/tree/protected/terminal/Terminal.tsx
index d412979..1305825 100644
--- a/packages/desktop/src/tree/protected/terminal/Terminal.tsx
+++ b/packages/desktop/src/tree/protected/terminal/Terminal.tsx
@@ -7,32 +7,19 @@ import MasterLineData from '@nirvana/core/models/masterLineData.model';
import useRooms from '../../../providers/RoomsProvider';
import toast from 'react-hot-toast';
+import SidePanel from './panels/SidePanel';
export default function Terminal() {
- const { rooms: initialRoomsState } = useRooms();
const { roomsMap } = useRealTimeRooms();
const { desktopMode } = useElectron();
- const { user } = useAuth();
-
- const [selectedLine, setSelectedLine] = useState();
-
- /** show user line details on click of one line */
- const handleSelectLine = useCallback(
- (newLineIdToSelect: string) => {
- toast('selecting line!! NOT IMPLEMENTED');
- setSelectedLine(roomsMap[newLineIdToSelect]);
- },
- [setSelectedLine],
- );
-
return (
+
+
+
+ {/* */}
);
}
-
-// have a socket view component to just connect on mount and disconnect from specific | tunes in and untunes similarly
-// have a socket view component to just tune into tuned in lines
-// have a stream view component to just make peer connections and have stream components available
diff --git a/packages/desktop/src/tree/protected/terminal/panels/SidePanel.tsx b/packages/desktop/src/tree/protected/terminal/panels/SidePanel.tsx
new file mode 100644
index 0000000..1e679f7
--- /dev/null
+++ b/packages/desktop/src/tree/protected/terminal/panels/SidePanel.tsx
@@ -0,0 +1,224 @@
+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 { FaPlus } from 'react-icons/fa';
+import { FiActivity, FiSun } from 'react-icons/fi';
+import useRealTimeRooms from '../../../../providers/RealTimeRoomProvider';
+import useRooms from '../../../../providers/RoomsProvider';
+import useAuth from '../../../../providers/AuthProvider';
+import LineIcon from '../../../../components/lineIcon';
+import moment from 'moment';
+
+export default function SidePanel() {
+ // using merely for loading state...better to add to realtimeroom context?
+ const { rooms: initialRoomsFetch } = useRooms();
+
+ const { roomsMap, handleSelectLine, selectedLine } = useRealTimeRooms();
+
+ const [toggleTunedLines, allLines] = useMemo(() => {
+ const masterLines: MasterLineData[] = Object.values(roomsMap);
+
+ const tunedLines: MasterLineData[] = [];
+ const restLines: MasterLineData[] = [];
+
+ masterLines.forEach((masterLine) => {
+ if (masterLine.currentUserMember.state === LineMemberState.TUNED) restLines.push(masterLine);
+ else restLines.push(masterLine);
+ });
+
+ return [tunedLines, restLines];
+ }, [roomsMap]);
+
+ return (
+
+ {/* tuned in lines block */}
+
+ {/* tuned in header + general controls */}
+
+
+
+
+ {!(allLines.length > 0) && !(toggleTunedLines.length > 0) && (
+
+ You have no lines! Create one to connect to your team instantly.
+
+ )}
+
+ {/* rest of the lines */}
+