Refactor and cleanup a bunch of code
This commit is contained in:
parent
114fb723dc
commit
9cba544ffd
@ -39,7 +39,7 @@ import exh.eh.EHentaiThrottleManager
|
|||||||
import exh.metadata.metadata.base.getFlatMetadataForManga
|
import exh.metadata.metadata.base.getFlatMetadataForManga
|
||||||
import exh.metadata.metadata.base.insertFlatMetadata
|
import exh.metadata.metadata.base.insertFlatMetadata
|
||||||
import exh.savedsearches.JsonSavedSearch
|
import exh.savedsearches.JsonSavedSearch
|
||||||
import exh.source.EnhancedHttpSource.Companion.getMainSource
|
import exh.source.getMainSource
|
||||||
import kotlinx.serialization.ExperimentalSerializationApi
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
import kotlinx.serialization.decodeFromString
|
import kotlinx.serialization.decodeFromString
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
|
@ -40,7 +40,7 @@ import exh.MERGED_SOURCE_ID
|
|||||||
import exh.md.utils.FollowStatus
|
import exh.md.utils.FollowStatus
|
||||||
import exh.md.utils.MdUtil
|
import exh.md.utils.MdUtil
|
||||||
import exh.metadata.metadata.base.insertFlatMetadata
|
import exh.metadata.metadata.base.insertFlatMetadata
|
||||||
import exh.source.EnhancedHttpSource.Companion.getMainSource
|
import exh.source.getMainSource
|
||||||
import exh.util.asObservable
|
import exh.util.asObservable
|
||||||
import exh.util.await
|
import exh.util.await
|
||||||
import exh.util.awaitSingle
|
import exh.util.awaitSingle
|
||||||
@ -425,7 +425,7 @@ class LibraryUpdateService(
|
|||||||
* @return a pair of the inserted and removed chapters.
|
* @return a pair of the inserted and removed chapters.
|
||||||
*/
|
*/
|
||||||
fun updateManga(manga: Manga): Observable<Pair<List<Chapter>, List<Chapter>>> {
|
fun updateManga(manga: Manga): Observable<Pair<List<Chapter>, List<Chapter>>> {
|
||||||
val source = sourceManager.getOrStub(manga.source)
|
val source = sourceManager.getOrStub(manga.source).getMainSource()
|
||||||
|
|
||||||
// Update manga details metadata in the background
|
// Update manga details metadata in the background
|
||||||
if (preferences.autoUpdateMetadata()) {
|
if (preferences.autoUpdateMetadata()) {
|
||||||
@ -447,21 +447,6 @@ class LibraryUpdateService(
|
|||||||
.subscribe()
|
.subscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SY -->
|
|
||||||
if (source.getMainSource() is MangaDex && trackManager.mdList.isLogged) {
|
|
||||||
try {
|
|
||||||
val tracks = db.getTracks(manga).executeAsBlocking()
|
|
||||||
if (tracks.isEmpty() || tracks.all { it.sync_id != TrackManager.MDLIST }) {
|
|
||||||
var track = trackManager.mdList.createInitialTracker(manga)
|
|
||||||
track = runBlocking { trackManager.mdList.refresh(track).awaitSingle() }
|
|
||||||
db.insertTrack(track).executeAsBlocking()
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
XLog.e(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// SY <--
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
/* SY --> */ if (source is MergedSource) runBlocking { source.fetchChaptersAndSync(manga, false).asObservable() }
|
/* SY --> */ if (source is MergedSource) runBlocking { source.fetchChaptersAndSync(manga, false).asObservable() }
|
||||||
else /* SY <-- */ source.fetchChapterList(manga)
|
else /* SY <-- */ source.fetchChapterList(manga)
|
||||||
@ -469,12 +454,16 @@ class LibraryUpdateService(
|
|||||||
// SY -->
|
// SY -->
|
||||||
)
|
)
|
||||||
.doOnNext {
|
.doOnNext {
|
||||||
if (source.getMainSource() is MangaDex) {
|
if (source is MangaDex && trackManager.mdList.isLogged) {
|
||||||
val tracks = db.getTracks(manga).executeAsBlocking()
|
try {
|
||||||
if (tracks.isEmpty() || tracks.all { it.sync_id != TrackManager.MDLIST }) {
|
val tracks = db.getTracks(manga).executeAsBlocking()
|
||||||
var track = trackManager.mdList.createInitialTracker(manga)
|
if (tracks.isEmpty() || tracks.all { it.sync_id != TrackManager.MDLIST }) {
|
||||||
track = runBlocking { trackManager.mdList.refresh(track).awaitSingle() }
|
var track = trackManager.mdList.createInitialTracker(manga)
|
||||||
db.insertTrack(track).executeAsBlocking()
|
track = runBlocking { trackManager.mdList.refresh(track).awaitSingle() }
|
||||||
|
db.insertTrack(track).executeAsBlocking()
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
XLog.e(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -548,7 +537,7 @@ class LibraryUpdateService(
|
|||||||
// filter all follows from Mangadex and only add reading or rereading manga to library
|
// filter all follows from Mangadex and only add reading or rereading manga to library
|
||||||
private fun syncFollows(): Observable<LibraryManga> {
|
private fun syncFollows(): Observable<LibraryManga> {
|
||||||
val count = AtomicInteger(0)
|
val count = AtomicInteger(0)
|
||||||
val mangaDex = MdUtil.getEnabledMangaDex(preferences, sourceManager)!!
|
val mangaDex = MdUtil.getEnabledMangaDex(preferences, sourceManager) ?: return Observable.empty()
|
||||||
return mangaDex.fetchAllFollows(true)
|
return mangaDex.fetchAllFollows(true)
|
||||||
.asObservable()
|
.asObservable()
|
||||||
.map { listManga ->
|
.map { listManga ->
|
||||||
@ -582,7 +571,7 @@ class LibraryUpdateService(
|
|||||||
.doOnCompleted {
|
.doOnCompleted {
|
||||||
notifier.cancelProgressNotification()
|
notifier.cancelProgressNotification()
|
||||||
}
|
}
|
||||||
.map { LibraryManga() }
|
.flatMap { Observable.empty() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -616,7 +605,7 @@ class LibraryUpdateService(
|
|||||||
.doOnCompleted {
|
.doOnCompleted {
|
||||||
notifier.cancelProgressNotification()
|
notifier.cancelProgressNotification()
|
||||||
}
|
}
|
||||||
.map { LibraryManga() }
|
.flatMap { Observable.empty() }
|
||||||
}
|
}
|
||||||
// SY <--
|
// SY <--
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ import exh.eh.EHTags
|
|||||||
import exh.eh.EHentaiUpdateHelper
|
import exh.eh.EHentaiUpdateHelper
|
||||||
import exh.eh.EHentaiUpdateWorkerConstants
|
import exh.eh.EHentaiUpdateWorkerConstants
|
||||||
import exh.eh.GalleryEntry
|
import exh.eh.GalleryEntry
|
||||||
import exh.metadata.EX_DATE_FORMAT
|
import exh.metadata.MetadataUtil
|
||||||
import exh.metadata.metadata.EHentaiSearchMetadata
|
import exh.metadata.metadata.EHentaiSearchMetadata
|
||||||
import exh.metadata.metadata.EHentaiSearchMetadata.Companion.EH_GENRE_NAMESPACE
|
import exh.metadata.metadata.EHentaiSearchMetadata.Companion.EH_GENRE_NAMESPACE
|
||||||
import exh.metadata.metadata.EHentaiSearchMetadata.Companion.TAG_TYPE_LIGHT
|
import exh.metadata.metadata.EHentaiSearchMetadata.Companion.TAG_TYPE_LIGHT
|
||||||
@ -35,7 +35,6 @@ import exh.metadata.metadata.EHentaiSearchMetadata.Companion.TAG_TYPE_WEAK
|
|||||||
import exh.metadata.metadata.base.RaisedSearchMetadata.Companion.TAG_TYPE_VIRTUAL
|
import exh.metadata.metadata.base.RaisedSearchMetadata.Companion.TAG_TYPE_VIRTUAL
|
||||||
import exh.metadata.metadata.base.RaisedSearchMetadata.Companion.toGenreString
|
import exh.metadata.metadata.base.RaisedSearchMetadata.Companion.toGenreString
|
||||||
import exh.metadata.metadata.base.RaisedTag
|
import exh.metadata.metadata.base.RaisedTag
|
||||||
import exh.metadata.parseHumanReadableByteCount
|
|
||||||
import exh.ui.login.LoginController
|
import exh.ui.login.LoginController
|
||||||
import exh.ui.metadata.adapters.EHentaiDescriptionAdapter
|
import exh.ui.metadata.adapters.EHentaiDescriptionAdapter
|
||||||
import exh.util.UriFilter
|
import exh.util.UriFilter
|
||||||
@ -239,7 +238,7 @@ class EHentai(
|
|||||||
private fun getDateTag(element: Element?): Long? {
|
private fun getDateTag(element: Element?): Long? {
|
||||||
val text = element?.text()?.nullIfBlank()
|
val text = element?.text()?.nullIfBlank()
|
||||||
return if (text != null) {
|
return if (text != null) {
|
||||||
val date = EX_DATE_FORMAT.parse(text)
|
val date = MetadataUtil.EX_DATE_FORMAT.parse(text)
|
||||||
date?.time
|
date?.time
|
||||||
} else null
|
} else null
|
||||||
}
|
}
|
||||||
@ -272,8 +271,8 @@ class EHentai(
|
|||||||
/**
|
/**
|
||||||
* Parse a list of galleries
|
* Parse a list of galleries
|
||||||
*/
|
*/
|
||||||
fun genericMangaParse(response: Response) = extendedGenericMangaParse(response.asJsoup()).let {
|
private fun genericMangaParse(response: Response) = extendedGenericMangaParse(response.asJsoup()).let { mangaFromSource ->
|
||||||
MetadataMangasPage(it.first.map { it.manga }, it.second, it.first.map { it.metadata })
|
MetadataMangasPage(mangaFromSource.first.map { it.manga }, mangaFromSource.second, mangaFromSource.first.map { it.metadata })
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun fetchChapterList(manga: SManga) = fetchChapterList(manga) {}
|
override fun fetchChapterList(manga: SManga) = fetchChapterList(manga) {}
|
||||||
@ -331,7 +330,7 @@ class EHentai(
|
|||||||
url = EHentaiSearchMetadata.normalizeUrl(d.location())
|
url = EHentaiSearchMetadata.normalizeUrl(d.location())
|
||||||
name = "v1: " + d.selectFirst("#gn").text()
|
name = "v1: " + d.selectFirst("#gn").text()
|
||||||
chapter_number = 1f
|
chapter_number = 1f
|
||||||
date_upload = EX_DATE_FORMAT.parse(
|
date_upload = MetadataUtil.EX_DATE_FORMAT.parse(
|
||||||
d.select("#gdd .gdt1").find { el ->
|
d.select("#gdd .gdt1").find { el ->
|
||||||
el.text().toLowerCase() == "posted:"
|
el.text().toLowerCase() == "posted:"
|
||||||
}!!.nextElementSibling().text()
|
}!!.nextElementSibling().text()
|
||||||
@ -348,7 +347,7 @@ class EHentai(
|
|||||||
this.url = EHentaiSearchMetadata.normalizeUrl(link)
|
this.url = EHentaiSearchMetadata.normalizeUrl(link)
|
||||||
this.name = "v${index + 2}: $name"
|
this.name = "v${index + 2}: $name"
|
||||||
this.chapter_number = index + 2f
|
this.chapter_number = index + 2f
|
||||||
this.date_upload = EX_DATE_FORMAT.parse(posted)!!.time
|
this.date_upload = MetadataUtil.EX_DATE_FORMAT.parse(posted)!!.time
|
||||||
}
|
}
|
||||||
}.reversed() + self
|
}.reversed() + self
|
||||||
}
|
}
|
||||||
@ -455,7 +454,7 @@ class EHentai(
|
|||||||
private fun exGet(url: String, page: Int? = null, additionalHeaders: Headers? = null, cache: Boolean = true): Request {
|
private fun exGet(url: String, page: Int? = null, additionalHeaders: Headers? = null, cache: Boolean = true): Request {
|
||||||
return GET(
|
return GET(
|
||||||
page?.let {
|
page?.let {
|
||||||
addParam(url, "page", Integer.toString(page - 1))
|
addParam(url, "page", (page - 1).toString())
|
||||||
} ?: url,
|
} ?: url,
|
||||||
additionalHeaders?.let { additionalHeadersNotNull ->
|
additionalHeaders?.let { additionalHeadersNotNull ->
|
||||||
val headers = headers.newBuilder()
|
val headers = headers.newBuilder()
|
||||||
@ -524,39 +523,35 @@ class EHentai(
|
|||||||
override fun parseIntoMetadata(metadata: EHentaiSearchMetadata, input: Document) {
|
override fun parseIntoMetadata(metadata: EHentaiSearchMetadata, input: Document) {
|
||||||
with(metadata) {
|
with(metadata) {
|
||||||
with(input) {
|
with(input) {
|
||||||
val url = input.location()
|
val url = location()
|
||||||
gId = EHentaiSearchMetadata.galleryId(url)
|
gId = EHentaiSearchMetadata.galleryId(url)
|
||||||
gToken = EHentaiSearchMetadata.galleryToken(url)
|
gToken = EHentaiSearchMetadata.galleryToken(url)
|
||||||
|
|
||||||
exh = this@EHentai.exh
|
exh = this@EHentai.exh
|
||||||
title = select("#gn").text().nullIfBlank()?.trim()
|
title = select("#gn").text().trimOrNull()
|
||||||
|
|
||||||
altTitle = select("#gj").text().nullIfBlank()?.trim()
|
altTitle = select("#gj").text().trimOrNull()
|
||||||
|
|
||||||
thumbnailUrl = select("#gd1 div").attr("style").nullIfBlank()?.let {
|
thumbnailUrl = select("#gd1 div").attr("style").nullIfBlank()?.let {
|
||||||
it.substring(it.indexOf('(') + 1 until it.lastIndexOf(')'))
|
it.substring(it.indexOf('(') + 1 until it.lastIndexOf(')'))
|
||||||
}
|
}
|
||||||
genre = select(".cs")
|
genre = select(".cs")
|
||||||
.attr("onclick")
|
.attr("onclick")
|
||||||
.nullIfBlank()
|
.trimOrNull()
|
||||||
?.trim()
|
|
||||||
?.substringAfterLast('/')
|
?.substringAfterLast('/')
|
||||||
?.removeSuffix("'")
|
?.removeSuffix("'")
|
||||||
|
|
||||||
uploader = select("#gdn").text().nullIfBlank()?.trim()
|
uploader = select("#gdn").text().trimOrNull()
|
||||||
|
|
||||||
// Parse the table
|
// Parse the table
|
||||||
select("#gdd tr").forEach {
|
select("#gdd tr").forEach {
|
||||||
val left = it.select(".gdt1").text().nullIfBlank()?.trim()
|
val left = it.select(".gdt1").text().trimOrNull()
|
||||||
val rightElement = it.selectFirst(".gdt2")
|
val rightElement = it.selectFirst(".gdt2")
|
||||||
val right = rightElement.text().nullIfBlank()?.trim()
|
val right = rightElement.text().trimOrNull()
|
||||||
if (left != null && right != null) {
|
if (left != null && right != null) {
|
||||||
ignore {
|
ignore {
|
||||||
when (
|
when (left.removeSuffix(":").toLowerCase()) {
|
||||||
left.removeSuffix(":")
|
"posted" -> datePosted = MetadataUtil.EX_DATE_FORMAT.parse(right)!!.time
|
||||||
.toLowerCase()
|
|
||||||
) {
|
|
||||||
"posted" -> datePosted = EX_DATE_FORMAT.parse(right)!!.time
|
|
||||||
// Example gallery with parent: https://e-hentai.org/g/1390451/7f181c2426/
|
// Example gallery with parent: https://e-hentai.org/g/1390451/7f181c2426/
|
||||||
// Example JP gallery: https://exhentai.org/g/1375385/03519d541b/
|
// Example JP gallery: https://exhentai.org/g/1375385/03519d541b/
|
||||||
// Parent is older variation of the gallery
|
// Parent is older variation of the gallery
|
||||||
@ -565,12 +560,12 @@ class EHentai(
|
|||||||
} else null
|
} else null
|
||||||
"visible" -> visible = right.nullIfBlank()
|
"visible" -> visible = right.nullIfBlank()
|
||||||
"language" -> {
|
"language" -> {
|
||||||
language = right.removeSuffix(TR_SUFFIX).trim().nullIfBlank()
|
language = right.removeSuffix(TR_SUFFIX).trimOrNull()
|
||||||
translated = right.endsWith(TR_SUFFIX, true)
|
translated = right.endsWith(TR_SUFFIX, true)
|
||||||
}
|
}
|
||||||
"file size" -> size = parseHumanReadableByteCount(right)?.toLong()
|
"file size" -> size = MetadataUtil.parseHumanReadableByteCount(right)?.toLong()
|
||||||
"length" -> length = right.removeSuffix("pages").trim().nullIfBlank()?.toInt()
|
"length" -> length = right.removeSuffix("pages").trimOrNull()?.toInt()
|
||||||
"favorited" -> favorites = right.removeSuffix("times").trim().nullIfBlank()?.toInt()
|
"favorited" -> favorites = right.removeSuffix("times").trimOrNull()?.toInt()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -589,13 +584,11 @@ class EHentai(
|
|||||||
averageRating = select("#rating_label")
|
averageRating = select("#rating_label")
|
||||||
.text()
|
.text()
|
||||||
.removePrefix("Average:")
|
.removePrefix("Average:")
|
||||||
.trim()
|
.trimOrNull()
|
||||||
.nullIfBlank()
|
|
||||||
?.toDouble()
|
?.toDouble()
|
||||||
ratingCount = select("#rating_count")
|
ratingCount = select("#rating_count")
|
||||||
.text()
|
.text()
|
||||||
.trim()
|
.trimOrNull()
|
||||||
.nullIfBlank()
|
|
||||||
?.toInt()
|
?.toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ class NHentai(delegate: HttpSource, val context: Context) :
|
|||||||
tags.clear()
|
tags.clear()
|
||||||
}.forEach {
|
}.forEach {
|
||||||
if (it.first != null && it.second != null) {
|
if (it.first != null && it.second != null) {
|
||||||
tags.add(RaisedTag(it.first!!, it.second!!, if (it.first == "category") RaisedSearchMetadata.TAG_TYPE_VIRTUAL else NHentaiSearchMetadata.TAG_TYPE_DEFAULT))
|
tags.add(RaisedTag(it.first!!, it.second!!, if (it.first == NHentaiSearchMetadata.NHENTAI_CATEGORIES_NAMESPACE) RaisedSearchMetadata.TAG_TYPE_VIRTUAL else NHentaiSearchMetadata.TAG_TYPE_DEFAULT))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ import eu.kanade.tachiyomi.widget.EmptyView
|
|||||||
import exh.isEhBasedSource
|
import exh.isEhBasedSource
|
||||||
import exh.md.similar.ui.EnableMangaDexSimilarDialogController
|
import exh.md.similar.ui.EnableMangaDexSimilarDialogController
|
||||||
import exh.savedsearches.EXHSavedSearch
|
import exh.savedsearches.EXHSavedSearch
|
||||||
import exh.source.EnhancedHttpSource.Companion.getMainSource
|
import exh.source.getMainSource
|
||||||
import kotlinx.android.synthetic.main.main_activity.root_coordinator
|
import kotlinx.android.synthetic.main.main_activity.root_coordinator
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.flow.drop
|
import kotlinx.coroutines.flow.drop
|
||||||
|
@ -12,11 +12,10 @@ import eu.kanade.tachiyomi.data.database.models.Manga
|
|||||||
import eu.kanade.tachiyomi.data.glide.GlideApp
|
import eu.kanade.tachiyomi.data.glide.GlideApp
|
||||||
import eu.kanade.tachiyomi.data.glide.toMangaThumbnail
|
import eu.kanade.tachiyomi.data.glide.toMangaThumbnail
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||||
import exh.metadata.EX_DATE_FORMAT
|
import exh.metadata.MetadataUtil
|
||||||
import exh.metadata.metadata.EHentaiSearchMetadata
|
import exh.metadata.metadata.EHentaiSearchMetadata
|
||||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||||
import exh.util.SourceTagsUtil
|
import exh.util.SourceTagsUtil
|
||||||
import exh.util.SourceTagsUtil.Companion.getLocaleSourceUtil
|
|
||||||
import kotlinx.android.synthetic.main.source_enhanced_ehentai_list_item.date_posted
|
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.genre
|
||||||
import kotlinx.android.synthetic.main.source_enhanced_ehentai_list_item.language
|
import kotlinx.android.synthetic.main.source_enhanced_ehentai_list_item.language
|
||||||
@ -82,11 +81,11 @@ class SourceEnhancedEHentaiListHolder(private val view: View, adapter: FlexibleA
|
|||||||
genre.text = view.context.getString(pair.second)
|
genre.text = view.context.getString(pair.second)
|
||||||
} else genre.text = metadata.genre
|
} else genre.text = metadata.genre
|
||||||
|
|
||||||
metadata.datePosted?.let { date_posted.text = EX_DATE_FORMAT.format(Date(it)) }
|
metadata.datePosted?.let { date_posted.text = MetadataUtil.EX_DATE_FORMAT.format(Date(it)) }
|
||||||
|
|
||||||
metadata.averageRating?.let { rating_bar.rating = it.toFloat() }
|
metadata.averageRating?.let { rating_bar.rating = it.toFloat() }
|
||||||
|
|
||||||
val locale = getLocaleSourceUtil(metadata.tags.firstOrNull { it.namespace == "language" }?.name)
|
val locale = SourceTagsUtil.getLocaleSourceUtil(metadata.tags.firstOrNull { it.namespace == "language" }?.name)
|
||||||
val pageCount = metadata.length
|
val pageCount = metadata.length
|
||||||
|
|
||||||
language.text = if (locale != null && pageCount != null) {
|
language.text = if (locale != null && pageCount != null) {
|
||||||
|
@ -19,7 +19,7 @@ import eu.kanade.tachiyomi.source.CatalogueSource
|
|||||||
import eu.kanade.tachiyomi.source.online.BrowseSourceFilterHeader
|
import eu.kanade.tachiyomi.source.online.BrowseSourceFilterHeader
|
||||||
import eu.kanade.tachiyomi.widget.SimpleNavigationView
|
import eu.kanade.tachiyomi.widget.SimpleNavigationView
|
||||||
import exh.savedsearches.EXHSavedSearch
|
import exh.savedsearches.EXHSavedSearch
|
||||||
import exh.source.EnhancedHttpSource.Companion.getMainSource
|
import exh.source.getMainSource
|
||||||
|
|
||||||
class SourceFilterSheet(
|
class SourceFilterSheet(
|
||||||
activity: Activity,
|
activity: Activity,
|
||||||
|
@ -21,10 +21,9 @@ import eu.kanade.tachiyomi.source.SourceManager
|
|||||||
import eu.kanade.tachiyomi.source.online.NamespaceSource
|
import eu.kanade.tachiyomi.source.online.NamespaceSource
|
||||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||||
import exh.metadata.metadata.base.RaisedTag
|
import exh.metadata.metadata.base.RaisedTag
|
||||||
import exh.source.EnhancedHttpSource.Companion.getMainSource
|
import exh.source.getMainSource
|
||||||
import exh.util.SourceTagsUtil.Companion.TAG_TYPE_EXCLUDE
|
import exh.util.SourceTagsUtil
|
||||||
import exh.util.SourceTagsUtil.Companion.getRaisedTags
|
import exh.util.getRaisedTags
|
||||||
import exh.util.SourceTagsUtil.Companion.parseTag
|
|
||||||
import kotlinx.android.synthetic.main.source_compact_grid_item.view.card
|
import kotlinx.android.synthetic.main.source_compact_grid_item.view.card
|
||||||
import kotlinx.android.synthetic.main.source_compact_grid_item.view.gradient
|
import kotlinx.android.synthetic.main.source_compact_grid_item.view.gradient
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
@ -160,14 +159,14 @@ class LibraryItem(val manga: LibraryManga, private val libraryDisplayMode: Prefe
|
|||||||
}
|
}
|
||||||
cleanConstraint.split(",").all {
|
cleanConstraint.split(",").all {
|
||||||
if (raisedTags == null) containsGenre(it.trim(), genres) else containsRaisedGenre(
|
if (raisedTags == null) containsGenre(it.trim(), genres) else containsRaisedGenre(
|
||||||
parseTag(it.trim()),
|
SourceTagsUtil.parseTag(it.trim()),
|
||||||
raisedTags
|
raisedTags
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else if (raisedTags == null) {
|
} else if (raisedTags == null) {
|
||||||
containsGenre(constraint, genres)
|
containsGenre(constraint, genres)
|
||||||
} else {
|
} else {
|
||||||
containsRaisedGenre(parseTag(constraint), raisedTags)
|
containsRaisedGenre(SourceTagsUtil.parseTag(constraint), raisedTags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +174,7 @@ class LibraryItem(val manga: LibraryManga, private val libraryDisplayMode: Prefe
|
|||||||
val genre = genres.find {
|
val genre = genres.find {
|
||||||
(it.namespace?.toLowerCase() == tag.namespace?.toLowerCase() && it.name.toLowerCase() == tag.name.toLowerCase())
|
(it.namespace?.toLowerCase() == tag.namespace?.toLowerCase() && it.name.toLowerCase() == tag.name.toLowerCase())
|
||||||
}
|
}
|
||||||
return if (tag.type == TAG_TYPE_EXCLUDE) {
|
return if (tag.type == SourceTagsUtil.TAG_TYPE_EXCLUDE) {
|
||||||
genre == null
|
genre == null
|
||||||
} else {
|
} else {
|
||||||
genre != null
|
genre != null
|
||||||
|
@ -103,7 +103,7 @@ import exh.isEhBasedSource
|
|||||||
import exh.md.similar.ui.MangaDexSimilarController
|
import exh.md.similar.ui.MangaDexSimilarController
|
||||||
import exh.metadata.metadata.base.FlatMetadata
|
import exh.metadata.metadata.base.FlatMetadata
|
||||||
import exh.recs.RecommendsController
|
import exh.recs.RecommendsController
|
||||||
import exh.source.EnhancedHttpSource.Companion.getMainSource
|
import exh.source.getMainSource
|
||||||
import kotlinx.android.synthetic.main.main_activity.root_coordinator
|
import kotlinx.android.synthetic.main.main_activity.root_coordinator
|
||||||
import kotlinx.android.synthetic.main.main_activity.toolbar
|
import kotlinx.android.synthetic.main.main_activity.toolbar
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
|
@ -50,7 +50,7 @@ import exh.metadata.metadata.base.FlatMetadata
|
|||||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||||
import exh.metadata.metadata.base.getFlatMetadataForManga
|
import exh.metadata.metadata.base.getFlatMetadataForManga
|
||||||
import exh.metadata.metadata.base.insertFlatMetadata
|
import exh.metadata.metadata.base.insertFlatMetadata
|
||||||
import exh.source.EnhancedHttpSource.Companion.getMainSource
|
import exh.source.getMainSource
|
||||||
import exh.util.asObservable
|
import exh.util.asObservable
|
||||||
import exh.util.await
|
import exh.util.await
|
||||||
import exh.util.shouldDeleteChapters
|
import exh.util.shouldDeleteChapters
|
||||||
|
@ -11,7 +11,7 @@ import eu.kanade.tachiyomi.data.download.model.Download
|
|||||||
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
|
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
|
||||||
import exh.EH_SOURCE_ID
|
import exh.EH_SOURCE_ID
|
||||||
import exh.EXH_SOURCE_ID
|
import exh.EXH_SOURCE_ID
|
||||||
import exh.metadata.EX_DATE_FORMAT
|
import exh.metadata.MetadataUtil
|
||||||
import kotlinx.android.synthetic.main.chapters_item.bookmark_icon
|
import kotlinx.android.synthetic.main.chapters_item.bookmark_icon
|
||||||
import kotlinx.android.synthetic.main.chapters_item.chapter_description
|
import kotlinx.android.synthetic.main.chapters_item.chapter_description
|
||||||
import kotlinx.android.synthetic.main.chapters_item.chapter_title
|
import kotlinx.android.synthetic.main.chapters_item.chapter_title
|
||||||
@ -56,7 +56,7 @@ class ChapterHolder(
|
|||||||
if (chapter.date_upload > 0) {
|
if (chapter.date_upload > 0) {
|
||||||
// SY -->
|
// SY -->
|
||||||
if (manga.source == EH_SOURCE_ID || manga.source == EXH_SOURCE_ID) {
|
if (manga.source == EH_SOURCE_ID || manga.source == EXH_SOURCE_ID) {
|
||||||
descriptions.add(EX_DATE_FORMAT.format(Date(chapter.date_upload)))
|
descriptions.add(MetadataUtil.EX_DATE_FORMAT.format(Date(chapter.date_upload)))
|
||||||
} else /* SY <-- */ descriptions.add(adapter.dateFormat.format(Date(chapter.date_upload)))
|
} else /* SY <-- */ descriptions.add(adapter.dateFormat.format(Date(chapter.date_upload)))
|
||||||
}
|
}
|
||||||
if ((!chapter.read || (adapter.preserveReadingPosition && (manga.source == EH_SOURCE_ID || manga.source == EXH_SOURCE_ID))) && chapter.last_page_read > 0) {
|
if ((!chapter.read || (adapter.preserveReadingPosition && (manga.source == EH_SOURCE_ID || manga.source == EXH_SOURCE_ID))) && chapter.last_page_read > 0) {
|
||||||
|
@ -18,7 +18,7 @@ import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Stat
|
|||||||
import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog
|
import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog
|
||||||
import exh.md.utils.MdUtil
|
import exh.md.utils.MdUtil
|
||||||
import exh.metadata.metadata.MangaDexSearchMetadata
|
import exh.metadata.metadata.MangaDexSearchMetadata
|
||||||
import exh.source.EnhancedHttpSource.Companion.getMainSource
|
import exh.source.getMainSource
|
||||||
|
|
||||||
class ChaptersSettingsSheet(
|
class ChaptersSettingsSheet(
|
||||||
private val router: Router,
|
private val router: Router,
|
||||||
|
@ -22,7 +22,7 @@ import eu.kanade.tachiyomi.source.online.all.MangaDex
|
|||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||||
import exh.MERGED_SOURCE_ID
|
import exh.MERGED_SOURCE_ID
|
||||||
import exh.source.EnhancedHttpSource.Companion.getMainSource
|
import exh.source.getMainSource
|
||||||
import exh.util.SourceTagsUtil
|
import exh.util.SourceTagsUtil
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -107,7 +107,7 @@ class MangaInfoHeaderAdapter(
|
|||||||
|
|
||||||
with(binding.btnTracking) {
|
with(binding.btnTracking) {
|
||||||
// SY -->
|
// SY -->
|
||||||
val sourceIsMangaDex = source.let { it.getMainSource() is MangaDex }
|
val sourceIsMangaDex = source.getMainSource() is MangaDex
|
||||||
// SY <--
|
// SY <--
|
||||||
if (trackManager.hasLoggedServices(/* SY --> */sourceIsMangaDex/* SY <-- */)) {
|
if (trackManager.hasLoggedServices(/* SY --> */sourceIsMangaDex/* SY <-- */)) {
|
||||||
isVisible = true
|
isVisible = true
|
||||||
@ -169,7 +169,7 @@ class MangaInfoHeaderAdapter(
|
|||||||
val author = binding.mangaAuthor.text.toString()
|
val author = binding.mangaAuthor.text.toString()
|
||||||
controller.activity?.copyToClipboard(
|
controller.activity?.copyToClipboard(
|
||||||
author,
|
author,
|
||||||
SourceTagsUtil().getWrappedTag(source.id, namespace = "artist", tag = author) ?: author
|
SourceTagsUtil.getWrappedTag(source.id, namespace = "artist", tag = author) ?: author
|
||||||
)
|
)
|
||||||
// SY <--
|
// SY <--
|
||||||
}
|
}
|
||||||
@ -179,7 +179,7 @@ class MangaInfoHeaderAdapter(
|
|||||||
.onEach {
|
.onEach {
|
||||||
// SY -->
|
// SY -->
|
||||||
val author = binding.mangaAuthor.text.toString()
|
val author = binding.mangaAuthor.text.toString()
|
||||||
controller.performGlobalSearch(SourceTagsUtil().getWrappedTag(source.id, namespace = "artist", tag = author) ?: author)
|
controller.performGlobalSearch(SourceTagsUtil.getWrappedTag(source.id, namespace = "artist", tag = author) ?: author)
|
||||||
// SY <--
|
// SY <--
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(scope)
|
||||||
@ -190,7 +190,7 @@ class MangaInfoHeaderAdapter(
|
|||||||
val artist = binding.mangaArtist.text.toString()
|
val artist = binding.mangaArtist.text.toString()
|
||||||
controller.activity?.copyToClipboard(
|
controller.activity?.copyToClipboard(
|
||||||
artist,
|
artist,
|
||||||
SourceTagsUtil().getWrappedTag(source.id, namespace = "artist", tag = artist) ?: artist
|
SourceTagsUtil.getWrappedTag(source.id, namespace = "artist", tag = artist) ?: artist
|
||||||
)
|
)
|
||||||
// SY <--
|
// SY <--
|
||||||
}
|
}
|
||||||
@ -200,7 +200,7 @@ class MangaInfoHeaderAdapter(
|
|||||||
.onEach {
|
.onEach {
|
||||||
// SY -->
|
// SY -->
|
||||||
val artist = binding.mangaArtist.text.toString()
|
val artist = binding.mangaArtist.text.toString()
|
||||||
controller.performGlobalSearch(SourceTagsUtil().getWrappedTag(source.id, namespace = "artist", tag = artist) ?: artist)
|
controller.performGlobalSearch(SourceTagsUtil.getWrappedTag(source.id, namespace = "artist", tag = artist) ?: artist)
|
||||||
// SY <--
|
// SY <--
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(scope)
|
||||||
|
@ -20,8 +20,8 @@ import eu.kanade.tachiyomi.util.system.copyToClipboard
|
|||||||
import exh.isEhBasedSource
|
import exh.isEhBasedSource
|
||||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||||
import exh.metadata.metadata.base.RaisedSearchMetadata.Companion.TAG_TYPE_VIRTUAL
|
import exh.metadata.metadata.base.RaisedSearchMetadata.Companion.TAG_TYPE_VIRTUAL
|
||||||
import exh.source.EnhancedHttpSource.Companion.getMainSource
|
import exh.source.getMainSource
|
||||||
import exh.util.SourceTagsUtil.Companion.getRaisedTags
|
import exh.util.getRaisedTags
|
||||||
import exh.util.makeSearchChip
|
import exh.util.makeSearchChip
|
||||||
import exh.util.setChipsExtended
|
import exh.util.setChipsExtended
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
@ -40,7 +40,7 @@ import exh.md.utils.MdUtil
|
|||||||
import exh.md.utils.scanlatorList
|
import exh.md.utils.scanlatorList
|
||||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||||
import exh.metadata.metadata.base.getFlatMetadataForManga
|
import exh.metadata.metadata.base.getFlatMetadataForManga
|
||||||
import exh.source.EnhancedHttpSource.Companion.getMainSource
|
import exh.source.getMainSource
|
||||||
import exh.util.awaitSingleOrNull
|
import exh.util.awaitSingleOrNull
|
||||||
import exh.util.defaultReaderType
|
import exh.util.defaultReaderType
|
||||||
import exh.util.shouldDeleteChapters
|
import exh.util.shouldDeleteChapters
|
||||||
|
@ -34,12 +34,12 @@ class SettingsMangaDexController :
|
|||||||
|
|
||||||
override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply {
|
override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply {
|
||||||
titleRes = R.string.mangadex_specific_settings
|
titleRes = R.string.mangadex_specific_settings
|
||||||
if (mdex == null) return@apply
|
val mdex = mdex ?: return@apply
|
||||||
val sourcePreference = MangaDexLoginPreference(context, mdex!!).apply {
|
val sourcePreference = MangaDexLoginPreference(context, mdex).apply {
|
||||||
title = mdex!!.name + " Login"
|
title = mdex.name + " Login"
|
||||||
key = getSourceKey(source.id)
|
key = getSourceKey(source.id)
|
||||||
setOnLoginClickListener {
|
setOnLoginClickListener {
|
||||||
if (mdex!!.isLogged()) {
|
if (mdex.isLogged()) {
|
||||||
val dialog = MangadexLogoutDialog(source)
|
val dialog = MangadexLogoutDialog(source)
|
||||||
dialog.targetController = this@SettingsMangaDexController
|
dialog.targetController = this@SettingsMangaDexController
|
||||||
dialog.showDialog(router)
|
dialog.showDialog(router)
|
||||||
|
@ -10,7 +10,7 @@ import eu.kanade.tachiyomi.source.SourceManager
|
|||||||
import eu.kanade.tachiyomi.source.online.UrlImportableSource
|
import eu.kanade.tachiyomi.source.online.UrlImportableSource
|
||||||
import eu.kanade.tachiyomi.source.online.all.EHentai
|
import eu.kanade.tachiyomi.source.online.all.EHentai
|
||||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||||
import exh.source.EnhancedHttpSource.Companion.getMainSource
|
import exh.source.getMainSource
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
|||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.source.SourceManager.Companion.currentDelegatedSources
|
|
||||||
import exh.EH_SOURCE_ID
|
import exh.EH_SOURCE_ID
|
||||||
import exh.EXHMigrations
|
import exh.EXHMigrations
|
||||||
import exh.EXH_SOURCE_ID
|
import exh.EXH_SOURCE_ID
|
||||||
@ -69,7 +68,7 @@ object DebugFunctions {
|
|||||||
}
|
}
|
||||||
private val throttleManager = EHentaiThrottleManager()
|
private val throttleManager = EHentaiThrottleManager()
|
||||||
|
|
||||||
fun getDelegatedSourceList(): String = currentDelegatedSources.map { it.value.sourceName + " : " + it.value.sourceId + " : " + it.value.factory }.joinToString(separator = "\n")
|
fun getDelegatedSourceList(): String = SourceManager.currentDelegatedSources.map { it.value.sourceName + " : " + it.value.sourceId + " : " + it.value.factory }.joinToString(separator = "\n")
|
||||||
|
|
||||||
fun resetEHGalleriesForUpdater() {
|
fun resetEHGalleriesForUpdater() {
|
||||||
throttleManager.resetThrottle()
|
throttleManager.resetThrottle()
|
||||||
|
@ -4,7 +4,7 @@ import eu.kanade.tachiyomi.source.model.FilterList
|
|||||||
import eu.kanade.tachiyomi.source.online.all.MangaDex
|
import eu.kanade.tachiyomi.source.online.all.MangaDex
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourcePresenter
|
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourcePresenter
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.browse.Pager
|
import eu.kanade.tachiyomi.ui.browse.source.browse.Pager
|
||||||
import exh.source.EnhancedHttpSource.Companion.getMainSource
|
import exh.source.getMainSource
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Presenter of [MangaDexFollowsController]. Inherit BrowseCataloguePresenter.
|
* Presenter of [MangaDexFollowsController]. Inherit BrowseCataloguePresenter.
|
||||||
|
@ -15,6 +15,7 @@ import exh.metadata.metadata.base.RaisedTag
|
|||||||
import exh.metadata.metadata.base.getFlatMetadataForManga
|
import exh.metadata.metadata.base.getFlatMetadataForManga
|
||||||
import exh.metadata.metadata.base.insertFlatMetadata
|
import exh.metadata.metadata.base.insertFlatMetadata
|
||||||
import exh.util.floor
|
import exh.util.floor
|
||||||
|
import exh.util.nullIfZero
|
||||||
import kotlinx.serialization.decodeFromString
|
import kotlinx.serialization.decodeFromString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonObject
|
import kotlinx.serialization.json.JsonObject
|
||||||
@ -126,7 +127,7 @@ class ApiMangaParser(private val langs: List<String>) {
|
|||||||
genres.add("Hentai")
|
genres.add("Hentai")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tags.size != 0) tags.clear()
|
if (tags.isNotEmpty()) tags.clear()
|
||||||
tags += genres.map { RaisedTag(null, it, MangaDexSearchMetadata.TAG_TYPE_DEFAULT) }
|
tags += genres.map { RaisedTag(null, it, MangaDexSearchMetadata.TAG_TYPE_DEFAULT) }
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
XLog.e(e)
|
XLog.e(e)
|
||||||
@ -157,10 +158,8 @@ class ApiMangaParser(private val langs: List<String>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val removeOneshots = filteredChapters.asSequence()
|
val removeOneshots = filteredChapters.asSequence()
|
||||||
.map { it.value.chapter!!.toDoubleOrNull() }
|
.map { it.value.chapter?.toDoubleOrNull()?.floor()?.nullIfZero() }
|
||||||
.filter { it != null }
|
.filterNotNull()
|
||||||
.map { it!!.floor() }
|
|
||||||
.filter { it != 0 }
|
|
||||||
.toList().distinctBy { it }
|
.toList().distinctBy { it }
|
||||||
return removeOneshots.toList().size == finalChapterNumber.toDouble().floor()
|
return removeOneshots.toList().size == finalChapterNumber.toDouble().floor()
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import eu.kanade.tachiyomi.data.track.TrackManager
|
|||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.POST
|
import eu.kanade.tachiyomi.network.POST
|
||||||
import eu.kanade.tachiyomi.network.asObservable
|
import eu.kanade.tachiyomi.network.asObservable
|
||||||
|
import eu.kanade.tachiyomi.network.await
|
||||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||||
import eu.kanade.tachiyomi.source.model.MetadataMangasPage
|
import eu.kanade.tachiyomi.source.model.MetadataMangasPage
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
@ -14,8 +15,6 @@ import exh.md.handlers.serializers.FollowsPageResult
|
|||||||
import exh.md.handlers.serializers.Result
|
import exh.md.handlers.serializers.Result
|
||||||
import exh.md.utils.FollowStatus
|
import exh.md.utils.FollowStatus
|
||||||
import exh.md.utils.MdUtil
|
import exh.md.utils.MdUtil
|
||||||
import exh.md.utils.MdUtil.Companion.baseUrl
|
|
||||||
import exh.md.utils.MdUtil.Companion.getMangaId
|
|
||||||
import exh.metadata.metadata.MangaDexSearchMetadata
|
import exh.metadata.metadata.MangaDexSearchMetadata
|
||||||
import exh.util.floor
|
import exh.util.floor
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -101,7 +100,7 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere
|
|||||||
if (result[0].chapter.isNotBlank()) {
|
if (result[0].chapter.isNotBlank()) {
|
||||||
track.last_chapter_read = follow.chapter.toFloat().floor()
|
track.last_chapter_read = follow.chapter.toFloat().floor()
|
||||||
}
|
}
|
||||||
track.tracking_url = baseUrl + follow.manga_id.toString()
|
track.tracking_url = MdUtil.baseUrl + follow.manga_id.toString()
|
||||||
track.title = follow.title
|
track.title = follow.title
|
||||||
}
|
}
|
||||||
return track
|
return track
|
||||||
@ -111,7 +110,7 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private fun followsListRequest(): Request {
|
private fun followsListRequest(): Request {
|
||||||
return GET("$baseUrl${MdUtil.followsAllApi}", headers, CacheControl.FORCE_NETWORK)
|
return GET("${MdUtil.baseUrl}${MdUtil.followsAllApi}", headers, CacheControl.FORCE_NETWORK)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,66 +138,66 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere
|
|||||||
if (followStatus == FollowStatus.UNFOLLOWED) {
|
if (followStatus == FollowStatus.UNFOLLOWED) {
|
||||||
client.newCall(
|
client.newCall(
|
||||||
GET(
|
GET(
|
||||||
"$baseUrl/ajax/actions.ajax.php?function=manga_unfollow&id=$mangaID&type=$mangaID",
|
"${MdUtil.baseUrl}/ajax/actions.ajax.php?function=manga_unfollow&id=$mangaID&type=$mangaID",
|
||||||
headers,
|
headers,
|
||||||
CacheControl.FORCE_NETWORK
|
CacheControl.FORCE_NETWORK
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.execute()
|
.await()
|
||||||
} else {
|
} else {
|
||||||
val status = followStatus.int
|
val status = followStatus.int
|
||||||
client.newCall(
|
client.newCall(
|
||||||
GET(
|
GET(
|
||||||
"$baseUrl/ajax/actions.ajax.php?function=manga_follow&id=$mangaID&type=$status",
|
"${MdUtil.baseUrl}/ajax/actions.ajax.php?function=manga_follow&id=$mangaID&type=$status",
|
||||||
headers,
|
headers,
|
||||||
CacheControl.FORCE_NETWORK
|
CacheControl.FORCE_NETWORK
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.execute()
|
.await()
|
||||||
}
|
}
|
||||||
|
|
||||||
response.body!!.string().isEmpty()
|
withContext(Dispatchers.IO) { response.body!!.string().isEmpty() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun updateReadingProgress(track: Track): Boolean {
|
suspend fun updateReadingProgress(track: Track): Boolean {
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
val mangaID = getMangaId(track.tracking_url)
|
val mangaID = MdUtil.getMangaId(track.tracking_url)
|
||||||
val formBody = FormBody.Builder()
|
val formBody = FormBody.Builder()
|
||||||
.add("chapter", track.last_chapter_read.toString())
|
.add("chapter", track.last_chapter_read.toString())
|
||||||
XLog.d("chapter to update %s", track.last_chapter_read.toString())
|
XLog.d("chapter to update %s", track.last_chapter_read.toString())
|
||||||
val response = client.newCall(
|
val response = client.newCall(
|
||||||
POST(
|
POST(
|
||||||
"$baseUrl/ajax/actions.ajax.php?function=edit_progress&id=$mangaID",
|
"${MdUtil.baseUrl}/ajax/actions.ajax.php?function=edit_progress&id=$mangaID",
|
||||||
headers,
|
headers,
|
||||||
formBody.build()
|
formBody.build()
|
||||||
)
|
)
|
||||||
).execute()
|
).await()
|
||||||
|
|
||||||
val response2 = client.newCall(
|
client.newCall(
|
||||||
GET(
|
GET(
|
||||||
"$baseUrl/ajax/actions.ajax.php?function=manga_rating&id=$mangaID&rating=${track.score.toInt()}",
|
"${MdUtil.baseUrl}/ajax/actions.ajax.php?function=manga_rating&id=$mangaID&rating=${track.score.toInt()}",
|
||||||
headers
|
headers
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.execute()
|
.await()
|
||||||
|
|
||||||
response.body!!.string().isEmpty()
|
withContext(Dispatchers.IO) { response.body!!.string().isEmpty() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun updateRating(track: Track): Boolean {
|
suspend fun updateRating(track: Track): Boolean {
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
val mangaID = getMangaId(track.tracking_url)
|
val mangaID = MdUtil.getMangaId(track.tracking_url)
|
||||||
val response = client.newCall(
|
val response = client.newCall(
|
||||||
GET(
|
GET(
|
||||||
"$baseUrl/ajax/actions.ajax.php?function=manga_rating&id=$mangaID&rating=${track.score.toInt()}",
|
"${MdUtil.baseUrl}/ajax/actions.ajax.php?function=manga_rating&id=$mangaID&rating=${track.score.toInt()}",
|
||||||
headers
|
headers
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.execute()
|
.await()
|
||||||
|
|
||||||
response.body!!.string().isEmpty()
|
withContext(Dispatchers.IO) { response.body!!.string().isEmpty() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +207,7 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere
|
|||||||
suspend fun fetchAllFollows(forceHd: Boolean): List<Pair<SManga, MangaDexSearchMetadata>> {
|
suspend fun fetchAllFollows(forceHd: Boolean): List<Pair<SManga, MangaDexSearchMetadata>> {
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
val listManga = mutableListOf<Pair<SManga, MangaDexSearchMetadata>>()
|
val listManga = mutableListOf<Pair<SManga, MangaDexSearchMetadata>>()
|
||||||
val response = client.newCall(followsListRequest()).execute()
|
val response = client.newCall(followsListRequest()).await()
|
||||||
val mangasPage = followsParseMangaPage(response, forceHd)
|
val mangasPage = followsParseMangaPage(response, forceHd)
|
||||||
listManga.addAll(
|
listManga.addAll(
|
||||||
mangasPage.mangas.mapIndexed { index, sManga ->
|
mangasPage.mangas.mapIndexed { index, sManga ->
|
||||||
@ -222,11 +221,11 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere
|
|||||||
suspend fun fetchTrackingInfo(url: String): Track {
|
suspend fun fetchTrackingInfo(url: String): Track {
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
val request = GET(
|
val request = GET(
|
||||||
"$baseUrl${MdUtil.followsMangaApi}" + getMangaId(url),
|
"${MdUtil.baseUrl}${MdUtil.followsMangaApi}" + MdUtil.getMangaId(url),
|
||||||
headers,
|
headers,
|
||||||
CacheControl.FORCE_NETWORK
|
CacheControl.FORCE_NETWORK
|
||||||
)
|
)
|
||||||
val response = client.newCall(request).execute()
|
val response = client.newCall(request).await()
|
||||||
val track = followStatusParse(response)
|
val track = followStatusParse(response)
|
||||||
|
|
||||||
track
|
track
|
||||||
|
@ -22,10 +22,10 @@ class MangaHandler(val client: OkHttpClient, val headers: Headers, val langs: Li
|
|||||||
// TODO make use of this
|
// TODO make use of this
|
||||||
suspend fun fetchMangaAndChapterDetails(manga: SManga): Pair<SManga, List<SChapter>> {
|
suspend fun fetchMangaAndChapterDetails(manga: SManga): Pair<SManga, List<SChapter>> {
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
val response = client.newCall(apiRequest(manga)).execute()
|
val response = client.newCall(apiRequest(manga)).await()
|
||||||
val parser = ApiMangaParser(langs)
|
val parser = ApiMangaParser(langs)
|
||||||
|
|
||||||
val jsonData = response.body!!.string()
|
val jsonData = withContext(Dispatchers.IO) { response.body!!.string() }
|
||||||
if (response.code != 200) {
|
if (response.code != 200) {
|
||||||
XLog.e("error from MangaDex with response code ${response.code} \n body: \n$jsonData")
|
XLog.e("error from MangaDex with response code ${response.code} \n body: \n$jsonData")
|
||||||
throw Exception("Error from MangaDex Response code ${response.code} ")
|
throw Exception("Error from MangaDex Response code ${response.code} ")
|
||||||
@ -43,14 +43,14 @@ class MangaHandler(val client: OkHttpClient, val headers: Headers, val langs: Li
|
|||||||
suspend fun getMangaIdFromChapterId(urlChapterId: String): Int {
|
suspend fun getMangaIdFromChapterId(urlChapterId: String): Int {
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
val request = GET(MdUtil.baseUrl + MdUtil.apiChapter + urlChapterId + MdUtil.apiChapterSuffix, headers, CacheControl.FORCE_NETWORK)
|
val request = GET(MdUtil.baseUrl + MdUtil.apiChapter + urlChapterId + MdUtil.apiChapterSuffix, headers, CacheControl.FORCE_NETWORK)
|
||||||
val response = client.newCall(request).execute()
|
val response = client.newCall(request).await()
|
||||||
ApiMangaParser(langs).chapterParseForMangaId(response)
|
ApiMangaParser(langs).chapterParseForMangaId(response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun fetchMangaDetails(manga: SManga): SManga {
|
suspend fun fetchMangaDetails(manga: SManga): SManga {
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
val response = client.newCall(apiRequest(manga)).execute()
|
val response = client.newCall(apiRequest(manga)).await()
|
||||||
ApiMangaParser(langs).parseToManga(manga, response, forceLatestCovers).await()
|
ApiMangaParser(langs).parseToManga(manga, response, forceLatestCovers).await()
|
||||||
manga.apply {
|
manga.apply {
|
||||||
initialized = true
|
initialized = true
|
||||||
@ -82,7 +82,7 @@ class MangaHandler(val client: OkHttpClient, val headers: Headers, val langs: Li
|
|||||||
|
|
||||||
suspend fun fetchChapterList(manga: SManga): List<SChapter> {
|
suspend fun fetchChapterList(manga: SManga): List<SChapter> {
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
val response = client.newCall(apiRequest(manga)).execute()
|
val response = client.newCall(apiRequest(manga)).await()
|
||||||
ApiMangaParser(langs).chapterListParse(response)
|
ApiMangaParser(langs).chapterListParse(response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import eu.kanade.tachiyomi.source.model.FilterList
|
|||||||
import eu.kanade.tachiyomi.source.online.all.MangaDex
|
import eu.kanade.tachiyomi.source.online.all.MangaDex
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourcePresenter
|
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourcePresenter
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.browse.Pager
|
import eu.kanade.tachiyomi.ui.browse.source.browse.Pager
|
||||||
import exh.source.EnhancedHttpSource.Companion.getMainSource
|
import exh.source.getMainSource
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,7 +6,9 @@ import eu.kanade.tachiyomi.source.SourceManager
|
|||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.source.online.all.MangaDex
|
import eu.kanade.tachiyomi.source.online.all.MangaDex
|
||||||
|
import exh.source.getMainSource
|
||||||
import exh.util.floor
|
import exh.util.floor
|
||||||
|
import exh.util.nullIfZero
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import org.jsoup.parser.Parser
|
import org.jsoup.parser.Parser
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
@ -14,6 +16,7 @@ import uy.kohesive.injekt.api.get
|
|||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.net.URISyntaxException
|
import java.net.URISyntaxException
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
class MdUtil {
|
class MdUtil {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -201,8 +204,8 @@ class MdUtil {
|
|||||||
/*}*/
|
/*}*/
|
||||||
}.sortedByDescending { it.chapter_number }
|
}.sortedByDescending { it.chapter_number }
|
||||||
|
|
||||||
remove0ChaptersFromCount.firstOrNull()?.let {
|
remove0ChaptersFromCount.firstOrNull()?.let { chapter ->
|
||||||
val chpNumber = it.chapter_number.floor()
|
val chpNumber = chapter.chapter_number.floor()
|
||||||
val allChapters = (1..chpNumber).toMutableSet()
|
val allChapters = (1..chpNumber).toMutableSet()
|
||||||
|
|
||||||
remove0ChaptersFromCount.forEach {
|
remove0ChaptersFromCount.forEach {
|
||||||
@ -217,8 +220,9 @@ class MdUtil {
|
|||||||
|
|
||||||
fun getEnabledMangaDex(preferences: PreferencesHelper = Injekt.get(), sourceManager: SourceManager = Injekt.get()): MangaDex? {
|
fun getEnabledMangaDex(preferences: PreferencesHelper = Injekt.get(), sourceManager: SourceManager = Injekt.get()): MangaDex? {
|
||||||
return getEnabledMangaDexs(preferences, sourceManager).let { mangadexs ->
|
return getEnabledMangaDexs(preferences, sourceManager).let { mangadexs ->
|
||||||
val preferredMangaDexId = preferences.preferredMangaDexId().get().toLongOrNull()
|
preferences.preferredMangaDexId().get().toLongOrNull()?.nullIfZero()?.let { preferredMangaDexId ->
|
||||||
mangadexs.firstOrNull { preferredMangaDexId != null && preferredMangaDexId != 0L && it.id == preferredMangaDexId } ?: mangadexs.firstOrNull()
|
mangadexs.firstOrNull { it.id == preferredMangaDexId }
|
||||||
|
} ?: mangadexs.firstOrNull()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,10 +230,11 @@ class MdUtil {
|
|||||||
val languages = preferences.enabledLanguages().get()
|
val languages = preferences.enabledLanguages().get()
|
||||||
val disabledSourceIds = preferences.disabledSources().get()
|
val disabledSourceIds = preferences.disabledSources().get()
|
||||||
|
|
||||||
return sourceManager.getDelegatedCatalogueSources()
|
return sourceManager.getVisibleOnlineSources()
|
||||||
|
.map { it.getMainSource() }
|
||||||
|
.filterIsInstance<MangaDex>()
|
||||||
.filter { it.lang in languages }
|
.filter { it.lang in languages }
|
||||||
.filterNot { it.id.toString() in disabledSourceIds }
|
.filterNot { it.id.toString() in disabledSourceIds }
|
||||||
.filterIsInstance(MangaDex::class.java)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun mapMdIdToMangaUrl(id: Int) = "/manga/$id/"
|
fun mapMdIdToMangaUrl(id: Int) = "/manga/$id/"
|
||||||
|
@ -1,62 +1,118 @@
|
|||||||
package exh.metadata
|
package exh.metadata
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
|
import androidx.annotation.FloatRange
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||||
|
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||||
|
import exh.util.SourceTagsUtil
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import kotlin.math.ln
|
import kotlin.math.ln
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Metadata utils
|
* Metadata utils
|
||||||
*/
|
*/
|
||||||
fun humanReadableByteCount(bytes: Long, si: Boolean): String {
|
object MetadataUtil {
|
||||||
val unit = if (si) 1000 else 1024
|
fun humanReadableByteCount(bytes: Long, si: Boolean): String {
|
||||||
if (bytes < unit) return "$bytes B"
|
val unit = if (si) 1000 else 1024
|
||||||
val exp = (ln(bytes.toDouble()) / ln(unit.toDouble())).toInt()
|
if (bytes < unit) return "$bytes B"
|
||||||
val pre = (if (si) "kMGTPE" else "KMGTPE")[exp - 1] + if (si) "" else "i"
|
val exp = (ln(bytes.toDouble()) / ln(unit.toDouble())).toInt()
|
||||||
return String.format("%.1f %sB", bytes / unit.toDouble().pow(exp.toDouble()), pre)
|
val pre = (if (si) "kMGTPE" else "KMGTPE")[exp - 1] + if (si) "" else "i"
|
||||||
}
|
return String.format("%.1f %sB", bytes / unit.toDouble().pow(exp.toDouble()), pre)
|
||||||
|
|
||||||
private const val KB_FACTOR: Long = 1000
|
|
||||||
private const val KIB_FACTOR: Long = 1024
|
|
||||||
private const val MB_FACTOR = 1000 * KB_FACTOR
|
|
||||||
private const val MIB_FACTOR = 1024 * KIB_FACTOR
|
|
||||||
private const val GB_FACTOR = 1000 * MB_FACTOR
|
|
||||||
private const val GIB_FACTOR = 1024 * MIB_FACTOR
|
|
||||||
|
|
||||||
fun parseHumanReadableByteCount(arg0: String): Double? {
|
|
||||||
val spaceNdx = arg0.indexOf(" ")
|
|
||||||
val ret = java.lang.Double.parseDouble(arg0.substring(0, spaceNdx))
|
|
||||||
when (arg0.substring(spaceNdx + 1)) {
|
|
||||||
"GB" -> return ret * GB_FACTOR
|
|
||||||
"GiB" -> return ret * GIB_FACTOR
|
|
||||||
"MB" -> return ret * MB_FACTOR
|
|
||||||
"MiB" -> return ret * MIB_FACTOR
|
|
||||||
"KB" -> return ret * KB_FACTOR
|
|
||||||
"KiB" -> return ret * KIB_FACTOR
|
|
||||||
}
|
}
|
||||||
return null
|
|
||||||
|
private const val KB_FACTOR: Long = 1000
|
||||||
|
private const val KIB_FACTOR: Long = 1024
|
||||||
|
private const val MB_FACTOR = 1000 * KB_FACTOR
|
||||||
|
private const val MIB_FACTOR = 1024 * KIB_FACTOR
|
||||||
|
private const val GB_FACTOR = 1000 * MB_FACTOR
|
||||||
|
private const val GIB_FACTOR = 1024 * MIB_FACTOR
|
||||||
|
|
||||||
|
fun parseHumanReadableByteCount(arg0: String): Double? {
|
||||||
|
val spaceNdx = arg0.indexOf(" ")
|
||||||
|
val ret = java.lang.Double.parseDouble(arg0.substring(0, spaceNdx))
|
||||||
|
when (arg0.substring(spaceNdx + 1)) {
|
||||||
|
"GB" -> return ret * GB_FACTOR
|
||||||
|
"GiB" -> return ret * GIB_FACTOR
|
||||||
|
"MB" -> return ret * MB_FACTOR
|
||||||
|
"MiB" -> return ret * MIB_FACTOR
|
||||||
|
"KB" -> return ret * KB_FACTOR
|
||||||
|
"KiB" -> return ret * KIB_FACTOR
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
val ONGOING_SUFFIX = arrayOf(
|
||||||
|
"[ongoing]",
|
||||||
|
"(ongoing)",
|
||||||
|
"{ongoing}",
|
||||||
|
"<ongoing>",
|
||||||
|
"ongoing",
|
||||||
|
"[incomplete]",
|
||||||
|
"(incomplete)",
|
||||||
|
"{incomplete}",
|
||||||
|
"<incomplete>",
|
||||||
|
"incomplete",
|
||||||
|
"[wip]",
|
||||||
|
"(wip)",
|
||||||
|
"{wip}",
|
||||||
|
"<wip>",
|
||||||
|
"wip"
|
||||||
|
)
|
||||||
|
|
||||||
|
val EX_DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US)
|
||||||
|
|
||||||
|
fun getRatingString(context: Context, @FloatRange(from = 0.0, to = 10.0) rating: Float?) = when ((rating ?: 100F).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
|
||||||
|
}.let { context.getString(it) }
|
||||||
|
|
||||||
|
fun getGenreAndColour(context: Context, genre: String) = when (genre) {
|
||||||
|
"doujinshi", "Doujinshi" -> SourceTagsUtil.DOUJINSHI_COLOR to R.string.doujinshi
|
||||||
|
"manga", "Japanese Manga", "Manga" -> SourceTagsUtil.MANGA_COLOR to R.string.manga
|
||||||
|
"artistcg", "artist CG", "artist-cg", "Artist CG" -> SourceTagsUtil.ARTIST_CG_COLOR to R.string.artist_cg
|
||||||
|
"gamecg", "game CG", "game-cg", "Game CG" -> SourceTagsUtil.GAME_CG_COLOR to R.string.game_cg
|
||||||
|
"western" -> SourceTagsUtil.WESTERN_COLOR to R.string.western
|
||||||
|
"non-h", "non-H" -> SourceTagsUtil.NON_H_COLOR to R.string.non_h
|
||||||
|
"imageset", "image Set" -> SourceTagsUtil.IMAGE_SET_COLOR to R.string.image_set
|
||||||
|
"cosplay" -> SourceTagsUtil.COSPLAY_COLOR to R.string.cosplay
|
||||||
|
"asianporn", "asian Porn" -> SourceTagsUtil.ASIAN_PORN_COLOR to R.string.asian_porn
|
||||||
|
"misc" -> SourceTagsUtil.MISC_COLOR to R.string.misc
|
||||||
|
"Korean Manhwa" -> SourceTagsUtil.ARTIST_CG_COLOR to R.string.manhwa
|
||||||
|
"Chinese Manhua" -> SourceTagsUtil.GAME_CG_COLOR to R.string.manhua
|
||||||
|
"Comic" -> SourceTagsUtil.WESTERN_COLOR to R.string.comic
|
||||||
|
"artbook" -> SourceTagsUtil.IMAGE_SET_COLOR to R.string.artbook
|
||||||
|
"webtoon" -> SourceTagsUtil.NON_H_COLOR to R.string.webtoon
|
||||||
|
"Video" -> SourceTagsUtil.WESTERN_COLOR to R.string.video
|
||||||
|
else -> "" to 0
|
||||||
|
}.let { if (it.second == 0) null else Color.parseColor(it.first) to context.getString(it.second) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <K, V> Set<Map.Entry<K, V>>.forEach(action: (K, V) -> Unit) {
|
fun <K, V> Set<Map.Entry<K, V>>.forEach(action: (K, V) -> Unit) {
|
||||||
forEach { action(it.key, it.value) }
|
forEach { action(it.key, it.value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val ONGOING_SUFFIX = arrayOf(
|
fun TextView.bindDrawable(context: Context, @DrawableRes drawable: Int) {
|
||||||
"[ongoing]",
|
ContextCompat.getDrawable(context, drawable)?.apply {
|
||||||
"(ongoing)",
|
setTint(context.getResourceColor(R.attr.colorAccent))
|
||||||
"{ongoing}",
|
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
||||||
"<ongoing>",
|
setCompoundDrawables(this, null, null, null)
|
||||||
"ongoing",
|
}
|
||||||
"[incomplete]",
|
}
|
||||||
"(incomplete)",
|
|
||||||
"{incomplete}",
|
|
||||||
"<incomplete>",
|
|
||||||
"incomplete",
|
|
||||||
"[wip]",
|
|
||||||
"(wip)",
|
|
||||||
"{wip}",
|
|
||||||
"<wip>",
|
|
||||||
"wip"
|
|
||||||
)
|
|
||||||
|
|
||||||
val EX_DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US)
|
|
||||||
|
@ -5,9 +5,7 @@ import android.net.Uri
|
|||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import exh.metadata.EX_DATE_FORMAT
|
import exh.metadata.MetadataUtil
|
||||||
import exh.metadata.ONGOING_SUFFIX
|
|
||||||
import exh.metadata.humanReadableByteCount
|
|
||||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
@ -71,7 +69,7 @@ class EHentaiSearchMetadata : RaisedSearchMetadata() {
|
|||||||
// We default to completed
|
// We default to completed
|
||||||
manga.status = SManga.COMPLETED
|
manga.status = SManga.COMPLETED
|
||||||
title?.let { t ->
|
title?.let { t ->
|
||||||
ONGOING_SUFFIX.find {
|
MetadataUtil.ONGOING_SUFFIX.find {
|
||||||
t.endsWith(it, ignoreCase = true)
|
t.endsWith(it, ignoreCase = true)
|
||||||
}?.let {
|
}?.let {
|
||||||
manga.status = SManga.ONGOING
|
manga.status = SManga.ONGOING
|
||||||
@ -111,25 +109,26 @@ class EHentaiSearchMetadata : RaisedSearchMetadata() {
|
|||||||
|
|
||||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||||
val pairs = mutableListOf<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) }
|
gId?.let { pairs += context.getString(R.string.id) to 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)) }
|
gToken?.let { pairs += context.getString(R.string.token) to it }
|
||||||
thumbnailUrl?.let { pairs += Pair(context.getString(R.string.thumbnail_url), it) }
|
exh?.let { pairs += context.getString(R.string.is_exhentai_gallery) to context.getString(if (it) android.R.string.yes else android.R.string.no) }
|
||||||
title?.let { pairs += Pair(context.getString(R.string.title), it) }
|
thumbnailUrl?.let { pairs += context.getString(R.string.thumbnail_url) to it }
|
||||||
altTitle?.let { pairs += Pair(context.getString(R.string.alt_title), it) }
|
title?.let { pairs += context.getString(R.string.title) to it }
|
||||||
genre?.let { pairs += Pair(context.getString(R.string.genre), it) }
|
altTitle?.let { pairs += context.getString(R.string.alt_title) to it }
|
||||||
datePosted?.let { pairs += Pair(context.getString(R.string.date_posted), EX_DATE_FORMAT.format(Date(it))) }
|
genre?.let { pairs += context.getString(R.string.genre) to it }
|
||||||
parent?.let { pairs += Pair(context.getString(R.string.parent), it) }
|
datePosted?.let { pairs += context.getString(R.string.date_posted) to MetadataUtil.EX_DATE_FORMAT.format(Date(it)) }
|
||||||
visible?.let { pairs += Pair(context.getString(R.string.visible), it) }
|
parent?.let { pairs += context.getString(R.string.parent) to it }
|
||||||
language?.let { pairs += Pair(context.getString(R.string.language), it) }
|
visible?.let { pairs += context.getString(R.string.visible) to it }
|
||||||
translated?.let { pairs += Pair("Translated", context.getString(if (it) android.R.string.yes else android.R.string.no)) }
|
language?.let { pairs += context.getString(R.string.language) to it }
|
||||||
size?.let { pairs += Pair(context.getString(R.string.gallery_size), humanReadableByteCount(it, true)) }
|
translated?.let { pairs += "Translated" to context.getString(if (it) android.R.string.yes else android.R.string.no) }
|
||||||
length?.let { pairs += Pair(context.getString(R.string.page_count), it.toString()) }
|
size?.let { pairs += context.getString(R.string.gallery_size) to MetadataUtil.humanReadableByteCount(it, true) }
|
||||||
favorites?.let { pairs += Pair(context.getString(R.string.total_favorites), it.toString()) }
|
length?.let { pairs += context.getString(R.string.page_count) to it.toString() }
|
||||||
ratingCount?.let { pairs += Pair(context.getString(R.string.total_ratings), it.toString()) }
|
favorites?.let { pairs += context.getString(R.string.total_favorites) to it.toString() }
|
||||||
averageRating?.let { pairs += Pair(context.getString(R.string.average_rating), it.toString()) }
|
ratingCount?.let { pairs += context.getString(R.string.total_ratings) to it.toString() }
|
||||||
aged.let { pairs += Pair(context.getString(R.string.aged), context.getString(if (it) android.R.string.yes else android.R.string.no)) }
|
averageRating?.let { pairs += context.getString(R.string.average_rating) to it.toString() }
|
||||||
lastUpdateCheck.let { pairs += Pair(context.getString(R.string.last_update_check), EX_DATE_FORMAT.format(Date(it))) }
|
aged.let { pairs += context.getString(R.string.aged) to context.getString(if (it) android.R.string.yes else android.R.string.no) }
|
||||||
|
lastUpdateCheck.let { pairs += context.getString(R.string.last_update_check) to MetadataUtil.EX_DATE_FORMAT.format(Date(it)) }
|
||||||
|
|
||||||
return pairs
|
return pairs
|
||||||
}
|
}
|
||||||
|
@ -41,12 +41,12 @@ class EightMusesSearchMetadata : RaisedSearchMetadata() {
|
|||||||
|
|
||||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||||
val pairs = mutableListOf<Pair<String, String>>()
|
val pairs = mutableListOf<Pair<String, String>>()
|
||||||
title?.let { pairs += Pair(context.getString(R.string.title), it) }
|
title?.let { pairs += context.getString(R.string.title) to it }
|
||||||
val path = path.joinToString("/", prefix = "/")
|
val path = path.joinToString("/", prefix = "/")
|
||||||
if (path.isNotBlank()) {
|
if (path.isNotBlank()) {
|
||||||
pairs += Pair(context.getString(R.string.path), path)
|
pairs += context.getString(R.string.path) to path
|
||||||
}
|
}
|
||||||
thumbnailUrl?.let { pairs += Pair(context.getString(R.string.thumbnail_url), it) }
|
thumbnailUrl?.let { pairs += context.getString(R.string.thumbnail_url) to it }
|
||||||
return pairs
|
return pairs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ package exh.metadata.metadata
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import exh.metadata.metadata.EightMusesSearchMetadata.Companion.ARTIST_NAMESPACE
|
|
||||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@ -51,11 +50,11 @@ class HBrowseSearchMetadata : RaisedSearchMetadata() {
|
|||||||
|
|
||||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||||
val pairs = mutableListOf<Pair<String, String>>()
|
val pairs = mutableListOf<Pair<String, String>>()
|
||||||
hbId?.let { pairs += Pair(context.getString(R.string.id), it.toString()) }
|
hbId?.let { pairs += context.getString(R.string.id) to it.toString() }
|
||||||
hbUrl?.let { pairs += Pair(context.getString(R.string.url), it) }
|
hbUrl?.let { pairs += context.getString(R.string.url) to it }
|
||||||
thumbnail?.let { pairs += Pair(context.getString(R.string.thumbnail_url), it) }
|
thumbnail?.let { pairs += context.getString(R.string.thumbnail_url) to it }
|
||||||
title?.let { pairs += Pair(context.getString(R.string.title), it) }
|
title?.let { pairs += context.getString(R.string.title) to it }
|
||||||
length?.let { pairs += Pair(context.getString(R.string.page_count), it.toString()) }
|
length?.let { pairs += context.getString(R.string.page_count) to it.toString() }
|
||||||
return pairs
|
return pairs
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +64,7 @@ class HBrowseSearchMetadata : RaisedSearchMetadata() {
|
|||||||
private const val TITLE_TYPE_MAIN = 0
|
private const val TITLE_TYPE_MAIN = 0
|
||||||
|
|
||||||
const val TAG_TYPE_DEFAULT = 0
|
const val TAG_TYPE_DEFAULT = 0
|
||||||
|
const val ARTIST_NAMESPACE = "artist"
|
||||||
|
|
||||||
fun guessThumbnailUrl(hbid: String): String {
|
fun guessThumbnailUrl(hbid: String): String {
|
||||||
return "$BASE_URL/thumbnails/${hbid}_1.jpg#guessed"
|
return "$BASE_URL/thumbnails/${hbid}_1.jpg#guessed"
|
||||||
|
@ -48,11 +48,11 @@ class HentaiCafeSearchMetadata : RaisedSearchMetadata() {
|
|||||||
|
|
||||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||||
val pairs = mutableListOf<Pair<String, String>>()
|
val pairs = mutableListOf<Pair<String, String>>()
|
||||||
hcId?.let { pairs += Pair(context.getString(R.string.id), it) }
|
hcId?.let { pairs += context.getString(R.string.id) to it }
|
||||||
readerId?.let { pairs += Pair(context.getString(R.string.reader_id), it) }
|
readerId?.let { pairs += context.getString(R.string.reader_id) to it }
|
||||||
thumbnailUrl?.let { pairs += Pair(context.getString(R.string.thumbnail_url), it) }
|
thumbnailUrl?.let { pairs += context.getString(R.string.thumbnail_url) to it }
|
||||||
title?.let { pairs += Pair(context.getString(R.string.title), it) }
|
title?.let { pairs += context.getString(R.string.title) to it }
|
||||||
artist?.let { pairs += Pair(context.getString(R.string.artist), it) }
|
artist?.let { pairs += context.getString(R.string.artist) to it }
|
||||||
return pairs
|
return pairs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ package exh.metadata.metadata
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import exh.metadata.EX_DATE_FORMAT
|
import exh.metadata.MetadataUtil
|
||||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
@ -94,25 +94,27 @@ class HitomiSearchMetadata : RaisedSearchMetadata() {
|
|||||||
|
|
||||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||||
val pairs = mutableListOf<Pair<String, String>>()
|
val pairs = mutableListOf<Pair<String, String>>()
|
||||||
hlId?.let { pairs += Pair(context.getString(R.string.id), it) }
|
with(context) {
|
||||||
title?.let { pairs += Pair(context.getString(R.string.title), it) }
|
hlId?.let { pairs += getString(R.string.id) to it }
|
||||||
thumbnailUrl?.let { pairs += Pair(context.getString(R.string.thumbnail_url), it) }
|
title?.let { pairs += getString(R.string.title) to it }
|
||||||
val artists = artists.joinToString()
|
thumbnailUrl?.let { pairs += getString(R.string.thumbnail_url) to it }
|
||||||
if (artists.isNotBlank()) {
|
val artists = artists.joinToString()
|
||||||
pairs += Pair(context.getString(R.string.artist), artists)
|
if (artists.isNotBlank()) {
|
||||||
|
pairs += getString(R.string.artist) to artists
|
||||||
|
}
|
||||||
|
group?.let { pairs += getString(R.string.group) to it }
|
||||||
|
genre?.let { pairs += getString(R.string.genre) to it }
|
||||||
|
language?.let { pairs += getString(R.string.language) to it }
|
||||||
|
val series = series.joinToString()
|
||||||
|
if (series.isNotBlank()) {
|
||||||
|
pairs += getString(R.string.series) to series
|
||||||
|
}
|
||||||
|
val characters = characters.joinToString()
|
||||||
|
if (characters.isNotBlank()) {
|
||||||
|
pairs += getString(R.string.characters) to characters
|
||||||
|
}
|
||||||
|
uploadDate?.let { pairs += getString(R.string.date_posted) to MetadataUtil.EX_DATE_FORMAT.format(Date(it)) }
|
||||||
}
|
}
|
||||||
group?.let { pairs += Pair(context.getString(R.string.group), it) }
|
|
||||||
genre?.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
|
return pairs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,24 +78,24 @@ class MangaDexSearchMetadata : RaisedSearchMetadata() {
|
|||||||
|
|
||||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||||
val pairs = mutableListOf<Pair<String, String>>()
|
val pairs = mutableListOf<Pair<String, String>>()
|
||||||
mdId?.let { pairs += Pair(context.getString(R.string.id), it) }
|
mdId?.let { pairs += context.getString(R.string.id) to it }
|
||||||
mdUrl?.let { pairs += Pair(context.getString(R.string.url), it) }
|
mdUrl?.let { pairs += context.getString(R.string.url) to it }
|
||||||
thumbnail_url?.let { pairs += Pair(context.getString(R.string.thumbnail_url), it) }
|
thumbnail_url?.let { pairs += context.getString(R.string.thumbnail_url) to it }
|
||||||
title?.let { pairs += Pair(context.getString(R.string.title), it) }
|
title?.let { pairs += context.getString(R.string.title) to it }
|
||||||
author?.let { pairs += Pair(context.getString(R.string.author), it) }
|
author?.let { pairs += context.getString(R.string.author) to it }
|
||||||
artist?.let { pairs += Pair(context.getString(R.string.artist), it) }
|
artist?.let { pairs += context.getString(R.string.artist) to it }
|
||||||
lang_flag?.let { pairs += Pair(context.getString(R.string.language), it) }
|
lang_flag?.let { pairs += context.getString(R.string.language) to it }
|
||||||
last_chapter_number?.let { pairs += Pair(context.getString(R.string.last_chapter_number), it.toString()) }
|
last_chapter_number?.let { pairs += context.getString(R.string.last_chapter_number) to it.toString() }
|
||||||
rating?.let { pairs += Pair(context.getString(R.string.average_rating), it) }
|
rating?.let { pairs += context.getString(R.string.average_rating) to it }
|
||||||
users?.let { pairs += Pair(context.getString(R.string.total_ratings), it) }
|
users?.let { pairs += context.getString(R.string.total_ratings) to it }
|
||||||
status?.let { pairs += Pair(context.getString(R.string.status), it.toString()) }
|
status?.let { pairs += context.getString(R.string.status) to it.toString() }
|
||||||
missing_chapters?.let { pairs += Pair(context.getString(R.string.missing_chapters), it) }
|
missing_chapters?.let { pairs += context.getString(R.string.missing_chapters) to it }
|
||||||
follow_status?.let { pairs += Pair(context.getString(R.string.follow_status), it.toString()) }
|
follow_status?.let { pairs += context.getString(R.string.follow_status) to it.toString() }
|
||||||
anilist_id?.let { pairs += Pair(context.getString(R.string.anilist_id), it) }
|
anilist_id?.let { pairs += context.getString(R.string.anilist_id) to it }
|
||||||
kitsu_id?.let { pairs += Pair(context.getString(R.string.kitsu_id), it) }
|
kitsu_id?.let { pairs += context.getString(R.string.kitsu_id) to it }
|
||||||
my_anime_list_id?.let { pairs += Pair(context.getString(R.string.mal_id), it) }
|
my_anime_list_id?.let { pairs += context.getString(R.string.mal_id) to it }
|
||||||
manga_updates_id?.let { pairs += Pair(context.getString(R.string.manga_updates_id), it) }
|
manga_updates_id?.let { pairs += context.getString(R.string.manga_updates_id) to it }
|
||||||
anime_planet_id?.let { pairs += Pair(context.getString(R.string.anime_planet_id), it) }
|
anime_planet_id?.let { pairs += context.getString(R.string.anime_planet_id) to it }
|
||||||
return pairs
|
return pairs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,8 +3,7 @@ package exh.metadata.metadata
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import exh.metadata.EX_DATE_FORMAT
|
import exh.metadata.MetadataUtil
|
||||||
import exh.metadata.ONGOING_SUFFIX
|
|
||||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
@ -65,7 +64,7 @@ class NHentaiSearchMetadata : RaisedSearchMetadata() {
|
|||||||
// We default to completed
|
// We default to completed
|
||||||
manga.status = SManga.COMPLETED
|
manga.status = SManga.COMPLETED
|
||||||
englishTitle?.let { t ->
|
englishTitle?.let { t ->
|
||||||
ONGOING_SUFFIX.find {
|
MetadataUtil.ONGOING_SUFFIX.find {
|
||||||
t.endsWith(it, ignoreCase = true)
|
t.endsWith(it, ignoreCase = true)
|
||||||
}?.let {
|
}?.let {
|
||||||
manga.status = SManga.ONGOING
|
manga.status = SManga.ONGOING
|
||||||
@ -77,17 +76,17 @@ class NHentaiSearchMetadata : RaisedSearchMetadata() {
|
|||||||
|
|
||||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||||
val pairs = mutableListOf<Pair<String, String>>()
|
val pairs = mutableListOf<Pair<String, String>>()
|
||||||
nhId?.let { pairs += Pair(context.getString(R.string.id), it.toString()) }
|
nhId?.let { pairs += context.getString(R.string.id) to it.toString() }
|
||||||
uploadDate?.let { pairs += Pair(context.getString(R.string.date_posted), EX_DATE_FORMAT.format(Date(it * 1000))) }
|
uploadDate?.let { pairs += context.getString(R.string.date_posted) to MetadataUtil.EX_DATE_FORMAT.format(Date(it * 1000)) }
|
||||||
favoritesCount?.let { pairs += Pair(context.getString(R.string.total_favorites), it.toString()) }
|
favoritesCount?.let { pairs += context.getString(R.string.total_favorites) to it.toString() }
|
||||||
mediaId?.let { pairs += Pair(context.getString(R.string.media_id), it) }
|
mediaId?.let { pairs += context.getString(R.string.media_id) to it }
|
||||||
japaneseTitle?.let { pairs += Pair(context.getString(R.string.japanese_title), it) }
|
japaneseTitle?.let { pairs += context.getString(R.string.japanese_title) to it }
|
||||||
englishTitle?.let { pairs += Pair(context.getString(R.string.english_title), it) }
|
englishTitle?.let { pairs += context.getString(R.string.english_title) to it }
|
||||||
shortTitle?.let { pairs += Pair(context.getString(R.string.short_title), it) }
|
shortTitle?.let { pairs += context.getString(R.string.short_title) to it }
|
||||||
coverImageType?.let { pairs += Pair(context.getString(R.string.cover_image_file_type), it) }
|
coverImageType?.let { pairs += context.getString(R.string.cover_image_file_type) to it }
|
||||||
pageImageTypes.size.let { pairs += Pair(context.getString(R.string.page_count), it.toString()) }
|
pageImageTypes.size.let { pairs += context.getString(R.string.page_count) to it.toString() }
|
||||||
thumbnailImageType?.let { pairs += Pair(context.getString(R.string.thumbnail_image_file_type), it) }
|
thumbnailImageType?.let { pairs += context.getString(R.string.thumbnail_image_file_type) to it }
|
||||||
scanlator?.let { pairs += Pair(context.getString(R.string.scanlator), it) }
|
scanlator?.let { pairs += context.getString(R.string.scanlator) to it }
|
||||||
return pairs
|
return pairs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,19 +95,19 @@ class PervEdenSearchMetadata : RaisedSearchMetadata() {
|
|||||||
|
|
||||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||||
val pairs = mutableListOf<Pair<String, String>>()
|
val pairs = mutableListOf<Pair<String, String>>()
|
||||||
pvId?.let { pairs += Pair(context.getString(R.string.id), it) }
|
pvId?.let { pairs += context.getString(R.string.id) to it }
|
||||||
url?.let { pairs += Pair(context.getString(R.string.url), it) }
|
url?.let { pairs += context.getString(R.string.url) to it }
|
||||||
thumbnailUrl?.let { pairs += Pair(context.getString(R.string.thumbnail_url), it) }
|
thumbnailUrl?.let { pairs += context.getString(R.string.thumbnail_url) to it }
|
||||||
title?.let { pairs += Pair(context.getString(R.string.title), it) }
|
title?.let { pairs += context.getString(R.string.title) to it }
|
||||||
val altTitles = altTitles.joinToString()
|
val altTitles = altTitles.joinToString()
|
||||||
if (altTitles.isNotBlank()) {
|
if (altTitles.isNotBlank()) {
|
||||||
pairs += Pair(context.getString(R.string.alt_titles), altTitles)
|
pairs += context.getString(R.string.alt_titles) to altTitles
|
||||||
}
|
}
|
||||||
artist?.let { pairs += Pair(context.getString(R.string.artist), it) }
|
artist?.let { pairs += context.getString(R.string.artist) to it }
|
||||||
genre?.let { pairs += Pair(context.getString(R.string.genre), it) }
|
genre?.let { pairs += context.getString(R.string.genre) to it }
|
||||||
rating?.let { pairs += Pair(context.getString(R.string.average_rating), it.toString()) }
|
rating?.let { pairs += context.getString(R.string.average_rating) to it.toString() }
|
||||||
status?.let { pairs += Pair(context.getString(R.string.status), it) }
|
status?.let { pairs += context.getString(R.string.status) to it }
|
||||||
lang?.let { pairs += Pair(context.getString(R.string.language), it) }
|
lang?.let { pairs += context.getString(R.string.language) to it }
|
||||||
return pairs
|
return pairs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,16 +64,16 @@ class PururinSearchMetadata : RaisedSearchMetadata() {
|
|||||||
|
|
||||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||||
val pairs = mutableListOf<Pair<String, String>>()
|
val pairs = mutableListOf<Pair<String, String>>()
|
||||||
prId?.let { pairs += Pair(context.getString(R.string.id), it.toString()) }
|
prId?.let { pairs += context.getString(R.string.id) to it.toString() }
|
||||||
title?.let { pairs += Pair(context.getString(R.string.title), it) }
|
title?.let { pairs += context.getString(R.string.title) to it }
|
||||||
altTitle?.let { pairs += Pair(context.getString(R.string.alt_title), it) }
|
altTitle?.let { pairs += context.getString(R.string.alt_title) to it }
|
||||||
thumbnailUrl?.let { pairs += Pair(context.getString(R.string.thumbnail_url), it) }
|
thumbnailUrl?.let { pairs += context.getString(R.string.thumbnail_url) to it }
|
||||||
uploaderDisp?.let { pairs += Pair(context.getString(R.string.uploader_capital), it) }
|
uploaderDisp?.let { pairs += context.getString(R.string.uploader_capital) to it }
|
||||||
uploader?.let { pairs += Pair(context.getString(R.string.uploader), it) }
|
uploader?.let { pairs += context.getString(R.string.uploader) to it }
|
||||||
pages?.let { pairs += Pair(context.getString(R.string.page_count), it.toString()) }
|
pages?.let { pairs += context.getString(R.string.page_count) to it.toString() }
|
||||||
fileSize?.let { pairs += Pair(context.getString(R.string.gallery_size), it) }
|
fileSize?.let { pairs += context.getString(R.string.gallery_size) to it }
|
||||||
ratingCount?.let { pairs += Pair(context.getString(R.string.total_ratings), it.toString()) }
|
ratingCount?.let { pairs += context.getString(R.string.total_ratings) to it.toString() }
|
||||||
averageRating?.let { pairs += Pair(context.getString(R.string.average_rating), it.toString()) }
|
averageRating?.let { pairs += context.getString(R.string.average_rating) to it.toString() }
|
||||||
return pairs
|
return pairs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import android.content.Context
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import exh.metadata.EX_DATE_FORMAT
|
import exh.metadata.MetadataUtil
|
||||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
@ -82,25 +82,25 @@ class TsuminoSearchMetadata : RaisedSearchMetadata() {
|
|||||||
|
|
||||||
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
override fun getExtraInfoPairs(context: Context): List<Pair<String, String>> {
|
||||||
val pairs = mutableListOf<Pair<String, String>>()
|
val pairs = mutableListOf<Pair<String, String>>()
|
||||||
tmId?.let { pairs += Pair(context.getString(R.string.id), it.toString()) }
|
tmId?.let { pairs += context.getString(R.string.id) to it.toString() }
|
||||||
title?.let { pairs += Pair(context.getString(R.string.title), it) }
|
title?.let { pairs += context.getString(R.string.title) to it }
|
||||||
uploader?.let { pairs += Pair(context.getString(R.string.uploader), it) }
|
uploader?.let { pairs += context.getString(R.string.uploader) to it }
|
||||||
uploadDate?.let { pairs += Pair(context.getString(R.string.date_posted), EX_DATE_FORMAT.format(Date(it))) }
|
uploadDate?.let { pairs += context.getString(R.string.date_posted) to MetadataUtil.EX_DATE_FORMAT.format(Date(it)) }
|
||||||
length?.let { pairs += Pair(context.getString(R.string.page_count), it.toString()) }
|
length?.let { pairs += context.getString(R.string.page_count) to it.toString() }
|
||||||
ratingString?.let { pairs += Pair(context.getString(R.string.rating_string), it) }
|
ratingString?.let { pairs += context.getString(R.string.rating_string) to it }
|
||||||
averageRating?.let { pairs += Pair(context.getString(R.string.average_rating), it.toString()) }
|
averageRating?.let { pairs += context.getString(R.string.average_rating) to it.toString() }
|
||||||
userRatings?.let { pairs += Pair(context.getString(R.string.total_ratings), it.toString()) }
|
userRatings?.let { pairs += context.getString(R.string.total_ratings) to it.toString() }
|
||||||
favorites?.let { pairs += Pair(context.getString(R.string.total_favorites), it.toString()) }
|
favorites?.let { pairs += context.getString(R.string.total_favorites) to it.toString() }
|
||||||
category?.let { pairs += Pair(context.getString(R.string.genre), it) }
|
category?.let { pairs += context.getString(R.string.genre) to it }
|
||||||
collection?.let { pairs += Pair(context.getString(R.string.collection), it) }
|
collection?.let { pairs += context.getString(R.string.collection) to it }
|
||||||
group?.let { pairs += Pair(context.getString(R.string.group), it) }
|
group?.let { pairs += context.getString(R.string.group) to it }
|
||||||
val parodiesString = parody.joinToString()
|
val parodiesString = parody.joinToString()
|
||||||
if (parodiesString.isNotEmpty()) {
|
if (parodiesString.isNotEmpty()) {
|
||||||
pairs += Pair(context.getString(R.string.parodies), parodiesString)
|
pairs += context.getString(R.string.parodies) to parodiesString
|
||||||
}
|
}
|
||||||
val charactersString = character.joinToString()
|
val charactersString = character.joinToString()
|
||||||
if (charactersString.isNotEmpty()) {
|
if (charactersString.isNotEmpty()) {
|
||||||
pairs += Pair(context.getString(R.string.characters), charactersString)
|
pairs += context.getString(R.string.characters) to charactersString
|
||||||
}
|
}
|
||||||
return pairs
|
return pairs
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package exh.search
|
package exh.search
|
||||||
|
|
||||||
import exh.plusAssign
|
import exh.plusAssign
|
||||||
import exh.search.SearchEngine.Companion.escapeLike
|
|
||||||
|
|
||||||
class Text : QueryComponent() {
|
class Text : QueryComponent() {
|
||||||
val components = mutableListOf<TextComponent>()
|
val components = mutableListOf<TextComponent>()
|
||||||
@ -44,7 +43,7 @@ class Text : QueryComponent() {
|
|||||||
val builder = StringBuilder()
|
val builder = StringBuilder()
|
||||||
for (component in components) {
|
for (component in components) {
|
||||||
when (component) {
|
when (component) {
|
||||||
is StringTextComponent -> builder += escapeLike(component.value)
|
is StringTextComponent -> builder += SearchEngine.escapeLike(component.value)
|
||||||
is SingleWildcard -> builder += "_"
|
is SingleWildcard -> builder += "_"
|
||||||
is MultiWildcard -> builder += "%"
|
is MultiWildcard -> builder += "%"
|
||||||
}
|
}
|
||||||
@ -60,5 +59,5 @@ class Text : QueryComponent() {
|
|||||||
rawText!!
|
rawText!!
|
||||||
}
|
}
|
||||||
|
|
||||||
fun rawTextEscapedForLike() = escapeLike(rawTextOnly())
|
fun rawTextEscapedForLike() = SearchEngine.escapeLike(rawTextOnly())
|
||||||
}
|
}
|
||||||
|
@ -235,21 +235,22 @@ class EnhancedHttpSource(
|
|||||||
originalSource
|
originalSource
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
companion object {
|
|
||||||
fun Source.getMainSource(): Source {
|
fun Source.getMainSource(): Source = if (this is EnhancedHttpSource) {
|
||||||
return if (this is EnhancedHttpSource) {
|
this.source()
|
||||||
this.source()
|
} else {
|
||||||
} else {
|
this
|
||||||
this
|
}
|
||||||
}
|
|
||||||
}
|
fun Source.getOriginalSource(): Source = if (this is EnhancedHttpSource) {
|
||||||
fun Source.getOriginalSource(): Source {
|
this.originalSource
|
||||||
return if (this is EnhancedHttpSource) {
|
} else {
|
||||||
this.originalSource
|
this
|
||||||
} else {
|
}
|
||||||
this
|
|
||||||
}
|
fun Source.getEnhancedSource(): Source = if (this is EnhancedHttpSource) {
|
||||||
}
|
this.enhancedSource
|
||||||
}
|
} else {
|
||||||
|
this
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import android.webkit.WebResourceRequest
|
|||||||
import android.webkit.WebResourceResponse
|
import android.webkit.WebResourceResponse
|
||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
import exh.ui.captcha.BrowserActionActivity.Companion.CROSS_WINDOW_SCRIPT_INNER
|
|
||||||
import org.jsoup.nodes.DataNode
|
import org.jsoup.nodes.DataNode
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
@ -24,7 +23,7 @@ class AutoSolvingWebViewClient(
|
|||||||
val oReq = request.toOkHttpRequest()
|
val oReq = request.toOkHttpRequest()
|
||||||
val response = activity.httpClient.newCall(oReq).execute()
|
val response = activity.httpClient.newCall(oReq).execute()
|
||||||
val doc = response.asJsoup()
|
val doc = response.asJsoup()
|
||||||
doc.body().appendChild(Element("script").appendChild(DataNode(CROSS_WINDOW_SCRIPT_INNER)))
|
doc.body().appendChild(Element("script").appendChild(DataNode(BrowserActionActivity.CROSS_WINDOW_SCRIPT_INNER)))
|
||||||
return WebResourceResponse(
|
return WebResourceResponse(
|
||||||
"text/html",
|
"text/html",
|
||||||
"UTF-8",
|
"UTF-8",
|
||||||
|
@ -16,7 +16,7 @@ import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
|||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
import exh.metadata.metadata.base.FlatMetadata
|
import exh.metadata.metadata.base.FlatMetadata
|
||||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||||
import exh.source.EnhancedHttpSource.Companion.getMainSource
|
import exh.source.getMainSource
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
|
@ -1,23 +1,19 @@
|
|||||||
package exh.ui.metadata.adapters
|
package exh.ui.metadata.adapters
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.graphics.Color
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterEhBinding
|
import eu.kanade.tachiyomi.databinding.DescriptionAdapterEhBinding
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
import exh.metadata.MetadataUtil
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import exh.metadata.bindDrawable
|
||||||
import exh.metadata.humanReadableByteCount
|
|
||||||
import exh.metadata.metadata.EHentaiSearchMetadata
|
import exh.metadata.metadata.EHentaiSearchMetadata
|
||||||
import exh.ui.metadata.MetadataViewController
|
import exh.ui.metadata.MetadataViewController
|
||||||
import exh.util.SourceTagsUtil
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
@ -25,7 +21,6 @@ import kotlinx.coroutines.flow.launchIn
|
|||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import reactivecircus.flowbinding.android.view.clicks
|
import reactivecircus.flowbinding.android.view.clicks
|
||||||
import reactivecircus.flowbinding.android.view.longClicks
|
import reactivecircus.flowbinding.android.view.longClicks
|
||||||
import kotlin.math.roundToInt
|
|
||||||
|
|
||||||
class EHentaiDescriptionAdapter(
|
class EHentaiDescriptionAdapter(
|
||||||
private val controller: MangaController
|
private val controller: MangaController
|
||||||
@ -51,52 +46,23 @@ class EHentaiDescriptionAdapter(
|
|||||||
val meta = controller.presenter.meta
|
val meta = controller.presenter.meta
|
||||||
if (meta == null || meta !is EHentaiSearchMetadata) return
|
if (meta == null || meta !is EHentaiSearchMetadata) return
|
||||||
|
|
||||||
val genre = meta.genre
|
binding.genre.text = meta.genre?.let { MetadataUtil.getGenreAndColour(itemView.context, it) }?.let {
|
||||||
if (genre != null) {
|
binding.genre.setBackgroundColor(it.first)
|
||||||
val pair = when (genre) {
|
it.second
|
||||||
"doujinshi" -> Pair(SourceTagsUtil.DOUJINSHI_COLOR, R.string.doujinshi)
|
} ?: meta.genre ?: itemView.context.getString(R.string.unknown)
|
||||||
"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()) {
|
|
||||||
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.visible.text = itemView.context.getString(R.string.is_visible, meta.visible ?: itemView.context.getString(R.string.unknown))
|
||||||
|
|
||||||
binding.favorites.text = (meta.favorites ?: 0).toString()
|
binding.favorites.text = (meta.favorites ?: 0).toString()
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_book_24dp)?.apply {
|
binding.favorites.bindDrawable(itemView.context, R.drawable.ic_book_24dp)
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.favorites.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.uploader.text = meta.uploader ?: itemView.context.getString(R.string.unknown)
|
binding.uploader.text = meta.uploader ?: itemView.context.getString(R.string.unknown)
|
||||||
|
|
||||||
binding.size.text = humanReadableByteCount(meta.size ?: 0, true)
|
binding.size.text = MetadataUtil.humanReadableByteCount(meta.size ?: 0, true)
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_outline_sd_card_24)?.apply {
|
binding.size.bindDrawable(itemView.context, R.drawable.ic_outline_sd_card_24)
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.size.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.pages.text = itemView.resources.getQuantityString(R.plurals.num_pages, meta.length ?: 0, meta.length ?: 0)
|
binding.pages.text = itemView.resources.getQuantityString(R.plurals.num_pages, meta.length ?: 0, meta.length ?: 0)
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_baseline_menu_book_24)?.apply {
|
binding.pages.bindDrawable(itemView.context, R.drawable.ic_baseline_menu_book_24)
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.pages.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
val language = meta.language ?: itemView.context.getString(R.string.unknown)
|
val language = meta.language ?: itemView.context.getString(R.string.unknown)
|
||||||
binding.language.text = if (meta.translated == true) {
|
binding.language.text = if (meta.translated == true) {
|
||||||
@ -106,29 +72,11 @@ class EHentaiDescriptionAdapter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val ratingFloat = meta.averageRating?.toFloat()
|
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.ratingBar.rating = ratingFloat ?: 0F
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
binding.rating.text = (ratingFloat ?: 0F).toString() + " - " + itemView.context.getString(name)
|
binding.rating.text = (ratingFloat ?: 0F).toString() + " - " + MetadataUtil.getRatingString(itemView.context, ratingFloat?.times(2))
|
||||||
|
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_info_24dp)?.apply {
|
binding.moreInfo.bindDrawable(itemView.context, R.drawable.ic_info_24dp)
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.moreInfo.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
listOf(
|
listOf(
|
||||||
binding.favorites,
|
binding.favorites,
|
||||||
|
@ -3,15 +3,13 @@ package exh.ui.metadata.adapters
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapter8mBinding
|
import eu.kanade.tachiyomi.databinding.DescriptionAdapter8mBinding
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
import exh.metadata.bindDrawable
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
|
||||||
import exh.metadata.metadata.EightMusesSearchMetadata
|
import exh.metadata.metadata.EightMusesSearchMetadata
|
||||||
import exh.ui.metadata.MetadataViewController
|
import exh.ui.metadata.MetadataViewController
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@ -48,11 +46,7 @@ class EightMusesDescriptionAdapter(
|
|||||||
|
|
||||||
binding.title.text = meta.title ?: itemView.context.getString(R.string.unknown)
|
binding.title.text = meta.title ?: itemView.context.getString(R.string.unknown)
|
||||||
|
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_info_24dp)?.apply {
|
binding.moreInfo.bindDrawable(itemView.context, R.drawable.ic_info_24dp)
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.moreInfo.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.title.longClicks()
|
binding.title.longClicks()
|
||||||
.onEach {
|
.onEach {
|
||||||
|
@ -3,15 +3,13 @@ package exh.ui.metadata.adapters
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterHbBinding
|
import eu.kanade.tachiyomi.databinding.DescriptionAdapterHbBinding
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
import exh.metadata.bindDrawable
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
|
||||||
import exh.metadata.metadata.HBrowseSearchMetadata
|
import exh.metadata.metadata.HBrowseSearchMetadata
|
||||||
import exh.ui.metadata.MetadataViewController
|
import exh.ui.metadata.MetadataViewController
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@ -47,17 +45,9 @@ class HBrowseDescriptionAdapter(
|
|||||||
if (meta == null || meta !is HBrowseSearchMetadata) return
|
if (meta == null || meta !is HBrowseSearchMetadata) return
|
||||||
|
|
||||||
binding.pages.text = itemView.resources.getQuantityString(R.plurals.num_pages, meta.length ?: 0, meta.length ?: 0)
|
binding.pages.text = itemView.resources.getQuantityString(R.plurals.num_pages, meta.length ?: 0, meta.length ?: 0)
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_baseline_menu_book_24)?.apply {
|
binding.pages.bindDrawable(itemView.context, R.drawable.ic_baseline_menu_book_24)
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.pages.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_info_24dp)?.apply {
|
binding.moreInfo.bindDrawable(itemView.context, R.drawable.ic_info_24dp)
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.moreInfo.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.pages.longClicks()
|
binding.pages.longClicks()
|
||||||
.onEach {
|
.onEach {
|
||||||
|
@ -3,15 +3,13 @@ package exh.ui.metadata.adapters
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterHcBinding
|
import eu.kanade.tachiyomi.databinding.DescriptionAdapterHcBinding
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
import exh.metadata.bindDrawable
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
|
||||||
import exh.metadata.metadata.HentaiCafeSearchMetadata
|
import exh.metadata.metadata.HentaiCafeSearchMetadata
|
||||||
import exh.ui.metadata.MetadataViewController
|
import exh.ui.metadata.MetadataViewController
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@ -48,11 +46,7 @@ class HentaiCafeDescriptionAdapter(
|
|||||||
|
|
||||||
binding.artist.text = meta.artist ?: itemView.context.getString(R.string.unknown)
|
binding.artist.text = meta.artist ?: itemView.context.getString(R.string.unknown)
|
||||||
|
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_info_24dp)?.apply {
|
binding.moreInfo.bindDrawable(itemView.context, R.drawable.ic_info_24dp)
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.moreInfo.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.artist.longClicks()
|
binding.artist.longClicks()
|
||||||
.onEach {
|
.onEach {
|
||||||
|
@ -1,22 +1,18 @@
|
|||||||
package exh.ui.metadata.adapters
|
package exh.ui.metadata.adapters
|
||||||
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterHiBinding
|
import eu.kanade.tachiyomi.databinding.DescriptionAdapterHiBinding
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
import exh.metadata.MetadataUtil
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import exh.metadata.bindDrawable
|
||||||
import exh.metadata.EX_DATE_FORMAT
|
|
||||||
import exh.metadata.metadata.HitomiSearchMetadata
|
import exh.metadata.metadata.HitomiSearchMetadata
|
||||||
import exh.ui.metadata.MetadataViewController
|
import exh.ui.metadata.MetadataViewController
|
||||||
import exh.util.SourceTagsUtil
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
@ -50,37 +46,16 @@ class HitomiDescriptionAdapter(
|
|||||||
val meta = controller.presenter.meta
|
val meta = controller.presenter.meta
|
||||||
if (meta == null || meta !is HitomiSearchMetadata) return
|
if (meta == null || meta !is HitomiSearchMetadata) return
|
||||||
|
|
||||||
val genre = meta.genre
|
binding.genre.text = meta.genre?.let { MetadataUtil.getGenreAndColour(itemView.context, it) }?.let {
|
||||||
if (genre != null) {
|
binding.genre.setBackgroundColor(it.first)
|
||||||
val pair = when (genre) {
|
it.second
|
||||||
"doujinshi" -> Pair(SourceTagsUtil.DOUJINSHI_COLOR, R.string.doujinshi)
|
} ?: meta.genre ?: itemView.context.getString(R.string.unknown)
|
||||||
"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)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pair.first.isNotBlank()) {
|
binding.whenPosted.text = MetadataUtil.EX_DATE_FORMAT.format(Date(meta.uploadDate ?: 0))
|
||||||
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.group.text = meta.group ?: itemView.context.getString(R.string.unknown)
|
||||||
binding.language.text = meta.language ?: itemView.context.getString(R.string.unknown)
|
binding.language.text = meta.language ?: itemView.context.getString(R.string.unknown)
|
||||||
|
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_info_24dp)?.apply {
|
binding.moreInfo.bindDrawable(itemView.context, R.drawable.ic_info_24dp)
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.moreInfo.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
listOf(
|
listOf(
|
||||||
binding.genre,
|
binding.genre,
|
||||||
|
@ -4,15 +4,14 @@ import android.annotation.SuppressLint
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterMdBinding
|
import eu.kanade.tachiyomi.databinding.DescriptionAdapterMdBinding
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
import exh.metadata.MetadataUtil.getRatingString
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import exh.metadata.bindDrawable
|
||||||
import exh.metadata.metadata.MangaDexSearchMetadata
|
import exh.metadata.metadata.MangaDexSearchMetadata
|
||||||
import exh.ui.metadata.MetadataViewController
|
import exh.ui.metadata.MetadataViewController
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@ -23,7 +22,6 @@ import kotlinx.coroutines.flow.onEach
|
|||||||
import reactivecircus.flowbinding.android.view.clicks
|
import reactivecircus.flowbinding.android.view.clicks
|
||||||
import reactivecircus.flowbinding.android.view.longClicks
|
import reactivecircus.flowbinding.android.view.longClicks
|
||||||
import kotlin.math.round
|
import kotlin.math.round
|
||||||
import kotlin.math.roundToInt
|
|
||||||
|
|
||||||
class MangaDexDescriptionAdapter(
|
class MangaDexDescriptionAdapter(
|
||||||
private val controller: MangaController
|
private val controller: MangaController
|
||||||
@ -50,31 +48,12 @@ class MangaDexDescriptionAdapter(
|
|||||||
val meta = controller.presenter.meta
|
val meta = controller.presenter.meta
|
||||||
if (meta == null || meta !is MangaDexSearchMetadata) return
|
if (meta == null || meta !is MangaDexSearchMetadata) return
|
||||||
|
|
||||||
val ratingFloat = meta.rating?.toFloatOrNull()?.div(2F)
|
val ratingFloat = meta.rating?.toFloatOrNull()
|
||||||
val name = when (((ratingFloat ?: 100F) * 2).roundToInt()) {
|
binding.ratingBar.rating = ratingFloat?.div(2F) ?: 0F
|
||||||
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
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
binding.rating.text = (round((meta.rating?.toFloatOrNull() ?: 0F) * 100.0) / 100.0).toString() + " - " + itemView.context.getString(name)
|
binding.rating.text = (round((meta.rating?.toFloatOrNull() ?: 0F) * 100.0) / 100.0).toString() + " - " + getRatingString(itemView.context, ratingFloat)
|
||||||
|
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_info_24dp)?.apply {
|
binding.moreInfo.bindDrawable(itemView.context, R.drawable.ic_info_24dp)
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.moreInfo.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.rating.longClicks()
|
binding.rating.longClicks()
|
||||||
.onEach {
|
.onEach {
|
||||||
|
@ -1,23 +1,19 @@
|
|||||||
package exh.ui.metadata.adapters
|
package exh.ui.metadata.adapters
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.graphics.Color
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterNhBinding
|
import eu.kanade.tachiyomi.databinding.DescriptionAdapterNhBinding
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
import exh.metadata.MetadataUtil
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import exh.metadata.bindDrawable
|
||||||
import exh.metadata.EX_DATE_FORMAT
|
|
||||||
import exh.metadata.metadata.NHentaiSearchMetadata
|
import exh.metadata.metadata.NHentaiSearchMetadata
|
||||||
import exh.ui.metadata.MetadataViewController
|
import exh.ui.metadata.MetadataViewController
|
||||||
import exh.util.SourceTagsUtil
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
@ -52,60 +48,30 @@ class NHentaiDescriptionAdapter(
|
|||||||
val meta = controller.presenter.meta
|
val meta = controller.presenter.meta
|
||||||
if (meta == null || meta !is NHentaiSearchMetadata) return
|
if (meta == null || meta !is NHentaiSearchMetadata) return
|
||||||
|
|
||||||
var category: String? = null
|
binding.genre.text = meta.tags.filter { it.namespace == NHentaiSearchMetadata.NHENTAI_CATEGORIES_NAMESPACE }.let { tags ->
|
||||||
meta.tags.filter { it.namespace == NHentaiSearchMetadata.NHENTAI_CATEGORIES_NAMESPACE }.let { tags ->
|
if (tags.isNotEmpty()) tags.joinToString(transform = { it.name }) else null
|
||||||
if (tags.isNotEmpty()) category = tags.joinToString(transform = { it.name })
|
}.let { categoriesString ->
|
||||||
|
categoriesString?.let { MetadataUtil.getGenreAndColour(itemView.context, it) }?.let {
|
||||||
|
binding.genre.setBackgroundColor(it.first)
|
||||||
|
it.second
|
||||||
|
} ?: categoriesString ?: itemView.context.getString(R.string.unknown)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (category != null) {
|
|
||||||
val pair = when (category) {
|
|
||||||
"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()) {
|
|
||||||
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 {
|
meta.favoritesCount?.let {
|
||||||
if (it == 0L) return@let
|
if (it == 0L) return@let
|
||||||
binding.favorites.text = it.toString()
|
binding.favorites.text = it.toString()
|
||||||
|
binding.favorites.bindDrawable(itemView.context, R.drawable.ic_book_24dp)
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_book_24dp)?.apply {
|
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.favorites.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.whenPosted.text = EX_DATE_FORMAT.format(Date((meta.uploadDate ?: 0) * 1000))
|
binding.whenPosted.text = MetadataUtil.EX_DATE_FORMAT.format(Date((meta.uploadDate ?: 0) * 1000))
|
||||||
|
|
||||||
binding.pages.text = itemView.resources.getQuantityString(R.plurals.num_pages, meta.pageImageTypes.size, meta.pageImageTypes.size)
|
binding.pages.text = itemView.resources.getQuantityString(R.plurals.num_pages, meta.pageImageTypes.size, meta.pageImageTypes.size)
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_baseline_menu_book_24)?.apply {
|
binding.pages.bindDrawable(itemView.context, R.drawable.ic_baseline_menu_book_24)
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.pages.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
binding.id.text = "#" + (meta.nhId ?: 0)
|
binding.id.text = "#" + (meta.nhId ?: 0)
|
||||||
|
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_info_24dp)?.apply {
|
binding.moreInfo.bindDrawable(itemView.context, R.drawable.ic_info_24dp)
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.moreInfo.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
listOf(
|
listOf(
|
||||||
binding.favorites,
|
binding.favorites,
|
||||||
|
@ -1,22 +1,19 @@
|
|||||||
package exh.ui.metadata.adapters
|
package exh.ui.metadata.adapters
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.graphics.Color
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterPeBinding
|
import eu.kanade.tachiyomi.databinding.DescriptionAdapterPeBinding
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
import exh.metadata.MetadataUtil
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import exh.metadata.bindDrawable
|
||||||
import exh.metadata.metadata.PervEdenSearchMetadata
|
import exh.metadata.metadata.PervEdenSearchMetadata
|
||||||
import exh.ui.metadata.MetadataViewController
|
import exh.ui.metadata.MetadataViewController
|
||||||
import exh.util.SourceTagsUtil
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
@ -26,7 +23,6 @@ import reactivecircus.flowbinding.android.view.clicks
|
|||||||
import reactivecircus.flowbinding.android.view.longClicks
|
import reactivecircus.flowbinding.android.view.longClicks
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import kotlin.math.round
|
import kotlin.math.round
|
||||||
import kotlin.math.roundToInt
|
|
||||||
|
|
||||||
class PervEdenDescriptionAdapter(
|
class PervEdenDescriptionAdapter(
|
||||||
private val controller: MangaController
|
private val controller: MangaController
|
||||||
@ -52,22 +48,10 @@ class PervEdenDescriptionAdapter(
|
|||||||
val meta = controller.presenter.meta
|
val meta = controller.presenter.meta
|
||||||
if (meta == null || meta !is PervEdenSearchMetadata) return
|
if (meta == null || meta !is PervEdenSearchMetadata) return
|
||||||
|
|
||||||
val genre = meta.genre
|
binding.genre.text = meta.genre?.let { MetadataUtil.getGenreAndColour(itemView.context, it) }?.let {
|
||||||
if (genre != null) {
|
binding.genre.setBackgroundColor(it.first)
|
||||||
val pair = when (genre) {
|
it.second
|
||||||
"Doujinshi" -> Pair(SourceTagsUtil.DOUJINSHI_COLOR, R.string.doujinshi)
|
} ?: meta.genre ?: itemView.context.getString(R.string.unknown)
|
||||||
"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)
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
val language = meta.lang
|
||||||
binding.language.text = if (language != null) {
|
binding.language.text = if (language != null) {
|
||||||
@ -75,29 +59,11 @@ class PervEdenDescriptionAdapter(
|
|||||||
local.displayName
|
local.displayName
|
||||||
} else itemView.context.getString(R.string.unknown)
|
} 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.ratingBar.rating = meta.rating ?: 0F
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
binding.rating.text = (round((meta.rating ?: 0F) * 100.0) / 100.0).toString() + " - " + itemView.context.getString(name)
|
binding.rating.text = (round((meta.rating ?: 0F) * 100.0) / 100.0).toString() + " - " + MetadataUtil.getRatingString(itemView.context, meta.rating?.times(2))
|
||||||
|
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_info_24dp)?.apply {
|
binding.moreInfo.bindDrawable(itemView.context, R.drawable.ic_info_24dp)
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.moreInfo.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
listOf(
|
listOf(
|
||||||
binding.genre,
|
binding.genre,
|
||||||
|
@ -1,23 +1,19 @@
|
|||||||
package exh.ui.metadata.adapters
|
package exh.ui.metadata.adapters
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.graphics.Color
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterPuBinding
|
import eu.kanade.tachiyomi.databinding.DescriptionAdapterPuBinding
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
import exh.metadata.MetadataUtil
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import exh.metadata.bindDrawable
|
||||||
import exh.metadata.metadata.PururinSearchMetadata
|
import exh.metadata.metadata.PururinSearchMetadata
|
||||||
import exh.metadata.metadata.PururinSearchMetadata.Companion.TAG_NAMESPACE_CATEGORY
|
|
||||||
import exh.ui.metadata.MetadataViewController
|
import exh.ui.metadata.MetadataViewController
|
||||||
import exh.util.SourceTagsUtil
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
@ -26,7 +22,6 @@ import kotlinx.coroutines.flow.onEach
|
|||||||
import reactivecircus.flowbinding.android.view.clicks
|
import reactivecircus.flowbinding.android.view.clicks
|
||||||
import reactivecircus.flowbinding.android.view.longClicks
|
import reactivecircus.flowbinding.android.view.longClicks
|
||||||
import kotlin.math.round
|
import kotlin.math.round
|
||||||
import kotlin.math.roundToInt
|
|
||||||
|
|
||||||
class PururinDescriptionAdapter(
|
class PururinDescriptionAdapter(
|
||||||
private val controller: MangaController
|
private val controller: MangaController
|
||||||
@ -52,64 +47,28 @@ class PururinDescriptionAdapter(
|
|||||||
val meta = controller.presenter.meta
|
val meta = controller.presenter.meta
|
||||||
if (meta == null || meta !is PururinSearchMetadata) return
|
if (meta == null || meta !is PururinSearchMetadata) return
|
||||||
|
|
||||||
val genre = meta.tags.find { it.namespace == TAG_NAMESPACE_CATEGORY }
|
binding.genre.text = meta.tags.find { it.namespace == PururinSearchMetadata.TAG_NAMESPACE_CATEGORY }.let { genre ->
|
||||||
if (genre != null) {
|
genre?.let { MetadataUtil.getGenreAndColour(itemView.context, it.name) }?.let {
|
||||||
val pair = when (genre.name) {
|
binding.genre.setBackgroundColor(it.first)
|
||||||
"doujinshi" -> Pair(SourceTagsUtil.DOUJINSHI_COLOR, R.string.doujinshi)
|
it.second
|
||||||
"manga" -> Pair(SourceTagsUtil.MANGA_COLOR, R.string.manga)
|
} ?: genre?.name ?: itemView.context.getString(R.string.unknown)
|
||||||
"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)
|
|
||||||
}
|
|
||||||
|
|
||||||
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.uploader.text = meta.uploaderDisp ?: meta.uploader ?: ""
|
||||||
|
|
||||||
binding.size.text = meta.fileSize ?: itemView.context.getString(R.string.unknown)
|
binding.size.text = meta.fileSize ?: itemView.context.getString(R.string.unknown)
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_outline_sd_card_24)?.apply {
|
binding.size.bindDrawable(itemView.context, R.drawable.ic_outline_sd_card_24)
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.size.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.pages.text = itemView.resources.getQuantityString(R.plurals.num_pages, meta.pages ?: 0, meta.pages ?: 0)
|
binding.pages.text = itemView.resources.getQuantityString(R.plurals.num_pages, meta.pages ?: 0, meta.pages ?: 0)
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_baseline_menu_book_24)?.apply {
|
binding.pages.bindDrawable(itemView.context, R.drawable.ic_baseline_menu_book_24)
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.pages.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
val ratingFloat = meta.averageRating?.toFloat()
|
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.ratingBar.rating = ratingFloat ?: 0F
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
binding.rating.text = (round((ratingFloat ?: 0F) * 100.0) / 100.0).toString() + " - " + itemView.context.getString(name)
|
binding.rating.text = (round((ratingFloat ?: 0F) * 100.0) / 100.0).toString() + " - " + MetadataUtil.getRatingString(itemView.context, ratingFloat?.times(2))
|
||||||
|
|
||||||
|
binding.moreInfo.bindDrawable(itemView.context, R.drawable.ic_info_24dp)
|
||||||
|
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_info_24dp)?.apply {
|
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.moreInfo.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
listOf(
|
listOf(
|
||||||
binding.genre,
|
binding.genre,
|
||||||
binding.pages,
|
binding.pages,
|
||||||
|
@ -1,22 +1,19 @@
|
|||||||
package exh.ui.metadata.adapters
|
package exh.ui.metadata.adapters
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.graphics.Color
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.databinding.DescriptionAdapterTsBinding
|
import eu.kanade.tachiyomi.databinding.DescriptionAdapterTsBinding
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
import exh.metadata.MetadataUtil
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import exh.metadata.bindDrawable
|
||||||
import exh.metadata.metadata.TsuminoSearchMetadata
|
import exh.metadata.metadata.TsuminoSearchMetadata
|
||||||
import exh.ui.metadata.MetadataViewController
|
import exh.ui.metadata.MetadataViewController
|
||||||
import exh.util.SourceTagsUtil
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
@ -26,7 +23,6 @@ import reactivecircus.flowbinding.android.view.clicks
|
|||||||
import reactivecircus.flowbinding.android.view.longClicks
|
import reactivecircus.flowbinding.android.view.longClicks
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import kotlin.math.round
|
import kotlin.math.round
|
||||||
import kotlin.math.roundToInt
|
|
||||||
|
|
||||||
class TsuminoDescriptionAdapter(
|
class TsuminoDescriptionAdapter(
|
||||||
private val controller: MangaController
|
private val controller: MangaController
|
||||||
@ -52,64 +48,26 @@ class TsuminoDescriptionAdapter(
|
|||||||
val meta = controller.presenter.meta
|
val meta = controller.presenter.meta
|
||||||
if (meta == null || meta !is TsuminoSearchMetadata) return
|
if (meta == null || meta !is TsuminoSearchMetadata) return
|
||||||
|
|
||||||
val genre = meta.category
|
binding.genre.text = meta.category?.let { MetadataUtil.getGenreAndColour(itemView.context, it) }?.let {
|
||||||
if (genre != null) {
|
binding.genre.setBackgroundColor(it.first)
|
||||||
val pair = when (genre) {
|
it.second
|
||||||
"Doujinshi" -> Pair(SourceTagsUtil.DOUJINSHI_COLOR, R.string.doujinshi)
|
} ?: meta.category ?: itemView.context.getString(R.string.unknown)
|
||||||
"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)
|
|
||||||
}
|
|
||||||
|
|
||||||
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()
|
binding.favorites.text = (meta.favorites ?: 0).toString()
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_book_24dp)?.apply {
|
binding.favorites.bindDrawable(itemView.context, R.drawable.ic_book_24dp)
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.favorites.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.whenPosted.text = TsuminoSearchMetadata.TSUMINO_DATE_FORMAT.format(Date(meta.uploadDate ?: 0))
|
binding.whenPosted.text = TsuminoSearchMetadata.TSUMINO_DATE_FORMAT.format(Date(meta.uploadDate ?: 0))
|
||||||
|
|
||||||
binding.uploader.text = meta.uploader ?: itemView.context.getString(R.string.unknown)
|
binding.uploader.text = meta.uploader ?: itemView.context.getString(R.string.unknown)
|
||||||
|
|
||||||
binding.pages.text = itemView.resources.getQuantityString(R.plurals.num_pages, meta.length ?: 0, meta.length ?: 0)
|
binding.pages.text = itemView.resources.getQuantityString(R.plurals.num_pages, meta.length ?: 0, meta.length ?: 0)
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_baseline_menu_book_24)?.apply {
|
binding.pages.bindDrawable(itemView.context, R.drawable.ic_baseline_menu_book_24)
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.pages.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
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.ratingBar.rating = meta.averageRating ?: 0F
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
binding.rating.text = (round((meta.averageRating ?: 0F) * 100.0) / 100.0).toString() + " - " + itemView.context.getString(name)
|
binding.rating.text = (round((meta.averageRating ?: 0F) * 100.0) / 100.0).toString() + " - " + MetadataUtil.getRatingString(itemView.context, meta.averageRating?.times(2))
|
||||||
|
|
||||||
ContextCompat.getDrawable(itemView.context, R.drawable.ic_info_24dp)?.apply {
|
binding.moreInfo.bindDrawable(itemView.context, R.drawable.ic_info_24dp)
|
||||||
setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
|
||||||
setBounds(0, 0, 20.dpToPx, 20.dpToPx)
|
|
||||||
binding.moreInfo.setCompoundDrawables(this, null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
listOf(
|
listOf(
|
||||||
binding.favorites,
|
binding.favorites,
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
package exh.util
|
|
||||||
|
|
||||||
import kotlinx.coroutines.sync.Mutex
|
|
||||||
import kotlinx.coroutines.sync.withLock
|
|
||||||
|
|
||||||
class CachedField<T>(private val expiresAfterMs: Long) {
|
|
||||||
@Volatile
|
|
||||||
private var initTime: Long = -1
|
|
||||||
|
|
||||||
@Volatile
|
|
||||||
private var content: T? = null
|
|
||||||
|
|
||||||
private val mutex = Mutex()
|
|
||||||
|
|
||||||
suspend fun obtain(producer: suspend () -> T): T {
|
|
||||||
return mutex.withLock {
|
|
||||||
if (initTime < 0 || System.currentTimeMillis() - initTime > expiresAfterMs) {
|
|
||||||
content = producer()
|
|
||||||
}
|
|
||||||
|
|
||||||
content!!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
package exh.util
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads entire `JsonObject`s and `JsonArray`s from `JsonReader`s
|
|
||||||
*
|
|
||||||
* @author nulldev
|
|
||||||
*/
|
|
||||||
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import com.google.gson.JsonNull
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import com.google.gson.stream.JsonReader
|
|
||||||
import com.google.gson.stream.JsonToken
|
|
||||||
import java.math.BigDecimal
|
|
||||||
|
|
||||||
fun JsonReader.nextJsonObject(): JsonObject {
|
|
||||||
beginObject()
|
|
||||||
|
|
||||||
val obj = JsonObject()
|
|
||||||
|
|
||||||
while (hasNext()) {
|
|
||||||
val name = nextName()
|
|
||||||
|
|
||||||
when (peek()) {
|
|
||||||
JsonToken.BEGIN_ARRAY -> obj.add(name, nextJsonArray())
|
|
||||||
JsonToken.BEGIN_OBJECT -> obj.add(name, nextJsonObject())
|
|
||||||
JsonToken.NULL -> {
|
|
||||||
nextNull()
|
|
||||||
obj.add(name, JsonNull.INSTANCE)
|
|
||||||
}
|
|
||||||
JsonToken.BOOLEAN -> obj.addProperty(name, nextBoolean())
|
|
||||||
JsonToken.NUMBER -> obj.addProperty(name, BigDecimal(nextString()))
|
|
||||||
JsonToken.STRING -> obj.addProperty(name, nextString())
|
|
||||||
else -> skipValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
endObject()
|
|
||||||
|
|
||||||
return obj
|
|
||||||
}
|
|
||||||
|
|
||||||
fun JsonReader.nextJsonArray(): JsonArray {
|
|
||||||
beginArray()
|
|
||||||
|
|
||||||
val arr = JsonArray()
|
|
||||||
|
|
||||||
while (hasNext()) {
|
|
||||||
when (peek()) {
|
|
||||||
JsonToken.BEGIN_ARRAY -> arr.add(nextJsonArray())
|
|
||||||
JsonToken.BEGIN_OBJECT -> arr.add(nextJsonObject())
|
|
||||||
JsonToken.NULL -> {
|
|
||||||
nextNull()
|
|
||||||
arr.add(JsonNull.INSTANCE)
|
|
||||||
}
|
|
||||||
JsonToken.BOOLEAN -> arr.add(nextBoolean())
|
|
||||||
JsonToken.NUMBER -> arr.add(BigDecimal(nextString()))
|
|
||||||
JsonToken.STRING -> arr.add(nextString())
|
|
||||||
else -> skipValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
endArray()
|
|
||||||
|
|
||||||
return arr
|
|
||||||
}
|
|
@ -1,5 +1,11 @@
|
|||||||
package exh.util
|
package exh.util
|
||||||
|
|
||||||
fun Float.floor(): Int = kotlin.math.floor(this).toInt()
|
import kotlin.math.floor
|
||||||
|
|
||||||
fun Double.floor(): Int = kotlin.math.floor(this).toInt()
|
fun Float.floor(): Int = floor(this).toInt()
|
||||||
|
|
||||||
|
fun Double.floor(): Int = floor(this).toInt()
|
||||||
|
|
||||||
|
fun Int.nullIfZero() = if (this == 0) null else this
|
||||||
|
|
||||||
|
fun Long.nullIfZero() = if (this == 0L) null else this
|
||||||
|
@ -1,368 +0,0 @@
|
|||||||
package exh.util
|
|
||||||
|
|
||||||
import android.util.SparseArray
|
|
||||||
import java.util.AbstractMap
|
|
||||||
import java.util.LinkedList
|
|
||||||
|
|
||||||
class NakedTrieNode<T>(val key: Int, var parent: NakedTrieNode<T>?) {
|
|
||||||
val children = SparseArray<NakedTrieNode<T>>(1)
|
|
||||||
var hasData: Boolean = false
|
|
||||||
var data: T? = null
|
|
||||||
|
|
||||||
// Walks in ascending order
|
|
||||||
// Consumer should return true to continue walking, false to stop walking
|
|
||||||
inline fun walk(prefix: String, consumer: (String, T) -> Boolean, leavesOnly: Boolean) {
|
|
||||||
// Special case root
|
|
||||||
if (hasData && (!leavesOnly || children.size() <= 0)) {
|
|
||||||
if (!consumer(prefix, data!! as T)) return
|
|
||||||
}
|
|
||||||
|
|
||||||
val stack = LinkedList<Pair<String, NakedTrieNode<T>>>()
|
|
||||||
SparseArrayValueCollection(children, true).forEach {
|
|
||||||
stack += prefix + it.key.toChar() to it
|
|
||||||
}
|
|
||||||
while (!stack.isEmpty()) {
|
|
||||||
val (key, bottom) = stack.removeLast()
|
|
||||||
SparseArrayValueCollection(bottom.children, true).forEach {
|
|
||||||
stack += key + it.key.toChar() to it
|
|
||||||
}
|
|
||||||
if (bottom.hasData && (!leavesOnly || bottom.children.size() <= 0)) {
|
|
||||||
if (!consumer(key, bottom.data!! as T)) return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getAsNode(key: String): NakedTrieNode<T>? {
|
|
||||||
var current = this
|
|
||||||
for (c in key) {
|
|
||||||
current = current.children.get(c.toInt()) ?: return null
|
|
||||||
if (!current.hasData) return null
|
|
||||||
}
|
|
||||||
return current
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fast, memory efficient and flexible trie implementation with implementation details exposed
|
|
||||||
*/
|
|
||||||
class NakedTrie<T> : MutableMap<String, T> {
|
|
||||||
/**
|
|
||||||
* Returns the number of key/value pairs in the map.
|
|
||||||
*/
|
|
||||||
override var size: Int = 0
|
|
||||||
private set
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns `true` if the map is empty (contains no elements), `false` otherwise.
|
|
||||||
*/
|
|
||||||
override fun isEmpty() = size <= 0
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes all elements from this map.
|
|
||||||
*/
|
|
||||||
override fun clear() {
|
|
||||||
root.children.clear()
|
|
||||||
root.hasData = false
|
|
||||||
root.data = null
|
|
||||||
size = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
val root = NakedTrieNode<T>(-1, null)
|
|
||||||
private var version: Long = 0
|
|
||||||
|
|
||||||
override fun put(key: String, value: T): T? {
|
|
||||||
// Traverse to node location in tree, making parent nodes if required
|
|
||||||
var current = root
|
|
||||||
for (c in key) {
|
|
||||||
val castedC = c.toInt()
|
|
||||||
var node = current.children.get(castedC)
|
|
||||||
if (node == null) {
|
|
||||||
node = NakedTrieNode(castedC, current)
|
|
||||||
current.children.put(castedC, node)
|
|
||||||
}
|
|
||||||
current = node
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add data to node or replace existing data
|
|
||||||
val previous = if (current.hasData) {
|
|
||||||
current.data
|
|
||||||
} else {
|
|
||||||
current.hasData = true
|
|
||||||
size++
|
|
||||||
null
|
|
||||||
}
|
|
||||||
current.data = value
|
|
||||||
|
|
||||||
version++
|
|
||||||
|
|
||||||
return previous
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun get(key: String): T? {
|
|
||||||
val current = getAsNode(key) ?: return null
|
|
||||||
return if (current.hasData) current.data else null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getAsNode(key: String): NakedTrieNode<T>? {
|
|
||||||
return root.getAsNode(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun containsKey(key: String): Boolean {
|
|
||||||
var current = root
|
|
||||||
for (c in key) {
|
|
||||||
current = current.children.get(c.toInt()) ?: return false
|
|
||||||
if (!current.hasData) return false
|
|
||||||
}
|
|
||||||
return current.hasData
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the specified key and its corresponding value from this map.
|
|
||||||
*
|
|
||||||
* @return the previous value associated with the key, or `null` if the key was not present in the map.
|
|
||||||
*/
|
|
||||||
override fun remove(key: String): T? {
|
|
||||||
// Traverse node tree while keeping track of the nodes we have visited
|
|
||||||
val nodeStack = LinkedList<NakedTrieNode<T>>()
|
|
||||||
for (c in key) {
|
|
||||||
val bottomOfStack = nodeStack.last
|
|
||||||
val current = bottomOfStack.children.get(c.toInt()) ?: return null
|
|
||||||
if (!current.hasData) return null
|
|
||||||
nodeStack.add(bottomOfStack)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark node as having no data
|
|
||||||
val bottomOfStack = nodeStack.last
|
|
||||||
bottomOfStack.hasData = false
|
|
||||||
val oldData = bottomOfStack.data
|
|
||||||
bottomOfStack.data = null // Clear data field for GC
|
|
||||||
|
|
||||||
// Remove nodes that we visited that are useless
|
|
||||||
for (curBottom in nodeStack.descendingIterator()) {
|
|
||||||
val parent = curBottom.parent ?: break
|
|
||||||
if (!curBottom.hasData && curBottom.children.size() <= 0) {
|
|
||||||
// No data or child nodes, this node is useless, discard
|
|
||||||
parent.children.remove(curBottom.key)
|
|
||||||
} else break
|
|
||||||
}
|
|
||||||
|
|
||||||
version++
|
|
||||||
size--
|
|
||||||
|
|
||||||
return oldData
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates this map with key/value pairs from the specified map [from].
|
|
||||||
*/
|
|
||||||
override fun putAll(from: Map<out String, T>) {
|
|
||||||
// No way to optimize this so yeah...
|
|
||||||
from.forEach { (s, u) ->
|
|
||||||
put(s, u)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Walks in ascending order
|
|
||||||
// Consumer should return true to continue walking, false to stop walking
|
|
||||||
inline fun walk(consumer: (String, T) -> Boolean) {
|
|
||||||
walk(consumer, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Walks in ascending order
|
|
||||||
// Consumer should return true to continue walking, false to stop walking
|
|
||||||
inline fun walk(consumer: (String, T) -> Boolean, leavesOnly: Boolean) {
|
|
||||||
root.walk("", consumer, leavesOnly)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getOrPut(key: String, producer: () -> T): T {
|
|
||||||
// Traverse to node location in tree, making parent nodes if required
|
|
||||||
var current = root
|
|
||||||
for (c in key) {
|
|
||||||
val castedC = c.toInt()
|
|
||||||
var node = current.children.get(castedC)
|
|
||||||
if (node == null) {
|
|
||||||
node = NakedTrieNode(castedC, current)
|
|
||||||
current.children.put(castedC, node)
|
|
||||||
}
|
|
||||||
current = node
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add data to node or replace existing data
|
|
||||||
if (!current.hasData) {
|
|
||||||
current.hasData = true
|
|
||||||
current.data = producer()
|
|
||||||
size++
|
|
||||||
version++
|
|
||||||
}
|
|
||||||
|
|
||||||
return current.data!!
|
|
||||||
}
|
|
||||||
|
|
||||||
// Includes root
|
|
||||||
fun subMap(prefix: String, leavesOnly: Boolean = false): Map<String, T> {
|
|
||||||
val node = getAsNode(prefix) ?: return emptyMap()
|
|
||||||
|
|
||||||
return object : Map<String, T> {
|
|
||||||
/**
|
|
||||||
* Returns a read-only [Set] of all key/value pairs in this map.
|
|
||||||
*/
|
|
||||||
override val entries: Set<Map.Entry<String, T>>
|
|
||||||
get() {
|
|
||||||
val out = mutableSetOf<Map.Entry<String, T>>()
|
|
||||||
node.walk(
|
|
||||||
"",
|
|
||||||
{ k, v ->
|
|
||||||
out.add(AbstractMap.SimpleImmutableEntry(k, v))
|
|
||||||
true
|
|
||||||
},
|
|
||||||
leavesOnly
|
|
||||||
)
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns a read-only [Set] of all keys in this map.
|
|
||||||
*/
|
|
||||||
override val keys: Set<String>
|
|
||||||
get() {
|
|
||||||
val out = mutableSetOf<String>()
|
|
||||||
node.walk(
|
|
||||||
"",
|
|
||||||
{ k, _ ->
|
|
||||||
out.add(k)
|
|
||||||
true
|
|
||||||
},
|
|
||||||
leavesOnly
|
|
||||||
)
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the number of key/value pairs in the map.
|
|
||||||
*/
|
|
||||||
override val size: Int get() {
|
|
||||||
var s = 0
|
|
||||||
node.walk("", { _, _ -> s++; true }, leavesOnly)
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a read-only [Collection] of all values in this map. Note that this collection may contain duplicate values.
|
|
||||||
*/
|
|
||||||
override val values: Collection<T>
|
|
||||||
get() {
|
|
||||||
val out = mutableSetOf<T>()
|
|
||||||
node.walk(
|
|
||||||
"",
|
|
||||||
{ _, v ->
|
|
||||||
out.add(v)
|
|
||||||
true
|
|
||||||
},
|
|
||||||
leavesOnly
|
|
||||||
)
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns `true` if the map contains the specified [key].
|
|
||||||
*/
|
|
||||||
override fun containsKey(key: String): Boolean {
|
|
||||||
if (!key.startsWith(prefix)) return false
|
|
||||||
|
|
||||||
val childNode = node.getAsNode(key.removePrefix(prefix)) ?: return false
|
|
||||||
return childNode.hasData && (!leavesOnly || childNode.children.size() <= 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns `true` if the map maps one or more keys to the specified [value].
|
|
||||||
*/
|
|
||||||
override fun containsValue(value: T): Boolean {
|
|
||||||
node.walk(
|
|
||||||
"",
|
|
||||||
{ _, v ->
|
|
||||||
if (v == value) return true
|
|
||||||
true
|
|
||||||
},
|
|
||||||
leavesOnly
|
|
||||||
)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the value corresponding to the given [key], or `null` if such a key is not present in the map.
|
|
||||||
*/
|
|
||||||
override fun get(key: String): T? {
|
|
||||||
if (!key.startsWith(prefix)) return null
|
|
||||||
|
|
||||||
val childNode = node.getAsNode(key.removePrefix(prefix)) ?: return null
|
|
||||||
if (!childNode.hasData || (leavesOnly && childNode.children.size() > 0)) return null
|
|
||||||
return childNode.data
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns `true` if the map is empty (contains no elements), `false` otherwise.
|
|
||||||
*/
|
|
||||||
override fun isEmpty(): Boolean {
|
|
||||||
if (node.children.size() <= 0 && !root.hasData) return true
|
|
||||||
if (!leavesOnly) return false
|
|
||||||
node.walk("", { _, _ -> return false }, leavesOnly)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Slow methods below
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns `true` if the map maps one or more keys to the specified [value].
|
|
||||||
*/
|
|
||||||
override fun containsValue(value: T): Boolean {
|
|
||||||
walk { _, t ->
|
|
||||||
if (t == value) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a [MutableSet] of all key/value pairs in this map.
|
|
||||||
*/
|
|
||||||
override val entries: MutableSet<MutableMap.MutableEntry<String, T>>
|
|
||||||
get() = FakeMutableSet.fromSet(
|
|
||||||
mutableSetOf<MutableMap.MutableEntry<String, T>>().apply {
|
|
||||||
walk { k, v ->
|
|
||||||
this += FakeMutableEntry.fromPair(k, v)
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a [MutableSet] of all keys in this map.
|
|
||||||
*/
|
|
||||||
override val keys: MutableSet<String>
|
|
||||||
get() = FakeMutableSet.fromSet(
|
|
||||||
mutableSetOf<String>().apply {
|
|
||||||
walk { k, _ ->
|
|
||||||
this += k
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a [MutableCollection] of all values in this map. Note that this collection may contain duplicate values.
|
|
||||||
*/
|
|
||||||
override val values: MutableCollection<T>
|
|
||||||
get() = FakeMutableCollection.fromCollection(
|
|
||||||
mutableListOf<T>().apply {
|
|
||||||
walk { _, v ->
|
|
||||||
this += v
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
@ -14,7 +14,7 @@ private val galleryAdder by lazy {
|
|||||||
/**
|
/**
|
||||||
* A version of fetchSearchManga that supports URL importing
|
* A version of fetchSearchManga that supports URL importing
|
||||||
*/
|
*/
|
||||||
fun UrlImportableSource.urlImportFetchSearchManga(context: Context, query: String, fail: () -> Observable<MangasPage>) =
|
fun UrlImportableSource.urlImportFetchSearchManga(context: Context, query: String, fail: () -> Observable<MangasPage>): Observable<MangasPage> =
|
||||||
when {
|
when {
|
||||||
query.startsWith("http://") || query.startsWith("https://") -> {
|
query.startsWith("http://") || query.startsWith("https://") -> {
|
||||||
Observable.fromCallable {
|
Observable.fromCallable {
|
||||||
|
@ -10,7 +10,7 @@ import exh.metadata.metadata.base.RaisedTag
|
|||||||
import exh.nHentaiSourceIds
|
import exh.nHentaiSourceIds
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
class SourceTagsUtil {
|
object SourceTagsUtil {
|
||||||
fun getWrappedTag(sourceId: Long, namespace: String? = null, tag: String? = null, fullTag: String? = null): String? {
|
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 in nHentaiSourceIds || sourceId in hitomiSourceIds) {
|
return if (sourceId == EXH_SOURCE_ID || sourceId == EH_SOURCE_ID || sourceId in nHentaiSourceIds || sourceId in hitomiSourceIds) {
|
||||||
val parsed = if (fullTag != null) parseTag(fullTag) else if (namespace != null && tag != null) RaisedTag(namespace, tag, TAG_TYPE_DEFAULT) else null
|
val parsed = if (fullTag != null) parseTag(fullTag) else if (namespace != null && tag != null) RaisedTag(namespace, tag, TAG_TYPE_DEFAULT) else null
|
||||||
@ -47,52 +47,53 @@ class SourceTagsUtil {
|
|||||||
} else {
|
} else {
|
||||||
"$namespace:$tag"
|
"$namespace:$tag"
|
||||||
}
|
}
|
||||||
companion object {
|
|
||||||
fun Manga.getRaisedTags(genres: List<String>? = null): List<RaisedTag>? = (genres ?: this.getGenres())?.map { parseTag(it) }
|
|
||||||
|
|
||||||
fun parseTag(tag: String) = RaisedTag(
|
fun parseTag(tag: String) = RaisedTag(
|
||||||
(
|
(
|
||||||
if (tag.startsWith("-")) {
|
if (tag.startsWith("-")) {
|
||||||
tag.substringAfter("-")
|
tag.substringAfter("-")
|
||||||
} else {
|
} else {
|
||||||
tag
|
tag
|
||||||
}
|
}
|
||||||
).substringBefore(':', missingDelimiterValue = "").trimOrNull(),
|
).substringBefore(':', missingDelimiterValue = "").trimOrNull(),
|
||||||
tag.substringAfter(':', missingDelimiterValue = tag).trim(),
|
tag.substringAfter(':', missingDelimiterValue = tag).trim(),
|
||||||
if (tag.startsWith("-")) TAG_TYPE_EXCLUDE else TAG_TYPE_DEFAULT
|
if (tag.startsWith("-")) TAG_TYPE_EXCLUDE else TAG_TYPE_DEFAULT
|
||||||
)
|
)
|
||||||
|
|
||||||
const val TAG_TYPE_EXCLUDE = 69 // why not
|
const val TAG_TYPE_EXCLUDE = 69 // why not
|
||||||
|
|
||||||
const val DOUJINSHI_COLOR = "#f44336"
|
const val DOUJINSHI_COLOR = "#f44336"
|
||||||
const val MANGA_COLOR = "#ff9800"
|
const val MANGA_COLOR = "#ff9800"
|
||||||
const val ARTIST_CG_COLOR = "#fbc02d"
|
const val ARTIST_CG_COLOR = "#fbc02d"
|
||||||
const val GAME_CG_COLOR = "#4caf50"
|
const val GAME_CG_COLOR = "#4caf50"
|
||||||
const val WESTERN_COLOR = "#8bc34a"
|
const val WESTERN_COLOR = "#8bc34a"
|
||||||
const val NON_H_COLOR = "#2196f3"
|
const val NON_H_COLOR = "#2196f3"
|
||||||
const val IMAGE_SET_COLOR = "#3f51b5"
|
const val IMAGE_SET_COLOR = "#3f51b5"
|
||||||
const val COSPLAY_COLOR = "#9c27b0"
|
const val COSPLAY_COLOR = "#9c27b0"
|
||||||
const val ASIAN_PORN_COLOR = "#9575cd"
|
const val ASIAN_PORN_COLOR = "#9575cd"
|
||||||
const val MISC_COLOR = "#f06292"
|
const val MISC_COLOR = "#f06292"
|
||||||
|
|
||||||
fun getLocaleSourceUtil(language: String?) = when (language) {
|
fun getLocaleSourceUtil(language: String?) = when (language) {
|
||||||
"english", "eng" -> Locale("en")
|
"english", "eng" -> Locale("en")
|
||||||
"chinese" -> Locale("zh")
|
"chinese" -> Locale("zh")
|
||||||
"spanish" -> Locale("es")
|
"spanish" -> Locale("es")
|
||||||
"korean" -> Locale("ko")
|
"korean" -> Locale("ko")
|
||||||
"russian" -> Locale("ru")
|
"russian" -> Locale("ru")
|
||||||
"french" -> Locale("fr")
|
"french" -> Locale("fr")
|
||||||
"portuguese" -> Locale("pt")
|
"portuguese" -> Locale("pt")
|
||||||
"thai" -> Locale("th")
|
"thai" -> Locale("th")
|
||||||
"german" -> Locale("de")
|
"german" -> Locale("de")
|
||||||
"italian" -> Locale("it")
|
"italian" -> Locale("it")
|
||||||
"vietnamese" -> Locale("vi")
|
"vietnamese" -> Locale("vi")
|
||||||
"polish" -> Locale("pl")
|
"polish" -> Locale("pl")
|
||||||
"hungarian" -> Locale("hu")
|
"hungarian" -> Locale("hu")
|
||||||
"dutch" -> Locale("nl")
|
"dutch" -> Locale("nl")
|
||||||
else -> null
|
else -> null
|
||||||
}
|
|
||||||
|
|
||||||
private const val TAG_TYPE_DEFAULT = 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const val TAG_TYPE_DEFAULT = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Manga.getRaisedTags(genres: List<String>? = null): List<RaisedTag>? = (genres ?: this.getGenres())?.map {
|
||||||
|
SourceTagsUtil.parseTag(it)
|
||||||
}
|
}
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
package exh.util
|
|
||||||
|
|
||||||
import android.util.SparseArray
|
|
||||||
import java.util.AbstractMap
|
|
||||||
|
|
||||||
class SparseArrayKeyCollection(val sparseArray: SparseArray<out Any?>, var reverse: Boolean = false) : AbstractCollection<Int>() {
|
|
||||||
override val size get() = sparseArray.size()
|
|
||||||
|
|
||||||
override fun iterator() = object : Iterator<Int> {
|
|
||||||
private var index: Int = 0
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns `true` if the iteration has more elements.
|
|
||||||
*/
|
|
||||||
override fun hasNext() = index < sparseArray.size()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the next element in the iteration.
|
|
||||||
*/
|
|
||||||
override fun next(): Int {
|
|
||||||
var idx = index++
|
|
||||||
if (reverse) idx = sparseArray.size() - 1 - idx
|
|
||||||
return sparseArray.keyAt(idx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SparseArrayValueCollection<E>(val sparseArray: SparseArray<E>, var reverse: Boolean = false) : AbstractCollection<E>() {
|
|
||||||
override val size get() = sparseArray.size()
|
|
||||||
|
|
||||||
override fun iterator() = object : Iterator<E> {
|
|
||||||
private var index: Int = 0
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns `true` if the iteration has more elements.
|
|
||||||
*/
|
|
||||||
override fun hasNext() = index < sparseArray.size()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the next element in the iteration.
|
|
||||||
*/
|
|
||||||
override fun next(): E {
|
|
||||||
var idx = index++
|
|
||||||
if (reverse) idx = sparseArray.size() - 1 - idx
|
|
||||||
return sparseArray.valueAt(idx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SparseArrayCollection<E>(val sparseArray: SparseArray<E>, var reverse: Boolean = false) : AbstractCollection<Map.Entry<Int, E>>() {
|
|
||||||
override val size get() = sparseArray.size()
|
|
||||||
|
|
||||||
override fun iterator() = object : Iterator<Map.Entry<Int, E>> {
|
|
||||||
private var index: Int = 0
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns `true` if the iteration has more elements.
|
|
||||||
*/
|
|
||||||
override fun hasNext() = index < sparseArray.size()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the next element in the iteration.
|
|
||||||
*/
|
|
||||||
override fun next(): Map.Entry<Int, E> {
|
|
||||||
var idx = index++
|
|
||||||
if (reverse) idx = sparseArray.size() - 1 - idx
|
|
||||||
return AbstractMap.SimpleImmutableEntry(
|
|
||||||
sparseArray.keyAt(idx),
|
|
||||||
sparseArray.valueAt(idx)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,9 +5,7 @@ import com.google.android.material.chip.Chip
|
|||||||
import com.google.android.material.chip.ChipGroup
|
import com.google.android.material.chip.ChipGroup
|
||||||
import exh.EH_SOURCE_ID
|
import exh.EH_SOURCE_ID
|
||||||
import exh.EXH_SOURCE_ID
|
import exh.EXH_SOURCE_ID
|
||||||
import exh.metadata.metadata.EHentaiSearchMetadata.Companion.TAG_TYPE_LIGHT
|
import exh.metadata.metadata.EHentaiSearchMetadata
|
||||||
import exh.metadata.metadata.EHentaiSearchMetadata.Companion.TAG_TYPE_NORMAL
|
|
||||||
import exh.metadata.metadata.EHentaiSearchMetadata.Companion.TAG_TYPE_WEAK
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replaces chips in a ChipGroup.
|
* Replaces chips in a ChipGroup.
|
||||||
@ -29,7 +27,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, type: Int? = 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 {
|
return Chip(context).apply {
|
||||||
text = item
|
text = item
|
||||||
val search = (if (namespace != null) SourceTagsUtil().getWrappedTag(sourceId, namespace = namespace, tag = item) else SourceTagsUtil().getWrappedTag(sourceId, fullTag = item)) ?: item
|
val search = (if (namespace != null) SourceTagsUtil.getWrappedTag(sourceId, namespace = namespace, tag = item) else SourceTagsUtil.getWrappedTag(sourceId, fullTag = item)) ?: item
|
||||||
setOnClickListener { onClick(search) }
|
setOnClickListener { onClick(search) }
|
||||||
setOnLongClickListener {
|
setOnLongClickListener {
|
||||||
onLongClick(search)
|
onLongClick(search)
|
||||||
@ -37,9 +35,9 @@ fun makeSearchChip(item: String, onClick: (item: String) -> Unit = {}, onLongCli
|
|||||||
}
|
}
|
||||||
if (sourceId == EXH_SOURCE_ID || sourceId == EH_SOURCE_ID) {
|
if (sourceId == EXH_SOURCE_ID || sourceId == EH_SOURCE_ID) {
|
||||||
chipStrokeWidth = when (type) {
|
chipStrokeWidth = when (type) {
|
||||||
TAG_TYPE_NORMAL -> 5F
|
EHentaiSearchMetadata.TAG_TYPE_NORMAL -> 5F
|
||||||
TAG_TYPE_LIGHT -> 3F
|
EHentaiSearchMetadata.TAG_TYPE_LIGHT -> 3F
|
||||||
TAG_TYPE_WEAK -> 0F
|
EHentaiSearchMetadata.TAG_TYPE_WEAK -> 0F
|
||||||
else -> chipStrokeWidth
|
else -> chipStrokeWidth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
package exh.util
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
|
|
||||||
fun dpToPx(context: Context, dp: Int): Int {
|
|
||||||
val scale = context.resources.displayMetrics.density
|
|
||||||
return (dp * scale + 0.5f).toInt()
|
|
||||||
}
|
|
@ -10,10 +10,11 @@ import com.afollestad.materialdialogs.customview.customView
|
|||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.source.online.all.MangaDex
|
import eu.kanade.tachiyomi.source.online.all.MangaDex
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import eu.kanade.tachiyomi.widget.preference.LoginDialogPreference
|
import eu.kanade.tachiyomi.widget.preference.LoginDialogPreference
|
||||||
import exh.md.utils.MdUtil
|
import exh.source.getMainSource
|
||||||
import kotlinx.android.synthetic.main.pref_site_login_two_factor_auth.view.login
|
import kotlinx.android.synthetic.main.pref_site_login_two_factor_auth.view.login
|
||||||
import kotlinx.android.synthetic.main.pref_site_login_two_factor_auth.view.password
|
import kotlinx.android.synthetic.main.pref_site_login_two_factor_auth.view.password
|
||||||
import kotlinx.android.synthetic.main.pref_site_login_two_factor_auth.view.two_factor_check
|
import kotlinx.android.synthetic.main.pref_site_login_two_factor_auth.view.two_factor_check
|
||||||
@ -29,7 +30,7 @@ import uy.kohesive.injekt.api.get
|
|||||||
|
|
||||||
class MangadexLoginDialog(bundle: Bundle? = null) : LoginDialogPreference(bundle = bundle) {
|
class MangadexLoginDialog(bundle: Bundle? = null) : LoginDialogPreference(bundle = bundle) {
|
||||||
|
|
||||||
val source by lazy { MdUtil.getEnabledMangaDex() }
|
val source = Injekt.get<SourceManager>().get(args.getLong("key", 0))?.getMainSource() as? MangaDex
|
||||||
|
|
||||||
val service = Injekt.get<TrackManager>().mdList
|
val service = Injekt.get<TrackManager>().mdList
|
||||||
|
|
||||||
|
@ -7,17 +7,21 @@ import com.afollestad.materialdialogs.MaterialDialog
|
|||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
|
import eu.kanade.tachiyomi.source.online.all.MangaDex
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||||
import eu.kanade.tachiyomi.util.lang.launchNow
|
import eu.kanade.tachiyomi.util.lang.launchNow
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import exh.md.utils.MdUtil
|
import exh.source.getMainSource
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
class MangadexLogoutDialog(bundle: Bundle? = null) : DialogController(bundle) {
|
class MangadexLogoutDialog(bundle: Bundle? = null) : DialogController(bundle) {
|
||||||
|
|
||||||
val source by lazy { MdUtil.getEnabledMangaDex() }
|
val source = Injekt.get<SourceManager>().get(args.getLong("key", 0))?.getMainSource() as? MangaDex
|
||||||
|
|
||||||
val trackManager: TrackManager by injectLazy()
|
val trackManager: TrackManager by injectLazy()
|
||||||
|
|
||||||
|
@ -1,93 +0,0 @@
|
|||||||
package org.vepta.vdm
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple cursor for use on byte arrays
|
|
||||||
* @author nulldev
|
|
||||||
*/
|
|
||||||
class ByteCursor(val content: ByteArray) {
|
|
||||||
var index = -1
|
|
||||||
private set
|
|
||||||
private var mark = -1
|
|
||||||
|
|
||||||
fun mark() {
|
|
||||||
mark = index
|
|
||||||
}
|
|
||||||
|
|
||||||
fun jumpToMark() {
|
|
||||||
index = mark
|
|
||||||
}
|
|
||||||
|
|
||||||
fun jumpToIndex(index: Int) {
|
|
||||||
this.index = index
|
|
||||||
}
|
|
||||||
|
|
||||||
fun next(): Byte {
|
|
||||||
return content[++index]
|
|
||||||
}
|
|
||||||
|
|
||||||
fun next(count: Int): ByteArray {
|
|
||||||
val res = content.sliceArray(index + 1..index + count)
|
|
||||||
skip(count)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// Used to perform conversions
|
|
||||||
private fun byteBuffer(count: Int): ByteBuffer {
|
|
||||||
return ByteBuffer.wrap(next(count))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Epic hack to get an unsigned short properly...
|
|
||||||
fun fakeNextShortInt(): Int = ByteBuffer
|
|
||||||
.wrap(arrayOf(0x00, 0x00, *next(2).toTypedArray()).toByteArray())
|
|
||||||
.getInt(0)
|
|
||||||
|
|
||||||
// fun nextShort(): Short = byteBuffer(2).getShort(0)
|
|
||||||
fun nextInt(): Int = byteBuffer(4).getInt(0)
|
|
||||||
fun nextLong(): Long = byteBuffer(8).getLong(0)
|
|
||||||
fun nextFloat(): Float = byteBuffer(4).getFloat(0)
|
|
||||||
fun nextDouble(): Double = byteBuffer(8).getDouble(0)
|
|
||||||
|
|
||||||
fun skip(count: Int) {
|
|
||||||
index += count
|
|
||||||
}
|
|
||||||
|
|
||||||
fun expect(vararg bytes: Byte) {
|
|
||||||
if (bytes.size > remaining()) {
|
|
||||||
throw IllegalStateException("Unexpected end of content!")
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i in 0..bytes.lastIndex) {
|
|
||||||
val expected = bytes[i]
|
|
||||||
val actual = content[index + i + 1]
|
|
||||||
|
|
||||||
if (expected != actual) {
|
|
||||||
throw IllegalStateException("Unexpected content (expected: $expected, actual: $actual)!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
index += bytes.size
|
|
||||||
}
|
|
||||||
|
|
||||||
fun checkEqual(vararg bytes: Byte): Boolean {
|
|
||||||
if (bytes.size > remaining()) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i in 0..bytes.lastIndex) {
|
|
||||||
val expected = bytes[i]
|
|
||||||
val actual = content[index + i + 1]
|
|
||||||
|
|
||||||
if (expected != actual) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
fun atEnd() = index >= content.size - 1
|
|
||||||
|
|
||||||
fun remaining() = content.size - index - 1
|
|
||||||
}
|
|
@ -34,20 +34,18 @@ class FilterSerializer {
|
|||||||
)
|
)
|
||||||
|
|
||||||
fun serialize(filters: FilterList) = buildJsonArray {
|
fun serialize(filters: FilterList) = buildJsonArray {
|
||||||
filters.forEach {
|
filters.filterIsInstance<Filter<Any?>>().forEach {
|
||||||
@Suppress("UNCHECKED_CAST")
|
add(serialize(it))
|
||||||
add(serialize(it as Filter<Any?>))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun serialize(filter: Filter<Any?>): JsonObject {
|
fun serialize(filter: Filter<Any?>): JsonObject {
|
||||||
for (serializer in serializers) {
|
return serializers
|
||||||
if (filter::class.isSubclassOf(serializer.clazz)) {
|
.filterIsInstance<Serializer<Filter<Any?>>>()
|
||||||
// TODO Not sure how to deal with the mess of types here
|
.firstOrNull {
|
||||||
@Suppress("UNCHECKED_CAST")
|
filter::class.isSubclassOf(it.clazz)
|
||||||
serializer as Serializer<Filter<Any?>>
|
}?.let { serializer ->
|
||||||
|
buildJsonObject {
|
||||||
return buildJsonObject {
|
|
||||||
with(serializer) { serialize(filter) }
|
with(serializer) { serialize(filter) }
|
||||||
|
|
||||||
val classMappings = mutableListOf<Pair<String, Any>>()
|
val classMappings = mutableListOf<Pair<String, Any>>()
|
||||||
@ -66,26 +64,21 @@ class FilterSerializer {
|
|||||||
|
|
||||||
put(TYPE, serializer.type)
|
put(TYPE, serializer.type)
|
||||||
}
|
}
|
||||||
}
|
} ?: throw IllegalArgumentException("Cannot serialize this Filter object!")
|
||||||
}
|
|
||||||
throw IllegalArgumentException("Cannot serialize this Filter object!")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserialize(filters: FilterList, json: JsonArray) {
|
fun deserialize(filters: FilterList, json: JsonArray) {
|
||||||
filters.zip(json).forEach { (filter, obj) ->
|
filters.filterIsInstance<Filter<Any?>>().zip(json).forEach { (filter, obj) ->
|
||||||
@Suppress("UNCHECKED_CAST")
|
deserialize(filter, obj.jsonObject)
|
||||||
deserialize(filter as Filter<Any?>, obj.jsonObject)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserialize(filter: Filter<Any?>, json: JsonObject) {
|
fun deserialize(filter: Filter<Any?>, json: JsonObject) {
|
||||||
val serializer = serializers.find {
|
val serializer = serializers
|
||||||
it.type == json[TYPE]!!.jsonPrimitive.content
|
.filterIsInstance<Serializer<Filter<Any?>>>()
|
||||||
} ?: throw IllegalArgumentException("Cannot deserialize this type!")
|
.firstOrNull {
|
||||||
|
it.type == json[TYPE]!!.jsonPrimitive.content
|
||||||
// TODO Not sure how to deal with the mess of types here
|
} ?: throw IllegalArgumentException("Cannot deserialize this type!")
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
serializer as Serializer<Filter<Any?>>
|
|
||||||
|
|
||||||
serializer.deserialize(json, filter)
|
serializer.deserialize(json, filter)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user