Merge branch 'codex/fix/catalog-search-empty-state'

This commit is contained in:
Tommaso Casaburi
2026-05-19 15:38:52 +07:00
43 changed files with 229 additions and 110 deletions
+27 -29
View File
@@ -523,7 +523,6 @@ export const MobileBoardButtons = () => {
const resolvedAddress = useResolvedCommunityAddress();
const communityAddress = resolvedAddress || accountComment?.communityAddress;
const { filteredCount, searchText } = useCatalogFiltersStore();
const enableInfiniteScroll = useFeedViewSettingsStore((state) => state.enableInfiniteScroll);
const isMultiboard = isInAllView || isInSubscriptionsView || isInModView;
const showTimeFilter = isMultiboard;
@@ -574,19 +573,7 @@ export const MobileBoardButtons = () => {
isInModView={isInModView}
isMobilePlacement={true}
/>
{searchText ? (
<span className={styles.filteredThreadsCount}>
{' '}
- {t('search_results_for')}: <strong>{searchText}</strong>
</span>
) : (
filteredCount > 0 && (
<span className={styles.filteredThreadsCount}>
{' '}
- {t('filtered_threads')}: <strong>{filteredCount}</strong>
</span>
)
)}
<CatalogSearchResultsLabel />
{(isInAllView || showTimeFilter || isInCatalogView) && (
<>
<hr />
@@ -683,6 +670,31 @@ export const PostPageStats = () => {
);
};
export const CatalogSearchResultsLabel = () => {
const { t } = useTranslation();
const { filteredCount, searchText } = useCatalogFiltersStore();
if (searchText) {
return (
<span className={styles.filteredThreadsCount}>
{' '}
{t('search_results_for')}: <strong>{searchText}</strong>
</span>
);
}
if (filteredCount > 0) {
return (
<span className={styles.filteredThreadsCount}>
{' '}
{t('filtered_threads')}: <strong>{filteredCount}</strong>
</span>
);
}
return null;
};
export const DesktopBoardButtons = () => {
const { t } = useTranslation();
const params = useParams();
@@ -698,7 +710,6 @@ export const DesktopBoardButtons = () => {
const isInModView = isModView(location.pathname);
const isInModQueueView = isModQueueView(location.pathname);
const { filteredCount, searchText } = useCatalogFiltersStore();
const enableInfiniteScroll = useFeedViewSettingsStore((state) => state.enableInfiniteScroll);
const isMultiboard = isInAllView || isInSubscriptionsView || isInModView;
const showTimeFilter = isMultiboard;
@@ -794,20 +805,7 @@ export const DesktopBoardButtons = () => {
<ModQueueButton boardIdentifier={boardIdentifier} isMobile={false} />
</>
)}
{isInCatalogView && searchText ? (
<span className={styles.filteredThreadsCount}>
{' '}
- {t('search_results_for')}: <strong>{searchText}</strong>
</span>
) : (
isInCatalogView &&
filteredCount > 0 && (
<span className={styles.filteredThreadsCount}>
{' '}
- {t('filtered_threads')}: <strong>{filteredCount}</strong>
</span>
)
)}
{isInCatalogView && <CatalogSearchResultsLabel />}
<span className={styles.rightSideButtons}>
{isInCatalogView && (
<>
@@ -5,6 +5,7 @@ import { MemoryRouter } from 'react-router-dom';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import {
CatalogFooterFirstRow,
CatalogFooterStyleRow,
PageFooterDesktop,
PageFooterMobile,
StyleOnlyFooterFirstRow,
@@ -51,6 +52,7 @@ vi.mock('../../style-selector/style-selector', () => ({
}));
vi.mock('../../board-buttons/board-buttons', () => ({
CatalogSearchResultsLabel: () => null,
AutoButton: () => createElement('button', { type: 'button' }, 'auto-button'),
CatalogButton: ({
address,
@@ -154,6 +156,7 @@ describe('footer', () => {
isInAllView: true,
communityAddress: 'music-posting.eth',
}),
createElement(CatalogFooterStyleRow),
createElement(ThreadFooterStyleRow),
createElement(PageFooterMobile, {
children: createElement('div', { 'data-testid': 'mobile-child' }, 'mobile-child'),
+4 -1
View File
@@ -4,6 +4,10 @@
padding-bottom: 24px;
}
.footerCatalog {
margin-top: 0;
}
.firstRow {
display: flex;
align-items: center;
@@ -76,7 +80,6 @@
}
.styleLabel {
font-size: 12px;
text-transform: capitalize;
}
+33 -11
View File
@@ -4,7 +4,16 @@ import { useComment } from '@bitsocial/bitsocial-react-hooks';
import BoardsBar from '../boards-bar';
import SiteLegalMeta from '../site-legal-meta';
import StyleSelector from '../style-selector/style-selector';
import { ReturnButton, CatalogButton, TopButton, UpdateButton, AutoButton, PostPageStats, RefreshButton } from '../board-buttons/board-buttons';
import {
CatalogSearchResultsLabel,
ReturnButton,
CatalogButton,
TopButton,
UpdateButton,
AutoButton,
PostPageStats,
RefreshButton,
} from '../board-buttons/board-buttons';
import { isAllView, isSubscriptionsView, isModView } from '../../lib/utils/view-utils';
import useReplyModalStore from '../../stores/use-reply-modal-store';
import useThreadLiveUpdatesStore from '../../stores/use-thread-live-updates-store';
@@ -22,15 +31,17 @@ import styles from './footer.module.css';
interface PageFooterDesktopProps {
/** Mode-specific first row content (e.g. board pagination or thread controls) */
firstRow: React.ReactNode;
firstRow?: React.ReactNode;
/** Optional row between first row and BoardsBar (e.g. style selector on thread page) */
styleRow?: React.ReactNode;
/** Catalog pages omit the default footer top margin */
variant?: 'catalog';
}
export const PageFooterDesktop = ({ firstRow, styleRow }: PageFooterDesktopProps) => (
<footer className={styles.footer}>
export const PageFooterDesktop = ({ firstRow, styleRow, variant }: PageFooterDesktopProps) => (
<footer className={variant === 'catalog' ? `${styles.footer} ${styles.footerCatalog}` : styles.footer}>
<hr />
<div className={styles.firstRow}>{firstRow}</div>
{firstRow != null ? <div className={styles.firstRow}>{firstRow}</div> : null}
{styleRow != null ? <div className={styles.styleRow}>{styleRow}</div> : null}
<div className={styles.boardsBarRow}>
<BoardsBar />
@@ -60,7 +71,7 @@ export const StyleOnlyFooterFirstRow = () => {
/* -----------------------------------------------------------------------------
* CatalogFooterFirstRow
* Catalog footer first row: Return, Archive, Top, Refresh on left; Style selector on right.
* Catalog footer nav row: Return, Catalog, Top, Refresh, plus search/filter label.
* -------------------------------------------------------------------------- */
interface CatalogFooterFirstRowProps {
@@ -71,7 +82,6 @@ interface CatalogFooterFirstRowProps {
}
export const CatalogFooterFirstRow = ({ communityAddress, isInAllView = false, isInSubscriptionsView = false, isInModView = false }: CatalogFooterFirstRowProps) => {
const { t } = useTranslation();
return (
<div className={styles.footerRow}>
<div className={styles.footerLeft}>
@@ -87,15 +97,27 @@ export const CatalogFooterFirstRow = ({ communityAddress, isInAllView = false, i
<span>
[<RefreshButton />]
</span>
</div>
<div className={styles.footerRight}>
<span className={styles.styleLabel}>{t('style')}:</span>
<StyleSelector />
<CatalogSearchResultsLabel />
</div>
</div>
);
};
/* -----------------------------------------------------------------------------
* CatalogFooterStyleRow
* Catalog style selector on its own row (below nav, above BoardsBar).
* -------------------------------------------------------------------------- */
export const CatalogFooterStyleRow = () => {
const { t } = useTranslation();
return (
<span className={styles.styleRowContent}>
<span className={styles.styleLabel}>{t('style')}:</span>
<StyleSelector />
</span>
);
};
/* -----------------------------------------------------------------------------
* ThreadFooterStyleRow
* Style selector on its own row (thread page only, below first row, above BoardsBar).
+1
View File
@@ -3,6 +3,7 @@ export {
PageFooterMobile,
StyleOnlyFooterFirstRow,
CatalogFooterFirstRow,
CatalogFooterStyleRow,
ThreadFooterFirstRow,
ThreadFooterStyleRow,
ThreadFooterMobile,