Skip to content

chore: migrate DirectoryView to Hooks#7359

Open
OtavioStasiak wants to merge 5 commits into
developfrom
chore.migrate-directoryview-to-hooks
Open

chore: migrate DirectoryView to Hooks#7359
OtavioStasiak wants to merge 5 commits into
developfrom
chore.migrate-directoryview-to-hooks

Conversation

@OtavioStasiak
Copy link
Copy Markdown
Contributor

@OtavioStasiak OtavioStasiak commented May 28, 2026

Proposed changes

Migrate DirectoryView to Hooks.

Issue(s)

https://rocketchat.atlassian.net/browse/NATIVE-16

How to test or reproduce

Screenshots

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

Summary by CodeRabbit

  • New Features

    • Directory search with pagination, type filtering, and workspace-scope selection
    • Accessibility announcements for search results (localized, singular/plural/no-results)
  • Refactor

    • Directory view converted to a hook-based functional component for smoother UI and navigation
    • Shared accessibility announcement logic consolidated and reused across search screens

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 58e99bb9-1abc-4fa6-b0d2-3974660897bd

📥 Commits

Reviewing files that changed from the base of the PR and between 95ed5a8 and c31d760.

📒 Files selected for processing (2)
  • app/views/DirectoryView/hooks/useDirectorySearch.ts
  • app/views/DirectoryView/index.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • app/views/DirectoryView/index.tsx
  • app/views/DirectoryView/hooks/useDirectorySearch.ts
📜 Recent 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). (2)
  • GitHub Check: E2E Build iOS / ios-build
  • GitHub Check: E2E Build Android / android-build

Walkthrough

DirectoryView is refactored from a Redux-connected class component to a hook-based functional component. A new useDirectorySearch hook centralizes search state management, pagination, and result announcement. A shared accessibility helper is extracted and reused across search hooks to announce result counts.

Changes

DirectoryView functional refactoring

Layer / File(s) Summary
Shared accessibility announcement helper
app/lib/methods/helpers/announceSearchResultsForAccessibility.ts, app/lib/methods/helpers/index.ts
New announceSearchResultsForAccessibility helper announces localized search result messages (no results, singular, or plural) via AccessibilityInfo.announceForAccessibility and is re-exported from the helpers index.
useDirectorySearch hook
app/views/DirectoryView/hooks/useDirectorySearch.ts
New hook manages directory search state (text, type, workspace scope, accumulated results, loading, total count), debounces search requests, handles pagination, announces accessibility results via the shared helper, and exposes stable callbacks for search text/type changes, result loading, workspace toggling with analytics, and initial mount search.
DirectoryView component migration
app/views/DirectoryView/index.tsx
Converts DirectoryView from a Redux-connected class component to a functional component using useAppSelector for federation/theme state and useDirectorySearch for search logic. Header options and filter ActionSheet are wired in useLayoutEffect. Navigation handlers (goRoom, onPressItem) are refactored to functional implementations with preserved branching for direct messages, subscriptions, and room joins. List rendering uses new functional renderHeader and renderItem helpers with theme-aware styling.
Consolidate RoomsListView search accessibility
app/views/RoomsListView/hooks/useSearch.ts
Updates useSearch hook to import and use the shared announceSearchResultsForAccessibility helper instead of maintaining a local accessibility-announcement function, eliminating duplication.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Suggested labels

type: chore

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'chore: migrate DirectoryView to Hooks' accurately reflects the main change, which is converting the DirectoryView component from a Redux-connected class component to a hook-based functional component.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • NATIVE-16: Request failed with status code 401

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.

@OtavioStasiak OtavioStasiak temporarily deployed to approve_e2e_testing May 28, 2026 19:53 — with GitHub Actions Inactive
@OtavioStasiak
Copy link
Copy Markdown
Contributor Author

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@OtavioStasiak OtavioStasiak marked this pull request as ready for review May 28, 2026 19:56
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: 3

