feat: add Enable Mobile Ringing toggle in user preferences#7155
feat: add Enable Mobile Ringing toggle in user preferences#7155diegolmello wants to merge 11 commits intofeat.voip-lib-newfrom
Conversation
…ry fields Iteration 2 fixes: wrap REST block in null guard, replace field accesses with as any casts since role/muted/held/contact/setMuted/setHeld were removed from IClientMediaCall in 0.2.0-rc.0 library.
WalkthroughImplements a mobile ringing preference feature by adding a new Changes
Sequence DiagramsequenceDiagram
actor User
participant UserPreferencesView
participant Redux Store
participant Server API
User->>UserPreferencesView: Toggle Enable Mobile Ringing
UserPreferencesView->>Redux Store: dispatch(setUser({enableMobileRinging: value}))
Redux Store-->>UserPreferencesView: State updated
UserPreferencesView->>Server API: saveUserPreferences({enableMobileRinging: value})
Server API-->>UserPreferencesView: Preference persisted
UserPreferencesView->>User: UI updated with new state
Estimated Code Review Effort🎯 2 (Simple) | ⏱️ ~10 minutes Suggested Labels
🚥 Pre-merge checks | ✅ 3✅ 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.
Actionable comments posted: 1
🧹 Nitpick comments (2)
app/views/UserPreferencesView/index.tsx (1)
30-30: NormalizeenableMobileRingingto a boolean before binding/toggling.Using a default boolean avoids undefined-driven toggle behavior and keeps
Switchusage deterministic.Proposed fix
-const enableMobileRinging = settings?.preferences?.enableMobileRinging; +const enableMobileRinging = settings?.preferences?.enableMobileRinging ?? false;Also applies to: 144-145, 149-149
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/views/UserPreferencesView/index.tsx` at line 30, The enableMobileRinging value is read from settings and may be undefined—normalize it to a boolean (e.g., const enableMobileRinging = Boolean(settings?.preferences?.enableMobileRinging) or use ?? false) before passing to the Switch or toggle handlers so the component always receives a deterministic true/false; update every occurrence (the initial const enableMobileRinging and places around lines referencing the Switch/toggle at 144-149 and 149) to use the normalized boolean and ensure any toggle handlers rely on the normalized value.app/i18n/locales/en.json (1)
317-317: Add this key to non-English locale bundles before release.Line 317 introduces the new key only in
en.json; please propagate it to the other locale files so non-English/RTL users don’t get fallback/mixed-language UI.As per coding guidelines, "Place internationalization configuration and locales in app/i18n/ with support for 40+ languages and RTL".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/i18n/locales/en.json` at line 317, Add the new i18n key "Enable_Mobile_Ringing" to every non-English locale bundle (including all RTL and supported language files) so no locale falls back to English; update each locale's JSON with the same key and an appropriate translated value, ensuring pluralization/formatting conventions are preserved and merge/commit the updated locale files alongside the en.json change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/views/UserPreferencesView/index.tsx`:
- Around line 62-65: The dispatched payload in toggleEnableMobileRinging
overwrites the entire preferences object with only enableMobileRinging, losing
sibling preference fields; update the dispatch to merge existing preferences
(use settings.preferences or settings?.preferences) into the new preferences
object so you dispatch setUser with settings: { ...settings, preferences: {
...settings.preferences, enableMobileRinging: value } } and then call
saveUserPreferences as before.
---
Nitpick comments:
In `@app/i18n/locales/en.json`:
- Line 317: Add the new i18n key "Enable_Mobile_Ringing" to every non-English
locale bundle (including all RTL and supported language files) so no locale
falls back to English; update each locale's JSON with the same key and an
appropriate translated value, ensuring pluralization/formatting conventions are
preserved and merge/commit the updated locale files alongside the en.json
change.
In `@app/views/UserPreferencesView/index.tsx`:
- Line 30: The enableMobileRinging value is read from settings and may be
undefined—normalize it to a boolean (e.g., const enableMobileRinging =
Boolean(settings?.preferences?.enableMobileRinging) or use ?? false) before
passing to the Switch or toggle handlers so the component always receives a
deterministic true/false; update every occurrence (the initial const
enableMobileRinging and places around lines referencing the Switch/toggle at
144-149 and 149) to use the normalized boolean and ensure any toggle handlers
rely on the normalized value.
🪄 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: 842a9512-5b33-4c40-b67b-105a6a7bde3e
📒 Files selected for processing (3)
app/definitions/IUser.tsapp/i18n/locales/en.jsonapp/views/UserPreferencesView/index.tsx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{js,jsx,ts,tsx,json}
📄 CodeRabbit inference engine (CLAUDE.md)
Configure Prettier with tabs, single quotes, 130 character width, no trailing commas, arrow parens avoid, and bracket same line
Files:
app/i18n/locales/en.jsonapp/definitions/IUser.tsapp/views/UserPreferencesView/index.tsx
app/i18n/**/*
📄 CodeRabbit inference engine (CLAUDE.md)
Place internationalization configuration and locales in app/i18n/ with support for 40+ languages and RTL
Files:
app/i18n/locales/en.json
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use ESLint with
@rocket.chat/eslint-configbase configuration including React, React Native, TypeScript, and Jest plugins
Files:
app/definitions/IUser.tsapp/views/UserPreferencesView/index.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use TypeScript with strict mode enabled and configure baseUrl to app/ for import resolution
**/*.{ts,tsx}: Use TypeScript for type safety; add explicit type annotations to function parameters and return types
Prefer interfaces over type aliases for defining object shapes in TypeScript
Use enums for sets of related constants rather than magic strings or numbers
Files:
app/definitions/IUser.tsapp/views/UserPreferencesView/index.tsx
app/definitions/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Place shared TypeScript type definitions in app/definitions/
Files:
app/definitions/IUser.ts
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,ts,jsx,tsx}: Use descriptive names for functions, variables, and classes that clearly convey their purpose
Write comments that explain the 'why' behind code decisions, not the 'what'
Keep functions small and focused on a single responsibility
Use const by default, let when reassignment is needed, and avoid var
Prefer async/await over .then() chains for handling asynchronous operations
Use explicit error handling with try/catch blocks for async operations
Avoid deeply nested code; refactor complex logic into helper functions
Files:
app/definitions/IUser.tsapp/views/UserPreferencesView/index.tsx
app/views/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Place screen components in app/views/ directory
Files:
app/views/UserPreferencesView/index.tsx
🔇 Additional comments (2)
app/definitions/IUser.ts (1)
115-115: Type addition is clean and correctly scoped.
enableMobileRinging?: booleaninINotificationPreferencesis a good extension point for the new preference flow.app/views/UserPreferencesView/index.tsx (1)
138-153: Version gating is correctly implemented for the new preference UI.Rendering the row only for
serverVersion >= 6.10.0matches the PR objective and avoids exposing unsupported settings.
| const toggleEnableMobileRinging = async (value: boolean) => { | ||
| try { | ||
| dispatch(setUser({ settings: { ...settings, preferences: { enableMobileRinging: value } } } as Partial<IUser>)); | ||
| await saveUserPreferences({ enableMobileRinging: value }); |
There was a problem hiding this comment.
Prevent sibling preference loss in local state updates.
At Line 64, the dispatched payload sets preferences to only { enableMobileRinging: value }, which can drop other settings.preferences fields in memory. Merge the existing preferences object when updating.
Proposed fix
const toggleEnableMobileRinging = async (value: boolean) => {
try {
- dispatch(setUser({ settings: { ...settings, preferences: { enableMobileRinging: value } } } as Partial<IUser>));
+ dispatch(
+ setUser({
+ settings: {
+ ...settings,
+ preferences: {
+ ...settings?.preferences,
+ enableMobileRinging: value
+ }
+ }
+ } as Partial<IUser>)
+ );
await saveUserPreferences({ enableMobileRinging: value });
} catch (e) {
log(e);
}
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const toggleEnableMobileRinging = async (value: boolean) => { | |
| try { | |
| dispatch(setUser({ settings: { ...settings, preferences: { enableMobileRinging: value } } } as Partial<IUser>)); | |
| await saveUserPreferences({ enableMobileRinging: value }); | |
| const toggleEnableMobileRinging = async (value: boolean) => { | |
| try { | |
| dispatch( | |
| setUser({ | |
| settings: { | |
| ...settings, | |
| preferences: { | |
| ...settings?.preferences, | |
| enableMobileRinging: value | |
| } | |
| } | |
| } as Partial<IUser>) | |
| ); | |
| await saveUserPreferences({ enableMobileRinging: value }); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/views/UserPreferencesView/index.tsx` around lines 62 - 65, The dispatched
payload in toggleEnableMobileRinging overwrites the entire preferences object
with only enableMobileRinging, losing sibling preference fields; update the
dispatch to merge existing preferences (use settings.preferences or
settings?.preferences) into the new preferences object so you dispatch setUser
with settings: { ...settings, preferences: { ...settings.preferences,
enableMobileRinging: value } } and then call saveUserPreferences as before.
2143aba to
2a098f7
Compare
Proposed changes
Adds an Enable Mobile Ringing toggle to
UserPreferencesView, matching the web client. When enabled, incoming video conference calls ring the device like a phone call. Server-side enterprise kill switch (VideoConf_Mobile_Ringing) is enforced silently by the server; no client-side check needed for MVP.INotificationPreferences: adds optionalenableMobileRinging?: booleanUserPreferencesView: adds version-gated (server >= 6.10.0)Switchwired tosaveUserPreferences()+dispatch(setUser(...)), following the existingconvertAsciiEmojipatternen.json: addsEnable_Mobile_RingingkeyIssue(s)
https://rocketchat.atlassian.net/browse/VMUX-72
How to test or reproduce
users.setPreferencesis called withenableMobileRinging: <value>.Screenshots
N/A
Types of changes
Checklist
Further comments
Targets
feat.voip-lib-new(notdevelop) since this stacks on the VoIP feature branch. MVP scope per ~/plans/enable-mobile-ringing/plan.md — no enterprise kill switch check (server enforces silently), no test additions (deferred).Summary by CodeRabbit
New Features
Localization