Use SQLDelight for mass migration
This commit is contained in:
parent
664f9b1484
commit
e71c9e2775
@ -1,18 +1,17 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.migration.advanced.process
|
||||
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.domain.manga.interactor.GetMangaById
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import exh.util.DeferredField
|
||||
import exh.util.executeOnIO
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class MigratingManga(
|
||||
private val db: DatabaseHelper,
|
||||
private val getMangaById: GetMangaById,
|
||||
private val sourceManager: SourceManager,
|
||||
val mangaId: Long,
|
||||
parentContext: CoroutineContext,
|
||||
@ -29,7 +28,7 @@ class MigratingManga(
|
||||
@Volatile
|
||||
private var manga: Manga? = null
|
||||
suspend fun manga(): Manga? {
|
||||
if (manga == null) manga = db.getManga(mangaId).executeOnIO()
|
||||
if (manga == null) manga = getMangaById.await(mangaId)
|
||||
return manga
|
||||
}
|
||||
|
||||
|
@ -15,17 +15,20 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import dev.chrisbanes.insetter.applyInsetter
|
||||
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
|
||||
import eu.kanade.domain.manga.interactor.GetMangaById
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.model.toDbManga
|
||||
import eu.kanade.domain.manga.model.toMangaInfo
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
|
||||
import eu.kanade.tachiyomi.data.database.models.toDomainManga
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.databinding.MigrationListControllerBinding
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.model.toSChapter
|
||||
import eu.kanade.tachiyomi.source.model.toSManga
|
||||
import eu.kanade.tachiyomi.source.online.all.EHentai
|
||||
import eu.kanade.tachiyomi.ui.base.changehandler.OneWayFadeChangeHandler
|
||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||
@ -35,15 +38,12 @@ import eu.kanade.tachiyomi.ui.browse.migration.MigrationMangaDialog
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.advanced.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.search.SearchController
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import exh.eh.EHentaiThrottleManager
|
||||
import exh.smartsearch.SmartSearchEngine
|
||||
import exh.util.executeOnIO
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@ -70,11 +70,13 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
|
||||
val config: MigrationProcedureConfig? = args.getParcelable(CONFIG_EXTRA)
|
||||
|
||||
private val db: DatabaseHelper by injectLazy()
|
||||
private val preferences: PreferencesHelper by injectLazy()
|
||||
private val sourceManager: SourceManager by injectLazy()
|
||||
|
||||
private val smartSearchEngine = SmartSearchEngine(config?.extraSearchParams)
|
||||
private val syncChaptersWithSource: SyncChaptersWithSource by injectLazy()
|
||||
private val getMangaById: GetMangaById by injectLazy()
|
||||
private val updateManga: UpdateManga by injectLazy()
|
||||
|
||||
private val migrationScope = CoroutineScope(Job() + Dispatchers.IO)
|
||||
var migrationsJob: Job? = null
|
||||
@ -107,7 +109,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
|
||||
val newMigratingManga = migratingManga ?: run {
|
||||
val new = config.mangaIds.map {
|
||||
MigratingManga(db, sourceManager, it, migrationScope.coroutineContext)
|
||||
MigratingManga(getMangaById, sourceManager, it, migrationScope.coroutineContext)
|
||||
}
|
||||
migratingManga = new.toMutableList()
|
||||
new
|
||||
@ -172,16 +174,16 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
sourceSemaphore.withPermit {
|
||||
try {
|
||||
val searchResult = if (useSmartSearch) {
|
||||
smartSearchEngine.smartSearch(source, mangaObj.originalTitle)
|
||||
smartSearchEngine.smartSearch(source, mangaObj.ogTitle)
|
||||
} else {
|
||||
smartSearchEngine.normalSearch(source, mangaObj.originalTitle)
|
||||
smartSearchEngine.normalSearch(source, mangaObj.ogTitle)
|
||||
}
|
||||
|
||||
if (searchResult != null && !(searchResult.url == mangaObj.url && source.id == mangaObj.source)) {
|
||||
val localManga = smartSearchEngine.networkToLocalManga(
|
||||
searchResult,
|
||||
source.id,
|
||||
)
|
||||
).toDomainManga()!!
|
||||
|
||||
val chapters = if (source is EHentai) {
|
||||
source.getChapterList(localManga.toMangaInfo(), throttleManager::throttle)
|
||||
@ -190,7 +192,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
}
|
||||
|
||||
try {
|
||||
syncChaptersWithSource(chapters.map { it.toSChapter() }, localManga, source)
|
||||
syncChaptersWithSource.await(chapters.map { it.toSChapter() }, localManga, source)
|
||||
} catch (e: Exception) {
|
||||
return@async2 null
|
||||
}
|
||||
@ -212,13 +214,13 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
validSources.forEachIndexed { index, source ->
|
||||
val searchResult = try {
|
||||
val searchResult = if (useSmartSearch) {
|
||||
smartSearchEngine.smartSearch(source, mangaObj.originalTitle)
|
||||
smartSearchEngine.smartSearch(source, mangaObj.ogTitle)
|
||||
} else {
|
||||
smartSearchEngine.normalSearch(source, mangaObj.originalTitle)
|
||||
smartSearchEngine.normalSearch(source, mangaObj.ogTitle)
|
||||
}
|
||||
|
||||
if (searchResult != null) {
|
||||
val localManga = smartSearchEngine.networkToLocalManga(searchResult, source.id)
|
||||
val localManga = smartSearchEngine.networkToLocalManga(searchResult, source.id).toDomainManga()!!
|
||||
val chapters = try {
|
||||
if (source is EHentai) {
|
||||
source.getChapterList(localManga.toMangaInfo(), throttleManager::throttle)
|
||||
@ -229,9 +231,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
this@MigrationListController.logcat(LogPriority.ERROR, e)
|
||||
emptyList()
|
||||
}
|
||||
withIOContext {
|
||||
syncChaptersWithSource(chapters, localManga, source)
|
||||
}
|
||||
syncChaptersWithSource.await(chapters, localManga, source)
|
||||
localManga
|
||||
} else null
|
||||
} catch (e: CancellationException) {
|
||||
@ -252,12 +252,10 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
continue
|
||||
}
|
||||
|
||||
if (result != null && result.thumbnail_url == null) {
|
||||
if (result != null && result.thumbnailUrl == null) {
|
||||
try {
|
||||
val newManga = sourceManager.getOrStub(result.source).getMangaDetails(result.toMangaInfo())
|
||||
result.copyFrom(newManga.toSManga())
|
||||
|
||||
db.insertManga(result).executeOnIO()
|
||||
updateManga.awaitUpdateFromSource(result, newManga, true)
|
||||
} catch (e: CancellationException) {
|
||||
// Ignore cancellations
|
||||
throw e
|
||||
@ -335,7 +333,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
} else {
|
||||
sources.filter { it.id != manga.source }
|
||||
}
|
||||
val searchController = SearchController(manga, validSources)
|
||||
val searchController = SearchController(manga.toDbManga(), validSources)
|
||||
searchController.targetController = this@MigrationListController
|
||||
router.pushController(searchController)
|
||||
}
|
||||
@ -359,11 +357,11 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
adapter?.notifyItemChanged(firstIndex)
|
||||
launchUI {
|
||||
val result = CoroutineScope(migratingManga.manga.migrationJob).async {
|
||||
val localManga = smartSearchEngine.networkToLocalManga(manga, source.id)
|
||||
val localManga = smartSearchEngine.networkToLocalManga(manga, source.id).toDomainManga()!!
|
||||
try {
|
||||
val chapters = source.getChapterList(localManga.toMangaInfo())
|
||||
.map { it.toSChapter() }
|
||||
syncChaptersWithSource(chapters, localManga, source)
|
||||
syncChaptersWithSource.await(chapters, localManga, source)
|
||||
} catch (e: Exception) {
|
||||
return@async null
|
||||
}
|
||||
@ -373,9 +371,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
if (result != null) {
|
||||
try {
|
||||
val newManga = sourceManager.getOrStub(result.source).getMangaDetails(result.toMangaInfo())
|
||||
result.copyFrom(newManga.toSManga())
|
||||
|
||||
db.insertManga(result).executeOnIO()
|
||||
updateManga.awaitUpdateFromSource(result, newManga, true)
|
||||
} catch (e: CancellationException) {
|
||||
// Ignore cancellations
|
||||
throw e
|
||||
@ -413,14 +409,14 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
val hasDetails = router.backstack.any { it.controller is MangaController }
|
||||
if (hasDetails) {
|
||||
val manga = migratingManga?.firstOrNull()?.searchResult?.get()?.let {
|
||||
db.getManga(it).executeOnIO()
|
||||
getMangaById.await(it)
|
||||
}
|
||||
if (manga != null) {
|
||||
val newStack = router.backstack.filter {
|
||||
it.controller !is MangaController &&
|
||||
it.controller !is MigrationListController &&
|
||||
it.controller !is PreMigrationController
|
||||
} + MangaController(manga.id!!).withFadeTransaction()
|
||||
} + MangaController(manga.id).withFadeTransaction()
|
||||
router.setBackstack(newStack, OneWayFadeChangeHandler())
|
||||
return@launchUI
|
||||
}
|
||||
|
@ -2,15 +2,28 @@ package eu.kanade.tachiyomi.ui.browse.migration.advanced.process
|
||||
|
||||
import android.view.MenuItem
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.kanade.data.DatabaseHandler
|
||||
import eu.kanade.data.history.historyMapper
|
||||
import eu.kanade.domain.category.interactor.GetCategories
|
||||
import eu.kanade.domain.category.interactor.SetMangaCategories
|
||||
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
||||
import eu.kanade.domain.chapter.interactor.UpdateChapter
|
||||
import eu.kanade.domain.chapter.model.Chapter
|
||||
import eu.kanade.domain.chapter.model.ChapterUpdate
|
||||
import eu.kanade.domain.history.interactor.UpsertHistory
|
||||
import eu.kanade.domain.history.model.HistoryUpdate
|
||||
import eu.kanade.domain.manga.interactor.GetMangaById
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.domain.manga.model.MangaUpdate
|
||||
import eu.kanade.domain.manga.model.hasCustomCover
|
||||
import eu.kanade.domain.manga.model.toDbManga
|
||||
import eu.kanade.domain.track.interactor.DeleteTrack
|
||||
import eu.kanade.domain.track.interactor.GetTracks
|
||||
import eu.kanade.domain.track.interactor.InsertTrack
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.models.History
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.MigrationFlags
|
||||
import eu.kanade.tachiyomi.util.hasCustomCover
|
||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||
import kotlinx.coroutines.cancel
|
||||
@ -19,9 +32,19 @@ import uy.kohesive.injekt.injectLazy
|
||||
class MigrationProcessAdapter(
|
||||
val controller: MigrationListController,
|
||||
) : FlexibleAdapter<MigrationProcessItem>(null, controller, true) {
|
||||
private val db: DatabaseHelper by injectLazy()
|
||||
private val handler: DatabaseHandler by injectLazy()
|
||||
private val preferences: PreferencesHelper by injectLazy()
|
||||
private val coverCache: CoverCache by injectLazy()
|
||||
private val getMangaById: GetMangaById by injectLazy()
|
||||
private val updateManga: UpdateManga by injectLazy()
|
||||
private val updateChapter: UpdateChapter by injectLazy()
|
||||
private val getChapterByMangaId: GetChapterByMangaId by injectLazy()
|
||||
private val upsertHistory: UpsertHistory by injectLazy()
|
||||
private val getCategories: GetCategories by injectLazy()
|
||||
private val setMangaCategories: SetMangaCategories by injectLazy()
|
||||
private val getTracks: GetTracks by injectLazy()
|
||||
private val insertTrack: InsertTrack by injectLazy()
|
||||
private val deleteTrack: DeleteTrack by injectLazy()
|
||||
|
||||
var items: List<MigrationProcessItem> = emptyList()
|
||||
|
||||
@ -55,19 +78,16 @@ class MigrationProcessAdapter(
|
||||
|
||||
suspend fun performMigrations(copy: Boolean) {
|
||||
withIOContext {
|
||||
db.inTransaction {
|
||||
currentItems.forEach { migratingManga ->
|
||||
val manga = migratingManga.manga
|
||||
if (manga.searchResult.initialized) {
|
||||
val toMangaObj =
|
||||
db.getManga(manga.searchResult.get() ?: return@forEach).executeAsBlocking()
|
||||
?: return@forEach
|
||||
migrateMangaInternal(
|
||||
manga.manga() ?: return@forEach,
|
||||
toMangaObj,
|
||||
!copy,
|
||||
)
|
||||
}
|
||||
currentItems.forEach { migratingManga ->
|
||||
val manga = migratingManga.manga
|
||||
if (manga.searchResult.initialized) {
|
||||
val toMangaObj = getMangaById.await(manga.searchResult.get() ?: return@forEach)
|
||||
?: return@forEach
|
||||
migrateMangaInternal(
|
||||
manga.manga() ?: return@forEach,
|
||||
toMangaObj,
|
||||
!copy,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -76,16 +96,15 @@ class MigrationProcessAdapter(
|
||||
fun migrateManga(position: Int, copy: Boolean) {
|
||||
launchUI {
|
||||
val manga = getItem(position)?.manga ?: return@launchUI
|
||||
db.inTransaction {
|
||||
val toMangaObj =
|
||||
db.getManga(manga.searchResult.get() ?: return@launchUI).executeAsBlocking()
|
||||
?: return@launchUI
|
||||
migrateMangaInternal(
|
||||
manga.manga() ?: return@launchUI,
|
||||
toMangaObj,
|
||||
!copy,
|
||||
)
|
||||
}
|
||||
|
||||
val toMangaObj = getMangaById.await(manga.searchResult.get() ?: return@launchUI)
|
||||
?: return@launchUI
|
||||
migrateMangaInternal(
|
||||
manga.manga() ?: return@launchUI,
|
||||
toMangaObj,
|
||||
!copy,
|
||||
)
|
||||
|
||||
removeManga(position)
|
||||
}
|
||||
}
|
||||
@ -107,7 +126,7 @@ class MigrationProcessAdapter(
|
||||
sourceFinished()
|
||||
}
|
||||
|
||||
private fun migrateMangaInternal(
|
||||
private suspend fun migrateMangaInternal(
|
||||
prevManga: Manga,
|
||||
manga: Manga,
|
||||
replace: Boolean,
|
||||
@ -116,69 +135,87 @@ class MigrationProcessAdapter(
|
||||
val flags = preferences.migrateFlags().get()
|
||||
// Update chapters read
|
||||
if (MigrationFlags.hasChapters(flags)) {
|
||||
val prevMangaChapters = db.getChapters(prevManga).executeAsBlocking()
|
||||
val prevMangaChapters = getChapterByMangaId.await(prevManga.id)
|
||||
val maxChapterRead =
|
||||
prevMangaChapters.filter(Chapter::read).maxOfOrNull(Chapter::chapter_number)
|
||||
val dbChapters = db.getChapters(manga).executeAsBlocking()
|
||||
val prevHistoryList = db.getHistoryByMangaId(prevManga.id!!).executeAsBlocking()
|
||||
val historyList = mutableListOf<History>()
|
||||
prevMangaChapters.filter(Chapter::read).maxOfOrNull(Chapter::chapterNumber)
|
||||
val dbChapters = getChapterByMangaId.await(manga.id)
|
||||
val prevHistoryList = handler.awaitList { historyQueries.getHistoryByMangaId(prevManga.id, historyMapper) }
|
||||
|
||||
val chapterUpdates = mutableListOf<ChapterUpdate>()
|
||||
val historyUpdates = mutableListOf<HistoryUpdate>()
|
||||
|
||||
dbChapters.forEach { chapter ->
|
||||
if (chapter.isRecognizedNumber) {
|
||||
val prevChapter =
|
||||
prevMangaChapters.find { it.isRecognizedNumber && it.chapter_number == chapter.chapter_number }
|
||||
val prevChapter = prevMangaChapters.find { it.isRecognizedNumber && it.chapterNumber == chapter.chapterNumber }
|
||||
if (prevChapter != null) {
|
||||
chapter.bookmark = prevChapter.bookmark
|
||||
chapter.read = prevChapter.read
|
||||
chapter.date_fetch = prevChapter.date_fetch
|
||||
prevHistoryList.find { it.chapter_id == prevChapter.id }?.let { prevHistory ->
|
||||
val history = History.create(chapter).apply { last_read = prevHistory.last_read }
|
||||
historyList.add(history)
|
||||
chapterUpdates += ChapterUpdate(
|
||||
id = chapter.id,
|
||||
bookmark = prevChapter.bookmark,
|
||||
read = prevChapter.read,
|
||||
dateFetch = prevChapter.dateFetch,
|
||||
)
|
||||
prevHistoryList.find { it.chapterId == prevChapter.id }?.let { prevHistory ->
|
||||
historyUpdates += HistoryUpdate(
|
||||
chapter.id,
|
||||
prevHistory.readAt ?: return@let,
|
||||
prevHistory.readDuration,
|
||||
)
|
||||
}
|
||||
} else if (maxChapterRead != null && chapter.chapter_number <= maxChapterRead) {
|
||||
chapter.read = true
|
||||
} else if (maxChapterRead != null && chapter.chapterNumber <= maxChapterRead) {
|
||||
chapterUpdates += ChapterUpdate(
|
||||
id = chapter.id,
|
||||
read = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
db.insertChapters(dbChapters).executeAsBlocking()
|
||||
db.upsertHistoryLastRead(historyList).executeAsBlocking()
|
||||
|
||||
updateChapter.awaitAll(chapterUpdates)
|
||||
historyUpdates.forEach {
|
||||
upsertHistory.await(it)
|
||||
}
|
||||
}
|
||||
// Update categories
|
||||
if (MigrationFlags.hasCategories(flags)) {
|
||||
val categories = db.getCategoriesForManga(prevManga).executeAsBlocking()
|
||||
val mangaCategories = categories.map { MangaCategory.create(manga, it) }
|
||||
db.setMangaCategories(mangaCategories, listOf(manga))
|
||||
val categories = getCategories.await(prevManga.id)
|
||||
setMangaCategories.await(manga.id, categories.map { it.id })
|
||||
}
|
||||
// Update track
|
||||
if (MigrationFlags.hasTracks(flags)) {
|
||||
val tracks = db.getTracks(prevManga.id).executeAsBlocking()
|
||||
val tracks = getTracks.await(prevManga.id)
|
||||
if (tracks.isNotEmpty()) {
|
||||
tracks.forEach { track ->
|
||||
track.id = null
|
||||
track.manga_id = manga.id!!
|
||||
getTracks.await(manga.id).forEach {
|
||||
deleteTrack.await(manga.id, it.syncId)
|
||||
}
|
||||
db.insertTracks(tracks).executeAsBlocking()
|
||||
insertTrack.awaitAll(tracks.map { it.copy(mangaId = manga.id) })
|
||||
}
|
||||
}
|
||||
// Update custom cover
|
||||
if (MigrationFlags.hasCustomCover(flags) && prevManga.hasCustomCover(coverCache)) {
|
||||
coverCache.setCustomCoverToCache(manga, coverCache.getCustomCoverFile(prevManga.id).inputStream())
|
||||
coverCache.setCustomCoverToCache(manga.toDbManga(), coverCache.getCustomCoverFile(prevManga.id).inputStream())
|
||||
}
|
||||
|
||||
var mangaUpdate = MangaUpdate(manga.id, favorite = true, dateAdded = System.currentTimeMillis())
|
||||
var prevMangaUpdate: MangaUpdate? = null
|
||||
// Update extras
|
||||
if (MigrationFlags.hasExtra(flags)) {
|
||||
manga.chapter_flags = prevManga.chapter_flags
|
||||
manga.viewer_flags = prevManga.viewer_flags
|
||||
mangaUpdate = mangaUpdate.copy(
|
||||
chapterFlags = prevManga.chapterFlags,
|
||||
viewerFlags = prevManga.viewerFlags,
|
||||
)
|
||||
}
|
||||
// Update favorite status
|
||||
if (replace) {
|
||||
prevManga.favorite = false
|
||||
manga.date_added = prevManga.date_added
|
||||
prevManga.date_added = 0
|
||||
db.updateMangaFavorite(prevManga).executeAsBlocking()
|
||||
} else {
|
||||
manga.date_added = System.currentTimeMillis()
|
||||
prevMangaUpdate = MangaUpdate(
|
||||
id = prevManga.id,
|
||||
favorite = false,
|
||||
dateAdded = 0,
|
||||
)
|
||||
mangaUpdate = mangaUpdate.copy(
|
||||
dateAdded = prevManga.dateAdded,
|
||||
)
|
||||
}
|
||||
manga.favorite = true
|
||||
|
||||
db.updateMangaMigrate(manga).executeAsBlocking()
|
||||
updateManga.awaitAll(listOfNotNull(mangaUpdate, prevMangaUpdate))
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,11 @@ import androidx.core.view.isInvisible
|
||||
import androidx.core.view.isVisible
|
||||
import coil.dispose
|
||||
import eu.davidea.viewholders.FlexibleViewHolder
|
||||
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
||||
import eu.kanade.domain.manga.interactor.GetMangaById
|
||||
import eu.kanade.domain.manga.interactor.GetMergedReferencesById
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.databinding.MigrationMangaCardBinding
|
||||
import eu.kanade.tachiyomi.databinding.MigrationProcessItemBinding
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
@ -19,7 +21,6 @@ import eu.kanade.tachiyomi.util.lang.launchUI
|
||||
import eu.kanade.tachiyomi.util.view.loadAutoPause
|
||||
import eu.kanade.tachiyomi.util.view.setVectorCompat
|
||||
import exh.source.MERGED_SOURCE_ID
|
||||
import exh.util.executeOnIO
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
@ -30,8 +31,10 @@ class MigrationProcessHolder(
|
||||
private val view: View,
|
||||
private val adapter: MigrationProcessAdapter,
|
||||
) : FlexibleViewHolder(view, adapter) {
|
||||
private val db: DatabaseHelper by injectLazy()
|
||||
private val sourceManager: SourceManager by injectLazy()
|
||||
private val getMangaById: GetMangaById by injectLazy()
|
||||
private val getChapterByMangaId: GetChapterByMangaId by injectLazy()
|
||||
private val getMergedReferencesById: GetMergedReferencesById by injectLazy()
|
||||
|
||||
private var item: MigrationProcessItem? = null
|
||||
private val binding = MigrationProcessItemBinding.bind(view)
|
||||
@ -67,7 +70,7 @@ class MigrationProcessHolder(
|
||||
.onEach {
|
||||
adapter.controller.router.pushController(
|
||||
MangaController(
|
||||
manga.id!!,
|
||||
manga.id,
|
||||
true,
|
||||
),
|
||||
)
|
||||
@ -86,7 +89,7 @@ class MigrationProcessHolder(
|
||||
}*/
|
||||
|
||||
val searchResult = item.manga.searchResult.get()?.let {
|
||||
db.getManga(it).executeOnIO()
|
||||
getMangaById.await(it)
|
||||
}
|
||||
val resultSource = searchResult?.source?.let {
|
||||
sourceManager.get(it)
|
||||
@ -103,7 +106,7 @@ class MigrationProcessHolder(
|
||||
.onEach {
|
||||
adapter.controller.router.pushController(
|
||||
MangaController(
|
||||
searchResult.id!!,
|
||||
searchResult.id,
|
||||
true,
|
||||
),
|
||||
)
|
||||
@ -143,24 +146,24 @@ class MigrationProcessHolder(
|
||||
title.text = if (manga.title.isBlank()) {
|
||||
view.context.getString(R.string.unknown)
|
||||
} else {
|
||||
manga.originalTitle
|
||||
manga.ogTitle
|
||||
}
|
||||
|
||||
mangaSourceLabel.text = if (source.id == MERGED_SOURCE_ID) {
|
||||
db.getMergedMangaReferences(manga.id!!).executeOnIO().map {
|
||||
getMergedReferencesById.await(manga.id).map {
|
||||
sourceManager.getOrStub(it.mangaSourceId).toString()
|
||||
}.distinct().joinToString()
|
||||
} else {
|
||||
source.toString()
|
||||
}
|
||||
|
||||
val chapters = db.getChapters(manga).executeOnIO()
|
||||
val chapters = getChapterByMangaId.await(manga.id)
|
||||
// For rounded corners
|
||||
badges.leftBadges.clipToOutline = true
|
||||
badges.rightBadges.clipToOutline = true
|
||||
badges.unreadText.isVisible = true
|
||||
badges.unreadText.text = chapters.size.toString()
|
||||
val latestChapter = chapters.maxByOrNull { it.chapter_number }?.chapter_number ?: -1f
|
||||
val latestChapter = chapters.maxOfOrNull { it.chapterNumber } ?: -1f
|
||||
|
||||
if (latestChapter > 0f) {
|
||||
mangaLastChapterLabel.text = root.context.getString(
|
||||
|
Loading…
x
Reference in New Issue
Block a user