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 {