Add a special view to replace descriptions for integrated and delegated sources!
As the integrated and delegated websites don't actually have descriptions, just info, I decided to make a special view for them! with all the info you need available to you in front of your face, there is now no need to go searching through the description! This is likely the most work I have put into 1 feature in the whole time I have been developing TachiyomiSY!
This commit is contained in:
@@ -58,4 +58,4 @@ fun isLewdSource(source: Long) = source in 6900..6999 ||
|
||||
|
||||
fun Source.isEhBasedSource() = id == EH_SOURCE_ID || id == EXH_SOURCE_ID
|
||||
|
||||
fun Source.isNamespaceSource() = id == EH_SOURCE_ID || id == EXH_SOURCE_ID || id == NHENTAI_SOURCE_ID || id == HITOMI_SOURCE_ID || id == PURURIN_SOURCE_ID || id == TSUMINO_SOURCE_ID
|
||||
fun Source.isNamespaceSource() = id == EH_SOURCE_ID || id == EXH_SOURCE_ID || id == NHENTAI_SOURCE_ID || id == HITOMI_SOURCE_ID || id == PURURIN_SOURCE_ID || id == TSUMINO_SOURCE_ID || id == EIGHTMUSES_SOURCE_ID || id == HBROWSE_SOURCE_ID
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package exh.metadata.metadata
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import exh.metadata.EX_DATE_FORMAT
|
||||
import exh.metadata.ONGOING_SUFFIX
|
||||
import exh.metadata.humanReadableByteCount
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
import exh.plusAssign
|
||||
import java.util.Date
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
@@ -76,7 +77,7 @@ class EHentaiSearchMetadata : RaisedSearchMetadata() {
|
||||
}
|
||||
|
||||
// Build a nice looking description out of what we know
|
||||
val titleDesc = StringBuilder()
|
||||
/* val titleDesc = StringBuilder()
|
||||
title?.let { titleDesc += "Title: $it\n" }
|
||||
altTitle?.let { titleDesc += "Alternate Title: $it\n" }
|
||||
|
||||
@@ -99,11 +100,36 @@ class EHentaiSearchMetadata : RaisedSearchMetadata() {
|
||||
detailsDesc += "\n"
|
||||
}
|
||||
|
||||
val tagsDesc = tagsToDescription()
|
||||
val tagsDesc = tagsToDescription()*/
|
||||
|
||||
manga.description = listOf(titleDesc.toString(), detailsDesc.toString(), tagsDesc.toString())
|
||||
manga.description = "meta" /*listOf(titleDesc.toString(), detailsDesc.toString(), tagsDesc.toString())
|
||||
.filter(String::isNotBlank)
|
||||
.joinToString(separator = "\n")
|
||||
.joinToString(separator = "\n")*/
|
||||
}
|
||||
|
||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||
val pairs = mutableListOf<Pair<String, String>>()
|
||||
gId?.let { pairs += Pair(context.getString(R.string.id), it) }
|
||||
gToken?.let { pairs += Pair(context.getString(R.string.token), it) }
|
||||
exh?.let { pairs += Pair(context.getString(R.string.is_exhentai_gallery), context.getString(if (it) android.R.string.yes else android.R.string.no)) }
|
||||
thumbnailUrl?.let { pairs += Pair(context.getString(R.string.thumbnail_url), it) }
|
||||
title?.let { pairs += Pair(context.getString(R.string.title), it) }
|
||||
altTitle?.let { pairs += Pair(context.getString(R.string.alt_title), it) }
|
||||
genre?.let { pairs += Pair(context.getString(R.string.genre), it) }
|
||||
datePosted?.let { pairs += Pair(context.getString(R.string.date_posted), EX_DATE_FORMAT.format(Date(it))) }
|
||||
parent?.let { pairs += Pair(context.getString(R.string.parent), it) }
|
||||
visible?.let { pairs += Pair(context.getString(R.string.visible), it) }
|
||||
language?.let { pairs += Pair(context.getString(R.string.language), it) }
|
||||
translated?.let { pairs += Pair("Translated", context.getString(if (it) android.R.string.yes else android.R.string.no)) }
|
||||
size?.let { pairs += Pair(context.getString(R.string.gallery_size), humanReadableByteCount(it, true)) }
|
||||
length?.let { pairs += Pair(context.getString(R.string.page_count), it.toString()) }
|
||||
favorites?.let { pairs += Pair(context.getString(R.string.total_favorites), it.toString()) }
|
||||
ratingCount?.let { pairs += Pair(context.getString(R.string.total_ratings), it.toString()) }
|
||||
averageRating?.let { pairs += Pair(context.getString(R.string.average_rating), it.toString()) }
|
||||
aged.let { pairs += Pair(context.getString(R.string.aged), context.getString(if (it) android.R.string.yes else android.R.string.no)) }
|
||||
lastUpdateCheck.let { pairs += Pair(context.getString(R.string.last_update_check), EX_DATE_FORMAT.format(Date(it))) }
|
||||
|
||||
return pairs
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -112,6 +138,7 @@ class EHentaiSearchMetadata : RaisedSearchMetadata() {
|
||||
|
||||
const val TAG_TYPE_NORMAL = 0
|
||||
const val TAG_TYPE_LIGHT = 1
|
||||
const val TAG_TYPE_WEAK = 2
|
||||
|
||||
const val EH_GENRE_NAMESPACE = "genre"
|
||||
private const val EH_ARTIST_NAMESPACE = "artist"
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package exh.metadata.metadata
|
||||
|
||||
import android.content.Context
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
import exh.plusAssign
|
||||
|
||||
class EightMusesSearchMetadata : RaisedSearchMetadata() {
|
||||
var path: List<String> = emptyList()
|
||||
@@ -26,14 +27,25 @@ class EightMusesSearchMetadata : RaisedSearchMetadata() {
|
||||
|
||||
manga.genre = tagsToGenreString()
|
||||
|
||||
val titleDesc = StringBuilder()
|
||||
/*val titleDesc = StringBuilder()
|
||||
title?.let { titleDesc += "Title: $it\n" }
|
||||
|
||||
val tagsDesc = tagsToDescription()
|
||||
val tagsDesc = tagsToDescription()*/
|
||||
|
||||
manga.description = listOf(titleDesc.toString(), tagsDesc.toString())
|
||||
manga.description = "meta" /*listOf(titleDesc.toString(), tagsDesc.toString())
|
||||
.filter(String::isNotBlank)
|
||||
.joinToString(separator = "\n")
|
||||
.joinToString(separator = "\n")*/
|
||||
}
|
||||
|
||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||
val pairs = mutableListOf<Pair<String, String>>()
|
||||
title?.let { pairs += Pair(context.getString(R.string.title), it) }
|
||||
val path = path.joinToString("/", prefix = "/")
|
||||
if (path.isNotBlank()) {
|
||||
pairs += Pair(context.getString(R.string.path), path)
|
||||
}
|
||||
thumbnailUrl?.let { pairs += Pair(context.getString(R.string.thumbnail_url), it) }
|
||||
return pairs
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package exh.metadata.metadata
|
||||
|
||||
import android.content.Context
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import exh.metadata.metadata.EightMusesSearchMetadata.Companion.ARTIST_NAMESPACE
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
import exh.plusAssign
|
||||
|
||||
class HBrowseSearchMetadata : RaisedSearchMetadata() {
|
||||
var hbId: Long? = null
|
||||
@@ -27,15 +28,25 @@ class HBrowseSearchMetadata : RaisedSearchMetadata() {
|
||||
|
||||
manga.artist = tags.ofNamespace(ARTIST_NAMESPACE).joinToString { it.name }
|
||||
|
||||
val titleDesc = StringBuilder()
|
||||
manga.genre = tagsToGenreString()
|
||||
|
||||
/*val titleDesc = StringBuilder()
|
||||
title?.let { titleDesc += "Title: $it\n" }
|
||||
length?.let { titleDesc += "Length: $it page(s)\n" }
|
||||
|
||||
val tagsDesc = tagsToDescription()
|
||||
val tagsDesc = tagsToDescription()*/
|
||||
|
||||
manga.description = listOf(titleDesc.toString(), tagsDesc.toString())
|
||||
manga.description = "meta" /*listOf(titleDesc.toString(), tagsDesc.toString())
|
||||
.filter(String::isNotBlank)
|
||||
.joinToString(separator = "\n")
|
||||
.joinToString(separator = "\n")*/
|
||||
}
|
||||
|
||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||
val pairs = mutableListOf<Pair<String, String>>()
|
||||
hbId?.let { pairs += Pair(context.getString(R.string.id), it.toString()) }
|
||||
title?.let { pairs += Pair(context.getString(R.string.title), it) }
|
||||
length?.let { pairs += Pair(context.getString(R.string.page_count), it.toString()) }
|
||||
return pairs
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package exh.metadata.metadata
|
||||
|
||||
import android.content.Context
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
|
||||
@@ -30,16 +32,26 @@ class HentaiCafeSearchMetadata : RaisedSearchMetadata() {
|
||||
// Not available
|
||||
manga.status = SManga.UNKNOWN
|
||||
|
||||
val detailsDesc = "Title: $title\n" +
|
||||
"Artist: $artist\n"
|
||||
|
||||
val tagsDesc = tagsToDescription()
|
||||
|
||||
manga.genre = tagsToGenreString()
|
||||
|
||||
manga.description = listOf(detailsDesc, tagsDesc.toString())
|
||||
/* val detailsDesc = "Title: $title\n" +
|
||||
"Artist: $artist\n"
|
||||
|
||||
val tagsDesc = tagsToDescription()*/
|
||||
|
||||
manga.description = "meta" /*listOf(detailsDesc, tagsDesc.toString())
|
||||
.filter(String::isNotBlank)
|
||||
.joinToString(separator = "\n")
|
||||
.joinToString(separator = "\n")*/
|
||||
}
|
||||
|
||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||
val pairs = mutableListOf<Pair<String, String>>()
|
||||
hcId?.let { pairs += Pair(context.getString(R.string.id), it) }
|
||||
readerId?.let { pairs += Pair(context.getString(R.string.reader_id), it) }
|
||||
thumbnailUrl?.let { pairs += Pair(context.getString(R.string.thumbnail_url), it) }
|
||||
title?.let { pairs += Pair(context.getString(R.string.title), it) }
|
||||
artist?.let { pairs += Pair(context.getString(R.string.artist), it) }
|
||||
return pairs
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package exh.metadata.metadata
|
||||
|
||||
import android.content.Context
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import exh.metadata.EX_DATE_FORMAT
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
@@ -37,17 +39,25 @@ class HitomiSearchMetadata : RaisedSearchMetadata() {
|
||||
override fun copyTo(manga: SManga) {
|
||||
thumbnailUrl?.let { manga.thumbnail_url = it }
|
||||
|
||||
val titleDesc = StringBuilder()
|
||||
|
||||
title?.let {
|
||||
manga.title = it
|
||||
}
|
||||
|
||||
// Copy tags -> genres
|
||||
manga.genre = tagsToGenreString()
|
||||
|
||||
manga.artist = artists.joinToString()
|
||||
|
||||
manga.status = SManga.UNKNOWN
|
||||
|
||||
/*val titleDesc = StringBuilder()
|
||||
|
||||
title?.let {
|
||||
titleDesc += "Title: $it\n"
|
||||
}
|
||||
|
||||
val detailsDesc = StringBuilder()
|
||||
|
||||
manga.artist = artists.joinToString()
|
||||
|
||||
detailsDesc += "Artist(s): ${manga.artist}\n"
|
||||
|
||||
group?.let {
|
||||
@@ -74,16 +84,35 @@ class HitomiSearchMetadata : RaisedSearchMetadata() {
|
||||
detailsDesc += "Upload date: ${EX_DATE_FORMAT.format(Date(it))}\n"
|
||||
}
|
||||
|
||||
manga.status = SManga.UNKNOWN
|
||||
val tagsDesc = tagsToDescription()*/
|
||||
|
||||
// Copy tags -> genres
|
||||
manga.genre = tagsToGenreString()
|
||||
|
||||
val tagsDesc = tagsToDescription()
|
||||
|
||||
manga.description = listOf(titleDesc.toString(), detailsDesc.toString(), tagsDesc.toString())
|
||||
manga.description = "meta" /*listOf(titleDesc.toString(), detailsDesc.toString(), tagsDesc.toString())
|
||||
.filter(String::isNotBlank)
|
||||
.joinToString(separator = "\n")
|
||||
.joinToString(separator = "\n")*/
|
||||
}
|
||||
|
||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||
val pairs = mutableListOf<Pair<String, String>>()
|
||||
hlId?.let { pairs += Pair(context.getString(R.string.id), it) }
|
||||
title?.let { pairs += Pair(context.getString(R.string.title), it) }
|
||||
thumbnailUrl?.let { pairs += Pair(context.getString(R.string.thumbnail_url), it) }
|
||||
val artists = artists.joinToString()
|
||||
if (artists.isNotBlank()) {
|
||||
pairs += Pair(context.getString(R.string.artist), artists)
|
||||
}
|
||||
group?.let { pairs += Pair(context.getString(R.string.group), it) }
|
||||
type?.let { pairs += Pair(context.getString(R.string.genre), it) }
|
||||
language?.let { pairs += Pair(context.getString(R.string.language), it) }
|
||||
val series = series.joinToString()
|
||||
if (series.isNotBlank()) {
|
||||
pairs += Pair(context.getString(R.string.series), series)
|
||||
}
|
||||
val characters = characters.joinToString()
|
||||
if (characters.isNotBlank()) {
|
||||
pairs += Pair(context.getString(R.string.characters), characters)
|
||||
}
|
||||
uploadDate?.let { pairs += Pair(context.getString(R.string.date_posted), EX_DATE_FORMAT.format(Date(it))) }
|
||||
return pairs
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package exh.metadata.metadata
|
||||
|
||||
import android.content.Context
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import exh.metadata.EX_DATE_FORMAT
|
||||
import exh.metadata.ONGOING_SUFFIX
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
import exh.metadata.nullIfBlank
|
||||
import exh.plusAssign
|
||||
import java.util.Date
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
@@ -77,7 +77,7 @@ class NHentaiSearchMetadata : RaisedSearchMetadata() {
|
||||
}
|
||||
}
|
||||
|
||||
val titleDesc = StringBuilder()
|
||||
/*val titleDesc = StringBuilder()
|
||||
englishTitle?.let { titleDesc += "English Title: $it\n" }
|
||||
japaneseTitle?.let { titleDesc += "Japanese Title: $it\n" }
|
||||
shortTitle?.let { titleDesc += "Short Title: $it\n" }
|
||||
@@ -89,11 +89,27 @@ class NHentaiSearchMetadata : RaisedSearchMetadata() {
|
||||
favoritesCount?.let { detailsDesc += "Favorited: $it times\n" }
|
||||
scanlator?.nullIfBlank()?.let { detailsDesc += "Scanlator: $it\n" }
|
||||
|
||||
val tagsDesc = tagsToDescription()
|
||||
val tagsDesc = tagsToDescription()*/
|
||||
|
||||
manga.description = listOf(titleDesc.toString(), detailsDesc.toString(), tagsDesc.toString())
|
||||
manga.description = "meta" /*listOf(titleDesc.toString(), detailsDesc.toString(), tagsDesc.toString())
|
||||
.filter(String::isNotBlank)
|
||||
.joinToString(separator = "\n")
|
||||
.joinToString(separator = "\n")*/
|
||||
}
|
||||
|
||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||
val pairs = mutableListOf<Pair<String, String>>()
|
||||
nhId?.let { pairs += Pair(context.getString(R.string.id), it.toString()) }
|
||||
uploadDate?.let { pairs += Pair(context.getString(R.string.date_posted), EX_DATE_FORMAT.format(Date(it * 1000))) }
|
||||
favoritesCount?.let { pairs += Pair(context.getString(R.string.total_favorites), it.toString()) }
|
||||
mediaId?.let { pairs += Pair(context.getString(R.string.media_id), it) }
|
||||
japaneseTitle?.let { pairs += Pair(context.getString(R.string.japanese_title), it) }
|
||||
englishTitle?.let { pairs += Pair(context.getString(R.string.english_title), it) }
|
||||
shortTitle?.let { pairs += Pair(context.getString(R.string.short_title), it) }
|
||||
coverImageType?.let { pairs += Pair(context.getString(R.string.cover_image_file_type), it) }
|
||||
pageImageTypes.size.let { pairs += Pair(context.getString(R.string.page_count), it.toString()) }
|
||||
thumbnailImageType?.let { pairs += Pair(context.getString(R.string.thumbnail_image_file_type), it) }
|
||||
scanlator?.let { pairs += Pair(context.getString(R.string.scanlator), it) }
|
||||
return pairs
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -106,7 +122,7 @@ class NHentaiSearchMetadata : RaisedSearchMetadata() {
|
||||
const val BASE_URL = "https://nhentai.net"
|
||||
|
||||
private const val NHENTAI_ARTIST_NAMESPACE = "artist"
|
||||
private const val NHENTAI_CATEGORIES_NAMESPACE = "category"
|
||||
const val NHENTAI_CATEGORIES_NAMESPACE = "category"
|
||||
|
||||
fun typeToExtension(t: String?) =
|
||||
when (t) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package exh.metadata.metadata
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import exh.PERV_EDEN_EN_SOURCE_ID
|
||||
import exh.PERV_EDEN_IT_SOURCE_ID
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
import exh.metadata.metadata.base.RaisedTitle
|
||||
import exh.plusAssign
|
||||
|
||||
class PervEdenSearchMetadata : RaisedSearchMetadata() {
|
||||
var pvId: String? = null
|
||||
@@ -36,9 +37,28 @@ class PervEdenSearchMetadata : RaisedSearchMetadata() {
|
||||
url?.let { manga.url = it }
|
||||
thumbnailUrl?.let { manga.thumbnail_url = it }
|
||||
|
||||
val titleDesc = StringBuilder()
|
||||
title?.let {
|
||||
manga.title = it
|
||||
}
|
||||
|
||||
artist?.let {
|
||||
manga.artist = it
|
||||
}
|
||||
|
||||
status?.let {
|
||||
manga.status = when (it) {
|
||||
"Ongoing" -> SManga.ONGOING
|
||||
"Completed", "Suspended" -> SManga.COMPLETED
|
||||
else -> SManga.UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
// Copy tags -> genres
|
||||
manga.genre = tagsToGenreString()
|
||||
|
||||
/*val titleDesc = StringBuilder()
|
||||
|
||||
title?.let {
|
||||
titleDesc += "Title: $it\n"
|
||||
}
|
||||
if (altTitles.isNotEmpty()) {
|
||||
@@ -50,7 +70,6 @@ class PervEdenSearchMetadata : RaisedSearchMetadata() {
|
||||
|
||||
val detailsDesc = StringBuilder()
|
||||
artist?.let {
|
||||
manga.artist = it
|
||||
detailsDesc += "Artist: $it\n"
|
||||
}
|
||||
|
||||
@@ -59,11 +78,6 @@ class PervEdenSearchMetadata : RaisedSearchMetadata() {
|
||||
}
|
||||
|
||||
status?.let {
|
||||
manga.status = when (it) {
|
||||
"Ongoing" -> SManga.ONGOING
|
||||
"Completed", "Suspended" -> SManga.COMPLETED
|
||||
else -> SManga.UNKNOWN
|
||||
}
|
||||
detailsDesc += "Status: $it\n"
|
||||
}
|
||||
|
||||
@@ -71,14 +85,30 @@ class PervEdenSearchMetadata : RaisedSearchMetadata() {
|
||||
detailsDesc += "Rating: %.2\n".format(it)
|
||||
}
|
||||
|
||||
// Copy tags -> genres
|
||||
manga.genre = tagsToGenreString()
|
||||
|
||||
val tagsDesc = tagsToDescription()
|
||||
val tagsDesc = tagsToDescription()*/
|
||||
|
||||
manga.description = listOf(titleDesc.toString(), detailsDesc.toString(), tagsDesc.toString())
|
||||
manga.description = "meta" /*listOf(titleDesc.toString(), detailsDesc.toString(), tagsDesc.toString())
|
||||
.filter(String::isNotBlank)
|
||||
.joinToString(separator = "\n")
|
||||
.joinToString(separator = "\n")*/
|
||||
}
|
||||
|
||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||
val pairs = mutableListOf<Pair<String, String>>()
|
||||
pvId?.let { pairs += Pair(context.getString(R.string.id), it) }
|
||||
url?.let { pairs += Pair(context.getString(R.string.url), it) }
|
||||
thumbnailUrl?.let { pairs += Pair(context.getString(R.string.thumbnail_url), it) }
|
||||
title?.let { pairs += Pair(context.getString(R.string.title), it) }
|
||||
val altTitles = altTitles.joinToString()
|
||||
if (altTitles.isNotBlank()) {
|
||||
pairs += Pair(context.getString(R.string.alt_titles), altTitles)
|
||||
}
|
||||
artist?.let { pairs += Pair(context.getString(R.string.artist), it) }
|
||||
type?.let { pairs += Pair(context.getString(R.string.genre), it) }
|
||||
rating?.let { pairs += Pair(context.getString(R.string.average_rating), it.toString()) }
|
||||
status?.let { pairs += Pair(context.getString(R.string.status), it) }
|
||||
lang?.let { pairs += Pair(context.getString(R.string.language), it) }
|
||||
return pairs
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package exh.metadata.metadata
|
||||
|
||||
import android.content.Context
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
import exh.plusAssign
|
||||
|
||||
class PururinSearchMetadata : RaisedSearchMetadata() {
|
||||
var prId: Int? = null
|
||||
@@ -42,7 +43,7 @@ class PururinSearchMetadata : RaisedSearchMetadata() {
|
||||
|
||||
manga.genre = tagsToGenreString()
|
||||
|
||||
val titleDesc = StringBuilder()
|
||||
/*val titleDesc = StringBuilder()
|
||||
title?.let { titleDesc += "English Title: $it\n" }
|
||||
altTitle?.let { titleDesc += "Japanese Title: $it\n" }
|
||||
|
||||
@@ -52,11 +53,26 @@ class PururinSearchMetadata : RaisedSearchMetadata() {
|
||||
fileSize?.let { detailsDesc += "Size: $it\n" }
|
||||
ratingCount?.let { detailsDesc += "Rating: $averageRating ($ratingCount)\n" }
|
||||
|
||||
val tagsDesc = tagsToDescription()
|
||||
val tagsDesc = tagsToDescription()*/
|
||||
|
||||
manga.description = listOf(titleDesc.toString(), detailsDesc.toString(), tagsDesc.toString())
|
||||
manga.description = "meta" /*listOf(titleDesc.toString(), detailsDesc.toString(), tagsDesc.toString())
|
||||
.filter(String::isNotBlank)
|
||||
.joinToString(separator = "\n")
|
||||
.joinToString(separator = "\n")*/
|
||||
}
|
||||
|
||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||
val pairs = mutableListOf<Pair<String, String>>()
|
||||
prId?.let { pairs += Pair(context.getString(R.string.id), it.toString()) }
|
||||
title?.let { pairs += Pair(context.getString(R.string.title), it) }
|
||||
altTitle?.let { pairs += Pair(context.getString(R.string.alt_title), it) }
|
||||
thumbnailUrl?.let { pairs += Pair(context.getString(R.string.thumbnail_url), it) }
|
||||
uploaderDisp?.let { pairs += Pair(context.getString(R.string.uploader_capital), it) }
|
||||
uploader?.let { pairs += Pair(context.getString(R.string.uploader), it) }
|
||||
pages?.let { pairs += Pair(context.getString(R.string.page_count), it.toString()) }
|
||||
fileSize?.let { pairs += Pair(context.getString(R.string.gallery_size), it) }
|
||||
ratingCount?.let { pairs += Pair(context.getString(R.string.total_ratings), it.toString()) }
|
||||
averageRating?.let { pairs += Pair(context.getString(R.string.average_rating), it.toString()) }
|
||||
return pairs
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -66,6 +82,7 @@ class PururinSearchMetadata : RaisedSearchMetadata() {
|
||||
const val TAG_TYPE_DEFAULT = 0
|
||||
|
||||
private const val TAG_NAMESPACE_ARTIST = "artist"
|
||||
const val TAG_NAMESPACE_CATEGORY = "category"
|
||||
|
||||
val BASE_URL = "https://pururin.io"
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package exh.metadata.metadata
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import exh.metadata.EX_DATE_FORMAT
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
import exh.plusAssign
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
class TsuminoSearchMetadata : RaisedSearchMetadata() {
|
||||
var tmId: Int? = null
|
||||
@@ -20,6 +23,12 @@ class TsuminoSearchMetadata : RaisedSearchMetadata() {
|
||||
|
||||
var ratingString: String? = null
|
||||
|
||||
var averageRating: Float? = null
|
||||
|
||||
var userRatings: Long? = null
|
||||
|
||||
var favorites: Long? = null
|
||||
|
||||
var category: String? = null
|
||||
|
||||
var collection: String? = null
|
||||
@@ -38,7 +47,10 @@ class TsuminoSearchMetadata : RaisedSearchMetadata() {
|
||||
|
||||
manga.status = SManga.UNKNOWN
|
||||
|
||||
val titleDesc = "Title: $title\n"
|
||||
// Copy tags -> genres
|
||||
manga.genre = tagsToGenreString()
|
||||
|
||||
/*val titleDesc = "Title: $title\n"
|
||||
|
||||
val detailsDesc = StringBuilder()
|
||||
uploader?.let { detailsDesc += "Uploader: $it\n" }
|
||||
@@ -59,14 +71,36 @@ class TsuminoSearchMetadata : RaisedSearchMetadata() {
|
||||
detailsDesc += "Character: $charactersString\n"
|
||||
}
|
||||
|
||||
// Copy tags -> genres
|
||||
manga.genre = tagsToGenreString()
|
||||
val tagsDesc = tagsToDescription()*/
|
||||
|
||||
val tagsDesc = tagsToDescription()
|
||||
|
||||
manga.description = listOf(titleDesc, detailsDesc.toString(), tagsDesc.toString())
|
||||
manga.description = "meta" /*listOf(titleDesc, detailsDesc.toString(), tagsDesc.toString())
|
||||
.filter(String::isNotBlank)
|
||||
.joinToString(separator = "\n")
|
||||
.joinToString(separator = "\n")*/
|
||||
}
|
||||
|
||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||
val pairs = mutableListOf<Pair<String, String>>()
|
||||
tmId?.let { pairs += Pair(context.getString(R.string.id), it.toString()) }
|
||||
title?.let { pairs += Pair(context.getString(R.string.title), it) }
|
||||
uploader?.let { pairs += Pair(context.getString(R.string.uploader), it) }
|
||||
uploadDate?.let { pairs += Pair(context.getString(R.string.date_posted), EX_DATE_FORMAT.format(Date(it))) }
|
||||
length?.let { pairs += Pair(context.getString(R.string.page_count), it.toString()) }
|
||||
ratingString?.let { pairs += Pair(context.getString(R.string.rating_string), it) }
|
||||
averageRating?.let { pairs += Pair(context.getString(R.string.average_rating), it.toString()) }
|
||||
userRatings?.let { pairs += Pair(context.getString(R.string.total_ratings), it.toString()) }
|
||||
favorites?.let { pairs += Pair(context.getString(R.string.total_favorites), it.toString()) }
|
||||
category?.let { pairs += Pair(context.getString(R.string.genre), it) }
|
||||
collection?.let { pairs += Pair(context.getString(R.string.collection), it) }
|
||||
group?.let { pairs += Pair(context.getString(R.string.group), it) }
|
||||
val parodiesString = parody.joinToString()
|
||||
if (parodiesString.isNotEmpty()) {
|
||||
pairs += Pair(context.getString(R.string.parodies), parodiesString)
|
||||
}
|
||||
val charactersString = character.joinToString()
|
||||
if (charactersString.isNotEmpty()) {
|
||||
pairs += Pair(context.getString(R.string.characters), charactersString)
|
||||
}
|
||||
return pairs
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -76,6 +110,8 @@ class TsuminoSearchMetadata : RaisedSearchMetadata() {
|
||||
|
||||
val BASE_URL = "https://www.tsumino.com"
|
||||
|
||||
val TSUMINO_DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd", Locale.US)
|
||||
|
||||
fun tmIdFromUrl(url: String) =
|
||||
Uri.parse(url).lastPathSegment
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package exh.metadata.metadata.base
|
||||
|
||||
import android.content.Context
|
||||
import com.google.gson.GsonBuilder
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import exh.metadata.forEach
|
||||
@@ -112,6 +113,8 @@ abstract class RaisedSearchMetadata {
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun getExtraInfoPairs(context: Context): List<Pair<String, String>>
|
||||
|
||||
companion object {
|
||||
// Virtual tags allow searching of otherwise unindexed fields
|
||||
const val TAG_TYPE_VIRTUAL = -2
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package exh.ui.metadata
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.kanade.tachiyomi.databinding.MetadataViewItemBinding
|
||||
import kotlin.math.floor
|
||||
|
||||
class MetadataViewAdapter(private var data: List<Pair<String, String>>) :
|
||||
RecyclerView.Adapter<MetadataViewAdapter.ViewHolder>() {
|
||||
|
||||
private lateinit var binding: MetadataViewItemBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MetadataViewAdapter.ViewHolder {
|
||||
binding = MetadataViewItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return ViewHolder(binding.root)
|
||||
}
|
||||
|
||||
fun update(data: List<Pair<String, String>>) {
|
||||
this.data = data
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
// binds the data to the TextView in each cell
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
holder.bind(position)
|
||||
}
|
||||
|
||||
// total number of cells
|
||||
override fun getItemCount(): Int = data.size * 2
|
||||
|
||||
// stores and recycles views as they are scrolled off screen
|
||||
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
fun bind(position: Int) {
|
||||
if (data.isEmpty()) return
|
||||
val dataPosition = floor(position / 2F).toInt()
|
||||
binding.infoText.text = if (position % 2 == 0) data[dataPosition].first else data[dataPosition].second
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package exh.ui.metadata
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.databinding.MetadataViewControllerBinding
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.online.LewdSource.Companion.getLewdSource
|
||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import exh.metadata.metadata.base.FlatMetadata
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class MetadataViewController : NucleusController<MetadataViewControllerBinding, MetadataViewPresenter> {
|
||||
constructor(manga: Manga?) : super(
|
||||
Bundle().apply {
|
||||
putLong(MangaController.MANGA_EXTRA, manga?.id ?: 0)
|
||||
}
|
||||
) {
|
||||
this.manga = manga
|
||||
if (manga != null) {
|
||||
source = Injekt.get<SourceManager>().getOrStub(manga.source)
|
||||
}
|
||||
}
|
||||
|
||||
constructor(mangaId: Long) : this(
|
||||
Injekt.get<DatabaseHelper>().getManga(mangaId).executeAsBlocking()
|
||||
)
|
||||
|
||||
@Suppress("unused")
|
||||
constructor(bundle: Bundle) : this(bundle.getLong(MangaController.MANGA_EXTRA))
|
||||
|
||||
var data = emptyList<Pair<String, String>>()
|
||||
|
||||
var adapter: MetadataViewAdapter? = null
|
||||
|
||||
var manga: Manga? = null
|
||||
private set
|
||||
var source: Source? = null
|
||||
private set
|
||||
|
||||
override fun getTitle(): String? {
|
||||
return manga?.title
|
||||
}
|
||||
|
||||
override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
|
||||
binding = MetadataViewControllerBinding.inflate(inflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun createPresenter(): MetadataViewPresenter {
|
||||
return MetadataViewPresenter(
|
||||
manga!!,
|
||||
source!!
|
||||
)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View) {
|
||||
super.onViewCreated(view)
|
||||
|
||||
if (manga == null || source == null) return
|
||||
binding.recycler.layoutManager = GridLayoutManager(view.context, 2)
|
||||
adapter = MetadataViewAdapter(data)
|
||||
binding.recycler.adapter = adapter
|
||||
binding.recycler.setHasFixedSize(true)
|
||||
}
|
||||
|
||||
fun onNextMetaInfo(flatMetadata: FlatMetadata) {
|
||||
val thisSourceAsLewdSource = presenter.source.getLewdSource()
|
||||
if (thisSourceAsLewdSource != null) {
|
||||
presenter.meta = flatMetadata.raise(thisSourceAsLewdSource.metaClass)
|
||||
}
|
||||
}
|
||||
|
||||
fun onNextMangaInfo(meta: RaisedSearchMetadata?) {
|
||||
val context = view?.context ?: return
|
||||
data = meta?.getExtraInfoPairs(context) ?: emptyList()
|
||||
adapter?.update(data)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package exh.ui.metadata
|
||||
|
||||
import android.os.Bundle
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import exh.metadata.metadata.base.FlatMetadata
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
import exh.metadata.metadata.base.getFlatMetadataForManga
|
||||
import rx.Observable
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import timber.log.Timber
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class MetadataViewPresenter(
|
||||
val manga: Manga,
|
||||
val source: Source,
|
||||
val preferences: PreferencesHelper = Injekt.get(),
|
||||
private val db: DatabaseHelper = Injekt.get()
|
||||
) : BasePresenter<MetadataViewController>() {
|
||||
|
||||
var meta: RaisedSearchMetadata? = null
|
||||
|
||||
override fun onCreate(savedState: Bundle?) {
|
||||
super.onCreate(savedState)
|
||||
|
||||
getMangaMetaObservable().subscribeLatestCache({ view, flatMetadata -> if (flatMetadata != null) view.onNextMetaInfo(flatMetadata) else Timber.d("Invalid metadata") })
|
||||
|
||||
getMangaObservable()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeLatestCache({ view, _ -> view.onNextMangaInfo(meta) })
|
||||
}
|
||||
|
||||
private fun getMangaObservable(): Observable<Manga> {
|
||||
return db.getManga(manga.url, manga.source).asRxObservable()
|
||||
}
|
||||
|
||||
private fun getMangaMetaObservable(): Observable<FlatMetadata?> {
|
||||
val mangaId = manga.id
|
||||
return if (mangaId != null) {
|
||||
db.getFlatMetadataForManga(mangaId).asRxObservable()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
} else Observable.just(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
package exh.ui.metadata.adapters
|
||||
|
||||
import android.graphics.Color
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterEhBinding
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import exh.metadata.EX_DATE_FORMAT
|
||||
import exh.metadata.humanReadableByteCount
|
||||
import exh.metadata.metadata.EHentaiSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import java.util.Date
|
||||
import kotlin.math.roundToInt
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
|
||||
class EHentaiDescriptionAdapter(
|
||||
private val controller: MangaController
|
||||
) :
|
||||
RecyclerView.Adapter<EHentaiDescriptionAdapter.EHentaiDescriptionViewHolder>() {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private lateinit var binding: DescriptionAdapterEhBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EHentaiDescriptionViewHolder {
|
||||
binding = DescriptionAdapterEhBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return EHentaiDescriptionViewHolder(binding.root)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = 1
|
||||
|
||||
override fun onBindViewHolder(holder: EHentaiDescriptionViewHolder, position: Int) {
|
||||
holder.bind()
|
||||
}
|
||||
|
||||
inner class EHentaiDescriptionViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
fun bind() {
|
||||
val meta = controller.presenter.meta
|
||||
if (meta == null || meta !is EHentaiSearchMetadata) return
|
||||
|
||||
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)
|
||||
else -> Pair("", 0)
|
||||
}
|
||||
|
||||
if (pair.first.isNotBlank()) {
|
||||
binding.genre.setBackgroundColor(Color.parseColor(pair.first))
|
||||
binding.genre.text = itemView.context.getString(pair.second)
|
||||
} else binding.genre.text = genre
|
||||
} else binding.genre.setText(R.string.unknown)
|
||||
|
||||
binding.visible.text = itemView.context.getString(R.string.is_visible, meta.visible ?: itemView.context.getString(R.string.unknown))
|
||||
|
||||
binding.favorites.text = (meta.favorites ?: 0).toString()
|
||||
val drawable = itemView.context.getDrawable(R.drawable.ic_favorite_24dp)
|
||||
drawable?.setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
||||
binding.favorites.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null)
|
||||
|
||||
binding.whenPosted.text = EX_DATE_FORMAT.format(Date(meta.datePosted ?: 0))
|
||||
|
||||
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)
|
||||
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)
|
||||
} else {
|
||||
language
|
||||
}
|
||||
|
||||
val ratingFloat = meta.averageRating?.toFloat()
|
||||
val name = when (((ratingFloat ?: 100F) * 2).roundToInt()) {
|
||||
0 -> R.string.rating0
|
||||
1 -> R.string.rating1
|
||||
2 -> R.string.rating2
|
||||
3 -> R.string.rating3
|
||||
4 -> R.string.rating4
|
||||
5 -> R.string.rating5
|
||||
6 -> R.string.rating6
|
||||
7 -> R.string.rating7
|
||||
8 -> R.string.rating8
|
||||
9 -> R.string.rating9
|
||||
10 -> R.string.rating10
|
||||
else -> R.string.no_rating
|
||||
}
|
||||
binding.ratingBar.rating = ratingFloat ?: 0F
|
||||
binding.rating.text = if (meta.ratingCount != null) {
|
||||
itemView.context.getString(R.string.rating_view, itemView.context.getString(name), (ratingFloat ?: 0F).toString(), meta.ratingCount ?: 0)
|
||||
} else {
|
||||
itemView.context.getString(R.string.rating_view_no_count, itemView.context.getString(name), (ratingFloat ?: 0F).toString())
|
||||
}
|
||||
|
||||
binding.moreInfo.clicks()
|
||||
.onEach {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package exh.ui.metadata.adapters
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapter8mBinding
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import exh.metadata.metadata.EightMusesSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
|
||||
class EightMusesDescriptionAdapter(
|
||||
private val controller: MangaController
|
||||
) :
|
||||
RecyclerView.Adapter<EightMusesDescriptionAdapter.EightMusesDescriptionViewHolder>() {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private lateinit var binding: DescriptionAdapter8mBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EightMusesDescriptionViewHolder {
|
||||
binding = DescriptionAdapter8mBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return EightMusesDescriptionViewHolder(binding.root)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = 1
|
||||
|
||||
override fun onBindViewHolder(holder: EightMusesDescriptionViewHolder, position: Int) {
|
||||
holder.bind()
|
||||
}
|
||||
|
||||
inner class EightMusesDescriptionViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
fun bind() {
|
||||
val meta = controller.presenter.meta
|
||||
if (meta == null || meta !is EightMusesSearchMetadata) return
|
||||
|
||||
binding.title.text = meta.title ?: itemView.context.getString(R.string.unknown)
|
||||
|
||||
binding.moreInfo.clicks()
|
||||
.onEach {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package exh.ui.metadata.adapters
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterHbBinding
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import exh.metadata.metadata.HBrowseSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
|
||||
class HBrowseDescriptionAdapter(
|
||||
private val controller: MangaController
|
||||
) :
|
||||
RecyclerView.Adapter<HBrowseDescriptionAdapter.HBrowseDescriptionViewHolder>() {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private lateinit var binding: DescriptionAdapterHbBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HBrowseDescriptionViewHolder {
|
||||
binding = DescriptionAdapterHbBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return HBrowseDescriptionViewHolder(binding.root)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = 1
|
||||
|
||||
override fun onBindViewHolder(holder: HBrowseDescriptionViewHolder, position: Int) {
|
||||
holder.bind()
|
||||
}
|
||||
|
||||
inner class HBrowseDescriptionViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
fun bind() {
|
||||
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.moreInfo.clicks()
|
||||
.onEach {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package exh.ui.metadata.adapters
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterHcBinding
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import exh.metadata.metadata.HentaiCafeSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
|
||||
class HentaiCafeDescriptionAdapter(
|
||||
private val controller: MangaController
|
||||
) :
|
||||
RecyclerView.Adapter<HentaiCafeDescriptionAdapter.HentaiCafeDescriptionViewHolder>() {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private lateinit var binding: DescriptionAdapterHcBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HentaiCafeDescriptionViewHolder {
|
||||
binding = DescriptionAdapterHcBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return HentaiCafeDescriptionViewHolder(binding.root)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = 1
|
||||
|
||||
override fun onBindViewHolder(holder: HentaiCafeDescriptionViewHolder, position: Int) {
|
||||
holder.bind()
|
||||
}
|
||||
|
||||
inner class HentaiCafeDescriptionViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
fun bind() {
|
||||
val meta = controller.presenter.meta
|
||||
if (meta == null || meta !is HentaiCafeSearchMetadata) return
|
||||
|
||||
binding.artist.text = meta.artist ?: itemView.context.getString(R.string.unknown)
|
||||
|
||||
binding.moreInfo.clicks()
|
||||
.onEach {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package exh.ui.metadata.adapters
|
||||
|
||||
import android.graphics.Color
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterHiBinding
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import exh.metadata.EX_DATE_FORMAT
|
||||
import exh.metadata.metadata.HitomiSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import java.util.Date
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
|
||||
class HitomiDescriptionAdapter(
|
||||
private val controller: MangaController
|
||||
) :
|
||||
RecyclerView.Adapter<HitomiDescriptionAdapter.HitomiDescriptionViewHolder>() {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private lateinit var binding: DescriptionAdapterHiBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HitomiDescriptionViewHolder {
|
||||
binding = DescriptionAdapterHiBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return HitomiDescriptionViewHolder(binding.root)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = 1
|
||||
|
||||
override fun onBindViewHolder(holder: HitomiDescriptionViewHolder, position: Int) {
|
||||
holder.bind()
|
||||
}
|
||||
|
||||
inner class HitomiDescriptionViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
fun bind() {
|
||||
val meta = controller.presenter.meta
|
||||
if (meta == null || meta !is HitomiSearchMetadata) return
|
||||
|
||||
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)
|
||||
else -> Pair("", 0)
|
||||
}
|
||||
|
||||
if (pair.first.isNotBlank()) {
|
||||
binding.genre.setBackgroundColor(Color.parseColor(pair.first))
|
||||
binding.genre.text = itemView.context.getString(pair.second)
|
||||
} else binding.genre.text = genre
|
||||
} else binding.genre.setText(R.string.unknown)
|
||||
|
||||
binding.whenPosted.text = EX_DATE_FORMAT.format(Date(meta.uploadDate ?: 0))
|
||||
binding.group.text = meta.group ?: itemView.context.getString(R.string.unknown)
|
||||
binding.language.text = meta.language ?: itemView.context.getString(R.string.unknown)
|
||||
|
||||
binding.moreInfo.clicks()
|
||||
.onEach {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package exh.ui.metadata.adapters
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.graphics.Color
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterNhBinding
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import exh.metadata.EX_DATE_FORMAT
|
||||
import exh.metadata.metadata.NHentaiSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import java.util.Date
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
|
||||
class NHentaiDescriptionAdapter(
|
||||
private val controller: MangaController
|
||||
) :
|
||||
RecyclerView.Adapter<NHentaiDescriptionAdapter.NHentaiDescriptionViewHolder>() {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private lateinit var binding: DescriptionAdapterNhBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NHentaiDescriptionViewHolder {
|
||||
binding = DescriptionAdapterNhBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return NHentaiDescriptionViewHolder(binding.root)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = 1
|
||||
|
||||
override fun onBindViewHolder(holder: NHentaiDescriptionViewHolder, position: Int) {
|
||||
holder.bind()
|
||||
}
|
||||
|
||||
inner class NHentaiDescriptionViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
|
||||
fun bind() {
|
||||
val meta = controller.presenter.meta
|
||||
if (meta == null || meta !is NHentaiSearchMetadata) return
|
||||
|
||||
var category: String? = null
|
||||
meta.tags.filter { it.namespace == NHentaiSearchMetadata.NHENTAI_CATEGORIES_NAMESPACE }.let {
|
||||
if (it.isNotEmpty()) category = it.joinToString(transform = { it.name })
|
||||
}
|
||||
|
||||
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)
|
||||
else -> Pair("", 0)
|
||||
}
|
||||
|
||||
if (pair.first.isNotBlank()) {
|
||||
binding.genre.setBackgroundColor(Color.parseColor(pair.first))
|
||||
binding.genre.text = itemView.context.getString(pair.second)
|
||||
} else binding.genre.text = category
|
||||
} else binding.genre.setText(R.string.unknown)
|
||||
|
||||
meta.favoritesCount?.let {
|
||||
if (it == 0L) return@let
|
||||
binding.favorites.text = it.toString()
|
||||
|
||||
val drawable = itemView.context.getDrawable(R.drawable.ic_favorite_24dp)
|
||||
drawable?.setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
||||
|
||||
binding.favorites.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null)
|
||||
}
|
||||
|
||||
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)
|
||||
@SuppressLint("SetTextI18n")
|
||||
binding.id.text = "#" + (meta.nhId ?: 0)
|
||||
|
||||
binding.moreInfo.clicks()
|
||||
.onEach {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package exh.ui.metadata.adapters
|
||||
|
||||
import android.graphics.Color
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterPeBinding
|
||||
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 java.util.Locale
|
||||
import kotlin.math.roundToInt
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
|
||||
class PervEdenDescriptionAdapter(
|
||||
private val controller: MangaController
|
||||
) :
|
||||
RecyclerView.Adapter<PervEdenDescriptionAdapter.PervEdenDescriptionViewHolder>() {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private lateinit var binding: DescriptionAdapterPeBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PervEdenDescriptionViewHolder {
|
||||
binding = DescriptionAdapterPeBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return PervEdenDescriptionViewHolder(binding.root)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = 1
|
||||
|
||||
override fun onBindViewHolder(holder: PervEdenDescriptionViewHolder, position: Int) {
|
||||
holder.bind()
|
||||
}
|
||||
|
||||
inner class PervEdenDescriptionViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
fun bind() {
|
||||
val meta = controller.presenter.meta
|
||||
if (meta == null || meta !is PervEdenSearchMetadata) return
|
||||
|
||||
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)
|
||||
else -> Pair("", 0)
|
||||
}
|
||||
|
||||
if (pair.first.isNotBlank()) {
|
||||
binding.genre.setBackgroundColor(Color.parseColor(pair.first))
|
||||
binding.genre.text = itemView.context.getString(pair.second)
|
||||
} else binding.genre.text = genre
|
||||
} else binding.genre.setText(R.string.unknown)
|
||||
|
||||
val language = meta.lang
|
||||
binding.language.text = if (language != null) {
|
||||
val local = Locale(language)
|
||||
local.displayName
|
||||
} else itemView.context.getString(R.string.unknown)
|
||||
|
||||
val name = when (((meta.rating ?: 100F) * 2).roundToInt()) {
|
||||
0 -> R.string.rating0
|
||||
1 -> R.string.rating1
|
||||
2 -> R.string.rating2
|
||||
3 -> R.string.rating3
|
||||
4 -> R.string.rating4
|
||||
5 -> R.string.rating5
|
||||
6 -> R.string.rating6
|
||||
7 -> R.string.rating7
|
||||
8 -> R.string.rating8
|
||||
9 -> R.string.rating9
|
||||
10 -> R.string.rating10
|
||||
else -> R.string.no_rating
|
||||
}
|
||||
binding.ratingBar.rating = meta.rating ?: 0F
|
||||
binding.rating.text = itemView.context.getString(R.string.rating_view_no_count, itemView.context.getString(name), (meta.rating ?: 0F).toString())
|
||||
|
||||
binding.moreInfo.clicks()
|
||||
.onEach {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package exh.ui.metadata.adapters
|
||||
|
||||
import android.graphics.Color
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterPuBinding
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
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 kotlin.math.roundToInt
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
|
||||
class PururinDescriptionAdapter(
|
||||
private val controller: MangaController
|
||||
) :
|
||||
RecyclerView.Adapter<PururinDescriptionAdapter.PururinDescriptionViewHolder>() {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private lateinit var binding: DescriptionAdapterPuBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PururinDescriptionViewHolder {
|
||||
binding = DescriptionAdapterPuBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return PururinDescriptionViewHolder(binding.root)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = 1
|
||||
|
||||
override fun onBindViewHolder(holder: PururinDescriptionViewHolder, position: Int) {
|
||||
holder.bind()
|
||||
}
|
||||
|
||||
inner class PururinDescriptionViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
fun bind() {
|
||||
val meta = controller.presenter.meta
|
||||
if (meta == null || meta !is PururinSearchMetadata) return
|
||||
|
||||
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)
|
||||
else -> Pair("", 0)
|
||||
}
|
||||
|
||||
if (pair.first.isNotBlank()) {
|
||||
binding.genre.setBackgroundColor(Color.parseColor(pair.first))
|
||||
binding.genre.text = itemView.context.getString(pair.second)
|
||||
} else binding.genre.text = genre.name
|
||||
} else binding.genre.setText(R.string.unknown)
|
||||
|
||||
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)
|
||||
|
||||
val ratingFloat = meta.averageRating?.toFloat()
|
||||
val name = when (((ratingFloat ?: 100F) * 2).roundToInt()) {
|
||||
0 -> R.string.rating0
|
||||
1 -> R.string.rating1
|
||||
2 -> R.string.rating2
|
||||
3 -> R.string.rating3
|
||||
4 -> R.string.rating4
|
||||
5 -> R.string.rating5
|
||||
6 -> R.string.rating6
|
||||
7 -> R.string.rating7
|
||||
8 -> R.string.rating8
|
||||
9 -> R.string.rating9
|
||||
10 -> R.string.rating10
|
||||
else -> R.string.no_rating
|
||||
}
|
||||
binding.ratingBar.rating = ratingFloat ?: 0F
|
||||
binding.rating.text = if (meta.ratingCount != null) {
|
||||
itemView.context.getString(R.string.rating_view, itemView.context.getString(name), (ratingFloat ?: 0F).toString(), meta.ratingCount ?: 0)
|
||||
} else {
|
||||
itemView.context.getString(R.string.rating_view_no_count, itemView.context.getString(name), (ratingFloat ?: 0F).toString())
|
||||
}
|
||||
|
||||
binding.moreInfo.clicks()
|
||||
.onEach {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package exh.ui.metadata.adapters
|
||||
|
||||
import android.graphics.Color
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterTsBinding
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
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 java.util.Date
|
||||
import kotlin.math.roundToInt
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
|
||||
class TsuminoDescriptionAdapter(
|
||||
private val controller: MangaController
|
||||
) :
|
||||
RecyclerView.Adapter<TsuminoDescriptionAdapter.TsuminoDescriptionViewHolder>() {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private lateinit var binding: DescriptionAdapterTsBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TsuminoDescriptionViewHolder {
|
||||
binding = DescriptionAdapterTsBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return TsuminoDescriptionViewHolder(binding.root)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = 1
|
||||
|
||||
override fun onBindViewHolder(holder: TsuminoDescriptionViewHolder, position: Int) {
|
||||
holder.bind()
|
||||
}
|
||||
|
||||
inner class TsuminoDescriptionViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
fun bind() {
|
||||
val meta = controller.presenter.meta
|
||||
if (meta == null || meta !is TsuminoSearchMetadata) return
|
||||
|
||||
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)
|
||||
else -> Pair("", 0)
|
||||
}
|
||||
|
||||
if (pair.first.isNotBlank()) {
|
||||
binding.genre.setBackgroundColor(Color.parseColor(pair.first))
|
||||
binding.genre.text = itemView.context.getString(pair.second)
|
||||
} else binding.genre.text = genre
|
||||
} else binding.genre.setText(R.string.unknown)
|
||||
|
||||
binding.favorites.text = (meta.favorites ?: 0).toString()
|
||||
val drawable = itemView.context.getDrawable(R.drawable.ic_favorite_24dp)
|
||||
drawable?.setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
||||
binding.favorites.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null)
|
||||
|
||||
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)
|
||||
|
||||
val name = when (((meta.averageRating ?: 100F) * 2).roundToInt()) {
|
||||
0 -> R.string.rating0
|
||||
1 -> R.string.rating1
|
||||
2 -> R.string.rating2
|
||||
3 -> R.string.rating3
|
||||
4 -> R.string.rating4
|
||||
5 -> R.string.rating5
|
||||
6 -> R.string.rating6
|
||||
7 -> R.string.rating7
|
||||
8 -> R.string.rating8
|
||||
9 -> R.string.rating9
|
||||
10 -> R.string.rating10
|
||||
else -> R.string.no_rating
|
||||
}
|
||||
binding.ratingBar.rating = meta.averageRating ?: 0F
|
||||
binding.rating.text = if (meta.userRatings != null) {
|
||||
itemView.context.getString(R.string.rating_view, itemView.context.getString(name), (meta.averageRating ?: 0F).toString(), meta.userRatings ?: 0L)
|
||||
} else {
|
||||
itemView.context.getString(R.string.rating_view_no_count, itemView.context.getString(name), (meta.averageRating ?: 0F).toString())
|
||||
}
|
||||
|
||||
binding.moreInfo.clicks()
|
||||
.onEach {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,11 @@ import android.widget.FrameLayout
|
||||
import androidx.annotation.Px
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.google.android.material.chip.ChipGroup
|
||||
import exh.EH_SOURCE_ID
|
||||
import exh.EXH_SOURCE_ID
|
||||
import exh.metadata.metadata.EHentaiSearchMetadata.Companion.TAG_TYPE_LIGHT
|
||||
import exh.metadata.metadata.EHentaiSearchMetadata.Companion.TAG_TYPE_NORMAL
|
||||
import exh.metadata.metadata.EHentaiSearchMetadata.Companion.TAG_TYPE_WEAK
|
||||
|
||||
inline val View.marginTop: Int
|
||||
get() = (layoutParams as? ViewGroup.MarginLayoutParams)?.topMargin ?: 0
|
||||
@@ -120,7 +125,7 @@ fun ChipGroup.setChipsExtended(items: List<String>?, onClick: (item: String) ->
|
||||
}
|
||||
}
|
||||
|
||||
fun makeSearchChip(item: String, onClick: (item: String) -> Unit = {}, onLongClick: (item: String) -> Unit = {}, sourceId: Long, context: Context, namespace: String? = null): Chip {
|
||||
fun makeSearchChip(item: String, onClick: (item: String) -> Unit = {}, onLongClick: (item: String) -> Unit = {}, sourceId: Long, context: Context, namespace: String? = null, type: Int? = 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
|
||||
@@ -129,5 +134,13 @@ fun makeSearchChip(item: String, onClick: (item: String) -> Unit = {}, onLongCli
|
||||
onLongClick(search)
|
||||
false
|
||||
}
|
||||
if (sourceId == EXH_SOURCE_ID || sourceId == EH_SOURCE_ID) {
|
||||
chipStrokeWidth = when (type) {
|
||||
TAG_TYPE_NORMAL -> 5F
|
||||
TAG_TYPE_LIGHT -> 3F
|
||||
TAG_TYPE_WEAK -> 0F
|
||||
else -> chipStrokeWidth
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user