Add option to group by langauge

Closes #1376
This commit is contained in:
Jays2Kings 2022-08-28 21:53:55 -04:00
parent 2139e04ab7
commit a796bcc3fe
8 changed files with 79 additions and 15 deletions

View file

@ -28,6 +28,8 @@ interface Category : Serializable {
var sourceId: Long?
var langId: String?
fun isAscending(): Boolean {
return ((mangaSort?.minus('a') ?: 0) % 2) != 1
}

View file

@ -22,6 +22,8 @@ class CategoryImpl : Category {
override var sourceId: Long? = null
override var langId: String? = null
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || javaClass != other.javaClass) return false

View file

@ -75,6 +75,7 @@ import eu.kanade.tachiyomi.ui.category.CategoryController
import eu.kanade.tachiyomi.ui.category.ManageCategoryDialog
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_AUTHOR
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_DEFAULT
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_LANGUAGE
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_SOURCE
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_STATUS
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_TAG
@ -506,6 +507,7 @@ class LibraryController(
if (presenter.isLoggedIntoTracking) {
groupItems.add(BY_TRACK_STATUS)
}
groupItems.add(BY_LANGUAGE)
if (presenter.allCategories.size > 1) {
groupItems.add(UNGROUPED)
}

View file

@ -10,6 +10,7 @@ object LibraryGroup {
const val BY_STATUS = 3
const val BY_TRACK_STATUS = 4
const val BY_AUTHOR = 6
const val BY_LANGUAGE = 7
const val UNGROUPED = 5
fun groupTypeStringRes(type: Int, hasCategories: Boolean = true): Int {
@ -19,6 +20,7 @@ object LibraryGroup {
BY_SOURCE -> R.string.sources
BY_TRACK_STATUS -> R.string.tracking_status
BY_AUTHOR -> R.string.author
BY_LANGUAGE -> R.string.language
UNGROUPED -> R.string.ungrouped
else -> if (hasCategories) R.string.categories else R.string.ungrouped
}
@ -31,6 +33,7 @@ object LibraryGroup {
BY_TRACK_STATUS -> R.drawable.ic_sync_24dp
BY_SOURCE -> R.drawable.ic_browse_24dp
BY_AUTHOR -> R.drawable.ic_author_24dp
BY_LANGUAGE -> R.drawable.ic_translate_24dp
UNGROUPED -> R.drawable.ic_ungroup_24dp
else -> R.drawable.ic_label_outline_24dp
}

View file

@ -169,6 +169,9 @@ class LibraryHeaderHolder(val view: View, val adapter: LibraryCategoryAdapter) :
val icon = adapter.sourceManager.get(category.sourceId!!)?.icon()
icon?.setBounds(0, 0, 32.dpToPx, 32.dpToPx)
binding.categoryTitle.setCompoundDrawablesRelative(icon, null, null, null)
} else if (category.langId != null) {
val icon = getFlagIcon(category.langId!!) ?: 0
binding.categoryTitle.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, icon, 0)
} else {
binding.categoryTitle.setCompoundDrawablesRelative(null, null, null, null)
}
@ -190,7 +193,7 @@ class LibraryHeaderHolder(val view: View, val adapter: LibraryCategoryAdapter) :
binding.updateButton.isVisible = false
setSelection()
}
category.id ?: -1 < 0 -> {
(category.id ?: -1) < 0 -> {
binding.collapseArrow.isVisible = false
binding.checkbox.isVisible = false
setRefreshing(false)
@ -211,6 +214,24 @@ class LibraryHeaderHolder(val view: View, val adapter: LibraryCategoryAdapter) :
}
}
@SuppressLint("DiscouragedApi")
fun getFlagIcon(lang: String): Int? {
val flagId = itemView.resources.getIdentifier(
"ic_flag_${lang.replace("-", "_")}",
"drawable",
itemView.context.packageName,
).takeIf { it != 0 } ?: (
if (lang.contains("-")) {
itemView.resources.getIdentifier(
"ic_flag_${lang.split("-").first()}",
"drawable",
itemView.context.packageName,
).takeIf { it != 0 }
} else null
)
return flagId
}
fun setRefreshing(refreshing: Boolean) {
binding.updateButton.isClickable = !refreshing
if (refreshing) {

View file

@ -22,6 +22,7 @@ import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.base.presenter.BaseCoroutinePresenter
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_AUTHOR
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_DEFAULT
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_LANGUAGE
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_SOURCE
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_TAG
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_TRACK_STATUS
@ -415,15 +416,15 @@ class LibraryPresenter(
private fun setSourceLanguage(itemList: List<LibraryItem>) {
val showLanguageBadges = preferences.languageBadge().get()
for (item in itemList) {
item.sourceLanguage = if (showLanguageBadges) {
if (item.manga.isLocal()) {
LocalSource.getMangaLang(item.manga, context)
} else {
sourceManager.get(item.manga.source)?.lang
}
} else {
null
}
item.sourceLanguage = if (showLanguageBadges) getLanguage(item.manga) else null
}
}
private fun getLanguage(manga: Manga): String? {
return if (manga.isLocal()) {
LocalSource.getMangaLang(manga, context)
} else {
sourceManager.get(manga.source)?.lang
}
}
@ -730,7 +731,25 @@ class LibraryPresenter(
}
}
}
else -> listOf(LibraryItem(manga, makeOrGetHeader(context.mapStatus(manga.status)), viewContext))
BY_LANGUAGE -> {
val lang = getLanguage(manga)
listOf(
LibraryItem(
manga,
makeOrGetHeader(
lang?.plus(langSplitter)?.plus(
run {
val locale = Locale.forLanguageTag(lang)
locale.getDisplayName(locale)
.replaceFirstChar { it.uppercase(locale) }
},
) ?: unknown,
),
viewContext,
),
)
}
else /* BY_STATUS */ -> listOf(LibraryItem(manga, makeOrGetHeader(context.mapStatus(manga.status)), viewContext))
}
}.flatten().toMutableList()
@ -746,6 +765,10 @@ class LibraryPresenter(
val split = name.split(sourceSplitter)
name = split.first()
sourceId = split.last().toLongOrNull()
} else if (name.contains(langSplitter)) {
val split = name.split(langSplitter)
name = split.last()
langId = split.first()
}
isHidden = getDynamicCategoryName(this) in hiddenDynamics
}
@ -764,7 +787,13 @@ class LibraryPresenter(
headers.forEach { category ->
val catId = category.id ?: return@forEach
val headerItem =
tagItems[if (category.sourceId != null) "${category.name}$sourceSplitter${category.sourceId}" else category.name]
tagItems[
when {
category.sourceId != null -> "${category.name}$sourceSplitter${category.sourceId}"
category.langId != null -> "${category.langId}$langSplitter${category.name}"
else -> category.name
},
]
if (category.isHidden) {
val mangaToRemove = items.filter { it.header.catId == catId }
val mergedTitle = mangaToRemove.joinToString("-") {
@ -1052,8 +1081,7 @@ class LibraryPresenter(
private fun getDynamicCategoryName(category: Category): String =
groupType.toString() + dynamicCategorySplitter + (
category.sourceId?.toString()
?: category.name
category.sourceId?.toString() ?: category.langId ?: category.name
)
fun toggleAllCategoryVisibility() {
@ -1162,6 +1190,7 @@ class LibraryPresenter(
private var lastLibraryItems: List<LibraryItem>? = null
private var lastCategories: List<Category>? = null
private const val sourceSplitter = "◘•◘"
private const val langSplitter = "⨼⨦⨠"
private const val dynamicCategorySplitter = "▄╪\t▄╪\t"
private val randomTags = arrayOf(0, 1, 2)

View file

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12.87,15.07l-2.54,-2.51 0.03,-0.03c1.74,-1.94 2.98,-4.17 3.71,-6.53L17,6L17,4h-7L10,2L8,2v2L1,4v1.99h11.17C11.5,7.92 10.44,9.75 9,11.35 8.07,10.32 7.3,9.19 6.69,8h-2c0.73,1.63 1.73,3.17 2.98,4.56l-5.09,5.02L4,19l5,-5 3.11,3.11 0.76,-2.04zM18.5,10h-2L12,22h2l1.12,-3h4.75L21,22h2l-4.5,-12zM15.88,17l1.62,-4.33L19.12,17h-3.24z"/>
</vector>

View file

@ -145,7 +145,7 @@
android:text="@string/language"
android:textColor="?attr/colorOnBackground"
app:checkedIconEnabled="false"
app:chipIcon="@drawable/ic_language_24dp"
app:chipIcon="@drawable/ic_translate_24dp"
app:chipIconEnabled="false"
app:chipIconTint="?attr/colorOnBackground"
app:chipStrokeColor="?attr/colorSecondary"