Action to mark manga as completed
This commit is contained in:
@@ -7,6 +7,7 @@ import android.view.View
|
||||
import androidx.appcompat.view.ActionMode
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.ui.list.ListSelectionController
|
||||
@@ -73,6 +74,18 @@ class FavouritesListFragment : MangaListFragment(), PopupMenu.OnMenuItemClickLis
|
||||
true
|
||||
}
|
||||
|
||||
R.id.action_mark_current -> {
|
||||
MaterialAlertDialogBuilder(context ?: return false)
|
||||
.setTitle(item.title)
|
||||
.setMessage(R.string.mark_as_completed_prompt)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
viewModel.markAsRead(selectedItems)
|
||||
mode.finish()
|
||||
}.show()
|
||||
true
|
||||
}
|
||||
|
||||
else -> super.onActionItemClicked(controller, mode, item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.koitharu.kotatsu.download.ui.worker.DownloadWorker
|
||||
import org.koitharu.kotatsu.favourites.domain.FavouritesRepository
|
||||
import org.koitharu.kotatsu.favourites.ui.list.FavouritesListFragment.Companion.ARG_CATEGORY_ID
|
||||
import org.koitharu.kotatsu.favourites.ui.list.FavouritesListFragment.Companion.NO_ID
|
||||
import org.koitharu.kotatsu.history.domain.MarkAsReadUseCase
|
||||
import org.koitharu.kotatsu.list.domain.ListExtraProvider
|
||||
import org.koitharu.kotatsu.list.domain.ListSortOrder
|
||||
import org.koitharu.kotatsu.list.ui.MangaListViewModel
|
||||
@@ -28,6 +29,7 @@ import org.koitharu.kotatsu.list.ui.model.EmptyState
|
||||
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
||||
import org.koitharu.kotatsu.list.ui.model.toErrorState
|
||||
import org.koitharu.kotatsu.list.ui.model.toUi
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
@@ -35,11 +37,13 @@ class FavouritesListViewModel @Inject constructor(
|
||||
savedStateHandle: SavedStateHandle,
|
||||
private val repository: FavouritesRepository,
|
||||
private val listExtraProvider: ListExtraProvider,
|
||||
private val markAsReadUseCase: MarkAsReadUseCase,
|
||||
settings: AppSettings,
|
||||
downloadScheduler: DownloadWorker.Scheduler,
|
||||
) : MangaListViewModel(settings, downloadScheduler) {
|
||||
|
||||
val categoryId: Long = savedStateHandle[ARG_CATEGORY_ID] ?: NO_ID
|
||||
private val refreshTrigger = MutableStateFlow(Any())
|
||||
|
||||
override val listMode = settings.observeAsFlow(AppSettings.KEY_LIST_MODE_FAVORITES) { favoritesListMode }
|
||||
.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, settings.favoritesListMode)
|
||||
@@ -59,7 +63,8 @@ class FavouritesListViewModel @Inject constructor(
|
||||
repository.observeAll(categoryId)
|
||||
},
|
||||
listMode,
|
||||
) { list, mode ->
|
||||
refreshTrigger,
|
||||
) { list, mode, _ ->
|
||||
when {
|
||||
list.isEmpty() -> listOf(
|
||||
EmptyState(
|
||||
@@ -80,10 +85,19 @@ class FavouritesListViewModel @Inject constructor(
|
||||
emit(listOf(it.toErrorState(canRetry = false)))
|
||||
}.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, listOf(LoadingState))
|
||||
|
||||
override fun onRefresh() = Unit
|
||||
override fun onRefresh() {
|
||||
refreshTrigger.value = Any()
|
||||
}
|
||||
|
||||
override fun onRetry() = Unit
|
||||
|
||||
fun markAsRead(items: Set<Manga>) {
|
||||
launchLoadingJob(Dispatchers.Default) {
|
||||
markAsReadUseCase(items)
|
||||
onRefresh()
|
||||
}
|
||||
}
|
||||
|
||||
fun removeFromFavourites(ids: Set<Long>) {
|
||||
if (ids.isEmpty()) {
|
||||
return
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.koitharu.kotatsu.history.domain
|
||||
|
||||
import dagger.Reusable
|
||||
import kotlinx.coroutines.joinAll
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.supervisorScope
|
||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||
import org.koitharu.kotatsu.history.data.HistoryRepository
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import javax.inject.Inject
|
||||
|
||||
@Reusable
|
||||
class MarkAsReadUseCase @Inject constructor(
|
||||
private val historyRepository: HistoryRepository,
|
||||
private val mangaRepositoryFactory: MangaRepository.Factory,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(manga: Manga) {
|
||||
val repo = mangaRepositoryFactory.create(manga.source)
|
||||
val details = if (manga.chapters.isNullOrEmpty()) {
|
||||
repo.getDetails(manga)
|
||||
} else {
|
||||
manga
|
||||
}
|
||||
val lastChapter = checkNotNull(details.chapters).last()
|
||||
val pages = repo.getPages(lastChapter)
|
||||
historyRepository.addOrUpdate(
|
||||
manga = details,
|
||||
chapterId = lastChapter.id,
|
||||
page = pages.lastIndex,
|
||||
scroll = 0,
|
||||
percent = 1f,
|
||||
)
|
||||
}
|
||||
|
||||
suspend operator fun invoke(manga: Collection<Manga>) {
|
||||
when (manga.size) {
|
||||
0 -> Unit
|
||||
1 -> invoke(manga.first())
|
||||
else -> supervisorScope {
|
||||
manga.map {
|
||||
launch {
|
||||
invoke(it)
|
||||
}
|
||||
}.joinAll()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,12 @@
|
||||
android:title="@string/categories"
|
||||
app:showAsAction="ifRoom|withText" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_mark_current"
|
||||
android:icon="@drawable/ic_eye_check"
|
||||
android:title="@string/mark_as_completed"
|
||||
app:showAsAction="ifRoom|withText" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_select_all"
|
||||
android:icon="?actionModeSelectAllDrawable"
|
||||
|
||||
@@ -556,4 +556,6 @@
|
||||
<string name="rating_suggestive">Suggestive</string>
|
||||
<string name="rating_adult">Adult</string>
|
||||
<string name="default_tab">Default tab</string>
|
||||
<string name="mark_as_completed">Mark as completed</string>
|
||||
<string name="mark_as_completed_prompt">Mark selected manga as completely read?\n\nWarning: current reading progress will be lost.</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user