diff --git a/.gitignore b/.gitignore index 5148e52..a038d5c 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,8 @@ jspm_packages # Optional REPL history .node_repl_history + +# file generated by webpack +public/index.html +public/signalk-autopilot.min.js +public/signalk-autopilot.min.js.map diff --git a/package.json b/package.json index 6c6311a..81abdb5 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,10 @@ "scripts": { "test": "$NODE $npm_package_main", "create-release": "github-create-release --owner signalk --repository signalk-autopilot", - "release": "git tag -d v$npm_package_version; git tag v$npm_package_version && git push --tags && git push && npm run create-release" + "release": "git tag -d v$npm_package_version; git tag v$npm_package_version && git push --tags && git push && npm run create-release", + "start": "webpack serve --config webpack.dev.config.js", + "build": "webpack --config webpack.prod.config.js --progress", + "prepublishOnly": "npm run build" }, "keywords": [ "signalk-node-server-plugin", @@ -18,7 +21,13 @@ "lodash": "^4.17.15" }, "devDependencies": { - "@signalk/github-create-release": "^1.0.1" + "@signalk/github-create-release": "^1.0.1", + "copy-webpack-plugin": "^11.0.0", + "html-minimizer-webpack-plugin": "^4.4.0", + "webpack": "^5.88.2", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^4.15.1", + "webpack-merge": "^5.9.0" }, "repository": { "type": "git", @@ -28,4 +37,4 @@ "appIcon": "./appIcon-72x72.png", "displayName": "Signal K autopilot" } -} +} \ No newline at end of file diff --git a/public-src/index.html b/public-src/index.html new file mode 100644 index 0000000..5024cf4 --- /dev/null +++ b/public-src/index.html @@ -0,0 +1,590 @@ + + + + + + + + + + + + Signal K Autopilot + + + +
+
+
+
+
Auto Pilot
+
+
+
88
+
+
5
+
+
+
+
+
+
+
+
 Loading Auto Pilot...
+
+
+
+
+
 Mute alarm press:
+
 Next alarm press:
+
+
+
+
+
+
+
+
+
: TACK :
+
+
+
+
+
+
+
+
-1
+
+
+
-10
+
+
+
+10
+
+
+
+1
+
+
+
AUTO
+
+
+
WIND
+
+
+
TRACK
+
+
+
STANDBY
+
+
+
+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/public/js/signalk-autopilot.js b/public-src/js/signalk-autopilot.js similarity index 94% rename from public/js/signalk-autopilot.js rename to public-src/js/signalk-autopilot.js index 3f8b595..ffd2b0a 100644 --- a/public/js/signalk-autopilot.js +++ b/public-src/js/signalk-autopilot.js @@ -12,7 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - const commands = { "auto": { "path": "steering.autopilot.state", "value": "auto" }, "wind": { "path": "steering.autopilot.state", "value": "wind" }, @@ -29,7 +28,7 @@ const commands = { var notificationsArray = {}; -var touchEnd = function (event) { +export function touchEnd(event) { event.currentTarget.onclick(); event.preventDefault(true); } @@ -40,6 +39,7 @@ var handleReceiveTimeout = null; var handleSilenceScreenTimeout = null; var handleConfirmActionTimeout = null; var handleCountDownCounterTimeout = null; +var handleMessageAlertTimeout = null; var connected = false; var reconnect = true; const timeoutReconnect = 2000; @@ -62,7 +62,7 @@ var bottomBarIconDiv = undefined; var notificationCounterDiv = undefined; var notificationCounterTextDiv = undefined; var silenceScreenDiv = undefined; -var silenceScreenText = undefined; +var silenceScreenTextDiv = undefined; var confirmScreenDiv = undefined; var remoteHelpDiv = undefined; var remoteMainDiv = undefined; @@ -119,7 +119,7 @@ const originalElementsSize = { 'remoteHelp': { width: 633, heigth: 693 } } -var startUpAutoPilot = function () { +export function startUpAutoPilot() { pilotStatusDiv = document.getElementById('pilotStatus'); headingValueDiv = document.getElementById('headingValue'); receiveIconDiv = document.getElementById('receiveIcon'); @@ -183,10 +183,10 @@ var demo = function () { countDownCounterDiv.innerHTML = countDownDefault.toString(); } */ -var buildAndSendCommand = function (cmd) { +export function buildAndSendCommand(cmd) { var cmdAction = commands[cmd]; if (typeof cmdAction === 'undefined') { - alert('Unknown command !'); + alertHtml('Unknown command !'); return null; } if ((actionToBeConfirmed !== '') && (actionToBeConfirmed !== cmd)) { @@ -219,7 +219,7 @@ var sendCommand = function (cmdAction) { wsConnect(); if ((ws === null) || (ws.readyState !== 1)) { errorIconDiv.style.visibility = 'visible'; - alert('Not connected yet, please retry your command...'); + alertHtml('Not connected yet, please retry your command...'); return null; } console.log(cmdAction); @@ -240,7 +240,7 @@ var notificationToValue = function (skPathToAck) { return message; } -var sendSilence = function () { +export function sendSilence() { if (silenceScreenDiv.style.visibility !== 'visible') { silenceScreenDiv.style.visibility = 'visible'; autoHideSilenceScreen(); @@ -259,7 +259,7 @@ var sendSilence = function () { silenceScreenTextDiv.innerHTML = notificationToValue(skPathToAck); } -var notificationScroll = function () { +export function notificationScroll() { autoHideSilenceScreen(); if (silenceScreenDiv.style.visibility !== 'visible') { silenceScreenDiv.style.visibility = 'visible'; @@ -301,7 +301,7 @@ var getNextNotification = function (skPath) { return newSkPathToAck; } -var changePreferedDisplayMode = function () { +export function changePreferedDisplayMode() { const currentPreferedDisplayMode = preferedDisplayMode[pilotStatus]; var pathForPilotStatus = []; if (typeof currentPreferedDisplayMode === 'undefined') { return null } @@ -360,7 +360,6 @@ var clearConfirmCmd = function () { confirmScreenDiv.style.visibility = 'hidden'; confirmScreenDiv.innerHTML = ''; actionToBeConfirmed = ''; - cmdConfirmed = false; } var wsConnect = function () { @@ -446,10 +445,10 @@ var wsConnect = function () { if (jsonData.state === 'COMPLETED') { if (jsonData.statusCode === 403) { errorIconDiv.style.visibility = 'visible'; - alert('[' + jsonData.statusCode + ']' + 'You must be authenticated to send command'); + alertHtml('[' + jsonData.statusCode + ']' + 'You must be authenticated to send command'); } else if (jsonData.statusCode !== 200) { errorIconDiv.style.visibility = 'visible'; - alert('[' + jsonData.statusCode + ']' + jsonData.message); + alertHtml('[' + jsonData.statusCode + ']' + jsonData.message); } } console.log(jsonData); @@ -576,14 +575,14 @@ var setNotificationMessage = function (value) { } } -var displayHelp = function () { +export function displayHelp() { if (remoteMainDiv.style.visibility !== 'hidden') { remoteMainDiv.style.visibility = 'hidden'; remoteMainDiv.style.display = 'none'; remoteHelpDiv.style.visibility = 'visible'; remoteHelpDiv.style.display = 'block'; - remoteHelpDiv.innerHTML = ''; + remoteHelpDiv.innerHTML = ''; updateMainSize() } else { remoteHelpDiv.style.visibility = 'hidden'; @@ -596,7 +595,7 @@ var displayHelp = function () { } } -var wsOpenClose = function () { +export function wsOpenClose() { if (connected === false) { wsConnect(); } else { @@ -662,8 +661,21 @@ function updateMainSize() { pageWidth / originalElementsSize[visibleElId].width, pageHeigth / originalElementsSize[visibleElId].heigth ); - xOffset = ((pageWidth - (originalElementsSize[visibleElId].width * scale))) / 2; + var xOffset = ((pageWidth - (originalElementsSize[visibleElId].width * scale))) / 2; mainDiv.style.transform = "scale(" + scale + ")"; mainDiv.style.transformOrigin = "0px 0px"; mainDiv.style.marginLeft = xOffset + "px"; } + +function alertHtml(message) { + confirmScreenDiv.innerHTML = '

' + message + '

'; + confirmScreenDiv.style.visibility = 'visible'; + confirmScreenDiv.style.color = 'red'; + clearTimeout(handleMessageAlertTimeout); + handleMessageAlertTimeout = setTimeout(() => { + confirmScreenDiv.style.visibility = 'hidden'; + confirmScreenDiv.innerHTML = ''; + confirmScreenDiv.style.color = 'black'; + }, 5000); + +} \ No newline at end of file diff --git a/public/css/signalk-autopilot.css b/public/css/signalk-autopilot.css deleted file mode 100644 index d9a5f09..0000000 --- a/public/css/signalk-autopilot.css +++ /dev/null @@ -1,486 +0,0 @@ -body, -html { - margin: 0; - padding: 0; - overflow: hidden; -} - -#main { - margin: 0px; - width: 100vw; - height: 100vh; - background-repeat: no-repeat; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -} - -.bgRemoteMain { - margin: 0px; - width: 238px; - height: 612px; - position: relative; - background-image: url("../img/bgRemoteMain.png"); -} - -.btnCircleWithDotRed { - width: 70px; - height: 70px; - background-image: url("../img/btnCircleWithDotRed.png"); -} - -.btnCircleWithDotRed:active { - background-position-x: -70px; -} - -.btnCircleRed { - width: 70px; - height: 70px; - background-image: url("../img/btnCircleRed.png"); -} - -.btnCircleRed:active { - background-position-x: -70px; -} - -.btnLeftBlack { - width: 50px; - height: 54px; - background-image: url("../img/btnLeftBlack.png"); - background-size: 100px; -} - -.btnLeftBlack:active { - background-position-x: -50px; -} - -.btnRightBlack { - width: 50px; - height: 54px; - background-image: url("../img/btnRightBlack.png"); - background-size: 100px; -} - -.btnRightBlack:active { - background-position-x: -50px; -} - -.btnTopBlack { - width: 54px; - height: 50px; - left: 90px; - top: 280px; - background-image: url("../img/btnTopBlack.png"); - background-size: 55px; -} - -.btnTopBlack:active { - background-position-y: -50px; -} - -.btnBottomBlack { - width: 54px; - height: 50px; - left: 90px; - top: 378px; - background-image: url("../img/btnBottomBlack.png"); - background-size: 55px; -} - -.btnBottomBlack:active { - background-position-y: -50px; -} - -.btnTopSmallBlack { - width: 52px; - height: 38px; - background-image: url("../img/btnTopSmallBlack.png"); - background-size: 104px; -} - -.btnTopSmallBlack:active { - background-position-x: -52px; -} - -.btnBottomSmallBlack { - width: 52px; - height: 38px; - background-image: url("../img/btnBottomSmallBlack.png"); - background-size: 104px; -} - -.btnBottomSmallBlack:active { - background-position-x: -52px; -} - -.defaultTextFontKey { - width: 100%; - color: white; - position: absolute; - text-align: center; - font-size: 20px; - font-weight: bold; -} - -.defaultKey { - cursor: pointer; - position: absolute; -} - -#remoteMain { - visibility: hidden; - display: none; -} - -#remoteHelp { - visibility: hidden; - display: none; - width: 633px; - height: 693px; - cursor: pointer; -} - -#logoSignalK { - top: 54px; - left: 44px; - width: 16px; - height: 16px; - position: absolute; - background-image: url("../img/signalK_16x16.png"); - background-size: 16px; - background-color: white; -} - -#logoText { - top: 54px; - left: 66px; - width: 100px; - height: 18px; - position: absolute; - color: white; -} - -#topBarIcon { - top: 94px; - left: 38px; - width: 155px; - height: 18px; - position: absolute; - background-repeat: no-repeat; - background-position-x: right; - background-color: initial; -} - -#bottomBarIcon { - top: 190px; - left: 38px; - width: 155px; - height: 18px; - position: absolute; - background-repeat: no-repeat; - background-position-x: right; - background-color: initial; - white-space: nowrap; - overflow: hidden; - color: red; - text-overflow: ellipsis; - text-align: center; -} - -.icon18x18 { - width: 18px; - height: 18px; - position: absolute; - visibility: visible; -} - -#powerOnIcon { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAQAAAD8x0bcAAAAeklEQVR4AdXQsQ2CUBgE4K/RxM64BNqxicQlYAMdQaZgAV0B/9AxDzUPW8ibgO/aKy5n7x46vRBKpRB6ncpKazGKTWkwWbQAheQld/KVFEBtdgSxClzMaqCRnJGXDmYNcJN8nOSekivA22IybIaHcT0cKp1fdsHdvv0B0+E2g9R6Y0QAAAAASUVORK5CYII=); - left: 140px; - visibility: hidden; -} - -#powerOffIcon { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAQAAAD8x0bcAAAAuklEQVR4Aa3NgUZDYRzG4ac0WkJCNxAS6ICQIgQQu4MQCgyAgAiKAAhhN1AGA8M2u5ddwWzGnPONPz7APtgPwON97bRDHw4UurYyKLM7yzLb8y1lVpmYGOnpIPcjmYnTjKbmki+AK8mvffdx2gLQ9q9xAXTVjsFMMtRSGYFTtRfgVeME4mYR7BkcqXWBS40/bcCtVTB41zgH+JTMTWOp8iROPVh7Q66jZyyQKp+e2dqNZTBl1qfMHu24DRTyPk1WGp22AAAAAElFTkSuQmCC); - left: 140px; -} - -#typeValIcon { - left: 48px; - width: 34px; -} - -#sendIcon { - left: 120px; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAQAAAD8x0bcAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAyklEQVQoz8XOIU4DARCF4Y+iIO02IeAxCERFRRWFW+DgAAjugK8gNXCFUlQNWHQNBDD1yGZTgmw3g9jNssmGSphR8+bN/I8/rc2aMnDkaf3RQAhX6ywtUyFMtX6z7IFDB5WpBvp0Xk5nvurQxEwIC89eLIQwk1Qtu2i7lYmiV260i00BmuuBpr5LF/qaoGeeQxPvwsrYsUb5u+HEnUx4y6FbxgUk9eDa0KO0UEa2f1J1TSzLRCEsTXTz5UYl/o5THfsyH17dS/1PfQMplUPMhfqpHwAAAABJRU5ErkJggg==); - transform: scaleY(-1); -} - -#receiveIcon { - left: 102px; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAQAAAD8x0bcAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAyklEQVQoz8XOIU4DARCF4Y+iIO02IeAxCERFRRWFW+DgAAjugK8gNXCFUlQNWHQNBDD1yGZTgmw3g9jNssmGSphR8+bN/I8/rc2aMnDkaf3RQAhX6ywtUyFMtX6z7IFDB5WpBvp0Xk5nvurQxEwIC89eLIQwk1Qtu2i7lYmiV260i00BmuuBpr5LF/qaoGeeQxPvwsrYsUb5u+HEnUx4y6FbxgUk9eDa0KO0UEa2f1J1TSzLRCEsTXTz5UYl/o5THfsyH17dS/1PfQMplUPMhfqpHwAAAABJRU5ErkJggg==); -} - -#errorIcon { - left: 85px; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAQAAAD8x0bcAAAAwElEQVR4AZXRtXUDMBQAwOvDjaEMwwBhWiE0RKiy9wiWYc4W3iSoGcKRS71n9qmU9FH7+izbtWVZr5pyHsR0PMiqMOjdp2MDYMCxT++GSfKCYILEhOBVHoAbf+YA+/YBc/5cA/T4dwagpATg1L8eYFU0XfPRlGgDKIi6az7qFhWAoqgTlTXRKSoC61I6gJRuPRV+XjPSWSqcK/9mVD6a8e+qcphjSMYEQZZkyJvKtTwbUiHvsdmCgV7Ldu1a1qtdZTafSCFQvo25AAAAAElFTkSuQmCC); -} - -#notificationCounter { - left: 0px; - width: 35px; - background-repeat: no-repeat; - background-position: right; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAQAAAD8x0bcAAAAhElEQVR4Aa3MoQ3CUABF0UNwCAbAMAMTYJkDyRxI5kCyDYoNKqqbmkdFQ2j6+wXhXPvy/OY0VGftNbRWdRFxUbHVimhtLbrJ2I2yvV7GentFDxEQ8VBwlMkojqasPGejp5WJs8xGcfZlo5FCjY2PqxSf4mq00y2OOjvgLpXucBD1Dv7mDVf3cw8sx/MwAAAAAElFTkSuQmCC); -} - -#notificationCounterText { - padding-right: 20px; - text-align: right; -} - -#countDownCounter { - left: 36px; - text-align: center; -} - -#headingValue { - top: 116px; - left: 38px; - width: 158px; - height: 34px; - overflow: hidden; - position: absolute; - text-align: center; - font-weight: bolder; - font-size: 30px; -} - -#pilotStatus { - top: 150px; - left: 38px; - width: 158px; - height: 34px; - overflow: hidden; - position: absolute; - text-align: center; - text-transform: uppercase; - font-weight: bolder; - font-size: 30px; -} - -.messageScreen { - position: absolute; - top: 112px; - left: 38px; - width: 158px; - height: 100px; - z-index: 1; - visibility: hidden; - background-color: #adc1b3; -} - -#silenceScreen { - text-align: left; -} - -#tackScreen { - text-align: center; - font-weight: bold; -} - -#silenceScreenScroll { - position: relative; - top: 0px; - left: 0px; - height: 20px; - width: 150px; - background-repeat: no-repeat; - background-position: right; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAIElEQVR4AWMYGDAKJoAxgn2ACDyBmgaNem3Ua4TBKAAA2Kk2AbLe+1QAAAAASUVORK5CYII=); - -} - -#silenceScreenMute { - position: relative; - top: 0px; - left: 0px; - height: 20px; - width: 150px; - background-repeat: no-repeat; - background-position: right; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAQAAAD8x0bcAAAAvElEQVR4Aa3OAUcDARzG4adUpSAQECYRoEAium8QBH2D1AkcAZxKRkjQ56hhCIQADOwLDIANwGzGf5zDbHcD+70AD14rruHBbBeuLPQopIAmcuHfgbkyIcONwL4XQz2H1WzND+DMwK+ZTiUSrYJtI5UgFS4B+BPKyfCkb8+Wic9qFHKb2q7R1a5DIbPhCB3fdei5YOwaeZs/3iwRHwVb9+XEQu8lUjJQzdhxa7yckQstr8Kd2s4dg3sNK20KQZNRkQgu8yAAAAAASUVORK5CYII=); -} - -#silenceScreenText { - padding-top: 4px; - text-align: center; - color: red; -} - -#keyPlusOne { - top: 296px; - right: 20px; -} - -#keyPlusOneText { - top: 16px; -} - -#keyMinusOne { - top: 296px; - left: 20px; -} - -#keyMinusOneText { - top: 16px; -} - -#keyPlusTen { - top: 296px; - right: 68px; -} - -#keyPlusTenText { - top: 16px; -} - -#keyMinusTen { - top: 296px; - left: 68px; -} - -#keyMinusTenText { - top: 16px; -} - -#keyMute { - top: 362px; - left: 28px; -} - -#keyMuteText { - top: 10px; - width: 20px; - height: 20px; - left: 16px; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAQAAAD8x0bcAAAAy0lEQVR4AayRtUICUBRA7a7Jye5RF7u+wM4vsF2s0e7O37BzkZqZ+AF2WGk4XLqZeO/dPq/TUtuoZSki7mIgFloFlv3+icgOoKE8GlsH1sVOgOgy9jGjpzIuRjqv/rgNI3/hQCuD0t+8WK7Eywx6NfSGIAX+5t90CwOF5ODgNj4EO2TzxbDkdXwlgmCdLOolr+UlEbTn37QAK0fRBz8BAImvEYwMnmiJfdRzHxTAYoAQJjqPWWxJMf+3vHEAzCf+8A4avXYR9xSpm5QAaOvUDhZuhCsAAAAASUVORK5CYII=); - background-size: 20px; -} - -#keyScroll { - top: 362px; - right: 28px; -} - -#keyScrollText { - top: 10px; - width: 20px; - height: 20px; - left: 16px; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAI0lEQVR4AWMYADAK/v//PwGEkdgHiMATqGnQqNdGvUYYjAIAXvgfJmV31egAAAAASUVORK5CYII=); - background-size: 20px; -} - -#keyPower { - top: 500px; - right: 28px; -} - -#keyPowerText { - top: 10px; - width: 20px; - height: 20px; - left: 16px; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAQAAAD8x0bcAAAAw0lEQVR4AbTQgQbCQBzH8QI2Vhh7iQEJAoLWqxSwdxhApb1FgLG9wNkDbPQGA4gNU2zgGznudleADu7/v/vc/fnN/rdISX9fLuUuELJamCTkwVZHRDT4Oplzp2c9QRt6bjraAbE1LgZWCl154VjI4clFoZxalhLJuiZXqKD6FgEVhUInRlwrFJeRs2oj4GihA7DXD0o6QiO5jnL6KqBhIMH7dB4JAw2B+blPBrQIBC2Q4b+HPf7s/1f8XwuEFcAoogkAANy1lXzi6lAZAAAAAElFTkSuQmCC); - background-size: 20px; -} - -#keyStandby { - top: 486px; - left: 84px; -} - -#keyStandbyText { - top: 28px; - font-size: 10px; -} - -#keyAuto { - top: 418px; - left: 26px; -} - -#keyAutoText { - top: 28px; - font-size: 10px; -} - -#keyWind { - top: 356px; - left: 84px; -} - -#keyWindText { - top: 28px; - font-size: 10px; -} - -#keyTrack { - top: 418px; - right: 26px; -} - -#keyTrackText { - top: 28px; - font-size: 10px; -} - -#tackLabel { - top: 250px; - font-size: 14px; -} - -#keyTackPort { - top: 230px; - left: 38px; - z-index: 1; -} - -#keyTackPortText { - top: 16px; - width: 25px; - height: 25px; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAd0lEQVRIx73WSw6AIAwE0I5H9P53qTsTFYR+ZliXvJTPACw43N3NzABgt/bIANFapCYtunjXgg1sdVIFlkgH8It0AVOkExgi3cAHYQAPhAXcCBMIx0p26JZLtvGyIyy7jLJYkQWkLOplj5bs+a1C0Vg5SbX1r9EF/au4qJQe+D0AAAAASUVORK5CYII=); - left: 10px; -} - -#keyTackStarbord { - top: 230px; - right: 38px; - z-index: 1; -} - -#keyTackStarbordText { - top: 16px; - width: 25px; - height: 25px; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAg0lEQVRIx81WQQ7AIAwCn+j//+IuW6IeZqmyjDOIqZYW7QYCULg9Sn9AVKQacRaRZNRgxR1M3EbMihUud8RRLndvGeHyRDlW3GN1f+NS6YmsEdXmyxgx0+WqUcEH+Ee57A9v/8L2ZrTHij0g7VFvH1r28es2GLYVAFVIiirlinMVenABXi3An6ky178AAAAASUVORK5CYII=); - right: 10px; -} - -#keyHelp { - top: 500px; - left: 28px; -} - -#keyHelpText { - top: 10px; - width: 20px; - height: 20px; - left: 16px; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAQAAAD8x0bcAAAA+0lEQVR4AZSOMQhBYRSF7QkUmJRSeiWDwYPBaBa70WBjtY8WM2Fgt5ed7GXkSVklC5/bfa8/ZHFP/fc7p9Pf9f09hKjRFdUI/S4kWPA+S+LflQxH7oxIq0sL3SXJfP7iiCyhKB1RVMjSLGlKzHlQlZ3jDCBvTlxF0rlXIciTidKGIzHRga36MU+CbqkB2EoD6rqHXHXbQMst9YDA24Up9qyUAkDPDfuA31QsLuwIK/uBvhs3AduUptyIeFwEml+Hq8tTMDwxh4uZiSl7vGbtUUnSmaLaOA4nsspt2rqzOKLXxJHDXBlrtKjA5BGmrUCPYNxJJRcIQUmFVAAAZtDpcTPc14kAAAAASUVORK5CYII=); - background-size: 20px; -} \ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..5df1a4d Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/index.html b/public/index.html deleted file mode 100644 index fabc992..0000000 --- a/public/index.html +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - Signal K Autopilot - - - -
-
-
-
-
Auto Pilot
-
-
-
88
-
-
5
-
-
-
-
-
-
-
-
 Loading Auto Pilot...
-
-
-
-
-
 Mute alarm press:
-
 Next alarm press:
-
-
-
-
-
-
-
-
-
: TACK :
-
-
-
-
-
-
-
-
-1
-
-
-
-10
-
-
-
+10
-
-
-
+1
-
-
-
AUTO
-
-
-
WIND
-
-
-
TRACK
-
-
-
STANDBY
-
-
-
-
-
-
-
-
-
- - - \ No newline at end of file diff --git a/webpack.commons.config.js b/webpack.commons.config.js new file mode 100644 index 0000000..4fd33b7 --- /dev/null +++ b/webpack.commons.config.js @@ -0,0 +1,13 @@ +const path = require('path'); + +module.exports = { + entry: path.resolve(__dirname, './public-src/js/signalk-autopilot.js'), + output: { + path: path.resolve(__dirname, './public'), + filename: 'signalk-autopilot.min.js', + library: { + name: 'autopilot', + type: 'var', + }, + }, +}; diff --git a/webpack.dev.config.js b/webpack.dev.config.js new file mode 100644 index 0000000..f2290f0 --- /dev/null +++ b/webpack.dev.config.js @@ -0,0 +1,25 @@ +const { merge } = require('webpack-merge'); +const common = require('./webpack.commons.config.js'); +const path = require('path'); + +module.exports = merge(common, { + mode: 'development', + devtool: 'inline-source-map', + devServer: { + static: path.resolve(__dirname, './public'), + allowedHosts: 'all', + compress: true, + host: '0.0.0.0', + client: { + logging: 'info', + overlay: true, + progress: true, + }, + proxy: { + '/signalk/v1/stream': { + target: 'ws://localhost:3000', + ws: true + }, + }, + }, +}); diff --git a/webpack.prod.config.js b/webpack.prod.config.js new file mode 100644 index 0000000..3dae659 --- /dev/null +++ b/webpack.prod.config.js @@ -0,0 +1,53 @@ +const { merge } = require('webpack-merge'); +const common = require('./webpack.commons.config.js'); +const TerserPlugin = require("terser-webpack-plugin"); +const HtmlMinimizerPlugin = require("html-minimizer-webpack-plugin"); +const CopyPlugin = require("copy-webpack-plugin"); +const path = require('path'); + +module.exports = merge(common, { + mode: 'production', + optimization: { + minimize: true, + minimizer: [ + new TerserPlugin({ + terserOptions: { + sourceMap: true + }, + }), + new HtmlMinimizerPlugin({ + minimizerOptions: { + caseSensitive: true, + collapseWhitespace: true, + conservativeCollapse: false, + keepClosingSlash: true, + minifyCSS: true, + minifyJS: true, + removeComments: true, + removeScriptTypeAttributes: true, + removeStyleLinkTypeAttributes: true, + }, + }), + ], + }, + devtool: 'source-map', + stats: 'normal', + module: { + rules: [ + { + test: /\.html$/i, + type: "asset/resource", + } + ], + }, + plugins: [ + new CopyPlugin({ + patterns: [ + { + context: path.resolve(__dirname, "public-src"), + from: "./*.html", + } + ], + }), + ], +});