Files
mindfulness/spec_kit/Card UI/tasks.md
2026-01-29 23:31:12 +08:00

7.6 KiB
Raw Blame History

Card UI任务清单

说明:本清单根据 plan.md 拆解,要求“可执行、可验收、可标记”。
标记规则:执行完成后将对应项从 - [ ] 改为 - [x],并把“状态”改为 已完成;进行中改为 进行中;阻塞写明原因与解除条件。

0. UI 参考(本次实现对齐)

  • 参考截图:你提供的卡片页 + 主题弹窗 + 我的弹窗
  • 弹窗内容区背景色#FAF3EC
  • 右上角按钮资源client/assets/images/home/theme.svgclient/assets/images/home/my.svg
  • 底部反应按钮资源client/assets/images/home/like.svgclient/assets/images/home/hate.svg
  • 交互约束
    • 弹窗为底部上拉Sheet
    • 关闭方式:点 X 关闭(不要求点遮罩关闭)
    • 顶部按钮使用系统导航栏headerRight
    • 主题切换最少影响:页面背景
    • 个人主页弹窗中的列表项:本期允许 仅做占位
    • 喜欢动效为强反馈:心形填满(按压回弹 + 填充变化)

1. 依赖与基础设施SVG 可 import

  • 安装 react-native-svg-transformer 并新增 client/metro.config.js
    • 状态:已完成
    • 原因:让 assets/images/home/*.svg 支持 import XxxIcon from '...svg' 作为组件使用
    • 命令
cd client
pnpm add react-native-svg-transformer
  • 实现点
    • 新增 client/metro.config.js,基于 expo/metro-config 配置 svg transformer
  • 验收
    • 任一页面可成功渲染 theme.svg/like.svg(真机/模拟器均可)
    • pnpm start 正常启动,无 Metro 报错

2. 本地存储:主题模式持久化

  • src/storage/appStorage.ts 新增主题 mode key 与读写方法
    • 状态:已完成
    • Keyui.theme.mode
    • 类型'scenery' | 'color'(默认 scenery
    • 新增 API建议
      • getThemeMode(): Promise<'scenery' | 'color'>
      • setThemeMode(mode: 'scenery' | 'color'): Promise<void>
    • 验收
      • 代码中不散落硬编码 key
      • 切换主题后重启 App 仍保持上次选择

3. 通用组件底部上拉弹窗Sheet框架

  • 新增通用 SheetModal 组件(底部上拉 + 背景色 #FAF3EC + X 关闭)
    • 状态:已完成
    • 建议路径client/components/ui/SheetModal.tsx
    • 要求
      • 遮罩存在(可拦截背景交互),但本期不要求点遮罩关闭
      • 内容区背景色固定为 #FAF3EC
      • 顶部提供右上/左上 X 按钮关闭(以设计稿为准)
      • 基础动效:上滑进入、下滑退出(或淡入淡出 + translateY
    • 验收
      • 任意页面可打开/关闭该弹窗,不闪烁、不穿透点击
      • iOS 安全区适配正常(底部不被 Home Indicator 遮挡)

4. 主题弹窗:风景 / 颜色

  • 实现 ThemeModal(复用 SheetModal
    • 状态:已完成
    • 建议路径client/components/home/ThemeModal.tsx
    • 内容
      • 标题:主题
      • 选项:风景 / 颜色(含预览卡片)
      • 选中态:明显高亮(描边/阴影/勾选均可)
    • 交互
      • 点击选项:setThemeMode(...) 并立即生效(可关闭弹窗或保持打开,按设计稿)
      • 点 X关闭
    • 验收
      • 两种主题可切换
      • 切换后 Home 页面背景立刻变化

5. 个人主页弹窗:占位入口

  • 实现 ProfileModal(复用 SheetModal
    • 状态:已完成
    • 建议路径client/components/home/ProfileModal.tsx
    • 内容(按设计最小闭环)
      • 顶部:插画/头像 + 昵称(来自 getUserProfile().name,无则占位)
      • 快捷卡片:我的喜欢 / 小组件(小组件可占位)
      • 通用列表:每日提醒 / 隐私政策 / 使用条款 / 语言(本期均允许占位)
    • 交互
      • 点 X关闭
      • 列表项点击:占位反馈(例如 Alert 或轻提示),不崩溃即可
    • 验收
      • 弹窗 UI 与 ThemeModal 同一套视觉(背景色/圆角/间距一致)
      • 点击各入口有明确反馈

6. 卡片页头部:系统导航栏右上角两个 icon 按钮

  • 改造 client/app/(app)/_layout.tsxhomeheaderRight 使用两个圆形 icon 按钮
    • 状态:已完成
    • 要求
      • 两按钮水平排列、圆形浅色底、hitSlop>=10
      • 左:主题(theme.svg),右:我的(my.svg
    • 事件传递方案(需要落地)
      • 实际落地:在 home.tsx 内通过 navigation.setOptions() 设置 headerRight,直接使用页面 state 打开 Theme/Profile 弹窗(避免跨层事件传递)
    • 验收
      • 右上角两个按钮展示正确
      • 点击分别能打开对应弹窗

7. 卡片页内容:喜欢/讨厌改为 icon + 强反馈动效

  • 改造 client/app/(app)/home.tsx:底部按钮从文字改为 icon

    • 状态:已完成
    • 要求
      • 喜欢按钮使用 like.svg
      • 讨厌按钮使用 hate.svg(逻辑仍写入 reaction=dislike
    • 验收:两按钮 icon 显示清晰,点击逻辑仍正常推进下一张卡片
  • 实现“强反馈:心形填满”点击动效

    • 状态:已完成
    • 范围:至少作用于“喜欢”按钮
    • 建议实现
      • pressIn/pressOut:按钮缩放回弹
      • onPress短促强调动效scale 1 → 1.12 → 1
      • “填满”效果:点击后切换到“填充版心形”(若当前资源仅描边,需要:
        • 新增一份 like_filled.svg(或在现有 SVG 上修改 fill/stroke并保持风格一致
        • 或用 react-native-svg 动态改 fill(可行但实现复杂)
    • 验收
      • 点击喜欢按钮能看到明显的“变填充 + 弹一下”反馈
      • 动效结束后再推进下一张卡片(避免动画被切页吞掉)

8. 主题对 Home 背景的影响

  • 让主题 mode 影响 Home 页面背景
    • 状态:已完成
    • 规则
      • scenery:使用风景主题背景(可先用现有米色/图片占位)
      • color:使用颜色主题背景(可先用淡粉色/纯色占位)
    • 验收:切换主题后背景立即变化;返回/重进页面仍正确

9. i18n用于标题/无障碍/占位文案)

  • 补齐本需求相关 i18n key至少 zh-CN/en
    • 状态:已完成
    • 建议 key
      • theme.titletheme.scenerytheme.color
      • profile.titleprofile.favoritesprofile.widget
      • profile.dailyReminderprofile.privacyprofile.termsprofile.language
      • home.themehome.profile(用于 accessibilityLabel
    • 验收:弹窗标题/选项/占位提示无硬编码长文案;切换语言可生效

10. 自测与验收

  • 主题弹窗流程自测

    • 状态:未开始
    • 路径Home 右上角主题按钮 → 主题弹窗 → 切换风景/颜色 → 背景变化 → 重启后仍保持
    • 验收:符合 spec.md / plan.md / 本清单验收点
  • 我的弹窗流程自测

    • 状态:未开始
    • 路径Home 右上角我的按钮 → 个人主页弹窗 → 点 X 关闭 → 列表项点击占位反馈
    • 验收:弹窗不穿透、关闭稳定、占位反馈明确
  • 喜欢/讨厌动效与逻辑自测

    • 状态:未开始
    • 路径:连续点击喜欢/讨厌 → 按钮动效可见 → 卡片索引推进 → 收藏/反应写入正常
    • 验收:无报错、不卡顿、动效不被切换吞掉