Skip to content

Commit

Permalink
refactored electron index
Browse files Browse the repository at this point in the history
This is the beginning of the refactoring effort
  • Loading branch information
YT-GameWorks committed Oct 26, 2023
1 parent 4082623 commit 5a494ab
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 132 deletions.
30 changes: 30 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module.exports = {
env: {
es2021: true,
node: true,
},
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
overrides: [
{
env: {
node: true,
},
files: [".eslintrc.{js,cjs}"],
parserOptions: {
sourceType: "script",
},
},
],
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
},
plugins: ["@typescript-eslint"],
rules: {
indent: ["error", 2],
"linebreak-style": ["error", "unix"],
quotes: ["error", "double"],
semi: ["error", "always"],
},
};
107 changes: 107 additions & 0 deletions client/electron/main/eventHandlers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { BrowserWindow, dialog, app, ipcMain } from "electron";
import settings from "electron-settings";
import { autoUpdater } from "electron-updater";

/**
* Provides handlers to critical events in the app's lifecycle such as auto updaters, url handles etc..
*
* @param {BrowserWindow} win
* @param {string} preload
* @param {string} indexHtml
*/
export async function callHandlers(
win: BrowserWindow,
preload: string,
indexHtml: string,
) {
// Quits when all windows are closed
app.on("window-all-closed", () => {
win = null;
if (process.platform !== "darwin") app.quit();
});

// Handles external websites linking back to the application.
app.on("open-url", (event, url) => {
dialog.showErrorBox("Welcome Back", `You arrived from: ${url}`);
});

// handles the dialog box to open folders.
ipcMain.handle("dialog:openFolder", handleFolderOpen);

/**
* Handles opening external folders
*/
async function handleFolderOpen() {
const currentLibraryPath = await (
await settings.get("locations.libraryLocation")
).toString();
const { canceled, filePaths } = await dialog.showOpenDialog(win, {
title: "Select Library Location",
defaultPath: currentLibraryPath,
properties: ["openDirectory"],
});
if (canceled) {
return;
} else {
return filePaths[0];
}
}

// handles child windows
ipcMain.handle("open-win", (event, arg) => {
const childWindow = new BrowserWindow({
webPreferences: {
preload,
nodeIntegration: true,
contextIsolation: false,
},
});

if (process.env.VITE_DEV_SERVER_URL) {
childWindow.loadURL(`${process.env.VITE_DEV_SERVER_URL}#${arg}`);
} else {
childWindow.loadFile(indexHtml, { hash: arg });
}
});

// This section handles auto updates
app.on("ready", () => {
autoUpdater.checkForUpdatesAndNotify();
});
autoUpdater.on("update-available", (info) => {
win.webContents.send(
"update_available",
`Updates are available! v${info.version} is ready to be installed.\n\nFeel free to use the app while the update is being downloaded.`,
);
});
autoUpdater.on("update-downloaded", () => {
win.webContents.send(
"update_downloaded",
"Update has been downloaded! We will launch the next version when you restart the app.",
);
});
}

/**
* Handles account verification links.
*
* @param {BrowserWindow} win
*/
export async function handleExternAuthentication(win: BrowserWindow) {
app.on("second-instance", (event, commandLine, workingDirectory) => {
// Someone tried to run a second instance, we should focus our window.
if (win) {
if (win.isMinimized()) win.restore();
win.focus();
win.reload();
console.log(commandLine);
if (commandLine[3].includes("select-launcher://home")) {
dialog.showMessageBox({
type: "info",
title: "Select Launcher",
message: "Account verification successful!",
});
}
}
});
}
36 changes: 36 additions & 0 deletions client/electron/main/globalSetup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { app } from "electron";
import { release } from "os";
import path, { join } from "path";

/**
* Sets up global variables.
*/
export function globalSetup() {
// Global Variable Setups
process.env.DIST_ELECTRON = join(__dirname, "../..");
process.env.DIST = join(process.env.DIST_ELECTRON, "../dist");
process.env.PUBLIC = app.isPackaged
? process.env.DIST
: join(process.env.DIST_ELECTRON, "../public");

// Disable GPU Acceleration for Windows 7
if (release().startsWith("6.1")) app.disableHardwareAcceleration();
// Set application name for Windows 10+ notifications
if (process.platform === "win32") app.setAppUserModelId(app.getName());

// Make sure only one instance of the app is running
if (!app.requestSingleInstanceLock()) {
app.quit();
process.exit(0);
}

if (process.defaultApp) {
if (process.argv.length >= 2) {
app.setAsDefaultProtocolClient("select-launcher", process.execPath, [
path.resolve(process.argv[1]),
]);
}
} else {
app.setAsDefaultProtocolClient("select-launcher");
}
}
135 changes: 8 additions & 127 deletions client/electron/main/index.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,19 @@
// The built directory structure
//
// ├─┬ dist-electron
// │ ├─┬ main
// │ │ └── index.js > Electron-Main
// │ └─┬ preload
// │ └── index.js > Preload-Scripts
// ├─┬ dist
// │ └── index.html > Electron-Renderer
//

process.env.DIST_ELECTRON = join(__dirname, "../..");
process.env.DIST = join(process.env.DIST_ELECTRON, "../dist");
process.env.PUBLIC = app.isPackaged
? process.env.DIST
: join(process.env.DIST_ELECTRON, "../public");

