Merge branch 'develop' into timer
authorLaurent Mazet <mazet@softndesign.org>
Mon, 28 Sep 2020 20:28:45 +0000 (22:28 +0200)
committerLaurent Mazet <mazet@softndesign.org>
Mon, 28 Sep 2020 20:28:45 +0000 (22:28 +0200)
1  2 
public/index.html
public/trivabble.js

index de2ef7f92c08ee023d0d1a46a0bde93c557023f1,dd9aec5fb2e7eaf75c123c14448d4f53b42cf937..e64be9ca43fb714b4de468122aa9b3a9482886ad
                      <span class="modal-button" id="btn-settings-close">&#215;</span>
                        </h2>
                  <div id="prefs">
-                     <p><label><input type="checkbox" id="tiles-sound" checked="checked" /><span data-l10n="text-content">Sound of the tiles</span></label></p>
-                     <p><label><input type="checkbox" id="msg-sound" checked="checked" /><span data-l10n="text-content">Sound of messages</span></label></p>
+                     <p><label><input type="checkbox" id="tiles-sound" /><span data-l10n="text-content">Sound of the tiles</span></label></p>
+                     <p><label><input type="checkbox" id="msg-sound" /><span data-l10n="text-content">Sound of messages</span></label></p>
 +                </div>
 +                <div id="prefs">
                      <p id="enable-spell-checker-outer" style="display:none"><label><input type="checkbox" id="enable-spell-checker" /> <span data-l10n="text-content">Enable spell checker</span></label></p>
 +                </div>
 +                <div id="prefs">
                            <p><label><span data-l10n="text-content">(fast)</span><input type="range" min="0" max="0" id="double-tap-duration"/><span data-l10n="text-content">(slow)</span><br/><span data-l10n="text-content">Double tap duration</span></label></p>
                            <p><label><span data-l10n="text-content">(fast)</span><input type="range" min="0" max="0" id="flash-light-duration"/><span data-l10n="text-content">(slow)</span><br/><span data-l10n="text-content">Flash light duration</span></label></p>
                      <p><label><input type="text" size="6" id="flash-light-color"/> <span data-l10n="text-content">Flash light color</span></label></p>
index 35028515061f66be4c1f96efe83fd67422f15cce,3d6414ec93bc8799b86b39a6b39f2badd7765890..56aaa08c721f222d93dd55dba2bd7f33dad24442
          }
      }
  
-     setConf("POLLING_DELAY",        2000);
-     setConf("ENABLE_WEBSOCKETS",    true);
-     setConf("ENABLE_EVENT_SOURCE",  true);
-     setConf("MAX_WEBSOCKET_ERRORS", 1);
-     setConf("APP_PATH",             "");
-     setConf("ENABLE_SPELL_CHECKER", false);
-     setConf("DOUBLE_TAP_DURATIONS", [650, 1100, 1800, 3000, 5000]);
+     setConf("POLLING_DELAY",         2000);
+     setConf("ENABLE_WEBSOCKETS",     true);
+     setConf("ENABLE_EVENT_SOURCE",   true);
+     setConf("MAX_WEBSOCKET_ERRORS",  1);
+     setConf("APP_PATH",              "");
+     setConf("ENABLE_MSG_SOUND",      true);
+     setConf("ENABLE_TILE_SOUND",     true);
+     setConf("ENABLE_SPELL_CHECKER",  false);
+     setConf("DOUBLE_TAP_DURATIONS",  [650, 1100, 1800, 3000, 5000]);
      setConf("FLASH_LIGHT_DURATIONS", [800, 1600, 3200]);
