aboutsummaryrefslogtreecommitdiff
path: root/templates
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2025-01-27 16:24:33 +0100
committerFlorian Fischer <florian.fischer@muhq.space>2025-01-27 16:24:33 +0100
commit6e3a9c5836aa3bb273529959d84dfae074857c78 (patch)
tree51596de780bfa105b02812fefdd3db04550b4c15 /templates
parent550c6ce51c2f95fa0902adc99534fbf11661bb89 (diff)
downloadcyberschuessel-6e3a9c5836aa3bb273529959d84dfae074857c78.tar.gz
cyberschuessel-6e3a9c5836aa3bb273529959d84dfae074857c78.zip
move python code into the project's root
Diffstat (limited to 'templates')
-rw-r--r--templates/index.html301
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>