From 3c739eed8e7af96fae20353b0d3abe706ece7cbc Mon Sep 17 00:00:00 2001 From: Koitharu Date: Tue, 19 Apr 2022 12:43:51 +0300 Subject: [PATCH] Fix empty chapters label --- .../kotatsu/details/ui/ChaptersFragment.kt | 7 ++- .../kotatsu/details/ui/DetailsViewModel.kt | 13 ++--- .../kotatsu/utils/PausingDispatcher.kt | 50 +++++++++++++++++++ app/src/main/res/drawable/ic_pause.xml | 12 +++++ app/src/main/res/drawable/ic_resume.xml | 12 +++++ app/src/main/res/menu/opt_downloads.xml | 18 +++++++ 6 files changed, 102 insertions(+), 10 deletions(-) create mode 100644 app/src/main/java/org/koitharu/kotatsu/utils/PausingDispatcher.kt create mode 100644 app/src/main/res/drawable/ic_pause.xml create mode 100644 app/src/main/res/drawable/ic_resume.xml create mode 100644 app/src/main/res/menu/opt_downloads.xml diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt index 0dbf3eea5..143a87713 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt @@ -9,7 +9,6 @@ import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.view.ActionMode import androidx.appcompat.widget.SearchView import androidx.core.graphics.Insets -import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.core.view.updatePadding import org.koin.androidx.viewmodel.ext.android.sharedViewModel @@ -67,8 +66,8 @@ class ChaptersFragment : viewModel.isChaptersReversed.observe(viewLifecycleOwner) { activity?.invalidateOptionsMenu() } - viewModel.hasChapters.observe(viewLifecycleOwner) { - binding.textViewHolder.isGone = it + viewModel.isChaptersEmpty.observe(viewLifecycleOwner) { + binding.textViewHolder.isVisible = it activity?.invalidateOptionsMenu() } } @@ -94,7 +93,7 @@ class ChaptersFragment : override fun onPrepareOptionsMenu(menu: Menu) { super.onPrepareOptionsMenu(menu) menu.findItem(R.id.action_reversed).isChecked = viewModel.isChaptersReversed.value == true - menu.findItem(R.id.action_search).isVisible = viewModel.hasChapters.value == true + menu.findItem(R.id.action_search).isVisible = viewModel.isChaptersEmpty.value == false } override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) { diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt index 4582e48ad..d0318779b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt @@ -4,7 +4,6 @@ import androidx.core.os.LocaleListCompat import androidx.lifecycle.asFlow import androidx.lifecycle.asLiveData import androidx.lifecycle.viewModelScope -import java.io.IOException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.flow.* @@ -29,7 +28,9 @@ import org.koitharu.kotatsu.parsers.util.mapToSet import org.koitharu.kotatsu.parsers.util.toTitleCase import org.koitharu.kotatsu.tracker.domain.TrackingRepository import org.koitharu.kotatsu.utils.SingleLiveEvent +import org.koitharu.kotatsu.utils.ext.asLiveDataDistinct import org.koitharu.kotatsu.utils.ext.iterator +import java.io.IOException class DetailsViewModel( private val intent: MangaIntent, @@ -89,18 +90,18 @@ class DetailsViewModel( val branches = mangaData.map { it?.chapters?.mapToSet { x -> x.branch }?.sortedBy { x -> x }.orEmpty() - }.asLiveData(viewModelScope.coroutineContext + Dispatchers.Default) + }.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default) val selectedBranchIndex = combine( branches.asFlow(), selectedBranch ) { branches, selected -> branches.indexOf(selected) - }.asLiveData(viewModelScope.coroutineContext + Dispatchers.Default) + }.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default) - val hasChapters = mangaData.map { - !(it?.chapters.isNullOrEmpty()) - }.asLiveData(viewModelScope.coroutineContext + Dispatchers.Default) + val isChaptersEmpty = mangaData.mapNotNull { m -> + m?.run { chapters.isNullOrEmpty() } + }.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default, false) val chapters = combine( combine( diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/PausingDispatcher.kt b/app/src/main/java/org/koitharu/kotatsu/utils/PausingDispatcher.kt new file mode 100644 index 000000000..57eb100a4 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/utils/PausingDispatcher.kt @@ -0,0 +1,50 @@ +package org.koitharu.kotatsu.utils + +import androidx.annotation.MainThread +import java.util.concurrent.ConcurrentLinkedQueue +import kotlin.coroutines.CoroutineContext +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Runnable + +class PausingDispatcher( + private val dispatcher: CoroutineDispatcher, +) : CoroutineDispatcher() { + + @Volatile + private var isPaused = false + private val queue = ConcurrentLinkedQueue() + + override fun isDispatchNeeded(context: CoroutineContext): Boolean { + return isPaused || super.isDispatchNeeded(context) + } + + override fun dispatch(context: CoroutineContext, block: Runnable) { + if (isPaused) { + queue.add(Task(context, block)) + } else { + dispatcher.dispatch(context, block) + } + } + + @MainThread + fun pause() { + isPaused = true + } + + @MainThread + fun resume() { + if (!isPaused) { + return + } + isPaused = false + while (true) { + val task = queue.poll() ?: break + dispatcher.dispatch(task.context, task.block) + } + } + + private class Task( + val context: CoroutineContext, + val block: Runnable, + ) +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_pause.xml b/app/src/main/res/drawable/ic_pause.xml new file mode 100644 index 000000000..e63766078 --- /dev/null +++ b/app/src/main/res/drawable/ic_pause.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_resume.xml b/app/src/main/res/drawable/ic_resume.xml new file mode 100644 index 000000000..448628b18 --- /dev/null +++ b/app/src/main/res/drawable/ic_resume.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/opt_downloads.xml b/app/src/main/res/menu/opt_downloads.xml new file mode 100644 index 000000000..f804ec53f --- /dev/null +++ b/app/src/main/res/menu/opt_downloads.xml @@ -0,0 +1,18 @@ + + + + + + + + \ No newline at end of file