mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
65 lines
2.6 KiB
TypeScript
65 lines
2.6 KiB
TypeScript
import { useMemo } from 'react';
|
|
import { useFeed } from '@bitsocial/bitsocial-react-hooks';
|
|
import useFeedsStore from '@bitsocial/bitsocial-react-hooks/dist/stores/feeds';
|
|
import { useDirectoryByAddress } from './use-directories';
|
|
import { useBoardFeedPageSize } from './use-board-feed-page-size';
|
|
import { useCommunityIdentifier } from './use-community-identifiers';
|
|
import { findPostPageInFeed, findPostPageInLoadedBoardFeeds, type FeedsOptionsLike, type LoadedFeedsLike } from '../lib/utils/post-page-resolution';
|
|
|
|
interface UsePostPageNumberOptions {
|
|
communityAddress?: string;
|
|
postCid: string | undefined;
|
|
/** When false, page segment is excluded (e.g. pending-post view). When true, resolve and show page. */
|
|
enabled?: boolean;
|
|
}
|
|
|
|
/**
|
|
* Resolve the board pagination page (1-based) for a post in a thread view.
|
|
* Uses cache-first lookup from feeds store, then preloads via useFeed if miss.
|
|
* Preload depth is capped to board pagination window (10 pages via paginationFeedPostsPerPage).
|
|
*
|
|
* @returns 1-based page number, or undefined when unresolved (render as "?")
|
|
*/
|
|
export function usePostPageNumber({ communityAddress, postCid, enabled = true }: UsePostPageNumberOptions): number | undefined {
|
|
const communityIdentifier = useCommunityIdentifier(communityAddress);
|
|
|
|
const community = useDirectoryByAddress(communityAddress);
|
|
const { guiPostsPerPage, paginationFeedPostsPerPage } = useBoardFeedPageSize(community);
|
|
|
|
const canResolve = Boolean(enabled && communityAddress && postCid && guiPostsPerPage > 0);
|
|
|
|
// Cache-first: selector returns only computed page to minimize rerenders
|
|
const cachedPage = useFeedsStore((state) => {
|
|
if (!canResolve) return undefined;
|
|
return findPostPageInLoadedBoardFeeds(
|
|
state.feedsOptions as unknown as FeedsOptionsLike,
|
|
state.loadedFeeds as unknown as LoadedFeedsLike,
|
|
communityAddress!,
|
|
postCid!,
|
|
guiPostsPerPage,
|
|
);
|
|
});
|
|
|
|
// Preload when cache miss and enabled (10 GUI pages)
|
|
const preloadOptions = useMemo(
|
|
() =>
|
|
canResolve
|
|
? {
|
|
communities: communityIdentifier ? [communityIdentifier] : [],
|
|
sortType: 'active' as const,
|
|
postsPerPage: paginationFeedPostsPerPage,
|
|
}
|
|
: undefined,
|
|
[canResolve, communityIdentifier, paginationFeedPostsPerPage],
|
|
);
|
|
|
|
const { feed: preloadFeed } = useFeed(preloadOptions);
|
|
|
|
const preloadedPage = useMemo(() => {
|
|
if (!canResolve || !preloadFeed?.length) return undefined;
|
|
return findPostPageInFeed(preloadFeed, postCid!, guiPostsPerPage);
|
|
}, [canResolve, postCid, preloadFeed, guiPostsPerPage]);
|
|
|
|
return cachedPage ?? preloadedPage;
|
|
}
|