feat(boards list): add filter by tag

This commit is contained in:
Tom (plebeius.eth)
2025-02-03 22:12:00 +01:00
parent cf849bab70
commit 0716aac9e2
7 changed files with 64 additions and 23 deletions
+34 -17
View File
@@ -1,19 +1,19 @@
import { Link } from 'react-router-dom';
import { Link, useLocation } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js';
import { Subplebbit } from '@plebbit/plebbit-react-hooks';
import { useDefaultSubplebbitTags } from '../../../hooks/use-default-subplebbits-tags';
import useIsSubplebbitOffline from '../../../hooks/use-is-subplebbit-offline';
import styles from '../home.module.css';
import { nsfwTags } from '../home';
import { useState } from 'react';
import { useState, useEffect } from 'react';
const Board = ({ subplebbit, subplebbits }: { subplebbit: Subplebbit; subplebbits: any; useCatalog?: boolean }) => {
const Board = ({ subplebbit }: { subplebbit: Subplebbit; useCatalog?: boolean }) => {
const { t } = useTranslation();
const { address, title, tags } = subplebbit || {};
const nsfwTag = tags.find((tag: string) => nsfwTags.includes(tag));
const nsfwTag = tags?.find((tag: string) => nsfwTags.includes(tag));
const subplebbitData = subplebbits && subplebbits.find((sub: Subplebbit) => sub?.address === address);
const { isOffline, isOnlineStatusLoading, offlineIconClass, offlineTitle } = useIsSubplebbitOffline(subplebbitData);
const { isOffline, isOnlineStatusLoading, offlineIconClass, offlineTitle } = useIsSubplebbitOffline(subplebbit);
const displayAddress = address === 'all' ? 'all' : Plebbit.getShortAddress(address);
const showOfflineIcon = address !== 'all' && (isOffline || isOnlineStatusLoading);
@@ -31,28 +31,41 @@ const Board = ({ subplebbit, subplebbits }: { subplebbit: Subplebbit; subplebbit
<p className={styles.boardCell}>{title || displayAddress}</p>
</td>
<td className={styles.boardTags}>
<p className={styles.boardCell}>{tags.join(', ')}</p>
<p className={styles.boardCell}>
{tags.map((tag: string, index: number) => (
<>
{tag === 'multiboard' ? <span>{tag}</span> : <Link to={`/${tag}`}>{tag}</Link>}
{index < tags.length - 1 && ', '}
</>
))}
</p>
</td>
</tr>
);
};
const BoardsList = ({ multisub, subplebbits }: { multisub: Subplebbit[]; subplebbits: any }) => {
const BoardsList = ({ multisub }: { multisub: Subplebbit[] }) => {
const { t } = useTranslation();
const location = useLocation();
const [displayCount, setDisplayCount] = useState(15);
const handleLoadMore = () => {
setDisplayCount((prevCount) => prevCount + 15);
};
const currentTag = location.pathname.split('/').filter(Boolean)[0];
const tags = useDefaultSubplebbitTags(multisub);
useEffect(() => {
setDisplayCount(15);
}, [currentTag]);
// First filter by tag, then limit by displayCount
const filteredBoards = (currentTag && tags.includes(currentTag) ? multisub.filter((sub) => sub?.tags?.includes(currentTag)) : multisub).slice(0, displayCount);
const visibleBoards = multisub.slice(0, displayCount);
const hasMoreBoards = displayCount < multisub.length;
const defaultBoard = {
address: 'all',
title: 'Temporary Default Subplebbits',
tags: ['multiboard'],
};
} as Subplebbit;
return (
<div className={styles.boardsBox}>
@@ -69,15 +82,19 @@ const BoardsList = ({ multisub, subplebbits }: { multisub: Subplebbit[]; subpleb
</tr>
</thead>
<tbody>
<Board key='all' subplebbit={defaultBoard} subplebbits={subplebbits} />
{visibleBoards.map((sub) => (
<Board key={sub.address} subplebbit={sub} subplebbits={subplebbits} />
{!currentTag && <Board key='all' subplebbit={defaultBoard} />}
{filteredBoards.map((sub) => (
<Board key={sub.address} subplebbit={sub} />
))}
</tbody>
</table>
<div className={styles.displayCount}>
displaying {filteredBoards.length} of {multisub.length} boards
{currentTag && tags.includes(currentTag) && ` tagged "${currentTag}"`}
</div>
{hasMoreBoards && (
<div className={styles.loadMoreButton}>
[<span onClick={handleLoadMore}>{t('load_more')}</span>]
[<span onClick={() => setDisplayCount((prevCount) => prevCount + 15)}>{t('load_more')}</span>]
</div>
)}
</div>