Add a translation module and add a french translation

This commit is contained in:
Tissevert 2019-01-01 12:57:27 +01:00
parent 0df6cd7ee8
commit 5c1ce754f5
8 changed files with 189 additions and 40 deletions

View file

@ -43,18 +43,18 @@ function Game(modules) {
if(status.step == "Scored") { if(status.step == "Scored") {
if(status.playing) { if(status.playing) {
modules.screen.dialog({ modules.screen.dialog({
text: "You scored ! Do you want to get your points and end the round or KoiKoi ?", text: modules.i18n.get('youScored'),
answers: { answers: [
'End the round': function() {play({koiKoi: false})}, {label: 'endRound', action: function() {play({koiKoi: false})}},
'KoiKoi !': function() {play({koiKoi: true});} {label: 'koikoi', action: function() {play({koiKoi: true});}}
} ]
}); });
} else { } else {
modules.screen.dialog({ modules.screen.dialog({
text: modules.room.name(o.game.playing) + " scored", text: modules.i18n.get('theyScored')(modules.room.name(o.game.playing)),
answers: { answers: [
'Ok': function() {} {label: 'ok', action: function() {}}
} ]
}); });
} }
} }
@ -81,16 +81,16 @@ function Game(modules) {
status.month = game.month; status.month = game.month;
} }
status.dom.appendChild( status.dom.appendChild(
modules.dom.make('li', {textContent: "This month's flower is the " + status.month}) modules.dom.make('li', {textContent: modules.i18n.get('monthFlower')(modules.i18n.get(status.month))})
); );
var turn = null; var turn = null;
status.playing = modules.session.is(game.playing); status.playing = modules.session.is(game.playing);
if(status.playing) { if(status.playing) {
sets.yourHand.dom.classList.toggle("yourTurn", status.step == "ToPlay"); sets.yourHand.dom.classList.toggle("yourTurn", status.step == "ToPlay");
turn = "Your turn"; turn = modules.i18n.get("yourTurn");
} else { } else {
sets.yourHand.dom.classList.remove("yourTurn"); sets.yourHand.dom.classList.remove("yourTurn");
turn = modules.room.name(game.playing) + " is playing"; turn = modules.i18n.get('playing')(modules.room.name(game.playing));
} }
status.dom.appendChild(modules.dom.make('li', {textContent: turn})); status.dom.appendChild(modules.dom.make('li', {textContent: turn}));
} }

32
www/i18n.js Normal file
View file

@ -0,0 +1,32 @@
function I18n(modules) {
var translations = modules.translations;
var language = chooseLanguage();
return {
get: get
};
function chooseLanguage() {
var userPreference = navigator.language || navigator.userLanguage;
if(userPreference != undefined) {
if(translations[userPreference] != undefined) {
return userPreference;
}
var lang = userPreference.replace(/-.*/, '');
for(var key in translations) {
if(key.replace(/-.*/, '') == lang) {
return key;
}
}
}
if(translations['en-US'] != undefined) {
return 'en-US';
}
for(var key in translations) {
return key;
}
}
function get(textId) {
return translations[language][textId] || ('TRANSLATE "'+textId+'" !!');
}
}

View file

@ -4,6 +4,8 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>KoiKoi</title> <title>KoiKoi</title>
<script src="dom.js"></script> <script src="dom.js"></script>
<script src="translations.js"></script>
<script src="i18n.js"></script>
<script src="fun.js"></script> <script src="fun.js"></script>
<script src="screen.js"></script> <script src="screen.js"></script>
<script src="messaging.js"></script> <script src="messaging.js"></script>
@ -23,16 +25,19 @@
<form id="login"> <form id="login">
<input type="submit" name="submitButton" hidden disabled/> <input type="submit" name="submitButton" hidden disabled/>
<p id="join" class="on"> <p id="join" class="on">
<label for="you">Pick a name you like</label><input type="text" name="you"/> <label for="you"></label><input type="text" name="you"/>
<input type="submit" name="join" value="Join" disabled/> <input type="submit" name="join" disabled/>
</p> </p>
<p id="invite"> <p id="invite">
<label for="them">Start a game with</label><input type="text" name="them"/> <label for="them"></label><input type="text" name="them"/>
<input type="submit" name="invite" value="Invite" disabled/> <input type="submit" name="invite" disabled/>
</p> </p>
<ul class="players"></ul> <div id="players">
<span class="message"></span>
<ul class="list"></ul>
</div>
<p id="leave"> <p id="leave">
<input type="button" name="leave" value="Leave"/> <input type="button" name="leave"/>
</p> </p>
</form> </form>
</div> </div>

