import React, { useState, useRef, useEffect, useMemo } from "react"; import { useTranslation } from "react-i18next"; import { SettingContainer } from "../ui/SettingContainer"; import { ResetButton } from "../ui/ResetButton"; import { useSettings } from "../../hooks/useSettings"; import { LANGUAGES } from "../../lib/constants/languages"; interface LanguageSelectorProps { descriptionMode?: "inline" | "tooltip"; grouped?: boolean; } export const LanguageSelector: React.FC = ({ descriptionMode = "tooltip", grouped = false, }) => { const { t } = useTranslation(); const { getSetting, updateSetting, resetSetting, isUpdating } = useSettings(); const [isOpen, setIsOpen] = useState(false); const [searchQuery, setSearchQuery] = useState(""); const dropdownRef = useRef(null); const searchInputRef = useRef(null); const selectedLanguage = getSetting("selected_language") || "auto"; useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if ( dropdownRef.current && !dropdownRef.current.contains(event.target as Node) ) { setIsOpen(false); setSearchQuery(""); } }; document.addEventListener("mousedown", handleClickOutside); return () => { document.removeEventListener("mousedown", handleClickOutside); }; }, []); useEffect(() => { if (isOpen && searchInputRef.current) { searchInputRef.current.focus(); } }, [isOpen]); const filteredLanguages = useMemo( () => LANGUAGES.filter((language) => language.label.toLowerCase().includes(searchQuery.toLowerCase()), ), [searchQuery], ); const selectedLanguageName = LANGUAGES.find((lang) => lang.value === selectedLanguage)?.label || t("settings.general.language.auto"); const handleLanguageSelect = async (languageCode: string) => { await updateSetting("selected_language", languageCode); setIsOpen(false); setSearchQuery(""); }; const handleReset = async () => { await resetSetting("selected_language"); }; const handleToggle = () => { if (isUpdating("selected_language")) return; setIsOpen(!isOpen); }; const handleSearchChange = (event: React.ChangeEvent) => { setSearchQuery(event.target.value); }; const handleKeyDown = (event: React.KeyboardEvent) => { if (event.key === "Enter" && filteredLanguages.length > 0) { // Select first filtered language on Enter handleLanguageSelect(filteredLanguages[0].value); } else if (event.key === "Escape") { setIsOpen(false); setSearchQuery(""); } }; return (
{isOpen && !isUpdating("selected_language") && (
{/* Search input */}
{filteredLanguages.length === 0 ? (
{t("settings.general.language.noResults")}
) : ( filteredLanguages.map((language) => ( )) )}
)}
{isUpdating("selected_language") && (
)}
); };