mirror of
https://github.com/LemmyNet/joinlemmy-site.git
synced 2024-12-22 19:01:28 +00:00
* Add language selector on site (fixes #64) * review fixes
This commit is contained in:
parent
c5baa7f0bc
commit
ba5015d2a7
6 changed files with 842 additions and 1159 deletions
|
@ -60,3 +60,8 @@ img {
|
|||
border-color: #FFD700 !important;
|
||||
color: #FFD700;
|
||||
}
|
||||
|
||||
.language-selector {
|
||||
margin-top: 7px;
|
||||
background-color: #333;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
import { hydrate } from "inferno-hydrate";
|
||||
import { BrowserRouter } from "inferno-router";
|
||||
import { App } from "../shared/components/app";
|
||||
import { i18n } from "../shared/i18next";
|
||||
import { getLanguageFromCookie, 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 = getLanguageFromCookie(document.cookie);
|
||||
if (languageCookie != null) {
|
||||
i18n.changeLanguage(languageCookie);
|
||||
} else {
|
||||
i18n.changeLanguage(navigator.language);
|
||||
}
|
||||
|
||||
const wrapper = (
|
||||
<BrowserRouter>
|
||||
|
|
|
@ -7,7 +7,7 @@ import { App } from "../shared/components/app";
|
|||
// import { routes } from "../shared/routes";
|
||||
import process from "process";
|
||||
import { Helmet } from "inferno-helmet";
|
||||
import { i18n } from "../shared/i18next";
|
||||
import { getLanguageFromCookie, i18n } from "../shared/i18next";
|
||||
|
||||
const server = express();
|
||||
const port = 1234;
|
||||
|
@ -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 = getLanguageFromCookie(req.headers.cookie);
|
||||
var language: string;
|
||||
if (req.query["lang"] != null) {
|
||||
language = req.query["lang"].toString();
|
||||
res.cookie("lang", language, {
|
||||
expires: new Date(Date.now() + 60 * 60 * 24 * 7),
|
||||
});
|
||||
} else if (cookieLang != null) {
|
||||
language = cookieLang;
|
||||
} else {
|
||||
language = req.headers["accept-language"]
|
||||
? req.headers["accept-language"].split(",")[0]
|
||||
: "en";
|
||||
}
|
||||
i18n.changeLanguage(language);
|
||||
|
||||
const wrapper = (
|
||||
<StaticRouter location={req.url} context={context}>
|
||||
|
|
|
@ -1,13 +1,22 @@
|
|||
import { Component } from "inferno";
|
||||
import { Component, ChangeEvent, linkEvent } 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(_: any, 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={linkEvent(this, 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>
|
||||
|
|
|
@ -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,23 @@ i18next.init({
|
|||
export const i18n = i18next as i18nTyped;
|
||||
|
||||
export { resources };
|
||||
|
||||
export function getLanguageName(key: string): string {
|
||||
return languageNames[key];
|
||||
}
|
||||
|
||||
// https://gist.github.com/hunan-rostomyan/28e8702c1cecff41f7fe64345b76f2ca
|
||||
export function getLanguageFromCookie(cookies?: string): string | null {
|
||||
if (cookies == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const key = "lang=";
|
||||
return (
|
||||
cookies
|
||||
.split(";")
|
||||
.map(c => c.trim())
|
||||
.filter(cookie => cookie.substring(0, key.length) === key)
|
||||
.map(cookie => cookie.substring(key.length))[0] || null
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue