From 51998e8f207e02ea3571f7fa1961785e127f5a71 Mon Sep 17 00:00:00 2001 From: Sean Mac Gillicuddy Date: Tue, 2 Jul 2019 16:31:29 +0100 Subject: [PATCH 1/3] #1253 readd action mode for sharing and deleting zim files on disk --- app/objectbox-models/default.json.bak | 2 +- .../di/components/ActivityComponent.kt | 3 + .../extensions/ActivityExtensions.kt | 43 +++++++ .../kiwix/kiwixmobile/main/MainActivity.java | 6 +- .../zim_manager/ZimManageViewModel.kt | 112 +++++++++++++++++- .../fileselect_view/FileSelectListState.kt | 37 ++++++ .../fileselect_view/ZimFileSelectFragment.kt | 102 +++++++--------- .../adapter/BookOnDiskDelegate.kt | 19 ++- .../adapter/BooksOnDiskAdapter.kt | 1 - .../adapter/BooksOnDiskListItem.kt | 1 + .../adapter/BooksOnDiskViewHolder.kt | 46 ++++--- .../fileselect_view/effects/DeleteFiles.kt | 42 +++++++ .../fileselect_view/effects/None.kt | 8 ++ .../fileselect_view/effects/OpenFile.kt | 38 ++++++ .../fileselect_view/effects/ShareFiles.kt | 42 +++++++ .../fileselect_view/effects/SideEffect.kt | 28 +++++ .../effects/StartMultiSelection.kt | 27 +++++ .../library_view/LibraryFragment.kt | 2 +- .../adapter/base/BaseDelegateAdapter.kt | 10 +- app/src/main/res/layout/item_book.xml | 16 ++- .../zim_manager/ZimManageViewModelTest.kt | 2 +- 21 files changed, 495 insertions(+), 92 deletions(-) create mode 100644 app/src/main/java/org/kiwix/kiwixmobile/extensions/ActivityExtensions.kt create mode 100644 app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/FileSelectListState.kt create mode 100644 app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/DeleteFiles.kt create mode 100644 app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/None.kt create mode 100644 app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/OpenFile.kt create mode 100644 app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/ShareFiles.kt create mode 100644 app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/SideEffect.kt create mode 100644 app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/StartMultiSelection.kt diff --git a/app/objectbox-models/default.json.bak b/app/objectbox-models/default.json.bak index d51d2ba302..757048b9fe 100644 --- a/app/objectbox-models/default.json.bak +++ b/app/objectbox-models/default.json.bak @@ -218,7 +218,7 @@ }, { "id": "2:6862771806221961183", - "name": "zimID" + "name": "zimId" }, { "id": "3:4312769031500860715", diff --git a/app/src/main/java/org/kiwix/kiwixmobile/di/components/ActivityComponent.kt b/app/src/main/java/org/kiwix/kiwixmobile/di/components/ActivityComponent.kt index 70350b1597..388c5397e0 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/di/components/ActivityComponent.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/di/components/ActivityComponent.kt @@ -23,6 +23,7 @@ import dagger.Subcomponent import org.kiwix.kiwixmobile.di.modules.ActivityModule import org.kiwix.kiwixmobile.downloader.DownloadFragment import org.kiwix.kiwixmobile.zim_manager.fileselect_view.ZimFileSelectFragment +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects.DeleteFiles import org.kiwix.kiwixmobile.zim_manager.library_view.LibraryFragment @Subcomponent(modules = [ActivityModule::class]) @@ -33,6 +34,8 @@ interface ActivityComponent { fun inject(zimFileSelectFragment: ZimFileSelectFragment) + fun inject(deleteFiles: DeleteFiles) + @Subcomponent.Builder interface Builder { diff --git a/app/src/main/java/org/kiwix/kiwixmobile/extensions/ActivityExtensions.kt b/app/src/main/java/org/kiwix/kiwixmobile/extensions/ActivityExtensions.kt new file mode 100644 index 0000000000..19f27325b6 --- /dev/null +++ b/app/src/main/java/org/kiwix/kiwixmobile/extensions/ActivityExtensions.kt @@ -0,0 +1,43 @@ +package org.kiwix.kiwixmobile.extensions + +import android.app.Activity +import android.view.ActionMode +import android.view.ActionMode.Callback +import android.view.Menu +import android.view.MenuItem + +fun Activity.startActionMode( + menuId: Int, + idsToClickActions: Map Any>, + onDestroyAction: () -> Unit +): ActionMode? { + return startActionMode(object : Callback { + override fun onActionItemClicked( + mode: ActionMode, + item: MenuItem + ) = idsToClickActions[item.itemId]?.let { + it() + mode.finish() + true + } ?: false + + override fun onCreateActionMode( + mode: ActionMode, + menu: Menu? + ): Boolean { + mode.getMenuInflater() + .inflate(menuId, menu) + return true + } + + override fun onPrepareActionMode( + mode: ActionMode?, + menu: Menu? + ) = false + + override fun onDestroyActionMode(mode: ActionMode?) { + onDestroyAction() + } + + }) +} diff --git a/app/src/main/java/org/kiwix/kiwixmobile/main/MainActivity.java b/app/src/main/java/org/kiwix/kiwixmobile/main/MainActivity.java index ab66be3964..e1e46b6d14 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/main/MainActivity.java +++ b/app/src/main/java/org/kiwix/kiwixmobile/main/MainActivity.java @@ -37,7 +37,6 @@ import android.os.Build; import android.os.Bundle; import android.os.CountDownTimer; -import android.os.Environment; import android.os.Handler; import android.provider.Settings; import android.text.SpannableString; @@ -100,11 +99,9 @@ import org.kiwix.kiwixmobile.bookmark.BookmarkItem; import org.kiwix.kiwixmobile.bookmark.BookmarksActivity; import org.kiwix.kiwixmobile.data.ZimContentProvider; -import org.kiwix.kiwixmobile.data.local.entity.Bookmark; import org.kiwix.kiwixmobile.help.HelpActivity; import org.kiwix.kiwixmobile.history.HistoryActivity; import org.kiwix.kiwixmobile.history.HistoryListItem; -import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity; import org.kiwix.kiwixmobile.search.SearchActivity; import org.kiwix.kiwixmobile.settings.KiwixSettingsActivity; import org.kiwix.kiwixmobile.utils.DimenUtils; @@ -377,6 +374,7 @@ public void onCreate(Bundle savedInstanceState) { open(bookOnDiskItem); return Unit.INSTANCE; }, + null, null), BookOnDiskDelegate.LanguageDelegate.INSTANCE ); @@ -2105,7 +2103,7 @@ public void open(BooksOnDiskListItem.BookOnDisk bookOnDisk) { @Override public void addBooks(List books) { - booksAdapter.setItemList(books); + booksAdapter.setItems(books); } private void searchFiles() { diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/ZimManageViewModel.kt b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/ZimManageViewModel.kt index e4ed2c862a..88a77ff755 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/ZimManageViewModel.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/ZimManageViewModel.kt @@ -52,9 +52,24 @@ import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.CanWrite4G import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.CannotWrite4GbFile import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.NotEnoughSpaceFor4GbFile import org.kiwix.kiwixmobile.zim_manager.NetworkState.CONNECTED +import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.MultiModeFinished +import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestDeleteMultiSelection +import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestMultiSelection +import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestOpen +import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestSelect +import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestShareMultiSelection +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.FileSelectListState +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.SelectionMode.MULTI +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.SelectionMode.NORMAL import org.kiwix.kiwixmobile.zim_manager.fileselect_view.StorageObserver import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskListItem import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects.DeleteFiles +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects.None +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects.OpenFile +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects.ShareFiles +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects.SideEffect +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects.StartMultiSelection import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem.BookItem import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem.DividerItem @@ -79,16 +94,26 @@ class ZimManageViewModel @Inject constructor( private val defaultLanguageProvider: DefaultLanguageProvider, private val dataSource: DataSource ) : ViewModel() { + sealed class FileSelectActions { + data class RequestOpen(val bookOnDisk: BookOnDisk) : FileSelectActions() + data class RequestSelect(val bookOnDisk: BookOnDisk) : FileSelectActions() + data class RequestMultiSelection(val bookOnDisk: BookOnDisk) : FileSelectActions() + object RequestDeleteMultiSelection : FileSelectActions() + object RequestShareMultiSelection : FileSelectActions() + object MultiModeFinished : FileSelectActions() + } + val sideEffects = PublishProcessor.create>() val libraryItems: MutableLiveData> = MutableLiveData() val downloadItems: MutableLiveData> = MutableLiveData() - val bookItems: MutableLiveData> = MutableLiveData() + val fileSelectListStates: MutableLiveData = MutableLiveData() val deviceListIsRefreshing = MutableLiveData() val libraryListIsRefreshing = MutableLiveData() val networkStates = MutableLiveData() val languageItems = MutableLiveData>() val requestFileSystemCheck = PublishProcessor.create() + val fileSelectActions = PublishProcessor.create() val requestDownloadLibrary = BehaviorProcessor.createDefault(Unit) val requestFiltering = BehaviorProcessor.createDefault("") val requestLanguagesDialog = PublishProcessor.create() @@ -127,8 +152,72 @@ class ZimManageViewModel @Inject constructor( updateLanguagesInDao(networkLibrary, languages), updateNetworkStates(), updateLanguageItemsForDialog(languages), - requestsAndConnectivtyChangesToLibraryRequests(networkLibrary) + requestsAndConnectivtyChangesToLibraryRequests(networkLibrary), + fileSelectActions() + ) + } + + private fun fileSelectActions() = fileSelectActions.subscribe({ + sideEffects.offer( + when (it) { + is RequestOpen -> OpenFile(it.bookOnDisk) + is RequestMultiSelection -> startMultiSelectionAndSelectBook(it.bookOnDisk) + RequestDeleteMultiSelection -> DeleteFiles(selectionsFromState()) + RequestShareMultiSelection -> ShareFiles(selectionsFromState()) + MultiModeFinished -> noSideEffectAndClearSelectionState() + is RequestSelect -> noSideEffectSelectBook(it.bookOnDisk) + } ) + }, Throwable::printStackTrace) + + private fun startMultiSelectionAndSelectBook( + bookOnDisk: BookOnDisk + ): StartMultiSelection { + fileSelectListStates.value?.let { + fileSelectListStates.postValue( + it.copy( + bookOnDiskListItems = selectBook(it, bookOnDisk), + selectionMode = MULTI + ) + ) + } + return StartMultiSelection(bookOnDisk, fileSelectActions) + } + + private fun selectBook( + it: FileSelectListState, + bookOnDisk: BookOnDisk + ): List { + return it.bookOnDiskListItems.map { listItem -> + if (listItem.id == bookOnDisk.id) listItem.apply { isSelected = !isSelected } + else listItem + } + } + + private fun noSideEffectSelectBook(bookOnDisk: BookOnDisk): SideEffect { + fileSelectListStates.value?.let { + fileSelectListStates.postValue( + it.copy(bookOnDiskListItems = it.bookOnDiskListItems.map { listItem -> + if (listItem.id == bookOnDisk.id) listItem.apply { isSelected = !isSelected } + else listItem + }) + ) + } + return None + } + + private fun selectionsFromState() = fileSelectListStates.value?.selectedBooks ?: emptyList() + + private fun noSideEffectAndClearSelectionState(): SideEffect { + fileSelectListStates.value?.let { + fileSelectListStates.postValue( + it.copy( + bookOnDiskListItems = it.bookOnDiskListItems.map { it.apply { isSelected = false } }, + selectionMode = NORMAL + ) + ) + } + return None } private fun requestsAndConnectivtyChangesToLibraryRequests(library: PublishProcessor) = @@ -411,10 +500,27 @@ class ZimManageViewModel @Inject constructor( private fun updateBookItems() = dataSource.booksOnDiskAsListItems() .subscribe( - bookItems::postValue, + { newList -> + fileSelectListStates.postValue( + fileSelectListStates.value?.let { inheritSelections(it, newList) } + ?: FileSelectListState(newList) + ) + }, Throwable::printStackTrace ) + private fun inheritSelections( + oldState: FileSelectListState, + newList: MutableList + ): FileSelectListState { + return oldState.copy( + bookOnDiskListItems = newList.map { newBookOnDisk -> + val firstOrNull = + oldState.bookOnDiskListItems.firstOrNull { oldBookOnDisk -> oldBookOnDisk.id == newBookOnDisk.id } + newBookOnDisk.apply { isSelected = firstOrNull?.isSelected ?: false } + }) + } + private fun removeCompletedDownloadsFromDb(downloadStatuses: Flowable>) = downloadStatuses .observeOn(Schedulers.io()) diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/FileSelectListState.kt b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/FileSelectListState.kt new file mode 100644 index 0000000000..df45efb885 --- /dev/null +++ b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/FileSelectListState.kt @@ -0,0 +1,37 @@ +/* + * Kiwix Android + * Copyright (C) 2018 Kiwix + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.kiwix.kiwixmobile.zim_manager.fileselect_view + +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.SelectionMode.NORMAL +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskListItem +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk + +data class FileSelectListState( + val bookOnDiskListItems: List, + val selectionMode: SelectionMode = NORMAL +) { + val selectedBooks by lazy { + bookOnDiskListItems.filter { it.isSelected }.filterIsInstance(BookOnDisk::class.java) + } + +} + +enum class SelectionMode { + NORMAL, + MULTI +} diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/ZimFileSelectFragment.kt b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/ZimFileSelectFragment.kt index d30b9822fa..854f3a55c6 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/ZimFileSelectFragment.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/ZimFileSelectFragment.kt @@ -21,8 +21,8 @@ package org.kiwix.kiwixmobile.zim_manager.fileselect_view import android.Manifest import android.content.pm.PackageManager -import android.os.Build import android.os.Bundle +import android.view.ActionMode import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -32,49 +32,49 @@ import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import io.reactivex.disposables.CompositeDisposable import kotlinx.android.synthetic.main.zim_list.file_management_no_files import kotlinx.android.synthetic.main.zim_list.zim_swiperefresh import kotlinx.android.synthetic.main.zim_list.zimfilelist import org.kiwix.kiwixmobile.R -import org.kiwix.kiwixmobile.R.string import org.kiwix.kiwixmobile.base.BaseFragment -import org.kiwix.kiwixmobile.data.ZimContentProvider -import org.kiwix.kiwixmobile.database.newdb.dao.NewBookDao import org.kiwix.kiwixmobile.di.components.ActivityComponent import org.kiwix.kiwixmobile.extensions.toast -import org.kiwix.kiwixmobile.utils.BookUtils import org.kiwix.kiwixmobile.utils.Constants.REQUEST_STORAGE_PERMISSION -import org.kiwix.kiwixmobile.utils.DialogShower -import org.kiwix.kiwixmobile.utils.KiwixDialog.DeleteZim import org.kiwix.kiwixmobile.utils.LanguageUtils import org.kiwix.kiwixmobile.utils.SharedPreferenceUtil -import org.kiwix.kiwixmobile.utils.files.FileUtils -import org.kiwix.kiwixmobile.zim_manager.ZimManageActivity import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel +import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions +import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestMultiSelection +import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestOpen +import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestSelect import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BookOnDiskDelegate.BookDelegate import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BookOnDiskDelegate.LanguageDelegate import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskAdapter -import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk import javax.inject.Inject class ZimFileSelectFragment : BaseFragment() { @Inject lateinit var sharedPreferenceUtil: SharedPreferenceUtil - @Inject lateinit var bookDao: NewBookDao - @Inject lateinit var dialogShower: DialogShower @Inject lateinit var viewModelFactory: ViewModelProvider.Factory - @Inject lateinit var bookUtils: BookUtils + + private var actionMode: ActionMode? = null + val disposable = CompositeDisposable() private val zimManageViewModel: ZimManageViewModel by lazy { ViewModelProviders.of(activity!!, viewModelFactory) .get(ZimManageViewModel::class.java) } + private val bookDelegate: BookDelegate by lazy { + BookDelegate(sharedPreferenceUtil, + { offerAction(RequestOpen(it)) }, + { offerAction(RequestMultiSelection(it)) }, + { offerAction(RequestSelect(it)) }) + } + private val booksOnDiskAdapter: BooksOnDiskAdapter by lazy { - BooksOnDiskAdapter( - BookDelegate(sharedPreferenceUtil, this::openOnClick, this::deleteOnLongClick), - LanguageDelegate - ) + BooksOnDiskAdapter(bookDelegate, LanguageDelegate) } override fun inject(activityComponent: ActivityComponent) { @@ -101,31 +101,51 @@ class ZimFileSelectFragment : BaseFragment() { layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false) setHasFixedSize(true) } - zimManageViewModel.bookItems.observe(this, Observer { - booksOnDiskAdapter.itemList = it!! - checkEmpty(it) - }) + zimManageViewModel.fileSelectListStates.observe(this, Observer { render(it) }) + disposable.add(sideEffects()) zimManageViewModel.deviceListIsRefreshing.observe(this, Observer { zim_swiperefresh.isRefreshing = it!! }) } + private fun sideEffects() = zimManageViewModel.sideEffects.subscribe( + { + val effectResult = it.invokeWith(activity!!) + if (effectResult is ActionMode) { + actionMode = effectResult + } + }, Throwable::printStackTrace + ) + + private fun render(state: FileSelectListState) { + val items = state.bookOnDiskListItems + bookDelegate.selectionMode = state.selectionMode + booksOnDiskAdapter.items = items + actionMode?.title = String.format("%d", state.selectedBooks.size) + file_management_no_files.visibility = if (items.isEmpty()) View.VISIBLE else View.GONE + } + override fun onResume() { super.onResume() checkPermissions() } - private fun checkEmpty(books: List) { - file_management_no_files.visibility = - if (books.isEmpty()) View.VISIBLE - else View.GONE + override fun onDestroy() { + super.onDestroy() + disposable.clear() + } + + private fun offerAction( + action: FileSelectActions + ) { + zimManageViewModel.fileSelectActions.offer(action) } private fun checkPermissions() { if (ContextCompat.checkSelfPermission( activity!!, Manifest.permission.WRITE_EXTERNAL_STORAGE - ) != PackageManager.PERMISSION_GRANTED && Build.VERSION.SDK_INT > 18 + ) != PackageManager.PERMISSION_GRANTED ) { context.toast(R.string.request_storage) requestPermissions( @@ -140,34 +160,4 @@ class ZimFileSelectFragment : BaseFragment() { private fun requestFileSystemCheck() { zimManageViewModel.requestFileSystemCheck.onNext(Unit) } - - private fun openOnClick(it: BookOnDisk) { - val file = it.file - ZimContentProvider.canIterate = false - if (!file.canRead()) { - context.toast(string.error_filenotfound) - } else { - (activity as ZimManageActivity).finishResult(file.path) - } - } - - private fun deleteOnLongClick(it: BookOnDisk) { - dialogShower.show(DeleteZim, { - if (deleteSpecificZimFile(it)) { - context.toast(string.delete_specific_zim_toast) - } else { - context.toast(string.delete_zim_failed) - } - }) - } - - private fun deleteSpecificZimFile(book: BookOnDisk): Boolean { - val file = book.file - FileUtils.deleteZimFile(file.path) - if (file.exists()) { - return false - } - bookDao.delete(book.databaseId!!) - return true - } } diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BookOnDiskDelegate.kt b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BookOnDiskDelegate.kt index 27e918e6e9..f1a1fe3a6c 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BookOnDiskDelegate.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BookOnDiskDelegate.kt @@ -18,11 +18,13 @@ package org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView.ViewHolder import org.kiwix.kiwixmobile.R import org.kiwix.kiwixmobile.extensions.inflate import org.kiwix.kiwixmobile.utils.SharedPreferenceUtil +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.SelectionMode +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.SelectionMode.NORMAL import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BookOnDiskViewHolder.BookViewHolder -import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BookOnDiskViewHolder.LanguageItemViewHolder import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.LanguageItem import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.base.AbsDelegateAdapter @@ -33,17 +35,28 @@ sealed class BookOnDiskDelegate Unit, - val longClickAction: ((BookOnDisk) -> Unit)? = null + val longClickAction: ((BookOnDisk) -> Unit)? = null, + val multiSelectAction: ((BookOnDisk) -> Unit)? = null ) : BookOnDiskDelegate() { override val itemClass = BookOnDisk::class.java + var selectionMode: SelectionMode = NORMAL + + override fun bind( + viewHolder: ViewHolder, + itemToBind: BooksOnDiskListItem + ) { + (viewHolder as BookOnDiskViewHolder.BookViewHolder).bind((itemToBind as BookOnDisk), selectionMode) + } + override fun createViewHolder(parent: ViewGroup) = BookViewHolder( parent.inflate(R.layout.item_book, false), sharedPreferenceUtil, clickAction, - longClickAction + longClickAction, + multiSelectAction ) } diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BooksOnDiskAdapter.kt b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BooksOnDiskAdapter.kt index 28cb6997ba..6cc49ca33d 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BooksOnDiskAdapter.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BooksOnDiskAdapter.kt @@ -1,7 +1,6 @@ package org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.base.AdapterDelegate -import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.base.AdapterDelegateManager import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.base.BaseDelegateAdapter class BooksOnDiskAdapter( diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BooksOnDiskListItem.kt b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BooksOnDiskListItem.kt index 5a19b774f8..bd4bb25020 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BooksOnDiskListItem.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BooksOnDiskListItem.kt @@ -6,6 +6,7 @@ import java.io.File import java.util.Locale sealed class BooksOnDiskListItem { + var isSelected: Boolean = false abstract val id: Long data class LanguageItem constructor( diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BooksOnDiskViewHolder.kt b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BooksOnDiskViewHolder.kt index fe91812d30..70e6ebab80 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BooksOnDiskViewHolder.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BooksOnDiskViewHolder.kt @@ -3,6 +3,7 @@ package org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter import android.graphics.ColorMatrixColorFilter import android.view.View import kotlinx.android.synthetic.main.header_language.header_language +import kotlinx.android.synthetic.main.item_book.itemBookCheckbox import kotlinx.android.synthetic.main.item_book.item_book_article_count import kotlinx.android.synthetic.main.item_book.item_book_date import kotlinx.android.synthetic.main.item_book.item_book_description @@ -17,6 +18,9 @@ import org.kiwix.kiwixmobile.main.KiwixWebView import org.kiwix.kiwixmobile.utils.SharedPreferenceUtil import org.kiwix.kiwixmobile.zim_manager.KiloByte import org.kiwix.kiwixmobile.zim_manager.fileselect_view.ArticleCount +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.SelectionMode +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.SelectionMode.MULTI +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.SelectionMode.NORMAL import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.LanguageItem import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.base.BaseViewHolder @@ -28,10 +32,17 @@ sealed class BookOnDiskViewHolder(containerView: View) containerView: View, private val sharedPreferenceUtil: SharedPreferenceUtil, private val clickAction: (BookOnDisk) -> Unit, - private val longClickAction: ((BookOnDisk) -> Unit)? + private val longClickAction: ((BookOnDisk) -> Unit)?, + private val multiSelectAction: ((BookOnDisk) -> Unit)? ) : BookOnDiskViewHolder(containerView) { override fun bind(item: BookOnDisk) { + } + + fun bind( + item: BookOnDisk, + selectionMode: SelectionMode + ) { val book = item.book item_book_title.text = book.getTitle() item_book_date.text = book.getDate() @@ -59,24 +70,29 @@ sealed class BookOnDiskViewHolder(containerView: View) item_book_label_video.visibility = View.GONE } - containerView.setOnClickListener { - clickAction.invoke(item) - } - containerView.setOnLongClickListener { - longClickAction?.invoke(item) - return@setOnLongClickListener true + when (selectionMode) { + MULTI -> { + itemBookCheckbox.visibility = View.VISIBLE + containerView.setOnClickListener { multiSelectAction?.invoke(item) } + containerView.setOnLongClickListener(null) + } + NORMAL -> { + itemBookCheckbox.visibility = View.GONE + containerView.setOnClickListener { clickAction.invoke(item) } + containerView.setOnLongClickListener { + longClickAction?.invoke(item) + return@setOnLongClickListener true + } + } } } } +} - class LanguageItemViewHolder(containerView: View) : - BookOnDiskViewHolder(containerView) { +class LanguageItemViewHolder(containerView: View) : + BookOnDiskViewHolder(containerView) { - override fun bind(item: LanguageItem) { - header_language.text = item.text - } + override fun bind(item: LanguageItem) { + header_language.text = item.text } - } - - diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/DeleteFiles.kt b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/DeleteFiles.kt new file mode 100644 index 0000000000..2e87df0aec --- /dev/null +++ b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/DeleteFiles.kt @@ -0,0 +1,42 @@ +package org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects + +import android.app.Activity +import org.kiwix.kiwixmobile.R.string +import org.kiwix.kiwixmobile.database.newdb.dao.NewBookDao +import org.kiwix.kiwixmobile.extensions.toast +import org.kiwix.kiwixmobile.utils.DialogShower +import org.kiwix.kiwixmobile.utils.KiwixDialog.DeleteZim +import org.kiwix.kiwixmobile.utils.files.FileUtils +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk +import javax.inject.Inject + +class DeleteFiles(val booksOnDiskListItem: List) : + SideEffect { + + @Inject lateinit var dialogShower: DialogShower + @Inject lateinit var newBookDao: NewBookDao + + override fun invokeWith(activity: Activity) { + activityComponent(activity).inject(this) + booksOnDiskListItem.forEach { + dialogShower.show(DeleteZim, { + if (deleteSpecificZimFile(it)) { + activity.toast(string.delete_specific_zim_toast) + } else { + activity.toast(string.delete_zim_failed) + } + }) + } + } + + private fun deleteSpecificZimFile(book: BookOnDisk): Boolean { + val file = book.file + FileUtils.deleteZimFile(file.path) + if (file.exists()) { + return false + } + newBookDao.delete(book.databaseId!!) + return true + } + +} diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/None.kt b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/None.kt new file mode 100644 index 0000000000..3d38f04c32 --- /dev/null +++ b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/None.kt @@ -0,0 +1,8 @@ +package org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects + +import android.app.Activity + +object None : SideEffect { + override fun invokeWith(activity: Activity) { + } +} diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/OpenFile.kt b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/OpenFile.kt new file mode 100644 index 0000000000..361f6ecf6c --- /dev/null +++ b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/OpenFile.kt @@ -0,0 +1,38 @@ +/* + * Kiwix Android + * Copyright (C) 2018 Kiwix + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects + +import android.app.Activity +import org.kiwix.kiwixmobile.R +import org.kiwix.kiwixmobile.data.ZimContentProvider +import org.kiwix.kiwixmobile.extensions.toast +import org.kiwix.kiwixmobile.zim_manager.ZimManageActivity +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk + +class OpenFile(val bookOnDisk: BookOnDisk): SideEffect { + + override fun invokeWith(activity: Activity) { + val file = bookOnDisk.file + ZimContentProvider.canIterate = false + if (!file.canRead()) { + activity.toast(R.string.error_filenotfound) + } else { + (activity as ZimManageActivity).finishResult(file.path) + } + } +} diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/ShareFiles.kt b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/ShareFiles.kt new file mode 100644 index 0000000000..9586ec5e10 --- /dev/null +++ b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/ShareFiles.kt @@ -0,0 +1,42 @@ +package org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects + +import android.app.Activity +import android.content.Intent +import android.net.Uri +import android.os.Build +import androidx.core.content.FileProvider +import org.kiwix.kiwixmobile.BuildConfig +import org.kiwix.kiwixmobile.R +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk + +class ShareFiles(val selectedBooks: List) : SideEffect { + override fun invokeWith(activity: Activity) { + val selectedFileShareIntent = Intent() + selectedFileShareIntent.action = Intent.ACTION_SEND_MULTIPLE + selectedFileShareIntent.type = "application/octet-stream" + val selectedFileContentURIs = selectedBooks.mapNotNull { + if (Build.VERSION.SDK_INT >= 24) { + FileProvider.getUriForFile( + activity, + BuildConfig.APPLICATION_ID + ".fileprovider", + it.file + ) + } else { + Uri.fromFile(it.file) + } + } + selectedFileShareIntent.putParcelableArrayListExtra( + Intent.EXTRA_STREAM, + ArrayList(selectedFileContentURIs) + ) + selectedFileShareIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION + val shareChooserIntent = Intent.createChooser( + selectedFileShareIntent, + activity.getString(R.string.selected_file_cab_app_chooser_title) + ) + if (shareChooserIntent.resolveActivity(activity.getPackageManager()) != null) { + activity.startActivity(shareChooserIntent) // Open the app chooser dialog + } + } + +} diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/SideEffect.kt b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/SideEffect.kt new file mode 100644 index 0000000000..1136995312 --- /dev/null +++ b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/SideEffect.kt @@ -0,0 +1,28 @@ +/* + * Kiwix Android + * Copyright (C) 2018 Kiwix + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects + +import android.app.Activity +import org.kiwix.kiwixmobile.KiwixApplication + +interface SideEffect { + fun invokeWith(activity: Activity):T + fun activityComponent(activity: Activity) = + KiwixApplication.getApplicationComponent().activityComponent().activity(activity).build() +} + diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/StartMultiSelection.kt b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/StartMultiSelection.kt new file mode 100644 index 0000000000..8faa86c99b --- /dev/null +++ b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/effects/StartMultiSelection.kt @@ -0,0 +1,27 @@ +package org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects + +import android.app.Activity +import android.view.ActionMode +import io.reactivex.processors.PublishProcessor +import org.kiwix.kiwixmobile.R +import org.kiwix.kiwixmobile.extensions.startActionMode +import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions +import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestDeleteMultiSelection +import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestShareMultiSelection +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskListItem + +data class StartMultiSelection( + val bookOnDisk: BooksOnDiskListItem.BookOnDisk, + val fileSelectActions: PublishProcessor +) : SideEffect { + override fun invokeWith(activity: Activity) = + activity.startActionMode( + R.menu.menu_zim_files_contextual, + mapOf( + R.id.zim_file_delete_item to { fileSelectActions.offer(RequestDeleteMultiSelection) }, + R.id.zim_file_share_item to { fileSelectActions.offer(RequestShareMultiSelection) } + ), + { fileSelectActions.offer(FileSelectActions.MultiModeFinished) } + ) + +} diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/library_view/LibraryFragment.kt b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/library_view/LibraryFragment.kt index f2739ff84e..7b9e2edb47 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/library_view/LibraryFragment.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/library_view/LibraryFragment.kt @@ -140,7 +140,7 @@ class LibraryFragment : BaseFragment() { } private fun onLibraryItemsChange(it: List?) { - libraryAdapter.itemList = it!! + libraryAdapter.items = it!! if (it.isEmpty()) { libraryErrorText.setText( if (isNotConnected) R.string.no_network_connection diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/library_view/adapter/base/BaseDelegateAdapter.kt b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/library_view/adapter/base/BaseDelegateAdapter.kt index f5fa281ff4..40e39b9e58 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/library_view/adapter/base/BaseDelegateAdapter.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/library_view/adapter/base/BaseDelegateAdapter.kt @@ -30,7 +30,7 @@ abstract class BaseDelegateAdapter( setHasStableIds(true) } - var itemList: List = mutableListOf() + var items: List = mutableListOf() set(value) { field = value notifyDataSetChanged() @@ -41,19 +41,19 @@ abstract class BaseDelegateAdapter( viewType: Int ) = delegateManager.createViewHolder(parent, viewType) - override fun getItemCount() = itemList.size + override fun getItemCount() = items.size override fun onBindViewHolder( holder: ViewHolder, position: Int ) { - delegateManager.onBindViewHolder(itemList[position], holder) + delegateManager.onBindViewHolder(items[position], holder) } override fun getItemViewType(position: Int) = - delegateManager.getViewTypeFor(itemList[position]) + delegateManager.getViewTypeFor(items[position]) override fun getItemId(position: Int): Long { - return getIdFor(itemList[position]) + return getIdFor(items[position]) } abstract fun getIdFor(item:ITEM):Long diff --git a/app/src/main/res/layout/item_book.xml b/app/src/main/res/layout/item_book.xml index 3552460d6a..1962e726ce 100644 --- a/app/src/main/res/layout/item_book.xml +++ b/app/src/main/res/layout/item_book.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?attr/selectableItemBackground" + android:background="?android:attr/selectableItemBackground" android:paddingEnd="0dp" android:paddingLeft="0dp" android:paddingRight="0dp" @@ -12,13 +12,25 @@ android:paddingTop="@dimen/activity_vertical_margin" > + + diff --git a/app/src/test/java/org/kiwix/kiwixmobile/zim_manager/ZimManageViewModelTest.kt b/app/src/test/java/org/kiwix/kiwixmobile/zim_manager/ZimManageViewModelTest.kt index 59b81cca0e..9c055d2af8 100644 --- a/app/src/test/java/org/kiwix/kiwixmobile/zim_manager/ZimManageViewModelTest.kt +++ b/app/src/test/java/org/kiwix/kiwixmobile/zim_manager/ZimManageViewModelTest.kt @@ -235,7 +235,7 @@ class ZimManageViewModelTest { val expectedList = listOf(bookOnDisk()) booksOnDiskListItems.onNext(expectedList) testScheduler.triggerActions() - viewModel.bookItems.test() + viewModel.fileSelectListStates.test() .assertValue(expectedList) } From 1e453822ad799d0267f030baa903b71f5e1ef388 Mon Sep 17 00:00:00 2001 From: Sean Mac Gillicuddy Date: Tue, 2 Jul 2019 17:10:33 +0100 Subject: [PATCH 2/3] #1253 check checkboxes --- .../zim_manager/fileselect_view/adapter/BooksOnDiskViewHolder.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BooksOnDiskViewHolder.kt b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BooksOnDiskViewHolder.kt index 70e6ebab80..dd3994f1b0 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BooksOnDiskViewHolder.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/adapter/BooksOnDiskViewHolder.kt @@ -70,6 +70,7 @@ sealed class BookOnDiskViewHolder(containerView: View) item_book_label_video.visibility = View.GONE } + itemBookCheckbox.isChecked = item.isSelected when (selectionMode) { MULTI -> { itemBookCheckbox.visibility = View.VISIBLE From a7888c2ec3f27eec255ddce57685646b74cb7339 Mon Sep 17 00:00:00 2001 From: Sean Mac Gillicuddy Date: Wed, 3 Jul 2019 09:52:11 +0100 Subject: [PATCH 3/3] #1253 fix unit test compilation --- .../kiwix/kiwixmobile/zim_manager/ZimManageViewModelTest.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/test/java/org/kiwix/kiwixmobile/zim_manager/ZimManageViewModelTest.kt b/app/src/test/java/org/kiwix/kiwixmobile/zim_manager/ZimManageViewModelTest.kt index 9c055d2af8..b598f77dc1 100644 --- a/app/src/test/java/org/kiwix/kiwixmobile/zim_manager/ZimManageViewModelTest.kt +++ b/app/src/test/java/org/kiwix/kiwixmobile/zim_manager/ZimManageViewModelTest.kt @@ -61,6 +61,7 @@ import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.CanWrite4G import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.CannotWrite4GbFile import org.kiwix.kiwixmobile.zim_manager.NetworkState.CONNECTED import org.kiwix.kiwixmobile.zim_manager.NetworkState.NOT_CONNECTED +import org.kiwix.kiwixmobile.zim_manager.fileselect_view.FileSelectListState import org.kiwix.kiwixmobile.zim_manager.fileselect_view.StorageObserver import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskListItem import org.kiwix.kiwixmobile.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk @@ -236,7 +237,7 @@ class ZimManageViewModelTest { booksOnDiskListItems.onNext(expectedList) testScheduler.triggerActions() viewModel.fileSelectListStates.test() - .assertValue(expectedList) + .assertValue(FileSelectListState(expectedList)) } @Test