Skip to content

Commit 28fa058

Browse files
committed
Add language selector and put languages behind flag.
1 parent 9f27367 commit 28fa058

11 files changed

Lines changed: 294 additions & 211 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<script lang="ts">
2+
import {
3+
availableBrowserLocale,
4+
locales,
5+
localeStore,
6+
} from "$lib/stores/locale.store";
7+
import Button from "$lib/components/ui/Button.svelte";
8+
import Popover from "$lib/components/ui/Popover.svelte";
9+
import { ChevronDownIcon } from "@lucide/svelte";
10+
11+
let buttonRef = $state<HTMLElement>();
12+
let isOpen = $state(false);
13+
</script>
14+
15+
{#if locales.length > 1}
16+
<Button
17+
bind:element={buttonRef}
18+
onclick={() => (isOpen = true)}
19+
variant="tertiary"
20+
class="uppercase"
21+
>
22+
{$localeStore}
23+
<ChevronDownIcon size="1.25rem" />
24+
</Button>
25+
{/if}
26+
{#if isOpen}
27+
<Popover
28+
anchor={buttonRef}
29+
onClose={() => (isOpen = false)}
30+
direction="down"
31+
align="start"
32+
distance="0.25rem"
33+
class="!w-18 !p-1.5"
34+
>
35+
<ul class="flex flex-col">
36+
{#each locales as locale}
37+
<li class="contents">
38+
<Button
39+
onclick={() => {
40+
isOpen = false;
41+
// Switch back to locale auto-detection if locale matches browser
42+
if (locale === availableBrowserLocale) {
43+
localeStore.reset();
44+
} else {
45+
localeStore.set(locale);
46+
}
47+
}}
48+
variant="tertiary"
49+
class={[
50+
"justify-start text-start uppercase",
51+
locale === $localeStore &&
52+
"[ul:not(:hover)_&]:bg-bg-primary_hover",
53+
]}
54+
>
55+
{locale}
56+
</Button>
57+
</li>
58+
{/each}
59+
</ul>
60+
</Popover>
61+
{/if}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
import Trans from "$lib/components/locale/Trans.svelte";
2+
import LanguageSelector from "$lib/components/locale/LanguageSelector.svelte";
23

3-
export { Trans };
4+
export { Trans, LanguageSelector };

src/frontend/src/lib/components/ui/Popover.svelte

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
direction?: Direction;
1515
align?: Align;
1616
distance?: string;
17+
responsive?: boolean;
1718
};
1819
1920
let {
@@ -25,6 +26,7 @@
2526
distance = "0px",
2627
children,
2728
class: className,
29+
responsive = true,
2830
...props
2931
}: Props = $props();
3032
@@ -83,7 +85,7 @@
8385

8486
<svelte:window bind:innerWidth={windowWidth} />
8587

86-
{#if windowWidth >= MOBILE_BREAKPOINT}
88+
{#if windowWidth >= MOBILE_BREAKPOINT || !responsive}
8789
<div
8890
class="fixed inset-0 z-10"
8991
role="presentation"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
// First locale is default directly defined in svelte components
22
export const availableLocales = ["en", "de", "es", "id"];
3+
4+
// List of languages that are actually enabled
5+
export const enabledLocales = ["en"];

src/frontend/src/lib/locales/de.po

Lines changed: 45 additions & 45 deletions
Large diffs are not rendered by default.

src/frontend/src/lib/locales/en.po

Lines changed: 45 additions & 45 deletions
Large diffs are not rendered by default.

src/frontend/src/lib/locales/es.po

Lines changed: 45 additions & 45 deletions
Large diffs are not rendered by default.

src/frontend/src/lib/locales/id.po

Lines changed: 45 additions & 45 deletions
Large diffs are not rendered by default.

src/frontend/src/lib/state/featureFlags.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ export const LARGE_GOOGLE_BUTTON = createFeatureFlagStore(
113113
},
114114
);
115115

116+
export const ENABLE_ALL_LOCALES = createFeatureFlagStore(
117+
"ENABLE_ALL_LOCALES",
118+
false,
119+
);
120+
116121
export default {
117122
DOMAIN_COMPATIBILITY,
118123
OPENID_AUTHENTICATION,
@@ -121,4 +126,5 @@ export default {
121126
CONTINUE_FROM_ANOTHER_DEVICE,
122127
AUTH_FLOW_UPDATES,
123128
LARGE_GOOGLE_BUTTON,
129+
ENABLE_ALL_LOCALES,
124130
} as Record<string, FeatureFlagStore>;

src/frontend/src/lib/stores/locale.store.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,24 @@ import { writableStored } from "./writable.store";
44
import { building } from "$app/environment";
55
import { i18n } from "@lingui/core";
66
import { MacroMessageDescriptor, ChoiceOptions } from "@lingui/core/macro";
7-
import { availableLocales } from "$lib/constants/locale.constants";
7+
import {
8+
availableLocales,
9+
enabledLocales,
10+
} from "$lib/constants/locale.constants";
11+
import { ENABLE_ALL_LOCALES } from "$lib/state/featureFlags";
12+
13+
export const locales = get(ENABLE_ALL_LOCALES)
14+
? availableLocales
15+
: enabledLocales;
816

917
export const browserLocales = building
10-
? [availableLocales[0]] // Fallback during SSG
18+
? [locales[0]] // Fallback during SSG
1119
: (navigator.languages ?? [navigator.language ?? availableLocales[0]]);
1220
export const availableBrowserLocale =
1321
// Exact match
14-
browserLocales.find((ul) => availableLocales.includes(ul)) ??
22+
browserLocales.find((ul) => locales.includes(ul)) ??
1523
// Language-only match
16-
availableLocales.find((al) =>
24+
locales.find((al) =>
1725
browserLocales.some((ul) => ul.split("-")[0] === al.split("-")[0]),
1826
) ??
1927
// Fallback
@@ -37,7 +45,6 @@ export const localeStore: LocaleStore = {
3745
const validLocale = availableLocales.includes(locale)
3846
? locale
3947
: availableLocales[0];
40-
console.log("validLocale", validLocale, locale);
4148
const { messages } = await import(`$lib/locales/${validLocale}.po`);
4249
i18n.loadAndActivate({ locale: locale, messages });
4350
},
@@ -55,14 +62,14 @@ export const localeStore: LocaleStore = {
5562
internalStore.set(locale);
5663
},
5764
reset: async () => {
58-
const { messages } = await import(`$lib/locales/${availableLocales[0]}.po`);
59-
i18n.loadAndActivate({ locale: availableLocales[0], messages });
65+
const { messages } = await import(
66+
`$lib/locales/${availableBrowserLocale}.po`
67+
);
68+
i18n.loadAndActivate({ locale: availableBrowserLocale, messages });
6069
internalStore.set(null);
6170
},
6271
};
6372

64-
console.log("local", localeStore);
65-
6673
// Derives based on localeStore so that translations update on language change
6774
export const t = derived(
6875
localeStore,

0 commit comments

Comments
 (0)