🤖 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/views/DirectoryView/hooks/useDirectorySearch.ts`:
- Line 44: The code calls
announceSearchResultsForAccessibility(directories.count) which reports the
current page size and fires on load-more; change it to announce the total result
count only for fresh searches by invoking announceSearchResultsForAccessibility
with the total count (e.g., directories.total or directories.totalCount) and
only when a new search is started — detect a fresh search by comparing the
current query/filters or page/offset reset (e.g., page === 1 or queryRef change)
inside useDirectorySearch, and skip the announcement when handling loadMore.
- Around line 20-43: The debounced load function can apply out-of-order
responses, so add a sequencing guard: create a mutable requestId ref (e.g.,
currentRequestId via useRef) and increment it each time load starts (especially
when newSearch) and capture the id in the async call; after awaiting
getDirectory, only call setData, setTotal, and setLoading if the captured id
matches currentRequestId.current. Use the existing load, getDirectory, setData,
setTotal, and setLoading symbols to locate where to increment/capture/check the
request id and drop results from stale requests.

In `@app/views/DirectoryView/index.tsx`:
- Around line 96-98: The local wrapper goRoom currently calls goRoomMethod({
item, isMasterDetail }) without returning or awaiting its promise, so rejections
are swallowed; change goRoom (in DirectoryView/index.tsx) to return the promise
(e.g., return goRoomMethod(...)) or mark it async and await/return the result,
and update the call sites that invoke goRoom (for example the calls passing {
rid: result.room._id, ... } and goRoom(subscription)) to await the call or
handle the returned promise so errors can be caught (e.g., use await goRoom(...)
inside async handlers or attach .catch where appropriate). Ensure all references
to goRoom and goRoomMethod are updated consistently so rejections propagate to
callers.
🪄 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: 5b9807ad-9800-4c67-adaf-a1106a2de71a

📥 Commits

Reviewing files that changed from the base of the PR and between 815ff6c and 2491c21.

📒 Files selected for processing (5)
  • app/lib/methods/helpers/announceSearchResultsForAccessibility.ts
  • app/lib/methods/helpers/index.ts
  • app/views/DirectoryView/hooks/useDirectorySearch.ts
  • app/views/DirectoryView/index.tsx
  • app/views/RoomsListView/hooks/useSearch.ts
📜 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). (2)
  • GitHub Check: E2E Build Android / android-build
  • 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/lib/methods/helpers/index.ts
  • app/lib/methods/helpers/announceSearchResultsForAccessibility.ts
  • app/views/DirectoryView/hooks/useDirectorySearch.ts
  • app/views/RoomsListView/hooks/useSearch.ts
  • app/views/DirectoryView/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 numbers

Use TypeScript with strict mode and baseUrl set to app/ for import resolution

Files:

  • app/lib/methods/helpers/index.ts
  • app/lib/methods/helpers/announceSearchResultsForAccessibility.ts
  • app/views/DirectoryView/hooks/useDirectorySearch.ts
  • app/views/RoomsListView/hooks/useSearch.ts
  • app/views/DirectoryView/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-config base with React, React Native, TypeScript, Jest plugins

Files:

  • app/lib/methods/helpers/index.ts
  • app/lib/methods/helpers/announceSearchResultsForAccessibility.ts
  • app/views/DirectoryView/hooks/useDirectorySearch.ts
  • app/views/RoomsListView/hooks/useSearch.ts
  • app/views/DirectoryView/index.tsx
app/views/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

View components (70+ screen components) should be placed in app/views/ directory

Files:

  • app/views/DirectoryView/hooks/useDirectorySearch.ts
  • app/views/RoomsListView/hooks/useSearch.ts
  • app/views/DirectoryView/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/lib/methods/helpers/index.ts
  • app/lib/methods/helpers/announceSearchResultsForAccessibility.ts
  • app/views/DirectoryView/hooks/useDirectorySearch.ts
  • app/views/RoomsListView/hooks/useSearch.ts
  • app/views/DirectoryView/index.tsx
🔇 Additional comments (5)
app/lib/methods/helpers/announceSearchResultsForAccessibility.ts (1)

1-13: LGTM!

app/lib/methods/helpers/index.ts (1)

21-21: LGTM!

app/views/DirectoryView/hooks/useDirectorySearch.ts (1)

1-19: LGTM!

Also applies to: 54-103

app/views/DirectoryView/index.tsx (1)

1-95: LGTM!

Also applies to: 140-219

app/views/RoomsListView/hooks/useSearch.ts (1)

6-6: LGTM!

Comment thread app/views/DirectoryView/hooks/useDirectorySearch.ts
Comment thread app/views/DirectoryView/hooks/useDirectorySearch.ts Outdated
Comment thread app/views/DirectoryView/index.tsx
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