Compare commits

...

4 Commits

42 changed files with 1183 additions and 337 deletions

View File

@ -72,7 +72,7 @@ android_build:
only:
- dev
- release
- feature-GHZS-5816
- feat/GHZSCY-5585
# 代码检查
sonarqube_analysis:
@ -104,6 +104,7 @@ sonarqube_analysis:
only:
- dev
- release
- feat/GHZSCY-5585
## 发送简易检测结果报告
send_sonar_report:
@ -122,6 +123,7 @@ send_sonar_report:
only:
- dev
- release
- feat/GHZSCY-5585
oss-upload&send-email:
tags:
@ -154,4 +156,4 @@ oss-upload&send-email:
only:
- dev
- release
- feature-GHZS-5816
- feat/GHZSCY-5585

View File

@ -792,6 +792,12 @@
android:screenOrientation="portrait"
android:theme="@style/AppCompatTheme.APP" />
<activity
android:name=".search.SearchTabActivity"
android:configChanges="keyboardHidden"
android:screenOrientation="portrait"
android:theme="@style/AppCompatTheme.APP" />
<!-- <activity-->
<!-- android:name="${applicationId}.douyinapi.DouYinEntryActivity"-->
<!-- android:launchMode="singleTask"-->

View File

@ -0,0 +1,36 @@
package com.gh.common.provider
import android.content.Context
import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.ISearchTabUtilsProvider
import com.gh.gamecenter.search.viewmodel.SearchTabViewModel
@Route(path = RouteConsts.provider.searchTabUtils, name = "SearchTabUtils暴露服务")
class SearchTabUtilsProviderImpl : ISearchTabUtilsProvider {
override fun obtainParentViewModel(fragment: Fragment): ViewModel {
val store = (fragment.parentFragment ?: fragment).viewModelStore
val factory = fragment.defaultViewModelProviderFactory
return ViewModelProvider(
store,
factory
).get(SearchTabViewModel::class.java)
}
override fun getKeyAndTypeLiveData(viewModel: ViewModel?): LiveData<Pair<String, String>>? =
if (viewModel is SearchTabViewModel) {
viewModel.searchKeyAndType
} else {
null
}
override fun init(context: Context?) {
// no implement
}
}

View File

@ -79,6 +79,7 @@ import com.gh.gamecenter.qa.questions.newdetail.NewQuestionDetailActivity
import com.gh.gamecenter.qa.subject.CommunitySubjectActivity
import com.gh.gamecenter.qa.video.detail.ForumVideoDetailActivity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.servers.GameServerTestActivity
import com.gh.gamecenter.servers.GameServersActivity
import com.gh.gamecenter.servers.gametest2.GameServerTestV2Activity

View File

