Native desktop app with NodeJS / Electron without having to think about how to solve browser issues
-
@thomaseinasto said in Native desktop app with NodeJS / Electron without having to think about how to solve browser issues:
This is awesome, ill give it a try. Not sure if you saw on the latest UI release that service workers are part of the package. So you can install a chrome app of the mango instance.
-
Oh awsome. But if I am not mistaken chrome app requires the user to install chrome on the PC. Electron solves this by wrapping the Chrome engine to its application without user realizing that they are actually using chrome browser.
We have had some clients who have company policy not to use google chrome or any browser in the manufacturing computers which created trouble for us to talk them into creating an exception for us.
-
Yes correct it does require chrome to be installed but it's still quite cool and handy for the clients who demand an app. Ive had my fair share from corporate ITC policies its a nightmare.
-
Yep as @CraigWeb said we have been expending a bit of effort recently turning Mango into a PWA (Progressive Web App). We have implemented a service worker which pre-caches all the assets for fast startup time. The next UI module release will let you customize the application name and colors via the UI settings page.
Next things on our plate for the PWA are:
- A startup progress screen in the new UI
- Better offline behavior (currently it just displays a pretty awful looking error message)
- Push notifications for events (This might be a few releases away, its not as easy as it sounds)
I gave nativefier a go and it seems to work pretty flawlessly with Mango. Thanks for the heads up, its nice thing to know about. I'll have to do a bit more reading about it but since it is a wrapper around the web app I would assume you can just create the app once and the web app will update itself via the service worker. Very nice.
We probably wont distribute any native apps like this but it is a very useful tool for people in your scenario.
-
Here's a screenshot showing the command to build the app, the output, and the running app for those interested -
-
Is it possible to add custom buttons to <md-toolbar> of the UI simply without doing changes in overrides? I would like to add a userModule component which brings window actions to the toolbar ( minimise, maximise, close)
Adding custom css so that the toolbar would be draggable can be done in UI settings via custom css and it works perfectly with electron.
Idea is something like this, so that user would not see the header of the application but everything is styled in css:
Thanks
Thomas -
You can in fact add a button to the toolbar, this is a user module that I use while developing that adds a button to clear the translations cache in the backend.
define(['angular', 'require'], function(angular, require) { 'use strict'; const userModule = angular.module('userModule', ['maUiApp']); run.$inject = ['$rootScope', 'maTranslate', '$templateCache']; function run($rootScope, Translate, $templateCache) { const userActionsUrl = 'userActions.html'; $templateCache.put(userActionsUrl, `<md-button class="md-icon-button" ng-click="clearTranslations()"> <md-icon>restore_page</md-icon> </md-button>`); $rootScope.userActions = userActionsUrl; $rootScope.clearTranslations = () => { Translate.clearCache().then(() => { window.location.reload(); }); }; } userModule.run(run); return userModule; }); // define
-
Thanks @Jared-Wiltshire
App works perfectly with buttons so that Mango is looking like a real app with buttons. Is it possible to inject them behind help button so that it would look better?
Anyone who is interested:
Solved this by first creating preloader.js file in the folder where app will be created with following code. There are several options I guess but this was just one of the easiest to accomplish:
function sd() { const remote = require('electron').remote; var currentwindow = remote.getCurrentWindow(); var logFn = console.log; console.log = function(arg1) { if (arg1 == 'close-electron'){ let windows = remote.getCurrentWindow(); windows.close(); }else if (arg1 == 'maximize-electron'){ if(currentwindow.isMaximized()){ let windows = remote.getCurrentWindow(); windows.unmaximize(); }else{ let windows = remote.getCurrentWindow(); windows.maximize(); } }else if (arg1 == 'minimize-electron'){ let windows = remote.getCurrentWindow(); windows.minimize(); }else{ logFn(arg1) } } } sd();
Following code actually rewrites console.log function to a custom function in a global scope within the application.
Then add usermodule by modifying @Jared-Wiltshire usermodule like this:
define(['angular', 'require'], function(angular, require) { 'use strict'; var electron = false; const userModule = angular.module('userModule', ['maUiApp','ngLocale']); var userAgent = navigator.userAgent.toLowerCase(); console.log(userAgent) if (userAgent == 'electron') { electron = true }else{ electron = false; } if (electron){ run.$inject = ['$rootScope', 'maTranslate', '$templateCache']; function run($rootScope, Translate, $templateCache) { const userActionsUrl = 'userActions.html'; $templateCache.put(userActionsUrl, ` <md-button class="md-icon-button" ng-click="minimize()"> <md-icon>more_horiz</md-icon> </md-button> <md-button class="md-icon-button" ng-click="maximize()"> <md-icon>fullscreen</md-icon> </md-button> <md-button class="md-icon-button" ng-click="close()"> <md-icon>close</md-icon> </md-button>`); $rootScope.userActions = userActionsUrl; $rootScope.close = () => { console.log('close-electron'); }; $rootScope.maximize = () => { console.log('maximize-electron'); }; $rootScope.minimize = () => { console.log('minimize-electron'); }; } userModule.run(run); } return userModule; }); // define
This module actually console.logs commands which are analyzed in a function located in preloader.js file and only activates when userAgent is called 'electron' which we will define in a final function below.
Add also your custom css in mango UI settings to make header draggable.
.ma-ui-main-toolbar{ -webkit-app-region: drag; } button { -webkit-app-region: no-drag; } md-input-container{ -webkit-app-region: no-drag; } .ma-ui-tools > div[ng-include=userActions] { order: 1; }
Finally, ensure that you are using nativefier version 7.6.10 so that injection actually would work correctly. Check your version with nativefier -v, should output as
7.6.10
If not then following command will allow you to install correct version from npm.
npm install -g nativefier@7.6.10
Now create app with following command:
nativefier -u electron -e 2.0.8 http://url-to-mangoinstance --browserwindow-options "{ \"webPreferences\": { \"nodeIntegration\":true } }" --inject preloader.js --hide-window-frame
-u specifies your useragent which is electron,
-e specifies electron version (use 2.0.8 so that --inject would be successful.
your link to the mango instance
--browserwindows-options JSON string for specifing electron browser options. see https://electronjs.org/docs/api/browser-window#new-browserwindowoptions
(we are using nodeIntegration to enable electron in front-end)
--inject The file to inject to the page after DOM has loaded.
--hide-window-frame Hide windows framing because we will be using mango header which css we have enabled in UI settings.You have now created the application for your Mango instance.
-
@thomaseinasto said in Native desktop app with NodeJS / Electron without having to think about how to solve browser issues:
Is it possible to inject them behind help button so that it would look better?
It's not possible to change the position in the markup no. But you can change the order in which they are displayed using CSS.
.ma-ui-tools > div[ng-include=userActions] { order: 1; }
-
Thanks @Jared-Wiltshire for helping out.
This solved it, I edited the previous post for css also, so that users would be able to copy-paste without missing out the ordering.
Final result :
Thomas