mirror of
https://github.com/mihonapp/mihon.git
synced 2024-11-21 20:47:03 -05:00
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
This commit is contained in:
parent
2932ed670f
commit
71ddb16574
4 changed files with 49 additions and 2 deletions
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
@ -525,7 +526,32 @@ class MangaController :
|
||||||
activity?.toast(activity?.getString(R.string.manga_removed_library))
|
activity?.toast(activity?.getString(R.string.manga_removed_library))
|
||||||
activity?.invalidateOptionsMenu()
|
activity?.invalidateOptionsMenu()
|
||||||
} else {
|
} 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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue