Include electron build dir

This commit is contained in:
WardPearce
2024-09-01 14:08:21 +12:00
parent e4743faf5f
commit c00dc4a884
8 changed files with 351 additions and 1 deletions
-1
View File
@@ -3,6 +3,5 @@
# And the CLI then renames it
app
node_modules
build
dist
logs
@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const config = {
appId: 'us.materialio.app',
appName: 'Materialious',
webDir: 'build',
bundledWebRuntime: false,
plugins: {
CapacitorHttp: {
enabled: true
}
},
};
exports.default = config;
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

+61
View File
@@ -0,0 +1,61 @@
"use strict";
var _a, _b;
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const electron_1 = require("@capacitor-community/electron");
const electron_2 = require("electron");
const electron_is_dev_1 = tslib_1.__importDefault(require("electron-is-dev"));
const electron_unhandled_1 = tslib_1.__importDefault(require("electron-unhandled"));
const electron_updater_1 = require("electron-updater");
const setup_1 = require("./setup");
// Graceful handling of unhandled errors.
(0, electron_unhandled_1.default)();
// Define our menu templates (these are optional)
const trayMenuTemplate = [new electron_2.MenuItem({ label: 'Quit App', role: 'quit' })];
const appMenuBarMenuTemplate = [
{ role: process.platform === 'darwin' ? 'appMenu' : 'fileMenu' },
{ role: 'viewMenu' },
];
// Get Config options from capacitor.config
const capacitorFileConfig = (0, electron_1.getCapacitorElectronConfig)();
// Initialize our app. You can pass menu templates into the app here.
// const myCapacitorApp = new ElectronCapacitorApp(capacitorFileConfig);
const myCapacitorApp = new setup_1.ElectronCapacitorApp(capacitorFileConfig, trayMenuTemplate, appMenuBarMenuTemplate);
// If deeplinking is enabled then we will set it up here.
if ((_a = capacitorFileConfig.electron) === null || _a === void 0 ? void 0 : _a.deepLinkingEnabled) {
(0, electron_1.setupElectronDeepLinking)(myCapacitorApp, {
customProtocol: (_b = capacitorFileConfig.electron.deepLinkingCustomProtocol) !== null && _b !== void 0 ? _b : 'mycapacitorapp',
});
}
// If we are in Dev mode, use the file watcher components.
if (electron_is_dev_1.default) {
(0, setup_1.setupReloadWatcher)(myCapacitorApp);
}
// Run Application
(async () => {
// Wait for electron app to be ready.
await electron_2.app.whenReady();
// Security - Set Content-Security-Policy based on whether or not we are in dev mode.
(0, setup_1.setupContentSecurityPolicy)(myCapacitorApp.getCustomURLScheme());
// Initialize our app, build windows, and load content.
await myCapacitorApp.init();
// Check for updates if we are in a packaged app.
electron_updater_1.autoUpdater.checkForUpdatesAndNotify();
})();
// Handle when all of our windows are close (platforms have their own expectations).
electron_2.app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
electron_2.app.quit();
}
});
// When the dock icon is clicked.
electron_2.app.on('activate', async function () {
// 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 (myCapacitorApp.getMainWindow().isDestroyed()) {
await myCapacitorApp.init();
}
});
// Place all ipc or other electron api calls and custom functionality under this line
@@ -0,0 +1,4 @@
require('./rt/electron-rt');
//////////////////////////////
// User Defined Preload scripts below
console.log('User Preload!');
@@ -0,0 +1,2 @@
/* eslint-disable @typescript-eslint/no-var-requires */
module.exports = {};
@@ -0,0 +1,68 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const crypto_1 = require("crypto");
const electron_1 = require("electron");
const events_1 = require("events");
////////////////////////////////////////////////////////
// eslint-disable-next-line @typescript-eslint/no-var-requires
const plugins = require('./electron-plugins');
const randomId = (length = 5) => (0, crypto_1.randomBytes)(length).toString('hex');
const contextApi = {};
Object.keys(plugins).forEach((pluginKey) => {
Object.keys(plugins[pluginKey])
.filter((className) => className !== 'default')
.forEach((classKey) => {
const functionList = Object.getOwnPropertyNames(plugins[pluginKey][classKey].prototype).filter((v) => v !== 'constructor');
if (!contextApi[classKey]) {
contextApi[classKey] = {};
}
functionList.forEach((functionName) => {
if (!contextApi[classKey][functionName]) {
contextApi[classKey][functionName] = (...args) => electron_1.ipcRenderer.invoke(`${classKey}-${functionName}`, ...args);
}
});
// Events
if (plugins[pluginKey][classKey].prototype instanceof events_1.EventEmitter) {
const listeners = {};
const listenersOfTypeExist = (type) => !!Object.values(listeners).find((listenerObj) => listenerObj.type === type);
Object.assign(contextApi[classKey], {
addListener(type, callback) {
const id = randomId();
// Deduplicate events
if (!listenersOfTypeExist(type)) {
electron_1.ipcRenderer.send(`event-add-${classKey}`, type);
}
const eventHandler = (_, ...args) => callback(...args);
electron_1.ipcRenderer.addListener(`event-${classKey}-${type}`, eventHandler);
listeners[id] = { type, listener: eventHandler };
return id;
},
removeListener(id) {
if (!listeners[id]) {
throw new Error('Invalid id');
}
const { type, listener } = listeners[id];
electron_1.ipcRenderer.removeListener(`event-${classKey}-${type}`, listener);
delete listeners[id];
if (!listenersOfTypeExist(type)) {
electron_1.ipcRenderer.send(`event-remove-${classKey}-${type}`);
}
},
removeAllListeners(type) {
Object.entries(listeners).forEach(([id, listenerObj]) => {
if (!type || listenerObj.type === type) {
electron_1.ipcRenderer.removeListener(`event-${classKey}-${listenerObj.type}`, listenerObj.listener);
electron_1.ipcRenderer.send(`event-remove-${classKey}-${listenerObj.type}`);
delete listeners[id];
}
});
},
});
}
});
});
electron_1.contextBridge.exposeInMainWorld('CapacitorCustomPlatform', {
name: 'electron',
plugins: contextApi,
});
////////////////////////////////////////////////////////
+202
View File
@@ -0,0 +1,202 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ElectronCapacitorApp = void 0;
exports.setupReloadWatcher = setupReloadWatcher;
exports.setupContentSecurityPolicy = setupContentSecurityPolicy;
const tslib_1 = require("tslib");
const electron_1 = require("@capacitor-community/electron");
const chokidar_1 = tslib_1.__importDefault(require("chokidar"));
const electron_2 = require("electron");
const electron_is_dev_1 = tslib_1.__importDefault(require("electron-is-dev"));
const electron_serve_1 = tslib_1.__importDefault(require("electron-serve"));
const electron_window_state_1 = tslib_1.__importDefault(require("electron-window-state"));
const path_1 = require("path");
// Define components for a watcher to detect when the webapp is changed so we can reload in Dev mode.
const reloadWatcher = {
debouncer: null,
ready: false,
watcher: null,
};
function setupReloadWatcher(electronCapacitorApp) {
reloadWatcher.watcher = chokidar_1.default
.watch((0, path_1.join)(electron_2.app.getAppPath(), 'app'), {
ignored: /[/\\]\./,
persistent: true,
})
.on('ready', () => {
reloadWatcher.ready = true;
})
.on('all', (_event, _path) => {
if (reloadWatcher.ready) {
clearTimeout(reloadWatcher.debouncer);
reloadWatcher.debouncer = setTimeout(async () => {
electronCapacitorApp.getMainWindow().webContents.reload();
reloadWatcher.ready = false;
clearTimeout(reloadWatcher.debouncer);
reloadWatcher.debouncer = null;
reloadWatcher.watcher = null;
setupReloadWatcher(electronCapacitorApp);
}, 1500);
}
});
}
// Define our class to manage our app.
class ElectronCapacitorApp {
constructor(capacitorFileConfig, trayMenuTemplate, appMenuBarMenuTemplate) {
var _a, _b;
this.MainWindow = null;
this.SplashScreen = null;
this.TrayIcon = null;
this.TrayMenuTemplate = [
new electron_2.MenuItem({ label: 'Quit App', role: 'quit' }),
];
this.AppMenuBarMenuTemplate = [
{ role: process.platform === 'darwin' ? 'appMenu' : 'fileMenu' },
{ role: 'viewMenu' },
];
this.CapacitorFileConfig = capacitorFileConfig;
this.customScheme = (_b = (_a = this.CapacitorFileConfig.electron) === null || _a === void 0 ? void 0 : _a.customUrlScheme) !== null && _b !== void 0 ? _b : 'capacitor-electron';
if (trayMenuTemplate) {
this.TrayMenuTemplate = trayMenuTemplate;
}
if (appMenuBarMenuTemplate) {
this.AppMenuBarMenuTemplate = appMenuBarMenuTemplate;
}
// Setup our web app loader, this lets us load apps like react, vue, and angular without changing their build chains.
this.loadWebApp = (0, electron_serve_1.default)({
directory: (0, path_1.join)(electron_2.app.getAppPath(), 'app'),
scheme: this.customScheme,
});
}
// Helper function to load in the app.
async loadMainWindow(thisRef) {
await thisRef.loadWebApp(thisRef.MainWindow);
}
// Expose the mainWindow ref for use outside of the class.
getMainWindow() {
return this.MainWindow;
}
getCustomURLScheme() {
return this.customScheme;
}
async init() {
var _a, _b, _c, _d;
const icon = electron_2.nativeImage.createFromPath((0, path_1.join)(electron_2.app.getAppPath(), 'assets', process.platform === 'win32' ? 'appIcon.ico' : 'appIcon.png'));
this.mainWindowState = (0, electron_window_state_1.default)({
defaultWidth: 1000,
defaultHeight: 800,
});
// Setup preload script path and construct our main window.
const preloadPath = (0, path_1.join)(electron_2.app.getAppPath(), 'build', 'src', 'preload.js');
this.MainWindow = new electron_2.BrowserWindow({
icon,
show: false,
x: this.mainWindowState.x,
y: this.mainWindowState.y,
width: this.mainWindowState.width,
height: this.mainWindowState.height,
webPreferences: {
nodeIntegration: true,
contextIsolation: true,
webSecurity: false,
// Use preload to inject the electron varriant overrides for capacitor plugins.
// preload: join(app.getAppPath(), "node_modules", "@capacitor-community", "electron", "dist", "runtime", "electron-rt.js"),
preload: preloadPath,
},
});
this.mainWindowState.manage(this.MainWindow);
if (this.CapacitorFileConfig.backgroundColor) {
this.MainWindow.setBackgroundColor(this.CapacitorFileConfig.electron.backgroundColor);
}
// If we close the main window with the splashscreen enabled we need to destory the ref.
this.MainWindow.on('closed', () => {
var _a;
if (((_a = this.SplashScreen) === null || _a === void 0 ? void 0 : _a.getSplashWindow()) && !this.SplashScreen.getSplashWindow().isDestroyed()) {
this.SplashScreen.getSplashWindow().close();
}
});
// When the tray icon is enabled, setup the options.
if ((_a = this.CapacitorFileConfig.electron) === null || _a === void 0 ? void 0 : _a.trayIconAndMenuEnabled) {
this.TrayIcon = new electron_2.Tray(icon);
this.TrayIcon.on('double-click', () => {
if (this.MainWindow) {
if (this.MainWindow.isVisible()) {
this.MainWindow.hide();
}
else {
this.MainWindow.show();
this.MainWindow.focus();
}
}
});
this.TrayIcon.on('click', () => {
if (this.MainWindow) {
if (this.MainWindow.isVisible()) {
this.MainWindow.hide();
}
else {
this.MainWindow.show();
this.MainWindow.focus();
}
}
});
this.TrayIcon.setToolTip(electron_2.app.getName());
this.TrayIcon.setContextMenu(electron_2.Menu.buildFromTemplate(this.TrayMenuTemplate));
}
// Setup the main manu bar at the top of our window.
electron_2.Menu.setApplicationMenu(electron_2.Menu.buildFromTemplate(this.AppMenuBarMenuTemplate));
// If the splashscreen is enabled, show it first while the main window loads then switch it out for the main window, or just load the main window from the start.
if ((_b = this.CapacitorFileConfig.electron) === null || _b === void 0 ? void 0 : _b.splashScreenEnabled) {
this.SplashScreen = new electron_1.CapacitorSplashScreen({
imageFilePath: (0, path_1.join)(electron_2.app.getAppPath(), 'assets', (_d = (_c = this.CapacitorFileConfig.electron) === null || _c === void 0 ? void 0 : _c.splashScreenImageName) !== null && _d !== void 0 ? _d : 'splash.png'),
windowWidth: 400,
windowHeight: 400,
});
this.SplashScreen.init(this.loadMainWindow, this);
}
else {
this.loadMainWindow(this);
}
// Security
this.MainWindow.webContents.setWindowOpenHandler((details) => {
if (!details.url.includes(this.customScheme)) {
return { action: 'deny' };
}
else {
return { action: 'allow' };
}
});
this.MainWindow.webContents.on('will-navigate', (event, _newURL) => {
if (!this.MainWindow.webContents.getURL().includes(this.customScheme)) {
event.preventDefault();
}
});
// Link electron plugins into the system.
(0, electron_1.setupCapacitorElectronPlugins)();
// When the web app is loaded we hide the splashscreen if needed and show the mainwindow.
this.MainWindow.webContents.on('dom-ready', () => {
var _a, _b;
if ((_a = this.CapacitorFileConfig.electron) === null || _a === void 0 ? void 0 : _a.splashScreenEnabled) {
this.SplashScreen.getSplashWindow().hide();
}
if (!((_b = this.CapacitorFileConfig.electron) === null || _b === void 0 ? void 0 : _b.hideMainWindowOnLaunch)) {
this.MainWindow.show();
}
setTimeout(() => {
if (electron_is_dev_1.default) {
this.MainWindow.webContents.openDevTools();
}
electron_1.CapElectronEventEmitter.emit('CAPELECTRON_DeeplinkListenerInitialized', '');
}, 400);
});
}
}
exports.ElectronCapacitorApp = ElectronCapacitorApp;
// Set a CSP up for our application based on the custom scheme
function setupContentSecurityPolicy(customScheme) {
electron_2.session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
callback({
responseHeaders: Object.assign({}, details.responseHeaders),
});
});
}