mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
fix(board-buttons): hide catalog controls on flash upload boards
Flash boards do not use catalog view, so hide catalog links and OP search without leaving empty bracket placeholders in desktop board controls.
This commit is contained in:
@@ -3,7 +3,7 @@ import { createElement } from 'react';
|
||||
import { createRoot, type Root } from 'react-dom/client';
|
||||
import { MemoryRouter, Route, Routes } from 'react-router-dom';
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { DesktopBoardButtons, MobileBoardButtons } from '../board-buttons';
|
||||
import { DesktopBoardButtons, BracketedCatalogButton, MobileBoardButtons } from '../board-buttons';
|
||||
import useThreadLiveUpdatesStore from '../../../stores/use-thread-live-updates-store';
|
||||
import useHiddenCatalogThreadsStore from '../../../stores/use-hidden-catalog-threads-store';
|
||||
import { clearStableLastVisitTimeFilterName, LAST_VISIT_STORAGE_KEY } from '../../../lib/utils/time-filter-utils';
|
||||
@@ -13,6 +13,7 @@ const act = (React as { act?: (cb: () => void | Promise<void>) => void | Promise
|
||||
|
||||
type DirectoryEntry = {
|
||||
address: string;
|
||||
directoryCode?: string;
|
||||
features?: { requirePostLinkIsMedia?: boolean };
|
||||
name?: string;
|
||||
publicKey?: string;
|
||||
@@ -120,7 +121,7 @@ vi.mock('../../../hooks/use-post-page-number', () => ({
|
||||
|
||||
vi.mock('../../../hooks/use-directories', () => ({
|
||||
findDirectoryByAddress: (directories: DirectoryEntry[], address?: string) =>
|
||||
directories.find((entry) => address && [entry.address, entry.name, entry.publicKey].includes(address)),
|
||||
directories.find((entry) => address && [entry.address, entry.name, entry.publicKey, entry.directoryCode].includes(address)),
|
||||
useDirectories: () => testState.directories,
|
||||
useDirectoryByAddress: (address: string | undefined) => testState.directories.find((entry) => entry.address === address),
|
||||
}));
|
||||
@@ -360,6 +361,28 @@ describe('BoardButtons', () => {
|
||||
expect(container.textContent).not.toContain('directory');
|
||||
});
|
||||
|
||||
it('does not render catalog or OP search controls on flash upload boards', async () => {
|
||||
testState.directories = [
|
||||
{ address: 'music-posting.eth', features: {}, name: 'music-posting.eth', publicKey: 'music-public-key', title: '/mu/ - Music' },
|
||||
{ address: 'flash-posting.bso', directoryCode: 'f', title: '/f/ - Flash' },
|
||||
];
|
||||
testState.resolvedCommunityAddress = 'flash-posting.bso';
|
||||
|
||||
await renderWithRoute(createElement(DesktopBoardButtons), '/f');
|
||||
|
||||
expect(findButtonLink('catalog')).toBeUndefined();
|
||||
expect(container.querySelector('input[type="text"]')).toBeNull();
|
||||
expect(container.textContent).not.toMatch(/\[\s*\]/);
|
||||
});
|
||||
|
||||
it('does not render bracketed catalog controls on flash upload boards', async () => {
|
||||
testState.directories = [{ address: 'flash-posting.bso', directoryCode: 'f', title: '/f/ - Flash' }];
|
||||
|
||||
await renderWithRoute(createElement(BracketedCatalogButton, { address: 'flash-posting.bso' }), '/f');
|
||||
|
||||
expect(container.textContent?.trim()).toBe('');
|
||||
});
|
||||
|
||||
it('renders desktop catalog controls and wires sort, style, filter, and refresh updates', async () => {
|
||||
testState.filteredCount = 4;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { usePostPageNumber } from '../../hooks/use-post-page-number';
|
||||
import { useDirectories, useDirectoryByAddress } from '../../hooks/use-directories';
|
||||
import { useAccountCommunityAddresses } from '../../hooks/use-account-community-addresses';
|
||||
import { useFilteredDirectoryAddresses } from '../../hooks/use-filtered-directory-addresses';
|
||||
import { getBoardPath, isDirectoryRoute } from '../../lib/utils/route-utils';
|
||||
import { getBoardPath, isDirectoryRoute, isFlashBoardRoute } from '../../lib/utils/route-utils';
|
||||
import { useResolvedCommunityAddress } from '../../hooks/use-resolved-community-address';
|
||||
import { useCommunityIdentifier } from '../../hooks/use-community-identifiers';
|
||||
import useSafeAccountComment from '../../hooks/use-safe-account-comment';
|
||||
@@ -45,6 +45,17 @@ interface BoardButtonsProps {
|
||||
|
||||
const EMPTY_COMMUNITY_ADDRESSES: string[] = [];
|
||||
|
||||
export const shouldShowCatalogButton = (
|
||||
boardIdentifier: string | undefined,
|
||||
directories: ReturnType<typeof useDirectories>,
|
||||
{ isInAllView, isInSubscriptionsView, isInModView }: Pick<BoardButtonsProps, 'isInAllView' | 'isInSubscriptionsView' | 'isInModView'>,
|
||||
): boolean => {
|
||||
if (isInAllView || isInSubscriptionsView || isInModView) {
|
||||
return true;
|
||||
}
|
||||
return !isFlashBoardRoute(boardIdentifier, directories);
|
||||
};
|
||||
|
||||
const getMultiboardPath = ({
|
||||
isInAllView,
|
||||
isInCatalogView,
|
||||
@@ -67,9 +78,14 @@ const getMultiboardPath = ({
|
||||
export const CatalogButton = ({ address, isInAllView, isInSubscriptionsView, isInModView }: BoardButtonsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const location = useLocation();
|
||||
const params = useParams();
|
||||
const directories = useDirectories();
|
||||
const { timeFilterValue } = useTimeFilter();
|
||||
|
||||
if (!shouldShowCatalogButton(params.boardIdentifier, directories, { isInAllView, isInSubscriptionsView, isInModView })) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const createCatalogLink = () => {
|
||||
const multiboardPath = getMultiboardPath({ isInAllView, isInCatalogView: true, isInSubscriptionsView, isInModView });
|
||||
if (multiboardPath) {
|
||||
@@ -94,6 +110,20 @@ export const CatalogButton = ({ address, isInAllView, isInSubscriptionsView, isI
|
||||
);
|
||||
};
|
||||
|
||||
export const BracketedCatalogButton = ({ address, isInAllView, isInSubscriptionsView, isInModView }: BoardButtonsProps) => {
|
||||
const params = useParams();
|
||||
const directories = useDirectories();
|
||||
if (!shouldShowCatalogButton(params.boardIdentifier, directories, { isInAllView, isInSubscriptionsView, isInModView })) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<span>
|
||||
[<CatalogButton address={address} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />]
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export const ArchiveButton = ({ address, isInAllView, isInSubscriptionsView, isInModView }: BoardButtonsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
@@ -526,13 +556,16 @@ export const MobileBoardButtons = () => {
|
||||
const directories = useDirectories();
|
||||
const boardIdentifier = params.boardIdentifier;
|
||||
const showDirectoryButton = boardIdentifier && isDirectoryRoute(boardIdentifier, directories);
|
||||
const showCatalogButton = shouldShowCatalogButton(boardIdentifier, directories, { isInAllView, isInSubscriptionsView, isInModView });
|
||||
|
||||
return (
|
||||
<div className={`${styles.mobileBoardButtons} ${!isInCatalogView ? styles.addMargin : ''}`}>
|
||||
{isInPostView || isInPendingPostPage ? (
|
||||
<>
|
||||
<ReturnButton address={communityAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />
|
||||
<CatalogButton address={communityAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />
|
||||
{showCatalogButton && (
|
||||
<CatalogButton address={communityAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />
|
||||
)}
|
||||
{showBottomButton && <BottomButton />}
|
||||
<div className={styles.secondRow}>
|
||||
<UpdateButton />
|
||||
@@ -592,7 +625,9 @@ export const MobileBoardButtons = () => {
|
||||
) : (
|
||||
<>
|
||||
{showBottomButton && <BottomButton />}
|
||||
<CatalogButton address={communityAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />
|
||||
{showCatalogButton && (
|
||||
<CatalogButton address={communityAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />
|
||||
)}
|
||||
<RefreshButton />
|
||||
<div className={styles.secondRow}>
|
||||
{showDirectoryButton && <DirectoryButton />}
|
||||
@@ -711,6 +746,7 @@ export const DesktopBoardButtons = () => {
|
||||
const directories = useDirectories();
|
||||
const boardIdentifier = params.boardIdentifier;
|
||||
const showDirectoryButton = boardIdentifier && isDirectoryRoute(boardIdentifier, directories);
|
||||
const showCatalogButton = shouldShowCatalogButton(boardIdentifier, directories, { isInAllView, isInSubscriptionsView, isInModView });
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -718,8 +754,13 @@ export const DesktopBoardButtons = () => {
|
||||
<div className={styles.desktopBoardButtons}>
|
||||
{isInPostView || isInPendingPostPage ? (
|
||||
<>
|
||||
[<ReturnButton address={communityAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />] [
|
||||
<CatalogButton address={communityAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />]
|
||||
[<ReturnButton address={communityAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />]
|
||||
{showCatalogButton && (
|
||||
<>
|
||||
{' '}
|
||||
[<CatalogButton address={communityAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />]
|
||||
</>
|
||||
)}
|
||||
{showBottomButton && (
|
||||
<>
|
||||
{' '}
|
||||
@@ -762,7 +803,12 @@ export const DesktopBoardButtons = () => {
|
||||
) : (
|
||||
<>
|
||||
<SearchOPsBar />
|
||||
[<CatalogButton address={communityAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />]
|
||||
{showCatalogButton && (
|
||||
<>
|
||||
{' '}
|
||||
[<CatalogButton address={communityAddress} isInAllView={isInAllView} isInSubscriptionsView={isInSubscriptionsView} isInModView={isInModView} />]
|
||||
</>
|
||||
)}
|
||||
{!(isInAllView || isInSubscriptionsView || isInModView) && (
|
||||
<>
|
||||
{' '}
|
||||
@@ -845,6 +891,10 @@ const SearchOPsBar = () => {
|
||||
const resolvedAddress = useResolvedCommunityAddress();
|
||||
const boardPath = resolvedAddress ? getBoardPath(resolvedAddress, directories) : params?.boardIdentifier || params?.communityAddress;
|
||||
|
||||
if (!shouldShowCatalogButton(params.boardIdentifier, directories, { isInAllView, isInSubscriptionsView, isInModView })) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const handleSearch = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
if (event.key === 'Enter') {
|
||||
const searchQuery = (event.target as HTMLInputElement).value.trim();
|
||||
|
||||
Reference in New Issue
Block a user