For #26957 - Allow SearchDialogFragment to be dismissed on homescreen swipe
This commit is contained in:
parent
d07de1e028
commit
782a903072
|
@ -1,57 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
package org.mozilla.fenix.home
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.graphics.Rect
|
|
||||||
import android.util.AttributeSet
|
|
||||||
import android.view.MotionEvent
|
|
||||||
import android.view.MotionEvent.ACTION_UP
|
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
||||||
import androidx.navigation.findNavController
|
|
||||||
import mozilla.components.support.ktx.android.view.findViewInHierarchy
|
|
||||||
import org.mozilla.fenix.R
|
|
||||||
import org.mozilla.fenix.search.SearchDialogFragment
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parent layout for [HomeFragment], used to dismiss the [SearchDialogFragment] when
|
|
||||||
* interacting with elements in the [HomeFragment].
|
|
||||||
*/
|
|
||||||
class HomeFragmentLayout @JvmOverloads constructor(
|
|
||||||
context: Context,
|
|
||||||
attrs: AttributeSet? = null,
|
|
||||||
defStyleAttr: Int = 0,
|
|
||||||
) : CoordinatorLayout(context, attrs, defStyleAttr) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not the motion event is touching the private browsing button.
|
|
||||||
*
|
|
||||||
* @param x X coordinate of the event.
|
|
||||||
* @param y Y coordinate of the event.
|
|
||||||
*/
|
|
||||||
private fun isTouchingPrivateButton(x: Float, y: Float): Boolean {
|
|
||||||
val view = this.findViewInHierarchy {
|
|
||||||
it.id == R.id.privateBrowsingButton
|
|
||||||
} ?: return false
|
|
||||||
val privateButtonRect = Rect()
|
|
||||||
view.getHitRect(privateButtonRect)
|
|
||||||
return privateButtonRect.contains(x.toInt(), y.toInt())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
|
|
||||||
val nav = findNavController()
|
|
||||||
|
|
||||||
// If the private button is touched from the [SearchDialogFragment], then it should not be
|
|
||||||
// dismissed to allow the user to continue the search.
|
|
||||||
if (ev?.action == ACTION_UP &&
|
|
||||||
nav.currentDestination?.id == R.id.searchDialogFragment &&
|
|
||||||
!isTouchingPrivateButton(ev.x, ev.y)
|
|
||||||
) {
|
|
||||||
nav.popBackStack()
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.onInterceptTouchEvent(ev)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -20,6 +20,7 @@ import android.os.Bundle
|
||||||
import android.speech.RecognizerIntent
|
import android.speech.RecognizerIntent
|
||||||
import android.text.style.StyleSpan
|
import android.text.style.StyleSpan
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.ViewStub
|
import android.view.ViewStub
|
||||||
|
@ -67,6 +68,7 @@ import mozilla.components.support.ktx.android.content.hasCamera
|
||||||
import mozilla.components.support.ktx.android.content.isPermissionGranted
|
import mozilla.components.support.ktx.android.content.isPermissionGranted
|
||||||
import mozilla.components.support.ktx.android.content.res.getSpanned
|
import mozilla.components.support.ktx.android.content.res.getSpanned
|
||||||
import mozilla.components.support.ktx.android.net.isHttpOrHttps
|
import mozilla.components.support.ktx.android.net.isHttpOrHttps
|
||||||
|
import mozilla.components.support.ktx.android.view.findViewInHierarchy
|
||||||
import mozilla.components.support.ktx.android.view.hideKeyboard
|
import mozilla.components.support.ktx.android.view.hideKeyboard
|
||||||
import mozilla.components.support.ktx.kotlin.toNormalizedUrl
|
import mozilla.components.support.ktx.kotlin.toNormalizedUrl
|
||||||
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged
|
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged
|
||||||
|
@ -83,6 +85,7 @@ import org.mozilla.fenix.components.toolbar.ToolbarPosition
|
||||||
import org.mozilla.fenix.databinding.FragmentSearchDialogBinding
|
import org.mozilla.fenix.databinding.FragmentSearchDialogBinding
|
||||||
import org.mozilla.fenix.databinding.SearchSuggestionsHintBinding
|
import org.mozilla.fenix.databinding.SearchSuggestionsHintBinding
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
|
import org.mozilla.fenix.ext.getRectWithScreenLocation
|
||||||
import org.mozilla.fenix.ext.increaseTapArea
|
import org.mozilla.fenix.ext.increaseTapArea
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
import org.mozilla.fenix.ext.settings
|
import org.mozilla.fenix.ext.settings
|
||||||
|
@ -118,6 +121,7 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
|
||||||
private val qrFeature = ViewBoundFeatureWrapper<QrFeature>()
|
private val qrFeature = ViewBoundFeatureWrapper<QrFeature>()
|
||||||
private val speechIntent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
|
private val speechIntent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
|
||||||
|
|
||||||
|
private var isPrivateButtonClicked = false
|
||||||
private var dialogHandledAction = false
|
private var dialogHandledAction = false
|
||||||
private var searchSelectorAlreadyAdded = false
|
private var searchSelectorAlreadyAdded = false
|
||||||
private var qrButtonAction: Toolbar.Action? = null
|
private var qrButtonAction: Toolbar.Action? = null
|
||||||
|
@ -267,6 +271,22 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
|
||||||
// When displayed above home, dispatches the touch events to scrim area to the HomeFragment
|
// When displayed above home, dispatches the touch events to scrim area to the HomeFragment
|
||||||
binding.searchWrapper.background = ColorDrawable(Color.TRANSPARENT)
|
binding.searchWrapper.background = ColorDrawable(Color.TRANSPARENT)
|
||||||
dialog?.window?.decorView?.setOnTouchListener { _, event ->
|
dialog?.window?.decorView?.setOnTouchListener { _, event ->
|
||||||
|
when (event?.action) {
|
||||||
|
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> {
|
||||||
|
isPrivateButtonClicked = isTouchingPrivateButton(event.x, event.y)
|
||||||
|
}
|
||||||
|
MotionEvent.ACTION_UP -> {
|
||||||
|
if (!isTouchingPrivateButton(
|
||||||
|
event.x,
|
||||||
|
event.y,
|
||||||
|
) && !isPrivateButtonClicked
|
||||||
|
) {
|
||||||
|
findNavController().popBackStack()
|
||||||
|
isPrivateButtonClicked = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> isPrivateButtonClicked = false
|
||||||
|
}
|
||||||
requireActivity().dispatchTouchEvent(event)
|
requireActivity().dispatchTouchEvent(event)
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -457,6 +477,13 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isTouchingPrivateButton(x: Float, y: Float): Boolean {
|
||||||
|
val view = parentFragmentManager.primaryNavigationFragment?.view?.findViewInHierarchy {
|
||||||
|
it.id == R.id.privateBrowsingButton
|
||||||
|
} ?: return false
|
||||||
|
return view.getRectWithScreenLocation().contains(x.toInt(), y.toInt())
|
||||||
|
}
|
||||||
|
|
||||||
private fun hideClipboardSection() {
|
private fun hideClipboardSection() {
|
||||||
binding.fillLinkFromClipboard.isVisible = false
|
binding.fillLinkFromClipboard.isVisible = false
|
||||||
binding.fillLinkDivider.isVisible = false
|
binding.fillLinkDivider.isVisible = false
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<!-- using an AppBarLayout to replace MotionLayout was done in order to improve Fenix
|
<!-- using an AppBarLayout to replace MotionLayout was done in order to improve Fenix
|
||||||
start up performance. The use of a MotionLayout was worsening our layout measures, especially
|
start up performance. The use of a MotionLayout was worsening our layout measures, especially
|
||||||
with the recycler view -->
|
with the recycler view -->
|
||||||
<org.mozilla.fenix.home.HomeFragmentLayout
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
@ -202,4 +202,4 @@
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
</org.mozilla.fenix.home.HomeFragmentLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user