getting decent logic and types and stuff for resizing and windows

This commit is contained in:
talksik
2022-05-02 07:48:03 -05:00
parent 77f54dd609
commit a97748d83d
7 changed files with 159 additions and 76 deletions
@@ -86,9 +86,10 @@ export default function NirvanaHeader({
<div <div
className="flex flex-row items-center bg-gray-100 pl-2 border-b border-b-gray-200" className="flex flex-row items-center bg-gray-100 pl-2 border-b border-b-gray-200"
id="titlebar" id="titlebar"
onFocus={onHeaderFocus}
> >
<Logo type="small" /> <div onClick={onHeaderFocus}>
<Logo type="small" />
</div>
<div className="mx-auto flex flex-row items-center space-x-2 ml-2"> <div className="mx-auto flex flex-row items-center space-x-2 ml-2">
<FaSearch className="text-xs text-gray-300" /> <FaSearch className="text-xs text-gray-300" />
@@ -29,3 +29,15 @@ export const $selectedOutputMode = atom<outputMode>({
key: "OUTPUT_MODE", key: "OUTPUT_MODE",
default: "video", default: "video",
}); });
// number of active lines
export const $numberActiveLines = atom<number>({
key: "NUMBER_ACTIVE_LINES",
default: 0,
});
// max number of active streams
export const $maxNumberActiveStreams = atom<number>({
key: "MAX_NUMBER_ACTIVE_STREAMS",
default: 0,
});
+19 -17
View File
@@ -13,25 +13,27 @@ export enum STORE_ITEMS {
AUTH_SESSION_JWT = "AUTH_SESSION_JWT", AUTH_SESSION_JWT = "AUTH_SESSION_JWT",
} }
export type Dimensions = { export type Dimensions = { height: number; width: number };
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 = { export const TERMINAL_DETAILS_PRESET: Dimensions = {
terminal: { height: 675,
height: 675, width: 800,
width: 400, };
},
terminalAndDetails: { export const OVERLAY_ONLY_INITIAL_PRESET: Dimensions = {
height: 675, height: 50,
width: 800, width: 325,
},
// todo: typically just send whatever dimensions are needed
overlayOnlyMode: {
height: 800,
width: 325,
},
}; };
export default Channels; export default Channels;
+2 -1
View File
@@ -1,3 +1,4 @@
import { Dimensions, DimensionChangeRequest } from "./constants";
import { electronAPI } from "./preload"; import { electronAPI } from "./preload";
export {}; export {};
@@ -12,7 +13,7 @@ declare global {
set(property: STORE_ITEMS, val: any): void; set(property: STORE_ITEMS, val: any): void;
}; };
window: { window: {
resizeWindow(newDimensions: { width: number; height: number }): void; resizeWindow(dimensionChangeRequest: DimensionChangeRequest): void;
}; };
on(channel: Channels, func: any): void; on(channel: Channels, func: any): void;
once(channel: Channels, func: any): void; once(channel: Channels, func: any): void;
+20 -29
View File
@@ -7,9 +7,9 @@ import {
ipcMain, ipcMain,
screen, screen,
} from "electron"; } 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 { handleGoogleLogin } from "./electron/handleLogin";
import path from "path"; import path from "path";
import store from "./electron/store"; import store from "./electron/store";
@@ -35,7 +35,7 @@ let display;
const createWindow = (): void => { const createWindow = (): void => {
// Create the browser window. // Create the browser window.
browserWindow = new BrowserWindow({ browserWindow = new BrowserWindow({
...DimensionPresets.terminal, ...{ height: TERMINAL_PRESET.height, width: TERMINAL_PRESET.width },
webPreferences: { webPreferences: {
preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY, preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY,
sandbox: true, sandbox: true,
@@ -87,26 +87,27 @@ app
}); });
// dynamically changing the window bounds // dynamically changing the window bounds
ipcMain.on(Channels.RESIZE_WINDOW, (event, arg) => { ipcMain.on(Channels.RESIZE_WINDOW, (event, req: DimensionChangeRequest) => {
const { width, height } = arg; if (req.setAlwaysOnTop) {
if (
width === DimensionPresets.overlayOnlyMode.width &&
height === DimensionPresets.overlayOnlyMode.height
) {
browserWindow.setAlwaysOnTop(true, "floating"); browserWindow.setAlwaysOnTop(true, "floating");
// move window/overlay to top right
browserWindow.setPosition(display.bounds.width - width, 0, true);
browserWindow.setSize(width, height, true);
} else { } else {
browserWindow.setSize(width, height, true);
browserWindow.center();
browserWindow.setAlwaysOnTop(false); 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(() => { .then(() => {
@@ -116,16 +117,6 @@ app
// on blur, show overlay, and tell app to trigger overlay mode // on blur, show overlay, and tell app to trigger overlay mode
browserWindow.on("blur", () => { 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); browserWindow.webContents.send(Channels.ON_WINDOW_BLUR);
}); });
}); });
+33 -1
View File
@@ -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() { 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 ( return (
<div className="flex flex-col bg-transparent"> <div className="flex flex-col bg-transparent">
@@ -7,6 +36,9 @@ export default function Overlay() {
className="w w-fit" className="w w-fit"
src="https://miro.medium.com/max/1200/1*hONz6Wttkst4FUp_0hwQJQ.png" src="https://miro.medium.com/max/1200/1*hONz6Wttkst4FUp_0hwQJQ.png"
/> />
<button onClick={addActiveLine}>add column</button>
<button onClick={addAnotherStream}>add row</button>
</div> </div>
); );
} }
+70 -26
View File
@@ -1,6 +1,13 @@
import {
$maxNumberActiveStreams,
$numberActiveLines,
} from "../../controller/recoil";
import Channels, { import Channels, {
DimensionPresets, DimensionChangeRequest,
Dimensions, Dimensions,
OVERLAY_ONLY_INITIAL_PRESET,
TERMINAL_DETAILS_PRESET,
TERMINAL_PRESET,
} from "../../electron/constants"; } from "../../electron/constants";
import React, { useState } from "react"; import React, { useState } from "react";
import { useCallback, useEffect, useMemo } from "react"; import { useCallback, useEffect, useMemo } from "react";
@@ -9,6 +16,7 @@ import LineDetailsTerminal from "../lineDetailsTerminal";
import NirvanaHeader from "../../components/header/index"; import NirvanaHeader from "../../components/header/index";
import NirvanaTerminal from "../terminal"; import NirvanaTerminal from "../terminal";
import Overlay from "../overlay"; import Overlay from "../overlay";
import { useRecoilValue } from "recoil";
export interface ILineDetails { export interface ILineDetails {
lineId: string; lineId: string;
@@ -210,45 +218,83 @@ const testLines: ILineDetails[] = [
), ),
]; ];
type DesktopMode = "overlay" | "terminal" | "terminalAndDetails"; type DesktopMode = "flowState" | "overlayOnly" | "terminal" | "terminalDetails";
export default function NirvanaRouter() { export default function NirvanaRouter() {
const [selectedLineId, setSelectedLineId] = useState<string>(null); const [selectedLineId, setSelectedLineId] = useState<string>(null);
const [desktopMode, setDesktopMode] = useState<Dimensions>( const [desktopMode, setDesktopMode] = useState<DesktopMode>("terminal");
DimensionPresets.terminal const numberOfOverlayColumns = useRecoilValue($numberActiveLines);
); const numberOfOverlayRows = useRecoilValue($maxNumberActiveStreams);
// on window blur, put app in overlay only mode
useEffect(() => { useEffect(() => {
window.electronAPI.on(Channels.ON_WINDOW_BLUR, () => { window.electronAPI.on(Channels.ON_WINDOW_BLUR, () => {
console.log( console.log(
"window blurring now, should be always on top and then ill tell main process to change dimensions" "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(() => { useEffect(() => {
window.electronAPI.window.resizeWindow(desktopMode); // always have overlay so need to calculate that
}, [desktopMode]); const overlayDimensions: Dimensions = {
height: 50 + numberOfOverlayRows * 200,
width: 325 + numberOfOverlayColumns,
};
const setAlwaysOnTop = desktopMode === "overlayOnly";
useEffect(() => { // add dimensions if it's not overlay only mode
if (selectedLineId) { let finalDimensions: Dimensions = { height: 0, width: 0 };
setSelectedLineId(selectedLineId);
setDesktopMode(DimensionPresets.terminalAndDetails); if (desktopMode === "terminal")
} else { finalDimensions = { height: 675, width: 400 };
setSelectedLineId(null); if (desktopMode === "terminalDetails")
setDesktopMode(DimensionPresets.terminal); finalDimensions = { height: 675, width: 800 };
} if (desktopMode === "flowState")
}, [selectedLineId, setDesktopMode]); 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 */ /** show user line details */
const handleSelectLine = useCallback( const handleSelectLine = useCallback(
(lineId: string) => { (lineId: string) => {
setSelectedLineId(lineId); setSelectedLineId(lineId);
setDesktopMode("terminalDetails");
}, },
[setSelectedLineId] [setSelectedLineId, setDesktopMode]
); );
const handleToggleFlowState = useCallback(() => {
setDesktopMode("flowState");
}, [setDesktopMode]);
const selectedLine = useMemo( const selectedLine = useMemo(
() => testLines.find((line) => line.lineId === selectedLineId), () => testLines.find((line) => line.lineId === selectedLineId),
[testLines, selectedLineId] [testLines, selectedLineId]
@@ -256,21 +302,19 @@ export default function NirvanaRouter() {
return ( return (
<div className="flex flex-col h-screen w-screen"> <div className="flex flex-col h-screen w-screen">
<NirvanaHeader <NirvanaHeader onHeaderFocus={() => setDesktopMode("terminal")} />
onHeaderFocus={() => setDesktopMode(DimensionPresets.terminal)}
/>
<div className="flex flex-row flex-1"> <div className="flex flex-row flex-1">
{(desktopMode === DimensionPresets.terminal || {(desktopMode === "terminal" || desktopMode === "terminalDetails") && (
desktopMode === DimensionPresets.terminalAndDetails) && (
<NirvanaTerminal <NirvanaTerminal
handleSelectLine={handleSelectLine} handleSelectLine={handleSelectLine}
allLines={testLines} allLines={testLines}
/> />
)} )}
{desktopMode === DimensionPresets.terminalAndDetails && {desktopMode === "terminalDetails" && selectedLine && (
selectedLine && <LineDetailsTerminal selectedLine={selectedLine} />} <LineDetailsTerminal selectedLine={selectedLine} />
)}
<Overlay /> <Overlay />
</div> </div>