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("FLASH_LIGHT_DURATIONS", [800, 1600, 3200]);
+ setConf("FLASH_LIGHT_COLOR", "#E3E");
const _ = (window.libD && libD.l10n) ? libD.l10n() : function (s) {
return s;
? format(_("You changed the language of the board to {0}"), newLang)
: format(_("{0} changed the language of the board to {1}"), msg.sender, newLang)
);
-
- return;
}
+
+ case "highlightTile": {
+ localHighlightTile(msg.specialMsg.tile);
+ infoMessage(msg.msg);
+ }
}
}
}
+ function getLetterFromBoard(row, col) {
+ if ((row < 0) || (row >= 15) || (col < 0) || (col >= 15)) {
+ return "";
+ }
+ try {
+ const index = (row * 15) + col;
+ const tilePlaceholder = boardCells[index].getElementsByClassName("tile-placeholder")[0];
+ const tile = tilePlaceholder.getElementsByClassName("tile")[0];
+ return tile.firstChild.textContent;
+ } catch (e) {
+ return "";
+ }
+ }
+
+ function searchWordInLine(row, col, incRow, incCol) {
+ const initLetter = getLetterFromBoard(row, col);
+
+ /* Look for first letter in line */
+ while (getLetterFromBoard(row - incRow, col - incCol) !== "") {
+ row -= incRow;
+ col -= incCol;
+ }
+
+ /* Look for last letter in line */
+ const word = {letters: "", row: row, col: col, incRow: incRow, incCol: incCol};
+ let letter;
+ while ((letter = getLetterFromBoard(row, col)) !== "") {
+ word.letters += letter;
+ row += incRow;
+ col += incCol;
+ }
+ return (word.letters === initLetter) ? null : word;
+ }
+
+ function isNewWord(newWord, words) {
+ if (newWord === null) {
+ return false;
+ }
+ for (const k of Object.keys(words)) {
+ if ((words[k].letters === newWord.letters) &&
+ (words[k].row === newWord.row) &&
+ (words[k].col === newWord.col) &&
+ (words[k].incRow === newWord.incRow) &&
+ (words[k].incCol === newWord.incCol)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ function searchNewWords() {
+
+ const words = [];
+ for (const i of Object.keys(currentTilePlayed)) {
+
+ /* Get board position */
+ const row = Math.floor(i / 15);
+ const col = i % 15;
+
+ /* Look for word in column */
+ const newWordInCol = searchWordInLine(row, col, 1, 0);
+ if (isNewWord(newWordInCol, words)) {
+ words.push(newWordInCol);
+ }
+
+ /* Look for word in row */
+ const newWordInRow = searchWordInLine(row, col, 0, 1);
+ if (isNewWord(newWordInRow, words)) {
+ words.push(newWordInRow);
+ }
+
+ /* Should we look for word in diag? */
+
+ /* If nothing found, it's a one letter word */
+ if ((newWordInCol === null) && (newWordInRow === null)) {
+ words.push({letters: getLetterFromBoard(row, col), row: row, col: col, incRow: 0, incCol: 0});
+ }
+ }
+
+ return words;
+ }
+
+ function modifyTileClass(word, value, action) {
+
+ /* action: true for add, false for remove */
+
+ if (action) {
+
+ /* only for new words */
+ for (let l = 0; l < word.letters.length; l++) {
+ const index = ((word.row + (l * word.incRow)) * 15) + word.col + (l * word.incCol);
+ const tilePlaceholder = boardCells[index].getElementsByClassName("tile-placeholder")[0];
+ const tile = tilePlaceholder.getElementsByClassName("tile")[0];
+
+ tile.classList.add(value);
+ }
+
+ } else {
+
+ /* tiles on board */
+ for (let index = 0; index < 15 * 15; index++) {
+ const tilePlaceholder = boardCells[index].getElementsByClassName("tile-placeholder")[0];
+ const tile = tilePlaceholder.getElementsByClassName("tile")[0];
+ if (typeof tile !== "undefined") {
+ tile.classList.remove(value);
+ }
+ }
+
+ /* tiles on rack */
+ for (const tilePlaceholder of rack.getElementsByClassName("tile-placeholder")) {
+ const tile = tilePlaceholder.getElementsByClassName("tile")[0];
+ if (typeof tile !== "undefined") {
+ tile.classList.remove(value);
+ }
+ }
+
+ /* tile on the move */
+ if (movingTile !== null) {
+ movingTile.classList.remove(value);
+ }
+ }
+ }
+
+ function checkSpellingClicked() {
+ if (localStorage.spellCheckerEnabled === "false") {
+ return;
+ }
+
+ getDictionary(localStorage.trivabbleBoardLang, checkSpelling);
+ }
+
+ function checkSpelling(dictionary) {
+ const newWords = searchNewWords();
+ if (newWords.length === 0) {
+ myAlert(_("No new word found"));
+ return;
+ }
+
+ /* Check if words are in dictionary */
+ let words = [];
+ let badWords = [];
+ for (const k of Object.keys(newWords)) {
+ const currentWord = newWords[k].letters.replace(/ /gu, "?");
+ if (words.indexOf(currentWord) === -1) {
+ words.push(currentWord);
+ }
+ modifyTileClass(newWords[k], "tile-spelling-ok", true);
+ const pattern = "^" + newWords[k].letters.replace(/ /gu, ".") + "$";
+ const find = dictionary.find(function (word) {
+ return word.match(pattern);
+ });
+ if (!find) {
+ if (badWords.indexOf(currentWord) === -1) {
+ badWords.push(currentWord);
+ }
+ modifyTileClass(newWords[k], "tile-spelling-nok", true);
+ }
+ }
+ setTimeout(
+ function () {
+ modifyTileClass(null, "tile-spelling-ok", false);
+ modifyTileClass(null, "tile-spelling-nok", false);
+ }, 5000);
+ words = words.join(", ").trim();
+ badWords = badWords.join(", ").trim();
+
+ /* Advice on erroneous spelling */
+ if (badWords.length > 0) {
+ const msg = chatMessage("", format(_("Incorrect spelling for {0} from {1}"), badWords, words));
+ msg.classList.add("error");
+ } else {
+ chatMessage("", format(_("All words are correct: {0}"), words));
+ }
+ }
+
+ function highlightTile(e) {
+ let id = this.id;
+ if (id === "") {
+ return;
+ } else if (id === "center-cell") {
+ id = 112;
+ }
+ if (e.type === "touchstart") {
+ if ((highlightTile.id !== id) || (Date.now() - highlightTile.date > localStorage.doubleTapDuration)) {
+ highlightTile.id = id;
+ highlightTile.date = Date.now();
+ return;
+ }
+ }
+
+ if (e.type === "dblclick") {
+ const tilePlaceholder = boardCells[id].getElementsByClassName("tile-placeholder")[0];
+ if (tilePlaceholder.getElementsByClassName("tile")[0]) {
+ return;
+ }
+ }
+
+ const letters = "ABCDEFGHIJKLMNO";
+ const col = (id % 15) + 1;
+ const row = letters[Math.floor(id / 15)];
+ sendCmds([{
+ cmd: "msg",
+ msg: _("Look at:") + " " + row + col,
+ specialMsg: {
+ type: "highlightTile",
+ tile: id
+ }
+ }]);
+ }
+
+ function localHighlightTile(id) {
+ const placeholder = boardCells[id].getElementsByClassName("tile-placeholder")[0];
+ placeholder.classList.add("highlight");
+ setTimeout(
+ function (x) {
+ x.classList.remove("highlight");
+ }, Number(localStorage.flashLightDuration) * 1 / 3, placeholder);
+ setTimeout(
+ function (x) {
+ x.classList.add("highlight");
+ }, Number(localStorage.flashLightDuration) * 1 / 2, placeholder);
+ setTimeout(
+ function (x) {
+ x.classList.remove("highlight");
+ }, Number(localStorage.flashLightDuration) * 2 / 3, placeholder);
+ setTimeout(
+ function (x) {
+ x.classList.add("highlight");
+ }, Number(localStorage.flashLightDuration) * 5 / 6, placeholder);
+ setTimeout(
+ function (x) {
+ x.classList.remove("highlight");
+ }, Number(localStorage.flashLightDuration) * 1, placeholder);
+ }
+
function initChat() {
const btn = document.getElementById("chat-btn");
}
}
+ function initSpellChecker() {
+ if (Conf.ENABLE_SPELL_CHECKER) {
+ document.getElementById("enable-spell-checker-outer").style.display = "";
+ }
+
+ document.getElementById("enable-spell-checker").onclick = spellCheckerSettingChecked;
+
+ if (!Conf.ENABLE_SPELL_CHECKER || localStorage.spellCheckerEnabled === "false") {
+ document.getElementById("check-spelling").style.display = "none";
+ document.getElementById("enable-spell-checker").checked = false;
+ document.getElementById("info-spell-checking").style.display = "none";
+ } else {
+ document.getElementById("check-spelling").style.display = "";
+ document.getElementById("info-spell-checking").style.display = "";
+ document.getElementById("enable-spell-checker").checked = true;
+ }
+ }
+
+ function translateDuration(x, values) {
+ if (x < 0) {
+ return null;
+ } else if (x < values.length) {
+ return values[Math.floor(x)];
+ } else {
+ for (let i = 0; i < values.length; i++) {
+ if (x <= values[i]) {
+ return i;
+ }
+ }
+ return values.length - 1;
+ }
+ }
+
+ function initLaserPointer() {
+ if (!Object.prototype.hasOwnProperty.call(localStorage, "doubleTapDuration")) {
+ localStorage.doubleTapDuration = Conf.DOUBLE_TAP_DURATIONS[Math.floor(Conf.DOUBLE_TAP_DURATIONS.length / 2)];
+ }
+ const doubleTapDuration = document.getElementById("double-tap-duration");
+ if (doubleTapDuration) {
+ doubleTapDuration.max = Conf.DOUBLE_TAP_DURATIONS.length - 1;
+ doubleTapDuration.value = translateDuration(localStorage.doubleTapDuration, Conf.DOUBLE_TAP_DURATIONS);
+ doubleTapDuration.onchange = function () {
+ localStorage.doubleTapDuration =
+ translateDuration(document.getElementById("double-tap-duration").value, Conf.DOUBLE_TAP_DURATIONS);
+ };
+ }
+
+ if (!Object.prototype.hasOwnProperty.call(localStorage, "flashLightDuration")) {
+ localStorage.flashLightDuration = Conf.FLASH_LIGHT_DURATIONS[Math.floor(Conf.FLASH_LIGHT_DURATIONS.length / 2)];
+ }
+ const flashLightDuration = document.getElementById("flash-light-duration");
+ if (flashLightDuration) {
+ flashLightDuration.max = Conf.FLASH_LIGHT_DURATIONS.length - 1;
+ flashLightDuration.value = translateDuration(localStorage.flashLightDuration, Conf.FLASH_LIGHT_DURATIONS);
+ flashLightDuration.onchange = function () {
+ localStorage.flashLightDuration =
+ translateDuration(document.getElementById("flash-light-duration").value, Conf.FLASH_LIGHT_DURATIONS);
+ };
+ }
+
+ if (!Object.prototype.hasOwnProperty.call(localStorage, "flashLightColor")) {
+ localStorage.flashLightColor = Conf.FLASH_LIGHT_COLOR;
+ }
+ const flashLightColor = document.getElementById("flash-light-color");
+ if (flashLightColor) {
+ flashLightColor.value = localStorage.flashLightColor;
+ flashLightColor.onchange = function () {
+ localStorage.flashLightColor =
+ document.getElementById("flash-light-color").value;
+ const style = document.createElement("style");
+ style.innerHTML = ".highlight {background-color: " + localStorage.flashLightColor + ";}";
+ document.body.appendChild(style);
+ };
+ flashLightColor.onchange();
+ }
+ }
+
function repromptName(f) {
if (localStorage.trivabblePlayerName && localStorage.trivabblePlayerName.trim()) {
f();
location.reload();
}
- function showConfig() {
- const modal = document.querySelector(".modal");
- modal.classList.toggle("show-modal");
+ function showSettings() {
- const modal = document.querySelector(".modal");
- modal.classList.toggle("show-modal");
++ const modal = document.querySelector(".modal");
++ modal.classList.toggle("show-modal");
}
function initGlobals() {
initChat();
initGame();
initSound();
+ initSpellChecker();
+ initLaserPointer();
};
trivabble.l10nError = trivabble.run;