diff --git a/app.js b/app.js index ecc0c79..915f676 100644 --- a/app.js +++ b/app.js @@ -17,7 +17,8 @@ require.config({ 'd3': '../node_modules/d3/d3.min', 'virtual-dom': '../node_modules/virtual-dom/dist/virtual-dom', 'rbush': '../node_modules/rbush/rbush', - 'helper': 'utils/helper' + 'helper': 'utils/helper', + 'language': 'utils/language' }, shim: { 'leaflet.label': ['leaflet'], diff --git a/lib/gui.js b/lib/gui.js index 9802d86..3f89245 100644 --- a/lib/gui.js +++ b/lib/gui.js @@ -7,7 +7,7 @@ define(['chroma-js', 'map', 'sidebar', 'tabs', 'container', 'legend', Title, About, DataDistributor, FilterGUI, HostnameFilter) { 'use strict'; - return function (config, router) { + return function (config, router, language) { var self = this; var content; var contentDiv; @@ -81,7 +81,7 @@ define(['chroma-js', 'map', 'sidebar', 'tabs', 'container', 'legend', var infobox = new Infobox(config, sidebar, router); var tabs = new Tabs(); var overview = new Container(); - var legend = new Legend(config); + var legend = new Legend(config, language); var newnodeslist = new SimpleNodelist('new', 'firstseen', router, _.t('node.new')); var lostnodeslist = new SimpleNodelist('lost', 'lastseen', router, _.t('node.missing')); var nodelist = new Nodelist(router); diff --git a/lib/legend.js b/lib/legend.js index d97b338..fca8a4f 100644 --- a/lib/legend.js +++ b/lib/legend.js @@ -1,7 +1,7 @@ define(['helper'], function (helper) { 'use strict'; - return function (config) { + return function (config, language) { var self = this; var stats = document.createTextNode(''); var timestamp = document.createTextNode(''); @@ -28,6 +28,8 @@ define(['helper'], function (helper) { h2.textContent = config.siteName; el.appendChild(h2); + language.languageSelect(el); + var p = document.createElement('p'); p.classList.add('legend'); p.innerHTML = ' ' + _.t('sidebar.nodeNew') + '' + diff --git a/lib/main.js b/lib/main.js index 0324ade..10bca3d 100644 --- a/lib/main.js +++ b/lib/main.js @@ -1,5 +1,5 @@ -define(['polyglot', 'moment', 'router', 'leaflet', 'gui', 'helper'], - function (Polyglot, moment, Router, L, GUI, helper) { +define(['polyglot', 'moment', 'router', 'leaflet', 'gui', 'helper', 'language'], + function (Polyglot, moment, Router, L, GUI, helper, Language) { 'use strict'; return function (config) { @@ -150,35 +150,7 @@ define(['polyglot', 'moment', 'router', 'leaflet', 'gui', 'helper'], }; } - function setTranslation(json) { - _.extend(json); - - moment.locale(_.locale(), { - longDateFormat: { - LT: 'HH:mm', - LTS: 'HH:mm:ss', - L: 'DD.MM.YYYY', - LL: 'D. MMMM YYYY', - LLL: 'D. MMMM YYYY HH:mm', - LLLL: 'dddd, D. MMMM YYYY HH:mm' - }, - calendar: json.momentjs.calendar, - relativeTime: json.momentjs.relativeTime - }); - } - - var language = navigator.languages && navigator.languages[0] || navigator.language || navigator.userLanguage; - var locale = config.supportedLocale[0]; - config.supportedLocale.some(function (item) { - if (language.indexOf(item) !== -1) { - locale = item; - return true; - } - return false; - }); - - window._ = new Polyglot({ locale: locale, allowMissing: true }); - helper.getJSON('locale/' + _.locale() + '.json?' + config.cacheBreaker).then(setTranslation); + var language = new Language(config); var router = new Router(); @@ -200,7 +172,7 @@ define(['polyglot', 'moment', 'router', 'leaflet', 'gui', 'helper'], update() .then(function (d) { - var gui = new GUI(config, router); + var gui = new GUI(config, router, language); gui.setData(d); router.setData(d); router.start(); diff --git a/lib/utils/language.js b/lib/utils/language.js new file mode 100644 index 0000000..91b3747 --- /dev/null +++ b/lib/utils/language.js @@ -0,0 +1,59 @@ +define(['polyglot', 'moment', 'helper'], function (Polyglot, moment, helper) { + 'use strict'; + return function (config) { + function languageSelect(el) { + var select = document.createElement('select'); + select.className = 'language-switch'; + select.addEventListener('change', setLocale); + el.appendChild(select); + + // Keep english + select.innerHTML = ''; + for (var i = 0; i < config.supportedLocale.length; i++) { + select.innerHTML += ''; + } + } + + function setLocale(event) { + localStorage.setItem('language', getLocale(event.target.value)); + location.reload(); + } + + function getLocale(input) { + var language = input || localStorage.getItem('language') || navigator.languages && navigator.languages[0] || navigator.language || navigator.userLanguage; + var locale = config.supportedLocale[0]; + config.supportedLocale.some(function (item) { + if (language.indexOf(item) !== -1) { + locale = item; + return true; + } + return false; + }); + return locale; + } + + function setTranslation(json) { + _.extend(json); + + moment.locale(_.locale(), { + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY HH:mm', + LLLL: 'dddd, D. MMMM YYYY HH:mm' + }, + calendar: json.momentjs.calendar, + relativeTime: json.momentjs.relativeTime + }); + } + + window._ = new Polyglot({ locale: getLocale(), allowMissing: true }); + helper.getJSON('locale/' + _.locale() + '.json?' + config.cacheBreaker).then(setTranslation); + + return { + languageSelect: languageSelect + }; + }; +}); diff --git a/scss/modules/_legend.scss b/scss/modules/_legend.scss index 965848d..50e96c1 100644 --- a/scss/modules/_legend.scss +++ b/scss/modules/_legend.scss @@ -1,3 +1,21 @@ +header { + h2 { + display: inline-block; + } +} + +.language-switch { + background: transparent; + border: 0; + color: $color-black; + float: right; + margin: 20px 16px 0 0; + + option { + background: $color-white; + } +} + .legend { .symbol { border-radius: 50%; diff --git a/scss/night.scss b/scss/night.scss index 304a31f..4e37f2f 100644 --- a/scss/night.scss +++ b/scss/night.scss @@ -35,6 +35,14 @@ html { } } + .language-switch { + color: $color-black; + + option { + background: $color-white; + } + } + //@import 'modules/filter'; .filter-node { input {