Add language selector on site (fixes #64)

This commit is contained in:
Felix Ableitner 2022-02-14 18:50:04 +01:00
parent c5baa7f0bc
commit 91706b4be6
6 changed files with 824 additions and 1157 deletions

View file

@ -60,3 +60,8 @@ img {
border-color: #FFD700 !important;
color: #FFD700;
}
.language-selector {
margin-top: 7px;
background-color: #333;
}

View file

@ -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 = (
<BrowserRouter>

View file

@ -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 = (
<StaticRouter location={req.url} context={context}>

View file

@ -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<any, any> {
constructor(props: any, context: any) {
super(props, context);
}
handleLanguageChange(event: ChangeEvent<HTMLSelectElement>) {
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<any, any> {
<LinkLine />
</div>
<div class="nav-right">
<div>
<select
onChange={this.handleLanguageChange}
class="text-light bd-dark language-selector"
>
{this.languageList().map((language, i) => (
<option
key={i}
value={language}
selected={i18n.language.startsWith(language)}
>
{getLanguageName(language)}
</option>
))}
</select>
</div>
<a href="https://github.com/LemmyNet">
<Icon icon="github" />
</a>

View file

@ -60,6 +60,36 @@ const resources = {
pt,
};
const languageNames = {
en: "English",
ru: "Русский",
zh: "中文",
es: "Español",
eu: "Euskara",
bg: "Български",
nl: "Nederlands",
fi: "Suomi",
fr: "Français",
el: "Ελληνικά",
ko: "한국어",
pl: "Polski",
ar: "العربية",
eo: "Esperanto",
de: "Deutsch",
gl: "Galego",
it: "Italiano",
ja: "日本語",
km: "ភាសាខ្មែរ",
nb_NO: "Norsk (Bokmål)",
zh_Hant: "文言",
fa: "فارسی",
id: "Bahasa Indonesia",
mnc: "ᠮᠠᠨᠵᡠ ᡤᡳᠰᡠᠨ",
sv: "Svenska",
vi: "Tiếng Việt",
pt: "Português",
};
function format(value: any, format: any): any {
return format === "uppercase" ? value.toUpperCase() : value;
}
@ -68,7 +98,6 @@ i18next.init({
debug: false,
// load: 'languageOnly',
// initImmediate: false,
lng: "en", // This is changed later
fallbackLng: "en",
resources,
interpolation: { format },
@ -77,3 +106,7 @@ i18next.init({
export const i18n = i18next as i18nTyped;
export { resources };
export function getLanguageName(key: string): string {
return languageNames[key];
}

1886
yarn.lock

File diff suppressed because it is too large Load diff