#2119 removed unnecessary states from history view model

This commit is contained in:
Frans-Lukas Lövenvald 2020-06-09 14:58:49 +02:00
parent 18d5f9a787
commit c0069c1a4c
6 changed files with 57 additions and 146 deletions

View File

@ -37,8 +37,6 @@ import org.kiwix.kiwixmobile.core.history.viewmodel.Action.UserClickedDeleteSele
import org.kiwix.kiwixmobile.core.history.viewmodel.Action.UserClickedShowAllToggle import org.kiwix.kiwixmobile.core.history.viewmodel.Action.UserClickedShowAllToggle
import org.kiwix.kiwixmobile.core.history.viewmodel.HistoryViewModel import org.kiwix.kiwixmobile.core.history.viewmodel.HistoryViewModel
import org.kiwix.kiwixmobile.core.history.viewmodel.State import org.kiwix.kiwixmobile.core.history.viewmodel.State
import org.kiwix.kiwixmobile.core.history.viewmodel.State.Results
import org.kiwix.kiwixmobile.core.history.viewmodel.State.SelectionResults
import org.kiwix.kiwixmobile.core.utils.SimpleTextListener import org.kiwix.kiwixmobile.core.utils.SimpleTextListener
import javax.inject.Inject import javax.inject.Inject
@ -128,25 +126,19 @@ class HistoryActivity : OnItemClickListener, BaseActivity() {
return super.onOptionsItemSelected(item) return super.onOptionsItemSelected(item)
} }
private fun render(state: State) = private fun render(state: State) {
when (state) { historyAdapter.items = state.getHistoryListItems()
is Results -> { if (!state.isInSelectionState) {
actionMode?.finish() actionMode?.finish()
historyAdapter.items = state.getHistoryListItems() history_switch.isEnabled = true
history_switch.isChecked = state.showAll } else {
history_switch.isEnabled = true if (actionMode == null) {
toggleNoHistoryText(state) actionMode = startSupportActionMode(actionModeCallback)
}
is SelectionResults -> {
if (state.historyItems.any(HistoryItem::isSelected) && actionMode == null) {
actionMode = startSupportActionMode(actionModeCallback)
}
historyAdapter.items = state.getHistoryListItems()
history_switch.isChecked = state.showAll
history_switch.isEnabled = false
toggleNoHistoryText(state)
} }
history_switch.isEnabled = false
} }
toggleNoHistoryText(state)
}
private fun toggleNoHistoryText(state: State) { private fun toggleNoHistoryText(state: State) {
if (state.getHistoryListItems().isEmpty()) { if (state.getHistoryListItems().isEmpty()) {

View File

@ -30,7 +30,6 @@ sealed class Action {
data class OnItemClick(val historyItem: HistoryItem) : Action() data class OnItemClick(val historyItem: HistoryItem) : Action()
data class OnItemLongClick(val historyItem: HistoryItem) : Action() data class OnItemLongClick(val historyItem: HistoryItem) : Action()
data class UserClickedShowAllToggle(val isChecked: Boolean) : Action() data class UserClickedShowAllToggle(val isChecked: Boolean) : Action()
data class AllHistoryPreferenceChanged(val showAll: Boolean) : Action()
data class Filter(val searchTerm: String) : Action() data class Filter(val searchTerm: String) : Action()
data class UpdateHistory(val history: List<HistoryItem>) : Action() data class UpdateHistory(val history: List<HistoryItem>) : Action()
} }

View File

@ -1,13 +1,12 @@
package org.kiwix.kiwixmobile.core.history.viewmodel package org.kiwix.kiwixmobile.core.history.viewmodel
import org.kiwix.kiwixmobile.core.history.viewmodel.effects.OpenHistoryItem
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.processors.PublishProcessor import io.reactivex.processors.PublishProcessor
import io.reactivex.schedulers.Schedulers
import org.kiwix.kiwixmobile.core.base.SideEffect import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.dao.HistoryDao import org.kiwix.kiwixmobile.core.dao.HistoryDao
import org.kiwix.kiwixmobile.core.history.viewmodel.Action.AllHistoryPreferenceChanged
import org.kiwix.kiwixmobile.core.history.viewmodel.Action.ExitActionModeMenu import org.kiwix.kiwixmobile.core.history.viewmodel.Action.ExitActionModeMenu
import org.kiwix.kiwixmobile.core.history.viewmodel.Action.ExitHistory import org.kiwix.kiwixmobile.core.history.viewmodel.Action.ExitHistory
import org.kiwix.kiwixmobile.core.history.viewmodel.Action.Filter import org.kiwix.kiwixmobile.core.history.viewmodel.Action.Filter
@ -18,9 +17,8 @@ import org.kiwix.kiwixmobile.core.history.viewmodel.Action.UserClickedConfirmDel
import org.kiwix.kiwixmobile.core.history.viewmodel.Action.UserClickedDeleteButton import org.kiwix.kiwixmobile.core.history.viewmodel.Action.UserClickedDeleteButton
import org.kiwix.kiwixmobile.core.history.viewmodel.Action.UserClickedDeleteSelectedHistoryItems import org.kiwix.kiwixmobile.core.history.viewmodel.Action.UserClickedDeleteSelectedHistoryItems
import org.kiwix.kiwixmobile.core.history.viewmodel.Action.UserClickedShowAllToggle import org.kiwix.kiwixmobile.core.history.viewmodel.Action.UserClickedShowAllToggle
import org.kiwix.kiwixmobile.core.history.viewmodel.State.Results
import org.kiwix.kiwixmobile.core.history.viewmodel.State.SelectionResults
import org.kiwix.kiwixmobile.core.history.viewmodel.effects.DeleteHistoryItems import org.kiwix.kiwixmobile.core.history.viewmodel.effects.DeleteHistoryItems
import org.kiwix.kiwixmobile.core.history.viewmodel.effects.OpenHistoryItem
import org.kiwix.kiwixmobile.core.history.viewmodel.effects.ShowDeleteHistoryDialog import org.kiwix.kiwixmobile.core.history.viewmodel.effects.ShowDeleteHistoryDialog
import org.kiwix.kiwixmobile.core.history.viewmodel.effects.UpdateAllHistoryPreference import org.kiwix.kiwixmobile.core.history.viewmodel.effects.UpdateAllHistoryPreference
import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer
@ -34,7 +32,7 @@ class HistoryViewModel @Inject constructor(
private val sharedPreferenceUtil: SharedPreferenceUtil private val sharedPreferenceUtil: SharedPreferenceUtil
) : ViewModel() { ) : ViewModel() {
val state = MutableLiveData<State>().apply { val state = MutableLiveData<State>().apply {
value = Results(emptyList(), sharedPreferenceUtil.showHistoryAllBooks, zimReaderContainer.id) value = State(emptyList(), sharedPreferenceUtil.showHistoryAllBooks, zimReaderContainer.id)
} }
val effects = PublishProcessor.create<SideEffect<*>>() val effects = PublishProcessor.create<SideEffect<*>>()
val actions = PublishProcessor.create<Action>() val actions = PublishProcessor.create<Action>()
@ -42,60 +40,36 @@ class HistoryViewModel @Inject constructor(
init { init {
compositeDisposable.addAll( compositeDisposable.addAll(
historyDao.history().subscribe { actions.offer(UpdateHistory(it)) }, viewStateReducer(),
sharedPreferenceUtil.showAllHistoryToggleSwitch.subscribe { historyDao.history().subscribeOn(Schedulers.io())
actions.offer(AllHistoryPreferenceChanged(it)) .subscribe({ actions.offer(UpdateHistory(it)) }, Throwable::printStackTrace)
},
viewStateReducer()
) )
} }
private fun viewStateReducer() = private fun viewStateReducer() =
actions.map { reduce(it, state.value!!) }.subscribe(state::postValue) actions.map { reduce(it, state.value!!) }
.subscribe(state::postValue, Throwable::printStackTrace)
private fun reduce(action: Action, state: State): State = private fun reduce(action: Action, state: State): State = when (action) {
when (action) { ExitHistory -> finishHistoryActivity(state)
ExitHistory -> finishHistoryActivity(state) ExitActionModeMenu -> deselectAllHistoryItems(state)
ExitActionModeMenu -> deselectAllHistoryItems(state) UserClickedConfirmDelete -> offerDeletionOfItems(state)
UserClickedConfirmDelete -> offerDeletionOfItems(state) UserClickedDeleteButton -> offerShowDeleteDialog(state)
UserClickedDeleteButton -> offerShowDeleteDialog(state) UserClickedDeleteSelectedHistoryItems -> offerShowDeleteDialog(state)
UserClickedDeleteSelectedHistoryItems -> offerShowDeleteDialog(state) is UserClickedShowAllToggle -> offerUpdateToShowAllToggle(action, state)
is OnItemClick -> handleItemClick(state, action) is OnItemClick -> handleItemClick(state, action)
is OnItemLongClick -> handleItemLongClick(state, action) is OnItemLongClick -> handleItemLongClick(state, action)
is UserClickedShowAllToggle -> offerUpdateToShowAllToggle(action, state) is Filter -> updateHistoryItemsBasedOnFilter(state, action)
is Filter -> updateHistoryItemsBasedOnFilter(state, action) is UpdateHistory -> updateHistoryList(state, action)
is UpdateHistory -> updateHistoryList(state, action) }
is AllHistoryPreferenceChanged -> changeShowHistoryToggle(state, action)
}
private fun updateHistoryItemsBasedOnFilter(state: State, action: Filter) = private fun updateHistoryItemsBasedOnFilter(state: State, action: Filter) =
when (state) { state.copy(searchTerm = action.searchTerm)
is Results -> state.copy(searchTerm = action.searchTerm)
is SelectionResults -> state.copy(searchTerm = action.searchTerm)
}
private fun changeShowHistoryToggle(
state: State,
action: AllHistoryPreferenceChanged
): State {
return when (state) {
is SelectionResults -> state
is Results -> state.copy(showAll = action.showAll)
}
}
private fun updateHistoryList( private fun updateHistoryList(
state: State, state: State,
action: UpdateHistory action: UpdateHistory
): State = when (state) { ): State = state.copy(historyItems = action.history)
is Results -> state.copy(historyItems = action.history)
is SelectionResults -> Results(
action.history,
state.showAll,
zimReaderContainer.id,
state.searchTerm
)
}
private fun offerUpdateToShowAllToggle( private fun offerUpdateToShowAllToggle(
action: UserClickedShowAllToggle, action: UserClickedShowAllToggle,
@ -107,33 +81,23 @@ class HistoryViewModel @Inject constructor(
action.isChecked action.isChecked
) )
) )
return when (state) { return state.copy(showAll = action.isChecked)
is Results -> state.copy(showAll = action.isChecked)
else -> state
}
} }
private fun handleItemLongClick( private fun handleItemLongClick(
state: State, state: State,
action: OnItemLongClick action: OnItemLongClick
): State { ): State = state.toggleSelectionOfItem(action.historyItem)
return when (state) {
is Results -> state.toggleSelectionOfItem(action.historyItem)
else -> state
}
}
private fun handleItemClick( private fun handleItemClick(
state: State, state: State,
action: OnItemClick action: OnItemClick
): State { ): State {
return when (state) { if (state.isInSelectionState) {
is Results -> { effects.offer(OpenHistoryItem(action.historyItem, zimReaderContainer))
effects.offer(OpenHistoryItem(action.historyItem, zimReaderContainer)) return state
state
}
is SelectionResults -> state.toggleSelectionOfItem(action.historyItem)
} }
return state.toggleSelectionOfItem(action.historyItem)
} }
private fun offerShowDeleteDialog(state: State): State { private fun offerShowDeleteDialog(state: State): State {
@ -142,31 +106,12 @@ class HistoryViewModel @Inject constructor(
} }
private fun offerDeletionOfItems(state: State): State { private fun offerDeletionOfItems(state: State): State {
return when (state) { effects.offer(DeleteHistoryItems(state, historyDao))
is Results -> { return state
effects.offer(DeleteHistoryItems(state.historyItems, historyDao))
state
}
is SelectionResults -> {
effects.offer(DeleteHistoryItems(state.selectedItems, historyDao))
state
}
}
} }
private fun deselectAllHistoryItems(state: State): State { private fun deselectAllHistoryItems(state: State): State =
return when (state) { state.copy(historyItems = state.historyItems.map { it.copy(isSelected = false) })
is SelectionResults -> {
Results(
state.historyItems.map { it.copy(isSelected = false) },
state.showAll,
state.currentZimId,
state.searchTerm
)
}
else -> state
}
}
private fun finishHistoryActivity(state: State): State { private fun finishHistoryActivity(state: State): State {
effects.offer(Finish) effects.offer(Finish)

View File

@ -25,13 +25,13 @@ import org.kiwix.kiwixmobile.core.history.adapter.HistoryListItem.HistoryItem
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
sealed class State( data class State(
open val historyItems: List<HistoryItem>, val historyItems: List<HistoryItem>,
open val showAll: Boolean, val showAll: Boolean,
open val currentZimId: String?, val currentZimId: String?,
open val searchTerm: String = "" val searchTerm: String = ""
) { ) {
val isInSelectionState = historyItems.any(HistoryItem::isSelected)
private val dateFormatter = SimpleDateFormat("d MMM yyyy", Locale.getDefault()) private val dateFormatter = SimpleDateFormat("d MMM yyyy", Locale.getDefault())
fun getHistoryListItems(): List<HistoryListItem> = fun getHistoryListItems(): List<HistoryListItem> =
@ -54,26 +54,6 @@ sealed class State(
isSelected = !isSelected isSelected = !isSelected
} else it } else it
} }
if (newList.none(HistoryItem::isSelected)) { return State(newList, showAll, currentZimId, searchTerm)
return Results(newList, showAll, currentZimId, searchTerm)
}
return SelectionResults(newList, showAll, currentZimId, searchTerm)
}
data class Results(
override val historyItems: List<HistoryItem>,
override val showAll: Boolean,
override val currentZimId: String?,
override val searchTerm: String = ""
) : State(historyItems, showAll, currentZimId, searchTerm)
data class SelectionResults(
override val historyItems: List<HistoryItem>,
override val showAll: Boolean,
override val currentZimId: String?,
override val searchTerm: String
) : State(historyItems, showAll, currentZimId, searchTerm) {
val selectedItems: List<HistoryItem> =
getHistoryListItems().filterIsInstance<HistoryItem>().filter(HistoryItem::isSelected)
} }
} }

