feat: Login on web#7360
Conversation
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughFilters services that opt out of mobile buttons, introduces a reusable ServiceList that can render an optional “Login on web” button (opens server web login via Linking), wires filtered services and layout changes into LoginServices, adds Storybook stories, and updates locale keys for the new label. ChangesMobile Login on Web Feature
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
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 (1)
app/containers/LoginServices/index.tsx (1)
63-63: ⚡ Quick winSimplify the boolean check.
The
=== truecomparison is redundant when the result is already wrapped inBoolean(). Thefind()method returns either a truthy value (the service object) orundefined, so the explicit comparison adds no value.♻️ Proposed simplification
-const showLoginOnWeb = Boolean(Object.values(services).find((service: IItemService) => service.hideButtonOnMobile === true)); +const showLoginOnWeb = Boolean(Object.values(services).find((service: IItemService) => service.hideButtonOnMobile));🤖 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/containers/LoginServices/index.tsx` at line 63, The boolean expression for showLoginOnWeb is overcomplicated: remove the redundant "=== true" and simplify the check by using the truthiness of the found service (e.g., use Object.values(services).find(...) directly wrapped with Boolean or use .some(...)) so that the expression references services, IItemService, and hideButtonOnMobile and relies on find()/some() returning a truthy value instead of comparing to true.
🤖 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/containers/LoginServices/index.tsx`:
- Around line 39-46: The call to Linking.openURL inside the conditional render
(when showLoginOnWeb is true) is unhandled and may reject; update the Button
onPress handler in LoginServices so
Linking.openURL(`${server}/home?loginClient=mobile`) is explicitly handled with
a Promise rejection handler (e.g., .catch(err => /* log or show error */)) to
satisfy ESLint's no-void rule and avoid unhandled rejections; keep the same
URL/template and ensure the catch logs or surfaces the error (using the app
logger or console) rather than leaving the promise unhandled.
---
Nitpick comments:
In `@app/containers/LoginServices/index.tsx`:
- Line 63: The boolean expression for showLoginOnWeb is overcomplicated: remove
the redundant "=== true" and simplify the check by using the truthiness of the
found service (e.g., use Object.values(services).find(...) directly wrapped with
Boolean or use .some(...)) so that the expression references services,
IItemService, and hideButtonOnMobile and relies on find()/some() returning a
truthy value instead of comparing to true.
🪄 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: c0aeed82-c575-4ea4-992d-1366f08eb79f
📒 Files selected for processing (3)
app/containers/LoginServices/index.tsxapp/containers/LoginServices/interfaces.tsapp/i18n/locales/en.json
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: ESLint and Test / run-eslint-and-test
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{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/containers/LoginServices/interfaces.tsapp/containers/LoginServices/index.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{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 numbersUse TypeScript with strict mode and baseUrl set to app/ for import resolution
Files:
app/containers/LoginServices/interfaces.tsapp/containers/LoginServices/index.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,js,jsx}: Use Prettier with tabs, single quotes, 130 char width, no trailing commas, arrow parens avoid, bracket same line
Use@rocket.chat/eslint-configbase with React, React Native, TypeScript, Jest plugins
Files:
app/containers/LoginServices/interfaces.tsapp/containers/LoginServices/index.tsx
app/containers/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Reusable UI components should be placed in app/containers/ directory
Files:
app/containers/LoginServices/interfaces.tsapp/containers/LoginServices/index.tsx
🧠 Learnings (1)
📚 Learning: 2026-04-30T17:07:51.020Z
Learnt from: diegolmello
Repo: RocketChat/Rocket.Chat.ReactNative PR: 7274
File: app/lib/services/voip/MediaCallEvents.ts:0-0
Timestamp: 2026-04-30T17:07:51.020Z
Learning: In this Rocket.Chat React Native codebase, the ESLint rule `no-void: error` is enforced. When you see a promise returned from an async call that is not awaited (a “floating promise”), do not silence it with the `void somePromise()` pattern. Instead, handle the promise explicitly by attaching `.catch(...)` (or otherwise awaiting/handling the error) so unhandled-rejection risks are addressed in a way that satisfies the existing ESLint configuration.
Applied to files:
app/containers/LoginServices/interfaces.tsapp/containers/LoginServices/index.tsx
🔇 Additional comments (6)
app/containers/LoginServices/interfaces.ts (1)
27-27: LGTM!app/containers/LoginServices/index.tsx (4)
64-67: LGTM!
77-77: LGTM!
86-92: LGTM!
107-113: LGTM!app/i18n/locales/en.json (1)
517-517: LGTM!
diegolmello
left a comment
There was a problem hiding this comment.
Also missing stories and tests
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (1)
app/containers/LoginServices/ServiceList.tsx (1)
39-39:⚠️ Potential issue | 🟠 Major | ⚡ Quick winAdd error handling for
Linking.openURL.
Linking.openURLreturns a Promise that can reject if the URL cannot be opened. The unhandled rejection could cause runtime errors. Based on learnings, you must handle the promise explicitly with.catch(...)to satisfy ESLint'sno-void: errorrule.🛡️ Proposed fix to add error handling
onPress={() => { - Linking.openURL(`${server}/home?loginClient=mobile`); + Linking.openURL(`${server}/home?loginClient=mobile`).catch(err => { + console.error('Failed to open login URL:', err); + }); }}🤖 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/containers/LoginServices/ServiceList.tsx` at line 39, Linking.openURL(`${server}/home?loginClient=mobile`) can reject and currently has no error handling; update the call in ServiceList.tsx (the Linking.openURL invocation) to handle the returned Promise by chaining a .catch(...) that logs or reports the error (e.g., via console.error or the app's logger) so the rejection is handled and satisfies ESLint no-void rule, and ensure any used logger is imported or available in the component.
🧹 Nitpick comments (2)
app/containers/LoginServices/ServiceList.tsx (2)
17-17: ⚡ Quick winAdd explanatory comment for button visibility logic.
The condition
(!collapsed || Object.keys(services).length <= 2)is not immediately clear. Consider adding a comment explaining why the button should be shown when there are 2 or fewer services, even when collapsed.📝 Suggested improvement
+// Show button when expanded, or when collapsed but only 2 or fewer services are visible const enableLoginOnWebButton = showLoginOnWebButton && (!collapsed || Object.keys(services).length <= 2);🤖 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/containers/LoginServices/ServiceList.tsx` at line 17, Add a short inline comment above the enableLoginOnWebButton declaration explaining the visibility rule: that showLoginOnWebButton gates overall visibility, but when the list is collapsed the button is still shown if there are two or fewer services to ensure access to limited service sets; reference the variables used (enableLoginOnWebButton, showLoginOnWebButton, collapsed, services) and briefly state why Object.keys(services).length <= 2 overrides the collapsed state.
8-16: ⚡ Quick winAdd explicit return type annotation.
The function lacks an explicit return type annotation. As per coding guidelines, TypeScript functions should have explicit return types for better type safety and documentation.
🔧 Proposed fix
-const ServiceList = ({ +const ServiceList = ({ services, CAS_enabled, CAS_login_url, Gitlab_URL, server, collapsed, showLoginOnWebButton -}: IServiceList & { showLoginOnWebButton: boolean }) => { +}: IServiceList & { showLoginOnWebButton: boolean }): React.ReactElement => {As per coding guidelines: Use TypeScript for type safety; add explicit type annotations to function parameters and return types.
🤖 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/containers/LoginServices/ServiceList.tsx` around lines 8 - 16, The ServiceList component is missing an explicit return type; update its declaration to include a TypeScript return annotation (e.g., use React.FC<IServiceList & { showLoginOnWebButton: boolean }> or annotate the arrow function return as JSX.Element) so ServiceList, its props type (IServiceList & { showLoginOnWebButton: boolean }) and the returned JSX are explicitly typed; locate the ServiceList declaration to apply the change.
🤖 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/containers/LoginServices/index.tsx`:
- Line 7: Remove the unused import IItemService from the top of LoginServices
(the import statement "import { type IItemService } from './interfaces';" in
index.tsx) since it is never referenced; simply delete that named import so the
file only imports used symbols and rerun linting to confirm no remaining unused
imports.
- Around line 30-31: Remove the stray debug console.log statements that print
filteredServices, enableLoginOnWebButton, and allServices in the LoginServices
component; locate the lines that call console.log('filteredServices',
filteredServices, 'enableLoginOnWebButton', enableLoginOnWebButton) and
console.log('allServices', allServices) and delete them (or replace with a
proper logger call if persistent runtime logging is required), ensuring no debug
console output remains in index.tsx.
In `@app/containers/LoginServices/LoginServices.stories.tsx`:
- Line 99: Rename the two story functions that contain a typo: change
ServciceListCollapsed to ServiceListCollapsed and ServciceListUncollapsed to
ServiceListUncollapsed in the LoginServices.stories file; update any references
or exports that use the old names (e.g., the functions declared as
ServciceListCollapsed and ServciceListUncollapsed) so the identifiers and any
places importing/using them match the corrected spellings.
---
Duplicate comments:
In `@app/containers/LoginServices/ServiceList.tsx`:
- Line 39: Linking.openURL(`${server}/home?loginClient=mobile`) can reject and
currently has no error handling; update the call in ServiceList.tsx (the
Linking.openURL invocation) to handle the returned Promise by chaining a
.catch(...) that logs or reports the error (e.g., via console.error or the app's
logger) so the rejection is handled and satisfies ESLint no-void rule, and
ensure any used logger is imported or available in the component.
---
Nitpick comments:
In `@app/containers/LoginServices/ServiceList.tsx`:
- Line 17: Add a short inline comment above the enableLoginOnWebButton
declaration explaining the visibility rule: that showLoginOnWebButton gates
overall visibility, but when the list is collapsed the button is still shown if
there are two or fewer services to ensure access to limited service sets;
reference the variables used (enableLoginOnWebButton, showLoginOnWebButton,
collapsed, services) and briefly state why Object.keys(services).length <= 2
overrides the collapsed state.
- Around line 8-16: The ServiceList component is missing an explicit return
type; update its declaration to include a TypeScript return annotation (e.g.,
use React.FC<IServiceList & { showLoginOnWebButton: boolean }> or annotate the
arrow function return as JSX.Element) so ServiceList, its props type
(IServiceList & { showLoginOnWebButton: boolean }) and the returned JSX are
explicitly typed; locate the ServiceList declaration to apply the change.
🪄 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: 25adeb57-96dd-4b86-a322-fc1afb3f83cc
📒 Files selected for processing (27)
app/containers/LoginServices/LoginServices.stories.tsxapp/containers/LoginServices/ServiceList.tsxapp/containers/LoginServices/index.tsxapp/i18n/locales/ar.jsonapp/i18n/locales/bn-IN.jsonapp/i18n/locales/cs.jsonapp/i18n/locales/de.jsonapp/i18n/locales/es.jsonapp/i18n/locales/fi.jsonapp/i18n/locales/fr.jsonapp/i18n/locales/hi-IN.jsonapp/i18n/locales/hu.jsonapp/i18n/locales/it.jsonapp/i18n/locales/ja.jsonapp/i18n/locales/nl.jsonapp/i18n/locales/nn.jsonapp/i18n/locales/no.jsonapp/i18n/locales/pt-BR.jsonapp/i18n/locales/pt-PT.jsonapp/i18n/locales/ru.jsonapp/i18n/locales/sl-SI.jsonapp/i18n/locales/sv.jsonapp/i18n/locales/ta-IN.jsonapp/i18n/locales/te-IN.jsonapp/i18n/locales/tr.jsonapp/i18n/locales/zh-CN.jsonapp/i18n/locales/zh-TW.json
✅ Files skipped from review due to trivial changes (13)
- app/i18n/locales/bn-IN.json
- app/i18n/locales/es.json
- app/i18n/locales/te-IN.json
- app/i18n/locales/it.json
- app/i18n/locales/hi-IN.json
- app/i18n/locales/cs.json
- app/i18n/locales/ta-IN.json
- app/i18n/locales/sl-SI.json
- app/i18n/locales/hu.json
- app/i18n/locales/nl.json
- app/i18n/locales/ar.json
- app/i18n/locales/zh-CN.json
- app/i18n/locales/tr.json
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: format
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{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/containers/LoginServices/ServiceList.tsxapp/containers/LoginServices/LoginServices.stories.tsxapp/containers/LoginServices/index.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{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 numbersUse TypeScript with strict mode and baseUrl set to app/ for import resolution
Files:
app/containers/LoginServices/ServiceList.tsxapp/containers/LoginServices/LoginServices.stories.tsxapp/containers/LoginServices/index.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,js,jsx}: Use Prettier with tabs, single quotes, 130 char width, no trailing commas, arrow parens avoid, bracket same line
Use@rocket.chat/eslint-configbase with React, React Native, TypeScript, Jest plugins
Files:
app/containers/LoginServices/ServiceList.tsxapp/containers/LoginServices/LoginServices.stories.tsxapp/containers/LoginServices/index.tsx
app/containers/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Reusable UI components should be placed in app/containers/ directory
Files:
app/containers/LoginServices/ServiceList.tsxapp/containers/LoginServices/LoginServices.stories.tsxapp/containers/LoginServices/index.tsx
🧠 Learnings (2)
📚 Learning: 2026-04-30T17:07:51.020Z
Learnt from: diegolmello
Repo: RocketChat/Rocket.Chat.ReactNative PR: 7274
File: app/lib/services/voip/MediaCallEvents.ts:0-0
Timestamp: 2026-04-30T17:07:51.020Z
Learning: In this Rocket.Chat React Native codebase, the ESLint rule `no-void: error` is enforced. When you see a promise returned from an async call that is not awaited (a “floating promise”), do not silence it with the `void somePromise()` pattern. Instead, handle the promise explicitly by attaching `.catch(...)` (or otherwise awaiting/handling the error) so unhandled-rejection risks are addressed in a way that satisfies the existing ESLint configuration.
Applied to files:
app/containers/LoginServices/ServiceList.tsxapp/containers/LoginServices/LoginServices.stories.tsxapp/containers/LoginServices/index.tsx
📚 Learning: 2026-03-15T13:55:42.038Z
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6911
File: app/containers/markdown/Markdown.stories.tsx:104-104
Timestamp: 2026-03-15T13:55:42.038Z
Learning: In Rocket.Chat React Native, the markdown parser requires a space between the underscore wrapping italic text and a mention sigil (_ mention _ instead of _mention_). Ensure stories and tests that include italic-wrapped mentions follow this form to guarantee proper parsing. Specifically, for files like app/containers/markdown/Markdown.stories.tsx, and any test/content strings that exercise italic-mentions, use the pattern _ mention _ (with spaces) to prevent the mention from being treated as plain text. Validate any test strings or story content accordingly.
Applied to files:
app/containers/LoginServices/LoginServices.stories.tsx
🪛 ESLint
app/containers/LoginServices/index.tsx
[error] 7-7: 'IItemService' is defined but never used.
(@typescript-eslint/no-unused-vars)
🪛 GitHub Check: ESLint and Test / run-eslint-and-test
app/containers/LoginServices/index.tsx
[failure] 7-7:
'IItemService' is defined but never used
🔇 Additional comments (11)
app/i18n/locales/pt-PT.json (1)
321-321: LGTM!app/i18n/locales/ru.json (1)
433-433: LGTM!app/i18n/locales/sv.json (1)
442-442: LGTM!app/i18n/locales/zh-TW.json (1)
356-356: LGTM!app/i18n/locales/de.json (1)
462-462: LGTM!app/i18n/locales/fi.json (1)
443-443: LGTM!app/i18n/locales/fr.json (1)
408-408: LGTM!app/i18n/locales/ja.json (1)
327-327: LGTM!app/i18n/locales/nn.json (1)
254-254: LGTM!app/i18n/locales/no.json (1)
496-496: LGTM!app/i18n/locales/pt-BR.json (1)
512-512: LGTM!
| </> | ||
| ); | ||
|
|
||
| export const ServciceListCollapsed = () => { |
There was a problem hiding this comment.
Fix typo in story function names.
The function names contain a typo: ServciceListCollapsed and ServciceListUncollapsed should be ServiceListCollapsed and ServiceListUncollapsed.
✏️ Proposed fix
-export const ServciceListCollapsed = () => {
+export const ServiceListCollapsed = () => {
return (
<ServiceListTest
services={services}
CAS_enabled={false}
CAS_login_url=''
Gitlab_URL=''
server='https://demo.rocket.chat'
collapsed={true}
showLoginOnWebButton={true}
/>
);
};
-export const ServciceListUncollapsed = () => {
+export const ServiceListUncollapsed = () => {
return (
<ServiceListTest
services={services}
CAS_enabled={false}
CAS_login_url=''
Gitlab_URL=''
server='https://demo.rocket.chat'
collapsed={false}
showLoginOnWebButton={true}
/>
);
};Also applies to: 113-113
🤖 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/containers/LoginServices/LoginServices.stories.tsx` at line 99, Rename
the two story functions that contain a typo: change ServciceListCollapsed to
ServiceListCollapsed and ServciceListUncollapsed to ServiceListUncollapsed in
the LoginServices.stories file; update any references or exports that use the
old names (e.g., the functions declared as ServciceListCollapsed and
ServciceListUncollapsed) so the identifiers and any places importing/using them
match the corrected spellings.
Proposed changes
Hides the required login services buttons and shows new login on web button based on server response.
Requires - Rocket.Chat/Rocket.Chat#40733
Issue(s)
How to test or reproduce
Screenshots
Uncollapsed with Login on web
Collapsed
Types of changes
Checklist
Further comments
PRM-48
Summary by CodeRabbit
New Features
Updates
Localization