Jelajahi Sumber

Added loader for long bakes and improved initial loading sequence

n1474335 8 tahun lalu
induk
melakukan
78d0369e71

+ 6 - 0
src/core/ChefWorker.js

@@ -12,6 +12,12 @@ import Chef from "./Chef.js";
 // Set up Chef instance
 self.chef = new Chef();
 
+// Tell the app that the worker has loaded and is ready to operate
+self.postMessage({
+    action: "workerLoaded",
+    data: {}
+});
+
 /**
  * Respond to message from parent thread.
  *

+ 20 - 15
src/web/App.js

@@ -54,6 +54,8 @@ App.prototype.setup = function() {
     this.resetLayout();
     this.setCompileMessage();
     this.loadURIParams();
+
+    this.appLoaded = true;
     this.loaded();
 };
 
@@ -62,6 +64,10 @@ App.prototype.setup = function() {
  * Fires once all setup activities have completed.
  */
 App.prototype.loaded = function() {
+    // Check that both the app and the worker have loaded successfully before
+    // removing the loading screen.
+    if (!this.worderLoaded || !this.appLoaded) return;
+
     // Trigger CSS animations to remove preloader
     document.body.classList.add("loaded");
 
@@ -97,25 +103,20 @@ App.prototype.handleError = function(err) {
 App.prototype.setBakingStatus = function(bakingStatus) {
     this.baking = bakingStatus;
 
-    let inputLoadingIcon = document.querySelector("#input .title .loading-icon"),
-        outputLoadingIcon = document.querySelector("#output .title .loading-icon"),
-        inputElement = document.querySelector("#input-text"),
-        outputElement = document.querySelector("#output-text");
+    let outputLoader = document.getElementById("output-loader"),
+        outputElement = document.getElementById("output-text");
 
     if (bakingStatus) {
-        inputLoadingIcon.style.display = "inline-block";
-        outputLoadingIcon.style.display = "inline-block";
-        inputElement.classList.add("disabled");
-        inputElement.disabled = true;
-        outputElement.classList.add("disabled");
-        outputElement.disabled = true;
+        this.bakingStatusTimeout = setTimeout(function() {
+            outputElement.disabled = true;
+            outputLoader.style.visibility = "visible";
+            outputLoader.style.opacity = 1;
+        }, 200);
     } else {
-        inputLoadingIcon.style.display = "none";
-        outputLoadingIcon.style.display = "none";
-        inputElement.classList.remove("disabled");
-        inputElement.disabled = false;
-        outputElement.classList.remove("disabled");
+        clearTimeout(this.bakingStatusTimeout);
         outputElement.disabled = false;
+        outputLoader.style.opacity = 0;
+        outputLoader.style.visibility = "hidden";
     }
 };
 
@@ -160,6 +161,10 @@ App.prototype.handleChefMessage = function(e) {
             break;
         case "silentBakeComplete":
             break;
+        case "workerLoaded":
+            this.worderLoaded = true;
+            this.loaded();
+            break;
         default:
             console.error("Unrecognised message from ChefWorker", e);
             break;

+ 0 - 6
src/web/ControlsWaiter.js

@@ -79,9 +79,6 @@ ControlsWaiter.prototype.setAutoBake = function(value) {
  */
 ControlsWaiter.prototype.bakeClick = function() {
     this.app.bake();
-    const outputText = document.getElementById("output-text");
-    outputText.focus();
-    outputText.setSelectionRange(0, 0);
 };
 
 
@@ -90,9 +87,6 @@ ControlsWaiter.prototype.bakeClick = function() {
  */
 ControlsWaiter.prototype.stepClick = function() {
     this.app.bake(true);
-    const outputText = document.getElementById("output-text");
-    outputText.focus();
-    outputText.setSelectionRange(0, 0);
 };
 
 

+ 4 - 3
src/web/html/index.html

@@ -76,7 +76,7 @@
     <body>
         <!-- Preloader overlay -->
         <div id="loader-wrapper">
-            <div id="preloader"></div>
+            <div id="preloader" class="loader"></div>
             <div id="preloader-msg"></div>
         </div>
         <!-- End preloader overlay -->
@@ -148,7 +148,6 @@
                     <div id="input" class="split no-select">
                         <div class="title no-select">
                             <label for="input-text">Input</label>
-                            <div class="loading-icon" style="display: none"></div>
                             <div class="btn-group io-btn-group">
                                 <button type="button" class="btn btn-default btn-sm" id="clr-io"><img aria-hidden="true" src="<%- require('../static/images/recycle-16x16.png') %>" alt="Recycle Icon"/> Clear I/O</button>
                                 <button type="button" class="btn btn-default btn-sm" id="reset-layout"><img aria-hidden="true" src="<%- require('../static/images/layout-16x16.png') %>" alt="Grid Icon"/> Reset layout</button>
@@ -165,7 +164,6 @@
                     <div id="output" class="split">
                         <div class="title no-select">
                             <label for="output-text">Output</label>
-                            <div class="loading-icon" style="display: none"></div>
                             <div class="btn-group io-btn-group">
                                 <button type="button" class="btn btn-default btn-sm" id="save-to-file" title="Save to file"><img aria-hidden="true" src="<%- require('../static/images/save_as-16x16.png') %>" alt="Save Icon"/> Save to file</button>
                                 <button type="button" class="btn btn-default btn-sm" id="switch" title="Move output to input"><img aria-hidden="true" src="<%- require('../static/images/switch-16x16.png') %>" alt="Switch Icon"/> Move output to input</button>
@@ -179,6 +177,9 @@
                             <div id="output-highlighter" class="no-select"></div>
                             <div id="output-html"></div>
                             <textarea id="output-text" readonly="readonly"></textarea>
+                            <div id="output-loader">
+                                <div class="loader"></div>
+                            </div>
                         </div>
                     </div>
                 </div>

+ 14 - 22
src/web/stylesheets/layout/_io.css

@@ -22,8 +22,6 @@
     background-color: transparent;
     white-space: pre-wrap;
     word-wrap: break-word;
-
-    transition: all 0.5s ease;
 }
 
 #output-html {
@@ -65,6 +63,20 @@
     border: none;
 }
 
+#output-loader {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    margin: 0;
+    background-color: var(--primary-background-colour);
+    visibility: hidden;
+    opacity: 0; 
+
+    transition: all 0.5s ease;
+}
+
 .io-btn-group {
     float: right;
     margin-top: -4px;
@@ -89,23 +101,3 @@
 .dropping-file {
     border: 5px dashed var(--drop-file-border-colour) !important;
 }
-
-@keyframes spinner {
-    from {
-        transform: rotate(0deg);
-    }
-    to {
-        transform: rotate(359deg);
-    }
-}
-
-.loading-icon::before {
-    content: "\21bb";
-}
-
-.loading-icon {
-    animation-name: spinner;
-    animation-duration: 1000ms;
-    animation-iteration-count: infinite;
-    animation-timing-function: linear;
-}

+ 5 - 7
src/web/stylesheets/preloader.css

@@ -16,7 +16,7 @@
     background-color: var(--secondary-border-colour);
 }
 
-#preloader {
+.loader {
     display: block;
     position: relative;
     left: 50%;
@@ -28,20 +28,19 @@
     border: 3px solid transparent;
     border-top-color: #3498db;
     border-radius: 50%;
-    z-index: 1500;
 
     animation: spin 2s linear infinite;
 }
 
-#preloader:before,
-#preloader:after {
+.loader:before,
+.loader:after {
     content: "";
     position: absolute;
     border: 3px solid transparent;
     border-radius: 50%;
 }
 
-#preloader:before {
+.loader:before {
     top: 5px;
     left: 5px;
     right: 5px;
@@ -50,7 +49,7 @@
     animation: spin 3s linear infinite;
 }
 
-#preloader:after {
+.loader:after {
     top: 13px;
     left: 13px;
     right: 13px;
@@ -77,7 +76,6 @@
 
 
 /* Loaded */
-.loaded #preloader,
 .loaded #preloader-msg {
     opacity: 0;
     transition: all 0.3s ease-out;