2024-04-03 22:52:27 +02:00
import { useTranslation } from 'react-i18next' ;
2024-06-09 16:40:32 +02:00
import { Link , useLocation , useNavigate , useParams } from 'react-router-dom' ;
2025-03-06 13:15:33 +01:00
import { useAccountComment , useSubscribe } from '@plebbit/plebbit-react-hooks' ;
import useSubplebbitsPagesStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits-pages' ;
2026-01-07 16:03:02 +01:00
import { isAllView , isCatalogView , isModView , isModQueueView , isPendingPostView , isPostPageView , isSubscriptionsView } from '../../lib/utils/view-utils' ;
2025-11-07 12:50:58 +01:00
import { useDefaultSubplebbits } from '../../hooks/use-default-subplebbits' ;
2025-11-12 14:54:50 +01:00
import { getBoardPath , isDirectoryBoard } from '../../lib/utils/route-utils' ;
2025-11-07 12:50:58 +01:00
import { useResolvedSubplebbitAddress } from '../../hooks/use-resolved-subplebbit-address' ;
2025-03-06 15:44:26 +01:00
import useCatalogFiltersStore from '../../stores/use-catalog-filters-store' ;
2024-06-20 15:00:31 +02:00
import useCatalogStyleStore from '../../stores/use-catalog-style-store' ;
2024-05-31 10:41:44 +02:00
import useFeedResetStore from '../../stores/use-feed-reset-store' ;
2024-06-20 15:00:31 +02:00
import useSortingStore from '../../stores/use-sorting-store' ;
2025-12-29 16:18:59 +01:00
import useAllFeedFilterStore from '../../stores/use-all-feed-filter-store' ;
2024-07-05 10:53:50 +02:00
import useCountLinksInReplies from '../../hooks/use-count-links-in-replies' ;
2024-09-08 10:41:08 +02:00
import useIsMobile from '../../hooks/use-is-mobile' ;
2025-03-06 15:44:26 +01:00
import useTimeFilter from '../../hooks/use-time-filter' ;
import CatalogFilters from '../catalog-filters' ;
import CatalogSearch from '../catalog-search' ;
import Tooltip from '../tooltip' ;
2026-01-08 16:43:14 +01:00
import { ModQueueButton } from '../../views/mod-queue/mod-queue' ;
2025-03-06 15:44:26 +01:00
import styles from './board-buttons.module.css' ;
import _ from 'lodash' ;
2024-03-22 12:09:17 +01:00
interface BoardButtonsProps {
2024-05-30 18:01:37 +02:00
address? : string | undefined ;
2024-06-09 16:50:51 +02:00
isInAllView? : boolean ;
2024-04-12 17:47:30 +02:00
isInCatalogView? : boolean ;
2024-05-17 16:39:02 +02:00
isInSubscriptionsView? : boolean ;
2025-06-04 16:36:16 +02:00
isInModView? : boolean ;
2026-01-07 16:03:02 +01:00
isInModQueueView? : boolean ;
2024-06-09 16:50:51 +02:00
isTopbar? : boolean ;
2024-03-22 12:09:17 +01:00
}
2025-06-04 16:36:16 +02:00
const CatalogButton = ({ address , isInAllView , isInSubscriptionsView , isInModView } : BoardButtonsProps ) => {
2024-03-22 12:22:20 +01:00
const { t } = useTranslation ();
2024-06-11 15:13:04 +02:00
const params = useParams ();
2025-11-07 12:50:58 +01:00
const defaultSubplebbits = useDefaultSubplebbits ();
2024-06-11 15:13:04 +02:00
const createCatalogLink = () => {
if ( isInAllView ) {
2025-11-07 12:50:58 +01:00
if ( params ? . timeFilterName ) return `/all/catalog/ ${ params . timeFilterName } ` ;
return `/all/catalog` ;
2024-06-11 15:13:04 +02:00
} else if ( isInSubscriptionsView ) {
2025-11-12 16:35:38 +01:00
if ( params ? . timeFilterName ) return `/subs/catalog/ ${ params . timeFilterName } ` ;
return `/subs/catalog` ;
2025-06-04 16:36:16 +02:00
} else if ( isInModView ) {
2025-11-07 12:50:58 +01:00
if ( params ? . timeFilterName ) return `/mod/catalog/ ${ params . timeFilterName } ` ;
return `/mod/catalog` ;
2024-06-11 15:13:04 +02:00
}
2025-11-07 18:54:45 +01:00
let boardPath = '' ;
if ( address ) {
boardPath = getBoardPath ( address , defaultSubplebbits );
} else if ( Array . isArray ( defaultSubplebbits ) && defaultSubplebbits . length > 0 && defaultSubplebbits [ 0 ] ? . address ) {
boardPath = getBoardPath ( defaultSubplebbits [ 0 ]. address , defaultSubplebbits );
}
2025-11-07 12:50:58 +01:00
return `/ ${ boardPath } /catalog` ;
2024-06-11 15:13:04 +02:00
};
2024-05-17 21:27:06 +02:00
return (
< button className = 'button' >
2024-06-11 15:13:04 +02:00
< Link to = { createCatalogLink ()}>{ t ( 'catalog' )}</ Link >
2024-05-17 21:27:06 +02:00
</ button >
);
2024-03-22 12:09:17 +01:00
};
const SubscribeButton = ({ address } : BoardButtonsProps ) => {
2024-03-22 12:22:20 +01:00
const { t } = useTranslation ();
2024-03-22 12:09:17 +01:00
const { subscribed , subscribe , unsubscribe } = useSubscribe ({ subplebbitAddress : address });
return (
< button className = 'button' onClick = { subscribed ? unsubscribe : subscribe }>
2024-03-22 12:22:20 +01:00
{ subscribed ? t ( 'unsubscribe' ) : t ( 'subscribe' )}
2024-03-22 12:09:17 +01:00
</ button >
);
};
2026-01-07 16:03:02 +01:00
const ReturnButton = ({ address , isInAllView , isInSubscriptionsView , isInModView , isInModQueueView } : BoardButtonsProps ) => {
2024-04-03 22:52:27 +02:00
const { t } = useTranslation ();
2024-06-11 15:13:04 +02:00
const params = useParams ();
2025-11-07 12:50:58 +01:00
const defaultSubplebbits = useDefaultSubplebbits ();
2024-06-11 15:13:04 +02:00
const createReturnLink = () => {
if ( isInAllView ) {
2025-11-07 12:50:58 +01:00
if ( params ? . timeFilterName ) return `/all/ ${ params . timeFilterName } ` ;
return `/all` ;
2024-06-11 15:13:04 +02:00
} else if ( isInSubscriptionsView ) {
2025-11-12 16:35:38 +01:00
if ( params ? . timeFilterName ) return `/subs/ ${ params . timeFilterName } ` ;
return `/subs` ;
2026-01-07 16:03:02 +01:00
} else if ( isInModQueueView ) {
// If in mod queue view, return to /mod or /:boardIdentifier
if ( params ? . boardIdentifier ) {
return `/ ${ params . boardIdentifier } ` ;
}
return `/mod` ;
2025-06-04 16:36:16 +02:00
} else if ( isInModView ) {
2025-11-07 12:50:58 +01:00
if ( params ? . timeFilterName ) return `/mod/ ${ params . timeFilterName } ` ;
return `/mod` ;
2024-06-11 15:13:04 +02:00
}
2025-11-07 18:54:45 +01:00
let boardPath = '' ;
if ( address ) {
boardPath = getBoardPath ( address , defaultSubplebbits );
} else if ( Array . isArray ( defaultSubplebbits ) && defaultSubplebbits . length > 0 && defaultSubplebbits [ 0 ] ? . address ) {
boardPath = getBoardPath ( defaultSubplebbits [ 0 ]. address , defaultSubplebbits );
}
2025-11-07 12:50:58 +01:00
return `/ ${ boardPath } ` ;
2024-06-11 15:13:04 +02:00
};
2024-04-03 22:52:27 +02:00
return (
< button className = 'button' >
2024-06-11 15:13:04 +02:00
< Link to = { createReturnLink ()}>{ t ( 'return' )}</ Link >
2024-04-03 22:52:27 +02:00
</ button >
);
};
2025-11-12 14:54:50 +01:00
const VoteButton = () => {
const { t } = useTranslation ();
const params = useParams ();
const defaultSubplebbits = useDefaultSubplebbits ();
// Get the boardIdentifier from params (try boardIdentifier first, then subplebbitAddress for backward compatibility)
const boardIdentifier = params . boardIdentifier || params . subplebbitAddress ;
// Only render the vote button if we're on a directory board route
if ( ! boardIdentifier || ! isDirectoryBoard ( boardIdentifier , defaultSubplebbits )) {
return null ;
}
const message = `Not available yet. Users will be able to submit and vote for boards competing for directory slots (like / ${ boardIdentifier } ). The highest-voted board becomes the directory board.` ;
return (
< button className = { `button ${ styles . disabledButton } ` } title = { message } onClick = {() => window . alert ( message )}>
{ t ( 'vote' )}
</ button >
);
};
2024-05-31 15:16:21 +02:00
const RefreshButton = () => {
2024-05-31 17:09:20 +02:00
const { t } = useTranslation ();
2024-05-31 15:16:21 +02:00
const reset = useFeedResetStore (( state ) => state . reset );
2024-04-03 22:52:27 +02:00
return (
2024-05-31 15:16:21 +02:00
< button className = 'button' onClick = {() => reset && reset ()}>
2024-05-31 17:09:20 +02:00
{ t ( 'refresh' )}
2024-04-03 22:52:27 +02:00
</ button >
);
};
2024-09-08 10:41:08 +02:00
const UpdateButton = () => {
const { t } = useTranslation ();
const isMobile = useIsMobile ();
2025-03-03 23:43:45 +01:00
const handleManualUpdate = () => {
2025-02-20 21:50:32 +01:00
window . alert ( 'Manual updates are not available yet. Posts update automatically every ~2 minutes.' );
};
2024-09-08 10:41:08 +02:00
return (
<>
{ /* TODO: Implement update button once available in API */ }
{ isMobile ? (
2025-03-03 23:43:45 +01:00
< button className = { `button ${ styles . disabledButton } ` } onClick = { handleManualUpdate }>
2025-02-20 21:50:32 +01:00
{ t ( 'update' )}
</ button >
2024-09-08 10:41:08 +02:00
) : (
2025-03-03 23:43:45 +01:00
< button className = { `button ${ styles . disabledButton } ` } onClick = { handleManualUpdate }>
2025-02-20 21:50:32 +01:00
{ t ( 'update' )}
</ button >
2024-09-08 10:41:08 +02:00
)}
</>
);
};
const AutoButton = () => {
const { t } = useTranslation ();
const isMobile = useIsMobile ();
2025-03-03 23:43:45 +01:00
const handleManualUpdate = () => {
window . alert ( 'Manual updates are not available yet. Posts update automatically every ~2 minutes.' );
};
2024-09-08 10:41:08 +02:00
return (
<>
{ isMobile ? (
2025-03-03 23:43:45 +01:00
< button className = 'button' onClick = { handleManualUpdate }>
2024-09-08 10:41:08 +02:00
< label >
< input type = 'checkbox' className = { styles . autoCheckbox } checked disabled />
{ t ( 'Auto' )}
</ label >
</ button >
) : (
2025-03-03 23:43:45 +01:00
< label onClick = { handleManualUpdate }>
2024-09-08 10:41:08 +02:00
{ ' ' }
< input type = 'checkbox' className = { styles . autoCheckbox } checked disabled /> { t ( 'Auto' )}
</ label >
)}
</>
);
};
2024-05-31 18:18:42 +02:00
const SortOptions = () => {
2024-06-09 16:40:32 +02:00
const { t } = useTranslation ();
2024-06-15 16:42:30 +02:00
const { sortType , setSortType } = useSortingStore ();
2024-05-31 18:18:42 +02:00
const handleSortChange = ( event : React.ChangeEvent < HTMLSelectElement >) => {
const type = event . target . value as 'active' | 'new' ;
setSortType ( type );
};
return (
<>
2024-09-04 20:48:20 +02:00
< span >{ t ( 'sort_by' )}</ span > :& nbsp ;
2024-06-22 10:32:19 +02:00
< select className = 'capitalize' value = { sortType } onChange = { handleSortChange }>
2024-06-09 16:40:32 +02:00
< option value = 'active' >{ t ( 'bump_order' )}</ option >
< option value = 'new' >{ t ( 'creation_date' )}</ option >
2024-06-01 18:13:41 +02:00
</ select >
2024-05-31 18:18:42 +02:00
</>
);
};
2024-06-17 21:16:31 +02:00
const ImageSizeOptions = () => {
2024-06-22 10:32:19 +02:00
const { t } = useTranslation ();
2024-06-17 21:16:31 +02:00
const { imageSize , setImageSize } = useCatalogStyleStore ();
return (
<>
2024-09-04 20:48:20 +02:00
< span >{ t ( 'image_size' )} : </ span > & nbsp ;
2024-06-22 10:32:19 +02:00
< select className = 'capitalize' value = { imageSize } onChange = {( e ) => setImageSize ( e . target . value as 'Small' | 'Large' )}>
< option value = 'Small' >{ t ( 'small' )}</ option >
< option value = 'Large' >{ t ( 'large' )}</ option >
2024-06-17 21:16:31 +02:00
</ select >
</>
);
};
const ShowOPCommentOption = () => {
2024-06-22 10:32:19 +02:00
const { t } = useTranslation ();
2024-06-17 21:16:31 +02:00
const { showOPComment , setShowOPComment } = useCatalogStyleStore ();
return (
<>
2024-09-04 20:48:20 +02:00
< span >{ t ( 'show_op_comment' )} : </ span > & nbsp ;
2024-06-22 10:32:19 +02:00
< select className = 'capitalize' value = { showOPComment ? 'On' : 'Off' } onChange = {( e ) => setShowOPComment ( e . target . value === 'On' )}>
< option value = 'Off' >{ t ( 'off' )}</ option >
< option value = 'On' >{ t ( 'on' )}</ option >
2024-06-17 21:16:31 +02:00
</ select >
</>
);
};
2025-06-04 16:36:16 +02:00
export const TimeFilter = ({ isInAllView , isInCatalogView , isInSubscriptionsView , isInModView , isTopbar = false } : BoardButtonsProps ) => {
2024-06-09 16:40:32 +02:00
const { t } = useTranslation ();
const navigate = useNavigate ();
2024-10-29 17:40:09 +01:00
const { timeFilterName , timeFilterNames } = useTimeFilter ();
2024-06-09 16:40:32 +02:00
const changeTimeFilter = ( event : React.ChangeEvent < HTMLSelectElement >) => {
const timeFilterName = event . target . value ;
2024-06-09 16:50:51 +02:00
const link = isInAllView
? isInCatalogView
2025-11-07 12:50:58 +01:00
? `/all/catalog/ ${ timeFilterName } `
: `/all/ ${ timeFilterName } `
2024-06-09 16:50:51 +02:00
: isInSubscriptionsView
2025-12-29 16:18:59 +01:00
? isInCatalogView
? `/subs/catalog/ ${ timeFilterName } `
: `/subs/ ${ timeFilterName } `
: isInModView
? isInCatalogView
? `/mod/catalog/ ${ timeFilterName } `
: `/mod/ ${ timeFilterName } `
: null ;
2024-06-09 16:50:51 +02:00
link && navigate ( link );
2024-06-09 16:40:32 +02:00
};
2024-10-29 15:56:43 +01:00
const { sortType } = useSortingStore ();
2024-11-14 16:43:10 +01:00
const allTimeFilterNames = timeFilterName ? Array . from ( new Set ([ timeFilterName , ... timeFilterNames ])) : timeFilterNames ;
2024-10-29 17:40:09 +01:00
2024-06-09 16:40:32 +02:00
return (
<>
{ ! isTopbar ? (
<>
2024-10-29 15:56:43 +01:00
< span >{ isInCatalogView ? ( sortType === 'active' ? t ( 'last_bumped' ) : t ( 'newer_than' )) : t ( 'last_bumped' )}</ span > :& nbsp ;
2024-06-09 16:40:32 +02:00
</>
) : (
<> </>
)}
2024-10-29 17:40:09 +01:00
< select onChange = { changeTimeFilter } className = {[ styles . feedName , styles . menuItem , 'capitalize' ]. join ( ' ' )} value = { timeFilterName }>
{ allTimeFilterNames . map (( name , i ) => (
< option key = { name + i } value = { name }>
{ name }
2024-06-09 16:40:32 +02:00
</ option >
))}
</ select >
</>
);
};
2025-12-29 16:18:59 +01:00
const AllFeedFilter = () => {
const { t } = useTranslation ();
const { filter , setFilter } = useAllFeedFilterStore ();
return (
<>
< span >{ t ( 'show' )}</ span > :& nbsp ;
< select className = 'capitalize' value = { filter } onChange = {( e ) => setFilter ( e . target . value as 'all' | 'nsfw' | 'sfw' )}>
2025-12-29 16:35:21 +01:00
< option value = 'all' >{ t ( 'all_boards' )}</ option >
< option value = 'nsfw' >{ t ( 'nsfw_boards_only' )}</ option >
< option value = 'sfw' >{ t ( 'worksafe_boards_only' )}</ option >
2025-12-29 16:18:59 +01:00
</ select >
</>
);
};
2024-04-08 17:13:02 +02:00
export const MobileBoardButtons = () => {
2024-09-10 19:19:39 +02:00
const { t } = useTranslation ();
2024-04-25 22:02:55 +02:00
const params = useParams ();
const location = useLocation ();
2024-10-29 17:40:09 +01:00
const isInAllView = isAllView ( location . pathname );
2024-06-09 16:40:32 +02:00
const isInCatalogView = isCatalogView ( location . pathname , params );
2024-04-25 22:02:55 +02:00
const isInPendingPostPage = isPendingPostView ( location . pathname , params );
2024-05-17 17:25:25 +02:00
const isInPostView = isPostPageView ( location . pathname , params );
2024-06-17 12:17:36 +02:00
const isInSubscriptionsView = isSubscriptionsView ( location . pathname , useParams ());
2025-06-04 16:36:16 +02:00
const isInModView = isModView ( location . pathname );
2026-01-07 16:03:02 +01:00
const isInModQueueView = isModQueueView ( location . pathname );
2024-05-17 17:25:25 +02:00
const accountComment = useAccountComment ({ commentIndex : params?.accountCommentIndex as any });
2025-11-07 12:50:58 +01:00
const resolvedAddress = useResolvedSubplebbitAddress ();
const subplebbitAddress = resolvedAddress || accountComment ? . subplebbitAddress ;
2024-04-25 22:02:55 +02:00
2025-03-06 16:27:09 +01:00
const { filteredCount , searchText } = useCatalogFiltersStore ();
2024-09-10 19:16:13 +02:00
2025-11-18 16:42:48 +01:00
// Check if we should show the vote button (only for directory boards)
const defaultSubplebbits = useDefaultSubplebbits ();
const boardIdentifier = params . boardIdentifier || params . subplebbitAddress ;
const showVoteButton = boardIdentifier && isDirectoryBoard ( boardIdentifier , defaultSubplebbits );
2024-03-22 12:09:17 +01:00
return (
2024-06-30 11:47:09 +02:00
< div className = { ` ${ styles . mobileBoardButtons } ${ ! isInCatalogView ? styles . addMargin : '' } ` }>
2024-05-17 15:29:03 +02:00
{ isInPostView || isInPendingPostPage ? (
2024-05-31 15:16:21 +02:00
<>
2025-06-04 16:36:16 +02:00
< ReturnButton address = { subplebbitAddress } isInAllView = { isInAllView } isInSubscriptionsView = { isInSubscriptionsView } isInModView = { isInModView } />
2025-11-18 16:42:48 +01:00
{ showVoteButton && < VoteButton />}
2025-06-04 16:36:16 +02:00
< CatalogButton address = { subplebbitAddress } isInAllView = { isInAllView } isInSubscriptionsView = { isInSubscriptionsView } isInModView = { isInModView } />
2024-05-31 15:16:21 +02:00
< SubscribeButton address = { subplebbitAddress } />
2024-09-08 10:41:08 +02:00
< div className = { styles . secondRow }>
< UpdateButton />
< AutoButton />
</ div >
2024-05-31 15:16:21 +02:00
</>
2026-01-07 16:03:02 +01:00
) : isInModQueueView ? (
<>
< ReturnButton
address = { subplebbitAddress }
isInAllView = { isInAllView }
isInSubscriptionsView = { isInSubscriptionsView }
isInModView = { isInModView }
isInModQueueView = { isInModQueueView }
/>
< RefreshButton />
</>
2024-04-03 22:52:27 +02:00
) : (
<>
2024-05-31 15:16:21 +02:00
{ isInCatalogView ? (
2025-06-04 16:36:16 +02:00
< ReturnButton address = { subplebbitAddress } isInAllView = { isInAllView } isInSubscriptionsView = { isInSubscriptionsView } isInModView = { isInModView } />
2024-05-31 15:16:21 +02:00
) : (
2025-06-04 16:36:16 +02:00
< CatalogButton address = { subplebbitAddress } isInAllView = { isInAllView } isInSubscriptionsView = { isInSubscriptionsView } isInModView = { isInModView } />
2024-05-31 15:16:21 +02:00
)}
2025-11-18 16:42:48 +01:00
{ showVoteButton && < VoteButton />}
2025-06-04 16:36:16 +02:00
{ ! ( isInAllView || isInSubscriptionsView || isInModView ) && < SubscribeButton address = { subplebbitAddress } />}
2026-01-08 16:43:14 +01:00
{ ! ( isInAllView || isInSubscriptionsView || isInModView ) && < ModQueueButton boardIdentifier = { boardIdentifier } isMobile = { true } />}
2024-05-31 15:16:21 +02:00
< RefreshButton />
2025-03-06 16:27:09 +01:00
{ isInCatalogView && searchText ? (
2024-09-10 19:16:13 +02:00
< span className = { styles . filteredThreadsCount }>
{ ' ' }
2025-03-06 16:27:09 +01:00
— { t ( 'search_results_for' )} : < strong >{ searchText }</ strong >
2024-09-10 19:16:13 +02:00
</ span >
2025-03-06 16:27:09 +01:00
) : (
isInCatalogView &&
filteredCount > 0 && (
< span className = { styles . filteredThreadsCount }>
{ ' ' }
— { t ( 'filtered_threads' )} : < strong >{ filteredCount }</ strong >
</ span >
)
2024-09-10 19:16:13 +02:00
)}
2025-12-29 16:18:59 +01:00
{ isInAllView && (
<>
< hr />
< div className = { styles . options }>
< AllFeedFilter />
</ div >
</>
)}
2024-05-31 18:18:42 +02:00
{ isInCatalogView && (
<>
< hr />
< div className = { styles . options }>
2024-06-17 21:16:31 +02:00
< div >
< SortOptions /> < ImageSizeOptions />
</ div >
< div className = { styles . mobileCatalogOptionsPadding }>
2025-03-06 15:44:26 +01:00
< ShowOPCommentOption /> < CatalogFilters /> < CatalogSearch />
2024-06-17 21:16:31 +02:00
</ div >
2024-05-31 18:18:42 +02:00
</ div >
</>
)}
2024-04-03 22:52:27 +02:00
</>
)}
2024-03-22 12:09:17 +01:00
</ div >
);
};
2024-07-05 10:53:50 +02:00
const PostPageStats = () => {
2024-07-12 10:40:02 +02:00
const { t } = useTranslation ();
2024-07-05 10:53:50 +02:00
const params = useParams ();
2025-03-06 13:15:33 +01:00
const comment = useSubplebbitsPagesStore (( state ) => state . comments [ params ? . commentCid as string ]);
2024-07-07 14:36:14 +02:00
const { closed , pinned , replyCount } = comment || {};
2024-07-05 10:53:50 +02:00
const linkCount = useCountLinksInReplies ( comment );
2025-12-23 19:14:25 +01:00
const displayReplyCount = replyCount !== undefined ? replyCount . toString () : '?' ;
const replyCountTooltip = replyCount !== undefined ? _ . capitalize ( t ( 'replies' )) : t ( 'loading' );
2024-07-12 10:40:02 +02:00
2024-07-05 10:53:50 +02:00
return (
< span >
2025-12-23 19:14:25 +01:00
{ pinned && ` ${ _ . capitalize ( t ( 'sticky' )) } / ` }
{ closed && ` ${ _ . capitalize ( t ( 'closed' )) } / ` }
2024-07-12 10:40:02 +02:00
< Tooltip children = { displayReplyCount } content = { replyCountTooltip } /> / < Tooltip children = { linkCount ? . toString ()} content = { _ . capitalize ( t ( 'links' ))} />
2024-07-05 10:53:50 +02:00
</ span >
);
};
2024-04-08 17:13:02 +02:00
export const DesktopBoardButtons = () => {
2024-09-10 19:19:39 +02:00
const { t } = useTranslation ();
2024-04-12 17:47:30 +02:00
const params = useParams ();
2024-04-25 22:02:55 +02:00
const location = useLocation ();
const accountComment = useAccountComment ({ commentIndex : params?.accountCommentIndex as any });
2025-11-07 12:50:58 +01:00
const resolvedAddress = useResolvedSubplebbitAddress ();
const subplebbitAddress = resolvedAddress || accountComment ? . subplebbitAddress ;
2024-06-09 16:40:32 +02:00
const isInCatalogView = isCatalogView ( location . pathname , params );
2024-10-29 17:40:09 +01:00
const isInAllView = isAllView ( location . pathname );
2024-04-25 22:02:55 +02:00
const isInPendingPostPage = isPendingPostView ( location . pathname , params );
2024-05-17 15:29:03 +02:00
const isInPostView = isPostPageView ( location . pathname , params );
2024-06-17 12:17:36 +02:00
const isInSubscriptionsView = isSubscriptionsView ( location . pathname , useParams ());
2025-06-04 16:36:16 +02:00
const isInModView = isModView ( location . pathname );
2026-01-07 16:03:02 +01:00
const isInModQueueView = isModQueueView ( location . pathname );
2024-04-12 17:47:30 +02:00
2025-03-06 16:27:09 +01:00
const { filteredCount , searchText } = useCatalogFiltersStore ();
2024-09-10 19:16:13 +02:00
2025-11-12 14:54:50 +01:00
// Check if we should show the vote button (only for directory boards)
const defaultSubplebbits = useDefaultSubplebbits ();
const boardIdentifier = params . boardIdentifier || params . subplebbitAddress ;
const showVoteButton = boardIdentifier && isDirectoryBoard ( boardIdentifier , defaultSubplebbits );
2024-03-22 12:09:17 +01:00
return (
2024-06-01 18:13:41 +02:00
<>
2024-03-22 13:03:04 +01:00
< hr />
2024-06-01 18:13:41 +02:00
< div className = { styles . desktopBoardButtons }>
{ isInPostView || isInPendingPostPage ? (
<>
[
2025-12-29 16:18:59 +01:00
< ReturnButton address = { subplebbitAddress } isInAllView = { isInAllView } isInSubscriptionsView = { isInSubscriptionsView } isInModView = { isInModView } />] [
2025-06-04 16:36:16 +02:00
< CatalogButton address = { subplebbitAddress } isInAllView = { isInAllView } isInSubscriptionsView = { isInSubscriptionsView } isInModView = { isInModView } />] [
2025-12-29 16:18:59 +01:00
< UpdateButton />] [
2024-09-08 10:41:08 +02:00
< AutoButton />]
2024-08-29 14:18:20 +02:00
< span className = { styles . rightSideButtons }>
< PostPageStats />
</ span >
2024-06-01 18:13:41 +02:00
</>
2026-01-07 16:03:02 +01:00
) : isInModQueueView ? (
<>
[
< ReturnButton
address = { subplebbitAddress }
isInAllView = { isInAllView }
isInSubscriptionsView = { isInSubscriptionsView }
isInModView = { isInModView }
isInModQueueView = { isInModQueueView }
/>
] [
< RefreshButton />]
</>
2024-06-01 18:13:41 +02:00
) : (
<>
{ isInCatalogView ? (
<>
[
2025-06-04 16:36:16 +02:00
< ReturnButton address = { subplebbitAddress } isInAllView = { isInAllView } isInSubscriptionsView = { isInSubscriptionsView } isInModView = { isInModView } />]{ ' ' }
2024-06-01 18:13:41 +02:00
</>
) : (
<>
2025-06-04 16:36:16 +02:00
< SearchOPsBar />
2024-06-01 18:13:41 +02:00
[
2025-06-04 16:36:16 +02:00
< CatalogButton address = { subplebbitAddress } isInAllView = { isInAllView } isInSubscriptionsView = { isInSubscriptionsView } isInModView = { isInModView } />]{ ' ' }
2024-05-31 18:18:42 +02:00
</>
)}
2024-06-03 19:46:30 +02:00
[< RefreshButton />]
2025-11-12 14:54:50 +01:00
{ showVoteButton && (
<>
{ ' ' }
[< VoteButton />]
</>
)}
2026-01-08 16:43:14 +01:00
{ ! ( isInAllView || isInSubscriptionsView || isInModView ) && (
<>
{ ' ' }
[< ModQueueButton boardIdentifier = { boardIdentifier } isMobile = { false } />]
</>
)}
2025-03-06 16:27:09 +01:00
{ isInCatalogView && searchText ? (
2024-09-10 19:16:13 +02:00
< span className = { styles . filteredThreadsCount }>
{ ' ' }
2025-03-06 16:27:09 +01:00
— { t ( 'search_results_for' )} : < strong >{ searchText }</ strong >
2024-09-10 19:16:13 +02:00
</ span >
2025-03-06 16:27:09 +01:00
) : (
isInCatalogView &&
filteredCount > 0 && (
< span className = { styles . filteredThreadsCount }>
{ ' ' }
— { t ( 'filtered_threads' )} : < strong >{ filteredCount }</ strong >
</ span >
)
2024-09-10 19:16:13 +02:00
)}
2024-06-01 18:13:41 +02:00
< span className = { styles . rightSideButtons }>
2024-06-17 21:16:31 +02:00
{ isInCatalogView && (
<>
< SortOptions />
< ImageSizeOptions />
< ShowOPCommentOption />
</>
)}
2025-12-29 16:18:59 +01:00
{ isInAllView && < AllFeedFilter />}
2025-06-04 16:36:16 +02:00
{( isInAllView || isInSubscriptionsView || isInModView ) && (
< TimeFilter isInAllView = { isInAllView } isInCatalogView = { isInCatalogView } isInSubscriptionsView = { isInSubscriptionsView } isInModView = { isInModView } />
2024-06-14 21:56:23 +02:00
)}
2025-06-04 16:36:16 +02:00
{ ! ( isInAllView || isInSubscriptionsView || isInModView ) && (
2024-06-01 18:13:41 +02:00
<>
[
< SubscribeButton address = { subplebbitAddress } />]
</>
2025-03-06 15:44:26 +01:00
)}{ ' ' }
{ isInCatalogView && (
<>
[< CatalogFilters />] < CatalogSearch />
</>
2024-06-01 18:13:41 +02:00
)}
</ span >
</>
)}
</ div >
</>
2024-03-22 12:09:17 +01:00
);
};
2025-06-04 16:36:16 +02:00
const SearchOPsBar = () => {
const { t } = useTranslation ();
const navigate = useNavigate ();
const params = useParams ();
const location = useLocation ();
const isInAllView = isAllView ( location . pathname );
const isInSubscriptionsView = isSubscriptionsView ( location . pathname , useParams ());
const isInModView = isModView ( location . pathname );
2025-11-07 12:50:58 +01:00
const defaultSubplebbits = useDefaultSubplebbits ();
const resolvedAddress = useResolvedSubplebbitAddress ();
const boardPath = resolvedAddress ? getBoardPath ( resolvedAddress , defaultSubplebbits ) : params ? . boardIdentifier || params ? . subplebbitAddress ;
2025-06-04 16:36:16 +02:00
const handleSearch = ( event : React.KeyboardEvent < HTMLInputElement >) => {
if ( event . key === 'Enter' ) {
const searchQuery = ( event . target as HTMLInputElement ). value . trim ();
if ( searchQuery ) {
let catalogUrl = '' ;
if ( isInAllView ) {
catalogUrl = params ? . timeFilterName
2025-11-07 12:50:58 +01:00
? `/all/catalog/ ${ params . timeFilterName } ?q= ${ encodeURIComponent ( searchQuery ) } `
: `/all/catalog?q= ${ encodeURIComponent ( searchQuery ) } ` ;
2025-06-04 16:36:16 +02:00
} else if ( isInSubscriptionsView ) {
catalogUrl = params ? . timeFilterName
2025-11-12 16:35:38 +01:00
? `/subs/catalog/ ${ params . timeFilterName } ?q= ${ encodeURIComponent ( searchQuery ) } `
: `/subs/catalog?q= ${ encodeURIComponent ( searchQuery ) } ` ;
2025-06-04 16:36:16 +02:00
} else if ( isInModView ) {
catalogUrl = params ? . timeFilterName
2025-11-07 12:50:58 +01:00
? `/mod/catalog/ ${ params . timeFilterName } ?q= ${ encodeURIComponent ( searchQuery ) } `
: `/mod/catalog?q= ${ encodeURIComponent ( searchQuery ) } ` ;
2025-06-04 16:36:16 +02:00
} else {
2025-11-07 12:50:58 +01:00
catalogUrl = `/ ${ boardPath } /catalog?q= ${ encodeURIComponent ( searchQuery ) } ` ;
2025-06-04 16:36:16 +02:00
}
navigate ( catalogUrl );
}
}
};
return < input type = 'text' placeholder = { t ( 'search_ops_placeholder' , 'Search OPs...' )} onKeyDown = { handleSearch } className = { styles . searchOPsInput } />;
};