(null);
const pagePath = getPagePath(platform, preset);
@@ -65,9 +73,10 @@ export function App() {
muted: muted ? '1' : '0',
loop: loop ? '1' : '0',
preload,
+ locale,
});
history.replaceState(null, '', `/?${params}`);
- }, [platform, styling, preset, skin, source, autoplay, muted, loop, preload]);
+ }, [platform, styling, preset, skin, source, autoplay, muted, loop, preload, locale]);
useEffect(() => {
iframeRef.current?.contentWindow?.postMessage({ type: 'skin-change', skin }, '*');
@@ -93,26 +102,30 @@ export function App() {
iframeRef.current?.contentWindow?.postMessage({ type: 'preload-change', preload }, '*');
}, [preload]);
+ useEffect(() => {
+ iframeRef.current?.contentWindow?.postMessage({ type: 'locale-change', locale }, '*');
+ }, [locale]);
+
// Constrain source to MP4 when switching to audio
useEffect(() => {
if (preset === 'audio' && SOURCES[source].type !== 'mp4') {
setSource(DEFAULT_AUDIO_SOURCE);
}
- }, [preset, source, setSource]);
+ }, [preset, source]);
// Constrain source to DASH when switching to dash-video
useEffect(() => {
if (preset === 'dash-video' && SOURCES[source].type !== 'dash') {
setSource(DEFAULT_DASH_SOURCE);
}
- }, [preset, source, setSource]);
+ }, [preset, source]);
// Constrain source away from DASH for non-DASH presets
useEffect(() => {
if (preset !== 'dash-video' && SOURCES[source].type === 'dash') {
setSource(DEFAULT_SOURCE);
}
- }, [preset, source, setSource]);
+ }, [preset, source]);
// CDN, background video, and vimeo video do not have a Tailwind skin variant.
useEffect(() => {
@@ -124,7 +137,7 @@ export function App() {
const availableSources =
preset === 'audio' ? MP4_SOURCE_IDS : preset === 'dash-video' ? DASH_SOURCE_IDS : NON_DASH_SOURCE_IDS;
- const handleSourceChange = useCallback((value: string) => setSource(value as SourceId), [setSource]);
+ const handleSourceChange = useCallback((value: string) => setSource(value as SourceId), []);
return (
@@ -147,6 +160,8 @@ export function App() {
onLoopChange={setLoop}
preload={preload}
onPreloadChange={setPreload}
+ locale={locale}
+ onLocaleChange={setLocale}
availableSources={availableSources}
isBackgroundVideo={preset === 'background-video'}
isSimpleHls={preset.startsWith('simple-hls-')}
@@ -170,6 +185,7 @@ export function App() {
muted={muted}
loop={loop}
preload={preload}
+ locale={locale}
/>
);
diff --git a/apps/sandbox/app/shell/navbar.tsx b/apps/sandbox/app/shell/navbar.tsx
index 3e267fe7..424cd5a1 100644
--- a/apps/sandbox/app/shell/navbar.tsx
+++ b/apps/sandbox/app/shell/navbar.tsx
@@ -1,4 +1,5 @@
import type { SKINS } from '@app/constants';
+import { SANDBOX_LOCALE_OPTION_GROUPS, type SandboxLocaleTag } from '@app/shared/i18n/locale-meta';
import { PRELOAD_VALUES, type PreloadValue } from '@app/shared/sandbox-listener';
import type { SourceId } from '@app/shared/sources';
import type { Platform, Preset, Skin, Styling } from '@app/types';
@@ -23,6 +24,8 @@ type NavbarProps = {
onLoopChange: (value: boolean) => void;
preload: PreloadValue;
onPreloadChange: (value: PreloadValue) => void;
+ locale: SandboxLocaleTag;
+ onLocaleChange: (value: SandboxLocaleTag) => void;
availableSources: readonly SourceId[];
isBackgroundVideo: boolean;
isSimpleHls: boolean;
@@ -76,6 +79,8 @@ export function Navbar({
onLoopChange,
preload,
onPreloadChange,
+ locale,
+ onLocaleChange,
availableSources,
isBackgroundVideo,
isSimpleHls,
@@ -154,6 +159,8 @@ export function Navbar({
onLoopChange={onLoopChange}
preload={preload}
onPreloadChange={onPreloadChange}
+ locale={locale}
+ onLocaleChange={onLocaleChange}
/>
void;
preload: PreloadValue;
onPreloadChange: (value: PreloadValue) => void;
+ locale: SandboxLocaleTag;
+ onLocaleChange: (value: SandboxLocaleTag) => void;
};
function SettingsMenu({
@@ -201,6 +210,8 @@ function SettingsMenu({
onLoopChange,
preload,
onPreloadChange,
+ locale,
+ onLocaleChange,
}: SettingsMenuProps) {
const [open, setOpen] = useState(false);
const containerRef = useRef(null);
@@ -209,6 +220,7 @@ function SettingsMenu({
const mutedId = useId();
const loopId = useId();
const preloadId = useId();
+ const localeId = useId();
useEffect(() => {
if (!open) return;
@@ -265,8 +277,15 @@ function SettingsMenu({