Consolidate List props a bit (#2216)
parent
987c543727
commit
bc31da47fd
|
@ -1,12 +1,5 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {
|
import {Dimensions, StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
|
||||||
Dimensions,
|
|
||||||
RefreshControl,
|
|
||||||
StyleProp,
|
|
||||||
StyleSheet,
|
|
||||||
View,
|
|
||||||
ViewStyle,
|
|
||||||
} from 'react-native'
|
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
import {List, ListRef} from '../util/List'
|
import {List, ListRef} from '../util/List'
|
||||||
import {FeedSourceCardLoaded} from './FeedSourceCard'
|
import {FeedSourceCardLoaded} from './FeedSourceCard'
|
||||||
|
@ -180,22 +173,14 @@ export const ProfileFeedgens = React.forwardRef<
|
||||||
data={items}
|
data={items}
|
||||||
keyExtractor={(item: any) => item._reactKey || item.uri}
|
keyExtractor={(item: any) => item._reactKey || item.uri}
|
||||||
renderItem={renderItemInner}
|
renderItem={renderItemInner}
|
||||||
refreshControl={
|
refreshing={isPTRing}
|
||||||
<RefreshControl
|
onRefresh={onRefresh}
|
||||||
refreshing={isPTRing}
|
headerOffset={headerOffset}
|
||||||
onRefresh={onRefresh}
|
|
||||||
tintColor={pal.colors.text}
|
|
||||||
titleColor={pal.colors.text}
|
|
||||||
progressViewOffset={headerOffset}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
contentContainerStyle={{
|
contentContainerStyle={{
|
||||||
minHeight: Dimensions.get('window').height * 1.5,
|
minHeight: Dimensions.get('window').height * 1.5,
|
||||||
}}
|
}}
|
||||||
style={{paddingTop: headerOffset}}
|
|
||||||
indicatorStyle={theme.colorScheme === 'dark' ? 'white' : 'black'}
|
indicatorStyle={theme.colorScheme === 'dark' ? 'white' : 'black'}
|
||||||
removeClippedSubviews={true}
|
removeClippedSubviews={true}
|
||||||
contentOffset={{x: 0, y: headerOffset * -1}}
|
|
||||||
// @ts-ignore our .web version only -prf
|
// @ts-ignore our .web version only -prf
|
||||||
desktopFixedHeight
|
desktopFixedHeight
|
||||||
onEndReached={onEndReached}
|
onEndReached={onEndReached}
|
||||||
|
|
|
@ -2,7 +2,6 @@ import React from 'react'
|
||||||
import {
|
import {
|
||||||
ActivityIndicator,
|
ActivityIndicator,
|
||||||
Dimensions,
|
Dimensions,
|
||||||
RefreshControl,
|
|
||||||
StyleProp,
|
StyleProp,
|
||||||
View,
|
View,
|
||||||
ViewStyle,
|
ViewStyle,
|
||||||
|
@ -15,7 +14,6 @@ import {LoadMoreRetryBtn} from '../util/LoadMoreRetryBtn'
|
||||||
import {ProfileCard} from '../profile/ProfileCard'
|
import {ProfileCard} from '../profile/ProfileCard'
|
||||||
import {Button} from '../util/forms/Button'
|
import {Button} from '../util/forms/Button'
|
||||||
import {useAnalytics} from 'lib/analytics/analytics'
|
import {useAnalytics} from 'lib/analytics/analytics'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
|
||||||
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||||
import {useListMembersQuery} from '#/state/queries/list-members'
|
import {useListMembersQuery} from '#/state/queries/list-members'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
|
@ -51,7 +49,6 @@ export function ListMembers({
|
||||||
headerOffset?: number
|
headerOffset?: number
|
||||||
desktopFixedHeightOffset?: number
|
desktopFixedHeightOffset?: number
|
||||||
}) {
|
}) {
|
||||||
const pal = usePalette('default')
|
|
||||||
const {track} = useAnalytics()
|
const {track} = useAnalytics()
|
||||||
const [isRefreshing, setIsRefreshing] = React.useState(false)
|
const [isRefreshing, setIsRefreshing] = React.useState(false)
|
||||||
const {isMobile} = useWebMediaQueries()
|
const {isMobile} = useWebMediaQueries()
|
||||||
|
@ -215,24 +212,16 @@ export function ListMembers({
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
ListHeaderComponent={renderHeader}
|
ListHeaderComponent={renderHeader}
|
||||||
ListFooterComponent={Footer}
|
ListFooterComponent={Footer}
|
||||||
refreshControl={
|
refreshing={isRefreshing}
|
||||||
<RefreshControl
|
onRefresh={onRefresh}
|
||||||
refreshing={isRefreshing}
|
headerOffset={headerOffset}
|
||||||
onRefresh={onRefresh}
|
|
||||||
tintColor={pal.colors.text}
|
|
||||||
titleColor={pal.colors.text}
|
|
||||||
progressViewOffset={headerOffset}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
contentContainerStyle={{
|
contentContainerStyle={{
|
||||||
minHeight: Dimensions.get('window').height * 1.5,
|
minHeight: Dimensions.get('window').height * 1.5,
|
||||||
}}
|
}}
|
||||||
style={{paddingTop: headerOffset}}
|
|
||||||
onScrolledDownChange={onScrolledDownChange}
|
onScrolledDownChange={onScrolledDownChange}
|
||||||
onEndReached={onEndReached}
|
onEndReached={onEndReached}
|
||||||
onEndReachedThreshold={0.6}
|
onEndReachedThreshold={0.6}
|
||||||
removeClippedSubviews={true}
|
removeClippedSubviews={true}
|
||||||
contentOffset={{x: 0, y: headerOffset * -1}}
|
|
||||||
// @ts-ignore our .web version only -prf
|
// @ts-ignore our .web version only -prf
|
||||||
desktopFixedHeight={desktopFixedHeightOffset || true}
|
desktopFixedHeight={desktopFixedHeightOffset || true}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -119,31 +119,51 @@ export function MyLists({
|
||||||
[error, onRefresh, renderItem, pal],
|
[error, onRefresh, renderItem, pal],
|
||||||
)
|
)
|
||||||
|
|
||||||
const FlatListCom = inline ? RNFlatList : List
|
if (inline) {
|
||||||
return (
|
return (
|
||||||
<View testID={testID} style={style}>
|
<View testID={testID} style={style}>
|
||||||
{items.length > 0 && (
|
{items.length > 0 && (
|
||||||
<FlatListCom
|
<RNFlatList
|
||||||
testID={testID ? `${testID}-flatlist` : undefined}
|
testID={testID ? `${testID}-flatlist` : undefined}
|
||||||
data={items}
|
data={items}
|
||||||
keyExtractor={item => (item.uri ? item.uri : item._reactKey)}
|
keyExtractor={item => (item.uri ? item.uri : item._reactKey)}
|
||||||
renderItem={renderItemInner}
|
renderItem={renderItemInner}
|
||||||
refreshControl={
|
refreshControl={
|
||||||
<RefreshControl
|
<RefreshControl
|
||||||
refreshing={isPTRing}
|
refreshing={isPTRing}
|
||||||
onRefresh={onRefresh}
|
onRefresh={onRefresh}
|
||||||
tintColor={pal.colors.text}
|
tintColor={pal.colors.text}
|
||||||
titleColor={pal.colors.text}
|
titleColor={pal.colors.text}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
contentContainerStyle={[s.contentContainer]}
|
contentContainerStyle={[s.contentContainer]}
|
||||||
removeClippedSubviews={true}
|
removeClippedSubviews={true}
|
||||||
// @ts-ignore our .web version only -prf
|
// @ts-ignore our .web version only -prf
|
||||||
desktopFixedHeight
|
desktopFixedHeight
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<View testID={testID} style={style}>
|
||||||
|
{items.length > 0 && (
|
||||||
|
<List
|
||||||
|
testID={testID ? `${testID}-flatlist` : undefined}
|
||||||
|
data={items}
|
||||||
|
keyExtractor={item => (item.uri ? item.uri : item._reactKey)}
|
||||||
|
renderItem={renderItemInner}
|
||||||
|
refreshing={isPTRing}
|
||||||
|
onRefresh={onRefresh}
|
||||||
|
contentContainerStyle={[s.contentContainer]}
|
||||||
|
removeClippedSubviews={true}
|
||||||
|
// @ts-ignore our .web version only -prf
|
||||||
|
desktopFixedHeight
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
|
|
|
@ -1,12 +1,5 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {
|
import {Dimensions, StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
|
||||||
Dimensions,
|
|
||||||
RefreshControl,
|
|
||||||
StyleProp,
|
|
||||||
StyleSheet,
|
|
||||||
View,
|
|
||||||
ViewStyle,
|
|
||||||
} from 'react-native'
|
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
import {List, ListRef} from '../util/List'
|
import {List, ListRef} from '../util/List'
|
||||||
import {ListCard} from './ListCard'
|
import {ListCard} from './ListCard'
|
||||||
|
@ -182,22 +175,14 @@ export const ProfileLists = React.forwardRef<SectionRef, ProfileListsProps>(
|
||||||
data={items}
|
data={items}
|
||||||
keyExtractor={(item: any) => item._reactKey}
|
keyExtractor={(item: any) => item._reactKey}
|
||||||
renderItem={renderItemInner}
|
renderItem={renderItemInner}
|
||||||
refreshControl={
|
refreshing={isPTRing}
|
||||||
<RefreshControl
|
onRefresh={onRefresh}
|
||||||
refreshing={isPTRing}
|
headerOffset={headerOffset}
|
||||||
onRefresh={onRefresh}
|
|
||||||
tintColor={pal.colors.text}
|
|
||||||
titleColor={pal.colors.text}
|
|
||||||
progressViewOffset={headerOffset}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
contentContainerStyle={{
|
contentContainerStyle={{
|
||||||
minHeight: Dimensions.get('window').height * 1.5,
|
minHeight: Dimensions.get('window').height * 1.5,
|
||||||
}}
|
}}
|
||||||
style={{paddingTop: headerOffset}}
|
|
||||||
indicatorStyle={theme.colorScheme === 'dark' ? 'white' : 'black'}
|
indicatorStyle={theme.colorScheme === 'dark' ? 'white' : 'black'}
|
||||||
removeClippedSubviews={true}
|
removeClippedSubviews={true}
|
||||||
contentOffset={{x: 0, y: headerOffset * -1}}
|
|
||||||
// @ts-ignore our .web version only -prf
|
// @ts-ignore our .web version only -prf
|
||||||
desktopFixedHeight
|
desktopFixedHeight
|
||||||
onEndReached={onEndReached}
|
onEndReached={onEndReached}
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {CenteredView} from '../util/Views'
|
import {CenteredView} from '../util/Views'
|
||||||
import {ActivityIndicator, RefreshControl, StyleSheet, View} from 'react-native'
|
import {ActivityIndicator, StyleSheet, View} from 'react-native'
|
||||||
import {FeedItem} from './FeedItem'
|
import {FeedItem} from './FeedItem'
|
||||||
import {NotificationFeedLoadingPlaceholder} from '../util/LoadingPlaceholder'
|
import {NotificationFeedLoadingPlaceholder} from '../util/LoadingPlaceholder'
|
||||||
import {ErrorMessage} from '../util/error/ErrorMessage'
|
import {ErrorMessage} from '../util/error/ErrorMessage'
|
||||||
import {LoadMoreRetryBtn} from '../util/LoadMoreRetryBtn'
|
import {LoadMoreRetryBtn} from '../util/LoadMoreRetryBtn'
|
||||||
import {EmptyState} from '../util/EmptyState'
|
import {EmptyState} from '../util/EmptyState'
|
||||||
import {s} from 'lib/styles'
|
import {s} from 'lib/styles'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
|
||||||
import {useNotificationFeedQuery} from '#/state/queries/notifications/feed'
|
import {useNotificationFeedQuery} from '#/state/queries/notifications/feed'
|
||||||
import {useUnreadNotificationsApi} from '#/state/queries/notifications/unread'
|
import {useUnreadNotificationsApi} from '#/state/queries/notifications/unread'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
|
@ -30,7 +29,6 @@ export function Feed({
|
||||||
onScrolledDownChange: (isScrolledDown: boolean) => void
|
onScrolledDownChange: (isScrolledDown: boolean) => void
|
||||||
ListHeaderComponent?: () => JSX.Element
|
ListHeaderComponent?: () => JSX.Element
|
||||||
}) {
|
}) {
|
||||||
const pal = usePalette('default')
|
|
||||||
const [isPTRing, setIsPTRing] = React.useState(false)
|
const [isPTRing, setIsPTRing] = React.useState(false)
|
||||||
|
|
||||||
const moderationOpts = useModerationOpts()
|
const moderationOpts = useModerationOpts()
|
||||||
|
@ -152,14 +150,8 @@ export function Feed({
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
ListHeaderComponent={ListHeaderComponent}
|
ListHeaderComponent={ListHeaderComponent}
|
||||||
ListFooterComponent={FeedFooter}
|
ListFooterComponent={FeedFooter}
|
||||||
refreshControl={
|
refreshing={isPTRing}
|
||||||
<RefreshControl
|
onRefresh={onRefresh}
|
||||||
refreshing={isPTRing}
|
|
||||||
onRefresh={onRefresh}
|
|
||||||
tintColor={pal.colors.text}
|
|
||||||
titleColor={pal.colors.text}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onEndReached={onEndReached}
|
onEndReached={onEndReached}
|
||||||
onEndReachedThreshold={0.6}
|
onEndReachedThreshold={0.6}
|
||||||
onScrolledDownChange={onScrolledDownChange}
|
onScrolledDownChange={onScrolledDownChange}
|
||||||
|
|
|
@ -1,18 +1,16 @@
|
||||||
import React, {useCallback, useMemo, useState} from 'react'
|
import React, {useCallback, useMemo, useState} from 'react'
|
||||||
import {ActivityIndicator, RefreshControl, StyleSheet, View} from 'react-native'
|
import {ActivityIndicator, StyleSheet, View} from 'react-native'
|
||||||
import {AppBskyFeedGetLikes as GetLikes} from '@atproto/api'
|
import {AppBskyFeedGetLikes as GetLikes} from '@atproto/api'
|
||||||
import {CenteredView} from '../util/Views'
|
import {CenteredView} from '../util/Views'
|
||||||
import {List} from '../util/List'
|
import {List} from '../util/List'
|
||||||
import {ErrorMessage} from '../util/error/ErrorMessage'
|
import {ErrorMessage} from '../util/error/ErrorMessage'
|
||||||
import {ProfileCardWithFollowBtn} from '../profile/ProfileCard'
|
import {ProfileCardWithFollowBtn} from '../profile/ProfileCard'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {useResolveUriQuery} from '#/state/queries/resolve-uri'
|
import {useResolveUriQuery} from '#/state/queries/resolve-uri'
|
||||||
import {usePostLikedByQuery} from '#/state/queries/post-liked-by'
|
import {usePostLikedByQuery} from '#/state/queries/post-liked-by'
|
||||||
import {cleanError} from '#/lib/strings/errors'
|
import {cleanError} from '#/lib/strings/errors'
|
||||||
|
|
||||||
export function PostLikedBy({uri}: {uri: string}) {
|
export function PostLikedBy({uri}: {uri: string}) {
|
||||||
const pal = usePalette('default')
|
|
||||||
const [isPTRing, setIsPTRing] = useState(false)
|
const [isPTRing, setIsPTRing] = useState(false)
|
||||||
const {
|
const {
|
||||||
data: resolvedUri,
|
data: resolvedUri,
|
||||||
|
@ -88,14 +86,8 @@ export function PostLikedBy({uri}: {uri: string}) {
|
||||||
<List
|
<List
|
||||||
data={likes}
|
data={likes}
|
||||||
keyExtractor={item => item.actor.did}
|
keyExtractor={item => item.actor.did}
|
||||||
refreshControl={
|
refreshing={isPTRing}
|
||||||
<RefreshControl
|
onRefresh={onRefresh}
|
||||||
refreshing={isPTRing}
|
|
||||||
onRefresh={onRefresh}
|
|
||||||
tintColor={pal.colors.text}
|
|
||||||
titleColor={pal.colors.text}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onEndReached={onEndReached}
|
onEndReached={onEndReached}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
initialNumToRender={15}
|
initialNumToRender={15}
|
||||||
|
|
|
@ -1,18 +1,16 @@
|
||||||
import React, {useMemo, useCallback, useState} from 'react'
|
import React, {useMemo, useCallback, useState} from 'react'
|
||||||
import {ActivityIndicator, RefreshControl, StyleSheet, View} from 'react-native'
|
import {ActivityIndicator, StyleSheet, View} from 'react-native'
|
||||||
import {AppBskyActorDefs as ActorDefs} from '@atproto/api'
|
import {AppBskyActorDefs as ActorDefs} from '@atproto/api'
|
||||||
import {CenteredView} from '../util/Views'
|
import {CenteredView} from '../util/Views'
|
||||||
import {List} from '../util/List'
|
import {List} from '../util/List'
|
||||||
import {ProfileCardWithFollowBtn} from '../profile/ProfileCard'
|
import {ProfileCardWithFollowBtn} from '../profile/ProfileCard'
|
||||||
import {ErrorMessage} from '../util/error/ErrorMessage'
|
import {ErrorMessage} from '../util/error/ErrorMessage'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {useResolveUriQuery} from '#/state/queries/resolve-uri'
|
import {useResolveUriQuery} from '#/state/queries/resolve-uri'
|
||||||
import {usePostRepostedByQuery} from '#/state/queries/post-reposted-by'
|
import {usePostRepostedByQuery} from '#/state/queries/post-reposted-by'
|
||||||
import {cleanError} from '#/lib/strings/errors'
|
import {cleanError} from '#/lib/strings/errors'
|
||||||
|
|
||||||
export function PostRepostedBy({uri}: {uri: string}) {
|
export function PostRepostedBy({uri}: {uri: string}) {
|
||||||
const pal = usePalette('default')
|
|
||||||
const [isPTRing, setIsPTRing] = useState(false)
|
const [isPTRing, setIsPTRing] = useState(false)
|
||||||
const {
|
const {
|
||||||
data: resolvedUri,
|
data: resolvedUri,
|
||||||
|
@ -89,14 +87,8 @@ export function PostRepostedBy({uri}: {uri: string}) {
|
||||||
<List
|
<List
|
||||||
data={repostedBy}
|
data={repostedBy}
|
||||||
keyExtractor={item => item.did}
|
keyExtractor={item => item.did}
|
||||||
refreshControl={
|
refreshing={isPTRing}
|
||||||
<RefreshControl
|
onRefresh={onRefresh}
|
||||||
refreshing={isPTRing}
|
|
||||||
onRefresh={onRefresh}
|
|
||||||
tintColor={pal.colors.text}
|
|
||||||
titleColor={pal.colors.text}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onEndReached={onEndReached}
|
onEndReached={onEndReached}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
initialNumToRender={15}
|
initialNumToRender={15}
|
||||||
|
|
|
@ -2,7 +2,6 @@ import React, {useEffect, useRef} from 'react'
|
||||||
import {
|
import {
|
||||||
ActivityIndicator,
|
ActivityIndicator,
|
||||||
Pressable,
|
Pressable,
|
||||||
RefreshControl,
|
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
TouchableOpacity,
|
TouchableOpacity,
|
||||||
View,
|
View,
|
||||||
|
@ -349,14 +348,8 @@ function PostThreadLoaded({
|
||||||
}
|
}
|
||||||
keyExtractor={item => item._reactKey}
|
keyExtractor={item => item._reactKey}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
refreshControl={
|
refreshing={isPTRing}
|
||||||
<RefreshControl
|
onRefresh={onPTR}
|
||||||
refreshing={isPTRing}
|
|
||||||
onRefresh={onPTR}
|
|
||||||
tintColor={pal.colors.text}
|
|
||||||
titleColor={pal.colors.text}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onContentSizeChange={onContentSizeChange}
|
onContentSizeChange={onContentSizeChange}
|
||||||
style={s.hContentRegion}
|
style={s.hContentRegion}
|
||||||
// @ts-ignore our .web version only -prf
|
// @ts-ignore our .web version only -prf
|
||||||
|
|
|
@ -3,7 +3,6 @@ import {
|
||||||
ActivityIndicator,
|
ActivityIndicator,
|
||||||
AppState,
|
AppState,
|
||||||
Dimensions,
|
Dimensions,
|
||||||
RefreshControl,
|
|
||||||
StyleProp,
|
StyleProp,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
View,
|
View,
|
||||||
|
@ -16,7 +15,6 @@ import {FeedErrorMessage} from './FeedErrorMessage'
|
||||||
import {FeedSlice} from './FeedSlice'
|
import {FeedSlice} from './FeedSlice'
|
||||||
import {LoadMoreRetryBtn} from '../util/LoadMoreRetryBtn'
|
import {LoadMoreRetryBtn} from '../util/LoadMoreRetryBtn'
|
||||||
import {useAnalytics} from 'lib/analytics/analytics'
|
import {useAnalytics} from 'lib/analytics/analytics'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
|
||||||
import {useTheme} from 'lib/ThemeContext'
|
import {useTheme} from 'lib/ThemeContext'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {
|
import {
|
||||||
|
@ -74,7 +72,6 @@ let Feed = ({
|
||||||
ListHeaderComponent?: () => JSX.Element
|
ListHeaderComponent?: () => JSX.Element
|
||||||
extraData?: any
|
extraData?: any
|
||||||
}): React.ReactNode => {
|
}): React.ReactNode => {
|
||||||
const pal = usePalette('default')
|
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const {track} = useAnalytics()
|
const {track} = useAnalytics()
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
|
@ -294,25 +291,17 @@ let Feed = ({
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
ListFooterComponent={FeedFooter}
|
ListFooterComponent={FeedFooter}
|
||||||
ListHeaderComponent={ListHeaderComponent}
|
ListHeaderComponent={ListHeaderComponent}
|
||||||
refreshControl={
|
refreshing={isPTRing}
|
||||||
<RefreshControl
|
onRefresh={onRefresh}
|
||||||
refreshing={isPTRing}
|
headerOffset={headerOffset}
|
||||||
onRefresh={onRefresh}
|
|
||||||
tintColor={pal.colors.text}
|
|
||||||
titleColor={pal.colors.text}
|
|
||||||
progressViewOffset={headerOffset}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
contentContainerStyle={{
|
contentContainerStyle={{
|
||||||
minHeight: Dimensions.get('window').height * 1.5,
|
minHeight: Dimensions.get('window').height * 1.5,
|
||||||
}}
|
}}
|
||||||
style={{paddingTop: headerOffset}}
|
|
||||||
onScrolledDownChange={onScrolledDownChange}
|
onScrolledDownChange={onScrolledDownChange}
|
||||||
indicatorStyle={theme.colorScheme === 'dark' ? 'white' : 'black'}
|
indicatorStyle={theme.colorScheme === 'dark' ? 'white' : 'black'}
|
||||||
onEndReached={onEndReached}
|
onEndReached={onEndReached}
|
||||||
onEndReachedThreshold={2} // number of posts left to trigger load more
|
onEndReachedThreshold={2} // number of posts left to trigger load more
|
||||||
removeClippedSubviews={true}
|
removeClippedSubviews={true}
|
||||||
contentOffset={{x: 0, y: headerOffset * -1}}
|
|
||||||
extraData={extraData}
|
extraData={extraData}
|
||||||
// @ts-ignore our .web version only -prf
|
// @ts-ignore our .web version only -prf
|
||||||
desktopFixedHeight={
|
desktopFixedHeight={
|
||||||
|
|
|
@ -1,18 +1,16 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {ActivityIndicator, RefreshControl, StyleSheet, View} from 'react-native'
|
import {ActivityIndicator, StyleSheet, View} from 'react-native'
|
||||||
import {AppBskyActorDefs as ActorDefs} from '@atproto/api'
|
import {AppBskyActorDefs as ActorDefs} from '@atproto/api'
|
||||||
import {CenteredView} from '../util/Views'
|
import {CenteredView} from '../util/Views'
|
||||||
import {List} from '../util/List'
|
import {List} from '../util/List'
|
||||||
import {ErrorMessage} from '../util/error/ErrorMessage'
|
import {ErrorMessage} from '../util/error/ErrorMessage'
|
||||||
import {ProfileCardWithFollowBtn} from './ProfileCard'
|
import {ProfileCardWithFollowBtn} from './ProfileCard'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
|
||||||
import {useProfileFollowersQuery} from '#/state/queries/profile-followers'
|
import {useProfileFollowersQuery} from '#/state/queries/profile-followers'
|
||||||
import {useResolveDidQuery} from '#/state/queries/resolve-uri'
|
import {useResolveDidQuery} from '#/state/queries/resolve-uri'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {cleanError} from '#/lib/strings/errors'
|
import {cleanError} from '#/lib/strings/errors'
|
||||||
|
|
||||||
export function ProfileFollowers({name}: {name: string}) {
|
export function ProfileFollowers({name}: {name: string}) {
|
||||||
const pal = usePalette('default')
|
|
||||||
const [isPTRing, setIsPTRing] = React.useState(false)
|
const [isPTRing, setIsPTRing] = React.useState(false)
|
||||||
const {
|
const {
|
||||||
data: resolvedDid,
|
data: resolvedDid,
|
||||||
|
@ -90,14 +88,8 @@ export function ProfileFollowers({name}: {name: string}) {
|
||||||
<List
|
<List
|
||||||
data={followers}
|
data={followers}
|
||||||
keyExtractor={item => item.did}
|
keyExtractor={item => item.did}
|
||||||
refreshControl={
|
refreshing={isPTRing}
|
||||||
<RefreshControl
|
onRefresh={onRefresh}
|
||||||
refreshing={isPTRing}
|
|
||||||
onRefresh={onRefresh}
|
|
||||||
tintColor={pal.colors.text}
|
|
||||||
titleColor={pal.colors.text}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onEndReached={onEndReached}
|
onEndReached={onEndReached}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
initialNumToRender={15}
|
initialNumToRender={15}
|
||||||
|
|
|
@ -1,18 +1,16 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {ActivityIndicator, RefreshControl, StyleSheet, View} from 'react-native'
|
import {ActivityIndicator, StyleSheet, View} from 'react-native'
|
||||||
import {AppBskyActorDefs as ActorDefs} from '@atproto/api'
|
import {AppBskyActorDefs as ActorDefs} from '@atproto/api'
|
||||||
import {CenteredView} from '../util/Views'
|
import {CenteredView} from '../util/Views'
|
||||||
import {List} from '../util/List'
|
import {List} from '../util/List'
|
||||||
import {ErrorMessage} from '../util/error/ErrorMessage'
|
import {ErrorMessage} from '../util/error/ErrorMessage'
|
||||||
import {ProfileCardWithFollowBtn} from './ProfileCard'
|
import {ProfileCardWithFollowBtn} from './ProfileCard'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
|
||||||
import {useProfileFollowsQuery} from '#/state/queries/profile-follows'
|
import {useProfileFollowsQuery} from '#/state/queries/profile-follows'
|
||||||
import {useResolveDidQuery} from '#/state/queries/resolve-uri'
|
import {useResolveDidQuery} from '#/state/queries/resolve-uri'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {cleanError} from '#/lib/strings/errors'
|
import {cleanError} from '#/lib/strings/errors'
|
||||||
|
|
||||||
export function ProfileFollows({name}: {name: string}) {
|
export function ProfileFollows({name}: {name: string}) {
|
||||||
const pal = usePalette('default')
|
|
||||||
const [isPTRing, setIsPTRing] = React.useState(false)
|
const [isPTRing, setIsPTRing] = React.useState(false)
|
||||||
const {
|
const {
|
||||||
data: resolvedDid,
|
data: resolvedDid,
|
||||||
|
@ -90,14 +88,8 @@ export function ProfileFollows({name}: {name: string}) {
|
||||||
<List
|
<List
|
||||||
data={follows}
|
data={follows}
|
||||||
keyExtractor={item => item.did}
|
keyExtractor={item => item.did}
|
||||||
refreshControl={
|
refreshing={isPTRing}
|
||||||
<RefreshControl
|
onRefresh={onRefresh}
|
||||||
refreshing={isPTRing}
|
|
||||||
onRefresh={onRefresh}
|
|
||||||
tintColor={pal.colors.text}
|
|
||||||
titleColor={pal.colors.text}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onEndReached={onEndReached}
|
onEndReached={onEndReached}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
initialNumToRender={15}
|
initialNumToRender={15}
|
||||||
|
|
|
@ -1,27 +1,42 @@
|
||||||
import React, {memo, startTransition} from 'react'
|
import React, {memo, startTransition} from 'react'
|
||||||
import {FlatListProps} from 'react-native'
|
import {FlatListProps, RefreshControl} from 'react-native'
|
||||||
import {FlatList_INTERNAL} from './Views'
|
import {FlatList_INTERNAL} from './Views'
|
||||||
|
import {addStyle} from 'lib/styles'
|
||||||
import {useScrollHandlers} from '#/lib/ScrollContext'
|
import {useScrollHandlers} from '#/lib/ScrollContext'
|
||||||
import {runOnJS, useSharedValue} from 'react-native-reanimated'
|
import {runOnJS, useSharedValue} from 'react-native-reanimated'
|
||||||
import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIXED'
|
import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIXED'
|
||||||
|
import {usePalette} from '#/lib/hooks/usePalette'
|
||||||
|
|
||||||
export type ListMethods = FlatList_INTERNAL
|
export type ListMethods = FlatList_INTERNAL
|
||||||
export type ListProps<ItemT> = Omit<
|
export type ListProps<ItemT> = Omit<
|
||||||
FlatListProps<ItemT>,
|
FlatListProps<ItemT>,
|
||||||
'onScroll' // Use ScrollContext instead.
|
| 'onScroll' // Use ScrollContext instead.
|
||||||
|
| 'refreshControl' // Pass refreshing and/or onRefresh instead.
|
||||||
|
| 'contentOffset' // Pass headerOffset instead.
|
||||||
> & {
|
> & {
|
||||||
onScrolledDownChange?: (isScrolledDown: boolean) => void
|
onScrolledDownChange?: (isScrolledDown: boolean) => void
|
||||||
|
headerOffset?: number
|
||||||
|
refreshing?: boolean
|
||||||
|
onRefresh?: () => void
|
||||||
}
|
}
|
||||||
export type ListRef = React.MutableRefObject<FlatList_INTERNAL | null>
|
export type ListRef = React.MutableRefObject<FlatList_INTERNAL | null>
|
||||||
|
|
||||||
const SCROLLED_DOWN_LIMIT = 200
|
const SCROLLED_DOWN_LIMIT = 200
|
||||||
|
|
||||||
function ListImpl<ItemT>(
|
function ListImpl<ItemT>(
|
||||||
{onScrolledDownChange, ...props}: ListProps<ItemT>,
|
{
|
||||||
|
onScrolledDownChange,
|
||||||
|
refreshing,
|
||||||
|
onRefresh,
|
||||||
|
headerOffset,
|
||||||
|
style,
|
||||||
|
...props
|
||||||
|
}: ListProps<ItemT>,
|
||||||
ref: React.Ref<ListMethods>,
|
ref: React.Ref<ListMethods>,
|
||||||
) {
|
) {
|
||||||
const isScrolledDown = useSharedValue(false)
|
const isScrolledDown = useSharedValue(false)
|
||||||
const contextScrollHandlers = useScrollHandlers()
|
const contextScrollHandlers = useScrollHandlers()
|
||||||
|
const pal = usePalette('default')
|
||||||
|
|
||||||
function handleScrolledDownChange(didScrollDown: boolean) {
|
function handleScrolledDownChange(didScrollDown: boolean) {
|
||||||
startTransition(() => {
|
startTransition(() => {
|
||||||
|
@ -49,12 +64,36 @@ function ListImpl<ItemT>(
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let refreshControl
|
||||||
|
if (refreshing !== undefined || onRefresh !== undefined) {
|
||||||
|
refreshControl = (
|
||||||
|
<RefreshControl
|
||||||
|
refreshing={refreshing ?? false}
|
||||||
|
onRefresh={onRefresh}
|
||||||
|
tintColor={pal.colors.text}
|
||||||
|
titleColor={pal.colors.text}
|
||||||
|
progressViewOffset={headerOffset}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let contentOffset
|
||||||
|
if (headerOffset != null) {
|
||||||
|
style = addStyle(style, {
|
||||||
|
paddingTop: headerOffset,
|
||||||
|
})
|
||||||
|
contentOffset = {x: 0, y: headerOffset * -1}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FlatList_INTERNAL
|
<FlatList_INTERNAL
|
||||||
{...props}
|
{...props}
|
||||||
scrollIndicatorInsets={{right: 1}}
|
scrollIndicatorInsets={{right: 1}}
|
||||||
|
contentOffset={contentOffset}
|
||||||
|
refreshControl={refreshControl}
|
||||||
onScroll={scrollHandler}
|
onScroll={scrollHandler}
|
||||||
scrollEventThrottle={1}
|
scrollEventThrottle={1}
|
||||||
|
style={style}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {ActivityIndicator, StyleSheet, View, RefreshControl} from 'react-native'
|
import {ActivityIndicator, StyleSheet, View} from 'react-native'
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||||
import {FontAwesomeIconStyle} from '@fortawesome/react-native-fontawesome'
|
import {FontAwesomeIconStyle} from '@fortawesome/react-native-fontawesome'
|
||||||
import {ViewHeader} from 'view/com/util/ViewHeader'
|
import {ViewHeader} from 'view/com/util/ViewHeader'
|
||||||
|
@ -487,14 +487,8 @@ export function FeedsScreen(_props: Props) {
|
||||||
keyExtractor={item => item.key}
|
keyExtractor={item => item.key}
|
||||||
contentContainerStyle={styles.contentContainer}
|
contentContainerStyle={styles.contentContainer}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
refreshControl={
|
refreshing={isPTR}
|
||||||
<RefreshControl
|
onRefresh={isUserSearching ? undefined : onPullToRefresh}
|
||||||
refreshing={isPTR}
|
|
||||||
onRefresh={isUserSearching ? undefined : onPullToRefresh}
|
|
||||||
tintColor={pal.colors.text}
|
|
||||||
titleColor={pal.colors.text}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
initialNumToRender={10}
|
initialNumToRender={10}
|
||||||
onEndReached={onEndReached}
|
onEndReached={onEndReached}
|
||||||
// @ts-ignore our .web version only -prf
|
// @ts-ignore our .web version only -prf
|
||||||
|
|
|
@ -3,7 +3,6 @@ import {
|
||||||
View,
|
View,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
ActivityIndicator,
|
ActivityIndicator,
|
||||||
RefreshControl,
|
|
||||||
TextInput,
|
TextInput,
|
||||||
Pressable,
|
Pressable,
|
||||||
Platform,
|
Platform,
|
||||||
|
@ -185,7 +184,6 @@ type SearchResultSlice =
|
||||||
|
|
||||||
function SearchScreenPostResults({query}: {query: string}) {
|
function SearchScreenPostResults({query}: {query: string}) {
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const pal = usePalette('default')
|
|
||||||
const [isPTR, setIsPTR] = React.useState(false)
|
const [isPTR, setIsPTR] = React.useState(false)
|
||||||
const {
|
const {
|
||||||
isFetched,
|
isFetched,
|
||||||
|
@ -254,14 +252,8 @@ function SearchScreenPostResults({query}: {query: string}) {
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
keyExtractor={item => item.key}
|
keyExtractor={item => item.key}
|
||||||
refreshControl={
|
refreshing={isPTR}
|
||||||
<RefreshControl
|
onRefresh={onPullToRefresh}
|
||||||
refreshing={isPTR}
|
|
||||||
onRefresh={onPullToRefresh}
|
|
||||||
tintColor={pal.colors.text}
|
|
||||||
titleColor={pal.colors.text}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
onEndReached={onEndReached}
|
onEndReached={onEndReached}
|
||||||
// @ts-ignore web only -prf
|
// @ts-ignore web only -prf
|
||||||
desktopFixedHeight
|
desktopFixedHeight
|
||||||
|
|
Loading…
Reference in New Issue