1
0
Fork 0

For #6413: Fixes snackbar positionining for bottom toolbar (#7415)

* For #6413: Fixes snackbar positionining for bottom toolbar

* For #6413: Cleans up snackbar usage
master
Sawyer Blatz 2019-12-30 14:43:15 -08:00 committed by GitHub
parent 13f73c2d2c
commit 3fb060f682
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 85 additions and 77 deletions

View File

@ -64,6 +64,7 @@ import org.mozilla.fenix.NavGraphDirections
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.browser.readermode.DefaultReaderModeController import org.mozilla.fenix.browser.readermode.DefaultReaderModeController
import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.BrowserSnackbarPresenter
import org.mozilla.fenix.components.FindInPageIntegration import org.mozilla.fenix.components.FindInPageIntegration
import org.mozilla.fenix.components.StoreProvider import org.mozilla.fenix.components.StoreProvider
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
@ -283,10 +284,10 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
download = download, download = download,
tryAgain = downloadFeature::tryAgain, tryAgain = downloadFeature::tryAgain,
onCannotOpenFile = { onCannotOpenFile = {
FenixSnackbar.make(view, Snackbar.LENGTH_SHORT) BrowserSnackbarPresenter(view).present(
.setText(context.getString(R.string.mozac_feature_downloads_could_not_open_file)) text = context.getString(R.string.mozac_feature_downloads_could_not_open_file),
.setAnchorView(browserToolbarView.getSnackbarAnchor()) length = Snackbar.LENGTH_SHORT
.show() )
} }
) )
@ -705,18 +706,17 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
requireComponents.analytics.metrics.track(Event.AddBookmark) requireComponents.analytics.metrics.track(Event.AddBookmark)
view?.let { view -> view?.let { view ->
FenixSnackbar.make(view, Snackbar.LENGTH_LONG) BrowserSnackbarPresenter(view).present(
.setAnchorView(browserToolbarView.getSnackbarAnchor()) text = getString(R.string.bookmark_saved_snackbar),
.setAction(getString(R.string.edit_bookmark_snackbar_action)) { action = { nav(
nav( R.id.browserFragment,
R.id.browserFragment, BrowserFragmentDirections.actionBrowserFragmentToBookmarkEditFragment(
BrowserFragmentDirections.actionBrowserFragmentToBookmarkEditFragment( guid
guid ))
) },
) actionName = getString(R.string.edit_bookmark_snackbar_action),
} length = Snackbar.LENGTH_LONG
.setText(getString(R.string.bookmark_saved_snackbar)) )
.show()
} }
} }
} }

View File

