Compare commits

..

4 Commits

Author SHA1 Message Date
cfde1e1e62 重构数据解析,ui组件刷新逻辑 2025-06-13 16:15:25 +08:00
0f382baec1 Merge branch 'feat/GHZSCY-8049' into 'dev'
feat: 游戏详情UI优化-客户端 https://jira.shanqu.cc/browse/GHZSCY-8049

See merge request halo/android/assistant-android!2207
2025-05-27 14:39:06 +08:00
62f80bbfdd feat: 游戏详情UI优化-客户端 https://jira.shanqu.cc/browse/GHZSCY-8049 2025-05-27 14:39:06 +08:00
63be9ac221 chore: 版本更新至 5.43.0 2025-05-27 14:04:44 +08:00
55 changed files with 1454 additions and 1326 deletions

View File

@ -18,7 +18,6 @@ import com.therouter.TheRouter
import com.facebook.drawee.controller.BaseControllerListener
import com.facebook.drawee.view.SimpleDraweeView
import com.facebook.imagepipeline.image.ImageInfo
import com.g00fy2.versioncompare.Version
import com.gh.common.exposure.ExposureManager
import com.gh.common.util.DirectUtils.directToLinkPage
import com.gh.common.util.LogUtils
@ -187,11 +186,11 @@ object AdDelegateHelper {
"halo_launch" -> {
config.ownerAd?.startAd?.let { it.id = config.ownerAd.id }
// HarmonyOS 4.2.0 版本不展示第三方开屏广告 (因为会引起奇怪的闪退)
if (MetaUtil.getRom().romName == "HarmonyOS"
&& Version(MetaUtil.getRom().romVersion).isLowerThan(Version("4.2.0"))
&& config.displayRule.adSource == AD_TYPE_SDK
) {
// HarmonyOS 2.2.0 版本不展示第三方开屏广告 (因为会引起奇怪的闪退)
if (MetaUtil.getRom().name == "HarmonyOS"
&& MetaUtil.getRom().versionName == "2.2.0"
&& config.displayRule.adSource == AD_TYPE_SDK) {
return
}

View File

@ -390,7 +390,7 @@ public class Config {
"manufacturer", Build.MANUFACTURER,
"model", Build.MODEL,
"android_sdk_version", String.valueOf(Build.VERSION.SDK_INT),
"rom", MetaUtil.INSTANCE.getRom().getRomName() + " " + MetaUtil.INSTANCE.getRom().getRomVersion()
"rom", MetaUtil.INSTANCE.getRom().name() + " " + MetaUtil.INSTANCE.getRom().getVersionName()
);
RetrofitManager.getInstance()

View File

@ -16,7 +16,6 @@ class DefaultExposureStateChangeListener : IExposureStateChangeListener {
val exposureStatus = if (inExposure) "曝光中" else "结束曝光"
val isCPMExposureEvent = exposureEvent.payload.miniGameType == Constants.WECHAT_MINI_GAME_CPM
val isDSPExposureEvent = exposureEvent.payload.miniGameType == Constants.DSP_GAME
Utils.log(
RecyclerViewExposureHelper.TAG,
@ -30,12 +29,6 @@ class DefaultExposureStateChangeListener : IExposureStateChangeListener {
"上报 CPM 曝光 ${exposureEvent.payload.gameName} ${exposureEvent.id}"
)
ExposureManager.logCPM(exposureEvent)
} else if (isDSPExposureEvent && inExposure) {
Utils.log(
RecyclerViewExposureHelper.TAG,
"上报 DSP 曝光 ${exposureEvent.payload.gameName} ${exposureEvent.id}"
)
ExposureManager.logDSP(exposureEvent)
}
if (!inExposure

View File

@ -111,12 +111,6 @@ object ExposureManager {
}
}
fun logDSP(event: ExposureEvent) {
AppExecutor.logExecutor.execute {
DspReportHelper.report(event.payload.showUrl)
}
}
/**
* @param forcedUpload Ignore all restrictions.
*/

View File

@ -73,7 +73,7 @@ object RegionSettingHelper {
if (list is ArrayList) return list
}
val listCopy: ArrayList<GameEntity> = ArrayList(list)
val listCopy: ArrayList<GameEntity> = if (list is ArrayList) list else ArrayList(list)
listCopy.removeAll { mFilterGameIdSet?.contains(it.id) ?: false }
return listCopy
}

View File

@ -108,32 +108,21 @@ object GameSubstituteRepositoryHelper {
var thisPositionNeedToBeReplaced = false
// 检查是否已安装该游戏里同包名的 APK
if (game.getApk().size == 1) {
val apk = game.getApk().firstOrNull()
// 若该游戏只有一个 APK且该 APK 的包名在本地已安装的包名列表中
if (PackageHelper.localPackageNameSet.contains(apk?.packageName)) {
for (apk in game.getApk()) {
if (PackageHelper.validLocalPackageNameSet.contains(apk.packageName)) {
// 将该位置的游戏标记为需要替换
positionOfGameToBeReplacedList.add(index)
thisPositionNeedToBeReplaced = true
}
} else {
// 检查是否已安装该游戏里同包名的 APK
for (apk in game.getApk()) {
if (PackageHelper.validLocalPackageNameSet.contains(apk.packageName)) {
// 将该位置的游戏标记为需要替换
positionOfGameToBeReplacedList.add(index)
thisPositionNeedToBeReplaced = true
break
}
break
}
}
// 检查是否已安装该游戏 id
if (!thisPositionNeedToBeReplaced && PackagesManager.getInstalledDataByGameId(game.id) != null) {
if (PackagesManager.getInstalledDataByGameId(game.id) != null) {
// 将该位置的游戏标记为需要替换
positionOfGameToBeReplacedList.add(index)
thisPositionNeedToBeReplaced = true
continue
break
}
// 若此游戏所包含的 apk 没有已安装,那么再检查是否已安装有预设相关包名
@ -163,19 +152,11 @@ object GameSubstituteRepositoryHelper {
if (mGameCollectionList.isNullOrEmpty()) return
// 临时的游戏 ID 列表(包含 gameList 的游戏),避免重复替换
val tempDisplayingGameIdSet = HashSet(displayingGameIdSet)
gameList.forEach {
tempDisplayingGameIdSet.add(it.id)
}
for (position in positionOfGameToBeReplacedList) {
val validGame = getValidGame(relatedCollectionId, tempDisplayingGameIdSet)
val validGame = getValidGame(relatedCollectionId, displayingGameIdSet)
validGame?.let {
gameList[position] = it
displayingGameIdSet.add(it.id)
tempDisplayingGameIdSet.add(it.id)
}
}
}

View File

@ -245,7 +245,6 @@ public class LogUtils {
object.put("jnfj", MetaUtil.getBase64EncodedIMEI());
object.put("G_ID", UserManager.getInstance().getDeviceId());
object.put("oaid", HaloApp.getInstance().getOAID());
object.put("rom", MetaUtil.getMeta().getRom());
} catch (JSONException e) {
e.printStackTrace();
}
@ -265,7 +264,6 @@ public class LogUtils {
object.put("channel", HaloApp.getInstance().getChannel());
object.put("dia", MetaUtil.getBase64EncodedAndroidId());
object.put("oaid", MetaUtil.INSTANCE.getMeta().getOaid());
object.put("rom", MetaUtil.getMeta().getRom());
object.put("time", Utils.getTime(context));
object.put("network", DeviceUtils.getNetwork(context));
object.put("user_id", UserManager.getInstance().getUserId());
@ -291,7 +289,6 @@ public class LogUtils {
metaObject.put("channel", meta.getChannel());
metaObject.put("gid", meta.getGid());
metaObject.put("oaid", meta.getOaid());
metaObject.put("rom", MetaUtil.getMeta().getRom());
metaObject.put("jnfj", MetaUtil.getBase64EncodedIMEI());
metaObject.put("mac", meta.getMac());
metaObject.put("manufacturer", meta.getManufacturer());
@ -498,7 +495,6 @@ public class LogUtils {
metaObject.put("os", meta.getOs());
metaObject.put("userId", meta.getUserId());
metaObject.put("oaid", HaloApp.getInstance().getOAID());
metaObject.put("rom", MetaUtil.getMeta().getRom());
} catch (JSONException e) {
e.printStackTrace();

View File

@ -33,7 +33,6 @@ import com.lightgame.utils.Utils
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.*
import java.util.HashMap
import java.util.Locale
import java.util.concurrent.Executors
import kotlin.collections.ArrayList
import kotlin.collections.HashSet
@ -289,22 +288,12 @@ object PackageHelper {
* 用户是否已经使用另类方式获取已安装应用列表
*/
private fun isUseAlternativeWayToGetInstalledPackages(): Boolean {
if (isBuggyHuaweiDevice()) {
useAlternativeWayToGetInstalledPackages = false
return false
}
return useAlternativeWayToGetInstalledPackages
|| (SPUtils.getBoolean(SP_GET_INSTALLED_PACKAGES_BY_ALTERNATIVE_API)
.also { useAlternativeWayToGetInstalledPackages = it })
}
private fun updateUseAlternativeWayToGetInstalledPackages() {
if (isBuggyHuaweiDevice()) {
useAlternativeWayToGetInstalledPackages = false
return
}
// 启用另类获取已安装应用列表的 API
useAlternativeWayToGetInstalledPackages = true
SPUtils.setBoolean(SP_GET_INSTALLED_PACKAGES_BY_ALTERNATIVE_API, true)
@ -489,12 +478,7 @@ object PackageHelper {
/**
* 是否支持动态获取已安装应用列表权限
*/
private fun isSupportGetInstalledAppsPermission(context: Context): Boolean {
if (isBuggyHuaweiDevice()) {
// 华为系 Android 10 设备存在 bug调用过多可能会触发 DeadSystemException
return false
}
fun isSupportGetInstalledAppsPermission(context: Context): Boolean {
if (isUseAlternativeWayToGetInstalledPackages()) {
// 已经使用另类获取已安装应用列表形式,强制判定为不支持动态获取已安装应用列表权限
return false
@ -805,13 +789,4 @@ object PackageHelper {
return packageList
}
private fun isBuggyHuaweiDevice(): Boolean {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
val manufacturer = Build.MANUFACTURER.lowercase(Locale.CHINA) ?: ""
return manufacturer == "huawei" || manufacturer == "honor"
} else {
return false
}
}
}

View File

@ -37,7 +37,7 @@ public class PostCommentUtils {
device.put("model", Build.MODEL);
device.put("manufacturer", Build.MANUFACTURER);
device.put("android_version", android.os.Build.VERSION.RELEASE);
device.put("rom", MetaUtil.INSTANCE.getRom().getRomName() + " " + MetaUtil.INSTANCE.getRom().getRomVersion());
device.put("rom", MetaUtil.INSTANCE.getRom().name() + " " + MetaUtil.INSTANCE.getRom().getVersionName());
content.put("device", device);
} catch (Exception e) {
e.printStackTrace();

View File

@ -9,14 +9,15 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import com.gh.common.constant.Config
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.entity.NewApiSettingsEntity
import com.lightgame.utils.Utils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.enlargeTouchArea
import com.gh.gamecenter.common.utils.setDrawableEnd
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.entity.NewApiSettingsEntity
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
/**
* 处理厂商纯净/安全模式的辅助类
@ -312,11 +313,9 @@ object PureModeHelper {
intent.setPackage("com.huawei.security.privacycenter")
intent.setAction("com.huawei.securitycenter.PURE_MODE_ACTIVITY")
intent.putExtra("intent_from_settings", true)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
HaloApp.getInstance().startActivity(intent)
context.startActivity(intent)
} catch (_: Exception) {
toSystemSettings(context)
}
}

View File

@ -9,11 +9,7 @@ import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.exposure.meta.MetaUtil
import com.gh.gamecenter.common.exposure.meta.MetaUtil.getMeta
import com.gh.gamecenter.common.loghub.LoghubUtils
import com.gh.gamecenter.common.utils.DeviceUtils
import com.gh.gamecenter.common.utils.asVGame
import com.gh.gamecenter.common.utils.getExtension
import com.gh.gamecenter.common.utils.getMetaExtra
import com.gh.gamecenter.common.utils.isSimulatorGame
import com.gh.gamecenter.common.utils.*
import com.gh.ndownload.NDataChanger
import com.gh.ndownload.NDownloadBridge
import com.halo.assistant.HaloApp
@ -431,7 +427,6 @@ object DownloadDataHelper {
metaObject.put("channel", meta.channel)
metaObject.put("gid", meta.gid)
metaObject.put("oaid", meta.oaid)
metaObject.put("rom", meta.rom)
metaObject.put("manufacturer", meta.manufacturer)
metaObject.put("model", meta.model)
metaObject.put("network", DeviceUtils.getNetwork(context))

View File

@ -3,6 +3,9 @@ package com.gh.download
import android.annotation.SuppressLint
import android.text.TextUtils
import com.gh.common.util.*
import com.gh.common.util.DataCollectionUtils
import com.gh.common.util.PackageInstaller
import com.gh.common.util.PackageUtils
import com.gh.common.xapk.XapkInstaller
import com.gh.download.server.BrowserInstallHelper
import com.gh.gamecenter.common.constant.Constants
@ -30,7 +33,9 @@ import com.lightgame.download.DownloadEntity
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONException
import org.json.JSONObject

View File

@ -7,7 +7,6 @@ import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.common.DefaultUrlHandler
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.loadDataCompat
import com.gh.gamecenter.databinding.DownloadDialogInstructionItemBinding
class DownloadDialogInstructionItemViewHolder(val binding: DownloadDialogInstructionItemBinding) :
@ -15,8 +14,11 @@ class DownloadDialogInstructionItemViewHolder(val binding: DownloadDialogInstruc
fun bindItem(listData: List<DownloadDialogItemData>, position: Int, entrance: String) {
val instruction = listData[position].instruction
binding.webView.loadDataCompat(
binding.webView.loadDataWithBaseURL(
null,
"<body style='margin:0;padding:0;color:#666666;font-size:12px;line-height:18px;'>$instruction</body>",
"text/html",
"utf-8", null
)
binding.webView.settings
binding.webView.setBackgroundColor(Color.TRANSPARENT)

View File

@ -9,7 +9,6 @@ import androidx.fragment.app.FragmentActivity
import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.common.utils.loadDataCompat
import com.gh.gamecenter.databinding.DialogDownloadLinkBinding
import com.gh.gamecenter.feature.entity.GameEntity
import com.halo.assistant.HaloApp
@ -28,7 +27,10 @@ class DownloadLinkDialog : BaseDialogFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val binding: DialogDownloadLinkBinding = DialogDownloadLinkBinding.inflate(layoutInflater, container, false)
binding.title.text = mLinkEntity?.title
binding.webView.loadDataCompat(mLinkEntity?.content ?: "")
binding.webView.loadDataWithBaseURL(
null,
mLinkEntity?.content ?: "", "text/html", "utf-8", null
)
binding.confirm.setOnClickListener {
dismissAllowingStateLoss()

View File

@ -886,7 +886,7 @@ class GameDetailViewModel(
params["source"] = HaloApp.getInstance().application.getString(R.string.app_name)
params["jnfj"] = MetaUtil.getBase64EncodedIMEI()
params["manufacturer"] = Build.MANUFACTURER
params["rom"] = MetaUtil.getRom().romName + " " + MetaUtil.getRom().romVersion
params["rom"] = MetaUtil.getRom().name + " " + MetaUtil.getRom().versionName
params["suggestion_type"] = "游戏求更新"
params["game_id"] = game?.id ?: ""

View File

@ -815,10 +815,7 @@ class GameDetailWrapperFragment : BaseLazyFragment(), IScrollable {
downloadStatus = gameEntity?.downloadStatusChinese ?: "",
gameType = gameEntity?.categoryChinese ?: "",
position = position,
tabContent = tabEntity.name,
linkType = tabEntity.link?.type ?: "",
linkId = tabEntity.link?.link ?: "",
linkText = tabEntity.link?.text ?: ""
tabContent = tabEntity.name
)
val entrance = if (mEntrance.contains("论坛详情")) "论坛" else "游戏"

View File

@ -7,7 +7,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import android.widget.LinearLayout
import androidx.core.view.forEach
import androidx.core.view.children
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.recyclerview.widget.RecyclerView
@ -117,7 +117,7 @@ class GameLibaoAdapter(
binding.horizontalScrollView.goneIf(libaoEntity.materials.isEmpty()) {
if (binding.imagesContainer.tag == libaoEntity.id) {
binding.imagesContainer.forEach { view ->
binding.imagesContainer.children.forEach { view ->
if (view is SimpleDraweeView) {
view.hierarchy.roundingParams = RoundingParams().apply {
setCornersRadius(4F.dip2px().toFloat())

View File

@ -541,7 +541,7 @@ class RatingEditActivity : ToolBarActivity(), KeyboardHeightObserver {
jsonObject.put("game_version", gameVersion)
jsonObject.put("source", if (mFromAmway) "anliwall" else "game_detail")
jsonObject.put("plugin_version", PackageUtils.getMetaData(this, mInstallPackageName, "gh_version"))
jsonObject.put("rom", MetaUtil.getRom().romName + " " + MetaUtil.getRom().romVersion)
jsonObject.put("rom", MetaUtil.getRom().name + " " + MetaUtil.getRom().versionName)
jsonObject.put("again", again)
val body = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())

View File

@ -246,10 +246,9 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable, IB
setNavigationTitle(it.title)
})
dataList.observe(viewLifecycleOwner) {
adapter.submitList(it) {
dataList.observe(viewLifecycleOwner) { (shouldScrollToTop, data) ->
adapter.submitList(data) {
if (shouldScrollToTop) {
shouldScrollToTop = false
binding.gameList.scrollToPosition(0)
}
}

View File

@ -29,7 +29,7 @@ interface OnCustomPageEventListener {
/**
* 换一批
*/
fun onChangeABatch(subjectEntity: SubjectEntity)
fun onChangeABatch(componentId: String, subjectEntity: SubjectEntity)
fun onChangeAppBarColor(color: Int)
@ -56,7 +56,10 @@ interface OnCustomPageEventListener {
/**
* 点击进入专题详情
*/
fun navigateSubjectDetailPage(item: CustomSubjectCollectionItem, subject: CustomPageData.LinkColumnCollection.CustomSubjectEntity)
fun navigateSubjectDetailPage(
item: CustomSubjectCollectionItem,
subject: CustomPageData.LinkColumnCollection.CustomSubjectEntity
)
/**

View File

@ -35,9 +35,11 @@ class SubjectEventHelper(viewModel: CustomPageViewModel) : CustomPageItemChildEv
gameEntity.tempDspLogMap = map.toMap() // Return an immutable copy
}
}
gameEntity.isMiniGame() -> {
tracker.trackMiniGameClick(_item, gameEntity)
}
else -> {
tracker.trackColumnClick(_item, gameEntity, "游戏")
}
@ -51,9 +53,11 @@ class SubjectEventHelper(viewModel: CustomPageViewModel) : CustomPageItemChildEv
gameEntity.isDspGame -> {
tracker.trackDspGameClick(_item, gameEntity, "按钮", "自定义页面")
}
gameEntity.isMiniGame() -> {
tracker.trackMiniGameClick(_item, gameEntity)
}
else -> {
tracker.trackColumnClick(_item, gameEntity, "按钮")
}
@ -67,9 +71,9 @@ class SubjectEventHelper(viewModel: CustomPageViewModel) : CustomPageItemChildEv
}
}
fun onChangeABatch(subject: SubjectEntity) {
fun onChangeABatch(componentId: String, subject: SubjectEntity) {
tracker.trackColumnClick(_item, null, "右上角", "换一批")
viewModel.onChangeABatch(subject)
viewModel.onChangeABatch(componentId,subject)
}
fun onMoreClick(link: LinkEntity) {

View File

@ -0,0 +1,185 @@
package com.gh.gamecenter.home.custom.model
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.common.entity.PKEntity
import com.gh.gamecenter.entity.AmwayCommentEntity
import com.gh.gamecenter.entity.DiscoveryCardEntity
import com.gh.gamecenter.entity.HomeItemTestV2Entity
import com.gh.gamecenter.entity.SubjectEntity
import com.gh.gamecenter.feature.entity.AcctRecord
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.CUSTOM_LINK_TYPE_COLUMN_COLLECTION
import com.gh.vspace.VGameItemData
/**
* 接口返回的原始数据模型,最终需要转化成 CustomPageItem 在ui层呈现
*/
sealed class CustomItemDTO(
val componentId: String, // 当前组件的唯一标识,用于后续更新单个数据时,快速找到目标数据
val link: LinkEntity
)
// 游戏专题:展开大图样式专用
class GameItemDTO(
private val _componentId: String,
private val _link: LinkEntity,
val data: GameEntity,
val linkColumn: SubjectEntity?,
) : CustomItemDTO(_componentId, _link)
//游戏专题
data class SubjectItemDTO(
private val _componentId: String,
private val _link: LinkEntity,
var data: SubjectEntity
) : CustomItemDTO(_componentId, _link) {
val scrollState = ScrollState()
}
// 专题合集/游戏单合集
class CollectionItemDTO(
private val _componentId: String,
private val _link: LinkEntity,
val data: CustomPageData.LinkColumnCollection
) : CustomItemDTO(_componentId, _link) {
val isSubjectCollection: Boolean // 是否是专题合集(还有可能是游戏单合集)
get() = link.type == CUSTOM_LINK_TYPE_COLUMN_COLLECTION
var showPage: Int = 0
var loadPage: Int = 1
var isLoadedEnd: Boolean = false
val uiState = UIState()
/**
* 保存ui层状态
*/
data class UIState(
var isBackToStart: Boolean = false
)
}
// 最近在玩
data class RecentGamesItemDTO(
private val _componentId: String,
private val _link: LinkEntity,
var data: List<VGameItemData>
) : CustomItemDTO(_componentId, _link)
// 微信小游戏-最近在玩
data class RecentWechatMiniGamesItemDTO(
private val _componentId: String,
private val _link: LinkEntity,
var data: List<GameEntity>
) : CustomItemDTO(_componentId, _link)
// qq小游戏-最近在玩
data class RecentQqMiniGamesItemDTO(
private val _componentId: String,
private val _link: LinkEntity,
var data: List<GameEntity>,
val linkQqGameRecentlyPlayed: CustomPageData.LinkRecentlyPlayed
) : CustomItemDTO(_componentId, _link)
// 加速游戏最近在玩
data class RecentAcceleratorGamesItemDTO(
private val _componentId: String,
private val _link: LinkEntity,
var data: List<AcctRecord>,
val moreLink: LinkEntity?
) : CustomItemDTO(_componentId, _link)
// qq小游戏专题
data class QqMiniGamesItemDTO(
private val _componentId: String,
private val _link: LinkEntity,
val data: SubjectEntity
) : CustomItemDTO(_componentId, _link) {
val scrollState = ScrollState()
}
// 微信小游戏专题
data class WechatMiniGamesItemDTO(
private val _componentId: String,
private val _link: LinkEntity,
val data: SubjectEntity
) : CustomItemDTO(_componentId, _link) {
val scrollState = ScrollState()
}
// 微信小游戏CPM专题组件
data class WeChatMiniGamesCPMSubjectItemDTO(
private val _componentId: String,
private val _link: LinkEntity,
var data: SubjectEntity
) : CustomItemDTO(_componentId, _link){
val scrollState = ScrollState()
}
// DSP专题组件
data class DSPItemDTO(
private val _componentId: String,
private val _link: LinkEntity,
var data: SubjectEntity
) : CustomItemDTO(_componentId, _link){
val scrollState = ScrollState()
}
// 插件化区域
data class PluginItemDTO(
private val _componentId: String,
private val _link: LinkEntity,
var data: List<GameEntity>
) : CustomItemDTO(_componentId, _link)
// 新游开测
data class GameTestV2ItemDTO(
private val _componentId: String,
private val _link: LinkEntity,
val data: HomeItemTestV2Entity
) : CustomItemDTO(_componentId, _link)
// 光环推荐
data class DiscoverCardItemDTO(
private val _componentId: String,
private val _link: LinkEntity,
var data: DiscoveryCardEntity?
) : CustomItemDTO(_componentId, _link)
// 安利墙
data class AmwayItemDTO(
private val _componentId: String,
private val _link: LinkEntity,
val data: List<AmwayCommentEntity>
) : CustomItemDTO(_componentId, _link)
// 内容卡片
data class ContentCardItemDTO(
private val _componentId: String,
private val _link: LinkEntity,
val data: CustomPageData.ContentCard
) : CustomItemDTO(_componentId, _link)
// 通用内容合集
data class CommonContentCollectionItemDTO(
private val _componentId: String,
private val _link: LinkEntity,
val data: CustomPageData.CommonContentCollection
) : CustomItemDTO(_componentId, _link)
// PK
data class PKItemDTO(
private val _componentId: String,
private val _link: LinkEntity,
var data: PKEntity?
) : CustomItemDTO(_componentId, _link)
class ScrollState(
var scrolledOffset: Int = 0
)

View File

@ -0,0 +1,42 @@
package com.gh.gamecenter.home.custom.model
import android.util.LruCache
import com.gh.gamecenter.feature.entity.GameEntity
import io.reactivex.Observable
import io.reactivex.Single
class CustomPageCacheDataSource {
// 计算内存缓存大小这里取应用最大可用内存的1/8单位KB
private fun calculateMemoryCacheSize(): Int {
val maxMemory = (Runtime.getRuntime().maxMemory() / 1024).toInt()
return maxMemory / 8
}
private val memoryCache: LruCache<String, List<GameEntity>> =
object : LruCache<String, List<GameEntity>>(calculateMemoryCacheSize()) {
override fun sizeOf(key: String, value: List<GameEntity>): Int {
return value.toTypedArray().size / 1024 // 单位KB
}
}
fun getGameList(subjectId: String) = Observable.create {
val gameList = memoryCache.get(subjectId)
if (gameList.isNullOrEmpty()) {
it.onComplete()
} else {
it.onNext(gameList)
}
}
fun putGameList(subjectId: String?, data: List<GameEntity>) {
if (!subjectId.isNullOrBlank()) {
memoryCache.put(subjectId, data)
}
}
fun onClear() {
memoryCache.evictAll()
}
}

View File

@ -15,10 +15,10 @@ import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.vspace.VGameItemData
abstract class CustomPageItem(
// 当前模块在数据列表中的位置注意非ui页面的位置而是数据列表中的位置因为某条数据可能会拆分成多个item
val link: LinkEntity,
var position: Int,
val componentPosition: Int
var position: Int,// 当前模块在数据列表中的位置注意非ui页面的位置而是数据列表中的位置因为某条数据可能会拆分成多个item
val componentPosition: Int,
val componentId: String,
) {
abstract val itemType: Int
@ -362,9 +362,11 @@ abstract class CustomPageItem(
data class CustomSubjectItem(
private val _link: LinkEntity,
val data: SubjectEntity,
private val scrollState: ScrollState,
private val _position: Int,
private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {
private val _componentPosition: Int,
private val _componentId: String,
) : CustomPageItem(_link, _position, _componentPosition, _componentId) {
override val itemType: Int
get() = subjectTypeMap[data.type] ?: CUSTOM_PAGE_ITEM_TYPE_INVALID
@ -379,7 +381,11 @@ data class CustomSubjectItem(
get() = data.data ?: emptyList()
// 临时变量,记录横向列表滚动的距离
var scrolledOffset: Int = 0
var scrolledOffset: Int
get() = scrollState.scrolledOffset
set(value) {
scrollState.scrolledOffset = value
}
val exposureSource: List<ExposureSource>
get() = listOf(ExposureSource("专题", "${data.name ?: ""}+$componentStyle+${data.id}"))
@ -420,7 +426,7 @@ data class CustomSubjectItem(
if (latestDayBeforeTodayPair.first >= testDayOffset) {
latestDayBeforeTodayPair = Pair(testDayOffset, index)
}
} else if (testDayOffset > 0) {
} else {
if (testDayOffset <= latestDayAfterTodayPair.first) {
latestDayAfterTodayPair = Pair(testDayOffset, index)
}
@ -440,11 +446,12 @@ data class CustomSubjectItem(
data class CustomSplitSubjectItem(
private val _link: LinkEntity,
var data: SubjectEntity,
val step: Int,
val startChildPosition: Int,
private val _position: Int,
private val _componentPosition: Int,
val step: Int,
val startChildPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {
private val _componentId: String,
) : CustomPageItem(_link, _position, _componentPosition, _componentId) {
var splitItemCount: Int = -1 // 游戏专题拆分出来的子项数量
@ -509,8 +516,9 @@ data class CustomGameItem(
val linkColumn: SubjectEntity?,
val childPosition: Int,
private val _position: Int, // 当前 item 在 ui 中的位置
private val _componentPosition: Int // 当前组件的位置
) : CustomPageItem(_link, _position, _componentPosition) {
private val _componentPosition: Int, // 当前组件的位置
private val _componentId: String
) : CustomPageItem(_link, _position, _componentPosition, _componentId) {
override val itemType: Int
get() = CUSTOM_PAGE_ITEM_TYPE_GAME_HOME_GAME_ITEM
@ -546,9 +554,11 @@ data class CustomGameItem(
data class CustomSubjectCollectionItem(
private val _link: LinkEntity,
val data: CustomPageData.LinkColumnCollection,
val uiState: CollectionItemDTO.UIState,
private val _position: Int,
private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {
private val _componentPosition: Int,
private val _componentId: String
) : CustomPageItem(_link, _position, _componentPosition, _componentId) {
val isSubjectCollection: Boolean // 是否是专题合集(还有可能是游戏单合集)
get() = link.type == CUSTOM_LINK_TYPE_COLUMN_COLLECTION
@ -572,19 +582,14 @@ data class CustomSubjectCollectionItem(
emptyList()
}
// 临时变量:记录合集中,轮换刷新时当前显示的页码
//当前显示的页码
var showPage: Int = 0
// 临时变量:记录合集中,轮换刷新时当前加载的页码
var loadPage: Int = 1
// 临时变量记录点击轮换刷新时是否正在loading
var isLoading: Boolean = false
// 临时变量,数据是否已全部加载完毕
var isLoadedEnd: Boolean = false
var isBackToStart = true
var isBackToStart: Boolean
get() = uiState.isBackToStart
set(value) {
uiState.isBackToStart = value
}
val showSubject: CustomPageData.LinkColumnCollection.CustomSubjectEntity?
get() = data.data.getOrNull(showPage % data.data.size)
@ -592,14 +597,12 @@ data class CustomSubjectCollectionItem(
override fun doAreItemsTheSame(other: CustomPageItem): Boolean {
return other is CustomSubjectCollectionItem
&& data.id == other.data.id
}
override fun doAreContentsTheSames(other: CustomPageItem): Boolean {
return other is CustomSubjectCollectionItem
&& showPage == other.showPage
&& isLoading == other.isLoading
&& isLoadedEnd == other.isLoadedEnd
&& showSubject == other.showSubject
}
}
@ -608,8 +611,9 @@ data class CustomRecentGamesItem(
private val _link: LinkEntity,
val data: List<VGameItemData>,
private val _position: Int,
private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {
private val _componentPosition: Int,
private val _componentId: String
) : CustomPageItem(_link, _position, _componentPosition, _componentId) {
override val itemType: Int
get() = CUSTOM_PAGE_ITEM_TYPE_RECENT_PLAY
@ -628,8 +632,9 @@ data class CustomRecentWeChatMiniGamesItem(
private val _link: LinkEntity,
val data: List<GameEntity>,
private val _position: Int,
private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {
private val _componentPosition: Int,
private val _componentId: String
) : CustomPageItem(_link, _position, _componentPosition, _componentId) {
override val itemType: Int
get() = CUSTOM_PAGE_ITEM_TYPE_MINI_GAME_RECENT_PLAY
@ -647,8 +652,9 @@ data class CustomWeChatMiniGamesCPMSubjectItem(
private val _link: LinkEntity,
val data: SubjectEntity,
private val _position: Int,
private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {
private val _componentPosition: Int,
private val _componentId: String
) : CustomPageItem(_link, _position, _componentPosition, _componentId) {
override val itemType: Int
get() = CUSTOM_PAGE_ITEM_TYPE_MINI_GAME_RECENT_PLAY
@ -667,8 +673,9 @@ data class CustomRecentQqMiniGamesItem(
val data: List<GameEntity>,
val linkQqGameRecentlyPlayed: CustomPageData.LinkRecentlyPlayed,
private val _position: Int,
private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {
private val _componentPosition: Int,
private val _componentId: String
) : CustomPageItem(_link, _position, _componentPosition, _componentId) {
override val itemType: Int
get() = CUSTOM_PAGE_ITEM_TYPE_MINI_GAME_RECENT_PLAY
@ -690,8 +697,9 @@ data class CustomRecentAcceleratorItem(
val data: List<AcctRecord>,
val moreLink: LinkEntity?,
private val _position: Int,
private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {
private val _componentPosition: Int,
private val _componentId: String
) : CustomPageItem(_link, _position, _componentPosition, _componentId) {
override val itemType: Int
get() = CUSTOM_PAGE_ITEM_TYPE_ACCELERATOR_RECENT_PLAYED
@ -713,8 +721,9 @@ data class CustomPluginItem(
private val _link: LinkEntity,
val data: List<GameEntity>,
private val _position: Int,
private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {
private val _componentPosition: Int,
private val _componentId: String
) : CustomPageItem(_link, _position, _componentPosition, _componentId) {
override val itemType: Int
get() = CUSTOM_PAGE_ITEM_TYPE_PLUGIN
@ -735,8 +744,9 @@ data class CustomGameTestV2Item(
private val _link: LinkEntity,
val data: HomeItemTestV2Entity,
private val _position: Int,
private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {
private val _componentPosition: Int,
private val _componentId: String
) : CustomPageItem(_link, _position, _componentPosition, _componentId) {
override val itemType: Int
get() = CUSTOM_PAGE_ITEM_TYPE_NEW_GAME_TEST
@ -754,8 +764,9 @@ data class CustomDiscoverCardItem(
private val _link: LinkEntity,
val data: DiscoveryCardEntity?,
private val _position: Int,
private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {
private val _componentPosition: Int,
private val _componentId: String
) : CustomPageItem(_link, _position, _componentPosition, _componentId) {
val spanCount = 3
@ -781,8 +792,9 @@ data class CustomAmwayItem(
private val _link: LinkEntity,
val data: List<AmwayCommentEntity>,
private val _position: Int,
private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {
private val _componentPosition: Int,
private val _componentId: String
) : CustomPageItem(_link, _position, _componentPosition, _componentId) {
override val itemType: Int
get() = CUSTOM_PAGE_ITEM_TYPE_AMWAY_WALL
@ -800,8 +812,9 @@ data class CustomContentCardItem(
private val _link: LinkEntity,
val data: CustomPageData.ContentCard,
private val _position: Int,
private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {
private val _componentPosition: Int,
private val _componentId: String
) : CustomPageItem(_link, _position, _componentPosition, _componentId) {
override val itemType: Int
get() = CUSTOM_PAGE_ITEM_TYPE_CONTENT_CARD
@ -822,8 +835,9 @@ data class CustomCommonContentCollectionItem(
private val _link: LinkEntity,
val data: CustomPageData.CommonContentCollection,
private val _position: Int,
private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {
private val _componentPosition: Int,
private val _componentId: String
) : CustomPageItem(_link, _position, _componentPosition, _componentId) {
override val itemType: Int
get() = if (data.layout == COMMON_CONTENT_COLLECTION_LAYOUT_BANNER) {
@ -861,10 +875,11 @@ data class CustomCommonContentCollectionItem(
data class CustomSplitCommonContentCollectionItem(
private val _link: LinkEntity,
val data: CustomPageData.CommonContentCollection,
val leftPosition: Int,
private val _position: Int,
private val _componentPosition: Int,
val leftPosition: Int,
) : CustomPageItem(_link, _position, _componentPosition) {
private val _componentId: String
) : CustomPageItem(_link, _position, _componentPosition, _componentId) {
override val itemType
get() = commonContentCollection[data.layout] ?: CUSTOM_PAGE_ITEM_TYPE_INVALID
@ -897,8 +912,9 @@ data class CustomPKItem(
private val _link: LinkEntity,
val data: PKEntity?,
private val _position: Int,
private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {
private val _componentPosition: Int,
private val _componentId: String
) : CustomPageItem(_link, _position, _componentPosition, _componentId) {
override val itemType: Int
get() = CUSTOM_PAGE_ITEM_TYPE_PK
@ -916,8 +932,9 @@ data class CustomDspPlaceholderItem(
private val _link: LinkEntity,
val data: SubjectEntity,
private val _position: Int,
private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {
private val _componentPosition: Int,
private val _componentId: String
) : CustomPageItem(_link, _position, _componentPosition, _componentId) {
override val itemType: Int
get() = CUSTOM_PAGE_ITEM_TYPE_MINI_GAME_RECENT_PLAY
@ -930,14 +947,9 @@ data class CustomDspPlaceholderItem(
}
}
object CustomFooterItem : CustomPageItem(LinkEntity(), -1, -1) {
object CustomFooterItem : CustomPageItem(LinkEntity(), -1, -1, "") {
override val itemType: Int
get() = CUSTOM_PAGE_ITEM_TYPE_FOOTER
}
object CustomInvalidItem : CustomPageItem(LinkEntity(), -2, -2) {
override val itemType: Int
get() = CUSTOM_PAGE_ITEM_TYPE_INVALID
}

View File

@ -1,8 +1,10 @@
package com.gh.gamecenter.home.custom.model
import android.content.Context
import android.util.LruCache
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.feature.entity.FloatingWindowEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.halo.assistant.HaloApp
import java.text.SimpleDateFormat
import java.util.*

View File

@ -56,12 +56,17 @@ class CustomPageRemoteDataSource(
}
}
fun loadCollectionContent(item: CustomSubjectCollectionItem): Single<List<CustomPageData.LinkColumnCollection.CustomSubjectEntity>> =
if (item.isSubjectCollection) {
newApi.getColumnsCollectionContents(item.data.id, "component", item.loadPage + 1, 1)
} else {
newApi.getGameCollectionContents(item.data.id, "component", item.loadPage + 1, 1)
}
fun loadColumnsCollectionContents(
collectionId: String,
page: Int
): Single<MutableList<CustomPageData.LinkColumnCollection.CustomSubjectEntity>> =
newApi.getColumnsCollectionContents(collectionId, "component", page, 1)
fun loadGameCollectionContents(
collectionId: String,
page: Int
): Single<MutableList<CustomPageData.LinkColumnCollection.CustomSubjectEntity>> =
newApi.getGameCollectionContents(collectionId, "component", page, 1)
fun loadChangeSubjectGame(subjectEntity: SubjectEntity): Observable<List<GameEntity>> =
if (subjectEntity.isQQColumn) {

View File

@ -2,10 +2,13 @@ package com.gh.gamecenter.home.custom.model
import androidx.annotation.MainThread
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.asLiveData
import com.gh.common.filter.RegionSettingHelper
import com.gh.common.util.HomePluggableHelper
import com.gh.common.util.PackageUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.Constants.SP_HIDDEN_NOTIFICATIONS
import com.gh.gamecenter.common.utils.observableToMain
@ -17,7 +20,9 @@ import com.gh.gamecenter.entity.DiscoveryGameCardEntity
import com.gh.gamecenter.entity.DiscoveryGameCardLabel
import com.gh.gamecenter.feature.entity.AcctRecord
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.PluginLocation
import com.gh.gamecenter.gamedetail.accelerator.AccelerationDataBase
import com.gh.gamecenter.packagehelper.PackageRepository
import com.gh.gamecenter.retrofit.RetrofitManager
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
@ -34,6 +39,30 @@ class CustomPageShareRepository private constructor() {
private val compositeDisposable = CompositeDisposable()
private val _pluginGames = MediatorLiveData<List<GameEntity>>().apply {
addSource(PackageRepository.gameUpdateLiveData) { updateList ->
val gameList = arrayListOf<GameEntity>()
updateList.forEach {
if (it.isPluggable && it.indexPlugin == "open" && it.isShowPlugin(PluginLocation.only_index)) {
val game = it.transformGameEntity()
if (HomePluggableHelper.showHomePluggable(game)) {
game.setEntryMap(DownloadManager.getInstance().getEntryMap(game.name))
gameList.add(game)
}
}
}
// 下载七天排序
gameList.sortWith { o1, o2 -> o2.download - o1.download }
value = gameList
}
}
val pluginGames: LiveData<List<GameEntity>> = _pluginGames
fun temporarilyBlockGameInPluginItem(gameId: String) {
val gameList = _pluginGames.value ?: return
_pluginGames.value = gameList.filterNot { it.id == gameId }
}
private val _discoverData = MutableLiveData<DiscoveryCardEntity>()
val discoverData: LiveData<DiscoveryCardEntity> = _discoverData

View File

@ -26,10 +26,7 @@ import com.gh.gamecenter.home.custom.createExposureEvent
import com.gh.gamecenter.home.custom.eventlistener.CustomPageItemChildEventHelper
import com.gh.gamecenter.home.custom.eventlistener.GameSubjectCollectionEventHelper
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 com.gh.gamecenter.home.custom.model.CustomSubjectCollectionItem
import com.gh.gamecenter.home.custom.model.CustomSubjectItem
import com.gh.gamecenter.home.custom.model.*
import com.lightgame.download.DownloadEntity
abstract class BaseCustomViewHolder(
@ -98,7 +95,14 @@ abstract class BaseCustomViewHolder(
titleBinding.root.goneIf(false)
setSubjectTitle(
titleBinding,
CustomSubjectItem(item.link, item.data, item.position, item.componentPosition),
CustomSubjectItem(
item.link,
item.data,
ScrollState(),
item.position,
item.componentPosition,
item.componentId
),
eventHelper,
titleType
)
@ -189,7 +193,7 @@ abstract class BaseCustomViewHolder(
when (subject.home) {
HOME_CHANGE -> {
// 点击换一批
eventHelper.onChangeABatch(subject)
eventHelper.onChangeABatch(item.componentId, subject)
}
HOME_MORE -> {

View File

@ -88,7 +88,7 @@ class CustomRefreshIconViewHolder(
} else {
_subjectEntity = subjectEntity
}
println("kayn -->isBackToStart:${item.isBackToStart}")
// 如果游戏全部被屏蔽,自动加载下一页
if (subjectEntity.games.isEmpty()) {
childEventHelper.onRotateRefresh()

View File

@ -38,19 +38,12 @@ object MiniGameRecentlyPlayUseCase {
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<List<GameEntity>>() {
override fun onSuccess(data: List<GameEntity>) {
if (gameType == Constants.QQ_MINI_GAME) {
_qqRecentGamesItemLiveData.value = data
} else {
_wechatRecentGamesItemLiveData.value = data
}
}
override fun onFailure(exception: Exception) {
super.onFailure(exception)
if (gameType == Constants.QQ_MINI_GAME) {
_qqRecentGamesItemLiveData.value = emptyList()
} else {
_wechatRecentGamesItemLiveData.value = emptyList()
if (data.isNotEmpty()) {
if (gameType == Constants.QQ_MINI_GAME) {
_qqRecentGamesItemLiveData.value = data
} else {
_wechatRecentGamesItemLiveData.value = data
}
}
}
})
@ -90,10 +83,7 @@ object MiniGameRecentlyPlayUseCase {
_qqRecentGamesItemLiveData.value
} else {
_wechatRecentGamesItemLiveData.value
} ?: let {
loadRecentlyPlayedMiniGameList(gameType)// 最近在玩数据为空时,则调用接口获取数据
emptyList()
}
} ?: emptyList()
fun clearRecentlyPlayedMiniGameList(gameType: String = "") {
when (gameType) {

View File

@ -6,6 +6,7 @@ import com.gh.gamecenter.common.livedata.NonStickyMutableLiveData
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.feature.entity.GameEntity
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
/**
@ -14,11 +15,7 @@ import io.reactivex.schedulers.Schedulers
class WGameSubjectCPMListUseCase(
private val repository: WGameSubjectCPMListRepository = WGameSubjectCPMListRepository()
) {
/**
* 微信专题CPM请求记录用于避免重复请求以专题ID作为Key
*/
private val requestKeyList = mutableListOf<String>()
private val compositeDisposable = CompositeDisposable()
/**
* 微信小游戏CPM列表这里的LiveData充当类似于EventBus的角色因此使用NonStickyMutableLiveData
@ -26,21 +23,18 @@ class WGameSubjectCPMListUseCase(
private val _wechatMiniGameCPMListLiveData = NonStickyMutableLiveData<Pair<String, List<GameEntity>>>()
val wechatMiniGameCPMListLiveData: LiveData<Pair<String, List<GameEntity>>> = _wechatMiniGameCPMListLiveData
@SuppressLint("CheckResult")
fun getWechatMiniGameCPMList(subjectId: String?, minimumSize: Int, onlyFee: Boolean) {
if (subjectId.isNullOrEmpty() || requestKeyList.contains(subjectId)) {
return
}
requestKeyList.add(subjectId)
fun getWechatMiniGameCPMList(componentId: String, minimumSize: Int, onlyFee: Boolean) {
repository.getColumn(null, 1, null, null, null, null, minimumSize, onlyFee)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<List<GameEntity>>() {
override fun onSuccess(data: List<GameEntity>) {
requestKeyList.remove(subjectId)
_wechatMiniGameCPMListLiveData.value = subjectId to data
_wechatMiniGameCPMListLiveData.value = componentId to data
}
})
}).let(compositeDisposable::add)
}
fun onClear() {
compositeDisposable.clear()
}
}

View File

@ -6,7 +6,6 @@ import androidx.recyclerview.widget.DiffUtil.ItemCallback
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.debounceActionWithInterval
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.common.view.Chips
import com.gh.gamecenter.databinding.ItemColumnCollectionCustomTabBinding
@ -31,10 +30,8 @@ class CustomTabFollowAdapter(private val viewModel: ColumnCollectionTabViewModel
endIcon.setImageResource(R.drawable.ic_basic_x_8_secondary)
endIcon.imageTintList = null
setOnClickListener {
debounceActionWithInterval(500) {
if (!isForbidden) {
viewModel?.addMore(subjectData)
}
if (!isForbidden) {
viewModel?.addMore(subjectData)
}
}
}

View File

@ -6,7 +6,6 @@ import androidx.recyclerview.widget.DiffUtil.ItemCallback
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.debounceActionWithInterval
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.common.view.Chips
import com.gh.gamecenter.databinding.ItemColumnCollectionCustomTabBinding
@ -27,9 +26,7 @@ class CustomTabMoreAdapter(private val viewModel: ColumnCollectionTabViewModel?)
startIcon.setImageResource(R.drawable.ic_auxiliary_plus_secondary_8)
startIcon.imageTintList = null
setOnClickListener {
debounceActionWithInterval(500) {
viewModel?.addFollow(subjectData)
}
viewModel?.addFollow(subjectData)
}
}
}

View File

@ -812,8 +812,6 @@ class SubjectTabFragment : ToolbarFragment() {
}
override fun onBackPressed(): Boolean {
if (!isAdded) return super.onBackPressed()
if (binding.settingGuideContainer.isVisible) {
binding.settingGuideContainer.performClick()
return true

View File

@ -118,8 +118,6 @@ class TabWrapperFragment: BaseTabWrapperFragment(), ISmartRefresh, ISmartRefresh
if (shouldShow && guide != null && guidePosition != -1) {
tabLayout?.post {
if (activity == null) return@post
val tabView = tabLayout?.getTabAt(guidePosition)?.view
if (tabView != null) {
if (!isDefaultCustomPageFragment() && priorityChain.isHandlerQueueEmpty()) {
@ -135,7 +133,7 @@ class TabWrapperFragment: BaseTabWrapperFragment(), ISmartRefresh, ISmartRefresh
} else {
multiTabGuideHandler.doPreProcess(
true,
activity,
requireActivity(),
mBaseHandler,
guide,
tabLayout,

View File

@ -243,7 +243,7 @@ class VFeedbackDialogFragment : BaseDialogFragment() {
"source" to HaloApp.getInstance().application.getString(R.string.app_name)
"jnfj" to MetaUtil.getBase64EncodedIMEI()
"manufacturer" to Build.MANUFACTURER
"rom" to MetaUtil.getRom().romName + " " + MetaUtil.getRom().romVersion
"rom" to MetaUtil.getRom().name + " " + MetaUtil.getRom().versionName
"suggestion_type" to "游戏问题"
"game_id" to game.id

View File

@ -152,7 +152,7 @@ class AccelerationUseCase {
"from" to "",
"game_id" to game.id,
"manufacturer" to Build.MANUFACTURER,
"rom" to MetaUtil.getRom().romName + " " + MetaUtil.getRom().romVersion,
"rom" to MetaUtil.getRom().name + " " + MetaUtil.getRom().versionName,
"suggestion_type" to "加速器失败",
"message" to "加速失败, 游戏ID: ${game.id}, 游戏名: ${game.name ?: ""}",
"log" to it

View File

@ -693,7 +693,7 @@ class WebFragment : LazyFragment(), IScrollable {
webview.loadUrl(mWebUrl)
}
} else {
webview.loadDataCompat(mWebUrl)
webview.loadDataWithBaseURL(null, mWebUrl, "text/html", "utf-8", null)
}
}
if (mIsHorizontalDispatcherEnabled) {

View File

@ -15,14 +15,9 @@ import com.tencent.vasdolly.helper.ChannelReaderUtil
class FlavorProviderImp : IFlavorProvider {
private var isInit = false
private val pendingEvent = arrayListOf<String>()
override fun init(application: Application, activity: Activity, activateRatio: Int) {
SMHelper.init(application, getChannelStr(application))
isInit = true
if (HaloApp.getInstance().isBrandNewInstall) {
logEvent("EVENT_ACTIVE")
SPUtils.setLong("TIME_OF_BRAND_NEW_INSTALL", System.currentTimeMillis() / 1000)
@ -36,8 +31,6 @@ class FlavorProviderImp : IFlavorProvider {
SPUtils.setBoolean("SHOULD_SEND_RETENTION_EVENT", false)
}
}
pendingEvent.forEach(SMHelper::onEvent)
pendingEvent.clear()
}
override fun getChannelStr(application: Application): String {
@ -50,11 +43,7 @@ class FlavorProviderImp : IFlavorProvider {
}
override fun logEvent(content: String) {
if (isInit) {
SMHelper.onEvent(content)
} else {
pendingEvent.add(content)
}
SMHelper.onEvent(content)
}
override fun logCoreEvent() {

View File

@ -7,8 +7,8 @@ ext {
targetSdkVersion = 30 // 升级targetSdkVersion到 34 时需要根据官方文档补全前台服务的权限类型。比如 NDownloadServiceKeepAliveService
// application info (每个大版本之间的 versionCode 增加 20)
versionCode = 1195
versionName = "5.42.5"
versionCode = 1210
versionName = "5.43.0"
applicationId = "com.gh.gamecenter"
applicationIdGat = "com.gh.gamecenter.intl"
@ -99,7 +99,7 @@ ext {
verifier = "1.0.6"
skeleton = "1.1.5"
mta = "6.8.0"
romChecker = "2.0.0"
romChecker = "1.0.3"
oss = "2.8.8"
desugarJdkLibs = "1.1.5"
toolargetool = "0.3.0"

View File

@ -39,7 +39,7 @@ class QaFeedbackViewModel(application: Application, private val contentId: Strin
map["source"] = HaloApp.getInstance().getString(R.string.app_name)
map["jnfj"] = getBase64EncodedIMEI()
map["manufacturer"] = Build.MANUFACTURER
map["rom"] = MetaUtil.getRom().romName + " " + MetaUtil.getRom().romVersion
map["rom"] = MetaUtil.getRom().name + " " + MetaUtil.getRom().versionName
val requestBody = map.toRequestBody()
RetrofitManager.getInstance().api

View File

@ -209,7 +209,7 @@ class SuggestViewModel(
"source" to getApplication<Application>().getString(R.string.app_name)
"jnfj" to getBase64EncodedIMEI()
"manufacturer" to Build.MANUFACTURER
"rom" to MetaUtil.getRom().romName + " " + MetaUtil.getRom().romVersion
"rom" to MetaUtil.getRom().name + " " + MetaUtil.getRom().versionName
"suggestion_type" to suggestType
"from" to contact
"contact_func" to contactType.value
@ -318,7 +318,7 @@ class SuggestViewModel(
"source" to getApplication<Application>().getString(R.string.app_name)
"jnfj" to getBase64EncodedIMEI()
"manufacturer" to Build.MANUFACTURER
"rom" to MetaUtil.getRom().romName + " " + MetaUtil.getRom().romVersion
"rom" to MetaUtil.getRom().name + " " + MetaUtil.getRom().versionName
"suggestion_type" to mSuggestType
"app_name" to appName
"owner_type" to copyrightIdentity

View File

@ -63,7 +63,7 @@ dependencies {
kapt "com.google.auto.service:auto-service:${autoServiceVersion}"
api "com.louiscad.splitties:splitties-views-dsl:${splitties}"
api "com.louiscad.splitties:splitties-views-dsl-constraintlayout:${splitties}"
api "com.lg:romchecker:${romChecker}"
api "com.github.nichbar:AndroidRomChecker:${romChecker}"
api "androidx.cardview:cardview:${cardView}"
api "com.google.android.material:material:${material}"
api "com.scwang.smartrefresh:SmartRefreshLayout:${smartRefreshLayout}"

View File

@ -33,6 +33,7 @@ object MetaUtil {
private var rom: Rom? = null
fun refreshMeta() {
val appProvider = TheRouter.get(IAppProvider::class.java)
val buildConfigProvider = TheRouter.get(IBuildConfigProvider::class.java)
val userManagerProvider = TheRouter.get(IUserManagerProvider::class.java)
@ -54,7 +55,7 @@ object MetaUtil {
exposureVersion = buildConfigProvider?.getExposureVersion(),
session_id = Tracker.sessionId,
launch_id = Tracker.launchId,
rom = getRom().romName + " " + getRom().romVersion
rom = ""
)
}
@ -67,13 +68,7 @@ object MetaUtil {
}
fun getRom(): Rom {
val appProvider = TheRouter.get(IAppProvider::class.java)
if (appProvider?.isUserAcceptPrivacyPolicy(HaloApp.getInstance()) == false) {
// 如果用户没有同意隐私政策,则返回一个默认的 Rom 对象
return Rom.create("unknown", "unknown", "unknown")
}
if (rom == null || rom?.romName == "unknown") {
if (rom == null) {
rom = RomIdentifier.getRom()
}
return rom!!

View File

@ -167,22 +167,20 @@ object TrackerLogger {
}
private fun getMeta(): JSONObject {
val meta = MetaUtil.getMeta()
val (_, _, model, manufacturer, _, _, android_version, network, _, gid, oaid, channel, appVersion, userId) = MetaUtil.getMeta()
val metaObject = JSONObject()
try {
metaObject.put("dia", getBase64EncodedAndroidId())
metaObject.put("android_version", meta.android_version)
metaObject.put("app_version", meta.appVersion)
metaObject.put("channel", meta.channel)
metaObject.put("gid", meta.gid)
metaObject.put("oaid", meta.oaid)
metaObject.put("rom", meta.rom)
metaObject.put("android_version", android_version)
metaObject.put("app_version", appVersion)
metaObject.put("channel", channel)
metaObject.put("gid", gid)
metaObject.put("oaid", oaid)
metaObject.put("jnfj", getBase64EncodedIMEI())
metaObject.put("manufacturer", meta.manufacturer)
metaObject.put("model", meta.model)
metaObject.put("network", meta.network)
metaObject.put("user_id", meta.userId)
metaObject.put("manufacturer", manufacturer)
metaObject.put("model", model)
metaObject.put("network", network)
metaObject.put("user_id", userId)
} catch (e: JSONException) {
e.printStackTrace()
}

View File

@ -1494,26 +1494,6 @@ fun WebView.enableForceDark(isDarkModeOn: Boolean) {
}
}
fun WebView.loadDataCompat(data: String, mimeType: String = "text/html", encoding: String = "utf-8") {
try {
this.loadDataWithBaseURL(
null,
data,
mimeType,
encoding,
null
)
} catch (e: NullPointerException) {
this.loadDataWithBaseURL(
"localhost",
data,
"text/html",
"utf-8",
null
)
}
}
/**
* WebView是否启用强制深色模式
*/

View File

@ -52,7 +52,7 @@ public class LogUtils {
metaObject.put("os", meta.getOs());
metaObject.put("userId", meta.getUserId());
metaObject.put("oaid", appProvider.getOaid());
metaObject.put("rom", meta.getRom());
} catch (JSONException e) {
e.printStackTrace();
}
@ -71,7 +71,6 @@ public class LogUtils {
metaObject.put("channel", meta.getChannel());
metaObject.put("gid", meta.getGid());
metaObject.put("oaid", meta.getOaid());
metaObject.put("rom", meta.getRom());
metaObject.put("jnfj", MetaUtil.getBase64EncodedIMEI());
metaObject.put("mac", meta.getMac());
metaObject.put("manufacturer", meta.getManufacturer());
@ -80,7 +79,7 @@ public class LogUtils {
metaObject.put("os", meta.getOs());
metaObject.put("user_id", meta.getUserId());
metaObject.put("oaid", appProvider.getOaid());
metaObject.put("rom", meta.getRom());
} catch (JSONException e) {
e.printStackTrace();
}
@ -133,7 +132,7 @@ public class LogUtils {
metaObject.put("os", meta.getOs());
metaObject.put("userId", meta.getUserId());
metaObject.put("oaid", meta.getOaid());
metaObject.put("rom", meta.getRom());
object.put("event", "SHARE");
object.put("meta", metaObject);
object.put("timestamp", System.currentTimeMillis() / 1000);

View File

@ -517,10 +517,7 @@ object SensorsBridge {
downloadStatus: String,
gameType: String,
position: Int,
tabContent: String,
linkType: String,
linkId: String,
linkText: String,
tabContent: String
) {
val json = json {
KEY_GAME_ID to gameId
@ -535,9 +532,6 @@ object SensorsBridge {
KEY_GAME_TYPE to gameType
KEY_POSITION to position
KEY_TAB_CONTENT to tabContent
KEY_LINK_TYPE to linkType
KEY_LINK_ID to linkId
KEY_LINK_TEXT to linkText
}
trackEvent(EVENT_GAME_DETAIL_PAGE_TAB_SELECT, json)

View File

@ -65,7 +65,6 @@ object AppExecutor {
val cachedScheduler by lazy { Schedulers.from(ioExecutor) }
val computationScheduler by lazy { Schedulers.from(heavyWeightIoExecutor) }
val logScheduler by lazy { Schedulers.from(logExecutor) }
class MainThreadExecutor : Executor {
private val mainThreadHandler = Handler(Looper.getMainLooper())

View File

@ -49,12 +49,7 @@ data class ExposureEvent(
eTrace: List<ExposureEvent>? = null,
event: ExposureType = ExposureType.EXPOSURE
) {
val currentActivity = try {
CurrentActivityHolder.getCurrentActivity()
} catch (e: Exception) {
// 捕获异常,避免在获取当前 Activity 时出现问题
null
}
val currentActivity = CurrentActivityHolder.getCurrentActivity()
val currentActivitySimpleName = if (currentActivity != null) currentActivity::class.simpleName else "unknown"
val businessId = if (currentActivity is IBusiness) currentActivity.getBusinessId() else null

View File

@ -72,7 +72,7 @@ class RecyclerViewExposureHelper(
init {
val disposable = collectExposureSubject
.throttleLatest(SAMPLE_RATE, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe({
collectExposureData()
}, {

View File

@ -169,7 +169,7 @@ class Va : IVa {
LogConstants.KEY_MANUFACTURER to Build.MANUFACTURER,
LogConstants.KEY_MODEL to Build.MODEL,
LogConstants.KEY_NETWORK to (MetaUtil.getMeta().network ?: ""),
LogConstants.KEY_ROM to RomIdentifier.getRom().romName + " " + RomIdentifier.getRom().romVersion,
LogConstants.KEY_ROM to RomIdentifier.getRom().name + " " + RomIdentifier.getRom().versionName,
LogConstants.KEY_HOST_VERSION to hostVersion,
LogConstants.KEY_HOST_CHANNEL to hostChannel,
LogConstants.KEY_OAID to oaid,

2
vasdk

Submodule vasdk updated: 16201868dd...02d9241f8d