12 Commits

Author SHA1 Message Date
xfy
f33e68d1db feat: compute birthday flag in LunarCache 2026-06-15 16:22:47 +08:00
xfy
58a97d1725 refactor: WebP 文件列表改由构建期 BuildConfig 注入,消除 (1..152) 硬编码
问题
- AnimatedWebp.kt 原写死 WEBP_FILES = (1..152).map{...}, 与磁盘文件耦合却无校验
- 加 153.webp → 永远不会被随机到; 删某个 → random() 偶发命中不存在的资源
- 这是静默失败, 运行期无报错, 难排查

改动
- core/build.gradle.kts defaultConfig: 构建期扫描 assets/animations/ 生成
  buildConfigField("String[]", "WEBP_FILES", "new String[]{...}")
  含 require(webpFiles.isNotEmpty()) 防空目录构建
- AnimatedWebp.kt: WEBP_FILES 从 private 硬编码改为 internal val = BuildConfig.WEBP_FILES.toList()
  (internal 让同模块测试可访问)
- 新增 AnimatedWebpFilesTest: 2 个守卫测试
  1. webpFilesMatchDirectoryContents: WEBP_FILES 必须与 assets/animations/ 一一对应
  2. webpFilesUseZeroPaddedThreeDigitNames: 锁定 NNN.webp 命名约定

TDD 流程
- 先写测试 → 编译失败(WEBP_FILES 是 private) → 红灯成立
- 改实现 → 测试 PASS → 绿灯
- 突变验证: 临时改 WEBP_FILES = (1..150) 漏掉 151/152
  → webpFilesMatchDirectoryContents 立即 FAIL, 守卫有效
- 恢复后全量 146 个测试 0 失败

设计说明
- 当前实现里 WEBP_FILES 与目录都来自同一次构建期扫描, 二者天然一致
- 测试的核心价值是锁定「两者一致」不变量, 防止有人回退成硬编码
  (突变验证已证明: 回退后测试立即失败)
- BuildConfig 生成结果验证: String[] 含 152 个元素 001~152.webp

验证
- ./gradlew :core:testDebugUnitTest → 146 tests, 0 failures, 0 errors
- ./gradlew :app:assembleDebug → BUILD SUCCESSFUL
- BuildConfig.java: public static final String[] WEBP_FILES = new String[]{"001.webp",...,"152.webp"}
2026-06-15 14:02:21 +08:00
xfy
55d50c3e1d feat: 添加 clampExpiryDays 纯函数钳制保质期天数为非负 2026-06-15 11:24:38 +08:00
xfy
0560e81fb2 feat: 日期检查器添加数据持久化和恢复默认按钮
- 新增 DateCheckerStorage,SharedPreferences 持久化生产日期和保质期列表
- 添加 DateCheckerStorageTest 单元测试(含 InMemorySharedPreferences stub)
- 页面退出后保留数据,重新打开自动恢复
- 左下角新增恢复默认 FAB,点击弹出确认弹窗后重置全部数据
- 双 FAB 样式统一(FloatingActionButton + CircleShape + primary 配色)
2026-06-08 11:08:48 +08:00
xfy
829f89eb7c refactor: 删除 P0 冗余代码(自定义combine/死StateFlow/网格重复算法/runBlocking)
- 删除自定义 6 参数 combine + Quintuple,改用标准库嵌套 combine + Triple
- 删除 yearViewProgress 死 StateFlow 及关联测试
- generateMonthDays/generateMiniMonthDays 复用 getMonthGridInfo
- WeekPager 移除 runBlocking,交由 DayCell 自行异步计算
- 修复 AnimLog 在 JVM 单元测试中因 android.util.Log 不可用而崩溃
2026-06-01 18:03:27 +08:00
xfy
e249700ee5 refactor: 清理不必要的 @Suppress 注解并替换弃用 API
移除 23 处不必要或可通过改写避免的 @Suppress。
- 删除 12 处完全不必要(误加/重构遗留)
- 替换 9 处 monthNumber/dayOfMonth → month.number/day
- 替换 4 处弃用构造函数 LocalDate(year,month,1) → LocalDate(year,Month(month),1)
- 保留 6 处必要 @Suppress(NOTHING_TO_INLINE、Android API 兼容等)
2026-06-01 17:55:18 +08:00
xfy
0cdac663c9 refactor: 移除 fling 速度阈值,改用 spring 动画驱动折叠过渡
- ViewModel onDragEnd/onExpandDragEnd 移除 velocity 参数
- BottomCard 移除 VelocityTracker,简化回调签名
- CalendarMonthView 添加 animateFloatAsState spring 动画
- 更新单元测试:移除 fling 测试,调整阈值边界

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 13:36:58 +08:00
xfy
fb7e19ddc9 test: Wave 4 — 补充 fling 速度阈值交互测试
- test: onDragEnd 高速上滑强制折叠(无视 progress 阈值)
- test: onDragEnd 高速下滑强制展开(无视 progress 阈值)
- test: onExpandDragEnd 高速下滑强制展开
- test: onExpandDragEnd 高速上滑保持折叠

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 18:18:34 +08:00
xfy
6f4d62b78f refactor: Wave 3 — ViewModel 解耦 Compose 运行时,迁移到 StateFlow
- refactor: CalendarViewModel 从 mutableStateOf/Animatable 迁移到 StateFlow
- refactor: 继承 Android ViewModel,使用 viewModelScope 管理生命周期
- refactor: 拖拽/动画方法改为同步修改 StateFlow(移除协程 launch)
- refactor: onDragEnd/onExpandDragEnd 实现 fling 速度阈值判断
- refactor: BottomCard 解耦为纯参数驱动
- refactor: CalendarMonthView 使用 viewModel() + collectAsState()
- test: 适配 StateFlow API,139 测试全部通过

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 18:16:20 +08:00
xfy
bf28008d17 refactor: Wave 1 — 构建清理、测试修复、文档修正、a11y 改进
- build: 清理版本目录死依赖(appcompat、core、material3)
- build: 精简 ProGuard keep 规则,仅保留热点路径和第三方库
- refactor: 重命名 PredictiveBackHandler → AppPredictiveBackHandler
- test: formatLunarDate 精确断言 + 闰月测试
- test: 统一测试命名风格(下划线),Unconfined → StandardTestDispatcher
- docs: 修正文档为纯 Android + Jetpack Compose 描述
- feat(a11y): 添加可访问性语义标注(WeekdayHeader heading、BottomCard 拖拽描述)
- feat: 为 DayCell、MonthHeader、WeekdayHeader、BottomCard 添加 @Preview

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 17:51:12 +08:00
xfy
2028897ce3 docs: 同步 AGENTS.md 文档,反映纯 Android 项目结构
- 更新所有层级 AGENTS.md 中的模块描述(:app / :core)
- 移除 KMP/iOS 相关引用,统一为纯 Android + Jetpack Compose
- 同步构建命令和测试路径

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 16:46:17 +08:00
xfy
f5cc4ef2e5 refactor: 完成纯 Android 迁移,清理旧 KMP 模块并添加 app/core 新模块
- 删除遗留的 androidApp/、shared/ 等 KMP 结构文件
- 将新的 app/、core/ 纯 Android 模块纳入版本控制

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 15:55:08 +08:00