MOBILE-2478 electron: Configure project to use Electron
parent
c6eb8c24af
commit
6af98854fa
|
@ -37,5 +37,6 @@ UserInterfaceState.xcuserstate
|
|||
e2e/build
|
||||
/desktop/*
|
||||
!/desktop/assets/
|
||||
!/desktop/electron.js
|
||||
src/configconstants.ts
|
||||
src/assets/lang
|
||||
|
|
|
@ -14,7 +14,18 @@ const customConfig = {
|
|||
'@directives': resolve('./src/directives'),
|
||||
'@pipes': resolve('./src/pipes')
|
||||
}
|
||||
},
|
||||
externals: [
|
||||
(function () {
|
||||
var IGNORES = ["fs","child_process","electron","path","assert","cluster","crypto","dns","domain","events","http","https","net","os","process","punycode","querystring","readline","repl","stream","string_decoder","tls","tty","dgram","url","util","v8","vm","zlib"];
|
||||
return function (context, request, callback) {
|
||||
if (IGNORES.indexOf(request) >= 0) {
|
||||
return callback(null, "require('" + request + "')");
|
||||
}
|
||||
return callback();
|
||||
};
|
||||
})()
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
|
|
|
@ -0,0 +1,240 @@
|
|||
|
||||
// dialog isn't used, but not requiring it throws an error.
|
||||
const {app, BrowserWindow, ipcMain, shell, dialog, Menu} = require('electron');
|
||||
const path = require('path');
|
||||
const url = require('url');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow,
|
||||
appName = 'Moodle Desktop', // Default value.
|
||||
isReady = false,
|
||||
configRead = false;
|
||||
|
||||
function createWindow() {
|
||||
// Create the browser window.
|
||||
var width = 800,
|
||||
height = 600;
|
||||
|
||||
const screen = require('electron').screen;
|
||||
if (screen) {
|
||||
const display = screen.getPrimaryDisplay();
|
||||
if (display && display.workArea) {
|
||||
width = display.workArea.width || width;
|
||||
height = display.workArea.height || height;
|
||||
}
|
||||
}
|
||||
|
||||
mainWindow = new BrowserWindow({
|
||||
width: width,
|
||||
height: height,
|
||||
minWidth: 400,
|
||||
minHeight: 400,
|
||||
textAreasAreResizable: false,
|
||||
plugins: true,
|
||||
show: false // Don't show it until it's ready to prevent showing a blank screen.
|
||||
});
|
||||
|
||||
// And load the index.html of the app.
|
||||
mainWindow.loadURL(url.format({
|
||||
pathname: path.join(__dirname, '/../www/index.html'),
|
||||
protocol: 'file:',
|
||||
slashes: true
|
||||
}));
|
||||
|
||||
mainWindow.once('ready-to-show', () => {
|
||||
mainWindow.show();
|
||||
mainWindow.maximize();
|
||||
});
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', () => {
|
||||
// Dereference the window object.
|
||||
mainWindow = null
|
||||
});
|
||||
|
||||
mainWindow.on('focus', () => {
|
||||
mainWindow.webContents.send('coreAppFocused'); // Send an event to the main window.
|
||||
});
|
||||
}
|
||||
|
||||
// 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', function() {
|
||||
isReady = true;
|
||||
|
||||
createWindow();
|
||||
|
||||
if (configRead) {
|
||||
setAppMenu();
|
||||
}
|
||||
});
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', () => {
|
||||
app.exit();
|
||||
});
|
||||
|
||||
app.on('activate', () => {
|
||||
// On macOS 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 (mainWindow === null) {
|
||||
createWindow();
|
||||
}
|
||||
});
|
||||
|
||||
// Read the config.json file.
|
||||
fs.readFile(path.join(__dirname, 'config.json'), 'utf8', (err, data) => {
|
||||
configRead = true;
|
||||
|
||||
var ssoScheme = 'moodlemobile'; // Default value.
|
||||
|
||||
if (!err) {
|
||||
try {
|
||||
data = JSON.parse(data);
|
||||
ssoScheme = data.customurlscheme;
|
||||
appName = data.desktopappname;
|
||||
} catch(ex) {}
|
||||
}
|
||||
|
||||
// Set default protocol (custom URL scheme).
|
||||
app.setAsDefaultProtocolClient(ssoScheme);
|
||||
|
||||
if (isReady) {
|
||||
setAppMenu();
|
||||
}
|
||||
});
|
||||
|
||||
// Make sure that only a single instance of the app is running.
|
||||
var shouldQuit = app.makeSingleInstance((argv, workingDirectory) => {
|
||||
// Another instance was launched. If it was launched with a URL, it should be in the second param.
|
||||
if (argv && argv[1]) {
|
||||
appLaunched(argv[1]);
|
||||
} else {
|
||||
focusApp();
|
||||
}
|
||||
});
|
||||
|
||||
// For some reason, shouldQuit is always true in signed Mac apps so we should ingore it.
|
||||
if (shouldQuit && os.platform().indexOf('darwin') == -1) {
|
||||
// It's not the main instance of the app, kill it.
|
||||
app.exit();
|
||||
return;
|
||||
}
|
||||
|
||||
// Listen for open-url events (Mac OS only).
|
||||
app.on('open-url', (event, url) => {
|
||||
event.preventDefault();
|
||||
appLaunched(url);
|
||||
});
|
||||
|
||||
function appLaunched(url) {
|
||||
// App was launched again with a URL. Focus the main window and send an event to treat the URL.
|
||||
if (mainWindow) {
|
||||
focusApp();
|
||||
mainWindow.webContents.send('coreAppLaunched', url); // Send an event to the main window.
|
||||
}
|
||||
}
|
||||
|
||||
function focusApp() {
|
||||
if (mainWindow) {
|
||||
if (mainWindow.isMinimized()) {
|
||||
mainWindow.restore();
|
||||
}
|
||||
mainWindow.focus();
|
||||
}
|
||||
}
|
||||
|
||||
// Listen for events sent by the renderer processes (windows).
|
||||
ipcMain.on('openItem', (event, path) => {
|
||||
var result;
|
||||
|
||||
// Add file:// protocol if it isn't there.
|
||||
if (path.indexOf('file://') == -1) {
|
||||
path = 'file://' + path;
|
||||
}
|
||||
|
||||
if (os.platform().indexOf('darwin') > -1) {
|
||||
// Use openExternal in MacOS because openItem doesn't work in sandboxed apps.
|
||||
// https://github.com/electron/electron/issues/9005
|
||||
result = shell.openExternal(path);
|
||||
} else {
|
||||
result = shell.openItem(path);
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
// Cannot open file, probably no app to handle it. Open the folder.
|
||||
result = shell.showItemInFolder(path.replace('file://', ''));
|
||||
}
|
||||
|
||||
event.returnValue = result;
|
||||
});
|
||||
|
||||
ipcMain.on('closeSecondaryWindows', () => {
|
||||
var windows = BrowserWindow.getAllWindows();
|
||||
for (var i = 0; i < windows.length; i++) {
|
||||
if (!mainWindow || windows[i].id != mainWindow.id) {
|
||||
windows[i].close();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.on('focusApp', focusApp);
|
||||
|
||||
// Configure the app's menu.
|
||||
function setAppMenu() {
|
||||
let menuTemplate = [
|
||||
{
|
||||
label: appName,
|
||||
role: 'window',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Quit',
|
||||
accelerator: 'CmdorCtrl+Q',
|
||||
role: 'close'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Edit',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Cut',
|
||||
accelerator: 'CmdOrCtrl+X',
|
||||
role: 'cut'
|
||||
},
|
||||
{
|
||||
label: 'Copy',
|
||||
accelerator: 'CmdOrCtrl+C',
|
||||
role: 'copy'
|
||||
},
|
||||
{
|
||||
label: 'Paste',
|
||||
accelerator: 'CmdOrCtrl+V',
|
||||
role: 'paste'
|
||||
},
|
||||
{
|
||||
label: 'Select All',
|
||||
accelerator: 'CmdOrCtrl+A',
|
||||
role: 'selectall'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
role: 'help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Docs',
|
||||
accelerator: 'CmdOrCtrl+H',
|
||||
click() {
|
||||
shell.openExternal('https://docs.moodle.org/en/Moodle_Mobile');
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
Menu.setApplicationMenu(Menu.buildFromTemplate(menuTemplate));
|
||||
}
|
File diff suppressed because it is too large
Load Diff
64
package.json
64
package.json
|
@ -32,7 +32,10 @@
|
|||
"ionic:build:before": "gulp",
|
||||
"ionic:watch:before": "gulp",
|
||||
"ionic:build:after": "gulp copy-component-templates",
|
||||
"postionic:build": "gulp copy-component-templates"
|
||||
"postionic:build": "gulp copy-component-templates",
|
||||
"desktop.pack": "electron-builder --dir",
|
||||
"desktop.dist": "electron-builder",
|
||||
"windows.store": "electron-windows-store --input-directory .\\desktop\\dist\\win-unpacked --output-directory .\\desktop\\store --flatten true -a .\\resources\\desktop -m .\\desktop\\assets\\windows\\AppXManifest.xml --package-version 0.0.0.0 --package-name MoodleDesktop"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/animations": "5.2.10",
|
||||
|
@ -95,7 +98,12 @@
|
|||
"gulp-slash": "^1.1.3",
|
||||
"through": "^2.3.8",
|
||||
"typescript": "~2.6.2",
|
||||
"webpack-merge": "^4.1.2"
|
||||
"webpack-merge": "^4.1.2",
|
||||
"electron-rebuild": "^1.8.1"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"electron-windows-notifications": "^2.1.1",
|
||||
"electron-builder-squirrel-windows": "^20.19.0"
|
||||
},
|
||||
"browser": {
|
||||
"electron": false
|
||||
|
@ -105,5 +113,57 @@
|
|||
"android",
|
||||
"ios"
|
||||
]
|
||||
},
|
||||
"main": "desktop/electron.js",
|
||||
"build": {
|
||||
"appId": "com.moodle.moodledesktop",
|
||||
"productName": "Moodle Desktop",
|
||||
"files": [
|
||||
"desktop/electron.js",
|
||||
"www/**/*",
|
||||
"!config",
|
||||
"!desktop/assets",
|
||||
"!desktop/dist",
|
||||
"!node_modules",
|
||||
"!**/e2e",
|
||||
"!hooks",
|
||||
"!platforms",
|
||||
"!plugins",
|
||||
"!resources",
|
||||
"!src",
|
||||
"!**/*.scss"
|
||||
],
|
||||
"directories": {
|
||||
"output": "desktop/dist"
|
||||
},
|
||||
"protocols": [
|
||||
{
|
||||
"name": "Moodle Mobile URL",
|
||||
"schemes": [
|
||||
"moodlemobile"
|
||||
],
|
||||
"role": "Viewer"
|
||||
}
|
||||
],
|
||||
"compression": "maximum",
|
||||
"electronVersion": "2.0.4",
|
||||
"mac": {
|
||||
"category": "public.app-category.education",
|
||||
"icon": "resources/desktop/icon.icns",
|
||||
"target": "mas",
|
||||
"extendInfo": {
|
||||
"ElectronTeamID": "2NU57U5PAW"
|
||||
}
|
||||
},
|
||||
"win": {
|
||||
"target": "appx",
|
||||
"icon": "resources/desktop/icon.ico"
|
||||
},
|
||||
"linux": {
|
||||
"category": "Education"
|
||||
},
|
||||
"snap": {
|
||||
"confinement": "classic"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -214,11 +214,16 @@ export class CoreEmulatorModule {
|
|||
|
||||
// Emulate Custom URL Scheme plugin in desktop apps.
|
||||
if (appProvider.isDesktop()) {
|
||||
require('electron').ipcRenderer.on('mmAppLaunched', (event, url) => {
|
||||
require('electron').ipcRenderer.on('coreAppLaunched', (event, url) => {
|
||||
if (typeof win.handleOpenURL != 'undefined') {
|
||||
win.handleOpenURL(url);
|
||||
}
|
||||
});
|
||||
|
||||
// Listen for 'resume' events.
|
||||
require('electron').ipcRenderer.on('coreAppFocused', function() {
|
||||
document.dispatchEvent(new Event('resume'));
|
||||
});
|
||||
}
|
||||
|
||||
if (!appProvider.isMobile()) {
|
||||
|
|
Loading…
Reference in New Issue