2025-03-22 23:21:26 -04:00
|
|
|
// app/(tabs)/profile/overview.tsx
|
2025-04-04 22:43:03 -04:00
|
|
|
import React, { useState, useCallback } from 'react';
|
|
|
|
import { View, ActivityIndicator } from 'react-native';
|
2025-03-22 23:21:26 -04:00
|
|
|
import { Text } from '@/components/ui/text';
|
|
|
|
import { Button } from '@/components/ui/button';
|
2025-04-01 21:28:50 -04:00
|
|
|
import NostrProfileLogin from '@/components/social/NostrProfileLogin';
|
2025-04-04 22:43:03 -04:00
|
|
|
import ProfileFeed from '@/components/profile/ProfileFeed';
|
|
|
|
import { useProfilePageData } from '@/lib/hooks/useProfilePageData';
|
|
|
|
import type { AnyFeedEntry } from '@/types/feed';
|
2025-03-22 23:21:26 -04:00
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
/**
|
|
|
|
* Profile overview screen - refactored for consistent hook ordering
|
|
|
|
* This component now uses the useProfilePageData hook to handle all data fetching
|
|
|
|
* and state management, avoiding hook ordering issues.
|
|
|
|
*/
|
2025-03-22 23:21:26 -04:00
|
|
|
export default function OverviewScreen() {
|
2025-04-04 22:43:03 -04:00
|
|
|
// Use our custom hook for all data needs (always calls hooks in same order)
|
|
|
|
const {
|
|
|
|
isAuthenticated,
|
|
|
|
currentUser,
|
|
|
|
stats,
|
|
|
|
bannerImage,
|
|
|
|
feed,
|
|
|
|
renderState,
|
|
|
|
renderError,
|
|
|
|
refreshAll,
|
|
|
|
setRenderError
|
|
|
|
} = useProfilePageData();
|
|
|
|
|
|
|
|
// Track refreshing state
|
2025-04-02 21:11:25 -04:00
|
|
|
const [isRefreshing, setIsRefreshing] = useState(false);
|
2025-03-28 10:18:44 -07:00
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
// Handle refresh
|
2025-03-22 23:21:26 -04:00
|
|
|
const handleRefresh = useCallback(async () => {
|
|
|
|
setIsRefreshing(true);
|
|
|
|
try {
|
2025-04-04 22:43:03 -04:00
|
|
|
await refreshAll();
|
2025-03-22 23:21:26 -04:00
|
|
|
} finally {
|
|
|
|
setIsRefreshing(false);
|
|
|
|
}
|
2025-04-04 22:43:03 -04:00
|
|
|
}, [refreshAll]);
|
2025-03-22 23:21:26 -04:00
|
|
|
|
|
|
|
// Handle post selection
|
|
|
|
const handlePostPress = useCallback((entry: AnyFeedEntry) => {
|
|
|
|
// Just log the entry info for now
|
|
|
|
console.log(`Selected ${entry.type}:`, entry);
|
|
|
|
}, []);
|
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
// Render the login screen
|
2025-03-29 17:47:10 -07:00
|
|
|
const renderLoginScreen = useCallback(() => {
|
|
|
|
return (
|
2025-04-01 21:28:50 -04:00
|
|
|
<NostrProfileLogin message="Login with your Nostr private key to view your profile and posts." />
|
2025-03-29 17:47:10 -07:00
|
|
|
);
|
2025-04-01 21:28:50 -04:00
|
|
|
}, []);
|
2025-03-29 17:47:10 -07:00
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
// Render loading screen
|
2025-03-29 17:47:10 -07:00
|
|
|
const renderLoadingScreen = useCallback(() => {
|
2025-03-22 23:21:26 -04:00
|
|
|
return (
|
|
|
|
<View className="flex-1 items-center justify-center">
|
|
|
|
<ActivityIndicator />
|
|
|
|
</View>
|
|
|
|
);
|
2025-03-29 17:47:10 -07:00
|
|
|
}, []);
|
2025-03-22 23:21:26 -04:00
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
// Render error screen
|
|
|
|
const renderErrorScreen = useCallback(() => {
|
2025-04-04 18:00:20 -04:00
|
|
|
return (
|
|
|
|
<View className="flex-1 items-center justify-center p-4">
|
|
|
|
<Text className="text-lg font-bold mb-2">Something went wrong</Text>
|
|
|
|
<Text className="text-sm text-muted-foreground mb-4 text-center">
|
2025-04-04 22:43:03 -04:00
|
|
|
{renderError?.message || "We had trouble loading your profile. Please try again."}
|
2025-04-04 18:00:20 -04:00
|
|
|
</Text>
|
|
|
|
<Button
|
|
|
|
onPress={() => {
|
|
|
|
setRenderError(null);
|
|
|
|
handleRefresh();
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
Retry
|
|
|
|
</Button>
|
|
|
|
</View>
|
|
|
|
);
|
2025-04-04 22:43:03 -04:00
|
|
|
}, [renderError, handleRefresh, setRenderError]);
|
2025-04-04 18:00:20 -04:00
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
// Render the main content
|
|
|
|
const renderMainContent = useCallback(() => {
|
|
|
|
// Create a wrapper for the stats refresh function to match expected Promise<void> type
|
|
|
|
const refreshStatsWrapper = async () => {
|
|
|
|
if (stats.refresh) {
|
|
|
|
try {
|
|
|
|
await stats.refresh();
|
|
|
|
} catch (error) {
|
|
|
|
console.error('Error refreshing stats:', error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<ProfileFeed
|
|
|
|
feedEntries={feed.entries}
|
|
|
|
isRefreshing={isRefreshing}
|
|
|
|
onRefresh={handleRefresh}
|
|
|
|
onPostPress={handlePostPress}
|
|
|
|
user={currentUser}
|
|
|
|
bannerImageUrl={bannerImage.url || undefined}
|
|
|
|
defaultBannerUrl={bannerImage.defaultUrl}
|
|
|
|
followersCount={stats.followersCount}
|
|
|
|
followingCount={stats.followingCount}
|
|
|
|
refreshStats={refreshStatsWrapper}
|
|
|
|
isStatsLoading={stats.isLoading}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}, [
|
|
|
|
feed.entries,
|
|
|
|
isRefreshing,
|
|
|
|
handleRefresh,
|
|
|
|
handlePostPress,
|
|
|
|
currentUser,
|
|
|
|
bannerImage.url,
|
|
|
|
bannerImage.defaultUrl,
|
|
|
|
stats.followersCount,
|
|
|
|
stats.followingCount,
|
|
|
|
stats.refresh,
|
|
|
|
stats.isLoading
|
|
|
|
]);
|
2025-03-29 17:47:10 -07:00
|
|
|
|
2025-04-04 22:43:03 -04:00
|
|
|
// SINGLE RETURN STATEMENT with conditional rendering
|
|
|
|
// This avoids hook ordering issues by ensuring all hooks are always called
|
|
|
|
return (
|
|
|
|
<View className="flex-1">
|
|
|
|
{renderState === 'login' && renderLoginScreen()}
|
|
|
|
{renderState === 'loading' && renderLoadingScreen()}
|
|
|
|
{renderState === 'error' && renderErrorScreen()}
|
|
|
|
{renderState === 'content' && renderMainContent()}
|
|
|
|
</View>
|
|
|
|
);
|
2025-03-22 23:21:26 -04:00
|
|
|
}
|