/* * Copyright (C) 2026 Fluxer Contributors * * This file is part of Fluxer. * * Fluxer is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Fluxer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Fluxer. If not, see . */ /** @jsxRuntime automatic */ /** @jsxImportSource hono/jsx */ import {AllLocales} from '@fluxer/constants/src/Locales'; import {getLocaleName} from '@fluxer/locale/src/LocaleService'; import {FlagSvg} from '@fluxer/marketing/src/components/Flags'; import {TranslateIcon} from '@fluxer/marketing/src/components/icons/TranslateIcon'; import type {MarketingContext} from '@fluxer/marketing/src/MarketingContext'; import {href, prependBasePath} from '@fluxer/marketing/src/UrlUtils'; import {CsrfInput} from '@fluxer/ui/src/components/CsrfInput'; interface LocaleSelectorProps { ctx: MarketingContext; currentPath: string; } export function LocaleSelector(props: LocaleSelectorProps): JSX.Element { return (
); } interface LocaleSelectorTriggerProps { ctx: MarketingContext; className?: string; text?: string; } export function LocaleSelectorTrigger(props: LocaleSelectorTriggerProps): JSX.Element { const {ctx, className, text} = props; const label = ctx.i18n.getMessage('languages.change_language', ctx.locale); const baseClass = 'locale-toggle flex items-center justify-center rounded-lg p-2 transition-colors hover:bg-gray-100'; const classes = [baseClass, className].filter(Boolean).join(' '); return ( {text ? {text} : null} ); } export function LocaleSelectorModal(props: LocaleSelectorProps): JSX.Element { const ctx = props.ctx; const currentPath = props.currentPath; const title = ctx.i18n.getMessage('languages.choose_your_language', ctx.locale); const notice = ctx.i18n.getMessage( 'company_and_resources.source_and_contribution.translation.llm_translation_note', ctx.locale, ); return (

{title}

{notice}

{AllLocales.map((locale) => { const isCurrent = locale === ctx.locale; const nativeName = getLocaleName(locale); const localizedName = getLocalizedLocaleName(ctx, locale); const localeCode = locale; return (
); })}
); } function getLocalizedLocaleName(ctx: MarketingContext, locale: string): string { switch (locale) { case 'ar': return ctx.i18n.getMessage('languages.list.arabic', ctx.locale); case 'bg': return ctx.i18n.getMessage('languages.list.bulgarian', ctx.locale); case 'cs': return ctx.i18n.getMessage('languages.list.czech', ctx.locale); case 'da': return ctx.i18n.getMessage('languages.list.danish', ctx.locale); case 'de': return ctx.i18n.getMessage('languages.list.german', ctx.locale); case 'el': return ctx.i18n.getMessage('languages.list.greek', ctx.locale); case 'en-GB': return ctx.i18n.getMessage('languages.list.english', ctx.locale); case 'en-US': return ctx.i18n.getMessage('languages.list.english_us', ctx.locale); case 'es-ES': return ctx.i18n.getMessage('languages.list.spanish_spain', ctx.locale); case 'es-419': return ctx.i18n.getMessage('languages.list.spanish_latin_america', ctx.locale); case 'fi': return ctx.i18n.getMessage('languages.list.finnish', ctx.locale); case 'fr': return ctx.i18n.getMessage('languages.list.french', ctx.locale); case 'he': return ctx.i18n.getMessage('languages.list.hebrew', ctx.locale); case 'hi': return ctx.i18n.getMessage('languages.list.hindi', ctx.locale); case 'hr': return ctx.i18n.getMessage('languages.list.croatian', ctx.locale); case 'hu': return ctx.i18n.getMessage('languages.list.hungarian', ctx.locale); case 'id': return ctx.i18n.getMessage('languages.list.indonesian', ctx.locale); case 'it': return ctx.i18n.getMessage('languages.list.italian', ctx.locale); case 'ja': return ctx.i18n.getMessage('languages.list.japanese', ctx.locale); case 'ko': return ctx.i18n.getMessage('languages.list.korean', ctx.locale); case 'lt': return ctx.i18n.getMessage('languages.list.lithuanian', ctx.locale); case 'nl': return ctx.i18n.getMessage('languages.list.dutch', ctx.locale); case 'no': return ctx.i18n.getMessage('languages.list.norwegian', ctx.locale); case 'pl': return ctx.i18n.getMessage('languages.list.polish', ctx.locale); case 'pt-BR': return ctx.i18n.getMessage('languages.list.portuguese_brazil', ctx.locale); case 'ro': return ctx.i18n.getMessage('languages.list.romanian', ctx.locale); case 'ru': return ctx.i18n.getMessage('languages.list.russian', ctx.locale); case 'sv-SE': return ctx.i18n.getMessage('languages.list.swedish', ctx.locale); case 'th': return ctx.i18n.getMessage('languages.list.thai', ctx.locale); case 'tr': return ctx.i18n.getMessage('languages.list.turkish', ctx.locale); case 'uk': return ctx.i18n.getMessage('languages.list.ukrainian', ctx.locale); case 'vi': return ctx.i18n.getMessage('languages.list.vietnamese', ctx.locale); case 'zh-CN': return ctx.i18n.getMessage('languages.list.chinese_simplified', ctx.locale); case 'zh-TW': return ctx.i18n.getMessage('languages.list.chinese_traditional', ctx.locale); default: return locale; } }