mirror of
https://github.com/mihonapp/mihon.git
synced 2025-11-17 22:47:29 +01:00
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:
@@ -9,6 +9,8 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import com.bluelinelabs.conductor.ControllerChangeHandler
|
||||
import com.bluelinelabs.conductor.ControllerChangeType
|
||||
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.isLocal
|
||||
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.main.MainActivity
|
||||
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.launchUI
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
@@ -50,6 +53,7 @@ class LibraryController(
|
||||
LibraryScreen(
|
||||
presenter = presenter,
|
||||
onMangaClicked = ::openManga,
|
||||
onContinueReadingClicked = ::continueReading,
|
||||
onGlobalSearchClicked = {
|
||||
router.pushController(GlobalSearchController(presenter.searchQuery))
|
||||
},
|
||||
@@ -196,6 +200,19 @@ class LibraryController(
|
||||
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
|
||||
* 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.SetMangaCategories
|
||||
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.model.Chapter
|
||||
import eu.kanade.domain.chapter.model.toDbChapter
|
||||
import eu.kanade.domain.history.interactor.GetNextChapters
|
||||
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.online.HttpSource
|
||||
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.launchNonCancellable
|
||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||
@@ -76,9 +79,10 @@ typealias LibraryMap = Map<Long, List<LibraryItem>>
|
||||
class LibraryPresenter(
|
||||
private val state: LibraryStateImpl = LibraryState() as LibraryStateImpl,
|
||||
private val getLibraryManga: GetLibraryManga = Injekt.get(),
|
||||
private val getTracksPerManga: GetTracksPerManga = Injekt.get(),
|
||||
private val getCategories: GetCategories = Injekt.get(),
|
||||
private val getTracksPerManga: GetTracksPerManga = Injekt.get(),
|
||||
private val getNextChapters: GetNextChapters = Injekt.get(),
|
||||
private val getChaptersByMangaId: GetChapterByMangaId = Injekt.get(),
|
||||
private val setReadStatus: SetReadStatus = Injekt.get(),
|
||||
private val updateManga: UpdateManga = Injekt.get(),
|
||||
private val setMangaCategories: SetMangaCategories = Injekt.get(),
|
||||
@@ -105,6 +109,8 @@ class LibraryPresenter(
|
||||
|
||||
var activeCategory: Int by libraryPreferences.lastUsedCategory().asState()
|
||||
|
||||
val showContinueReadingButton by libraryPreferences.showContinueReadingButton().asState()
|
||||
|
||||
val isDownloadOnly: Boolean by preferences.downloadedOnly().asState()
|
||||
val isIncognitoMode: Boolean by preferences.incognitoMode().asState()
|
||||
|
||||
@@ -389,6 +395,10 @@ class LibraryPresenter(
|
||||
.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.
|
||||
*
|
||||
|
||||
@@ -282,12 +282,14 @@ class LibrarySettingsSheet(
|
||||
private val displayGroup: DisplayGroup
|
||||
private val badgeGroup: BadgeGroup
|
||||
private val tabsGroup: TabsGroup
|
||||
private val otherGroup: OtherGroup
|
||||
|
||||
init {
|
||||
displayGroup = DisplayGroup()
|
||||
badgeGroup = BadgeGroup()
|
||||
tabsGroup = TabsGroup()
|
||||
setGroups(listOf(displayGroup, badgeGroup, tabsGroup))
|
||||
otherGroup = OtherGroup()
|
||||
setGroups(listOf(displayGroup, badgeGroup, tabsGroup, otherGroup))
|
||||
}
|
||||
|
||||
// Refreshes Display Setting selections
|
||||
@@ -408,6 +410,28 @@ class LibrarySettingsSheet(
|
||||
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?) :
|
||||
|
||||
@@ -16,6 +16,7 @@ import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
|
||||
import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
|
||||
import eu.kanade.domain.chapter.interactor.UpdateChapter
|
||||
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.download.service.DownloadPreferences
|
||||
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.SetMangaChapterFlags
|
||||
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.track.interactor.DeleteTrack
|
||||
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.manga.track.TrackItem
|
||||
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.launchNonCancellable
|
||||
import eu.kanade.tachiyomi.util.lang.toRelativeString
|
||||
@@ -579,13 +579,7 @@ class MangaPresenter(
|
||||
*/
|
||||
fun getNextUnreadChapter(): DomainChapter? {
|
||||
val successState = successState ?: return null
|
||||
return successState.processedChapters.map { it.chapter }.let { chapters ->
|
||||
if (successState.manga.sortDescending()) {
|
||||
chapters.findLast { !it.read }
|
||||
} else {
|
||||
chapters.find { !it.read }
|
||||
}
|
||||
}
|
||||
return successState.chapters.getNextUnread(successState.manga)
|
||||
}
|
||||
|
||||
fun getUnreadChapters(): List<DomainChapter> {
|
||||
@@ -1092,40 +1086,6 @@ sealed class MangaScreenState {
|
||||
|
||||
val processedChapters: Sequence<ChapterItem>
|
||||
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) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user