1
0
mirror of https://github.com/DocNR/POWR.git synced 2025-05-16 11:15:51 +00:00
POWR/lib/hooks/useProfileWithQuery.ts
DocNR c64ca8bf19 fix: profile stats loading and display issues on iOS and Android
- Enhanced NostrBandService with aggressive cache-busting and better error handling
- Improved useProfileStats hook with optimized refresh settings and platform-specific logging
- Fixed ProfileFollowerStats UI to show actual values with loading indicators
- Added visual feedback during refresh operations
- Updated CHANGELOG.md to document these improvements

This resolves the issue where follower/following counts were not updating properly
on Android and iOS platforms.
2025-04-04 15:46:31 -04:00

142 lines
3.5 KiB
TypeScript

import { useCallback } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { QUERY_KEYS } from '@/lib/queryKeys';
import { useAuthQuery } from './useAuthQuery';
import NDK, { NDKEvent, NDKUser } from '@nostr-dev-kit/ndk-mobile';
interface ProfileData {
profile?: {
displayName?: string;
name?: string;
about?: string;
website?: string;
picture?: string;
banner?: string;
nip05?: string;
lud16?: string;
};
pubkey: string;
raw?: NDKEvent;
lastUpdated?: number;
}
interface ProfileUpdateParams {
displayName?: string;
name?: string;
about?: string;
website?: string;
picture?: string;
banner?: string;
nip05?: string;
lud16?: string;
}
/**
* useProfileWithQuery Hook
*
* React Query-based hook for fetching and updating user profiles
*
* Features:
* - Fetch profile data for the authenticated user or any pubkey
* - Update the user's profile
* - Optimistic updates
* - Automatic revalidation
*/
export function useProfileWithQuery(pubkey?: string) {
const queryClient = useQueryClient();
const { user, isAuthenticated } = useAuthQuery();
// Use the provided pubkey, or the authenticated user's pubkey if not provided
const targetPubkey = pubkey || user?.pubkey;
const isSelf = isAuthenticated && user?.pubkey === targetPubkey;
// No pubkey available - return placeholder state
if (!targetPubkey) {
return {
profile: undefined,
isLoading: false,
isError: false,
error: undefined,
isUpdating: false,
updateProfile: async () => {
throw new Error('Cannot update profile without a pubkey');
},
};
}
// Query for profile data
const {
data: profile,
isLoading,
isError,
error,
refetch
} = useQuery({
queryKey: QUERY_KEYS.auth.profile(targetPubkey),
queryFn: async (): Promise<ProfileData> => {
// Basic implementation - in reality, this would fetch from NDK and SQLite
return {
pubkey: targetPubkey,
profile: {
displayName: targetPubkey.slice(0, 8),
about: 'Profile fetched with React Query',
},
lastUpdated: Date.now(),
};
},
staleTime: 5 * 60 * 1000, // 5 minutes
enabled: !!targetPubkey,
});
// Mutation for updating profile
const { mutateAsync, isPending: isUpdating } = useMutation({
mutationFn: async (params: ProfileUpdateParams): Promise<ProfileData> => {
if (!isSelf) {
throw new Error('Cannot update profile of another user');
}
// In a real implementation, this would create and publish a kind 0 event
console.log('[useProfileWithQuery] Updating profile:', params);
// Return the updated profile (optimistically)
return {
pubkey: targetPubkey,
profile: {
...profile?.profile,
...params,
},
lastUpdated: Date.now(),
};
},
onSuccess: (data) => {
// Update the profile in the cache
queryClient.setQueryData(
QUERY_KEYS.auth.profile(targetPubkey),
data
);
},
});
// Update profile function
const updateProfile = useCallback(
async (params: ProfileUpdateParams) => {
if (!isSelf) {
throw new Error('Cannot update profile of another user');
}
return await mutateAsync(params);
},
[isSelf, mutateAsync]
);
return {
profile,
isLoading,
isError,
error,
isUpdating,
updateProfile,
refetch,
};
}