Skip to content

Commit 28eb722

Browse files
authored
Merge pull request #757 from parallaxinc/merge_1.0.7
Release 1.7.0
2 parents 40f09ea + c0485f2 commit 28eb722

File tree

89 files changed

+23578
-15473
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+23578
-15473
lines changed

.github/workflows/solo-develop.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Solo Test
1+
name: Solo-Test
22

33
on:
44
push:

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,6 @@ dist
2929
# SASS outputs
3030
src/scss/*.css
3131
src/scss/*.map
32+
33+
# Shell scripts
34+
*.sh

package-lock.json

Lines changed: 16038 additions & 9905 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 53 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
{
22
"name": "blocklyprop-solo",
3-
"version": "1.6.0",
3+
"version": "1.7.0",
44
"description": "A simplified implementation of Google's Blockly project configured to support Parallax robots and sensors.",
5-
"main": "load_images.js",
5+
"main": "./index.js",
66
"scripts": {
7-
"compile:sass": "sass sass/main.scss dist/main.css -w",
8-
"dev": "npm run build:sass; webpack --config webpack/dev.config.js --node-env development --watch",
7+
"compile:sass": "sass src/scss/main.scss dist/main.css",
8+
"dev": "rm -rdf ./dist/*; npm run build:sass; webpack --config webpack/dev.config.js --node-env development",
99
"dev:analyze": "npm run dev -- --env.addons=bundleanalyzer",
10-
"build": "webpack --config webpack/prod.config.js --node-env production --stats",
11-
"build:deploy": "rm -rdf ./dist/*; npm run build:sass; webpack --config webpack/prod.config.js --node-env production --stats",
10+
"build": "SOLO_DEV_MODE=false; SOLO_RELEASE=1.7.0; npm run build:sass; webpack --config webpack/prod.config.js --node-env production --stats",
11+
"build:deploy": "rm -rdf ./dist/*; npm run build:sass; SOLO_DEV_MODE=false webpack --config webpack/prod.config.js --node-env production --stats",
1212
"build:analyze": "npm run build -- --env.addons=bundleanalyzer",
13-
"build:sass": "npx sass src/scss/main.scss dist/main.css",
13+
"build:sass": "npx sass src/scss/main.scss src/scss/main.css",
1414
"build:test": "ls ./dist/*",
1515
"lint": "eslint \"src/modules/**/*.js\"",
1616
"profile": "webpack --profile --json --config webpack/dev.config.js > stats.json",
@@ -33,56 +33,67 @@
3333
},
3434
"homepage": "https://github.com/parallaxinc/solo#readme",
3535
"dependencies": {
36-
"@mapbox/node-pre-gyp": "^1.0.4",
37-
"@sentry/browser": "^6.10.0",
38-
"@sentry/tracing": "^6.10.0",
36+
"@mapbox/node-pre-gyp": "^1.0.7",
3937
"ace-builds": "^1.4.8",
40-
"blockly": "^3.20191014.4",
41-
"bootbox": "^5.4.0",
42-
"bootstrap": "^3.4.1",
38+
"blockly": "^3.20200924.4",
39+
"bootbox": "^5.5.3",
4340
"chartist": "^0.11.4",
44-
"dotenv": "^8.2.0",
41+
"clean-webpack-plugin": "^4.0.0",
42+
"dotenv": "^8.6.0",
4543
"file-saver": "^2.0.5",
46-
"jquery": "^3.5.1",
47-
"jquery-validation": "^1.19.3",
48-
"jszip": "^3.3.0",
44+
"jquery": "^3.6.1",
45+
"jquery-validation": "^1.19.5",
46+
"jszip": "^3.10.0",
4947
"node-chartist": "^1.0.5",
5048
"stream": "0.0.2",
51-
"websocket-extensions": ">=0.1.4"
49+
"websocket-extensions": ">=0.1.4",
50+
"workbox-background-sync": "6.5.4",
51+
"workbox-broadcast-update": "6.5.4",
52+
"workbox-cacheable-response": "6.5.4",
53+
"workbox-core": "6.5.4",
54+
"workbox-expiration": "6.5.4",
55+
"workbox-navigation-preload": "6.5.4",
56+
"workbox-precaching": "6.5.4",
57+
"workbox-routing": "6.5.4",
58+
"workbox-strategies": "6.5.4",
59+
"workbox-window": "6.5.4"
5260
},
5361
"devDependencies": {
5462
"@types/ace": "0.0.43",
5563
"acorn": "^7.1.1",
56-
"chai": "^4.3.4",
64+
"chai": "^4.3.6",
65+
"compression-webpack-plugin": "^10.0.0",
5766
"copy-webpack-plugin": "^7.0.0",
58-
"css-loader": "^5.2.4",
67+
"css-loader": "^5.2.7",
5968
"elliptic": "^6.5.4",
60-
"eslint": "^6.6.0",
69+
"eslint": "^6.8.0",
6170
"eslint-config-google": "^0.14.0",
62-
"html-webpack-plugin": "^5.3.1",
63-
"mini-css-extract-plugin": "^2.1.0",
64-
"minimist": "^1.2.5",
65-
"mocha": "^8.3.2",
71+
"html-webpack-plugin": "^5.5.0",
72+
"mini-css-extract-plugin": "^2.6.0",
73+
"minimist": "^1.2.6",
74+
"mocha": "^10.1.0",
6675
"node-env-webpack-plugin": "^1.1.0",
67-
"postcss-loader": "^6.1.1",
68-
"postcss-preset-env": "^6.7.0",
69-
"sass": "^1.36.0",
70-
"sass-loader": "^12.1.0",
71-
"selenium-standalone": "^6.23.0",
72-
"selenium-webdriver": "^4.0.0-alpha.7",
73-
"selfsigned": "^1.10.8",
74-
"sinon": "^10.0.1",
75-
"style-loader": "^1.1.3",
76-
"terser-webpack-plugin": "^5.1.2",
77-
"urijs": "^1.19.7",
76+
"postcss-loader": "^6.2.1",
77+
"postcss-preset-env": "^6.7.1",
78+
"sass": "^1.52.3",
79+
"sass-loader": "^12.6.0",
80+
"selenium-standalone": "^6.24.0",
81+
"selenium-webdriver": "^4.2.0",
82+
"selfsigned": "^2.0.1",
83+
"sinon": "^13.0.2",
84+
"style-loader": "^1.3.0",
85+
"terser-webpack-plugin": "^5.3.3",
86+
"urijs": "^1.19.11",
7887
"watchpack-chokidar2": "^2.0.1",
79-
"webdriverio": "^7.5.3",
80-
"webpack": "^5.47.0",
81-
"webpack-bundle-analyzer": "^4.4.1",
82-
"webpack-cli": "^4.7.0",
83-
"webpack-merge": "^5.7.3"
88+
"webdriverio": "^7.20.2",
89+
"webpack": "^5.75.0",
90+
"webpack-bundle-analyzer": "^4.7.0",
91+
"webpack-cli": "^4.10.0",
92+
"webpack-merge": "^5.8.0",
93+
"workbox-build": "6.5.4",
94+
"workbox-webpack-plugin": "^6.5.4"
8495
},
8596
"optionalDependencies": {
86-
"fsevents": "^2.1.3"
97+
"fsevents": "^2.3.2"
8798
}
8899
}

