Display staff information on Anilist tracker search results (mihonapp/mihon#1810)
Co-authored-by: Cuong-Tran <cuongtran.tm@gmail.com> Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com> (cherry picked from commit b702603965044cfe3ee852f8d0c970b6eb93b97a)
This commit is contained in:
parent
9183c19cd2
commit
7d1ee6c587
8 changed files with 87 additions and 22 deletions
|
|
@ -21,6 +21,7 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co
|
|||
- Add option to export minimal library information to a CSV file ([@Animeboynz](https://github.com/Animeboynz), [@AntsyLich](https://github.com/AntsyLich)) ([#1161](https://github.com/mihonapp/mihon/pull/1161))
|
||||
- Add back support for drag-and-drop category reordering ([@cuong-tran](https://github.com/cuong-tran)) ([#1427](https://github.com/mihonapp/mihon/pull/1427))
|
||||
- Add option to mark new duplicate read chapters as read
|
||||
- Display staff information on Anilist tracker search results ([@NarwhalHorns](https://github.com/NarwhalHorns)) ([#1810](https://github.com/mihonapp/mihon/pull/1810))
|
||||
|
||||
### Changed
|
||||
- Apply "Downloaded only" filter to all entries regardless of favourite status ([@NGB-Was-Taken](https://github.com/NGB-Was-Taken)) ([#1603](https://github.com/mihonapp/mihon/pull/1603))
|
||||
|
|
|
|||
|
|
@ -304,6 +304,15 @@ private fun SearchResultItem(
|
|||
}
|
||||
},
|
||||
)
|
||||
if (trackSearch.authors.isNotEmpty() || trackSearch.artists.isNotEmpty()) {
|
||||
Text(
|
||||
text = (trackSearch.authors + trackSearch.artists).distinct().joinToString(),
|
||||
modifier = Modifier.secondaryItemAlpha(),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
)
|
||||
}
|
||||
if (type.isNotBlank()) {
|
||||
SearchResultItemDetails(
|
||||
title = stringResource(MR.strings.track_type),
|
||||
|
|
|
|||
|
|
@ -97,9 +97,13 @@ internal class TrackerSearchPreviewProvider : PreviewParameterProvider<@Composab
|
|||
it.summary = lorem((0..40).random()).joinToString()
|
||||
it.publishing_status = if (Random.nextBoolean()) "Finished" else ""
|
||||
it.publishing_type = if (Random.nextBoolean()) "Oneshot" else ""
|
||||
it.artists = randomNames()
|
||||
it.authors = randomNames()
|
||||
it
|
||||
}
|
||||
|
||||
private fun randomNames(): List<String> = (0..(0..3).random()).map { lorem((3..5).random()).joinToString() }
|
||||
|
||||
private fun lorem(words: Int): Sequence<String> =
|
||||
LoremIpsum(words).values
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,6 +143,19 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
|||
|Page (perPage: 50) {
|
||||
|media(search: ${'$'}query, type: MANGA, format_not_in: [NOVEL]) {
|
||||
|id
|
||||
|staff {
|
||||
|edges {
|
||||
|role
|
||||
|id
|
||||
|node {
|
||||
|name {
|
||||
|full
|
||||
|userPreferred
|
||||
|native
|
||||
|}
|
||||
|}
|
||||
|}
|
||||
|}
|
||||
|title {
|
||||
|userPreferred
|
||||
|}
|
||||
|
|
@ -223,6 +236,19 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
|||
|month
|
||||
|day
|
||||
|}
|
||||
|staff {
|
||||
|edges {
|
||||
|role
|
||||
|id
|
||||
|node {
|
||||
|name {
|
||||
|full
|
||||
|userPreferred
|
||||
|native
|
||||
|}
|
||||
|}
|
||||
|}
|
||||
|}
|
||||
|}
|
||||
|}
|
||||
|}
|
||||
|
|
@ -310,9 +336,12 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
|||
|staff {
|
||||
|edges {
|
||||
|role
|
||||
|id
|
||||
|node {
|
||||
|name {
|
||||
|full
|
||||
|userPreferred
|
||||
|native
|
||||
|}
|
||||
|}
|
||||
|}
|
||||
|
|
@ -345,15 +374,13 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
|||
description = media.description?.htmlDecode()?.ifEmpty { null },
|
||||
authors = media.staff.edges
|
||||
.filter { it.role == "Story" || it.role == "Story & Art" }
|
||||
// KMK -->
|
||||
.joinToString(", ") { it.node.name.userPreferred }
|
||||
// KMK <--
|
||||
.mapNotNull { it.node.name.userPreferred }
|
||||
.joinToString(", ")
|
||||
.ifEmpty { null },
|
||||
artists = media.staff.edges
|
||||
.filter { it.role == "Art" || it.role == "Story & Art" }
|
||||
// KMK -->
|
||||
.joinToString(", ") { it.node.name.userPreferred }
|
||||
// KMK <--
|
||||
.mapNotNull { it.node.name.userPreferred }
|
||||
.joinToString(", ")
|
||||
.ifEmpty { null },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ data class ALManga(
|
|||
val startDateFuzzy: Long,
|
||||
val totalChapters: Long,
|
||||
val averageScore: Int,
|
||||
val staff: ALStaff,
|
||||
) {
|
||||
fun toTrack() = TrackSearch.create(TrackerManager.ANILIST).apply {
|
||||
remote_id = remoteId
|
||||
|
|
@ -38,6 +39,11 @@ data class ALManga(
|
|||
""
|
||||
}
|
||||
}
|
||||
staff.edges.forEach {
|
||||
val name = it.node.name() ?: return@forEach
|
||||
if ("Story" in it.role) authors += name
|
||||
if ("Art" in it.role) artists += name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,19 +22,3 @@ data class ALMangaMetadataMedia(
|
|||
val description: String?,
|
||||
val staff: ALStaff,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class ALStaff(
|
||||
val edges: List<ALStaffEdge>,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class ALStaffEdge(
|
||||
val role: String,
|
||||
val node: ALStaffNode,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class ALStaffNode(
|
||||
val name: ALItemTitle,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ data class ALSearchItem(
|
|||
val startDate: ALFuzzyDate,
|
||||
val chapters: Long?,
|
||||
val averageScore: Int?,
|
||||
val staff: ALStaff,
|
||||
) {
|
||||
fun toALManga(): ALManga = ALManga(
|
||||
remoteId = id,
|
||||
|
|
@ -24,6 +25,7 @@ data class ALSearchItem(
|
|||
startDateFuzzy = startDate.toEpochMilli(),
|
||||
totalChapters = chapters ?: 0,
|
||||
averageScore = averageScore ?: -1,
|
||||
staff = staff,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -36,3 +38,31 @@ data class ALItemTitle(
|
|||
data class ItemCover(
|
||||
val large: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class ALStaff(
|
||||
val edges: List<ALEdge>,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class ALEdge(
|
||||
val role: String,
|
||||
val id: Int,
|
||||
val node: ALStaffNode,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class ALStaffNode(
|
||||
val name: ALStaffName,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class ALStaffName(
|
||||
val userPreferred: String?,
|
||||
val native: String?,
|
||||
val full: String?,
|
||||
) {
|
||||
operator fun invoke(): String? {
|
||||
return userPreferred ?: full ?: native
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,10 @@ class TrackSearch : Track {
|
|||
|
||||
override lateinit var tracking_url: String
|
||||
|
||||
var authors: List<String> = emptyList()
|
||||
|
||||
var artists: List<String> = emptyList()
|
||||
|
||||
var cover_url: String = ""
|
||||
|
||||
var summary: String = ""
|
||||
|
|
|
|||
Loading…
Reference in a new issue