diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkComponent.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkComponent.kt index 485ebb46ca..4de81624eb 100644 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkComponent.kt +++ b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkComponent.kt @@ -53,6 +53,7 @@ class BookmarkComponent( ) state.copy(mode = mode) } + is BookmarkChange.ClearSelection -> state.copy(mode = BookmarkState.Mode.Normal) } } @@ -64,7 +65,7 @@ class BookmarkComponent( } } -data class BookmarkState(val tree: BookmarkNode?, val mode: BookmarkState.Mode) : ViewState { +data class BookmarkState(val tree: BookmarkNode?, val mode: Mode) : ViewState { sealed class Mode { object Normal : Mode() data class Selecting(val selectedItems: Set) : Mode() @@ -90,6 +91,7 @@ sealed class BookmarkChange : Change { data class Change(val tree: BookmarkNode) : BookmarkChange() data class IsSelected(val newlySelectedItem: BookmarkNode) : BookmarkChange() data class IsDeselected(val newlyDeselectedItem: BookmarkNode) : BookmarkChange() + object ClearSelection : BookmarkChange() } operator fun BookmarkNode.contains(item: BookmarkNode): Boolean { 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 182850267c..8f99490385 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 @@ -17,14 +17,11 @@ import android.view.MenuInflater import android.view.MenuItem import android.view.View import android.view.ViewGroup -import android.widget.ImageButton import androidx.appcompat.app.AppCompatActivity -import androidx.appcompat.view.menu.ActionMenuItemView -import androidx.appcompat.widget.ActionMenuView -import androidx.appcompat.widget.Toolbar import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProviders +import androidx.navigation.NavController import androidx.navigation.Navigation import kotlinx.android.synthetic.main.fragment_bookmark.view.* import kotlinx.coroutines.CoroutineScope @@ -46,7 +43,6 @@ import org.mozilla.fenix.R import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.ext.allowUndo -import org.mozilla.fenix.ext.getColorIntFromAttr import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.share import org.mozilla.fenix.ext.urlToHost @@ -62,6 +58,14 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve private lateinit var bookmarkComponent: BookmarkComponent private lateinit var signInComponent: SignInComponent private var currentRoot: BookmarkNode? = null + private val navigation by lazy { Navigation.findNavController(requireActivity(), R.id.container) } + private val onDestinationChangedListener = + NavController.OnDestinationChangedListener { _, destination, args -> + if (destination.id != R.id.bookmarkFragment || + args != null && BookmarkFragmentArgs.fromBundle(args).currentRoot != currentRoot?.guid + ) + getManagedEmitter().onNext(BookmarkChange.ClearSelection) + } override val coroutineContext: CoroutineContext get() = Main + job @@ -85,13 +89,13 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve (activity as AppCompatActivity).supportActionBar?.show() checkIfSignedIn() + navigation.addOnDestinationChangedListener(onDestinationChangedListener) val currentGuid = BookmarkFragmentArgs.fromBundle(arguments!!).currentRoot.ifEmpty { BookmarkRoot.Root.id } launch(IO) { currentRoot = requireComponents.core.bookmarksStorage.getTree(currentGuid) as BookmarkNode launch(Main) { - if (currentGuid != BookmarkRoot.Root.id) (activity as HomeActivity).title = currentRoot!!.title getManagedEmitter().onNext(BookmarkChange.Change(currentRoot!!)) activity?.run { @@ -108,114 +112,26 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve ?: getManagedEmitter().onNext(SignInChange.SignedOut) } - fun setToolbarColors(foreground: Int, background: Int) { - val toolbar = (activity as AppCompatActivity).findViewById(R.id.navigationToolbar) - val colorFilter = PorterDuffColorFilter( - ContextCompat.getColor(context!!, foreground), PorterDuff.Mode.SRC_IN - ) - toolbar.setBackgroundColor(ContextCompat.getColor(context!!, background)) - toolbar.setTitleTextColor(ContextCompat.getColor(context!!, foreground)) - - themeToolbar( - toolbar, foreground, - background, colorFilter - ) - } - - override fun onStop() { - super.onStop() - // Reset the toolbar color - setToolbarColors( - R.attr.primaryText.getColorIntFromAttr(context!!), - R.attr.foundation.getColorIntFromAttr(context!!) - ) - } - override fun onDestroy() { super.onDestroy() + navigation.removeOnDestinationChangedListener(onDestinationChangedListener) job.cancel() } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - val toolbar = (activity as AppCompatActivity).findViewById(R.id.navigationToolbar) when (val mode = (bookmarkComponent.uiView as BookmarkUIView).mode) { BookmarkState.Mode.Normal -> { inflater.inflate(R.menu.library_menu, menu) - activity?.title = - if (currentRoot?.title in setOf( - "root", - null - ) - ) getString(R.string.library_bookmarks) else currentRoot!!.title - - setToolbarColors( - R.attr.primaryText.getColorIntFromAttr(context!!), - R.attr.foundation.getColorIntFromAttr(context!!) - ) } is BookmarkState.Mode.Selecting -> { inflater.inflate(R.menu.bookmarks_select_multi, menu) - - menu.findItem(R.id.edit_bookmark_multi_select).run { + menu.findItem(R.id.edit_bookmark_multi_select)?.run { isVisible = mode.selectedItems.size == 1 icon.colorFilter = PorterDuffColorFilter( ContextCompat.getColor(context!!, R.color.white_color), PorterDuff.Mode.SRC_IN ) } - - activity?.title = getString(R.string.bookmarks_multi_select_title, mode.selectedItems.size) - setToolbarColors( - R.color.white_color, - R.attr.accentBright.getColorIntFromAttr(context!!) - ) - } - } - } - - private fun themeToolbar( - toolbar: Toolbar, - textColor: Int, - backgroundColor: Int, - colorFilter: PorterDuffColorFilter? = null - ) { - toolbar.setTitleTextColor(ContextCompat.getColor(context!!, textColor)) - toolbar.setBackgroundColor(ContextCompat.getColor(context!!, backgroundColor)) - - if (colorFilter == null) { - return - } - - toolbar.overflowIcon?.colorFilter = colorFilter - (0 until toolbar.childCount).forEach { - when (val item = toolbar.getChildAt(it)) { - is ImageButton -> item.drawable.colorFilter = colorFilter - is ActionMenuView -> themeActionMenuView(item, colorFilter) - } - } - } - - private fun themeActionMenuView( - item: ActionMenuView, - colorFilter: PorterDuffColorFilter - ) { - (0 until item.childCount).forEach { - val innerChild = item.getChildAt(it) - if (innerChild is ActionMenuItemView) { - themeChildren(innerChild, item, colorFilter) - } - } - } - - private fun themeChildren( - innerChild: ActionMenuItemView, - item: ActionMenuView, - colorFilter: PorterDuffColorFilter - ) { - val drawables = innerChild.compoundDrawables - for (k in drawables.indices) { - drawables[k]?.let { - item.post { innerChild.compoundDrawables[k].colorFilter = colorFilter } } } } @@ -236,14 +152,14 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve requireComponents.analytics.metrics.track(Event.OpenedBookmark) } is BookmarkAction.Expand -> { - Navigation.findNavController(requireActivity(), R.id.container) + navigation .navigate(BookmarkFragmentDirections.actionBookmarkFragmentSelf(it.folder.guid)) } is BookmarkAction.BackPressed -> { - Navigation.findNavController(requireActivity(), R.id.container).popBackStack() + navigation.popBackStack() } is BookmarkAction.Edit -> { - Navigation.findNavController(requireActivity(), R.id.container) + navigation .navigate( BookmarkFragmentDirections .actionBookmarkFragmentToBookmarkEditFragment(it.item.guid) @@ -310,7 +226,7 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.libraryClose -> { - Navigation.findNavController(requireActivity(), R.id.container) + navigation .popBackStack(R.id.libraryFragment, true) true } @@ -322,14 +238,14 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve } (activity as HomeActivity).browsingModeManager.mode = BrowsingModeManager.Mode.Normal - Navigation.findNavController(requireActivity(), R.id.container) + navigation .navigate(BookmarkFragmentDirections.actionBookmarkFragmentToHomeFragment()) requireComponents.analytics.metrics.track(Event.OpenedBookmarksInNewTabs) true } R.id.edit_bookmark_multi_select -> { val bookmark = getSelectedBookmarks().first() - Navigation.findNavController(requireActivity(), R.id.container) + navigation .navigate( BookmarkFragmentDirections .actionBookmarkFragmentToBookmarkEditFragment(bookmark.guid) @@ -344,7 +260,7 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve } (activity as HomeActivity).browsingModeManager.mode = BrowsingModeManager.Mode.Private - Navigation.findNavController(requireActivity(), R.id.container) + navigation .navigate(BookmarkFragmentDirections.actionBookmarkFragmentToHomeFragment()) requireComponents.analytics.metrics.track(Event.OpenedBookmarksInPrivateTabs) true diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkUIView.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkUIView.kt index befef7a794..905def6a96 100644 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkUIView.kt +++ b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkUIView.kt @@ -4,9 +4,17 @@ package org.mozilla.fenix.library.bookmarks +import android.graphics.PorterDuff +import android.graphics.PorterDuffColorFilter import android.view.LayoutInflater import android.view.ViewGroup +import android.widget.ImageButton import android.widget.LinearLayout +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.view.menu.ActionMenuItemView +import androidx.appcompat.widget.ActionMenuView +import androidx.appcompat.widget.Toolbar +import androidx.core.content.ContextCompat import io.reactivex.Observable import io.reactivex.Observer import io.reactivex.functions.Consumer @@ -15,6 +23,8 @@ import mozilla.appservices.places.BookmarkRoot import mozilla.components.concept.storage.BookmarkNode import mozilla.components.support.base.feature.BackHandler import org.mozilla.fenix.R +import org.mozilla.fenix.ext.asActivity +import org.mozilla.fenix.ext.getColorIntFromAttr import org.mozilla.fenix.mvi.UIView class BookmarkUIView( @@ -28,12 +38,14 @@ class BookmarkUIView( var mode: BookmarkState.Mode = BookmarkState.Mode.Normal private set - var canGoBack = false + private var canGoBack = false override val view: LinearLayout = LayoutInflater.from(container.context) .inflate(R.layout.component_bookmark, container, true) as LinearLayout private val bookmarkAdapter: BookmarkAdapter + private val context = container.context + private val activity = context?.asActivity() init { view.bookmark_list.apply { @@ -48,6 +60,10 @@ class BookmarkUIView( if (it.mode != mode) { mode = it.mode actionEmitter.onNext(BookmarkAction.ModeChanged) + when (val modeCopy = mode) { + is BookmarkState.Mode.Normal -> setUIForNormalMode(it.tree) + is BookmarkState.Mode.Selecting -> setUIForSelectingMode(modeCopy) + } } } @@ -59,4 +75,89 @@ class BookmarkUIView( } fun getSelected(): Set = bookmarkAdapter.selected + + private fun setToolbarColors(foreground: Int, background: Int) { + val toolbar = (activity as AppCompatActivity).findViewById(R.id.navigationToolbar) + val colorFilter = PorterDuffColorFilter( + ContextCompat.getColor(context, foreground), PorterDuff.Mode.SRC_IN + ) + toolbar.setBackgroundColor(ContextCompat.getColor(context, background)) + toolbar.setTitleTextColor(ContextCompat.getColor(context, foreground)) + + themeToolbar( + toolbar, foreground, + background, colorFilter + ) + } + + private fun setUIForSelectingMode( + mode: BookmarkState.Mode.Selecting + ) { + activity?.title = context.getString(R.string.bookmarks_multi_select_title, mode.selectedItems.size) + setToolbarColors( + R.color.white_color, + R.attr.accentBright.getColorIntFromAttr(context!!) + ) + } + + private fun setUIForNormalMode(root: BookmarkNode?) { + activity?.title = + if (root?.title in setOf( + "root", + null + ) + ) context.getString(R.string.library_bookmarks) else root!!.title + + setToolbarColors( + R.attr.primaryText.getColorIntFromAttr(context!!), + R.attr.foundation.getColorIntFromAttr(context) + ) + } + + private fun themeToolbar( + toolbar: Toolbar, + textColor: Int, + backgroundColor: Int, + colorFilter: PorterDuffColorFilter? = null + ) { + toolbar.setTitleTextColor(ContextCompat.getColor(context!!, textColor)) + toolbar.setBackgroundColor(ContextCompat.getColor(context, backgroundColor)) + + if (colorFilter == null) { + return + } + + toolbar.overflowIcon?.colorFilter = colorFilter + (0 until toolbar.childCount).forEach { + when (val item = toolbar.getChildAt(it)) { + is ImageButton -> item.drawable.colorFilter = colorFilter + is ActionMenuView -> themeActionMenuView(item, colorFilter) + } + } + } + + private fun themeActionMenuView( + item: ActionMenuView, + colorFilter: PorterDuffColorFilter + ) { + (0 until item.childCount).forEach { + val innerChild = item.getChildAt(it) + if (innerChild is ActionMenuItemView) { + themeChildren(innerChild, item, colorFilter) + } + } + } + + private fun themeChildren( + innerChild: ActionMenuItemView, + item: ActionMenuView, + colorFilter: PorterDuffColorFilter + ) { + val drawables = innerChild.compoundDrawables + for (k in drawables.indices) { + drawables[k]?.let { + item.post { innerChild.compoundDrawables[k].colorFilter = colorFilter } + } + } + } }