Skip to content

feat: add Enable Mobile Ringing toggle in user preferences#7155

Open
diegolmello wants to merge 11 commits intofeat.voip-lib-newfrom
chore/enable-mobile-ringing
Open

feat: add Enable Mobile Ringing toggle in user preferences#7155
diegolmello wants to merge 11 commits intofeat.voip-lib-newfrom
chore/enable-mobile-ringing

Conversation

@diegolmello
Copy link
Copy Markdown
Member

@diegolmello diegolmello commented Apr 14, 2026

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 optional enableMobileRinging?: boolean
  • UserPreferencesView: adds version-gated (server >= 6.10.0) Switch wired to saveUserPreferences() + dispatch(setUser(...)), following the existing convertAsciiEmoji pattern
  • en.json: adds Enable_Mobile_Ringing key

Issue(s)

https://rocketchat.atlassian.net/browse/VMUX-72

How to test or reproduce

  1. Connect to a Rocket.Chat server with version >= 6.10.0.
  2. Go to Profile → Preferences.
  3. Verify the Enable Mobile Ringing toggle is visible in the preferences section.
  4. Toggle it on/off and verify users.setPreferences is called with enableMobileRinging: <value>.
  5. Connect to a server < 6.10.0 and verify the toggle is NOT visible.

Screenshots

N/A

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • Improvement (non-breaking change which improves a current function)
  • New feature (non-breaking change which adds functionality)
  • Documentation update (if none of the other choices apply)

Checklist

  • I have read the CONTRIBUTING doc
  • I have signed the CLA
  • Lint and unit tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works (if applicable)
  • I have added necessary documentation (if applicable)
  • Any dependent changes have been merged and published in downstream modules

Further comments

Targets feat.voip-lib-new (not develop) 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

    • Users can now configure mobile ringing notifications through a new toggle in their notification settings. This provides fine-grained control over whether the mobile device rings for incoming alerts and messages. Configuration is automatically saved and persists across sessions and devices.
  • Localization

    • Added English language translations for the new mobile ringing notification setting.

@diegolmello diegolmello requested a deployment to approve_e2e_testing April 14, 2026 19:21 — with GitHub Actions Waiting
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 14, 2026

Walkthrough

Implements a mobile ringing preference feature by adding a new enableMobileRinging field to user notification preferences, providing i18n translation, and creating a conditional UI toggle in user preferences that persists changes to the server for compatible versions (6.10.0+).

Changes

Cohort / File(s) Summary
Type Definitions & Localization
app/definitions/IUser.ts, app/i18n/locales/en.json
Added optional enableMobileRinging field to INotificationPreferences interface and corresponding i18n string key for mobile ringing label.
User Preferences UI
app/views/UserPreferencesView/index.tsx
Implemented toggle handler for mobile ringing preference that updates Redux state and persists via saveUserPreferences(). Conditionally renders preference switch only for server versions ≥ 6.10.0.

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested Labels

type: feature

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding an Enable Mobile Ringing toggle to user preferences, which is the primary feature across all modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ 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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
app/views/UserPreferencesView/index.tsx (1)

30-30: Normalize enableMobileRinging to a boolean before binding/toggling.

Using a default boolean avoids undefined-driven toggle behavior and keeps Switch usage 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

📥 Commits

Reviewing files that changed from the base of the PR and between 2143aba and 8f0bec8.

📒 Files selected for processing (3)
  • app/definitions/IUser.ts
  • app/i18n/locales/en.json
  • app/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.json
  • app/definitions/IUser.ts
  • app/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-config base configuration including React, React Native, TypeScript, and Jest plugins

Files:

  • app/definitions/IUser.ts
  • app/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.ts
  • app/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.ts
  • app/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?: boolean in INotificationPreferences is 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.0 matches the PR objective and avoids exposing unsupported settings.

Comment on lines +62 to +65
const toggleEnableMobileRinging = async (value: boolean) => {
try {
dispatch(setUser({ settings: { ...settings, preferences: { enableMobileRinging: value } } } as Partial<IUser>));
await saveUserPreferences({ enableMobileRinging: value });
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.

⚠️ Potential issue | 🟠 Major

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.

Suggested change
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.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant