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>
+7 -1
View File
@@ -95,6 +95,12 @@
color: var(--topbar-separator-color);
}
.displayCount {
font-size: 12px;
text-align: center;
margin-bottom: 10px;
}
.loadMoreButton span {
color: var(--topbar-desktop-link-text-color);
text-transform: capitalize;
@@ -122,7 +128,7 @@
color: var(--homepage-box-bar-text-color);
}
.boxBar h2, .infoboxBar h2{
.boxBar h2, .infoboxBar h2 {
font-size: 131%;
font-weight: 700;
}
+1 -1
View File
@@ -214,7 +214,7 @@ const Home = () => {
<HomeLogo />
<SearchBar />
<InfoBox />
<BoardsList multisub={defaultSubplebbits} subplebbits={subplebbits} />
<BoardsList multisub={defaultSubplebbits} />
<PopularThreadsBox multisub={defaultSubplebbits} subplebbits={subplebbits} />
<Stats subplebbitAddresses={subplebbitAddresses} />
<Footer />
+1 -1
View File
@@ -1 +1 @@
export { HomeLogo, Footer, default } from './home';
export { HomeLogo, Footer, nsfwTags, default } from './home';