Skip to content

fix(mobile): 同步键盘避让与输入卡片动画 - #3945

Merged
MagicLizi merged 2 commits into
mainfrom
dash/mobile-keyboard-sync
Sep 5, 2026
Merged

fix(mobile): 同步键盘避让与输入卡片动画#3945
MagicLizi merged 2 commits into
mainfrom
dash/mobile-keyboard-sync

Conversation

@dashhuang

Copy link
Copy Markdown
Member

这次改了什么

摘要

任务页和新建页的 iOS 键盘避让、输入卡片尺寸和消息区域共用键盘几何与动画时序。切换输入法、候选栏改高、交互式收起时更新底部实际遮挡,避免只监听显示/隐藏以及固定 250ms 卡片动画造成不同步。

变更类型

  • fix 缺陷修复
  • feat 新功能
  • refactor / perf 重构或性能优化
  • docs / test / chore 文档、测试或工程维护
  • 其他:

范围

  • 关联 Issue / 需求:手机版键盘、输入卡片与消息区域同步运动。
  • 本 PR 包含:共享键盘状态与避让容器;iOS frame 变化与系统动画同步;did 事件校正页面在键盘动画中途挂载时的旧状态;任务页绝对输入区按真实遮挡连续避让;新建页扣除外层已消耗的底部安全区;卡片减少动态效果支持及回归测试。
  • 明确不包含:消息渲染性能、导航重构、登录页避让逻辑、原生配置或依赖调整。
  • 用户可见变化:键盘改高时同步调整输入区和内容视口;任务页键盘剩余遮挡不足 80pt 时输入区不再提前落下;新建页不重复计算底部安全区。独立卡片尺寸过渡统一使用现有 200ms token。
  • 是否存在 breaking change:无。

UI 变化

  • 引用的设计规范:docs/design-rules/DESIGN.md §14.4 Motion & Transitions:独立尺寸变化使用 motionDuration.base(200ms),iOS 键盘联动使用系统事件时序,减少动态效果开启或偏好尚未查明时不添加动画;§10 Theme System & Token Reference:沿用现有语义主题样式,Light/Dark 共用几何和动效逻辑,无新增颜色。
  • iOS 使用共享状态驱动底部留白,并通过 Keyboard.scheduleLayoutAnimation 配置同次布局;零时长事件直接更新,卡片不覆盖键盘动画。悬浮键盘不抬起整个页面,保留系统 cross-fade 特例并忽略过期异步查询结果。
  • Android 继续使用原有 KeyboardAvoidingView 与 did 事件,不叠加 iOS 底部偏移;卡片独立动画由 250ms 改为 200ms,并遵循减少动态效果偏好。
  • 未提供设备截图或录屏,验证边界见下。

怎么验证的

自动验证

pnpm test:unit:related
结果:通过,相关范围 apps/mobile(8 个改动文件)。

pnpm --filter mobile run --if-present typecheck
结果:通过。

pnpm --filter mobile exec vitest run src/__tests__/composerKeyboard.test.tsx src/__tests__/mobileNativeShellLayout.test.ts src/auth/__tests__/loginKeyboardAvoidance.test.ts --pool=threads
结果:3 个测试文件、53 项测试通过。

run-unit-gate.sh(执行仓库根 pnpm test:unit)
结果:GATE_EXIT=0;仓库脚本测试及全部适用工作区单测通过。

git diff --check
结果:通过。

手工验证

只读检查了 React Native 本地 Keyboard / KeyboardAvoidingView 与 iOS 事件桥接源码,核对事件时序、metrics 缓存更新时机、零时长动画和坐标体系;复查任务页绝对输入层与新建页 SafeAreaView 的实际布局关系。两轮独立源码复查发现的 80pt 跳变和 will/did 之间挂载残留占位问题均已修复,并加入回归测试。

未执行的验证

  • 本次未启动 iOS Simulator、Android 模拟器或真机,未验证真实输入法切换、手势跟随帧率与 Light/Dark 设备观感;单测模拟事件和布局输入,不能替代设备上的动效验证。
  • 本地验证分支:dash/mobile-keyboard-sync;worktree:/Users/dash/Code/Cindy/cindy-mobile-keyboard-sync。本轮未启动或接管 Metro,因此无 Metro 归属与 __DEV__ build label 证据。
  • 未运行原生构建或 fingerprint 哈希对比;本次 diff 不包含原生配置、依赖、config plugin 或原生模块输入。

风险

风险分类

  • 无已知风险
  • SQLite / migration
  • system prompt
  • 协议兼容
  • 权限 / 安全 / 用户数据
  • 存量插件兼容(批准状态 / 指纹 / manifest 校验 / 安装布局 / 包格式)
  • 原生层 / fingerprint / OTA
  • 跨平台差异
  • 其他:

