getting decent logic and types and stuff for resizing and windows
This commit is contained in:
@@ -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,
|
||||||
|
});
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user