@ -30,7 +30,7 @@ import mozilla.components.support.base.feature.UserInteractionHandler
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.components.BrowserSnackbarPresenter
import org.mozilla.fenix.components.TabCollectionStorage import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
@ -230,10 +230,10 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
private fun showTabSavedToCollectionSnackbar() { private fun showTabSavedToCollectionSnackbar() {
view?.let { view -> view?.let { view ->
FenixSnackbar.make(view, Snackbar.LENGTH_SHORT) BrowserSnackbarPresenter(view).present(
.setText(view.context.getString(R.string.create_collection_tab_saved)) text = view.context.getString(R.string.create_collection_tab_saved),
.setAnchorView(browserToolbarView.getSnackbarAnchor()) length = Snackbar.LENGTH_SHORT
.show() )
} }
} }
} }
@ -246,10 +246,7 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
context.components.useCases.tabsUseCases, context.components.useCases.tabsUseCases,
context.components.useCases.contextMenuUseCases, context.components.useCases.contextMenuUseCases,
view, view,
FenixSnackbarDelegate( FenixSnackbarDelegate(view)
view,
browserToolbarView.getSnackbarAnchor()
)
) )
companion object { companion object {

View File

@ -8,9 +8,9 @@ import android.view.View
import androidx.annotation.StringRes import androidx.annotation.StringRes
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import mozilla.components.feature.contextmenu.ContextMenuCandidate import mozilla.components.feature.contextmenu.ContextMenuCandidate
import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.components.BrowserSnackbarPresenter
class FenixSnackbarDelegate(val view: View, private val anchorView: View?) : class FenixSnackbarDelegate(val view: View) :
ContextMenuCandidate.SnackbarDelegate { ContextMenuCandidate.SnackbarDelegate {
override fun show( override fun show(
snackBarParentView: View, snackBarParentView: View,
@ -19,13 +19,18 @@ class FenixSnackbarDelegate(val view: View, private val anchorView: View?) :
@StringRes action: Int, @StringRes action: Int,
listener: ((v: View) -> Unit)? listener: ((v: View) -> Unit)?
) { ) {
val snackbar = FenixSnackbar.make(view, Snackbar.LENGTH_LONG).setText(view.context.getString(text))
if (listener != null && action != 0) { if (listener != null && action != 0) {
snackbar.setAction(view.context.getString(action)) { BrowserSnackbarPresenter(view).present(
listener.invoke(view) text = view.context.getString(text),
} length = Snackbar.LENGTH_LONG,
actionName = view.context.getString(action),
action = { listener.invoke(view) }
)
} else {
BrowserSnackbarPresenter(view).present(
text = view.context.getString(text),
length = Snackbar.LENGTH_LONG
)
} }
snackbar.anchorView = anchorView
snackbar.show()
} }
} }

View File

@ -18,6 +18,7 @@ import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.fenix_snackbar.view.* import kotlinx.android.synthetic.main.fenix_snackbar.view.*
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.ext.increaseTapArea import org.mozilla.fenix.ext.increaseTapArea
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.test.Mockable import org.mozilla.fenix.test.Mockable
@Mockable @Mockable
@ -147,7 +148,11 @@ private class FenixSnackbarCallback(
} }
} }
class FenixSnackbarPresenter( /**
* This snackbar presenter should be used when displaying a snackbar that will appear in
* the BrowserFragment as it takes into account the position of the BrowserToolbar
*/
class BrowserSnackbarPresenter(
private val view: View private val view: View
) { ) {
fun present( fun present(
@ -157,8 +162,20 @@ class FenixSnackbarPresenter(
actionName: String? = null, actionName: String? = null,
isError: Boolean = false isError: Boolean = false
) { ) {
FenixSnackbar.make(view, length, isError).setText(text).let { val shouldUseBottomToolbar = view.context.settings().shouldUseBottomToolbar
if (action != null && actionName != null) it.setAction(actionName, action) else it val toolbarHeight = view.context.resources
}.show() .getDimensionPixelSize(R.dimen.browser_toolbar_height)
FenixSnackbar.make(view, length, isError).apply {
if (action != null && actionName != null) setAction(actionName, action)
setText(text)
view.setPadding(
0,
0,
0,
if (shouldUseBottomToolbar) toolbarHeight else 0
)
show()
}
} }
} }

View File

@ -224,14 +224,6 @@ class BrowserToolbarView(
} }
} }
/**
* Returns the correct snackbar anchor for bottom or top toolbar configuration.
* A null anchor view is ignored.
*
* @see #setAnchorView(com.google.android.material.snackbar.BaseTransientBottomBar)
*/
fun getSnackbarAnchor(): View? = if (shouldUseBottomToolbar) view else null
@Suppress("UNUSED_PARAMETER") @Suppress("UNUSED_PARAMETER")
fun update(state: BrowserFragmentState) { fun update(state: BrowserFragmentState) {
// Intentionally leaving this as a stub for now since we don't actually want to update currently // Intentionally leaving this as a stub for now since we don't actually want to update currently

View File

@ -192,9 +192,6 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler
context, context,
context.components.useCases.contextMenuUseCases, context.components.useCases.contextMenuUseCases,
view, view,
FenixSnackbarDelegate( FenixSnackbarDelegate(view)
view,
null
)
) )
} }

View File

