mirror of
https://github.com/plebbit/seedit.git
synced 2026-02-06 12:01:04 -05:00
417 lines
17 KiB
TypeScript
417 lines
17 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { Link, useLocation, useParams } from 'react-router-dom';
|
|
import { useTranslation } from 'react-i18next';
|
|
import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js';
|
|
import { useAccount, useSubplebbit } from '@plebbit/plebbit-react-hooks';
|
|
import { sortTypes } from '../../app';
|
|
import {
|
|
getAboutLink,
|
|
isAllView,
|
|
isAllAboutView,
|
|
isAuthorView,
|
|
isAuthorCommentsView,
|
|
isAuthorSubmittedView,
|
|
isCreateSubplebbitView,
|
|
isHomeAboutView,
|
|
isHomeView,
|
|
isInboxView,
|
|
isPendingPostView,
|
|
isPostPageView,
|
|
isProfileView,
|
|
isProfileCommentsView,
|
|
isProfileDownvotedView,
|
|
isProfileSubmittedView,
|
|
isProfileHiddenView,
|
|
isSettingsView,
|
|
isSubmitView,
|
|
isSubplebbitView,
|
|
isSubplebbitSettingsView,
|
|
isSubplebbitSubmitView,
|
|
isSubplebbitsView,
|
|
isSubplebbitsSubscriberView,
|
|
isSubplebbitsModeratorView,
|
|
isSubplebbitsAdminView,
|
|
isSubplebbitsVoteView,
|
|
isSubplebbitsOwnerView,
|
|
isProfileUpvotedView,
|
|
isSettingsPlebbitOptionsView,
|
|
isSubplebbitAboutView,
|
|
} from '../../lib/utils/view-utils';
|
|
import useNotFoundStore from '../../stores/use-not-found-store';
|
|
import useTheme from '../../hooks/use-theme';
|
|
import useWindowWidth from '../../hooks/use-window-width';
|
|
import styles from './header.module.css';
|
|
import SubscribeButton from '../subscribe-button';
|
|
|
|
const AboutButton = () => {
|
|
const { t } = useTranslation();
|
|
const params = useParams();
|
|
const location = useLocation();
|
|
const aboutLink = getAboutLink(location.pathname, params);
|
|
const isInHomeAboutView = isHomeAboutView(location.pathname);
|
|
const isInSubplebbitAboutView = isSubplebbitAboutView(location.pathname, params);
|
|
|
|
return (
|
|
<li className={`${styles.about} ${isInHomeAboutView || isInSubplebbitAboutView ? styles.selected : styles.choice}`}>
|
|
<Link to={aboutLink}>{t('about')}</Link>
|
|
</li>
|
|
);
|
|
};
|
|
|
|
const CommentsButton = () => {
|
|
const { t } = useTranslation();
|
|
const params = useParams();
|
|
const location = useLocation();
|
|
const isInPostPageView = isPostPageView(location.pathname, params);
|
|
const isInHomeAboutView = isHomeAboutView(location.pathname);
|
|
|
|
return (
|
|
<li className={isInPostPageView && !isInHomeAboutView ? styles.selected : styles.choice}>
|
|
<Link to={`/p/${params.subplebbitAddress}/c/${params.commentCid}`}>{t('comments')}</Link>
|
|
</li>
|
|
);
|
|
};
|
|
|
|
const SortItems = () => {
|
|
const { t } = useTranslation();
|
|
const params = useParams();
|
|
const location = useLocation();
|
|
const isInHomeAboutView = isHomeAboutView(location.pathname);
|
|
const isInSubplebbitAboutView = isSubplebbitAboutView(location.pathname, params);
|
|
const isInAllView = isAllView(location.pathname);
|
|
const isInSubplebbitView = isSubplebbitView(location.pathname, params);
|
|
const sortLabels = [t('hot'), t('new'), t('active'), t('controversial'), t('top')];
|
|
const [selectedSortType, setSelectedSortType] = useState(params.sortType || '/hot');
|
|
const timeFilterName = params.timeFilterName;
|
|
|
|
useEffect(() => {
|
|
if (isInHomeAboutView || isInSubplebbitAboutView) {
|
|
setSelectedSortType('');
|
|
} else if (params.sortType) {
|
|
setSelectedSortType(params.sortType);
|
|
} else {
|
|
setSelectedSortType('hot');
|
|
}
|
|
}, [params.sortType, isInHomeAboutView, isInSubplebbitAboutView]);
|
|
|
|
return sortTypes.map((sortType, index) => {
|
|
let sortLink = isInSubplebbitView ? `/p/${params.subplebbitAddress}/${sortType}` : isInAllView ? `p/all/${sortType}` : sortType;
|
|
if (timeFilterName) {
|
|
sortLink = sortLink + `/${timeFilterName}`;
|
|
}
|
|
return (
|
|
<li key={sortType} className={selectedSortType === sortType ? styles.selected : styles.choice}>
|
|
<Link to={sortLink} onClick={() => setSelectedSortType(sortType)}>
|
|
{sortLabels[index]}
|
|
</Link>
|
|
</li>
|
|
);
|
|
});
|
|
};
|
|
|
|
const AuthorHeaderTabs = () => {
|
|
const { t } = useTranslation();
|
|
const location = useLocation();
|
|
const params = useParams();
|
|
const isInAuthorView = isAuthorView(location.pathname);
|
|
const isInAuthorCommentsView = isAuthorCommentsView(location.pathname, params);
|
|
const isInAuthorSubmittedView = isAuthorSubmittedView(location.pathname, params);
|
|
const isInProfileDownvotedView = isProfileDownvotedView(location.pathname);
|
|
const isInProfileView = isProfileView(location.pathname);
|
|
const isInProfileCommentsView = isProfileCommentsView(location.pathname);
|
|
const isInProfileSubmittedView = isProfileSubmittedView(location.pathname);
|
|
const isInProfileUpvotedView = isProfileUpvotedView(location.pathname);
|
|
const isInProfileHiddenView = isProfileHiddenView(location.pathname);
|
|
|
|
const authorRoute = `/u/${params.authorAddress}/c/${params.commentCid}`;
|
|
const overviewSelectedClass =
|
|
(isInProfileView || isInAuthorView) &&
|
|
!isInProfileUpvotedView &&
|
|
!isInProfileDownvotedView &&
|
|
!isInProfileCommentsView &&
|
|
!isInProfileSubmittedView &&
|
|
!isInAuthorCommentsView &&
|
|
!isInProfileHiddenView &&
|
|
!isInAuthorSubmittedView
|
|
? styles.selected
|
|
: styles.choice;
|
|
|
|
return (
|
|
<>
|
|
<li className={overviewSelectedClass}>
|
|
<Link to={isInAuthorView ? authorRoute : '/profile'}>{t('overview')}</Link>
|
|
</li>
|
|
<li className={isInProfileCommentsView || isInAuthorCommentsView ? styles.selected : styles.choice}>
|
|
<Link to={isInAuthorView ? authorRoute + '/comments' : '/profile/comments'}>{t('comments')}</Link>
|
|
</li>
|
|
<li className={isInProfileSubmittedView || isInAuthorSubmittedView ? styles.selected : styles.choice}>
|
|
<Link to={isInAuthorView ? authorRoute + '/submitted' : '/profile/submitted'}>{t('submitted')}</Link>
|
|
</li>
|
|
{isInProfileView && (
|
|
<>
|
|
<li className={isInProfileUpvotedView ? styles.selected : styles.choice}>
|
|
<Link to='/profile/upvoted'>{t('upvoted')}</Link>
|
|
</li>
|
|
<li className={isInProfileDownvotedView ? styles.selected : styles.choice}>
|
|
<Link to='/profile/downvoted'>{t('downvoted')}</Link>
|
|
</li>
|
|
<li className={isInProfileHiddenView ? styles.selected : styles.choice}>
|
|
<Link to={'/profile/hidden'}>{t('hidden')}</Link>
|
|
</li>
|
|
{/* TODO: implement functionality from API once available
|
|
<li>
|
|
<Link to={'/'} className={styles.choice} onClick={(e) => e.preventDefault()}>
|
|
{t('saved')}
|
|
</Link>
|
|
</li> */}
|
|
</>
|
|
)}
|
|
</>
|
|
);
|
|
};
|
|
|
|
const InboxHeaderTabs = () => {
|
|
const { t } = useTranslation();
|
|
|
|
return (
|
|
<>
|
|
<li className={styles.selected}>
|
|
<Link to={'/inbox'}>{t('inbox')}</Link>
|
|
</li>
|
|
{/* TODO: add tabs for messaging when available in the API */}
|
|
</>
|
|
);
|
|
};
|
|
|
|
const SubplebbitsHeaderTabs = () => {
|
|
const { t } = useTranslation();
|
|
const location = useLocation();
|
|
const isInSubplebbitsSubscriberView = isSubplebbitsSubscriberView(location.pathname);
|
|
const isInSubplebbitsModeratorView = isSubplebbitsModeratorView(location.pathname);
|
|
const isInSubplebbitsAdminView = isSubplebbitsAdminView(location.pathname);
|
|
const isInSubplebbitsOwnerView = isSubplebbitsOwnerView(location.pathname);
|
|
const isInSubplebbitsVoteView = isSubplebbitsVoteView(location.pathname);
|
|
const isInSubplebbitsView =
|
|
isSubplebbitsView(location.pathname) &&
|
|
!isInSubplebbitsSubscriberView &&
|
|
!isInSubplebbitsModeratorView &&
|
|
!isInSubplebbitsAdminView &&
|
|
!isInSubplebbitsOwnerView &&
|
|
!isInSubplebbitsVoteView;
|
|
|
|
return (
|
|
<>
|
|
<li className={`${isInSubplebbitsVoteView ? styles.selected : styles.choice}`}>
|
|
<Link to={'/communities/vote'}>{t('vote')}</Link>
|
|
</li>
|
|
<li
|
|
className={
|
|
isInSubplebbitsSubscriberView || isInSubplebbitsModeratorView || isInSubplebbitsAdminView || isInSubplebbitsOwnerView || isInSubplebbitsView
|
|
? styles.selected
|
|
: styles.choice
|
|
}
|
|
>
|
|
<Link to={'/communities'}>{t('my_communities')}</Link>
|
|
</li>
|
|
</>
|
|
);
|
|
};
|
|
|
|
const SettingsHeaderTabs = () => {
|
|
const { t } = useTranslation();
|
|
const isInSettingsPlebbitOptionsView = isSettingsPlebbitOptionsView(useLocation().pathname);
|
|
|
|
return (
|
|
<>
|
|
<li className={isInSettingsPlebbitOptionsView ? styles.choice : styles.selected}>
|
|
<Link to={'/settings'}>{t('general')}</Link>
|
|
</li>
|
|
<li className={isInSettingsPlebbitOptionsView ? styles.selected : styles.choice}>
|
|
<Link to={'/settings/plebbit-options'}>{t('plebbit_options')}</Link>
|
|
</li>
|
|
</>
|
|
);
|
|
};
|
|
|
|
const HeaderTabs = () => {
|
|
const { t } = useTranslation();
|
|
const params = useParams();
|
|
const location = useLocation();
|
|
const isInAllView = isAllView(location.pathname);
|
|
const isInAuthorView = isAuthorView(location.pathname);
|
|
const isInHomeAboutView = isHomeAboutView(location.pathname);
|
|
const isInHomeView = isHomeView(location.pathname);
|
|
const isInInboxView = isInboxView(location.pathname);
|
|
const isInPendingPostView = isPendingPostView(location.pathname, params);
|
|
const isInPostPageView = isPostPageView(location.pathname, params);
|
|
const isInProfileView = isProfileView(location.pathname);
|
|
const isInSubplebbitView = isSubplebbitView(location.pathname, params);
|
|
const isInSubplebbitSettingsView = isSubplebbitSettingsView(location.pathname, params);
|
|
const isInSubplebbitSubmitView = isSubplebbitSubmitView(location.pathname, params);
|
|
const isInSubplebbitsView = isSubplebbitsView(location.pathname);
|
|
const isInCreateSubplebbitView = isCreateSubplebbitView(location.pathname);
|
|
const isInSettingsView = isSettingsView(location.pathname);
|
|
const isInSettingsPlebbitOptionsView = isSettingsPlebbitOptionsView(location.pathname);
|
|
|
|
if (isInPostPageView) {
|
|
return <CommentsButton />;
|
|
} else if (isInHomeView || isInHomeAboutView || (isInSubplebbitView && !isInSubplebbitSubmitView && !isInSubplebbitSettingsView) || isInAllView) {
|
|
return <SortItems />;
|
|
} else if ((isInProfileView || isInAuthorView) && !isInPendingPostView) {
|
|
return <AuthorHeaderTabs />;
|
|
} else if (isInPendingPostView) {
|
|
return <span className={styles.pageName}>{t('pending')}</span>;
|
|
} else if (isInInboxView) {
|
|
return <InboxHeaderTabs />;
|
|
} else if (isInSubplebbitsView && !isInCreateSubplebbitView) {
|
|
return <SubplebbitsHeaderTabs />;
|
|
} else if (isInSettingsView || isInSettingsPlebbitOptionsView) {
|
|
return <SettingsHeaderTabs />;
|
|
}
|
|
return null;
|
|
};
|
|
|
|
const HeaderTitle = ({ title, shortAddress }: { title: string; shortAddress: string }) => {
|
|
const account = useAccount();
|
|
const { t } = useTranslation();
|
|
const params = useParams();
|
|
const location = useLocation();
|
|
const isInAllView = isAllView(location.pathname);
|
|
const isInAuthorView = isAuthorView(location.pathname);
|
|
const isInInboxView = isInboxView(location.pathname);
|
|
const isInPostPageView = isPostPageView(location.pathname, params);
|
|
const isInProfileView = isProfileView(location.pathname);
|
|
const isInSettingsView = isSettingsView(location.pathname);
|
|
const isInSettingsPlebbitOptionsView = isSettingsPlebbitOptionsView(location.pathname);
|
|
const isInSubmitView = isSubmitView(location.pathname);
|
|
const isInSubplebbitView = isSubplebbitView(location.pathname, params);
|
|
const isInSubplebbitSubmitView = isSubplebbitSubmitView(location.pathname, params);
|
|
const isInSubplebbitSettingsView = isSubplebbitSettingsView(location.pathname, params);
|
|
const isInSubplebbitsView = isSubplebbitsView(location.pathname);
|
|
const isInCreateSubplebbitView = isCreateSubplebbitView(location.pathname);
|
|
const isInNotFoundView = useNotFoundStore((state) => state.isNotFound);
|
|
|
|
const subplebbitTitle = <Link to={`/p/${params.subplebbitAddress}`}>{title || shortAddress}</Link>;
|
|
const submitTitle = <span className={styles.submitTitle}>{t('submit')}</span>;
|
|
const profileTitle = <Link to='/profile'>{account?.author?.shortAddress}</Link>;
|
|
const authorTitle = <Link to={`/u/${params.authorAddress}/c/${params.commentCid}`}>{params.authorAddress && Plebbit.getShortAddress(params.authorAddress)}</Link>;
|
|
|
|
if (isInSubplebbitSubmitView) {
|
|
return (
|
|
<>
|
|
{subplebbitTitle}: {submitTitle}
|
|
</>
|
|
);
|
|
} else if (isInPostPageView || (isInSubplebbitView && !isInSubplebbitSettingsView)) {
|
|
return subplebbitTitle;
|
|
} else if (isInSubplebbitSettingsView) {
|
|
return (
|
|
<>
|
|
{subplebbitTitle}: <span className={styles.lowercase}>{t('community_settings')}</span>
|
|
</>
|
|
);
|
|
} else if (isInSubmitView) {
|
|
return submitTitle;
|
|
} else if (isInSettingsView || isInSettingsPlebbitOptionsView) {
|
|
return t('preferences');
|
|
} else if (isInProfileView) {
|
|
return profileTitle;
|
|
} else if (isInAuthorView) {
|
|
return authorTitle;
|
|
} else if (isInInboxView) {
|
|
return t('messages');
|
|
} else if (isInCreateSubplebbitView) {
|
|
return <span className={styles.lowercase}>{t('create_community')}</span>;
|
|
} else if (isInSubplebbitsView) {
|
|
return t('communities');
|
|
} else if (isInNotFoundView) {
|
|
return <span className={styles.lowercase}>{t('page_not_found')}</span>;
|
|
} else if (isInAllView) {
|
|
return t('all');
|
|
}
|
|
return null;
|
|
};
|
|
|
|
const Header = () => {
|
|
const [theme] = useTheme();
|
|
const location = useLocation();
|
|
const params = useParams();
|
|
const subplebbit = useSubplebbit({ subplebbitAddress: params.subplebbitAddress });
|
|
const { suggested, title, shortAddress } = subplebbit || {};
|
|
|
|
const isMobile = useWindowWidth() < 640;
|
|
const isInAllAboutView = isAllAboutView(location.pathname);
|
|
const isInAllView = isAllView(location.pathname);
|
|
const isInAuthorView = isAuthorView(location.pathname);
|
|
const isInHomeView = isHomeView(location.pathname);
|
|
const isInHomeAboutView = isHomeAboutView(location.pathname);
|
|
const isInInboxView = isInboxView(location.pathname);
|
|
const isInPostPageView = isPostPageView(location.pathname, params);
|
|
const isInProfileView = isProfileView(location.pathname);
|
|
const isInSettingsView = isSettingsView(location.pathname);
|
|
const isInSubplebbitView = isSubplebbitView(location.pathname, params);
|
|
const isInSubplebbitAboutView = isSubplebbitAboutView(location.pathname, params);
|
|
const isInSubmitView = isSubmitView(location.pathname);
|
|
const isInSubplebbitSubmitView = isSubplebbitSubmitView(location.pathname, params);
|
|
const isInSubplebbitSettingsView = isSubplebbitSettingsView(location.pathname, params);
|
|
const isInNotFoundView = useNotFoundStore((state) => state.isNotFound);
|
|
|
|
const hasFewTabs =
|
|
isInPostPageView || isInSubmitView || isInSubplebbitSubmitView || isInSubplebbitSettingsView || isInSettingsView || isInInboxView || isInSettingsView;
|
|
const hasStickyHeader =
|
|
isInHomeView ||
|
|
isInNotFoundView ||
|
|
(isInSubplebbitView && !isInSubplebbitSubmitView && !isInSubplebbitSettingsView && !isInPostPageView && !isInHomeAboutView && !isInSubplebbitAboutView) ||
|
|
(isInProfileView && !isInHomeAboutView) ||
|
|
(isInAllView && !isInAllAboutView) ||
|
|
(isInAuthorView && !isInHomeAboutView);
|
|
const logoSrc = isInSubplebbitView && suggested?.avatarUrl ? suggested?.avatarUrl : 'assets/logo/seedit.png';
|
|
const logoIsAvatar = isInSubplebbitView && suggested?.avatarUrl;
|
|
const logoLink = isInSubplebbitView ? `/p/${params.subplebbitAddress}` : isInProfileView ? '/profile' : '/';
|
|
|
|
return (
|
|
<div className={styles.header}>
|
|
<div
|
|
className={`${styles.container} ${hasFewTabs && styles.reducedHeight} ${
|
|
isInSubmitView && isInSubplebbitSubmitView && !isInSubplebbitView && isMobile && styles.reduceSubmitPageHeight
|
|
} ${hasStickyHeader && styles.increasedHeight}`}
|
|
>
|
|
<div className={styles.logoContainer}>
|
|
<Link to={logoLink} className={styles.logoLink}>
|
|
{(logoIsAvatar || (!isInSubplebbitView && !isInProfileView && !isInAuthorView) || (isInSubplebbitView && !suggested?.avatarUrl)) && (
|
|
<img className={`${logoIsAvatar ? styles.avatar : styles.logo}`} src={logoSrc} alt='' />
|
|
)}
|
|
{((!isInSubplebbitView && !isInProfileView && !isInAuthorView) || (isInSubplebbitView && !suggested?.avatarUrl)) && (
|
|
<img src={`assets/logo/seedit-text-${theme === 'dark' ? 'dark' : 'light'}.svg`} className={styles.logoText} alt='' />
|
|
)}
|
|
</Link>
|
|
</div>
|
|
{!isInHomeView && !isInHomeAboutView && (
|
|
<span className={`${styles.pageName} ${!logoIsAvatar && styles.soloPageName}`}>
|
|
<HeaderTitle title={title} shortAddress={shortAddress} />
|
|
</span>
|
|
)}
|
|
{isInSubplebbitView && !isInSubplebbitSubmitView && (
|
|
<span className={styles.joinButton}>
|
|
<SubscribeButton address={params.subplebbitAddress} />
|
|
</span>
|
|
)}
|
|
{!isMobile && (
|
|
<ul className={styles.tabMenu}>
|
|
<HeaderTabs />
|
|
{(isInHomeView || isInHomeAboutView) && <AboutButton />}
|
|
</ul>
|
|
)}
|
|
</div>
|
|
{isMobile && !isInSubplebbitSubmitView && (
|
|
<ul className={`${styles.tabMenu} ${isInProfileView ? styles.horizontalScroll : ''}`}>
|
|
<HeaderTabs />
|
|
{(isInHomeView || isInHomeAboutView || isInSubplebbitView || isInHomeAboutView || isInAllView || isInPostPageView) && <AboutButton />}
|
|
</ul>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Header;
|