From 82de50b88a025eabb5b4f05491ddabe5b469ef56 Mon Sep 17 00:00:00 2001 From: "Tom (plebeius.eth)" Date: Mon, 3 Jun 2024 17:55:29 +0200 Subject: [PATCH] refactor home component --- src/hooks/use-popular-posts.ts | 2 +- src/stores/use-home-filters.ts | 44 ++ src/views/home/boards-box/boards-box.tsx | 296 +++++++++++++ src/views/home/boards-box/index.ts | 1 + src/views/home/box-modal/box-modal.tsx | 138 ++++++ src/views/home/box-modal/index.ts | 1 + src/views/home/home.tsx | 415 +----------------- src/views/home/popular-threads-box/index.ts | 1 + .../popular-threads-box.tsx | 82 ++++ 9 files changed, 573 insertions(+), 407 deletions(-) create mode 100644 src/stores/use-home-filters.ts create mode 100644 src/views/home/boards-box/boards-box.tsx create mode 100644 src/views/home/boards-box/index.ts create mode 100644 src/views/home/box-modal/box-modal.tsx create mode 100644 src/views/home/box-modal/index.ts create mode 100644 src/views/home/popular-threads-box/index.ts create mode 100644 src/views/home/popular-threads-box/popular-threads-box.tsx diff --git a/src/hooks/use-popular-posts.ts b/src/hooks/use-popular-posts.ts index 65360890..e40c3810 100644 --- a/src/hooks/use-popular-posts.ts +++ b/src/hooks/use-popular-posts.ts @@ -29,7 +29,7 @@ const usePopularPosts = (subplebbits: Subplebbit[]) => { if ( isMediaShowed && - (replyCount > 0 || postsPerSub > 1) && + replyCount > 0 && !deleted && !removed && !locked && diff --git a/src/stores/use-home-filters.ts b/src/stores/use-home-filters.ts new file mode 100644 index 00000000..86884b7a --- /dev/null +++ b/src/stores/use-home-filters.ts @@ -0,0 +1,44 @@ +import { create } from 'zustand'; + +interface HomeFiltersStore { + showNsfwBoardsOnly: boolean; + setShowNsfwBoardsOnly: (value: boolean) => void; + showWorksafeBoardsOnly: boolean; + setShowWorksafeBoardsOnly: (value: boolean) => void; + useCatalog: boolean; + setUseCatalog: (value: boolean) => void; + showWorksafeContentOnly: boolean; + setShowWorksafeContentOnly: (value: boolean) => void; + showNsfwContentOnly: boolean; + setShowNsfwContentOnly: (value: boolean) => void; +} + +const useHomeFiltersStore = create((set) => ({ + showNsfwBoardsOnly: localStorage.getItem('showNsfwBoardsOnly') === 'true' ? true : false, + setShowNsfwBoardsOnly: (value: boolean) => { + set({ showNsfwBoardsOnly: value }); + localStorage.setItem('showNsfwBoardsOnly', value.toString()); + }, + showWorksafeBoardsOnly: localStorage.getItem('showWorksafeBoardsOnly') === 'true' ? true : false, + setShowWorksafeBoardsOnly: (value: boolean) => { + set({ showWorksafeBoardsOnly: value }); + localStorage.setItem('showWorksafeBoardsOnly', value.toString()); + }, + useCatalog: localStorage.getItem('useCatalog') === 'true' ? true : false, + setUseCatalog: (value: boolean) => { + set({ useCatalog: value }); + localStorage.setItem('useCatalog', value.toString()); + }, + showWorksafeContentOnly: localStorage.getItem('showWorksafeContentOnly') === 'true' ? true : false, + setShowWorksafeContentOnly: (value: boolean) => { + set({ showWorksafeContentOnly: value }); + localStorage.setItem('showWorksafeContentOnly', value.toString()); + }, + showNsfwContentOnly: localStorage.getItem('showNsfwContentOnly') === 'true' ? true : false, + setShowNsfwContentOnly: (value: boolean) => { + set({ showNsfwContentOnly: value }); + localStorage.setItem('showNsfwContentOnly', value.toString()); + }, +})); + +export default useHomeFiltersStore; diff --git a/src/views/home/boards-box/boards-box.tsx b/src/views/home/boards-box/boards-box.tsx new file mode 100644 index 00000000..01dc0f1b --- /dev/null +++ b/src/views/home/boards-box/boards-box.tsx @@ -0,0 +1,296 @@ +import { useCallback, useEffect, useRef, useState } from 'react'; +import { Link } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; +import { Subplebbit, useAccount, useAccountSubplebbits } from '@plebbit/plebbit-react-hooks'; +import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js'; +import useHomeFiltersStore from '../../../stores/use-home-filters'; +import { useMultisubMetadata } from '../../../hooks/use-default-subplebbits'; +import styles from '../home.module.css'; +import { nsfwTags } from '../home'; + +const BoxModal = ({ isBoardsBoxModal }: { isBoardsBoxModal: boolean }) => { + const { t } = useTranslation(); + const [showFilterModal, setShowFilterModal] = useState(false); + const modalRef = useRef(null); + + const { + showNsfwBoardsOnly, + setShowNsfwBoardsOnly, + showWorksafeBoardsOnly, + setShowWorksafeBoardsOnly, + useCatalog, + setUseCatalog, + showWorksafeContentOnly, + setShowWorksafeContentOnly, + showNsfwContentOnly, + setShowNsfwContentOnly, + } = useHomeFiltersStore(); + + const handleClickOutside = useCallback( + (event: MouseEvent) => { + if (modalRef.current && !modalRef.current.contains(event.target as Node)) { + setShowFilterModal(false); + } + }, + [modalRef, setShowFilterModal], + ); + + useEffect(() => { + document.addEventListener('mousedown', handleClickOutside); + return () => { + document.removeEventListener('mousedown', handleClickOutside); + }; + }, [handleClickOutside]); + + return ( + <> + setShowFilterModal(true)}> + {isBoardsBoxModal ? t('filter') : t('options')} ▼ + + {showFilterModal && ( +
+ {isBoardsBoxModal ? ( + <> +
{ + setShowNsfwBoardsOnly(false); + setShowWorksafeBoardsOnly(false); + setShowFilterModal(false); + }} + > + Show All Boards +
+
{ + if (showWorksafeBoardsOnly) { + setShowWorksafeBoardsOnly(false); + } + setShowNsfwBoardsOnly(!showNsfwBoardsOnly); + setShowFilterModal(false); + }} + > + Show NSFW Boards Only +
+
{ + if (showNsfwBoardsOnly) { + setShowNsfwBoardsOnly(false); + } + setShowWorksafeBoardsOnly(!showWorksafeBoardsOnly); + setShowFilterModal(false); + }} + > + Show Worksafe Boards Only +
+
+
{ + setUseCatalog(!useCatalog); + setShowFilterModal(false); + }} + > + Use Catalog +
+ + ) : ( + <> +
{ + if (showNsfwContentOnly) { + setShowNsfwContentOnly(false); + } + setShowWorksafeContentOnly(!showWorksafeContentOnly); + setShowFilterModal(false); + }} + > + Show Worksafe Content Only +
+
{ + if (showWorksafeContentOnly) { + setShowWorksafeContentOnly(false); + } + setShowNsfwContentOnly(!showNsfwContentOnly); + setShowFilterModal(false); + }} + > + Show NSFW Content Only +
+
{ + setShowWorksafeContentOnly(false); + setShowNsfwContentOnly(false); + setShowFilterModal(false); + }} + > + Show All Content +
+ + )} +
+ )} + + ); +}; + +const Board = ({ isOffline, subplebbit }: { isOffline: boolean; subplebbit: Subplebbit }) => { + const { t } = useTranslation(); + const { address, title, tags } = subplebbit || {}; + const nsfwTag = tags.find((tag: string) => nsfwTags.includes(tag)); + const { useCatalog } = useHomeFiltersStore(); + + const boardLink = useCatalog ? `/p/${address}/catalog` : `/p/${address}`; + + return ( +
+ {isOffline && } + {title || address} + {nsfwTag && ({t(nsfwTag)})} +
+ ); +}; + +const BoardsBox = ({ multisub, subplebbits }: { multisub: Subplebbit[]; subplebbits: any }) => { + const { t } = useTranslation(); + const account = useAccount(); + const subscriptions = account?.subscriptions || []; + const { accountSubplebbits } = useAccountSubplebbits(); + const accountSubplebbitAddresses = Object.keys(accountSubplebbits); + const { showNsfwBoardsOnly, showWorksafeBoardsOnly } = useHomeFiltersStore(); + + const filterSubs = (subs: Subplebbit[], includeTags: string[], excludeTags: string[] = []) => + subs.filter((sub) => includeTags.every((tag) => sub.tags?.includes(tag)) && excludeTags.every((tag) => !sub.tags?.includes(tag))); + + let plebbitSubs = filterSubs(multisub, ['plebbit']); + let interestsSubs = filterSubs(multisub, ['topic'], ['plebbit', 'country', 'international']); + let randomSubs = filterSubs(multisub, ['random'], ['plebbit']); + let internationalSubs = filterSubs(multisub, ['international']); + let projectsSubs = filterSubs(multisub, ['project'], ['plebbit', 'topic']); + + const filterByNsfw = (subs: Subplebbit[], includeNsfw: boolean) => subs.filter((sub) => sub.tags.some((tag: string) => nsfwTags.includes(tag)) === includeNsfw); + + const filterCategoriesByNsfw = (subsArray: Subplebbit[][], includeNsfw: boolean) => subsArray.map((subs) => filterByNsfw(subs, includeNsfw)); + + const includeNsfw = showNsfwBoardsOnly ? true : showWorksafeBoardsOnly ? false : null; + + if (includeNsfw !== null) { + [plebbitSubs, interestsSubs, randomSubs, internationalSubs, projectsSubs] = filterCategoriesByNsfw( + [plebbitSubs, interestsSubs, randomSubs, internationalSubs, projectsSubs], + includeNsfw, + ); + } + + const isSubOffline = (address: string) => { + const subplebbit = subplebbits && subplebbits.find((sub: Subplebbit) => sub?.address === address); + const isOffline = subplebbit?.updatedAt && subplebbit.updatedAt < Date.now() / 1000 - 60 * 60; + return isOffline; + }; + const multisubMetadata = useMultisubMetadata(); + + return ( +
+
+

{t('boards')}

+ +
+
+
+

Multiboards

+
+
+ {multisubMetadata?.title || 'All'} +
+
+ Subscriptions +
+
+ {plebbitSubs.length > 0 && ( + <> +

Plebbit

+
+ {plebbitSubs.map((sub) => ( + + ))} +
+ + )} + {projectsSubs.length > 0 && ( + <> +

{t('projects')}

+
+ {projectsSubs.map((sub) => ( + + ))} +
+ + )} +
+
+ {interestsSubs.length > 0 && ( + <> +

{t('interests')}

+
+ {interestsSubs.map((sub) => ( + + ))} +
+ + )} +
+
+ {randomSubs.length > 0 && ( + <> +

{t('random')}

+
+ {randomSubs.map((sub) => ( + + ))} +
+ + )} + {internationalSubs.length > 0 && ( + <> +

{t('international')}

+
+ {internationalSubs.map((sub) => ( + + ))} +
+ + )} +
+
+
+

{t('subscriptions')}

+ {subscriptions.length > 0 + ? subscriptions.map((address: string, index: number) => ( +
+ p/{address && Plebbit.getShortAddress(address)} +
+ )) + : t('not_subscribed')} +
+
+

{t('moderating')}

+ {accountSubplebbitAddresses.length > 0 + ? accountSubplebbitAddresses.map((address: string, index: number) => ( +
+ p/{address && Plebbit.getShortAddress(address)} +
+ )) + : t('not_moderating')} +
+
+
+
+ ); +}; + +export default BoardsBox; diff --git a/src/views/home/boards-box/index.ts b/src/views/home/boards-box/index.ts new file mode 100644 index 00000000..4482f675 --- /dev/null +++ b/src/views/home/boards-box/index.ts @@ -0,0 +1 @@ +export { default } from './boards-box'; diff --git a/src/views/home/box-modal/box-modal.tsx b/src/views/home/box-modal/box-modal.tsx new file mode 100644 index 00000000..4a7c3490 --- /dev/null +++ b/src/views/home/box-modal/box-modal.tsx @@ -0,0 +1,138 @@ +import { useCallback, useEffect, useRef, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import useHomeFiltersStore from '../../../stores/use-home-filters'; +import styles from '../home.module.css'; + +const BoxModal = ({ isBoardsBoxModal }: { isBoardsBoxModal: boolean }) => { + const { t } = useTranslation(); + const [showFilterModal, setShowFilterModal] = useState(false); + const modalRef = useRef(null); + + const { + showNsfwBoardsOnly, + setShowNsfwBoardsOnly, + showWorksafeBoardsOnly, + setShowWorksafeBoardsOnly, + useCatalog, + setUseCatalog, + showWorksafeContentOnly, + setShowWorksafeContentOnly, + showNsfwContentOnly, + setShowNsfwContentOnly, + } = useHomeFiltersStore(); + + const handleClickOutside = useCallback( + (event: MouseEvent) => { + if (modalRef.current && !modalRef.current.contains(event.target as Node)) { + setShowFilterModal(false); + } + }, + [modalRef, setShowFilterModal], + ); + + useEffect(() => { + document.addEventListener('mousedown', handleClickOutside); + return () => { + document.removeEventListener('mousedown', handleClickOutside); + }; + }, [handleClickOutside]); + + return ( + <> + setShowFilterModal(true)}> + {isBoardsBoxModal ? t('filter') : t('options')} ▼ + + {showFilterModal && ( +
+ {isBoardsBoxModal ? ( + <> +
{ + setShowNsfwBoardsOnly(false); + setShowWorksafeBoardsOnly(false); + setShowFilterModal(false); + }} + > + Show All Boards +
+
{ + if (showWorksafeBoardsOnly) { + setShowWorksafeBoardsOnly(false); + } + setShowNsfwBoardsOnly(!showNsfwBoardsOnly); + setShowFilterModal(false); + }} + > + Show NSFW Boards Only +
+
{ + if (showNsfwBoardsOnly) { + setShowNsfwBoardsOnly(false); + } + setShowWorksafeBoardsOnly(!showWorksafeBoardsOnly); + setShowFilterModal(false); + }} + > + Show Worksafe Boards Only +
+
+
{ + setUseCatalog(!useCatalog); + setShowFilterModal(false); + }} + > + Use Catalog +
+ + ) : ( + <> +
{ + if (showNsfwContentOnly) { + setShowNsfwContentOnly(false); + } + setShowWorksafeContentOnly(!showWorksafeContentOnly); + setShowFilterModal(false); + }} + > + Show Worksafe Content Only +
+
{ + if (showWorksafeContentOnly) { + setShowWorksafeContentOnly(false); + } + setShowNsfwContentOnly(!showNsfwContentOnly); + setShowFilterModal(false); + }} + > + Show NSFW Content Only +
+
{ + setShowWorksafeContentOnly(false); + setShowNsfwContentOnly(false); + setShowFilterModal(false); + }} + > + Show All Content +
+ + )} +
+ )} + + ); +}; + +export default BoxModal; diff --git a/src/views/home/box-modal/index.ts b/src/views/home/box-modal/index.ts new file mode 100644 index 00000000..2c0fa188 --- /dev/null +++ b/src/views/home/box-modal/index.ts @@ -0,0 +1 @@ +export { default } from './box-modal'; diff --git a/src/views/home/home.tsx b/src/views/home/home.tsx index 388df874..84456ae4 100644 --- a/src/views/home/home.tsx +++ b/src/views/home/home.tsx @@ -1,58 +1,17 @@ -import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { useEffect, useMemo, useRef } from 'react'; import { Link, useNavigate } from 'react-router-dom'; import { Trans, useTranslation } from 'react-i18next'; -import { Comment, Subplebbit, useAccount, useAccountSubplebbits, useSubplebbits } from '@plebbit/plebbit-react-hooks'; -import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js'; -import { create } from 'zustand'; +import { useSubplebbits } from '@plebbit/plebbit-react-hooks'; import styles from './home.module.css'; import packageJson from '../../../package.json'; -import useDefaultSubplebbits, { useMultisubMetadata, useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits'; -import usePopularPosts from '../../hooks/use-popular-posts'; +import useDefaultSubplebbits, { useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits'; import useSubplebbitsStats from '../../hooks/use-subplebbits-stats'; -import { getCommentMediaInfo } from '../../lib/utils/media-utils'; -import { CatalogPostMedia } from '../../components/catalog-row'; import LoadingEllipsis from '../../components/loading-ellipsis'; +import PopularThreadsBox from './popular-threads-box'; +import BoardsBox from './boards-box'; -interface BoxModalStore { - showNsfwBoardsOnly: boolean; - setShowNsfwBoardsOnly: (value: boolean) => void; - showWorksafeBoardsOnly: boolean; - setShowWorksafeBoardsOnly: (value: boolean) => void; - useCatalog: boolean; - setUseCatalog: (value: boolean) => void; - showWorksafeContentOnly: boolean; - setShowWorksafeContentOnly: (value: boolean) => void; - showNsfwContentOnly: boolean; - setShowNsfwContentOnly: (value: boolean) => void; -} - -const useBoxModalStore = create((set) => ({ - showNsfwBoardsOnly: localStorage.getItem('showNsfwBoardsOnly') === 'true' ? true : false, - setShowNsfwBoardsOnly: (value: boolean) => { - set({ showNsfwBoardsOnly: value }); - localStorage.setItem('showNsfwBoardsOnly', value.toString()); - }, - showWorksafeBoardsOnly: localStorage.getItem('showWorksafeBoardsOnly') === 'true' ? true : false, - setShowWorksafeBoardsOnly: (value: boolean) => { - set({ showWorksafeBoardsOnly: value }); - localStorage.setItem('showWorksafeBoardsOnly', value.toString()); - }, - useCatalog: localStorage.getItem('useCatalog') === 'true' ? true : false, - setUseCatalog: (value: boolean) => { - set({ useCatalog: value }); - localStorage.setItem('useCatalog', value.toString()); - }, - showWorksafeContentOnly: localStorage.getItem('showWorksafeContentOnly') === 'true' ? true : false, - setShowWorksafeContentOnly: (value: boolean) => { - set({ showWorksafeContentOnly: value }); - localStorage.setItem('showWorksafeContentOnly', value.toString()); - }, - showNsfwContentOnly: localStorage.getItem('showNsfwContentOnly') === 'true' ? true : false, - setShowNsfwContentOnly: (value: boolean) => { - set({ showNsfwContentOnly: value }); - localStorage.setItem('showNsfwContentOnly', value.toString()); - }, -})); +// https://github.com/plebbit/temporary-default-subplebbits/blob/master/README.md +export const nsfwTags = ['adult', 'anti', 'gore']; const SearchBar = () => { const searchInputRef = useRef(null); @@ -101,362 +60,6 @@ const InfoBox = () => { ); }; -// https://github.com/plebbit/temporary-default-subplebbits/blob/master/README.md -const nsfwTags = ['adult', 'anti', 'gore']; - -const Board = ({ isOffline, subplebbit }: { isOffline: boolean; subplebbit: Subplebbit }) => { - const { t } = useTranslation(); - const { address, title, tags } = subplebbit || {}; - const nsfwTag = tags.find((tag: string) => nsfwTags.includes(tag)); - const { useCatalog } = useBoxModalStore(); - - const boardLink = useCatalog ? `/p/${address}/catalog` : `/p/${address}`; - - return ( -
- {isOffline && } - {title || address} - {nsfwTag && ({t(nsfwTag)})} -
- ); -}; - -const BoxModal = ({ isBoardsBoxModal }: { isBoardsBoxModal: boolean }) => { - const { t } = useTranslation(); - const [showFilterModal, setShowFilterModal] = useState(false); - const modalRef = useRef(null); - - const { - showNsfwBoardsOnly, - setShowNsfwBoardsOnly, - showWorksafeBoardsOnly, - setShowWorksafeBoardsOnly, - useCatalog, - setUseCatalog, - showWorksafeContentOnly, - setShowWorksafeContentOnly, - showNsfwContentOnly, - setShowNsfwContentOnly, - } = useBoxModalStore(); - - const handleClickOutside = useCallback( - (event: MouseEvent) => { - if (modalRef.current && !modalRef.current.contains(event.target as Node)) { - setShowFilterModal(false); - } - }, - [modalRef, setShowFilterModal], - ); - - useEffect(() => { - document.addEventListener('mousedown', handleClickOutside); - return () => { - document.removeEventListener('mousedown', handleClickOutside); - }; - }, [handleClickOutside]); - - return ( - <> - setShowFilterModal(true)}> - {isBoardsBoxModal ? t('filter') : t('options')} ▼ - - {showFilterModal && ( -
- {isBoardsBoxModal ? ( - <> -
{ - setShowNsfwBoardsOnly(false); - setShowWorksafeBoardsOnly(false); - setShowFilterModal(false); - }} - > - Show All Boards -
-
{ - if (showWorksafeBoardsOnly) { - setShowWorksafeBoardsOnly(false); - } - setShowNsfwBoardsOnly(!showNsfwBoardsOnly); - setShowFilterModal(false); - }} - > - Show NSFW Boards Only -
-
{ - if (showNsfwBoardsOnly) { - setShowNsfwBoardsOnly(false); - } - setShowWorksafeBoardsOnly(!showWorksafeBoardsOnly); - setShowFilterModal(false); - }} - > - Show Worksafe Boards Only -
-
-
{ - setUseCatalog(!useCatalog); - setShowFilterModal(false); - }} - > - Use Catalog -
- - ) : ( - <> -
{ - if (showNsfwContentOnly) { - setShowNsfwContentOnly(false); - } - setShowWorksafeContentOnly(!showWorksafeContentOnly); - setShowFilterModal(false); - }} - > - Show Worksafe Content Only -
-
{ - if (showWorksafeContentOnly) { - setShowWorksafeContentOnly(false); - } - setShowNsfwContentOnly(!showNsfwContentOnly); - setShowFilterModal(false); - }} - > - Show NSFW Content Only -
-
{ - setShowWorksafeContentOnly(false); - setShowNsfwContentOnly(false); - setShowFilterModal(false); - }} - > - Show All Content -
- - )} -
- )} - - ); -}; - -const Boards = ({ multisub, subplebbits }: { multisub: Subplebbit[]; subplebbits: any }) => { - const { t } = useTranslation(); - const account = useAccount(); - const subscriptions = account?.subscriptions || []; - const { accountSubplebbits } = useAccountSubplebbits(); - const accountSubplebbitAddresses = Object.keys(accountSubplebbits); - const { showNsfwBoardsOnly, showWorksafeBoardsOnly } = useBoxModalStore(); - - const filterSubs = (subs: Subplebbit[], includeTags: string[], excludeTags: string[] = []) => - subs.filter((sub) => includeTags.every((tag) => sub.tags?.includes(tag)) && excludeTags.every((tag) => !sub.tags?.includes(tag))); - - let plebbitSubs = filterSubs(multisub, ['plebbit']); - let interestsSubs = filterSubs(multisub, ['topic'], ['plebbit', 'country', 'international']); - let randomSubs = filterSubs(multisub, ['random'], ['plebbit']); - let internationalSubs = filterSubs(multisub, ['international']); - let projectsSubs = filterSubs(multisub, ['project'], ['plebbit', 'topic']); - - const filterByNsfw = (subs: Subplebbit[], includeNsfw: boolean) => subs.filter((sub) => sub.tags.some((tag: string) => nsfwTags.includes(tag)) === includeNsfw); - - const filterCategoriesByNsfw = (subsArray: Subplebbit[][], includeNsfw: boolean) => subsArray.map((subs) => filterByNsfw(subs, includeNsfw)); - - const includeNsfw = showNsfwBoardsOnly ? true : showWorksafeBoardsOnly ? false : null; - - if (includeNsfw !== null) { - [plebbitSubs, interestsSubs, randomSubs, internationalSubs, projectsSubs] = filterCategoriesByNsfw( - [plebbitSubs, interestsSubs, randomSubs, internationalSubs, projectsSubs], - includeNsfw, - ); - } - - const isSubOffline = (address: string) => { - const subplebbit = subplebbits && subplebbits.find((sub: Subplebbit) => sub?.address === address); - const isOffline = subplebbit?.updatedAt && subplebbit.updatedAt < Date.now() / 1000 - 60 * 60; - return isOffline; - }; - const multisubMetadata = useMultisubMetadata(); - - return ( -
-
-

{t('boards')}

- -
-
-
-

Multiboards

-
-
- {multisubMetadata?.title || 'All'} -
-
- Subscriptions -
-
- {plebbitSubs.length > 0 && ( - <> -

Plebbit

-
- {plebbitSubs.map((sub) => ( - - ))} -
- - )} - {projectsSubs.length > 0 && ( - <> -

{t('projects')}

-
- {projectsSubs.map((sub) => ( - - ))} -
- - )} -
-
- {interestsSubs.length > 0 && ( - <> -

{t('interests')}

-
- {interestsSubs.map((sub) => ( - - ))} -
- - )} -
-
- {randomSubs.length > 0 && ( - <> -

{t('random')}

-
- {randomSubs.map((sub) => ( - - ))} -
- - )} - {internationalSubs.length > 0 && ( - <> -

{t('international')}

-
- {internationalSubs.map((sub) => ( - - ))} -
- - )} -
-
-
-

{t('subscriptions')}

- {subscriptions.length > 0 - ? subscriptions.map((address: string, index: number) => ( -
- p/{address && Plebbit.getShortAddress(address)} -
- )) - : t('not_subscribed')} -
-
-

{t('moderating')}

- {accountSubplebbitAddresses.length > 0 - ? accountSubplebbitAddresses.map((address: string, index: number) => ( -
- p/{address && Plebbit.getShortAddress(address)} -
- )) - : t('not_moderating')} -
-
-
-
- ); -}; - -interface PopularThreadProps { - post: Comment; - boardTitle: string | undefined; - boardShortAddress: string; -} - -const PopularThreadCard = ({ post, boardTitle, boardShortAddress }: PopularThreadProps) => { - const { cid, content, subplebbitAddress, title } = post || {}; - const commentMediaInfo = getCommentMediaInfo(post); - - return ( -
-
{boardTitle || boardShortAddress}
-
- - - -
-
- {title && {title}} - {content && (content.length > 99 ? `: ${content.substring(0, 99)}...` : `: ${content}`)} -
-
- ); -}; - -const PopularThreads = ({ multisub, subplebbits }: { multisub: Subplebbit[]; subplebbits: any }) => { - const { t } = useTranslation(); - const { showWorksafeContentOnly, showNsfwContentOnly } = useBoxModalStore(); - - const getFilteredSubplebbits = () => { - if (showWorksafeContentOnly) { - return subplebbits.filter((sub: Subplebbit) => { - const multisubEntry = multisub.find((ms) => ms.address === sub.address); - return multisubEntry ? !multisubEntry.tags.some((tag: string) => nsfwTags.includes(tag)) : true; - }); - } - if (showNsfwContentOnly) { - return subplebbits.filter((sub: Subplebbit) => { - const multisubEntry = multisub.find((ms) => ms.address === sub.address); - return multisubEntry ? multisubEntry.tags.some((tag: string) => nsfwTags.includes(tag)) : false; - }); - } - return subplebbits; - }; - - const filteredSubplebbits = getFilteredSubplebbits(); - const popularPosts = usePopularPosts(filteredSubplebbits); - - return ( -
-
-

{t('popular_threads')}

- -
-
- {popularPosts.length < 8 ? ( - - ) : ( - popularPosts.map((post: any) => ( - - )) - )} -
-
- ); -}; - const Stats = ({ multisub, subplebbitAddresses }: { multisub: any; subplebbitAddresses: string[] }) => { const { t } = useTranslation(); const stats = useSubplebbitsStats({ subplebbitAddresses }); @@ -620,8 +223,8 @@ const Home = () => { - - + +
diff --git a/src/views/home/popular-threads-box/index.ts b/src/views/home/popular-threads-box/index.ts new file mode 100644 index 00000000..bae48ca6 --- /dev/null +++ b/src/views/home/popular-threads-box/index.ts @@ -0,0 +1 @@ +export { default } from './popular-threads-box'; diff --git a/src/views/home/popular-threads-box/popular-threads-box.tsx b/src/views/home/popular-threads-box/popular-threads-box.tsx new file mode 100644 index 00000000..a49d8c77 --- /dev/null +++ b/src/views/home/popular-threads-box/popular-threads-box.tsx @@ -0,0 +1,82 @@ +import { useMemo } from 'react'; +import { Link } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; +import { Comment, Subplebbit } from '@plebbit/plebbit-react-hooks'; +import styles from '../home.module.css'; +import usePopularPosts from '../../../hooks/use-popular-posts'; +import useHomeFiltersStore from '../../../stores/use-home-filters'; +import { getCommentMediaInfo } from '../../../lib/utils/media-utils'; +import { CatalogPostMedia } from '../../../components/catalog-row'; +import LoadingEllipsis from '../../../components/loading-ellipsis'; +import BoxModal from '../box-modal'; +import { nsfwTags } from '../home'; + +interface PopularThreadProps { + post: Comment; + boardTitle: string | undefined; + boardShortAddress: string; +} + +const PopularThreadCard = ({ post, boardTitle, boardShortAddress }: PopularThreadProps) => { + const { cid, content, subplebbitAddress, title } = post || {}; + const commentMediaInfo = getCommentMediaInfo(post); + + return ( +
+
{boardTitle || boardShortAddress}
+
+ + + +
+
+ {title && {title}} + {content && (content.length > 99 ? `: ${content.substring(0, 99)}...` : `: ${content}`)} +
+
+ ); +}; + +const PopularThreadsBox = ({ multisub, subplebbits }: { multisub: Subplebbit[]; subplebbits: any }) => { + const { t } = useTranslation(); + const { showWorksafeContentOnly, showNsfwContentOnly } = useHomeFiltersStore(); + + const getFilteredSubplebbits = () => { + if (showWorksafeContentOnly) { + return subplebbits.filter((sub: Subplebbit) => { + const multisubEntry = multisub.find((ms) => ms?.address === sub?.address); + return multisubEntry ? !multisubEntry.tags.some((tag: string) => nsfwTags.includes(tag)) : true; + }); + } + if (showNsfwContentOnly) { + return subplebbits.filter((sub: Subplebbit) => { + const multisubEntry = multisub.find((ms) => ms?.address === sub?.address); + return multisubEntry ? multisubEntry.tags.some((tag: string) => nsfwTags.includes(tag)) : false; + }); + } + return subplebbits; + }; + + const filteredSubplebbits = useMemo(getFilteredSubplebbits, [subplebbits, showWorksafeContentOnly, showNsfwContentOnly, multisub]); + const popularPosts = usePopularPosts(filteredSubplebbits); + + return ( +
+
+

{t('popular_threads')}

+ +
+
+ {popularPosts.length < 8 ? ( + + ) : ( + popularPosts.map((post: any) => ( + + )) + )} +
+
+ ); +}; + +export default PopularThreadsBox;