// app/(tabs)/social/following.tsx import React, { useCallback, useState, useRef } from 'react'; import { View, FlatList, RefreshControl, TouchableOpacity } from 'react-native'; import { Text } from '@/components/ui/text'; import EnhancedSocialPost from '@/components/social/EnhancedSocialPost'; import { router } from 'expo-router'; import NostrLoginPrompt from '@/components/social/NostrLoginPrompt'; import { useNDKCurrentUser, useNDK } from '@/lib/hooks/useNDK'; import { useFollowingFeed } from '@/lib/hooks/useFeedHooks'; import { ChevronUp, Bug } from 'lucide-react-native'; import { AnyFeedEntry } from '@/types/feed'; // Define the conversion function here to avoid import issues function convertToLegacyFeedItem(entry: AnyFeedEntry) { return { id: entry.eventId, type: entry.type, originalEvent: entry.event!, parsedContent: entry.content!, createdAt: (entry.timestamp || Date.now()) / 1000 }; } export default function FollowingScreen() { const { isAuthenticated, currentUser } = useNDKCurrentUser(); const { ndk } = useNDK(); const { entries, newEntries, loading, resetFeed, clearNewEntries, hasFollows, followCount, followedUsers, isLoadingContacts } = useFollowingFeed(); const [isRefreshing, setIsRefreshing] = useState(false); const [showNewButton, setShowNewButton] = useState(false); const [showDebug, setShowDebug] = useState(false); // Use ref for FlatList to scroll to top const listRef = useRef(null); // Show new entries button when we have new content React.useEffect(() => { if (newEntries.length > 0) { setShowNewButton(true); } }, [newEntries.length]); // Depend on length, not array reference // If not authenticated, show login prompt if (!isAuthenticated) { return ; } // Handle showing new entries const handleShowNewEntries = useCallback(() => { clearNewEntries(); setShowNewButton(false); // Scroll to top listRef.current?.scrollToOffset({ offset: 0, animated: true }); }, [clearNewEntries]); // Handle refresh - updated with proper reset handling const handleRefresh = useCallback(async () => { setIsRefreshing(true); try { await resetFeed(); // Add a slight delay to ensure the UI updates await new Promise(resolve => setTimeout(resolve, 300)); } catch (error) { console.error('Error refreshing feed:', error); } finally { setIsRefreshing(false); } }, [resetFeed]); // Check relay connections const checkRelayConnections = useCallback(() => { if (!ndk) return; console.log("=== RELAY CONNECTION STATUS ==="); if (ndk.pool && ndk.pool.relays) { console.log(`Connected to ${ndk.pool.relays.size} relays:`); ndk.pool.relays.forEach((relay) => { console.log(`- ${relay.url}: ${relay.status}`); }); } else { console.log("No relay pool or connections available"); } console.log("==============================="); }, [ndk]); // Handle post selection - simplified for testing const handlePostPress = useCallback((entry: AnyFeedEntry) => { // Just show an alert with the entry info for testing alert(`Selected ${entry.type} with ID: ${entry.eventId}`); // Alternatively, log to console for debugging console.log(`Selected ${entry.type}:`, entry); }, []); // Memoize render item function const renderItem = useCallback(({ item }: { item: AnyFeedEntry }) => ( handlePostPress(item)} /> ), [handlePostPress]); // Debug controls component - memoized const DebugControls = useCallback(() => ( Debug Info: User: {currentUser?.pubkey?.substring(0, 8)}... Following Count: {followCount || 0} Feed Items: {entries.length} Loading: {loading ? "Yes" : "No"} Loading Contacts: {isLoadingContacts ? "Yes" : "No"} {followedUsers && followedUsers.length > 0 && ( Followed Users: {followedUsers.slice(0, 3).map((pubkey, idx) => ( {idx+1}. {pubkey.substring(0, 12)}... ))} {followedUsers.length > 3 && ( ...and {followedUsers.length - 3} more )} )} Check Relays Force Refresh ), [currentUser?.pubkey, followCount, entries.length, loading, isLoadingContacts, followedUsers, checkRelayConnections, handleRefresh]); // If user doesn't follow anyone if (isAuthenticated && !hasFollows) { return ( You're not following anyone yet. Find and follow other users to see their content here. {/* Debug toggle */} setShowDebug(!showDebug)} > {showDebug ? "Hide" : "Show"} Debug Info {showDebug && ( User pubkey: {currentUser?.pubkey?.substring(0, 12)}... Authenticated: {isAuthenticated ? "Yes" : "No"} Follow count: {followCount || 0} Has NDK follows: {currentUser?.follows ? "Yes" : "No"} NDK follows count: { typeof currentUser?.follows === 'function' ? 'Function' : (currentUser?.follows && Array.isArray(currentUser?.follows)) ? (currentUser?.follows as any[]).length : (currentUser?.follows && typeof currentUser?.follows === 'object' && 'size' in currentUser?.follows) ? (currentUser?.follows as any).size : 'unknown' } Loading contacts: {isLoadingContacts ? "Yes" : "No"} {/* Toggle relays button */} Check Relay Connections {/* Manual refresh */} Force Refresh Feed )} ); } return ( {/* Debug toggle button */} setShowDebug(!showDebug)} > {/* Debug panel */} {showDebug && } {showNewButton && ( New Posts ({newEntries.length}) )} item.id} renderItem={renderItem} refreshControl={ } ListEmptyComponent={ loading || isLoadingContacts ? ( Loading followed content... ) : ( No posts from followed users found You're following {followCount || 0} users, but no content was found. This could be because they haven't posted recently, or their content is not available on connected relays. ) } contentContainerStyle={{ paddingVertical: 0 }} // Changed from paddingVertical: 8 /> ); }