@@ -993,9 +993,41 @@ export function useUnfollowMutationForUser(handle: string, onSuccess: () => void
993
993
} ;
994
994
} ) ;
995
995
996
- // Invalidate the follows query cache for the account performing the unfollow
997
- const accountFollowsQueryKey = QUERY_KEYS . accountFollows ( handle , 'following' ) ;
998
- queryClient . invalidateQueries ( { queryKey : accountFollowsQueryKey } ) ;
996
+ const followingHandle = handle === 'index' ? 'me' : handle ;
997
+ const accountFollowsQueryKey = QUERY_KEYS . accountFollows ( followingHandle , 'following' ) ;
998
+ const existingData = queryClient . getQueryData ( accountFollowsQueryKey ) ;
999
+
1000
+ // Update the following list cache if it exists, otherwise invalidate
1001
+ if ( existingData ) {
1002
+ queryClient . setQueryData ( accountFollowsQueryKey , ( oldData ?: {
1003
+ pages : Array < {
1004
+ accounts : Array < {
1005
+ id : string ;
1006
+ name : string ;
1007
+ handle : string ;
1008
+ avatarUrl : string ;
1009
+ blockedByMe : boolean ;
1010
+ domainBlockedByMe : boolean ;
1011
+ isFollowing : boolean ;
1012
+ } > ;
1013
+ } > ;
1014
+ } ) => {
1015
+ if ( ! oldData ?. pages ) {
1016
+ return oldData ;
1017
+ }
1018
+
1019
+ return {
1020
+ ...oldData ,
1021
+ pages : oldData . pages . map ( page => ( {
1022
+ ...page ,
1023
+ accounts : page . accounts . filter ( account => account . handle !== fullHandle )
1024
+ } ) )
1025
+ } ;
1026
+ } ) ;
1027
+ } else {
1028
+ // Cache doesn't exist, invalidate to fetch fresh data when needed
1029
+ queryClient . invalidateQueries ( { queryKey : accountFollowsQueryKey } ) ;
1030
+ }
999
1031
1000
1032
// Update explore profiles cache
1001
1033
queryClient . setQueryData ( QUERY_KEYS . exploreProfiles ( handle ) , ( current : { pages : Array < { results : Record < string , { categoryName : string ; sites : Account [ ] } > } > } | undefined ) => {
@@ -1109,12 +1141,55 @@ export function useFollowMutationForUser(handle: string, onSuccess: () => void,
1109
1141
1110
1142
const profileFollowersQueryKey = QUERY_KEYS . accountFollows ( fullHandle , 'followers' ) ;
1111
1143
1112
- // Invalidate the follows query cache for the account performing the follow
1113
- // because we cannot directly add to it due to potentially incompatible data
1114
- // shapes
1115
- const accountFollowsQueryKey = QUERY_KEYS . accountFollows ( handle , 'following' ) ;
1144
+ const followingHandle = handle === 'index' ? 'me' : handle ;
1145
+ const accountFollowsQueryKey = QUERY_KEYS . accountFollows ( followingHandle , 'following' ) ;
1146
+ const existingData = queryClient . getQueryData ( accountFollowsQueryKey ) ;
1147
+
1148
+ // Update the following list cache if it exists, otherwise invalidate
1149
+ if ( existingData ) {
1150
+ queryClient . setQueryData ( accountFollowsQueryKey , ( oldData ?: {
1151
+ pages : Array < {
1152
+ accounts : Array < {
1153
+ id : string ;
1154
+ name : string ;
1155
+ handle : string ;
1156
+ avatarUrl : string ;
1157
+ blockedByMe : boolean ;
1158
+ domainBlockedByMe : boolean ;
1159
+ isFollowing : boolean ;
1160
+ } > ;
1161
+ } > ;
1162
+ } ) => {
1163
+ if ( ! oldData ?. pages ?. [ 0 ] ) {
1164
+ return oldData ;
1165
+ }
1166
+
1167
+ const followedAccount = queryClient . getQueryData < Account > ( QUERY_KEYS . account ( fullHandle === 'me' ? 'index' : fullHandle ) ) ;
1168
+ if ( ! followedAccount ) {
1169
+ return oldData ;
1170
+ }
1116
1171
1117
- queryClient . invalidateQueries ( { queryKey : accountFollowsQueryKey } ) ;
1172
+ const newFollowing = {
1173
+ id : followedAccount . id ,
1174
+ name : followedAccount . name ,
1175
+ handle : followedAccount . handle ,
1176
+ avatarUrl : followedAccount . avatarUrl ,
1177
+ blockedByMe : followedAccount . blockedByMe ,
1178
+ domainBlockedByMe : followedAccount . domainBlockedByMe ,
1179
+ isFollowing : true
1180
+ } ;
1181
+
1182
+ return {
1183
+ ...oldData ,
1184
+ pages : [ {
1185
+ ...oldData . pages [ 0 ] ,
1186
+ accounts : [ newFollowing , ...oldData . pages [ 0 ] . accounts ]
1187
+ } , ...oldData . pages . slice ( 1 ) ]
1188
+ } ;
1189
+ } ) ;
1190
+ } else {
1191
+ queryClient . invalidateQueries ( { queryKey : accountFollowsQueryKey } ) ;
1192
+ }
1118
1193
1119
1194
// Update explore profiles cache
1120
1195
queryClient . setQueryData ( QUERY_KEYS . exploreProfiles ( handle ) , ( current : { pages : Array < { results : Record < string , { categoryName : string ; sites : Account [ ] } > } > } | undefined ) => {
@@ -1506,13 +1581,24 @@ export function useAccountForUser(handle: string, profileHandle: string) {
1506
1581
}
1507
1582
1508
1583
export function useAccountFollowsForUser ( profileHandle : string , type : AccountFollowsType ) {
1584
+ const queryClient = useQueryClient ( ) ;
1585
+
1509
1586
return useInfiniteQuery ( {
1510
1587
queryKey : QUERY_KEYS . accountFollows ( profileHandle , type ) ,
1511
1588
async queryFn ( { pageParam} : { pageParam ?: string } ) {
1512
1589
const siteUrl = await getSiteUrl ( ) ;
1513
1590
const api = createActivityPubAPI ( 'index' , siteUrl ) ;
1514
1591
1515
- return api . getAccountFollows ( profileHandle , type , pageParam ) ;
1592
+ const response = await api . getAccountFollows ( profileHandle , type , pageParam ) ;
1593
+
1594
+ // Cache individual account data for follow mutations
1595
+ if ( response . accounts ) {
1596
+ response . accounts . forEach ( ( account ) => {
1597
+ queryClient . setQueryData ( QUERY_KEYS . account ( account . handle ) , account ) ;
1598
+ } ) ;
1599
+ }
1600
+
1601
+ return response ;
1516
1602
} ,
1517
1603
getNextPageParam ( prevPage ) {
1518
1604
return prevPage . next ;
@@ -2374,6 +2460,11 @@ export function useExploreProfilesForUser(handle: string) {
2374
2460
const fetchExploreProfilesFromJSON = useCallback ( async ( ) => {
2375
2461
const accounts = await fetchAndFilterAccounts ( ) ;
2376
2462
2463
+ // Cache account data for follow mutations
2464
+ accounts . forEach ( ( account : Account ) => {
2465
+ queryClient . setQueryData ( QUERY_KEYS . account ( account . handle ) , account ) ;
2466
+ } ) ;
2467
+
2377
2468
const results = {
2378
2469
uncategorized : {
2379
2470
categoryName : 'Recommended' ,
@@ -2385,7 +2476,7 @@ export function useExploreProfilesForUser(handle: string) {
2385
2476
results,
2386
2477
nextPage : undefined
2387
2478
} ;
2388
- } , [ fetchAndFilterAccounts ] ) ;
2479
+ } , [ fetchAndFilterAccounts , queryClient ] ) ;
2389
2480
2390
2481
const exploreProfilesQuery = useInfiniteQuery ( {
2391
2482
queryKey,
@@ -2454,6 +2545,13 @@ export function useSuggestedProfilesForUser(handle: string, limit = 3) {
2454
2545
. sort ( ( ) => Math . random ( ) - 0.5 )
2455
2546
. slice ( 0 , limit ) ;
2456
2547
2548
+ // Cache account data for follow mutations
2549
+ if ( randomAccounts . length > 0 ) {
2550
+ randomAccounts . forEach ( ( account : Account ) => {
2551
+ queryClient . setQueryData ( QUERY_KEYS . account ( account . handle ) , account ) ;
2552
+ } ) ;
2553
+ }
2554
+
2457
2555
return randomAccounts . length > 0 ? randomAccounts : null ;
2458
2556
} ,
2459
2557
retry : false ,
0 commit comments