Vlogtruyen: Update search add filter by genre, status, sort by (#9069)

Update search, add filter genre & status, orderby
This commit is contained in:
are-are-are 2025-06-03 09:21:07 +07:00 committed by Draff
parent db240799f0
commit 9814a9770d
Signed by: Draff
GPG Key ID: E8A89F3211677653
2 changed files with 116 additions and 11 deletions

View File

@ -1,7 +1,7 @@
ext {
extName = 'VlogTruyen'
extClass = '.VlogTruyen'
extVersionCode = 11
extVersionCode = 12
isNsfw = true
}

View File

@ -9,6 +9,7 @@ import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.network.interceptor.rateLimit
import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
@ -16,6 +17,7 @@ import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup
import keiyoushi.utils.getPreferences
import keiyoushi.utils.tryParse
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import okhttp3.Headers
@ -45,8 +47,6 @@ class VlogTruyen : ParsedHttpSource(), ConfigurableSource {
override val baseUrl by lazy { getPrefBaseUrl() }
private val searchURL by lazy { "$baseUrl/tim-kiem" }
private val dateFormat = SimpleDateFormat("dd-MM-yyyy", Locale.US)
private val json: Json by injectLazy()
@ -114,15 +114,11 @@ class VlogTruyen : ParsedHttpSource(), ConfigurableSource {
if (it.select("li > b").text().isNotBlank()) {
name += " " + it.select("li > b").text() + " 🔒"
}
date_upload = parseDate(it.select("li:not(:has(> span.chapter-view)) > span, li > span:last-child").text())
date_upload = dateFormat.tryParse(it.select("li:not(:has(> span.chapter-view)) > span, li > span:last-child").text())
}
}
}
private fun parseDate(date: String): Long = runCatching {
dateFormat.parse(date)?.time
}.getOrNull() ?: 0L
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
val url = client.newCall(GET(baseUrl + manga.url, headers)).execute().asJsoup()
if (checkChapterLists(url).isNotEmpty()) {
@ -141,9 +137,20 @@ class VlogTruyen : ParsedHttpSource(), ConfigurableSource {
override fun chapterFromElement(element: Element) = throw UnsupportedOperationException()
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = searchURL.toHttpUrl().newBuilder().apply {
addQueryParameter("q", query)
if (page > 1) {
val url = baseUrl.toHttpUrl().newBuilder().apply {
if (query.isNotBlank()) {
addPathSegment("tim-kiem")
addQueryParameter("q", query)
addQueryParameter("page", page.toString())
} else {
(if (filters.isEmpty()) getFilterList() else filters).forEach {
when (it) {
is GenreList -> addPathSegments(it.values[it.state].genre)
is StatusByFilter -> addQueryParameter("status", it.values[it.state].genre)
is OrderByFilter -> addQueryParameter("sort", it.values[it.state].genre)
else -> {}
}
}
addQueryParameter("page", page.toString())
}
}.build()
@ -169,6 +176,104 @@ class VlogTruyen : ParsedHttpSource(), ConfigurableSource {
override fun imageUrlParse(document: Document): String = ""
override fun getFilterList() = FilterList(
Filter.Header("Không dùng chung với tìm kiếm bằng từ khoá."),
StatusByFilter(),
OrderByFilter(),
GenreList(getGenreList()),
)
private class OrderByFilter : Filter.Select<Genre>(
"Sắp xếp theo",
arrayOf(
Genre("Mới nhất", "moi-nhat"),
Genre("Đang hot", "dang-hot"),
Genre("Cũ nhất", "cu-nhat"),
),
)
private class StatusByFilter : Filter.Select<Genre>(
"Trạng thái",
arrayOf(
Genre("Trạng thái", "Trang-thai"),
Genre("Đã hoàn thành", "1"),
Genre("Chưa hoàn thành", "2"),
),
)
private class GenreList(genre: Array<Genre>) : Filter.Select<Genre>("Thể loại", genre)
private fun getGenreList() = arrayOf(
Genre("Hành Động", "the-loai/hanh-dong"),
Genre("Fantasy", "the-loai/fantasy"),
Genre("Truyện Trung", "the-loai/manhua"),
Genre("Võ Thuật", "the-loai/vo-thuat"),
Genre("Truyện Màu", "the-loai/truyen-mau"),
Genre("Chuyển Sinh", "the-loai/chuyen-sinh"),
Genre("Bí Ẩn", "the-loai/mystery"),
Genre("Ngôn Tình", "the-loai/ngon-tinh"),
Genre("Manhwa", "the-loai/manhwa"),
Genre("Phiêu Lưu", "the-loai/adventure"),
Genre("Cổ Đại", "the-loai/co"),
Genre("Hài Hước", "the-loai/hai"),
Genre("Kịch Tính", "the-loai/drama"),
Genre("Lịch Sử", "the-loai/historical"),
Genre("Xuyên Không", "the-loai/xuyen-khong"),
Genre("Lãng Mạn", "the-loai/romance"),
Genre("Học Đường", "the-loai/school-life"),
Genre("Đời Thường", "the-loai/slice-of-life"),
Genre("Siêu Nhiên", "the-loai/supernatural"),
Genre("Truyện Âu Mỹ", "the-loai/comic"),
Genre("Việt Nam", "the-loai/viet-nam"),
Genre("Shounen", "the-loai/shounen"),
Genre("Webtoon", "the-loai/webtoon"),
Genre("Kinh Dị", "the-loai/horror"),
Genre("Tâm Lý", "the-loai/psychological"),
Genre("Seinen", "the-loai/seinen"),
Genre("Manga", "the-loai/manga"),
Genre("Khoa Học Viễn Tưởng", "the-loai/sci-fi"),
Genre("Bi Kịch", "the-loai/tragedy"),
Genre("Thể Thao", "the-loai/sports"),
Genre("Anime", "the-loai/anime"),
Genre("Thiếu Nhi", "the-loai/thieu-nhi"),
Genre("Người Máy", "the-loai/mecha"),
Genre("Trinh Thám", "the-loai/trinh-tham"),
Genre("One shot", "the-loai/one-shot"),
Genre("Tạp chí truyện tranh", "the-loai/tap-chi-truyen-tranh"),
Genre("Doujinshi", "the-loai/doujinshi"),
Genre("Live action", "the-loai/live-action"),
Genre("Nấu Nướng", "the-loai/cooking"),
Genre("Truyện scan", "the-loai/truyen-scan"),
Genre("Cổ Đại", "the-loai/co-dai"),
Genre("Detective", "the-loai/detective"),
Genre("Trọng Sinh", "the-loai/trong-sinh"),
Genre("Chuyển sinh", "the-loai/isekai"),
Genre("Huyền Huyễn", "the-loai/huyen-huyen"),
Genre("Game", "the-loai/game"),
Genre("Chuyển sinh", "the-loai/isekaidi-gioitrong-sinh"),
Genre("Tu tiên", "the-loai/tu-tien"),
Genre("Hệ Thống", "the-loai/he-thong"),
Genre("Võ lâm", "the-loai/vo-lam"),
Genre("Già Gân", "the-loai/gia-gan"),
Genre("Hồi Quy", "the-loai/hoi-quy"),
Genre("Bắt Nạt", "the-loai/bat-nat"),
Genre("Báo Thù", "the-loai/bao-thu"),
Genre("Đấu Trí", "the-loai/dau-tri"),
Genre("Tài Chính", "the-loai/tai-chinh"),
Genre("Tận Thế", "the-loai/tan-the"),
Genre("Sinh Tồn", "the-loai/sinh-ton"),
Genre("Phản Diện", "the-loai/phan-dien"),
Genre("Martial Arts", "the-loai/martial-arts"),
Genre("Hành Động", "the-loai/action"),
Genre("Comedy", "the-loai/comedy"),
Genre("Âm Nhạc", "the-loai/am-nhac"),
Genre("Công Sở", "the-loai/cong-so"),
Genre("Diễn Viên", "the-loai/dien-vien"),
Genre("Vlogtruyen", "the-loai/vlogtruyen"),
)
private class Genre(val name: String, val genre: String) {
override fun toString() = name
}
private val preferences: SharedPreferences = getPreferences()
init {