Compare commits
106 Commits
v5.29.2-93
...
v5.30.0-95
| Author | SHA1 | Date | |
|---|---|---|---|
| 7cfa26ff02 | |||
| a7335d21c5 | |||
| 0fd84f8b44 | |||
| 43bcf78dea | |||
| fb44391500 | |||
| 4c4de337cd | |||
| 625e448928 | |||
| 2bfefc5082 | |||
| 1538d77960 | |||
| 9f77e70c16 | |||
| 630f78e62d | |||
| dc7b103cbc | |||
| d30f51123d | |||
| 00f625c350 | |||
| 95f63bd4f2 | |||
| 07a1b2a63b | |||
| 6a36874ef8 | |||
| 285e0caafe | |||
| 0e0c6c48af | |||
| 38c02380ad | |||
| bf5608492d | |||
| 267f03fd42 | |||
| d39a62d4e0 | |||
| 5d02c40227 | |||
| 910d1eb6b7 | |||
| 755a2a0633 | |||
| 1a33e24a85 | |||
| 9a9c219082 | |||
| 3e9c3027f2 | |||
| c895965822 | |||
| 8dff7f3e69 | |||
| 5abb229fcc | |||
| d0b6d4ae5c | |||
| 772a21210d | |||
| b81df5b2ad | |||
| 07c44ef6a1 | |||
| 6aa1a0a00e | |||
| c6890cee19 | |||
| f83a4035c3 | |||
| 5fc03780a9 | |||
| ac7828c9f2 | |||
| 270a02366d | |||
| 25d96aba67 | |||
| f6558e1e13 | |||
| 7784cecdbc | |||
| ad3301e0a8 | |||
| 8f2ee5d323 | |||
| 9a999eefb7 | |||
| cdb274229b | |||
| b20a3717e1 | |||
| 3ef8dea4d2 | |||
| 17ee9752d3 | |||
| a5992750ed | |||
| 8b76b72222 | |||
| ad6b7228cf | |||
| 9a0873cf67 | |||
| 6cf461dbf7 | |||
| 68252a4375 | |||
| 9925022660 | |||
| 5972b8b4bf | |||
| f31507ae9f | |||
| dec546238e | |||
| 5715d36ad1 | |||
| c62021ee64 | |||
| 7bab11d2a1 | |||
| 5bb2451750 | |||
| ef0341ad6d | |||
| f645964bdf | |||
| e420b261bb | |||
| 1781f4c665 | |||
| ee79ed528b | |||
| fc9137a48d | |||
| 2dceaeec3e | |||
| f59bc42539 | |||
| 5b7c98224c | |||
| 2710c03112 | |||
| 3341d55f5a | |||
| f81d315800 | |||
| 33f5badfd9 | |||
| 0407244cca | |||
| 64449ec38b | |||
| fb937e8ced | |||
| 96f9e8aceb | |||
| be294fbba5 | |||
| aabc676f94 | |||
| 4c867390c2 | |||
| f9c6bb1e56 | |||
| 33ed2796c8 | |||
| c4fb785e55 | |||
| 8d5e6c8940 | |||
| f258b71648 | |||
| f3679aa041 | |||
| 3b02c9df23 | |||
| 1034254613 | |||
| bc3e92c4a1 | |||
| c7dabaa37b | |||
| 69866eaf91 | |||
| 5a8f1d663d | |||
| 2be72776ce | |||
| d92f6ff164 | |||
| 9aaeee9b3d | |||
| b4e94eeabb | |||
| 6f86dd7eef | |||
| 04d001a055 | |||
| f10b08e152 | |||
| 56c8885030 |
@ -72,6 +72,7 @@ android_build:
|
||||
only:
|
||||
- dev
|
||||
- dev-5.29.0
|
||||
- dev-5.30.0
|
||||
|
||||
# 代码检查
|
||||
sonarqube_analysis:
|
||||
@ -103,6 +104,7 @@ sonarqube_analysis:
|
||||
only:
|
||||
- dev
|
||||
- dev-5.29.0
|
||||
- dev-5.30.0
|
||||
|
||||
## 发送简易检测结果报告
|
||||
send_sonar_report:
|
||||
@ -121,6 +123,7 @@ send_sonar_report:
|
||||
only:
|
||||
- dev
|
||||
- dev-5.29.0
|
||||
- dev-5.30.0
|
||||
|
||||
oss-upload&send-email:
|
||||
tags:
|
||||
@ -152,4 +155,5 @@ oss-upload&send-email:
|
||||
- /usr/local/bin/python /ci-android-mail.py
|
||||
only:
|
||||
- dev
|
||||
- dev-5.29.0
|
||||
- dev-5.29.0
|
||||
- dev-5.30.0
|
||||
@ -188,6 +188,7 @@ android {
|
||||
buildConfigField "String", "DEV_VAPI_HOST", "\"${DEV_VAPI_HOST}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${DEV_QUICK_LOGIN_APPID}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${DEV_QUICK_LOGIN_APPKEY}\""
|
||||
buildConfigField "String", "CSJ_APPID", "\"${DEV_CSJ_APPID}\""
|
||||
}
|
||||
|
||||
// publish, 发布时候使用的 flavor,接口仅包含正式环境
|
||||
@ -199,6 +200,7 @@ android {
|
||||
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
|
||||
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
|
||||
}
|
||||
|
||||
tea {
|
||||
@ -209,6 +211,7 @@ android {
|
||||
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
|
||||
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
|
||||
|
||||
manifestPlaceholders.put("APPLOG_SCHEME", "rangersapplog.byAx6uYt".toLowerCase())
|
||||
}
|
||||
@ -221,6 +224,7 @@ android {
|
||||
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
|
||||
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
|
||||
}
|
||||
|
||||
gdt {
|
||||
@ -231,6 +235,7 @@ android {
|
||||
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
|
||||
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -338,12 +343,19 @@ dependencies {
|
||||
implementation(project(':module_sensors_data')) {
|
||||
exclude group: 'androidx.swiperefreshlayout'
|
||||
}
|
||||
implementation(project(':module_message')) {
|
||||
exclude group: 'androidx.swiperefreshlayout'
|
||||
}
|
||||
// implementation(project(':feature:vpn'))
|
||||
implementation(project(':feature:pkg'))
|
||||
implementation(project(':feature:oaid'))
|
||||
implementation(project(':feature:floating-window'))
|
||||
implementation(project(':feature:csj_ad'))
|
||||
// implementation(project(':feature:beizi_startup_ad'))
|
||||
implementation(project(':feature:xapk-installer'))
|
||||
implementation(project(':feature:qq_game')) {
|
||||
exclude group: 'androidx.swiperefreshlayout'
|
||||
}
|
||||
}
|
||||
|
||||
File propFile = file('sign.properties')
|
||||
|
||||
@ -77,7 +77,12 @@
|
||||
androidx.compose.animation.core,
|
||||
androidx.constraintlayout.compose,
|
||||
androidx.compose.ui.test.manifest,
|
||||
androidx.compose.ui.tooling.preview" />
|
||||
com.bytedance.sdk.openadsdk,
|
||||
androidx.compose.ui.tooling.preview,
|
||||
com.tencent.qqmini,
|
||||
com.tencent.qqmini.minigame.external,
|
||||
com.tencent.qqmini.minigame.opensdk,
|
||||
com.tencent.qqmini.union.ad" />
|
||||
|
||||
<!-- 去掉 SDK 一些流氓权限 -->
|
||||
<uses-permission
|
||||
@ -297,10 +302,6 @@
|
||||
android:name="com.gh.gamecenter.CollectionActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.MessageActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.UserInfoEditActivity"
|
||||
android:screenOrientation="portrait"
|
||||
@ -314,26 +315,10 @@
|
||||
android:name="com.gh.gamecenter.qa.answer.edit.AnswerEditActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.ConcernInfoActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.InfoActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.MessageKeFuActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.MessageInviteActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.MessageVoteActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".qa.questions.invite.QuestionsInviteActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
@ -760,6 +745,18 @@
|
||||
android:name="com.gh.gamecenter.gamecollection.hotlist.GameCollectionHotListActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.qgame.QGameHomeWrapperActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.qgame.QGameSearchActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.qgame.QGameSubjectActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
|
||||
<!-- <activity-->
|
||||
<!-- android:name="${applicationId}.douyinapi.DouYinEntryActivity"-->
|
||||
@ -843,39 +840,6 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- 梦工厂配置 开始 -->
|
||||
<!--<meta-data
|
||||
android:name="MGC_APPID"
|
||||
android:value="1001276" />
|
||||
|
||||
<provider
|
||||
android:name="com.leto.game.base.provider.LetoFileProvider"
|
||||
android:authorities="${applicationId}.leto.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/leto_file_path"
|
||||
tools:replace="android:resource" />
|
||||
</provider>-->
|
||||
<!-- 梦工厂配置 结束 -->
|
||||
|
||||
<!-- 穿山甲配置 开始 -->
|
||||
<!--<provider
|
||||
android:name="com.bytedance.sdk.openadsdk.TTFileProvider"
|
||||
android:authorities="${applicationId}.TTFileProvider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
|
||||
<provider
|
||||
android:name="com.bytedance.sdk.openadsdk.multipro.TTMultiProvider"
|
||||
android:authorities="${applicationId}.TTMultiProvider"
|
||||
android:exported="false" />-->
|
||||
<!-- 穿山甲配置 结束 -->
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
445
app/src/main/java/com/gh/ad/AdDelegateHelper.kt
Normal file
445
app/src/main/java/com/gh/ad/AdDelegateHelper.kt
Normal file
@ -0,0 +1,445 @@
|
||||
package com.gh.ad
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
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.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.MainActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.retrofit.BiResponse
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.provider.IBeiziAdProvider
|
||||
import com.gh.gamecenter.core.provider.ICsjAdProvider
|
||||
import com.gh.gamecenter.core.utils.CurrentActivityHolder
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.core.utils.TimeUtils.getToday
|
||||
import com.gh.gamecenter.entity.AdConfig
|
||||
import com.gh.gamecenter.entity.StartupAdEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent.Companion.createEvent
|
||||
import com.gh.gamecenter.feature.exposure.ExposureSource
|
||||
import com.gh.gamecenter.feature.exposure.ExposureType
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
/**
|
||||
* 广告实现代理类
|
||||
*
|
||||
* 由它来分发功能实现到具体的实现
|
||||
*
|
||||
* 以最复杂的开屏广告为例,有三种实现(1. 自有的广告实现 2. 穿山甲的开屏广告实现 3. Beizi 的开屏广告实现)
|
||||
*
|
||||
* 由于两个广告 SDK 有可能在一次启动中都被使用,所以会根据获取到的广告配置 config 来决定是否需要出是很好两个 SDK
|
||||
*/
|
||||
object AdDelegateHelper {
|
||||
|
||||
private var mCsjAdImpl: ICsjAdProvider? = null
|
||||
private var mBeiziAdImpl: IBeiziAdProvider? = null
|
||||
|
||||
private var mAdConfigList: ArrayList<AdConfig>? = null
|
||||
|
||||
private var mSplashAd: AdConfig? = null
|
||||
private var mDownloadManagerAd: AdConfig? = null
|
||||
private val mGameSearchAdList: ArrayList<AdConfig> by lazy { arrayListOf() }
|
||||
private var mVGameLaunchAd: AdConfig? = null
|
||||
|
||||
private var mIsCsjRequired: Boolean = false // 是否需要初始化穿山甲 SDK
|
||||
private var mIsBeiziRequired: Boolean = false // 师傅需要初始化 Beizi SDK
|
||||
|
||||
private const val AD_SDK_CSJ = "穿山甲"
|
||||
private const val AD_SDK_BEIZI = "倍孜"
|
||||
private const val AD_TYPE_SDK = "third_party_ads" // 第三方 SDK 广告
|
||||
|
||||
private const val KEY_CACHE_CONFIG = "cache_config" // 放在 SP 里的广告缓存(避免接口加载问题)
|
||||
|
||||
private val mAdConfigSp: SharedPreferences by lazy {
|
||||
HaloApp.getInstance().getSharedPreferences("AdConfig", Context.MODE_PRIVATE)
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求接口获取广告相关配置
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
fun requestAdConfig(context: Context, isFromRetry: Boolean) {
|
||||
// mAdConfigList 不为空不需要重试
|
||||
if (isFromRetry && mAdConfigList != null) {
|
||||
return
|
||||
}
|
||||
|
||||
RetrofitManager.getInstance()
|
||||
.newApi
|
||||
.adConfig
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(object : BiResponse<List<AdConfig>>() {
|
||||
override fun onSuccess(data: List<AdConfig>) {
|
||||
handleAdConfig(context, data)
|
||||
|
||||
// 缓存数据到 SP 供接口请求失败用
|
||||
SPUtils.setString(mAdConfigSp, KEY_CACHE_CONFIG, data.toJson())
|
||||
}
|
||||
|
||||
override fun onFailure(exception: Exception) {
|
||||
super.onFailure(exception)
|
||||
|
||||
// 若接口请求失败时,从 SP 里获取上次缓存的数据
|
||||
val cachedConfig: List<AdConfig>? = SPUtils.getString(mAdConfigSp, KEY_CACHE_CONFIG).toObject()
|
||||
if (cachedConfig != null) {
|
||||
handleAdConfig(context, cachedConfig)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取搜索页的广告列表
|
||||
*/
|
||||
fun getGameSearchAdList(): ArrayList<AdConfig> {
|
||||
return mGameSearchAdList
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下载管理页的广告
|
||||
*/
|
||||
fun getDownloadManagerAd(): AdConfig? {
|
||||
return mDownloadManagerAd
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理广告配置
|
||||
*/
|
||||
fun handleAdConfig(context: Context, configList: List<AdConfig>) {
|
||||
for (config in configList) {
|
||||
// 处理返回的数据
|
||||
when (config.location) {
|
||||
"halo_launch" -> mSplashAd = config
|
||||
"download_manager" -> mDownloadManagerAd = config
|
||||
"game_search" -> config.let { mGameSearchAdList.add(it) }
|
||||
"helper_launch" -> mVGameLaunchAd = config
|
||||
}
|
||||
|
||||
// 根据返回的值里判断是否含有 Beizi 的广告
|
||||
if (!mIsBeiziRequired) {
|
||||
if (config.thirdPartyAd?.sourceName == AD_SDK_BEIZI) {
|
||||
mIsBeiziRequired = true
|
||||
}
|
||||
}
|
||||
|
||||
// 根据返回的值里判断是否含有 穿山甲 的广告
|
||||
if (!mIsCsjRequired) {
|
||||
if (config.thirdPartyAd?.sourceName == AD_SDK_CSJ) {
|
||||
mIsCsjRequired = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化 Beizi
|
||||
if (mIsBeiziRequired && mBeiziAdImpl == null) {
|
||||
mBeiziAdImpl =
|
||||
ARouter.getInstance().build(RouteConsts.provider.beiziAd).navigation() as? IBeiziAdProvider
|
||||
mBeiziAdImpl?.initSDK(context)
|
||||
}
|
||||
|
||||
// 初始化穿山甲
|
||||
if (mIsCsjRequired && mCsjAdImpl == null) {
|
||||
mCsjAdImpl =
|
||||
ARouter.getInstance().build(RouteConsts.provider.csjAd).navigation() as? ICsjAdProvider
|
||||
mCsjAdImpl?.initSDK(context, BuildConfig.CSJ_APPID, HaloApp.getInstance().oaid)
|
||||
// 监听亮色/暗色模式切换
|
||||
DarkModeUtils.registerModeChangeListener {
|
||||
val topActivity = CurrentActivityHolder.getCurrentActivity() ?: return@registerModeChangeListener
|
||||
updateThemeStatus(context, DarkModeUtils.isDarkModeOn(topActivity))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否需要显示开屏广告
|
||||
*/
|
||||
fun shouldShowStartUpAd(): Boolean {
|
||||
return mSplashAd != null
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新主题样式
|
||||
*/
|
||||
private fun updateThemeStatus(context: Context, isDarkMode: Boolean) {
|
||||
mCsjAdImpl?.updateThemeStatus(context, isDarkMode)
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求开屏广告
|
||||
*/
|
||||
@JvmStatic
|
||||
fun requestSplashAd(
|
||||
activity: Activity,
|
||||
adViewWidthInPx: Int,
|
||||
adViewHeightInPx: Int,
|
||||
adViewWidthInDp: Float,
|
||||
adViewHeightInDp: Float,
|
||||
startAdContainer: ViewGroup,
|
||||
sdkStartAdContainer: ViewGroup,
|
||||
adsViewGroup: FrameLayout,
|
||||
handler: BaseActivity.BaseHandler,
|
||||
hideCallback: () -> Unit
|
||||
) {
|
||||
if (mSplashAd != null) {
|
||||
if (mSplashAd!!.displayRule.adSource == AD_TYPE_SDK) {
|
||||
// 第三方开屏广告回调,失败时根据接口配置选项决定是否显示自有开屏广告
|
||||
val sdkSplashCallback: (isSuccess: Boolean) -> Unit = { isSuccess ->
|
||||
if (isSuccess) {
|
||||
hideCallback.invoke()
|
||||
} else {
|
||||
if (mSplashAd?.displayRule?.onFailedAction == "show") {
|
||||
sdkStartAdContainer.visibility = View.GONE
|
||||
requestStandardSplashAd(mSplashAd!!.ownerAd, startAdContainer, handler, hideCallback)
|
||||
} else {
|
||||
hideCallback.invoke()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 第三方广告的数据为空,按加载失败处理
|
||||
if (mSplashAd?.thirdPartyAd == null) {
|
||||
sdkSplashCallback.invoke(false)
|
||||
return
|
||||
}
|
||||
|
||||
if (mSplashAd?.thirdPartyAd?.sourceName == AD_SDK_BEIZI) {
|
||||
sdkStartAdContainer.visibility = View.VISIBLE
|
||||
requestBeiziSplashAd(sdkStartAdContainer, adsViewGroup, adViewWidthInPx, adViewHeightInPx, sdkSplashCallback)
|
||||
} else if (mSplashAd?.thirdPartyAd?.sourceName == AD_SDK_CSJ) {
|
||||
sdkStartAdContainer.visibility = View.VISIBLE
|
||||
requestCsjSplashAd(
|
||||
activity,
|
||||
mSplashAd?.thirdPartyAd?.slotId ?: "unknown",
|
||||
adViewWidthInPx,
|
||||
adViewHeightInPx,
|
||||
adViewWidthInDp,
|
||||
adViewHeightInDp,
|
||||
sdkStartAdContainer,
|
||||
sdkSplashCallback
|
||||
)
|
||||
}
|
||||
} else {
|
||||
requestStandardSplashAd(mSplashAd!!.ownerAd, startAdContainer, handler, hideCallback)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取穿山甲的开屏广告
|
||||
*/
|
||||
private fun requestCsjSplashAd(
|
||||
activity: Activity,
|
||||
slotId: String,
|
||||
adViewWidthInPx: Int,
|
||||
adViewHeightInPx: Int,
|
||||
adViewWidthInDp: Float,
|
||||
adViewHeightInDp: Float,
|
||||
startAdContainer: ViewGroup,
|
||||
callback: (isSuccess: Boolean) -> Unit,
|
||||
) {
|
||||
if (mCsjAdImpl == null) {
|
||||
callback.invoke(false)
|
||||
} else {
|
||||
mCsjAdImpl?.requestSplashAd(
|
||||
activity,
|
||||
slotId,
|
||||
adViewWidthInPx,
|
||||
adViewHeightInPx,
|
||||
adViewWidthInDp,
|
||||
adViewHeightInDp,
|
||||
startAdContainer,
|
||||
callback,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Beizi 的开屏广告
|
||||
*/
|
||||
private fun requestBeiziSplashAd(
|
||||
startAdContainer: View,
|
||||
adsFl: FrameLayout,
|
||||
adViewWidthInPx: Int,
|
||||
adViewHeightInPx: Int,
|
||||
callback: (isSuccess: Boolean) -> Unit,
|
||||
) {
|
||||
if (mBeiziAdImpl == null) {
|
||||
callback.invoke(false)
|
||||
} else {
|
||||
mBeiziAdImpl?.requestSplashAd(startAdContainer, adsFl, adViewWidthInPx, adViewHeightInPx, callback)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示自有的开屏广告
|
||||
*/
|
||||
private fun requestStandardSplashAd(
|
||||
splashAd: StartupAdEntity?,
|
||||
startAdContainer: ViewGroup,
|
||||
handler: BaseActivity.BaseHandler,
|
||||
hideCallback: () -> Unit
|
||||
) {
|
||||
if (splashAd == null) {
|
||||
hideCallback.invoke()
|
||||
return
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(splashAd.img)) {
|
||||
val showedTodayTimestamp = SPUtils.getString(Constants.SP_STARTUP_AD_TIMESTAMP, "") ?: ""
|
||||
when (splashAd.rule) {
|
||||
"each" -> showStandardSplashAd(splashAd, startAdContainer, handler, hideCallback)
|
||||
"once" -> if (TextUtils.isEmpty(showedTodayTimestamp)
|
||||
|| !showedTodayTimestamp.contains(splashAd.id)
|
||||
) {
|
||||
showStandardSplashAd(splashAd, startAdContainer, handler, hideCallback)
|
||||
} else {
|
||||
hideCallback.invoke()
|
||||
}
|
||||
|
||||
"everyday" -> {
|
||||
val today = getToday()
|
||||
if (TextUtils.isEmpty(showedTodayTimestamp)
|
||||
|| !showedTodayTimestamp.contains(today)
|
||||
|| !showedTodayTimestamp.contains(splashAd.id)
|
||||
) {
|
||||
showStandardSplashAd(splashAd, startAdContainer, handler, hideCallback)
|
||||
} else {
|
||||
hideCallback.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
else -> hideCallback.invoke()
|
||||
}
|
||||
SPUtils.setString(Constants.SP_STARTUP_AD_TIMESTAMP, splashAd.id + getToday())
|
||||
} else {
|
||||
hideCallback.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
private fun showStandardSplashAd(
|
||||
ad: StartupAdEntity,
|
||||
startAdContainer: ViewGroup,
|
||||
handler: BaseActivity.BaseHandler,
|
||||
hideCallback: () -> Unit
|
||||
) {
|
||||
val jumpBtn: View = startAdContainer.findViewById(R.id.jumpBtn)
|
||||
val jumpDetailBtn: TextView = startAdContainer.findViewById(R.id.jumpDetailBtn)
|
||||
val adImage: SimpleDraweeView = startAdContainer.findViewById(R.id.adImage)
|
||||
startAdContainer.visibility = View.VISIBLE
|
||||
jumpDetailBtn.text = ad.desc
|
||||
jumpDetailBtn.setDrawableEnd(
|
||||
AppCompatResources.getDrawable(
|
||||
startAdContainer.context,
|
||||
R.drawable.ic_startup_ad_arrow
|
||||
), null, null
|
||||
)
|
||||
ImageUtils.display(adImage, ad.img)
|
||||
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 "")!!
|
||||
)
|
||||
}
|
||||
val sources: MutableList<ExposureSource> = ArrayList()
|
||||
sources.add(ExposureSource("开屏广告", ad.id))
|
||||
val event = createEvent(null, sources, null, ExposureType.EXPOSURE)
|
||||
ExposureManager.log(event)
|
||||
if (ad.button) {
|
||||
jumpDetailBtn.setOnClickListener { v: View ->
|
||||
directToLinkPage(v.context, ad.jump, "(启动广告)", "", event)
|
||||
v.postDelayed({
|
||||
handler.removeMessages(MainActivity.COUNTDOWN_AD)
|
||||
hideCallback.invoke()
|
||||
}, 1000)
|
||||
}
|
||||
jumpDetailBtn.visibility = View.VISIBLE
|
||||
LogUtils.logStartAd("watch_start_ads", ad)
|
||||
} else {
|
||||
LogUtils.logStartAd("start_ads", ad)
|
||||
}
|
||||
handler.sendEmptyMessageDelayed(MainActivity.COUNTDOWN_AD, 1000)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取信息流广告
|
||||
*/
|
||||
fun requestFlowAd(
|
||||
fragment: Fragment,
|
||||
slotId: String,
|
||||
adContainerView: ViewGroup,
|
||||
expressViewWidth: Float,
|
||||
callback: (isSuccess: Boolean) -> Unit,
|
||||
) {
|
||||
mCsjAdImpl?.requestFlowAd(fragment, adContainerView, slotId, expressViewWidth, callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Banner 广告
|
||||
*/
|
||||
fun requestBannerAd(
|
||||
fragment: Fragment,
|
||||
containerView: ViewGroup,
|
||||
ad: AdConfig.ThirdPartyAd,
|
||||
expressViewWidthInDp: Float,
|
||||
callback: (isSuccess: Boolean) -> Unit
|
||||
) {
|
||||
|
||||
val slotId = ad.slotId
|
||||
val displayRatio: Float = if (ad.displaySize.isEmpty()) {
|
||||
2F
|
||||
} else {
|
||||
val array = ad.displaySize.split("*")
|
||||
if (array.size == 2) {
|
||||
array[0].toFloat() / array[1].toFloat()
|
||||
} else {
|
||||
2F
|
||||
}
|
||||
}
|
||||
val expressViewHeightInDp = expressViewWidthInDp / displayRatio
|
||||
|
||||
mCsjAdImpl?.requestBannerAd(
|
||||
fragment,
|
||||
containerView,
|
||||
slotId,
|
||||
expressViewWidthInDp,
|
||||
expressViewHeightInDp,
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消开屏广告
|
||||
*/
|
||||
fun cancelSplashAd(context: Context) {
|
||||
mBeiziAdImpl?.cancelSplashAd(context)
|
||||
mCsjAdImpl?.cancelSplashAd(context)
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,18 +1,20 @@
|
||||
package com.gh.base
|
||||
|
||||
import android.graphics.Typeface
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.DownloadManagerActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.activity.ToolBarActivity
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.common.utils.viewModelProvider
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.core.utils.SPUtils.getBoolean
|
||||
import com.gh.gamecenter.entity.GameUpdateEntity
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
@ -58,6 +60,7 @@ abstract class DownloadToolbarActivity : ToolBarActivity() {
|
||||
}
|
||||
val downloadMenuView = mActionMenuView.menu.findItem(R.id.menu_download).actionView
|
||||
mDownloadCountHint = downloadMenuView?.findViewById(R.id.menu_download_count_hint)
|
||||
mDownloadCountHint?.typeface = Typeface.createFromAsset(assets, "fonts/d_din_bold_only_number.ttf")
|
||||
}
|
||||
|
||||
override fun onMenuItemClick(item: MenuItem?): Boolean {
|
||||
@ -74,19 +77,27 @@ abstract class DownloadToolbarActivity : ToolBarActivity() {
|
||||
if (mDownloadCountHint == null) return
|
||||
val count = DownloadManager.getInstance().getDownloadOrUpdateCount(updateList)
|
||||
if (count != null) {
|
||||
mDownloadCountHint!!.visibility = View.VISIBLE
|
||||
mDownloadCountHint!!.text = count
|
||||
val params = mDownloadCountHint!!.layoutParams
|
||||
if (TextUtils.isEmpty(count)) {
|
||||
params.width = DisplayUtils.dip2px(6f)
|
||||
params.height = DisplayUtils.dip2px(6f)
|
||||
} else {
|
||||
params.width = DisplayUtils.dip2px(12f)
|
||||
params.height = DisplayUtils.dip2px(12f)
|
||||
}
|
||||
mDownloadCountHint!!.layoutParams = params
|
||||
mDownloadCountHint?.visibility = View.VISIBLE
|
||||
mDownloadCountHint?.text = count
|
||||
val params = mDownloadCountHint?.layoutParams
|
||||
params?.width = if (count.isEmpty()) 6F.dip2px() else ConstraintLayout.LayoutParams.WRAP_CONTENT
|
||||
params?.height = if (count.isEmpty()) 6F.dip2px() else 14F.dip2px()
|
||||
(params as? ViewGroup.MarginLayoutParams)?.setMargins(
|
||||
0,
|
||||
if (count.isEmpty()) 0 else (-4F).dip2px(),
|
||||
if (count.isEmpty()) (-4F).dip2px() else (-8F).dip2px(),
|
||||
0
|
||||
)
|
||||
mDownloadCountHint?.setPadding(
|
||||
if (count.isEmpty()) 0 else 4F.dip2px(),
|
||||
0,
|
||||
if (count.isEmpty()) 0 else 4F.dip2px(),
|
||||
0
|
||||
)
|
||||
mDownloadCountHint?.minWidth = if (count.isEmpty()) 0 else 14F.dip2px()
|
||||
mDownloadCountHint?.layoutParams = params
|
||||
} else {
|
||||
mDownloadCountHint!!.visibility = View.GONE
|
||||
mDownloadCountHint?.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -68,6 +68,7 @@ class DefaultJsApi(
|
||||
val entrance: String = "",
|
||||
private var mFragment: Fragment? = null,
|
||||
private var mBbsId: String? = "",
|
||||
private var mOriginUrl: String?= "",
|
||||
) {
|
||||
|
||||
private var mLoginHandler: CompletionHandler<Any>? = null
|
||||
@ -632,12 +633,19 @@ class DefaultJsApi(
|
||||
fun logExposure(event: Any) {
|
||||
val simpleExposureEvent = event.toString().toObject() ?: SimpleExposureEvent()
|
||||
if (simpleExposureEvent.id.isNotEmpty()) {
|
||||
val exposureSource = ExposureSource("游戏活动", "${simpleExposureEvent.title}+${simpleExposureEvent.id}")
|
||||
val sourceKey = if (mOriginUrl?.contains(Constants.URL_QUERY_FROM_FLOATING_WINDOW) == true) {
|
||||
"落地页"
|
||||
} else {
|
||||
"游戏活动"
|
||||
}
|
||||
|
||||
val exposureSource = ExposureSource(sourceKey, "${simpleExposureEvent.title}+${simpleExposureEvent.id}")
|
||||
mExposureEvent = ExposureEvent.createEvent(
|
||||
gameEntity = null,
|
||||
source = arrayListOf(exposureSource),
|
||||
)
|
||||
ExposureManager.log(mExposureEvent!!)
|
||||
ExposureManager.commitSavedExposureEvents(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -84,11 +84,6 @@ object FixedRateJobHelper {
|
||||
VideoRecordUtils.commitVideoRecord()
|
||||
}
|
||||
|
||||
// 获取启动广告 (第一次不需要获取)
|
||||
if (elapsedTime % STARTUP_AD == 0L && mExecuteCount != 0) {
|
||||
AdHelper.getSettingAdCache()
|
||||
}
|
||||
|
||||
mExecuteCount++
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
package com.gh.common.chain
|
||||
|
||||
import android.content.Context
|
||||
import com.gh.common.util.DialogUtils
|
||||
import com.gh.common.util.DirectUtils
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
|
||||
class LandPageAddressHandler : ChainHandler() {
|
||||
|
||||
override fun handleRequest(context: Context, gameEntity: GameEntity) {
|
||||
if (gameEntity.isLandPageAddressDialog()) {
|
||||
DialogUtils.showLandPageAddressDialog(context, gameEntity) {// 跳转第三方落地页
|
||||
DirectUtils.directToExternalBrowser(context, gameEntity.landPageAddressDialog!!.link!!)
|
||||
}
|
||||
} else {
|
||||
if (hasNext()) {
|
||||
getNext()?.handleRequest(context, gameEntity)
|
||||
} else {
|
||||
processEndCallback?.invoke(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,7 +7,15 @@ import com.gh.gamecenter.feature.entity.GameEntity
|
||||
class OverseaDownloadHandler : ChainHandler() {
|
||||
|
||||
override fun handleRequest(context: Context, gameEntity: GameEntity) {
|
||||
DialogUtils.showOverseaDownloadDialog(context, gameEntity) {
|
||||
if (gameEntity.isOverseaAddressDialog()) {
|
||||
DialogUtils.showOverseaDownloadDialog(context, gameEntity) {// 跳转海外下载地址弹窗
|
||||
if (hasNext()) {
|
||||
getNext()?.handleRequest(context, gameEntity)
|
||||
} else {
|
||||
processEndCallback?.invoke(null)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (hasNext()) {
|
||||
getNext()?.handleRequest(context, gameEntity)
|
||||
} else {
|
||||
|
||||
@ -459,7 +459,6 @@ public class Config {
|
||||
DarkModeUtils.INSTANCE.updateFollowSystemDarkModeToSp(true);
|
||||
DarkModeUtils.INSTANCE.initDarkMode();
|
||||
}
|
||||
AdHelper.prefetchStartUpAd(mNewApiSettingsEntity);
|
||||
SPUtils.setString(Constants.SP_NEW_API_SETTINGS, GsonUtils.toJson(data));
|
||||
}
|
||||
});
|
||||
|
||||
@ -28,6 +28,7 @@ import com.gh.common.chain.CheckDownloadHandler;
|
||||
import com.gh.common.chain.CheckStoragePermissionHandler;
|
||||
import com.gh.common.chain.DownloadDialogHelperHandler;
|
||||
import com.gh.common.chain.GamePermissionHandler;
|
||||
import com.gh.common.chain.LandPageAddressHandler;
|
||||
import com.gh.common.chain.OverseaDownloadHandler;
|
||||
import com.gh.common.chain.PackageCheckHandler;
|
||||
import com.gh.common.chain.UnsupportedFeatureHandler;
|
||||
@ -412,6 +413,7 @@ public class BindingAdapters {
|
||||
builder.addHandler(new DownloadDialogHelperHandler());
|
||||
builder.addHandler(new CertificationHandler());
|
||||
builder.addHandler(new VersionNumberHandler());
|
||||
builder.addHandler(new LandPageAddressHandler());
|
||||
builder.addHandler(new OverseaDownloadHandler());
|
||||
builder.addHandler(new CheckDownloadHandler());
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ 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.entity.NewsEntity
|
||||
import com.gh.gamecenter.feature.entity.User
|
||||
import com.gh.gamecenter.qa.entity.AnswerDetailEntity
|
||||
import com.gh.gamecenter.qa.entity.ArticleDetailEntity
|
||||
|
||||
|
||||
@ -19,6 +19,10 @@ class AppProviderImpl : IAppProvider {
|
||||
return HaloApp.getInstance().getString(R.string.app_name)
|
||||
}
|
||||
|
||||
override fun getAppVersion(): String {
|
||||
return BuildConfig.VERSION_NAME
|
||||
}
|
||||
|
||||
override fun getGid(): String {
|
||||
return HaloApp.getInstance().gid ?: ""
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
@ -24,6 +25,14 @@ class BindingAdaptersProviderImpl : IBindingAdaptersProvider {
|
||||
BindingAdapters.setGameTags(layout, gameEntity)
|
||||
}
|
||||
|
||||
override fun setMessageUnread(view: TextView, unreadCount: Int) {
|
||||
BindingAdapters.setMessageUnread(view, unreadCount)
|
||||
}
|
||||
|
||||
override fun setGame(view: View, gameEntity: GameEntity) {
|
||||
BindingAdapters.setGame(view, gameEntity)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Parcelable
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.CommentDetailActivity
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.provider.ICommentDetailProvider
|
||||
import com.gh.gamecenter.feature.entity.MessageEntity
|
||||
|
||||
@Route(path = RouteConsts.provider.commentDetail, name = "CommentDetailActivity暴露服务")
|
||||
class CommentDetailProviderImpl : ICommentDetailProvider {
|
||||
|
||||
override fun getIntent(context: Context, commentId: String?, message: Parcelable): Intent {
|
||||
return CommentDetailActivity.getIntent(context, commentId, message as MessageEntity.Article)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.ICommentManagerProvider
|
||||
import com.gh.gamecenter.manager.CommentManager
|
||||
|
||||
@Route(path = RouteConsts.provider.commentManager, name = "CommentManager暴露服务")
|
||||
class CommentManagerProviderImpl : ICommentManagerProvider {
|
||||
override fun addUrl(ids: String) {
|
||||
CommentManager.getInstance().addUrl(ids)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.TextView
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.util.CommentUtils
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.provider.ICommentUtilsProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.commentUtils, name = "CommentUtils暴露服务")
|
||||
class CommentUtilsProviderImpl : ICommentUtilsProvider {
|
||||
override fun setCommentTime(textView: TextView, time: Long) {
|
||||
CommentUtils.setCommentTime(textView, time)
|
||||
}
|
||||
|
||||
override fun getCommentTime(timestamp: Long): String {
|
||||
return CommentUtils.getCommentTime(timestamp)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.LinearLayout
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.util.ConcernContentUtils
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.IConcernContentUtilsProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.concernContentUtils, name = "ConcernContentUtils暴露服务")
|
||||
class ConcernContentUtilsProviderImpl : IConcernContentUtilsProvider {
|
||||
override fun addContentPic(
|
||||
context: Context,
|
||||
linearLayout: LinearLayout,
|
||||
list: List<String>,
|
||||
entrance: String,
|
||||
width: Int
|
||||
) {
|
||||
ConcernContentUtils.addContentPic(context, linearLayout, list, entrance, width)
|
||||
}
|
||||
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.ConcernActivity
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.IConcernProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.concernActivity, name = "ConcernActivity暴露服务")
|
||||
class ConcernProviderImpl : IConcernProvider {
|
||||
|
||||
override fun getIntent(context: Context, entrance: String): Intent {
|
||||
return ConcernActivity.getIntent(context, entrance)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.entity.SettingsEntity
|
||||
import com.gh.gamecenter.feature.provider.IConfigSettingProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.configSetting, name = "Config.getSettings暴露服务")
|
||||
class ConfigSettingProviderImpl : IConfigSettingProvider {
|
||||
override fun getSettings(): SettingsEntity? {
|
||||
return Config.getSettings()
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.util.DataCollectionUtils
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.provider.IDataCollectionProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.dataCollection, name = "DataCollectionUtils暴露服务")
|
||||
class DataCollectionProviderImpl : IDataCollectionProvider {
|
||||
override fun uploadClick(context: Context, vararg args: String) {
|
||||
DataCollectionUtils.uploadClick(context, *args)
|
||||
}
|
||||
|
||||
override fun uploadConcern(context: Context, vararg args: String) {
|
||||
DataCollectionUtils.uploadConcern(context, *args)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -69,6 +69,56 @@ class DirectProviderImpl : IDirectProvider {
|
||||
return DirectUtils.directToQqGroup(context, groupNumber)
|
||||
}
|
||||
|
||||
override fun directToHomeActivity(context: Context, userId: String?, entrance: String?, path: String?) {
|
||||
DirectUtils.directToHomeActivity(context, userId, entrance, path)
|
||||
}
|
||||
|
||||
override fun directToAnswerDetail(context: Context, id: String, entrance: String?, path: String?) {
|
||||
DirectUtils.directToAnswerDetail(context, id, entrance, path)
|
||||
}
|
||||
|
||||
override fun directToCommunityArticle(
|
||||
context: Context,
|
||||
articleId: String?,
|
||||
communityId: String?,
|
||||
entrance: String?,
|
||||
path: String?
|
||||
) {
|
||||
DirectUtils.directToCommunityArticle(context, articleId, communityId, entrance, path)
|
||||
}
|
||||
|
||||
override fun directToVideoDetail(context: Context, videoId: String, entrance: String?, path: String?) {
|
||||
DirectUtils.directToVideoDetail(context, videoId, entrance, path)
|
||||
}
|
||||
|
||||
override fun directToAmway(context: Context, fixedTopAmwayCommentId: String?, entrance: String?, path: String?) {
|
||||
DirectUtils.directToAmway(context, fixedTopAmwayCommentId, entrance, path)
|
||||
}
|
||||
|
||||
override fun directToOrderCenter(context: Context) {
|
||||
DirectUtils.directToOrderCenter(context)
|
||||
}
|
||||
|
||||
override fun directToOrderDetail(context: Context, orderId: String) {
|
||||
DirectUtils.directToOrderDetail(context, orderId)
|
||||
}
|
||||
|
||||
override fun directToEnergyRecord(context: Context, position: Int) {
|
||||
DirectUtils.directToEnergyRecord(context, position)
|
||||
}
|
||||
|
||||
override fun directToMyPrizePage(context: Context) {
|
||||
DirectUtils.directToMyPrizePage(context)
|
||||
}
|
||||
|
||||
override fun directToWinOrderDetail(context: Context, orderId: String, activityId: String) {
|
||||
DirectUtils.directToWinOrderDetail(context, orderId, activityId)
|
||||
}
|
||||
|
||||
override fun directToQGame(context: Context) {
|
||||
return DirectUtils.directToQGameHome(context)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.provider.IGameCollectionDetailProvider
|
||||
import com.gh.gamecenter.gamecollection.detail.GameCollectionDetailActivity
|
||||
|
||||
@Route(path = RouteConsts.provider.gameCollectionDetail, name = "GameCollectionDetailActivity暴露服务")
|
||||
class GameCollectionDetailProviderImpl : IGameCollectionDetailProvider {
|
||||
override fun getIntent(context: Context, gameCollectionId: String, isFromSquare: Boolean): Intent {
|
||||
return GameCollectionDetailActivity.getIntent(context, gameCollectionId, isFromSquare)
|
||||
}
|
||||
|
||||
override fun getSpecifiedCommentIntent(context: Context, gameCollectionId: String, topCommentId: String): Intent {
|
||||
return GameCollectionDetailActivity.getSpecifiedCommentIntent(context, gameCollectionId, topCommentId)
|
||||
}
|
||||
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,15 @@ import com.gh.gamecenter.feature.provider.IGameDetailProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.gameDetail, name = "GameDetailActivity暴露服务")
|
||||
class GameDetailProviderImpl : IGameDetailProvider {
|
||||
override fun startGameDetailActivity(
|
||||
context: Context,
|
||||
gameEntity: GameEntity?,
|
||||
entrance: String,
|
||||
traceEvent: ExposureEvent?
|
||||
) {
|
||||
GameDetailActivity.startGameDetailActivity(context, gameEntity, entrance, traceEvent)
|
||||
}
|
||||
|
||||
override fun startGameDetailActivity(
|
||||
context: Context,
|
||||
gameId: String,
|
||||
@ -18,6 +27,7 @@ class GameDetailProviderImpl : IGameDetailProvider {
|
||||
) {
|
||||
GameDetailActivity.startGameDetailActivity(context, gameId, entrance, traceEvent)
|
||||
}
|
||||
|
||||
override fun startGameDetailActivity(
|
||||
context: Context,
|
||||
gameEntity: GameEntity?,
|
||||
@ -40,6 +50,30 @@ class GameDetailProviderImpl : IGameDetailProvider {
|
||||
)
|
||||
}
|
||||
|
||||
override fun startGameDetailActivity(
|
||||
context: Context,
|
||||
gameId: String,
|
||||
entrance: String?,
|
||||
defaultTab: Int,
|
||||
isSkipGameComment: Boolean,
|
||||
scrollToLibao: Boolean,
|
||||
openVideoStreaming: Boolean,
|
||||
openPlatformWindow: Boolean,
|
||||
traceEvent: ExposureEvent?
|
||||
) {
|
||||
GameDetailActivity.startGameDetailActivity(
|
||||
context,
|
||||
gameId,
|
||||
entrance,
|
||||
defaultTab,
|
||||
isSkipGameComment,
|
||||
scrollToLibao,
|
||||
openVideoStreaming,
|
||||
openPlatformWindow,
|
||||
traceEvent
|
||||
)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.util.GameTrendsHelper
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.IGameTrendsHelperProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.gameTrendsHelper, name = "GameTrendsHelper暴露服务")
|
||||
class GameTrendsHelperProviderImpl : IGameTrendsHelperProvider {
|
||||
override fun updateReadPostTime() {
|
||||
GameTrendsHelper.updateReadPostTime()
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.util.LibaoUtils
|
||||
import com.gh.common.util.LibaoUtils.PostLibaoListener
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.ILibaoUtilsProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.libaoUtils, name = "LibaoUtils暴露服务")
|
||||
class LibaoUtilsProviderImpl : ILibaoUtilsProvider {
|
||||
override fun getLibaoStatus(ids: String, successCallback: ((Any?) -> Unit)?, failureCallback: (() -> Unit)?) {
|
||||
LibaoUtils.getLibaoStatus(ids, object : PostLibaoListener {
|
||||
override fun postSucceed(response: Any?) {
|
||||
successCallback?.invoke(response)
|
||||
}
|
||||
|
||||
override fun postFailed(error: Throwable?) {
|
||||
failureCallback?.invoke()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,7 @@ import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.util.DirectUtils
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.entity.CommunityEntity
|
||||
import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.gh.gamecenter.common.entity.SimpleGameEntity
|
||||
import com.gh.gamecenter.common.entity.SuggestType
|
||||
@ -62,6 +63,16 @@ class LinkDirectUtilsProviderImpl : ILinkDirectUtilsProvider {
|
||||
DirectUtils.directToSuggestion(context, type, hiddenHint)
|
||||
}
|
||||
|
||||
override fun directToCommunityColumn(
|
||||
context: Context,
|
||||
community: CommunityEntity?,
|
||||
subjectId: String,
|
||||
entrance: String?,
|
||||
path: String?
|
||||
) {
|
||||
DirectUtils.directToCommunityColumn(context, community, subjectId, entrance, path)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.MessageDetailActivity
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.entity.ConcernEntity
|
||||
import com.gh.gamecenter.feature.provider.IMessageDetailProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.messageDetail, name = "MessageDetailActivity暴露服务")
|
||||
class MessageDetailProviderImpl : IMessageDetailProvider {
|
||||
|
||||
override fun getIntentById(
|
||||
context: Context,
|
||||
newsId: String,
|
||||
commentNum: Int,
|
||||
openSoftInput: Boolean,
|
||||
entrance: String
|
||||
): Intent {
|
||||
return MessageDetailActivity.getIntentById(context, newsId, commentNum, openSoftInput, entrance)
|
||||
}
|
||||
|
||||
override fun getIntentByEntity(context: Context, concernEntity: ConcernEntity, entrance: String): Intent? {
|
||||
return MessageDetailActivity.getIntentByEntity(context, concernEntity, entrance)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,13 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.MediatorLiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.IMessageUnreadRepositoryProvider
|
||||
import com.gh.gamecenter.feature.entity.MessageUnreadCount
|
||||
import com.gh.gamecenter.feature.entity.MessageUnreadEntity
|
||||
import com.gh.gamecenter.feature.provider.IMessageUnreadRepositoryProvider
|
||||
import com.gh.gamecenter.message.MessageUnreadRepository
|
||||
|
||||
@Route(path = RouteConsts.provider.messageUnreadRepository, name = "MessageUnreadRepository暴露服务")
|
||||
@ -13,6 +17,22 @@ class MessageUnreadRepositoryProviderImpl : IMessageUnreadRepositoryProvider {
|
||||
MessageUnreadRepository.loadMessageUnreadData()
|
||||
}
|
||||
|
||||
override fun loadMessageUnreadTotal(isRecordData: Boolean) {
|
||||
MessageUnreadRepository.loadMessageUnreadTotal(isRecordData)
|
||||
}
|
||||
|
||||
override fun getUnreadLiveData(): MediatorLiveData<MessageUnreadEntity> {
|
||||
return MessageUnreadRepository.unreadLiveData
|
||||
}
|
||||
|
||||
override fun getZixunConcernLiveData(): MutableLiveData<Boolean> {
|
||||
return MessageUnreadRepository.zixunConcern
|
||||
}
|
||||
|
||||
override fun getMessageUnreadCountLiveData(): MutableLiveData<MessageUnreadCount?> {
|
||||
return MessageUnreadRepository.messageUnreadCountLiveData
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@ -0,0 +1,83 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.provider.INewCommentDetailProvider
|
||||
import com.gh.gamecenter.qa.comment.NewCommentDetailActivity
|
||||
|
||||
@Route(path = RouteConsts.provider.newCommentDetail, name = "NewCommentDetailActivity暴露服务")
|
||||
class NewCommentDetailProviderImpl : INewCommentDetailProvider {
|
||||
|
||||
override fun getAnswerCommentIntent(
|
||||
context: Context,
|
||||
commentId: String,
|
||||
questionId: String,
|
||||
topCommentId: String,
|
||||
entrance: String,
|
||||
path: String
|
||||
): Intent {
|
||||
return NewCommentDetailActivity.getAnswerCommentIntent(
|
||||
context,
|
||||
commentId,
|
||||
questionId,
|
||||
topCommentId,
|
||||
entrance,
|
||||
path
|
||||
)
|
||||
}
|
||||
|
||||
override fun getArticleCommentIntent(
|
||||
context: Context,
|
||||
commentId: String,
|
||||
communityId: String,
|
||||
articleId: String,
|
||||
topCommentId: String,
|
||||
entrance: String,
|
||||
path: String
|
||||
): Intent {
|
||||
return NewCommentDetailActivity.getArticleCommentIntent(
|
||||
context,
|
||||
commentId,
|
||||
communityId,
|
||||
articleId,
|
||||
topCommentId,
|
||||
entrance,
|
||||
path
|
||||
)
|
||||
}
|
||||
|
||||
override fun getVideoCommentIntent(
|
||||
context: Context,
|
||||
commentId: String,
|
||||
videoId: String,
|
||||
topCommentId: String,
|
||||
entrance: String,
|
||||
path: String
|
||||
): Intent {
|
||||
return NewCommentDetailActivity.getVideoCommentIntent(context, commentId, videoId, topCommentId, entrance, path)
|
||||
}
|
||||
|
||||
override fun getGameCollectionCommentIntent(
|
||||
context: Context,
|
||||
commentId: String,
|
||||
gameCollectionId: String,
|
||||
topCommentId: String,
|
||||
entrance: String,
|
||||
path: String
|
||||
): Intent {
|
||||
return NewCommentDetailActivity.getGameCollectionCommentIntent(
|
||||
context,
|
||||
commentId,
|
||||
gameCollectionId,
|
||||
topCommentId,
|
||||
entrance,
|
||||
path
|
||||
)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -33,6 +33,18 @@ class PackageUtilsProviderImpl : IPackageUtilsProvider {
|
||||
return PackageUtils.getSideLoadedInfo()
|
||||
}
|
||||
|
||||
override fun isSignedByGh(context: Context, packageName: String): Boolean {
|
||||
return PackageUtils.isSignedByGh(context, packageName)
|
||||
}
|
||||
|
||||
override fun getInstalledTime(context: Context, packageName: String): Long {
|
||||
return PackageUtils.getInstalledTime(context, packageName)
|
||||
}
|
||||
|
||||
override fun getVersionNameByPackageName(packageName: String): String {
|
||||
return PackageUtils.getVersionNameByPackageName(packageName) ?: ""
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@ -3,7 +3,8 @@ package com.gh.common.provider
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.IPackagesManagerProvider
|
||||
import com.gh.gamecenter.feature.entity.GameInstall
|
||||
import com.gh.gamecenter.feature.provider.IPackagesManagerProvider
|
||||
import com.gh.gamecenter.manager.PackagesManager
|
||||
|
||||
@Route(path = RouteConsts.provider.packagesManager, name = "PackagesManager暴露服务")
|
||||
@ -12,6 +13,10 @@ class PackagesManagerProviderImpl: IPackagesManagerProvider {
|
||||
return PackagesManager.isCanPluggable(gameId, packageName)
|
||||
}
|
||||
|
||||
override fun getFilterSameApkInstalledList(): ArrayList<GameInstall> {
|
||||
return PackagesManager.getFilterSameApkInstalledList()
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@ -30,6 +30,10 @@ class RegionSettingHelperProviderImpl : IRegionSettingHelperProvider {
|
||||
return RegionSettingHelper.getIpInfo()
|
||||
}
|
||||
|
||||
override fun shouldThisGameBeFiltered(gameId: String?): Boolean {
|
||||
return RegionSettingHelper.shouldThisGameBeFiltered(gameId)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.ShareCardPicActivity
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.entity.ConcernEntity
|
||||
import com.gh.gamecenter.feature.provider.IShareCardPicProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.shareCardPicActivity, name = "ShareCardPicActivity暴露服务")
|
||||
class ShareCardPicProviderImpl : IShareCardPicProvider {
|
||||
override fun startShareCardPicActivity(context: Context, concernEntity: ConcernEntity, entrance: String) {
|
||||
ShareCardPicActivity.startShareCardPicActivity(context, concernEntity, entrance)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.ShareCardActivity
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.entity.ConcernEntity
|
||||
import com.gh.gamecenter.feature.provider.IShareCardProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.shareCardActivity, name = "ShareCardActivity暴露服务")
|
||||
class ShareCardProviderImpl : IShareCardProvider {
|
||||
override fun getIntent(context: Context, concernEntity: ConcernEntity, shareContent: String): Intent {
|
||||
return ShareCardActivity.getIntent(context, concernEntity, shareContent)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.provider.ISimpleAnswerDetailProvider
|
||||
import com.gh.gamecenter.qa.answer.detail.SimpleAnswerDetailActivity
|
||||
|
||||
@Route(path = RouteConsts.provider.simpleAnswerDetail, name = "SimpleAnswerDetailActivity暴露服务")
|
||||
class SimpleAnswerDetailProviderImpl : ISimpleAnswerDetailProvider {
|
||||
|
||||
override fun getIntent(context: Context, answerId: String, entrance: String, path: String): Intent {
|
||||
return SimpleAnswerDetailActivity.getIntent(context, answerId, entrance, path)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.provider.ISubjectProvider
|
||||
import com.gh.gamecenter.subject.SubjectActivity
|
||||
|
||||
@Route(path = RouteConsts.provider.subject, name = "SubjectActivity暴露服务")
|
||||
class SubjectProviderImpl : ISubjectProvider {
|
||||
override fun startSubjectActivity(
|
||||
context: Context,
|
||||
id: String?,
|
||||
name: String?,
|
||||
isOrder: Boolean,
|
||||
entrance: String?
|
||||
) {
|
||||
SubjectActivity.startSubjectActivity(context, id, name, isOrder, null, entrance)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.IVisitManagerProvider
|
||||
import com.gh.gamecenter.manager.VisitManager
|
||||
|
||||
@Route(path = RouteConsts.provider.visitManager, name = "VisitManager暴露服务")
|
||||
class VisitManagerProviderImpl : IVisitManagerProvider {
|
||||
override fun updateOkhttpCache(context: Context, newsId: String) {
|
||||
VisitManager.updateOkhttpCache(context, newsId)
|
||||
}
|
||||
|
||||
override fun addUrl(ids: String) {
|
||||
VisitManager.getInstance().addUrl(ids)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -35,6 +35,16 @@ class WebProviderImpl : IWebProvider {
|
||||
return WebActivity.getQAIntent(context, url, title, isWebPageHandleBackPressed, qaType)
|
||||
}
|
||||
|
||||
override fun getIntentByNews(
|
||||
context: Context?,
|
||||
concernLink: String?,
|
||||
concernGameName: String,
|
||||
concernId: String?,
|
||||
entrance: String?
|
||||
): Intent {
|
||||
return WebActivity.getIntentByNews(context, concernLink, concernGameName, concernId, entrance)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@ -19,44 +19,11 @@ object AdHelper {
|
||||
const val LOCATION_SUGGESTION_FUNCTION = "suggestion_function"
|
||||
const val LOCATION_SIMULATOR_GAME = "simulator_game"
|
||||
|
||||
@JvmStatic
|
||||
fun getStartUpAd(): StartupAdEntity? {
|
||||
return Config.getNewApiSettingsEntity()?.startAd
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getStartUp(): StartupAdEntity? {
|
||||
return Config.getNewApiSettingsEntity()?.startup
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun prefetchStartUpAd(settingsEntity: NewApiSettingsEntity) {
|
||||
if (settingsEntity.startAd != null && !settingsEntity.startAd?.img.isNullOrEmpty()) {
|
||||
val screenWidth = DisplayUtils.getScreenWidth()
|
||||
val transformedUrl = ImageUtils.getTransformedUrl(settingsEntity.startAd?.img, screenWidth) ?: return
|
||||
ImageUtils.prefetchToDiskCache(transformedUrl)
|
||||
}
|
||||
}
|
||||
|
||||
fun getSettingAdCache() {
|
||||
RetrofitManager.getInstance().newApi
|
||||
.getSettingAdCache(HaloApp.getInstance().channel)
|
||||
.compose(observableToMain())
|
||||
.subscribe(object : Response<NewApiSettingsEntity>() {
|
||||
override fun onResponse(response: NewApiSettingsEntity?) {
|
||||
super.onResponse(response)
|
||||
val settings = Config.getNewApiSettingsEntity()
|
||||
if (settings != null) {
|
||||
settings.startAd = response?.startAd
|
||||
Config.updateNewApiSettings(settings)
|
||||
if (response != null) {
|
||||
prefetchStartUpAd(response)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun getAd(location: String): SettingsEntity.AD? {
|
||||
val adList = Config.getSettings()?.adList ?: return null
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ import com.gh.gamecenter.common.json.json
|
||||
import com.gh.gamecenter.common.utils.ifLogin
|
||||
import com.gh.gamecenter.common.utils.showAutoOrientation
|
||||
import com.gh.gamecenter.common.view.BugFixedPopupWindow
|
||||
import com.gh.gamecenter.entity.CommentEntity
|
||||
import com.gh.gamecenter.feature.entity.CommentEntity
|
||||
import com.gh.gamecenter.feature.entity.Permissions
|
||||
import com.gh.gamecenter.login.user.UserManager
|
||||
import com.gh.gamecenter.qa.comment.OnCommentOptionClickListener
|
||||
|
||||
@ -29,7 +29,7 @@ import com.gh.gamecenter.common.utils.ImageUtils;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
import com.gh.gamecenter.core.utils.NumberUtils;
|
||||
import com.gh.gamecenter.core.utils.ToastUtils;
|
||||
import com.gh.gamecenter.entity.CommentEntity;
|
||||
import com.gh.gamecenter.feature.entity.CommentEntity;
|
||||
import com.gh.gamecenter.feature.entity.MeEntity;
|
||||
import com.gh.gamecenter.login.entity.UserInfoEntity;
|
||||
import com.gh.gamecenter.login.user.UserManager;
|
||||
|
||||
@ -71,8 +71,8 @@ import com.gh.gamecenter.core.utils.MtaHelper;
|
||||
import com.gh.gamecenter.core.utils.SPUtils;
|
||||
import com.gh.gamecenter.core.utils.SpanBuilder;
|
||||
import com.gh.gamecenter.core.utils.ToastUtils;
|
||||
import com.gh.gamecenter.databinding.DialogAddressConfirmationBinding;
|
||||
import com.gh.gamecenter.databinding.DialogBindPhoneBinding;
|
||||
import com.gh.gamecenter.databinding.DialogOverseaConfirmationBinding;
|
||||
import com.gh.gamecenter.databinding.DialogPackageParseErrorBinding;
|
||||
import com.gh.gamecenter.databinding.DialogRelievePhoneBinding;
|
||||
import com.gh.gamecenter.databinding.DialogReportReasonBinding;
|
||||
@ -732,40 +732,65 @@ public class DialogUtils {
|
||||
public static void showOverseaDownloadDialog(Context context, GameEntity gameEntity, @NonNull ConfirmListener listener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
if (gameEntity.getOverseasAddressDialog() == null
|
||||
|| gameEntity.getApk().size() == 0
|
||||
|| !gameEntity.getOverseasAddressDialog().isEnable()) {
|
||||
listener.onConfirm();
|
||||
} else {
|
||||
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
|
||||
DialogOverseaConfirmationBinding binding = DialogOverseaConfirmationBinding.inflate(LayoutInflater.from(context), null, false);
|
||||
DialogAddressConfirmationBinding binding = DialogAddressConfirmationBinding.inflate(LayoutInflater.from(context), null, false);
|
||||
|
||||
View contentView = binding.getRoot();
|
||||
View contentView = binding.getRoot();
|
||||
|
||||
binding.gameIcon.displayGameIcon(gameEntity);
|
||||
binding.gameNameTv.setText(context.getString(R.string.dialog_oversea_hint, gameEntity.getName()));
|
||||
binding.closeIv.setOnClickListener(v -> dialog.dismiss());
|
||||
binding.gameIcon.displayGameIcon(gameEntity);
|
||||
binding.gameNameTv.setText(context.getString(R.string.dialog_oversea_hint, gameEntity.getName()));
|
||||
binding.closeIv.setOnClickListener(v -> dialog.dismiss());
|
||||
|
||||
if ("show&download".equals(gameEntity.getOverseasAddressDialog().getStatus())) {
|
||||
gameEntity.getApk().get(0).setUrl(gameEntity.getOverseasAddressDialog().getLink());
|
||||
}
|
||||
binding.urlTv.setText(gameEntity.getOverseasAddressDialog().getLink());
|
||||
binding.downloadBtn.setText("下载(" + gameEntity.getApk().get(0).getSize() + ")");
|
||||
binding.downloadBtn.setOnClickListener(v -> {
|
||||
listener.onConfirm();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
if ("show&download".equals(gameEntity.getOverseasAddressDialog().getStatus())) {
|
||||
gameEntity.getApk().get(0).setUrl(gameEntity.getOverseasAddressDialog().getLink());
|
||||
}
|
||||
binding.urlTv.setText(gameEntity.getOverseasAddressDialog().getLink());
|
||||
binding.downloadBtn.setText("下载(" + gameEntity.getApk().get(0).getSize() + ")");
|
||||
binding.downloadBtn.setOnClickListener(v -> {
|
||||
listener.onConfirm();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
// 跳转第三方落地页下载弹窗
|
||||
public static void showLandPageAddressDialog(Context context, GameEntity gameEntity, @NonNull ConfirmListener listener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
|
||||
DialogAddressConfirmationBinding binding = DialogAddressConfirmationBinding.inflate(LayoutInflater.from(context), null, false);
|
||||
|
||||
View contentView = binding.getRoot();
|
||||
|
||||
binding.gameIcon.displayGameIcon(gameEntity);
|
||||
binding.gameNameTv.setText(context.getString(R.string.dialog_land_page_address_hint, gameEntity.getName()));
|
||||
binding.closeIv.setOnClickListener(v -> dialog.dismiss());
|
||||
|
||||
binding.urlTv.setText(gameEntity.getLandPageAddressDialog().getLink());
|
||||
binding.downloadBtn.setText(context.getString(R.string.dialog_land_page_address_confirm));
|
||||
binding.downloadBtn.setOnClickListener(v -> {
|
||||
listener.onConfirm();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public static void showGameH5DownloadDialog(Context context, GameEntity gameEntity, RegionSetting.GameH5Download gameH5Download) {
|
||||
@ -773,7 +798,7 @@ public class DialogUtils {
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
|
||||
DialogOverseaConfirmationBinding binding = DialogOverseaConfirmationBinding.inflate(LayoutInflater.from(context), null, false);
|
||||
DialogAddressConfirmationBinding binding = DialogAddressConfirmationBinding.inflate(LayoutInflater.from(context), null, false);
|
||||
|
||||
View contentView = binding.getRoot();
|
||||
|
||||
@ -1293,11 +1318,13 @@ public class DialogUtils {
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static void showReserveSuccess2WechatBindDialog(Context context, ConfirmListener confirmListener, CancelListener cancelListener) {
|
||||
public static void showReserveOrVoteSuccess2WechatBindDialog(Context context, Boolean isReserve, ConfirmListener confirmListener, CancelListener cancelListener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
|
||||
DialogWechatReserveSuccessBinding binding = DialogWechatReserveSuccessBinding.inflate(LayoutInflater.from(context));
|
||||
binding.titleIv.setImageResource(isReserve ? R.drawable.bg_reserve_success : R.drawable.bg_vote_success);
|
||||
binding.contentTv.setText(isReserve ? "游戏上线时,您将在消息中心收到通知。为了避免错过通知,建议您开启微信公众号提醒": "版本上线时,您将在消息中心收到通知。为了避免错过通知,亦建议您开启微信公众号提醒");
|
||||
binding.closeBtn.setOnClickListener(v -> {
|
||||
cancelListener.onCancel();
|
||||
dialog.dismiss();
|
||||
@ -1318,13 +1345,13 @@ public class DialogUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void showReserveSuccessDialog(Context context) {
|
||||
public static void showReserveOrVoteSuccessDialog(Context context, Boolean isReserve) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
|
||||
DialogAlertDefaultBinding binding = DialogAlertDefaultBinding.inflate(LayoutInflater.from(context));
|
||||
binding.titleTv.setText("游戏预约成功");
|
||||
binding.contentTv.setText("游戏上线时,您将在消息中心和微信公众号收到通知,不会错过任何预约的游戏");
|
||||
binding.titleTv.setText(isReserve ? "游戏预约成功" : "版本投票成功");
|
||||
binding.contentTv.setText(isReserve ? "游戏上线时,您将在消息中心和微信公众号收到通知,不会错过任何预约的游戏" : "版本上线时,您将在消息中心和微信公众号收到通知,不会错过任何投票的版本");
|
||||
binding.confirmTv.setText("我知道了");
|
||||
binding.centerDivider.setVisibility(View.GONE);
|
||||
binding.cancelTv.setVisibility(View.GONE);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
@ -9,6 +10,7 @@ import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.exposure.ExposureManager.log
|
||||
import com.gh.common.exposure.ExposureTraceUtils.appendTrace
|
||||
@ -28,9 +30,9 @@ import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts.*
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.entity.*
|
||||
import com.gh.gamecenter.common.entity.Display
|
||||
import com.gh.gamecenter.common.retrofit.Response
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.provider.IQGameProvider
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.discovery.DiscoveryActivity
|
||||
@ -39,10 +41,12 @@ import com.gh.gamecenter.entity.*
|
||||
import com.gh.gamecenter.eventbus.EBSkip
|
||||
import com.gh.gamecenter.feature.entity.GameDetailServer
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.LibaoEntity
|
||||
import com.gh.gamecenter.feature.entity.MeEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent.Companion.createEvent
|
||||
import com.gh.gamecenter.feature.exposure.ExposureType
|
||||
import com.gh.gamecenter.feature.provider.IConcernInfoProvider
|
||||
import com.gh.gamecenter.forum.detail.ForumDetailActivity
|
||||
import com.gh.gamecenter.forum.home.CommunityHomeFragment
|
||||
import com.gh.gamecenter.forum.search.ForumOrUserSearchActivity
|
||||
@ -68,6 +72,9 @@ import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
|
||||
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.qgame.QGameHomeWrapperActivity
|
||||
import com.gh.gamecenter.qgame.QGameSearchActivity
|
||||
import com.gh.gamecenter.qgame.QGameViewModel
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.gamecenter.servers.GameServerTestActivity
|
||||
import com.gh.gamecenter.servers.GameServersActivity
|
||||
@ -91,7 +98,6 @@ import org.greenrobot.eventbus.EventBus
|
||||
import retrofit2.HttpException
|
||||
import java.net.URLEncoder
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
@ -99,53 +105,6 @@ import kotlin.math.roundToInt
|
||||
*/
|
||||
object DirectUtils {
|
||||
|
||||
/**
|
||||
* 跳转到特定页面,根据 [type] 决定跳转页面,[path] 为跳转前的页面名称
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToSpecificPage(
|
||||
context: Context,
|
||||
type: String,
|
||||
link: String,
|
||||
text: String? = "",
|
||||
entrance: String? = null,
|
||||
path: String? = null
|
||||
) {
|
||||
when (type) {
|
||||
HOST_ARTICLE -> directToArticle(context, id = link, entrance = entrance)
|
||||
|
||||
HOST_GAME -> directToGameDetail(context, id = link, entrance = entrance)
|
||||
|
||||
HOST_GAME_DOWNLOAD -> directToGameDetail(context, id = link, entrance = entrance, autoDownload = true)
|
||||
|
||||
HOST_COLUMN -> directToSubject(context, id = link, subjectName = text, entrance = entrance)
|
||||
|
||||
HOST_QUESTION -> directToQuestionDetail(context, id = link, entrance = entrance, path = path)
|
||||
|
||||
HOST_ANSWER -> directToAnswerDetail(context, id = link, entrance = entrance, path = path)
|
||||
|
||||
HOST_WEB -> directToWebView(context, url = link, entrance = entrance)
|
||||
|
||||
HOST_DOWNLOAD -> directToDownloadManagerAndStartDownload(
|
||||
context,
|
||||
gameId = link,
|
||||
packageName = text,
|
||||
entrance = entrance
|
||||
)
|
||||
|
||||
HOST_UPDATE -> directToDownloadManagerAndStartUpdate(
|
||||
context,
|
||||
gameId = link,
|
||||
packageName = text,
|
||||
entrance = entrance
|
||||
)
|
||||
|
||||
HOST_LIBAO -> directToGiftDetail(context, giftId = link, entrance = entrance)
|
||||
|
||||
HOST_COMMUNITY -> directToCommunity(context, CommunityEntity(link, text!!))
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToLinkPage(context: Context, linkEntity: LinkEntity, entrance: String, path: String) {
|
||||
directToLinkPage(context, linkEntity, entrance, path, null)
|
||||
@ -261,7 +220,7 @@ object DirectUtils {
|
||||
path
|
||||
)
|
||||
|
||||
"web", "inurl", "web链接" -> {
|
||||
HOST_WEB, HOST_WEB_INURL, HOST_WEB_AL -> {
|
||||
when {
|
||||
linkEntity.link!!.contains("v.douyin") && PackageHelper.localPackageNameSet.contains("com.ss.android.ugc.aweme") -> {
|
||||
directDouyin(context, "1402577827140941")
|
||||
@ -413,7 +372,7 @@ object DirectUtils {
|
||||
"column_test" -> context.startActivity(
|
||||
GameServerTestActivity.getIntent(
|
||||
context, linkEntity.link
|
||||
?: "", linkEntity.text ?: "", entrance
|
||||
?: "", linkEntity.text ?: "", entrance, exposureEvent
|
||||
)
|
||||
)
|
||||
|
||||
@ -441,7 +400,7 @@ object DirectUtils {
|
||||
|
||||
//"h5_game_center" -> directLetoGameCenter(context)
|
||||
|
||||
"game_list" -> directToGameCollectionSquare(context, entrance, "", "", "")
|
||||
"game_list" -> directToGameCollectionSquare(context, entrance, traceEvent = exposureEvent)
|
||||
|
||||
"game_list_detail" -> directToGameCollectionDetail(
|
||||
context,
|
||||
@ -466,6 +425,8 @@ object DirectUtils {
|
||||
)
|
||||
)
|
||||
|
||||
"qq_mini_game_column" -> directToQGameHome(context)
|
||||
|
||||
"" -> {
|
||||
// do nothing
|
||||
}
|
||||
@ -755,11 +716,12 @@ object DirectUtils {
|
||||
id: String,
|
||||
subjectName: String? = "",
|
||||
entrance: String? = null,
|
||||
exposureEvent: ExposureEvent? = null
|
||||
exposureEvent: ExposureEvent? = null,
|
||||
isQQMiniGame: Boolean = false,
|
||||
) {
|
||||
if (id.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
val subjectData = SubjectData(subjectId = id, subjectName = subjectName, isOrder = false)
|
||||
val subjectData = SubjectData(subjectId = id, subjectName = subjectName, isOrder = false, isQQMiniGame = isQQMiniGame)
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_TO, SubjectActivity::class.java.name)
|
||||
bundle.putParcelable(EntranceConsts.KEY_SUBJECT_DATA, subjectData)
|
||||
@ -1871,8 +1833,11 @@ object DirectUtils {
|
||||
* 跳转到游戏动态,请不要随意修改方法名
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToConcernInfo(context: Context) {
|
||||
context.startActivity(ConcernInfoActivity.getIntent(context));
|
||||
fun directToConcernInfo(context: Context, entrance: String) {
|
||||
context.startActivity(
|
||||
(ARouter.getInstance().build(RouteConsts.provider.concernInfo)
|
||||
.navigation() as? IConcernInfoProvider)?.getIntent(context, entrance)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1886,9 +1851,11 @@ object DirectUtils {
|
||||
gameCollectionTitle: String = "",
|
||||
gameCollectionId: String = "",
|
||||
collectionName: String = "",
|
||||
collectionId: String = ""
|
||||
collectionId: String = "",
|
||||
traceEvent: ExposureEvent? = null
|
||||
) {
|
||||
val bundle = Bundle()
|
||||
val exposureSourceList = traceEvent?.source
|
||||
bundle.putString(KEY_TO, GameCollectionSquareActivity::class.java.name)
|
||||
bundle.putString(KEY_ENTRANCE, entrance)
|
||||
bundle.putString(KEY_FORUM_NAME, forumName)
|
||||
@ -1896,6 +1863,11 @@ object DirectUtils {
|
||||
bundle.putString(KEY_GAME_COLLECTION_ID, gameCollectionId)
|
||||
bundle.putString(KEY_COLLECTION_ID, collectionId)
|
||||
bundle.putString(KEY_COLLECTION_NAME, collectionName)
|
||||
if (exposureSourceList is ArrayList) {
|
||||
bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, exposureSourceList)
|
||||
} else if (exposureSourceList != null) {
|
||||
bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureSourceList))
|
||||
}
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@ -2057,4 +2029,66 @@ object DirectUtils {
|
||||
platform = platform
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToQGameHome(context: Context) {
|
||||
context.startActivity(QGameHomeWrapperActivity.getIntent(context))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToQGameSearch(
|
||||
context: Context,
|
||||
hint: String,
|
||||
sourceEntrance: String
|
||||
) {
|
||||
context.startActivity(QGameSearchActivity.getIntent(context, hint, sourceEntrance))
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
@JvmStatic
|
||||
fun directToQGameById(
|
||||
activity: Activity,
|
||||
qqGameId: String
|
||||
) {
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
ToastUtils.toast("该游戏仅支持安卓5.0及以上设备")
|
||||
return
|
||||
}
|
||||
|
||||
CheckLoginUtils.checkLogin(
|
||||
activity, null, true, "QQ小游戏-秒开"
|
||||
) {
|
||||
val userToken = UserManager.getInstance().token
|
||||
val userId = UserManager.getInstance().userId
|
||||
val userName = UserManager.getInstance().userInfoEntity?.name ?: "unknown"
|
||||
|
||||
val qGameProvider = ARouter
|
||||
.getInstance()
|
||||
.build(RouteConsts.provider.qGame)
|
||||
.navigation() as IQGameProvider<*>
|
||||
qGameProvider.setLoginInfo(activity, userId, userName, userToken)
|
||||
qGameProvider.launchGame(activity, qqGameId) { _, _ ->
|
||||
RetrofitManager
|
||||
.getInstance()
|
||||
.newApi
|
||||
.postQGamePlay(qqGameId, userId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
QGameViewModel.notifyQGameSubjectUpdate() // 通知QQ小游戏首页列表刷新
|
||||
},
|
||||
{}
|
||||
) // 秒玩记录上报
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToMessageCenter(defaultTabIndex: Int) {
|
||||
ARouter.getInstance().build(RouteConsts.activity.messageWrapperActivity)
|
||||
.withInt(BaseActivity_TabLayout.PAGE_INDEX, defaultTabIndex)
|
||||
.navigation()
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.os.Message
|
||||
import android.text.TextUtils
|
||||
@ -7,6 +8,7 @@ import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.collection.ArrayMap
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.gh.common.chain.*
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.dialog.DeviceRemindDialog
|
||||
@ -26,19 +28,24 @@ import com.gh.download.server.BrowserInstallHelper
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.WebActivity
|
||||
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
|
||||
import com.gh.gamecenter.common.base.GlobalActivityManager
|
||||
import com.gh.gamecenter.common.callback.CancelListener
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.provider.IQGameProvider
|
||||
import com.gh.gamecenter.core.utils.*
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.PluginLocation
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.view.DownloadButton
|
||||
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment
|
||||
import com.gh.gamecenter.login.user.UserManager
|
||||
import com.gh.gamecenter.manager.PackagesManager
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.gamecenter.teenagermode.TeenagerModeActivity
|
||||
import com.gh.vspace.VHelper
|
||||
import com.lightgame.download.DownloadConfig
|
||||
@ -237,6 +244,24 @@ object DownloadItemUtils {
|
||||
}
|
||||
return
|
||||
}
|
||||
if (gameEntity.isQQMiniGame()) {
|
||||
val isQQMiniGameOffShelve = gameEntity.qqMiniGameAppStatus == 1 // QQ小游戏是否下架
|
||||
if (isQQMiniGameOffShelve) {
|
||||
downloadBtn.apply {
|
||||
isClickable = false
|
||||
text = context.getString(R.string.off_shelve)
|
||||
buttonStyle = DownloadButton.ButtonStyle.NONE
|
||||
}
|
||||
} else {
|
||||
downloadBtn.apply {
|
||||
isClickable = true
|
||||
setBackgroundResource(R.drawable.download_button_normal_style)
|
||||
setTextColor(R.color.white.toColor(context))
|
||||
text = context.getString(R.string.quick_play)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if (gameEntity.getApk().isEmpty() || gameEntity.downloadOffStatus != null) {
|
||||
val h5LinkEntity = gameEntity.h5Link
|
||||
val offStatus = gameEntity.downloadOffStatus
|
||||
@ -275,11 +300,6 @@ object DownloadItemUtils {
|
||||
downloadEntity = VHelper.getVDownloadEntitySnapshot(gameEntity.id, gameEntity.getUniquePackageName())
|
||||
}
|
||||
|
||||
// 还是找不到时,尝试从 gameEntity 里找已绑定的 downloadEntity
|
||||
if (downloadEntity == null) {
|
||||
downloadEntity = gameEntity.getEntryMap().getOrDefault(gameEntity.getUniquePlatform(), null)
|
||||
}
|
||||
|
||||
if (downloadEntity != null) {
|
||||
downloadBtn.apply {
|
||||
when (downloadEntity.status) {
|
||||
@ -366,15 +386,7 @@ object DownloadItemUtils {
|
||||
briefStyle: String?,
|
||||
isShowRecommendStar: Boolean = false
|
||||
) {
|
||||
val entryMap: ArrayMap<String, DownloadEntity> = gameEntity.getEntryMap()
|
||||
val apkEntity = gameEntity.getApk()[0]
|
||||
var downloadEntity: DownloadEntity? = null
|
||||
if (entryMap.isNotEmpty()) {
|
||||
downloadEntity = entryMap[apkEntity.getPlatform()]
|
||||
}
|
||||
if (downloadEntity == null) {
|
||||
downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
|
||||
}
|
||||
val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
|
||||
if (downloadEntity != null) {
|
||||
if (downloadEntity.isSimulatorGame()) {
|
||||
if (downloadEntity.status != DownloadStatus.done) {
|
||||
@ -740,6 +752,15 @@ object DownloadItemUtils {
|
||||
}
|
||||
return
|
||||
}
|
||||
if (gameEntity.isQQMiniGame()) {
|
||||
downloadBtn.setOnClickListener {
|
||||
NewFlatLogUtils.logQGameClick(gameEntity.qqMiniGameAppId, gameEntity.name)
|
||||
GlobalActivityManager.currentActivity?.let { activity ->
|
||||
DirectUtils.directToQGameById(activity, gameEntity.qqMiniGameAppId)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if (gameEntity.getApk().size == 0 && gameEntity.h5Link != null) {
|
||||
downloadBtn.setOnClickListener {
|
||||
allStateClickCallback?.onCallback()
|
||||
@ -827,6 +848,7 @@ object DownloadItemUtils {
|
||||
addHandler(DownloadDialogHelperHandler())
|
||||
addHandler(CertificationHandler())
|
||||
addHandler(OverseaDownloadHandler())
|
||||
addHandler(LandPageAddressHandler())
|
||||
addHandler(CheckDownloadHandler())
|
||||
}
|
||||
.setProcessEndCallback {
|
||||
@ -845,6 +867,7 @@ object DownloadItemUtils {
|
||||
addHandler(DownloadDialogHelperHandler())
|
||||
addHandler(CertificationHandler())
|
||||
addHandler(VersionNumberHandler())
|
||||
addHandler(LandPageAddressHandler())
|
||||
addHandler(OverseaDownloadHandler())
|
||||
addHandler(CheckDownloadHandler())
|
||||
}
|
||||
@ -862,6 +885,7 @@ object DownloadItemUtils {
|
||||
addHandler(DownloadDialogHelperHandler())
|
||||
addHandler(CertificationHandler())
|
||||
addHandler(VersionNumberHandler())
|
||||
addHandler(LandPageAddressHandler())
|
||||
addHandler(OverseaDownloadHandler())
|
||||
addHandler(CheckStoragePermissionHandler())
|
||||
addHandler(ValidateVSpaceHandler())
|
||||
@ -943,16 +967,24 @@ object DownloadItemUtils {
|
||||
VHelper.updateOrReDownload(gameEntity)
|
||||
return
|
||||
}
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk) {
|
||||
DialogUtils.checkDownload(
|
||||
context,
|
||||
apk.size,
|
||||
gameEntity.id,
|
||||
gameEntity.name
|
||||
) { isSubscribe: Boolean ->
|
||||
update(context, gameEntity, entrance, location, isSubscribe, traceEvent)
|
||||
|
||||
ChainBuilder()
|
||||
.apply {
|
||||
addHandler(LandPageAddressHandler())
|
||||
}.setProcessEndCallback {
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk) {
|
||||
DialogUtils.checkDownload(
|
||||
context,
|
||||
apk.size,
|
||||
gameEntity.id,
|
||||
gameEntity.name
|
||||
) { isSubscribe: Boolean ->
|
||||
update(context, gameEntity, entrance, location, isSubscribe, traceEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.buildHandlerChain()
|
||||
?.handleRequest(context, gameEntity)
|
||||
} else {
|
||||
var downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
|
||||
|
||||
|
||||
18
app/src/main/java/com/gh/common/util/GameTrendsHelper.kt
Normal file
18
app/src/main/java/com/gh/common/util/GameTrendsHelper.kt
Normal file
@ -0,0 +1,18 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import com.gh.gamecenter.db.GameTrendsDao
|
||||
import com.gh.gamecenter.login.user.UserManager
|
||||
import com.gh.gamecenter.message.MessageUnreadRepository
|
||||
import com.halo.assistant.HaloApp
|
||||
|
||||
object GameTrendsHelper {
|
||||
private val mGameTrendsDao = GameTrendsDao(HaloApp.getInstance().application)
|
||||
|
||||
fun updateReadPostTime() {
|
||||
mGameTrendsDao.findGameTrendsInfo(UserManager.getInstance().userId)?.let { trendsInfo ->
|
||||
trendsInfo.readPostTime = System.currentTimeMillis()
|
||||
mGameTrendsDao.add(trendsInfo)
|
||||
MessageUnreadRepository.loadMessageUnreadTotal(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -22,8 +22,8 @@ import com.gh.gamecenter.common.utils.SensorsBridge;
|
||||
import com.gh.gamecenter.core.utils.ToastUtils;
|
||||
import com.gh.gamecenter.core.utils.UrlFilterUtils;
|
||||
import com.gh.gamecenter.feature.entity.ApkEntity;
|
||||
import com.gh.gamecenter.entity.LibaoEntity;
|
||||
import com.gh.gamecenter.entity.LibaoStatusEntity;
|
||||
import com.gh.gamecenter.feature.entity.LibaoEntity;
|
||||
import com.gh.gamecenter.feature.entity.LibaoStatusEntity;
|
||||
import com.gh.gamecenter.feature.entity.MeEntity;
|
||||
import com.gh.gamecenter.common.entity.NotificationUgc;
|
||||
import com.gh.gamecenter.feature.entity.UserDataLibaoEntity;
|
||||
@ -46,7 +46,6 @@ import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
|
||||
@ -986,7 +986,7 @@ public class LogUtils {
|
||||
LoghubUtils.log(object, LOG_STORE_EVENT, false);
|
||||
}
|
||||
|
||||
public static void logHomeTopTabClick(String tabName, String linkType, String linkTitle, String linkId, int sequence) {
|
||||
public static void logHomeTopTabClick(String tabName, String linkType, String linkTitle, String linkId, int sequence, String entrance) {
|
||||
JSONObject object = new JSONObject();
|
||||
try {
|
||||
object.put(KEY_EVENT, "top_tab_click");
|
||||
@ -995,6 +995,7 @@ public class LogUtils {
|
||||
object.put("link_id", linkId);
|
||||
object.put("link_text", linkTitle);
|
||||
object.put("sequence", sequence);
|
||||
object.put("entrance", entrance);
|
||||
object.put(KEY_META, getMetaObject());
|
||||
object.put(KEY_TIMESTAMP, System.currentTimeMillis() / 1000);
|
||||
} catch (JSONException e) {
|
||||
|
||||
@ -2340,4 +2340,74 @@ object NewFlatLogUtils {
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
// 游戏详情-求加速点击事件
|
||||
fun logGameDetailClickForAccelerate(gameId: String, gameName: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_detail_click_for_accelerate"
|
||||
"game_name" to gameName
|
||||
"game_id" to gameId
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
// 游戏详情-求版本投票事件
|
||||
fun logGameDetailClickForVersionVote(gameId: String, gameName: String, button: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_detail_click_for_version_vote"
|
||||
"game_name" to gameName
|
||||
"game_id" to gameId
|
||||
"button" to button
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
// 游戏详情-求版本取消投票事件
|
||||
fun logGameDetailCancelForVersionVote(gameId: String, gameName: String, button: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_detail_cancel_for_version_vote"
|
||||
"game_name" to gameName
|
||||
"game_id" to gameId
|
||||
"button" to button
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
// 消息中心-插件版本提醒弹窗点击事件
|
||||
@JvmStatic
|
||||
fun logMessageInformClickPluginVersion(gameId: String, gameName: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "message_inform_click_plugin_version"
|
||||
"game_name" to gameName
|
||||
"game_id" to gameId
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
// 游戏动态关注列表取消关注事件 / 游戏动态关注列表查看详情事件
|
||||
@JvmStatic
|
||||
fun logGameActivityConcern(event: String, gameId: String, gameName: String?) {
|
||||
val json = json {
|
||||
KEY_EVENT to event
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun logQGameClick(qqGameId: String, qqGameName: String?) {
|
||||
val json = json {
|
||||
KEY_EVENT to "qq_game_click"
|
||||
"qq_game_id" to qqGameId
|
||||
"qq_game_name" to qqGameName ?: ""
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
}
|
||||
@ -2,7 +2,7 @@ package com.gh.common.util
|
||||
|
||||
import android.content.Context
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.entity.GameInstall
|
||||
import com.gh.gamecenter.feature.entity.GameInstall
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.packagehelper.PackageRepository
|
||||
|
||||
|
||||
@ -7,12 +7,14 @@ import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.PermissionInfo;
|
||||
import android.content.pm.Signature;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@ -29,6 +31,7 @@ import com.gh.gamecenter.BuildConfig;
|
||||
import com.gh.gamecenter.common.constant.Constants;
|
||||
import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.common.utils.PackageFlavorHelper;
|
||||
import com.gh.gamecenter.common.utils.PermissionHelper;
|
||||
import com.gh.gamecenter.core.utils.MD5Utils;
|
||||
import com.gh.gamecenter.core.utils.SentryHelper;
|
||||
import com.gh.gamecenter.feature.entity.ApkEntity;
|
||||
@ -74,6 +77,9 @@ public class PackageUtils {
|
||||
|
||||
private static final String TAG = "PackageUtils";
|
||||
|
||||
// 设备是否支持禁用获取已安装应用列表。-1 代表支持情况未知,0 代表不支持, 1 代表支持
|
||||
private static int mIsSupportGetInstalledListPermission = -1;
|
||||
|
||||
public static String getInstallPackageInfoSourceDir(String packageName) {
|
||||
try {
|
||||
return HaloApp.getInstance().getApplication().getPackageManager().getPackageInfo(packageName,
|
||||
@ -137,6 +143,9 @@ public class PackageUtils {
|
||||
updateEntity.setSignature(apkEntity.getSignature());
|
||||
updateEntity.setCategory(gameEntity.getCategory());
|
||||
updateEntity.setCurrentVersion(PackageUtils.getVersionNameByPackageName(apkEntity.getPackageName()));
|
||||
if (gameEntity.isLandPageAddressDialog()) {
|
||||
updateEntity.setLandPageAddressDialog(gameEntity.getLandPageAddressDialog());
|
||||
}
|
||||
updateList.add(updateEntity);
|
||||
}
|
||||
}
|
||||
@ -211,6 +220,9 @@ public class PackageUtils {
|
||||
updateEntity.setSignature(apkEntity.getSignature());
|
||||
updateEntity.setCategory(gameEntity.getCategory());
|
||||
updateEntity.setCurrentVersion(PackageUtils.getVersionNameByPackageName(apkEntity.getPackageName()));
|
||||
if (gameEntity.isLandPageAddressDialog()) {
|
||||
updateEntity.setLandPageAddressDialog(gameEntity.getLandPageAddressDialog());
|
||||
}
|
||||
updateList.add(updateEntity);
|
||||
}
|
||||
}
|
||||
@ -960,18 +972,78 @@ public class PackageUtils {
|
||||
return new ArrayList<>(mInstalledPackageList);
|
||||
}
|
||||
|
||||
Utils.log(TAG, "调用系统 API 获取全新的已安装应用列表");
|
||||
// 是否需要调用系统 API 获取最新的已安装应用列表
|
||||
boolean shouldGetNewInstalledPackagedList = false;
|
||||
|
||||
// 当前设备是否支持限制获取已安装应用列表的功能
|
||||
if (isSupportGetInstalledAppsPermission(context)) {
|
||||
Utils.log(TAG, "当前设备支持限制获取已安装应用列表的功能");
|
||||
// 当前设备是否支持禁用了获取已安装应用列表
|
||||
if (!PermissionHelper.isGetInstalledListPermissionDisabled(context)) {
|
||||
Utils.log(TAG, "当前设备没有限制获取已安装应用列表的功能");
|
||||
shouldGetNewInstalledPackagedList = true;
|
||||
} else {
|
||||
Utils.log(TAG, "当前设备已限制获取已安装应用列表的功能");
|
||||
}
|
||||
} else {
|
||||
Utils.log(TAG, "当前设备不支持限制获取已安装应用列表的功能");
|
||||
shouldGetNewInstalledPackagedList = true;
|
||||
}
|
||||
|
||||
if (shouldGetNewInstalledPackagedList) {
|
||||
mLastInstalledPackageListTime = System.currentTimeMillis();
|
||||
mInstalledPackageList = getInstalledPackagesInternal(context, flags);
|
||||
}
|
||||
|
||||
if (mInstalledPackageList == null) {
|
||||
mInstalledPackageList = new ArrayList<>();
|
||||
}
|
||||
|
||||
mLastInstalledPackageListTime = System.currentTimeMillis();
|
||||
mInstalledPackageList = getInstalledPackagesInternal(context, flags);
|
||||
return mInstalledPackageList;
|
||||
}
|
||||
|
||||
public static boolean isSupportGetInstalledAppsPermission(Context context) {
|
||||
// 若存在缓存,直接返回缓存结果。为 0 代表不支持,为 1 代表支持
|
||||
if (mIsSupportGetInstalledListPermission != -1) {
|
||||
return mIsSupportGetInstalledListPermission != 0;
|
||||
}
|
||||
|
||||
try {
|
||||
// 根据官方提供的方法来判定是否支持限制获取已安装应用列表
|
||||
int flag = Settings.Secure.getInt(context.getContentResolver(), "oem_installed_apps_runtime_permission_enable", 0);
|
||||
if (flag == 1) {
|
||||
mIsSupportGetInstalledListPermission = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 部分未升级的手机没有上面配置项,有定义下面危险权限也认为是支持设备软件列表管控
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
PermissionInfo permissionInfo = packageManager.getPermissionInfo("com.android.permission.GET_INSTALLED_APPS", 0);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
if (permissionInfo.getProtection() == PermissionInfo.PROTECTION_DANGEROUS) {
|
||||
mIsSupportGetInstalledListPermission = 1;
|
||||
return true;
|
||||
} else {
|
||||
mIsSupportGetInstalledListPermission = 0;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
mIsSupportGetInstalledListPermission = 0;
|
||||
return false;
|
||||
}
|
||||
} catch (NameNotFoundException e) {
|
||||
mIsSupportGetInstalledListPermission = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 在5.1系统手机使用PackageManager获取已安装应用容易发生Package manager has died异常
|
||||
* https://stackoverflow.com/questions/13235793/transactiontoolargeeception-when-trying-tÏo-get-a-list-of-applications-installed/30062632#30062632
|
||||
*/
|
||||
private static List<PackageInfo> getInstalledPackagesInternal(Context context, int flags) {
|
||||
Utils.log(TAG, "调用系统 API 获取已安装应用列表");
|
||||
|
||||
final PackageManager pm = context.getPackageManager();
|
||||
try {
|
||||
return pm.getInstalledPackages(flags);
|
||||
|
||||
@ -7,7 +7,7 @@ import android.text.TextUtils;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.common.retrofit.JSONObjectResponse;
|
||||
import com.gh.gamecenter.common.retrofit.Response;
|
||||
import com.gh.gamecenter.entity.CommentEntity;
|
||||
import com.gh.gamecenter.feature.entity.CommentEntity;
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager;
|
||||
import com.lightgame.utils.Utils;
|
||||
import com.walkud.rom.checker.RomIdentifier;
|
||||
|
||||
@ -95,21 +95,19 @@ object ReservationHelper {
|
||||
NewLogUtils.logReserveGameSuccess(wechatConfig)
|
||||
if (bind && follow && notice) {
|
||||
NewLogUtils.logReserveWechatSuccessPopShow()
|
||||
DialogUtils.showReserveSuccessDialog(context)
|
||||
DialogUtils.showReserveOrVoteSuccessDialog(context, true)
|
||||
} else {
|
||||
NewLogUtils.logReserveWechatRemindPopShow(wechatConfig)
|
||||
SensorsBridge.trackEvent("AppointmenWechatRemindDialogShow")
|
||||
DialogUtils.showReserveSuccess2WechatBindDialog(context, object : ConfirmListener {
|
||||
override fun onConfirm() {
|
||||
NewLogUtils.logReserveWechatRemindPopClick(wechatConfig, "开启微信提醒")
|
||||
SensorsBridge.trackEvent("AppointmenWechatRemindDialogClick")
|
||||
context.startActivity(WebActivity.getBindWechatIntent(context))
|
||||
SensorsBridge.trackEvent(
|
||||
"AppointmenWechatRemindConfigPageShow",
|
||||
"source_entrance",
|
||||
"设置微信提醒弹窗"
|
||||
)
|
||||
}
|
||||
DialogUtils.showReserveOrVoteSuccess2WechatBindDialog(context, true, {
|
||||
NewLogUtils.logReserveWechatRemindPopClick(wechatConfig, "开启微信提醒")
|
||||
SensorsBridge.trackEvent("AppointmenWechatRemindDialogClick")
|
||||
context.startActivity(WebActivity.getBindWechatIntent(context))
|
||||
SensorsBridge.trackEvent(
|
||||
"AppointmenWechatRemindConfigPageShow",
|
||||
"source_entrance",
|
||||
"设置微信提醒弹窗"
|
||||
)
|
||||
}, object : CancelListener {
|
||||
override fun onCancel() {
|
||||
NewLogUtils.logReserveWechatRemindPopClick(wechatConfig, "关闭弹窗")
|
||||
|
||||
@ -270,7 +270,11 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
|
||||
pendingSessionInfo.updateStatus(XapkPendingSessionInfo.STATUS_INSTALL_CANCELED)
|
||||
} else if (sessionInfo.progress <= 0.8F) {
|
||||
AppExecutor.ioExecutor.execute {
|
||||
installer.abandonSession(sessionInfo.sessionId)
|
||||
try {
|
||||
installer.abandonSession(sessionInfo.sessionId)
|
||||
} catch (_: Exception) {
|
||||
// 有概率抛SecurityException,这里只要直接catch不做处理即可
|
||||
}
|
||||
}
|
||||
pendingSessionInfo.updateStatus(XapkPendingSessionInfo.STATUS_INSTALL_CANCELED)
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ package com.gh.download
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.text.TextUtils
|
||||
import com.gh.common.util.ConcernUtils
|
||||
import com.gh.gamecenter.feature.utils.ConcernUtils
|
||||
import com.gh.common.util.DataCollectionUtils
|
||||
import com.gh.common.util.PackageInstaller
|
||||
import com.gh.common.util.PackageUtils
|
||||
|
||||
@ -10,7 +10,7 @@ import com.gh.gamecenter.common.base.activity.ToolBarActivity;
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
import com.gh.gamecenter.common.entity.LinkEntity;
|
||||
import com.gh.gamecenter.entity.MessageEntity;
|
||||
import com.gh.gamecenter.feature.entity.MessageEntity;
|
||||
import com.gh.gamecenter.qa.comment.CommentActivity;
|
||||
import com.gh.gamecenter.qa.comment.NewCommentConversationFragment;
|
||||
import com.halo.assistant.fragment.comment.CommentDetailFragment;
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
package com.gh.gamecenter;
|
||||
|
||||
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.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.info.ConcernFragment;
|
||||
|
||||
/**
|
||||
* Created by khy on 10/04/18.
|
||||
*/
|
||||
|
||||
public class ConcernInfoActivity extends ToolBarActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white);
|
||||
}
|
||||
|
||||
public static Intent getIntent(Context context) {
|
||||
return getTargetIntent(context, ConcernInfoActivity.class, ConcernFragment.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDarkModeChanged() {
|
||||
super.onDarkModeChanged();
|
||||
ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white);
|
||||
}
|
||||
}
|
||||
@ -34,6 +34,7 @@ import androidx.transition.*
|
||||
import androidx.viewpager.widget.PagerAdapter
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import androidx.viewpager.widget.ViewPager.OnPageChangeListener
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||
import com.facebook.drawee.backends.pipeline.Fresco
|
||||
import com.facebook.imagepipeline.core.ImagePipeline
|
||||
@ -41,6 +42,7 @@ import com.facebook.imagepipeline.request.ImageRequest
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.entity.CommunityEntity
|
||||
import com.gh.gamecenter.common.retrofit.Response
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
@ -71,6 +73,7 @@ import kotlin.math.roundToInt
|
||||
* @author 黄壮华
|
||||
*
|
||||
*/
|
||||
@Route(path = RouteConsts.activity.imageViewerActivity)
|
||||
class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
|
||||
private var mScale = 0F
|
||||
@ -150,8 +153,8 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
mUrlList = ArrayList()
|
||||
mUrlList?.add(base64Image)
|
||||
} else {
|
||||
mUrlList = it.getStringArrayList(KEY_URL_LIST) ?: arrayListOf()
|
||||
mInitialPosition = it.getInt(KEY_CURRENT, 0)
|
||||
mUrlList = it.getStringArrayList(EntranceConsts.KEY_URL_LIST) ?: arrayListOf()
|
||||
mInitialPosition = it.getInt(EntranceConsts.KEY_CURRENT, 0)
|
||||
}
|
||||
mShowSaveBtn = it.getBoolean(KEY_SHOW_SAVE)
|
||||
mUseEnterAndExitAnimation = it.getBoolean(KEY_USE_ENTER_AND_EXIT_ANIMATION)
|
||||
@ -930,8 +933,6 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
var base64Image: String = ""
|
||||
|
||||
private const val KEY_BASE64 = "base64"
|
||||
private const val KEY_URL_LIST = "urls"
|
||||
private const val KEY_CURRENT = "current"
|
||||
private const val KEY_SHOW_SAVE = "showSave"
|
||||
private const val KEY_USE_ENTER_AND_EXIT_ANIMATION = "use_enter_and_exit_animation"
|
||||
private const val KEY_IS_FROM_IMAGE_CONTAINER_VIEW = "is_from_image_container_view"
|
||||
@ -995,8 +996,8 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
isFromICV: Boolean = false
|
||||
): Intent {
|
||||
val intent = Intent(context, ImageViewerActivity::class.java)
|
||||
intent.putExtra(KEY_URL_LIST, list)
|
||||
intent.putExtra(KEY_CURRENT, position)
|
||||
intent.putExtra(EntranceConsts.KEY_URL_LIST, list)
|
||||
intent.putExtra(EntranceConsts.KEY_CURRENT, position)
|
||||
intent.putExtra(KEY_SHOW_SAVE, isShowSaveBtn)
|
||||
intent.putExtra(AnswerEntity::class.java.name, answerEntity)
|
||||
intent.putExtra(EntranceConsts.KEY_ENTRANCE, entrance)
|
||||
|
||||
@ -18,9 +18,11 @@ import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.alibaba.android.arouter.facade.annotation.Route;
|
||||
import com.ethanhua.skeleton.Skeleton;
|
||||
import com.ethanhua.skeleton.ViewSkeletonScreen;
|
||||
import com.gh.common.filter.RegionSettingHelper;
|
||||
import com.gh.gamecenter.common.constant.RouteConsts;
|
||||
import com.gh.gamecenter.feature.utils.ApkActiveUtils;
|
||||
import com.gh.common.util.CheckLoginUtils;
|
||||
import com.gh.common.util.DetailDownloadUtils;
|
||||
@ -38,8 +40,8 @@ import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.common.view.VerticalItemDecoration;
|
||||
import com.gh.gamecenter.feature.entity.ApkEntity;
|
||||
import com.gh.gamecenter.feature.entity.GameEntity;
|
||||
import com.gh.gamecenter.entity.LibaoEntity;
|
||||
import com.gh.gamecenter.entity.LibaoStatusEntity;
|
||||
import com.gh.gamecenter.feature.entity.LibaoEntity;
|
||||
import com.gh.gamecenter.feature.entity.LibaoStatusEntity;
|
||||
import com.gh.gamecenter.feature.entity.MeEntity;
|
||||
import com.gh.gamecenter.feature.entity.UserDataLibaoEntity;
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus;
|
||||
@ -70,6 +72,7 @@ import retrofit2.HttpException;
|
||||
/**
|
||||
* Created by khy on 2016/12/13.
|
||||
*/
|
||||
@Route(path = RouteConsts.activity.libaoDetailActivity)
|
||||
public class LibaoDetailActivity extends ToolBarActivity implements LibaoDetailAdapter.OnCodeScrollListener,
|
||||
OnRequestCallBackListener {
|
||||
|
||||
|
||||
@ -21,7 +21,6 @@ import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
@ -33,6 +32,7 @@ import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
@ -43,9 +43,8 @@ import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
|
||||
import com.alibaba.android.arouter.launcher.ARouter;
|
||||
import com.facebook.drawee.view.SimpleDraweeView;
|
||||
import com.gh.common.DefaultUrlHandler;
|
||||
import com.gh.ad.AdDelegateHelper;
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.exposure.ExposureManager;
|
||||
import com.gh.common.filter.RegionSettingHelper;
|
||||
@ -77,7 +76,6 @@ import com.gh.gamecenter.common.base.fragment.ToolbarFragment;
|
||||
import com.gh.gamecenter.common.constant.CommonConsts;
|
||||
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.LinkEntity;
|
||||
import com.gh.gamecenter.common.entity.NotificationUgc;
|
||||
import com.gh.gamecenter.common.entity.SuggestType;
|
||||
@ -92,7 +90,6 @@ import com.gh.gamecenter.common.utils.ImageUtils;
|
||||
import com.gh.gamecenter.common.utils.NotificationHelper;
|
||||
import com.gh.gamecenter.common.utils.ShareUtils;
|
||||
import com.gh.gamecenter.core.AppExecutor;
|
||||
import com.gh.gamecenter.core.provider.IStartUpAdProvider;
|
||||
import com.gh.gamecenter.core.utils.ClassUtils;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
import com.gh.gamecenter.core.utils.GsonUtils;
|
||||
@ -102,8 +99,6 @@ import com.gh.gamecenter.core.utils.SentryHelper;
|
||||
import com.gh.gamecenter.core.utils.TimeUtils;
|
||||
import com.gh.gamecenter.core.utils.ToastUtils;
|
||||
import com.gh.gamecenter.core.utils.UrlFilterUtils;
|
||||
import com.gh.gamecenter.download.DownloadFragment;
|
||||
import com.gh.gamecenter.entity.InnerMetaInfoEntity;
|
||||
import com.gh.gamecenter.entity.StartupAdEntity;
|
||||
import com.gh.gamecenter.eventbus.EBSkip;
|
||||
import com.gh.gamecenter.feature.entity.GameEntity;
|
||||
@ -141,22 +136,16 @@ import org.greenrobot.eventbus.ThreadMode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import io.reactivex.SingleSource;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
@ -174,7 +163,7 @@ public class MainActivity extends BaseActivity {
|
||||
public static final String SWITCH_TO_COMMUNITY = "switch_to_community";
|
||||
public static final String SWITCH_TO_VIDEO = "switch_to_video";
|
||||
public static final String SHOW_AD = "show_ad";
|
||||
private static final int COUNTDOWN_AD = 100;
|
||||
public static final int COUNTDOWN_AD = 100;
|
||||
private static final int COUNTDOWN_MAX_COUNT = 3;
|
||||
private int countdownCount = 0;
|
||||
|
||||
@ -190,13 +179,11 @@ public class MainActivity extends BaseActivity {
|
||||
public static boolean isNewFirstLaunch;
|
||||
|
||||
private final Handler handler = new Handler();
|
||||
public boolean showAd = false; // 是否显示广告
|
||||
|
||||
private IStartUpAdProvider mStartUpAdProvider;
|
||||
private boolean mShouldShowAd = false; // 是否显示广告
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
showAd = getIntent().getBooleanExtra(SHOW_AD, false) && savedInstanceState == null;
|
||||
mShouldShowAd = getIntent().getBooleanExtra(SHOW_AD, false) && savedInstanceState == null;
|
||||
|
||||
HaloApp.getInstance().isAlreadyUpAndRunning = true;
|
||||
|
||||
@ -230,7 +217,6 @@ public class MainActivity extends BaseActivity {
|
||||
}
|
||||
}
|
||||
}, 2000L);
|
||||
getPluginUpdate();
|
||||
sp.edit().putBoolean("isNewFirstLaunchV" + PackageUtils.getGhVersionName(), false).apply();
|
||||
|
||||
// 记录曾安装过的版本 + 渠道
|
||||
@ -284,8 +270,6 @@ public class MainActivity extends BaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
// checkTinkerPath(); // 看情况是否需要显示补丁弹窗
|
||||
|
||||
// 必须放在这里,否则会导致获取 baseActivity 不是本应用包名
|
||||
DownloadManager.getInstance().initDownloadService();
|
||||
|
||||
@ -302,17 +286,16 @@ public class MainActivity extends BaseActivity {
|
||||
doSkip();
|
||||
}
|
||||
|
||||
// debug 模式下的快速跳转页面
|
||||
if (BuildConfig.DEBUG) {
|
||||
handler.postDelayed(() -> {
|
||||
EntranceUtils.jumpShortcut(this);
|
||||
}, 500);
|
||||
handler.postDelayed(() -> EntranceUtils.jumpShortcut(this), 500);
|
||||
}
|
||||
|
||||
if (showAd) {
|
||||
observeStartUp();
|
||||
if (mShouldShowAd) {
|
||||
showAd();
|
||||
} else {
|
||||
hideStartUp();
|
||||
hideStartUpAd();
|
||||
hideTextAd();
|
||||
hideSplashAd();
|
||||
}
|
||||
|
||||
// 默认配置为空时重试
|
||||
@ -475,7 +458,7 @@ public class MainActivity extends BaseActivity {
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
if (mStartUpAdProvider != null) mStartUpAdProvider.cancelStartUpAd(this);
|
||||
AdDelegateHelper.INSTANCE.cancelSplashAd(this);
|
||||
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
releaseExoSourceCache();
|
||||
@ -499,87 +482,58 @@ public class MainActivity extends BaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private void observeStartUp() {
|
||||
if (!showAd) {
|
||||
hideStartUp();
|
||||
hideStartUpAd();
|
||||
/**
|
||||
* 显示广告 (包括文本广告和开屏广告)
|
||||
*/
|
||||
private void showAd() {
|
||||
if (!mShouldShowAd) {
|
||||
hideTextAd();
|
||||
hideSplashAd();
|
||||
return;
|
||||
}
|
||||
final StartupAdEntity startUp = AdHelper.getStartUp();
|
||||
if (startUp != null) {
|
||||
showStartUp(startUp);
|
||||
final StartupAdEntity textAd = AdHelper.getStartUp();
|
||||
if (textAd != null) {
|
||||
showTextAd(textAd);
|
||||
AppExecutor.getUiExecutor().executeWithDelay(() -> {
|
||||
hideStartUp();
|
||||
initStartUpAd();
|
||||
hideTextAd();
|
||||
showSplashAd();
|
||||
}, 2000);
|
||||
} else {
|
||||
initStartUpAd();
|
||||
showSplashAd();
|
||||
}
|
||||
}
|
||||
|
||||
private void initStartUpAd() {
|
||||
mStartUpAdProvider = (IStartUpAdProvider) ARouter.getInstance().build(RouteConsts.provider.adSdk).navigation();
|
||||
if (mStartUpAdProvider != null && mStartUpAdProvider.shouldEnableSDK(HaloApp.getInstance().getChannel())) {
|
||||
initSDKStartUpAd();
|
||||
} else {
|
||||
observeStartUpAd();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 显示开屏广告
|
||||
*/
|
||||
private void showSplashAd() {
|
||||
if (AdDelegateHelper.INSTANCE.shouldShowStartUpAd()) {
|
||||
ViewGroup startAdContainer = findViewById(R.id.startAdContainer);
|
||||
ViewGroup sdkStartAdContainer = findViewById(R.id.sdkStartAdContainer);
|
||||
FrameLayout adsFl = findViewById(R.id.adsFl);
|
||||
|
||||
private void observeStartUpAd() {
|
||||
final StartupAdEntity startUpAd = AdHelper.getStartUpAd();
|
||||
int screenWidthInPx = DisplayUtils.getScreenWidth(this);
|
||||
int screenHeightInPx = DisplayUtils.getScreenHeight(this) + DisplayUtils.getStatusBarHeight(this.getResources());
|
||||
float screenWidthInDp = DisplayUtils.px2dip(this, screenWidthInPx);
|
||||
float screenHeightInDp = DisplayUtils.px2dip(this, screenHeightInPx);
|
||||
|
||||
if (startUpAd != null && !TextUtils.isEmpty(startUpAd.getImg())) {
|
||||
// 根据接口返回的广告时间,判断该图片广告是否还有必要显示
|
||||
boolean isAdValid = false;
|
||||
if (startUpAd.getTime() != null) {
|
||||
long currentTimeInSecond = System.currentTimeMillis() / 1000;
|
||||
if (currentTimeInSecond > startUpAd.getTime().getStart()
|
||||
&& currentTimeInSecond < startUpAd.getTime().getEnd()) {
|
||||
isAdValid = true;
|
||||
}
|
||||
} else {
|
||||
// 接口没有返回开始和结束时间时,默认有效
|
||||
isAdValid = true;
|
||||
}
|
||||
|
||||
// 图片广告无效,跳过
|
||||
if (!isAdValid) {
|
||||
hideStartUpAd();
|
||||
return;
|
||||
}
|
||||
|
||||
final String showedTodayTimestamp = SPUtils.getString(Constants.SP_STARTUP_AD_TIMESTAMP, "");
|
||||
final String rule = startUpAd.getRule();
|
||||
switch (rule) {
|
||||
case "each":
|
||||
showStartUpAd(startUpAd);
|
||||
break;
|
||||
case "once":
|
||||
if (TextUtils.isEmpty(showedTodayTimestamp)
|
||||
|| !showedTodayTimestamp.contains(startUpAd.getId())) {
|
||||
showStartUpAd(startUpAd);
|
||||
} else {
|
||||
hideStartUpAd();
|
||||
AdDelegateHelper.requestSplashAd(
|
||||
this,
|
||||
screenWidthInPx,
|
||||
screenHeightInPx,
|
||||
screenWidthInDp,
|
||||
screenHeightInDp,
|
||||
startAdContainer,
|
||||
sdkStartAdContainer,
|
||||
adsFl,
|
||||
(BaseHandler) mBaseHandler,
|
||||
() -> {
|
||||
hideSplashAd();
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case "everyday":
|
||||
final String today = TimeUtils.getToday();
|
||||
if (TextUtils.isEmpty(showedTodayTimestamp)
|
||||
|| !showedTodayTimestamp.contains(today)
|
||||
|| !showedTodayTimestamp.contains(startUpAd.getId())) {
|
||||
showStartUpAd(startUpAd);
|
||||
} else {
|
||||
hideStartUpAd();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
hideStartUpAd();
|
||||
break;
|
||||
}
|
||||
SPUtils.setString(Constants.SP_STARTUP_AD_TIMESTAMP, startUpAd.getId() + TimeUtils.getToday());
|
||||
);
|
||||
} else {
|
||||
hideStartUpAd();
|
||||
hideSplashAd();
|
||||
}
|
||||
}
|
||||
|
||||
@ -591,14 +545,17 @@ public class MainActivity extends BaseActivity {
|
||||
TextView jumpBtn = findViewById(R.id.jumpBtn);
|
||||
jumpBtn.setText(String.format(Locale.CHINA, "跳过 %d", COUNTDOWN_MAX_COUNT - countdownCount));
|
||||
if (COUNTDOWN_MAX_COUNT < countdownCount) {
|
||||
hideStartUpAd();
|
||||
hideSplashAd();
|
||||
} else {
|
||||
mBaseHandler.sendEmptyMessageDelayed(COUNTDOWN_AD, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void hideStartUp() {
|
||||
/**
|
||||
* 隐藏开屏文案
|
||||
*/
|
||||
private void hideTextAd() {
|
||||
View maskContainer = findViewById(R.id.maskContainer);
|
||||
if (maskContainer != null) {
|
||||
maskContainer.setVisibility(View.GONE);
|
||||
@ -606,8 +563,11 @@ public class MainActivity extends BaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private void hideStartUpAd() {
|
||||
showAd = false;
|
||||
/**
|
||||
* 隐藏开屏广告
|
||||
*/
|
||||
private void hideSplashAd() {
|
||||
mShouldShowAd = false;
|
||||
getIntent().putExtra(SHOW_AD, false);
|
||||
View startAdContainer = findViewById(R.id.startAdContainer);
|
||||
if (startAdContainer != null) {
|
||||
@ -618,7 +578,7 @@ public class MainActivity extends BaseActivity {
|
||||
if (startSdkAdContainer != null) {
|
||||
startSdkAdContainer.setVisibility(View.GONE);
|
||||
ExtensionsKt.removeFromParent(startSdkAdContainer);
|
||||
if (mStartUpAdProvider != null) mStartUpAdProvider.cancelStartUpAd(this);
|
||||
AdDelegateHelper.INSTANCE.cancelSplashAd(this);
|
||||
}
|
||||
checkDialog();
|
||||
}
|
||||
@ -634,62 +594,10 @@ public class MainActivity extends BaseActivity {
|
||||
});
|
||||
}
|
||||
|
||||
private void showStartUpAd(StartupAdEntity ad) {
|
||||
View startAdContainer = findViewById(R.id.startAdContainer);
|
||||
View jumpBtn = findViewById(R.id.jumpBtn);
|
||||
TextView jumpDetailBtn = findViewById(R.id.jumpDetailBtn);
|
||||
SimpleDraweeView adImage = findViewById(R.id.adImage);
|
||||
startAdContainer.setVisibility(View.VISIBLE);
|
||||
jumpDetailBtn.setText(ad.getDesc());
|
||||
ExtensionsKt.setDrawableEnd(jumpDetailBtn, AppCompatResources.getDrawable(this, R.drawable.ic_startup_ad_arrow), null, null);
|
||||
ImageUtils.display(adImage, ad.getImg());
|
||||
startAdContainer.setOnClickListener(v -> {
|
||||
// do nothing 只是为了点击拦截事件,避免传递到下面的页面
|
||||
});
|
||||
jumpBtn.setOnClickListener(v -> {
|
||||
mBaseHandler.removeMessages(COUNTDOWN_AD);
|
||||
hideStartUpAd();
|
||||
LinkEntity linkEntity = ad.getJump();
|
||||
NewFlatLogUtils.logOpenScreenAdSkip(
|
||||
ad.getId(),
|
||||
linkEntity.getText() != null ? linkEntity.getText() : "",
|
||||
linkEntity.getType() != null ? linkEntity.getType() : "",
|
||||
linkEntity.getLink() != null ? linkEntity.getLink() : ""
|
||||
);
|
||||
});
|
||||
List<ExposureSource> sources = new ArrayList<>();
|
||||
sources.add(new ExposureSource("开屏广告", ad.getId()));
|
||||
final ExposureEvent event = ExposureEvent.createEvent(null, sources, null, ExposureType.EXPOSURE);
|
||||
ExposureManager.INSTANCE.log(event);
|
||||
if (ad.getButton()) {
|
||||
jumpDetailBtn.setOnClickListener(v -> {
|
||||
DirectUtils.directToLinkPage(this, ad.getJump(), "(启动广告)", "", event);
|
||||
v.postDelayed(() -> {
|
||||
mBaseHandler.removeMessages(COUNTDOWN_AD);
|
||||
hideStartUpAd();
|
||||
}, 1000);
|
||||
});
|
||||
jumpDetailBtn.setVisibility(View.VISIBLE);
|
||||
LogUtils.logStartAd("watch_start_ads", ad);
|
||||
} else {
|
||||
LogUtils.logStartAd("start_ads", ad);
|
||||
}
|
||||
mBaseHandler.sendEmptyMessageDelayed(COUNTDOWN_AD, 1000);
|
||||
}
|
||||
|
||||
private void initSDKStartUpAd() {
|
||||
View startAdContainer = findViewById(R.id.sdkStartAdContainer);
|
||||
startAdContainer.setVisibility(View.VISIBLE);
|
||||
FrameLayout adsFl = findViewById(R.id.adsFl);
|
||||
if (mStartUpAdProvider != null) {
|
||||
mStartUpAdProvider.initStartUpAd(startAdContainer, adsFl, showAd, () -> {
|
||||
hideStartUpAd();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void showStartUp(StartupAdEntity ad) {
|
||||
/**
|
||||
* 显示文本广告
|
||||
*/
|
||||
private void showTextAd(StartupAdEntity ad) {
|
||||
TextView adContentTv = findViewById(R.id.adContentTv);
|
||||
View containerView = findViewById(R.id.maskContainer);
|
||||
containerView.setVisibility(View.VISIBLE);
|
||||
@ -697,7 +605,7 @@ public class MainActivity extends BaseActivity {
|
||||
containerView.setElevation(500F);
|
||||
}
|
||||
containerView.setOnClickListener(v -> {
|
||||
// do nothing 只是为了点击拦截事件,避免传递到下面的页面
|
||||
// 拦截点击事件,避免传递到下面的页面
|
||||
});
|
||||
adContentTv.setText(ad.getDesc());
|
||||
adContentTv.setVisibility(View.VISIBLE);
|
||||
@ -747,7 +655,6 @@ public class MainActivity extends BaseActivity {
|
||||
} else {
|
||||
Intent skipIntent = new Intent(MainActivity.this, clazz);
|
||||
skipIntent.putExtras(bundle);
|
||||
// startActivity(skipIntent);
|
||||
AvoidOnResultManager.Companion.getInstance(this)
|
||||
.startForResult(skipIntent, (resultCode, data) -> {
|
||||
Bundle nextToBundle = getIntent().getBundleExtra(KEY_NEXT_TO);
|
||||
@ -869,7 +776,7 @@ public class MainActivity extends BaseActivity {
|
||||
@Override
|
||||
public Boolean invoke(Integer code) {
|
||||
if (code == 404001) {
|
||||
if (showAd) {
|
||||
if (mShouldShowAd) {
|
||||
AppExecutor.getUiExecutor().executeWithDelay(() -> {
|
||||
toast("抱歉,暂未找到相关内容");
|
||||
}, 1000);
|
||||
@ -980,7 +887,7 @@ public class MainActivity extends BaseActivity {
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
if (showAd) {
|
||||
if (mShouldShowAd) {
|
||||
return R.layout.activity_main;
|
||||
} else {
|
||||
return R.layout.layout_wrapper_activity;
|
||||
@ -1003,71 +910,6 @@ public class MainActivity extends BaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
// 获取META-INF中的plugin_update 文件,判断是否从游戏插件中下载的app,是则获取游戏id,启动游戏更新,下载该游戏
|
||||
private void getPluginUpdate() {
|
||||
AppExecutor.getIoExecutor().execute(() -> {
|
||||
ApplicationInfo appinfo = getApplicationInfo();
|
||||
String sourceDir = appinfo.sourceDir;
|
||||
ZipFile zipfile = null;
|
||||
|
||||
try {
|
||||
zipfile = new ZipFile(sourceDir);
|
||||
Enumeration<?> entries = zipfile.entries();
|
||||
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = ((ZipEntry) entries.nextElement());
|
||||
String entryName = entry.getName();
|
||||
if (entryName.contains("gh_assist")) {
|
||||
String packageName = entryName.substring(entryName.lastIndexOf("_") + 1);
|
||||
startActivity(DownloadManagerActivity.getDownloadMangerIntent(MainActivity.this,
|
||||
packageName, DownloadFragment.INDEX_UPDATE, "(游戏插件)"));
|
||||
break;
|
||||
} else if (entryName.contains("halo_skip.json")) {
|
||||
InputStream in = zipfile.getInputStream(entry);
|
||||
if (in != null) {
|
||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
||||
|
||||
InnerMetaInfoEntity info = GsonUtils.getGson().fromJson(reader, InnerMetaInfoEntity.class);
|
||||
if (info != null) {
|
||||
if (EntranceConsts.HOST_COMMUNITY.equals(info.getType())) {
|
||||
runOnUiThread(() -> mMainWrapperFragment.setCurrentItem(MainWrapperFragment.INDEX_BBS));
|
||||
} else {
|
||||
DirectUtils.directToSpecificPage(this,
|
||||
info.getType(),
|
||||
info.getLink(),
|
||||
info.getText(),
|
||||
EntranceConsts.KEY_PLUGIN,
|
||||
"特定包启动跳转");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (entryName.contains("halo_skip.dat")) {
|
||||
InputStream in = zipfile.getInputStream(entry);
|
||||
if (in != null) {
|
||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
||||
String content = "";
|
||||
for (String line; (line = reader.readLine()) != null; content += line) ;
|
||||
|
||||
if (!TextUtils.isEmpty(content)) {
|
||||
DefaultUrlHandler.interceptUrl(this, content, "(特定包启动跳转)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (zipfile != null) {
|
||||
try {
|
||||
zipfile.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 连接上网络事件
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onEventMainThread(EBNetworkState busNetworkState) {
|
||||
|
||||
@ -9,8 +9,8 @@ import android.view.ViewGroup;
|
||||
import com.gh.gamecenter.common.base.activity.ToolBarActivity;
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
import com.gh.gamecenter.entity.CommentEntity;
|
||||
import com.gh.gamecenter.entity.ConcernEntity;
|
||||
import com.gh.gamecenter.feature.entity.CommentEntity;
|
||||
import com.gh.gamecenter.feature.entity.ConcernEntity;
|
||||
import com.gh.gamecenter.message.MessageDetailFragment;
|
||||
import com.halo.assistant.HaloApp;
|
||||
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
package com.gh.gamecenter;
|
||||
|
||||
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.EntranceConsts;
|
||||
import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.message.MessageNormalFragment;
|
||||
|
||||
/**
|
||||
* Created by khy on 10/04/18.
|
||||
*/
|
||||
|
||||
public class MessageInviteActivity extends ToolBarActivity {
|
||||
|
||||
public static Intent getIntent(Context context, String messageType, String outerInfo, String entrance) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(EntranceConsts.KEY_MESSAGE_TYPE, messageType);
|
||||
bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance);
|
||||
bundle.putString(EntranceConsts.KEY_OUTER_INFO, outerInfo);
|
||||
return getTargetIntent(context, MessageInviteActivity.class, MessageNormalFragment.class, bundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDarkModeChanged() {
|
||||
super.onDarkModeChanged();
|
||||
ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white);
|
||||
}
|
||||
}
|
||||
@ -1,40 +0,0 @@
|
||||
package com.gh.gamecenter;
|
||||
|
||||
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.EntranceConsts;
|
||||
import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.message.KeFuFragment;
|
||||
|
||||
/**
|
||||
* Created by khy on 10/04/18.
|
||||
*/
|
||||
|
||||
public class MessageKeFuActivity extends ToolBarActivity {
|
||||
|
||||
@Override
|
||||
protected Intent provideNormalIntent() {
|
||||
return getTargetIntent(this, MessageKeFuActivity.class, KeFuFragment.class);
|
||||
}
|
||||
|
||||
public static Intent getIntent(Context context, String entrance) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance);
|
||||
return getTargetIntent(context, MessageKeFuActivity.class, KeFuFragment.class, bundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDarkModeChanged() {
|
||||
super.onDarkModeChanged();
|
||||
ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white);
|
||||
}
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
package com.gh.gamecenter;
|
||||
|
||||
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.EntranceConsts;
|
||||
import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.message.MessageNormalFragment;
|
||||
|
||||
/**
|
||||
* Created by khy on 10/04/18.
|
||||
*/
|
||||
|
||||
public class MessageVoteActivity extends ToolBarActivity {
|
||||
|
||||
public static Intent getIntent(Context context, String messageType, String outerInfo, String entrance) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance);
|
||||
bundle.putString(EntranceConsts.KEY_MESSAGE_TYPE, messageType);
|
||||
bundle.putString(EntranceConsts.KEY_OUTER_INFO, outerInfo);
|
||||
return getTargetIntent(context, MessageVoteActivity.class, MessageNormalFragment.class, bundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDarkModeChanged() {
|
||||
super.onDarkModeChanged();
|
||||
ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white);
|
||||
}
|
||||
}
|
||||
@ -25,6 +25,7 @@ import androidx.core.content.ContextCompat;
|
||||
import androidx.core.view.MotionEventCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.alibaba.android.arouter.facade.annotation.Route;
|
||||
import com.ethanhua.skeleton.Skeleton;
|
||||
import com.ethanhua.skeleton.ViewSkeletonScreen;
|
||||
import com.gh.base.DownloadToolbarActivity;
|
||||
@ -40,6 +41,7 @@ import com.gh.gamecenter.adapter.viewholder.DetailViewHolder;
|
||||
import com.gh.gamecenter.common.callback.OnRequestCallBackListener;
|
||||
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.eventbus.EBNetworkState;
|
||||
import com.gh.gamecenter.common.eventbus.EBReuse;
|
||||
import com.gh.gamecenter.common.retrofit.Response;
|
||||
@ -51,9 +53,9 @@ import com.gh.gamecenter.core.utils.ClickUtils;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
import com.gh.gamecenter.core.utils.MtaHelper;
|
||||
import com.gh.gamecenter.entity.NewsDetailEntity;
|
||||
import com.gh.gamecenter.eventbus.EBConcernChanged;
|
||||
import com.gh.gamecenter.eventbus.EBAddComment;
|
||||
import com.gh.gamecenter.eventbus.EBDeleteComment;
|
||||
import com.gh.gamecenter.feature.eventbus.EBConcernChanged;
|
||||
import com.gh.gamecenter.feature.eventbus.EBAddComment;
|
||||
import com.gh.gamecenter.feature.eventbus.EBDeleteComment;
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus;
|
||||
import com.gh.gamecenter.eventbus.EBPackage;
|
||||
import com.gh.gamecenter.feature.entity.GameEntity;
|
||||
@ -83,6 +85,7 @@ import retrofit2.HttpException;
|
||||
*
|
||||
* @author 黄壮华
|
||||
*/
|
||||
@Route(path = RouteConsts.activity.newsDetailActivity)
|
||||
public class NewsDetailActivity extends DownloadToolbarActivity implements OnClickListener, OnRequestCallBackListener {
|
||||
|
||||
RecyclerView mDetailRv;
|
||||
|
||||
@ -18,12 +18,12 @@ import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.facebook.drawee.view.SimpleDraweeView;
|
||||
import com.gh.common.util.MessageShareUtils;
|
||||
import com.gh.common.util.QRCodeUtils;
|
||||
import com.gh.gamecenter.common.base.activity.ToolBarActivity;
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts;
|
||||
import com.gh.gamecenter.common.utils.ImageUtils;
|
||||
import com.gh.common.util.MessageShareUtils;
|
||||
import com.gh.common.util.QRCodeUtils;
|
||||
import com.gh.gamecenter.entity.ConcernEntity;
|
||||
import com.gh.gamecenter.feature.entity.ConcernEntity;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ import com.gh.gamecenter.common.utils.ImageUtils;
|
||||
import com.gh.common.util.MessageShareUtils;
|
||||
import com.gh.common.util.QRCodeUtils;
|
||||
import com.gh.gamecenter.core.utils.StringUtils;
|
||||
import com.gh.gamecenter.entity.ConcernEntity;
|
||||
import com.gh.gamecenter.feature.entity.ConcernEntity;
|
||||
import com.gh.gamecenter.common.retrofit.ObservableUtil;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@ -16,6 +16,7 @@ import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_GAME_COLLECT
|
||||
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_INVOKE_ONLY;
|
||||
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_LIBAO;
|
||||
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_QQ;
|
||||
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_QQ_GAME;
|
||||
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_QQ_GROUP;
|
||||
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_QQ_QUN;
|
||||
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_QUESTION;
|
||||
@ -49,19 +50,25 @@ import android.util.Base64;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.alibaba.android.arouter.launcher.ARouter;
|
||||
import com.gh.common.util.CheckLoginUtils;
|
||||
import com.gh.common.util.DirectUtils;
|
||||
import com.gh.common.util.DownloadItemUtils;
|
||||
import com.gh.common.util.EntranceUtils;
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity;
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts;
|
||||
import com.gh.gamecenter.common.constant.RouteConsts;
|
||||
import com.gh.gamecenter.common.entity.CommunityEntity;
|
||||
import com.gh.gamecenter.common.entity.LinkEntity;
|
||||
import com.gh.gamecenter.common.entity.SimpleGameEntity;
|
||||
import com.gh.gamecenter.core.provider.IQGameProvider;
|
||||
import com.gh.gamecenter.core.utils.GsonUtils;
|
||||
import com.gh.gamecenter.core.utils.ToastUtils;
|
||||
import com.gh.gamecenter.entity.SubjectRecommendEntity;
|
||||
import com.gh.gamecenter.entity.VideoLinkEntity;
|
||||
import com.gh.gamecenter.feature.utils.PlatformUtils;
|
||||
import com.gh.gamecenter.login.entity.UserInfoEntity;
|
||||
import com.gh.gamecenter.login.user.UserManager;
|
||||
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel;
|
||||
import com.gh.gamecenter.video.videomanager.VideoManagerActivity;
|
||||
import com.gh.vspace.shortcut.OnCreateShortcutResult;
|
||||
@ -72,6 +79,14 @@ import com.lightgame.config.CommonDebug;
|
||||
import com.lightgame.utils.Utils;
|
||||
import com.muugi.shortcut.core.Executor;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function2;
|
||||
|
||||
/**
|
||||
* Created by LGT on 2016/11/16.
|
||||
* 链接跳转用
|
||||
@ -123,7 +138,7 @@ public class SkipActivity extends BaseActivity {
|
||||
DirectUtils.directToGameDetail(this, path, ENTRANCE_BROWSER, "true".equals(uri.getQueryParameter("auto_download")), to, null);
|
||||
break;
|
||||
case HOST_COLUMN:
|
||||
DirectUtils.directToSubject(this, path, uri.getQueryParameter(KEY_NAME), ENTRANCE_BROWSER, null);
|
||||
DirectUtils.directToSubject(this, path, uri.getQueryParameter(KEY_NAME), ENTRANCE_BROWSER, null, false);
|
||||
break;
|
||||
case HOST_SUGGESTION:
|
||||
String platform = uri.getQueryParameter(KEY_PLATFORM);
|
||||
@ -403,7 +418,15 @@ public class SkipActivity extends BaseActivity {
|
||||
DirectUtils.directToGameCollectionDetail(this, path, ENTRANCE_BROWSER, "", null);
|
||||
break;
|
||||
case HOST_GAME_COLLECTION_SQUARE:
|
||||
DirectUtils.directToGameCollectionSquare(this, ENTRANCE_BROWSER, "", "", "", "", "");
|
||||
DirectUtils.directToGameCollectionSquare(this, ENTRANCE_BROWSER, "", "", "", "", "", null);
|
||||
break;
|
||||
case HOST_QQ_GAME:
|
||||
String extJson = uri.getQueryParameter("ext");
|
||||
try {
|
||||
JSONObject extJsonObject = new JSONObject(extJson);
|
||||
String qqGameId = extJsonObject.optString("aid");
|
||||
DirectUtils.directToQGameById(this, qqGameId);
|
||||
} catch (JSONException ignored) {}
|
||||
break;
|
||||
default:
|
||||
EntranceUtils.jumpActivity(this, new Bundle()); // 跳转至首页
|
||||
|
||||
@ -19,6 +19,7 @@ import androidx.viewpager.widget.ViewPager
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.g00fy2.versioncompare.Version
|
||||
import com.gh.ad.AdDelegateHelper
|
||||
import com.gh.common.dialog.NewPrivacyPolicyDialogFragment
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.util.GameSubstituteRepositoryHelper.updateGameSubstituteRepository
|
||||
@ -33,7 +34,6 @@ import com.gh.gamecenter.common.tracker.TrackerLogger
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.provider.IAppProvider
|
||||
import com.gh.gamecenter.core.provider.IPackageUtilsProvider
|
||||
import com.gh.gamecenter.core.provider.IStartUpAdProvider
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.core.utils.*
|
||||
import com.gh.gamecenter.entity.PrivacyPolicyEntity
|
||||
@ -64,9 +64,6 @@ class SplashScreenActivity : BaseActivity() {
|
||||
private var mStartMainActivityDirectly = false // 是否不需要用户点击立即体验就直接跳转首页
|
||||
private var mViewModel: SplashScreenViewModel? = null
|
||||
private var mShouldPrefetchData = true
|
||||
private val mStartUpAdProvider by lazy {
|
||||
ARouter.getInstance().build(RouteConsts.provider.adSdk).navigation() as? IStartUpAdProvider
|
||||
}
|
||||
|
||||
private val mPermissions = arrayOf(
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
@ -122,18 +119,13 @@ class SplashScreenActivity : BaseActivity() {
|
||||
"这个弹窗只会在右上角有环境标签的测试包出现\n进入应用以后还可以到关于我们页面长按应用图标重新选择",
|
||||
"正式环境",
|
||||
"测试环境",
|
||||
object : EmptyCallback {
|
||||
override fun onCallback() {
|
||||
SPUtils.setBoolean(Constants.SP_IS_DEV_ENV, false)
|
||||
showPrivacyDialog(guideLayout)
|
||||
}
|
||||
{
|
||||
SPUtils.setBoolean(Constants.SP_IS_DEV_ENV, false)
|
||||
showPrivacyDialog(guideLayout)
|
||||
},
|
||||
object : EmptyCallback {
|
||||
override fun onCallback() {
|
||||
SPUtils.setBoolean(Constants.SP_IS_DEV_ENV, true)
|
||||
showPrivacyDialog(guideLayout)
|
||||
}
|
||||
|
||||
{
|
||||
SPUtils.setBoolean(Constants.SP_IS_DEV_ENV, true)
|
||||
showPrivacyDialog(guideLayout)
|
||||
},
|
||||
false,
|
||||
"",
|
||||
@ -285,7 +277,6 @@ class SplashScreenActivity : BaseActivity() {
|
||||
overridePendingTransition(0, 0)
|
||||
startActivity(intent)
|
||||
doFlavorInit()
|
||||
initStartUpAdSDK()
|
||||
logAppLaunch()
|
||||
finish()
|
||||
}
|
||||
@ -298,14 +289,6 @@ class SplashScreenActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun initStartUpAdSDK() {
|
||||
mStartUpAdProvider?.run {
|
||||
if (shouldEnableSDK(HaloApp.getInstance().channel)) {
|
||||
initSDK(applicationContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getGitLogString(): String {
|
||||
if (com.gh.gamecenter.common.BuildConfig.BUILD_TIME != 0L) {
|
||||
val stringBuilder = StringBuilder()
|
||||
|
||||
@ -13,7 +13,7 @@ import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.utils.EnvHelper
|
||||
import com.gh.gamecenter.common.utils.updateStatusBarColor
|
||||
import com.gh.gamecenter.entity.ConcernEntity
|
||||
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
|
||||
@ -197,11 +197,23 @@ open class WebActivity : ToolBarActivity() {
|
||||
context: Context?,
|
||||
concernEntity: ConcernEntity,
|
||||
entrance: String?
|
||||
): Intent {
|
||||
return getIntentByNews(context, concernEntity.link, concernEntity.getGameName(), concernEntity.id, entrance)
|
||||
}
|
||||
|
||||
// 获取游戏动态详情页
|
||||
@JvmStatic
|
||||
fun getIntentByNews(
|
||||
context: Context?,
|
||||
concernLink: String?,
|
||||
concernGameName: String,
|
||||
concernId: String?,
|
||||
entrance: String?
|
||||
): Intent {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(EntranceConsts.KEY_URL, concernEntity.link)
|
||||
bundle.putString(EntranceConsts.KEY_GAMENAME, concernEntity.getGameName())
|
||||
bundle.putString(EntranceConsts.KEY_NEWSID, concernEntity.id)
|
||||
bundle.putString(EntranceConsts.KEY_URL, concernLink)
|
||||
bundle.putString(EntranceConsts.KEY_GAMENAME, concernGameName)
|
||||
bundle.putString(EntranceConsts.KEY_NEWSID, concernId)
|
||||
bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance)
|
||||
return getTargetIntent(
|
||||
context,
|
||||
|
||||
@ -20,9 +20,9 @@ import com.gh.gamecenter.common.utils.ImageUtils;
|
||||
import com.gh.gamecenter.common.utils.TextHelper;
|
||||
import com.gh.gamecenter.common.viewholder.FooterViewHolder;
|
||||
import com.gh.gamecenter.core.utils.MtaHelper;
|
||||
import com.gh.gamecenter.entity.ArticleCommentParent;
|
||||
import com.gh.gamecenter.entity.CommentEntity;
|
||||
import com.gh.gamecenter.eventbus.EBDeleteComment;
|
||||
import com.gh.gamecenter.feature.entity.ArticleCommentParent;
|
||||
import com.gh.gamecenter.feature.entity.CommentEntity;
|
||||
import com.gh.gamecenter.feature.eventbus.EBDeleteComment;
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager;
|
||||
import com.lightgame.adapter.BaseRecyclerAdapter;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
@ -39,8 +39,8 @@ import com.gh.gamecenter.core.utils.StringUtils;
|
||||
import com.gh.gamecenter.databinding.LibaodetailItemContentBinding;
|
||||
import com.gh.gamecenter.databinding.LibaodetailItemTopBinding;
|
||||
import com.gh.gamecenter.entity.LibaoDetailEntity;
|
||||
import com.gh.gamecenter.entity.LibaoEntity;
|
||||
import com.gh.gamecenter.entity.LibaoStatusEntity;
|
||||
import com.gh.gamecenter.feature.entity.LibaoEntity;
|
||||
import com.gh.gamecenter.feature.entity.LibaoStatusEntity;
|
||||
import com.gh.gamecenter.feature.entity.GameEntity;
|
||||
import com.gh.gamecenter.feature.entity.MeEntity;
|
||||
import com.gh.gamecenter.feature.entity.UserDataLibaoEntity;
|
||||
|
||||
@ -36,13 +36,13 @@ import com.gh.gamecenter.WebActivity;
|
||||
import com.gh.gamecenter.adapter.viewholder.CommentHeadViewHolder;
|
||||
import com.gh.gamecenter.adapter.viewholder.CommentViewHolder;
|
||||
import com.gh.gamecenter.common.viewholder.FooterViewHolder;
|
||||
import com.gh.gamecenter.adapter.viewholder.NewsDigestViewHolder;
|
||||
import com.gh.gamecenter.feature.databinding.NewsDigestItemBinding;
|
||||
import com.gh.gamecenter.feature.viewholder.NewsDigestViewHolder;
|
||||
import com.gh.gamecenter.databinding.CommentHeadItemBinding;
|
||||
import com.gh.gamecenter.databinding.NewsDigestItemBinding;
|
||||
import com.gh.gamecenter.entity.ArticleCommentParent;
|
||||
import com.gh.gamecenter.entity.CommentEntity;
|
||||
import com.gh.gamecenter.entity.ConcernEntity;
|
||||
import com.gh.gamecenter.eventbus.EBDeleteComment;
|
||||
import com.gh.gamecenter.feature.entity.ArticleCommentParent;
|
||||
import com.gh.gamecenter.feature.entity.CommentEntity;
|
||||
import com.gh.gamecenter.feature.entity.ConcernEntity;
|
||||
import com.gh.gamecenter.feature.eventbus.EBDeleteComment;
|
||||
import com.gh.gamecenter.manager.VisitManager;
|
||||
import com.gh.gamecenter.common.retrofit.JSONObjectResponse;
|
||||
import com.gh.gamecenter.common.retrofit.OkHttpCache;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
package com.gh.gamecenter.adapter;
|
||||
|
||||
import com.gh.gamecenter.entity.CommentEntity;
|
||||
import com.gh.gamecenter.feature.entity.CommentEntity;
|
||||
|
||||
public interface OnCommentCallBackListener {
|
||||
void onCommentCallback(CommentEntity entity);
|
||||
|
||||
@ -20,6 +20,7 @@ import com.gh.common.chain.CheckDownloadHandler;
|
||||
import com.gh.common.chain.CheckStoragePermissionHandler;
|
||||
import com.gh.common.chain.DownloadDialogHelperHandler;
|
||||
import com.gh.common.chain.GamePermissionHandler;
|
||||
import com.gh.common.chain.LandPageAddressHandler;
|
||||
import com.gh.common.chain.OverseaDownloadHandler;
|
||||
import com.gh.common.chain.PackageCheckHandler;
|
||||
import com.gh.common.chain.UnsupportedFeatureHandler;
|
||||
@ -237,6 +238,7 @@ public class DetailViewHolder {
|
||||
builder.addHandler(new DownloadDialogHelperHandler());
|
||||
builder.addHandler(new CertificationHandler());
|
||||
builder.addHandler(new VersionNumberHandler());
|
||||
builder.addHandler(new LandPageAddressHandler());
|
||||
builder.addHandler(new OverseaDownloadHandler());
|
||||
builder.addHandler(new CheckDownloadHandler());
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ package com.gh.gamecenter.adapter.viewholder;
|
||||
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder;
|
||||
import com.gh.gamecenter.common.callback.OnListClickListener;
|
||||
import com.gh.gamecenter.databinding.LibaoItemBinding;
|
||||
import com.gh.gamecenter.entity.LibaoEntity;
|
||||
import com.gh.gamecenter.feature.entity.LibaoEntity;
|
||||
|
||||
/**
|
||||
* Created by khy on 2016/12/12.
|
||||
|
||||
@ -7,6 +7,7 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.gh.common.util.NewFlatLogUtils
|
||||
import com.gh.gamecenter.common.baselist.ListViewModel
|
||||
import com.gh.gamecenter.common.baselist.LoadStatus
|
||||
import com.gh.gamecenter.common.baselist.LoadType
|
||||
import com.gh.gamecenter.common.retrofit.BiResponse
|
||||
import com.gh.gamecenter.common.utils.toRequestBody
|
||||
@ -15,6 +16,7 @@ import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.utils.ApkActiveUtils
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.vspace.VArchiveHelper
|
||||
import com.gh.vspace.db.VArchiveEntity
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.Observable
|
||||
@ -29,8 +31,7 @@ class CloudArchiveManagerViewModel(
|
||||
private val mType: MyArchiveFragment.Type = MyArchiveFragment.Type.MY_ARCHIVE,
|
||||
val gameId: String,
|
||||
val configUrl: String
|
||||
) :
|
||||
ListViewModel<ArchiveEntity, ArchiveEntity>(application) {
|
||||
) : ListViewModel<ArchiveEntity, ArchiveEntity>(application) {
|
||||
|
||||
companion object {
|
||||
private const val SORT_TYPE_CREATE = "time.create:-1"
|
||||
@ -47,50 +48,98 @@ class CloudArchiveManagerViewModel(
|
||||
|
||||
init {
|
||||
getGameDigest()
|
||||
|
||||
if (mType == MyArchiveFragment.Type.MY_DOWNLOAD_ARCHIVE) {
|
||||
syncDownloadedArchives()
|
||||
}
|
||||
|
||||
if (configUrl.isNotEmpty()) getArchiveConfigString(configUrl)
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步已下载但还没同步到接口端的存档数据
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
fun syncDownloadedArchives() {
|
||||
val unSyncedDownloadedArchivesIdSet = hashSetOf<String>()
|
||||
val unSyncedDownloadedArchivesList = arrayListOf<VArchiveEntity>()
|
||||
VArchiveHelper.getVArchiveEntityList().forEach {
|
||||
if (it.isLocal == 0) {
|
||||
unSyncedDownloadedArchivesIdSet.add(it.id)
|
||||
unSyncedDownloadedArchivesList.add(it)
|
||||
}
|
||||
}
|
||||
mNewApi.syncGameArchives(gameId, unSyncedDownloadedArchivesIdSet.toRequestBody())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(object : BiResponse<ResponseBody>() {
|
||||
override fun onSuccess(data: ResponseBody) {
|
||||
unSyncedDownloadedArchivesList.forEach {
|
||||
it.isLocal = 1
|
||||
}
|
||||
if (unSyncedDownloadedArchivesList.isNotEmpty()) {
|
||||
VArchiveHelper.updateArchives(unSyncedDownloadedArchivesList)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun mergeResultLiveData() {
|
||||
mResultLiveData.addSource(mListLiveData) { list ->
|
||||
list.forEach { it.gameId = gameId }
|
||||
mResultLiveData.postValue(list)
|
||||
|
||||
if (mType == MyArchiveFragment.Type.MY_DOWNLOAD_ARCHIVE) {
|
||||
// 优先使用本地数据(未成功同步的数据),相同 ID 的网络数据屏蔽掉,加载到的网络数据补充到列表后面
|
||||
val localIdSet = hashSetOf<String>()
|
||||
val downloadList = VArchiveHelper.getVArchiveEntityList()
|
||||
val archiveEntityList = arrayListOf<ArchiveEntity>()
|
||||
for (vArchiveEntity in downloadList) {
|
||||
if (vArchiveEntity.gameId == gameId
|
||||
&& vArchiveEntity.type == 1
|
||||
&& vArchiveEntity.isLocal == 0
|
||||
) {
|
||||
localIdSet.add(vArchiveEntity.id)
|
||||
|
||||
archiveEntityList.add(
|
||||
ArchiveEntity(
|
||||
id = vArchiveEntity.id,
|
||||
name = vArchiveEntity.name,
|
||||
gameId = vArchiveEntity.gameId,
|
||||
desc = vArchiveEntity.descContent,
|
||||
url = vArchiveEntity.url,
|
||||
configUrl = vArchiveEntity.configUrl,
|
||||
md5 = vArchiveEntity.md5,
|
||||
time = ArchiveEntity.Time(create = vArchiveEntity.time),
|
||||
gameVersion = vArchiveEntity.gameVersion
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
list.forEach {
|
||||
if (!localIdSet.contains(it.id)) {
|
||||
archiveEntityList.add(it)
|
||||
}
|
||||
}
|
||||
if (archiveEntityList.isNotEmpty()) {
|
||||
// 若数据不够用
|
||||
mLoadStatusLiveData.postValue(LoadStatus.LIST_LOADED)
|
||||
}
|
||||
mResultLiveData.postValue(archiveEntityList)
|
||||
} else {
|
||||
mResultLiveData.postValue(list)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideDataObservable(page: Int): Observable<List<ArchiveEntity>>? = when (mType) {
|
||||
MyArchiveFragment.Type.MY_ARCHIVE -> {
|
||||
mNewApi.getMyArchives(gameId, page, SORT_TYPE_CREATE)
|
||||
}
|
||||
MyArchiveFragment.Type.MY_ARCHIVE -> mNewApi.getMyArchives(gameId, page, SORT_TYPE_CREATE)
|
||||
MyArchiveFragment.Type.MY_DOWNLOAD_ARCHIVE -> null
|
||||
MyArchiveFragment.Type.MY_SHARE_ARCHIVE -> mNewApi.getMyShareArchives(gameId, page, SORT_TYPE_SHARE_AND_CREATE)
|
||||
}
|
||||
|
||||
override fun provideDataSingle(page: Int): Single<MutableList<ArchiveEntity>>? {
|
||||
return if (mType == MyArchiveFragment.Type.MY_DOWNLOAD_ARCHIVE) {
|
||||
Single.create { emitter ->
|
||||
val downloadList = VArchiveHelper.vArchiveDao.getAll()
|
||||
val archiveEntityList = arrayListOf<ArchiveEntity>()
|
||||
if (downloadList != null) {
|
||||
for (vArchiveEntity in downloadList) {
|
||||
if (vArchiveEntity.gameId == gameId && vArchiveEntity.type == 1) {
|
||||
archiveEntityList.add(
|
||||
ArchiveEntity(
|
||||
id = vArchiveEntity.id,
|
||||
name = vArchiveEntity.name,
|
||||
gameId = vArchiveEntity.gameId,
|
||||
desc = vArchiveEntity.descContent,
|
||||
url = vArchiveEntity.url,
|
||||
configUrl = vArchiveEntity.configUrl,
|
||||
md5 = vArchiveEntity.md5,
|
||||
time = ArchiveEntity.Time(create = vArchiveEntity.time),
|
||||
gameVersion = vArchiveEntity.gameVersion
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
emitter.onSuccess(archiveEntityList)
|
||||
}
|
||||
mNewApi.getArchivesDownloadHistories(gameId, page, 20)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
@ -196,6 +245,9 @@ class CloudArchiveManagerViewModel(
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除我的存档
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
fun deleteArchive(archiveEntity: ArchiveEntity) {
|
||||
mNewApi.deleteMyArchive(gameId, archiveEntity.id)
|
||||
@ -214,6 +266,27 @@ class CloudArchiveManagerViewModel(
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除我下过的存档
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
fun deleteSyncedArchive(archiveEntity: ArchiveEntity) {
|
||||
mNewApi.deleteSyncedGameArchive(gameId, archiveEntity.id)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BiResponse<ResponseBody>() {
|
||||
override fun onSuccess(data: ResponseBody) {
|
||||
load(LoadType.REFRESH)
|
||||
Utils.toast(getApplication(), "删除成功")
|
||||
}
|
||||
|
||||
override fun onFailure(exception: Exception) {
|
||||
super.onFailure(exception)
|
||||
Utils.toast(getApplication(), "删除失败")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 通过url获取config字符串内容
|
||||
private fun getArchiveConfigString(url: String) {
|
||||
|
||||
@ -120,6 +120,11 @@ open class MyArchiveFragment : ListFragment<ArchiveEntity, CloudArchiveManagerVi
|
||||
open fun onEventMainThread(reuse: EBReuse) {
|
||||
if (reuse.type == Constants.LOGIN_TAG) {
|
||||
onLoadRefresh()
|
||||
|
||||
// 从未登录变成登录状态时,同步本地已下载的数据
|
||||
if (mType == Type.MY_DOWNLOAD_ARCHIVE) {
|
||||
mViewModel.syncDownloadedArchives()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -86,6 +86,7 @@ class MyArchiveOptionDialogFragment(
|
||||
deleteLocalArchive(entity.md5)
|
||||
EventBus.getDefault().post(EBReuse("RefreshArchive"))
|
||||
}
|
||||
mViewModel.deleteSyncedArchive(entity)
|
||||
}
|
||||
MyArchiveFragment.Type.MY_SHARE_ARCHIVE -> {
|
||||
mViewModel.cancelShareArchive(entity)
|
||||
|
||||
@ -9,7 +9,7 @@ import com.gh.gamecenter.core.utils.UrlFilterUtils;
|
||||
import com.gh.gamecenter.common.baselist.ListViewModel;
|
||||
import com.gh.gamecenter.common.baselist.LoadType;
|
||||
import com.gh.gamecenter.feature.entity.NewsEntity;
|
||||
import com.gh.gamecenter.entity.ViewsEntity;
|
||||
import com.gh.gamecenter.feature.entity.ViewsEntity;
|
||||
import com.gh.gamecenter.info.NewsViewsRepository;
|
||||
import com.gh.gamecenter.login.user.UserManager;
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager;
|
||||
|
||||
@ -10,7 +10,7 @@ import com.gh.gamecenter.common.baselist.ListViewModel
|
||||
import com.gh.gamecenter.common.baselist.LoadType
|
||||
import com.gh.gamecenter.entity.MyVideoEntity
|
||||
import com.gh.gamecenter.entity.PersonalHistoryEntity
|
||||
import com.gh.gamecenter.entity.User
|
||||
import com.gh.gamecenter.feature.entity.User
|
||||
import com.gh.gamecenter.login.user.UserManager
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
|
||||
@ -9,15 +9,19 @@ import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.gh.ad.AdDelegateHelper
|
||||
import com.gh.common.util.HomePluggableHelper
|
||||
import com.gh.common.util.PackageInstaller
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.DownloadManagerActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.fragment.BaseFragment_TabLayout
|
||||
import com.gh.gamecenter.common.databinding.FragmentDownloadBinding
|
||||
import com.gh.gamecenter.common.eventbus.EBMiPush
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.common.utils.goneIf
|
||||
import com.gh.gamecenter.common.utils.visibleIf
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.databinding.TabItemDownloadNumberBinding
|
||||
import com.gh.gamecenter.entity.HomePluggableFilterEntity
|
||||
import com.gh.gamecenter.feature.entity.PluginLocation
|
||||
@ -42,12 +46,17 @@ class DownloadFragment : BaseFragment_TabLayout() {
|
||||
|
||||
private var mPermanentInactivePluggableApkList: List<HomePluggableFilterEntity>? = null
|
||||
|
||||
private val mBinding by lazy { FragmentDownloadBinding.inflate(layoutInflater) }
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
mPermanentInactivePluggableApkList = HomePluggableHelper.getPermanentInactivePluggablePackage()
|
||||
}
|
||||
|
||||
override fun getLayoutId() = 0
|
||||
override fun getInflatedLayout() = mBinding.root
|
||||
|
||||
override fun initFragmentList(fragments: MutableList<Fragment>) {
|
||||
fragments.add(GameDownloadFragment())
|
||||
fragments.add(UpdatableGameFragment())
|
||||
@ -94,6 +103,18 @@ class DownloadFragment : BaseFragment_TabLayout() {
|
||||
mDownloadManager.markDownloadedTaskAsRead()
|
||||
}
|
||||
|
||||
val ad = AdDelegateHelper.getDownloadManagerAd()?.thirdPartyAd
|
||||
if (ad != null) {
|
||||
AdDelegateHelper.requestBannerAd(
|
||||
this,
|
||||
mBinding.adContainer,
|
||||
ad,
|
||||
DisplayUtils.getScreenWidthInDp(requireActivity())
|
||||
) { isSuccess ->
|
||||
mBinding.maskView.goneIf(!isSuccess)
|
||||
}
|
||||
}
|
||||
|
||||
val pathOfPackageToInstall = activity?.intent?.getStringExtra(KEY_PATH_OF_PACKAGE_TO_INSTALL)
|
||||
if (!TextUtils.isEmpty(pathOfPackageToInstall)) {
|
||||
PackageInstaller.install(requireContext(), false, pathOfPackageToInstall)
|
||||
@ -179,6 +200,7 @@ class DownloadFragment : BaseFragment_TabLayout() {
|
||||
mDownloadNumberTv.setBackgroundColor(Color.TRANSPARENT)
|
||||
mDownloadNumberTv.text = downloadingCount.toString()
|
||||
}
|
||||
|
||||
mDownloadManager.isContainsUnreadDownloadedTask -> {
|
||||
layoutParams.width = 6F.dip2px()
|
||||
layoutParams.height = 6F.dip2px()
|
||||
@ -186,6 +208,7 @@ class DownloadFragment : BaseFragment_TabLayout() {
|
||||
mDownloadNumberTv.setBackgroundResource(R.drawable.oval_hint_red_bg)
|
||||
mDownloadNumberTv.text = ""
|
||||
}
|
||||
|
||||
else -> mDownloadNumberTv.visibility = View.GONE
|
||||
}
|
||||
mDownloadNumberTv.layoutParams = layoutParams
|
||||
|
||||
@ -14,7 +14,7 @@ import com.gh.gamecenter.common.retrofit.Response
|
||||
import com.gh.gamecenter.core.utils.ThirdPartyPackageHelper.getGameId
|
||||
import com.gh.gamecenter.feature.entity.ApkEntity
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.GameInstall
|
||||
import com.gh.gamecenter.feature.entity.GameInstall
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
|
||||
@ -23,7 +23,7 @@ import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.core.utils.EmptyCallback
|
||||
import com.gh.gamecenter.databinding.FragmentMyGameBinding
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.GameInstall
|
||||
import com.gh.gamecenter.feature.entity.GameInstall
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.gh.gamecenter.fragment.MainWrapperFragment
|
||||
|
||||
@ -5,6 +5,7 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.view.setPadding
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@ -66,7 +67,7 @@ class UpdatableGameAdapter(private var mViewModel: UpdatableGameViewModel) :
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
val item = mItemList!![position]
|
||||
return when {
|
||||
item.header != null || item.ignoredUpdateHeader != null -> TYPE_HEADER
|
||||
item.header != null || item.ignoredUpdateHeader != null || item.landPageAddressDialogHeader != null -> TYPE_HEADER
|
||||
item.normalUpdate != null || item.ignoredUpdate != null -> TYPE_NORMAL_GAME
|
||||
item.normalUpdateWithArrow != null -> TYPE_NORMAL_GAME_WITH_ARROW
|
||||
item.otherVersionUpdateHint != null -> TYPE_OTHER_VERSION_GAME_HINT
|
||||
@ -89,6 +90,7 @@ class UpdatableGameAdapter(private var mViewModel: UpdatableGameViewModel) :
|
||||
height = 8F.dip2px()
|
||||
}
|
||||
}
|
||||
|
||||
else -> BlankDividerViewHolder(parent.toBinding())
|
||||
}
|
||||
}
|
||||
@ -105,19 +107,45 @@ class UpdatableGameAdapter(private var mViewModel: UpdatableGameViewModel) :
|
||||
holder.binding.updateAllBtn.text = itemData.miscUpdateText
|
||||
holder.binding.updateAllBtn.setOnClickListener {
|
||||
if (itemData.miscUpdateText == "全部更新") {
|
||||
if (mViewModel.hasLandPageAddressDialog()) {
|
||||
DialogHelper.showDialog(
|
||||
it.context,
|
||||
title = it.context.getString(R.string.update_all_has_land_page_address_dialog_title),
|
||||
content = it.context.getString(R.string.update_all_has_land_page_address_dialog_content),
|
||||
confirmText = it.context.getString(R.string.update_all_has_land_page_address_dialog_confirm),
|
||||
cancelText = ""
|
||||
)
|
||||
}
|
||||
mViewModel.updateAllMatchedVersionValidUpdate()
|
||||
}
|
||||
}
|
||||
holder.binding.infoTv.text = itemData.header ?: itemData.ignoredUpdateHeader
|
||||
holder.binding.infoTv.text =
|
||||
itemData.header ?: itemData.ignoredUpdateHeader ?: itemData.landPageAddressDialogHeader
|
||||
if (itemData.header != null) {
|
||||
holder.binding.infoTv.setTextColor(R.color.text_title.toColor(mContext))
|
||||
(holder.binding.infoTv.layoutParams as ConstraintLayout.LayoutParams).apply {
|
||||
bottomToBottom = ConstraintLayout.LayoutParams.UNSET
|
||||
}
|
||||
holder.binding.root.setOnClickListener(null)
|
||||
holder.binding.root.setPadding(16F.dip2px(), 16F.dip2px(), 16F.dip2px(), 0)
|
||||
holder.binding.infoTv.removeDrawable()
|
||||
} else if (itemData.landPageAddressDialogHeader != null) {
|
||||
holder.binding.infoTv.setTextColor(R.color.theme_yellow.toColor(mContext))
|
||||
(holder.binding.infoTv.layoutParams as ConstraintLayout.LayoutParams).apply {
|
||||
bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID
|
||||
}
|
||||
holder.binding.root.setOnClickListener(null)
|
||||
holder.binding.root.setPadding(16F.dip2px(), 0, 16F.dip2px(), 0)
|
||||
holder.binding.root.setBackgroundColor(R.color.home_realname_error.toColor(mContext))
|
||||
} else {
|
||||
holder.binding.infoTv.setTextColor(R.color.text_subtitleDesc.toColor(mContext))
|
||||
(holder.binding.infoTv.layoutParams as ConstraintLayout.LayoutParams).apply {
|
||||
bottomToBottom = ConstraintLayout.LayoutParams.UNSET
|
||||
}
|
||||
holder.binding.root.setOnClickListener {
|
||||
mViewModel.toggleIgnoredUpdateVisibility()
|
||||
}
|
||||
holder.binding.root.setPadding(16F.dip2px(), 16F.dip2px(), 16F.dip2px(), 0)
|
||||
holder.binding.infoTv.setDrawableEnd(
|
||||
if (mViewModel.isIgnoredUpdateExpanded()) {
|
||||
R.drawable.ic_arrow_up_grey.toDrawable()
|
||||
@ -128,6 +156,7 @@ class UpdatableGameAdapter(private var mViewModel: UpdatableGameViewModel) :
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is BlankDividerViewHolder -> {
|
||||
if (itemData.divider == UpdatableGameViewModel.GREY) {
|
||||
holder.binding.container.setBackgroundColor(R.color.background.toColor(holder.binding.root.context))
|
||||
@ -137,6 +166,7 @@ class UpdatableGameAdapter(private var mViewModel: UpdatableGameViewModel) :
|
||||
holder.binding.container.setBackgroundColor(R.color.background_white.toColor(holder.binding.root.context))
|
||||
}
|
||||
}
|
||||
|
||||
is UpdatableGameViewHolder -> {
|
||||
val update: GameUpdateEntity = (itemData.normalUpdate
|
||||
?: itemData.normalUpdateWithArrow
|
||||
@ -188,6 +218,7 @@ class UpdatableGameAdapter(private var mViewModel: UpdatableGameViewModel) :
|
||||
|
||||
generateExposureEvent(update)
|
||||
}
|
||||
|
||||
is UpdatableOtherVersionGameHintViewHolder -> {
|
||||
holder.binding.root.setOnClickListener {
|
||||
mViewModel.toggleOtherVersionVisibility(itemData.miscPackageName)
|
||||
@ -310,10 +341,12 @@ class UpdatableGameAdapter(private var mViewModel: UpdatableGameViewModel) :
|
||||
if (update.isPluggable) DownloadButton.ButtonStyle.DOWNLOADING_PLUGIN else DownloadButton.ButtonStyle.DOWNLOADING_NORMAL
|
||||
updateBtn.progress = (downloadEntity.percent * 10).toInt()
|
||||
}
|
||||
|
||||
DownloadStatus.waiting -> {
|
||||
updateBtn.setText(R.string.waiting)
|
||||
updateBtn.buttonStyle = DownloadButton.ButtonStyle.WAITING
|
||||
}
|
||||
|
||||
DownloadStatus.timeout,
|
||||
DownloadStatus.neterror,
|
||||
DownloadStatus.subscribe,
|
||||
@ -322,11 +355,13 @@ class UpdatableGameAdapter(private var mViewModel: UpdatableGameViewModel) :
|
||||
updateBtn.setText(R.string.resume)
|
||||
updateBtn.buttonStyle = DownloadButton.ButtonStyle.NORMAL
|
||||
}
|
||||
|
||||
DownloadStatus.done -> {
|
||||
updateBtn.setText(R.string.install)
|
||||
updateBtn.buttonStyle =
|
||||
if (update.isPluggable) DownloadButton.ButtonStyle.INSTALL_PLUGIN else DownloadButton.ButtonStyle.INSTALL_NORMAL
|
||||
}
|
||||
|
||||
else -> {
|
||||
// do nothing
|
||||
}
|
||||
@ -340,6 +375,13 @@ class UpdatableGameAdapter(private var mViewModel: UpdatableGameViewModel) :
|
||||
if ("更新" == str || str.contains("化")) {
|
||||
// 这里用 CurrentActivity 不用 view.context 的原因是
|
||||
// view.context 在 5.0 以下设备会使用 TintContextWrapper 包一层导致类型转换异常
|
||||
if ("更新" == str && update.isLandPageAddressDialog()) {// 第三方落地页跳转直接展示跳转弹窗
|
||||
DialogUtils.showLandPageAddressDialog(it.context, update.transformGameEntity()) {// 跳转第三方落地页
|
||||
DirectUtils.directToExternalBrowser(it.context, update.landPageAddressDialog!!.link!!)
|
||||
}
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
(CurrentActivityHolder.getCurrentActivity() as? FragmentActivity)?.checkStoragePermissionBeforeAction {
|
||||
DialogUtils.checkDownload(
|
||||
updateBtn.context,
|
||||
|
||||
@ -36,6 +36,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class UpdatableGameViewModel(
|
||||
application: Application,
|
||||
@ -50,6 +51,8 @@ class UpdatableGameViewModel(
|
||||
|
||||
private var mUpdatableListLiveData = MutableLiveData<ArrayList<UpdatableDataItem>>()
|
||||
|
||||
private var mHasLandPageAddressDialog = false // 是否存在由第三方提供的游戏下载
|
||||
|
||||
private val mSuppressUpdateDao by lazy { SuppressUpdateDao() }
|
||||
private val mIgnoredUpdateDao by lazy { IgnoredUpdateDao() }
|
||||
private val mDownloadedGameIdAndPackageNameDao by lazy { DownloadedGameIdAndPackageNameDao() }
|
||||
@ -77,7 +80,8 @@ class UpdatableGameViewModel(
|
||||
// 筛选仅下载管理出现的插件化更新
|
||||
if (update.isShowPlugin(PluginLocation.only_index)
|
||||
&& update.downloadStatus != Constants.V_GAME
|
||||
&& update.downloadStatus != Constants.V_GAME_32) {
|
||||
&& update.downloadStatus != Constants.V_GAME_32
|
||||
) {
|
||||
val platform =
|
||||
PlatformUtils.getInstance(getApplication()).getPlatformName(update.platform)
|
||||
if (!platform.isNullOrEmpty() && "官方版" != platform) {
|
||||
@ -273,6 +277,7 @@ class UpdatableGameViewModel(
|
||||
val validPackageUpdateList: ArrayList<PackageUpdate> = arrayListOf() // 按钮为更新的我的游戏列表
|
||||
val invalidPackageUpdateList: ArrayList<PackageUpdate> = arrayListOf() // 按钮为启动的我的游戏列表
|
||||
val ignoredPackageUpdateList: ArrayList<PackageUpdate> = arrayListOf() // 被隐藏的我的游戏列表
|
||||
val landPageAddressUpdateList: ArrayList<PackageUpdate> = arrayListOf() // 跳转第三方落地页的游戏列表
|
||||
|
||||
val ignoredUpdateList = mIgnoredUpdateDao.getAll()
|
||||
|
||||
@ -296,17 +301,26 @@ class UpdatableGameViewModel(
|
||||
ignoredUpdateList?.contains(matchedPackageName + matchedVersionName) == true -> {
|
||||
ignoredPackageUpdateList.add(packageUpdate)
|
||||
}
|
||||
|
||||
packageUpdate.matchedVersionUpdate.version == currentlyUpdatableVersion
|
||||
&& !PackagesManager.isCanUpdate(installedGhId, matchedPackageName)
|
||||
&& !isUpdatePluggableRelated(packageUpdate.matchedVersionUpdate) -> {
|
||||
&& !isUpdatePluggableRelated(packageUpdate.matchedVersionUpdate)
|
||||
&& !packageUpdate.matchedVersionUpdate.isLandPageAddressDialog() -> {
|
||||
invalidPackageUpdateList.add(packageUpdate)
|
||||
}
|
||||
|
||||
packageUpdate.matchedVersionUpdate.isLandPageAddressDialog() -> {// 第三方落地页跳转
|
||||
landPageAddressUpdateList.add(packageUpdate)
|
||||
}
|
||||
|
||||
else -> {
|
||||
validPackageUpdateList.add(packageUpdate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mHasLandPageAddressDialog = landPageAddressUpdateList.isNotEmpty()
|
||||
|
||||
// 构建装饰好的页面列表
|
||||
// 正常的我的版本
|
||||
if (validPackageUpdateList.isNotEmpty()) {
|
||||
@ -406,6 +420,34 @@ class UpdatableGameViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
// 游戏下载资源由第三方提供
|
||||
if (landPageAddressUpdateList.isNotEmpty()) {
|
||||
if (updatableDataItemList.size != 0) {
|
||||
updatableDataItemList.add(UpdatableDataItem(divider = WHITE))
|
||||
}
|
||||
updatableDataItemList.add(UpdatableDataItem(landPageAddressDialogHeader = "以下游戏下载资源由第三方提供"))
|
||||
for (packageUpdate in landPageAddressUpdateList) {
|
||||
if (packageUpdate.mismatchedVersionUpdateList.isNotEmpty()) {
|
||||
updatableDataItemList.add(UpdatableDataItem(normalUpdateWithArrow = packageUpdate.matchedVersionUpdate))
|
||||
updatableDataItemList.add(
|
||||
UpdatableDataItem(
|
||||
otherVersionUpdateHint = mOtherVersionExpandedMap[packageUpdate.matchedVersionUpdate.packageName] == true,
|
||||
miscPackageName = packageUpdate.matchedVersionUpdate.packageName,
|
||||
miscVersion = packageUpdate.matchedVersionUpdate.currentVersion ?: ""
|
||||
)
|
||||
)
|
||||
if (mOtherVersionExpandedMap[packageUpdate.matchedVersionUpdate.packageName] == true) {
|
||||
for (update in packageUpdate.mismatchedVersionUpdateList) {
|
||||
updatableDataItemList.add(UpdatableDataItem(otherVersionUpdate = update))
|
||||
}
|
||||
updatableDataItemList.add(UpdatableDataItem(divider = BLUE))
|
||||
}
|
||||
} else {
|
||||
updatableDataItemList.add(UpdatableDataItem(normalUpdate = packageUpdate.matchedVersionUpdate))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return updatableDataItemList
|
||||
}
|
||||
|
||||
@ -558,6 +600,11 @@ class UpdatableGameViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存在第三方提供下载的游戏
|
||||
*/
|
||||
fun hasLandPageAddressDialog(): Boolean = mHasLandPageAddressDialog
|
||||
|
||||
/**
|
||||
* 更新列表状态
|
||||
*/
|
||||
@ -686,6 +733,7 @@ class UpdatableGameViewModel(
|
||||
var divider: String? = null,
|
||||
var header: String? = null,
|
||||
var ignoredUpdateHeader: String? = null,
|
||||
var landPageAddressDialogHeader: String? = null,
|
||||
var normalUpdate: GameUpdateEntity? = null,
|
||||
var normalUpdateWithArrow: GameUpdateEntity? = null,
|
||||
var ignoredUpdate: GameUpdateEntity? = null,
|
||||
|
||||
35
app/src/main/java/com/gh/gamecenter/entity/AdConfig.kt
Normal file
35
app/src/main/java/com/gh/gamecenter/entity/AdConfig.kt
Normal file
@ -0,0 +1,35 @@
|
||||
package com.gh.gamecenter.entity
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
class AdConfig(
|
||||
val name: String,
|
||||
val location: String, // 广告插入位置。光环启动:halo_launch 下载管理:download_manager 游戏搜索:game_search 助手启动:helper_launch
|
||||
val type: String, // 广告位类型。开屏广告:launch 信息流广告:native banner 广告:banner 插屏广告:interstitial
|
||||
val position: Int, // 定位,不存在的时候返回:-1
|
||||
@SerializedName("display_rules")
|
||||
val displayRule: DisplayRule,
|
||||
@SerializedName("third_party_ads")
|
||||
val thirdPartyAd: ThirdPartyAd? = null,
|
||||
@SerializedName("owner_ads")
|
||||
val ownerAd: StartupAdEntity? = null,
|
||||
) {
|
||||
|
||||
class DisplayRule(
|
||||
@SerializedName("ad_source")
|
||||
val adSource: String, // 广告位获取广告源。第三方广告:third_party_ads 自有广告:owner_ads
|
||||
@SerializedName("on_failed")
|
||||
val onFailedAction: String, // 第三方广告获取失败时。显示自有广告:show 隐藏广告位:hide
|
||||
)
|
||||
|
||||
class ThirdPartyAd(
|
||||
@SerializedName("source_name")
|
||||
val sourceName: String, // 广告源名。穿山甲、倍孜
|
||||
@SerializedName("ad_size")
|
||||
val displaySize: String,
|
||||
@SerializedName("code_name")
|
||||
val slotName: String,
|
||||
@SerializedName("code_id")
|
||||
val slotId: String
|
||||
)
|
||||
}
|
||||
@ -47,7 +47,8 @@ data class GameUpdateEntity(
|
||||
var signature: String? = "",
|
||||
var category: String? = "",
|
||||
var md5: String? = "",
|
||||
var downloadStatus: String? = ""
|
||||
var downloadStatus: String? = "",
|
||||
var landPageAddressDialog: GameEntity.AddressDialog? = null // 第三方跳转落地页跳转链接
|
||||
) {
|
||||
val categoryChinese: String
|
||||
get() = when (category) {
|
||||
@ -74,6 +75,13 @@ data class GameUpdateEntity(
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为第三方落地页跳转游戏
|
||||
*/
|
||||
fun isLandPageAddressDialog(): Boolean {
|
||||
return landPageAddressDialog?.let { it.status == "on" } ?: false
|
||||
}
|
||||
|
||||
fun transformGameEntity(): GameEntity {
|
||||
val gameEntity = GameEntity()
|
||||
gameEntity.id = id
|
||||
@ -90,6 +98,7 @@ data class GameUpdateEntity(
|
||||
gameEntity.pluginDesc = pluginDesc
|
||||
gameEntity.pluggableCollection = pluggableCollection
|
||||
gameEntity.category = category
|
||||
gameEntity.landPageAddressDialog = landPageAddressDialog
|
||||
|
||||
val apkEntity = ApkEntity()
|
||||
apkEntity.url = url
|
||||
|
||||
@ -6,9 +6,7 @@ import androidx.room.Ignore
|
||||
import androidx.room.PrimaryKey
|
||||
import androidx.room.TypeConverters
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.feature.entity.MeEntity
|
||||
import com.gh.gamecenter.feature.entity.SimpleGame
|
||||
import com.gh.gamecenter.feature.entity.Count
|
||||
import com.gh.gamecenter.feature.entity.*
|
||||
import com.gh.gamecenter.feature.entity.TimeEntity
|
||||
import com.gh.gamecenter.room.converter.*
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
@ -5,6 +5,7 @@ import androidx.room.Entity
|
||||
import androidx.room.Ignore
|
||||
import androidx.room.PrimaryKey
|
||||
import androidx.room.TypeConverters
|
||||
import com.gh.gamecenter.feature.entity.User
|
||||
import com.gh.gamecenter.room.converter.UserConverter
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@ -8,8 +8,6 @@ class NewApiSettingsEntity(
|
||||
@SerializedName("night_mode")
|
||||
var nightMode: NightMode? = null,
|
||||
var simulator: SimulatorEntity? = null,
|
||||
@SerializedName("start_ad")
|
||||
var startAd: StartupAdEntity? = null,//开屏图片广告
|
||||
var startup: StartupAdEntity? = null,//启动文案广告
|
||||
@SerializedName("user_interested_game")
|
||||
var userInterestedGame: Boolean = false, //偏好设置状态开关
|
||||
|
||||
@ -4,7 +4,8 @@ import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
class StartupAdEntity(
|
||||
@SerializedName("_id")
|
||||
// 接口返回了个狗屎 code_id 过来,只能用 alternate 来 map 一下了
|
||||
@SerializedName(value = "_id", alternate = ["code_id"])
|
||||
val id: String,
|
||||
val desc: String,
|
||||
val button: Boolean,
|
||||
|
||||
@ -16,6 +16,7 @@ class SubjectData(
|
||||
var tagType: String? = "", // 游戏Item 标签类型
|
||||
var briefStyle: String = "",
|
||||
var showSuffix: Boolean = true,
|
||||
var isQQMiniGame: Boolean = false,
|
||||
|
||||
var requireUpdateSetting: Boolean = false, // 多专题页面需要专题页面自行获取专题配置
|
||||
var isAdData: Boolean = false,
|
||||
|
||||
@ -96,7 +96,10 @@ data class SubjectEntity(
|
||||
var position: Int = -1,
|
||||
|
||||
// 本地字段,用来标记在外部页面中的序号,仅用于曝光记录,具体细节可见 https://git.ghzs.com/pm/halo-app-issues/-/issues/1087
|
||||
var outerSequence: Int = -1
|
||||
var outerSequence: Int = -1,
|
||||
|
||||
@SerializedName("is_qq_column")
|
||||
var isQQColumn: Boolean = false
|
||||
) : Parcelable {
|
||||
|
||||
@IgnoredOnParcel
|
||||
|
||||
@ -2,6 +2,7 @@ package com.gh.gamecenter.entity
|
||||
|
||||
import com.gh.gamecenter.common.entity.ToolBoxEntity
|
||||
import com.gh.gamecenter.feature.entity.AnswerEntity
|
||||
import com.gh.gamecenter.feature.entity.LibaoEntity
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
class UnifiedUserTrendEntity(
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
package com.gh.gamecenter.eventbus;
|
||||
|
||||
public class EBAddComment {}
|
||||
@ -46,7 +46,7 @@ class WelfaresAdapter(
|
||||
"游戏动态" -> {
|
||||
NewLogUtils.logForumPageEvent("click_forum_game_general")
|
||||
CheckLoginUtils.checkLogin(mContext, "社区-论坛:游戏动态") {
|
||||
DirectUtils.directToConcernInfo(mContext)
|
||||
DirectUtils.directToConcernInfo(mContext, "社区-论坛:游戏动态")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,171 @@
|
||||
package com.gh.gamecenter.fragment
|
||||
|
||||
import android.graphics.Typeface
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.gh.common.util.DataCollectionUtils
|
||||
import com.gh.common.util.DirectUtils
|
||||
import com.gh.common.util.LogUtils
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.DownloadManagerActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.SearchActivity
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.common.utils.goneIf
|
||||
import com.gh.gamecenter.common.utils.viewModelProvider
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.core.utils.SentryHelper
|
||||
import com.gh.gamecenter.databinding.FragmentHomeGameWrapperBinding
|
||||
import com.gh.gamecenter.entity.GameUpdateEntity
|
||||
import com.gh.gamecenter.entity.SubjectRecommendEntity
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.packagehelper.PackageViewModel
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class HomeGameWrapperFragment : HomeTabWrapperFragment() {
|
||||
|
||||
private var mViewModel: HomeGameWrapperViewModel? = null
|
||||
private var mPackageViewModel: PackageViewModel? = null
|
||||
private var mBinding: FragmentHomeGameWrapperBinding? = null
|
||||
|
||||
override fun getRealLayoutId(): Int = R.layout.fragment_home_game_wrapper
|
||||
|
||||
override fun getInflatedLayout(): View =
|
||||
FragmentHomeGameWrapperBinding.inflate(layoutInflater).apply { mBinding = this }.root
|
||||
|
||||
override fun onPageSelected(position: Int) {
|
||||
super.onPageSelected(position)
|
||||
mViewModel?.forumTabPairs?.forEach { pair ->
|
||||
if (pair.first == position) {
|
||||
DirectUtils.directForumDetail(requireContext(), pair.second, "游戏库")
|
||||
mViewPager?.post { mViewPager?.currentItem = position - 1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPageScrolled(
|
||||
position: Int,
|
||||
positionOffset: Float,
|
||||
tabEntityList: ArrayList<SubjectRecommendEntity>
|
||||
) {
|
||||
mCurrentTabSelectedColor = mTabSelectedColor
|
||||
mCurrentTabDefaultColor = mTabDefaultColor
|
||||
|
||||
// 这里的 selectedPosition 指的是应该被高亮显示的 position
|
||||
val selectedPosition = try {
|
||||
(position + positionOffset).roundToInt()
|
||||
} catch (e: IllegalArgumentException) {
|
||||
// roundToInt() 方法有时候会报 Cannot round NaN value. 错误
|
||||
// https://sentry.shanqu.cc/organizations/lightgame/issues/301377/?project=22
|
||||
SentryHelper.onEvent(
|
||||
"HOME_NAN_POSITION",
|
||||
"value",
|
||||
"$position+$positionOffset=(${position + positionOffset})"
|
||||
)
|
||||
position
|
||||
}
|
||||
val positionOffsetOnRealSelectedPosition = if (positionOffset >= 0.5) {
|
||||
positionOffset - 1
|
||||
} else {
|
||||
positionOffset
|
||||
}
|
||||
|
||||
updateTabStyle(selectedPosition, positionOffsetOnRealSelectedPosition)
|
||||
}
|
||||
|
||||
override fun initRealView() {
|
||||
super.initRealView()
|
||||
mBinding?.run {
|
||||
searchIv.setOnClickListener {
|
||||
startActivity(SearchActivity.getIntent(requireContext(), false, "", "游戏库", "游戏库"))
|
||||
}
|
||||
downloadContainer.setOnClickListener {
|
||||
DataCollectionUtils.uploadClick(activity, "下载图标", "主页")
|
||||
startActivity(DownloadManagerActivity.getDownloadMangerIntent(requireContext(), "游戏库"))
|
||||
}
|
||||
mBinding?.menuDownloadCountHint?.typeface =
|
||||
Typeface.createFromAsset(requireContext().assets, "fonts/d_din_bold_only_number.ttf")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFragmentFirstVisible() {
|
||||
super.onFragmentFirstVisible()
|
||||
val factory = HomeGameWrapperViewModel.Factory(arguments?.getParcelable(EntranceConsts.KEY_BLOCK_DATA))
|
||||
mViewModel = viewModelProvider(factory)
|
||||
mPackageViewModel = viewModelProvider(PackageViewModel.Factory())
|
||||
|
||||
mViewModel?.tabs?.observe(viewLifecycleOwner) {
|
||||
if (mDefaultSelectedTab == -1) {
|
||||
mDefaultSelectedTab = mViewModel?.defaultTabPosition ?: 0
|
||||
}
|
||||
mHomeTabPosition = mViewModel?.getHomeTabPosition() ?: 0
|
||||
initViewPager(it, "游戏库")
|
||||
|
||||
mBinding?.toolbarContainer?.visibility = View.VISIBLE
|
||||
mBinding?.noConnectionContainer?.reuseNoConnection?.visibility = View.GONE
|
||||
mBinding?.loadingContainer?.reuseLlLoading?.visibility = View.GONE
|
||||
}
|
||||
|
||||
mViewModel?.error?.observe(viewLifecycleOwner) {
|
||||
mBinding?.toolbarContainer?.visibility = View.GONE
|
||||
mBinding?.noConnectionContainer?.reuseNoConnection?.visibility = View.VISIBLE
|
||||
mBinding?.loadingContainer?.reuseLlLoading?.visibility = View.GONE
|
||||
mBinding?.noConnectionContainer?.reuseNoConnection?.setOnClickListener {
|
||||
mViewModel?.getHomeGameTab()
|
||||
mBinding?.noConnectionContainer?.reuseNoConnection?.visibility = View.GONE
|
||||
mBinding?.loadingContainer?.reuseLlLoading?.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
mPackageViewModel?.filterSameUpdateLiveData?.observe(this) {
|
||||
setDownloadHint(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setDownloadHint(updateList: List<GameUpdateEntity>) {
|
||||
val count = DownloadManager.getInstance().getDownloadOrUpdateCount(updateList)
|
||||
val params = mBinding?.menuDownloadCountHint?.layoutParams
|
||||
params?.width = if (count.isNullOrEmpty()) 6F.dip2px() else ConstraintLayout.LayoutParams.WRAP_CONTENT
|
||||
params?.height = if (count.isNullOrEmpty()) 6F.dip2px() else 14F.dip2px()
|
||||
(params as ViewGroup.MarginLayoutParams).setMargins(
|
||||
0,
|
||||
if (count.isNullOrEmpty()) 0 else (-4F).dip2px(),
|
||||
if (count.isNullOrEmpty()) (-4F).dip2px() else (-8F).dip2px(),
|
||||
0
|
||||
)
|
||||
mBinding?.menuDownloadCountHint?.setPadding(
|
||||
if (count.isNullOrEmpty()) 0 else 4F.dip2px(),
|
||||
0,
|
||||
if (count.isNullOrEmpty()) 0 else 4F.dip2px(),
|
||||
0
|
||||
)
|
||||
mBinding?.menuDownloadCountHint?.minWidth = if (count.isNullOrEmpty()) 0 else 14F.dip2px()
|
||||
mBinding?.menuDownloadCountHint?.layoutParams = params
|
||||
mBinding?.menuDownloadCountHint?.goneIf(count == null)
|
||||
mBinding?.menuDownloadCountHint?.text = count.toString()
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(status: EBDownloadStatus?) {
|
||||
mPackageViewModel?.filterSameUpdateLiveData?.value?.let { setDownloadHint(it) }
|
||||
}
|
||||
|
||||
override fun getLastTabRightMargin(): Int = 26F.dip2px()
|
||||
|
||||
override fun logTabSelected(tabEntity: SubjectRecommendEntity, position: Int) {
|
||||
LogUtils.logHomeTopTabClick(tabEntity.name, tabEntity.type, tabEntity.text, tabEntity.link, position, "游戏库")
|
||||
}
|
||||
|
||||
override fun onDarkModeChanged() {
|
||||
super.onDarkModeChanged()
|
||||
if (isSupportVisible) DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn)
|
||||
|
||||
mCurrentTabSelectedColor = mTabSelectedColor
|
||||
mCurrentTabDefaultColor = mTabDefaultColor
|
||||
updateTabStyle(mLastSelectedPosition, 0F)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,87 @@
|
||||
package com.gh.gamecenter.fragment
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.gh.gamecenter.common.retrofit.BiResponse
|
||||
import com.gh.gamecenter.common.utils.singleToMain
|
||||
import com.gh.gamecenter.entity.SubjectRecommendEntity
|
||||
import com.gh.gamecenter.pkg.PkgHelper
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
|
||||
class HomeGameWrapperViewModel(application: Application, val blockData: SubjectRecommendEntity?) :
|
||||
AndroidViewModel(application) {
|
||||
|
||||
private val mApi = RetrofitManager.getInstance().newApi
|
||||
val tabs = MutableLiveData<ArrayList<SubjectRecommendEntity>>()
|
||||
val error = MutableLiveData<Exception>()
|
||||
|
||||
var defaultTabPosition = 0
|
||||
var forumTabPairs: ArrayList<Pair<Int, String>> = arrayListOf()
|
||||
|
||||
private var mHomeTab: SubjectRecommendEntity? = null
|
||||
private var mHomeTabPosition: Int = -1
|
||||
|
||||
init {
|
||||
getHomeGameTab()
|
||||
}
|
||||
|
||||
fun getHomeTabEntity() = mHomeTab
|
||||
|
||||
fun getHomeTabPosition() = mHomeTabPosition
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
fun getHomeGameTab() {
|
||||
mApi.getBlockTab(blockData?.link)
|
||||
.compose(singleToMain())
|
||||
.subscribe(object : BiResponse<List<SubjectRecommendEntity>>() {
|
||||
override fun onSuccess(data: List<SubjectRecommendEntity>) {
|
||||
data.forEachIndexed { index, tab ->
|
||||
if (tab.type == "block") {
|
||||
mHomeTab = tab
|
||||
mHomeTabPosition = index
|
||||
}
|
||||
if (tab.default) {
|
||||
defaultTabPosition = index
|
||||
}
|
||||
if (tab.type == "bbs") {
|
||||
forumTabPairs.add(Pair(index, tab.link ?: ""))
|
||||
}
|
||||
}
|
||||
|
||||
// 根据特殊打包配置,调整默认选中的 tab
|
||||
PkgHelper.getPkgConfig(isFromGameTopTab = true)?.let { pkgLinkEntity ->
|
||||
if (pkgLinkEntity.shouldStayAtMainActivity) {
|
||||
for ((index, tab) in data.withIndex()) {
|
||||
if (pkgLinkEntity.type == tab.type
|
||||
&& (pkgLinkEntity.link == tab.link || tab.link == null)) {
|
||||
defaultTabPosition = index
|
||||
break
|
||||
}
|
||||
}
|
||||
// 无论是否找到默认选中的 tab,都把这个配置标记为已读,避免下次启动这个配置仍生效
|
||||
PkgHelper.markConfigUsed()
|
||||
}
|
||||
}
|
||||
|
||||
tabs.postValue(ArrayList(data))
|
||||
}
|
||||
|
||||
override fun onFailure(exception: Exception) {
|
||||
super.onFailure(exception)
|
||||
error.postValue(exception)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
class Factory(val blockData: SubjectRecommendEntity?) :
|
||||
ViewModelProvider.NewInstanceFactory() {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return HomeGameWrapperViewModel(HaloApp.getInstance().application, blockData) as T
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,16 +1,10 @@
|
||||
package com.gh.gamecenter.fragment
|
||||
|
||||
import android.graphics.Color
|
||||
import android.graphics.Typeface
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import com.gh.common.exposure.ExposureManager
|
||||
import com.gh.common.util.DirectUtils
|
||||
import com.gh.common.util.DownloadItemUtils
|
||||
@ -21,42 +15,27 @@ import com.gh.gamecenter.GameDetailActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
|
||||
import com.gh.gamecenter.amway.AmwayFragment
|
||||
import com.gh.gamecenter.catalog.CatalogFragment
|
||||
import com.gh.gamecenter.category.CategoryDirectoryFragment
|
||||
import com.gh.gamecenter.category2.CategoryV2Fragment
|
||||
import com.gh.gamecenter.common.base.adapter.FragmentAdapter
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.eventbus.EBReuse
|
||||
import com.gh.gamecenter.common.json.json
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.common.view.TabIndicatorView
|
||||
import com.gh.gamecenter.common.view.WrapContentDraweeView
|
||||
import com.gh.gamecenter.core.utils.*
|
||||
import com.gh.gamecenter.databinding.FragmentMainHomeWrapperBinding
|
||||
import com.gh.gamecenter.databinding.TabItemMainBinding
|
||||
import com.gh.gamecenter.discovery.DiscoveryFragment
|
||||
import com.gh.gamecenter.entity.HomePush
|
||||
import com.gh.gamecenter.entity.SubjectData
|
||||
import com.gh.gamecenter.entity.SubjectRecommendEntity
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.ExposureSource
|
||||
import com.gh.gamecenter.feature.exposure.time.TimeUtil
|
||||
import com.gh.gamecenter.feature.game.GameItemViewHolder
|
||||
import com.gh.gamecenter.game.GameFragment
|
||||
import com.gh.gamecenter.game.columncollection.detail.ColumnCollectionDetailFragment
|
||||
import com.gh.gamecenter.game.commoncollection.detail.CommonCollectionDetailFragment
|
||||
import com.gh.gamecenter.gamecollection.square.GameCollectionSquareFragment
|
||||
import com.gh.gamecenter.home.HomeFragment
|
||||
import com.gh.gamecenter.home.video.ScrollCalculatorHelper
|
||||
import com.gh.gamecenter.servers.GameServersPublishFragment
|
||||
import com.gh.gamecenter.servers.GameServersTestFragment
|
||||
import com.gh.gamecenter.servers.gametest2.GameServerTestV2Fragment
|
||||
import com.gh.gamecenter.subject.SubjectFragment
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.halo.assistant.fragment.WebFragment
|
||||
import com.lightgame.download.DataWatcher
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.scwang.smartrefresh.layout.api.RefreshHeader
|
||||
@ -70,27 +49,16 @@ import org.greenrobot.eventbus.ThreadMode
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
class HomeSearchToolWrapperFragment : HomeTabWrapperFragment() {
|
||||
|
||||
private var mBinding: FragmentMainHomeWrapperBinding? = null
|
||||
private var mTabBindingList = arrayListOf<TabItemMainBinding>()
|
||||
private var mTabImageStyleList = arrayListOf<Int>()
|
||||
|
||||
private var mTabSelectedColor: Int = 0
|
||||
private var mTabDefaultColor: Int = 0
|
||||
|
||||
private var mCurrentAppBarColor: Int = 0
|
||||
|
||||
private var mIsDisplayingLightContent = false
|
||||
|
||||
private var mDefaultSelectedTab = -1
|
||||
private var mLastSelectedPosition = 0
|
||||
|
||||
private var mViewModel: HomeSearchToolWrapperViewModel? = null
|
||||
|
||||
private var mFragmentList = ArrayList<Fragment>()
|
||||
|
||||
private var mHomeTabPosition = -1
|
||||
private var mOffsetCritical = 0.7F
|
||||
|
||||
private var mShowTwoLevel = false
|
||||
@ -119,13 +87,8 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
savedInstanceState?.let { mDefaultSelectedTab = it.getInt(LAST_SELECTED_POSITION) }
|
||||
}
|
||||
|
||||
override fun onFragmentFirstVisible() {
|
||||
super.onFragmentFirstVisible()
|
||||
mViewModel = viewModelProviderFromParent()
|
||||
mElapsedHelper = TimeElapsedHelper()
|
||||
mSearchToolbarFragment =
|
||||
@ -151,7 +114,7 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
mDefaultSelectedTab = mViewModel?.defaultTabPosition ?: 0
|
||||
}
|
||||
mHomeTabPosition = mViewModel?.getHomeTabPosition() ?: 0
|
||||
initViewPager(it)
|
||||
initViewPager(it, "首页")
|
||||
|
||||
// 当 tab 只有一个的时候隐藏顶部 tab 栏,停用 nestedScroll
|
||||
if (it.size == 1) {
|
||||
@ -349,18 +312,12 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
})
|
||||
|
||||
twoLevelHeader.setOnTwoLevelListener {
|
||||
mHomePush?.run {
|
||||
if (game != null) {
|
||||
game.sequence = mTwoLevelOpenCount
|
||||
mExposureEvent = ExposureEvent.createEventWithSourceConcat(
|
||||
game,
|
||||
basicSource = listOf(ExposureSource("新首页", "")),
|
||||
source = listOf(ExposureSource("下拉推送", id))
|
||||
)
|
||||
ExposureManager.log(mExposureEvent!!)
|
||||
}
|
||||
mExposureEvent?.timeInMillisecond = System.currentTimeMillis()
|
||||
mExposureEvent?.time = TimeUtil.currentTime()
|
||||
mExposureEvent?.payload?.sequence = mTwoLevelOpenCount
|
||||
mExposureEvent?.let {
|
||||
ExposureManager.log(it)
|
||||
}
|
||||
|
||||
mElapsedHelper.resetCounting()
|
||||
mElapsedHelper.resumeCounting()
|
||||
playHomePushVideo()
|
||||
@ -427,9 +384,9 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
) else R.drawable.ic_commodity_selected.toDrawable(
|
||||
requireContext()
|
||||
)
|
||||
if (mTabSelectedColor != tabSelectedColor || mTabDefaultColor != tabDefaultColor) {
|
||||
mTabSelectedColor = tabSelectedColor
|
||||
mTabDefaultColor = tabDefaultColor
|
||||
if (mCurrentTabSelectedColor != tabSelectedColor || mCurrentTabDefaultColor != tabDefaultColor) {
|
||||
mCurrentTabSelectedColor = tabSelectedColor
|
||||
mCurrentTabDefaultColor = tabDefaultColor
|
||||
updateTabStyle(mLastSelectedPosition, 0F)
|
||||
indicatorView.updateIndicatorDrawable(indicatorDrawable)
|
||||
}
|
||||
@ -482,6 +439,15 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
|
||||
private fun setHomePush() {
|
||||
mHomePush?.run {
|
||||
if (game != null) {
|
||||
game.sequence = 1
|
||||
mExposureEvent = ExposureEvent.createEventWithSourceConcat(
|
||||
game,
|
||||
basicSource = listOf(ExposureSource("新首页", "")),
|
||||
source = listOf(ExposureSource("下拉推送", id))
|
||||
)
|
||||
}
|
||||
|
||||
mBinding?.run {
|
||||
if (game != null) {
|
||||
gameNameTv.text = game.name
|
||||
@ -528,7 +494,8 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
|
||||
fun popUpHomePushIfNeeded() {
|
||||
mBinding?.run {
|
||||
if (mFragmentList.safelyGetInRelease(viewPager.currentItem) !is HomeFragment) return
|
||||
if (mFragmentList.isEmpty()
|
||||
|| mFragmentList.safelyGetInRelease(viewPager.currentItem) !is HomeFragment) return
|
||||
mHomePush?.run {
|
||||
val homePushSet = HashSet(SPUtils.getStringSet(Constants.SP_HOME_PUSH_POP_UP_SET))
|
||||
if (popSwitch == "on" && !homePushSet.contains(id)) {
|
||||
@ -642,48 +609,18 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
updateHomePushDownloadBtn()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
mBinding?.viewPager?.let { outState.putInt(LAST_SELECTED_POSITION, it.currentItem) }
|
||||
super.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun getInflatedLayout() =
|
||||
FragmentMainHomeWrapperBinding.inflate(layoutInflater).apply { mBinding = this }.root
|
||||
|
||||
private fun initViewPager(tabEntityList: ArrayList<SubjectRecommendEntity>) {
|
||||
val fragmentList = generateFragments(tabEntityList).apply { mFragmentList = this }
|
||||
val tabTitleList = arrayListOf<String>()
|
||||
|
||||
tabEntityList.forEach { tabTitleList.add(it.name ?: "") }
|
||||
|
||||
mBinding?.run {
|
||||
viewPager.offscreenPageLimit = fragmentList.size
|
||||
viewPager.doOnScroll(
|
||||
onPageSelected = { position ->
|
||||
refreshLayout.setEnableRefresh(getFragment(position) is HomeFragment && mHomePush != null)
|
||||
if (mShowTwoLevel) finishTwoLevel("跳转收起")
|
||||
notifyChildFragmentLifecycle(position)
|
||||
mViewModel?.forumTabPairs?.forEach { pair ->
|
||||
if (pair.first == position) {
|
||||
DirectUtils.directForumDetail(requireContext(), pair.second, "首页")
|
||||
viewPager.post { viewPager.currentItem = position - 1 }
|
||||
}
|
||||
}
|
||||
tabEntityList.safelyGetInRelease(position)?.let { logTabSelected(it, position) }
|
||||
},
|
||||
onPageScrolled = { position, positionOffset, _ ->
|
||||
onPageScrolled(position, positionOffset, tabEntityList)
|
||||
}
|
||||
)
|
||||
|
||||
setRestoredCurItem(viewPager)
|
||||
viewPager.adapter = FragmentAdapter(childFragmentManager, fragmentList, tabTitleList)
|
||||
tabLayout.setupWithViewPager(mBinding?.viewPager)
|
||||
indicatorView.setupWithTabLayout(mBinding?.tabLayout)
|
||||
indicatorView.setupWithViewPager(mBinding?.viewPager)
|
||||
indicatorView.setIndicatorWidth(18)
|
||||
|
||||
initTabView(tabEntityList)
|
||||
override fun onPageSelected(position: Int) {
|
||||
super.onPageSelected(position)
|
||||
mBinding?.refreshLayout?.setEnableRefresh(getFragment(position) is HomeFragment && mHomePush != null)
|
||||
if (mShowTwoLevel) finishTwoLevel("跳转收起")
|
||||
mViewModel?.forumTabPairs?.forEach { pair ->
|
||||
if (pair.first == position) {
|
||||
DirectUtils.directForumDetail(requireContext(), pair.second, "首页")
|
||||
mViewPager?.post { mViewPager?.currentItem = position - 1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -695,34 +632,29 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun onPageScrolled(position: Int, positionOffset: Float, tabEntityList: ArrayList<SubjectRecommendEntity>) {
|
||||
override fun onPageScrolled(
|
||||
position: Int,
|
||||
positionOffset: Float,
|
||||
tabEntityList: ArrayList<SubjectRecommendEntity>
|
||||
) {
|
||||
val nextPosition = position + 1
|
||||
|
||||
// TODO 避免高频调用 toColor 方法
|
||||
val backgroundColor = R.color.background.toColor(requireContext())
|
||||
val backgroundWhiteColor = R.color.background_white.toColor(requireContext())
|
||||
val amwayPrimaryColor = R.color.amway_primary_color.toColor(requireContext())
|
||||
val tabDefaultColor = TAB_DEFAULT_COLOR.toColor(requireContext())
|
||||
val tabSelectedColor = TAB_SELECTED_COLOR.toColor(requireContext())
|
||||
val tabDefaultLightColor = TAB_DEFAULT_COLOR_LIGHT.toColor(requireContext())
|
||||
|
||||
val tabEntity = tabEntityList.safelyGetInRelease(position)
|
||||
|
||||
// 处理当前 tab 和下一个 tab
|
||||
if (nextPosition != mTabBindingList.size) {
|
||||
val nextTabEntity = tabEntityList.safelyGetInRelease(nextPosition)
|
||||
var currentAppBarColor = tabEntity?.primaryColor ?: backgroundWhiteColor
|
||||
var nextAppBarColor = nextTabEntity?.primaryColor ?: backgroundWhiteColor
|
||||
var currentAppBarColor = tabEntity?.primaryColor ?: mBackgroundWhiteColor
|
||||
var nextAppBarColor = nextTabEntity?.primaryColor ?: mBackgroundWhiteColor
|
||||
|
||||
if (currentAppBarColor == Color.WHITE) currentAppBarColor = backgroundWhiteColor
|
||||
if (nextAppBarColor == Color.WHITE) nextAppBarColor = backgroundWhiteColor
|
||||
if (currentAppBarColor == Color.WHITE) currentAppBarColor = mBackgroundWhiteColor
|
||||
if (nextAppBarColor == Color.WHITE) nextAppBarColor = mBackgroundWhiteColor
|
||||
|
||||
if (getFragment(position) is AmwayFragment) {
|
||||
currentAppBarColor = if (mIsDarkModeOn) backgroundColor else amwayPrimaryColor
|
||||
currentAppBarColor = if (mIsDarkModeOn) mBackgroundColor else mAmwayPrimaryColor
|
||||
tabEntity?.currentSelectColor = currentAppBarColor
|
||||
}
|
||||
if (getFragment(nextPosition) is AmwayFragment) {
|
||||
nextAppBarColor = if (mIsDarkModeOn) backgroundColor else amwayPrimaryColor
|
||||
nextAppBarColor = if (mIsDarkModeOn) mBackgroundColor else mAmwayPrimaryColor
|
||||
}
|
||||
|
||||
val proximatelySelectedTabEntity = if (positionOffset < 0.5) tabEntity else nextTabEntity
|
||||
@ -739,9 +671,9 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
mIsDisplayingLightContent = proximatelySelectedTabEntity?.useLightStyle ?: false
|
||||
|
||||
if (!mShowTwoLevel) {
|
||||
mTabSelectedColor =
|
||||
if (mIsDisplayingLightContent) tabDefaultLightColor else tabSelectedColor
|
||||
mTabDefaultColor = if (mIsDisplayingLightContent) tabDefaultLightColor else tabDefaultColor
|
||||
mCurrentTabSelectedColor =
|
||||
if (mIsDisplayingLightContent) mTabDefaultLightColor else mTabSelectedColor
|
||||
mCurrentTabDefaultColor = if (mIsDisplayingLightContent) mTabDefaultLightColor else mTabDefaultColor
|
||||
}
|
||||
|
||||
if (isContentStyleChanged) {
|
||||
@ -752,19 +684,19 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
mCurrentAppBarColor = appBarColorInBetween
|
||||
updateAppBarStyle(appBarColorInBetween, mIsDisplayingLightContent)
|
||||
} else {
|
||||
var currentAppBarColor = tabEntity?.primaryColor ?: backgroundWhiteColor
|
||||
var currentAppBarColor = tabEntity?.primaryColor ?: mBackgroundWhiteColor
|
||||
if (mIsDarkModeOn && currentAppBarColor == Color.WHITE) {
|
||||
currentAppBarColor = backgroundWhiteColor
|
||||
currentAppBarColor = mBackgroundWhiteColor
|
||||
}
|
||||
if (getFragment(position) is AmwayFragment) {
|
||||
currentAppBarColor = if (mIsDarkModeOn) backgroundColor else amwayPrimaryColor
|
||||
currentAppBarColor = if (mIsDarkModeOn) mBackgroundColor else mAmwayPrimaryColor
|
||||
tabEntity?.currentSelectColor = currentAppBarColor
|
||||
}
|
||||
mIsDisplayingLightContent = tabEntity?.useLightStyle == true
|
||||
if (!mShowTwoLevel) {
|
||||
mTabSelectedColor =
|
||||
if (mIsDisplayingLightContent) tabDefaultLightColor else tabSelectedColor
|
||||
mTabDefaultColor = if (mIsDisplayingLightContent) tabDefaultLightColor else tabDefaultColor
|
||||
mCurrentTabSelectedColor =
|
||||
if (mIsDisplayingLightContent) mTabDefaultLightColor else mTabSelectedColor
|
||||
mCurrentTabDefaultColor = if (mIsDisplayingLightContent) mTabDefaultLightColor else mTabDefaultColor
|
||||
}
|
||||
|
||||
updateAppBarStyle(currentAppBarColor, mIsDisplayingLightContent)
|
||||
@ -789,170 +721,21 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
updateTabStyle(selectedPosition, positionOffsetOnRealSelectedPosition)
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新 tab 的样式
|
||||
* @param selectedPosition 选中的 tab
|
||||
* @param positionOffset 与选中 tab 的位置偏移,为负时在选中的 tab 左边,为正时在选中 tab 的右边
|
||||
*/
|
||||
private fun updateTabStyle(selectedPosition: Int, positionOffset: Float) {
|
||||
if (mTabBindingList.isEmpty()) return
|
||||
|
||||
val prePosition = selectedPosition - 1
|
||||
val nextPosition = selectedPosition + 1
|
||||
|
||||
// positionOffset 小于零,表示 indicator 当前位置处于选中的 tab 的左边
|
||||
val indicatorOnLeft = positionOffset < 0F
|
||||
|
||||
val selectedTabBinding = mTabBindingList.safelyGetInRelease(selectedPosition) ?: return
|
||||
val selectedTabImageStyle = mTabImageStyleList.safelyGetInRelease(selectedPosition) ?: return
|
||||
|
||||
// 前一个 tab、当前选中的 tab、后一个 tab 的显示比例
|
||||
val preScaleRatio = 1 + abs(positionOffset) / 4
|
||||
val selectedScaleRatio = 1 + (1 - abs(positionOffset)) / 4
|
||||
val nextScaleRatio = 1 + positionOffset / 4
|
||||
|
||||
// 处理前一个 tab
|
||||
if (prePosition != -1) {
|
||||
mTabBindingList[prePosition].run {
|
||||
if (indicatorOnLeft) {
|
||||
when (mTabImageStyleList[prePosition]) {
|
||||
TAB_IMAGE_ALWAYS_ON -> {
|
||||
titleIv.scaleX = preScaleRatio
|
||||
titleIv.scaleY = preScaleRatio
|
||||
}
|
||||
|
||||
TAB_IMAGE_HIDE_ON_SELECTED -> {
|
||||
titleIv.scaleX = preScaleRatio
|
||||
titleIv.scaleY = preScaleRatio
|
||||
titleIv.visibility = View.VISIBLE
|
||||
titleTv.visibility = View.GONE
|
||||
invisibleTitleTv.visibility = View.GONE
|
||||
}
|
||||
|
||||
else -> {
|
||||
titleIv.visibility = View.GONE
|
||||
titleTv.visibility = View.VISIBLE
|
||||
invisibleTitleTv.visibility = View.INVISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
titleTv.textSize = (DEFAULT_TAB_TEXT_SIZE * preScaleRatio).roundTo(1)
|
||||
titleTv.setTextColor(ColorUtils.blendARGB(mTabDefaultColor, mTabSelectedColor, abs(positionOffset)))
|
||||
} else {
|
||||
titleTv.setTextColor(mTabDefaultColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 更新当前选中的 tab
|
||||
selectedTabBinding.run {
|
||||
// 更新当前选中的 tab 的图片显示状态
|
||||
when (selectedTabImageStyle) {
|
||||
TAB_IMAGE_ALWAYS_ON -> {
|
||||
val scaleRatio = (1 + (1 - abs(positionOffset)) * 0.25).toFloat()
|
||||
titleIv.scaleX = scaleRatio
|
||||
titleIv.scaleY = scaleRatio
|
||||
}
|
||||
|
||||
else -> {
|
||||
titleIv.visibility = View.GONE
|
||||
titleTv.visibility = View.VISIBLE
|
||||
invisibleTitleTv.visibility = View.INVISIBLE
|
||||
|
||||
mBinding?.indicatorView?.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
// 选中常驻型的图片时隐藏 indicatorView
|
||||
mBinding?.indicatorView?.goneIf(selectedTabImageStyle == TAB_IMAGE_ALWAYS_ON)
|
||||
|
||||
titleTv.textSize = (DEFAULT_TAB_TEXT_SIZE * selectedScaleRatio).roundTo(1)
|
||||
titleTv.setTextColor(ColorUtils.blendARGB(mTabDefaultColor, mTabSelectedColor, 1 - abs(positionOffset)))
|
||||
}
|
||||
|
||||
// 处理后一个 tab
|
||||
if (nextPosition < mTabBindingList.size) {
|
||||
mTabBindingList[nextPosition].run {
|
||||
if (!indicatorOnLeft) {
|
||||
when (mTabImageStyleList[nextPosition]) {
|
||||
TAB_IMAGE_ALWAYS_ON -> {
|
||||
titleIv.scaleX = nextScaleRatio
|
||||
titleIv.scaleY = nextScaleRatio
|
||||
}
|
||||
|
||||
TAB_IMAGE_HIDE_ON_SELECTED -> {
|
||||
titleIv.scaleX = nextScaleRatio
|
||||
titleIv.scaleY = nextScaleRatio
|
||||
titleIv.visibility = View.VISIBLE
|
||||
titleTv.visibility = View.GONE
|
||||
invisibleTitleTv.visibility = View.GONE
|
||||
}
|
||||
|
||||
else -> {
|
||||
titleIv.visibility = View.GONE
|
||||
titleTv.visibility = View.VISIBLE
|
||||
invisibleTitleTv.visibility = View.INVISIBLE
|
||||
}
|
||||
}
|
||||
titleTv.textSize = (DEFAULT_TAB_TEXT_SIZE * nextScaleRatio).roundTo(1)
|
||||
titleTv.setTextColor(ColorUtils.blendARGB(mTabDefaultColor, mTabSelectedColor, positionOffset))
|
||||
} else {
|
||||
titleTv.setTextColor(mTabDefaultColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 多 tab 切换的时候可能会出现某些 tab 的文字没有回归到原始大小的问题的问题 (positionOffset 不保证连续)
|
||||
for ((index, binding) in mTabBindingList.withIndex()) {
|
||||
if (index != prePosition && index != selectedPosition && index != nextPosition) {
|
||||
if (binding.titleTv.textSize != DEFAULT_TAB_TEXT_SIZE) {
|
||||
binding.titleTv.textSize = DEFAULT_TAB_TEXT_SIZE
|
||||
binding.titleTv.setTextColor(mTabDefaultColor)
|
||||
}
|
||||
if (binding.titleIv.scaleX != 1F) {
|
||||
binding.titleIv.scaleX = 1F
|
||||
binding.titleIv.scaleY = 1F
|
||||
}
|
||||
}
|
||||
|
||||
if (index == selectedPosition) {
|
||||
if (positionOffset == 0F) {
|
||||
binding.titleTv.setTextColor(mTabSelectedColor)
|
||||
}
|
||||
|
||||
binding.titleTv.setTypeface(binding.titleTv.typeface, Typeface.BOLD)
|
||||
} else {
|
||||
if (positionOffset == 0F) {
|
||||
binding.titleTv.setTextColor(mTabDefaultColor)
|
||||
}
|
||||
|
||||
binding.titleTv.setTypeface(null, Typeface.NORMAL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onScrollChanged(totalHeight: Int, offset: Int) {
|
||||
val currentTab = getCurrentTabEntity()
|
||||
val backgroundWhiteColor = R.color.background_white.toColor(requireContext())
|
||||
val backgroundColor = R.color.background.toColor(requireContext())
|
||||
val amwayPrimaryColor = R.color.amway_primary_color.toColor(requireContext())
|
||||
val tabDefaultLightColor = TAB_DEFAULT_COLOR_LIGHT.toColor(requireContext())
|
||||
val tabSelectedColor = TAB_SELECTED_COLOR.toColor(requireContext())
|
||||
val tabDefaultColor = TAB_DEFAULT_COLOR.toColor(requireContext())
|
||||
|
||||
currentTab?.offsetRatio = offset / totalHeight.toFloat()
|
||||
if ((currentTab?.isTopViewShow == true && offset >= totalHeight)
|
||||
|| currentTab?.isSlideEmpty == true
|
||||
) {
|
||||
currentTab.isTopViewShow = false
|
||||
currentTab.primaryColor = backgroundWhiteColor
|
||||
currentTab.primaryColor = mBackgroundWhiteColor
|
||||
currentTab.useLightStyle = false
|
||||
mIsDisplayingLightContent = false
|
||||
updateAppBarColorWhenScrollChanged(backgroundWhiteColor)
|
||||
updateAppBarColorWhenScrollChanged(mBackgroundWhiteColor)
|
||||
refreshStatusBarStyle()
|
||||
if (!mShowTwoLevel) {
|
||||
mTabSelectedColor = TAB_SELECTED_COLOR.toColor(requireContext())
|
||||
mTabDefaultColor = TAB_DEFAULT_COLOR.toColor(requireContext())
|
||||
mCurrentTabSelectedColor = TAB_SELECTED_COLOR.toColor(requireContext())
|
||||
mCurrentTabDefaultColor = TAB_DEFAULT_COLOR.toColor(requireContext())
|
||||
mBinding?.indicatorView?.updateIndicatorDrawable(R.drawable.ic_commodity_selected.toDrawable())
|
||||
updateTabStyle(mLastSelectedPosition, 0F)
|
||||
}
|
||||
@ -961,10 +744,10 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
val offsetMeetsCriticalPoint = (currentTab?.offsetRatio ?: 0F) < mOffsetCritical
|
||||
currentTab?.isTopViewShow = true
|
||||
if (getFragment(mBinding?.viewPager?.currentItem ?: 0) is AmwayFragment) {
|
||||
currentSelectColor = if (mIsDarkModeOn) backgroundColor else amwayPrimaryColor
|
||||
currentSelectColor = if (mIsDarkModeOn) mBackgroundColor else mAmwayPrimaryColor
|
||||
}
|
||||
val colorInBetween =
|
||||
ColorUtils.blendARGB(currentSelectColor, backgroundWhiteColor, currentTab?.offsetRatio ?: 0F)
|
||||
ColorUtils.blendARGB(currentSelectColor, mBackgroundWhiteColor, currentTab?.offsetRatio ?: 0F)
|
||||
updateAppBarColorWhenScrollChanged(colorInBetween)
|
||||
currentTab?.primaryColor = colorInBetween
|
||||
currentTab?.useLightStyle = offsetMeetsCriticalPoint
|
||||
@ -975,8 +758,8 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
}
|
||||
refreshStatusBarStyle()
|
||||
if (!mShowTwoLevel) {
|
||||
mTabSelectedColor = if (offsetMeetsCriticalPoint) tabDefaultLightColor else tabSelectedColor
|
||||
mTabDefaultColor = if (offsetMeetsCriticalPoint) tabDefaultLightColor else tabDefaultColor
|
||||
mCurrentTabSelectedColor = if (offsetMeetsCriticalPoint) mTabDefaultLightColor else mTabSelectedColor
|
||||
mCurrentTabDefaultColor = if (offsetMeetsCriticalPoint) mTabDefaultLightColor else mTabDefaultColor
|
||||
mBinding?.indicatorView?.updateIndicatorDrawable(
|
||||
if (offsetMeetsCriticalPoint) {
|
||||
R.drawable.ic_home_tab_indicator_white.toDrawable()
|
||||
@ -1031,144 +814,6 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
} else null
|
||||
}
|
||||
|
||||
private fun notifyChildFragmentLifecycle(currentSelectedPosition: Int) {
|
||||
tryWithDefaultCatch {
|
||||
// 补充 Viewpager Fragment 的生命周期, 先调用旧选中 fragment 的 onPause 再当前的 onResume
|
||||
// 避免部分被内嵌的 Fragment 不能正常运作
|
||||
if (mFragmentList.size > mLastSelectedPosition) {
|
||||
val fragment: Fragment = mFragmentList[mLastSelectedPosition]
|
||||
if (!fragment.isAdded) return
|
||||
|
||||
fragment.onPause()
|
||||
val childFragmentManager = fragment.childFragmentManager
|
||||
val fragments = childFragmentManager.fragments
|
||||
for (childFragment in fragments) {
|
||||
childFragment.onPause()
|
||||
}
|
||||
}
|
||||
if (mFragmentList.size > currentSelectedPosition) {
|
||||
val fragment: Fragment = mFragmentList[currentSelectedPosition]
|
||||
if (!fragment.isAdded) return
|
||||
|
||||
fragment.onResume()
|
||||
val childFragmentManager = fragment.childFragmentManager
|
||||
val fragments = childFragmentManager.fragments
|
||||
for (childFragment in fragments) {
|
||||
childFragment.onResume()
|
||||
}
|
||||
}
|
||||
mLastSelectedPosition = currentSelectedPosition
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateFragments(tabEntityList: ArrayList<SubjectRecommendEntity>): ArrayList<Fragment> {
|
||||
val fragmentList = arrayListOf<Fragment>()
|
||||
for ((index, tabEntity) in tabEntityList.withIndex()) {
|
||||
val fragment = when (tabEntity.type) {
|
||||
"home" -> HomeFragment().with(Bundle())
|
||||
"top_game_comment" -> AmwayFragment().with(Bundle())
|
||||
"block" -> GameFragment().with(Bundle().apply {
|
||||
putParcelable(EntranceConsts.KEY_BLOCK_DATA, tabEntity)
|
||||
})
|
||||
|
||||
"server" -> GameServersPublishFragment().with(Bundle())
|
||||
"game_list" -> GameCollectionSquareFragment().with(Bundle().apply {
|
||||
putString(EntranceConsts.KEY_ENTRANCE, "顶部tab")
|
||||
putInt(EntranceConsts.KEY_TAB_INDEX, index)
|
||||
putString(EntranceConsts.KEY_NAME, tabEntity.name)
|
||||
})
|
||||
|
||||
"column_test" -> GameServersTestFragment().with(Bundle().apply {
|
||||
putString(GameServersTestFragment.TEST_COLUMN_ID, tabEntity.link)
|
||||
})
|
||||
|
||||
"category" -> CategoryDirectoryFragment().with(Bundle().apply {
|
||||
putString(EntranceConsts.KEY_CATEGORY_ID, tabEntity.link)
|
||||
putString(EntranceConsts.KEY_CATEGORY_TITLE, tabEntity.text)
|
||||
})
|
||||
|
||||
"catalog" -> CatalogFragment().with(Bundle().apply {
|
||||
putString(EntranceConsts.KEY_CATALOG_ID, tabEntity.link)
|
||||
putString(EntranceConsts.KEY_CATALOG_TITLE, tabEntity.text)
|
||||
})
|
||||
|
||||
"category_v2" -> CategoryV2Fragment().with(Bundle().apply {
|
||||
putString(EntranceConsts.KEY_CATEGORY_ID, tabEntity.link)
|
||||
putString(EntranceConsts.KEY_CATEGORY_TITLE, tabEntity.text)
|
||||
})
|
||||
|
||||
"ranking", "column_collection" -> ColumnCollectionDetailFragment().with(Bundle().apply {
|
||||
putString(EntranceConsts.KEY_ENTRANCE, "首页")
|
||||
putString(EntranceConsts.KEY_COLLECTION_ID, tabEntity.link)
|
||||
putInt(EntranceConsts.KEY_POSITION, 0)
|
||||
putString(EntranceConsts.KEY_COLUMNNAME, tabEntity.text)
|
||||
putBoolean(EntranceConsts.KEY_IS_COLUMN_COLLECTION, true)
|
||||
putInt(EntranceConsts.KEY_TAB_INDEX, index)
|
||||
putParcelableArrayList(
|
||||
EntranceConsts.KEY_EXPOSURE_SOURCE_LIST,
|
||||
arrayListOf(ExposureSource("顶部tab", tabEntity.name ?: ""))
|
||||
)
|
||||
})
|
||||
|
||||
"column" -> SubjectFragment().with(Bundle().apply {
|
||||
putString(EntranceConsts.KEY_ENTRANCE, "首页")
|
||||
putParcelable(
|
||||
EntranceConsts.KEY_SUBJECT_DATA,
|
||||
SubjectData(tabEntity.link, tabEntity.text, false)
|
||||
)
|
||||
})
|
||||
|
||||
"web" -> WebFragment().with(Bundle().apply {
|
||||
putString(EntranceConsts.KEY_URL, tabEntity.link)
|
||||
putString(EntranceConsts.KEY_ENTRANCE, "首页tab")
|
||||
putBoolean(WebFragment.KEY_OPEN_NATIVE_PAGE, false)
|
||||
putBoolean(WebFragment.KEY_ENABLE_HORIZONTAL_SCROLL_DISPATCH, true)
|
||||
if (tabEntity.link?.contains("leave_web_page_handle_back_pressed=true") == true) {
|
||||
putBoolean(WebFragment.KEY_LEAVE_WEB_PAGE_TO_HANDLE_BACK_PRESSED, true)
|
||||
}
|
||||
})
|
||||
|
||||
"common_collection" -> CommonCollectionDetailFragment().with(Bundle().apply {
|
||||
putString(EntranceConsts.KEY_ENTRANCE, "首页顶部Tab栏")
|
||||
putString(EntranceConsts.KEY_COLLECTION_ID, tabEntity.link)
|
||||
putString(EntranceConsts.KEY_COLUMNNAME, tabEntity.text)
|
||||
putInt(EntranceConsts.KEY_TAB_INDEX, index)
|
||||
putParcelableArrayList(
|
||||
EntranceConsts.KEY_EXPOSURE_SOURCE_LIST,
|
||||
arrayListOf(ExposureSource("顶部tab", tabEntity.name ?: ""))
|
||||
)
|
||||
})
|
||||
|
||||
"explore_column" -> DiscoveryFragment().with(Bundle().apply {
|
||||
putString(EntranceConsts.KEY_ENTRANCE, "首页")
|
||||
putInt(EntranceConsts.KEY_POSITION, index)
|
||||
})
|
||||
|
||||
"column_test_v2" -> GameServerTestV2Fragment().with(Bundle().apply {
|
||||
putString(EntranceConsts.KEY_ENTRANCE, "首页")
|
||||
putInt(EntranceConsts.KEY_POSITION, index)
|
||||
putParcelable(
|
||||
EntranceConsts.KEY_EXPOSURE_SOURCE,
|
||||
ExposureSource("顶部tab", tabEntity.name ?: "")
|
||||
)
|
||||
})
|
||||
|
||||
"bbs" -> Fragment()
|
||||
else -> Fragment()
|
||||
}
|
||||
fragment.arguments?.putInt(EntranceConsts.KEY_TAB_COUNT, tabEntityList.size)
|
||||
fragment.arguments?.putBoolean(EntranceConsts.KEY_IS_HOME, true)
|
||||
if (fragment.arguments?.getParcelable<ExposureSource>(EntranceConsts.KEY_EXPOSURE_SOURCE) == null) {
|
||||
fragment.arguments?.putParcelable(
|
||||
EntranceConsts.KEY_EXPOSURE_SOURCE,
|
||||
ExposureSource("首页顶部Tab栏", tabEntity.name ?: "")
|
||||
)
|
||||
}
|
||||
fragmentList.add(fragment)
|
||||
}
|
||||
return fragmentList
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新 AppBar 的控件 style
|
||||
*/
|
||||
@ -1181,34 +826,11 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
mSearchToolbarFragment.updateStyle(mIsDarkModeOn || useLightStyle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 TabView
|
||||
*/
|
||||
private fun generateTabView(title: String): TabItemMainBinding {
|
||||
val binding = TabItemMainBinding.inflate(LayoutInflater.from(requireContext()))
|
||||
binding.titleTv.run {
|
||||
text = title
|
||||
textSize = DEFAULT_TAB_TEXT_SIZE
|
||||
setTextColor(mTabDefaultColor)
|
||||
}
|
||||
binding.invisibleTitleTv.run {
|
||||
text = title
|
||||
textSize = DEFAULT_TAB_TEXT_SIZE
|
||||
}
|
||||
return binding
|
||||
}
|
||||
|
||||
override fun onBackPressed(): Boolean {
|
||||
if (mShowTwoLevel) {
|
||||
finishTwoLevel("主动收起")
|
||||
return true
|
||||
}
|
||||
mBinding?.viewPager?.run {
|
||||
val currentFragment = mFragmentList.safelyGetInRelease(currentItem)
|
||||
if (currentFragment is WebFragment) {
|
||||
return currentFragment.onBackPressed()
|
||||
}
|
||||
}
|
||||
return super.onBackPressed()
|
||||
}
|
||||
|
||||
@ -1256,70 +878,11 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化每个需要显示的 TabView
|
||||
*/
|
||||
private fun initTabView(tabEntityList: ArrayList<SubjectRecommendEntity>) {
|
||||
for (i in 0 until tabEntityList.size) {
|
||||
val tabView = mBinding?.tabLayout?.getTabAt(i) ?: continue
|
||||
val tabEntity = tabEntityList[i]
|
||||
val tabTitle = if (tabView.text != null) tabView.text.toString() else ""
|
||||
val tabViewBinding = generateTabView(tabTitle)
|
||||
val tabImageStyle = if (tabEntity.img.isNullOrEmpty()) {
|
||||
TAB_IMAGE_EMPTY
|
||||
} else if (tabEntity.showImgOnSelected == true) {
|
||||
TAB_IMAGE_ALWAYS_ON
|
||||
} else {
|
||||
TAB_IMAGE_HIDE_ON_SELECTED
|
||||
}
|
||||
|
||||
mTabBindingList.add(tabViewBinding)
|
||||
mTabImageStyleList.add(tabImageStyle)
|
||||
|
||||
if (!tabEntity.img.isNullOrEmpty()) {
|
||||
tabViewBinding.titleTv.visibility = View.GONE
|
||||
tabViewBinding.invisibleTitleTv.visibility = View.GONE
|
||||
tabViewBinding.titleIv.setFixedHeight(16)
|
||||
// 部分设备加载图片时会获取到错误的最小宽度,这里为它做个 64DP 的保底尺寸
|
||||
tabViewBinding.titleIv.setTag(ImageUtils.TAG_TARGET_WIDTH, 64F.dip2px())
|
||||
tabViewBinding.titleIv.display(tabEntity.img)
|
||||
tabViewBinding.titleIv.registerLoadingCallback(object : WrapContentDraweeView.LoadingCallback {
|
||||
override fun loaded() {
|
||||
postRunnable {
|
||||
mBinding?.run {
|
||||
// 图片 layout 完成后,更新 tabBar 和 indicatorView 的位置,避免偏移
|
||||
tabLayout.setScrollPosition(viewPager.currentItem, 0F, false)
|
||||
indicatorView.generatePath(viewPager.currentItem, 0F)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
tabViewBinding.titleTv.visibility = View.VISIBLE
|
||||
tabViewBinding.invisibleTitleTv.visibility = View.INVISIBLE
|
||||
}
|
||||
tabView.customView = tabViewBinding.root
|
||||
tabView.view.setPadding(0, 0, 0, 0)
|
||||
tabView.view.setOnClickListener {
|
||||
if (mShowTwoLevel) {
|
||||
mBinding?.twoLevelHeader?.setFloorDuration(100)
|
||||
mBinding?.refreshLayout?.setFloorDuration(100)
|
||||
finishTwoLevel("跳转收起")
|
||||
}
|
||||
}
|
||||
|
||||
// 第一个和最后一个分别设置额外的外边距
|
||||
if (i == 0) {
|
||||
tabView.view.updateLayoutParams {
|
||||
this as LinearLayout.LayoutParams
|
||||
setMargins(10F.dip2px(), 0, 0, 0)
|
||||
}
|
||||
} else if (i == tabEntityList.size - 1) {
|
||||
tabView.view.updateLayoutParams {
|
||||
this as LinearLayout.LayoutParams
|
||||
setMargins(0, 0, 10F.dip2px(), 0)
|
||||
}
|
||||
}
|
||||
override fun onTabViewClick() {
|
||||
if (mShowTwoLevel) {
|
||||
mBinding?.twoLevelHeader?.setFloorDuration(100)
|
||||
mBinding?.refreshLayout?.setFloorDuration(100)
|
||||
finishTwoLevel("跳转收起")
|
||||
}
|
||||
}
|
||||
|
||||
@ -1331,35 +894,11 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
DisplayUtils.setLightStatusBar(requireActivity(), !mIsDisplayingLightContent && !mIsDarkModeOn)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 ViewPager 默认的选中项
|
||||
*/
|
||||
private fun setRestoredCurItem(viewPager: ViewPager) {
|
||||
// 设置默认 position 避免 position 为 0 的 fragment 被先加载显示再跳转至具体页面
|
||||
tryCatchInRelease {
|
||||
val field = ViewPager::class.java.getDeclaredField("mRestoredCurItem")
|
||||
field.isAccessible = true
|
||||
field.set(viewPager, mDefaultSelectedTab)
|
||||
mLastSelectedPosition = mDefaultSelectedTab
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全地从根据 position 获取 fragment
|
||||
*/
|
||||
private fun getFragment(position: Int): Fragment? {
|
||||
return if (position < mFragmentList.size) {
|
||||
mFragmentList.safelyGetInRelease(position)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录 tab 被选中的日志
|
||||
*/
|
||||
private fun logTabSelected(tabEntity: SubjectRecommendEntity, position: Int) {
|
||||
LogUtils.logHomeTopTabClick(tabEntity.name, tabEntity.type, tabEntity.text, tabEntity.link, position)
|
||||
override fun logTabSelected(tabEntity: SubjectRecommendEntity, position: Int) {
|
||||
LogUtils.logHomeTopTabClick(tabEntity.name, tabEntity.type, tabEntity.text, tabEntity.link, position, "首页")
|
||||
|
||||
SensorsBridge.trackEvent("HomeTopTabSelect",
|
||||
json {
|
||||
@ -1384,24 +923,11 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val LAST_SELECTED_POSITION = "last_selected_position"
|
||||
|
||||
var TAB_SELECTED_COLOR: Int = R.color.text_title
|
||||
var TAB_DEFAULT_COLOR: Int = R.color.text_subtitle
|
||||
|
||||
var TAB_DEFAULT_COLOR_LIGHT: Int = R.color.search_text_color_light
|
||||
|
||||
var DEFAULT_TAB_TEXT_SIZE = 16F
|
||||
|
||||
const val HOME_PUSH_VIDEO_PLAY_DELAY = 100L
|
||||
const val AUTO_FINISH_TWO_LEVEL_DELAY = 5000L
|
||||
const val FINISH_TWO_LEVEL_DELAY = 1000L
|
||||
const val AUTO_OPEN_TWO_LEVEL_DURATION = 1000L
|
||||
const val PULL_TAB_TEXT_STYLE_UPDATE_PERCENT = 0.5F
|
||||
|
||||
const val TAB_IMAGE_EMPTY = 0
|
||||
const val TAB_IMAGE_HIDE_ON_SELECTED = 1
|
||||
const val TAB_IMAGE_ALWAYS_ON = 2
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user