feat(native): add recently viewed history to search screen

Track titles and people visited in the native app and surface them
in the search tab when the query is empty, replacing the static
empty-state icon.

- Add `lib/recently-viewed.ts` — MMKV-backed store (max 20 items)
  with `addRecentlyViewed`, `removeItem`, `clearAll`, and a
  `useRecentlyViewed` hook
- Track visits via `useEffect` in `title/[id].tsx` and
  `person/[id].tsx` once data resolves
- `RecentlyViewedList` — platform-split component:
  - iOS (`.ios.tsx`): native SwiftUI List via `@expo/ui` with
    system SF Symbols, swipe-to-delete, and a "Clear" button
  - Android/fallback: FlatList with `SwipeableRow` for delete
- Add `SwipeableRow` component using `ReanimatedSwipeable`
- Clear recently viewed history on sign-out (both `HeaderAvatar`
  and Settings screen)
- Add `@expo/ui@55.0.2` dependency
This commit is contained in:
2026-03-13 19:08:13 -04:00
parent 35bdfc171e
commit b4c2a1d343
12 changed files with 578 additions and 13 deletions
+3
View File
@@ -19,6 +19,7 @@
"@expo-google-fonts/dm-serif-display": "0.4.2",
"@expo-google-fonts/geist-mono": "0.4.1",
"@expo/metro-runtime": "55.0.6",
"@expo/ui": "55.0.2",
"@gorhom/bottom-sheet": "5.2.8",
"@orpc/client": "catalog:",
"@orpc/contract": "catalog:",
@@ -667,6 +668,8 @@
"@expo/sudo-prompt": ["@expo/sudo-prompt@9.3.2", "", {}, "sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw=="],
"@expo/ui": ["@expo/ui@55.0.2", "", { "dependencies": { "sf-symbols-typescript": "^2.1.0" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-nVWFz0/7w/+Tr0/Jd3TTTY3HUrMSQzOfbuL1nl257zGfJzp2cGmHNuaRlh3Yi72NcVlFNLRbZzLdH3Jwa1R0jg=="],
"@expo/vector-icons": ["@expo/vector-icons@15.1.1", "", { "peerDependencies": { "expo-font": ">=14.0.4", "react": "*", "react-native": "*" } }, "sha512-Iu2VkcoI5vygbtYngm7jb4ifxElNVXQYdDrYkT7UCEIiKLeWnQY0wf2ZhHZ+Wro6Sc5TaumpKUOqDRpLi5rkvw=="],
"@expo/ws-tunnel": ["@expo/ws-tunnel@1.0.6", "", {}, "sha512-nDRbLmSrJar7abvUjp3smDwH8HcbZcoOEa5jVPUv9/9CajgmWw20JNRwTuBRzWIWIkEJDkz20GoNA+tSwUqk0Q=="],