#2154 more merging of viewmodels bookmark and history

This commit is contained in:
Frans-Lukas 2020-07-01 20:01:24 +02:00
parent 8679e390f2
commit 37418efb53
9 changed files with 77 additions and 44 deletions

View File

@ -1,11 +1,12 @@
package org.kiwix.kiwixmobile.core.page.bookmark
import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.di.components.CoreComponent
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.viewModel
import org.kiwix.kiwixmobile.core.page.PageActivity
import org.kiwix.kiwixmobile.core.page.adapter.PageAdapter
import org.kiwix.kiwixmobile.core.page.bookmark.viewmodel.BookmarkViewModel
import org.kiwix.kiwixmobile.core.page.adapter.PageDelegate.PageItemDelegate
import org.kiwix.kiwixmobile.core.page.bookmark.viewmodel.BookmarkViewModel
class BookmarksActivity : PageActivity() {
override val pageViewModel by lazy { viewModel<BookmarkViewModel>(viewModelFactory) }
@ -14,6 +15,10 @@ class BookmarksActivity : PageActivity() {
PageAdapter(PageItemDelegate(this))
}
override fun injection(coreComponent: CoreComponent) {
activityComponent.inject(this)
}
override val title: String by lazy { getString(R.string.bookmarks) }
override val noItemsString: String by lazy { getString(R.string.no_bookmarks) }
override val switchString: String by lazy { getString(R.string.bookmarks_from_current_book) }

View File

@ -31,13 +31,13 @@ import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import javax.inject.Inject
class BookmarkViewModel @Inject constructor(
override val pageDao: NewBookmarksDao,
bookmarksDao: NewBookmarksDao,
override val zimReaderContainer: ZimReaderContainer,
override val sharedPreferenceUtil: SharedPreferenceUtil
) : PageViewModel<BookmarkState>() {
) : PageViewModel<BookmarkState>(bookmarksDao) {
override fun initialState(): BookmarkState =
BookmarkState(emptyList(), sharedPreferenceUtil.showBookmarksAllBooks, zimReaderContainer.id)
BookmarkState(emptyList(), true, null)
init {
compositeDisposable.addAll(
@ -61,11 +61,9 @@ class BookmarkViewModel @Inject constructor(
return (state as BookmarkState).copy(showAll = action.isChecked)
}
override fun offerShowDeleteDialog(state: PageState): PageState {
effects.offer(ShowDeleteBookmarksDialog(effects, state as BookmarkState, pageDao))
return state
}
override fun deselectAllPages(state: PageState): PageState =
(state as BookmarkState).copy(pageItems = state.pageItems.map { it.copy(isSelected = false) })
override fun createDeletePageDialogEffect(state: PageState) =
ShowDeleteBookmarksDialog(effects, state as BookmarkState, pageDao)
}

View File

@ -21,7 +21,7 @@ package org.kiwix.kiwixmobile.core.page.bookmark.viewmodel.effects
import androidx.appcompat.app.AppCompatActivity
import io.reactivex.processors.PublishProcessor
import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.dao.NewBookmarksDao
import org.kiwix.kiwixmobile.core.dao.PageDao
import org.kiwix.kiwixmobile.core.page.bookmark.BookmarksActivity
import org.kiwix.kiwixmobile.core.page.bookmark.viewmodel.BookmarkState
import org.kiwix.kiwixmobile.core.page.viewmodel.effects.DeletePageItems
@ -33,7 +33,7 @@ import javax.inject.Inject
data class ShowDeleteBookmarksDialog(
private val effects: PublishProcessor<SideEffect<*>>,
private val state: BookmarkState,
private val bookmarksDao: NewBookmarksDao
private val bookmarksDao: PageDao
) : SideEffect<Unit> {
@Inject lateinit var dialogShower: DialogShower
override fun invokeWith(activity: AppCompatActivity) {

View File

@ -1,6 +1,7 @@
package org.kiwix.kiwixmobile.core.page.history
import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.di.components.CoreComponent
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.viewModel
import org.kiwix.kiwixmobile.core.page.PageActivity
import org.kiwix.kiwixmobile.core.page.adapter.PageAdapter
@ -17,6 +18,10 @@ class HistoryActivity : PageActivity() {
PageAdapter(PageItemDelegate(this), HistoryDateDelegate())
}
override fun injection(coreComponent: CoreComponent) {
activityComponent.inject(this)
}
override val noItemsString: String by lazy { getString(R.string.no_history) }
override val switchString: String by lazy { getString(R.string.history_from_current_book) }
override val title: String by lazy { getString(R.string.history) }

View File

@ -18,7 +18,6 @@
package org.kiwix.kiwixmobile.core.page.history.viewmodel
import io.reactivex.schedulers.Schedulers
import org.kiwix.kiwixmobile.core.dao.HistoryDao
import org.kiwix.kiwixmobile.core.page.history.adapter.HistoryListItem.HistoryItem
import org.kiwix.kiwixmobile.core.page.history.viewmodel.effects.ShowDeleteHistoryDialog
@ -31,21 +30,13 @@ import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import javax.inject.Inject
class HistoryViewModel @Inject constructor(
override val pageDao: HistoryDao,
override val zimReaderContainer: ZimReaderContainer,
override val sharedPreferenceUtil: SharedPreferenceUtil
) : PageViewModel<HistoryState>() {
override val sharedPreferenceUtil: SharedPreferenceUtil,
historyDao: HistoryDao
) : PageViewModel<HistoryState>(historyDao) {
override fun initialState(): HistoryState =
HistoryState(emptyList(), sharedPreferenceUtil.showHistoryAllBooks, zimReaderContainer.id)
init {
compositeDisposable.addAll(
viewStateReducer(),
pageDao.pages().subscribeOn(Schedulers.io())
.subscribe({ actions.offer(Action.UpdatePages(it)) }, Throwable::printStackTrace)
)
}
HistoryState(emptyList(), true, null)
override fun updatePagesBasedOnFilter(state: PageState, action: Action.Filter): PageState =
(state as HistoryState).copy(searchTerm = action.searchTerm)
@ -61,10 +52,8 @@ class HistoryViewModel @Inject constructor(
return (state as HistoryState).copy(showAll = action.isChecked)
}
override fun offerShowDeleteDialog(state: PageState): PageState {
effects.offer(ShowDeleteHistoryDialog(effects, state as HistoryState, pageDao))
return state
}
override fun createDeletePageDialogEffect(state: PageState) =
ShowDeleteHistoryDialog(effects, state as HistoryState, pageDao)
override fun deselectAllPages(state: PageState): PageState =
(state as HistoryState).copy(pageItems = state.pageItems.map { it.copy(isSelected = false) })

View File

@ -21,7 +21,7 @@ package org.kiwix.kiwixmobile.core.page.history.viewmodel.effects
import androidx.appcompat.app.AppCompatActivity
import io.reactivex.processors.PublishProcessor
import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.dao.HistoryDao
import org.kiwix.kiwixmobile.core.dao.PageDao
import org.kiwix.kiwixmobile.core.page.history.HistoryActivity
import org.kiwix.kiwixmobile.core.page.history.viewmodel.HistoryState
import org.kiwix.kiwixmobile.core.page.viewmodel.effects.DeletePageItems
@ -33,7 +33,7 @@ import javax.inject.Inject
data class ShowDeleteHistoryDialog(
private val effects: PublishProcessor<SideEffect<*>>,
private val state: HistoryState,
private val historyDao: HistoryDao
private val historyDao: PageDao
) : SideEffect<Unit> {
@Inject lateinit var dialogShower: DialogShower
override fun invokeWith(activity: AppCompatActivity) {

View File

@ -23,6 +23,7 @@ import androidx.lifecycle.ViewModel
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.processors.PublishProcessor
import io.reactivex.schedulers.Schedulers
import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.dao.PageDao
import org.kiwix.kiwixmobile.core.page.viewmodel.Action.Exit
@ -39,17 +40,24 @@ import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer
import org.kiwix.kiwixmobile.core.search.viewmodel.effects.Finish
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
abstract class PageViewModel<out T : PageState> : ViewModel() {
abstract class PageViewModel<out T : PageState>(val pageDao: PageDao) : ViewModel() {
abstract val zimReaderContainer: ZimReaderContainer
abstract val sharedPreferenceUtil: SharedPreferenceUtil
abstract val pageDao: PageDao
val state = MutableLiveData<PageState>().apply {
value = initialState()
}
val compositeDisposable = CompositeDisposable()
val effects = PublishProcessor.create<SideEffect<*>>()
val actions = PublishProcessor.create<Action>()
val compositeDisposable = CompositeDisposable()
init {
compositeDisposable.addAll(
viewStateReducer(),
pageDao.pages().subscribeOn(Schedulers.io())
.subscribe({ actions.offer(Action.UpdatePages(it)) }, Throwable::printStackTrace)
)
}
fun viewStateReducer(): Disposable =
actions.map { reduce(it, state.value!!) }
@ -77,6 +85,11 @@ abstract class PageViewModel<out T : PageState> : ViewModel() {
state: PageState
): PageState
private fun offerShowDeleteDialog(state: PageState): PageState {
effects.offer(createDeletePageDialogEffect(state))
return state
}
private fun handleItemLongClick(state: PageState, action: OnItemLongClick): PageState =
state.toggleSelectionOfItem(action.page)
@ -88,8 +101,6 @@ abstract class PageViewModel<out T : PageState> : ViewModel() {
return state
}
abstract fun offerShowDeleteDialog(state: PageState): PageState
abstract fun deselectAllPages(state: PageState): PageState
private fun finishActivity(state: PageState): PageState {
@ -101,4 +112,6 @@ abstract class PageViewModel<out T : PageState> : ViewModel() {
compositeDisposable.clear()
super.onCleared()
}
abstract fun createDeletePageDialogEffect(state: PageState): SideEffect<*>
}

View File

@ -84,14 +84,26 @@ internal class HistoryViewModelTest {
@Test
internal fun `UserClickedDeleteButton offers ShowDeleteHistoryDialog`() {
viewModel.effects.test().also { viewModel.actions.offer(UserClickedDeleteButton) }
.assertValue(ShowDeleteHistoryDialog(viewModel.effects, historyState(), historyDao))
.assertValue(
ShowDeleteHistoryDialog(
viewModel.effects,
historyState(),
historyDao
)
)
viewModel.state.test().assertValue(historyState())
}
@Test
internal fun `UserClickedDeleteSelectedHistoryItems offers ShowDeleteHistoryDialog`() {
viewModel.effects.test().also { viewModel.actions.offer(UserClickedDeleteSelectedPages) }
.assertValue(ShowDeleteHistoryDialog(viewModel.effects, historyState(), historyDao))
.assertValue(
ShowDeleteHistoryDialog(
viewModel.effects,
historyState(),
historyDao
)
)
viewModel.state.test().assertValue(historyState())
}

View File

@ -24,7 +24,12 @@ internal class ShowDeleteHistoryDialogTest {
@Test
fun `invoke with shows dialog that offers ConfirmDelete action`() {
val showDeleteHistoryDialog = ShowDeleteHistoryDialog(effects, historyState(), historyDao)
val showDeleteHistoryDialog =
ShowDeleteHistoryDialog(
effects,
historyState(),
historyDao
)
mockkActivityInjection(showDeleteHistoryDialog)
val lambdaSlot = slot<() -> Unit>()
showDeleteHistoryDialog.invokeWith(activity)
@ -35,11 +40,12 @@ internal class ShowDeleteHistoryDialogTest {
@Test
fun `invoke with selected item shows dialog with delete selected items title`() {
val showDeleteHistoryDialog = ShowDeleteHistoryDialog(
effects,
historyState(listOf(historyItem(isSelected = true))),
historyDao
)
val showDeleteHistoryDialog =
ShowDeleteHistoryDialog(
effects,
historyState(listOf(historyItem(isSelected = true))),
historyDao
)
mockkActivityInjection(showDeleteHistoryDialog)
showDeleteHistoryDialog.invokeWith(activity)
verify { dialogShower.show(DeleteSelectedHistory, any()) }
@ -47,7 +53,12 @@ internal class ShowDeleteHistoryDialogTest {
@Test
fun `invoke with no selected items shows dialog with delete all items title`() {
val showDeleteHistoryDialog = ShowDeleteHistoryDialog(effects, historyState(), historyDao)
val showDeleteHistoryDialog =
ShowDeleteHistoryDialog(
effects,
historyState(),
historyDao
)
mockkActivityInjection(showDeleteHistoryDialog)
showDeleteHistoryDialog.invokeWith(activity)
verify { dialogShower.show(DeleteAllHistory, any()) }