]> rtime.felk.cvut.cz Git - coffee/coffee-flask.git/blob - templates/main.js
8135983b75c8bdbee3570c81e2738047564b3867
[coffee/coffee-flask.git] / templates / main.js
1 var flask = "{{ url_for('hello', _external=True) }}"
2
3 // State variables
4
5 var updateRemote = undefined;   // defined iff remote server accessible
6 var timeToLogout = undefined;   // defined during logout countdown
7 var logoutTimer;
8 var reloadTimer = undefined;
9 var id_user;                    // ID of the user who is to be accounted for the next coffee
10
11 console.log("hello from flask");
12 //sendJSON("{\"type\":\"empty\"}");
13
14 function update(id, msg) {
15     document.getElementById(id).innerHTML = msg;
16 }
17
18 function replayOfflineQueue() {
19     if (localStorage) {
20         let queue = JSON.parse(localStorage.getItem("offlineQueue")) || [];
21         if (Array.isArray(queue)) {
22             queue.forEach(function (entry) {
23                 updateRemote(entry.data, new Date(entry.time));
24             });
25             localStorage.removeItem("offlineQueue");
26         }
27     }
28 }
29
30 var flavorChosen;
31
32 // Central function to update UI elements. To ensure that the UI is
33 // consistent, other code should only change state variables and then
34 // call this function. This function updates the UI to match the state.
35 function updateUI()
36 {
37     try {
38         let offline = updateRemote === undefined;
39
40         document.getElementById("local").style.display = !offline ? "none" : "block";
41         document.getElementById("remote").style.display = offline ? "none" : "block";
42
43         if (offline) {
44             showOfflineQueue();
45             return;
46         }
47
48         if (id_user !== undefined) {
49             document.getElementById("nextStep").innerHTML = "Now select a beverage on the coffee machineā€¦";
50         } else {
51             document.getElementById("nextStep").innerHTML = "Enjoy your " + flavorChosen + "!";
52         }
53
54         if (timeToLogout !== undefined)
55             document.getElementById("logout_button").innerHTML = '<br>logout<br>(' + timeToLogout + ' s)';
56     }
57     catch (err) {
58         console.log("Error: ", err);
59     }
60 }
61
62 function hiddenUpdateRemote(json, time = new Date()) {
63     var msg = JSON.parse(json);
64
65     switch(msg.type) {
66         case "empty":
67             break;
68         case "rfid":
69             login(msg.uid);
70             break;
71         case "keys":
72             var flavor = getFlavor(msg.key);
73             if (flavor !== "") {
74                 addCoffee(flavor, time);
75             }
76             break;
77         case "ajax_failure":
78             ajax(msg.method, msg.route, msg.data, msg.id);
79             break;
80     }
81     sendLog(json);
82 }
83
84 function loadRemote(string) {
85     var xhr = new XMLHttpRequest();
86     xhr.onreadystatechange = function() {
87         if (this.readyState == 4) {
88             if (this.status == 200) {
89                 update("remote", this.responseText);
90                 updateRemote = hiddenUpdateRemote;
91                 replayOfflineQueue();
92                 updateUI();
93                 clearTimeout(reloadTimer);
94             } else {
95                 // Cancel current timer for the case when loadRemote()
96                 // was called multiple times (e.g. multiple ajax()
97                 // calls failed simultaneously).
98                 clearTimeout(reloadTimer);
99                 reloadTimer = setTimeout(loadRemote, 1000);
100             }
101         }
102     };
103     xhr.open("GET", flask, true);
104     xhr.send();
105 }
106
107 loadRemote();
108
109 function ajax(method, route, data, id) {
110     var xhr = new XMLHttpRequest();
111     xhr.onreadystatechange = function() {
112         if (this.readyState == 4) {
113             if (this.status == 200) {
114                 update(id, this.responseText);
115                 updateUI();
116             } else {
117                 updateRemote = undefined;
118                 updateUI();
119                 loadRemote(); // Try to contact the server periodically
120
121                 if (localStorage) {
122                     var ajax_failure = JSON.stringify({
123                         type: "ajax_failure",
124                         method: method,
125                         route: route,
126                         data: data,
127                         id: id
128                     });
129                     let queue = JSON.parse(localStorage.getItem("offlineQueue")) || [];
130                     queue.push({ time: Date.now(), data: ajax_failure });
131                     try {
132                         localStorage.setItem("offlineQueue", JSON.stringify(queue));
133                     }
134                     catch (err) {
135                         console.log(err);
136                     }
137                 }
138             }
139         }
140     };
141     xhr.open(method, flask + route, true);
142     xhr.withCredentials = true;
143     xhr.setRequestHeader("Content-type", "application/json");
144     if (method === "POST") {
145         xhr.send(data);
146     } else {
147         xhr.send();
148     }
149 }
150
151
152 function login(id) {
153     ajax("POST", "login", id, "user");
154     id_user = id;
155     countingTimeLogout(120);
156 }
157
158 function logout() {
159     sendReset();
160     ajax("GET", "logout", "", "user");
161     id_user = undefined;
162     timeToLogout = undefined;
163 }
164
165 function countingTimeLogout(count_time)
166 {
167     clearTimeout(logoutTimer);
168     timeToLogout = count_time;
169     updateUI();
170     if (count_time == 0) {
171         logout();
172     } else {
173         logoutTimer = setTimeout(function() { countingTimeLogout(count_time - 1); }, 1000);
174     }
175 }
176
177 function renameUser() {
178     ajax("GET", "user/rename?name=" +  document.getElementById("username").value, "", "user");
179 }
180
181 function getFlavor(letter) {
182     switch (letter) {
183         case "E": return "espresso";
184         case "C": return "cappuccino";
185         case "B": return "latte macchiato";
186         case "D": return "espresso lungo";
187         default: return "";
188     }
189 }
190
191 function addCoffee(flavor, time = new Date()) {
192     var data = JSON.stringify({
193         time: time.toISOString(),
194         flavor: flavor,
195         uid: id_user
196     });
197     if (id_user) {
198         ajax("POST", "coffee/add", data, "user");
199         flavorChosen = flavor;
200         id_user = undefined;
201         countingTimeLogout(10); //mean 10 seconds
202     }
203 }
204
205 function sendLog(json) {
206     ajax("POST", "log", json, "log");
207 }