diff --git a/src/stores/use-catalog-filters-store.ts b/src/stores/use-catalog-filters-store.ts index 543f7478..1ed9c862 100644 --- a/src/stores/use-catalog-filters-store.ts +++ b/src/stores/use-catalog-filters-store.ts @@ -1,5 +1,7 @@ import { create } from 'zustand'; import { persist } from 'zustand/middleware'; +import { Comment } from '@plebbit/plebbit-react-hooks'; +import { getCommentMediaInfo, getHasThumbnail } from '../lib/utils/media-utils'; interface FilterItem { text: string; @@ -16,15 +18,21 @@ interface CatalogFiltersStore { filterText: string; setFilterText: (value: string) => void; filterItems: FilterItem[]; - setFilterItems: (items: FilterItem[]) => void; // New method to set all filter items at once - saveAndApplyFilters: (items: FilterItem[]) => void; // Updated to accept items + setFilterItems: (items: FilterItem[]) => void; + saveAndApplyFilters: (items: FilterItem[]) => void; + filter: ((comment: Comment) => boolean) | undefined; + updateFilter: () => void; + initializeFilter: () => void; } const useCatalogFiltersStore = create( persist( - (set) => ({ + (set, get) => ({ showTextOnlyThreads: false, - setShowTextOnlyThreads: (value: boolean) => set({ showTextOnlyThreads: value }), + setShowTextOnlyThreads: (value: boolean) => { + set({ showTextOnlyThreads: value }); + get().updateFilter(); + }, showAdultBoards: false, setShowAdultBoards: (value: boolean) => set({ showAdultBoards: value }), showGoreBoards: false, @@ -39,12 +47,44 @@ const useCatalogFiltersStore = create( saveAndApplyFilters: (items: FilterItem[]) => { const nonEmptyItems = items.filter((item) => item.text.trim() !== ''); set({ filterItems: nonEmptyItems }); + get().updateFilter(); + }, + filter: undefined, + updateFilter: () => + set((state) => ({ + filter: (comment: Comment) => { + const { showTextOnlyThreads, filterItems } = state; + if (!showTextOnlyThreads && !getHasThumbnail(getCommentMediaInfo(comment), comment?.link)) { + return false; + } + + const title = comment?.title?.toLowerCase() || ''; + const content = comment?.content?.toLowerCase() || ''; + + return !filterItems + .filter((item) => item.enabled) + .some((item) => { + const text = item.text.toLowerCase(); + return title.includes(text) || content.includes(text); + }); + }, + })), + initializeFilter: () => { + const { updateFilter } = get(); + updateFilter(); }, }), { name: 'catalog-filters-storage', + onRehydrateStorage: () => (state) => { + if (state) { + state.updateFilter(); + } + }, }, ), ); +useCatalogFiltersStore.getState().updateFilter(); + export default useCatalogFiltersStore; diff --git a/src/views/catalog/catalog.tsx b/src/views/catalog/catalog.tsx index 280064fb..5afc8eaa 100644 --- a/src/views/catalog/catalog.tsx +++ b/src/views/catalog/catalog.tsx @@ -1,9 +1,8 @@ -import { useEffect, useMemo, useRef, useCallback } from 'react'; +import { useEffect, useMemo, useRef } from 'react'; import { useLocation, useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; -import { Comment, useAccount, useFeed, useSubplebbit, useBlock } from '@plebbit/plebbit-react-hooks'; +import { useAccount, useFeed, useSubplebbit, useBlock } from '@plebbit/plebbit-react-hooks'; import { Virtuoso, VirtuosoHandle, StateSnapshot } from 'react-virtuoso'; -import { getCommentMediaInfo, getHasThumbnail } from '../../lib/utils/media-utils'; import { isAllView, isSubscriptionsView } from '../../lib/utils/view-utils'; import useCatalogFeedRows from '../../hooks/use-catalog-feed-rows'; import useDefaultSubplebbits from '../../hooks/use-default-subplebbits'; @@ -28,7 +27,7 @@ const Catalog = () => { const isInAllView = isAllView(location.pathname, useParams()); const defaultSubplebbits = useDefaultSubplebbits(); - const { showAdultBoards, showGoreBoards } = useCatalogFiltersStore(); + const { filter, showAdultBoards, showGoreBoards } = useCatalogFiltersStore(); const account = useAccount(); const subscriptions = account?.subscriptions; @@ -57,27 +56,6 @@ const Catalog = () => { return [subplebbitAddress]; }, [isInAllView, isInSubscriptionsView, subplebbitAddress, defaultSubplebbits, subscriptions, showAdultBoards, showGoreBoards]); - const { showTextOnlyThreads, filterItems } = useCatalogFiltersStore(); - - const filter = useCallback( - (comment: Comment) => { - if (!showTextOnlyThreads && !getHasThumbnail(getCommentMediaInfo(comment), comment?.link)) { - return false; - } - - const title = comment?.title?.toLowerCase() || ''; - const content = comment?.content?.toLowerCase() || ''; - - return !filterItems - .filter((item) => item.enabled) - .some((item) => { - const text = item.text.toLowerCase(); - return title.includes(text) || content.includes(text); - }); - }, - [filterItems, showTextOnlyThreads], - ); - const { imageSize } = useCatalogStyleStore(); const columnWidth = imageSize === 'Large' ? 270 : 180; @@ -87,16 +65,20 @@ const Catalog = () => { const { timeFilterSeconds } = useTimeFilter(); const { sortType } = useSortingStore(); - const feedOptions: any = { - subplebbitAddresses, - sortType, - postsPerPage: isInAllView || isInSubscriptionsView ? 10 : postsPerPage, - filter, - }; + const feedOptions = useMemo(() => { + const options: any = { + subplebbitAddresses, + sortType, + postsPerPage: isInAllView || isInSubscriptionsView ? 10 : postsPerPage, + filter, + }; - if (isInAllView || isInSubscriptionsView) { - feedOptions.newerThan = timeFilterSeconds; - } + if (isInAllView || isInSubscriptionsView) { + options.newerThan = timeFilterSeconds; + } + + return options; + }, [subplebbitAddresses, sortType, isInAllView, isInSubscriptionsView, postsPerPage, timeFilterSeconds, filter]); const { feed, hasMore, loadMore, reset } = useFeed(feedOptions);