Skip to content

Commit

Permalink
Reduce input during on-boarding (UnchartedBull#954)
Browse files Browse the repository at this point in the history
* - Add mdns and ngx-electron plugin
- Add electron-rebuild to dev depends so that electron can be rebuilt with the installed node
- Fix setTimeout and setInstance to with with Node modules (required for mdns)
- Reduce the version on node as electron needs to be on the same version for this to work
- Change order in on boarding wizard to select API first
- Use mdns to detect and list octoprint instances (WIP need to figure out min version required)
- Auto set Printer name if a detected install if found.

I'm trying to reduce input and the need for a keyboard during onboarding.  Obviously this is just the first step as the API key still needs to be inputed.  But it's still a start.

Follow Issue UnchartedBull#921 for more info on the changes.

* Add postinstall so it auto rebuilds electron against node

* Update src/app/config/no-config/no-config.component.ts

Returns void

Co-authored-by: Timon G. <timon.gaebelein@icloud.com>

* Update src/app/config/no-config/no-config.component.ts

Return Boolean

Co-authored-by: Timon G. <timon.gaebelein@icloud.com>

* Update src/app/config/no-config/no-config.component.ts

Returns void

Co-authored-by: Timon G. <timon.gaebelein@icloud.com>

* Resolve a few issues with VSCode and more consistent var naming

* Add version compare to disable older Nodes

* Switch back to 5000 as the default and add a note about port 80

* test

* Revert "test"

This reverts commit 8564d39.

* Attempt to fix CI

* restructure main.js

* With the new changes newer node is working again

* Use proper indentation

* Forgot to update package-lock with node update

* electron stuff finished

* Fix lint errors and warnings

* finalise workflow

* small bugfix

* prevent the same instance showing multiple times

* remove node from angular app

* Manually trigger change detection

* Also trigger change detection for Page changes to fix bug

* intial setup to load op script

* Fix ngZone issue

* Remove ngx-electron from package-lock

* Remove electron-rebuild, postinstall script and test if the travis changes are still needed since we are no longer rebuilding

* Tested and no longer required, was a rebuild only issue

* fix OctoPrint var

* finally get that freakin jQuery working

not pretty, but it works

* cleanup + reset URL if manual input is opened.

* Check OctoPrint connection and load client library

* Update package-lock, fix a few navigation bugs

* Make sure pages can't go below 0 or above totalPages

* refactor navigation controller + show next button after page 1 again

* login with request working

* use printer name from printerprofile

* fix setup (all working)

* Convert to range slider to numeric input is not required

* I think 150 would be fast enough to load

* value selector for numbers

* fix layout issue

* Fix alignemnt on large and small views

Co-authored-by: Timon G. <timon.gaebelein@icloud.com>
  • Loading branch information
2 people authored and kantlivelong committed May 5, 2021
1 parent e0a891e commit 58ff9d0
Show file tree
Hide file tree
Showing 25 changed files with 1,047 additions and 494 deletions.
8 changes: 7 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module.exports = {
'@typescript-eslint/no-parameter-properties': 'off',
'@typescript-eslint/no-use-before-define': 'off',
'import/no-unresolved': 'off',
camelcase: 'warn',
'camelcase': 'warn',
'simple-import-sort/sort': 'warn',
'sort-imports': 'off',
'import/first': 'warn',
Expand All @@ -42,5 +42,11 @@ module.exports = {
],
},
},
{
files: '**/*.js',
env: {
node: true,
},
},
],
};
41 changes: 14 additions & 27 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": 1,
"newProjectRoot": "projects",
"projects": {
"OctoPrintDash": {
"OctoDash": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
Expand All @@ -18,6 +18,7 @@
"builder": "@angular-devkit/build-angular:browser",
"options": {
"aot": true,
"allowedCommonJsDependencies": ["angular-svg-round-progressbar"],
"outputPath": "dist",
"index": "src/index.html",
"main": "src/main.ts",
Expand All @@ -40,9 +41,7 @@
"output": "/"
}
],
"styles": [
"src/styles.scss"
],
"styles": ["src/styles.scss"],
"scripts": []
},
"configurations": {
Expand Down Expand Up @@ -79,18 +78,18 @@
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "OctoPrintDash:build"
"browserTarget": "OctoDash:build"
},
"configurations": {
"production": {
"browserTarget": "OctoPrintDash:build:production"
"browserTarget": "OctoDash:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "OctoPrintDash:build"
"browserTarget": "OctoDash:build"
}
},
"test": {
Expand All @@ -100,47 +99,35 @@
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"assets": [
"src/favicon.ico",
"src/assets",
"src/assets/icon/icon-main-title.svg"
],
"styles": [
"src/styles.scss"
],
"assets": ["src/favicon.ico", "src/assets", "src/assets/icon/icon-main-title.svg"],
"styles": ["src/styles.scss"],
"scripts": []
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"tsconfig.app.json",
"tsconfig.spec.json",
"tsconfig.json"
],
"exclude": [
"**/node_modules/**"
]
"tsConfig": ["tsconfig.app.json", "tsconfig.spec.json", "tsconfig.json"],
"exclude": ["**/node_modules/**"]
}
},
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "OctoPrintDash:serve"
"devServerTarget": "OctoDash:serve"
},
"configurations": {
"production": {
"devServerTarget": "OctoPrintDash:serve:production"
"devServerTarget": "OctoDash:serve:production"
}
}
}
}
}
},
"defaultProject": "OctoPrintDash",
"defaultProject": "OctoDash",
"cli": {
"analytics": "e1569209-2b82-4195-9c15-0669a78feccb"
}
}
}
41 changes: 41 additions & 0 deletions helper/discover.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* eslint-disable @typescript-eslint/no-var-requires */
/* eslint-disable import/no-commonjs */