影响与回滚

  • 影响范围:任务页与新建页的键盘避让和卡片动画。iOS 由共享状态配置系统时序;Android 保留原有避让路径,只有独立卡片动画时长及无障碍动效降级改变。未新增原生依赖,也未修改原生配置或数据协议。
  • 回滚 / 降级方式:回退本 PR 的 JS/TS 改动即可恢复原有 KAV 与卡片动画,无数据迁移。

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名(git commit -s
  • UI 改动已在「UI 变化」注明引用的设计规范章节
  • 未提交凭证、令牌或授权文件
  • 已补充必要文档(实现约束注释与本 PR 验证说明;无需新增产品文档)
  • 已确认测试结果或说明未执行原因

Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
@dashhuang
dashhuang requested a review from a team as a code owner September 5, 2026 01:29
@greptile-apps

greptile-apps Bot commented Sep 5, 2026

Copy link
Copy Markdown

Greptile Summary

此 PR 将任务页和新建页的输入卡片、内容视口及键盘避让统一到共享键盘几何和系统动画时序中。

  • iOS 监听键盘显示、隐藏及 frame 变化,按窗口底部实际遮挡持续更新布局。
  • 新增共享避让容器,并避免新建页重复消费底部安全区。
  • 任务页的绝对定位输入区在交互式收起期间持续跟随键盘。
  • 卡片独立尺寸动画改用 200ms 设计 token,并支持减少动态效果偏好。
  • 新增键盘切换、浮动键盘、跨淡化、挂载时序、Android 回退和监听清理测试。

Confidence Score: 5/5

未发现具体且可操作的正确性、安全性或仓库规则问题,此 PR 看起来可以合并。

共享键盘状态、iOS 避让容器、绝对输入层偏移和卡片动画所有权保持一致,新增测试也覆盖了主要事件顺序、边界几何和跨平台回退路径。

Important Files Changed

Filename Overview
apps/mobile/src/session/useMobileKeyboardState.ts 扩展共享键盘状态以跟踪 iOS frame 几何、系统动画、挂载校正和浮动键盘例外。
apps/mobile/src/session/ComposerKeyboardAvoidingView.tsx 新增跨平台避让容器,iOS 使用共享遮挡高度,Android 保留原生 KeyboardAvoidingView。
apps/mobile/src/session/mobileNativeShellLayout.ts 将内容密度阈值与输入区实际遮挡偏移分离,使绝对输入层连续跟随键盘。
apps/mobile/src/session/useComposerCardTransition.ts 让输入卡片尺寸动画遵循动效 token、减少动态效果偏好及键盘动画所有权。
apps/mobile/app/sessions/[sessionId].tsx 会话页接入共享键盘避让和动画状态,并保持消息区域与绝对输入层的职责分离。
apps/mobile/app/sessions/new.tsx 新建页接入共享避让容器,并扣除外层 SafeAreaView 已消费的底部安全区。
apps/mobile/src/tests/composerKeyboard.test.tsx 覆盖键盘改高、交互式收起、浮动键盘、跨淡化、事件去重、挂载校正、动效偏好和 Android 回退。
apps/mobile/src/tests/mobileNativeShellLayout.test.ts 增加从完整遮挡到零遮挡的输入区连续避让边界测试。

Sequence Diagram

sequenceDiagram
  participant IOS as iOS 键盘事件
  participant State as useMobileKeyboardState
  participant Motion as LayoutAnimation
  participant KAV as ComposerKeyboardAvoidingView
  participant Card as 输入卡片与消息区域
  IOS->>State: willShow / willChangeFrame / willHide
  State->>State: 计算窗口底部实际遮挡
  State->>Motion: 使用系统事件时序配置下一次布局
  State-->>KAV: height、visible、transition
  KAV-->>Card: 更新底部留白
  State-->>Card: 更新尺寸与绝对定位偏移
  Card->>Motion: 仅在键盘未拥有动画时配置 200ms 过渡
Loading

Reviews (1): Last reviewed commit: "fix(mobile): 同步键盘避让与输入卡片动画" | Re-trigger Greptile

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bcf19e11d5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/mobile/src/session/useMobileKeyboardState.ts
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 5, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-05T01:55:51.028831Z 9f1ddb2 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
@MagicLizi MagicLizi added status:awaiting-bot-review 等外部审查机器人表态(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) labels Sep 5, 2026
@MagicLizi MagicLizi removed the status:awaiting-bot-review 等外部审查机器人表态(review-pr 自动维护,仅展示) label Sep 5, 2026
@MagicLizi

Copy link
Copy Markdown
Contributor

命中 UI 路径(apps/mobile/app/sessions/[sessionId].tsx / apps/mobile/app/sessions/new.tsx / apps/mobile/src/session/ComposerKeyboardAvoidingView.tsx 等)但 description 未附界面效果证据——建议补充改动后效果:截图/录屏,或改动后界面的 HTML 页面(```html 代码块、.html 附件或在线预览链接),便于确认界面符合 DESIGN.md 设计规范

@MagicLizi MagicLizi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

独立审查通过:键盘避让与输入卡片动画仅 JS/layout,不触发冷更;几何与 reduce-motion 与测试一致。无 P0/P1。

@MagicLizi
MagicLizi merged commit bf911de into main Sep 5, 2026
19 checks passed
@MagicLizi
MagicLizi deleted the dash/mobile-keyboard-sync branch September 5, 2026 03:19
@MagicLizi

Copy link
Copy Markdown
Contributor

键盘跟着系统避让走,输入卡片也不再和键盘抢位置,手机上打字会顺很多。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants