From e64277e43832f0c51e84a54b9e40422a68fa1a78 Mon Sep 17 00:00:00 2001 From: mattmcw Date: Sat, 25 Feb 2023 02:08:56 -0500 Subject: [PATCH] More work on #20. Fix typos in display code. Should re-work script into transpiled ts file. --- app/lib/delay/index.d.ts | 8 -- app/lib/server/index.js | 58 +++++++++- app/lib/server/index.js.map | 2 +- app/package-lock.json | 2 +- app/package.json | 2 +- app/server.html | 31 +++++- app/src/lib/client/index.ts | 213 +++++++++++++++++++++++++++++++++++- data/cfg.json | 2 +- package-lock.json | 4 +- package.json | 2 +- processing/mcopy/cfg.json | 2 +- src/server/index.ts | 76 +++++++++++-- 12 files changed, 372 insertions(+), 30 deletions(-) diff --git a/app/lib/delay/index.d.ts b/app/lib/delay/index.d.ts index 62d586e..e69de29 100644 --- a/app/lib/delay/index.d.ts +++ b/app/lib/delay/index.d.ts @@ -1,8 +0,0 @@ -/** - * Delay in an async/await function - * - * @param {integer} ms Milliseconds to delay for - * - * @returns {Promise} Promise to resolve after timeout - **/ -declare function delay(ms: number): Promise; diff --git a/app/lib/server/index.js b/app/lib/server/index.js index 4c38267..eeeea01 100644 --- a/app/lib/server/index.js +++ b/app/lib/server/index.js @@ -3,8 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); +const ws_1 = require("ws"); const express_1 = __importDefault(require("express")); const promises_1 = require("fs/promises"); +const mime_1 = __importDefault(require("mime")); const Log = require("log"); class Server { constructor() { @@ -22,6 +24,7 @@ class Server { ]; this.port = 9900; this.wsPort = 9901; + this.proxy = {}; this.init(); } async init() { @@ -36,6 +39,7 @@ class Server { } this.http.get('/', this.index.bind(this)); this.http.get('/client.js', this.script.bind(this)); + this.http.get('/image/:key', this.image.bind(this)); this.log.info("Server assets loaded"); } template(name, data) { @@ -45,7 +49,22 @@ class Server { } return html; } - async start() { + async startWss() { + try { + this.wss = new ws_1.WebSocketServer({ port: this.wsPort }); + } + catch (err) { + this.log.error(err); + return; + } + this.wss.on('connection', (ws) => { + this.log.info(`Client connected to WebSocketServer`); + console.dir(ws); + ws.send('mcopy'); + }); + this.log.info(`WSS [ ws://localhost:${this.wsPort} ]`); + } + async startHttp() { return new Promise(function (resolve, reject) { this.httpd = this.http.listen(this.port, function () { this.isActive = true; @@ -55,11 +74,16 @@ class Server { }.bind(this)); }.bind(this)); } - stop() { + async start() { + await this.startHttp(); + await this.startWss(); + } + async stop() { return new Promise(function (resolve, reject) { return this.httpd.close(function () { this.isActive = false; this.log.info(`Server stopped :(`); + return resolve(false); }.bind(this)); }.bind(this)); } @@ -74,6 +98,36 @@ class Server { this.log.info('GET /script.js'); return res.send(js); } + async image(req, res, next) { + let filePath; + if (req.params && req.params.key) { + if (this.proxy[req.params.key]) { + filePath = this.proxy[req.params.key].path; + } + else { + return false; + } + } + else { + return false; + } + return new Promise(function (resolve, reject) { + return res.sendFile(filePath, function (err) { + if (err) { + res.status(err.status).end(); + return reject(err); + } + return resolve(true); + }); + }.bind(this)); + } + addProxy(key, filePath) { + this.proxy[key] = { + path: filePath, + mime: mime_1.default.getType(filePath) + }; + this.log.info(`Added proxy image [${key}]`); + } } module.exports = function () { return new Server(); diff --git a/app/lib/server/index.js.map b/app/lib/server/index.js.map index c2fc08d..c17759c 100644 --- a/app/lib/server/index.js.map +++ b/app/lib/server/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/app/package-lock.json b/app/package-lock.json index d18b6a6..a4b7642 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -1,6 +1,6 @@ { "name": "mcopy-app", - "version": "1.7.8", + "version": "1.7.9", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/app/package.json b/app/package.json index 3e2c7b6..0dbd52c 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "mcopy-app", - "version": "1.7.8", + "version": "1.7.9", "description": "GUI for the mcopy small gauge film optical printer platform", "main": "main.js", "scripts": { diff --git a/app/server.html b/app/server.html index cbf9741..df36fa2 100644 --- a/app/server.html +++ b/app/server.html @@ -1,10 +1,37 @@ +
Click to prevent sleep
+
+
+ + \ No newline at end of file diff --git a/app/src/lib/client/index.ts b/app/src/lib/client/index.ts index 258d03b..183a559 100644 --- a/app/src/lib/client/index.ts +++ b/app/src/lib/client/index.ts @@ -1,5 +1,212 @@ +/*! NoSleep.min.js v0.12.0 - git.io/vfn01 - Rich Tibbett - MIT license */ +//@ts-ignore +!function(A,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.NoSleep=e():A.NoSleep=e()}(this,(function(){return function(A){var e={};function B(g){if(e[g])return e[g].exports;var o=e[g]={i:g,l:!1,exports:{}};return A[g].call(o.exports,o,o.exports,B),o.l=!0,o.exports}return B.m=A,B.c=e,B.d=function(A,e,g){B.o(A,e)||Object.defineProperty(A,e,{enumerable:!0,get:g})},B.r=function(A){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(A,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(A,"__esModule",{value:!0})},B.t=function(A,e){if(1&e&&(A=B(A)),8&e)return A;if(4&e&&"object"==typeof A&&A&&A.__esModule)return A;var g=Object.create(null);if(B.r(g),Object.defineProperty(g,"default",{enumerable:!0,value:A}),2&e&&"string"!=typeof A)for(var o in A)B.d(g,o,function(e){return A[e]}.bind(null,o));return g},B.n=function(A){var e=A&&A.__esModule?function(){return A.default}:function(){return A};return B.d(e,"a",e),e},B.o=function(A,e){return Object.prototype.hasOwnProperty.call(A,e)},B.p="",B(B.s=0)}([function(A,e,B){"use strict";var g=function(){function A(A,e){for(var B=0;B.5&&(e.noSleepVideo.currentTime=Math.random())}))})))}return g(A,[{key:"_addSourceToVideo",value:function(A,e,B){var g=document.createElement("source");g.src=B,g.type="video/"+e,A.appendChild(g)}},{key:"enable",value:function(){var A=this;return Q()?navigator.wakeLock.request("screen").then((function(e){A._wakeLock=e,A.enabled=!0,console.log("Wake Lock active."),A._wakeLock.addEventListener("release",(function(){console.log("Wake Lock released.")}))})).catch((function(e){throw A.enabled=!1,console.error(e.name+", "+e.message),e})):C()?(this.disable(),console.warn("\n NoSleep enabled for older iOS devices. This can interrupt\n active or long-running network requests from completing successfully.\n See https://github.com/richtr/NoSleep.js/issues/15 for more details.\n "),this.noSleepTimer=window.setInterval((function(){document.hidden||(window.location.href=window.location.href.split("#")[0],window.setTimeout(window.stop,0))}),15e3),this.enabled=!0,Promise.resolve()):this.noSleepVideo.play().then((function(e){return A.enabled=!0,e})).catch((function(e){throw A.enabled=!1,e}))}},{key:"disable",value:function(){Q()?(this._wakeLock&&this._wakeLock.release(),this._wakeLock=null):C()?this.noSleepTimer&&(console.warn("\n NoSleep now disabled for older iOS devices.\n "),window.clearInterval(this.noSleepTimer),this.noSleepTimer=null):this.noSleepVideo.pause(),this.enabled=!1}},{key:"isEnabled",get:function(){return this.enabled}}]),A}();A.exports=i},function(A,e,B){"use strict";A.exports={webm:"data:video/webm;base64,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",mp4:"data:video/mp4;base64,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"}}])})); + const webSocket = new WebSocket('ws://localhost:{{PORT}}/'); -webSocket.onmessage = (event) => { +let imgTmp : Image; + +function preventSleep () { + //@ts-ignore + var noSleep = new NoSleep(); + document.addEventListener('click', function enableNoSleep() { + document.removeEventListener('click', enableNoSleep, false); + document.getElementById('nosleep').remove(); + noSleep.enable(); + }, false); +} + + +async function setImage (src : string) { + return new Promise(async (resolve : Function, reject : Function) => { + imgTmp = new Image() + let img = document.getElementById('img') + let body = document.querySelector('body') + if (body.classList.contains('meter')) { + body.classList.remove('meter') + } + imgTmp.onload = function () { + img.style.backgroundImage = `url('${src}')`; + return resolve(src); + }; + imgTmp.src = src; + }); +} +async function onMeter () { + console.log('meter') + const body = document.querySelector('body') + if (!body.classList.contains('meter')) { + body.classList.add('meter') + } +} +async function onFocus () { + console.log('focus') + const can = document.getElementById('can') + const dpr = window.devicePixelRatio || 1 + let ctx; + + if (!can.classList.contains('show')) { + can.classList.add('show') + } + + can.width = window.innerWidth * dpr + can.height = window.innerHeight * dpr + + can.style.width = `${window.innerWidth}px` + can.style.height = `${window.innerHeight}px` + + ctx = can.getContext('2d') + ctx.scale(dpr, dpr) + + try{ + await drawFocus(can, ctx) + } catch (err) { + alert(JSON.stringify(err)) + } +} +async function drawFocus (can, ctx) { + const count = 20 + const half = Math.round(count / 2) + const dpr = window.devicePixelRatio || 1 + const w = can.width / dpr + const h = can.height / dpr + const longest = w >= h ? w * 1.5 : h * 1.5 + const opp = Math.tan(360 / (count * 32)) * longest / 10 + + //console.log(`l: ${longest}`) + //console.log(`${360 / (count * 8)}deg`) + //console.log(`o: ${opp}`) + + for (let i = 0; i < count; i++) { + ctx.beginPath() + ctx.moveTo(w / 2, h / 2) + ctx.lineTo((w / 2) + opp, longest) + ctx.lineTo((w / 2) - opp, longest) + ctx.fill() + ctx.translate(w / 2, h / 2); + ctx.rotate((360 / count) * Math.PI / 180) + ctx.translate(- w / 2, -h / 2) + } +} +async function onField (arg : any) { + console.log('field guide') + const can : HTMLCanvasElement = document.getElementById('can') + const dpr = window.devicePixelRatio || 1 + const screen = window.outerWidth / window.outerHeight + let ctx : CanvasRenderingContext2D; + if (!can.classList.contains('show')) { + can.classList.add('show') + } + if (arg.ratio) { + if (arg.ratio < screen) { + can.width = (window.innerHeight * arg.ratio) * dpr + can.height = window.innerHeight * dpr + } else { + can.width =window.innerWidth * dpr + can.height = (window.innerWidth / arg.ratio) * dpr + } + } else { + can.width = window.innerWidth * dpr + can.height = window.innerHeight * dpr + } + + if (arg.ratio) { + if (arg.ratio < screen) { + can.style.width = `${window.innerHeight * arg.ratio}px` + can.style.height = `${window.innerHeight}px` + } else { + can.style.width = `${window.innerWidth}px` + can.style.height = `${window.innerWidth / arg.ratio}px` + } + } else { + can.style.width = `${window.innerWidth}px` + can.style.height = `${window.innerHeight}px` + } + + ctx = can.getContext('2d') + ctx.scale(dpr, dpr) + + try{ + await drawField(can, ctx) + } catch (err) { + alert(JSON.stringify(err)) + } +} +// draw a field guide +async function drawField (can : HTMLCanvasElement, ctx : CanvasRenderingContext2D) { + const count = 20 + const half = Math.round(count / 2) + const dpr = window.devicePixelRatio || 1 + const w = can.width / dpr + const h = can.height / dpr + const wsec = w / count + const hsec = h / count + const spacer = 12 + const fontSize = 18 + + ctx.lineWidth = 2 + + ctx.moveTo(w / 2, 0) + ctx.lineTo(w / 2, h) + ctx.stroke() + ctx.moveTo(0, h / 2) + ctx.lineTo(w, h / 2) + ctx.stroke() + + for (let i = 0; i < count; i++) { + ctx.moveTo(wsec * i, hsec * i) + ctx.lineTo(wsec * i, h - (hsec * i)) + ctx.stroke() + ctx.moveTo(wsec * i, hsec * i) + ctx.lineTo(w - (wsec * i), hsec * i) + ctx.stroke() + } + + ctx.lineWidth = 1 + + ctx.font = `${fontSize}px Arial` + for (let i = 0; i < half; i++) { + //left count + ctx.fillText(`${(half - i)}`, (wsec * i) + spacer, (h / 2) - spacer) + //right count + ctx.fillText(`${(half - i)}`, (w - (wsec * i)) - (spacer * 2), (h / 2) + (spacer * 2)) + //up count + ctx.fillText(`${(half - i)}`, (w / 2) + spacer, (hsec * i) + spacer + (fontSize / 2) ) + //down count + ctx.fillText(`${(half - i)}`, (w / 2) - (spacer * 2), (h - (hsec * i)) - spacer) + } +} + +function send (obj : any) { + if (webSocket) { + webSocket.send(JSON.stringify(obj)) + } +} + +webSocket.onmessage = async (event : any) => { const data = JSON.parse(event.data); - console.log(data); -} \ No newline at end of file + if (data.action === 'mcopy') { + console.log('Connected') + send({ action : 'mcopy' }) + } + if (data.action === 'image') { + await setImage(data.image) + send({ action : 'image' }) + } + if (data.action === 'field') { + await onField( { ratio : data.ratio }) + send({ action : 'field' }) + } + if (data.action === 'meter') { + await onMeter() + send({ action : 'meter' }) + } + if (data.action === 'focus') { + await onFocus() + send({ action : 'focus' }) + } +} + + +(function main () { + preventSleep(); +})() \ No newline at end of file diff --git a/data/cfg.json b/data/cfg.json index e19df65..b2ca107 100644 --- a/data/cfg.json +++ b/data/cfg.json @@ -1,5 +1,5 @@ { - "version": "1.7.8", + "version": "1.7.9", "ext_port": 1111, "profiles": { "mcopy": { diff --git a/package-lock.json b/package-lock.json index 943fdc9..2bb1c99 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "mcopy", - "version": "1.7.8", + "version": "1.7.9", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "mcopy", - "version": "1.7.8", + "version": "1.7.9", "license": "MIT", "dependencies": { "arduino": "file:app/lib/arduino", diff --git a/package.json b/package.json index c396ded..fffa9cf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mcopy", - "version": "1.7.8", + "version": "1.7.9", "description": "Small gauge film optical printer platform", "main": "build.js", "directories": { diff --git a/processing/mcopy/cfg.json b/processing/mcopy/cfg.json index e19df65..b2ca107 100644 --- a/processing/mcopy/cfg.json +++ b/processing/mcopy/cfg.json @@ -1,5 +1,5 @@ { - "version": "1.7.8", + "version": "1.7.9", "ext_port": 1111, "profiles": { "mcopy": { diff --git a/src/server/index.ts b/src/server/index.ts index 0e8ea4b..623437f 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -1,7 +1,8 @@ -import * as WebSocket from 'ws' +import WebSocket, { WebSocketServer } from 'ws' import express, { Express, Request, Response, Application } from 'express' import { readFile } from 'fs/promises' -import Log = require('log'); +import mime from 'mime' +import Log = require('log') interface ServerData { [key: string]: string; @@ -11,7 +12,16 @@ interface ServerData { interface ServerTemplate { name : string; path : string; - data? : string + data? : string; +} + +interface ServerProxy { + path : string; + mime : string; +} + +interface ServerProxyList { + [key: string]: ServerProxy; } class Server { @@ -30,8 +40,10 @@ class Server { ] private http : Application private httpd : Server + private wss : WebSocketServer private port : number = 9900 private wsPort : number = 9901 + private proxy : ServerProxyList = {} constructor () { this.init() @@ -52,6 +64,7 @@ class Server { this.http.get('/', this.index.bind(this)) this.http.get('/client.js', this.script.bind(this)) + this.http.get('/image/:key', this.image.bind(this)) this.log.info("Server assets loaded") } @@ -64,10 +77,23 @@ class Server { return html } - async start () { + async startWss () { + try { + this.wss = new WebSocketServer({ port: this.wsPort }) + } catch (err) { + this.log.error(err) + return + } + this.wss.on('connection', (ws) => { + this.log.info(`Client connected to WebSocketServer`) + ws.send(JSON.stringify({ action : 'mcopy' }); + }) + this.log.info(`WSS [ ws://localhost:${this.wsPort} ]`) + } + + async startHttp () { return new Promise(function (resolve : Function, reject : Function) { this.httpd = this.http.listen(this.port, function () { - this.isActive = true this.log.info(`Server started!`) this.log.info(`URL [ http://localhost:${this.port} ]`) return resolve(true) @@ -75,14 +101,20 @@ class Server { }.bind(this)) } - stop() { + async start () { + await this.startHttp() + await this.startWss() + this.isActive = true + } + + async stop() { return new Promise(function (resolve : Function, reject : Function) { return this.httpd.close(function () { this.isActive = false this.log.info(`Server stopped :(`) + return resolve(false) }.bind(this)) }.bind(this)) - } index (req : Request, res : Response, next : Function) { @@ -96,6 +128,36 @@ class Server { this.log.info('GET /script.js') return res.send(js) } + + async image (req : Request, res : Response, next : Function) { + let filePath : string + if (req.params && req.params.key) { + if (this.proxy[req.params.key]) { + filePath = this.proxy[req.params.key].path + } else { + return false + } + } else { + return false + } + return new Promise(function (resolve : Function, reject: Function) { + return res.sendFile(filePath, function (err : any) { + if (err) { + res.status(err.status).end() + return reject(err) + } + return resolve(true) + }) + }.bind(this)) + } + + public addProxy (key : string, filePath : string) { + this.proxy[key] = { + path : filePath, + mime : mime.getType(filePath) + } + this.log.info(`Added proxy image [${key}]`) + } } module.exports = function () {