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.playing) {
modules.screen.dialog({
text: "You scored ! Do you want to get your points and end the round or KoiKoi ?",
answers: {
'End the round': function() {play({koiKoi: false})},
'KoiKoi !': function() {play({koiKoi: true});}
}
text: modules.i18n.get('youScored'),
answers: [
{label: 'endRound', action: function() {play({koiKoi: false})}},
{label: 'koikoi', action: function() {play({koiKoi: true});}}
]
});
} else {
modules.screen.dialog({
text: modules.room.name(o.game.playing) + " scored",
answers: {
'Ok': function() {}
}
text: modules.i18n.get('theyScored')(modules.room.name(o.game.playing)),
answers: [
{label: 'ok', action: function() {}}
]
});
}
}
@ -81,16 +81,16 @@ function Game(modules) {
status.month = game.month;
}
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;
status.playing = modules.session.is(game.playing);
if(status.playing) {
sets.yourHand.dom.classList.toggle("yourTurn", status.step == "ToPlay");
turn = "Your turn";
turn = modules.i18n.get("yourTurn");
} else {
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}));
}

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

View File

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

View File

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

View File

@ -1,13 +1,29 @@
window.addEventListener('load', function() {
var dom = Dom();
var translations = Translations();
var i18n = I18n({translations: translations});
var fun = Fun();
var screen = Screen({dom: dom});
var screen = Screen({dom: dom, i18n: i18n});
var messaging = Messaging();
var session = Session({messaging: messaging});
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 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();
});

View File

@ -25,10 +25,10 @@ function Screen(modules) {
var dialog = modules.dom.make('div', {});
dialog.appendChild(modules.dom.make('p', {textContent: config.text}));
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', {
textContent: key,
onClick: closeAndRun(layer, config.answers[key])
textContent: modules.i18n.get(config.answers[i].label),
onClick: closeAndRun(layer, config.answers[i].action)
}));
}
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 ?"
}
}
}