Migrate duplicate manga check to SQLDelight
Extracted from #7244 Co-authored-by: ivaniskandar <ivaniskandar@users.noreply.github.com>
This commit is contained in:
parent
0f5731360b
commit
9f66c85281
@ -22,6 +22,12 @@ class MangaRepositoryImpl(
|
|||||||
return handler.subscribeToList { mangasQueries.getFavoriteBySourceId(sourceId, mangaMapper) }
|
return handler.subscribeToList { mangasQueries.getFavoriteBySourceId(sourceId, mangaMapper) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun getDuplicateLibraryManga(title: String, sourceId: Long): Manga? {
|
||||||
|
return handler.awaitOneOrNull {
|
||||||
|
mangasQueries.getDuplicateLibraryManga(title, sourceId, mangaMapper)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun resetViewerFlags(): Boolean {
|
override suspend fun resetViewerFlags(): Boolean {
|
||||||
return try {
|
return try {
|
||||||
handler.await { mangasQueries.resetViewerFlags() }
|
handler.await { mangasQueries.resetViewerFlags() }
|
||||||
|
@ -26,6 +26,7 @@ import eu.kanade.domain.history.interactor.RemoveHistoryById
|
|||||||
import eu.kanade.domain.history.interactor.RemoveHistoryByMangaId
|
import eu.kanade.domain.history.interactor.RemoveHistoryByMangaId
|
||||||
import eu.kanade.domain.history.interactor.UpsertHistory
|
import eu.kanade.domain.history.interactor.UpsertHistory
|
||||||
import eu.kanade.domain.history.repository.HistoryRepository
|
import eu.kanade.domain.history.repository.HistoryRepository
|
||||||
|
import eu.kanade.domain.manga.interactor.GetDuplicateLibraryManga
|
||||||
import eu.kanade.domain.manga.interactor.GetFavoritesBySourceId
|
import eu.kanade.domain.manga.interactor.GetFavoritesBySourceId
|
||||||
import eu.kanade.domain.manga.interactor.GetMangaById
|
import eu.kanade.domain.manga.interactor.GetMangaById
|
||||||
import eu.kanade.domain.manga.interactor.ResetViewerFlags
|
import eu.kanade.domain.manga.interactor.ResetViewerFlags
|
||||||
@ -58,6 +59,7 @@ class DomainModule : InjektModule {
|
|||||||
addFactory { DeleteCategory(get()) }
|
addFactory { DeleteCategory(get()) }
|
||||||
|
|
||||||
addSingletonFactory<MangaRepository> { MangaRepositoryImpl(get()) }
|
addSingletonFactory<MangaRepository> { MangaRepositoryImpl(get()) }
|
||||||
|
addFactory { GetDuplicateLibraryManga(get()) }
|
||||||
addFactory { GetFavoritesBySourceId(get()) }
|
addFactory { GetFavoritesBySourceId(get()) }
|
||||||
addFactory { GetMangaById(get()) }
|
addFactory { GetMangaById(get()) }
|
||||||
addFactory { GetNextChapter(get()) }
|
addFactory { GetNextChapter(get()) }
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
package eu.kanade.domain.manga.interactor
|
||||||
|
|
||||||
|
import eu.kanade.domain.manga.model.Manga
|
||||||
|
import eu.kanade.domain.manga.repository.MangaRepository
|
||||||
|
|
||||||
|
class GetDuplicateLibraryManga(private val mangaRepository: MangaRepository) {
|
||||||
|
suspend fun await(title: String, sourceId: Long): Manga? {
|
||||||
|
return mangaRepository.getDuplicateLibraryManga(title.lowercase(), sourceId)
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,8 @@ interface MangaRepository {
|
|||||||
|
|
||||||
fun getFavoritesBySourceId(sourceId: Long): Flow<List<Manga>>
|
fun getFavoritesBySourceId(sourceId: Long): Flow<List<Manga>>
|
||||||
|
|
||||||
|
suspend fun getDuplicateLibraryManga(title: String, sourceId: Long): Manga?
|
||||||
|
|
||||||
suspend fun resetViewerFlags(): Boolean
|
suspend fun resetViewerFlags(): Boolean
|
||||||
|
|
||||||
suspend fun update(update: MangaUpdate): Boolean
|
suspend fun update(update: MangaUpdate): Boolean
|
||||||
|
@ -28,21 +28,6 @@ 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)
|
||||||
|
@ -42,6 +42,8 @@ import eu.kanade.tachiyomi.ui.manga.AddDuplicateMangaDialog
|
|||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
import eu.kanade.tachiyomi.ui.more.MoreController
|
import eu.kanade.tachiyomi.ui.more.MoreController
|
||||||
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
|
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
|
||||||
|
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||||
|
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||||
import eu.kanade.tachiyomi.util.preference.asImmediateFlow
|
import eu.kanade.tachiyomi.util.preference.asImmediateFlow
|
||||||
import eu.kanade.tachiyomi.util.system.connectivityManager
|
import eu.kanade.tachiyomi.util.system.connectivityManager
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
import eu.kanade.tachiyomi.util.system.logcat
|
||||||
@ -589,8 +591,10 @@ open class BrowseSourceController(bundle: Bundle) :
|
|||||||
override fun onItemLongClick(position: Int) {
|
override fun onItemLongClick(position: Int) {
|
||||||
val activity = activity ?: return
|
val activity = activity ?: return
|
||||||
val manga = (adapter?.getItem(position) as? SourceItem?)?.manga ?: return
|
val manga = (adapter?.getItem(position) as? SourceItem?)?.manga ?: return
|
||||||
|
launchIO {
|
||||||
val duplicateManga = presenter.getDuplicateLibraryManga(manga)
|
val duplicateManga = presenter.getDuplicateLibraryManga(manga)
|
||||||
|
|
||||||
|
withUIContext {
|
||||||
if (manga.favorite) {
|
if (manga.favorite) {
|
||||||
MaterialAlertDialogBuilder(activity)
|
MaterialAlertDialogBuilder(activity)
|
||||||
.setTitle(manga.title)
|
.setTitle(manga.title)
|
||||||
@ -606,13 +610,20 @@ open class BrowseSourceController(bundle: Bundle) :
|
|||||||
.show()
|
.show()
|
||||||
} else {
|
} else {
|
||||||
if (duplicateManga != null) {
|
if (duplicateManga != null) {
|
||||||
AddDuplicateMangaDialog(this, duplicateManga) { addToLibrary(manga, position) }
|
AddDuplicateMangaDialog(this@BrowseSourceController, duplicateManga) {
|
||||||
|
addToLibrary(
|
||||||
|
manga,
|
||||||
|
position,
|
||||||
|
)
|
||||||
|
}
|
||||||
.showDialog(router)
|
.showDialog(router)
|
||||||
} else {
|
} else {
|
||||||
addToLibrary(manga, position)
|
addToLibrary(manga, position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun addToLibrary(newManga: Manga, position: Int) {
|
private fun addToLibrary(newManga: Manga, position: Int) {
|
||||||
val activity = activity ?: return
|
val activity = activity ?: return
|
||||||
|
@ -2,6 +2,8 @@ package eu.kanade.tachiyomi.ui.browse.source.browse
|
|||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
|
import eu.kanade.domain.manga.interactor.GetDuplicateLibraryManga
|
||||||
|
import eu.kanade.domain.manga.model.toDbManga
|
||||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
@ -60,6 +62,7 @@ open class BrowseSourcePresenter(
|
|||||||
private val db: DatabaseHelper = Injekt.get(),
|
private val db: DatabaseHelper = Injekt.get(),
|
||||||
private val prefs: PreferencesHelper = Injekt.get(),
|
private val prefs: PreferencesHelper = Injekt.get(),
|
||||||
private val coverCache: CoverCache = Injekt.get(),
|
private val coverCache: CoverCache = Injekt.get(),
|
||||||
|
private val getDuplicateLibraryManga: GetDuplicateLibraryManga = Injekt.get(),
|
||||||
) : BasePresenter<BrowseSourceController>() {
|
) : BasePresenter<BrowseSourceController>() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -348,8 +351,8 @@ open class BrowseSourcePresenter(
|
|||||||
return db.getCategories().executeAsBlocking()
|
return db.getCategories().executeAsBlocking()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDuplicateLibraryManga(manga: Manga): Manga? {
|
suspend fun getDuplicateLibraryManga(manga: Manga): Manga? {
|
||||||
return db.getDuplicateLibraryManga(manga).executeAsBlocking()
|
return getDuplicateLibraryManga.await(manga.title, manga.source)?.toDbManga()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,6 +87,7 @@ import eu.kanade.tachiyomi.ui.webview.WebViewActivity
|
|||||||
import eu.kanade.tachiyomi.util.hasCustomCover
|
import eu.kanade.tachiyomi.util.hasCustomCover
|
||||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||||
|
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
import eu.kanade.tachiyomi.util.system.logcat
|
||||||
import eu.kanade.tachiyomi.util.system.toShareIntent
|
import eu.kanade.tachiyomi.util.system.toShareIntent
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
@ -516,15 +517,20 @@ 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 {
|
||||||
|
launchIO {
|
||||||
val duplicateManga = presenter.getDuplicateLibraryManga(manga)
|
val duplicateManga = presenter.getDuplicateLibraryManga(manga)
|
||||||
|
|
||||||
|
withUIContext {
|
||||||
if (duplicateManga != null) {
|
if (duplicateManga != null) {
|
||||||
AddDuplicateMangaDialog(this, duplicateManga) { addToLibrary(manga) }
|
AddDuplicateMangaDialog(this@MangaController, duplicateManga) { addToLibrary(manga) }
|
||||||
.showDialog(router)
|
.showDialog(router)
|
||||||
} else {
|
} else {
|
||||||
addToLibrary(manga)
|
addToLibrary(manga)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun onTrackingClick() {
|
fun onTrackingClick() {
|
||||||
trackSheet?.show()
|
trackSheet?.show()
|
||||||
|
@ -6,6 +6,8 @@ import android.os.Bundle
|
|||||||
import com.jakewharton.rxrelay.PublishRelay
|
import com.jakewharton.rxrelay.PublishRelay
|
||||||
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
||||||
import eu.kanade.domain.chapter.model.toDbChapter
|
import eu.kanade.domain.chapter.model.toDbChapter
|
||||||
|
import eu.kanade.domain.manga.interactor.GetDuplicateLibraryManga
|
||||||
|
import eu.kanade.domain.manga.model.toDbManga
|
||||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
@ -69,6 +71,7 @@ class MangaPresenter(
|
|||||||
private val downloadManager: DownloadManager = Injekt.get(),
|
private val downloadManager: DownloadManager = Injekt.get(),
|
||||||
private val coverCache: CoverCache = Injekt.get(),
|
private val coverCache: CoverCache = Injekt.get(),
|
||||||
private val getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
|
private val getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
|
||||||
|
private val getDuplicateLibraryManga: GetDuplicateLibraryManga = Injekt.get(),
|
||||||
) : BasePresenter<MangaController>() {
|
) : BasePresenter<MangaController>() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -167,8 +170,8 @@ class MangaPresenter(
|
|||||||
fetchTrackers()
|
fetchTrackers()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDuplicateLibraryManga(manga: Manga): Manga? {
|
suspend fun getDuplicateLibraryManga(manga: Manga): Manga? {
|
||||||
return db.getDuplicateLibraryManga(manga).executeAsBlocking()
|
return getDuplicateLibraryManga.await(manga.title, manga.source)?.toDbManga()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manga info - start
|
// Manga info - start
|
||||||
|
@ -58,6 +58,13 @@ FROM mangas
|
|||||||
WHERE favorite = 1
|
WHERE favorite = 1
|
||||||
AND source = :sourceId;
|
AND source = :sourceId;
|
||||||
|
|
||||||
|
getDuplicateLibraryManga:
|
||||||
|
SELECT *
|
||||||
|
FROM mangas
|
||||||
|
WHERE favorite = 1
|
||||||
|
AND LOWER(title) = :title
|
||||||
|
AND source != :source;
|
||||||
|
|
||||||
resetViewerFlags:
|
resetViewerFlags:
|
||||||
UPDATE mangas
|
UPDATE mangas
|
||||||
SET viewer = 0;
|
SET viewer = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user