Add "Play" button on manga in library (#8218)
* resume manga button in libarary * work on resume button * Backup * work on opening the last read chapter * backup * renaming * fab instead of image * done with logic * cleanup * cleanup * import cleanup * cleanup... * refactoring * fixing logic * fixing scopes * Reworking design * adding ability to turn on/off the feature * cleanup * refactoring, fixing logic, adding filter logic (partial) * backup * backup * logic done * backup before merge fix * merge conflict.... * merge conflict... * reworking ui logic * removing unnecessary file * refactoring * refactoring * review changes + minor parameter position movement * commiting suggestion Co-authored-by: arkon <arkon@users.noreply.github.com> * fixing minor mistake * moving ChapterFilter.kt Co-authored-by: arkon <arkon@users.noreply.github.com>
This commit is contained in:
parent
bf9edda04c
commit
ba00d9e5d2
15 changed files with 271 additions and 48 deletions
|
@ -0,0 +1,82 @@
|
||||||
|
package eu.kanade.domain.chapter.model
|
||||||
|
|
||||||
|
import eu.kanade.domain.manga.model.Manga
|
||||||
|
import eu.kanade.domain.manga.model.TriStateFilter
|
||||||
|
import eu.kanade.domain.manga.model.isLocal
|
||||||
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||||
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
|
import eu.kanade.tachiyomi.ui.manga.ChapterItem
|
||||||
|
import eu.kanade.tachiyomi.util.chapter.getChapterSort
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the view filters to the list of chapters obtained from the database.
|
||||||
|
* @return an observable of the list of chapters filtered and sorted.
|
||||||
|
*/
|
||||||
|
fun List<Chapter>.applyFilters(manga: Manga, downloadManager: DownloadManager): List<Chapter> {
|
||||||
|
val isLocalManga = manga.isLocal()
|
||||||
|
val unreadFilter = manga.unreadFilter
|
||||||
|
val downloadedFilter = manga.downloadedFilter
|
||||||
|
val bookmarkedFilter = manga.bookmarkedFilter
|
||||||
|
|
||||||
|
return filter { chapter ->
|
||||||
|
when (unreadFilter) {
|
||||||
|
TriStateFilter.DISABLED -> true
|
||||||
|
TriStateFilter.ENABLED_IS -> !chapter.read
|
||||||
|
TriStateFilter.ENABLED_NOT -> chapter.read
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.filter { chapter ->
|
||||||
|
when (bookmarkedFilter) {
|
||||||
|
TriStateFilter.DISABLED -> true
|
||||||
|
TriStateFilter.ENABLED_IS -> chapter.bookmark
|
||||||
|
TriStateFilter.ENABLED_NOT -> !chapter.bookmark
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.filter { chapter ->
|
||||||
|
val downloaded = downloadManager.isChapterDownloaded(chapter.name, chapter.scanlator, manga.title, manga.source)
|
||||||
|
val downloadState = when {
|
||||||
|
downloaded -> Download.State.DOWNLOADED
|
||||||
|
else -> Download.State.NOT_DOWNLOADED
|
||||||
|
}
|
||||||
|
when (downloadedFilter) {
|
||||||
|
TriStateFilter.DISABLED -> true
|
||||||
|
TriStateFilter.ENABLED_IS -> downloadState == Download.State.DOWNLOADED || isLocalManga
|
||||||
|
TriStateFilter.ENABLED_NOT -> downloadState != Download.State.DOWNLOADED && !isLocalManga
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.sortedWith(getChapterSort(manga))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the view filters to the list of chapters obtained from the database.
|
||||||
|
* @return an observable of the list of chapters filtered and sorted.
|
||||||
|
*/
|
||||||
|
fun List<ChapterItem>.applyFilters(manga: Manga): Sequence<ChapterItem> {
|
||||||
|
val isLocalManga = manga.isLocal()
|
||||||
|
val unreadFilter = manga.unreadFilter
|
||||||
|
val downloadedFilter = manga.downloadedFilter
|
||||||
|
val bookmarkedFilter = manga.bookmarkedFilter
|
||||||
|
return asSequence()
|
||||||
|
.filter { (chapter) ->
|
||||||
|
when (unreadFilter) {
|
||||||
|
TriStateFilter.DISABLED -> true
|
||||||
|
TriStateFilter.ENABLED_IS -> !chapter.read
|
||||||
|
TriStateFilter.ENABLED_NOT -> chapter.read
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.filter { (chapter) ->
|
||||||
|
when (bookmarkedFilter) {
|
||||||
|
TriStateFilter.DISABLED -> true
|
||||||
|
TriStateFilter.ENABLED_IS -> chapter.bookmark
|
||||||
|
TriStateFilter.ENABLED_NOT -> !chapter.bookmark
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.filter {
|
||||||
|
when (downloadedFilter) {
|
||||||
|
TriStateFilter.DISABLED -> true
|
||||||
|
TriStateFilter.ENABLED_IS -> it.isDownloaded || isLocalManga
|
||||||
|
TriStateFilter.ENABLED_NOT -> !it.isDownloaded && !isLocalManga
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.sortedWith { (chapter1), (chapter2) -> getChapterSort(manga).invoke(chapter1, chapter2) }
|
||||||
|
}
|
|
@ -32,6 +32,8 @@ class LibraryPreferences(
|
||||||
|
|
||||||
fun autoUpdateTrackers() = preferenceStore.getBoolean("auto_update_trackers", false)
|
fun autoUpdateTrackers() = preferenceStore.getBoolean("auto_update_trackers", false)
|
||||||
|
|
||||||
|
fun showContinueReadingButton() = preferenceStore.getBoolean("display_continue_reading_button", false)
|
||||||
|
|
||||||
// region Filter
|
// region Filter
|
||||||
|
|
||||||
fun filterDownloaded() = preferenceStore.getInt("pref_filter_library_downloaded", ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value)
|
fun filterDownloaded() = preferenceStore.getInt("pref_filter_library_downloaded", ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value)
|
||||||
|
|
|
@ -12,10 +12,17 @@ import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.PlayArrow
|
||||||
|
import androidx.compose.material3.FilledIconButton
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButtonDefaults
|
||||||
import androidx.compose.material3.LocalContentColor
|
import androidx.compose.material3.LocalContentColor
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.contentColorFor
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
|
@ -41,6 +48,7 @@ object CommonMangaItemDefaults {
|
||||||
const val BrowseFavoriteCoverAlpha = 0.34f
|
const val BrowseFavoriteCoverAlpha = 0.34f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val ContinueReadingButtonSize = 38.dp
|
||||||
private const val GridSelectedCoverAlpha = 0.76f
|
private const val GridSelectedCoverAlpha = 0.76f
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,8 +63,10 @@ fun MangaCompactGridItem(
|
||||||
coverAlpha: Float = 1f,
|
coverAlpha: Float = 1f,
|
||||||
coverBadgeStart: (@Composable RowScope.() -> Unit)? = null,
|
coverBadgeStart: (@Composable RowScope.() -> Unit)? = null,
|
||||||
coverBadgeEnd: (@Composable RowScope.() -> Unit)? = null,
|
coverBadgeEnd: (@Composable RowScope.() -> Unit)? = null,
|
||||||
|
showContinueReadingButton: Boolean = false,
|
||||||
onLongClick: () -> Unit,
|
onLongClick: () -> Unit,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
|
onClickContinueReading: (() -> Unit)? = null,
|
||||||
) {
|
) {
|
||||||
GridItemSelectable(
|
GridItemSelectable(
|
||||||
isSelected = isSelected,
|
isSelected = isSelected,
|
||||||
|
@ -76,7 +86,12 @@ fun MangaCompactGridItem(
|
||||||
badgesEnd = coverBadgeEnd,
|
badgesEnd = coverBadgeEnd,
|
||||||
content = {
|
content = {
|
||||||
if (title != null) {
|
if (title != null) {
|
||||||
CoverTextOverlay(title = title)
|
CoverTextOverlay(title = title, showContinueReadingButton)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
continueReadingButton = {
|
||||||
|
if (showContinueReadingButton && onClickContinueReading != null) {
|
||||||
|
ContinueReadingButton(onClickContinueReading)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -87,7 +102,10 @@ fun MangaCompactGridItem(
|
||||||
* Title overlay for [MangaCompactGridItem]
|
* Title overlay for [MangaCompactGridItem]
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
private fun BoxScope.CoverTextOverlay(title: String) {
|
private fun BoxScope.CoverTextOverlay(
|
||||||
|
title: String,
|
||||||
|
showContinueReadingButton: Boolean = false,
|
||||||
|
) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clip(RoundedCornerShape(bottomStart = 4.dp, bottomEnd = 4.dp))
|
.clip(RoundedCornerShape(bottomStart = 4.dp, bottomEnd = 4.dp))
|
||||||
|
@ -101,9 +119,10 @@ private fun BoxScope.CoverTextOverlay(title: String) {
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.align(Alignment.BottomCenter),
|
.align(Alignment.BottomCenter),
|
||||||
)
|
)
|
||||||
|
val endPadding = if (showContinueReadingButton) ContinueReadingButtonSize else 8.dp
|
||||||
GridItemTitle(
|
GridItemTitle(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(8.dp)
|
.padding(start = 8.dp, top = 8.dp, end = endPadding, bottom = 8.dp)
|
||||||
.align(Alignment.BottomStart),
|
.align(Alignment.BottomStart),
|
||||||
title = title,
|
title = title,
|
||||||
style = MaterialTheme.typography.titleSmall.copy(
|
style = MaterialTheme.typography.titleSmall.copy(
|
||||||
|
@ -127,8 +146,10 @@ fun MangaComfortableGridItem(
|
||||||
coverAlpha: Float = 1f,
|
coverAlpha: Float = 1f,
|
||||||
coverBadgeStart: (@Composable RowScope.() -> Unit)? = null,
|
coverBadgeStart: (@Composable RowScope.() -> Unit)? = null,
|
||||||
coverBadgeEnd: (@Composable RowScope.() -> Unit)? = null,
|
coverBadgeEnd: (@Composable RowScope.() -> Unit)? = null,
|
||||||
|
showContinueReadingButton: Boolean = false,
|
||||||
onLongClick: () -> Unit,
|
onLongClick: () -> Unit,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
|
onClickContinueReading: (() -> Unit)? = null,
|
||||||
) {
|
) {
|
||||||
GridItemSelectable(
|
GridItemSelectable(
|
||||||
isSelected = isSelected,
|
isSelected = isSelected,
|
||||||
|
@ -147,6 +168,11 @@ fun MangaComfortableGridItem(
|
||||||
},
|
},
|
||||||
badgesStart = coverBadgeStart,
|
badgesStart = coverBadgeStart,
|
||||||
badgesEnd = coverBadgeEnd,
|
badgesEnd = coverBadgeEnd,
|
||||||
|
continueReadingButton = {
|
||||||
|
if (showContinueReadingButton && onClickContinueReading != null) {
|
||||||
|
ContinueReadingButton(onClickContinueReading)
|
||||||
|
}
|
||||||
|
},
|
||||||
)
|
)
|
||||||
GridItemTitle(
|
GridItemTitle(
|
||||||
modifier = Modifier.padding(4.dp),
|
modifier = Modifier.padding(4.dp),
|
||||||
|
@ -166,6 +192,7 @@ private fun MangaGridCover(
|
||||||
cover: @Composable BoxScope.() -> Unit = {},
|
cover: @Composable BoxScope.() -> Unit = {},
|
||||||
badgesStart: (@Composable RowScope.() -> Unit)? = null,
|
badgesStart: (@Composable RowScope.() -> Unit)? = null,
|
||||||
badgesEnd: (@Composable RowScope.() -> Unit)? = null,
|
badgesEnd: (@Composable RowScope.() -> Unit)? = null,
|
||||||
|
continueReadingButton: (@Composable BoxScope.() -> Unit)? = null,
|
||||||
content: @Composable (BoxScope.() -> Unit)? = null,
|
content: @Composable (BoxScope.() -> Unit)? = null,
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
|
@ -192,6 +219,7 @@ private fun MangaGridCover(
|
||||||
content = badgesEnd,
|
content = badgesEnd,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
continueReadingButton?.invoke(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,8 +311,10 @@ fun MangaListItem(
|
||||||
coverData: eu.kanade.domain.manga.model.MangaCover,
|
coverData: eu.kanade.domain.manga.model.MangaCover,
|
||||||
coverAlpha: Float = 1f,
|
coverAlpha: Float = 1f,
|
||||||
badge: @Composable RowScope.() -> Unit,
|
badge: @Composable RowScope.() -> Unit,
|
||||||
|
showContinueReadingButton: Boolean = false,
|
||||||
onLongClick: () -> Unit,
|
onLongClick: () -> Unit,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
|
onClickContinueReading: (() -> Unit)? = null,
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
@ -313,5 +343,37 @@ fun MangaListItem(
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
)
|
)
|
||||||
BadgeGroup(content = badge)
|
BadgeGroup(content = badge)
|
||||||
|
if (showContinueReadingButton && onClickContinueReading != null) {
|
||||||
|
Box {
|
||||||
|
ContinueReadingButton(onClickContinueReading)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun BoxScope.ContinueReadingButton(
|
||||||
|
onClickContinueReading: () -> Unit,
|
||||||
|
) {
|
||||||
|
FilledIconButton(
|
||||||
|
onClick = {
|
||||||
|
onClickContinueReading()
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.size(ContinueReadingButtonSize)
|
||||||
|
.padding(3.dp)
|
||||||
|
.align(Alignment.BottomEnd),
|
||||||
|
shape = MaterialTheme.shapes.small,
|
||||||
|
colors = IconButtonDefaults.filledIconButtonColors(
|
||||||
|
containerColor = MaterialTheme.colorScheme.primaryContainer,
|
||||||
|
contentColor = contentColorFor(MaterialTheme.colorScheme.primaryContainer),
|
||||||
|
),
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Filled.PlayArrow,
|
||||||
|
contentDescription = "",
|
||||||
|
modifier = Modifier
|
||||||
|
.size(15.dp),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
import androidx.compose.ui.platform.LocalUriHandler
|
import androidx.compose.ui.platform.LocalUriHandler
|
||||||
import androidx.compose.ui.util.fastAll
|
import androidx.compose.ui.util.fastAll
|
||||||
import eu.kanade.domain.category.model.Category
|
import eu.kanade.domain.category.model.Category
|
||||||
|
import eu.kanade.domain.library.model.LibraryManga
|
||||||
import eu.kanade.domain.library.model.display
|
import eu.kanade.domain.library.model.display
|
||||||
import eu.kanade.domain.manga.model.isLocal
|
import eu.kanade.domain.manga.model.isLocal
|
||||||
import eu.kanade.presentation.components.EmptyScreen
|
import eu.kanade.presentation.components.EmptyScreen
|
||||||
|
@ -29,6 +30,7 @@ import eu.kanade.tachiyomi.widget.TachiyomiBottomNavigationView
|
||||||
fun LibraryScreen(
|
fun LibraryScreen(
|
||||||
presenter: LibraryPresenter,
|
presenter: LibraryPresenter,
|
||||||
onMangaClicked: (Long) -> Unit,
|
onMangaClicked: (Long) -> Unit,
|
||||||
|
onContinueReadingClicked: (LibraryManga) -> Unit,
|
||||||
onGlobalSearchClicked: () -> Unit,
|
onGlobalSearchClicked: () -> Unit,
|
||||||
onChangeCategoryClicked: () -> Unit,
|
onChangeCategoryClicked: () -> Unit,
|
||||||
onMarkAsReadClicked: () -> Unit,
|
onMarkAsReadClicked: () -> Unit,
|
||||||
|
@ -104,6 +106,7 @@ fun LibraryScreen(
|
||||||
showMangaCount = presenter.mangaCountVisibility,
|
showMangaCount = presenter.mangaCountVisibility,
|
||||||
onChangeCurrentPage = { presenter.activeCategory = it },
|
onChangeCurrentPage = { presenter.activeCategory = it },
|
||||||
onMangaClicked = onMangaClicked,
|
onMangaClicked = onMangaClicked,
|
||||||
|
onContinueReadingClicked = onContinueReadingClicked,
|
||||||
onToggleSelection = { presenter.toggleSelection(it) },
|
onToggleSelection = { presenter.toggleSelection(it) },
|
||||||
onToggleRangeSelection = {
|
onToggleRangeSelection = {
|
||||||
presenter.toggleRangeSelection(it)
|
presenter.toggleRangeSelection(it)
|
||||||
|
@ -119,6 +122,7 @@ fun LibraryScreen(
|
||||||
showUnreadBadges = presenter.showUnreadBadges,
|
showUnreadBadges = presenter.showUnreadBadges,
|
||||||
showLocalBadges = presenter.showLocalBadges,
|
showLocalBadges = presenter.showLocalBadges,
|
||||||
showLanguageBadges = presenter.showLanguageBadges,
|
showLanguageBadges = presenter.showLanguageBadges,
|
||||||
|
showContinueReadingButton = presenter.showContinueReadingButton,
|
||||||
isIncognitoMode = presenter.isIncognitoMode,
|
isIncognitoMode = presenter.isIncognitoMode,
|
||||||
isDownloadOnly = presenter.isDownloadOnly,
|
isDownloadOnly = presenter.isDownloadOnly,
|
||||||
)
|
)
|
||||||
|
|
|
@ -18,11 +18,13 @@ fun LibraryComfortableGrid(
|
||||||
showUnreadBadges: Boolean,
|
showUnreadBadges: Boolean,
|
||||||
showLocalBadges: Boolean,
|
showLocalBadges: Boolean,
|
||||||
showLanguageBadges: Boolean,
|
showLanguageBadges: Boolean,
|
||||||
|
showContinueReadingButton: Boolean,
|
||||||
columns: Int,
|
columns: Int,
|
||||||
contentPadding: PaddingValues,
|
contentPadding: PaddingValues,
|
||||||
selection: List<LibraryManga>,
|
selection: List<LibraryManga>,
|
||||||
onClick: (LibraryManga) -> Unit,
|
onClick: (LibraryManga) -> Unit,
|
||||||
onLongClick: (LibraryManga) -> Unit,
|
onLongClick: (LibraryManga) -> Unit,
|
||||||
|
onClickContinueReading: (LibraryManga) -> Unit,
|
||||||
searchQuery: String?,
|
searchQuery: String?,
|
||||||
onGlobalSearchClicked: () -> Unit,
|
onGlobalSearchClicked: () -> Unit,
|
||||||
) {
|
) {
|
||||||
|
@ -65,8 +67,10 @@ fun LibraryComfortableGrid(
|
||||||
item = libraryItem,
|
item = libraryItem,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
showContinueReadingButton = showContinueReadingButton,
|
||||||
onLongClick = { onLongClick(libraryItem.libraryManga) },
|
onLongClick = { onLongClick(libraryItem.libraryManga) },
|
||||||
onClick = { onClick(libraryItem.libraryManga) },
|
onClick = { onClick(libraryItem.libraryManga) },
|
||||||
|
onClickContinueReading = { onClickContinueReading(libraryItem.libraryManga) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,13 @@ fun LibraryCompactGrid(
|
||||||
showUnreadBadges: Boolean,
|
showUnreadBadges: Boolean,
|
||||||
showLocalBadges: Boolean,
|
showLocalBadges: Boolean,
|
||||||
showLanguageBadges: Boolean,
|
showLanguageBadges: Boolean,
|
||||||
|
showContinueReadingButton: Boolean,
|
||||||
columns: Int,
|
columns: Int,
|
||||||
contentPadding: PaddingValues,
|
contentPadding: PaddingValues,
|
||||||
selection: List<LibraryManga>,
|
selection: List<LibraryManga>,
|
||||||
onClick: (LibraryManga) -> Unit,
|
onClick: (LibraryManga) -> Unit,
|
||||||
onLongClick: (LibraryManga) -> Unit,
|
onLongClick: (LibraryManga) -> Unit,
|
||||||
|
onClickContinueReading: (LibraryManga) -> Unit,
|
||||||
searchQuery: String?,
|
searchQuery: String?,
|
||||||
onGlobalSearchClicked: () -> Unit,
|
onGlobalSearchClicked: () -> Unit,
|
||||||
) {
|
) {
|
||||||
|
@ -66,8 +68,10 @@ fun LibraryCompactGrid(
|
||||||
item = libraryItem,
|
item = libraryItem,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
showContinueReadingButton = showContinueReadingButton,
|
||||||
onLongClick = { onLongClick(libraryItem.libraryManga) },
|
onLongClick = { onLongClick(libraryItem.libraryManga) },
|
||||||
onClick = { onClick(libraryItem.libraryManga) },
|
onClick = { onClick(libraryItem.libraryManga) },
|
||||||
|
onClickContinueReading = { onClickContinueReading(libraryItem.libraryManga) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ fun LibraryContent(
|
||||||
showMangaCount: Boolean,
|
showMangaCount: Boolean,
|
||||||
onChangeCurrentPage: (Int) -> Unit,
|
onChangeCurrentPage: (Int) -> Unit,
|
||||||
onMangaClicked: (Long) -> Unit,
|
onMangaClicked: (Long) -> Unit,
|
||||||
|
onContinueReadingClicked: (LibraryManga) -> Unit,
|
||||||
onToggleSelection: (LibraryManga) -> Unit,
|
onToggleSelection: (LibraryManga) -> Unit,
|
||||||
onToggleRangeSelection: (LibraryManga) -> Unit,
|
onToggleRangeSelection: (LibraryManga) -> Unit,
|
||||||
onRefresh: (Category?) -> Boolean,
|
onRefresh: (Category?) -> Boolean,
|
||||||
|
@ -49,6 +50,7 @@ fun LibraryContent(
|
||||||
showUnreadBadges: Boolean,
|
showUnreadBadges: Boolean,
|
||||||
showLocalBadges: Boolean,
|
showLocalBadges: Boolean,
|
||||||
showLanguageBadges: Boolean,
|
showLanguageBadges: Boolean,
|
||||||
|
showContinueReadingButton: Boolean,
|
||||||
isDownloadOnly: Boolean,
|
isDownloadOnly: Boolean,
|
||||||
isIncognitoMode: Boolean,
|
isIncognitoMode: Boolean,
|
||||||
) {
|
) {
|
||||||
|
@ -88,6 +90,9 @@ fun LibraryContent(
|
||||||
val onLongClickManga = { manga: LibraryManga ->
|
val onLongClickManga = { manga: LibraryManga ->
|
||||||
onToggleRangeSelection(manga)
|
onToggleRangeSelection(manga)
|
||||||
}
|
}
|
||||||
|
val onClickContinueReading = { manga: LibraryManga ->
|
||||||
|
onContinueReadingClicked(manga)
|
||||||
|
}
|
||||||
|
|
||||||
SwipeRefresh(
|
SwipeRefresh(
|
||||||
refreshing = isRefreshing,
|
refreshing = isRefreshing,
|
||||||
|
@ -115,8 +120,10 @@ fun LibraryContent(
|
||||||
showUnreadBadges = showUnreadBadges,
|
showUnreadBadges = showUnreadBadges,
|
||||||
showLocalBadges = showLocalBadges,
|
showLocalBadges = showLocalBadges,
|
||||||
showLanguageBadges = showLanguageBadges,
|
showLanguageBadges = showLanguageBadges,
|
||||||
|
showContinueReadingButton = showContinueReadingButton,
|
||||||
onClickManga = onClickManga,
|
onClickManga = onClickManga,
|
||||||
onLongClickManga = onLongClickManga,
|
onLongClickManga = onLongClickManga,
|
||||||
|
onClickContinueReading = onClickContinueReading,
|
||||||
onGlobalSearchClicked = onGlobalSearchClicked,
|
onGlobalSearchClicked = onGlobalSearchClicked,
|
||||||
searchQuery = state.searchQuery,
|
searchQuery = state.searchQuery,
|
||||||
)
|
)
|
||||||
|
|
|
@ -27,10 +27,12 @@ fun LibraryList(
|
||||||
showUnreadBadges: Boolean,
|
showUnreadBadges: Boolean,
|
||||||
showLocalBadges: Boolean,
|
showLocalBadges: Boolean,
|
||||||
showLanguageBadges: Boolean,
|
showLanguageBadges: Boolean,
|
||||||
|
showContinueReadingButton: Boolean,
|
||||||
contentPadding: PaddingValues,
|
contentPadding: PaddingValues,
|
||||||
selection: List<LibraryManga>,
|
selection: List<LibraryManga>,
|
||||||
onClick: (LibraryManga) -> Unit,
|
onClick: (LibraryManga) -> Unit,
|
||||||
onLongClick: (LibraryManga) -> Unit,
|
onLongClick: (LibraryManga) -> Unit,
|
||||||
|
onClickContinueReading: (LibraryManga) -> Unit,
|
||||||
searchQuery: String?,
|
searchQuery: String?,
|
||||||
onGlobalSearchClicked: () -> Unit,
|
onGlobalSearchClicked: () -> Unit,
|
||||||
) {
|
) {
|
||||||
|
@ -72,8 +74,10 @@ fun LibraryList(
|
||||||
UnreadBadge(enabled = showUnreadBadges, item = libraryItem)
|
UnreadBadge(enabled = showUnreadBadges, item = libraryItem)
|
||||||
LanguageBadge(showLanguage = showLanguageBadges, showLocal = showLocalBadges, item = libraryItem)
|
LanguageBadge(showLanguage = showLanguageBadges, showLocal = showLocalBadges, item = libraryItem)
|
||||||
},
|
},
|
||||||
|
showContinueReadingButton = showContinueReadingButton,
|
||||||
onLongClick = { onLongClick(libraryItem.libraryManga) },
|
onLongClick = { onLongClick(libraryItem.libraryManga) },
|
||||||
onClick = { onClick(libraryItem.libraryManga) },
|
onClick = { onClick(libraryItem.libraryManga) },
|
||||||
|
onClickContinueReading = { onClickContinueReading(libraryItem.libraryManga) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,10 @@ fun LibraryPager(
|
||||||
showUnreadBadges: Boolean,
|
showUnreadBadges: Boolean,
|
||||||
showLocalBadges: Boolean,
|
showLocalBadges: Boolean,
|
||||||
showLanguageBadges: Boolean,
|
showLanguageBadges: Boolean,
|
||||||
|
showContinueReadingButton: Boolean,
|
||||||
onClickManga: (LibraryManga) -> Unit,
|
onClickManga: (LibraryManga) -> Unit,
|
||||||
onLongClickManga: (LibraryManga) -> Unit,
|
onLongClickManga: (LibraryManga) -> Unit,
|
||||||
|
onClickContinueReading: (LibraryManga) -> Unit,
|
||||||
) {
|
) {
|
||||||
HorizontalPager(
|
HorizontalPager(
|
||||||
count = pageCount,
|
count = pageCount,
|
||||||
|
@ -64,10 +66,12 @@ fun LibraryPager(
|
||||||
showUnreadBadges = showUnreadBadges,
|
showUnreadBadges = showUnreadBadges,
|
||||||
showLocalBadges = showLocalBadges,
|
showLocalBadges = showLocalBadges,
|
||||||
showLanguageBadges = showLanguageBadges,
|
showLanguageBadges = showLanguageBadges,
|
||||||
|
showContinueReadingButton = showContinueReadingButton,
|
||||||
contentPadding = contentPadding,
|
contentPadding = contentPadding,
|
||||||
selection = selectedManga,
|
selection = selectedManga,
|
||||||
onClick = onClickManga,
|
onClick = onClickManga,
|
||||||
onLongClick = onLongClickManga,
|
onLongClick = onLongClickManga,
|
||||||
|
onClickContinueReading = onClickContinueReading,
|
||||||
searchQuery = searchQuery,
|
searchQuery = searchQuery,
|
||||||
onGlobalSearchClicked = onGlobalSearchClicked,
|
onGlobalSearchClicked = onGlobalSearchClicked,
|
||||||
)
|
)
|
||||||
|
@ -80,11 +84,13 @@ fun LibraryPager(
|
||||||
showUnreadBadges = showUnreadBadges,
|
showUnreadBadges = showUnreadBadges,
|
||||||
showLocalBadges = showLocalBadges,
|
showLocalBadges = showLocalBadges,
|
||||||
showLanguageBadges = showLanguageBadges,
|
showLanguageBadges = showLanguageBadges,
|
||||||
|
showContinueReadingButton = showContinueReadingButton,
|
||||||
columns = columns,
|
columns = columns,
|
||||||
contentPadding = contentPadding,
|
contentPadding = contentPadding,
|
||||||
selection = selectedManga,
|
selection = selectedManga,
|
||||||
onClick = onClickManga,
|
onClick = onClickManga,
|
||||||
onLongClick = onLongClickManga,
|
onLongClick = onLongClickManga,
|
||||||
|
onClickContinueReading = onClickContinueReading,
|
||||||
searchQuery = searchQuery,
|
searchQuery = searchQuery,
|
||||||
onGlobalSearchClicked = onGlobalSearchClicked,
|
onGlobalSearchClicked = onGlobalSearchClicked,
|
||||||
)
|
)
|
||||||
|
@ -96,10 +102,12 @@ fun LibraryPager(
|
||||||
showUnreadBadges = showUnreadBadges,
|
showUnreadBadges = showUnreadBadges,
|
||||||
showLocalBadges = showLocalBadges,
|
showLocalBadges = showLocalBadges,
|
||||||
showLanguageBadges = showLanguageBadges,
|
showLanguageBadges = showLanguageBadges,
|
||||||
|
showContinueReadingButton = showContinueReadingButton,
|
||||||
columns = columns,
|
columns = columns,
|
||||||
contentPadding = contentPadding,
|
contentPadding = contentPadding,
|
||||||
selection = selectedManga,
|
selection = selectedManga,
|
||||||
onClick = onClickManga,
|
onClick = onClickManga,
|
||||||
|
onClickContinueReading = onClickContinueReading,
|
||||||
onLongClick = onLongClickManga,
|
onLongClick = onLongClickManga,
|
||||||
searchQuery = searchQuery,
|
searchQuery = searchQuery,
|
||||||
onGlobalSearchClicked = onGlobalSearchClicked,
|
onGlobalSearchClicked = onGlobalSearchClicked,
|
||||||
|
|
|
@ -9,6 +9,8 @@ import androidx.compose.ui.platform.LocalContext
|
||||||
import com.bluelinelabs.conductor.ControllerChangeHandler
|
import com.bluelinelabs.conductor.ControllerChangeHandler
|
||||||
import com.bluelinelabs.conductor.ControllerChangeType
|
import com.bluelinelabs.conductor.ControllerChangeType
|
||||||
import eu.kanade.core.prefs.CheckboxState
|
import eu.kanade.core.prefs.CheckboxState
|
||||||
|
import eu.kanade.domain.chapter.model.Chapter
|
||||||
|
import eu.kanade.domain.library.model.LibraryManga
|
||||||
import eu.kanade.domain.manga.model.Manga
|
import eu.kanade.domain.manga.model.Manga
|
||||||
import eu.kanade.domain.manga.model.isLocal
|
import eu.kanade.domain.manga.model.isLocal
|
||||||
import eu.kanade.domain.manga.model.toDbManga
|
import eu.kanade.domain.manga.model.toDbManga
|
||||||
|
@ -26,6 +28,7 @@ import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
|
||||||
import eu.kanade.tachiyomi.ui.category.CategoryController
|
import eu.kanade.tachiyomi.ui.category.CategoryController
|
||||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
|
@ -50,6 +53,7 @@ class LibraryController(
|
||||||
LibraryScreen(
|
LibraryScreen(
|
||||||
presenter = presenter,
|
presenter = presenter,
|
||||||
onMangaClicked = ::openManga,
|
onMangaClicked = ::openManga,
|
||||||
|
onContinueReadingClicked = ::continueReading,
|
||||||
onGlobalSearchClicked = {
|
onGlobalSearchClicked = {
|
||||||
router.pushController(GlobalSearchController(presenter.searchQuery))
|
router.pushController(GlobalSearchController(presenter.searchQuery))
|
||||||
},
|
},
|
||||||
|
@ -196,6 +200,19 @@ class LibraryController(
|
||||||
router.pushController(MangaController(mangaId))
|
router.pushController(MangaController(mangaId))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun continueReading(libraryManga: LibraryManga) {
|
||||||
|
viewScope.launchIO {
|
||||||
|
val chapter = presenter.getNextUnreadChapter(libraryManga.manga)
|
||||||
|
if (chapter != null) openChapter(chapter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openChapter(chapter: Chapter) {
|
||||||
|
activity?.run {
|
||||||
|
startActivity(ReaderActivity.newIntent(this, chapter.mangaId, chapter.id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear all of the manga currently selected, and
|
* Clear all of the manga currently selected, and
|
||||||
* invalidate the action mode to revert the top toolbar
|
* invalidate the action mode to revert the top toolbar
|
||||||
|
|
|
@ -17,7 +17,9 @@ import eu.kanade.domain.base.BasePreferences
|
||||||
import eu.kanade.domain.category.interactor.GetCategories
|
import eu.kanade.domain.category.interactor.GetCategories
|
||||||
import eu.kanade.domain.category.interactor.SetMangaCategories
|
import eu.kanade.domain.category.interactor.SetMangaCategories
|
||||||
import eu.kanade.domain.category.model.Category
|
import eu.kanade.domain.category.model.Category
|
||||||
|
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
||||||
import eu.kanade.domain.chapter.interactor.SetReadStatus
|
import eu.kanade.domain.chapter.interactor.SetReadStatus
|
||||||
|
import eu.kanade.domain.chapter.model.Chapter
|
||||||
import eu.kanade.domain.chapter.model.toDbChapter
|
import eu.kanade.domain.chapter.model.toDbChapter
|
||||||
import eu.kanade.domain.history.interactor.GetNextChapters
|
import eu.kanade.domain.history.interactor.GetNextChapters
|
||||||
import eu.kanade.domain.library.model.LibraryManga
|
import eu.kanade.domain.library.model.LibraryManga
|
||||||
|
@ -44,6 +46,7 @@ import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||||
|
import eu.kanade.tachiyomi.util.chapter.getNextUnread
|
||||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||||
import eu.kanade.tachiyomi.util.lang.launchNonCancellable
|
import eu.kanade.tachiyomi.util.lang.launchNonCancellable
|
||||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||||
|
@ -76,9 +79,10 @@ typealias LibraryMap = Map<Long, List<LibraryItem>>
|
||||||
class LibraryPresenter(
|
class LibraryPresenter(
|
||||||
private val state: LibraryStateImpl = LibraryState() as LibraryStateImpl,
|
private val state: LibraryStateImpl = LibraryState() as LibraryStateImpl,
|
||||||
private val getLibraryManga: GetLibraryManga = Injekt.get(),
|
private val getLibraryManga: GetLibraryManga = Injekt.get(),
|
||||||
private val getTracksPerManga: GetTracksPerManga = Injekt.get(),
|
|
||||||
private val getCategories: GetCategories = Injekt.get(),
|
private val getCategories: GetCategories = Injekt.get(),
|
||||||
|
private val getTracksPerManga: GetTracksPerManga = Injekt.get(),
|
||||||
private val getNextChapters: GetNextChapters = Injekt.get(),
|
private val getNextChapters: GetNextChapters = Injekt.get(),
|
||||||
|
private val getChaptersByMangaId: GetChapterByMangaId = Injekt.get(),
|
||||||
private val setReadStatus: SetReadStatus = Injekt.get(),
|
private val setReadStatus: SetReadStatus = Injekt.get(),
|
||||||
private val updateManga: UpdateManga = Injekt.get(),
|
private val updateManga: UpdateManga = Injekt.get(),
|
||||||
private val setMangaCategories: SetMangaCategories = Injekt.get(),
|
private val setMangaCategories: SetMangaCategories = Injekt.get(),
|
||||||
|
@ -105,6 +109,8 @@ class LibraryPresenter(
|
||||||
|
|
||||||
var activeCategory: Int by libraryPreferences.lastUsedCategory().asState()
|
var activeCategory: Int by libraryPreferences.lastUsedCategory().asState()
|
||||||
|
|
||||||
|
val showContinueReadingButton by libraryPreferences.showContinueReadingButton().asState()
|
||||||
|
|
||||||
val isDownloadOnly: Boolean by preferences.downloadedOnly().asState()
|
val isDownloadOnly: Boolean by preferences.downloadedOnly().asState()
|
||||||
val isIncognitoMode: Boolean by preferences.incognitoMode().asState()
|
val isIncognitoMode: Boolean by preferences.incognitoMode().asState()
|
||||||
|
|
||||||
|
@ -389,6 +395,10 @@ class LibraryPresenter(
|
||||||
.reduce { set1, set2 -> set1.intersect(set2) }
|
.reduce { set1, set2 -> set1.intersect(set2) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getNextUnreadChapter(manga: Manga): Chapter? {
|
||||||
|
return getChaptersByMangaId.await(manga.id).getNextUnread(manga, downloadManager)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the mix (non-common) categories for the given list of manga.
|
* Returns the mix (non-common) categories for the given list of manga.
|
||||||
*
|
*
|
||||||
|
|
|
@ -282,12 +282,14 @@ class LibrarySettingsSheet(
|
||||||
private val displayGroup: DisplayGroup
|
private val displayGroup: DisplayGroup
|
||||||
private val badgeGroup: BadgeGroup
|
private val badgeGroup: BadgeGroup
|
||||||
private val tabsGroup: TabsGroup
|
private val tabsGroup: TabsGroup
|
||||||
|
private val otherGroup: OtherGroup
|
||||||
|
|
||||||
init {
|
init {
|
||||||
displayGroup = DisplayGroup()
|
displayGroup = DisplayGroup()
|
||||||
badgeGroup = BadgeGroup()
|
badgeGroup = BadgeGroup()
|
||||||
tabsGroup = TabsGroup()
|
tabsGroup = TabsGroup()
|
||||||
setGroups(listOf(displayGroup, badgeGroup, tabsGroup))
|
otherGroup = OtherGroup()
|
||||||
|
setGroups(listOf(displayGroup, badgeGroup, tabsGroup, otherGroup))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refreshes Display Setting selections
|
// Refreshes Display Setting selections
|
||||||
|
@ -408,6 +410,28 @@ class LibrarySettingsSheet(
|
||||||
adapter.notifyItemChanged(item)
|
adapter.notifyItemChanged(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inner class OtherGroup : Group {
|
||||||
|
private val showContinueReadingButton = Item.CheckboxGroup(R.string.action_display_show_continue_reading_button, this)
|
||||||
|
|
||||||
|
override val header = Item.Header(R.string.other_header)
|
||||||
|
override val items = listOf(showContinueReadingButton)
|
||||||
|
override val footer = null
|
||||||
|
|
||||||
|
override fun initModels() {
|
||||||
|
showContinueReadingButton.checked = libraryPreferences.showContinueReadingButton().get()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onItemClicked(item: Item) {
|
||||||
|
item as Item.CheckboxGroup
|
||||||
|
item.checked = !item.checked
|
||||||
|
when (item) {
|
||||||
|
showContinueReadingButton -> libraryPreferences.showContinueReadingButton().set(item.checked)
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
adapter.notifyItemChanged(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open inner class Settings(context: Context, attrs: AttributeSet?) :
|
open inner class Settings(context: Context, attrs: AttributeSet?) :
|
||||||
|
|
|
@ -16,6 +16,7 @@ import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
|
||||||
import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
|
import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
|
||||||
import eu.kanade.domain.chapter.interactor.UpdateChapter
|
import eu.kanade.domain.chapter.interactor.UpdateChapter
|
||||||
import eu.kanade.domain.chapter.model.ChapterUpdate
|
import eu.kanade.domain.chapter.model.ChapterUpdate
|
||||||
|
import eu.kanade.domain.chapter.model.applyFilters
|
||||||
import eu.kanade.domain.chapter.model.toDbChapter
|
import eu.kanade.domain.chapter.model.toDbChapter
|
||||||
import eu.kanade.domain.download.service.DownloadPreferences
|
import eu.kanade.domain.download.service.DownloadPreferences
|
||||||
import eu.kanade.domain.library.service.LibraryPreferences
|
import eu.kanade.domain.library.service.LibraryPreferences
|
||||||
|
@ -23,8 +24,6 @@ import eu.kanade.domain.manga.interactor.GetDuplicateLibraryManga
|
||||||
import eu.kanade.domain.manga.interactor.GetMangaWithChapters
|
import eu.kanade.domain.manga.interactor.GetMangaWithChapters
|
||||||
import eu.kanade.domain.manga.interactor.SetMangaChapterFlags
|
import eu.kanade.domain.manga.interactor.SetMangaChapterFlags
|
||||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||||
import eu.kanade.domain.manga.model.TriStateFilter
|
|
||||||
import eu.kanade.domain.manga.model.isLocal
|
|
||||||
import eu.kanade.domain.manga.model.toDbManga
|
import eu.kanade.domain.manga.model.toDbManga
|
||||||
import eu.kanade.domain.track.interactor.DeleteTrack
|
import eu.kanade.domain.track.interactor.DeleteTrack
|
||||||
import eu.kanade.domain.track.interactor.GetTracks
|
import eu.kanade.domain.track.interactor.GetTracks
|
||||||
|
@ -45,6 +44,7 @@ import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||||
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
|
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
|
||||||
import eu.kanade.tachiyomi.util.chapter.getChapterSort
|
import eu.kanade.tachiyomi.util.chapter.getChapterSort
|
||||||
|
import eu.kanade.tachiyomi.util.chapter.getNextUnread
|
||||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||||
import eu.kanade.tachiyomi.util.lang.launchNonCancellable
|
import eu.kanade.tachiyomi.util.lang.launchNonCancellable
|
||||||
import eu.kanade.tachiyomi.util.lang.toRelativeString
|
import eu.kanade.tachiyomi.util.lang.toRelativeString
|
||||||
|
@ -579,13 +579,7 @@ class MangaPresenter(
|
||||||
*/
|
*/
|
||||||
fun getNextUnreadChapter(): DomainChapter? {
|
fun getNextUnreadChapter(): DomainChapter? {
|
||||||
val successState = successState ?: return null
|
val successState = successState ?: return null
|
||||||
return successState.processedChapters.map { it.chapter }.let { chapters ->
|
return successState.chapters.getNextUnread(successState.manga)
|
||||||
if (successState.manga.sortDescending()) {
|
|
||||||
chapters.findLast { !it.read }
|
|
||||||
} else {
|
|
||||||
chapters.find { !it.read }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getUnreadChapters(): List<DomainChapter> {
|
fun getUnreadChapters(): List<DomainChapter> {
|
||||||
|
@ -1092,40 +1086,6 @@ sealed class MangaScreenState {
|
||||||
|
|
||||||
val processedChapters: Sequence<ChapterItem>
|
val processedChapters: Sequence<ChapterItem>
|
||||||
get() = chapters.applyFilters(manga)
|
get() = chapters.applyFilters(manga)
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies the view filters to the list of chapters obtained from the database.
|
|
||||||
* @return an observable of the list of chapters filtered and sorted.
|
|
||||||
*/
|
|
||||||
private fun List<ChapterItem>.applyFilters(manga: DomainManga): Sequence<ChapterItem> {
|
|
||||||
val isLocalManga = manga.isLocal()
|
|
||||||
val unreadFilter = manga.unreadFilter
|
|
||||||
val downloadedFilter = manga.downloadedFilter
|
|
||||||
val bookmarkedFilter = manga.bookmarkedFilter
|
|
||||||
return asSequence()
|
|
||||||
.filter { (chapter) ->
|
|
||||||
when (unreadFilter) {
|
|
||||||
TriStateFilter.DISABLED -> true
|
|
||||||
TriStateFilter.ENABLED_IS -> !chapter.read
|
|
||||||
TriStateFilter.ENABLED_NOT -> chapter.read
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.filter { (chapter) ->
|
|
||||||
when (bookmarkedFilter) {
|
|
||||||
TriStateFilter.DISABLED -> true
|
|
||||||
TriStateFilter.ENABLED_IS -> chapter.bookmark
|
|
||||||
TriStateFilter.ENABLED_NOT -> !chapter.bookmark
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.filter {
|
|
||||||
when (downloadedFilter) {
|
|
||||||
TriStateFilter.DISABLED -> true
|
|
||||||
TriStateFilter.ENABLED_IS -> it.isDownloaded || isLocalManga
|
|
||||||
TriStateFilter.ENABLED_NOT -> !it.isDownloaded && !isLocalManga
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.sortedWith { (chapter1), (chapter2) -> getChapterSort(manga).invoke(chapter1, chapter2) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package eu.kanade.tachiyomi.util.chapter
|
||||||
|
|
||||||
|
import eu.kanade.domain.chapter.model.Chapter
|
||||||
|
import eu.kanade.domain.chapter.model.applyFilters
|
||||||
|
import eu.kanade.domain.manga.model.Manga
|
||||||
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||||
|
import eu.kanade.tachiyomi.ui.manga.ChapterItem
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets next unread chapter with filters and sorting applied
|
||||||
|
*/
|
||||||
|
fun List<Chapter>.getNextUnread(manga: Manga, downloadManager: DownloadManager): Chapter? {
|
||||||
|
return applyFilters(manga, downloadManager).let { chapters ->
|
||||||
|
if (manga.sortDescending()) {
|
||||||
|
chapters.findLast { !it.read }
|
||||||
|
} else {
|
||||||
|
chapters.find { !it.read }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets next unread chapter with filters and sorting applied
|
||||||
|
*/
|
||||||
|
fun List<ChapterItem>.getNextUnread(manga: Manga): Chapter? {
|
||||||
|
return applyFilters(manga).let { chapters ->
|
||||||
|
if (manga.sortDescending()) {
|
||||||
|
chapters.findLast { !it.chapter.read }
|
||||||
|
} else {
|
||||||
|
chapters.find { !it.chapter.read }
|
||||||
|
}
|
||||||
|
}?.chapter
|
||||||
|
}
|
|
@ -108,6 +108,7 @@
|
||||||
<string name="action_display_language_badge">Language</string>
|
<string name="action_display_language_badge">Language</string>
|
||||||
<string name="action_display_show_tabs">Show category tabs</string>
|
<string name="action_display_show_tabs">Show category tabs</string>
|
||||||
<string name="action_display_show_number_of_items">Show number of items</string>
|
<string name="action_display_show_number_of_items">Show number of items</string>
|
||||||
|
<string name="action_display_show_continue_reading_button">Show continue reading button</string>
|
||||||
<string name="action_disable">Disable</string>
|
<string name="action_disable">Disable</string>
|
||||||
<string name="action_pin">Pin</string>
|
<string name="action_pin">Pin</string>
|
||||||
<string name="action_unpin">Unpin</string>
|
<string name="action_unpin">Unpin</string>
|
||||||
|
@ -579,6 +580,7 @@
|
||||||
<string name="downloaded_chapters">Downloaded chapters</string>
|
<string name="downloaded_chapters">Downloaded chapters</string>
|
||||||
<string name="badges_header">Badges</string>
|
<string name="badges_header">Badges</string>
|
||||||
<string name="tabs_header">Tabs</string>
|
<string name="tabs_header">Tabs</string>
|
||||||
|
<string name="other_header">Other</string>
|
||||||
|
|
||||||
<!-- Catalogue fragment -->
|
<!-- Catalogue fragment -->
|
||||||
<!-- missing prompt after Compose rewrite #7901 -->
|
<!-- missing prompt after Compose rewrite #7901 -->
|
||||||
|
|
Reference in a new issue