2025-01-31 12:31:38 +01:00
|
|
|
import { useCallback, useEffect, useState } from 'react';
|
2024-09-06 16:30:46 +02:00
|
|
|
import { useLocation, useNavigate } from 'react-router-dom';
|
2024-05-09 18:29:55 +02:00
|
|
|
import { useTranslation } from 'react-i18next';
|
2024-05-10 12:46:52 +02:00
|
|
|
import styles from './settings-modal.module.css';
|
2024-05-15 16:54:55 +02:00
|
|
|
import AccountSettings from './account-settings';
|
|
|
|
|
import CryptoAddressSetting from './crypto-address-setting';
|
2024-05-15 21:20:14 +02:00
|
|
|
import CryptoWalletsSetting from './crypto-wallets-setting';
|
2024-05-16 22:41:36 +02:00
|
|
|
import InterfaceSettings from './interface-settings';
|
2026-02-17 18:57:54 +08:00
|
|
|
import MediaHostingSettings from './media-hosting-settings';
|
2026-02-18 17:29:41 +08:00
|
|
|
import AdvancedSettings from './advanced-settings';
|
2025-02-05 15:20:07 +01:00
|
|
|
import SubscriptionsSetting from './subscriptions-setting';
|
2024-05-10 17:03:33 +02:00
|
|
|
|
2024-05-09 18:29:55 +02:00
|
|
|
const SettingsModal = () => {
|
|
|
|
|
const { t } = useTranslation();
|
2024-09-06 16:30:46 +02:00
|
|
|
const location = useLocation();
|
2024-05-09 18:29:55 +02:00
|
|
|
const navigate = useNavigate();
|
2025-01-23 15:08:40 +01:00
|
|
|
const hash = location.hash.slice(1);
|
2024-05-09 18:29:55 +02:00
|
|
|
|
2025-01-31 12:31:38 +01:00
|
|
|
const closeModal = useCallback(() => {
|
2024-09-06 16:30:46 +02:00
|
|
|
const newPath = location.pathname.replace(/\/settings$/, '');
|
|
|
|
|
navigate(newPath);
|
2025-01-31 12:31:38 +01:00
|
|
|
}, [location.pathname, navigate]);
|
2024-05-09 18:29:55 +02:00
|
|
|
|
2025-01-30 22:05:54 +01:00
|
|
|
useEffect(() => {
|
|
|
|
|
const handleEscape = (e: KeyboardEvent) => {
|
|
|
|
|
if (e.key === 'Escape') {
|
|
|
|
|
closeModal();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
document.addEventListener('keydown', handleEscape);
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
document.removeEventListener('keydown', handleEscape);
|
|
|
|
|
};
|
|
|
|
|
}, [closeModal]);
|
|
|
|
|
|
2024-05-16 22:41:36 +02:00
|
|
|
const [showInterfaceSettings, setShowInterfaceSettings] = useState(false);
|
2026-02-17 18:57:54 +08:00
|
|
|
const [showMediaHostingSettings, setShowMediaHostingSettings] = useState(false);
|
2024-05-10 17:03:33 +02:00
|
|
|
const [showAccountSettings, setShowAccountSettings] = useState(false);
|
2025-02-05 15:20:07 +01:00
|
|
|
const [showSubscriptionsSettings, setShowSubscriptionsSettings] = useState(false);
|
2026-02-18 17:29:41 +08:00
|
|
|
const [showAdvancedSettings, setShowAdvancedSettings] = useState(false);
|
2024-05-16 22:00:22 +02:00
|
|
|
const [expandAll, setExpandAll] = useState(false);
|
|
|
|
|
|
2025-01-23 15:08:40 +01:00
|
|
|
const getExpandedCount = () => {
|
|
|
|
|
return (
|
2026-02-19 18:37:43 +08:00
|
|
|
Number(showInterfaceSettings) + Number(showMediaHostingSettings) + Number(showAccountSettings) + Number(showSubscriptionsSettings) + Number(showAdvancedSettings)
|
2025-01-23 15:08:40 +01:00
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getExpandedCategoryId = (excludeCategoryId?: string) => {
|
|
|
|
|
if (showInterfaceSettings && 'interface-settings' !== excludeCategoryId) return 'interface-settings';
|
2026-02-17 18:57:54 +08:00
|
|
|
if (showMediaHostingSettings && 'media-hosting-settings' !== excludeCategoryId) return 'media-hosting-settings';
|
2025-01-23 15:08:40 +01:00
|
|
|
if (showAccountSettings && 'account-settings' !== excludeCategoryId) return 'account-settings';
|
2025-02-05 15:20:07 +01:00
|
|
|
if (showSubscriptionsSettings && 'subscriptions-settings' !== excludeCategoryId) return 'subscriptions-settings';
|
2026-02-18 17:29:41 +08:00
|
|
|
if (showAdvancedSettings && 'advanced-settings' !== excludeCategoryId) return 'advanced-settings';
|
2025-01-23 15:08:40 +01:00
|
|
|
return null;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleCategoryClick = (categoryId: string, isShowing: boolean, setShowing: (value: boolean) => void) => {
|
|
|
|
|
const newState = !isShowing;
|
|
|
|
|
setShowing(newState);
|
|
|
|
|
|
|
|
|
|
const currentPath = location.pathname;
|
|
|
|
|
const baseSettingsPath = currentPath.split('#')[0];
|
|
|
|
|
|
|
|
|
|
const currentExpandedCount = getExpandedCount();
|
|
|
|
|
|
|
|
|
|
if (newState) {
|
|
|
|
|
if (currentExpandedCount === 0) {
|
|
|
|
|
navigate(`${baseSettingsPath}#${categoryId}`, { replace: true });
|
|
|
|
|
} else {
|
|
|
|
|
navigate(baseSettingsPath, { replace: true });
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (currentExpandedCount === 1) {
|
|
|
|
|
navigate(baseSettingsPath, { replace: true });
|
|
|
|
|
} else if (currentExpandedCount === 2) {
|
|
|
|
|
const remainingCategory = getExpandedCategoryId(categoryId);
|
|
|
|
|
if (remainingCategory) {
|
|
|
|
|
navigate(`${baseSettingsPath}#${remainingCategory}`, { replace: true });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (hash) {
|
2026-02-19 18:37:43 +08:00
|
|
|
const expandAccount = hash === 'account-settings' || hash === 'crypto-address-settings' || hash === 'crypto-wallet-settings';
|
2025-01-23 15:08:40 +01:00
|
|
|
setShowInterfaceSettings(hash === 'interface-settings');
|
2026-02-17 18:57:54 +08:00
|
|
|
setShowMediaHostingSettings(hash === 'media-hosting-settings');
|
2026-02-19 18:37:43 +08:00
|
|
|
setShowAccountSettings(expandAccount);
|
2025-02-05 15:20:07 +01:00
|
|
|
setShowSubscriptionsSettings(hash === 'subscriptions-settings');
|
2026-02-18 17:29:41 +08:00
|
|
|
setShowAdvancedSettings(hash === 'advanced-settings');
|
2025-01-23 15:08:40 +01:00
|
|
|
}
|
|
|
|
|
}, [hash]);
|
|
|
|
|
|
2024-05-16 22:00:22 +02:00
|
|
|
const handleExpandAll = () => {
|
|
|
|
|
const newExpandState = !expandAll;
|
|
|
|
|
setExpandAll(newExpandState);
|
2024-05-16 22:41:36 +02:00
|
|
|
setShowInterfaceSettings(newExpandState);
|
2026-02-17 18:57:54 +08:00
|
|
|
setShowMediaHostingSettings(newExpandState);
|
2024-05-16 22:00:22 +02:00
|
|
|
setShowAccountSettings(newExpandState);
|
2025-02-05 15:20:07 +01:00
|
|
|
setShowSubscriptionsSettings(newExpandState);
|
2026-02-18 17:29:41 +08:00
|
|
|
setShowAdvancedSettings(newExpandState);
|
2025-01-23 15:08:40 +01:00
|
|
|
|
|
|
|
|
const baseSettingsPath = location.pathname.split('#')[0];
|
|
|
|
|
navigate(baseSettingsPath, { replace: true });
|
2024-05-16 22:00:22 +02:00
|
|
|
};
|
2024-05-10 17:03:33 +02:00
|
|
|
|
2024-05-09 18:29:55 +02:00
|
|
|
return (
|
|
|
|
|
<>
|
2024-06-15 16:42:30 +02:00
|
|
|
<div className={styles.overlay} onClick={closeModal} />
|
2024-05-09 18:29:55 +02:00
|
|
|
<div className={styles.settingsModal}>
|
|
|
|
|
<div className={styles.header}>
|
|
|
|
|
<span className={styles.title}>{t('settings')}</span>
|
|
|
|
|
<span className={styles.closeButton} title='close' onClick={closeModal} />
|
|
|
|
|
</div>
|
2024-05-16 22:00:22 +02:00
|
|
|
<div className={styles.expandAllSettings}>
|
2024-05-31 17:09:20 +02:00
|
|
|
[<span onClick={handleExpandAll}>{expandAll ? t('collapse_all_settings') : t('expand_all_settings')}</span>]
|
2024-05-16 22:00:22 +02:00
|
|
|
</div>
|
2025-01-23 15:08:40 +01:00
|
|
|
<div id='interface-settings' className={`${styles.setting} ${styles.category}`}>
|
|
|
|
|
<label onClick={() => handleCategoryClick('interface-settings', showInterfaceSettings, setShowInterfaceSettings)}>
|
2024-05-16 22:41:36 +02:00
|
|
|
<span className={showInterfaceSettings ? styles.hideButton : styles.showButton} />
|
2024-05-31 16:51:22 +02:00
|
|
|
{t('interface')}
|
2024-05-16 22:41:36 +02:00
|
|
|
</label>
|
2024-05-10 12:46:52 +02:00
|
|
|
</div>
|
2024-05-16 22:41:36 +02:00
|
|
|
{showInterfaceSettings && <InterfaceSettings />}
|
2026-02-17 18:57:54 +08:00
|
|
|
<div id='media-hosting-settings' className={`${styles.setting} ${styles.category}`}>
|
|
|
|
|
<label onClick={() => handleCategoryClick('media-hosting-settings', showMediaHostingSettings, setShowMediaHostingSettings)}>
|
|
|
|
|
<span className={showMediaHostingSettings ? styles.hideButton : styles.showButton} />
|
|
|
|
|
{t('media_hosting')}
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
{showMediaHostingSettings && <MediaHostingSettings />}
|
2025-01-23 15:08:40 +01:00
|
|
|
<div id='account-settings' className={`${styles.setting} ${styles.category}`}>
|
|
|
|
|
<label onClick={() => handleCategoryClick('account-settings', showAccountSettings, setShowAccountSettings)}>
|
2024-05-10 17:03:33 +02:00
|
|
|
<span className={showAccountSettings ? styles.hideButton : styles.showButton} />
|
2025-12-31 15:40:16 +01:00
|
|
|
{t('bitsocial_account')}
|
2024-05-10 17:03:33 +02:00
|
|
|
</label>
|
|
|
|
|
</div>
|
2026-02-19 18:37:43 +08:00
|
|
|
{showAccountSettings && (
|
|
|
|
|
<>
|
|
|
|
|
<AccountSettings />
|
|
|
|
|
<div className={styles.subSectionHeader}>{t('crypto_address')}</div>
|
|
|
|
|
<CryptoAddressSetting />
|
|
|
|
|
<div className={styles.subSectionHeader}>{t('crypto_wallets')}</div>
|
|
|
|
|
<CryptoWalletsSetting />
|
|
|
|
|
</>
|
|
|
|
|
)}
|
2025-02-05 15:20:07 +01:00
|
|
|
<div id='subscriptions-settings' className={`${styles.setting} ${styles.category}`}>
|
|
|
|
|
<label onClick={() => handleCategoryClick('subscriptions-settings', showSubscriptionsSettings, setShowSubscriptionsSettings)}>
|
|
|
|
|
<span className={showSubscriptionsSettings ? styles.hideButton : styles.showButton} />
|
2026-02-19 15:25:46 +08:00
|
|
|
{t('board_subscriptions')}
|
2025-02-05 15:20:07 +01:00
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
{showSubscriptionsSettings && <SubscriptionsSetting />}
|
2026-02-18 17:29:41 +08:00
|
|
|
<div id='advanced-settings' className={`${styles.setting} ${styles.category}`}>
|
|
|
|
|
<label onClick={() => handleCategoryClick('advanced-settings', showAdvancedSettings, setShowAdvancedSettings)}>
|
|
|
|
|
<span className={showAdvancedSettings ? styles.hideButton : styles.showButton} />
|
|
|
|
|
{t('advanced_settings')}
|
2024-06-18 11:50:17 +02:00
|
|
|
</label>
|
|
|
|
|
</div>
|
2026-02-18 17:29:41 +08:00
|
|
|
{showAdvancedSettings && <AdvancedSettings />}
|
2024-05-09 18:29:55 +02:00
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2024-05-09 16:04:24 +02:00
|
|
|
export default SettingsModal;
|