Skip to content

feat: action sheet bottom blank space#7390

Open
OtavioStasiak wants to merge 22 commits into
developfrom
fix/actionsheet-safe-area-spacing
Open

feat: action sheet bottom blank space#7390
OtavioStasiak wants to merge 22 commits into
developfrom
fix/actionsheet-safe-area-spacing

Conversation

@OtavioStasiak

@OtavioStasiak OtavioStasiak commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Proposed changes

Removes the extra blank space at the bottom of action-sheet content. These views
were adding marginBottom: insets.bottom on top of the safe-area inset the action
sheet already applies, producing a double gap:

  • DirectoryView/Options, MediaAutoDownloadView/ListPicker, RoomsListView/ServersList
    — drop the redundant marginBottom (and the now-unused useSafeAreaInsets).
  • UserNotificationPreferencesView/ListPicker — switch marginBottom → paddingBottom
    so the inset sits inside the content.

Issue(s)

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

How to test or reproduce

  1. Servers list — Rooms list header → tap the server name/avatar (top-left) to open
    the servers list sheet.
  2. Directory options — Search/Directory view → tap the filter/options control.
  3. Media auto-download — Settings → Media auto-download → tap one of the options
    (e.g. Images) to open its picker sheet.
  4. Notification preferences — Room → Notification Preferences → tap an option (e.g.
    Alert) to open its picker sheet.

Screenshots

ServersList (Before) ServersList (After)
Simulator Screenshot - iPhone 16 - 2026-06-16 at 20 16 43 Simulator Screenshot - iPhone 16 - 2026-06-16 at 20 07 06
ServersList Landscape (Before) ServersList Landscape (After)
Simulator Screenshot - iPhone 16 - 2026-06-16 at 20 16 50 Simulator Screenshot - iPhone 16 - 2026-06-16 at 20 07 18
DirectoryOptions (Before) DirectoryOptions (After)
Simulator Screenshot - iPhone 16 - 2026-06-16 at 20 17 26 Simulator Screenshot - iPhone 16 - 2026-06-16 at 20 07 30
MediaAutoDownload (Before) MediaAutoDownload (After)
Simulator Screenshot - iPhone 16 - 2026-06-16 at 20 17 03 Simulator Screenshot - iPhone 16 - 2026-06-16 at 20 07 54
NotificationPreferences (Before) NotificationPreferences (After)
Simulator Screenshot - iPhone 16 - 2026-06-16 at 20 17 13 Simulator Screenshot - iPhone 16 - 2026-06-16 at 20 11 08

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

  • Refactor

    • Improved safe-area handling for bottom spacing in action sheets and option pickers across Directory options, Media auto-download, server list, and notification preferences (removing bottom inset marginBottom and adjusting how bottom spacing is applied for consistent layout).
  • Tests

    • Added/updated Jest tests to ensure action sheet content doesn’t double-apply the bottom safe-area inset.
    • Added a Maestro regression test (“Action Sheet Safe Area”) covering both Workspaces and Directory filter action sheets.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Three view components (DirectoryView/Options, MediaAutoDownloadView/ListPicker) remove useSafeAreaInsets entirely and drop marginBottom: insets.bottom. RoomsListView/ServersList also removes safe-area insets but now uses useWindowDimensions with a new layout helper getServersListMaxHeight() to compute dynamic list heights. UserNotificationPreferencesView/ListPicker retains insets but changes marginBottom to paddingBottom. Unit tests and a Maestro E2E test validate the safe-area behavior across all components.

Changes

Safe-area inset bottom spacing cleanup and validation

Layer / File(s) Summary
Remove useSafeAreaInsets bottom margin from DirectoryView and MediaAutoDownloadView with unit tests
app/views/DirectoryView/Options.tsx, app/views/DirectoryView/Options.test.tsx, app/views/MediaAutoDownloadView/ListPicker.tsx, app/views/MediaAutoDownloadView/ListPicker.test.tsx
DirectoryView/Options and MediaAutoDownloadView/ListPicker each remove the useSafeAreaInsets import and hook call, and drop marginBottom: insets.bottom from the container style. Unit tests verify that marginBottom is not set when the mocked safe-area inset is non-zero.
New layout helper module for ServersList height calculation
app/views/RoomsListView/components/serversListLayout.ts, app/views/RoomsListView/components/serversListLayout.test.ts
New serversListLayout.ts module exports row sizing constants and getServersListMaxHeight(windowHeight) function that computes a clamped list height based on fixed chrome and action-sheet maximum height fraction. Tests verify portrait/landscape behavior, shrink-to-fit logic, and minimum height guarantees.
ServersList refactoring to use window dimensions and new layout helper
app/views/RoomsListView/components/ServersList.tsx
RoomsListView/ServersList replaces useSafeAreaInsets with useWindowDimensions, removes safe-area-based marginBottom from the header, and switches FlatList maxHeight from a static calculation to dynamic getServersListMaxHeight(windowHeight) for responsive list sizing.
Switch marginBottom to paddingBottom in UserNotificationPreferencesView/ListPicker with unit test
app/views/UserNotificationPreferencesView/ListPicker.tsx, app/views/UserNotificationPreferencesView/ListPicker.test.tsx
The getOptions container <View> changes its safe-area bottom handling from marginBottom: insets.bottom to paddingBottom: insets.bottom. Unit test asserts marginBottom is not applied.
Maestro E2E test for action sheet safe-area behavior
.maestro/tests/assorted/action-sheet-safe-area.yaml
Test validates action sheet bottom spacing across Workspaces (ServersList) and Directory filter (DirectoryOptions) action sheets, ensuring bottom-row elements remain visible and accessible after the safe-area spacing changes.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~13 minutes

