about summary refs log tree commit diff
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/Error.tsx4
-rw-r--r--src/components/LikedByList.tsx96
-rw-r--r--src/components/Lists.tsx56
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
 }