diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7b0f6315dd..03ba04b5b5 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -747,11 +747,11 @@ android:screenOrientation="portrait" /> directToQGameHome(context) + ColumnCollectionDetailFragment.TYPE_QQ_MINI_GAME_COLUMN -> directToQGameHome(context) // QQ游戏专题详情页 - "qq_mini_game_column_detail" -> { + ViewPagerFragmentHelper.TYPE_QQ_MINI_GAME_COLUMN, ViewPagerFragmentHelper.TYPE_WECHAT_GAME_COLUMN -> { + val subjectType = if (linkEntity.type == ViewPagerFragmentHelper.TYPE_QQ_MINI_GAME_COLUMN) { + SubjectData.SubjectType.QQ_GAME + } else { + SubjectData.SubjectType.WECHAT_GAME + } directToSubject( context = context, id = linkEntity.link ?: "", subjectName = linkEntity.text, entrance = BaseActivity.mergeEntranceAndPath(entrance, path), exposureEvent = exposureEvent, - isQQMiniGame = true + subjectType = subjectType ) } @@ -536,6 +551,10 @@ object DirectUtils { } } + "wechat_game" -> linkEntity.link?.let { + MiniGameItemHelper.launchMiniGame(it, Constants.WECHAT_MINI_GAME) + } + "" -> { // do nothing } @@ -774,7 +793,12 @@ object DirectUtils { } } if (traceEvent != null) { - val clickEvent = createEvent(GameEntity(id = id, name = name), traceEvent.source, appendTrace(traceEvent), ExposureType.CLICK) + val clickEvent = createEvent( + GameEntity(id = id, name = name), + traceEvent.source, + appendTrace(traceEvent), + ExposureType.CLICK + ) log(clickEvent) bundle.putParcelable(KEY_TRACE_EVENT, clickEvent) } @@ -837,12 +861,12 @@ object DirectUtils { subjectName: String? = "", entrance: String? = null, exposureEvent: ExposureEvent? = null, - isQQMiniGame: Boolean = false, + subjectType: SubjectData.SubjectType = SubjectData.SubjectType.NORMAL ) { if (id.isEmpty()) return val bundle = Bundle() val subjectData = - SubjectData(subjectId = id, subjectName = subjectName, isOrder = false, isQQMiniGame = isQQMiniGame) + SubjectData(subjectId = id, subjectName = subjectName, isOrder = false, subjectType = subjectType) bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER) bundle.putString(KEY_TO, SubjectActivity::class.java.name) bundle.putParcelable(EntranceConsts.KEY_SUBJECT_DATA, subjectData) @@ -991,7 +1015,13 @@ object DirectUtils { } @JvmStatic - fun directToQuestionDetail(context: Context, id: String, entrance: String? = null, path: String? = null, sourceEntrance: String = "") { + fun directToQuestionDetail( + context: Context, + id: String, + entrance: String? = null, + path: String? = null, + sourceEntrance: String = "" + ) { if (id.isEmpty()) return val bundle = Bundle() bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER) @@ -1935,7 +1965,7 @@ object DirectUtils { } @JvmStatic - fun directToQGameSearch( + fun directToMiniGameSearch( context: Context, hint: String, sourceEntrance: String, @@ -1947,7 +1977,7 @@ object DirectUtils { searchBoxPattern: String = "" ) { context.startActivity( - QGameSearchActivity.getIntent( + MiniGameSearchActivity.getIntent( context, hint, sourceEntrance, @@ -1963,11 +1993,10 @@ object DirectUtils { @SuppressLint("CheckResult") @JvmStatic - fun directToQGameById( + fun directToQQGameById( activity: Activity, - qqGameId: String + qqAppId: String ) { - if (activity !is AppCompatActivity || activity.supportFragmentManager.isDestroyed) { ToastUtils.toast("启动QQ小游戏失败,请稍后再试") return @@ -1990,23 +2019,37 @@ object DirectUtils { .build(RouteConsts.provider.qGame) .navigation() as IQGameProvider qGameProvider.setLoginInfo(activity, userId, userName, userToken) - qGameProvider.launchGame(activity, qqGameId) { _, _ -> - RetrofitManager - .getInstance() - .newApi - .postQGamePlay(qqGameId, userId) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe( - { - QGameViewModel.notifyQGameSubjectUpdate() // 通知QQ小游戏首页列表刷新 - }, - {} - ) // 秒玩记录上报 + qGameProvider.launchGame(activity, qqAppId) { _, _ -> + MiniGameRecentlyPlayUseCase.submitRecentPlayedQGame(qqAppId, userId) } } } + @SuppressLint("CheckResult") + fun directToWechatGameById( + activity: Activity, + wechatAppId: String, + ) { + + val wxApiProxy = WXAPIFactory.createWXAPI( + activity, + Config.WECHAT_APPID + ) + if (!wxApiProxy.isWXAppInstalled) { + ToastUtils.toast("请安装微信客户端") + return + } + + wxApiProxy.sendReq( + WXLaunchMiniProgram.Req().apply { + userName = wechatAppId + miniprogramType = WXLaunchMiniProgram.Req.MINIPTOGRAM_TYPE_RELEASE; + } + ) + + MiniGameRecentlyPlayUseCase.submitRecentPlayedWGame(wechatAppId, HaloApp.getInstance().gid) + } + @JvmStatic fun directToMessageCenter(defaultTabIndex: Int) { ARouter.getInstance().build(RouteConsts.activity.messageWrapperActivity) @@ -2082,7 +2125,7 @@ object DirectUtils { ) ) - BottomTab.SearchStyle.TYPE_QQ_MINI_GAME -> directToQGameSearch( + BottomTab.SearchStyle.TYPE_MINI_GAME -> directToMiniGameSearch( context, "请输入小游戏关键词", sourceEntrance, diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index dd2babb65f..f3881083ed 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -27,7 +27,6 @@ import com.gh.download.server.BrowserInstallHelper import com.gh.gamecenter.R import com.gh.gamecenter.WebActivity import com.gh.gamecenter.adapter.viewholder.GameViewHolder -import com.gh.gamecenter.common.base.GlobalActivityManager import com.gh.gamecenter.common.callback.CancelListener import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.constant.EntranceConsts @@ -41,6 +40,7 @@ import com.gh.gamecenter.feature.exposure.ExposureEvent import com.gh.gamecenter.feature.view.DownloadButton import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment import com.gh.gamecenter.manager.PackagesManager +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper import com.gh.gamecenter.teenagermode.TeenagerModeActivity import com.gh.vspace.VHelper import com.lightgame.download.DownloadConfig @@ -247,9 +247,8 @@ object DownloadItemUtils { } return } - if (gameEntity.isQQMiniGame()) { - val isQQMiniGameOffShelve = gameEntity.qqMiniGameAppStatus == 1 // QQ小游戏是否下架 - if (isQQMiniGameOffShelve) { + if (gameEntity.isMiniGame()) { + if (gameEntity.isMiniGameOffShelve()) { downloadBtn.apply { isClickable = false text = context.getString(R.string.off_shelve) @@ -844,12 +843,11 @@ object DownloadItemUtils { } return } - if (gameEntity.isQQMiniGame()) { + if (gameEntity.isMiniGame()) { downloadBtn.setOnClickListener { - NewFlatLogUtils.logQGameClick(gameEntity.qqMiniGameAppId, gameEntity.name) - GlobalActivityManager.currentActivity?.let { activity -> - DirectUtils.directToQGameById(activity, gameEntity.qqMiniGameAppId) - } + MiniGameItemHelper.launchMiniGame(gameEntity.miniGameAppId, gameEntity.miniGameType) + clickCallback?.onCallback() + allStateClickCallback?.onCallback() } return } diff --git a/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt b/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt index b34a72a32d..cdc02949fc 100644 --- a/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt +++ b/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt @@ -2600,17 +2600,6 @@ object NewFlatLogUtils { log(json) } - @JvmStatic - fun logQGameClick(qqGameId: String, qqGameName: String?) { - val json = json { - KEY_EVENT to "qq_game_click" - "qq_game_id" to qqGameId - "qq_game_name" to qqGameName ?: "" - parseAndPutMeta().invoke(this) - } - log(json) - } - // 点击个人主页的认证文案事件 @JvmStatic fun logClickAuthText(linkType: String, linkId: String, linkText: String, userId: String, text: String) { diff --git a/app/src/main/java/com/gh/common/util/ViewPagerFragmentHelper.kt b/app/src/main/java/com/gh/common/util/ViewPagerFragmentHelper.kt index 73306675d7..3e88348355 100644 --- a/app/src/main/java/com/gh/common/util/ViewPagerFragmentHelper.kt +++ b/app/src/main/java/com/gh/common/util/ViewPagerFragmentHelper.kt @@ -62,7 +62,8 @@ object ViewPagerFragmentHelper { const val TYPE_GAME_LIST = "game_list" // 游戏单广场 const val TYPE_FEEDBACK = "feedback" // 帮助与反馈 const val TYPE_COLUMN = "column" // 游戏专题详情页 - const val TYPE_QQ_MINI_GAME_COLUMN = "qq_mini_game_column_detail" // QQ游戏专题详情页 + const val TYPE_QQ_MINI_GAME_COLUMN = "qq_mini_game_column_detail" // QQ小游戏专题详情页 + const val TYPE_WECHAT_GAME_COLUMN = "wechat_game_column_detail" // 微信小游戏专题详情页 const val TYPE_COLUMN_COLLECTION = "column_collection" // 专题合集详情页 const val TYPE_SERVER = "server" // 开服表 const val TYPE_COLUMN_TEST = "column_test_v2" // 新游开测 @@ -151,11 +152,16 @@ object ViewPagerFragmentHelper { className = GameCollectionSquareFragment::class.java.name } // 游戏专题详情页/QQ游戏专题详情页 - TYPE_COLUMN, TYPE_QQ_MINI_GAME_COLUMN -> { + TYPE_COLUMN, TYPE_QQ_MINI_GAME_COLUMN, TYPE_WECHAT_GAME_COLUMN -> { + val subjectType = when(entity.type) { + TYPE_QQ_MINI_GAME_COLUMN -> SubjectData.SubjectType.QQ_GAME + TYPE_WECHAT_GAME_COLUMN -> SubjectData.SubjectType.WECHAT_GAME + else -> SubjectData.SubjectType.NORMAL + } className = SubjectFragment::class.java.name bundle.putParcelable( EntranceConsts.KEY_SUBJECT_DATA, - SubjectData(entity.link, entity.text, false, isQQMiniGame = entity.type == "qq_mini_game_column_detail") + SubjectData(entity.link, entity.text, false, subjectType = subjectType) ) bundle.putBoolean(EntranceConsts.KEY_SHOW_DOWNLOAD_MENU, !isTabWrapper) } diff --git a/app/src/main/java/com/gh/gamecenter/SearchActivity.kt b/app/src/main/java/com/gh/gamecenter/SearchActivity.kt index 819971619a..eeb2b8daf6 100644 --- a/app/src/main/java/com/gh/gamecenter/SearchActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/SearchActivity.kt @@ -17,6 +17,7 @@ import com.gh.gamecenter.common.base.GlobalActivityManager import com.gh.gamecenter.common.base.activity.BaseActivity import com.gh.gamecenter.common.constant.EntranceConsts 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.SearchDefaultFragment @@ -39,7 +40,7 @@ open class SearchActivity : BaseActivity() { lateinit var backBtn: RelativeLayout private lateinit var deleteIv: ImageView - private var mDao: SearchHistoryDao? = null + protected val mDao: ISearchHistoryDao by lazy { provideDao() } protected var mSearchKey: String? = null protected var mIsAutoSearchDisabled: Boolean = false @@ -78,7 +79,6 @@ open class SearchActivity : BaseActivity() { val searchImmediately = intent.getBooleanExtra(KEY_SEARCH_IMMEDIATELY, false) var ignoreTextChanges = savedInstanceState != null - mDao = SearchHistoryDao(this) mPublishSubject = PublishSubject.create() mPublishSubject!! @@ -102,7 +102,7 @@ open class SearchActivity : BaseActivity() { searchEt.hint = hint if (searchImmediately) { mDisplayType = GAME_DETAIL - mDao?.add(hint) + mDao.add(hint) search(SearchType.DEFAULT, hint) } } else { @@ -190,12 +190,12 @@ open class SearchActivity : BaseActivity() { mIsAutoSearchDisabled = false } - private fun handleAutoSearch(key: String?) { + protected open fun handleAutoSearch(key: String?) { val newSearchKey = searchEt.text.toString().trim { it <= ' ' } if (newSearchKey.isEmpty()) { val hint = searchEt.hint.toString() if (!TextUtils.isEmpty(hint) && HINT_TEXT != hint) { - mDao?.add(hint) + mDao.add(hint) search(SearchType.DEFAULT, hint) } } else { @@ -213,7 +213,7 @@ open class SearchActivity : BaseActivity() { } } - private fun handleDefaultSearch(key: String?) { + protected open fun handleDefaultSearch(key: String?) { mSearchKey = key searchEt.setText(key) searchEt.setSelection(searchEt.text.length) @@ -230,14 +230,14 @@ open class SearchActivity : BaseActivity() { // MtaHelper.onEvent("游戏搜索", "默认搜索", key) } - private fun handleHotSearch(key: String?) { + protected open fun handleHotSearch(key: String?) { mSearchKey = key searchEt.setText(key) searchEt.setSelection(searchEt.text.length) updateDisplayType(GAME_DETAIL) } - private fun handleHistorySearch(key: String?) { + protected open fun handleHistorySearch(key: String?) { mSearchKey = key searchEt.setText(key) searchEt.setSelection(searchEt.text.length) @@ -254,12 +254,12 @@ open class SearchActivity : BaseActivity() { // MtaHelper.onEvent("游戏搜索", "历史搜索", key) } - private fun handleManualSearch() { + protected open fun handleManualSearch() { val newSearchKey = searchEt.text.toString().trim { it <= ' ' } if (newSearchKey.isEmpty()) { val hint = searchEt.hint.toString() if (!TextUtils.isEmpty(hint) && HINT_TEXT != hint) { - mDao?.add(hint) + mDao.add(hint) search(SearchType.DEFAULT, hint) } } else if (newSearchKey != mSearchKey || mDisplayType != GAME_DETAIL) { @@ -273,7 +273,7 @@ open class SearchActivity : BaseActivity() { mSourceEntrance ) - mDao?.add(mSearchKey) + mDao.add(mSearchKey) updateDisplayType(GAME_DETAIL) } else { toast("请输入搜索内容") @@ -283,6 +283,8 @@ open class SearchActivity : BaseActivity() { // MtaHelper.onEvent("游戏搜索", "主动搜索", newSearchKey) } + protected open fun provideDao(): ISearchHistoryDao = SearchHistoryDao(this) + open fun updateDisplayType(type: DisplayType) { val transaction = supportFragmentManager.beginTransaction() when (type) { diff --git a/app/src/main/java/com/gh/gamecenter/SkipActivity.java b/app/src/main/java/com/gh/gamecenter/SkipActivity.java index 5c25b69ed8..7d26e629f6 100644 --- a/app/src/main/java/com/gh/gamecenter/SkipActivity.java +++ b/app/src/main/java/com/gh/gamecenter/SkipActivity.java @@ -55,15 +55,18 @@ import com.gh.common.util.CheckLoginUtils; import com.gh.common.util.DirectUtils; import com.gh.common.util.EntranceUtils; import com.gh.gamecenter.common.base.activity.BaseActivity; +import com.gh.gamecenter.common.constant.Constants; import com.gh.gamecenter.common.constant.EntranceConsts; import com.gh.gamecenter.common.entity.CommunityEntity; import com.gh.gamecenter.common.entity.LinkEntity; import com.gh.gamecenter.common.entity.SimpleGameEntity; import com.gh.gamecenter.core.utils.GsonUtils; import com.gh.gamecenter.core.utils.ToastUtils; +import com.gh.gamecenter.entity.SubjectData; import com.gh.gamecenter.entity.SubjectRecommendEntity; import com.gh.gamecenter.entity.VideoLinkEntity; import com.gh.gamecenter.feature.utils.PlatformUtils; +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper; import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel; import com.gh.gamecenter.video.videomanager.VideoManagerActivity; import com.gh.vspace.shortcut.OnCreateShortcutResult; @@ -152,7 +155,7 @@ public class SkipActivity extends BaseActivity { DirectUtils.directToGameDetail(this, path, "", entrance, "true".equals(uri.getQueryParameter("auto_download")), to, null); break; case HOST_COLUMN: - DirectUtils.directToSubject(this, path, uri.getQueryParameter(KEY_NAME), entrance, null, false); + DirectUtils.directToSubject(this, path, uri.getQueryParameter(KEY_NAME), entrance, null, SubjectData.SubjectType.NORMAL); break; case HOST_SUGGESTION: if (!TextUtils.isEmpty(qaId)) { @@ -401,7 +404,7 @@ public class SkipActivity extends BaseActivity { try { JSONObject extJsonObject = new JSONObject(extJson); String qqGameId = extJsonObject.optString("aid"); - DirectUtils.directToQGameById(this, qqGameId); + MiniGameItemHelper.INSTANCE.launchMiniGame(qqGameId, Constants.QQ_MINI_GAME); } catch (JSONException ignored) { } break; diff --git a/app/src/main/java/com/gh/gamecenter/amway/search/AmwaySearchActivity.kt b/app/src/main/java/com/gh/gamecenter/amway/search/AmwaySearchActivity.kt index 751b228183..612a0ff8b2 100644 --- a/app/src/main/java/com/gh/gamecenter/amway/search/AmwaySearchActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/amway/search/AmwaySearchActivity.kt @@ -9,12 +9,12 @@ import com.gh.gamecenter.DisplayType import com.gh.gamecenter.R import com.gh.gamecenter.SearchActivity import com.gh.gamecenter.SearchType +import com.gh.gamecenter.db.ISearchHistoryDao import com.gh.gamecenter.search.SearchDefaultFragment class AmwaySearchActivity : SearchActivity() { private lateinit var mViewModel: AmwaySearchViewModel - private val mSearchHistoryDao by lazy { AmwaySearchDao() } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -22,38 +22,43 @@ class AmwaySearchActivity : SearchActivity() { mViewModel = viewModelProvider() } + override fun provideDao(): ISearchHistoryDao = AmwaySearchDao() + + override fun handleAutoSearch(key: String?) { + mSearchKey = key + updateDisplayType(DisplayType.GAME_DIGEST) + mViewModel.getSearchResult(mSearchKey!!) + } + + override fun handleHistorySearch(key: String?) { + mSearchKey = key + searchEt.setText(key) + searchEt.setSelection(searchEt.text.length) + mViewModel.getSearchResult(mSearchKey!!) + updateDisplayType(DisplayType.GAME_DETAIL) + } + + private fun handleOtherSearch() { + val newSearchKey = searchEt.text.toString().trim { it <= ' ' } + if (newSearchKey != mSearchKey || mDisplayType != DisplayType.GAME_DETAIL) { + mSearchKey = newSearchKey + if (!TextUtils.isEmpty(mSearchKey)) { + mViewModel.getSearchResult(mSearchKey!!) + mDao.add(mSearchKey!!) + updateDisplayType(DisplayType.GAME_DETAIL) + } else { + toast("请先输入游戏名再搜索~") + } + } + } + override fun search(type: SearchType, key: String?) { mSearchType = type mIsAutoSearchDisabled = true - when (type) { - SearchType.AUTO -> { - mSearchKey = key - updateDisplayType(DisplayType.GAME_DIGEST) - mViewModel.getSearchResult(mSearchKey!!) - } - - SearchType.HISTORY -> { - mSearchKey = key - searchEt.setText(key) - searchEt.setSelection(searchEt.text.length) - mViewModel.getSearchResult(mSearchKey!!) - updateDisplayType(DisplayType.GAME_DETAIL) - } - - else -> { - val newSearchKey = searchEt.text.toString().trim { it <= ' ' } - if (newSearchKey != mSearchKey || mDisplayType != DisplayType.GAME_DETAIL) { - mSearchKey = newSearchKey - if (!TextUtils.isEmpty(mSearchKey)) { - mViewModel.getSearchResult(mSearchKey!!) - mSearchHistoryDao.add(mSearchKey!!) - updateDisplayType(DisplayType.GAME_DETAIL) - } else { - toast("请先输入游戏名再搜索~") - } - } - } + SearchType.AUTO -> handleAutoSearch(key) + SearchType.HISTORY -> handleHistorySearch(key) + else -> handleOtherSearch() } mIsAutoSearchDisabled = false } diff --git a/app/src/main/java/com/gh/gamecenter/amway/search/AmwaySearchDao.kt b/app/src/main/java/com/gh/gamecenter/amway/search/AmwaySearchDao.kt index 5a58a81281..04e39e3d08 100644 --- a/app/src/main/java/com/gh/gamecenter/amway/search/AmwaySearchDao.kt +++ b/app/src/main/java/com/gh/gamecenter/amway/search/AmwaySearchDao.kt @@ -1,9 +1,11 @@ package com.gh.gamecenter.amway.search import com.gh.gamecenter.core.utils.SPUtils +import com.gh.gamecenter.db.ISearchHistoryDao -class AmwaySearchDao { - fun add(keyword: String) { +class AmwaySearchDao : ISearchHistoryDao { + + override fun add(keyword: String) { val originString = SPUtils.getString(SP_KEY) if (originString.isEmpty()) { @@ -28,16 +30,18 @@ class AmwaySearchDao { } } - fun getAll(): ArrayList? { + override fun getAll(): ArrayList? { val list = SPUtils.getString(SP_KEY).split(SEARCH_KEY_DIVIDER) return if (list.size == 1 && list[0].isEmpty()) null else ArrayList(list) } - fun deleteAll() { + override fun deleteAll() { SPUtils.setString(SP_KEY, "") } + override fun delete(item: String) {} + companion object { const val SP_KEY = "amway_key" const val SEARCH_KEY_DIVIDER = "<-||->" diff --git a/app/src/main/java/com/gh/gamecenter/amway/search/AmwaySearchDefaultFragment.kt b/app/src/main/java/com/gh/gamecenter/amway/search/AmwaySearchDefaultFragment.kt index bc8e577b17..11ba8ff21f 100644 --- a/app/src/main/java/com/gh/gamecenter/amway/search/AmwaySearchDefaultFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/amway/search/AmwaySearchDefaultFragment.kt @@ -7,6 +7,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import com.gh.gamecenter.R import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.databinding.FragmentAmwaySearchDefaultBinding +import com.gh.gamecenter.db.ISearchHistoryDao import com.gh.gamecenter.eventbus.EBSearch import com.gh.gamecenter.search.SearchDefaultFragment import com.lightgame.utils.Util_System_Keyboard @@ -14,7 +15,6 @@ import org.greenrobot.eventbus.EventBus class AmwaySearchDefaultFragment : SearchDefaultFragment() { - private lateinit var mSearchDao: AmwaySearchDao private lateinit var mViewModel: AmwaySearchViewModel private val mAmwayBinding by lazy { FragmentAmwaySearchDefaultBinding.inflate(layoutInflater) } @@ -22,11 +22,15 @@ class AmwaySearchDefaultFragment : SearchDefaultFragment() { override fun getLayoutId() = 0 override fun getInflatedLayout() = mAmwayBinding.root + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + mViewModel = viewModelProviderFromParent() + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - mViewModel = viewModelProviderFromParent() - mViewModel.playedGames.observeNonNull(this) { + mViewModel.playedGames.observeNonNull(viewLifecycleOwner) { defaultViewModel?.isExistHotSearch = it.isNotEmpty() updateView() mBinding.hotList.run { @@ -38,28 +42,21 @@ class AmwaySearchDefaultFragment : SearchDefaultFragment() { } } - override fun initDao() { - mSearchDao = AmwaySearchDao() - mHistoryList = mSearchDao.getAll() - } - + override fun provideDao(): ISearchHistoryDao = AmwaySearchDao() override fun initView() { mBinding = mAmwayBinding.searchContent - defaultViewModel?.isExistHistory = mHistoryList?.isNotEmpty() == true - updateView() mBinding.hotHeadContainer.headTitle.text = "最近玩过" mBinding.historyFlexContainer.setLimitHeight(mFlexMaxHeight) - createFlexContent(mBinding.historyFlex, mHistoryList, clickListener = { - val key = mHistoryList!![it] - mSearchDao.add(key) - EventBus.getDefault().post(EBSearch("history", key)) - Util_System_Keyboard.hideSoftKeyboardByIBinder(context, mBinding.historyFlex.windowToken) - }) - initHistoryHeadView() + updateHistorySearchView(null) + defaultViewModel?.historySearchLiveData?.observe(this) { + updateHistorySearchView(it) + } + + initHeadView() } - private fun initHistoryHeadView() { + override fun initHeadView() { mBinding.historyHeadContainer.run { headTitle.text = getString(R.string.search_history) headTitle.textSize = 16F @@ -73,17 +70,15 @@ class AmwaySearchDefaultFragment : SearchDefaultFragment() { ) headActionTv.setOnClickListener { DialogHelper.showCenterWarningDialog(requireContext(), "清空记录", "确定清空历史搜索记录?", confirmClickCallback = { - mSearchDao.deleteAll() - defaultViewModel?.isExistHistory = false - updateView() - updateNoPlayedGameHint() + defaultViewModel?.deleteAll() }) } } } private fun updateNoPlayedGameHint() { - if (mSearchDao.getAll() != null && mSearchDao.getAll()?.size != 0) { + val historyList = defaultViewModel?.historySearchLiveData?.value + if (!historyList.isNullOrEmpty()) { mAmwayBinding.noDataContainer.visibility = View.GONE return } @@ -95,4 +90,21 @@ class AmwaySearchDefaultFragment : SearchDefaultFragment() { } } + override fun updateHistorySearchView(historyList: List?) { + defaultViewModel?.isExistHistory = historyList?.isNotEmpty() == true + updateView() + updateNoPlayedGameHint() + historyList?.let { + createFlexContent(mBinding.historyFlex, historyList, clickListener = { id -> + val key = it[id] + defaultViewModel?.add(key) + EventBus.getDefault().post(EBSearch("history", key)) + Util_System_Keyboard.hideSoftKeyboardByIBinder( + context, + mBinding.historyFlex.windowToken + ) + }) + } + } + } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/db/ISearchHistoryDao.java b/app/src/main/java/com/gh/gamecenter/db/ISearchHistoryDao.java new file mode 100644 index 0000000000..0040921d7f --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/db/ISearchHistoryDao.java @@ -0,0 +1,14 @@ +package com.gh.gamecenter.db; + +import java.util.List; + +public interface ISearchHistoryDao { + + void deleteAll(); + + void add(String item); + + void delete(String item); + + List getAll(); +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/db/SearchHistoryDao.java b/app/src/main/java/com/gh/gamecenter/db/SearchHistoryDao.java index d862e6a412..9b6a327ff1 100644 --- a/app/src/main/java/com/gh/gamecenter/db/SearchHistoryDao.java +++ b/app/src/main/java/com/gh/gamecenter/db/SearchHistoryDao.java @@ -11,7 +11,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; -public class SearchHistoryDao { +public class SearchHistoryDao implements ISearchHistoryDao { private DatabaseHelper helper; private Dao dao; @@ -25,6 +25,7 @@ public class SearchHistoryDao { } } + @Override public void add(String item) { AppExecutor.getIoExecutor().execute(() -> { try { @@ -35,6 +36,7 @@ public class SearchHistoryDao { }); } + @Override public void delete(String item) { AppExecutor.getIoExecutor().execute(() -> { try { @@ -45,6 +47,7 @@ public class SearchHistoryDao { }); } + @Override public void deleteAll() { AppExecutor.getIoExecutor().execute(() -> { CloseableIterator iterator = dao.iterator(); @@ -59,6 +62,7 @@ public class SearchHistoryDao { return; } + @Override public List getAll() { List history = new ArrayList(); diff --git a/app/src/main/java/com/gh/gamecenter/download/AdGameBannerAdapter.kt b/app/src/main/java/com/gh/gamecenter/download/AdGameBannerAdapter.kt index 7d8518cfeb..486cf2d6c2 100644 --- a/app/src/main/java/com/gh/gamecenter/download/AdGameBannerAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/download/AdGameBannerAdapter.kt @@ -6,12 +6,10 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.PagerSnapHelper import androidx.recyclerview.widget.RecyclerView import com.gh.common.exposure.ExposureManager -import com.gh.common.util.DirectUtils import com.gh.common.util.DownloadItemUtils import com.gh.common.util.NewFlatLogUtils import com.gh.gamecenter.GameDetailActivity import com.gh.gamecenter.adapter.viewholder.GameViewHolder -import com.gh.gamecenter.common.base.GlobalActivityManager import com.gh.gamecenter.common.base.activity.BaseActivity import com.gh.gamecenter.common.exposure.ExposureSource import com.gh.gamecenter.common.utils.safelyGetInRelease @@ -21,6 +19,7 @@ import com.gh.gamecenter.entity.AdConfig import com.gh.gamecenter.feature.entity.GameEntity import com.gh.gamecenter.feature.exposure.ExposureEvent import com.gh.gamecenter.feature.game.GameItemViewHolder +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper import com.lightgame.adapter.BaseRecyclerAdapter import com.lightgame.download.DownloadEntity @@ -93,11 +92,8 @@ class AdGameBannerAdapter( it.id, it.name ?: "" ) - if (it.isQQMiniGame()) { - GlobalActivityManager.currentActivity?.let { activity -> - NewFlatLogUtils.logQGameClick(it.qqMiniGameAppId, it.name) - DirectUtils.directToQGameById(activity, it.qqMiniGameAppId) - } + if (it.isMiniGame()) { + MiniGameItemHelper.launchMiniGame(it.miniGameAppId, it.miniGameType) } else { GameDetailActivity.startGameDetailActivity( mContext, diff --git a/app/src/main/java/com/gh/gamecenter/entity/BottomTab.kt b/app/src/main/java/com/gh/gamecenter/entity/BottomTab.kt index ed32f2f834..57ece54861 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/BottomTab.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/BottomTab.kt @@ -26,19 +26,19 @@ data class BottomTab( @SerializedName("is_default_page") var default: Boolean = false, // 是否为默认显示页 var isTransparentStyle: Boolean = false // 本地字段,透明底部Tab -): Parcelable { +) : Parcelable { @Parcelize data class SearchStyle( @SerializedName("style_type") var styleType: String = STYLE_TWO_LINES, // 样式类型(two_lines:搜索栏与顶部tab分为两行、apposition:搜索栏与顶部tab同一行) @SerializedName("search_type") - var searchType: String = TYPE_HALO_GAME, // 搜索类型(halo_game:光环游戏、qq_mini_game:QQ小游戏、bbs:论坛) - ): Parcelable { + var searchType: String = TYPE_HALO_GAME, // 搜索类型(halo_game:光环游戏、bbs:论坛、mini_game:小游戏搜索(低于v5.36版本返回qq_mini_game)) + ) : Parcelable { companion object { const val STYLE_TWO_LINES = "two_lines" const val STYLE_APPOSITION = "apposition" const val TYPE_HALO_GAME = "halo_game" - const val TYPE_QQ_MINI_GAME = "qq_mini_game" + const val TYPE_MINI_GAME = "mini_game" const val TYPE_BBS = "bbs" } } diff --git a/app/src/main/java/com/gh/gamecenter/entity/NewApiSettingsEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/NewApiSettingsEntity.kt index 879d7fde1c..b238ccd47a 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/NewApiSettingsEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/NewApiSettingsEntity.kt @@ -1,6 +1,7 @@ package com.gh.gamecenter.entity import com.gh.gamecenter.common.entity.LinkEntity +import com.gh.gamecenter.feature.entity.SettingsEntity import com.gh.gamecenter.feature.entity.SimulatorEntity import com.google.gson.annotations.SerializedName @@ -20,6 +21,7 @@ class NewApiSettingsEntity( var install: Install, // 安装相关的 @SerializedName("game_shield_contents") var gameShieldContents: List? = listOf(),//游戏屏蔽内容 + var search: SettingsEntity.Search? = null// 游戏搜索配置 ) { /** * diff --git a/app/src/main/java/com/gh/gamecenter/entity/SubjectData.kt b/app/src/main/java/com/gh/gamecenter/entity/SubjectData.kt index b748e232bc..142e2a3b03 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/SubjectData.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/SubjectData.kt @@ -17,7 +17,7 @@ class SubjectData( var filter: String = "", // Filter: 类型(分类) var tagType: String? = "", // 游戏Item 标签类型 var briefStyle: String = "", - var isQQMiniGame: Boolean = false, + var subjectType: SubjectType = SubjectType.NORMAL, var subjectStyle: String = "", var requireUpdateSetting: Boolean = false, // 多专题页面需要专题页面自行获取专题配置 @@ -43,4 +43,24 @@ class SubjectData( tag = tagType ) } + + /** + * 专题类型 + */ + enum class SubjectType { + /** + * 普通专题 + */ + NORMAL, + + /** + * QQ小游戏专题 + */ + QQ_GAME, + + /** + * 微信小游戏专题 + */ + WECHAT_GAME + } } diff --git a/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt index eb585b5dfa..79689edb3f 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt @@ -102,6 +102,9 @@ data class SubjectEntity( @SerializedName("is_qq_column") var isQQColumn: Boolean = false, + @SerializedName("is_wechat_column") + var isWechatColumn: Boolean = false, + var explain: String = "", // 游戏单合集说明 @SerializedName("show_star") @@ -115,6 +118,14 @@ data class SubjectEntity( mData = value } + val subjectType: SubjectData.SubjectType get() = when { + isQQColumn -> SubjectData.SubjectType.QQ_GAME + isWechatColumn -> SubjectData.SubjectType.WECHAT_GAME + else -> SubjectData.SubjectType.NORMAL + } + + val isMiniGame: Boolean get() = isQQColumn || isWechatColumn + val showStar: Boolean get() = _showStar ?: false diff --git a/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchActivity.kt b/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchActivity.kt index 9bee918a6a..2247a6e085 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchActivity.kt @@ -16,6 +16,7 @@ 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 import com.gh.gamecenter.forum.detail.ForumDetailFragment import com.gh.gamecenter.search.SearchDefaultFragment import com.lightgame.utils.Util_System_Keyboard @@ -28,7 +29,6 @@ class ForumOrUserSearchActivity : SearchActivity() { private var mBbsId = "" private var mLocation = "" private var mSourceEntrance = "" - private val mSearchHistoryDao by lazy { ForumSearchDao() } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -63,66 +63,66 @@ class ForumOrUserSearchActivity : SearchActivity() { } } + override fun provideDao(): ISearchHistoryDao = ForumSearchDao() + + 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?) { + mSearchKey = key + 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) { + val newSearchKey = searchEt.text.toString().trim { it <= ' ' } + if (newSearchKey != mSearchKey || mDisplayType != DisplayType.GAME_DETAIL) { + mSearchKey = newSearchKey + if (!TextUtils.isEmpty(mSearchKey)) { + mDao.add(mSearchKey!!) + updateDisplayType(DisplayType.FORUM_OR_USER) + val searchType = if (type == SearchType.MANUAL) { + TRACK_SEARCH_TYPE_INPUT + } else { + TRACK_SEARCH_TYPE_DEFAULT + } + SensorsBridge.trackSearchButtonClick( + GlobalActivityManager.getCurrentPageEntity().pageId, + GlobalActivityManager.getCurrentPageEntity().pageName, + newSearchKey, + searchType, + mSourceEntrance + ) + } else { + toast("请先输入搜索内容再搜索~") + } + } + } + override fun search(type: SearchType, key: String?) { mSearchType = type mIsAutoSearchDisabled = true - when (type) { - SearchType.AUTO -> { - mSearchKey = key - updateDisplayType(DisplayType.FORUM_OR_USER) - SensorsBridge.trackSearchButtonClick( - GlobalActivityManager.getCurrentPageEntity().pageId, - GlobalActivityManager.getCurrentPageEntity().pageName, - key ?: "", - TRACK_SEARCH_TYPE_INPUT, - mSourceEntrance - ) - } - - SearchType.HISTORY -> { - mSearchKey = key - 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 - ) - } - - else -> { - val newSearchKey = searchEt.text.toString().trim { it <= ' ' } - if (newSearchKey != mSearchKey || mDisplayType != DisplayType.GAME_DETAIL) { - mSearchKey = newSearchKey - if (!TextUtils.isEmpty(mSearchKey)) { - mSearchHistoryDao.add(mSearchKey!!) - updateDisplayType(DisplayType.FORUM_OR_USER) - if (type == SearchType.MANUAL) { - SensorsBridge.trackSearchButtonClick( - GlobalActivityManager.getCurrentPageEntity().pageId, - GlobalActivityManager.getCurrentPageEntity().pageName, - newSearchKey, - TRACK_SEARCH_TYPE_INPUT, - mSourceEntrance - ) - } else { - SensorsBridge.trackSearchButtonClick( - GlobalActivityManager.getCurrentPageEntity().pageId, - GlobalActivityManager.getCurrentPageEntity().pageName, - newSearchKey, - TRACK_SEARCH_TYPE_DEFAULT, - mSourceEntrance - ) - } - } else { - toast("请先输入搜索内容再搜索~") - } - } - } + SearchType.AUTO -> handleAutoSearch(key) + SearchType.HISTORY -> handleHistorySearch(key) + else -> handleOtherSearch(type) } mIsAutoSearchDisabled = false diff --git a/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchDefaultFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchDefaultFragment.kt index d6669e3650..57401ab2b2 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchDefaultFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchDefaultFragment.kt @@ -7,6 +7,7 @@ import androidx.constraintlayout.widget.ConstraintLayout import com.gh.gamecenter.R import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.databinding.FragmentSearchDefaultBinding +import com.gh.gamecenter.db.ISearchHistoryDao import com.gh.gamecenter.eventbus.EBSearch import com.gh.gamecenter.search.SearchDefaultFragment import com.lightgame.utils.Util_System_Keyboard @@ -14,7 +15,6 @@ import org.greenrobot.eventbus.EventBus class ForumOrUserSearchDefaultFragment : SearchDefaultFragment() { - private lateinit var mSearchDao: ForumSearchDao private lateinit var mViewModel: ForumOrUserSearchDefaultViewModel override fun onCreate(savedInstanceState: Bundle?) { @@ -38,10 +38,7 @@ class ForumOrUserSearchDefaultFragment : SearchDefaultFragment() { updateView() } - override fun initDao() { - mSearchDao = ForumSearchDao() - mHistoryList = mSearchDao.getAll() - } + override fun provideDao(): ISearchHistoryDao = ForumSearchDao() override fun initView() { mBinding = FragmentSearchDefaultBinding.bind(mCachedView) @@ -57,18 +54,12 @@ class ForumOrUserSearchDefaultFragment : SearchDefaultFragment() { val params = mBinding.historyHeadContainer.root.layoutParams as ConstraintLayout.LayoutParams params.topMargin = 0.5f.dip2px() mBinding.historyHeadContainer.root.layoutParams = params - defaultViewModel?.isExistHistory = mHistoryList?.isNotEmpty() == true - updateView() mBinding.historyFlexContainer.setLimitHeight(mFlexMaxHeight) - createFlexContent(mBinding.historyFlex, mHistoryList, clickListener = { - val key = mHistoryList!![it] - mSearchDao.add(key) - EventBus.getDefault().post(EBSearch("history", key)) - Util_System_Keyboard.hideSoftKeyboardByIBinder( - context, - mBinding.historyFlex.windowToken - ) - }) + + updateHistorySearchView(null) + defaultViewModel?.historySearchLiveData?.observe(this) { + updateHistorySearchView(it) + } mBinding.historyHeadContainer.run { headTitle.text = getString(R.string.search_history) @@ -83,11 +74,27 @@ class ForumOrUserSearchDefaultFragment : SearchDefaultFragment() { ) headActionTv.setOnClickListener { DialogHelper.showCenterWarningDialog(requireContext(), "清空记录", "确定清空历史搜索记录?", confirmClickCallback = { - mSearchDao.deleteAll() + defaultViewModel?.deleteAll() defaultViewModel?.isExistHistory = false updateView() }) } } } + + override fun updateHistorySearchView(historyList: List?) { + defaultViewModel?.isExistHistory = historyList?.isNotEmpty() == true + updateView() + historyList?.let { + createFlexContent(mBinding.historyFlex, historyList, clickListener = { id -> + val key = it[id] + defaultViewModel?.add(key) + EventBus.getDefault().post(EBSearch("history", key)) + Util_System_Keyboard.hideSoftKeyboardByIBinder( + context, + mBinding.historyFlex.windowToken + ) + }) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/forum/search/ForumSearchDao.kt b/app/src/main/java/com/gh/gamecenter/forum/search/ForumSearchDao.kt index d92979a233..79fc4608de 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/search/ForumSearchDao.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/search/ForumSearchDao.kt @@ -1,9 +1,10 @@ package com.gh.gamecenter.forum.search import com.gh.gamecenter.core.utils.SPUtils +import com.gh.gamecenter.db.ISearchHistoryDao -class ForumSearchDao { - fun add(keyword: String) { +class ForumSearchDao : ISearchHistoryDao { + override fun add(keyword: String) { val originString = SPUtils.getString(SP_KEY) if (originString.isEmpty()) { @@ -28,13 +29,15 @@ class ForumSearchDao { } } - fun getAll(): ArrayList? { + override fun delete(item: String) {} + + override fun getAll(): ArrayList? { val list = SPUtils.getString(SP_KEY).split(SEARCH_KEY_DIVIDER) return if (list.size == 1 && list[0].isEmpty()) null else ArrayList(list) } - fun deleteAll() { + override fun deleteAll() { SPUtils.setString(SP_KEY, "") } diff --git a/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt index 1f4868bce3..d2822795f6 100644 --- a/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt @@ -22,9 +22,11 @@ import com.gh.gamecenter.GameDetailActivity import com.gh.gamecenter.MainActivity import com.gh.gamecenter.R import com.gh.gamecenter.adapter.ImagePagerAdapter -import com.gh.gamecenter.adapter.viewholder.* +import com.gh.gamecenter.adapter.viewholder.GameHeadViewHolder +import com.gh.gamecenter.adapter.viewholder.GameImageViewHolder +import com.gh.gamecenter.adapter.viewholder.GameViewHolder +import com.gh.gamecenter.adapter.viewholder.GameViewPagerViewHolder import com.gh.gamecenter.category.CategoryDirectoryActivity -import com.gh.gamecenter.common.base.GlobalActivityManager import com.gh.gamecenter.common.baselist.LoadStatus import com.gh.gamecenter.common.callback.OnViewClickListener import com.gh.gamecenter.common.constant.EntranceConsts @@ -71,7 +73,10 @@ import com.gh.gamecenter.game.rank.RankCollectionViewHolder import com.gh.gamecenter.game.vertical.GameVerticalAdapter import com.gh.gamecenter.game.vertical.GameVerticalSlideViewHolder import com.gh.gamecenter.game.vertical.OnPagerSnapScrollListener -import com.gh.gamecenter.home.* +import com.gh.gamecenter.home.BlankDividerViewHolder +import com.gh.gamecenter.home.HomeDividerViewHolder +import com.gh.gamecenter.home.HomeGameItemViewHolder +import com.gh.gamecenter.home.LegacyHomeFragmentAdapterAssistant import com.gh.gamecenter.home.discovercard.DiscoverCardGameAdapter import com.gh.gamecenter.home.discovercard.HomeDiscoverCardViewHolder import com.gh.gamecenter.home.gamecollection.carousel.HomeGameCollectionCarouselViewHolder @@ -85,7 +90,8 @@ import com.gh.gamecenter.home.test_v2.HomeGameTestV2GameListRvAdapter import com.gh.gamecenter.home.test_v2.HomeGameTestV2ViewModel import com.gh.gamecenter.home.test_v2.HomeItemGameTestV2ViewHolder import com.gh.gamecenter.home.video.ScrollCalculatorHelper -import com.gh.gamecenter.qgame.QGameHorizontalSlideListViewHolder +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper +import com.gh.gamecenter.minigame.qq.QGameRecentlyPlayViewHolder import com.gh.gamecenter.servers.gametest2.GameServerTestV2Activity import com.gh.gamecenter.subject.SubjectActivity import com.gh.vspace.HomeRecentVGameAdapter @@ -189,7 +195,7 @@ class GameFragmentAdapter( ItemViewType.GAME_SUBJECT -> GameHorizontalListViewHolder(parent.toBinding()) // 游戏专题-横屏滑动 ItemViewType.GAME_SUBJECT_SLIDE -> GameHorizontalSlideListViewHolder(parent.toBinding()) - ItemViewType.QQ_GAME_SUBJECT_SLIDE -> QGameHorizontalSlideListViewHolder(parent.toBinding()) + ItemViewType.QQ_GAME_SUBJECT_SLIDE -> QGameRecentlyPlayViewHolder(parent.toBinding()) // 正常游戏 ItemViewType.GAME_NORMAL -> GameItemViewHolder(parent.toBinding()) // 游戏专题-大图-显示/只显示 @@ -257,7 +263,7 @@ class GameFragmentAdapter( is FooterViewHolder -> bindFooterView(holder) is GameImageViewHolder -> bindGameImageView(holder, position) is GameHorizontalListViewHolder -> bindGameHorizontalListView(holder, position) - is QGameHorizontalSlideListViewHolder -> bindQGameHorizontalSlideListView(holder, position) + is QGameRecentlyPlayViewHolder -> bindQGameHorizontalSlideListView(holder, position) is GameHorizontalSlideListViewHolder -> bindGameHorizontalSlideListView(holder, position) is GameImageSlideViewHolder -> bindGameImageSlide(holder, position) is GameVerticalSlideViewHolder -> bindVerticalSlide(holder, position) @@ -306,7 +312,7 @@ class GameFragmentAdapter( holder.cell.binding?.root?.setOnClickListener { setPageSwitchData() DirectUtils.directToSubject( - it.context, gallery.id ?: "", gallery.name, "(游戏-专题)", null, gallery.isQQColumn + it.context, gallery.id ?: "", gallery.name, "(游戏-专题)", null, gallery.subjectType ) NewLogUtils.logColumnPictureClick( "显示图集", gallery.name ?: "", gallery.id ?: "", gallery.id ?: "", "column", @@ -591,11 +597,8 @@ class GameFragmentAdapter( val clickClosure: (Int, GameEntity) -> Unit = { _, gameEntity -> val subjectData = gameEntity.subjectData DataCollectionUtils.uploadClick(mContext, subjectData?.name + "-列表", "游戏-专题", gameEntity.name) - if (gameEntity.isQQMiniGame()) { - NewFlatLogUtils.logQGameClick(gameEntity.qqMiniGameAppId, gameEntity.name) - GlobalActivityManager.currentActivity?.let { - DirectUtils.directToQGameById(it, gameEntity.qqMiniGameAppId) - } + if (gameEntity.isMiniGame()) { + MiniGameItemHelper.launchMiniGame(gameEntity.miniGameAppId, gameEntity.miniGameType) } else { GameDetailActivity.startGameDetailActivity( mContext, gameEntity, @@ -783,9 +786,9 @@ class GameFragmentAdapter( } } - private fun bindQGameHorizontalSlideListView(holder: QGameHorizontalSlideListViewHolder, position: Int) { + private fun bindQGameHorizontalSlideListView(holder: QGameRecentlyPlayViewHolder, position: Int) { val subject = mItemDataList[position].qqHorizontalSlide - holder.bindHorizontalSlideList(subject!!) + holder.bindView(subject!!) holder.binding.moreTv.setOnClickListener { val buttonType = when (subject.home) { @@ -837,7 +840,7 @@ class GameFragmentAdapter( subject.isOrder, mBasicExposureSource, "(游戏-专题:" + subject.name + "-全部)", - subject.isQQColumn + subject.subjectType ) } MtaHelper.onEvent("游戏专题", "全部", subject.name) @@ -1313,11 +1316,8 @@ class GameFragmentAdapter( DataCollectionUtils.uploadClick(mContext, subjectData.name + "-列表", "游戏-专题", gameEntity.name) - if (gameEntity.isQQMiniGame()) { - GlobalActivityManager.currentActivity?.let { - NewFlatLogUtils.logQGameClick(gameEntity.qqMiniGameAppId, gameEntity.name) - DirectUtils.directToQGameById(it, gameEntity.qqMiniGameAppId) - } + if (gameEntity.isMiniGame()) { + MiniGameItemHelper.launchMiniGame(gameEntity.miniGameAppId, gameEntity.miniGameType) } else if (gameEntity.isPluggable) { GameDetailActivity.startGameDetailActivity( mContext, @@ -1546,26 +1546,15 @@ class GameFragmentAdapter( } DirectUtils.directToLinkPage(mContext, link, "(游戏-专题:" + column.name + "-全部)", "") } else { - if (column.isQQColumn) { - SubjectActivity.startSubjectActivity( - mContext, - column.id, - column.getFilterName(), - column.isOrder, - mBasicExposureSource, - "(游戏-专题:" + column.name + "-全部)", - column.isQQColumn - ) - } else { - SubjectActivity.startSubjectActivity( - mContext, - column.id, - column.getFilterName(), - column.isOrder, - mBasicExposureSource, - "(游戏-专题:" + column.name + "-全部)" - ) - } + SubjectActivity.startSubjectActivity( + mContext, + column.id, + column.getFilterName(), + column.isOrder, + mBasicExposureSource, + "(游戏-专题:" + column.name + "-全部)", + column.subjectType + ) } MtaHelper.onEvent("游戏专题", "全部", column.name) } diff --git a/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailFragment.kt index 32c5463720..33596c91b8 100644 --- a/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailFragment.kt @@ -70,6 +70,11 @@ class ColumnCollectionDetailFragment : LazyListFragment() for (link in linkEntityList) { + val subjectType = when(link.type) { + TYPE_QQ_MINI_GAME_COLUMN -> SubjectData.SubjectType.QQ_GAME + TYPE_WECHAT_MINI_GAME_COLUMN -> SubjectData.SubjectType.WECHAT_GAME + else -> SubjectData.SubjectType.NORMAL + } subjectDataList.add( SubjectData( subjectId = link.link, @@ -78,7 +83,7 @@ class ColumnCollectionDetailFragment : LazyListFragment { + size + } + GameHorizontalListType.MiniGameSubjectHorizontalType -> { + mSubjectEntity.data!!.size + } + else -> when { size < 4 -> size size < 8 -> 4 else -> 8 @@ -125,7 +127,7 @@ class GameHorizontalAdapter( clickGameName = gameEntity.name ?: "", clickGameId = gameEntity.id ) - if (!gameEntity.isQQMiniGame() && trackColumnClick) { + if (!gameEntity.isMiniGame() && trackColumnClick) { SensorsBridge.trackColumnClick( location = "游戏详情", gameName = gameName, @@ -138,11 +140,8 @@ class GameHorizontalAdapter( } } - if (gameEntity.isQQMiniGame()) { - NewFlatLogUtils.logQGameClick(gameEntity.qqMiniGameAppId, gameEntity.name) - GlobalActivityManager.currentActivity?.let { - DirectUtils.directToQGameById(it, gameEntity.qqMiniGameAppId) - } + if (gameEntity.isMiniGame()) { + MiniGameItemHelper.launchMiniGame(gameEntity.miniGameAppId, gameEntity.miniGameType) } else { GameDetailActivity.startGameDetailActivity( mContext, @@ -224,5 +223,5 @@ sealed class GameHorizontalListType { object GameDetailHorizontalType : GameHorizontalListType() object SubjectHorizontalType : GameHorizontalListType() - object QGameSubjectHorizontalType : GameHorizontalListType() + object MiniGameSubjectHorizontalType : GameHorizontalListType() } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalListViewHolder.kt b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalListViewHolder.kt index c5409ab3f4..14bba27071 100644 --- a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalListViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalListViewHolder.kt @@ -23,8 +23,8 @@ class GameHorizontalListViewHolder(val binding: GameHorizontalListBinding) : subjectAdapter = GameHorizontalAdapter( context, subjectEntity, - if (subjectEntity.isQQColumn) { - GameHorizontalListType.QGameSubjectHorizontalType + if (subjectEntity.isMiniGame) { + GameHorizontalListType.MiniGameSubjectHorizontalType } else { GameHorizontalListType.SubjectHorizontalType diff --git a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideAdapter.kt index f7c0043c4c..40870e652d 100644 --- a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideAdapter.kt @@ -2,18 +2,16 @@ package com.gh.gamecenter.game.horizontal import android.content.Context import android.view.ViewGroup -import com.gh.common.util.DirectUtils import com.gh.gamecenter.feature.exposure.ExposureEvent import com.gh.common.util.DownloadItemUtils -import com.gh.common.util.NewFlatLogUtils import com.gh.gamecenter.GameDetailActivity import com.gh.gamecenter.R import com.gh.gamecenter.adapter.viewholder.GameViewHolder -import com.gh.gamecenter.common.base.GlobalActivityManager import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.* import com.gh.gamecenter.databinding.GameHorizontalItemBinding import com.gh.gamecenter.entity.SubjectEntity +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper import com.lightgame.adapter.BaseRecyclerAdapter import com.lightgame.download.DownloadEntity @@ -70,11 +68,8 @@ class GameHorizontalSlideAdapter( } holder.bindGameHorizontalItem(gameEntity, mSubjectEntity) holder.itemView.setOnClickListener { - if (gameEntity.isQQMiniGame()) { - NewFlatLogUtils.logQGameClick(gameEntity.qqMiniGameAppId, gameEntity.name) - GlobalActivityManager.currentActivity?.let { - DirectUtils.directToQGameById(it, gameEntity.qqMiniGameAppId) - } + if (gameEntity.isMiniGame()) { + MiniGameItemHelper.launchMiniGame(gameEntity.miniGameAppId, gameEntity.miniGameType) } else { val exposureEvent = exposureEventList?.safelyGetInRelease(position) if (exposureEvent != null) { diff --git a/app/src/main/java/com/gh/gamecenter/game/vertical/GameItemUi.kt b/app/src/main/java/com/gh/gamecenter/game/vertical/GameItemUi.kt index aa4eeee98c..32d9622bb0 100644 --- a/app/src/main/java/com/gh/gamecenter/game/vertical/GameItemUi.kt +++ b/app/src/main/java/com/gh/gamecenter/game/vertical/GameItemUi.kt @@ -3,6 +3,7 @@ package com.gh.gamecenter.game.vertical import android.content.Context import android.graphics.Color import android.graphics.Typeface +import android.os.Build import android.text.TextUtils import android.util.AttributeSet import android.view.Gravity @@ -59,6 +60,7 @@ class GameItemUi(override val ctx: Context) : Ui { var recommendTv: TextView var gameTagContainer: GameTagContainerView var recommendConstraintLayout: ConstraintLayout + var gamePlayCountTv: TextView var mGameDesSpace: Space @@ -78,6 +80,7 @@ class GameItemUi(override val ctx: Context) : Ui { gameRatingTv = initGameRatingTv() recommendIv = SimpleDraweeView(ctx).apply { id = R.id.recommendIv } recommendTv = initRecommendTv() + gamePlayCountTv = initGamePlayCountTv() gameTagContainer = GameTagContainerView(ctx).apply { id = R.id.label_list } mGameDesSpace = space { }.apply { id = R.id.gameDesSpace } recommendConstraintLayout = initRecommendConstraintLayout() @@ -120,8 +123,7 @@ class GameItemUi(override val ctx: Context) : Ui { startToEndOf(gameRatingTv) endToEndOf(mGameDesSpace) topToTopOf(mGameDesSpace) - - topMargin = dip(5) + bottomToBottomOf(mGameDesSpace) }) add(recommendConstraintLayout, lParams(wrapContent, dip(18)) { startToStartOf(mGameDesSpace) @@ -135,10 +137,17 @@ class GameItemUi(override val ctx: Context) : Ui { add(gameTagContainer, lParams(0, wrapContent) { topToBottomOf(mGameDesSpace) bottomToBottomOf(iconIv) - startToStartOf(mGameDesSpace) + startToEndOf(gamePlayCountTv) endToEndOf(mGameDesSpace) orientation = LinearLayout.HORIZONTAL }) + add(gamePlayCountTv, lParams(wrapContent, wrapContent) { + topToBottomOf(mGameDesSpace) + bottomToBottomOf(iconIv) + startToStartOf(mGameDesSpace) + endToStartOf(gameTagContainer) + endMargin = dip(8) + }) add(gameNameContainer, lParams(0, wrapContent) { startToStartOf(mGameDesSpace) topToTopOf(iconIv) @@ -226,6 +235,15 @@ class GameItemUi(override val ctx: Context) : Ui { setTextColor(ContextCompat.getColor(context, R.color.text_tertiary)) } + private fun initGamePlayCountTv() = textView { + id = R.id.game_play_count + textSize = 11F + includeFontPadding = false + gravity = Gravity.CENTER + setTextColor(ContextCompat.getColor(context, R.color.text_tertiary)) + visibility = View.GONE + } + private fun initDownloadTv() = DownloadButton(ctx).apply { id = R.id.download_btn text = "下载" diff --git a/app/src/main/java/com/gh/gamecenter/game/vertical/GameVerticalAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/vertical/GameVerticalAdapter.kt index 17c1bcf864..53715664c3 100644 --- a/app/src/main/java/com/gh/gamecenter/game/vertical/GameVerticalAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/game/vertical/GameVerticalAdapter.kt @@ -14,6 +14,7 @@ import com.gh.gamecenter.entity.SubjectEntity import com.gh.gamecenter.feature.entity.GameEntity import com.gh.gamecenter.feature.entity.GameSubjectData import com.gh.gamecenter.feature.game.GameItemViewHolder +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper import com.lightgame.adapter.BaseRecyclerAdapter import com.lightgame.download.DownloadEntity @@ -178,6 +179,8 @@ class GameVerticalAdapter( adLabelTv ) + MiniGameItemHelper.setMiniGameUsage(gamePlayCountTv, gameEntity) + var gameRatingPaddingEnd = 0 var gameRatingDrawableStart: Drawable? = null var gameRatingTextColor = R.color.primary_theme.toColor(context) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt index 968d7cea46..edc026171d 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt @@ -7,12 +7,10 @@ import androidx.constraintlayout.widget.ConstraintSet import androidx.recyclerview.widget.RecyclerView import com.gh.common.util.DirectUtils import com.gh.common.util.DownloadItemUtils -import com.gh.common.util.NewFlatLogUtils import com.gh.gamecenter.GameDetailActivity import com.gh.gamecenter.R import com.gh.gamecenter.adapter.viewholder.GameViewHolder import com.gh.gamecenter.common.base.BaseRecyclerViewHolder -import com.gh.gamecenter.common.base.GlobalActivityManager import com.gh.gamecenter.common.exposure.ExposureSource import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.RandomUtils @@ -20,6 +18,7 @@ import com.gh.gamecenter.databinding.HomeGameItemBinding import com.gh.gamecenter.entity.SubjectEntity import com.gh.gamecenter.feature.exposure.ExposureEvent import com.gh.gamecenter.feature.game.GameItemViewHolder +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder import com.shuyu.gsyvideoplayer.video.base.GSYVideoView @@ -97,11 +96,8 @@ class HomeGameItemViewHolder(val binding: HomeGameItemBinding) : BaseRecyclerVie } } holder.itemView.setOnClickListener { - if (game.isQQMiniGame()) { - NewFlatLogUtils.logQGameClick(game.qqMiniGameAppId, game.name) - GlobalActivityManager.currentActivity?.let { - DirectUtils.directToQGameById(it, game.qqMiniGameAppId) - } + if (game.isMiniGame()) { + MiniGameItemHelper.launchMiniGame(game.miniGameAppId, game.miniGameType) } else { GameDetailActivity.startGameDetailActivity( binding.root.context, @@ -156,6 +152,7 @@ class HomeGameItemViewHolder(val binding: HomeGameItemBinding) : BaseRecyclerVie subjectEntity.adIconActive, binding.adLabelTv ) + MiniGameItemHelper.setMiniGameUsage(binding.gamePlayCount, game) val hierarchy = binding.gameImage.hierarchy try { hierarchy.setPlaceholderImage(ColorDrawable(game.homeSetting.placeholderColor.hexStringToIntColor())) diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageFragment.kt b/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageFragment.kt index d4b08f0ba0..1de036dc47 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageFragment.kt @@ -19,13 +19,11 @@ import com.gh.common.prioritychain.PullDownPushHandler import com.gh.common.util.DefaultSearchHintHelper import com.gh.common.util.DialogUtils import com.gh.common.util.DirectUtils -import com.gh.common.util.NewFlatLogUtils import com.gh.common.xapk.XapkInstaller import com.gh.common.xapk.XapkUnzipStatus import com.gh.download.DownloadManager import com.gh.gamecenter.GameDetailActivity import com.gh.gamecenter.R -import com.gh.gamecenter.common.base.GlobalActivityManager import com.gh.gamecenter.common.base.fragment.LazyFragment import com.gh.gamecenter.common.baselist.LoadStatus import com.gh.gamecenter.common.constant.Constants @@ -57,6 +55,7 @@ import com.gh.gamecenter.home.custom.adapter.CustomPageAdapter import com.gh.gamecenter.home.custom.floatview.CustomFloatViewAnimationHelper import com.gh.gamecenter.home.video.ScrollCalculatorHelper import com.gh.gamecenter.livedata.EventObserver +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper import com.gh.gamecenter.wrapper.MainWrapperViewModel import com.gh.gamecenter.wrapper.SearchToolbarTabWrapperFragment import com.gh.gamecenter.wrapper.SearchToolbarTabWrapperViewModel @@ -264,11 +263,8 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable { } gameDetailDestination.observe(viewLifecycleOwner, EventObserver { (trackData, entrance, game) -> - if (game.isQQMiniGame()) { - GlobalActivityManager.currentActivity?.let { - NewFlatLogUtils.logQGameClick(game.qqMiniGameAppId, game.name) - DirectUtils.directToQGameById(it, game.qqMiniGameAppId) - } + if (game.isMiniGame()) { + MiniGameItemHelper.launchMiniGame(game.miniGameAppId, game.miniGameType) } else { GameDetailActivity.startGameDetailActivity( requireContext(), @@ -284,13 +280,13 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable { subjectDestination.observe(viewLifecycleOwner, EventObserver { subject -> DirectUtils.directToSubject( - requireContext(), subject.id ?: "", subject.name, "自定义页面", null, subject.isQQColumn + requireContext(), subject.id ?: "", subject.name, "自定义页面", null, subject.subjectType ) }) - subjectDestinationWithCustom.observe(viewLifecycleOwner, EventObserver { (subject, isQqMini) -> + subjectDestinationWithCustom.observe(viewLifecycleOwner, EventObserver { (subject, subjectType) -> DirectUtils.directToSubject( - requireContext(), subject.id, subject.title, "自定义页面", null, isQqMini + requireContext(), subject.id, subject.title, "自定义页面", null, subjectType ) }) @@ -458,7 +454,7 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable { private fun setSearchHint(searchType: String) { when (searchType) { BottomTab.SearchStyle.TYPE_HALO_GAME -> DefaultSearchHintHelper.setSearchHint(binding.reuseSearchBar.searchTv) - BottomTab.SearchStyle.TYPE_QQ_MINI_GAME -> binding.reuseSearchBar.searchTv.hint = "请输入小游戏关键词" + BottomTab.SearchStyle.TYPE_MINI_GAME -> binding.reuseSearchBar.searchTv.hint = "请输入小游戏关键词" BottomTab.SearchStyle.TYPE_BBS -> binding.reuseSearchBar.searchTv.hint = "搜索论坛内容、用户" } } diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageViewModel.kt index 05a67ab1dc..18819f1596 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/CustomPageViewModel.kt @@ -4,6 +4,7 @@ import android.app.Application import androidx.collection.ArrayMap import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData +import androidx.lifecycle.MediatorLiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Observer import com.gh.common.util.GameUtils @@ -17,10 +18,7 @@ import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.common.utils.observableToMain import com.gh.gamecenter.core.utils.RandomUtils import com.gh.gamecenter.core.utils.SPUtils -import com.gh.gamecenter.entity.HomeSubSlide -import com.gh.gamecenter.entity.PullDownPush -import com.gh.gamecenter.entity.RatingComment -import com.gh.gamecenter.entity.SubjectEntity +import com.gh.gamecenter.entity.* import com.gh.gamecenter.feature.entity.CustomPageTrackData import com.gh.gamecenter.feature.entity.GameEntity import com.gh.gamecenter.feature.entity.PageLocation @@ -33,6 +31,7 @@ import com.gh.gamecenter.home.custom.model.* import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMPONENTS_COLLECTION_STYLE_REFRESH_ICONS_4_2 import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMPONENTS_COLLECTION_STYLE_REFRESH_SLIDE_LIST import com.gh.gamecenter.livedata.Event +import com.gh.gamecenter.minigame.MiniGameRecentlyPlayUseCase import com.gh.gamecenter.wrapper.SearchToolbarTabWrapperViewModel import com.lightgame.utils.Utils import io.reactivex.android.schedulers.AndroidSchedulers @@ -69,7 +68,13 @@ class CustomPageViewModel( private val _customPageData = MutableLiveData() val customPageData: LiveData = _customPageData - private val _dataList = MutableLiveData>() + private val _dataList = MediatorLiveData>().apply { + addSource(repository.recentMiniGamesItemLiveData, ::notifyItemChanged) + addSource(repository.customDiscoverItemLiveData, ::notifyItemChanged) + addSource(repository.recentGamesItemLiveData, ::notifyItemChanged) + addSource(repository.customPluginItemLiveData, ::notifyItemChanged) + } + val dataList: LiveData> = _dataList private val _loadStatus = MutableLiveData>() @@ -77,12 +82,6 @@ class CustomPageViewModel( var refreshCount = 0 - private val recentGamesObserver = Observer(::notifyItemChanged) - - private val pluginObserver = Observer(::notifyItemChanged) - - private val discoverObserver = Observer(::notifyItemChanged) - val pullDownPushData = MutableLiveData() val pageSwitchData = MutableLiveData() @@ -100,12 +99,6 @@ class CustomPageViewModel( val pageLocation: PageLocation get() = pageTracker.pageLocation - init { - repository.recentGamesItemLiveData.observeForever(recentGamesObserver) - repository.customPluginItemLiveData.observeForever(pluginObserver) - repository.customDiscoverItemLiveData.observeForever(discoverObserver) - } - fun init( pageConfigure: PageConfigure, searchToolbarTabWrapperViewModel: SearchToolbarTabWrapperViewModel?, @@ -546,15 +539,15 @@ class CustomPageViewModel( } private val _subjectDestinationWithCustom = - MutableLiveData>>() - val subjectDestinationWithCustom: LiveData>> = + MutableLiveData>>() + val subjectDestinationWithCustom: LiveData>> = _subjectDestinationWithCustom override fun navigateSubjectDetailPage( item: CustomSubjectCollectionItem, subject: CustomPageData.LinkColumnCollection.CustomSubjectEntity ) { - _subjectDestinationWithCustom.value = Event(subject to item.data.isQqMini) + _subjectDestinationWithCustom.value = Event(subject to item.data.subjectType) } private val _subjectCollectionDestination = @@ -699,9 +692,6 @@ class CustomPageViewModel( super.onCleared() compositeDisposable.clear() repository.onClear() - repository.recentGamesItemLiveData.removeObserver(recentGamesObserver) - repository.customPluginItemLiveData.removeObserver(pluginObserver) - repository.customDiscoverItemLiveData.removeObserver(discoverObserver) } diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomFoldSlideLargeImageItemAdapter.kt b/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomFoldSlideLargeImageItemAdapter.kt index 18017b9c61..afce634eff 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomFoldSlideLargeImageItemAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomFoldSlideLargeImageItemAdapter.kt @@ -28,6 +28,7 @@ import com.gh.gamecenter.eventbus.EBPackage import com.gh.gamecenter.feature.entity.CustomPageTrackData import com.gh.gamecenter.feature.entity.GameEntity import com.gh.gamecenter.feature.game.GameItemViewHolder +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper import com.gh.gamecenter.home.custom.eventlistener.SubjectEventHelper import com.gh.gamecenter.home.custom.model.CustomSubjectItem import com.lightgame.download.DownloadEntity @@ -166,7 +167,12 @@ class CustomFoldSlideLargeImageItemAdapter( ) { item = game - ImageUtils.display(binding.poster, game.homeSetting.image) + if (game.isWechatMiniGame()) { + ImageUtils.display(binding.poster, game.banner) + } else { + ImageUtils.display(binding.poster, game.homeSetting.image) + } + binding.ivIcon.displayGameIcon(game) binding.tvTitle.text = game.name GameItemViewHolder.initGameSubtitleAndAdLabel( @@ -177,6 +183,8 @@ class CustomFoldSlideLargeImageItemAdapter( data.data.adIconActive ) + MiniGameItemHelper.setMiniGameUsage(binding.gamePlayCount, game) + binding.tvBubble.text = game.bubbleText binding.gStar.goneIf(!(data.data.showStar && game.commentCount > 3)) { binding.tvStar.text = if (game.star == 10.0F) "10" else game.star.toString() diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomGameHorizontalAdapter.kt b/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomGameHorizontalAdapter.kt index 823c0a3c4f..af1fbd46ed 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomGameHorizontalAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomGameHorizontalAdapter.kt @@ -4,7 +4,6 @@ import android.content.Context import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.gh.common.util.* -import com.gh.common.util.NewFlatLogUtils import com.gh.common.util.NewLogUtils import com.gh.gamecenter.GameDetailActivity import com.gh.gamecenter.R @@ -19,6 +18,7 @@ import com.gh.gamecenter.game.horizontal.GameHorizontalSimpleItemViewHolder import com.gh.gamecenter.home.PageConfigure import com.gh.gamecenter.home.custom.model.CustomSubjectItem import com.gh.gamecenter.home.custom.viewholder.CustomGameHorizontalItemViewHolder +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper import com.lightgame.download.DownloadEntity class CustomGameHorizontalAdapter( @@ -40,8 +40,8 @@ class CustomGameHorizontalAdapter( get() = _data.data private val type: GameHorizontalListType - get() = if (subjectEntity.isQQColumn) { - GameHorizontalListType.QGameSubjectHorizontalType + get() = if (subjectEntity.isMiniGame) { + GameHorizontalListType.MiniGameSubjectHorizontalType } else { GameHorizontalListType.SubjectHorizontalType } @@ -60,12 +60,14 @@ class CustomGameHorizontalAdapter( override fun getItemCount(): Int { val size = dataList.size - return if (type == GameHorizontalListType.GameDetailHorizontalType) { - size - } else if (type == GameHorizontalListType.QGameSubjectHorizontalType) { - dataList.size - } else { - when { + return when (type) { + GameHorizontalListType.GameDetailHorizontalType -> { + size + } + GameHorizontalListType.MiniGameSubjectHorizontalType -> { + dataList.size + } + else -> when { size < 4 -> size size < 8 -> 4 else -> 8 @@ -132,11 +134,8 @@ class CustomGameHorizontalAdapter( ) } - if (gameEntity.isQQMiniGame()) { - NewFlatLogUtils.logQGameClick(gameEntity.qqMiniGameAppId, gameEntity.name) - GlobalActivityManager.currentActivity?.let { - DirectUtils.directToQGameById(it, gameEntity.qqMiniGameAppId) - } + if (gameEntity.isMiniGame()) { + MiniGameItemHelper.launchMiniGame(gameEntity.miniGameAppId, gameEntity.miniGameType) } else { GameDetailActivity.startGameDetailActivity( context, @@ -201,5 +200,5 @@ sealed class GameHorizontalListType { object GameDetailHorizontalType : GameHorizontalListType() object SubjectHorizontalType : GameHorizontalListType() - object QGameSubjectHorizontalType : GameHorizontalListType() + object MiniGameSubjectHorizontalType : GameHorizontalListType() } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomGameRefreshVerticalAdapter.kt b/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomGameRefreshVerticalAdapter.kt index 4eee845f92..a0e1d0c9b3 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomGameRefreshVerticalAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomGameRefreshVerticalAdapter.kt @@ -15,6 +15,7 @@ import com.gh.gamecenter.eventbus.EBPackage import com.gh.gamecenter.feature.entity.CustomPageTrackData import com.gh.gamecenter.feature.entity.GameEntity import com.gh.gamecenter.feature.game.GameItemViewHolder +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper import com.gh.gamecenter.game.vertical.GameItemUi import com.gh.gamecenter.home.custom.eventlistener.GameSubjectCollectionEventHelper import com.gh.gamecenter.home.custom.model.CustomPageData diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomGameVerticalAdapter.kt b/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomGameVerticalAdapter.kt index aa2ea1d6ad..a6153c641a 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomGameVerticalAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomGameVerticalAdapter.kt @@ -1,12 +1,8 @@ package com.gh.gamecenter.home.custom.adapter import android.content.Context -import android.graphics.drawable.Drawable import android.os.Build import android.view.ViewGroup -import android.view.ViewGroup.MarginLayoutParams -import androidx.core.content.ContextCompat -import androidx.core.view.marginBottom import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView.ViewHolder import com.gh.common.databind.BindingAdapters @@ -20,6 +16,7 @@ import com.gh.gamecenter.eventbus.EBPackage import com.gh.gamecenter.feature.entity.CustomPageTrackData import com.gh.gamecenter.feature.entity.GameEntity import com.gh.gamecenter.feature.game.GameItemViewHolder +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper import com.gh.gamecenter.game.vertical.GameItemUi import com.gh.gamecenter.home.custom.eventlistener.SubjectEventHelper import com.lightgame.download.DownloadEntity @@ -45,7 +42,7 @@ class CustomGameVerticalAdapter( } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { - return SimpleGameItemViewHolder(GameItemUi(context)) + return SimpleGameItemViewHolder(GameItemUi(context), eventHelper) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { @@ -102,7 +99,10 @@ class CustomGameVerticalAdapter( } - class SimpleGameItemViewHolder(private val ui: GameItemUi) : ViewHolder(ui.root) { + class SimpleGameItemViewHolder( + private val ui: GameItemUi, + private val eventHelper: SubjectEventHelper + ) : ViewHolder(ui.root) { var placeholderGameViewHolder: GameViewHolder? = null fun bindSimpleGameItem( @@ -171,6 +171,8 @@ class CustomGameVerticalAdapter( adLabelTv ) + MiniGameItemHelper.setMiniGameUsage(gamePlayCountTv, gameEntity) + // 没错,产品就把这个通用样式叫推荐榜单专题 downloadTv.putWidgetBusinessName("推荐榜单专题") @@ -201,7 +203,9 @@ class CustomGameVerticalAdapter( adapter, entrance, location = location, traceEvent = gameEntity.exposureEvent - ) + ) { + eventHelper.onDownloadButtonClick(position, gameEntity) + } root.setPadding(paddingStart, root.paddingTop, paddingEnd, root.paddingBottom) } diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomPageAdapter.kt b/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomPageAdapter.kt index 42603a02a1..facb1f2c13 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomPageAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/adapter/CustomPageAdapter.kt @@ -42,6 +42,7 @@ import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.CUSTOM_PAGE_ import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.CUSTOM_PAGE_ITEM_TYPE_GAME_LONG_LIST import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.CUSTOM_PAGE_ITEM_TYPE_GAME_VERTICAL_SLIDE import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.CUSTOM_PAGE_ITEM_TYPE_HORIZONTAL_SLIDE_VIDEO_LIST +import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.CUSTOM_PAGE_ITEM_TYPE_MINI_GAME_RECENT_PLAY import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.CUSTOM_PAGE_ITEM_TYPE_NAVIGATION import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.CUSTOM_PAGE_ITEM_TYPE_NEW_GAME_TEST import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.CUSTOM_PAGE_ITEM_TYPE_PLUGIN @@ -192,6 +193,8 @@ class CustomPageAdapter( CUSTOM_PAGE_ITEM_TYPE_FOOTER -> CustomFooterViewHolder(viewModel, parent.toBinding()) + CUSTOM_PAGE_ITEM_TYPE_MINI_GAME_RECENT_PLAY -> CustomHomeRecentMiniGameViewHolder(viewModel, parent.toBinding()) + else -> CustomDoubleCardViewHolder(viewModel, parent.toBinding()) } @@ -256,6 +259,8 @@ class CustomPageAdapter( is CustomRefreshIconViewHolder -> holder.bindView(item) + is CustomHomeRecentMiniGameViewHolder -> holder.bindView(item) + is CustomGameCollectionRefreshVerticalSlideViewHolder -> holder.bindView(item) is CustomFooterViewHolder -> holder.initFooterViewHolder( diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/eventlistener/GameSubjectCollectionEventHelper.kt b/app/src/main/java/com/gh/gamecenter/home/custom/eventlistener/GameSubjectCollectionEventHelper.kt index 227cafdf60..ca0383a202 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/eventlistener/GameSubjectCollectionEventHelper.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/eventlistener/GameSubjectCollectionEventHelper.kt @@ -42,7 +42,9 @@ class GameSubjectCollectionEventHelper( fun navigateToGameDetailPage(childPosition: Int, game: GameEntity, subject: CustomPageData.LinkColumnCollection.CustomSubjectEntity? = null) { isMatch { - if (it.isSubjectCollection) { + if (game.isMiniGame()) { + tracker.trackMiniGameClick(it, subject, game) + } else if (it.isSubjectCollection) { tracker.trackColumnCollectionClick(it, subject, game, "游戏") } else { tracker.trackGameListCollectionClickWithGame(it, game.id, game.name ?: "") @@ -53,7 +55,9 @@ class GameSubjectCollectionEventHelper( fun onDownloadButtonClick(childPosition: Int, gameEntity: GameEntity, subject: CustomPageData.LinkColumnCollection.CustomSubjectEntity? = null) { isMatch { - if (it.isSubjectCollection) { + if (gameEntity.isMiniGame()) { + tracker.trackMiniGameClick(it, subject, gameEntity) + } else if (it.isSubjectCollection) { tracker.trackColumnCollectionClick(it, subject, gameEntity, "按钮") } else { tracker.trackGameListCollectionClick(it, "按钮") diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/eventlistener/RecentMiniGameItemEventHelper.kt b/app/src/main/java/com/gh/gamecenter/home/custom/eventlistener/RecentMiniGameItemEventHelper.kt new file mode 100644 index 0000000000..d608cfa384 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/home/custom/eventlistener/RecentMiniGameItemEventHelper.kt @@ -0,0 +1,16 @@ +package com.gh.gamecenter.home.custom.eventlistener + +import com.gh.gamecenter.feature.entity.GameEntity +import com.gh.gamecenter.home.custom.CustomPageViewModel +import com.gh.gamecenter.home.custom.tracker.SubjectTracker + +class RecentMiniGameItemEventHelper (viewModel: CustomPageViewModel +) : CustomPageItemChildEventHelper(viewModel) { + + private val tracker = SubjectTracker(viewModel.pageLocation) + + fun navigateToGameDetailPage(position: Int, gameEntity: GameEntity) { + viewModel.navigateToGameDetailPageByGame(_item, position, gameEntity) + tracker.trackMiniGameClick(_item, gameEntity) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/eventlistener/SubjectEventHelper.kt b/app/src/main/java/com/gh/gamecenter/home/custom/eventlistener/SubjectEventHelper.kt index 354e1dfb2e..2934bcbb1e 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/eventlistener/SubjectEventHelper.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/eventlistener/SubjectEventHelper.kt @@ -12,8 +12,8 @@ class SubjectEventHelper(viewModel: CustomPageViewModel) : CustomPageItemChildEv private val tracker = SubjectTracker(viewModel.pageLocation) fun navigateToGameDetailPage(position: Int, gameEntity: GameEntity) { - if (gameEntity.isQQMiniGame()) { - tracker.trackQQGameClick(_item, gameEntity) + if (gameEntity.isMiniGame()) { + tracker.trackMiniGameClick(_item, gameEntity) } else { tracker.trackColumnClick(_item, gameEntity, "游戏") } @@ -22,7 +22,11 @@ class SubjectEventHelper(viewModel: CustomPageViewModel) : CustomPageItemChildEv } fun onDownloadButtonClick(childPosition: Int, gameEntity: GameEntity) { - tracker.trackColumnClick(_item, gameEntity, "按钮") + if (gameEntity.isMiniGame()) { + tracker.trackMiniGameClick(_item, gameEntity) + } else { + tracker.trackColumnClick(_item, gameEntity, "按钮") + } } fun navigateSubjectPage() { diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/model/CustomPageData.kt b/app/src/main/java/com/gh/gamecenter/home/custom/model/CustomPageData.kt index 999e87690b..8ca86ae726 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/model/CustomPageData.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/model/CustomPageData.kt @@ -33,7 +33,7 @@ class CustomPageData( data class PageSwitch( @SerializedName("top_search") - private val _topSearch: String? = null, + private val _topSearch: String? = null,// 顶部搜索类型(halo_game:光环游戏、mini_game:小游戏(低于v5.36版本返回qq_mini_game)、bbs:论坛、空字符串:不显示) @SerializedName("pull_down_push") private val _pullDownPush: Boolean? = null, @SerializedName("suspended_window") @@ -69,12 +69,18 @@ class CustomPageData( val linkTopGameComments: List? = null, @SerializedName("link_qq_mini_game_column_detail") val qqMiniGameColumn: SubjectEntity? = null, + @SerializedName("link_wechat_game_column_detail") + val wechatMiniGameColumn: SubjectEntity? = null, @SerializedName("link_common_collection") val linkCommonCollection: CommonContentCollection? = null ) { // 游戏专题 val gameSubjectEntity: SubjectEntity? - get() = linkColumn ?: qqMiniGameColumn + get() = when(link.type) { + CustomPageItem.CUSTOM_LINK_TYPE_QQ_MINI_GAME_COLUMN_DETAIL -> qqMiniGameColumn + CustomPageItem.CUSTOM_LINK_TYPE_WECHAT_MINI_GAME_COLUMN_DETAIL -> wechatMiniGameColumn + else -> linkColumn + } val link: LinkEntity get() = _link ?: LinkEntity() @@ -141,6 +147,15 @@ class CustomPageData( val isQqMini: Boolean get() = gamePlatform == "qq_mini" + val isWechatMini: Boolean + get() = gamePlatform == "wechat_mini" + + val subjectType: SubjectData.SubjectType get() = when { + isQqMini -> SubjectData.SubjectType.QQ_GAME + isWechatMini -> SubjectData.SubjectType.WECHAT_GAME + else -> SubjectData.SubjectType.NORMAL + } + val explain: String get() = _explain ?: "" diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/model/CustomPageItem.kt b/app/src/main/java/com/gh/gamecenter/home/custom/model/CustomPageItem.kt index 3939ef239f..6a75ada82e 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/model/CustomPageItem.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/model/CustomPageItem.kt @@ -1,5 +1,6 @@ package com.gh.gamecenter.home.custom.model +import com.gh.common.util.ViewPagerFragmentHelper import com.gh.gamecenter.common.entity.LinkEntity import com.gh.gamecenter.common.exposure.ExposureSource import com.gh.gamecenter.core.utils.TimeUtils @@ -79,7 +80,10 @@ abstract class CustomPageItem( const val CUSTOM_LINK_TYPE_QUESTION = "question" const val CUSTOM_LINK_TYPE_PLUGIN_AREA = "plugin_area" const val CUSTOM_LINK_TYPE_CWZS_RECENTLY_PLAYED = "cwzs_recently_played" - const val CUSTOM_LINK_TYPE_QQ_MINI_GAME_COLUMN_DETAIL = "qq_mini_game_column_detail" + const val CUSTOM_LINK_TYPE_QQ_GAME_RECENTLY_PLAYED = "qq_game_recently_played" + const val CUSTOM_LINK_TYPE_WECHAT_GAME_RECENTLY_PLAYED = "wechat_game_recently_played" + const val CUSTOM_LINK_TYPE_QQ_MINI_GAME_COLUMN_DETAIL = ViewPagerFragmentHelper.TYPE_QQ_MINI_GAME_COLUMN + const val CUSTOM_LINK_TYPE_WECHAT_MINI_GAME_COLUMN_DETAIL = ViewPagerFragmentHelper.TYPE_WECHAT_GAME_COLUMN const val CUSTOM_LINK_TYPE_HALO_RECOMMEND = "halo_recommend" const val CUSTOM_LINK_TYPE_COLUMN_COLLECTION = "column_collection" // 专题合集 const val CUSTOM_LINK_TYPE_GAME_LIST_COLLECTION = "game_list_collection" @@ -155,6 +159,7 @@ abstract class CustomPageItem( const val CUSTOM_PAGE_ITEM_TYPE_COLLECTION_REFRESH_ICON_MATRIX = 28 const val CUSTOM_PAGE_ITEM_TYPE_COLLECTION_REFRESH_ICON_LANE = 29 const val CUSTOM_PAGE_ITEM_TYPE_COLLECTION_REFRESH_SLIDE_LIST = 30 + const val CUSTOM_PAGE_ITEM_TYPE_MINI_GAME_RECENT_PLAY = 31 // 专题样式 to itemType val subjectTypeMap: HashMap = hashMapOf( @@ -266,7 +271,10 @@ abstract class CustomPageItem( CUSTOM_LINK_TYPE_QUESTION to "内容卡片", CUSTOM_LINK_TYPE_PLUGIN_AREA to "插件化区域", CUSTOM_LINK_TYPE_CWZS_RECENTLY_PLAYED to "最近在玩", + CUSTOM_LINK_TYPE_QQ_GAME_RECENTLY_PLAYED to "QQ小游戏-最近在玩", + CUSTOM_LINK_TYPE_WECHAT_GAME_RECENTLY_PLAYED to "微信小游戏-最近在玩", CUSTOM_LINK_TYPE_QQ_MINI_GAME_COLUMN_DETAIL to "QQ小游戏专题", + CUSTOM_LINK_TYPE_WECHAT_MINI_GAME_COLUMN_DETAIL to "微信小游戏专题", CUSTOM_LINK_TYPE_HALO_RECOMMEND to "光环推荐", CUSTOM_LINK_TYPE_COLUMN_COLLECTION to "专题合集", CUSTOM_LINK_TYPE_GAME_LIST_COLLECTION to "游戏单合集", @@ -303,7 +311,7 @@ abstract class CustomPageItem( CUSTOM_PAGE_ITEM_TYPE_GAME_LONG_LIST, CUSTOM_PAGE_ITEM_TYPE_GAME_VERTICAL_SLIDE, CUSTOM_PAGE_ITEM_TYPE_PLUGIN, - CUSTOM_PAGE_ITEM_TYPE_RECENT_PLAY + CUSTOM_PAGE_ITEM_TYPE_RECENT_PLAY, ) @@ -569,6 +577,26 @@ data class CustomRecentGamesItem( } } + +// 最近在玩 +data class CustomRecentMiniGamesItem( + private val _link: LinkEntity, + val data: List, + private val _position: Int, + private val _componentPosition: Int +) : CustomPageItem(_link, _position, _componentPosition) { + + override val itemType: Int + get() = CUSTOM_PAGE_ITEM_TYPE_MINI_GAME_RECENT_PLAY + + override fun doAreContentsTheSames(other: CustomPageItem): Boolean { + return other is CustomRecentMiniGamesItem + && data == other.data + && position == other.position + && componentPosition == other.componentPosition + } +} + // 插件化区域 data class CustomPluginItem( private val _link: LinkEntity, diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/model/CustomPageRemoteDataSource.kt b/app/src/main/java/com/gh/gamecenter/home/custom/model/CustomPageRemoteDataSource.kt index 663d65d545..3040005f31 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/model/CustomPageRemoteDataSource.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/model/CustomPageRemoteDataSource.kt @@ -45,6 +45,8 @@ class CustomPageRemoteDataSource( fun loadChangeSubjectGame(subjectEntity: SubjectEntity): Observable> = if (subjectEntity.isQQColumn) { newApi.getSubjectQGame(subjectEntity.id) + } else if (subjectEntity.isWechatColumn) { + newApi.getSubjectWGame(subjectEntity.id) } else { api.getSubjectGame(subjectEntity.id) } diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/model/CustomPageRepository.kt b/app/src/main/java/com/gh/gamecenter/home/custom/model/CustomPageRepository.kt index 7948643914..a48d6dee4b 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/model/CustomPageRepository.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/model/CustomPageRepository.kt @@ -2,6 +2,7 @@ package com.gh.gamecenter.home.custom.model import android.graphics.Paint import androidx.lifecycle.LiveData +import androidx.lifecycle.MediatorLiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Observer import com.gh.common.filter.RegionSettingHelper @@ -9,6 +10,7 @@ import com.gh.common.util.GameSubstituteRepositoryHelper import com.gh.common.util.HomePluggableHelper import com.gh.download.DownloadManager import com.gh.gamecenter.R +import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.utils.TextHelper import com.gh.gamecenter.common.utils.dip2px import com.gh.gamecenter.common.utils.sp2px @@ -46,7 +48,12 @@ import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMPONENTS_S import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.CUSTOM_LINK_TYPE_COLUMN import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.CUSTOM_LINK_TYPE_GAME import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.CUSTOM_LINK_TYPE_HALO_RECOMMEND +import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.CUSTOM_LINK_TYPE_QQ_GAME_RECENTLY_PLAYED import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.CUSTOM_LINK_TYPE_QQ_MINI_GAME_COLUMN_DETAIL +import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.CUSTOM_LINK_TYPE_WECHAT_GAME_RECENTLY_PLAYED +import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.CUSTOM_LINK_TYPE_WECHAT_MINI_GAME_COLUMN_DETAIL +import com.gh.gamecenter.minigame.MiniGameRecentlyPlayRepository +import com.gh.gamecenter.minigame.MiniGameRecentlyPlayUseCase import com.gh.gamecenter.packagehelper.PackageRepository import com.gh.gamecenter.retrofit.RetrofitManager import com.gh.gamecenter.wrapper.MainWrapperRepository @@ -71,6 +78,10 @@ class CustomPageRepository private constructor( private var recentItem: CustomRecentGamesItem? = null + private var recentQQItem: CustomRecentMiniGamesItem? = null + + private var recentWechatItem: CustomRecentMiniGamesItem? = null + private var pluginItem: CustomPluginItem? = null private var discoverCardItem: CustomDiscoverCardItem? = null @@ -79,43 +90,45 @@ class CustomPageRepository private constructor( private var displayingGameIdSet = hashSetOf() // 当前正在显示的游戏 id 列表 - private val _customPluginItemLiveData = MutableLiveData() + private val _customPluginItemLiveData = MediatorLiveData().apply { + addSource(PackageRepository.gameUpdateLiveData) { + refreshPluginIfNeed(it)?.let(this::setValue) + } + } val customPluginItemLiveData: LiveData = _customPluginItemLiveData - private val _recentGamesItemLiveData = MutableLiveData() + private val _recentGamesItemLiveData = MediatorLiveData().apply { + addSource(DownloadManager.getInstance().downloadEntityLiveData) { + refreshRecentVGameIfNeed()?.let(this::setValue) + } + addSource(PackageRepository.recentVaPlayedChanged) { + refreshRecentVGameIfNeed()?.let(this::setValue) + } + } val recentGamesItemLiveData: LiveData = _recentGamesItemLiveData - private val _customDiscoverItemLiveData = MutableLiveData() + private val _recentMiniGamesItemLiveData = MediatorLiveData().apply { + addSource(MiniGameRecentlyPlayUseCase.qqRecentGamesItemLiveData) { + refreshRecentQQMiniGameIfNeed(it)?.let(this::setValue) + } + addSource(MiniGameRecentlyPlayUseCase.wechatRecentGamesItemLiveData) { + refreshRecentWechatMiniGameIfNeed(it)?.let(this::setValue) + } + } + + val recentMiniGamesItemLiveData: LiveData = _recentMiniGamesItemLiveData + + private val _customDiscoverItemLiveData = MediatorLiveData().apply { + addSource(shareRepository.discoverData) { + refreshDiscoverDataIfNeed(it)?.let(this::setValue) + } + } val customDiscoverItemLiveData: LiveData = _customDiscoverItemLiveData - private val gameUpdateObserver = Observer> { - refreshPluginIfNeed(it)?.let(_customPluginItemLiveData::setValue) - - } - - private val recentVaPlayedObserver = Observer { - refreshRecentVGameIfNeed()?.let(_recentGamesItemLiveData::setValue) - } - - private val downloadEntityObserver = Observer> { - refreshRecentVGameIfNeed()?.let(_recentGamesItemLiveData::setValue) - } - - private val discoveryCardObserver = Observer { - refreshDiscoverDataIfNeed(it)?.let(_customDiscoverItemLiveData::setValue) - } - private var lastComponentType = "" private var lastSubjectId = "" private var gameChildPosition = 0 - init { - PackageRepository.gameUpdateLiveData.observeForever(gameUpdateObserver) - PackageRepository.recentVaPlayedChanged.observeForever(recentVaPlayedObserver) - DownloadManager.getInstance().downloadEntityLiveData.observeForever(downloadEntityObserver) - shareRepository.discoverData.observeForever(discoveryCardObserver) - } - private fun refreshPluginIfNeed(updateList: List): CustomPluginItem? { val gameList = arrayListOf() updateList.forEach { @@ -144,6 +157,20 @@ class CustomPageRepository private constructor( } } + private fun refreshRecentQQMiniGameIfNeed(list: List): CustomRecentMiniGamesItem? { + return recentQQItem?.let { + recentQQItem = CustomRecentMiniGamesItem(it.link, list, it.position, it.componentPosition) + recentQQItem + } + } + + private fun refreshRecentWechatMiniGameIfNeed(list: List): CustomRecentMiniGamesItem? { + return recentWechatItem?.let { + recentQQItem = CustomRecentMiniGamesItem(it.link, list, it.position, it.componentPosition) + recentQQItem + } + } + private fun refreshDiscoverDataIfNeed(discoveryCardEntity: DiscoveryCardEntity): CustomDiscoverCardItem? { return discoverCardItem?.let { discoverCardItem = CustomDiscoverCardItem(it.link, discoveryCardEntity, it.position, it.componentPosition) @@ -220,15 +247,14 @@ class CustomPageRepository private constructor( } } - item.link.type == CUSTOM_LINK_TYPE_COLUMN || item.link.type == CUSTOM_LINK_TYPE_QQ_MINI_GAME_COLUMN_DETAIL -> { + item.link.type == CUSTOM_LINK_TYPE_COLUMN || item.link.type == CUSTOM_LINK_TYPE_QQ_MINI_GAME_COLUMN_DETAIL || item.link.type == CUSTOM_LINK_TYPE_WECHAT_MINI_GAME_COLUMN_DETAIL -> { // 游戏专题 - val gameSubject = if (item.link.type == CUSTOM_LINK_TYPE_COLUMN) { - item.linkColumn?.data?.forEach { - it.gameLocation = GameEntity.GameLocation.INDEX + val gameSubject = item.gameSubjectEntity?.also { + if (item.link.type == CUSTOM_LINK_TYPE_COLUMN) { + it.data?.forEach { game -> + game.gameLocation = GameEntity.GameLocation.INDEX + } } - item.linkColumn - } else { - item.qqMiniGameColumn } var isAdded = false @@ -321,6 +347,30 @@ class CustomPageRepository private constructor( } } + item.link.type == CUSTOM_LINK_TYPE_WECHAT_GAME_RECENTLY_PLAYED || + item.link.type == CUSTOM_LINK_TYPE_QQ_GAME_RECENTLY_PLAYED -> { + // 微信小游戏-最近在玩/QQ小游戏-最近在玩(需要用户登录才显示) + val gameType = if (item.link.type == CUSTOM_LINK_TYPE_WECHAT_GAME_RECENTLY_PLAYED) { + Constants.WECHAT_MINI_GAME + } else { + Constants.QQ_MINI_GAME + } + val recentItem = CustomRecentMiniGamesItem( + item.link, + MiniGameRecentlyPlayUseCase.getRecentlyPlayedMiniGameList(gameType), + pageInfo.position, + pageInfo.componentPosition + ) + if (item.link.type == CUSTOM_LINK_TYPE_WECHAT_GAME_RECENTLY_PLAYED) { + recentWechatItem = recentItem + } else { + recentQQItem = recentItem + } + list.add(recentItem) + pageInfo.positionIncrement() + pageInfo.componentPositionIncrement() + } + item.linkColumnCollection != null -> { // 专题合集 val linkColumnCollection = item.linkColumnCollection @@ -661,7 +711,7 @@ class CustomPageRepository private constructor( */ private fun substituteGameIfNeeded(gameSubject: SubjectEntity) { if (!gameSubject.relatedColumnId.isNullOrEmpty() && gameSubject.data != null) { - when(gameSubject.type) { + when (gameSubject.type) { COMPONENTS_GAME_SUBJECT_TYPE_GAME_VERTICAL, COMPONENTS_SUBJECT_TYPE_GAME_VERTICAL_SLIDE, COMPONENTS_SUBJECT_TYPE_GAME_HORIZONTAL, @@ -726,10 +776,6 @@ class CustomPageRepository private constructor( fun onClear() { compositeDisposable.clear() - PackageRepository.gameUpdateLiveData.removeObserver(gameUpdateObserver) - PackageRepository.recentVaPlayedChanged.removeObserver(recentVaPlayedObserver) - shareRepository.discoverData.removeObserver(discoveryCardObserver) - DownloadManager.getInstance().downloadEntityLiveData.removeObserver(downloadEntityObserver) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/tracker/GameSubjectCollectionTracker.kt b/app/src/main/java/com/gh/gamecenter/home/custom/tracker/GameSubjectCollectionTracker.kt index f8f86b6ae3..a7262899dc 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/tracker/GameSubjectCollectionTracker.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/tracker/GameSubjectCollectionTracker.kt @@ -4,9 +4,9 @@ import com.gh.gamecenter.common.entity.LinkEntity import com.gh.gamecenter.common.utils.SensorsBridge import com.gh.gamecenter.feature.entity.GameEntity import com.gh.gamecenter.feature.entity.PageLocation +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper import com.gh.gamecenter.home.custom.CustomPageTracker -import com.gh.gamecenter.home.custom.model.CustomPageData -import com.gh.gamecenter.home.custom.model.CustomSubjectCollectionItem +import com.gh.gamecenter.home.custom.model.* class GameSubjectCollectionTracker(private val pageLocation: PageLocation) { @@ -102,4 +102,26 @@ class GameSubjectCollectionTracker(private val pageLocation: PageLocation) { } trackGameListCollectionClick(item, "更多", otherParams) } + + fun trackMiniGameClick( + item: CustomSubjectCollectionItem, + subject: CustomPageData.LinkColumnCollection.CustomSubjectEntity?, + game: GameEntity + ) { + MiniGameItemHelper.trackMiniGameClick( + gameEntity = game, + pageLocation.bottomTab, + pageLocation.severalTabPageId, + pageLocation.severalTabPageName, + pageLocation.tabPosition, + pageLocation.tabContent, + pageLocation.pageId, + pageLocation.pageName, + subject?.id ?: "", + subject?.title ?: "", + "自定义页面", + item.componentStyle, + "", + ) + } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/tracker/SubjectTracker.kt b/app/src/main/java/com/gh/gamecenter/home/custom/tracker/SubjectTracker.kt index 99bf5789c9..30810b9d38 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/tracker/SubjectTracker.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/tracker/SubjectTracker.kt @@ -8,6 +8,7 @@ import com.gh.gamecenter.home.custom.model.CustomGameItem import com.gh.gamecenter.home.custom.model.CustomPageItem import com.gh.gamecenter.home.custom.model.CustomSplitSubjectItem import com.gh.gamecenter.home.custom.model.CustomSubjectItem +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper class SubjectTracker(private val pageLocation: PageLocation) { @@ -46,14 +47,15 @@ class SubjectTracker(private val pageLocation: PageLocation) { ) } - fun trackQQGameClick(item: CustomPageItem, game: GameEntity) { + fun trackMiniGameClick(item: CustomPageItem, game: GameEntity) { val subject = when { item is CustomGameItem -> item.linkColumn item is CustomSubjectItem -> item.data item is CustomSplitSubjectItem -> item.data else -> null } - SensorsBridge.trackQQGameClick( + MiniGameItemHelper.trackMiniGameClick( + gameEntity = game, pageLocation.bottomTab, pageLocation.severalTabPageId, pageLocation.severalTabPageName, @@ -66,8 +68,6 @@ class SubjectTracker(private val pageLocation: PageLocation) { "自定义页面", item.componentStyle, "", - game.id, - game.name ?: "" ) } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomDoubleCardViewHolder.kt b/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomDoubleCardViewHolder.kt index ef7b5611b5..9d0a0686d2 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomDoubleCardViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomDoubleCardViewHolder.kt @@ -100,7 +100,13 @@ class CustomDoubleCardViewHolder( ) { subBinding.run { poster.setTag(ImageUtils.TAG_TARGET_WIDTH, mPosterWidth) - poster.post { poster.display(gameEntity.columnImage) } + poster.post { + if (gameEntity.isWechatMiniGame()) { + poster.display(gameEntity.banner) + } else { + poster.display(gameEntity.columnImage) + } + } gameName.text = gameEntity.name brief.text = if (gameEntity.columnRecommend?.text.isNullOrBlank()) gameEntity.brief diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomGameItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomGameItemViewHolder.kt index 4f8e89f080..0c61914326 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomGameItemViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomGameItemViewHolder.kt @@ -19,7 +19,7 @@ import com.gh.gamecenter.core.utils.StringUtils import com.gh.gamecenter.databinding.GameItemCustomBinding import com.gh.gamecenter.feature.R import com.gh.gamecenter.feature.entity.GameEntity -import com.gh.gamecenter.feature.entity.PluginLocation +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper import com.gh.gamecenter.feature.provider.IBindingAdaptersProvider import com.gh.gamecenter.home.custom.CustomPageViewModel import com.gh.gamecenter.home.custom.adapter.CustomViewExt @@ -27,7 +27,6 @@ import com.gh.gamecenter.home.custom.createExposureEvent import com.gh.gamecenter.home.custom.eventlistener.SubjectEventHelper import com.gh.gamecenter.home.custom.model.CustomPageItem import com.gh.gamecenter.home.custom.model.CustomSplitSubjectItem -import splitties.views.bottomPadding /** * 长列表式 @@ -93,6 +92,7 @@ class CustomGameItemViewHolder( adLabelTv, forceShowSubtitle ) + MiniGameItemHelper.setMiniGameUsage(gamePlayCount, entity) } entity.customPageTrackData = createTrackData(item) @@ -118,7 +118,7 @@ class CustomGameItemViewHolder( briefStyle = subject.briefStyle ) - itemView.setOnClickListener { + binding.clContainer.setOnClickListener { val entrance = if (entity.isPluggable) { StringUtils.buildString("(游戏-专题:插件化-列表[", "${item.startChildPosition}", "])") } else { diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomHomeGameCollectionSlideViewHolder.kt b/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomHomeGameCollectionSlideViewHolder.kt index f17c3c1891..0954e966dc 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomHomeGameCollectionSlideViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomHomeGameCollectionSlideViewHolder.kt @@ -1,7 +1,6 @@ package com.gh.gamecenter.home.custom.viewholder import androidx.recyclerview.widget.RecyclerView -import com.gh.gamecenter.common.utils.DarkModeUtils import com.gh.gamecenter.common.view.FixLinearLayoutManager import com.gh.gamecenter.databinding.HomeGameCollectionSlideItemCustomBinding import com.gh.gamecenter.home.custom.CustomPageViewModel diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomHomeGameItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomHomeGameItemViewHolder.kt index 2c01edd415..8098cc30c5 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomHomeGameItemViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomHomeGameItemViewHolder.kt @@ -17,6 +17,7 @@ import com.gh.gamecenter.feature.entity.CustomPageTrackData import com.gh.gamecenter.feature.entity.GameEntity import com.gh.gamecenter.feature.exposure.ExposureEvent import com.gh.gamecenter.feature.game.GameItemViewHolder +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper import com.gh.gamecenter.home.custom.CustomPageViewModel import com.gh.gamecenter.home.custom.createExposureEvent import com.gh.gamecenter.home.custom.eventlistener.SubjectEventHelper @@ -190,6 +191,8 @@ class CustomHomeGameItemViewHolder( binding.adLabelTv ) + MiniGameItemHelper.setMiniGameUsage(binding.gamePlayCount, game) + game.customPageTrackData = createTrackData() DownloadItemUtils.setOnClickListener( diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomHomeHorizontalSlideVideoItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomHomeHorizontalSlideVideoItemViewHolder.kt index 65bdca7696..c02a473a0a 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomHomeHorizontalSlideVideoItemViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomHomeHorizontalSlideVideoItemViewHolder.kt @@ -17,6 +17,7 @@ import com.gh.gamecenter.feature.entity.CustomPageTrackData import com.gh.gamecenter.feature.entity.GameEntity import com.gh.gamecenter.feature.exposure.ExposureEvent import com.gh.gamecenter.feature.game.GameItemViewHolder +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper import com.gh.gamecenter.home.custom.eventlistener.SubjectEventHelper import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder import splitties.views.backgroundColor @@ -86,6 +87,8 @@ class CustomHomeHorizontalSlideVideoItemViewHolder( BindingAdapters.setGameTags(binding.gameTags, gameEntity) GameItemViewHolder.initGameSubtitleAndAdLabel(gameEntity, binding.gameSubtitleTv) + MiniGameItemHelper.setMiniGameUsage(binding.gamePlayCount, gameEntity) + gameEntity.customPageTrackData = createTrackData() DownloadItemUtils.setOnClickListener( binding.root.context, diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomHomeRecentMiniGameViewHolder.kt b/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomHomeRecentMiniGameViewHolder.kt new file mode 100644 index 0000000000..5b6ee61006 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomHomeRecentMiniGameViewHolder.kt @@ -0,0 +1,132 @@ +package com.gh.gamecenter.home.custom.viewholder + +import android.view.View +import android.view.ViewGroup +import androidx.core.view.updateLayoutParams +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.gh.gamecenter.R +import com.gh.gamecenter.common.exposure.ExposureSource +import com.gh.gamecenter.common.utils.dip2px +import com.gh.gamecenter.common.utils.goneIf +import com.gh.gamecenter.common.view.GridSpacingItemColorDecoration +import com.gh.gamecenter.core.runOnIoThread +import com.gh.gamecenter.databinding.ItemHomeRecentVgameBinding +import com.gh.gamecenter.feature.exposure.ExposureEvent +import com.gh.gamecenter.home.custom.CustomPageViewModel +import com.gh.gamecenter.home.custom.IGameChangedNotifier +import com.gh.gamecenter.home.custom.adapter.CustomHomeRecentVGameAdapter +import com.gh.gamecenter.home.custom.createExposureEvent +import com.gh.gamecenter.home.custom.eventlistener.CustomPageItemChildEventHelper +import com.gh.gamecenter.home.custom.eventlistener.RecentMiniGameItemEventHelper +import com.gh.gamecenter.home.custom.model.CustomPageItem +import com.gh.gamecenter.home.custom.model.CustomRecentMiniGamesItem +import com.gh.gamecenter.minigame.MiniGameRecentlyPlayListAdapter + +/** + * 小游戏-最近在玩 + */ +class CustomHomeRecentMiniGameViewHolder( + viewModel: CustomPageViewModel, + var binding: ItemHomeRecentVgameBinding +) : BaseCustomViewHolder(viewModel, binding.root) { + + override val childEventHelper: RecentMiniGameItemEventHelper by lazy { RecentMiniGameItemEventHelper(viewModel) } + + override fun bindView(item: CustomPageItem) { + super.bindView(item) + if (item is CustomRecentMiniGamesItem) { + + fillExposureEventList(item) + + binding.vspaceIv.visibility = View.GONE + binding.divider.visibility = View.GONE + binding.moreTv.visibility = View.GONE + + val entities = item.data + if (entities.isEmpty()) { + binding.root.goneIf(true) + binding.root.updateLayoutParams { + height = 0 + width = RecyclerView.LayoutParams.MATCH_PARENT + } + } else { + binding.root.goneIf(false) + binding.root.updateLayoutParams { + height = 106F.dip2px() + width = RecyclerView.LayoutParams.MATCH_PARENT + } + + binding.titleTv.text = item.componentName + + val gameListAdapter = if (binding.recyclerView.adapter == null) { + val layoutManager = + LinearLayoutManager(binding.root.context, RecyclerView.HORIZONTAL, false) + + binding.recyclerView.layoutManager = layoutManager + binding.recyclerView.itemAnimator = null + val adapter = MiniGameRecentlyPlayListAdapter(binding.root.context) { game, position -> + childEventHelper.navigateToGameDetailPage(position, game) + } + binding.recyclerView.adapter = adapter + binding.recyclerView.addItemDecoration( + GridSpacingItemColorDecoration(binding.root.context, 4, 0, R.color.transparent) + ) + + binding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() { + override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { + if (dx == 0) { + val scrollToEnd = + layoutManager.findLastCompletelyVisibleItemPosition() == (binding.recyclerView.adapter!!.itemCount - 1) + // 当游戏数量超过一屏时,需去除列表右侧的分隔线;去除后,列表最后一个游戏图标与卡片右侧的边距应为16dp + if (scrollToEnd) { + binding.recyclerViewContainer.post { + binding.recyclerViewContainer.layoutParams = + (binding.recyclerViewContainer.layoutParams as ViewGroup.MarginLayoutParams).apply { + rightMargin = 10F.dip2px() + } + } + binding.divider.visibility = View.VISIBLE + + } else { + binding.recyclerViewContainer.post { + binding.recyclerViewContainer.layoutParams = + (binding.recyclerViewContainer.layoutParams as ViewGroup.MarginLayoutParams).apply { + rightMargin = 0 + } + } + binding.divider.visibility = View.GONE + } + } + } + }) + adapter + } else { + binding.recyclerView.adapter as MiniGameRecentlyPlayListAdapter + } + + gameListAdapter.submitList(item.data) + } + } + } + + private fun fillExposureEventList(item: CustomRecentMiniGamesItem) { + val exposureEventList = arrayListOf() + runOnIoThread(true) { + item.data.forEachIndexed { index, game -> + + val event = createExposureEvent( + game, + listOf( + ExposureSource(item.componentName, "") + ), + pageConfigure.exposureSourceList, + index, + item.componentPosition + ) + exposureEventList.add(event) + } + } + item.exposureEventList = exposureEventList + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomRefreshIconViewHolder.kt b/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomRefreshIconViewHolder.kt index 38d651289a..60e226367b 100644 --- a/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomRefreshIconViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/home/custom/viewholder/CustomRefreshIconViewHolder.kt @@ -7,7 +7,6 @@ import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.gh.gamecenter.common.exposure.ExposureSource -import com.gh.gamecenter.common.utils.DarkModeUtils import com.gh.gamecenter.common.utils.dip2px import com.gh.gamecenter.databinding.HomeGameCollectionRefreshItemCustomBinding import com.gh.gamecenter.home.custom.CustomPageViewModel diff --git a/app/src/main/java/com/gh/gamecenter/home/horizontalslidevideo/HomeHorizontalSlideVideoItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/home/horizontalslidevideo/HomeHorizontalSlideVideoItemViewHolder.kt index a3d349ee27..098ec1ab3e 100644 --- a/app/src/main/java/com/gh/gamecenter/home/horizontalslidevideo/HomeHorizontalSlideVideoItemViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/home/horizontalslidevideo/HomeHorizontalSlideVideoItemViewHolder.kt @@ -17,6 +17,7 @@ import com.gh.gamecenter.databinding.ItemHomeHorizontalSlideVideoBinding import com.gh.gamecenter.feature.entity.GameEntity import com.gh.gamecenter.feature.exposure.ExposureEvent import com.gh.gamecenter.feature.game.GameItemViewHolder +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder class HomeHorizontalSlideVideoItemViewHolder(val binding: ItemHomeHorizontalSlideVideoBinding) : @@ -78,6 +79,8 @@ class HomeHorizontalSlideVideoItemViewHolder(val binding: ItemHomeHorizontalSlid BindingAdapters.setGameTags(binding.gameTags, gameEntity) GameItemViewHolder.initGameSubtitleAndAdLabel(gameEntity, binding.gameSubtitleTv) + MiniGameItemHelper.setMiniGameUsage(binding.gamePlayCount, gameEntity) + DownloadItemUtils.setOnClickListener( binding.root.context, binding.downloadBtn, diff --git a/app/src/main/java/com/gh/gamecenter/minigame/MiniGameRecentlyPlayListAdapter.kt b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameRecentlyPlayListAdapter.kt new file mode 100644 index 0000000000..cdb8a7e3a9 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameRecentlyPlayListAdapter.kt @@ -0,0 +1,67 @@ +package com.gh.gamecenter.minigame + +import android.content.Context +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.gh.gamecenter.common.baselist.DiffUtilAdapter +import com.gh.gamecenter.common.utils.toBinding +import com.gh.gamecenter.databinding.ItemHomeVgameBinding +import com.gh.gamecenter.feature.entity.GameEntity +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper + +/** + * 微信小游戏-最近在玩列表 + */ +class MiniGameRecentlyPlayListAdapter( + context: Context, + private val onItemClick:((GameEntity, Int) -> Unit)? = null +) : DiffUtilAdapter(context) { + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): MiniGameRecentlyPlayItemViewHolder { + return MiniGameRecentlyPlayItemViewHolder(parent.toBinding()) + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + (holder as MiniGameRecentlyPlayItemViewHolder).bindView(mDataList[position], position, onItemClick) + } + + override fun getItemCount(): Int { + return mDataList.size + } + + override fun areItemsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean { + return oldItem == newItem + } + + override fun areContentsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean { + return oldItem == newItem + } + + class MiniGameRecentlyPlayItemViewHolder(private var mBinding: ItemHomeVgameBinding) : + RecyclerView.ViewHolder(mBinding.root) { + + fun bindView(entity: GameEntity, position: Int, onItemClick: ((GameEntity, Int) -> Unit)? = null) { + mBinding.gameIconIv.displayGameIcon(entity) + + mBinding.maskView.visibility = View.GONE + mBinding.controlTv.visibility = View.GONE + mBinding.progressBar.visibility = View.GONE + mBinding.dotView.visibility = View.GONE + mBinding.updateHintIv.visibility = View.GONE + mBinding.controlTv.visibility = View.GONE + mBinding.progressBar.visibility = View.GONE + + mBinding.root.setOnClickListener { + if (onItemClick != null) { + onItemClick.invoke(entity, position) + } else { + MiniGameItemHelper.launchMiniGame(entity.miniGameAppId, entity.miniGameType) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/minigame/MiniGameRecentlyPlayRepository.kt b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameRecentlyPlayRepository.kt new file mode 100644 index 0000000000..bb628e0ba8 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameRecentlyPlayRepository.kt @@ -0,0 +1,41 @@ +package com.gh.gamecenter.minigame + +import com.gh.gamecenter.feature.entity.GameEntity +import com.gh.gamecenter.retrofit.RetrofitManager +import com.gh.gamecenter.retrofit.service.ApiService +import io.reactivex.Single +import okhttp3.ResponseBody + +/** + * 小游戏-最近在玩-数据层 + */ +class MiniGameRecentlyPlayRepository( + private val apiService: ApiService = RetrofitManager.getInstance().newApi +) { + + /** + * 获取小游戏-最近在玩游戏列表 + * @param gameType 游戏类型(qq/wechat) + */ + fun getRecentPlayedMiniGameList(gameType: String): Single> { + return apiService.getRecentPlayedMiniGameList(gameType) + } + + /** + * 提交微信小游戏秒玩记录 + * @param wechatAppId 微信游戏ID + * @param gid 设备ID + */ + fun postRecentPlayedWGame(wechatAppId: String, gid: String): Single { + return apiService.postWGamePlay(wechatAppId, gid) + } + + /** + * 提交QQ小游戏秒玩记录 + * @param qqAppId QQ游戏ID + * @param userId 用户ID + */ + fun postRecentPlayedQGame(qqAppId: String, userId: String): Single { + return apiService.postQGamePlay(qqAppId, userId) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/minigame/MiniGameRecentlyPlayUseCase.kt b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameRecentlyPlayUseCase.kt new file mode 100644 index 0000000000..00447230f8 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameRecentlyPlayUseCase.kt @@ -0,0 +1,86 @@ +package com.gh.gamecenter.minigame + +import android.annotation.SuppressLint +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.retrofit.BiResponse +import com.gh.gamecenter.feature.entity.GameEntity +import com.gh.gamecenter.retrofit.RetrofitManager +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.schedulers.Schedulers +import okhttp3.ResponseBody + +/** + * 小游戏-最近在玩-网域层 + */ +object MiniGameRecentlyPlayUseCase { + + private val repository = MiniGameRecentlyPlayRepository(RetrofitManager.getInstance().newApi) + + /** + * 微信小游戏-最近在玩 + */ + private val _wechatRecentGamesItemLiveData = MutableLiveData>() + val wechatRecentGamesItemLiveData: LiveData> = _wechatRecentGamesItemLiveData + + /** + * QQ小游戏-最近在玩 + */ + private val _qqRecentGamesItemLiveData = MutableLiveData>() + val qqRecentGamesItemLiveData: LiveData> = _qqRecentGamesItemLiveData + + @SuppressLint("CheckResult") + fun loadRecentlyPlayedMiniGameList(gameType: String) { + repository.getRecentPlayedMiniGameList(gameType) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(object : BiResponse>() { + override fun onSuccess(data: List) { + if (gameType == Constants.QQ_MINI_GAME) { + _qqRecentGamesItemLiveData.value = data + } else { + _wechatRecentGamesItemLiveData.value = data + } + } + }) + } + + @SuppressLint("CheckResult") + fun submitRecentPlayedWGame(wechatAppId: String, gid: String) { + repository.postRecentPlayedWGame(wechatAppId, gid) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(object : BiResponse() { + override fun onSuccess(data: ResponseBody) { + loadRecentlyPlayedMiniGameList(Constants.WECHAT_MINI_GAME) + } + }) + } + + @SuppressLint("CheckResult") + fun submitRecentPlayedQGame(qqAppId: String,userId: String) { + repository.postRecentPlayedQGame(qqAppId, userId) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(object : BiResponse() { + override fun onSuccess(data: ResponseBody) { + loadRecentlyPlayedMiniGameList(Constants.QQ_MINI_GAME) + } + }) + } + + /** + * 获取小游戏-最近在玩游戏列表缓存 + * @param gameType 游戏类型(qq/wechat) + */ + fun getRecentlyPlayedMiniGameList(gameType: String): List = + if (gameType == Constants.QQ_MINI_GAME) { + _qqRecentGamesItemLiveData.value + } else { + _wechatRecentGamesItemLiveData.value + } ?: let { + loadRecentlyPlayedMiniGameList(gameType)// 最近在玩数据为空时,则调用接口获取数据 + emptyList() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/qgame/QGameSearchActivity.kt b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchActivity.kt similarity index 51% rename from app/src/main/java/com/gh/gamecenter/qgame/QGameSearchActivity.kt rename to app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchActivity.kt index 4cdc16943d..760428f071 100644 --- a/app/src/main/java/com/gh/gamecenter/qgame/QGameSearchActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchActivity.kt @@ -1,45 +1,53 @@ -package com.gh.gamecenter.qgame +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.core.AppExecutor -import com.gh.gamecenter.search.SearchGameIndexFragment -import com.lightgame.utils.Util_System_Keyboard +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 /** - * QQ小游戏-搜索页面 + * 小游戏-搜索页面 */ -class QGameSearchActivity : SearchActivity() { +class MiniGameSearchActivity : SearchActivity() { + + override fun provideDao(): ISearchHistoryDao = MiniGameSearchDao() override fun updateDisplayType(type: DisplayType) { val transaction = supportFragmentManager.beginTransaction() when(type) { - DisplayType.GAME_DETAIL -> { - val digestListFragment = - supportFragmentManager.findFragmentByTag(QGameSearchResultFragment::class.java.name) as? QGameSearchResultFragment - ?: QGameSearchResultFragment() - digestListFragment.setParams(mSearchKey ?: "", mSearchType.value) - transaction.replace(com.gh.gamecenter.R.id.search_result, digestListFragment, SearchGameIndexFragment::class.java.name) + DisplayType.DEFAULT -> { + val fragment = supportFragmentManager.findFragmentByTag(SearchDefaultFragment::class.java.name) + ?: MiniGameSearchDefaultFragment().apply { + arguments = Bundle().also { it.putBoolean(SearchDefaultFragment.KEY_IS_GAME_SEARCH, true) } + } + transaction.replace(R.id.search_result, fragment, SearchDefaultFragment::class.java.name) } + else -> { - AppExecutor.uiExecutor.executeWithDelay({ - Util_System_Keyboard.showSoftKeyboard(this) - }, 100) + val digestListFragment = + supportFragmentManager.findFragmentByTag(SearchGameResultFragment::class.java.name) as? MiniGameSearchResultFragment + ?: MiniGameSearchResultFragment() + digestListFragment.setParams(mSearchKey ?: "", mSearchType.value) + transaction.replace(R.id.search_result, digestListFragment, SearchGameResultFragment::class.java.name) } } mDisplayType = type transaction.commitAllowingStateLoss() } - override fun handleBackPressed(): Boolean { - Util_System_Keyboard.hideSoftKeyboard(this) - finish() - return true - } - companion object { @JvmStatic @@ -54,7 +62,7 @@ class QGameSearchActivity : SearchActivity() { customPageName: String = "", searchBoxPattern: String = "" ): Intent { - val intent = Intent(context, QGameSearchActivity::class.java) + val intent = Intent(context, MiniGameSearchActivity::class.java) intent.putExtra(EntranceConsts.KEY_HINT, hint) intent.putExtra(EntranceConsts.KEY_SOURCE_ENTRANCE, sourceEntrance) intent.putExtra(EntranceConsts.KEY_BOTTOM_TAB_NAME, bottomTab) diff --git a/app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchDao.kt b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchDao.kt new file mode 100644 index 0000000000..44ca3a8783 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchDao.kt @@ -0,0 +1,53 @@ +package com.gh.gamecenter.minigame + +import com.gh.gamecenter.core.utils.SPUtils +import com.gh.gamecenter.db.ISearchHistoryDao + +/** + * 微信小游戏-历史搜索记录 + */ +class MiniGameSearchDao : ISearchHistoryDao { + + override fun add(keyword: String) { + val originString = SPUtils.getString(SP_KEY) + + if (originString.isEmpty()) { + // Insert keyword only for the very first time. + SPUtils.setString(SP_KEY, keyword) + } else { + all?.let { + // Move keyword to the very front if it exists. + if (it.contains(keyword)) { + it.remove(keyword) + } + it.add(0, keyword) + val builder = StringBuilder() + for ((index, key) in it.withIndex()) { + builder.append(key) + if (index != it.size - 1) { + builder.append(SEARCH_KEY_DIVIDER) + } + } + SPUtils.setString(SP_KEY, builder.toString()) + } + } + } + + override fun getAll(): ArrayList? { + val list = SPUtils.getString(SP_KEY).split(SEARCH_KEY_DIVIDER) + + return if (list.size == 1 && list[0].isEmpty()) null else ArrayList(list) + } + + override fun delete(item: String) {} + + override fun deleteAll() { + SPUtils.setString(SP_KEY, "") + } + + + companion object { + const val SP_KEY = "mini_game_key" + const val SEARCH_KEY_DIVIDER = "<-||->" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchDefaultFragment.kt b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchDefaultFragment.kt new file mode 100644 index 0000000000..dd17bfe9d6 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchDefaultFragment.kt @@ -0,0 +1,61 @@ +package com.gh.gamecenter.minigame + +import androidx.viewpager.widget.PagerAdapter +import com.gh.common.constant.Config +import com.gh.common.filter.RegionSettingHelper +import com.gh.gamecenter.common.exposure.ExposureSource +import com.gh.gamecenter.databinding.FragmentSearchDefaultBinding +import com.gh.gamecenter.db.ISearchHistoryDao +import com.gh.gamecenter.feature.exposure.ExposureEvent +import com.gh.gamecenter.search.SearchDefaultFragment + +/** + * 微信小游戏-搜索主页 + */ +class MiniGameSearchDefaultFragment : SearchDefaultFragment() { + + override fun provideDao(): ISearchHistoryDao = MiniGameSearchDao() + + override fun initView() { + mBinding = FragmentSearchDefaultBinding.bind(mCachedView) + mRankList = Config.getNewApiSettingsEntity()?.search?.wechatGameSearchList?.apply { + forEachIndexed { outIndex, rankList -> + rankList.isShowIcon = !rankList.content.any { it.icon.isBlank() } + var i = 0 + while (i < rankList.content.size) { + if (RegionSettingHelper.shouldThisGameBeFiltered(rankList.content[i].linkGame?.id)) { + rankList.content.removeAt(i) + i-- + } + i++ + } + rankList.content.forEachIndexed { index, rank -> + val source = listOf(ExposureSource("小游戏搜索 -> 搜索榜单", "${rankList.title}-${rank.name}")) + if (rank.link.type == "game") { + rank.exposureEvent = ExposureEvent.createEvent( + rank.linkGame?.toGameEntity()?.apply { + outerSequence = outIndex + sequence = index + }, + source + ) + } else { + rank.exposureEvent = ExposureEvent.createEvent(null, source) + } + } + } + } + defaultViewModel?.isExistRankList = mRankList?.isNotEmpty() == true + + updateHistorySearchView(null) + defaultViewModel?.historySearchLiveData?.observe(this) { + updateHistorySearchView(it) + } + + initHeadView() + initRankViewPager() + } + + override fun provideAdapter(pageRatio: Float): PagerAdapter = + MiniGameSearchDefaultRankListAdapter(requireContext(), mRankList!!, pageRatio) +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchDefaultRankAdapter.kt b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchDefaultRankAdapter.kt new file mode 100644 index 0000000000..c6ad9dcc06 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchDefaultRankAdapter.kt @@ -0,0 +1,89 @@ +package com.gh.gamecenter.minigame + +import android.content.Context +import android.graphics.Typeface +import android.view.View +import android.view.View.OnClickListener +import android.view.ViewGroup +import com.gh.common.util.DirectUtils +import com.gh.gamecenter.R +import com.gh.gamecenter.common.base.BaseRecyclerViewHolder +import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.utils.* +import com.gh.gamecenter.databinding.SearchDefaultRankItemBinding +import com.gh.gamecenter.feature.entity.GameEntity +import com.gh.gamecenter.feature.entity.SettingsEntity +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper +import com.lightgame.adapter.BaseRecyclerAdapter +import com.lightgame.utils.Util_System_Keyboard + +/** + * 微信小游戏-搜索榜单列表 + */ +class MiniGameSearchDefaultRankAdapter( + context: Context, + private val mRankList: SettingsEntity.Search.RankList, +) : BaseRecyclerAdapter(context) { + + override fun getItemCount() = minOf(mRankList.content.size, 10) + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = + MiniGameSearchDefaultRankItemViewHolder(parent.toBinding()) + + override fun onBindViewHolder(holder: MiniGameSearchDefaultRankItemViewHolder, position: Int) { + val rank = mRankList.content[position] + + + holder.binding.run { + val gameEntity = rank.linkGame?.toGameEntity() + icon.goneIf(!mRankList.isShowIcon) { + icon.display(if (rank.link.type == "game") gameEntity?.icon else rank.icon) + } + name.text = if (rank.link.type == "game") gameEntity?.name else rank.name.ifBlank { rank.link.text } + index.run { + typeface = Typeface.createFromAsset(mContext.assets, Constants.DIN_FONT_PATH) + text = (position + 1).toString() + setTextColor( + when (position + 1) { + 1 -> R.color.text_ff5151 + 2 -> R.color.text_f67722 + 3 -> R.color.text_ffbf00 + else -> R.color.text_tertiary + }.toColor() + ) + } + + labelIv.visibility = View.GONE + + // 转成Game实体比较好处理数据 + val trackGame = GameEntity( + id = rank.id, + mName = rank.name, + miniGameAppId = rank.link.link ?: "", + miniGameType = Constants.WECHAT_MINI_GAME, + usage = rank.usage ?: 0 + ) + holder.binding.playCount.visibility = View.VISIBLE + MiniGameItemHelper.setMiniGameUsage(holder.binding.playCount, trackGame) + holder.binding.playContainer.visibility = View.VISIBLE + + val onWechatMiniGameClick = OnClickListener { + MiniGameItemHelper.trackMiniGameClick(gameEntity = trackGame, location = "搜索榜单") + // 通过link启动微信小游戏 + DirectUtils.directToLinkPage( + mContext, + rank.link, + "小游戏搜索-搜索榜单", + "${mRankList.title}-${rank.name}", + rank.exposureEvent + ) + Util_System_Keyboard.hideSoftKeyboardByIBinder(mContext, it.windowToken) + } + holder.binding.playContainer.setOnClickListener(onWechatMiniGameClick) + holder.binding.root.setOnClickListener(onWechatMiniGameClick) + } + } + + inner class MiniGameSearchDefaultRankItemViewHolder(val binding: SearchDefaultRankItemBinding) : + BaseRecyclerViewHolder(binding.root) +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchDefaultRankListAdapter.kt b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchDefaultRankListAdapter.kt new file mode 100644 index 0000000000..0163cc0e56 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchDefaultRankListAdapter.kt @@ -0,0 +1,46 @@ +package com.gh.gamecenter.minigame + +import android.content.Context +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.gh.gamecenter.R +import com.gh.gamecenter.adapter.RecyclingPagerAdapter +import com.gh.gamecenter.common.utils.dip2px +import com.gh.gamecenter.feature.entity.SettingsEntity + +/** + * 微信小游戏-搜索榜单 + */ +class MiniGameSearchDefaultRankListAdapter( + private val mContext: Context, + private val mRankList: List, + private val mPageWidth: Float +) : RecyclingPagerAdapter() { + + override fun getCount() = mRankList.size + + override fun getPageWidth(position: Int) = mPageWidth + + override fun getPageTitle(position: Int) = mRankList[position].title + + override fun getView(position: Int, convertView: View?, container: ViewGroup?): View { + var view: View? = convertView + if (convertView == null) { + view = View.inflate(mContext, R.layout.search_default_rank_list_item, null).apply { + findViewById(R.id.rankContainer).apply { + setPadding(16F.dip2px(), 16F.dip2px(), 16F.dip2px(), 16F.dip2px()) + } + } + container?.layoutParams?.height = 432F.dip2px() + } + + view!!.findViewById(R.id.rankContainer).run { + layoutManager = LinearLayoutManager(mContext) + adapter = MiniGameSearchDefaultRankAdapter(mContext, mRankList[position]) + + } + return view + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/qgame/QGameSearchResultFragment.kt b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchResultFragment.kt similarity index 82% rename from app/src/main/java/com/gh/gamecenter/qgame/QGameSearchResultFragment.kt rename to app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchResultFragment.kt index 428074d4ef..c0709df703 100644 --- a/app/src/main/java/com/gh/gamecenter/qgame/QGameSearchResultFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchResultFragment.kt @@ -1,4 +1,4 @@ -package com.gh.gamecenter.qgame +package com.gh.gamecenter.minigame import com.gh.gamecenter.SearchActivity.Companion.TRACK_SEARCH_TYPE_INPUT import com.gh.gamecenter.common.constant.EntranceConsts @@ -8,9 +8,9 @@ import com.gh.gamecenter.search.SearchGameResultViewModel import com.halo.assistant.HaloApp /** - * QQ小游戏-搜索结果页面 + * 小游戏-搜索结果页面 */ -class QGameSearchResultFragment : SearchGameResultFragment() { +class MiniGameSearchResultFragment : SearchGameResultFragment() { /** * 仅替换搜索游戏的API,搜索结果页面样式与首页的完全一致 @@ -20,7 +20,7 @@ class QGameSearchResultFragment : SearchGameResultFragment() { HaloApp.getInstance().application, mKey, true, - QGameSearchResultRepository(), + MiniGameSearchResultRepository(), TRACK_SEARCH_TYPE_INPUT, activity?.intent?.getStringExtra(EntranceConsts.KEY_SOURCE_ENTRANCE) ?: "" ) diff --git a/app/src/main/java/com/gh/gamecenter/qgame/QGameSearchResultRepository.kt b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchResultRepository.kt similarity index 62% rename from app/src/main/java/com/gh/gamecenter/qgame/QGameSearchResultRepository.kt rename to app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchResultRepository.kt index 59c29f5936..115fd2cedd 100644 --- a/app/src/main/java/com/gh/gamecenter/qgame/QGameSearchResultRepository.kt +++ b/app/src/main/java/com/gh/gamecenter/minigame/MiniGameSearchResultRepository.kt @@ -1,6 +1,5 @@ -package com.gh.gamecenter.qgame +package com.gh.gamecenter.minigame -import com.gh.gamecenter.common.utils.EnvHelper import com.gh.gamecenter.entity.SearchSubjectEntity import com.gh.gamecenter.feature.entity.GameEntity import com.gh.gamecenter.retrofit.RetrofitManager @@ -9,7 +8,7 @@ import com.gh.gamecenter.search.ISearchGameResultRepository import io.reactivex.Observable import java.net.URLEncoder -class QGameSearchResultRepository( +class MiniGameSearchResultRepository( private val api: ApiService = RetrofitManager.getInstance().newApi ) : ISearchGameResultRepository { @@ -17,12 +16,7 @@ class QGameSearchResultRepository( key: String?, page: Int ): Observable> { - // 可能会有特殊字符,需要 encode 处理 - val encodedKey = URLEncoder.encode(key, "utf-8") - return api.getSearchQGame( - EnvHelper.getNewHost() + "games/qq_mini/columns/game_search?keyword=" + - encodedKey + "&page=" + page + "&page_size=20" - ) + return api.getSearchMiniGameList(key, page, 20) } override fun getSearchSubject(key: String?, page: Int): Observable> { diff --git a/app/src/main/java/com/gh/gamecenter/qgame/QGameFragment.kt b/app/src/main/java/com/gh/gamecenter/minigame/qq/QGameFragment.kt similarity index 81% rename from app/src/main/java/com/gh/gamecenter/qgame/QGameFragment.kt rename to app/src/main/java/com/gh/gamecenter/minigame/qq/QGameFragment.kt index 443f742c2b..be81562416 100644 --- a/app/src/main/java/com/gh/gamecenter/qgame/QGameFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/minigame/qq/QGameFragment.kt @@ -1,4 +1,4 @@ -package com.gh.gamecenter.qgame +package com.gh.gamecenter.minigame.qq import com.gh.gamecenter.common.utils.viewModelProvider import com.gh.gamecenter.entity.SubjectRecommendEntity @@ -6,7 +6,7 @@ import com.gh.gamecenter.game.GameFragment import com.halo.assistant.HaloApp /** - * QQ小游戏-专题页面 + * QQ小游戏-主页 */ class QGameFragment : GameFragment() { @@ -16,7 +16,7 @@ class QGameFragment : GameFragment() { override fun provideViewModel(): QGameViewModel { val factory = QGameViewModel.Factory( HaloApp.getInstance().application, - SubjectRecommendEntity(text = "QQ小游戏") + SubjectRecommendEntity(text = "小游戏") ) return viewModelProvider(factory) } diff --git a/app/src/main/java/com/gh/gamecenter/qgame/QGameHomeWrapperActivity.kt b/app/src/main/java/com/gh/gamecenter/minigame/qq/QGameHomeWrapperActivity.kt similarity index 94% rename from app/src/main/java/com/gh/gamecenter/qgame/QGameHomeWrapperActivity.kt rename to app/src/main/java/com/gh/gamecenter/minigame/qq/QGameHomeWrapperActivity.kt index fb01636902..323377905c 100644 --- a/app/src/main/java/com/gh/gamecenter/qgame/QGameHomeWrapperActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/minigame/qq/QGameHomeWrapperActivity.kt @@ -1,4 +1,4 @@ -package com.gh.gamecenter.qgame +package com.gh.gamecenter.minigame.qq import android.content.Context import android.content.Intent @@ -8,7 +8,7 @@ import com.gh.gamecenter.common.base.activity.ToolBarActivity import com.gh.gamecenter.common.utils.updateStatusBarColor /** - * QQ小游戏-首页 + * 小游戏-主页 */ class QGameHomeWrapperActivity : ToolBarActivity() { diff --git a/app/src/main/java/com/gh/gamecenter/qgame/QGameHomeWrapperFragment.kt b/app/src/main/java/com/gh/gamecenter/minigame/qq/QGameHomeWrapperFragment.kt similarity index 78% rename from app/src/main/java/com/gh/gamecenter/qgame/QGameHomeWrapperFragment.kt rename to app/src/main/java/com/gh/gamecenter/minigame/qq/QGameHomeWrapperFragment.kt index 28bbaab85f..7b44427729 100644 --- a/app/src/main/java/com/gh/gamecenter/qgame/QGameHomeWrapperFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/minigame/qq/QGameHomeWrapperFragment.kt @@ -1,11 +1,9 @@ -package com.gh.gamecenter.qgame +package com.gh.gamecenter.minigame.qq import android.os.Bundle import android.view.View import com.gh.common.util.DirectUtils import com.gh.gamecenter.R -import com.gh.gamecenter.SearchActivity -import com.gh.gamecenter.SearchType import com.gh.gamecenter.common.base.fragment.ToolbarFragment import com.gh.gamecenter.databinding.FragmentQgameHomeBinding @@ -15,7 +13,7 @@ class QGameHomeWrapperFragment : ToolbarFragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setNavigationTitle(getString(R.string.qgame_title)) + setNavigationTitle(getString(R.string.mini_game_title)) val contentFragment = childFragmentManager.findFragmentById(R.id.wrapper_content) ?: QGameFragment() childFragmentManager.beginTransaction().replace(R.id.wrapper_content, contentFragment).commitAllowingStateLoss() } @@ -26,7 +24,7 @@ class QGameHomeWrapperFragment : ToolbarFragment() { override fun initView(view: View?) { super.initView(view) viewBinding.searchBar.root.setOnClickListener { - DirectUtils.directToQGameSearch(it.context, "请输入小游戏关键词", "QQ小游戏") + DirectUtils.directToMiniGameSearch(it.context, "请输入小游戏关键词", "小游戏") } } diff --git a/app/src/main/java/com/gh/gamecenter/qgame/QGameHorizontalSlideListViewHolder.kt b/app/src/main/java/com/gh/gamecenter/minigame/qq/QGameRecentlyPlayViewHolder.kt similarity index 61% rename from app/src/main/java/com/gh/gamecenter/qgame/QGameHorizontalSlideListViewHolder.kt rename to app/src/main/java/com/gh/gamecenter/minigame/qq/QGameRecentlyPlayViewHolder.kt index 1afa66da20..f525f6fabe 100644 --- a/app/src/main/java/com/gh/gamecenter/qgame/QGameHorizontalSlideListViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/minigame/qq/QGameRecentlyPlayViewHolder.kt @@ -1,32 +1,20 @@ -package com.gh.gamecenter.qgame +package com.gh.gamecenter.minigame.qq -import android.content.Context -import android.os.Build import android.view.View -import android.view.ViewGroup import android.view.ViewGroup.MarginLayoutParams import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView.OnScrollListener -import com.gh.common.util.DirectUtils -import com.gh.common.util.DownloadItemUtils -import com.gh.common.util.NewFlatLogUtils import com.gh.gamecenter.R -import com.gh.gamecenter.common.base.GlobalActivityManager -import com.gh.gamecenter.common.baselist.DiffUtilAdapter import com.gh.gamecenter.common.utils.dip2px -import com.gh.gamecenter.common.utils.toBinding -import com.gh.gamecenter.common.utils.visibleIf import com.gh.gamecenter.common.view.GridSpacingItemColorDecoration import com.gh.gamecenter.databinding.ItemHomeRecentVgameBinding -import com.gh.gamecenter.databinding.ItemHomeVgameBinding import com.gh.gamecenter.entity.SubjectEntity -import com.gh.gamecenter.feature.entity.GameEntity +import com.gh.gamecenter.minigame.MiniGameRecentlyPlayListAdapter -class QGameHorizontalSlideListViewHolder(var binding: ItemHomeRecentVgameBinding) : - RecyclerView.ViewHolder(binding.root) { +class QGameRecentlyPlayViewHolder(var binding: ItemHomeRecentVgameBinding) : RecyclerView.ViewHolder(binding.root) { - fun bindHorizontalSlideList(subject: SubjectEntity) { + fun bindView(subject: SubjectEntity) { binding.vspaceIv.visibility = View.GONE binding.divider.visibility = View.GONE @@ -76,7 +64,7 @@ class QGameHorizontalSlideListViewHolder(var binding: ItemHomeRecentVgameBinding binding.recyclerView.layoutManager = layoutManager binding.recyclerView.itemAnimator = null - val adapter = QGameHorizontalSlideAdapter(binding.root.context) + val adapter = MiniGameRecentlyPlayListAdapter(binding.root.context) binding.recyclerView.adapter = adapter binding.recyclerView.addItemDecoration( GridSpacingItemColorDecoration(binding.root.context, 4, 0, R.color.transparent) @@ -111,58 +99,11 @@ class QGameHorizontalSlideListViewHolder(var binding: ItemHomeRecentVgameBinding }) adapter } else { - binding.recyclerView.adapter as QGameHorizontalSlideAdapter + binding.recyclerView.adapter as MiniGameRecentlyPlayListAdapter } subjectAdapter.submitList(subject.data) } } -class QGameHorizontalSlideAdapter(context: Context) : DiffUtilAdapter(context) { - override fun onCreateViewHolder( - parent: ViewGroup, - viewType: Int - ): QGameHorizontalSlideViewHolder { - return QGameHorizontalSlideViewHolder(parent.toBinding()) - } - - override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - (holder as QGameHorizontalSlideViewHolder).bindView(mDataList[position]) - } - - override fun getItemCount(): Int { - return mDataList.size - } - - override fun areItemsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean { - return oldItem == newItem - } - - override fun areContentsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean { - return oldItem == newItem - } - - class QGameHorizontalSlideViewHolder(private var mBinding: ItemHomeVgameBinding) : - RecyclerView.ViewHolder(mBinding.root) { - - fun bindView(entity: GameEntity) { - mBinding.gameIconIv.displayGameIcon(entity) - - mBinding.maskView.visibility = View.GONE - mBinding.controlTv.visibility = View.GONE - mBinding.progressBar.visibility = View.GONE - mBinding.dotView.visibility = View.GONE - mBinding.updateHintIv.visibility = View.GONE - mBinding.controlTv.visibility = View.GONE - mBinding.progressBar.visibility = View.GONE - - mBinding.root.setOnClickListener { - NewFlatLogUtils.logQGameClick(entity.qqMiniGameAppId, entity.name) - GlobalActivityManager.currentActivity?.let { - DirectUtils.directToQGameById(it, entity.qqMiniGameAppId) - } - } - } - } -} diff --git a/app/src/main/java/com/gh/gamecenter/qgame/QGameSubjectListRepository.kt b/app/src/main/java/com/gh/gamecenter/minigame/qq/QGameSubjectListRepository.kt similarity index 67% rename from app/src/main/java/com/gh/gamecenter/qgame/QGameSubjectListRepository.kt rename to app/src/main/java/com/gh/gamecenter/minigame/qq/QGameSubjectListRepository.kt index d1bcbb4eb6..89ae631019 100644 --- a/app/src/main/java/com/gh/gamecenter/qgame/QGameSubjectListRepository.kt +++ b/app/src/main/java/com/gh/gamecenter/minigame/qq/QGameSubjectListRepository.kt @@ -1,9 +1,11 @@ -package com.gh.gamecenter.qgame +package com.gh.gamecenter.minigame.qq +import com.gh.gamecenter.entity.SubjectSettingEntity import com.gh.gamecenter.feature.entity.GameEntity import com.gh.gamecenter.retrofit.RetrofitManager import com.gh.gamecenter.retrofit.service.ApiService import com.gh.gamecenter.subject.ISubjectListRepository +import io.reactivex.Observable import io.reactivex.Single class QGameSubjectListRepository( @@ -14,4 +16,8 @@ class QGameSubjectListRepository( return api.getQGameColumn(column_id, order, page, 20) } + override fun getColumnSettings(column_id: String?): Observable { + return api.getQGameColumnSettings(column_id) + } + } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/qgame/QGameSubjectRepository.kt b/app/src/main/java/com/gh/gamecenter/minigame/qq/QGameSubjectRepository.kt similarity index 90% rename from app/src/main/java/com/gh/gamecenter/qgame/QGameSubjectRepository.kt rename to app/src/main/java/com/gh/gamecenter/minigame/qq/QGameSubjectRepository.kt index 237c4db8a2..83c183ba7e 100644 --- a/app/src/main/java/com/gh/gamecenter/qgame/QGameSubjectRepository.kt +++ b/app/src/main/java/com/gh/gamecenter/minigame/qq/QGameSubjectRepository.kt @@ -1,6 +1,5 @@ -package com.gh.gamecenter.qgame +package com.gh.gamecenter.minigame.qq -import androidx.lifecycle.viewmodel.viewModelFactory import com.gh.gamecenter.entity.SubjectSettingEntity import com.gh.gamecenter.retrofit.RetrofitManager import com.gh.gamecenter.retrofit.service.ApiService @@ -15,7 +14,6 @@ class QGameSubjectRepository( override fun getColumnSettings(column_id: String?): Observable { return api.getQGameColumnSettings(column_id) - } override fun getSubjectName(column_id: String?): Observable { diff --git a/app/src/main/java/com/gh/gamecenter/minigame/qq/QGameSubjectUpdateEvent.kt b/app/src/main/java/com/gh/gamecenter/minigame/qq/QGameSubjectUpdateEvent.kt new file mode 100644 index 0000000000..53297f1bcf --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/minigame/qq/QGameSubjectUpdateEvent.kt @@ -0,0 +1,4 @@ +package com.gh.gamecenter.minigame.qq + +class QGameSubjectUpdateEvent { +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/qgame/QGameViewModel.kt b/app/src/main/java/com/gh/gamecenter/minigame/qq/QGameViewModel.kt similarity index 97% rename from app/src/main/java/com/gh/gamecenter/qgame/QGameViewModel.kt rename to app/src/main/java/com/gh/gamecenter/minigame/qq/QGameViewModel.kt index 5863c6dfb1..d0af8c10fc 100644 --- a/app/src/main/java/com/gh/gamecenter/qgame/QGameViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/minigame/qq/QGameViewModel.kt @@ -1,8 +1,9 @@ -package com.gh.gamecenter.qgame +package com.gh.gamecenter.minigame.qq import android.app.Application import android.text.TextUtils import androidx.collection.ArrayMap +import androidx.lifecycle.Observer import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import com.gh.common.filter.RegionSettingHelper @@ -23,13 +24,11 @@ import com.gh.gamecenter.game.data.GameItemData import com.gh.gamecenter.game.rank.RankCollectionAdapter import com.gh.gamecenter.home.BlankDividerViewHolder import com.gh.gamecenter.home.LegacyHomeFragmentAdapterAssistant +import com.gh.gamecenter.minigame.MiniGameRecentlyPlayUseCase import com.gh.gamecenter.retrofit.RetrofitManager import com.lightgame.utils.Utils import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers -import org.greenrobot.eventbus.EventBus -import org.greenrobot.eventbus.Subscribe -import org.greenrobot.eventbus.ThreadMode import retrofit2.HttpException import kotlin.math.roundToInt @@ -47,9 +46,15 @@ class QGameViewModel(application: Application, blockData: SubjectRecommendEntity private var mIsLoading = false + private val mQGameRecentlyPlayObserver = Observer> { + onInitData() + } + init { initData() - EventBus.getDefault().register(this)// 为了减少对原有逻辑的影响,把EventBus注册在这里 + MiniGameRecentlyPlayUseCase + .qqRecentGamesItemLiveData + .observeForever(mQGameRecentlyPlayObserver) } override fun onInitData() { @@ -528,12 +533,9 @@ class QGameViewModel(application: Application, blockData: SubjectRecommendEntity override fun onCleared() { super.onCleared() - EventBus.getDefault().unregister(this) - } - - @Subscribe(threadMode = ThreadMode.MAIN) - fun onQGameSubjectUpdate(event: QGameSubjectUpdateEvent) { - onInitData() + MiniGameRecentlyPlayUseCase + .qqRecentGamesItemLiveData + .removeObserver(mQGameRecentlyPlayObserver) } override fun replaceRefreshData(itemData: GameItemData): Boolean = false @@ -548,11 +550,4 @@ class QGameViewModel(application: Application, blockData: SubjectRecommendEntity return QGameViewModel(mApplication, blockData) as T } } - - companion object { - - fun notifyQGameSubjectUpdate() { - EventBus.getDefault().post(QGameSubjectUpdateEvent()) - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/minigame/wechat/WGameSubjectListRepository.kt b/app/src/main/java/com/gh/gamecenter/minigame/wechat/WGameSubjectListRepository.kt new file mode 100644 index 0000000000..8a7362d5f0 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/minigame/wechat/WGameSubjectListRepository.kt @@ -0,0 +1,23 @@ +package com.gh.gamecenter.minigame.wechat + +import com.gh.gamecenter.entity.SubjectSettingEntity +import com.gh.gamecenter.feature.entity.GameEntity +import com.gh.gamecenter.retrofit.RetrofitManager +import com.gh.gamecenter.retrofit.service.ApiService +import com.gh.gamecenter.subject.ISubjectListRepository +import io.reactivex.Observable +import io.reactivex.Single + +class WGameSubjectListRepository( + private val api: ApiService = RetrofitManager.getInstance().newApi +) : ISubjectListRepository { + + override fun getColumn(column_id: String?, page: Int, sort: String?, order: String?): Single> { + return api.getWGameColumn(column_id, order, page, 20) + } + + override fun getColumnSettings(column_id: String?): Observable { + return api.getWGameColumnSettings(column_id) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/minigame/wechat/WGameSubjectRepository.kt b/app/src/main/java/com/gh/gamecenter/minigame/wechat/WGameSubjectRepository.kt new file mode 100644 index 0000000000..e98932d611 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/minigame/wechat/WGameSubjectRepository.kt @@ -0,0 +1,21 @@ +package com.gh.gamecenter.minigame.wechat + +import com.gh.gamecenter.entity.SubjectSettingEntity +import com.gh.gamecenter.retrofit.RetrofitManager +import com.gh.gamecenter.retrofit.service.ApiService +import com.gh.gamecenter.subject.ISubjectRepository +import io.reactivex.Observable +import okhttp3.MediaType +import okhttp3.ResponseBody + +class WGameSubjectRepository( + private val api: ApiService = RetrofitManager.getInstance().newApi +) : ISubjectRepository { + override fun getColumnSettings(column_id: String?): Observable { + return api.getWGameColumnSettings(column_id) + } + + override fun getSubjectName(column_id: String?): Observable { + return Observable.just(ResponseBody.create(MediaType.parse("application/json"), "{\"name\": \"专题\"}")) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/qgame/QGameSubjectUpdateEvent.kt b/app/src/main/java/com/gh/gamecenter/qgame/QGameSubjectUpdateEvent.kt deleted file mode 100644 index d17f5c89d3..0000000000 --- a/app/src/main/java/com/gh/gamecenter/qgame/QGameSubjectUpdateEvent.kt +++ /dev/null @@ -1,4 +0,0 @@ -package com.gh.gamecenter.qgame - -class QGameSubjectUpdateEvent { -} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java index 1adb304417..2ebc240071 100644 --- a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java +++ b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java @@ -3144,6 +3144,20 @@ public interface ApiService { @GET("blocks/{block_id}/tabs") Single> getBlockTab(@Path("block_id") String blockId); + /** + * QQ/微信小游戏-搜索 + */ + @GET("mini_game/search") + Observable> getSearchMiniGameList(@Query("keyword") String keyword, + @Query("page") int page, + @Query("page_size") int pageSize); + + /** + * QQ/微信小游戏-最近在玩 + */ + @GET("mini_game/recently_played/{game_type}") + Single> getRecentPlayedMiniGameList(@Path("game_type") String gameType); + /** * QQ小游戏-专题列表 */ @@ -3165,12 +3179,6 @@ public interface ApiService { @Query("page") int page, @Query("page_size") int pageSize); - /** - * QQ小游戏-搜索 - */ - @GET - Observable> getSearchQGame(@Url String url); - /** * QQ小游戏-游玩记录 */ @@ -3183,6 +3191,33 @@ public interface ApiService { @GET("/games/qq_mini/columns/{column_id}/setting") Observable getQGameColumnSettings(@Path("column_id") String column_id); + /** + * 微信小游戏-专题数据详情 + */ + @GET("/wechat_game/columns/{column_id}/setting") + Observable getWGameColumnSettings(@Path("column_id") String column_id); + + /** + * 微信小游戏-专题-换一换 + */ + @GET("wechat_game/columns/{column_id}/games?page=1&page_size=30") + Observable> getSubjectWGame(@Path("column_id") String columnId); + + /** + * 微信小游戏-专题游戏列表 + */ + @GET("wechat_game/columns/{column_id}/games") + Single> getWGameColumn(@Path("column_id") String columnId, + @Query("filter") String order, + @Query("page") int page, + @Query("page_size") int pageSize); + + /** + * 微信小游戏-游玩记录 + */ + @POST("/wechat_game/{appid}/user/{gid}") + Single postWGamePlay(@Path("appid") String wechatGameId, @Path("gid") String gid); + /** * 获取广告配置 */ diff --git a/app/src/main/java/com/gh/gamecenter/search/SearchDefaultFragment.kt b/app/src/main/java/com/gh/gamecenter/search/SearchDefaultFragment.kt index 8b23b27dac..341bdbf517 100644 --- a/app/src/main/java/com/gh/gamecenter/search/SearchDefaultFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/search/SearchDefaultFragment.kt @@ -14,6 +14,7 @@ import android.widget.CheckedTextView import android.widget.TextView import androidx.appcompat.content.res.AppCompatResources import androidx.constraintlayout.widget.ConstraintLayout +import androidx.viewpager.widget.PagerAdapter import com.gh.common.constant.Config import com.gh.common.exposure.ExposureManager import com.gh.common.filter.RegionSettingHelper @@ -30,6 +31,7 @@ import com.gh.gamecenter.core.utils.PageSwitchDataHelper import com.gh.gamecenter.core.utils.StringUtils import com.gh.gamecenter.databinding.FragmentSearchDefaultBinding import com.gh.gamecenter.databinding.TabItemSearchDefaultRankBinding +import com.gh.gamecenter.db.ISearchHistoryDao import com.gh.gamecenter.db.SearchHistoryDao import com.gh.gamecenter.eventbus.EBSearch import com.gh.gamecenter.feature.entity.HotTagEntity @@ -45,13 +47,10 @@ import org.json.JSONObject open class SearchDefaultFragment : BaseFragment() { private var mHotTagList: List? = null - protected var mHistoryList: List? = null protected var mRankList: List? = null protected lateinit var mBinding: FragmentSearchDefaultBinding - private var mSearchHistoryDao: SearchHistoryDao? = null - private var mViewModel: SearchDefaultViewModel? = null private var mIsGameSearch = false // 是否为游戏搜索 @@ -95,20 +94,19 @@ open class SearchDefaultFragment : BaseFragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - mViewModel = viewModelProvider() + mViewModel = provideViewModel() mIsGameSearch = arguments?.getBoolean(KEY_IS_GAME_SEARCH) ?: false mSourceEntrance = arguments?.getString(EntranceConsts.KEY_SOURCE_ENTRANCE) ?: "" - initDao() + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) initView() } - open fun initDao() { - mSearchHistoryDao = SearchHistoryDao(context) - } - - open fun initView() { + protected open fun initView() { mBinding = FragmentSearchDefaultBinding.bind(mCachedView) mRankList = Config.getSettings()?.search?.rankList?.apply { forEachIndexed { outIndex, rankList -> @@ -143,7 +141,7 @@ open class SearchDefaultFragment : BaseFragment() { mViewModel?.isExistHotTag = mHotTagList?.isNotEmpty() == true updateHistorySearchView(null) - mViewModel?.historySearchLiveData?.observe(this) { + mViewModel?.historySearchLiveData?.observe(viewLifecycleOwner) { updateHistorySearchView(it) } @@ -153,7 +151,7 @@ open class SearchDefaultFragment : BaseFragment() { initRankViewPager() } - private fun initHeadView() { + protected open fun initHeadView() { mBinding.historyHeadContainer.run { headTitle.text = getString(R.string.search_history) headTitle.textSize = 16F @@ -166,11 +164,15 @@ open class SearchDefaultFragment : BaseFragment() { ) ) headActionTv.setOnClickListener { - DialogHelper.showCenterWarningDialog(requireContext(), "清空记录", "确定清空历史搜索记录?", confirmClickCallback = { - mSearchHistoryDao?.deleteAll() - mViewModel?.isExistHistory = false - updateView() - }) + DialogHelper.showCenterWarningDialog( + requireContext(), + "清空记录", + "确定清空历史搜索记录?", + confirmClickCallback = { + mViewModel?.deleteAll() + mViewModel?.isExistHistory = false + updateView() + }) } } mBinding.hotHeadContainer.headTitle.text = getString(R.string.search_hot) @@ -181,7 +183,7 @@ open class SearchDefaultFragment : BaseFragment() { mBinding.hotTagHeadContainer.headActionTv.visibility = View.GONE } - fun initRankViewPager() { + protected open fun initRankViewPager() { mRankList = mRankList?.filter { it.content.isNotEmpty() }?.take(6) if (mRankList.isNullOrEmpty()) return @@ -204,7 +206,7 @@ open class SearchDefaultFragment : BaseFragment() { visibility = View.VISIBLE offscreenPageLimit = mRankList!!.size pageMargin = 12F.dip2px() - adapter = SearchDefaultRankListAdapter(requireContext(), mRankList!!, pageRatio, mIsGameSearch, mSourceEntrance) + adapter = provideAdapter(pageRatio) postExposureEvent(0) doOnPageSelected { postExposureEvent(it) @@ -342,14 +344,14 @@ open class SearchDefaultFragment : BaseFragment() { mBinding.rankViewPager.visibility = if (mViewModel?.isExistRankList == true) View.VISIBLE else View.GONE } - private fun updateHistorySearchView(historyList: List?) { + protected open fun updateHistorySearchView(historyList: List?) { mViewModel?.isExistHistory = historyList?.isNotEmpty() == true updateView() if (historyList != null) { mBinding.historyFlexContainer.setLimitHeight(DisplayUtils.dip2px(88F)) createFlexContent(mBinding.historyFlex, historyList, clickListener = { val key = historyList[it] - mSearchHistoryDao?.add(key) + mViewModel?.add(key) EventBus.getDefault().post(EBSearch("history", key)) Util_System_Keyboard.hideSoftKeyboardByIBinder(context, mBinding.historyFlex.windowToken) }) @@ -449,6 +451,16 @@ open class SearchDefaultFragment : BaseFragment() { createFlexContent(mBinding.hotTagFlex, getTagListString(), true, clickListener = mHotTagClickListener) } + protected open fun provideDao(): ISearchHistoryDao = SearchHistoryDao(requireContext().applicationContext) + + protected open fun provideAdapter(pageRatio: Float): PagerAdapter = + SearchDefaultRankListAdapter(requireContext(), mRankList!!, pageRatio, mIsGameSearch, mSourceEntrance) + + private fun provideViewModel(): SearchDefaultViewModel { + val factory = SearchDefaultViewModel.Factory(provideDao()) + return viewModelProvider(factory) + } + companion object { const val KEY_IS_GAME_SEARCH = "key_is_game_search" } diff --git a/app/src/main/java/com/gh/gamecenter/search/SearchDefaultViewModel.kt b/app/src/main/java/com/gh/gamecenter/search/SearchDefaultViewModel.kt index 02e88ace12..2afca76427 100644 --- a/app/src/main/java/com/gh/gamecenter/search/SearchDefaultViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/search/SearchDefaultViewModel.kt @@ -1,12 +1,12 @@ package com.gh.gamecenter.search -import android.app.Application -import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider import com.gh.gamecenter.core.runOnIoThread -import com.gh.gamecenter.db.SearchHistoryDao +import com.gh.gamecenter.db.ISearchHistoryDao -class SearchDefaultViewModel(application: Application) : AndroidViewModel(application) { +class SearchDefaultViewModel(private val dao: ISearchHistoryDao) : ViewModel() { val historySearchLiveData = MutableLiveData>() var isExistHotSearch: Boolean = false @@ -16,7 +16,32 @@ class SearchDefaultViewModel(application: Application) : AndroidViewModel(applic init { runOnIoThread { - historySearchLiveData.postValue(SearchHistoryDao(application).all) + historySearchLiveData.postValue(dao.all) + } + } + + fun deleteAll() { + dao.deleteAll() + historySearchLiveData.postValue(emptyList()) + } + + fun add(item: String) { + val oldList = historySearchLiveData.value + if (oldList.isNullOrEmpty()) { + dao.add(item) + historySearchLiveData.postValue(listOf(item)) + return + } + + if (!oldList.contains(item)) { + dao.add(item) + historySearchLiveData.postValue(oldList + item) + } + } + + class Factory(private val dao: ISearchHistoryDao) : ViewModelProvider.NewInstanceFactory() { + override fun create(modelClass: Class): T { + return SearchDefaultViewModel(dao) as T } } diff --git a/app/src/main/java/com/gh/gamecenter/search/SearchGameIndexAdapter.kt b/app/src/main/java/com/gh/gamecenter/search/SearchGameIndexAdapter.kt index e3d050aa3d..eb3fd30689 100644 --- a/app/src/main/java/com/gh/gamecenter/search/SearchGameIndexAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/search/SearchGameIndexAdapter.kt @@ -40,6 +40,7 @@ import com.gh.gamecenter.eventbus.EBSearch 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.feature.minigame.MiniGameItemHelper import com.gh.gamecenter.gamedetail.GameDetailFragment import com.lightgame.download.DownloadEntity import com.lightgame.utils.Util_System_Keyboard @@ -158,6 +159,7 @@ class SearchGameIndexAdapter( gameEntity.adIconActive, adLabelTv ) + MiniGameItemHelper.setMiniGameUsage(gamePlayCount, gameEntity) } binding.topDivider.goneIf(position == 0) binding.gameItemIncluded.root.setPadding( diff --git a/app/src/main/java/com/gh/gamecenter/search/SearchGameIndexItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/search/SearchGameIndexItemViewHolder.kt index e17c96ad65..221d8a1f53 100644 --- a/app/src/main/java/com/gh/gamecenter/search/SearchGameIndexItemViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/search/SearchGameIndexItemViewHolder.kt @@ -110,7 +110,7 @@ class SearchSubjectItemViewHolder(var binding: SearchSubjectItemBinding) : Recyc ) } - if (!it.isQQMiniGame()) { + if (!it.isMiniGame()) { SensorsBridge.trackColumnClick( location = "游戏搜索", gameColumnId = entity.columnId, diff --git a/app/src/main/java/com/gh/gamecenter/search/SearchGameResultAdapter.kt b/app/src/main/java/com/gh/gamecenter/search/SearchGameResultAdapter.kt index 53357cfa58..38424c001e 100644 --- a/app/src/main/java/com/gh/gamecenter/search/SearchGameResultAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/search/SearchGameResultAdapter.kt @@ -43,6 +43,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.feature.minigame.MiniGameItemHelper import com.gh.gamecenter.gamedetail.GameDetailFragment import com.gh.gamecenter.help.HelpAndFeedbackBridge import com.lightgame.download.DownloadEntity @@ -310,6 +311,7 @@ class SearchGameResultAdapter( gameEntity.adIconActive, adLabelTv ) + MiniGameItemHelper.setMiniGameUsage(gamePlayCount, gameEntity) } binding.gameItemIncluded.root.setPadding(16F.dip2px(), 16F.dip2px(), 16F.dip2px(), 16F.dip2px()) SearchGameIndexItemViewHolder.initServerType(gameEntity, binding.gameItemIncluded) @@ -685,15 +687,12 @@ class SearchGameResultAdapter( EventBus.getDefault().post(EBSearch("click", gameEntity.id, gameEntity.name)) } - if (gameEntity.isQQMiniGame()) { - GlobalActivityManager.currentActivity?.let { - DirectUtils.directToQGameById(it, gameEntity.qqMiniGameAppId) - } - SensorsBridge.trackQQGameClick( - location = "QQ小游戏搜索结果列表", + if (gameEntity.isMiniGame()) { + MiniGameItemHelper.launchMiniGame(gameEntity.miniGameAppId, gameEntity.miniGameType) + MiniGameItemHelper.trackMiniGameClick( + gameEntity = gameEntity, + location = "小游戏搜索结果列表", searchContent = key, - gameId = gameEntity.id, - gameName = gameEntity.name ?: "" ) } else { GameDetailActivity.startGameDetailActivity( @@ -791,6 +790,13 @@ class SearchGameResultAdapter( gameEntity.name ?: "" ) } + if (gameEntity.isMiniGame()) { + MiniGameItemHelper.trackMiniGameClick( + gameEntity = gameEntity, + location = "小游戏搜索结果列表", + searchContent = key, + ) + } }, refreshCallback = null ) { diff --git a/app/src/main/java/com/gh/gamecenter/subject/AdSubjectListFragment.kt b/app/src/main/java/com/gh/gamecenter/subject/AdSubjectListFragment.kt index 3496c4a176..f1c0f62af2 100644 --- a/app/src/main/java/com/gh/gamecenter/subject/AdSubjectListFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/subject/AdSubjectListFragment.kt @@ -5,15 +5,30 @@ import com.gh.gamecenter.R import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.viewModelProvider import com.gh.gamecenter.entity.SubjectData +import com.gh.gamecenter.feature.entity.PageLocation class AdSubjectListFragment : SubjectListFragment() { private var mSubjectData: SubjectData? = null - override fun provideListViewModel(): SubjectListViewModel = viewModelProvider( - AdSubjectListViewModel.Factory( - mSubjectData!!, - arguments?.getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST) + override fun provideListViewModel(): SubjectListViewModel { + val bottomTabName = arguments?.getString(EntranceConsts.KEY_BOTTOM_TAB_NAME, "") ?: "" + val tabIndex = arguments?.getInt(EntranceConsts.KEY_TAB_INDEX, -1) ?: -1 + val tabName = arguments?.getString(EntranceConsts.KEY_TAB_NAME, "") ?: "" + val multiTabNavId = arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_ID, "") ?: "" + val multiTabNavName = arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_NAME, "") ?: "" + return viewModelProvider( + AdSubjectListViewModel.Factory( + mSubjectData!!, + PageLocation( + bottomTab = bottomTabName, + severalTabPageId = multiTabNavId, + severalTabPageName = multiTabNavName, + tabPosition = tabIndex, + tabContent = tabName + ), + arguments?.getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST) + ) ) - ) + } override fun onCreate(savedInstanceState: Bundle?) { mSubjectData = arguments?.getParcelable(EntranceConsts.KEY_SUBJECT_DATA) diff --git a/app/src/main/java/com/gh/gamecenter/subject/AdSubjectListViewModel.kt b/app/src/main/java/com/gh/gamecenter/subject/AdSubjectListViewModel.kt index 44edf5a5f7..265d8df6d5 100644 --- a/app/src/main/java/com/gh/gamecenter/subject/AdSubjectListViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/subject/AdSubjectListViewModel.kt @@ -7,6 +7,7 @@ import com.gh.gamecenter.common.baselist.LoadParams import com.gh.gamecenter.common.exposure.ExposureSource import com.gh.gamecenter.entity.SubjectData import com.gh.gamecenter.feature.entity.GameEntity +import com.gh.gamecenter.feature.entity.PageLocation import com.gh.gamecenter.retrofit.RetrofitManager import com.halo.assistant.HaloApp import io.reactivex.Single @@ -14,9 +15,10 @@ import io.reactivex.Single class AdSubjectListViewModel( application: Application, private val mSubjectData: SubjectData, + pageLocation: PageLocation, exposureSourceList: List? = null ) : - SubjectListViewModel(application, mSubjectData, exposureSourceList) { + SubjectListViewModel(application, mSubjectData, pageLocation, exposureSourceList) { override fun provideDataSingle(page: Int): Single> = RetrofitManager.getInstance().newApi.getAdGames( mSubjectData.adId, @@ -34,10 +36,11 @@ class AdSubjectListViewModel( class Factory( private val mSubjectData: SubjectData, + private val mPageLocation: PageLocation, private val mExposureSourceList: List? = null ) : ViewModelProvider.NewInstanceFactory() { override fun create(modelClass: Class): T { - return AdSubjectListViewModel(HaloApp.getInstance(), mSubjectData, mExposureSourceList) as T + return AdSubjectListViewModel(HaloApp.getInstance(), mSubjectData, mPageLocation, mExposureSourceList) as T } } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/subject/ISubjectListRepository.kt b/app/src/main/java/com/gh/gamecenter/subject/ISubjectListRepository.kt index 3dfb916419..3543b097fc 100644 --- a/app/src/main/java/com/gh/gamecenter/subject/ISubjectListRepository.kt +++ b/app/src/main/java/com/gh/gamecenter/subject/ISubjectListRepository.kt @@ -1,6 +1,8 @@ package com.gh.gamecenter.subject +import com.gh.gamecenter.entity.SubjectSettingEntity import com.gh.gamecenter.feature.entity.GameEntity +import io.reactivex.Observable import io.reactivex.Single interface ISubjectListRepository { @@ -11,4 +13,6 @@ interface ISubjectListRepository { sort: String?, order: String?, ): Single> + + fun getColumnSettings(column_id: String?): Observable } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/subject/SubjectActivity.kt b/app/src/main/java/com/gh/gamecenter/subject/SubjectActivity.kt index a5456339a9..9d5d92502f 100644 --- a/app/src/main/java/com/gh/gamecenter/subject/SubjectActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/subject/SubjectActivity.kt @@ -70,13 +70,13 @@ open class SubjectActivity : DownloadToolbarActivity() { isOrder: Boolean, exposureSourceList: ArrayList? = null, entrance: String?, - isQQMiniGame: Boolean = false + subjectType: SubjectData.SubjectType = SubjectData.SubjectType.NORMAL ) { MtaHelper.onEvent("详情页面", "专题详情", name) val bundle = Bundle() bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance) - val subjectData = SubjectData(subjectId = id, subjectName = name, isOrder = isOrder, isQQMiniGame = isQQMiniGame) + val subjectData = SubjectData(subjectId = id, subjectName = name, isOrder = isOrder, subjectType = subjectType) bundle.putParcelable(EntranceConsts.KEY_SUBJECT_DATA, subjectData) bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance) if (exposureSourceList != null) { diff --git a/app/src/main/java/com/gh/gamecenter/subject/SubjectAdapter.kt b/app/src/main/java/com/gh/gamecenter/subject/SubjectAdapter.kt index 4113621eef..6032c3ce55 100644 --- a/app/src/main/java/com/gh/gamecenter/subject/SubjectAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/subject/SubjectAdapter.kt @@ -17,7 +17,6 @@ import com.gh.gamecenter.GameDetailActivity import com.gh.gamecenter.R import com.gh.gamecenter.adapter.viewholder.GameImageViewHolder import com.gh.gamecenter.adapter.viewholder.GameViewHolder -import com.gh.gamecenter.common.base.GlobalActivityManager import com.gh.gamecenter.common.baselist.ListAdapter import com.gh.gamecenter.common.constant.ItemViewType import com.gh.gamecenter.common.entity.LinkEntity @@ -33,6 +32,7 @@ import com.gh.gamecenter.feature.databinding.GameItemBinding import com.gh.gamecenter.feature.entity.GameEntity import com.gh.gamecenter.feature.exposure.ExposureEvent import com.gh.gamecenter.feature.game.GameItemViewHolder +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper import com.gh.gamecenter.home.custom.model.CustomPageItem import com.lightgame.download.DownloadEntity @@ -218,19 +218,22 @@ class SubjectAdapter( holder.itemView.setOnClickListener { DataCollectionUtils.uploadClick(mContext, "列表", subjectData.subjectName, gameEntity.name) - if (gameEntity.isQQMiniGame()) { - GlobalActivityManager.currentActivity?.let { - DirectUtils.directToQGameById(it, gameEntity.qqMiniGameAppId) - } - if (!mIsColumnCollection) { - SensorsBridge.trackQQGameClick( - location = "专题详情", - gameColumnId = subjectData.subjectId ?: "", - gameColumnName = subjectData.subjectName ?: "", - gameId = gameEntity.id, - gameName = gameEntity.name ?: "" - ) - } + if (gameEntity.isMiniGame()) { + MiniGameItemHelper.launchMiniGame(gameEntity.miniGameAppId, gameEntity.miniGameType) + val pageLocation = mViewModel.pageLocation + MiniGameItemHelper.trackMiniGameClick( + gameEntity = gameEntity, + location = "专题详情", + bottomTab = pageLocation.bottomTab, + multiTabId = pageLocation.severalTabPageId, + multiTabName = pageLocation.severalTabPageName, + position = pageLocation.tabPosition, + tabContent = pageLocation.tabContent, + gameColumnId = subjectData.subjectId ?: "", + gameColumnName = subjectData.subjectName ?: "", + columnPattern = CustomPageItem.collectionTypeToComponentName[mCollectionStyle] + ?: mCollectionStyle + ) } else { GameDetailActivity.startGameDetailActivity( mContext, @@ -317,6 +320,23 @@ class SubjectAdapter( text = "按钮" ) } + + if (gameEntity.isMiniGame() && !mIsColumnCollection) { + val pageLocation = mViewModel.pageLocation + MiniGameItemHelper.trackMiniGameClick( + gameEntity = gameEntity, + location = "专题详情", + bottomTab = pageLocation.bottomTab, + multiTabId = pageLocation.severalTabPageId, + multiTabName = pageLocation.severalTabPageName, + position = pageLocation.tabPosition, + tabContent = pageLocation.tabContent, + gameColumnId = subjectData.subjectId ?: "", + gameColumnName = subjectData.subjectName ?: "", + columnPattern = CustomPageItem.collectionTypeToComponentName[mCollectionStyle] + ?: mCollectionStyle + ) + } } ) diff --git a/app/src/main/java/com/gh/gamecenter/subject/SubjectListFragment.kt b/app/src/main/java/com/gh/gamecenter/subject/SubjectListFragment.kt index bdaa631ea8..1b0a08e73e 100644 --- a/app/src/main/java/com/gh/gamecenter/subject/SubjectListFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/subject/SubjectListFragment.kt @@ -14,6 +14,7 @@ import com.gh.gamecenter.common.baselist.LazyListFragment import com.gh.gamecenter.common.baselist.LoadType import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.constant.EntranceConsts +import com.gh.gamecenter.common.entity.LinkEntity import com.gh.gamecenter.common.utils.toColor import com.gh.gamecenter.common.utils.viewModelProviderFromParent import com.gh.gamecenter.common.view.SpacingItemDecoration @@ -23,6 +24,7 @@ import com.gh.gamecenter.entity.SubjectSettingEntity import com.gh.gamecenter.eventbus.EBDownloadStatus import com.gh.gamecenter.eventbus.EBPackage import com.gh.gamecenter.feature.entity.GameEntity +import com.gh.gamecenter.feature.entity.PageLocation import com.halo.assistant.HaloApp import com.lightgame.OnTitleClickListener import com.lightgame.download.DataWatcher @@ -86,9 +88,21 @@ open class SubjectListFragment : LazyListFragment> { return api.getColumn(column_id, sort, order, page) } + + override fun getColumnSettings(column_id: String?): Observable { + return api.getColumnSettings(column_id) + } + + } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/subject/SubjectListViewModel.kt b/app/src/main/java/com/gh/gamecenter/subject/SubjectListViewModel.kt index 582c3ddbaa..cce8963ff6 100644 --- a/app/src/main/java/com/gh/gamecenter/subject/SubjectListViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/subject/SubjectListViewModel.kt @@ -13,8 +13,8 @@ import com.gh.gamecenter.core.utils.TimeUtils import com.gh.gamecenter.entity.SubjectData import com.gh.gamecenter.entity.SubjectSettingEntity import com.gh.gamecenter.feature.entity.GameEntity +import com.gh.gamecenter.feature.entity.PageLocation import com.gh.gamecenter.feature.entity.TagStyleEntity -import com.gh.gamecenter.qgame.QGameSubjectListRepository import com.gh.gamecenter.retrofit.RetrofitManager import io.reactivex.Observable import io.reactivex.Single @@ -25,6 +25,7 @@ import retrofit2.HttpException open class SubjectListViewModel( application: Application, var subjectData: SubjectData, + var pageLocation: PageLocation, var exposureSourceList: List? ) : ListViewModel(application) { @@ -34,7 +35,7 @@ open class SubjectListViewModel( var lastPageDataMap: HashMap? = null - private val repository = if (subjectData.isQQMiniGame) QGameSubjectListRepository() else SubjectListRepository() + private val repository = SubjectRepositoryFactory.createListRepo(subjectData.subjectType) override fun provideDataObservable(page: Int): Observable>? = null @@ -43,7 +44,7 @@ open class SubjectListViewModel( subjectData.subjectId, page, subjectData.sort, - if (subjectData.filter.isEmpty()) "type:全部" else subjectData.filter, + subjectData.filter.ifEmpty { "type:全部" }, ) } @@ -76,7 +77,7 @@ open class SubjectListViewModel( private fun updateSubjectSettingBeforeInitialLoad() { // 无论是否加载成功都回落到普通的专题列表加载 - RetrofitManager.getInstance().api + repository .getColumnSettings(subjectData.subjectId) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) @@ -115,10 +116,11 @@ open class SubjectListViewModel( class Factory( private val mApplication: Application, private val subjectData: SubjectData, + private val pageLocation: PageLocation, private val exposureSourceList: List? = null ) : ViewModelProvider.NewInstanceFactory() { override fun create(modelClass: Class): T { - return SubjectListViewModel(mApplication, subjectData, exposureSourceList) as T + return SubjectListViewModel(mApplication, subjectData, pageLocation, exposureSourceList) as T } } diff --git a/app/src/main/java/com/gh/gamecenter/subject/SubjectRepositoryFactory.kt b/app/src/main/java/com/gh/gamecenter/subject/SubjectRepositoryFactory.kt new file mode 100644 index 0000000000..e1033b6f60 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/subject/SubjectRepositoryFactory.kt @@ -0,0 +1,21 @@ +package com.gh.gamecenter.subject + +import com.gh.gamecenter.entity.SubjectData +import com.gh.gamecenter.minigame.qq.QGameSubjectListRepository +import com.gh.gamecenter.minigame.qq.QGameSubjectRepository +import com.gh.gamecenter.minigame.wechat.WGameSubjectListRepository +import com.gh.gamecenter.minigame.wechat.WGameSubjectRepository + +object SubjectRepositoryFactory { + fun createRepo(subjectType: SubjectData.SubjectType): ISubjectRepository = when(subjectType) { + SubjectData.SubjectType.QQ_GAME -> QGameSubjectRepository() + SubjectData.SubjectType.WECHAT_GAME -> WGameSubjectRepository() + else -> SubjectRepository() + } + + fun createListRepo(subjectType: SubjectData.SubjectType): ISubjectListRepository = when(subjectType) { + SubjectData.SubjectType.QQ_GAME -> QGameSubjectListRepository() + SubjectData.SubjectType.WECHAT_GAME -> WGameSubjectListRepository() + else -> SubjectListRepository() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/subject/SubjectViewModel.kt b/app/src/main/java/com/gh/gamecenter/subject/SubjectViewModel.kt index 7e0c61f65d..76fb1ab18a 100644 --- a/app/src/main/java/com/gh/gamecenter/subject/SubjectViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/subject/SubjectViewModel.kt @@ -9,7 +9,6 @@ import com.gh.gamecenter.common.retrofit.JSONObjectResponse import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.entity.SubjectData import com.gh.gamecenter.entity.SubjectSettingEntity -import com.gh.gamecenter.qgame.QGameSubjectRepository import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers import org.json.JSONObject @@ -23,7 +22,8 @@ class SubjectViewModel( val subjectNameLD = MutableLiveData() val subjectSettingLD = MutableLiveData() - private val repository = if (subjectData?.isQQMiniGame == true) QGameSubjectRepository() else SubjectRepository() + private val repository = + SubjectRepositoryFactory.createRepo(subjectData?.subjectType ?: SubjectData.SubjectType.NORMAL) init { initData() diff --git a/app/src/main/java/com/gh/gamecenter/wrapper/BaseTabWrapperFragment.kt b/app/src/main/java/com/gh/gamecenter/wrapper/BaseTabWrapperFragment.kt index a93a1f6b45..42640cd894 100644 --- a/app/src/main/java/com/gh/gamecenter/wrapper/BaseTabWrapperFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/wrapper/BaseTabWrapperFragment.kt @@ -195,6 +195,7 @@ abstract class BaseTabWrapperFragment : BaseLazyFragment(), IMultiTab { bundle.putBoolean(EntranceConsts.KEY_IS_FROM_TAB_WRAPPER, true) bundle.putInt(EntranceConsts.KEY_TAB_COUNT, tabEntityList.size) bundle.putInt(EntranceConsts.KEY_TAB_INDEX, index) + bundle.putString(EntranceConsts.KEY_TAB_NAME, tabEntity.name) bundle.putInt(EntranceConsts.KEY_POSITION, index) val bottomTabExposureSource = arguments?.getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST) @@ -214,7 +215,6 @@ abstract class BaseTabWrapperFragment : BaseLazyFragment(), IMultiTab { val superiorChain = if (this is ISuperiorChain) this else null bundle.putString(EntranceConsts.KEY_CUSTOM_PAGE_ID, tabEntity.link.link) bundle.putString(EntranceConsts.KEY_CUSTOM_PAGE_NAME, tabEntity.link.text) - bundle.putString(EntranceConsts.KEY_TAB_NAME, tabEntity.name) CustomPageFragment().setSuperiorChain(superiorChain).with(bundle) } diff --git a/app/src/main/java/com/gh/gamecenter/wrapper/SearchToolbarTabWrapperFragment.kt b/app/src/main/java/com/gh/gamecenter/wrapper/SearchToolbarTabWrapperFragment.kt index 61d498dc3d..899f4ac76e 100644 --- a/app/src/main/java/com/gh/gamecenter/wrapper/SearchToolbarTabWrapperFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/wrapper/SearchToolbarTabWrapperFragment.kt @@ -299,7 +299,7 @@ class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbar BottomTab.SearchStyle.TYPE_HALO_GAME -> { mSearchHintTv?.let { DefaultSearchHintHelper.setSearchHint(it) } } - BottomTab.SearchStyle.TYPE_QQ_MINI_GAME -> { + BottomTab.SearchStyle.TYPE_MINI_GAME -> { mSearchHintTv?.hint = if (mSearchStyle?.styleType == BottomTab.SearchStyle.STYLE_APPOSITION) "搜索" else "请输入小游戏关键词" } BottomTab.SearchStyle.TYPE_BBS -> { diff --git a/app/src/main/res/drawable-xxhdpi/icon_right_arrow_blue.png b/app/src/main/res/drawable-xxhdpi/icon_right_arrow_blue.png new file mode 100644 index 0000000000..ad6cf7d5f9 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_right_arrow_blue.png differ diff --git a/app/src/main/res/layout/game_item_custom.xml b/app/src/main/res/layout/game_item_custom.xml index f8af1abb4f..92745c75fb 100644 --- a/app/src/main/res/layout/game_item_custom.xml +++ b/app/src/main/res/layout/game_item_custom.xml @@ -260,10 +260,27 @@ android:orientation="horizontal" android:visibility="visible" app:layout_constraintBottom_toBottomOf="@+id/gameIconView" - app:layout_constraintLeft_toLeftOf="@+id/gameDesSpace" + app:layout_constraintLeft_toRightOf="@+id/game_play_count" app:layout_constraintRight_toRightOf="@+id/gameDesSpace" app:layout_constraintTop_toBottomOf="@+id/gameDesSpace" /> + + + + + + + app:layout_constraintStart_toEndOf="@+id/game_play_count" /> + + + app:layout_constraintStart_toEndOf="@+id/game_play_count" /> + + + + + android:layout_height="40dp" + xmlns:tools="http://schemas.android.com/tools"> + app:layout_constraintTop_toTopOf="parent" + tools:text="剑侠风云单职业版" /> + + + + + + + + + + + diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 9835161943..b0b835705d 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -471,7 +471,7 @@ 發布於%1$s 評論 %1$d 點贊 %1$d · 評論 %2$d - QQ小遊戲 + 小遊戲 存檔數量已達上限 請選擇替換覆蓋的存檔 加入訂閱 @@ -566,5 +566,6 @@ 這是一個神秘的崽 個人主頁 來自光環助手(最強卡牌神器) + 立即玩 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dc0ad91c78..0950b952d1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -473,7 +473,7 @@ 发布于%1$s 评论 %1$d 点赞 %1$d · 评论 %2$d - QQ小游戏 + 小游戏 分享光环 去首页看看 今天已签到,明天再来吧~ @@ -570,4 +570,5 @@ 这是一个神秘的崽 个人主页 来自光环助手(最强卡牌神器) + 立即玩 diff --git a/dependencies.gradle b/dependencies.gradle index 883dafdd82..7e70d79370 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -98,7 +98,7 @@ ext { pickerView = "4.1.8" verifier = "1.0.6" skeleton = "1.1.5" - mta = "6.7.9" + mta = "6.8.0" romChecker = "1.0.3" oss = "2.6.0" desugarJdkLibs = "1.1.5" diff --git a/feature/qq_game/src/main/java/com/gh/gamecenter/qgame/HaloApp.kt b/feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/HaloApp.kt similarity index 95% rename from feature/qq_game/src/main/java/com/gh/gamecenter/qgame/HaloApp.kt rename to feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/HaloApp.kt index 2d4dfaf072..ed881320cc 100644 --- a/feature/qq_game/src/main/java/com/gh/gamecenter/qgame/HaloApp.kt +++ b/feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/HaloApp.kt @@ -1,4 +1,4 @@ -package com.gh.gamecenter.qgame +package com.gh.gamecenter.qqmini import android.app.Application import android.content.res.Configuration diff --git a/feature/qq_game/src/main/java/com/gh/gamecenter/qgame/LogProxyImpl.java b/feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/LogProxyImpl.java similarity index 97% rename from feature/qq_game/src/main/java/com/gh/gamecenter/qgame/LogProxyImpl.java rename to feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/LogProxyImpl.java index 2f5b29b933..efedd784b7 100644 --- a/feature/qq_game/src/main/java/com/gh/gamecenter/qgame/LogProxyImpl.java +++ b/feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/LogProxyImpl.java @@ -1,4 +1,4 @@ -package com.gh.gamecenter.qgame; +package com.gh.gamecenter.qqmini; import android.util.Log; diff --git a/feature/qq_game/src/main/java/com/gh/gamecenter/qgame/MiniCustomizedProxyImpl.kt b/feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/MiniCustomizedProxyImpl.kt similarity index 91% rename from feature/qq_game/src/main/java/com/gh/gamecenter/qgame/MiniCustomizedProxyImpl.kt rename to feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/MiniCustomizedProxyImpl.kt index c0095cc07d..bd7010bae4 100644 --- a/feature/qq_game/src/main/java/com/gh/gamecenter/qgame/MiniCustomizedProxyImpl.kt +++ b/feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/MiniCustomizedProxyImpl.kt @@ -1,7 +1,6 @@ -package com.gh.gamecenter.qgame +package com.gh.gamecenter.qqmini import com.alibaba.android.arouter.launcher.ARouter -import com.gh.gamecenter.common.base.GlobalActivityManager import com.gh.gamecenter.common.constant.RouteConsts import com.gh.gamecenter.core.provider.IRealNameProvider import com.tencent.qqmini.sdk.launcher.AppLoaderFactory diff --git a/feature/qq_game/src/main/java/com/gh/gamecenter/qgame/MiniGameChannelInfoProxyImpl.java b/feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/MiniGameChannelInfoProxyImpl.java similarity index 98% rename from feature/qq_game/src/main/java/com/gh/gamecenter/qgame/MiniGameChannelInfoProxyImpl.java rename to feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/MiniGameChannelInfoProxyImpl.java index 75381689c6..194f500c23 100644 --- a/feature/qq_game/src/main/java/com/gh/gamecenter/qgame/MiniGameChannelInfoProxyImpl.java +++ b/feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/MiniGameChannelInfoProxyImpl.java @@ -1,4 +1,4 @@ -package com.gh.gamecenter.qgame; +package com.gh.gamecenter.qqmini; import android.app.Application; import android.content.pm.ApplicationInfo; diff --git a/feature/qq_game/src/main/java/com/gh/gamecenter/qgame/MiniGameWebViewUtils.kt b/feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/MiniGameWebViewUtils.kt similarity index 98% rename from feature/qq_game/src/main/java/com/gh/gamecenter/qgame/MiniGameWebViewUtils.kt rename to feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/MiniGameWebViewUtils.kt index 42414ab0d2..48833486df 100644 --- a/feature/qq_game/src/main/java/com/gh/gamecenter/qgame/MiniGameWebViewUtils.kt +++ b/feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/MiniGameWebViewUtils.kt @@ -1,4 +1,4 @@ -package com.gh.gamecenter.qgame +package com.gh.gamecenter.qqmini import android.annotation.TargetApi import android.app.Application diff --git a/feature/qq_game/src/main/java/com/gh/gamecenter/qgame/QGameHelper.kt b/feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/QGameHelper.kt similarity index 99% rename from feature/qq_game/src/main/java/com/gh/gamecenter/qgame/QGameHelper.kt rename to feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/QGameHelper.kt index d411081b3b..6aee3c2fa0 100644 --- a/feature/qq_game/src/main/java/com/gh/gamecenter/qgame/QGameHelper.kt +++ b/feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/QGameHelper.kt @@ -1,4 +1,4 @@ -package com.gh.gamecenter.qgame +package com.gh.gamecenter.qqmini import android.app.Activity import android.content.Context diff --git a/feature/qq_game/src/main/java/com/gh/gamecenter/qgame/QGameProviderImpl.kt b/feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/QGameProviderImpl.kt similarity index 98% rename from feature/qq_game/src/main/java/com/gh/gamecenter/qgame/QGameProviderImpl.kt rename to feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/QGameProviderImpl.kt index 6ab23591f6..3fe8d9f46a 100644 --- a/feature/qq_game/src/main/java/com/gh/gamecenter/qgame/QGameProviderImpl.kt +++ b/feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/QGameProviderImpl.kt @@ -1,4 +1,4 @@ -package com.gh.gamecenter.qgame +package com.gh.gamecenter.qqmini import android.app.Activity import android.content.Context diff --git a/feature/qq_game/src/main/java/com/gh/gamecenter/qgame/ShareProxyImpl.java b/feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/ShareProxyImpl.java similarity index 99% rename from feature/qq_game/src/main/java/com/gh/gamecenter/qgame/ShareProxyImpl.java rename to feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/ShareProxyImpl.java index e2ceb820d4..adb04f28a9 100644 --- a/feature/qq_game/src/main/java/com/gh/gamecenter/qgame/ShareProxyImpl.java +++ b/feature/qq_game/src/main/java/com/gh/gamecenter/qqmini/ShareProxyImpl.java @@ -1,4 +1,4 @@ -package com.gh.gamecenter.qgame; +package com.gh.gamecenter.qqmini; import android.app.Activity; import android.content.Context; diff --git a/feature/qq_game/src/main/java/com/tencent/qqmini/sdk/core/generated/ExtProxyServiceScope.java b/feature/qq_game/src/main/java/com/tencent/qqmini/sdk/core/generated/ExtProxyServiceScope.java index f90ac83d47..d40d021ca4 100644 --- a/feature/qq_game/src/main/java/com/tencent/qqmini/sdk/core/generated/ExtProxyServiceScope.java +++ b/feature/qq_game/src/main/java/com/tencent/qqmini/sdk/core/generated/ExtProxyServiceScope.java @@ -2,9 +2,9 @@ package com.tencent.qqmini.sdk.core.generated; import androidx.annotation.Keep; -import com.gh.gamecenter.qgame.LogProxyImpl; -import com.gh.gamecenter.qgame.MiniGameChannelInfoProxyImpl; -import com.gh.gamecenter.qgame.ShareProxyImpl; +import com.gh.gamecenter.qqmini.LogProxyImpl; +import com.gh.gamecenter.qqmini.MiniGameChannelInfoProxyImpl; +import com.gh.gamecenter.qqmini.ShareProxyImpl; import java.util.HashMap; import java.util.Map; diff --git a/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java b/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java index f0fd8ad1d0..0ebc5be4cf 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java +++ b/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java @@ -72,6 +72,10 @@ public class Constants { public static final String SIMULATOR = "simulator"; public static final String VGAME = "smooth_game"; // 畅玩类型的游戏 + public static final String QQ_MINI_GAME = "qq"; + + public static final String WECHAT_MINI_GAME = "wechat"; + public static final String DUAL_DOWNLOAD_VGAME = "dual_download_vgame"; // 双下载模式,触发的时候是畅玩 public static final String DUAL_DOWNLOAD_LOCAL = "dual_download_local"; // 双下载模式,触发的时候是普通游戏 public static final String VSPACE_32_DOWNLOAD_ONLY = "vspace_32_download_only"; // 仅下载32位畅玩助手,不跳转安装 @@ -431,4 +435,6 @@ public class Constants { public static final String SP_PLUGIN_AREA_SHOWED_LAUNCH_ID = ""; // 插件化区域显示过的 launchId (Tracker.launchId) public static final String DIN_FONT_PATH = "fonts/d_din_bold_only_number.ttf"; + + } diff --git a/module_common/src/main/java/com/gh/gamecenter/common/entity/ExposureEntity.kt b/module_common/src/main/java/com/gh/gamecenter/common/entity/ExposureEntity.kt index a0b9040d57..8bad3c3cc8 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/entity/ExposureEntity.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/entity/ExposureEntity.kt @@ -30,8 +30,11 @@ data class ExposureEntity( val displayType: String? = "", @SerializedName("is_platform_recommend") val isPlatformRecommend: Boolean? = false, + @SerializedName("mini_game_id") + val miniGameId: String? = "",// 小游戏ID + @SerializedName("mini_game_type") + val miniGameType: String? = "",// 小游戏类型:QQ小游戏:qq 微信小游戏:wechat var speed: Long = 0, - var certification: Int? = null, // 0表示未实名,1表示未成年,2表示成年 // 外层内容 id (包括) diff --git a/module_common/src/main/java/com/gh/gamecenter/common/utils/ImageUtils.kt b/module_common/src/main/java/com/gh/gamecenter/common/utils/ImageUtils.kt index 333a011db2..7af6ad1dc9 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/utils/ImageUtils.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/utils/ImageUtils.kt @@ -306,6 +306,7 @@ object ImageUtils { ) { if (url.isNullOrEmpty()) { view?.setTag(TAG_BOUNDED_URL, null) + view?.setImageURI("") return } diff --git a/module_common/src/main/java/com/gh/gamecenter/common/utils/SensorsBridge.kt b/module_common/src/main/java/com/gh/gamecenter/common/utils/SensorsBridge.kt index 0ab1ae580f..aa8ef3eefe 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/utils/SensorsBridge.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/utils/SensorsBridge.kt @@ -53,6 +53,8 @@ object SensorsBridge { private const val KEY_GAME_COLUMN_ID = "game_column_id" private const val KEY_SOURCE_ENTRANCE = "source_entrance" private const val KEY_SEARCH_CONTENT = "search_content" + private const val KEY_WECHAT_GAME_ID = "wechat_game_id" + private const val KEY_WECHAT_GAME_NAME = "wechat_game_name" private const val KEY_SEARCH_TYPE = "search_type" private const val KEY_SEARCH_RESULT = "search_result" private const val KEY_IS_NOT_PROMPT = "is_not_prompt" @@ -102,6 +104,7 @@ object SensorsBridge { private const val KEY_GAME_COLLECT_PATTERN = "game_collect_pattern" private const val KEY_LINK_CONTENT_COLLECTIONE_PATTERN = "link_content_collectione_pattern" private const val KEY_COLUMN_COLLECTIONE_PATTERN = "column_collectione_pattern" + private const val KEY_COLUMN_PATTERN = "column_pattern" private const val KEY_SEQUENCE = "sequence" private const val KEY_NUMBER = "number" private const val KEY_APP_LIST = "app_list" @@ -215,6 +218,7 @@ object SensorsBridge { private const val EVENT_COMMUNITY_BROWSING_DURATION = "CommunityBrowsingDuration" private const val EVENT_COLUMN_CLICK = "ColumnClick" private const val EVENT_QQ_GAME_CLICK = "QqGameClick" + private const val EVENT_WECHAT_GAME_CLICK = "WechatGameClick" private const val EVENT_GAME_LIST_COLLECTION_CLICK = "GameListCollectionClick" private const val EVENT_CONTENT_CARD_CLICK = "ContentCardClick" private const val EVENT_VIEW_CUSTOM_PAGE = "ViewCustomPage" @@ -3306,7 +3310,7 @@ object SensorsBridge { KEY_GAME_ID to gameId KEY_GAME_NAME to gameName KEY_LOCATION to location - "column_pattern" to columnPattern + KEY_COLUMN_PATTERN to columnPattern KEY_TEXT to text KEY_BUTTON_TYPE to buttonType } @@ -3328,6 +3332,8 @@ object SensorsBridge { * @param location 位置 * @param columnPattern 游戏专题样式 * @param searchContent 搜索内容 + * @param gameId 游戏ID + * @param gameName 游戏名称 * @see EVENT_QQ_GAME_CLICK */ fun trackQQGameClick( @@ -3367,6 +3373,62 @@ object SensorsBridge { trackEvent(EVENT_QQ_GAME_CLICK, json) } + /** + * 事件ID:WechatGameClick + * 事件名称:微信小游戏点击事件 + * @param bottomTab 底部tab + * @param multiTabId 多tab导航页ID + * @param multiTabName 多tab导航页名称 + * @param position 序号 + * @param tabContent 选中tab的名称 + * @param customPageId 自定义页面ID + * @param customPageName 自定义页面名称 + * @param gameColumnId 游戏专题ID + * @param gameColumnName 游戏专题名称 + * @param location 位置 + * @param columnPattern 游戏专题样式 + * @param searchContent 搜索内容 + * @param gameId 微信小游戏ID + * @param gameName 微信小游戏名称 + * @see EVENT_WECHAT_GAME_CLICK + */ + fun trackWechatGameClick( + bottomTab: String = "", + multiTabId: String = "", + multiTabName: String = "", + position: Int = -1, + tabContent: String = "", + customPageId: String = "", + customPageName: String = "", + gameColumnId: String = "", + gameColumnName: String = "", + location: String = "", + columnPattern: String = "", + searchContent: String = "", + gameId: String = "", + gameName: String = "" + ) { + val json = json { + KEY_BOTTOM_TAB to bottomTab + KEY_MULTI_TAB_ID to multiTabId + KEY_MULTI_TAB_NAME to multiTabName + KEY_TAB_CONTENT to tabContent + if (position != -1) { + KEY_POSITION to position + } + KEY_CUSTOM_PAGE_ID to customPageId + KEY_CUSTOM_PAGE_NAME to customPageName + KEY_GAME_COLUMN_ID to gameColumnId + KEY_GAME_COLUMN_NAME to gameColumnName + KEY_LOCATION to location + KEY_COLUMN_PATTERN to columnPattern + KEY_SEARCH_CONTENT to searchContent + KEY_GAME_ID to gameId + KEY_GAME_NAME to gameName + } + trackEvent(EVENT_WECHAT_GAME_CLICK, json) + } + /** * 事件ID GameListCollectionClick * 事件名称 游戏单合集点击事件 diff --git a/module_core/src/main/java/com/gh/gamecenter/core/provider/IDirectProvider.kt b/module_core/src/main/java/com/gh/gamecenter/core/provider/IDirectProvider.kt index da5682fe87..1329142080 100644 --- a/module_core/src/main/java/com/gh/gamecenter/core/provider/IDirectProvider.kt +++ b/module_core/src/main/java/com/gh/gamecenter/core/provider/IDirectProvider.kt @@ -1,5 +1,6 @@ package com.gh.gamecenter.core.provider +import android.app.Activity import android.content.Context import android.os.Bundle import com.alibaba.android.arouter.facade.template.IProvider @@ -49,7 +50,11 @@ interface IDirectProvider : IProvider { path: String? = "" ) - fun directToQGame(context: Context) - fun directToExternalBrowser(context: Context, url: String) + + fun directToQQGameHome(context: Context) + + fun directToQQGameById(activity: Activity, qqAppId: String) + + fun directToWechatGameById(activity: Activity, qqAppId: String) } \ No newline at end of file diff --git a/module_core_feature/src/main/java/com/gh/gamecenter/feature/entity/GameEntity.kt b/module_core_feature/src/main/java/com/gh/gamecenter/feature/entity/GameEntity.kt index 44e2c666d0..c8cda9238c 100644 --- a/module_core_feature/src/main/java/com/gh/gamecenter/feature/entity/GameEntity.kt +++ b/module_core_feature/src/main/java/com/gh/gamecenter/feature/entity/GameEntity.kt @@ -228,7 +228,8 @@ data class GameEntity( var active: Boolean = true, @SerializedName("package_dialog") val packageDialog: PackageDialogEntity? = null, - @SerializedName("top_video") + // 视频信息,微信游戏返回video_info字段,其他游戏返回top_video字段 + @SerializedName("top_video", alternate = ["video_info"]) val topVideo: SimpleVideoEntity? = null, @SerializedName("column_recommend") val columnRecommend: LinkEntity? = null, @@ -250,7 +251,7 @@ data class GameEntity( var recommendStar: Int = 5, //游戏单推荐理由 @SerializedName("recommend_text") - var recommendText: String = "", + private var _recommendText: String = "", // 专题封面图 @SerializedName("column_image") @@ -284,12 +285,26 @@ data class GameEntity( @SerializedName("message_private_id") var messageId: String = "", - // 游戏ID,仅用于QQ小游戏 + // 小游戏ID,仅用于小游戏 @SerializedName("appid") - var qqMiniGameAppId: String = "", - // 状态(1:下架 2:秒玩),仅用于QQ小游戏 + var miniGameAppId: String = "", + // 小游戏状态(1:下架 2:秒玩),仅用于小游戏 @SerializedName("app_status") - var qqMiniGameAppStatus: Int = 0, + var miniGameAppStatus: Int = 0, + // 小游戏类型(qq/wechat),仅用于小游戏 + @SerializedName("game_type") + var miniGameType: String = "", + // 小游戏链接URL,仅用于小游戏 + @SerializedName("appidLink") + var miniGameAppLink: String = "", + // 使用人数,仅用于微信小游戏 + var usage: Int = 0, + // 游戏封面图,仅用于微信小游戏 + var banner: String = "", + // 宣传图,仅用于微信小游戏 + @SerializedName("publicity_img") + var publicityImg: List? = null, + @SerializedName("first_setting") var firstSetting: FirstSetting? = null, @SerializedName("bubble_text") @@ -424,6 +439,17 @@ data class GameEntity( } } + @IgnoredOnParcel + var recommendText: String + get() = if (isWechatMiniGame()) { + brief ?: "" + } else { + _recommendText + } + set(value) { + _recommendText = value + } + @IgnoredOnParcel var h5Link: LinkEntity? get() = if (shouldUseMirrorInfo()) { @@ -732,10 +758,25 @@ data class GameEntity( return category.equals("gjonline") } + /** + * 当前游戏是否为小游戏 + */ + fun isMiniGame(): Boolean = miniGameAppId.isNotEmpty() + /** * 当前游戏是否为QQ小游戏 */ - fun isQQMiniGame(): Boolean = qqMiniGameAppId.isNotEmpty() + fun isQQMiniGame(): Boolean = isMiniGame() && miniGameType == Constants.QQ_MINI_GAME + + /** + * 当前游戏是否为微信小游戏 + */ + fun isWechatMiniGame(): Boolean = isMiniGame() && miniGameType == Constants.WECHAT_MINI_GAME + + /** + * 当前小游戏是否下架 + */ + fun isMiniGameOffShelve(): Boolean = miniGameAppStatus == 1 /** * 是否需要重新检查镜像中的 apk 信息 @@ -1189,13 +1230,13 @@ class SimpleGame( @IgnoredOnParcel val categoryChinese: String - get() = when (category) { - "online" -> "网络" - "local" -> "单机" - "welfare" -> "福利" - "simulator" -> "模拟器" - else -> category ?: "" - } + get() = when (category) { + "online" -> "网络" + "local" -> "单机" + "welfare" -> "福利" + "simulator" -> "模拟器" + else -> category ?: "" + } fun toGameEntity(): GameEntity { val gameEntity = GameEntity(id = id, name = name) diff --git a/module_core_feature/src/main/java/com/gh/gamecenter/feature/entity/SettingsEntity.kt b/module_core_feature/src/main/java/com/gh/gamecenter/feature/entity/SettingsEntity.kt index a5ae1b3c19..6bd8e0862d 100644 --- a/module_core_feature/src/main/java/com/gh/gamecenter/feature/entity/SettingsEntity.kt +++ b/module_core_feature/src/main/java/com/gh/gamecenter/feature/entity/SettingsEntity.kt @@ -71,7 +71,9 @@ class SettingsEntity( @SerializedName("tag") var hotTag: List? = listOf(), @SerializedName("hot_list") - var rankList: List? = listOf() + var rankList: List? = listOf(), + @SerializedName("wechat_game_search_list") + var wechatGameSearchList: List? = listOf()// 微信小游戏-搜索榜单 ) { class RankList( var title: String = "", @@ -90,7 +92,11 @@ class SettingsEntity( var link: LinkEntity = LinkEntity(), //link.type等于game时,字段存在 @SerializedName("link_game") - var linkGame: SimpleGame? = null + var linkGame: SimpleGame? = null, + var brief: String? = "", + var appid: String? = "",// 游戏appId,仅用于小游戏 + var type: String? = "",// 游戏类型(qq/wechat),仅用于小游戏 + var usage: Int? = 0// 游玩人数,仅用于微信小游戏 ) { var exposureEvent: ExposureEvent? = null } diff --git a/module_core_feature/src/main/java/com/gh/gamecenter/feature/entity/SimpleVideoEntity.kt b/module_core_feature/src/main/java/com/gh/gamecenter/feature/entity/SimpleVideoEntity.kt index c1770a7240..497a741db9 100644 --- a/module_core_feature/src/main/java/com/gh/gamecenter/feature/entity/SimpleVideoEntity.kt +++ b/module_core_feature/src/main/java/com/gh/gamecenter/feature/entity/SimpleVideoEntity.kt @@ -9,6 +9,10 @@ data class SimpleVideoEntity( @SerializedName("video_id") val id: String = "", val title: String = "", + // 视频封面,微信游戏返回cover_img_url字段,其他游戏返回poster字段 + @SerializedName("poster", alternate = ["cover_img_url"]) val poster: String = "", + // 视频链接,微信游戏返回video_url字段, 其他游戏返回url字段 + @SerializedName("url", alternate = ["video_url"]) val url: String = "" ) : Parcelable \ No newline at end of file diff --git a/module_core_feature/src/main/java/com/gh/gamecenter/feature/exposure/ExposureEvent.kt b/module_core_feature/src/main/java/com/gh/gamecenter/feature/exposure/ExposureEvent.kt index e4f4e1471c..1c3d17bef3 100644 --- a/module_core_feature/src/main/java/com/gh/gamecenter/feature/exposure/ExposureEvent.kt +++ b/module_core_feature/src/main/java/com/gh/gamecenter/feature/exposure/ExposureEvent.kt @@ -107,7 +107,9 @@ data class ExposureEvent( city = regionSettingHelper?.getIpInfo()?.city ?: "", controlLinkDesc = firstTracePayload?.controlLinkDesc, controlLinkName = firstTracePayload?.controlLinkName, - controlLinkType = firstTracePayload?.controlLinkType + controlLinkType = firstTracePayload?.controlLinkType, + miniGameId = gameEntity?.miniGameAppId ?: "", + miniGameType = gameEntity?.miniGameType ?: "" ) this.id = UUID.randomUUID().toString() this.timeInMillisecond = System.currentTimeMillis() diff --git a/module_core_feature/src/main/java/com/gh/gamecenter/feature/game/GameItemViewHolder.kt b/module_core_feature/src/main/java/com/gh/gamecenter/feature/game/GameItemViewHolder.kt index 4c57ca9098..f938218039 100644 --- a/module_core_feature/src/main/java/com/gh/gamecenter/feature/game/GameItemViewHolder.kt +++ b/module_core_feature/src/main/java/com/gh/gamecenter/feature/game/GameItemViewHolder.kt @@ -15,6 +15,7 @@ import com.gh.gamecenter.common.view.DrawableView import com.gh.gamecenter.feature.R import com.gh.gamecenter.feature.databinding.GameItemBinding import com.gh.gamecenter.feature.entity.GameEntity +import com.gh.gamecenter.feature.minigame.MiniGameItemHelper import com.gh.gamecenter.feature.provider.IBindingAdaptersProvider /** @@ -65,6 +66,7 @@ class GameItemViewHolder(var binding: GameItemBinding) : BaseRecyclerViewHolder< adLabelTv, forceShowSubtitle ) + MiniGameItemHelper.setMiniGameUsage(gamePlayCount, entity) } } diff --git a/module_core_feature/src/main/java/com/gh/gamecenter/feature/minigame/MiniGameItemHelper.kt b/module_core_feature/src/main/java/com/gh/gamecenter/feature/minigame/MiniGameItemHelper.kt new file mode 100644 index 0000000000..8dbd609965 --- /dev/null +++ b/module_core_feature/src/main/java/com/gh/gamecenter/feature/minigame/MiniGameItemHelper.kt @@ -0,0 +1,102 @@ +package com.gh.gamecenter.feature.minigame + +import android.view.View +import android.widget.TextView +import com.alibaba.android.arouter.launcher.ARouter +import com.gh.gamecenter.common.base.GlobalActivityManager +import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.constant.RouteConsts +import com.gh.gamecenter.common.utils.SensorsBridge +import com.gh.gamecenter.core.provider.IDirectProvider +import com.gh.gamecenter.feature.entity.GameEntity +import com.gh.gamecenter.feature.utils.NewFlatLogUtils + +object MiniGameItemHelper { + + /** + * 设置已玩人数,仅支持微信小游戏显示 + */ + fun setMiniGameUsage(tv: TextView, gameEntity: GameEntity) = + if (gameEntity.isWechatMiniGame() && gameEntity.usage > 0) { + tv.visibility = View.VISIBLE + tv.text = getUsageText(gameEntity.usage) + } else { + tv.visibility = View.GONE + } + + private fun getUsageText(usage: Int) = when { + usage < 10000 -> "${usage}人玩过" + else -> { + val value = usage * 1.0F / 10000 + "${"%.1f".format(value)}万人玩过" + } + } + + fun launchMiniGame(miniAppId: String, miniAppType: String) { + GlobalActivityManager.currentActivity?.let { activity -> + val directProvider = ARouter + .getInstance() + .build(RouteConsts.provider.directUtils) + .navigation() as IDirectProvider + if (miniAppType == Constants.QQ_MINI_GAME) { + directProvider.directToQQGameById(activity, miniAppId) + } else { + directProvider.directToWechatGameById(activity, miniAppId) + } + } + } + + fun trackMiniGameClick( + gameEntity: GameEntity, + bottomTab: String = "", + multiTabId: String = "", + multiTabName: String = "", + position: Int = -1, + tabContent: String = "", + customPageId: String = "", + customPageName: String = "", + gameColumnId: String = "", + gameColumnName: String = "", + location: String = "", + columnPattern: String = "", + searchContent: String = "", + ) { + if (gameEntity.miniGameType == Constants.QQ_MINI_GAME) { + NewFlatLogUtils.logQGameClick(gameEntity.miniGameAppId, gameEntity.name) + SensorsBridge.trackQQGameClick( + bottomTab = bottomTab, + multiTabId = multiTabId, + multiTabName = multiTabName, + position = position, + tabContent = tabContent, + customPageId = customPageId, + customPageName = customPageName, + gameColumnId = gameColumnId, + gameColumnName = gameColumnName, + location = location, + columnPattern = columnPattern, + searchContent = searchContent, + gameId = gameEntity.id, + gameName = gameEntity.name ?: "", + ) + } else { + SensorsBridge.trackWechatGameClick( + bottomTab = bottomTab, + multiTabId = multiTabId, + multiTabName = multiTabName, + position = position, + tabContent = tabContent, + customPageId = customPageId, + customPageName = customPageName, + gameColumnId = gameColumnId, + gameColumnName = gameColumnName, + location = location, + columnPattern = columnPattern, + searchContent = searchContent, + gameId = gameEntity.id, + gameName = gameEntity.name ?: "" + ) + } + + } +} \ No newline at end of file diff --git a/module_core_feature/src/main/java/com/gh/gamecenter/feature/utils/NewFlatLogUtils.kt b/module_core_feature/src/main/java/com/gh/gamecenter/feature/utils/NewFlatLogUtils.kt index 844a3e8b6b..1b17a6193b 100644 --- a/module_core_feature/src/main/java/com/gh/gamecenter/feature/utils/NewFlatLogUtils.kt +++ b/module_core_feature/src/main/java/com/gh/gamecenter/feature/utils/NewFlatLogUtils.kt @@ -41,4 +41,15 @@ object NewFlatLogUtils { } log(json) } + + @JvmStatic + fun logQGameClick(qqGameId: String, qqGameName: String?) { + val json = json { + KEY_EVENT to "qq_game_click" + "qq_game_id" to qqGameId + "qq_game_name" to (qqGameName ?: "") + parseAndPutMeta().invoke(this) + } + log(json) + } } \ No newline at end of file diff --git a/module_core_feature/src/main/res/layout/game_item.xml b/module_core_feature/src/main/res/layout/game_item.xml index 4d3090ced6..39bd1f1b4a 100644 --- a/module_core_feature/src/main/res/layout/game_item.xml +++ b/module_core_feature/src/main/res/layout/game_item.xml @@ -158,7 +158,6 @@ android:id="@+id/game_des" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginTop="5dp" android:ellipsize="end" android:includeFontPadding="false" android:singleLine="true" @@ -167,6 +166,7 @@ app:layout_constraintLeft_toRightOf="@+id/game_rating" app:layout_constraintRight_toRightOf="@+id/gameDesSpace" app:layout_constraintTop_toTopOf="@+id/gameDesSpace" + app:layout_constraintBottom_toBottomOf="@id/gameDesSpace" tools:text="巫妖王再怒霜之哀殤又飢渴" /> + + + + + +