diff options
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/Error.tsx | 4 | ||||
-rw-r--r-- | src/components/LikedByList.tsx | 96 | ||||
-rw-r--r-- | src/components/Lists.tsx | 56 |
3 files changed, 74 insertions, 82 deletions
diff --git a/src/components/Error.tsx b/src/components/Error.tsx index 7df166c3f..91b33f48e 100644 --- a/src/components/Error.tsx +++ b/src/components/Error.tsx @@ -1,9 +1,9 @@ import React from 'react' import {View} from 'react-native' -import {useNavigation} from '@react-navigation/core' -import {StackActions} from '@react-navigation/native' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' +import {useNavigation} from '@react-navigation/core' +import {StackActions} from '@react-navigation/native' import {NavigationProp} from 'lib/routes/types' import {CenteredView} from 'view/com/util/Views' diff --git a/src/components/LikedByList.tsx b/src/components/LikedByList.tsx index bd1213639..239a7044f 100644 --- a/src/components/LikedByList.tsx +++ b/src/components/LikedByList.tsx @@ -1,47 +1,54 @@ import React from 'react' -import {View} from 'react-native' import {AppBskyFeedGetLikes as GetLikes} from '@atproto/api' -import {Trans} from '@lingui/macro' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' import {logger} from '#/logger' -import {List} from '#/view/com/util/List' -import {ProfileCardWithFollowBtn} from '#/view/com/profile/ProfileCard' -import {useResolveUriQuery} from '#/state/queries/resolve-uri' import {useLikedByQuery} from '#/state/queries/post-liked-by' +import {useResolveUriQuery} from '#/state/queries/resolve-uri' import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender' -import {ListFooter} from '#/components/Lists' +import {cleanError} from 'lib/strings/errors' +import {ProfileCardWithFollowBtn} from '#/view/com/profile/ProfileCard' +import {List} from '#/view/com/util/List' +import {ListFooter, ListMaybePlaceholder} from '#/components/Lists' -import {atoms as a, useTheme} from '#/alf' -import {Loader} from '#/components/Loader' -import {Text} from '#/components/Typography' +function renderItem({item}: {item: GetLikes.Like}) { + return <ProfileCardWithFollowBtn key={item.actor.did} profile={item.actor} /> +} + +function keyExtractor(item: GetLikes.Like) { + return item.actor.did +} export function LikedByList({uri}: {uri: string}) { - const t = useTheme() + const {_} = useLingui() + const initialNumToRender = useInitialNumToRender() const [isPTRing, setIsPTRing] = React.useState(false) + const { data: resolvedUri, error: resolveError, - isFetching: isFetchingResolvedUri, + isLoading: isUriLoading, } = useResolveUriQuery(uri) const { data, - isFetching, - isFetched, - isRefetching, + isLoading: isLikedByLoading, + isFetchingNextPage, hasNextPage, fetchNextPage, - isError, error: likedByError, refetch, } = useLikedByQuery(resolvedUri?.uri) + + const error = resolveError || likedByError + const isError = !!resolveError || !!likedByError + const likes = React.useMemo(() => { if (data?.pages) { return data.pages.flatMap(page => page.likes) } return [] }, [data]) - const initialNumToRender = useInitialNumToRender() - const error = resolveError || likedByError const onRefresh = React.useCallback(async () => { setIsPTRing(true) @@ -54,56 +61,47 @@ export function LikedByList({uri}: {uri: string}) { }, [refetch, setIsPTRing]) const onEndReached = React.useCallback(async () => { - if (isFetching || !hasNextPage || isError) return + if (isFetchingNextPage || !hasNextPage || isError) return try { await fetchNextPage() } catch (err) { logger.error('Failed to load more likes', {message: err}) } - }, [isFetching, hasNextPage, isError, fetchNextPage]) - - const renderItem = React.useCallback(({item}: {item: GetLikes.Like}) => { - return ( - <ProfileCardWithFollowBtn key={item.actor.did} profile={item.actor} /> - ) - }, []) + }, [isFetchingNextPage, hasNextPage, isError, fetchNextPage]) - if (isFetchingResolvedUri || !isFetched) { + if (likes.length < 1) { return ( - <View style={[a.w_full, a.align_center, a.p_lg]}> - <Loader size="xl" /> - </View> + <ListMaybePlaceholder + isLoading={isUriLoading || isLikedByLoading} + isError={isError} + emptyType="results" + emptyMessage={_( + msg`Nobody has liked this yet. Maybe you should be the first!`, + )} + errorMessage={cleanError(resolveError || error)} + onRetry={isError ? refetch : undefined} + /> ) } - return likes.length ? ( + return ( <List data={likes} - keyExtractor={item => item.actor.did} + renderItem={renderItem} + keyExtractor={keyExtractor} refreshing={isPTRing} onRefresh={onRefresh} onEndReached={onEndReached} - onEndReachedThreshold={3} - renderItem={renderItem} - initialNumToRender={initialNumToRender} - ListFooterComponent={() => ( + ListFooterComponent={ <ListFooter - isFetching={isFetching && !isRefetching} - isError={isError} - error={error ? error.toString() : undefined} + isFetchingNextPage={isFetchingNextPage} + error={cleanError(error)} onRetry={fetchNextPage} /> - )} + } + onEndReachedThreshold={3} + initialNumToRender={initialNumToRender} + windowSize={11} /> - ) : ( - <View style={[a.p_lg]}> - <View style={[a.p_lg, a.rounded_sm, t.atoms.bg_contrast_25]}> - <Text style={[a.text_md, a.leading_snug]}> - <Trans> - Nobody has liked this yet. Maybe you should be the first! - </Trans> - </Text> - </View> - </View> ) } diff --git a/src/components/Lists.tsx b/src/components/Lists.tsx index d3e072028..605626fef 100644 --- a/src/components/Lists.tsx +++ b/src/components/Lists.tsx @@ -1,25 +1,23 @@ import React from 'react' -import {atoms as a, useBreakpoints, useTheme} from '#/alf' import {View} from 'react-native' +import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {Trans, msg} from '@lingui/macro' -import {CenteredView} from 'view/com/util/Views' -import {Loader} from '#/components/Loader' import {cleanError} from 'lib/strings/errors' +import {CenteredView} from 'view/com/util/Views' +import {atoms as a, useBreakpoints, useTheme} from '#/alf' import {Button} from '#/components/Button' -import {Text} from '#/components/Typography' import {Error} from '#/components/Error' +import {Loader} from '#/components/Loader' +import {Text} from '#/components/Typography' export function ListFooter({ - isFetching, - isError, + isFetchingNextPage, error, onRetry, height, }: { - isFetching?: boolean - isError?: boolean + isFetchingNextPage?: boolean error?: string onRetry?: () => Promise<unknown> height?: number @@ -36,32 +34,26 @@ export function ListFooter({ t.atoms.border_contrast_low, {height: height ?? 180, paddingTop: 30}, ]}> - {isFetching ? ( + {isFetchingNextPage ? ( <Loader size="xl" /> ) : ( - <ListFooterMaybeError - isError={isError} - error={error} - onRetry={onRetry} - /> + <ListFooterMaybeError error={error} onRetry={onRetry} /> )} </View> ) } function ListFooterMaybeError({ - isError, error, onRetry, }: { - isError?: boolean error?: string onRetry?: () => Promise<unknown> }) { const t = useTheme() const {_} = useLingui() - if (!isError) return null + if (!error) return null return ( <View style={[a.w_full, a.px_lg]}> @@ -128,7 +120,7 @@ export function ListHeaderDesktop({ export function ListMaybePlaceholder({ isLoading, - isEmpty, + noEmpty, isError, emptyTitle, emptyMessage, @@ -138,7 +130,7 @@ export function ListMaybePlaceholder({ onRetry, }: { isLoading: boolean - isEmpty?: boolean + noEmpty?: boolean isError?: boolean emptyTitle?: string emptyMessage?: string @@ -151,16 +143,6 @@ export function ListMaybePlaceholder({ const {_} = useLingui() const {gtMobile, gtTablet} = useBreakpoints() - if (!isLoading && isError) { - return ( - <Error - title={errorTitle ?? _(msg`Oops!`)} - message={errorMessage ?? _(`Something went wrong!`)} - onRetry={onRetry} - /> - ) - } - if (isLoading) { return ( <CenteredView @@ -180,7 +162,17 @@ export function ListMaybePlaceholder({ ) } - if (isEmpty) { + if (isError) { + return ( + <Error + title={errorTitle ?? _(msg`Oops!`)} + message={errorMessage ?? _(`Something went wrong!`)} + onRetry={onRetry} + /> + ) + } + + if (!noEmpty) { return ( <Error title={ @@ -197,4 +189,6 @@ export function ListMaybePlaceholder({ /> ) } + + return null } |