Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce window modes with overlay and transparent overlay #355

Merged
merged 19 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
01c9c1b
update: save windowState separately for each windowMode
fperera123 Sep 3, 2024
10838a8
add: windowMode manager
fperera123 Sep 3, 2024
c7b069b
add: windowMode handler
fperera123 Sep 3, 2024
c3c325d
add: windowMode handle on mainWindow
fperera123 Sep 3, 2024
c2034f6
update: make overlay draggable
fperera123 Sep 3, 2024
193e2cf
update: ui for smaller sizes
fperera123 Sep 3, 2024
55b8518
update: Add window mode handling and local storage storage for window…
fperera123 Sep 3, 2024
bf65d06
feat: Add support for transparent overlay window mode
fperera123 Sep 3, 2024
45c6eb5
feat: Add window mode selection and handling in settings page
fperera123 Sep 3, 2024
6eae0f7
Update: overlayTransparent window mode dimensions and options
fperera123 Sep 3, 2024
5509298
update: Remove console.log statement in handleSetWindowMode function
fperera123 Sep 6, 2024
8b22a82
feat: add switch to windowed mode from overlay mode via dashboard screen
fperera123 Sep 6, 2024
cb41ff2
update: exit from overlay mode if user has to authenticate
fperera123 Sep 6, 2024
94b6037
fix: responsiveness of switch window mode icon
fperera123 Sep 6, 2024
7b0d758
update: window mode button styles
fperera123 Sep 6, 2024
00fcaf3
update: skip restore previous window size for overlayTransparent mode
fperera123 Sep 6, 2024
844bc66
update: improve type settings
fperera123 Sep 6, 2024
7726f6f
update: remove frame shadow for mac
fperera123 Sep 6, 2024
9cc7521
update: add text shadow when overlay transparent
fperera123 Sep 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 73 additions & 23 deletions src/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { app, BrowserWindow, ipcMain, shell } from "electron"
import MenuBuilder from "./menu"
import { resolveHtmlPath } from "./util"
import { WindowStateManager, WindowState } from './windowState';
import { WindowModeManager } from "./windowMode";
import { registerWindowHandlers, destroyWindowHandlers } from "./windowHandler";
import { registerLogoutHandler, destroyLogoutHandler } from "./logoutHandler";
import { registerRefreshHandler, destroyRefreshHandler } from "./refreshHandler";
Expand Down Expand Up @@ -44,41 +45,28 @@ const installExtensions = async () => {
.catch(console.log)
}

const windowModeManager = new WindowModeManager('main-window');
const windowMode = windowModeManager.getWindowMode();

