mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-23 13:31:52 +01:00
Added option to migrate manga from manga details
Also copying manga date added to migrated manga
This commit is contained in:
parent
0b0f985e24
commit
3a4780e19b
@ -7,6 +7,7 @@ import eu.kanade.tachiyomi.data.database.DbProvider
|
||||
import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.database.resolvers.LibraryMangaGetResolver
|
||||
import eu.kanade.tachiyomi.data.database.resolvers.MangaDateAddedPutResolver
|
||||
import eu.kanade.tachiyomi.data.database.resolvers.MangaFavoritePutResolver
|
||||
import eu.kanade.tachiyomi.data.database.resolvers.MangaFlagsPutResolver
|
||||
import eu.kanade.tachiyomi.data.database.resolvers.MangaInfoPutResolver
|
||||
@ -92,6 +93,11 @@ interface MangaQueries : DbProvider {
|
||||
.withPutResolver(MangaFavoritePutResolver())
|
||||
.prepare()
|
||||
|
||||
fun updateMangaAdded(manga: Manga) = db.put()
|
||||
.`object`(manga)
|
||||
.withPutResolver(MangaDateAddedPutResolver())
|
||||
.prepare()
|
||||
|
||||
fun updateMangaViewer(manga: Manga) = db.put()
|
||||
.`object`(manga)
|
||||
.withPutResolver(MangaViewerPutResolver())
|
||||
|
@ -0,0 +1,31 @@
|
||||
package eu.kanade.tachiyomi.data.database.resolvers
|
||||
|
||||
import android.content.ContentValues
|
||||
import com.pushtorefresh.storio.sqlite.StorIOSQLite
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.inTransactionReturn
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
||||
|
||||
class MangaDateAddedPutResolver : PutResolver<Manga>() {
|
||||
|
||||
override fun performPut(db: StorIOSQLite, manga: Manga) = db.inTransactionReturn {
|
||||
val updateQuery = mapToUpdateQuery(manga)
|
||||
val contentValues = mapToContentValues(manga)
|
||||
|
||||
val numberOfRowsUpdated = db.lowLevel().update(updateQuery, contentValues)
|
||||
PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
|
||||
}
|
||||
|
||||
fun mapToUpdateQuery(manga: Manga) = UpdateQuery.builder()
|
||||
.table(MangaTable.TABLE)
|
||||
.where("${MangaTable.COL_ID} = ?")
|
||||
.whereArgs(manga.id)
|
||||
.build()
|
||||
|
||||
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
||||
put(MangaTable.COL_DATE_ADDED, manga.date_added)
|
||||
}
|
||||
}
|
@ -52,8 +52,6 @@ import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.main.RootSearchInterface
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationListController
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationProcedureConfig
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
@ -893,15 +891,7 @@ class LibraryController(
|
||||
}
|
||||
R.id.action_migrate -> {
|
||||
val skipPre = preferences.skipPreMigration().getOrDefault()
|
||||
router.pushController(
|
||||
if (skipPre) {
|
||||
MigrationListController.create(
|
||||
MigrationProcedureConfig(selectedMangas.mapNotNull { it.id }, null)
|
||||
)
|
||||
} else {
|
||||
PreMigrationController.create(selectedMangas.mapNotNull { it.id })
|
||||
}.withFadeTransaction().tag(if (skipPre) MigrationListController.TAG else null)
|
||||
)
|
||||
PreMigrationController.navigateToMigration(skipPre, router, selectedMangas.mapNotNull { it.id })
|
||||
destroyActionModeIfNeeded()
|
||||
}
|
||||
else -> return false
|
||||
|
@ -71,6 +71,7 @@ import eu.kanade.tachiyomi.data.download.DownloadService
|
||||
import eu.kanade.tachiyomi.data.download.model.Download
|
||||
import eu.kanade.tachiyomi.data.glide.GlideApp
|
||||
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||
import eu.kanade.tachiyomi.source.LocalSource
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
@ -89,6 +90,7 @@ import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
|
||||
import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersSortBottomSheet
|
||||
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
|
||||
import eu.kanade.tachiyomi.ui.manga.track.TrackingBottomSheet
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
|
||||
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
|
||||
@ -690,10 +692,15 @@ class MangaDetailsController : BaseController,
|
||||
menu.findItem(R.id.action_mark_all_as_unread).isVisible =
|
||||
!presenter.allUnread() && !presenter.isLockedFromSearch
|
||||
menu.findItem(R.id.action_remove_downloads).isVisible =
|
||||
presenter.hasDownloads() && !presenter.isLockedFromSearch
|
||||
presenter.hasDownloads() && !presenter.isLockedFromSearch &&
|
||||
manga?.source != LocalSource.ID
|
||||
menu.findItem(R.id.remove_non_bookmarked).isVisible =
|
||||
presenter.hasBookmark() && !presenter.isLockedFromSearch
|
||||
menu.findItem(R.id.action_mark_all_as_unread).isVisible = presenter.isTracked()
|
||||
menu.findItem(R.id.action_migrate).isVisible = !presenter.isLockedFromSearch &&
|
||||
manga?.source != LocalSource.ID && presenter.manga.favorite
|
||||
menu.findItem(R.id.action_migrate).title = view?.context?.getString(R.string.migrate_,
|
||||
presenter.manga.mangaType(view!!.context))
|
||||
val iconPrimary = view?.context?.getResourceColor(android.R.attr.textColorPrimary)
|
||||
?: Color.BLACK
|
||||
menu.findItem(R.id.action_download).icon?.mutate()?.setTint(iconPrimary)
|
||||
@ -753,6 +760,11 @@ class MangaDetailsController : BaseController,
|
||||
R.id.action_open_in_web_view -> openInWebView()
|
||||
R.id.action_add_to_home_screen -> addToHomeScreen()
|
||||
R.id.action_refresh_tracking -> presenter.refreshTrackers()
|
||||
R.id.action_migrate ->
|
||||
PreMigrationController.navigateToMigration(
|
||||
presenter.preferences.skipPreMigration().getOrDefault(),
|
||||
router,
|
||||
listOf(manga!!.id!!))
|
||||
R.id.action_mark_all_as_read -> {
|
||||
MaterialDialog(view!!.context).message(R.string.mark_all_chapters_as_read)
|
||||
.positiveButton(R.string.mark_as_read) {
|
||||
|
@ -11,10 +11,7 @@ import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationListController
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationProcedureConfig
|
||||
import eu.kanade.tachiyomi.util.system.await
|
||||
import eu.kanade.tachiyomi.util.system.launchUI
|
||||
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
|
||||
@ -111,10 +108,9 @@ class MigrationController : NucleusController<MigrationPresenter>(),
|
||||
val item = adapter?.getItem(position) ?: return false
|
||||
|
||||
if (item is MangaItem) {
|
||||
val controller = PreMigrationController.create(listOf(item.manga.id!!))
|
||||
controller.targetController = this
|
||||
|
||||
router.pushController(controller.withFadeTransaction())
|
||||
PreMigrationController.navigateToMigration(Injekt.get<PreferencesHelper>().skipPreMigration().getOrDefault(),
|
||||
router,
|
||||
listOf(item.manga.id!!))
|
||||
} else if (item is SourceItem) {
|
||||
presenter.setSelectedSource(item.source)
|
||||
}
|
||||
@ -135,15 +131,9 @@ class MigrationController : NucleusController<MigrationPresenter>(),
|
||||
val sourceMangas =
|
||||
manga.asSequence().filter { it.source == item.source.id }.map { it.id!! }.toList()
|
||||
withContext(Dispatchers.Main) {
|
||||
router.pushController(
|
||||
if (Injekt.get<PreferencesHelper>().skipPreMigration().getOrDefault()) {
|
||||
MigrationListController.create(
|
||||
MigrationProcedureConfig(sourceMangas, null)
|
||||
)
|
||||
} else {
|
||||
PreMigrationController.create(sourceMangas)
|
||||
}.withFadeTransaction()
|
||||
)
|
||||
PreMigrationController.navigateToMigration(Injekt.get<PreferencesHelper>().skipPreMigration().getOrDefault(),
|
||||
router,
|
||||
sourceMangas)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.bluelinelabs.conductor.Router
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
@ -152,6 +153,18 @@ class PreMigrationController(bundle: Bundle? = null) : BaseController(bundle), F
|
||||
companion object {
|
||||
private const val MANGA_IDS_EXTRA = "manga_ids"
|
||||
|
||||
fun navigateToMigration(skipPre: Boolean, router: Router, mangaIds: List<Long>) {
|
||||
router.pushController(
|
||||
if (skipPre) {
|
||||
MigrationListController.create(
|
||||
MigrationProcedureConfig(mangaIds, null)
|
||||
)
|
||||
} else {
|
||||
create(mangaIds)
|
||||
}.withFadeTransaction().tag(if (skipPre) MigrationListController.TAG else null)
|
||||
)
|
||||
}
|
||||
|
||||
fun create(mangaIds: List<Long>): PreMigrationController {
|
||||
return PreMigrationController(Bundle().apply {
|
||||
putLongArray(MANGA_IDS_EXTRA, mangaIds.toLongArray())
|
||||
|
@ -14,6 +14,7 @@ import androidx.core.graphics.ColorUtils
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
@ -27,10 +28,13 @@ import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.main.BottomNavBarInterface
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
|
||||
import eu.kanade.tachiyomi.ui.migration.MigrationMangaDialog
|
||||
import eu.kanade.tachiyomi.ui.migration.SearchController
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||
import eu.kanade.tachiyomi.util.system.await
|
||||
import eu.kanade.tachiyomi.util.system.executeOnIO
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import eu.kanade.tachiyomi.util.system.launchUI
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
@ -383,17 +387,40 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle),
|
||||
fun migrateMangas() {
|
||||
launchUI {
|
||||
adapter?.performMigrations(false)
|
||||
router.popCurrentController()
|
||||
navigateOut()
|
||||
}
|
||||
}
|
||||
|
||||
fun copyMangas() {
|
||||
launchUI {
|
||||
adapter?.performMigrations(true)
|
||||
router.popCurrentController()
|
||||
navigateOut()
|
||||
}
|
||||
}
|
||||
|
||||
private fun navigateOut() {
|
||||
if (migratingManga?.size == 1) {
|
||||
launchUI {
|
||||
val hasDetails = router.backstack.any { it.controller() is MangaDetailsController }
|
||||
if (hasDetails) {
|
||||
val manga = migratingManga?.firstOrNull()?.searchResult?.get()?.let {
|
||||
db.getManga(it).executeOnIO()
|
||||
}
|
||||
if (manga != null) {
|
||||
val newStack = router.backstack.filter {
|
||||
it.controller() !is MangaDetailsController &&
|
||||
it.controller() !is MigrationListController &&
|
||||
it.controller() !is PreMigrationController
|
||||
} + MangaDetailsController(manga).withFadeTransaction()
|
||||
router.setBackstack(newStack, FadeChangeHandler())
|
||||
return@launchUI
|
||||
}
|
||||
}
|
||||
router.popCurrentController()
|
||||
}
|
||||
} else router.popCurrentController()
|
||||
}
|
||||
|
||||
override fun handleBack(): Boolean {
|
||||
activity?.let {
|
||||
MaterialDialog(it).show {
|
||||
|
@ -13,6 +13,7 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.withContext
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.util.Date
|
||||
|
||||
class MigrationProcessAdapter(
|
||||
val controller: MigrationListController
|
||||
@ -101,8 +102,8 @@ class MigrationProcessAdapter(
|
||||
// Update chapters read
|
||||
if (MigrationFlags.hasChapters(flags)) {
|
||||
val prevMangaChapters = db.getChapters(prevManga).executeAsBlocking()
|
||||
val maxChapterRead = prevMangaChapters.filter { it.read }
|
||||
.maxBy { it.chapter_number }?.chapter_number
|
||||
val maxChapterRead =
|
||||
prevMangaChapters.filter { it.read }.maxBy { it.chapter_number }?.chapter_number
|
||||
if (maxChapterRead != null) {
|
||||
val dbChapters = db.getChapters(manga).executeAsBlocking()
|
||||
for (chapter in dbChapters) {
|
||||
@ -134,10 +135,10 @@ class MigrationProcessAdapter(
|
||||
db.updateMangaFavorite(prevManga).executeAsBlocking()
|
||||
}
|
||||
manga.favorite = true
|
||||
if (replace) manga.date_added = prevManga.date_added
|
||||
else manga.date_added = Date().time
|
||||
db.updateMangaFavorite(manga).executeAsBlocking()
|
||||
|
||||
// SearchPresenter#networkToLocalManga may have updated the manga title, so ensure db gets updated title
|
||||
db.updateMangaAdded(manga).executeAsBlocking()
|
||||
db.updateMangaTitle(manga).executeAsBlocking()
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
@ -73,6 +73,12 @@
|
||||
android:title="@string/edit"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_migrate"
|
||||
android:icon="@drawable/ic_swap_calls_white_24dp"
|
||||
android:title="@string/migrate"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_add_to_home_screen"
|
||||
android:title="@string/add_to_home_screen"
|
||||
|
@ -402,6 +402,7 @@
|
||||
<string name="copy_now">Copy now</string>
|
||||
<string name="select">Select</string>
|
||||
<string name="migrate">Migrate</string>
|
||||
<string name="migrate_">Migrate %1$s</string>
|
||||
<string name="copy_value">Copy</string>
|
||||
<string name="no_chapters_found_for_migration">No chapters found, this manga cannot be used for
|
||||
migration</string>
|
||||
|
Loading…
Reference in New Issue
Block a user