diff --git a/app/src/main/java/eu/kanade/data/manga/MangaRepositoryImpl.kt b/app/src/main/java/eu/kanade/data/manga/MangaRepositoryImpl.kt new file mode 100644 index 000000000..137d2ec0d --- /dev/null +++ b/app/src/main/java/eu/kanade/data/manga/MangaRepositoryImpl.kt @@ -0,0 +1,15 @@ +package eu.kanade.data.manga + +import eu.kanade.data.DatabaseHandler +import eu.kanade.domain.manga.model.Manga +import eu.kanade.domain.manga.repository.MangaRepository +import kotlinx.coroutines.flow.Flow + +class MangaRepositoryImpl( + private val databaseHandler: DatabaseHandler +) : MangaRepository { + + override fun getFavoritesBySourceId(sourceId: Long): Flow> { + return databaseHandler.subscribeToList { mangasQueries.getFavoriteBySourceId(sourceId, mangaMapper) } + } +} diff --git a/app/src/main/java/eu/kanade/domain/DomainModule.kt b/app/src/main/java/eu/kanade/domain/DomainModule.kt index a6c3957f4..e870ff9a9 100644 --- a/app/src/main/java/eu/kanade/domain/DomainModule.kt +++ b/app/src/main/java/eu/kanade/domain/DomainModule.kt @@ -1,6 +1,7 @@ package eu.kanade.domain import eu.kanade.data.history.HistoryRepositoryImpl +import eu.kanade.data.manga.MangaRepositoryImpl import eu.kanade.data.source.SourceRepositoryImpl import eu.kanade.domain.history.interactor.DeleteHistoryTable import eu.kanade.domain.history.interactor.GetHistory @@ -8,6 +9,8 @@ import eu.kanade.domain.history.interactor.GetNextChapterForManga import eu.kanade.domain.history.interactor.RemoveHistoryById import eu.kanade.domain.history.interactor.RemoveHistoryByMangaId import eu.kanade.domain.history.repository.HistoryRepository +import eu.kanade.domain.manga.interactor.GetFavoritesBySourceId +import eu.kanade.domain.manga.repository.MangaRepository import eu.kanade.domain.source.interactor.DisableSource import eu.kanade.domain.source.interactor.GetEnabledSources import eu.kanade.domain.source.interactor.GetShowLatest @@ -27,6 +30,8 @@ import uy.kohesive.injekt.api.get class DomainModule : InjektModule { override fun InjektRegistrar.registerInjectables() { + addSingletonFactory { MangaRepositoryImpl(get()) } + addFactory { GetFavoritesBySourceId(get()) } addFactory { GetNextChapterForManga(get()) } addSingletonFactory { HistoryRepositoryImpl(get()) } diff --git a/app/src/main/java/eu/kanade/domain/manga/interactor/GetFavoritesBySourceId.kt b/app/src/main/java/eu/kanade/domain/manga/interactor/GetFavoritesBySourceId.kt new file mode 100644 index 000000000..9fd42effa --- /dev/null +++ b/app/src/main/java/eu/kanade/domain/manga/interactor/GetFavoritesBySourceId.kt @@ -0,0 +1,14 @@ +package eu.kanade.domain.manga.interactor + +import eu.kanade.domain.manga.model.Manga +import eu.kanade.domain.manga.repository.MangaRepository +import kotlinx.coroutines.flow.Flow + +class GetFavoritesBySourceId( + private val mangaRepository: MangaRepository +) { + + fun subscribe(sourceId: Long): Flow> { + return mangaRepository.getFavoritesBySourceId(sourceId) + } +} diff --git a/app/src/main/java/eu/kanade/domain/manga/repository/MangaRepository.kt b/app/src/main/java/eu/kanade/domain/manga/repository/MangaRepository.kt new file mode 100644 index 000000000..8fb60a78a --- /dev/null +++ b/app/src/main/java/eu/kanade/domain/manga/repository/MangaRepository.kt @@ -0,0 +1,9 @@ +package eu.kanade.domain.manga.repository + +import eu.kanade.domain.manga.model.Manga +import kotlinx.coroutines.flow.Flow + +interface MangaRepository { + + fun getFavoritesBySourceId(sourceId: Long): Flow> +} diff --git a/app/src/main/java/eu/kanade/presentation/manga/components/BaseMangaListItem.kt b/app/src/main/java/eu/kanade/presentation/manga/components/BaseMangaListItem.kt new file mode 100644 index 000000000..1f00c52ba --- /dev/null +++ b/app/src/main/java/eu/kanade/presentation/manga/components/BaseMangaListItem.kt @@ -0,0 +1,65 @@ +package eu.kanade.presentation.manga.components + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import eu.kanade.domain.manga.model.Manga +import eu.kanade.presentation.components.MangaCover +import eu.kanade.presentation.util.horizontalPadding + +@Composable +fun BaseMangaListItem( + modifier: Modifier = Modifier, + manga: Manga, + onClickItem: () -> Unit = {}, + onClickCover: () -> Unit = onClickItem, + cover: @Composable RowScope.() -> Unit = { defaultCover(manga, onClickCover) }, + actions: @Composable RowScope.() -> Unit = {}, + content: @Composable RowScope.() -> Unit = { defaultContent(manga) }, +) { + Row( + modifier = modifier + .clickable(onClick = onClickItem) + .height(56.dp) + .padding(horizontal = horizontalPadding), + verticalAlignment = Alignment.CenterVertically + ) { + cover() + content() + actions() + } +} + +private val defaultCover: @Composable RowScope.(Manga, () -> Unit) -> Unit = { manga, onClick -> + MangaCover.Square( + modifier = Modifier + .padding(vertical = 8.dp) + .clickable(onClick = onClick) + .fillMaxHeight(), + data = manga.thumbnailUrl + ) +} + +private val defaultContent: @Composable RowScope.(Manga) -> Unit = { + Box(modifier = Modifier.weight(1f)) { + Text( + text = it.title, + modifier = Modifier + .padding(start = horizontalPadding), + overflow = TextOverflow.Ellipsis, + maxLines = 1, + style = MaterialTheme.typography.bodyMedium + ) + } +} diff --git a/app/src/main/java/eu/kanade/presentation/source/MigrateMangaScreen.kt b/app/src/main/java/eu/kanade/presentation/source/MigrateMangaScreen.kt new file mode 100644 index 000000000..2bb052638 --- /dev/null +++ b/app/src/main/java/eu/kanade/presentation/source/MigrateMangaScreen.kt @@ -0,0 +1,84 @@ +package eu.kanade.presentation.source + +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.asPaddingValues +import androidx.compose.foundation.layout.navigationBars +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.input.nestedscroll.NestedScrollConnection +import androidx.compose.ui.input.nestedscroll.nestedScroll +import eu.kanade.domain.manga.model.Manga +import eu.kanade.presentation.components.EmptyScreen +import eu.kanade.presentation.components.LoadingScreen +import eu.kanade.presentation.manga.components.BaseMangaListItem +import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.ui.browse.migration.manga.MigrateMangaState +import eu.kanade.tachiyomi.ui.browse.migration.manga.MigrationMangaPresenter + +@Composable +fun MigrateMangaScreen( + nestedScrollInterop: NestedScrollConnection, + presenter: MigrationMangaPresenter, + onClickItem: (Manga) -> Unit, + onClickCover: (Manga) -> Unit +) { + val state by presenter.state.collectAsState() + + when (state) { + MigrateMangaState.Loading -> LoadingScreen() + is MigrateMangaState.Error -> Text(text = (state as MigrateMangaState.Error).error.message!!) + is MigrateMangaState.Success -> { + MigrateMangaContent( + nestedScrollInterop = nestedScrollInterop, + list = (state as MigrateMangaState.Success).list, + onClickItem = onClickItem, + onClickCover = onClickCover, + ) + } + } +} + +@Composable +fun MigrateMangaContent( + nestedScrollInterop: NestedScrollConnection, + list: List, + onClickItem: (Manga) -> Unit, + onClickCover: (Manga) -> Unit +) { + if (list.isEmpty()) { + EmptyScreen(textResource = R.string.migrate_empty_screen) + return + } + LazyColumn( + modifier = Modifier.nestedScroll(nestedScrollInterop), + contentPadding = WindowInsets.navigationBars.asPaddingValues(), + ) { + items(list) { manga -> + MigrateMangaItem( + manga = manga, + onClickItem = onClickItem, + onClickCover = onClickCover + ) + } + } +} + +@Composable +fun MigrateMangaItem( + modifier: Modifier = Modifier, + manga: Manga, + onClickItem: (Manga) -> Unit, + onClickCover: (Manga) -> Unit +) { + BaseMangaListItem( + modifier = modifier, + manga = manga, + onClickItem = { onClickItem(manga) }, + onClickCover = { onClickCover(manga) } + ) +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/ComposeController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/ComposeController.kt index e43e5de41..2d77b2f87 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/ComposeController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/ComposeController.kt @@ -14,7 +14,7 @@ import nucleus.presenter.Presenter /** * Compose controller with a Nucleus presenter. */ -abstract class ComposeController

> : NucleusController() { +abstract class ComposeController

>(bundle: Bundle? = null) : NucleusController(bundle) { override fun createBinding(inflater: LayoutInflater): ComposeControllerBinding = ComposeControllerBinding.inflate(inflater) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaAdapter.kt deleted file mode 100644 index 389b76f72..000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaAdapter.kt +++ /dev/null @@ -1,14 +0,0 @@ -package eu.kanade.tachiyomi.ui.browse.migration.manga - -import eu.davidea.flexibleadapter.FlexibleAdapter -import eu.davidea.flexibleadapter.items.IFlexible - -class MigrationMangaAdapter(controller: MigrationMangaController) : - FlexibleAdapter>(null, controller, true) { - - val coverClickListener: OnCoverClickListener = controller - - interface OnCoverClickListener { - fun onCoverClick(position: Int) - } -} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaController.kt index fcf2c9c0b..82435e965 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaController.kt @@ -1,31 +1,19 @@ package eu.kanade.tachiyomi.ui.browse.migration.manga import android.os.Bundle -import android.view.LayoutInflater -import android.view.View +import androidx.compose.runtime.Composable +import androidx.compose.ui.input.nestedscroll.NestedScrollConnection import androidx.core.os.bundleOf -import androidx.recyclerview.widget.LinearLayoutManager -import dev.chrisbanes.insetter.applyInsetter -import eu.davidea.flexibleadapter.FlexibleAdapter -import eu.kanade.tachiyomi.data.database.models.Manga +import eu.kanade.presentation.source.MigrateMangaScreen import eu.kanade.tachiyomi.data.preference.PreferencesHelper -import eu.kanade.tachiyomi.databinding.MigrationMangaControllerBinding -import eu.kanade.tachiyomi.ui.base.controller.NucleusController +import eu.kanade.tachiyomi.ui.base.controller.ComposeController import eu.kanade.tachiyomi.ui.base.controller.pushController import eu.kanade.tachiyomi.ui.browse.migration.advanced.design.PreMigrationController import eu.kanade.tachiyomi.ui.manga.MangaController import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get -class MigrationMangaController : - NucleusController, - FlexibleAdapter.OnItemClickListener, - MigrationMangaAdapter.OnCoverClickListener, - // SY --> - MigrationInterface { - // SY <-- - - private var adapter: MigrationMangaAdapter? = null +class MigrationMangaController : ComposeController { constructor(sourceId: Long, sourceName: String?) : super( bundleOf( @@ -43,72 +31,30 @@ class MigrationMangaController : private val sourceId: Long = args.getLong(SOURCE_ID_EXTRA) private val sourceName: String? = args.getString(SOURCE_NAME_EXTRA) - override fun getTitle(): String? { - return sourceName - } + override fun getTitle(): String? = sourceName - override fun createPresenter(): MigrationMangaPresenter { - return MigrationMangaPresenter(sourceId) - } + override fun createPresenter(): MigrationMangaPresenter = MigrationMangaPresenter(sourceId) - override fun createBinding(inflater: LayoutInflater) = MigrationMangaControllerBinding.inflate(inflater) - - override fun onViewCreated(view: View) { - super.onViewCreated(view) - - binding.recycler.applyInsetter { - type(navigationBars = true) { - padding() + @Composable + override fun ComposeContent(nestedScrollInterop: NestedScrollConnection) { + MigrateMangaScreen( + nestedScrollInterop = nestedScrollInterop, + presenter = presenter, + onClickItem = { + PreMigrationController.navigateToMigration( + Injekt.get().skipPreMigration().get(), + router, + listOf(it.id), + ) + }, + onClickCover = { + router.pushController(MangaController(it.id)) } - } - - adapter = MigrationMangaAdapter(this) - binding.recycler.layoutManager = LinearLayoutManager(view.context) - binding.recycler.adapter = adapter - adapter?.fastScroller = binding.fastScroller - } - - override fun onDestroyView(view: View) { - adapter = null - super.onDestroyView(view) - } - - fun setManga(manga: List) { - adapter?.updateDataSet(manga) - } - - override fun onItemClick(view: View, position: Int): Boolean { - val item = adapter?.getItem(position) as? MigrationMangaItem ?: return false - // SY --> - PreMigrationController.navigateToMigration( - Injekt.get().skipPreMigration().get(), - router, - listOf(item.manga.id!!), ) - // SY <-- - return false } - override fun onCoverClick(position: Int) { - val mangaItem = adapter?.getItem(position) as? MigrationMangaItem ?: return - router.pushController(MangaController(mangaItem.manga)) - } - - // SY --> - override fun migrateManga(prevManga: Manga, manga: Manga, replace: Boolean): Manga? { - presenter.migrateManga(prevManga, manga, replace) - return null - } - // SY <-- - companion object { const val SOURCE_ID_EXTRA = "source_id_extra" const val SOURCE_NAME_EXTRA = "source_name_extra" } } - -// SY --> -interface MigrationInterface { - fun migrateManga(prevManga: Manga, manga: Manga, replace: Boolean): Manga? -} -// SY <-- diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaHolder.kt deleted file mode 100644 index 3e398f1bd..000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaHolder.kt +++ /dev/null @@ -1,29 +0,0 @@ -package eu.kanade.tachiyomi.ui.browse.migration.manga - -import android.view.View -import coil.dispose -import coil.load -import eu.davidea.viewholders.FlexibleViewHolder -import eu.kanade.tachiyomi.databinding.SourceListItemBinding - -class MigrationMangaHolder( - view: View, - private val adapter: MigrationMangaAdapter, -) : FlexibleViewHolder(view, adapter) { - - private val binding = SourceListItemBinding.bind(view) - - init { - binding.thumbnail.setOnClickListener { - adapter.coverClickListener.onCoverClick(bindingAdapterPosition) - } - } - - fun bind(item: MigrationMangaItem) { - binding.title.text = item.manga.originalTitle - - // Update the cover - binding.thumbnail.dispose() - binding.thumbnail.load(item.manga) - } -} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaItem.kt deleted file mode 100644 index 6ad16471b..000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaItem.kt +++ /dev/null @@ -1,40 +0,0 @@ -package eu.kanade.tachiyomi.ui.browse.migration.manga - -import android.view.View -import androidx.recyclerview.widget.RecyclerView -import eu.davidea.flexibleadapter.FlexibleAdapter -import eu.davidea.flexibleadapter.items.AbstractFlexibleItem -import eu.davidea.flexibleadapter.items.IFlexible -import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.database.models.Manga - -class MigrationMangaItem(val manga: Manga) : AbstractFlexibleItem() { - - override fun getLayoutRes(): Int { - return R.layout.source_list_item - } - - override fun createViewHolder(view: View, adapter: FlexibleAdapter>): MigrationMangaHolder { - return MigrationMangaHolder(view, adapter as MigrationMangaAdapter) - } - - override fun bindViewHolder( - adapter: FlexibleAdapter>, - holder: MigrationMangaHolder, - position: Int, - payloads: List?, - ) { - holder.bind(this) - } - - override fun equals(other: Any?): Boolean { - if (other is MigrationMangaItem) { - return manga.id == other.manga.id - } - return false - } - - override fun hashCode(): Int { - return manga.id!!.hashCode() - } -} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaPresenter.kt index 3df1b180c..f98a2de62 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrationMangaPresenter.kt @@ -1,136 +1,42 @@ package eu.kanade.tachiyomi.ui.browse.migration.manga import android.os.Bundle -import eu.kanade.tachiyomi.data.database.DatabaseHelper -import eu.kanade.tachiyomi.data.database.models.Manga -import eu.kanade.tachiyomi.data.database.models.MangaCategory -import eu.kanade.tachiyomi.data.database.models.toMangaInfo -import eu.kanade.tachiyomi.data.preference.PreferencesHelper -import eu.kanade.tachiyomi.data.track.EnhancedTrackService -import eu.kanade.tachiyomi.data.track.TrackManager -import eu.kanade.tachiyomi.source.Source -import eu.kanade.tachiyomi.source.model.SChapter -import eu.kanade.tachiyomi.source.model.toSChapter +import eu.kanade.domain.manga.interactor.GetFavoritesBySourceId +import eu.kanade.domain.manga.model.Manga import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter -import eu.kanade.tachiyomi.ui.browse.migration.MigrationFlags -import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource -import eu.kanade.tachiyomi.util.lang.runAsObservable -import exh.debug.DebugFunctions.sourceManager -import rx.Observable -import rx.android.schedulers.AndroidSchedulers -import rx.schedulers.Schedulers +import eu.kanade.tachiyomi.util.lang.launchIO +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.collectLatest import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get class MigrationMangaPresenter( private val sourceId: Long, - private val db: DatabaseHelper = Injekt.get(), + private val getFavoritesBySourceId: GetFavoritesBySourceId = Injekt.get() ) : BasePresenter() { - private val enhancedServices by lazy { Injekt.get().services.filterIsInstance() } + private val _state: MutableStateFlow = MutableStateFlow(MigrateMangaState.Loading) + val state: StateFlow = _state.asStateFlow() override fun onCreate(savedState: Bundle?) { super.onCreate(savedState) - - db.getFavoriteMangas() - .asRxObservable() - .observeOn(AndroidSchedulers.mainThread()) - .map { libraryToMigrationItem(it) } - .subscribeLatestCache(MigrationMangaController::setManga) - } - - private fun libraryToMigrationItem(library: List): List { - return library.filter { it.source == sourceId } - .sortedBy { it.originalTitle } - .map { MigrationMangaItem(it) } - } - - // SY --> - fun migrateManga(prevManga: Manga, manga: Manga, replace: Boolean) { - val source = sourceManager.get(manga.source) ?: return - val prevSource = sourceManager.get(prevManga.source) - - Observable.defer { runAsObservable { source.getChapterList(manga.toMangaInfo()).map { it.toSChapter() } } }.onErrorReturn { emptyList() } - .doOnNext { migrateMangaInternal(prevSource, source, it, prevManga, manga, replace) } - .onErrorReturn { emptyList() }.subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe() - } - - private fun migrateMangaInternal( - prevSource: Source?, - source: Source, - sourceChapters: List, - prevManga: Manga, - manga: Manga, - replace: Boolean, - ) { - val flags = Injekt.get().migrateFlags().get() - val migrateChapters = MigrationFlags.hasChapters(flags) - val migrateCategories = MigrationFlags.hasCategories(flags) - val migrateTracks = MigrationFlags.hasTracks(flags) - val migrateExtra = MigrationFlags.hasExtra(flags) - - db.inTransaction { - // Update chapters read - if (migrateChapters) { - try { - syncChaptersWithSource(db, sourceChapters, manga, source) - } catch (e: Exception) { - // Worst case, chapters won't be synced + presenterScope.launchIO { + getFavoritesBySourceId + .subscribe(sourceId) + .catch { exception -> + _state.emit(MigrateMangaState.Error(exception)) } - - val prevMangaChapters = db.getChapters(prevManga).executeAsBlocking() - val maxChapterRead = - prevMangaChapters.filter { it.read }.maxByOrNull { it.chapter_number }?.chapter_number - if (maxChapterRead != null) { - val dbChapters = db.getChapters(manga).executeAsBlocking() - for (chapter in dbChapters) { - if (chapter.isRecognizedNumber && chapter.chapter_number <= maxChapterRead) { - chapter.read = true - } - } - db.insertChapters(dbChapters).executeAsBlocking() + .collectLatest { list -> + _state.emit(MigrateMangaState.Success(list)) } - } - // Update categories - if (migrateCategories) { - val categories = db.getCategoriesForManga(prevManga).executeAsBlocking() - val mangaCategories = categories.map { MangaCategory.create(manga, it) } - db.setMangaCategories(mangaCategories, listOf(manga)) - } - // Update track - if (migrateTracks) { - val tracksToUpdate = db.getTracks(prevManga).executeAsBlocking().mapNotNull { track -> - track.id = null - track.manga_id = manga.id!! - - val service = enhancedServices - .firstOrNull { it.isTrackFrom(track, prevManga, prevSource) } - if (service != null) service.migrateTrack(track, manga, source) - else track - } - db.insertTracks(tracksToUpdate).executeAsBlocking() - } - - if (migrateExtra) { - manga.viewer_flags = prevManga.viewer_flags - manga.chapter_flags = prevManga.chapter_flags - } - - // 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() - } - // Set extra data - - manga.favorite = true - db.updateMangaMigrate(manga).executeAsBlocking() } } - // SY <-- +} + +sealed class MigrateMangaState { + object Loading : MigrateMangaState() + data class Error(val error: Throwable) : MigrateMangaState() + data class Success(val list: List) : MigrateMangaState() } diff --git a/app/src/main/res/layout/migration_manga_controller.xml b/app/src/main/res/layout/migration_manga_controller.xml deleted file mode 100644 index 368782972..000000000 --- a/app/src/main/res/layout/migration_manga_controller.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8093d988d..ec5e2854e 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -717,6 +717,7 @@ Select a source to migrate from Migrate Copy + Well, this is awkward Couldn\'t download chapters. You can try again in the downloads section diff --git a/app/src/main/sqldelight/data/mangas.sq b/app/src/main/sqldelight/data/mangas.sq index 9efcf3162..fe82b610c 100644 --- a/app/src/main/sqldelight/data/mangas.sq +++ b/app/src/main/sqldelight/data/mangas.sq @@ -37,4 +37,10 @@ source, count(*) FROM mangas WHERE favorite = 1 -GROUP BY source; \ No newline at end of file +GROUP BY source; + +getFavoriteBySourceId: +SELECT * +FROM mangas +WHERE favorite = 1 +AND source = :sourceId; \ No newline at end of file