diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/LandingHeader.svelte | 37 | ||||
| -rw-r--r-- | src/components/LocaleSelector.svelte | 10 | ||||
| -rw-r--r-- | src/components/index.js | 1 | ||||
| -rw-r--r-- | src/lib/i18n.js | 48 | ||||
| -rw-r--r-- | src/locales/en.json | 10 | ||||
| -rw-r--r-- | src/locales/fr.json | 10 | ||||
| -rw-r--r-- | src/routes/[username]/settings.svelte | 7 | ||||
| -rw-r--r-- | src/routes/__layout.svelte | 14 |
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} |
