address claude review feedback
- thread subject into add mutation so starter pack cache stays fresh - rename RQKEY to createListsWithMembershipQueryKey with object arg - show loader footer while paginating lists - guard empty state on resolved data - drop unnecessary useCallback (react compiler) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
import {useCallback} from 'react'
|
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {Trans, useLingui} from '@lingui/react/macro'
|
import {Trans, useLingui} from '@lingui/react/macro'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
@@ -96,31 +95,28 @@ function ListsContent({
|
|||||||
|
|
||||||
const listItems = data?.pages.flatMap(page => page.listsWithMembership) || []
|
const listItems = data?.pages.flatMap(page => page.listsWithMembership) || []
|
||||||
|
|
||||||
const onEndReached = useCallback(async () => {
|
const onEndReached = async () => {
|
||||||
if (isFetchingNextPage || !hasNextPage || isError) return
|
if (isFetchingNextPage || !hasNextPage || isError) return
|
||||||
try {
|
try {
|
||||||
await fetchNextPage()
|
await fetchNextPage()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Error handling is optional since this is just pagination
|
// Error handling is optional since this is just pagination
|
||||||
}
|
}
|
||||||
}, [isFetchingNextPage, hasNextPage, isError, fetchNextPage])
|
}
|
||||||
|
|
||||||
const renderItem = useCallback(
|
const renderItem = ({item}: {item: ListWithMembership}) =>
|
||||||
({item}: {item: ListWithMembership}) =>
|
profile ? (
|
||||||
profile ? (
|
<ListItem
|
||||||
<ListItem
|
listWithMembership={item}
|
||||||
listWithMembership={item}
|
profile={profile}
|
||||||
profile={profile}
|
onAdd={onAdd}
|
||||||
onAdd={onAdd}
|
onRemove={onRemove}
|
||||||
onRemove={onRemove}
|
/>
|
||||||
/>
|
) : null
|
||||||
) : null,
|
|
||||||
[profile, onAdd, onRemove],
|
|
||||||
)
|
|
||||||
|
|
||||||
const onClose = useCallback(() => {
|
const onClose = () => {
|
||||||
control.close()
|
control.close()
|
||||||
}, [control])
|
}
|
||||||
|
|
||||||
const listHeader = (
|
const listHeader = (
|
||||||
<View
|
<View
|
||||||
@@ -174,7 +170,14 @@ function ListsContent({
|
|||||||
onEndReached={() => void onEndReached()}
|
onEndReached={() => void onEndReached()}
|
||||||
onEndReachedThreshold={0.1}
|
onEndReachedThreshold={0.1}
|
||||||
ListHeaderComponent={listHeader}
|
ListHeaderComponent={listHeader}
|
||||||
ListEmptyComponent={<Empty />}
|
ListFooterComponent={
|
||||||
|
isFetchingNextPage ? (
|
||||||
|
<View style={[a.align_center, a.py_lg]}>
|
||||||
|
<Loader size="lg" />
|
||||||
|
</View>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
ListEmptyComponent={!isLoading && data ? <Empty /> : null}
|
||||||
style={platform({
|
style={platform({
|
||||||
web: [a.px_2xl, {minHeight: 400}],
|
web: [a.px_2xl, {minHeight: 400}],
|
||||||
native: [a.px_2xl, a.pt_lg],
|
native: [a.px_2xl, a.pt_lg],
|
||||||
@@ -205,6 +208,7 @@ function ListItem({
|
|||||||
|
|
||||||
const {mutate: addMembership, isPending: isPendingAdd} =
|
const {mutate: addMembership, isPending: isPendingAdd} =
|
||||||
useListMembershipAddMutation({
|
useListMembershipAddMutation({
|
||||||
|
subject: profile,
|
||||||
onSuccess: data => {
|
onSuccess: data => {
|
||||||
Toast.show(l`Added to list`)
|
Toast.show(l`Added to list`)
|
||||||
onAdd?.(list.uri)
|
onAdd?.(list.uri)
|
||||||
@@ -249,7 +253,7 @@ function ListItem({
|
|||||||
|
|
||||||
const isPending = isPendingAdd || isPendingRemove
|
const isPending = isPendingAdd || isPendingRemove
|
||||||
|
|
||||||
const handleToggleMembership = useCallback(() => {
|
const handleToggleMembership = () => {
|
||||||
if (isPending) return
|
if (isPending) return
|
||||||
|
|
||||||
if (!isMember) {
|
if (!isMember) {
|
||||||
@@ -268,15 +272,7 @@ function ListItem({
|
|||||||
membershipUri: listItem.uri,
|
membershipUri: listItem.uri,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}, [
|
}
|
||||||
list.uri,
|
|
||||||
profile.did,
|
|
||||||
isMember,
|
|
||||||
listItem,
|
|
||||||
isPending,
|
|
||||||
addMembership,
|
|
||||||
removeMembership,
|
|
||||||
])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
|
|||||||
@@ -15,8 +15,9 @@ import {useAgent} from '#/state/session'
|
|||||||
export type ListWithMembership =
|
export type ListWithMembership =
|
||||||
AppBskyGraphGetListsWithMembership.ListWithMembership
|
AppBskyGraphGetListsWithMembership.ListWithMembership
|
||||||
|
|
||||||
const RQKEY_ROOT = 'lists-with-membership'
|
const listsWithMembershipQueryKeyRoot = 'lists-with-membership'
|
||||||
export const RQKEY = (actor: string) => createQueryKey(RQKEY_ROOT, {actor})
|
export const createListsWithMembershipQueryKey = (args: {actor: string}) =>
|
||||||
|
createQueryKey(listsWithMembershipQueryKeyRoot, args)
|
||||||
|
|
||||||
export function useListsWithMembershipQuery({
|
export function useListsWithMembershipQuery({
|
||||||
actor,
|
actor,
|
||||||
@@ -34,7 +35,7 @@ export function useListsWithMembershipQuery({
|
|||||||
QueryKey,
|
QueryKey,
|
||||||
string | undefined
|
string | undefined
|
||||||
>({
|
>({
|
||||||
queryKey: RQKEY(actor ?? ''),
|
queryKey: createListsWithMembershipQueryKey({actor: actor ?? ''}),
|
||||||
queryFn: async ({pageParam}: {pageParam?: string}) => {
|
queryFn: async ({pageParam}: {pageParam?: string}) => {
|
||||||
const res = await agent.app.bsky.graph.getListsWithMembership({
|
const res = await agent.app.bsky.graph.getListsWithMembership({
|
||||||
actor: actor!, // the enabled flag prevents this from running until actor is set
|
actor: actor!, // the enabled flag prevents this from running until actor is set
|
||||||
@@ -64,7 +65,7 @@ export function updateListMembershipOptimistically({
|
|||||||
}) {
|
}) {
|
||||||
queryClient.setQueryData<
|
queryClient.setQueryData<
|
||||||
InfiniteData<AppBskyGraphGetListsWithMembership.OutputSchema>
|
InfiniteData<AppBskyGraphGetListsWithMembership.OutputSchema>
|
||||||
>(RQKEY(actor), old => {
|
>(createListsWithMembershipQueryKey({actor}), old => {
|
||||||
if (!old) return old
|
if (!old) return old
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -99,7 +100,7 @@ export function removeListMembershipOptimistically({
|
|||||||
}) {
|
}) {
|
||||||
queryClient.setQueryData<
|
queryClient.setQueryData<
|
||||||
InfiniteData<AppBskyGraphGetListsWithMembership.OutputSchema>
|
InfiniteData<AppBskyGraphGetListsWithMembership.OutputSchema>
|
||||||
>(RQKEY(actor), old => {
|
>(createListsWithMembershipQueryKey({actor}), old => {
|
||||||
if (!old) return old
|
if (!old) return old
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user