Skip to content

Conversation

@OtavioStasiak
Copy link
Contributor

@OtavioStasiak OtavioStasiak commented Sep 22, 2025

Proposed changes

Navigating on iOS is causing a weird issue, such as adding extra padding to the list and breaking the Composer component layout.
This PR prevents premature onBlur events and properly dismisses the keyboard on iOS.

Issue(s)

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

How to test or reproduce

Case I - Swipe back to RoomView;

  • Open the app;
  • Go to room;
  • Open the keyboard;
  • Navigate to RoomInfoView;
  • Go Back using Swipe;

Case II - Swipe back to RoomsListView and navigate to RoomView;

  • Open the app;
  • Go to room;
  • Open the keyboard;
  • Go Back using Swipe;
  • Open the room again;

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

  • Bug Fixes

    • On iOS, back-swipe gestures no longer clear the message input or interrupt autocomplete, preventing accidental loss of focus and suggestions.
  • Improvements

    • Composer now preserves focus and autocomplete state during iOS back-swipe gestures for a more reliable editing experience.
    • Keyboard dismisses appropriately when leaving the composer, reducing UI flicker and unexpected state changes.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 22, 2025

Walkthrough

Adds a new iOS back-swipe handling hook and integrates it into the message composer input; the composer checks the hook's iOSBackSwipe flag on blur to avoid clearing focus or stopping autocomplete during an iOS back-swipe; the hook listens to navigation transitionStart/transitionEnd events and also subscribes to input blur to dismiss the keyboard.

Changes

Cohort / File(s) Summary
Composer input integration
app/containers/MessageComposer/components/ComposerInput.tsx
Integrates useIOSBackSwipeHandler; updates onBlur to consult iOSBackSwipe.current and only clear focus / stop autocomplete when not in an iOS back-swipe gesture.
New iOS back-swipe hook
app/containers/MessageComposer/hooks/useIOSBackSwipeHandler.ts
Adds default-exported useIOSBackSwipeHandler. On iOS, subscribes to navigation transitionStart to set iOSBackSwipe.current = true, subscribes to transitionEnd to reset the ref, subscribes to input blur to dismiss the keyboard, and cleans up listeners on unmount.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User (iOS)
  participant N as Navigation
  participant H as useIOSBackSwipeHandler
  participant C as ComposerInput
  participant D as Device / Keyboard

  U->>N: Begin back-swipe (navigate back)
  N-->>H: transitionStart (closing)
  activate H
  H->>H: set iOSBackSwipe.current = true
  deactivate H

  U->>C: Input loses focus (blur)
  C->>H: check iOSBackSwipe.current
  alt Back-swipe active
    C-->>C: skip clearing focus / stop autocomplete
    C->>H: (may) let hook handle blur
    H->>D: dismiss keyboard (blur handler)
  else No back-swipe
    C-->>C: clear focus and stop autocomplete
    C->>D: dismiss keyboard (normal)
  end

  N-->>H: transitionEnd (closing finished)
  H->>H: set iOSBackSwipe.current = false

  Note over H,C: listeners removed on unmount
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

I hop the edge of a moonlit swipe,
A back-press breeze — I hold my type.
Don’t clear my focus mid-flight,
Let autocomplete stay bright.
Hops and hooks keep UX right. 🐇✨

Pre-merge checks and finishing touches

✅ 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 succinctly describes the iOS swipe-back bug causing extra padding in the messages list and indicates that the PR fixes this issue, which aligns directly with the main change implemented. It is concise, specific, and free of extraneous details. Team members scanning the history will understand the primary intent at a glance.
Linked Issues Check ✅ Passed The PR’s integration of the useIOSBackSwipeHandler hook to conditionally suppress onBlur events and manage keyboard dismissal on iOS directly addresses the NATIVE-1028 requirement to prevent premature focus loss and layout shifts caused by swipe-back gestures. These code changes align with the linked issue’s objective of fixing the extra padding in message and thread views. All implementation details map to the bugfix criteria specified in the issue.
Out of Scope Changes Check ✅ Passed All modifications occur within the ComposerInput component and the new useIOSBackSwipeHandler hook to handle iOS back-swipe behavior, which are directly related to the stated bugfix objectives. There are no alterations to unrelated modules or features. The PR stays tightly scoped to resolving the padding and focus issues described in NATIVE-1028.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix.padding-composer

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7423163 and f70347c.

📒 Files selected for processing (1)
  • app/containers/MessageComposer/hooks/useIOSBackSwipeHandler.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/containers/MessageComposer/hooks/useIOSBackSwipeHandler.ts
⏰ 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

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.

@github-actions
Copy link

iOS Build Available

Rocket.Chat 4.65.0.107359

@github-actions
Copy link

github-actions bot commented Oct 6, 2025

iOS Build Available

Rocket.Chat Experimental 4.65.0.107497