src/LICENSE

Lines changed: 0 additions & 21 deletions
This file was deleted.
23.3 KB
27.7 KB
30.3 KB
43.2 KB
14.2 KB
74.4 KB
4.68 KB
166 KB
8.94 KB
14.5 KB

src/images/icons/checkmark-green.png

1.06 KB

src/images/icons/checkmark-white.png

593 Bytes
789 Bytes

src/images/icons/danger-triangle.png

1.3 KB

src/images/icons/downarrow-box.png

429 Bytes

src/images/icons/downarrow-white.png

410 Bytes

src/images/icons/graph-white.png

686 Bytes
File renamed without changes.
File renamed without changes.
File renamed without changes.

src/images/icons/src/checkmark-green.svg

src/images/icons/src/checkmark-white.svg

src/images/icons/src/danger-triangle.svg

src/images/icons/src/downarrow-box.svg

src/images/icons/src/downarrow-white.svg

src/images/icons/src/graph-white.svg

Lines changed: 1 addition & 0 deletions

src/images/icons/src/search-white.svg

Lines changed: 1 addition & 0 deletions

src/images/icons/src/terminal-white.svg

src/images/icons/terminal-white.png

575 Bytes

src/images/icons/warningCircle.png

1.8 KB

src/images/lang-icons/c.png

