parent
1dc0ad39f4
commit
afbb039a08
|
@ -117,6 +117,7 @@ class DefaultTabTrayController(
|
|||
}
|
||||
|
||||
showUndoSnackbar(snackbarMessage, snapshot)
|
||||
dismissTabTray()
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.mozilla.fenix.components.FenixSnackbar
|
|||
import org.mozilla.fenix.components.TabCollectionStorage
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.getRootView
|
||||
import org.mozilla.fenix.ext.requireComponents
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.utils.allowUndo
|
||||
|
@ -204,19 +205,32 @@ class TabTrayDialogFragment : AppCompatDialogFragment() {
|
|||
getString(R.string.snackbar_tab_closed)
|
||||
}
|
||||
|
||||
view?.tabLayout?.let {
|
||||
viewLifecycleOwner.lifecycleScope.allowUndo(
|
||||
it,
|
||||
// Check if this is the last tab of this session type
|
||||
val isLastOpenTab = sessionManager.sessions.filter { snapshot.session.private }.size == 1
|
||||
val rootView = if (isLastOpenTab) { requireActivity().getRootView()!! } else { requireView().tabLayout }
|
||||
val anchorView = if (isLastOpenTab) { null } else { snackbarAnchor }
|
||||
|
||||
requireActivity().lifecycleScope.allowUndo(
|
||||
rootView,
|
||||
snackbarMessage,
|
||||
getString(R.string.snackbar_deleted_undo),
|
||||
{
|
||||
sessionManager.add(snapshot.session, isSelected, engineSessionState = state)
|
||||
tabTrayView.scrollToTab(snapshot.session.id)
|
||||
_tabTrayView?.scrollToTab(snapshot.session.id)
|
||||
},
|
||||
operation = { },
|
||||
elevation = ELEVATION,
|
||||
anchorView = snackbarAnchor
|
||||
paddedForBottomToolbar = isLastOpenTab,
|
||||
anchorView = anchorView
|
||||
)
|
||||
|
||||
dismissTabTrayIfNecessary()
|
||||
}
|
||||
|
||||
private fun dismissTabTrayIfNecessary() {
|
||||
if (requireComponents.core.sessionManager.sessions.size == 1) {
|
||||
findNavController().popBackStack(R.id.homeFragment, false)
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,20 +264,21 @@ class TabTrayDialogFragment : AppCompatDialogFragment() {
|
|||
}
|
||||
|
||||
private fun showUndoSnackbar(snackbarMessage: String, snapshot: SessionManager.Snapshot) {
|
||||
view?.let {
|
||||
viewLifecycleOwner.lifecycleScope.allowUndo(
|
||||
it,
|
||||
// Warning: removing this definition and using it directly in the onCancel block will fail silently.
|
||||
val sessionManager = view?.context?.components?.core?.sessionManager
|
||||
|
||||
requireActivity().lifecycleScope.allowUndo(
|
||||
requireActivity().getRootView()!!,
|
||||
snackbarMessage,
|
||||
getString(R.string.snackbar_deleted_undo),
|
||||
{
|
||||
context?.components?.core?.sessionManager?.restore(snapshot)
|
||||
sessionManager?.restore(snapshot)
|
||||
},
|
||||
operation = { },
|
||||
elevation = ELEVATION,
|
||||
anchorView = snackbarAnchor
|
||||
paddedForBottomToolbar = true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showCollectionSnackbar(tabSize: Int, isNewCollection: Boolean = false) {
|
||||
view.let {
|
||||
|
|
|
@ -5,10 +5,12 @@
|
|||
package org.mozilla.fenix.utils
|
||||
|
||||
import android.view.View
|
||||
import androidx.appcompat.widget.ContentFrameLayout
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.FenixSnackbar
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
@ -37,7 +39,8 @@ fun CoroutineScope.allowUndo(
|
|||
onCancel: suspend () -> Unit = {},
|
||||
operation: suspend () -> Unit,
|
||||
anchorView: View? = null,
|
||||
elevation: Float? = null
|
||||
elevation: Float? = null,
|
||||
paddedForBottomToolbar: Boolean = false
|
||||
) {
|
||||
// By using an AtomicBoolean, we achieve memory effects of reading and
|
||||
// writing a volatile variable.
|
||||
|
@ -63,6 +66,30 @@ fun CoroutineScope.allowUndo(
|
|||
snackbar.view.elevation = it
|
||||
}
|
||||
|
||||
val shouldUseBottomToolbar = view.context.settings().shouldUseBottomToolbar
|
||||
val toolbarHeight = view.context.resources
|
||||
.getDimensionPixelSize(R.dimen.browser_toolbar_height)
|
||||
|
||||
snackbar.view.setPadding(
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
if (
|
||||
paddedForBottomToolbar &&
|
||||
shouldUseBottomToolbar &&
|
||||
// If the view passed in is a ContentFrameLayout, it does not matter
|
||||
// if the user has a dynamicBottomToolbar or not, as the Android system
|
||||
// can't intelligently position the snackbar on the upper most view.
|
||||
// Ideally we should not pass ContentFrameLayout in, but it's the only
|
||||
// way to display snackbars through a fragment transition.
|
||||
view is ContentFrameLayout
|
||||
) {
|
||||
toolbarHeight
|
||||
} else {
|
||||
0
|
||||
}
|
||||
)
|
||||
|
||||
snackbar.show()
|
||||
|
||||
// Wait a bit, and if user didn't request cancellation, proceed with
|
||||
|
|
Loading…
Reference in New Issue
Block a user