diff --git a/packages/pl-fe/src/components/scrollable-list.tsx b/packages/pl-fe/src/components/scrollable-list.tsx index edaf7e1af..4cc09aab7 100644 --- a/packages/pl-fe/src/components/scrollable-list.tsx +++ b/packages/pl-fe/src/components/scrollable-list.tsx @@ -1,5 +1,5 @@ /* eslint-disable react-hooks/rules-of-hooks */ -import { useVirtualizer, useWindowVirtualizer, type Virtualizer } from '@tanstack/react-virtual'; +import { useVirtualizer, type Virtualizer } from '@tanstack/react-virtual'; import clsx from 'clsx'; import React, { useEffect, useMemo } from 'react'; @@ -8,16 +8,7 @@ import { useSettings } from 'pl-fe/hooks'; import LoadMore from './load-more'; import { Card, Spinner } from './ui'; -type IScrollableListWindowScroll = { - /** Whether to use the window to scroll the content instead of the container. */ - useWindowScroll?: true; -} | { - /** Whether to use the window to scroll the content instead of the container. */ - useWindowScroll: false; - parentRef: React.RefObject; -}; - -interface IScrollableList { +interface IScrollableListBase { /** Pagination callback when the end of the list is reached. */ onLoadMore?: () => void; /** Whether the data is currently being fetched. */ @@ -42,8 +33,6 @@ interface IScrollableList { placeholderComponent?: React.ComponentType | React.NamedExoticComponent; /** Number of placeholders to render while loading. */ placeholderCount?: number; - /** Extra class names on the parent element. */ - className?: string; /** Extra class names on the list element. */ listClassName?: string; /** Class names on each item container. */ @@ -52,8 +41,6 @@ interface IScrollableList { loadMoreClassName?: string; /** `id` attribute on the parent element. */ id?: string; - /** CSS styles on the parent element. */ - style?: React.CSSProperties; /** Initial item index to scroll to. */ initialIndex?: number; /** Estimated size for items. */ @@ -62,7 +49,20 @@ interface IScrollableList { alignToBottom?: boolean; } -const ScrollableList = React.forwardRef, IScrollableList & IScrollableListWindowScroll>(({ +interface IScrollableListWithContainer extends IScrollableListBase { + /** Extra class names on the container element. */ + className?: string; + /** CSS styles on the container element. */ + style?: React.CSSProperties; +} + +interface IScrollableListWithoutContainer extends IScrollableListBase { + parentRef: React.RefObject; +} + +type IScrollableList = IScrollableListWithContainer | IScrollableListWithoutContainer; + +const ScrollableList = React.forwardRef, IScrollableList>(({ prepend = null, alwaysPrepend, children, @@ -72,7 +72,6 @@ const ScrollableList = React.forwardRef, IScrollableList & showLoading, onScroll, onLoadMore, - className, listClassName, itemClassName, loadMoreClassName, @@ -81,7 +80,6 @@ const ScrollableList = React.forwardRef, IScrollableList & placeholderComponent: Placeholder, placeholderCount = 0, initialIndex, - style = {}, estimatedSize = 300, alignToBottom, ...props @@ -97,15 +95,11 @@ const ScrollableList = React.forwardRef, IScrollableList & const data = showPlaceholder ? Array(placeholderCount).fill('') : elements; - const virtualizer = props.useWindowScroll === false ? useVirtualizer({ + const virtualizer = useVirtualizer({ count: data.length + (hasMore ? 1 : 0), - overscan: 3, - estimateSize: () => estimatedSize, - getScrollElement: () => props.parentRef.current || parentRef.current, - }) : useWindowVirtualizer({ - count: data.length + (hasMore ? 1 : 0), - overscan: 3, + overscan: 2, estimateSize: () => estimatedSize, + getScrollElement: () => ('parentRef' in props && props.parentRef.current) || parentRef.current, }); useEffect(() => { @@ -170,44 +164,51 @@ const ScrollableList = React.forwardRef, IScrollableList & const virtualItems = virtualizer.getVirtualItems(); + const body = ( +
+ {(!showLoading || showPlaceholder) && data.length ? ( + <> + {prepend} + {virtualItems.map((item) => ( +
+ {renderItem(item.index)} +
+ ))} + + ) : renderEmpty()} +
+ ); + + if ('parentRef' in props) return body; + return (
-
- {(!showLoading || showPlaceholder) && data.length ? ( - <> - {prepend} - {virtualItems.map((item) => ( -
- {renderItem(item.index)} -
- ))} - - ) : renderEmpty()} -
+ {body}
); }); -export { type IScrollableList, ScrollableList as default }; +export { type IScrollableList, type IScrollableListWithContainer, type IScrollableListWithoutContainer, ScrollableList as default }; diff --git a/packages/pl-fe/src/components/status-list.tsx b/packages/pl-fe/src/components/status-list.tsx index e44d5936b..2f7d0ab6e 100644 --- a/packages/pl-fe/src/components/status-list.tsx +++ b/packages/pl-fe/src/components/status-list.tsx @@ -14,9 +14,9 @@ import { usePlFeConfig } from 'pl-fe/hooks'; import { Stack, Text } from './ui'; import type { OrderedSet as ImmutableOrderedSet } from 'immutable'; -import type { IScrollableList } from 'pl-fe/components/scrollable-list'; +import type { IScrollableListWithContainer } from 'pl-fe/components/scrollable-list'; -interface IStatusList extends Omit { +interface IStatusList extends Omit { /** Unique key to preserve the scroll position when navigating back. */ scrollKey: string; /** List of status IDs to display. */ @@ -54,7 +54,6 @@ const StatusList: React.FC = ({ isLoading, isPartial, showGroup = true, - className, ...other }) => { const plFeConfig = usePlFeConfig(); @@ -220,7 +219,6 @@ const StatusList: React.FC = ({ onLoadMore={handleLoadOlder} placeholderComponent={() => } placeholderCount={20} - className={className} listClassName={clsx('divide-y divide-solid divide-gray-200 dark:divide-gray-800', { 'divide-none': divideType !== 'border', })} diff --git a/packages/pl-fe/src/features/chats/components/chat-list.tsx b/packages/pl-fe/src/features/chats/components/chat-list.tsx index d6f83feb3..2810ad44a 100644 --- a/packages/pl-fe/src/features/chats/components/chat-list.tsx +++ b/packages/pl-fe/src/features/chats/components/chat-list.tsx @@ -59,7 +59,6 @@ const ChatList: React.FC = ({ onClickChat, parentRef, topOffset }) => hasMore={hasNextPage} onLoadMore={handleLoadMore} estimatedSize={64} - useWindowScroll={false} parentRef={parentRef} loadMoreClassName='mx-4 mb-4' > diff --git a/packages/pl-fe/src/features/chats/components/chat-message-list.tsx b/packages/pl-fe/src/features/chats/components/chat-message-list.tsx index 1cc1e148b..964fb938b 100644 --- a/packages/pl-fe/src/features/chats/components/chat-message-list.tsx +++ b/packages/pl-fe/src/features/chats/components/chat-message-list.tsx @@ -196,7 +196,6 @@ const ChatMessageList: React.FC = ({ chat }) => { isLoading={isFetching} showLoading={isFetching && !isFetchingNextPage} onLoadMore={handleStartReached} - useWindowScroll={false} parentRef={parentRef} > {cachedChatMessages.map((chatMessage, index) => { diff --git a/packages/pl-fe/src/features/chats/components/chat-search/results.tsx b/packages/pl-fe/src/features/chats/components/chat-search/results.tsx index f78dd890c..e53f7c286 100644 --- a/packages/pl-fe/src/features/chats/components/chat-search/results.tsx +++ b/packages/pl-fe/src/features/chats/components/chat-search/results.tsx @@ -61,7 +61,6 @@ const Results = ({ accountSearchResult, onSelect, parentRef }: IResults) => { isLoading={isFetching} hasMore={hasNextPage} onLoadMore={handleLoadMore} - useWindowScroll={false} parentRef={parentRef} > {(accounts || []).map((chat) => renderAccount(chat))} diff --git a/packages/pl-fe/src/features/onboarding/steps/suggested-accounts-step.tsx b/packages/pl-fe/src/features/onboarding/steps/suggested-accounts-step.tsx index c0a89012d..02681b36b 100644 --- a/packages/pl-fe/src/features/onboarding/steps/suggested-accounts-step.tsx +++ b/packages/pl-fe/src/features/onboarding/steps/suggested-accounts-step.tsx @@ -21,7 +21,6 @@ const SuggestedAccountsStep = ({ onNext }: { onNext: () => void }) => { {data.map((suggestion) => ( diff --git a/packages/pl-fe/src/features/status/components/thread.tsx b/packages/pl-fe/src/features/status/components/thread.tsx index 70e956a44..8cc3ea812 100644 --- a/packages/pl-fe/src/features/status/components/thread.tsx +++ b/packages/pl-fe/src/features/status/components/thread.tsx @@ -78,14 +78,14 @@ const getDescendantsIds = createSelector([ interface IThread { status: SelectedStatus; withMedia?: boolean; - useWindowScroll?: boolean; + isModal?: boolean; itemClassName?: string; } const Thread: React.FC = ({ itemClassName, status, - useWindowScroll = true, + isModal = false, withMedia = true, }) => { const dispatch = useAppDispatch(); @@ -114,7 +114,7 @@ const Thread: React.FC = ({ }); let initialIndex = ancestorsIds.size; - if (!useWindowScroll && initialIndex !== 0) initialIndex = ancestorsIds.size + 1; + if (isModal && initialIndex !== 0) initialIndex = ancestorsIds.size + 1; const node = useRef(null); const statusRef = useRef(null); @@ -234,7 +234,7 @@ const Thread: React.FC = ({ }; const _selectChild = (index: number) => { - if (!useWindowScroll) index = index + 1; + if (isModal) index = index + 1; const selector = `[data-index="${index}"] .focusable`; const element = node.current?.querySelector(selector); @@ -341,7 +341,7 @@ const Thread: React.FC = ({ @@ -356,7 +356,7 @@ const Thread: React.FC = ({ const children: JSX.Element[] = []; - if (!useWindowScroll) { + if (isModal) { // Add padding to the top of the Thread (for Media Modal) children.push(
); } @@ -376,8 +376,8 @@ const Thread: React.FC = ({ space={2} className={ clsx({ - 'h-full': !useWindowScroll, - 'mt-2': useWindowScroll, + 'h-full': isModal, + 'mt-2': !isModal, }) } > @@ -391,7 +391,7 @@ const Thread: React.FC = ({ ref={node} className={ clsx('bg-white black:bg-black dark:bg-primary-900', { - 'h-full overflow-auto': !useWindowScroll, + 'h-full overflow-auto': isModal, }) } > @@ -403,10 +403,9 @@ const Thread: React.FC = ({ itemClassName={itemClassName} listClassName={ clsx({ - 'h-full': !useWindowScroll, + 'h-full': isModal, }) } - useWindowScroll={useWindowScroll} parentRef={node} > {children} diff --git a/packages/pl-fe/src/features/ui/components/modals/familiar-followers-modal.tsx b/packages/pl-fe/src/features/ui/components/modals/familiar-followers-modal.tsx index 0596f88c2..87b006cf3 100644 --- a/packages/pl-fe/src/features/ui/components/modals/familiar-followers-modal.tsx +++ b/packages/pl-fe/src/features/ui/components/modals/familiar-followers-modal.tsx @@ -38,7 +38,6 @@ const FamiliarFollowersModal: React.FC {familiarFollowerIds.map(id => diff --git a/packages/pl-fe/src/features/ui/components/modals/favourites-modal.tsx b/packages/pl-fe/src/features/ui/components/modals/favourites-modal.tsx index 5cca93b98..a3f6a3241 100644 --- a/packages/pl-fe/src/features/ui/components/modals/favourites-modal.tsx +++ b/packages/pl-fe/src/features/ui/components/modals/favourites-modal.tsx @@ -54,7 +54,6 @@ const FavouritesModal: React.FC = ({ onCl onLoadMore={handleLoadMore} hasMore={!!next} estimatedSize={42} - useWindowScroll={false} parentRef={modalRef} > {accountIds.map(id => diff --git a/packages/pl-fe/src/features/ui/components/modals/media-modal.tsx b/packages/pl-fe/src/features/ui/components/modals/media-modal.tsx index d99aba5ee..55b6cc8de 100644 --- a/packages/pl-fe/src/features/ui/components/modals/media-modal.tsx +++ b/packages/pl-fe/src/features/ui/components/modals/media-modal.tsx @@ -337,7 +337,7 @@ const MediaModal: React.FC = (props) => {
diff --git a/packages/pl-fe/src/features/ui/components/modals/mentions-modal.tsx b/packages/pl-fe/src/features/ui/components/modals/mentions-modal.tsx index 6ab36dc96..ba559f169 100644 --- a/packages/pl-fe/src/features/ui/components/modals/mentions-modal.tsx +++ b/packages/pl-fe/src/features/ui/components/modals/mentions-modal.tsx @@ -46,7 +46,6 @@ const MentionsModal: React.FC = ({ onClose, listClassName='max-w-full' itemClassName='pb-3' estimatedSize={42} - useWindowScroll={false} parentRef={modalRef} > {accountIds.map(id => diff --git a/packages/pl-fe/src/features/ui/components/modals/reactions-modal.tsx b/packages/pl-fe/src/features/ui/components/modals/reactions-modal.tsx index da5a30c42..07d06894f 100644 --- a/packages/pl-fe/src/features/ui/components/modals/reactions-modal.tsx +++ b/packages/pl-fe/src/features/ui/components/modals/reactions-modal.tsx @@ -95,7 +95,6 @@ const ReactionsModal: React.FC = ({ onClos itemClassName='pb-3' style={{ height: 'calc(80vh - 88px)' }} estimatedSize={42} - useWindowScroll={false} parentRef={modalRef} > {accounts.map((account) => diff --git a/packages/pl-fe/src/features/ui/components/modals/reblogs-modal.tsx b/packages/pl-fe/src/features/ui/components/modals/reblogs-modal.tsx index e0514763f..6a8120c58 100644 --- a/packages/pl-fe/src/features/ui/components/modals/reblogs-modal.tsx +++ b/packages/pl-fe/src/features/ui/components/modals/reblogs-modal.tsx @@ -56,7 +56,6 @@ const ReblogsModal: React.FC = ({ onClose, s onLoadMore={handleLoadMore} hasMore={!!next} estimatedSize={42} - useWindowScroll={false} parentRef={modalRef} > {accountIds.map((id) =>