import { useCallback, useEffect, useMemo, useState } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import styles from './settings-modal.module.css'; import AccountSettings from './account-settings'; import CryptoAddressSetting from './crypto-address-setting'; import CryptoWalletsSetting from './crypto-wallets-setting'; import InterfaceSettings from './interface-settings'; import MediaHostingSettings from './media-hosting-settings'; import AdvancedSettings from './advanced-settings'; import SubscriptionsSetting from './subscriptions-setting'; const allSectionIds = ['interface-settings', 'media-hosting-settings', 'account-settings', 'subscriptions-settings', 'advanced-settings']; const hashToSection = (hash: string): string | null => { if (hash === 'crypto-address-settings' || hash === 'crypto-wallet-settings') return 'account-settings'; if (allSectionIds.includes(hash)) return hash; return null; }; const SettingsModal = () => { const { t } = useTranslation(); const location = useLocation(); const navigate = useNavigate(); const hash = location.hash.slice(1); const hashSection = hashToSection(hash); const closeModal = useCallback(() => { const newPath = location.pathname.replace(/\/settings$/, ''); navigate(newPath); }, [location.pathname, navigate]); useEffect(() => { const handleEscape = (e: KeyboardEvent) => { if (e.key === 'Escape') { closeModal(); } }; document.addEventListener('keydown', handleEscape); return () => { document.removeEventListener('keydown', handleEscape); }; }, [closeModal]); const [expandedSections, setExpandedSections] = useState>(() => { return hashSection ? new Set([hashSection]) : new Set(); }); const visibleExpandedSections = useMemo(() => { if (!hashSection || expandedSections.has(hashSection)) return expandedSections; const nextSections = new Set(expandedSections); nextSections.add(hashSection); return nextSections; }, [expandedSections, hashSection]); const showInterfaceSettings = visibleExpandedSections.has('interface-settings'); const showMediaHostingSettings = visibleExpandedSections.has('media-hosting-settings'); const showAccountSettings = visibleExpandedSections.has('account-settings'); const showSubscriptionsSettings = visibleExpandedSections.has('subscriptions-settings'); const showAdvancedSettings = visibleExpandedSections.has('advanced-settings'); const allExpanded = useMemo(() => allSectionIds.every((id) => visibleExpandedSections.has(id)), [visibleExpandedSections]); const basePath = location.pathname; const handleCategoryClick = (categoryId: string) => { const isOpening = !visibleExpandedSections.has(categoryId); const next = new Set(visibleExpandedSections); if (isOpening) { next.add(categoryId); } else { next.delete(categoryId); } setExpandedSections(next); if (isOpening) { navigate(`${basePath}#${categoryId}`, { replace: true }); } else if (next.size === 1) { const remaining = next.values().next().value; navigate(`${basePath}#${remaining}`, { replace: true }); } else { navigate(basePath, { replace: true }); } }; const handleExpandAll = () => { if (allExpanded) { setExpandedSections(new Set()); navigate(basePath, { replace: true }); } else { setExpandedSections(new Set(allSectionIds)); navigate(basePath, { replace: true }); } }; const handleKeyDown = (handler: () => void) => (e: React.KeyboardEvent) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); handler(); } }; return ( <>
{t('settings')}
[ {allExpanded ? t('collapse_all_settings') : t('expand_all_settings')} ]
{showInterfaceSettings && }
{showMediaHostingSettings && }
{showAccountSettings && ( <>
{t('crypto_address')}
{t('crypto_wallets')}
)}
{showSubscriptionsSettings && }
{showAdvancedSettings && }
); }; export default SettingsModal;