Copy link
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 (1)
app/containers/MessageComposer/hooks/useIOSBackSwipeHandler.ts (1)

14-14: Consider adding type definitions for transition events.

Using as any bypasses TypeScript's type checking. While this works, it reduces type safety and IDE support. Consider defining proper types for the transition events:

type TransitionEvent = {
  data?: {
    closing?: boolean;
  };
};

const transitionStartListener = navigation.addListener(
  'transitionStart' as any,
  (e: TransitionEvent) => {
    if (e?.data?.closing) {
      iOSBackSwipe.current = true;
      Keyboard.dismiss();
    }
  }
);

Apply similar typing to the transitionEnd listener. This provides better IDE autocomplete and catches potential bugs at compile time.

Also applies to: 21-21

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 44db62d and 972e96b.

📒 Files selected for processing (1)
  • app/containers/MessageComposer/hooks/useIOSBackSwipeHandler.ts (1 hunks)
⏰ 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 comments (1)
app/containers/MessageComposer/hooks/useIOSBackSwipeHandler.ts (1)

14-19: LGTM! Correctly handles the start of back-swipe gestures.

The logic properly:

  • Sets the flag only during closing transitions (back navigation)
  • Dismisses the keyboard immediately to prevent layout issues
  • Uses optional chaining to safely check the event data

@github-actions
Copy link

github-actions bot commented Oct 6, 2025

iOS Build Available

Rocket.Chat Experimental 4.65.0.107508

Copy link
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 (1)
app/containers/MessageComposer/hooks/useIOSBackSwipeHandler.ts (1)

14-14: Consider replacing as any with properly typed event names.

The as any assertions bypass TypeScript checks. If React Navigation v7 exports types for transitionStart and transitionEnd events (or you can define them), replace these assertions for better type safety.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 21e5b53 and 7423163.

📒 Files selected for processing (1)
  • app/containers/MessageComposer/hooks/useIOSBackSwipeHandler.ts (1 hunks)
⏰ 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: ESLint and Test / run-eslint-and-test
  • GitHub Check: format
🔇 Additional comments (1)
app/containers/MessageComposer/hooks/useIOSBackSwipeHandler.ts (1)

21-23: LGTM! Correctly resets the flag after any transition.

Unconditionally resetting iOSBackSwipe.current ensures the flag is cleared whether the back-swipe completes or is cancelled. This addresses the critical bug flagged in previous reviews.

@github-actions
Copy link

github-actions bot commented Oct 7, 2025

iOS Build Available

Rocket.Chat Experimental 4.65.0.107509

@OtavioStasiak OtavioStasiak temporarily deployed to approve_e2e_testing October 7, 2025 00:29 — with GitHub Actions Inactive
@OtavioStasiak OtavioStasiak temporarily deployed to experimental_android_build October 7, 2025 00:31 — with GitHub Actions Inactive
@OtavioStasiak OtavioStasiak requested a deployment to official_android_build October 7, 2025 00:31 — with GitHub Actions Waiting
@OtavioStasiak OtavioStasiak temporarily deployed to experimental_ios_build October 7, 2025 00:31 — with GitHub Actions Inactive
@github-actions
Copy link

github-actions bot commented Oct 7, 2025

iOS Build Available

Rocket.Chat Experimental 4.65.0.107510

Copy link
Member

@diegolmello diegolmello left a comment

Choose a reason for hiding this comment

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

Working fine here!
Can you test Android just in case?

I'm just missing a root cause analysis.
What introduced this issue? Did you create an issue on another repo, so we can track and remove this workaround in the future?

@OtavioStasiak OtavioStasiak requested a deployment to upload_experimental_android October 7, 2025 16:06 — with GitHub Actions Waiting
@github-actions
Copy link

github-actions bot commented Oct 7, 2025

Android Build Available

Rocket.Chat Experimental 4.65.0.107513

Internal App Sharing: https://play.google.com/apps/test/RQVpXLytHNc/ahAO29uNTHfsqQASVlbcH39tJeTUlKpkh0vKvSnXrRXhCtdL2XifqZnKBTtclwacfuckGRPFjC1Qv1pxGs6-aT_AGf

@OtavioStasiak OtavioStasiak merged commit 995520d into develop Oct 7, 2025
27 of 37 checks passed
@OtavioStasiak OtavioStasiak deleted the fix.padding-composer branch October 7, 2025 16:26
OtavioStasiak added a commit that referenced this pull request Oct 21, 2025
* fix: on navigate with keyboard opened and go back add a padding on keyboard manager

* fix: onBlur changing isFocused and breaking the composer

* chore: code improvements

* fix: snapshot test

* fix: setFocused and useOnBlur

* fix: snapshot test

* fix: navigation issue

* fix: edge case on navigate userInfo

* chore: code improvements

* chore: code improvements

* chore: code improvements

* fix: iOSBackSwipe reset

* fix: iOSBackSwipe reset

* fix: onback dismiss

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants