import { useTranslation } from 'react-i18next'; import { Link, useLocation, useNavigate, useParams } from 'react-router-dom'; import { useAccountComment, useComment, useSubplebbit, useSubscribe } from '@plebbit/plebbit-react-hooks'; import { isAllView, isCatalogView, isDescriptionView, isPendingPostView, isPostPageView, isSubscriptionsView } from '../../lib/utils/view-utils'; import useCatalogStyleStore from '../../stores/use-catalog-style-store'; import useFeedResetStore from '../../stores/use-feed-reset-store'; import useSortingStore from '../../stores/use-sorting-store'; import useTimeFilter from '../../hooks/use-time-filter'; import CatalogFilters from '../../views/catalog/catalog-filters/'; import styles from './board-buttons.module.css'; import Tooltip from '../tooltip'; import useCountLinksInReplies from '../../hooks/use-count-links-in-replies'; import _ from 'lodash'; import useIsMobile from '../../hooks/use-is-mobile'; import useCatalogFiltersStore from '../../stores/use-catalog-filters-store'; import { useEffect } from 'react'; interface BoardButtonsProps { address?: string | undefined; isInAllView?: boolean; isInCatalogView?: boolean; isInSubscriptionsView?: boolean; isTopbar?: boolean; } const CatalogButton = ({ address, isInAllView, isInSubscriptionsView }: BoardButtonsProps) => { const { t } = useTranslation(); const params = useParams(); const createCatalogLink = () => { if (isInAllView) { if (params?.timeFilterName) return `/p/all/catalog/${params.timeFilterName}`; return `/p/all/catalog`; } else if (isInSubscriptionsView) { if (params?.timeFilterName) return `/p/subscriptions/catalog/${params.timeFilterName}`; return `/p/subscriptions/catalog`; } return `/p/${address}/catalog`; }; return ( ); }; const SubscribeButton = ({ address }: BoardButtonsProps) => { const { t } = useTranslation(); const { subscribed, subscribe, unsubscribe } = useSubscribe({ subplebbitAddress: address }); return ( ); }; const ReturnButton = ({ address, isInAllView, isInSubscriptionsView }: BoardButtonsProps) => { const { t } = useTranslation(); const params = useParams(); const createReturnLink = () => { if (isInAllView) { if (params?.timeFilterName) return `/p/all/${params.timeFilterName}`; return `/p/all`; } else if (isInSubscriptionsView) { if (params?.timeFilterName) return `/p/subscriptions/${params.timeFilterName}`; return `/p/subscriptions`; } return `/p/${address}`; }; return ( ); }; const RefreshButton = () => { const { t } = useTranslation(); const reset = useFeedResetStore((state) => state.reset); return ( ); }; const UpdateButton = () => { const { t } = useTranslation(); const isMobile = useIsMobile(); return ( <> {/* TODO: Implement update button once available in API */} {isMobile ? ( ) : ( )} ); }; const AutoButton = () => { const { t } = useTranslation(); const isMobile = useIsMobile(); return ( <> {isMobile ? ( ) : ( )} ); }; const SortOptions = () => { const { t } = useTranslation(); const { sortType, setSortType } = useSortingStore(); const handleSortChange = (event: React.ChangeEvent) => { const type = event.target.value as 'active' | 'new'; setSortType(type); }; return ( <> {t('sort_by')} ); }; const ImageSizeOptions = () => { const { t } = useTranslation(); const { imageSize, setImageSize } = useCatalogStyleStore(); return ( <> {t('image_size')}:  ); }; const ShowOPCommentOption = () => { const { t } = useTranslation(); const { showOPComment, setShowOPComment } = useCatalogStyleStore(); return ( <> {t('show_op_comment')}:  ); }; export const TimeFilter = ({ isInAllView, isInCatalogView, isInSubscriptionsView, isTopbar = false }: BoardButtonsProps) => { const { t } = useTranslation(); const navigate = useNavigate(); const { timeFilterName, timeFilterNames } = useTimeFilter(); const changeTimeFilter = (event: React.ChangeEvent) => { const timeFilterName = event.target.value; const link = isInAllView ? isInCatalogView ? `/p/all/catalog/${timeFilterName}` : `/p/all/${timeFilterName}` : isInSubscriptionsView ? isInCatalogView ? `/p/subscriptions/catalog/${timeFilterName}` : `/p/subscriptions/${timeFilterName}` : null; link && navigate(link); }; const { sortType } = useSortingStore(); const allTimeFilterNames = timeFilterName && !timeFilterNames.includes(timeFilterName) ? [timeFilterName, ...timeFilterNames.slice(1)] : timeFilterNames.slice(1); return ( <> {!isTopbar ? ( <> {isInCatalogView ? (sortType === 'active' ? t('last_bumped') : t('newer_than')) : t('last_bumped')}:  ) : ( <> )} ); }; export const MobileBoardButtons = () => { const { t } = useTranslation(); const params = useParams(); const location = useLocation(); const isInAllView = isAllView(location.pathname); const isInCatalogView = isCatalogView(location.pathname, params); const isInPendingPostPage = isPendingPostView(location.pathname, params); const isInPostView = isPostPageView(location.pathname, params); const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any }); const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress; const { filteredCount, resetFilteredCount } = useCatalogFiltersStore(); useEffect(() => { if (subplebbitAddress) { resetFilteredCount(); } }, [subplebbitAddress, resetFilteredCount]); return (
{isInPostView || isInPendingPostPage ? ( <>
) : ( <> {isInCatalogView ? ( ) : ( )} {!(isInAllView || isInSubscriptionsView) && } {isInCatalogView && filteredCount > 0 && ( {' '} — {t('filtered_threads')}: {filteredCount} )} {isInCatalogView && ( <>
)} )}
); }; const PostPageStats = () => { const { t } = useTranslation(); const params = useParams(); const location = useLocation(); const isInDescriptionView = isDescriptionView(location.pathname, params); const comment = useComment({ commentCid: params?.commentCid }); const subplebbit = useSubplebbit({ subplebbitAddress: params?.subplebbitAddress }); const descriptionReplyCount = location?.pathname.startsWith('/p/all/') ? 0 : subplebbit?.rules?.length > 0 ? 1 : 0; const { closed, pinned, replyCount } = comment || {}; const linkCount = useCountLinksInReplies(comment); const displayReplyCount = replyCount !== undefined ? replyCount.toString() : isInDescriptionView ? descriptionReplyCount : '?'; const replyCountTooltip = replyCount !== undefined || isInDescriptionView ? _.capitalize(t('replies')) : t('loading'); return ( {(pinned || isInDescriptionView) && `${_.capitalize(t('sticky'))} / `} {(closed || isInDescriptionView) && `${_.capitalize(t('closed'))} / `} / ); }; export const DesktopBoardButtons = () => { const { t } = useTranslation(); const params = useParams(); const location = useLocation(); const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any }); const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress; const isInCatalogView = isCatalogView(location.pathname, params); const isInAllView = isAllView(location.pathname); const isInPendingPostPage = isPendingPostView(location.pathname, params); const isInPostView = isPostPageView(location.pathname, params); const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const { filteredCount, resetFilteredCount } = useCatalogFiltersStore(); useEffect(() => { if (subplebbitAddress) { resetFilteredCount(); } }, [subplebbitAddress, resetFilteredCount]); return ( <>
{isInPostView || isInPendingPostPage ? ( <> [ ] [ ] [ ] [ ] ) : ( <> {isInCatalogView ? ( <> [ ]{' '} ) : ( <> [ ]{' '} )} [] {isInCatalogView && filteredCount > 0 && ( {' '} — {t('filtered_threads')}: {filteredCount} )} {isInCatalogView && ( <> )} {(isInAllView || isInSubscriptionsView) && ( )} {isInCatalogView && ( <> [ ] )}{' '} {!(isInAllView || isInSubscriptionsView) && ( <> [ ] )} )}
); };