mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
Update settings-modal.tsx
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
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';
|
||||
@@ -10,6 +10,14 @@ 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();
|
||||
@@ -34,58 +42,57 @@ const SettingsModal = () => {
|
||||
};
|
||||
}, [closeModal]);
|
||||
|
||||
const [expandAll, setExpandAll] = useState(false);
|
||||
const [expandedSections, setExpandedSections] = useState<Set<string>>(() => {
|
||||
const section = hashToSection(hash);
|
||||
return section ? new Set([section]) : new Set();
|
||||
});
|
||||
|
||||
const expandAccount = hash === 'account-settings' || hash === 'crypto-address-settings' || hash === 'crypto-wallet-settings';
|
||||
const showInterfaceSettings = expandAll || hash === 'interface-settings';
|
||||
const showMediaHostingSettings = expandAll || hash === 'media-hosting-settings';
|
||||
const showAccountSettings = expandAll || expandAccount;
|
||||
const showSubscriptionsSettings = expandAll || hash === 'subscriptions-settings';
|
||||
const showAdvancedSettings = expandAll || hash === 'advanced-settings';
|
||||
const showInterfaceSettings = expandedSections.has('interface-settings');
|
||||
const showMediaHostingSettings = expandedSections.has('media-hosting-settings');
|
||||
const showAccountSettings = expandedSections.has('account-settings');
|
||||
const showSubscriptionsSettings = expandedSections.has('subscriptions-settings');
|
||||
const showAdvancedSettings = expandedSections.has('advanced-settings');
|
||||
|
||||
const getExpandedCount = () => {
|
||||
return (
|
||||
Number(showInterfaceSettings) + Number(showMediaHostingSettings) + Number(showAccountSettings) + Number(showSubscriptionsSettings) + Number(showAdvancedSettings)
|
||||
);
|
||||
};
|
||||
const allExpanded = useMemo(() => allSectionIds.every((id) => expandedSections.has(id)), [expandedSections]);
|
||||
|
||||
const getExpandedCategoryId = (excludeCategoryId?: string) => {
|
||||
if (showInterfaceSettings && 'interface-settings' !== excludeCategoryId) return 'interface-settings';
|
||||
if (showMediaHostingSettings && 'media-hosting-settings' !== excludeCategoryId) return 'media-hosting-settings';
|
||||
if (showAccountSettings && 'account-settings' !== excludeCategoryId) return 'account-settings';
|
||||
if (showSubscriptionsSettings && 'subscriptions-settings' !== excludeCategoryId) return 'subscriptions-settings';
|
||||
if (showAdvancedSettings && 'advanced-settings' !== excludeCategoryId) return 'advanced-settings';
|
||||
return null;
|
||||
};
|
||||
const basePath = location.pathname;
|
||||
|
||||
const handleCategoryClick = (categoryId: string, isShowing: boolean) => {
|
||||
const newState = !isShowing;
|
||||
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(() => {
|
||||
const section = hashToSection(hash);
|
||||
if (section && !expandedSections.has(section)) {
|
||||
setExpandedSections((prev) => new Set(prev).add(section));
|
||||
}
|
||||
}, [hash]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
const handleCategoryClick = (categoryId: string) => {
|
||||
setExpandedSections((prev) => {
|
||||
const next = new Set(prev);
|
||||
const isOpening = !next.has(categoryId);
|
||||
if (isOpening) {
|
||||
next.add(categoryId);
|
||||
} else {
|
||||
next.delete(categoryId);
|
||||
}
|
||||
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 });
|
||||
}
|
||||
return next;
|
||||
});
|
||||
};
|
||||
|
||||
const handleExpandAll = () => {
|
||||
setExpandAll((prev) => !prev);
|
||||
const baseSettingsPath = location.pathname.split('#')[0];
|
||||
navigate(baseSettingsPath, { replace: true });
|
||||
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) => {
|
||||
@@ -106,26 +113,26 @@ const SettingsModal = () => {
|
||||
<div className={styles.expandAllSettings}>
|
||||
[
|
||||
<span role='button' tabIndex={0} onClick={handleExpandAll} onKeyDown={handleKeyDown(handleExpandAll)}>
|
||||
{expandAll ? t('collapse_all_settings') : t('expand_all_settings')}
|
||||
{allExpanded ? t('collapse_all_settings') : t('expand_all_settings')}
|
||||
</span>
|
||||
]
|
||||
</div>
|
||||
<div id='interface-settings' className={`${styles.setting} ${styles.category}`}>
|
||||
<label onClick={() => handleCategoryClick('interface-settings', showInterfaceSettings)}>
|
||||
<label onClick={() => handleCategoryClick('interface-settings')}>
|
||||
<span className={showInterfaceSettings ? styles.hideButton : styles.showButton} />
|
||||
{t('interface')}
|
||||
</label>
|
||||
</div>
|
||||
{showInterfaceSettings && <InterfaceSettings />}
|
||||
<div id='media-hosting-settings' className={`${styles.setting} ${styles.category}`}>
|
||||
<label onClick={() => handleCategoryClick('media-hosting-settings', showMediaHostingSettings)}>
|
||||
<label onClick={() => handleCategoryClick('media-hosting-settings')}>
|
||||
<span className={showMediaHostingSettings ? styles.hideButton : styles.showButton} />
|
||||
{t('media_hosting')}
|
||||
</label>
|
||||
</div>
|
||||
{showMediaHostingSettings && <MediaHostingSettings />}
|
||||
<div id='account-settings' className={`${styles.setting} ${styles.category}`}>
|
||||
<label onClick={() => handleCategoryClick('account-settings', showAccountSettings)}>
|
||||
<label onClick={() => handleCategoryClick('account-settings')}>
|
||||
<span className={showAccountSettings ? styles.hideButton : styles.showButton} />
|
||||
{t('bitsocial_account')}
|
||||
</label>
|
||||
@@ -140,14 +147,14 @@ const SettingsModal = () => {
|
||||
</>
|
||||
)}
|
||||
<div id='subscriptions-settings' className={`${styles.setting} ${styles.category}`}>
|
||||
<label onClick={() => handleCategoryClick('subscriptions-settings', showSubscriptionsSettings)}>
|
||||
<label onClick={() => handleCategoryClick('subscriptions-settings')}>
|
||||
<span className={showSubscriptionsSettings ? styles.hideButton : styles.showButton} />
|
||||
{t('board_subscriptions')}
|
||||
</label>
|
||||
</div>
|
||||
{showSubscriptionsSettings && <SubscriptionsSetting />}
|
||||
<div id='advanced-settings' className={`${styles.setting} ${styles.category}`}>
|
||||
<label onClick={() => handleCategoryClick('advanced-settings', showAdvancedSettings)}>
|
||||
<label onClick={() => handleCategoryClick('advanced-settings')}>
|
||||
<span className={showAdvancedSettings ? styles.hideButton : styles.showButton} />
|
||||
{t('advanced_settings')}
|
||||
</label>
|
||||
|
||||
Reference in New Issue
Block a user