谁悲失路之人

拾遗 PickUp · 开发日志
Development Journal

拾遗 PickUp
开发日志

从第一条提交到 v1.8 上线 — 一部产品的进化轨迹,记录每一个关键里程碑

时间跨度
2026-05-21 → 05-28
日志条目
10 条
版本迭代
v1.0 → v1.8
状态
持续更新中
8
版本迭代
30+
Bug 修复
13
PRD 需求
4
构建成功

拾遗 App Android 开发构建成功,save-memory 技能创建完成。

关键结论

  • Plan 审计完成:原 15 个 task 中 4 项缺失(E2E test, stats-service test, Modal, GestureGuideOverlay),已全部补齐
  • 权限崩溃修复:expo-media-library 在 Expo Go 中不可用,必须用 development build
  • EAS 构建配置:eas.json 配好 development / preview / production 三个 profile
  • 构建 #1-#3 均失败,根因 react-native-reanimated v4 强制要求 newArchEnabled: true
  • 构建 #4 成功,APK 已生成(192MB,开发包正常体积)
下一步
  • 在 Android 手机上安装 APK 并测试基本功能
  • 验证媒体库权限、照片浏览、标记删除/保留、撤销等核心流程

修复了滑动抽搐、黑屏、无限循环等关键 Bug,优化手势交互体验,推送代码到 GitHub。

关键结论

  • BUG 滑动抽搐:withSpring → withTiming,消除欠阻尼振荡
  • BUG 黑屏根因:advanceToNext 闭包过期,currentGroup.length 不在依赖数组
  • BUG 无限循环:review.tsx useEffect 加 autoNavRef 守卫
  • BUG 导航错误:router.back() 在 Expo Tabs 中不可靠,全部改为 router.replace('/')
  • FEAT 底部进度条圆点可点击跳转、左滑跳过/右滑上一张、零删除直接跳下一组
  • ADJUST 每组 15→10 张、隐藏开发者模式提示文字
下一步
  • 预览构建 c4ca434e 完成后下载 APK 安装测试
  • 后续可考虑:照片元数据显示、相册分类、iCloud 照片支持

完成多项 UI/UX 需求改动,修复多个 JS 层 Bug,并定位修复了困扰已久的 Android 原生崩溃 getDirectConverter。

需求改动

  • FEAT 动态包名配置:app.config.js 区分三套包名(dev / preview / prod),同设备并存
  • FEAT 首次启动手势引导:GestureGuideOverlay,四向滑动操作说明,4 秒自动消失
  • FEAT 批量删除按钮:QuickDeleteButton,浮动右下角,一键批量删除
  • FEAT SplashScreen 启动页:标题+标语渐入效果
  • UI PhotoCard 卡片重设计、ActionIndicator 胶囊样式、底部进度条增强

Bug 修复

  • CRITICAL getDirectConverter 原生崩溃:expo-font@56.0.5 不兼容 SDK 54 → 降至 14.0.11
  • BUG @expo/vector-icons 异常 → 替换 emoji 临时方案,重建后恢复矢量图标
  • BUG refillGroup 崩溃风险 / handleQuickDelete UI 锁定 / advanceToNext 闭包过期

教训 重要教训

  • 添加 Expo 包务必用 npx expo install <pkg>,不能用 npm install
  • EAS 构建日志里的 duplicate / missing peer dependency 警告是崩溃的直接线索

v1.0.1 Bug 修复 + UI 打磨完成,README 架构文档更新,Android preview 构建提交中。

Bug 修复

  • 日限制重启失效:dailyUsageLoaded 未导出 → loadPhotos() 提前执行。导出并 gate 等待
  • 权限弹窗闪屏:permissionStatus 初始化为 undetermined。挂载时调用 getPermissionsAsync() 同步真实状态
  • 日限制时 Loading 死循环:调整渲染顺序,先检查 canBrowseNextGroup 再检查 isLoading
  • 进度条圆点着色错位:改传 Set<number> 索引集合,每个圆点独立判断
  • 删除确认页预勾选失效:React 状态批处理竞态,加 useEffect 同步

UI 打磨

  • 照片原比例展示:getDisplaySize() 根据宽高比计算 + borderRadius: 24
  • 相对日期:"2024年3月15日 · X天前/昨天/今天"
  • 进度条位置下调:50→34,去掉文字计数器;卡片间距收紧

教训

  • index.tsx 渲染检查顺序至关重要:权限 → 日用量 → 限制 → 加载 → 空相册
  • getPermissionsAsync() 不弹对话框也能获取真实权限状态

用户提出 4 个新改动点,已整理为 v1.3 需求文档。

新需求清单

  • UI 删除确认弹框改造:毛玻璃 + 圆角卡片 + 淡入淡出动画,次按钮统一为"取消"
  • BUG 修复不弹框 Bug:排查 markedForDelete 与 currentGroup 同步竞态
  • UI Tab 栏 Touch Bar 改造:透明背景 + 浮动胶囊 + 毛玻璃 + 发光边框
  • FEAT 新增聚合图标入口,占位页面"更多功能 · 敬请期待"

