From 8a3b6107755c768924a31c2b58d705296133839c Mon Sep 17 00:00:00 2001
From: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
Date: Wed, 19 Mar 2025 02:27:58 +0600
Subject: [PATCH] Seperate mark duplicate read chapters as read behaviors as
options (#1870)
---
CHANGELOG.md | 3 +-
.../interactor/SyncChaptersWithSource.kt | 7 +--
.../settings/screen/SettingsLibraryScreen.kt | 18 ++++++--
.../settings/screen/SettingsReaderScreen.kt | 4 --
.../tachiyomi/ui/reader/ReaderViewModel.kt | 46 +++++++++++--------
.../ui/reader/setting/ReaderPreferences.kt | 2 -
.../library/service/LibraryPreferences.kt | 5 ++
.../moko-resources/base/strings.xml | 10 ++--
8 files changed, 60 insertions(+), 35 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 26356cee0..61d177bbe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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))
- Add `id:` prefix search to library to search by internal DB ID ([@MajorTanya](https://github.com/MajorTanya)) ([#1856](https://github.com/mihonapp/mihon/pull/1856))
- Add back option to disable unread chapter badge in library ([@AntsyLich](https://github.com/AntsyLich)) ([#1871](https://github.com/mihonapp/mihon/pull/1871))
@@ -34,6 +34,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))
diff --git a/app/src/main/java/eu/kanade/domain/chapter/interactor/SyncChaptersWithSource.kt b/app/src/main/java/eu/kanade/domain/chapter/interactor/SyncChaptersWithSource.kt
index 29e85d849..2a34e5994 100644
--- a/app/src/main/java/eu/kanade/domain/chapter/interactor/SyncChaptersWithSource.kt
+++ b/app/src/main/java/eu/kanade/domain/chapter/interactor/SyncChaptersWithSource.kt
@@ -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 tachiyomi.data.chapter.ChapterSanitizer
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
import tachiyomi.domain.chapter.interactor.ShouldUpdateDbChapter
@@ -20,6 +19,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
@@ -35,7 +35,7 @@ class SyncChaptersWithSource(
private val updateChapter: UpdateChapter,
private val getChaptersByMangaId: GetChaptersByMangaId,
private val getExcludedScanlators: GetExcludedScanlators,
- private val readerPreferences: ReaderPreferences,
+ private val libraryPreferences: LibraryPreferences,
) {
/**
@@ -168,7 +168,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.
diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsLibraryScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsLibraryScreen.kt
index e3e9825a5..5c1dbf270 100644
--- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsLibraryScreen.kt
+++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsLibraryScreen.kt
@@ -35,6 +35,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.presentation.core.i18n.pluralStringResource
import tachiyomi.presentation.core.i18n.stringResource
@@ -57,7 +59,7 @@ object SettingsLibraryScreen : SearchableSettings {
return listOf(
getCategoriesGroup(LocalNavigator.currentOrThrow, allCategories, libraryPreferences),
getGlobalUpdateGroup(allCategories, libraryPreferences),
- getChapterSwipeActionsGroup(libraryPreferences),
+ getBehaviorGroup(libraryPreferences),
)
}
@@ -210,11 +212,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(),
@@ -244,6 +246,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),
+ ),
),
)
}
diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt
index 7118f7c48..903397bca 100644
--- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt
+++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt
@@ -197,10 +197,6 @@ object SettingsReaderScreen : SearchableSettings {
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),
- ),
),
)
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
index 5ca99c6c0..d3205f793 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
@@ -71,6 +71,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.GetManga
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.service.SourceManager
@@ -101,6 +102,7 @@ class ReaderViewModel @JvmOverloads constructor(
private val updateChapter: UpdateChapter = Injekt.get(),
private val setMangaViewerFlags: SetMangaViewerFlags = Injekt.get(),
private val getIncognitoState: GetIncognitoState = Injekt.get(),
+ private val libraryPreferences: LibraryPreferences = Injekt.get(),
) : ViewModel() {
private val mutableState = MutableStateFlow(State())
@@ -535,24 +537,7 @@ class ReaderViewModel @JvmOverloads constructor(
readerChapter.chapter.last_page_read = pageIndex
if (readerChapter.pages?.lastIndex == pageIndex) {
- readerChapter.chapter.read = true
- updateTrackChapterRead(readerChapter)
- deleteChapterIfNeeded(readerChapter)
-
- val duplicateUnreadChapters = chapterList
- .mapNotNull {
- val chapter = it.chapter
- if (
- !chapter.read &&
- chapter.isRecognizedNumber &&
- chapter.chapter_number == readerChapter.chapter.chapter_number
- ) {
- ChapterUpdate(id = chapter.id!!, read = true)
- } else {
- null
- }
- }
- updateChapter.awaitAll(duplicateUnreadChapters)
+ updateChapterProgressOnComplete(readerChapter)
}
updateChapter.await(
@@ -565,6 +550,31 @@ class ReaderViewModel @JvmOverloads constructor(
}
}
+ private suspend fun updateChapterProgressOnComplete(readerChapter: ReaderChapter) {
+ readerChapter.chapter.read = true
+ 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
+ if (
+ !chapter.read &&
+ chapter.isRecognizedNumber &&
+ chapter.chapter_number == readerChapter.chapter.chapter_number
+ ) {
+ ChapterUpdate(id = chapter.id!!, read = true)
+ } else {
+ null
+ }
+ }
+ updateChapter.awaitAll(duplicateUnreadChapters)
+ }
+
fun restartReadTimer() {
chapterReadStartTime = Instant.now().toEpochMilli()
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt
index a722d1d24..5cd742ad1 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt
@@ -137,8 +137,6 @@ class ReaderPreferences(
fun showNavigationOverlayOnStart() = preferenceStore.getBoolean("reader_navigation_overlay_on_start", false)
- fun markDuplicateReadChapterAsRead() = preferenceStore.getBoolean("mark_duplicate_chapter_read", false)
-
// endregion
enum class FlashColor {
diff --git a/domain/src/main/java/tachiyomi/domain/library/service/LibraryPreferences.kt b/domain/src/main/java/tachiyomi/domain/library/service/LibraryPreferences.kt
index 1be9bafce..9a68baf7b 100644
--- a/domain/src/main/java/tachiyomi/domain/library/service/LibraryPreferences.kt
+++ b/domain/src/main/java/tachiyomi/domain/library/service/LibraryPreferences.kt
@@ -58,6 +58,8 @@ class LibraryPreferences(
false,
)
+ fun markDuplicateReadChapterAsRead() = preferenceStore.getStringSet("mark_duplicate_read_chapter_read", emptySet())
+
// region Filter
fun filterDownloaded() = preferenceStore.getEnum(
@@ -206,6 +208,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"
diff --git a/i18n/src/commonMain/moko-resources/base/strings.xml b/i18n/src/commonMain/moko-resources/base/strings.xml
index e86543d0f..a322d92dd 100644
--- a/i18n/src/commonMain/moko-resources/base/strings.xml
+++ b/i18n/src/commonMain/moko-resources/base/strings.xml
@@ -293,7 +293,6 @@
Skip unstarted entries
Predict next release time
Show unread count on Updates icon
- Mark duplicate read chapters as read
Automatically refresh metadata
Check for new cover and details when updating library
@@ -307,11 +306,14 @@
Include: %s
Exclude: %s
- Chapter swipe
+ Behavior
- Swipe to right action
+ Chapter on swipe to right
- Swipe to left action
+ Chapter on swipe to left
+ Mark duplicate read chapter as read
+ After reading a chapter
+ After fetching new chapter
Multi