diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index 0c0c3383..d5584294 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -3,7 +3,20 @@ - + + + + + + + + + + + + + + diff --git a/app/src/main/java/com/xiaoyv/bangumi/helper/RouteHelper.kt b/app/src/main/java/com/xiaoyv/bangumi/helper/RouteHelper.kt index 1bae5536..2a718ec0 100644 --- a/app/src/main/java/com/xiaoyv/bangumi/helper/RouteHelper.kt +++ b/app/src/main/java/com/xiaoyv/bangumi/helper/RouteHelper.kt @@ -54,6 +54,35 @@ object RouteHelper { titleLink.contains(BgmPathType.TYPE_PERSON) -> { jumpPerson(id, false) } + // 话题 + titleLink.contains(BgmPathType.TYPE_TOPIC) -> { + when{ + // 虚拟人物 + titleLink.contains(TopicType.TYPE_CRT)-> { + jumpTopicDetail(id, TopicType.TYPE_CRT) + } + // 章节 + titleLink.contains(TopicType.TYPE_EP)-> { + jumpTopicDetail(id, TopicType.TYPE_EP) + } + // 小组 + titleLink.contains(TopicType.TYPE_GROUP)-> { + jumpTopicDetail(id, TopicType.TYPE_GROUP) + } + // 现实人物 + titleLink.contains(TopicType.TYPE_PERSON)-> { + jumpTopicDetail(id, TopicType.TYPE_PERSON) + } + // 条目 + titleLink.contains(TopicType.TYPE_SUBJECT)-> { + jumpTopicDetail(id, TopicType.TYPE_SUBJECT) + } + } + } + // 日志 + titleLink.contains(BgmPathType.TYPE_BLOG) -> { + jumpBlogDetail(id) + } } debugLog { "Handle Url: $titleLink" } diff --git a/app/src/main/java/com/xiaoyv/bangumi/ui/discover/blog/detail/BlogActivity.kt b/app/src/main/java/com/xiaoyv/bangumi/ui/discover/blog/detail/BlogActivity.kt index 62d0cad0..596bbd47 100644 --- a/app/src/main/java/com/xiaoyv/bangumi/ui/discover/blog/detail/BlogActivity.kt +++ b/app/src/main/java/com/xiaoyv/bangumi/ui/discover/blog/detail/BlogActivity.kt @@ -122,4 +122,9 @@ class BlogActivity : BaseViewModelActivity() item.initNavBack(this) return super.onOptionsItemSelected(item) } + + override fun onDestroy() { + super.onDestroy() + binding.webView.destroy() + } } \ No newline at end of file diff --git a/app/src/main/java/com/xiaoyv/bangumi/ui/feature/notify/NotifyActivity.kt b/app/src/main/java/com/xiaoyv/bangumi/ui/feature/notify/NotifyActivity.kt index 79f44160..548d9b98 100644 --- a/app/src/main/java/com/xiaoyv/bangumi/ui/feature/notify/NotifyActivity.kt +++ b/app/src/main/java/com/xiaoyv/bangumi/ui/feature/notify/NotifyActivity.kt @@ -30,6 +30,8 @@ class NotifyActivity : BaseListActivity() { contentAdapter.setOnDebouncedChildClickListener(R.id.item_notify) { if (it.titleLink.isNotBlank()) { RouteHelper.handleUrl(it.titleLink) + } else { + RouteHelper.jumpUserDetail(it.userId) } } } diff --git a/app/src/main/java/com/xiaoyv/bangumi/ui/feature/post/blog/PostBlogActivity.kt b/app/src/main/java/com/xiaoyv/bangumi/ui/feature/post/blog/PostBlogActivity.kt index 00293e75..f7f90cd5 100644 --- a/app/src/main/java/com/xiaoyv/bangumi/ui/feature/post/blog/PostBlogActivity.kt +++ b/app/src/main/java/com/xiaoyv/bangumi/ui/feature/post/blog/PostBlogActivity.kt @@ -109,4 +109,9 @@ class PostBlogActivity : BaseViewModelActivity - viewModel.currentSearchItem.value = subjectItemAdapter.getItem(position) + viewModel.switchSearchType(subjectItemAdapter.getItem(position)) KeyboardUtils.showSoftInput(binding.searchBar.etKeyword) } personItemAdapter.addOnItemChildClickListener(R.id.item_search) { _, _, position -> - viewModel.currentSearchItem.value = personItemAdapter.getItem(position) + viewModel.switchSearchType(personItemAdapter.getItem(position)) + KeyboardUtils.showSoftInput(binding.searchBar.etKeyword) + } + + tagItemAdapter.addOnItemChildClickListener(R.id.item_search) { _, _, position -> + viewModel.switchSearchType(tagItemAdapter.getItem(position)) KeyboardUtils.showSoftInput(binding.searchBar.etKeyword) } @@ -73,22 +90,27 @@ class SearchActivity : BaseViewModelActivity() + internal val currentSearchItem = MutableLiveData() internal val onSearchSubjectLiveData = MutableLiveData>() internal val onSearchPersonLiveData = MutableLiveData>() + internal val onSearchTagLiveData = MutableLiveData>() internal val onSearchRecentlyLiveData = MutableLiveData?>() override fun onViewCreated() { @@ -59,7 +61,35 @@ class SearchViewModel : BaseViewModel() { label = "三次元", pathType = BgmPathType.TYPE_SEARCH_SUBJECT, id = SearchCatType.TYPE_REAL, + ) + ) + + onSearchTagLiveData.value = listOf( + SearchItem( + label = "动画", + pathType = BgmPathType.TYPE_SEARCH_TAG, + id = MediaType.TYPE_ANIME + ), + SearchItem( + label = "书籍", + pathType = BgmPathType.TYPE_SEARCH_TAG, + id = MediaType.TYPE_BOOK + ), + SearchItem( + label = "音乐", + pathType = BgmPathType.TYPE_SEARCH_TAG, + id = MediaType.TYPE_MUSIC ), + SearchItem( + label = "游戏", + pathType = BgmPathType.TYPE_SEARCH_TAG, + id = MediaType.TYPE_GAME + ), + SearchItem( + label = "三次元", + pathType = BgmPathType.TYPE_SEARCH_TAG, + id = MediaType.TYPE_REAL + ) ) onSearchPersonLiveData.value = listOf( @@ -85,7 +115,15 @@ class SearchViewModel : BaseViewModel() { } // 默认搜索 条目-全部 - currentSearchItem.value = onSearchSubjectLiveData.value?.firstOrNull() + switchSearchType(onSearchSubjectLiveData.value?.firstOrNull()) } } + + + /** + * 切换搜索类型 + */ + fun switchSearchType(searchItem: SearchItem?) { + currentSearchItem.value = searchItem + } } \ No newline at end of file diff --git a/app/src/main/java/com/xiaoyv/bangumi/ui/feature/search/detail/SearchDetailActivity.kt b/app/src/main/java/com/xiaoyv/bangumi/ui/feature/search/detail/SearchDetailActivity.kt index fec38bd6..f24fe4de 100644 --- a/app/src/main/java/com/xiaoyv/bangumi/ui/feature/search/detail/SearchDetailActivity.kt +++ b/app/src/main/java/com/xiaoyv/bangumi/ui/feature/search/detail/SearchDetailActivity.kt @@ -7,6 +7,8 @@ import androidx.recyclerview.widget.LinearLayoutManager import com.blankj.utilcode.util.KeyboardUtils import com.chad.library.adapter.base.QuickAdapterHelper import com.chad.library.adapter.base.loadState.trailing.TrailingLoadStateAdapter +import com.google.android.flexbox.FlexDirection +import com.google.android.flexbox.FlexboxLayoutManager import com.xiaoyv.bangumi.R import com.xiaoyv.bangumi.databinding.ActivitySearchDetailBinding import com.xiaoyv.bangumi.helper.RouteHelper @@ -16,6 +18,7 @@ import com.xiaoyv.common.config.annotation.BgmPathType import com.xiaoyv.common.config.annotation.SearchCatType import com.xiaoyv.common.kts.GoogleAttr import com.xiaoyv.common.kts.setOnDebouncedChildClickListener +import com.xiaoyv.common.widget.scroll.AnimeLinearLayoutManager import com.xiaoyv.widget.callback.setOnFastLimitClickListener import com.xiaoyv.widget.kts.getAttrColor import com.xiaoyv.widget.kts.getParcelObj @@ -29,10 +32,21 @@ import com.xiaoyv.widget.kts.useNotNull */ class SearchDetailActivity : BaseViewModelActivity() { - private val contentAdapter by lazy { - SearchDetailAdapter() + private val contentItemAdapter by lazy { + SearchDetailItemAdapter() } + private val contentTagAdapter by lazy { + SearchDetailTagAdapter() + } + + /** + * 适配器 + */ + private val contentAdapter + get() = if (viewModel.isSearchTag) contentTagAdapter else contentItemAdapter + + private val adapterHelper by lazy { QuickAdapterHelper.Builder(contentAdapter) .setTrailingLoadStateAdapter(object : TrailingLoadStateAdapter.OnTrailingListener { @@ -51,9 +65,6 @@ class SearchDetailActivity : .build() } - private val layoutManager: LinearLayoutManager? - get() = binding.rvContent.layoutManager as? LinearLayoutManager - override fun initIntentData(intent: Intent, bundle: Bundle, isNewIntent: Boolean) { viewModel.currentSearchItem.value = bundle.getParcelObj(NavKey.KEY_PARCELABLE) } @@ -61,11 +72,18 @@ class SearchDetailActivity : override fun initView() { binding.srlRefresh.initRefresh { false } binding.srlRefresh.setColorSchemeColors(getAttrColor(GoogleAttr.colorPrimary)) - - binding.rvContent.adapter = adapterHelper.adapter } override fun initData() { + if (viewModel.isSearchTag) { + binding.rvContent.layoutManager = FlexboxLayoutManager(this, FlexDirection.ROW) + binding.rvContent.adapter = contentAdapter + } else { + binding.rvContent.layoutManager = + AnimeLinearLayoutManager(this, LinearLayoutManager.VERTICAL, false) + binding.rvContent.adapter = adapterHelper.adapter + } + viewModel.refresh() } @@ -89,7 +107,7 @@ class SearchDetailActivity : true } - contentAdapter.setOnDebouncedChildClickListener(R.id.item_search) { + contentItemAdapter.setOnDebouncedChildClickListener(R.id.item_search) { useNotNull(viewModel.currentSearchItem.value) { if (pathType == BgmPathType.TYPE_SEARCH_SUBJECT) { RouteHelper.jumpMediaDetail(it.id) @@ -126,9 +144,14 @@ class SearchDetailActivity : contentAdapter.submitList(it) { if (viewModel.isRefresh) { - layoutManager?.scrollToPositionWithOffset(0, 0) + if (viewModel.isSearchTag) { + (binding.rvContent.layoutManager as? FlexboxLayoutManager) + ?.scrollToPosition(0) + } else { + (binding.rvContent.layoutManager as? LinearLayoutManager) + ?.scrollToPositionWithOffset(0, 0) + } } - adapterHelper.trailingLoadState = viewModel.loadingMoreState } } diff --git a/app/src/main/java/com/xiaoyv/bangumi/ui/feature/search/detail/SearchDetailAdapter.kt b/app/src/main/java/com/xiaoyv/bangumi/ui/feature/search/detail/SearchDetailItemAdapter.kt similarity index 92% rename from app/src/main/java/com/xiaoyv/bangumi/ui/feature/search/detail/SearchDetailAdapter.kt rename to app/src/main/java/com/xiaoyv/bangumi/ui/feature/search/detail/SearchDetailItemAdapter.kt index 6c7c55e9..66bad799 100644 --- a/app/src/main/java/com/xiaoyv/bangumi/ui/feature/search/detail/SearchDetailAdapter.kt +++ b/app/src/main/java/com/xiaoyv/bangumi/ui/feature/search/detail/SearchDetailItemAdapter.kt @@ -9,12 +9,12 @@ import com.xiaoyv.widget.binder.BaseQuickBindingHolder import com.xiaoyv.widget.binder.BaseQuickDiffBindingAdapter /** - * Class: [SearchDetailAdapter] + * Class: [SearchDetailItemAdapter] * * @author why * @since 12/8/23 */ -class SearchDetailAdapter : BaseQuickDiffBindingAdapter(IdDiffItemCallback()) { override fun BaseQuickBindingHolder.converted(item: SearchResultEntity) { diff --git a/app/src/main/java/com/xiaoyv/bangumi/ui/feature/search/detail/SearchDetailTagAdapter.kt b/app/src/main/java/com/xiaoyv/bangumi/ui/feature/search/detail/SearchDetailTagAdapter.kt new file mode 100644 index 00000000..854b411f --- /dev/null +++ b/app/src/main/java/com/xiaoyv/bangumi/ui/feature/search/detail/SearchDetailTagAdapter.kt @@ -0,0 +1,22 @@ +package com.xiaoyv.bangumi.ui.feature.search.detail + +import com.xiaoyv.bangumi.databinding.ActivitySearchDetailTagBinding +import com.xiaoyv.common.api.parser.entity.SearchResultEntity +import com.xiaoyv.common.helper.callback.IdDiffItemCallback +import com.xiaoyv.widget.binder.BaseQuickBindingHolder +import com.xiaoyv.widget.binder.BaseQuickDiffBindingAdapter + +/** + * Class: [SearchDetailTagAdapter] + * + * @author why + * @since 12/8/23 + */ +class SearchDetailTagAdapter : BaseQuickDiffBindingAdapter(IdDiffItemCallback()) { + + override fun BaseQuickBindingHolder.converted(item: SearchResultEntity) { + binding.tvTitleTag.text = item.title + binding.tvCommentCount.text = item.count + } +} \ No newline at end of file diff --git a/app/src/main/java/com/xiaoyv/bangumi/ui/feature/search/detail/SearchDetailViewModel.kt b/app/src/main/java/com/xiaoyv/bangumi/ui/feature/search/detail/SearchDetailViewModel.kt index a39c10f5..084d3e85 100644 --- a/app/src/main/java/com/xiaoyv/bangumi/ui/feature/search/detail/SearchDetailViewModel.kt +++ b/app/src/main/java/com/xiaoyv/bangumi/ui/feature/search/detail/SearchDetailViewModel.kt @@ -3,15 +3,18 @@ package com.xiaoyv.bangumi.ui.feature.search.detail import androidx.lifecycle.MutableLiveData +import com.blankj.utilcode.constant.TimeConstants import com.blankj.utilcode.util.StringUtils import com.xiaoyv.bangumi.base.BaseListViewModel import com.xiaoyv.common.api.BgmApiManager import com.xiaoyv.common.api.parser.entity.SearchResultEntity import com.xiaoyv.common.api.parser.impl.parserSearchResult +import com.xiaoyv.common.config.annotation.BgmPathType import com.xiaoyv.common.config.bean.SearchItem import com.xiaoyv.common.kts.CommonString import okhttp3.Cookie import okhttp3.HttpUrl.Companion.toHttpUrl +import kotlin.random.Random /** * Class: [SearchDetailViewModel] @@ -24,27 +27,57 @@ class SearchDetailViewModel : BaseListViewModel() { internal val isLegacy = MutableLiveData(1) + /** + * 是否搜索标签 + */ + internal val isSearchTag + get() = currentSearchItem.value?.pathType == BgmPathType.TYPE_SEARCH_TAG + override suspend fun onRequestListImpl(): List { val searchItem = requireNotNull(currentSearchItem.value) // 填充上次搜索时间的 Cookie - val fakeCookie = "chii_searchDateLine=0;" + val fakeTime = System.currentTimeMillis() / 1000 - Random.nextInt(10000) + val fakeCookie = "chii_searchDateLine=$fakeTime;" val httpUrl = BgmApiManager.URL_BASE_WEB.toHttpUrl() val cookie = Cookie.parse(httpUrl, fakeCookie) if (cookie != null) { - BgmApiManager.httpClient.cookieJar.saveFromResponse(httpUrl, listOf(cookie)) + val newCookie = cookie.newBuilder() + .expiresAt(System.currentTimeMillis() + TimeConstants.DAY) + .build() + BgmApiManager.httpClient.cookieJar.saveFromResponse(httpUrl, listOf(newCookie)) } - return BgmApiManager.bgmWebApi.querySearch( - pathType = searchItem.pathType, - keyword = searchItem.keyword, - cat = searchItem.id, - page = current, - legacy = isLegacy.value ?: 0 - ).parserSearchResult(searchItem.pathType).apply { - if (isRefresh && isEmpty()) { - throw IllegalArgumentException(StringUtils.getString(CommonString.common_empty_tip)) + // 搜索逻辑 + when (searchItem.pathType) { + // 条目、人物 搜索 + BgmPathType.TYPE_SEARCH_SUBJECT, BgmPathType.TYPE_SEARCH_MONO -> { + return BgmApiManager.bgmWebApi.querySearchMedia( + pathType = searchItem.pathType, + keyword = searchItem.keyword, + cat = searchItem.id, + page = current, + legacy = isLegacy.value ?: 0 + ).parserSearchResult(searchItem.pathType).apply { + if (isRefresh && isEmpty()) { + throw IllegalArgumentException(StringUtils.getString(CommonString.common_empty_tip)) + } + } + } + + // 标签搜索 + BgmPathType.TYPE_SEARCH_TAG -> { + return BgmApiManager.bgmWebApi.querySearchTag( + mediaType = searchItem.id, + keyword = searchItem.keyword, + ).parserSearchResult(searchItem.pathType).apply { + if (isRefresh && isEmpty()) { + throw IllegalArgumentException(StringUtils.getString(CommonString.common_empty_tip)) + } + } } + + else -> throw IllegalArgumentException("不支持的搜索类型:${searchItem.pathType}") } } } \ No newline at end of file diff --git a/app/src/main/java/com/xiaoyv/bangumi/ui/feature/summary/SummaryViewModel.kt b/app/src/main/java/com/xiaoyv/bangumi/ui/feature/summary/SummaryViewModel.kt index 99d5280d..0251c712 100644 --- a/app/src/main/java/com/xiaoyv/bangumi/ui/feature/summary/SummaryViewModel.kt +++ b/app/src/main/java/com/xiaoyv/bangumi/ui/feature/summary/SummaryViewModel.kt @@ -47,7 +47,7 @@ class SummaryViewModel : BaseViewModel() { launchUI(stateView = loadingViewState) { isShowOriginal = true summaryOriginal.value = withContext(Dispatchers.IO) { - summary.map { it.parseHtml() } + summary.map { it.parseHtml(true) } } } } diff --git a/app/src/main/java/com/xiaoyv/bangumi/ui/feature/topic/TopicActivity.kt b/app/src/main/java/com/xiaoyv/bangumi/ui/feature/topic/TopicActivity.kt index 34415993..af0dcd4c 100644 --- a/app/src/main/java/com/xiaoyv/bangumi/ui/feature/topic/TopicActivity.kt +++ b/app/src/main/java/com/xiaoyv/bangumi/ui/feature/topic/TopicActivity.kt @@ -123,4 +123,9 @@ class TopicActivity : BaseViewModelActivity + + + + + + diff --git a/app/src/main/res/layout/activity_search_detail_tag.xml b/app/src/main/res/layout/activity_search_detail_tag.xml new file mode 100644 index 00000000..b369cc4b --- /dev/null +++ b/app/src/main/res/layout/activity_search_detail_tag.xml @@ -0,0 +1,39 @@ + + + + + + + diff --git a/lib-common/src/main/java/com/xiaoyv/common/api/api/BgmWebApi.kt b/lib-common/src/main/java/com/xiaoyv/common/api/api/BgmWebApi.kt index d20a017f..2dffcad3 100644 --- a/lib-common/src/main/java/com/xiaoyv/common/api/api/BgmWebApi.kt +++ b/lib-common/src/main/java/com/xiaoyv/common/api/api/BgmWebApi.kt @@ -403,14 +403,26 @@ interface BgmWebApi { @Query("gh") gh: String, ): Document + /** + * 搜索人物、条目 + */ @GET("/{pathType}/{keyword}") - suspend fun querySearch( + suspend fun querySearchMedia( @Path("pathType") pathType: String, @Path("keyword") keyword: String, @Query("cat") @SearchCatType cat: String, @Query("page") page: Int, @Query("legacy") legacy: Int = 1 ): Document + + /** + * 搜索标签 + */ + @GET("/search/tag/{mediaType}/{keyword}") + suspend fun querySearchTag( + @Path("mediaType") mediaType: String, + @Path("keyword") keyword: String + ): Document } diff --git a/lib-common/src/main/java/com/xiaoyv/common/api/parser/Parser.kt b/lib-common/src/main/java/com/xiaoyv/common/api/parser/Parser.kt index 73ebd7a3..fb63377c 100644 --- a/lib-common/src/main/java/com/xiaoyv/common/api/parser/Parser.kt +++ b/lib-common/src/main/java/com/xiaoyv/common/api/parser/Parser.kt @@ -92,8 +92,10 @@ class GlobalChickHandler(private val span: URLSpan) : ClickableSpan() { /** * 解析 Html 并添加链接 */ -fun String.parseHtml(): CharSequence { +fun String.parseHtml(handleLink: Boolean = false): CharSequence { val spanned = parseAsHtml() + if (!handleLink) return spanned + val builder = SpannableStringBuilder(spanned) val urlSpans = builder.getSpans(0, builder.length, URLSpan::class.java) for (span in urlSpans) { diff --git a/lib-common/src/main/java/com/xiaoyv/common/api/parser/entity/MediaDetailEntity.kt b/lib-common/src/main/java/com/xiaoyv/common/api/parser/entity/MediaDetailEntity.kt index f72ccfa0..e0ac5cd3 100644 --- a/lib-common/src/main/java/com/xiaoyv/common/api/parser/entity/MediaDetailEntity.kt +++ b/lib-common/src/main/java/com/xiaoyv/common/api/parser/entity/MediaDetailEntity.kt @@ -27,7 +27,7 @@ data class MediaDetailEntity( @SerializedName("subtype") var subtype: String = "", @SerializedName("cover") var cover: String = "", @SerializedName("collectState") var collectState: MediaCollectForm = MediaCollectForm(), - @SerializedName("infos") var infos: List = emptyList(), + @SerializedName("infos") var infoShort: List = emptyList(), @SerializedName("infoHtml") var infoHtml: List = emptyList(), @SerializedName("recommendIndex") var recommendIndex: List = emptyList(), @SerializedName("whoSee") var whoSee: List = emptyList(), diff --git a/lib-common/src/main/java/com/xiaoyv/common/api/parser/impl/MediaDetailParser.kt b/lib-common/src/main/java/com/xiaoyv/common/api/parser/impl/MediaDetailParser.kt index ce82cf6f..7262b08a 100644 --- a/lib-common/src/main/java/com/xiaoyv/common/api/parser/impl/MediaDetailParser.kt +++ b/lib-common/src/main/java/com/xiaoyv/common/api/parser/impl/MediaDetailParser.kt @@ -18,6 +18,7 @@ import com.xiaoyv.common.api.parser.selectLegal import com.xiaoyv.common.config.annotation.MediaType import com.xiaoyv.common.kts.decodeUrl import com.xiaoyv.common.widget.star.StarCommentView +import com.xiaoyv.widget.kts.subListLimit import com.xiaoyv.widget.kts.useNotNull import org.jsoup.nodes.Document import org.jsoup.nodes.Element @@ -161,8 +162,8 @@ fun Document.parserMediaDetail(): MediaDetailEntity { } entity.subtype = select(".nameSingle small").text() entity.cover = select("img.cover").attr("src").optImageUrl() - entity.infos = select("#infobox > li").map { it.html().parseHtml() } - entity.infoHtml = select("#infobox > li").map { it.html()} + entity.infoHtml = select("#infobox > li").map { it.html() } + entity.infoShort = entity.infoHtml.subListLimit(10).map { it.parseHtml() } entity.time = select("#infobox").text().parserTime() entity.collectState = select("#panelInterestWrapper").let { item -> diff --git a/lib-common/src/main/java/com/xiaoyv/common/api/parser/impl/SearchParser.kt b/lib-common/src/main/java/com/xiaoyv/common/api/parser/impl/SearchParser.kt index 3f43d93a..5ac77e7e 100644 --- a/lib-common/src/main/java/com/xiaoyv/common/api/parser/impl/SearchParser.kt +++ b/lib-common/src/main/java/com/xiaoyv/common/api/parser/impl/SearchParser.kt @@ -19,56 +19,73 @@ fun Element.parserSearchResult(@BgmPathType pathType: String): List li").map { item -> - val entity = SearchResultEntity() - entity.id = item.select("a.cover").attr("href").substringAfterLast("/") - entity.coverImage = item.select("a.cover img").attr("src").optImageUrl() - entity.title = item.select(".inner h3 a").text() - entity.subtitle = item.select(".inner h3 small").text() - entity.rank = item.select(".rank").text() - entity.infoTip = BrowserParser.parserInfoTip(item.select(".tip").text()) + return when (pathType) { + BgmPathType.TYPE_SEARCH_SUBJECT -> { + select("#browserItemList > li").map { item -> + val entity = SearchResultEntity() + entity.id = item.select("a.cover").attr("href").substringAfterLast("/") + entity.coverImage = item.select("a.cover img").attr("src").optImageUrl() + entity.title = item.select(".inner h3 a").text() + entity.subtitle = item.select(".inner h3 small").text() + entity.rank = item.select(".rank").text() + entity.infoTip = BrowserParser.parserInfoTip(item.select(".tip").text()) - val rateInfo = item.select(".rateInfo") - entity.rating = rateInfo.select(".starstop-s > span").attr("class").let { starClass -> - StarCommentView.parseScore(starClass) - } - entity.ratingScore = rateInfo.select(".fade").text() - entity.count = rateInfo.select(".tip_j").text() + val rateInfo = item.select(".rateInfo") + entity.rating = + rateInfo.select(".starstop-s > span").attr("class").let { starClass -> + StarCommentView.parseScore(starClass) + } + entity.ratingScore = rateInfo.select(".fade").text() + entity.count = rateInfo.select(".tip_j").text() - val collectBlock = item.select(".collectBlock") - entity.isCollection = collectBlock.select(".collectModify").isNotEmpty() + val collectBlock = item.select(".collectBlock") + entity.isCollection = collectBlock.select(".collectModify").isNotEmpty() - val mediaType = item.select(".ico_subject_type").toString().let { clsName: String -> - when { - clsName.contains("subject_type_1") -> MediaType.TYPE_BOOK - clsName.contains("subject_type_2") -> MediaType.TYPE_ANIME - clsName.contains("subject_type_3") -> MediaType.TYPE_MUSIC - clsName.contains("subject_type_4") -> MediaType.TYPE_GAME - clsName.contains("subject_type_6") -> MediaType.TYPE_REAL - else -> MediaType.TYPE_UNKNOWN + val mediaType = item.select(".ico_subject_type").toString().let { clsName: String -> + when { + clsName.contains("subject_type_1") -> MediaType.TYPE_BOOK + clsName.contains("subject_type_2") -> MediaType.TYPE_ANIME + clsName.contains("subject_type_3") -> MediaType.TYPE_MUSIC + clsName.contains("subject_type_4") -> MediaType.TYPE_GAME + clsName.contains("subject_type_6") -> MediaType.TYPE_REAL + else -> MediaType.TYPE_UNKNOWN + } } + entity.searchType = GlobalConfig.mediaTypeName(mediaType) + entity } - entity.searchType = GlobalConfig.mediaTypeName(mediaType) - entity } - } - // 搜索人物解析 - else { - select("#columnSearchB > div") - .filter { item -> item.select("a").isNotEmpty() } - .map { item -> - val entity = SearchResultEntity() - entity.id = item.select("a.avatar").attr("href").substringAfterLast("/") - entity.coverImage = item.select("a.avatar img").attr("src").optImageUrl() - entity.count = "讨论:" + item.select(".rr small").text() - item.select("h2 a.l").apply { - entity.subtitle = select(".tip").remove().text().trim().trim('/') - entity.title = text().trim().trim('/') + // 搜索人物解析 + BgmPathType.TYPE_SEARCH_MONO -> { + select("#columnSearchB > div") + .filter { item -> item.select("a").isNotEmpty() } + .map { item -> + val entity = SearchResultEntity() + entity.id = item.select("a.avatar").attr("href").substringAfterLast("/") + entity.coverImage = item.select("a.avatar img").attr("src").optImageUrl() + entity.count = "讨论:" + item.select(".rr small").text() + item.select("h2 a.l").apply { + entity.subtitle = select(".tip").remove().text().trim().trim('/') + entity.title = text().trim().trim('/') + } + entity.infoTip = + BrowserParser.parserInfoTip(item.select(".prsn_info .tip").text().trim('/')) + entity.searchType = "人物" + entity } - entity.infoTip = BrowserParser.parserInfoTip(item.select(".prsn_info .tip").text().trim('/')) - entity.searchType = "人物" + } + // 搜索标签解析 + BgmPathType.TYPE_SEARCH_TAG -> { + select("#tagList > a").map { item -> + val entity = SearchResultEntity() + entity.id = item.attr("href").substringAfterLast("/") + entity.count = item.nextElementSibling()?.text().orEmpty() + entity.title = item.text() + entity.searchType = "标签" entity } + } + + else -> throw IllegalArgumentException("暂不支持搜索该类型") } } \ No newline at end of file diff --git a/lib-common/src/main/java/com/xiaoyv/common/config/annotation/BgmPathType.kt b/lib-common/src/main/java/com/xiaoyv/common/config/annotation/BgmPathType.kt index bbf7895a..876a74d7 100644 --- a/lib-common/src/main/java/com/xiaoyv/common/config/annotation/BgmPathType.kt +++ b/lib-common/src/main/java/com/xiaoyv/common/config/annotation/BgmPathType.kt @@ -18,7 +18,8 @@ import androidx.annotation.StringDef BgmPathType.TYPE_TOPIC, BgmPathType.TYPE_MESSAGE_BOX, BgmPathType.TYPE_SEARCH_SUBJECT, - BgmPathType.TYPE_SEARCH_MONO + BgmPathType.TYPE_SEARCH_MONO, + BgmPathType.TYPE_SEARCH_TAG ) @Retention(AnnotationRetention.SOURCE) annotation class BgmPathType { @@ -33,11 +34,13 @@ annotation class BgmPathType { const val TYPE_MESSAGE_BOX = "pm" const val TYPE_SEARCH_SUBJECT = "subject_search" const val TYPE_SEARCH_MONO = "mono_search" + const val TYPE_SEARCH_TAG = "tag" fun string(@BgmPathType type: String): String { return when (type) { TYPE_SEARCH_SUBJECT -> "条目查询" TYPE_SEARCH_MONO -> "人物查询" + TYPE_SEARCH_TAG -> "标签查询" else -> "" } } diff --git a/lib-common/src/main/java/com/xiaoyv/common/config/bean/SearchItem.kt b/lib-common/src/main/java/com/xiaoyv/common/config/bean/SearchItem.kt index 9e4e3a51..04ce3b78 100644 --- a/lib-common/src/main/java/com/xiaoyv/common/config/bean/SearchItem.kt +++ b/lib-common/src/main/java/com/xiaoyv/common/config/bean/SearchItem.kt @@ -3,7 +3,6 @@ package com.xiaoyv.common.config.bean import android.os.Parcelable import androidx.annotation.Keep import com.xiaoyv.common.config.annotation.BgmPathType -import com.xiaoyv.common.config.annotation.SearchCatType import com.xiaoyv.common.helper.callback.IdEntity import kotlinx.parcelize.Parcelize @@ -14,7 +13,6 @@ import kotlinx.parcelize.Parcelize @Parcelize data class SearchItem( var label: String, - @SearchCatType override var id: String, @BgmPathType var pathType: String,