feat(board): add search bar to board page, redirect to catalog view

This commit is contained in:
Tom (plebeius.eth)
2025-06-04 16:36:16 +02:00
parent 20c601ac18
commit 53e04823df
2 changed files with 90 additions and 16 deletions
@@ -88,6 +88,27 @@
margin-bottom: 15px; margin-bottom: 15px;
} }
.searchOPsInput {
height: 16px;
line-height: 16px;
margin-left: 2px;
padding: 0 2px;
width: 120px;
margin: 0px;
margin-right: 4px;
padding: 0 2px;
border: var(--post-form-field-input-border, revert);
background-color: var(--post-form-field-input-background-color, revert);
color: var(--post-form-field-input-color);
outline: none;
font-family: arial, helvetica, sans-serif;
font-size: 10pt;
}
.searchOPsInput:focus {
border: var(--post-form-field-input-focus-border, revert);
}
@media (max-width: 640px) { @media (max-width: 640px) {
.desktopBoardButtons { .desktopBoardButtons {
display: none; display: none;
+69 -16
View File
@@ -3,7 +3,7 @@ import { Link, useLocation, useNavigate, useParams } from 'react-router-dom';
import { useAccountComment, useSubscribe } from '@plebbit/plebbit-react-hooks'; import { useAccountComment, useSubscribe } from '@plebbit/plebbit-react-hooks';
import useSubplebbitsStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits'; import useSubplebbitsStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits';
import useSubplebbitsPagesStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits-pages'; import useSubplebbitsPagesStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits-pages';
import { isAllView, isCatalogView, isDescriptionView, isPendingPostView, isPostPageView, isSubscriptionsView } from '../../lib/utils/view-utils'; import { isAllView, isCatalogView, isDescriptionView, isModView, isPendingPostView, isPostPageView, isSubscriptionsView } from '../../lib/utils/view-utils';
import useCatalogFiltersStore from '../../stores/use-catalog-filters-store'; import useCatalogFiltersStore from '../../stores/use-catalog-filters-store';
import useCatalogStyleStore from '../../stores/use-catalog-style-store'; import useCatalogStyleStore from '../../stores/use-catalog-style-store';
import useFeedResetStore from '../../stores/use-feed-reset-store'; import useFeedResetStore from '../../stores/use-feed-reset-store';
@@ -22,10 +22,11 @@ interface BoardButtonsProps {
isInAllView?: boolean; isInAllView?: boolean;
isInCatalogView?: boolean; isInCatalogView?: boolean;
isInSubscriptionsView?: boolean; isInSubscriptionsView?: boolean;
isInModView?: boolean;
isTopbar?: boolean; isTopbar?: boolean;
} }
const CatalogButton = ({ address, isInAllView, isInSubscriptionsView }: BoardButtonsProps) => { const CatalogButton = ({ address, isInAllView, isInSubscriptionsView, isInModView }: BoardButtonsProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const params = useParams(); const params = useParams();
@@ -36,6 +37,9 @@ const CatalogButton = ({ address, isInAllView, isInSubscriptionsView }: BoardBut
} else if (isInSubscriptionsView) { } else if (isInSubscriptionsView) {
if (params?.timeFilterName) return `/p/subscriptions/catalog/${params.timeFilterName}`; if (params?.timeFilterName) return `/p/subscriptions/catalog/${params.timeFilterName}`;
return `/p/subscriptions/catalog`; return `/p/subscriptions/catalog`;
} else if (isInModView) {
if (params?.timeFilterName) return `/p/mod/catalog/${params.timeFilterName}`;
return `/p/mod/catalog`;
} }
return `/p/${address}/catalog`; return `/p/${address}/catalog`;
}; };
@@ -58,7 +62,7 @@ const SubscribeButton = ({ address }: BoardButtonsProps) => {
); );
}; };
const ReturnButton = ({ address, isInAllView, isInSubscriptionsView }: BoardButtonsProps) => { const ReturnButton = ({ address, isInAllView, isInSubscriptionsView, isInModView }: BoardButtonsProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const params = useParams(); const params = useParams();
@@ -69,6 +73,9 @@ const ReturnButton = ({ address, isInAllView, isInSubscriptionsView }: BoardButt
} else if (isInSubscriptionsView) { } else if (isInSubscriptionsView) {
if (params?.timeFilterName) return `/p/subscriptions/${params.timeFilterName}`; if (params?.timeFilterName) return `/p/subscriptions/${params.timeFilterName}`;
return `/p/subscriptions`; return `/p/subscriptions`;
} else if (isInModView) {
if (params?.timeFilterName) return `/p/mod/${params.timeFilterName}`;
return `/p/mod`;
} }
return `/p/${address}`; return `/p/${address}`;
}; };
@@ -190,7 +197,7 @@ const ShowOPCommentOption = () => {
); );
}; };
export const TimeFilter = ({ isInAllView, isInCatalogView, isInSubscriptionsView, isTopbar = false }: BoardButtonsProps) => { export const TimeFilter = ({ isInAllView, isInCatalogView, isInSubscriptionsView, isInModView, isTopbar = false }: BoardButtonsProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const navigate = useNavigate(); const navigate = useNavigate();
const { timeFilterName, timeFilterNames } = useTimeFilter(); const { timeFilterName, timeFilterNames } = useTimeFilter();
@@ -205,6 +212,10 @@ export const TimeFilter = ({ isInAllView, isInCatalogView, isInSubscriptionsView
? isInCatalogView ? isInCatalogView
? `/p/subscriptions/catalog/${timeFilterName}` ? `/p/subscriptions/catalog/${timeFilterName}`
: `/p/subscriptions/${timeFilterName}` : `/p/subscriptions/${timeFilterName}`
: isInModView
? isInCatalogView
? `/p/mod/catalog/${timeFilterName}`
: `/p/mod/${timeFilterName}`
: null; : null;
link && navigate(link); link && navigate(link);
}; };
@@ -242,6 +253,7 @@ export const MobileBoardButtons = () => {
const isInPendingPostPage = isPendingPostView(location.pathname, params); const isInPendingPostPage = isPendingPostView(location.pathname, params);
const isInPostView = isPostPageView(location.pathname, params); const isInPostView = isPostPageView(location.pathname, params);
const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams());
const isInModView = isModView(location.pathname);
const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any }); const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any });
const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress; const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress;
@@ -252,8 +264,8 @@ export const MobileBoardButtons = () => {
<div className={`${styles.mobileBoardButtons} ${!isInCatalogView ? styles.addMargin : ''}`}> <div className={`${styles.mobileBoardButtons} ${!isInCatalogView ? styles.addMargin : ''}`}>
{isInPostView || isInPendingPostPage ? ( {isInPostView || isInPendingPostPage ? (
<> <>
<ReturnButton address={subplebbitAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} /> <ReturnButton address={subplebbitAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />
<CatalogButton address={subplebbitAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} /> <CatalogButton address={subplebbitAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />
<SubscribeButton address={subplebbitAddress} /> <SubscribeButton address={subplebbitAddress} />
<div className={styles.secondRow}> <div className={styles.secondRow}>
<UpdateButton /> <UpdateButton />
@@ -263,11 +275,11 @@ export const MobileBoardButtons = () => {
) : ( ) : (
<> <>
{isInCatalogView ? ( {isInCatalogView ? (
<ReturnButton address={subplebbitAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} /> <ReturnButton address={subplebbitAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />
) : ( ) : (
<CatalogButton address={subplebbitAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} /> <CatalogButton address={subplebbitAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />
)} )}
{!(isInAllView || isInSubscriptionsView) && <SubscribeButton address={subplebbitAddress} />} {!(isInAllView || isInSubscriptionsView || isInModView) && <SubscribeButton address={subplebbitAddress} />}
<RefreshButton /> <RefreshButton />
{isInCatalogView && searchText ? ( {isInCatalogView && searchText ? (
<span className={styles.filteredThreadsCount}> <span className={styles.filteredThreadsCount}>
@@ -338,6 +350,7 @@ export const DesktopBoardButtons = () => {
const isInPendingPostPage = isPendingPostView(location.pathname, params); const isInPendingPostPage = isPendingPostView(location.pathname, params);
const isInPostView = isPostPageView(location.pathname, params); const isInPostView = isPostPageView(location.pathname, params);
const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams());
const isInModView = isModView(location.pathname);
const { filteredCount, searchText } = useCatalogFiltersStore(); const { filteredCount, searchText } = useCatalogFiltersStore();
@@ -348,9 +361,9 @@ export const DesktopBoardButtons = () => {
{isInPostView || isInPendingPostPage ? ( {isInPostView || isInPendingPostPage ? (
<> <>
[ [
<ReturnButton address={subplebbitAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} /> <ReturnButton address={subplebbitAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />
] [ ] [
<CatalogButton address={subplebbitAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} />] [ <CatalogButton address={subplebbitAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />] [
<UpdateButton /> <UpdateButton />
] [ ] [
<AutoButton />] <AutoButton />]
@@ -363,12 +376,13 @@ export const DesktopBoardButtons = () => {
{isInCatalogView ? ( {isInCatalogView ? (
<> <>
[ [
<ReturnButton address={subplebbitAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} />]{' '} <ReturnButton address={subplebbitAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />]{' '}
</> </>
) : ( ) : (
<> <>
<SearchOPsBar />
[ [
<CatalogButton address={subplebbitAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} />]{' '} <CatalogButton address={subplebbitAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />]{' '}
</> </>
)} )}
[<RefreshButton />] [<RefreshButton />]
@@ -394,10 +408,10 @@ export const DesktopBoardButtons = () => {
<ShowOPCommentOption /> <ShowOPCommentOption />
</> </>
)} )}
{(isInAllView || isInSubscriptionsView) && ( {(isInAllView || isInSubscriptionsView || isInModView) && (
<TimeFilter isInAllView={isInAllView} isInCatalogView={isInCatalogView} isInSubscriptionsView={isInSubscriptionsView} /> <TimeFilter isInAllView={isInAllView} isInCatalogView={isInCatalogView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />
)} )}
{!(isInAllView || isInSubscriptionsView) && ( {!(isInAllView || isInSubscriptionsView || isInModView) && (
<> <>
[ [
<SubscribeButton address={subplebbitAddress} />] <SubscribeButton address={subplebbitAddress} />]
@@ -415,3 +429,42 @@ export const DesktopBoardButtons = () => {
</> </>
); );
}; };
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);
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
? `/p/all/catalog/${params.timeFilterName}?q=${encodeURIComponent(searchQuery)}`
: `/p/all/catalog?q=${encodeURIComponent(searchQuery)}`;
} else if (isInSubscriptionsView) {
catalogUrl = params?.timeFilterName
? `/p/subscriptions/catalog/${params.timeFilterName}?q=${encodeURIComponent(searchQuery)}`
: `/p/subscriptions/catalog?q=${encodeURIComponent(searchQuery)}`;
} else if (isInModView) {
catalogUrl = params?.timeFilterName
? `/p/mod/catalog/${params.timeFilterName}?q=${encodeURIComponent(searchQuery)}`
: `/p/mod/catalog?q=${encodeURIComponent(searchQuery)}`;
} else {
catalogUrl = `/p/${params?.subplebbitAddress}/catalog?q=${encodeURIComponent(searchQuery)}`;
}
navigate(catalogUrl);
}
}
};
return <input type='text' placeholder={t('search_ops_placeholder', 'Search OPs...')} onKeyDown={handleSearch} className={styles.searchOPsInput} />;
};