MAL: add way to search by list items' titles

This commit is contained in:
arkon 2021-01-04 14:30:04 -05:00
parent d8a3692d92
commit 8a792e6d76
2 changed files with 58 additions and 22 deletions

View File

@ -22,6 +22,7 @@ class MyAnimeList(private val context: Context, id: Int) : TrackService(id) {
const val REREADING = 7 const val REREADING = 7
private const val SEARCH_ID_PREFIX = "id:" private const val SEARCH_ID_PREFIX = "id:"
private const val SEARCH_LIST_PREFIX = "my:"
} }
private val json: Json by injectLazy() private val json: Json by injectLazy()
@ -88,6 +89,12 @@ class MyAnimeList(private val context: Context, id: Int) : TrackService(id) {
} }
} }
if (query.startsWith(SEARCH_LIST_PREFIX)) {
query.substringAfter(SEARCH_LIST_PREFIX).let { title ->
return api.findListItems(title)
}
}
return api.search(query) return api.search(query)
} }

View File

@ -164,6 +164,56 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
} }
suspend fun findListItem(track: Track, offset: Int = 0): Track? { suspend fun findListItem(track: Track, offset: Int = 0): Track? {
val json = getListPage(offset)
val obj = json.jsonObject
val trackedManga = obj["data"]!!.jsonArray.find { data ->
data.jsonObject["node"]!!.jsonObject["id"]!!.jsonPrimitive.int == track.media_id
}
return when {
// Found the item in the list
trackedManga != null -> {
parseMangaItem(trackedManga.jsonObject["list_status"]!!.jsonObject, track)
}
// Check next page if there's more
!obj["paging"]!!.jsonObject["next"]?.jsonPrimitive?.contentOrNull.isNullOrBlank() -> {
findListItem(track, offset + listPaginationAmount)
}
// No more pages to check, item wasn't found
else -> {
null
}
}
}
suspend fun findListItems(query: String, offset: Int = 0): List<TrackSearch> {
return withContext(Dispatchers.IO) {
val json = getListPage(offset)
val obj = json.jsonObject
val matches = obj["data"]!!.jsonArray
.filter {
it.jsonObject["node"]!!.jsonObject["title"]!!.jsonPrimitive.content.contains(
query,
ignoreCase = true
)
}
.map {
val id = it.jsonObject["node"]!!.jsonObject["id"]!!.jsonPrimitive.int
async { getMangaDetails(id) }
}
.awaitAll()
// Check next page if there's more
if (!obj["paging"]!!.jsonObject["next"]?.jsonPrimitive?.contentOrNull.isNullOrBlank()) {
matches + findListItems(query, offset + listPaginationAmount)
} else {
matches
}
}
}
private suspend fun getListPage(offset: Int): JsonObject {
return withContext(Dispatchers.IO) { return withContext(Dispatchers.IO) {
val urlBuilder = "$baseApiUrl/users/@me/mangalist".toUri().buildUpon() val urlBuilder = "$baseApiUrl/users/@me/mangalist".toUri().buildUpon()
.appendQueryParameter("fields", "list_status") .appendQueryParameter("fields", "list_status")
@ -178,28 +228,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.build() .build()
authClient.newCall(request) authClient.newCall(request)
.await() .await()
.parseAs<JsonObject>() .parseAs()
.let {
val obj = it.jsonObject
val trackedManga = obj["data"]!!.jsonArray.find { data ->
data.jsonObject["node"]!!.jsonObject["id"]!!.jsonPrimitive.int == track.media_id
}
when {
// Found the item in the list
trackedManga != null -> {
parseMangaItem(trackedManga.jsonObject["list_status"]!!.jsonObject, track)
}
// Check next page if there's more
!obj["paging"]!!.jsonObject["next"]?.jsonPrimitive?.contentOrNull.isNullOrBlank() -> {
findListItem(track, offset + listPaginationAmount)
}
// No more pages to check, item wasn't found
else -> {
null
}
}
}
} }
} }