mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
use zustand memoization for catalog filters, it fixes the useFeed bug with performance
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
import { create } from 'zustand';
|
import { create } from 'zustand';
|
||||||
import { persist } from 'zustand/middleware';
|
import { persist } from 'zustand/middleware';
|
||||||
|
import { Comment } from '@plebbit/plebbit-react-hooks';
|
||||||
|
import { getCommentMediaInfo, getHasThumbnail } from '../lib/utils/media-utils';
|
||||||
|
|
||||||
interface FilterItem {
|
interface FilterItem {
|
||||||
text: string;
|
text: string;
|
||||||
@@ -16,15 +18,21 @@ interface CatalogFiltersStore {
|
|||||||
filterText: string;
|
filterText: string;
|
||||||
setFilterText: (value: string) => void;
|
setFilterText: (value: string) => void;
|
||||||
filterItems: FilterItem[];
|
filterItems: FilterItem[];
|
||||||
setFilterItems: (items: FilterItem[]) => void; // New method to set all filter items at once
|
setFilterItems: (items: FilterItem[]) => void;
|
||||||
saveAndApplyFilters: (items: FilterItem[]) => void; // Updated to accept items
|
saveAndApplyFilters: (items: FilterItem[]) => void;
|
||||||
|
filter: ((comment: Comment) => boolean) | undefined;
|
||||||
|
updateFilter: () => void;
|
||||||
|
initializeFilter: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const useCatalogFiltersStore = create(
|
const useCatalogFiltersStore = create(
|
||||||
persist<CatalogFiltersStore>(
|
persist<CatalogFiltersStore>(
|
||||||
(set) => ({
|
(set, get) => ({
|
||||||
showTextOnlyThreads: false,
|
showTextOnlyThreads: false,
|
||||||
setShowTextOnlyThreads: (value: boolean) => set({ showTextOnlyThreads: value }),
|
setShowTextOnlyThreads: (value: boolean) => {
|
||||||
|
set({ showTextOnlyThreads: value });
|
||||||
|
get().updateFilter();
|
||||||
|
},
|
||||||
showAdultBoards: false,
|
showAdultBoards: false,
|
||||||
setShowAdultBoards: (value: boolean) => set({ showAdultBoards: value }),
|
setShowAdultBoards: (value: boolean) => set({ showAdultBoards: value }),
|
||||||
showGoreBoards: false,
|
showGoreBoards: false,
|
||||||
@@ -39,12 +47,44 @@ const useCatalogFiltersStore = create(
|
|||||||
saveAndApplyFilters: (items: FilterItem[]) => {
|
saveAndApplyFilters: (items: FilterItem[]) => {
|
||||||
const nonEmptyItems = items.filter((item) => item.text.trim() !== '');
|
const nonEmptyItems = items.filter((item) => item.text.trim() !== '');
|
||||||
set({ filterItems: nonEmptyItems });
|
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',
|
name: 'catalog-filters-storage',
|
||||||
|
onRehydrateStorage: () => (state) => {
|
||||||
|
if (state) {
|
||||||
|
state.updateFilter();
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useCatalogFiltersStore.getState().updateFilter();
|
||||||
|
|
||||||
export default useCatalogFiltersStore;
|
export default useCatalogFiltersStore;
|
||||||
|
|||||||
@@ -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 { useLocation, useParams } from 'react-router-dom';
|
||||||
import { useTranslation } from 'react-i18next';
|
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 { Virtuoso, VirtuosoHandle, StateSnapshot } from 'react-virtuoso';
|
||||||
import { getCommentMediaInfo, getHasThumbnail } from '../../lib/utils/media-utils';
|
|
||||||
import { isAllView, isSubscriptionsView } from '../../lib/utils/view-utils';
|
import { isAllView, isSubscriptionsView } from '../../lib/utils/view-utils';
|
||||||
import useCatalogFeedRows from '../../hooks/use-catalog-feed-rows';
|
import useCatalogFeedRows from '../../hooks/use-catalog-feed-rows';
|
||||||
import useDefaultSubplebbits from '../../hooks/use-default-subplebbits';
|
import useDefaultSubplebbits from '../../hooks/use-default-subplebbits';
|
||||||
@@ -28,7 +27,7 @@ const Catalog = () => {
|
|||||||
|
|
||||||
const isInAllView = isAllView(location.pathname, useParams());
|
const isInAllView = isAllView(location.pathname, useParams());
|
||||||
const defaultSubplebbits = useDefaultSubplebbits();
|
const defaultSubplebbits = useDefaultSubplebbits();
|
||||||
const { showAdultBoards, showGoreBoards } = useCatalogFiltersStore();
|
const { filter, showAdultBoards, showGoreBoards } = useCatalogFiltersStore();
|
||||||
|
|
||||||
const account = useAccount();
|
const account = useAccount();
|
||||||
const subscriptions = account?.subscriptions;
|
const subscriptions = account?.subscriptions;
|
||||||
@@ -57,27 +56,6 @@ const Catalog = () => {
|
|||||||
return [subplebbitAddress];
|
return [subplebbitAddress];
|
||||||
}, [isInAllView, isInSubscriptionsView, subplebbitAddress, defaultSubplebbits, subscriptions, showAdultBoards, showGoreBoards]);
|
}, [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 { imageSize } = useCatalogStyleStore();
|
||||||
const columnWidth = imageSize === 'Large' ? 270 : 180;
|
const columnWidth = imageSize === 'Large' ? 270 : 180;
|
||||||
|
|
||||||
@@ -87,16 +65,20 @@ const Catalog = () => {
|
|||||||
const { timeFilterSeconds } = useTimeFilter();
|
const { timeFilterSeconds } = useTimeFilter();
|
||||||
const { sortType } = useSortingStore();
|
const { sortType } = useSortingStore();
|
||||||
|
|
||||||
const feedOptions: any = {
|
const feedOptions = useMemo(() => {
|
||||||
subplebbitAddresses,
|
const options: any = {
|
||||||
sortType,
|
subplebbitAddresses,
|
||||||
postsPerPage: isInAllView || isInSubscriptionsView ? 10 : postsPerPage,
|
sortType,
|
||||||
filter,
|
postsPerPage: isInAllView || isInSubscriptionsView ? 10 : postsPerPage,
|
||||||
};
|
filter,
|
||||||
|
};
|
||||||
|
|
||||||
if (isInAllView || isInSubscriptionsView) {
|
if (isInAllView || isInSubscriptionsView) {
|
||||||
feedOptions.newerThan = timeFilterSeconds;
|
options.newerThan = timeFilterSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}, [subplebbitAddresses, sortType, isInAllView, isInSubscriptionsView, postsPerPage, timeFilterSeconds, filter]);
|
||||||
|
|
||||||
const { feed, hasMore, loadMore, reset } = useFeed(feedOptions);
|
const { feed, hasMore, loadMore, reset } = useFeed(feedOptions);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user