@ -652,12 +652,14 @@ object NewFlatLogUtils {
@JvmStatic
fun logSearchBbs(
searchType: String,
searchKey: String
searchKey: String,
location: String
) {
json {
KEY_EVENT to "search_bbs"
"search_type" to searchType
"key" to searchKey
KEY_LOCATION to location
parseAndPutMeta()()
}.let(::log)
}
@ -669,7 +671,8 @@ object NewFlatLogUtils {
bbsId: String,
sequence: Int,
name: String,
button: String
button: String,
location: String
) {
json {
KEY_EVENT to "search_bbs_click"
@ -679,6 +682,7 @@ object NewFlatLogUtils {
"sequence" to sequence
"name" to name
"button" to button
KEY_LOCATION to location
parseAndPutMeta()()
}.let(::log)
}
@ -686,12 +690,14 @@ object NewFlatLogUtils {
@JvmStatic
fun logSearchUser(
searchType: String,
searchKey: String
searchKey: String,
location: String
) {
json {
KEY_EVENT to "search_user"
"search_type" to searchType
"key" to searchKey
KEY_LOCATION to location
parseAndPutMeta()()
}.let(::log)
}
@ -702,7 +708,8 @@ object NewFlatLogUtils {
searchKey: String,
userId: String,
name: String,
sequence: Int
sequence: Int,
location: String
) {
json {
KEY_EVENT to "search_user_click"
@ -711,6 +718,7 @@ object NewFlatLogUtils {
"user_id" to userId
"name" to name
"sequence" to sequence
KEY_LOCATION to location
parseAndPutMeta()()
}.let(::log)
}
@ -1335,7 +1343,13 @@ object NewFlatLogUtils {
}
// 上传存档弹窗点击事件
fun logCloudArchiveUploadDialogClick(gameId: String, gameName: String, cloudSaveId: String, cloudSaveName: String, isSuccess: Boolean) {
fun logCloudArchiveUploadDialogClick(
gameId: String,
gameName: String,
cloudSaveId: String,
cloudSaveName: String,
isSuccess: Boolean
) {
val json = json {
KEY_EVENT to "cloud_save_upload_dialog_click"
KEY_GAME_ID to gameId

View File

@ -20,6 +20,7 @@ import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.db.ISearchHistoryDao
import com.gh.gamecenter.db.SearchHistoryDao
import com.gh.gamecenter.eventbus.EBSearch
import com.gh.gamecenter.search.SearchTabActivity
import com.gh.gamecenter.search.SearchDefaultFragment
import com.gh.gamecenter.search.SearchGameIndexFragment
import com.gh.gamecenter.search.SearchGameResultFragment
@ -50,7 +51,11 @@ open class SearchActivity : BaseActivity() {
private var mPublishSubject: PublishSubject<String>? = null
private var mSourceEntrance: String = ""
/**
* 神策的 SourceEntrance 字段相当于 火山云的 location
* 如果有火山云埋点需要上传 location 字段,那么直接使用此字段的值就行
*/
protected var mSourceEntrance: String = ""
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
@ -115,27 +120,10 @@ open class SearchActivity : BaseActivity() {
updateDisplayType(DEFAULT)
}
trackSearchPageShow()
}
protected open fun trackSearchPageShow(){
val bottomTab = intent.getStringExtra(EntranceConsts.KEY_BOTTOM_TAB_NAME) ?: ""
val multiTabId = intent.getStringExtra(EntranceConsts.KEY_MULTI_TAB_NAV_ID) ?: ""
val multiTabName = intent.getStringExtra(EntranceConsts.KEY_MULTI_TAB_NAV_NAME) ?: ""
val customPageId = intent.getStringExtra(EntranceConsts.KEY_CUSTOM_PAGE_ID) ?: ""
val customPageName = intent.getStringExtra(EntranceConsts.KEY_CUSTOM_PAGE_NAME) ?: ""
val searchBoxPattern = intent.getStringExtra(EntranceConsts.KEY_SEARCH_BOX_PATTERN) ?: ""
SensorsBridge.trackSearchPageShow(
SensorsBridge.trackGameSearchPageShow(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
intent.getStringExtra(EntranceConsts.KEY_SOURCE_ENTRANCE) ?: "",
bottomTab,
multiTabId,
multiTabName,
customPageId,
customPageName,
searchBoxPattern
mSourceEntrance
)
}
@ -203,12 +191,12 @@ open class SearchActivity : BaseActivity() {
updateDisplayType(GAME_DIGEST)
LogUtils.uploadSearchGame("searching", "搜索页", key, "自动搜索")
SensorsBridge.trackSearchButtonClick(
SensorsBridge.trackGameSearchPageButtonClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
mSourceEntrance,
key ?: "",
TRACK_SEARCH_TYPE_INPUT,
mSourceEntrance
TRACK_SEARCH_TYPE_AUTO
)
}
}
@ -220,14 +208,13 @@ open class SearchActivity : BaseActivity() {
updateDisplayType(GAME_DETAIL)
LogUtils.uploadSearchGame("searching", "搜索页", key, "默认搜索")
SensorsBridge.trackSearchButtonClick(
SensorsBridge.trackGameSearchPageButtonClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
mSourceEntrance,
key ?: "",
TRACK_SEARCH_TYPE_DEFAULT,
mSourceEntrance
TRACK_SEARCH_TYPE_DEFAULT
)
// MtaHelper.onEvent("游戏搜索", "默认搜索", key)
}
protected open fun handleHotSearch(key: String?) {
@ -244,14 +231,13 @@ open class SearchActivity : BaseActivity() {
updateDisplayType(GAME_DETAIL)
LogUtils.uploadSearchGame("searching", "搜索页", key, "历史搜索")
SensorsBridge.trackSearchButtonClick(
SensorsBridge.trackGameSearchPageButtonClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
mSourceEntrance,
key ?: "",
TRACK_SEARCH_TYPE_HISTORY,
mSourceEntrance
TRACK_SEARCH_TYPE_HISTORY
)
// MtaHelper.onEvent("游戏搜索", "历史搜索", key)
}
protected open fun handleManualSearch() {
@ -265,16 +251,16 @@ open class SearchActivity : BaseActivity() {
} else if (newSearchKey != mSearchKey || mDisplayType != GAME_DETAIL) {
mSearchKey = newSearchKey
if (!TextUtils.isEmpty(mSearchKey)) {
SensorsBridge.trackSearchButtonClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
newSearchKey,
TRACK_SEARCH_TYPE_INPUT,
mSourceEntrance
)
mDao.add(mSearchKey)
updateDisplayType(GAME_DETAIL)
SensorsBridge.trackGameSearchPageButtonClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
mSourceEntrance,
newSearchKey,
TRACK_SEARCH_TYPE_INPUT
)
} else {
toast("请输入搜索内容")
}
@ -362,13 +348,15 @@ open class SearchActivity : BaseActivity() {
private const val KEY_SEARCH_IMMEDIATELY = "search_immediately"
private const val HINT_TEXT = "搜索游戏..."
const val TRACK_SEARCH_TYPE_AUTO = "自动搜索"
const val TRACK_SEARCH_TYPE_INPUT = "输入搜索"
const val TRACK_SEARCH_TYPE_DEFAULT = "默认搜索"
const val TRACK_SEARCH_TYPE_HISTORY = "历史搜索"
@JvmStatic
fun toTrackSearchType(type: String) = when (type) {
SearchType.AUTO.value, SearchType.MANUAL.value -> TRACK_SEARCH_TYPE_INPUT
SearchType.AUTO.value -> TRACK_SEARCH_TYPE_AUTO
SearchType.MANUAL.value -> TRACK_SEARCH_TYPE_INPUT
SearchType.HISTORY.value -> TRACK_SEARCH_TYPE_HISTORY
else -> TRACK_SEARCH_TYPE_DEFAULT
}
@ -380,7 +368,8 @@ open class SearchActivity : BaseActivity() {
hint: String,
entrance: String,
sourceEntrance: String
): Intent = getIntent(context, searchImmediately, hint, entrance, sourceEntrance, "", "", "", "", "", "")
): Intent =
getIntent(context, searchImmediately, hint, entrance, sourceEntrance, "", "", "", "", "", "")
@JvmStatic
fun getIntent(
@ -396,7 +385,7 @@ open class SearchActivity : BaseActivity() {
customPageName: String = "",
searchBoxPattern: String = ""
): Intent {
val intent = Intent(context, SearchActivity::class.java)
val intent = Intent(context, SearchTabActivity::class.java)
intent.putExtra(KEY_SEARCH_IMMEDIATELY, searchImmediately)
intent.putExtra(EntranceConsts.KEY_HINT, hint)
intent.putExtra(EntranceConsts.KEY_ENTRANCE, entrance)

View File

@ -82,9 +82,6 @@ class AmwaySearchActivity : SearchActivity() {
transaction.commitAllowingStateLoss()
}
// 安利墙搜索页不需要神策埋点
override fun trackSearchPageShow() = Unit
companion object {
fun getIntent(context: Context): Intent {
val intent = Intent(context, AmwaySearchActivity::class.java)

View File

@ -1,7 +1,9 @@
package com.gh.gamecenter.forum.search
import android.os.Bundle
import android.view.View
import androidx.core.content.ContextCompat
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.NewLogUtils
@ -24,12 +26,19 @@ import com.gh.gamecenter.feature.entity.AnswerEntity
import com.gh.gamecenter.forum.home.ForumScrollCalculatorHelper
import com.gh.gamecenter.forum.search.CommunitySearchEventListener.Companion.SEARCH_BUTTON_VIEW_CONTENT_DETAIL
import com.gh.gamecenter.forum.search.ForumOrUserSearchActivity.Companion.LOCATION_COMMUNITY
import com.gh.gamecenter.search.viewmodel.SearchTabViewModel
import com.gh.gamecenter.video.detail.CustomManager
import com.shuyu.gsyvideoplayer.video.base.GSYVideoView
class ForumContentSearchListFragment : LazyListFragment<AnswerEntity, ForumContentSearchListViewModel>(),
CommunitySearchEventListener {
private val parentTabViewModel by viewModels<SearchTabViewModel>(
ownerProducer = {
parentFragment ?: this
}
)
private var mBbsId = ""
private var mSearchKey = ""
private var mSearchType = SearchType.DEFAULT.value
@ -42,6 +51,8 @@ class ForumContentSearchListFragment : LazyListFragment<AnswerEntity, ForumConte
private var mListReachTop = true
private var mIsAutoLoad = true
override fun provideListAdapter(): ListAdapter<*> {
return mAdapter
?: ForumContentSearchListAdapter(
@ -79,6 +90,11 @@ class ForumContentSearchListFragment : LazyListFragment<AnswerEntity, ForumConte
mListViewModel?.updateSearchKeyAndType(mSearchKey, mSearchType)
}
override fun onCreate(savedInstanceState: Bundle?) {
mIsAutoLoad = arguments?.getBoolean(EntranceConsts.KEY_IS_AUTO_LOAD, true) ?: true
super.onCreate(savedInstanceState)
}
override fun onFragmentResume() {
resumeVideo()
super.onFragmentResume()
@ -235,7 +251,12 @@ class ForumContentSearchListFragment : LazyListFragment<AnswerEntity, ForumConte
override fun initRealView() {
super.initRealView()
mListViewModel?.updateSearchKeyAndType(mSearchKey, mSearchType)
if (mIsAutoLoad) {
mListViewModel?.updateSearchKeyAndType(mSearchKey, mSearchType)
}
parentTabViewModel.searchKeyAndType.observe(viewLifecycleOwner) { (key, type) ->
setSearchKeyAndType(key, type)
}
}
override fun getItemDecoration(): RecyclerView.ItemDecoration? {
@ -260,13 +281,16 @@ class ForumContentSearchListFragment : LazyListFragment<AnswerEntity, ForumConte
}
override fun onItemClick(contentId: String?, itemType: String?, title: String?, sequence: Int) {
SensorsBridge.trackSearchResultClick(
SensorsBridge.trackArticleSearchResultClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
mListViewModel.sourceEntrance,
mSearchKey,
SearchActivity.toTrackSearchType(mSearchType),
mListViewModel.sourceEntrance
contentId ?: "",
title ?: ""
)
NewFlatLogUtils.logSearchContentClick(
mLocation,
mBbsId,

View File

@ -89,13 +89,13 @@ class ForumContentSearchListViewModel(application: Application, val bbsId: Strin
mResultLiveData.postValue(it)
if (mPage == 1) {
SensorsBridge.trackSearchResultReturn(
SensorsBridge.trackArticleSearchResultReturn(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
sourceEntrance,
searchKey,
SearchActivity.toTrackSearchType(searchType),
it.isNotEmpty(),
sourceEntrance
it.isNotEmpty()
)
}
}

View File

@ -11,9 +11,7 @@ import com.gh.gamecenter.DisplayType
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.SearchType
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.showKeyBoard
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.db.ISearchHistoryDao
@ -28,7 +26,6 @@ class ForumOrUserSearchActivity : SearchActivity() {
private var mBbsId = ""
private var mLocation = ""
private var mSourceEntrance = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -68,13 +65,6 @@ class ForumOrUserSearchActivity : SearchActivity() {
override fun handleAutoSearch(key: String?) {
mSearchKey = key
updateDisplayType(DisplayType.FORUM_OR_USER)
SensorsBridge.trackSearchButtonClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
key ?: "",
TRACK_SEARCH_TYPE_INPUT,
mSourceEntrance
)
}
override fun handleHistorySearch(key: String?) {
@ -82,13 +72,6 @@ class ForumOrUserSearchActivity : SearchActivity() {
searchEt.setText(key)
searchEt.setSelection(searchEt.text.length)
updateDisplayType(DisplayType.FORUM_OR_USER)
SensorsBridge.trackSearchButtonClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
key ?: "",
TRACK_SEARCH_TYPE_HISTORY,
mSourceEntrance
)
}
private fun handleOtherSearch(type: SearchType) {
@ -103,13 +86,6 @@ class ForumOrUserSearchActivity : SearchActivity() {
} else {
TRACK_SEARCH_TYPE_DEFAULT
}
SensorsBridge.trackSearchButtonClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
newSearchKey,
searchType,
mSourceEntrance
)
} else {
toast("请先输入搜索内容再搜索~")
}

View File

@ -1,7 +1,9 @@
package com.gh.gamecenter.forum.search
import android.os.Bundle
import android.view.View
import androidx.core.content.ContextCompat
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.R
@ -15,31 +17,39 @@ import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.entity.FollowersOrFansEntity
import com.gh.gamecenter.eventbus.EBUserFollow
import com.gh.gamecenter.search.viewmodel.SearchTabViewModel
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
class UserSearchListFragment : LazyListFragment<FollowersOrFansEntity, UserSearchListViewModel>() {
private val parentTabViewModel by viewModels<SearchTabViewModel>(
ownerProducer = { parentFragment ?: this }
)
private var mSearchKey = ""
private var mAdapter: UserSearchListAdapter? = null
private var mSearchType = SearchType.DEFAULT.value
private var mIsAutoLoad = true
override fun provideListAdapter(): ListAdapter<*> {
return mAdapter
?: UserSearchListAdapter(requireContext(), mEntrance, mListViewModel) { userId, name, position ->
SensorsBridge.trackSearchResultClick(
SensorsBridge.trackUserSearchResultClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
mSearchKey,
SearchActivity.toTrackSearchType(mSearchType),
mListViewModel.sourceEntrance
mListViewModel.sourceEntrance,
userId
)
NewFlatLogUtils.logSearchUserClick(
SearchType.fromString(mSearchType).toChinese(),
mSearchKey,
userId,
name,
position + 1
position + 1,
mListViewModel.sourceEntrance
)
}.apply { mAdapter = this }
}
@ -54,6 +64,11 @@ class UserSearchListFragment : LazyListFragment<FollowersOrFansEntity, UserSearc
override fun isAutomaticLoad(): Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
mIsAutoLoad = arguments?.getBoolean(EntranceConsts.KEY_IS_AUTO_LOAD, true) ?: true
super.onCreate(savedInstanceState)
}
fun setSearchKeyAndType(searchKey: String, searchType: String) {
mSearchKey = searchKey
mSearchType = searchType
@ -69,7 +84,13 @@ class UserSearchListFragment : LazyListFragment<FollowersOrFansEntity, UserSearc
override fun initRealView() {
super.initRealView()
mListViewModel?.updateSearchKeyAndType(mSearchKey, mSearchType)
if (mIsAutoLoad) {
mListViewModel?.updateSearchKeyAndType(mSearchKey, mSearchType)
}
parentTabViewModel.searchKeyAndType.observe(viewLifecycleOwner) { (key, type) ->
setSearchKeyAndType(key, type)
}
}
override fun getItemDecoration(): RecyclerView.ItemDecoration? = null

View File

@ -34,7 +34,8 @@ class UserSearchListViewModel(application: Application) :
if (page == 1) {
NewFlatLogUtils.logSearchUser(
SearchType.fromString(searchType).toChinese(),
searchKey
searchKey,
sourceEntrance
)
}
return RetrofitManager.getInstance().api.searchUsers(searchKey, page)
@ -44,13 +45,13 @@ class UserSearchListViewModel(application: Application) :
mResultLiveData.addSource(mListLiveData) {
mResultLiveData.postValue(it)
if (page == 1) {
SensorsBridge.trackSearchResultReturn(
SensorsBridge.trackUserSearchResultReturn(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
sourceEntrance,
searchKey,
SearchActivity.toTrackSearchType(searchType),
it.isNotEmpty(),
sourceEntrance
it.isNotEmpty()
)
}
}

View File

@ -83,6 +83,7 @@ import com.gh.gamecenter.home.video.ScrollCalculatorHelper
import com.gh.gamecenter.login.user.UserViewModel
import com.gh.gamecenter.newsdetail.NewsDetailActivity
import com.gh.gamecenter.packagehelper.PackageViewModel
import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.simulatorgame.SimulatorGameActivity
import com.gh.gamecenter.tag.TagsActivity
import com.gh.gamecenter.video.detail.CustomManager

View File

@ -3,20 +3,13 @@ package com.gh.gamecenter.minigame
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.text.TextUtils
import com.gh.gamecenter.DisplayType
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.SearchType
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.db.ISearchHistoryDao
import com.gh.gamecenter.forum.search.ForumSearchDao
import com.gh.gamecenter.search.SearchDefaultFragment
import com.gh.gamecenter.search.SearchGameResultFragment
import com.lightgame.config.CommonDebug
import com.lightgame.listeners.OnBackPressedListener
/**
* 小游戏-搜索页面

View File

@ -14,18 +14,13 @@ import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.gamecenter.common.base.adapter.FragmentAdapter
import com.gh.common.util.*
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.SearchActivity.Companion.TRACK_SEARCH_TYPE_INPUT
import com.gh.gamecenter.SearchType
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.doOnPageSelected
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.doOnEnd
import com.gh.gamecenter.databinding.DialogChooseForumBinding
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.forum.detail.ForumDetailFragment.Companion.SOURCE_ENTRANCE
/**
* 选择论坛
@ -57,13 +52,6 @@ class ChooseForumActivity : BaseActivity() {
} else {
switchUI(true)
mSearchResultFragment?.setSearchKeyAndType(searchKey, SearchType.MANUAL.value)
SensorsBridge.trackSearchButtonClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
searchKey,
TRACK_SEARCH_TYPE_INPUT,
sourceEntrance
)
}
}
binding.searchEt.setOnTouchListener { _, event ->
@ -82,12 +70,6 @@ class ChooseForumActivity : BaseActivity() {
binding.maskView.setOnClickListener { binding.closeIv.performClick() }
binding.forumContainer.translationY = (DisplayUtils.getScreenHeight()).toFloat()
binding.forumContainer.animate().translationY(0f).setDuration(300).start()
SensorsBridge.trackSearchPageShow(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
SOURCE_ENTRANCE
)
}
private fun initViewPager() {

View File

@ -1,8 +1,10 @@
package com.gh.gamecenter.qa.dialog
import android.os.Bundle
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.NewLogUtils
@ -18,9 +20,14 @@ 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
import com.gh.gamecenter.search.viewmodel.SearchTabViewModel
class ChooseForumContainerFragment : LazyListFragment<ForumEntity, ChooseForumContainerViewModel>() {
private val parentTabViewModel by viewModels<SearchTabViewModel>(
ownerProducer = { parentFragment ?: this }
)
private var mAdapter: ChooseForumContainerAdapter? = null
private var type: String = ""
private var mSearchKey: String = ""
@ -29,6 +36,13 @@ class ChooseForumContainerFragment : LazyListFragment<ForumEntity, ChooseForumCo
private var mSearchType = SearchType.DEFAULT.value
private var entrance = ""
private var mIsAutoLoad = true
override fun onCreate(savedInstanceState: Bundle?) {
mIsAutoLoad = arguments?.getBoolean(EntranceConsts.KEY_IS_AUTO_LOAD, true) ?: true
super.onCreate(savedInstanceState)
}
override fun onFragmentFirstVisible() {
type = arguments?.getString(EntranceConsts.KEY_CHOOSE_FORUM_TYPE) ?: ""
entrance =
@ -46,17 +60,27 @@ class ChooseForumContainerFragment : LazyListFragment<ForumEntity, ChooseForumCo
childClick = { position, forumEntity, button ->
NewFlatLogUtils.logSearchBbsClick(
mSearchType, mSearchKey, forumEntity.id, position + 1, HtmlUtils.stripHtml(forumEntity.name), button
mSearchType,
mSearchKey,
forumEntity.id,
position + 1,
HtmlUtils.stripHtml(forumEntity.name),
button,
mListViewModel.sourceEntrance
)
SensorsBridge.trackForumSearchResultClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
mListViewModel.sourceEntrance,
mListViewModel.searchKey,
SearchActivity.toTrackSearchType(mSearchType),
forumEntity.id,
HtmlUtils.stripHtml(forumEntity.name),
forumEntity.typeChinese
)
}
) { enity, position ->
SensorsBridge.trackSearchResultClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
mSearchKey,
SearchActivity.toTrackSearchType(mSearchType),
mListViewModel.sourceEntrance
)
if (requireActivity() is ChooseForumActivity) {
(requireActivity() as ChooseForumActivity).chooseSuccess(enity)
val bbsType = if (enity.type == "game_bbs") "游戏论坛" else "综合论坛"
@ -82,9 +106,13 @@ class ChooseForumContainerFragment : LazyListFragment<ForumEntity, ChooseForumCo
override fun initRealView() {
super.initRealView()
if (type == ChooseForumType.SEARCH.value) {
if (mIsAutoLoad && type == ChooseForumType.SEARCH.value) {
mListViewModel?.setSearchKeyAndRefresh(mSearchKey, mSearchType)
}
parentTabViewModel.searchKeyAndType.observe(viewLifecycleOwner, { (key, type) ->
setSearchKeyAndType(key, type)
})
}
override fun onChanged(ts: MutableList<ForumEntity>?) {

View File

@ -1,6 +1,5 @@
package com.gh.gamecenter.qa.dialog
import android.annotation.SuppressLint
import android.app.Application
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
@ -13,7 +12,6 @@ import com.gh.gamecenter.common.baselist.LoadType
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.entity.ForumEntity
import com.gh.gamecenter.forum.search.ForumOrUserSearchActivity.Companion.LOCATION_COMMUNITY
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.retrofit.service.ApiService
@ -29,7 +27,7 @@ class ChooseForumContainerViewModel(
val type: String,
var searchKey: String,
var searchType: String,
var sourceEntrance: String
var sourceEntrance: String // 神策sourceEntrance 相当火山云 location
) :
ListViewModel<ForumEntity, ForumEntity>(application) {
@ -47,7 +45,7 @@ class ChooseForumContainerViewModel(
override fun provideDataObservable(page: Int): Observable<MutableList<ForumEntity>> {
mPage = page
if (mPage == 1 && type == ChooseForumContainerFragment.ChooseForumType.SEARCH.value) {
NewFlatLogUtils.logSearchBbs(SearchType.fromString(searchType).toChinese(), searchKey)
NewFlatLogUtils.logSearchBbs(SearchType.fromString(searchType).toChinese(), searchKey, sourceEntrance)
}
return when (type) {
ChooseForumContainerFragment.ChooseForumType.ATTENTION.value -> {
@ -74,13 +72,13 @@ class ChooseForumContainerViewModel(
mResultLiveData.addSource<List<ForumEntity>>(mListLiveData) {
mResultLiveData.postValue(it)
if (mPage == 1) {
SensorsBridge.trackSearchResultReturn(
SensorsBridge.trackForumSearchResultReturn(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
sourceEntrance,
searchKey,
SearchActivity.toTrackSearchType(searchType),
it.isNotEmpty(),
sourceEntrance
it.isNotEmpty()
)
}
}
@ -119,7 +117,13 @@ class ChooseForumContainerViewModel(
class Factory(val type: String, val searchKey: String, val searchType: String, private val sourceEntrance: String) :
ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return ChooseForumContainerViewModel(HaloApp.getInstance().application, type, searchKey, searchType, sourceEntrance) as T
return ChooseForumContainerViewModel(
HaloApp.getInstance().application,
type,
searchKey,
searchType,
sourceEntrance
) as T
}
}
}

View File

@ -11,8 +11,8 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.databind.BindingAdapters
import com.gh.common.util.DirectUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchType
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.HtmlUtils
@ -24,6 +24,7 @@ import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureType
import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.gh.gamecenter.SearchType
import com.gh.gamecenter.search.SearchGameResultAdapter.Companion.setItemCLick
import com.gh.gamecenter.search.SearchGameResultAdapter.Companion.showContentTag
import com.lzf.easyfloat.utils.DisplayUtils
@ -51,7 +52,7 @@ class SearchGameFirstItemViewHolder(
game?.let {
val link = bannerItem.link ?: return@let
// 阿里云埋点
com.gh.common.util.NewFlatLogUtils.logGameSearchFirstGameBannerClick(
NewFlatLogUtils.logGameSearchFirstGameBannerClick(
it.id,
HtmlUtils.stripHtml(it.name),
position + 1,
@ -86,7 +87,7 @@ class SearchGameFirstItemViewHolder(
game?.let {
val link = cardItem.link ?: return@let
// 阿里云埋点
com.gh.common.util.NewFlatLogUtils.logGameSearchFirstGameCardClick(
NewFlatLogUtils.logGameSearchFirstGameCardClick(
it.id,
HtmlUtils.stripHtml(it.name),
cardItem.cardName,

View File

@ -17,11 +17,9 @@ import com.gh.common.util.LogUtils
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.SearchType
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
import com.gh.gamecenter.adapter.viewholder.SearchHistoryViewHolder
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.ItemViewType
@ -418,13 +416,6 @@ class SearchGameIndexAdapter(
gameEntity.adSpaceId,
gameEntity.gameAdSourceId
)
SensorsBridge.trackSearchResultClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
key,
SearchActivity.toTrackSearchType(type),
sourceEntrance
)
}
@ -527,14 +518,6 @@ class SearchGameIndexAdapter(
gameEntity.adSpaceId,
gameEntity.gameAdSourceId
)
SensorsBridge.trackSearchResultClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
key,
SearchActivity.toTrackSearchType(type),
sourceEntrance
)
}
}
}

View File

@ -7,8 +7,6 @@ import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.DirectUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchActivity.Companion.toTrackSearchType
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.DrawableView
@ -89,14 +87,6 @@ class SearchSubjectItemViewHolder(var binding: SearchSubjectItemBinding) : Recyc
subjectRv.layoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
subjectRv.adapter = SearchSubjectAdapter(context, entity.getFilterGame(), "($type-专题)") {
dao?.add(key)
SensorsBridge.trackSearchButtonClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
key,
toTrackSearchType(type),
sourceEntrance
)
if (itemData.adConfig != null) {
NewFlatLogUtils.logClickGameAd(
itemData.adConfig.id,

View File

@ -185,7 +185,13 @@ class SearchGameResultAdapter(
}
bottomDivider.visibility = View.VISIBLE
}
holder.bindSubjectItem(mContext, mEntityList[position], SearchType.fromString(type).toChinese(), key, sourceEntrance = sourceEntrance)
holder.bindSubjectItem(
mContext,
mEntityList[position],
SearchType.fromString(type).toChinese(),
key,
sourceEntrance = sourceEntrance
)
}
is SearchGameFirstItemViewHolder -> {
@ -688,6 +694,16 @@ class SearchGameResultAdapter(
}
if (gameEntity.isMiniGame()) {
SensorsBridge.trackMiniGameSearchResultClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
sourceEntrance,
key,
SearchActivity.toTrackSearchType(type),
gameEntity.id,
gameEntity.name ?: "",
gameEntity.categoryChinese
)
MiniGameItemHelper.launchMiniGame(gameEntity.miniGameAppId, gameEntity.miniGameType)
MiniGameItemHelper.trackMiniGameClick(
gameEntity = gameEntity,
@ -695,6 +711,16 @@ class SearchGameResultAdapter(
searchContent = key,
)
} else {
SensorsBridge.trackGameSearchResultClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
sourceEntrance,
key,
SearchActivity.toTrackSearchType(type),
gameEntity.id,
gameEntity.name ?: "",
gameEntity.categoryChinese
)
GameDetailActivity.startGameDetailActivity(
context, gameEntity,
StringUtils.buildString(
@ -730,14 +756,6 @@ class SearchGameResultAdapter(
gameEntity.name ?: ""
)
}
SensorsBridge.trackSearchResultClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
key,
SearchActivity.toTrackSearchType(type),
sourceEntrance
)
}

View File

@ -11,6 +11,8 @@ import android.view.animation.Animation
import android.view.animation.TranslateAnimation
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.exposure.ExposureListener
import com.gh.common.util.*
@ -18,8 +20,6 @@ import com.gh.common.xapk.XapkInstaller
import com.gh.common.xapk.XapkUnzipStatus
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.SearchType
import com.gh.gamecenter.common.baselist.ListFragment
import com.gh.gamecenter.common.baselist.LoadType
import com.gh.gamecenter.common.constant.EntranceConsts
@ -34,6 +34,9 @@ import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.help.HelpAndFeedbackBridge
import com.gh.gamecenter.pkg.HaloApp
import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.SearchType
import com.gh.gamecenter.search.viewmodel.SearchTabViewModel
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.utils.Util_System_Keyboard
@ -42,6 +45,10 @@ import org.greenrobot.eventbus.ThreadMode
open class SearchGameResultFragment : ListFragment<GameEntity, SearchGameResultViewModel>() {
private val parentTabViewModel by viewModels<SearchTabViewModel>(
ownerProducer = { parentFragment ?: this }
)
private var mAdapter: SearchGameResultAdapter? = null
private var mExposureListener: ExposureListener? = null
private lateinit var mShowAction: Animation
@ -53,6 +60,7 @@ open class SearchGameResultFragment : ListFragment<GameEntity, SearchGameResultV
private var mType: String = ""
private var mLoadingAnimation = false
private var mScrollIng = false
private var mIsAutoLoad = true
private val dataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
@ -68,6 +76,10 @@ open class SearchGameResultFragment : ListFragment<GameEntity, SearchGameResultV
}
}
override fun isAutomaticLoad(): Boolean {
return mIsAutoLoad
}
override fun getLayoutId() = 0
override fun getInflatedLayout() = mBinding.root
@ -105,7 +117,7 @@ open class SearchGameResultFragment : ListFragment<GameEntity, SearchGameResultV
mKey = savedInstanceState.getString(EntranceConsts.KEY_SEARCHKEY) ?: ""
mType = savedInstanceState.getString(SearchActivity.KEY_SEARCH_TYPE) ?: ""
}
mIsAutoLoad = arguments?.getBoolean(EntranceConsts.KEY_IS_AUTO_LOAD, true) ?: true
super.onCreate(savedInstanceState)
mListRefresh?.isEnabled = false
mBinding.reuseNoneData.reuseNoneDataDescTv.visibility = View.VISIBLE
@ -170,6 +182,10 @@ open class SearchGameResultFragment : ListFragment<GameEntity, SearchGameResultV
})
initAnimation()
parentTabViewModel.searchKeyAndType.observe(viewLifecycleOwner, Observer { (key, type) ->
setParams(key, type)
})
}
private fun handleCloseMenuVisibility(recyclerView: RecyclerView) {
@ -251,6 +267,7 @@ open class SearchGameResultFragment : ListFragment<GameEntity, SearchGameResultV
outState.putString(EntranceConsts.KEY_SEARCHKEY, mKey)
outState.putString(SearchActivity.KEY_SEARCH_TYPE, mType)
outState.putBoolean(EntranceConsts.KEY_IS_AUTO_LOAD, mIsAutoLoad)
}
private fun showOpenMenuView() {

View File

@ -7,7 +7,6 @@ import androidx.lifecycle.ViewModelProvider
import com.gh.ad.AdDelegateHelper
import com.gh.common.filter.RegionSettingHelper
import com.gh.common.util.PackageHelper
import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.baselist.ListViewModel
import com.gh.gamecenter.common.baselist.LoadParams
@ -21,7 +20,9 @@ import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.entity.AdConfig
import com.gh.gamecenter.entity.SearchSubjectEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.minigame.MiniGameSearchResultRepository
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.SearchActivity
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
@ -57,6 +58,10 @@ class SearchGameResultViewModel(
mSearchSubjects.clear()
}
override fun loadData() {
super.loadData()
}
override fun mergeResultLiveData() {
mResultLiveData.addSource(mListLiveData) { list ->
mGameEntityList = ArrayList(list)
@ -293,14 +298,27 @@ class SearchGameResultViewModel(
private fun postResultList(resultList: ArrayList<SearchItemData>, list: List<GameEntity>) {
mResultLiveData.postValue(resultList)
if (mPage == 1) {
SensorsBridge.trackSearchResultReturn(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
mSearchKey ?: "",
SearchActivity.toTrackSearchType(mSearchType),
list.isNotEmpty(),
sourceEntrance
)
if (repository is MiniGameSearchResultRepository) {
SensorsBridge.trackMiniGameSearchResultReturn(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
sourceEntrance,
mSearchKey ?: "",
SearchActivity.toTrackSearchType(mSearchType),
list.isNotEmpty()
)
} else {
SensorsBridge.trackGameSearchResultReturn(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
sourceEntrance,
mSearchKey ?: "",
SearchActivity.toTrackSearchType(mSearchType),
list.isNotEmpty()
)
}
}
}
@ -353,7 +371,14 @@ class SearchGameResultViewModel(
private val mSourceEntrance: String
) : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return SearchGameResultViewModel(mApplication, mSearchKey, mIsManuallySearch, repository, mSearchType, mSourceEntrance) as T
return SearchGameResultViewModel(
mApplication,
mSearchKey,
mIsManuallySearch,
repository,
mSearchType,
mSourceEntrance
) as T
}
}

View File

@ -0,0 +1,39 @@
package com.gh.gamecenter.search
import android.os.Bundle
import androidx.activity.viewModels
import com.gh.gamecenter.DisplayType
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.search.fragment.SearchTabFragment
import com.gh.gamecenter.search.viewmodel.SearchTabActivityViewModel
class SearchTabActivity : SearchActivity() {
private val viewModel by viewModels<SearchTabActivityViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.loadTabs()
}
override fun updateDisplayType(type: DisplayType) {
viewModel.updateSearchKeyAndType(mSearchKey, mSearchType.value)
val lastDisplayType = mDisplayType
mDisplayType = type
// 如果上一次展示的是SearchTabFragment并且当前需要展示的也是SearchTabFragment则无需重复显示
if (lastDisplayType != DisplayType.DEFAULT && type != DisplayType.DEFAULT) {
return
}
if (type == DisplayType.DEFAULT) {
super.updateDisplayType(type)
} else {
val transaction = supportFragmentManager.beginTransaction()
val fragment = supportFragmentManager.findFragmentByTag(SearchTabFragment::class.java.name)
?: SearchTabFragment.newInstance(mSourceEntrance)
transaction.replace(R.id.search_result, fragment)
transaction.commitAllowingStateLoss()
}
}
}

View File

@ -0,0 +1,16 @@
package com.gh.gamecenter.search
import com.gh.common.constant.Config
import com.gh.gamecenter.feature.entity.SettingsEntity
import io.reactivex.Single
class SearchTabRepository private constructor() {
fun getSearchTabs(): List<SettingsEntity.Search.Navigation> =
Config.getNewApiSettingsEntity()?.search?.navigations ?: emptyList()
companion object {
fun newInstance() = SearchTabRepository()
}
}

View File

@ -0,0 +1,69 @@
package com.gh.gamecenter.search.adapter
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.feature.entity.SettingsEntity
import com.gh.gamecenter.feedback.view.qa.HelpContentFragment
import com.gh.gamecenter.forum.search.ForumContentSearchListFragment
import com.gh.gamecenter.forum.search.UserSearchListFragment
import com.gh.gamecenter.minigame.MiniGameSearchResultFragment
import com.gh.gamecenter.qa.dialog.ChooseForumContainerFragment
import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.search.SearchGameResultFragment
class SearchTabAdapter(
private val location: String,
private val searchType: String?,
private val tabs: List<SettingsEntity.Search.Navigation>,
private val fragment: Fragment
) : FragmentStateAdapter(fragment) {
override fun getItemCount() = tabs.size
override fun createFragment(position: Int): Fragment {
val navigation = tabs[position]
val bundle = Bundle().apply {
putBoolean(EntranceConsts.KEY_IS_AUTO_LOAD, false)
putString(EntranceConsts.KEY_LOCATION, location)
}
val fragment = when (navigation.type) {
SEARCH_TYPE_GAME -> SearchGameResultFragment()
SEARCH_TYPE_BBS -> ChooseForumContainerFragment.getInstance(ChooseForumContainerFragment.ChooseForumType.SEARCH)
SEARCH_TYPE_BBS_CONTENT -> ForumContentSearchListFragment()
SEARCH_TYPE_USER -> UserSearchListFragment()
SEARCH_TYPE_MINI_GAME -> MiniGameSearchResultFragment()
SEARCH_TYPE_QA -> HelpContentFragment().apply {
arguments = Bundle().apply {
putString(EntranceConsts.KEY_SEARCH_TYPE, SearchActivity.toTrackSearchType(searchType ?: ""))
}
}
else -> SearchGameResultFragment()
}.also {
if (it.arguments != null) {
it.arguments?.putAll(bundle)
} else {
it.arguments = bundle
}
}
return fragment
}
companion object {
private const val SEARCH_TYPE_GAME = "game"
private const val SEARCH_TYPE_BBS = "bbs"
private const val SEARCH_TYPE_BBS_CONTENT = "bbs_content"
private const val SEARCH_TYPE_USER = "user"
private const val SEARCH_TYPE_QA = "qa"
private const val SEARCH_TYPE_MINI_GAME = "mini_game"
private const val SEARCH_TYPE_GAME_LIST = "game_list"
}
}

View File

@ -0,0 +1,141 @@
package com.gh.gamecenter.search.fragment
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.BaseFragment
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.databinding.FragmentSearchTabBinding
import com.gh.gamecenter.feature.entity.SettingsEntity
import com.gh.gamecenter.search.SearchGameResultFragment
import com.gh.gamecenter.search.adapter.SearchTabAdapter
import com.gh.gamecenter.search.viewmodel.SearchTabActivityViewModel
import com.gh.gamecenter.search.viewmodel.SearchTabViewModel
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayout.OnTabSelectedListener
import com.google.android.material.tabs.TabLayoutMediator
class SearchTabFragment : BaseFragment<Any>() {
private lateinit var binding: FragmentSearchTabBinding
private val activityViewModel by activityViewModels<SearchTabActivityViewModel>()
private val viewModel by viewModels<SearchTabViewModel>()
private lateinit var adapter: SearchTabAdapter
private var location = ""
private var _key: String? = null
private var _searchType: String? = null
override fun getLayoutId(): Int = 0
override fun getInflatedLayout() =
FragmentSearchTabBinding.inflate(LayoutInflater.from(context))
.also {
binding = it
}.root
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
location = arguments?.getString(EntranceConsts.KEY_LOCATION) ?: ""
println("kayn -->onCreate:${activityViewModel}")
with(activityViewModel) {
searchKeyAndType.observe(this@SearchTabFragment) { (key, type) ->
println("kayn -->key:$key")
if (key != null) {
_key = key
_searchType = type
println("kayn -->searchKeyAndType:$viewModel")
viewModel.updateSearchKeyAndType(key, type)
}
}
}
}
override fun initView(view: View?) {
super.initView(view)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
with(activityViewModel) {
tabs.observe(viewLifecycleOwner) {
if (it.size > 1) {
initTabs(it)
} else {
initSingleFragment()
}
}
}
}
private fun initTabs(tabs: List<SettingsEntity.Search.Navigation>) {
println("kayn -->initTabs:")
binding.gTabs.goneIf(false)
binding.flContainer.goneIf(true)
binding.tabLayout.addOnTabSelectedListener(object : OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab) {
viewModel.trackGameSearchPageTabClick(location, tab.text?.toString(), tab.position)
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
}
override fun onTabReselected(tab: TabLayout.Tab?) {
}
})
if (tabs.size > 5) {
binding.tabLayout.tabMode = TabLayout.MODE_SCROLLABLE
} else {
binding.tabLayout.tabMode = TabLayout.MODE_FIXED
}
adapter = SearchTabAdapter(location, _searchType, tabs, this)
binding.viewPager.adapter = adapter
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
tab.text = tabs[position].title
tab.customView?.setBackgroundColor(Color.RED)
}.attach()
}
private fun initSingleFragment() {
binding.gTabs.goneIf(true)
binding.flContainer.goneIf(false)
val transaction = childFragmentManager.beginTransaction()
val fragment = childFragmentManager.findFragmentByTag(SearchGameResultFragment::class.java.name)
?: SearchGameResultFragment().apply {
arguments = Bundle().apply {
putBoolean(EntranceConsts.KEY_IS_AUTO_LOAD, false)
}
}
transaction.replace(R.id.fl_container, fragment, SearchGameResultFragment::class.java.name)
transaction.commitAllowingStateLoss()
}
companion object {
fun newInstance(location: String) =
SearchTabFragment().apply {
arguments = Bundle().apply {
putString(EntranceConsts.KEY_LOCATION, location)
}
}
}
}

View File

@ -0,0 +1,26 @@
package com.gh.gamecenter.search.viewmodel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.gh.gamecenter.feature.entity.SettingsEntity
import com.gh.gamecenter.search.SearchTabRepository
class SearchTabActivityViewModel : ViewModel() {
private val repository = SearchTabRepository.newInstance()
private val _searchKeyAndType = MutableLiveData<Pair<String?, String>>()
val searchKeyAndType: LiveData<Pair<String?, String>> = _searchKeyAndType
fun updateSearchKeyAndType(key: String?, type: String) {
_searchKeyAndType.value = key to type
}
private val _tabs = MutableLiveData<List<SettingsEntity.Search.Navigation>>()
val tabs: LiveData<List<SettingsEntity.Search.Navigation>> = _tabs
fun loadTabs() {
_tabs.value = repository.getSearchTabs()
}
}

View File

@ -0,0 +1,29 @@
package com.gh.gamecenter.search.viewmodel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.utils.SensorsBridge
import io.reactivex.disposables.CompositeDisposable
class SearchTabViewModel : ViewModel() {
private val _searchKeyAndType = MutableLiveData<Pair<String, String>>()
val searchKeyAndType: LiveData<Pair<String, String>> = _searchKeyAndType
fun updateSearchKeyAndType(key: String, type: String) {
_searchKeyAndType.value = key to type
}
fun trackGameSearchPageTabClick(location: String, text: String?, position: Int) {
SensorsBridge.trackGameSearchPageTabClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
location,
searchKeyAndType.value?.first ?: "",
searchKeyAndType.value?.second ?: "",
text ?: "",
position
)
}
}

View File

@ -1,11 +1,9 @@
package com.gh.gamecenter.vote
import android.annotation.SuppressLint
import android.app.Application
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
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.ApiResponse

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:gravity="center">
<shape>
<size
android:width="20dp"
android:height="3dp" />
<corners android:radius="3dp" />
<solid android:color="@color/primary_theme" />
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="0dp"
android:layout_height="45dp"
android:background="@color/ui_surface"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tabBackground="@color/ui_surface"
app:tabIndicator="@drawable/search_tab_indicator"
app:tabIndicatorHeight="3dp"
app:tabPaddingEnd="12dp"
app:tabPaddingStart="12dp"
app:tabSelectedTextColor="@color/text_theme" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tab_layout" />
<androidx.constraintlayout.widget.Group
android:id="@+id/g_tabs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="tab_layout,view_pager" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fl_container"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -5,6 +5,7 @@ import android.text.TextUtils
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.baselist.NormalListViewModel
import com.gh.gamecenter.common.constant.ItemViewType
@ -21,7 +22,9 @@ class HelpContentAdapter(
private val mViewModel: NormalListViewModel<HelpEntity>,
private val mQaId: String?,
private val mQaCollectionId: String?,
private val mNavigationTitle: String
private val mNavigationTitle: String,
private val searchType: String,
private val location: String
) : ListAdapter<HelpEntity>(context) {
var searchKey = ""
@ -103,6 +106,15 @@ class HelpContentAdapter(
entity.helpId
)
}
SensorsBridge.trackQASearchResultClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
location,
searchKey,
searchType,
entity.id,
entity.title
)
}
}

View File

@ -7,12 +7,17 @@ import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.RecyclerView
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.baselist.ListFragment
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.baselist.LoadType
import com.gh.gamecenter.common.baselist.NormalListViewModel
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.toDrawable
import com.gh.gamecenter.core.provider.ISearchTabUtilsProvider
import com.gh.gamecenter.core.utils.UrlFilterUtils
import com.gh.gamecenter.feedback.HaloApp
import com.gh.gamecenter.feedback.R
@ -40,12 +45,27 @@ class HelpContentFragment : ListFragment<HelpEntity, NormalListViewModel<HelpEnt
private var mNavigationTitle = ""
var searchKey: String? = null
private var mLocation = ""
private var mSearchType = ""
private val iSearchTabUtilsProvider: ISearchTabUtilsProvider?
get() = ARouter.getInstance().build(RouteConsts.provider.searchTabUtils)
.navigation() as? ISearchTabUtilsProvider
override fun provideListAdapter(): HelpContentAdapter {
if (mAdapter == null) {
mAdapter =
HelpContentAdapter(requireContext(), this, mListViewModel, mQaId, mQaCollectionId, mNavigationTitle)
HelpContentAdapter(
requireContext(),
this,
mListViewModel,
mQaId,
mQaCollectionId,
mNavigationTitle,
mSearchType,
mLocation
)
mAdapter?.searchKey = searchKey ?: ""
}
return mAdapter!!
@ -70,6 +90,8 @@ class HelpContentFragment : ListFragment<HelpEntity, NormalListViewModel<HelpEnt
mCategoryId = arguments?.getString(EntranceConsts.KEY_CATEGORY_ID)
mIsMyRelatedQA = arguments?.getBoolean(EntranceConsts.KEY_MY_RELATED_QA) ?: false
mNavigationTitle = arguments?.getString(EntranceConsts.KEY_NAVIGATION_TITLE) ?: ""
mLocation = arguments?.getString(EntranceConsts.KEY_LOCATION) ?: ""
mSearchType = arguments?.getString(EntranceConsts.KEY_SEARCH_TYPE) ?: ""
super.onCreate(savedInstanceState)
mReuseNoneDataSearch = mCachedView.findViewById(R.id.reuse_none_data_search)
mReuseNoneDataButton = mCachedView.findViewById(R.id.reuseResetLoadTv)
@ -85,6 +107,11 @@ class HelpContentFragment : ListFragment<HelpEntity, NormalListViewModel<HelpEnt
mReuseNoneDataButton.setOnClickListener {
requireContext().startActivity(SuggestionActivity.getSuggestionCategoryIntent(requireContext()))
}
val parentViewModel = iSearchTabUtilsProvider?.obtainParentViewModel(this)
iSearchTabUtilsProvider?.getKeyAndTypeLiveData(parentViewModel)?.observe(this) { (key, _) ->
updateSearchKey(key)
}
}
override fun provideDataObservable(page: Int): Observable<List<HelpEntity>> {
@ -125,6 +152,17 @@ class HelpContentFragment : ListFragment<HelpEntity, NormalListViewModel<HelpEnt
RetrofitManager.getInstance().api.getSearchHelps(filterQuery, page)
} else {
RetrofitManager.getInstance().api.getQaContents(filterQuery, page)
}.doOnNext {
if (page == 1) {
SensorsBridge.trackQASearchResultReturn(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
mLocation,
searchKey ?: "",
mSearchType,
it.isNotEmpty()
)
}
}
}

View File

@ -88,6 +88,10 @@ class QaSearchActivity : BaseActivity() {
mDefaultFragment = alterFragment(transaction, HelpQaDefaultFragment::class.java, default)
} else {
mSearchFragment = alterFragment(transaction, HelpContentFragment::class.java, default)
val bundle = mSearchFragment?.arguments ?: Bundle()
bundle.putString(EntranceConsts.KEY_LOCATION, "帮助与反馈")
bundle.putString(EntranceConsts.KEY_SEARCH_TYPE, "自动搜索")
mSearchFragment?.arguments = bundle
}
transaction.commitAllowingStateLoss()
}
@ -117,7 +121,9 @@ class QaSearchActivity : BaseActivity() {
companion object {
fun getIntent(context: Context): Intent {
return Intent(context, QaSearchActivity::class.java)
val intent = Intent(context, QaSearchActivity::class.java)
return intent
}
}
}

View File

@ -138,6 +138,7 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.out.println("kayn -->onCreate:" + this.getClass().getSimpleName());
final Intent intent = getActivity().getIntent();
mEntrance = intent.getStringExtra(KEY_ENTRANCE);
if (getArguments() != null) {

View File

@ -220,6 +220,7 @@ public abstract class ListFragment<T, VM extends BaseListViewModel /* 该泛型
public void onLoadRefresh() {
showSkeleton(true);
System.out.println("kayn -->onLoadRefresh");
if (mReuseNoConn != null) mReuseNoConn.setVisibility(View.GONE);
if (mListLoading != null)
mListLoading.setVisibility(mListRefresh == null || !mListRefresh.isRefreshing() ? View.VISIBLE : View.GONE);

View File

@ -138,6 +138,8 @@ public class EntranceConsts {
public static final String KEY_OUTER_INFO = "outerInfo";
public static final String KEY_OLDERUSER = "isOldUser";
public static final String KEY_SEARCHKEY = "searchKey";
public static final String KEY_SEARCH_TYPE = "searchType";
public static final String KEY_HINT = "hint";
public static final String KEY_GAME = "game";
@ -345,4 +347,6 @@ public class EntranceConsts {
public static final String IS_DETAIL_PAGE = "is_detail_page";
public static final String KEY_IS_FROM_PUSH = "is_from_push";
public static final String KEY_IS_AUTO_LOAD = "key_is_auto_load";
}

View File

@ -90,6 +90,7 @@ object RouteConsts {
const val concernShareNews = "/services/concernShareNews"
const val libaoUtils = "/services/libaoUtils"
const val gameTrendsHelper = "/services/gameTrendsHelper"
const val searchTabUtils = "/services/SearchTabUtils"
const val downloadButtonClickedHandler = "/downloadbutton/clickedHandler"

View File

@ -112,6 +112,8 @@ object SensorsBridge {
private const val KEY_CONTENT_TITLE = "content_title"
private const val KEY_USER_ID_2 = "user_id"
private const val KEY_BBS_NAME = "bbs_name"
private const val KEY_CONTENT_ID = "content_id"
private const val KEY_CONTENT_NAME = "content_name"
private const val EVENT_GAME_DETAIL_PAGE_TAB_SELECT = "GameDetailPageTabSelect"
private const val EVENT_GAME_DETAIL_PAGE_TAG_CLICK = "GameDetailPageGameTagClick"
@ -167,10 +169,6 @@ object SensorsBridge {
private const val EVENT_UNLOAD_GAME_FINISH = "UnloadGameFinish"
private const val EVENT_INSTALL_GAME_CLICK = "InstallGameClick"
private const val EVENT_INSTALL_GAME_FINISH = "InstallGameFinish"
private const val EVENT_SEARCH_PAGE_SHOW = "SearchPageShow"
private const val EVENT_SEARCH_BUTTON_CLICK = "SearchButtonClick"
private const val EVENT_SEARCH_RESULT_RETURN = "SearchResultReturn"
private const val EVENT_SEARCH_RESULT_CLICK = "SearchResultClick"
private const val EVENT_ARTICLE_SEARCH_TAB_CLICK = "ArticleSearchTabClick"
private const val EVENT_MESSAGE_RECEIVE = "MessageReceive"
private const val EVENT_MESSAGE_CENTER_CLICK = "MessageCenterClick"
@ -247,6 +245,21 @@ object SensorsBridge {
private const val EVENT_JUMP_LAND_PAGE_ADDRESS_DIALOG_SHOW = "JumpLandPageAddressDialogShow"
private const val EVENT_JUMP_LAND_PAGE_ADDRESS_DIALOG_CLICK = "JumpLandPageAddressDialogClick"
private const val EVENT_GAME_SEARCH_PAGE_SHOW = "GameSearchPageShow"
private const val EVENT_GAME_SEARCH_PAGE_TAB_CLICK = "GameSearchPageTabClick"
private const val EVENT_GAME_SEARCH_PAGE_BUTTON_CLICK = "GameSearchPageButtonClick"
private const val EVENT_GAME_SEARCH_RESULT_RETURN = "GameSearchResultReturn"
private const val EVENT_GAME_SEARCH_RESULT_CLICK = "GameSearchResultClick"
private const val EVENT_ARTICLE_SEARCH_RESULT_RETURN = "ArticleSearchResultReturn"
private const val EVENT_ARTICLE_SEARCH_RESULT_CLICK = "ArticleSearchResultClick"
private const val EVENT_QA_SEARCH_RESULT_RETURN = "QASearchResultReturn"
private const val EVENT_QA_SEARCH_RESULT_CLICK = "QASearchResultClick"
private const val EVENT_MINI_GAME_SEARCH_RESULT_RETURN = "MiniGameSearchResultReturn"
private const val EVENT_MINI_GAME_SEARCH_RESULT_CLICK = "MiniGameSearchResultClick"
private const val EVENT_USER_SEARCH_RESULT_RETURN = "UserSearchResultReturn"
private const val EVENT_USER_SEARCH_RESULT_CLICK = "UserSearchResultClick"
private const val EVENT_FORUM_SEARCH_RESULT_RETURN = "ForumSearchResultReturn"
private const val EVENT_FORUM_SEARCH_RESULT_CLICK = "ForumSearchResultClick"
private var mIsSensorsEnabled = false
@ -319,129 +332,6 @@ object SensorsBridge {
mSensor?.profileSet(key, value)
}
/**
* 序号25
* 事件IDSearchPageShow
* 事件名称:搜索页面访问事件
* @param pageId 页面ID
* @param pageName 页面名称
* @param sourceEntrance 来源入口
* @param bottomTab 来源入口
* @param multiTabId 多tab导航页ID
* @param multiTabName 多tab导航页名称
* @param customPageId 自定义页面ID
* @param customPageName 自定义页面名称
* @param searchBoxPattern 搜索框样式
*/
@JvmStatic
fun trackSearchPageShow(
pageId: String,
pageName: String,
sourceEntrance: String,
bottomTab: String = "",
multiTabId: String = "",
multiTabName: String = "",
customPageId: String = "",
customPageName: String = "",
searchBoxPattern: String = ""
) {
val json = json {
KEY_PAGE_ID to pageId
KEY_PAGE_NAME to pageName
KEY_SOURCE_ENTRANCE to sourceEntrance
KEY_BOTTOM_TAB to bottomTab
KEY_MULTI_TAB_ID to multiTabId
KEY_MULTI_TAB_NAME to multiTabName
KEY_CUSTOM_PAGE_ID to customPageId
KEY_CUSTOM_PAGE_NAME to customPageName
KEY_SEARCH_BOX_PATTERN to searchBoxPattern
}
trackEvent(EVENT_SEARCH_PAGE_SHOW, json)
}
/**
* 序号:26
* 事件ID: SearchButtonClick
* 事件名称:搜索按钮点击事件
* @param pageId 页面ID
* @param pageName 页面名称
* @param searchContent 搜索内容
* @param searchType 搜索内型
* @param sourceEntrance 入口来源首页、游戏库、游戏详情、QQ小游戏、社区、论坛、webView
*/
fun trackSearchButtonClick(
pageId: String,
pageName: String,
searchContent: String,
searchType: String,
sourceEntrance: String
) {
val json = json {
KEY_PAGE_ID to pageId
KEY_PAGE_NAME to pageName
KEY_SEARCH_CONTENT to searchContent
KEY_SEARCH_TYPE to searchType
KEY_SOURCE_ENTRANCE to sourceEntrance
}
trackEvent(EVENT_SEARCH_BUTTON_CLICK, json)
}
/**
* 序号: 27
* 事件ID:SearchResultReturn
* 事件名称:搜索结果返回事件
* @param pageId 页面ID
* @param pageName 页面名称
* @param searchContent 搜索内容
* @param searchType 搜索类型
* @param searchResult 搜索结果 true or false
* @param sourceEntrance 入口来源首页、游戏库、游戏详情、QQ小游戏、社区、论坛、webView
*/
fun trackSearchResultReturn(
pageId: String,
pageName: String,
searchContent: String,
searchType: String,
searchResult: Boolean,
sourceEntrance: String
) {
val json = json {
KEY_PAGE_ID to pageId
KEY_PAGE_NAME to pageName
KEY_SEARCH_CONTENT to searchContent
KEY_SEARCH_TYPE to searchType
KEY_SEARCH_RESULT to searchResult
KEY_SOURCE_ENTRANCE to sourceEntrance
}
trackEvent(EVENT_SEARCH_RESULT_RETURN, json)
}
/**
* 事件ID:SearchResultClick
* 事件名称:搜索结果点击事件
* @param pageId 页面ID
* @param pageName 页面名称
* @param searchContent 搜索内容
* @param searchType 搜索类型
* @param sourceEntrance 入口来源首页、游戏库、游戏详情、QQ小游戏、社区、论坛、webView
*/
fun trackSearchResultClick(
pageId: String,
pageName: String,
searchContent: String,
searchType: String,
sourceEntrance: String
) {
val json = json {
KEY_PAGE_ID to pageId
KEY_PAGE_NAME to pageName
KEY_SEARCH_CONTENT to searchContent
KEY_SEARCH_TYPE to searchType
KEY_SOURCE_ENTRANCE to sourceEntrance
}
trackEvent(EVENT_SEARCH_RESULT_CLICK, json)
}
/**
* 事件IDArticleSearchTabClick
* 事件名称:内容搜索Tab选中事件
@ -3692,14 +3582,16 @@ object SensorsBridge {
* 事件ID: PureModeDialogClick
* 事件名称: 纯净模式弹窗点击事件
*/
fun trackPureModeDialogClick(gameId: String,
gameName: String,
gameType: String,
buttonName: String,
isIgnored: Boolean,
linkId: String,
linkType: String,
linkText: String) {
fun trackPureModeDialogClick(
gameId: String,
gameName: String,
gameType: String,
buttonName: String,
isIgnored: Boolean,
linkId: String,
linkType: String,
linkText: String
) {
val json = json {
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
@ -3730,14 +3622,16 @@ object SensorsBridge {
* 事件ID: AddedProtectionDialogClick
* 事件名称: 增强保护弹窗点击事件
*/
fun trackAddedProtectionDialogClick(gameId: String,
gameName: String,
gameType: String,
buttonName: String,
isIgnored: Boolean,
linkId: String,
linkType: String,
linkText: String) {
fun trackAddedProtectionDialogClick(
gameId: String,
gameName: String,
gameType: String,
buttonName: String,
isIgnored: Boolean,
linkId: String,
linkType: String,
linkText: String
) {
val json = json {
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
@ -3750,6 +3644,7 @@ object SensorsBridge {
}
trackEvent(EVENT_ADDED_PROTECTION_DIALOG_CLICK, json)
}
/**
* 事件IDfollow_tab_filter_option_click
* 事件名称关注tab筛选项点击事件
@ -3857,6 +3752,7 @@ object SensorsBridge {
}
trackEvent(EVENT_FOLLOW_PAGE_USER_AND_FORUM_DATA_CLICK, json)
}
/**
* 事件IDJumpLandPageAddressDialogShow
* 事件名称:下载跳转第三方提示弹窗展示事件
@ -3894,4 +3790,369 @@ object SensorsBridge {
trackEvent(EVENT_JUMP_LAND_PAGE_ADDRESS_DIALOG_CLICK, json)
}
/**
* 事件ID:GameSearchPageShow
* 事件名称:游戏搜索页面访问事件
* 触发时机:游戏搜索页面点击搜索框时触发
*/
fun trackGameSearchPageShow(pageId: String, pageName: String, sourceEntrance: String) {
val json = json {
KEY_PAGE_ID to pageId
KEY_PAGE_NAME to pageName
KEY_SOURCE_ENTRANCE to sourceEntrance
}
trackEvent(EVENT_GAME_SEARCH_PAGE_SHOW, json)
}
/**
* 事件ID:GameSearchPageTabClick
* 事件名称:游戏搜索页面tab选中事件
* 触发时机:游戏搜索页面的导航tab被选中时触发
*/
fun trackGameSearchPageTabClick(
pageId: String,
pageName: String,
sourceEntrance: String,
searchContent: String,
searchType: String,
tabContent: String,
position: Int
) {
val json = json {
KEY_PAGE_ID to pageId
KEY_PAGE_NAME to pageName
KEY_SOURCE_ENTRANCE to sourceEntrance
KEY_SEARCH_CONTENT to searchContent
KEY_SEARCH_TYPE to searchType
KEY_TAB_CONTENT to tabContent
KEY_POSITION to position
}
trackEvent(EVENT_GAME_SEARCH_PAGE_TAB_CLICK, json)
}
/**
* 事件ID:GameSearchPageButtonClick
* 事件名称:游戏搜索页面搜索按钮点击事件
* 触发时机:点击搜索按钮(搜索历史)时触发
*/
fun trackGameSearchPageButtonClick(
pageId: String,
pageName: String,
sourceEntrance: String,
searchContent: String,
searchType: String
) {
val json = json {
KEY_PAGE_ID to pageId
KEY_PAGE_NAME to pageName
KEY_SOURCE_ENTRANCE to sourceEntrance
KEY_SEARCH_CONTENT to searchContent
KEY_SEARCH_TYPE to searchType
}
trackEvent(EVENT_GAME_SEARCH_PAGE_BUTTON_CLICK, json)
}
/**
* 事件ID:GameSearchResultReturn
* 事件名称:游戏搜索结果返回事件
* 触发时机:返回游戏搜索结果时触发
*/
fun trackGameSearchResultReturn(
pageId: String,
pageName: String,
sourceEntrance: String,
searchContent: String,
searchType: String,
searchResult: Boolean
) {
val json = json {
KEY_PAGE_ID to pageId
KEY_PAGE_NAME to pageName
KEY_SOURCE_ENTRANCE to sourceEntrance
KEY_SEARCH_CONTENT to searchContent
KEY_SEARCH_TYPE to searchType
KEY_SEARCH_RESULT to searchResult
}
trackEvent(EVENT_GAME_SEARCH_RESULT_RETURN, json)
}
/**
* 事件ID:GameSearchResultClick
* 事件名称:游戏搜索结果点击事件
* 触发时机:点击游戏搜索结果时触发
*/
fun trackGameSearchResultClick(
pageId: String,
pageName: String,
sourceEntrance: String,
searchContent: String,
searchType: String,
gameId: String,
gameName: String,
gameType: String
) {
val json = json {
KEY_PAGE_ID to pageId
KEY_PAGE_NAME to pageName
KEY_SOURCE_ENTRANCE to sourceEntrance
KEY_SEARCH_CONTENT to searchContent
KEY_SEARCH_TYPE to searchType
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
KEY_GAME_TYPE to gameType
}
trackEvent(EVENT_GAME_SEARCH_RESULT_CLICK, json)
}
/**
* 事件ID:ArticleSearchResultReturn
* 事件名称:内容搜索结果返回事件
* 触发时机:返回内容搜索结果时触发
*/
fun trackArticleSearchResultReturn(
pageId: String,
pageName: String,
sourceEntrance: String,
searchContent: String,
searchType: String,
searchResult: Boolean
) {
val json = json {
KEY_PAGE_ID to pageId
KEY_PAGE_NAME to pageName
KEY_SOURCE_ENTRANCE to sourceEntrance
KEY_SEARCH_CONTENT to searchContent
KEY_SEARCH_TYPE to searchType
KEY_SEARCH_RESULT to searchResult
}
trackEvent(EVENT_ARTICLE_SEARCH_RESULT_RETURN, json)
}
/**
* 事件ID:ArticleSearchResultClick
* 事件名称:内容搜索结果点击事件
* 触发时机:点击内容搜索结果时触发
*/
fun trackArticleSearchResultClick(
pageId: String,
pageName: String,
sourceEntrance: String,
searchContent: String,
searchType: String,
contentId: String,
contentName: String
) {
val json = json {
KEY_PAGE_ID to pageId
KEY_PAGE_NAME to pageName
KEY_SOURCE_ENTRANCE to sourceEntrance
KEY_SEARCH_CONTENT to searchContent
KEY_SEARCH_TYPE to searchType
KEY_CONTENT_ID to contentId
KEY_CONTENT_NAME to contentName
}
trackEvent(EVENT_ARTICLE_SEARCH_RESULT_CLICK, json)
}
/**
* 事件ID:QASearchResultReturn
* 事件名称:Q&A搜索结果返回事件
* 触发时机:返回Q&A搜索结果时触发
*/
fun trackQASearchResultReturn(
pageId: String,
pageName: String,
sourceEntrance: String,
searchContent: String,
searchType: String,
searchResult: Boolean
) {
val json = json {
KEY_PAGE_ID to pageId
KEY_PAGE_NAME to pageName
KEY_SOURCE_ENTRANCE to sourceEntrance
KEY_SEARCH_CONTENT to searchContent
KEY_SEARCH_TYPE to searchType
KEY_SEARCH_RESULT to searchResult
}
trackEvent(EVENT_QA_SEARCH_RESULT_RETURN, json)
}
/**
* 事件ID:QASearchResultClick
* 事件名称:Q&A搜索结果点击事件
* 触发时机:点击Q&A搜索结果时触发
*/
fun trackQASearchResultClick(
pageId: String,
pageName: String,
sourceEntrance: String,
searchContent: String,
searchType: String,
contentId: String,
contentName: String
) {
val json = json {
KEY_PAGE_ID to pageId
KEY_PAGE_NAME to pageName
KEY_SOURCE_ENTRANCE to sourceEntrance
KEY_SEARCH_CONTENT to searchContent
KEY_SEARCH_TYPE to searchType
KEY_CONTENT_ID to contentId
KEY_CONTENT_NAME to contentName
}
trackEvent(EVENT_QA_SEARCH_RESULT_CLICK, json)
}
/**
* 事件ID:MiniGameSearchResultReturn
* 事件名称:小游戏搜索结果返回事件
* 触发时机:返回小游戏搜索结果时触发
*/
fun trackMiniGameSearchResultReturn(
pageId: String,
pageName: String,
sourceEntrance: String,
searchContent: String,
searchType: String,
searchResult: Boolean
) {
val json = json {
KEY_PAGE_ID to pageId
KEY_PAGE_NAME to pageName
KEY_SOURCE_ENTRANCE to sourceEntrance
KEY_SEARCH_CONTENT to searchContent
KEY_SEARCH_TYPE to searchType
KEY_SEARCH_RESULT to searchResult
}
trackEvent(EVENT_MINI_GAME_SEARCH_RESULT_RETURN, json)
}
/**
* 事件ID:MiniGameSearchResultClick
* 事件名称:小游戏搜索结果点击事件
* 触发时机:点击小游戏搜索结果时触发
*/
fun trackMiniGameSearchResultClick(
pageId: String,
pageName: String,
sourceEntrance: String,
searchContent: String,
searchType: String,
gameId: String,
gameName: String,
gameType: String
) {
val json = json {
KEY_PAGE_ID to pageId
KEY_PAGE_NAME to pageName
KEY_SOURCE_ENTRANCE to sourceEntrance
KEY_SEARCH_CONTENT to searchContent
KEY_SEARCH_TYPE to searchType
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
KEY_GAME_TYPE to gameType
}
trackEvent(EVENT_MINI_GAME_SEARCH_RESULT_CLICK, json)
}
/**
* 事件ID:UserSearchResultReturn
* 事件名称:用户搜索结果返回事件
* 触发时机:返回用户搜索结果时触发
*/
fun trackUserSearchResultReturn(
pageId: String,
pageName: String,
sourceEntrance: String,
searchContent: String,
searchType: String,
searchResult: Boolean
) {
val json = json {
KEY_PAGE_ID to pageId
KEY_PAGE_NAME to pageName
KEY_SOURCE_ENTRANCE to sourceEntrance
KEY_SEARCH_CONTENT to searchContent
KEY_SEARCH_TYPE to searchType
KEY_SEARCH_RESULT to searchResult
}
trackEvent(EVENT_USER_SEARCH_RESULT_RETURN, json)
}
/**
* 事件ID:UserSearchResultClick
* 事件名称:用户搜索结果点击事件
* 触发时机:点击用户搜索结果时触发
*/
fun trackUserSearchResultClick(
pageId: String,
pageName: String,
sourceEntrance: String,
searchContent: String,
searchType: String,
mongold_id: String,
) {
val json = json {
KEY_PAGE_ID to pageId
KEY_PAGE_NAME to pageName
KEY_SOURCE_ENTRANCE to sourceEntrance
KEY_SEARCH_CONTENT to searchContent
KEY_SEARCH_TYPE to searchType
KEY_MONGOLD_ID to mongold_id
}
trackEvent(EVENT_USER_SEARCH_RESULT_CLICK, json)
}
/**
* 事件ID:ForumSearchResultReturn
* 事件名称:论坛搜索结果返回事件
* 触发时机:返回论坛搜索结果时触发
*/
fun trackForumSearchResultReturn(
pageId: String,
pageName: String,
sourceEntrance: String,
searchContent: String,
searchType: String,
searchResult: Boolean
) {
val json = json {
KEY_PAGE_ID to pageId
KEY_PAGE_NAME to pageName
KEY_SOURCE_ENTRANCE to sourceEntrance
KEY_SEARCH_CONTENT to searchContent
KEY_SEARCH_TYPE to searchType
KEY_SEARCH_RESULT to searchResult
}
trackEvent(EVENT_FORUM_SEARCH_RESULT_RETURN, json)
}
/**
* 事件ID:ForumSearchResultClick
* 事件名称:论坛搜索结果点击事件
* 触发时机:点击论坛搜索结果时触发
*/
fun trackForumSearchResultClick(
pageId: String,
pageName: String,
sourceEntrance: String,
searchContent: String,
searchType: String,
bbsId: String,
forumName: String,
bbsType: String,
) {
val json = json {
KEY_PAGE_ID to pageId
KEY_PAGE_NAME to pageName
KEY_SOURCE_ENTRANCE to sourceEntrance
KEY_SEARCH_CONTENT to searchContent
KEY_SEARCH_TYPE to searchType
KEY_BBS_ID to bbsId
KEY_FORUM_NAME to forumName
KEY_BBS_TYPE to bbsType
}
trackEvent(EVENT_FORUM_SEARCH_RESULT_CLICK, json)
}
}

View File

@ -0,0 +1,13 @@
package com.gh.gamecenter.core.provider
import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import com.alibaba.android.arouter.facade.template.IProvider
interface ISearchTabUtilsProvider : IProvider {
fun obtainParentViewModel(fragment: Fragment): ViewModel
fun getKeyAndTypeLiveData(viewModel: ViewModel?): LiveData<Pair<String, String>>?
}

View File

@ -73,8 +73,14 @@ class SettingsEntity(
@SerializedName("hot_list")
var rankList: List<RankList>? = listOf(),
@SerializedName("wechat_game_search_list")
var wechatGameSearchList: List<RankList>? = listOf()// 微信小游戏-搜索榜单
var wechatGameSearchList: List<RankList>? = listOf(),// 微信小游戏-搜索榜单
@SerializedName("navigations")
private val _navigations: List<Navigation>? = null
) {
val navigations: List<Navigation>
get() = _navigations ?: emptyList()
class RankList(
var title: String = "",
var content: ArrayList<RankContent> = arrayListOf(),
@ -101,6 +107,19 @@ class SettingsEntity(
var exposureEvent: ExposureEvent? = null
}
}
data class Navigation(
@SerializedName("type")
private val _type: String? = null,
@SerializedName("title")
private val _title: String? = null
) {
val type: String
get() = _type ?: ""
val title: String
get() = _title ?: ""
}
}
class Suggestion(
@ -237,10 +256,11 @@ class SettingsEntity(
var text: String = "",
var display: Display? = Display()
) {
val typeChinese: String get() = when(type) {
"revolving" -> "走马灯"
else -> "图片"
}
val typeChinese: String
get() = when (type) {
"revolving" -> "走马灯"
else -> "图片"
}
}
class PermissionPopupAppliedVersions(