View file

@ -18,24 +18,24 @@
display: inline; display: inline;
} }
#login .players { #players {
min-height: 4em; min-height: 4em;
border: 1px solid #ccc; border: 1px solid #ccc;
list-style: none;
padding-left: 0;
} }
.players:empty::before { #players .message {
display: block; display: block;
text-align: center; text-align: center;
margin: 1em; margin: 1em;
color: #555; color: #555;
} }
.players.alone::before { #players .message:empty {
content: "No one to play with yet ! Wait a little"; display: none;
} }
.players.notFound::before { #players .list {
content: "No one by that name is awaiting an opponent"; list-style: none;
margin: 0;
padding-left: 0;
} }

View file

@ -1,10 +1,23 @@
function Login(modules) { function Login(modules) {
var root = document.getElementById('login'); var root = document.getElementById('login');
var players = root.getElementsByClassName('players')[0]; var playersMessage = root.getElementsByClassName('message')[0];
var players = root.getElementsByClassName('list')[0];
var join = document.getElementById("join"); var join = document.getElementById("join");
var invite = document.getElementById("invite"); var invite = document.getElementById("invite");
var submit = root.submitButton; var submit = root.submitButton;
var them = null; var them = null;
var invitationAnswers = [{
label: 'accept',
action: function() {
modules.messaging.send({tag: "Answer", accept: true});
modules.screen.select("game");
}
}, {
label: 'decline',
action: function() {
modules.messaging.send({tag: "Answer", accept: false});
}
}];
root.addEventListener('submit', function(e) { root.addEventListener('submit', function(e) {
e.preventDefault(); e.preventDefault();
@ -44,11 +57,8 @@ function Login(modules) {
// invitations should come only from known players, in doubt say «no» // invitations should come only from known players, in doubt say «no»
if(name) { if(name) {
modules.screen.dialog({ modules.screen.dialog({
text: name + " has invited you to a game", text: modules.i18n.get('invited')(name),
answers: { answers: invitationAnswers
Accept: function() {modules.messaging.send({tag: "Answer", accept: true}); modules.screen.select("game");},
Decline: function() {modules.messaging.send({tag: "Answer", accept: false});}
}
}); });
} else { } else {
modules.messaging.send({tag: "Answer", accept: false}); modules.messaging.send({tag: "Answer", accept: false});
@ -96,13 +106,15 @@ function Login(modules) {
players.appendChild(player.dom); players.appendChild(player.dom);
}); });
var exact = filtered.find(exactMatch(name)); var exact = filtered.find(exactMatch(name));
players.classList.remove("alone", "notFound"); playersMessage.textContent = '';
if(exact != undefined) { if(exact != undefined) {
them = exact.key; them = exact.key;
} else if(filtered.length == 1) { } else if(filtered.length == 1) {
them = filtered[0].key; them = filtered[0].key;
} else if(filtered.length == 0) { } else if(filtered.length == 0) {
players.classList.add(name.length > 0 ? "notFound" : "alone"); playersMessage.textContent = modules.i18n.get(
name.length > 0 ? "notFound" : "alone"
);
} }
formDisable("invite", them == undefined); formDisable("invite", them == undefined);
} }

View file

@ -1,13 +1,29 @@
window.addEventListener('load', function() { window.addEventListener('load', function() {
var dom = Dom(); var dom = Dom();
var translations = Translations();
var i18n = I18n({translations: translations});
var fun = Fun(); var fun = Fun();
var screen = Screen({dom: dom}); var screen = Screen({dom: dom, i18n: i18n});
var messaging = Messaging(); var messaging = Messaging();
var session = Session({messaging: messaging}); var session = Session({messaging: messaging});
var room = Room({dom: dom, messaging: messaging, session: session, fun: fun}); var room = Room({dom: dom, messaging: messaging, session: session, fun: fun});
var login = Login({dom: dom, messaging: messaging, room: room, screen: screen, session: session}); var login = Login({dom: dom, i18n: i18n, messaging: messaging, room: room, screen: screen, session: session});
var hanafuda = Hanafuda({fun: fun}); var hanafuda = Hanafuda({fun: fun});
var game = Game({dom: dom, fun: fun, hanafuda: hanafuda, messaging: messaging, room: room, screen: screen, session: session}); var game = Game({dom: dom, i18n: i18n, fun: fun, hanafuda: hanafuda, messaging: messaging, room: room, screen: screen, session: session});
var domElems = {
join: document.getElementById('login').join,
invite: document.getElementById('login').invite,
leave: document.getElementById('login').leave,
pickName: document.getElementById('join').getElementsByTagName('label')[0],
startGameWith: document.getElementById('invite').getElementsByTagName('label')[0]
};
for(var key in domElems) {
switch(domElems[key].tagName.toLowerCase()) {
case 'input': domElems[key].value = i18n.get(key); break;
default: domElems[key].textContent = i18n.get(key);
}
}
messaging.start(); messaging.start();
}); });

View file

@ -25,10 +25,10 @@ function Screen(modules) {
var dialog = modules.dom.make('div', {}); var dialog = modules.dom.make('div', {});
dialog.appendChild(modules.dom.make('p', {textContent: config.text})); dialog.appendChild(modules.dom.make('p', {textContent: config.text}));
var answers = modules.dom.make('p', {class: 'answers'}); var answers = modules.dom.make('p', {class: 'answers'});
for(var key in config.answers) { for(var i in config.answers) {
answers.appendChild(modules.dom.make('button', { answers.appendChild(modules.dom.make('button', {
textContent: key, textContent: modules.i18n.get(config.answers[i].label),
onClick: closeAndRun(layer, config.answers[key]) onClick: closeAndRun(layer, config.answers[i].action)
})); }));
} }
dialog.appendChild(answers); dialog.appendChild(answers);

84
www/translations.js Normal file
View file

@ -0,0 +1,84 @@
function Translations() {
return {
'en-US': {
BushClover: "bush clover",
Cherry: "cherry",
Chrysanthemum: "chrysanthemum",
Iris: "iris",
Maple: "maple",
Paulownia: "paulownias",
Peony: "peony",
Pine: "pine",
Plum: "plum",
SusukiGrass: "susuki grass",
Willow: "willow",
Wisteria: "wisteria",
accept: "Accept",
alone: "No one to play with yet ! Wait a little",
decline: "Decline",
endRound: "End the round",
join: "Join",
invite: "Invite",
invited: function(name) {
return name + " has invited you to a game";
},
koikoi: "KoiKoi !!",
leave: "Leave",
monthFlower: function(flower) {
return "This month's flower is the " + flower;
},
notFound: "No one goes by that name",
pickName: "Pick a name you like",
playing: function(name) {
return name + " is playing";
},
ok: "Ok",
startGameWith: "Start a game with",
theyScored: function(name) {
return name + " scored";
},
yourTurn: "Your turn",
youScored: "You scored ! Do you want to get your points and end the round or KoiKoi ?"
},
'fr-FR': {
BushClover: "lespédézas",
Cherry: "cerisiers",
Chrysanthemum: "chrysanthèmes",
Iris: "iris",
Maple: "érables",
Paulownia: "paulownias",
Peony: "pivoines",
Pine: "pins",
Plum: "prunus",
SusukiGrass: "herbes susukis",
Willow: "saules",
Wisteria: "glycines",
accept: "Accepter",
alone: "Personne pour jouer pour l'instant ! Attendez un peu",
decline: "Refuser",
endRound: "Finir la manche",
join: "Entrer",
invite: "Inviter",
invited: function(name) {
return name + " vous propose une partie";
},
koikoi: "KoiKoi !!",
leave: "Partir",
monthFlower: function(flower) {
return "C'est le mois des " + flower;
},
notFound: "Personne ne s'appelle comme ça",
pickName: "Choisissez votre nom",
playing: function(name) {
return "C'est à " + name;
},
ok: "Ok",
startGameWith: "Commencer une partie avec",
theyScored: function(name) {
return name + " a marqué";
},
yourTurn: "À vous",
youScored: "Vous avez marqué ! Voulez-vous empocher vos gains et terminer la manche ou faire KoiKoi ?"
}
}
}