/* 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.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 import kotlinx.android.synthetic.main.component_bookmark.view.* 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( container: ViewGroup, actionEmitter: Observer, changesObservable: Observable ) : UIView(container, actionEmitter, changesObservable), BackHandler { var mode: BookmarkState.Mode = BookmarkState.Mode.Normal private set var tree: BookmarkNode? = null private set 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 { bookmarkAdapter = BookmarkAdapter(view.bookmarks_empty_view, actionEmitter) adapter = bookmarkAdapter } } override fun updateView() = Consumer { canGoBack = !(listOf(null, BookmarkRoot.Root.id).contains(it.tree?.guid)) if (it.tree != tree) { tree = it.tree } if (it.mode != mode) { mode = it.mode actionEmitter.onNext(BookmarkAction.ModeChanged) } bookmarkAdapter.updateData(it.tree, it.mode) when (val modeCopy = mode) { is BookmarkState.Mode.Normal -> setUIForNormalMode(it.tree) is BookmarkState.Mode.Selecting -> setUIForSelectingMode(modeCopy) } } override fun onBackPressed(): Boolean { return when { mode is BookmarkState.Mode.Selecting -> { mode = BookmarkState.Mode.Normal bookmarkAdapter.updateData(tree, mode) setUIForNormalMode(tree) actionEmitter.onNext(BookmarkAction.ModeChanged) true } canGoBack -> { actionEmitter.onNext(BookmarkAction.BackPressed) true } else -> false } } fun getSelected(): Set = bookmarkAdapter.selected private fun setToolbarColors(foreground: Int, background: Int) { val toolbar = activity?.findViewById(R.id.navigationToolbar) val colorFilter = PorterDuffColorFilter( ContextCompat.getColor(context, foreground), PorterDuff.Mode.SRC_IN ) toolbar?.run { setBackgroundColor(ContextCompat.getColor(context, background)) 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?) { setTitle(root) setToolbarColors( R.attr.primaryText.getColorIntFromAttr(context!!), R.attr.foundation.getColorIntFromAttr(context) ) } private fun setTitle(root: BookmarkNode?) { (activity as? AppCompatActivity)?.title = if (root?.guid in setOf( BookmarkRoot.Mobile.id, BookmarkRoot.Root.id, null ) ) context.getString(R.string.library_bookmarks) else root!!.title } 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 } } } } }