-     setConf("FLASH_LIGHT_COLOR", "#E3E");
-     setConf("ENABLE_TIMER",         true);
+     setConf("FLASH_LIGHT_COLOR",     "#E3E");
++    setConf("ENABLE_TIMER",          true);
+ 
+     function isSetting(key) {
+         return Object.prototype.hasOwnProperty.call(Conf, key) ||
+             Object.prototype.hasOwnProperty.call(localStorage, key);
+     }
+ 
+     function getSetting(key) {
+         let type;
+         let value;
+ 
+         /* get default value from configuration */
+         if (Object.prototype.hasOwnProperty.call(Conf, key)) {
+             value = Conf[key];
+             type = typeof value;
+         }
+ 
+         /* try to retrieve value from localstorage */
+         if (Object.prototype.hasOwnProperty.call(localStorage, key)) {
+             value = localStorage.getItem(key);
+ 
+             /* get type from localStorage if no default is set */
+             if (typeof type === "undefined") {
+                 if (Object.prototype.hasOwnProperty.call(localStorage, key + "_type")) {
+                     type = localStorage.getItem(key + "_type");
+                 } else {
+                     type = "string";
+                 }
+             }
+ 
+             /* cast from string to type */
+             if (type === "boolean") {
+                 value = (value === "true");
+             } else if (type === "number") {
+                 value = Number(value);
+             } else if (type === "object") {
+                 value = JSON.parse(value);
+             } else if (type === "string") {
+                 value = String(value);
+             } else {
+                 console.error("Unsupported type");
+             }
+         }
+ 
+         return value;
+     }
+ 
+     function setSetting(key, value) {
+         let type;
+ 
+         /* try to retrieve type from configuration */
+         if (Object.prototype.hasOwnProperty.call(Conf, key)) {
+             type = typeof Conf[key];
+         }
+ 
+         /* try to retrieve type from localstorage */
+         if (typeof type === "undefined") {
+             if (Object.prototype.hasOwnProperty.call(localStorage, key)) {
+                 type = localStorage.getItem(key + "_type");
+             }
+         }
+ 
+         /* if not set type is defined from value */
+         if (typeof type === "undefined") {
+             type = typeof value;
+         }
+ 
+         /* storage value in localstorage */
+         if (type === typeof value) {
+             if (type === "object") {
+                 value = JSON.stringify(value);
+             }
+             if ((type === "boolean") ||
+                 (type === "number") ||
+                 (type === "object") ||
+                 (type === "string")) {
+                 localStorage.setItem(key, value);
+ 
+                 /* store type into localstorage if no default value in configuration */
+                 if (!Object.prototype.hasOwnProperty.call(Conf, key)) {
+                     localStorage.setItem(key + "_type", type);
+                 }
+             } else {
+                 console.error("Unsupported type");
+             }
+         } else {
+             console.error("incoherent type");
+         }
+     }
+ 
+     function migrateSetting(key, type) {
+         if (Object.prototype.hasOwnProperty.call(localStorage, key)) {
+             localStorage.setItem(key + "_type", type);
+         }
+     }
+     migrateSetting("doubleTapDuration", "number");
+     migrateSetting("flashLightDuration", "number");
+     migrateSetting("spellCheckerEnabled", "boolean");
+     migrateSetting("trivabbleGameNumber", "number");
+     migrateSetting("trivabbleBoardLang", "string");
+     migrateSetting("trivabbleGameNumber", "number");
+     migrateSetting("trivabbleLang", "string");
+     migrateSetting("trivabblePlayerName", "string");
  
      const _ = (window.libD && libD.l10n) ? libD.l10n() : function (s) {
          return s;
          }
      }
  
-             localStorage.timerEnable = Conf.ENABLE_TIMER;
 +    function timerString(delta) {
 +        const d = Math.floor(delta / (60 * 60 * 24));
 +        const h = Math.floor((delta % (60 * 60 * 24)) / (60 * 60));
 +        const m = Math.floor((delta % (60 * 60)) / 60);
 +        const s = Math.floor(delta % 60);
 +        return ((d > 0) ? format(_("{0}d "), d) : "") +
 +               ((h > 0) ? format(_("{0}h "), h) : "") +
 +               format(_("{0}' {1}''"), m, s);
 +    }
 +
 +    function timerDate() {
 +        return Math.floor(Date.now() / 1000);
 +    }
 +
 +    function initTimer() {
 +        if (!Object.prototype.hasOwnProperty.call(localStorage, "timerTurnDate")) {
 +            localStorage.timerTurnDate = timerDate();
 +        }
 +        if (!Object.prototype.hasOwnProperty.call(localStorage, "timerGlobalDate")) {
 +            localStorage.timerGlobalDate = timerDate();
 +        }
 +        if (!Object.prototype.hasOwnProperty.call(localStorage, "timerEnable")) {
++            localStorage.timerEnable = getSetting("ENABLE_TIMER");
 +        }
 +        document.getElementById("enable-timer").onclick = function () {
 +            setTimerState(document.getElementById("enable-timer").checked);
 +        };
 +        setTimerState(localStorage.timerEnable);
 +    }
 +
 +    function setTimerState(state) {
 +        if (state) {
 +            document.getElementById("timer").style.display = "block";
 +            document.getElementById("enable-timer").checked = true;
 +            localStorage.timer = setInterval(function () {
 +                document.getElementById("timer-turn").textContent = timerString(timerDate() - Number(localStorage.timerTurnDate));
 +                document.getElementById("timer-global").textContent = timerString(timerDate() - Number(localStorage.timerGlobalDate));
 +            }, 1000);
 +        } else {
 +            document.getElementById("timer").style.display = "none";
 +            document.getElementById("enable-timer").checked = false;
 +            if (Object.prototype.hasOwnProperty.call(localStorage, "timer")) {
 +                clearInterval(localStorage.timer);
 +                delete localStorage.timer;
 +            }
 +            localStorage.timerGlobalDate = localStorage.timerTurnDate = timerDate();
 +        }
 +    }
 +
      function repromptName(f) {
-         if (localStorage.trivabblePlayerName && localStorage.trivabblePlayerName.trim()) {
+         if (getSetting("trivabblePlayerName") && getSetting("trivabblePlayerName").trim()) {
              f();
          } else {
              myPrompt(