mirror of
https://github.com/LemmyNet/joinlemmy-site.git
synced 2024-11-22 12:21:16 +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;
|
border-color: #FFD700 !important;
|
||||||
color: #FFD700;
|
color: #FFD700;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.language-selector {
|
||||||
|
margin-top: 7px;
|
||||||
|
background-color: #333;
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
import { hydrate } from "inferno-hydrate";
|
import { hydrate } from "inferno-hydrate";
|
||||||
import { BrowserRouter } from "inferno-router";
|
import { BrowserRouter } from "inferno-router";
|
||||||
import { App } from "../shared/components/app";
|
import { App } from "../shared/components/app";
|
||||||
import { i18n } from "../shared/i18next";
|
import { getLanguageFromCookie, i18n } from "../shared/i18next";
|
||||||
|
|
||||||
// Setting the language for js browsers
|
// 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 = (
|
const wrapper = (
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { App } from "../shared/components/app";
|
||||||
// import { routes } from "../shared/routes";
|
// import { routes } from "../shared/routes";
|
||||||
import process from "process";
|
import process from "process";
|
||||||
import { Helmet } from "inferno-helmet";
|
import { Helmet } from "inferno-helmet";
|
||||||
import { i18n } from "../shared/i18next";
|
import { getLanguageFromCookie, i18n } from "../shared/i18next";
|
||||||
|
|
||||||
const server = express();
|
const server = express();
|
||||||
const port = 1234;
|
const port = 1234;
|
||||||
|
@ -23,10 +23,21 @@ server.get("/*", async (req, res) => {
|
||||||
const context = {} as any;
|
const context = {} as any;
|
||||||
|
|
||||||
// Setting the language for non-js browsers
|
// Setting the language for non-js browsers
|
||||||
let lang = req.headers["accept-language"]
|
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]
|
? req.headers["accept-language"].split(",")[0]
|
||||||
: "en";
|
: "en";
|
||||||
i18n.changeLanguage(lang);
|
}
|
||||||
|
i18n.changeLanguage(language);
|
||||||
|
|
||||||
const wrapper = (
|
const wrapper = (
|
||||||
<StaticRouter location={req.url} context={context}>
|
<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 { Link } from "inferno-router";
|
||||||
import { LinkLine } from "./link-line";
|
import { LinkLine } from "./link-line";
|
||||||
import { Icon } from "./icon";
|
import { Icon } from "./icon";
|
||||||
|
import { getLanguageName, i18n } from "../i18next";
|
||||||
|
|
||||||
export class Navbar extends Component<any, any> {
|
export class Navbar extends Component<any, any> {
|
||||||
constructor(props: any, context: any) {
|
constructor(props: any, context: any) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleLanguageChange(_: any, event: ChangeEvent<HTMLSelectElement>) {
|
||||||
|
location.href = `/?lang=${event.target.value}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
languageList() {
|
||||||
|
return Object.keys(i18n.services.resourceStore.data).sort();
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -23,6 +32,22 @@ export class Navbar extends Component<any, any> {
|
||||||
<LinkLine />
|
<LinkLine />
|
||||||
</div>
|
</div>
|
||||||
<div class="nav-right">
|
<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">
|
<a href="https://github.com/LemmyNet">
|
||||||
<Icon icon="github" />
|
<Icon icon="github" />
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -60,6 +60,36 @@ const resources = {
|
||||||
pt,
|
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 {
|
function format(value: any, format: any): any {
|
||||||
return format === "uppercase" ? value.toUpperCase() : value;
|
return format === "uppercase" ? value.toUpperCase() : value;
|
||||||
}
|
}
|
||||||
|
@ -68,7 +98,6 @@ i18next.init({
|
||||||
debug: false,
|
debug: false,
|
||||||
// load: 'languageOnly',
|
// load: 'languageOnly',
|
||||||
// initImmediate: false,
|
// initImmediate: false,
|
||||||
lng: "en", // This is changed later
|
|
||||||
fallbackLng: "en",
|
fallbackLng: "en",
|
||||||
resources,
|
resources,
|
||||||
interpolation: { format },
|
interpolation: { format },
|
||||||
|
@ -77,3 +106,23 @@ i18next.init({
|
||||||
export const i18n = i18next as i18nTyped;
|
export const i18n = i18next as i18nTyped;
|
||||||
|
|
||||||
export { resources };
|
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