const mdns = require('mdns');
const compareVersions = require('compare-versions');

const minimumVersion = '1.3.5';
let mdnsBrowser;
let nodes = [];

function discoverNodes(window) {
nodes = [];
mdnsBrowser = mdns.createBrowser(mdns.tcp('octoprint'));
mdnsBrowser.on('serviceUp', service => {
nodes.push({
id: service.interfaceIndex,
name: service.name,
version: service.txtRecord.version,
url: `http://${service.host.replace(/\.$/, '')}:${service.port}${service.txtRecord.path}api/`,
disable: compareVersions(minimumVersion, service.txtRecord.version) === -1,
});
sendNodes(window);
});

mdnsBrowser.on('serviceDown', service => {
nodes = nodes.filter(node => node.id !== service.interfaceIndex);
sendNodes(window);
});

mdnsBrowser.start();
}

function stopDiscovery() {
mdnsBrowser.stop();
}

function sendNodes(window) {
window.webContents.send('discoveredNodes', nodes);
}

module.exports = { discoverNodes, stopDiscovery };
68 changes: 68 additions & 0 deletions helper/listener.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/* eslint-disable @typescript-eslint/no-var-requires */
/* eslint-disable import/no-commonjs */

const path = require('path');
const url = require('url');

const exec = require('child_process').exec;

const sendCustomStyles = require('./styles');
const { downloadUpdate, sendVersionInfo } = require('./update');
const { discoverNodes, stopDiscovery } = require('./discover');

function activateScreenSleepListener(ipcMain) {
ipcMain.on('screenSleep', () => {
exec('xset dpms force standby');
});

ipcMain.on('screenWakeup', () => {
exec('xset s off');
exec('xset -dpms');
exec('xset s noblank');
});
}

function activateReloadListener(ipcMain, window) {
ipcMain.on('reload', () => {
window.loadURL(
url.format({
pathname: path.join(__dirname, 'dist/index.html'),
protocol: 'file:',
slashes: true,
}),
);
});
}

function activateAppInfoListener(ipcMain, window, app) {
ipcMain.on('appInfo', () => {
sendCustomStyles(window);
sendVersionInfo(window, app);
});
}

function activateUpdateListener(ipcMain, window) {
ipcMain.on('update', (_, updateInfo) => {
downloadUpdate(updateInfo, window);
});
}

function activateDiscoverListener(ipcMain, window) {
ipcMain.on('discover', () => {
discoverNodes(window);
});

ipcMain.on('stopDiscover', () => {
stopDiscovery();
});
}

function activateListeners(ipcMain, window, app) {
activateAppInfoListener(ipcMain, window, app);
activateScreenSleepListener(ipcMain);
activateReloadListener(ipcMain, window);
activateUpdateListener(ipcMain, window);
activateDiscoverListener(ipcMain, window);
}

module.exports = activateListeners;
28 changes: 28 additions & 0 deletions helper/styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* eslint-disable @typescript-eslint/no-var-requires */
/* eslint-disable import/no-commonjs */

const fs = require('fs');
const path = require('path');
const { app } = require('electron');

function sendCustomStyles(window) {
fs.readFile(path.join(app.getPath('userData'), 'custom-styles.css'), 'utf-8', (err, data) => {
if (err) {
if (err.code === 'ENOENT') {
fs.writeFile(path.join(app.getPath('userData'), 'custom-styles.css'), '', err => {
if (err) {
window.webContents.send('customStylesError', err);
} else {
window.webContents.send('customStyles', '');
}
});
} else {
window.webContents.send('customStylesError', err);
}
} else {
window.webContents.send('customStyles', data);
}
});
}

module.exports = sendCustomStyles;
103 changes: 103 additions & 0 deletions helper/update.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/* eslint-disable no-sync */
/* eslint-disable @typescript-eslint/no-var-requires */
/* eslint-disable import/no-commonjs */

const fs = require('fs');
const got = require('got');
const stream = require('stream');
const { promisify } = require('util');
const progress = require('progress-stream');

const exec = require('child_process').exec;

function downloadUpdate(updateInfo, window) {
const downloadPath = '/tmp/octodash.deb';

exec('arch', (err, stdout, stderr) => {
if (err || stderr) {
window.webContents.send('updateError', {
error: err || { message: stderr },
});
}
got(updateInfo.assetsURL)
.then(releaseFiles => {
const reducer = (accumulator, currentValue) => accumulator + currentValue;
const averageETA = [];
let downloadURL;
let packageSize;
for (const package of JSON.parse(releaseFiles.body)) {
if (package.name.includes(stdout.trim())) {
downloadURL = package.browser_download_url;
packageSize = package.size;
}
}
if (downloadURL) {
const downloadPipeline = promisify(stream.pipeline);
const downloadProgress = progress({
length: packageSize,
time: 300,
});

downloadProgress.on('progress', progress => {
averageETA.push(progress.eta);
if (averageETA.length > 4) averageETA.shift();
window.webContents.send('updateDownloadProgress', {
percentage: progress.percentage,
transferred: (progress.transferred / 100000).toFixed(1),
total: (progress.length / 1000000).toFixed(1),
remaining: (progress.remaining / 100000).toFixed(1),
eta: new Date(averageETA.reduce(reducer) * 1000).toISOString().substr(14, 5),
runtime: new Date(progress.runtime * 1000).toISOString().substr(14, 5),
delta: (progress.delta / 100000).toFixed(1),
speed: (progress.speed / 1000000).toFixed(2),
});
});

try {
if (fs.existsSync(downloadPath)) fs.unlinkSync(downloadPath);
} catch {
// no need to handle this properly
}

downloadPipeline(got.stream(downloadURL), downloadProgress, fs.createWriteStream(downloadPath))
.catch(error => {
window.webContents.send('updateError', {
error: {
message: `Can't download package! ${error.message}.`,
},
});
})
.then(() => {
window.webContents.send('updateDownloadFinished');
exec('sudo ~/scripts/update-octodash', (err, _, stderr) => {
if (err || stderr) {
window.webContents.send('updateError', {
error: err || { message: stderr },
});
} else {
window.webContents.send('updateInstalled');
}
});
});
} else {
window.webContents.send('updateError', {
error: {
message: `Can't find matching package for architecture ${stdout}.`,
},
});
}
})
.catch(error => {
error.message = `Can't load releases. ${error.message}`;
window.webContents.send('updateError', { error });
});
});
}

function sendVersionInfo(window, app) {
window.webContents.send('versionInformation', {
version: app.getVersion(),
});
}

module.exports = { downloadUpdate, sendVersionInfo };
Loading

0 comments on commit 58ff9d0

Please sign in to comment.