Skip to content

Commit

Permalink
get preload script working, minimize/maximize buttons, upgrade deps
Browse files Browse the repository at this point in the history
  • Loading branch information
marcello3d committed Dec 5, 2020
1 parent 61a06bf commit ad4b4d2
Show file tree
Hide file tree
Showing 19 changed files with 1,198 additions and 1,126 deletions.
27 changes: 23 additions & 4 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 31 additions & 25 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "graphql-98",
"productName": "GraphQL ‘98",
"version": "0.1.0-rc.4",
"private": true,
"description": "A visual GraphQL data browser. Like a SQL GUI for GraphQL!",
Expand Down Expand Up @@ -41,7 +42,8 @@
{
"name": "@electron-forge/maker-squirrel",
"config": {
"name": "GraphQL 98"
"name": "GraphQL98",
"exe": "GraphQL 98"
},
"platforms": [
"win32"
Expand All @@ -66,6 +68,9 @@
{
"html": "./src/renderer/index.html",
"js": "./src/renderer/index.tsx",
"preload": {
"js": "./src/preload/preload.ts"
},
"name": "app"
}
]
Expand All @@ -87,7 +92,8 @@
}
},
"dependencies": {
"electron-squirrel-startup": "1.0.0"
"electron-squirrel-startup": "1.0.0",
"fast-deep-equal": "3.1.3"
},
"devDependencies": {
"98.css": "0.1.16",
Expand All @@ -101,44 +107,44 @@
"@marshallofsound/webpack-asset-relocator-loader": "^0.5.0",
"@reach/router": "1.3.4",
"@types/classnames": "2.2.11",
"@types/node": "14.14.6",
"@types/node": "14.14.10",
"@types/reach__router": "1.3.6",
"@types/react": "^16.9.55",
"@types/react-dom": "^16.9.8",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@types/react-table": "7.0.25",
"@typescript-eslint/eslint-plugin": "^4.6.0",
"@typescript-eslint/parser": "^4.6.0",
"camelcase": "^5.3.1",
"@typescript-eslint/eslint-plugin": "^4.9.0",
"@typescript-eslint/parser": "^4.9.0",
"camelcase": "^6.2.0",
"classnames": "2.2.6",
"css-loader": "^4.2.1",
"electron": "11.0.0-beta.16",
"css-loader": "^5.0.1",
"electron": "11.0.3",
"electron-is-dev": "1.2.0",
"eslint": "^7.12.1",
"eslint": "^7.15.0",
"eslint-config-prettier": "6.15.0",
"eslint-plugin-react": "7.21.5",
"eslint-plugin-react-hooks": "^4.2.0",
"file-loader": "4.3.0",
"file-loader": "6.2.0",
"graphql": "15.4.0",
"graphql-formatter": "1.0.3",
"graphql-hooks": "5.0.0",
"husky": "4.3.0",
"mini-css-extract-plugin": "0.9.0",
"mini-css-extract-plugin": "1.3.2",
"node-loader": "^1.0.1",
"prettier": "2.1.2",
"pretty-quick": "2.0.1",
"query-string": "6.13.6",
"prettier": "2.2.1",
"pretty-quick": "3.1.0",
"query-string": "6.13.7",
"react": "17.0.1",
"react-dev-utils": "^10.2.1",
"react-dev-utils": "^11.0.1",
"react-dom": "17.0.1",
"react-table": "7.6.1",
"semver": "6.3.0",
"style-loader": "^1.2.1",
"ts-loader": "^8.0.2",
"typescript": "^4.0.5",
"url-loader": "2.3.0",
"use-query-params": "1.1.8",
"react-table": "7.6.2",
"semver": "7.3.4",
"style-loader": "^2.0.0",
"ts-loader": "^8.0.11",
"typescript": "^4.1.2",
"url-loader": "4.1.1",
"use-query-params": "1.1.9",
"viz.js": "2.1.2",
"ws": "7.3.1"
"ws": "7.4.1"
},
"babel": {
"presets": [
Expand Down
5 changes: 5 additions & 0 deletions src/WindowState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type WindowState = {
maximized: boolean;
fullscreen: boolean;
fullscreenable: boolean;
};
49 changes: 0 additions & 49 deletions src/main/index.ts

This file was deleted.

120 changes: 120 additions & 0 deletions src/main/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { app, BrowserWindow, ipcMain, shell } from 'electron';
import fastDeepEqual from 'fast-deep-equal';

declare const APP_WEBPACK_ENTRY: string;
declare const APP_PRELOAD_WEBPACK_ENTRY: string;

// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require('electron-squirrel-startup')) {
// eslint-disable-line global-require
app.quit();
}

console.log(APP_PRELOAD_WEBPACK_ENTRY, APP_WEBPACK_ENTRY);

const createWindow = (): void => {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 500,
resizable: true,
maximizable: true,
minimizable: true,
frame: false,

webPreferences: {
allowRunningInsecureContent: false,
contextIsolation: true,
enableRemoteModule: false,
preload: APP_PRELOAD_WEBPACK_ENTRY,
nativeWindowOpen: true,
nodeIntegration: false,
nodeIntegrationInWorker: false,
nodeIntegrationInSubFrames: false,
safeDialogs: true,
sandbox: true,
webSecurity: false, // Needed to bypass CORS requests---could replace this with a proxied fetch in the future
webviewTag: false,
},
});

