mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
feat(catalog): add reply-count sorting mode
This commit is contained in:
@@ -11,7 +11,6 @@ import { useFilteredDirectoryAddresses } from '../../hooks/use-filtered-director
|
||||
import { useResolvedSubplebbitAddress } from '../../hooks/use-resolved-subplebbit-address';
|
||||
import { useFeedStateString } from '../../hooks/use-state-string';
|
||||
import useFeedResetStore from '../../stores/use-feed-reset-store';
|
||||
import useSortingStore from '../../stores/use-sorting-store';
|
||||
import useFeedViewSettingsStore from '../../stores/use-feed-view-settings-store';
|
||||
import { useBoardFeedPageSize } from '../../hooks/use-board-feed-page-size';
|
||||
import { getPageSlice } from '../../lib/utils/board-feed-pagination';
|
||||
@@ -24,6 +23,9 @@ import { Post } from '../post';
|
||||
|
||||
const lastVirtuosoStates: { [key: string]: StateSnapshot } = {};
|
||||
|
||||
/** Board feed always uses 'active' sort; catalog dropdown does not affect board ordering. */
|
||||
const BOARD_SORT_TYPE = 'active' as const;
|
||||
|
||||
interface BoardFooterProps {
|
||||
subplebbitAddresses: string[];
|
||||
hasMore: boolean;
|
||||
@@ -145,8 +147,6 @@ const Board = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp, i
|
||||
return [subplebbitAddress];
|
||||
}, [isInAllView, isInSubscriptionsView, isInModView, subplebbitAddress, directoryAddresses, filteredDirectoryAddresses, subscriptions, accountSubplebbitAddresses]);
|
||||
|
||||
const { sortType } = useSortingStore();
|
||||
|
||||
const enableInfiniteScroll = useFeedViewSettingsStore((state) => state.enableInfiniteScroll);
|
||||
const isForcedInfiniteScroll = isInAllView || isInSubscriptionsView || isInModView;
|
||||
const effectiveInfiniteScroll = enableInfiniteScroll || isForcedInfiniteScroll;
|
||||
@@ -156,16 +156,16 @@ const Board = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp, i
|
||||
const feedOptions = useMemo(
|
||||
() => ({
|
||||
subplebbitAddresses,
|
||||
sortType,
|
||||
sortType: BOARD_SORT_TYPE,
|
||||
postsPerPage: effectiveInfiniteScroll ? infiniteFeedPostsPerPage : paginationFeedPostsPerPage,
|
||||
}),
|
||||
[subplebbitAddresses, sortType, effectiveInfiniteScroll, infiniteFeedPostsPerPage, paginationFeedPostsPerPage],
|
||||
[subplebbitAddresses, effectiveInfiniteScroll, infiniteFeedPostsPerPage, paginationFeedPostsPerPage],
|
||||
);
|
||||
|
||||
const { feed, hasMore, loadMore, reset, subplebbitAddressesWithNewerPosts } = useFeed(feedOptions);
|
||||
const { accountComments } = useAccountComments();
|
||||
|
||||
const feedContextKey = `${isInAllView ? 'all' : isInSubscriptionsView ? 'subs' : isInModView ? 'mod' : (subplebbitAddress ?? 'board')}-${sortType}-${viewType ?? 'board'}-${effectiveInfiniteScroll}`;
|
||||
const feedContextKey = `${isInAllView ? 'all' : isInSubscriptionsView ? 'subs' : isInModView ? 'mod' : (subplebbitAddress ?? 'board')}-${BOARD_SORT_TYPE}-${viewType ?? 'board'}-${effectiveInfiniteScroll}`;
|
||||
const pathWithoutSettings = location.pathname.replace(/\/settings$/, '');
|
||||
const currentPage = getPageFromFeedPath(pathWithoutSettings);
|
||||
const paginationBasePath = stripPageFromFeedPath(pathWithoutSettings);
|
||||
@@ -310,7 +310,7 @@ const Board = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp, i
|
||||
);
|
||||
|
||||
const virtuosoRef = useRef<VirtuosoHandle | null>(null);
|
||||
const virtuosoStateKey = feedCacheKey ? `${feedCacheKey}-${sortType}` : `${location.pathname}-${sortType}`;
|
||||
const virtuosoStateKey = feedCacheKey ? `${feedCacheKey}-${BOARD_SORT_TYPE}` : `${location.pathname}-${BOARD_SORT_TYPE}`;
|
||||
const navigationType = useNavigationType();
|
||||
|
||||
const hasBeenVisibleRef = useRef(false);
|
||||
|
||||
@@ -23,6 +23,7 @@ import ErrorDisplay from '../../components/error-display/error-display';
|
||||
import PageFooterDesktop from '../../components/page-footer-desktop';
|
||||
import styles from './catalog.module.css';
|
||||
import { commentMatchesPattern } from '../../lib/utils/pattern-utils';
|
||||
import { sortCatalogFeedForDisplay } from '../../lib/utils/catalog-sort';
|
||||
|
||||
const lastVirtuosoStates: { [key: string]: StateSnapshot } = {};
|
||||
|
||||
@@ -267,6 +268,7 @@ const Catalog = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp,
|
||||
}, [isInAllView, isInSubscriptionsView, isInModView, location.pathname, navigate]);
|
||||
|
||||
const { sortType } = useSortingStore();
|
||||
const feedSortType = sortType === 'new' ? 'new' : 'active';
|
||||
|
||||
// Create a stable callback for filter matching
|
||||
const handleFilterMatch = useCallback((filterIndex: number, cid: string, subplebbitAddress: string) => {
|
||||
@@ -293,13 +295,13 @@ const Catalog = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp,
|
||||
|
||||
return {
|
||||
subplebbitAddresses,
|
||||
sortType,
|
||||
sortType: feedSortType,
|
||||
postsPerPage: catalogPostsPerPage,
|
||||
filter: createCombinedFilter(filterItems, searchText, subplebbitAddress || 'all', handleFilterMatch),
|
||||
};
|
||||
}, [
|
||||
subplebbitAddresses,
|
||||
sortType,
|
||||
feedSortType,
|
||||
isInAllView,
|
||||
isInSubscriptionsView,
|
||||
isInModView,
|
||||
@@ -363,6 +365,8 @@ const Catalog = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp,
|
||||
[effectiveInfiniteScroll, combinedFeed, boardPostsPerPage, maxGuiPages],
|
||||
);
|
||||
|
||||
const sortedFeed = useMemo(() => sortCatalogFeedForDisplay(cappedFeed, sortType), [cappedFeed, sortType]);
|
||||
|
||||
useEffect(() => {
|
||||
if (filteredComments.length > 0 && !resetTriggeredRef.current) {
|
||||
reset();
|
||||
@@ -424,18 +428,18 @@ const Catalog = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp,
|
||||
|
||||
const isFeedLoaded = feed.length > 0 || state === 'failed';
|
||||
|
||||
// Process the feed to move "top" posts to the top
|
||||
// Process the feed to move "top" posts to the top (applied after display sort)
|
||||
const processedFeed = useMemo(() => {
|
||||
if (!cappedFeed || cappedFeed.length === 0) return cappedFeed;
|
||||
if (!sortedFeed || sortedFeed.length === 0) return sortedFeed;
|
||||
|
||||
const enabledTopFilters = filterItems.filter((item) => item.enabled && item.text.trim() !== '' && item.top);
|
||||
if (enabledTopFilters.length === 0) return cappedFeed;
|
||||
if (enabledTopFilters.length === 0) return sortedFeed;
|
||||
|
||||
// Separate posts that match "top" filters
|
||||
const topPosts: Comment[] = [];
|
||||
const regularPosts: Comment[] = [];
|
||||
|
||||
cappedFeed.forEach((comment) => {
|
||||
sortedFeed.forEach((comment) => {
|
||||
if (!comment) return;
|
||||
|
||||
let isTop = false;
|
||||
@@ -455,7 +459,7 @@ const Catalog = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp,
|
||||
|
||||
// Return top posts followed by regular posts
|
||||
return [...topPosts, ...regularPosts];
|
||||
}, [cappedFeed, filterItems]);
|
||||
}, [sortedFeed, filterItems]);
|
||||
|
||||
const rows = useCatalogFeedRows(columnCount, processedFeed, isFeedLoaded, subplebbit);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user