const createWindow = async () => {
if (isDebug) {
await installExtensions()
}

const RESOURCES_PATH = app.isPackaged
? path.join(process.resourcesPath, 'assets')
: path.join(__dirname, '../../assets')
const windowOptions = getWindowOptions(windowMode);

const getAssetPath = (...paths: string[]): string => {
return path.join(RESOURCES_PATH, ...paths)
}

mainWindow = new BrowserWindow({
show: false,
width: 1024,
height: 728,
icon: getAssetPath('icon.png'),
webPreferences: {
webSecurity: false,
preload: app.isPackaged
? path.join(__dirname, 'preload.js')
: path.join(__dirname, '../../.erb/dll/preload.js'),
},
})

mainWindow.isPrimary = true;
mainWindow = new BrowserWindow(windowOptions);

// 👉 save window state
const defaultWindowState: WindowState = {
width: 1024,
height: 728,
};
const windowStateManager = new WindowStateManager('main', defaultWindowState);
windowStateManager.manage(mainWindow);

if(windowMode !== 'overlayTransparent') {
const windowStateManager = new WindowStateManager('main', defaultWindowState, windowMode);
windowStateManager.manage(mainWindow);
}

mainWindow.loadURL(resolveHtmlPath('index.html'))

Expand Down Expand Up @@ -111,6 +99,66 @@ const createWindow = async () => {
// new AppUpdater()
}

const getWindowOptions = (windowMode: 'overlay' | 'windowed' | 'overlayTransparent'): Electron.BrowserWindowConstructorOptions => {

const RESOURCES_PATH = app.isPackaged
? path.join(process.resourcesPath, 'assets')
: path.join(__dirname, '../../assets')

const getAssetPath = (...paths: string[]): string => {
return path.join(RESOURCES_PATH, ...paths)
}

const baseOptions: Electron.BrowserWindowConstructorOptions = {
show: false,
minWidth: 200,
minHeight: 45,
icon: getAssetPath('icon.png'),
webPreferences: {
webSecurity: false,
preload: app.isPackaged
? path.join(__dirname, 'preload.js')
: path.join(__dirname, '../../.erb/dll/preload.js'),
},
isPrimary: true,
resizable: true,
movable: true,
};

if (windowMode === 'overlay') {
return {
...baseOptions,
width: 800,
height: 600,
alwaysOnTop: true,
frame: false,
};
}
if (windowMode === 'overlayTransparent') {
return {
...baseOptions,
width: 200,
height: 45,
alwaysOnTop: true,
frame: false,
transparent: true,
resizable: false,
hasShadow: false,
};
}
else if (windowMode === 'windowed') {
return {
...baseOptions,
width: 1024,
height: 728,
frame: true,
};
}

return baseOptions;
}


/**
* Add event listeners...
*/
Expand Down Expand Up @@ -152,3 +200,5 @@ ipcMain.handle('ipc-open-file', async (event, ...args) => {
registerWindowHandlers();
registerLogoutHandler();
registerRefreshHandler();

export const getMainWindow = () => mainWindow;
18 changes: 18 additions & 0 deletions src/main/windowHandler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { BrowserWindow, ipcMain, app } from 'electron';
import path from 'path';
import { resolveHtmlPath } from './util';
import { WindowModeManager } from './windowMode';

interface WindowCache {
[url: string]: BrowserWindow | undefined;
Expand All @@ -9,6 +10,9 @@ interface WindowCache {
export const registerWindowHandlers = () => {
const windowCache: WindowCache = {};

const windowModeManager = new WindowModeManager('main-window');


// 👉 register window handlers
ipcMain.on('open-new-window', (event, url, width, height) => {
// Check if the window for this URL already exists
Expand Down Expand Up @@ -40,9 +44,23 @@ export const registerWindowHandlers = () => {
});

});

ipcMain.on('set-window-mode', (event, mode: 'overlay' | 'windowed') => {
windowModeManager.setWindowMode(mode);

// in order to change window options we need to restart
app.relaunch();
app.exit();
});

ipcMain.handle('get-window-mode', () => {
return windowModeManager.getWindowMode();
});
};

export const destroyWindowHandlers = () => {
// 👉 destroy window handlers
ipcMain.removeAllListeners('open-new-window');
ipcMain.removeAllListeners('set-window-mode');
ipcMain.removeAllListeners('get-window-mode');
};
30 changes: 30 additions & 0 deletions src/main/windowMode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { app } from 'electron';
import fs from 'fs';
import path from 'path';

export class WindowModeManager {

private filePath: string;

constructor(private windowName: string) {
const userDataPath = app.getPath('userData');
this.filePath = path.join(userDataPath, `${windowName}-window-mode.json`);
console.log('filePath', this.filePath);
}

getWindowMode(): 'overlay' | 'windowed' | 'overlayTransparent' {
try {
const data = fs.readFileSync(this.filePath, 'utf8');
const parsed = JSON.parse(data);
return parsed.windowMode;
} catch (error) {
return 'windowed';
}
}

setWindowMode(mode: 'overlay' | 'windowed') {
const data = JSON.stringify({ windowMode: mode }, null, 2);
console.log('setWindowMode', this.filePath, data, mode);
fs.writeFileSync(this.filePath, data);
}
}
8 changes: 6 additions & 2 deletions src/main/windowState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ export class WindowStateManager {

private state: WindowState;

constructor(private windowName: string, private defaultState: WindowState) {
constructor(private windowName: string, private defaultState: WindowState, private windowMode: 'overlay' | 'overlayTransparent' | 'windowed') {
const userDataPath = app.getPath('userData');
this.stateFilePath = path.join(userDataPath, `${windowName}-window-state.json`);
this.stateFilePath = path.join(userDataPath, `${windowName}-${windowMode}-window-state.json`);
this.state = this.readState();
}

Expand Down Expand Up @@ -61,4 +61,8 @@ export class WindowStateManager {
};
this.saveState(this.state);
}

public getState(): WindowState {
return this.state;
}
}
13 changes: 13 additions & 0 deletions src/renderer/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import "@/globals.css"
import "@/custom.css"
import "@/i18n/config"
import { useEffect } from "react"
import { getWindowMode, setLocalStorageWindowMode } from "@/lib/utils";

export default function App() {
const token = useAuthStore((state) => state.token)
Expand All @@ -22,6 +23,18 @@ export default function App() {
};
}, []);


useEffect(() => {
async function fetchAndStoreWindowMode() {
const mode = await getWindowMode();
console.log('fetchWindowMode', mode);

setLocalStorageWindowMode(mode);
}

fetchAndStoreWindowMode();
}, []);

return (
<AnimatePresence>
<RouterProvider router={routes(!!token)} />
Expand Down
16 changes: 16 additions & 0 deletions src/renderer/config/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,25 @@ const resultUnits: DropdownConfigType[] = [
},
];

const windowModes: DropdownConfigType[] = [
{
label: 'Overlay',
value: 'overlay',
},
{
label: 'Overlay (Transparent)',
value: 'overlayTransparent',
},
{
label: 'Windowed',
value: 'windowed',
},
];

export {
countries,
languages,
themes,
resultUnits,
windowModes,
}
12 changes: 12 additions & 0 deletions src/renderer/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,15 @@
--ring: 12 100% 50%;
}
}

.draggable{
-webkit-app-region: drag;
}

.no-draggable{
-webkit-app-region: no-drag;
}

.overlay-shadow{
text-shadow: 2px 1px 5px rgba(0, 0, 0, 0.8);
}
20 changes: 18 additions & 2 deletions src/renderer/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,24 @@ export async function openFile(type: string, folder: string, group: string, file
await window.electron.ipcRenderer.invoke('ipc-open-file', type, folder, group, filename)
}

export function openNewWindow(path: string, width: number, height: number) {
window.electron.ipcRenderer.sendMessage('open-new-window', path, width, height)
export async function openNewWindow(path: string, width: number, height: number) {
await window.electron.ipcRenderer.sendMessage('open-new-window', path, width, height)
}

export async function setWindowMode(mode: string) {
await window.electron.ipcRenderer.sendMessage('set-window-mode', mode)
}

export async function getWindowMode() {
return await window.electron.ipcRenderer.invoke('get-window-mode')
}

export async function setLocalStorageWindowMode(mode: string) {
await localStorage.setItem('windowMode', mode);
}

export async function getLocalStorageWindowMode(): Promise<string> {
return await localStorage.getItem('windowMode') as string;
}

export async function setRedirectTo (path: string) {
Expand Down
Loading
Loading