Skip to content

Commit

Permalink
Added IPC (for IpcRenderer and IpcMain) and a (very simple) loading s…
Browse files Browse the repository at this point in the history
…creen
  • Loading branch information
el3um4s committed Jul 15, 2021
1 parent 682ab23 commit 1ee576b
Show file tree
Hide file tree
Showing 17 changed files with 545 additions and 61 deletions.
32 changes: 32 additions & 0 deletions electron/IPC/General/IPC.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { BrowserWindow, IpcMain } from "electron";
import { APIChannels, SendChannels } from "./channelsInterface";

export default class IPC {
nameAPI: string = "api";
validSendChannel: SendChannels = {};
validReceiveChannel: string[] = [];

constructor(channels: APIChannels) {
this.nameAPI = channels.nameAPI;
this.validSendChannel = channels.validSendChannel;
this.validReceiveChannel = channels.validReceiveChannel;
}

get channels():APIChannels {
return {
nameAPI: this.nameAPI,
validSendChannel: this.validSendChannel,
validReceiveChannel: this.validReceiveChannel
}
}

initIpcMain(ipcMain:IpcMain, mainWindow: BrowserWindow) {
if (mainWindow) {
Object.keys(this.validSendChannel).forEach(key => {
ipcMain.on(key, async( event, message) => {
this.validSendChannel[key](mainWindow, event, message);
});
});
}
}
}
9 changes: 9 additions & 0 deletions electron/IPC/General/channelsInterface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export interface APIChannels {
nameAPI: string,
validSendChannel: SendChannels,
validReceiveChannel: string[]
}

export interface SendChannels {
[key: string]: Function
}
54 changes: 54 additions & 0 deletions electron/IPC/General/contextBridge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { contextBridge, ipcRenderer } from "electron";
import { APIChannels } from "./channelsInterface";
import IPC from "./IPC";

interface APIContextBridge {
send: (channel: string, data: any) => void;
receive: (channel: string, func: (arg0: any) => void) => void;
}

export function generateContextBridge(listIPC: IPC[]) {

let listChannels: APIChannels[] = [];
listIPC.forEach(el => {
listChannels.push(el.channels);
});

let listAPI: {[key: string]: APIContextBridge} = {};

listChannels.forEach(el => {
const api = getContextBridge(el);
const name = el.nameAPI;
listAPI[name] = {...api};
});

contextBridge.exposeInMainWorld("api", {
...listAPI
});
}

function getContextBridge(obj: APIChannels): APIContextBridge {
const { validReceiveChannel } = { ...obj };
const validSendChannel = getArrayOfValidSendChannel(obj);

return {
send: (channel: string, data: any) => {
// whitelist channels
if (validSendChannel.includes(channel)) {
ipcRenderer.send(channel, data);
}
},
receive: (channel: string, func: (arg0: any) => void) => {
if (validReceiveChannel.includes(channel)) {
// Deliberately strip event as it includes `sender`
ipcRenderer.on(channel, (event, ...args: [any]) => {func(...args);});
}
}
}
};

function getArrayOfValidSendChannel(obj: APIChannels): string[] {
const { validSendChannel } = { ...obj };
let result: string[] = Object.keys(validSendChannel);
return result;
}
38 changes: 38 additions & 0 deletions electron/IPC/systemInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { SendChannels } from "./General/channelsInterface";
import IPC from "./General/IPC";
import { BrowserWindow } from "electron";

const nameAPI = "systemInfo";

// to Main
const validSendChannel: SendChannels = {
"requestSystemInfo": requestSystemInfo
};

// from Main
const validReceiveChannel: string[] = [
"getSystemInfo",
];

const systemInfo = new IPC ({
nameAPI,
validSendChannel,
validReceiveChannel
});

export default systemInfo;

// Enter here the functions for ElectronJS

function requestSystemInfo(mainWindow: BrowserWindow, event: Electron.IpcMainEvent, message: any) {
const versionChrome = process.versions.chrome;
const versionNode = process.versions.node;
const versionElectron = process.versions.electron;
const result = {
chrome: versionChrome,
node: versionNode,
electron: versionElectron
}
mainWindow.webContents.send("getSystemInfo", result);
}

94 changes: 94 additions & 0 deletions electron/IPC/updaterInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { BrowserWindow, app } from "electron";
import { AppUpdater, autoUpdater } from "electron-updater";
import { SendChannels } from "./General/channelsInterface";
import IPC from "./General/IPC";

const nameAPI = "updaterInfo";

// to Main
const validSendChannel: SendChannels = {
"requestVersionNumber": requestVersionNumber,
"checkForUpdate": checkForUpdate,
"startDownloadUpdate": startDownloadUpdate,
"quitAndInstall": quitAndInstall,
};

// from Main
const validReceiveChannel: string[] = [
"getVersionNumber",
"checkingForUpdate",
"updateAvailable",
"updateNotAvailable",
"downloadProgress",
"updateDownloaded",
];

class UpdaterInfo extends IPC {
initAutoUpdater(autoUpdater: AppUpdater, mainWindow: BrowserWindow) {
initAutoUpdater(autoUpdater, mainWindow);
}
}

const updaterInfo = new UpdaterInfo ({
nameAPI,
validSendChannel,
validReceiveChannel
});

export default updaterInfo;

// Enter here the functions for ElectronJS

function initAutoUpdater(autoUpdater: AppUpdater, mainWindow: BrowserWindow) {
autoUpdater.on('checking-for-update', () => {
mainWindow.webContents.send("checkingForUpdate", null);
});

autoUpdater.on('error', (err) => { });

autoUpdater.on("update-available", (info: any) => {
mainWindow.webContents.send("updateAvailable", info);
});

autoUpdater.on('download-progress', (info: any) => {
mainWindow.webContents.send("downloadProgress", info);
});

autoUpdater.on("update-downloaded", (info: any) => {
mainWindow.webContents.send("updateDownloaded", info);
});

autoUpdater.on("update-not-available", (info: any) => {
mainWindow.webContents.send("updateNotAvailable", info);
});
}

