feat:论坛搜索排序逻辑优化—客户端 https://jira.shanqu.cc/browse/GHZS-3730

This commit is contained in:
张晨
2023-11-09 14:01:17 +08:00
parent a25503113b
commit 852f7734ef
14 changed files with 236 additions and 66 deletions

View File

@ -668,7 +668,8 @@ object NewFlatLogUtils {
searchKey: String,
bbsId: String,
sequence: Int,
name: String
name: String,
button: String
) {
json {
KEY_EVENT to "search_bbs_click"
@ -677,6 +678,7 @@ object NewFlatLogUtils {
"bbs_id" to bbsId
"sequence" to sequence
"name" to name
"button" to button
parseAndPutMeta()()
}.let(::log)
}

View File

@ -15,6 +15,7 @@ import com.gh.gamecenter.common.utils.debounceActionWithInterval
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.toDrawable
import com.gh.gamecenter.core.utils.NumberUtils
import com.gh.gamecenter.databinding.ForumMyFollowBinding
import com.gh.gamecenter.entity.ForumEntity
import com.gh.gamecenter.eventbus.EBForumFollowChange
@ -58,7 +59,6 @@ class ForumListAdapter(
holder.binding.run {
root.setBackgroundColor(R.color.ui_surface.toColor(mContext))
forumNameTv.setTextColor(R.color.text_primary.toColor(mContext))
topLine.setBackgroundColor(R.color.ui_divider.toColor(mContext))
val forumEntity = mEntityList[position]
forumNameTv.text = forumEntity.name
@ -71,14 +71,16 @@ class ForumListAdapter(
forumEntity.game.iconFloat
)
}
topLine.visibility = if (position == 0) View.GONE else View.VISIBLE
if (mViewModel?.type == ForumListActivity.TYPE_FOLLOW) {
moreIv.visibility = View.VISIBLE
followTv.visibility = View.GONE
hotTv.visibility = View.GONE
} else {
moreIv.visibility = View.GONE
followTv.visibility = View.VISIBLE
hotTv.visibility = View.VISIBLE
hotTv.text = NumberUtils.transSimpleCount(forumEntity.hot)
followTv.run {
text = if (forumEntity.me.isFollowForum) {

View File

@ -13,17 +13,17 @@ class ForumListFragment : ListFragment<ForumEntity, ForumListViewModel>() {
private var mAdapter: ForumListAdapter? = null
private var mViewModel: ForumListViewModel? = null
private var type = ""
override fun provideListAdapter() = mAdapter
?: ForumListAdapter(requireContext(), mEntrance, provideListViewModel()).apply { mAdapter = this }
override fun provideListViewModel() = viewModelProvider<ForumListViewModel>()
override fun getItemDecoration() = SpacingItemDecoration(onlyDecorateTheFirstItem = true, top = 8F.dip2px())
override fun getItemDecoration() = SpacingItemDecoration(onlyDecorateTheFirstItem = true, top = 0.5F.dip2px())
override fun onCreate(savedInstanceState: Bundle?) {
val type = arguments?.getString(EntranceConsts.KEY_TYPE) ?: ""
type = arguments?.getString(EntranceConsts.KEY_TYPE) ?: ""
mViewModel = provideListViewModel()
mViewModel?.type = type
when (type) {
@ -31,6 +31,7 @@ class ForumListFragment : ListFragment<ForumEntity, ForumListViewModel>() {
setNavigationTitle("关注论坛")
mViewModel?.setOverLimitSize(1000)
}
ForumListActivity.TYPE_HOT -> setNavigationTitle("热门论坛")
ForumListActivity.TYPE_OFFICIAL -> setNavigationTitle("综合论坛")
}

View File

@ -42,7 +42,7 @@ class ModeratorListFragment : ToolbarFragment() {
mViewModel?.isModerators?.observe(this, Observer {
if (it) {
mBinding.applyTv.background = R.drawable.bg_forum_follow.toDrawable()
mBinding.applyTv.background = R.drawable.bg_forum_follow.toDrawable(requireContext())
mBinding.applyTv.setTextColor(R.color.text_theme.toColor(requireContext()))
mBinding.applyTv.text = "您已是版主"
mBinding.applyTv.setOnClickListener {

View File

@ -11,7 +11,7 @@ interface CommunitySearchEventListener {
fun onItemExposed(contentId: String?, itemType: String?, title: String?, sequence: Int)
// 在论坛搜索点击论坛item进入论坛详情
fun onBbsItemClick(sequence: Int, bbsId: String, name: String)
fun onBbsItemClick(sequence: Int, bbsId: String, name: String, button: String)
companion object {

View File

@ -295,7 +295,8 @@ class ForumContentSearchListAdapter(
eventListener.onBbsItemClick(
position,
answer.questions.id,
htmlToString(answer.questions.title)
htmlToString(answer.questions.title),
BUTTON_VIEW_FORUM_DETAIL
)
mContext.startActivity(
ForumVideoDetailActivity.getIntent(
@ -426,7 +427,8 @@ class ForumContentSearchListAdapter(
eventListener.onBbsItemClick(
position,
answer.questions.id,
htmlToString(answer.questions.title)
htmlToString(answer.questions.title),
BUTTON_VIEW_FORUM_DETAIL
)
}
}
@ -443,12 +445,16 @@ class ForumContentSearchListAdapter(
}
}
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)
}
companion object {
private const val BUTTON_VIEW_FORUM_DETAIL = "查看论坛详情"
}
class ForumSearchContentListViewHolder(val binding: ForumSearchContentListBinding) :
BaseRecyclerViewHolder<Any>(binding.root)
}

View File

@ -173,13 +173,14 @@ class ForumContentSearchListFragment : LazyListFragment<AnswerEntity, ForumConte
)
}
override fun onBbsItemClick(sequence: Int, bbsId: String, name: String) {
override fun onBbsItemClick(sequence: Int, bbsId: String, name: String, button: String) {
NewFlatLogUtils.logSearchBbsClick(
SearchType.fromString(mSearchType).toChinese(),
mSearchKey,
bbsId,
sequence + 1,
name
name,
button
)
}
}

View File

@ -1,29 +1,33 @@
package com.gh.gamecenter.qa.dialog
import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.gamecenter.common.constant.ItemViewType
import com.gh.common.util.*
import com.gh.common.util.CheckLoginUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.viewholder.FooterViewHolder
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.utils.fromHtml
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.toDrawable
import com.gh.gamecenter.core.utils.HtmlUtils
import com.gh.gamecenter.databinding.ForumItemBinding
import com.gh.gamecenter.common.constant.ItemViewType
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.viewholder.FooterViewHolder
import com.gh.gamecenter.core.utils.HtmlUtils
import com.gh.gamecenter.core.utils.NumberUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.databinding.ForumItemBinding
import com.gh.gamecenter.entity.ForumEntity
import com.gh.gamecenter.eventbus.EBForumFollowChange
import org.greenrobot.eventbus.EventBus
class ChooseForumContainerAdapter(
content: Context,
val type: String,
val viewModel: ChooseForumContainerViewModel,
private val entrance: String,
private val childClick: (Int, ForumEntity, String) -> Unit,
val onSelectCallback: ((entity: CommunityEntity, position: Int) -> Unit)? = null
) : ListAdapter<ForumEntity>(content) {
@ -63,18 +67,27 @@ class ChooseForumContainerAdapter(
if (holder is ForumItemViewHolder) {
val forumEntity = mEntityList[position]
holder.binding.forumNameTv.text = forumEntity.name.fromHtml()
holder.binding.followTv.background =
if (forumEntity.isFollow) R.drawable.button_round_gray_light.toDrawable() else R.drawable.bg_forum_follow.toDrawable()
holder.binding.followTv.text = if (forumEntity.isFollow) "已关注" else "关注"
val drawableResId =
if (forumEntity.me.isFollowForum) R.drawable.bg_forum_already_follow else R.drawable.bg_forum_follow
holder.binding.followTv.background = drawableResId.toDrawable(holder.itemView.context)
holder.binding.followTv.text = if (forumEntity.me.isFollowForum) "已关注" else "关注"
holder.binding.followTv.setTextColor(
if (forumEntity.isFollow) R.color.text_tertiary.toColor(mContext) else R.color.text_theme.toColor(
if (forumEntity.me.isFollowForum) R.color.text_tertiary.toColor(mContext) else R.color.primary_theme.toColor(
mContext
)
)
holder.binding.hotTv.text = NumberUtils.transSimpleCount(forumEntity.hot)
holder.binding.followTv.setOnClickListener {
val button = if (forumEntity.me.isFollowForum) BUTTON_UN_FOLLOW else BUTTON_FOLLOW
childClick(position, forumEntity, button)
handleFollowTvClick(holder.binding, forumEntity)
}
val icon = forumEntity.icon.ifEmpty { forumEntity.game.getIcon() }
holder.binding.forumIcon.displayGameIcon(icon, forumEntity.game.iconSubscript, forumEntity.game.iconFloat)
holder.binding.followTv.visibility = View.GONE
holder.itemView.setOnClickListener {
val tabType = if (type == ChooseForumContainerFragment.ChooseForumType.SEARCH.value) "论坛tab" else ""
val bbsType = if (forumEntity.type == "official_bbs") "综合论坛" else "游戏论坛"
@ -98,6 +111,8 @@ class ChooseForumContainerAdapter(
iconSubscript = forumEntity.game.iconSubscript
), position
)
childClick(position, forumEntity, VIEW_FORUM_DETAIL)
}
} else if (holder is FooterViewHolder) {
holder.initItemPadding()
@ -107,5 +122,47 @@ class ChooseForumContainerAdapter(
}
}
private fun handleFollowTvClick(binding: ForumItemBinding, forumEntity: ForumEntity) {
binding.run {
debounceActionWithInterval(R.id.followTv) {
CheckLoginUtils.checkLogin(mContext, entrance) {
if (forumEntity.me.isFollowForum) {
viewModel.unFollowForum(forumEntity.id) {
forumEntity.me.isFollowForum = false
followTv.background = R.drawable.bg_forum_follow.toDrawable(mContext)
followTv.setTextColor(R.color.primary_theme.toColor(mContext))
followTv.text = "关注"
ToastUtils.showToast("取消成功")
EventBus.getDefault().post(EBForumFollowChange(newEntity(forumEntity), false))
}
} else {
viewModel.followForum(forumEntity.id) {
forumEntity.me.isFollowForum = true
followTv.background = R.drawable.bg_forum_already_follow.toDrawable(mContext)
followTv.setTextColor(R.color.text_tertiary.toColor(mContext))
followTv.text = "已关注"
ToastUtils.showToast("关注成功")
EventBus.getDefault().post(EBForumFollowChange(newEntity(forumEntity), true))
}
}
}
}
}
}
private fun newEntity(forumEntity: ForumEntity) = with(forumEntity) {
ForumEntity(
id, game, HtmlUtils.stripHtml(name), icon, isFollow, isRecommend, orderTag, unread, type, me, hot
)
}
companion object {
private const val BUTTON_FOLLOW = "关注"
private const val BUTTON_UN_FOLLOW = "取消关注"
private const val VIEW_FORUM_DETAIL = "查看论坛详情"
}
class ForumItemViewHolder(val binding: ForumItemBinding) : BaseRecyclerViewHolder<ForumEntity>(binding.root)
}

View File

@ -4,6 +4,7 @@ import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchActivity.Companion.trackSearchResultClick
@ -12,6 +13,7 @@ import com.gh.gamecenter.common.baselist.LazyListFragment
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.core.utils.HtmlUtils
import com.gh.gamecenter.entity.ForumEntity
import com.gh.gamecenter.forum.detail.ForumDetailActivity
@ -21,21 +23,34 @@ class ChooseForumContainerFragment : LazyListFragment<ForumEntity, ChooseForumCo
private var type: String = ""
private var mSearchKey: String = ""
private var mIsFirstIn = true
private var mSearchType = SearchType.DEFAULT.value
private var entrance = ""
override fun onFragmentFirstVisible() {
type = arguments?.getString(EntranceConsts.KEY_CHOOSE_FORUM_TYPE) ?: ""
entrance =
if (type == ChooseForumType.ATTENTION.value) "我的关注tab" else if (type == ChooseForumType.HOT.value) "热门论坛tab" else "搜索结果"
mReuseNoData?.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.ui_surface))
super.onFragmentFirstVisible()
}
override fun provideListAdapter(): ListAdapter<*> {
return mAdapter ?: ChooseForumContainerAdapter(requireContext(), type, mListViewModel) { enity, position ->
return mAdapter ?: ChooseForumContainerAdapter(
requireContext(),
type,
mListViewModel,
mEntrance,
childClick = { position, forumEntity, button ->
NewFlatLogUtils.logSearchBbsClick(
mSearchType, mSearchKey, forumEntity.id, position + 1, HtmlUtils.stripHtml(forumEntity.name), button
)
}
) { enity, position ->
trackSearchResultClick(mSearchKey, mSearchType)
if (requireActivity() is ChooseForumActivity) {
(requireActivity() as ChooseForumActivity).chooseSuccess(enity)
val entrance =
if (type == ChooseForumType.ATTENTION.value) "我的关注tab" else if (type == ChooseForumType.HOT.value) "热门论坛tab" else "搜索结果"
val bbsType = if (enity.type == "game_bbs") "游戏论坛" else "综合论坛"
NewLogUtils.logChooseForumPanelClick("click_select_forum_panel_forum", entrance, enity.id, bbsType)
} else {
@ -81,6 +96,7 @@ class ChooseForumContainerFragment : LazyListFragment<ForumEntity, ChooseForumCo
}
companion object {
fun getInstance(type: ChooseForumType): Fragment {
val bundle = bundleOf(EntranceConsts.KEY_CHOOSE_FORUM_TYPE to type.value)
return ChooseForumContainerFragment().apply {
@ -94,4 +110,5 @@ class ChooseForumContainerFragment : LazyListFragment<ForumEntity, ChooseForumCo
HOT("hot"),
SEARCH("search")
}
}

View File

@ -1,5 +1,6 @@
package com.gh.gamecenter.qa.dialog
import android.annotation.SuppressLint
import android.app.Application
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
@ -8,6 +9,7 @@ import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.SearchType
import com.gh.gamecenter.common.baselist.ListViewModel
import com.gh.gamecenter.common.baselist.LoadType
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.entity.ForumEntity
import com.gh.gamecenter.forum.search.ForumOrUserSearchActivity.Companion.LOCATION_COMMUNITY
import com.gh.gamecenter.login.user.UserManager
@ -15,6 +17,10 @@ import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.retrofit.service.ApiService
import com.halo.assistant.HaloApp
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
class ChooseForumContainerViewModel(
application: Application,
@ -23,7 +29,9 @@ class ChooseForumContainerViewModel(
var searchType: String
) :
ListViewModel<ForumEntity, ForumEntity>(application) {
private val mApi: ApiService = RetrofitManager.getInstance().api
private val mCompositeDisposable = CompositeDisposable()
private var mPage = 0
@ -68,6 +76,36 @@ class ChooseForumContainerViewModel(
}
}
fun followForum(bbsId: String, onSuccess: () -> Unit) {
val disposable = mApi
.followForum(bbsId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<ResponseBody>() {
override fun onSuccess(data: ResponseBody) {
onSuccess.invoke()
}
})
mCompositeDisposable.add(disposable)
}
fun unFollowForum(bbsId: String, onSuccess: () -> Unit) {
val disposable = mApi.unFollowForum(bbsId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<ResponseBody>() {
override fun onSuccess(data: ResponseBody) {
onSuccess.invoke()
}
})
mCompositeDisposable.add(disposable)
}
override fun onCleared() {
super.onCleared()
mCompositeDisposable.clear()
}
class Factory(val type: String, val searchKey: String, val searchType: String) :
ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T {

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="999dp" />
<solid android:color="@color/ui_container_2" />
</shape>

View File

@ -2,5 +2,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="999dp" />
<solid android:color="@color/text_EEF5FB" />
<solid android:color="@color/primary_theme_10" />
</shape>

View File

@ -1,36 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/ui_surface"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingLeft="16dp"
android:paddingStart="16dp"
android:paddingTop="12dp"
android:paddingRight="20dp"
android:paddingEnd="16dp"
android:paddingBottom="12dp">
<com.gh.gamecenter.feature.view.GameIconView
android:id="@+id/forumIcon"
android:layout_width="44dp"
android:layout_height="44dp" />
android:layout_width="48dp"
android:layout_height="48dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/forumNameTv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginRight="20dp"
android:layout_weight="1"
android:layout_marginStart="12dp"
android:layout_marginEnd="16dp"
android:ellipsize="end"
android:maxLines="1"
android:textStyle="bold"
android:textColor="@color/text_primary"
android:textSize="14sp" />
android:textSize="14sp"
app:layout_constraintEnd_toStartOf="@id/followTv"
app:layout_constraintStart_toEndOf="@id/forumIcon"
app:layout_constraintTop_toTopOf="@id/forumIcon"
app:layout_constraintBottom_toTopOf="@id/hotTv"
app:layout_constraintVertical_chainStyle="packed"
tools:text="口袋妖怪-游戏标题游戏游戏标题游戏游戏标题游戏" />
<TextView
android:id="@+id/hotTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:drawablePadding="4dp"
android:textColor="@color/text_A2ADB8"
android:textSize="10sp"
app:drawableStartCompat="@drawable/ic_forum_heat"
app:layout_constraintStart_toStartOf="@id/forumNameTv"
app:layout_constraintTop_toBottomOf="@id/forumNameTv"
app:layout_constraintBottom_toBottomOf="@id/forumIcon"
tools:text="1688" />
<TextView
android:id="@+id/followTv"
android:layout_width="56dp"
android:layout_height="28dp"
android:gravity="center"
android:textSize="12sp" />
</LinearLayout>
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="关注" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,22 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:background="@color/ui_surface"
android:orientation="vertical">
<View
android:id="@+id/topLine"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:background="@color/ui_divider" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_height="72dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingLeft="16dp"
@ -27,18 +20,36 @@
android:layout_width="48dp"
android:layout_height="48dp" />
<TextView
android:id="@+id/forumNameTv"
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginRight="20dp"
android:orientation="vertical"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@color/text_primary"
android:textSize="14sp"
android:textStyle="bold" />
android:layout_marginStart="12dp"
android:layout_marginEnd="16dp">
<TextView
android:id="@+id/forumNameTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
tools:text="口袋妖怪"
android:textColor="@color/text_primary"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:id="@+id/hotTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="4dp"
tools:text="1688"
android:textSize="10sp"
android:drawablePadding="4dp"
android:textColor="@color/text_A2ADB8"
app:drawableStartCompat="@drawable/ic_forum_heat" />
</LinearLayout>
<ImageView
android:id="@+id/moreIv"
@ -50,7 +61,7 @@
android:id="@+id/followTv"
style="@style/PrimaryLightButton"
android:layout_width="56dp"
android:layout_height="24dp"
android:layout_height="28dp"
android:gravity="center"
android:text="关注"
android:textSize="12sp"