Add custom GIF mascot avatar override#2347
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (12)
✅ Files skipped from review due to trivial changes (3)
📝 WalkthroughWalkthroughAdds custom GIF mascot avatar support: component and exports, Redux state/validation/persistence, settings UI to save/reset a GIF URL with preview, HumanPage conditional rendering, tests, and i18n entries. ChangesCustom Mascot GIF Avatar Feature
Sequence DiagramsequenceDiagram
participant User
participant MascotPanel
participant Redux as ReduxStore
participant HumanPage
User->>MascotPanel: Enter custom GIF URL
MascotPanel->>MascotPanel: Trim & validate with isCustomMascotGifUrl
User->>MascotPanel: Click Save
MascotPanel->>ReduxStore: dispatch setCustomMascotGifUrl(url)
ReduxStore->>ReduxStore: validate/store, clear selectedMascotId, persist
MascotPanel->>MascotPanel: Render preview (CustomGifMascot)
User->>HumanPage: Navigate to page
HumanPage->>ReduxStore: selectCustomMascotGifUrl
alt custom GIF set
HumanPage->>HumanPage: Render CustomGifMascot
else no custom GIF
HumanPage->>HumanPage: Render YellowMascot
end
User->>MascotPanel: Click Reset
MascotPanel->>ReduxStore: dispatch setCustomMascotGifUrl(null)
ReduxStore->>ReduxStore: clear customMascotGifUrl
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add 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.
🧹 Nitpick comments (1)
app/src/components/settings/panels/MascotPanel.tsx (1)
166-166: ⚡ Quick winInternationalize hardcoded UI strings for consistency.
The custom GIF section contains hardcoded English strings:
- Line 166: validation error message
- Line 497: "Custom GIF avatar" label
- Line 501: aria-label
The rest of the component internationalizes all UI-facing text via
t('settings.mascot.*'). For consistency, these strings should also use the i18n system.Suggested i18n keys
Add to your i18n resources:
'settings.mascot.customGifHeading': 'Custom GIF avatar', 'settings.mascot.customGifLabel': 'Custom GIF avatar URL', 'settings.mascot.customGifError': 'Enter an HTTPS .gif URL, file:// .gif URL, or local .gif path.',Then update the component:
- Custom GIF avatar + {t('settings.mascot.customGifHeading')} - aria-label="Custom GIF avatar URL" + aria-label={t('settings.mascot.customGifLabel')} - setCustomGifError('Enter an HTTPS .gif URL, file:// .gif URL, or local .gif path.'); + setCustomGifError(t('settings.mascot.customGifError'));Also applies to: 497-497, 501-501
🤖 Prompt for 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. In `@app/src/components/settings/panels/MascotPanel.tsx` at line 166, Replace the hardcoded English strings in the custom GIF section with i18n keys: change the validation call setCustomGifError('Enter an HTTPS .gif URL, file:// .gif URL, or local .gif path.') to use t('settings.mascot.customGifError'), and replace the visible label "Custom GIF avatar" and the aria-label on the input with t('settings.mascot.customGifHeading') and t('settings.mascot.customGifLabel') respectively; also add the three keys ('settings.mascot.customGifHeading', 'settings.mascot.customGifLabel', 'settings.mascot.customGifError') to the i18n resource files so the component (MascotPanel.tsx) uses the same t(...) pattern as the rest of the file.
🤖 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.
Nitpick comments:
In `@app/src/components/settings/panels/MascotPanel.tsx`:
- Line 166: Replace the hardcoded English strings in the custom GIF section with
i18n keys: change the validation call setCustomGifError('Enter an HTTPS .gif
URL, file:// .gif URL, or local .gif path.') to use
t('settings.mascot.customGifError'), and replace the visible label "Custom GIF
avatar" and the aria-label on the input with
t('settings.mascot.customGifHeading') and t('settings.mascot.customGifLabel')
respectively; also add the three keys ('settings.mascot.customGifHeading',
'settings.mascot.customGifLabel', 'settings.mascot.customGifError') to the i18n
resource files so the component (MascotPanel.tsx) uses the same t(...) pattern
as the rest of the file.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 55d54160-705e-4bd0-abf0-232f682d85e9
📒 Files selected for processing (10)
app/src/components/settings/panels/MascotPanel.tsxapp/src/components/settings/panels/__tests__/MascotPanel.test.tsxapp/src/features/human/HumanPage.test.tsxapp/src/features/human/HumanPage.tsxapp/src/features/human/Mascot/CustomGifMascot.test.tsxapp/src/features/human/Mascot/CustomGifMascot.tsxapp/src/features/human/Mascot/index.tsapp/src/store/__tests__/mascotSlice.test.tsapp/src/store/index.tsapp/src/store/mascotSlice.ts
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 `@app/src/lib/i18n/chunks/en-5.ts`:
- Around line 207-210: The i18n error message for
'settings.mascot.customGifError' omits loopback HTTP .gif URLs; update the
string value for that key (settings.mascot.customGifError) so it lists all
accepted formats including loopback HTTP .gif URLs (e.g., http://localhost or
http://127.0.0.1), e.g. "Enter an HTTPS .gif URL, loopback HTTP .gif URL
(http://localhost or http://127.0.0.1), file:// .gif URL, or local .gif path."
Ensure only the message string is changed.
In `@app/src/lib/i18n/en.ts`:
- Around line 1954-1957: Update the user-facing help text for the message key
'settings.mascot.customGifError' to include loopback HTTP (e.g., allow
http://localhost .gif) alongside the existing HTTPS, file://, and local path
options, then propagate the identical text change to any locale chunk files that
currently use the same English fallback string so all translations/partials
remain consistent with the new wording.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 917f0d53-92fd-4b8d-9190-caba2075f4e7
📒 Files selected for processing (15)
app/src/components/settings/panels/MascotPanel.tsxapp/src/lib/i18n/chunks/ar-5.tsapp/src/lib/i18n/chunks/bn-5.tsapp/src/lib/i18n/chunks/en-5.tsapp/src/lib/i18n/chunks/es-5.tsapp/src/lib/i18n/chunks/fr-5.tsapp/src/lib/i18n/chunks/hi-5.tsapp/src/lib/i18n/chunks/id-5.tsapp/src/lib/i18n/chunks/it-5.tsapp/src/lib/i18n/chunks/ko-5.tsapp/src/lib/i18n/chunks/pt-5.tsapp/src/lib/i18n/chunks/ru-5.tsapp/src/lib/i18n/chunks/zh-CN-5.tsapp/src/lib/i18n/en.tsapp/src/lib/i18n/ko.ts
✅ Files skipped from review due to trivial changes (4)
- app/src/lib/i18n/chunks/fr-5.ts
- app/src/lib/i18n/ko.ts
- app/src/lib/i18n/chunks/zh-CN-5.ts
- app/src/lib/i18n/chunks/es-5.ts
graycyrus
left a comment
There was a problem hiding this comment.
Review — Custom GIF Mascot Avatar Override
Nice feature, @vaddisrinivas. The URL validation logic is solid — blocks javascript:, data:, non-loopback HTTP, and non-.gif extensions. The mutual exclusivity between backend mascot / custom GIF / local default is well-handled in both the reducer and the UI. Tests are thorough (66 passing covers the key paths). referrerPolicy="no-referrer" on the img tag is a good touch.
Two items below — one scoping note on the persist whitelist, one i18n nit.
| Area | Files | Verdict |
|---|---|---|
| Store (slice) | mascotSlice.ts |
Clean — validation, mutual exclusivity, rehydrate scrubbing all look correct |
| Store (persist) | index.ts |
See comment — whitelist expansion beyond new field |
| Frontend (renderer) | CustomGifMascot.tsx, HumanPage.tsx |
Clean — simple conditional render, proper fallback |
| Frontend (settings) | MascotPanel.tsx |
Clean — save/reset/validation/preview all wired up |
| i18n | en.ts, ko.ts, 11 chunk files |
See comment — untranslated strings |
| Tests | 4 test files | Good coverage of slice logic, component render, panel interaction |
|
@graycyrus Thanks again for the review. I addressed the persist-scope and i18n fallback notes in b3b936d and resolved the threads; current checks are green. Could you please take another look when you have a chance? |
|
merging this for now. we're going to convert mascots into rive files soon. but for now this is fine. |
Summary
Refs #2345
Adds a lightweight custom GIF avatar override for the mascot/persona surface:
customMascotGifUrlin the mascot sliceHumanPagewhen configured, falling back toYellowMascotBranch / commit
codex/OH-2345-persona-gif-avatar9ed52f53aeb2caad9c041a50c1a7a2521ea1fc19Files changed
app/src/store/mascotSlice.tsapp/src/store/index.tsapp/src/features/human/HumanPage.tsxapp/src/features/human/Mascot/CustomGifMascot.tsxapp/src/features/human/Mascot/index.tsapp/src/components/settings/panels/MascotPanel.tsxBehavior change
Users can paste an HTTPS
.gif,file://.gif, loopback HTTP.gif, or local.gifpath as a mascot avatar override. Invalid or unsafe values reset/reject to default behavior. Custom GIF avatars are simple image renderers: no lip-sync or state-specific visemes.Validation
corepack pnpm install --frozen-lockfilecorepack pnpm --dir app exec vitest run src/store/__tests__/mascotSlice.test.ts src/features/human/Mascot/CustomGifMascot.test.tsx src/features/human/HumanPage.test.tsx src/components/settings/panels/__tests__/MascotPanel.test.tsx --config test/vitest.config.ts— pass, 66 testsPATH=/tmp/openhuman-pnpm-shim:$PATH corepack pnpm typecheck— passPATH=/tmp/openhuman-pnpm-shim:$PATH corepack pnpm --filter openhuman-app format:check— passPATH=/tmp/openhuman-pnpm-shim:$PATH git push -u fork codex/OH-2345-persona-gif-avatar— pre-push hook passed: format, lint, compile, rust:check, command-token lint. Lint/Rust emitted pre-existing warnings only.PATH=/tmp/openhuman-pnpm-shim:$PATH corepack pnpm pr:checklist /tmp/openhuman-pr-2345.md— passnode scripts/codex-pr-preflight.mjs --strict-path --lightweight— blocked only by local checkout path: expected/workspace/openhuman, got/Users/srinivasvaddi/Projects/openhuman-2345-persona-gif-avatar; all other checks passed.Duplicate / stale PR check
gh pr list --repo tinyhumansai/openhuman --state open --search 'custom GIF avatar OR persona pack OR mascot avatar' --json number,title,headRefName,urlreturned no open duplicates.Summary by CodeRabbit
New Features
Persistence
Tests
Localization