Issue #2379 - Use LibraryPageView in history
parent
2813a3cff7
commit
ccae66c08a
|
@ -17,7 +17,6 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.annotation.AttrRes
|
import androidx.annotation.AttrRes
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import androidx.annotation.ColorRes
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
@ -100,14 +99,9 @@ fun Context.share(text: String, subject: String = ""): Boolean {
|
||||||
fun Context.getRootView(): View? =
|
fun Context.getRootView(): View? =
|
||||||
asActivity()?.window?.decorView?.findViewById<View>(android.R.id.content) as? ViewGroup
|
asActivity()?.window?.decorView?.findViewById<View>(android.R.id.content) as? ViewGroup
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the color resource corresponding to the attribute.
|
|
||||||
*/
|
|
||||||
@ColorRes
|
|
||||||
fun Context.getColorResFromAttr(@AttrRes attr: Int) = ThemeManager.resolveAttribute(attr, this)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the color int corresponding to the attribute.
|
* Returns the color int corresponding to the attribute.
|
||||||
*/
|
*/
|
||||||
@ColorInt
|
@ColorInt
|
||||||
fun Context.getColorFromAttr(@AttrRes attr: Int) = ContextCompat.getColor(this, getColorResFromAttr(attr))
|
fun Context.getColorFromAttr(@AttrRes attr: Int) =
|
||||||
|
ContextCompat.getColor(this, ThemeManager.resolveAttribute(attr, this))
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/* 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.library
|
||||||
|
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import org.mozilla.fenix.BrowsingModeManager
|
||||||
|
import org.mozilla.fenix.HomeActivity
|
||||||
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.ext.components
|
||||||
|
|
||||||
|
abstract class LibraryPageFragment<T> : Fragment() {
|
||||||
|
|
||||||
|
abstract val selectedItems: Set<T>
|
||||||
|
|
||||||
|
protected fun close() {
|
||||||
|
findNavController().popBackStack(R.id.libraryFragment, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun openItemsInNewTab(private: Boolean = false, toUrl: (T) -> String?) {
|
||||||
|
context?.components?.useCases?.tabsUseCases?.let { tabsUseCases ->
|
||||||
|
val addTab = if (private) tabsUseCases.addPrivateTab else tabsUseCases.addTab
|
||||||
|
selectedItems.asSequence()
|
||||||
|
.mapNotNull(toUrl)
|
||||||
|
.forEach { url ->
|
||||||
|
addTab.invoke(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(activity as HomeActivity).browsingModeManager.mode = if (private) {
|
||||||
|
BrowsingModeManager.Mode.Private
|
||||||
|
} else {
|
||||||
|
BrowsingModeManager.Mode.Normal
|
||||||
|
}
|
||||||
|
(activity as HomeActivity).supportActionBar?.hide()
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,29 +11,44 @@ import android.graphics.PorterDuffColorFilter
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ActionMenuView
|
import android.widget.ActionMenuView
|
||||||
import android.widget.ImageButton
|
import android.widget.ImageButton
|
||||||
import androidx.annotation.ColorRes
|
import androidx.annotation.ColorInt
|
||||||
import androidx.appcompat.view.menu.ActionMenuItemView
|
import androidx.appcompat.view.menu.ActionMenuItemView
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.forEach
|
import androidx.core.view.forEach
|
||||||
|
import kotlinx.android.extensions.LayoutContainer
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.ext.asActivity
|
import org.mozilla.fenix.ext.asActivity
|
||||||
|
import org.mozilla.fenix.ext.getColorFromAttr
|
||||||
|
|
||||||
open class LibraryPageView(
|
open class LibraryPageView(
|
||||||
container: ViewGroup
|
override val containerView: ViewGroup
|
||||||
) {
|
) : LayoutContainer {
|
||||||
protected val context: Context = container.context
|
protected val context: Context inline get() = containerView.context
|
||||||
protected val activity = context.asActivity()
|
protected val activity = context.asActivity()
|
||||||
|
|
||||||
|
protected fun setUiForNormalMode(title: String?) {
|
||||||
|
activity?.title = title
|
||||||
|
setToolbarColors(
|
||||||
|
ContextCompat.getColor(context, R.color.white_color),
|
||||||
|
context.getColorFromAttr(R.attr.accentHighContrast)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun setUiForSelectingMode(title: String?) {
|
||||||
|
activity?.title = title
|
||||||
|
setToolbarColors(
|
||||||
|
context.getColorFromAttr(R.attr.primaryText),
|
||||||
|
context.getColorFromAttr(R.attr.foundation)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adjust the colors of the [Toolbar] on the top of the screen.
|
* Adjust the colors of the [Toolbar] on the top of the screen.
|
||||||
*/
|
*/
|
||||||
protected fun setToolbarColors(@ColorRes foregroundRes: Int, @ColorRes backgroundRes: Int) {
|
private fun setToolbarColors(@ColorInt foreground: Int, @ColorInt background: Int) {
|
||||||
val toolbar = activity?.findViewById<Toolbar>(R.id.navigationToolbar)
|
val toolbar = activity?.findViewById<Toolbar>(R.id.navigationToolbar)
|
||||||
|
|
||||||
val foreground = ContextCompat.getColor(context, foregroundRes)
|
|
||||||
val background = ContextCompat.getColor(context, backgroundRes)
|
|
||||||
|
|
||||||
toolbar?.apply {
|
toolbar?.apply {
|
||||||
setBackgroundColor(background)
|
setBackgroundColor(background)
|
||||||
setTitleTextColor(foreground)
|
setTitleTextColor(foreground)
|
||||||
|
|
|
@ -15,7 +15,6 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
@ -34,8 +33,6 @@ import mozilla.components.concept.sync.OAuthAccount
|
||||||
import mozilla.components.concept.sync.Profile
|
import mozilla.components.concept.sync.Profile
|
||||||
import mozilla.components.lib.state.ext.consumeFrom
|
import mozilla.components.lib.state.ext.consumeFrom
|
||||||
import mozilla.components.support.base.feature.BackHandler
|
import mozilla.components.support.base.feature.BackHandler
|
||||||
import org.mozilla.fenix.BrowsingModeManager
|
|
||||||
import org.mozilla.fenix.HomeActivity
|
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.FenixSnackbarPresenter
|
import org.mozilla.fenix.components.FenixSnackbarPresenter
|
||||||
import org.mozilla.fenix.components.StoreProvider
|
import org.mozilla.fenix.components.StoreProvider
|
||||||
|
@ -47,10 +44,11 @@ import org.mozilla.fenix.ext.nav
|
||||||
import org.mozilla.fenix.ext.setRootTitles
|
import org.mozilla.fenix.ext.setRootTitles
|
||||||
import org.mozilla.fenix.ext.urlToTrimmedHost
|
import org.mozilla.fenix.ext.urlToTrimmedHost
|
||||||
import org.mozilla.fenix.ext.withOptionalDesktopFolders
|
import org.mozilla.fenix.ext.withOptionalDesktopFolders
|
||||||
|
import org.mozilla.fenix.library.LibraryPageFragment
|
||||||
import org.mozilla.fenix.utils.allowUndo
|
import org.mozilla.fenix.utils.allowUndo
|
||||||
|
|
||||||
@SuppressWarnings("TooManyFunctions", "LargeClass")
|
@SuppressWarnings("TooManyFunctions", "LargeClass")
|
||||||
class BookmarkFragment : Fragment(), BackHandler, AccountObserver {
|
class BookmarkFragment : LibraryPageFragment<BookmarkNode>(), BackHandler, AccountObserver {
|
||||||
|
|
||||||
private lateinit var bookmarkStore: BookmarkStore
|
private lateinit var bookmarkStore: BookmarkStore
|
||||||
private lateinit var bookmarkView: BookmarkView
|
private lateinit var bookmarkView: BookmarkView
|
||||||
|
@ -75,6 +73,8 @@ class BookmarkFragment : Fragment(), BackHandler, AccountObserver {
|
||||||
private val metrics
|
private val metrics
|
||||||
get() = context?.components?.analytics?.metrics
|
get() = context?.components?.analytics?.metrics
|
||||||
|
|
||||||
|
override val selectedItems get() = bookmarkStore.state.mode.selectedItems
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
val view = inflater.inflate(R.layout.fragment_bookmark, container, false)
|
val view = inflater.inflate(R.layout.fragment_bookmark, container, false)
|
||||||
|
|
||||||
|
@ -173,8 +173,7 @@ class BookmarkFragment : Fragment(), BackHandler, AccountObserver {
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
return when (item.itemId) {
|
return when (item.itemId) {
|
||||||
R.id.libraryClose -> {
|
R.id.libraryClose -> {
|
||||||
navigation
|
close()
|
||||||
.popBackStack(R.id.libraryFragment, true)
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
R.id.add_bookmark_folder -> {
|
R.id.add_bookmark_folder -> {
|
||||||
|
@ -186,20 +185,21 @@ class BookmarkFragment : Fragment(), BackHandler, AccountObserver {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
R.id.open_bookmarks_in_new_tabs_multi_select -> {
|
R.id.open_bookmarks_in_new_tabs_multi_select -> {
|
||||||
getSelectedBookmarks().forEach { node ->
|
openItemsInNewTab { node -> node.url }
|
||||||
node.url?.let {
|
|
||||||
context?.components?.useCases?.tabsUseCases?.addTab?.invoke(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(activity as HomeActivity).browsingModeManager.mode = BrowsingModeManager.Mode.Normal
|
|
||||||
(activity as HomeActivity).supportActionBar?.hide()
|
|
||||||
nav(R.id.bookmarkFragment, BookmarkFragmentDirections.actionBookmarkFragmentToHomeFragment())
|
nav(R.id.bookmarkFragment, BookmarkFragmentDirections.actionBookmarkFragmentToHomeFragment())
|
||||||
metrics?.track(Event.OpenedBookmarksInNewTabs)
|
metrics?.track(Event.OpenedBookmarksInNewTabs)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
R.id.open_bookmarks_in_private_tabs_multi_select -> {
|
||||||
|
openItemsInNewTab(private = true) { node -> node.url }
|
||||||
|
|
||||||
|
nav(R.id.bookmarkFragment, BookmarkFragmentDirections.actionBookmarkFragmentToHomeFragment())
|
||||||
|
metrics?.track(Event.OpenedBookmarksInPrivateTabs)
|
||||||
|
true
|
||||||
|
}
|
||||||
R.id.edit_bookmark_multi_select -> {
|
R.id.edit_bookmark_multi_select -> {
|
||||||
val bookmark = getSelectedBookmarks().first()
|
val bookmark = bookmarkStore.state.mode.selectedItems.first()
|
||||||
nav(
|
nav(
|
||||||
R.id.bookmarkFragment,
|
R.id.bookmarkFragment,
|
||||||
BookmarkFragmentDirections
|
BookmarkFragmentDirections
|
||||||
|
@ -207,21 +207,8 @@ class BookmarkFragment : Fragment(), BackHandler, AccountObserver {
|
||||||
)
|
)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
R.id.open_bookmarks_in_private_tabs_multi_select -> {
|
|
||||||
getSelectedBookmarks().forEach { node ->
|
|
||||||
node.url?.let {
|
|
||||||
context?.components?.useCases?.tabsUseCases?.addPrivateTab?.invoke(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(activity as HomeActivity).browsingModeManager.mode = BrowsingModeManager.Mode.Private
|
|
||||||
(activity as HomeActivity).supportActionBar?.hide()
|
|
||||||
nav(R.id.bookmarkFragment, BookmarkFragmentDirections.actionBookmarkFragmentToHomeFragment())
|
|
||||||
metrics?.track(Event.OpenedBookmarksInPrivateTabs)
|
|
||||||
true
|
|
||||||
}
|
|
||||||
R.id.delete_bookmarks_multi_select -> {
|
R.id.delete_bookmarks_multi_select -> {
|
||||||
deleteMulti(getSelectedBookmarks())
|
deleteMulti(bookmarkStore.state.mode.selectedItems)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
else -> super.onOptionsItemSelected(item)
|
else -> super.onOptionsItemSelected(item)
|
||||||
|
@ -247,8 +234,6 @@ class BookmarkFragment : Fragment(), BackHandler, AccountObserver {
|
||||||
override fun onProfileUpdated(profile: Profile) {
|
override fun onProfileUpdated(profile: Profile) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSelectedBookmarks() = bookmarkView.getSelected()
|
|
||||||
|
|
||||||
private suspend fun refreshBookmarks() {
|
private suspend fun refreshBookmarks() {
|
||||||
context?.bookmarkStorage()?.getTree(bookmarkStore.state.tree!!.guid, false).withOptionalDesktopFolders(context)
|
context?.bookmarkStorage()?.getTree(bookmarkStore.state.tree!!.guid, false).withOptionalDesktopFolders(context)
|
||||||
?.let { node ->
|
?.let { node ->
|
||||||
|
@ -265,7 +250,7 @@ class BookmarkFragment : Fragment(), BackHandler, AccountObserver {
|
||||||
super.onPause()
|
super.onPause()
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun deleteSelectedBookmarks(selected: Set<BookmarkNode> = getSelectedBookmarks()) {
|
private suspend fun deleteSelectedBookmarks(selected: Set<BookmarkNode>) {
|
||||||
selected.forEach {
|
selected.forEach {
|
||||||
context?.bookmarkStorage()?.deleteNode(it.guid)
|
context?.bookmarkStorage()?.deleteNode(it.guid)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,10 @@ class BookmarkStore(
|
||||||
*/
|
*/
|
||||||
data class BookmarkState(val tree: BookmarkNode?, val mode: Mode = Mode.Normal) : State {
|
data class BookmarkState(val tree: BookmarkNode?, val mode: Mode = Mode.Normal) : State {
|
||||||
sealed class Mode {
|
sealed class Mode {
|
||||||
|
open val selectedItems = emptySet<BookmarkNode>()
|
||||||
|
|
||||||
object Normal : Mode()
|
object Normal : Mode()
|
||||||
data class Selecting(val selectedItems: Set<BookmarkNode>) : Mode()
|
data class Selecting(override val selectedItems: Set<BookmarkNode>) : Mode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,32 +48,22 @@ sealed class BookmarkAction : Action {
|
||||||
fun bookmarkStateReducer(state: BookmarkState, action: BookmarkAction): BookmarkState {
|
fun bookmarkStateReducer(state: BookmarkState, action: BookmarkAction): BookmarkState {
|
||||||
return when (action) {
|
return when (action) {
|
||||||
is BookmarkAction.Change -> {
|
is BookmarkAction.Change -> {
|
||||||
val mode =
|
val items = state.mode.selectedItems.filter { it in action.tree }
|
||||||
if (state.mode is BookmarkState.Mode.Selecting) {
|
state.copy(
|
||||||
val items = state.mode.selectedItems.filter {
|
tree = action.tree,
|
||||||
it in action.tree
|
mode = if (items.isEmpty()) BookmarkState.Mode.Normal else BookmarkState.Mode.Selecting(items.toSet())
|
||||||
}.toSet()
|
)
|
||||||
if (items.isEmpty()) BookmarkState.Mode.Normal else BookmarkState.Mode.Selecting(items)
|
|
||||||
} else state.mode
|
|
||||||
state.copy(tree = action.tree, mode = mode)
|
|
||||||
}
|
|
||||||
is BookmarkAction.Select -> {
|
|
||||||
val selectedItems = if (state.mode is BookmarkState.Mode.Selecting) {
|
|
||||||
state.mode.selectedItems + action.item
|
|
||||||
} else setOf(action.item)
|
|
||||||
state.copy(mode = BookmarkState.Mode.Selecting(selectedItems))
|
|
||||||
}
|
}
|
||||||
|
is BookmarkAction.Select ->
|
||||||
|
state.copy(mode = BookmarkState.Mode.Selecting(state.mode.selectedItems + action.item))
|
||||||
is BookmarkAction.Deselect -> {
|
is BookmarkAction.Deselect -> {
|
||||||
val selectedItems = if (state.mode is BookmarkState.Mode.Selecting) {
|
val items = state.mode.selectedItems - action.item
|
||||||
state.mode.selectedItems - action.item
|
state.copy(
|
||||||
} else setOf()
|
mode = if (items.isEmpty()) BookmarkState.Mode.Normal else BookmarkState.Mode.Selecting(items)
|
||||||
val mode =
|
)
|
||||||
if (selectedItems.isEmpty()) BookmarkState.Mode.Normal else BookmarkState.Mode.Selecting(selectedItems)
|
|
||||||
state.copy(mode = mode)
|
|
||||||
}
|
}
|
||||||
BookmarkAction.DeselectAll -> {
|
BookmarkAction.DeselectAll ->
|
||||||
state.copy(mode = BookmarkState.Mode.Normal)
|
state.copy(mode = BookmarkState.Mode.Normal)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,16 +5,13 @@
|
||||||
package org.mozilla.fenix.library.bookmarks
|
package org.mozilla.fenix.library.bookmarks
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import kotlinx.android.extensions.LayoutContainer
|
|
||||||
import kotlinx.android.synthetic.main.component_bookmark.view.*
|
import kotlinx.android.synthetic.main.component_bookmark.view.*
|
||||||
import mozilla.appservices.places.BookmarkRoot
|
import mozilla.appservices.places.BookmarkRoot
|
||||||
import mozilla.components.concept.storage.BookmarkNode
|
import mozilla.components.concept.storage.BookmarkNode
|
||||||
import mozilla.components.support.base.feature.BackHandler
|
import mozilla.components.support.base.feature.BackHandler
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.ext.getColorResFromAttr
|
|
||||||
import org.mozilla.fenix.library.LibraryPageView
|
import org.mozilla.fenix.library.LibraryPageView
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -129,12 +126,13 @@ interface BookmarkViewInteractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
class BookmarkView(
|
class BookmarkView(
|
||||||
private val container: ViewGroup,
|
container: ViewGroup,
|
||||||
val interactor: BookmarkViewInteractor
|
val interactor: BookmarkViewInteractor
|
||||||
) : LibraryPageView(container), LayoutContainer, BackHandler {
|
) : LibraryPageView(container), BackHandler {
|
||||||
|
|
||||||
override val containerView: View?
|
val view: LinearLayout = LayoutInflater.from(container.context)
|
||||||
get() = container
|
.inflate(R.layout.component_bookmark, container, true)
|
||||||
|
.findViewById(R.id.bookmarks_wrapper)
|
||||||
|
|
||||||
var mode: BookmarkState.Mode = BookmarkState.Mode.Normal
|
var mode: BookmarkState.Mode = BookmarkState.Mode.Normal
|
||||||
private set
|
private set
|
||||||
|
@ -142,9 +140,6 @@ class BookmarkView(
|
||||||
private set
|
private set
|
||||||
private var canGoBack = false
|
private var canGoBack = false
|
||||||
|
|
||||||
val view: LinearLayout = LayoutInflater.from(container.context)
|
|
||||||
.inflate(R.layout.component_bookmark, container, true) as LinearLayout
|
|
||||||
|
|
||||||
private val bookmarkAdapter: BookmarkAdapter
|
private val bookmarkAdapter: BookmarkAdapter
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -155,17 +150,19 @@ class BookmarkView(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun update(state: BookmarkState) {
|
fun update(state: BookmarkState) {
|
||||||
canGoBack = !(listOf(null, BookmarkRoot.Root.id).contains(state.tree?.guid))
|
canGoBack = BookmarkRoot.Root.matches(state.tree)
|
||||||
if (state.tree != tree) {
|
tree = state.tree
|
||||||
tree = state.tree
|
|
||||||
}
|
|
||||||
if (state.mode != mode) {
|
if (state.mode != mode) {
|
||||||
mode = state.mode
|
mode = state.mode
|
||||||
interactor.switchMode(mode)
|
interactor.switchMode(mode)
|
||||||
}
|
}
|
||||||
when (val modeCopy = state.mode) {
|
|
||||||
is BookmarkState.Mode.Normal -> setUIForNormalMode(state.tree)
|
bookmarkAdapter.updateData(state.tree, mode)
|
||||||
is BookmarkState.Mode.Selecting -> setUIForSelectingMode(state.tree, modeCopy)
|
when (state.mode) {
|
||||||
|
is BookmarkState.Mode.Normal ->
|
||||||
|
setUiForNormalMode(state.tree)
|
||||||
|
is BookmarkState.Mode.Selecting ->
|
||||||
|
setUiForSelectingMode(context.getString(R.string.bookmarks_multi_select_title, mode.selectedItems.size))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,34 +180,16 @@ class BookmarkView(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getSelected(): Set<BookmarkNode> = bookmarkAdapter.selected
|
private fun setUiForNormalMode(root: BookmarkNode?) {
|
||||||
|
super.setUiForNormalMode(
|
||||||
private fun setUIForSelectingMode(
|
if (BookmarkRoot.Mobile.matches(root)) context.getString(R.string.library_bookmarks) else root?.title
|
||||||
root: BookmarkNode?,
|
|
||||||
mode: BookmarkState.Mode.Selecting
|
|
||||||
) {
|
|
||||||
bookmarkAdapter.updateData(root, mode)
|
|
||||||
activity?.title =
|
|
||||||
context.getString(R.string.bookmarks_multi_select_title, mode.selectedItems.size)
|
|
||||||
setToolbarColors(
|
|
||||||
R.color.white_color,
|
|
||||||
context.getColorResFromAttr(R.attr.accentHighContrast)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setUIForNormalMode(root: BookmarkNode?) {
|
/**
|
||||||
bookmarkAdapter.updateData(root, BookmarkState.Mode.Normal)
|
* Returns true if [root] matches the bookmark root ID.
|
||||||
setTitle(root)
|
*/
|
||||||
setToolbarColors(
|
private fun BookmarkRoot.matches(root: BookmarkNode?): Boolean {
|
||||||
context.getColorResFromAttr(R.attr.primaryText),
|
return root == null || id == root.guid
|
||||||
context.getColorResFromAttr(R.attr.foundation)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setTitle(root: BookmarkNode?) {
|
|
||||||
activity?.title = when (root?.guid) {
|
|
||||||
BookmarkRoot.Mobile.id, null -> context.getString(R.string.library_bookmarks)
|
|
||||||
else -> root.title
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,8 @@ import android.view.ViewGroup
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.Navigation
|
|
||||||
import kotlinx.android.synthetic.main.fragment_history.view.*
|
import kotlinx.android.synthetic.main.fragment_history.view.*
|
||||||
import kotlinx.coroutines.Dispatchers.Main
|
import kotlinx.coroutines.Dispatchers.Main
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -37,10 +35,11 @@ import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.ext.nav
|
import org.mozilla.fenix.ext.nav
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
|
import org.mozilla.fenix.library.LibraryPageFragment
|
||||||
import org.mozilla.fenix.share.ShareTab
|
import org.mozilla.fenix.share.ShareTab
|
||||||
|
|
||||||
@SuppressWarnings("TooManyFunctions")
|
@SuppressWarnings("TooManyFunctions")
|
||||||
class HistoryFragment : Fragment(), BackHandler {
|
class HistoryFragment : LibraryPageFragment<HistoryItem>(), BackHandler {
|
||||||
private lateinit var historyStore: HistoryStore
|
private lateinit var historyStore: HistoryStore
|
||||||
private lateinit var historyView: HistoryView
|
private lateinit var historyView: HistoryView
|
||||||
private lateinit var historyInteractor: HistoryInteractor
|
private lateinit var historyInteractor: HistoryInteractor
|
||||||
|
@ -71,6 +70,8 @@ class HistoryFragment : Fragment(), BackHandler {
|
||||||
return view
|
return view
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val selectedItems get() = historyStore.state.mode.selectedItems
|
||||||
|
|
||||||
private fun invalidateOptionsMenu() {
|
private fun invalidateOptionsMenu() {
|
||||||
activity?.invalidateOptionsMenu()
|
activity?.invalidateOptionsMenu()
|
||||||
}
|
}
|
||||||
|
@ -91,7 +92,7 @@ class HistoryFragment : Fragment(), BackHandler {
|
||||||
setHasOptionsMenu(true)
|
setHasOptionsMenu(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteHistoryItems(items: Set<HistoryItem>) {
|
private fun deleteHistoryItems(items: Set<HistoryItem>) {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
val storage = context?.components?.core?.historyStorage
|
val storage = context?.components?.core?.historyStorage
|
||||||
for (item in items) {
|
for (item in items) {
|
||||||
|
@ -126,10 +127,8 @@ class HistoryFragment : Fragment(), BackHandler {
|
||||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
val mode = historyStore.state.mode
|
val mode = historyStore.state.mode
|
||||||
when (mode) {
|
when (mode) {
|
||||||
HistoryState.Mode.Normal ->
|
HistoryState.Mode.Normal -> R.menu.library_menu
|
||||||
R.menu.library_menu
|
is HistoryState.Mode.Editing -> R.menu.history_select_multi
|
||||||
is HistoryState.Mode.Editing ->
|
|
||||||
R.menu.history_select_multi
|
|
||||||
else -> null
|
else -> null
|
||||||
}?.let { inflater.inflate(it, menu) }
|
}?.let { inflater.inflate(it, menu) }
|
||||||
|
|
||||||
|
@ -146,11 +145,10 @@ class HistoryFragment : Fragment(), BackHandler {
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) {
|
||||||
R.id.share_history_multi_select -> {
|
R.id.share_history_multi_select -> {
|
||||||
val selectedHistory =
|
val selectedHistory = historyStore.state.mode.selectedItems
|
||||||
(historyStore.state.mode as? HistoryState.Mode.Editing)?.selectedItems ?: setOf()
|
|
||||||
when {
|
when {
|
||||||
selectedHistory.size == 1 ->
|
selectedHistory.size == 1 ->
|
||||||
share(selectedHistory.first().url)
|
share(url = selectedHistory.first().url)
|
||||||
selectedHistory.size > 1 -> {
|
selectedHistory.size > 1 -> {
|
||||||
val shareTabs = selectedHistory.map { ShareTab(it.url, it.title) }
|
val shareTabs = selectedHistory.map { ShareTab(it.url, it.title) }
|
||||||
share(tabs = shareTabs)
|
share(tabs = shareTabs)
|
||||||
|
@ -159,36 +157,25 @@ class HistoryFragment : Fragment(), BackHandler {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
R.id.libraryClose -> {
|
R.id.libraryClose -> {
|
||||||
Navigation.findNavController(requireActivity(), R.id.container)
|
close()
|
||||||
.popBackStack(R.id.libraryFragment, true)
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
R.id.delete_history_multi_select -> {
|
R.id.delete_history_multi_select -> {
|
||||||
val components = context?.applicationContext?.components!!
|
val components = context?.components!!
|
||||||
val selectedHistory =
|
|
||||||
(historyStore.state.mode as? HistoryState.Mode.Editing)?.selectedItems ?: setOf()
|
|
||||||
|
|
||||||
lifecycleScope.launch(Main) {
|
lifecycleScope.launch(Main) {
|
||||||
deleteSelectedHistory(selectedHistory, components)
|
deleteSelectedHistory(historyStore.state.mode.selectedItems, components)
|
||||||
viewModel.invalidate()
|
viewModel.invalidate()
|
||||||
historyStore.dispatch(HistoryAction.ExitDeletionMode)
|
historyStore.dispatch(HistoryAction.ExitDeletionMode)
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
R.id.open_history_in_new_tabs_multi_select -> {
|
R.id.open_history_in_new_tabs_multi_select -> {
|
||||||
val selectedHistory =
|
openItemsInNewTab { selectedItem ->
|
||||||
(historyStore.state.mode as? HistoryState.Mode.Editing)?.selectedItems ?: setOf()
|
requireComponents.analytics.metrics.track(Event.HistoryItemOpened)
|
||||||
requireComponents.useCases.tabsUseCases.addTab.let { useCase ->
|
selectedItem.url
|
||||||
for (selectedItem in selectedHistory) {
|
|
||||||
requireComponents.analytics.metrics.track(Event.HistoryItemOpened)
|
|
||||||
useCase.invoke(selectedItem.url)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(activity as HomeActivity).apply {
|
|
||||||
browsingModeManager.mode = BrowsingModeManager.Mode.Normal
|
|
||||||
supportActionBar?.hide()
|
|
||||||
}
|
|
||||||
nav(
|
nav(
|
||||||
R.id.historyFragment,
|
R.id.historyFragment,
|
||||||
HistoryFragmentDirections.actionHistoryFragmentToHomeFragment()
|
HistoryFragmentDirections.actionHistoryFragmentToHomeFragment()
|
||||||
|
@ -196,13 +183,9 @@ class HistoryFragment : Fragment(), BackHandler {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
R.id.open_history_in_private_tabs_multi_select -> {
|
R.id.open_history_in_private_tabs_multi_select -> {
|
||||||
val selectedHistory =
|
openItemsInNewTab(private = true) { selectedItem ->
|
||||||
(historyStore.state.mode as? HistoryState.Mode.Editing)?.selectedItems ?: setOf()
|
requireComponents.analytics.metrics.track(Event.HistoryItemOpened)
|
||||||
requireComponents.useCases.tabsUseCases.addPrivateTab.let { useCase ->
|
selectedItem.url
|
||||||
for (selectedItem in selectedHistory) {
|
|
||||||
requireComponents.analytics.metrics.track(Event.HistoryItemOpened)
|
|
||||||
useCase.invoke(selectedItem.url)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(activity as HomeActivity).apply {
|
(activity as HomeActivity).apply {
|
||||||
|
@ -220,7 +203,7 @@ class HistoryFragment : Fragment(), BackHandler {
|
||||||
|
|
||||||
override fun onBackPressed(): Boolean = historyView.onBackPressed()
|
override fun onBackPressed(): Boolean = historyView.onBackPressed()
|
||||||
|
|
||||||
fun openItem(item: HistoryItem) {
|
private fun openItem(item: HistoryItem) {
|
||||||
requireComponents.analytics.metrics.track(Event.HistoryItemOpened)
|
requireComponents.analytics.metrics.track(Event.HistoryItemOpened)
|
||||||
(activity as HomeActivity).openToBrowserAndLoad(
|
(activity as HomeActivity).openToBrowserAndLoad(
|
||||||
searchTermOrURL = item.url,
|
searchTermOrURL = item.url,
|
||||||
|
|
|
@ -16,8 +16,7 @@ class HistoryInteractor(
|
||||||
private val deleteHistoryItems: (Set<HistoryItem>) -> Unit
|
private val deleteHistoryItems: (Set<HistoryItem>) -> Unit
|
||||||
) : HistoryViewInteractor {
|
) : HistoryViewInteractor {
|
||||||
override fun onItemPress(item: HistoryItem) {
|
override fun onItemPress(item: HistoryItem) {
|
||||||
val mode = store.state.mode
|
when (val mode = store.state.mode) {
|
||||||
when (mode) {
|
|
||||||
is HistoryState.Mode.Normal -> openToBrowser(item)
|
is HistoryState.Mode.Normal -> openToBrowser(item)
|
||||||
is HistoryState.Mode.Editing -> {
|
is HistoryState.Mode.Editing -> {
|
||||||
val isSelected = mode.selectedItems.contains(item)
|
val isSelected = mode.selectedItems.contains(item)
|
||||||
|
@ -32,9 +31,7 @@ class HistoryInteractor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemLongPress(item: HistoryItem) {
|
override fun onItemLongPress(item: HistoryItem) {
|
||||||
val isSelected = (store.state.mode as? HistoryState.Mode.Editing)?.let {
|
val isSelected = store.state.mode.selectedItems.contains(item)
|
||||||
it.selectedItems.contains(item)
|
|
||||||
} ?: false
|
|
||||||
|
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
store.dispatch(HistoryAction.RemoveItemForRemoval(item))
|
store.dispatch(HistoryAction.RemoveItemForRemoval(item))
|
||||||
|
|
|
@ -41,9 +41,11 @@ sealed class HistoryAction : Action {
|
||||||
*/
|
*/
|
||||||
data class HistoryState(val items: List<HistoryItem>, val mode: Mode) : State {
|
data class HistoryState(val items: List<HistoryItem>, val mode: Mode) : State {
|
||||||
sealed class Mode {
|
sealed class Mode {
|
||||||
|
open val selectedItems = emptySet<HistoryItem>()
|
||||||
|
|
||||||
object Normal : Mode()
|
object Normal : Mode()
|
||||||
data class Editing(val selectedItems: Set<HistoryItem>) : Mode()
|
|
||||||
object Deleting : Mode()
|
object Deleting : Mode()
|
||||||
|
data class Editing(override val selectedItems: Set<HistoryItem>) : Mode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,24 +54,13 @@ data class HistoryState(val items: List<HistoryItem>, val mode: Mode) : State {
|
||||||
*/
|
*/
|
||||||
fun historyStateReducer(state: HistoryState, action: HistoryAction): HistoryState {
|
fun historyStateReducer(state: HistoryState, action: HistoryAction): HistoryState {
|
||||||
return when (action) {
|
return when (action) {
|
||||||
is HistoryAction.AddItemForRemoval -> {
|
is HistoryAction.AddItemForRemoval ->
|
||||||
val mode = state.mode
|
state.copy(mode = HistoryState.Mode.Editing(state.mode.selectedItems + action.item))
|
||||||
if (mode is HistoryState.Mode.Editing) {
|
|
||||||
val items = mode.selectedItems + setOf(action.item)
|
|
||||||
state.copy(mode = HistoryState.Mode.Editing(items))
|
|
||||||
} else {
|
|
||||||
state.copy(mode = HistoryState.Mode.Editing(setOf(action.item)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is HistoryAction.RemoveItemForRemoval -> {
|
is HistoryAction.RemoveItemForRemoval -> {
|
||||||
var mode = state.mode
|
val selected = state.mode.selectedItems - action.item
|
||||||
|
state.copy(
|
||||||
if (mode is HistoryState.Mode.Editing) {
|
mode = if (selected.isEmpty()) HistoryState.Mode.Normal else HistoryState.Mode.Editing(selected)
|
||||||
val items = mode.selectedItems.minus(action.item)
|
)
|
||||||
state.copy(mode = HistoryState.Mode.Editing(items))
|
|
||||||
} else {
|
|
||||||
state
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
is HistoryAction.ExitEditMode -> state.copy(mode = HistoryState.Mode.Normal)
|
is HistoryAction.ExitEditMode -> state.copy(mode = HistoryState.Mode.Normal)
|
||||||
is HistoryAction.EnterDeletionMode -> state.copy(mode = HistoryState.Mode.Deleting)
|
is HistoryAction.EnterDeletionMode -> state.copy(mode = HistoryState.Mode.Deleting)
|
||||||
|
|
|
@ -4,27 +4,17 @@
|
||||||
|
|
||||||
package org.mozilla.fenix.library.history
|
package org.mozilla.fenix.library.history
|
||||||
|
|
||||||
import android.graphics.PorterDuff
|
|
||||||
import android.graphics.PorterDuffColorFilter
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageButton
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.appcompat.widget.Toolbar
|
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.SimpleItemAnimator
|
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||||
import kotlinx.android.extensions.LayoutContainer
|
|
||||||
import kotlinx.android.synthetic.main.component_history.*
|
import kotlinx.android.synthetic.main.component_history.*
|
||||||
import kotlinx.android.synthetic.main.component_history.view.*
|
import kotlinx.android.synthetic.main.component_history.view.*
|
||||||
import kotlinx.android.synthetic.main.component_history.view.history_list
|
|
||||||
import mozilla.components.support.base.feature.BackHandler
|
import mozilla.components.support.base.feature.BackHandler
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.ext.asActivity
|
import org.mozilla.fenix.library.LibraryPageView
|
||||||
import org.mozilla.fenix.ext.getColorResFromAttr
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for the HistoryViewInteractor. This interface is implemented by objects that want
|
* Interface for the HistoryViewInteractor. This interface is implemented by objects that want
|
||||||
|
@ -73,27 +63,22 @@ interface HistoryViewInteractor {
|
||||||
* View that contains and configures the History List
|
* View that contains and configures the History List
|
||||||
*/
|
*/
|
||||||
class HistoryView(
|
class HistoryView(
|
||||||
private val container: ViewGroup,
|
container: ViewGroup,
|
||||||
val interactor: HistoryInteractor
|
val interactor: HistoryInteractor
|
||||||
) : LayoutContainer, BackHandler {
|
) : LibraryPageView(container), BackHandler {
|
||||||
|
|
||||||
val view: ConstraintLayout = LayoutInflater.from(container.context)
|
val view: ConstraintLayout = LayoutInflater.from(container.context)
|
||||||
.inflate(R.layout.component_history, container, true)
|
.inflate(R.layout.component_history, container, true)
|
||||||
.findViewById(R.id.history_wrapper)
|
.findViewById(R.id.history_wrapper)
|
||||||
|
|
||||||
override val containerView: View?
|
|
||||||
get() = container
|
|
||||||
|
|
||||||
val historyAdapter: HistoryAdapter
|
|
||||||
private var items: List<HistoryItem> = listOf()
|
private var items: List<HistoryItem> = listOf()
|
||||||
private val context = container.context
|
|
||||||
var mode: HistoryState.Mode = HistoryState.Mode.Normal
|
var mode: HistoryState.Mode = HistoryState.Mode.Normal
|
||||||
private set
|
private set
|
||||||
private val activity = context?.asActivity()
|
|
||||||
private val layoutManager = LinearLayoutManager(container.context)
|
|
||||||
init {
|
|
||||||
historyAdapter = HistoryAdapter(interactor)
|
|
||||||
|
|
||||||
|
val historyAdapter = HistoryAdapter(interactor)
|
||||||
|
private val layoutManager = LinearLayoutManager(container.context)
|
||||||
|
|
||||||
|
init {
|
||||||
view.history_list.apply {
|
view.history_list.apply {
|
||||||
layoutManager = this@HistoryView.layoutManager
|
layoutManager = this@HistoryView.layoutManager
|
||||||
adapter = historyAdapter
|
adapter = historyAdapter
|
||||||
|
@ -102,37 +87,36 @@ class HistoryView(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun update(state: HistoryState) {
|
fun update(state: HistoryState) {
|
||||||
view.progress_bar.visibility =
|
val oldMode = mode
|
||||||
if (state.mode is HistoryState.Mode.Deleting) View.VISIBLE else View.GONE
|
|
||||||
|
|
||||||
if (state.mode != mode) {
|
view.progress_bar.isVisible = state.mode === HistoryState.Mode.Deleting
|
||||||
|
items = state.items
|
||||||
|
mode = state.mode
|
||||||
|
|
||||||
|
if (state.mode != oldMode) {
|
||||||
interactor.onModeSwitched()
|
interactor.onModeSwitched()
|
||||||
historyAdapter.updateMode(state.mode)
|
historyAdapter.updateMode(state.mode)
|
||||||
|
|
||||||
val oldMode = mode
|
// Deselect all the previously selected items
|
||||||
if (oldMode is HistoryState.Mode.Editing) {
|
oldMode.selectedItems.forEach {
|
||||||
oldMode.selectedItems.forEach {
|
historyAdapter.notifyItemChanged(it.id)
|
||||||
historyAdapter.notifyItemChanged(it.id)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(state.mode as? HistoryState.Mode.Editing)?.also {
|
if (state.mode is HistoryState.Mode.Editing) {
|
||||||
val oldMode = (mode as? HistoryState.Mode.Editing)
|
val unselectedItems = oldMode.selectedItems - state.mode.selectedItems
|
||||||
val unselectedItems = oldMode?.selectedItems?.minus(it.selectedItems) ?: setOf()
|
|
||||||
|
|
||||||
it.selectedItems.union(unselectedItems).forEach { item ->
|
state.mode.selectedItems.union(unselectedItems).forEach { item ->
|
||||||
historyAdapter.notifyItemChanged(item.id)
|
historyAdapter.notifyItemChanged(item.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
items = state.items
|
|
||||||
when (val mode = state.mode) {
|
when (val mode = state.mode) {
|
||||||
is HistoryState.Mode.Normal -> setUIForNormalMode()
|
is HistoryState.Mode.Normal ->
|
||||||
is HistoryState.Mode.Editing -> setUIForSelectingMode(mode.selectedItems.size)
|
setUiForNormalMode(context.getString(R.string.library_history))
|
||||||
|
is HistoryState.Mode.Editing ->
|
||||||
|
setUiForSelectingMode(context.getString(R.string.history_multi_select_title, mode.selectedItems.size))
|
||||||
}
|
}
|
||||||
|
|
||||||
mode = state.mode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateEmptyState(userHasHistory: Boolean) {
|
fun updateEmptyState(userHasHistory: Boolean) {
|
||||||
|
@ -140,59 +124,6 @@ class HistoryView(
|
||||||
history_empty_view.isVisible = !userHasHistory
|
history_empty_view.isVisible = !userHasHistory
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setUIForSelectingMode(selectedItemSize: Int) {
|
|
||||||
activity?.title =
|
|
||||||
context.getString(R.string.history_multi_select_title, selectedItemSize)
|
|
||||||
setToolbarColors(
|
|
||||||
R.color.white_color,
|
|
||||||
context!!.getColorResFromAttr(R.attr.accentHighContrast)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setUIForNormalMode() {
|
|
||||||
activity?.title = context.getString(R.string.library_history)
|
|
||||||
setToolbarColors(
|
|
||||||
context!!.getColorResFromAttr(R.attr.primaryText),
|
|
||||||
context.getColorResFromAttr(R.attr.foundation)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setToolbarColors(foreground: Int, background: Int) {
|
|
||||||
val toolbar = (activity as AppCompatActivity).findViewById<Toolbar>(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 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBackPressed(): Boolean {
|
override fun onBackPressed(): Boolean {
|
||||||
return interactor.onBackPressed()
|
return interactor.onBackPressed()
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
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"
|
||||||
|
android:id="@+id/bookmarks_wrapper"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:listitem="@layout/bookmark_row" />
|
tools:listitem="@layout/library_site_item" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/bookmarks_empty_view"
|
android:id="@+id/bookmarks_empty_view"
|
||||||
|
|
Loading…
Reference in New Issue