Suggested reviewers

  • diegolmello
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: action sheet bottom blank space' directly describes the main change: fixing extra blank space at the bottom of action sheets, which is the core issue addressed throughout the PR.
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.
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.

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • NATIVE-1254: 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 and others added 4 commits June 9, 2026 18:13
Add a local "run & compare" command and a GitHub Actions flow for the
action-sheet visual regression, both sourcing baselines from the reference
repo (OtavioStasiak/Rocket.Chat.ReactNative.VisualRegressionTest).

- scripts/owl-compare.sh + pnpm owl:compare:{ios,android}: pull the prints
  for the current OWL_VARIANT into .owl/baseline/<platform>/ (the only path
  owl reads), run owl test, open the report.
- CI: orchestrator visual-regression.yml fans out build->run reusable
  workflows over 4 legs (iPhone 16 Pro, iPhone SE 3rd gen, Android portrait,
  Android landscape). Build once per platform, run downloads the app artifact
  to the path owl installs from.
- owl.config.json: android packageName chat.rocket.android.
- .owl/.gitignore: baselines/reference are pulled, never committed here.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Mirror e2e's e2e-hold: a `hold` job on the protected `approve_e2e_testing`
environment that build-ios and build-android depend on, so the macOS + emulator
legs only run after a reviewer approves.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Android: build.gradle reads a BugsnagAPIKey gradle property into a manifest
  placeholder; provide a dummy value (Owl builds are throwaway, never uploaded)
  so config evaluation doesn't fail with "unknown property 'BugsnagAPIKey'".
- iOS: the runner doesn't pre-create named simulators for the selected Xcode, so
  "iPhone 16 Pro"/"iPhone SE (3rd generation)" were Invalid device. Resolve by
  name and create on the latest available iOS runtime if missing, boot by UDID.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The reference-repo prints were captured locally and can never match a CI
render (owl is pixel-exact; cross-machine font hinting, a 1px sheet offset and
the status-bar clock format all differ). Goldens must be captured by CI.

In update_baseline mode each run leg now uploads owl-baseline-<variant> with
just the correctly-named PNGs, so seeding the reference repo is a drag-and-drop.
Documented the CI-golden flow in tests/owl/README.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- iOS: pin the simulator runtime (OWL_IOS_RUNTIME); create the device on exactly
  that runtime and fail loudly if absent, so baselines can't silently drift on a
  runner image bump. Force 24-hour time so owl's "9:41" status-bar stamp renders
  identically regardless of region (09:41 vs 9:41 AM).
- Android: owl doesn't manage the status bar, so enter SystemUI demo mode to
  freeze the clock/battery/network and set 24-hour time before running.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Owl captures the full device screen and its matcher passes only at zero
pixel diff, so the live status-bar clock/battery/signal made every
baseline fail. Patch the matcher to zero the top OWL_MASK_TOP px of both
images before pixelmatch (default 0 = no-op) and set a per-variant mask
height from the owl test, so the top bar is excluded while the app below
is still verified. Source-agnostic for future Maestro screenshots.

Also drop default React imports in the owl host files to satisfy lint.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This view intentionally keeps the bottom safe-area inset as paddingBottom,
so assert it equals the inset to pin the intended behaviour.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🤖 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/UserNotificationPreferencesView/ListPicker.tsx`:
- Line 41: The View component with backgroundColor: colors.surfaceRoom is
missing the safe-area inset padding that was removed during refactoring. Add
paddingBottom: insets.bottom to the style object of this View to ensure content
properly reserves internal bottom space for the safe area, while keeping the
marginBottom removal intact.
🪄 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: 6fff9caa-42c8-42b4-ad4f-a93be5cfccee

📥 Commits

Reviewing files that changed from the base of the PR and between cbd23fa and e6c40e2.

📒 Files selected for processing (1)
  • app/views/UserNotificationPreferencesView/ListPicker.tsx
📜 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 (5)
**/*.{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/views/UserNotificationPreferencesView/ListPicker.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 enabled

Files:

  • app/views/UserNotificationPreferencesView/ListPicker.tsx
**/*.{js,jsx,ts,tsx,json}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Prettier formatting with tabs, single quotes, 130 character line width, no trailing commas, and avoid arrow function parentheses

Files:

  • app/views/UserNotificationPreferencesView/ListPicker.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Enforce ESLint rules from @rocket.chat/eslint-config with React, React Native, TypeScript, and Jest plugins

Files:

  • app/views/UserNotificationPreferencesView/ListPicker.tsx
app/views/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Place screen components in 'app/views/' directory

Files:

  • app/views/UserNotificationPreferencesView/ListPicker.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/views/UserNotificationPreferencesView/ListPicker.tsx

Comment thread app/views/UserNotificationPreferencesView/ListPicker.tsx
Comment thread app/views/DirectoryView/Options.test.tsx Outdated
@github-actions

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

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.

2 participants