diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 853789373..26397d9b4 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -64,6 +64,7 @@ import org.mozilla.fenix.NavGraphDirections import org.mozilla.fenix.R import org.mozilla.fenix.browser.readermode.DefaultReaderModeController import org.mozilla.fenix.components.FenixSnackbar +import org.mozilla.fenix.components.BrowserSnackbarPresenter import org.mozilla.fenix.components.FindInPageIntegration import org.mozilla.fenix.components.StoreProvider import org.mozilla.fenix.components.metrics.Event @@ -283,10 +284,10 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session download = download, tryAgain = downloadFeature::tryAgain, onCannotOpenFile = { - FenixSnackbar.make(view, Snackbar.LENGTH_SHORT) - .setText(context.getString(R.string.mozac_feature_downloads_could_not_open_file)) - .setAnchorView(browserToolbarView.getSnackbarAnchor()) - .show() + BrowserSnackbarPresenter(view).present( + text = context.getString(R.string.mozac_feature_downloads_could_not_open_file), + length = Snackbar.LENGTH_SHORT + ) } ) @@ -705,18 +706,17 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session requireComponents.analytics.metrics.track(Event.AddBookmark) view?.let { view -> - FenixSnackbar.make(view, Snackbar.LENGTH_LONG) - .setAnchorView(browserToolbarView.getSnackbarAnchor()) - .setAction(getString(R.string.edit_bookmark_snackbar_action)) { - nav( - R.id.browserFragment, - BrowserFragmentDirections.actionBrowserFragmentToBookmarkEditFragment( - guid - ) - ) - } - .setText(getString(R.string.bookmark_saved_snackbar)) - .show() + BrowserSnackbarPresenter(view).present( + text = getString(R.string.bookmark_saved_snackbar), + action = { nav( + R.id.browserFragment, + BrowserFragmentDirections.actionBrowserFragmentToBookmarkEditFragment( + guid + )) + }, + actionName = getString(R.string.edit_bookmark_snackbar_action), + length = Snackbar.LENGTH_LONG + ) } } } diff --git a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt index e61333177..825b786db 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt @@ -30,7 +30,7 @@ import mozilla.components.support.base.feature.UserInteractionHandler import mozilla.components.support.base.feature.ViewBoundFeatureWrapper import org.mozilla.fenix.HomeActivity 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.metrics.Event import org.mozilla.fenix.ext.components @@ -230,10 +230,10 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler { private fun showTabSavedToCollectionSnackbar() { view?.let { view -> - FenixSnackbar.make(view, Snackbar.LENGTH_SHORT) - .setText(view.context.getString(R.string.create_collection_tab_saved)) - .setAnchorView(browserToolbarView.getSnackbarAnchor()) - .show() + BrowserSnackbarPresenter(view).present( + text = view.context.getString(R.string.create_collection_tab_saved), + length = Snackbar.LENGTH_SHORT + ) } } } @@ -246,10 +246,7 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler { context.components.useCases.tabsUseCases, context.components.useCases.contextMenuUseCases, view, - FenixSnackbarDelegate( - view, - browserToolbarView.getSnackbarAnchor() - ) + FenixSnackbarDelegate(view) ) companion object { diff --git a/app/src/main/java/org/mozilla/fenix/browser/FenixSnackbarDelegate.kt b/app/src/main/java/org/mozilla/fenix/browser/FenixSnackbarDelegate.kt index 92023b6fd..73ffc05af 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/FenixSnackbarDelegate.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/FenixSnackbarDelegate.kt @@ -8,9 +8,9 @@ import android.view.View import androidx.annotation.StringRes import com.google.android.material.snackbar.Snackbar 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 { override fun show( snackBarParentView: View, @@ -19,13 +19,18 @@ class FenixSnackbarDelegate(val view: View, private val anchorView: View?) : @StringRes action: Int, listener: ((v: View) -> Unit)? ) { - val snackbar = FenixSnackbar.make(view, Snackbar.LENGTH_LONG).setText(view.context.getString(text)) if (listener != null && action != 0) { - snackbar.setAction(view.context.getString(action)) { - listener.invoke(view) - } + BrowserSnackbarPresenter(view).present( + 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() } } diff --git a/app/src/main/java/org/mozilla/fenix/components/FenixSnackbar.kt b/app/src/main/java/org/mozilla/fenix/components/FenixSnackbar.kt index 5c2d4b983..000d5bc32 100644 --- a/app/src/main/java/org/mozilla/fenix/components/FenixSnackbar.kt +++ b/app/src/main/java/org/mozilla/fenix/components/FenixSnackbar.kt @@ -18,6 +18,7 @@ import com.google.android.material.snackbar.Snackbar import kotlinx.android.synthetic.main.fenix_snackbar.view.* import org.mozilla.fenix.R import org.mozilla.fenix.ext.increaseTapArea +import org.mozilla.fenix.ext.settings import org.mozilla.fenix.test.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 ) { fun present( @@ -157,8 +162,20 @@ class FenixSnackbarPresenter( actionName: String? = null, isError: Boolean = false ) { - FenixSnackbar.make(view, length, isError).setText(text).let { - if (action != null && actionName != null) it.setAction(actionName, action) else it - }.show() + val shouldUseBottomToolbar = view.context.settings().shouldUseBottomToolbar + val toolbarHeight = view.context.resources + .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() + } } } diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt index de98ce5a4..8bc5d342d 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt @@ -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") fun update(state: BrowserFragmentState) { // Intentionally leaving this as a stub for now since we don't actually want to update currently diff --git a/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt index 25024678c..d6dd18369 100644 --- a/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt @@ -192,9 +192,6 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler context, context.components.useCases.contextMenuUseCases, view, - FenixSnackbarDelegate( - view, - null - ) + FenixSnackbarDelegate(view) ) } diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkController.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkController.kt index f4a71e2c8..8fc6313da 100644 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkController.kt +++ b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkController.kt @@ -17,7 +17,7 @@ import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R 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.metrics.Event import org.mozilla.fenix.ext.components @@ -46,7 +46,7 @@ interface BookmarkController { class DefaultBookmarkController( private val context: Context, private val navController: NavController, - private val snackbarPresenter: FenixSnackbarPresenter, + private val snackbarPresenter: BrowserSnackbarPresenter, private val deleteBookmarkNodes: (Set, Event) -> Unit, private val invokePendingDeletion: () -> Unit ) : BookmarkController { diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkFragment.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkFragment.kt index 0fea4c141..ca99abb80 100644 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkFragment.kt @@ -38,7 +38,7 @@ import mozilla.components.concept.sync.OAuthAccount import mozilla.components.lib.state.ext.consumeFrom import mozilla.components.support.base.feature.UserInteractionHandler 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.metrics.Event import org.mozilla.fenix.ext.bookmarkStorage @@ -87,7 +87,7 @@ class BookmarkFragment : LibraryPageFragment(), UserInteractionHan bookmarksController = DefaultBookmarkController( context = context!!, navController = findNavController(), - snackbarPresenter = FenixSnackbarPresenter(view), + snackbarPresenter = BrowserSnackbarPresenter(view), deleteBookmarkNodes = ::deleteMulti, invokePendingDeletion = ::invokePendingDeletion ), diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/edit/EditBookmarkFragment.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/edit/EditBookmarkFragment.kt index 8dfa2d874..8e6625142 100644 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/edit/EditBookmarkFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/library/bookmarks/edit/EditBookmarkFragment.kt @@ -37,7 +37,7 @@ import mozilla.components.concept.storage.BookmarkNodeType import mozilla.components.support.ktx.android.content.getColorFromAttr import mozilla.components.support.ktx.android.view.hideKeyboard 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.ext.components import org.mozilla.fenix.ext.getRootView @@ -185,17 +185,15 @@ class EditBookmarkFragment : Fragment(R.layout.fragment_edit_bookmark) { launch(Main) { Navigation.findNavController(requireActivity(), R.id.container) .popBackStack() - activity.getRootView()?.let { rootView -> - bookmarkNode?.let { - FenixSnackbar.make(rootView, FenixSnackbar.LENGTH_SHORT) - .setText( - getString( - R.string.bookmark_deletion_snackbar_message, - it.url?.toShortUrl(context.components.publicSuffixList) ?: it.title - ) - ) - .show() - } + + bookmarkNode?.let { bookmark -> + BrowserSnackbarPresenter(activity.getRootView()!!).present( + getString( + R.string.bookmark_deletion_snackbar_message, + bookmark.url?.toShortUrl(context.components.publicSuffixList) + ?: bookmark.title + ) + ) } } } diff --git a/app/src/main/java/org/mozilla/fenix/settings/account/TurnOnSyncFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/account/TurnOnSyncFragment.kt index aa1394cb6..5e627ed16 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/account/TurnOnSyncFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/account/TurnOnSyncFragment.kt @@ -18,6 +18,7 @@ import mozilla.components.concept.sync.AuthType import mozilla.components.concept.sync.OAuthAccount 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.ext.requireComponents import org.mozilla.fenix.ext.showToolbar @@ -73,8 +74,9 @@ class TurnOnSyncFragment : Fragment(), AccountObserver { } override fun onAuthenticated(account: OAuthAccount, authType: AuthType) { - FenixSnackbar.make(view!!, FenixSnackbar.LENGTH_SHORT) - .setText(requireContext().getString(R.string.sync_syncing_in_progress)) - .show() + BrowserSnackbarPresenter(requireView()).present( + text = requireContext().getString(R.string.sync_syncing_in_progress), + length = FenixSnackbar.LENGTH_SHORT + ) } } diff --git a/app/src/main/java/org/mozilla/fenix/share/ShareController.kt b/app/src/main/java/org/mozilla/fenix/share/ShareController.kt index 46cd1fcf3..9c925dfaf 100644 --- a/app/src/main/java/org/mozilla/fenix/share/ShareController.kt +++ b/app/src/main/java/org/mozilla/fenix/share/ShareController.kt @@ -22,7 +22,7 @@ import mozilla.components.concept.sync.Device import mozilla.components.concept.sync.TabData import mozilla.components.feature.accounts.push.SendTabUseCases 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.ext.metrics import org.mozilla.fenix.ext.nav @@ -53,7 +53,7 @@ interface ShareController { * @param context [Context] used for various Android interactions. * @param shareData the list of [ShareData]s that can be shared. * @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 dismiss - callback signalling sharing can be closed. */ @@ -62,7 +62,7 @@ class DefaultShareController( private val context: Context, private val shareData: List, private val sendTabUseCases: SendTabUseCases, - private val snackbarPresenter: FenixSnackbarPresenter, + private val snackbarPresenter: BrowserSnackbarPresenter, private val navController: NavController, private val dismiss: (ShareController.Result) -> Unit ) : ShareController { diff --git a/app/src/main/java/org/mozilla/fenix/share/ShareFragment.kt b/app/src/main/java/org/mozilla/fenix/share/ShareFragment.kt index 39ccd0bf3..d7df65418 100644 --- a/app/src/main/java/org/mozilla/fenix/share/ShareFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/share/ShareFragment.kt @@ -21,7 +21,7 @@ import mozilla.components.browser.state.selector.findTabOrCustomTab import mozilla.components.concept.engine.prompt.PromptRequest import mozilla.components.feature.accounts.push.SendTabUseCases 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.requireComponents @@ -65,7 +65,7 @@ class ShareFragment : AppCompatDialogFragment() { DefaultShareController( context = requireContext(), shareData = shareData, - snackbarPresenter = FenixSnackbarPresenter(activity!!.getRootView()!!), + snackbarPresenter = BrowserSnackbarPresenter(requireActivity().getRootView()!!), navController = findNavController(), sendTabUseCases = SendTabUseCases(accountManager) ) { result -> diff --git a/app/src/test/java/org/mozilla/fenix/library/bookmarks/BookmarkControllerTest.kt b/app/src/test/java/org/mozilla/fenix/library/bookmarks/BookmarkControllerTest.kt index c8c927838..d8ce0f03b 100644 --- a/app/src/test/java/org/mozilla/fenix/library/bookmarks/BookmarkControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/library/bookmarks/BookmarkControllerTest.kt @@ -29,7 +29,7 @@ import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R 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.metrics.Event import org.mozilla.fenix.ext.components @@ -41,7 +41,7 @@ class BookmarkControllerTest { private val context: Context = 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, Event) -> Unit = mockk(relaxed = true) private val invokePendingDeletion: () -> Unit = mockk(relaxed = true) diff --git a/app/src/test/java/org/mozilla/fenix/share/ShareControllerTest.kt b/app/src/test/java/org/mozilla/fenix/share/ShareControllerTest.kt index f0c29e466..bac142a5d 100644 --- a/app/src/test/java/org/mozilla/fenix/share/ShareControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/share/ShareControllerTest.kt @@ -35,7 +35,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.mozilla.fenix.R 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.MetricController import org.mozilla.fenix.ext.metrics @@ -61,7 +61,7 @@ class ShareControllerTest { ) private val textToShare = "${shareData[0].url}\n${shareData[1].url}" private val sendTabUseCases = mockk(relaxed = true) - private val snackbarPresenter = mockk(relaxed = true) + private val snackbarPresenter = mockk(relaxed = true) private val navController = mockk(relaxed = true) private val dismiss = mockk<(ShareController.Result) -> Unit>(relaxed = true) private val controller = DefaultShareController(