Add LanguageSwitch component for changing app's language (#25)

Co-authored-by: msramalho <19508417+msramalho@users.noreply.github.com>
This commit is contained in:
wattroll
2022-04-07 00:54:42 +03:00
committed by GitHub
parent 4c1b220d75
commit f024d2195a
12 changed files with 108 additions and 9 deletions

View File

@@ -93,7 +93,8 @@
"warning": "(!) HECHOS CUESTIONADOS"
}
},
"en-US": {
"en": {
"language_short": "Eng",
"tiles": {
"default": "Map",
"satellite": "Sat"
@@ -192,5 +193,11 @@
"receiver": "Receiver",
"warning": "(!) Highly questioned"
}
},
"ru": {
"language_short": "Рус"
},
"uk": {
"language_short": "Укр"
}
}

View File

@@ -7,7 +7,7 @@ let { DATE_FMT, TIME_FMT } = process.env;
if (!DATE_FMT) DATE_FMT = "MM/DD/YYYY";
if (!TIME_FMT) TIME_FMT = "HH:mm";
export const language = process.env.store.app.language || "en-US";
export const language = process.env.store.app.language || "en";
export function getPathLeaf(path) {
const splitPath = path.split("/");

View File

@@ -23,6 +23,7 @@ import {
} from "../common/utilities.js";
import { ToolbarButton } from "./controls/atoms/ToolbarButton";
import { FullscreenToggle } from "./controls/FullScreenToggle";
import { LanguageSwitch } from "./controls/LanguageSwitch";
class Toolbar extends React.Component {
constructor(props) {
@@ -274,6 +275,15 @@ class Toolbar extends React.Component {
<div className="toolbar-header" onClick={this.props.methods.onTitle}>
<p>{title}</p>
</div>
<div className="toolbar-languages">
<LanguageSwitch
language={this.props.language}
languages={this.props.languages}
actions={{
toggleLanguage: this.props.actions.toggleLanguage,
}}
/>
</div>
<div className="toolbar-tabs">
<TabList>
{narrativesExist
@@ -347,6 +357,7 @@ function mapStateToProps(state) {
narratives: selectors.selectNarratives(state),
shapes: selectors.getShapes(state),
language: state.app.language,
languages: state.app.languages,
toolbarCopy: state.app.toolbar,
activeFilters: selectors.getActiveFilters(state),
activeCategories: selectors.getActiveCategories(state),

View File

@@ -84,7 +84,7 @@ export const Card = ({
onSelect = () => {},
sources = [],
isSelected = false,
language = "en-US",
language = "en",
}) => {
const [isOpen, setIsOpen] = useState(false);
const toggle = () => setIsOpen(!isOpen);

View File

@@ -0,0 +1,24 @@
import { createElement } from "react";
import copy from "../../common/data/copy.json";
export function LanguageSwitch({
language: currentLanguage,
languages,
actions: { toggleLanguage },
}) {
if (!languages || languages.length <= 1) return null;
return createElement("div", {
className: "language-switch",
onClick: () => toggleLanguage(),
children: languages.map((language) =>
createElement("span", {
key: language,
className:
language !== currentLanguage
? "language-option"
: "language-option selected",
children: copy[language].language_short,
})
),
});
}

View File

@@ -3,6 +3,14 @@ import ReactDOM from "react-dom/client";
import { Provider } from "react-redux";
import store from "./store";
import App from "./components/App";
import copy from "./common/data/copy.json";
// XXX: Hack to make migration from "copy.json" and
// adding missing translation strings smoother.
Object.assign(copy, {
ru: { ...copy["en"], ...copy["uk"], ...copy["ru"] },
uk: { ...copy["en"], ...copy["ru"], ...copy["uk"] },
});
const root = ReactDOM.createRoot(document.getElementById("explore-app"));
root.render(
@@ -11,6 +19,21 @@ root.render(
</Provider>
);
store.subscribe(() => {
const { app } = store.getState();
renderAppLanguage(app);
});
// Update language in places that are out of the App's reach
function renderAppLanguage({ language }) {
const html = document.documentElement;
if (language && language !== html.lang) {
html.lang = language;
const title = process.env.page_title[language];
if (title) document.title = title;
}
}
// Expressions from https://exceptionshub.com/how-to-detect-safari-chrome-ie-firefox-and-opera-browser.html
/* eslint-disable */

View File

@@ -227,10 +227,15 @@ function updateDimensions(appState, action) {
}
function toggleLanguage(appState, action) {
const otherLanguage = appState.language === "es-MX" ? "en-US" : "es-MX";
return Object.assign({}, appState, {
language: action.language || otherLanguage,
});
return {
...appState,
language: action.language || selectNextLanguage(appState),
};
function selectNextLanguage({ language, languages }) {
const currentIndex = appState.languages.indexOf(language);
const nextIndex = (currentIndex + 1) % languages.length;
return languages[nextIndex];
}
}
function updateSource(appState, action) {

View File

@@ -0,0 +1,22 @@
.language-switch {
padding: 1.5em 1em;
color: $midwhite;
text-transform: uppercase;
cursor: pointer;
user-select: none;
.language-option {
padding: 0.5em 0.25em;
transition: 0.2s ease;
border-bottom: solid 2px transparent;
&.selected {
font-weight: bold;
border-bottom-color: $midwhite;
color: $offwhite;
}
}
&:hover {
.language-option {
border-bottom-color: $offwhite;
}
}
}

View File

@@ -14,3 +14,4 @@
@import "cover";
@import "search";
@import "satelliteoverlaytoggle";
@import "languageswitch";

View File

@@ -66,7 +66,8 @@ const initial = {
},
},
shapes: [],
language: "en-US",
language: "en",
languages: ["en", "ru", "uk"],
cluster: {
radius: 30,
minZoom: 2,