Skip to content

Commit 5b8631d

Browse files
authored
Fix profile lists/feeds/starterpacks tabs position issue (#8935)
1 parent 5be753e commit 5b8631d

File tree

5 files changed

+250
-233
lines changed

5 files changed

+250
-233
lines changed

src/components/StarterPack/ProfileStarterPacks.tsx

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
import React, {
2-
useCallback,
3-
useEffect,
4-
useImperativeHandle,
5-
useState,
6-
} from 'react'
1+
import {useCallback, useEffect, useImperativeHandle, useState} from 'react'
72
import {
83
findNodeHandle,
94
type ListRenderItemInfo,
105
type StyleProp,
6+
useWindowDimensions,
117
View,
128
type ViewStyle,
139
} from 'react-native'
@@ -42,6 +38,7 @@ interface SectionRef {
4238
}
4339

4440
interface ProfileFeedgensProps {
41+
ref?: React.Ref<SectionRef>
4542
scrollElRef: ListRef
4643
did: string
4744
headerOffset: number
@@ -56,24 +53,20 @@ function keyExtractor(item: AppBskyGraphDefs.StarterPackView) {
5653
return item.uri
5754
}
5855

59-
export const ProfileStarterPacks = React.forwardRef<
60-
SectionRef,
61-
ProfileFeedgensProps
62-
>(function ProfileFeedgensImpl(
63-
{
64-
scrollElRef,
65-
did,
66-
headerOffset,
67-
enabled,
68-
style,
69-
testID,
70-
setScrollViewTag,
71-
isMe,
72-
},
56+
export function ProfileStarterPacks({
7357
ref,
74-
) {
58+
scrollElRef,
59+
did,
60+
headerOffset,
61+
enabled,
62+
style,
63+
testID,
64+
setScrollViewTag,
65+
isMe,
66+
}: ProfileFeedgensProps) {
7567
const t = useTheme()
7668
const bottomBarOffset = useBottomBarOffset(100)
69+
const {height} = useWindowDimensions()
7770
const [isPTRing, setIsPTRing] = useState(false)
7871
const {
7972
data,
@@ -101,7 +94,7 @@ export const ProfileStarterPacks = React.forwardRef<
10194
setIsPTRing(false)
10295
}, [refetch, setIsPTRing])
10396

104-
const onEndReached = React.useCallback(async () => {
97+
const onEndReached = useCallback(async () => {
10598
if (isFetchingNextPage || !hasNextPage || isError) return
10699
try {
107100
await fetchNextPage()
@@ -144,7 +137,10 @@ export const ProfileStarterPacks = React.forwardRef<
144137
refreshing={isPTRing}
145138
headerOffset={headerOffset}
146139
progressViewOffset={ios(0)}
147-
contentContainerStyle={{paddingBottom: headerOffset + bottomBarOffset}}
140+
contentContainerStyle={{
141+
minHeight: height + headerOffset,
142+
paddingBottom: bottomBarOffset,
143+
}}
148144
removeClippedSubviews={true}
149145
desktopFixedHeight
150146
onEndReached={onEndReached}
@@ -158,7 +154,7 @@ export const ProfileStarterPacks = React.forwardRef<
158154
/>
159155
</View>
160156
)
161-
})
157+
}
162158

163159
function CreateAnother() {
164160
const {_} = useLingui()

src/screens/Profile/Sections/Feed.tsx

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react'
1+
import {useCallback, useEffect, useImperativeHandle, useState} from 'react'
22
import {findNodeHandle, View} from 'react-native'
33
import {msg, Trans} from '@lingui/macro'
44
import {useLingui} from '@lingui/react'
@@ -18,38 +18,34 @@ import {Text} from '#/components/Typography'
1818
import {type SectionRef} from './types'
1919

2020
interface FeedSectionProps {
21+
ref?: React.Ref<SectionRef>
2122
feed: FeedDescriptor
2223
headerHeight: number
2324
isFocused: boolean
2425
scrollElRef: ListRef
2526
ignoreFilterFor?: string
2627
setScrollViewTag: (tag: number | null) => void
2728
}
28-
export const ProfileFeedSection = React.forwardRef<
29-
SectionRef,
30-
FeedSectionProps
31-
>(function FeedSectionImpl(
32-
{
33-
feed,
34-
headerHeight,
35-
isFocused,
36-
scrollElRef,
37-
ignoreFilterFor,
38-
setScrollViewTag,
39-
},
29+
export function ProfileFeedSection({
4030
ref,
41-
) {
31+
feed,
32+
headerHeight,
33+
isFocused,
34+
scrollElRef,
35+
ignoreFilterFor,
36+
setScrollViewTag,
37+
}: FeedSectionProps) {
4238
const {_} = useLingui()
4339
const queryClient = useQueryClient()
44-
const [hasNew, setHasNew] = React.useState(false)
45-
const [isScrolledDown, setIsScrolledDown] = React.useState(false)
40+
const [hasNew, setHasNew] = useState(false)
41+
const [isScrolledDown, setIsScrolledDown] = useState(false)
4642
const shouldUseAdjustedNumToRender = feed.endsWith('posts_and_author_threads')
4743
const isVideoFeed = isNative && feed.endsWith('posts_with_video')
4844
const adjustedInitialNumToRender = useInitialNumToRender({
4945
screenHeightOffset: headerHeight,
5046
})
5147

52-
const onScrollToTop = React.useCallback(() => {
48+
const onScrollToTop = useCallback(() => {
5349
scrollElRef.current?.scrollToOffset({
5450
animated: isNative,
5551
offset: -headerHeight,
@@ -58,15 +54,15 @@ export const ProfileFeedSection = React.forwardRef<
5854
setHasNew(false)
5955
}, [scrollElRef, headerHeight, queryClient, feed, setHasNew])
6056

61-
React.useImperativeHandle(ref, () => ({
57+
useImperativeHandle(ref, () => ({
6258
scrollToTop: onScrollToTop,
6359
}))
6460

65-
const renderPostsEmpty = React.useCallback(() => {
61+
const renderPostsEmpty = useCallback(() => {
6662
return <EmptyState icon="growth" message={_(msg`No posts yet.`)} />
6763
}, [_])
6864

69-
React.useEffect(() => {
65+
useEffect(() => {
7066
if (isIOS && isFocused && scrollElRef.current) {
7167
const nativeTag = findNodeHandle(scrollElRef.current)
7268
setScrollViewTag(nativeTag)
@@ -101,7 +97,7 @@ export const ProfileFeedSection = React.forwardRef<
10197
)}
10298
</View>
10399
)
104-
})
100+
}
105101

106102
function ProfileEndOfFeed() {
107103
const t = useTheme()

src/screens/Profile/Sections/Labels.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ interface LabelsSectionProps {
3333
isFocused: boolean
3434
setScrollViewTag: (tag: number | null) => void
3535
}
36+
3637
export function ProfileLabelsSection({
3738
ref,
3839
isLabelerLoading,

src/view/com/feeds/ProfileFeedgens.tsx

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1-
import React from 'react'
1+
import {
2+
useCallback,
3+
useEffect,
4+
useImperativeHandle,
5+
useMemo,
6+
useState,
7+
} from 'react'
28
import {
39
findNodeHandle,
410
type ListRenderItemInfo,
511
type StyleProp,
12+
useWindowDimensions,
613
View,
714
type ViewStyle,
815
} from 'react-native'
@@ -34,6 +41,7 @@ interface SectionRef {
3441
}
3542

3643
interface ProfileFeedgensProps {
44+
ref?: React.Ref<SectionRef>
3745
did: string
3846
scrollElRef: ListRef
3947
headerOffset: number
@@ -43,17 +51,21 @@ interface ProfileFeedgensProps {
4351
setScrollViewTag: (tag: number | null) => void
4452
}
4553

46-
export const ProfileFeedgens = React.forwardRef<
47-
SectionRef,
48-
ProfileFeedgensProps
49-
>(function ProfileFeedgensImpl(
50-
{did, scrollElRef, headerOffset, enabled, style, testID, setScrollViewTag},
54+
export function ProfileFeedgens({
5155
ref,
52-
) {
56+
did,
57+
scrollElRef,
58+
headerOffset,
59+
enabled,
60+
style,
61+
testID,
62+
setScrollViewTag,
63+
}: ProfileFeedgensProps) {
5364
const {_} = useLingui()
5465
const t = useTheme()
55-
const [isPTRing, setIsPTRing] = React.useState(false)
56-
const opts = React.useMemo(() => ({enabled}), [enabled])
66+
const [isPTRing, setIsPTRing] = useState(false)
67+
const {height} = useWindowDimensions()
68+
const opts = useMemo(() => ({enabled}), [enabled])
5769
const {
5870
data,
5971
isPending,
@@ -67,7 +79,7 @@ export const ProfileFeedgens = React.forwardRef<
6779
const isEmpty = !isPending && !data?.pages[0]?.feeds.length
6880
const {data: preferences} = usePreferencesQuery()
6981

70-
const items = React.useMemo(() => {
82+
const items = useMemo(() => {
7183
let items: any[] = []
7284
if (isError && isEmpty) {
7385
items = items.concat([ERROR_ITEM])
@@ -91,19 +103,19 @@ export const ProfileFeedgens = React.forwardRef<
91103

92104
const queryClient = useQueryClient()
93105

94-
const onScrollToTop = React.useCallback(() => {
106+
const onScrollToTop = useCallback(() => {
95107
scrollElRef.current?.scrollToOffset({
96108
animated: isNative,
97109
offset: -headerOffset,
98110
})
99111
queryClient.invalidateQueries({queryKey: RQKEY(did)})
100112
}, [scrollElRef, queryClient, headerOffset, did])
101113

102-
React.useImperativeHandle(ref, () => ({
114+
useImperativeHandle(ref, () => ({
103115
scrollToTop: onScrollToTop,
104116
}))
105117

106-
const onRefresh = React.useCallback(async () => {
118+
const onRefresh = useCallback(async () => {
107119
setIsPTRing(true)
108120
try {
109121
await refetch()
@@ -113,7 +125,7 @@ export const ProfileFeedgens = React.forwardRef<
113125
setIsPTRing(false)
114126
}, [refetch, setIsPTRing])
115127

116-
const onEndReached = React.useCallback(async () => {
128+
const onEndReached = useCallback(async () => {
117129
if (isFetchingNextPage || !hasNextPage || isError) return
118130

119131
try {
@@ -123,14 +135,14 @@ export const ProfileFeedgens = React.forwardRef<
123135
}
124136
}, [isFetchingNextPage, hasNextPage, isError, fetchNextPage])
125137

126-
const onPressRetryLoadMore = React.useCallback(() => {
138+
const onPressRetryLoadMore = useCallback(() => {
127139
fetchNextPage()
128140
}, [fetchNextPage])
129141

130142
// rendering
131143
// =
132144

133-
const renderItem = React.useCallback(
145+
const renderItem = useCallback(
134146
({item, index}: ListRenderItemInfo<any>) => {
135147
if (item === EMPTY) {
136148
return (
@@ -174,14 +186,14 @@ export const ProfileFeedgens = React.forwardRef<
174186
[_, t, error, refetch, onPressRetryLoadMore, preferences],
175187
)
176188

177-
React.useEffect(() => {
189+
useEffect(() => {
178190
if (isIOS && enabled && scrollElRef.current) {
179191
const nativeTag = findNodeHandle(scrollElRef.current)
180192
setScrollViewTag(nativeTag)
181193
}
182194
}, [enabled, scrollElRef, setScrollViewTag])
183195

184-
const ProfileFeedgensFooter = React.useCallback(() => {
196+
const ProfileFeedgensFooter = useCallback(() => {
185197
if (isEmpty) return null
186198
return (
187199
<ListFooter
@@ -217,10 +229,11 @@ export const ProfileFeedgens = React.forwardRef<
217229
removeClippedSubviews={true}
218230
desktopFixedHeight
219231
onEndReached={onEndReached}
232+
contentContainerStyle={{minHeight: height + headerOffset}}
220233
/>
221234
</View>
222235
)
223-
})
236+
}
224237

225238
function keyExtractor(item: any) {
226239
return item._reactKey || item.uri

0 commit comments

Comments
 (0)