Skip to content

Commit 91306e3

Browse files
committed
feat: implement auto-scroll to entry after pull-up navigation
1 parent bf7193d commit 91306e3

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

apps/mobile/src/modules/entry-list/EntryListSelector.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
import { FeedViewType } from "@follow/constants"
22
import { useWhoami } from "@follow/store/user/hooks"
33
import type { FlashList } from "@shopify/flash-list"
4+
import type { RefObject } from "react"
45
import { useEffect } from "react"
56

67
import { useGeneralSettingKey } from "@/src/atoms/settings/general"
78
import { withErrorBoundary } from "@/src/components/common/ErrorBoundary"
89
import { NoLoginInfo } from "@/src/components/common/NoLoginInfo"
910
import { ListErrorView } from "@/src/components/errors/ListErrorView"
1011
import { useRegisterNavigationScrollView } from "@/src/components/layouts/tabbar/hooks"
12+
import { useNavigation } from "@/src/lib/navigation/hooks"
1113
import { EntryListContentPicture } from "@/src/modules/entry-list/EntryListContentPicture"
14+
import { EntryDetailScreen } from "@/src/screens/(stack)/entries/[entryId]/EntryDetailScreen"
1215

1316
import { useFetchEntriesControls } from "../screen/atoms"
1417
import { EntryListContentArticle } from "./EntryListContentArticle"
@@ -69,6 +72,8 @@ function EntryListSelectorImpl({ entryIds, viewId, active = true }: EntryListSel
6972
}
7073
}, [isRefetching, ref])
7174

75+
useAutoScrollToEntryAfterPullUpToNext(ref, entryIds || [])
76+
7277
return <ContentComponent ref={ref} entryIds={entryIds} active={active} view={viewId} />
7378
}
7479

@@ -82,3 +87,32 @@ export const EntryListSelector = withErrorBoundary(
8287
},
8388
ListErrorView,
8489
)
90+
91+
const useAutoScrollToEntryAfterPullUpToNext = (
92+
ref: RefObject<FlashList<any> | null>,
93+
entryIds: string[],
94+
) => {
95+
const navigation = useNavigation()
96+
useEffect(() => {
97+
return navigation.on("screenChange", (payload) => {
98+
if (!payload.route) return
99+
if (payload.type !== "appear") return
100+
if (payload.route.Component !== EntryDetailScreen) return
101+
if (payload.route.screenOptions?.stackAnimation !== "fade_from_bottom") return
102+
const nextEntryId =
103+
payload.route.props &&
104+
typeof payload.route.props === "object" &&
105+
"entryId" in payload.route.props &&
106+
typeof payload.route.props.entryId === "string"
107+
? payload.route.props.entryId
108+
: undefined
109+
const idx = nextEntryId ? (entryIds?.indexOf(nextEntryId || "") ?? -1) : -1
110+
if (idx === -1) return
111+
ref?.current?.scrollToIndex({
112+
index: idx,
113+
animated: false,
114+
viewOffset: 70,
115+
})
116+
})
117+
}, [entryIds, navigation, ref])
118+
}

0 commit comments

Comments
 (0)