Add custom tag view for namespaced sources (E-Hentai, nHentai, Hitomi.la, and Pururin)
This commit is contained in:
parent
74012e0830
commit
8b95d93a96
@ -7,8 +7,11 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.glide.GlideApp
|
||||
@ -27,8 +30,14 @@ import eu.kanade.tachiyomi.util.view.gone
|
||||
import eu.kanade.tachiyomi.util.view.setTooltip
|
||||
import eu.kanade.tachiyomi.util.view.visible
|
||||
import eu.kanade.tachiyomi.util.view.visibleIf
|
||||
import exh.EH_SOURCE_ID
|
||||
import exh.EXH_SOURCE_ID
|
||||
import exh.HITOMI_SOURCE_ID
|
||||
import exh.MERGED_SOURCE_ID
|
||||
import exh.NHENTAI_SOURCE_ID
|
||||
import exh.PURURIN_SOURCE_ID
|
||||
import exh.util.SourceTagsUtil
|
||||
import exh.util.makeSearchChip
|
||||
import exh.util.setChipsExtended
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@ -66,6 +75,8 @@ class MangaInfoHeaderAdapter(
|
||||
holder.bind()
|
||||
}
|
||||
|
||||
val tagsAdapter: FlexibleAdapter<IFlexible<*>> = FlexibleAdapter(null)
|
||||
|
||||
/**
|
||||
* Update the view with manga information.
|
||||
*
|
||||
@ -229,6 +240,11 @@ class MangaInfoHeaderAdapter(
|
||||
}
|
||||
// EXH <--
|
||||
|
||||
// SY -->
|
||||
binding.mangaNamespaceTagsRecycler.layoutManager = LinearLayoutManager(itemView.context)
|
||||
binding.mangaNamespaceTagsRecycler.adapter = tagsAdapter
|
||||
// SY <--
|
||||
|
||||
setMangaInfo(manga, source)
|
||||
}
|
||||
|
||||
@ -320,8 +336,18 @@ class MangaInfoHeaderAdapter(
|
||||
// Update genres list
|
||||
if (!manga.genre.isNullOrBlank()) {
|
||||
// SY -->
|
||||
binding.mangaGenresTagsCompactChips.setChipsExtended(manga.getGenres(), controller::performSearch, controller::performGlobalSearch, source?.id ?: 0)
|
||||
if (source != null && (source.id == EH_SOURCE_ID || source.id == EXH_SOURCE_ID || source.id == NHENTAI_SOURCE_ID || source.id == HITOMI_SOURCE_ID || source.id == PURURIN_SOURCE_ID)) {
|
||||
val genre = manga.getGenres()
|
||||
if (!genre.isNullOrEmpty()) {
|
||||
val namespaceTags = genre.map { SourceTagsUtil().parseTag(it) }
|
||||
.groupBy { it.first }
|
||||
.mapValues { values -> values.value.map { makeSearchChip(it.second, controller::performSearch, controller::performGlobalSearch, source.id, itemView.context, it.first) } }
|
||||
.map { NamespaceTagsItem(it.key, it.value) }
|
||||
tagsAdapter.updateDataSet(namespaceTags)
|
||||
}
|
||||
}
|
||||
binding.mangaGenresTagsFullChips.setChipsExtended(manga.getGenres(), controller::performSearch, controller::performGlobalSearch, source?.id ?: 0)
|
||||
binding.mangaGenresTagsCompactChips.setChipsExtended(manga.getGenres(), controller::performSearch, controller::performGlobalSearch, source?.id ?: 0)
|
||||
// SY <--
|
||||
} else {
|
||||
binding.mangaGenresTagsWrapper.gone()
|
||||
@ -387,7 +413,13 @@ class MangaInfoHeaderAdapter(
|
||||
}
|
||||
|
||||
binding.mangaGenresTagsCompact.visibleIf { isExpanded }
|
||||
binding.mangaGenresTagsFullChips.visibleIf { !isExpanded }
|
||||
// SY -->
|
||||
if (source.id == EH_SOURCE_ID || source.id == EXH_SOURCE_ID || source.id == NHENTAI_SOURCE_ID || source.id == HITOMI_SOURCE_ID || source.id == PURURIN_SOURCE_ID) {
|
||||
binding.mangaNamespaceTagsRecycler.visibleIf { !isExpanded }
|
||||
} else {
|
||||
binding.mangaGenresTagsFullChips.visibleIf { !isExpanded }
|
||||
}
|
||||
// SY <--
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,47 @@
|
||||
package eu.kanade.tachiyomi.ui.manga.info
|
||||
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.google.android.material.chip.ChipGroup
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.davidea.viewholders.FlexibleViewHolder
|
||||
import eu.kanade.tachiyomi.R
|
||||
|
||||
open class NamespaceTagsItem(val namespace: String, val tags: List<Chip>) : AbstractFlexibleItem<NamespaceTagsItem.Holder>() {
|
||||
|
||||
override fun getLayoutRes(): Int {
|
||||
return R.layout.manga_info_genre_grouping
|
||||
}
|
||||
|
||||
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): Holder {
|
||||
return Holder(view, adapter)
|
||||
}
|
||||
|
||||
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
||||
val namespaceChip = Chip(holder.itemView.context)
|
||||
namespaceChip.text = namespace
|
||||
holder.namespaceChipGroup.addView(namespaceChip)
|
||||
|
||||
tags.forEach {
|
||||
holder.tagsChipGroup.addView(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
return namespace == (other as NamespaceTagsItem).namespace
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return namespace.hashCode()
|
||||
}
|
||||
|
||||
class Holder(view: View, adapter: FlexibleAdapter<*>) : FlexibleViewHolder(view, adapter) {
|
||||
val namespaceChipGroup: ChipGroup = itemView.findViewById(R.id.namespace)
|
||||
val tagsChipGroup: ChipGroup = itemView.findViewById(R.id.tags)
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import exh.EH_SOURCE_ID
|
||||
import exh.EXH_SOURCE_ID
|
||||
import exh.HITOMI_SOURCE_ID
|
||||
import exh.NHENTAI_SOURCE_ID
|
||||
import exh.PURURIN_SOURCE_ID
|
||||
|
||||
class SourceTagsUtil {
|
||||
fun getWrappedTag(sourceId: Long, namespace: String? = null, tag: String? = null, fullTag: String? = null): String? {
|
||||
@ -13,6 +14,7 @@ class SourceTagsUtil {
|
||||
when (sourceId) {
|
||||
HITOMI_SOURCE_ID -> wrapTagHitomi(parsed.first, parsed.second.substringBefore('|').trim())
|
||||
NHENTAI_SOURCE_ID -> wrapTagNHentai(parsed.first, parsed.second.substringBefore('|').trim())
|
||||
PURURIN_SOURCE_ID -> parsed.second.substringBefore('|').trim()
|
||||
else -> wrapTag(parsed.first, parsed.second.substringBefore('|').trim())
|
||||
}
|
||||
} else null
|
||||
|
@ -1,5 +1,6 @@
|
||||
package exh.util
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowInsets
|
||||
@ -114,16 +115,19 @@ fun ChipGroup.setChipsExtended(items: List<String>?, onClick: (item: String) ->
|
||||
removeAllViews()
|
||||
|
||||
items?.forEach { item ->
|
||||
val chip = Chip(context).apply {
|
||||
text = item
|
||||
val search = SourceTagsUtil().getWrappedTag(sourceId, fullTag = item) ?: item
|
||||
setOnClickListener { onClick(search) }
|
||||
setOnLongClickListener {
|
||||
onLongClick(search)
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
val chip = makeSearchChip(item, onClick, onLongClick, sourceId, context)
|
||||
addView(chip)
|
||||
}
|
||||
}
|
||||
|
||||
fun makeSearchChip(item: String, onClick: (item: String) -> Unit = {}, onLongClick: (item: String) -> Unit = {}, sourceId: Long, context: Context, namespace: String? = null): Chip {
|
||||
return Chip(context).apply {
|
||||
text = item
|
||||
val search = (if (namespace != null) SourceTagsUtil().getWrappedTag(sourceId, namespace = namespace, tag = item) else SourceTagsUtil().getWrappedTag(sourceId, fullTag = item)) ?: item
|
||||
setOnClickListener { onClick(search) }
|
||||
setOnLongClickListener {
|
||||
onLongClick(search)
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
23
app/src/main/res/layout/manga_info_genre_grouping.xml
Normal file
23
app/src/main/res/layout/manga_info_genre_grouping.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/namespace"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
app:chipSpacingHorizontal="4dp"/>
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/tags"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
app:chipSpacingHorizontal="4dp"/>
|
||||
|
||||
</LinearLayout>
|
@ -244,6 +244,15 @@
|
||||
android:textIsSelectable="false"
|
||||
tools:text="Summary" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/manga_namespace_tags_recycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:visibility="gone"
|
||||
tools:listitem="@layout/manga_info_genre_grouping"/>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/manga_genres_tags_wrapper"
|
||||
android:layout_width="match_parent"
|
||||
|
Loading…
x
Reference in New Issue
Block a user