perf(bundle): replace plebbit-js imports with local utility, split chunks, fix CLS and rerenders

Eliminate direct @plebbit/plebbit-js (8.7MB) imports from all UI components by replacing
Plebbit.getShortAddress() with a local get-short-address utility. Add Vite manual chunks for
plebbit-js, plebbit-react-hooks, and react-spring/use-gesture. Fix catalog CLS by matching
skeleton to wrapper dimensions. Lazy-load ChallengeModal and ReplyModal. Add failed-URL cache
to useFetchGifFirstFrame, optimize useHide selector, and memoize useFeed options in mod-queue.
This commit is contained in:
plebeius
2026-02-26 16:42:36 +08:00
parent cd71602730
commit 4bdee0362d
16 changed files with 92 additions and 59 deletions
+17 -13
View File
@@ -27,9 +27,7 @@ import PendingPost from './views/pending-post';
import Post from './views/post'; import Post from './views/post';
import Rules from './views/rules'; import Rules from './views/rules';
import BoardHeader from './components/board-header'; import BoardHeader from './components/board-header';
import ChallengeModal from './components/challenge-modal';
import FeedCacheContainer from './components/feed-cache-container'; import FeedCacheContainer from './components/feed-cache-container';
import ReplyModal from './components/reply-modal';
import PostForm from './components/post-form'; import PostForm from './components/post-form';
import BoardBlotter from './components/board-blotter'; import BoardBlotter from './components/board-blotter';
import BoardsBar from './components/boardsbar'; import BoardsBar from './components/boardsbar';
@@ -37,8 +35,10 @@ import BoardsBar from './components/boardsbar';
const AccountDataEditor = lazy(() => import('./views/account-data-editor')); const AccountDataEditor = lazy(() => import('./views/account-data-editor'));
const BoardsBarEditModal = lazy(() => import('./components/boardsbar-edit-modal')); const BoardsBarEditModal = lazy(() => import('./components/boardsbar-edit-modal'));
const CreateBoardModal = lazy(() => import('./components/create-board-modal')); const CreateBoardModal = lazy(() => import('./components/create-board-modal'));
const ChallengeModal = lazy(() => import('./components/challenge-modal'));
const DirectoryModal = lazy(() => import('./components/directory-modal')); const DirectoryModal = lazy(() => import('./components/directory-modal'));
const DisclaimerModal = lazy(() => import('./components/disclaimer-modal')); const DisclaimerModal = lazy(() => import('./components/disclaimer-modal'));
const ReplyModal = lazy(() => import('./components/reply-modal'));
const SettingsModal = lazy(() => import('./components/settings-modal')); const SettingsModal = lazy(() => import('./components/settings-modal'));
// Preload all theme assets (buttons, backgrounds) immediately on app load // Preload all theme assets (buttons, backgrounds) immediately on app load
@@ -134,18 +134,22 @@ const GlobalLayout = () => {
return ( return (
<> <>
<ChallengeModal /> <Suspense fallback={null}>
<ChallengeModal />
</Suspense>
{activeCid && threadCid && subplebbitAddress && ( {activeCid && threadCid && subplebbitAddress && (
<ReplyModal <Suspense fallback={null}>
closeModal={closeModal} <ReplyModal
parentCid={activeCid} closeModal={closeModal}
parentNumber={parentNumber} parentCid={activeCid}
threadNumber={threadNumber} parentNumber={parentNumber}
postCid={threadCid} threadNumber={threadNumber}
scrollY={scrollY} postCid={threadCid}
showReplyModal={showReplyModal} scrollY={scrollY}
subplebbitAddress={subplebbitAddress} showReplyModal={showReplyModal}
/> subplebbitAddress={subplebbitAddress}
/>
</Suspense>
)} )}
{isInSettingsView && ( {isInSettingsView && (
<Suspense fallback={null}> <Suspense fallback={null}>
+2 -2
View File
@@ -4,7 +4,7 @@ import { useLocation, useParams, useNavigate } from 'react-router-dom';
import { useAccountComment } from '@plebbit/plebbit-react-hooks'; import { useAccountComment } from '@plebbit/plebbit-react-hooks';
import useAccountsStore from '@plebbit/plebbit-react-hooks/dist/stores/accounts'; import useAccountsStore from '@plebbit/plebbit-react-hooks/dist/stores/accounts';
import useSubplebbitsStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits'; import useSubplebbitsStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits';
import Plebbit from '@plebbit/plebbit-js'; import getShortAddress from '../../lib/get-short-address';
import { useStableSubplebbit } from '../../hooks/use-stable-subplebbit'; import { useStableSubplebbit } from '../../hooks/use-stable-subplebbit';
import { isAllView, isSubscriptionsView, isModView } from '../../lib/utils/view-utils'; import { isAllView, isSubscriptionsView, isModView } from '../../lib/utils/view-utils';
import styles from './board-header.module.css'; import styles from './board-header.module.css';
@@ -95,7 +95,7 @@ const BoardHeader = () => {
? shortAddress.endsWith('.eth') || shortAddress.endsWith('.sol') ? shortAddress.endsWith('.eth') || shortAddress.endsWith('.sol')
? shortAddress.slice(0, -4) ? shortAddress.slice(0, -4)
: shortAddress : shortAddress
: subplebbitAddress && Plebbit.getShortAddress({ address: subplebbitAddress }))} : subplebbitAddress && getShortAddress(subplebbitAddress))}
{!isInAllView && !isInSubscriptionsView && !isInModView && <OfflineIndicator subplebbitAddress={subplebbitAddress} />} {!isInAllView && !isInSubscriptionsView && !isInModView && <OfflineIndicator subplebbitAddress={subplebbitAddress} />}
</div> </div>
<div className={styles.boardSubtitle}> <div className={styles.boardSubtitle}>
+2 -2
View File
@@ -1,7 +1,7 @@
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Link, useLocation, useNavigate, useParams } from 'react-router-dom'; import { Link, useLocation, useNavigate, useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import Plebbit from '@plebbit/plebbit-js'; import getShortAddress from '../../lib/get-short-address';
import { useAccountComment } from '@plebbit/plebbit-react-hooks'; import { useAccountComment } from '@plebbit/plebbit-react-hooks';
import useAccountsStore from '@plebbit/plebbit-react-hooks/dist/stores/accounts'; import useAccountsStore from '@plebbit/plebbit-react-hooks/dist/stores/accounts';
import { isAllView, isCatalogView, isSubscriptionsView } from '../../lib/utils/view-utils'; import { isAllView, isCatalogView, isSubscriptionsView } from '../../lib/utils/view-utils';
@@ -200,7 +200,7 @@ const BoardsBarDesktop = () => {
// Render a subscription link // Render a subscription link
const renderSubscription = (address: string, index: number, total: number) => { const renderSubscription = (address: string, index: number, total: number) => {
const boardPath = getBoardPath(address, directories); const boardPath = getBoardPath(address, directories);
const displayText = address.endsWith('.eth') || address.endsWith('.sol') ? address : Plebbit.getShortAddress({ address }); const displayText = address.endsWith('.eth') || address.endsWith('.sol') ? address : getShortAddress(address);
return ( return (
<span key={address}> <span key={address}>
@@ -110,8 +110,8 @@
} }
.loadingSkeleton { .loadingSkeleton {
width: var(--maxWidth); width: 100%;
height: var(--maxHeight); height: 100%;
display: inline-block; display: inline-block;
} }
+4 -4
View File
@@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next';
import { Link, useLocation, useParams } from 'react-router-dom'; import { Link, useLocation, useParams } from 'react-router-dom';
import { useFloating, offset, size, Placement } from '@floating-ui/react'; import { useFloating, offset, size, Placement } from '@floating-ui/react';
import { Comment, useReplies } from '@plebbit/plebbit-react-hooks'; import { Comment, useReplies } from '@plebbit/plebbit-react-hooks';
import Plebbit from '@plebbit/plebbit-js'; import getShortAddress from '../../lib/get-short-address';
import { shouldShowSnow } from '../../lib/snow'; import { shouldShowSnow } from '../../lib/snow';
import { getHasThumbnail } from '../../lib/utils/media-utils'; import { getHasThumbnail } from '../../lib/utils/media-utils';
import { getFormattedTimeAgo } from '../../lib/utils/time-utils'; import { getFormattedTimeAgo } from '../../lib/utils/time-utils';
@@ -57,8 +57,8 @@ export const CatalogPostMedia = ({ cid, commentMediaInfo, linkWidth, linkHeight
} }
if (type === 'audio') { if (type === 'audio') {
displayWidth = 'unset'; displayWidth = `${maxThumbnailSize}px`;
displayHeight = 'unset'; displayHeight = '54px';
} }
const numericWidth = parseInt(displayWidth) || undefined; const numericWidth = parseInt(displayWidth) || undefined;
@@ -288,7 +288,7 @@ const CatalogPost = memo(
{author?.displayName || capitalize(t('anonymous'))} {author?.displayName || capitalize(t('anonymous'))}
{isCatalogPostAuthorMod && <span className='capitalize'>{` ## Board ${catalogPostAuthorRole}`}</span>} {isCatalogPostAuthorMod && <span className='capitalize'>{` ## Board ${catalogPostAuthorRole}`}</span>}
</span> </span>
{(isInAllView || isInSubscriptionsView) && subplebbitAddress && ` to p/${Plebbit.getShortAddress({ address: subplebbitAddress })}`} {(isInAllView || isInSubscriptionsView) && subplebbitAddress && ` to p/${getShortAddress(subplebbitAddress)}`}
<span className={styles.postAgo}> {getFormattedTimeAgo(timestamp)}</span> <span className={styles.postAgo}> {getFormattedTimeAgo(timestamp)}</span>
{replyCount > 0 && ( {replyCount > 0 && (
<div className={styles.postLast}> <div className={styles.postLast}>
@@ -4,7 +4,7 @@ import { Trans, useTranslation } from 'react-i18next';
import { Comment, useComment } from '@plebbit/plebbit-react-hooks'; import { Comment, useComment } from '@plebbit/plebbit-react-hooks';
import useSubplebbitsPagesStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits-pages'; import useSubplebbitsPagesStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits-pages';
import usePostNumberStore from '../../stores/use-post-number-store'; import usePostNumberStore from '../../stores/use-post-number-store';
import Plebbit from '@plebbit/plebbit-js'; import getShortAddress from '../../lib/get-short-address';
import { getFormattedDate, getFormattedTimeAgo } from '../../lib/utils/time-utils'; import { getFormattedDate, getFormattedTimeAgo } from '../../lib/utils/time-utils';
import { isPostPageView } from '../../lib/utils/view-utils'; import { isPostPageView } from '../../lib/utils/view-utils';
import useIsMobile from '../../hooks/use-is-mobile'; import useIsMobile from '../../hooks/use-is-mobile';
@@ -253,7 +253,7 @@ const CommentContent = ({ comment: post }: { comment: Comment }) => {
<br /> <br />
<Tooltip <Tooltip
content={`${t('ban_expires_at', { content={`${t('ban_expires_at', {
address: subplebbitAddress && Plebbit.getShortAddress({ address: subplebbitAddress }), address: subplebbitAddress && getShortAddress(subplebbitAddress),
timestamp: getFormattedDate(post?.author?.subplebbit?.banExpiresAt), timestamp: getFormattedDate(post?.author?.subplebbit?.banExpiresAt),
interpolation: { escapeValue: false }, interpolation: { escapeValue: false },
})}${reason ? `. ${capitalize(t('reason'))}: "${reason}"` : ''}`} })}${reason ? `. ${capitalize(t('reason'))}: "${reason}"` : ''}`}
+4 -4
View File
@@ -3,7 +3,7 @@ import { Trans, useTranslation } from 'react-i18next';
import { Link, useLocation, useNavigationType, useParams } from 'react-router-dom'; import { Link, useLocation, useNavigationType, useParams } from 'react-router-dom';
import { Virtuoso, VirtuosoHandle, StateSnapshot } from 'react-virtuoso'; import { Virtuoso, VirtuosoHandle, StateSnapshot } from 'react-virtuoso';
import { Comment, useEditedComment, useReplies, useAccount, useAccountComment } from '@plebbit/plebbit-react-hooks'; import { Comment, useEditedComment, useReplies, useAccount, useAccountComment } from '@plebbit/plebbit-react-hooks';
import Plebbit from '@plebbit/plebbit-js'; import getShortAddress from '../../lib/get-short-address';
import styles from '../../views/post/post.module.css'; import styles from '../../views/post/post.module.css';
import { CommentMediaInfo, getDisplayMediaInfoType, getHasThumbnail, getMediaDimensions } from '../../lib/utils/media-utils'; import { CommentMediaInfo, getDisplayMediaInfoType, getHasThumbnail, getMediaDimensions } from '../../lib/utils/media-utils';
import { hashStringToColor, getTextColorForBackground } from '../../lib/utils/post-utils'; import { hashStringToColor, getTextColorForBackground } from '../../lib/utils/post-utils';
@@ -211,7 +211,7 @@ const PostInfo = ({
const alertThresholdSeconds = getAlertThresholdSeconds(); const alertThresholdSeconds = getAlertThresholdSeconds();
const isOverThreshold = isAwaitingApproval && timeWaiting > alertThresholdSeconds; const isOverThreshold = isAwaitingApproval && timeWaiting > alertThresholdSeconds;
const userID = address && Plebbit.getShortAddress({ address }); // shortened to 8 chars for display; users can verify the full user ID via "Copy user ID" in the post menu to guard against spoofing const userID = address && getShortAddress(address); // shortened to 8 chars for display; users can verify the full user ID via "Copy user ID" in the post menu to guard against spoofing
const userIDBackgroundColor = hashStringToColor(userID); const userIDBackgroundColor = hashStringToColor(userID);
const userIDTextColor = getTextColorForBackground(userIDBackgroundColor); const userIDTextColor = getTextColorForBackground(userIDBackgroundColor);
@@ -562,7 +562,7 @@ const PostMedia = ({
? boardPath ? boardPath
: subplebbitAddress.endsWith('.eth') || subplebbitAddress.endsWith('.sol') : subplebbitAddress.endsWith('.eth') || subplebbitAddress.endsWith('.sol')
? subplebbitAddress ? subplebbitAddress
: Plebbit.getShortAddress({ address: subplebbitAddress }); : getShortAddress(subplebbitAddress);
return ( return (
<div className={styles.file}> <div className={styles.file}>
@@ -741,7 +741,7 @@ const PostDesktop = ({
? boardPath ? boardPath
: subplebbitAddress.endsWith('.eth') || subplebbitAddress.endsWith('.sol') : subplebbitAddress.endsWith('.eth') || subplebbitAddress.endsWith('.sol')
? subplebbitAddress ? subplebbitAddress
: Plebbit.getShortAddress({ address: subplebbitAddress }) : getShortAddress(subplebbitAddress)
: undefined; : undefined;
const { hidden, unhide, hide } = useHide({ cid }); const { hidden, unhide, hide } = useHide({ cid });
+2 -2
View File
@@ -2,7 +2,7 @@ import { useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useLocation, useNavigate, useParams } from 'react-router-dom'; import { useLocation, useNavigate, useParams } from 'react-router-dom';
import { Comment, setAccount, useAccount, useAccountComment, useAccountSubplebbits, useEditedComment } from '@plebbit/plebbit-react-hooks'; import { Comment, setAccount, useAccount, useAccountComment, useAccountSubplebbits, useEditedComment } from '@plebbit/plebbit-react-hooks';
import Plebbit from '@plebbit/plebbit-js'; import getShortAddress from '../../lib/get-short-address';
import useSubplebbitsStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits'; import useSubplebbitsStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits';
import useSubplebbitsPagesStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits-pages'; import useSubplebbitsPagesStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits-pages';
import { getHasThumbnail, getLinkMediaInfo } from '../../lib/utils/media-utils'; import { getHasThumbnail, getLinkMediaInfo } from '../../lib/utils/media-utils';
@@ -280,7 +280,7 @@ const PostFormFields = ({
{isInModView && {isInModView &&
accountSubplebbitAddresses.map((address: string) => ( accountSubplebbitAddresses.map((address: string) => (
<option key={address} value={address}> <option key={address} value={address}>
{address && Plebbit.getShortAddress({ address })} {address && getShortAddress(address)}
</option> </option>
))} ))}
{isInSubscriptionsView && {isInSubscriptionsView &&
+3 -3
View File
@@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
import { Link, useLocation, useNavigationType, useParams } from 'react-router-dom'; import { Link, useLocation, useNavigationType, useParams } from 'react-router-dom';
import { Virtuoso, VirtuosoHandle, StateSnapshot } from 'react-virtuoso'; import { Virtuoso, VirtuosoHandle, StateSnapshot } from 'react-virtuoso';
import { Comment, useEditedComment, useReplies, useAccount, usePublishCommentModeration, useAccountComment } from '@plebbit/plebbit-react-hooks'; import { Comment, useEditedComment, useReplies, useAccount, usePublishCommentModeration, useAccountComment } from '@plebbit/plebbit-react-hooks';
import Plebbit from '@plebbit/plebbit-js'; import getShortAddress from '../../lib/get-short-address';
import styles from '../../views/post/post.module.css'; import styles from '../../views/post/post.module.css';
import { shouldShowSnow } from '../../lib/snow'; import { shouldShowSnow } from '../../lib/snow';
import { getHasThumbnail } from '../../lib/utils/media-utils'; import { getHasThumbnail } from '../../lib/utils/media-utils';
@@ -66,7 +66,7 @@ const PostInfoAndMedia = ({ post, postReplyCount = 0, roles, threadNumber }: Pos
? boardPath ? boardPath
: subplebbitAddress.endsWith('.eth') || subplebbitAddress.endsWith('.sol') : subplebbitAddress.endsWith('.eth') || subplebbitAddress.endsWith('.sol')
? subplebbitAddress ? subplebbitAddress
: Plebbit.getShortAddress({ address: subplebbitAddress }) : getShortAddress(subplebbitAddress)
: undefined; : undefined;
const isReply = parentCid; const isReply = parentCid;
const title = post?.title?.trim(); const title = post?.title?.trim();
@@ -203,7 +203,7 @@ const PostInfoAndMedia = ({ post, postReplyCount = 0, roles, threadNumber }: Pos
return Math.max(domCount, 1); return Math.max(domCount, 1);
})(); })();
const userID = address && Plebbit.getShortAddress({ address }); // shortened to 8 chars for display; users can verify the full user ID via "Copy user ID" in the post menu to guard against spoofing const userID = address && getShortAddress(address); // shortened to 8 chars for display; users can verify the full user ID via "Copy user ID" in the post menu to guard against spoofing
const userIDBackgroundColor = hashStringToColor(userID); const userIDBackgroundColor = hashStringToColor(userID);
const userIDTextColor = getTextColorForBackground(userIDBackgroundColor); const userIDTextColor = getTextColorForBackground(userIDBackgroundColor);
@@ -1,5 +1,5 @@
import { setAccount, useAccount, useSubscribe } from '@plebbit/plebbit-react-hooks'; import { setAccount, useAccount, useSubscribe } from '@plebbit/plebbit-react-hooks';
import Plebbit from '@plebbit/plebbit-js'; import getShortAddress from '../../../lib/get-short-address';
import styles from './subscriptions-setting.module.css'; import styles from './subscriptions-setting.module.css';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useState } from 'react'; import { useState } from 'react';
@@ -79,7 +79,7 @@ const SubscriptionsSetting = () => {
<ul className={styles.subscriptions}> <ul className={styles.subscriptions}>
{subscriptions?.map((address: string) => ( {subscriptions?.map((address: string) => (
<li key={address} className={styles.subscription}> <li key={address} className={styles.subscription}>
{address && Plebbit.getShortAddress({ address })} <SubscriptionButton address={address} /> {address && getShortAddress(address)} <SubscriptionButton address={address} />
</li> </li>
))} ))}
</ul> </ul>
+6
View File
@@ -2,6 +2,7 @@ import { useEffect, useState } from 'react';
import localForageLru from '@plebbit/plebbit-react-hooks/dist/lib/localforage-lru/index.js'; import localForageLru from '@plebbit/plebbit-react-hooks/dist/lib/localforage-lru/index.js';
const gifFrameDb = localForageLru.createInstance({ name: '5chanGifFrames', size: 500 }); const gifFrameDb = localForageLru.createInstance({ name: '5chanGifFrames', size: 500 });
const failedUrls = new Set<string>();
const getCachedGifFrame = async (url: string): Promise<string | null> => { const getCachedGifFrame = async (url: string): Promise<string | null> => {
return await gifFrameDb.getItem(url); return await gifFrameDb.getItem(url);
@@ -72,6 +73,10 @@ const useFetchGifFirstFrame = (url: string | undefined) => {
let isActive = true; let isActive = true;
const fetchFrame = async () => { const fetchFrame = async () => {
if (failedUrls.has(url)) {
if (isActive) setFrameUrl(null);
return;
}
try { try {
const cachedFrame = await getCachedGifFrame(url); const cachedFrame = await getCachedGifFrame(url);
if (cachedFrame) { if (cachedFrame) {
@@ -91,6 +96,7 @@ const useFetchGifFirstFrame = (url: string | undefined) => {
await setCachedGifFrame(url, objectUrl); await setCachedGifFrame(url, objectUrl);
} }
} catch (error) { } catch (error) {
failedUrls.add(url);
console.error('Failed to load GIF frame:', error); console.error('Failed to load GIF frame:', error);
if (isActive) setFrameUrl(null); if (isActive) setFrameUrl(null);
} }
+3 -5
View File
@@ -1,4 +1,4 @@
import { useCallback } from 'react'; import { useCallback, useMemo } from 'react';
import { create } from 'zustand'; import { create } from 'zustand';
import localForageLru from '@plebbit/plebbit-react-hooks/dist/lib/localforage-lru/index.js'; import localForageLru from '@plebbit/plebbit-react-hooks/dist/lib/localforage-lru/index.js';
@@ -46,16 +46,14 @@ const initializeHideStore = async () => {
initializeHideStore(); initializeHideStore();
const useHide = ({ cid }: { cid: string }) => { const useHide = ({ cid }: { cid: string }) => {
const hiddenCids = useHideStore((state) => state.hiddenCids); const hidden = useHideStore((state) => !!state.hiddenCids[cid]);
const hide = useHideStore((state) => state.hide); const hide = useHideStore((state) => state.hide);
const unhide = useHideStore((state) => state.unhide); const unhide = useHideStore((state) => state.unhide);
const hidden = !!hiddenCids[cid];
const hideCallback = useCallback(() => hide(cid), [hide, cid]); const hideCallback = useCallback(() => hide(cid), [hide, cid]);
const unhideCallback = useCallback(() => unhide(cid), [unhide, cid]); const unhideCallback = useCallback(() => unhide(cid), [unhide, cid]);
return { hidden, hide: hideCallback, unhide: unhideCallback }; return useMemo(() => ({ hidden, hide: hideCallback, unhide: unhideCallback }), [hidden, hideCallback, unhideCallback]);
}; };
export default useHide; export default useHide;
+8
View File
@@ -0,0 +1,8 @@
const getShortAddress = (address: string): string => {
if (!address) return '';
if (address.includes('.')) return address;
if (address.length < 20) return '';
return address.slice(8, 20);
};
export default getShortAddress;
+6 -7
View File
@@ -1,10 +1,9 @@
if (import.meta.env.DEV) { if (import.meta.env.DEV) {
const { scan, getReport } = await import('react-scan'); import('react-scan').then(({ scan, getReport }) => {
scan({ scan({
enabled: true, enabled: true,
showToolbar: !(window as any).__PROFILING__, showToolbar: !(window as any).__PROFILING__,
playSound: !(window as any).__PROFILING__, });
report: true, (window as any).__getReactScanReport = getReport;
}); });
(window as any).__getReactScanReport = getReport;
} }
+20 -11
View File
@@ -622,12 +622,17 @@ export const ModQueueButton = ({ boardIdentifier, isMobile }: ModQueueButtonProp
// Only fetch if we have addresses to check and permissions // Only fetch if we have addresses to check and permissions
const shouldFetch = subplebbitAddresses.length > 0 && isModOfBoard; const shouldFetch = subplebbitAddresses.length > 0 && isModOfBoard;
const { feed } = useFeed({ const feedAddresses = shouldFetch ? subplebbitAddresses : [];
subplebbitAddresses: shouldFetch ? subplebbitAddresses : [], const feedOptions = useMemo(
modQueue: ['pendingApproval'], () => ({
sortType: 'new', subplebbitAddresses: feedAddresses,
postsPerPage: 200, // Fetch more items to get accurate pending count for the badge modQueue: ['pendingApproval'],
}); sortType: 'new' as const,
postsPerPage: 200,
}),
[feedAddresses],
);
const { feed } = useFeed(feedOptions);
if (!shouldFetch || subplebbitAddresses.length === 0) { if (!shouldFetch || subplebbitAddresses.length === 0) {
return null; return null;
@@ -694,11 +699,15 @@ const ModQueueView = ({ boardIdentifier: propBoardIdentifier }: ModQueueViewProp
const subplebbit = useSubplebbit({ subplebbitAddress }); const subplebbit = useSubplebbit({ subplebbitAddress });
const { error: subplebbitError } = subplebbit || {}; const { error: subplebbitError } = subplebbit || {};
const { feed, hasMore, loadMore, reset } = useFeed({ const feedOptions = useMemo(
subplebbitAddresses, () => ({
modQueue: ['pendingApproval'], subplebbitAddresses,
postsPerPage: 50, modQueue: ['pendingApproval'],
}); postsPerPage: 50,
}),
[subplebbitAddresses],
);
const { feed, hasMore, loadMore, reset } = useFeed(feedOptions);
const setResetFunction = useFeedResetStore((state) => state.setResetFunction); const setResetFunction = useFeedResetStore((state) => state.setResetFunction);
useEffect(() => { useEffect(() => {
+9
View File
@@ -169,6 +169,15 @@ export default defineConfig({
rollupOptions: { rollupOptions: {
output: { output: {
manualChunks(id) { manualChunks(id) {
if (/[\\/]node_modules[\\/](@plebbit[\\/]plebbit-js)[\\/]/.test(id)) {
return 'plebbit-js';
}
if (/[\\/]node_modules[\\/](@plebbit[\\/]plebbit-react-hooks)[\\/]/.test(id)) {
return 'plebbit-react-hooks';
}
if (/[\\/]node_modules[\\/](@react-spring|@use-gesture)[\\/]/.test(id)) {
return 'spring-gesture';
}
if (/[\\/]node_modules[\\/](react|react-dom|react-router-dom|react-i18next|i18next|i18next-browser-languagedetector|i18next-http-backend)[\\/]/.test(id)) { if (/[\\/]node_modules[\\/](react|react-dom|react-router-dom|react-i18next|i18next|i18next-browser-languagedetector|i18next-http-backend)[\\/]/.test(id)) {
return 'vendor'; return 'vendor';
} }