diff --git a/www/game.js b/www/game.js index 18c2e75..aea89ba 100644 --- a/www/game.js +++ b/www/game.js @@ -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})); } diff --git a/www/i18n.js b/www/i18n.js new file mode 100644 index 0000000..dfb8eb6 --- /dev/null +++ b/www/i18n.js @@ -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+'" !!'); + } +} diff --git a/www/index.html b/www/index.html index 394454c..b54e639 100644 --- a/www/index.html +++ b/www/index.html @@ -4,6 +4,8 @@ KoiKoi + + @@ -23,16 +25,19 @@

- - + +

- - + +

- +
+ + +

- +

diff --git a/www/login.css b/www/login.css index 9c43de9..f48bb71 100644 --- a/www/login.css +++ b/www/login.css @@ -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; } diff --git a/www/login.js b/www/login.js index 8682a48..ef51a32 100644 --- a/www/login.js +++ b/www/login.js @@ -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); } diff --git a/www/main.js b/www/main.js index a6172b9..323f5e7 100644 --- a/www/main.js +++ b/www/main.js @@ -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(); }); diff --git a/www/screen.js b/www/screen.js index e2f5c7a..cc10e4b 100644 --- a/www/screen.js +++ b/www/screen.js @@ -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); diff --git a/www/translations.js b/www/translations.js new file mode 100644 index 0000000..f10e5db --- /dev/null +++ b/www/translations.js @@ -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 ?" + } + } +}