mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-10 20:15:09 +01:00
Fixes to default grid size + older android versions
Spinner in title now only shows if there's multiple categories Subscreens in migrations now also prompts to stop migration before switching When hiding categories in single list mode, D&D sorting is renamed to "Category" Removed top margin from first category header
This commit is contained in:
parent
55bdd3b4d6
commit
bd9633dd08
@ -19,6 +19,8 @@ interface Category : Serializable {
|
||||
|
||||
var mangaSort:Char?
|
||||
|
||||
var isFirst:Boolean?
|
||||
|
||||
val nameLower: String
|
||||
get() = name.toLowerCase()
|
||||
|
||||
@ -85,9 +87,10 @@ interface Category : Serializable {
|
||||
LibrarySort.UNREAD -> UNREAD_ASC
|
||||
LibrarySort.LAST_READ -> LAST_READ_ASC
|
||||
LibrarySort.TOTAL -> TOTAL_ASC
|
||||
else -> 'D'
|
||||
LibrarySort.DRAG_AND_DROP -> DRAG_AND_DROP
|
||||
else -> DRAG_AND_DROP
|
||||
}
|
||||
if (mangaSort != 'D' && !ascending) {
|
||||
if (mangaSort != DRAG_AND_DROP && !ascending) {
|
||||
mangaSort?.plus(1)
|
||||
}
|
||||
order = -1
|
||||
|
@ -14,6 +14,8 @@ class CategoryImpl : Category {
|
||||
|
||||
override var mangaSort: Char? = null
|
||||
|
||||
override var isFirst: Boolean? = null
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || javaClass != other.javaClass) return false
|
||||
|
@ -52,7 +52,7 @@ class LibraryCategoryAdapter(val libraryListener: LibraryListener) :
|
||||
*/
|
||||
fun indexOf(categoryOrder: Int): Int {
|
||||
return currentItems.indexOfFirst {
|
||||
if (it is LibraryHeaderItem) it.gCategory().order == categoryOrder
|
||||
if (it is LibraryHeaderItem) it.category.order == categoryOrder
|
||||
else false }
|
||||
}
|
||||
|
||||
|
@ -576,8 +576,9 @@ open class LibraryController(
|
||||
}
|
||||
}
|
||||
R.id.action_migrate -> {
|
||||
val skipPre = preferences.skipPreMigration().getOrDefault()
|
||||
router.pushController(
|
||||
if (preferences.skipPreMigration().getOrDefault()) {
|
||||
if (skipPre) {
|
||||
MigrationListController.create(
|
||||
MigrationProcedureConfig(
|
||||
selectedMangas.mapNotNull { it.id },null)
|
||||
@ -586,7 +587,7 @@ open class LibraryController(
|
||||
else {
|
||||
PreMigrationController.create( selectedMangas.mapNotNull { it.id } )
|
||||
}
|
||||
.withFadeTransaction())
|
||||
.withFadeTransaction().tag(if (skipPre) MigrationListController.TAG else null))
|
||||
destroyActionModeIfNeeded()
|
||||
}
|
||||
/*R.id.action_to_top, R.id.action_to_bottom -> {
|
||||
|
@ -1,12 +1,14 @@
|
||||
package eu.kanade.tachiyomi.ui.library
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Build
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.view.menu.MenuBuilder
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.button.MaterialButton
|
||||
@ -18,9 +20,11 @@ import eu.davidea.viewholders.FlexibleViewHolder
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import eu.kanade.tachiyomi.util.system.launchUI
|
||||
import eu.kanade.tachiyomi.util.view.gone
|
||||
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
||||
import eu.kanade.tachiyomi.util.view.visible
|
||||
import kotlinx.android.synthetic.main.library_category_header_item.view.*
|
||||
|
||||
@ -47,13 +51,13 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
|
||||
holder.bind(categoryF(catId))
|
||||
}
|
||||
|
||||
var category:Category = categoryF(catId)
|
||||
fun gCategory():Category = categoryF(catId)
|
||||
val category:Category
|
||||
get() = categoryF(catId)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other is LibraryHeaderItem) {
|
||||
return gCategory().id == other.gCategory().id
|
||||
return category.id == other.category.id
|
||||
}
|
||||
return false
|
||||
}
|
||||
@ -67,7 +71,7 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return -(gCategory().id!!)
|
||||
return -(category.id!!)
|
||||
}
|
||||
|
||||
class Holder(val view: View, private val adapter: LibraryCategoryAdapter) :
|
||||
@ -81,16 +85,25 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
|
||||
|
||||
init {
|
||||
updateButton.setOnClickListener { addCategoryToUpdate() }
|
||||
sortText.setOnClickListener { showCatSortOptions() }
|
||||
sortText.setOnClickListener { it.post { showCatSortOptions() } }
|
||||
checkboxImage.setOnClickListener { selectAll() }
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||
sortText.compoundDrawablesRelative[2]?.mutate()?.setTint(
|
||||
ContextCompat.getColor(contentView.context, R.color.gray_button))
|
||||
}
|
||||
}
|
||||
|
||||
fun bind(category: Category) {
|
||||
sectionText.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||
topMargin = (if (category.isFirst == true) 2 else 32).dpToPx
|
||||
}
|
||||
sectionText.text = category.name
|
||||
sortText.text = itemView.context.getString(
|
||||
when (category.sortingMode()) {
|
||||
LibrarySort.LAST_UPDATED -> R.string.action_sort_last_updated
|
||||
LibrarySort.DRAG_AND_DROP -> R.string.action_sort_drag_and_drop
|
||||
LibrarySort.DRAG_AND_DROP ->
|
||||
if (category.id == -1) R.string.category
|
||||
else R.string.action_sort_drag_and_drop
|
||||
LibrarySort.TOTAL -> R.string.action_sort_total
|
||||
LibrarySort.UNREAD -> R.string.action_filter_unread
|
||||
LibrarySort.LAST_READ -> R.string.action_sort_last_read
|
||||
@ -134,7 +147,7 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
|
||||
}
|
||||
private fun showCatSortOptions() {
|
||||
val category =
|
||||
(adapter.getItem(adapterPosition) as? LibraryHeaderItem)?.gCategory() ?: return
|
||||
(adapter.getItem(adapterPosition) as? LibraryHeaderItem)?.category ?: return
|
||||
// Create a PopupMenu, giving it the clicked view for an anchor
|
||||
val popup = PopupMenu(itemView.context, view.category_sort)
|
||||
|
||||
@ -162,6 +175,11 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
|
||||
}
|
||||
)
|
||||
|
||||
if (category.id == -1)
|
||||
popup.menu.findItem(R.id.action_drag_and_drop).title = contentView.context.getString(
|
||||
R.string.category
|
||||
)
|
||||
|
||||
if (sortingMode != null && popup.menu is MenuBuilder) {
|
||||
val m = popup.menu as MenuBuilder
|
||||
m.setOptionalIconsVisible(true)
|
||||
@ -193,6 +211,10 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
|
||||
}
|
||||
else {
|
||||
val order = when (menuId) {
|
||||
R.id.action_drag_and_drop -> {
|
||||
adapter.libraryListener.sortCategory(category.id!!, 'D' - 'a' + 1)
|
||||
return
|
||||
}
|
||||
R.id.action_total_chaps -> 4
|
||||
R.id.action_last_read -> 3
|
||||
R.id.action_unread -> 2
|
||||
|
@ -54,7 +54,7 @@ class LibraryItem(val manga: LibraryManga,
|
||||
val marginParams = card.layoutParams as ConstraintLayout.LayoutParams
|
||||
marginParams.bottomMargin = 6.dpToPx
|
||||
card.layoutParams = marginParams
|
||||
cover_thumbnail.maxHeight = Integer.MAX_VALUE
|
||||
cover_thumbnail.maxHeight = coverHeight
|
||||
constraint_layout.minHeight = 0
|
||||
cover_thumbnail.adjustViewBounds = false
|
||||
cover_thumbnail.layoutParams = FrameLayout.LayoutParams(
|
||||
|
@ -9,6 +9,7 @@ import android.view.MenuInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Spinner
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.view.ActionMode
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.content.ContextCompat
|
||||
@ -72,7 +73,11 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
||||
override fun contentView():View = recycler_layout
|
||||
|
||||
override fun getTitle(): String? {
|
||||
return null
|
||||
return when {
|
||||
spinnerAdapter?.array?.size ?: 0 > 1 -> null
|
||||
spinnerAdapter?.array?.size == 1 -> return spinnerAdapter?.array?.firstOrNull()
|
||||
else -> return super.getTitle()
|
||||
}
|
||||
}
|
||||
|
||||
private var scrollListener = object : RecyclerView.OnScrollListener () {
|
||||
@ -81,7 +86,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
||||
val position =
|
||||
(recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
|
||||
val order = when (val item = adapter.getItem(position)) {
|
||||
is LibraryHeaderItem -> item.gCategory().order
|
||||
is LibraryHeaderItem -> item.category.order
|
||||
is LibraryItem -> presenter.categories.find { it.id == item.manga.category }?.order
|
||||
else -> null
|
||||
}
|
||||
@ -92,9 +97,10 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
||||
|
||||
bottom_sheet.lastCategory = category
|
||||
bottom_sheet.updateTitle()
|
||||
if (spinner.selectedItemPosition != order + 1) {
|
||||
val categortPosition = presenter.categories.indexOf(category)
|
||||
if (spinner.selectedItemPosition != categortPosition) {
|
||||
updateScroll = true
|
||||
spinner.setSelection(order + 1, true)
|
||||
spinner.setSelection(categortPosition, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -148,7 +154,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
||||
view.context, tv.resourceId
|
||||
)
|
||||
(activity as MainActivity).supportActionBar?.customView = spinner
|
||||
(activity as MainActivity).supportActionBar?.setDisplayShowCustomEnabled(true)
|
||||
(activity as MainActivity).supportActionBar?.setDisplayShowCustomEnabled(false)
|
||||
spinnerAdapter = SpinnerAdapter(
|
||||
view.context,
|
||||
R.layout.library_spinner_textview,
|
||||
@ -161,7 +167,9 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
||||
override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
|
||||
super.onChangeStarted(handler, type)
|
||||
if (type.isEnter) {
|
||||
(activity as MainActivity).supportActionBar?.setDisplayShowCustomEnabled(true)
|
||||
(activity as MainActivity).supportActionBar
|
||||
?.setDisplayShowCustomEnabled(router?.backstack?.lastOrNull()?.controller() ==
|
||||
this && spinnerAdapter?.array?.size ?: 0 > 1)
|
||||
}
|
||||
else if (type == ControllerChangeType.PUSH_EXIT) {
|
||||
(activity as MainActivity).toolbar.menu.findItem(R.id
|
||||
@ -187,11 +195,19 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
||||
|
||||
|
||||
spinner.onItemSelectedListener = null
|
||||
val categoryNames = presenter.categories.map { it.name }.toTypedArray()
|
||||
spinnerAdapter = SpinnerAdapter(spinner.context, R.layout.library_spinner_textview,
|
||||
presenter.categories.map { it.name }.toTypedArray())
|
||||
if (categoryNames.isNotEmpty()) categoryNames
|
||||
else arrayOf(spinner.context.getString(R.string.label_library))
|
||||
)
|
||||
spinnerAdapter?.setDropDownViewResource(R.layout.library_spinner_entry_text)
|
||||
spinner.adapter = spinnerAdapter
|
||||
|
||||
val isCurrentController = router?.backstack?.lastOrNull()?.controller() ==
|
||||
this
|
||||
(activity as AppCompatActivity).supportActionBar
|
||||
?.setDisplayShowCustomEnabled(isCurrentController && categoryNames.size > 1)
|
||||
if (isCurrentController) setTitle()
|
||||
|
||||
spinner.setSelection(min(presenter.categories.size - 1, activeCategory + 1))
|
||||
updateScroll = false
|
||||
@ -202,10 +218,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
||||
|
||||
|
||||
} else if (justStarted) {
|
||||
val position = if (freshStart) adapter.indexOf(activeCategory) else null
|
||||
if (position != null)
|
||||
(recycler.layoutManager as LinearLayoutManager)
|
||||
.scrollToPositionWithOffset(position, (-30).dpToPx)
|
||||
if (freshStart) scrollToHeader(activeCategory)
|
||||
}
|
||||
else {
|
||||
updateScroll = true
|
||||
@ -213,21 +226,25 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
||||
adapter.isLongPressDragEnabled = canDrag()
|
||||
tabsVisibilityRelay.call(false)
|
||||
|
||||
bottom_sheet.lastCategory = presenter.categories[MathUtils.clamp(
|
||||
bottom_sheet.lastCategory = presenter.categories.getOrNull(MathUtils.clamp(
|
||||
activeCategory, 0, presenter.categories.size - 1
|
||||
)]
|
||||
))
|
||||
bottom_sheet.updateTitle()
|
||||
spinner.onItemSelectedListener = IgnoreFirstSpinnerListener { pos ->
|
||||
if (updateScroll) {
|
||||
updateScroll = false
|
||||
return@IgnoreFirstSpinnerListener
|
||||
}
|
||||
val headerPosition = adapter.indexOf(pos - 1)
|
||||
if (headerPosition > -1) {
|
||||
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
|
||||
headerPosition, (-30).dpToPx
|
||||
)
|
||||
}
|
||||
scrollToHeader(pos - 1)
|
||||
}
|
||||
}
|
||||
|
||||
private fun scrollToHeader(pos: Int) {
|
||||
val headerPosition = adapter.indexOf(pos)
|
||||
if (headerPosition > -1) {
|
||||
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
|
||||
headerPosition, if (headerPosition == 0) 0 else (-30).dpToPx
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -345,8 +345,13 @@ class LibraryPresenter(
|
||||
}
|
||||
}
|
||||
|
||||
fun getCategory(categoryId: Int): Category {
|
||||
return categories.find { it.id == categoryId } ?: createDefaultCategory()
|
||||
private fun getCategory(categoryId: Int): Category {
|
||||
val category = categories.find { it.id == categoryId } ?: createDefaultCategory()
|
||||
if (category.isFirst == null) {
|
||||
category.isFirst = (category.id ?: 0 <= 0 ||
|
||||
(category.order == 0 && categories.none { it.id == 0 }))
|
||||
}
|
||||
return category
|
||||
}
|
||||
|
||||
private fun sortCategory(i1: LibraryItem, i2: LibraryItem,
|
||||
|
@ -26,10 +26,12 @@ import eu.kanade.tachiyomi.ui.base.controller.RxController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.TabbedController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.requestPermissionsSafe
|
||||
import eu.kanade.tachiyomi.ui.catalogue.CatalogueController
|
||||
import eu.kanade.tachiyomi.ui.main.BottomNavBarInterface
|
||||
import eu.kanade.tachiyomi.ui.main.SearchActivity
|
||||
import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersController
|
||||
import eu.kanade.tachiyomi.ui.manga.info.MangaInfoController
|
||||
import eu.kanade.tachiyomi.ui.manga.track.TrackController
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationListController
|
||||
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.android.synthetic.main.main_activity.*
|
||||
@ -40,7 +42,7 @@ import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.util.Date
|
||||
|
||||
class MangaController : RxController, TabbedController {
|
||||
class MangaController : RxController, TabbedController, BottomNavBarInterface {
|
||||
|
||||
constructor(manga: Manga?,
|
||||
fromCatalogue: Boolean = false,
|
||||
@ -216,6 +218,13 @@ class MangaController : RxController, TabbedController {
|
||||
//tab.icon = drawable
|
||||
}
|
||||
|
||||
override fun canChangeTabs(block: () -> Unit): Boolean {
|
||||
val migrationListController = router.getControllerWithTag(MigrationListController.TAG)
|
||||
as? BottomNavBarInterface
|
||||
if (migrationListController != null) return migrationListController.canChangeTabs(block)
|
||||
return true
|
||||
}
|
||||
|
||||
private inner class MangaDetailAdapter : RouterPagerAdapter(this@MangaController) {
|
||||
|
||||
private val tabCount = if (Injekt.get<TrackManager>().hasLoggedServices()) 3 else 2
|
||||
|
@ -18,12 +18,13 @@ import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController
|
||||
import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchPresenter
|
||||
import eu.kanade.tachiyomi.ui.main.BottomNavBarInterface
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationListController
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class SearchController(
|
||||
private var manga: Manga? = null
|
||||
) : CatalogueSearchController(manga?.originalTitle()) {
|
||||
) : CatalogueSearchController(manga?.originalTitle()), BottomNavBarInterface{
|
||||
|
||||
private var newManga: Manga? = null
|
||||
private var progress = 1
|
||||
@ -191,5 +192,10 @@ class SearchController(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun canChangeTabs(block: () -> Unit): Boolean {
|
||||
val migrationListController = router.getControllerWithTag(MigrationListController.TAG)
|
||||
as? BottomNavBarInterface
|
||||
if (migrationListController != null) return migrationListController.canChangeTabs(block)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -17,13 +17,12 @@ import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationListController
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationProcedureConfig
|
||||
import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets
|
||||
import eu.kanade.tachiyomi.util.view.marginBottom
|
||||
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
||||
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationProcedureConfig
|
||||
import kotlinx.android.synthetic.main.pre_migration_controller.fab
|
||||
import kotlinx.android.synthetic.main.pre_migration_controller.recycler
|
||||
import kotlinx.android.synthetic.main.pre_migration_controller.*
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class PreMigrationController(bundle: Bundle? = null) : BaseController(bundle), FlexibleAdapter
|
||||
@ -98,7 +97,7 @@ class PreMigrationController(bundle: Bundle? = null) : BaseController(bundle), F
|
||||
config.toList(),
|
||||
extraSearchParams = extraParam
|
||||
)
|
||||
).withFadeTransaction())
|
||||
).withFadeTransaction().tag(MigrationListController.TAG))
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
|
@ -446,6 +446,7 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle),
|
||||
|
||||
companion object {
|
||||
const val CONFIG_EXTRA = "config_extra"
|
||||
const val TAG = "migration_list"
|
||||
|
||||
fun create(config: MigrationProcedureConfig): MigrationListController {
|
||||
return MigrationListController(Bundle().apply {
|
||||
|
@ -21,7 +21,10 @@ class AutofitRecyclerView @JvmOverloads constructor(context: Context, attrs: Att
|
||||
}
|
||||
|
||||
val itemWidth: Int
|
||||
get() = measuredWidth / manager.spanCount
|
||||
get() {
|
||||
return if (spanCount == 0) measuredWidth / getTempSpan()
|
||||
else measuredWidth / manager.spanCount
|
||||
}
|
||||
|
||||
init {
|
||||
if (attrs != null) {
|
||||
@ -34,6 +37,13 @@ class AutofitRecyclerView @JvmOverloads constructor(context: Context, attrs: Att
|
||||
layoutManager = manager
|
||||
}
|
||||
|
||||
private fun getTempSpan():Int {
|
||||
if (spanCount == 0 && columnWidth > 0) {
|
||||
return max(1, measuredWidth / columnWidth)
|
||||
}
|
||||
return 2
|
||||
}
|
||||
|
||||
override fun onMeasure(widthSpec: Int, heightSpec: Int) {
|
||||
super.onMeasure(widthSpec, heightSpec)
|
||||
if (spanCount == 0 && columnWidth > 0) {
|
||||
|
@ -443,6 +443,8 @@
|
||||
</plurals>
|
||||
<string name="remember_choice">Remember this choice</string>
|
||||
<string name="already_in_category">Manga already in category</string>
|
||||
<string name="category">Category</string>
|
||||
|
||||
|
||||
<!-- Catalogue fragment -->
|
||||
<string name="source_search_options">Search filters</string>
|
||||
|
Loading…
Reference in New Issue
Block a user