]> rtime.felk.cvut.cz Git - coffee/coffee-flask.git/blobdiff - templates/main.js
Rename the class of the main div from "user" to "content"
[coffee/coffee-flask.git] / templates / main.js
index 1ceb6798ba38299f1dd5fedd093a61c7d5778105..9cc11f5351a4ff891aceb0bf4c3341c426d22fe4 100644 (file)
@@ -1,7 +1,14 @@
 var flask = "{{ url_for('hello', _external=True) }}"
 
-var updateRemote = undefined;
-var loggedIn = false;
+// State variables
+
+var updateRemote = undefined;           // defined iff remote server accessible
+var timeToLogout = undefined;           // defined during logout countdown
+var logoutTimer;
+var reloadTimer = undefined;
+var id_user;                            // ID of the user who is to be accounted for the next coffee
+var identifier_registration = false;    // true if identifier is supposed to be registered for user
+var eventMsg = undefined;               // Feedback message about the last event performed by the user
 
 console.log("hello from flask");
 //sendJSON("{\"type\":\"empty\"}");
@@ -10,89 +17,101 @@ function update(id, msg) {
     document.getElementById(id).innerHTML = msg;
 }
 
-function loadLocalStorage() {
+function replayOfflineQueue() {
     if (localStorage) {
-        if (localStorage.length) {
-            for (var i = 0; i < localStorage.length; i++) {
-                var value = localStorage.getItem(localStorage.key(i));
-                try {
-                    updateRemote(value);
-                } catch (err) {
-                    console.log("no json: " + value)
-                }
-            }
-            localStorage.clear();
+        let queue = JSON.parse(localStorage.getItem("offlineQueue")) || [];
+        if (Array.isArray(queue)) {
+            queue.forEach(function (entry) {
+                updateRemote(entry.data, new Date(entry.time));
+            });
+            localStorage.removeItem("offlineQueue");
         }
     }
 }
 
 var flavorChosen;
 
-function countingTimeLogout(count_time){
-    document.getElementById("logout_button").value = '\nlogout\n(' + count_time + ' s)';
-    if (count_time == 0) {
-        logout();
-    } else {
-        setTimeout(function() { countingTimeLogout(count_time - 1); }, 1000);
-    }
-}
-
-function updateNextStep()
+// Central function to update UI elements. To ensure that the UI is
+// consistent, other code should only change state variables and then
+// call this function. This function updates the UI to match the state.
+function updateUI()
 {
-    if (loggedIn) {
-       document.getElementById("nextStep").innerHTML = "Now select a beverage on the coffee machineā€¦";
-    } else {
-        if (flavorChosen !== undefined) {
-           document.getElementById("nextStep").innerHTML = "Enjoy your " + flavorChosen + "!";
-           flavorChosen=undefined;
-           countingTimeLogout(10); //mean 10 seconds
+    try {
+        let offline = updateRemote === undefined;
+
+        document.getElementById("local").style.display = !offline ? "none" : "block";
+        document.getElementById("remote").style.display = offline ? "none" : "block";
+
+        if (offline) {
+            showOfflineQueue();
+            return;
+        }
+
+        if (eventMsg !== undefined) {
+            update("eventMsg", eventMsg);
+            eventMsg = undefined;
         }
+        if (id_user !== undefined) {
+            document.getElementById("nextStep").innerHTML = "Now select a beverage on the coffee machineā€¦";
+        } else if (flavorChosen !== undefined) {
+            document.getElementById("nextStep").innerHTML = "Enjoy your " + flavorChosen + "!";
+        }
+
+        if (timeToLogout !== undefined)
+            document.getElementById("logout_button").innerHTML = '<br>logout<br>(' + timeToLogout + ' s)';
+    }
+    catch (err) {
+        console.log("updateUI error: ", err);
     }
 }
 
-function hiddenUpdateRemote(json) {
+function hiddenUpdateRemote(json, time = new Date()) {
     var msg = JSON.parse(json);
 
-    //update("json", "json: " + JSON.stringify(msg))
-
     switch(msg.type) {
         case "empty":
-            //update("json","");
             break;
         case "rfid":
-            /*update("json",
-                "uid: " + msg.uid + "<br>" +
-                "card type: " + msg.card_type + "<br>" +
-                "uid size: " + msg.size + " bytes<br>" +
-                "sak: " + msg.sak
-            );*/
-            login(msg.uid);
+            if (identifier_registration) {
+                ajax("POST", "user/identifier/add", JSON.stringify({ id: msg.uid }), "content");
+
+                addIdentifier_finish();
+            } else {
+                login(msg.uid);
+            }
             break;
         case "keys":
-            //update("json", "key: " + msg.key);
-            if (loggedIn) {
+            if (!identifier_registration) {
                 var flavor = getFlavor(msg.key);
                 if (flavor !== "") {
-                    addCoffee(flavor);
+                    addCoffee(flavor, time);
                 }
             }
             break;
-        case "fuck":
+        case "ajax_failure":
             ajax(msg.method, msg.route, msg.data, msg.id);
             break;
     }
+
     sendLog(json);
 }
 
 function loadRemote(string) {
     var xhr = new XMLHttpRequest();
     xhr.onreadystatechange = function() {
-        if (this.readyState == 4 && this.status == 200) {
-            update("remote", this.responseText);
-            updateRemote = hiddenUpdateRemote;
-            loadLocalStorage();
-            if (loggedIn) {
-                document.getElementById("local").style.display = "none";
+        if (this.readyState == 4) {
+            if (this.status == 200) {
+                update("remote", this.responseText);
+                updateRemote = hiddenUpdateRemote;
+                replayOfflineQueue();
+                updateUI();
+                clearTimeout(reloadTimer);
+            } else {
+                // Cancel current timer for the case when loadRemote()
+                // was called multiple times (e.g. multiple ajax()
+                // calls failed simultaneously).
+                clearTimeout(reloadTimer);
+                reloadTimer = setTimeout(loadRemote, 1000);
             }
         }
     };
@@ -108,22 +127,28 @@ function ajax(method, route, data, id) {
         if (this.readyState == 4) {
             if (this.status == 200) {
                 update(id, this.responseText);
-                updateNextStep();
+                updateUI();
             } else {
                 updateRemote = undefined;
-                update("remote", "<center>Server offline...</center>");
-                document.getElementById("local").style.display = "block";
+                updateUI();
+                loadRemote(); // Try to contact the server periodically
+
                 if (localStorage) {
-                    var now = Date.now();
-                    var fuck = JSON.stringify({
-                        type: "fuck",
+                    var ajax_failure = JSON.stringify({
+                        type: "ajax_failure",
                         method: method,
                         route: route,
                         data: data,
                         id: id
                     });
-                    localStorage.setItem(now, fuck);
-                    console.log(now + ": " + fuck);
+                    let queue = JSON.parse(localStorage.getItem("offlineQueue")) || [];
+                    queue.push({ time: Date.now(), data: ajax_failure });
+                    try {
+                        localStorage.setItem("offlineQueue", JSON.stringify(queue));
+                    }
+                    catch (err) {
+                        console.log(err);
+                    }
                 }
             }
         }
@@ -140,20 +165,34 @@ function ajax(method, route, data, id) {
 
 
 function login(id) {
-    ajax("POST", "login", id, "user");
-    loggedIn = true;
-    document.getElementById("local").style.display = "none";
+    ajax("POST", "login", id, "content");
+    id_user = id;
+    countingTimeLogout(120);
 }
 
 function logout() {
     sendReset();
-    ajax("GET", "logout", "", "user");
-    loggedIn = false;
-    document.getElementById("local").style.display = "block";
+    ajax("GET", "logout", "", "content");
+    id_user = undefined;
+    timeToLogout = undefined;
+    identifier_registration = false;
+    window.scrollTo(0, 0); // Scroll up
+}
+
+function countingTimeLogout(count_time)
+{
+    clearTimeout(logoutTimer);
+    timeToLogout = count_time;
+    updateUI();
+    if (count_time == 0) {
+        logout();
+    } else {
+        logoutTimer = setTimeout(function() { countingTimeLogout(count_time - 1); }, 1000);
+    }
 }
 
 function renameUser() {
-    ajax("GET", "user/rename?name=" +  document.getElementById("username").value, "", "user");
+    ajax("GET", "user/rename?name=" +  document.getElementById("username").value, "", "content");
 }
 
 function getFlavor(letter) {
@@ -166,18 +205,66 @@ function getFlavor(letter) {
     }
 }
 
-function addCoffee(flavor) {
+function addCoffee(flavor, time = new Date()) {
     var data = JSON.stringify({
-        time: new Date().toISOString(),
+        time: time.toISOString(),
         flavor: flavor
     });
-    if (loggedIn) {
-        ajax("POST", "coffee/add", data, "user");
+    if (id_user) {
+        ajax("POST", "coffee/add", data, "content");
         flavorChosen = flavor;
-        loggedIn = false;
+        id_user = undefined;
+        countingTimeLogout(10); //mean 10 seconds
+    }
+}
+
+
+function addEvent(event_name, action_msg, time = new Date()) {
+    var data = JSON.stringify({
+        time: time.toISOString(),
+        event_name: event_name,
+        uid: id_user
+    });
+    if (id_user) {
+        eventMsg = "You have " + action_msg + ". Thanks!"
+        ajax("POST", "event", data, "content");
+        window.scrollTo(0, 0); // Scroll up
     }
 }
 
+
+function addIdentifier_start() {
+    identifier_registration = true;
+    document.getElementById("addIdentifier").disabled = true;
+    document.getElementById("labelIdentifier").style.visibility = "visible";
+    document.getElementById("abortIdentifier").disabled = false;
+}
+
+function addIdentifier_finish() {
+    identifier_registration = false;
+    document.getElementById("addIdentifier").disabled = false;
+    document.getElementById("labelIdentifier").style.visibility = "hidden";
+    document.getElementById("abortIdentifier").disabled = true;
+}
+
+function disableIdentifier(id) {
+    ajax("POST", "user/identifier/disable", JSON.stringify({ id: id }), "content");
+}
+
+function renameIdentifier(i) {
+    var data = JSON.stringify({
+        id: document.getElementById("identifier_" + i).innerText,
+        name: document.getElementById("identifier_name_" + i).value
+    });
+
+    ajax("POST", "user/identifier/rename", data, "content");
+}
+
 function sendLog(json) {
     ajax("POST", "log", json, "log");
 }
+
+function tellCoffeebot(what)
+{
+    ajax("POST", "tellCoffeebot", JSON.stringify({text: what}), "log");
+}