function requestVersionNumber(mainWindow: BrowserWindow, event: Electron.IpcMainEvent, message: any) {
const version = app.getVersion();
const result = {version};
mainWindow.webContents.send("getVersionNumber", result);
}

function checkForUpdate(mainWindow: BrowserWindow, event: Electron.IpcMainEvent, message: any) {
autoUpdater.autoDownload = false;
autoUpdater.checkForUpdates();
}

function startDownloadUpdate(mainWindow: BrowserWindow, event: Electron.IpcMainEvent, message: any) {
autoUpdater.downloadUpdate();
}

function quitAndInstall(mainWindow: BrowserWindow, event: Electron.IpcMainEvent, message: any) {
autoUpdater.quitAndInstall();
}











54 changes: 54 additions & 0 deletions electron/configureDev.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import path from "path";
import serve from "electron-serve";
import { exec } from "child_process";

export interface DeveloperOptions {
isInProduction: boolean;
serveSvelteDev: boolean;
buildSvelteDev: boolean;
watchSvelteBuild: boolean;
}

class ConfigureDev {
isInProduction: boolean;
serveSvelteDev: boolean;
buildSvelteDev: boolean;
watchSvelteBuild: boolean;
loadURL: any;

constructor(settings: DeveloperOptions) {
this.isInProduction = settings.isInProduction
this.serveSvelteDev = settings.serveSvelteDev
this.buildSvelteDev = settings.buildSvelteDev
this.watchSvelteBuild = settings.watchSvelteBuild
this.loadURL = null;

this._check_isInProduction();

if (!this.isInProduction && this.serveSvelteDev) this._dev_Svelte();
if (!this.isInProduction && this.buildSvelteDev) this._build_Dist();
if (!this.isInProduction && this.watchSvelteBuild) this._watch_Dist();
if (this.isInProduction || !this.serveSvelteDev) this._serve_Dist();
}

_check_isInProduction() {
if (! this.isInProduction){
this.isInProduction = process.env.NODE_ENV === "production" || !/[\\/]electron/.exec(process.execPath); // !process.execPath.match(/[\\/]electron/);
};
}
_dev_Svelte() {
exec("npm run svelte:dev");
require("electron-reload")(path.join(__dirname, "..", "svelte"));
}
_build_Dist() { exec("npm run svelte:build"); }
_watch_Dist() { require("electron-reload")(path.join(__dirname, "www")); }
_serve_Dist() {
this.loadURL = serve({ directory: "dist/www" });
}

isLocalHost() { return this.serveSvelteDev; }
isElectronServe() { return !this.serveSvelteDev; }

}

export default ConfigureDev;
74 changes: 17 additions & 57 deletions electron/index.ts
Original file line number Diff line number Diff line change
@@ -1,70 +1,30 @@
import { app, BrowserWindow } from "electron";
import path from "path";
import serve from "electron-serve";
import { exec } from "child_process";
import { ipcMain } from 'electron';
import { autoUpdater } from "electron-updater";
import Main from "./mainWindow";

import systemInfo from './IPC/systemInfo';
import updaterInfo from './IPC/updaterInfo';

const developerOptions = {
isInProduction: false, // true if is in production
isInProduction: true, // true if is in production
serveSvelteDev: false, // true when you want to watch svelte
buildSvelteDiv: false, // true when you want to build svelte
buildSvelteDev: false, // true when you want to build svelte
watchSvelteBuild: false, // true when you want to watch build svelte
};

if (! developerOptions.isInProduction){
developerOptions.isInProduction = process.env.NODE_ENV === "production" || !/[\\/]electron/.exec(process.execPath); // !process.execPath.match(/[\\/]electron/);
}
let loadURL:any = null;

if (!developerOptions.isInProduction && developerOptions.serveSvelteDev) {
console.log("npm run svelte:dev");
exec("npm run svelte:dev");
console.log("electron-reload svelte dev");
require("electron-reload")(path.join(__dirname, "..", "svelte"));
}

if (!developerOptions.isInProduction && developerOptions.buildSvelteDiv) {
console.log("npm run svelte:build");
exec("npm run svelte:build");
const windowSettings = {
title: "MEMENTO - SvelteKit, Electron, TypeScript",
width: 854,
height: 854
}

if (!developerOptions.isInProduction && developerOptions.watchSvelteBuild) {
console.log("electron-reload www");
require("electron-reload")(path.join(__dirname, "www"));
}
let main = new Main(windowSettings, developerOptions);

main.onEvent.on("window-created", async () => {
systemInfo.initIpcMain(ipcMain, main.window);
updaterInfo.initIpcMain(ipcMain, main.window);

if (developerOptions.isInProduction || !developerOptions.serveSvelteDev) {
console.log("serve dist/www");
loadURL = serve({ directory: "dist/www" });
}
updaterInfo.initAutoUpdater(autoUpdater, main.window);

let mainWindow = null;

const createWindow = async () => {
mainWindow = new BrowserWindow({
width: 854,
height: 480,
webPreferences: {
nodeIntegration: true,
contextIsolation: true,
enableRemoteModule: true,
},
});

if (developerOptions.serveSvelteDev) {
mainWindow.loadURL("http://localhost:3000/");
} else if (loadURL) {
await loadURL(mainWindow);
}
};

app.on("ready", async () => {
app.name = "Svelte Template";
await createWindow();
});

app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});
Loading

0 comments on commit 1ee576b

Please sign in to comment.