diff --git a/browser/devtools/webide/content/webide.js b/browser/devtools/webide/content/webide.js
index 04ebb37c950..4b996fdd21e 100644
--- a/browser/devtools/webide/content/webide.js
+++ b/browser/devtools/webide/content/webide.js
@@ -138,6 +138,8 @@ let UI = {
this.updateProjectButton();
this.updateProjectEditorHeader();
break;
+ case "install-progress":
+ this.updateProgress(Math.round(100 * details.bytesSent / details.totalBytes));
};
},
@@ -169,34 +171,71 @@ let UI = {
}
},
+ /********** BUSY UI **********/
+
+ _busyTimeout: null,
+ _busyOperationDescription: null,
+ _busyPromise: null,
+
+ updateProgress: function(percent) {
+ let progress = document.querySelector("#action-busy-determined");
+ progress.mode = "determined";
+ progress.value = percent;
+ this.setupBusyTimeout();
+ },
+
busy: function() {
this.hidePanels();
- document.querySelector("window").classList.add("busy")
+ let win = document.querySelector("window");
+ win.classList.add("busy")
+ win.classList.add("busy-undetermined");
this.updateCommands();
},
unbusy: function() {
- document.querySelector("window").classList.remove("busy")
+ let win = document.querySelector("window");
+ win.classList.remove("busy")
+ win.classList.remove("busy-determined");
+ win.classList.remove("busy-undetermined");
this.updateCommands();
this._busyPromise = null;
},
+ setupBusyTimeout: function() {
+ this.cancelBusyTimeout();
+ this._busyTimeout = setTimeout(() => {
+ this.unbusy();
+ UI.reportError("error_operationTimeout", this._busyOperationDescription);
+ this._busyPromise.reject("promise timeout: " + this._busyOperationDescription);
+ }, 30000);
+ },
+
+ cancelBusyTimeout: function() {
+ clearTimeout(this._busyTimeout);
+ },
+
+ busyWithProgressUntil: function(promise, operationDescription) {
+ this.busyUntil(promise, operationDescription);
+ let win = document.querySelector("window");
+ let progress = document.querySelector("#action-busy-determined");
+ progress.mode = "undetermined";
+ win.classList.add("busy-determined");
+ win.classList.remove("busy-undetermined");
+ },
+
busyUntil: function(promise, operationDescription) {
// Freeze the UI until the promise is resolved. A 30s timeout
// will unfreeze the UI, just in case the promise never gets
// resolved.
this._busyPromise = promise;
- let timeout = setTimeout(() => {
- this.unbusy();
- UI.reportError("error_operationTimeout", operationDescription);
- promise.reject("promise timeout: " + operationDescription);
- }, 30000);
+ this._busyOperationDescription = operationDescription;
+ this.setupBusyTimeout();
this.busy();
promise.then(() => {
- clearTimeout(timeout);
+ this.cancelBusyTimeout();
this.unbusy();
}, (e) => {
- clearTimeout(timeout);
+ this.cancelBusyTimeout();
UI.reportError("error_operationFail", operationDescription);
console.error(e);
this.unbusy();
@@ -396,6 +435,12 @@ let UI = {
return;
}
+ // Save last project location
+
+ if (project.location) {
+ Services.prefs.setCharPref("devtools.webide.lastprojectlocation", project.location);
+ }
+
// Make sure the directory exist before we show Project Editor
let forceDetailsOnly = false;
@@ -420,10 +465,6 @@ let UI = {
this.getProjectEditor().then(() => {
this.updateProjectEditorHeader();
}, console.error);
-
- if (project.location) {
- Services.prefs.setCharPref("devtools.webide.lastprojectlocation", project.location);
- }
},
/********** DECK **********/
@@ -823,12 +864,11 @@ let Cmds = {
play: function() {
switch(AppManager.selectedProject.type) {
case "packaged":
+ return UI.busyWithProgressUntil(AppManager.installAndRunProject(), "installing and running app");
case "hosted":
return UI.busyUntil(AppManager.installAndRunProject(), "installing and running app");
- break;
case "runtimeApp":
return UI.busyUntil(AppManager.runRuntimeApp(), "running app");
- break;
}
return promise.reject();
},
diff --git a/browser/devtools/webide/content/webide.xul b/browser/devtools/webide/content/webide.xul
index 16cac8db20f..ec31544858b 100644
--- a/browser/devtools/webide/content/webide.xul
+++ b/browser/devtools/webide/content/webide.xul
@@ -102,7 +102,10 @@
-
+
+
+
+
diff --git a/browser/devtools/webide/modules/app-manager.js b/browser/devtools/webide/modules/app-manager.js
index a82a1d2fc53..a62b8668a69 100644
--- a/browser/devtools/webide/modules/app-manager.js
+++ b/browser/devtools/webide/modules/app-manager.js
@@ -59,11 +59,15 @@ exports.AppManager = AppManager = {
this.trackWiFiRuntimes();
this.trackSimulatorRuntimes();
+ this.onInstallProgress = this.onInstallProgress.bind(this);
+ AppActorFront.on("install-progress", this.onInstallProgress);
+
this.observe = this.observe.bind(this);
Services.prefs.addObserver(WIFI_SCANNING_PREF, this, false);
},
uninit: function() {
+ AppActorFront.off("install-progress", this.onInstallProgress);
this._unlistenToApps();
this.selectedProject = null;
this.selectedRuntime = null;
@@ -134,6 +138,10 @@ exports.AppManager = AppManager = {
this.update("connection");
},
+ onInstallProgress: function(event, details) {
+ this.update("install-progress", details);
+ },
+
onWebAppsStoreready: function() {
this.update("runtime-apps-found");
},
diff --git a/browser/devtools/webide/themes/webide.css b/browser/devtools/webide/themes/webide.css
index ef876951957..fe16b3a8849 100644
--- a/browser/devtools/webide/themes/webide.css
+++ b/browser/devtools/webide/themes/webide.css
@@ -21,13 +21,15 @@
pointer-events: auto;
}
-#action-busy {
+#action-busy-undetermined {
height: 24px;
width: 24px;
}
window.busy .action-button,
-window:not(.busy) #action-busy {
+window:not(.busy) #action-busy,
+window.busy-undetermined #action-busy-determined,
+window.busy-determined #action-busy-undetermined {
display: none;
}