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