For #2419 - Adds a deletion state to the history component

nightly-build-test
Jeff Boek 5 years ago
parent 9617a06232
commit 3920cda693

@ -38,6 +38,7 @@ data class HistoryState(val items: List<HistoryItem>, val mode: Mode) : ViewStat
sealed class Mode { sealed class Mode {
object Normal : Mode() object Normal : Mode()
data class Editing(val selectedItems: List<HistoryItem>) : Mode() data class Editing(val selectedItems: List<HistoryItem>) : Mode()
object Deleting : Mode()
} }
} }
@ -62,6 +63,8 @@ sealed class HistoryChange : Change {
object ExitEditMode : HistoryChange() object ExitEditMode : HistoryChange()
data class AddItemForRemoval(val item: HistoryItem) : HistoryChange() data class AddItemForRemoval(val item: HistoryItem) : HistoryChange()
data class RemoveItemForRemoval(val item: HistoryItem) : HistoryChange() data class RemoveItemForRemoval(val item: HistoryItem) : HistoryChange()
object EnterDeletionMode : HistoryChange()
object ExitDeletionMode : HistoryChange()
} }
class HistoryViewModel( class HistoryViewModel(
@ -95,6 +98,8 @@ class HistoryViewModel(
} }
} }
is HistoryChange.ExitEditMode -> state.copy(mode = HistoryState.Mode.Normal) is HistoryChange.ExitEditMode -> state.copy(mode = HistoryState.Mode.Normal)
is HistoryChange.EnterDeletionMode -> state.copy(mode = HistoryState.Mode.Deleting)
is HistoryChange.ExitDeletionMode -> state.copy(mode = HistoryState.Mode.Normal)
} }
} }
} }

@ -22,6 +22,7 @@ import androidx.fragment.app.Fragment
import androidx.navigation.Navigation import androidx.navigation.Navigation
import kotlinx.android.synthetic.main.fragment_history.view.* import kotlinx.android.synthetic.main.fragment_history.view.*
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.MainScope import kotlinx.coroutines.MainScope
@ -106,7 +107,8 @@ class HistoryFragment : Fragment(), CoroutineScope by MainScope(), BackHandler {
R.menu.library_menu R.menu.library_menu
is HistoryState.Mode.Editing -> is HistoryState.Mode.Editing ->
R.menu.history_select_multi R.menu.history_select_multi
}.let { inflater.inflate(it, menu) } else -> null
}?.let { inflater.inflate(it, menu) }
if (mode is HistoryState.Mode.Editing) { if (mode is HistoryState.Mode.Editing) {
menu.findItem(R.id.share_history_multi_select)?.run { menu.findItem(R.id.share_history_multi_select)?.run {
@ -237,10 +239,15 @@ class HistoryFragment : Fragment(), CoroutineScope by MainScope(), BackHandler {
dialog.cancel() dialog.cancel()
} }
setPositiveButton(R.string.history_clear_dialog) { dialog: DialogInterface, _ -> setPositiveButton(R.string.history_clear_dialog) { dialog: DialogInterface, _ ->
emitChange { HistoryChange.EnterDeletionMode }
launch { launch {
requireComponents.core.historyStorage.deleteEverything() requireComponents.core.historyStorage.deleteEverything()
reloadData() reloadData()
launch(Dispatchers.Main) {
emitChange { HistoryChange.ExitDeletionMode }
}
} }
dialog.dismiss() dialog.dismiss()
} }
create() create()
@ -302,6 +309,8 @@ class HistoryFragment : Fragment(), CoroutineScope by MainScope(), BackHandler {
private inline fun emitChange(producer: () -> HistoryChange) { private inline fun emitChange(producer: () -> HistoryChange) {
getManagedEmitter<HistoryChange>().onNext(producer()) getManagedEmitter<HistoryChange>().onNext(producer())
} }
}
private const val HISTORY_TIME_DAYS = 3L companion object {
private const val HISTORY_TIME_DAYS = 3L
}
}

@ -9,10 +9,10 @@ import android.graphics.PorterDuffColorFilter
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import android.widget.ImageButton import android.widget.ImageButton
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.reactivex.Observable import io.reactivex.Observable
@ -45,7 +45,7 @@ class HistoryUIView(
fun getSelected(): List<HistoryItem> = historyAdapter.selected fun getSelected(): List<HistoryItem> = historyAdapter.selected
override val view: FrameLayout = LayoutInflater.from(container.context) override 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)
@ -58,10 +58,13 @@ class HistoryUIView(
} }
override fun updateView() = Consumer<HistoryState> { override fun updateView() = Consumer<HistoryState> {
view.progress_bar.visibility = if (it.mode is HistoryState.Mode.Deleting) View.VISIBLE else View.GONE
if (it.mode != mode) { if (it.mode != mode) {
mode = it.mode mode = it.mode
actionEmitter.onNext(HistoryAction.SwitchMode) actionEmitter.onNext(HistoryAction.SwitchMode)
} }
(view.history_list.adapter as HistoryAdapter).updateData(it.items, it.mode) (view.history_list.adapter as HistoryAdapter).updateData(it.items, it.mode)
items = it.items items = it.items
@ -128,8 +131,8 @@ class HistoryUIView(
} }
override fun onBackPressed(): Boolean { override fun onBackPressed(): Boolean {
return when { return when (mode) {
mode is HistoryState.Mode.Editing -> { is HistoryState.Mode.Editing -> {
mode = HistoryState.Mode.Normal mode = HistoryState.Mode.Normal
historyAdapter.updateData(items, mode) historyAdapter.updateData(items, mode)
setUIForNormalMode(items.isEmpty()) setUIForNormalMode(items.isEmpty())

@ -25,7 +25,8 @@ class HistoryDeleteButtonViewHolder(
val action = when (it) { val action = when (it) {
is HistoryState.Mode.Normal -> HistoryAction.Delete.All is HistoryState.Mode.Normal -> HistoryAction.Delete.All
is HistoryState.Mode.Editing -> HistoryAction.Delete.Some(it.selectedItems) is HistoryState.Mode.Editing -> HistoryAction.Delete.Some(it.selectedItems)
} is HistoryState.Mode.Deleting -> null
} ?: return@also
actionEmitter.onNext(action) actionEmitter.onNext(action)
} }
@ -35,7 +36,8 @@ class HistoryDeleteButtonViewHolder(
this.mode = mode this.mode = mode
buttonView.run { buttonView.run {
if (mode is HistoryState.Mode.Editing && mode.selectedItems.isNotEmpty()) { val isDeleting = mode is HistoryState.Mode.Deleting
if (isDeleting || mode is HistoryState.Mode.Editing && mode.selectedItems.isNotEmpty()) {
isEnabled = false isEnabled = false
alpha = DISABLED_ALPHA alpha = DISABLED_ALPHA
} else { } else {

@ -85,7 +85,7 @@ class HistoryListItemViewHolder(
val selected = when (mode) { val selected = when (mode) {
is HistoryState.Mode.Editing -> mode.selectedItems.contains(item) is HistoryState.Mode.Editing -> mode.selectedItems.contains(item)
HistoryState.Mode.Normal -> false else -> false
} }
setClickListeners(item, selected) setClickListeners(item, selected)

@ -3,11 +3,21 @@
- License, v. 2.0. If a copy of the MPL was not distributed with this - 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/. --> - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<FrameLayout <androidx.constraintlayout.widget.ConstraintLayout 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"
android:id="@+id/history_wrapper" android:id="@+id/history_wrapper"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<ProgressBar
android:id="@+id/progress_bar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:indeterminate="true"
android:layout_width="match_parent"
android:layout_height="8dp"
android:translationY="-3dp"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView <TextView
android:id="@+id/history_empty_view" android:id="@+id/history_empty_view"
@ -17,9 +27,13 @@
android:text="@string/history_empty_message" android:text="@string/history_empty_message"
android:textColor="?secondaryText" android:textColor="?secondaryText"
android:textSize="16sp" android:textSize="16sp"
android:visibility="gone" /> android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/history_list" android:id="@+id/history_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
</FrameLayout> </androidx.constraintlayout.widget.ConstraintLayout>

Loading…
Cancel
Save