Compare commits
233 Commits
fix/va-tes
...
chen/accel
| Author | SHA1 | Date | |
|---|---|---|---|
| d98b00f2dc | |||
| 8127ba7bd0 | |||
| 158c36a6b1 | |||
| c4184b9cbb | |||
| 585153cc0e | |||
| 112ce8da4c | |||
| 88cfb99a12 | |||
| b9fbad85b2 | |||
| 86f8aaf1e1 | |||
| 59da6eb171 | |||
| 4d5af5044f | |||
| 30105b3cc2 | |||
| f0b4085455 | |||
| 4e896ceccf | |||
| 52a3d4a9a7 | |||
| 8df60fcc1d | |||
| 9946dd0df3 | |||
| e3e218dd2b | |||
| e089347f8c | |||
| 174ca03ce4 | |||
| 6adae085b1 | |||
| 6a3b164177 | |||
| d08d1bf8e9 | |||
| 7ece9b0d4e | |||
| c45a2c34eb | |||
| 06b4c3f8ab | |||
| 7f71c1d740 | |||
| c1c2078294 | |||
| 34d31647c3 | |||
| e6badcb7c3 | |||
| 8e1973bad1 | |||
| d9a08037b5 | |||
| a65fb3535d | |||
| f6d5d6f719 | |||
| 10cc81e7fc | |||
| 60a50f5722 | |||
| 644881c14f | |||
| a0e43930a0 | |||
| aa5f6f4f24 | |||
| ab7668fd81 | |||
| c6f014c984 | |||
| c215bd195e | |||
| bb73598a87 | |||
| c6f70d1b4c | |||
| ce7f75976c | |||
| c8a7999990 | |||
| 0cd281a53c | |||
| e92d89d498 | |||
| a22858389b | |||
| e9d091043d | |||
| db4ac95094 | |||
| 13be47d440 | |||
| beee098cfe | |||
| d67aaf956b | |||
| 1ed9151b1f | |||
| 13f20f6883 | |||
| 78e320a192 | |||
| e51db47fad | |||
| ac02ea88b9 | |||
| f60004fc81 | |||
| 0cf39a82e2 | |||
| 315f244153 | |||
| f4bdc02d70 | |||
| aef39eb481 | |||
| dc2e7147d9 | |||
| fdcb6342bf | |||
| b0da4f8986 | |||
| f7cc906cc5 | |||
| 795fbabd90 | |||
| e770f8a359 | |||
| dd12b103be | |||
| 21f4a398d5 | |||
| f8a26ece01 | |||
| 54ee3ea376 | |||
| 8dfb1644a8 | |||
| 945e034f88 | |||
| a5ca88729a | |||
| d4bb3835cf | |||
| 3c63b74900 | |||
| 712cd21f6e | |||
| 2b9098faa7 | |||
| c0fde44534 | |||
| 785f99f0ef | |||
| dbd733aec6 | |||
| e30557e261 | |||
| 9744b95126 | |||
| 009608165c | |||
| 98356a7dd7 | |||
| 8389041379 | |||
| e4352590e9 | |||
| 4f68a52d54 | |||
| 93f87c8022 | |||
| a77beed7db | |||
| 112ddfda13 | |||
| 14cf39f10b | |||
| d775e804fd | |||
| d65062af26 | |||
| 2522bf5654 | |||
| 92177ae5f2 | |||
| 21ab15a907 | |||
| 5bea92c08e | |||
| da6725e444 | |||
| 2a2e887ddf | |||
| cc39a754db | |||
| b14cd3d143 | |||
| dc5b354861 | |||
| 64462ebdbe | |||
| 2e63257523 | |||
| c69d117ee7 | |||
| ddccb25559 | |||
| 913ea39302 | |||
| 1002d02f12 | |||
| fa663cd2f6 | |||
| 19af061311 | |||
| d643795fa3 | |||
| 44d93b7527 | |||
| c3d55d4ff9 | |||
| d6f35c5942 | |||
| c53c1b8228 | |||
| 61b967e533 | |||
| b1f2d0a303 | |||
| bb906f0bb8 | |||
| 6f242dcc95 | |||
| b47a64c63d | |||
| 948df2582c | |||
| 35edcf1d68 | |||
| 286d7650f2 | |||
| e566ab838f | |||
| cae720d4ec | |||
| 925516724f | |||
| a5f807c038 | |||
| f442a70bd3 | |||
| 9b3dab9897 | |||
| d939aae901 | |||
| 028974ec0d | |||
| ecd4610186 | |||
| 21e5f2c98d | |||
| 71c0cfe350 | |||
| 3b8b60bc6b | |||
| ac59158dbb | |||
| 5becdf2095 | |||
| a88b49344f | |||
| f34646cde8 | |||
| bc4bb9b7c6 | |||
| 9e8ffce772 | |||
| 008985489a | |||
| 2f3fbd3e7c | |||
| abef224830 | |||
| 8feb9b788e | |||
| 0a059deb44 | |||
| 448160d255 | |||
| 533f93a340 | |||
| d80b8a97a3 | |||
| f2e6d98788 | |||
| 238a83c5fe | |||
| ca71f23363 | |||
| c96b41c621 | |||
| 9afb35bbb9 | |||
| e8ee63d52c | |||
| 90359cfffd | |||
| a3da883033 | |||
| a9f1437a52 | |||
| 8c95286fe5 | |||
| 8a835a94e3 | |||
| 14ec4aed3a | |||
| 07f956a1f0 | |||
| 6ef8d04e57 | |||
| 30248ef205 | |||
| 87b9bb0bf3 | |||
| b346882bfa | |||
| eeddb5ea51 | |||
| 2ccdd93e47 | |||
| d98466f60f | |||
| 2afc2bc9d6 | |||
| 243b0ccbd4 | |||
| 78f9aa3ee4 | |||
| f355eae99b | |||
| 3c1af6e02d | |||
| 57a8b96f56 | |||
| 71265e0ea7 | |||
| b007e63b5e | |||
| c281ea7ac5 | |||
| f34ad0675d | |||
| 36abcc9f19 | |||
| d6443a401a | |||
| 6c8ea6ffb2 | |||
| ae878eddf1 | |||
| ece519115b | |||
| b9e0a8e37a | |||
| 34ca8896ae | |||
| d6e19bfaff | |||
| 943fb4d4e0 | |||
| 2c5471d524 | |||
| cf527db60e | |||
| f261991a55 | |||
| 0f9f0b7c9a | |||
| c29efbefd7 | |||
| ab66621751 | |||
| af262c624a | |||
| d2813ecbda | |||
| 0ea932e36d | |||
| 68151ed6f9 | |||
| e6d2361008 | |||
| 570b777c8e | |||
| 0e557b2246 | |||
| f155440814 | |||
| 62ba9fc7bf | |||
| 4637aa8808 | |||
| 81998e3aad | |||
| 82a8aa03ba | |||
| c876711578 | |||
| 41fcee7f4d | |||
| 0ccbc4d581 | |||
| 56151bc38d | |||
| f05fc73e3a | |||
| ca3c545f26 | |||
| 226539328e | |||
| bb7db78b0c | |||
| ede62c5363 | |||
| 12bb6824ea | |||
| 15c0950754 | |||
| f86b7fe12a | |||
| d12cdbd34b | |||
| 8436d4eda3 | |||
| be832037a7 | |||
| b620257825 | |||
| 6c88cace99 | |||
| f875fa1b14 | |||
| 8076c3a70a | |||
| bebab317a3 | |||
| c450ca570d | |||
| d239b0755f | |||
| 0a187b2242 |
@ -72,6 +72,8 @@ android_build:
|
||||
only:
|
||||
- dev
|
||||
- release
|
||||
- feat/GHZSCY-6976
|
||||
- feat/GHZSCY-6976-log
|
||||
|
||||
# 代码检查
|
||||
sonarqube_analysis:
|
||||
@ -103,6 +105,8 @@ sonarqube_analysis:
|
||||
only:
|
||||
- dev
|
||||
- release
|
||||
- feat/GHZSCY-6976
|
||||
- feat/GHZSCY-6976-log
|
||||
|
||||
## 发送简易检测结果报告
|
||||
send_sonar_report:
|
||||
@ -121,6 +125,8 @@ send_sonar_report:
|
||||
only:
|
||||
- dev
|
||||
- release
|
||||
- feat/GHZSCY-6976
|
||||
- feat/GHZSCY-6976-log
|
||||
|
||||
oss-upload&send-email:
|
||||
tags:
|
||||
@ -157,3 +163,5 @@ oss-upload&send-email:
|
||||
only:
|
||||
- dev
|
||||
- release
|
||||
- feat/GHZSCY-6976
|
||||
- feat/GHZSCY-6976-log
|
||||
|
||||
@ -372,8 +372,6 @@ dependencies {
|
||||
// debugImplementation "com.gu.android:toolargetool:${toolargetool}" // 需要使用调试时才启用
|
||||
debugImplementation "com.github.nichbar:WhatTheStack:${whatTheStack}"
|
||||
|
||||
ksp project(":feature:route_doc")
|
||||
|
||||
implementation "androidx.multidex:multidex:${multiDex}"
|
||||
implementation "androidx.fragment:fragment-ktx:${fragment}"
|
||||
|
||||
@ -404,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'
|
||||
}
|
||||
|
||||
@ -449,14 +447,14 @@ dependencies {
|
||||
exclude group: 'androidx.swiperefreshlayout'
|
||||
}
|
||||
|
||||
// implementation(project(':module_setting')) {
|
||||
implementation(project(':module_setting')) {
|
||||
exclude group: 'androidx.swiperefreshlayout'
|
||||
}
|
||||
|
||||
// implementation(project(':module_setting_compose')) {
|
||||
// exclude group: 'androidx.swiperefreshlayout'
|
||||
// }
|
||||
|
||||
implementation(project(':module_setting_compose')) {
|
||||
exclude group: 'androidx.swiperefreshlayout'
|
||||
}
|
||||
|
||||
if (!gradle.ext.excludeOptionalModules || gradle.ext.enablePkg) {
|
||||
implementation(project(':feature:pkg'))
|
||||
}
|
||||
@ -512,6 +510,10 @@ dependencies {
|
||||
implementation(project(':feature:sentry'))
|
||||
}
|
||||
|
||||
if (gradle.ext.enableRouteDoc) {
|
||||
ksp project(":feature:route_doc")
|
||||
}
|
||||
|
||||
implementation(project(':feature:media_select'))
|
||||
|
||||
implementation(project(":module_va_api"))
|
||||
@ -524,6 +526,18 @@ 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')
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -68,6 +68,9 @@
|
||||
<!-- 悬浮窗 -->
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
|
||||
<!-- 适配 双开/分身 游戏授权登录 -->
|
||||
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
|
||||
|
||||
<uses-sdk tools:overrideLibrary="
|
||||
com.shuyu.gsyvideoplayer,
|
||||
com.shuyu.gsyvideoplayer.lib,
|
||||
@ -194,7 +197,9 @@
|
||||
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" />
|
||||
|
||||
@ -517,10 +522,6 @@
|
||||
android:name=".video.data.VideoDataActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".video.poster.PosterEditActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".forum.detail.ForumDetailActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
@ -640,6 +641,7 @@
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.SkipCompatActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@style/Theme.AppCompat.Light.Fullscreen.Transparent">
|
||||
<intent-filter>
|
||||
<data android:scheme="ghzhushou" />
|
||||
@ -663,7 +665,8 @@
|
||||
android:name=".authorization.AuthorizationActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="portrait">
|
||||
android:screenOrientation="portrait"
|
||||
android:taskAffinity=".auth">
|
||||
<intent-filter>
|
||||
<data android:scheme="ghzhushou_authorization" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
@ -809,6 +812,18 @@
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/AppCompatTheme.APP" />
|
||||
|
||||
<activity
|
||||
android:name=".video.poster.PosterEditActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.halo.assistant.member.MemberActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".BatchRegisterActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<!-- <activity-->
|
||||
<!-- android:name="${applicationId}.douyinapi.DouYinEntryActivity"-->
|
||||
<!-- android:launchMode="singleTask"-->
|
||||
@ -864,10 +879,6 @@
|
||||
<!-- tools:node="remove" />-->
|
||||
<!-- </provider>-->
|
||||
|
||||
<service android:name="com.gh.gamecenter.install.InstallService" />
|
||||
|
||||
<service android:name="com.gh.download.suspendwindow.DownloadSuspendWindowService" />
|
||||
|
||||
<receiver
|
||||
android:name="com.gh.gamecenter.receiver.DownloadReceiver"
|
||||
android:exported="false">
|
||||
|
||||
@ -4,6 +4,7 @@ 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
|
||||
@ -13,11 +14,13 @@ 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.logOpenScreenAdSkip
|
||||
import com.gh.common.util.NewFlatLogUtils
|
||||
import com.gh.common.util.PackageUtils
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.MainActivity
|
||||
@ -59,6 +62,8 @@ object AdDelegateHelper {
|
||||
private val mGameSearchAdList: ArrayList<AdConfig> by lazy { arrayListOf() }
|
||||
private var mVGameLaunchAd: AdConfig? = null
|
||||
|
||||
private var ownerSplashAdLoadTime = 0L
|
||||
|
||||
val vGameLaunchAd: AdConfig?
|
||||
get() = mVGameLaunchAd
|
||||
|
||||
@ -76,6 +81,7 @@ object AdDelegateHelper {
|
||||
}
|
||||
|
||||
var isShowingSplashAd = false // 是否正在显示开屏广告
|
||||
var isOwnerSplashAdShown = false // 自有开屏广告是否展示
|
||||
var gameSearchKeyword = ""
|
||||
|
||||
fun initAdSdk(context: Context) {
|
||||
@ -302,6 +308,7 @@ object AdDelegateHelper {
|
||||
) {
|
||||
val hideCallback = {
|
||||
isShowingSplashAd = false
|
||||
isOwnerSplashAdShown = false
|
||||
hideAction.invoke()
|
||||
}
|
||||
if (mSplashAd != null) {
|
||||
@ -574,6 +581,8 @@ 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)
|
||||
@ -592,38 +601,62 @@ object AdDelegateHelper {
|
||||
)
|
||||
|
||||
adImage.visibleIf(true)
|
||||
ImageUtils.display(adImage, ad.img)
|
||||
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, "启动广告图加载失败")
|
||||
}
|
||||
})
|
||||
|
||||
if (ad.isImageType) {
|
||||
adVideo.visibleIf(false)
|
||||
} else {
|
||||
adVideo.visibleIf(true)
|
||||
adVideo.startPlay(ad.video.url)
|
||||
}
|
||||
startAdContainer.setOnClickListener {
|
||||
// 拦截点击事件传递
|
||||
}
|
||||
jumpBtn.setOnClickListener {
|
||||
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 ?: ""
|
||||
)
|
||||
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 ?: ""
|
||||
)
|
||||
}
|
||||
}
|
||||
val sources: MutableList<ExposureSource> = ArrayList()
|
||||
sources.add(ExposureSource("开屏广告", ad.id))
|
||||
|
||||
@ -44,6 +44,16 @@ class SplashAdVideoView @JvmOverloads constructor(
|
||||
return R.layout.layout_splash_ad_video
|
||||
}
|
||||
|
||||
override fun touchSurfaceMoveFullLogic(absDeltaX: Float, absDeltaY: Float) {
|
||||
// no nothing
|
||||
}
|
||||
|
||||
override fun onPrepared() {
|
||||
super.onPrepared()
|
||||
|
||||
visibility = VISIBLE
|
||||
}
|
||||
|
||||
override fun onAutoCompletion() {
|
||||
setStateAndUi(CURRENT_STATE_AUTO_COMPLETE);
|
||||
|
||||
|
||||
@ -21,26 +21,31 @@ import com.gh.common.view.RichEditor
|
||||
import com.gh.gamecenter.CropImageActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.activity.ToolBarActivity
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.entity.LocalVideoEntity
|
||||
import com.gh.gamecenter.feature.selector.LocalMediaActivity
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.core.utils.*
|
||||
import com.gh.gamecenter.entity.*
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.qa.editor.*
|
||||
import com.gh.gamecenter.entity.GamesCollectionEntity
|
||||
import com.gh.gamecenter.entity.MyVideoEntity
|
||||
import com.gh.gamecenter.entity.VideoEntity
|
||||
import com.gh.gamecenter.feature.entity.AnswerEntity
|
||||
import com.gh.gamecenter.feature.entity.ArticleEntity
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.selector.ChooseType
|
||||
import com.gh.gamecenter.feature.selector.LocalMediaActivity
|
||||
import com.gh.gamecenter.qa.editor.*
|
||||
import com.gh.gamecenter.qa.entity.EditorInsertEntity
|
||||
import com.gh.gamecenter.video.poster.PosterEditActivity
|
||||
import com.gh.gamecenter.video.poster.video.VideoPosterFragment
|
||||
import com.gh.gamecenter.video.upload.UploadManager
|
||||
import com.google.gson.JsonObject
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Util_System_Keyboard
|
||||
import com.lightgame.utils.Utils
|
||||
import com.lightgame.view.CheckableImageView
|
||||
import com.therouter.TheRouter
|
||||
import io.reactivex.disposables.Disposable
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
@ -229,6 +234,7 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> constructor(
|
||||
@SuppressLint("AddJavascriptInterface", "ClickableViewAccessibility")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
VideoPosterFragment.createVideoCoverFile(this)
|
||||
findView()
|
||||
onRichClick()
|
||||
mViewModel = provideViewModel()
|
||||
@ -739,9 +745,9 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> constructor(
|
||||
mViewModel.id = id
|
||||
mViewModel.videoId = videoId
|
||||
val videoEntity = VideoEntity(url = url)
|
||||
val intent =
|
||||
PosterEditActivity.getIntentByVideo(this@BaseRichEditorActivity, videoEntity)
|
||||
startActivityForResult(intent, REQUEST_CODE_IMAGE_CROP)
|
||||
TheRouter.build(RouteConsts.activity.videoCoverEditActivity)
|
||||
.withParcelable(EntranceConsts.KEY_VIDEO_ENTITY, videoEntity)
|
||||
.navigation(this@BaseRichEditorActivity, REQUEST_CODE_IMAGE_CROP)
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
|
||||
@ -22,7 +22,8 @@ import com.gh.gamecenter.ImageViewerActivity
|
||||
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.RouteConsts
|
||||
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.entity.NotificationUgc
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.common.loghub.LoghubUtils
|
||||
@ -30,20 +31,23 @@ 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.IAcceleratorProvider
|
||||
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.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.core.utils.*
|
||||
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
|
||||
@ -55,6 +59,9 @@ 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.member.MemberRepository
|
||||
import com.halo.assistant.member.MemberRepository.Companion.PAYMENT_TYPE_ALIPAY
|
||||
import com.halo.assistant.member.MemberRepository.Companion.PAYMENT_TYPE_WECHAT
|
||||
import com.lightgame.download.DataWatcher
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.download.DownloadStatus.*
|
||||
@ -75,6 +82,7 @@ class DefaultJsApi(
|
||||
private var mBbsId: String? = "",
|
||||
private var mOriginUrl: String? = "",
|
||||
private val mForumName: String? = "",
|
||||
private val listener: OnWebClickListener? = null
|
||||
) {
|
||||
|
||||
companion object {
|
||||
@ -699,6 +707,84 @@ 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 {
|
||||
val isSpeeding = TheRouter.get(IAcceleratorProvider::class.java)?.isCurAccSuccess() ?: false
|
||||
val gameId = if (isSpeeding) {
|
||||
MemberRepository.instance.acctGameRecord.gameId
|
||||
} else {
|
||||
""
|
||||
}
|
||||
return gameId
|
||||
}
|
||||
|
||||
@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,可能为空
|
||||
*/
|
||||
@ -815,4 +901,15 @@ class DefaultJsApi(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface OnWebClickListener {
|
||||
|
||||
fun onPreOrderWithAli(order: OrderEntity)
|
||||
|
||||
fun onPreOrderWithWechat(order: OrderEntity)
|
||||
|
||||
fun onStartGameAccelerate(accInfo: AcctRecordEntity.AccInfo)
|
||||
|
||||
fun onStopGameAccelerate()
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ import kotlin.concurrent.fixedRateTimer
|
||||
|
||||
object FixedRateJobHelper {
|
||||
private const val CHECKER_PERIOD: Long = 15 * 1000L
|
||||
private const val TIME_PERIOD: Long = 10 * 60 * 1000L
|
||||
private const val TIME_PERIOD: Long = 24 * 60 * 60 * 1000L
|
||||
private const val LOGHUB_PERIOD: Long = 2 * 60 * 1000L
|
||||
private const val EXPOSURE_PERIOD: Long = 1 * 60 * 1000L
|
||||
private const val REGION_SETTING_PERIOD: Long = 60 * 1000L
|
||||
@ -35,7 +35,7 @@ object FixedRateJobHelper {
|
||||
// 时间检查,每15秒检查一次
|
||||
fixedRateTimer("Global-Fixed-Rate-Timer", initialDelay = 100, period = CHECKER_PERIOD) {
|
||||
val elapsedTime = mExecuteCount * CHECKER_PERIOD
|
||||
// 时间校对,10分钟一次
|
||||
// 时间校对,24 小时一次
|
||||
if (elapsedTime % TIME_PERIOD == 0L) {
|
||||
RetrofitManager.getInstance().api.time
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
@ -4,6 +4,7 @@ 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
|
||||
|
||||
@ -25,6 +26,10 @@ 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!!)
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,12 +8,21 @@ import com.gh.gamecenter.feature.entity.GameEntity
|
||||
class PackageCheckHandler : DownloadChainHandler() {
|
||||
|
||||
override fun handleRequest(context: Context, gameEntity: GameEntity, asVGame: Boolean) {
|
||||
PackageCheckDialogFragment.show((context as AppCompatActivity), gameEntity) {
|
||||
fun nextOrProcessEnd() {
|
||||
if (hasNext()) {
|
||||
getNext()?.handleRequest(context, gameEntity, asVGame)
|
||||
} else {
|
||||
processEndCallback?.invoke(asVGame, null)
|
||||
}
|
||||
}
|
||||
|
||||
if (gameEntity.canSpeed) {
|
||||
nextOrProcessEnd()
|
||||
} else {
|
||||
PackageCheckDialogFragment.show((context as AppCompatActivity), gameEntity) {
|
||||
nextOrProcessEnd()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -114,8 +114,6 @@ public class Config {
|
||||
if (!TextUtils.isEmpty(json)) {
|
||||
mSettingsEntity = GsonUtils.fromJson(json, SettingsEntity.class);
|
||||
}
|
||||
|
||||
mSettingsEntity.setGameSmooth("off");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -263,8 +261,7 @@ public class Config {
|
||||
public void onSuccess(VSetting data) {
|
||||
mVSetting = data;
|
||||
SPUtils.setString(Constants.SP_V_SETTINGS, GsonUtils.toJson(data));
|
||||
|
||||
VHelper.init(HaloApp.getInstance());
|
||||
VHelper.checkVspaceUpdate(HaloApp.getInstance());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -15,10 +15,10 @@ import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.gh.common.chain.BrowserInstallHandler;
|
||||
import com.gh.common.chain.DownloadChainBuilder;
|
||||
import com.gh.common.chain.DownloadChainHandler;
|
||||
import com.gh.common.chain.CheckDownloadHandler;
|
||||
import com.gh.common.chain.CheckStoragePermissionHandler;
|
||||
import com.gh.common.chain.DownloadChainBuilder;
|
||||
import com.gh.common.chain.DownloadChainHandler;
|
||||
import com.gh.common.chain.DownloadDialogHelperHandler;
|
||||
import com.gh.common.chain.GamePermissionHandler;
|
||||
import com.gh.common.chain.LandPageAddressHandler;
|
||||
@ -287,19 +287,11 @@ public class BindingAdapters {
|
||||
});
|
||||
break;
|
||||
case RESERVED:
|
||||
if ("download".equals(gameEntity.getReserveStatus())) {
|
||||
ReservationHelper.showDeleteReservationDialog(progressBar.getContext(), () -> {
|
||||
ReservationHelper.deleteReservation(gameEntity, () -> {
|
||||
updateReservation(progressBar, gameEntity);
|
||||
});
|
||||
ReservationHelper.showCancelReservationDialog(progressBar.getContext(),gameEntity, () -> {
|
||||
ReservationHelper.cancelReservation(gameEntity, () -> {
|
||||
updateReservation(progressBar, gameEntity);
|
||||
});
|
||||
} else {
|
||||
ReservationHelper.showCancelReservationDialog(progressBar.getContext(),gameEntity, () -> {
|
||||
ReservationHelper.cancelReservation(gameEntity, () -> {
|
||||
updateReservation(progressBar, gameEntity);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
break;
|
||||
case H5_GAME:
|
||||
LinkEntity linkEntity = gameEntity.getH5Link();
|
||||
@ -345,9 +337,9 @@ public class BindingAdapters {
|
||||
}
|
||||
progressBar.setButtonStyle(DownloadButton.ButtonStyle.H5_GAME);
|
||||
} else {
|
||||
if (offStatus != null && "dialog".equals(offStatus)) {
|
||||
if (("dialog".equals(offStatus) || "third_party".equals(offStatus))) {
|
||||
progressBar.setText("查看");
|
||||
progressBar.setButtonStyle(DownloadButton.ButtonStyle.NONE);
|
||||
progressBar.setButtonStyle(DownloadButton.ButtonStyle.NONE_WITH_HINT);
|
||||
} else if ("updating".equals(offStatus)) {
|
||||
progressBar.setText("更新中");
|
||||
progressBar.setButtonStyle(DownloadButton.ButtonStyle.UPDATING);
|
||||
|
||||
@ -3,7 +3,6 @@ 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
|
||||
@ -19,7 +18,6 @@ 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
|
||||
@ -59,7 +57,6 @@ 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
|
||||
|
||||
@ -195,7 +192,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
|
||||
if (binding.noRemindAgainCb.isChecked) {
|
||||
saveRecord(entity)
|
||||
}
|
||||
val isAllPackageInstalled = isAllPackageInstalled(mAllInstalledPackages, entity)
|
||||
val isAllPackageInstalled = isAllPackageInstalled(entity)
|
||||
if (isAllPackageInstalled) {
|
||||
mDismissByTouchInside = true
|
||||
callBack?.onConfirm()
|
||||
@ -299,7 +296,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
|
||||
private fun getNotInstalledLink(packageDialogEntity: PackageDialogEntity): LinkEntity? {
|
||||
val links = LinkedHashSet<LinkEntity>()
|
||||
packageDialogEntity.detectionObjects.forEach { obj ->
|
||||
if (!checkDetectionsInstalled(mAllInstalledPackages, obj.packages)) {
|
||||
if (!checkDetectionsInstalled(obj.packages)) {
|
||||
obj.assignDownload.forEach {
|
||||
links.add(packageDialogEntity.links[it])
|
||||
}
|
||||
@ -325,9 +322,8 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mAllInstalledPackages = PackageHelper.getInstalledPackageNameList(HaloApp.getInstance().application, 0)
|
||||
gameEntity?.packageDialog?.let {
|
||||
if (isAllPackageInstalled(mAllInstalledPackages, it)) {
|
||||
if (isAllPackageInstalled(it)) {
|
||||
callBack?.onConfirm()
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
@ -363,7 +359,6 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(busFour: EBPackage) {
|
||||
if (busFour.isInstalledOrUninstalled()) {
|
||||
mAllInstalledPackages = PackageHelper.getInstalledPackageNameList(HaloApp.getInstance().application, 0)
|
||||
mAdapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
@ -388,7 +383,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
|
||||
val entity = entities[position]
|
||||
holder.binding.gameNameTv.text = entity.text
|
||||
if (position <= index) {
|
||||
val isAllInstalled = checkDetectionsInstalled(mAllInstalledPackages, entity.packages)
|
||||
val isAllInstalled = checkDetectionsInstalled(entity.packages)
|
||||
if (isAllInstalled) {
|
||||
holder.binding.statusTv.text = "已安装"
|
||||
holder.binding.statusTv.setTextColor(ContextCompat.getColor(context, com.gh.gamecenter.common.R.color.text_theme))
|
||||
@ -416,8 +411,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
|
||||
return
|
||||
}
|
||||
|
||||
val allInstalledPackages = PackageHelper.getInstalledPackageNameList(HaloApp.getInstance().application, 0)
|
||||
if (isAllPackageInstalled(allInstalledPackages, packageDialogEntity)) {
|
||||
if (isAllPackageInstalled(packageDialogEntity)) {
|
||||
callBack.onConfirm()
|
||||
return
|
||||
}
|
||||
@ -453,13 +447,11 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
|
||||
}
|
||||
|
||||
private fun checkDetectionsInstalled(
|
||||
allInstalledPackages: List<String>,
|
||||
packages: ArrayList<String>
|
||||
): Boolean {
|
||||
var isPackagesInstalled = false
|
||||
packages.forEach { packageName ->
|
||||
val isInstalled = allInstalledPackages.find { it == packageName } != null
|
||||
if (isInstalled) {
|
||||
if (PackageUtils.isInstalledFromAllPackage(HaloApp.getInstance(), packageName)) {
|
||||
isPackagesInstalled = true
|
||||
return@forEach
|
||||
}
|
||||
@ -469,17 +461,14 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
|
||||
|
||||
|
||||
fun isAllPackageInstalled(
|
||||
allInstalledPackages: List<String>,
|
||||
packageDialogEntity: PackageDialogEntity
|
||||
): Boolean {
|
||||
var isAllInstalled = true
|
||||
packageDialogEntity.detectionObjects.forEach loop@{ obj ->
|
||||
if (!checkDetectionsInstalled(allInstalledPackages, obj.packages)) {
|
||||
isAllInstalled = false
|
||||
return isAllInstalled
|
||||
if (!checkDetectionsInstalled(obj.packages)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return isAllInstalled
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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.UserRepository
|
||||
import com.gh.gamecenter.login.user.UserManager
|
||||
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)
|
||||
|
||||
UserRepository.getInstance().loginUserInfo.observe(viewLifecycleOwner) {
|
||||
currentUserId = it.data.getShortUserId()
|
||||
binding.tvCurrentName.text = it.data.name
|
||||
binding.ivCurrentAvatar.displayAvatar(it.data.icon)
|
||||
UserManager.getInstance().userInfoEntity?.let {
|
||||
currentUserId = it.getShortUserId()
|
||||
binding.tvCurrentName.text = it.name ?: ""
|
||||
binding.ivCurrentAvatar.displayAvatar(it.icon)
|
||||
binding.tvUserId.text = getString(R.string.user_id, currentUserId)
|
||||
}
|
||||
|
||||
|
||||
@ -31,6 +31,7 @@ class ExposureListener(var fragment: Fragment, var exposable: IExposable) : Recy
|
||||
override fun onFragmentPaused(fm: FragmentManager, f: Fragment) {
|
||||
if (fragment == f) {
|
||||
visibleState?.let { commitExposure(it) }
|
||||
visibleState?.let { commitWXCPMExposure(it) }
|
||||
throttleBus.clear()
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
package com.gh.common.fragment
|
||||
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import java.lang.reflect.Field
|
||||
|
||||
fun FragmentManager.popBackStackAllowStateLoss() {
|
||||
popBackStackAllowStateLoss(-1, 0)
|
||||
}
|
||||
|
||||
fun FragmentManager.popBackStackAllowStateLoss(id: Int, flags: Int) {
|
||||
if (!isStateSaved) {
|
||||
popBackStack(id, flags)
|
||||
}
|
||||
}
|
||||
|
||||
fun FragmentManager.popBackStackAllowStateLoss(name: String?, flags: Int) {
|
||||
if (!isStateSaved) {
|
||||
popBackStack(name, flags)
|
||||
}
|
||||
}
|
||||
|
||||
fun FragmentManager.popBackStackImmediateAllowStateLoss() = popBackStackAllowStateLoss(-1, 0)
|
||||
|
||||
fun FragmentManager.popBackStackImmediateAllowStateLoss(id: Int, flags: Int) =
|
||||
if (!isStateSaved) {
|
||||
popBackStackImmediate(id, flags)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
@Throws(NoSuchFieldException::class)
|
||||
private fun getField(clazz: Class<*>, name: String): Field {
|
||||
var cls: Class<*>? = clazz
|
||||
while (cls != null) {
|
||||
try {
|
||||
val declaredField = cls.getDeclaredField(name)
|
||||
declaredField.isAccessible = true
|
||||
return declaredField
|
||||
} catch (e: NoSuchFieldException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
cls = cls.superclass
|
||||
}
|
||||
throw NoSuchFieldException()
|
||||
}
|
||||
@ -1,12 +1,9 @@
|
||||
package com.gh.common.iinterface
|
||||
|
||||
interface ISmartRefreshContent {
|
||||
/**
|
||||
* 启用/关闭 页面滑动
|
||||
* @param isScrollEnabled 是否启用
|
||||
*/
|
||||
fun setScrollEnabled(isScrollEnabled: Boolean)
|
||||
import com.scwang.smartrefresh.layout.api.RefreshLayout
|
||||
import com.scwang.smartrefresh.layout.constant.RefreshState
|
||||
|
||||
interface ISmartRefreshContent {
|
||||
fun onRefresh()
|
||||
|
||||
/**
|
||||
@ -14,4 +11,6 @@ interface ISmartRefreshContent {
|
||||
* @param isSwipeRefreshEnabled 是否启用
|
||||
*/
|
||||
fun setSwipeRefreshEnabled(isSwipeRefreshEnabled: Boolean)
|
||||
|
||||
fun onStateChanged(refreshLayout: RefreshLayout, oldState: RefreshState, newState: RefreshState)
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import com.gh.gamecenter.CropImageActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.core.provider.ICropImageProvider
|
||||
import com.gh.gamecenter.personalhome.background.BackgroundClipActivity
|
||||
import com.halo.assistant.fragment.user.UserPortraitCropImageActivity
|
||||
import com.lightgame.utils.Utils
|
||||
import com.zhihu.matisse.internal.utils.PathUtils
|
||||
|
||||
@com.therouter.inject.ServiceProvider
|
||||
class CropImageProviderImpl : ICropImageProvider {
|
||||
override fun getCropImageIntent(data: List<Uri>, imageType: Int, entrance: String, context: Context): Intent? {
|
||||
if (data.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
val picturePath = PathUtils.getPath(context, data[0])
|
||||
Utils.log("picturePath = $picturePath")
|
||||
return when (imageType) {
|
||||
|
||||
IMAGE_TYPE_AVATAR -> {// 上传头像
|
||||
UserPortraitCropImageActivity.getIntent(
|
||||
context,
|
||||
picturePath,
|
||||
"我的光环(选择头像)"
|
||||
)
|
||||
}
|
||||
|
||||
IMAGE_TYPE_GAME_COLLECTION_COVER -> {// 游戏单封面
|
||||
CropImageActivity.getIntent(
|
||||
context,
|
||||
picturePath,
|
||||
142 / 328F,
|
||||
false,
|
||||
R.layout.layout_game_collection_crop_image_assist,
|
||||
entrance
|
||||
)
|
||||
}
|
||||
|
||||
IMAGE_TYPE_PERSONAL_BACKGROUND -> { // 用户主页背景
|
||||
BackgroundClipActivity.getIntent(context, picturePath, entrance)
|
||||
}
|
||||
|
||||
else ->
|
||||
null
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val IMAGE_TYPE_AVATAR = 1
|
||||
const val IMAGE_TYPE_GAME_COLLECTION_COVER = 2
|
||||
const val IMAGE_TYPE_PERSONAL_BACKGROUND = 3
|
||||
}
|
||||
}
|
||||
@ -112,6 +112,12 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
|
||||
"本地下载"
|
||||
}
|
||||
|
||||
// 小游戏的启动不需要上报下载点击事件
|
||||
// @see https://jira.shanqu.cc/browse/GHZSCY-7013
|
||||
if (boundedObject is GameEntity && boundedObject.isMiniGame()) {
|
||||
return
|
||||
}
|
||||
|
||||
// 上报神策点击事件
|
||||
val customPageKV = customPageTrackData?.toKV() ?: arrayOf()
|
||||
SensorsBridge.trackEventWithExposureSource(
|
||||
@ -121,7 +127,7 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
|
||||
"game_name", gameName,
|
||||
"game_type", gameTypeInChinese,
|
||||
"download_status", downloadStatusInChinese,
|
||||
"button_name", downloadButton.text,
|
||||
"button_name", text,
|
||||
"game_schema_type", gameSchemaType,
|
||||
"download_type", downloadType,
|
||||
"page_name", GlobalActivityManager.getCurrentPageEntity().pageName,
|
||||
|
||||
@ -2,18 +2,16 @@ package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.therouter.router.Route
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.provider.IGameCollectionDetailProvider
|
||||
import com.gh.gamecenter.gamecollection.detail.GameCollectionDetailActivity
|
||||
|
||||
@com.therouter.inject.ServiceProvider
|
||||
class GameCollectionDetailProviderImpl : IGameCollectionDetailProvider {
|
||||
override fun getIntent(context: Context, gameCollectionId: String, isFromSquare: Boolean): Intent {
|
||||
return GameCollectionDetailActivity.getIntent(context, gameCollectionId, isFromSquare)
|
||||
override fun getIntent(context: Context, gameCollectionId: String, isFromSquare: Boolean, entrance: String): Intent {
|
||||
return GameCollectionDetailActivity.getIntent(context, gameCollectionId, isFromSquare, entrance)
|
||||
}
|
||||
|
||||
override fun getSpecifiedCommentIntent(context: Context, gameCollectionId: String, topCommentId: String): Intent {
|
||||
return GameCollectionDetailActivity.getSpecifiedCommentIntent(context, gameCollectionId, topCommentId)
|
||||
override fun getSpecifiedCommentIntent(context: Context, gameCollectionId: String, topCommentId: String, entrance: String): Intent {
|
||||
return GameCollectionDetailActivity.getSpecifiedCommentIntent(context, gameCollectionId, topCommentId, entrance)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
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.IAcceleratorProvider
|
||||
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.gh.gamecenter.login.user.UserManager
|
||||
import com.gh.gamecenter.login.user.UserRepository
|
||||
import com.halo.assistant.member.MemberRepository
|
||||
import com.therouter.TheRouter
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
|
||||
@com.therouter.inject.ServiceProvider
|
||||
class WechatPayResultProviderImpl : IWechatPayResultProvider {
|
||||
|
||||
private val repository = MemberRepository.instance
|
||||
|
||||
@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)
|
||||
|
||||
// 先刷新本地状态,支付成功,肯定是付费会员
|
||||
TheRouter.get(IAcceleratorProvider::class.java)?.setVipEntity(
|
||||
VipEntity(
|
||||
_vipStatus = true,
|
||||
_isNewUser = false,
|
||||
_isTryVip = false
|
||||
)
|
||||
)
|
||||
val userId = UserManager.getInstance().userId
|
||||
if (userId.isNotBlank()) {
|
||||
UserRepository.getInstance().refreshVipStatus(userId, true)
|
||||
}
|
||||
|
||||
SensorsBridge.trackMemberRechargeResult(
|
||||
MemberRepository.PAYMENT_TYPE_WECHAT,
|
||||
orderEntity?.setMenuName ?: "",
|
||||
orderEntity?.paymentAmount ?: "",
|
||||
MemberRepository.RECHARGE_RESULT_SUCCESS
|
||||
)
|
||||
}, {
|
||||
// 支付失败
|
||||
EventBus.getDefault().post(EBPayState.PayFail)
|
||||
SensorsBridge.trackMemberRechargeResult(
|
||||
MemberRepository.PAYMENT_TYPE_WECHAT,
|
||||
orderEntity?.setMenuName ?: "",
|
||||
orderEntity?.paymentAmount ?: "",
|
||||
MemberRepository.RECHARGE_RESULT_FAILURE
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,8 @@ import android.annotation.SuppressLint
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.database.sqlite.SQLiteDiskIOException
|
||||
import android.database.sqlite.SQLiteException
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.text.TextUtils
|
||||
@ -284,7 +286,11 @@ object SimulatorGameManager {
|
||||
entity.isRecentlyPlayed = it.id == gameId
|
||||
simulatorGameRecordList.add(entity)
|
||||
}
|
||||
simulatorGameDao.addSimulatorGameList(simulatorGameRecordList)
|
||||
try {
|
||||
simulatorGameDao.addSimulatorGameList(simulatorGameRecordList)
|
||||
} catch (e: SQLiteException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@ 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;
|
||||
import com.gh.gamecenter.core.AppExecutor;
|
||||
import com.gh.gamecenter.core.provider.ISentryProvider;
|
||||
import com.gh.gamecenter.core.utils.GsonUtils;
|
||||
@ -39,6 +40,11 @@ import io.reactivex.schedulers.Schedulers;
|
||||
*/
|
||||
public class DataUtils {
|
||||
|
||||
// 神策 OAID 是否已绑定
|
||||
private static boolean isSensorOAIDBounded = false;
|
||||
// 原始的 OAID 是否已成功获取
|
||||
private static boolean originalOAIDIsReceived = false;
|
||||
|
||||
private DataUtils() {
|
||||
throw new IllegalStateException("Utility class");
|
||||
}
|
||||
@ -65,7 +71,6 @@ public class DataUtils {
|
||||
// 默认用 APP 级已存储的 GID 来使用,不使用外部 GID
|
||||
String savedGid = SPUtils.getString(Constants.GID);
|
||||
if (!TextUtils.isEmpty(savedGid)) {
|
||||
HaloApp.getInstance().setGid(savedGid);
|
||||
onGidReceived(savedGid);
|
||||
} else {
|
||||
GidHelper.getInstance().registerDevice(HaloApp.getInstance().getApplication(), new GidCallback() {
|
||||
@ -89,6 +94,8 @@ public class DataUtils {
|
||||
}
|
||||
|
||||
private static void onGidReceived(String gid) {
|
||||
bindValidOaidToSensor(false);
|
||||
|
||||
HaloApp.getInstance().setGid(gid);
|
||||
// 更新广告配置
|
||||
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
|
||||
@ -111,6 +118,35 @@ public class DataUtils {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 为神策绑定有效的 OAID
|
||||
*/
|
||||
public static void bindValidOaidToSensor(boolean fromOaidResult) {
|
||||
if (isSensorOAIDBounded) return;
|
||||
|
||||
String oaid = HaloApp.getInstance().getOAID();
|
||||
|
||||
// 来自于 oaid 获取回调,或者说原始 oaid 已经获取成功
|
||||
if (fromOaidResult || originalOAIDIsReceived) {
|
||||
originalOAIDIsReceived = true;
|
||||
// 遇到异常的 OAID
|
||||
if (Constants.INVALID_OAID_1.equals(oaid)
|
||||
|| Constants.INVALID_OAID_2.equals(oaid)
|
||||
|| Constants.INVALID_OAID_3.equals(oaid)
|
||||
|| TextUtils.isEmpty(oaid)) {
|
||||
// 若 gid 不为空,那么整合 gid 作为 oaid https://jira.shanqu.cc/browse/GHZSCY-7004
|
||||
if (HaloApp.getInstance().getGid() != null) {
|
||||
oaid = "GID" + HaloApp.getInstance().getGid();
|
||||
SensorsBridge.INSTANCE.setOAID(oaid);
|
||||
isSensorOAIDBounded = true;
|
||||
}
|
||||
} else {
|
||||
SensorsBridge.INSTANCE.setOAID(oaid);
|
||||
isSensorOAIDBounded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取应用 gid 绑定的实名信息
|
||||
*/
|
||||
|
||||
@ -5,6 +5,8 @@ import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
|
||||
import com.gh.common.filter.RegionSetting;
|
||||
import com.gh.common.filter.RegionSettingHelper;
|
||||
import com.gh.common.repository.ReservationRepository;
|
||||
@ -41,7 +43,8 @@ public class DetailDownloadUtils {
|
||||
|
||||
/**
|
||||
* 更新底部下载区域
|
||||
* @param viewHolder 下载区域的包裹
|
||||
*
|
||||
* @param viewHolder 下载区域的包裹
|
||||
* @param ignoreDownloadEntity 忽略下载实体(往往用于下载异常时)
|
||||
*/
|
||||
public static void updateViewHolder(DetailViewHolder viewHolder, boolean ignoreDownloadEntity) {
|
||||
@ -52,6 +55,11 @@ public class DetailDownloadUtils {
|
||||
if (viewHolder.getMultiVersionDownloadTv() != null) {
|
||||
viewHolder.getMultiVersionDownloadTv().setVisibility(View.GONE);
|
||||
}
|
||||
if (viewHolder.getSpeedContainer() != null) {
|
||||
viewHolder.getSpeedContainer().setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
viewHolder.setSpeedViewsVisible(false);
|
||||
|
||||
// 根据预置的配置更新 ViewHolder 的状态 (譬如青少年模式、下载内容为空等)
|
||||
if (updateViewHolderWithPredefinedConfig(viewHolder, gameEntity)) {
|
||||
@ -139,6 +147,7 @@ public class DetailDownloadUtils {
|
||||
// 游戏包含多 APK 的情况
|
||||
viewHolder.getMultiVersionDownloadTv().setText("选择下载你的版本" + (TextUtils.isEmpty(downloadAddWord) ? "" : "-" + downloadAddWord));
|
||||
viewHolder.getMultiVersionDownloadTv().setVisibility(View.VISIBLE);
|
||||
viewHolder.getDownloadPb().setTag(com.gh.gamecenter.feature.R.string.download, viewHolder.getMultiVersionDownloadTv().getText());
|
||||
viewHolder.getDownloadPb().setText("");
|
||||
viewHolder.getDownloadPb().setButtonStyle(DownloadButton.ButtonStyle.NORMAL);
|
||||
DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity);
|
||||
@ -218,7 +227,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)
|
||||
@ -245,16 +254,24 @@ public class DetailDownloadUtils {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
boolean isLaunchState = false;
|
||||
// 非畅玩,显示为普通游戏
|
||||
if (context.getString(com.gh.gamecenter.feature.R.string.pluggable).equals(rawBtnText)) {
|
||||
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.PLUGIN);
|
||||
} else if (context.getString(com.gh.gamecenter.feature.R.string.launch).equals(rawBtnText)) {
|
||||
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.LAUNCH_OR_OPEN);
|
||||
isLaunchState = true;
|
||||
} else if (context.getString(com.gh.gamecenter.feature.R.string.install).equals(rawBtnText)) {
|
||||
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_NORMAL);
|
||||
} else {
|
||||
downloadButton.setButtonStyle(DownloadButton.ButtonStyle.NORMAL);
|
||||
}
|
||||
// 只有下载按钮状态为 “启动” 时,才需要展示加速ui
|
||||
if (isLaunchState) {
|
||||
viewHolder.showAcceleratorGuideLayer();
|
||||
} else {
|
||||
viewHolder.hideSpeedUi();
|
||||
}
|
||||
|
||||
if (showDualDownloadButton && viewHolder.getLocalDownloadSizeTv() != null) {
|
||||
viewHolder.getLocalDownloadSizeTv().setVisibility(View.GONE);
|
||||
@ -457,7 +474,7 @@ public class DetailDownloadUtils {
|
||||
}
|
||||
viewHolder.getDownloadPb().setButtonStyle(DownloadButton.ButtonStyle.H5_GAME);
|
||||
} else {
|
||||
if ("dialog".equals(gameEntity.getDownloadOffStatus())) {
|
||||
if ("dialog".equals(gameEntity.getDownloadOffStatus()) || "third_party".equals(gameEntity.getDownloadOffStatus())) {
|
||||
viewHolder.getDownloadPb().setText(TextUtils.isEmpty(gameEntity.getDownloadOffText()) ? "查看详情" : gameEntity.getDownloadOffText());
|
||||
viewHolder.getDownloadPb().setButtonStyle(DownloadButton.ButtonStyle.NONE_WITH_HINT);
|
||||
} else if ("updating".equals(gameEntity.getDownloadOffStatus())) {
|
||||
|
||||
@ -11,7 +11,6 @@ import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.os.bundleOf
|
||||
import com.therouter.TheRouter
|
||||
import com.gh.ad.AdPluginDownloadHelper
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.exposure.ExposureManager.log
|
||||
@ -57,7 +56,6 @@ 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.fuli.kaifu.ServersCalendarActivity
|
||||
import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersCalendarManagementActivity
|
||||
import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersSubscribedGameListActivity
|
||||
import com.gh.gamecenter.gamedetail.history.HistoryApkListActivity
|
||||
import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity
|
||||
@ -77,7 +75,6 @@ import com.gh.gamecenter.qa.questions.newdetail.NewQuestionDetailActivity
|
||||
import com.gh.gamecenter.qa.subject.CommunitySubjectActivity
|
||||
import com.gh.gamecenter.qa.video.detail.ForumVideoDetailActivity
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.gamecenter.SearchActivity
|
||||
import com.gh.gamecenter.servers.GameServerTestActivity
|
||||
import com.gh.gamecenter.servers.GameServersActivity
|
||||
import com.gh.gamecenter.servers.gametest2.GameServerTestV2Activity
|
||||
@ -98,6 +95,7 @@ import com.halo.assistant.fragment.WebFragment
|
||||
import com.lightgame.utils.Utils
|
||||
import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram
|
||||
import com.tencent.mm.opensdk.openapi.WXAPIFactory
|
||||
import com.therouter.TheRouter
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import retrofit2.HttpException
|
||||
@ -178,7 +176,23 @@ object DirectUtils {
|
||||
"qa",
|
||||
"feedback",
|
||||
"toolkit",
|
||||
"float_window_game"
|
||||
"float_window_game",
|
||||
"my_halo",
|
||||
"my_game",
|
||||
"server_manager",
|
||||
"receiving_information",
|
||||
"game_archive",
|
||||
"game_dynamics",
|
||||
"game_upload",
|
||||
"certification",
|
||||
"wechat_reminder",
|
||||
"apk_clean",
|
||||
"personal_center",
|
||||
"video_upload",
|
||||
"account_security",
|
||||
"simulator",
|
||||
"teen_mode",
|
||||
"message_center",
|
||||
)
|
||||
|
||||
fun directToLinkPage(
|
||||
@ -383,8 +397,8 @@ object DirectUtils {
|
||||
}
|
||||
}
|
||||
|
||||
"authentication" -> {
|
||||
context.startActivity(ShellActivity.getIntent(context, ShellActivity.Type.REAL_NAME_INFO, null))
|
||||
"authentication", "certification" -> {
|
||||
directToRealName(context)
|
||||
}
|
||||
|
||||
"user_background" -> {
|
||||
@ -442,7 +456,7 @@ object DirectUtils {
|
||||
} ?: ""
|
||||
}
|
||||
|
||||
"halo_tab" -> directToHomeMyHaloTab(context)
|
||||
"my_halo", "halo_tab" -> directToHomeMyHaloTab(context)
|
||||
|
||||
"common_collection" -> directToCommonCollectionDetail(
|
||||
context,
|
||||
@ -524,7 +538,8 @@ object DirectUtils {
|
||||
ToolbarWrapperActivity.getMultiTabNavIntent(
|
||||
context,
|
||||
linkEntity.link ?: "",
|
||||
linkEntity.text ?: ""
|
||||
linkEntity.text ?: "",
|
||||
entrance
|
||||
)
|
||||
)
|
||||
|
||||
@ -532,16 +547,20 @@ object DirectUtils {
|
||||
ToolbarWrapperActivity.getCustomPageIntent(
|
||||
context,
|
||||
linkEntity.link ?: "",
|
||||
linkEntity.text ?: ""
|
||||
linkEntity.text ?: "",
|
||||
entrance
|
||||
)
|
||||
)
|
||||
|
||||
// 选中首页底部 tab
|
||||
"bottom_tab" -> {
|
||||
val intent = Intent(context, MainActivity::class.java).apply {
|
||||
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
if (HaloApp.getInstance().isRunningForeground) {
|
||||
val intent = Intent(context, MainActivity::class.java)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
context.startActivity(intent)
|
||||
} else {
|
||||
jumpActivity(context, Bundle())
|
||||
}
|
||||
context.startActivity(intent)
|
||||
|
||||
if (linkEntity is LaunchRedirect) {
|
||||
MainWrapperRepository.getInstance().sendSelectTabEvent(linkEntity)
|
||||
@ -568,6 +587,32 @@ object DirectUtils {
|
||||
}
|
||||
}
|
||||
|
||||
"my_game" -> directToMyGame(0, entrance)
|
||||
|
||||
"server_manager" -> directToServersCalendarManagement(entrance)
|
||||
|
||||
"receiving_information" -> directToDeliveryInfo(entrance)
|
||||
|
||||
"game_archive" -> directToGameArchive(entrance)
|
||||
|
||||
"game_dynamics" -> directToConcernInfo(context, entrance)
|
||||
|
||||
"wechat_reminder" -> CheckLoginUtils.checkLogin(context, entrance) {
|
||||
context.startActivity(WebActivity.getBindWechatIntent(context))
|
||||
}
|
||||
|
||||
"apk_clean" -> directToCleanApk(context, entrance)
|
||||
|
||||
"personal_center" -> directToUserInfo(entrance)
|
||||
|
||||
"simulator" -> directToSimulatorGame(entrance)
|
||||
|
||||
"account_security" -> directToAccountSecurity(entrance)
|
||||
|
||||
"teen_mode" -> directToTeenMode(entrance)
|
||||
|
||||
"message_center" -> directToMessageCenter(0, entrance)
|
||||
|
||||
"" -> {
|
||||
// do nothing
|
||||
}
|
||||
@ -2083,13 +2128,17 @@ object DirectUtils {
|
||||
|
||||
/**
|
||||
* 跳转到开服订阅页面
|
||||
* @param context 上下文
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToServersCalendarManagement(context: Context, entrance: String) {
|
||||
CheckLoginUtils.checkLogin(context, entrance) {
|
||||
context.startActivity(ServersCalendarManagementActivity.getIntent(context))
|
||||
}
|
||||
fun directToServersCalendarManagement(entrance: String) {
|
||||
val uri = Uri.Builder()
|
||||
.path(RouteConsts.activity.serversCalendarManagementActivity)
|
||||
.appendQueryParameter(RouteConsts.QueryParams.REQUIRE_LOGIN, "true")
|
||||
.appendQueryParameter(RouteConsts.QueryParams.SOURCE, entrance)
|
||||
.build()
|
||||
|
||||
TheRouter.build(uri.toString())
|
||||
.navigation()
|
||||
}
|
||||
|
||||
fun directToSearch(
|
||||
@ -2149,4 +2198,100 @@ object DirectUtils {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToMyGame(defaultTabIndex: Int, source: String) {
|
||||
val uri = Uri.Builder()
|
||||
.path(RouteConsts.activity.myGameActivity)
|
||||
.appendQueryParameter(RouteConsts.QueryParams.SOURCE, source)
|
||||
.build()
|
||||
|
||||
TheRouter.build(uri.toString())
|
||||
.withInt(BaseActivity_TabLayout.PAGE_INDEX, defaultTabIndex)
|
||||
.navigation()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToDeliveryInfo(source: String) {
|
||||
val uri = Uri.Builder()
|
||||
.path(RouteConsts.activity.deliveryInfoActivity)
|
||||
.appendQueryParameter(RouteConsts.QueryParams.REQUIRE_LOGIN, "true")
|
||||
.appendQueryParameter(RouteConsts.QueryParams.SOURCE, source)
|
||||
.build()
|
||||
|
||||
TheRouter.build(uri.toString())
|
||||
.navigation()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToGameArchive(source: String) {
|
||||
val uri = Uri.Builder()
|
||||
.path(RouteConsts.activity.gameArchiveListActivity)
|
||||
.appendQueryParameter(RouteConsts.QueryParams.SOURCE, source)
|
||||
.build()
|
||||
|
||||
TheRouter.build(uri.toString())
|
||||
.navigation()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToSimulatorGame(source: String) {
|
||||
val uri = Uri.Builder()
|
||||
.path(RouteConsts.activity.simulatorGameActivity)
|
||||
.appendQueryParameter(RouteConsts.QueryParams.SOURCE, source)
|
||||
.build()
|
||||
|
||||
TheRouter.build(uri.toString())
|
||||
.navigation()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToTeenMode(source: String) {
|
||||
val uri = Uri.Builder()
|
||||
.path(RouteConsts.activity.teenagerModeActivity)
|
||||
.appendQueryParameter(RouteConsts.QueryParams.SOURCE, source)
|
||||
.build()
|
||||
|
||||
TheRouter.build(uri.toString())
|
||||
.navigation()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToUserInfo(source: String) {
|
||||
val uri = Uri.Builder()
|
||||
.path(RouteConsts.activity.userInfoActivity)
|
||||
.appendQueryParameter(RouteConsts.QueryParams.REQUIRE_LOGIN, "true")
|
||||
.appendQueryParameter(RouteConsts.QueryParams.SOURCE, source)
|
||||
.build()
|
||||
|
||||
TheRouter.build(uri.toString())
|
||||
.navigation()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToCleanApk(context: Context, source: String) {
|
||||
val uri = Uri.Builder()
|
||||
.path(RouteConsts.activity.cleanApkActivity)
|
||||
.appendQueryParameter(RouteConsts.QueryParams.SOURCE, source)
|
||||
.build()
|
||||
|
||||
PermissionHelper.checkManageAllFilesOrStoragePermissionBeforeAction(context) {
|
||||
TheRouter.build(uri.toString())
|
||||
.navigation()
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToAccountSecurity(source: String, isLogoutStyle: Boolean = false) {
|
||||
val uri = Uri.Builder()
|
||||
.path(RouteConsts.activity.securityActivity)
|
||||
.appendQueryParameter(RouteConsts.QueryParams.REQUIRE_LOGIN, "true")
|
||||
.appendQueryParameter(RouteConsts.QueryParams.SOURCE, source)
|
||||
.build()
|
||||
|
||||
TheRouter.build(uri.toString())
|
||||
.withString(KEY_ENTRANCE, source)
|
||||
.withBoolean(KEY_DISPLAY_TYPE, isLogoutStyle)
|
||||
.navigation()
|
||||
}
|
||||
}
|
||||
@ -280,9 +280,9 @@ object DownloadItemUtils {
|
||||
isClickable = true
|
||||
buttonStyle = DownloadButton.ButtonStyle.NORMAL
|
||||
} else {
|
||||
if ("dialog" == offStatus) {
|
||||
if ("dialog" == offStatus || "third_party" == offStatus) {
|
||||
text = context.getString(com.gh.gamecenter.feature.R.string.check)
|
||||
buttonStyle = DownloadButton.ButtonStyle.NORMAL
|
||||
buttonStyle = DownloadButton.ButtonStyle.NONE_WITH_HINT
|
||||
} else if ("updating" == offStatus) {
|
||||
text = context.getString(com.gh.gamecenter.feature.R.string.updating)
|
||||
buttonStyle = DownloadButton.ButtonStyle.UPDATING
|
||||
@ -839,34 +839,25 @@ object DownloadItemUtils {
|
||||
} else {
|
||||
allStateClickCallback?.onCallback()
|
||||
clickCallback?.onCallback()
|
||||
if ("download" == gameEntity.reserveStatus) {
|
||||
ReservationHelper.showDeleteReservationDialog(context) {
|
||||
ReservationHelper.deleteReservation(gameEntity) {
|
||||
adapter?.notifyItemChanged(position)
|
||||
refreshCallback?.onCallback()
|
||||
}
|
||||
ReservationHelper.showCancelReservationDialog(context, gameEntity, {
|
||||
NewFlatLogUtils.logMyGameCancelReserveDialogClick(
|
||||
"确定取消",
|
||||
gameEntity.id,
|
||||
gameEntity.name ?: ""
|
||||
)
|
||||
ReservationHelper.cancelReservation(gameEntity) {
|
||||
adapter?.notifyItemChanged(position)
|
||||
refreshCallback?.onCallback()
|
||||
}
|
||||
} else {
|
||||
ReservationHelper.showCancelReservationDialog(context, gameEntity,{
|
||||
}, object : CancelListener {
|
||||
override fun onCancel() {
|
||||
NewFlatLogUtils.logMyGameCancelReserveDialogClick(
|
||||
"确定取消",
|
||||
"关闭弹窗",
|
||||
gameEntity.id,
|
||||
gameEntity.name ?: ""
|
||||
)
|
||||
ReservationHelper.cancelReservation(gameEntity) {
|
||||
adapter?.notifyItemChanged(position)
|
||||
refreshCallback?.onCallback()
|
||||
}
|
||||
}, object : CancelListener {
|
||||
override fun onCancel() {
|
||||
NewFlatLogUtils.logMyGameCancelReserveDialogClick(
|
||||
"关闭弹窗",
|
||||
gameEntity.id,
|
||||
gameEntity.name ?: ""
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
@ -53,6 +53,7 @@ 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>()
|
||||
|
||||
/**
|
||||
* 当下载任务是 预约上线提醒 触发的,则所有弹窗均不显示
|
||||
@ -146,7 +147,8 @@ object DownloadObserver {
|
||||
|| DownloadStatus.timeout == status
|
||||
) {
|
||||
if (mRetryableHashMap[downloadEntity.url] == true
|
||||
&& NetworkUtils.isWifiConnected(HaloApp.getInstance().application)
|
||||
&& (NetworkUtils.isWifiConnected(HaloApp.getInstance().application)
|
||||
|| NDownloadBridge.isDownloadViaTrafficAllowed(downloadEntity))
|
||||
) {
|
||||
downloadManager.resumeDownload(downloadEntity.url)
|
||||
mRetryableHashMap[downloadEntity.url] = false
|
||||
@ -257,6 +259,7 @@ object DownloadObserver {
|
||||
}
|
||||
|
||||
mRetryableHashMap.remove(downloadEntity.url)
|
||||
mRetryableProgressMap.remove(downloadEntity.url)
|
||||
|
||||
EventBus.getDefault().post(EBDownloadStatus("done", "", "", "", downloadEntity.packageName, ""))
|
||||
}
|
||||
@ -264,7 +267,9 @@ object DownloadObserver {
|
||||
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
|
||||
|
||||
// 如果已下载大小发生变化,表示成功恢复下载,则重置重试标记
|
||||
if (status == DownloadStatus.downloading) {
|
||||
if (status == DownloadStatus.downloading
|
||||
&& downloadEntity.progress != mRetryableProgressMap[downloadEntity.url]) {
|
||||
mRetryableProgressMap[downloadEntity.url] = downloadEntity.progress
|
||||
mRetryableHashMap[downloadEntity.url] = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,12 +135,16 @@ object GameUtils {
|
||||
// 畅玩状态优先,且畅玩实体不为空时将 downloadEntity 置为畅玩实体
|
||||
if (performAsVGame && vGameDownloadEntity != null) {
|
||||
downloadEntity = vGameDownloadEntity
|
||||
} else if (!performAsVGame && !isFromList && downloadEntity?.isVGameDownloadInDualDownloadMode() == true) {
|
||||
// 下载的任务是由畅玩触发的,游戏详情页不需判定为需要安装
|
||||
downloadEntity = null
|
||||
} else if (performAsVGame && !isFromList && downloadEntity?.isLocalDownloadInDualDownloadMode() == true) {
|
||||
// 下载的任务是由下载安装触发的,游戏详情页不需判定为需要安装
|
||||
downloadEntity = null
|
||||
} else if (!isFromList) {
|
||||
if (!performAsVGame
|
||||
&& gameEntity.isDualBtnModeEnabled()
|
||||
&& downloadEntity?.isVGameDownloadInDualDownloadMode() == true) {
|
||||
// 下载的任务是由畅玩触发的,并且双下载按钮启用,游戏详情页不需判定为需要安装
|
||||
downloadEntity = null
|
||||
} else if (performAsVGame && downloadEntity?.isLocalDownloadInDualDownloadMode() == true) {
|
||||
// 下载的任务是由下载安装触发的,游戏详情页不需判定为需要安装
|
||||
downloadEntity = null
|
||||
}
|
||||
}
|
||||
|
||||
if (downloadEntity != null) {
|
||||
|
||||
@ -2778,4 +2778,34 @@ 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)
|
||||
}
|
||||
}
|
||||
@ -578,7 +578,6 @@ 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)
|
||||
@ -587,18 +586,9 @@ 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}"
|
||||
@ -616,12 +606,6 @@ object PackageHelper {
|
||||
additionalWhiteListPackageNameSet.toString()
|
||||
)
|
||||
}
|
||||
|
||||
if (updatedButKeepingWrongStatusPackageNameSet.isNotEmpty()) {
|
||||
for (packageName in updatedButKeepingWrongStatusPackageNameSet) {
|
||||
PackageChangeHelper.addUpdate(packageName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -635,7 +619,6 @@ 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()) {
|
||||
@ -651,13 +634,6 @@ 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -666,10 +642,6 @@ object PackageHelper {
|
||||
TAG,
|
||||
"refreshWrongInstallStatus 需要更新已安装状态的包数量为 ${installedButKeepingWrongStatusPackageNameSet.size}"
|
||||
)
|
||||
Utils.log(
|
||||
TAG,
|
||||
"refreshWrongInstallStatus 需要更新已更新状态的包数量为 ${updatedButKeepingWrongStatusPackageNameSet.size}"
|
||||
)
|
||||
Utils.log(
|
||||
TAG,
|
||||
"refreshWrongInstallStatus 需要移除已安装的包数量为 ${uninstalledButKeepingWrongStatusPackageNameSet.size}"
|
||||
@ -699,12 +671,6 @@ object PackageHelper {
|
||||
additionalWhiteListPackageNameSet.toString()
|
||||
)
|
||||
}
|
||||
|
||||
if (updatedButKeepingWrongStatusPackageNameSet.isNotEmpty()) {
|
||||
for (packageName in updatedButKeepingWrongStatusPackageNameSet) {
|
||||
PackageChangeHelper.addUpdate(packageName, cachedPkgNameAndGameEntityMap.remove(packageName))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,7 +18,6 @@ import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.utils.MD5Utils
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.install.InstallService
|
||||
import com.gh.vspace.VHelper
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.DownloadEntity
|
||||
@ -194,12 +193,6 @@ object PackageInstaller {
|
||||
private fun install(context: Context, pkgPath: String, pkgName: String?) {
|
||||
HaloApp.put(Constants.LAST_INSTALL_GAME, pkgPath)
|
||||
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU && Build.MANUFACTURER.lowercase().contains("xiaomi")) {
|
||||
val foregroundServiceIntent = Intent(context, InstallService::class.java)
|
||||
foregroundServiceIntent.putExtra(InstallService.KEY_SERVICE_ACTION, InstallService.START_FOREGROUND)
|
||||
context.startForegroundService(foregroundServiceIntent)
|
||||
}
|
||||
|
||||
val installIntent = getInstallIntent(context, pkgPath)
|
||||
context.startActivity(installIntent)
|
||||
|
||||
@ -284,7 +277,12 @@ object PackageInstaller {
|
||||
installIntent.setDataAndType(uri, "application/vnd.android.package-archive")
|
||||
}
|
||||
|
||||
updateSystemInstallerIfAvailable(context, installIntent)
|
||||
// 优选系统的安装器(遇到 Exception 就回落到正常的安装器)
|
||||
try {
|
||||
updateSystemInstallerIfAvailable(context, installIntent)
|
||||
} catch (ignored: Exception) {
|
||||
// ignored
|
||||
}
|
||||
|
||||
InstallUtils.getInstance()
|
||||
.addInstall(PackageUtils.getPackageNameByPath(context, path))
|
||||
|
||||
@ -7,7 +7,7 @@ import com.gh.gamecenter.common.utils.isVGameDownloadInDualDownloadMode
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.GameInstall
|
||||
import com.gh.gamecenter.packagehelper.PackageRepository
|
||||
import com.gh.gamecenter.manager.PackagesManager
|
||||
import com.gh.vspace.VHelper
|
||||
|
||||
object PackageLauncher {
|
||||
@ -81,28 +81,11 @@ object PackageLauncher {
|
||||
gameEntity: GameEntity? = null,
|
||||
packageName: String?
|
||||
) {
|
||||
|
||||
if (packageName.isNullOrEmpty()) {
|
||||
ToastUtils.toast("启动失败")
|
||||
return
|
||||
}
|
||||
|
||||
// 获取 GameInstall 实体,用于记录启动日志用
|
||||
val gameInstall = if (gameEntity != null) {
|
||||
GameInstall.transformGameInstall(gameEntity, packageName)
|
||||
} else {
|
||||
PackageRepository.gameInstalled.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) {
|
||||
@ -113,6 +96,26 @@ 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 了,还想啥日志上报
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -14,7 +14,6 @@ import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AndroidException;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@ -29,9 +28,9 @@ import com.gh.gamecenter.BuildConfig;
|
||||
import com.gh.gamecenter.common.constant.Constants;
|
||||
import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.core.utils.MD5Utils;
|
||||
import com.gh.gamecenter.entity.GameUpdateEntity;
|
||||
import com.gh.gamecenter.feature.entity.ApkEntity;
|
||||
import com.gh.gamecenter.feature.entity.GameEntity;
|
||||
import com.gh.gamecenter.entity.GameUpdateEntity;
|
||||
import com.gh.gamecenter.feature.utils.SentryHelper;
|
||||
import com.gh.gamecenter.manager.PackagesManager;
|
||||
import com.gh.vspace.VHelper;
|
||||
@ -302,7 +301,7 @@ public class PackageUtils {
|
||||
Signature[] signatures = packageInfo.signatures;
|
||||
|
||||
// 使用幸运破解器破解安卓签名认证可能会出现不用签名也能装的情况,这里有可能是空的
|
||||
if (signatures[0] != null) {
|
||||
if (signatures.length > 0 && signatures[0] != null) {
|
||||
return parseSignature(signatures[0].toByteArray());
|
||||
} else {
|
||||
return new String[]{null, null};
|
||||
@ -542,10 +541,8 @@ public class PackageUtils {
|
||||
try {
|
||||
Intent intent = context.getApplicationContext().getPackageManager().getLaunchIntentForPackage(packageName);
|
||||
return intent != null;
|
||||
} catch (IllegalArgumentException exception) {
|
||||
// 一些设备调用获取 intent 的时候会触发 Parcel.readException !
|
||||
exception.printStackTrace();
|
||||
return false;
|
||||
} catch (Exception exception) {
|
||||
return PackageHelper.INSTANCE.getLocalPackageNameSet().contains(packageName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -645,6 +642,19 @@ public class PackageUtils {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 获取应用的名称
|
||||
*/
|
||||
public static CharSequence getNameByPackageName(Context context, String packageName) {
|
||||
try {
|
||||
PackageManager packageManager = context.getApplicationContext().getPackageManager();
|
||||
return packageManager.getApplicationLabel(packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 获取应用的 icon
|
||||
|
||||
@ -29,53 +29,31 @@ import okhttp3.ResponseBody
|
||||
|
||||
object ReservationHelper {
|
||||
|
||||
@JvmStatic
|
||||
fun deleteReservation(game: GameEntity, refreshCallback: EmptyCallback) {
|
||||
deleteOrCancelReservation(game, true, refreshCallback)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun cancelReservation(game: GameEntity, refreshCallback: EmptyCallback) {
|
||||
deleteOrCancelReservation(game, false, refreshCallback)
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private fun deleteOrCancelReservation(
|
||||
@JvmStatic
|
||||
fun cancelReservation(
|
||||
game: GameEntity,
|
||||
deleteReservation: Boolean,
|
||||
refreshCallback: EmptyCallback
|
||||
) {
|
||||
|
||||
val retrofit = RetrofitManager.getInstance()
|
||||
val single = if (deleteReservation) {
|
||||
retrofit.newApi
|
||||
.deleteGameReservation(
|
||||
game.id,
|
||||
getReserveRequestBody(game, context = HaloApp.getInstance().application)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
} else {
|
||||
retrofit.newApi
|
||||
.cancelGameReservation(
|
||||
game.id,
|
||||
getReserveRequestBody(game, context = HaloApp.getInstance().application)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
}
|
||||
retrofit.newApi
|
||||
.cancelGameReservation(
|
||||
game.id,
|
||||
getReserveRequestBody(game, context = HaloApp.getInstance().application)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BiResponse<ResponseBody>() {
|
||||
override fun onSuccess(data: ResponseBody) {
|
||||
ReservationRepository.removeReservationFromMemoryAndRefresh(game.id)
|
||||
refreshCallback.onCallback()
|
||||
}
|
||||
|
||||
single.subscribe(object : BiResponse<ResponseBody>() {
|
||||
override fun onSuccess(data: ResponseBody) {
|
||||
ReservationRepository.removeReservationFromMemoryAndRefresh(game.id)
|
||||
refreshCallback.onCallback()
|
||||
}
|
||||
|
||||
override fun onFailure(exception: Exception) {
|
||||
Utils.toast(HaloApp.getInstance().application, exception.message)
|
||||
exception.printStackTrace()
|
||||
}
|
||||
})
|
||||
override fun onFailure(exception: Exception) {
|
||||
Utils.toast(HaloApp.getInstance().application, exception.message)
|
||||
exception.printStackTrace()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@ -146,21 +124,6 @@ object ReservationHelper {
|
||||
})
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun showDeleteReservationDialog(context: Context, emptyCallback: EmptyCallback) {
|
||||
DialogUtils.showCancelOrDeleteReservationDialog(
|
||||
context,
|
||||
"删除预约",
|
||||
"游戏已上线,你可以删除此预约记录,确定删除吗?",
|
||||
"确定删除",
|
||||
"暂不删除", object : ConfirmListener {
|
||||
override fun onConfirm() {
|
||||
emptyCallback.onCallback()
|
||||
}
|
||||
}, null
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun showCancelReservationDialog(context: Context, game: GameEntity?, emptyCallback: EmptyCallback) {
|
||||
showCancelReservationDialog(context, game, emptyCallback, null)
|
||||
|
||||
@ -6,6 +6,7 @@ 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
|
||||
@ -89,4 +90,12 @@ object TempCertificationUtils {
|
||||
return stringBuffer.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测光环是否实名
|
||||
*/
|
||||
fun isUserVerified(): Boolean {
|
||||
val idCard = UserManager.getInstance().userInfoEntity?.idCard
|
||||
// 账号已实名
|
||||
return idCard != null && idCard.status == 0
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@ package com.gh.download.simple
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.database.sqlite.SQLiteException
|
||||
import android.database.sqlite.SQLiteFullException
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.lg.download.*
|
||||
import com.lg.download.listener.InnerDownloadListener
|
||||
@ -174,6 +175,9 @@ object DownloadMessageHandler : InnerDownloadListener {
|
||||
DownloadError.CONTENT_LENGTH_IS_ZERO -> {
|
||||
ToastUtils.toast("下载链接异常,请检查")
|
||||
}
|
||||
DownloadError.DISK_IS_FULL -> {
|
||||
ToastUtils.toast("磁盘已满,请清理空间后获得更好的体验")
|
||||
}
|
||||
else -> {
|
||||
// 想怎么处理就怎么处理
|
||||
}
|
||||
@ -264,18 +268,30 @@ object DownloadMessageHandler : InnerDownloadListener {
|
||||
}
|
||||
|
||||
fun insertDownloadToDatabase(downloadEntity: SimpleDownloadEntity) {
|
||||
mDownloadDao.insertDownloadEntity(downloadEntity)
|
||||
updateDownloadList()
|
||||
try {
|
||||
mDownloadDao.insertDownloadEntity(downloadEntity)
|
||||
updateDownloadList()
|
||||
} catch (e: SQLiteException) {
|
||||
if (e is SQLiteFullException) {
|
||||
ToastUtils.showToast("磁盘已满,请清理空间获得更好的体验")
|
||||
}
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
fun updateDownloadToDatabase(
|
||||
downloadEntity: SimpleDownloadEntity,
|
||||
updateDownloadList: Boolean = false
|
||||
) {
|
||||
mDownloadDao.updateDownloadEntity(downloadEntity)
|
||||
try {
|
||||
mDownloadDao.updateDownloadEntity(downloadEntity)
|
||||
|
||||
if (updateDownloadList) {
|
||||
updateDownloadList()
|
||||
if (updateDownloadList) {
|
||||
updateDownloadList()
|
||||
}
|
||||
} catch (e: SQLiteFullException) {
|
||||
// 底层的下载服务遇到 SQLiteFullException 时会自动暂停下载任务,上层这里就不用纠结处理方式了
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
81
app/src/main/java/com/gh/gamecenter/BatchRegisterActivity.kt
Normal file
81
app/src/main/java/com/gh/gamecenter/BatchRegisterActivity.kt
Normal file
@ -0,0 +1,81 @@
|
||||
package com.gh.gamecenter
|
||||
|
||||
import android.os.Bundle
|
||||
import android.widget.Button
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.gh.gamecenter.common.retrofit.Response
|
||||
import com.gh.gamecenter.core.provider.IAcceleratorProvider
|
||||
import com.gh.gamecenter.feature.entity.BaseEntity
|
||||
import com.gh.gamecenter.login.retrofit.RetrofitManager
|
||||
import com.gh.gamecenter.login.user.UserManager
|
||||
import com.therouter.TheRouter
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import retrofit2.HttpException
|
||||
|
||||
|
||||
/**
|
||||
* 奇游用户批量注册
|
||||
*/
|
||||
class BatchRegisterActivity : AppCompatActivity() {
|
||||
|
||||
private val userIds = listOf(
|
||||
""
|
||||
)
|
||||
private var iAcceleratorProvider: IAcceleratorProvider? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_batch_register)
|
||||
|
||||
iAcceleratorProvider = TheRouter.get(IAcceleratorProvider::class.java)
|
||||
val btnRegister = findViewById<Button>(R.id.btn_register)
|
||||
btnRegister.setOnClickListener {
|
||||
doRegister()
|
||||
}
|
||||
}
|
||||
|
||||
private fun doRegister() {
|
||||
println("kayn -->doRegister:${userIds.size}")
|
||||
Observable.fromIterable(userIds)
|
||||
.flatMap({ userId ->
|
||||
RetrofitManager.getInstance().newApi
|
||||
.getQyToken(userId, "gjonline_vip")
|
||||
.onErrorReturnItem(BaseEntity())
|
||||
.flatMap { entity ->
|
||||
val token = entity.data?.token ?: ""
|
||||
Single.create<Pair<Boolean, String>> {
|
||||
if (token.isBlank()) {
|
||||
it.onSuccess(false to userId)
|
||||
} else {
|
||||
iAcceleratorProvider?.setQyUserToken(token) { isSuccess ->
|
||||
it.onSuccess(isSuccess to userId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.toObservable()
|
||||
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Response<Pair<Boolean, String>>() {
|
||||
override fun onNext(response: Pair<Boolean, String>) {
|
||||
super.onNext(response)
|
||||
val (isSuccess, userId) = response
|
||||
println("kayn -->isSuccess:$isSuccess --userId:$userId")
|
||||
}
|
||||
|
||||
override fun onFailure(e: HttpException?) {
|
||||
super.onFailure(e)
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
super.onComplete()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -3,26 +3,25 @@ package com.gh.gamecenter;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.gh.gamecenter.common.base.activity.ToolBarActivity;
|
||||
import com.gh.gamecenter.common.utils.BitmapUtils;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts;
|
||||
import com.gh.gamecenter.common.utils.BitmapUtils;
|
||||
import com.gh.gamecenter.common.view.CropImageCustom;
|
||||
import com.gh.gamecenter.common.view.cropbox.CropBoxStyle;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.ref.SoftReference;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* 裁剪图片
|
||||
*/
|
||||
@ -32,6 +31,8 @@ public class CropImageActivity extends ToolBarActivity {
|
||||
|
||||
public static final String RESULT_CLIP_PATH = "result_clip_path";
|
||||
|
||||
public static final String RESULT_ORIGINAL_PATH = "result_original_path";
|
||||
|
||||
private SoftReference<Bitmap> reference;
|
||||
|
||||
protected boolean mBlackTheme = false;
|
||||
@ -51,7 +52,7 @@ public class CropImageActivity extends ToolBarActivity {
|
||||
Intent intent = new Intent(context, CropImageActivity.class);
|
||||
intent.putExtra(EntranceConsts.KEY_PATH, picturePath);
|
||||
intent.putExtra(EntranceConsts.KEY_ENTRANCE, entrance);
|
||||
intent.putExtra(EntranceConsts.KEY_IMAGE_CROP_RATIO, cropRatio);
|
||||
intent.putExtra(EntranceConsts.KEY_IMAGE_CROP_STYLE, new CropBoxStyle.Rectangle(cropRatio));
|
||||
intent.putExtra(EntranceConsts.KEY_BLACK_THEME, isBlackTheme);
|
||||
intent.putExtra(EntranceConsts.KEY_ASSIST_RES, assistRes);
|
||||
return intent;
|
||||
@ -68,20 +69,14 @@ public class CropImageActivity extends ToolBarActivity {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mCropImageCustom = findViewById(R.id.cropimage_custom);
|
||||
View statusBarView = findViewById(R.id.status_bar);
|
||||
TextView tvCancel = findViewById(R.id.tv_cancel);
|
||||
TextView tvSubmit = findViewById(R.id.tv_submit);
|
||||
|
||||
mTitleTv.setTextColor(mBlackTheme ? Color.WHITE : Color.BLACK);
|
||||
mToolbar.setBackgroundColor(getResources().getColor(mBlackTheme ? com.gh.gamecenter.common.R.color.text_28282E : com.gh.gamecenter.common.R.color.white));
|
||||
statusBarView.setBackgroundColor(getResources().getColor(mBlackTheme ? com.gh.gamecenter.common.R.color.text_28282E : com.gh.gamecenter.common.R.color.white));
|
||||
|
||||
setNavigationTitle(getString(R.string.title_crop_image));
|
||||
setToolbarMenu(R.menu.menu_positive);
|
||||
MenuItem menuItem = getMenuItem(R.id.layout_menu_positive);
|
||||
TextView menuButton = menuItem.getActionView().findViewById(R.id.menu_answer_post);
|
||||
menuButton.setTextColor(getResources().getColor(com.gh.gamecenter.common.R.color.text_theme));
|
||||
|
||||
float ratio = getIntent().getFloatExtra(EntranceConsts.KEY_IMAGE_CROP_RATIO, 1F);
|
||||
mCropImageCustom.setCropRatio(ratio);
|
||||
CropBoxStyle boxStyle = getIntent().getParcelableExtra(EntranceConsts.KEY_IMAGE_CROP_STYLE);
|
||||
if (boxStyle == null) {
|
||||
boxStyle = new CropBoxStyle.Rectangle(1F);
|
||||
}
|
||||
mCropImageCustom.setCropBoxStyle(boxStyle);
|
||||
|
||||
int assistRes = getIntent().getIntExtra(EntranceConsts.KEY_ASSIST_RES, -1);
|
||||
if (assistRes > 0) {
|
||||
@ -89,8 +84,21 @@ public class CropImageActivity extends ToolBarActivity {
|
||||
addAssistView(view);
|
||||
}
|
||||
|
||||
DisplayUtils.setLightStatusBar(this, !mBlackTheme);
|
||||
DisplayUtils.setStatusBarColor(this, com.gh.gamecenter.common.R.color.transparent, !mBlackTheme);
|
||||
DisplayUtils.setLightStatusBar(this, false);
|
||||
DisplayUtils.setStatusBarColor(this, com.gh.gamecenter.common.R.color.transparent, false);
|
||||
|
||||
tvCancel.setOnClickListener(v -> finish());
|
||||
|
||||
tvSubmit.setOnClickListener(v -> saveImage());
|
||||
}
|
||||
|
||||
protected void saveImage() {
|
||||
Intent data = new Intent();
|
||||
String clipPath = getCacheDir().getAbsolutePath() + File.separator + System.currentTimeMillis() + ".jpg";
|
||||
mCropImageCustom.savePicture(clipPath);
|
||||
data.putExtra(RESULT_CLIP_PATH, clipPath);
|
||||
setResult(RESULT_OK, data);
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -98,20 +106,6 @@ public class CropImageActivity extends ToolBarActivity {
|
||||
return mBlackTheme ? com.gh.gamecenter.common.R.drawable.ic_toolbar_back_white : com.gh.gamecenter.common.R.drawable.ic_bar_back;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
if (item.getItemId() == R.id.layout_menu_positive) {
|
||||
Intent data = new Intent();
|
||||
String clipPath = getCacheDir().getAbsolutePath() + File.separator + System.currentTimeMillis() + ".jpg";
|
||||
mCropImageCustom.savePicture(clipPath);
|
||||
|
||||
data.putExtra(RESULT_CLIP_PATH, clipPath);
|
||||
setResult(RESULT_OK, data);
|
||||
finish();
|
||||
}
|
||||
return super.onMenuItemClick(item);
|
||||
}
|
||||
|
||||
public void addAssistView(View view) {
|
||||
mCropImageCustom.addAssistView(view);
|
||||
}
|
||||
|
||||
@ -166,8 +166,13 @@ public class MainActivity extends BaseActivity {
|
||||
private final Handler handler = new Handler();
|
||||
private boolean mShouldShowAd = false; // 是否显示广告
|
||||
|
||||
private Bundle mTempSavedInstanceState;
|
||||
private boolean mFragmentIsCreated = false;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
mTempSavedInstanceState = savedInstanceState;
|
||||
|
||||
mShouldShowAd = getIntent().getBooleanExtra(SHOW_AD, false) && savedInstanceState == null
|
||||
&& !HaloApp.getInstance().isAlreadyUpAndRunning;
|
||||
HaloApp.getInstance().isAlreadyUpAndRunning = true;
|
||||
@ -175,21 +180,12 @@ public class MainActivity extends BaseActivity {
|
||||
mMainWrapperViewModel = new ViewModelProvider(this, new MainWrapperViewModel.Factory(HaloApp.getInstance()))
|
||||
.get(MainWrapperViewModel.class);
|
||||
|
||||
DisplayUtils.transparentStatusBar(this);
|
||||
DisplayUtils.updateGlobalScreen(this);
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setStatusBarColor(Color.TRANSPARENT);
|
||||
|
||||
Fragment fragmentFromFM = getSupportFragmentManager().findFragmentById(com.gh.gamecenter.selector.R.id.layout_activity_content);
|
||||
|
||||
mMainWrapperFragment = fragmentFromFM != null ? (MainWrapperFragment) fragmentFromFM : new MainWrapperFragment();
|
||||
if (savedInstanceState != null) {
|
||||
mMainWrapperFragment.setArguments(savedInstanceState);
|
||||
} else if (getIntent() != null) {
|
||||
mMainWrapperFragment.setArguments(getIntent().getExtras());
|
||||
}
|
||||
replaceFragment(mMainWrapperFragment);
|
||||
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
if (HaloApp.getInstance().isNewForThisVersion) {
|
||||
LunchType lunchType = HaloApp.getInstance().getLaunchType();
|
||||
@ -215,7 +211,6 @@ public class MainActivity extends BaseActivity {
|
||||
DataUtils.getGid();
|
||||
}
|
||||
|
||||
|
||||
mPackageViewModel = ViewModelProviders.of(this, new PackageViewModel.Factory()).get(PackageViewModel.class);
|
||||
|
||||
final boolean containsErrorMsg = com.gh.gamecenter.common.constant.Config.isContainsErrorMsg();
|
||||
@ -273,6 +268,7 @@ public class MainActivity extends BaseActivity {
|
||||
if (mShouldShowAd) {
|
||||
showAd();
|
||||
} else {
|
||||
doInitMainFragment(mTempSavedInstanceState);
|
||||
hideTextAd();
|
||||
hideSplashAd();
|
||||
}
|
||||
@ -328,6 +324,23 @@ public class MainActivity extends BaseActivity {
|
||||
CertificationSwitchHelper.getCertificationSwitch();
|
||||
}
|
||||
|
||||
private void doInitMainFragment(Bundle savedInstanceState) {
|
||||
if (mFragmentIsCreated) return;
|
||||
|
||||
mTempSavedInstanceState = null;
|
||||
Fragment fragmentFromFM = getSupportFragmentManager().findFragmentById(com.gh.gamecenter.selector.R.id.layout_activity_content);
|
||||
|
||||
mMainWrapperFragment = fragmentFromFM != null ? (MainWrapperFragment) fragmentFromFM : new MainWrapperFragment();
|
||||
if (savedInstanceState != null) {
|
||||
mMainWrapperFragment.setArguments(savedInstanceState);
|
||||
} else if (getIntent() != null) {
|
||||
mMainWrapperFragment.setArguments(getIntent().getExtras());
|
||||
}
|
||||
replaceFragment(mMainWrapperFragment);
|
||||
|
||||
mFragmentIsCreated = true;
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private void getTeenagerMode() {
|
||||
RetrofitManager.getInstance()
|
||||
@ -541,19 +554,31 @@ 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;
|
||||
|
||||
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",
|
||||
@ -633,10 +658,11 @@ public class MainActivity extends BaseActivity {
|
||||
ExtensionsKt.removeFromParent(startSdkAdIcpContainer, true);
|
||||
}
|
||||
|
||||
onSplashHidden();
|
||||
onAdHidden();
|
||||
}
|
||||
|
||||
private void onSplashHidden() {
|
||||
private void onAdHidden() {
|
||||
doInitMainFragment(mTempSavedInstanceState);
|
||||
// 通知全局弹窗可以进行显示
|
||||
AppExecutor.getUiExecutor().execute(GlobalPriorityChainHelper.INSTANCE::start);
|
||||
}
|
||||
@ -854,7 +880,9 @@ public class MainActivity extends BaseActivity {
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0 && !mMainWrapperFragment.onHandleBackPressed()) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0
|
||||
&& mMainWrapperFragment != null
|
||||
&& !mMainWrapperFragment.onHandleBackPressed()) {
|
||||
DownloadEntity downloadEntity = null;
|
||||
for (DownloadEntity entity : DownloadManager.getInstance().getAllDownloadEntityExcludeSilentTask()) {
|
||||
if (entity.getStatus().equals(DownloadStatus.done)) {
|
||||
@ -1045,6 +1073,7 @@ public class MainActivity extends BaseActivity {
|
||||
blackList.add(R.id.historyTv);
|
||||
blackList.add(R.id.myCollectionTv);
|
||||
blackList.add(R.id.searchTv);
|
||||
blackList.add(R.id.subject_tab);
|
||||
updateStaticView(view, blackList);
|
||||
|
||||
View communityHomeWrapper = view.findViewById(R.id.communityHomeContainer);
|
||||
|
||||
@ -15,6 +15,7 @@ import androidx.core.widget.doAfterTextChanged
|
||||
import androidx.core.widget.doOnTextChanged
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import com.gh.common.fragment.popBackStackAllowStateLoss
|
||||
import com.gh.common.util.DataCollectionUtils
|
||||
import com.gh.common.util.LogUtils
|
||||
import com.gh.gamecenter.DisplayType.*
|
||||
@ -190,6 +191,7 @@ open class SearchActivity : BaseActivity() {
|
||||
when (type) {
|
||||
SearchType.AUTO -> handleAutoSearch(key)
|
||||
SearchType.DEFAULT -> handleDefaultSearch(key)
|
||||
SearchType.DISCOVERY -> handleDiscoverySearch(key)
|
||||
SearchType.RANK -> handleRankSearch(key)
|
||||
SearchType.HOT -> handleHotSearch(key)
|
||||
SearchType.HISTORY -> handleHistorySearch(key)
|
||||
@ -243,6 +245,22 @@ open class SearchActivity : BaseActivity() {
|
||||
)
|
||||
}
|
||||
|
||||
protected open fun handleDiscoverySearch(key: String?) {
|
||||
mSearchKey = key
|
||||
searchEt.setText(key)
|
||||
searchEt.setSelection(searchEt.text.length)
|
||||
updateDisplayType(GAME_DETAIL)
|
||||
LogUtils.uploadSearchGame("searching", "搜索页", key, "搜索发现")
|
||||
|
||||
SensorsBridge.trackSearchButtonClick(
|
||||
GlobalActivityManager.getCurrentPageEntity().pageId,
|
||||
GlobalActivityManager.getCurrentPageEntity().pageName,
|
||||
key ?: "",
|
||||
TRACK_SEARCH_TYPE_DISCOVERY,
|
||||
mSourceEntrance
|
||||
)
|
||||
}
|
||||
|
||||
protected open fun handleDefaultSearch(key: String?) {
|
||||
mSearchKey = key
|
||||
searchEt.setText(key)
|
||||
@ -311,6 +329,19 @@ 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) {
|
||||
@ -381,7 +412,7 @@ open class SearchActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
protected fun popBackToFragment(tag: String) {
|
||||
supportFragmentManager.popBackStack(tag, 0)
|
||||
supportFragmentManager.popBackStackAllowStateLoss(tag, 0)
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
@ -390,6 +421,7 @@ open class SearchActivity : BaseActivity() {
|
||||
SearchType.HISTORY.value -> search(SearchType.HISTORY, search.key)
|
||||
SearchType.HOT.value -> search(SearchType.HOT, search.key)
|
||||
SearchType.RANK.value -> search(SearchType.RANK, search.key)
|
||||
SearchType.DISCOVERY.value -> search(SearchType.DISCOVERY, search.key)
|
||||
|
||||
"click" -> DataCollectionUtils.uploadSearchClick(
|
||||
this, mSearchKey, mSearchType.value, "搜索页面",
|
||||
@ -434,6 +466,7 @@ open class SearchActivity : BaseActivity() {
|
||||
const val TRACK_SEARCH_TYPE_DEFAULT = "默认搜索"
|
||||
const val TRACK_SEARCH_TYPE_HISTORY = "历史搜索"
|
||||
const val TRACK_SEARCH_TYPE_RANK = "榜单搜索"
|
||||
const val TRACK_SEARCH_TYPE_DISCOVERY = "搜索发现"
|
||||
|
||||
@JvmStatic
|
||||
fun toTrackSearchType(type: String) = when (type) {
|
||||
@ -441,6 +474,7 @@ open class SearchActivity : BaseActivity() {
|
||||
SearchType.MANUAL.value -> TRACK_SEARCH_TYPE_INPUT
|
||||
SearchType.HISTORY.value -> TRACK_SEARCH_TYPE_HISTORY
|
||||
SearchType.RANK.value -> TRACK_SEARCH_TYPE_RANK
|
||||
SearchType.DISCOVERY.value -> TRACK_SEARCH_TYPE_DISCOVERY
|
||||
else -> TRACK_SEARCH_TYPE_DEFAULT
|
||||
}
|
||||
|
||||
@ -490,7 +524,8 @@ enum class SearchType(var value: String) {
|
||||
HISTORY("history"),
|
||||
MANUAL("initiative"),
|
||||
HOT("remen"),
|
||||
RANK("rank");
|
||||
RANK("rank"),
|
||||
DISCOVERY("dicovery");
|
||||
|
||||
fun toChinese() = when (this) {
|
||||
AUTO -> "自动搜索"
|
||||
@ -499,6 +534,7 @@ enum class SearchType(var value: String) {
|
||||
MANUAL -> "主动搜索"
|
||||
HOT -> "热门搜索"
|
||||
RANK -> "榜单搜索"
|
||||
DISCOVERY -> "搜索发现"
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@ -62,16 +62,16 @@ import com.gh.gamecenter.common.base.activity.BaseActivity;
|
||||
import com.gh.gamecenter.common.constant.Constants;
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts;
|
||||
import com.gh.gamecenter.common.entity.CommunityEntity;
|
||||
import com.gh.gamecenter.common.entity.LinkEntity;
|
||||
import com.gh.gamecenter.common.entity.LaunchRedirect;
|
||||
import com.gh.gamecenter.common.entity.SimpleGameEntity;
|
||||
import com.gh.gamecenter.core.utils.GsonUtils;
|
||||
import com.gh.gamecenter.core.utils.ToastUtils;
|
||||
import com.gh.gamecenter.entity.SubjectData;
|
||||
import com.gh.gamecenter.entity.SubjectRecommendEntity;
|
||||
import com.gh.gamecenter.entity.VideoLinkEntity;
|
||||
import com.gh.gamecenter.feature.minigame.MiniGameItemHelper;
|
||||
import com.gh.gamecenter.feature.utils.PlatformUtils;
|
||||
import com.gh.gamecenter.login.view.LoginActivity;
|
||||
import com.gh.gamecenter.feature.minigame.MiniGameItemHelper;
|
||||
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel;
|
||||
import com.gh.gamecenter.video.videomanager.VideoManagerActivity;
|
||||
import com.gh.vspace.VHelper;
|
||||
@ -356,8 +356,8 @@ public class SkipActivity extends BaseActivity {
|
||||
if (!TextUtils.isEmpty(dataString)) {
|
||||
byte[] linkData = Base64.decode(dataString, Base64.DEFAULT);
|
||||
String linkDataString = new String(linkData, "UTF-8");
|
||||
LinkEntity le = GsonUtils.INSTANCE.getGson().fromJson(linkDataString, LinkEntity.class);
|
||||
DirectUtils.directToLinkPage(this, le, entrance, "", "");
|
||||
LaunchRedirect launchRedirect = GsonUtils.fromJson(linkDataString, LaunchRedirect.class);
|
||||
DirectUtils.directToLinkPage(this, launchRedirect, entrance, "", "");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@ -14,8 +14,6 @@ import androidx.core.app.NotificationCompat
|
||||
import androidx.core.text.bold
|
||||
import androidx.core.text.buildSpannedString
|
||||
import androidx.core.text.color
|
||||
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
|
||||
@ -32,13 +30,14 @@ import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.iinterface.ISplashScreen
|
||||
import com.gh.gamecenter.core.provider.IAppProvider
|
||||
import com.gh.gamecenter.core.provider.IPackageUtilsProvider
|
||||
import com.gh.gamecenter.core.provider.IPushProvider
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.feature.utils.PlatformUtils
|
||||
import com.gh.gamecenter.pkg.PkgHelper
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.therouter.TheRouter
|
||||
import com.therouter.router.Route
|
||||
import org.json.JSONObject
|
||||
import splitties.systemservices.notificationManager
|
||||
import java.text.SimpleDateFormat
|
||||
@ -90,8 +89,10 @@ 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点击这里进行预设置渠道")
|
||||
@ -103,7 +104,7 @@ class SplashScreenActivity : BaseActivity(), ISplashScreen {
|
||||
executeDex2OatInAdvance()
|
||||
DialogHelper.showDialog(
|
||||
context = this,
|
||||
title ="选择环境",
|
||||
title = "选择环境",
|
||||
content = spanBuilder,
|
||||
confirmText = "正式环境",
|
||||
cancelText = "测试环境",
|
||||
@ -130,6 +131,7 @@ class SplashScreenActivity : BaseActivity(), ISplashScreen {
|
||||
} else {
|
||||
launchMainActivity()
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
|
||||
SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, "")
|
||||
SPUtils.setString(Constants.SP_XAPK_URL, "")
|
||||
@ -282,11 +284,11 @@ class SplashScreenActivity : BaseActivity(), ISplashScreen {
|
||||
SensorsBridge.init(HaloApp.getInstance(), HaloApp.getInstance().channel)
|
||||
SensorsBridge.setOAID(HaloApp.getInstance().oaid)
|
||||
|
||||
val pushProvider = TheRouter.get(IPushProvider::class.java)
|
||||
val registrationId = pushProvider?.getRegistrationId(this)
|
||||
if (!registrationId.isNullOrEmpty()) {
|
||||
SensorsBridge.profileAppend(KEY_REGISTRATION_ID, registrationId)
|
||||
}
|
||||
// val pushProvider = ARouter.getInstance().build(RouteConsts.provider.push).navigation() as? IPushProvider
|
||||
// val registrationId = pushProvider?.getRegistrationId(this)
|
||||
// if (!registrationId.isNullOrEmpty()) {
|
||||
// SensorsBridge.profileSet(KEY_REGISTRATION_ID, registrationId)
|
||||
// }
|
||||
}
|
||||
|
||||
private fun prefetchData() {
|
||||
|
||||
@ -4,12 +4,15 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import com.gh.gamecenter.common.base.activity.ToolBarActivity
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.utils.updateStatusBarColor
|
||||
import com.halo.assistant.fragment.user.UserInfoFragment
|
||||
import com.therouter.router.Route
|
||||
|
||||
/**
|
||||
* 编辑资料
|
||||
*/
|
||||
@Route(
|
||||
path = RouteConsts.activity.userInfoActivity,
|
||||
description = "个人中心"
|
||||
)
|
||||
class UserInfoActivity : ToolBarActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@ -17,6 +20,14 @@ class UserInfoActivity : ToolBarActivity() {
|
||||
updateStatusBarColor(com.gh.gamecenter.common.R.color.ui_surface, com.gh.gamecenter.common.R.color.ui_surface)
|
||||
}
|
||||
|
||||
override fun provideNormalIntent(): Intent {
|
||||
return getTargetIntent(
|
||||
this,
|
||||
UserInfoActivity::class.java,
|
||||
UserInfoFragment::class.java
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getIntent(context: Context?): Intent? {
|
||||
return getTargetIntent(
|
||||
|
||||
@ -6,17 +6,19 @@ import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.KeyEvent
|
||||
import android.view.View
|
||||
import com.therouter.router.Route
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.gamecenter.common.base.activity.ToolBarActivity
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.entity.ToolBoxEntity
|
||||
import com.gh.gamecenter.common.utils.EnvHelper
|
||||
import com.gh.gamecenter.common.utils.updateStatusBarColor
|
||||
import com.gh.gamecenter.feature.entity.ConcernEntity
|
||||
import com.gh.gamecenter.feature.entity.NewsEntity
|
||||
import com.gh.gamecenter.common.entity.ToolBoxEntity
|
||||
import com.halo.assistant.fragment.WebFragment
|
||||
import com.halo.assistant.member.MemberActivity
|
||||
import com.therouter.router.Route
|
||||
|
||||
@Route(path = RouteConsts.activity.webActivity)
|
||||
open class WebActivity : ToolBarActivity() {
|
||||
@ -29,6 +31,8 @@ open class WebActivity : ToolBarActivity() {
|
||||
val mIsBackpressRequireConfirmation =
|
||||
bundle.getBoolean(WebFragment.KEY_REQUIRE_BACK_CONFIRMATION, false)
|
||||
mIsFullScreen = !TextUtils.isEmpty(mGameName) && mIsBackpressRequireConfirmation
|
||||
mIsFullScreen = true
|
||||
|
||||
if (mIsFullScreen) {
|
||||
setTheme(R.style.AppFullScreenTheme)
|
||||
}
|
||||
@ -305,5 +309,17 @@ open class WebActivity : ToolBarActivity() {
|
||||
intent.putExtra(NORMAL_FRAGMENT_BUNDLE, bundle)
|
||||
return intent
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getMyAssetsIntent(context: Context): Intent {
|
||||
val intent = Intent(context, MemberActivity::class.java)
|
||||
val url = if (EnvHelper.isDevEnv) {
|
||||
Constants.MY_ASSETS_DEV
|
||||
} else {
|
||||
Constants.MY_ASSETS
|
||||
}
|
||||
intent.putExtra(EntranceConsts.KEY_URL, url)
|
||||
return intent
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,8 +4,11 @@ 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
|
||||
@ -13,6 +16,7 @@ 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
|
||||
@ -45,6 +49,7 @@ 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.GameDetailFragment
|
||||
import com.gh.gamecenter.gamedetail.accelerator.GameDetailAcceleratorUiHelper
|
||||
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment
|
||||
import com.gh.gamecenter.teenagermode.TeenagerModeActivity.Companion.getIntent
|
||||
import com.gh.vspace.VHelper
|
||||
@ -62,7 +67,8 @@ class DetailViewHolder(
|
||||
name: String?,
|
||||
title: String?,
|
||||
val traceEvent: ExposureEvent?,
|
||||
val isSupportDualButton: Boolean = false // 是否支持双下载按钮,不支持的时候跟普通列表意义选用优先级高的那个来显示
|
||||
val isSupportDualButton: Boolean = false, // 是否支持双下载按钮,不支持的时候跟普通列表意义选用优先级高的那个来显示,
|
||||
val acceleratorUiHelper: GameDetailAcceleratorUiHelper? = null // 网速加速,只有游戏详情才有
|
||||
) {
|
||||
var context: Context
|
||||
var downloadBottom: View
|
||||
@ -90,6 +96,12 @@ 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)
|
||||
@ -104,6 +116,10 @@ class DetailViewHolder(
|
||||
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()
|
||||
@ -158,7 +174,9 @@ 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("游戏详情页")
|
||||
@ -176,6 +194,19 @@ class DetailViewHolder(
|
||||
gamePermissionDialogFragment?.dismissAllowingStateLoss()
|
||||
}
|
||||
|
||||
fun hideSpeedUi() {
|
||||
acceleratorUiHelper?.showSpeedUi = false
|
||||
}
|
||||
|
||||
fun showAcceleratorGuideLayer() {
|
||||
acceleratorUiHelper?.checkIfShowGuideLayer(context)
|
||||
}
|
||||
|
||||
fun setSpeedViewsVisible(isVisible: Boolean) {
|
||||
ivFreeVipTag?.goneIf(!isVisible)
|
||||
speedContainer?.goneIf(!isVisible)
|
||||
}
|
||||
|
||||
internal class OnDetailDownloadClickListener(
|
||||
private val mViewHolder: DetailViewHolder,
|
||||
private val mEntrance: String?,
|
||||
@ -194,6 +225,10 @@ 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!!)
|
||||
}
|
||||
}
|
||||
@ -271,14 +306,20 @@ class DetailViewHolder(
|
||||
ButtonStyle.NONE_WITH_HINT, ButtonStyle.NONE -> {
|
||||
val offStatus = mGameEntity.downloadOffStatus
|
||||
if (offStatus != null && "off" != offStatus) {
|
||||
if ("dialog" == offStatus) {
|
||||
showOffServiceDialog(mGameEntity.downloadOffDialog) {
|
||||
when (offStatus) {
|
||||
"dialog" -> {
|
||||
showOffServiceDialog(mGameEntity.downloadOffDialog) {
|
||||
showLandPageAddressDialogIfNeeded()
|
||||
}
|
||||
}
|
||||
"toast" -> {
|
||||
EventBus.getDefault().post(EBReuse(GameDetailFragment.SKIP_RATING))
|
||||
ToastUtils.toast("该游戏因故暂不提供下载,具体详情可在相关评论中查看,敬请谅解~")
|
||||
showLandPageAddressDialogIfNeeded()
|
||||
}
|
||||
"third_party" -> {
|
||||
showLandPageAddressDialogIfNeeded()
|
||||
}
|
||||
} else if ("toast" == offStatus) {
|
||||
EventBus.getDefault().post(EBReuse(GameDetailFragment.SKIP_RATING))
|
||||
ToastUtils.toast("该游戏因故暂不提供下载,具体详情可在相关评论中查看,敬请谅解~")
|
||||
showLandPageAddressDialogIfNeeded()
|
||||
}
|
||||
} else {
|
||||
ToastUtils.toast("该游戏已关闭下载")
|
||||
@ -324,7 +365,19 @@ class DetailViewHolder(
|
||||
if (mAsVGame) {
|
||||
VHelper.installOrLaunch(mViewHolder.context, mGameEntity, null)
|
||||
} else {
|
||||
PackageLauncher.launchApp(mViewHolder.context, mGameEntity, mGameEntity.getUniquePackageName())
|
||||
// 如果游戏配置了加速,则启动时需要进行包名检测
|
||||
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()
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
GamePermissionDialogFragment.show(
|
||||
@ -455,17 +508,9 @@ class DetailViewHolder(
|
||||
}
|
||||
|
||||
ButtonStyle.RESERVED -> {
|
||||
if ("download" == mGameEntity.reserveStatus) {
|
||||
ReservationHelper.showDeleteReservationDialog(mViewHolder.context) {
|
||||
ReservationHelper.deleteReservation(mGameEntity) {
|
||||
DetailDownloadUtils.updateViewHolder(mViewHolder)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ReservationHelper.showCancelReservationDialog(mViewHolder.context, mGameEntity) {
|
||||
ReservationHelper.cancelReservation(mGameEntity) {
|
||||
DetailDownloadUtils.updateViewHolder(mViewHolder)
|
||||
}
|
||||
ReservationHelper.showCancelReservationDialog(mViewHolder.context, mGameEntity) {
|
||||
ReservationHelper.cancelReservation(mGameEntity) {
|
||||
DetailDownloadUtils.updateViewHolder(mViewHolder)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -592,8 +637,9 @@ 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)
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
package com.gh.gamecenter.authorization
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.UserHandle
|
||||
import com.gh.common.util.CheckLoginUtils
|
||||
import com.gh.common.util.DialogUtils
|
||||
import com.gh.common.util.NewFlatLogUtils
|
||||
import com.gh.common.util.PackageUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.activity.ToolBarActivity
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
@ -16,6 +19,7 @@ import com.gh.gamecenter.common.utils.viewModelProvider
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.databinding.ActivityAuthorizationBinding
|
||||
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.lightgame.utils.Utils
|
||||
@ -68,6 +72,13 @@ class AuthorizationActivity : ToolBarActivity() {
|
||||
//授权token
|
||||
private var mToken = ""
|
||||
|
||||
/**
|
||||
* 游戏UID (适配双开/分身游戏)
|
||||
*/
|
||||
private var gameUid = -1
|
||||
|
||||
private var loadingDialog: Dialog? = null
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_authorization
|
||||
}
|
||||
@ -80,11 +91,16 @@ class AuthorizationActivity : ToolBarActivity() {
|
||||
mBinding = ActivityAuthorizationBinding.bind(mContentView)
|
||||
checkParam()
|
||||
initView()
|
||||
mBinding.authorizeBtn.postDelayed({
|
||||
mBaseHandler.post {
|
||||
if (loadingDialog == null) {
|
||||
loadingDialog = DialogUtils.showWaitDialog(this, "请稍后...")
|
||||
}
|
||||
}
|
||||
UserRepository.getInstance().loginUserInfo.observe(this) {
|
||||
checkLogin {
|
||||
initUserInfo()
|
||||
}
|
||||
}, 500)
|
||||
}
|
||||
NewFlatLogUtils.logLoginFromGHZSShow(
|
||||
gameId = gameId,
|
||||
gameName = gameName
|
||||
@ -97,14 +113,21 @@ class AuthorizationActivity : ToolBarActivity() {
|
||||
}
|
||||
|
||||
private fun initData() {
|
||||
if (mToken.isNotEmpty() || isFinishing) return
|
||||
val loadingDialog = DialogUtils.showWaitDialog(this, "请稍后...")
|
||||
if (mToken.isNotEmpty() || isFinishing) {
|
||||
loadingDialog?.dismiss()
|
||||
return
|
||||
}
|
||||
if (loadingDialog == null) {
|
||||
loadingDialog = DialogUtils.showWaitDialog(this, "请稍后...")
|
||||
} else if (loadingDialog?.isShowing == false) {
|
||||
loadingDialog?.show()
|
||||
}
|
||||
mViewModel.getAccessToken(listOf(mContent), {
|
||||
mToken = it
|
||||
loadingDialog.dismiss()
|
||||
loadingDialog?.dismiss()
|
||||
}, {
|
||||
toast("获取token失败")
|
||||
loadingDialog.dismiss()
|
||||
loadingDialog?.dismiss()
|
||||
})
|
||||
}
|
||||
|
||||
@ -143,6 +166,7 @@ class AuthorizationActivity : ToolBarActivity() {
|
||||
mContent = uri.getQueryParameter(EntranceConsts.KEY_CONTENT) ?: ""
|
||||
gameId = uri.getQueryParameter(EntranceConsts.KEY_GAME_ID) ?: ""
|
||||
gameName = uri.getQueryParameter(EntranceConsts.KEY_GAME_NAME) ?: ""
|
||||
gameUid = uri.getQueryParameter(EntranceConsts.KEY_UID)?.toIntOrNull() ?: -1
|
||||
if (mRemotePkgName == null) {
|
||||
finish()
|
||||
return
|
||||
@ -152,8 +176,8 @@ class AuthorizationActivity : ToolBarActivity() {
|
||||
private fun initView() {
|
||||
//通过包名获取app图标和名称
|
||||
val pkgName = mRemotePkgName ?: return
|
||||
val icon = packageManager.getApplicationIcon(pkgName)
|
||||
val name = packageManager.getApplicationLabel(packageManager.getApplicationInfo(pkgName, 0))
|
||||
val icon = PackageUtils.getIconByPackageName(this, pkgName)
|
||||
val name = PackageUtils.getNameByPackageName(this, pkgName)
|
||||
mBinding.authorizeAppIcon.setImageDrawable(icon)
|
||||
mBinding.authorizeAppName.text = name
|
||||
mBinding.authorizeBtn.setOnClickListener {
|
||||
@ -217,7 +241,11 @@ class AuthorizationActivity : ToolBarActivity() {
|
||||
intent.putExtra(EntranceConsts.KEY_USER_ID, userId)
|
||||
intent.putExtra(EntranceConsts.KEY_USER_NAME, username)
|
||||
intent.putExtra(EntranceConsts.KEY_USER_AVATAR, userAvatar)
|
||||
sendBroadcast(intent)
|
||||
if (gameUid != -1 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
sendBroadcastAsUser(intent, UserHandle.getUserHandleForUid(gameUid))
|
||||
} else {
|
||||
sendBroadcast(intent)
|
||||
}
|
||||
logAuthResult(true)
|
||||
backToLaunchApp()
|
||||
finish()
|
||||
@ -242,10 +270,10 @@ class AuthorizationActivity : ToolBarActivity() {
|
||||
VHelper.launch(this, gamePkg, ignoreGApps = true, showLoading = showLoading)
|
||||
return
|
||||
}
|
||||
val remotePkgName = this.mRemotePkgName
|
||||
if (remotePkgName != null) {// 跳转回其他授权app
|
||||
startActivity(packageManager.getLaunchIntentForPackage(remotePkgName))
|
||||
}
|
||||
// val remotePkgName = this.mRemotePkgName
|
||||
// if (remotePkgName != null) {// 跳转回其他授权app
|
||||
// startActivity(packageManager.getLaunchIntentForPackage(remotePkgName))
|
||||
// }
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
|
||||
@ -132,6 +132,13 @@ class GamesCollectionAdapter(
|
||||
)
|
||||
mExposureEventArray?.put(position, exposureEvent)
|
||||
|
||||
val path = when (mViewModel.type) {
|
||||
GamesCollectionFragment.TYPE_COLLECT -> "我的收藏-游戏单"
|
||||
GamesCollectionFragment.TYPE_HISTORY -> "浏览记录-游戏单"
|
||||
GamesCollectionFragment.TYPE_USER -> "个人主页-游戏单"
|
||||
else -> ""
|
||||
}
|
||||
|
||||
holder.binding.run {
|
||||
ImageUtils.display(poster, itemEntity.cover)
|
||||
nameTv.text = itemEntity.title
|
||||
@ -249,12 +256,6 @@ class GamesCollectionAdapter(
|
||||
}
|
||||
|
||||
userIcon.setOnClickListener {
|
||||
val path = when (mViewModel.type) {
|
||||
GamesCollectionFragment.TYPE_COLLECT -> "我的收藏-游戏单"
|
||||
GamesCollectionFragment.TYPE_HISTORY -> "浏览记录-游戏单"
|
||||
GamesCollectionFragment.TYPE_USER -> "个人主页-游戏单"
|
||||
else -> ""
|
||||
}
|
||||
DirectUtils.directToHomeActivity(mContext, itemEntity.user?.id, "", path)
|
||||
}
|
||||
userName.setOnClickListener { userIcon.performClick() }
|
||||
@ -266,7 +267,8 @@ class GamesCollectionAdapter(
|
||||
mContext,
|
||||
itemEntity.id,
|
||||
isScrollToCommentArea = true,
|
||||
exposureSourceList = ArrayList(exposureEvent.source)
|
||||
exposureSourceList = ArrayList(exposureEvent.source),
|
||||
entrance = path
|
||||
)
|
||||
)
|
||||
}
|
||||
@ -329,7 +331,8 @@ class GamesCollectionAdapter(
|
||||
GameCollectionDetailActivity.getIntent(
|
||||
mContext,
|
||||
itemEntity.id,
|
||||
exposureSourceList = ArrayList(exposureEvent.source)
|
||||
exposureSourceList = ArrayList(exposureEvent.source),
|
||||
entrance = path
|
||||
)
|
||||
)
|
||||
} else {
|
||||
|
||||
@ -12,6 +12,7 @@ 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
|
||||
@ -398,6 +399,10 @@ 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!!)
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
package com.gh.gamecenter.entity
|
||||
|
||||
import com.gh.gamecenter.feature.entity.SimpleGame
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
class GameServerTestTopGame(
|
||||
@SerializedName("_id")
|
||||
var id: String = "",
|
||||
var game: SimpleGame? = null,
|
||||
@SerializedName("column_test_v2_icon")
|
||||
var icon: String = "",
|
||||
@SerializedName("event_description")
|
||||
var description: String = "",
|
||||
@SerializedName("event_date")
|
||||
var date: String = ""
|
||||
)
|
||||
@ -18,7 +18,13 @@ data class SearchSubjectEntity(
|
||||
@SerializedName("ad_icon_active")
|
||||
val adIconActive: Boolean = false,
|
||||
// 本地字段,标记是否为微信小游戏CPM专题
|
||||
var isWGameSubjectCPM: Boolean = false
|
||||
var isWGameSubjectCPM: Boolean = false,
|
||||
val type: String = ""
|
||||
) : Parcelable {
|
||||
|
||||
companion object {
|
||||
const val TYPE_WECHAT_GAME_CPM_COLUMN = "wechat_game_cpm_column"
|
||||
}
|
||||
|
||||
fun getFilterGame() = RegionSettingHelper.filterGame(games)
|
||||
}
|
||||
@ -288,7 +288,8 @@ class ForumContentSearchListFragment : LazyListFragment<AnswerEntity, ForumConte
|
||||
mSearchKey,
|
||||
SearchActivity.toTrackSearchType(mSearchType),
|
||||
contentId ?: "",
|
||||
title ?: ""
|
||||
title ?: "",
|
||||
sequence
|
||||
)
|
||||
|
||||
NewFlatLogUtils.logSearchContentClick(
|
||||
|
||||
@ -39,8 +39,8 @@ class ForumOrUserSearchDefaultFragment : SearchDefaultFragment() {
|
||||
|
||||
override fun initView() {
|
||||
mBinding = FragmentSearchDefaultBinding.bind(mCachedView)
|
||||
mBinding.hotTagHeadContainer.root.visibility = View.GONE
|
||||
mBinding.hotTagFlexContainer.visibility = View.GONE
|
||||
mBinding.hotAndDiscoveryTagHeadContainer.root.visibility = View.GONE
|
||||
mBinding.hotAndDiscoveryTagFlexContainer.visibility = View.GONE
|
||||
if (mEntrance == "论坛首页" || mEntrance == "搜索栏") {
|
||||
mBinding.hotHeadContainer.headTitle.text = "热门论坛"
|
||||
mViewModel.getForumSearchHotContent()
|
||||
|
||||
@ -40,7 +40,8 @@ class UserSearchListFragment : LazyListFragment<FollowersOrFansEntity, UserSearc
|
||||
mSearchKey,
|
||||
SearchActivity.toTrackSearchType(mSearchType),
|
||||
mListViewModel.sourceEntrance,
|
||||
userId
|
||||
userId,
|
||||
position
|
||||
)
|
||||
NewFlatLogUtils.logSearchUserClick(
|
||||
SearchType.fromString(mSearchType).toChinese(),
|
||||
|
||||
@ -4,14 +4,18 @@ import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.lifecycle.ViewModelProviders
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.GlobalActivityManager
|
||||
import com.gh.gamecenter.common.baselist.LazyListFragment
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts.KEY_SHOW_SUBJECT_TAB
|
||||
import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.common.json.json
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge
|
||||
import com.gh.gamecenter.common.utils.observeNonNull
|
||||
import com.gh.gamecenter.common.utils.toColor
|
||||
import com.gh.gamecenter.databinding.FragmentColumnCollectionDetailBinding
|
||||
import com.gh.gamecenter.entity.GameColumnCollection
|
||||
import com.gh.gamecenter.entity.SubjectData
|
||||
import com.gh.gamecenter.subject.tab.SubjectTabFragment
|
||||
|
||||
@ -55,11 +59,37 @@ class ColumnCollectionDetailFragment : LazyListFragment<LinkEntity, ColumnCollec
|
||||
mListViewModel.getGameColumnCollection()
|
||||
mListViewModel.columnCollection.observeNonNull(this) {
|
||||
setNavigationTitle(it.name)
|
||||
|
||||
mCachedView?.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext()))
|
||||
logPageShow(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun logPageShow(entity: GameColumnCollection) {
|
||||
val tabIndex = arguments?.getInt(EntranceConsts.KEY_TAB_INDEX, -1) ?: -1
|
||||
val tabName = arguments?.getString(EntranceConsts.KEY_TAB_NAME, "") ?: ""
|
||||
val multiTabNavId = arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_ID, "") ?: ""
|
||||
val multiTabNavName = arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_NAME, "") ?: ""
|
||||
val bottomTabName = arguments?.getString(EntranceConsts.KEY_BOTTOM_TAB_NAME, "") ?: ""
|
||||
mBaseHandler.postDelayed({
|
||||
SensorsBridge.trackEvent("ColumnCollectionDetailPageShow", json {
|
||||
"column_collection_name" to entity.name
|
||||
"column_collection_id" to entity.id
|
||||
"page_name" to GlobalActivityManager.getCurrentPageEntity().pageName
|
||||
"page_id" to GlobalActivityManager.getCurrentPageEntity().pageId
|
||||
"page_business_id" to GlobalActivityManager.getCurrentPageEntity().pageBusinessId
|
||||
"last_page_name" to GlobalActivityManager.getLastPageEntity().pageName
|
||||
"last_page_id" to GlobalActivityManager.getLastPageEntity().pageId
|
||||
"last_page_business_id" to GlobalActivityManager.getLastPageEntity().pageBusinessId
|
||||
"bottom_tab" to bottomTabName
|
||||
"several_tab_page_name" to multiTabNavName
|
||||
"several_tab_page_id" to multiTabNavId
|
||||
"position" to tabIndex
|
||||
"tab_content" to tabName
|
||||
"source_entrance" to mEntrance
|
||||
})
|
||||
}, 3000L)
|
||||
}
|
||||
|
||||
override fun onChanged(list: MutableList<LinkEntity>?) {
|
||||
if (list != null && list.isNotEmpty()) {
|
||||
showSubjectTab(list)
|
||||
|
||||
@ -11,18 +11,22 @@ import com.gh.common.exposure.ExposureListener
|
||||
import com.gh.common.exposure.IExposable
|
||||
import com.gh.common.util.NewLogUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.GlobalActivityManager
|
||||
import com.gh.gamecenter.common.baselist.LazyListFragment
|
||||
import com.gh.gamecenter.common.baselist.ListAdapter
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.common.json.json
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.common.utils.viewModelProvider
|
||||
import com.gh.gamecenter.common.view.FixGridLayoutManager
|
||||
import com.gh.gamecenter.common.view.GridSpacingItemDecoration
|
||||
import com.gh.gamecenter.common.view.VerticalItemDecoration
|
||||
import com.gh.gamecenter.databinding.FragmentListBaseSkeletonBinding
|
||||
import com.gh.gamecenter.entity.CommonCollectionEntity
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageItem
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMMON_CONTENT_COLLECTION_LAYOUT_HORIZONTAL_SLIDE_BANNER
|
||||
|
||||
@ -120,6 +124,8 @@ class CustomCommonCollectionDetailFragment : LazyListFragment<LinkEntity, Custom
|
||||
}
|
||||
mListRv?.removeItemDecorationAt(0)
|
||||
mListRv?.addItemDecoration(itemDecoration)
|
||||
|
||||
logPageShow(it)
|
||||
}
|
||||
mListViewModel.loadExceptionLiveData.observe(viewLifecycleOwner) {
|
||||
if (it != null && it.code() == 404) {
|
||||
@ -154,6 +160,32 @@ class CustomCommonCollectionDetailFragment : LazyListFragment<LinkEntity, Custom
|
||||
})
|
||||
}
|
||||
|
||||
private fun logPageShow(entity: CommonCollectionEntity) {
|
||||
val tabIndex = arguments?.getInt(EntranceConsts.KEY_TAB_INDEX, -1) ?: -1
|
||||
val tabName = arguments?.getString(EntranceConsts.KEY_TAB_NAME, "") ?: ""
|
||||
val multiTabNavId = arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_ID, "") ?: ""
|
||||
val multiTabNavName = arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_NAME, "") ?: ""
|
||||
val bottomTabName = arguments?.getString(EntranceConsts.KEY_BOTTOM_TAB_NAME, "") ?: ""
|
||||
mBaseHandler.postDelayed({
|
||||
SensorsBridge.trackEvent("LinkContentCollectionDetailPageShow", json {
|
||||
"link_content_collection_name" to entity.name
|
||||
"link_content_collection_id" to entity.id
|
||||
"page_name" to GlobalActivityManager.getCurrentPageEntity().pageName
|
||||
"page_id" to GlobalActivityManager.getCurrentPageEntity().pageId
|
||||
"page_business_id" to GlobalActivityManager.getCurrentPageEntity().pageBusinessId
|
||||
"last_page_name" to GlobalActivityManager.getLastPageEntity().pageName
|
||||
"last_page_id" to GlobalActivityManager.getLastPageEntity().pageId
|
||||
"last_page_business_id" to GlobalActivityManager.getLastPageEntity().pageBusinessId
|
||||
"bottom_tab" to bottomTabName
|
||||
"several_tab_page_name" to multiTabNavName
|
||||
"several_tab_page_id" to multiTabNavId
|
||||
"position" to tabIndex
|
||||
"tab_content" to tabName
|
||||
"source_entrance" to mEntrance
|
||||
})
|
||||
}, 3000L)
|
||||
}
|
||||
|
||||
override fun getItemDecoration(): RecyclerView.ItemDecoration =
|
||||
when (mCollectionStyle) {
|
||||
"1-2" ->
|
||||
|
||||
@ -49,21 +49,24 @@ class GameCollectionDetailActivity : ToolBarActivity() {
|
||||
fun getIntent(
|
||||
context: Context,
|
||||
gameCollectionId: String,
|
||||
isFromSquare: Boolean = false
|
||||
isFromSquare: Boolean = false,
|
||||
entrance: String = ""
|
||||
): Intent {
|
||||
return getIntent(context, gameCollectionId, "", isFromSquare, false)
|
||||
return getIntent(context, gameCollectionId, "", isFromSquare, false, entrance = entrance)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getSpecifiedCommentIntent(
|
||||
context: Context,
|
||||
gameCollectionId: String,
|
||||
topCommentId: String
|
||||
topCommentId: String,
|
||||
entrance: String
|
||||
): Intent {
|
||||
return getIntent(
|
||||
context, gameCollectionId, topCommentId,
|
||||
isFromSquare = false,
|
||||
isScrollToCommentArea = true
|
||||
isScrollToCommentArea = true,
|
||||
entrance = entrance
|
||||
)
|
||||
}
|
||||
|
||||
@ -74,13 +77,15 @@ class GameCollectionDetailActivity : ToolBarActivity() {
|
||||
topCommentId: String = "",
|
||||
isFromSquare: Boolean = false,
|
||||
isScrollToCommentArea: Boolean = false,
|
||||
exposureSourceList: ArrayList<ExposureSource>? = null
|
||||
exposureSourceList: ArrayList<ExposureSource>? = null,
|
||||
entrance: String = ""
|
||||
): Intent {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(EntranceConsts.KEY_GAME_COLLECTION_ID, gameCollectionId)
|
||||
bundle.putString(EntranceConsts.KEY_TOP_COMMENT_ID, topCommentId)
|
||||
bundle.putBoolean(EntranceConsts.KEY_IS_FROM_SQUARE, isFromSquare)
|
||||
bundle.putBoolean(EntranceConsts.KEY_SCROLL_TO_COMMENT_AREA, isScrollToCommentArea)
|
||||
bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance)
|
||||
if (exposureSourceList != null) {
|
||||
bundle.putParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST, exposureSourceList)
|
||||
}
|
||||
|
||||
@ -851,6 +851,7 @@ class GameCollectionDetailFragment :
|
||||
trackEvent.put("game_collect_title", mGameCollectionTitle)
|
||||
trackEvent.put("game_collect_id", mGameCollectionId)
|
||||
trackEvent.put("stay_length", mElapsedHelper?.elapsedTime)
|
||||
trackEvent.put("source_entrance", mEntrance)
|
||||
} catch (e: JSONException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import androidx.recyclerview.widget.DefaultItemAnimator
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.common.exposure.ExposureListener
|
||||
import com.gh.common.util.NewFlatLogUtils
|
||||
import com.gh.gamecenter.common.base.GlobalActivityManager
|
||||
import com.gh.gamecenter.common.baselist.ListFragment
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
@ -58,6 +59,7 @@ class GameCollectionHotListFragment : ListFragment<GameCollectionListItemData, G
|
||||
if (requireActivity() is GameCollectionListDetailActivity) {
|
||||
mBasicExposureSourceList.add(ExposureSource("游戏单合集", mGameCollectionListEntity?.id ?: ""))
|
||||
mBasicExposureSourceList.add(ExposureSource("合集详情", ""))
|
||||
logPageShow()
|
||||
} else {
|
||||
mBasicExposureSourceList.add(ExposureSource("游戏单热榜", ""))
|
||||
mBasicExposureSourceList.add(ExposureSource("游戏单合集", mGameCollectionListEntity?.id ?: ""))
|
||||
@ -68,6 +70,32 @@ class GameCollectionHotListFragment : ListFragment<GameCollectionListItemData, G
|
||||
}
|
||||
}
|
||||
|
||||
private fun logPageShow() {
|
||||
val tabIndex = arguments?.getInt(EntranceConsts.KEY_TAB_INDEX, -1) ?: -1
|
||||
val tabName = arguments?.getString(EntranceConsts.KEY_TAB_NAME, "") ?: ""
|
||||
val multiTabNavId = arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_ID, "") ?: ""
|
||||
val multiTabNavName = arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_NAME, "") ?: ""
|
||||
val bottomTabName = arguments?.getString(EntranceConsts.KEY_BOTTOM_TAB_NAME, "") ?: ""
|
||||
mBaseHandler.postDelayed({
|
||||
SensorsBridge.trackEvent("GameListCollectionDetailPageShow", json {
|
||||
"game_list_collection_name" to mGameCollectionListEntity?.name
|
||||
"game_list_collection_id" to mGameCollectionListEntity?.id
|
||||
"page_name" to GlobalActivityManager.getCurrentPageEntity().pageName
|
||||
"page_id" to GlobalActivityManager.getCurrentPageEntity().pageId
|
||||
"page_business_id" to GlobalActivityManager.getCurrentPageEntity().pageBusinessId
|
||||
"last_page_name" to GlobalActivityManager.getLastPageEntity().pageName
|
||||
"last_page_id" to GlobalActivityManager.getLastPageEntity().pageId
|
||||
"last_page_business_id" to GlobalActivityManager.getLastPageEntity().pageBusinessId
|
||||
"bottom_tab" to bottomTabName
|
||||
"several_tab_page_name" to multiTabNavName
|
||||
"several_tab_page_id" to multiTabNavId
|
||||
"position" to tabIndex
|
||||
"tab_content" to tabName
|
||||
"source_entrance" to mEntrance
|
||||
})
|
||||
}, 3000L)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
if (mListRefresh != null) {
|
||||
mListRefresh!!.setColorSchemeResources(com.gh.gamecenter.common.R.color.primary_theme)
|
||||
|
||||
@ -76,7 +76,8 @@ class MyGameCollectionViewHolder(
|
||||
binding.root.context.startActivity(
|
||||
GameCollectionDetailActivity.getIntent(
|
||||
binding.root.context,
|
||||
entity.id
|
||||
entity.id,
|
||||
entrance = path
|
||||
)
|
||||
)
|
||||
} else {
|
||||
|
||||
@ -11,6 +11,7 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.os.bundleOf
|
||||
import com.gh.common.provider.CropImageProviderImpl.Companion.IMAGE_TYPE_GAME_COLLECTION_COVER
|
||||
import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.common.util.NewLogUtils
|
||||
@ -45,7 +46,8 @@ class ChooseGameCollectionCoverTypeDialog : BaseDialogFragment() {
|
||||
requireContext(),
|
||||
ChooseType.IMAGE,
|
||||
1,
|
||||
"创建游戏单"
|
||||
"创建游戏单",
|
||||
IMAGE_TYPE_GAME_COLLECTION_COVER
|
||||
), REQUEST_CODE_IMAGE
|
||||
)
|
||||
}
|
||||
@ -101,7 +103,8 @@ class ChooseGameCollectionCoverTypeDialog : BaseDialogFragment() {
|
||||
com.gh.gamecenter.common.R.drawable.bg_choose_option_selector.toDrawable(requireContext())
|
||||
defaultUploadContainer.background =
|
||||
com.gh.gamecenter.common.R.drawable.bg_choose_option_selector.toDrawable(requireContext())
|
||||
cancelBtn.background = com.gh.gamecenter.common.R.drawable.bg_shape_f5_radius_999.toDrawable(requireContext())
|
||||
cancelBtn.background =
|
||||
com.gh.gamecenter.common.R.drawable.bg_shape_f5_radius_999.toDrawable(requireContext())
|
||||
recommentTv.background = R.drawable.bg_game_collection_cover_tag.toDrawable(requireContext())
|
||||
titleTv.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(requireContext()))
|
||||
localUploadTitleTv.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext()))
|
||||
|
||||
@ -313,14 +313,14 @@ class GameCollectionEditActivity : ToolBarActivity(), ChooseGamesAdapter.ItemDra
|
||||
val games = mChooseGamesViewModel.chooseGamesLiveData.value ?: arrayListOf()
|
||||
if (mIsCreateGameCollection) {
|
||||
SensorsBridge.trackEvent("GameCollectCreateSuccess", json {
|
||||
"game_collect_status" to if(mBinding.selfOnlyCb.isChecked) "仅自己可见" else "公开"
|
||||
"game_collect_status" to if (mBinding.selfOnlyCb.isChecked) "仅自己可见" else "公开"
|
||||
"game_num" to games.size
|
||||
"game_collect_title" to mBinding.gameCollectionTitleEt.text.toString().trim()
|
||||
"game_collect_id" to it.data as String
|
||||
})
|
||||
} else if (mViewModel.gameCollectionPatch != null) {
|
||||
SensorsBridge.trackEvent("GameCollectEditSuccess", json {
|
||||
"game_collect_status" to if(mBinding.selfOnlyCb.isChecked) "仅自己可见" else "公开"
|
||||
"game_collect_status" to if (mBinding.selfOnlyCb.isChecked) "仅自己可见" else "公开"
|
||||
"game_num" to games.size
|
||||
"game_collect_title" to mBinding.gameCollectionTitleEt.text.toString().trim()
|
||||
"game_collect_id" to mViewModel.gameCollectionPatch?.id
|
||||
@ -355,7 +355,7 @@ class GameCollectionEditActivity : ToolBarActivity(), ChooseGamesAdapter.ItemDra
|
||||
CheckLoginUtils.checkLogin(this, mEntrance) {}
|
||||
return@observe
|
||||
}
|
||||
ErrorHelper.handleError(this, errorMsg, false, "发布游戏单", "社区实名") {
|
||||
ErrorHelper.handleError(this, errorMsg, false, "发布游戏单", "社区实名") {
|
||||
if (::mMenuPost.isInitialized) {
|
||||
onMenuItemClick(mMenuPost)
|
||||
}
|
||||
@ -433,18 +433,6 @@ class GameCollectionEditActivity : ToolBarActivity(), ChooseGamesAdapter.ItemDra
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (data == null || resultCode != Activity.RESULT_OK) return
|
||||
when (requestCode) {
|
||||
REQUEST_CODE_IMAGE_CROP -> {
|
||||
val imagePath = data.getStringExtra(CropImageActivity.RESULT_CLIP_PATH) ?: ""
|
||||
mViewModel.imageUrl = ""
|
||||
mViewModel.imagePath = imagePath
|
||||
if (imagePath.isEmpty()) {
|
||||
mBinding.uploadPictureTv.text = "点击上传图片"
|
||||
} else {
|
||||
mBinding.uploadPictureTv.text = "图片上传中..."
|
||||
mViewModel.uploadPoster()
|
||||
}
|
||||
initPosterUI()
|
||||
}
|
||||
REQUEST_CHOOSE_TAG -> {
|
||||
val tags = data.getParcelableArrayListExtra<TagInfoEntity>(GameCollectionTagSelectFragment.SELECTED_TAG)
|
||||
?: arrayListOf()
|
||||
@ -457,20 +445,16 @@ class GameCollectionEditActivity : ToolBarActivity(), ChooseGamesAdapter.ItemDra
|
||||
fun onActivityDialogResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||
if (requestCode == REQUEST_CODE_IMAGE) {
|
||||
val selectedPaths = Matisse.obtainResult(data)
|
||||
if (!selectedPaths.isNullOrEmpty()) {
|
||||
val path = PathUtils.getPath(this, selectedPaths[0])
|
||||
val intent =
|
||||
CropImageActivity.getIntent(
|
||||
this,
|
||||
path,
|
||||
142 / 328F,
|
||||
false,
|
||||
R.layout.layout_game_collection_crop_image_assist,
|
||||
mEntrance
|
||||
)
|
||||
startActivityForResult(intent, REQUEST_CODE_IMAGE_CROP)
|
||||
val imagePath = data.getStringExtra(CropImageActivity.RESULT_CLIP_PATH) ?: ""
|
||||
mViewModel.imageUrl = ""
|
||||
mViewModel.imagePath = imagePath
|
||||
if (imagePath.isEmpty()) {
|
||||
mBinding.uploadPictureTv.text = "点击上传图片"
|
||||
} else {
|
||||
mBinding.uploadPictureTv.text = "图片上传中..."
|
||||
mViewModel.uploadPoster()
|
||||
}
|
||||
initPosterUI()
|
||||
} else if (requestCode == ChooseGameCollectionDefaultCoverDialog.REQUEST_CODE_DEFAULT_IMAGE) {
|
||||
val entity = data.getParcelableExtra<GameCollectionCoverEntity>(EntranceConsts.KEY_DATA)
|
||||
if (entity != null) {
|
||||
@ -731,9 +715,17 @@ class GameCollectionEditActivity : ToolBarActivity(), ChooseGamesAdapter.ItemDra
|
||||
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
|
||||
)
|
||||
} else {
|
||||
DialogHelper.showDialog(this, "温馨提示", "游戏单会在1-2个工作日内审核完成,您可以在“我的光环-我的游戏单”查看进度", "继续提交", "取消", {
|
||||
mViewModel.uploadContent(this, requestMap)
|
||||
}, extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true))
|
||||
DialogHelper.showDialog(
|
||||
this,
|
||||
"温馨提示",
|
||||
"游戏单会在1-2个工作日内审核完成,您可以在“我的光环-我的游戏单”查看进度",
|
||||
"继续提交",
|
||||
"取消",
|
||||
{
|
||||
mViewModel.uploadContent(this, requestMap)
|
||||
},
|
||||
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -804,7 +796,8 @@ class GameCollectionEditActivity : ToolBarActivity(), ChooseGamesAdapter.ItemDra
|
||||
activityDivider.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_divider.toColor(this@GameCollectionEditActivity))
|
||||
titleDivider.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_divider.toColor(this@GameCollectionEditActivity))
|
||||
introduceDivider.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_divider.toColor(this@GameCollectionEditActivity))
|
||||
placeholderView.background = com.gh.gamecenter.common.R.drawable.bg_shape_f5_radius_8.toDrawable(this@GameCollectionEditActivity)
|
||||
placeholderView.background =
|
||||
com.gh.gamecenter.common.R.drawable.bg_shape_f5_radius_8.toDrawable(this@GameCollectionEditActivity)
|
||||
selfOnlyCb.background =
|
||||
R.drawable.border_round_stroke_0dot5_eee_999.toDrawable(this@GameCollectionEditActivity)
|
||||
uploadPictureTv.setTextColor(com.gh.gamecenter.common.R.color.text_instance.toColor(this@GameCollectionEditActivity))
|
||||
@ -912,7 +905,6 @@ class GameCollectionEditActivity : ToolBarActivity(), ChooseGamesAdapter.ItemDra
|
||||
companion object {
|
||||
|
||||
const val REQUEST_CODE_IMAGE = 100
|
||||
const val REQUEST_CODE_IMAGE_CROP = 101
|
||||
const val REQUEST_CHOOSE_GAMES = 102
|
||||
const val REQUEST_CHOOSE_TAG = 103
|
||||
const val REQUEST_CHOOSE_ACTIVITY = 105
|
||||
|
||||
@ -596,7 +596,8 @@ class GameCollectionSquareAdapter(
|
||||
context,
|
||||
gamesCollectionEntity.id,
|
||||
isFromSquare = true,
|
||||
exposureSourceList = ArrayList(exposureSource)
|
||||
exposureSourceList = ArrayList(exposureSource),
|
||||
entrance = "游戏单广场"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@ -209,7 +209,7 @@ class GameCollectionSquareFragment : LazyListFragment<GamesCollectionEntity, Gam
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (data == null || resultCode != Activity.RESULT_OK) return
|
||||
if (data == null || resultCode != Activity.RESULT_OK || !::mViewModel.isInitialized) return
|
||||
if (requestCode == REQUEST_SELECT_TAG) {
|
||||
val tagInfoEntity = data.getParcelableExtra<TagInfoEntity>(GameCollectionTagSelectFragment.SELECTED_TAG)
|
||||
val tagCategory = data.getStringExtra(GameCollectionTagSelectFragment.SELECTED_TAG_CATEGORY)
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
package com.gh.gamecenter.gamedetail
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.halo.assistant.member.MemberUseCase
|
||||
|
||||
class AcceleratorZoneViewModel : ViewModel() {
|
||||
|
||||
val useCase = MemberUseCase()
|
||||
|
||||
override fun onCleared() {
|
||||
useCase.onClear()
|
||||
}
|
||||
}
|
||||
@ -58,20 +58,20 @@ import com.gh.gamecenter.common.mvvm.Status
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.common.view.WrapContentDraweeView
|
||||
import com.gh.gamecenter.core.iinterface.IScrollable
|
||||
import com.gh.gamecenter.core.provider.IAcceleratorProvider
|
||||
import com.gh.gamecenter.core.utils.*
|
||||
import com.gh.gamecenter.databinding.*
|
||||
import com.gh.gamecenter.entity.GameUpdateEntity
|
||||
import com.gh.gamecenter.entity.RecommendPopupEntity
|
||||
import com.gh.gamecenter.eventbus.*
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.PluginLocation
|
||||
import com.gh.gamecenter.feature.entity.SimpleGame
|
||||
import com.gh.gamecenter.feature.entity.TagStyleEntity
|
||||
import com.gh.gamecenter.feature.entity.*
|
||||
import com.gh.gamecenter.feature.eventbus.EBConcernChanged
|
||||
import com.gh.gamecenter.feature.eventbus.EBPayState
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.utils.ApkActiveUtils
|
||||
import com.gh.gamecenter.feature.utils.SentryHelper
|
||||
import com.gh.gamecenter.forum.detail.ForumDetailActivity
|
||||
import com.gh.gamecenter.gamedetail.accelerator.GameDetailAcceleratorUiHelper
|
||||
import com.gh.gamecenter.gamedetail.cloudarchive.CloudArchiveFragment
|
||||
import com.gh.gamecenter.gamedetail.desc.DescFragment
|
||||
import com.gh.gamecenter.gamedetail.dialog.*
|
||||
@ -86,7 +86,6 @@ import com.gh.gamecenter.home.video.ScrollCalculatorHelper
|
||||
import com.gh.gamecenter.login.user.UserViewModel
|
||||
import com.gh.gamecenter.newsdetail.NewsDetailActivity
|
||||
import com.gh.gamecenter.packagehelper.PackageViewModel
|
||||
import com.gh.gamecenter.SearchActivity
|
||||
import com.gh.gamecenter.simulatorgame.SimulatorGameActivity
|
||||
import com.gh.gamecenter.tag.TagsActivity
|
||||
import com.gh.gamecenter.video.detail.CustomManager
|
||||
@ -101,6 +100,7 @@ import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
|
||||
import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
|
||||
import com.shuyu.gsyvideoplayer.utils.OrientationUtils
|
||||
import com.shuyu.gsyvideoplayer.video.base.GSYVideoView
|
||||
import com.therouter.TheRouter
|
||||
import io.reactivex.disposables.Disposable
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
@ -155,6 +155,8 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
private val mLooperHandle = LooperHandle(this)
|
||||
private val mServerLooperKey = 123
|
||||
|
||||
private lateinit var acceleratorUiHelper: GameDetailAcceleratorUiHelper
|
||||
|
||||
private val dataWatcher = object : DataWatcher() {
|
||||
override fun onDataChanged(downloadEntity: DownloadEntity) {
|
||||
if (downloadEntity.gameId == mViewModel.gameId) {
|
||||
@ -265,7 +267,8 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
name = "游戏详情",
|
||||
title = mGameEntity!!.name ?: "",
|
||||
traceEvent = mTraceEvent,
|
||||
isSupportDualButton = true
|
||||
isSupportDualButton = true,
|
||||
acceleratorUiHelper
|
||||
)
|
||||
|
||||
private val contentCardClick: (contentCard: ContentCardEntity, position: Int) -> Unit =
|
||||
@ -412,6 +415,7 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
mVideoBinding = mBodyBinding.gameDetailVideo
|
||||
mDownloadBinding = mBinding.detailLlBottom
|
||||
mRecommendBinding = mBinding.gameDetailRecommendView
|
||||
acceleratorUiHelper = GameDetailAcceleratorUiHelper(mDownloadBinding)
|
||||
}.root
|
||||
}
|
||||
|
||||
@ -548,7 +552,12 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
pauseVideo()
|
||||
mIsPauseTopVideo = true
|
||||
}
|
||||
mBodyBinding.toolbar.setTitleTextColor(ContextCompat.getColor(requireContext(), com.gh.gamecenter.common.R.color.black))
|
||||
mBodyBinding.toolbar.setTitleTextColor(
|
||||
ContextCompat.getColor(
|
||||
requireContext(),
|
||||
com.gh.gamecenter.common.R.color.black
|
||||
)
|
||||
)
|
||||
} else if (mIsPauseTopVideo && absVerticalOffset == 0 && mVideoBinding.player.currentState == GSYVideoView.CURRENT_STATE_PAUSE) {
|
||||
resumeVideo()
|
||||
mIsPauseTopVideo = false
|
||||
@ -669,7 +678,9 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
}
|
||||
} else {
|
||||
setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(requireContext()))
|
||||
background = com.gh.gamecenter.feature.R.drawable.bg_advance_download_game_subtitle.toDrawable(requireContext())
|
||||
background = com.gh.gamecenter.feature.R.drawable.bg_advance_download_game_subtitle.toDrawable(
|
||||
requireContext()
|
||||
)
|
||||
}
|
||||
}
|
||||
tagView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
|
||||
@ -768,6 +779,8 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
if (gameResource.status == Status.SUCCESS) {
|
||||
mViewModel.logHistory(gameResource.data!!)
|
||||
mGameEntity = gameResource.data
|
||||
acceleratorUiHelper.setGame(gameResource.data)
|
||||
loadAccelerationData(mGameEntity!!)
|
||||
showBrowserInstallHintIfNeeded()
|
||||
controlInstallHint()
|
||||
// 添加启动弹窗的相关信息
|
||||
@ -787,7 +800,9 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
mViewModel.gameDetailLiveData.observeNonNull(this) { detailResource ->
|
||||
if (detailResource.status == Status.SUCCESS) {
|
||||
val data = detailResource.data ?: return@observeNonNull
|
||||
|
||||
if (detailResource.data?.acceleratorStatus == true) {
|
||||
acceleratorUiHelper.initSpeedUi(requireActivity())
|
||||
}
|
||||
DataLogUtils.uploadGameLog(context, mGameEntity!!.id, mGameEntity!!.name, mEntrance)
|
||||
|
||||
postDelayedRunnable({
|
||||
@ -839,7 +854,12 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
DetailDownloadUtils.updateViewHolder(viewHolder)
|
||||
|
||||
mDestinationTab =
|
||||
getTabPositionFromTabType(arguments?.getString(EntranceConsts.KEY_TARGET, EntranceConsts.TAB_TYPE_DESC) ?: EntranceConsts.TAB_TYPE_DESC)
|
||||
getTabPositionFromTabType(
|
||||
arguments?.getString(
|
||||
EntranceConsts.KEY_TARGET,
|
||||
EntranceConsts.TAB_TYPE_DESC
|
||||
) ?: EntranceConsts.TAB_TYPE_DESC
|
||||
)
|
||||
|
||||
// destinationTab 的优先级最高,关注和关联关注在它的后面
|
||||
if (mDestinationTab != -1) {
|
||||
@ -866,10 +886,11 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
|
||||
showConcernIconAtBottomBarIfAvailable()
|
||||
|
||||
val downloadEntitySnapshot = DownloadManager.getInstance().getDownloadEntitySnapshot(mGameEntity)
|
||||
val downloadEntitySnapshot = DownloadManager.getInstance().getDownloadEntitySnapshot(mGameEntity)
|
||||
|
||||
if (isSpecialDownloadDialogAvailable(downloadEntitySnapshot)
|
||||
&& downloadEntitySnapshot != null) {
|
||||
&& downloadEntitySnapshot != null
|
||||
) {
|
||||
updateSpecialDownloadDialogIcon(true)
|
||||
}
|
||||
|
||||
@ -993,6 +1014,32 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用此方法时,只是能获取game的包名,还无法确认该游戏是否支持加速
|
||||
* 所以这里只是提前加载加速所需的数据,并不需要初始化加速相关的UI
|
||||
*/
|
||||
private fun loadAccelerationData(game: GameEntity) {
|
||||
game.getApk().size
|
||||
if (game.getApk().size == 1) {
|
||||
// 单版本游戏才能支持加速(后台未对此作限制,所以需要在客户端判断)
|
||||
val pkgName = game.getUniquePackageName() ?: ""
|
||||
mViewModel.getLastSpeedLiveData(pkgName).observe(viewLifecycleOwner) {
|
||||
acceleratorUiHelper.setCurrentAcctGameInfo(it)
|
||||
}
|
||||
|
||||
mViewModel.getZoneListLiveData(pkgName).observe(viewLifecycleOwner) {
|
||||
acceleratorUiHelper.setZoneList(it)
|
||||
}
|
||||
|
||||
mViewModel.upsertAcctZoneListBeanAction.observe(viewLifecycleOwner) { (pkgName, zoneList) ->
|
||||
mViewModel.upsertAcctZoneListBean(pkgName, zoneList)
|
||||
}
|
||||
|
||||
mViewModel.loadAccelerationData(pkgName)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private fun initViewPage(data: NewGameDetailEntity) {
|
||||
// 各个 tab 显示的顺序为:详情>云存档>评价>专区>论坛
|
||||
@ -1031,7 +1078,8 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
mTabTitleList.clear()
|
||||
|
||||
val tag = "android:switcher:${mBodyBinding.gamedetailVp.id}:"
|
||||
val descFragment = childFragmentManager.findFragmentByTag("${tag}${EntranceConsts.TAB_TYPE_DESC}") ?: DescFragment()
|
||||
val descFragment =
|
||||
childFragmentManager.findFragmentByTag("${tag}${EntranceConsts.TAB_TYPE_DESC}") ?: DescFragment()
|
||||
descFragment.arguments = bundle
|
||||
mFragmentsList.add(descFragment)
|
||||
mTabTitleList.add(getString(R.string.game_detail_desc))
|
||||
@ -1039,7 +1087,8 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
|
||||
if (data.showArchive) {
|
||||
val cloudArchiveFragment =
|
||||
childFragmentManager.findFragmentByTag("${tag}${EntranceConsts.TAB_TYPE_ARCHIVE}") ?: CloudArchiveFragment()
|
||||
childFragmentManager.findFragmentByTag("${tag}${EntranceConsts.TAB_TYPE_ARCHIVE}")
|
||||
?: CloudArchiveFragment()
|
||||
bundle.putParcelable(EntranceConsts.KEY_GAME, mGameEntity ?: GameEntity())
|
||||
bundle.putString(EntranceConsts.KEY_ARCHIVE_CONFIG_URL, data.archiveTab.configUrl)
|
||||
cloudArchiveFragment.arguments = bundle
|
||||
@ -1055,7 +1104,8 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
}
|
||||
|
||||
if (data.showComment) {
|
||||
val ratingFragment = childFragmentManager.findFragmentByTag("${tag}${EntranceConsts.TAB_TYPE_RATING}") ?: RatingFragment()
|
||||
val ratingFragment =
|
||||
childFragmentManager.findFragmentByTag("${tag}${EntranceConsts.TAB_TYPE_RATING}") ?: RatingFragment()
|
||||
bundle.putBoolean(EntranceConsts.KEY_COMMENT_AS_DEFAULT_TAB, mSkipGameComment)
|
||||
bundle.putBoolean(EntranceConsts.KEY_DIRECT_COMMENT, data.directComment)
|
||||
ratingFragment.arguments = bundle
|
||||
@ -1072,7 +1122,8 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
mFragmentsList.add(Fragment())
|
||||
} else if (it.style == "link") {
|
||||
//显示web页面
|
||||
val webFragment = childFragmentManager.findFragmentByTag("${tag}${EntranceConsts.TAB_TYPE_TRENDS}") ?: WebFragment()
|
||||
val webFragment =
|
||||
childFragmentManager.findFragmentByTag("${tag}${EntranceConsts.TAB_TYPE_TRENDS}") ?: WebFragment()
|
||||
val webBundle = Bundle()
|
||||
webBundle.putString(EntranceConsts.KEY_ENTRANCE, "游戏专区")
|
||||
webBundle.putString(EntranceConsts.KEY_URL, it.link)
|
||||
@ -1080,7 +1131,8 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
webFragment.arguments = webBundle
|
||||
mFragmentsList.add(webFragment)
|
||||
} else {
|
||||
val fuliFragment = childFragmentManager.findFragmentByTag("${tag}${EntranceConsts.TAB_TYPE_TRENDS}") ?: FuLiFragment()
|
||||
val fuliFragment =
|
||||
childFragmentManager.findFragmentByTag("${tag}${EntranceConsts.TAB_TYPE_TRENDS}") ?: FuLiFragment()
|
||||
fuliFragment.arguments = bundle
|
||||
mFragmentsList.add(fuliFragment)
|
||||
}
|
||||
@ -1180,7 +1232,8 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
}
|
||||
|
||||
private fun doShowAlertDialog(dialog: GameEntity.Dialog) {
|
||||
SensorsBridge.trackEvent("GameDetailDialogShow",
|
||||
SensorsBridge.trackEvent(
|
||||
"GameDetailDialogShow",
|
||||
"game_id", mGameEntity?.id ?: "",
|
||||
"game_name", mGameEntity?.name ?: "",
|
||||
"game_type", mGameEntity?.categoryChinese ?: ""
|
||||
@ -1192,7 +1245,8 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
dialog.confirmButton.text.toString(),
|
||||
dialog.closeButtonText,
|
||||
{
|
||||
SensorsBridge.trackEvent("GameDetailDialogClick",
|
||||
SensorsBridge.trackEvent(
|
||||
"GameDetailDialogClick",
|
||||
"game_id", mGameEntity?.id ?: "",
|
||||
"game_name", mGameEntity?.name ?: "",
|
||||
"game_type", mGameEntity?.categoryChinese ?: "",
|
||||
@ -1205,7 +1259,8 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
DirectUtils.directToLinkPage(requireContext(), dialog.confirmButton, mEntrance, "")
|
||||
},
|
||||
{
|
||||
SensorsBridge.trackEvent("GameDetailDialogClick",
|
||||
SensorsBridge.trackEvent(
|
||||
"GameDetailDialogClick",
|
||||
"game_id", mGameEntity?.id ?: "",
|
||||
"game_name", mGameEntity?.name ?: "",
|
||||
"game_type", mGameEntity?.categoryChinese ?: "",
|
||||
@ -1213,7 +1268,8 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
)
|
||||
},
|
||||
{
|
||||
SensorsBridge.trackEvent("GameDetailDialogClick",
|
||||
SensorsBridge.trackEvent(
|
||||
"GameDetailDialogClick",
|
||||
"game_id", mGameEntity?.id ?: "",
|
||||
"game_name", mGameEntity?.name ?: "",
|
||||
"game_type", mGameEntity?.categoryChinese ?: "",
|
||||
@ -1385,7 +1441,12 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
mNewGameDetailEntity?.event?.let {
|
||||
mBodyBinding.gameBigEvent.visibility = View.VISIBLE
|
||||
if (it.highLight) {
|
||||
mBodyBinding.gameBigEvent.setTextColor(ContextCompat.getColor(requireContext(), com.gh.gamecenter.common.R.color.text_2A85FB))
|
||||
mBodyBinding.gameBigEvent.setTextColor(
|
||||
ContextCompat.getColor(
|
||||
requireContext(),
|
||||
com.gh.gamecenter.common.R.color.text_2A85FB
|
||||
)
|
||||
)
|
||||
mBodyBinding.gameBigEvent.background =
|
||||
ContextCompat.getDrawable(requireContext(), R.drawable.bg_game_big_event_light)
|
||||
mBodyBinding.gameBigEvent.setCompoundDrawablesWithIntrinsicBounds(
|
||||
@ -1852,22 +1913,12 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
requireContext(),
|
||||
mGameEntity,
|
||||
callback = getCallback(),
|
||||
|
||||
)
|
||||
)
|
||||
} else {
|
||||
if ("download" == mGameEntity?.reserveStatus) {
|
||||
ReservationHelper.showDeleteReservationDialog(requireContext()) {
|
||||
ReservationHelper.deleteReservation(mGameEntity!!) {
|
||||
DetailDownloadUtils.updateViewHolder(detailViewHolder)
|
||||
showReserveBtn(isShowReserveBtn())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ReservationHelper.showCancelReservationDialog(requireContext(), mGameEntity) {
|
||||
ReservationHelper.cancelReservation(mGameEntity!!) {
|
||||
DetailDownloadUtils.updateViewHolder(detailViewHolder)
|
||||
showReserveBtn(isShowReserveBtn())
|
||||
}
|
||||
ReservationHelper.showCancelReservationDialog(requireContext(), mGameEntity) {
|
||||
ReservationHelper.cancelReservation(mGameEntity!!) {
|
||||
DetailDownloadUtils.updateViewHolder(detailViewHolder)
|
||||
showReserveBtn(isShowReserveBtn())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2222,7 +2273,8 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
pluginLocation = PluginLocation.only_game
|
||||
)
|
||||
val isLaunch = (status == getString(com.gh.gamecenter.feature.R.string.launch) || status == getString(
|
||||
com.gh.gamecenter.feature.R.string.open))
|
||||
com.gh.gamecenter.feature.R.string.open
|
||||
))
|
||||
if (SPUtils.getBoolean(
|
||||
Constants.SP_SHOULD_SHOW_GAME_DETAIL_INSTALL_GUIDE,
|
||||
false
|
||||
@ -2382,6 +2434,9 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
}
|
||||
|
||||
override fun onBackPressed(): Boolean {
|
||||
if (acceleratorUiHelper.onBack()) {
|
||||
return true
|
||||
}
|
||||
mOrientationUtils?.backToProtVideo()
|
||||
|
||||
val trendsTabPosition = getTabPositionFromTabType(EntranceConsts.TAB_TYPE_TRENDS)
|
||||
@ -2442,6 +2497,11 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
NewFlatLogUtils.logGameDetailExit(mGameEntity?.name ?: "", mGameEntity?.id ?: "")
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
acceleratorUiHelper.clear()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
releaseVideo()
|
||||
@ -2535,9 +2595,21 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
// 更新分割线样式
|
||||
updateDivider()
|
||||
|
||||
mBodyBinding.collapsingToolbar.setContentScrimColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext()))
|
||||
mBodyBinding.gamedetailAppbar.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext()))
|
||||
mBodyBinding.toolbarGapView.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_background.toColor(requireContext()))
|
||||
mBodyBinding.collapsingToolbar.setContentScrimColor(
|
||||
com.gh.gamecenter.common.R.color.ui_surface.toColor(
|
||||
requireContext()
|
||||
)
|
||||
)
|
||||
mBodyBinding.gamedetailAppbar.setBackgroundColor(
|
||||
com.gh.gamecenter.common.R.color.ui_surface.toColor(
|
||||
requireContext()
|
||||
)
|
||||
)
|
||||
mBodyBinding.toolbarGapView.setBackgroundColor(
|
||||
com.gh.gamecenter.common.R.color.ui_background.toColor(
|
||||
requireContext()
|
||||
)
|
||||
)
|
||||
mBodyBinding.gamedetailTvName.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext()))
|
||||
mBodyBinding.gameBigEvent.background = R.drawable.bg_game_big_event.toDrawable(requireContext())
|
||||
mBodyBinding.gameBigEvent.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(requireContext()))
|
||||
@ -2549,7 +2621,11 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
}
|
||||
}
|
||||
if (it is ImageView) {
|
||||
if (mIsDarkModeOn) it.setColorFilter(com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext())) else it.colorFilter =
|
||||
if (mIsDarkModeOn) it.setColorFilter(
|
||||
com.gh.gamecenter.common.R.color.text_primary.toColor(
|
||||
requireContext()
|
||||
)
|
||||
) else it.colorFilter =
|
||||
null
|
||||
it.background = (it.background as GradientDrawable).apply {
|
||||
setStroke(0.5F.dip2px(), Color.parseColor(if (mIsDarkModeOn) "#33FFFFFF" else "#CCCCCC"))
|
||||
@ -2561,7 +2637,11 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
val textView = tab.customView?.findViewById(R.id.tab_title) as? TextView ?: break
|
||||
TextViewCompat.setTextAppearance(textView, com.gh.gamecenter.common.R.style.TabLayoutTextAppearance)
|
||||
}
|
||||
mBinding.detailLlBottom.detailLlBottom.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_background.toColor(requireContext()))
|
||||
mBinding.detailLlBottom.detailLlBottom.setBackgroundColor(
|
||||
com.gh.gamecenter.common.R.color.ui_background.toColor(
|
||||
requireContext()
|
||||
)
|
||||
)
|
||||
updateToolbarStyle(!mViewModel.displayTopVideo || mBodyBinding.gamedetailThumbSmall.visibility == View.VISIBLE)
|
||||
mViewModel.gameDetailLiveData.value?.data?.let {
|
||||
if (it.isShowContentCard(mGameEntity)) {
|
||||
@ -2594,6 +2674,7 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
* 3. 当前游戏 APK 不为 1 个
|
||||
* 4. 当前游戏类型不为畅玩
|
||||
* 5. 当前游戏不是双下载时使用本地下载进行下载
|
||||
* 6. 当前游戏配置了网络加速
|
||||
*/
|
||||
private fun isSpecialDownloadDialogAvailable(downloadEntity: DownloadEntity? = null): Boolean {
|
||||
if (Config.getNewApiSettingsEntity()?.install?.questionTip?.linkEntity == null) return false
|
||||
@ -2602,6 +2683,7 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
if (downloadEntity?.asVGame() == true) return false
|
||||
if (downloadEntity?.isSimulatorGame() == true) return false
|
||||
if (downloadEntity?.isLocalDownloadInDualDownloadMode() == true) return false
|
||||
if (mGameEntity?.canSpeed == true) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@ -5,14 +5,10 @@ import android.app.Application
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.text.TextUtils
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.*
|
||||
import com.gh.common.filter.RegionSettingHelper
|
||||
import com.gh.common.history.HistoryHelper
|
||||
import com.gh.common.util.CheckLoginUtils
|
||||
import com.gh.gamecenter.feature.utils.ConcernUtils
|
||||
import com.gh.common.util.LibaoUtils
|
||||
import com.gh.common.util.PackageHelper
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
@ -20,28 +16,53 @@ import com.gh.gamecenter.common.mvvm.Resource
|
||||
import com.gh.gamecenter.common.retrofit.BiResponse
|
||||
import com.gh.gamecenter.common.retrofit.Response
|
||||
import com.gh.gamecenter.common.utils.singleToMain
|
||||
import com.gh.gamecenter.common.utils.toArrayList
|
||||
import com.gh.gamecenter.common.utils.toRequestBody
|
||||
import com.gh.gamecenter.core.provider.IAcceleratorProvider
|
||||
import com.gh.gamecenter.core.utils.GsonUtils
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.core.utils.UrlFilterUtils
|
||||
import com.gh.gamecenter.entity.*
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.LibaoEntity
|
||||
import com.gh.gamecenter.feature.entity.LibaoStatusEntity
|
||||
import com.gh.gamecenter.feature.entity.SimpleGame
|
||||
import com.gh.gamecenter.entity.RecommendPopupEntity
|
||||
import com.gh.gamecenter.entity.UnifiedUserTrendEntity
|
||||
import com.gh.gamecenter.feature.entity.*
|
||||
import com.gh.gamecenter.feature.utils.ApkActiveUtils
|
||||
import com.gh.gamecenter.feature.utils.ConcernUtils
|
||||
import com.gh.gamecenter.feature.utils.ContentBlockedHelper
|
||||
import com.gh.gamecenter.gamedetail.entity.*
|
||||
import com.gh.gamecenter.gamedetail.accelerator.AccelerationDataBase
|
||||
import com.gh.gamecenter.gamedetail.entity.BigEvent
|
||||
import com.gh.gamecenter.gamedetail.entity.CustomColumn
|
||||
import com.gh.gamecenter.gamedetail.entity.DetailEntity
|
||||
import com.gh.gamecenter.gamedetail.entity.NewGameDetailEntity
|
||||
import com.gh.gamecenter.login.user.UserManager
|
||||
import com.gh.gamecenter.login.user.UserRepository
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.halo.assistant.member.MemberUseCase
|
||||
import com.therouter.TheRouter
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.ResponseBody
|
||||
import org.json.JSONObject
|
||||
import retrofit2.HttpException
|
||||
import tv.danmaku.ijk.media.exo2.ExoSourceManager
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.collections.List
|
||||
import kotlin.collections.arrayListOf
|
||||
import kotlin.collections.find
|
||||
import kotlin.collections.firstOrNull
|
||||
import kotlin.collections.forEach
|
||||
import kotlin.collections.forEachIndexed
|
||||
import kotlin.collections.hashMapOf
|
||||
import kotlin.collections.isNotEmpty
|
||||
import kotlin.collections.isNullOrEmpty
|
||||
import kotlin.collections.removeAll
|
||||
import kotlin.collections.set
|
||||
import kotlin.collections.sortByDescending
|
||||
import kotlin.collections.withIndex
|
||||
|
||||
class GameDetailViewModel(
|
||||
application: Application,
|
||||
@ -69,6 +90,10 @@ class GameDetailViewModel(
|
||||
var videoIsMuted = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
|
||||
var displayTopVideo: Boolean = false
|
||||
|
||||
private val compositeDisposable = CompositeDisposable()
|
||||
|
||||
val memberUseCase = MemberUseCase()
|
||||
|
||||
init {
|
||||
loadData()
|
||||
}
|
||||
@ -85,9 +110,17 @@ class GameDetailViewModel(
|
||||
getGameDetailNew()
|
||||
getRecommendPopup(game?.id ?: "")
|
||||
}
|
||||
|
||||
gameId != null -> getGameDigest()
|
||||
else -> gameLiveData.postValue(null)
|
||||
}
|
||||
|
||||
val userId = UserManager.getInstance().userId
|
||||
if (userId.isNotBlank()) {
|
||||
// 如果是登录状态,获取最新的vip状态
|
||||
UserRepository.getInstance().refreshVipStatus(userId, false)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 获取游戏摘要
|
||||
@ -162,6 +195,11 @@ class GameDetailViewModel(
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BiResponse<NewGameDetailEntity>() {
|
||||
override fun onSuccess(data: NewGameDetailEntity) {
|
||||
game?.acceleratorStatus = data.acceleratorStatus
|
||||
if (game?.canSpeed == true) {
|
||||
// 此游戏支持加速
|
||||
pkgName.value = game?.getUniquePackageName() ?: ""
|
||||
}
|
||||
if (data.newNotice != null) {
|
||||
// 存在new_notice字段时移除detail_tab里面type=notice的项并添加new_notice到detail_tab
|
||||
var noticePosition = -1
|
||||
@ -659,6 +697,66 @@ class GameDetailViewModel(
|
||||
})
|
||||
}
|
||||
|
||||
fun getLastSpeedLiveData(pkgName: String) =
|
||||
AccelerationDataBase.instance.accelerationDao().findByPackageName(pkgName)
|
||||
|
||||
fun getZoneListLiveData(pkgName: String) =
|
||||
AccelerationDataBase.instance.accelerationDao().findZoneListBeanByPkgName(pkgName)
|
||||
.map {
|
||||
it?.acctGameList?.toArrayList()
|
||||
}
|
||||
|
||||
private val zoneList = MutableLiveData<List<AcctGameInfo>>()
|
||||
private val pkgName = MutableLiveData<String>()
|
||||
|
||||
val upsertAcctZoneListBeanAction = MediatorLiveData<Pair<String, List<AcctGameInfo>>>().apply {
|
||||
addSource(zoneList) {
|
||||
val pkgNameValue = pkgName.value
|
||||
if (!pkgNameValue.isNullOrBlank()) {
|
||||
value = pkgNameValue to it
|
||||
}
|
||||
}
|
||||
|
||||
addSource(pkgName) {
|
||||
val zoneListValue = zoneList.value
|
||||
if (zoneListValue != null) {
|
||||
value = it to zoneListValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun loadAccelerationData(pkgName: String) {
|
||||
Single.create<ArrayList<AcctGameInfo>> { emitter ->
|
||||
val iAcceleratorProvider = TheRouter.get(IAcceleratorProvider::class.java)
|
||||
iAcceleratorProvider?.loadQyGameZoneData(pkgName) {
|
||||
val zoneData = (it as List<AcctGameInfo>).toArrayList()
|
||||
emitter.onSuccess(zoneData)
|
||||
} ?: emitter.onSuccess(arrayListOf())
|
||||
}.timeout(5, TimeUnit.SECONDS)
|
||||
.doOnSuccess {
|
||||
zoneList.value = it
|
||||
}
|
||||
.subscribe({}, {}).let(compositeDisposable::add)
|
||||
}
|
||||
|
||||
/**
|
||||
* 只有能够加速的游戏需要保存区服信息
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
fun upsertAcctZoneListBean(pkgName: String, zoneList: List<AcctGameInfo>) {
|
||||
AccelerationDataBase.instance.accelerationDao()
|
||||
.upsertAcctZoneListBean(AcctZoneListBean(pkgName, zoneList))
|
||||
.compose(singleToMain())
|
||||
.subscribe({}, {})
|
||||
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
compositeDisposable.clear()
|
||||
memberUseCase.onClear()
|
||||
}
|
||||
|
||||
class Factory(
|
||||
private val mApplication: Application,
|
||||
private val gameId: String?,
|
||||
|
||||
@ -0,0 +1,76 @@
|
||||
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.core.provider.IAcceleratorProvider
|
||||
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.member.MemberUseCase
|
||||
import com.therouter.TheRouter
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
|
||||
class StartingAcceleratorViewModel : ViewModel() {
|
||||
|
||||
private val compositeDisposable = CompositeDisposable()
|
||||
|
||||
val useCase = MemberUseCase()
|
||||
|
||||
private val _restartingAcceleratorAction = MutableLiveData<Event<Boolean>>()
|
||||
val restartingAcceleratorAction: LiveData<Event<Boolean>> = _restartingAcceleratorAction
|
||||
fun loadAcceleratorToken() {
|
||||
val userId = UserManager.getInstance().userId
|
||||
if (userId.isNotBlank()) {
|
||||
UserRepository.getInstance().setAcceleratorToken(userId) {
|
||||
_restartingAcceleratorAction.value = Event(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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状态
|
||||
// 这里先刷新内存数据,再去刷新api数据
|
||||
TheRouter.get(IAcceleratorProvider::class.java)?.setVipEntity(
|
||||
VipEntity(
|
||||
_vipStatus = true,
|
||||
_isNewUser = false,
|
||||
_isTryVip = true
|
||||
)
|
||||
)
|
||||
refreshVipStatus(userId)
|
||||
_rechargeTrailResult.value = Event(true)
|
||||
} else {
|
||||
_rechargeTrailResult.value = Event(false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(exception: Exception) {
|
||||
super.onFailure(exception)
|
||||
_rechargeTrailResult.value = Event(false)
|
||||
}
|
||||
}).let(compositeDisposable::add)
|
||||
}
|
||||
|
||||
private fun refreshVipStatus(userId: String) {
|
||||
UserRepository.getInstance().refreshVipStatus(userId, true)
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
compositeDisposable.clear()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
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 com.gh.gamecenter.feature.entity.AcctGameInfo
|
||||
import com.gh.gamecenter.feature.entity.AcctZoneListBean
|
||||
import com.gh.gamecenter.room.converter.AcctGameInfoConverter
|
||||
import com.halo.assistant.HaloApp
|
||||
|
||||
@Database(
|
||||
entities = [AcctGameInfo::class, AcctZoneListBean::class],
|
||||
version = 1,
|
||||
exportSchema = false
|
||||
)
|
||||
@TypeConverters(
|
||||
AcctGameInfoConverter::class
|
||||
)
|
||||
abstract class AccelerationDataBase : RoomDatabase() {
|
||||
|
||||
abstract fun accelerationDao(): AcceleratorDao
|
||||
|
||||
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)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package com.gh.gamecenter.gamedetail.accelerator
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
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.AcctZoneListBean
|
||||
import io.reactivex.Single
|
||||
|
||||
@Dao
|
||||
interface AcceleratorDao {
|
||||
|
||||
@Upsert
|
||||
fun upsertAcctGameInfo(gameInfo: AcctGameInfo): Single<Long>
|
||||
|
||||
@Query("SELECT * FROM AcctGameInfo WHERE accGamePkgName = :pkgName")
|
||||
fun findByPackageName(pkgName: String): LiveData<AcctGameInfo?>
|
||||
|
||||
@Upsert
|
||||
fun upsertAcctZoneListBean(acctZoneListBean: AcctZoneListBean): Single<Long>
|
||||
|
||||
@Query("SELECT * FROM AcctZoneListBean WHERE pkgName = :pkgName")
|
||||
fun findZoneListBeanByPkgName(pkgName: String): LiveData<AcctZoneListBean?>
|
||||
}
|
||||
@ -0,0 +1,182 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,401 @@
|
||||
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.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.databinding.DetailDownloadItemBinding
|
||||
import com.gh.gamecenter.feature.entity.AcctGameInfo
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.gamedetail.accelerator.chain.*
|
||||
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.member.MemberRepository
|
||||
import com.therouter.TheRouter
|
||||
|
||||
class GameDetailAcceleratorUiHelper(private val binding: DetailDownloadItemBinding) {
|
||||
|
||||
private var iAcceleratorProvider = TheRouter.get(IAcceleratorProvider::class.java)
|
||||
|
||||
private var guideView: AcceleratorGuideView? = null
|
||||
|
||||
val isGuideLayerShowing: Boolean
|
||||
get() = guideView?.isShowing ?: false
|
||||
|
||||
private val zoneList = arrayListOf<AcctGameInfo>()
|
||||
private var hasZoneListLoaded = false
|
||||
|
||||
private var _last: AcctGameInfo? = null
|
||||
val last: AcctGameInfo?
|
||||
get() = _last
|
||||
|
||||
private val hasMultiZone: Boolean
|
||||
get() = zoneList.size > 1
|
||||
|
||||
private val hasZone: Boolean
|
||||
get() = zoneList.isNotEmpty()
|
||||
|
||||
private val isVip: Boolean
|
||||
get() = iAcceleratorProvider?.isVip() ?: false
|
||||
|
||||
val isNewUser: Boolean
|
||||
get() = iAcceleratorProvider?.isNewUser() ?: false
|
||||
|
||||
private var canSpeed = false
|
||||
|
||||
var showSpeedUi = false
|
||||
|
||||
private var _game: GameEntity? = null
|
||||
fun setGame(game: GameEntity?) {
|
||||
_game = game
|
||||
}
|
||||
|
||||
private val accelerationListener = object : OnAccelerateListener {
|
||||
override fun onStateChanged(state: AccelerateState) {
|
||||
when (state) {
|
||||
is AccelerateState.Success -> {
|
||||
_game?.let {
|
||||
val acctGameInfo = state.acctGameInfo
|
||||
if (acctGameInfo is AcctGameInfo) {
|
||||
setCurrentAcctGameInfo(acctGameInfo)
|
||||
}
|
||||
updateSpeedUi()
|
||||
}
|
||||
}
|
||||
|
||||
is AccelerateState.Normal -> {
|
||||
if (!state.isTokenExpired) {
|
||||
updateSpeedUi()
|
||||
}
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
override fun onProgress(progress: Int, curGamePkgName: String?, curGameZoneFlag: String?) = Unit
|
||||
|
||||
override fun onVipStatusChanged(isNewUser: Boolean, isVip: Boolean) {
|
||||
binding.ivFreeVipTag.visibleIf(
|
||||
showSpeedUi &&
|
||||
CheckLoginUtils.isLogin() &&
|
||||
isNewUser &&
|
||||
!isGuideLayerShowing
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun initSpeedUi(context: Context) {
|
||||
canSpeed = true
|
||||
|
||||
_game?.let {
|
||||
iAcceleratorProvider?.bindAccRelatedListener(it.getUniquePackageName() ?: "", accelerationListener)
|
||||
}
|
||||
|
||||
binding.vSpeedContent.setOnClickListener {
|
||||
_game?.let { game ->
|
||||
checkDataReady {
|
||||
startAccelerating(context, game, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
binding.vMoreZone.setOnClickListener {
|
||||
_game?.let { game ->
|
||||
checkDataReady {
|
||||
showZoneList(context, game)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
binding.tvStopSpeed.setOnClickListener {
|
||||
_game?.let {
|
||||
SensorsBridge.trackNetworkAccelerationOtherButtonClick(
|
||||
it.getUniquePackageName() ?: "",
|
||||
it.id,
|
||||
it.name ?: "",
|
||||
iAcceleratorProvider?.getMemberType() ?: "",
|
||||
BUTTON_NAME_STOP_ACCELERATOR,
|
||||
SOURCE_ENTRANCE_GAME_DETAIL
|
||||
)
|
||||
|
||||
AcceleratorDialogFragment.show(
|
||||
SPEED_STOP, it.getUniquePackageName() ?: "", it.id, it.name ?: "",
|
||||
SOURCE_ENTRANCE_GAME_DETAIL, context
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
binding.tvEnterGame.setOnClickListener {
|
||||
_game?.let { game ->
|
||||
SensorsBridge.trackNetworkAccelerationOtherButtonClick(
|
||||
game.getUniquePackageName() ?: "",
|
||||
game.id,
|
||||
game.name ?: "",
|
||||
iAcceleratorProvider?.getMemberType() ?: "",
|
||||
BUTTON_NAME_ENTER_GAME,
|
||||
SOURCE_ENTRANCE_GAME_DETAIL
|
||||
)
|
||||
PackageLauncher.launchApp(context, game, game.getUniquePackageName())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateSpeedUi()
|
||||
}
|
||||
|
||||
fun updateSpeedUi() {
|
||||
if (!showSpeedUi) {
|
||||
return
|
||||
}
|
||||
val hasGameBeingAccelerated = iAcceleratorProvider?.isCurAccSuccess() ?: false
|
||||
val isCurAccSuccess = hasGameBeingAccelerated &&
|
||||
MemberRepository.instance.acctGameRecord.gameId == (_game?.id ?: "")
|
||||
binding.detailProgressbar.goneIf(isCurAccSuccess)
|
||||
binding.clSpeed.goneIf(isCurAccSuccess)
|
||||
binding.gAccelerating.goneIf(!isCurAccSuccess)
|
||||
binding.gMoreZone.goneIf(!hasMultiZone)
|
||||
binding.ivFreeVipTag.visibleIf(
|
||||
showSpeedUi &&
|
||||
CheckLoginUtils.isLogin() &&
|
||||
isNewUser &&
|
||||
!isGuideLayerShowing
|
||||
)
|
||||
binding.tvSpeed.text = if (hasMultiZone) {
|
||||
last?.zoneName
|
||||
} else {
|
||||
null
|
||||
} ?: R.string.network_acceleration.toResString()
|
||||
}
|
||||
|
||||
/**
|
||||
* 在这个方法里确定是否需要展示 加速ui
|
||||
* 当 clSpeedContainer没有显示时,调用updateSpeedUi()无效,可以调用initSpeedUi()
|
||||
* 请注意,只要是 gameDetail 发生变化,这里就会回调,所以当 canSpeed 确定之后,这里最少还会回调一次
|
||||
*/
|
||||
fun checkIfShowGuideLayer(context: Context) {
|
||||
showSpeedUi = canSpeed
|
||||
binding.clSpeedContainer.goneIf(!showSpeedUi) {
|
||||
// canSpeed =true 说明detail接口已完成
|
||||
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))
|
||||
updateSpeedUi()
|
||||
if (CheckLoginUtils.isLogin()) {
|
||||
if (!hasShow()) {
|
||||
// 优先显示弹窗
|
||||
binding.ivFreeVipTag.visibleIf(false)
|
||||
showGuideLayer(context)
|
||||
}
|
||||
} else {
|
||||
// 未登录
|
||||
binding.ivFreeVipTag.visibleIf(false)
|
||||
showGuideLayer(context)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun showGuideLayer(context: Context) {
|
||||
if (!hasShow()) {
|
||||
binding.root.post {
|
||||
val uiListener = object : OnAcceleratorListener {
|
||||
override fun onStartAccelerator() {
|
||||
_game?.let {
|
||||
startAccelerating(context, it, true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onGuideLayerDismiss() {
|
||||
binding.ivFreeVipTag.visibleIf(CheckLoginUtils.isLogin() && hasZone && isNewUser)
|
||||
}
|
||||
|
||||
}
|
||||
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) {
|
||||
_game?.let {
|
||||
SensorsBridge.trackNetworkAccelerationGuidanceDiagramShow(
|
||||
it.getUniquePackageName() ?: "",
|
||||
it.id,
|
||||
it.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 hasShow(): Boolean {
|
||||
return SPUtils.getBoolean(Constants.SP_HAS_SHOW_ACCELERATION_GUIDE_LAYER)
|
||||
}
|
||||
|
||||
private fun startAccelerating(context: Context, game: GameEntity, isShowing: Boolean) {
|
||||
if (isInvalidClick() || !hasZone) {
|
||||
return
|
||||
}
|
||||
val lastAcctGameInfo = last
|
||||
|
||||
val memberType = if (CheckLoginUtils.isLogin()) {
|
||||
iAcceleratorProvider?.getMemberType() ?: ""
|
||||
} else {
|
||||
MEMBER_TYPE_NOT_LOGIN
|
||||
}
|
||||
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)
|
||||
|
||||
hasMultiZone -> AcceleratorZoneDialogFragment.show(context, zoneList, game)
|
||||
else -> {
|
||||
val gameInfo = zoneList.firstOrNull() ?: AcctGameInfo("", AcctGameInfo.ZoneInfo(0))
|
||||
doStartAccelerating(context, game, gameInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showZoneList(context: Context, game: GameEntity) {
|
||||
if (isInvalidClick() || !hasZone) {
|
||||
return
|
||||
}
|
||||
AcceleratorZoneDialogFragment.show(context, zoneList, game)
|
||||
|
||||
}
|
||||
|
||||
private var clickTime = 0L
|
||||
|
||||
private fun doStartAccelerating(context: Context, game: GameEntity, acctGameInfo: AcctGameInfo) {
|
||||
|
||||
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, acctGameInfo, game, true, hasMultiZone,
|
||||
SOURCE_ENTRANCE_GAME_DETAIL,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun setCurrentAcctGameInfo(acctGameInfo: AcctGameInfo?) {
|
||||
_last = acctGameInfo
|
||||
if (hasZoneListLoaded) {
|
||||
updateSpeedUi()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 第一次调用 setZoneList 是使用缓存中的数据
|
||||
* 第二次调用,是使用sdk中的最新数据
|
||||
* 这里优先使用缓存中的,sdk中的数据更新到数据库后,待下次进入详情页在显示
|
||||
* 当zoneList为null时,说明磁盘上没有数据,这时候使用sdk中的
|
||||
*
|
||||
*/
|
||||
fun setZoneList(newZoneList: ArrayList<AcctGameInfo>?) {
|
||||
if (newZoneList != null && zoneList.isEmpty()) {
|
||||
hasZoneListLoaded = true
|
||||
zoneList.clear()
|
||||
zoneList.addAll(newZoneList)
|
||||
updateSpeedUi()
|
||||
}
|
||||
}
|
||||
|
||||
private fun isInvalidClick(): Boolean {
|
||||
// 300ms内只能调用一次
|
||||
val currentTime = System.currentTimeMillis()
|
||||
val difTime = currentTime - clickTime
|
||||
if (difTime <= CLICK_DURATION) {
|
||||
return true
|
||||
}
|
||||
clickTime = currentTime
|
||||
return false
|
||||
}
|
||||
|
||||
private fun checkDataReady(block: () -> Unit) {
|
||||
when {
|
||||
!hasZoneListLoaded -> {
|
||||
ToastUtils.showToast("区服信息正在加载中,请稍后再试!")
|
||||
}
|
||||
|
||||
zoneList.isEmpty() -> {
|
||||
ToastUtils.showToast("区服信息加载失败,请稍后再试!")
|
||||
}
|
||||
|
||||
else -> {
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
iAcceleratorProvider?.unBindAccRelatedListener(accelerationListener)
|
||||
guideView?.dismiss()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val CLICK_DURATION = 300
|
||||
const val MEMBER_TYPE_NOT_LOGIN = "未登录"
|
||||
|
||||
private 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 BUTTON_NAME_ENTER_GAME = "进入游戏"
|
||||
const val BUTTON_NAME_STOP_ACCELERATOR = "停止加速"
|
||||
|
||||
}
|
||||
|
||||
interface OnAcceleratorListener {
|
||||
|
||||
fun onStartAccelerator()
|
||||
|
||||
fun onGuideLayerDismiss()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
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 = "",
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
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()
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
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()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
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.AcceleratorReplaceDialogFragment
|
||||
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
|
||||
AcceleratorReplaceDialogFragment.show(
|
||||
context,
|
||||
game.getUniquePackageName() ?: "",
|
||||
game.id,
|
||||
game.name ?: "",
|
||||
request.sourceEntrance
|
||||
) {
|
||||
if (chain.isValidContext(context)) {
|
||||
listener?.finished(context)
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
chain.proceed(context, request, listener)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,241 @@
|
||||
package com.gh.gamecenter.gamedetail.accelerator.dialog
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.IntDef
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.gh.common.util.DirectUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.WebActivity
|
||||
import com.gh.gamecenter.common.HaloApp
|
||||
import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.common.utils.goneIf
|
||||
import com.gh.gamecenter.common.utils.toColor
|
||||
import com.gh.gamecenter.core.provider.IAcceleratorProvider
|
||||
import com.gh.gamecenter.core.utils.CurrentActivityHolder
|
||||
import com.gh.gamecenter.databinding.DialogFragmentSpeedReplaceGameBinding
|
||||
import com.therouter.TheRouter
|
||||
|
||||
/**
|
||||
* 加速器相关的dialog
|
||||
*/
|
||||
class AcceleratorDialogFragment : BaseDialogFragment() {
|
||||
|
||||
private lateinit var binding: DialogFragmentSpeedReplaceGameBinding
|
||||
private lateinit var uiHelper: SpeedDialogUiHelper
|
||||
private var pkgName = ""
|
||||
private var gameId = ""
|
||||
private var gameName = ""
|
||||
private var sourceEntrance = ""
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val type = arguments?.getInt(EntranceConsts.KEY_SPEED_TYPE) ?: 0
|
||||
pkgName = arguments?.getString(EntranceConsts.KEY_PACKAGENAME) ?: ""
|
||||
gameId = arguments?.getString(EntranceConsts.KEY_GAMEID) ?: ""
|
||||
gameName = arguments?.getString(EntranceConsts.KEY_GAMENAME) ?: ""
|
||||
sourceEntrance = arguments?.getString(EntranceConsts.KEY_SOURCE_ENTRANCE) ?: ""
|
||||
uiHelper = when (type) {
|
||||
SPEED_ENABLE_VIP -> {
|
||||
SensorsBridge.trackMembershipActivationDialogShow(pkgName, gameId, gameName, sourceEntrance)
|
||||
EnableVipUi()
|
||||
}
|
||||
|
||||
SPEED_START_FAILURE -> {
|
||||
SensorsBridge.trackNetworkAccelerationFailureDialogShow(pkgName, gameId, gameName, sourceEntrance)
|
||||
SpeedFailureUi()
|
||||
}
|
||||
|
||||
SPEED_STOP -> StopSpeedUi()
|
||||
SPEED_NOT_INSTALLED -> NotInstalledUi()
|
||||
else -> throw IllegalArgumentException("请传递正确的参数 SpeedType !")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val createDialog = super.onCreateDialog(savedInstanceState)
|
||||
createDialog.setCanceledOnTouchOutside(true)
|
||||
createDialog.setCancelable(true)
|
||||
return createDialog
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
return DialogFragmentSpeedReplaceGameBinding.inflate(inflater, container, false)
|
||||
.also {
|
||||
binding = it
|
||||
}.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.tvContent.setText(uiHelper.contentResId)
|
||||
binding.tvCancel.goneIf(!uiHelper.isShowCancelButton) {
|
||||
if (uiHelper.cancelResId != -1) {
|
||||
binding.tvCancel.setText(uiHelper.cancelResId)
|
||||
}
|
||||
binding.tvCancel.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
binding.tvSubmit.setText(uiHelper.submitResId)
|
||||
binding.tvSubmit.setTextColor(uiHelper.submitTextColorResId.toColor(view.context))
|
||||
binding.tvSubmit.setBackgroundResource(uiHelper.submitBackgroundResId)
|
||||
|
||||
binding.tvSubmit.setOnClickListener {
|
||||
dismiss()
|
||||
when (uiHelper) {
|
||||
|
||||
is EnableVipUi -> {
|
||||
SensorsBridge.trackMembershipActivationDialogClick(
|
||||
pkgName,
|
||||
gameId,
|
||||
gameName,
|
||||
sourceEntrance
|
||||
)
|
||||
SensorsBridge.trackMyAssetsPageShow(pkgName, gameId, gameName, sourceEntrance)
|
||||
val intent = WebActivity.getMyAssetsIntent(requireContext())
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
is SpeedFailureUi -> {
|
||||
SensorsBridge.trackNetworkAccelerationFailureDialogClick(pkgName, gameId, gameName, sourceEntrance)
|
||||
context?.let {
|
||||
DirectUtils.directToWebView(it, Constants.QQ_QIDIAN_ADDRESS, "")
|
||||
}
|
||||
}
|
||||
|
||||
is StopSpeedUi -> {
|
||||
TheRouter.get(IAcceleratorProvider::class.java)?.stopQyGameAccelerate()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val width = HaloApp.getInstance().resources.displayMetrics.widthPixels - 60F.dip2px()
|
||||
val height = dialog?.window?.attributes?.height ?: ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
dialog?.window?.setLayout(width, height)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val SPEED_ENABLE_VIP = 1
|
||||
const val SPEED_START_FAILURE = 2
|
||||
const val SPEED_STOP = 3
|
||||
const val SPEED_NOT_INSTALLED = 4
|
||||
|
||||
fun show(
|
||||
@SpeedType type: Int,
|
||||
pkgName: String,
|
||||
gameId: String,
|
||||
gameName: String,
|
||||
sourceEntrance: String,
|
||||
context: Context
|
||||
) {
|
||||
if (context is AppCompatActivity) {
|
||||
context.supportFragmentManager
|
||||
} else {
|
||||
(CurrentActivityHolder.getCurrentActivity() as? AppCompatActivity)?.supportFragmentManager
|
||||
}?.let {
|
||||
val fragment = AcceleratorDialogFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putInt(EntranceConsts.KEY_SPEED_TYPE, type)
|
||||
putString(EntranceConsts.KEY_PACKAGENAME, pkgName)
|
||||
putString(EntranceConsts.KEY_GAMEID, gameId)
|
||||
putString(EntranceConsts.KEY_GAMENAME, gameName)
|
||||
putString(EntranceConsts.KEY_SOURCE_ENTRANCE, sourceEntrance)
|
||||
}
|
||||
}
|
||||
fragment.show(it, AcceleratorDialogFragment::class.java.simpleName)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@IntDef(SPEED_ENABLE_VIP, SPEED_START_FAILURE, SPEED_STOP, SPEED_NOT_INSTALLED)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class SpeedType
|
||||
|
||||
abstract class SpeedDialogUiHelper {
|
||||
|
||||
abstract val contentResId: Int
|
||||
|
||||
abstract val isShowCancelButton: Boolean
|
||||
|
||||
open val cancelResId: Int = -1
|
||||
|
||||
abstract val submitResId: Int
|
||||
|
||||
open val submitTextColorResId = com.gh.gamecenter.common.R.color.text_aw_primary
|
||||
|
||||
open val submitBackgroundResId = com.gh.gamecenter.common.R.drawable.bg_common_button_fill_blue
|
||||
}
|
||||
|
||||
class EnableVipUi : SpeedDialogUiHelper() {
|
||||
override val contentResId: Int
|
||||
get() = R.string.enable_vip_tips
|
||||
|
||||
override val isShowCancelButton: Boolean
|
||||
get() = false
|
||||
|
||||
override val submitResId: Int
|
||||
get() = R.string.go_to_activate
|
||||
|
||||
}
|
||||
|
||||
class SpeedFailureUi : SpeedDialogUiHelper() {
|
||||
override val contentResId: Int
|
||||
get() = R.string.speed_failure_tips
|
||||
|
||||
override val isShowCancelButton: Boolean
|
||||
get() = false
|
||||
|
||||
override val submitResId: Int
|
||||
get() = R.string.contact_service
|
||||
|
||||
override val submitTextColorResId: Int
|
||||
get() = com.gh.gamecenter.common.R.color.primary_theme
|
||||
|
||||
override val submitBackgroundResId: Int
|
||||
get() = com.gh.gamecenter.common.R.drawable.bg_common_button_light_fill_blue
|
||||
|
||||
}
|
||||
|
||||
class StopSpeedUi : SpeedDialogUiHelper() {
|
||||
override val contentResId: Int
|
||||
get() = R.string.stop_speed_tips
|
||||
|
||||
override val isShowCancelButton: Boolean
|
||||
get() = true
|
||||
|
||||
override val submitResId: Int
|
||||
get() = R.string.stop_speed
|
||||
|
||||
override val cancelResId: Int
|
||||
get() = R.string.cancel
|
||||
|
||||
}
|
||||
|
||||
class NotInstalledUi : SpeedDialogUiHelper() {
|
||||
|
||||
override val contentResId: Int
|
||||
get() = R.string.speed_not_installed_tips
|
||||
|
||||
override val isShowCancelButton: Boolean
|
||||
get() = false
|
||||
|
||||
override val submitResId: Int
|
||||
get() = R.string.dialog_hint_confirm
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,116 @@
|
||||
package com.gh.gamecenter.gamedetail.accelerator.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.HaloApp
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.core.utils.CurrentActivityHolder
|
||||
import com.gh.gamecenter.databinding.DialogFragmentSpeedReplaceGameBinding
|
||||
import com.lightgame.dialog.BaseDialogFragment
|
||||
|
||||
class AcceleratorReplaceDialogFragment : BaseDialogFragment() {
|
||||
|
||||
private lateinit var binding: DialogFragmentSpeedReplaceGameBinding
|
||||
private var pkgName = ""
|
||||
private var gameId = ""
|
||||
private var gameName = ""
|
||||
private var sourceEntrance = ""
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
pkgName = arguments?.getString(EntranceConsts.KEY_PACKAGENAME) ?: ""
|
||||
gameId = arguments?.getString(EntranceConsts.KEY_GAMEID) ?: ""
|
||||
gameName = arguments?.getString(EntranceConsts.KEY_GAMENAME) ?: ""
|
||||
sourceEntrance = arguments?.getString(EntranceConsts.KEY_SOURCE_ENTRANCE) ?: ""
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
return DialogFragmentSpeedReplaceGameBinding.inflate(inflater, container, false)
|
||||
.also {
|
||||
binding = it
|
||||
}.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
SensorsBridge.trackNetworkAccelerationConflictDialogShow(pkgName, gameId, gameName, sourceEntrance)
|
||||
|
||||
binding.tvContent.text = getString(R.string.speed_replace_game_tips, gameName)
|
||||
|
||||
binding.tvCancel.setOnClickListener {
|
||||
SensorsBridge.trackNetworkAccelerationConflictDialogClick(
|
||||
pkgName,
|
||||
gameId,
|
||||
gameName,
|
||||
BUTTON_NAME_CANCEL,
|
||||
sourceEntrance
|
||||
)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
binding.tvSubmit.setOnClickListener {
|
||||
SensorsBridge.trackNetworkAccelerationConflictDialogClick(
|
||||
pkgName,
|
||||
gameId,
|
||||
gameName,
|
||||
BUTTON_NAME_CONTINUE,
|
||||
sourceEntrance
|
||||
)
|
||||
// 加速
|
||||
dismiss()
|
||||
callback?.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val width = HaloApp.getInstance().resources.displayMetrics.widthPixels - 60F.dip2px()
|
||||
val height = dialog?.window?.attributes?.height ?: ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
dialog?.window?.setLayout(width, height)
|
||||
}
|
||||
|
||||
private var callback: (() -> Unit)? = null
|
||||
fun setOnSubmitListener(callback: () -> Unit) {
|
||||
this.callback = callback
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val BUTTON_NAME_CANCEL = "暂不启动"
|
||||
private const val BUTTON_NAME_CONTINUE = "继续启动"
|
||||
|
||||
fun show(
|
||||
context: Context,
|
||||
pkgName: String,
|
||||
gameId: String,
|
||||
gameName: String,
|
||||
sourceEntrance: String,
|
||||
callback: () -> Unit
|
||||
) {
|
||||
if (context is AppCompatActivity) {
|
||||
context.supportFragmentManager
|
||||
} else {
|
||||
(CurrentActivityHolder.getCurrentActivity() as? AppCompatActivity)?.supportFragmentManager
|
||||
}?.let {
|
||||
val fragment = AcceleratorReplaceDialogFragment().apply {
|
||||
setOnSubmitListener(callback)
|
||||
arguments = Bundle().apply {
|
||||
putString(EntranceConsts.KEY_PACKAGENAME, pkgName)
|
||||
putString(EntranceConsts.KEY_GAMEID, gameId)
|
||||
putString(EntranceConsts.KEY_GAMENAME, gameName)
|
||||
putString(EntranceConsts.KEY_SOURCE_ENTRANCE, sourceEntrance)
|
||||
}
|
||||
}
|
||||
fragment.show(it, AcceleratorDialogFragment::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,197 @@
|
||||
package com.gh.gamecenter.gamedetail.accelerator.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Rect
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||
import com.gh.common.util.CheckLoginUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.fragment.BaseBottomDialogFragment
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.common.utils.toBinding
|
||||
import com.gh.gamecenter.common.utils.toColor
|
||||
import com.gh.gamecenter.core.provider.IAcceleratorProvider
|
||||
import com.gh.gamecenter.core.utils.CurrentActivityHolder
|
||||
import com.gh.gamecenter.databinding.DialogFragmentAcceleratorZoneBinding
|
||||
import com.gh.gamecenter.databinding.RecyclerAcceleratorZoneBinding
|
||||
import com.gh.gamecenter.feature.entity.AcctGameInfo
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.gamedetail.accelerator.GameDetailAcceleratorUiHelper.Companion.MEMBER_TYPE_NOT_LOGIN
|
||||
import com.gh.gamecenter.gamedetail.accelerator.GameDetailAcceleratorUiHelper.Companion.SCENE_TYPE_NO_GUIDE_LAYER
|
||||
import com.gh.gamecenter.gamedetail.accelerator.GameDetailAcceleratorUiHelper.Companion.SOURCE_ENTRANCE_GAME_DETAIL
|
||||
import com.gh.gamecenter.gamedetail.AcceleratorZoneViewModel
|
||||
import com.gh.gamecenter.gamedetail.accelerator.chain.AcceleratorClient
|
||||
import com.gh.gamecenter.gamedetail.accelerator.chain.AcceleratorValidator
|
||||
import com.therouter.TheRouter
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class AcceleratorZoneDialogFragment : BaseBottomDialogFragment<DialogFragmentAcceleratorZoneBinding>() {
|
||||
|
||||
private val viewModel by viewModels<AcceleratorZoneViewModel>()
|
||||
|
||||
private lateinit var adapter: ZoneAdapter
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val data =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
arguments?.getParcelableArrayList(KEY_DATA, AcctGameInfo::class.java)
|
||||
} else {
|
||||
arguments?.getParcelableArrayList(KEY_DATA)
|
||||
} ?: listOf<AcctGameInfo>()
|
||||
|
||||
val game = arguments?.getParcelable<GameEntity>(KEY_GAME)!!
|
||||
|
||||
mBinding.titleView.setOnRightClickListener {
|
||||
dismiss()
|
||||
}
|
||||
adapter = ZoneAdapter {
|
||||
startAccelerating(game, it)
|
||||
dismiss()
|
||||
}
|
||||
mBinding.recyclerZone.layoutManager = GridLayoutManager(requireContext(), 3)
|
||||
mBinding.recyclerZone.addItemDecoration(MyDecorationItem())
|
||||
mBinding.recyclerZone.adapter = adapter
|
||||
adapter.submitList(data)
|
||||
}
|
||||
|
||||
private fun startAccelerating(game: GameEntity, acctGameInfo: AcctGameInfo) {
|
||||
context?.let {
|
||||
viewModel.useCase.insertAcctGameInfo(acctGameInfo)
|
||||
val iAcceleratorProvider = TheRouter.get(IAcceleratorProvider::class.java)
|
||||
|
||||
val memberType = if (CheckLoginUtils.isLogin()) {
|
||||
iAcceleratorProvider?.getMemberType() ?: ""
|
||||
} else {
|
||||
MEMBER_TYPE_NOT_LOGIN
|
||||
}
|
||||
|
||||
SensorsBridge.trackNetworkAccelerationButtonClick(
|
||||
game.getUniquePackageName() ?: "",
|
||||
game.id,
|
||||
game.name ?: "",
|
||||
memberType,
|
||||
acctGameInfo.zoneInfo.cnName ?: "",
|
||||
SCENE_TYPE_NO_GUIDE_LAYER,
|
||||
SOURCE_ENTRANCE_GAME_DETAIL
|
||||
)
|
||||
|
||||
val isVip = iAcceleratorProvider?.isVip() ?: false
|
||||
val isNewUser = iAcceleratorProvider?.isNewUser() ?: false
|
||||
val request = AcceleratorValidator.Request(isVip, isNewUser, game, SOURCE_ENTRANCE_GAME_DETAIL)
|
||||
AcceleratorClient.newInstance()
|
||||
.execute(it, request, object : AcceleratorValidator.ValidateListener {
|
||||
override fun finished(context: Context) {
|
||||
StartingAcceleratorDialogFragment.show(
|
||||
context, acctGameInfo, game, isNeedRecord = true, hasMultiZone = true,
|
||||
sourceEntrance = SOURCE_ENTRANCE_GAME_DETAIL
|
||||
)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val KEY_DATA = "key_data"
|
||||
private const val KEY_GAME = "key_game"
|
||||
fun show(context: Context, data: ArrayList<AcctGameInfo>, game: GameEntity) {
|
||||
if (context is AppCompatActivity) {
|
||||
context.supportFragmentManager
|
||||
} else {
|
||||
(CurrentActivityHolder.getCurrentActivity() as? AppCompatActivity)?.supportFragmentManager
|
||||
}?.let {
|
||||
val fragment = AcceleratorZoneDialogFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putParcelableArrayList(KEY_DATA, data)
|
||||
putParcelable(KEY_GAME, game)
|
||||
}
|
||||
}
|
||||
fragment.show(it, fragment::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MyDecorationItem : RecyclerView.ItemDecoration() {
|
||||
|
||||
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
|
||||
val position = parent.getChildAdapterPosition(view)
|
||||
val space = (16F.dip2px() / 3F).roundToInt()
|
||||
val (left, right) = when (position % 3) {
|
||||
0 -> 0 to space
|
||||
1 -> space to space
|
||||
else -> space to 0
|
||||
}
|
||||
outRect.top = 8F.dip2px()
|
||||
outRect.left = left
|
||||
outRect.right = right
|
||||
}
|
||||
}
|
||||
|
||||
class ZoneAdapter(private val click: (AcctGameInfo) -> Unit) :
|
||||
ListAdapter<AcctGameInfo, ZoneAdapter.ZoneViewHolder>(diffCallback) {
|
||||
|
||||
private var selectedPosition = -1
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ZoneViewHolder {
|
||||
return ZoneViewHolder(parent.toBinding())
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ZoneViewHolder, position: Int, payloads: MutableList<Any>) {
|
||||
if (payloads.isNotEmpty()) {
|
||||
updateSelectedState(holder, position)
|
||||
} else {
|
||||
super.onBindViewHolder(holder, position, payloads)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ZoneViewHolder, position: Int) {
|
||||
val item = getItem(position) ?: return
|
||||
updateSelectedState(holder, position)
|
||||
holder.binding.tvName.text = item.zoneName
|
||||
holder.itemView.setOnClickListener {
|
||||
click(item)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateSelectedState(holder: ZoneViewHolder, position: Int) {
|
||||
val (textColorResId, backgroundResId) = if (position == selectedPosition) {
|
||||
com.gh.gamecenter.common.R.color.text_theme to R.drawable.bg_shape_2496ff_alpha_10_radius_8
|
||||
} else {
|
||||
com.gh.gamecenter.common.R.color.text_secondary to R.drawable.bg_shape_f8_radius_8
|
||||
}
|
||||
holder.binding.tvName.setTextColor(textColorResId.toColor(holder.itemView.context))
|
||||
holder.binding.tvName.setBackgroundResource(backgroundResId)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val SELECTED_CHANGED_PAYLOAD = "selected_changed_payload"
|
||||
|
||||
private val diffCallback = object : DiffUtil.ItemCallback<AcctGameInfo>() {
|
||||
override fun areItemsTheSame(oldItem: AcctGameInfo, newItem: AcctGameInfo): Boolean {
|
||||
return oldItem.zoneInfo.id == newItem.zoneInfo.id
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: AcctGameInfo, newItem: AcctGameInfo): Boolean {
|
||||
return oldItem == newItem
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class ZoneViewHolder(val binding: RecyclerAcceleratorZoneBinding) : ViewHolder(binding.root)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,258 @@
|
||||
package com.gh.gamecenter.gamedetail.accelerator.dialog
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.gh.common.util.PackageLauncher
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge
|
||||
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.CurrentActivityHolder
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.databinding.DialogFragmentStartingAcceleratorBinding
|
||||
import com.gh.gamecenter.feature.entity.AcctGameInfo
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.gamedetail.StartingAcceleratorViewModel
|
||||
import com.gh.gamecenter.gamedetail.accelerator.GameDetailAcceleratorUiHelper.Companion.DISTRICT_SERVER_HAVA
|
||||
import com.gh.gamecenter.gamedetail.accelerator.GameDetailAcceleratorUiHelper.Companion.SOURCE_ENTRANCE_GAME_DETAIL
|
||||
import com.gh.gamecenter.gamedetail.accelerator.dialog.AcceleratorDialogFragment.Companion.SPEED_START_FAILURE
|
||||
import com.gh.gamecenter.livedata.EventObserver
|
||||
import com.therouter.TheRouter
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import kotlin.math.max
|
||||
|
||||
class StartingAcceleratorDialogFragment : BaseDialogFragment() {
|
||||
|
||||
private val viewModel by viewModels<StartingAcceleratorViewModel>()
|
||||
|
||||
private lateinit var binding: DialogFragmentStartingAcceleratorBinding
|
||||
|
||||
private lateinit var acctGameInfo: AcctGameInfo
|
||||
private lateinit var game: GameEntity
|
||||
private var isNeedRecord: Boolean = false
|
||||
private var iAcceleratorProvider: IAcceleratorProvider? = null
|
||||
private var hasMultiZone = false
|
||||
private var sourceEntrance = SOURCE_ENTRANCE_GAME_DETAIL
|
||||
|
||||
private val compositeDisposable = CompositeDisposable()
|
||||
private var _progress = 0
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
|
||||
private var refreshTokenCount = 0
|
||||
|
||||
private val accelerationListener = object : OnAccelerateListener {
|
||||
override fun onStateChanged(state: AccelerateState) {
|
||||
// 如果状态能成功回,则移除计时
|
||||
handler.removeCallbacksAndMessages(null)
|
||||
when (state) {
|
||||
is AccelerateState.Success -> {
|
||||
ToastUtils.showToast("加速成功")
|
||||
// 加速成功,启动游戏
|
||||
PackageLauncher.launchApp(requireContext(), game, game.getUniquePackageName())
|
||||
// 记录加速记录
|
||||
if (isNeedRecord) {
|
||||
viewModel.useCase.recordAcctGameInfo(game.id, acctGameInfo, hasMultiZone)
|
||||
}
|
||||
|
||||
trackNetworkAccelerationStartupResult("成功")
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
|
||||
is AccelerateState.Failure -> {
|
||||
// 有些错误需要额外处理,这里直接跳过错误提示(如:token失效,登录时token设置失败)
|
||||
if ((state.isTokenExpired || state.isTokenEmpty) && refreshTokenCount < REFRESH_TOKEN_MAX_COUNT) {
|
||||
// do nothing
|
||||
} else {
|
||||
if (!state.isSkipError) {
|
||||
context?.let {
|
||||
AcceleratorDialogFragment.show(
|
||||
SPEED_START_FAILURE,
|
||||
game.getUniquePackageName() ?: "",
|
||||
game.id,
|
||||
game.name ?: "",
|
||||
sourceEntrance,
|
||||
it
|
||||
)
|
||||
}
|
||||
}
|
||||
dismissAllowingStateLoss()
|
||||
trackNetworkAccelerationStartupResult("失败(${state.code})")
|
||||
}
|
||||
}
|
||||
|
||||
is AccelerateState.Normal -> {
|
||||
if (state.isTokenExpired || state.isTokenEmpty) {
|
||||
// token过期/登录时token设置失败,在此获取token并重新启动加速(最多重试三次)
|
||||
if (refreshTokenCount < REFRESH_TOKEN_MAX_COUNT) {
|
||||
viewModel.loadAcceleratorToken()
|
||||
refreshTokenCount++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
override fun onProgress(progress: Int, curGamePkgName: String?, curGameZoneFlag: String?) {
|
||||
_progress = max(_progress, progress)
|
||||
binding.tvProgress.text = getString(R.string.accelerating_with_progress, "$progress")
|
||||
}
|
||||
|
||||
override fun onVipStatusChanged(isNewUser: Boolean, isVip: Boolean) = Unit
|
||||
|
||||
}
|
||||
|
||||
private fun trackNetworkAccelerationStartupResult(result: String) {
|
||||
SensorsBridge.trackNetworkAccelerationStartupResult(
|
||||
game.getUniquePackageName() ?: "",
|
||||
game.id,
|
||||
game.name ?: "",
|
||||
iAcceleratorProvider?.getMemberType() ?: "",
|
||||
if (hasMultiZone) acctGameInfo.zoneInfo.cnName ?: "" else DISTRICT_SERVER_HAVA,
|
||||
result,
|
||||
sourceEntrance
|
||||
)
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
return super.onCreateDialog(savedInstanceState).apply {
|
||||
setCancelable(false)
|
||||
setCanceledOnTouchOutside(false)
|
||||
this@StartingAcceleratorDialogFragment.isCancelable = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
iAcceleratorProvider = TheRouter.get(IAcceleratorProvider::class.java)
|
||||
acctGameInfo = arguments?.getParcelable(EntranceConsts.KEY_ACCT_GAME_INFO)!!
|
||||
game = arguments?.getParcelable(EntranceConsts.KEY_GAME)!!
|
||||
isNeedRecord = arguments?.getBoolean(EntranceConsts.KEY_IS_NEED_RECORD) ?: false
|
||||
hasMultiZone = arguments?.getBoolean(EntranceConsts.KEY_HAS_MULTI_ZONE) ?: false
|
||||
sourceEntrance = arguments?.getString(EntranceConsts.KEY_SOURCE_ENTRANCE) ?: SOURCE_ENTRANCE_GAME_DETAIL
|
||||
}
|
||||
|
||||
override fun onBack(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
return DialogFragmentStartingAcceleratorBinding.inflate(inflater, container, false)
|
||||
.also {
|
||||
binding = it
|
||||
}.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.tvProgress.text = getString(R.string.accelerating_with_progress, "0")
|
||||
iAcceleratorProvider?.bindAccRelatedListener("", accelerationListener)
|
||||
val isVip = iAcceleratorProvider?.isVip() ?: false
|
||||
val isNewUser = iAcceleratorProvider?.isNewUser() ?: false
|
||||
if (isNewUser && !isVip) {
|
||||
// 新用户,并且还不是vip
|
||||
viewModel.rechargeTrial()
|
||||
} else {
|
||||
startGameAccelerate()
|
||||
}
|
||||
|
||||
viewModel.restartingAcceleratorAction.observe(viewLifecycleOwner, EventObserver {
|
||||
startGameAccelerate()
|
||||
})
|
||||
|
||||
viewModel.rechargeTrailResult.observe(viewLifecycleOwner, EventObserver {
|
||||
if (it) {
|
||||
startGameAccelerate()
|
||||
} else {
|
||||
// 充值失败
|
||||
AcceleratorDialogFragment.show(
|
||||
SPEED_START_FAILURE,
|
||||
game.getUniquePackageName() ?: "",
|
||||
game.id,
|
||||
game.name ?: "",
|
||||
sourceEntrance,
|
||||
requireContext()
|
||||
)
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
private fun startGameAccelerate() {
|
||||
handler.removeCallbacksAndMessages(null)
|
||||
handler.postDelayed({
|
||||
// 15s以后,不管成功还是失败,都要关闭当前页面
|
||||
dismissAllowingStateLoss()
|
||||
}, TIME_OUT)
|
||||
viewModel.useCase.setLastAcctGameRecord(game)
|
||||
iAcceleratorProvider?.startQyGameAccelerate(acctGameInfo)
|
||||
if (isNeedRecord) {
|
||||
viewModel.useCase.insertAcctGameInfo(acctGameInfo)
|
||||
}
|
||||
if (refreshTokenCount == 0) {
|
||||
SensorsBridge.trackNetworkAccelerationStartup(
|
||||
game.getUniquePackageName() ?: "",
|
||||
game.id,
|
||||
game.name ?: "",
|
||||
iAcceleratorProvider?.getMemberType() ?: "",
|
||||
if (hasMultiZone) acctGameInfo.zoneInfo.cnName ?: "" else DISTRICT_SERVER_HAVA,
|
||||
sourceEntrance
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
handler.removeCallbacksAndMessages(null)
|
||||
iAcceleratorProvider?.unBindAccRelatedListener(accelerationListener)
|
||||
super.onDestroyView()
|
||||
compositeDisposable.clear()
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TIME_OUT = 1000 * 15L
|
||||
private const val REFRESH_TOKEN_MAX_COUNT = 3
|
||||
|
||||
fun show(
|
||||
context: Context,
|
||||
acctGameInfo: AcctGameInfo,
|
||||
game: GameEntity,
|
||||
isNeedRecord: Boolean,
|
||||
hasMultiZone: Boolean,
|
||||
sourceEntrance: String
|
||||
) {
|
||||
if (context is AppCompatActivity) {
|
||||
context.supportFragmentManager
|
||||
} else {
|
||||
(CurrentActivityHolder.getCurrentActivity() as? AppCompatActivity)?.supportFragmentManager
|
||||
}?.let {
|
||||
val fragment = StartingAcceleratorDialogFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putParcelable(EntranceConsts.KEY_ACCT_GAME_INFO, acctGameInfo)
|
||||
putParcelable(EntranceConsts.KEY_GAME, game)
|
||||
putBoolean(EntranceConsts.KEY_IS_NEED_RECORD, isNeedRecord)
|
||||
putBoolean(EntranceConsts.KEY_HAS_MULTI_ZONE, hasMultiZone)
|
||||
putString(EntranceConsts.KEY_SOURCE_ENTRANCE, sourceEntrance)
|
||||
}
|
||||
}
|
||||
fragment.show(it, fragment::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -983,14 +983,17 @@ class DescAdapter(
|
||||
setExpandMaxLines(maxDesLines)
|
||||
setIsExpanded(Int.MAX_VALUE == maxDesLines)
|
||||
if (customColumn.isHtmlDes == true) {
|
||||
val decoratedDesBrief = (customColumn.desBrief ?: "").dropFontColorInDarkMode(contentTv.context)
|
||||
val decoratedDes = (customColumn.des ?: "").dropFontColorInDarkMode(contentTv.context)
|
||||
|
||||
shrankSpanned = HtmlCompat.fromHtml(
|
||||
customColumn.desBrief ?: "",
|
||||
decoratedDesBrief,
|
||||
HtmlCompat.FROM_HTML_MODE_COMPACT,
|
||||
PicassoImageGetter(contentTv),
|
||||
ExtraTagHandler()
|
||||
)
|
||||
expandedSpanned = HtmlCompat.fromHtml(
|
||||
customColumn.des ?: "",
|
||||
decoratedDes,
|
||||
HtmlCompat.FROM_HTML_MODE_COMPACT,
|
||||
PicassoImageGetter(contentTv),
|
||||
ExtraTagHandler()
|
||||
|
||||
@ -61,7 +61,14 @@ class NewGameDetailEntity(
|
||||
|
||||
@SerializedName("new_notice")
|
||||
var newNotice: ArrayList<LinkEntity>? = null,
|
||||
|
||||
@SerializedName("accelerator_status")
|
||||
private var _acceleratorStatus: Boolean? = null
|
||||
) {
|
||||
|
||||
val acceleratorStatus: Boolean
|
||||
get() = _acceleratorStatus ?: false
|
||||
|
||||
fun isShowContentCard(gameEntity: GameEntity?): Boolean {
|
||||
return contentCard.size > 1 && (gameEntity?.shouldUseMirrorInfo() == false || (gameEntity?.shouldUseMirrorInfo() == true && mirrorData?.contentCardStatus == "on"))
|
||||
}
|
||||
|
||||
@ -6,11 +6,14 @@ import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity_TabLayout
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.utils.updateStatusBarColor
|
||||
import com.therouter.router.Route
|
||||
|
||||
/**
|
||||
* 开服订阅
|
||||
*/
|
||||
@Route(
|
||||
path = RouteConsts.activity.serversCalendarManagementActivity,
|
||||
description = "开服订阅"
|
||||
)
|
||||
class ServersCalendarManagementActivity : BaseActivity_TabLayout() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
||||
@ -25,10 +25,10 @@ import com.gh.gamecenter.common.utils.toPx
|
||||
import com.gh.gamecenter.core.iinterface.IScrollable
|
||||
import com.gh.gamecenter.core.utils.MtaHelper
|
||||
import com.gh.gamecenter.core.utils.SpanBuilder
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.RatingComment
|
||||
import com.gh.gamecenter.eventbus.EBStar
|
||||
import com.gh.gamecenter.eventbus.EBTypeChange
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.gamedetail.GameDetailFragment
|
||||
import com.halo.assistant.HaloApp
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
@ -60,7 +60,7 @@ class RatingFragment : LazyListFragment<RatingComment, RatingViewModel>(), IScro
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (requestCode == RATING_EDIT_REQUEST && resultCode == Activity.RESULT_OK) {
|
||||
mListViewModel.initData()
|
||||
mListViewModel?.initData()
|
||||
} else if (
|
||||
(requestCode == RATING_REPLAY_REQUEST || requestCode == RATING_PATCH_REQUEST)
|
||||
&& resultCode == Activity.RESULT_OK
|
||||
|
||||
@ -3,7 +3,11 @@ package com.gh.gamecenter.home.custom
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@ -54,6 +58,7 @@ import com.gh.gamecenter.feature.entity.PageLocation
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.ExposureType
|
||||
import com.gh.gamecenter.feature.minigame.MiniGameItemHelper
|
||||
import com.gh.gamecenter.feature.utils.SentryHelper
|
||||
import com.gh.gamecenter.game.commoncollection.detail.CustomCommonCollectionDetailActivity
|
||||
import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity
|
||||
import com.gh.gamecenter.home.PageConfigure
|
||||
@ -69,6 +74,9 @@ import com.gh.gamecenter.wrapper.SearchToolbarTabWrapperViewModel
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.DataWatcher
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.scwang.smartrefresh.layout.api.RefreshLayout
|
||||
import com.scwang.smartrefresh.layout.constant.RefreshState
|
||||
import com.shuyu.gsyvideoplayer.video.base.GSYVideoView
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
|
||||
@ -179,6 +187,22 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
viewModel.init(pageConfigure, searchToolbarTabWrapperViewModel, pageLocation)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
binding = try {
|
||||
FragmentCustomBinding.inflate(layoutInflater)
|
||||
} catch (e: Exception) {
|
||||
SentryHelper.onEvent(
|
||||
"VIEW_BINDING_BIND_ERROR",
|
||||
"digest", e.localizedMessage,
|
||||
"gid", HaloApp.getInstance().gid
|
||||
)
|
||||
// 玄学,重试一次,该闪退闪退
|
||||
FragmentCustomBinding.inflate(layoutInflater)
|
||||
}
|
||||
mCachedView = binding.root
|
||||
return mCachedView
|
||||
}
|
||||
|
||||
override fun getRealLayoutId() = R.layout.fragment_custom
|
||||
|
||||
override fun onFragmentFirstVisible() {
|
||||
@ -215,7 +239,7 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
viewModel.loadFirst(false)
|
||||
}
|
||||
}
|
||||
binding.reuseNoConnectionStub.inflate()
|
||||
binding.reuseNoConnectionStub.inflateOrShow()
|
||||
} else {
|
||||
noConnectionBinding?.root?.visibility = View.VISIBLE
|
||||
}
|
||||
@ -225,7 +249,7 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
noDataBinding = ReuseNoneDataBinding.bind(inflated)
|
||||
noDataBinding?.root?.visibility = View.VISIBLE
|
||||
}
|
||||
binding.reuseNoDataStub.inflate()
|
||||
binding.reuseNoDataStub.inflateOrShow()
|
||||
} else {
|
||||
noDataBinding?.root?.visibility = View.VISIBLE
|
||||
}
|
||||
@ -275,9 +299,12 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
if (searchBarBinding == null) {
|
||||
binding.reuseSearchBarStub.setOnInflateListener { _, inflated ->
|
||||
searchBarBinding = LayoutSearchBarBinding.bind(inflated)
|
||||
binding.gameRefresh.updateLayoutParams<RelativeLayout.LayoutParams> {
|
||||
addRule(RelativeLayout.BELOW, R.id.reuseSearchBar)
|
||||
}
|
||||
initSearchBar(it)
|
||||
}
|
||||
binding.reuseSearchBarStub.inflate()
|
||||
binding.reuseSearchBarStub.inflateOrShow()
|
||||
} else {
|
||||
initSearchBar(it)
|
||||
}
|
||||
@ -469,7 +496,8 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
pageLocation.tabPosition,
|
||||
pageLocation.tabContent,
|
||||
pageLocation.pageId,
|
||||
pageLocation.pageName
|
||||
pageLocation.pageName,
|
||||
mEntrance
|
||||
)
|
||||
|
||||
viewModel.loadData()
|
||||
@ -488,8 +516,6 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
override fun initRealView() {
|
||||
super.initRealView()
|
||||
|
||||
binding = FragmentCustomBinding.bind(mCachedView)
|
||||
|
||||
scrollCalculatorHelper = ScrollCalculatorHelper(binding.gameList, R.id.autoVideoView, 0, false)
|
||||
|
||||
buildPriorityChain()
|
||||
@ -743,7 +769,7 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
}
|
||||
}
|
||||
|
||||
override fun setScrollEnabled(isScrollEnabled: Boolean) {
|
||||
private fun setScrollEnabled(isScrollEnabled: Boolean) {
|
||||
if (::layoutManager.isInitialized) {
|
||||
layoutManager.isScrollVerticallyEnabled = isScrollEnabled
|
||||
}
|
||||
@ -759,6 +785,32 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStateChanged(refreshLayout: RefreshLayout, oldState: RefreshState, newState: RefreshState) {
|
||||
if (oldState == RefreshState.None && newState == RefreshState.PullDownToRefresh) {
|
||||
pauseVideo()
|
||||
} else if ((oldState == RefreshState.TwoLevelFinish || oldState == RefreshState.RefreshFinish) && newState == RefreshState.None) {
|
||||
val currentPlayer = scrollCalculatorHelper.currentPlayer
|
||||
if (currentPlayer == null) {
|
||||
scrollCalculatorHelper.playIfValid()
|
||||
} else if (currentPlayer.currentState == GSYVideoView.CURRENT_STATE_PAUSE) {
|
||||
resumeVideo()
|
||||
}
|
||||
}
|
||||
|
||||
when (newState) {
|
||||
RefreshState.TwoLevel -> {
|
||||
setScrollEnabled(false)
|
||||
}
|
||||
RefreshState.None -> {
|
||||
setScrollEnabled(true)
|
||||
}
|
||||
|
||||
else -> {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun scrollToTop() {
|
||||
if (::binding.isInitialized) {
|
||||
binding.gameList.stopScroll()
|
||||
|
||||
@ -93,7 +93,12 @@ class CustomPageViewModel(
|
||||
|
||||
private var searchToolbarTabWrapperViewModel: SearchToolbarTabWrapperViewModel? = null
|
||||
|
||||
private val subjectChangedMap: ArrayMap<String, List<GameEntity>> = ArrayMap()
|
||||
private val subjectChangedMap: ArrayMap<SubjectChanged, List<GameEntity>> = ArrayMap()
|
||||
|
||||
/**
|
||||
* 微信CPM专题当前的页码记录
|
||||
*/
|
||||
private val cpmSubjectChangedPageMap: ArrayMap<String, Int> = ArrayMap()
|
||||
|
||||
var slideDiscoveryGamesPage = -1
|
||||
|
||||
@ -358,9 +363,68 @@ class CustomPageViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onChangeABatch(subjectEntity: SubjectEntity) {
|
||||
override fun onChangeABatch(subjectEntity: SubjectEntity) =
|
||||
if (subjectEntity.isWechatColumnCPM) {
|
||||
onChangeWGameCPMABatch(subjectEntity)
|
||||
} else {
|
||||
onChangeNormalGameABatch(subjectEntity)
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信小游戏CPM的“换一批”功能实现
|
||||
*
|
||||
* @see <a href="https://jira.shanqu.cc/browse/GHZSCY-7167">【光环助手】CPM微信小游戏“换一批”功能优化</a>
|
||||
*/
|
||||
private fun onChangeWGameCPMABatch(subjectEntity: SubjectEntity) {
|
||||
val subjectId = subjectEntity.id ?: return
|
||||
val gameList = subjectChangedMap[subjectId]
|
||||
val page = cpmSubjectChangedPageMap[subjectId] ?: let {
|
||||
// 第一次点击“换一批”时,先缓存第一页的数据
|
||||
subjectChangedMap[SubjectChanged(subjectId, 1)] = subjectEntity.data
|
||||
2
|
||||
}
|
||||
val subjectChanged = SubjectChanged(subjectId, page)
|
||||
val gameList = subjectChangedMap[subjectChanged]
|
||||
if (gameList != null) {// 直接读取缓存数据
|
||||
notifyWGameCPMABatchChanged(gameList, subjectId, page)
|
||||
} else {
|
||||
repository.loadChangeSubjectWGameCPM(page)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Response<List<GameEntity>>() {
|
||||
override fun onResponse(response: List<GameEntity>?) {
|
||||
if (response != null) {
|
||||
subjectChangedMap[subjectChanged] = response
|
||||
notifyWGameCPMABatchChanged(response, subjectId, page)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(e: HttpException?) {
|
||||
Utils.toast(getApplication(), "网络异常")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyWGameCPMABatchChanged(gameList: List<GameEntity>, subjectId: String, page: Int) {
|
||||
val nextPage: Int
|
||||
val cpmGameList = if(gameList.isEmpty()) {
|
||||
nextPage = 1// 已经到最后一页了,下一页是第一页
|
||||
subjectChangedMap[SubjectChanged(subjectId, 1)]!!
|
||||
} else {
|
||||
nextPage = page + 1
|
||||
gameList
|
||||
}
|
||||
cpmSubjectChangedPageMap[subjectId] = nextPage// 加载下一页数据
|
||||
changeSubjectCustomPageItem(subjectId, ArrayList(cpmGameList))
|
||||
}
|
||||
|
||||
/**
|
||||
* 光环游戏的“换一批”功能实现
|
||||
*/
|
||||
private fun onChangeNormalGameABatch(subjectEntity: SubjectEntity) {
|
||||
val subjectId = subjectEntity.id ?: return
|
||||
val subjectChanged = SubjectChanged(subjectId, 2)
|
||||
val gameList = subjectChangedMap[subjectChanged]
|
||||
if (gameList != null) {
|
||||
changeSubjectCustomPageItem(subjectId, getRandomGameList(subjectEntity.data, ArrayList(gameList)))
|
||||
} else {
|
||||
@ -370,7 +434,7 @@ class CustomPageViewModel(
|
||||
.subscribe(object : Response<List<GameEntity>>() {
|
||||
override fun onResponse(response: List<GameEntity>?) {
|
||||
if (response != null) {
|
||||
subjectChangedMap[subjectId] = response
|
||||
subjectChangedMap[subjectChanged] = response
|
||||
onChangeABatch(subjectEntity)
|
||||
}
|
||||
}
|
||||
@ -760,5 +824,26 @@ class CustomPageViewModel(
|
||||
repository.onClear()
|
||||
}
|
||||
|
||||
class SubjectChanged(
|
||||
val subjectId: String,
|
||||
val page: Int
|
||||
) {
|
||||
companion object {
|
||||
private const val HASH = 30
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return subjectId.hashCode() + page.hashCode() + HASH
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is SubjectChanged) {
|
||||
return false
|
||||
}
|
||||
return other.subjectId == subjectId
|
||||
&& other.page == page
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -6,6 +6,8 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.utils.goneIf
|
||||
import com.gh.gamecenter.common.utils.toBinding
|
||||
import com.gh.gamecenter.common.utils.toColor
|
||||
import com.gh.gamecenter.common.utils.toDrawable
|
||||
import com.gh.gamecenter.databinding.RecyclerContentLabelLaneItemBinding
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageData
|
||||
|
||||
@ -28,6 +30,10 @@ class ContentLabelLaneAdapter(
|
||||
override fun onBindViewHolder(holder: ContentLabelChildViewHolder, position: Int) {
|
||||
val item = getItem(position)
|
||||
with(holder.binding) {
|
||||
vBackground.background = R.drawable.bg_shape_content_label_lane_item.toDrawable(context)
|
||||
tvTitle.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(context))
|
||||
tvSubTitle.setTextColor(com.gh.gamecenter.common.R.color.primary_theme.toColor(context))
|
||||
|
||||
ivIcon.goneIf(item.image.isBlank()){
|
||||
ivIcon.displayGameIcon(item.image, null, null)
|
||||
}
|
||||
|
||||
@ -805,11 +805,13 @@ class CustomPageRepository private constructor(
|
||||
}
|
||||
|
||||
fun loadChangeSubjectGame(subjectEntity: SubjectEntity): Observable<List<GameEntity>> =
|
||||
if (subjectEntity.isWechatColumnCPM) {// 微信小游戏CPM专题的“换一批”接口
|
||||
wGameSubjectCPMRemoteDataSource.getRecommendCPMList(2, 10).toObservable()
|
||||
} else {
|
||||
remoteDataSource.loadChangeSubjectGame(subjectEntity)
|
||||
}
|
||||
remoteDataSource.loadChangeSubjectGame(subjectEntity)
|
||||
.map(RegionSettingHelper.filterGame)
|
||||
.map(ApkActiveUtils.filterMapperList)
|
||||
|
||||
fun loadChangeSubjectWGameCPM(page: Int): Observable<MutableList<GameEntity>> =
|
||||
wGameSubjectCPMRemoteDataSource.getEditorRecommendCPMList(page, 10)// 微信小游戏CPM专题的“换一批”接口
|
||||
.toObservable()
|
||||
.map(RegionSettingHelper.filterGame)
|
||||
.map(ApkActiveUtils.filterMapperList)
|
||||
|
||||
|
||||
@ -65,7 +65,7 @@ class SubjectTracker(private val pageLocation: PageLocation) {
|
||||
pageLocation.pageName,
|
||||
subject?.id ?: "",
|
||||
subject?.name ?: "",
|
||||
"最近在玩",
|
||||
"自定义页面",
|
||||
item.componentStyle,
|
||||
"",
|
||||
)
|
||||
|
||||
@ -363,7 +363,7 @@ class CommonContentHomeSlideWithCardsUi(
|
||||
homeSlideCardItemBinding.cardIv.visibility = View.VISIBLE
|
||||
// 防止重复加载图片导致闪烁
|
||||
if (homeSubSlide.image != cardIv.getTag(R.string.tag_img_url_id)) {
|
||||
ImageUtils.display(cardIv, homeSubSlide.image, false, AlphaGradientProcess())
|
||||
ImageUtils.display(cardIv, homeSubSlide.image, true, AlphaGradientProcess())
|
||||
cardIv.setTag(R.string.tag_img_url_id, homeSubSlide.image)
|
||||
}
|
||||
ConstraintSet().apply {
|
||||
@ -398,7 +398,7 @@ class CommonContentHomeSlideWithCardsUi(
|
||||
descTv.text = homeSubSlide.cardDesc
|
||||
// 防止重复加载图片导致闪烁
|
||||
if (homeSubSlide.image != cardIv.getTag(R.string.tag_img_url_id)) {
|
||||
ImageUtils.display(cardIv, homeSubSlide.image, false, AlphaGradientProcess())
|
||||
ImageUtils.display(cardIv, homeSubSlide.image, true, AlphaGradientProcess())
|
||||
cardIv.setTag(R.string.tag_img_url_id, homeSubSlide.image)
|
||||
}
|
||||
ConstraintSet().apply {
|
||||
|
||||
@ -40,7 +40,7 @@ class CustomGameGallerySlideViewHolder(
|
||||
override fun bindView(item: CustomPageItem) {
|
||||
super.bindView(item)
|
||||
if (item is CustomSubjectItem) {
|
||||
|
||||
binding.cardView.setCardBackgroundColor(com.gh.gamecenter.common.R.color.ui_container_1.toColor(binding.root.context))
|
||||
if (item.data == cachedSubject) return
|
||||
|
||||
cachedSubject = item.data
|
||||
@ -77,7 +77,6 @@ class CustomGameGallerySlideViewHolder(
|
||||
val gameList = item.data.data ?: emptyList()
|
||||
(recyclerView.adapter as? GameGallerySlideAdapter)?.submitList(gameList)
|
||||
}
|
||||
binding.cardView.setCardBackgroundColor(com.gh.gamecenter.common.R.color.text_FAFAFA.toColor(binding.root.context))
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -192,9 +192,6 @@ class CustomGameItemViewHolder(
|
||||
adLabelTv: TextView? = null,
|
||||
canShowSubTitle: Boolean
|
||||
) {
|
||||
if (entity.id == gameSubtitleTv.getTag(com.gh.gamecenter.common.R.string.tag_game_name_id)) return
|
||||
gameSubtitleTv.setTag(com.gh.gamecenter.common.R.string.tag_game_name_id, entity.id)
|
||||
|
||||
var showSubtitle = false
|
||||
var showAdvancedDownload = false
|
||||
if (canShowSubTitle && entity.serverLabel == null && entity.subtitle.isNotEmpty() && !entity.advanceDownload) {
|
||||
@ -214,6 +211,9 @@ class CustomGameItemViewHolder(
|
||||
setColor("#${entity.subtitleStyle?.background}".hexStringToIntColor())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(context))
|
||||
background = R.drawable.bg_advance_download_game_subtitle.toDrawable(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -226,6 +226,10 @@ class CustomGameItemViewHolder(
|
||||
background = R.drawable.bg_advance_download_game_subtitle.toDrawable(context)
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.id == gameSubtitleTv.getTag(com.gh.gamecenter.common.R.string.tag_game_name_id)) return
|
||||
gameSubtitleTv.setTag(com.gh.gamecenter.common.R.string.tag_game_name_id, entity.id)
|
||||
|
||||
if (showSubtitle || showAdvancedDownload) {
|
||||
val minWidth =
|
||||
if (showSubtitle) SUBTITLE_MIN_WIDTH.dip2px() else if (showAdvancedDownload) ADVANCED_DOWNLOAD_WIDTH.dip2px() else 0
|
||||
|
||||
@ -109,7 +109,9 @@ class CustomHomeGameItemViewHolder(
|
||||
item.linkColumn?.id ?: ""
|
||||
)
|
||||
}
|
||||
binding.gameBrief.text = game.recommendText
|
||||
binding.gameBrief.goneIf(game.recommendText.isEmpty()) {
|
||||
binding.gameBrief.text = game.recommendText
|
||||
}
|
||||
binding.gameImage.visibleIf(game.showImage) {
|
||||
if (game.isWechatMiniGame()) {
|
||||
ImageUtils.display(binding.gameImage, game.banner)
|
||||
|
||||
@ -53,6 +53,7 @@ class CustomHomeSlideListItemViewHolder(val binding: HomeSlideListItemCustomBind
|
||||
ImageUtils.displayWithCallback(
|
||||
binding.slideBackground,
|
||||
homeSlide.image,
|
||||
false,
|
||||
object : BaseControllerListener<ImageInfo>() {
|
||||
override fun onFinalImageSet(id: String?, imageInfo: ImageInfo?, animatable: Animatable?) {
|
||||
binding.bottomGradient.visibility = View.VISIBLE
|
||||
|
||||
@ -67,6 +67,7 @@ class CustomHomeSubSlideListItemViewHolder(val binding: HomeSubSlideListItemCust
|
||||
ImageUtils.displayWithCallback(
|
||||
binding.slideBackground,
|
||||
homeSlide.image,
|
||||
false,
|
||||
object : BaseControllerListener<ImageInfo>() {
|
||||
override fun onFinalImageSet(id: String?, imageInfo: ImageInfo?, animatable: Animatable?) {
|
||||
if (homeSlide.placeholderColor.isNotEmpty() && homeSlide.linkGame != null) {
|
||||
|
||||
@ -62,7 +62,11 @@ class HomeGameTestV2GameListViewHolder(
|
||||
)
|
||||
|
||||
//开服日期
|
||||
val gameTimeText = getGameTimeText(gameEntity)
|
||||
val gameTimeText = if (gameEntity.openTest?.startPending == true) {
|
||||
gameEntity.openTest?.startText ?: ""
|
||||
} else {
|
||||
getGameTimeText(gameEntity)
|
||||
}
|
||||
gameDes.text = gameTimeText
|
||||
gameDes.isVisible = gameTimeText.isNotEmpty()
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user