diff --git a/packages/desktop/src/components/header/index.tsx b/packages/desktop/src/components/header/index.tsx index 59ac376..5cdc334 100644 --- a/packages/desktop/src/components/header/index.tsx +++ b/packages/desktop/src/components/header/index.tsx @@ -86,9 +86,10 @@ export default function NirvanaHeader({
- +
+ +
diff --git a/packages/desktop/src/controller/recoil.tsx b/packages/desktop/src/controller/recoil.tsx index 333588f..73cec33 100644 --- a/packages/desktop/src/controller/recoil.tsx +++ b/packages/desktop/src/controller/recoil.tsx @@ -29,3 +29,15 @@ export const $selectedOutputMode = atom({ key: "OUTPUT_MODE", default: "video", }); + +// number of active lines +export const $numberActiveLines = atom({ + key: "NUMBER_ACTIVE_LINES", + default: 0, +}); + +// max number of active streams +export const $maxNumberActiveStreams = atom({ + key: "MAX_NUMBER_ACTIVE_STREAMS", + default: 0, +}); diff --git a/packages/desktop/src/electron/constants.ts b/packages/desktop/src/electron/constants.ts index 47d3a5e..e79bbdc 100644 --- a/packages/desktop/src/electron/constants.ts +++ b/packages/desktop/src/electron/constants.ts @@ -13,25 +13,27 @@ export enum STORE_ITEMS { AUTH_SESSION_JWT = "AUTH_SESSION_JWT", } -export type Dimensions = { - height: number; - width: number; +export type Dimensions = { height: number; width: number }; + +export interface DimensionChangeRequest { + setAlwaysOnTop: boolean; + dimensions: Dimensions; + addDimensions: boolean; +} + +export const TERMINAL_PRESET: Dimensions = { + height: 675, + width: 400, }; -export const DimensionPresets = { - terminal: { - height: 675, - width: 400, - }, - terminalAndDetails: { - height: 675, - width: 800, - }, - // todo: typically just send whatever dimensions are needed - overlayOnlyMode: { - height: 800, - width: 325, - }, +export const TERMINAL_DETAILS_PRESET: Dimensions = { + height: 675, + width: 800, +}; + +export const OVERLAY_ONLY_INITIAL_PRESET: Dimensions = { + height: 50, + width: 325, }; export default Channels; diff --git a/packages/desktop/src/electron/global.d.ts b/packages/desktop/src/electron/global.d.ts index 807a803..bdd23e5 100644 --- a/packages/desktop/src/electron/global.d.ts +++ b/packages/desktop/src/electron/global.d.ts @@ -1,3 +1,4 @@ +import { Dimensions, DimensionChangeRequest } from "./constants"; import { electronAPI } from "./preload"; export {}; @@ -12,7 +13,7 @@ declare global { set(property: STORE_ITEMS, val: any): void; }; window: { - resizeWindow(newDimensions: { width: number; height: number }): void; + resizeWindow(dimensionChangeRequest: DimensionChangeRequest): void; }; on(channel: Channels, func: any): void; once(channel: Channels, func: any): void; diff --git a/packages/desktop/src/index.ts b/packages/desktop/src/index.ts index 27d6557..bdcc616 100644 --- a/packages/desktop/src/index.ts +++ b/packages/desktop/src/index.ts @@ -7,9 +7,9 @@ import { ipcMain, screen, } from "electron"; -import Channels, { Dimensions } from "./electron/constants"; +import Channels, { TERMINAL_PRESET } from "./electron/constants"; -import { DimensionPresets } from "./electron/constants"; +import { DimensionChangeRequest } from "./electron/constants"; import { handleGoogleLogin } from "./electron/handleLogin"; import path from "path"; import store from "./electron/store"; @@ -35,7 +35,7 @@ let display; const createWindow = (): void => { // Create the browser window. browserWindow = new BrowserWindow({ - ...DimensionPresets.terminal, + ...{ height: TERMINAL_PRESET.height, width: TERMINAL_PRESET.width }, webPreferences: { preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY, sandbox: true, @@ -87,26 +87,27 @@ app }); // dynamically changing the window bounds - ipcMain.on(Channels.RESIZE_WINDOW, (event, arg) => { - const { width, height } = arg; - - if ( - width === DimensionPresets.overlayOnlyMode.width && - height === DimensionPresets.overlayOnlyMode.height - ) { + ipcMain.on(Channels.RESIZE_WINDOW, (event, req: DimensionChangeRequest) => { + if (req.setAlwaysOnTop) { browserWindow.setAlwaysOnTop(true, "floating"); - - // move window/overlay to top right - - browserWindow.setPosition(display.bounds.width - width, 0, true); - - browserWindow.setSize(width, height, true); } else { - browserWindow.setSize(width, height, true); - - browserWindow.center(); browserWindow.setAlwaysOnTop(false); } + + if (req.addDimensions) { + const currentDimensions = browserWindow.getSize(); + browserWindow.setSize( + currentDimensions[0] + req.dimensions.width, + currentDimensions[1] + req.dimensions.height, + true + ); + } else { + browserWindow.setSize( + req.dimensions.width, + req.dimensions.height, + true + ); + } }); }) .then(() => { @@ -116,16 +117,6 @@ app // on blur, show overlay, and tell app to trigger overlay mode browserWindow.on("blur", () => { - // browserWindow.setAlwaysOnTop(true, "floating"); - - // let frontend handshake and then send remote control to change size - // const overlayDimensions = DimensionPresets.overlayMode; - // browserWindow.setSize( - // overlayDimensions.width, - // overlayDimensions.height, - // true - // ); - browserWindow.webContents.send(Channels.ON_WINDOW_BLUR); }); }); diff --git a/packages/desktop/src/pages/overlay/index.tsx b/packages/desktop/src/pages/overlay/index.tsx index 90d217c..d1ab0ed 100644 --- a/packages/desktop/src/pages/overlay/index.tsx +++ b/packages/desktop/src/pages/overlay/index.tsx @@ -1,5 +1,34 @@ +import { useEffect, useState } from "react"; + +import { $maxNumberActiveStreams } from "../../controller/recoil"; +import { $numberActiveLines } from "../../controller/recoil"; +import { OVERLAY_ONLY_INITIAL_PRESET } from "../../electron/constants"; +import { useRecoilState } from "recoil"; + export default function Overlay() { - //todo: change window size based on how many streams are being shown + /** how many lines have someone broadcasting in them */ + const [numActiveLines, setNumActiveLines] = + useRecoilState($numberActiveLines); + const [maxNumActiveStreams, setMaxNumActiveStreams] = useRecoilState( + $maxNumberActiveStreams + ); + + // initially, have these set to default + useEffect(() => { + setNumActiveLines(1); + setMaxNumActiveStreams(1); + }, []); + + // TODO: get all of the toggle tuned in lines and any line that I am toggle broadcasting to + // loop through and send lineId to the x child stream overlay components who will do the work + + const addActiveLine = () => { + setNumActiveLines((prevNum) => prevNum + 1); + }; + + const addAnotherStream = () => { + setMaxNumActiveStreams((prevNum) => prevNum + 1); + }; return (
@@ -7,6 +36,9 @@ export default function Overlay() { className="w w-fit" src="https://miro.medium.com/max/1200/1*hONz6Wttkst4FUp_0hwQJQ.png" /> + + +
); } diff --git a/packages/desktop/src/pages/router/index.tsx b/packages/desktop/src/pages/router/index.tsx index 315b4d9..44a9c6d 100644 --- a/packages/desktop/src/pages/router/index.tsx +++ b/packages/desktop/src/pages/router/index.tsx @@ -1,6 +1,13 @@ +import { + $maxNumberActiveStreams, + $numberActiveLines, +} from "../../controller/recoil"; import Channels, { - DimensionPresets, + DimensionChangeRequest, Dimensions, + OVERLAY_ONLY_INITIAL_PRESET, + TERMINAL_DETAILS_PRESET, + TERMINAL_PRESET, } from "../../electron/constants"; import React, { useState } from "react"; import { useCallback, useEffect, useMemo } from "react"; @@ -9,6 +16,7 @@ import LineDetailsTerminal from "../lineDetailsTerminal"; import NirvanaHeader from "../../components/header/index"; import NirvanaTerminal from "../terminal"; import Overlay from "../overlay"; +import { useRecoilValue } from "recoil"; export interface ILineDetails { lineId: string; @@ -210,45 +218,83 @@ const testLines: ILineDetails[] = [ ), ]; -type DesktopMode = "overlay" | "terminal" | "terminalAndDetails"; +type DesktopMode = "flowState" | "overlayOnly" | "terminal" | "terminalDetails"; export default function NirvanaRouter() { const [selectedLineId, setSelectedLineId] = useState(null); - const [desktopMode, setDesktopMode] = useState( - DimensionPresets.terminal - ); + const [desktopMode, setDesktopMode] = useState("terminal"); + const numberOfOverlayColumns = useRecoilValue($numberActiveLines); + const numberOfOverlayRows = useRecoilValue($maxNumberActiveStreams); + // on window blur, put app in overlay only mode useEffect(() => { window.electronAPI.on(Channels.ON_WINDOW_BLUR, () => { console.log( "window blurring now, should be always on top and then ill tell main process to change dimensions" ); - setDesktopMode(DimensionPresets.overlayOnlyMode); + setDesktopMode("overlayOnly"); }); - }, []); + }, [setDesktopMode]); + // handle all window resizing logic useEffect(() => { - window.electronAPI.window.resizeWindow(desktopMode); - }, [desktopMode]); + // always have overlay so need to calculate that + const overlayDimensions: Dimensions = { + height: 50 + numberOfOverlayRows * 200, + width: 325 + numberOfOverlayColumns, + }; + const setAlwaysOnTop = desktopMode === "overlayOnly"; - useEffect(() => { - if (selectedLineId) { - setSelectedLineId(selectedLineId); - setDesktopMode(DimensionPresets.terminalAndDetails); - } else { - setSelectedLineId(null); - setDesktopMode(DimensionPresets.terminal); - } - }, [selectedLineId, setDesktopMode]); + // add dimensions if it's not overlay only mode + let finalDimensions: Dimensions = { height: 0, width: 0 }; + + if (desktopMode === "terminal") + finalDimensions = { height: 675, width: 400 }; + if (desktopMode === "terminalDetails") + finalDimensions = { height: 675, width: 800 }; + if (desktopMode === "flowState") + finalDimensions = { height: 50, width: 325 }; + + if (desktopMode !== "flowState") + finalDimensions = { + width: finalDimensions.width + overlayDimensions.width, + height: Math.max(finalDimensions.height, overlayDimensions.height), + }; + + console.log( + "setting new dimensions", + desktopMode, + numberOfOverlayColumns, + numberOfOverlayRows, + overlayDimensions, + finalDimensions, + setAlwaysOnTop + ); + + // send the final dimensions to main process + window.electronAPI.window.resizeWindow({ + setAlwaysOnTop, + dimensions: { + height: finalDimensions.height, + width: finalDimensions.width, + }, + addDimensions: false, + }); + }, [desktopMode, numberOfOverlayColumns, numberOfOverlayRows]); /** show user line details */ const handleSelectLine = useCallback( (lineId: string) => { setSelectedLineId(lineId); + setDesktopMode("terminalDetails"); }, - [setSelectedLineId] + [setSelectedLineId, setDesktopMode] ); + const handleToggleFlowState = useCallback(() => { + setDesktopMode("flowState"); + }, [setDesktopMode]); + const selectedLine = useMemo( () => testLines.find((line) => line.lineId === selectedLineId), [testLines, selectedLineId] @@ -256,21 +302,19 @@ export default function NirvanaRouter() { return (
- setDesktopMode(DimensionPresets.terminal)} - /> + setDesktopMode("terminal")} />
- {(desktopMode === DimensionPresets.terminal || - desktopMode === DimensionPresets.terminalAndDetails) && ( + {(desktopMode === "terminal" || desktopMode === "terminalDetails") && ( )} - {desktopMode === DimensionPresets.terminalAndDetails && - selectedLine && } + {desktopMode === "terminalDetails" && selectedLine && ( + + )}