Skip to content

fix(pet): stop i18n from corrupting CSS keyframes in PetOverlay#6360

Open
AloneFire wants to merge 1 commit into
stablyai:mainfrom
AloneFire:fix/pet-spritesheet-i18n-css-corruption
Open

fix(pet): stop i18n from corrupting CSS keyframes in PetOverlay#6360
AloneFire wants to merge 1 commit into
stablyai:mainfrom
AloneFire:fix/pet-spritesheet-i18n-css-corruption

Conversation

@AloneFire

Copy link
Copy Markdown

PetOverlay passed CSS @Keyframes strings through translate(), routing CSS
through the i18n pipeline. Translators (zh/ja/es) translated CSS keywords
(transform变换, background-position背景位置, to),
producing invalid CSS that browsers silently discard. The pet sprite animation
froze on the first frame, and pet-bob float stopped.

Bundled pets (animated WebP via <img>) were unaffected — they bypass the CSS
keyframes path entirely. Custom spritesheet pets (SpriteFrame, CSS
background-position stepping) were fully broken in any non-English locale whose
translation touched those two keys.

Fix:

  • Replace translate() wrapping CSS with a template-literal variable
    (keyframesCss) and a module-level constant (PET_BOB_KEYFRAMES_CSS) in
    PetOverlay.tsx, so CSS never enters the i18n pipeline.
  • Remove the now-orphaned localization keys (de932b0e8f, 4712d196c6) from
    all locale files (en/zh/ja/es/ko) since they are no longer referenced by any
    source code.

Root cause verified via CDP: injecting valid @keyframes made
background-position cycle through 6 frames (0 → -507.7px → 0) and pet-bob
transform animate immediately.

Summary

Custom spritesheet pets freeze on the first frame in non-English locales
(zh/ja/es), and the pet-bob floating animation also stops. This PR fixes the
sprite frame animation and the bob float for custom pets in all locales.

Screenshots

No visual change to the UI chrome. The fix restores an existing animation that
was broken — the pet sprite now steps through its frames and bobs up and down as
intended.

Testing

  • pnpm lint
  • pnpm typecheck
  • pnpm test
  • pnpm build
  • Added or updated high-quality tests that would catch regressions, or
    explained why tests were not needed

pnpm lint — oxlint, switch-exhaustiveness, localization catalog (9115 refs
verified), and coverage audit (0 unlocalized candidates) all pass.

pnpm typecheck — tsgo across all three tsconfigs (node/cli/web) passes.

pnpm test — 20791 passed, 5 failed. All 5 failures are pre-existing
environment issues unrelated to this PR: zh-system-locale cron label mismatch
(星期日s vs Sundays), missing hermes CLI, and three filesystem/git timeout
flakes. None of the failing test files touch PetOverlay, pet/, or i18n locale
files. Pet and i18n test suites (7 files, 20 tests) pass cleanly.

pnpm build — full desktop build (typecheck → relay 6-platform → cli →
electron-vite 961 modules → web 8165 modules) succeeds.

No new tests added. The existing PetOverlay.test.ts only covers
clampPositionToViewport (pure positioning math) and does not assert on CSS
keyframes or animation playback — CSS @keyframes validity is enforced by the
browser, not by jsdom. The regression is structural (CSS string passing through
i18n) and is prevented at the source level by removing the translate() calls.
The no-top-level-translate.test.ts static-analysis guard remains satisfied.

AI Review Report

Reviewed the change for correctness, fallback behavior, and cross-locale
impact.

Main risks checked:

  • i18n catalog integrity: verify-localization-catalog.mjs only checks the
    "source reference → en.json" direction and does not flag orphaned keys, so
    removing unreferenced keys is safe. Catalog parity across locales is preserved
    (all 5 locales had the same two keys removed; parity verified at 9653 keys each).
  • Localization coverage audit: moving CSS strings from inline JSX
    expressions to variable assignments / module constants avoids the
    jsx-expression candidate classification — coverage passes with 0 allowlisted
    candidates, no exemption debt.
  • no-top-level-translate.test.ts: checks that translate() is not called
    at module load time. This PR removes translate() calls from PetOverlay.tsx
    entirely, so the guard is trivially satisfied.
  • Animation behavior across states: selectPetAnimationName and the
    SpriteFrame row/frames logic are unchanged — only the CSS string generation
    mechanism changed (i18n → template literal variable / module constant). All
    animation states (idle/running/waiting/review/jumping) remain driven as before.
  • Bundled pets: unaffected — they use animated WebP via <img>, never
    touching the CSS keyframes path.

Cross-platform compatibility (macOS/Linux/Windows): this is a renderer-only CSS
string change with no platform-specific APIs, shortcuts, paths, shell behavior,
or Electron platform differences. Identical behavior on all platforms.

Security Audit

No security-relevant surface touched. No new IPC channels, no file/path
handling, no command execution, no auth/secrets, no new dependencies. The change
replaces an i18n function call with a string variable/constant and removes unused
JSON values. No follow-up needed.

Notes

No platform-specific behavior or risks. The fix applies uniformly across all
locales and platforms. The bundled animated-WebP pets were never affected and
continue to work as before.

PetOverlay passed CSS @Keyframes strings through translate(), which
routes them through i18n. Translators (zh/ja/es) translated CSS
keywords (transform -> 变换, background-position -> 背景位置, to -> 到),
producing invalid CSS that browsers silently discard. The pet sprite
animation froze on the first frame, and pet-bob float stopped.

Bundled pets (animated WebP via <img>) were unaffected — they bypass
the CSS keyframes path entirely. Custom spritesheet pets (SpriteFrame,
CSS background-position stepping) were fully broken in any non-English
locale whose translation touched those two keys.

Fix:
- Replace translate() wrapping CSS with template literals / string
  literals in PetOverlay.tsx so CSS never enters the i18n pipeline.
- Remove the now-orphaned localization keys (de932b0e8f, 4712d196c6)
  from all locale files (en/zh/ja/es/ko) since they are no longer
  referenced by any source code.

Root cause verified via CDP: injecting valid @Keyframes made
background-position cycle through 6 frames (0 -> -507.7px -> 0) and
pet-bob transform animate immediately.
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 87a5015c-1deb-4c79-a78d-0fcc68b347fa

📥 Commits

Reviewing files that changed from the base of the PR and between f6ad569 and 676a0ad.

📒 Files selected for processing (6)
  • src/renderer/src/components/pet/PetOverlay.tsx
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json
💤 Files with no reviewable changes (5)
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/zh.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/ja.json

📝 Walkthrough

Walkthrough

PetOverlay now defines the sprite-row and bobbing @keyframes CSS strings inside the component instead of reading them through i18n. The English, Spanish, Japanese, and Korean locale files remove the PetOverlay animation string entries, and the Chinese locale file removes stray numeric tokens from the pet.pet.models mapping.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main fix: preventing translated CSS keyframes in PetOverlay from being corrupted by i18n.
Description check ✅ Passed The description follows the required template and includes summary, screenshots, testing, AI review, security audit, and notes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants