From b702603965044cfe3ee852f8d0c970b6eb93b97a Mon Sep 17 00:00:00 2001 From: NarwhalHorns Date: Thu, 6 Mar 2025 08:21:05 +0000 Subject: [PATCH] Display staff information on Anilist tracker search results (#1810) Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com> --- CHANGELOG.md | 1 + .../presentation/track/TrackerSearch.kt | 9 ++++++ .../track/TrackerSearchPreviewProvider.kt | 4 +++ .../data/track/anilist/AnilistApi.kt | 26 ++++++++++++++++ .../data/track/anilist/dto/ALManga.kt | 6 ++++ .../data/track/anilist/dto/ALSearchItem.kt | 30 +++++++++++++++++++ .../tachiyomi/data/track/model/TrackSearch.kt | 4 +++ 7 files changed, 80 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68469d128..4e4c26392 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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)) diff --git a/app/src/main/java/eu/kanade/presentation/track/TrackerSearch.kt b/app/src/main/java/eu/kanade/presentation/track/TrackerSearch.kt index 61fa61667..67c919c07 100644 --- a/app/src/main/java/eu/kanade/presentation/track/TrackerSearch.kt +++ b/app/src/main/java/eu/kanade/presentation/track/TrackerSearch.kt @@ -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), diff --git a/app/src/main/java/eu/kanade/presentation/track/TrackerSearchPreviewProvider.kt b/app/src/main/java/eu/kanade/presentation/track/TrackerSearchPreviewProvider.kt index 477589c89..11a5c8dcc 100644 --- a/app/src/main/java/eu/kanade/presentation/track/TrackerSearchPreviewProvider.kt +++ b/app/src/main/java/eu/kanade/presentation/track/TrackerSearchPreviewProvider.kt @@ -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 = (0..(0..3).random()).map { lorem((3..5).random()).joinToString() } + private fun lorem(words: Int): Sequence = LoremIpsum(words).values } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt index 4d4c630f9..0cac9bed9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt @@ -140,6 +140,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 |} @@ -220,6 +233,19 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) { |month |day |} + |staff { + |edges { + |role + |id + |node { + |name { + |full + |userPreferred + |native + |} + |} + |} + |} |} |} |} diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/dto/ALManga.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/dto/ALManga.kt index 5c69381ce..9eedf22c4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/dto/ALManga.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/dto/ALManga.kt @@ -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 + } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/dto/ALSearchItem.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/dto/ALSearchItem.kt index 98db89e04..610900816 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/dto/ALSearchItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/dto/ALSearchItem.kt @@ -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, +) + +@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 + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/model/TrackSearch.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/model/TrackSearch.kt index 5f44e9aa2..763f1f903 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/model/TrackSearch.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/model/TrackSearch.kt @@ -34,6 +34,10 @@ class TrackSearch : Track { override lateinit var tracking_url: String + var authors: List = emptyList() + + var artists: List = emptyList() + var cover_url: String = "" var summary: String = ""