View File

@ -22,12 +22,17 @@ import androidx.appcompat.app.AppCompatActivity
import org.kiwix.kiwixmobile.core.base.SideEffect import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.dao.HistoryDao import org.kiwix.kiwixmobile.core.dao.HistoryDao
import org.kiwix.kiwixmobile.core.history.adapter.HistoryListItem.HistoryItem import org.kiwix.kiwixmobile.core.history.adapter.HistoryListItem.HistoryItem
import org.kiwix.kiwixmobile.core.history.viewmodel.State
data class DeleteHistoryItems( data class DeleteHistoryItems(
private val itemsToDelete: List<HistoryItem>, private val state: State,
private val historyDao: HistoryDao private val historyDao: HistoryDao
) : SideEffect<Unit> { ) : SideEffect<Unit> {
override fun invokeWith(activity: AppCompatActivity) { override fun invokeWith(activity: AppCompatActivity) {
historyDao.deleteHistory(itemsToDelete) if (state.isInSelectionState) {
historyDao.deleteHistory(state.historyItems.filter(HistoryItem::isSelected))
} else {
historyDao.deleteHistory(state.historyItems)
}
} }
} }

View File

@ -61,11 +61,6 @@ public class SharedPreferenceUtil {
private SharedPreferences sharedPreferences; private SharedPreferences sharedPreferences;
private final PublishProcessor<String> prefStorages = PublishProcessor.create(); private final PublishProcessor<String> prefStorages = PublishProcessor.create();
public PublishProcessor<Boolean> getShowAllHistoryToggleSwitch() {
return showAllHistoryToggleSwitch;
}
private final PublishProcessor<Boolean> showAllHistoryToggleSwitch = PublishProcessor.create();
private final PublishProcessor<NightModeConfig.Mode> nightModes = PublishProcessor.create(); private final PublishProcessor<NightModeConfig.Mode> nightModes = PublishProcessor.create();
@Inject @Inject
@ -158,10 +153,6 @@ public class SharedPreferenceUtil {
return prefStorages.startWith(getPrefStorage()); return prefStorages.startWith(getPrefStorage());
} }
public Flowable<Boolean> getShowAllHistoryToggleSwitches() {
return showAllHistoryToggleSwitch.startWith(getShowHistoryAllBooks());
}
public void putPrefFullScreen(boolean fullScreen) { public void putPrefFullScreen(boolean fullScreen) {
sharedPreferences.edit().putBoolean(PREF_FULLSCREEN, fullScreen).apply(); sharedPreferences.edit().putBoolean(PREF_FULLSCREEN, fullScreen).apply();
} }
@ -186,7 +177,6 @@ public class SharedPreferenceUtil {
sharedPreferences.edit() sharedPreferences.edit()
.putBoolean(PREF_SHOW_HISTORY_ALL_BOOKS, prefShowHistoryAllBooks) .putBoolean(PREF_SHOW_HISTORY_ALL_BOOKS, prefShowHistoryAllBooks)
.apply(); .apply();
showAllHistoryToggleSwitch.offer(prefShowHistoryAllBooks);
} }
public boolean getShowBookmarksCurrentBook() { public boolean getShowBookmarksCurrentBook() {