> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Add a full-width "big card" as the last item of the homepage video list, which auto-plays the video muted (qn=16, 360P) when scrolled into view, with a 16:9 thumbnail that fades out once the video is ready.
**Architecture:** Transform `videos: VideoItem[]` into typed rows (`NormalRow | BigRow`) before rendering; FlatList renders rows via `numColumns={1}`; viewport detection uses FlatList's `onViewableItemsChanged`; `BigVideoCard` fetches play URL lazily and renders a `Video` component from `react-native-video` on top of the thumbnail.
git commit -m "feat: add videoRows utility for big-card list layout"
```
---
## Chunk 2: BigVideoCard component
### Task 2: Create `components/BigVideoCard.tsx`
**Files:**
- Create: `components/BigVideoCard.tsx`
**Overview:** Displays a full-width card with a 16:9 thumbnail. When `isVisible` becomes true, fetches the play URL at qn=16 and renders a muted `Video`. When the video is ready to display, the thumbnail fades out. When `isVisible` becomes false, the video pauses.
- [ ]**Step 1: Create the component skeleton**
```tsx
// components/BigVideoCard.tsx
import React, { useEffect, useRef, useState } from 'react';
import {
View, Text, Image, TouchableOpacity, StyleSheet,
Dimensions, Animated,
} from 'react-native';
import Video from 'react-native-video';
import { Ionicons } from '@expo/vector-icons';
import { buildDashMpdUri } from '../utils/dash';
import { getPlayUrl, getVideoDetail } from '../services/bilibili';
import { proxyImageUrl } from '../utils/imageUrl';
import { formatCount, formatDuration } from '../utils/format';
import type { VideoItem } from '../services/types';
- [ ]**Step 3: Add state and derived data inside `HomeScreen`**
Add inside `HomeScreen`, after the existing `useRef` lines. **Order matters:** declare state first, then memo, then the ref (the ref's closure captures `setVisibleBigKey`):
onPress={() => router.push(`/video/${row.item.bvid}` as any)}
/>
);
}
// Normal pair row
return (
<View style={styles.row}>
<View style={styles.leftCol}>
<VideoCard
item={row.left}
onPress={() => router.push(`/video/${row.left.bvid}` as any)}
/>
</View>
{row.right && (
<View style={styles.rightCol}>
<VideoCard
item={row.right}
onPress={() => router.push(`/video/${row.right!.bvid}` as any)}
/>
</View>
)}
</View>
);
};
```
- [ ]**Step 5: Update `styles.row` in the StyleSheet**
`styles.row` was previously used as `columnWrapperStyle` — FlatList automatically applies `flexDirection: 'row'` to column wrappers. Now that it becomes an explicit `<View style={styles.row}>`, `flexDirection: 'row'` must be added explicitly or the pair columns will stack vertically.
Find the `row` entry in `StyleSheet.create({...})` and update it:
**Important:** Apply Step 4 (new `renderItem`) before or simultaneously with this step. Removing `numColumns` while the old `renderItem` (which relies on `numColumns` to pair items via `index % 2`) is still in place will break layout mid-edit.
4. Remove the `columnWrapperStyle={styles.row}`**prop** from FlatList. Do NOT delete the `styles.row` StyleSheet entry — it is still referenced in the pair renderItem's `<View style={styles.row}>` (and now has `flexDirection: 'row'` from Step 5).
Note: `react-native-video` is already installed in this project (confirmed by `components/NativeVideoPlayer.tsx` which imports `Video` from it). No additional installation needed.
- [ ]**Step 7: TypeScript check**
```bash
npx tsc --noEmit
```
Expected: no errors
- [ ]**Step 8: Run the app and verify visually**
```bash
expo start --port 8082
```
Check:
1. Homepage renders two-column layout for normal cards
2. Last card is full-width with 16:9 thumbnail
3. Scrolling to the last card starts muted video after a brief delay
4. Thumbnail fades out when video is ready
5. Scrolling away from the big card pauses the video
6. After loading more items, the entire row list is recomputed: the previously-last item now appears in a normal pair row, and the new last item appears as the big card at the bottom
7. When the number of normal (non-big) items is odd, the last pair row shows a single card on the left with an empty right slot
- [ ]**Step 9: Commit**
```bash
git add app/index.tsx
git commit -m "feat: refactor homepage FlatList for big-card layout with viewport autoplay"