Skip to content

Feature FXIOS-16158 [Toolbar] Add an interactive swipe gesture to close a tab and open the tab tray#34539

Closed
Alex-Bangu wants to merge 22 commits into
mainfrom
abangu/swipe-up-address-bar-animation
Closed

Feature FXIOS-16158 [Toolbar] Add an interactive swipe gesture to close a tab and open the tab tray#34539
Alex-Bangu wants to merge 22 commits into
mainfrom
abangu/swipe-up-address-bar-animation

Conversation

@Alex-Bangu

@Alex-Bangu Alex-Bangu commented Jul 6, 2026

Copy link
Copy Markdown
Member

📜 Tickets

Jira ticket
Github issue

💡 Description

Implements a significantly more involved swipe up / pan up gesture. Users will be able to drag up on the address bar to open the tab tray. They will also be able to close the tab if they drag the tab into the top 1/4 of their screen, however this is gated behind a separate feature flag.

Major changes:

  • Two new files that implement a pan gesture handler for the new gesture, SwipeUpTabWebViewPreview.swift and SwipeUpTabPreviewGestureHandler.swift
  • Refactor of the open tab tray animation in TabAnimation.swift

Other changes:

  • Minimal changes to several other files
  • Added a new feature flag switch and did some changes to how we use the existing address bar gesture feature flags

🎥 Demos

Before After
https://github.com/user-attachments/assets/f8d2a79d-9ad3-49b4-a43a-fe811f3eda62 https://github.com/user-attachments/assets/3e14e4c7-a72b-4660-91cd-1ac9e96e7bc0

📝 Checklist

  • I filled in the ticket numbers and a description of my work
  • I updated the PR name to follow our PR naming guidelines
  • I ensured unit tests pass and wrote tests for new code
  • If working on UI, I checked and implemented accessibility (Dynamic Text and VoiceOver)
  • If adding telemetry, I read the data stewardship requirements and will request a data review
  • If adding or modifying strings, I read the guidelines and will request a string review from l10n
  • If needed, I updated documentation and added comments to complex code

@Alex-Bangu Alex-Bangu requested a review from a team as a code owner July 6, 2026 16:03
@mergify

mergify Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

This pull request has conflicts when rebasing. Could you fix it @Alex-Bangu? 🙏

@mobiletest-ci-bot

mobiletest-ci-bot commented Jul 6, 2026

Copy link
Copy Markdown
Fails
🚫

❌ Code coverage

The following file(s) are below their scaled coverage:

File Coverage Required
firefox-ios/Client/Frontend/Browser/Toolbars/SwipeUpTabPreviewGestureHandler.swift 33.3% 62.1%
firefox-ios/Client/TabManagement/SwipeUpTabWebViewPreview.swift 35.7% 63.6%
firefox-ios/Client/Frontend/Browser/Tabs/Views/Animation/TabAnimation.swift 0.0% 24.8%

You can add the ignore-code-coverage label with a short justification to bypass this check. Please also tag a member of the @fxios-unit-test-owners if the bypass is used.

Messages
📖 Project coverage: 44.65%

🧩 Neat Piece

This PR changes 626 lines. It's a substantial update,
but still review-friendly if there’s a clear description. Thanks for keeping things moving! 🚀

💬 Description craftsman

Great PR description! Reviewers salute you 🫡

🦊 BrowserViewController Check

We’re tracking the size of BrowserViewController.swift to keep it healthy.

  • ✨ Change in file size: +24 lines

Client.app: Coverage: 43.51

File Coverage
FeatureFlagsDebugViewController.swift 0.0% ⚠️
SwipeUpTabWebViewPreview.swift 35.68% ⚠️
GeneralBrowserAction.swift 100.0%
TabAnimation.swift 0.0% ⚠️
FeatureFlagID.swift 100.0%
BrowserViewController.swift 38.42% ⚠️
TabDisplayView.swift 34.58% ⚠️
BrowserViewControllerState.swift 53.54%
SwipeUpTabPreviewGestureHandler.swift 33.33% ⚠️
ExperimentTabCell.swift 0.0% ⚠️
AddressBarPanGestureHandler.swift 29.55% ⚠️
NimbusFeatureFlagLayer.swift 84.25%

Generated by 🚫 Danger Swift against 39852d9

@PARAIPAN9

Copy link
Copy Markdown
Collaborator

@Alex-Bangu, just took a glance at the video!! Great work, it looks awesome!!

var theme: Theme?

/// UUID of the tab currently minimizing into the tray during the open animation
var minimizingTabUUID: TabUUID?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: handle this on TabAnimation.swift


let a11yId = "\(AccessibilityIdentifiers.TabTray.tabCell)_\(indexPath.section)_\(indexPath.row)"
cell.configure(with: tab, theme: theme, delegate: self, a11yId: a11yId, newTabTitle: newTabTitle)
if tab.tabUUID == self.minimizingTabUUID {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

same for this

// safely re-enable the gesture
if state.addressToolbar.isEditing {
disablePanGestureRecognizer()
disableSwipeUpGestureRecognizer()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

this can be one method for both up and down, to check also the feature flag inside

addressToolbarContainer.addGestureRecognizer(panGesture)
panGestureRecognizer = panGesture

let swipeUpGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Add FF check also here

let bvcSnapshot = UIImageView(image: browserVC.view.screenshot(quality: UX.bvcScreenshotQuality))
// Keep the selected tab cell hidden for the whole animation so it minimizes into an empty
// grid square
let tabDisplayView = panelViewController.tabDisplayView

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

this new code path should be under the feature flag

var microsurveyState: MicrosurveyPromptState
var autoTranslatePromptState: AutoTranslatePromptState
var navigationDestination: NavigationDestination?
var cellBounds: CGRect?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: could we have this property more self explenatory

}

/// The action to take when the gesture ends, based on where the finger is released on screen.
enum ReleaseOutcome {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: could be on top of the class


// MARK: - UIGestureRecognizerDelegate

func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

could be in the AddressBarPanGestureHandler

case .ended:
let fingerLocation = gesture.location(in: tabPreview)
switch tabPreview.releaseOutcome(fingerLocation: fingerLocation) {
case .closeTab:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

this switch could on a separate method

import Redux

@MainActor
class SwipeUpTabPreviewGestureHandler: NSObject, UIGestureRecognizerDelegate, StoreSubscriber, FeatureFlaggable {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

port the swipe up and down gesture inside here

@OrlaM OrlaM left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This PR is too large. I can suggest a way to break it down into 4 PR's but feel free to tackle it a different way if you prefer.
1 PR for each:
Adding and configuring the feature flag.
SwipeUpTabWebViewPreview.swift
SwipeUpTabPreviewGestureHandler.swift
Refactor of the open tab tray animation in TabAnimation.swift

Small PR's are a little more work on the authors side but it makes a big difference in the PR review and code quality side of things.

@Alex-Bangu

Copy link
Copy Markdown
Member Author

Hi Orla!

I'm currently working on breaking up this pr into three parts (new files, animation work, feature flag work). As such, I am going to close this PR and reuse the Jira ticket for the animation PR.

Thanks for the advice!

@Alex-Bangu Alex-Bangu closed this Jul 10, 2026
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.

5 participants