sexy flow with data
This commit is contained in:
@@ -5,6 +5,7 @@ import { $selectedLineId } from "../../../controller/recoil";
|
||||
import { Avatar } from "antd";
|
||||
import { FiSun } from "react-icons/fi";
|
||||
import LineIcon from "../lineIcon";
|
||||
import { LineMemberState } from "@nirvana/core/models/line.model";
|
||||
import MasterLineData from "@nirvana/core/models/masterLineData.model";
|
||||
import { useGetUserDetails } from "../../../controller/index";
|
||||
|
||||
|
||||
@@ -1,39 +1,50 @@
|
||||
import React, { useContext } from "react";
|
||||
import { Socket, io } from "socket.io-client";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
import { $jwtToken } from "./recoil";
|
||||
import MasterLineData from "@nirvana/core/models/masterLineData.model";
|
||||
import SocketChannels from "@nirvana/core/sockets/channels";
|
||||
import { User } from "@nirvana/core/models";
|
||||
import { io } from "socket.io-client";
|
||||
import { queryClient } from "../pages/nirvanaApp";
|
||||
import toast from "react-hot-toast";
|
||||
import { useEffect } from "react";
|
||||
import { useRecoilValue } from "recoil";
|
||||
import { useUserLines } from "./index";
|
||||
|
||||
type LineIdToMasterLine = {
|
||||
[lineId: string]: MasterLineData;
|
||||
};
|
||||
interface ILineDataContext {
|
||||
// represents the modified and up to date lines data with availability from session
|
||||
lines: MasterLineData[];
|
||||
linesMap: LineIdToMasterLine;
|
||||
relevantUsers: User[];
|
||||
}
|
||||
|
||||
const LineDataContext = React.createContext<ILineDataContext>({
|
||||
lines: [],
|
||||
linesMap: {},
|
||||
relevantUsers: [],
|
||||
});
|
||||
|
||||
let $ws;
|
||||
let $ws: Socket;
|
||||
|
||||
export function LineDataProvider({ children }) {
|
||||
// TODO: have internal loading to prevent showing even router and all if something is not ready
|
||||
// or have it within each property within the context value
|
||||
|
||||
// persistent store of lines
|
||||
// ?just do simple synchronous axios/fetch in useEffect and manage isLoading ourselves?
|
||||
const { data: basicUserLinesData } = useUserLines();
|
||||
const jwtToken = useRecoilValue($jwtToken);
|
||||
|
||||
const [linesMap, setLinesMap] = useState<LineIdToMasterLine>({});
|
||||
|
||||
useEffect(() => {
|
||||
$ws = io("http://localhost:5000", {
|
||||
query: { token: jwtToken },
|
||||
});
|
||||
|
||||
$ws.on("connection", () => toast.success("you are connected"));
|
||||
|
||||
// client-side errors
|
||||
$ws.on("connect_error", (err) => {
|
||||
console.error(err.message); // prints the message associated with the error
|
||||
@@ -55,12 +66,46 @@ export function LineDataProvider({ children }) {
|
||||
// $ws.on(SocketChannels.CONNECT, console.log());
|
||||
|
||||
$ws.on("test", () => console.log("test"));
|
||||
|
||||
if (basicUserLinesData?.data?.masterLines.length > 0) {
|
||||
setLinesMap((prevMappings) => {
|
||||
// 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 };
|
||||
|
||||
basicUserLinesData.data.masterLines.map((masterLine) => {
|
||||
newMap[masterLine.lineDetails._id.toString()] = masterLine;
|
||||
});
|
||||
|
||||
return newMap;
|
||||
});
|
||||
}
|
||||
}, [basicUserLinesData]);
|
||||
|
||||
// get updated associations with certain lines
|
||||
/**
|
||||
* get more audio blocks for a certain line
|
||||
*/
|
||||
const handleFetchMoreAudioBlocks = useCallback(
|
||||
(lineId: string) => {
|
||||
// simple axios fetch for this specific block
|
||||
// update the specific line in lines map
|
||||
// set the state to trigger the re-renders in the tree
|
||||
},
|
||||
[setLinesMap]
|
||||
);
|
||||
|
||||
const value: ILineDataContext = {
|
||||
linesMap, // TODO send the updated map instead of this array
|
||||
relevantUsers: [],
|
||||
};
|
||||
|
||||
return (
|
||||
<LineDataContext.Provider value={{} as ILineDataContext}>
|
||||
<LineDataContext.Provider value={value}>
|
||||
{children}
|
||||
</LineDataContext.Provider>
|
||||
);
|
||||
|
||||
@@ -47,8 +47,6 @@ const createWindow = (): void => {
|
||||
|
||||
// backgroundColor: "#00000000",
|
||||
|
||||
alwaysOnTop: true, // testing purposes
|
||||
|
||||
frame: false,
|
||||
roundedCorners: false,
|
||||
});
|
||||
|
||||
@@ -5,11 +5,33 @@ import { useCallback, useMemo } from "react";
|
||||
import { $selectedLineId } from "../../controller/recoil";
|
||||
import { ILineDetails } from "../router";
|
||||
import LineIcon from "../../components/lines/lineIcon/index";
|
||||
import { LineMemberState } from "@nirvana/core/models/line.model";
|
||||
import MasterLineData from "@nirvana/core/models/masterLineData.model";
|
||||
import { Tooltip } from "antd";
|
||||
import { useLineDataProvider } from "../../controller/lineDataProvider";
|
||||
import { useRecoilState } from "recoil";
|
||||
|
||||
export default function LineDetailsTerminal() {
|
||||
const [selectedLineId, setSelectedLineId] = useRecoilState($selectedLineId);
|
||||
|
||||
const { linesMap } = useLineDataProvider();
|
||||
|
||||
const selectedLine: MasterLineData | undefined = useMemo(() => {
|
||||
if (!selectedLineId) return undefined;
|
||||
|
||||
// find the line from the data provider
|
||||
if (linesMap[selectedLineId]) {
|
||||
return linesMap[selectedLineId];
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}, [selectedLineId, linesMap]);
|
||||
|
||||
const isUserToggleTuned = useMemo(
|
||||
() => selectedLine.currentUserMember.state === LineMemberState.TUNED,
|
||||
[selectedLine]
|
||||
);
|
||||
|
||||
const handleEscape = useCallback(() => {
|
||||
console.log("deselecting line");
|
||||
|
||||
@@ -59,16 +81,33 @@ export default function LineDetailsTerminal() {
|
||||
className="absolute bottom-0 p-4 shadow-2xl
|
||||
flex flex-row items-center gap-2 justify-end w-full"
|
||||
>
|
||||
<button className="p-3 flex justify-center items-center hover:bg-gray-300 transition-all">
|
||||
<button
|
||||
className={`p-3 flex justify-center items-center hover:bg-gray-300
|
||||
transition-all hover:scale-105`}
|
||||
>
|
||||
<FiSettings className="text-gray-400 text-md" />
|
||||
</button>
|
||||
|
||||
<button className="bg-gray-800 p-3 flex justify-center items-center shadow-lg">
|
||||
<FiActivity className="text-white text-lg" />
|
||||
</button>
|
||||
<Tooltip
|
||||
title={`${
|
||||
isUserToggleTuned ? "toggle tuned" : "temporarily tuned"
|
||||
}`}
|
||||
>
|
||||
<button
|
||||
className={`p-3 flex justify-center items-center shadow-lg
|
||||
hover:scale-105 transition-all animate-pulse ${
|
||||
isUserToggleTuned ? "bg-gray-800 text-white" : "text-black"
|
||||
}`}
|
||||
>
|
||||
<FiActivity className="text-lg" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
|
||||
{/* TODO: change to border and inset color for when inactive button */}
|
||||
<button className="bg-teal-800 p-3 flex justify-center items-center shadow-lg">
|
||||
<button
|
||||
className={`bg-teal-800 p-3 flex justify-center items-center shadow-lg
|
||||
hover:scale-105 transition-all `}
|
||||
>
|
||||
<FiSun className="text-white text-lg" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -12,12 +12,16 @@ import Channels, {
|
||||
TERMINAL_PRESET,
|
||||
} from "../../electron/constants";
|
||||
import { GlobalHotKeys, KeyMap } from "react-hotkeys";
|
||||
import {
|
||||
LineDataProvider,
|
||||
useLineDataProvider,
|
||||
} from "../../controller/lineDataProvider";
|
||||
import React, { useState } from "react";
|
||||
import { useCallback, useEffect, useMemo } from "react";
|
||||
import { useRecoilState, useRecoilValue } from "recoil";
|
||||
|
||||
import { LineDataProvider } from "../../controller/lineDataProvider";
|
||||
import LineDetailsTerminal from "../lineDetailsTerminal";
|
||||
import MasterLineData from "@nirvana/core/models/masterLineData.model";
|
||||
import NirvanaHeader from "../../components/header/index";
|
||||
import NirvanaTerminal from "../terminal";
|
||||
import Overlay from "../overlay";
|
||||
@@ -269,7 +273,7 @@ export default function NirvanaRouter() {
|
||||
|
||||
// send the final dimensions to main process
|
||||
window.electronAPI.window.resizeWindow({
|
||||
setAlwaysOnTop,
|
||||
setAlwaysOnTop: true, // TODO: remove, just this for testing
|
||||
dimensions: {
|
||||
height: finalDimensions.height,
|
||||
width: finalDimensions.width,
|
||||
@@ -318,11 +322,11 @@ export default function NirvanaRouter() {
|
||||
|
||||
<div className="flex flex-row flex-1">
|
||||
{(desktopMode === "terminal" ||
|
||||
desktopMode === "terminalDetails") && (
|
||||
<NirvanaTerminal allLines={testLines} />
|
||||
)}
|
||||
desktopMode === "terminalDetails") && <NirvanaTerminal />}
|
||||
|
||||
{desktopMode === "terminalDetails" && <LineDetailsTerminal />}
|
||||
{desktopMode === "terminalDetails" && selectedLineId && (
|
||||
<LineDetailsTerminal />
|
||||
)}
|
||||
|
||||
{desktopMode === "overlayOnly" && <Overlay />}
|
||||
</div>
|
||||
|
||||
@@ -6,35 +6,45 @@ import { FaPlus } from "react-icons/fa";
|
||||
import { FiActivity } from "react-icons/fi";
|
||||
import { ILineDetails } from "../router";
|
||||
import IconButton from "../../components/Button/IconButton/index";
|
||||
import { LineMemberState } from "@nirvana/core/models/line.model";
|
||||
import LineRow from "../../components/lines/lineRow.tsx/index";
|
||||
import MasterLineData from "@nirvana/core/models/masterLineData.model";
|
||||
import NewLineModal from "./newLine";
|
||||
import { useLineDataProvider } from "../../controller/lineDataProvider";
|
||||
import { useSetRecoilState } from "recoil";
|
||||
import { useUserLines } from "../../controller/index";
|
||||
|
||||
export default function NirvanaTerminal({
|
||||
allLines,
|
||||
}: {
|
||||
allLines: ILineDetails[];
|
||||
}) {
|
||||
export default function NirvanaTerminal() {
|
||||
const [isModalVisible, setIsModalVisible] = useState<boolean>(false);
|
||||
|
||||
const setSelectedLineId = useSetRecoilState($selectedLineId);
|
||||
const setDesktopMode = useSetRecoilState($desktopMode);
|
||||
|
||||
const { data: userLinesRes, isLoading } = useUserLines();
|
||||
// simply using this query for specific data on loading
|
||||
// todo: add these properties in context provider value although more work down the line for control
|
||||
const { isLoading: isLoadingInitialLines } = useUserLines();
|
||||
const { linesMap } = useLineDataProvider();
|
||||
|
||||
const allLines: MasterLineData[] = useMemo(() => {
|
||||
const masterLines: MasterLineData[] = Object.values(linesMap);
|
||||
|
||||
return masterLines.filter(
|
||||
(masterLine) =>
|
||||
masterLine.currentUserMember.state === LineMemberState.INBOX
|
||||
);
|
||||
}, [linesMap]);
|
||||
|
||||
const toggleTunedLines = useMemo(() => {
|
||||
const masterLines: MasterLineData[] = Object.values(linesMap);
|
||||
|
||||
return masterLines.filter(
|
||||
(masterLine) =>
|
||||
masterLine.currentUserMember.state === LineMemberState.TUNED
|
||||
);
|
||||
}, [linesMap]);
|
||||
|
||||
// todo: sort/order based on activity and activity date and currently broadcasting/live
|
||||
|
||||
const toggleTunedLines = useMemo(
|
||||
() => allLines.filter((line) => line.isUserToggleTunedIn),
|
||||
[]
|
||||
);
|
||||
|
||||
const restLines = useMemo(
|
||||
() => allLines.filter((line) => !line.isUserToggleTunedIn),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col bg-white w-[400px]">
|
||||
{/* modal for creating new line */}
|
||||
@@ -68,22 +78,29 @@ export default function NirvanaTerminal({
|
||||
</div>
|
||||
|
||||
{/* list of toggle tuned lines */}
|
||||
<div className="flex flex-col mt-2"></div>
|
||||
<div className="flex flex-col mt-2">
|
||||
{toggleTunedLines.map((masterLineData) => (
|
||||
<LineRow
|
||||
key={`terminalListLines-${masterLineData.lineDetails._id.toString()}`}
|
||||
masterLineData={masterLineData}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* rest of the lines */}
|
||||
<div className={"flex flex-col"}>
|
||||
{isLoading ? (
|
||||
{isLoadingInitialLines ? (
|
||||
<Skeleton />
|
||||
) : (
|
||||
<>
|
||||
{!userLinesRes?.data?.masterLines?.length && (
|
||||
{!allLines.length && (
|
||||
<span className="text-gray-300 text-sm my-5 text-center">
|
||||
You have no lines! <br /> Create one to connect to your team
|
||||
instantly.
|
||||
</span>
|
||||
)}
|
||||
{userLinesRes?.data?.masterLines?.map((masterLineData) => (
|
||||
{allLines.map((masterLineData) => (
|
||||
<LineRow
|
||||
key={`terminalListLines-${masterLineData.lineDetails._id.toString()}`}
|
||||
masterLineData={masterLineData}
|
||||
|
||||
Reference in New Issue
Block a user