Add special view for browsing E/Exhentai! All the important info is now in front of your face when browsing, it is on by default and can be toggled off in the E-Hentai settings. Let me know if you find any errors
This commit is contained in:
@@ -272,4 +272,6 @@ object PreferenceKeys {
|
||||
const val recommendsInOverflow = "recommends_in_overflow"
|
||||
|
||||
const val hitomiAlwaysWebp = "hitomi_always_webp"
|
||||
|
||||
const val enhancedEHentaiView = "enhanced_e_hentai_view"
|
||||
}
|
||||
|
||||
@@ -380,4 +380,6 @@ class PreferencesHelper(val context: Context) {
|
||||
fun recommendsInOverflow() = flowPrefs.getBoolean(Keys.recommendsInOverflow, false)
|
||||
|
||||
fun hitomiAlwaysWebp() = flowPrefs.getBoolean(Keys.hitomiAlwaysWebp, true)
|
||||
|
||||
fun enhancedEHentaiView() = flowPrefs.getBoolean(Keys.enhancedEHentaiView, true)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
package eu.kanade.tachiyomi.source.model
|
||||
|
||||
data class MangasPage(val mangas: List<SManga>, val hasNextPage: Boolean)
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
|
||||
/* SY --> */ open /* SY <-- */ class MangasPage(val mangas: List<SManga>, val hasNextPage: Boolean)
|
||||
|
||||
// SY -->
|
||||
class MetadataMangasPage(mangas: List<SManga>, hasNextPage: Boolean, val mangasMetadata: List<RaisedSearchMetadata>) : MangasPage(mangas, hasNextPage)
|
||||
// SY <--
|
||||
|
||||
@@ -18,7 +18,7 @@ import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||
import eu.kanade.tachiyomi.source.model.MetadataMangasPage
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
@@ -96,9 +96,9 @@ class EHentai(
|
||||
/**
|
||||
* Gallery list entry
|
||||
*/
|
||||
data class ParsedManga(val fav: Int, val manga: Manga)
|
||||
data class ParsedManga(val fav: Int, val manga: Manga, val metadata: EHentaiSearchMetadata)
|
||||
|
||||
fun extendedGenericMangaParse(doc: Document) = with(doc) {
|
||||
private fun extendedGenericMangaParse(doc: Document) = with(doc) {
|
||||
// Parse mangas (supports compact + extended layout)
|
||||
val parsedMangas = select(".itg > tbody > tr").filter {
|
||||
// Do not parse header and ads
|
||||
@@ -110,6 +110,8 @@ class EHentai(
|
||||
val infoElement = it.selectFirst(".gl3e")
|
||||
|
||||
val favElement = column2.children().find { it.attr("style").startsWith("border-color") }
|
||||
val infoElements = infoElement?.select("div")
|
||||
val parsedTags = mutableListOf<RaisedTag>()
|
||||
|
||||
ParsedManga(
|
||||
fav = FAVORITES_BORDER_HEX_COLORS.indexOf(
|
||||
@@ -122,14 +124,10 @@ class EHentai(
|
||||
// Get image
|
||||
thumbnail_url = thumbnailElement.attr("src")
|
||||
|
||||
val tags = mutableListOf<RaisedTag>()
|
||||
|
||||
val infoElements = infoElement?.select("div")
|
||||
|
||||
if (infoElements != null) {
|
||||
linkElement.select("div div")?.getOrNull(1)?.select("tr")?.forEach { row ->
|
||||
val namespace = row.select(".tc").text().removeSuffix(":")
|
||||
tags.addAll(
|
||||
parsedTags.addAll(
|
||||
row.select("div").map { element ->
|
||||
RaisedTag(
|
||||
namespace,
|
||||
@@ -143,46 +141,61 @@ class EHentai(
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
getGenre(infoElements[1])?.let { tags += it }
|
||||
|
||||
getDateTag(infoElements[2])?.let { tags += it }
|
||||
|
||||
getRating(infoElements[3])?.let { tags += it }
|
||||
|
||||
getAuthor(infoElements[4])?.let { author = it }
|
||||
} else {
|
||||
val tagElement = it.selectFirst(".gl3c > a")
|
||||
val tagElements = tagElement.select("div")
|
||||
tagElements.forEach { element ->
|
||||
if (element.className() == "gt") {
|
||||
val namespace = element.attr("title").substringBefore(":").trimOrNull() ?: "misc"
|
||||
tags += RaisedTag(
|
||||
parsedTags += RaisedTag(
|
||||
namespace,
|
||||
element.attr("title").substringAfter(":").trim(),
|
||||
TAG_TYPE_NORMAL
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val genre = it.selectFirst(".gl1c div")
|
||||
getGenre(genreString = genre?.text()?.nullIfBlank()?.toLowerCase()?.replace(" ", ""))?.let { tags += it }
|
||||
genre = parsedTags.toGenreString()
|
||||
},
|
||||
metadata = EHentaiSearchMetadata().apply {
|
||||
tags += parsedTags
|
||||
|
||||
if (infoElements != null) {
|
||||
getGenre(infoElements.getOrNull(1))?.let { genre = it }
|
||||
|
||||
getDateTag(infoElements.getOrNull(2))?.let { datePosted = it }
|
||||
|
||||
getRating(infoElements.getOrNull(3))?.let { averageRating = it }
|
||||
|
||||
getUploader(infoElements.getOrNull(4))?.let { uploader = it }
|
||||
|
||||
getPageCount(infoElements.getOrNull(5))?.let { length = it }
|
||||
} else {
|
||||
val parsedGenre = it.selectFirst(".gl1c div")
|
||||
getGenre(genreString = parsedGenre?.text()?.nullIfBlank()?.toLowerCase()?.replace(" ", ""))?.let { genre = it }
|
||||
|
||||
val info = it.selectFirst(".gl2c")
|
||||
val extraInfo = it.selectFirst(".gl4c")
|
||||
|
||||
val infoList = info.select("div div")
|
||||
|
||||
getDateTag(infoList[8])?.let { tags += it }
|
||||
getDateTag(infoList.getOrNull(8))?.let { datePosted = it }
|
||||
|
||||
getRating(infoList[9])?.let { tags += it }
|
||||
getRating(infoList.getOrNull(9))?.let { averageRating = it }
|
||||
|
||||
val extraInfoList = extraInfo.select("div")
|
||||
|
||||
getAuthor(extraInfoList[1])?.let { author = it }
|
||||
}
|
||||
if (extraInfoList.getOrNull(2) == null) {
|
||||
getUploader(extraInfoList.getOrNull(0))?.let { uploader = it }
|
||||
|
||||
genre = tags.toGenreString()
|
||||
getPageCount(extraInfoList.getOrNull(1))?.let { length = it }
|
||||
} else {
|
||||
getUploader(extraInfoList.getOrNull(1))?.let { uploader = it }
|
||||
|
||||
getPageCount(extraInfoList.getOrNull(2))?.let { length = it }
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -202,68 +215,54 @@ class EHentai(
|
||||
Pair(parsedMangas, hasNextPage)
|
||||
}
|
||||
|
||||
private fun getGenre(element: Element? = null, genreString: String? = null): RaisedTag? {
|
||||
val attr = element?.attr("onclick")
|
||||
private fun getGenre(element: Element? = null, genreString: String? = null): String? {
|
||||
return element?.attr("onclick")
|
||||
?.nullIfBlank()
|
||||
?.substringAfterLast('/')
|
||||
?.removeSuffix("'")
|
||||
?.trim()
|
||||
?.substringAfterLast('/')
|
||||
?.removeSuffix("'") ?: genreString
|
||||
return if (attr != null) {
|
||||
RaisedTag(
|
||||
EH_GENRE_NAMESPACE,
|
||||
attr,
|
||||
TAG_TYPE_NORMAL
|
||||
)
|
||||
} else null
|
||||
}
|
||||
|
||||
private fun getDateTag(element: Element?): RaisedTag? {
|
||||
private fun getDateTag(element: Element?): Long? {
|
||||
val text = element?.text()?.nullIfBlank()
|
||||
return if (text != null) {
|
||||
val date = EX_DATE_FORMAT.parse(text)
|
||||
if (date != null) {
|
||||
RaisedTag(
|
||||
EH_DATE_POSTED_NAMESPACE,
|
||||
date.time.toString(),
|
||||
TAG_TYPE_NORMAL
|
||||
)
|
||||
} else null
|
||||
date?.time
|
||||
} else null
|
||||
}
|
||||
|
||||
private fun getRating(element: Element?): RaisedTag? {
|
||||
private fun getRating(element: Element?): Double? {
|
||||
val ratingStyle = element?.attr("style")?.nullIfBlank()
|
||||
return if (ratingStyle != null) {
|
||||
val matches = "([0-9]*)px".toRegex().findAll(ratingStyle).mapNotNull { it.groupValues.getOrNull(1)?.toIntOrNull() }.toList()
|
||||
val matches = RATING_REGEX.findAll(ratingStyle).mapNotNull { it.groupValues.getOrNull(1)?.toIntOrNull() }.toList()
|
||||
if (matches.size == 2) {
|
||||
var rate = 5 - matches[0] / 16
|
||||
RaisedTag(
|
||||
EH_RATING_NAMESPACE,
|
||||
if (matches[1] == 21) {
|
||||
rate--
|
||||
"$rate.5"
|
||||
} else rate.toString(),
|
||||
TAG_TYPE_NORMAL
|
||||
)
|
||||
if (matches[1] == 21) {
|
||||
rate--
|
||||
rate + 0.5
|
||||
} else rate.toDouble()
|
||||
} else null
|
||||
} else null
|
||||
}
|
||||
|
||||
private fun getAuthor(element: Element?): String? {
|
||||
return element?.select("a")
|
||||
?.attr("href")
|
||||
?.nullIfBlank()
|
||||
?.trim()
|
||||
?.substringAfterLast('/')
|
||||
private fun getUploader(element: Element?): String? {
|
||||
return element?.select("a")?.text()?.trimOrNull()
|
||||
}
|
||||
|
||||
private fun getPageCount(element: Element?): Int? {
|
||||
val pageCount = element?.text()?.trimOrNull()
|
||||
return if (pageCount != null) {
|
||||
PAGE_COUNT_REGEX.find(pageCount)?.value?.toIntOrNull()
|
||||
} else null
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a list of galleries
|
||||
*/
|
||||
fun genericMangaParse(response: Response) = extendedGenericMangaParse(response.asJsoup()).let {
|
||||
MangasPage(it.first.map { it.manga }, it.second)
|
||||
MetadataMangasPage(it.first.map { it.manga }, it.second, it.first.map { it.metadata })
|
||||
}
|
||||
|
||||
override fun fetchChapterList(manga: SManga) = fetchChapterList(manga) {}
|
||||
@@ -675,7 +674,7 @@ class EHentai(
|
||||
page++
|
||||
} while (parsed.second)
|
||||
|
||||
return Pair(result as List<ParsedManga>, favNames!!)
|
||||
return Pair(result.toList(), favNames!!)
|
||||
}
|
||||
|
||||
fun spPref() = if (exh) {
|
||||
@@ -965,8 +964,8 @@ class EHentai(
|
||||
private const val QUERY_PREFIX = "?f_apply=Apply+Filter"
|
||||
private const val TR_SUFFIX = "TR"
|
||||
private const val REVERSE_PARAM = "TEH_REVERSE"
|
||||
private const val EH_DATE_POSTED_NAMESPACE = "date_posted"
|
||||
private const val EH_RATING_NAMESPACE = "rating"
|
||||
private val PAGE_COUNT_REGEX = "[0-9]*".toRegex()
|
||||
private val RATING_REGEX = "([0-9]*)px".toRegex()
|
||||
|
||||
private const val EH_API_BASE = "https://api.e-hentai.org/api.php"
|
||||
private val JSON = "application/json; charset=utf-8".toMediaTypeOrNull()!!
|
||||
|
||||
+7
-1
@@ -54,6 +54,7 @@ import eu.kanade.tachiyomi.util.view.snack
|
||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||
import eu.kanade.tachiyomi.widget.EmptyView
|
||||
import exh.EXHSavedSearch
|
||||
import exh.isEhBasedSource
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.drop
|
||||
@@ -348,7 +349,7 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||
binding.catalogueView.removeView(oldRecycler)
|
||||
}
|
||||
|
||||
val recycler = if (preferences.sourceDisplayMode().get() == DisplayMode.LIST) {
|
||||
val recycler = if (preferences.sourceDisplayMode().get() == DisplayMode.LIST /* SY --> */ || (preferences.enhancedEHentaiView().get() && presenter.source.isEhBasedSource()) /* SY <-- */) {
|
||||
RecyclerView(view.context).apply {
|
||||
id = R.id.recycler
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
@@ -439,6 +440,11 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||
DisplayMode.LIST -> R.id.action_list
|
||||
}
|
||||
menu.findItem(displayItem).isChecked = true
|
||||
// SY -->
|
||||
if (preferences.enhancedEHentaiView().get() && presenter.source.isEhBasedSource()) {
|
||||
menu.findItem(R.id.action_display_mode).isVisible = false
|
||||
}
|
||||
// SY <--
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
|
||||
+7
-3
@@ -38,9 +38,9 @@ import eu.kanade.tachiyomi.ui.browse.source.filter.TriStateItem
|
||||
import eu.kanade.tachiyomi.ui.browse.source.filter.TriStateSectionItem
|
||||
import eu.kanade.tachiyomi.util.removeCovers
|
||||
import exh.EXHSavedSearch
|
||||
import exh.isEhBasedSource
|
||||
import java.lang.RuntimeException
|
||||
import java.util.Date
|
||||
import kotlinx.coroutines.flow.subscribe
|
||||
import rx.Observable
|
||||
import rx.Subscription
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
@@ -165,9 +165,13 @@ open class BrowseSourcePresenter(
|
||||
pagerSubscription?.let { remove(it) }
|
||||
pagerSubscription = pager.results()
|
||||
.observeOn(Schedulers.io())
|
||||
.map { pair -> pair.first to pair.second.map { networkToLocalManga(it, sourceId) } }
|
||||
// SY -->
|
||||
.map { triple -> Triple(triple.first, triple.second.map { networkToLocalManga(it, sourceId) }, triple.third) }
|
||||
// SY <--
|
||||
.doOnNext { initializeMangas(it.second) }
|
||||
.map { pair -> pair.first to pair.second.map { SourceItem(it, sourceDisplayMode) } }
|
||||
// SY -->
|
||||
.map { triple -> triple.first to triple.second.mapIndexed { index, manga -> SourceItem(manga, sourceDisplayMode, if (prefs.enhancedEHentaiView().get() && source.isEhBasedSource()) triple.third?.getOrNull(index) else null) } }
|
||||
// SY <--
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeReplay(
|
||||
{ view, (page, mangas) ->
|
||||
|
||||
@@ -2,7 +2,9 @@ package eu.kanade.tachiyomi.ui.browse.source.browse
|
||||
|
||||
import com.jakewharton.rxrelay.PublishRelay
|
||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||
import eu.kanade.tachiyomi.source.model.MetadataMangasPage
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
import rx.Observable
|
||||
|
||||
/**
|
||||
@@ -13,9 +15,9 @@ abstract class Pager(var currentPage: Int = 1) {
|
||||
var hasNextPage = true
|
||||
private set
|
||||
|
||||
protected val results: PublishRelay<Pair<Int, List<SManga>>> = PublishRelay.create()
|
||||
protected val results: PublishRelay< /* SY --> */ Triple /* SY <-- */ <Int, List<SManga> /* SY --> */, List<RaisedSearchMetadata>? /* SY <-- */ >> = PublishRelay.create()
|
||||
|
||||
fun results(): Observable<Pair<Int, List<SManga>>> {
|
||||
fun results(): Observable< /* SY --> */ Triple /* SY <-- */ <Int, List<SManga> /* SY --> */, List<RaisedSearchMetadata>?> /* SY <-- */> {
|
||||
return results.asObservable()
|
||||
}
|
||||
|
||||
@@ -25,6 +27,11 @@ abstract class Pager(var currentPage: Int = 1) {
|
||||
val page = currentPage
|
||||
currentPage++
|
||||
hasNextPage = mangasPage.hasNextPage && mangasPage.mangas.isNotEmpty()
|
||||
results.call(Pair(page, mangasPage.mangas))
|
||||
// SY -->
|
||||
val mangasMetadata = if (mangasPage is MetadataMangasPage) {
|
||||
mangasPage.mangasMetadata
|
||||
} else null
|
||||
// SY <--
|
||||
results.call( /* SY <-- */ Triple /* SY <-- */ (page, mangasPage.mangas /* SY --> */, mangasMetadata /* SY <-- */))
|
||||
}
|
||||
}
|
||||
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
package eu.kanade.tachiyomi.ui.browse.source.browse
|
||||
|
||||
import android.graphics.Color
|
||||
import android.view.View
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.load.resource.bitmap.CenterCrop
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||
import com.bumptech.glide.request.RequestOptions
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.glide.GlideApp
|
||||
import eu.kanade.tachiyomi.data.glide.toMangaThumbnail
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import exh.metadata.EX_DATE_FORMAT
|
||||
import exh.metadata.metadata.EHentaiSearchMetadata
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
import exh.util.SourceTagsUtil
|
||||
import exh.util.SourceTagsUtil.Companion.getLocaleSourceUtil
|
||||
import java.util.Date
|
||||
import kotlinx.android.synthetic.main.source_enhanced_ehentai_list_item.date_posted
|
||||
import kotlinx.android.synthetic.main.source_enhanced_ehentai_list_item.genre
|
||||
import kotlinx.android.synthetic.main.source_enhanced_ehentai_list_item.language
|
||||
import kotlinx.android.synthetic.main.source_enhanced_ehentai_list_item.rating_bar
|
||||
import kotlinx.android.synthetic.main.source_enhanced_ehentai_list_item.thumbnail
|
||||
import kotlinx.android.synthetic.main.source_enhanced_ehentai_list_item.title
|
||||
import kotlinx.android.synthetic.main.source_enhanced_ehentai_list_item.uploader
|
||||
|
||||
/**
|
||||
* Class used to hold the displayed data of a manga in the catalogue, like the cover or the title.
|
||||
* All the elements from the layout file "item_catalogue_list" are available in this class.
|
||||
*
|
||||
* @param view the inflated view for this holder.
|
||||
* @param adapter the adapter handling this holder.
|
||||
* @constructor creates a new catalogue holder.
|
||||
*/
|
||||
class SourceEnhancedEHentaiListHolder(private val view: View, adapter: FlexibleAdapter<*>) :
|
||||
SourceHolder(view, adapter) {
|
||||
|
||||
private val favoriteColor = view.context.getResourceColor(R.attr.colorOnSurface, 0.38f)
|
||||
private val unfavoriteColor = view.context.getResourceColor(R.attr.colorOnSurface)
|
||||
|
||||
/**
|
||||
* Method called from [CatalogueAdapter.onBindViewHolder]. It updates the data for this
|
||||
* holder with the given manga.
|
||||
*
|
||||
* @param manga the manga to bind.
|
||||
*/
|
||||
override fun onSetValues(manga: Manga) {
|
||||
title.text = manga.title
|
||||
title.setTextColor(if (manga.favorite) favoriteColor else unfavoriteColor)
|
||||
|
||||
// Set alpha of thumbnail.
|
||||
thumbnail.alpha = if (manga.favorite) 0.3f else 1.0f
|
||||
|
||||
setImage(manga)
|
||||
}
|
||||
|
||||
fun onSetMetadataValues(manga: Manga, metadata: RaisedSearchMetadata) {
|
||||
if (metadata !is EHentaiSearchMetadata) return
|
||||
|
||||
if (metadata.uploader != null) {
|
||||
uploader.text = metadata.uploader
|
||||
}
|
||||
|
||||
val pair = when (metadata.genre) {
|
||||
"doujinshi" -> Pair(SourceTagsUtil.DOUJINSHI_COLOR, R.string.doujinshi)
|
||||
"manga" -> Pair(SourceTagsUtil.MANGA_COLOR, R.string.manga)
|
||||
"artistcg" -> Pair(SourceTagsUtil.ARTIST_CG_COLOR, R.string.artist_cg)
|
||||
"gamecg" -> Pair(SourceTagsUtil.GAME_CG_COLOR, R.string.game_cg)
|
||||
"western" -> Pair(SourceTagsUtil.WESTERN_COLOR, R.string.western)
|
||||
"non-h" -> Pair(SourceTagsUtil.NON_H_COLOR, R.string.non_h)
|
||||
"imageset" -> Pair(SourceTagsUtil.IMAGE_SET_COLOR, R.string.image_set)
|
||||
"cosplay" -> Pair(SourceTagsUtil.COSPLAY_COLOR, R.string.cosplay)
|
||||
"asianporn" -> Pair(SourceTagsUtil.ASIAN_PORN_COLOR, R.string.asian_porn)
|
||||
"misc" -> Pair(SourceTagsUtil.MISC_COLOR, R.string.misc)
|
||||
else -> Pair("", 0)
|
||||
}
|
||||
|
||||
if (pair.first.isNotBlank()) {
|
||||
genre.setBackgroundColor(Color.parseColor(pair.first))
|
||||
genre.text = view.context.getString(pair.second)
|
||||
} else genre.text = metadata.genre
|
||||
|
||||
metadata.datePosted?.let { date_posted.text = EX_DATE_FORMAT.format(Date(it)) }
|
||||
|
||||
metadata.averageRating?.let { rating_bar.rating = it.toFloat() }
|
||||
|
||||
val locale = getLocaleSourceUtil(metadata.tags.firstOrNull { it.namespace == "language" }?.name)
|
||||
val pageCount = metadata.length
|
||||
|
||||
language.text = if (locale != null && pageCount != null) {
|
||||
view.resources.getQuantityString(R.plurals.browse_language_and_pages, pageCount, pageCount, locale.toLanguageTag().toUpperCase())
|
||||
} else if (pageCount != null) {
|
||||
view.resources.getQuantityString(R.plurals.num_pages, pageCount, pageCount)
|
||||
} else locale?.toLanguageTag()?.toUpperCase()
|
||||
}
|
||||
|
||||
override fun setImage(manga: Manga) {
|
||||
GlideApp.with(view.context).clear(thumbnail)
|
||||
|
||||
if (!manga.thumbnail_url.isNullOrEmpty()) {
|
||||
val radius = view.context.resources.getDimensionPixelSize(R.dimen.card_radius)
|
||||
val requestOptions = RequestOptions().transform(CenterCrop(), RoundedCorners(radius))
|
||||
GlideApp.with(view.context)
|
||||
.load(manga.toMangaThumbnail())
|
||||
.diskCacheStrategy(DiskCacheStrategy.DATA)
|
||||
.apply(requestOptions)
|
||||
.dontAnimate()
|
||||
.placeholder(android.R.color.transparent)
|
||||
.into(thumbnail)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,25 +14,26 @@ import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
|
||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
import kotlinx.android.synthetic.main.source_compact_grid_item.view.card
|
||||
import kotlinx.android.synthetic.main.source_compact_grid_item.view.gradient
|
||||
|
||||
class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMode>) :
|
||||
class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMode> /* SY --> */, private val metadata: RaisedSearchMetadata? = null /* SY <-- */) :
|
||||
AbstractFlexibleItem<SourceHolder>() {
|
||||
|
||||
override fun getLayoutRes(): Int {
|
||||
return when (displayMode.get()) {
|
||||
return /* SY --> */ if (metadata == null) /* SY <-- */ when (displayMode.get()) {
|
||||
DisplayMode.COMPACT_GRID -> R.layout.source_compact_grid_item
|
||||
DisplayMode.COMFORTABLE_GRID -> R.layout.source_comfortable_grid_item
|
||||
DisplayMode.LIST -> R.layout.source_list_item
|
||||
}
|
||||
} /* SY --> */ else R.layout.source_enhanced_ehentai_list_item /* SY <-- */
|
||||
}
|
||||
|
||||
override fun createViewHolder(
|
||||
view: View,
|
||||
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>
|
||||
): SourceHolder {
|
||||
return when (displayMode.get()) {
|
||||
return /* SY --> */ if (metadata == null) /* SY <-- */ when (displayMode.get()) {
|
||||
DisplayMode.COMPACT_GRID -> {
|
||||
val parent = adapter.recyclerView as AutofitRecyclerView
|
||||
val coverHeight = parent.itemWidth / 3 * 4
|
||||
@@ -59,7 +60,11 @@ class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMo
|
||||
DisplayMode.LIST -> {
|
||||
SourceListHolder(view, adapter)
|
||||
}
|
||||
// SY -->
|
||||
} else {
|
||||
SourceEnhancedEHentaiListHolder(view, adapter)
|
||||
}
|
||||
// SY <--
|
||||
}
|
||||
|
||||
override fun bindViewHolder(
|
||||
@@ -69,6 +74,11 @@ class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMo
|
||||
payloads: List<Any?>?
|
||||
) {
|
||||
holder.onSetValues(manga)
|
||||
// SY -->
|
||||
if (metadata != null) {
|
||||
(holder as? SourceEnhancedEHentaiListHolder)?.onSetMetadataValues(manga, metadata)
|
||||
}
|
||||
// SY <--
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
|
||||
@@ -20,7 +20,7 @@ import exh.isEhBasedSource
|
||||
import exh.isNamespaceSource
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata.Companion.TAG_TYPE_VIRTUAL
|
||||
import exh.util.SourceTagsUtil
|
||||
import exh.util.SourceTagsUtil.Companion.getRaisedTags
|
||||
import exh.util.makeSearchChip
|
||||
import exh.util.setChipsExtended
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -128,11 +128,11 @@ class MangaInfoItemAdapter(
|
||||
.mapValues { values -> values.value.map { makeSearchChip(it.name, controller::performSearch, controller::performGlobalSearch, source.id, itemView.context, it.namespace, it.type) } }
|
||||
.map { NamespaceTagsItem(it.key!!, it.value) }
|
||||
} else {
|
||||
val genre = manga.getGenres()
|
||||
val genre = manga.getRaisedTags()
|
||||
if (!genre.isNullOrEmpty()) {
|
||||
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) } }
|
||||
namespaceTags = genre
|
||||
.groupBy { it.namespace }
|
||||
.mapValues { values -> values.value.map { makeSearchChip(it.name, controller::performSearch, controller::performGlobalSearch, source.id, itemView.context, it.namespace) } }
|
||||
.map { NamespaceTagsItem(it.key, it.value) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ 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>() {
|
||||
open class NamespaceTagsItem(val namespace: String?, val tags: List<Chip>) : AbstractFlexibleItem<NamespaceTagsItem.Holder>() {
|
||||
|
||||
override fun getLayoutRes(): Int {
|
||||
return R.layout.manga_info_genre_grouping
|
||||
@@ -22,7 +22,7 @@ open class NamespaceTagsItem(val namespace: String, val tags: List<Chip>) : Abst
|
||||
|
||||
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>, holder: Holder, position: Int, payloads: List<Any?>?) {
|
||||
val namespaceChip = Chip(holder.itemView.context)
|
||||
namespaceChip.text = namespace
|
||||
namespaceChip.text = namespace ?: holder.itemView.context.getString(R.string.unknown)
|
||||
holder.namespaceChipGroup.addView(namespaceChip)
|
||||
|
||||
tags.forEach {
|
||||
|
||||
@@ -518,6 +518,13 @@ class SettingsEhController : SettingsController() {
|
||||
|
||||
onChange { preferences.imageQuality().reconfigure() }
|
||||
}.dependency = PreferenceKeys.eh_enableExHentai
|
||||
|
||||
switchPreference {
|
||||
titleRes = R.string.pref_enhanced_e_hentai_view
|
||||
summaryRes = R.string.pref_enhanced_e_hentai_view_summary
|
||||
key = PreferenceKeys.enhancedEHentaiView
|
||||
defaultValue = true
|
||||
}
|
||||
}
|
||||
|
||||
preferenceCategory {
|
||||
|
||||
@@ -14,6 +14,7 @@ import exh.metadata.EX_DATE_FORMAT
|
||||
import exh.metadata.humanReadableByteCount
|
||||
import exh.metadata.metadata.EHentaiSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import exh.util.SourceTagsUtil
|
||||
import java.util.Date
|
||||
import kotlin.math.roundToInt
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -50,16 +51,16 @@ class EHentaiDescriptionAdapter(
|
||||
val genre = meta.genre
|
||||
if (genre != null) {
|
||||
val pair = when (genre) {
|
||||
"doujinshi" -> Pair("#fc4e4e", R.string.doujinshi)
|
||||
"manga" -> Pair("#e78c1a", R.string.manga)
|
||||
"artistcg" -> Pair("#dde500", R.string.artist_cg)
|
||||
"gamecg" -> Pair("#05bf0b", R.string.game_cg)
|
||||
"western" -> Pair("#14e723", R.string.western)
|
||||
"non-h" -> Pair("#08d7e2", R.string.non_h)
|
||||
"imageset" -> Pair("#5f5fff", R.string.image_set)
|
||||
"cosplay" -> Pair("#9755f5", R.string.cosplay)
|
||||
"asianporn" -> Pair("#fe93ff", R.string.asian_porn)
|
||||
"misc" -> Pair("#9e9e9e", R.string.misc)
|
||||
"doujinshi" -> Pair(SourceTagsUtil.DOUJINSHI_COLOR, R.string.doujinshi)
|
||||
"manga" -> Pair(SourceTagsUtil.MANGA_COLOR, R.string.manga)
|
||||
"artistcg" -> Pair(SourceTagsUtil.ARTIST_CG_COLOR, R.string.artist_cg)
|
||||
"gamecg" -> Pair(SourceTagsUtil.GAME_CG_COLOR, R.string.game_cg)
|
||||
"western" -> Pair(SourceTagsUtil.WESTERN_COLOR, R.string.western)
|
||||
"non-h" -> Pair(SourceTagsUtil.NON_H_COLOR, R.string.non_h)
|
||||
"imageset" -> Pair(SourceTagsUtil.IMAGE_SET_COLOR, R.string.image_set)
|
||||
"cosplay" -> Pair(SourceTagsUtil.COSPLAY_COLOR, R.string.cosplay)
|
||||
"asianporn" -> Pair(SourceTagsUtil.ASIAN_PORN_COLOR, R.string.asian_porn)
|
||||
"misc" -> Pair(SourceTagsUtil.MISC_COLOR, R.string.misc)
|
||||
else -> Pair("", 0)
|
||||
}
|
||||
|
||||
@@ -80,7 +81,7 @@ class EHentaiDescriptionAdapter(
|
||||
|
||||
binding.uploader.text = meta.uploader ?: itemView.context.getString(R.string.unknown)
|
||||
binding.size.text = humanReadableByteCount(meta.size ?: 0, true)
|
||||
binding.pages.text = itemView.context.getString(R.string.num_pages, meta.length ?: 0)
|
||||
binding.pages.text = itemView.resources.getQuantityString(R.plurals.num_pages, meta.length ?: 0, meta.length ?: 0)
|
||||
val language = meta.language ?: itemView.context.getString(R.string.unknown)
|
||||
binding.language.text = if (meta.translated == true) {
|
||||
itemView.context.getString(R.string.language_translated, language)
|
||||
|
||||
@@ -41,7 +41,7 @@ class HBrowseDescriptionAdapter(
|
||||
val meta = controller.presenter.meta
|
||||
if (meta == null || meta !is HBrowseSearchMetadata) return
|
||||
|
||||
binding.pages.text = itemView.context.getString(R.string.num_pages, meta.length ?: 0)
|
||||
binding.pages.text = itemView.resources.getQuantityString(R.plurals.num_pages, meta.length ?: 0, meta.length ?: 0)
|
||||
|
||||
binding.moreInfo.clicks()
|
||||
.onEach {
|
||||
|
||||
@@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import exh.metadata.EX_DATE_FORMAT
|
||||
import exh.metadata.metadata.HitomiSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import exh.util.SourceTagsUtil
|
||||
import java.util.Date
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -47,16 +48,16 @@ class HitomiDescriptionAdapter(
|
||||
val genre = meta.type
|
||||
if (genre != null) {
|
||||
val pair = when (genre) {
|
||||
"doujinshi" -> Pair("#fc4e4e", R.string.doujinshi)
|
||||
"manga" -> Pair("#e78c1a", R.string.manga)
|
||||
"artist CG" -> Pair("#dde500", R.string.artist_cg)
|
||||
"game CG" -> Pair("#05bf0b", R.string.game_cg)
|
||||
"western" -> Pair("#14e723", R.string.western)
|
||||
"non-H" -> Pair("#08d7e2", R.string.non_h)
|
||||
"image Set" -> Pair("#5f5fff", R.string.image_set)
|
||||
"cosplay" -> Pair("#9755f5", R.string.cosplay)
|
||||
"asian Porn" -> Pair("#fe93ff", R.string.asian_porn)
|
||||
"misc" -> Pair("#9e9e9e", R.string.misc)
|
||||
"doujinshi" -> Pair(SourceTagsUtil.DOUJINSHI_COLOR, R.string.doujinshi)
|
||||
"manga" -> Pair(SourceTagsUtil.MANGA_COLOR, R.string.manga)
|
||||
"artist CG" -> Pair(SourceTagsUtil.ARTIST_CG_COLOR, R.string.artist_cg)
|
||||
"game CG" -> Pair(SourceTagsUtil.GAME_CG_COLOR, R.string.game_cg)
|
||||
"western" -> Pair(SourceTagsUtil.WESTERN_COLOR, R.string.western)
|
||||
"non-H" -> Pair(SourceTagsUtil.NON_H_COLOR, R.string.non_h)
|
||||
"image Set" -> Pair(SourceTagsUtil.IMAGE_SET_COLOR, R.string.image_set)
|
||||
"cosplay" -> Pair(SourceTagsUtil.COSPLAY_COLOR, R.string.cosplay)
|
||||
"asian Porn" -> Pair(SourceTagsUtil.ASIAN_PORN_COLOR, R.string.asian_porn)
|
||||
"misc" -> Pair(SourceTagsUtil.MISC_COLOR, R.string.misc)
|
||||
else -> Pair("", 0)
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import exh.metadata.EX_DATE_FORMAT
|
||||
import exh.metadata.metadata.NHentaiSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import exh.util.SourceTagsUtil
|
||||
import java.util.Date
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -54,16 +55,16 @@ class NHentaiDescriptionAdapter(
|
||||
|
||||
if (category != null) {
|
||||
val pair = when (category) {
|
||||
"doujinshi" -> Pair("#fc4e4e", R.string.doujinshi)
|
||||
"manga" -> Pair("#e78c1a", R.string.manga)
|
||||
"artistcg" -> Pair("#dde500", R.string.artist_cg)
|
||||
"gamecg" -> Pair("#05bf0b", R.string.game_cg)
|
||||
"western" -> Pair("#14e723", R.string.western)
|
||||
"non-h" -> Pair("#08d7e2", R.string.non_h)
|
||||
"imageset" -> Pair("#5f5fff", R.string.image_set)
|
||||
"cosplay" -> Pair("#9755f5", R.string.cosplay)
|
||||
"asianporn" -> Pair("#fe93ff", R.string.asian_porn)
|
||||
"misc" -> Pair("#9e9e9e", R.string.misc)
|
||||
"doujinshi" -> Pair(SourceTagsUtil.DOUJINSHI_COLOR, R.string.doujinshi)
|
||||
"manga" -> Pair(SourceTagsUtil.MANGA_COLOR, R.string.manga)
|
||||
"artistcg" -> Pair(SourceTagsUtil.ARTIST_CG_COLOR, R.string.artist_cg)
|
||||
"gamecg" -> Pair(SourceTagsUtil.GAME_CG_COLOR, R.string.game_cg)
|
||||
"western" -> Pair(SourceTagsUtil.WESTERN_COLOR, R.string.western)
|
||||
"non-h" -> Pair(SourceTagsUtil.NON_H_COLOR, R.string.non_h)
|
||||
"imageset" -> Pair(SourceTagsUtil.IMAGE_SET_COLOR, R.string.image_set)
|
||||
"cosplay" -> Pair(SourceTagsUtil.COSPLAY_COLOR, R.string.cosplay)
|
||||
"asianporn" -> Pair(SourceTagsUtil.ASIAN_PORN_COLOR, R.string.asian_porn)
|
||||
"misc" -> Pair(SourceTagsUtil.MISC_COLOR, R.string.misc)
|
||||
else -> Pair("", 0)
|
||||
}
|
||||
|
||||
@@ -85,7 +86,7 @@ class NHentaiDescriptionAdapter(
|
||||
|
||||
binding.whenPosted.text = EX_DATE_FORMAT.format(Date((meta.uploadDate ?: 0) * 1000))
|
||||
|
||||
binding.pages.text = itemView.context.getString(R.string.num_pages, meta.pageImageTypes.size)
|
||||
binding.pages.text = itemView.resources.getQuantityString(R.plurals.num_pages, meta.pageImageTypes.size, meta.pageImageTypes.size)
|
||||
@SuppressLint("SetTextI18n")
|
||||
binding.id.text = "#" + (meta.nhId ?: 0)
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import exh.metadata.metadata.PervEdenSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import exh.util.SourceTagsUtil
|
||||
import java.util.Locale
|
||||
import kotlin.math.roundToInt
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -47,11 +48,11 @@ class PervEdenDescriptionAdapter(
|
||||
val genre = meta.type
|
||||
if (genre != null) {
|
||||
val pair = when (genre) {
|
||||
"Doujinshi" -> Pair("#fc4e4e", R.string.doujinshi)
|
||||
"Japanese Manga" -> Pair("#e78c1a", R.string.manga)
|
||||
"Korean Manhwa" -> Pair("#dde500", R.string.manhwa)
|
||||
"Chinese Manhua" -> Pair("#05bf0b", R.string.manhua)
|
||||
"Comic" -> Pair("#14e723", R.string.comic)
|
||||
"Doujinshi" -> Pair(SourceTagsUtil.DOUJINSHI_COLOR, R.string.doujinshi)
|
||||
"Japanese Manga" -> Pair(SourceTagsUtil.MANGA_COLOR, R.string.manga)
|
||||
"Korean Manhwa" -> Pair(SourceTagsUtil.ARTIST_CG_COLOR, R.string.manhwa)
|
||||
"Chinese Manhua" -> Pair(SourceTagsUtil.GAME_CG_COLOR, R.string.manhua)
|
||||
"Comic" -> Pair(SourceTagsUtil.WESTERN_COLOR, R.string.comic)
|
||||
else -> Pair("", 0)
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import exh.metadata.metadata.PururinSearchMetadata
|
||||
import exh.metadata.metadata.PururinSearchMetadata.Companion.TAG_NAMESPACE_CATEGORY
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import exh.util.SourceTagsUtil
|
||||
import kotlin.math.roundToInt
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -47,12 +48,12 @@ class PururinDescriptionAdapter(
|
||||
val genre = meta.tags.find { it.namespace == TAG_NAMESPACE_CATEGORY }
|
||||
if (genre != null) {
|
||||
val pair = when (genre.name) {
|
||||
"doujinshi" -> Pair("#fc4e4e", R.string.doujinshi)
|
||||
"manga" -> Pair("#e78c1a", R.string.manga)
|
||||
"artist-cg" -> Pair("#dde500", R.string.artist_cg)
|
||||
"game-cg" -> Pair("#05bf0b", R.string.game_cg)
|
||||
"artbook" -> Pair("#5f5fff", R.string.artbook)
|
||||
"webtoon" -> Pair("#5f5fff", R.string.webtoon)
|
||||
"doujinshi" -> Pair(SourceTagsUtil.DOUJINSHI_COLOR, R.string.doujinshi)
|
||||
"manga" -> Pair(SourceTagsUtil.MANGA_COLOR, R.string.manga)
|
||||
"artist-cg" -> Pair(SourceTagsUtil.ARTIST_CG_COLOR, R.string.artist_cg)
|
||||
"game-cg" -> Pair(SourceTagsUtil.GAME_CG_COLOR, R.string.game_cg)
|
||||
"artbook" -> Pair(SourceTagsUtil.IMAGE_SET_COLOR, R.string.artbook)
|
||||
"webtoon" -> Pair(SourceTagsUtil.NON_H_COLOR, R.string.webtoon)
|
||||
else -> Pair("", 0)
|
||||
}
|
||||
|
||||
@@ -64,7 +65,7 @@ class PururinDescriptionAdapter(
|
||||
|
||||
binding.uploader.text = meta.uploaderDisp ?: meta.uploader ?: ""
|
||||
binding.size.text = meta.fileSize ?: itemView.context.getString(R.string.unknown)
|
||||
binding.pages.text = itemView.context.getString(R.string.num_pages, meta.pages ?: 0)
|
||||
binding.pages.text = itemView.resources.getQuantityString(R.plurals.num_pages, meta.pages ?: 0, meta.pages ?: 0)
|
||||
|
||||
val ratingFloat = meta.averageRating?.toFloat()
|
||||
val name = when (((ratingFloat ?: 100F) * 2).roundToInt()) {
|
||||
|
||||
@@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import exh.metadata.metadata.TsuminoSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import exh.util.SourceTagsUtil
|
||||
import java.util.Date
|
||||
import kotlin.math.roundToInt
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -48,11 +49,11 @@ class TsuminoDescriptionAdapter(
|
||||
val genre = meta.category
|
||||
if (genre != null) {
|
||||
val pair = when (genre) {
|
||||
"Doujinshi" -> Pair("#fc4e4e", R.string.doujinshi)
|
||||
"Manga" -> Pair("#e78c1a", R.string.manga)
|
||||
"Artist CG" -> Pair("#dde500", R.string.artist_cg)
|
||||
"Game CG" -> Pair("#05bf0b", R.string.game_cg)
|
||||
"Video" -> Pair("#14e723", R.string.video)
|
||||
"Doujinshi" -> Pair(SourceTagsUtil.DOUJINSHI_COLOR, R.string.doujinshi)
|
||||
"Manga" -> Pair(SourceTagsUtil.MANGA_COLOR, R.string.manga)
|
||||
"Artist CG" -> Pair(SourceTagsUtil.ARTIST_CG_COLOR, R.string.artist_cg)
|
||||
"Game CG" -> Pair(SourceTagsUtil.GAME_CG_COLOR, R.string.game_cg)
|
||||
"Video" -> Pair(SourceTagsUtil.WESTERN_COLOR, R.string.video)
|
||||
else -> Pair("", 0)
|
||||
}
|
||||
|
||||
@@ -70,7 +71,7 @@ class TsuminoDescriptionAdapter(
|
||||
binding.whenPosted.text = TsuminoSearchMetadata.TSUMINO_DATE_FORMAT.format(Date(meta.uploadDate ?: 0))
|
||||
|
||||
binding.uploader.text = meta.uploader ?: itemView.context.getString(R.string.unknown)
|
||||
binding.pages.text = itemView.context.getString(R.string.num_pages, meta.length ?: 0)
|
||||
binding.pages.text = itemView.resources.getQuantityString(R.plurals.num_pages, meta.length ?: 0, meta.length ?: 0)
|
||||
|
||||
val name = when (((meta.averageRating ?: 100F) * 2).roundToInt()) {
|
||||
0 -> R.string.rating0
|
||||
|
||||
@@ -1,30 +1,31 @@
|
||||
package exh.util
|
||||
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
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
|
||||
import exh.TSUMINO_SOURCE_ID
|
||||
import exh.metadata.metadata.base.RaisedTag
|
||||
import java.util.Locale
|
||||
|
||||
class SourceTagsUtil {
|
||||
fun getWrappedTag(sourceId: Long, namespace: String? = null, tag: String? = null, fullTag: String? = null): String? {
|
||||
return if (sourceId == EXH_SOURCE_ID || sourceId == EH_SOURCE_ID || sourceId == NHENTAI_SOURCE_ID || sourceId == HITOMI_SOURCE_ID) {
|
||||
val parsed = if (fullTag != null) parseTag(fullTag) else if (namespace != null && tag != null) Pair(namespace, tag) else null
|
||||
if (parsed != null) {
|
||||
val parsed = if (fullTag != null) parseTag(fullTag) else if (namespace != null && tag != null) RaisedTag(namespace, tag, TAG_TYPE_DEFAULT) else null
|
||||
if (parsed?.namespace != null) {
|
||||
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()
|
||||
TSUMINO_SOURCE_ID -> parsed.second.substringBefore('|').trim()
|
||||
else -> wrapTag(parsed.first, parsed.second.substringBefore('|').trim())
|
||||
HITOMI_SOURCE_ID -> wrapTagHitomi(parsed.namespace, parsed.name.substringBefore('|').trim())
|
||||
NHENTAI_SOURCE_ID -> wrapTagNHentai(parsed.namespace, parsed.name.substringBefore('|').trim())
|
||||
PURURIN_SOURCE_ID -> parsed.name.substringBefore('|').trim()
|
||||
TSUMINO_SOURCE_ID -> parsed.name.substringBefore('|').trim()
|
||||
else -> wrapTag(parsed.namespace, parsed.name.substringBefore('|').trim())
|
||||
}
|
||||
} else null
|
||||
} else null
|
||||
}
|
||||
|
||||
fun parseTag(tag: String) = tag.substringBefore(':').trim() to tag.substringAfter(':').trim()
|
||||
|
||||
private fun wrapTag(namespace: String, tag: String) = if (tag.contains(' ')) {
|
||||
"$namespace:\"$tag$\""
|
||||
} else {
|
||||
@@ -46,4 +47,40 @@ class SourceTagsUtil {
|
||||
} else {
|
||||
"$namespace:$tag"
|
||||
}
|
||||
companion object {
|
||||
fun Manga.getRaisedTags(): List<RaisedTag>? = this.getGenres()?.map { parseTag(it) }
|
||||
|
||||
fun parseTag(tag: String) = RaisedTag(tag.substringBefore(':').trimOrNull(), (tag.substringAfter(':').trimOrNull() ?: tag), TAG_TYPE_DEFAULT)
|
||||
|
||||
const val DOUJINSHI_COLOR = "#f44336"
|
||||
const val MANGA_COLOR = "#ff9800"
|
||||
const val ARTIST_CG_COLOR = "#fbc02d"
|
||||
const val GAME_CG_COLOR = "#4caf50"
|
||||
const val WESTERN_COLOR = "#8bc34a"
|
||||
const val NON_H_COLOR = "#2196f3"
|
||||
const val IMAGE_SET_COLOR = "#3f51b5"
|
||||
const val COSPLAY_COLOR = "#9c27b0"
|
||||
const val ASIAN_PORN_COLOR = "#9575cd"
|
||||
const val MISC_COLOR = "#f06292"
|
||||
|
||||
fun getLocaleSourceUtil(language: String?) = when (language) {
|
||||
"english", "eng" -> Locale("en")
|
||||
"chinese" -> Locale("zh")
|
||||
"spanish" -> Locale("es")
|
||||
"korean" -> Locale("ko")
|
||||
"russian" -> Locale("ru")
|
||||
"french" -> Locale("fr")
|
||||
"portuguese" -> Locale("pt")
|
||||
"thai" -> Locale("th")
|
||||
"german" -> Locale("de")
|
||||
"italian" -> Locale("it")
|
||||
"vietnamese" -> Locale("vi")
|
||||
"polish" -> Locale("pl")
|
||||
"hungarian" -> Locale("hu")
|
||||
"dutch" -> Locale("nl")
|
||||
else -> null
|
||||
}
|
||||
|
||||
private const val TAG_TYPE_DEFAULT = 1
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user