Compare commits

..

1 Commits

568 changed files with 9618 additions and 27358 deletions

View File

@ -346,7 +346,7 @@ repositories {
android.applicationVariants.configureEach { variant ->
variant.mergeAssets.doLast {
def assetDir = variant.mergeAssetsProvider.get().outputDir.get()
def unwantedAssets = ['1832823466', 'gdt_plugin/gdtadv2.jar']
def unwantedAssets = ['2011394667', 'gdt_plugin/gdtadv2.jar']
unwantedAssets.each { assetPath ->
def file = new File([assetDir, assetPath].join(File.separator))
@ -402,7 +402,7 @@ dependencies {
exclude module: "gsyvideoplayer-androidvideocache"
exclude group: "tv.danmaku.ijk.media"
})
implementation("com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-exo_player2:$gsyVideo") {
implementation ("com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-exo_player2:$gsyVideo") {
exclude group: 'com.google.android.exoplayer', module: 'extension-rtmp'
}
@ -526,18 +526,6 @@ dependencies {
debugImplementation 'com.bytedance.android:shadowhook:1.0.9'
debugImplementation 'io.github.shiqos:wytrace:1.0.1'
if (!gradle.ext.excludeOptionalModules || gradle.ext.enableAccelerator) {
implementation(project(":feature:accelerator"))
}
if (!gradle.ext.excludeOptionalModules || gradle.ext.enableAliPay) {
implementation(project(":feature:ali_pay"))
}
if(!gradle.ext.excludeOptionalModules || gradle.ext.enableWechatPay){
implementation(project(":feature:wechat_pay"))
}
}
File propFile = file('sign.properties')

View File

@ -20,7 +20,6 @@
-keep class com.gh.gamecenter.db.info.* {*;}
-keep class com.gh.gamecenter.entity.** {<fields>;}
-keep class com.gh.gamecenter.qa.entity.** {<fields>;}
-keep class com.gh.gamecenter.gamedetail.entity.** {<fields>;}
-keep class com.gh.download.DownloadDataSimpleEntity {<fields>;}
-keep class com.gh.gamecenter.floatingwindow.FloatingWindowEntity {<fields>;}
-keep class com.gh.gamecenter.BR
@ -77,7 +76,6 @@
### TEA
-keep class com.gh.gamecenter.TeaHelper { *; }
-keep class com.bytedance.ads.convert.broadcast.common.EncryptionTools {*;}
### EasyFloat
-keep class com.lzf.easyfloat.* {*;}

Binary file not shown.

View File

@ -10,9 +10,9 @@
<queries>
<package android:name="com.gh.toolmap" />
<intent>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="ghtoolmap" />
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="ghtoolmap"/>
</intent>
</queries>
@ -71,10 +71,6 @@
<!-- 适配 双开/分身 游戏授权登录 -->
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<!-- 日历 -->
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-sdk tools:overrideLibrary="
com.shuyu.gsyvideoplayer,
com.shuyu.gsyvideoplayer.lib,
@ -201,9 +197,7 @@
android:name="io.sentry.breadcrumbs.system-events"
android:value="false" />
<meta-data
android:name="module_version"
android:value="${VA_VERSION_NAME}" />
<meta-data android:name="module_version" android:value="${VA_VERSION_NAME}" />
<service android:name="com.gh.ndownload.NDownloadService" />
@ -820,10 +814,6 @@
android:name=".video.poster.PosterEditActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.halo.assistant.accelerator.MyAssetsActivity"
android:screenOrientation="portrait" />
<!-- <activity-->
<!-- android:name="${applicationId}.douyinapi.DouYinEntryActivity"-->
<!-- android:launchMode="singleTask"-->

View File

@ -4,7 +4,6 @@ import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.SharedPreferences
import android.graphics.drawable.Animatable
import android.os.Message
import android.text.TextUtils
import android.view.View
@ -14,21 +13,19 @@ import android.widget.TextView
import androidx.appcompat.content.res.AppCompatResources
import androidx.fragment.app.Fragment
import com.therouter.TheRouter
import com.facebook.drawee.controller.BaseControllerListener
import com.facebook.drawee.view.SimpleDraweeView
import com.facebook.imagepipeline.image.ImageInfo
import com.gh.common.exposure.ExposureManager
import com.gh.common.util.DirectUtils.directToLinkPage
import com.gh.common.util.LogUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.NewFlatLogUtils.logOpenScreenAdSkip
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.MainActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.exposure.meta.MetaUtil
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.AppExecutor
@ -62,8 +59,6 @@ object AdDelegateHelper {
private val mGameSearchAdList: ArrayList<AdConfig> by lazy { arrayListOf() }
private var mVGameLaunchAd: AdConfig? = null
private var ownerSplashAdLoadTime = 0L
val vGameLaunchAd: AdConfig?
get() = mVGameLaunchAd
@ -81,7 +76,6 @@ object AdDelegateHelper {
}
var isShowingSplashAd = false // 是否正在显示开屏广告
var isOwnerSplashAdShown = false // 自有开屏广告是否展示
var gameSearchKeyword = ""
fun initAdSdk(context: Context) {
@ -178,15 +172,6 @@ object AdDelegateHelper {
when (config.location) {
"halo_launch" -> {
config.ownerAd?.startAd?.let { it.id = config.ownerAd.id }
// HarmonyOS 2.2.0 版本不展示第三方开屏广告 (因为会引起奇怪的闪退)
// if (MetaUtil.getRom().name == "HarmonyOS"
// && MetaUtil.getRom().versionName == "2.2.0"
// && config.displayRule.adSource == "third_party_ads") {
//
// return
// }
mSplashAd = config
}
@ -317,7 +302,6 @@ object AdDelegateHelper {
) {
val hideCallback = {
isShowingSplashAd = false
isOwnerSplashAdShown = false
hideAction.invoke()
}
if (mSplashAd != null) {
@ -590,8 +574,6 @@ object AdDelegateHelper {
handler: BaseActivity.BaseHandler,
hideCallback: () -> Unit
) {
isOwnerSplashAdShown = false
val jumpBtn = startAdContainer.findViewById<TextView>(R.id.jumpBtn)
val jumpDetailBtn: TextView = startAdContainer.findViewById(R.id.jumpDetailBtn)
val adImage: SimpleDraweeView = startAdContainer.findViewById(R.id.adImage)
@ -610,62 +592,38 @@ object AdDelegateHelper {
)
adImage.visibleIf(true)
ImageUtils.displayWithCallback(adImage, ad.img, true, object : BaseControllerListener<ImageInfo>() {
override fun onSubmit(id: String?, callerContext: Any?) {
super.onSubmit(id, callerContext)
adImage.post {
ownerSplashAdLoadTime = System.currentTimeMillis()
NewFlatLogUtils.logSplashAdLoad(ad.id)
}
}
override fun onFinalImageSet(id: String?, imageInfo: ImageInfo?, animatable: Animatable?) {
isOwnerSplashAdShown = true
adImage.post {
NewFlatLogUtils.logSplashAdShow(ad.id, System.currentTimeMillis() - ownerSplashAdLoadTime)
}
}
override fun onFailure(id: String?, throwable: Throwable?) {
super.onFailure(id, throwable)
NewFlatLogUtils.logSplashAdFail(ad.id, "启动广告图加载失败")
}
})
ImageUtils.display(adImage, ad.img)
if (ad.isImageType) {
adVideo.visibleIf(false)
} else {
adVideo.visibleIf(true)
adVideo.startPlay(ad.video.url)
}
startAdContainer.setOnClickListener {
// 拦截点击事件传递
}
jumpBtn.setOnClickListener {
it.debounceActionWithInterval(1000L) {
if (!isOwnerSplashAdShown) {
NewFlatLogUtils.logSplashAdFail(ad.id, "加载过程中点击跳过广告")
}
handler.removeMessages(MainActivity.COUNTDOWN_AD)
hideCallback.invoke()
val linkEntity = ad.jump
NewFlatLogUtils.logOpenScreenAdSkip(
ad.id,
(if (linkEntity.text != null) linkEntity.text else "")!!,
(if (linkEntity.type != null) linkEntity.type else "")!!,
(if (linkEntity.link != null) linkEntity.link else "")!!
)
SensorsBridge.trackEvent(
"SplashAdOwnSkip",
"splash_ad_id",
ad.id,
"link_type",
linkEntity.type ?: "",
"link_id",
linkEntity.link ?: "",
"link_text",
linkEntity.text ?: ""
)
}
handler.removeMessages(MainActivity.COUNTDOWN_AD)
hideCallback.invoke()
val linkEntity = ad.jump
logOpenScreenAdSkip(
ad.id,
(if (linkEntity.text != null) linkEntity.text else "")!!,
(if (linkEntity.type != null) linkEntity.type else "")!!,
(if (linkEntity.link != null) linkEntity.link else "")!!
)
SensorsBridge.trackEvent(
"SplashAdOwnSkip",
"splash_ad_id",
ad.id,
"link_type",
linkEntity.type ?: "",
"link_id",
linkEntity.link ?: "",
"link_text",
linkEntity.text ?: ""
)
}
val sources: MutableList<ExposureSource> = ArrayList()
sources.add(ExposureSource("开屏广告", ad.id))

View File

@ -19,10 +19,10 @@ import java.net.URLConnection
object AdPluginDownloadHelper : InnerDownloadListener {
private const val CSJ_FILE_NAME = "1832823466"
private const val CSJ_FILE_NAME = "2011394667"
private const val GDT_FILE_NAME = "gdt_plugin/gdtadv2.jar"
private const val CSJ_PLUGIN_URL = "https://and-static.ghzs66.com/android/static/1832823466"
private const val CSJ_PLUGIN_URL = "https://and-static.ghzs66.com/android/static/2011394667"
private const val GDT_PLUGIN_URL = "https://and-static.ghzs66.com/android/static/gdtadv2.jar"
private var csjDownloadedCallback: (() -> Unit)? = null

View File

@ -48,12 +48,6 @@ class SplashAdVideoView @JvmOverloads constructor(
// no nothing
}
override fun onPrepared() {
super.onPrepared()
visibility = VISIBLE
}
override fun onAutoCompletion() {
setStateAndUi(CURRENT_STATE_AUTO_COMPLETE);

View File

@ -2,9 +2,9 @@ package com.gh.base
import android.app.Activity
import android.app.Application
import android.content.res.Configuration
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.therouter.TheRouter
import com.gh.ad.AdDelegateHelper
import com.gh.common.util.FloatingBackViewManager
import com.gh.common.xapk.XapkInstaller
@ -15,45 +15,27 @@ import com.gh.gamecenter.SplashAdActivity
import com.gh.gamecenter.SplashScreenActivity
import com.gh.gamecenter.authorization.AuthorizationActivity
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.provider.IHelpAndFeedbackProvider
import com.gh.gamecenter.common.utils.PackageFlavorHelper
import com.gh.gamecenter.core.provider.IPushProvider
import com.gh.gamecenter.login.utils.QuickLoginHelper
import com.gh.gamecenter.login.view.LoginActivity
import com.gh.gamecenter.va.VCore
import com.gh.gamecenter.login.utils.QuickLoginHelper
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.therouter.TheRouter
// TODO移动到对应的模块
class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
private var isFromBackgroundToForeground = false // 是否后台回到前台
override fun onActivityPreCreated(activity: Activity, savedInstanceState: Bundle?) {
if (QuickLoginHelper.isLoginAuthPage(activity)) {
try {
val resources = activity.resources
val config = Configuration(resources.configuration)
config.fontScale = 1.0f
// 更新Resources配置
val metrics = resources.displayMetrics
metrics.scaledDensity = metrics.density
resources.updateConfiguration(config, metrics)
} catch (e: Exception) {
// 设置字体失败
}
}
}
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
// do nothing
}
override fun onActivityStarted(activity: Activity) {
GlobalActivityManager.currentActivity = activity
GlobalActivityManager.activityCount++
GlobalActivityManager.activityCount ++
if (GlobalActivityManager.activityCount == 1 && isFromBackgroundToForeground) {
if (AdDelegateHelper.shouldShowStartUpAd(true)
&& !HaloApp.getInstance().isDisableSplashAdTemporarily
@ -129,7 +111,7 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
}
override fun onActivityStopped(activity: Activity) {
GlobalActivityManager.activityCount--
GlobalActivityManager.activityCount --
isFromBackgroundToForeground = GlobalActivityManager.activityCount <= 0
}

View File

@ -3,8 +3,6 @@ package com.gh.common
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.util.Base64
import android.view.View
import android.webkit.JavascriptInterface
@ -13,7 +11,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import com.therouter.TheRouter
import com.gh.common.exposure.ExposureManager
import com.gh.common.util.*
import com.gh.common.util.LogUtils
@ -21,12 +19,10 @@ import com.gh.download.DownloadManager
import com.gh.download.PackageObserver
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.ImageViewerActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.common.callback.BiCallback
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.Constants.SP_MEMBER_PAYMENT_BUTTON_CLICK
import com.gh.gamecenter.common.constant.Constants.SP_MEMBER_RECHARGE_BUTTON_CLICK
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.entity.NotificationUgc
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.loghub.LoghubUtils
@ -34,22 +30,20 @@ import com.gh.gamecenter.common.provider.IHelpAndFeedbackProvider
import com.gh.gamecenter.common.tracker.Tracker
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.utils.NewFlatLogUtils
import com.gh.gamecenter.common.utils.SensorsBridge.EVENT_MEMBER_RECHARGE_BUTTON_CLICK
import com.gh.gamecenter.common.utils.SensorsBridge.EVENT_NAME
import com.gh.gamecenter.common.utils.SensorsBridge.KEY_IS_FIRST_TIME
import com.gh.gamecenter.common.view.dsbridge.CompletionHandler
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.provider.IPushProvider
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.entity.SensorsEvent
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.feature.entity.AcctRecordEntity
import com.gh.gamecenter.feature.entity.Badge
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.OrderEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.login.user.LoginTag
import com.gh.gamecenter.login.user.UserManager
@ -61,14 +55,10 @@ import com.gh.gamecenter.personalhome.border.AvatarBorderActivity
import com.gh.gamecenter.setting.SettingBridge
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.halo.assistant.accelerator.repository.AccelerationRepository.Companion.PAYMENT_TYPE_ALIPAY
import com.halo.assistant.accelerator.repository.AccelerationRepository.Companion.PAYMENT_TYPE_WECHAT
import com.halo.assistant.accelerator.repository.AcceleratorDataHolder
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus.*
import com.lightgame.utils.Utils
import com.therouter.TheRouter
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
@ -81,11 +71,10 @@ import java.util.*
class DefaultJsApi(
var context: Context,
val entrance: String = "",
private val mFragment: Fragment? = null,
private var mFragment: Fragment? = null,
private var mBbsId: String? = "",
private var mOriginUrl: String? = "",
private val mForumName: String? = "",
private val listener: OnWebClickListener? = null
) {
companion object {
@ -98,8 +87,6 @@ class DefaultJsApi(
private var mDownloadHandler: CompletionHandler<Any>? = null // 下载信息回调
private var mExposureEvent: ExposureEvent? = null // 活动曝光实体
private val handler = Handler(Looper.getMainLooper())
init {
if (mFragment != null) {
EventBus.getDefault().register(this)
@ -246,12 +233,6 @@ class DefaultJsApi(
VHelper.launch(context, packageName)
}
} else {
val wechatPkgName = "com.tencent.mm"
if (packageName == wechatPkgName && !PackageUtils.isInstalled(context, wechatPkgName)) {
// 如果是微信客户端,需要检查是否安装微信
ToastUtils.showToast(R.string.wechat_app_not_install_tips.toResString())
return@runOnUiThread
}
PackageLauncher.launchApp(context, packageName = packageName)
}
}
@ -514,44 +495,6 @@ class DefaultJsApi(
}
}
@JavascriptInterface
fun saveWechatQRCode(msg: Any) {
val base64StringData = msg.toString()
runOnUiThread {
(context as? FragmentActivity)?.checkStoragePermissionBeforeAction {
runOnIoThread {
val base64String = base64StringData.replace("data:image/png;base64", "")
tryWithDefaultCatch {
val imageFile =
File(HaloApp.getInstance().cacheDir.absolutePath + File.separator + System.currentTimeMillis() + ".png")
val decodedString = Base64.decode(base64String, Base64.DEFAULT)
val bos = BufferedOutputStream(FileOutputStream(imageFile))
bos.write(decodedString)
bos.flush()
bos.close()
ImageUtils.saveImageToFile(imageFile, "", true) {
// 这里是 ui 线程
// 保存微信二维码成功1s 以后跳转微信
if (mFragment != null && mFragment.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
handler.removeCallbacksAndMessages(null)
handler.postDelayed({
val wechatPkgName = "com.tencent.mm"
if (!PackageUtils.isInstalled(context, wechatPkgName)) {
ToastUtils.showToast(R.string.wechat_app_not_install_tips.toResString())
return@postDelayed
}
PackageLauncher.launchApp(context, packageName = wechatPkgName)
}, 1000)
}
}
}
}
}
}
}
@JavascriptInterface
fun loginWithCallback(msg: Any, handler: CompletionHandler<Any>) {
mLoginHandler = handler
@ -756,78 +699,6 @@ class DefaultJsApi(
}
}
@JavascriptInterface
fun preOrderWithAli(json: Any) {
val order = json.toString().toObject<OrderEntity>() ?: return
trackMemberPaymentButtonClick(order, PAYMENT_TYPE_ALIPAY)
listener?.onPreOrderWithAli(order)
}
@JavascriptInterface
fun preOrderWithWechat(json: Any) {
val order = json.toString().toObject<OrderEntity>() ?: return
trackMemberPaymentButtonClick(order, PAYMENT_TYPE_WECHAT)
listener?.onPreOrderWithWechat(order)
}
private fun trackMemberPaymentButtonClick(order: OrderEntity, paymentType: String) {
val isFirstTime = SPUtils.getBoolean(SP_MEMBER_PAYMENT_BUTTON_CLICK, true)
SPUtils.setBoolean(SP_MEMBER_PAYMENT_BUTTON_CLICK, false)
SensorsBridge.trackMemberPaymentButtonClick(
isFirstTime,
paymentType,
order.setMenuName,
order.paymentAmount
)
}
@JavascriptInterface
fun startGameAccelerate(acctJson: Any) {
if (acctJson is String) {
val acctRecord = GsonUtils.fromJson(acctJson, AcctRecordEntity::class.java)
val accInfo = acctRecord.accInfo
listener?.onStartGameAccelerate(accInfo)
}
}
@JavascriptInterface
fun getCurAcctGameId(): String {
return AcceleratorDataHolder.instance.getAcceleratingGameId()
}
@JavascriptInterface
fun stopGameAccelerate() {
listener?.onStopGameAccelerate()
}
@JavascriptInterface
fun refreshToken(token: Any, handler: CompletionHandler<Any>) {
val accessToken = token.toString()
UserManager.getInstance().refreshToken(accessToken, object : UserManager.refreshCallBack {
override fun onLogin() {
handler.complete(true)
}
override fun onLoginFailure(errorMessage: String?) {
handler.complete(false)
}
})
}
@JavascriptInterface
fun trackSensorsAnalytics(json: Any) {
val hashMap = json.toString().toObject<HashMap<String, Any>>() ?: return
val eventName = hashMap.remove(EVENT_NAME) ?: return
when (eventName) {
EVENT_MEMBER_RECHARGE_BUTTON_CLICK -> {
hashMap[KEY_IS_FIRST_TIME] = SPUtils.getBoolean(SP_MEMBER_RECHARGE_BUTTON_CLICK, true)
SPUtils.setBoolean(SP_MEMBER_RECHARGE_BUTTON_CLICK, false)
}
}
SensorsBridge.trackSensorsAnalyticsFromWeb(eventName.toString(), hashMap)
}
/**
* 获取 ExposureEvent可能为空
*/
@ -848,8 +719,6 @@ class DefaultJsApi(
}
EventBus.getDefault().unregister(this@DefaultJsApi)
handler.removeCallbacksAndMessages(null)
}
}
@ -946,15 +815,4 @@ class DefaultJsApi(
}
}
}
interface OnWebClickListener {
fun onPreOrderWithAli(order: OrderEntity)
fun onPreOrderWithWechat(order: OrderEntity)
fun onStartGameAccelerate(accInfo: AcctRecordEntity.AccInfo)
fun onStopGameAccelerate()
}
}

View File

@ -4,7 +4,6 @@ import android.app.Activity
import android.content.Context
import com.gh.common.util.DialogUtils
import com.gh.common.util.DirectUtils
import com.gh.common.util.PackageChangeHelper
import com.gh.common.util.TempCertificationUtils
import com.gh.gamecenter.feature.entity.GameEntity
@ -26,10 +25,6 @@ class LandPageAddressHandler : DownloadChainHandler() {
processEndCallback?.invoke(asVGame, null)
}
} else {
val packageName = gameEntity.getApk().firstOrNull()?.packageName
if (packageName?.isNotEmpty() == true) {
PackageChangeHelper.addInstallPendingPackage(packageName)
}
DirectUtils.directToExternalBrowser(context, gameEntity.landPageAddressDialog!!.link!!)
}
}

View File

@ -8,21 +8,12 @@ import com.gh.gamecenter.feature.entity.GameEntity
class PackageCheckHandler : DownloadChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity, asVGame: Boolean) {
fun nextOrProcessEnd() {
PackageCheckDialogFragment.show((context as AppCompatActivity), gameEntity) {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity, asVGame)
} else {
processEndCallback?.invoke(asVGame, null)
}
}
if (gameEntity.canSpeed) {
nextOrProcessEnd()
} else {
PackageCheckDialogFragment.show((context as AppCompatActivity), gameEntity) {
nextOrProcessEnd()
}
}
}
}

View File

@ -1,10 +1,5 @@
package com.gh.common.databind;
import static com.gh.gamecenter.entity.SubjectEntity.SUBJECT_TAG_SELLING_POINT;
import static com.gh.gamecenter.entity.SubjectEntity.SUBJECT_TAG_TEST;
import static com.gh.gamecenter.entity.SubjectEntity.SUBJECT_TAG_TYPE;
import static com.gh.gamecenter.entity.SubjectEntity.SUBJECT_TAG_UPDATE;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
@ -53,7 +48,6 @@ import com.gh.download.server.BrowserInstallHelper;
import com.gh.gamecenter.DownloadManagerActivity;
import com.gh.gamecenter.R;
import com.gh.gamecenter.WebActivity;
import com.gh.gamecenter.common.databinding.LayoutGameItemSellingPointBinding;
import com.gh.gamecenter.common.entity.LinkEntity;
import com.gh.gamecenter.common.utils.DarkModeUtils;
import com.gh.gamecenter.common.utils.ExtensionsKt;
@ -61,7 +55,6 @@ import com.gh.gamecenter.common.utils.FileUtils;
import com.gh.gamecenter.common.utils.NewFlatLogUtils;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.utils.MtaHelper;
import com.gh.gamecenter.core.utils.TimeUtils;
import com.gh.gamecenter.core.utils.ToastUtils;
import com.gh.gamecenter.feature.entity.ApkEntity;
import com.gh.gamecenter.feature.entity.GameEntity;
@ -208,8 +201,7 @@ public class BindingAdapters {
gameEntity,
traceEvent,
entrance,
location + ":" + gameEntity.getName(),
null);
location + ":" + gameEntity.getName());
return null;
});
final DownloadChainHandler chainHandler = builder.buildHandlerChain();
@ -254,8 +246,7 @@ public class BindingAdapters {
gameEntity,
traceEvent,
entrance,
location + ":" + gameEntity.getName(),
null);
location + ":" + gameEntity.getName());
}
break;
case INSTALL_PLUGIN:
@ -296,7 +287,7 @@ public class BindingAdapters {
});
break;
case RESERVED:
ReservationHelper.showCancelReservationDialog(progressBar.getContext(), gameEntity, () -> {
ReservationHelper.showCancelReservationDialog(progressBar.getContext(),gameEntity, () -> {
ReservationHelper.cancelReservation(gameEntity, () -> {
updateReservation(progressBar, gameEntity);
});
@ -479,37 +470,39 @@ public class BindingAdapters {
}
}
/**
* 包含测试开服标签
*
* @param layout
* @param gameEntity
* @param subjectTag 默认为 “”只有游戏专题可以配置subjectTag
*/
public static void setGameTags(LinearLayout layout, GameEntity gameEntity, String subjectTag) {
// 包含测试开服标签
public static void setGameTags(LinearLayout layout, GameEntity gameEntity) {
try {
if (layout.getVisibility() == View.GONE) return;
ArrayList<TagStyleEntity> tagStyle = new ArrayList<>();
TestEntity test = gameEntity.getTest();
if (test != null && subjectTag.equals(SUBJECT_TAG_TEST)) {
// 显示开测表标签
TagStyleEntity typeTag = new TagStyleEntity();
boolean isDarkModeOn = DarkModeUtils.INSTANCE.isDarkModeOn(layout.getContext());
typeTag.setName(test.getType() != null ? test.getType() : "");
typeTag.setBackground("1AFFA142");
typeTag.setColor(isDarkModeOn ? "EB9238" : "FFA142");
tagStyle.add(typeTag);
TagStyleEntity timeTag = new TagStyleEntity();
if (test.getStartPending()) {
timeTag.setName(test.getStartText());
if (test != null
// 这个判断用于开测表列表
&& !"type_tag".equals(test.getGameTag())) {
if ("custom".equals(test.getGameTag())) {
TagStyleEntity typeTag = new TagStyleEntity();
if (!TextUtils.isEmpty(test.getText())) {
typeTag.setName(test.getText() != null ? test.getText() : "");
} else {
typeTag.setName(test.getType() != null ? test.getType() : "");
}
typeTag.setBackground("E8F3FF");
typeTag.setColor("1383EB");
tagStyle.add(typeTag);
} else {
timeTag.setName(GameViewUtils.getGameTestDate(test.getStart()));
}
timeTag.setBackground("1A06CEA8");
timeTag.setColor(isDarkModeOn ? "07A385" : "06CEA8");
tagStyle.add(timeTag);
TagStyleEntity typeTag = new TagStyleEntity();
boolean isDarkModeOn = DarkModeUtils.INSTANCE.isDarkModeOn(layout.getContext());
typeTag.setName(test.getType() != null ? test.getType() : "");
typeTag.setBackground("1AFFA142");
typeTag.setColor(isDarkModeOn ? "EB9238" : "FFA142");
tagStyle.add(typeTag);
TagStyleEntity timeTag = new TagStyleEntity();
timeTag.setName(GameViewUtils.getGameTestDate(test.getStart()));
timeTag.setBackground("1A06CEA8");
timeTag.setColor(isDarkModeOn ? "07A385" : "06CEA8");
tagStyle.add(timeTag);
}
} else {
tagStyle = gameEntity.getTagStyle();
}
@ -519,59 +512,6 @@ public class BindingAdapters {
}
}
public static void setGameTagsWithSellingPoint(LinearLayout layout, LayoutGameItemSellingPointBinding binding, GameEntity gameEntity, String subjectTag) {
if (subjectTag.equals(SUBJECT_TAG_SELLING_POINT)) {
layout.setVisibility(View.GONE);
binding.getRoot().setVisibility(View.VISIBLE);
GameEntity.SellingPoints sellingPoints = gameEntity.getSellingPoints();
if (sellingPoints != null) {
binding.tvSellingPoints.setVisibility(View.VISIBLE);
binding.tvSellingPoints.setText(sellingPoints.getText());
} else {
binding.tvSellingPoints.setVisibility(View.GONE);
}
Context context = layout.getContext();
binding.gtcvTags.removeAllViews();
ArrayList<TagStyleEntity> tagStyle = gameEntity.getTagStyle();
for (int i = 0; i < tagStyle.size(); i++) {
if (i < 3) {
TextView textView = new TextView(layout.getContext());
textView.setTextColor(ExtensionsKt.toColor(com.gh.gamecenter.common.R.color.text_tertiary, context));
textView.setTextSize(10);
textView.setText((i == 0 ? "" : "·") + tagStyle.get(i).getName());
binding.gtcvTags.addView(textView);
}
}
} else {
layout.setVisibility(View.VISIBLE);
binding.getRoot().setVisibility(View.GONE);
switch (subjectTag) {
case SUBJECT_TAG_UPDATE:
List<TagStyleEntity> updateTags = new ArrayList<>();
TagStyleEntity updateTag = new TagStyleEntity(
"local_generated",
TimeUtils.getFormatTime(gameEntity.getUpdateTime(), "MM-dd") + " 更新",
"",
"1383EB",
"E8F3FF",
"1383EB",
false
);
updateTags.add(updateTag);
GameViewUtils.setLabelList(layout.getContext(), layout, updateTags);
break;
case SUBJECT_TAG_TYPE:
GameViewUtils.setLabelList(layout.getContext(), layout, gameEntity.getTagStyle());
break;
default:
setGameTags(layout, gameEntity, subjectTag);
break;
}
}
}
public static void setVideoDetailGameTags(LinearLayout layout, GameEntity gameEntity) {
try {
ArrayList<TagStyleEntity> tagStyle = new ArrayList<>();

View File

@ -3,6 +3,7 @@ package com.gh.common.dialog
import android.animation.ValueAnimator
import android.content.Context
import android.content.DialogInterface
import android.content.pm.PackageInfo
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@ -18,6 +19,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.DirectUtils
import com.gh.common.util.LogUtils
import com.gh.common.util.PackageHelper
import com.gh.common.util.PackageUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
@ -57,6 +59,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
private val mDuration = 3000
private var mDisposable: Disposable? = null
private var mAdapter: PackageCheckAdapter? = null
private var mAllInstalledPackages = PackageHelper.getInstalledPackageNameList(HaloApp.getInstance().application, 0)
var gameEntity: GameEntity? = null
var callBack: ConfirmListener? = null
@ -192,7 +195,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
if (binding.noRemindAgainCb.isChecked) {
saveRecord(entity)
}
val isAllPackageInstalled = isAllPackageInstalled(entity)
val isAllPackageInstalled = isAllPackageInstalled(mAllInstalledPackages, entity)
if (isAllPackageInstalled) {
mDismissByTouchInside = true
callBack?.onConfirm()
@ -296,7 +299,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
private fun getNotInstalledLink(packageDialogEntity: PackageDialogEntity): LinkEntity? {
val links = LinkedHashSet<LinkEntity>()
packageDialogEntity.detectionObjects.forEach { obj ->
if (!checkDetectionsInstalled(obj.packages)) {
if (!checkDetectionsInstalled(mAllInstalledPackages, obj.packages)) {
obj.assignDownload.forEach {
links.add(packageDialogEntity.links[it])
}
@ -322,8 +325,9 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
override fun onResume() {
super.onResume()
mAllInstalledPackages = PackageHelper.getInstalledPackageNameList(HaloApp.getInstance().application, 0)
gameEntity?.packageDialog?.let {
if (isAllPackageInstalled(it)) {
if (isAllPackageInstalled(mAllInstalledPackages, it)) {
callBack?.onConfirm()
dismissAllowingStateLoss()
}
@ -359,6 +363,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(busFour: EBPackage) {
if (busFour.isInstalledOrUninstalled()) {
mAllInstalledPackages = PackageHelper.getInstalledPackageNameList(HaloApp.getInstance().application, 0)
mAdapter?.notifyDataSetChanged()
}
}
@ -383,7 +388,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
val entity = entities[position]
holder.binding.gameNameTv.text = entity.text
if (position <= index) {
val isAllInstalled = checkDetectionsInstalled(entity.packages)
val isAllInstalled = checkDetectionsInstalled(mAllInstalledPackages, entity.packages)
if (isAllInstalled) {
holder.binding.statusTv.text = "已安装"
holder.binding.statusTv.setTextColor(ContextCompat.getColor(context, com.gh.gamecenter.common.R.color.text_theme))
@ -411,7 +416,8 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
return
}
if (isAllPackageInstalled(packageDialogEntity)) {
val allInstalledPackages = PackageHelper.getInstalledPackageNameList(HaloApp.getInstance().application, 0)
if (isAllPackageInstalled(allInstalledPackages, packageDialogEntity)) {
callBack.onConfirm()
return
}
@ -447,11 +453,13 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
}
private fun checkDetectionsInstalled(
allInstalledPackages: List<String>,
packages: ArrayList<String>
): Boolean {
var isPackagesInstalled = false
packages.forEach { packageName ->
if (PackageUtils.isInstalledFromAllPackage(HaloApp.getInstance(), packageName)) {
val isInstalled = allInstalledPackages.find { it == packageName } != null
if (isInstalled) {
isPackagesInstalled = true
return@forEach
}
@ -461,14 +469,17 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
fun isAllPackageInstalled(
allInstalledPackages: List<String>,
packageDialogEntity: PackageDialogEntity
): Boolean {
var isAllInstalled = true
packageDialogEntity.detectionObjects.forEach loop@{ obj ->
if (!checkDetectionsInstalled(obj.packages)) {
return false
if (!checkDetectionsInstalled(allInstalledPackages, obj.packages)) {
isAllInstalled = false
return isAllInstalled
}
}
return true
return isAllInstalled
}
}
}

View File

@ -16,7 +16,6 @@ import com.gh.common.pop.EditBindWechatPop
import com.gh.common.pop.RealNameTipsPop
import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.entity.WechatConfigEntity
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.common.utils.toObject
@ -84,90 +83,79 @@ class ReserveSuccessReminderDialog(
handlers.clear()
binding.flContentContainer.removeAllViews()
val configTypes = mutableListOf<Int>()
// 短信
if (reserveReminder.hasSmsConfig) {
if (reserveReminder.smsConfig.notice) {
configTypes.add(SMS_REMINDER_ENABLE_TYPE)
} else {
configTypes.add(SMS_REMINDER_UNABLE_TYPE)
}
}
// 微信
if (reserveReminder.wechatConfig.isReminderEnable) {
configTypes.add(WECHAT_REMINDER_ENABLE_TYPE)
} else {
configTypes.add(WECHAT_REMINDER_UNABLE_TYPE)
}
// 日历
if (reserveReminder.hasCalendarConfig) {
if (reserveReminder.calendarConfig.notice) {
configTypes.add(CALENDAR_REMINDER_ENABLE_TYPE)
} else {
configTypes.add(CALENDAR_REMINDER_UNABLE_TYPE)
}
}
if (configTypes.size == 1) {
// 只有微信提醒
if (configTypes.first() == WECHAT_REMINDER_ENABLE_TYPE) {
binding.tvContent.setText(R.string.reverse_success_with_reminder_tips)
handlers.add(
WechatReminderEnableHandler(reserveReminder.wechatConfig, 8.dp, binding.flContentContainer, this)
)
} else {
val smsConfig = reserveReminder.smsConfig
val wechatConfig = reserveReminder.wechatConfig
when {
reserveReminder.onlyShowWechatReminder && !wechatConfig.isReminderEnable -> { // 只显示微信:未开启
binding.tvContent.setText(R.string.reverse_success_without_reminder_tips)
handlers.add(OnlyWechatReminderUnableHandler(16.dp, binding.flContentContainer, this))
arrayListOf(OnlyWechatReminderUnableHandler(16.dp, binding.flContentContainer, this))
}
} else {
binding.tvContent.setText(R.string.reverse_success_with_reminder_tips)
var isLargerSpacing = true
fun getPaddingTop(): Int {
val paddingTop = if (isLargerSpacing) 16.dp else 8.dp
isLargerSpacing = false
return paddingTop
reserveReminder.onlyShowWechatReminder && wechatConfig.isReminderEnable -> { // 只显示微信:已开
binding.tvContent.setText(R.string.reverse_success_with_reminder_tips)
arrayListOf(
WechatReminderEnableHandler(
reserveReminder.wechatConfig.nickName,
8.dp,
binding.flContentContainer,
this
)
)
}
configTypes.sorted().forEach {
when (it) {
SMS_REMINDER_ENABLE_TYPE -> {
isLargerSpacing = true
SmsReminderEnableHandler(reserveReminder.smsConfig, 8.dp, binding.flContentContainer, this)
}
SMS_REMINDER_UNABLE_TYPE -> {
SmsReminderUnableHandler(getPaddingTop(), binding.flContentContainer, this)
}
WECHAT_REMINDER_ENABLE_TYPE -> {
isLargerSpacing = true
WechatReminderEnableHandler(
reserveReminder.wechatConfig,
8.dp,
binding.flContentContainer,
this
)
}
WECHAT_REMINDER_UNABLE_TYPE ->
WechatReminderUnableHandler(getPaddingTop(), binding.flContentContainer, this)
CALENDAR_REMINDER_ENABLE_TYPE -> {
isLargerSpacing = true
CalendarReminderEnableHandler(8.dp, binding.flContentContainer, this)
}
CALENDAR_REMINDER_UNABLE_TYPE ->
CalendarReminderUnableHandler(getPaddingTop(), binding.flContentContainer, this)
else -> null
}?.let(handlers::add)
!smsConfig.notice && !wechatConfig.isReminderEnable -> { // 短信,微信未开启
binding.tvContent.setText(R.string.reverse_success_without_reminder_tips)
arrayListOf(
SmsReminderUnableHandler(16.dp, binding.flContentContainer, this),
WechatReminderUnableHandler(8.dp, binding.flContentContainer, this)
)
}
smsConfig.notice && wechatConfig.isReminderEnable -> {// 短信,微信已开启
binding.tvContent.setText(R.string.reverse_success_with_reminder_tips)
arrayListOf(
SmsReminderEnableHandler(reserveReminder.smsConfig, 8.dp, binding.flContentContainer, this),
WechatReminderEnableHandler(
reserveReminder.wechatConfig.nickName,
8.dp,
binding.flContentContainer,
this
)
)
}
smsConfig.notice && !wechatConfig.isReminderEnable -> { // 短信开启,微信未开启
binding.tvContent.setText(R.string.reverse_success_with_reminder_tips)
arrayListOf(
SmsReminderEnableHandler(smsConfig, 8.dp, binding.flContentContainer, this),
WechatReminderUnableHandler(16.dp, binding.flContentContainer, this)
)
}
!smsConfig.notice && wechatConfig.isReminderEnable -> { // 微信开启,短信未开启
binding.tvContent.setText(R.string.reverse_success_with_reminder_tips)
arrayListOf(
WechatReminderEnableHandler(
wechatConfig.nickName,
8.dp,
binding.flContentContainer,
this
),
SmsReminderUnableHandler(16.dp, binding.flContentContainer, this)
)
}
else -> {
binding.tvContent.setText(R.string.reverse_success_without_reminder_tips)
arrayListOf()
}
}.let {
handlers.clear()
handlers.addAll(it)
}
handlers.forEach {
binding.flContentContainer.addView(it.init())
}
@ -232,14 +220,9 @@ class ReserveSuccessReminderDialog(
listener.changeWechatBinding()
}
override fun updateCalendarReminder() {
listener.updateCalendarReminder()
}
override fun onStart() {
super.onStart()
window?.let {
it.setDimAmount(0.4F)
it.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
val params = it.attributes
params.width = DisplayUtils.dip2px(300F)
@ -261,13 +244,6 @@ class ReserveSuccessReminderDialog(
private val Int.dp: Int
get() = DisplayUtils.dip2px(this.toFloat())
private const val SMS_REMINDER_ENABLE_TYPE = 1
private const val WECHAT_REMINDER_ENABLE_TYPE = 2
private const val CALENDAR_REMINDER_ENABLE_TYPE = 3
private const val SMS_REMINDER_UNABLE_TYPE = 4
private const val WECHAT_REMINDER_UNABLE_TYPE = 5
private const val CALENDAR_REMINDER_UNABLE_TYPE = 6
fun create(context: Context, listener: OnReserveReminderListener) =
ReserveSuccessReminderDialog(
context,
@ -384,7 +360,7 @@ class ReserveSuccessReminderDialog(
}
class WechatReminderEnableHandler(
private val wechatConfig: WechatConfigEntity,
private val nickName: String,
topMargin: Int,
parent: ViewGroup,
listener: OnReserveSuccessListener
@ -404,7 +380,7 @@ class ReserveSuccessReminderDialog(
}.root
override fun initView() {
binding.tvWechat.text = wechatConfig.nickName
binding.tvWechat.text = nickName
binding.vModifyWechat.setOnClickListener {
editWechatPop.showAsDropDown(
binding.ivModifyWechat,
@ -435,51 +411,6 @@ class ReserveSuccessReminderDialog(
}
class CalendarReminderUnableHandler(
topMargin: Int,
parent: ViewGroup,
listener: OnReserveSuccessListener
) : ReminderContentHandler(topMargin, parent, listener) {
private lateinit var binding: LayoutReserveWechatReminderUnableBinding
// 复用微信提醒未开启状态布局
override fun createView(inflater: LayoutInflater) =
LayoutReserveWechatReminderUnableBinding.inflate(inflater, parent, false)
.also {
binding = it
}.root
override fun initView() {
binding.tvWechatReminderTitle.setText(R.string.calendar_reminders)
binding.tvWechatReminderDescription.setText(R.string.calendar_reminders_description)
binding.vWechatAdd.setOnClickListener {
listener.updateCalendarReminder()
}
}
}
class CalendarReminderEnableHandler(
topMargin: Int,
parent: ViewGroup,
listener: OnReserveSuccessListener
) : ReminderContentHandler(topMargin, parent, listener) {
private lateinit var binding: LayoutReserveCalendarReminderUnableBinding
override fun createView(inflater: LayoutInflater) =
LayoutReserveCalendarReminderUnableBinding.inflate(inflater, parent, false)
.also {
binding = it
}.root
override fun initView() {
}
}
}
@ -494,6 +425,4 @@ interface OnReserveSuccessListener {
fun verifyPhoneNumber()
fun changeWechatBinding()
fun updateCalendarReminder()
}

View File

@ -17,7 +17,7 @@ import com.gh.gamecenter.common.entity.ErrorEntity
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.databinding.DialogWechatBindingFailedBinding
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.login.user.UserRepository
import com.lightgame.utils.Utils
class WechatBindingFailedDialogFragment : BaseDialogFragment() {
@ -48,10 +48,10 @@ class WechatBindingFailedDialogFragment : BaseDialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
UserManager.getInstance().userInfoEntity?.let {
currentUserId = it.getShortUserId()
binding.tvCurrentName.text = it.name ?: ""
binding.ivCurrentAvatar.displayAvatar(it.icon)
UserRepository.getInstance().loginUserInfo.observe(viewLifecycleOwner) {
currentUserId = it.data.getShortUserId()
binding.tvCurrentName.text = it.data.name
binding.ivCurrentAvatar.displayAvatar(it.data.icon)
binding.tvUserId.text = getString(R.string.user_id, currentUserId)
}

View File

@ -4,7 +4,6 @@ import android.annotation.SuppressLint
import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.PackageFlavorHelper
import com.gh.gamecenter.common.utils.debounceActionWithInterval
import com.gh.gamecenter.common.utils.toJson
import com.gh.gamecenter.common.utils.toObject
@ -124,16 +123,10 @@ object RegionSettingHelper {
mIsInit = false
}
val fakeIp = if (PackageFlavorHelper.IS_TEST_FLAVOR) {
SPUtils.getString(Constants.SP_TEST_FLAVOR_IP)
} else {
""
}
// 使用默认的 Schdulers.io() 可能会触发 OOM
RetrofitManager.getInstance()
.api
.getRegionSetting(HaloApp.getInstance().channel, fakeIp)
.getRegionSetting(HaloApp.getInstance().channel)
.subscribeOn(Schedulers.io())
.subscribe(object : BiResponse<RegionSetting>() {
override fun onSuccess(data: RegionSetting) {

View File

@ -10,12 +10,16 @@ fun FragmentManager.popBackStackAllowStateLoss() {
fun FragmentManager.popBackStackAllowStateLoss(id: Int, flags: Int) {
if (!isStateSaved) {
popBackStack(id, flags)
} else {
hook { popBackStack(id, flags) }
}
}
fun FragmentManager.popBackStackAllowStateLoss(name: String?, flags: Int) {
if (!isStateSaved) {
popBackStack(name, flags)
} else {
hook { popBackStack(name, flags) }
}
}
@ -25,9 +29,34 @@ fun FragmentManager.popBackStackImmediateAllowStateLoss(id: Int, flags: Int) =
if (!isStateSaved) {
popBackStackImmediate(id, flags)
} else {
false
hook { popBackStackImmediate(id, flags) }
}
fun FragmentManager.popBackStackImmediateAllowStateLoss(name: String?, flags: Int): Boolean =
if (!isStateSaved) {
popBackStackImmediate(name, flags)
} else {
hook { popBackStackImmediate(name, flags) }
}
/**
* 通过反射将FragmentManager的mStateSaved和mStopped设为false否则Activity在回调onSavedInstance以后
* 调用Fragment的popBackStack和popBackStackImmediate方法会触发“java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState”的异常。
* @see <a href="https://sentry.shanqu.cc/organizations/lightgame/issues/418688/?project=22">Sentry-418688</a>
*/
private fun <T> FragmentManager.hook(callback: FragmentManager.() -> T): T {
val mStateSavedField = getField(this::class.java,"mStateSaved")
val stateSaved = mStateSavedField.get(this);
mStateSavedField.set(this, false)
val mStoppedField = getField(this::class.java,"mStopped")
val stopped = mStateSavedField.get(this);
mStoppedField.set(this, false)
val result = callback.invoke(this)
mStateSavedField.set(this, stateSaved)
mStoppedField.set(this, stopped)
return result
}
@Throws(NoSuchFieldException::class)
private fun getField(clazz: Class<*>, name: String): Field {
var cls: Class<*>? = clazz

View File

@ -7,20 +7,19 @@ import androidx.room.TypeConverters
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import com.gh.gamecenter.entity.GamesCollectionEntity
import com.gh.gamecenter.entity.HistoryGameDetailEntity
import com.gh.gamecenter.entity.HistoryGameEntity
import com.gh.gamecenter.entity.MyVideoEntity
import com.gh.gamecenter.feature.entity.NewsEntity
import com.gh.gamecenter.feature.entity.AnswerEntity
import com.gh.gamecenter.feature.entity.ArticleEntity
import com.gh.gamecenter.feature.entity.NewsEntity
import com.gh.gamecenter.feature.room.converter.*
import com.gh.gamecenter.room.converter.*
import com.gh.gamecenter.room.dao.*
import com.halo.assistant.HaloApp
@Database(
entities = [AnswerEntity::class, ArticleEntity::class, NewsEntity::class, HistoryGameEntity::class, MyVideoEntity::class, GamesCollectionEntity::class, HistoryGameDetailEntity::class],
version = 15,
entities = [AnswerEntity::class, ArticleEntity::class, NewsEntity::class, HistoryGameEntity::class, MyVideoEntity::class, GamesCollectionEntity::class],
version = 14,
exportSchema = false
)
@TypeConverters(
@ -54,7 +53,6 @@ abstract class HistoryDatabase : RoomDatabase() {
abstract fun gameDao(): GameDao
abstract fun videoHistoryDao(): VideoHistoryDao
abstract fun gamesCollectionDao(): GamesCollectionDao
abstract fun gameDetailDao(): GameDetailHistoryDao
companion object {
@ -154,12 +152,6 @@ abstract class HistoryDatabase : RoomDatabase() {
}
}
val MIGRATION_14_15: Migration = object : Migration(14, 15) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE HistoryGameDetailEntity (id TEXT NOT NULL PRIMARY KEY, name TEXT DEFAULT '')")
}
}
val instance by lazy {
Room.databaseBuilder(
HaloApp.getInstance().application,
@ -178,7 +170,6 @@ abstract class HistoryDatabase : RoomDatabase() {
.addMigrations(MIGRATION_11_12)
.addMigrations(MIGRATION_12_13)
.addMigrations(MIGRATION_13_14)
.addMigrations(MIGRATION_14_15)
.build()
}
}

View File

@ -44,20 +44,6 @@ object HistoryHelper {
runOnIoThread { tryCatchInRelease { HistoryDatabase.instance.gameDao().addGame(historyGameEntity) } }
}
@JvmStatic
fun insertGameDetail(gameEntity: GameEntity) {
val historyGameDetailEntity = HistoryGameDetailEntity(gameEntity.id, gameEntity.name)
runOnIoThread { tryCatchInRelease { HistoryDatabase.instance.gameDetailDao().addGame(historyGameDetailEntity) } }
}
@JvmStatic
fun getHistoryGameDetailById(id: String): HistoryGameDetailEntity? =
try {
HistoryDatabase.instance.gameDetailDao().getHistoryGameDetailById(id)
} catch (e: Throwable) {
null
}
private fun convertGameUpdateEntityToHistoryGameEntity(updateEntity: GameUpdateEntity): HistoryGameEntity {
val historyGame = HistoryGameEntity()
@ -156,15 +142,6 @@ object HistoryHelper {
}
}
@JvmStatic
fun deleteGameDetailEntity(gameId: String) {
runOnIoThread {
tryCatchInRelease {
HistoryDatabase.instance.gameDetailDao().deleteGame(HistoryGameDetailEntity(id = gameId))
}
}
}
@JvmStatic
fun emptyDatabase() {

View File

@ -1,29 +0,0 @@
package com.gh.common.interceptor
import com.gh.gamecenter.common.constant.RouteConsts
import com.halo.assistant.HaloApp
import com.therouter.router.RouteItem
import com.therouter.router.interceptor.RouterReplaceInterceptor
import com.therouter.router.matchRouteMap
/**
* 主拦截器
*/
class MainInterceptor: RouterReplaceInterceptor() {
override fun replace(routeItem: RouteItem?): RouteItem? {
if (routeItem == null) return null
// 用户是否已经同意隐私政策
val isUserAcceptPrivacyPolicy = HaloApp.isUserAcceptPrivacyPolicy(HaloApp.getInstance())
// 如果用户已经同意隐私政策并且应用已经启动,直接返回 routeItem ,运行跳转
if (isUserAcceptPrivacyPolicy && HaloApp.getInstance().isAlreadyUpAndRunning) {
return routeItem
}
// 指向调整为 SplashScreenActivity
return matchRouteMap(RouteConsts.activity.splashActivity)
}
}

View File

@ -4,10 +4,8 @@ import android.view.View
import android.widget.LinearLayout
import android.widget.TextView
import com.gh.common.databind.BindingAdapters
import com.gh.gamecenter.common.databinding.LayoutGameItemSellingPointBinding
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.provider.IBindingAdaptersProvider
import com.gh.gamecenter.home.custom.adapter.CustomViewExt
@com.therouter.inject.ServiceProvider
class BindingAdaptersProviderImpl : IBindingAdaptersProvider {
@ -20,7 +18,7 @@ class BindingAdaptersProviderImpl : IBindingAdaptersProvider {
}
override fun setGameTags(layout: LinearLayout, gameEntity: GameEntity) {
BindingAdapters.setGameTags(layout, gameEntity, "")
BindingAdapters.setGameTags(layout, gameEntity)
}
override fun setMessageUnread(view: TextView, unreadCount: Int) {
@ -30,17 +28,4 @@ class BindingAdaptersProviderImpl : IBindingAdaptersProvider {
override fun setGame(view: View, gameEntity: GameEntity) {
BindingAdapters.setGame(view, gameEntity)
}
override fun setGameTagsWithSellingPoints(
layout: LinearLayout,
sellingPointsBinding: LayoutGameItemSellingPointBinding,
gameEntity: GameEntity,
subjectTag: String
) {
BindingAdapters.setGameTagsWithSellingPoint(layout, sellingPointsBinding, gameEntity, subjectTag)
}
override fun setGameDescription(tvDesc: TextView, briefStyle: String, game: GameEntity) {
CustomViewExt.setDescription(tvDesc, briefStyle, game)
}
}

View File

@ -2,8 +2,6 @@ package com.gh.common.provider
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.entity.GameUpdateEntity
@ -13,7 +11,6 @@ import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.provider.IDownloadButtonClickedProvider
import com.gh.gamecenter.feature.view.DownloadButton
import com.gh.gamecenter.packagehelper.PackageRepository
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadEntity
import com.lightgame.utils.Utils
@ -30,9 +27,6 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
var packageName = ""
var exposureSourceList: List<ExposureSource>? = null
var customPageTrackData: CustomPageTrackData? = null
val pushMessageId = (HaloApp.get(Constants.PUSH_MESSAGE_ID, false) as? String) ?: ""
val pushLinkId = (HaloApp.get(Constants.PUSH_LINK_ENTITY, false) as? LinkEntity)?.link ?: ""
val isFromPush = pushMessageId.isNotEmpty()
val boundedObject = downloadButton.getObject()
@ -142,9 +136,6 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
"last_page_name", GlobalActivityManager.getLastPageEntity().pageName,
"last_page_id", GlobalActivityManager.getLastPageEntity().pageId,
"last_page_business_id", GlobalActivityManager.getLastPageEntity().pageBusinessId,
"is_from_push_notifications", isFromPush,
"message_id", pushMessageId,
"link_id", pushLinkId,
*customPageKV
)
}

View File

@ -1,23 +0,0 @@
package com.gh.common.provider
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.core.provider.IAcceleratorDataHolderProvider
import com.gh.gamecenter.feature.entity.VipEntity
import com.halo.assistant.accelerator.repository.AcceleratorDataHolder
@com.therouter.inject.ServiceProvider
class IAcceleratorDataHolderProviderImpl : IAcceleratorDataHolderProvider {
override fun setVipEntity(vip: Any) {
if (vip is VipEntity) {
AcceleratorDataHolder.instance.setVipEntity(vip)
}
}
override fun getGhVersionName(): String {
return PackageUtils.getGhVersionName()
}
override fun clear() {
AcceleratorDataHolder.instance.clear()
}
}

View File

@ -7,6 +7,9 @@ import com.gh.gamecenter.feature.provider.IRegionSettingHelperProvider
@com.therouter.inject.ServiceProvider
class RegionSettingHelperProviderImpl : IRegionSettingHelperProvider {
override fun shouldThisGameDisplayMirrorInfo(gameId: String): Boolean {
return RegionSettingHelper.shouldThisGameDisplayMirrorInfo(gameId)
}
override fun getMirrorPosition(gameId: String): Int {
return RegionSettingHelper.getMirrorPosition(gameId)

View File

@ -1,54 +0,0 @@
package com.gh.common.provider
import android.annotation.SuppressLint
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.core.provider.IWechatPayResultProvider
import com.gh.gamecenter.feature.entity.OrderEntity
import com.gh.gamecenter.feature.entity.VipEntity
import com.gh.gamecenter.feature.eventbus.EBPayState
import com.halo.assistant.accelerator.repository.AccelerationRepository
import com.halo.assistant.accelerator.repository.AcceleratorDataHolder
import org.greenrobot.eventbus.EventBus
@com.therouter.inject.ServiceProvider
class WechatPayResultProviderImpl : IWechatPayResultProvider {
private val repository = AccelerationRepository.newInstance()
@SuppressLint("CheckResult")
override fun onPayComplete(nonceStr: String, order: Any?) {
val orderEntity = order as? OrderEntity
repository.getWechatPayResult(nonceStr)
.compose(singleToMain())
.subscribe({
// 支付成功
EventBus.getDefault().post(EBPayState.PaySuccess)
// 先刷新本地状态,支付成功,肯定是付费会员
AcceleratorDataHolder.instance.setVipEntity(
VipEntity(
_vipStatus = true,
_isNewUser = false,
_isTryVip = false
)
)
SensorsBridge.trackMemberRechargeResult(
AccelerationRepository.PAYMENT_TYPE_WECHAT,
orderEntity?.setMenuName ?: "",
orderEntity?.paymentAmount ?: "",
AccelerationRepository.RECHARGE_RESULT_SUCCESS
)
}, {
// 支付失败
EventBus.getDefault().post(EBPayState.PayFail)
SensorsBridge.trackMemberRechargeResult(
AccelerationRepository.PAYMENT_TYPE_WECHAT,
orderEntity?.setMenuName ?: "",
orderEntity?.paymentAmount ?: "",
AccelerationRepository.RECHARGE_RESULT_FAILURE
)
})
}
}

View File

@ -2,7 +2,6 @@ package com.gh.common.util
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.core.utils.TimeUtils
import com.gh.gamecenter.retrofit.RetrofitManager
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
@ -13,18 +12,15 @@ import okhttp3.ResponseBody
object ActivationHelper {
private const val HAS_SENT_ACTIVATED_INFO = "has_sent_activated_info"
private const val SENT_ACTIVATED_INFO_TIME = "sent_activated_info_time"
private const val HAS_SENT_RETENTION_INFO = "has_sent_retention_info"
private var hasSentActivatedInfo = SPUtils.getBoolean(HAS_SENT_ACTIVATED_INFO, false)
private var hasSentRetentionInfo = SPUtils.getBoolean(HAS_SENT_RETENTION_INFO, false)
var mHasSentActivatedInfo = SPUtils.getBoolean(HAS_SENT_ACTIVATED_INFO, false)
/**
* 发送激活信息 (用于推广)
*/
@JvmStatic
fun sendActivationInfo() {
if (!hasSentActivatedInfo) {
if (!mHasSentActivatedInfo) {
RetrofitManager.getInstance()
.api.postActivationInfo()
.subscribeOn(Schedulers.io())
@ -32,36 +28,8 @@ object ActivationHelper {
override fun onResponse(response: ResponseBody?) {
super.onResponse(response)
hasSentActivatedInfo = true
mHasSentActivatedInfo = true
SPUtils.setBoolean(HAS_SENT_ACTIVATED_INFO, true)
SPUtils.setLong(SENT_ACTIVATED_INFO_TIME, System.currentTimeMillis())
}
})
}
}
/**
* 发送次日留存信息 (用于推广)
*/
@JvmStatic
fun sendRetentionInfo() {
if (hasSentActivatedInfo && !hasSentRetentionInfo) {
val activateTimeMillis = SPUtils.getLong(SENT_ACTIVATED_INFO_TIME, 0)
val currentTimeMillis = System.currentTimeMillis()
if (!TimeUtils.isNextDay(activateTimeMillis, currentTimeMillis)) {
return
}
RetrofitManager.getInstance()
.api.postRetentionInfo()
.subscribeOn(Schedulers.io())
.subscribe(object : Response<ResponseBody>() {
override fun onResponse(response: ResponseBody?) {
super.onResponse(response)
hasSentRetentionInfo = true
SPUtils.setBoolean(HAS_SENT_RETENTION_INFO, true)
}
})
}

View File

@ -13,6 +13,7 @@ import com.therouter.TheRouter;
import com.gh.ad.AdDelegateHelper;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.constant.RouteConsts;
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
import com.gh.gamecenter.common.retrofit.BiResponse;
import com.gh.gamecenter.common.utils.SensorsBridge;
@ -111,6 +112,7 @@ public class DataUtils {
try {
HaloApp.getInstance().getContentResolver().insert(Uri.parse("content://com.gh.gamecenter.provider/device"), values);
} catch (Exception exception) {
SentryHelper.INSTANCE.onEvent("DEVICE_INSERT_ERROR", "exception_digest", exception.getLocalizedMessage());
exception.printStackTrace();
}
});
@ -148,7 +150,6 @@ public class DataUtils {
/**
* 获取应用 gid 绑定的实名信息
*/
// TODO 这个方法启动时会被调用多次,后面考虑优化优化
@SuppressLint("CheckResult")
public static void getDeviceCertification(String gid) {
RetrofitManager.getInstance()
@ -195,6 +196,7 @@ public class DataUtils {
// TODO 将 com.gh.gamecenter 改成 BuildConfig.ApplicationID
HaloApp.getInstance().getContentResolver().insert(Uri.parse("content://com.gh.gamecenter.provider/certification"), values);
} catch (Exception exception) {
SentryHelper.INSTANCE.onEvent("CERTIFICATION_INSERT_ERROR", "exception_digest", exception.getLocalizedMessage());
exception.printStackTrace();
}
}

View File

@ -41,8 +41,7 @@ public class DetailDownloadUtils {
/**
* 更新底部下载区域
*
* @param viewHolder 下载区域的包裹
* @param viewHolder 下载区域的包裹
* @param ignoreDownloadEntity 忽略下载实体(往往用于下载异常时)
*/
public static void updateViewHolder(DetailViewHolder viewHolder, boolean ignoreDownloadEntity) {
@ -54,8 +53,6 @@ public class DetailDownloadUtils {
viewHolder.getMultiVersionDownloadTv().setVisibility(View.GONE);
}
viewHolder.setSpeedViewsVisible(false);
// 根据预置的配置更新 ViewHolder 的状态 (譬如青少年模式、下载内容为空等)
if (updateViewHolderWithPredefinedConfig(viewHolder, gameEntity)) {
return;
@ -138,12 +135,6 @@ public class DetailDownloadUtils {
showDualDownloadButton,
downloadEntity
);
if(!showVGame){
String rawBtnText = GameUtils.getDownloadBtnText(viewHolder.getContext(), gameEntity, false, showVGame, PluginLocation.only_game);
viewHolder.checkIfShowSpeedUi(rawBtnText);
}
} else {
// 游戏包含多 APK 的情况
viewHolder.getMultiVersionDownloadTv().setText("选择下载你的版本" + (TextUtils.isEmpty(downloadAddWord) ? "" : "-" + downloadAddWord));
@ -228,7 +219,7 @@ public class DetailDownloadUtils {
downloadButton.setText("");
}
} else {
decoratedBtnText = rawBtnText + (containsAddWord ? "" : downloadAddWord) + getWrappedDownloadSizeText(viewHolder);
decoratedBtnText = rawBtnText + (containsAddWord? "" : downloadAddWord) + getWrappedDownloadSizeText(viewHolder);
if (overlayTv != null && downloadButton.getVisibility() != View.GONE) {
if (context.getString(com.gh.gamecenter.feature.R.string.launch).equals(rawBtnText)
@ -270,7 +261,7 @@ public class DetailDownloadUtils {
viewHolder.getLocalDownloadSizeTv().setVisibility(View.GONE);
String size = viewHolder.getGameEntity().getApk().isEmpty() ? "" : viewHolder.getGameEntity().getApk().get(0).getSize();
if (size != null) {
String sizeWithoutDigit = convertSizeString(size);
String sizeWithoutDigit = size.replaceAll("(?<=\\d)\\.[0-9]+(?!\\d)", "");
viewHolder.getLocalDownloadSizeTv().setText(sizeWithoutDigit);
}
@ -610,30 +601,6 @@ public class DetailDownloadUtils {
return (int) Math.ceil(downloadEntity.getPercent());
}
private static String convertSizeString(String sizeString) {
String numberPart;
String indicator;
// Check if the string ends with "MB"
if (sizeString.endsWith("MB")) {
numberPart = sizeString.substring(0, sizeString.length() - 2);
indicator = "MB";
} else if (sizeString.endsWith("G")) {
numberPart = sizeString.substring(0, sizeString.length() - 1);
indicator = "G";
} else {
return sizeString;
}
// Round number
double number = Double.parseDouble(numberPart);
long roundedNumber = Math.round(number);
// Combine rounded number and size indicator
return roundedNumber + indicator;
}
private static boolean handleDownloadButtonAsXapk(DownloadEntity downloadEntity, DownloadButton downloadButton) {
String xapkStatus = downloadEntity.getMeta().get(XapkInstaller.XAPK_UNZIP_STATUS);

View File

@ -18,7 +18,6 @@ import com.gh.common.exposure.ExposureTraceUtils.appendTrace
import com.gh.common.util.EntranceUtils.jumpActivity
import com.gh.common.util.EntranceUtils.jumpActivityCompat
import com.gh.gamecenter.*
import com.gh.gamecenter.ShellActivity.Type
import com.gh.gamecenter.amway.AmwayActivity
import com.gh.gamecenter.category2.CategoryV2Activity
import com.gh.gamecenter.common.base.activity.BaseActivity
@ -56,7 +55,6 @@ import com.gh.gamecenter.gamecollection.detail.GameCollectionDetailActivity
import com.gh.gamecenter.gamecollection.hotlist.GameCollectionHotListActivity
import com.gh.gamecenter.gamecollection.hotlist.GameCollectionListDetailActivity
import com.gh.gamecenter.gamecollection.square.GameCollectionSquareActivity
import com.gh.gamecenter.gamedetail.entity.GameDetailTabEntity
import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersCalendarActivity
import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersSubscribedGameListActivity
import com.gh.gamecenter.gamedetail.history.HistoryApkListActivity
@ -195,8 +193,6 @@ object DirectUtils {
"simulator",
"teen_mode",
"message_center",
"archive",
"my_assets",
)
fun directToLinkPage(
@ -617,10 +613,6 @@ object DirectUtils {
"message_center" -> directToMessageCenter(0, entrance)
"archive" -> directToCloudArchive(context, linkEntity.link ?: "", linkEntity.text ?: "", "", entrance)
"my_assets" -> navigateToMyAssetsPage(context, entrance)
"" -> {
// do nothing
}
@ -854,42 +846,33 @@ object DirectUtils {
entrance: String? = null,
autoDownload: Boolean? = null,
tab: String? = "",
traceEvent: ExposureEvent? = null,
from: String? = null
traceEvent: ExposureEvent? = null
) {
if (id.isEmpty()) return
val uri = Uri.Builder()
.path(RouteConsts.activity.gameDetailActivity)
.appendQueryParameter(KEY_ENTRANCE, entrance)
.appendQueryParameter(KEY_GAME_ID, id)
.appendQueryParameter(KEY_FROM, from)
.build()
TheRouter
.build(uri.toString())
.fillParams { bundle ->
if (!TextUtils.isEmpty(tab)) {
when (tab) {
"comment" -> bundle.putString(KEY_TARGET, GameDetailTabEntity.TYPE_COMMENT)
"desc" -> bundle.putString(KEY_TARGET, GameDetailTabEntity.TYPE_DETAIL)
"forum" -> bundle.putString(KEY_TARGET, GameDetailTabEntity.TYPE_BBS)
"zone" -> bundle.putString(KEY_TARGET, GameDetailTabEntity.TYPE_ZONE)
}
}
if (traceEvent != null) {
val clickEvent = createEvent(
GameEntity(id = id, name = name),
traceEvent.source,
appendTrace(traceEvent),
ExposureType.CLICK
)
log(clickEvent)
bundle.putParcelable(KEY_TRACE_EVENT, clickEvent)
}
bundle.putBoolean(KEY_AUTO_DOWNLOAD, autoDownload ?: false)
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, GameDetailActivity::class.java.simpleName)
bundle.putString(KEY_GAMEID, id)
if (!TextUtils.isEmpty(tab)) {
when (tab) {
"comment" -> bundle.putString(KEY_TARGET, EntranceConsts.TAB_TYPE_RATING)
"desc" -> bundle.putString(KEY_TARGET, EntranceConsts.TAB_TYPE_DESC)
"forum" -> bundle.putString(KEY_TARGET, EntranceConsts.TAB_TYPE_BBS)
"zone" -> bundle.putString(KEY_TARGET, EntranceConsts.TAB_TYPE_TRENDS)
}
.navigation(context)
}
if (traceEvent != null) {
val clickEvent = createEvent(
GameEntity(id = id, name = name),
traceEvent.source,
appendTrace(traceEvent),
ExposureType.CLICK
)
log(clickEvent)
bundle.putParcelable(KEY_TRACE_EVENT, clickEvent)
}
bundle.putBoolean(KEY_AUTO_DOWNLOAD, autoDownload ?: false)
jumpActivity(context, bundle)
}
/**
@ -920,7 +903,7 @@ object DirectUtils {
bundle.putString(KEY_ENTRANCE, entrance)
bundle.putString(KEY_GAMEID, id)
bundle.putBoolean(KEY_OPEN_VIDEO_STREAMING, true)
bundle.putString(KEY_TARGET, GameDetailTabEntity.TYPE_DETAIL)
bundle.putString(KEY_TARGET, EntranceConsts.TAB_TYPE_DESC)
jumpActivity(context, bundle)
}
@ -928,21 +911,15 @@ object DirectUtils {
fun directToGameDetail(
context: Context,
id: String,
defaultTab: String = GameDetailTabEntity.TYPE_DETAIL,
defaultTab: String = EntranceConsts.TAB_TYPE_DESC,
entrance: String? = null
) {
val uri = Uri.Builder()
.path(RouteConsts.activity.gameDetailActivity)
.appendQueryParameter(KEY_ENTRANCE, entrance)
.appendQueryParameter(KEY_GAME_ID, id)
.build()
TheRouter
.build(uri.toString())
.fillParams { bundle ->
bundle.putString(KEY_TARGET, defaultTab)
}
.navigation(context)
val bundle = Bundle()
bundle.putString(KEY_TO, GameDetailActivity::class.java.name)
bundle.putString(KEY_ENTRANCE, entrance)
bundle.putString(KEY_GAMEID, id)
bundle.putString(KEY_TARGET, defaultTab)
jumpActivity(context, bundle)
}
// 专栏
@ -1592,7 +1569,7 @@ object DirectUtils {
response?.apply {
if (zone.status == "on") {
if (zone.style == "link") {
directToGameDetail(context, gameId, GameDetailTabEntity.TYPE_ZONE, entrance)
directToGameDetail(context, gameId, EntranceConsts.TAB_TYPE_TRENDS, entrance)
} else {
directToWebView(context, url, entrance)
}
@ -1705,7 +1682,7 @@ object DirectUtils {
fun directToHelpAndFeedback(context: Context, bundle: Bundle? = null) {
TheRouter.build(RouteConsts.activity.helpAndFeedbackActivity)
.fillParams {
bundle?.run { it.putAll(this) }
it.putAll(bundle)
}
.navigation(context)
}
@ -2317,32 +2294,4 @@ object DirectUtils {
.withBoolean(KEY_DISPLAY_TYPE, isLogoutStyle)
.navigation()
}
// 跳转云存档详情页
@JvmStatic
fun directToCloudArchive(
context: Context,
gameId: String,
gameName: String,
configUrl: String = "",
entrance: String = ""
) {
val bundle = Bundle()
val gameEntity = GameEntity(id = gameId, name = gameName)
bundle.putParcelable(KEY_GAME_ENTITY, gameEntity)
bundle.putString(KEY_ARCHIVE_CONFIG_URL, configUrl)
bundle.putString(KEY_ENTRANCE, entrance)
bundle.putBoolean(KEY_USE_ALTERNATIVE_LAYOUT, true)
context.startActivity(ShellActivity.getIntent(context, Type.CLOUD_ARCHIVE, bundle))
}
@JvmStatic
fun navigateToMyAssetsPage(context: Context, entrance: String?) {
if (CheckLoginUtils.isLogin()) {
TheRouter.build(RouteConsts.activity.myAssetsActivity).navigation(context)
} else {
CheckLoginUtils.checkLogin(context, entrance, null)
}
}
}

View File

@ -176,8 +176,7 @@ object DownloadItemUtils {
pluginLocation: PluginLocation? = PluginLocation.only_game,
hideDownloadBtnIfNoAvailableContent: Boolean = false,
briefStyle: String? = null,
isShowRecommendStar: Boolean = false,
listener: DownloadButton.OnUpdateListener? = null
isShowRecommendStar: Boolean = false
) {
holder.gameDownloadBtn.putObject(gameEntity)
@ -190,8 +189,7 @@ object DownloadItemUtils {
holder.gameDownloadBtn,
gameEntity,
hideDownloadBtnIfNoAvailableContent,
pluginLocation,
listener
pluginLocation
)
return
}
@ -212,8 +210,7 @@ object DownloadItemUtils {
holder.gameDownloadBtn,
gameEntity,
hideDownloadBtnIfNoAvailableContent,
pluginLocation,
listener
pluginLocation
)
}
@ -222,8 +219,7 @@ object DownloadItemUtils {
downloadBtn: DownloadButton,
gameEntity: GameEntity,
hideDownloadBtnIfNoAvailableContent: Boolean = false,
pluginLocation: PluginLocation? = PluginLocation.only_game,
listener: DownloadButton.OnUpdateListener?
pluginLocation: PluginLocation? = PluginLocation.only_game
) {
// 控制是否显示下载按钮
downloadBtn.goneIf(context.getString(R.string.app_name) == gameEntity.name)
@ -231,7 +227,6 @@ object DownloadItemUtils {
if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE) || gameEntity.isSpecialDownload()) {
downloadBtn.text = "查看"
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.TEENAGER_MODE
listener?.completion(downloadBtn.text)
return
}
if (gameEntity.isReservable) {
@ -244,7 +239,6 @@ object DownloadItemUtils {
buttonStyle = DownloadButton.ButtonStyle.RESERVED
}
}
listener?.completion(downloadBtn.text)
return
}
if (RegionSettingHelper.getGameH5DownloadByGameId(gameEntity.id) != null) {
@ -254,7 +248,6 @@ object DownloadItemUtils {
setBackgroundResource(com.gh.gamecenter.common.R.drawable.download_button_normal_style)
setTextColor(com.gh.gamecenter.common.R.color.white.toColor(context))
}
listener?.completion(downloadBtn.text)
return
}
if (gameEntity.isMiniGame()) {
@ -272,7 +265,6 @@ object DownloadItemUtils {
text = context.getString(com.gh.gamecenter.feature.R.string.quick_play)
}
}
listener?.completion(downloadBtn.text)
return
}
if (gameEntity.getApk().isEmpty() || gameEntity.downloadOffStatus != null) {
@ -304,7 +296,6 @@ object DownloadItemUtils {
downloadBtn.isClickable = false
}
}
listener?.completion(downloadBtn.text)
} else if (gameEntity.getApk().size == 1) {
// 来自于下载管理的实体快照
val entityFromDownloadManager = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
@ -363,60 +354,43 @@ object DownloadItemUtils {
downloadBtn.apply {
when (downloadEntity.status) {
DownloadStatus.done -> {
val xapkStatus = downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS]
when {
downloadEntity.isSimulatorGame() && gameEntity.simulator != null -> {
GameUtils.setDownloadBtnStatus(
context,
gameEntity,
downloadBtn,
pluginLocation,
listener
)
}
isVGamePreferred -> {
buttonStyle =
if (PackagesManager.isCanUpdate(
downloadEntity.gameId,
downloadEntity.packageName,
asVGame = true
)
) {
setText(com.gh.gamecenter.feature.R.string.update)
DownloadButton.ButtonStyle.NORMAL
} else {
setText(com.gh.gamecenter.feature.R.string.launch)
DownloadButton.ButtonStyle.LAUNCH_OR_OPEN
}
listener?.completion(downloadBtn.text)
}
XapkUnzipStatus.SUCCESS.name == xapkStatus && isInstalling(downloadEntity.path) -> {
if (downloadEntity.isSimulatorGame() && gameEntity.simulator != null) {
GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, pluginLocation)
} else if (isVGamePreferred) {
buttonStyle =
if (PackagesManager.isCanUpdate(
downloadEntity.gameId,
downloadEntity.packageName,
asVGame = true
)
) {
setText(com.gh.gamecenter.feature.R.string.update)
DownloadButton.ButtonStyle.NORMAL
} else {
setText(com.gh.gamecenter.feature.R.string.launch)
DownloadButton.ButtonStyle.LAUNCH_OR_OPEN
}
} else {
val xapkStatus = downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS]
if (XapkUnzipStatus.SUCCESS.name == xapkStatus && isInstalling(downloadEntity.path)) {
progress = 100
setText(com.gh.gamecenter.feature.R.string.installing)
buttonStyle = DownloadButton.ButtonStyle.INSTALL_NORMAL
listener?.completion(downloadBtn.text)
return
}
XapkUnzipStatus.UNZIPPING.name == xapkStatus -> {
if (XapkUnzipStatus.UNZIPPING.name == xapkStatus) {
val percent = downloadEntity.meta[XapkInstaller.XAPK_UNZIP_PERCENT]
progress = (java.lang.Float.valueOf(percent) * 10).toInt()
text = "$percent%"
buttonStyle = DownloadButton.ButtonStyle.XAPK_UNZIPPING
listener?.completion(downloadBtn.text)
return
}
XapkUnzipStatus.FAILURE.name == xapkStatus -> {
} else if (XapkUnzipStatus.FAILURE.name == xapkStatus) {
setText(com.gh.gamecenter.feature.R.string.install)
buttonStyle = DownloadButton.ButtonStyle.INSTALL_NORMAL
listener?.completion(downloadBtn.text)
return
}
PackagesManager.isInstalled(downloadEntity.packageName) && !downloadEntity.isUpdate -> {
if (PackagesManager.isInstalled(downloadEntity.packageName) && !downloadEntity.isUpdate) {
// 双下载按钮快速安装时存在已下载的安装包过时,需要重新下载的情况
if (PackagesManager.isCanUpdate(
downloadEntity.gameId,
@ -429,13 +403,9 @@ object DownloadItemUtils {
buttonStyle = DownloadButton.ButtonStyle.LAUNCH_OR_OPEN
setText(com.gh.gamecenter.feature.R.string.launch)
}
listener?.completion(downloadBtn.text)
}
else -> {
} else {
buttonStyle = DownloadButton.ButtonStyle.INSTALL_NORMAL
setText(com.gh.gamecenter.feature.R.string.install)
listener?.completion(downloadBtn.text)
}
}
buttonStyle =
@ -455,24 +425,22 @@ object DownloadItemUtils {
DownloadStatus.overflow -> {
buttonStyle = DownloadButton.ButtonStyle.NORMAL
setText(com.gh.gamecenter.feature.R.string.resume)
listener?.completion(downloadBtn.text)
}
DownloadStatus.cancel -> {
GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, pluginLocation, listener)
GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, pluginLocation)
}
else -> {
// do nothing
listener?.completion(downloadBtn.text)
}
}
}
} else {
GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, pluginLocation, listener)
GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, pluginLocation)
}
} else {
GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, pluginLocation, listener)
GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, pluginLocation)
}
}
@ -542,18 +510,13 @@ object DownloadItemUtils {
DownloadStatus.downloading -> {
if (isMultiVersion) {
holder.gameDownloadBtn.buttonStyle = DownloadButton.ButtonStyle.NORMAL
val darkMode =
(holder.gameDownloadTips?.getTag(com.gh.gamecenter.common.R.string.is_dark_mode_on_id) as? Boolean)
?: false
val darkMode = (holder.gameDownloadTips?.getTag(com.gh.gamecenter.common.R.string.is_dark_mode_on_id) as? Boolean) ?: false
val isDarkModeChanged = DarkModeUtils.isDarkModeOn(context) != darkMode
if (holder.gameDownloadTips?.visibility == View.GONE || holder.gameDownloadTips?.isAnimating == false || isDarkModeChanged) {
holder.gameDownloadTips?.visibility = View.VISIBLE
holder.gameDownloadTips?.setDownloadTipsAnimation(true)
}
holder.gameDownloadTips?.setTag(
com.gh.gamecenter.common.R.string.is_dark_mode_on_id,
DarkModeUtils.isDarkModeOn(context)
)
holder.gameDownloadTips?.setTag(com.gh.gamecenter.common.R.string.is_dark_mode_on_id, DarkModeUtils.isDarkModeOn(context))
} else {
holder.gameDownloadTips?.visibility = View.GONE
holder.gameDownloadBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_NORMAL
@ -655,11 +618,7 @@ object DownloadItemUtils {
}
// 缺省情况下回落到游戏简介
if (TextUtils.isEmpty(briefStyle)
|| briefStyle!!.contains("brief")
|| briefStyle.contains("recommend")
|| briefStyle.contains("test&appointment")
) {
if (TextUtils.isEmpty(briefStyle) || briefStyle!!.contains("brief") || briefStyle.contains("recommend")) {
holder.gameDes?.visibility = View.VISIBLE
} else {
holder.gameDes?.visibility = View.GONE
@ -1002,8 +961,7 @@ object DownloadItemUtils {
traceEvent: ExposureEvent? = null,
refreshCallback: EmptyCallback? = null
) {
val str =
if (downloadBtn is DownloadButton) downloadBtn.text else context.getString(com.gh.gamecenter.feature.R.string.download)
val str = if (downloadBtn is DownloadButton) downloadBtn.text else context.getString(com.gh.gamecenter.feature.R.string.download)
if (gameEntity.getApk().isEmpty()) return
val apk = gameEntity.getApk().safelyGetInRelease(0) ?: return
@ -1022,16 +980,7 @@ object DownloadItemUtils {
addHandler(CheckDownloadHandler())
}
.setProcessEndCallback(gameEntity.id) { asVGame, isSubscribe ->
download(
context,
gameEntity,
downloadBtn,
entrance,
location,
asVGame,
isSubscribe as Boolean,
traceEvent
)
download(context, gameEntity, downloadBtn, entrance, location, asVGame, isSubscribe as Boolean, traceEvent)
}
.buildHandlerChain()
?.handleRequest(context, gameEntity, shouldPerformAsVGame)
@ -1050,16 +999,7 @@ object DownloadItemUtils {
addHandler(CheckDownloadHandler())
}
.setProcessEndCallback(gameEntity.id) { asVGame, isSubscribe ->
download(
context,
gameEntity,
downloadBtn,
entrance,
location,
asVGame,
isSubscribe as Boolean,
traceEvent
)
download(context, gameEntity, downloadBtn, entrance, location, asVGame, isSubscribe as Boolean, traceEvent)
}
.buildHandlerChain()
?.handleRequest(context, gameEntity, shouldPerformAsVGame)
@ -1078,16 +1018,7 @@ object DownloadItemUtils {
addHandler(CheckDownloadHandler())
}
.setProcessEndCallback(gameEntity.id) { asVGame, isSubscribe ->
download(
context,
gameEntity,
downloadBtn,
entrance,
location,
asVGame,
isSubscribe as Boolean,
traceEvent
)
download(context, gameEntity, downloadBtn, entrance, location, asVGame, isSubscribe as Boolean, traceEvent)
}
.buildHandlerChain()
?.handleRequest(context, gameEntity, shouldPerformAsVGame)

View File

@ -14,7 +14,6 @@ import com.gh.gamecenter.common.base.GlobalActivityManager.getLastPageEntity
import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.gamecenter.common.callback.ConfirmListener
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.common.entity.SimpleGameEntity
import com.gh.gamecenter.common.entity.SuggestType
import com.gh.gamecenter.common.eventbus.EBShowDialog
@ -54,7 +53,6 @@ object DownloadObserver {
private const val CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED = "CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED"
private val mRetryableHashMap = hashMapOf<String, Boolean>()
private val mRetryableProgressMap = hashMapOf<String, Long>()
/**
* 当下载任务是 预约上线提醒 触发的,则所有弹窗均不显示
@ -148,8 +146,7 @@ object DownloadObserver {
|| DownloadStatus.timeout == status
) {
if (mRetryableHashMap[downloadEntity.url] == true
&& (NetworkUtils.isWifiConnected(HaloApp.getInstance().application)
|| NDownloadBridge.isDownloadViaTrafficAllowed(downloadEntity))
&& NetworkUtils.isWifiConnected(HaloApp.getInstance().application)
) {
downloadManager.resumeDownload(downloadEntity.url)
mRetryableHashMap[downloadEntity.url] = false
@ -260,7 +257,6 @@ object DownloadObserver {
}
mRetryableHashMap.remove(downloadEntity.url)
mRetryableProgressMap.remove(downloadEntity.url)
EventBus.getDefault().post(EBDownloadStatus("done", "", "", "", downloadEntity.packageName, ""))
}
@ -268,9 +264,7 @@ object DownloadObserver {
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
// 如果已下载大小发生变化,表示成功恢复下载,则重置重试标记
if (status == DownloadStatus.downloading
&& downloadEntity.progress != mRetryableProgressMap[downloadEntity.url]) {
mRetryableProgressMap[downloadEntity.url] = downloadEntity.progress
if (status == DownloadStatus.downloading) {
mRetryableHashMap[downloadEntity.url] = true
}
}
@ -557,10 +551,6 @@ object DownloadObserver {
} else {
arrayOf()
}
val pushMessageId = (HaloApp.get(Constants.PUSH_MESSAGE_ID, false) as? String) ?: ""
val pushLinkId = (HaloApp.get(Constants.PUSH_LINK_ENTITY, false) as? LinkEntity)?.link ?: ""
val isFromPush = pushMessageId.isNotEmpty()
SensorsBridge.trackEventWithExposureSource(
"DownloadProcessFinish",
exposureEvent?.source,
@ -577,9 +567,6 @@ object DownloadObserver {
"last_page_business_id", getLastPageEntity().pageBusinessId,
"download_status", downloadEntity.meta[Constants.DOWNLOAD_STATUS_IN_CHINESE] ?: "",
"download_type", if (downloadEntity.asVGame()) "畅玩下载" else "本地下载",
"is_from_push_notifications", isFromPush,
"message_id", pushMessageId,
"link_id", pushLinkId,
*kvs
)
}

View File

@ -25,10 +25,7 @@ object GameUtils {
/**
* 去除与重复sourceList相同的数据
*/
fun removeDuplicateData(
sourceList: MutableList<GameEntity>?,
rawList: MutableList<GameEntity>?
): MutableList<GameEntity>? {
fun removeDuplicateData(sourceList: MutableList<GameEntity>?, rawList: MutableList<GameEntity>?): MutableList<GameEntity>? {
if (sourceList.isNullOrEmpty() || rawList.isNullOrEmpty()) {
return rawList
}
@ -55,8 +52,7 @@ object GameUtils {
context: Context,
gameEntity: GameEntity,
downloadBtn: DownloadButton,
pluginLocation: PluginLocation?,
listener: DownloadButton.OnUpdateListener? = null
pluginLocation: PluginLocation?
) {
// getDownloadBtnText 里包括查询数据库、根据包名读取包体 meta 信息等
lightWeightIoExecutor.execute {
@ -77,7 +73,6 @@ object GameUtils {
} else {
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.NORMAL
}
listener?.completion(downloadBtn.text)
}
}
}
@ -90,13 +85,11 @@ object GameUtils {
*/
@WorkerThread
@JvmStatic
fun getDownloadBtnText(
context: Context,
gameEntity: GameEntity,
isFromList: Boolean,
fixedAsVGame: Boolean,
pluginLocation: PluginLocation?
): String {
fun getDownloadBtnText(context: Context,
gameEntity: GameEntity,
isFromList: Boolean,
fixedAsVGame: Boolean,
pluginLocation: PluginLocation?): String {
if (gameEntity.getApk().size > 1) {
return ""
}
@ -145,8 +138,7 @@ object GameUtils {
} else if (!isFromList) {
if (!performAsVGame
&& gameEntity.isDualBtnModeEnabled()
&& downloadEntity?.isVGameDownloadInDualDownloadMode() == true
) {
&& downloadEntity?.isVGameDownloadInDualDownloadMode() == true) {
// 下载的任务是由畅玩触发的,并且双下载按钮启用,游戏详情页不需判定为需要安装
downloadEntity = null
} else if (performAsVGame && downloadEntity?.isLocalDownloadInDualDownloadMode() == true) {

View File

@ -14,26 +14,25 @@ import androidx.core.content.ContextCompat;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.LibaoDetailAdapter;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.entity.NotificationUgc;
import com.gh.gamecenter.common.eventbus.EBReuse;
import com.gh.gamecenter.common.retrofit.JSONObjectResponse;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.common.utils.DialogHelper;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.NotificationHelper;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.utils.ToastUtils;
import com.gh.gamecenter.core.utils.UrlFilterUtils;
import com.gh.gamecenter.eventbus.EBUISwitch;
import com.gh.gamecenter.feature.entity.ApkEntity;
import com.gh.gamecenter.feature.entity.LibaoEntity;
import com.gh.gamecenter.feature.entity.LibaoStatusEntity;
import com.gh.gamecenter.feature.entity.MeEntity;
import com.gh.gamecenter.common.entity.NotificationUgc;
import com.gh.gamecenter.feature.entity.UserDataLibaoEntity;
import com.gh.gamecenter.common.eventbus.EBReuse;
import com.gh.gamecenter.eventbus.EBUISwitch;
import com.gh.gamecenter.feature.utils.PlatformUtils;
import com.gh.gamecenter.geetest.GeetestUtils;
import com.gh.gamecenter.login.user.UserManager;
import com.gh.gamecenter.common.retrofit.JSONObjectResponse;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.halo.assistant.HaloApp;
import com.lightgame.utils.Utils;
@ -481,7 +480,7 @@ public class LibaoUtils {
UserDataLibaoEntity me = new UserDataLibaoEntity(libaoCode, "ling", Utils.getTime(context));
initLibaoCode(libaoEntity, me);
if (adapter != null) adapter.initLibaoCode(me);
EventBus.getDefault().post(new EBReuse(Constants.LIBAO_CHANGED_TAG));
EventBus.getDefault().post(new EBReuse("libaoChanged"));
if (listener != null) listener.onLibaoStatusChange();
uploadEvent(libaoEntity, true, entrance);
String des;
@ -621,7 +620,7 @@ public class LibaoUtils {
UserDataLibaoEntity me = new UserDataLibaoEntity(libaoCode, "ling", Utils.getTime(context));
initLibaoCode(libaoEntity, me);
if (listener != null) listener.onLibaoStatusChange();
EventBus.getDefault().post(new EBReuse(Constants.LIBAO_CHANGED_TAG));
EventBus.getDefault().post(new EBReuse("libaoChanged"));
uploadEvent(libaoEntity, false, entrance);
if (adapter != null) {

View File

@ -2778,34 +2778,4 @@ object NewFlatLogUtils {
parseAndPutMeta()(this)
}.let(::log)
}
// 自有开屏广告加载
fun logSplashAdLoad(id: String) {
json {
KEY_EVENT to "splash_ad_load"
"ad_id" to id
parseAndPutMeta()(this)
}.let(::log)
}
// 自有开屏广告展示
fun logSplashAdShow(id: String, duration: Long) {
json {
KEY_EVENT to "splash_ad_show"
"ad_id" to id
"duration" to duration
parseAndPutMeta()(this)
}.let(::log)
}
// 自有开屏广告加载/展示失败
@JvmStatic
fun logSplashAdFail(id: String, error: String) {
json {
KEY_EVENT to "splash_ad_fail"
"ad_id" to id
"error" to error
parseAndPutMeta()(this)
}.let(::log)
}
}

View File

@ -12,7 +12,6 @@ import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.gh.common.constant.Config
import com.gh.download.server.BrowserInstallHelper
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.common.utils.PermissionHelper
@ -25,6 +24,7 @@ import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.entity.WhitePackageListEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.SettingsEntity
import com.gh.gamecenter.feature.utils.SentryHelper
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.packagehelper.PackageRepository
import com.gh.gamecenter.retrofit.RetrofitManager
@ -459,9 +459,6 @@ object PackageHelper {
PackageRepository.initData {
refreshLocalPackageList()
refreshPackageNameList()
// 初始化使用浏览器安装的条件
BrowserInstallHelper.initIfConditionMatched(Config.getNewSettingsEntity())
}
}
@ -581,6 +578,7 @@ object PackageHelper {
Utils.log(TAG, "refreshWrongInstallStatus 检查安装状态异常的应用")
val uninstalledButKeepingWrongStatusPackageNameSet: HashSet<String> = hashSetOf()
val updatedButKeepingWrongStatusPackageNameSet: HashSet<String> = hashSetOf()
for (packageName in packageNameSet) {
val installedVersionName = PackageUtils.getVersionNameByPackageName(packageName)
@ -589,9 +587,18 @@ object PackageHelper {
&& installedVersionName == null
) {
uninstalledButKeepingWrongStatusPackageNameSet.add(packageName)
} else if (PackagesManager.isInstalled(packageName)
&& installedVersionName != null
&& !PackagesManager.isInstalledWithSpecificVersion(packageName, installedVersionName)
) {
updatedButKeepingWrongStatusPackageNameSet.add(packageName)
}
}
Utils.log(
TAG,
"refreshWrongInstallStatus 需要更新已更新状态的包数量为 ${updatedButKeepingWrongStatusPackageNameSet.size}"
)
Utils.log(
TAG,
"refreshWrongInstallStatus 需要移除已安装的包数量为 ${uninstalledButKeepingWrongStatusPackageNameSet.size}"
@ -609,6 +616,12 @@ object PackageHelper {
additionalWhiteListPackageNameSet.toString()
)
}
if (updatedButKeepingWrongStatusPackageNameSet.isNotEmpty()) {
for (packageName in updatedButKeepingWrongStatusPackageNameSet) {
PackageChangeHelper.addUpdate(packageName)
}
}
}
}
}
@ -622,6 +635,7 @@ object PackageHelper {
val installedButKeepingWrongStatusPackageNameSet: HashSet<String> = hashSetOf()
val uninstalledButKeepingWrongStatusPackageNameSet: HashSet<String> = hashSetOf()
val updatedButKeepingWrongStatusPackageNameSet: HashSet<String> = hashSetOf()
for (game in gameEntityList) {
for (apk in game.getApk()) {
@ -637,6 +651,13 @@ object PackageHelper {
&& installedVersionName == null
) {
uninstalledButKeepingWrongStatusPackageNameSet.add(packageName)
} else if (PackagesManager.isInstalled(packageName)
&& installedVersionName != null
&& !PackagesManager.isInstalledWithSpecificVersion(packageName, installedVersionName)
&& !PackagesManager.isCanUpdate(game.id, packageName, false)
) {
cachedPkgNameAndGameEntityMap.put(packageName, game)
updatedButKeepingWrongStatusPackageNameSet.add(packageName)
}
}
}
@ -645,6 +666,10 @@ object PackageHelper {
TAG,
"refreshWrongInstallStatus 需要更新已安装状态的包数量为 ${installedButKeepingWrongStatusPackageNameSet.size}"
)
Utils.log(
TAG,
"refreshWrongInstallStatus 需要更新已更新状态的包数量为 ${updatedButKeepingWrongStatusPackageNameSet.size}"
)
Utils.log(
TAG,
"refreshWrongInstallStatus 需要移除已安装的包数量为 ${uninstalledButKeepingWrongStatusPackageNameSet.size}"
@ -674,6 +699,12 @@ object PackageHelper {
additionalWhiteListPackageNameSet.toString()
)
}
if (updatedButKeepingWrongStatusPackageNameSet.isNotEmpty()) {
for (packageName in updatedButKeepingWrongStatusPackageNameSet) {
PackageChangeHelper.addUpdate(packageName, cachedPkgNameAndGameEntityMap.remove(packageName))
}
}
}
}
}

View File

@ -69,24 +69,18 @@ object PackageInstaller {
val isDownloadAsVGame = downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) == Constants.VGAME
|| downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) == Constants.DUAL_DOWNLOAD_VGAME
val properContext = if (context is AppCompatActivity && !context.isFinishing) {
context
} else {
AppManager.getInstance().currentActivity()
}
properContext ?: return
val currentActivity = AppManager.getInstance().currentActivity() ?: return
if (!ignoreAsVGame && isDownloadAsVGame) {
VHelper.install(properContext, downloadEntity)
VHelper.install(currentActivity, downloadEntity)
return
}
// 已知问题
// 1. 此处可能遇到 activity 是 WXEntryActivity因为 WXEntryActivity 不是 AppCompatActivity 调不起弹窗
// 2. 当 activity 全部出栈,但是应用还在下载游戏,下载完会唤不起安装
if (properContext is AppCompatActivity && !properContext.isFinishing) {
InstallPermissionDialogFragment.show(properContext, downloadEntity) { isFromPermissionGrantedCallback ->
if (currentActivity is AppCompatActivity && !currentActivity.isFinishing) {
InstallPermissionDialogFragment.show(currentActivity, downloadEntity) { isFromPermissionGrantedCallback ->
// 取消状态栏下载完成的通知,若存在
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)

View File

@ -81,11 +81,28 @@ object PackageLauncher {
gameEntity: GameEntity? = null,
packageName: String?
) {
if (packageName.isNullOrEmpty()) {
ToastUtils.toast("启动失败")
return
}
// 获取 GameInstall 实体,用于记录启动日志用
val gameInstall = if (gameEntity != null) {
GameInstall.transformGameInstall(gameEntity, packageName)
} else {
PackagesManager.getInstalledList().find { it.packageName == packageName }
}
if (gameInstall != null) {
NewFlatLogUtils.logGameLaunch(
gameId = gameInstall.id ?: "unknown",
gameName = gameInstall.name ?: "unknown",
gameCategory = gameInstall.category ?: "unknown",
downloadStatus = if (gameInstall.downloadStatus == "demo") "试玩" else "下载"
)
}
try {
val intent = context.applicationContext.packageManager.getLaunchIntentForPackage(packageName)
if (intent != null) {
@ -96,26 +113,6 @@ object PackageLauncher {
} catch (e: Exception) {
ToastUtils.toast( "启动失败")
}
try {
// 获取 GameInstall 实体,用于记录启动日志用
val gameInstall = if (gameEntity != null) {
GameInstall.transformGameInstall(gameEntity, packageName)
} else {
PackagesManager.getInstalledList().find { it.packageName == packageName }
}
if (gameInstall != null) {
NewFlatLogUtils.logGameLaunch(
gameId = gameInstall.id ?: "unknown",
gameName = gameInstall.name ?: "unknown",
gameCategory = gameInstall.category ?: "unknown",
downloadStatus = if (gameInstall.downloadStatus == "demo") "试玩" else "下载"
)
}
} catch (e: RuntimeException) {
// 都 DeadSystemException 了,还想啥日志上报
}
}
}

View File

@ -301,7 +301,7 @@ public class PackageUtils {
Signature[] signatures = packageInfo.signatures;
// 使用幸运破解器破解安卓签名认证可能会出现不用签名也能装的情况,这里有可能是空的
if (signatures.length > 0 && signatures[0] != null) {
if (signatures[0] != null) {
return parseSignature(signatures[0].toByteArray());
} else {
return new String[]{null, null};

View File

@ -95,8 +95,7 @@ object ReservationHelper {
it.categoryChinese,
data.wechatConfig.isReminderEnable,
if (data.hasSmsConfig) data.smsConfig.notice else null,
if (data.isEnableAutoDownload) data.wifiAutoDownload else null,
if (data.hasCalendarConfig) false else null
if (data.isEnableAutoDownload) data.wifiAutoDownload else null
)
}

View File

@ -6,7 +6,6 @@ import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.login.user.UserManager
import com.gh.ndownload.NHttpClient
import com.lightgame.utils.AppManager
import org.json.JSONObject
@ -90,12 +89,4 @@ object TempCertificationUtils {
return stringBuffer.toString()
}
/**
* 检测光环是否实名
*/
fun isUserVerified(): Boolean {
val idCard = UserManager.getInstance().userInfoEntity?.idCard
// 账号已实名
return idCard != null && idCard.status == 0
}
}

View File

@ -32,7 +32,6 @@ import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.ResponseBody
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import java.util.*
@ -230,19 +229,15 @@ object UsageStatsHelper {
mApi.getUsageStatusUpdateTime(HaloApp.getInstance().gid)
.subscribe(object : BiResponse<ResponseBody>() {
override fun onSuccess(data: ResponseBody) {
try {
val body = JSONObject(data.string())
val lastPostTime = body.getLong("update_time") * 1000
val body = JSONObject(data.string())
val lastPostTime = body.getLong("update_time") * 1000
val beginTime = if (lastPostTime == 0L) {
getDefaultBeginTime()
} else {
lastPostTime
}
postUsageStats(beginTime)
} catch (e: JSONException) {
Utils.log("UsageStats: 获取上次上传时间失败,错误信息:${e.message}")
val beginTime = if (lastPostTime == 0L) {
getDefaultBeginTime()
} else {
lastPostTime
}
postUsageStats(beginTime)
}
})
}

View File

@ -19,7 +19,7 @@ import com.gh.gamecenter.game.columncollection.detail.ColumnCollectionDetailFrag
import com.gh.gamecenter.game.commoncollection.detail.CustomCommonCollectionDetailFragment
import com.gh.gamecenter.gamecollection.hotlist.GameCollectionHotListWrapperFragment
import com.gh.gamecenter.gamecollection.square.GameCollectionSquareFragment
import com.gh.gamecenter.gamedetail.GameDetailWrapperFragment
import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.gh.gamecenter.info.InfoWrapperFragment
import com.gh.gamecenter.libao.LibaoDetailFragment
import com.gh.gamecenter.libao.LibaoFragment
@ -88,7 +88,7 @@ object ViewPagerFragmentHelper {
// 游戏详情页
TYPE_GAME -> {
bundle.putString(EntranceConsts.KEY_GAMEID, linkEntity.link)
GameDetailWrapperFragment().with(bundle)
GameDetailFragment().with(bundle)
}
// 我的光环
TYPE_MY_HALO -> {
@ -149,11 +149,11 @@ object ViewPagerFragmentHelper {
NewQuestionDetailFragment().with(bundle)
}
// 其他原来带Toolbar的Fragment
else -> createToolbarWrapperFragment(bundle, linkEntity, isTabWrapper)
else -> createToolbarWrapperFragment(parentFragment, bundle, linkEntity, isTabWrapper)
}
}
private fun createToolbarWrapperFragment(bundle: Bundle, entity: LinkEntity, isTabWrapper: Boolean): Fragment {
private fun createToolbarWrapperFragment(parentFragment: Fragment?, bundle: Bundle, entity: LinkEntity, isTabWrapper: Boolean): Fragment {
var className = ReloadFragment::class.java.name
when (entity.type) {

View File

@ -32,7 +32,6 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
private var mLastItemWidth = 0//最后更多按钮宽度
private var mTotalWidth = 0
private var mStrokeWidth = 0
private var mShowMore = true
var onClickListener: OnItemClickListener? = null
init {
@ -45,12 +44,11 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
mTextSize = ta.getDimension(R.styleable.FlexLinearLayout_itemTextSize, 10F.sp2px().toFloat())
mLastItemWidth = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_lastItemWidth, 18F.dip2px())
mStrokeWidth = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_strokeWidth, 0.5F.dip2px())
mShowMore = ta.getBoolean(R.styleable.FlexLinearLayout_showMore, true)
ta.recycle()
}
fun setTags(tags: List<TagStyleEntity>) {
fun setTags(tags: ArrayList<TagStyleEntity>) {
mTags.clear()
mTotalCount = tags.size
mTotalWidth = measuredWidth
@ -88,7 +86,7 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
mTags.forEachIndexed { index, tag ->
addView(createView(tag, index))
}
if (mShowMore && mTotalCount != mTags.size) {
if (mTotalCount != mTags.size) {
val imageView = ImageView(context).apply {
val params = LayoutParams(mLastItemWidth, mItemHeight)
layoutParams = params

View File

@ -3,15 +3,9 @@ package com.gh.common.xapk
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.DocumentsContract
import android.provider.Settings
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.documentfile.provider.DocumentFile
import com.gh.common.constant.Config
import com.gh.common.util.DirectUtils
import com.gh.common.util.DownloadNotificationHelper
@ -30,7 +24,6 @@ import com.gh.gamecenter.xapk.core.XApkUnZipCallback
import com.gh.gamecenter.xapk.core.XApkUnZipEntry
import com.gh.gamecenter.xapk.core.XApkUnZipOutputFactory
import com.gh.gamecenter.xapk.io.NonSplitApksOutput
import com.gh.gamecenter.xapk.io.OBBDocOutput
import com.gh.gamecenter.xapk.io.OBBFileOutput
import com.gh.gamecenter.xapk.io.SplitApksOutput
import com.gh.gamecenter.xapk.io.XApkFileOutput
@ -41,8 +34,6 @@ import com.lightgame.download.DownloadEntity
import com.lightgame.utils.Utils
import java.io.File
import java.util.*
import androidx.core.net.toUri
import com.gh.gamecenter.core.utils.SPUtils
/**
* 目前已知的Xapk内容是:只有一个apk包和一个或做多个obb数据包(多余文件不解压,如果存在多个apk包,则以下安装无效)
@ -74,10 +65,6 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
systemMatched && fileListMatched
}
// 是否使用 DocumentUi 的方式访问 obb 文件夹
private var useDocStyleToUnzip = false
private var tempLauncher: ActivityResultLauncher<Uri>? = null
private const val GUIDE_TYPE_MIUI_OPTIMIZATION = "miui_optimization"
private const val MIUI_OPTIMIZATION_WARNING_DIALOG_ENTRANCE = "MIUI优化关闭提示弹窗"
@ -134,39 +121,13 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
}
PermissionHelper.checkManageAllFilesOrStoragePermissionBeforeAction(context) {
val unzipAction = {
DownloadManager.getInstance().getDownloadEntitySnapshot(downloadEntity.url, downloadEntity.gameId)
?.let {
unzipXapkFile(it)
if (showUnzipToast) {
Utils.toast(mContext, "解压过程请勿退出光环助手!")
}
DownloadManager.getInstance().getDownloadEntitySnapshot(downloadEntity.url, downloadEntity.gameId)
?.let {
unzipXapkFile(it)
if (showUnzipToast) {
Utils.toast(mContext, "解压过程请勿退出光环助手!")
}
}
// XAPK (apks) 格式,不在乎 obb 文件夹是否可读
if (downloadEntity.format == Constants.XAPK_APKS_FORMAT) {
unzipAction.invoke()
return@checkManageAllFilesOrStoragePermissionBeforeAction
}
// 以 file 的方式访问 obb 文件夹是否可行
val isFileStyleObbFolderReadable =
if (systemHasFlaw) {
File(Environment.getExternalStorageDirectory().path, "\u200bAndroid/obb").list() != null
} else {
File(Environment.getExternalStorageDirectory().path, "Android/obb").list() != null
}
// 如果是文件夹风格的 obb 文件夹可读,或当前上下文不是 AppCompatActivity或当前上下文已经被销毁则直接解压
if (isFileStyleObbFolderReadable
|| context !is AppCompatActivity
|| context.isFinishing
) {
unzipAction.invoke()
} else {
unzipWithCulpritHandled(context, downloadEntity.url, unzipAction)
}
}
} else {
throwExceptionInDebug("如果是Apk包请使用PackageInstaller进行安装")
@ -174,82 +135,6 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
}
}
/**
* 兜底解压方案,适用于一些奇葩系统
*/
private fun unzipWithCulpritHandled(activity: AppCompatActivity, xApkUrl: String, unzipAction: () -> Unit?) {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R
|| Build.VERSION.SDK_INT == Build.VERSION_CODES.S
) {
val isDocStyleObbFolderReadable = isDocStyleObbFolderReadable(activity)
if (isDocStyleObbFolderReadable) {
useDocStyleToUnzip = true
unzipAction.invoke()
} else {
DialogHelper.showDialog(
context = activity,
title = "安装提示",
content = "为了安装 XAPK 文件,请授予 OBB 文件夹的访问权限",
confirmText = "确定",
cancelText = "取消",
confirmClickCallback = {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
intent.setFlags(
Intent.FLAG_GRANT_READ_URI_PERMISSION
and Intent.FLAG_GRANT_WRITE_URI_PERMISSION
and Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
and Intent.FLAG_GRANT_PREFIX_URI_PERMISSION
)
val obbUri = OBBDocOutput.ANDROID_OBB_DOC_STYLE_URI.toUri()
val df = DocumentFile.fromTreeUri(activity, obbUri)
if (df != null) {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, df.uri)
}
tempLauncher =
activity.registerActivityResultLauncher(ActivityResultContracts.OpenDocumentTree()) { uri ->
if (uri != null) {
activity.contentResolver.takePersistableUriPermission(
uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
useDocStyleToUnzip = true
unzipAction.invoke()
}
tempLauncher?.unregister()
}
tempLauncher?.launch(obbUri)
},
cancelClickCallback = {
unzipAction.invoke()
}
)
}
} else {
PermissionHelper.checkStoragePermissionBeforeAction(activity) {
// 设备大于 12需要重启才能生效 (是的,我们又重启了!)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// 记录应用重启前需要重解压的信息
SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, activity.javaClass.name)
SPUtils.setString(Constants.SP_XAPK_URL, xApkUrl)
val pm = activity.packageManager
val intent = pm.getLaunchIntentForPackage(activity.packageName)
val mainIntent = Intent.makeRestartActivityTask(intent!!.component)
activity.startActivity(mainIntent)
Runtime.getRuntime().exit(0)
} else {
unzipAction.invoke()
}
}
}
}
private fun unzipXapkFile(downloadEntity: DownloadEntity) {
mXApkUnZipper.unzip(
XApkUnZipEntry(
@ -306,14 +191,21 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
NDataChanger.notifyDataChanged(downloadEntity)
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
// 仅官网渠道上报 XAPK 异常信息
if (HaloApp.getInstance().channel == "GH_206") {
SentryHelper.onEvent(
"XAPK_UNZIP_ERROR",
"gameName", downloadEntity.name,
"errorDigest", exception.localizedMessage
)
}
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk解压失败")
SensorsBridge.trackGameDecompressionFailed(
downloadEntity.gameId,
downloadEntity.name,
downloadEntity.categoryChinese,
exception.localizedMessage ?: "unknown error"
downloadEntity.categoryChinese
)
}
@ -432,7 +324,7 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
}
override fun onCreateOBBOutput(apk: XApkFile): XApkFileOutput<Unit> {
return if (useDocStyleToUnzip) OBBDocOutput(mContext) else OBBFileOutput()
return OBBFileOutput()
}
override fun onCreateApkOutput(apk: XApkFile): XApkFileOutput<IPackageInstaller> {
@ -448,16 +340,6 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
}
}
/**
* 是否能以 DocumentUi 的方式访问 obb 文件夹
*/
private fun isDocStyleObbFolderReadable(context: Context): Boolean {
return context
.contentResolver
.persistedUriPermissions
.any { it.uri == OBBDocOutput.ANDROID_OBB_URI.toUri() }
}
private class SplitApksInstaller(
private val xApkFile: XApkFile,
private val sessionId: Int,
@ -469,12 +351,7 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
mPendingSessionInfoMap[downloadEntity.path] = XapkPendingSessionInfo(downloadEntity.path, sessionId)
AppExecutor.ioExecutor.execute {// 有可能卡顿造成anr
PackageInstaller.installMultiple(
applicationContext,
downloadEntity.packageName,
downloadEntity.path,
sessionId
)
PackageInstaller.installMultiple(applicationContext, downloadEntity.packageName, downloadEntity.path, sessionId)
NDataChanger.notifyDataChanged(downloadEntity)
}
}

View File

@ -17,6 +17,15 @@ import androidx.collection.ArrayMap;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import com.gh.gamecenter.common.base.GlobalActivityManager;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.core.GHThreadFactory;
import com.gh.gamecenter.feature.entity.TagStyleEntity;
import com.gh.gamecenter.feature.entity.CustomPageTrackData;
import com.gh.gamecenter.feature.exposure.ExposureEvent;
import com.gh.common.exposure.ExposureUtils;
import com.gh.common.history.HistoryHelper;
import com.gh.common.simulator.SimulatorGameManager;
@ -27,17 +36,10 @@ import com.gh.common.util.LunchType;
import com.gh.common.util.PackageInstaller;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.common.base.GlobalActivityManager;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.entity.LinkEntity;
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
import com.gh.gamecenter.common.utils.DeviceUtils;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.FileUtils;
import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.core.GHThreadFactory;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.PageSwitchDataHelper;
import com.gh.gamecenter.core.utils.SPUtils;
@ -46,11 +48,8 @@ import com.gh.gamecenter.entity.GameUpdateEntity;
import com.gh.gamecenter.entity.HomePluggableFilterEntity;
import com.gh.gamecenter.eventbus.EBDownloadStatus;
import com.gh.gamecenter.feature.entity.ApkEntity;
import com.gh.gamecenter.feature.entity.CustomPageTrackData;
import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.feature.entity.PluginLocation;
import com.gh.gamecenter.feature.entity.TagStyleEntity;
import com.gh.gamecenter.feature.exposure.ExposureEvent;
import com.gh.gamecenter.feature.utils.SentryHelper;
import com.gh.gamecenter.login.user.UserManager;
import com.gh.gamecenter.manager.PackagesManager;
@ -452,15 +451,8 @@ public class DownloadManager implements DownloadStatusListener {
trackDownloadType = "本地下载";
}
String pushMessageId = HaloApp.get(Constants.PUSH_MESSAGE_ID, false) instanceof String
? (String) HaloApp.get(Constants.PUSH_MESSAGE_ID, false)
: "";
String pushLinkId = HaloApp.get(Constants.PUSH_LINK_ENTITY, false) instanceof LinkEntity
? ((LinkEntity) HaloApp.get(Constants.PUSH_LINK_ENTITY, false)).getLink()
: "";
boolean isFromPush = !pushMessageId.isEmpty();
Object[] arrayKv = {
String[] arrayKv = {
"game_id", gameEntity.getId(),
"game_name", gameEntity.getName(),
"game_type", gameEntity.getCategoryChinese(),
@ -473,19 +465,16 @@ public class DownloadManager implements DownloadStatusListener {
"last_page_id", GlobalActivityManager.getLastPageEntity().getPageId(),
"last_page_business_id", GlobalActivityManager.getLastPageEntity().getPageBusinessId(),
"download_status", gameEntity.getDownloadStatusChinese(),
"download_type", trackDownloadType,
"is_from_push_notifications", isFromPush,
"message_id", pushMessageId,
"link_id", pushLinkId,
"download_type", trackDownloadType
};
List<Object> kvs = new ArrayList<>(Arrays.asList(arrayKv));
List<String> kvs = new ArrayList<>(Arrays.asList(arrayKv));
if (customPageTrackData != null) {
kvs.addAll(Arrays.asList(customPageTrackData.toKV()));
}
SensorsBridge.trackEventWithExposureSource("DownloadProcessBegin",
downloadExposureEvent.getSource(), kvs.toArray(new Object[0])
downloadExposureEvent.getSource(), kvs.toArray(new String[0])
);
//TODO remove
@ -1307,7 +1296,7 @@ public class DownloadManager implements DownloadStatusListener {
getInstance().packageExecutor.execute(() -> {
boolean markHasChanged = false;
List<GameUpdateEntity> updates = PackageRepository.INSTANCE.getGameUpdate();
ArrayList<GameUpdateEntity> updates = PackageRepository.INSTANCE.getGameUpdate();
for (GameUpdateEntity update : updates) {
if (update == null) continue;
String mark = update.getId() + update.getPackageName();
@ -1328,7 +1317,7 @@ public class DownloadManager implements DownloadStatusListener {
* 将可用更新标记为已读的事件
*/
public void saveUpdateMarkToStorage() {
List<GameUpdateEntity> updates = PackageRepository.INSTANCE.getGameUpdate();
ArrayList<GameUpdateEntity> updates = PackageRepository.INSTANCE.getGameUpdate();
if (updates.size() == mUpdateMarks.size()) {
SPUtils.setStringSet(UPDATE_IS_READ_MARK, mUpdateMarks);
return;

View File

@ -15,8 +15,7 @@ import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.*
import androidx.recyclerview.widget.RecyclerView.SmoothScroller
import com.gh.common.util.DialogUtils
import com.gh.common.util.DirectUtils
import com.gh.common.util.*
import com.gh.download.DownloadManager
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.R
@ -31,9 +30,9 @@ import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.utils.TimeElapsedHelper
import com.gh.gamecenter.databinding.DialogDownloadBinding
import com.gh.gamecenter.entity.GamePlatform
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.feature.entity.ApkEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.halo.assistant.HaloApp
import com.lightgame.download.DataWatcher
@ -71,8 +70,6 @@ class DownloadDialog : BaseDraggableDialogFragment() {
private var mEntrance: String = "" // 入口位置
private var mLocation: String = "" // 最终位置
private var onDownloadClickAction: ((Boolean) -> Unit)? = null
private val mDataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
@ -125,7 +122,7 @@ class DownloadDialog : BaseDraggableDialogFragment() {
}
mViewModel.listLiveData.observeNonNull(this, callback = { itemList ->
mAdapter =
DownloadDialogAdapter(requireContext(), mViewModel, itemList, false, mTraceEvent, mEntrance, mLocation, onDownloadClickAction)
DownloadDialogAdapter(requireContext(), mViewModel, itemList, false, mTraceEvent, mEntrance, mLocation)
mBinding.contentList.layoutManager = createLayoutManager(itemList)
mBinding.contentList.adapter = mAdapter
performAutoDownload(itemList, mBinding.contentList)
@ -164,8 +161,7 @@ class DownloadDialog : BaseDraggableDialogFragment() {
true,
mTraceEvent,
mEntrance,
mLocation,
onDownloadClickAction
mLocation
)
mBinding.collectionList.layoutManager = createLayoutManager(itemList)
mBinding.collectionList.adapter = mCollectionAdapter
@ -430,8 +426,7 @@ class DownloadDialog : BaseDraggableDialogFragment() {
gameEntity: GameEntity,
traceEvent: ExposureEvent?,
entrance: String?,
location: String?,
onDownloadClickAction: ((Boolean) -> Unit)? = null
location: String?
) {
val fragmentActivity: FragmentActivity = if (context is FragmentActivity) {
context
@ -457,7 +452,6 @@ class DownloadDialog : BaseDraggableDialogFragment() {
bundle.putParcelable(EntranceConsts.KEY_TRACE_EVENT, traceEvent)
arguments = bundle
}
downloadDialog.onDownloadClickAction = onDownloadClickAction
downloadDialog.show(fragmentActivity.supportFragmentManager, DownloadDialog::class.java.name)
}

View File

@ -24,8 +24,7 @@ class DownloadDialogAdapter(
val isCollectionPage: Boolean,
private val mTraceEvent: ExposureEvent?,
private val mEntrance: String,
private val mLocation: String,
private val onDownloadClickAction: ((Boolean) -> Unit)? = null
private val mLocation: String
) : BaseRecyclerAdapter<RecyclerView.ViewHolder>(context) {
private val mPath = if (isCollectionPage) {
@ -171,8 +170,7 @@ class DownloadDialogAdapter(
mTraceEvent,
mEntrance,
mPath,
mLocation,
onDownloadClickAction
mLocation
)
}
}

View File

@ -41,8 +41,7 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
traceEvent: ExposureEvent?,
entrance: String,
path: String,
location: String,
onDownloadClickAction: ((Boolean) -> Unit)? = null
location: String
) {
val apkEntity = listData[position].normal!!
@ -182,7 +181,7 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
}
}
setDownloadClickListener(itemView, apkEntity, viewModel, traceEvent, entrance, path, location, onDownloadClickAction)
setDownloadClickListener(itemView, apkEntity, viewModel, traceEvent, entrance, path, location)
}
private fun changeRecommendUI(apkEntity: ApkEntity, listData: List<DownloadDialogItemData>, position: Int) {
@ -227,8 +226,7 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
traceEvent: ExposureEvent?,
entrance: String,
path: String,
location: String,
onDownloadClickAction: ((Boolean) -> Unit)? = null
location: String
) {
val gameEntity = viewModel.gameEntity
@ -236,7 +234,6 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
when (itemView.getTag(DownloadDialogAdapter.ITEM_TAG_KEY)) {
DownloadDialogItemStatus.DOWNLOAD -> {
createDownloadTask(it.context, apkEntity, gameEntity, traceEvent, entrance, location)
onDownloadClickAction?.invoke(false)
}
DownloadDialogItemStatus.LAUNCH -> {
PackageLauncher.launchApp(it.context, gameEntity, apkEntity.packageName)
@ -294,7 +291,6 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
}
DownloadDialogItemStatus.UPDATE -> {
createDownloadTask(it.context, apkEntity, gameEntity, traceEvent, entrance, location)
onDownloadClickAction?.invoke(true)
}
DownloadDialogItemStatus.COLLECTION -> {
val apkCollection = apkEntity.apkCollection

View File

@ -3,7 +3,6 @@ package com.gh.download.server
import android.content.Context
import android.os.Build
import android.util.Base64
import androidx.annotation.WorkerThread
import com.gh.common.constant.Config
import com.gh.common.util.DirectUtils
import com.gh.common.util.LogUtils
@ -247,19 +246,6 @@ object BrowserInstallHelper {
}
}
/**
* 初始化是否满足开启浏览器安装的条件(后续会使用缓存来判断)
* @param settingsEntity 服务器返回的配置
*
* 因为可能需要查询已安装的应用,所以需要在子线程中调用
*/
@WorkerThread
fun initIfConditionMatched(settingsEntity: NewSettingsEntity?) {
settingsEntity?.let {
isConditionMatched(it)
}
}
/**
* 是否满足开启浏览器安装的条件
*/

View File

@ -5,10 +5,15 @@ import android.content.ContextWrapper
import android.content.Intent
import android.os.Bundle
import android.view.View
import com.therouter.router.Autowired
import com.therouter.router.Route
import com.therouter.TheRouter
import com.gh.base.DownloadToolbarActivity
import com.gh.common.exposure.ExposureManager
import com.gh.common.exposure.ExposureTraceUtils.appendTrace
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.base.activity.ToolBarActivity.NORMAL_FRAGMENT_BUNDLE
import com.gh.gamecenter.common.base.activity.ToolBarActivity.NORMAL_FRAGMENT_NAME
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.utils.toArrayList
@ -19,11 +24,7 @@ import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureEvent.Companion.createEvent
import com.gh.gamecenter.feature.exposure.ExposureType
import com.gh.gamecenter.gamedetail.GameDetailWrapperFragment
import com.gh.gamecenter.gamedetail.entity.GameDetailTabEntity
import com.therouter.TheRouter
import com.therouter.router.Autowired
import com.therouter.router.Route
import com.gh.gamecenter.gamedetail.GameDetailFragment
@Route(
path = RouteConsts.activity.gameDetailActivity,
@ -73,11 +74,11 @@ class GameDetailActivity : DownloadToolbarActivity() {
generateDataFromRoute()
super.onCreate(savedInstanceState)
DisplayUtils.setStatusBarColor(this, com.gh.gamecenter.common.R.color.transparent, !mIsDarkModeOn)
DisplayUtils.transparentStatusBar(this)
}
override fun provideNormalIntent(): Intent {
return getTargetIntent(this, GameDetailActivity::class.java, GameDetailWrapperFragment::class.java)
return getTargetIntent(this, GameDetailActivity::class.java, GameDetailFragment::class.java)
}
override fun getLayoutId() = R.layout.activity_game_detail
@ -114,6 +115,7 @@ class GameDetailActivity : DownloadToolbarActivity() {
view,
listOf(
R.id.menu_download_iv,
R.id.gameBigEvent,
R.id.cardContainer,
R.id.iv_reserve,
R.id.iv_concern,
@ -125,15 +127,10 @@ class GameDetailActivity : DownloadToolbarActivity() {
private fun generateDataFromRoute() {
val bundle = intent.extras
intent?.putExtra(NORMAL_FRAGMENT_NAME, GameDetailWrapperFragment::class.java.canonicalName)
intent?.putExtra(NORMAL_FRAGMENT_NAME, GameDetailFragment::class.java.canonicalName)
intent?.putExtra(NORMAL_FRAGMENT_BUNDLE, bundle)
}
override fun onDarkModeChanged() {
super.onDarkModeChanged()
DisplayUtils.setStatusBarColor(this, com.gh.gamecenter.common.R.color.transparent, !mIsDarkModeOn)
}
companion object {
@JvmStatic
@ -193,12 +190,12 @@ class GameDetailActivity : DownloadToolbarActivity() {
}
if (scrollToLibao) {
bundle.putString(EntranceConsts.KEY_TARGET, GameDetailTabEntity.TYPE_DETAIL)
bundle.putString(EntranceConsts.KEY_TARGET, EntranceConsts.TAB_TYPE_DESC)
bundle.putBoolean(EntranceConsts.KEY_SCROLL_TO_LIBAO, true)
}
if (scrollToServer) {
bundle.putString(EntranceConsts.KEY_TARGET, GameDetailTabEntity.TYPE_DETAIL)
bundle.putString(EntranceConsts.KEY_TARGET, EntranceConsts.TAB_TYPE_DESC)
bundle.putBoolean(EntranceConsts.KEY_SCROLL_TO_SERVER, true)
}
@ -305,7 +302,7 @@ class GameDetailActivity : DownloadToolbarActivity() {
}
if (openVideoStreaming) {
bundle.putBoolean(EntranceConsts.KEY_OPEN_VIDEO_STREAMING, true)
bundle.putString(EntranceConsts.KEY_TARGET, GameDetailTabEntity.TYPE_DETAIL)
bundle.putString(EntranceConsts.KEY_TARGET, EntranceConsts.TAB_TYPE_DESC)
}
if (openPlatformWindow) {
bundle.putBoolean(EntranceConsts.KEY_OPEN_PLATFORM_WINDOW, true)
@ -319,7 +316,7 @@ class GameDetailActivity : DownloadToolbarActivity() {
}
}
if (scrollToLibao) {
bundle.putString(EntranceConsts.KEY_TARGET, GameDetailTabEntity.TYPE_DETAIL)
bundle.putString(EntranceConsts.KEY_TARGET, EntranceConsts.TAB_TYPE_DESC)
bundle.putBoolean(EntranceConsts.KEY_SCROLL_TO_LIBAO, true)
}
bundle.putString(EntranceConsts.KEY_GAME_ID, gameId)

View File

@ -119,7 +119,6 @@ import com.sina.weibo.sdk.auth.AuthInfo;
import com.sina.weibo.sdk.openapi.IWBAPI;
import com.sina.weibo.sdk.openapi.WBAPIFactory;
import com.therouter.TheRouter;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.jetbrains.annotations.NotNull;
@ -137,7 +136,6 @@ import io.reactivex.SingleSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import kotlin.Pair;
import kotlin.Unit;
import kotlin.jvm.functions.Function0;
import okhttp3.RequestBody;
@ -183,6 +181,7 @@ public class MainActivity extends BaseActivity {
.get(MainWrapperViewModel.class);
DisplayUtils.transparentStatusBar(this);
DisplayUtils.updateGlobalScreen(this);
super.onCreate(savedInstanceState);
setStatusBarColor(Color.TRANSPARENT);
@ -223,7 +222,7 @@ public class MainActivity extends BaseActivity {
DialogHelper.showCenterWarningDialog(this, "发生闪退", "光环助手发生了闪退,建议安装到最新版本修复异常"
, "马上反馈", "马上安装修复",
() -> {
DirectUtils.directToGameDetail(this, Constants.GHZS_GAME_ID, "", "crash", true, "desc", null, "");
DirectUtils.directToGameDetail(this, Constants.GHZS_GAME_ID, "", "crash", true, "desc", null);
return null;
},
() -> {
@ -256,12 +255,9 @@ public class MainActivity extends BaseActivity {
// 跳转至其它页面
if (getIntent() != null
&& getIntent().getExtras() != null) {
if (getIntent().getBooleanExtra(EntranceConsts.KEY_REQUIRE_REDIRECT, false)) {
doSkip();
} else if (!TextUtils.isEmpty(getIntent().getStringExtra(EntranceConsts.KEY_THE_ROUTER_PATH))) {
doRedirect(getIntent().getStringExtra(EntranceConsts.KEY_THE_ROUTER_PATH));
}
&& getIntent().getExtras() != null
&& getIntent().getBooleanExtra(EntranceConsts.KEY_REQUIRE_REDIRECT, false)) {
doSkip();
}
// debug 模式下的快速跳转页面
@ -460,10 +456,6 @@ public class MainActivity extends BaseActivity {
handler.removeCallbacksAndMessages(null);
releaseExoSourceCache();
// 移除推送触发启动记录
HaloApp.remove(Constants.PUSH_MESSAGE_ID);
HaloApp.remove(Constants.PUSH_LINK_ENTITY);
}
/**
@ -562,31 +554,25 @@ public class MainActivity extends BaseActivity {
protected void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == COUNTDOWN_AD || msg.what == COUNTDOWN_SDK_AD) {
mCountdownCount++;
int maxCount;
// 第三秒的时候初始化 Fragment
if (mCountdownCount == 3) {
doInitMainFragment(mTempSavedInstanceState);
}
if (msg.what == COUNTDOWN_AD) {
maxCount = mCountdownMaxCount;
} else {
maxCount = COUNTDOWN_SDK_MAX_COUNT;
}
// 读秒到一半的时候初始化 MainWrapperFragment
if (mCountdownCount == maxCount / 2) {
doInitMainFragment(mTempSavedInstanceState);
}
mCountdownCount++;
if (maxCount < mCountdownCount) {
AdDelegateHelper.INSTANCE.setShowingSplashAd(false);
hideSplashAd();
if (msg.what == COUNTDOWN_AD && msg.obj instanceof StartupAdEntity) {
StartupAdEntity ad = (StartupAdEntity) msg.obj;
if (!AdDelegateHelper.INSTANCE.isOwnerSplashAdShown()) {
com.gh.common.util.NewFlatLogUtils.logSplashAdFail(ad.getId(), "广告加载超时");
}
AdDelegateHelper.INSTANCE.setOwnerSplashAdShown(false);
LinkEntity linkEntity = ad.getJump();
SensorsBridge.trackEvent(
"SplashAdOwnSkip",
@ -828,19 +814,6 @@ public class MainActivity extends BaseActivity {
}, 500);
}
/**
* 重定向至 TheRouter 配置的页面
*/
private void doRedirect(String path) {
if (getIntent().getExtras() != null) {
// 更新 intent 数据,避免页面重建重新跳转
getIntent().getExtras().putString(EntranceConsts.KEY_THE_ROUTER_PATH, "");
AppExecutor.getUiExecutor().executeWithDelay(() -> {
TheRouter.build(path).navigation(this);
}, 500L);
}
}
@NonNull
private Function0<Unit> launchGame(String gamePackageName) {
return () -> {
@ -1105,12 +1078,4 @@ public class MainActivity extends BaseActivity {
}
}
}
@Override
public Pair<String, String> getBusinessId() {
if (mMainWrapperFragment != null) {
return mMainWrapperFragment.getBusinessId();
}
return super.getBusinessId();
}
}

View File

@ -91,6 +91,7 @@ open class SearchActivity : BaseActivity() {
mSourceEntrance = intent.getStringExtra(EntranceConsts.KEY_SOURCE_ENTRANCE) ?: ""
val hint = intent.getStringExtra(EntranceConsts.KEY_HINT)
val searchImmediately = intent.getBooleanExtra(KEY_SEARCH_IMMEDIATELY, false)
var ignoreTextChanges = savedInstanceState != null
mPublishSubject = PublishSubject.create()
@ -101,9 +102,12 @@ open class SearchActivity : BaseActivity() {
.subscribe {
if (searchEt.text.isNotEmpty()
&& searchEt.text != searchEt.hint
&& !ignoreTextChanges
) {
search(SearchType.AUTO, it)
}
ignoreTextChanges = false
}
initSearchBar()
@ -198,6 +202,7 @@ open class SearchActivity : BaseActivity() {
protected open fun handleEmptySearch(newSearchKey: String) {
popBackToFragment(SearchDefaultFragment::class.java.name)// 回退到搜索首页
updateDisplayType(DisplayType.DEFAULT)
mPublishSubject?.onNext(newSearchKey)
}
@ -324,19 +329,6 @@ open class SearchActivity : BaseActivity() {
// MtaHelper.onEvent("游戏搜索", "主动搜索", newSearchKey)
}
override fun onResume() {
super.onResume()
val newSearchKey = searchEt.text.toString().trim { it <= ' ' }
if (newSearchKey.isBlank()) {
try {
popBackToFragment(SearchDefaultFragment::class.java.name)
} catch (e: Exception) {
// no implement
}
}
}
protected open fun provideDao(): ISearchHistoryDao = SearchHistoryDao(this)
open fun updateDisplayType(type: DisplayType) {

View File

@ -5,12 +5,11 @@ import android.content.Intent
import android.os.Bundle
import android.os.Parcelable
import android.view.View
import com.gh.gamecenter.amway.AmwaySuccessFragment
import com.gh.gamecenter.common.base.activity.ToolBarActivity
import com.gh.gamecenter.common.base.fragment.BaseFragment
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.gamedetail.cloudarchive.CloudArchiveFragment
import com.gh.gamecenter.gamedetail.libao.LibaoListFragment
import com.gh.gamecenter.amway.AmwaySuccessFragment
import com.gh.gamecenter.gamedetail.LibaoListFragment
import com.halo.assistant.fragment.SwitchInstallMethodFragment
import com.halo.assistant.fragment.user.ManuallyRealNameFragment
import com.halo.assistant.fragment.user.RealNameInfoFragment
@ -39,7 +38,6 @@ class ShellActivity : ToolBarActivity() {
Type.REAL_NAME_INFO -> startFragment(RealNameInfoFragment().with(bundle))
Type.MANUALLY_REAL_NAME -> startFragment(ManuallyRealNameFragment().with(extraData))
Type.SIMPLE_LIBAO_LIST -> startFragment(LibaoListFragment.newInstance(extraData))
Type.CLOUD_ARCHIVE -> startFragment(CloudArchiveFragment().with(extraData))
}
}
@ -74,8 +72,7 @@ class ShellActivity : ToolBarActivity() {
SWITCH_INSTALL_METHOD("switch_install_method"),
REAL_NAME_INFO("real_name_info"),
MANUALLY_REAL_NAME("manually_real_name"),
SIMPLE_LIBAO_LIST("simple_libao_list"),
CLOUD_ARCHIVE("cloud_archive");
SIMPLE_LIBAO_LIST("simple_libao_list");
companion object {
fun fromString(typeString: String): Type {

View File

@ -1,7 +1,6 @@
package com.gh.gamecenter;
import static com.gh.gamecenter.common.constant.EntranceConsts.ENTRANCE_BROWSER;
import static com.gh.gamecenter.common.constant.EntranceConsts.ENTRANCE_OTHER;
import static com.gh.gamecenter.common.constant.EntranceConsts.ENTRANCE_PUSH;
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_ANSWER;
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_ARCHIVE_LOGIN;
@ -36,7 +35,6 @@ import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_VIDEO_STREAM
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_VIDEO_STREAMING_HOME;
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_WEB;
import static com.gh.gamecenter.common.constant.EntranceConsts.KEY_DATA;
import static com.gh.gamecenter.common.constant.EntranceConsts.KEY_FROM;
import static com.gh.gamecenter.common.constant.EntranceConsts.KEY_GAME_NAME;
import static com.gh.gamecenter.common.constant.EntranceConsts.KEY_NAME;
import static com.gh.gamecenter.common.constant.EntranceConsts.KEY_PACKAGENAME;
@ -102,6 +100,7 @@ public class SkipActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Uri uri = getIntent().getData();
Bundle bundle;
if (uri != null) {
@ -161,8 +160,7 @@ public class SkipActivity extends BaseActivity {
DirectUtils.directToArticle(this, path, entrance);
break;
case HOST_GAME:
String from = uri.getQueryParameter(KEY_FROM);
DirectUtils.directToGameDetail(this, path, "", entrance, "true".equals(uri.getQueryParameter("auto_download")), to, null, from);
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, SubjectData.SubjectType.NORMAL);
@ -182,7 +180,7 @@ public class SkipActivity extends BaseActivity {
DirectUtils.directToAnswerDetail(this, path, entrance, pathName);
break;
case HOST_QUESTION:
DirectUtils.directToQuestionDetail(this, path, entrance, pathName, isFromPush ? ENTRANCE_PUSH : ENTRANCE_OTHER);
DirectUtils.directToQuestionDetail(this, path, entrance, pathName, "");
break;
case HOST_TOOLBOX:
DirectUtils.directToToolbox(this, uri.getQueryParameter("gameId"), uri.getQueryParameter("toolboxUrl"), entrance);
@ -192,7 +190,7 @@ public class SkipActivity extends BaseActivity {
break;
// 社区文章格式一
case "community.article":
DirectUtils.directToCommunityArticle(this, uri.getQueryParameter("articleId"), uri.getQueryParameter("communityId"), entrance, pathName, isFromPush ? ENTRANCE_PUSH : ENTRANCE_OTHER);
DirectUtils.directToCommunityArticle(this, uri.getQueryParameter("articleId"), uri.getQueryParameter("communityId"), entrance, pathName, "");
break;
// 社区文章格式二
case "communities":
@ -213,13 +211,13 @@ public class SkipActivity extends BaseActivity {
}
}
if ("articles".equals(type)) {
DirectUtils.directToCommunityArticle(this, typeId, communityId, entrance, pathName, isFromPush ? ENTRANCE_PUSH : ENTRANCE_OTHER);
DirectUtils.directToCommunityArticle(this, typeId, communityId, entrance, pathName, "");
break;
}
break;
case HOST_VIDEO:
DirectUtils.directToVideoDetail(this, path, VideoDetailContainerViewModel.Location.HOTTEST_GAME_VIDEO.getValue(),
false, id, entrance, pathName, TextUtils.isEmpty(referer) ? "" : referer, isFromPush ? ENTRANCE_PUSH : ENTRANCE_OTHER);
false, id, entrance, pathName, TextUtils.isEmpty(referer) ? "" : referer, "");
break;
case HOST_UPLOAD_VIDEO://跳转上传视频
String titleParameter = uri.getQueryParameter("title");
@ -239,7 +237,7 @@ public class SkipActivity extends BaseActivity {
break;
case HOST_VIDEO_SINGLE:
DirectUtils.directToVideoDetail(this, path, VideoDetailContainerViewModel.Location.SINGLE_VIDEO.getValue(),
false, "", entrance, pathName, TextUtils.isEmpty(referer) ? "" : referer, isFromPush ? ENTRANCE_PUSH : ENTRANCE_OTHER);
false, "", entrance, pathName, TextUtils.isEmpty(referer) ? "" : referer, "");
break;
case HOST_VIDEO_MORE:
gameId = uri.getQueryParameter("gameId");
@ -296,7 +294,7 @@ public class SkipActivity extends BaseActivity {
EntranceUtils.jumpActivityCompat(this, bundle);
break;
case EntranceConsts.HOST_VIDEO_DETAIL:
DirectUtils.directToVideoDetail(this, path, entrance, "", isFromPush ? ENTRANCE_PUSH : ENTRANCE_OTHER);
DirectUtils.directToVideoDetail(this, path, entrance, "", "");
break;
case HOST_LIBAO:
DirectUtils.directToGiftDetail(this, path, entrance);
@ -317,7 +315,7 @@ public class SkipActivity extends BaseActivity {
break;
case HOST_COLUMN_COLLECTION:
DirectUtils.directToColumnCollection(this, path, -1, entrance, "", "", "", "", null, false);
DirectUtils.directToColumnCollection(this, path, -1, entrance, "", "", "", "", null,false);
break;
case EntranceConsts.HOST_BLOCK:
name = uri.getQueryParameter("name");
@ -359,7 +357,7 @@ public class SkipActivity extends BaseActivity {
byte[] linkData = Base64.decode(dataString, Base64.DEFAULT);
String linkDataString = new String(linkData, "UTF-8");
LaunchRedirect launchRedirect = GsonUtils.fromJson(linkDataString, LaunchRedirect.class);
DirectUtils.directToLinkPage(this, launchRedirect, entrance, "", isFromPush ? ENTRANCE_PUSH : ENTRANCE_OTHER);
DirectUtils.directToLinkPage(this, launchRedirect, entrance, "", "");
}
} catch (Exception e) {
e.printStackTrace();
@ -416,13 +414,13 @@ public class SkipActivity extends BaseActivity {
break;
case HOST_ARCHIVE_LOGIN:
String gamePkg = uri.getQueryParameter(EntranceConsts.KEY_GAME_PKG);
if (CheckLoginUtils.isLogin()) {
if(CheckLoginUtils.isLogin()) {
VHelper.INSTANCE.updateAuthorizeInfo(true);
} else {
Bundle newBundle = new Bundle();
newBundle.putString(EntranceConsts.KEY_TO, LoginActivity.class.getName());
EntranceUtils.jumpActivityCompat(this, newBundle, null, (resultCode, data) -> {
if (CheckLoginUtils.isLogin()) {
if(CheckLoginUtils.isLogin()) {
VHelper.INSTANCE.updateAuthorizeInfo(true);
}
VHelper.launch(this, gamePkg, false, false);

View File

@ -5,7 +5,6 @@ import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.preference.PreferenceManager
@ -15,8 +14,8 @@ import androidx.core.app.NotificationCompat
import androidx.core.text.bold
import androidx.core.text.buildSpannedString
import androidx.core.text.color
import com.therouter.TheRouter
import com.therouter.router.Route
import com.therouter.TheRouter
import com.gh.common.dialog.NewPrivacyPolicyDialogFragment
import com.gh.common.util.DeviceTokenUtils
import com.gh.common.util.DialogUtils
@ -27,9 +26,6 @@ import com.gh.common.util.UsageStatsHelper.checkAndPostUsageStats
import com.gh.download.DownloadManager
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.constant.EntranceConsts.KEY_FROM
import com.gh.gamecenter.common.constant.EntranceConsts.KEY_GAMEID
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.tracker.TrackerLogger
import com.gh.gamecenter.common.utils.*
@ -94,10 +90,8 @@ class SplashScreenActivity : BaseActivity(), ISplashScreen {
showPrivacyDialog()
} else {
val spanBuilder = buildSpannedString {
append(
"这个弹窗只会在右上角有环境标签的测试包出现" +
"\n进入应用以后还可以到关于我们页面长按应用图标重新选择"
)
append("这个弹窗只会在右上角有环境标签的测试包出现" +
"\n进入应用以后还可以到关于我们页面长按应用图标重新选择")
bold {
color(com.gh.gamecenter.common.R.color.text_theme.toColor(this@SplashScreenActivity)) {
append("\n点击这里进行预设置渠道")
@ -109,7 +103,7 @@ class SplashScreenActivity : BaseActivity(), ISplashScreen {
executeDex2OatInAdvance()
DialogHelper.showDialog(
context = this,
title = "选择环境",
title ="选择环境",
content = spanBuilder,
confirmText = "正式环境",
cancelText = "测试环境",
@ -150,10 +144,6 @@ class SplashScreenActivity : BaseActivity(), ISplashScreen {
val trackEvent = JSONObject()
// 是否首次使用神策
val isFirstTime = SPUtils.getBoolean(Constants.SP_SENSORS_IS_FIRST_TIME, true)
val therouterPath = intent.extras?.getString(EntranceConsts.KEY_THE_ROUTER_PATH) ?: ""
val uri = Uri.parse(therouterPath)
val isFromWechat = WECHAT_APPOINTMENT == if (!uri.isOpaque) uri.getQueryParameter(KEY_FROM) else false
val gameId = if (!uri.isOpaque) uri.getQueryParameter(KEY_GAMEID) else ""
tryCatchInRelease {
trackEvent.run {
put("\$is_first_time", isFirstTime)
@ -163,10 +153,6 @@ class SplashScreenActivity : BaseActivity(), ISplashScreen {
put("signature", signatureHash)
put("app_name", appProvider?.getAppName())
put("install_first_time", if (HaloApp.getInstance().isBrandNewInstall) "" else "")
if (isFromWechat) {
put("source_entrance", WECHAT_NOTIFICATION)
put("page_business_id", gameId)
}
}
}
SensorsBridge.trackEvent("AppLaunch", trackEvent)
@ -337,9 +323,6 @@ class SplashScreenActivity : BaseActivity(), ISplashScreen {
const val HONOR_CULPRIT_ID = 12324
const val HONOR_CULPRIT_CHANNEL = "荣耀通道"
private const val WECHAT_APPOINTMENT = "wechat_appointment"
private const val WECHAT_NOTIFICATION = "微信通知"
@JvmStatic
fun getSplashScreenIntent(context: Context?, bundle: Bundle?): Intent {
val intent = Intent(context, SplashScreenActivity::class.java)

View File

@ -2,7 +2,6 @@ package com.gh.gamecenter.adapter;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.text.Html;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
@ -13,7 +12,6 @@ import android.text.style.ClickableSpan;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
@ -22,14 +20,9 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import com.facebook.drawee.drawable.ScalingUtils;
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
import com.facebook.drawee.generic.RoundingParams;
import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.common.util.DirectUtils;
import com.gh.common.util.LibaoUtils;
import com.gh.gamecenter.GameDetailActivity;
import com.gh.gamecenter.ImageViewerActivity;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.viewholder.LibaoDetailContentViewHolder;
import com.gh.gamecenter.adapter.viewholder.LibaoDetailTopViewHolder;
@ -38,7 +31,6 @@ import com.gh.gamecenter.common.entity.SimpleGameEntity;
import com.gh.gamecenter.common.entity.SuggestType;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.ImageUtils;
import com.gh.gamecenter.common.utils.PicassoImageGetter;
import com.gh.gamecenter.common.viewholder.FooterViewHolder;
import com.gh.gamecenter.core.utils.DisplayUtils;
@ -87,7 +79,6 @@ public class LibaoDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
private String mEntrance;
private final int TYPE_FOOTER = 100;
public LibaoDetailTopViewHolder libaoDetailTopViewHolder;
private ArrayList<View> mImageViewList = new ArrayList<>();
public LibaoDetailAdapter(Context context, OnRequestCallBackListener onRequestCallBackListener,
OnCodeScrollListener onCodeScrollListener, LibaoEntity libaoEntity,
@ -326,35 +317,6 @@ public class LibaoDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
holder.binding.libaodetailContentLl.setVisibility(View.VISIBLE);
holder.binding.libaodetailContent.setText(Html.fromHtml(mLibaoEntity.getContent()));
}
if (mLibaoEntity.getMaterials().isEmpty()) {
holder.binding.horizontalScrollView.setVisibility(View.GONE);
} else {
holder.binding.horizontalScrollView.setVisibility(View.VISIBLE);
holder.binding.imagesContainer.removeAllViews();
mImageViewList.clear();
for (int i = 0; i < mLibaoEntity.getMaterials().size(); i++) {
String imageUrl = mLibaoEntity.getMaterials().get(i).getImg();
SimpleDraweeView imageView = new SimpleDraweeView(mContext);
RoundingParams roundingParams = new RoundingParams();
roundingParams.setCornersRadius(DisplayUtils.dip2px(4F));
roundingParams.setOverlayColor(ContextCompat.getColor(mContext, com.gh.gamecenter.common.R.color.ui_surface));
imageView.setHierarchy(new GenericDraweeHierarchyBuilder(mContext.getResources())
.setFadeDuration(500)
.setRoundingParams(roundingParams)
.setPlaceholderImage(com.gh.gamecenter.common.R.drawable.occupy, ScalingUtils.ScaleType.FIT_XY)
.build());
ImageUtils.display(imageView, imageUrl);
final int index = i;
imageView.setOnClickListener(v -> {
Intent intent = ImageViewerActivity.getIntent(mContext, mLibaoEntity.getMaterialImgList(), index, mImageViewList, mEntrance);
mContext.startActivity(intent);
});
mImageViewList.add(imageView);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(DisplayUtils.dip2px(24F), DisplayUtils.dip2px(24F));
layoutParams.setMargins(DisplayUtils.dip2px(i == 0 ? 8F : 16F), 0, 0, 0);
holder.binding.imagesContainer.addView(imageView, layoutParams);
}
}
if (mLibaoDetailEntity != null) {
holder.binding.libaodetailTimeLl.setVisibility(View.VISIBLE);

View File

@ -4,11 +4,8 @@ import android.content.Context
import android.content.Intent
import android.text.TextUtils
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.Group
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity
import com.airbnb.lottie.LottieAnimationView
@ -16,7 +13,6 @@ import com.gh.common.chain.*
import com.gh.common.constant.Config
import com.gh.common.dialog.DeviceRemindDialog
import com.gh.common.dialog.GameOffServiceDialogFragment
import com.gh.common.dialog.PackageCheckDialogFragment
import com.gh.common.filter.RegionSettingHelper
import com.gh.common.history.HistoryHelper
import com.gh.common.simulator.NewSimulatorGameManager
@ -35,6 +31,7 @@ import com.gh.gamecenter.common.base.GlobalActivityManager.getCurrentPageEntity
import com.gh.gamecenter.common.base.GlobalActivityManager.getLastPageEntity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.utils.NewFlatLogUtils
import com.gh.gamecenter.core.runOnIoThread
@ -47,10 +44,8 @@ import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.view.DownloadButton
import com.gh.gamecenter.feature.view.DownloadButton.ButtonStyle
import com.gh.gamecenter.gamedetail.GameDetailViewModel
import com.gh.gamecenter.gamedetail.accelerator.GameDetailAcceleratorUiHelper
import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment
import com.gh.gamecenter.gamedetail.entity.GameDetailTabEntity
import com.gh.gamecenter.teenagermode.TeenagerModeActivity.Companion.getIntent
import com.gh.vspace.VHelper
import com.lightgame.download.DownloadEntity
@ -61,16 +56,13 @@ import java.io.File
// 虽然叫 ViewHolder但其实就是一个用来临时放 View 和相关操作的包裹类
class DetailViewHolder(
view: View,
val viewModel: GameDetailViewModel?,
val gameEntity: GameEntity,
val isNewsDetail: Boolean, // 新闻详情不显示下载的游戏名, 只显示下载状态
entrance: String?,
name: String?,
title: String?,
val traceEvent: ExposureEvent?,
val isSupportDualButton: Boolean = false, // 是否支持双下载按钮,不支持的时候跟普通列表意义选用优先级高的那个来显示,
val acceleratorUiHelper: GameDetailAcceleratorUiHelper? = null, // 网速加速,只有游戏详情才有
onDownloadClickAction: ((Boolean) -> Unit)? = null
val isSupportDualButton: Boolean = false // 是否支持双下载按钮,不支持的时候跟普通列表意义选用优先级高的那个来显示
) {
var context: Context
var downloadBottom: View
@ -98,30 +90,20 @@ class DetailViewHolder(
// 多版本下载文字
var multiVersionDownloadTv: TextView?
// 加速按钮
val speedContainer: ConstraintLayout?
private val ivFreeVipTag: ImageView?
private val gMoreZone: Group?
// 注意 View 的命名
init {
downloadBottom = view.findViewById(R.id.detail_ll_bottom)
downloadPb = downloadBottom.findViewById(R.id.detail_progressbar)
downloadTips = downloadBottom.findViewById(R.id.downloadTipsLottie)
downloadPb = view.findViewById(R.id.detail_progressbar)
downloadTips = view.findViewById(R.id.downloadTipsLottie)
overlayTv = view.findViewById(R.id.overlayTv)
overlayContainer = view.findViewById(R.id.overlayContainer)
extraOverlayTv = view.findViewById(R.id.extraOverlayTv)
multiVersionDownloadTv = downloadBottom.findViewById(R.id.multiVersionDownloadTv)
multiVersionDownloadTv = view.findViewById(R.id.multiVersionDownloadTv)
localDownloadContainer = view.findViewById(R.id.localDownloadContainer)
localDownloadSizeTv = view.findViewById(R.id.localDownloadSizeTv)
localDownloadTitleTv = view.findViewById(R.id.localDownloadTitleTv)
localDownloadButton = view.findViewById(R.id.localDownloadButton)
speedContainer = view.findViewById(R.id.cl_speed_container)
ivFreeVipTag = view.findViewById(R.id.iv_free_vip_tag)
gMoreZone = view.findViewById(R.id.g_more_zone)
context = view.context
var gameDownloadMode = gameEntity.getGameDownloadButtonMode()
@ -133,8 +115,7 @@ class DetailViewHolder(
mTitle = title ?: "",
mAsVGame = false,
mShowDualDownloadButton = gameDownloadMode == GameEntity.GAME_DOWNLOAD_BUTTON_MODE_DUAL,
mTraceEvent = traceEvent,
onDownloadClickAction = onDownloadClickAction
mTraceEvent = traceEvent
)
val vGameDownloadListener = OnDetailDownloadClickListener(
@ -144,8 +125,7 @@ class DetailViewHolder(
mTitle = title ?: "",
mAsVGame = true,
mShowDualDownloadButton = gameDownloadMode == GameEntity.GAME_DOWNLOAD_BUTTON_MODE_DUAL,
mTraceEvent = traceEvent,
onDownloadClickAction = onDownloadClickAction
mTraceEvent = traceEvent
)
// 不支持双下载按钮的情况时,优选一个下载方式显示
@ -178,9 +158,7 @@ class DetailViewHolder(
localDownloadButton?.putObject(gameEntity)
localDownloadButton?.setTag(
com.gh.gamecenter.feature.R.string.download, context.getString(
com.gh.gamecenter.feature.R.string.download_local
)
)
com.gh.gamecenter.feature.R.string.download_local))
}
}
downloadPb.putWidgetBusinessName("游戏详情页")
@ -198,33 +176,6 @@ class DetailViewHolder(
gamePermissionDialogFragment?.dismissAllowingStateLoss()
}
fun checkIfShowSpeedUi(rawBtnText: String) {
acceleratorUiHelper?.let {
when {
rawBtnText == "启动" && gameEntity.canSpeed -> {
downloadPb.goneIf(true)
localDownloadButton?.goneIf(true)
it.checkIfShowSpeedUi(true)
}
rawBtnText == "更新" && gameEntity.canSpeed -> {
it.checkIfShowSpeedUi(true)
}
else -> {
it.checkIfShowSpeedUi(false)
}
}
}
}
fun setSpeedViewsVisible(isVisible: Boolean) {
ivFreeVipTag?.goneIf(!isVisible)
speedContainer?.goneIf(!isVisible)
}
internal class OnDetailDownloadClickListener(
private val mViewHolder: DetailViewHolder,
private val mEntrance: String?,
@ -232,8 +183,7 @@ class DetailViewHolder(
private val mTitle: String,
private val mAsVGame: Boolean,
private val mShowDualDownloadButton: Boolean,
private val mTraceEvent: ExposureEvent?,
private val onDownloadClickAction: ((Boolean) -> Unit)? = null
private val mTraceEvent: ExposureEvent?
) : View.OnClickListener {
private val mGameEntity: GameEntity = mViewHolder.gameEntity
@ -244,10 +194,6 @@ class DetailViewHolder(
if (mGameEntity.isLandPageAddressDialog() && !mGameEntity.isLandPageAddressDialogShowOnly()) {
// 第三方落地页为开启状态并且展示状态不为“仅显示弹窗”,需要在点击确认后显示弹窗
DialogUtils.showLandPageAddressDialog(mViewHolder.context, mGameEntity) {
val packageName = mGameEntity.getApk().firstOrNull()?.packageName
if (packageName?.isNotEmpty() == true) {
PackageChangeHelper.addInstallPendingPackage(packageName)
}
DirectUtils.directToExternalBrowser(mViewHolder.context, mGameEntity.landPageAddressDialog!!.link!!)
}
}
@ -331,13 +277,11 @@ class DetailViewHolder(
showLandPageAddressDialogIfNeeded()
}
}
"toast" -> {
mViewHolder.viewModel?.performTabSelected(GameDetailTabEntity.TYPE_COMMENT)
EventBus.getDefault().post(EBReuse(GameDetailFragment.SKIP_RATING))
ToastUtils.toast("该游戏因故暂不提供下载,具体详情可在相关评论中查看,敬请谅解~")
showLandPageAddressDialogIfNeeded()
}
"third_party" -> {
showLandPageAddressDialogIfNeeded()
}
@ -386,19 +330,7 @@ class DetailViewHolder(
if (mAsVGame) {
VHelper.installOrLaunch(mViewHolder.context, mGameEntity, null)
} else {
// 如果游戏配置了加速,则启动时需要进行包名检测
if (mGameEntity.canSpeed) {
PackageCheckDialogFragment.show(mViewHolder.context as AppCompatActivity, mGameEntity) {
PackageLauncher.launchApp(
mViewHolder.context, mGameEntity, mGameEntity.getUniquePackageName()
)
}
} else {
PackageLauncher.launchApp(
mViewHolder.context, mGameEntity, mGameEntity.getUniquePackageName()
)
}
PackageLauncher.launchApp(mViewHolder.context, mGameEntity, mGameEntity.getUniquePackageName())
}
} else {
GamePermissionDialogFragment.show(
@ -418,8 +350,7 @@ class DetailViewHolder(
gameEntity = mGameEntity,
traceEvent = mTraceEvent,
entrance = StringUtils.buildString(mEntrance, "+(", mName, "[", mTitle, "])"),
location = "$mName:$mTitle",
onDownloadClickAction = onDownloadClickAction
location = "$mName:$mTitle"
)
}
}
@ -659,9 +590,8 @@ class DetailViewHolder(
val apkEntity = mGameEntity.getApk().firstOrNull()
val msg = FileUtils.isCanDownload(mViewHolder.context, apkEntity?.size ?: "")
if (TextUtils.isEmpty(msg)) {
val btnContainsUpdateText =
mViewHolder.context.getString(com.gh.gamecenter.feature.R.string.update_v) == buttonText
|| buttonText.contains(mViewHolder.context.getString(com.gh.gamecenter.feature.R.string.update))
val btnContainsUpdateText = mViewHolder.context.getString(com.gh.gamecenter.feature.R.string.update_v) == buttonText
|| buttonText.contains(mViewHolder.context.getString(com.gh.gamecenter.feature.R.string.update))
if (asVGame && btnContainsUpdateText) {
VHelper.updateOrReDownload(mGameEntity)
@ -737,7 +667,6 @@ class DetailViewHolder(
builder.addHandler(OverseaDownloadHandler())
builder.addHandler(CheckDownloadHandler())
builder.setProcessEndCallback(mGameEntity.id) { asVGame: Boolean, isSubscribe: Any? ->
performDownloadClickAction()
download(asVGame, isSubscribe as Boolean)
}
} else {
@ -755,8 +684,7 @@ class DetailViewHolder(
mTitle,
"])"
),
"$mName:$mTitle",
onDownloadClickAction
"$mName:$mTitle"
)
}
}
@ -767,20 +695,5 @@ class DetailViewHolder(
mAsVGame
)
}
private fun performDownloadClickAction() {
val buttonText = if (mShowDualDownloadButton && !mAsVGame) {
mViewHolder.localDownloadTitleTv?.text?.ifEmpty {
mViewHolder.downloadPb.text.ifEmpty {
mViewHolder.overlayTv?.text ?: ""
}
}
} else {
mViewHolder.downloadPb.text.ifEmpty { mViewHolder.overlayTv?.text ?: "" }
}
val isUpdate =
buttonText?.contains(mViewHolder.context.getString(com.gh.gamecenter.feature.R.string.update)) == true
onDownloadClickAction?.invoke(isUpdate)
}
}
}

View File

@ -1,7 +1,5 @@
package com.gh.gamecenter.authorization
import android.app.Activity
import android.app.Application.ActivityLifecycleCallbacks
import android.app.Dialog
import android.content.Intent
import android.os.Build
@ -24,7 +22,6 @@ import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.login.user.UserRepository
import com.gh.gamecenter.login.view.LoginActivity
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
/**
@ -142,7 +139,7 @@ class AuthorizationActivity : ToolBarActivity() {
override fun onRestart() {
super.onRestart()
if (!CheckLoginUtils.isLogin()) {
finishAndRemoveTask()
finish()
} else {
initUserInfo()
initData()
@ -153,12 +150,12 @@ class AuthorizationActivity : ToolBarActivity() {
private fun checkParam() {
val uri = intent.data
if (uri == null) {
finishAndRemoveTask()
finish()
return
}
val host = uri.host
if (host != "authorize") {
finishAndRemoveTask()
finish()
return
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
@ -171,7 +168,7 @@ class AuthorizationActivity : ToolBarActivity() {
gameName = uri.getQueryParameter(EntranceConsts.KEY_GAME_NAME) ?: ""
gameUid = uri.getQueryParameter(EntranceConsts.KEY_UID)?.toIntOrNull() ?: -1
if (mRemotePkgName == null) {
finishAndRemoveTask()
finish()
return
}
}
@ -224,7 +221,7 @@ class AuthorizationActivity : ToolBarActivity() {
val remotePkgName = mRemotePkgName
if (remotePkgName == null) {
logAuthResult(false)
finishAndRemoveTask()
finish()
return
}
if (mToken.isEmpty()) {
@ -245,44 +242,13 @@ class AuthorizationActivity : ToolBarActivity() {
intent.putExtra(EntranceConsts.KEY_USER_NAME, username)
intent.putExtra(EntranceConsts.KEY_USER_AVATAR, userAvatar)
if (gameUid != -1 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
try {
sendBroadcastAsUser(intent, UserHandle.getUserHandleForUid(gameUid))
} catch (e: Exception) {
// 双开/分身游戏进行授权时,如果无 INTERACT_ACROSS_USERS 权限则使用Activity传递授权结果
authByActivity(intent)
return
}
sendBroadcastAsUser(intent, UserHandle.getUserHandleForUid(gameUid))
} else {
sendBroadcast(intent)
}
logAuthResult(true)
backToLaunchApp()
finishAndRemoveTask()
}
private fun authByActivity(intent: Intent) {
intent.setClassName(mRemotePkgName!!, AUTHORIZATION_RESULT_ACTIVITY)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
HaloApp.getInstance().registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
override fun onActivityStarted(activity: Activity) {}
override fun onActivityResumed(activity: Activity) {}
override fun onActivityPaused(activity: Activity) {}
override fun onActivityStopped(activity: Activity) {
if (activity == this@AuthorizationActivity) {
HaloApp.getInstance().unregisterActivityLifecycleCallbacks(this)
finishAndRemoveTask()
}
}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
override fun onActivityDestroyed(activity: Activity) {
if (activity == this@AuthorizationActivity) {
HaloApp.getInstance().unregisterActivityLifecycleCallbacks(this)
}
}
})
startActivity(intent)
logAuthResult(true)
finish()
}
private fun logAuthResult(isSuccess: Boolean) {
@ -311,7 +277,7 @@ class AuthorizationActivity : ToolBarActivity() {
}
override fun onBackPressed() {
finishAndRemoveTask()
super.onBackPressed()
backToLaunchApp(false)
@ -326,7 +292,6 @@ class AuthorizationActivity : ToolBarActivity() {
private const val BUTTON_TYPE_CONFIRM = "确定"
private const val BUTTON_TYPE_BACK = "返回"
private const val TYPE_PLUGIN = "plugin"
private const val AUTHORIZATION_RESULT_ACTIVITY = "com.gh.plugin.AuthorizationResultActivity"
}
}

View File

@ -242,7 +242,7 @@ class CategoryV2ListAdapter(
gameIconView.displayGameIcon(gameEntity)
gameRating.textSize = if (gameEntity.commentCount > 3) 12F else 10F
BindingAdapters.setGameName(gameName, gameEntity, false)
BindingAdapters.setGameTags(labelList, gameEntity, "")
BindingAdapters.setGameTags(labelList, gameEntity)
gameRating.setDrawableStart(if (gameEntity.commentCount > 3) com.gh.gamecenter.feature.R.drawable.game_horizontal_rating.toDrawable() else null)
gameRating.text = if (gameEntity.commentCount > 3) {
if (gameEntity.star == 10.0F) "10" else gameEntity.star.toString()

View File

@ -2,30 +2,17 @@ package com.gh.gamecenter.cloudarchive
import android.app.Application
import com.gh.gamecenter.common.baselist.ListViewModel
import com.gh.gamecenter.common.utils.toRequestBody
import com.gh.gamecenter.entity.ArchiveEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.lightgame.utils.Utils
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.*
import retrofit2.HttpException
import java.io.IOException
open class BaseCloudArchiveViewModel(
application: Application,
private val mGameId: String,
private var mConfigUrl: String
) : ListViewModel<ArchiveEntity, ArchiveEntity>(application) {
open class BaseCloudArchiveViewModel(application: Application, private val mConfigUrl: String): ListViewModel<ArchiveEntity, ArchiveEntity>(application) {
private var mArchiveConfigStr = ""
init {
if (mConfigUrl.isEmpty()) {
getArchiveConfigUrl()
} else {
getArchiveConfigString()
}
getArchiveConfigString()
}
// 通过url获取config字符串内容
@ -54,27 +41,6 @@ open class BaseCloudArchiveViewModel(
}
}
// 获取游戏存档配置url
private fun getArchiveConfigUrl() {
val map = mapOf(
"game_ids" to listOf(mGameId)
)
RetrofitManager.getInstance().newApi.getGamesArchiveConfigs(map.toRequestBody())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : com.gh.gamecenter.common.retrofit.Response<List<ArchiveEntity>>() {
override fun onResponse(response: List<ArchiveEntity>?) {
mConfigUrl = response?.find { it.gameId == mGameId }?.configUrl ?: return
getArchiveConfigString()
}
override fun onFailure(e: HttpException?) {
super.onFailure(e)
Utils.toast(getApplication(), "获取存档配置失败")
}
})
}
override fun provideDataObservable(page: Int): Observable<List<ArchiveEntity>>? = null
override fun mergeResultLiveData() {}

View File

@ -216,7 +216,7 @@ class CloudArchiveManagerActivity : BaseActivity_TabLayout(), ArchiveLimitSelect
private fun initDownloadBtn() {
mGameEntity?.let { gameEntity ->
DownloadItemUtils.updateDownloadButton(this, mBinding.downloadBtn, gameEntity, listener = null)
DownloadItemUtils.updateDownloadButton(this, mBinding.downloadBtn, gameEntity)
DownloadItemUtils.setOnClickListener(this, mBinding.downloadBtn, gameEntity, 0, null, mEntrance, "")
}
}

View File

@ -8,6 +8,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.toJson
import com.gh.gamecenter.common.utils.toRequestBody
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.entity.ArchiveEntity
@ -21,7 +22,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import okhttp3.*
import retrofit2.HttpException
class CloudArchiveManagerViewModel(
@ -29,7 +30,7 @@ class CloudArchiveManagerViewModel(
val gameId: String,
val gameName: String,
configUrl: String
) : BaseCloudArchiveViewModel(application, gameId, configUrl) {
) : BaseCloudArchiveViewModel(application, configUrl) {
companion object {
private const val SORT_TYPE_CREATE = "time.create:-1"

View File

@ -12,7 +12,6 @@ import androidx.recyclerview.widget.RecyclerView
import com.gh.common.exposure.IExposable
import com.gh.common.util.DialogUtils
import com.gh.common.util.DirectUtils
import com.gh.common.util.PackageChangeHelper
import com.gh.common.util.PackageInstaller
import com.gh.common.util.PackageLauncher
import com.gh.download.DownloadManager
@ -399,10 +398,6 @@ class UpdatableGameAdapter(private var mViewModel: UpdatableGameViewModel) :
if (update.isLandPageAddressDialogShowOnly()) {
updateOrPluggable(updateBtn, update, downloadEntity, pluginDesc)
} else {
val packageName = update.packageName
if (packageName.isNotEmpty() == true) {
PackageChangeHelper.addInstallPendingPackage(packageName)
}
DirectUtils.directToExternalBrowser(it.context, update.landPageAddressDialog!!.link!!)
}
}

View File

@ -15,7 +15,6 @@ import com.gh.gamecenter.common.base.BaseSimpleDao
import com.gh.gamecenter.common.base.GlobalActivityManager.getCurrentPageEntity
import com.gh.gamecenter.common.base.GlobalActivityManager.getLastPageEntity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.GsonUtils.toJson
@ -630,7 +629,6 @@ class UpdatableGameViewModel(
downloadEntity.addMetaExtra(Constants.APK_MD5, update.md5)
downloadEntity.addMetaExtra(Constants.GAME_NAME, update.name)
downloadEntity.addMetaExtra(Constants.GAME_CATEGORY_IN_CHINESE, update.categoryChinese)
downloadEntity.addMetaExtra(Constants.DOWNLOAD_STATUS_IN_CHINESE, update.downloadStatusChinese)
downloadEntity.putGameCategory(update.category ?: "")
if (update.isModdedGame) {
downloadEntity.addMetaExtra(Constants.EXTRA_IS_MODDED_GAME, "true")
@ -687,9 +685,6 @@ class UpdatableGameViewModel(
// 收集下载数据
DataCollectionUtils.uploadDownload(getApplication(), downloadEntity, "开始")
val pushMessageId = (HaloApp.get(Constants.PUSH_MESSAGE_ID, false) as? String) ?: ""
val pushLinkId = (HaloApp.get(Constants.PUSH_LINK_ENTITY, false) as? LinkEntity)?.link ?: ""
val isFromPush = pushMessageId.isNotEmpty()
SensorsBridge.trackEventWithExposureSource(
"DownloadProcessBegin",
event.source,
@ -705,9 +700,6 @@ class UpdatableGameViewModel(
"last_page_business_id", getLastPageEntity().pageBusinessId,
"download_status", update.downloadStatusChinese,
"download_type", "本地下载",
"is_from_push_notifications", isFromPush,
"message_id", pushMessageId,
"link_id", pushLinkId,
)
}

View File

@ -1,10 +1,10 @@
package com.gh.gamecenter.entity
import com.gh.gamecenter.feature.entity.Count
import com.gh.gamecenter.feature.entity.SimpleGame
import com.gh.gamecenter.feature.entity.Count
import com.google.gson.annotations.SerializedName
data class GameDetailRecommendGameCollectionEntity(
data class GameDetailRecommendGameEntity(
@SerializedName("_id")
val id: String = "",
val cover: String = "",

View File

@ -1,11 +0,0 @@
package com.gh.gamecenter.entity
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity
data class HistoryGameDetailEntity(
@PrimaryKey
var id: String = "",
var name: String? = "",
)

View File

@ -11,8 +11,6 @@ class ReserveReminderEntity(
private var _smsConfig: SmsConfig? = null,
@SerializedName("wechat_config")
private var _wechatConfig: WechatConfigEntity? = null,
@SerializedName("calendar_config")
private var _calendarConfig: CalendarConfig? = null,
@SerializedName("mirror_type")
private val _mirrorType: String? = null,
@SerializedName("wifi_auto_download")
@ -36,14 +34,8 @@ class ReserveReminderEntity(
_wechatConfig = value
}
val hasCalendarConfig: Boolean
get() = _calendarConfig != null
var calendarConfig: CalendarConfig
get() = _calendarConfig ?: CalendarConfig()
set(value) {
_calendarConfig = value
}
val onlyShowWechatReminder: Boolean
get() = _smsConfig == null
val mirrorType: String
get() = _mirrorType ?: ""
@ -89,39 +81,4 @@ class ReserveReminderEntity(
}
}
@Parcelize
class CalendarConfig(
@SerializedName("notice")
private val _notice: Boolean? = null,
@SerializedName("title")
private val _title: String? = null,
@SerializedName("time_start")
private val _timeStart: Long? = null,
@SerializedName("time_end")
private val _timeEnd: Long? = null,
@SerializedName("advance_seconds")
private val _advanceSeconds: Long? = null,
@SerializedName("remark")
private val _remark: String? = null
) : Parcelable {
val notice: Boolean
get() = _notice ?: false
val title: String
get() = _title ?: ""
val timeStart: Long
get() = _timeStart ?: 0L
val timeEnd: Long
get() = _timeEnd ?: 0L
val advanceSeconds: Long
get() = _advanceSeconds ?: 0L
val remark: String
get() = _remark ?: ""
}
}

View File

@ -130,13 +130,12 @@ data class SubjectEntity(
@IgnoredOnParcel
private var filteredData: MutableList<GameEntity>? = null
val subjectType: SubjectData.SubjectType
get() = when {
isQQColumn -> SubjectData.SubjectType.QQ_GAME
isWechatColumnCPM -> SubjectData.SubjectType.WECHAT_GAME_CPM
isWechatColumn -> SubjectData.SubjectType.WECHAT_GAME
else -> SubjectData.SubjectType.NORMAL
}
val subjectType: SubjectData.SubjectType get() = when {
isQQColumn -> SubjectData.SubjectType.QQ_GAME
isWechatColumnCPM -> SubjectData.SubjectType.WECHAT_GAME_CPM
isWechatColumn -> SubjectData.SubjectType.WECHAT_GAME
else -> SubjectData.SubjectType.NORMAL
}
val isMiniGame: Boolean get() = isQQColumn || isWechatColumn
@ -149,11 +148,4 @@ data class SubjectEntity(
val list: Int
get() = max(min(_list ?: 0, data?.size ?: 0), 1)
companion object {
const val SUBJECT_TAG_UPDATE = "update" // 更新时间
const val SUBJECT_TAG_TYPE = "type" // 游戏标签
const val SUBJECT_TAG_TEST = "test" // 开测时间
const val SUBJECT_TAG_SELLING_POINT = "selling_points&type" // 卖点文案+游戏标签
}
}

View File

@ -1,5 +0,0 @@
package com.gh.gamecenter.eventbus
import com.gh.gamecenter.feature.entity.AcctGameInfo
class EBStartupAcceleration(val acctGameInfo: AcctGameInfo)

View File

@ -8,6 +8,7 @@ import android.text.SpannableStringBuilder
import android.view.View
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.common.util.*
import com.gh.common.util.DialogUtils
import com.gh.common.util.LogUtils
import com.gh.common.util.NewLogUtils
import com.gh.common.view.ImageContainerView
@ -16,18 +17,22 @@ import com.gh.gamecenter.ImageViewerActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.gamecenter.common.callback.ConfirmListener
import com.gh.gamecenter.common.entity.AdditionalParamsEntity
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.MtaHelper
import com.gh.gamecenter.core.utils.SpanBuilder
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.databinding.CommunityAnswerItemBinding
import com.gh.gamecenter.feature.entity.ForumVideoEntity
import com.gh.gamecenter.eventbus.EBUserFollow
import com.gh.gamecenter.forum.detail.ForumDetailActivity
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.qa.answer.BaseAnswerOrArticleItemViewHolder
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.feature.entity.AnswerEntity
import com.gh.gamecenter.feature.entity.ArticleEntity
import com.gh.gamecenter.feature.entity.CommunityItemData
import com.gh.gamecenter.feature.entity.ForumVideoEntity
import com.gh.gamecenter.forum.detail.ForumDetailActivity
import com.gh.gamecenter.forum.home.ArticleItemVideoView.Companion.toArticleVideoData
import com.gh.gamecenter.forum.search.CommunitySearchEventListener
import com.gh.gamecenter.forum.search.CommunitySearchEventListener.Companion.SEARCH_BUTTON_COMMENT
@ -39,9 +44,6 @@ import com.gh.gamecenter.forum.search.CommunitySearchEventListener.Companion.SEA
import com.gh.gamecenter.forum.search.CommunitySearchEventListener.Companion.SEARCH_BUTTON_VIEW_IMAGE
import com.gh.gamecenter.forum.search.CommunitySearchEventListener.Companion.SEARCH_BUTTON_VIEW_USER_DETAIL
import com.gh.gamecenter.forum.search.CommunitySearchEventListener.Companion.htmlToString
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.qa.answer.BaseAnswerOrArticleItemViewHolder
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.qa.entity.QuestionsDetailEntity
import com.gh.gamecenter.qa.questions.invite.QuestionsInviteActivity
import com.gh.gamecenter.qa.questions.newdetail.NewQuestionDetailActivity
@ -346,8 +348,8 @@ class ForumArticleAskItemViewHolder(
.setReleaseWhenLossAudio(true)
.setLooping(false)
.setShowFullAnimation(false)
.setEnlargeImageRes(R.drawable.ic_video_enter_full_screen)
.setShrinkImageRes(R.drawable.ic_video_exit_full_screen)
.setEnlargeImageRes(R.drawable.ic_game_detail_enter_full_screen)
.setShrinkImageRes(R.drawable.ic_game_detail_exit_full_screen)
.setVideoAllCallBack(object : GSYSampleCallBack() {
override fun onQuitFullscreen(url: String?, vararg objects: Any) {
orientationUtils.backToProtVideo()

View File

@ -37,9 +37,9 @@ class UserSearchListFragment : LazyListFragment<FollowersOrFansEntity, UserSearc
SensorsBridge.trackUserSearchResultClick(
GlobalActivityManager.getCurrentPageEntity().pageId,
GlobalActivityManager.getCurrentPageEntity().pageName,
mListViewModel.sourceEntrance,
mSearchKey,
SearchActivity.toTrackSearchType(mSearchType),
mListViewModel.sourceEntrance,
userId,
position
)

View File

@ -3,29 +3,26 @@ package com.gh.gamecenter.game.horizontal
import android.content.Context
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.DataCollectionUtils
import com.gh.common.util.DownloadItemUtils
import com.gh.common.util.*
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.GameDetailActivity
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.StringUtils
import com.gh.gamecenter.entity.SubjectEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.minigame.MiniGameItemHelper
import com.gh.gamecenter.gamedetail.detail.viewholder.BaseGameDetailItemViewHolder
import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.subjectTypeToComponentStyle
import com.gh.gamecenter.feature.minigame.MiniGameItemHelper
import com.lightgame.adapter.BaseRecyclerAdapter
import com.lightgame.download.DownloadEntity
class GameHorizontalAdapter(
context: Context,
var subjectEntity: SubjectEntity,
private var mSubjectEntity: SubjectEntity,
private var type: GameHorizontalListType = GameHorizontalListType.SubjectHorizontalType,
private val trackColumnClick: Boolean = true,
private val gameDetailTrackData: BaseGameDetailItemViewHolder.GameDetailModuleTrackData? = null,
private val getGameStatus: (() -> String)? = null
private val trackColumnClick: Boolean = true
) : BaseRecyclerAdapter<GameHorizontalItemViewHolder>(context) {
var gameName = ""
@ -40,15 +37,15 @@ class GameHorizontalAdapter(
init {
var dataIds = ""
subjectEntity.data?.forEach {
mSubjectEntity.data?.forEach {
dataIds += it.id
}
if (dataIds.isNotEmpty()) countAndKey = Pair(subjectEntity.data?.size ?: 0, dataIds)
if (dataIds.isNotEmpty()) countAndKey = Pair(mSubjectEntity.data?.size ?: 0, dataIds)
}
fun getIndex(): Int {
if (subjectEntity.data!!.isNotEmpty()) {
return if (subjectEntity.data!![0].image.isNullOrEmpty()) 0 else 1
if (mSubjectEntity.data!!.isNotEmpty()) {
return if (mSubjectEntity.data!![0].image.isNullOrEmpty()) 0 else 1
}
return 0
}
@ -56,13 +53,13 @@ class GameHorizontalAdapter(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = GameHorizontalItemViewHolder(parent.toBinding())
override fun getItemCount(): Int {
val size = subjectEntity.data!!.size - getIndex()
val size = mSubjectEntity.data!!.size - getIndex()
return when (type) {
GameHorizontalListType.GameDetailHorizontalType -> {
size
}
GameHorizontalListType.MiniGameSubjectHorizontalType -> {
subjectEntity.data!!.size
mSubjectEntity.data!!.size
}
else -> when {
size < 4 -> size
@ -83,15 +80,14 @@ class GameHorizontalAdapter(
}
holder.binding.root.layoutParams = params
val gameEntity = subjectEntity.data!![position + getIndex()]
val gameEntity = mSubjectEntity.data!![position + getIndex()]
holder.binding.simpleGameContainer.run {
gameIcon.displayGameIcon(gameEntity)
GameHorizontalSimpleItemViewHolder.setHorizontalNameAndGravity(gameName, gameEntity.name)
downloadBtn.goneIf(!subjectEntity.showDownload)
gameName.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(mContext))
gameName.maxLines = if (subjectEntity.showDownload) 1 else 2
downloadBtn.goneIf(!mSubjectEntity.showDownload)
gameName.maxLines = if (mSubjectEntity.showDownload) 1 else 2
}
holder.bindGameHorizontalItem(gameEntity, subjectEntity)
holder.bindGameHorizontalItem(gameEntity, mSubjectEntity)
val entranceResult: String
val locationResult: String
if (type == GameHorizontalListType.GameDetailHorizontalType) {
@ -108,35 +104,37 @@ class GameHorizontalAdapter(
locationResult = StringUtils.buildString("游戏详情-", gameName, "-${path}", ":", gameEntity.name)
} else {
entranceResult =
StringUtils.buildString("(游戏-专题:", subjectEntity.name, "-列表[", (position + 1).toString(), "])")
locationResult = StringUtils.buildString("游戏-专题-", subjectEntity.name, ":", gameEntity.name)
StringUtils.buildString("(游戏-专题:", mSubjectEntity.name, "-列表[", (position + 1).toString(), "])")
locationResult = StringUtils.buildString("游戏-专题-", mSubjectEntity.name, ":", gameEntity.name)
}
holder.itemView.setOnClickListener {
if (type == GameHorizontalListType.GameDetailHorizontalType) {
DataCollectionUtils.uploadClick(mContext, path, "游戏详情", gameEntity.name)
NewLogUtils.logGameDetailPopularClick(gameName, gameId, "game", gameEntity.name ?: "")
SensorsBridge.trackGameDetailModuleClick(
gameDetailTrackData?.gameId,
gameDetailTrackData?.gameName,
gameDetailTrackData?.gameType,
"组件内容",
gameDetailTrackData?.moduleType,
gameDetailTrackData?.moduleName,
gameDetailTrackData?.sequence,
linkType = "game",
linkId = gameEntity.id,
linkText = gameEntity.name ?: "",
gameStatus = getGameStatus?.invoke()
SensorsBridge.trackGameDetailPagePopularClick(
gameId = gameId,
gameName = gameName,
pageName = GlobalActivityManager.getCurrentPageEntity().pageName,
pageId = GlobalActivityManager.getCurrentPageEntity().pageId,
pageBusinessId = GlobalActivityManager.getCurrentPageEntity().pageBusinessId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId,
downloadStatus = game?.downloadStatusChinese ?: "",
gameType = game?.categoryChinese ?: "",
clickGameType = gameEntity.categoryChinese,
clickGameName = gameEntity.name ?: "",
clickGameId = gameEntity.id
)
if (!gameEntity.isMiniGame() && trackColumnClick) {
SensorsBridge.trackColumnClick(
location = "游戏详情",
gameName = gameName,
gameId = gameId,
gameColumnName = subjectEntity.name ?: "",
gameColumnId = subjectEntity.id ?: "",
gameColumnName = mSubjectEntity.name ?: "",
gameColumnId = mSubjectEntity.id ?: "",
text = "游戏",
columnPattern = subjectTypeToComponentStyle[subjectEntity.type] ?: ""
columnPattern = subjectTypeToComponentStyle[mSubjectEntity.type] ?: ""
)
}
}
@ -153,7 +151,7 @@ class GameHorizontalAdapter(
}
}
if (subjectEntity.showDownload && type != GameHorizontalListType.GameDetailHorizontalType) {
if (mSubjectEntity.showDownload && type != GameHorizontalListType.GameDetailHorizontalType) {
DownloadItemUtils.setOnClickListener(
mContext,
holder.binding.simpleGameContainer.downloadBtn,
@ -181,7 +179,7 @@ class GameHorizontalAdapter(
if (downloadEntity == null) {
notifyDataSetChanged()
} else {
subjectEntity.data?.forEachIndexed { position, gameEntity ->
mSubjectEntity.data?.forEachIndexed { position, gameEntity ->
if (downloadEntity.gameId == gameEntity.id) {
notifyItemChanged(position - getIndex())
return
@ -191,7 +189,7 @@ class GameHorizontalAdapter(
}
fun notifyChildItem(packageName: String) {
subjectEntity.data?.forEachIndexed { position, gameEntity ->
mSubjectEntity.data?.forEachIndexed { position, gameEntity ->
gameEntity.getApk().forEach { apkEntity ->
if (apkEntity.packageName == packageName) {
notifyItemChanged(position - getIndex())
@ -208,11 +206,11 @@ class GameHorizontalAdapter(
dataIds += it.id
}
this.subjectEntity = subjectEntity
if (countAndKey?.first != subjectEntity.data?.size) { // 数量发生改变
notifyDataSetChanged()
} else {
mSubjectEntity = subjectEntity
if (countAndKey?.first == subjectEntity.data?.size && countAndKey?.second != dataIds) { // 数量不变,内容发生改变
notifyItemRangeChanged(0, itemCount)
} else if (countAndKey?.first != subjectEntity.data?.size) { // 数量发生改变
notifyDataSetChanged()
}
// 重新刷新数据标识

View File

@ -3,10 +3,10 @@ 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
import android.view.LayoutInflater
import android.view.View
import android.widget.LinearLayout
import android.widget.Space
@ -17,12 +17,11 @@ import androidx.core.content.ContextCompat
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieDrawable
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.gamecenter.R
import com.gh.gamecenter.common.databinding.LayoutGameItemSellingPointBinding
import com.gh.gamecenter.common.utils.setDrawableEnd
import com.gh.gamecenter.common.view.GameTagContainerView
import com.gh.gamecenter.feature.view.DownloadButton
import com.gh.gamecenter.feature.view.GameIconView
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.setDrawableEnd
import com.gh.gamecenter.common.view.GameTagContainerView
import splitties.dimensions.dip
import splitties.views.backgroundColor
import splitties.views.dsl.constraintlayout.*
@ -64,7 +63,6 @@ class GameItemUi(override val ctx: Context) : Ui {
var gamePlayCountTv: TextView
var mGameDesSpace: Space
var sellingPointsBinding: LayoutGameItemSellingPointBinding
override val root: ConstraintLayout = constraintLayout {
padding = dip(16)
@ -86,7 +84,6 @@ class GameItemUi(override val ctx: Context) : Ui {
gameTagContainer = GameTagContainerView(ctx).apply { id = R.id.label_list }
mGameDesSpace = space { }.apply { id = R.id.gameDesSpace }
recommendConstraintLayout = initRecommendConstraintLayout()
sellingPointsBinding = LayoutGameItemSellingPointBinding.inflate(LayoutInflater.from(context))
add(iconIv, lParams(dip(64), dip(64)) {
topOfParent()
@ -145,12 +142,6 @@ class GameItemUi(override val ctx: Context) : Ui {
endToEndOf(mGameDesSpace)
orientation = LinearLayout.HORIZONTAL
})
add(sellingPointsBinding.root, lParams(0, wrapContent) {
topToBottomOf(mGameDesSpace)
bottomToBottomOf(iconIv)
startToEndOf(gamePlayCountTv)
endToEndOf(mGameDesSpace)
})
add(gamePlayCountTv, lParams(wrapContent, wrapContent) {
topToBottomOf(mGameDesSpace)
bottomToBottomOf(iconIv)
@ -206,8 +197,7 @@ class GameItemUi(override val ctx: Context) : Ui {
startPadding = dip(2)
endPadding = dip(2)
ellipsize = TextUtils.TruncateAt.END
background =
ContextCompat.getDrawable(context, com.gh.gamecenter.feature.R.drawable.bg_advance_download_game_subtitle)
background = ContextCompat.getDrawable(context, com.gh.gamecenter.feature.R.drawable.bg_advance_download_game_subtitle)
setTextColor(ContextCompat.getColor(context, com.gh.gamecenter.common.R.color.text_secondary))
visibility = View.GONE
}
@ -315,12 +305,7 @@ class GameItemUi(override val ctx: Context) : Ui {
gravity = Gravity.CENTER
text = "展开"
setTextColor(ContextCompat.getColor(context, com.gh.gamecenter.common.R.color.white))
setDrawableEnd(
AppCompatResources.getDrawable(
context,
com.gh.gamecenter.feature.R.drawable.ic_jump_universal
)
)
setDrawableEnd(AppCompatResources.getDrawable(context, com.gh.gamecenter.feature.R.drawable.ic_jump_universal))
compoundDrawablePadding = dip(2)
visibility = View.GONE
}

View File

@ -166,7 +166,7 @@ class GameVerticalAdapter(
false
)
BindingAdapters.setGame(iconIv, gameEntity)
BindingAdapters.setGameTags(gameTagContainer, gameEntity, subjectData?.tag ?: "")
BindingAdapters.setGameTags(gameTagContainer, gameEntity)
GameItemViewHolder.initServerType(gameNameTv, serverTypeTv, gameEntity)
gameDesTv.text = gameEntity.decoratedDes
GameItemViewHolder.initGameSubtitleAndAdLabel(
@ -225,10 +225,10 @@ class GameVerticalAdapter(
subjectData?.briefStyle
)
DownloadItemUtils.setOnClickListener(
context, downloadTv, gameEntity, position,
adapter, entrance, location = location, traceEvent = gameEntity.exposureEvent
)
DownloadItemUtils.setOnClickListener(
context, downloadTv, gameEntity, position,
adapter, entrance, location = location, traceEvent = gameEntity.exposureEvent
)
root.setPadding(paddingStart, 8F.dip2px(), paddingEnd, 8F.dip2px())
}

View File

@ -610,7 +610,7 @@ open class GameCollectionDetailAdapter(
gameIconView.displayGameIcon(gameEntity)
gameRating.textSize = if (gameEntity.commentCount > 3) 12F else 10F
BindingAdapters.setGameName(gameName, gameEntity, false)
BindingAdapters.setGameTags(labelList, gameEntity, "")
BindingAdapters.setGameTags(labelList, gameEntity)
gameRating.setDrawableStart(
if (gameEntity.commentCount > 3) com.gh.gamecenter.feature.R.drawable.game_horizontal_rating.toDrawable(mContext) else null
)

View File

@ -39,6 +39,7 @@ import com.gh.gamecenter.common.syncpage.SyncDataEntity
import com.gh.gamecenter.common.syncpage.SyncFieldConstants
import com.gh.gamecenter.common.syncpage.SyncPageRepository
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.SegmentedFilterView
import com.gh.gamecenter.core.iinterface.IScrollable
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.databinding.FragmentGameCollectionDetailBinding
@ -47,6 +48,7 @@ import com.gh.gamecenter.entity.GamesCollectionDetailEntity
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.eventbus.EBUserFollow
import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.gh.gamecenter.home.video.ScrollCalculatorHelper
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.login.user.UserViewModel
@ -185,10 +187,12 @@ class GameCollectionDetailFragment :
root.layoutParams = this
}
orderSfv.setItemList(listOf("正序", "倒序"), 0)
orderSfv.setOnCheckedCallback { position ->
getFilterVH()?.binding?.orderSfv?.performClick(position)
updateFilterView()
}
orderSfv.setOnCheckedCallback(object : SegmentedFilterView.OnCheckedCallback {
override fun onItemCheck(position: Int) {
getFilterVH()?.binding?.orderSfv?.performClick(position)
updateFilterView()
}
})
commentHintTv.text = "玩家评论"
}
}
@ -737,7 +741,7 @@ class GameCollectionDetailFragment :
if (activity != null && activity?.isFinishing != true) {
startPlayLogic(isAutoPlay = true)
}
}, INITIAL_DELAY)
}, GameDetailFragment.INITIAL_DELAY)
}
}
}
@ -1206,8 +1210,4 @@ class GameCollectionDetailFragment :
appbar.setExpanded(true)
}
}
companion object {
const val INITIAL_DELAY = 500L
}
}

View File

@ -13,15 +13,15 @@ import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.observer.MuteCallback
import com.gh.gamecenter.common.observer.VolumeObserver
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.common.utils.NetworkUtils
import com.gh.gamecenter.core.runOnIoThread
import com.gh.common.util.*
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.debounceActionWithInterval
import com.gh.gamecenter.common.utils.rxTimer
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.common.utils.NetworkUtils
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.entity.GamesCollectionDetailEntity
import com.gh.gamecenter.home.video.ScrollCalculatorHelper
@ -180,7 +180,7 @@ class GameCollectionVideoView @JvmOverloads constructor(context: Context, attrs:
private fun mute(isManual: Boolean = false) {
viewModel?.videoIsMuted = true
volume.setImageResource(R.drawable.ic_video_volume_off)
volume.setImageResource(R.drawable.ic_game_detail_volume_off)
CustomManager.getCustomManager(getKey()).isNeedMute = true
if (isManual) {
Utils.toast(context, "当前处于静音状态")
@ -190,7 +190,7 @@ class GameCollectionVideoView @JvmOverloads constructor(context: Context, attrs:
private fun unMute(isManual: Boolean = false) {
viewModel?.videoIsMuted = false
volume.setImageResource(R.drawable.ic_video_volume_on)
volume.setImageResource(R.drawable.ic_game_detail_volume_on)
CustomManager.getCustomManager(getKey()).isNeedMute = false
if (isManual) {
logVideoEvent("video_game_collect_detail_mute_cancel")
@ -278,9 +278,9 @@ class GameCollectionVideoView @JvmOverloads constructor(context: Context, attrs:
if (mStartButton is ImageView) {
val imageView = mStartButton as ImageView
when (mCurrentState) {
GSYVideoView.CURRENT_STATE_PLAYING -> imageView.setImageResource(R.drawable.ic_video_pause)
GSYVideoView.CURRENT_STATE_ERROR -> imageView.setImageResource(R.drawable.ic_video_play)
else -> imageView.setImageResource(R.drawable.ic_video_play)
GSYVideoView.CURRENT_STATE_PLAYING -> imageView.setImageResource(R.drawable.ic_game_detail_pause)
GSYVideoView.CURRENT_STATE_ERROR -> imageView.setImageResource(R.drawable.ic_game_detail_play)
else -> imageView.setImageResource(R.drawable.ic_game_detail_play)
}
}
}
@ -314,11 +314,11 @@ class GameCollectionVideoView @JvmOverloads constructor(context: Context, attrs:
}
override fun getEnlargeImageRes(): Int {
return R.drawable.ic_video_enter_full_screen
return R.drawable.ic_game_detail_enter_full_screen
}
override fun getShrinkImageRes(): Int {
return R.drawable.ic_video_exit_full_screen
return R.drawable.ic_game_detail_exit_full_screen
}
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {

View File

@ -73,7 +73,6 @@ class GameCollectionHotListAdapter(
if (holder is GameCollectionPlayerCreationAdapter.GameCollectionPlayerCreationHeaderItemViewHolder) {
holder.binding.run {
root.setPadding(0, if (mIsFromDetail) 16F.dip2px() else 0, 0, 12F.dip2px())
timeSfv.visibility = View.GONE
tipsIv.visibility = View.GONE
tipsTv.text = mGameCollectionListEntity?.explain
tipsTv.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(mContext))

View File

@ -617,7 +617,6 @@ class GameCollectionSquareFragment : LazyListFragment<GamesCollectionEntity, Gam
mAlternativeBinding.listRv.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if (!isSupportVisible) return
if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
setFabStatus(mPostFabView, View.GONE)
setFabStatus(mRefreshFabView, View.GONE)

View File

@ -1,13 +0,0 @@
package com.gh.gamecenter.gamedetail
import androidx.lifecycle.ViewModel
import com.halo.assistant.accelerator.AccelerationUseCase
class AcceleratorZoneViewModel : ViewModel() {
val useCase = AccelerationUseCase()
override fun onCleared() {
useCase.onClear()
}
}

View File

@ -0,0 +1,51 @@
package com.gh.gamecenter.gamedetail
import android.content.Context
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.common.utils.safelyGetInRelease
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.core.utils.TimeUtils
import com.gh.gamecenter.databinding.ItemGameDetailContentCardContentBinding
import com.gh.gamecenter.gamedetail.entity.ContentCardEntity
import com.lightgame.adapter.BaseRecyclerAdapter
class GameDetailContentCardContentAdapter(
context: Context,
private val linkEntity: ContentCardEntity,
private val isHighlightBg: Boolean = false
) : BaseRecyclerAdapter<RecyclerView.ViewHolder>(context) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder =
GameDetailContentCardContentItemViewHolder(parent.toBinding())
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is GameDetailContentCardContentItemViewHolder) {
holder.binding.root.setTextColor(
if (isHighlightBg) com.gh.gamecenter.common.R.color.text_secondary.toColor(mContext) else com.gh.gamecenter.common.R.color.text_tertiary.toColor(
mContext
)
)
if (linkEntity.type == "func_server" && linkEntity.server != null && linkEntity.server?.calendar?.isNotEmpty() == true) {
val calendarList = linkEntity.server!!.calendar
val realPosition = position % calendarList.size
calendarList.safelyGetInRelease(realPosition)?.let {
val serverTime =
if (TimeUtils.isToday(it.getTime()))
it.getFormatTime("今天 HH:mm")
else if (TimeUtils.isTomorrow(it.getTime()))
it.getFormatTime("明天 HH:mm")
else
it.getFormatTime("MM-dd HH:mm")
holder.binding.root.text = "$serverTime ${it.type}"
}
}
}
}
override fun getItemCount(): Int = Int.MAX_VALUE
class GameDetailContentCardContentItemViewHolder(var binding: ItemGameDetailContentCardContentBinding) :
RecyclerView.ViewHolder(binding.root)
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,57 @@
package com.gh.gamecenter.gamedetail
import android.os.Bundle
import android.view.View
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.BaseFragment
import com.gh.gamecenter.common.utils.toDrawable
import com.gh.gamecenter.feature.entity.LibaoEntity
import com.gh.gamecenter.gamedetail.desc.GameLibaoAdapter
class LibaoListFragment : BaseFragment<Any>() {
override fun getLayoutId() = R.layout.fragment_libao_list
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val recyclerView = view.findViewById<RecyclerView>(R.id.recyclerView)
val toolbarTitleTv = view.findViewById<TextView>(R.id.normal_title)
val toolbarBackContainer = view.findViewById<View>(com.gh.gamecenter.selector.R.id.backContainer)
toolbarTitleTv.setText("游戏礼包")
toolbarBackContainer.setOnClickListener { requireActivity().onBackPressed() }
val gameId = arguments?.getString(ARG_GAME_ID) ?: ""
val gameName = arguments?.getString(ARG_GAME_NAME) ?: ""
val libaoList = arguments?.getParcelableArrayList<LibaoEntity>(ARG_LIBAO_LIST) ?: arrayListOf()
recyclerView?.apply {
layoutManager = LinearLayoutManager(requireContext())
adapter = adapter ?: GameLibaoAdapter(requireContext(), libaoList, gameName, gameId, false, true)
}
}
companion object {
private const val ARG_GAME_ID = "game_id"
private const val ARG_GAME_NAME = "game_name"
private const val ARG_LIBAO_LIST = "libao_list"
fun getBundle(gameId: String, gameName: String, libaoList: ArrayList<LibaoEntity>) = Bundle().apply {
putString(ARG_GAME_ID, gameId)
putString(ARG_GAME_NAME, gameName)
putParcelableArrayList(ARG_LIBAO_LIST, libaoList)
}
fun newInstance(bundle: Bundle?) = LibaoListFragment().apply {
if (bundle != null) {
arguments = bundle
}
}
}
}

View File

@ -1,72 +0,0 @@
package com.gh.gamecenter.gamedetail
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.feature.entity.BaseEntity
import com.gh.gamecenter.feature.entity.TrialEntity
import com.gh.gamecenter.feature.entity.VipEntity
import com.gh.gamecenter.livedata.Event
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.login.user.UserRepository
import com.halo.assistant.accelerator.AccelerationUseCase
import com.halo.assistant.accelerator.repository.AcceleratorDataHolder
import io.reactivex.disposables.CompositeDisposable
class StartingAcceleratorViewModel : ViewModel() {
private val compositeDisposable = CompositeDisposable()
val useCase = AccelerationUseCase()
private val _restartingAcceleratorAction = MutableLiveData<Event<Unit>>()
val restartingAcceleratorAction: LiveData<Event<Unit>> = _restartingAcceleratorAction
fun loadAcceleratorToken() {
val userId = UserManager.getInstance().userId
if (userId.isNotBlank()) {
UserRepository.getInstance().setAcceleratorToken(userId) {
// 这里就算setToken失败也要调用启动加速失败会走正常的日志上报
_restartingAcceleratorAction.value = Event(Unit)
}
}
}
private val _rechargeTrailResult = MutableLiveData<Event<Boolean>>()
val rechargeTrailResult: LiveData<Event<Boolean>> = _rechargeTrailResult
fun rechargeTrial() {
val userId = UserManager.getInstance().userId
useCase.rechargeTrial(userId)
.compose(singleToMain())
.subscribe(object : BiResponse<BaseEntity<TrialEntity>>() {
override fun onSuccess(data: BaseEntity<TrialEntity>) {
if (data.data?.result == true) {
// 刷新vip状态
// 这里先刷新内存数据
AcceleratorDataHolder.instance.setVipEntity(
VipEntity(
_vipStatus = true,
_isNewUser = false,
_isTryVip = true
)
)
_rechargeTrailResult.value = Event(true)
} else {
_rechargeTrailResult.value = Event(false)
}
}
override fun onFailure(exception: Exception) {
super.onFailure(exception)
_rechargeTrailResult.value = Event(false)
}
}).let(compositeDisposable::add)
}
override fun onCleared() {
super.onCleared()
compositeDisposable.clear()
}
}

View File

@ -1,49 +0,0 @@
package com.gh.gamecenter.gamedetail.accelerator
import androidx.room.Dao
import androidx.room.Query
import androidx.room.Upsert
import com.gh.gamecenter.feature.entity.AcctGameInfo
import com.gh.gamecenter.feature.entity.AcctRecord
import io.reactivex.Observable
import io.reactivex.Single
@Dao
interface AccelerationDao {
@Upsert
fun upsertAcctGameInfo(gameInfo: AcctGameInfo): Single<Long>
@Upsert
fun upsertAcctRecord(record: AcctRecord): Single<Long>
/**
* 为什么这里定义成 Observable<List<AcctGameInfo>> 而不是 Observable<AcctGameInfo>
* 因为当返回值为 Observable<T> 时,当表中未查询到数据,则不会收到任何回调
* 使用 Observable<List<AcctGameInfo>>时,为查询到数据时会返回空数组
*/
@Query("SELECT * FROM AcctGameInfo WHERE gameId = :gameId")
fun getAcctGameInfoByGameIdObservable(gameId: String): Observable<List<AcctGameInfo>>
@Query("SELECT EXISTS(SELECT 1 FROM AcctGameInfo LIMIT 1)")
fun hasAnyAcctGameInfo(): Single<Boolean>
@Query("SELECT * FROM AcctGameInfo WHERE gameId IN (:gameIds)")
fun queryAcctGameInfoByGameId(gameIds: List<String>): List<AcctGameInfo>
@Query("SELECT * FROM AcctRecord ORDER BY createTime DESC LIMIT 20")
fun loadAcctRecordsObservable(): Observable<List<AcctRecord>>
@Query("SELECT * FROM AcctRecord ORDER BY createTime DESC LIMIT 20")
fun loadAcctRecords(): List<AcctRecord>
/**
* 获取最新的记录根据createTime排序
* @return 最新的AcctRecord记录
*/
@Query("SELECT * FROM AcctRecord ORDER BY createTime DESC LIMIT 1")
fun loadLatestRecord(): Single<AcctRecord>
@Query("SELECT EXISTS(SELECT 1 FROM AcctRecord LIMIT 1)")
fun getAnyAcctRecordObservable(): Observable<Boolean>
}

View File

@ -1,93 +0,0 @@
package com.gh.gamecenter.gamedetail.accelerator
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import com.gh.gamecenter.feature.entity.AcctGameInfo
import com.gh.gamecenter.feature.entity.AcctRecord
import com.gh.gamecenter.room.converter.AcctGameInfoConverter
import com.halo.assistant.HaloApp
@Database(
entities = [AcctGameInfo::class, AcctRecord::class],
version = 2,
exportSchema = false
)
@TypeConverters(
AcctGameInfoConverter::class
)
abstract class AccelerationDataBase : RoomDatabase() {
abstract fun accelerationDao(): AccelerationDao
companion object {
private const val DATABASE_NAME: String = "acceleration_db"
val instance: AccelerationDataBase by lazy { buildDatabase(HaloApp.getInstance().application) }
private fun buildDatabase(context: Context): AccelerationDataBase {
return Room.databaseBuilder(context, AccelerationDataBase::class.java, DATABASE_NAME)
.addMigrations(MIGRATION_1_2)
.allowMainThreadQueries()
.build()
}
private val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(db: SupportSQLiteDatabase) {
// 删除表 AcctZoneListBean
db.execSQL("DROP TABLE IF EXISTS AcctZoneListBean")
// 创建新表的SQL ,游戏加速成功记录
createAcctRecordTab(db)
renamePrimaryKeyWithAcctGameInfoTab(db)
}
private fun createAcctRecordTab(db: SupportSQLiteDatabase) {
db.execSQL(
"""
CREATE TABLE IF NOT EXISTS AcctRecord (
gameId TEXT PRIMARY KEY NOT NULL,
game TEXT NOT NULL,
zoneInfo TEXT NOT NULL,
hasMultiZone INTEGER NOT NULL,
createTime INTEGER NOT NULL
)
"""
)
}
/**
* 重命名表 AcctGameInfo 主键
* 游戏旧表中没有 gameId 字段,这里将旧表数据直接清空
*/
private fun renamePrimaryKeyWithAcctGameInfoTab(db: SupportSQLiteDatabase) {
// 1. 创建临时表(包含新的结构)
db.execSQL(
"""
CREATE TABLE IF NOT EXISTS AcctGameInfo_temp (
gameId TEXT PRIMARY KEY NOT NULL,
accGamePkgName TEXT NOT NULL,
zoneInfo TEXT NOT NULL,
notifyGameName TEXT,
notifyGameTxtTitle TEXT,
notifyGameSmallLogo INTEGER,
notifyGameLargeLogo INTEGER,
notifyClickParam TEXT
)
"""
)
// 2. 删除旧表
db.execSQL("DROP TABLE AcctGameInfo")
// 3. 重命名新表
db.execSQL("ALTER TABLE AcctGameInfo_temp RENAME TO AcctGameInfo")
}
}
}
}

View File

@ -1,182 +0,0 @@
package com.gh.gamecenter.gamedetail.accelerator
import android.app.Activity
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.core.view.updateLayoutParams
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.databinding.LayoutAcceleratorGuidePageBinding
class AcceleratorGuideView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
def: Int = 0
) : FrameLayout(context, attrs, def) {
private val binding: LayoutAcceleratorGuidePageBinding
private val rect = Rect()
private var _isShowing = false
val isShowing: Boolean
get() = _isShowing
private var isCanDismiss = false
private val guideBackgroundColor =
com.gh.gamecenter.common.R.color.black_alpha_60.toColor(context)
private val xfermode by lazy {
val mode = PorterDuff.Mode.CLEAR
PorterDuffXfermode(mode)
}
private val paint by lazy {
Paint().apply {
color = Color.YELLOW
isAntiAlias = true
isDither = true
}
}
private var onStartSpeed: (() -> Unit)? = null
init {
val inflater = LayoutInflater.from(context)
binding = LayoutAcceleratorGuidePageBinding.inflate(inflater, this, true)
binding.root.setOnClickListener {
// 点击透明区域消失
dismiss()
}
binding.clContainer.setOnClickListener {
//覆盖外部点击事件,点击此区域 guideView 不消失
}
binding.vIKnow.setOnClickListener {
dismiss()
}
binding.vSpeed.setOnClickListener {
dismiss()
onStartSpeed?.invoke()
}
}
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
super.onLayout(changed, left, top, right, bottom)
val bottom = rect.bottom
val top = bottom - binding.clContainer.height
val right = rect.right + BORDER_WIDTH.dip2px()
val left = right - binding.clContainer.width
binding.clContainer.layout(left, top, right, bottom)
}
override fun dispatchDraw(canvas: Canvas) {
val saveCount = canvas.saveLayer(0f, 0f, width.toFloat(), height.toFloat(), paint)
paint.color = guideBackgroundColor
canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint)
onDrawDecoration(canvas)
paint.xfermode = xfermode
canvas.drawRoundRect(
RectF(rect),
HIGH_LIGHT_RADIUS.dip2px().toFloat(),
HIGH_LIGHT_RADIUS.dip2px().toFloat(),
paint
)
paint.xfermode = null
canvas.restoreToCount(saveCount)
super.dispatchDraw(canvas)
}
private fun onDrawDecoration(canvas: Canvas) {
paint.color = com.gh.gamecenter.common.R.color.ui_surface.toColor(context)
val border = BORDER_WIDTH.dip2px()
val radius = HIGH_LIGHT_RADIUS.dip2px().toFloat()
val dRectF = RectF(
rect.left.toFloat() - border,
rect.top.toFloat() - border,
rect.right.toFloat() + border,
rect.bottom.toFloat() + border
)
canvas.drawRoundRect(dRectF, radius, radius, paint)
}
private fun setHighLightRect(newRect: Rect) {
rect.set(newRect)
binding.vSpeed.updateLayoutParams {
width = rect.width()
}
}
fun show(anchor: View, activity: Activity, block: () -> Unit) {
onStartSpeed = block
val newRect = getLocationInWindow(anchor)
val content = activity.window.decorView as ViewGroup
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
setHighLightRect(newRect)
content.addView(this)
setOnClickListener {
if (isCanDismiss) {
dismiss()
}
}
setOnClickListener {
}
_isShowing = true
isCanDismiss = false
AppExecutor.uiExecutor.executeWithDelay({
isCanDismiss = true
}, SHOW_MIN_DURATION)
}
fun dismiss() {
(parent as? ViewGroup)?.removeView(this)
_isShowing = false
onDismissListener?.invoke()
}
private var onDismissListener: (() -> Unit)? = null
fun setDismissListener(listener: () -> Unit) {
onDismissListener = listener
}
private fun getLocationInWindow(anchor: View): Rect {
val result = Rect()
val pos = IntArray(2)
anchor.getLocationInWindow(pos)
result.left = pos[0]
result.top = pos[1]
result.right = result.left + anchor.width
result.bottom = result.top + anchor.height
return result
}
companion object {
private const val BORDER_WIDTH = 4F
private const val HIGH_LIGHT_RADIUS = 100F
private const val SHOW_MIN_DURATION = 500L
}
}

View File

@ -1,368 +0,0 @@
package com.gh.gamecenter.gamedetail.accelerator
import android.content.Context
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import com.gh.common.util.CheckLoginUtils
import com.gh.common.util.PackageLauncher
import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.callback.AccelerateState
import com.gh.gamecenter.core.callback.OnAccelerateListener
import com.gh.gamecenter.core.provider.IAcceleratorProvider
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.databinding.DetailDownloadItemBinding
import com.gh.gamecenter.feature.entity.AcctGameInfo
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.VipEntity
import com.gh.gamecenter.gamedetail.accelerator.chain.AcceleratorClient
import com.gh.gamecenter.gamedetail.accelerator.chain.AcceleratorValidator
import com.gh.gamecenter.gamedetail.accelerator.dialog.AcceleratorDialogFragment
import com.gh.gamecenter.gamedetail.accelerator.dialog.AcceleratorDialogFragment.Companion.SPEED_STOP
import com.gh.gamecenter.gamedetail.accelerator.dialog.AcceleratorZoneDialogFragment
import com.gh.gamecenter.gamedetail.accelerator.dialog.StartingAcceleratorDialogFragment
import com.halo.assistant.accelerator.repository.AcceleratorDataHolder
import com.therouter.TheRouter
class GameDetailAcceleratorUiHelper(private val binding: DetailDownloadItemBinding) {
private var iAcceleratorProvider = TheRouter.get(IAcceleratorProvider::class.java)
private var guideView: AcceleratorGuideView? = null
private lateinit var game: GameEntity
private var isGuideLayerShowing = false
private var _last: AcctGameInfo? = null
private val last: AcctGameInfo?
get() = _last
private val hasMultiZone: Boolean
get() = game.serviceArea.size > 1
private val isVip: Boolean
get() = AcceleratorDataHolder.instance.isVip
val isNewUser: Boolean
get() = AcceleratorDataHolder.instance.isNewUser
private val isInit: Boolean
get() = ::game.isInitialized
val context: Context
get() = binding.root.context
private var hasAnyAcctRecord = false
private val accelerationListener = object : OnAccelerateListener {
override fun onStateChanged(state: AccelerateState) {
when (state) {
is AccelerateState.Success -> {
updateSpeedUi()
}
is AccelerateState.Normal -> {
updateSpeedUi()
}
else -> Unit
}
}
override fun onProgress(progress: Int, curGamePkgName: String?, curGameZoneFlag: String?) = Unit
}
private val onDataHolderListener = object : AcceleratorDataHolder.OnDataHolderListener {
override fun onVipStateChanged(vip: VipEntity) {
showFreeTag()
}
}
fun initUi(game: GameEntity, context: Context) {
this.game = game
iAcceleratorProvider?.bindAccRelatedListener(game.getUniquePackageName() ?: "", accelerationListener)
AcceleratorDataHolder.instance.addListener(onDataHolderListener)
binding.vSpeedContent.setOnClickListener {
startAccelerating(context, game, false)
}
binding.vMoreZone.setOnClickListener {
showZoneList(context, game)
}
binding.tvStopSpeed.setOnClickListener {
SensorsBridge.trackNetworkAccelerationOtherButtonClick(
game.getUniquePackageName() ?: "",
game.id,
game.name ?: "",
AcceleratorDataHolder.instance.memberType,
BUTTON_NAME_STOP_ACCELERATOR,
SOURCE_ENTRANCE_GAME_DETAIL
)
AcceleratorDialogFragment.show(
SPEED_STOP, game.getUniquePackageName() ?: "", game.id, game.name ?: "",
SOURCE_ENTRANCE_GAME_DETAIL, context
)
}
binding.tvEnterGame.setOnClickListener {
SensorsBridge.trackNetworkAccelerationOtherButtonClick(
game.getUniquePackageName() ?: "",
game.id,
game.name ?: "",
AcceleratorDataHolder.instance.memberType,
BUTTON_NAME_ENTER_GAME,
SOURCE_ENTRANCE_GAME_DETAIL
)
PackageLauncher.launchApp(context, game, game.getUniquePackageName())
}
updateSpeedUi()
}
fun updateSpeedUi() {
if (!isInit || !showSpeedUi) {
return
}
val isCurrentGameAccelerating = AcceleratorDataHolder.instance.isCurrentGameAccelerating(game.id)
when {
isCurrentGameAccelerating -> {// 如果当前游戏正处于加速状态,则需要隐藏当前下载按钮
binding.detailProgressbar.goneIf(true)
}
binding.detailProgressbar.text == "更新" -> { // 游戏没有处于加速状态,如果 下载按钮为 “更新” 状态,则需要显示出来
binding.detailProgressbar.goneIf(false)
}
}
binding.clSpeed.goneIf(isCurrentGameAccelerating)
binding.gAccelerating.goneIf(!isCurrentGameAccelerating)
binding.gMoreZone.goneIf(!hasMultiZone)
showFreeTag()
binding.tvSpeed.text = if (hasMultiZone) {
last?.zoneName
} else {
null
} ?: R.string.network_acceleration.toResString()
}
fun checkIfShowSpeedUi(show: Boolean) {
if (!isInit) {
return
}
showSpeedUi = show
binding.clSpeedContainer.goneIf(!showSpeedUi) {
binding.detailProgressbar.setBackgroundResource(com.gh.gamecenter.common.R.drawable.bg_common_button_light_fill_blue)
binding.detailProgressbar.setTextColor(com.gh.gamecenter.common.R.color.text_theme.toColor(context))
// 是否需要展示弹窗
showGuideLayerIfNeed()
updateSpeedUi()
}
}
private fun showFreeTag() {
binding.ivFreeVipTag.visibleIf(
showSpeedUi && last == null && !isGuideLayerShowing &&
(!CheckLoginUtils.isLogin() || isNewUser)
)
}
/**
* 需要同时满足这四个条件,才需要判断是否需要展示弹窗
*/
var isButtonSizeDetermined = false // 底部下载按钮尺寸是否已确定
private var isLastLoaded = false // 本地存在区服记录(用户点击过选择区服/启动加速)
private var hasAnyAcctRecordLoaded = false // 已获取:是否存在加速成功的游戏记录
private var showSpeedUi = false // 显示加速器ui
fun showGuideLayerIfNeed() {
if (isButtonSizeDetermined && hasAnyAcctRecordLoaded && isLastLoaded && showSpeedUi) {
if (shouldShowGuideLayer()) {
isGuideLayerShowing = true
showGuideLayer(context)
}
showFreeTag()
}
}
private fun shouldShowGuideLayer() =
!SPUtils.getBoolean(Constants.SP_HAS_SHOW_ACCELERATION_GUIDE_LAYER) &&
!hasAnyAcctRecord &&
last == null &&
!isGuideLayerShowing
private fun showGuideLayer(context: Context) {
binding.root.post {
val uiListener = object : OnAcceleratorListener {
override fun onStartAccelerator() {
startAccelerating(context, game, true)
}
override fun onGuideLayerDismiss() {
isGuideLayerShowing = false
showFreeTag()
}
}
SPUtils.setBoolean(Constants.SP_HAS_SHOW_ACCELERATION_GUIDE_LAYER, true)
if (guideView == null) {
guideView = AcceleratorGuideView(context).apply {
setDismissListener(uiListener::onGuideLayerDismiss)
}
}
(guideView?.parent as? ViewGroup)?.removeView(guideView)
if (context is AppCompatActivity) {
SensorsBridge.trackNetworkAccelerationGuidanceDiagramShow(
game.getUniquePackageName() ?: "",
game.id,
game.name ?: ""
)
guideView?.show(binding.clSpeedContainer, context, uiListener::onStartAccelerator)
}
}
}
fun onBack(): Boolean {
val isShowing = guideView?.isShowing ?: false
if (isShowing) {
guideView?.dismiss()
return true
} else {
return false
}
}
private fun startAccelerating(context: Context, game: GameEntity, isShowing: Boolean) {
if (isInvalidClick()) {
return
}
val lastAcctGameInfo = last
val memberType = AcceleratorDataHolder.instance.memberType
val districtServer = when {
hasMultiZone && lastAcctGameInfo != null -> lastAcctGameInfo.zoneName
hasMultiZone -> DISTRICT_SERVER_EMPTY
else -> DISTRICT_SERVER_HAVA
}
SensorsBridge.trackNetworkAccelerationButtonClick(
game.getUniquePackageName() ?: "",
game.id,
game.name ?: "",
memberType,
districtServer,
if (isShowing) SCENE_TYPE_HAVE_GUIDE_LAYER else SCENE_TYPE_NO_GUIDE_LAYER,
SOURCE_ENTRANCE_GAME_DETAIL
)
when {
lastAcctGameInfo != null ->
doStartAccelerating(context, game, lastAcctGameInfo.zoneInfo)
hasMultiZone -> context.ifLogin("[网络加速]") {
AcceleratorZoneDialogFragment.show(
context, last?.zoneInfo?.id, game.serviceArea, game,
SOURCE_ENTRANCE_GAME_DETAIL
)
}
else -> {
val gameInfo = game.serviceArea.firstOrNull() ?: AcctGameInfo.ZoneInfo(0)
doStartAccelerating(context, game, gameInfo)
}
}
}
private fun showZoneList(context: Context, game: GameEntity) {
if (isInvalidClick()) {
return
}
context.ifLogin("[网络加速]") {
AcceleratorZoneDialogFragment.show(
context, last?.zoneInfo?.id, game.serviceArea, game,
SOURCE_ENTRANCE_GAME_DETAIL
)
}
}
private var clickTime = 0L
private fun doStartAccelerating(context: Context, game: GameEntity, zoneInfo: AcctGameInfo.ZoneInfo) {
val request = AcceleratorValidator.Request(isVip, isNewUser, game, SOURCE_ENTRANCE_GAME_DETAIL)
AcceleratorClient.newInstance()
.execute(context, request, object : AcceleratorValidator.ValidateListener {
override fun finished(context: Context) {
StartingAcceleratorDialogFragment.show(
context, zoneInfo, game, true, hasMultiZone,
SOURCE_ENTRANCE_GAME_DETAIL,
)
}
})
}
fun setCurrentAcctGameInfo(acctGameInfo: AcctGameInfo?) {
isLastLoaded = true
if (last?.zoneInfo?.id != acctGameInfo?.zoneInfo?.id) {
_last = acctGameInfo
updateSpeedUi()
}
showGuideLayerIfNeed()
}
fun setHasAnyAcctRecord(hasAnyAcctRecord: Boolean) {
hasAnyAcctRecordLoaded = true
this.hasAnyAcctRecord = hasAnyAcctRecord
showGuideLayerIfNeed()
}
private fun isInvalidClick(): Boolean {
// 300ms内只能调用一次
val currentTime = System.currentTimeMillis()
val difTime = currentTime - clickTime
if (difTime <= CLICK_DURATION) {
return true
}
clickTime = currentTime
return false
}
fun clear() {
iAcceleratorProvider?.unBindAccRelatedListener(accelerationListener)
AcceleratorDataHolder.instance.removeListener(onDataHolderListener)
guideView?.dismiss()
}
companion object {
private const val CLICK_DURATION = 300
const val DISTRICT_SERVER_EMPTY = ""
const val DISTRICT_SERVER_HAVA = ""
private const val SCENE_TYPE_HAVE_GUIDE_LAYER = "有引导图"
const val SCENE_TYPE_NO_GUIDE_LAYER = "无引导图"
const val SOURCE_ENTRANCE_GAME_DETAIL = "游戏详情页"
const val SOURCE_ENTRANCE_MY_ASSETS = "我的资产"
const val SOURCE_ENTRANCE_SEARCH = "搜索页"
const val SOURCE_ENTRANCE_RECENTLY_PLAYED = "最近在玩"
const val BUTTON_NAME_ENTER_GAME = "进入游戏"
const val BUTTON_NAME_STOP_ACCELERATOR = "停止加速"
}
interface OnAcceleratorListener {
fun onStartAccelerator()
fun onGuideLayerDismiss()
}
}

View File

@ -1,54 +0,0 @@
package com.gh.gamecenter.gamedetail.accelerator
import android.content.Context
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.ShellActivity
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.toResString
/**
* 会员功能 实名认证相关弹窗
*/
object UserVerifyDialogUtils {
fun showUnVerifiedDialog(context: Context, title: String, content: String) {
DialogHelper.showDialog(
context,
title = title,
content = content,
confirmText = R.string.go_to_real_name_authentication.toResString(),
cancelText = "取消",
confirmClickCallback = {
context.startActivity(
ShellActivity.getIntent(
context,
ShellActivity.Type.REAL_NAME_INFO
).apply {
putExtra(EntranceConsts.KEY_SOURCE_ENTRANCE, "游戏实名")
putExtra(EntranceConsts.KEY_IS_FORCED_TO_CERTIFICATE, true)
}
)
NewLogUtils.logCertificationHintDialogOptionsClicked("前往实名认证")
SensorsBridge.trackVerificationPopupClick("前往实名认证")
},
cancelClickCallback = {
NewLogUtils.logCertificationHintDialogOptionsClicked("取消")
SensorsBridge.trackVerificationPopupClick("取消")
}
)
}
fun showMinorsOrVerifyingDialog(context: Context, title: String, content: String) {
DialogHelper.showDialog(
context,
title = title,
content = content,
confirmText = R.string.dialog_hint_confirm.toResString(),
cancelText = "",
)
}
}

View File

@ -1,28 +0,0 @@
package com.gh.gamecenter.gamedetail.accelerator.chain
import android.content.Context
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.gamedetail.accelerator.dialog.AcceleratorDialogFragment
import com.gh.gamecenter.gamedetail.accelerator.dialog.AcceleratorDialogFragment.Companion.SPEED_NOT_INSTALLED
class AcceleratorCheckInstallInterceptor : AcceleratorValidator.Interceptor {
override fun intercept(
context: Context,
chain: AcceleratorValidator.Chain,
listener: AcceleratorValidator.ValidateListener?
) {
val request = chain.request
if (PackageUtils.isInstalled(context, request.game.getUniquePackageName() ?: "")) {
chain.proceed(context, request, listener)
} else {
val game = request.game
AcceleratorDialogFragment.show(
SPEED_NOT_INSTALLED,
game.getUniquePackageName() ?: "",
game.id,
game.name ?: "",
request.sourceEntrance, context
)
}
}
}

View File

@ -1,29 +0,0 @@
package com.gh.gamecenter.gamedetail.accelerator.chain
import android.content.Context
class AcceleratorClient(
private vararg val interceptors: AcceleratorValidator.Interceptor,
) {
fun execute(
context: Context,
request: AcceleratorValidator.Request,
listener: AcceleratorValidator.ValidateListener
) {
val chain = RealAcceleratorInterceptorChain(interceptors.toList(), 0, request)
chain.proceed(context, request, listener)
}
companion object {
fun newInstance() = AcceleratorClient(
AcceleratorCheckInstallInterceptor(),
AcceleratorLoginInterceptor(),
AcceleratorPackageCheckInterceptor(),
AcceleratorRealNameInterceptor(),
AcceleratorVipInterceptor(),
AcceleratorStateInterceptor()
)
}
}

View File

@ -1,18 +0,0 @@
package com.gh.gamecenter.gamedetail.accelerator.chain
import android.content.Context
import com.gh.gamecenter.common.utils.ifLogin
class AcceleratorLoginInterceptor : AcceleratorValidator.Interceptor {
override fun intercept(
context: Context,
chain: AcceleratorValidator.Chain,
listener: AcceleratorValidator.ValidateListener?
) {
context.ifLogin("[网络加速]") {
val request = chain.request
chain.proceed(context, request, listener)
}
}
}

View File

@ -1,20 +0,0 @@
package com.gh.gamecenter.gamedetail.accelerator.chain
import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import com.gh.common.dialog.PackageCheckDialogFragment
class AcceleratorPackageCheckInterceptor : AcceleratorValidator.Interceptor {
override fun intercept(
context: Context,
chain: AcceleratorValidator.Chain,
listener: AcceleratorValidator.ValidateListener?
) {
val request = chain.request
if (context is AppCompatActivity) {
PackageCheckDialogFragment.show(context, request.game) {
chain.proceed(context, request, listener)
}
}
}
}

View File

@ -1,26 +0,0 @@
package com.gh.gamecenter.gamedetail.accelerator.chain
import android.content.Context
import com.gh.common.util.TempCertificationUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.toResString
import com.gh.gamecenter.gamedetail.accelerator.UserVerifyDialogUtils
class AcceleratorRealNameInterceptor : AcceleratorValidator.Interceptor {
override fun intercept(
context: Context,
chain: AcceleratorValidator.Chain,
listener: AcceleratorValidator.ValidateListener?
) {
val request = chain.request
if (TempCertificationUtils.isUserVerified()) {
chain.proceed(context, request, listener)
} else {
UserVerifyDialogUtils.showUnVerifiedDialog(
context,
R.string.real_name_tips.toResString(),
R.string.acceleration_service_without_real_name_description.toResString()
)
}
}
}

View File

@ -1,52 +0,0 @@
package com.gh.gamecenter.gamedetail.accelerator.chain
import android.content.Context
import com.gh.gamecenter.core.provider.IAcceleratorProvider
import com.gh.gamecenter.gamedetail.accelerator.dialog.AcceleratorDialogFragment
import com.gh.gamecenter.gamedetail.accelerator.dialog.AcceleratorDialogFragment.Companion.SPEED_CURRENT_ACCELERATING
import com.gh.gamecenter.gamedetail.accelerator.dialog.AcceleratorReplaceDialogFragment
import com.halo.assistant.accelerator.repository.AcceleratorDataHolder
import com.therouter.TheRouter
class AcceleratorStateInterceptor : AcceleratorValidator.Interceptor {
override fun intercept(
context: Context,
chain: AcceleratorValidator.Chain,
listener: AcceleratorValidator.ValidateListener?
) {
val request = chain.request
val iAcceleratorProvider = TheRouter.get(IAcceleratorProvider::class.java)
val isAccelerating = iAcceleratorProvider?.isCurAccSuccess() ?: false
if (isAccelerating) {
val game = request.game
val isCurrentAccelerating = AcceleratorDataHolder.instance.isCurrentGameAccelerating(game.id)
if (isCurrentAccelerating) {
AcceleratorDialogFragment.show(
SPEED_CURRENT_ACCELERATING,
game.getUniquePackageName() ?: "",
game.id,
game.name ?: "",
request.sourceEntrance,
context
)
} else {
AcceleratorReplaceDialogFragment.show(
context,
game.getUniquePackageName() ?: "",
game.id,
game.name ?: "",
request.sourceEntrance
) {
if (chain.isValidContext(context)) {
listener?.finished(context)
}
}
}
} else {
chain.proceed(context, request, listener)
}
}
}

View File

@ -1,71 +0,0 @@
package com.gh.gamecenter.gamedetail.accelerator.chain
import android.content.Context
import android.os.Parcelable
import androidx.appcompat.app.AppCompatActivity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.gamedetail.accelerator.chain.AcceleratorValidator.Request
import kotlinx.parcelize.Parcelize
class AcceleratorValidator {
interface ValidateListener {
fun finished(context: Context)
}
interface Interceptor {
fun intercept(context: Context, chain: Chain, listener: ValidateListener?)
}
interface Chain {
val request: Request
fun proceed(context: Context, request: Request, listener: ValidateListener?)
fun isValidContext(context: Context) =
context is AppCompatActivity && !context.isFinishing && !context.isDestroyed
}
@Parcelize
data class Request(
val isVip: Boolean,
val isNewUser: Boolean,
val game: GameEntity,
val sourceEntrance: String
):Parcelable
}
class RealAcceleratorInterceptorChain(
private val interceptors: List<AcceleratorValidator.Interceptor>,
private val index: Int,
private val _request: Request
) : AcceleratorValidator.Chain {
override val request: Request
get() = _request
override
fun proceed(context: Context, request: Request, listener: AcceleratorValidator.ValidateListener?) {
if (!isValidContext(context)) {
// 如果 context失效说明当前页面已销毁直接中断流程
return
}
if (index >= interceptors.size) {
// 验证完成
listener?.finished(context)
return
}
val next = RealAcceleratorInterceptorChain(
interceptors,
index + 1,
_request
)
interceptors[index].intercept(context, next, listener)
}
}

View File

@ -1,31 +0,0 @@
package com.gh.gamecenter.gamedetail.accelerator.chain
import android.content.Context
import com.gh.gamecenter.gamedetail.accelerator.dialog.AcceleratorDialogFragment
import com.gh.gamecenter.gamedetail.accelerator.dialog.AcceleratorDialogFragment.Companion.SPEED_ENABLE_VIP
class AcceleratorVipInterceptor : AcceleratorValidator.Interceptor {
override fun intercept(
context: Context,
chain: AcceleratorValidator.Chain,
listener: AcceleratorValidator.ValidateListener?
) {
val request = chain.request
val isVip = request.isVip
val isNewUser = request.isNewUser
if (isVip || isNewUser) {
chain.proceed(context, request, listener)
} else {
val game = request.game
AcceleratorDialogFragment.show(
SPEED_ENABLE_VIP,
game.getUniquePackageName() ?: "",
game.id,
game.name ?: "",
request.sourceEntrance,
context
)
}
}
}

Some files were not shown because too many files have changed in this diff Show More