From 6abd7ac5bb79d628c29b85a3dcba2c08fc609ccf Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Thu, 4 Jun 2026 11:46:05 +0300 Subject: [PATCH] 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) --- .../lists/UserAddRemoveListsDialog.tsx | 52 +++++++++---------- src/state/queries/lists-with-membership.ts | 11 ++-- 2 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/components/dialogs/lists/UserAddRemoveListsDialog.tsx b/src/components/dialogs/lists/UserAddRemoveListsDialog.tsx index 4d5f939dcc..d3eb725383 100644 --- a/src/components/dialogs/lists/UserAddRemoveListsDialog.tsx +++ b/src/components/dialogs/lists/UserAddRemoveListsDialog.tsx @@ -1,4 +1,3 @@ -import {useCallback} from 'react' import {View} from 'react-native' import {Trans, useLingui} from '@lingui/react/macro' import {useQueryClient} from '@tanstack/react-query' @@ -96,31 +95,28 @@ function ListsContent({ const listItems = data?.pages.flatMap(page => page.listsWithMembership) || [] - const onEndReached = useCallback(async () => { + const onEndReached = async () => { if (isFetchingNextPage || !hasNextPage || isError) return try { await fetchNextPage() } catch (err) { // Error handling is optional since this is just pagination } - }, [isFetchingNextPage, hasNextPage, isError, fetchNextPage]) + } - const renderItem = useCallback( - ({item}: {item: ListWithMembership}) => - profile ? ( - - ) : null, - [profile, onAdd, onRemove], - ) + const renderItem = ({item}: {item: ListWithMembership}) => + profile ? ( + + ) : null - const onClose = useCallback(() => { + const onClose = () => { control.close() - }, [control]) + } const listHeader = ( void onEndReached()} onEndReachedThreshold={0.1} ListHeaderComponent={listHeader} - ListEmptyComponent={} + ListFooterComponent={ + isFetchingNextPage ? ( + + + + ) : null + } + ListEmptyComponent={!isLoading && data ? : null} style={platform({ web: [a.px_2xl, {minHeight: 400}], native: [a.px_2xl, a.pt_lg], @@ -205,6 +208,7 @@ function ListItem({ const {mutate: addMembership, isPending: isPendingAdd} = useListMembershipAddMutation({ + subject: profile, onSuccess: data => { Toast.show(l`Added to list`) onAdd?.(list.uri) @@ -249,7 +253,7 @@ function ListItem({ const isPending = isPendingAdd || isPendingRemove - const handleToggleMembership = useCallback(() => { + const handleToggleMembership = () => { if (isPending) return if (!isMember) { @@ -268,15 +272,7 @@ function ListItem({ membershipUri: listItem.uri, }) } - }, [ - list.uri, - profile.did, - isMember, - listItem, - isPending, - addMembership, - removeMembership, - ]) + } return ( createQueryKey(RQKEY_ROOT, {actor}) +const listsWithMembershipQueryKeyRoot = 'lists-with-membership' +export const createListsWithMembershipQueryKey = (args: {actor: string}) => + createQueryKey(listsWithMembershipQueryKeyRoot, args) export function useListsWithMembershipQuery({ actor, @@ -34,7 +35,7 @@ export function useListsWithMembershipQuery({ QueryKey, string | undefined >({ - queryKey: RQKEY(actor ?? ''), + queryKey: createListsWithMembershipQueryKey({actor: actor ?? ''}), queryFn: async ({pageParam}: {pageParam?: string}) => { const res = await agent.app.bsky.graph.getListsWithMembership({ actor: actor!, // the enabled flag prevents this from running until actor is set @@ -64,7 +65,7 @@ export function updateListMembershipOptimistically({ }) { queryClient.setQueryData< InfiniteData - >(RQKEY(actor), old => { + >(createListsWithMembershipQueryKey({actor}), old => { if (!old) return old return { @@ -99,7 +100,7 @@ export function removeListMembershipOptimistically({ }) { queryClient.setQueryData< InfiniteData - >(RQKEY(actor), old => { + >(createListsWithMembershipQueryKey({actor}), old => { if (!old) return old return {