# 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 `Feed` view (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 `posts` with `pictures`. - **Transformation**: Instead of flattening to a single `MediaItem`, we need a structure that preserves the list of pictures for each post. ```typescript 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-window` or 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: 1. **Refactor `MediaCard`**: Add support for an array of media and internal carousel logic. 2. **Create `FeedCard`**: A specialized card for the Feed view that wraps `MediaCard` or implements its own carousel. * *Decision*: Use `FeedCard` (or `PostCard`) to encapsulate the carousel logic (Embla Carousel or similar) and use `MediaCard` for individual slides if needed, or implement a lighter slide view. * **Carousel**: Must support touch gestures for left/right swiping. ### 4. `PhotoGrid` Updates - **Logic Separation**: Extract the data fetching hook (e.g., `useFeedMedia`) so both `PhotoGrid` and `Feed` can share the same data source and state (likes, etc.). - **Responsive Switch**: In `Index.tsx`, conditionally render `PhotoGrid` (desktop) or `Feed` (mobile). Or render both and hide via CSS (better for SSR/hydration matching, but heavier on DOM). Better to use a valid hook for `isMobile`. ## Implementation Steps ### Phase 1: Data & Hooks 1. Create `useFeedQuery` hook to fetch posts + pictures. 2. Implement pagination (infinite scroll) logic (load 10, load next 10 when bottom reached). 3. Preloading utility: Function to preload images `n` indexes ahead of the current viewport item. ### Phase 2: Carousel Component 1. Implement a Swipe/Carousel component (using `embla-carousel-react` or purely custom CSS scroll-snap). 2. Ensure it handles image aspect ratios gracefully (Instagram usually restricts to 4:5 or square, but we might support flexible). ### Phase 3: `MobileFeed` Component 1. Create the vertical list layout. 2. Implement the "Load 5 ahead" logic (prefetching images for the next 5 cards). 3. Integrate the Carousel for multi-image posts. ### Phase 4: Integration 1. Update `Index.tsx` to switch between `PhotoGrid` and `MobileFeed`. 2. 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"` or `new Image()` for the `cover` images 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.tsx` - `src/components/feed/FeedCard.tsx` (Handles the carousel) - `src/components/feed/FeedCarousel.tsx` (The actual swiper) - `src/hooks/useFeed.ts` (Data fetching logic)