From 0cbcd932088e004b666f1d330d15feb6156693ec Mon Sep 17 00:00:00 2001 From: Jeff Boek Date: Wed, 13 Feb 2019 14:36:59 -0800 Subject: [PATCH] For #357 - Adds an editing mode to the history component --- .../fenix/library/history/HistoryComponent.kt | 12 +++++-- .../fenix/library/history/HistoryFragment.kt | 28 +++++++++------ .../fenix/library/history/HistoryUIView.kt | 34 +++++++++++++++---- app/src/main/res/layout/history_list_item.xml | 10 +++++- 4 files changed, 64 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/library/history/HistoryComponent.kt b/app/src/main/java/org/mozilla/fenix/library/history/HistoryComponent.kt index e6885546a..e685c3e9c 100644 --- a/app/src/main/java/org/mozilla/fenix/library/history/HistoryComponent.kt +++ b/app/src/main/java/org/mozilla/fenix/library/history/HistoryComponent.kt @@ -28,7 +28,7 @@ data class HistoryItem(val url: String) { class HistoryComponent( private val container: ViewGroup, bus: ActionBusFactory, - override var initialState: HistoryState = HistoryState(emptyList()) + override var initialState: HistoryState = HistoryState(emptyList(), HistoryState.Mode.Normal) ) : UIComponent( bus.getManagedEmitter(HistoryAction::class.java), @@ -38,6 +38,7 @@ class HistoryComponent( override val reducer: (HistoryState, HistoryChange) -> HistoryState = { state, change -> when (change) { is HistoryChange.Change -> state.copy(items = change.list) + is HistoryChange.Mode-> state.copy(mode = change.mode) } } @@ -48,12 +49,19 @@ class HistoryComponent( } } -data class HistoryState(val items: List) : ViewState +data class HistoryState(val items: List, val mode: Mode) : ViewState { + sealed class Mode { + object Normal : Mode() + object Editing : Mode() + } +} sealed class HistoryAction : Action { data class Select(val item: HistoryItem) : HistoryAction() + data class Edit(val item: HistoryItem) : HistoryAction() } sealed class HistoryChange : Change { data class Change(val list: List) : HistoryChange() + data class Mode(val mode: HistoryState.Mode) : HistoryChange() } diff --git a/app/src/main/java/org/mozilla/fenix/library/history/HistoryFragment.kt b/app/src/main/java/org/mozilla/fenix/library/history/HistoryFragment.kt index 8bbc174d1..0dbc1a658 100644 --- a/app/src/main/java/org/mozilla/fenix/library/history/HistoryFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/library/history/HistoryFragment.kt @@ -25,6 +25,7 @@ import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.mvi.ActionBusFactory +import org.mozilla.fenix.mvi.getManagedEmitter import org.mozilla.fenix.mvi.getSafeManagedObservable import kotlin.coroutines.CoroutineContext @@ -40,7 +41,7 @@ class HistoryFragment : Fragment(), CoroutineScope { savedInstanceState: Bundle? ): View? { val view = inflater.inflate(R.layout.fragment_history, container, false) - HistoryComponent(view.history_layout, ActionBusFactory.get(this), initialState = HistoryState(emptyList())) + HistoryComponent(view.history_layout, ActionBusFactory.get(this)) return view } @@ -55,20 +56,25 @@ class HistoryFragment : Fragment(), CoroutineScope { getSafeManagedObservable() .subscribe { - if (it is HistoryAction.Select) { - Navigation.findNavController(requireActivity(), R.id.container).apply { - navigate( - HistoryFragmentDirections.actionGlobalBrowser(null, - (activity as HomeActivity).browsingModeManager.isPrivate), - NavOptions.Builder().setPopUpTo(R.id.homeFragment, false).build() - ) - } - - requireComponents.useCases.sessionUseCases.loadUrl.invoke(it.item.url) + when (it) { + is HistoryAction.Select -> selectItem(it.item) + is HistoryAction.Edit -> getManagedEmitter().onNext(HistoryChange.Mode(HistoryState.Mode.Editing)) } } } + private fun selectItem(item: HistoryItem) { + Navigation.findNavController(requireActivity(), R.id.container).apply { + navigate( + HistoryFragmentDirections.actionGlobalBrowser(null, + (activity as HomeActivity).browsingModeManager.isPrivate), + NavOptions.Builder().setPopUpTo(R.id.homeFragment, false).build() + ) + } + + requireComponents.useCases.sessionUseCases.loadUrl.invoke(item.url) + } + override fun onDestroy() { super.onDestroy() job.cancel() diff --git a/app/src/main/java/org/mozilla/fenix/library/history/HistoryUIView.kt b/app/src/main/java/org/mozilla/fenix/library/history/HistoryUIView.kt index 1e70c41eb..2115f41e1 100644 --- a/app/src/main/java/org/mozilla/fenix/library/history/HistoryUIView.kt +++ b/app/src/main/java/org/mozilla/fenix/library/history/HistoryUIView.kt @@ -8,6 +8,8 @@ package org.mozilla.fenix.library.history import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.CheckBox +import android.widget.ImageView import android.widget.TextView import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -36,7 +38,9 @@ class HistoryUIView( } override fun updateView() = Consumer { - (view.adapter as HistoryAdapter).updateData(it.items) + val isEditing = it.mode == HistoryState.Mode.Editing + + (view.adapter as HistoryAdapter).updateData(it.items, it.mode) } } @@ -48,9 +52,12 @@ private class HistoryAdapter( private val actionEmitter: Observer ) : RecyclerView.ViewHolder(view) { - private var title = view.findViewById(R.id.history_title) - private var url = view.findViewById(R.id.history_url) + private val checkbox = view.findViewById(R.id.should_remove_checkbox) + private val favicon = view.findViewById(R.id.history_favicon) + private val title = view.findViewById(R.id.history_title) + private val url = view.findViewById(R.id.history_url) private var item: HistoryItem? = null + private var mode: HistoryState.Mode = HistoryState.Mode.Normal init { view.setOnClickListener { @@ -58,13 +65,26 @@ private class HistoryAdapter( actionEmitter.onNext(HistoryAction.Select(this)) } } + + view.setOnLongClickListener { + item?.apply { + actionEmitter.onNext(HistoryAction.Edit(this)) + } + + true + } } - fun bind(item: HistoryItem) { + fun bind(item: HistoryItem, mode: HistoryState.Mode) { this.item = item + this.mode = mode title.text = item.title url.text = item.url + + val isEditing = mode == HistoryState.Mode.Editing + checkbox.visibility = if (isEditing) { View.VISIBLE } else { View.GONE } + favicon.visibility = if (isEditing) { View.INVISIBLE } else { View.VISIBLE } } companion object { @@ -87,9 +107,11 @@ private class HistoryAdapter( } private var items: List = emptyList() + private var mode: HistoryState.Mode = HistoryState.Mode.Normal - fun updateData(items: List) { + fun updateData(items: List, mode: HistoryState.Mode) { this.items = items + this.mode = mode notifyDataSetChanged() } @@ -116,7 +138,7 @@ private class HistoryAdapter( when (holder) { is HistoryHeaderViewHolder -> holder.bind("Today") - is HistoryListItemViewHolder -> holder.bind(items[position - NUMBER_OF_SECTIONS]) + is HistoryListItemViewHolder -> holder.bind(items[position - NUMBER_OF_SECTIONS], mode) } } diff --git a/app/src/main/res/layout/history_list_item.xml b/app/src/main/res/layout/history_list_item.xml index 9dabd5c29..ca4606fbb 100644 --- a/app/src/main/res/layout/history_list_item.xml +++ b/app/src/main/res/layout/history_list_item.xml @@ -8,7 +8,15 @@ android:paddingStart="20dp" android:background="?android:attr/selectableItemBackground" xmlns:app="http://schemas.android.com/apk/res-auto"> - + + +