refactor(header): each element should be a component not a variable

This commit is contained in:
plebeius.eth
2023-12-01 21:06:16 +01:00
parent 1cf75f8320
commit ba0200ab85
2 changed files with 136 additions and 91 deletions

View File

@@ -2,20 +2,138 @@ import { useEffect, useState } from 'react';
import { Link, useLocation, useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { useSubplebbit } from '@plebbit/plebbit-react-hooks';
import { isAboutView, isHomeView, isPostView, isSettingsView, isSubplebbitView, isSubmitView, isSubplebbitSubmitView } from '../../lib/utils/view-utils';
import { getAboutLink, isAboutView, isHomeView, isPostView, isSettingsView, isSubplebbitView, isSubmitView, isSubplebbitSubmitView } from '../../lib/utils/view-utils';
import useTheme from '../../hooks/use-theme';
import styles from './header.module.css';
import SubscribeButton from '../subscribe-button';
const sortTypes = ['hot', 'new', 'active', 'controversialAll', 'topAll'];
const AboutButton = () => {
const { t } = useTranslation();
const params = useParams();
const location = useLocation();
const aboutLink = getAboutLink(location.pathname, params);
const isHome = isHomeView(location.pathname);
const isAbout = isAboutView(location.pathname);
return (
<li className={styles.about}>
<Link
to={aboutLink}
className={`${isAbout ? styles.selected : styles.choice}`}
onClick={(event) => {
isHome && event.preventDefault();
}}
>
{t('header_about')}
</Link>
</li>
)
}
const CommentsButton = () => {
const { t } = useTranslation();
const params = useParams();
const location = useLocation();
const isPost = isPostView(location.pathname, params);
const isAbout = isAboutView(location.pathname);
return (
<li>
<Link to={`/p/${params.subplebbitAddress}/c/${params.commentCid}`} className={isPost && !isAbout ? styles.selected : styles.choice}>
{t('header_comments')}
</Link>
</li>
);
}
const SortItems = () => {
const { t } = useTranslation();
const params = useParams();
const location = useLocation();
const isSubplebbit = isSubplebbitView(location.pathname, params);
const sortLabels = [t('header_hot'), t('header_new'), t('header_active'), t('header_controversial'), t('header_top')];
const [selectedSortType, setSelectedSortType] = useState(params.sortType || '/hot');
const handleSelect = (choice: string) => {
setSelectedSortType(choice);
};
useEffect(() => {
if (location.pathname.endsWith('/about')) {
setSelectedSortType('');
} else if (params.sortType) {
setSelectedSortType(params.sortType);
} else {
setSelectedSortType('hot');
}
}, [params.sortType, location.pathname]);
return (
sortTypes.map((choice, index) => (
<li key={choice}>
<Link
to={isSubplebbit ? `/p/${params.subplebbitAddress}/${choice}` : choice}
className={selectedSortType === choice ? styles.selected : styles.choice}
onClick={() => handleSelect(choice)}
>
{sortLabels[index]}
</Link>
</li>
))
);
}
const HeaderTabs = () => {
const params = useParams();
const location = useLocation();
const isHome = isHomeView(location.pathname);
const isPost = isPostView(location.pathname, params);
const isSubplebbit = isSubplebbitView(location.pathname, params);
const isSubplebbitSubmit = isSubplebbitSubmitView(location.pathname, params);
if (isPost) {
return <CommentsButton />;
} else if (isHome || (isSubplebbit && !isSubplebbitSubmit)) {
return <SortItems />;
}
return null;
};
const HeaderTitle = ({title, shortAddress}: {title: string, shortAddress: string}) => {
const { t } = useTranslation();
const params = useParams();
const location = useLocation();
const isPost = isPostView(location.pathname, params);
const isSubplebbit = isSubplebbitView(location.pathname, params);
const isSubmit = isSubmitView(location.pathname);
const isSubplebbitSubmit = isSubplebbitSubmitView(location.pathname, params);
const isSettings = isSettingsView(location.pathname);
const subplebbitTitle = <Link to={`/p/${params.subplebbitAddress}`}>{title || shortAddress}</Link>;
const submitTitle = <span className={styles.submitTitle}>{t('submit')}</span>;
if (isSubplebbitSubmit) {
return (
<>
{subplebbitTitle}: {submitTitle}
</>
);
} else if (isPost || isSubplebbit) {
return subplebbitTitle;
} else if (isSubmit) {
return submitTitle;
} else if (isSettings) {
return t('preferences');
}
return null;
}
const Header = () => {
const [theme] = useTheme();
const { t } = useTranslation();
const location = useLocation();
const params = useParams();
const [selectedSortType, setSelectedSortType] = useState(params.sortType || '/hot');
const sortLabels = [t('header_hot'), t('header_new'), t('header_active'), t('header_controversial'), t('header_top')];
const subplebbit = useSubplebbit({ subplebbitAddress: params.subplebbitAddress });
const { suggested, title, shortAddress } = subplebbit || {};
@@ -32,90 +150,6 @@ const Header = () => {
const logoSrc = isSubplebbit ? suggested?.avatarUrl : '/assets/logo/seedit.png';
const logoIsAvatar = isSubplebbit && suggested?.avatarUrl;
const handleSelect = (choice: string) => {
setSelectedSortType(choice);
};
useEffect(() => {
if (location.pathname.endsWith('/about')) {
setSelectedSortType('');
} else if (params.sortType) {
setSelectedSortType(params.sortType);
} else {
setSelectedSortType('hot');
}
}, [params.sortType, location.pathname]);
const sortItems = sortTypes.map((choice, index) => (
<li key={choice}>
<Link
to={isSubplebbit ? `/p/${params.subplebbitAddress}/${choice}` : choice}
className={selectedSortType === choice ? styles.selected : styles.choice}
onClick={() => handleSelect(choice)}
>
{sortLabels[index]}
</Link>
</li>
));
const commentsButton = (
<li>
<Link to={`/p/${params.subplebbitAddress}/c/${params.commentCid}`} className={isPost && !isAbout ? styles.selected : styles.choice}>
{t('header_comments')}
</Link>
</li>
);
let headerTabs;
if (isPost) {
headerTabs = commentsButton;
} else if (isHome || (isSubplebbit && !isSubplebbitSubmit)) {
headerTabs = sortItems;
}
const subplebbitTitle = <Link to={`/p/${params.subplebbitAddress}`}>{title || shortAddress}</Link>;
let headerTitle;
const submitTitle = <span className={styles.submitTitle}>{t('submit')}</span>;
if (isSubplebbitSubmit) {
headerTitle = (
<>
{subplebbitTitle}: {submitTitle}
</>
);
} else if (isPost || isSubplebbit) {
headerTitle = subplebbitTitle;
} else if (isSubmit) {
headerTitle = submitTitle;
} else if (isSettings) {
headerTitle = t('preferences');
}
let aboutLink;
if (isPost) {
aboutLink = `/p/${params.subplebbitAddress}/c/${params.commentCid}/about`;
} else if (isSubplebbit || isSubplebbitSubmit) {
aboutLink = `/p/${params.subplebbitAddress}/about`;
} else {
aboutLink = '/about';
}
const aboutButton = (
<li className={styles.about}>
<Link
to={aboutLink}
className={`${isAbout ? styles.selected : styles.choice}`}
onClick={(event) => {
isHome && event.preventDefault();
}}
>
{t('header_about')}
</Link>
</li>
);
return (
<div className={styles.header}>
<div className={`${styles.container} ${hasFewTabs && styles.reducedHeight} ${hasStickyHeader && styles.increasedHeight}`}>
@@ -127,7 +161,7 @@ const Header = () => {
)}
</Link>
</div>
{!isHome && <span className={`${styles.pageName} ${!logoIsAvatar && styles.soloPageName}`}>{headerTitle}</span>}
{!isHome && <span className={`${styles.pageName} ${!logoIsAvatar && styles.soloPageName}`}><HeaderTitle title={title} shortAddress={shortAddress} /></span>}
{isSubplebbit && !isAbout && (
<span className={styles.joinButton}>
<SubscribeButton address={params.subplebbitAddress} />
@@ -135,8 +169,8 @@ const Header = () => {
)}
<div className={`${styles.tabs} ${hasFewTabs ? styles.fewTabs : ''}`}>
<ul className={styles.tabMenu}>
{headerTabs}
{(isSubplebbit || isSubplebbitSubmit || isPost) && aboutButton}
<HeaderTabs />
{(isSubplebbit || isSubplebbitSubmit || isPost) && <AboutButton />}
</ul>
</div>
</div>

View File

@@ -8,6 +8,17 @@ export type ViewType = 'home' | 'pending' | 'post' | 'submit' | 'subplebbit' | '
const sortTypes = ['/hot', '/new', '/active', '/controversialAll', '/topAll'];
export const getAboutLink = (pathname: string, params: ParamsType): string => {
if (params.subplebbitAddress && params.commentCid) {
if (pathname.startsWith(`/p/${params.subplebbitAddress}/c/${params.commentCid}`)) {
return `/p/${params.subplebbitAddress}/c/${params.commentCid}/about`;
} else if (pathname.startsWith(`/p/${params.subplebbitAddress}`)) {
return `/p/${params.subplebbitAddress}/about`;
}
}
return '/about';
};
export const isAboutView = (pathname: string): boolean => {
return pathname.endsWith('/about');
}