Komiic: Add search filter (#9531)
* add comic description * fix manga search results missing descriptions * clean unused variables * clean unused class * Add some config options and refactor some code * refactor some code * modify config option summary * apply comments * modify Queries.kt * small modification * Format code * Format code * replace parse method * optimize check API limit * modify config summary * add search filter * add getChapterUrl() * refactor Query.kt * use filters.firstInstance() * nothing * Replace require() with check()
This commit is contained in:
parent
5ec031e3b8
commit
3b64f94ff8
@ -1,7 +1,7 @@
|
|||||||
ext {
|
ext {
|
||||||
extName = 'Komiic'
|
extName = 'Komiic'
|
||||||
extClass = '.Komiic'
|
extClass = '.Komiic'
|
||||||
extVersionCode = 2
|
extVersionCode = 3
|
||||||
isNsfw = true
|
isNsfw = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ class Result<T>(val result: T)
|
|||||||
class MultiResult<T, V>(val result1: T, val result2: V)
|
class MultiResult<T, V>(val result1: T, val result2: V)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class ComicItem(val id: String, val name: String)
|
data class Item(val id: String, val name: String)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Comic(
|
data class Comic(
|
||||||
@ -26,8 +26,8 @@ data class Comic(
|
|||||||
val description: String,
|
val description: String,
|
||||||
val status: String,
|
val status: String,
|
||||||
val imageUrl: String,
|
val imageUrl: String,
|
||||||
var authors: List<ComicItem>,
|
var authors: List<Item>,
|
||||||
val categories: List<ComicItem>,
|
val categories: List<Item>,
|
||||||
) {
|
) {
|
||||||
fun toSManga() = SManga.create().apply {
|
fun toSManga() = SManga.create().apply {
|
||||||
url = "/comic/$id"
|
url = "/comic/$id"
|
@ -0,0 +1,45 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.zh.komiic
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.source.model.Filter
|
||||||
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
|
|
||||||
|
fun buildFilterList(): FilterList {
|
||||||
|
val categories = mapOf(
|
||||||
|
"1" to "愛情", "3" to "神鬼", "4" to "校園", "5" to "搞笑", "6" to "生活",
|
||||||
|
"7" to "懸疑", "8" to "冒險", "10" to "職場", "11" to "魔幻", "2" to "後宮",
|
||||||
|
"12" to "魔法", "13" to "格鬥", "14" to "宅男", "15" to "勵志", "16" to "耽美",
|
||||||
|
"17" to "科幻", "18" to "百合", "19" to "治癒", "20" to "萌系", "21" to "熱血",
|
||||||
|
"22" to "競技", "23" to "推理", "24" to "雜誌", "25" to "偵探", "26" to "偽娘",
|
||||||
|
"27" to "美食", "9" to "恐怖", "28" to "四格", "31" to "社會", "32" to "歷史",
|
||||||
|
"33" to "戰爭", "34" to "舞蹈", "35" to "武俠", "36" to "機戰", "37" to "音樂",
|
||||||
|
"40" to "體育", "42" to "黑道", "46" to "腐女", "47" to "異世界", "48" to "驚悚",
|
||||||
|
"51" to "成人", "54" to "戰鬥", "55" to "復仇", "56" to "轉生", "57" to "黑暗奇幻",
|
||||||
|
"58" to "戲劇", "59" to "生存", "60" to "策略", "61" to "政治", "62" to "黑暗",
|
||||||
|
"64" to "動作", "70" to "性轉換", "73" to "色情", "181" to "校园", "78" to "日常",
|
||||||
|
"81" to "青春", "83" to "料理", "85" to "醫療", "86" to "致鬱", "87" to "心理",
|
||||||
|
"88" to "穿越", "92" to "友情", "93" to "犯罪", "97" to "劇情",
|
||||||
|
"110" to "運動", "113" to "少女", "114" to "賭博", "119" to "情色", "123" to "女性向",
|
||||||
|
"128" to "性轉", "129" to "溫馨", "164" to "同人",
|
||||||
|
)
|
||||||
|
return FilterList(
|
||||||
|
Filter.Header("過濾條件(搜索關鍵字時無效)"),
|
||||||
|
CategoryFilter(categories),
|
||||||
|
StatusFilter(),
|
||||||
|
SortFilter(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Category(val id: String, name: String) : Filter.CheckBox(name)
|
||||||
|
|
||||||
|
class CategoryFilter(categories: Map<String, String>) :
|
||||||
|
Filter.Group<Category>("類型(篩選同時包含全部所選標簽的漫畫)", categories.map { Category(it.key, it.value) }) {
|
||||||
|
val selected get() = state.filter(Category::state).map(Category::id)
|
||||||
|
}
|
||||||
|
|
||||||
|
class StatusFilter : Filter.Select<String>("狀態", arrayOf("全部", "連載", "完結")) {
|
||||||
|
val value get() = arrayOf("", "ONGOING", "END")[state]
|
||||||
|
}
|
||||||
|
|
||||||
|
class SortFilter : Filter.Select<String>("排序", arrayOf("更新", "觀看數", "喜愛數")) {
|
||||||
|
val value get() = arrayOf("DATE_UPDATED", "VIEWS", "FAVORITE_COUNT")[state]
|
||||||
|
}
|
@ -10,7 +10,8 @@ import eu.kanade.tachiyomi.source.model.Page
|
|||||||
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.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import keiyoushi.utils.getPreferences
|
import keiyoushi.utils.firstInstance
|
||||||
|
import keiyoushi.utils.getPreferencesLazy
|
||||||
import keiyoushi.utils.parseAs
|
import keiyoushi.utils.parseAs
|
||||||
import keiyoushi.utils.toJsonString
|
import keiyoushi.utils.toJsonString
|
||||||
import keiyoushi.utils.tryParse
|
import keiyoushi.utils.tryParse
|
||||||
@ -31,7 +32,7 @@ class Komiic : HttpSource(), ConfigurableSource {
|
|||||||
override val client = network.cloudflareClient
|
override val client = network.cloudflareClient
|
||||||
|
|
||||||
private val apiUrl = "$baseUrl/api/query"
|
private val apiUrl = "$baseUrl/api/query"
|
||||||
private val preferences = getPreferences()
|
private val preferences by getPreferencesLazy()
|
||||||
|
|
||||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||||
preferencesInternal(screen.context).forEach(screen::addPreference)
|
preferencesInternal(screen.context).forEach(screen::addPreference)
|
||||||
@ -57,8 +58,8 @@ class Komiic : HttpSource(), ConfigurableSource {
|
|||||||
* Search the comic based on the ID.
|
* Search the comic based on the ID.
|
||||||
*/
|
*/
|
||||||
private fun comicByIDRequest(id: String): Request {
|
private fun comicByIDRequest(id: String): Request {
|
||||||
val variables = Variables().set("comicId", id).build()
|
val variables = Variables().field("comicId", id).build()
|
||||||
val payload = Payload("comicById", variables, QUERY_COMIC_BY_ID)
|
val payload = Payload(Query.COMIC_BY_ID, variables)
|
||||||
return POST(apiUrl, headers, payload.toRequestBody())
|
return POST(apiUrl, headers, payload.toRequestBody())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,11 +88,9 @@ class Komiic : HttpSource(), ConfigurableSource {
|
|||||||
// Popular Manga ===============================================================================
|
// Popular Manga ===============================================================================
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int): Request {
|
override fun popularMangaRequest(page: Int): Request {
|
||||||
val variables = Variables().set(
|
val pagination = Pagination((page - 1) * PAGE_SIZE, "MONTH_VIEWS")
|
||||||
"pagination",
|
val variables = Variables().field("pagination", pagination).build()
|
||||||
Pagination((page - 1) * PAGE_SIZE, "MONTH_VIEWS"),
|
val payload = Payload(Query.HOT_COMICS, variables)
|
||||||
).build()
|
|
||||||
val payload = Payload("hotComics", variables, QUERY_HOT_COMICS)
|
|
||||||
return POST(apiUrl, headers, payload.toRequestBody())
|
return POST(apiUrl, headers, payload.toRequestBody())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,11 +103,9 @@ class Komiic : HttpSource(), ConfigurableSource {
|
|||||||
// Latest Updates ==============================================================================
|
// Latest Updates ==============================================================================
|
||||||
|
|
||||||
override fun latestUpdatesRequest(page: Int): Request {
|
override fun latestUpdatesRequest(page: Int): Request {
|
||||||
val variables = Variables().set(
|
val pagination = Pagination((page - 1) * PAGE_SIZE, "DATE_UPDATED")
|
||||||
"pagination",
|
val variables = Variables().field("pagination", pagination).build()
|
||||||
Pagination((page - 1) * PAGE_SIZE, "DATE_UPDATED"),
|
val payload = Payload(Query.RECENT_UPDATE, variables)
|
||||||
).build()
|
|
||||||
val payload = Payload("recentUpdate", variables, QUERY_RECENT_UPDATE)
|
|
||||||
return POST(apiUrl, headers, payload.toRequestBody())
|
return POST(apiUrl, headers, payload.toRequestBody())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,19 +113,23 @@ class Komiic : HttpSource(), ConfigurableSource {
|
|||||||
|
|
||||||
// Search Manga ================================================================================
|
// Search Manga ================================================================================
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun getFilterList() = buildFilterList()
|
||||||
val variables = Variables().set("keyword", query).build()
|
|
||||||
val payload = Payload("searchComicAndAuthorQuery", variables, QUERY_SEARCH)
|
|
||||||
return POST(apiUrl, headers, payload.toRequestBody())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
return if (query.startsWith(PREFIX_ID_SEARCH)) {
|
if (query.isNotBlank()) {
|
||||||
client.newCall(comicByIDRequest(query.substringAfter(PREFIX_ID_SEARCH)))
|
val variables = Variables().field("keyword", query).build()
|
||||||
.asObservableSuccess()
|
val payload = Payload(Query.SEARCH, variables)
|
||||||
.map(::parseComicByID)
|
return POST(apiUrl, headers, payload.toRequestBody())
|
||||||
} else {
|
} else {
|
||||||
super.fetchSearchManga(page, query, filters)
|
val categories = filters.firstInstance<CategoryFilter>()
|
||||||
|
val status = filters.firstInstance<StatusFilter>()
|
||||||
|
val sort = filters.firstInstance<SortFilter>()
|
||||||
|
val variables = Variables().field(
|
||||||
|
"pagination",
|
||||||
|
Pagination((page - 1) * PAGE_SIZE, sort.value, status.value, false),
|
||||||
|
).field("categoryId", categories.selected).build()
|
||||||
|
val payload = Payload(Query.COMIC_BY_CATEGORIES, variables)
|
||||||
|
return POST(apiUrl, headers, payload.toRequestBody())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,6 +139,17 @@ class Komiic : HttpSource(), ConfigurableSource {
|
|||||||
return MangasPage(comics.map(Comic::toSManga), comics.size == PAGE_SIZE)
|
return MangasPage(comics.map(Comic::toSManga), comics.size == PAGE_SIZE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
|
||||||
|
if (query.startsWith(PREFIX_ID_SEARCH)) {
|
||||||
|
return client.newCall(comicByIDRequest(query.substringAfter(PREFIX_ID_SEARCH)))
|
||||||
|
.asObservableSuccess().map(::parseComicByID)
|
||||||
|
} else if (query.isNotBlank()) {
|
||||||
|
return super.fetchSearchManga(page, query, filters)
|
||||||
|
}
|
||||||
|
return client.newCall(searchMangaRequest(page, query, filters))
|
||||||
|
.asObservableSuccess().map(::popularMangaParse)
|
||||||
|
}
|
||||||
|
|
||||||
// Manga Details ===============================================================================
|
// Manga Details ===============================================================================
|
||||||
|
|
||||||
override fun getMangaUrl(manga: SManga) = baseUrl + manga.url
|
override fun getMangaUrl(manga: SManga) = baseUrl + manga.url
|
||||||
@ -154,8 +166,8 @@ class Komiic : HttpSource(), ConfigurableSource {
|
|||||||
override fun getChapterUrl(chapter: SChapter) = baseUrl + chapter.url + "/images/all"
|
override fun getChapterUrl(chapter: SChapter) = baseUrl + chapter.url + "/images/all"
|
||||||
|
|
||||||
override fun chapterListRequest(manga: SManga): Request {
|
override fun chapterListRequest(manga: SManga): Request {
|
||||||
val variables = Variables().set("comicId", manga.id).build()
|
val variables = Variables().field("comicId", manga.id).build()
|
||||||
val payload = Payload("chapterByComicId", variables, QUERY_CHAPTER)
|
val payload = Payload(Query.CHAPTERS_BY_COMIC_ID, variables)
|
||||||
return POST("$apiUrl#${manga.url}", headers, payload.toRequestBody())
|
return POST("$apiUrl#${manga.url}", headers, payload.toRequestBody())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,15 +190,15 @@ class Komiic : HttpSource(), ConfigurableSource {
|
|||||||
// Page List ===================================================================================
|
// Page List ===================================================================================
|
||||||
|
|
||||||
override fun pageListRequest(chapter: SChapter): Request {
|
override fun pageListRequest(chapter: SChapter): Request {
|
||||||
val variables = Variables().set("chapterId", chapter.id).build()
|
val variables = Variables().field("chapterId", chapter.id).build()
|
||||||
val payload = Payload("imagesByChapterId", variables, QUERY_PAGE_LIST)
|
val payload = Payload(Query.IMAGES_BY_CHAPTER_ID, variables)
|
||||||
return POST("$apiUrl#${chapter.url}", headers, payload.toRequestBody())
|
return POST("$apiUrl#${chapter.url}", headers, payload.toRequestBody())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pageListParse(response: Response): List<Page> {
|
override fun pageListParse(response: Response): List<Page> {
|
||||||
val res = response.parseAs<MultiData<Boolean, List<Image>>>()
|
val res = response.parseAs<MultiData<Boolean, List<Image>>>()
|
||||||
val check = preferences.getBoolean(CHECK_API_LIMIT_PREF, true)
|
val check = preferences.getBoolean(CHECK_API_LIMIT_PREF, true)
|
||||||
require(!check || !res.data.result1) { "今日圖片讀取次數已達上限,請登录或明天再來!" }
|
check(!check || !res.data.result1) { "今日圖片讀取次數已達上限,請登录或明天再來!" }
|
||||||
val chapterUrl = response.request.url.fragment!!
|
val chapterUrl = response.request.url.fragment!!
|
||||||
return res.data.result2.mapIndexed { index, image ->
|
return res.data.result2.mapIndexed { index, image ->
|
||||||
Page(index, "$chapterUrl/page/$index", "$baseUrl/api/image/${image.kid}")
|
Page(index, "$chapterUrl/page/$index", "$baseUrl/api/image/${image.kid}")
|
||||||
|
@ -12,24 +12,26 @@ data class Payload<T>(
|
|||||||
val operationName: String,
|
val operationName: String,
|
||||||
val variables: T,
|
val variables: T,
|
||||||
val query: String,
|
val query: String,
|
||||||
)
|
) {
|
||||||
|
constructor(query: Query, variables: T) : this(query.operation, variables, query.body)
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Pagination(
|
data class Pagination(
|
||||||
val offset: Int,
|
val offset: Int,
|
||||||
val orderBy: String,
|
val orderBy: String,
|
||||||
@EncodeDefault
|
@EncodeDefault
|
||||||
val limit: Int = Komiic.PAGE_SIZE,
|
|
||||||
@EncodeDefault
|
|
||||||
val status: String = "",
|
val status: String = "",
|
||||||
@EncodeDefault
|
@EncodeDefault
|
||||||
val asc: Boolean = true,
|
val asc: Boolean = true,
|
||||||
|
@EncodeDefault
|
||||||
|
val limit: Int = Komiic.PAGE_SIZE,
|
||||||
)
|
)
|
||||||
|
|
||||||
class Variables {
|
class Variables {
|
||||||
val variableMap = mutableMapOf<String, JsonElement>()
|
val variableMap = mutableMapOf<String, JsonElement>()
|
||||||
|
|
||||||
inline fun <reified T> set(key: String, value: T): Variables {
|
inline fun <reified T> field(key: String, value: T): Variables {
|
||||||
variableMap[key] = Json.encodeToJsonElement(value)
|
variableMap[key] = Json.encodeToJsonElement(value)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,8 @@ fun preferencesInternal(context: Context) = arrayOf(
|
|||||||
},
|
},
|
||||||
SwitchPreferenceCompat(context).apply {
|
SwitchPreferenceCompat(context).apply {
|
||||||
key = CHECK_API_LIMIT_PREF
|
key = CHECK_API_LIMIT_PREF
|
||||||
title = "自動檢查API受限"
|
title = "自動檢查 API 狀態"
|
||||||
summary = "點擊單個章節請求漫畫圖片時,自動檢查一次圖片API是否達到今日請求上限。若已達上限,則終止後續操作"
|
summary = "點擊單個章節請求漫畫圖片時,自動檢查一次圖片API是否達到今日請求上限。若已達上限,則終止後續操作(注:關閉后仍會檢查API,只是不再終止操作)"
|
||||||
setDefaultValue(true)
|
setDefaultValue(true)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -1,90 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.extension.zh.komiic
|
|
||||||
|
|
||||||
private fun buildQuery(body: String = "", queryAction: () -> String): String {
|
|
||||||
return queryAction().trimIndent()
|
|
||||||
.replace("#{body}", body.trimIndent())
|
|
||||||
.replace("%", "$")
|
|
||||||
}
|
|
||||||
|
|
||||||
const val COMIC_BODY =
|
|
||||||
"""
|
|
||||||
{
|
|
||||||
id
|
|
||||||
title
|
|
||||||
description
|
|
||||||
status
|
|
||||||
imageUrl
|
|
||||||
authors {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
}
|
|
||||||
categories {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
val QUERY_HOT_COMICS = buildQuery(COMIC_BODY) {
|
|
||||||
"""
|
|
||||||
query hotComics(%pagination: Pagination!) {
|
|
||||||
result: hotComics(pagination: %pagination) #{body}
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
|
|
||||||
val QUERY_RECENT_UPDATE = buildQuery(COMIC_BODY) {
|
|
||||||
"""
|
|
||||||
query recentUpdate(%pagination: Pagination!) {
|
|
||||||
result: recentUpdate(pagination: %pagination) #{body}
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
|
|
||||||
val QUERY_SEARCH = buildQuery(COMIC_BODY) {
|
|
||||||
"""
|
|
||||||
query searchComicAndAuthorQuery(%keyword: String!) {
|
|
||||||
result: searchComicsAndAuthors(keyword: %keyword) {
|
|
||||||
result: comics #{body}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
|
|
||||||
val QUERY_COMIC_BY_ID = buildQuery(COMIC_BODY) {
|
|
||||||
"""
|
|
||||||
query comicById(%comicId: ID!) {
|
|
||||||
result: comicById(comicId: %comicId) #{body}
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
|
|
||||||
val QUERY_CHAPTER = buildQuery {
|
|
||||||
"""
|
|
||||||
query chapterByComicId(%comicId: ID!) {
|
|
||||||
result: chaptersByComicId(comicId: %comicId) {
|
|
||||||
id
|
|
||||||
serial
|
|
||||||
type
|
|
||||||
size
|
|
||||||
dateCreated
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
|
|
||||||
val QUERY_PAGE_LIST = buildQuery {
|
|
||||||
"""
|
|
||||||
query imagesByChapterId(%chapterId: ID!) {
|
|
||||||
result1: reachedImageLimit,
|
|
||||||
result2: imagesByChapterId(chapterId: %chapterId) {
|
|
||||||
id
|
|
||||||
kid
|
|
||||||
height
|
|
||||||
width
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
|
|
||||||
// val QUERY_API_LIMIT = buildQuery { "query reachedImageLimit { result: reachedImageLimit }" }
|
|
@ -0,0 +1,115 @@
|
|||||||
|
package eu.kanade.tachiyomi.extension.zh.komiic
|
||||||
|
|
||||||
|
enum class Query {
|
||||||
|
HOT_COMICS {
|
||||||
|
override val operation = "hotComics"
|
||||||
|
override val body = buildQuery(comicBody) {
|
||||||
|
"""
|
||||||
|
query hotComics(%pagination: Pagination!) {
|
||||||
|
result: hotComics(pagination: %pagination) #{body}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RECENT_UPDATE {
|
||||||
|
override val operation = "recentUpdate"
|
||||||
|
override val body = buildQuery(comicBody) {
|
||||||
|
"""
|
||||||
|
query recentUpdate(%pagination: Pagination!) {
|
||||||
|
result: recentUpdate(pagination: %pagination) #{body}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
SEARCH {
|
||||||
|
override val operation = "searchComicAndAuthorQuery"
|
||||||
|
override val body = buildQuery(comicBody) {
|
||||||
|
"""
|
||||||
|
query searchComicAndAuthorQuery(%keyword: String!) {
|
||||||
|
result: searchComicsAndAuthors(keyword: %keyword) {
|
||||||
|
result: comics #{body}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
COMIC_BY_CATEGORIES {
|
||||||
|
override val operation = "comicByCategories"
|
||||||
|
override val body = buildQuery(comicBody) {
|
||||||
|
"""
|
||||||
|
query comicByCategories(%categoryId: [ID!]!, %pagination: Pagination!) {
|
||||||
|
result: comicByCategories(categoryId: %categoryId, pagination: %pagination) #{body}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
COMIC_BY_ID {
|
||||||
|
override val operation = "comicById"
|
||||||
|
override val body = buildQuery(comicBody) {
|
||||||
|
"""
|
||||||
|
query comicById(%comicId: ID!) {
|
||||||
|
result: comicById(comicId: %comicId) #{body}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
CHAPTERS_BY_COMIC_ID {
|
||||||
|
override val operation = "chapterByComicId"
|
||||||
|
override val body = buildQuery {
|
||||||
|
"""
|
||||||
|
query chapterByComicId(%comicId: ID!) {
|
||||||
|
result: chaptersByComicId(comicId: %comicId) {
|
||||||
|
id
|
||||||
|
serial
|
||||||
|
type
|
||||||
|
size
|
||||||
|
dateCreated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
IMAGES_BY_CHAPTER_ID {
|
||||||
|
override val operation = "imagesByChapterId"
|
||||||
|
override val body = buildQuery {
|
||||||
|
"""
|
||||||
|
query imagesByChapterId(%chapterId: ID!) {
|
||||||
|
result1: reachedImageLimit,
|
||||||
|
result2: imagesByChapterId(chapterId: %chapterId) {
|
||||||
|
id
|
||||||
|
kid
|
||||||
|
height
|
||||||
|
width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}, ;
|
||||||
|
|
||||||
|
abstract val body: String
|
||||||
|
abstract val operation: String
|
||||||
|
val comicBody =
|
||||||
|
"""
|
||||||
|
{
|
||||||
|
id
|
||||||
|
title
|
||||||
|
description
|
||||||
|
status
|
||||||
|
imageUrl
|
||||||
|
authors {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
categories {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
fun buildQuery(body: String = "", queryAction: () -> String): String {
|
||||||
|
return queryAction().trimIndent()
|
||||||
|
.replace("#{body}", body.trimIndent())
|
||||||
|
.replace("%", "$")
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user