【光环助手V4.5.0】论坛搜索功能及部分优化(帖子搜索) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/1049

This commit is contained in:
张玉久
2020-11-16 14:15:52 +08:00
parent ba55a5a61c
commit a2c3873c8d
15 changed files with 1179 additions and 34 deletions

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@ import androidx.core.content.ContextCompat
import com.gh.common.view.CenterImageSpan
import com.halo.assistant.HaloApp
class SpanBuilder(content: String) {
class SpanBuilder(content: CharSequence) {
private var spannableString: SpannableStringBuilder = SpannableStringBuilder(content)
fun color(context: Context, start: Int, end: Int, colorRes: Int): SpanBuilder {

View File

@ -220,7 +220,7 @@ class ForumDetailFragment : BaseLazyTabFragment() {
fun onViewClick(view: View) {
when (view.id) {
R.id.searchIv -> {
requireContext().startActivity(ForumOrUserSearchActivity.getIntent(requireContext(), "论坛详情"))
requireContext().startActivity(ForumOrUserSearchActivity.getIntent(requireContext(), bbsId, "论坛详情"))
}
R.id.filterContainer -> {
MtaHelper.onEvent("论坛详情", "全部Tab", "过滤选项")

View File

@ -1,6 +1,7 @@
package com.gh.gamecenter.forum.follow
import android.content.Context
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -68,10 +69,12 @@ class ForumMyFollowAdapter(context: Context, val mViewModel: ForumMyFollowViewMo
popupWindow.dismiss()
when (text) {
"取消关注" -> {
MtaHelper.onEvent("论坛首页", "我关注的论坛", "取消关注")
mViewModel.unFollowForum(entity.id) {
EventBus.getDefault().post(EBForumFollowChange(entity, false))
}
DialogUtils.showNewAlertDialog(mContext, "提示", "确定取消关注", "暂不", "确定", null, Gravity.CENTER, {}, {
MtaHelper.onEvent("论坛首页", "我关注的论坛", "取消关注")
mViewModel.unFollowForum(entity.id) {
EventBus.getDefault().post(EBForumFollowChange(entity, false))
}
})
}
}
}

View File

@ -8,6 +8,7 @@ import com.gh.common.util.*
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.CommunityAnswerItemBinding
import com.gh.gamecenter.entity.CommunityEntity
import com.gh.gamecenter.forum.detail.ForumDetailActivity
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.qa.answer.BaseAnswerOrArticleItemViewHolder
import com.gh.gamecenter.qa.answer.edit.AnswerEditActivity
@ -34,7 +35,7 @@ class ForumArticleAskItemViewHolder(val binding: CommunityAnswerItemBinding) : B
binding.entity = entity
binding.executePendingBindings()
binding.userIcon.display(entity.user.border,entity.user.icon,entity.user.auth?.icon)
binding.userIcon.display(entity.user.border, entity.user.icon, entity.user.auth?.icon)
binding.forumNameTv.text = entity.bbs.name
if (entity.type == "question") {
binding.content.visibility = View.GONE
@ -84,6 +85,11 @@ class ForumArticleAskItemViewHolder(val binding: CommunityAnswerItemBinding) : B
voteCount.text = "邀请回答"
voteIcon.setImageDrawable(ContextCompat.getDrawable(itemView.context, R.drawable.community_invite_follow))
}
forumNameTv.setOnClickListener {
MtaHelper.onEvent(getEventId(entrance), getKey(entrance), if (entity.bbs.name.isEmpty()) entity.bbs.name else entity.bbs.name)
itemView.context.startActivity(ForumDetailActivity.getIntent(itemView.context, entity.bbs.id, entrance))
LogUtils.uploadAccessToBbs(entity.bbs.id, "文章外所属论坛")
}
commentCountContainer.setOnClickListener {
if (filterIllegalCommentStatus(entity.commentable, entity.active)) return@setOnClickListener

View File

@ -233,7 +233,7 @@ class ForumHomeFragment : BaseLazyTabFragment() {
fun onViewClicked(view: View) {
when (view.id) {
R.id.actionbar_search_rl -> {
requireContext().startActivity(ForumOrUserSearchActivity.getIntent(requireContext(), "论坛首页"))
requireContext().startActivity(ForumOrUserSearchActivity.getIntent(requireContext(), "", "论坛首页"))
}
R.id.filterContainer -> {
showFilterPopupWindow {

View File

@ -1,17 +1,23 @@
package com.gh.gamecenter.forum.search
import android.content.Context
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.core.content.ContextCompat
import androidx.core.text.getSpans
import androidx.recyclerview.widget.RecyclerView
import com.gh.base.BaseActivity
import com.gh.base.BaseRecyclerViewHolder
import com.gh.common.constant.ItemViewType
import com.gh.common.syncpage.ISyncAdapterHandler
import com.gh.common.util.MtaHelper
import com.gh.common.util.SpanBuilder
import com.gh.common.util.dip2px
import com.gh.common.util.fromHtml
import com.gh.common.view.CenterImageSpan
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
import com.gh.gamecenter.baselist.ListAdapter
@ -24,7 +30,7 @@ import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.qa.entity.Questions
import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity
class ForumContentSearchListAdapter(context: Context, val mEntrance: String) : ListAdapter<AnswerEntity>(context) {
class ForumContentSearchListAdapter(context: Context, val mEntrance: String) : ListAdapter<AnswerEntity>(context), ISyncAdapterHandler {
override fun getItemViewType(position: Int): Int {
if (position == itemCount - 1) return ItemViewType.ITEM_FOOTER
@ -63,6 +69,8 @@ class ForumContentSearchListAdapter(context: Context, val mEntrance: String) : L
if (mEntrance == "论坛首页+(搜索)") {
val answerViewHolder = holder as ForumArticleAskItemViewHolder
answerViewHolder.bindForumAnswerItem(answer, mEntrance, "")
answerViewHolder.binding.title.text = answer.questions.title?.fromHtml()
answerViewHolder.binding.content.text = answer.brief?.fromHtml()
answerViewHolder.itemView.setOnClickListener {
val entrance = BaseActivity.mergeEntranceAndPath(mEntrance, "")
if ("community_article" == answer.type) {
@ -76,15 +84,18 @@ class ForumContentSearchListAdapter(context: Context, val mEntrance: String) : L
} else {
val forumSearchHolder = holder as ForumSearchContentListViewHolder
forumSearchHolder.binding.entity = answer
if (answer.type == "question") {
forumSearchHolder.binding.content.visibility = View.GONE
val title = " ${answer.questions.title}"
forumSearchHolder.binding.title.text = SpanBuilder(title).image(0, 1, R.drawable.ic_ask_label).build()
val title = answer.questions.title ?: ""
val spannableStringBuilder = SpannableStringBuilder(" ")
spannableStringBuilder.setSpan(CenterImageSpan(mContext, R.drawable.ic_ask_label), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
spannableStringBuilder.append(title.fromHtml())
forumSearchHolder.binding.title.text = spannableStringBuilder
} else {
forumSearchHolder.binding.content.visibility = View.VISIBLE
forumSearchHolder.binding.title.text = answer.questions.title
forumSearchHolder.binding.title.text = answer.questions.title?.fromHtml()
}
forumSearchHolder.binding.content.text = answer.brief?.fromHtml()
forumSearchHolder.itemView.setOnClickListener {
if ("community_article" == answer.type) {
mContext.startActivity(ArticleDetailActivity.getIntent(mContext, CommunityEntity(answer.bbs.id), answer.id!!, mEntrance, ""))
@ -108,4 +119,10 @@ class ForumContentSearchListAdapter(context: Context, val mEntrance: String) : L
}
class ForumSearchContentListViewHolder(val binding: ForumSearchContentListBinding) : BaseRecyclerViewHolder<Any>(binding.root)
override fun getSyncData(position: Int): Pair<String, Any>? {
if (position >= mEntityList.size) return null
val entity = mEntityList[position]
return Pair(entity.id ?: "", entity)
}
}

View File

@ -7,14 +7,17 @@ import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.EntranceUtils
import com.gh.common.util.viewModelProvider
import com.gh.gamecenter.R
import com.gh.gamecenter.baselist.ListAdapter
import com.gh.gamecenter.baselist.ListFragment
import com.gh.gamecenter.forum.detail.ForumArticleAskListAdapter
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.lightgame.utils.Utils
class ForumContentSearchListFragment : ListFragment<AnswerEntity, ForumContentSearchListViewModel>() {
private var bbsId = ""
private var mSearchKey = ""
private var mAdapter: ForumContentSearchListAdapter? = null
@ -23,6 +26,11 @@ class ForumContentSearchListFragment : ListFragment<AnswerEntity, ForumContentSe
?: ForumContentSearchListAdapter(requireContext(), "${mEntrance}+(搜索)").apply { mAdapter = this }
}
override fun provideListViewModel(): ForumContentSearchListViewModel {
val factory = ForumContentSearchListViewModel.Factory(bbsId)
return viewModelProvider(factory)
}
override fun isAutomaticLoad(): Boolean = false
fun setSearchKey(searchKey: String) {
@ -31,6 +39,7 @@ class ForumContentSearchListFragment : ListFragment<AnswerEntity, ForumContentSe
}
override fun onCreate(savedInstanceState: Bundle?) {
bbsId = arguments?.getString(EntranceUtils.KEY_BBS_ID) ?: ""
super.onCreate(savedInstanceState)
mListRv.overScrollMode = View.OVER_SCROLL_NEVER
mListRv.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.white))
@ -45,4 +54,8 @@ class ForumContentSearchListFragment : ListFragment<AnswerEntity, ForumContentSe
}
override fun getItemDecoration(): RecyclerView.ItemDecoration? = null
override fun addSyncPageObserver(): Boolean = true
override fun provideSyncAdapter(): ForumContentSearchListAdapter = mAdapter!!
}

View File

@ -1,18 +1,26 @@
package com.gh.gamecenter.forum.search
import android.app.Application
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.common.util.UrlFilterUtils
import com.gh.gamecenter.baselist.ListViewModel
import com.gh.gamecenter.baselist.LoadType
import com.gh.gamecenter.qa.article.detail.ArticleDetailViewModel
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import io.reactivex.Observable
class ForumContentSearchListViewModel(application: Application):ListViewModel<AnswerEntity, AnswerEntity>(application) {
class ForumContentSearchListViewModel(application: Application, val bbsId: String) : ListViewModel<AnswerEntity, AnswerEntity>(application) {
var searchKey = ""
override fun provideDataObservable(page: Int): Observable<MutableList<AnswerEntity>>? {
return RetrofitManager.getInstance(getApplication()).api.getAllForumList("5a605c3501edfe00213dd061", UrlFilterUtils.getFilterQuery("time.reply", "-1"), page)
val map = hashMapOf("keyword" to searchKey)
if (bbsId.isNotEmpty()) {
map["bbs_id"] = bbsId
}
return RetrofitManager.getInstance(getApplication()).api.searchForumContent(map, page)
}
override fun mergeResultLiveData() {
@ -23,4 +31,11 @@ class ForumContentSearchListViewModel(application: Application):ListViewModel<An
this.searchKey = searchKey
load(LoadType.REFRESH)
}
class Factory(private val bbsId: String) : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return ForumContentSearchListViewModel(HaloApp.getInstance().application, bbsId) as T
}
}
}

View File

@ -79,6 +79,7 @@ class ForumOrUserSearchActivity : SearchActivity() {
val fragment = supportFragmentManager.findFragmentByTag(ForumContentSearchListFragment::class.java.simpleName) as? ForumContentSearchListFragment
?: ForumContentSearchListFragment()
fragment.setSearchKey(mSearchKey ?: "")
fragment.arguments = intent.extras
transaction.replace(R.id.search_result, fragment, ForumContentSearchListFragment::class.java.simpleName)
}
}
@ -88,8 +89,9 @@ class ForumOrUserSearchActivity : SearchActivity() {
}
companion object {
fun getIntent(context: Context, mEntrance: String): Intent {
fun getIntent(context: Context, bbsId: String, mEntrance: String): Intent {
val intent = Intent(context, ForumOrUserSearchActivity::class.java)
intent.putExtra(EntranceUtils.KEY_BBS_ID, bbsId)
intent.putExtra(EntranceUtils.KEY_ENTRANCE, mEntrance)
return intent
}

View File

@ -3,9 +3,11 @@ package com.gh.gamecenter.forum.search
import android.os.Bundle
import android.view.View
import android.widget.LinearLayout
import android.widget.RelativeLayout
import androidx.fragment.app.Fragment
import com.gh.base.fragment.BaseFragment_TabLayout
import com.gh.common.util.dip2px
import com.google.android.material.tabs.TabLayout
class ForumOrUserSearchFragment : BaseFragment_TabLayout() {
private var mSearchKey = ""
@ -40,9 +42,15 @@ class ForumOrUserSearchFragment : BaseFragment_TabLayout() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val params = mViewPager.layoutParams as LinearLayout.LayoutParams
params.topMargin = 0.5f.dip2px()
mViewPager.layoutParams = params
mTabLayout.tabMode = TabLayout.MODE_AUTO
val tabLayoutParams = mTabLayout.layoutParams as RelativeLayout.LayoutParams
tabLayoutParams.width = RelativeLayout.LayoutParams.WRAP_CONTENT
mTabLayout.layoutParams = tabLayoutParams
val viewpagerParams = mViewPager.layoutParams as LinearLayout.LayoutParams
viewpagerParams.topMargin = 0.5f.dip2px()
mViewPager.layoutParams = viewpagerParams
setSearchKeyToChildFragment()
}
}

View File

@ -7,14 +7,13 @@ import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.gh.base.BaseRecyclerViewHolder
import com.gh.common.constant.ItemViewType
import com.gh.common.util.DirectUtils
import com.gh.common.util.SpanBuilder
import com.gh.common.util.dip2px
import com.gh.common.util.*
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
import com.gh.gamecenter.baselist.ListAdapter
import com.gh.gamecenter.databinding.UserSearchListItemBinding
import com.gh.gamecenter.entity.FollowersOrFansEntity
import com.gh.gamecenter.manager.UserManager
import java.util.*
class UserSearchListAdapter(context: Context, val mEntrance: String, val mViewModel: UserSearchListViewModel) : ListAdapter<FollowersOrFansEntity>(context) {
@ -45,16 +44,24 @@ class UserSearchListAdapter(context: Context, val mEntrance: String, val mViewMo
val binding = (holder as UserSearchListViewHolder).binding
val entity = mEntityList[position]
binding.entity = entity
val index = entity.name.toLowerCase(Locale.CHINA).indexOf(mViewModel.searchKey.toLowerCase(Locale.CHINA))
if (index >= 0) {
binding.userNameTv.text = SpanBuilder(entity.name).color(index, index + mViewModel.searchKey.length, R.color.theme_font).build()
} else {
binding.userNameTv.text = entity.name
}
binding.executePendingBindings()
if (entity.id == UserManager.getInstance().userId) {
binding.attentionTv.text = "自己"
binding.attentionTv.setTextColor(ContextCompat.getColor(mContext, R.color.text_999999))
binding.attentionTv.background = ContextCompat.getDrawable(mContext, R.drawable.bg_shape_f5_radius_999)
binding.attentionTv.isEnabled = false
}
holder.itemView.setOnClickListener {
DirectUtils.directToHomeActivity(mContext, entity.id, mEntrance, "用户搜索")
}
binding.userBadgeName.setOnClickListener { binding.userBadgeIcon.performClick() }
binding.userBadgeIcon.setOnClickListener {
DialogUtils.showViewBadgeDialog(binding.root.context, entity.badge) {
MtaHelper.onEvent("进入徽章墙_用户记录", "用户搜索", entity.name + "" + entity.id + "")
MtaHelper.onEvent("徽章中心", "进入徽章中心", "用户搜索")
DirectUtils.directToBadgeWall(binding.root.context, entity.id, entity.name, entity.icon)
}
}
holder.binding.attentionTv.setOnClickListener {
if (entity.me.isFollower) {
mViewModel.unFollow(entity.id) {

View File

@ -104,6 +104,7 @@ import com.gh.gamecenter.qa.entity.SuggestedFollowEntity;
import com.google.gson.JsonObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -2746,4 +2747,10 @@ public interface ApiService {
*/
@POST("users/{user_id}/recommends/bbses")
Observable<List<ForumEntity>> getRecommendForum(@Path("user_id") String userId, @Body RequestBody body);
/**
* 论坛首页搜索
*/
@GET("./bbses:search")
Observable<List<AnswerEntity>> searchForumContent(@QueryMap HashMap<String, String> map, @Query("page") int page);
}