Skip to content

Commit

Permalink
fix: translations
Browse files Browse the repository at this point in the history
  • Loading branch information
ricardocasares committed Oct 29, 2020
1 parent c38b985 commit 6dad3fe
Show file tree
Hide file tree
Showing 14 changed files with 137 additions and 80 deletions.
14 changes: 1 addition & 13 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
module.exports = {
i18n: {
locales: [
"en",
"en-US",
"en-GB",
"es",
"es-AR",
"es-ES",
"pl",
"pl-PL",
"fr",
"fr-BE",
"fr-CA",
],
locales: ["en", "es", "pl", "fr"],
defaultLocale: "en",
},
};
3 changes: 1 addition & 2 deletions src/components/Player/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import { useContext } from "react";
import { Play, Pause, Square, AlertCircle } from "@geist-ui/react-icons";
import { LineSkeleton } from "@/components/Skeleton";
import { PlayerContext } from "@/lib/context/player";
import { useTranslation } from "@/lib/hooks/useTranslation";

import { Container, Controls, Title, ErrorNotification, Button } from "./style";
import { useTranslation } from "@/lib/hooks/useTranslation";

export const Player = () => {
const { t } = useTranslation();
Expand Down
14 changes: 14 additions & 0 deletions src/components/Toggle/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { FC } from "react";
import { ToggleLeft, ToggleRight } from "@geist-ui/react-icons";

export { ToggleItem } from "./style";

export type Toggle = { active: boolean };

export const Toggle: FC<Toggle> = ({ active }) => {
if (active) {
return <ToggleRight color="var(--cyan)" />;
}

return <ToggleLeft color="var(--accents-5)" />;
};
9 changes: 9 additions & 0 deletions src/components/Toggle/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import styled from "@emotion/styled";

export const ToggleItem = styled.div`
display: grid;
grid-template-columns: 1fr auto;
align-items: center;
border-bottom: 1px solid var(--accents-2);
padding: var(--sz3) 0;
`;
6 changes: 4 additions & 2 deletions src/components/Typography/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import styled from "@emotion/styled";

const map = {
const sizesMap = {
h1: "var(--sz8)",
h2: "var(--sz7)",
h3: "var(--sz6)",
Expand All @@ -11,13 +11,15 @@ const map = {

export type Text = {
as?: string;
muted?: boolean;
};

export const Heading = styled.h1<Text>`
font-weight: 500;
line-height: 1.3em;
margin-bottom: var(--sz4);
font-size: ${({ as = "h1" }) => map[as]};
font-size: ${({ as = "h1" }) => sizesMap[as]};
color: ${({ muted }) => (muted ? "var(--accents-6)" : "var(--foreground)")};
`;

export const Text = styled.p<Text>`
Expand Down
1 change: 0 additions & 1 deletion src/lib/context/player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ export const PlayerContext = createContext<PlayerContext>({
loading: false,
});

// @TODO: This is very messy
export const PlayerProvider = ({ children }) => {
const audio = useRef<HTMLAudioElement>(null);

Expand Down
42 changes: 42 additions & 0 deletions src/lib/context/translate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useRouter } from "next/router";
import { createContext, useEffect, useState } from "react";
import defaultLang from "@/i18n/en.json";

export type Translation = typeof defaultLang;

export type TranslateContext = {
t: Translation;
locale: string;
locales: string[];
};

const cache = new Map<string, Translation>();
cache.set("en", defaultLang);

export const TranslateContext = createContext<TranslateContext>(null);

export const TranslateProvider = ({ children }) => {
const { locale, locales } = useRouter();
const [t, setTranslation] = useState(defaultLang);

useEffect(() => {
if (cache.has(locale)) {
setTranslation(cache.get(locale));
}

if (!cache.has(locale)) {
fetch(`/i18n/${locale}.json`)
.then((r) => r.json())
.then((translation) => {
cache.set(locale, translation);
setTranslation(cache.get(locale));
});
}
}, [locale]);

return (
<TranslateContext.Provider value={{ t, locale, locales }}>
{children}
</TranslateContext.Provider>
);
};
22 changes: 22 additions & 0 deletions src/lib/hooks/useDarkMode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useState, useEffect } from "react";

const modeMap = {
true: "dark",
false: "light",
};

export function useDarkMode() {
const [initialMode, setInitialMode] = useState(false);
const [currentMode, setCurrentMode] = useState(!initialMode);

useEffect(() => {
setInitialMode(window.matchMedia("(prefers-color-scheme: dark)").matches);
}, []);

const toggle = () => {
document.body.classList.toggle(modeMap[(!initialMode).toString()]);
setCurrentMode(!currentMode);
};

return { isDarkMode: currentMode === initialMode, toggle };
}
33 changes: 4 additions & 29 deletions src/lib/hooks/useTranslation.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,6 @@
import { useRouter } from "next/router";
import { useState, useEffect } from "react";
import en from "../../../public/i18n/en.json";
import { useContext } from "react";
import { TranslateContext } from "@/lib/context/translate";

export const useTranslation = createUseTranslation("en", en);

export function createUseTranslation<T>(defaultLocale: string, translation: T) {
const cache = new Map();
cache.set(defaultLocale, translation);

return function useTranslation() {
const { locale } = useRouter();
const [lang] = locale.split("-");
const [t, setTranslation] = useState(translation);

useEffect(() => {
if (cache.has(lang)) {
return setTranslation(cache.get(lang));
}

fetch(`/i18n/${lang}.json`)
.then((r) => r.json())
.then((translation) => {
cache.set(lang, translation);
setTranslation(translation);
});
}, [lang]);

return { t };
};
export function useTranslation() {
return useContext(TranslateContext);
}
9 changes: 9 additions & 0 deletions src/lib/providers/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { FC } from "react";
import { PlayerProvider } from "@/lib/context/player";
import { TranslateProvider } from "@/lib/context/translate";

export const Providers: FC = ({ children }) => (
<TranslateProvider>
<PlayerProvider>{children}</PlayerProvider>
</TranslateProvider>
);
8 changes: 4 additions & 4 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { AppProps } from "next/app";
import { Global } from "@emotion/core";
import { Providers } from "@/lib/providers";
import { styles } from "@/css/global";
import { Layout } from "@/components/Layout";
import { Header } from "@/components/Header";
import { Scrollable } from "@/components/Scrollable";
import { Player } from "@/components/Player";
import { AppProps } from "next/app";
import { PlayerProvider } from "@/lib/context/player";

export function App({ Component, pageProps }: AppProps) {
return (
<PlayerProvider>
<Providers>
<Global styles={styles} />
<Layout>
<Header />
Expand All @@ -18,7 +18,7 @@ export function App({ Component, pageProps }: AppProps) {
</Scrollable>
<Player />
</Layout>
</PlayerProvider>
</Providers>
);
}

Expand Down
4 changes: 2 additions & 2 deletions src/pages/search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { SearchInput } from "@/components/SearchInput";
import { StationCardList } from "@/components/StationCardList";
import { useTranslation } from "@/lib/hooks/useTranslation";

export const Index = () => {
export const Search = () => {
const { t } = useTranslation();
const input = useRef<HTMLInputElement>(null);
const [Q, setQ] = useState("");
Expand Down Expand Up @@ -47,4 +47,4 @@ export const Index = () => {
);
};

export default Index;
export default Search;
50 changes: 24 additions & 26 deletions src/pages/settings.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,38 @@
import Link from "next/link";
import { Box } from "@/components/Box";
import { Toggle, ToggleItem } from "@/components/Toggle";
import { Heading } from "@/components/Typography";
import { useTranslation } from "@/lib/hooks/useTranslation";
import { Stack } from "@/components/Stack";

const localesMap = {
en: "English",
es: "Español",
fr: "Française",
pl: "Polski",
};

export const Index = () => {
const { t } = useTranslation();
const { t, locale, locales } = useTranslation();

return (
<Box p={["var(--sz4)"]}>
<Heading as="h3">{t.settings.title}</Heading>
<Heading as="h4" muted>
{t.settings.language}
</Heading>

<Heading as="h4">{t.settings.language}</Heading>

<Stack as="ul" stackSpacing={["var(--sz3)"]}>
<li>
<Link href="/settings" locale="en">
<a>English</a>
</Link>
</li>
<li>
<Link href="/settings" locale="es">
<a>Español</a>
</Link>
</li>
<li>
<Link href="/settings" locale="fr">
<a>Française</a>
</Link>
</li>
<li>
<Link href="/settings" locale="pl">
<a>Polski</a>
</Link>
</li>
</Stack>
<ul>
{locales.map((lang) => (
<li key={lang}>
<Link href="/settings" locale={lang}>
<ToggleItem>
<a>{localesMap[lang]}</a>
<Toggle active={locale == lang} />
</ToggleItem>
</Link>
</li>
))}
</ul>
</Box>
);
};
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"jsx": "preserve",
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
"@/*": ["src/*", "public/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
Expand Down

0 comments on commit 6dad3fe

Please sign in to comment.