import { app, BrowserWindow, shell, ipcMain, dialog } from "electron";
import { app, BrowserWindow, shell } from "electron";
import settings from "electron-settings";
import { release, homedir } from "os";
import path, { join } from "path";
import fs from "fs";
import runIpcStorageEvents from "./ipc/ipcStorageEvents";
import runIpcGameEvents from "./ipc/ipcGameEvents";
import { checkIfGamesDirectoryExists } from "../api/gameManager";
import { autoUpdater } from "electron-updater";
// Disable GPU Acceleration for Windows 7
if (release().startsWith("6.1")) app.disableHardwareAcceleration();

// Set application name for Windows 10+ notifications
if (process.platform === "win32") app.setAppUserModelId(app.getName());

if (!app.requestSingleInstanceLock()) {
app.quit();
process.exit(0);
}
import { callHandlers, handleExternAuthentication } from "./eventHandlers";
import { globalSetup } from "./globalSetup";

// global scoped constants
export let win: BrowserWindow | null = null;
// Here, you can also use other preload
const preload = join(__dirname, "../preload/index.js");
const url = process.env.VITE_DEV_SERVER_URL;
const indexHtml = join(process.env.DIST, "index.html");

if (process.defaultApp) {
if (process.argv.length >= 2) {
app.setAsDefaultProtocolClient("select-launcher", process.execPath, [
path.resolve(process.argv[1]),
]);
}
} else {
app.setAsDefaultProtocolClient("select-launcher");
}
globalSetup();

async function createWindow() {
win = new BrowserWindow({
Expand All @@ -66,9 +30,7 @@ async function createWindow() {
});

if (process.env.VITE_DEV_SERVER_URL) {
// electron-vite-vue#298
win.loadURL(url);
// Open devTool if the app is not packaged
win.webContents.openDevTools();
} else {
win.loadFile(indexHtml);
Expand All @@ -78,7 +40,6 @@ async function createWindow() {
win.webContents.on("did-finish-load", () => {
win?.webContents.send("main-process-message", new Date().toLocaleString());
});
win.webContents.setVisualZoomLevelLimits(1, 1);

// Make all links open with the browser, not with the application
win.webContents.setWindowOpenHandler(({ url }) => {
Expand All @@ -87,55 +48,15 @@ async function createWindow() {
});
}

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

const gotTheLock = app.requestSingleInstanceLock();

async function handleFolderOpen() {
const currentLibraryPath = await (
await settings.get("locations.libraryLocation")
).toString();
const { canceled, filePaths } = await dialog.showOpenDialog(win, {
title: "Select Library Location",
defaultPath: currentLibraryPath,
properties: ["openDirectory"],
});
if (canceled) {
return;
} else {
return filePaths[0];
}
}
callHandlers(win, preload, indexHtml);

if (!gotTheLock) {
if (!app.requestSingleInstanceLock()) {
app.quit();
} else {
app.on("second-instance", (event, commandLine, workingDirectory) => {
// Someone tried to run a second instance, we should focus our window.
if (win) {
if (win.isMinimized()) win.restore();
win.focus();
win.reload();
console.log(commandLine);
if (commandLine[3].includes("select-launcher://home")) {
dialog.showMessageBox({
type: "info",
title: "Select Launcher",
message: "Account verification successful!",
});
}
}
});
handleExternAuthentication(win);

// Create mainWindow, load the rest of the app, etc...
app.whenReady().then(async () => {
// if (app.isPackaged) {
// await checkForUpdates();
// }

createWindow();

// create game storage directory
Expand All @@ -147,15 +68,9 @@ if (!gotTheLock) {
return;
}

ipcMain.handle("dialog:openFolder", handleFolderOpen);
runIpcStorageEvents();
runIpcGameEvents();
});

// Handle the protocol. In this case, we choose to show an Error Box.
app.on("open-url", (event, url) => {
dialog.showErrorBox("Welcome Back", `You arrived from: ${url}`);
});
}

app.on("activate", () => {
Expand All @@ -166,37 +81,3 @@ app.on("activate", () => {
createWindow();
}
});

// new window example arg: new windows url
ipcMain.handle("open-win", (event, arg) => {
const childWindow = new BrowserWindow({
webPreferences: {
preload,
nodeIntegration: true,
contextIsolation: false,
},
});

if (process.env.VITE_DEV_SERVER_URL) {
childWindow.loadURL(`${url}#${arg}`);
} else {
childWindow.loadFile(indexHtml, { hash: arg });
}
});

app.on("ready", () => {
autoUpdater.checkForUpdatesAndNotify();
});

autoUpdater.on("update-available", (info) => {
win.webContents.send(
"update_available",
`Updates are available! v${info.version} is ready to be installed.\n\nFeel free to use the app while the update is being downloaded.`,
);
});
autoUpdater.on("update-downloaded", () => {
win.webContents.send(
"update_downloaded",
`Update has been downloaded! We will launch the next version when you restart the app.`,
);
});
2 changes: 1 addition & 1 deletion cspell.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version":"0.2","flagWords":[],"language":"en","words":["nextui"]}
{"flagWords":[],"words":["nextui","linebreak"],"language":"en","version":"0.2"}
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
},
"homepage": "https://github.com/select-studios/Select-Launcher#readme",
"devDependencies": {
"concurrently": "^7.6.0"
},
"dependencies": {
"eslint": "^8.40.0"
"@typescript-eslint/eslint-plugin": "^6.9.0",
"@typescript-eslint/parser": "^6.9.0",
"concurrently": "^7.6.0",
"eslint": "^8.52.0"
}
}

0 comments on commit 5a494ab

Please sign in to comment.