From 40f18efdd9904a5d6a523938f59f48765ce08ca8 Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Mon, 30 Oct 2023 13:58:30 +0300 Subject: [PATCH 1/3] add batches pre-loading --- src/pages/commonFeed/CommonFeed.tsx | 2 ++ .../commonFeed/components/FeedLayout/FeedLayout.tsx | 13 +++++++++++++ .../components/FeedLayout/constants/index.ts | 1 + src/shared/hooks/useCases/useCommonFeedItems.ts | 3 ++- src/store/states/common/actions.ts | 2 +- src/store/states/common/reducer.ts | 2 ++ src/store/states/common/types.ts | 1 + 7 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 src/pages/commonFeed/components/FeedLayout/constants/index.ts diff --git a/src/pages/commonFeed/CommonFeed.tsx b/src/pages/commonFeed/CommonFeed.tsx index 5f3c58f20d..8182a5d33c 100644 --- a/src/pages/commonFeed/CommonFeed.tsx +++ b/src/pages/commonFeed/CommonFeed.tsx @@ -161,6 +161,7 @@ const CommonFeedComponent: FC = (props) => { loading: areCommonFeedItemsLoading, hasMore: hasMoreCommonFeedItems, fetch: fetchCommonFeedItems, + batchNumber, } = useCommonFeedItems(commonId, commonFeedItemIdsForNotListening); const { @@ -508,6 +509,7 @@ const CommonFeedComponent: FC = (props) => { topFeedItems={topFeedItems} feedItems={commonFeedItems} loading={areCommonFeedItemsLoading} + batchNumber={batchNumber} onFetchNext={fetchMoreCommonFeedItems} renderFeedItemBaseContent={renderFeedItemBaseContent} onFeedItemUpdate={handleFeedItemUpdate} diff --git a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx index b320084497..406c85c93f 100644 --- a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx +++ b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx @@ -79,6 +79,7 @@ import { MobileProfile, SplitView, } from "./components"; +import { BATCHES_AMOUNT_TO_PRELOAD } from "./constants"; import { useUserForProfile } from "./hooks"; import { checkShouldAutoOpenPreview, @@ -114,6 +115,7 @@ interface FeedLayoutProps { topFeedItems?: FeedLayoutItem[]; loading: boolean; shouldHideContent?: boolean; + batchNumber?: number; onFetchNext: (feedItemId?: string) => void; renderFeedItemBaseContent: (props: FeedItemBaseContentProps) => ReactNode; renderChatChannelItem?: (props: ChatChannelFeedLayoutItemProps) => ReactNode; @@ -153,6 +155,7 @@ const FeedLayout: ForwardRefRenderFunction = ( topFeedItems = [], loading, shouldHideContent = false, + batchNumber, onFetchNext, renderFeedItemBaseContent, renderChatChannelItem, @@ -603,6 +606,16 @@ const FeedLayout: ForwardRefRenderFunction = ( } }, [isTabletView, shouldAutoExpandItem, activeFeedItemId]); + useEffect(() => { + if ( + batchNumber && + batchNumber >= 1 && + batchNumber <= BATCHES_AMOUNT_TO_PRELOAD + ) { + onFetchNext(); + } + }, [batchNumber]); + useImperativeHandle( ref, () => ({ diff --git a/src/pages/commonFeed/components/FeedLayout/constants/index.ts b/src/pages/commonFeed/components/FeedLayout/constants/index.ts new file mode 100644 index 0000000000..7c420a58f4 --- /dev/null +++ b/src/pages/commonFeed/components/FeedLayout/constants/index.ts @@ -0,0 +1 @@ +export const BATCHES_AMOUNT_TO_PRELOAD = 2; diff --git a/src/shared/hooks/useCases/useCommonFeedItems.ts b/src/shared/hooks/useCases/useCommonFeedItems.ts index 0e6329195c..3a4a6c2f66 100644 --- a/src/shared/hooks/useCases/useCommonFeedItems.ts +++ b/src/shared/hooks/useCases/useCommonFeedItems.ts @@ -3,7 +3,8 @@ import { useDispatch, useSelector } from "react-redux"; import { CommonFeedService } from "@/services"; import { commonActions, FeedItems, selectFeedItems } from "@/store/states"; -interface Return extends Pick { +interface Return + extends Pick { fetch: (feedItemId?: string) => void; } diff --git a/src/store/states/common/actions.ts b/src/store/states/common/actions.ts index 406985d6f5..a83093fe8e 100644 --- a/src/store/states/common/actions.ts +++ b/src/store/states/common/actions.ts @@ -119,7 +119,7 @@ export const getFeedItems = createAsyncAction( feedItemId?: string; limit?: number; }, - Omit, + Omit, Error, string >(); diff --git a/src/store/states/common/reducer.ts b/src/store/states/common/reducer.ts index 150dd9154e..5e4b5fbd07 100644 --- a/src/store/states/common/reducer.ts +++ b/src/store/states/common/reducer.ts @@ -15,6 +15,7 @@ const initialFeedItems: FeedItems = { hasMore: false, firstDocTimestamp: null, lastDocTimestamp: null, + batchNumber: 0, }; const initialPinnedFeedItems: PinnedFeedItems = { @@ -428,6 +429,7 @@ export const reducer = createReducer(initialState) data: payloadData && (nextState.feedItems.data || []).concat(payloadData), loading: false, + batchNumber: nextState.feedItems.batchNumber + 1, }; }), ) diff --git a/src/store/states/common/types.ts b/src/store/states/common/types.ts index f3062a3622..ae0ff281ac 100644 --- a/src/store/states/common/types.ts +++ b/src/store/states/common/types.ts @@ -18,6 +18,7 @@ export interface FeedItems { hasMore: boolean; firstDocTimestamp: Timestamp | null; lastDocTimestamp: Timestamp | null; + batchNumber: number; } export interface PinnedFeedItems { From 88086293ba581cff9198e4cf9c33be9f1f436fa5 Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Mon, 30 Oct 2023 14:14:35 +0300 Subject: [PATCH 2/3] move infinite scroll marker higher for feed layout --- .../commonFeed/components/FeedLayout/FeedLayout.module.scss | 6 ++++++ src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx | 5 +++++ src/shared/ui-kit/InfiniteScroll/InfiniteScroll.tsx | 6 ++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/pages/commonFeed/components/FeedLayout/FeedLayout.module.scss b/src/pages/commonFeed/components/FeedLayout/FeedLayout.module.scss index d08805480b..8a8742305f 100644 --- a/src/pages/commonFeed/components/FeedLayout/FeedLayout.module.scss +++ b/src/pages/commonFeed/components/FeedLayout/FeedLayout.module.scss @@ -1,6 +1,7 @@ @import "../../../../styles/sizes"; .content { + position: relative; flex: 1; padding: 0 1.5rem; display: flex; @@ -17,6 +18,11 @@ justify-content: center; } +.infiniteScrollMarker { + position: absolute; + bottom: 50rem; +} + .emptyText { margin: 0; font-weight: 500; diff --git a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx index 406c85c93f..1ad096f4b4 100644 --- a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx +++ b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx @@ -653,6 +653,11 @@ const FeedLayout: ForwardRefRenderFunction = ( {topContent} {isContentEmpty &&

{emptyText}

} 7 + ? styles.infiniteScrollMarker + : "" + } onFetchNext={onFetchNext} isLoading={loading} loaderDelay={LOADER_APPEARANCE_DELAY} diff --git a/src/shared/ui-kit/InfiniteScroll/InfiniteScroll.tsx b/src/shared/ui-kit/InfiniteScroll/InfiniteScroll.tsx index 340946f68e..9f77049387 100644 --- a/src/shared/ui-kit/InfiniteScroll/InfiniteScroll.tsx +++ b/src/shared/ui-kit/InfiniteScroll/InfiniteScroll.tsx @@ -6,11 +6,13 @@ import styles from "./InfiniteScroll.module.scss"; interface InfiniteScrollProps { isLoading: boolean; loaderDelay?: number; + markerClassName?: string; onFetchNext: () => void; } const InfiniteScroll: FC = (props) => { - const { isLoading, loaderDelay, onFetchNext, children } = props; + const { isLoading, loaderDelay, markerClassName, onFetchNext, children } = + props; const [isInnerLoading, setIsInnerLoading] = useState(isLoading); const markerRef = useRef(null); const isMarkerOnScreen = useIntersectionObserver(markerRef.current); @@ -39,7 +41,7 @@ const InfiniteScroll: FC = (props) => { return ( <> {children} -
+
{isLoading && (
From df853d6be897c4f16f38d06c8b3c4a7237a16da8 Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Mon, 30 Oct 2023 14:37:11 +0300 Subject: [PATCH 3/3] add batch number to inbox items --- src/pages/inbox/BaseInbox.tsx | 2 ++ src/shared/hooks/useCases/useInboxItems.ts | 3 ++- src/store/states/inbox/actions.ts | 2 +- src/store/states/inbox/reducer.ts | 2 ++ src/store/states/inbox/types.ts | 1 + 5 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/pages/inbox/BaseInbox.tsx b/src/pages/inbox/BaseInbox.tsx index 1efb7696fb..95f1de212e 100644 --- a/src/pages/inbox/BaseInbox.tsx +++ b/src/pages/inbox/BaseInbox.tsx @@ -88,6 +88,7 @@ const InboxPage: FC = (props) => { loading: areInboxItemsLoading, hasMore: hasMoreInboxItems, fetch: fetchInboxItems, + batchNumber, } = useInboxItems(feedItemIdsForNotListening, { unread: queryParams.unread === "true", }); @@ -257,6 +258,7 @@ const InboxPage: FC = (props) => { feedItems={inboxItems} loading={areInboxItemsLoading || !user} shouldHideContent={!user} + batchNumber={batchNumber} onFetchNext={fetchMoreInboxItems} renderFeedItemBaseContent={renderFeedItemBaseContent} renderChatChannelItem={renderChatChannelItem} diff --git a/src/shared/hooks/useCases/useInboxItems.ts b/src/shared/hooks/useCases/useInboxItems.ts index 97f9d46af0..98c2426492 100644 --- a/src/shared/hooks/useCases/useInboxItems.ts +++ b/src/shared/hooks/useCases/useInboxItems.ts @@ -13,7 +13,8 @@ import { FeedLayoutItemWithFollowData } from "@/shared/interfaces"; import { FeedItemFollow, FeedItemFollowWithMetadata } from "@/shared/models"; import { inboxActions, InboxItems, selectInboxItems } from "@/store/states"; -interface Return extends Pick { +interface Return + extends Pick { fetch: () => void; } diff --git a/src/store/states/inbox/actions.ts b/src/store/states/inbox/actions.ts index 36ff292b4e..360ec377ed 100644 --- a/src/store/states/inbox/actions.ts +++ b/src/store/states/inbox/actions.ts @@ -16,7 +16,7 @@ export const getInboxItems = createAsyncAction( limit?: number; unread?: boolean; }, - Omit, + Omit, Error, string >(); diff --git a/src/store/states/inbox/reducer.ts b/src/store/states/inbox/reducer.ts index ef82ac6c60..55d625cfa3 100644 --- a/src/store/states/inbox/reducer.ts +++ b/src/store/states/inbox/reducer.ts @@ -20,6 +20,7 @@ const initialInboxItems: InboxItems = { hasMore: false, firstDocTimestamp: null, lastDocTimestamp: null, + batchNumber: 0, }; const initialState: InboxState = { @@ -432,6 +433,7 @@ export const reducer = createReducer(initialState) ...payload, data: payloadData && (nextState.items.data || []).concat(payloadData), loading: false, + batchNumber: nextState.items.batchNumber + 1, }; }), ) diff --git a/src/store/states/inbox/types.ts b/src/store/states/inbox/types.ts index 9851305f01..46e97b4137 100644 --- a/src/store/states/inbox/types.ts +++ b/src/store/states/inbox/types.ts @@ -10,6 +10,7 @@ export interface InboxItems { hasMore: boolean; firstDocTimestamp: Timestamp | null; lastDocTimestamp: Timestamp | null; + batchNumber: number; } export interface InboxState {