-1.13 KB
Binary file not shown.

src/images/lang-icons/spin.png

-4.27 KB
Binary file not shown.

src/index.js

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
/*
2+
* TERMS OF USE: MIT License
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a
5+
* copy of this software and associated documentation files (the "Software"),
6+
* to deal in the Software without restriction, including without limitation
7+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+
* and/or sell copies of the Software, and to permit persons to whom the
9+
* Software is furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL
17+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20+
* DEALINGS IN THE SOFTWARE.
21+
*/
22+
23+
import {initToolbarIcons} from './modules/load_images';
24+
import {Workbox} from 'workbox-window';
25+
import {logConsoleMessage} from './modules/utility';
26+
27+
28+
/**
29+
* Initialize deferredPrompt for use later to show browser install prompt.
30+
* @type {BeforeInstallPromptEvent}
31+
*/
32+
export let deferredPrompt;
33+
34+
/**
35+
* Flag to indicate that the app is installed and active.
36+
* @type {boolean}
37+
*/
38+
export let pwaActive = false;
39+
40+
41+
// Load the service worker if the browser supports it.
42+
if ("serviceWorker" in navigator) {
43+
// Register the service worker only after the page load is complete. This
44+
// will ensure that all page assets have been loaded before the service worker
45+
// is registered. The service worker will begin loading assets into a local
46+
// cache once it is registered.
47+
window.addEventListener("load", () => {
48+
logConsoleMessage(`Page has been loaded. Register the root service worker.`)
49+
// Do nothing if the app is already installed
50+
if (pwaActive) {
51+
return;
52+
}
53+
54+
const installButtonElement = document.getElementById('btn-install-pwa');
55+
let wb = null;
56+
57+
pwaBeforeInstall();
58+
59+
try {
60+
logConsoleMessage(`Newing a WorkBox object`);
61+
wb = new Workbox("./sw.js");
62+
logConsoleMessage(`Workbox object created`);
63+
} catch (err) {
64+
logConsoleMessage(`Workbox init failed: ${err.message}`);
65+
return;
66+
}
67+
68+
installButtonElement.addEventListener('click', async () => {
69+
console.log(`User clicked the install app button.`)
70+
71+
// deferredPrompt is a global variable we've been using in the sample to capture the `beforeinstallevent`
72+
deferredPrompt.prompt();
73+
74+
// Find out whether the user confirmed the installation or not
75+
const {outcome} = await deferredPrompt.userChoice;
76+
77+
// The deferredPrompt can only be used once.
78+
deferredPrompt = null;
79+
80+
// Act on the user's choice
81+
if (outcome === 'accepted') {
82+
console.log('User accepted the install prompt.');
83+
} else if (outcome === 'dismissed') {
84+
console.log('User dismissed the install prompt');
85+
}
86+
87+
// Hide the 'Install' button
88+
pwaInstallButton(false);
89+
});
90+
91+
// Fires when the registered service worker has installed but is waiting to activate.
92+
wb.addEventListener("waiting", (event) => {
93+
logConsoleMessage(`Service worker is installed but waiting to activate...`);
94+
logConsoleMessage(`Waiting event: ${event}`);
95+
96+
// Hide the 'install' button
97+
pwaInstallButton(false);
98+
99+
const button = document.getElementById('btn-install-pwa');
100+
button.addEventListener("click", (event) => {
101+
console.log(`Install button clicked.`, event)
102+
103+
// Set up a listener that will reload the page as soon as the previously
104+
// waiting service worker has taken control.
105+
wb.addEventListener("controlling", () => {
106+
window.location.reload();
107+
});
108+
109+
// Send a message telling the service worker to skip waiting.
110+
// This will trigger the `controlling` event handler above.
111+
wb.messageSW({type: "SKIP_WAITING"});
112+
113+
// It may seem that this is the same as registering a service worker yourself using
114+
// navigator.serviceWorker.register. However, Workbox.register takes care of waiting
115+
// until the window load event before registering the service worker. This is desirable
116+
// in situations where precaching is involved so bandwidth contention that may delay
117+
// page startup can be avoided.
118+
wb.register();
119+
});
120+
});
121+
122+
// Intercept the browser's prompt to install the application
123+
//
124+
// The 'beforeinstallprompt' event fires on devices when a user is about to
125+
// be prompted to "install" a web application. It may be saved for later
126+
// and used to prompt the user at a more suitable time.
127+
//
128+
// Here, the event details are stored in a global variable, deferredPrompt,
129+
// that will be referenced later.
130+
// ----------------------------------------------------------------------------
131+
window.addEventListener('beforeinstallprompt', (e) => {
132+
console.log(`Before install prompt fires...`);
133+
134+
// Log the platforms that the beforeinstallprompt event was sent to.
135+
// The platforms property is an array of strings. Typically, it should
136+
// contain a single element, 'web', when the site is viewed from a web
137+
// browser.
138+
console.log(`Platforms: ${e.platforms}`);
139+
140+
// Prevent the mini-info bar from appearing on mobile
141+
e.preventDefault();
142+
143+
// Stash the event so it can be triggered later.
144+
deferredPrompt = e;
145+
146+
// Update UI notify the user they can install the PWA
147+
// showInstallPromotion();
148+
149+
return false;
150+
});
151+
});
152+
}
153+
154+
/**
155+
* Install listener for the 'beforeinstallprompt' event.
156+
* @param {HTMLElement} button
157+
*/
158+
function pwaBeforeInstall() {
159+
window.addEventListener('beforeinstallprompt', (event) => {
160+
console.log(`BeforeInstallPrompt...`)
161+
162+
// Prevent the mini-info bar from appearing on mobile.
163+
event.preventDefault();
164+
165+
// Stash the event so it can be triggered later.
166+
window.deferredPrompt = event;
167+
168+
// Remove the 'hidden' class from the 'install' button container.
169+
console.log(`Show the install button on the toolbar`)
170+
171+
// Temporarily disable the 'install' button while the details of updating
172+
// a pwa are addressed.
173+
// pwaInstallButton(true);
174+
pwaInstallButton(false);
175+
});
176+
}
177+
178+
function showInstallPromotion() {
179+
console.log(`Prompt the user to install the application.`)
180+
}
181+
182+
/**
183+
* Unregister the application from the browser.
184+
*/
185+
function serviceWorkerUnregister() {
186+
navigator.serviceWorker.getRegistrations()
187+
.then(function(registrations) {
188+
for(let registration of registrations) {
189+
registration.unregister()
190+
}
191+
});
192+
}
193+
194+
/**
195+
* Set the state of the PWA installation button
196+
* @param {boolean} enable
197+
*/
198+
export function pwaInstallButton(enable) {
199+
const installButtonElement = document.getElementById('btn-install-pwa');
200+
if (enable) {
201+
logConsoleMessage(`Showing PWA Install button`);
202+
installButtonElement.classList.remove("hidden");
203+
} else {
204+
logConsoleMessage(`Hiding PWA Install button`);
205+
installButtonElement.classList.add("hidden");
206+
}
207+
}
208+
209+
210+
/**
211+
* Set the state of the PWA update button
212+
* @param {boolean} enable
213+
*/
214+
function pwaUpdateButton(enable) {
215+
216+
}
217+
218+
219+
function getPWADisplayMode() {
220+
const isStandalone = window.matchMedia('(display-mode: standalone)').matches;
221+
if (document.referrer.startsWith('android-app://')) {
222+
return 'twa';
223+
} else if (navigator.standalone || isStandalone) {
224+
return 'standalone';
225+
}
226+
return 'browser';
227+
}
228+
229+
initToolbarIcons();
230+
231+
logConsoleMessage(`Starting the editor...`);
232+
233+
import './modules/editor';

0 commit comments

Comments
 (0)