diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml new file mode 100644 index 00000000..75132889 --- /dev/null +++ b/.github/workflows/build-test.yml @@ -0,0 +1,52 @@ +name: Test Electron App Production Build + +on: + # Runs on pushes targeting the default branch + push: + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + + +jobs: + build-ubuntu: + runs-on: "ubuntu-latest" + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install dependencies + run: npm install + + - name: Build Electron app + env: + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + run: npm run build + + build-windows: + runs-on: "windows-latest" + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install dependencies + run: npm install + + - name: Build Electron app + env: + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + run: npm run build + + + diff --git a/.github/workflows/prod-test.yml b/.github/workflows/prod-test.yml new file mode 100644 index 00000000..28093deb --- /dev/null +++ b/.github/workflows/prod-test.yml @@ -0,0 +1,27 @@ +name: Test NPM Production Build + +on: + # Runs on pushes targeting the default branch + push: + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + + +jobs: + build: + runs-on: "ubuntu-latest" + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Setup And Install dependencies + run: npm run setup + + - name: dry run production build + run: npm run prod-dryrun \ No newline at end of file diff --git a/mods/bambu/bambu.js b/mods/bambu/bambu.js index 6ff97b21..5d182528 100644 --- a/mods/bambu/bambu.js +++ b/mods/bambu/bambu.js @@ -126,7 +126,12 @@ self.kiri.load(api => { }, drain() { while (socket.open && socket.q.length) { - socket.ws.send(JSON.stringify(socket.q.shift())); + let data = socket.q.shift(); + if (data instanceof ArrayBuffer) { + socket.ws.send(data); + } else { + socket.ws.send(JSON.stringify(data)); + } } }, send(msg) { @@ -614,6 +619,16 @@ self.kiri.load(api => { } } + function file_send(file, data) { + if (selected?.rec?.host) { + let { rec } = selected; + host = rec.host; + serial = rec.serial; + password = rec.code; + send(file.name, data, false); + } + } + function calcFG(bg) { let r = parseInt(bg.substring(0, 2), 16); let g = parseInt(bg.substring(2, 4), 16); @@ -1007,7 +1022,7 @@ self.kiri.load(api => { ]) ]), - h.div({ class: "t-body t-inset f-col gap3 pad4 grow" }, [ + h.div({ id: "bbl_drop", class: "t-body t-inset f-col gap3 pad4 grow" }, [ h.div({ class: "set-header", onclick() { file_list(); } }, h.a({ class: "flex f-row grow a-center" }, [ @@ -1050,7 +1065,10 @@ self.kiri.load(api => { file_print(selected.file.path); api.alerts.show(`printing: ${selected.file.path}`,2); }}), - ]) + ]), + h.div({ id: "bbl_drop_zone", class: "full hide allpe", style: "background-color: rgba(0,255,0,0.75); font-weight: bold" }, [ + h.label('drop to upload') + ]), ]), h.div({ class: "t-body t-inset f-col gap3 pad4" }, [ h.label({ class: "set-header dev-sel" }, [ @@ -1122,6 +1140,41 @@ self.kiri.load(api => { $('bbl_file_delete').disabled = $('bbl_file_print').disabled = false; }); + let drop = modal.bbl_drop; + let drop_zone = modal.bbl_drop_zone; + let drop_timer; + drop.ondragenter = (ev) => { + if (!selected?.rec?.serial) { + return; + } + drop.classList.add('nope'); + drop_zone.classList.remove('hide'); + clearTimeout(drop_timer); + }; + drop_zone.ondragleave = (ev) => { + clearTimeout(drop_timer); + drop_timer = setTimeout(() => { + drop.classList.remove('nope'); + drop_zone.classList.add('hide'); + }, 50); + }; + drop_zone.ondrop = (ev) => { + drop.classList.remove('nope'); + drop_zone.classList.add('hide'); + ev.preventDefault(); + ev.stopPropagation(); + let files = ev.dataTransfer.files; + console.log('filedrop', files); + for (let file of files) { + let reader = new FileReader(); + // reader.file = file; + reader.onloadend = (ev) => { + let data = ev.target.result; + file_send(file, data); + }; + reader.readAsArrayBuffer(file); + } + }; }); api.event.on("modal.show", which => { @@ -1251,6 +1304,7 @@ self.kiri.load(api => { console.log('Bambu Send', res); if (res.sent) { api.alerts.show('File Sent', 3); + file_list(); } else { api.alerts.show('File Send Error', 3); } diff --git a/mods/bambu/init.js b/mods/bambu/init.js index 25020120..370554c6 100644 --- a/mods/bambu/init.js +++ b/mods/bambu/init.js @@ -349,9 +349,13 @@ module.exports = async (server) => { wsopen.push(ws); debug && util.log('ws open', req.url, wsopen.length); wsend({ found }); - ws.on('message', msg => { - msg = JSON.parse(msg); - let { cmd, host, code, serial, path, amsmap, direct, frames } = msg; + let binaryData; + ws.on('message', (msg, isBinary) => { + if (isBinary) { + return binaryData = msg; + } + msg = isBinary ? msg : JSON.parse(msg.toString()); + let { cmd, host, code, serial, path, amsmap, direct, frames, file, data } = msg; switch (cmd) { case "monitor": get_mqtt(host, code, serial, message => { diff --git a/package.json b/package.json index 3dfb17e4..a09a9fab 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "grid-apps", - "version": "4.1.6", + "version": "4.1.7", "description": "grid.space 3d slicing & modeling tools", "author": "Stewart Allen ", "license": "MIT", @@ -36,7 +36,7 @@ }, "dependencies": { "@fortawesome/fontawesome-free": "^6.1.1", - "@gridspace/app-server": "^0.0.15", + "@gridspace/app-server": "^0.0.16", "@gridspace/net-level-client": "^0.2.3", "@tracespace/parser": "^5.0.0-next.0", "@tweenjs/tween.js": "^16.6.0", @@ -55,7 +55,7 @@ "three-mesh-bvh": "^0.7.6", "uglify-js": "3.14.5", "validator": ">=13.7.0", - "ws": "^7.5.5" + "ws": "^8.18.2" }, "devDependencies": { "@electron/notarize": "^3.0.0", @@ -72,6 +72,7 @@ "setup": "npm i && cd mods && npm i", "dev": "gs-app-server --debug", "prod": "gs-app-server", + "prod-dryrun": "gs-app-server --dryrun", "start": "npm run prebuild && electron .", "start-dev": "npm run prebuild && electron . --devel", "start-dbg": "npm run prebuild && electron . --debugg", diff --git a/src/moto/license.js b/src/moto/license.js index 9d24a228..05f7cb15 100644 --- a/src/moto/license.js +++ b/src/moto/license.js @@ -5,7 +5,7 @@ let terms = { COPYRIGHT: "Copyright (C) Stewart Allen - All Rights Reserved", LICENSE: "See the license.md file included with the source distribution", - VERSION: (is_self ? self : this).debug_version || "4.1.6" + VERSION: (is_self ? self : this).debug_version || "4.1.7" }; if (typeof(module) === 'object') { diff --git a/web/kiri/index.css b/web/kiri/index.css index 65c51cd2..a35f0b7f 100644 --- a/web/kiri/index.css +++ b/web/kiri/index.css @@ -646,6 +646,23 @@ details[open] summary::after { .contents { display: contents; } +.full { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} +.nope, .nope * { + pointer-events: none; +} +.allpe { + pointer-events: auto !important; +} .hide { display: none !important; } diff --git a/web/kiri/manifest.json b/web/kiri/manifest.json index 4c762d51..84bfb412 100644 --- a/web/kiri/manifest.json +++ b/web/kiri/manifest.json @@ -1,5 +1,5 @@ { - "name": "Kiri:Moto 4.1.6", + "name": "Kiri:Moto 4.1.7", "short_name": "Kiri:Moto", "description": "Slicer for 3D printers, CNC mills, laser cutters and more", "start_url": "/kiri/",