aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdrien Hopkins <[email protected]>2022-08-16 20:16:38 +0000
committerGitHub <[email protected]>2022-08-16 20:16:38 +0000
commitbb40e60e8623ea9a097dc5f7debe97fef94001e0 (patch)
treea611fefe2c47468068d0d13442b5d8df009ed969 /src
parent6392463d4d542385bc515b07407ab462614b16bd (diff)
parent6af45235e86686b2ea1ca54fe061e0f230a644fc (diff)
downloadcoinos-ui-bb40e60e8623ea9a097dc5f7debe97fef94001e0.tar.gz
coinos-ui-bb40e60e8623ea9a097dc5f7debe97fef94001e0.zip
Merge pull request #1 from coinos/i18n
Add Internationalization to CoinOS
Diffstat (limited to 'src')
-rw-r--r--src/components/LandingHeader.svelte37
-rw-r--r--src/components/LocaleSelector.svelte10
-rw-r--r--src/components/index.js1
-rw-r--r--src/lib/i18n.js48
-rw-r--r--src/locales/en.json10
-rw-r--r--src/locales/fr.json10
-rw-r--r--src/routes/[username]/settings.svelte7
-rw-r--r--src/routes/__layout.svelte14
8 files changed, 119 insertions, 18 deletions
diff --git a/src/components/LandingHeader.svelte b/src/components/LandingHeader.svelte
index a8abfaba..cc743b79 100644
--- a/src/components/LandingHeader.svelte
+++ b/src/components/LandingHeader.svelte
@@ -1,8 +1,9 @@
<script>
import { goto } from '$app/navigation';
import { scroll } from '$lib/utils';
- import { Icon } from '$comp';
+ import { Icon, LocaleSelector } from '$comp';
import { user } from '$lib/store';
+ import { _ } from 'svelte-i18n';
export let howItWorks;
export let faq;
@@ -17,25 +18,28 @@
<header class="w-full lg:w-5/6 py-5 mx-auto fixed md:sticky z-10 top-0 bg-white/90">
<nav class="block xl:flex flex-wrap justify-between items-center">
- <a href="/" class="hidden md:block">
- <Icon icon="logo" style="mx-auto mb-5 xl:mb-0" />
- </a>
- <Icon icon="logo" style="block md:hidden ml-5 w-48" />
+ <div class="flex justify-start md:justify-center items-center md:space-x-10">
+ <a href="/" class="hidden md:block">
+ <Icon icon="logo" style="mb-5 xl:mb-0" />
+ </a>
+ <Icon icon="logo" style="block md:hidden ml-5 w-48" />
+ <LocaleSelector style="hidden md:block py-1 mb-5 xl:mb-0" />
+ </div>
<!-- desktop nav -->
<div class="hidden space-x-10 md:flex flex-wrap justify-center items-center font-bold">
- <button on:click={() => scroll(howItWorks)}>How It Works</button>
- <button on:click={() => scroll(faq)}>FAQ</button>
- <button on:click={() => scroll(about)}>About</button>
+ <button on:click={() => scroll(howItWorks)}>{$_('nav.howItWorks')}</button>
+ <button on:click={() => scroll(faq)}>{$_('nav.faq')}</button>
+ <button on:click={() => scroll(about)}>{$_('nav.about')}</button>
{#if !$user}
<button class="border rounded-full px-6 py-2 font-bold" on:click={() => goto('/register')}
- >Start in Seconds
+ >{$_('nav.startInSeconds')}
</button>
<button
class="bg-black text-white border rounded-full px-6 py-2 font-bold"
on:click={() => goto('/login')}
>
- Sign in
+ {$_('nav.signIn')}
</button>
{:else}
<button
@@ -66,21 +70,23 @@
>
<div class="space-y-8 mt-24 ml-10 font-bold text-xl">
<button on:click={() => mobileMenuButtonClick(howItWorks)} class="block"
- >How It Works</button
+ >{$_('nav.howItWorks')}</button
+ >
+ <button on:click={() => mobileMenuButtonClick(faq)} class="block">{$_('nav.faq')}</button>
+ <button on:click={() => mobileMenuButtonClick(about)} class="block"
+ >{$_('nav.about')}</button
>
- <button on:click={() => mobileMenuButtonClick(faq)} class="block">FAQ</button>
- <button on:click={() => mobileMenuButtonClick(about)} class="block">About</button>
{#if !$user}
<button
class="border rounded-full px-6 py-2 font-bold block"
on:click={() => goto('/register')}
- >Start in Seconds
+ >{$_('nav.startInSeconds')}
</button>
<button
class="bg-black text-white border rounded-full px-6 py-2 font-bold block"
on:click={() => goto('/login')}
>
- Sign in
+ {$_('nav.signIn')}
</button>
{:else}
<button
@@ -95,6 +101,7 @@
Sign out
</button>
{/if}
+ <LocaleSelector style="py-1" />
</div>
</div>
</nav>
diff --git a/src/components/LocaleSelector.svelte b/src/components/LocaleSelector.svelte
new file mode 100644
index 00000000..2ae65986
--- /dev/null
+++ b/src/components/LocaleSelector.svelte
@@ -0,0 +1,10 @@
+<script>
+ import { _, locale, locales } from 'svelte-i18n';
+ export let style;
+</script>
+
+<select name="language" bind:value={$locale} class={style}>
+ {#each $locales as locale}
+ <option value={locale}>{locale}</option>
+ {/each}
+</select>
diff --git a/src/components/index.js b/src/components/index.js
index 1003a1b0..39a4e5e7 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -7,6 +7,7 @@ export { default as Icon } from './Icon.svelte';
export { default as Image } from './Image.svelte';
export { default as RegisterOrLogin } from './RegisterOrLogin.svelte';
export { default as AppHeader } from './AppHeader.svelte';
+export { default as LocaleSelector } from './LocaleSelector.svelte';
export { default as LoadingSplash } from './LoadingSplash.svelte';
export { default as PageNotFound } from './404.svelte';
export { default as About } from './About.svelte';
diff --git a/src/lib/i18n.js b/src/lib/i18n.js
new file mode 100644
index 00000000..3105c709
--- /dev/null
+++ b/src/lib/i18n.js
@@ -0,0 +1,48 @@
+import { register, init, getLocaleFromNavigator } from 'svelte-i18n';
+
+// The list of locales to look for
+// ADD ALL NEW LANGUAGE CODES TO THIS LIST
+const localeCodes = ['en', 'fr'];
+
+// the default locale to use if none was found
+const defaultLocale = 'en';
+
+// Adds a new locale based on its code
+function addLocale(localeCode) {
+ register(localeCode, () => import(`../locales/${localeCode}.json`));
+}
+
+// Picks the default locale based on navigator locale and the list of available locales
+function pickLocale(navigatorLocale, availableLocales) {
+ // locale can be null the first time you load this
+ // return the default locale in that case - reloading should fix this
+ if (!navigatorLocale) return defaultLocale;
+
+ // determine langugage part of locale
+ // (e.g. if navigatorLocale is 'en-US', languageCode is 'en')
+ let dashIndex = navigatorLocale ? navigatorLocale.indexOf('-') : -1;
+ let languageCode; // navigator locale without the regional part
+ if (dashIndex === -1) {
+ languageCode = navigatorLocale;
+ } else {
+ languageCode = navigatorLocale.slice(0, dashIndex);
+ }
+
+ // get locale
+ if (availableLocales.includes(navigatorLocale)) {
+ return navigatorLocale;
+ } else if (availableLocales.includes(languageCode)) {
+ return languageCode;
+ } else {
+ return navigatorLocale;
+ }
+}
+
+// add locales
+localeCodes.forEach(addLocale);
+
+let initialLocale = pickLocale(getLocaleFromNavigator(), localeCodes);
+init({
+ fallbackLocale: defaultLocale,
+ initialLocale: initialLocale
+});
diff --git a/src/locales/en.json b/src/locales/en.json
new file mode 100644
index 00000000..a44c202f
--- /dev/null
+++ b/src/locales/en.json
@@ -0,0 +1,10 @@
+{
+ "langname": "English",
+ "nav": {
+ "howItWorks": "How It Works",
+ "faq": "FAQ",
+ "about": "About",
+ "startInSeconds": "Start in Seconds",
+ "signIn": "Sign In"
+ }
+}
diff --git a/src/locales/fr.json b/src/locales/fr.json
new file mode 100644
index 00000000..9adc9488
--- /dev/null
+++ b/src/locales/fr.json
@@ -0,0 +1,10 @@
+{
+ "langname": "Français",
+ "nav": {
+ "howItWorks": "Comment Ça Fonctionne",
+ "faq": "FAQ",
+ "about": "À Propos",
+ "startInSeconds": "Commence en Secondes",
+ "signIn": "Connexion"
+ }
+}
diff --git a/src/routes/[username]/settings.svelte b/src/routes/[username]/settings.svelte
index 5abe58e0..e4d7b0bf 100644
--- a/src/routes/[username]/settings.svelte
+++ b/src/routes/[username]/settings.svelte
@@ -1,5 +1,5 @@
<script>
- import { AppHeader, Icon, Toggle } from '$comp';
+ import { AppHeader, Icon, Toggle, LocaleSelector } from '$comp';
import { user, colorTheme } from '$lib/store';
let setting = 'account';
@@ -45,6 +45,11 @@
{#if setting === 'account'}
<div>
+ <label for="language" class="font-bold block mb-1">Language</label>
+ <LocaleSelector style="block py-3 w-full" />
+ </div>
+
+ <div>
<label for="username" class="font-bold mb-1 block">Username</label>
<input
type="text"
diff --git a/src/routes/__layout.svelte b/src/routes/__layout.svelte
index 5ffdc9a0..8ac6f20f 100644
--- a/src/routes/__layout.svelte
+++ b/src/routes/__layout.svelte
@@ -1,6 +1,8 @@
<script>
import { SvelteToast } from '@zerodevx/svelte-toast';
- import '../app.css';
+ import '$lib/i18n';
+ import { isLoading, locale } from 'svelte-i18n';
+ import '../app.css';
import { onMount } from 'svelte';
import { connect } from '$lib/socket';
import { user, token } from '$lib/store';
@@ -15,6 +17,14 @@
let ready = false;
onMount(() => {
+ // get locale from local storage
+ let localStorageLocale = localStorage.getItem('svelte-i18n-locale');
+ if (localStorageLocale) locale.set(localStorageLocale);
+
+ locale.subscribe((lng) => {
+ if (lng) localStorage.setItem('svelte-i18n-locale', lng);
+ });
+
if (protectedRoutes.find((p) => $page.url.pathname.match(p))) {
if (!$token) {
goto('/login');
@@ -29,7 +39,7 @@
});
</script>
-{#if ready}
+{#if ready && !$isLoading}
<SvelteToast options={{ reversed: true, intro: { y: 192 } }} />
<slot />
{:else}