diff --git a/frontend/public/fonts/noto-sans-mongolian/SOURCE.md b/frontend/public/fonts/noto-sans-mongolian/SOURCE.md index 844260e..9c38df4 100644 --- a/frontend/public/fonts/noto-sans-mongolian/SOURCE.md +++ b/frontend/public/fonts/noto-sans-mongolian/SOURCE.md @@ -7,5 +7,5 @@ Font copyright: Copyright 2018 Google Inc. All Rights Reserved. - License: SIL Open Font License 1.1; see the accompanying LICENSE. - Retrieved: 2026-11-08. -Used only by the Unicode Mongolian sample in the development layout route. +Used by the Mongolian UI at `/mn-Mong`. The font and license are served together from this directory. diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index dd76140..8ea37b4 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -26,7 +26,7 @@ import { isAuthorityDependentQuery, localesKeys, sessionKeys } from '@/lib/query import { isCountsPath } from '@/lib/routeLocales' import { switchPostFilterLocale } from '@/lib/posts' import { switchWikiLocale } from '@/lib/wiki' -import { useLocale, useVerticalPreview } from '@/lib/useLocale' +import { useLocale, useUILocale, useVerticalPreview } from '@/lib/useLocale' import { applyClientAnimationMode, applyClientAppearance, fetchUserThemeSlots, @@ -46,7 +46,7 @@ import ServiceUnavailable from '@/pages/ServiceUnavailable' import type { ComponentType, Dispatch, FC, ReactNode, SetStateAction } from 'react' import type { RouteMatch } from 'react-router-dom' -import type { AvailableLocale, LocaleCode } from '@/lib/locales' +import type { AvailableLocale, LocaleCode, UILocaleCode } from '@/lib/locales' import type { PageRoute } from '@/lib/routeLocales' import type { User } from '@/types' @@ -272,11 +272,16 @@ const RoutedApp = ({ locales }: { locales: AvailableLocale[] }) => { const robots = isCountsPath (location.pathname) ? 'noindex' : route?.route.handle?.robots const pagePath = unlocalisedPath (location.pathname) const countsPage = pagePath === '/counts' || pagePath.startsWith ('/counts/') - const switchLocale = async (targetLocale: LocaleCode): Promise => { + const switchLocale = async (target: UILocaleCode): Promise => { + const targetLocale = target === 'mn-Mong' ? 'ja' : target + if (targetLocale === locale) + return switchLocalePath (location, target) const resolve = route?.route.handle?.switchLocale - return (resolve != null && route != null) - ? resolve ({ location, params: route.params, locale, targetLocale }) + const destination = + (resolve != null && route != null) + ? await resolve ({ location, params: route.params, locale, targetLocale }) : switchLocalePath (location, targetLocale) + return target === 'mn-Mong' ? `/mn-Mong${unlocalisedPath (destination)}` : destination } const [user, setUserState] = useState ( () => client.getQueryData (sessionKeys.current) ?? null) @@ -413,6 +418,7 @@ const RoutedApp = ({ locales }: { locales: AvailableLocale[] }) => { const LocaleRoute: FC = () => { const { locale } = useParams () + const uiLocale = useUILocale () const location = useLocation () const verticalPreview = isVerticalPreviewPath (location.pathname) const { i18n } = useTranslation () @@ -433,10 +439,10 @@ const LocaleRoute: FC = () => { useLayoutEffect (() => { if (activeLocale != null) - document.documentElement.lang = activeLocale - if (activeLocale != null && i18n.language !== activeLocale) - void i18n.changeLanguage (activeLocale) - }, [activeLocale, i18n]) + document.documentElement.lang = uiLocale + if (activeLocale != null && i18n.language !== uiLocale) + void i18n.changeLanguage (uiLocale) + }, [activeLocale, uiLocale, i18n]) const redirect = legacyLocalePath (location, pathname => resolvePageRoute (pathname) != null) if (!(isLocaleCode (locale)) && !verticalPreview && redirect == null) diff --git a/frontend/src/components/TopNav.tsx b/frontend/src/components/TopNav.tsx index 4be2888..4720374 100644 --- a/frontend/src/components/TopNav.tsx +++ b/frontend/src/components/TopNav.tsx @@ -4,7 +4,7 @@ import { Globe } from 'lucide-react' import { Fragment, useEffect, useLayoutEffect, useRef, useState } from 'react' import { useLocation } from 'react-router-dom' -import { useLocale, useLocaleNavigate, useVerticalPreview } from '@/lib/useLocale' +import { useLocale, useLocaleNavigate, useUILocale, useVerticalPreview } from '@/lib/useLocale' import LocalisedText, { formatUIString } from '@/components/LocalisedText' import Separator from '@/components/MenuSeparator' import PrefetchLink from '@/components/PrefetchLink' @@ -13,8 +13,10 @@ import TranslatedText from '@/components/TranslatedText' import { toast } from '@/components/ui/use-toast' import { WikiIdBus } from '@/lib/eventBus/WikiIdBus' import { isLocaleCode, - localeFromPath, + isUILocaleCode, + MONGOLIAN_LOCALE, switchLocalePath, + uiLocaleFromPath, unlocalisedPath } from '@/lib/locales' import { uiMessage, uiMessageLanguage } from '@/lib/messages' import { useUITranslation } from '@/lib/useUITranslation' @@ -28,13 +30,13 @@ import { fetchWikiPage } from '@/lib/wiki' import type { FC, MouseEvent } from 'react' -import type { AvailableLocale, LocaleCode } from '@/lib/locales' +import type { AvailableLocale, UILocaleCode } from '@/lib/locales' import type { Material, Menu, MenuVisibleItem, Tag, User } from '@/types' type Props = { user: User | null locales: AvailableLocale[] - resolveLocaleSwitch?: (locale: LocaleCode) => Promise } + resolveLocaleSwitch?: (locale: UILocaleCode) => Promise } type NavDensity = 'auto' | 'comfortable' | 'compact' @@ -47,7 +49,7 @@ export const menuOutline = ( pathName: string }, ): Menu => { const pathName = unlocalisedPath (fullPathname) - const locale = localeFromPath (fullPathname) ?? 'ja' + const locale = uiLocaleFromPath (fullPathname) const message = ( key: Parameters[1], @@ -137,8 +139,11 @@ export const menuOutline = ( const TopNav: FC = ({ user, locales, resolveLocaleSwitch }) => { const { message, label } = useUITranslation ('shared') const locale = useLocale () + const uiLocale = useUILocale () const verticalPreview = useVerticalPreview () - const localeName = locales.find (entry => entry.code === locale)?.name + const uiLocales = [...locales.filter (entry => isLocaleCode (entry.code)), + ...(locales.some (entry => entry.code === 'ja') ? [MONGOLIAN_LOCALE] : [])] + const localeName = uiLocales.find (entry => entry.code === uiLocale)?.name const navigate = useLocaleNavigate () const location = useLocation () const currentLocation = useRef (location) @@ -443,17 +448,18 @@ const TopNav: FC = ({ user, locales, resolveLocaleSwitch }) => { rounded px-1 focus-within:ring-2">