Skip to content

Commit

Permalink
Merge pull request #185 from openstreetmap-polska/defaultLanguage
Browse files Browse the repository at this point in the history
Default language. Generate build for every lang
  • Loading branch information
starsep authored Dec 25, 2023
2 parents 3f56961 + ab39e06 commit b07c06a
Show file tree
Hide file tree
Showing 13 changed files with 71 additions and 31 deletions.
16 changes: 8 additions & 8 deletions .github/workflows/deploy_development.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,21 @@ jobs:
run: npm run typecheck
- name: Set git commit
run: echo "VITE_GIT_COMMIT=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: Create robots.txt
run: |
cat << 'EOF' >> public/robots.txt
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow: /
EOF
- name: Build app
env:
VITE_ENV: development
VITE_OSM_API_URL: ${{ secrets.REACT_APP_OSM_API_URL }}
VITE_OSM_OAUTH2_CLIENT_ID: ${{ secrets.REACT_APP_OSM_OAUTH2_CLIENT_ID }}
VITE_OSM_OAUTH2_CLIENT_SECRET: ${{ secrets.REACT_APP_OSM_OAUTH2_CLIENT_SECRET }}
VITE_BACKEND_API_URL: ${{ secrets.REACT_APP_BACKEND_API_URL_NEW }}
run: npm run build
- name: Create robots.txt
run: |
cat << 'EOF' >> build/robots.txt
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow: /
EOF
run: npm run build && ./scripts/build_every_lang.sh
- name: Run deploy script on host
run: |
rsync -rp -e 'ssh -p ${{ secrets.SSH_HOST_NEW_PORT }}' build/* ${{ secrets.SSH_USER_NEW }}@${{ secrets.SSH_HOST_NEW_IP }}:~/dev-static/
6 changes: 3 additions & 3 deletions .github/workflows/deploy_production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ jobs:
run: npm run typecheck
- name: Set git commit
run: echo "VITE_GIT_COMMIT=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: Create robots.txt
run: touch public/robots.txt
- name: Build app
env:
VITE_ENV: production
VITE_OSM_API_URL: ${{ secrets.REACT_APP_OSM_API_URL }}
VITE_OSM_OAUTH2_CLIENT_ID: ${{ secrets.REACT_APP_OSM_OAUTH2_CLIENT_ID }}
VITE_OSM_OAUTH2_CLIENT_SECRET: ${{ secrets.REACT_APP_OSM_OAUTH2_CLIENT_SECRET }}
VITE_BACKEND_API_URL: ${{ secrets.REACT_APP_BACKEND_API_URL_NEW }}
run: npm run build
- name: Create robots.txt
run: touch build/robots.txt
run: npm run build && ./scripts/build_every_lang.sh
- name: Run deploy script on host
run: |
rsync -rp -e 'ssh -p ${{ secrets.SSH_HOST_NEW_PORT }}' build/* ${{ secrets.SSH_USER_NEW }}@${{ secrets.SSH_HOST_NEW_IP }}:~/prod-static/
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="%VITE_DEFAULT_LANG%">
<head>
<title>OpenAEDMap - Map of Defibrillators</title>
<meta charset="utf-8" />
Expand Down
16 changes: 16 additions & 0 deletions scripts/build_every_lang.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -eu
LANG_PLACEHOLDER=LANG_PLACEHOLDER
VITE_DEFAULT_LANG=$LANG_PLACEHOLDER
npm run build -- --outDir build/$VITE_DEFAULT_LANG --base "/$VITE_DEFAULT_LANG"

for lang in public/locales/*; do
lang=$(basename "$lang")
if [[ $lang = "debug" ]]; then
continue
fi
echo "Generating $lang"
cp -r "build/$LANG_PLACEHOLDER" "build/$lang"
sed -i -- "s/$LANG_PLACEHOLDER/$lang/g" "build/$lang/index.html" "build/$lang/assets"/*
done
rm -rf "build/$LANG_PLACEHOLDER"
5 changes: 3 additions & 2 deletions src/components/downloadCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import Icon from "@mdi/react";
import { mdiDownload } from "@mdi/js";
import { backendBaseUrl, fetchCountriesData } from "~/backend";
import { Country } from "../model/country";
import {useLanguage} from "~/i18n";

const worldCountryCode = "WORLD";

export default function DownloadCard() {
const { t, i18n: { resolvedLanguage } } = useTranslation();
const language = resolvedLanguage ?? "en";
const { t} = useTranslation();
const language = useLanguage();
function countryName(country: Country) {
if (country.code === worldCountryCode) return t("sidebar.world");
const backendLanguageUppercase = language.toUpperCase();
Expand Down
5 changes: 3 additions & 2 deletions src/components/languageSwitcher.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import React from "react";
import i18n from "i18next";
import { Navbar } from "react-bulma-components";
import { languages } from "../i18n";
import {languages, useLanguage} from "../i18n";

export default function LanguageSwitcher() {
const language = useLanguage();
return (
<Navbar.Item px={1}>
<div className="select">
<select
id="language-switcher"
value={i18n.resolvedLanguage ?? "en"}
value={language}
onChange={(e) => {
i18n.changeLanguage(e.target.value);
}}
Expand Down
5 changes: 3 additions & 2 deletions src/components/map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { useAppContext } from "../appContext";
import FooterDiv from "./footer";
import SidebarLeft from "./sidebar-left";
import styleJson from "./map_style";
import {useLanguage} from "~/i18n";

function fillSidebarWithOsmDataAndShow(
nodeId: string,
Expand Down Expand Up @@ -83,8 +84,8 @@ const MapView: FC<MapViewProps> = ({ openChangesetId, setOpenChangesetId }) => {
const {
authState: { auth }, setModalState, sidebarAction, setSidebarAction, sidebarData, setSidebarData,
} = useAppContext();
const { t, i18n: { resolvedLanguage } } = useTranslation();
const language = resolvedLanguage ?? "en";
const { t} = useTranslation();
const language = useLanguage();

const hash4MapName = "map";

Expand Down
5 changes: 3 additions & 2 deletions src/components/navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ import LogInButton from "./logInButton";
import { initialModalState, ModalType } from "../model/modal";
import { useAppContext } from "../appContext";
import ReactStoreBadges from "../3rdparty/react-store-badges";
import {useLanguage} from "~/i18n";

const SiteNavbar: FC<SiteNavbarProps> = ({ toggleSidebarShown }) => {
const { setModalState } = useAppContext();
const [isActive, setIsActive] = React.useState(false);
const { t, i18n: { resolvedLanguage } } = useTranslation();
const language = resolvedLanguage ?? "en";
const { t} = useTranslation();
const language = useLanguage();
return (
<Navbar color="success" className="has-background-green">
<Navbar.Brand>
Expand Down
8 changes: 5 additions & 3 deletions src/components/sidebar/defibrillatorDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { CheckDateField } from "./verificationDate";
import DetailTextRow from "./detailTextRow";
import { accessColourClass } from "./access";
import { initialModalState, ModalType } from "../../model/modal";
import {useLanguage} from "~/i18n";

function photoGallery(data: DefibrillatorData, closeSidebar: () => void) {
const { t } = useTranslation();
Expand Down Expand Up @@ -95,13 +96,14 @@ function photoGallery(data: DefibrillatorData, closeSidebar: () => void) {
}

const DefibrillatorDetails: FC<DefibrillatorDetailsProps> = (props) => {
const { t, i18n: { resolvedLanguage } } = useTranslation();
const { t} = useTranslation();
const language = useLanguage();
const {
data, closeSidebar,
} = props;
if (data === null) return null;
const accessText = data.tags.access ? ` - ${t(`access.${data.tags.access}`)}` : "";
const defibrillatorLocation = data.tags[`defibrillator:location:${resolvedLanguage}`]
const defibrillatorLocation = data.tags[`defibrillator:location:${language}`]
?? data.tags["defibrillator:location"];
const levelText = data.tags.level ? ` (${t("sidebar.level")}: ${data.tags.level})` : "";
const indoorText = data.tags.indoor ? t(`indoor.${data.tags.indoor}`) + levelText : "";
Expand Down Expand Up @@ -172,7 +174,7 @@ const DefibrillatorDetails: FC<DefibrillatorDetailsProps> = (props) => {
</Columns.Column>
<Columns.Column className="py-1">
<DetailTextRow
text={data.tags[`description:${resolvedLanguage}`] ?? data.tags.description}
text={data.tags[`description:${language}`] ?? data.tags.description}
translationId="sidebar.description"
/>
</Columns.Column>
Expand Down
5 changes: 3 additions & 2 deletions src/components/sidebar/defibrillatorEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ import ContactPhoneFormField from "./contactNumber";
import { CheckDateFormField } from "./verificationDate";
import { useAppContext } from "../../appContext";
import { DefibrillatorData } from "../../model/defibrillatorData";
import {useLanguage} from "~/i18n";

const DefibrillatorEditor: FC<DefibrillatorEditorProps> = ({
closeSidebar, marker, openChangesetId, setOpenChangesetId, data,
}) => {
const { t, i18n: { resolvedLanguage } } = useTranslation();
const language = resolvedLanguage ?? "en";
const { t } = useTranslation();
const language = useLanguage();
const { authState: { auth }, setModalState } = useAppContext();
const newAED = data === null;
const initialTags = data !== null ? data.tags : { emergency: "defibrillator" };
Expand Down
6 changes: 4 additions & 2 deletions src/components/sidebar/location.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React from "react";
import { useTranslation } from "react-i18next";
import { useLanguage } from "~/i18n";

export default function LocationFormField({ location, setLocation }: LocationFormFieldProps) {
const { t, i18n: { resolvedLanguage } } = useTranslation();
const locationLabelText = `${t("form.location")} (${resolvedLanguage}):`;
const { t} = useTranslation();
const language = useLanguage();
const locationLabelText = `${t("form.location")} (${language}):`;
return (
<div className="field pt-2">
<label htmlFor="aedLocation" className="label has-text-weight-semibold">{locationLabelText}</label>
Expand Down
4 changes: 3 additions & 1 deletion src/components/sidebar/openingHours.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import i18n from "i18next";
import React, { FC } from "react";

import SpanNoData from "./spanNoData";
import {useLanguage} from "~/i18n";

interface OpeningHoursProps {
openingHours: string,
Expand Down Expand Up @@ -39,7 +40,8 @@ function parseOpeningHours(openingHours: string): string | null {

try {
const oh = new OpeningHours(openingHours, null, 2);
const config = getOpeningHoursConfig(i18n.resolvedLanguage ?? "en");
const language = useLanguage();
const config = getOpeningHoursConfig(language);
// @ts-ignore
return oh.prettifyValue({ conf: config });
} catch (error) {
Expand Down
19 changes: 16 additions & 3 deletions src/i18n.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import { initReactI18next, useTranslation } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import Backend from "i18next-http-backend";

Expand Down Expand Up @@ -33,6 +33,7 @@ if (!isProduction) {
languages.debug = { nativeName: "--debug--" };
}
const languagesIsoCodes = Object.keys(languages);
const defaultLanguage = import.meta.env.VITE_DEFAULT_LANGUAGE ?? "en";

i18n
// i18next-http-backend
Expand All @@ -49,13 +50,20 @@ i18n
.init({
debug: !isProduction,
supportedLngs: languagesIsoCodes,
fallbackLng: isProduction ? "en" : "debug",
fallbackLng: isProduction ? defaultLanguage : "debug",
interpolation: {
escapeValue: false, // not needed for react as it escapes by default
},
backend: {
loadPath: "./locales/{{lng}}/{{ns}}.json",
},
detection: {
order: ['localStorage', 'path', 'navigator', 'htmlTag'],
lookupLocalStorage: 'i18nextLng',
// cache user language
caches: ['localStorage'],
excludeCacheFor: ['cimode'],
}
}, (err, t) => {
if (err) return console.log("something went wrong loading", err);
return t("key");
Expand All @@ -65,5 +73,10 @@ i18n.on("languageChanged", (lang: string) => {
document.documentElement.setAttribute("lang", lang);
});

function useLanguage(): string {
const { i18n: { resolvedLanguage } } = useTranslation();
return resolvedLanguage ?? defaultLanguage;
}

export default i18n;
export { languages, languagesIsoCodes };
export { languages, languagesIsoCodes, useLanguage };

0 comments on commit b07c06a

Please sign in to comment.