From 91706b4be618c771d51c98eec38e55024d77318a Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Mon, 14 Feb 2022 18:50:04 +0100 Subject: [PATCH] Add language selector on site (fixes #64) --- src/assets/css/main.css | 5 + src/client/index.tsx | 9 +- src/server/index.tsx | 19 +- src/shared/components/navbar.tsx | 27 +- src/shared/i18next.ts | 35 +- yarn.lock | 1886 ++++++++++++------------------ 6 files changed, 824 insertions(+), 1157 deletions(-) diff --git a/src/assets/css/main.css b/src/assets/css/main.css index 75f68b8..e84e0a3 100644 --- a/src/assets/css/main.css +++ b/src/assets/css/main.css @@ -60,3 +60,8 @@ img { border-color: #FFD700 !important; color: #FFD700; } + +.language-selector { + margin-top: 7px; + background-color: #333; +} diff --git a/src/client/index.tsx b/src/client/index.tsx index 81808d2..96e3b95 100644 --- a/src/client/index.tsx +++ b/src/client/index.tsx @@ -4,7 +4,14 @@ import { App } from "../shared/components/app"; import { i18n } from "../shared/i18next"; // Setting the language for js browsers -i18n.changeLanguage(navigator.language); +// If query param is set, server updates cookie automatically, +// so no need to check the query here +const languageCookie = document.cookie.split("=")[1]; +if (languageCookie != null) { + i18n.changeLanguage(languageCookie); +} else { + i18n.changeLanguage(navigator.language); +} const wrapper = ( diff --git a/src/server/index.tsx b/src/server/index.tsx index 8114ee5..50a20d3 100644 --- a/src/server/index.tsx +++ b/src/server/index.tsx @@ -23,10 +23,21 @@ server.get("/*", async (req, res) => { const context = {} as any; // Setting the language for non-js browsers - let lang = req.headers["accept-language"] - ? req.headers["accept-language"].split(",")[0] - : "en"; - i18n.changeLanguage(lang); + const cookieLang = req.headers.cookie?.split("=")[1]; + if (req.query["lang"] != null) { + const lang = req.query["lang"].toString(); + res.cookie("lang", lang, { + expires: new Date(Date.now() + 60 * 60 * 24 * 7), + }); + i18n.changeLanguage(lang); + } else if (cookieLang != null) { + i18n.changeLanguage(cookieLang); + } else { + const lang = req.headers["accept-language"] + ? req.headers["accept-language"].split(",")[0] + : "en"; + i18n.changeLanguage(lang); + } const wrapper = ( diff --git a/src/shared/components/navbar.tsx b/src/shared/components/navbar.tsx index e58f0e8..81cddd1 100644 --- a/src/shared/components/navbar.tsx +++ b/src/shared/components/navbar.tsx @@ -1,13 +1,22 @@ -import { Component } from "inferno"; +import { Component, ChangeEvent } from "inferno"; import { Link } from "inferno-router"; import { LinkLine } from "./link-line"; import { Icon } from "./icon"; +import { getLanguageName, i18n } from "../i18next"; export class Navbar extends Component { constructor(props: any, context: any) { super(props, context); } + handleLanguageChange(event: ChangeEvent) { + location.href = `/?lang=${event.target.value}`; + } + + languageList() { + return Object.keys(i18n.services.resourceStore.data).sort(); + } + render() { return ( <> @@ -23,6 +32,22 @@ export class Navbar extends Component {