diff --git a/src/features/misc/sections/Language.jsx b/src/features/misc/sections/Language.jsx
index 04104007..23ac212c 100644
--- a/src/features/misc/sections/Language.jsx
+++ b/src/features/misc/sections/Language.jsx
@@ -2,7 +2,8 @@ import { useState, useEffect, useRef, useMemo } from 'react';
import { useT, useTranslation } from 'contexts/TranslationContext';
import variables from 'config/variables';
-import { MdOutlineOpenInNew } from 'react-icons/md';
+import { MdOutlineOpenInNew, MdSearch } from 'react-icons/md';
+import { TextField, InputAdornment } from '@mui/material';
import { Radio } from 'components/Form/Settings';
@@ -10,12 +11,14 @@ import languages from '@/i18n/languages.json';
const LanguageOptions = () => {
const t = useT();
- const { language: currentLanguage } = useTranslation();
+ const { language: currentLanguage, changeLanguage } = useTranslation();
const loadingText = t('modals.main.loading');
const offlineText = t('modals.main.marketplace.offline.description');
const languageTitle = t('modals.main.settings.sections.language.title');
const quoteTitle = t('modals.main.settings.sections.language.quote');
+ const [searchQuery, setSearchQuery] = useState('');
+
// Create language options with both translated and native names
const languageOptions = useMemo(() => {
// Convert currentLanguage to ISO format (e.g., "de_DE" -> "de-DE")
@@ -24,7 +27,7 @@ const LanguageOptions = () => {
// Use Intl.DisplayNames to get language names in the current language
const displayNames = new Intl.DisplayNames([currentLanguageISO], { type: 'language' });
- return languages.map((lang) => {
+ const mappedLanguages = languages.map((lang) => {
const nativeName = lang.name;
// Convert language code to ISO format for Intl.DisplayNames
@@ -56,10 +59,33 @@ const LanguageOptions = () => {
return {
name: displayName,
value: lang.value,
+ nativeName,
+ searchText: `${nativeName} ${translatedName || ''}`.toLowerCase(),
};
});
+
+ // Sort alphabetically by native name
+ return mappedLanguages.sort((a, b) => a.nativeName.localeCompare(b.nativeName));
}, [currentLanguage]);
+ // Filter languages based on search query
+ const filteredLanguages = useMemo(() => {
+ if (!searchQuery.trim()) return languageOptions;
+ const query = searchQuery.toLowerCase();
+ return languageOptions.filter(lang => lang.searchText.includes(query));
+ }, [languageOptions, searchQuery]);
+
+ // Detect system language
+ const systemLanguage = useMemo(() => {
+ const browserLang = navigator.language.replace('-', '_');
+ // Check exact match first, then base language
+ return languages.find(l => l.value === browserLang) ||
+ languages.find(l => l.value.startsWith(browserLang.split('_')[0]));
+ }, []);
+
+ // Find current language option for display
+ const currentLangOption = languageOptions.find(l => l.value === currentLanguage);
+
const [quoteLanguages, setQuoteLanguages] = useState([
{
name: loadingText,
@@ -136,8 +162,54 @@ const LanguageOptions = () => {
+
+
setSearchQuery(e.target.value)}
+ variant="outlined"
+ size="small"
+ InputProps={{
+ startAdornment: (
+
+
+
+ ),
+ }}
+ sx={{
+ width: '250px',
+ '& .MuiOutlinedInput-root': {
+ borderRadius: '24px',
+ backgroundColor: 'rgba(255, 255, 255, 0.08)',
+ '& fieldset': {
+ border: 'none',
+ },
+ '&:hover fieldset': {
+ border: 'none',
+ },
+ '&.Mui-focused fieldset': {
+ border: 'none',
+ },
+ },
+ }}
+ />
+ {currentLangOption && (
+
+ {t('modals.main.settings.sections.language.current')}: {currentLangOption.nativeName}
+
+ )}
+
+ {systemLanguage && systemLanguage.value !== currentLanguage && (
+
+ )}
-
+
{quoteTitle}
diff --git a/src/features/welcome/components/Sections/ChooseLanguage.jsx b/src/features/welcome/components/Sections/ChooseLanguage.jsx
index 971d4adc..d53de184 100644
--- a/src/features/welcome/components/Sections/ChooseLanguage.jsx
+++ b/src/features/welcome/components/Sections/ChooseLanguage.jsx
@@ -1,5 +1,6 @@
-import { useMemo } from 'react';
-import { MdOutlineOpenInNew } from 'react-icons/md';
+import { useState, useMemo } from 'react';
+import { MdOutlineOpenInNew, MdSearch } from 'react-icons/md';
+import { TextField, InputAdornment } from '@mui/material';
import languages from '@/i18n/languages.json';
import { useT, useTranslation } from 'contexts/TranslationContext';
import variables from 'config/variables';
@@ -9,15 +10,17 @@ import { Header, Content } from '../Layout';
function ChooseLanguage() {
const t = useT();
- const { language: currentLanguage } = useTranslation();
+ const { language: currentLanguage, changeLanguage } = useTranslation();
const title = t('modals.welcome.sections.language.title');
const description = t('modals.welcome.sections.language.description');
+ const [searchQuery, setSearchQuery] = useState('');
+
const languageOptions = useMemo(() => {
const currentLanguageISO = currentLanguage.replace('_', '-');
const displayNames = new Intl.DisplayNames([currentLanguageISO], { type: 'language' });
- return languages.map((lang) => {
+ const mappedLanguages = languages.map((lang) => {
const nativeName = lang.name;
const isoCode = lang.value.replace('_', '-');
@@ -44,10 +47,29 @@ function ChooseLanguage() {
return {
name: displayName,
value: lang.value,
+ nativeName,
+ searchText: `${nativeName} ${translatedName || ''}`.toLowerCase(),
};
});
+
+ // Sort alphabetically by native name
+ return mappedLanguages.sort((a, b) => a.nativeName.localeCompare(b.nativeName));
}, [currentLanguage]);
+ // Filter languages based on search query
+ const filteredLanguages = useMemo(() => {
+ if (!searchQuery.trim()) return languageOptions;
+ const query = searchQuery.toLowerCase();
+ return languageOptions.filter(lang => lang.searchText.includes(query));
+ }, [languageOptions, searchQuery]);
+
+ // Detect system language
+ const systemLanguage = useMemo(() => {
+ const browserLang = navigator.language.replace('-', '_');
+ return languages.find(l => l.value === browserLang) ||
+ languages.find(l => l.value.startsWith(browserLang.split('_')[0]));
+ }, []);
+
return (
}
/>
+ {systemLanguage && systemLanguage.value !== currentLanguage && (
+
+ )}
+ setSearchQuery(e.target.value)}
+ variant="outlined"
+ size="small"
+ fullWidth
+ InputProps={{
+ startAdornment: (
+
+
+
+ ),
+ }}
+ sx={{
+ marginBottom: 2,
+ '& .MuiOutlinedInput-root': {
+ borderRadius: '24px',
+ backgroundColor: 'rgba(255, 255, 255, 0.08)',
+ '& fieldset': {
+ border: 'none',
+ },
+ '&:hover fieldset': {
+ border: 'none',
+ },
+ '&.Mui-focused fieldset': {
+ border: 'none',
+ },
+ },
+ }}
+ />
-
+
);
diff --git a/src/i18n/locales/achievements/ar.json b/src/i18n/locales/achievements/ar.json
index 6859159a..0ec5e920 100644
--- a/src/i18n/locales/achievements/ar.json
+++ b/src/i18n/locales/achievements/ar.json
@@ -7,7 +7,7 @@
"name": "MU3T4B",
"description": "Opened 1337 tabs"
},
- "10tabs": {
+ "tentabs": {
"name": "10/10 IGN",
"description": "Opened 10 tabs"
},
diff --git a/src/i18n/locales/ar.json b/src/i18n/locales/ar.json
index 979fbd2c..04345b32 100644
--- a/src/i18n/locales/ar.json
+++ b/src/i18n/locales/ar.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "اللغة",
- "quote": "لغة الاقتباس"
+ "quote": "لغة الاقتباس",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "سجل التغييرات",
diff --git a/src/i18n/locales/arz.json b/src/i18n/locales/arz.json
index 0f0984e7..7e464d46 100644
--- a/src/i18n/locales/arz.json
+++ b/src/i18n/locales/arz.json
@@ -478,7 +478,10 @@
},
"language": {
"title": "Language",
- "quote": "Quote language"
+ "quote": "Quote language",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Change Log",
diff --git a/src/i18n/locales/az.json b/src/i18n/locales/az.json
index cd7e4395..9cafbab9 100644
--- a/src/i18n/locales/az.json
+++ b/src/i18n/locales/az.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "Dil",
- "quote": "Sitat dili"
+ "quote": "Sitat dili",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Dəyişikliklər Siyahısı",
diff --git a/src/i18n/locales/azb.json b/src/i18n/locales/azb.json
index 5119798c..802c85c7 100644
--- a/src/i18n/locales/azb.json
+++ b/src/i18n/locales/azb.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "Dil",
- "quote": "Sitat dili"
+ "quote": "Sitat dili",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Dəyişikliklər Siyahısı",
diff --git a/src/i18n/locales/bn.json b/src/i18n/locales/bn.json
index d99827cc..02a396d2 100644
--- a/src/i18n/locales/bn.json
+++ b/src/i18n/locales/bn.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "Language",
- "quote": "Quote language"
+ "quote": "Quote language",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Change Log",
diff --git a/src/i18n/locales/de_DE.json b/src/i18n/locales/de_DE.json
index fc88a9b2..23fd79e7 100644
--- a/src/i18n/locales/de_DE.json
+++ b/src/i18n/locales/de_DE.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "Sprache",
- "quote": "Zitat-Sprache"
+ "quote": "Zitat-Sprache",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Änderungen",
diff --git a/src/i18n/locales/el.json b/src/i18n/locales/el.json
index 9871d072..31f5b6a1 100644
--- a/src/i18n/locales/el.json
+++ b/src/i18n/locales/el.json
@@ -478,7 +478,10 @@
},
"language": {
"title": "Language",
- "quote": "Quote language"
+ "quote": "Quote language",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Change Log",
diff --git a/src/i18n/locales/en_GB.json b/src/i18n/locales/en_GB.json
index 351afab1..00b6b69c 100644
--- a/src/i18n/locales/en_GB.json
+++ b/src/i18n/locales/en_GB.json
@@ -478,7 +478,10 @@
},
"language": {
"title": "Language",
- "quote": "Quote language"
+ "quote": "Quote language",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Change Log",
diff --git a/src/i18n/locales/en_US.json b/src/i18n/locales/en_US.json
index ae799dda..eb6822f5 100644
--- a/src/i18n/locales/en_US.json
+++ b/src/i18n/locales/en_US.json
@@ -478,7 +478,10 @@
},
"language": {
"title": "Language",
- "quote": "Quote language"
+ "quote": "Quote language",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Change Log",
diff --git a/src/i18n/locales/es.json b/src/i18n/locales/es.json
index ec31c28b..c49a9d6c 100644
--- a/src/i18n/locales/es.json
+++ b/src/i18n/locales/es.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "Idioma",
- "quote": "Idioma de las citas"
+ "quote": "Idioma de las citas",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Registro de cambios",
diff --git a/src/i18n/locales/es_419.json b/src/i18n/locales/es_419.json
index f16d6eb5..ef2b7152 100644
--- a/src/i18n/locales/es_419.json
+++ b/src/i18n/locales/es_419.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "Idioma",
- "quote": "Idioma de las citaciones"
+ "quote": "Idioma de las citaciones",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Registro de cambios",
diff --git a/src/i18n/locales/et.json b/src/i18n/locales/et.json
index ddce32e0..1d69effe 100644
--- a/src/i18n/locales/et.json
+++ b/src/i18n/locales/et.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "Keel",
- "quote": "Tsitaadi keel"
+ "quote": "Tsitaadi keel",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Muudatuste logi",
diff --git a/src/i18n/locales/fa.json b/src/i18n/locales/fa.json
index 59796e42..1f19b62e 100644
--- a/src/i18n/locales/fa.json
+++ b/src/i18n/locales/fa.json
@@ -478,7 +478,10 @@
},
"language": {
"title": "Language",
- "quote": "Quote language"
+ "quote": "Quote language",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Change Log",
diff --git a/src/i18n/locales/fr.json b/src/i18n/locales/fr.json
index f46b613a..f19ac842 100644
--- a/src/i18n/locales/fr.json
+++ b/src/i18n/locales/fr.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "Langue",
- "quote": "Langue des citations"
+ "quote": "Langue des citations",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Journal des modifications",
diff --git a/src/i18n/locales/hu.json b/src/i18n/locales/hu.json
index 351afab1..00b6b69c 100644
--- a/src/i18n/locales/hu.json
+++ b/src/i18n/locales/hu.json
@@ -478,7 +478,10 @@
},
"language": {
"title": "Language",
- "quote": "Quote language"
+ "quote": "Quote language",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Change Log",
diff --git a/src/i18n/locales/id_ID.json b/src/i18n/locales/id_ID.json
index 274fea02..77cc1284 100644
--- a/src/i18n/locales/id_ID.json
+++ b/src/i18n/locales/id_ID.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "Bahasa",
- "quote": "Bahasa untuk kutipan"
+ "quote": "Bahasa untuk kutipan",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Changelog",
diff --git a/src/i18n/locales/ja.json b/src/i18n/locales/ja.json
index ad7c7534..862f1f4a 100644
--- a/src/i18n/locales/ja.json
+++ b/src/i18n/locales/ja.json
@@ -478,7 +478,10 @@
},
"language": {
"title": "Language",
- "quote": "Quote language"
+ "quote": "Quote language",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Change Log",
diff --git a/src/i18n/locales/lt.json b/src/i18n/locales/lt.json
index 056af7df..3caa6207 100644
--- a/src/i18n/locales/lt.json
+++ b/src/i18n/locales/lt.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "Kalba",
- "quote": "Citatų kalba"
+ "quote": "Citatų kalba",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Pakeitimų žurnalas",
diff --git a/src/i18n/locales/lv.json b/src/i18n/locales/lv.json
index ad21d1c2..c7635b44 100644
--- a/src/i18n/locales/lv.json
+++ b/src/i18n/locales/lv.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "Valoda",
- "quote": "Citātu valoda"
+ "quote": "Citātu valoda",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Izmaiņu žurnāls",
diff --git a/src/i18n/locales/nl.json b/src/i18n/locales/nl.json
index 8cebab42..8734da98 100644
--- a/src/i18n/locales/nl.json
+++ b/src/i18n/locales/nl.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "Taal",
- "quote": "Quote language"
+ "quote": "Quote language",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Change Log",
diff --git a/src/i18n/locales/no.json b/src/i18n/locales/no.json
index ed0d3bef..30aa1e12 100644
--- a/src/i18n/locales/no.json
+++ b/src/i18n/locales/no.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "Språk",
- "quote": "Quote language"
+ "quote": "Quote language",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Change Log",
diff --git a/src/i18n/locales/peo.json b/src/i18n/locales/peo.json
index 1fb2662a..c6e6b5ee 100644
--- a/src/i18n/locales/peo.json
+++ b/src/i18n/locales/peo.json
@@ -478,7 +478,10 @@
},
"language": {
"title": "Language",
- "quote": "Quote language"
+ "quote": "Quote language",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Change Log",
diff --git a/src/i18n/locales/pt.json b/src/i18n/locales/pt.json
index daa08b34..5cc29cdb 100644
--- a/src/i18n/locales/pt.json
+++ b/src/i18n/locales/pt.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "Idioma",
- "quote": "Idioma das citações"
+ "quote": "Idioma das citações",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Registo de alterações",
diff --git a/src/i18n/locales/pt_BR.json b/src/i18n/locales/pt_BR.json
index b1167b4d..bc63ea57 100644
--- a/src/i18n/locales/pt_BR.json
+++ b/src/i18n/locales/pt_BR.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "Idioma",
- "quote": "Idioma das citações"
+ "quote": "Idioma das citações",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Registo de alterações",
diff --git a/src/i18n/locales/ru.json b/src/i18n/locales/ru.json
index 3d6effea..0f54e3bb 100644
--- a/src/i18n/locales/ru.json
+++ b/src/i18n/locales/ru.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "Язык",
- "quote": "Язык цитат"
+ "quote": "Язык цитат",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Журнал изменений",
diff --git a/src/i18n/locales/sl.json b/src/i18n/locales/sl.json
index 0c509355..82ab92f7 100644
--- a/src/i18n/locales/sl.json
+++ b/src/i18n/locales/sl.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "Jezik",
- "quote": "Jezik citata"
+ "quote": "Jezik citata",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Dnevnik sprememb",
diff --git a/src/i18n/locales/sv.json b/src/i18n/locales/sv.json
index 6d5f6835..b5f05fc4 100644
--- a/src/i18n/locales/sv.json
+++ b/src/i18n/locales/sv.json
@@ -478,7 +478,10 @@
},
"language": {
"title": "Language",
- "quote": "Quote language"
+ "quote": "Quote language",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Change Log",
diff --git a/src/i18n/locales/ta.json b/src/i18n/locales/ta.json
index bf86aa93..c4ccfebc 100644
--- a/src/i18n/locales/ta.json
+++ b/src/i18n/locales/ta.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "மொழி",
- "quote": "மேற்கோள் மொழி"
+ "quote": "மேற்கோள் மொழி",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "பதிவை மாற்றவும்",
diff --git a/src/i18n/locales/tr_TR.json b/src/i18n/locales/tr_TR.json
index 5b82d2a4..401829f0 100644
--- a/src/i18n/locales/tr_TR.json
+++ b/src/i18n/locales/tr_TR.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "Dil",
- "quote": "Alıntı dili"
+ "quote": "Alıntı dili",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Değişiklik Günlüğü",
diff --git a/src/i18n/locales/uk.json b/src/i18n/locales/uk.json
index ee961986..a25f5d76 100644
--- a/src/i18n/locales/uk.json
+++ b/src/i18n/locales/uk.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "Мова",
- "quote": "Мова цитат"
+ "quote": "Мова цитат",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Журнал змін",
diff --git a/src/i18n/locales/vi.json b/src/i18n/locales/vi.json
index c53aa096..adc4f49e 100644
--- a/src/i18n/locales/vi.json
+++ b/src/i18n/locales/vi.json
@@ -478,7 +478,10 @@
},
"language": {
"title": "Language",
- "quote": "Quote language"
+ "quote": "Quote language",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Change Log",
diff --git a/src/i18n/locales/zh_CN.json b/src/i18n/locales/zh_CN.json
index 82ebe8d7..1e5d9c6e 100644
--- a/src/i18n/locales/zh_CN.json
+++ b/src/i18n/locales/zh_CN.json
@@ -476,7 +476,10 @@
},
"language": {
"title": "语言",
- "quote": "名言语言"
+ "quote": "名言语言",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "更新日志",
diff --git a/src/i18n/locales/zh_Hant.json b/src/i18n/locales/zh_Hant.json
index 651de479..61f7bcfe 100644
--- a/src/i18n/locales/zh_Hant.json
+++ b/src/i18n/locales/zh_Hant.json
@@ -478,7 +478,10 @@
},
"language": {
"title": "Language",
- "quote": "Quote language"
+ "quote": "Quote language",
+ "search": "Search languages...",
+ "current": "Current",
+ "use_system": "Use system language"
},
"changelog": {
"title": "Change Log",