决策

  • v1.3 需求文档已追加到 REQUIREMENTS-v1.1.md 末尾
  • 聚合页路由暂定为 app/hub.tsx

深入探索绕过 Android 系统删除弹框方案,经历多轮尝试,最终结论不可行,回退到系统弹框方案。

技术探索过程

  • 失败 方案 A:MANAGE_EXTERNAL_STORAGE + FileSystem.deleteAsync → SDK 54 已弃用
  • 失败 改用新 File/Directory 类 → File.delete() 仍被系统 rejected
  • 根本原因:Android 11+ Scoped Storage 对共享存储文件删除有 OS 级保护,无法绕过

当前方案

  • Android MediaLibrary.deleteAssetsAsync → 系统弹框确认(一次)
  • iOS 自定义毛玻璃 DeleteConfirmSheet → MediaLibrary.deleteAssetsAsync(无系统弹框)

修复 Tab bar 图标左偏 + 幽灵点击区域 Bug,最终方案:隐藏默认 tab bar + 独立 SimpleTabBar 组件。

关键结论

  • Bug 根因:自定义 TabBar 与默认 tab bar 双重渲染叠加
  • 尝试过的失败方案:flex/justifyContent 调整、去胶囊框、绝对定位 —— 均未解决
  • 方案 tabBarStyle: display: none + SimpleTabBar 独立渲染
  • 纯黑背景、图标居中、选中金色 / 未选中灰色

完成 v1.4-v1.6 多轮迭代——首页架构重构、Hub 柱状图、滑动优化、品牌改名 PickUp、新 LOGO、本地构建环境搭建。

v1.4

  • 首页相册选择、PhotoContext 新增 selectedAlbum、Hub 月度柱状图

v1.5

  • 浏览页回归默认首页,删除 browse.tsx,流程简化为 index ↔ albums ↔ review

v1.6

  • 滑动优化:卡片独立移动、去红背景;Hub 年份筛选;Review 空状态卡通幽灵
  • 滑动特效设置(5 种)、Tab 栏 usePathname 修复

品牌

  • 拾遗 → PickUp,标语:记忆由你选择;新 LOGO 堆叠滑出设计;assets/icon.png 已替换

BUILD 本地构建环境

  • EAS 免费配额已用完(6月1日重置),放弃 EAS 改用本地 Gradle
  • 已配置阿里云 / 腾讯云 / 华为云镜像解决国内网络问题
  • Android SDK 36、NDK 27、Build-Tools 37 已安装
  • 备选方案:GitHub Actions workflow 已配好

v1.2 功能优化全部完成 + 3 个用户反馈 Bug 修复,Release APK 本地构建成功并推送到 GitHub。

v1.2 完成项

  • REQ-01 释放空间累计:像素估算法作为兜底
  • REQ-02 统计卡片改造:中文加粗 + "最近删除"可点击跳转
  • REQ-03 最近删除页:3 列网格 + useFocusEffect 重新加载
  • REQ-04 排序功能:SortMode 四种模式,generateGroup() 重构

关键文件

新增修改
app/recent-deletes.tsxapp/index.tsx app/settings.tsx
SortPickerSheet.tsxdelete-service.ts stats-service.ts photo-service.ts

BUILD

  • EAS 配额用尽,本地 Gradle assembleRelease 成功
  • APK 路径:android/app/build/outputs/apk/release/app-release.apk(106MB)
  • Git push:2637361 master → origin/master,13 files changed

v1.7 全部需求实现 + 滑动动效增强 + 庆祝动画 + 新手引导重做 + release APK 打包完成。

v1.7 四项需求

  • REQ-01 QuickDeleteButton 去文字去胶囊框,仅图标+badge
  • REQ-02 日期文字移入 topBar flexbox,严格水平对齐,恢复 LIVE badge
  • REQ-03 delete-service.ts 增加缓存逻辑,最近删除页缩略图可见
  • REQ-04 标题改为 "最近删除 · X 张",paddingHorizontal 防重叠

新增

  • FEAT 左右滑动动画增强:rotationZ(±8°) + cardScale + withSpring 回弹
  • FEAT 庆祝动画:CelebrationOverlay — 黄色 ✓ + 12 颗彩色粒子爆散
  • UI 新手引导重做:GestureGuideOverlay 完整覆盖全部 UI 区域

关键文件

新增修改
CelebrationOverlay.tsxQuickDeleteButton.tsx SwipeableCard.tsx
app/index.tsx app/review.tsx app/recent-deletes.tsx
delete-service.ts GestureGuideOverlay.tsx

BUILD

  • Dev APK:192MB,包名 com.zackf.pickup.dev
  • Release APK:105MB,包名 com.zackf.pickup.preview
  • Metro IP:192.168.5.15
拾遗 PickUp · 开发日志 · 2026-05 · Generated with ❤️
© 2019-2026 Fueen