4.4 KiB
4.4 KiB
Instagram-like Feed Implementation Plan
Objective
Create a responsive, immersive feed experience that adapts to device size:
- Desktop/Large Screens: Retain the current
PhotoGrid(grid view). - Mobile: Implement a new
Feedview (vertical list) similar to Instagram. - Carousel: Support horizontal swiping (left/right) through multiple pictures within a single post.
- Performance: Implement "load ahead" strategy (buffer ~5 posts) to ensure smooth scrolling without loading the entire database.
Architecture & Components
1. Data Layer Enhancements
Current PhotoGrid logic fetches posts and selects a single "cover" image.
We need to modify the data transformation to pass all visible pictures to the UI components.
- Query: Keep fetching
postswithpictures. - Transformation: Instead of flattening to a single
MediaItem, we need a structure that preserves the list of pictures for each post.interface FeedPost { id: string; // Post ID user_id: string; // Author pictures: MediaItemType[]; // Array of pictures in the post // ... other post metadata (title, description, etc.) }
2. New Feed Component (Mobile)
A new component src/components/Feed.tsx will be created for the mobile view.
- Layout: Vertical list of full-width cards.
- Virtualization: Use
react-windowor simpler intersection observer-based rendering to only render posts in (and slightly outside) the viewport. - Preloading: Ensure the next 5 image/video assets are preloaded.
3. Updated MediaCard / New FeedCard
MediaCard currently handles a single media item. We have two options:
- Refactor
MediaCard: Add support for an array of media and internal carousel logic. - Create
FeedCard: A specialized card for the Feed view that wrapsMediaCardor implements its own carousel.- Decision: Use
FeedCard(orPostCard) to encapsulate the carousel logic (Embla Carousel or similar) and useMediaCardfor individual slides if needed, or implement a lighter slide view. - Carousel: Must support touch gestures for left/right swiping.
- Decision: Use
4. PhotoGrid Updates
- Logic Separation: Extract the data fetching hook (e.g.,
useFeedMedia) so bothPhotoGridandFeedcan share the same data source and state (likes, etc.). - Responsive Switch: In
Index.tsx, conditionally renderPhotoGrid(desktop) orFeed(mobile). Or render both and hide via CSS (better for SSR/hydration matching, but heavier on DOM). Better to use a valid hook forisMobile.
Implementation Steps
Phase 1: Data & Hooks
- Create
useFeedQueryhook to fetch posts + pictures. - Implement pagination (infinite scroll) logic (load 10, load next 10 when bottom reached).
- Preloading utility: Function to preload images
nindexes ahead of the current viewport item.
Phase 2: Carousel Component
- Implement a Swipe/Carousel component (using
embla-carousel-reactor purely custom CSS scroll-snap). - Ensure it handles image aspect ratios gracefully (Instagram usually restricts to 4:5 or square, but we might support flexible).
Phase 3: MobileFeed Component
- Create the vertical list layout.
- Implement the "Load 5 ahead" logic (prefetching images for the next 5 cards).
- Integrate the Carousel for multi-image posts.
Phase 4: Integration
- Update
Index.tsxto switch betweenPhotoGridandMobileFeed. - Ensure shared state (Likes, Comments) works in both views.
Technical Details
"Load 5 Ahead" Strategy
- Intersection Observer: Watch the last rendered element to trigger fetching the next page.
- Image Preloading: Watch the currently visible post index. Automatically create
Link rel="preload"ornew Image()for thecoverimages of the next 5 posts. - Carousel Preloading: If a user stops on a post, prioritize loading the next slide of that specific post.
Swiping Interaction
- Carousel (Inner): Swiping horizontally moves between pictures of the same post.
- Feed (Outer): Scrolling vertically moves between different posts.
Proposed File Structure
src/components/feed/Feed.tsxsrc/components/feed/FeedCard.tsx(Handles the carousel)src/components/feed/FeedCarousel.tsx(The actual swiper)src/hooks/useFeed.ts(Data fetching logic)