diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2025-01-27 16:24:33 +0100 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2025-01-27 16:24:33 +0100 |
| commit | 6e3a9c5836aa3bb273529959d84dfae074857c78 (patch) | |
| tree | 51596de780bfa105b02812fefdd3db04550b4c15 /templates | |
| parent | 550c6ce51c2f95fa0902adc99534fbf11661bb89 (diff) | |
| download | cyberschuessel-6e3a9c5836aa3bb273529959d84dfae074857c78.tar.gz cyberschuessel-6e3a9c5836aa3bb273529959d84dfae074857c78.zip | |
move python code into the project's root
Diffstat (limited to 'templates')
| -rw-r--r-- | templates/index.html | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..2cfb3a0 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,301 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + + <!-- we do not have a favicon --> + <link rel="icon" href="data:," /> + + <title>Cyberschuessel</title> + + <!-- css needed to keep the footer at the bottom of the viewport --> + <style> + html { + position: relative; + min-height: 100%; + } + + body { + margin: 0 0 100px; + } + + .content { + padding: 15px; + box-sizing: border-box; + text-align: center; + } + + footer { + position: absolute; + left: 0; + bottom: 0; + height: 100px; + width: 100%; + text-align: center; + } + </style> + + <script language="javascript" type="text/javascript"> + /* + @licstart The following is the entire license notice for the + JavaScript code in this page. + + Copyright (C) 2020 Florian Fischer + + The JavaScript code in this page is free software: you can + redistribute it and/or modify it under the terms of the GNU + General Public License (GNU GPL) as published by the Free Software + Foundation, either version 3 of the License, or any later version. + The code is distributed WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. + + As additional permission under GNU GPL version 3 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU GPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + @licend The above is the entire license notice + for the JavaScript code in this page. + */ + + // Extend Storage prototype to support objects + Storage.prototype.setObject = function(key, value) { + this.setItem(key, JSON.stringify(value)); + } + + Storage.prototype.getObject = function(key) { + var value = this.getItem(key); + return value && JSON.parse(value); + } + + let strings = {}; + strings.phase_prefix = {'en': 'Round:', 'de': 'Runde:'}; + strings.words_prefix = {'en': 'Words to guess:', 'de': 'Wörter noch zu erraten:'}; + strings.guessed_prefix = {'en': 'Words already guessed:', 'de': 'Wörter bereits erraten:'}; + strings.drawn_word_prefix = {'en': 'Current word:', 'de': 'Aktuelles Wort:'}; + strings.draw_button = {'en': 'Draw word', 'de': 'Wort ziehen'}; + strings.reset_button = {'en': 'Reset', 'de': 'Neu'}; + strings.add_button = {'en': 'Add word', 'de': 'Wort hinzufügen:'}; + strings.add_word = {'en': 'Anything', 'de': 'Irgendwas'}; + strings.phase_changed = {'en': 'Next Phase', 'de': 'Nächste Runde'}; + strings.reload = {'en': 'Connection not available. Trying to reload ...', + 'de': 'Verbindung unterbrochen. Seite wird neu geladen ...'}; + + let userLang = navigator.language || navigator.userLanguage; + userLang = userLang.substring(0, 2); + + let phase = 0; + let words_to_guess = 0; + let words_guessed = 0; + + // logical clock counting all draw events to check if our stored last_word is outdated + let draw_counter = 0; + + set_words_to_guess = function(val) { + words_to_guess = val; + let word_count_text = document.getElementById('word_count'); + word_count_text.innerText = strings.words_prefix[userLang] + " " + words_to_guess; + } + + change_words_to_guess = function(diff) { + set_words_to_guess(words_to_guess+ diff); + } + + set_words_guessed = function(val) { + words_guessed = val; + let words_guessed_text = document.getElementById('guessed_count'); + words_guessed_text.innerText = strings.guessed_prefix[userLang] + " " + words_guessed; + } + + update_drawn_word = function(draw_counter) { + let drawn_word = document.getElementById('drawn_word') + let last_word = localStorage.getObject('last_word'); + // we drew last -> show our word + if (last_word && last_word.draw_counter == draw_counter) { + drawn_word.innerText = strings.drawn_word_prefix[userLang] + " " + last_word.word; + } else { + drawn_word.innerText = ""; + } + } + + set_phase = function(val) { + phase = val; + let phase_text = document.getElementById('schuessel_phase'); + phase_text.innerText = strings.phase_prefix[userLang] + " " + phase; + + let add_div = document.getElementById('add_div'); + if (phase != 0) { + add_div.style.display = 'none'; + } else { + add_div.style.display = 'block'; + } + } + + conn_open = function(uri) { + let ws = new WebSocket(uri); + + ws.onerror = conn_onerror; + ws.onmessage = conn_onmessage; + ws.onclose = conn_onclose; + + return ws; + } + + conn_onerror = function(e) { + console.log("Websocket error " + e); + conn = conn_open(wsUri); + }; + + conn_onclose = function(e) { + console.log("Websocket closed " + e); + conn = conn_open(wsUri); + }; + + conn_onmessage = function(e) { + let data = JSON.parse(e.data); + switch (data.action) { + case 'init': + set_words_to_guess(data.words); + set_words_guessed(data.guessed); + set_phase(data.phase); + + if (draw_counter > data.draw_counter) { + localStorage.removeItem('last_word'); + } + + update_drawn_word(data.draw_counter) + draw_counter = data.draw_counter; + break; + + case 'drawn': + set_words_to_guess(data.words); + set_words_guessed(data.guessed); + set_phase(data.phase); + + if (data.draw_counter > draw_counter) { + draw_counter = data.draw_counter; + } + + // update drawn word element + update_drawn_word(draw_counter); + break; + + case 'draw': + if (data.draw_counter >= draw_counter) { + draw_counter = data.draw_counter; + last_word = {'word': data.drawn_word, 'draw_counter': draw_counter}; + localStorage.setObject('last_word', last_word); + } + + update_drawn_word(draw_counter); + // schuessel is empty when we draw + // alert the user that a phase change occurred + if (data.phase_change) { + alert(strings.phase_changed[userLang]); + } + break; + + case 'add': + change_words_to_guess(1); + break; + } + } + + let wsUri = (window.location.protocol=='https:'&&'wss://'||'ws://') + window.location.host; + // our websocket connection + let conn; + + document.addEventListener('DOMContentLoaded', function() { + // init visual strings + let reset_button = document.getElementById("reset_button"); + reset_button.value = strings.reset_button[userLang]; + + let add_word = document.getElementById('add_word'); + add_word.placeholder = strings.add_word[userLang]; + + let add_button = document.getElementById('add_button'); + add_button.value = strings.add_button[userLang]; + + let draw_button = document.getElementById("draw_button"); + draw_button.value = strings.draw_button[userLang]; + + // open websocket connection if DOM was loaded to make all received events + // can access the DOM elements + conn = conn_open(wsUri); + + document.getElementById("add_form").onsubmit = function() { + let word_add_form = document.getElementById('add_form'); + + let word = word_add_form[0].value; + if (word) { + let data = {}; + data.action = 'add'; + data.word = word; + try { + conn.send(JSON.stringify(data)); + } catch(err) { + alert(strings.reload[userLang]); + location.reload(); + } + } + document.getElementById('add_form').reset(); + return false; + } + + document.getElementById("draw_button").onclick = function() { + let data = {}; + data.action = 'draw'; + data.last_word = localStorage.getObject('last_word'); + try { + conn.send(JSON.stringify(data)); + } catch(err) { + alert(strings.reload[userLang]); + location.reload(); + } + return false; + } + + document.getElementById("reset_button").onclick = function() { + let data = {}; + data.action = 'reset'; + try { + conn.send(JSON.stringify(data)); + } catch(err) { + alert(strings.reload[userLang]); + location.reload(); + } + return false; + } + }); + </script> + </head> + + <body> + <!-- <h3 id="schuessel_id"></h3> --> + <div class="content"> + <input id="reset_button" type="button"/> + <h3 id="schuessel_phase" style="display:inline-block" ></h3> + <h3 id="word_count"></h3> + <h3 id="guessed_count"></h3> + <div id="add_div"> + <form id="add_form"> + <input id="add_word" type="text"/> + <!-- non visual submit input to submit on "Enter" --> + <input type="submit" style="display: none" /> + <input id="add_button" type="submit"/> + </form> + </div> + <h3 id="drawn_word"></h3> + <input id="draw_button" type="button"/> + </div> + + <footer> + This website as well as the server code for cyberschuessel by Florian Fischer is free software licenced under the <a href="">GNU General Public License 3</a>. + </br> + The source code can be found at <a href="https://muhq.space/software/cyberschuessel.html">https://muhq.space/</a>. + </footer> + </body> +</html> |