@ -17,7 +17,7 @@ import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.FenixSnackbarPresenter import org.mozilla.fenix.components.BrowserSnackbarPresenter
import org.mozilla.fenix.components.Services import org.mozilla.fenix.components.Services
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
@ -46,7 +46,7 @@ interface BookmarkController {
class DefaultBookmarkController( class DefaultBookmarkController(
private val context: Context, private val context: Context,
private val navController: NavController, private val navController: NavController,
private val snackbarPresenter: FenixSnackbarPresenter, private val snackbarPresenter: BrowserSnackbarPresenter,
private val deleteBookmarkNodes: (Set<BookmarkNode>, Event) -> Unit, private val deleteBookmarkNodes: (Set<BookmarkNode>, Event) -> Unit,
private val invokePendingDeletion: () -> Unit private val invokePendingDeletion: () -> Unit
) : BookmarkController { ) : BookmarkController {

View File

@ -38,7 +38,7 @@ import mozilla.components.concept.sync.OAuthAccount
import mozilla.components.lib.state.ext.consumeFrom import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.support.base.feature.UserInteractionHandler import mozilla.components.support.base.feature.UserInteractionHandler
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbarPresenter import org.mozilla.fenix.components.BrowserSnackbarPresenter
import org.mozilla.fenix.components.StoreProvider import org.mozilla.fenix.components.StoreProvider
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.bookmarkStorage import org.mozilla.fenix.ext.bookmarkStorage
@ -87,7 +87,7 @@ class BookmarkFragment : LibraryPageFragment<BookmarkNode>(), UserInteractionHan
bookmarksController = DefaultBookmarkController( bookmarksController = DefaultBookmarkController(
context = context!!, context = context!!,
navController = findNavController(), navController = findNavController(),
snackbarPresenter = FenixSnackbarPresenter(view), snackbarPresenter = BrowserSnackbarPresenter(view),
deleteBookmarkNodes = ::deleteMulti, deleteBookmarkNodes = ::deleteMulti,
invokePendingDeletion = ::invokePendingDeletion invokePendingDeletion = ::invokePendingDeletion
), ),

View File

@ -37,7 +37,7 @@ import mozilla.components.concept.storage.BookmarkNodeType
import mozilla.components.support.ktx.android.content.getColorFromAttr import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.android.view.hideKeyboard import mozilla.components.support.ktx.android.view.hideKeyboard
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.components.BrowserSnackbarPresenter
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.getRootView import org.mozilla.fenix.ext.getRootView
@ -185,17 +185,15 @@ class EditBookmarkFragment : Fragment(R.layout.fragment_edit_bookmark) {
launch(Main) { launch(Main) {
Navigation.findNavController(requireActivity(), R.id.container) Navigation.findNavController(requireActivity(), R.id.container)
.popBackStack() .popBackStack()
activity.getRootView()?.let { rootView ->
bookmarkNode?.let { bookmarkNode?.let { bookmark ->
FenixSnackbar.make(rootView, FenixSnackbar.LENGTH_SHORT) BrowserSnackbarPresenter(activity.getRootView()!!).present(
.setText( getString(
getString( R.string.bookmark_deletion_snackbar_message,
R.string.bookmark_deletion_snackbar_message, bookmark.url?.toShortUrl(context.components.publicSuffixList)
it.url?.toShortUrl(context.components.publicSuffixList) ?: it.title ?: bookmark.title
) )
) )
.show()
}
} }
} }
} }

View File

@ -18,6 +18,7 @@ import mozilla.components.concept.sync.AuthType
import mozilla.components.concept.sync.OAuthAccount import mozilla.components.concept.sync.OAuthAccount
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.BrowserSnackbarPresenter
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.ext.showToolbar
@ -73,8 +74,9 @@ class TurnOnSyncFragment : Fragment(), AccountObserver {
} }
override fun onAuthenticated(account: OAuthAccount, authType: AuthType) { override fun onAuthenticated(account: OAuthAccount, authType: AuthType) {
FenixSnackbar.make(view!!, FenixSnackbar.LENGTH_SHORT) BrowserSnackbarPresenter(requireView()).present(
.setText(requireContext().getString(R.string.sync_syncing_in_progress)) text = requireContext().getString(R.string.sync_syncing_in_progress),
.show() length = FenixSnackbar.LENGTH_SHORT
)
} }
} }

View File