// and load the index.html of the app.
mainWindow.loadURL(APP_WEBPACK_ENTRY);

// Open the DevTools.
mainWindow.webContents.openDevTools({ mode: 'detach' });
let lastWindowState: unknown;
function updateWindowState() {
const windowState = {
maximized: mainWindow.isMaximized(),
fullscreen: mainWindow.isFullScreen(),
fullscreenable: mainWindow.isFullScreenable(),
};
if (!fastDeepEqual(lastWindowState, windowState)) {
lastWindowState = windowState;
mainWindow.webContents.send('window-state', windowState);
}
}
mainWindow.on('maximize', updateWindowState);
mainWindow.on('resize', updateWindowState);
mainWindow.on('minimize', updateWindowState);
mainWindow.on('enter-full-screen', updateWindowState);
mainWindow.on('enter-html-full-screen', updateWindowState);
mainWindow.on('leave-full-screen', updateWindowState);
mainWindow.on('leave-html-full-screen', updateWindowState);
mainWindow.on('restore', updateWindowState);
mainWindow.webContents.once('did-finish-load', updateWindowState);
};

app.on('web-contents-created', (event, contents) => {
contents
.on('new-window', (event, url) => {
event.preventDefault();
if (url.startsWith('https://')) {
shell.openExternal(url);
}
})
.on('will-navigate', (event, navigationUrl) => {
event.preventDefault();
});
});

function getWin(event: Electron.IpcMainInvokeEvent) {
return BrowserWindow.getAllWindows().find(
(win) => win.webContents === event.sender,
);
}

ipcMain.handle('minimize', (event) => {
getWin(event)?.minimize();
});
ipcMain.handle('restore', (event) => {
getWin(event)?.restore();
});
ipcMain.handle('maximize', (event) => {
getWin(event)?.maximize();
});
ipcMain.handle('unmaximize', (event) => {
getWin(event)?.unmaximize();
});

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
if (process.platform !== 'darwin') {
app.on('window-all-closed', () => {
app.quit();
});
app.on('activate', () => {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
}
14 changes: 14 additions & 0 deletions src/preload.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { WindowState } from './WindowState';

declare global {
interface Window {
ElectronMainApi: {
minimize(): void;
restore(): void;
maximize(): void;
unmaximize(): void;
getWindowState(): WindowState;
subscribeWindowState(callback: (state: WindowState) => void): () => void;
};
}
}
29 changes: 29 additions & 0 deletions src/preload/preload.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { contextBridge, ipcRenderer } from 'electron';
import { WindowState } from '../WindowState';

let windowState: WindowState = {
maximized: false,
fullscreen: false,
fullscreenable: false,
};
const subscribers = new Set<(state: WindowState) => void>();
ipcRenderer.on('window-state', (event, _windowState) => {
windowState = _windowState;
for (const subscriber of subscribers) {
subscriber(windowState);
}
});

contextBridge.exposeInMainWorld('ElectronMainApi', {
minimize: () => ipcRenderer.invoke('minimize'),
restore: () => ipcRenderer.invoke('restore'),
maximize: () => ipcRenderer.invoke('maximize'),
unmaximize: () => ipcRenderer.invoke('unmaximize'),
getWindowState: () => windowState,
subscribeWindowState: (callback: (windowState: WindowState) => void) => {
subscribers.add(callback);
return () => {
subscribers.delete(callback);
};
},
});
Loading

0 comments on commit ad4b4d2

Please sign in to comment.