fix(cat): polish cat/model transition behavio#1666
Conversation
调整 cat_model_change.gif 的帧时长分布,让烟圈到散开的关键阶段更均匀连贯。\n\n保持动画总时长、帧数和代码引用不变,仅更新过渡 GIF 资源。
修复 CAT1 蹲在网页 compact 对话框上缘时的表现问题。\n\n- 叫声触发时切换到 CAT1 点击态并在播放结束后恢复\n- compact mirror 状态先本页派发再广播,避免同页拖动时原图隐藏但镜像不显示\n- 补充静态契约测试覆盖声音反应和本页 mirror 派发
修复猫形态和人形态切换时靠近屏幕边界的过渡遮罩偏移。\n\n- 过渡遮罩按猫/模型中心直接定位,允许遮罩部分出屏\n- 保持猫/模型实体原有边界夹取不变\n- 补充静态契约测试,防止重新把遮罩夹回视口
|
PR changed again? Review this PR in Change Stack to compare snapshots and stay oriented. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Walkthrough该 PR 移除猫1过渡矩形的视口夹紧,新增猫1环保音触发的声音反应与紧凑镜像同步(含本地 CustomEvent 与 broadcast),并在 React 中为紧凑导出历史关闭期间缓存消息快照以避免新消息闪烁喵。 Changes猫1声音联动与镜像同步流程完善
React:紧凑导出历史关闭期间快照
Sequence Diagram(s)sequenceDiagram
participant Ambient as Cat1AmbientSound
participant SoundReaction as _playNekoIdleCat1SoundReaction
participant HoverArt as _playNekoIdleHoverArt
participant SyncMirror as _syncNekoIdleCat1CompactMirrorReaction
participant PostState as _postNekoIdleCat1CompactMirrorState
participant LocalEvent as CustomEvent(neko:idle-cat1-compact-mirror-state)
participant Broadcast as nekoBroadcastChannel
Ambient->>SoundReaction: 触发声音反应
SoundReaction->>HoverArt: 播放悬停艺术资源
SoundReaction->>SyncMirror: 延迟(基于 GIF 时长)调用同步
SyncMirror->>PostState: 发送镜像状态载荷
PostState->>LocalEvent: 先派发本地 CustomEvent (via:'local')
PostState->>Broadcast: 再尝试 postMessage 广播
Broadcast-->>PostState: 返回发送结果
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1a38e9504a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const token = art.__nekoIdleHoverToken || 0; | ||
| _getNekoIdleGifDurationMs(clickSrc).then((durationMs) => { | ||
| window.setTimeout(() => { | ||
| if ((art.__nekoIdleHoverToken || 0) !== token) return; |
There was a problem hiding this comment.
Restore compact mirror after sound reaction
When CAT1 is perched on the compact top edge and the ambient sound reaction plays, this token check prevents the mirror from switching back from the click GIF. _finishNekoIdleHoverArtAfterPlayback() is scheduled just above and, at the end of the same playback, calls _clearNekoIdleHoverPlayback(), which increments art.__nekoIdleHoverToken; because that timeout is registered before this mirror-restore timeout, this guard usually returns and leaves the compact mirror on clickSrc until another mirror update or timeout occurs, while the hidden original art has already returned to idle.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@static/avatar-ui-buttons.js`:
- Around line 664-699: 在 _playNekoIdleIdleCat1SoundReaction 中的问题是镜像同步仍然使用硬编码
clickSrc 并等待 fetch 得到完整 GIF 时长,导致本地按钮与 compact mirror 播放资源/时长不同步;修复方法是在调用
_playNekoIdleHoverArt(art, _NEKO_IDLE_TIER_CAT1) 之后立即读取 art.__nekoIdleHoverSrc 和
art.__nekoIdleHoverStartedAt,使用实际播放的资源(art.__nekoIdleHoverSrc)立即调用
_syncNekoIdleCat1CompactMirrorReaction(...) 做“开始/切换”同步,随后用
_getNekoIdleGifDurationMs(art.__nekoIdleHoverSrc) 减去 (Date.now() -
art.__nekoIdleHoverStartedAt) 计算剩余播放时长并在该剩余时长到期后再次调用
_syncNekoIdleCat1CompactMirrorReaction(...) 做“恢复/结束”同步;不要再使用 clickSrc 或等待 fetch
的全长作为延迟基准,并保留对 art.__nekoIdleHoverToken 检查逻辑以防竞态。
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 48f414cd-d79f-4043-abb5-3fb1d9358bea
⛔ Files ignored due to path filters (1)
static/assets/neko-idle/cat_model_change.gifis excluded by!**/*.gif
📒 Files selected for processing (3)
static/app-ui.jsstatic/avatar-ui-buttons.jstests/unit/test_avatar_return_button_idle_tiers_static.py
修复 CAT1 蹲在 compact 对话框上时的桌面镜像拖拽闪烁和叫声反应同步问题。\n\n关闭历史对话时冻结 closing 动画期间的消息快照,避免新消息在关闭态历史区域闪现;重新打开后仍按最新消息渲染。\n\n补充对应静态与 React 回归测试。
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@static/avatar-ui-buttons.js`:
- Around line 1417-1438: The settle timer can fire later and flip a
newly-changed state back to inactive; ensure any existing
container.__nekoIdleCat1CompactMirrorSettleTimer is cleared whenever we take any
!nextActive path (not only when nextActive becomes true) before creating a new
timer or performing immediate deactivation. Concretely: in the !nextActive
branch clearTimeout(container.__nekoIdleCat1CompactMirrorSettleTimer) and set it
to 0 at the start (or immediately before any early returns), then proceed to
create a new settle timer only if none exists; also ensure any early
immediate-deactivate paths (calls to _setNekoIdleCat1CompactMirrorActive with
forceImmediate) clear the timer first so stale callbacks cannot later override
the new state.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: ff783ae3-3a2f-428c-828f-0fad57313052
📒 Files selected for processing (4)
frontend/react-neko-chat/src/App.test.tsxfrontend/react-neko-chat/src/App.tsxstatic/avatar-ui-buttons.jstests/unit/test_avatar_return_button_idle_tiers_static.py
在 CAT1 compact mirror 的立即关闭路径中清理 pending settled timer,避免延迟回调在状态变化后再次触发 inactive。\n\n保留 compact-surface-settled 的一次性延迟关闭语义,补充静态契约测试覆盖 timer 清理顺序。
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b7c9932958
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| window.dispatchEvent(new CustomEvent('neko:idle-cat1-compact-mirror-state', { | ||
| detail: Object.assign({ | ||
| via: 'local' | ||
| }, message) |
There was a problem hiding this comment.
Don't mirror compact CAT1 locally from the pet window
When the compact chat runs in the separate Electron chat window, templates/index.html loads both avatar-ui-buttons.js and app-react-chat-window.js, so this new local dispatch is consumed by the pet window's handleIdleCat1CompactMirrorState before the broadcast reaches the chat window. In that context the original cat is hidden by is-cat1-compact-mirror-active, while the pet window also creates a compact mirror using the chat window's screen rect, which can leave a duplicate/mispositioned cat in the pet window; the local event should be gated to same-page compact surfaces or ignored by the pet window.
Useful? React with 👍 / 👎.
修复桌面端 pet 主窗口误消费 CAT1 compact mirror 本地事件的问题。\n\n仅让 Electron pet 主窗口忽略 via=local 且 source=pet-window 的 mirror 状态,避免主窗口创建错位镜像或隐藏原猫;独立聊天窗口仍通过 BroadcastChannel 同步,网页端同页 compact 路径保持不变。\n\n补充静态回归测试,锁定 pet 主窗口本地事件过滤边界。
变更内容
cat_model_change.gif资源。验证
node --check static/avatar-ui-buttons.jsnode --check static/app-ui.js.venv/bin/pytest tests/unit/test_avatar_return_button_idle_tiers_static.py -qgit diff --checkSummary by CodeRabbit
Bug Fixes
New Features
Tests