diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt index f9a821c04..1f7a43d28 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt @@ -165,6 +165,16 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att subscriptions += controller.selectionRelay .subscribe { onSelectionChanged(it) } + + subscriptions += controller.selectAllRelay + .subscribe { + if (it == category.id) { + adapter.currentItems.forEach { item -> + controller.setSelection(item.manga, true) + } + controller.invalidateActionMode() + } + } } fun onRecycle() { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index 20c1ef9a8..3b7f5b46b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -99,6 +99,8 @@ class LibraryController( */ val libraryMangaRelay: BehaviorRelay = BehaviorRelay.create() + val selectAllRelay: PublishRelay = PublishRelay.create() + /** * Number of manga per row in grid mode. */ @@ -436,6 +438,9 @@ class LibraryController( } R.id.action_move_to_category -> showChangeMangaCategoriesDialog() R.id.action_delete -> showDeleteMangaDialog() + R.id.action_select_all -> { + selectAllRelay.call(activeCategory) + } R.id.action_auto_source_migration -> { router.pushController(MigrationDesignController.create( selectedMangas.mapNotNull { it.id } diff --git a/app/src/main/java/exh/smartsearch/SmartSearchEngine.kt b/app/src/main/java/exh/smartsearch/SmartSearchEngine.kt index 26ea3ac60..66255b895 100644 --- a/app/src/main/java/exh/smartsearch/SmartSearchEngine.kt +++ b/app/src/main/java/exh/smartsearch/SmartSearchEngine.kt @@ -13,7 +13,8 @@ import rx.schedulers.Schedulers import uy.kohesive.injekt.injectLazy import kotlin.coroutines.CoroutineContext -class SmartSearchEngine(parentContext: CoroutineContext): CoroutineScope { +class SmartSearchEngine(parentContext: CoroutineContext, + val extraSearchParams: String? = null): CoroutineScope { override val coroutineContext: CoroutineContext = parentContext + Job() + Dispatchers.Default private val db: DatabaseHelper by injectLazy() @@ -26,7 +27,11 @@ class SmartSearchEngine(parentContext: CoroutineContext): CoroutineScope { val eligibleManga = supervisorScope { queries.map { query -> async(Dispatchers.Default) { - val searchResults = source.fetchSearchManga(1, query, FilterList()).toSingle().await(Schedulers.io()) + val builtQuery = if(extraSearchParams != null) { + "$query ${extraSearchParams.trim()}" + } else title + + val searchResults = source.fetchSearchManga(1, builtQuery, FilterList()).toSingle().await(Schedulers.io()) searchResults.mangas.map { val cleanedMangaTitle = cleanSmartSearchTitle(it.title) @@ -44,7 +49,10 @@ class SmartSearchEngine(parentContext: CoroutineContext): CoroutineScope { suspend fun normalSearch(source: CatalogueSource, title: String): SManga? { val eligibleManga = supervisorScope { - val searchResults = source.fetchSearchManga(1, title, FilterList()).toSingle().await(Schedulers.io()) + val searchQuery = if(extraSearchParams != null) { + "$title ${extraSearchParams.trim()}" + } else title + val searchResults = source.fetchSearchManga(1, searchQuery, FilterList()).toSingle().await(Schedulers.io()) searchResults.mangas.map { val normalizedDistance = NormalizedLevenshtein().similarity(title, it.title) @@ -80,7 +88,7 @@ class SmartSearchEngine(parentContext: CoroutineContext): CoroutineScope { ) return searchQueries.map { - it.joinToString().trim() + it.joinToString(" ").trim() }.distinct() } @@ -167,8 +175,8 @@ class SmartSearchEngine(parentContext: CoroutineContext): CoroutineScope { } companion object { - const val MIN_SMART_ELIGIBLE_THRESHOLD = 0.7 - const val MIN_NORMAL_ELIGIBLE_THRESHOLD = 0.5 + const val MIN_SMART_ELIGIBLE_THRESHOLD = 0.4 + const val MIN_NORMAL_ELIGIBLE_THRESHOLD = 0.4 private val titleRegex = Regex("[^a-zA-Z0-9- ]") private val consecutiveSpacesRegex = Regex(" +") diff --git a/app/src/main/java/exh/ui/migration/manga/design/MigrationDesignController.kt b/app/src/main/java/exh/ui/migration/manga/design/MigrationDesignController.kt index 3c358edb7..f1c0f443d 100644 --- a/app/src/main/java/exh/ui/migration/manga/design/MigrationDesignController.kt +++ b/app/src/main/java/exh/ui/migration/manga/design/MigrationDesignController.kt @@ -11,13 +11,14 @@ import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.migration.MigrationFlags +import eu.kanade.tachiyomi.util.gone +import eu.kanade.tachiyomi.util.visible import exh.ui.base.BaseExhController import exh.ui.migration.manga.process.MigrationProcedureConfig import exh.ui.migration.manga.process.MigrationProcedureController import kotlinx.android.synthetic.main.eh_migration_design.* import uy.kohesive.injekt.injectLazy -// TODO Handle config changes // TODO Select all in library class MigrationDesignController(bundle: Bundle? = null) : BaseExhController(bundle), FlexibleAdapter.OnItemClickListener { private val sourceManager: SourceManager by injectLazy() @@ -29,6 +30,8 @@ class MigrationDesignController(bundle: Bundle? = null) : BaseExhController(bund private val config: LongArray = args.getLongArray(MANGA_IDS_EXTRA) ?: LongArray(0) + private var showingOptions = false + override fun getTitle() = "Select target sources" override fun onViewCreated(view: View) { @@ -53,13 +56,33 @@ class MigrationDesignController(bundle: Bundle? = null) : BaseExhController(bund use_smart_search.toggle() } + copy_manga_desc.setOnClickListener { + copy_manga.toggle() + } + + extra_search_param_desc.setOnClickListener { + extra_search_param.toggle() + } + prioritize_chapter_count.setOnCheckedChangeListener { _, b -> updatePrioritizeChapterCount(b) } + extra_search_param.setOnCheckedChangeListener { _, b -> + updateOptionsState() + } + updatePrioritizeChapterCount(prioritize_chapter_count.isChecked) + updateOptionsState() + begin_migration_btn.setOnClickListener { + if(!showingOptions) { + showingOptions = true + updateOptionsState() + return@setOnClickListener + } + var flags = 0 if(mig_chapters.isChecked) flags = flags or MigrationFlags.CHAPTERS if(mig_categories.isChecked) flags = flags or MigrationFlags.CATEGORIES @@ -73,12 +96,41 @@ class MigrationDesignController(bundle: Bundle? = null) : BaseExhController(bund }.map { it.source.id }, useSourceWithMostChapters = prioritize_chapter_count.isChecked, enableLenientSearch = use_smart_search.isChecked, - migrationFlags = flags + migrationFlags = flags, + copy = copy_manga.isChecked, + extraSearchParams = if(extra_search_param.isChecked && extra_search_param_text.text.isNotBlank()) { + extra_search_param_text.text.toString() + } else null ) ).withFadeTransaction()) } } + fun updateOptionsState() { + if (showingOptions) { + begin_migration_btn.text = "Begin migration" + options_group.visible() + if(extra_search_param.isChecked) { + extra_search_param_text.visible() + } else { + extra_search_param_text.gone() + } + } else { + begin_migration_btn.text = "Next step" + options_group.gone() + extra_search_param_text.gone() + } + } + + override fun handleBack(): Boolean { + if(showingOptions) { + showingOptions = false + updateOptionsState() + return true + } + return super.handleBack() + } + override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) adapter?.onSaveInstanceState(outState) @@ -92,9 +144,9 @@ class MigrationDesignController(bundle: Bundle? = null) : BaseExhController(bund private fun updatePrioritizeChapterCount(migrationMode: Boolean) { migration_mode.text = if(migrationMode) { - "Use the source with the most chapters and use the above list to break ties (slow with many sources or smart search)" + "Currently using the source with the most chapters and the above list to break ties (slow with many sources or smart search)" } else { - "Use the first source in the list that has the manga" + "Currently using the first source in the list that has the manga" } } diff --git a/app/src/main/java/exh/ui/migration/manga/process/MigratingManga.kt b/app/src/main/java/exh/ui/migration/manga/process/MigratingManga.kt index 94eba088f..3707832e8 100644 --- a/app/src/main/java/exh/ui/migration/manga/process/MigratingManga.kt +++ b/app/src/main/java/exh/ui/migration/manga/process/MigratingManga.kt @@ -7,11 +7,7 @@ import eu.kanade.tachiyomi.source.SourceManager import exh.util.DeferredField import exh.util.await import kotlinx.coroutines.* -import kotlinx.coroutines.channels.BroadcastChannel -import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.ConflatedBroadcastChannel -import kotlinx.coroutines.channels.ReceiveChannel -import kotlinx.coroutines.flow.Flow import kotlin.coroutines.CoroutineContext class MigratingManga(private val db: DatabaseHelper, diff --git a/app/src/main/java/exh/ui/migration/manga/process/MigrationProcedureAdapter.kt b/app/src/main/java/exh/ui/migration/manga/process/MigrationProcedureAdapter.kt index 96d7dbbe1..436b94038 100644 --- a/app/src/main/java/exh/ui/migration/manga/process/MigrationProcedureAdapter.kt +++ b/app/src/main/java/exh/ui/migration/manga/process/MigrationProcedureAdapter.kt @@ -4,28 +4,22 @@ import android.support.v4.view.PagerAdapter import android.view.View import android.view.ViewGroup import com.bumptech.glide.load.engine.DiskCacheStrategy +import com.elvishew.xlog.XLog import com.google.gson.Gson 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.MangaCategory import eu.kanade.tachiyomi.data.glide.GlideApp -import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.SourceManager -import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.all.MergedSource import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.manga.MangaController -import eu.kanade.tachiyomi.ui.manga.info.MangaInfoController import eu.kanade.tachiyomi.ui.migration.MigrationFlags -import eu.kanade.tachiyomi.util.gone -import eu.kanade.tachiyomi.util.inflate -import eu.kanade.tachiyomi.util.syncChaptersWithSource -import eu.kanade.tachiyomi.util.visible +import eu.kanade.tachiyomi.util.* import exh.MERGED_SOURCE_ID -import exh.debug.DebugFunctions.sourceManager import exh.util.await import kotlinx.android.synthetic.main.eh_manga_card.view.* import kotlinx.android.synthetic.main.eh_migration_process_item.view.* @@ -33,6 +27,9 @@ import kotlinx.coroutines.* import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.collect import uy.kohesive.injekt.injectLazy +import java.text.DateFormat +import java.text.DecimalFormat +import java.util.* import kotlin.coroutines.CoroutineContext class MigrationProcedureAdapter(val controller: MigrationProcedureController, @@ -42,6 +39,8 @@ class MigrationProcedureAdapter(val controller: MigrationProcedureController, private val gson: Gson by injectLazy() private val sourceManager: SourceManager by injectLazy() + private val logger = XLog.tag(this::class.simpleName) + override fun isViewFromObject(p0: View, p1: Any): Boolean { return p0 == p1 } @@ -57,34 +56,51 @@ class MigrationProcedureAdapter(val controller: MigrationProcedureController, controller.nextMigration() } - view.accept_migration.setOnClickListener { - view.migrating_frame.visible() - } - val viewTag = ViewTag(coroutineContext) view.tag = viewTag view.setupView(viewTag, item) + view.accept_migration.setOnClickListener { + viewTag.launch(Dispatchers.Main) { + view.migrating_frame.visible() + try { + withContext(Dispatchers.Default) { + performMigration(item) + } + controller.nextMigration() + } catch(e: Exception) { + logger.e("Migration failure!", e) + controller.migrationFailure() + } + view.migrating_frame.gone() + } + } + return view } - fun performMigration() { + suspend fun performMigration(manga: MigratingManga) { + if(!manga.searchResult.initialized) { + return + } + val toMangaObj = db.getManga(manga.searchResult.get() ?: return).await() ?: return + + withContext(Dispatchers.IO) { + migrateMangaInternal( + manga.manga() ?: return@withContext, + toMangaObj, + !controller.config.copy + ) + } } - private fun migrateMangaInternal(source: Source, - sourceChapters: List, - prevManga: Manga, + + private fun migrateMangaInternal(prevManga: Manga, manga: Manga, replace: Boolean) { db.inTransaction { // Update chapters read - if (migrateChapters) { - try { - syncChaptersWithSource(db, sourceChapters, manga, source) - } catch (e: Exception) { - // Worst case, chapters won't be synced - } - + if (MigrationFlags.hasChapters(controller.config.migrationFlags)) { val prevMangaChapters = db.getChapters(prevManga).executeAsBlocking() val maxChapterRead = prevMangaChapters.filter { it.read } .maxBy { it.chapter_number }?.chapter_number @@ -99,13 +115,13 @@ class MigrationProcedureAdapter(val controller: MigrationProcedureController, } } // Update categories - if (migrateCategories) { + if (MigrationFlags.hasCategories(controller.config.migrationFlags)) { val categories = db.getCategoriesForManga(prevManga).executeAsBlocking() val mangaCategories = categories.map { MangaCategory.create(manga, it) } db.setMangaCategories(mangaCategories, listOf(manga)) } // Update track - if (migrateTracks) { + if (MigrationFlags.hasTracks(controller.config.migrationFlags)) { val tracks = db.getTracks(prevManga).executeAsBlocking() for (track in tracks) { track.id = null @@ -174,7 +190,7 @@ class MigrationProcedureAdapter(val controller: MigrationProcedureController, } } - fun View.attachManga(tag: ViewTag, manga: Manga, source: Source) { + suspend fun View.attachManga(tag: ViewTag, manga: Manga, source: Source) { // TODO Duplicated in MangaInfoController GlideApp.with(context) @@ -221,6 +237,23 @@ class MigrationProcedureAdapter(val controller: MigrationProcedureController, SManga.LICENSED -> R.string.licensed else -> R.string.unknown }) + + val mangaChapters = db.getChapters(manga).await() + manga_chapters.text = mangaChapters.size.toString() + val latestChapter = mangaChapters.maxBy { it.chapter_number }?.chapter_number ?: -1f + val lastUpdate = Date(mangaChapters.maxBy { it.date_upload }?.date_upload ?: 0) + + if (latestChapter > 0f) { + manga_last_chapter.text = DecimalFormat("#.#").format(count) + } else { + manga_last_chapter.setText(R.string.unknown) + } + + if (lastUpdate.time != 0L) { + manga_last_update.text = DateFormat.getDateInstance(DateFormat.SHORT).format(lastUpdate) + } else { + manga_last_update.setText(R.string.unknown) + } } override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) { diff --git a/app/src/main/java/exh/ui/migration/manga/process/MigrationProcedureConfig.kt b/app/src/main/java/exh/ui/migration/manga/process/MigrationProcedureConfig.kt index 85611c815..d11b70bcc 100644 --- a/app/src/main/java/exh/ui/migration/manga/process/MigrationProcedureConfig.kt +++ b/app/src/main/java/exh/ui/migration/manga/process/MigrationProcedureConfig.kt @@ -9,5 +9,7 @@ data class MigrationProcedureConfig( val targetSourceIds: List, val useSourceWithMostChapters: Boolean, val enableLenientSearch: Boolean, - val migrationFlags: Int + val migrationFlags: Int, + val copy: Boolean, + val extraSearchParams: String? ): Parcelable \ No newline at end of file diff --git a/app/src/main/java/exh/ui/migration/manga/process/MigrationProcedureController.kt b/app/src/main/java/exh/ui/migration/manga/process/MigrationProcedureController.kt index 60d471660..0b9f5fddd 100644 --- a/app/src/main/java/exh/ui/migration/manga/process/MigrationProcedureController.kt +++ b/app/src/main/java/exh/ui/migration/manga/process/MigrationProcedureController.kt @@ -4,12 +4,13 @@ import android.content.pm.ActivityInfo import android.os.Build import android.os.Bundle import android.view.View +import com.afollestad.materialdialogs.MaterialDialog import com.elvishew.xlog.XLog import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.DatabaseHelper -import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.SourceManager +import eu.kanade.tachiyomi.util.syncChaptersWithSource import eu.kanade.tachiyomi.util.toast import exh.smartsearch.SmartSearchEngine import exh.ui.base.BaseExhController @@ -22,6 +23,7 @@ import rx.schedulers.Schedulers import uy.kohesive.injekt.injectLazy import java.util.concurrent.atomic.AtomicInteger +// TODO Will probably implode if activity is fully destroyed class MigrationProcedureController(bundle: Bundle? = null) : BaseExhController(bundle), CoroutineScope { override val layoutId = R.layout.eh_migration_process @@ -29,12 +31,12 @@ class MigrationProcedureController(bundle: Bundle? = null) : BaseExhController(b private var adapter: MigrationProcedureAdapter? = null - private val config: MigrationProcedureConfig = args.getParcelable(CONFIG_EXTRA) + val config: MigrationProcedureConfig = args.getParcelable(CONFIG_EXTRA) private val db: DatabaseHelper by injectLazy() private val sourceManager: SourceManager by injectLazy() - private val smartSearchEngine = SmartSearchEngine(coroutineContext) + private val smartSearchEngine = SmartSearchEngine(coroutineContext, config.extraSearchParams) private val logger = XLog.tag("MigrationProcedureController") @@ -74,11 +76,15 @@ class MigrationProcedureController(bundle: Bundle? = null) : BaseExhController(b } } - updateTitle() + pager.post { + // pager.currentItem doesn't appear to be valid if we don't do this in a post + updateTitle() + } } fun updateTitle() { titleText = "Migrate manga (${pager.currentItem + 1}/${adapter?.count ?: 0})" + setTitle() } fun nextMigration() { @@ -88,14 +94,23 @@ class MigrationProcedureController(bundle: Bundle? = null) : BaseExhController(b router.popCurrentController() } else { pager.setCurrentItem(pager.currentItem + 1, true) - updateTitle() launch(Dispatchers.Main) { - setTitle() + updateTitle() } } } } + fun migrationFailure() { + activity?.let { + MaterialDialog.Builder(it) + .title("Migration failure") + .content("An unknown error occured while migrating this manga!") + .positiveText("Ok") + .show() + } + } + suspend fun runMigrations(mangas: List) { val sources = config.targetSourceIds.mapNotNull { sourceManager.get(it) as? CatalogueSource } @@ -123,21 +138,22 @@ class MigrationProcedureController(bundle: Bundle? = null) : BaseExhController(b async { sourceSemaphore.withPermit { try { - supervisorScope { - val searchResult = if (config.enableLenientSearch) { - smartSearchEngine.smartSearch(source, mangaObj.title) - } else { - smartSearchEngine.normalSearch(source, mangaObj.title) - } + val searchResult = if (config.enableLenientSearch) { + smartSearchEngine.smartSearch(source, mangaObj.title) + } else { + smartSearchEngine.normalSearch(source, mangaObj.title) + } - if(searchResult != null) { - val localManga = smartSearchEngine.networkToLocalManga(searchResult, source.id) - val chapters = source.fetchChapterList(localManga).toSingle().await(Schedulers.io()) - manga.progress.send(validSources.size to processedSources.incrementAndGet()) - localManga to chapters.size - } else { - null + if(searchResult != null) { + val localManga = smartSearchEngine.networkToLocalManga(searchResult, source.id) + val chapters = source.fetchChapterList(localManga).toSingle().await(Schedulers.io()) + withContext(Dispatchers.IO) { + syncChaptersWithSource(db, chapters, localManga, source) } + manga.progress.send(validSources.size to processedSources.incrementAndGet()) + localManga to chapters.size + } else { + null } } catch(e: Exception) { logger.e("Failed to search in source: ${source.id}!", e) @@ -149,17 +165,20 @@ class MigrationProcedureController(bundle: Bundle? = null) : BaseExhController(b } else { validSources.forEachIndexed { index, source -> val searchResult = try { - supervisorScope { - val searchResult = if (config.enableLenientSearch) { - smartSearchEngine.smartSearch(source, mangaObj.title) - } else { - smartSearchEngine.normalSearch(source, mangaObj.title) - } - - if (searchResult != null) { - smartSearchEngine.networkToLocalManga(searchResult, source.id) - } else null + val searchResult = if (config.enableLenientSearch) { + smartSearchEngine.smartSearch(source, mangaObj.title) + } else { + smartSearchEngine.normalSearch(source, mangaObj.title) } + + if (searchResult != null) { + val localManga = smartSearchEngine.networkToLocalManga(searchResult, source.id) + val chapters = source.fetchChapterList(localManga).toSingle().await(Schedulers.io()) + withContext(Dispatchers.IO) { + syncChaptersWithSource(db, chapters, localManga, source) + } + localManga + } else null } catch(e: Exception) { logger.e("Failed to search in source: ${source.id}!", e) null @@ -180,15 +199,13 @@ class MigrationProcedureController(bundle: Bundle? = null) : BaseExhController(b if(result != null && result.thumbnail_url == null) { try { - supervisorScope { - val newManga = sourceManager.getOrStub(result.source) - .fetchMangaDetails(result) - .toSingle() - .await() - result.copyFrom(newManga) + val newManga = sourceManager.getOrStub(result.source) + .fetchMangaDetails(result) + .toSingle() + .await() + result.copyFrom(newManga) - db.insertManga(result).await() - } + db.insertManga(result).await() } catch(e: Exception) { logger.e("Could not load search manga details", e) } diff --git a/app/src/main/java/exh/util/DeferredField.kt b/app/src/main/java/exh/util/DeferredField.kt index 8137fcb79..bbaf501a3 100644 --- a/app/src/main/java/exh/util/DeferredField.kt +++ b/app/src/main/java/exh/util/DeferredField.kt @@ -41,6 +41,6 @@ class DeferredField { mutex.withLock {} // Field is initialized, return value - return content!! + return content as T } } \ No newline at end of file diff --git a/app/src/main/res/layout/eh_manga_card.xml b/app/src/main/res/layout/eh_manga_card.xml index eb83d4c11..6b1b64ac1 100644 --- a/app/src/main/res/layout/eh_manga_card.xml +++ b/app/src/main/res/layout/eh_manga_card.xml @@ -19,11 +19,10 @@ android:layout_height="0dp" android:layout_marginLeft="16dp" android:layout_marginTop="16dp" - android:layout_marginBottom="16dp" android:contentDescription="@string/description_cover" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintDimensionRatio="h,3:2" + app:layout_constraintDimensionRatio="l,2:3" app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintRight_toLeftOf="@+id/card_scroll_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintWidth_min="100dp" tools:background="@color/material_grey_700" /> @@ -31,10 +30,11 @@ @@ -130,6 +130,75 @@ app:layout_constraintLeft_toRightOf="@+id/manga_status_label" app:layout_constraintRight_toRightOf="parent" /> + + + + + + + + + + + + + app:layout_constraintTop_toBottomOf="@+id/manga_last_update_label" /> + app:layout_constraintTop_toBottomOf="@+id/manga_last_update_label" /> diff --git a/app/src/main/res/layout/eh_migration_design.xml b/app/src/main/res/layout/eh_migration_design.xml index 8c0314bf3..a7c58090a 100644 --- a/app/src/main/res/layout/eh_migration_design.xml +++ b/app/src/main/res/layout/eh_migration_design.xml @@ -35,8 +35,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="8dp" - android:text="@string/chapters" android:checked="true" + android:text="@string/chapters" app:layout_constraintBottom_toTopOf="@+id/textView" app:layout_constraintStart_toStartOf="@+id/textView2" /> @@ -46,8 +46,8 @@ android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" - android:text="@string/categories" android:checked="true" + android:text="@string/categories" app:layout_constraintBottom_toBottomOf="@+id/mig_chapters" app:layout_constraintStart_toEndOf="@+id/mig_chapters" /> @@ -57,8 +57,8 @@ android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" - android:text="@string/track" android:checked="true" + android:text="@string/track" app:layout_constraintBottom_toBottomOf="@+id/mig_categories" app:layout_constraintStart_toEndOf="@+id/mig_categories" /> @@ -92,6 +92,7 @@ android:layout_marginRight="8dp" android:layout_marginBottom="8dp" android:gravity="start|center_vertical" + android:clickable="true" app:layout_constraintBottom_toTopOf="@+id/fuzzy_search" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/prioritize_chapter_count" /> @@ -100,7 +101,6 @@ android:id="@+id/use_smart_search" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginBottom="8dp" app:layout_constraintStart_toStartOf="@+id/textView" app:layout_constraintTop_toTopOf="@+id/fuzzy_search" /> @@ -114,11 +114,73 @@ android:layout_marginRight="8dp" android:layout_marginBottom="8dp" android:gravity="start|center_vertical" - android:text="Use smart search algorithm" - app:layout_constraintBottom_toTopOf="@+id/begin_migration_btn" + android:text="Use intelligent search algorithm" + android:clickable="true" + app:layout_constraintBottom_toTopOf="@+id/copy_manga" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/prioritize_chapter_count" /> + + + + + + + + + +