@ -22,7 +22,7 @@ import mozilla.components.concept.sync.Device
import mozilla.components.concept.sync.TabData import mozilla.components.concept.sync.TabData
import mozilla.components.feature.accounts.push.SendTabUseCases import mozilla.components.feature.accounts.push.SendTabUseCases
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbarPresenter import org.mozilla.fenix.components.BrowserSnackbarPresenter
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.metrics import org.mozilla.fenix.ext.metrics
import org.mozilla.fenix.ext.nav import org.mozilla.fenix.ext.nav
@ -53,7 +53,7 @@ interface ShareController {
* @param context [Context] used for various Android interactions. * @param context [Context] used for various Android interactions.
* @param shareData the list of [ShareData]s that can be shared. * @param shareData the list of [ShareData]s that can be shared.
* @param sendTabUseCases instance of [SendTabUseCases] which allows sending tabs to account devices. * @param sendTabUseCases instance of [SendTabUseCases] which allows sending tabs to account devices.
* @param snackbarPresenter - instance of [FenixSnackbarPresenter] for displaying styled snackbars * @param snackbarPresenter - instance of [BrowserSnackbarPresenter] for displaying styled snackbars
* @param navController - [NavController] used for navigation. * @param navController - [NavController] used for navigation.
* @param dismiss - callback signalling sharing can be closed. * @param dismiss - callback signalling sharing can be closed.
*/ */
@ -62,7 +62,7 @@ class DefaultShareController(
private val context: Context, private val context: Context,
private val shareData: List<ShareData>, private val shareData: List<ShareData>,
private val sendTabUseCases: SendTabUseCases, private val sendTabUseCases: SendTabUseCases,
private val snackbarPresenter: FenixSnackbarPresenter, private val snackbarPresenter: BrowserSnackbarPresenter,
private val navController: NavController, private val navController: NavController,
private val dismiss: (ShareController.Result) -> Unit private val dismiss: (ShareController.Result) -> Unit
) : ShareController { ) : ShareController {

View File

@ -21,7 +21,7 @@ import mozilla.components.browser.state.selector.findTabOrCustomTab
import mozilla.components.concept.engine.prompt.PromptRequest import mozilla.components.concept.engine.prompt.PromptRequest
import mozilla.components.feature.accounts.push.SendTabUseCases import mozilla.components.feature.accounts.push.SendTabUseCases
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbarPresenter import org.mozilla.fenix.components.BrowserSnackbarPresenter
import org.mozilla.fenix.ext.getRootView import org.mozilla.fenix.ext.getRootView
import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.requireComponents
@ -65,7 +65,7 @@ class ShareFragment : AppCompatDialogFragment() {
DefaultShareController( DefaultShareController(
context = requireContext(), context = requireContext(),
shareData = shareData, shareData = shareData,
snackbarPresenter = FenixSnackbarPresenter(activity!!.getRootView()!!), snackbarPresenter = BrowserSnackbarPresenter(requireActivity().getRootView()!!),
navController = findNavController(), navController = findNavController(),
sendTabUseCases = SendTabUseCases(accountManager) sendTabUseCases = SendTabUseCases(accountManager)
) { result -> ) { result ->

View File

@ -29,7 +29,7 @@ import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.FenixSnackbarPresenter import org.mozilla.fenix.components.BrowserSnackbarPresenter
import org.mozilla.fenix.components.Services import org.mozilla.fenix.components.Services
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
@ -41,7 +41,7 @@ class BookmarkControllerTest {
private val context: Context = mockk(relaxed = true) private val context: Context = mockk(relaxed = true)
private val navController: NavController = mockk(relaxed = true) private val navController: NavController = mockk(relaxed = true)
private val snackbarPresenter: FenixSnackbarPresenter = mockk(relaxed = true) private val snackbarPresenter: BrowserSnackbarPresenter = mockk(relaxed = true)
private val deleteBookmarkNodes: (Set<BookmarkNode>, Event) -> Unit = mockk(relaxed = true) private val deleteBookmarkNodes: (Set<BookmarkNode>, Event) -> Unit = mockk(relaxed = true)
private val invokePendingDeletion: () -> Unit = mockk(relaxed = true) private val invokePendingDeletion: () -> Unit = mockk(relaxed = true)

View File

@ -35,7 +35,7 @@ import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.TestApplication import org.mozilla.fenix.TestApplication
import org.mozilla.fenix.components.FenixSnackbarPresenter import org.mozilla.fenix.components.BrowserSnackbarPresenter
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.ext.metrics import org.mozilla.fenix.ext.metrics
@ -61,7 +61,7 @@ class ShareControllerTest {
) )
private val textToShare = "${shareData[0].url}\n${shareData[1].url}" private val textToShare = "${shareData[0].url}\n${shareData[1].url}"
private val sendTabUseCases = mockk<SendTabUseCases>(relaxed = true) private val sendTabUseCases = mockk<SendTabUseCases>(relaxed = true)
private val snackbarPresenter = mockk<FenixSnackbarPresenter>(relaxed = true) private val snackbarPresenter = mockk<BrowserSnackbarPresenter>(relaxed = true)
private val navController = mockk<NavController>(relaxed = true) private val navController = mockk<NavController>(relaxed = true)
private val dismiss = mockk<(ShareController.Result) -> Unit>(relaxed = true) private val dismiss = mockk<(ShareController.Result) -> Unit>(relaxed = true)
private val controller = DefaultShareController( private val controller = DefaultShareController(