From 71ddb1657440d54178f10fd62e3d0c66ee95a5a0 Mon Sep 17 00:00:00 2001 From: Felix Kaiser <30923667+foxscore@users.noreply.github.com> Date: Sat, 12 Feb 2022 17:00:57 +0100 Subject: [PATCH] Detect identical mangas when adding to library (#6579) * added duplicate manga check When adding a manga to your library, the app will go through each manga previously added and compare their names. If a match is detected, it will prompt the user and ask for confirmation. On this prompt there is also an option to view the other manga. * added german translations for newly added strings * Revert "added german translations for newly added strings" This reverts commit 71ada620671651daeeb2546aecd02400a4bc86bc. * changed `AlertDialog.Builder` to `MaterialAlertDialogBuilder` * using SQL query instead of filtering entire library with Kotlin --- .../data/database/queries/MangaQueries.kt | 15 ++++++++++ .../tachiyomi/ui/manga/MangaController.kt | 30 +++++++++++++++++-- .../tachiyomi/ui/manga/MangaPresenter.kt | 4 +++ app/src/main/res/values/strings.xml | 2 ++ 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt index 78e6c5a8d0..5d5f65c364 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt @@ -34,6 +34,21 @@ interface MangaQueries : DbProvider { .withGetResolver(LibraryMangaGetResolver.INSTANCE) .prepare() + fun getDuplicateLibraryManga(manga: Manga) = db.get() + .`object`(Manga::class.java) + .withQuery( + Query.builder() + .table(MangaTable.TABLE) + .where("${MangaTable.COL_FAVORITE} = 1 AND LOWER(${MangaTable.COL_TITLE}) = ? AND ${MangaTable.COL_SOURCE} != ?") + .whereArgs( + manga.title.lowercase(), + manga.source, + ) + .limit(1) + .build() + ) + .prepare() + fun getFavoriteMangas(sortByTitle: Boolean = true): PreparedGetListOfObjects { var queryBuilder = Query.builder() .table(MangaTable.TABLE) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt index 66f06fdf4e..c35dbb0ebf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt @@ -19,7 +19,6 @@ import androidx.core.os.bundleOf import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.doOnLayout -import androidx.core.view.isVisible import androidx.core.view.updateLayoutParams import androidx.recyclerview.widget.ConcatAdapter import androidx.recyclerview.widget.LinearLayoutManager @@ -30,6 +29,7 @@ import coil.request.ImageRequest import com.bluelinelabs.conductor.Controller import com.bluelinelabs.conductor.ControllerChangeHandler import com.bluelinelabs.conductor.ControllerChangeType +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton import com.google.android.material.snackbar.Snackbar import dev.chrisbanes.insetter.applyInsetter @@ -145,6 +145,7 @@ class MangaController : private val preferences: PreferencesHelper by injectLazy() private val coverCache: CoverCache by injectLazy() + private val sourceManager: SourceManager by injectLazy() private var mangaInfoAdapter: MangaInfoHeaderAdapter? = null private var chaptersHeaderAdapter: MangaChaptersHeaderAdapter? = null @@ -525,7 +526,32 @@ class MangaController : activity?.toast(activity?.getString(R.string.manga_removed_library)) activity?.invalidateOptionsMenu() } else { - addToLibrary(manga) + val duplicateManga = presenter.getDuplicateLibraryManga(manga) + if (duplicateManga != null) { + showAddDuplicateDialog( + manga, + duplicateManga, + ) + } else { + addToLibrary(manga) + } + } + } + + private fun showAddDuplicateDialog(newManga: Manga, libraryManga: Manga) { + activity?.let { + val source = sourceManager.getOrStub(libraryManga.source) + MaterialAlertDialogBuilder(it).apply { + setMessage(activity?.getString(R.string.confirm_manga_add_duplicate, source.name)) + setPositiveButton(activity?.getString(R.string.action_add)) { _, _, -> + addToLibrary(newManga) + } + setNegativeButton(activity?.getString(R.string.action_cancel)) { _, _, -> } + setNeutralButton(activity?.getString(R.string.action_show_manga)) { _, _, -> + router.pushController(MangaController(libraryManga).withFadeTransaction()) + } + setCancelable(true) + }.create().show() } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt index beccee6b99..c2a2579a08 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt @@ -174,6 +174,10 @@ class MangaPresenter( fetchTrackers() } + fun getDuplicateLibraryManga(manga: Manga): Manga? { + return db.getDuplicateLibraryManga(manga).executeAsBlocking() + } + // Manga info - start private fun getMangaObservable(): Observable { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4ed26f5425..11656c49f6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -81,6 +81,7 @@ Start Resume Open in browser + Show manga Open in WebView WebView @@ -571,6 +572,7 @@ In library Remove from library Title + You have an entry in your library with the same name but from a different source (%1$s).\n\nDo you still wish to continue? Added to library Removed from library More