File size: 4,984 Bytes
ec4551b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | 'use client';
import { useModals } from '@gitroom/frontend/components/layout/new-modal';
import {
cookieName,
fallbackLng,
languages,
} from '@gitroom/react/translation/i18n.config';
import i18next from 'i18next';
import useCookie from 'react-use-cookie';
import ReactCountryFlag from 'react-country-flag';
import { List, Box, Group, Text } from '@mantine/core';
import React, { useCallback } from 'react';
import countries from 'i18n-iso-countries';
// Register required locales
import countriesEn from 'i18n-iso-countries/langs/en.json';
import { useT } from '@gitroom/react/translation/get.transation.service.client';
import { ModalWrapperComponent } from '../new-launch/modal.wrapper.component';
import clsx from 'clsx';
countries.registerLocale(countriesEn);
const getCountryCodeForFlag = (languageCode: string) => {
// For multi-region languages, here are some common defaults
if (languageCode === 'en') return 'GB';
if (languageCode === 'es') return 'ES';
if (languageCode === 'ar') return 'SA';
if (languageCode === 'zh') return 'CN';
if (languageCode === 'he') return 'IL';
if (languageCode === 'ja') return 'JP';
if (languageCode === 'ko') return 'KR';
if (languageCode === 'vi') return 'VN';
// Check if language code itself is a valid country code
try {
const countryName = countries.getName(languageCode.toUpperCase(), 'en');
if (countryName) {
return languageCode.toUpperCase();
}
} catch (e) {
// Not a valid country code, continue to next approach
}
// Try to extract region code if language code has a region component (e.g., en-US)
const parts = languageCode.split('-');
if (parts.length > 1) {
const regionCode = parts[1].toUpperCase();
try {
const countryName = countries.getName(regionCode, 'en');
if (countryName) {
return regionCode;
}
} catch (e) {
// Not a valid country code, continue to next approach
}
}
// For most language codes that match their primary country
// Examples: fr->FR, it->IT, de->DE, etc.
return languageCode.toUpperCase();
};
export const ChangeLanguageComponent = () => {
const currentLanguage = i18next.resolvedLanguage || fallbackLng;
const availableLanguages = languages;
const [_, setCookie] = useCookie(cookieName, currentLanguage || fallbackLng);
const modals = useModals();
const t = useT();
const handleLanguageChange = (language: string) => {
setCookie(language);
i18next.changeLanguage(language);
modals.closeCurrent();
const rtlLanguages = ['he', 'ar'];
const dir = rtlLanguages.includes(language) ? 'rtl' : 'ltr';
document.documentElement.setAttribute('dir', dir);
};
// Function to get language name in its native script
const getLanguageName = useCallback((code: string) => {
try {
// Use browser's Intl API to get language name in native script
const displayNames = new Intl.DisplayNames([code], {
type: 'language',
});
return displayNames.of(code);
} catch (error) {
// Fallback to language code if the API isn't supported or language is not found
return code;
}
}, []);
return (
<div className="relative">
<div className="grid grid-cols-4 gap-2">
{availableLanguages.map((language) => (
<div
className={clsx(
'flex items-center flex-col bg-newTableHeader hover:bg-newTableBorder p-[20px] cursor-pointer gap-2',
language === currentLanguage ? 'border border-textColor' : ''
)}
key={language}
onClick={() => handleLanguageChange(language)}
>
<ReactCountryFlag
countryCode={getCountryCodeForFlag(language)}
svg
style={{
width: '1.5em',
height: '1.5em',
}}
title={language}
/>
<Text weight={language === currentLanguage ? 'bold' : 'normal'}>
{getLanguageName(language)}
</Text>
</div>
))}
</div>
</div>
);
};
export const LanguageComponent = () => {
const modal = useModals();
const currentLanguage = i18next.resolvedLanguage || fallbackLng;
const t = useT();
const openModal = () => {
modal.openModal({
title: t('change_language', 'Change Language'),
withCloseButton: true,
children: <ChangeLanguageComponent />,
});
};
return (
<div
onClick={openModal}
className="rounded-full overflow-hidden h-[22px] w-[22px] relative cursor-pointer"
>
<ReactCountryFlag
countryCode={getCountryCodeForFlag(currentLanguage)}
svg
style={{
width: '22px',
height: '22px',
position: 'absolute',
left: '50%',
top: '50%',
transform: 'translate(-50%, -50%)',
objectFit: 'cover',
}}
title={currentLanguage}
/>
</div>
);
};
|