// app/(tabs)/social/powr.tsx import React, { useState, useCallback, useEffect, useRef } from 'react'; import { View, FlatList, RefreshControl, TouchableOpacity } from 'react-native'; import { Text } from '@/components/ui/text'; import EnhancedSocialPost from '@/components/social/EnhancedSocialPost'; import { ChevronUp, Zap } from 'lucide-react-native'; import POWRPackSection from '@/components/social/POWRPackSection'; import { useSocialFeed } from '@/lib/hooks/useSocialFeed'; import { POWR_PUBKEY_HEX } from '@/lib/hooks/useFeedHooks'; import { router } from 'expo-router'; import { AnyFeedEntry } from '@/types/feed'; import { withOfflineState } from '@/components/social/SocialOfflineState'; // Define the conversion function here to avoid import issues function convertToLegacyFeedItem(entry: any) { return { id: entry.id || entry.eventId, type: entry.type, originalEvent: entry.originalEvent || entry.event, parsedContent: entry.parsedContent || entry.content, createdAt: entry.createdAt || (entry.timestamp ? entry.timestamp / 1000 : Date.now() / 1000) }; } function PowerScreen() { const { feedItems, loading, refresh, isOffline } = useSocialFeed({ feedType: 'powr', authors: POWR_PUBKEY_HEX ? [POWR_PUBKEY_HEX] : undefined, limit: 30 }); // For compatibility with the existing UI const entries = React.useMemo(() => { return feedItems.map(item => ({ id: item.id, eventId: item.id, event: item.originalEvent, content: item.parsedContent, timestamp: item.createdAt * 1000, type: item.type as any })); }, [feedItems]); const [newEntries, setNewEntries] = useState([]); const [isRefreshing, setIsRefreshing] = useState(false); const [showNewButton, setShowNewButton] = useState(false); // Use ref for list to scroll to top const listRef = useRef(null); // Break the dependency cycle by using proper effect useEffect(() => { // Only set the button if we have new entries if (newEntries.length > 0) { setShowNewButton(true); } }, [newEntries.length]); // Depend only on length change, not the array itself // Handle showing new entries const handleShowNewEntries = useCallback(() => { setNewEntries([]); setShowNewButton(false); // Scroll to top listRef.current?.scrollToOffset({ offset: 0, animated: true }); }, []); // Handle refresh - updated to use forceRefresh parameter const handleRefresh = useCallback(async () => { setIsRefreshing(true); try { console.log('[POWRScreen] Starting manual refresh (force=true)'); // Use force=true to bypass cooldown await refresh(true); // Add a slight delay to ensure the UI updates await new Promise(resolve => setTimeout(resolve, 300)); console.log('[POWRScreen] Manual refresh completed successfully'); } catch (error) { console.error('Error refreshing feed:', error); } finally { setIsRefreshing(false); } }, [refresh]); // Handle post selection - simplified for testing const handlePostPress = useCallback((entry: any) => { // Just show an alert with the entry info for testing alert(`Selected ${entry.type} with ID: ${entry.id || entry.eventId}`); // Alternatively, log to console for debugging console.log(`Selected ${entry.type}:`, entry); }, []); // Memoize render item to prevent re-renders const renderItem = useCallback(({ item }: { item: any }) => ( handlePostPress(item)} /> ), [handlePostPress]); // Memoize empty component const renderEmptyComponent = useCallback(() => ( loading ? ( Loading POWR content... ) : ( {isOffline ? "No cached POWR content available" : "No POWR content found"} {isOffline && ( You're currently offline. Connect to the internet to see the latest content. )} ) ), [loading, isOffline]); // Header component const renderHeaderComponent = useCallback(() => ( <> {/* POWR Welcome Section */} POWR Community Official updates, featured content, and community highlights from the POWR team. {/* POWR Packs Section */} ), []); return ( {showNewButton && ( New Posts ({newEntries.length}) )} item.id} renderItem={renderItem} refreshControl={ } ListHeaderComponent={renderHeaderComponent} ListEmptyComponent={renderEmptyComponent} contentContainerStyle={{ flexGrow: 1, paddingBottom: 16 }} /> ); } // Export the component wrapped with the offline state HOC export default withOfflineState(PowerScreen);