Option to show only downloaded chapters
This commit is contained in:
@@ -21,7 +21,6 @@ import kotlinx.coroutines.flow.transform
|
||||
import kotlinx.coroutines.flow.transformLatest
|
||||
import kotlinx.coroutines.flow.transformWhile
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.withTimeout
|
||||
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
|
||||
import org.koitharu.kotatsu.parsers.util.suspendlazy.SuspendLazy
|
||||
import java.util.concurrent.TimeUnit
|
||||
@@ -135,6 +134,28 @@ fun <T1, T2, T3, T4, T5, T6, R> combine(
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T1, T2, T3, T4, T5, T6, T7, R> combine(
|
||||
flow: Flow<T1>,
|
||||
flow2: Flow<T2>,
|
||||
flow3: Flow<T3>,
|
||||
flow4: Flow<T4>,
|
||||
flow5: Flow<T5>,
|
||||
flow6: Flow<T6>,
|
||||
flow7: Flow<T7>,
|
||||
transform: suspend (T1, T2, T3, T4, T5, T6, T7) -> R,
|
||||
): Flow<R> = combine(flow, flow2, flow3, flow4, flow5, flow6, flow7) { args: Array<*> ->
|
||||
transform(
|
||||
args[0] as T1,
|
||||
args[1] as T2,
|
||||
args[2] as T3,
|
||||
args[3] as T4,
|
||||
args[4] as T5,
|
||||
args[5] as T6,
|
||||
args[6] as T7,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun <T : Any> Flow<T?>.firstNotNull(): T = checkNotNull(first { x -> x != null })
|
||||
|
||||
suspend fun <T : Any> Flow<T?>.firstNotNullOrNull(): T? = firstOrNull { x -> x != null }
|
||||
|
||||
@@ -17,7 +17,6 @@ data class MangaDetails(
|
||||
private val localManga: LocalManga?,
|
||||
private val override: MangaOverride?,
|
||||
val description: CharSequence?,
|
||||
@Deprecated("Caller should decide if manga is loaded enough by itself")
|
||||
val isLoaded: Boolean,
|
||||
) {
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ fun MangaDetails.mapChapters(
|
||||
branch: String?,
|
||||
bookmarks: List<Bookmark>,
|
||||
isGrid: Boolean,
|
||||
isDownloadedOnly: Boolean,
|
||||
): List<ChapterListItem> {
|
||||
val remoteChapters = chapters[branch].orEmpty()
|
||||
val localChapters = local?.manga?.getChapters(branch).orEmpty()
|
||||
@@ -35,19 +36,21 @@ fun MangaDetails.mapChapters(
|
||||
null
|
||||
}
|
||||
var isUnread = currentChapterId !in ids
|
||||
for (chapter in remoteChapters) {
|
||||
val local = localMap?.remove(chapter.id)
|
||||
if (chapter.id == currentChapterId) {
|
||||
isUnread = true
|
||||
if (!isDownloadedOnly || local?.manga?.chapters == null) {
|
||||
for (chapter in remoteChapters) {
|
||||
val local = localMap?.remove(chapter.id)
|
||||
if (chapter.id == currentChapterId) {
|
||||
isUnread = true
|
||||
}
|
||||
result += (local ?: chapter).toListItem(
|
||||
isCurrent = chapter.id == currentChapterId,
|
||||
isUnread = isUnread,
|
||||
isNew = isUnread && result.size >= newFrom,
|
||||
isDownloaded = local != null,
|
||||
isBookmarked = chapter.id in bookmarked,
|
||||
isGrid = isGrid,
|
||||
)
|
||||
}
|
||||
result += (local ?: chapter).toListItem(
|
||||
isCurrent = chapter.id == currentChapterId,
|
||||
isUnread = isUnread,
|
||||
isNew = isUnread && result.size >= newFrom,
|
||||
isDownloaded = local != null,
|
||||
isBookmarked = chapter.id in bookmarked,
|
||||
isGrid = isGrid,
|
||||
)
|
||||
}
|
||||
if (!localMap.isNullOrEmpty()) {
|
||||
for (chapter in localMap.values) {
|
||||
|
||||
@@ -9,6 +9,7 @@ import androidx.core.view.MenuProvider
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.google.android.material.slider.LabelFormatter
|
||||
import com.google.android.material.slider.Slider
|
||||
import com.google.android.material.slider.TickVisibilityMode
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.core.ui.sheet.BaseAdaptiveSheet
|
||||
@@ -41,6 +42,10 @@ class ChapterPagesMenuProvider(
|
||||
menu.findItem(R.id.action_search)?.isVisible = viewModel.isChaptersEmpty.value == false
|
||||
menu.findItem(R.id.action_reversed)?.isChecked = viewModel.isChaptersReversed.value == true
|
||||
menu.findItem(R.id.action_grid_view)?.isChecked = viewModel.isChaptersInGridView.value == true
|
||||
menu.findItem(R.id.action_downloaded)?.let { menuItem ->
|
||||
menuItem.isVisible = viewModel.mangaDetails.value?.local != null
|
||||
menuItem.isChecked = viewModel.isDownloadedOnly.value == true
|
||||
}
|
||||
}
|
||||
|
||||
TAB_PAGES, TAB_BOOKMARKS -> {
|
||||
@@ -64,6 +69,11 @@ class ChapterPagesMenuProvider(
|
||||
true
|
||||
}
|
||||
|
||||
R.id.action_downloaded -> {
|
||||
viewModel.isDownloadedOnly.value = !menuItem.isChecked
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
|
||||
@@ -110,7 +120,7 @@ class ChapterPagesMenuProvider(
|
||||
valueFrom = 50f
|
||||
valueTo = 150f
|
||||
stepSize = 5f
|
||||
isTickVisible = false
|
||||
tickVisibilityMode = TickVisibilityMode.TICK_VISIBILITY_HIDDEN
|
||||
labelBehavior = LabelFormatter.LABEL_FLOATING
|
||||
setLabelFormatter(IntPercentLabelFormatter(context))
|
||||
setValueRounded(settings.gridSizePages.toFloat())
|
||||
|
||||
@@ -81,6 +81,7 @@ class ChaptersPagesSheet : BaseAdaptiveSheet<SheetChaptersPagesBinding>(),
|
||||
val menuInvalidator = MenuInvalidator(binding.toolbar)
|
||||
viewModel.isChaptersReversed.observe(viewLifecycleOwner, menuInvalidator)
|
||||
viewModel.isChaptersInGridView.observe(viewLifecycleOwner, menuInvalidator)
|
||||
viewModel.isDownloadedOnly.observe(viewLifecycleOwner, menuInvalidator)
|
||||
|
||||
actionModeDelegate?.addListener(this, viewLifecycleOwner)
|
||||
addSheetCallback(this, viewLifecycleOwner)
|
||||
|
||||
@@ -87,6 +87,8 @@ abstract class ChaptersPagesViewModel(
|
||||
valueProducer = { isChaptersGridView },
|
||||
)
|
||||
|
||||
val isDownloadedOnly = MutableStateFlow(false)
|
||||
|
||||
val newChaptersCount = mangaDetails.flatMapLatest { d ->
|
||||
if (d?.isLocal == false) {
|
||||
interactor.observeNewChapters(d.id)
|
||||
@@ -115,13 +117,15 @@ abstract class ChaptersPagesViewModel(
|
||||
newChaptersCount,
|
||||
bookmarks,
|
||||
isChaptersInGridView,
|
||||
) { manga, currentChapterId, branch, news, bookmarks, grid ->
|
||||
isDownloadedOnly,
|
||||
) { manga, currentChapterId, branch, news, bookmarks, grid, downloadedOnly ->
|
||||
manga?.mapChapters(
|
||||
currentChapterId,
|
||||
news,
|
||||
branch,
|
||||
bookmarks,
|
||||
grid,
|
||||
currentChapterId = currentChapterId,
|
||||
newCount = news,
|
||||
branch = branch,
|
||||
bookmarks = bookmarks,
|
||||
isGrid = grid,
|
||||
isDownloadedOnly = downloadedOnly,
|
||||
).orEmpty()
|
||||
},
|
||||
isChaptersReversed,
|
||||
|
||||
@@ -11,6 +11,13 @@
|
||||
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||
app:showAsAction="ifRoom|collapseActionView" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_downloaded"
|
||||
android:checkable="true"
|
||||
android:orderInCategory="18"
|
||||
android:title="@string/on_device"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_reversed"
|
||||
android:checkable="true"
|
||||
|
||||
Reference in New Issue
Block a user