mirror of
https://github.com/DocNR/POWR.git
synced 2025-04-23 01:01:27 +00:00

- Add ultra-early content display after just 500ms with ANY data available - Implement progressive content loading with three-tier timeout system - Reduce timeouts from 5s to 4s on Android and 4s to 3s on iOS - Enhance render state logic to prioritize partial content display - Improve parallel data loading for all profile elements - Add multiple fallback timers to ensure content always displays - Update CHANGELOG.md with detailed performance improvements This commit dramatically improves perceived performance by showing content as soon as it becomes available rather than waiting for complete data load.
108 lines
3.3 KiB
TypeScript
108 lines
3.3 KiB
TypeScript
// components/profile/ProfileFeed.tsx
|
|
import React, { useCallback, useMemo } from 'react';
|
|
import { View, FlatList, RefreshControl } from 'react-native';
|
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
import EmptyFeed from '@/components/social/EmptyFeed';
|
|
import EnhancedSocialPost from '@/components/social/EnhancedSocialPost';
|
|
import { convertToLegacyFeedItem } from '@/lib/hooks/useProfilePageData';
|
|
import type { AnyFeedEntry } from '@/types/feed';
|
|
import ProfileHeader from './ProfileHeader';
|
|
import { NDKUser } from '@nostr-dev-kit/ndk';
|
|
|
|
interface ProfileFeedProps {
|
|
feedEntries: AnyFeedEntry[];
|
|
isRefreshing: boolean;
|
|
onRefresh: () => void;
|
|
onPostPress: (entry: AnyFeedEntry) => void;
|
|
user: NDKUser | null;
|
|
bannerImageUrl?: string;
|
|
defaultBannerUrl?: string;
|
|
followersCount: number;
|
|
followingCount: number;
|
|
refreshStats: () => Promise<void>;
|
|
isStatsLoading: boolean;
|
|
}
|
|
|
|
/**
|
|
* Profile feed component that displays the user's posts
|
|
* Pure presentational component with performance optimizations
|
|
*/
|
|
const ProfileFeed: React.FC<ProfileFeedProps> = ({
|
|
feedEntries,
|
|
isRefreshing,
|
|
onRefresh,
|
|
onPostPress,
|
|
user,
|
|
bannerImageUrl,
|
|
defaultBannerUrl,
|
|
followersCount,
|
|
followingCount,
|
|
refreshStats,
|
|
isStatsLoading,
|
|
}) => {
|
|
const insets = useSafeAreaInsets();
|
|
|
|
// Performance optimization: memoize item renderer
|
|
const renderItem = useCallback(({ item }: { item: AnyFeedEntry }) => (
|
|
<EnhancedSocialPost
|
|
item={convertToLegacyFeedItem(item)}
|
|
onPress={() => onPostPress(item)}
|
|
/>
|
|
), [onPostPress]);
|
|
|
|
// Performance optimization: memoize key extractor
|
|
const keyExtractor = useCallback((item: AnyFeedEntry) => item.id, []);
|
|
|
|
// Performance optimization: memoize header component
|
|
const ListHeaderComponent = useMemo(() => (
|
|
<ProfileHeader
|
|
user={user}
|
|
bannerImageUrl={bannerImageUrl}
|
|
defaultBannerUrl={defaultBannerUrl}
|
|
followersCount={followersCount}
|
|
followingCount={followingCount}
|
|
refreshStats={refreshStats}
|
|
isStatsLoading={isStatsLoading}
|
|
/>
|
|
), [user, bannerImageUrl, defaultBannerUrl, followersCount, followingCount, refreshStats, isStatsLoading]);
|
|
|
|
// Performance optimization: memoize empty component
|
|
const ListEmptyComponent = useMemo(() => (
|
|
<View className="px-4 py-8">
|
|
<EmptyFeed message="No posts yet. Share your workouts or create posts to see them here." />
|
|
</View>
|
|
), []);
|
|
|
|
// Performance optimization: memoize content container style
|
|
const contentContainerStyle = useMemo(() => ({
|
|
paddingBottom: insets.bottom + 20,
|
|
flexGrow: feedEntries.length === 0 ? 1 : undefined
|
|
}), [insets.bottom, feedEntries.length]);
|
|
|
|
return (
|
|
<FlatList
|
|
data={feedEntries}
|
|
keyExtractor={keyExtractor}
|
|
renderItem={renderItem}
|
|
refreshControl={
|
|
<RefreshControl
|
|
refreshing={isRefreshing}
|
|
onRefresh={onRefresh}
|
|
/>
|
|
}
|
|
ListHeaderComponent={ListHeaderComponent}
|
|
ListEmptyComponent={ListEmptyComponent}
|
|
contentContainerStyle={contentContainerStyle}
|
|
|
|
// Performance optimizations for FlatList
|
|
removeClippedSubviews={true}
|
|
maxToRenderPerBatch={5}
|
|
initialNumToRender={8}
|
|
windowSize={5}
|
|
updateCellsBatchingPeriod={50}
|
|
/>
|
|
);
|
|
};
|
|
|
|
export default ProfileFeed;
|