Merge branch 'develop' into custon_board_layout

This commit is contained in:
Laurent Mazet 2021-04-24 21:48:11 +02:00
commit 915f84a4ff
7 changed files with 149 additions and 34 deletions

View File

@ -4,6 +4,8 @@ PORT = 3000
ESLINT?=eslint ESLINT?=eslint
TIDY?=tidy
ifeq (, $(shell which $(firstword ${ESLINT}))) ifeq (, $(shell which $(firstword ${ESLINT})))
ESLINT?=npx eslint ESLINT?=npx eslint
endif endif
@ -34,5 +36,8 @@ public/dict/list.js:
eslint: eslint:
-${ESLINT} **/*.js -${ESLINT} **/*.js
tidy:
-${TIDY} -xml -errors -q public/*.html
start-dev-server: lang start-dev-server: lang
cd server && make start-dev-server cd server && make start-dev-server

View File

@ -262,10 +262,26 @@ msgstr "Chronométrer la partie"
msgid "To measure playing time, activate the timer." msgid "To measure playing time, activate the timer."
msgstr "Pour mesurer les temps de jeu, activez le chronomètre." msgstr "Pour mesurer les temps de jeu, activez le chronomètre."
msgid "Cell captions:"
msgstr "Légendes des cellules :"
msgid "Clip when overflow"
msgstr "Raccourcies en cas de débordement"
msgid "Dots when overflow"
msgstr "Pointillés en cas de débordement"
msgid "No caption"
msgstr "Pas de légende"
msgid "Short caption"
msgstr "Légendes courtes"
msgid "Board label:" msgid "Board label:"
msgstr "Type du plateau" msgstr "Type du plateau"
msgid "Are you sure you want to change board to {0}? This will put all the tiles back in the bag and start another game." msgid "Are you sure you want to change board to {0}? This will put all the tiles back in the bag and start another game."
msgstr "Êtes-vous sûr·e de vouloir de changer le type du plateau à {0} ? Cela remettra toutes les lettres du jeu dans le sac et commencera une nouvelle partie." msgstr "Êtes-vous sûr·e de vouloir de changer le type du plateau à {0} ? Cela remettra toutes les lettres du jeu dans le sac et commencera une nouvelle partie."
msgid "Can't find board '{0}'. Change board or start a new game." msgid "Can't find board '{0}'. Change board or start a new game."
msgstr "Impossible de trouver le plateau de type '{0}'. Changez de type de plateau ou démarrez une nouvelle partie." msgstr "Impossible de trouver le plateau de type '{0}'. Changez de type de plateau ou démarrez une nouvelle partie."

View File

@ -267,6 +267,21 @@ msgstr ""
msgid "To measure playing time, activate the timer." msgid "To measure playing time, activate the timer."
msgstr "" msgstr ""
msgid "Cell captions:"
msgstr ""
msgid "Clip when overflow"
msgstr ""
msgid "Dots when overflow"
msgstr ""
msgid "No caption"
msgstr ""
msgid "Short caption"
msgstr ""
msgid "Board label:" msgid "Board label:"
msgstr "" msgstr ""

View File

@ -3,46 +3,55 @@
window.TrivabbleConf = { window.TrivabbleConf = {
// The amount of time to wait after a connection failure // The amount of time to wait after a connection failure
POLLING_DELAY: 2000, //POLLING_DELAY: 2000,
// Whether WebSockets should be used, if possible // Whether WebSockets should be used, if possible
ENABLE_WEBSOCKETS: true, //ENABLE_WEBSOCKETS: true,
// Whether Server Sent Events should be used, if available // Whether Server Sent Events should be used, if available
ENABLE_EVENT_SOURCE: true, //ENABLE_EVENT_SOURCE: true,
// Max consecutive tries before blacklisting WebSockets for the current session // Max consecutive tries before blacklisting WebSockets for the current session
MAX_WEBSOCKET_ERRORS: 1, //MAX_WEBSOCKET_ERRORS: 1,
// To tweak only if your webserver is shared with other conflicting resources at / (e.g. Yunohost integration) // To tweak only if your webserver is shared with other conflicting resources at / (e.g. Yunohost integration)
APP_PATH: "", //APP_PATH: "",
// The API entry point. Default value: APP_PATH + '/:trivabble' // The API entry point. Default value: APP_PATH + '/:trivabble'
API_ENTRY_POINT: "/:trivabble", //API_ENTRY_POINT: "/:trivabble",
// The color of the flash light when double clicking on a cell // Wether sounds should be played when receiving messages
FLASH_LIGHT_COLOR: "#EE6633", //ENABLE_MSG_SOUND: true,
// The list of durations of the flash light available in the settings box // Wether sounds should be played when moving tiles
FLASH_LIGHT_DURATIONS: [800, 1600, 3200], //ENABLE_TILE_SOUND: true,
// The defaut flash light duration. If not set, the value at the middle of the previous array is used.
FLASH_LIGHT_DURATION: 1600,
// The list of durations used to detect a double tap available in the settings box // The list of durations used to detect a double tap available in the settings box
DOUBLE_TAP_DURATIONS: [650, 1100, 1800, 3000, 5000], //DOUBLE_TAP_DURATIONS: [650, 1100, 1800, 3000, 5000],
// The defaut double tap duration. If not set, the value at the middle of the previous array is used. // The defaut double tap duration. If not set, the value at the middle of the previous array is used.
DOUBLE_TAP_DURATION: 1800, //DOUBLE_TAP_DURATION: 1800,
// The color of the flash light when double clicking on a cell
//FLASH_LIGHT_COLOR: "#EE6633",
// The list of durations of the flash light available in the settings box
//FLASH_LIGHT_DURATIONS: [800, 1600, 3200],
// The defaut flash light duration. If not set, the value at the middle of the previous array is used.
//FLASH_LIGHT_DURATION: 1600,
// The default premium for playing seven tiles on a turn // The default premium for playing seven tiles on a turn
PREMIUM_SEVEN_TILES: 50, //PREMIUM_SEVEN_TILES: 50,
// Score is automically affected to last player. If false, score is automatically affected to the player who pressed the Score button // Score is automically affected to last player. If false, score is automatically affected to the player who pressed the Score button
SCORE_LAST_PLAYER: true, //SCORE_LAST_PLAYER: true,
// Timer activation // Timer activation
ENABLE_TIMER: false, //ENABLE_TIMER: false,
// Cell captions. Could be "clip", "dots", "none" or "short"
//CELL_CAPTIONS: "dots",
// I don't like trailing commas, here is a nice message for you reading this file :-) // I don't like trailing commas, here is a nice message for you reading this file :-)
HAVE_FUN: true HAVE_FUN: true

View File

@ -108,6 +108,19 @@
</label> </label>
</p> </p>
</div> </div>
<div>
<p id="cell-captions-p">
<label>
<span data-l10n="text-content">Cell captions:</span>
<select id="cell-captions">
<option value="clip" data-l10n="text-content">Clip when overflow</option>
<option value="dots" data-l10n="text-content">Dots when overflow</option>
<option value="none" data-l10n="text-content">No caption</option>
<option value="short" data-l10n="text-content">Short caption</option>
</select>
</label>
</p>
</div>
</div> </div>
</section> </section>

View File

@ -122,10 +122,25 @@ html, #board, [draggable], .tile {
display:inline-block; display:inline-block;
white-space:pre-wrap; white-space:pre-wrap;
font-size:7px; font-size:7px;
text-overflow:ellipsis;
overflow:hidden; overflow:hidden;
} }
.special-cell-label-clip .special-cell-label {
text-overflow:clip;
}
.special-cell-label-dots .special-cell-label {
text-overflow:ellipsis;
}
.special-cell-label-none .special-cell-label {
visibility:hidden;
}
.special-cell-label-short .special-cell-label {
display:inline;
}
#center-cell .special-cell-label { #center-cell .special-cell-label {
font-weight:bold; font-weight:bold;
color:black; color:black;

View File

@ -54,17 +54,18 @@
setConf("ENABLE_EVENT_SOURCE", true); setConf("ENABLE_EVENT_SOURCE", true);
setConf("MAX_WEBSOCKET_ERRORS", 1); setConf("MAX_WEBSOCKET_ERRORS", 1);
setConf("APP_PATH", ""); setConf("APP_PATH", "");
setConf("API_ENTRY_POINT", Conf.APP_PATH + "/:trivabble");
setConf("ENABLE_MSG_SOUND", true); setConf("ENABLE_MSG_SOUND", true);
setConf("ENABLE_TILE_SOUND", true); setConf("ENABLE_TILE_SOUND", true);
setConf("DOUBLE_TAP_DURATIONS", [650, 1100, 1800, 3000, 5000]); setConf("DOUBLE_TAP_DURATIONS", [650, 1100, 1800, 3000, 5000]);
setConf("DOUBLE_TAP_DURATION", middle("DOUBLE_TAP_DURATIONS")); setConf("DOUBLE_TAP_DURATION", middle("DOUBLE_TAP_DURATIONS"));
setConf("FLASH_LIGHT_COLOR", "#ee6633");
setConf("FLASH_LIGHT_DURATIONS", [800, 1600, 3200]); setConf("FLASH_LIGHT_DURATIONS", [800, 1600, 3200]);
setConf("FLASH_LIGHT_DURATION", middle("FLASH_LIGHT_DURATIONS")); setConf("FLASH_LIGHT_DURATION", middle("FLASH_LIGHT_DURATIONS"));
setConf("FLASH_LIGHT_COLOR", "#ee6633");
setConf("API_ENTRY_POINT", Conf.APP_PATH + "/:trivabble");
setConf("PREMIUM_SEVEN_TILES", 50); setConf("PREMIUM_SEVEN_TILES", 50);
setConf("SCORE_LAST_PLAYER", true); setConf("SCORE_LAST_PLAYER", true);
setConf("ENABLE_TIMER", false); setConf("ENABLE_TIMER", false);
setConf("CELL_CAPTIONS", "dots"); // "clip", "dots", "none", "short"
function isSetting(key) { function isSetting(key) {
return Object.prototype.hasOwnProperty.call(Conf, key) || return Object.prototype.hasOwnProperty.call(Conf, key) ||
@ -138,7 +139,13 @@
(type === "number") || (type === "number") ||
(type === "object") || (type === "object") ||
(type === "string")) { (type === "string")) {
localStorage.setItem("trivabble" + key, value); if (Object.prototype.hasOwnProperty.call(Conf, key) && (Conf[key] === value)) {
if (Object.prototype.hasOwnProperty.call(localStorage, "trivabble" + key)) {
delete localStorage["trivabble" + key];
}
} else {
localStorage.setItem("trivabble" + key, value);
}
} else { } else {
console.error("Unsupported type"); console.error("Unsupported type");
} }
@ -148,15 +155,14 @@
} }
const SettingsTypes = { const SettingsTypes = {
SpellCheckerEnabledOnce: "boolean", BoardLang: "string",
DisableSpellChecker: "boolean", DisableSpellChecker: "boolean",
GameNumber: "number", GameNumber: "number",
BoardLang: "string", BoardLang: "string",
BoardLabel: "string", BoardLabel: "string",
Lang: "string", Lang: "string",
PlayerName: "string", PlayerName: "string",
Timer: "number", SpellCheckerEnabledOnce: "boolean",
TimerEnable: "boolean",
TimerGameDate: "number", TimerGameDate: "number",
TimerTurnDate: "number" TimerTurnDate: "number"
}; };
@ -1410,7 +1416,7 @@
webSocket = new WebSocket( webSocket = new WebSocket(
(window.location.protocol === "http:" ? "ws://" : "wss://") + (window.location.protocol === "http:" ? "ws://" : "wss://") +
window.location.host + window.location.host +
Conf.API_ENTRY_POINT + "/ws/" + getSetting("API_ENTRY_POINT") + "/ws/" +
JSON.stringify(cmdsWithContext()) JSON.stringify(cmdsWithContext())
); );
@ -1424,7 +1430,7 @@
function xhrRequest(data, onreadystatechange) { function xhrRequest(data, onreadystatechange) {
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
xhr.open("POST", Conf.API_ENTRY_POINT, true); xhr.open("POST", getSetting("API_ENTRY_POINT"), true);
xhr.setRequestHeader("Content-Type", "text/plain"); xhr.setRequestHeader("Content-Type", "text/plain");
xhr.send(JSON.stringify(data)); xhr.send(JSON.stringify(data));
@ -1573,17 +1579,25 @@
} }
const specialTypesText = { const specialTypesText = {
doubleLetter: _("Double\nLetter"), doubleLetter: "Double\nLetter",
doubleWord: _("Double\nWord"), doubleWord: "Double\nWord",
tripleLetter: _("Triple\nLetter"), tripleLetter: "Triple\nLetter",
tripleWord: _("Triple\nWord") tripleWord: "Triple\nWord"
};
const specialTypesShortText = {
doubleLetter: "DL",
doubleWord: "DW",
tripleLetter: "TL",
tripleWord: "TW"
}; };
function specialCell(type, cell) { function specialCell(type, cell) {
cell.firstChild.appendChild(document.createElement("span")); cell.firstChild.appendChild(document.createElement("span"));
cell.classList.add("special-cell"); cell.classList.add("special-cell");
cell.classList.add("special-cell-" + type); cell.classList.add("special-cell-" + type);
cell.lastChild.lastChild.textContent = cell.title = _(specialTypesText[type]); cell.lastChild.lastChild.longText = cell.title = _(specialTypesText[type]);
cell.lastChild.lastChild.shortText = _(specialTypesShortText[type]);
cell.lastChild.lastChild.className = "special-cell-label"; cell.lastChild.lastChild.className = "special-cell-label";
} }
@ -2316,7 +2330,7 @@
setTimerState(document.getElementById("enable-timer").checked); setTimerState(document.getElementById("enable-timer").checked);
}; };
setTimerState(getSetting("TimerEnable", getSetting("ENABLE_TIMER"))); setTimerState(getSetting("ENABLE_TIMER"));
} }
let timerTimeout = 0; let timerTimeout = 0;
@ -2328,7 +2342,7 @@
} }
function setTimerState(enabled) { function setTimerState(enabled) {
setSetting("TimerEnable", enabled); setSetting("ENABLE_TIMER", enabled);
if (timerTimeout) { if (timerTimeout) {
clearInterval(timerTimeout); clearInterval(timerTimeout);
timerTimeout = 0; timerTimeout = 0;
@ -2346,6 +2360,32 @@
} }
} }
function initCellCaptions() {
setCellCaptions(getSetting("CELL_CAPTIONS"));
document.getElementById("cell-captions").onchange = function () {
setCellCaptions(document.getElementById("cell-captions").value);
setSetting("CELL_CAPTIONS", mode);
};
}
function setCellCaptions(mode) {
document.getElementById("cell-captions").value = mode;
board.classList.remove("special-cell-label-short");
board.classList.remove("special-cell-label-clip");
board.classList.remove("special-cell-label-dots");
board.classList.remove("special-cell-label-none");
for (const cell of [].slice.call(document.getElementsByClassName("special-cell-label"))) {
if (cell.textContent !== "★") {
cell.textContent = (mode === "short") ? cell.shortText : cell.longText;
}
}
board.classList.add("special-cell-label-" + mode);
}
function repromptName(f) { function repromptName(f) {
if (getSetting("PlayerName") && getSetting("PlayerName").trim()) { if (getSetting("PlayerName") && getSetting("PlayerName").trim()) {
f(); f();
@ -2465,6 +2505,7 @@
setSetting("PlayerName", name); setSetting("PlayerName", name);
} }
repromptName(initGame); repromptName(initGame);
setCellCaptions(getSetting("CELL_CAPTIONS"));
} }
); );
@ -2602,6 +2643,7 @@
initFlashLight(); initFlashLight();
nextHelpMessage(); nextHelpMessage();
initTimer(); initTimer();
initCellCaptions();
}; };
trivabble.l10nError = trivabble.run; trivabble.l10nError = trivabble.run;