Seperate mark duplicate read chapters as read behaviors as options (mihonapp/mihon#1870)
(cherry picked from commit 8a3b6107755c768924a31c2b58d705296133839c)
This commit is contained in:
parent
81fac93d94
commit
6fa34ab5e9
8 changed files with 87 additions and 87 deletions
|
|
@ -21,7 +21,7 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co
|
|||
- Add private tracking support for Kitsu ([@MajorTanya](https://github.com/MajorTanya)) ([#1774](https://github.com/mihonapp/mihon/pull/1774))
|
||||
- Add option to export minimal library information to a CSV file ([@Animeboynz](https://github.com/Animeboynz), [@AntsyLich](https://github.com/AntsyLich)) ([#1161](https://github.com/mihonapp/mihon/pull/1161))
|
||||
- Add back support for drag-and-drop category reordering ([@cuong-tran](https://github.com/cuong-tran)) ([#1427](https://github.com/mihonapp/mihon/pull/1427))
|
||||
- Add option to mark duplicate read chapters as read
|
||||
- Add option to mark duplicate read chapters as read after library update or while reading ([@AntsyLich](https://github.com/AntsyLich)) ([#1785](https://github.com/mihonapp/mihon/pull/1785), [#1791](https://github.com/mihonapp/mihon/pull/1791), [#1870](https://github.com/mihonapp/mihon/pull/1870))
|
||||
- Display staff information on Anilist tracker search results ([@NarwhalHorns](https://github.com/NarwhalHorns)) ([#1810](https://github.com/mihonapp/mihon/pull/1810))
|
||||
|
||||
### Changed
|
||||
|
|
@ -32,6 +32,7 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co
|
|||
- Now showing manga starting dates in search
|
||||
- Reduced request load by 2-4x in certain situations
|
||||
- Bump default user agent
|
||||
- Changed the label of chapter swipe settings and renamed the group to "Behavior" ([@AntsyLich](https://github.com/AntsyLich)) ([#1870](https://github.com/mihonapp/mihon/pull/1870))
|
||||
|
||||
### Fixed
|
||||
- Fix MAL `main_picture` nullability breaking search if a result doesn't have a cover set ([@MajorTanya](https://github.com/MajorTanya)) ([#1618](https://github.com/mihonapp/mihon/pull/1618))
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import eu.kanade.tachiyomi.data.download.DownloadProvider
|
|||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
|
||||
import exh.source.isEhBasedManga
|
||||
import tachiyomi.data.chapter.ChapterSanitizer
|
||||
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
|
||||
|
|
@ -21,6 +20,7 @@ import tachiyomi.domain.chapter.model.NoChaptersException
|
|||
import tachiyomi.domain.chapter.model.toChapterUpdate
|
||||
import tachiyomi.domain.chapter.repository.ChapterRepository
|
||||
import tachiyomi.domain.chapter.service.ChapterRecognition
|
||||
import tachiyomi.domain.library.service.LibraryPreferences
|
||||
import tachiyomi.domain.manga.model.Manga
|
||||
import tachiyomi.source.local.isLocal
|
||||
import java.lang.Long.max
|
||||
|
|
@ -36,7 +36,7 @@ class SyncChaptersWithSource(
|
|||
private val updateChapter: UpdateChapter,
|
||||
private val getChaptersByMangaId: GetChaptersByMangaId,
|
||||
private val getExcludedScanlators: GetExcludedScanlators,
|
||||
private val readerPreferences: ReaderPreferences,
|
||||
private val libraryPreferences: LibraryPreferences,
|
||||
) {
|
||||
|
||||
/**
|
||||
|
|
@ -176,7 +176,8 @@ class SyncChaptersWithSource(
|
|||
val deletedChapterNumberDateFetchMap = removedChapters.sortedByDescending { it.dateFetch }
|
||||
.associate { it.chapterNumber to it.dateFetch }
|
||||
|
||||
val markDuplicateAsRead = readerPreferences.markDuplicateReadChapterAsRead().get()
|
||||
val markDuplicateAsRead = libraryPreferences.markDuplicateReadChapterAsRead().get()
|
||||
.contains(LibraryPreferences.MARK_DUPLICATE_CHAPTER_READ_NEW)
|
||||
|
||||
// Date fetch is set in such a way that the upper ones will have bigger value than the lower ones
|
||||
// Sources MUST return the chapters from most to less recent, which is common.
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_HAS_U
|
|||
import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_NON_COMPLETED
|
||||
import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_NON_READ
|
||||
import tachiyomi.domain.library.service.LibraryPreferences.Companion.MANGA_OUTSIDE_RELEASE_PERIOD
|
||||
import tachiyomi.domain.library.service.LibraryPreferences.Companion.MARK_DUPLICATE_CHAPTER_READ_EXISTING
|
||||
import tachiyomi.domain.library.service.LibraryPreferences.Companion.MARK_DUPLICATE_CHAPTER_READ_NEW
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.i18n.kmk.KMR
|
||||
import tachiyomi.i18n.sy.SYMR
|
||||
|
|
@ -66,7 +68,7 @@ object SettingsLibraryScreen : SearchableSettings {
|
|||
return listOf(
|
||||
getCategoriesGroup(LocalNavigator.currentOrThrow, allCategories, libraryPreferences),
|
||||
getGlobalUpdateGroup(allCategories, libraryPreferences),
|
||||
getChapterSwipeActionsGroup(libraryPreferences),
|
||||
getBehaviorGroup(libraryPreferences),
|
||||
// SY -->
|
||||
getSortingCategory(LocalNavigator.currentOrThrow, libraryPreferences),
|
||||
getMigrationCategory(unsortedPreferences),
|
||||
|
|
@ -242,11 +244,11 @@ object SettingsLibraryScreen : SearchableSettings {
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun getChapterSwipeActionsGroup(
|
||||
private fun getBehaviorGroup(
|
||||
libraryPreferences: LibraryPreferences,
|
||||
): Preference.PreferenceGroup {
|
||||
return Preference.PreferenceGroup(
|
||||
title = stringResource(MR.strings.pref_chapter_swipe),
|
||||
title = stringResource(MR.strings.pref_behavior),
|
||||
preferenceItems = persistentListOf(
|
||||
Preference.PreferenceItem.ListPreference(
|
||||
preference = libraryPreferences.swipeToStartAction(),
|
||||
|
|
@ -276,6 +278,16 @@ object SettingsLibraryScreen : SearchableSettings {
|
|||
),
|
||||
title = stringResource(MR.strings.pref_chapter_swipe_end),
|
||||
),
|
||||
Preference.PreferenceItem.MultiSelectListPreference(
|
||||
preference = libraryPreferences.markDuplicateReadChapterAsRead(),
|
||||
entries = persistentMapOf(
|
||||
MARK_DUPLICATE_CHAPTER_READ_EXISTING to
|
||||
stringResource(MR.strings.pref_mark_duplicate_read_chapter_read_existing),
|
||||
MARK_DUPLICATE_CHAPTER_READ_NEW to
|
||||
stringResource(MR.strings.pref_mark_duplicate_read_chapter_read_new),
|
||||
),
|
||||
title = stringResource(MR.strings.pref_mark_duplicate_read_chapter_read),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -228,21 +228,10 @@ object SettingsReaderScreen : SearchableSettings {
|
|||
preference = readerPreferences.skipDupe(),
|
||||
title = stringResource(MR.strings.pref_skip_dupe_chapters),
|
||||
),
|
||||
// SY -->
|
||||
Preference.PreferenceItem.SwitchPreference(
|
||||
preference = readerPreferences.markReadDupe(),
|
||||
title = stringResource(SYMR.strings.pref_mark_read_dupe_chapters),
|
||||
subtitle = stringResource(SYMR.strings.pref_mark_read_dupe_chapters_summary),
|
||||
),
|
||||
// SY <--
|
||||
Preference.PreferenceItem.SwitchPreference(
|
||||
preference = readerPreferences.alwaysShowChapterTransition(),
|
||||
title = stringResource(MR.strings.pref_always_show_chapter_transition),
|
||||
),
|
||||
Preference.PreferenceItem.SwitchPreference(
|
||||
preference = readerPreferences.markDuplicateReadChapterAsRead(),
|
||||
title = stringResource(MR.strings.pref_mark_duplicate_read_chapter_read),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import androidx.lifecycle.SavedStateHandle
|
|||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.domain.chapter.interactor.SetReadStatus
|
||||
import eu.kanade.domain.chapter.model.toDbChapter
|
||||
import eu.kanade.domain.manga.interactor.SetMangaViewerFlags
|
||||
import eu.kanade.domain.manga.model.readerOrientation
|
||||
|
|
@ -95,6 +94,7 @@ import tachiyomi.domain.download.service.DownloadPreferences
|
|||
import tachiyomi.domain.history.interactor.GetNextChapters
|
||||
import tachiyomi.domain.history.interactor.UpsertHistory
|
||||
import tachiyomi.domain.history.model.HistoryUpdate
|
||||
import tachiyomi.domain.library.service.LibraryPreferences
|
||||
import tachiyomi.domain.manga.interactor.GetFlatMetadataById
|
||||
import tachiyomi.domain.manga.interactor.GetManga
|
||||
import tachiyomi.domain.manga.interactor.GetMergedMangaById
|
||||
|
|
@ -129,14 +129,14 @@ class ReaderViewModel @JvmOverloads constructor(
|
|||
private val updateChapter: UpdateChapter = Injekt.get(),
|
||||
private val setMangaViewerFlags: SetMangaViewerFlags = Injekt.get(),
|
||||
private val getIncognitoState: GetIncognitoState = Injekt.get(),
|
||||
private val syncPreferences: SyncPreferences = Injekt.get(),
|
||||
private val libraryPreferences: LibraryPreferences = Injekt.get(),
|
||||
// SY -->
|
||||
private val syncPreferences: SyncPreferences = Injekt.get(),
|
||||
private val uiPreferences: UiPreferences = Injekt.get(),
|
||||
private val getFlatMetadataById: GetFlatMetadataById = Injekt.get(),
|
||||
private val getMergedMangaById: GetMergedMangaById = Injekt.get(),
|
||||
private val getMergedReferencesById: GetMergedReferencesById = Injekt.get(),
|
||||
private val getMergedChaptersByMangaId: GetMergedChaptersByMangaId = Injekt.get(),
|
||||
private val setReadStatus: SetReadStatus = Injekt.get(),
|
||||
// SY <--
|
||||
) : ViewModel() {
|
||||
|
||||
|
|
@ -702,35 +702,41 @@ class ReaderViewModel @JvmOverloads constructor(
|
|||
if (!incognitoMode && page.status != Page.State.ERROR) {
|
||||
readerChapter.chapter.last_page_read = pageIndex
|
||||
|
||||
if (readerChapter.pages?.lastIndex == pageIndex ||
|
||||
// SY -->
|
||||
if (
|
||||
readerChapter.pages?.lastIndex == pageIndex ||
|
||||
(hasExtraPage && readerChapter.pages?.lastIndex?.minus(1) == page.index)
|
||||
) {
|
||||
// SY <--
|
||||
) {
|
||||
updateChapterProgressOnComplete(readerChapter)
|
||||
|
||||
// SY -->
|
||||
// Check if syncing is enabled for chapter read:
|
||||
if (isSyncEnabled && syncTriggerOpt.syncOnChapterRead) {
|
||||
SyncDataJob.startNow(Injekt.get<Application>())
|
||||
}
|
||||
// SY <--
|
||||
}
|
||||
|
||||
updateChapter.await(
|
||||
ChapterUpdate(
|
||||
id = readerChapter.chapter.id!!,
|
||||
read = readerChapter.chapter.read,
|
||||
lastPageRead = readerChapter.chapter.last_page_read.toLong(),
|
||||
),
|
||||
)
|
||||
|
||||
// SY -->
|
||||
// Check if syncing is enabled for chapter open:
|
||||
if (isSyncEnabled && syncTriggerOpt.syncOnChapterOpen && readerChapter.chapter.last_page_read == 0) {
|
||||
SyncDataJob.startNow(Injekt.get<Application>())
|
||||
}
|
||||
// SY <--
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun updateChapterProgressOnComplete(readerChapter: ReaderChapter) {
|
||||
readerChapter.chapter.read = true
|
||||
// SY -->
|
||||
if (readerChapter.chapter.chapter_number >= 0 && readerPreferences.markReadDupe().get()) {
|
||||
getChaptersByMangaId.await(manga!!.id).sortedByDescending { it.sourceOrder }
|
||||
.filter {
|
||||
it.id != readerChapter.chapter.id &&
|
||||
!it.read &&
|
||||
it.chapterNumber.toFloat() == readerChapter.chapter.chapter_number
|
||||
}
|
||||
.ifEmpty { null }
|
||||
?.also {
|
||||
setReadStatus.await(
|
||||
true,
|
||||
*it.toTypedArray(),
|
||||
// KMK -->
|
||||
manually = false,
|
||||
// KMK <--
|
||||
)
|
||||
it.forEach { chapter ->
|
||||
deleteChapterIfNeeded(ReaderChapter(chapter))
|
||||
}
|
||||
}
|
||||
}
|
||||
if (manga?.isEhBasedManga() == true) {
|
||||
viewModelScope.launchNonCancellable {
|
||||
val chapterUpdates = chapterList
|
||||
|
|
@ -745,9 +751,14 @@ class ReaderViewModel @JvmOverloads constructor(
|
|||
}
|
||||
}
|
||||
// SY <--
|
||||
|
||||
updateTrackChapterRead(readerChapter)
|
||||
deleteChapterIfNeeded(readerChapter)
|
||||
|
||||
val markDuplicateAsRead = libraryPreferences.markDuplicateReadChapterAsRead().get()
|
||||
.contains(LibraryPreferences.MARK_DUPLICATE_CHAPTER_READ_EXISTING)
|
||||
if (!markDuplicateAsRead) return
|
||||
|
||||
val duplicateUnreadChapters = chapterList
|
||||
.mapNotNull {
|
||||
val chapter = it.chapter
|
||||
|
|
@ -757,31 +768,14 @@ class ReaderViewModel @JvmOverloads constructor(
|
|||
chapter.chapter_number == readerChapter.chapter.chapter_number
|
||||
) {
|
||||
ChapterUpdate(id = chapter.id!!, read = true)
|
||||
// SY -->
|
||||
.also { deleteChapterIfNeeded(ReaderChapter(chapter)) }
|
||||
// SY <--
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
updateChapter.awaitAll(duplicateUnreadChapters)
|
||||
|
||||
// Check if syncing is enabled for chapter read:
|
||||
if (isSyncEnabled && syncTriggerOpt.syncOnChapterRead) {
|
||||
SyncDataJob.startNow(Injekt.get<Application>())
|
||||
}
|
||||
}
|
||||
|
||||
updateChapter.await(
|
||||
ChapterUpdate(
|
||||
id = readerChapter.chapter.id!!,
|
||||
read = readerChapter.chapter.read,
|
||||
lastPageRead = readerChapter.chapter.last_page_read.toLong(),
|
||||
),
|
||||
)
|
||||
|
||||
// Check if syncing is enabled for chapter open:
|
||||
if (isSyncEnabled && syncTriggerOpt.syncOnChapterOpen && readerChapter.chapter.last_page_read == 0) {
|
||||
SyncDataJob.startNow(Injekt.get<Application>())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun restartReadTimer() {
|
||||
|
|
|
|||
|
|
@ -143,8 +143,6 @@ class ReaderPreferences(
|
|||
|
||||
fun showNavigationOverlayOnStart() = preferenceStore.getBoolean("reader_navigation_overlay_on_start", false)
|
||||
|
||||
fun markDuplicateReadChapterAsRead() = preferenceStore.getBoolean("mark_duplicate_chapter_read", false)
|
||||
|
||||
// endregion
|
||||
|
||||
// SY -->
|
||||
|
|
@ -186,8 +184,6 @@ class ReaderPreferences(
|
|||
fun centerMarginType() = preferenceStore.getInt("center_margin_type", PagerConfig.CenterMarginType.NONE)
|
||||
|
||||
fun archiveReaderMode() = preferenceStore.getInt("archive_reader_mode", ArchiveReaderMode.LOAD_FROM_FILE)
|
||||
|
||||
fun markReadDupe() = preferenceStore.getBoolean("mark_read_dupe", false)
|
||||
// SY <--
|
||||
|
||||
enum class FlashColor {
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ class LibraryPreferences(
|
|||
false,
|
||||
)
|
||||
|
||||
fun markDuplicateReadChapterAsRead() = preferenceStore.getStringSet("mark_duplicate_read_chapter_read", emptySet())
|
||||
|
||||
// region Filter
|
||||
|
||||
fun filterDownloaded() = preferenceStore.getEnum(
|
||||
|
|
@ -251,6 +253,9 @@ class LibraryPreferences(
|
|||
const val MANGA_NON_READ = "manga_started"
|
||||
const val MANGA_OUTSIDE_RELEASE_PERIOD = "manga_outside_release_period"
|
||||
|
||||
const val MARK_DUPLICATE_CHAPTER_READ_NEW = "new"
|
||||
const val MARK_DUPLICATE_CHAPTER_READ_EXISTING = "existing"
|
||||
|
||||
const val DEFAULT_CATEGORY_PREF_KEY = "default_category"
|
||||
private const val LIBRARY_UPDATE_CATEGORIES_PREF_KEY = "library_update_categories"
|
||||
private const val LIBRARY_UPDATE_CATEGORIES_EXCLUDE_PREF_KEY = "library_update_categories_exclude"
|
||||
|
|
|
|||
|
|
@ -294,7 +294,6 @@
|
|||
<string name="pref_update_only_started">Skip unstarted entries</string>
|
||||
<string name="pref_update_only_in_release_period">Predict next release time</string>
|
||||
<string name="pref_library_update_show_tab_badge">Show unread count on Updates icon</string>
|
||||
<string name="pref_mark_duplicate_read_chapter_read">Mark duplicate read chapters as read</string>
|
||||
|
||||
<string name="pref_library_update_refresh_metadata">Automatically refresh metadata</string>
|
||||
<string name="pref_library_update_refresh_metadata_summary">Check for new cover and details when updating library</string>
|
||||
|
|
@ -308,11 +307,14 @@
|
|||
<string name="include">Include: %s</string>
|
||||
<string name="exclude">Exclude: %s</string>
|
||||
|
||||
<string name="pref_chapter_swipe">Chapter swipe</string>
|
||||
<string name="pref_behavior">Behavior</string>
|
||||
<!-- This should be to the left for RTL locales -->
|
||||
<string name="pref_chapter_swipe_end">Swipe to right action</string>
|
||||
<string name="pref_chapter_swipe_end">Chapter on swipe to right</string>
|
||||
<!-- This should be to the right for RTL locales -->
|
||||
<string name="pref_chapter_swipe_start">Swipe to left action</string>
|
||||
<string name="pref_chapter_swipe_start">Chapter on swipe to left</string>
|
||||
<string name="pref_mark_duplicate_read_chapter_read">Mark duplicate read chapter as read</string>
|
||||
<string name="pref_mark_duplicate_read_chapter_read_existing">After reading a chapter</string>
|
||||
<string name="pref_mark_duplicate_read_chapter_read_new">After fetching new chapter</string>
|
||||
|
||||
<!-- Extension section -->
|
||||
<string name="multi_lang">Multi</string>
|
||||
|
|
|
|||
Loading…
Reference in a new issue