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 71ada62067.

* changed `AlertDialog.Builder` to `MaterialAlertDialogBuilder`

* using SQL query instead of filtering entire library with Kotlin
This commit is contained in:
Felix Kaiser 2022-02-12 17:00:57 +01:00 committed by arkon
parent 2932ed670f
commit 71ddb16574
4 changed files with 49 additions and 2 deletions

View File

@ -34,6 +34,21 @@ interface MangaQueries : DbProvider {
.withGetResolver(LibraryMangaGetResolver.INSTANCE) .withGetResolver(LibraryMangaGetResolver.INSTANCE)
.prepare() .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<Manga> { fun getFavoriteMangas(sortByTitle: Boolean = true): PreparedGetListOfObjects<Manga> {
var queryBuilder = Query.builder() var queryBuilder = Query.builder()
.table(MangaTable.TABLE) .table(MangaTable.TABLE)

View File

@ -19,7 +19,6 @@ import androidx.core.os.bundleOf
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.core.view.doOnLayout import androidx.core.view.doOnLayout
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import androidx.recyclerview.widget.ConcatAdapter import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
@ -30,6 +29,7 @@ import coil.request.ImageRequest
import com.bluelinelabs.conductor.Controller import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.ControllerChangeHandler import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.ControllerChangeType import com.bluelinelabs.conductor.ControllerChangeType
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import dev.chrisbanes.insetter.applyInsetter import dev.chrisbanes.insetter.applyInsetter
@ -145,6 +145,7 @@ class MangaController :
private val preferences: PreferencesHelper by injectLazy() private val preferences: PreferencesHelper by injectLazy()
private val coverCache: CoverCache by injectLazy() private val coverCache: CoverCache by injectLazy()
private val sourceManager: SourceManager by injectLazy()
private var mangaInfoAdapter: MangaInfoHeaderAdapter? = null private var mangaInfoAdapter: MangaInfoHeaderAdapter? = null
private var chaptersHeaderAdapter: MangaChaptersHeaderAdapter? = null private var chaptersHeaderAdapter: MangaChaptersHeaderAdapter? = null
@ -524,10 +525,35 @@ class MangaController :
toggleFavorite() toggleFavorite()
activity?.toast(activity?.getString(R.string.manga_removed_library)) activity?.toast(activity?.getString(R.string.manga_removed_library))
activity?.invalidateOptionsMenu() activity?.invalidateOptionsMenu()
} else {
val duplicateManga = presenter.getDuplicateLibraryManga(manga)
if (duplicateManga != null) {
showAddDuplicateDialog(
manga,
duplicateManga,
)
} else { } else {
addToLibrary(manga) 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()
}
}
fun onTrackingClick() { fun onTrackingClick() {
trackSheet?.show() trackSheet?.show()

View File

@ -174,6 +174,10 @@ class MangaPresenter(
fetchTrackers() fetchTrackers()
} }
fun getDuplicateLibraryManga(manga: Manga): Manga? {
return db.getDuplicateLibraryManga(manga).executeAsBlocking()
}
// Manga info - start // Manga info - start
private fun getMangaObservable(): Observable<Manga> { private fun getMangaObservable(): Observable<Manga> {

View File

@ -81,6 +81,7 @@
<string name="action_start">Start</string> <string name="action_start">Start</string>
<string name="action_resume">Resume</string> <string name="action_resume">Resume</string>
<string name="action_open_in_browser">Open in browser</string> <string name="action_open_in_browser">Open in browser</string>
<string name="action_show_manga">Show manga</string>
<!-- Do not translate "WebView" --> <!-- Do not translate "WebView" -->
<string name="action_open_in_web_view">Open in WebView</string> <string name="action_open_in_web_view">Open in WebView</string>
<string name="action_web_view" translatable="false">WebView</string> <string name="action_web_view" translatable="false">WebView</string>
@ -571,6 +572,7 @@
<string name="in_library">In library</string> <string name="in_library">In library</string>
<string name="remove_from_library">Remove from library</string> <string name="remove_from_library">Remove from library</string>
<string name="manga_info_full_title_label">Title</string> <string name="manga_info_full_title_label">Title</string>
<string name="confirm_manga_add_duplicate">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?</string>
<string name="manga_added_library">Added to library</string> <string name="manga_added_library">Added to library</string>
<string name="manga_removed_library">Removed from library</string> <string name="manga_removed_library">Removed from library</string>
<string name="manga_info_expand">More</string> <string name="manga_info_expand">More</string>