Compare commits
112 Commits
feat/cw-te
...
feat/sync-
| Author | SHA1 | Date | |
|---|---|---|---|
| bd02a0b4be | |||
| 7a498763bb | |||
| 8b839a5b13 | |||
| 7d2ed0eac0 | |||
| 5c70bc2237 | |||
| 03b36096b8 | |||
| 4191dbc4f0 | |||
| cc20b6e38a | |||
| 3ad5890238 | |||
| 6179d7055b | |||
| f18391adc2 | |||
| 3a2f15a436 | |||
| c0e8160955 | |||
| 9038131c96 | |||
| 4430ae1107 | |||
| d6aa2690b2 | |||
| e42fd24b71 | |||
| 452a1ede24 | |||
| ceb227f645 | |||
| 479ea5778b | |||
| 8969d6fd5d | |||
| cc43f2e0fd | |||
| ab12491f2f | |||
| ae24ab0c87 | |||
| 383712900c | |||
| cea62b55e2 | |||
| ff6cdb1ba3 | |||
| b6e531fa96 | |||
| e7a37df690 | |||
| 5308ccfabe | |||
| 2ee49b9a20 | |||
| 3af3d413c0 | |||
| 9bf24977ca | |||
| bf1dd958cd | |||
| 30c34b799b | |||
| b202b580bb | |||
| 239b056abb | |||
| 315be3797c | |||
| 6d29da5172 | |||
| 8aeb0d6f09 | |||
| bdcca58770 | |||
| 4115383b68 | |||
| 9075bfa214 | |||
| 3fa63e331b | |||
| aef19fcd49 | |||
| 15d7252974 | |||
| f6fa060f3a | |||
| 7cfe48b3c8 | |||
| 6bd3c1011d | |||
| 3447ecffd8 | |||
| 644b93ab02 | |||
| 6b44140ff3 | |||
| 78d26b4cc1 | |||
| 5565539445 | |||
| 1ee0f292ba | |||
| f609637f0b | |||
| 9d10add8eb | |||
| f5a39f982e | |||
| 1a063bb0c1 | |||
| 86340d603f | |||
| 0731cc1fde | |||
| 86dfee2ff9 | |||
| edf82952ce | |||
| 062f0149d0 | |||
| a504f00bac | |||
| 4412d159bb | |||
| e119b7fecd | |||
| 72460b88be | |||
| 3fe7c8252e | |||
| 36ebab77ee | |||
| e84db01984 | |||
| ae605d4a55 | |||
| 882bf4b551 | |||
| 968164af55 | |||
| 0119e6f123 | |||
| 7093552259 | |||
| 2be52d21ee | |||
| cb093cc3f0 | |||
| 3cbdd94189 | |||
| 11013319bf | |||
| aa954b3af9 | |||
| 93f279a384 | |||
| 4e54833cc9 | |||
| f95862da8b | |||
| 1515df34b5 | |||
| 8a8ef40dc1 | |||
| b6194fed26 | |||
| 02752f6c81 | |||
| b33d367dfd | |||
| d5046ab431 | |||
| a53168c9bc | |||
| 3cbc8c2f74 | |||
| 7398b83004 | |||
| 8013426ded | |||
| b86d85b15f | |||
| 5a73afbab3 | |||
| e19ee25839 | |||
| 61bf39e95f | |||
| ef82ae2378 | |||
| 2dcccc22a8 | |||
| cb0e77d204 | |||
| a6ea178609 | |||
| 6a62f08891 | |||
| ddb48481d2 | |||
| 48a55a6b31 | |||
| 50fcb0c3ea | |||
| e97722b6fb | |||
| 2163b2ff9e | |||
| b9558e2732 | |||
| e9139c66e1 | |||
| f492d2ea97 | |||
| 46955685bb |
@ -72,6 +72,7 @@ android_build:
|
||||
only:
|
||||
- dev
|
||||
- release
|
||||
- feat/GHZSCY-6578
|
||||
|
||||
# 代码检查
|
||||
sonarqube_analysis:
|
||||
@ -156,4 +157,5 @@ oss-upload&send-email:
|
||||
- /usr/local/bin/python /ci-android-mail-jira-comment.py
|
||||
only:
|
||||
- dev
|
||||
- release
|
||||
- release
|
||||
- feat/GHZSCY-6578
|
||||
@ -107,7 +107,6 @@ android {
|
||||
buildConfigField "String", "WEIBO_APPKEY", "\"${WEIBO_APPKEY}\""
|
||||
// 一体包的32位畅玩游戏助手包名
|
||||
buildConfigField "String", "EXT_PACKAGE_NAME", "\"${rootProject.ext.EXT_PACKAGE_NAME}\""
|
||||
buildConfigField "String", "VA_VERSION_NAME", "\"${rootProject.ext.VA_VERSION}\""
|
||||
}
|
||||
|
||||
// gradle 2.2以上默认同时启用v1和v2(优先用于Android N)
|
||||
@ -218,6 +217,9 @@ android {
|
||||
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${DEV_QUICK_LOGIN_APPKEY}\""
|
||||
buildConfigField "String", "DEV_CSJ_APPID", "\"${DEV_CSJ_APPID}\""
|
||||
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
|
||||
|
||||
buildConfigField "String", "VA_VERSION_NAME", "\"${rootProject.ext.VA_VERSION}-debug\""
|
||||
manifestPlaceholders.put("VA_VERSION_NAME", "${rootProject.ext.VA_VERSION}-debug")
|
||||
}
|
||||
|
||||
// publish, 发布时候使用的 flavor,接口仅包含正式环境
|
||||
@ -231,6 +233,9 @@ android {
|
||||
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
|
||||
buildConfigField "String", "DEV_CSJ_APPID", "\"${CSJ_APPID}\""
|
||||
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
|
||||
|
||||
buildConfigField "String", "VA_VERSION_NAME", "\"${rootProject.ext.VA_VERSION}\""
|
||||
manifestPlaceholders.put("VA_VERSION_NAME", "${rootProject.ext.VA_VERSION}")
|
||||
}
|
||||
|
||||
tea {
|
||||
@ -244,7 +249,10 @@ android {
|
||||
buildConfigField "String", "DEV_CSJ_APPID", "\"${CSJ_APPID}\""
|
||||
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
|
||||
|
||||
buildConfigField "String", "VA_VERSION_NAME", "\"${rootProject.ext.VA_VERSION}\""
|
||||
|
||||
manifestPlaceholders.put("APPLOG_SCHEME", "rangersapplog.byAx6uYt".toLowerCase())
|
||||
manifestPlaceholders.put("VA_VERSION_NAME", "${rootProject.ext.VA_VERSION}")
|
||||
}
|
||||
|
||||
kuaishou {
|
||||
@ -257,6 +265,9 @@ android {
|
||||
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
|
||||
buildConfigField "String", "DEV_CSJ_APPID", "\"${CSJ_APPID}\""
|
||||
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
|
||||
|
||||
buildConfigField "String", "VA_VERSION_NAME", "\"${rootProject.ext.VA_VERSION}\""
|
||||
manifestPlaceholders.put("VA_VERSION_NAME", "${rootProject.ext.VA_VERSION}")
|
||||
}
|
||||
|
||||
gdt {
|
||||
@ -269,6 +280,9 @@ android {
|
||||
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
|
||||
buildConfigField "String", "DEV_CSJ_APPID", "\"${CSJ_APPID}\""
|
||||
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
|
||||
|
||||
buildConfigField "String", "VA_VERSION_NAME", "\"${rootProject.ext.VA_VERSION}\""
|
||||
manifestPlaceholders.put("VA_VERSION_NAME", "${rootProject.ext.VA_VERSION}")
|
||||
}
|
||||
|
||||
sm {
|
||||
@ -281,6 +295,9 @@ android {
|
||||
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
|
||||
buildConfigField "String", "DEV_CSJ_APPID", "\"${CSJ_APPID}\""
|
||||
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
|
||||
|
||||
buildConfigField "String", "VA_VERSION_NAME", "\"${rootProject.ext.VA_VERSION}\""
|
||||
manifestPlaceholders.put("VA_VERSION_NAME", "${rootProject.ext.VA_VERSION}")
|
||||
}
|
||||
|
||||
// 港澳台
|
||||
@ -371,7 +388,7 @@ dependencies {
|
||||
|
||||
implementation "com.lg:easyfloat:${easyFloat}"
|
||||
|
||||
implementation ("com.lg:apksig:${apksig}") {
|
||||
implementation("com.lg:apksig:${apksig}") {
|
||||
exclude group: 'com.google.protobuf'
|
||||
}
|
||||
|
||||
@ -387,7 +404,7 @@ dependencies {
|
||||
implementation project(':vspace-bridge:vspace')
|
||||
implementation(project(':feature:xapk-installer'))
|
||||
|
||||
implementation (project(':module_common')) {
|
||||
implementation(project(':module_common')) {
|
||||
exclude group: 'androidx.swiperefreshlayout'
|
||||
}
|
||||
|
||||
@ -462,9 +479,11 @@ dependencies {
|
||||
implementation(project(':feature:sentry'))
|
||||
}
|
||||
|
||||
implementation(project(':feature:media_select'))
|
||||
|
||||
implementation(project(":module_va_api"))
|
||||
implementation(project(":va-archive-common"))
|
||||
if(!gradle.ext.excludeOptionalModules || gradle.ext.enableVa) {
|
||||
if (!gradle.ext.excludeOptionalModules || gradle.ext.enableVa) {
|
||||
implementation(project(":module_va_impl"))
|
||||
}
|
||||
debugImplementation "com.bytedance.tools.codelocator:codelocator-core:2.0.3"
|
||||
|
||||
@ -194,7 +194,6 @@ class InstallExternalGameFragment : ToolbarFragment(), OnItemClickListener {
|
||||
VirtualAppManager.AIDL_SERVER_REMOTE_GUIDE_ACTIVITY
|
||||
)
|
||||
)
|
||||
intent.putExtra("isOpTest", true)
|
||||
requireActivity().startActivity(intent)
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
<resources>
|
||||
<string name="title_install_external_game">從SD卡安裝</string>
|
||||
<string name="text_install">安裝</string>
|
||||
<string name="text_update">更新</string>
|
||||
<string name="text_uninstall">卸載</string>
|
||||
<string name="text_start">啟動</string>
|
||||
</resources>
|
||||
@ -185,6 +185,8 @@
|
||||
android:name="io.sentry.breadcrumbs.system-events"
|
||||
android:value="false" />
|
||||
|
||||
<meta-data android:name="module_version" android:value="${VA_VERSION_NAME}" />
|
||||
|
||||
<service android:name="com.gh.ndownload.NDownloadService" />
|
||||
|
||||
<activity
|
||||
@ -454,9 +456,6 @@
|
||||
android:name="com.gh.gamecenter.video.game.GameVideoActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.qa.editor.LocalMediaActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.servers.GameServersActivity"
|
||||
@ -574,10 +573,6 @@
|
||||
android:name=".personal.DeliveryInfoActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".qa.editor.PreviewVideoActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".qa.video.publish.VideoPublishActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
@ -227,18 +227,7 @@ object AdDelegateHelper {
|
||||
/**
|
||||
* 是否大于开屏广告展示间隔时长
|
||||
*/
|
||||
private fun isMatchStartUpAdDisplayRule(): Boolean {
|
||||
mSplashAd?.displayRule?.run {
|
||||
if (adDisplayInterval > 0) {
|
||||
val lastShowTime = SPUtils.getLong(Constants.SP_LAST_SPLASH_AD_SHOW_TIME, 0L)
|
||||
val durationInMinutes = (System.currentTimeMillis() - lastShowTime).toFloat() / 1000 / 60
|
||||
return durationInMinutes > adDisplayInterval
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
private fun isMatchStartUpAdDisplayRule(): Boolean = isMatchAdDisplayRule(mSplashAd, Constants.SP_LAST_SPLASH_AD_SHOW_TIME)
|
||||
|
||||
/**
|
||||
* 是否大于广告管理展示间隔时长
|
||||
@ -292,6 +281,7 @@ object AdDelegateHelper {
|
||||
adViewHeightInDp: Float,
|
||||
startAdContainer: ViewGroup,
|
||||
sdkStartAdContainer: ViewGroup,
|
||||
sdkJumpBtn: TextView,
|
||||
adsViewGroup: FrameLayout,
|
||||
handler: BaseActivity.BaseHandler,
|
||||
isHotLaunch: Boolean,
|
||||
@ -313,6 +303,7 @@ object AdDelegateHelper {
|
||||
adViewHeightInDp,
|
||||
startAdContainer,
|
||||
sdkStartAdContainer,
|
||||
sdkJumpBtn,
|
||||
adsViewGroup,
|
||||
handler,
|
||||
isHotLaunch,
|
||||
@ -330,6 +321,7 @@ object AdDelegateHelper {
|
||||
adViewHeightInDp,
|
||||
startAdContainer,
|
||||
sdkStartAdContainer,
|
||||
sdkJumpBtn,
|
||||
adsViewGroup,
|
||||
handler,
|
||||
isHotLaunch,
|
||||
@ -353,6 +345,7 @@ object AdDelegateHelper {
|
||||
adViewHeightInDp: Float,
|
||||
startAdContainer: ViewGroup,
|
||||
sdkStartAdContainer: ViewGroup,
|
||||
sdkJumpBtn: TextView,
|
||||
adsViewGroup: FrameLayout,
|
||||
handler: BaseActivity.BaseHandler,
|
||||
isHotLaunch: Boolean,
|
||||
@ -374,6 +367,7 @@ object AdDelegateHelper {
|
||||
adViewHeightInDp,
|
||||
startAdContainer,
|
||||
sdkStartAdContainer,
|
||||
sdkJumpBtn,
|
||||
adsViewGroup,
|
||||
handler,
|
||||
isHotLaunch,
|
||||
@ -403,13 +397,14 @@ object AdDelegateHelper {
|
||||
sdkStartAdContainer.visibility = View.VISIBLE
|
||||
requestCsjSplashAd(
|
||||
activity,
|
||||
thirdPartyAd.slotId,
|
||||
adViewWidthInPx,
|
||||
adViewHeightInPx,
|
||||
adViewWidthInDp,
|
||||
adViewHeightInDp,
|
||||
sdkStartAdContainer,
|
||||
sdkJumpBtn,
|
||||
timeout,
|
||||
isHotLaunch,
|
||||
sdkSplashCallback
|
||||
)
|
||||
}
|
||||
@ -420,27 +415,65 @@ object AdDelegateHelper {
|
||||
*/
|
||||
private fun requestCsjSplashAd(
|
||||
activity: Activity,
|
||||
slotId: String,
|
||||
adViewWidthInPx: Int,
|
||||
adViewHeightInPx: Int,
|
||||
adViewWidthInDp: Float,
|
||||
adViewHeightInDp: Float,
|
||||
startAdContainer: ViewGroup,
|
||||
sdkJumpBtn: TextView,
|
||||
timeout: Int,
|
||||
isHotLaunch: Boolean,
|
||||
callback: (isSuccess: Boolean) -> Unit,
|
||||
) {
|
||||
if (mCsjAdImpl == null) {
|
||||
val thirdPartyAd = if (isHotLaunch) mSplashAd?.hotStartThirdPartyAd else mSplashAd?.thirdPartyAd
|
||||
if (mCsjAdImpl == null || thirdPartyAd == null) {
|
||||
callback.invoke(false)
|
||||
} else {
|
||||
sdkJumpBtn.setOnClickListener {
|
||||
callback.invoke(true)
|
||||
if (activity is BaseActivity) {
|
||||
activity.baseHandler.removeMessages(MainActivity.COUNTDOWN_SDK_AD)
|
||||
}
|
||||
}
|
||||
|
||||
val onAdShowAction = {
|
||||
sdkJumpBtn.visibility = View.VISIBLE
|
||||
if (activity is BaseActivity) {
|
||||
activity.baseHandler.sendEmptyMessageDelayed(MainActivity.COUNTDOWN_SDK_AD, 1000)
|
||||
}
|
||||
SensorsBridge.trackEvent("ThirdPartyAdShow",
|
||||
"ad_source", thirdPartyAd.sourceName,
|
||||
"ad_id", thirdPartyAd.slotId,
|
||||
"ad_format", mSplashAd?.typeChinese ?: "",
|
||||
"ad_placement", "光环启动",
|
||||
"launch_type", if (isHotLaunch) "热启动" else "冷启动",
|
||||
"ad_space_id", mSplashAd?.id ?: "",
|
||||
"ad_space_name", mSplashAd?.name ?: ""
|
||||
)
|
||||
}
|
||||
val onAdClickAction = {
|
||||
callback.invoke(true)
|
||||
SensorsBridge.trackEvent("ThirdPartyAdClick",
|
||||
"ad_source", thirdPartyAd.sourceName,
|
||||
"ad_id", thirdPartyAd.slotId,
|
||||
"ad_format", mSplashAd?.typeChinese ?: "",
|
||||
"ad_placement", "光环启动",
|
||||
"launch_type", if (isHotLaunch) "热启动" else "冷启动",
|
||||
"ad_space_id", mSplashAd?.id ?: "",
|
||||
"ad_space_name", mSplashAd?.name ?: ""
|
||||
)
|
||||
}
|
||||
mCsjAdImpl?.requestSplashAd(
|
||||
activity,
|
||||
slotId,
|
||||
thirdPartyAd.slotId,
|
||||
adViewWidthInPx,
|
||||
adViewHeightInPx,
|
||||
adViewWidthInDp,
|
||||
adViewHeightInDp,
|
||||
startAdContainer,
|
||||
timeout,
|
||||
onAdShowAction,
|
||||
onAdClickAction,
|
||||
callback,
|
||||
)
|
||||
}
|
||||
@ -457,6 +490,7 @@ object AdDelegateHelper {
|
||||
adViewHeightInDp: Float,
|
||||
startAdContainer: ViewGroup,
|
||||
sdkStartAdContainer: ViewGroup,
|
||||
sdkJumpBtn: TextView,
|
||||
adsViewGroup: FrameLayout,
|
||||
handler: BaseActivity.BaseHandler,
|
||||
isHotLaunch: Boolean,
|
||||
@ -474,6 +508,7 @@ object AdDelegateHelper {
|
||||
adViewHeightInDp,
|
||||
startAdContainer,
|
||||
sdkStartAdContainer,
|
||||
sdkJumpBtn,
|
||||
adsViewGroup,
|
||||
handler,
|
||||
isHotLaunch,
|
||||
@ -621,9 +656,11 @@ object AdDelegateHelper {
|
||||
slotId: String,
|
||||
adContainerView: ViewGroup,
|
||||
expressViewWidth: Float,
|
||||
onAdShowAction: () -> Unit,
|
||||
onAdClickAction: () -> Unit,
|
||||
callback: (isSuccess: Boolean) -> Unit,
|
||||
) {
|
||||
mCsjAdImpl?.requestFlowAd(fragment, adContainerView, slotId, expressViewWidth, callback)
|
||||
mCsjAdImpl?.requestFlowAd(fragment, adContainerView, slotId, expressViewWidth, onAdShowAction, onAdClickAction, callback)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -634,6 +671,8 @@ object AdDelegateHelper {
|
||||
containerView: ViewGroup,
|
||||
ad: AdConfig.ThirdPartyAd,
|
||||
expressViewWidthInDp: Float,
|
||||
onAdShowAction: () -> Unit,
|
||||
onAdClickAction: () -> Unit,
|
||||
callback: (isSuccess: Boolean) -> Unit
|
||||
) {
|
||||
|
||||
@ -656,6 +695,28 @@ object AdDelegateHelper {
|
||||
slotId,
|
||||
expressViewWidthInDp,
|
||||
expressViewHeightInDp,
|
||||
onAdShowAction,
|
||||
onAdClickAction,
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取第三方 全屏/插屏 广告
|
||||
*/
|
||||
fun requestFullScreenAd(
|
||||
fragment: Fragment,
|
||||
ad: AdConfig.ThirdPartyAd,
|
||||
onAdShowAction: () -> Unit,
|
||||
onAdClickAction: () -> Unit,
|
||||
callback: (isSuccess: Boolean) -> Unit
|
||||
) {
|
||||
val slotId = ad.slotId
|
||||
mCsjAdImpl?.requestFullScreenAd(
|
||||
fragment,
|
||||
slotId,
|
||||
onAdShowAction,
|
||||
onAdClickAction,
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
@ -3,42 +3,105 @@ package com.gh.ad
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
||||
import android.view.ViewStub
|
||||
import androidx.fragment.app.Fragment
|
||||
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.provider.ILaunchAd
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge
|
||||
import com.gh.gamecenter.common.utils.goneIf
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.entity.AdConfig
|
||||
|
||||
@Route(path = RouteConsts.provider.vaAd, name = "畅玩启动页广告")
|
||||
class LaunchAdImpl : ILaunchAd {
|
||||
override fun init(context: Context?) {
|
||||
}
|
||||
|
||||
override fun requestAd(fragment: Fragment, container: ViewGroup, maskView: View) {
|
||||
override fun requestAd(fragment: Fragment, container: ViewGroup, maskView: View, topViewStub: ViewStub, bottomViewStub: ViewStub, adClickAction: () -> Unit): View {
|
||||
if (AdDelegateHelper.shouldShowHelperLaunchAd()) {
|
||||
val launchAd = AdDelegateHelper.vGameLaunchAd
|
||||
val showThirdPartyAd = launchAd?.displayRule?.adSource == AdDelegateHelper.AD_TYPE_SDK
|
||||
val thirdPartyAd = launchAd?.thirdPartyAd
|
||||
if (showThirdPartyAd && thirdPartyAd != null) {
|
||||
AdDelegateHelper.requestThirdPartyBannerAd(
|
||||
fragment,
|
||||
container,
|
||||
thirdPartyAd,
|
||||
DisplayUtils.getScreenWidthInDp(fragment.requireActivity()),
|
||||
) { isSuccess ->
|
||||
maskView.goneIf(!isSuccess)
|
||||
if (isSuccess) {
|
||||
SPUtils.setLong(Constants.SP_LAST_HELPER_LAUNCH_AD_SHOW_TIME, System.currentTimeMillis())
|
||||
}
|
||||
val onAdShowAction = {
|
||||
SensorsBridge.trackEvent("ThirdPartyAdShow",
|
||||
"ad_source", thirdPartyAd.sourceName,
|
||||
"ad_id", thirdPartyAd.slotId,
|
||||
"ad_format", launchAd.typeChinese,
|
||||
"ad_placement", AD_PLACEMENT,
|
||||
"ad_space_id", launchAd.id,
|
||||
"ad_space_name", launchAd.name
|
||||
)
|
||||
}
|
||||
val onAdClickAction = {
|
||||
SensorsBridge.trackEvent("ThirdPartyAdClick",
|
||||
"ad_source", thirdPartyAd.sourceName,
|
||||
"ad_id", thirdPartyAd.slotId,
|
||||
"ad_format", launchAd.typeChinese,
|
||||
"ad_placement", AD_PLACEMENT,
|
||||
"ad_space_id", launchAd.id,
|
||||
"ad_space_name", launchAd.name
|
||||
)
|
||||
adClickAction.invoke()
|
||||
}
|
||||
|
||||
if (launchAd.type == AdConfig.TYPE_BANNER) {
|
||||
requestBannerAd(fragment, container, maskView, thirdPartyAd, onAdShowAction, onAdClickAction)
|
||||
return topViewStub.inflate()
|
||||
} else if (launchAd.type == AdConfig.TYPE_INTERSTITIAL) {
|
||||
requestFullScreenAd(fragment, thirdPartyAd, onAdShowAction, onAdClickAction)
|
||||
return bottomViewStub.inflate()
|
||||
}
|
||||
}
|
||||
}
|
||||
return bottomViewStub.inflate()
|
||||
}
|
||||
|
||||
private fun requestBannerAd(
|
||||
fragment: Fragment,
|
||||
container: ViewGroup,
|
||||
maskView: View,
|
||||
thirdPartyAd: AdConfig.ThirdPartyAd,
|
||||
onAdShowAction: () -> Unit,
|
||||
onAdClickAction: () -> Unit,
|
||||
) {
|
||||
AdDelegateHelper.requestThirdPartyBannerAd(
|
||||
fragment,
|
||||
container,
|
||||
thirdPartyAd,
|
||||
DisplayUtils.getScreenWidthInDp(fragment.requireActivity()),
|
||||
onAdShowAction,
|
||||
onAdClickAction
|
||||
) { isSuccess ->
|
||||
maskView.goneIf(!isSuccess)
|
||||
if (isSuccess) {
|
||||
SPUtils.setLong(Constants.SP_LAST_HELPER_LAUNCH_AD_SHOW_TIME, System.currentTimeMillis())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun requestFullScreenAd(
|
||||
fragment: Fragment,
|
||||
thirdPartyAd: AdConfig.ThirdPartyAd,
|
||||
onAdShowAction: () -> Unit,
|
||||
onAdClickAction: () -> Unit
|
||||
) {
|
||||
AdDelegateHelper.requestFullScreenAd(
|
||||
fragment,
|
||||
thirdPartyAd,
|
||||
onAdShowAction,
|
||||
onAdClickAction
|
||||
) { isSuccess ->
|
||||
if (isSuccess) {
|
||||
SPUtils.setLong(Constants.SP_LAST_HELPER_LAUNCH_AD_SHOW_TIME, System.currentTimeMillis())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val AD_PLACEMENT = "畅玩启动"
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,8 @@ import com.gh.common.view.RichEditor
|
||||
import com.gh.gamecenter.CropImageActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.activity.ToolBarActivity
|
||||
import com.gh.gamecenter.common.entity.LocalVideoEntity
|
||||
import com.gh.gamecenter.feature.selector.LocalMediaActivity
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
@ -30,6 +32,7 @@ import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.qa.editor.*
|
||||
import com.gh.gamecenter.feature.entity.AnswerEntity
|
||||
import com.gh.gamecenter.feature.entity.ArticleEntity
|
||||
import com.gh.gamecenter.feature.selector.ChooseType
|
||||
import com.gh.gamecenter.qa.entity.EditorInsertEntity
|
||||
import com.gh.gamecenter.video.poster.PosterEditActivity
|
||||
import com.gh.gamecenter.video.upload.UploadManager
|
||||
@ -502,7 +505,7 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> constructor(
|
||||
startActivityForResult(
|
||||
LocalMediaActivity.getIntent(
|
||||
this@BaseRichEditorActivity,
|
||||
LocalMediaActivity.ChooseType.VIDEO,
|
||||
ChooseType.VIDEO,
|
||||
maxChooseCount,
|
||||
if (mtaEventName() == "提问帖") "发提问帖" else "发帖子"
|
||||
), INSERT_MEDIA_VIDEO_CODE
|
||||
@ -531,7 +534,7 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> constructor(
|
||||
val maxChooseCount = if (imageCount + 10 <= MAX_IMAGE_COUNT) 10 else MAX_IMAGE_COUNT - imageCount
|
||||
val intent = LocalMediaActivity.getIntent(
|
||||
this@BaseRichEditorActivity,
|
||||
LocalMediaActivity.ChooseType.IMAGE,
|
||||
ChooseType.IMAGE,
|
||||
maxChooseCount,
|
||||
if (mtaEventName() == "提问帖") "发提问帖" else "发帖子"
|
||||
)
|
||||
|
||||
@ -20,7 +20,7 @@ import com.gh.gamecenter.core.runOnUiThread
|
||||
import com.gh.gamecenter.core.utils.MD5Utils
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.entity.ForumDetailEntity
|
||||
import com.gh.gamecenter.entity.LocalVideoEntity
|
||||
import com.gh.gamecenter.common.entity.LocalVideoEntity
|
||||
import com.gh.gamecenter.entity.QuoteCountEntity
|
||||
import com.gh.gamecenter.qa.BbsType
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
@ -39,8 +39,6 @@ import retrofit2.HttpException
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.collections.HashMap
|
||||
import kotlin.collections.LinkedHashMap
|
||||
import kotlin.collections.set
|
||||
|
||||
|
||||
@ -6,8 +6,8 @@ class DownloadChainBuilder {
|
||||
|
||||
private var processEndCallback: ((asVGame: Boolean, Any?) -> Unit)? = null
|
||||
|
||||
fun setProcessEndCallback(callback: (asVGame: Boolean, Any?) -> Unit): DownloadChainBuilder {
|
||||
processEndCallback = callback
|
||||
fun setProcessEndCallback(gameId: String, callback: (asVGame: Boolean, Any?) -> Unit): DownloadChainBuilder {
|
||||
processEndCallback = VaPluginDownloadWrapper(gameId = gameId, callback = callback) // 其他需要添加行为的装饰者可以一直包装A(B(C(callback))), 执行顺序 A->B->C->callback
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
package com.gh.common.chain
|
||||
|
||||
import com.gh.vspace.VHelper
|
||||
|
||||
class VaPluginDownloadWrapper(val gameId: String, val callback: (Boolean, Any?) -> Unit) : (Boolean, Any?) -> Unit {
|
||||
override fun invoke(asVGame: Boolean, any: Any?) {
|
||||
callback.invoke(asVGame, any)
|
||||
if (asVGame) {
|
||||
VHelper.initVaPlugin(gameId)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,6 +7,7 @@ import android.os.Build;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.gh.common.util.PackageHelper;
|
||||
@ -46,6 +47,7 @@ import org.json.JSONObject;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.Single;
|
||||
import io.reactivex.SingleSource;
|
||||
import io.reactivex.functions.Function;
|
||||
@ -78,10 +80,10 @@ public class Config {
|
||||
private static NewApiSettingsEntity.NightMode mNightModeSetting;
|
||||
private static SimulatorEntity mNewSimulatorEntity;
|
||||
private static VSetting mVSetting;
|
||||
private static VNewSetting mVNewSetting;
|
||||
private volatile static VNewSetting mVNewSetting;
|
||||
|
||||
private static AppEntity mNew32UpdateEntity;
|
||||
public static BehaviorSubject<VNewSetting> vNewSettingSubject = BehaviorSubject.create();
|
||||
private static BehaviorSubject<VNewSetting> vNewSettingSubject = BehaviorSubject.create();
|
||||
private static GameGuidePopupEntity mGameGuidePopupEntity;
|
||||
private static SharedPreferences mDefaultSharedPreferences;
|
||||
|
||||
@ -212,6 +214,16 @@ public class Config {
|
||||
return mVNewSetting;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static Observable<VNewSetting> getVNewSettingObservable() {
|
||||
if (mVNewSetting != null) {
|
||||
return Observable.just(mVNewSetting);
|
||||
} else {
|
||||
return vNewSettingSubject.hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public static AppEntity getNew32UpdateEntity() {
|
||||
return mNew32UpdateEntity;
|
||||
|
||||
@ -172,7 +172,7 @@ public class BindingAdapters {
|
||||
builder.addHandler(new OverseaDownloadHandler());
|
||||
builder.addHandler(new CheckDownloadHandler());
|
||||
|
||||
builder.setProcessEndCallback((asVGame, isSubscribe) -> {
|
||||
builder.setProcessEndCallback(gameEntity.getId(), (asVGame, isSubscribe) -> {
|
||||
download(v.getContext(),
|
||||
progressBar,
|
||||
gameEntity,
|
||||
@ -197,7 +197,7 @@ public class BindingAdapters {
|
||||
builder.addHandler(new GamePermissionHandler());
|
||||
builder.addHandler(new VersionNumberHandler());
|
||||
|
||||
builder.setProcessEndCallback((asVGame, isSubscribe) -> {
|
||||
builder.setProcessEndCallback(gameEntity.getId(), (asVGame, isSubscribe) -> {
|
||||
DownloadDialog.showDownloadDialog(
|
||||
v.getContext(),
|
||||
gameEntity,
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
package com.gh.common.prioritychain
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.FrameLayout
|
||||
import com.airbnb.lottie.LottieAnimationView
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.databinding.LayoutCommunityHomeVideoGuideBinding
|
||||
|
||||
class CommunityHomeGuideHandler(
|
||||
priority: Int,
|
||||
private val context: Context,
|
||||
private val decorView: FrameLayout?,
|
||||
private val videoLottie: LottieAnimationView?
|
||||
) : PriorityChainHandler(priority) {
|
||||
|
||||
init {
|
||||
updateStatus(STATUS_VALID)
|
||||
}
|
||||
|
||||
override fun onProcess(): Boolean {
|
||||
return if (SPUtils.getBoolean(Constants.SP_SHOW_COMMUNITY_HOME_VIDEO_GUIDE, true)) {
|
||||
showHomeVideoGuide(context, decorView, videoLottie)
|
||||
processNext()
|
||||
true
|
||||
} else {
|
||||
processNext()
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun showHomeVideoGuide(context: Context, decorView: FrameLayout?, videoLottie: LottieAnimationView?) {
|
||||
val guideLayoutBinding = LayoutCommunityHomeVideoGuideBinding.inflate(
|
||||
LayoutInflater.from(context),
|
||||
decorView,
|
||||
true
|
||||
)
|
||||
guideLayoutBinding.root.setOnClickListener { view ->
|
||||
decorView?.removeView(view)
|
||||
SPUtils.setBoolean(Constants.SP_SHOW_COMMUNITY_HOME_VIDEO_GUIDE, false)
|
||||
|
||||
videoLottie?.playAnimation()
|
||||
SPUtils.setLong(
|
||||
Constants.SP_COMMUNITY_HOME_VIDEO_LOTTIE_LAST_PLAY_TIME,
|
||||
System.currentTimeMillis()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.gh.common.prioritychain
|
||||
|
||||
import com.gh.gamecenter.home.video.ScrollCalculatorHelper
|
||||
|
||||
class VideoHandler(priority: Int, val scrollCalculatorHelper: ScrollCalculatorHelper): PriorityChainHandler(priority) {
|
||||
|
||||
init {
|
||||
updateStatus(STATUS_VALID)
|
||||
}
|
||||
|
||||
override fun onProcess(): Boolean {
|
||||
scrollCalculatorHelper.enableAndPlayIfValid()
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
@ -2,12 +2,15 @@ package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.util.EntranceUtils
|
||||
import com.gh.gamecenter.common.avoidcallback.Callback
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.IEntranceUtilsProvider
|
||||
import com.lightgame.utils.AppManager
|
||||
|
||||
@Route(path = RouteConsts.provider.entranceUtils, name = "EntranceUtils暴露服务")
|
||||
class EntranceUtilsProviderImpl : IEntranceUtilsProvider {
|
||||
@ -20,11 +23,16 @@ class EntranceUtilsProviderImpl : IEntranceUtilsProvider {
|
||||
}
|
||||
|
||||
override fun jumpActivityWithCallback(context: Context, bundle: Bundle, callback: () -> Unit) {
|
||||
EntranceUtils.jumpActivity(context, null, bundle, object : Callback {
|
||||
override fun onActivityResult(resultCode: Int, data: Intent?) {
|
||||
callback()
|
||||
}
|
||||
})
|
||||
if (context is FragmentActivity && !context.supportFragmentManager.isDestroyed) {
|
||||
EntranceUtils.jumpActivityCompat(context, bundle, null, object : Callback {
|
||||
override fun onActivityResult(resultCode: Int, data: Intent?) {
|
||||
callback()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
EntranceUtils.jumpActivityCompat(AppManager.getInstance().currentActivity(), bundle)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
|
||||
@ -74,7 +74,7 @@ public class CheckLoginUtils {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance);
|
||||
bundle.putString(EntranceConsts.KEY_TO, LoginActivity.class.getName());
|
||||
EntranceUtils.jumpActivity(context, nextToBundle, bundle, (resultCode, data) -> {
|
||||
EntranceUtils.jumpActivityCompat(context, bundle, nextToBundle, (resultCode, data) -> {
|
||||
if (isTriggerNextStep && listener != null && isLogin()) {
|
||||
listener.onLogin();
|
||||
}
|
||||
|
||||
@ -37,10 +37,10 @@ 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.minigame.MiniGameItemHelper
|
||||
import com.gh.gamecenter.feature.view.DownloadButton
|
||||
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment
|
||||
import com.gh.gamecenter.manager.PackagesManager
|
||||
import com.gh.gamecenter.feature.minigame.MiniGameItemHelper
|
||||
import com.gh.gamecenter.teenagermode.TeenagerModeActivity
|
||||
import com.gh.vspace.VHelper
|
||||
import com.lightgame.download.DownloadConfig
|
||||
@ -697,7 +697,7 @@ object DownloadItemUtils {
|
||||
// 为 downloadButton 添加游戏实体,供点击的时候上报用
|
||||
downloadBtn.putObject(gameEntity)
|
||||
|
||||
val gamePermissionDialogFragment = (context as AppCompatActivity).supportFragmentManager.findFragmentByTag(
|
||||
val gamePermissionDialogFragment = (context as? AppCompatActivity)?.supportFragmentManager?.findFragmentByTag(
|
||||
GamePermissionDialogFragment::class.java.name
|
||||
) as GamePermissionDialogFragment?
|
||||
gamePermissionDialogFragment?.dismissAllowingStateLoss()
|
||||
@ -910,7 +910,7 @@ object DownloadItemUtils {
|
||||
addHandler(CheckStoragePermissionHandler())
|
||||
addHandler(VersionNumberHandler())
|
||||
}
|
||||
.setProcessEndCallback { _, _ ->
|
||||
.setProcessEndCallback(gameEntity.id) { _, _ ->
|
||||
DownloadDialog.showDownloadDialog(view.context, gameEntity, traceEvent, entrance, location)
|
||||
}
|
||||
.buildHandlerChain()
|
||||
@ -953,7 +953,7 @@ object DownloadItemUtils {
|
||||
addHandler(LandPageAddressHandler())
|
||||
addHandler(CheckDownloadHandler())
|
||||
}
|
||||
.setProcessEndCallback { asVGame, isSubscribe ->
|
||||
.setProcessEndCallback(gameEntity.id) { asVGame, isSubscribe ->
|
||||
download(context, gameEntity, downloadBtn, entrance, location, asVGame, isSubscribe as Boolean, traceEvent)
|
||||
}
|
||||
.buildHandlerChain()
|
||||
@ -972,7 +972,7 @@ object DownloadItemUtils {
|
||||
addHandler(OverseaDownloadHandler())
|
||||
addHandler(CheckDownloadHandler())
|
||||
}
|
||||
.setProcessEndCallback { asVGame, isSubscribe ->
|
||||
.setProcessEndCallback(gameEntity.id) { asVGame, isSubscribe ->
|
||||
download(context, gameEntity, downloadBtn, entrance, location, asVGame, isSubscribe as Boolean, traceEvent)
|
||||
}
|
||||
.buildHandlerChain()
|
||||
@ -991,7 +991,7 @@ object DownloadItemUtils {
|
||||
addHandler(ValidateVSpaceHandler())
|
||||
addHandler(CheckDownloadHandler())
|
||||
}
|
||||
.setProcessEndCallback { asVGame, isSubscribe ->
|
||||
.setProcessEndCallback(gameEntity.id) { asVGame, isSubscribe ->
|
||||
download(context, gameEntity, downloadBtn, entrance, location, asVGame, isSubscribe as Boolean, traceEvent)
|
||||
}
|
||||
.buildHandlerChain()
|
||||
@ -1004,7 +1004,7 @@ object DownloadItemUtils {
|
||||
addHandler(DownloadDialogHelperHandler())
|
||||
addHandler(CheckDownloadHandler())
|
||||
}
|
||||
.setProcessEndCallback { _, isSubscribe ->
|
||||
.setProcessEndCallback(gameEntity.id) { _, isSubscribe ->
|
||||
plugin(context, gameEntity, downloadBtn, entrance, location, isSubscribe as Boolean, traceEvent)
|
||||
}
|
||||
.buildHandlerChain()
|
||||
@ -1089,7 +1089,7 @@ object DownloadItemUtils {
|
||||
DownloadChainBuilder()
|
||||
.apply {
|
||||
addHandler(LandPageAddressHandler())
|
||||
}.setProcessEndCallback { asVGame, _ ->
|
||||
}.setProcessEndCallback(gameEntity.id) { asVGame, _ ->
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk) {
|
||||
DialogUtils.checkDownload(
|
||||
context,
|
||||
|
||||
@ -69,11 +69,13 @@ object DownloadObserver {
|
||||
DownloadDataHelper.uploadDownloadEvent(downloadEntity)
|
||||
}
|
||||
|
||||
if (DownloadStatus.hijack == downloadEntity.status) {
|
||||
val status = downloadEntity.status
|
||||
|
||||
if (DownloadStatus.hijack == status) {
|
||||
// 链接被劫持
|
||||
processHijack(downloadEntity)
|
||||
return
|
||||
} else if (DownloadStatus.notfound == downloadEntity.status) {
|
||||
} else if (DownloadStatus.notfound == status) {
|
||||
// 404 Not Found
|
||||
// 删除任务
|
||||
downloadEntity.status = DownloadStatus.cancel
|
||||
@ -127,10 +129,9 @@ object DownloadObserver {
|
||||
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
|
||||
)
|
||||
return
|
||||
} else if (DownloadStatus.neterror == downloadEntity.status
|
||||
|| DownloadStatus.timeout == downloadEntity.status
|
||||
|| DownloadStatus.diskioerror == downloadEntity.status
|
||||
|| DownloadStatus.diskisfull == downloadEntity.status
|
||||
} else if (DownloadStatus.neterror == status
|
||||
|| DownloadStatus.diskioerror == status
|
||||
|| DownloadStatus.timeout == status
|
||||
) {
|
||||
if (mRetryableHashMap[downloadEntity.url] == true
|
||||
&& NetworkUtils.isWifiConnected(HaloApp.getInstance().application)
|
||||
@ -139,9 +140,7 @@ object DownloadObserver {
|
||||
mRetryableHashMap[downloadEntity.url] = false
|
||||
Utils.log(TAG, "下载重试->" + downloadEntity.toJson())
|
||||
} else {
|
||||
if (DownloadStatus.diskisfull == downloadEntity.status) {
|
||||
ToastUtils.toast("磁盘已满,请清理空间后重试下载")
|
||||
} else if (DownloadStatus.diskioerror == downloadEntity.status) {
|
||||
if (DownloadStatus.diskioerror == status) {
|
||||
ToastUtils.toast("磁盘 IO 异常,请稍后重试")
|
||||
} else {
|
||||
ToastUtils.toast("网络不稳定,下载任务已暂停")
|
||||
@ -150,17 +149,21 @@ object DownloadObserver {
|
||||
DataLogUtils.uploadNeterrorLog(mApplication, downloadEntity)
|
||||
Utils.log(TAG, "下载自动暂停->" + downloadEntity.toJson())
|
||||
}
|
||||
} else if (DownloadStatus.redirected == downloadEntity.status) {
|
||||
} else if (DownloadStatus.diskisfull == status) {
|
||||
ToastUtils.toast("磁盘已满,请清理空间后重试下载")
|
||||
|
||||
downloadManager.pause(downloadEntity.url)
|
||||
} else if (DownloadStatus.redirected == status) {
|
||||
Utils.log(TAG, "重定向完毕")
|
||||
DownloadDataHelper.uploadRedirectEvent(downloadEntity)
|
||||
} else if (DownloadStatus.unqualified == downloadEntity.status) {
|
||||
} else if (DownloadStatus.unqualified == status) {
|
||||
// 未成年
|
||||
RealNameHelper.showRealNameUnqualifiedDialog(downloadEntity)
|
||||
|
||||
// 删除任务
|
||||
downloadEntity.status = DownloadStatus.cancel
|
||||
downloadManager.cancel(downloadEntity.url)
|
||||
} else if (DownloadStatus.unavailable == downloadEntity.status) {
|
||||
} else if (DownloadStatus.unavailable == status) {
|
||||
// 未接入防沉迷系统
|
||||
val currentActivity = AppManager.getInstance().currentActivity()
|
||||
|
||||
@ -179,7 +182,7 @@ object DownloadObserver {
|
||||
// 删除任务
|
||||
downloadEntity.status = DownloadStatus.cancel
|
||||
downloadManager.cancel(downloadEntity.url)
|
||||
} else if (DownloadStatus.isCertificating == downloadEntity.status) {
|
||||
} else if (DownloadStatus.isCertificating == status) {
|
||||
// 未接入防沉迷系统
|
||||
val currentActivity = AppManager.getInstance().currentActivity()
|
||||
|
||||
@ -207,21 +210,21 @@ object DownloadObserver {
|
||||
// 删除任务
|
||||
downloadEntity.status = DownloadStatus.cancel
|
||||
downloadManager.cancel(downloadEntity.url)
|
||||
} else if (DownloadStatus.uncertificated == downloadEntity.status) {
|
||||
} else if (DownloadStatus.uncertificated == status) {
|
||||
// 未实名
|
||||
RealNameHelper.showRealNameUncertificatedDialog(downloadEntity)
|
||||
|
||||
// 删除任务
|
||||
downloadEntity.status = DownloadStatus.cancel
|
||||
downloadManager.cancel(downloadEntity.url)
|
||||
} else if (DownloadStatus.banned == downloadEntity.status) {
|
||||
} else if (DownloadStatus.banned == status) {
|
||||
ToastUtils.showToast("网络异常")
|
||||
// 删除任务
|
||||
downloadEntity.status = DownloadStatus.cancel
|
||||
downloadManager.cancel(downloadEntity.url)
|
||||
}
|
||||
|
||||
if (DownloadStatus.done == downloadEntity.status) {
|
||||
if (DownloadStatus.done == status) {
|
||||
if (mDoneDebouncePair?.first != downloadEntity.url) {
|
||||
mDoneDebouncePair = Pair(downloadEntity.url, System.currentTimeMillis())
|
||||
performDownloadCompleteAction(downloadEntity, downloadManager)
|
||||
@ -241,7 +244,7 @@ object DownloadObserver {
|
||||
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
|
||||
|
||||
// 如果已下载大小发生变化,表示成功恢复下载,则重置重试标记
|
||||
if (downloadEntity.status == DownloadStatus.downloading) {
|
||||
if (status == DownloadStatus.downloading) {
|
||||
mRetryableHashMap[downloadEntity.url] = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +27,6 @@ import com.gh.gamecenter.core.utils.ClassUtils;
|
||||
import com.gh.gamecenter.core.utils.GsonUtils;
|
||||
import com.gh.gamecenter.core.utils.SPUtils;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.utils.AppManager;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import org.json.JSONException;
|
||||
@ -38,7 +37,18 @@ import java.util.Set;
|
||||
|
||||
public class EntranceUtils {
|
||||
|
||||
public static void jumpActivity(Context context, Bundle bundle) {
|
||||
jumpActivityCompat(context, bundle, null, null);
|
||||
}
|
||||
|
||||
public static void jumpActivityCompat(Context context, Bundle bundle) {
|
||||
jumpActivityCompat(context, bundle, null,null);
|
||||
}
|
||||
|
||||
public static void jumpActivityCompat(Context context,
|
||||
Bundle bundle,
|
||||
@Nullable Bundle nextToBundle,
|
||||
@Nullable Callback callback) {
|
||||
bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);
|
||||
|
||||
if (HaloApp.getInstance().isRunningForeground || HaloApp.getInstance().isAlreadyUpAndRunning) {
|
||||
@ -48,66 +58,27 @@ public class EntranceUtils {
|
||||
if (clazz == null) clazz = MainActivity.class;
|
||||
if (ToolbarFragment.class.isAssignableFrom(clazz)) { // 兼容ToolbarFragment
|
||||
ToolBarActivity.startFragmentNewTask(context, (Class<? extends ToolbarFragment>) clazz, bundle);
|
||||
} else {
|
||||
Intent intent1 = new Intent(context, clazz);
|
||||
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
// 如果 activity 名称有 singleton 的就添加 reorder_to_front 标签 (有点粗暴有点蠢,但暂时就先这样吧 :C )
|
||||
if (clazz.getSimpleName().toLowerCase().contains("singleton")) {
|
||||
intent1.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||
}
|
||||
intent1.putExtras(bundle);
|
||||
context.startActivity(intent1);
|
||||
}
|
||||
} else {
|
||||
// 应用未在运行
|
||||
context.startActivity(SplashScreenActivity.getSplashScreenIntent(context, bundle));
|
||||
}
|
||||
}
|
||||
|
||||
public static void jumpActivity(Context context, Bundle bundle) {
|
||||
bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);
|
||||
|
||||
if (AppManager.getInstance().findActivity(MainActivity.class) != null) {
|
||||
// 应用正在运行,前台或后台,且MainActivity在栈中
|
||||
String to = bundle.getString(KEY_TO);
|
||||
Class<?> clazz = ClassUtils.forName(to);
|
||||
if (clazz == null) clazz = MainActivity.class;
|
||||
if (ToolbarFragment.class.isAssignableFrom(clazz)) { // 兼容ToolbarFragment
|
||||
ToolBarActivity.startFragmentNewTask(context, (Class<? extends ToolbarFragment>) clazz, bundle);
|
||||
} else {
|
||||
Intent intent1 = new Intent(context, clazz);
|
||||
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
// 如果 activity 名称有 singleton 的就添加 reorder_to_front 标签 (有点粗暴有点蠢,但暂时就先这样吧 :C )
|
||||
if (clazz.getSimpleName().toLowerCase().contains("singleton")) {
|
||||
intent1.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||
}
|
||||
intent1.putExtras(bundle);
|
||||
context.startActivity(intent1);
|
||||
}
|
||||
} else {
|
||||
// 应用未在运行
|
||||
context.startActivity(SplashScreenActivity.getSplashScreenIntent(context, bundle));
|
||||
}
|
||||
}
|
||||
|
||||
public static void jumpActivity(Context context, Bundle nextToBundle, Bundle bundle, Callback callback) {
|
||||
bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);
|
||||
|
||||
if (AppManager.getInstance().findActivity(MainActivity.class) != null) {
|
||||
// 应用正在运行,前台或后台,且MainActivity在栈中
|
||||
String to = bundle.getString(KEY_TO);
|
||||
Class<?> clazz = ClassUtils.forName(to);
|
||||
if (clazz == null) clazz = MainActivity.class;
|
||||
if (ToolbarFragment.class.isAssignableFrom(clazz)) { // 兼容ToolbarFragment
|
||||
ToolBarActivity.startFragmentNewTask(context, (Class<? extends ToolbarFragment>) clazz, bundle);
|
||||
} else {
|
||||
} else if (callback != null ) {
|
||||
Intent intent1 = new Intent(context, clazz);
|
||||
//TODO:添加FLAG_ACTIVITY_NEW_TASK会导致一跳转页面callback就被调用
|
||||
//intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent1.putExtras(bundle);
|
||||
|
||||
AvoidOnResultManager.Companion.getInstance((AppCompatActivity) context)
|
||||
.startForResult(intent1, callback);
|
||||
if (context instanceof AppCompatActivity) {
|
||||
AvoidOnResultManager.Companion.getInstance((AppCompatActivity) context)
|
||||
.startForResult(intent1, callback);
|
||||
} else {
|
||||
// 不要回调,正常跳转
|
||||
context.startActivity(intent1);
|
||||
}
|
||||
} else {
|
||||
Intent intent1 = new Intent(context, clazz);
|
||||
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
// 如果 activity 名称有 singleton 的就添加 reorder_to_front 标签 (有点粗暴有点蠢,但暂时就先这样吧 :C )
|
||||
if (clazz.getSimpleName().toLowerCase().contains("singleton")) {
|
||||
intent1.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||
}
|
||||
intent1.putExtras(bundle);
|
||||
context.startActivity(intent1);
|
||||
}
|
||||
} else {
|
||||
// 应用未在运行
|
||||
|
||||
@ -7,6 +7,7 @@ import com.gh.gamecenter.common.utils.toObject
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.SubjectEntity
|
||||
import com.gh.gamecenter.common.retrofit.Response
|
||||
import com.gh.gamecenter.manager.PackagesManager
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
@ -111,6 +112,14 @@ object GameSubstituteRepositoryHelper {
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否已安装该游戏 id
|
||||
if (PackagesManager.getInstalledDataByGameId(game.id) != null) {
|
||||
// 将该位置的游戏标记为需要替换
|
||||
positionOfGameToBeReplacedList.add(index)
|
||||
thisPositionNeedToBeReplaced = true
|
||||
break
|
||||
}
|
||||
|
||||
// 若此游戏所包含的 apk 没有已安装,那么再检查是否已安装有预设相关包名
|
||||
if (!thisPositionNeedToBeReplaced) {
|
||||
var relatedPackageList = arrayListOf<String>()
|
||||
|
||||
@ -308,7 +308,7 @@ object GameUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否以畅玩游戏的形式来处理
|
||||
* 是否默认以畅玩游戏的形式来处理
|
||||
*/
|
||||
@JvmStatic
|
||||
fun shouldPerformAsVGame(gameEntity: GameEntity): Boolean {
|
||||
|
||||
@ -30,6 +30,9 @@ object NewFlatLogUtils {
|
||||
private const val EVENT_LOGIN_FROM_GHZS_SHOW = "halo_fun_login_from_ghzs_show"
|
||||
private const val EVENT_LOGIN_FROM_GHZS_CLICK = "halo_fun_login_from_ghzs_click"
|
||||
|
||||
private const val EVENT_INSTALLED_LAUNCH_DIALOG_SHOW = "halo_fun_installed_launch_dialog_show"
|
||||
private const val EVENT_INSTALLED_LAUNCH_DIALOG_CLICK = "halo_fun_installed_launch_dialog_click"
|
||||
|
||||
private fun log(jsonObject: JSONObject, logStore: String = "event", uploadImmediately: Boolean = false) {
|
||||
Utils.log("NewFlatLogUtils", jsonObject.toString(4))
|
||||
LoghubUtils.log(jsonObject, logStore, uploadImmediately, true)
|
||||
@ -550,6 +553,8 @@ object NewFlatLogUtils {
|
||||
// 搜索-点击搜索榜单内容
|
||||
@JvmStatic
|
||||
fun logSearchClickRankDetail(
|
||||
key: String,
|
||||
rankType: String,
|
||||
rankName: String,
|
||||
rankSequence: String,
|
||||
linkId: String,
|
||||
@ -558,6 +563,8 @@ object NewFlatLogUtils {
|
||||
) {
|
||||
val json = json {
|
||||
KEY_EVENT to "search_click_rank_detail"
|
||||
"key" to key
|
||||
"rank_type" to rankType
|
||||
"rank_name" to rankName
|
||||
"rank_sequence" to rankSequence
|
||||
"link_id" to linkId
|
||||
@ -2688,4 +2695,73 @@ object NewFlatLogUtils {
|
||||
parseAndPutMeta()(this)
|
||||
}.let(::log)
|
||||
}
|
||||
|
||||
fun logHaloFunInstalledLaunchDialogShow() {
|
||||
json {
|
||||
KEY_EVENT to EVENT_INSTALLED_LAUNCH_DIALOG_SHOW
|
||||
parseAndPutMeta()(this)
|
||||
}.let(::log)
|
||||
}
|
||||
|
||||
fun logHaloFunInstalledLaunchDialogClick(
|
||||
gameId: String,
|
||||
gameName: String,
|
||||
buttonType: String
|
||||
) {
|
||||
json {
|
||||
KEY_EVENT to EVENT_INSTALLED_LAUNCH_DIALOG_CLICK
|
||||
"game_id" to gameId
|
||||
"game_name" to gameName
|
||||
"button_type" to buttonType
|
||||
parseAndPutMeta()(this)
|
||||
}.let(::log)
|
||||
}
|
||||
|
||||
// 用户访问分流器
|
||||
fun logByPassBrowsing(
|
||||
source: String,
|
||||
bypassName: String,
|
||||
bypassId: String,
|
||||
branchId: String,
|
||||
branchName: String,
|
||||
inProcessTime: Int,
|
||||
bypassVisitTime: Int,
|
||||
linkType: String,
|
||||
linkId: String,
|
||||
linkText: String,
|
||||
bypassStatus: Int
|
||||
) {
|
||||
json {
|
||||
KEY_EVENT to "BypassBrowsing"
|
||||
"source" to source
|
||||
"bypass_name" to bypassName
|
||||
"bypass_id" to bypassId
|
||||
"branch_id" to branchId
|
||||
"branch_name" to branchName
|
||||
"inprocess_time" to inProcessTime
|
||||
"bypass_visit_time" to bypassVisitTime
|
||||
"link_type" to linkType
|
||||
"link_id" to linkId
|
||||
"link_text" to linkText
|
||||
"bypass_status" to bypassStatus
|
||||
parseAndPutMeta()(this)
|
||||
}.let(::log)
|
||||
}
|
||||
|
||||
// 分流失败
|
||||
fun logFailByPass(
|
||||
source: String,
|
||||
bypassName: String,
|
||||
bypassId: String,
|
||||
defeatedReason: String
|
||||
) {
|
||||
json {
|
||||
KEY_EVENT to "FailBypass"
|
||||
"source" to source
|
||||
"bypass_name" to bypassName
|
||||
"bypass_id" to bypassId
|
||||
"defeated_reason" to defeatedReason
|
||||
parseAndPutMeta()(this)
|
||||
}.let(::log)
|
||||
}
|
||||
}
|
||||
@ -90,7 +90,7 @@ object PackageChangeHelper : DefaultLifecycleObserver {
|
||||
pendingPackageTriple = null
|
||||
pendingGhId = null
|
||||
|
||||
PackageRepository.addInstalledGame(packageName)
|
||||
PackageRepository.addInstalledGame(PackageRepository.packageFilterManager, packageName)
|
||||
|
||||
// 添加到额外的包名白名单,下次启动同时查询此包的安装情况
|
||||
PackageHelper.updateAdditionalWhiteListPackageName(packageName = packageName, isAdd = true)
|
||||
|
||||
@ -81,23 +81,28 @@ object PackageHelper {
|
||||
|
||||
// 评论黑名单包名列表,避免用户安装了 Xposed Installer 这样的工具,也能在包含该安装包的游戏详情页评论
|
||||
private var _commentPackageNameBlackList = arrayListOf<String>()
|
||||
val commentPackageNameBlackList: ArrayList<String> = _commentPackageNameBlackList
|
||||
val commentPackageNameBlackList: ArrayList<String>
|
||||
get() = _commentPackageNameBlackList
|
||||
|
||||
// 关闭下载的包列表
|
||||
private var _downloadPackageNameBlackList = arrayListOf<String>()
|
||||
val downloadPackageNameBlackList: ArrayList<String> = _downloadPackageNameBlackList
|
||||
val downloadPackageNameBlackList: ArrayList<String>
|
||||
get() = _downloadPackageNameBlackList
|
||||
|
||||
// 本地已安装的包去掉关闭下载的包后的列表
|
||||
private var _validLocalPackageNameSet = hashSetOf<String>()
|
||||
val validLocalPackageNameSet: HashSet<String> = _validLocalPackageNameSet
|
||||
val validLocalPackageNameSet: HashSet<String>
|
||||
get() = _validLocalPackageNameSet
|
||||
|
||||
// 游戏包名匹配列表
|
||||
private var _relatedPackageList = arrayListOf<SettingsEntity.GameWithPackages>()
|
||||
val relatedPackageList: ArrayList<SettingsEntity.GameWithPackages> = _relatedPackageList
|
||||
val relatedPackageList: ArrayList<SettingsEntity.GameWithPackages>
|
||||
get() = _relatedPackageList
|
||||
|
||||
// 接口控制的已安装应用列表获取开关状态 (UI 显示)
|
||||
private var _installedPackageApiSwitchStatusLiveData = MutableLiveData<Boolean>()
|
||||
val installedPackageApiSwitchStatusLiveData: LiveData<Boolean> = _installedPackageApiSwitchStatusLiveData
|
||||
val installedPackageApiSwitchStatusLiveData: LiveData<Boolean>
|
||||
get() = _installedPackageApiSwitchStatusLiveData
|
||||
|
||||
// 本地已安装包的列表
|
||||
var localPackageNameSet = hashSetOf<String>()
|
||||
@ -541,6 +546,7 @@ object PackageHelper {
|
||||
Utils.log(TAG, "addInstalledButMissingPackages 需要请求接口获取的包数量为 ${installedPackageNameSet.size}")
|
||||
|
||||
PackageRepository.addInstalledGames(
|
||||
packageFilterManager = PackageRepository.packageFilterManager,
|
||||
pkgNameList = ArrayList(installedPackageNameSet),
|
||||
updateInstallStatus = true
|
||||
)
|
||||
|
||||
@ -14,6 +14,7 @@ import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AndroidException;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@ -222,8 +223,19 @@ public class PackageUtils {
|
||||
if (metaDate != null) {
|
||||
return metaDate.get(name);
|
||||
}
|
||||
} catch (NameNotFoundException e) {
|
||||
// e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
if (e instanceof AndroidException) {
|
||||
// 有些设备会出现 DeadSystemException
|
||||
SentryHelper.INSTANCE.onEvent(
|
||||
"GET_META_DATA_ERROR",
|
||||
"packageName",
|
||||
packageName,
|
||||
"exception_digest",
|
||||
e.getLocalizedMessage()
|
||||
);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -627,8 +639,19 @@ public class PackageUtils {
|
||||
try {
|
||||
return HaloApp.getInstance().getApplication().getPackageManager().getPackageInfo(packageName,
|
||||
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT).versionName;
|
||||
} catch (NameNotFoundException e) {
|
||||
// do nothing
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
if (e instanceof AndroidException) {
|
||||
// 有些设备会出现 DeadSystemException
|
||||
SentryHelper.INSTANCE.onEvent(
|
||||
"GET_VERSION_NAME_ERROR",
|
||||
"packageName",
|
||||
packageName,
|
||||
"exception_digest",
|
||||
e.getLocalizedMessage()
|
||||
);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -640,8 +663,18 @@ public class PackageUtils {
|
||||
try {
|
||||
return HaloApp.getInstance().getApplication().getPackageManager().getPackageInfo(packageName,
|
||||
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT).versionCode;
|
||||
} catch (NameNotFoundException e) {
|
||||
// do nothing
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (e instanceof AndroidException) {
|
||||
// 有些设备会出现 DeadSystemException
|
||||
SentryHelper.INSTANCE.onEvent(
|
||||
"GET_VERSION_CODE_ERROR",
|
||||
"packageName",
|
||||
packageName,
|
||||
"exception_digest",
|
||||
e.getLocalizedMessage()
|
||||
);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -654,8 +687,18 @@ public class PackageUtils {
|
||||
try {
|
||||
PackageManager packageManager = context.getApplicationContext().getPackageManager();
|
||||
return packageManager.getApplicationIcon(packageName);
|
||||
} catch (NameNotFoundException e) {
|
||||
// do nothing
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (e instanceof AndroidException) {
|
||||
// 有些设备会出现 DeadSystemException
|
||||
SentryHelper.INSTANCE.onEvent(
|
||||
"GET_ICON_ERROR",
|
||||
"packageName",
|
||||
packageName,
|
||||
"exception_digest",
|
||||
e.getLocalizedMessage()
|
||||
);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -706,8 +749,19 @@ public class PackageUtils {
|
||||
jsonObject.put("version", packageInfo.versionName);
|
||||
}
|
||||
return jsonObject;
|
||||
} catch (JSONException | NameNotFoundException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (e instanceof AndroidException) {
|
||||
// 有些设备会出现 DeadSystemException
|
||||
SentryHelper.INSTANCE.onEvent(
|
||||
"GET_APP_BASIC_INFO_BY_PACKAGE_NAME",
|
||||
"packageName",
|
||||
packageName,
|
||||
"exception_digest",
|
||||
e.getLocalizedMessage()
|
||||
);
|
||||
}
|
||||
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,6 +82,7 @@ object ViewPagerFragmentHelper {
|
||||
const val TYPE_TOOLKIT = "toolkit" // 工具箱
|
||||
|
||||
fun createFragment(parentFragment: Fragment?, bundle: Bundle, linkEntity: LinkEntity, isTabWrapper: Boolean): Fragment {
|
||||
val superiorChain = if (parentFragment is ISuperiorChain) parentFragment else null
|
||||
return when (linkEntity.type) {
|
||||
// 游戏详情页
|
||||
TYPE_GAME -> {
|
||||
@ -90,11 +91,12 @@ object ViewPagerFragmentHelper {
|
||||
}
|
||||
// 我的光环
|
||||
TYPE_MY_HALO -> {
|
||||
val superiorChain = if (parentFragment is ISuperiorChain) parentFragment else null
|
||||
HaloPersonalFragment().setSuperiorChain(superiorChain).with(bundle)
|
||||
}
|
||||
// 社区首页
|
||||
TYPE_COMMUNITY_HOME -> CommunityHomeFragment().with(bundle)
|
||||
TYPE_COMMUNITY_HOME -> {
|
||||
CommunityHomeFragment().setSuperiorChain(superiorChain).with(bundle)
|
||||
}
|
||||
// 视频信息流
|
||||
TYPE_VIDEO_STREAM -> {
|
||||
bundle.putBoolean(EntranceConsts.KEY_IS_HOME_VIDEO, true)
|
||||
@ -148,11 +150,11 @@ object ViewPagerFragmentHelper {
|
||||
NewQuestionDetailFragment().with(bundle)
|
||||
}
|
||||
// 其他原来带Toolbar的Fragment
|
||||
else -> createToolbarWrapperFragment(bundle, linkEntity, isTabWrapper)
|
||||
else -> createToolbarWrapperFragment(parentFragment, bundle, linkEntity, isTabWrapper)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createToolbarWrapperFragment(bundle: Bundle, entity: LinkEntity, isTabWrapper: Boolean): Fragment {
|
||||
private fun createToolbarWrapperFragment(parentFragment: Fragment?, bundle: Bundle, entity: LinkEntity, isTabWrapper: Boolean): Fragment {
|
||||
var className = ReloadFragment::class.java.name
|
||||
|
||||
when (entity.type) {
|
||||
|
||||
@ -59,8 +59,8 @@ class GameDetailActivity : DownloadToolbarActivity() {
|
||||
}
|
||||
|
||||
override fun getBusinessId(): Pair<String, String> {
|
||||
val fragment = targetFragment as GameDetailFragment
|
||||
return if (fragment.arguments != null) {
|
||||
val fragment = targetFragment as? GameDetailFragment?
|
||||
return if (fragment?.arguments != null) {
|
||||
Pair(fragment.requireArguments().getString(EntranceConsts.KEY_GAMEID) ?: "", "")
|
||||
} else {
|
||||
super.getBusinessId()
|
||||
|
||||
@ -48,6 +48,7 @@ import com.gh.gamecenter.common.entity.SensorsEvent
|
||||
import com.gh.gamecenter.common.retrofit.Response
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.common.utils.ImageUtils.getIdealImageUrl
|
||||
import com.gh.gamecenter.common.view.DragListener
|
||||
import com.gh.gamecenter.common.view.DraggableBigImageView
|
||||
import com.gh.gamecenter.common.view.Gh_RelativeLayout
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
@ -815,18 +816,18 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
if (mBigImageView == null) {
|
||||
mBigImageView = imageView
|
||||
}
|
||||
imageView.setDragListener(object : DraggableBigImageView.DragListener {
|
||||
override fun onRelease(draggableBigImageView: DraggableBigImageView, scale: Float) {
|
||||
imageView.setDragListener(object : DragListener {
|
||||
override fun onRelease(scale: Float) {
|
||||
updateOriginPosition(mViewPager.currentItem)
|
||||
performExitAnimation(draggableBigImageView, scale, isFadeOnly())
|
||||
performExitAnimation(imageView, scale, isFadeOnly())
|
||||
}
|
||||
|
||||
override fun onDrag(draggableBigImageView: DraggableBigImageView, fraction: Float) {
|
||||
override fun onDrag(fraction: Float) {
|
||||
mBackgroundView.alpha = 1 - fraction
|
||||
mIndicatorMask.visibility = View.GONE
|
||||
}
|
||||
|
||||
override fun onRestore(draggableBigImageView: DraggableBigImageView, fraction: Float) {
|
||||
override fun onRestore(fraction: Float) {
|
||||
mBackgroundView.alpha = 1F
|
||||
// mIndicatorMask.goneIf(mUrlList?.size == 1)
|
||||
if (mUrlList?.size != 1 || mAnswerEntity != null) {
|
||||
|
||||
@ -138,7 +138,6 @@ import io.reactivex.functions.Function;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.ResponseBody;
|
||||
import retrofit2.HttpException;
|
||||
@ -149,6 +148,8 @@ public class MainActivity extends BaseActivity {
|
||||
public static final String SHOW_AD = "show_ad";
|
||||
public static final int COUNTDOWN_AD = 100;
|
||||
private int mCountdownMaxCount = 3;
|
||||
public static final int COUNTDOWN_SDK_AD = 101;
|
||||
public static final int COUNTDOWN_SDK_MAX_COUNT = 5;
|
||||
private int mCountdownCount = 0;
|
||||
|
||||
private static final String CURRENT_PAGE = "current_page";
|
||||
@ -490,6 +491,7 @@ public class MainActivity extends BaseActivity {
|
||||
if (AdDelegateHelper.INSTANCE.shouldShowStartUpAd(false)) {
|
||||
ViewGroup startAdContainer = findViewById(R.id.startAdContainer);
|
||||
ViewGroup sdkStartAdContainer = findViewById(R.id.sdkStartAdContainer);
|
||||
TextView sdkJumpBtn = findViewById(R.id.sdkJumpBtn);
|
||||
FrameLayout adsFl = findViewById(R.id.adsFl);
|
||||
View icpContainer = findViewById(R.id.sdkStartAdIcpContainer);
|
||||
if (icpContainer != null) {
|
||||
@ -518,6 +520,7 @@ public class MainActivity extends BaseActivity {
|
||||
screenHeightInDp,
|
||||
startAdContainer,
|
||||
sdkStartAdContainer,
|
||||
sdkJumpBtn,
|
||||
adsFl,
|
||||
(BaseHandler) mBaseHandler,
|
||||
false,
|
||||
@ -537,13 +540,19 @@ public class MainActivity extends BaseActivity {
|
||||
@Override
|
||||
protected void handleMessage(Message msg) {
|
||||
super.handleMessage(msg);
|
||||
if (msg.what == COUNTDOWN_AD) {
|
||||
if (msg.what == COUNTDOWN_AD || msg.what == COUNTDOWN_SDK_AD) {
|
||||
mCountdownCount++;
|
||||
if (mCountdownMaxCount < mCountdownCount) {
|
||||
int maxCount;
|
||||
if (msg.what == COUNTDOWN_AD) {
|
||||
maxCount = mCountdownMaxCount;
|
||||
} else {
|
||||
maxCount = COUNTDOWN_SDK_MAX_COUNT;
|
||||
}
|
||||
if (maxCount < mCountdownCount) {
|
||||
AdDelegateHelper.INSTANCE.setShowingSplashAd(false);
|
||||
hideSplashAd();
|
||||
|
||||
if (msg.obj instanceof StartupAdEntity) {
|
||||
if (msg.what == COUNTDOWN_AD && msg.obj instanceof StartupAdEntity) {
|
||||
StartupAdEntity ad = (StartupAdEntity) msg.obj;
|
||||
LinkEntity linkEntity = ad.getJump();
|
||||
SensorsBridge.trackEvent(
|
||||
@ -556,14 +565,26 @@ public class MainActivity extends BaseActivity {
|
||||
linkEntity.getLink(),
|
||||
"link_text",
|
||||
linkEntity.getText());
|
||||
} else if (msg.what == COUNTDOWN_SDK_AD) {
|
||||
SPUtils.setLong(Constants.SP_LAST_SPLASH_AD_SHOW_TIME, System.currentTimeMillis());
|
||||
}
|
||||
} else {
|
||||
TextView jumpBtn = findViewById(R.id.jumpBtn);
|
||||
jumpBtn.setText(getString(R.string.splash_jump, mCountdownMaxCount - mCountdownCount));
|
||||
Message newMsg = Message.obtain();
|
||||
newMsg.what = COUNTDOWN_AD;
|
||||
newMsg.obj = msg.obj;
|
||||
mBaseHandler.sendMessageDelayed(newMsg, 1000);
|
||||
if (msg.what == COUNTDOWN_AD) {
|
||||
TextView jumpBtn = findViewById(R.id.jumpBtn);
|
||||
if (jumpBtn != null) {
|
||||
jumpBtn.setText(getString(R.string.splash_jump, maxCount - mCountdownCount));
|
||||
}
|
||||
Message newMsg = Message.obtain();
|
||||
newMsg.what = COUNTDOWN_AD;
|
||||
newMsg.obj = msg.obj;
|
||||
mBaseHandler.sendMessageDelayed(newMsg, 1000);
|
||||
} else {
|
||||
TextView jumpBtn = findViewById(R.id.sdkJumpBtn);
|
||||
if (jumpBtn != null) {
|
||||
jumpBtn.setText(getString(R.string.splash_jump, maxCount - mCountdownCount));
|
||||
}
|
||||
mBaseHandler.sendEmptyMessageDelayed(COUNTDOWN_SDK_AD, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -601,7 +622,11 @@ public class MainActivity extends BaseActivity {
|
||||
ExtensionsKt.removeFromParent(startSdkAdContainer, true);
|
||||
AdDelegateHelper.INSTANCE.cancelSplashAd(this);
|
||||
}
|
||||
|
||||
TextView jumpBtn = findViewById(R.id.sdkJumpBtn);
|
||||
if (jumpBtn != null) {
|
||||
jumpBtn.setVisibility(View.GONE);
|
||||
ExtensionsKt.removeFromParent(jumpBtn, true);
|
||||
}
|
||||
View startSdkAdIcpContainer = findViewById(R.id.sdkStartAdIcpContainer);
|
||||
if (startSdkAdIcpContainer != null) {
|
||||
startSdkAdIcpContainer.setVisibility(View.GONE);
|
||||
|
||||
@ -10,6 +10,8 @@ import android.view.inputmethod.EditorInfo
|
||||
import android.widget.*
|
||||
import androidx.core.widget.doAfterTextChanged
|
||||
import androidx.core.widget.doOnTextChanged
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.util.LogUtils
|
||||
import com.gh.gamecenter.DisplayType.*
|
||||
@ -118,7 +120,7 @@ open class SearchActivity : BaseActivity() {
|
||||
trackSearchPageShow()
|
||||
}
|
||||
|
||||
protected open fun trackSearchPageShow(){
|
||||
protected open fun trackSearchPageShow() {
|
||||
val bottomTab = intent.getStringExtra(EntranceConsts.KEY_BOTTOM_TAB_NAME) ?: ""
|
||||
val multiTabId = intent.getStringExtra(EntranceConsts.KEY_MULTI_TAB_NAV_ID) ?: ""
|
||||
val multiTabName = intent.getStringExtra(EntranceConsts.KEY_MULTI_TAB_NAV_NAME) ?: ""
|
||||
@ -179,10 +181,11 @@ open class SearchActivity : BaseActivity() {
|
||||
open fun search(type: SearchType, key: String?) {
|
||||
mSearchType = type
|
||||
mIsAutoSearchDisabled = true
|
||||
// 自动搜索,默认搜索,热门搜索,历史搜索,主动搜索
|
||||
// 自动搜索,默认搜索,热门搜索,历史搜索,主动搜索,榜单搜索
|
||||
when (type) {
|
||||
SearchType.AUTO -> handleAutoSearch(key)
|
||||
SearchType.DEFAULT -> handleDefaultSearch(key)
|
||||
SearchType.RANK -> handleRankSearch(key)
|
||||
SearchType.HOT -> handleHotSearch(key)
|
||||
SearchType.HISTORY -> handleHistorySearch(key)
|
||||
SearchType.MANUAL -> handleManualSearch()
|
||||
@ -213,6 +216,22 @@ open class SearchActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun handleRankSearch(key: String?) {
|
||||
mSearchKey = key
|
||||
searchEt.setText(key)
|
||||
searchEt.setSelection(searchEt.text.length)
|
||||
updateDisplayType(GAME_DETAIL)
|
||||
LogUtils.uploadSearchGame("searching", "搜索页", key, "榜单搜索")
|
||||
|
||||
SensorsBridge.trackSearchButtonClick(
|
||||
GlobalActivityManager.getCurrentPageEntity().pageId,
|
||||
GlobalActivityManager.getCurrentPageEntity().pageName,
|
||||
key ?: "",
|
||||
TRACK_SEARCH_TYPE_DEFAULT,
|
||||
mSourceEntrance
|
||||
)
|
||||
}
|
||||
|
||||
protected open fun handleDefaultSearch(key: String?) {
|
||||
mSearchKey = key
|
||||
searchEt.setText(key)
|
||||
@ -286,38 +305,72 @@ open class SearchActivity : BaseActivity() {
|
||||
protected open fun provideDao(): ISearchHistoryDao = SearchHistoryDao(this)
|
||||
|
||||
open fun updateDisplayType(type: DisplayType) {
|
||||
val transaction = supportFragmentManager.beginTransaction()
|
||||
when (type) {
|
||||
DEFAULT -> {
|
||||
val fragment = supportFragmentManager.findFragmentByTag(SearchDefaultFragment::class.java.name)
|
||||
?: SearchDefaultFragment().apply {
|
||||
arguments = Bundle().also { it.putBoolean(SearchDefaultFragment.KEY_IS_GAME_SEARCH, true) }
|
||||
}
|
||||
transaction.replace(R.id.search_result, fragment, SearchDefaultFragment::class.java.name)
|
||||
val transaction = when (type) {
|
||||
DEFAULT -> showFragment(
|
||||
SearchDefaultFragment::class.java.name,
|
||||
{ SearchDefaultFragment() }
|
||||
) {
|
||||
it.arguments = Bundle().also { bundle ->
|
||||
bundle.putBoolean(SearchDefaultFragment.KEY_IS_GAME_SEARCH, true)
|
||||
}
|
||||
}
|
||||
|
||||
GAME_DIGEST -> {
|
||||
val digestListFragment =
|
||||
supportFragmentManager.findFragmentByTag(SearchGameIndexFragment::class.java.name) as? SearchGameIndexFragment
|
||||
?: SearchGameIndexFragment()
|
||||
digestListFragment.setParams(mSearchKey ?: "", mSearchType.value)
|
||||
transaction.replace(R.id.search_result, digestListFragment, SearchGameIndexFragment::class.java.name)
|
||||
GAME_DIGEST -> showFragment(
|
||||
SearchGameIndexFragment::class.java.name,
|
||||
{ SearchGameIndexFragment() }
|
||||
) {
|
||||
removeFragment(SearchGameResultFragment::class.java.name)
|
||||
it.setParams(mSearchKey ?: "", mSearchType.value)
|
||||
}
|
||||
|
||||
GAME_DETAIL -> {
|
||||
val detailListFragment =
|
||||
supportFragmentManager.findFragmentByTag(SearchGameResultFragment::class.java.name) as? SearchGameResultFragment
|
||||
?: SearchGameResultFragment()
|
||||
detailListFragment.setParams(mSearchKey ?: "", mSearchType.value)
|
||||
transaction.replace(R.id.search_result, detailListFragment, SearchGameResultFragment::class.java.name)
|
||||
GAME_DETAIL -> showFragment(
|
||||
SearchGameResultFragment::class.java.name,
|
||||
{ SearchGameResultFragment() }
|
||||
) {
|
||||
removeFragment(SearchGameIndexFragment::class.java.name)
|
||||
it.setParams(mSearchKey ?: "", mSearchType.value)
|
||||
}
|
||||
|
||||
else -> {
|
||||
//do nothing
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
mDisplayType = type
|
||||
transaction.commitAllowingStateLoss()
|
||||
transaction?.let {
|
||||
mDisplayType = type
|
||||
it.commitAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
|
||||
protected fun <T : Fragment> showFragment(
|
||||
tag: String,
|
||||
onFragmentCreate: () -> T,
|
||||
onFragmentCreated: ((T) -> Unit)? = null,
|
||||
): FragmentTransaction {
|
||||
val transaction = supportFragmentManager.beginTransaction()
|
||||
var createNewFragment = false
|
||||
var fragment = supportFragmentManager
|
||||
.findFragmentByTag(tag)
|
||||
if (fragment == null) {
|
||||
createNewFragment = true
|
||||
fragment = onFragmentCreate.invoke()
|
||||
}
|
||||
onFragmentCreated?.invoke(fragment as T)
|
||||
if (createNewFragment) {
|
||||
transaction.add(R.id.search_result, fragment, tag)
|
||||
transaction.addToBackStack(null)
|
||||
} else if (!fragment.isAdded) {
|
||||
transaction.show(fragment)
|
||||
transaction.addToBackStack(null)
|
||||
}
|
||||
return transaction
|
||||
}
|
||||
|
||||
protected fun removeFragment(tag: String) {
|
||||
val fragment = supportFragmentManager
|
||||
.findFragmentByTag(tag) ?: return
|
||||
supportFragmentManager
|
||||
.beginTransaction()
|
||||
.remove(fragment)
|
||||
.commit()
|
||||
supportFragmentManager.popBackStack()
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
@ -325,6 +378,7 @@ open class SearchActivity : BaseActivity() {
|
||||
when (search.type) {
|
||||
SearchType.HISTORY.value -> search(SearchType.HISTORY, search.key)
|
||||
SearchType.HOT.value -> search(SearchType.HOT, search.key)
|
||||
SearchType.RANK.value -> search(SearchType.RANK, search.key)
|
||||
|
||||
"click" -> DataCollectionUtils.uploadSearchClick(
|
||||
this, mSearchKey, mSearchType.value, "搜索页面",
|
||||
@ -341,9 +395,8 @@ open class SearchActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
override fun handleBackPressed(): Boolean {
|
||||
val fragment = supportFragmentManager.findFragmentByTag(SearchDefaultFragment::class.java.name)
|
||||
if (fragment == null) {
|
||||
updateDisplayType(DEFAULT)
|
||||
if (supportFragmentManager.fragments.size == 1) {
|
||||
finish()
|
||||
return true
|
||||
}
|
||||
return super.handleBackPressed()
|
||||
@ -417,7 +470,8 @@ enum class SearchType(var value: String) {
|
||||
DEFAULT("default"),
|
||||
HISTORY("history"),
|
||||
MANUAL("initiative"),
|
||||
HOT("remen");
|
||||
HOT("remen"),
|
||||
RANK("rank");
|
||||
|
||||
fun toChinese() = when (this) {
|
||||
AUTO -> "自动搜索"
|
||||
@ -425,6 +479,7 @@ enum class SearchType(var value: String) {
|
||||
HISTORY -> "历史搜索"
|
||||
MANUAL -> "主动搜索"
|
||||
HOT -> "热门搜索"
|
||||
RANK -> "榜单搜索"
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@ -419,7 +419,7 @@ public class SkipActivity extends BaseActivity {
|
||||
} else {
|
||||
Bundle newBundle = new Bundle();
|
||||
newBundle.putString(EntranceConsts.KEY_TO, LoginActivity.class.getName());
|
||||
EntranceUtils.jumpActivity(this, null, newBundle, (resultCode, data) -> {
|
||||
EntranceUtils.jumpActivityCompat(this, newBundle, null, (resultCode, data) -> {
|
||||
if(CheckLoginUtils.isLogin()) {
|
||||
VHelper.INSTANCE.updateAuthorizeInfo(true);
|
||||
}
|
||||
@ -442,7 +442,7 @@ public class SkipActivity extends BaseActivity {
|
||||
break;
|
||||
default:
|
||||
EntranceUtils.jumpActivity(this, new Bundle()); // 跳转至首页
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if ("market".equals(uri.getScheme())) {
|
||||
|
||||
@ -12,8 +12,10 @@ import com.gh.ad.AdDelegateHelper
|
||||
import com.gh.ad.AdDelegateHelper.requestSplashAd
|
||||
import com.gh.ad.AdDelegateHelper.shouldShowStartUpAd
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
@ -37,6 +39,7 @@ class SplashAdActivity : BaseActivity() {
|
||||
if (shouldShowStartUpAd(true)) {
|
||||
val startAdContainer = findViewById<ViewGroup>(R.id.startAdContainer)
|
||||
val sdkStartAdContainer = findViewById<ViewGroup>(R.id.sdkStartAdContainer)
|
||||
val sdkJumpBtn = findViewById<TextView>(R.id.sdkJumpBtn)
|
||||
val adsFl = findViewById<FrameLayout>(R.id.adsFl)
|
||||
val icpContainer = findViewById<View>(R.id.sdkStartAdIcpContainer)
|
||||
|
||||
@ -58,6 +61,7 @@ class SplashAdActivity : BaseActivity() {
|
||||
screenHeightInDp,
|
||||
startAdContainer!!,
|
||||
sdkStartAdContainer!!,
|
||||
sdkJumpBtn!!,
|
||||
adsFl!!,
|
||||
(mBaseHandler as BaseHandler),
|
||||
true
|
||||
@ -81,15 +85,23 @@ class SplashAdActivity : BaseActivity() {
|
||||
|
||||
override fun handleMessage(msg: Message) {
|
||||
super.handleMessage(msg)
|
||||
if (msg.what == MainActivity.COUNTDOWN_AD) {
|
||||
if (msg.what == MainActivity.COUNTDOWN_AD || msg.what == MainActivity.COUNTDOWN_SDK_AD) {
|
||||
mCountdownCount++
|
||||
if (COUNTDOWN_MAX_COUNT < mCountdownCount) {
|
||||
val maxCount = if (msg.what == MainActivity.COUNTDOWN_AD) {
|
||||
COUNTDOWN_MAX_COUNT
|
||||
} else {
|
||||
MainActivity.COUNTDOWN_SDK_MAX_COUNT
|
||||
}
|
||||
if (maxCount < mCountdownCount) {
|
||||
AdDelegateHelper.isShowingSplashAd = false
|
||||
if (msg.what == MainActivity.COUNTDOWN_SDK_AD) {
|
||||
SPUtils.setLong(Constants.SP_LAST_SPLASH_AD_SHOW_TIME, System.currentTimeMillis())
|
||||
}
|
||||
finishActivity()
|
||||
} else {
|
||||
val jumpBtn = findViewById<TextView>(R.id.jumpBtn)
|
||||
jumpBtn.text = getString(R.string.splash_jump, COUNTDOWN_MAX_COUNT - mCountdownCount)
|
||||
mBaseHandler.sendEmptyMessageDelayed(MainActivity.COUNTDOWN_AD, 1000)
|
||||
val jumpBtn = findViewById<TextView>(if (msg.what == MainActivity.COUNTDOWN_AD) R.id.jumpBtn else R.id.sdkJumpBtn)
|
||||
jumpBtn?.text = getString(R.string.splash_jump, maxCount - mCountdownCount)
|
||||
mBaseHandler.sendEmptyMessageDelayed(msg.what, 1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,8 +17,11 @@ import androidx.core.text.color
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.gh.common.dialog.NewPrivacyPolicyDialogFragment
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.util.DeviceTokenUtils
|
||||
import com.gh.common.util.DialogUtils
|
||||
import com.gh.common.util.GameSubstituteRepositoryHelper.updateGameSubstituteRepository
|
||||
import com.gh.common.util.PackageHelper
|
||||
import com.gh.common.util.PackageUtils
|
||||
import com.gh.common.util.UsageStatsHelper.checkAndPostUsageStats
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity
|
||||
@ -28,6 +31,7 @@ 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.IPushProvider
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
@ -55,6 +59,9 @@ class SplashScreenActivity : BaseActivity() {
|
||||
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
mIsNewForThisVersion = HaloApp.getInstance().isNewForThisVersion
|
||||
HaloApp.getInstance().isBrandNewInstall = SPUtils.getBoolean(Constants.SP_BRAND_NEW_USER, true)
|
||||
if (HaloApp.getInstance().isBrandNewInstall) {
|
||||
SPUtils.setLong(Constants.SP_BRAND_NEW_FIRST_LAUNCH_TIME, System.currentTimeMillis())
|
||||
}
|
||||
|
||||
// 用户不是新版本,但应用最后更新时间不是上次的时间代表用户重新安装了当前版本
|
||||
if (!mIsNewForThisVersion) {
|
||||
@ -274,6 +281,12 @@ class SplashScreenActivity : BaseActivity() {
|
||||
|
||||
SensorsBridge.init(HaloApp.getInstance(), HaloApp.getInstance().channel)
|
||||
SensorsBridge.setOAID(HaloApp.getInstance().oaid)
|
||||
|
||||
val pushProvider = ARouter.getInstance().build(RouteConsts.provider.push).navigation() as? IPushProvider
|
||||
val registrationId = pushProvider?.getRegistrationId(this)
|
||||
if (!registrationId.isNullOrEmpty()) {
|
||||
SensorsBridge.profileAppend(KEY_REGISTRATION_ID, registrationId)
|
||||
}
|
||||
}
|
||||
|
||||
private fun prefetchData() {
|
||||
@ -305,6 +318,7 @@ class SplashScreenActivity : BaseActivity() {
|
||||
|
||||
|
||||
companion object {
|
||||
private const val KEY_REGISTRATION_ID = "registration_id"
|
||||
|
||||
const val HONOR_CULPRIT_ID = 12324
|
||||
const val HONOR_CULPRIT_CHANNEL = "荣耀通道"
|
||||
|
||||
@ -24,6 +24,7 @@ import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.adapter.viewholder.KcSelectGameViewHolder;
|
||||
import com.gh.gamecenter.common.retrofit.Response;
|
||||
import com.gh.gamecenter.common.utils.BitmapUtils;
|
||||
import com.gh.gamecenter.common.utils.FileUtils;
|
||||
import com.gh.gamecenter.core.utils.MtaHelper;
|
||||
import com.gh.gamecenter.core.utils.TimeUtils;
|
||||
import com.gh.gamecenter.core.utils.ToastUtils;
|
||||
@ -85,7 +86,7 @@ public class CleanApkAdapter extends BaseRecyclerAdapter<KcSelectGameViewHolder>
|
||||
Observable.create(emitter -> {
|
||||
// 扫描和获取apk数据 分步操作 尽量避免 StackoverflowError
|
||||
FindAllAPKPath(Environment.getExternalStorageDirectory());
|
||||
FindAllAPKPath(mContext.getFilesDir());
|
||||
FindAllAPKPath(new File(FileUtils.getDownloadDir(mContext)));
|
||||
LoadApkData();
|
||||
emitter.onComplete();
|
||||
})
|
||||
|
||||
@ -652,12 +652,12 @@ class DetailViewHolder(
|
||||
builder.addHandler(LandPageAddressHandler())
|
||||
builder.addHandler(OverseaDownloadHandler())
|
||||
builder.addHandler(CheckDownloadHandler())
|
||||
builder.setProcessEndCallback { asVGame: Boolean, isSubscribe: Any? ->
|
||||
builder.setProcessEndCallback(mGameEntity.id) { asVGame: Boolean, isSubscribe: Any? ->
|
||||
download(asVGame, isSubscribe as Boolean)
|
||||
}
|
||||
} else {
|
||||
builder.addHandler(VersionNumberHandler())
|
||||
builder.setProcessEndCallback { _: Boolean?, _: Any? ->
|
||||
builder.setProcessEndCallback(mGameEntity.id) { _: Boolean?, _: Any? ->
|
||||
DownloadDialog.showDownloadDialog(
|
||||
mViewHolder.context,
|
||||
mGameEntity,
|
||||
|
||||
@ -4,11 +4,10 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import com.gh.gamecenter.common.utils.viewModelProvider
|
||||
import com.gh.gamecenter.DisplayType
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.SearchActivity
|
||||
import com.gh.gamecenter.SearchType
|
||||
import com.gh.gamecenter.common.utils.viewModelProvider
|
||||
import com.gh.gamecenter.db.ISearchHistoryDao
|
||||
import com.gh.gamecenter.search.SearchDefaultFragment
|
||||
|
||||
@ -64,19 +63,16 @@ class AmwaySearchActivity : SearchActivity() {
|
||||
}
|
||||
|
||||
override fun updateDisplayType(type: DisplayType) {
|
||||
val transaction = supportFragmentManager.beginTransaction()
|
||||
when (type) {
|
||||
DisplayType.DEFAULT -> {
|
||||
val fragment = supportFragmentManager.findFragmentByTag(SearchDefaultFragment::class.java.name)
|
||||
?: AmwaySearchDefaultFragment()
|
||||
transaction.replace(R.id.search_result, fragment, SearchDefaultFragment::class.java.name)
|
||||
}
|
||||
val transaction = when (type) {
|
||||
DisplayType.DEFAULT -> showFragment(
|
||||
SearchDefaultFragment::class.java.name,
|
||||
{ AmwaySearchDefaultFragment() }
|
||||
)
|
||||
|
||||
else -> {
|
||||
val fragment = supportFragmentManager.findFragmentByTag(AmwaySearchListFragment::class.java.name)
|
||||
?: AmwaySearchListFragment()
|
||||
transaction.replace(R.id.search_result, fragment, AmwaySearchListFragment::class.java.name)
|
||||
}
|
||||
else -> showFragment(
|
||||
AmwaySearchListFragment::class.java.name,
|
||||
{ AmwaySearchListFragment() }
|
||||
)
|
||||
}
|
||||
mDisplayType = type
|
||||
transaction.commitAllowingStateLoss()
|
||||
|
||||
@ -33,7 +33,7 @@ class AmwaySearchDefaultFragment : SearchDefaultFragment() {
|
||||
mViewModel.playedGames.observeNonNull(viewLifecycleOwner) {
|
||||
defaultViewModel?.isExistHotSearch = it.isNotEmpty()
|
||||
updateView()
|
||||
mBinding.hotList.run {
|
||||
mBinding.searchDiscoveryList.run {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
adapter = AmwaySearchAdapter(context, mViewModel, "安利墙搜索-最近玩过").apply { setData(it) }
|
||||
}
|
||||
@ -45,7 +45,7 @@ class AmwaySearchDefaultFragment : SearchDefaultFragment() {
|
||||
override fun provideDao(): ISearchHistoryDao = AmwaySearchDao()
|
||||
override fun initView() {
|
||||
mBinding = mAmwayBinding.searchContent
|
||||
mBinding.hotHeadContainer.headTitle.text = "最近玩过"
|
||||
mBinding.searchDiscoveryHeadContainer.headTitle.text = "最近玩过"
|
||||
mBinding.historyFlexContainer.setLimitHeight(mFlexMaxHeight)
|
||||
|
||||
updateHistorySearchView(null)
|
||||
|
||||
@ -57,6 +57,7 @@ class AmwaySearchListFragment : ToolbarFragment() {
|
||||
when (it) {
|
||||
LoadStatus.INIT_LOADING -> {
|
||||
hideError()
|
||||
hideRvList()
|
||||
showLoading()
|
||||
hideNoDataHint()
|
||||
}
|
||||
@ -64,16 +65,19 @@ class AmwaySearchListFragment : ToolbarFragment() {
|
||||
hideError()
|
||||
hideLoading()
|
||||
hideNoDataHint()
|
||||
showRvList()
|
||||
}
|
||||
LoadStatus.INIT_FAILED -> {
|
||||
hideLoading()
|
||||
hideNoDataHint()
|
||||
showError()
|
||||
hideRvList()
|
||||
}
|
||||
LoadStatus.INIT_EMPTY -> {
|
||||
showNoDataHint()
|
||||
hideError()
|
||||
hideLoading()
|
||||
hideRvList()
|
||||
}
|
||||
else -> {
|
||||
// do nothing
|
||||
@ -82,6 +86,14 @@ class AmwaySearchListFragment : ToolbarFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun hideRvList() {
|
||||
mBinding.recyclerView.visibility = View.GONE
|
||||
}
|
||||
|
||||
private fun showRvList() {
|
||||
mBinding.recyclerView.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
private fun showLoading() {
|
||||
mBinding.loadingContainer.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
@ -44,6 +44,7 @@ class AmwaySearchViewModel(application: Application) : AndroidViewModel(applicat
|
||||
mTempSearchKey = searchKey
|
||||
currentSearchKey = searchKey
|
||||
loadStatus.postValue(LoadStatus.INIT_LOADING)
|
||||
searchGames.postValue(emptyList())
|
||||
RetrofitManager
|
||||
.getInstance().api
|
||||
.getSearchGame(Config.API_HOST + "games:search?keyword=" + searchKey + "&view=anliwall" + "&channel=" + HaloApp.getInstance().channel + "&version=" + BuildConfig.VERSION_NAME)
|
||||
|
||||
@ -160,7 +160,7 @@ class DownloadFragment : BaseFragment_TabLayout() {
|
||||
val ownerAd = downloadManagerAd?.ownerAd
|
||||
val showOnFailed = downloadManagerAd?.displayRule?.onFailedAction == "show"
|
||||
if ((showThirdPartyAd && thirdPartyAd != null) || (!showThirdPartyAd && thirdPartyAd != null && ownerAd == null)) {
|
||||
initThirdPartyAd(thirdPartyAd) { isSuccess ->
|
||||
initThirdPartyAd(downloadManagerAd, thirdPartyAd) { isSuccess ->
|
||||
mBinding.maskView.goneIf(!isSuccess)
|
||||
if (!isSuccess && ownerAd != null && showOnFailed) {
|
||||
mSlideInterval = ownerAd.adSource?.sliderInterval ?: -1
|
||||
@ -182,12 +182,34 @@ class DownloadFragment : BaseFragment_TabLayout() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun initThirdPartyAd(thirdPartyAd: AdConfig.ThirdPartyAd, callback: (isSuccess: Boolean) -> Unit) {
|
||||
private fun initThirdPartyAd(adConfig: AdConfig?, thirdPartyAd: AdConfig.ThirdPartyAd, callback: (isSuccess: Boolean) -> Unit) {
|
||||
val onAdShowAction = {
|
||||
SensorsBridge.trackEvent("ThirdPartyAdShow",
|
||||
"ad_source", thirdPartyAd.sourceName,
|
||||
"ad_id", thirdPartyAd.slotId,
|
||||
"ad_format", adConfig?.typeChinese ?: "",
|
||||
"ad_placement", "下载管理",
|
||||
"ad_space_id", adConfig?.id ?: "",
|
||||
"ad_space_name", adConfig?.name ?: ""
|
||||
)
|
||||
}
|
||||
val onAdClickAction = {
|
||||
SensorsBridge.trackEvent("ThirdPartyAdClick",
|
||||
"ad_source", thirdPartyAd.sourceName,
|
||||
"ad_id", thirdPartyAd.slotId,
|
||||
"ad_format", adConfig?.typeChinese ?: "",
|
||||
"ad_placement", "下载管理",
|
||||
"ad_space_id", adConfig?.id ?: "",
|
||||
"ad_space_name", adConfig?.name ?: ""
|
||||
)
|
||||
}
|
||||
AdDelegateHelper.requestThirdPartyBannerAd(
|
||||
this,
|
||||
mBinding.adContainer,
|
||||
thirdPartyAd,
|
||||
DisplayUtils.getScreenWidthInDp(requireActivity()),
|
||||
onAdShowAction,
|
||||
onAdClickAction,
|
||||
callback
|
||||
)
|
||||
}
|
||||
@ -226,7 +248,7 @@ class DownloadFragment : BaseFragment_TabLayout() {
|
||||
if (it.isNullOrEmpty() && adConfig.displayRule.adSource == AdDelegateHelper.AD_TYPE_OWNER &&
|
||||
adConfig.displayRule.onFailedAction == "show" && adConfig.thirdPartyAd != null) {
|
||||
// 自有广告游戏为空时,显示第三方广告
|
||||
initThirdPartyAd(adConfig.thirdPartyAd) { isSuccess ->
|
||||
initThirdPartyAd(adConfig, adConfig.thirdPartyAd) { isSuccess ->
|
||||
mBinding.maskView.goneIf(!isSuccess)
|
||||
if (isSuccess) {
|
||||
SPUtils.setLong(Constants.SP_LAST_DOWNLOAD_MANAGER_AD_SHOW_TIME, System.currentTimeMillis())
|
||||
|
||||
@ -6,7 +6,7 @@ class AdConfig(
|
||||
@SerializedName("_id")
|
||||
val id: String = "",
|
||||
val name: String,
|
||||
val location: String, // 广告插入位置。光环启动:halo_launch 下载管理:download_manager 游戏搜索:game_search 助手启动:helper_launch
|
||||
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")
|
||||
@ -18,12 +18,19 @@ class AdConfig(
|
||||
@SerializedName("owner_ads")
|
||||
val ownerAd: OwnerAdEntity? = null,
|
||||
) {
|
||||
companion object {
|
||||
const val TYPE_LAUNCH = "launch"
|
||||
const val TYPE_NATIVE = "native"
|
||||
const val TYPE_BANNER = "banner"
|
||||
const val TYPE_INTERSTITIAL = "interstitial"
|
||||
}
|
||||
|
||||
val typeChinese
|
||||
get() = when (type) {
|
||||
"launch" -> "开屏"
|
||||
"native" -> "信息流"
|
||||
"banner" -> "banner"
|
||||
"interstitial" -> "插屏"
|
||||
TYPE_LAUNCH -> "开屏"
|
||||
TYPE_NATIVE -> "信息流"
|
||||
TYPE_BANNER -> "banner"
|
||||
TYPE_INTERSTITIAL -> "插屏"
|
||||
else -> ""
|
||||
}
|
||||
|
||||
|
||||
@ -26,7 +26,8 @@ data class BottomTab(
|
||||
@SerializedName("is_default_page")
|
||||
var default: Boolean = false, // 是否为默认显示页
|
||||
var guide: Guide? = null, // 引导文案
|
||||
var isTransparentStyle: Boolean = false // 本地字段,透明底部Tab
|
||||
var diverter: DiverterEntity? = null, // 分流器
|
||||
var isTransparentStyle: Boolean = false, // 本地字段,透明底部Tab
|
||||
) : Parcelable {
|
||||
@Parcelize
|
||||
data class SearchStyle(
|
||||
|
||||
31
app/src/main/java/com/gh/gamecenter/entity/DiverterData.kt
Normal file
31
app/src/main/java/com/gh/gamecenter/entity/DiverterData.kt
Normal file
@ -0,0 +1,31 @@
|
||||
package com.gh.gamecenter.entity
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
class DiverterData(
|
||||
@SerializedName("diverter_id")
|
||||
val diverterId: String = "",
|
||||
@SerializedName("diverter_name")
|
||||
val diverterName: String = "",
|
||||
@SerializedName("branch_id")
|
||||
val branchId: String = "",
|
||||
@SerializedName("branch_name")
|
||||
val branchName: String = "",
|
||||
@SerializedName("branch_type")
|
||||
val branchType: String = "",
|
||||
@SerializedName("inprocess_time")
|
||||
val inprocessTime: Int = 0,
|
||||
@SerializedName("bypass_visit_time")
|
||||
val bypassVisitTime: Int = 0,
|
||||
@SerializedName("link_id")
|
||||
val linkId: String = "",
|
||||
@SerializedName("link_type")
|
||||
val linkType: String = "",
|
||||
@SerializedName("link_text")
|
||||
val linkText: String = "",
|
||||
@SerializedName("bypass_status")
|
||||
val bypassStatus: Int = 0,
|
||||
): Parcelable
|
||||
15
app/src/main/java/com/gh/gamecenter/entity/DiverterEntity.kt
Normal file
15
app/src/main/java/com/gh/gamecenter/entity/DiverterEntity.kt
Normal file
@ -0,0 +1,15 @@
|
||||
package com.gh.gamecenter.entity
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
class DiverterEntity(
|
||||
@SerializedName("module_id")
|
||||
val moduleId: String = "",
|
||||
@SerializedName("module_index")
|
||||
val moduleIndex: Int = -1,
|
||||
@SerializedName("diverter_data")
|
||||
val diverterData: DiverterData = DiverterData()
|
||||
): Parcelable
|
||||
@ -23,6 +23,9 @@ import com.airbnb.lottie.SimpleColorFilter
|
||||
import com.airbnb.lottie.model.KeyPath
|
||||
import com.airbnb.lottie.value.LottieValueCallback
|
||||
import com.gh.common.browse.BrowseTimer
|
||||
import com.gh.common.iinterface.ISuperiorChain
|
||||
import com.gh.common.prioritychain.CommunityHomeGuideHandler
|
||||
import com.gh.common.prioritychain.PriorityChain
|
||||
import com.gh.common.util.DirectUtils
|
||||
import com.gh.common.util.NewFlatLogUtils
|
||||
import com.gh.common.util.NewLogUtils
|
||||
@ -42,7 +45,6 @@ import com.gh.gamecenter.core.utils.MtaHelper
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.core.utils.TimeUtils
|
||||
import com.gh.gamecenter.databinding.FragmentCommunityHomeBinding
|
||||
import com.gh.gamecenter.databinding.LayoutCommunityHomeVideoGuideBinding
|
||||
import com.gh.gamecenter.databinding.TabItemCommunityBinding
|
||||
import com.gh.gamecenter.eventbus.EBSkip
|
||||
import com.gh.gamecenter.eventbus.EBTypeChange
|
||||
@ -81,6 +83,8 @@ class CommunityHomeFragment : LazyFragment() {
|
||||
private var mNavigationBitmap: Bitmap? = null
|
||||
private var mShowVideo = true
|
||||
private var mBottomTabId = ""
|
||||
private val mPriorityChain by lazy { PriorityChain() }
|
||||
private var mSuperiorChain: ISuperiorChain? = null
|
||||
|
||||
private val browseTimer = BrowseTimer()
|
||||
.withResult {
|
||||
@ -156,6 +160,12 @@ class CommunityHomeFragment : LazyFragment() {
|
||||
})
|
||||
}
|
||||
|
||||
private fun addHomeVideoGuideHandler() {
|
||||
val decorView = activity?.window?.decorView as? FrameLayout
|
||||
val communityHomeGuideHandler = CommunityHomeGuideHandler(21, requireContext(), decorView, mBinding?.videoLottie)
|
||||
mPriorityChain.addHandler(communityHomeGuideHandler)
|
||||
}
|
||||
|
||||
override fun initRealView() {
|
||||
super.initRealView()
|
||||
|
||||
@ -166,24 +176,7 @@ class CommunityHomeFragment : LazyFragment() {
|
||||
mMainWrapperViewModel?.bottomTabListLiveData?.observe(this) { tabList ->
|
||||
mBinding?.videoAndSearchContainer?.goneIf(!mShowVideo) {
|
||||
val decorView = requireActivity().window.decorView as? FrameLayout
|
||||
|
||||
if (SPUtils.getBoolean(Constants.SP_SHOW_COMMUNITY_HOME_VIDEO_GUIDE, true)) {
|
||||
val guideLayoutBinding = LayoutCommunityHomeVideoGuideBinding.inflate(
|
||||
LayoutInflater.from(requireContext()),
|
||||
decorView,
|
||||
true
|
||||
)
|
||||
guideLayoutBinding.root.setOnClickListener { view ->
|
||||
decorView?.removeView(view)
|
||||
SPUtils.setBoolean(Constants.SP_SHOW_COMMUNITY_HOME_VIDEO_GUIDE, false)
|
||||
|
||||
mBinding?.videoLottie?.playAnimation()
|
||||
SPUtils.setLong(
|
||||
Constants.SP_COMMUNITY_HOME_VIDEO_LOTTIE_LAST_PLAY_TIME,
|
||||
System.currentTimeMillis()
|
||||
)
|
||||
}
|
||||
}
|
||||
addHomeVideoGuideHandler()
|
||||
|
||||
// 每日首次进入社区tab视频lottie播放3次
|
||||
val lastPlayTime = SPUtils.getLong(Constants.SP_COMMUNITY_HOME_VIDEO_LOTTIE_LAST_PLAY_TIME, 0L) / 1000
|
||||
@ -285,6 +278,14 @@ class CommunityHomeFragment : LazyFragment() {
|
||||
DisplayUtils.transparentStatusBar(requireActivity())
|
||||
DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn)
|
||||
NewLogUtils.logCommunityHomeEvent("view_community")
|
||||
|
||||
mSuperiorChain?.registerInferiorChain(mPriorityChain)
|
||||
}
|
||||
|
||||
override fun onFragmentPause() {
|
||||
super.onFragmentPause()
|
||||
|
||||
mSuperiorChain?.unregisterInferiorChain(mPriorityChain)
|
||||
}
|
||||
|
||||
fun setCurrentItem(index: Int) {
|
||||
@ -836,6 +837,11 @@ class CommunityHomeFragment : LazyFragment() {
|
||||
|
||||
fun getTopBgView() = mBinding?.topBg
|
||||
|
||||
fun setSuperiorChain(superiorChain: ISuperiorChain?): CommunityHomeFragment {
|
||||
this.mSuperiorChain = superiorChain
|
||||
return this
|
||||
}
|
||||
|
||||
companion object {
|
||||
var TAB_SELECTED_COLOR: Int = R.color.text_primary
|
||||
var TAB_DEFAULT_COLOR: Int = R.color.community_forum_more
|
||||
|
||||
@ -129,39 +129,40 @@ class ForumOrUserSearchActivity : SearchActivity() {
|
||||
}
|
||||
|
||||
override fun updateDisplayType(type: DisplayType) {
|
||||
val transaction = supportFragmentManager.beginTransaction()
|
||||
when (type) {
|
||||
DisplayType.DEFAULT -> {
|
||||
val fragment = supportFragmentManager.findFragmentByTag(SearchDefaultFragment::class.java.name)
|
||||
?: ForumOrUserSearchDefaultFragment()
|
||||
fragment.arguments = intent.extras
|
||||
transaction.replace(R.id.search_result, fragment, SearchDefaultFragment::class.java.name)
|
||||
val key = searchEt.text.toString().trim { it <= ' ' }
|
||||
if (key.isNotEmpty()) {
|
||||
val stayTime = (System.currentTimeMillis() - startPageTime) / 1000
|
||||
if (mEntrance != ForumDetailFragment.ENTRANCE) {
|
||||
NewFlatLogUtils.logViewSearchList(stayTime, key)
|
||||
} else {
|
||||
NewFlatLogUtils.logViewBbsSearchList(stayTime, key, mBbsId)
|
||||
val transaction = when (type) {
|
||||
DisplayType.DEFAULT -> showFragment(
|
||||
SearchDefaultFragment::class.java.name,
|
||||
onFragmentCreate = { ForumOrUserSearchDefaultFragment() }
|
||||
) { fragment ->
|
||||
fragment.arguments = intent.extras
|
||||
}.apply {
|
||||
val key = searchEt.text.toString().trim { it <= ' ' }
|
||||
if (key.isNotEmpty()) {
|
||||
val stayTime = (System.currentTimeMillis() - startPageTime) / 1000
|
||||
if (mEntrance != ForumDetailFragment.ENTRANCE) {
|
||||
NewFlatLogUtils.logViewSearchList(stayTime, key)
|
||||
} else {
|
||||
NewFlatLogUtils.logViewBbsSearchList(stayTime, key, mBbsId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
if (mEntrance != ForumDetailFragment.ENTRANCE) {
|
||||
val fragment =
|
||||
supportFragmentManager.findFragmentByTag(ForumOrUserSearchFragment::class.java.name) as? ForumOrUserSearchFragment
|
||||
?: ForumOrUserSearchFragment()
|
||||
fragment.setSearchKeyAndType(mSearchKey ?: "", mSearchType.value)
|
||||
transaction.replace(R.id.search_result, fragment, ForumOrUserSearchFragment::class.java.name)
|
||||
else -> if (mEntrance != ForumDetailFragment.ENTRANCE) {
|
||||
showFragment(
|
||||
ForumOrUserSearchFragment::class.java.name,
|
||||
{ ForumOrUserSearchFragment() }
|
||||
) { fragment ->
|
||||
fragment.setSearchKeyAndType(mSearchKey ?: "", mSearchType.value)
|
||||
}
|
||||
} else {
|
||||
val fragment =
|
||||
supportFragmentManager.findFragmentByTag(ForumContentSearchListFragment::class.java.name) as? ForumContentSearchListFragment
|
||||
?: ForumContentSearchListFragment()
|
||||
fragment.setSearchKeyAndType(mSearchKey ?: "", mSearchType.value)
|
||||
fragment.arguments = intent.extras
|
||||
transaction.replace(R.id.search_result, fragment, ForumContentSearchListFragment::class.java.name)
|
||||
}
|
||||
showFragment(
|
||||
ForumOrUserSearchFragment::class.java.name,
|
||||
{ ForumContentSearchListFragment() }
|
||||
) { fragment ->
|
||||
fragment.setSearchKeyAndType(mSearchKey ?: "", mSearchType.value)
|
||||
fragment.arguments = intent.extras
|
||||
}
|
||||
}.apply {
|
||||
startPageTime = System.currentTimeMillis()
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,14 +42,14 @@ class ForumOrUserSearchDefaultFragment : SearchDefaultFragment() {
|
||||
|
||||
override fun initView() {
|
||||
mBinding = FragmentSearchDefaultBinding.bind(mCachedView)
|
||||
mBinding.hotTagHeadContainer.root.visibility = View.GONE
|
||||
mBinding.hotTagFlexContainer.visibility = View.GONE
|
||||
mBinding.searchDiscoveryTagHeadContainer.root.visibility = View.GONE
|
||||
mBinding.searchDiscoveryTagFlexContainer.visibility = View.GONE
|
||||
if (mEntrance == "论坛首页" || mEntrance == "搜索栏") {
|
||||
mBinding.hotHeadContainer.headTitle.text = "热门论坛"
|
||||
mBinding.searchDiscoveryHeadContainer.headTitle.text = "热门论坛"
|
||||
mViewModel.getForumSearchHotContent()
|
||||
} else {
|
||||
mBinding.hotHeadContainer.root.visibility = View.GONE
|
||||
mBinding.hotList.visibility = View.GONE
|
||||
mBinding.searchDiscoveryHeadContainer.root.visibility = View.GONE
|
||||
mBinding.searchDiscoveryList.visibility = View.GONE
|
||||
}
|
||||
val params = mBinding.historyHeadContainer.root.layoutParams as ConstraintLayout.LayoutParams
|
||||
params.topMargin = 0.5f.dip2px()
|
||||
|
||||
@ -23,7 +23,7 @@ class ReloadFragment: BaseLazyFragment() {
|
||||
super.onCreate(savedInstanceState)
|
||||
mBinding.reuseLoading.root.visibility = View.VISIBLE
|
||||
mBinding.reuseNoConnection.connectionReloadTv.setOnClickListener {
|
||||
MainWrapperRepository.getInstance().getDataUnion()
|
||||
MainWrapperRepository.getInstance().init()
|
||||
mBinding.reuseNoConnection.root.visibility = View.GONE
|
||||
mBinding.reuseLoading.root.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
@ -2,8 +2,8 @@ package com.gh.gamecenter.game.columncollection.detail
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import com.gh.gamecenter.common.base.activity.ToolBarActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.activity.ToolBarActivity
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.utils.updateStatusBarColor
|
||||
|
||||
@ -34,8 +34,8 @@ class ColumnCollectionDetailActivity : ToolBarActivity() {
|
||||
}
|
||||
|
||||
override fun getBusinessId(): Pair<String, String> {
|
||||
val fragment = targetFragment as ColumnCollectionDetailFragment
|
||||
return if (fragment.arguments != null) {
|
||||
val fragment = targetFragment as? ColumnCollectionDetailFragment?
|
||||
return if (fragment?.arguments != null) {
|
||||
Pair(fragment.requireArguments().getString(EntranceConsts.KEY_COLLECTION_ID) ?: "", "")
|
||||
} else {
|
||||
super.getBusinessId()
|
||||
|
||||
@ -36,8 +36,8 @@ class CommonCollectionDetailActivity : ToolBarActivity() {
|
||||
}
|
||||
|
||||
override fun getBusinessId(): Pair<String, String> {
|
||||
val fragment = targetFragment as CommonCollectionDetailFragment
|
||||
return if (fragment.arguments != null) {
|
||||
val fragment = targetFragment as? CommonCollectionDetailFragment?
|
||||
return if (fragment?.arguments != null) {
|
||||
Pair(
|
||||
fragment.requireArguments().getString(EntranceConsts.KEY_COLLECTION_ID) ?: "",
|
||||
fragment.requireArguments().getString(EntranceConsts.KEY_BLOCK_ID) ?: ""
|
||||
|
||||
@ -36,8 +36,8 @@ class CustomCommonCollectionDetailActivity : ToolBarActivity() {
|
||||
}
|
||||
|
||||
override fun getBusinessId(): Pair<String, String> {
|
||||
val fragment = targetFragment as CustomCommonCollectionDetailFragment
|
||||
return if (fragment.arguments != null) {
|
||||
val fragment = targetFragment as? CustomCommonCollectionDetailFragment?
|
||||
return if (fragment?.arguments != null) {
|
||||
Pair(
|
||||
fragment.requireArguments().getString(EntranceConsts.KEY_COLLECTION_ID) ?: "",
|
||||
fragment.requireArguments().getString(EntranceConsts.KEY_BLOCK_ID) ?: ""
|
||||
|
||||
@ -3,7 +3,6 @@ package com.gh.gamecenter.game.upload
|
||||
import android.app.Dialog
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.provider.MediaStore
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
import android.text.TextPaint
|
||||
@ -29,18 +28,21 @@ import com.gh.gamecenter.WebActivity
|
||||
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
|
||||
import com.gh.gamecenter.common.callback.OnListClickListener
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.feature.selector.LocalMediaActivity
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.common.view.choosepic.ChoosePicAdapter
|
||||
import com.gh.gamecenter.core.utils.GsonUtils
|
||||
import com.gh.gamecenter.core.utils.MtaHelper
|
||||
import com.gh.gamecenter.core.utils.SpanBuilder
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.databinding.FragmentGameUploadBinding
|
||||
import com.gh.gamecenter.feature.entity.InstallGameEntity
|
||||
import com.gh.gamecenter.feature.game.SelectGameAdapter
|
||||
import com.gh.gamecenter.feature.selector.ChooseType
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Util_System_Keyboard
|
||||
import com.lightgame.utils.Utils
|
||||
import com.zhihu.matisse.Matisse
|
||||
import com.zhihu.matisse.internal.utils.PathUtils
|
||||
import io.reactivex.disposables.Disposable
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
@ -86,7 +88,6 @@ class GameUploadFragment : ToolbarFragment() {
|
||||
mViewModel.upLoadSuccess.observe(viewLifecycleOwner, Observer {
|
||||
if (it) {
|
||||
ToastUtils.showToast("上传成功")
|
||||
MtaHelper.onEvent("游戏上传", "游戏上传", "上传成功")
|
||||
mUploadDialog.dismiss()
|
||||
requireActivity().finish()
|
||||
} else {
|
||||
@ -119,17 +120,11 @@ class GameUploadFragment : ToolbarFragment() {
|
||||
5,
|
||||
object : OnListClickListener {
|
||||
override fun <T : Any?> onListClick(view: View?, position: Int, data: T) {
|
||||
MtaHelper.onEvent("游戏上传", "游戏图片", "添加图片")
|
||||
val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
|
||||
val intent = LocalMediaActivity.getIntent(requireContext(), ChooseType.IMAGE, 1, "游戏上传")
|
||||
startActivityForResult(intent, MEDIA_STORE_REQUEST)
|
||||
}
|
||||
}
|
||||
) {
|
||||
MtaHelper.onEvent(
|
||||
"游戏上传",
|
||||
"游戏图片",
|
||||
"删除图片"
|
||||
)
|
||||
}
|
||||
mAdapter?.setPicItem(R.layout.game_upload_pic_item)
|
||||
mAdapter?.setSuggestAddPicIcon(R.drawable.icon_pic_add)
|
||||
@ -147,19 +142,13 @@ class GameUploadFragment : ToolbarFragment() {
|
||||
1,
|
||||
object : OnListClickListener {
|
||||
override fun <T : Any?> onListClick(view: View?, position: Int, data: T) {
|
||||
MtaHelper.onEvent("游戏上传", "游戏图标", "添加图片")
|
||||
PermissionHelper.checkStoragePermissionBeforeAction(requireActivity()) {
|
||||
val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
|
||||
val intent = LocalMediaActivity.getIntent(requireContext(), ChooseType.IMAGE, 1, "游戏上传")
|
||||
startActivityForResult(intent, MEDIA_ICON_STORE_REQUEST)
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
MtaHelper.onEvent(
|
||||
"游戏上传",
|
||||
"游戏图标",
|
||||
"删除图片"
|
||||
)
|
||||
}
|
||||
mIconAdapter?.setPicItem(R.layout.game_upload_pic_item)
|
||||
mIconAdapter?.setSuggestAddPicIcon(R.drawable.icon_pic_add)
|
||||
@ -194,18 +183,15 @@ class GameUploadFragment : ToolbarFragment() {
|
||||
private fun initListener() {
|
||||
|
||||
mBinding.chooseGameLl.setOnClickListener {
|
||||
MtaHelper.onEvent("游戏上传", "安装包", "点我选择")
|
||||
showSelectDialog()
|
||||
}
|
||||
mBinding.gameIsNetworkingRg.setOnCheckedChangeListener { _, checkedId ->
|
||||
when (checkedId) {
|
||||
R.id.gameNetworkingRb -> {
|
||||
mIsOnline = "yes"
|
||||
MtaHelper.onEvent("游戏上传", "是否联网", "需要联网")
|
||||
}
|
||||
R.id.gameNoNetworkingRb -> {
|
||||
mIsOnline = "no"
|
||||
MtaHelper.onEvent("游戏上传", "是否联网", "无需联网")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -213,15 +199,12 @@ class GameUploadFragment : ToolbarFragment() {
|
||||
when (checkedId) {
|
||||
R.id.gameLanguageChineseRb -> {
|
||||
mGameLanguage = "中文"
|
||||
MtaHelper.onEvent("游戏上传", "游戏语言", "中文")
|
||||
}
|
||||
R.id.gameLanguageEnglishRb -> {
|
||||
mGameLanguage = "英文"
|
||||
MtaHelper.onEvent("游戏上传", "游戏语言", "英文")
|
||||
}
|
||||
R.id.gameLanguageOtherRb -> {
|
||||
mGameLanguage = "其他"
|
||||
MtaHelper.onEvent("游戏上传", "游戏语言", "其他")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -229,21 +212,17 @@ class GameUploadFragment : ToolbarFragment() {
|
||||
when (checkedId) {
|
||||
R.id.gameTypeLocalRb -> {
|
||||
mGameType = "local"
|
||||
MtaHelper.onEvent("游戏上传", "游戏类型", "单机")
|
||||
}
|
||||
R.id.gameTypeOnlineRb -> {
|
||||
mGameType = "online"
|
||||
MtaHelper.onEvent("游戏上传", "游戏类型", "网游")
|
||||
}
|
||||
R.id.gameTypeOtherRb -> {
|
||||
mGameType = "other"
|
||||
MtaHelper.onEvent("游戏上传", "游戏类型", "其他")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mBinding.addGameLabeTv.setOnClickListener {
|
||||
MtaHelper.onEvent("游戏上传", "游戏标签", "添加标签")
|
||||
if (mTags.size < mMaxTagSize) {
|
||||
showAddTagDialog()
|
||||
} else {
|
||||
@ -256,7 +235,6 @@ class GameUploadFragment : ToolbarFragment() {
|
||||
}
|
||||
|
||||
private fun commit() {
|
||||
MtaHelper.onEvent("游戏上传", "提交", "提交")
|
||||
if (TextUtils.isEmpty(mBinding.tvChoose.text.toString())) {
|
||||
ToastUtils.showToast("请先选择游戏安装包")
|
||||
return
|
||||
@ -471,11 +449,9 @@ class GameUploadFragment : ToolbarFragment() {
|
||||
}
|
||||
|
||||
back.setOnClickListener {
|
||||
MtaHelper.onEvent("游戏上传", "安装包", "关闭")
|
||||
mSelectGameDialog?.cancel()
|
||||
}
|
||||
manualBtn.setOnClickListener {
|
||||
MtaHelper.onEvent("游戏上传", "安装包", "从设备上选择")
|
||||
val intent = CleanApkActivity.getIntent(requireContext(), true)
|
||||
PermissionHelper.checkManageAllFilesOrStoragePermissionBeforeAction(requireActivity()) {
|
||||
startActivityForResult(intent, CHOOSE_LOCAL_APK)
|
||||
@ -499,32 +475,20 @@ class GameUploadFragment : ToolbarFragment() {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (data == null) return
|
||||
if (requestCode == MEDIA_STORE_REQUEST || requestCode == MEDIA_ICON_STORE_REQUEST) {
|
||||
val selectedImage = data.data ?: return
|
||||
val filePathColumn = arrayOf(MediaStore.Images.Media.DATA)
|
||||
val selectedPaths = Matisse.obtainResult(data) ?: return
|
||||
val picturePath = PathUtils.getPath(requireContext(), selectedPaths[0])
|
||||
|
||||
val cursor = requireContext().contentResolver.query(selectedImage, filePathColumn, null, null, null)
|
||||
?: return
|
||||
cursor.moveToFirst()
|
||||
Utils.log("picturePath = $picturePath")
|
||||
|
||||
try {
|
||||
val columnIndex = cursor.getColumnIndex(filePathColumn[0])
|
||||
val picturePath = cursor.getString(columnIndex)
|
||||
cursor.close()
|
||||
|
||||
Utils.log("picturePath = $picturePath")
|
||||
|
||||
val file = File(picturePath)
|
||||
if (file.length() > 5 * 1024 * 1024) {
|
||||
ToastUtils.showToast(getString(R.string.pic_max_hint, 5))
|
||||
val file = File(picturePath)
|
||||
if (file.length() > 5 * 1024 * 1024) {
|
||||
ToastUtils.showToast(getString(R.string.pic_max_hint, 5))
|
||||
} else {
|
||||
if (requestCode == MEDIA_STORE_REQUEST) {
|
||||
mAdapter!!.addFileList(picturePath)
|
||||
} else {
|
||||
if (requestCode == MEDIA_STORE_REQUEST) {
|
||||
mAdapter!!.addFileList(picturePath)
|
||||
} else {
|
||||
mIconAdapter!!.addFileList(picturePath)
|
||||
}
|
||||
mIconAdapter!!.addFileList(picturePath)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
ToastUtils.showToast(e.message ?: "")
|
||||
}
|
||||
} else if (requestCode == CHOOSE_LOCAL_APK) {
|
||||
val packageName = data.getStringExtra(EntranceConsts.KEY_PACKAGENAME) ?: ""
|
||||
@ -610,7 +574,6 @@ class GameUploadFragment : ToolbarFragment() {
|
||||
labelTv.text = tag
|
||||
labelView.findViewById<View>(R.id.picDelIv).setOnClickListener {
|
||||
if (mTags.contains(tag)) {
|
||||
MtaHelper.onEvent("游戏上传", "游戏标签", "删除标签")
|
||||
mBinding.gameLabelFl.removeView(labelView)
|
||||
mTags.remove(tag)
|
||||
mBinding.gameLabelFl.goneIf(mTags.isEmpty())
|
||||
|
||||
@ -182,7 +182,9 @@ class AddGamesDialogFragment : BaseDialogFragment() {
|
||||
return super.onBack()
|
||||
}
|
||||
|
||||
private fun showGuidePopupWindow(): PopupWindow {
|
||||
private fun showGuidePopupWindow(): PopupWindow? {
|
||||
if (!isAdded) return null
|
||||
|
||||
val guideBinding = LayoutGameCollectionAddGamesGuideBinding.inflate(layoutInflater)
|
||||
val popupWindow = BugFixedPopupWindow(
|
||||
guideBinding.root,
|
||||
|
||||
@ -7,8 +7,8 @@ import android.view.View
|
||||
import com.gh.gamecenter.R
|
||||
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.exposure.ExposureSource
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
|
||||
/**
|
||||
* 游戏单详情
|
||||
@ -30,8 +30,8 @@ class GameCollectionDetailActivity : ToolBarActivity() {
|
||||
}
|
||||
|
||||
override fun getBusinessId(): Pair<String, String> {
|
||||
val fragment = targetFragment as GameCollectionDetailFragment
|
||||
return if (fragment.arguments != null) {
|
||||
val fragment = targetFragment as? GameCollectionDetailFragment?
|
||||
return if (fragment?.arguments != null) {
|
||||
Pair(fragment.requireArguments().getString(EntranceConsts.KEY_GAME_COLLECTION_ID) ?: "", "")
|
||||
} else {
|
||||
super.getBusinessId()
|
||||
|
||||
@ -16,12 +16,13 @@ import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.common.util.NewLogUtils
|
||||
import com.gh.gamecenter.common.utils.PermissionHelper
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.feature.selector.LocalMediaActivity
|
||||
import com.gh.gamecenter.common.utils.setRootBackgroundDrawable
|
||||
import com.gh.gamecenter.common.utils.toColor
|
||||
import com.gh.gamecenter.common.utils.toDrawable
|
||||
import com.gh.gamecenter.databinding.DialogChooseGameCollectionCoverTypeBinding
|
||||
import com.gh.gamecenter.feature.selector.ChooseType
|
||||
import com.gh.gamecenter.gamecollection.publish.GameCollectionEditActivity.Companion.REQUEST_CODE_IMAGE
|
||||
import com.gh.gamecenter.qa.editor.LocalMediaActivity
|
||||
import com.halo.assistant.HaloApp
|
||||
|
||||
class ChooseGameCollectionCoverTypeDialog : BaseDialogFragment() {
|
||||
@ -42,7 +43,7 @@ class ChooseGameCollectionCoverTypeDialog : BaseDialogFragment() {
|
||||
startActivityForResult(
|
||||
LocalMediaActivity.getIntent(
|
||||
requireContext(),
|
||||
LocalMediaActivity.ChooseType.IMAGE,
|
||||
ChooseType.IMAGE,
|
||||
1,
|
||||
"创建游戏单"
|
||||
), REQUEST_CODE_IMAGE
|
||||
|
||||
@ -285,7 +285,7 @@ class GameCollectionSquareAdapter(
|
||||
}
|
||||
})
|
||||
addOnScrollListener(ScrollEventListener(this).apply {
|
||||
setOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
|
||||
super.onPageScrolled(position, positionOffset, positionOffsetPixels)
|
||||
binding.bannerIndicator.onPageScrolled(
|
||||
|
||||
@ -410,7 +410,7 @@ class GameCollectionSquareFragment : LazyListFragment<GamesCollectionEntity, Gam
|
||||
}
|
||||
})
|
||||
addOnScrollListener(ScrollEventListener(this).apply {
|
||||
setOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
|
||||
super.onPageScrolled(position, positionOffset, positionOffsetPixels)
|
||||
mDefaultBinding.headerContainer.bannerIndicator.onPageScrolled(
|
||||
|
||||
@ -63,7 +63,10 @@ import com.gh.gamecenter.databinding.*
|
||||
import com.gh.gamecenter.entity.GameUpdateEntity
|
||||
import com.gh.gamecenter.entity.RecommendPopupEntity
|
||||
import com.gh.gamecenter.eventbus.*
|
||||
import com.gh.gamecenter.feature.entity.*
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.PluginLocation
|
||||
import com.gh.gamecenter.feature.entity.SimpleGame
|
||||
import com.gh.gamecenter.feature.entity.TagStyleEntity
|
||||
import com.gh.gamecenter.feature.eventbus.EBConcernChanged
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.utils.ApkActiveUtils
|
||||
@ -71,11 +74,7 @@ import com.gh.gamecenter.feature.utils.SentryHelper
|
||||
import com.gh.gamecenter.forum.detail.ForumDetailActivity
|
||||
import com.gh.gamecenter.gamedetail.cloudarchive.CloudArchiveFragment
|
||||
import com.gh.gamecenter.gamedetail.desc.DescFragment
|
||||
import com.gh.gamecenter.gamedetail.dialog.GameBigEventDialog
|
||||
import com.gh.gamecenter.gamedetail.dialog.GameDetailMoreDialog
|
||||
import com.gh.gamecenter.gamedetail.dialog.GameTagsDialog
|
||||
import com.gh.gamecenter.gamedetail.dialog.SpecialDownloadDialogFragment
|
||||
import com.gh.gamecenter.gamedetail.dialog.SpecialDownloadVisibilityViewModel
|
||||
import com.gh.gamecenter.gamedetail.dialog.*
|
||||
import com.gh.gamecenter.gamedetail.entity.ContentCardEntity
|
||||
import com.gh.gamecenter.gamedetail.entity.NewGameDetailEntity
|
||||
import com.gh.gamecenter.gamedetail.entity.Video
|
||||
@ -149,8 +148,6 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
|
||||
private var mShowConcernOnMenu = false
|
||||
|
||||
private var mSpecialDownloadDetailFragmentIsShowing = false
|
||||
|
||||
private val mFragmentsList = ArrayList<Fragment>()
|
||||
private val mTabTitleList = ArrayList<String>()
|
||||
private val mTabTypeList = ArrayList<String>() // tab 类型的列表,用于确定某个类型的 tab 在第几个位置
|
||||
@ -167,7 +164,7 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
|| downloadEntity.status == DownloadStatus.redirected
|
||||
) {
|
||||
// 特殊下载弹窗
|
||||
if (isSpecialDownloadDialogAvailable() && !mSpecialDownloadDetailFragmentIsShowing) {
|
||||
if (isSpecialDownloadDialogAvailable(downloadEntity) && !isSpecialDownloadDetailFragmentIsShowing()) {
|
||||
updateSpecialDownloadDialogIcon(true)
|
||||
|
||||
if (downloadEntity.status == DownloadStatus.add) {
|
||||
@ -868,8 +865,10 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
|
||||
showConcernIconAtBottomBarIfAvailable()
|
||||
|
||||
if (isSpecialDownloadDialogAvailable()
|
||||
&& DownloadManager.getInstance().getDownloadEntitySnapshot(mGameEntity) != null) {
|
||||
val downloadEntitySnapshot = DownloadManager.getInstance().getDownloadEntitySnapshot(mGameEntity)
|
||||
|
||||
if (isSpecialDownloadDialogAvailable(downloadEntitySnapshot)
|
||||
&& downloadEntitySnapshot != null) {
|
||||
updateSpecialDownloadDialogIcon(true)
|
||||
}
|
||||
|
||||
@ -1180,6 +1179,11 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
}
|
||||
|
||||
private fun doShowAlertDialog(dialog: GameEntity.Dialog) {
|
||||
SensorsBridge.trackEvent("GameDetailDialogShow",
|
||||
"game_id", mGameEntity?.id ?: "",
|
||||
"game_name", mGameEntity?.name ?: "",
|
||||
"game_type", mGameEntity?.categoryChinese ?: ""
|
||||
)
|
||||
DialogHelper.showDialogWithHtmlContent(
|
||||
requireContext(),
|
||||
dialog.title,
|
||||
@ -1187,8 +1191,33 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
dialog.confirmButton.text.toString(),
|
||||
dialog.closeButtonText,
|
||||
{
|
||||
SensorsBridge.trackEvent("GameDetailDialogClick",
|
||||
"game_id", mGameEntity?.id ?: "",
|
||||
"game_name", mGameEntity?.name ?: "",
|
||||
"game_type", mGameEntity?.categoryChinese ?: "",
|
||||
"link_type", dialog.confirmButton.type ?: "",
|
||||
"link_id", dialog.confirmButton.link ?: "",
|
||||
"link_text", dialog.confirmButton.linkText ?: "",
|
||||
"button_name", dialog.confirmButton.text.toString()
|
||||
)
|
||||
dialog.confirmButton.text = dialog.confirmButton.linkText
|
||||
DirectUtils.directToLinkPage(requireContext(), dialog.confirmButton, mEntrance, "")
|
||||
},
|
||||
{
|
||||
SensorsBridge.trackEvent("GameDetailDialogClick",
|
||||
"game_id", mGameEntity?.id ?: "",
|
||||
"game_name", mGameEntity?.name ?: "",
|
||||
"game_type", mGameEntity?.categoryChinese ?: "",
|
||||
"button_name", dialog.closeButtonText
|
||||
)
|
||||
},
|
||||
{
|
||||
SensorsBridge.trackEvent("GameDetailDialogClick",
|
||||
"game_id", mGameEntity?.id ?: "",
|
||||
"game_name", mGameEntity?.name ?: "",
|
||||
"game_type", mGameEntity?.categoryChinese ?: "",
|
||||
"button_name", "关闭弹窗"
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -2562,12 +2591,15 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
* 2. 未获取到游戏详情数据
|
||||
* 3. 当前游戏 APK 不为 1 个
|
||||
* 4. 当前游戏类型不为畅玩
|
||||
* 5. 当前游戏不是双下载时使用本地下载进行下载
|
||||
*/
|
||||
private fun isSpecialDownloadDialogAvailable(): Boolean {
|
||||
private fun isSpecialDownloadDialogAvailable(downloadEntity: DownloadEntity? = null): Boolean {
|
||||
if (Config.getNewApiSettingsEntity()?.install?.questionTip?.linkEntity == null) return false
|
||||
if (mNewGameDetailEntity == null || mGameEntity == null) return false
|
||||
if (mGameEntity?.getApk()?.size != 1) return false
|
||||
if (GameUtils.shouldPerformAsVGame(mGameEntity!!)) return false
|
||||
if (downloadEntity?.asVGame() == true) return false
|
||||
if (downloadEntity?.isSimulatorGame() == true) return false
|
||||
if (downloadEntity?.isLocalDownloadInDualDownloadMode() == true) return false
|
||||
|
||||
return true
|
||||
}
|
||||
@ -2585,7 +2617,6 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
if (fragment == null) {
|
||||
if (!visibilityViewModel.specialDownloadVisibleLiveData.hasObservers()) {
|
||||
visibilityViewModel.specialDownloadVisibleLiveData.observe(viewLifecycleOwner) {
|
||||
mSpecialDownloadDetailFragmentIsShowing = it
|
||||
updateSpecialDownloadDialogIcon(visible = !it)
|
||||
}
|
||||
}
|
||||
@ -2601,6 +2632,10 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
}
|
||||
}
|
||||
|
||||
private fun isSpecialDownloadDetailFragmentIsShowing(): Boolean {
|
||||
return childFragmentManager.findFragmentByTag(TAG_SPECIAL_DOWNLOAD_DIALOG) != null
|
||||
}
|
||||
|
||||
override fun scrollToTop() {
|
||||
val fragment = mFragmentsList.safelyGetInRelease(mBodyBinding.gamedetailVp.currentItem)
|
||||
if (fragment is IScrollable && fragment.isAdded) {
|
||||
|
||||
@ -17,6 +17,7 @@ import com.gh.common.iinterface.ISuperiorChain
|
||||
import com.gh.common.prioritychain.CustomFloatingWindowHandler
|
||||
import com.gh.common.prioritychain.PriorityChain
|
||||
import com.gh.common.prioritychain.PullDownPushHandler
|
||||
import com.gh.common.prioritychain.VideoHandler
|
||||
import com.gh.common.util.DefaultSearchHintHelper
|
||||
import com.gh.common.util.DialogUtils
|
||||
import com.gh.common.util.DirectUtils
|
||||
@ -468,9 +469,9 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
|
||||
binding = FragmentCustomBinding.bind(mCachedView)
|
||||
|
||||
buildPriorityChain()
|
||||
scrollCalculatorHelper = ScrollCalculatorHelper(binding.gameList, R.id.autoVideoView, 0, false)
|
||||
|
||||
scrollCalculatorHelper = ScrollCalculatorHelper(binding.gameList, R.id.autoVideoView, 0)
|
||||
buildPriorityChain()
|
||||
|
||||
adapter = CustomPageAdapter(
|
||||
viewModel,
|
||||
@ -512,9 +513,11 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
|
||||
private fun buildPriorityChain() {
|
||||
val floatingWindowHandler = CustomFloatingWindowHandler(23)
|
||||
val videoHandler = VideoHandler(24, scrollCalculatorHelper)
|
||||
|
||||
priorityChain.addHandler(pullDownPushHandler)
|
||||
priorityChain.addHandler(floatingWindowHandler)
|
||||
priorityChain.addHandler(videoHandler)
|
||||
(parentFragment as? BaseTabWrapperFragment)?.addTabGuideHandlerIfExists(priorityChain)
|
||||
|
||||
viewModel.floatingWindows.observe(viewLifecycleOwner, EventObserver {
|
||||
|
||||
@ -146,7 +146,7 @@ class CustomFoldSlideLargeImageItemAdapter(
|
||||
if (dataList.isEmpty()) {
|
||||
0
|
||||
} else {
|
||||
Int.MAX_VALUE / 2 - Int.MAX_VALUE % dataList.size
|
||||
Int.MAX_VALUE / 2 - (Int.MAX_VALUE / 2) % dataList.size
|
||||
}
|
||||
|
||||
class ImageItemViewHolder(
|
||||
|
||||
@ -140,7 +140,7 @@ class CommonContentHomeSLideListUi(
|
||||
}
|
||||
|
||||
binding.recyclerView.addOnScrollListener(scrollEventListener.apply {
|
||||
setOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageScrollStateChanged(state: Int) {
|
||||
super.onPageScrollStateChanged(state)
|
||||
|
||||
|
||||
@ -163,7 +163,7 @@ class CommonContentHomeSlideWithCardsUi(
|
||||
}
|
||||
})
|
||||
binding.recyclerView.addOnScrollListener(ScrollEventListener(binding.recyclerView).apply {
|
||||
setOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageSelected(position: Int) {
|
||||
_currentDataPosition = adapter.getDataPosition(position)
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ class NotificationColumnViewHolder(
|
||||
|
||||
private val scrollEventListener by lazy(LazyThreadSafetyMode.NONE) {
|
||||
ScrollEventListener(binding.rvNotification).apply {
|
||||
setOnPageChangeCallback(object : OnPageChangeCallback() {
|
||||
registerOnPageChangeCallback(object : OnPageChangeCallback() {
|
||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
|
||||
if (positionOffset > 0F) {
|
||||
// position 代表的是正在移出屏幕的 itemView 的位置
|
||||
|
||||
@ -132,7 +132,7 @@ class HomeSlideListViewHolder(
|
||||
updateImmersiveColor(slideList[0].placeholderColor.hexStringToIntColor())
|
||||
|
||||
binding.recyclerView.addOnScrollListener(ScrollEventListener(binding.recyclerView).apply {
|
||||
setOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
var lastStatePosition = -1
|
||||
var lastScrollState = RecyclerView.SCROLL_STATE_IDLE
|
||||
|
||||
|
||||
@ -153,7 +153,7 @@ class HomeSlideWithCardsViewHolder(
|
||||
}
|
||||
})
|
||||
binding.recyclerView.addOnScrollListener(ScrollEventListener(binding.recyclerView).apply {
|
||||
setOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
var lastStatePosition = -1
|
||||
var lastScrollState = RecyclerView.SCROLL_STATE_IDLE
|
||||
|
||||
|
||||
@ -5,7 +5,6 @@ import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.forEach
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
@ -15,13 +14,28 @@ import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.video.detail.CustomManager
|
||||
import com.halo.assistant.HaloApp
|
||||
|
||||
class ScrollCalculatorHelper(val mListRv: RecyclerView, private val mPlayId: Int, private val mRangeTop: Int) {
|
||||
class ScrollCalculatorHelper(
|
||||
val mListRv: RecyclerView,
|
||||
private val mPlayId: Int,
|
||||
private val mRangeTop: Int,
|
||||
private var isEnabled: Boolean = true
|
||||
) {
|
||||
|
||||
private var mFirstVisible = -1
|
||||
private var mLastVisible = 0
|
||||
private var mRunnable: PlayRunnable? = null
|
||||
private val mPlayHandler = Handler(Looper.getMainLooper())
|
||||
var currentPlayer: AutomaticVideoView? = null
|
||||
|
||||
fun enableAndPlayIfValid() {
|
||||
isEnabled = true
|
||||
|
||||
if (mListRv.isAttachedToWindow
|
||||
&& mListRv.scrollState == RecyclerView.SCROLL_STATE_IDLE) {
|
||||
playVideo(mListRv)
|
||||
}
|
||||
}
|
||||
|
||||
fun onScrollStateChanged(scrollState: Int) {
|
||||
if (scrollState == RecyclerView.SCROLL_STATE_IDLE) {
|
||||
playVideo(mListRv)
|
||||
@ -80,7 +94,7 @@ class ScrollCalculatorHelper(val mListRv: RecyclerView, private val mPlayId: Int
|
||||
}
|
||||
|
||||
private fun playVideo(view: RecyclerView?) {
|
||||
if (view == null) return
|
||||
if (view == null || !view.isAttachedToWindow || !isEnabled) return
|
||||
val layoutManager = view.layoutManager
|
||||
var gsyBaseVideoPlayer: AutomaticVideoView
|
||||
for (i in mFirstVisible until mLastVisible + 1) {
|
||||
|
||||
@ -130,6 +130,24 @@ object PackagesManager {
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据游戏 ID 获取已安装的信息
|
||||
*
|
||||
* @param gameId 游戏 Id
|
||||
* @return 如果为空:未安装
|
||||
*/
|
||||
fun getInstalledDataByGameId(gameId: String?): GameInstall? {
|
||||
if (TextUtils.isEmpty(gameId)) {
|
||||
return null
|
||||
}
|
||||
for (gameInstall in mInstalledList) {
|
||||
if (gameInstall.id == gameId) {
|
||||
return gameInstall
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断包名是否可以更新
|
||||
|
||||
@ -3,20 +3,12 @@ package com.gh.gamecenter.minigame
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import com.gh.gamecenter.DisplayType
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.SearchActivity
|
||||
import com.gh.gamecenter.SearchType
|
||||
import com.gh.gamecenter.common.base.GlobalActivityManager
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge
|
||||
import com.gh.gamecenter.db.ISearchHistoryDao
|
||||
import com.gh.gamecenter.forum.search.ForumSearchDao
|
||||
import com.gh.gamecenter.search.SearchDefaultFragment
|
||||
import com.gh.gamecenter.search.SearchGameResultFragment
|
||||
import com.lightgame.config.CommonDebug
|
||||
import com.lightgame.listeners.OnBackPressedListener
|
||||
|
||||
/**
|
||||
* 小游戏-搜索页面
|
||||
@ -26,22 +18,21 @@ class MiniGameSearchActivity : SearchActivity() {
|
||||
override fun provideDao(): ISearchHistoryDao = MiniGameSearchDao()
|
||||
|
||||
override fun updateDisplayType(type: DisplayType) {
|
||||
val transaction = supportFragmentManager.beginTransaction()
|
||||
when(type) {
|
||||
DisplayType.DEFAULT -> {
|
||||
val fragment = supportFragmentManager.findFragmentByTag(SearchDefaultFragment::class.java.name)
|
||||
?: MiniGameSearchDefaultFragment().apply {
|
||||
arguments = Bundle().also { it.putBoolean(SearchDefaultFragment.KEY_IS_GAME_SEARCH, true) }
|
||||
}
|
||||
transaction.replace(R.id.search_result, fragment, SearchDefaultFragment::class.java.name)
|
||||
val transaction = when(type) {
|
||||
DisplayType.DEFAULT -> showFragment(
|
||||
SearchDefaultFragment::class.java.name,
|
||||
{ MiniGameSearchDefaultFragment() }
|
||||
) {
|
||||
it.arguments = Bundle().also { bundle ->
|
||||
bundle.putBoolean(SearchDefaultFragment.KEY_IS_GAME_SEARCH, true)
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
val digestListFragment =
|
||||
supportFragmentManager.findFragmentByTag(SearchGameResultFragment::class.java.name) as? MiniGameSearchResultFragment
|
||||
?: MiniGameSearchResultFragment()
|
||||
digestListFragment.setParams(mSearchKey ?: "", mSearchType.value)
|
||||
transaction.replace(R.id.search_result, digestListFragment, SearchGameResultFragment::class.java.name)
|
||||
else -> showFragment(
|
||||
SearchGameResultFragment::class.java.name,
|
||||
{ MiniGameSearchResultFragment() }
|
||||
) {
|
||||
it.setParams(mSearchKey ?: "", mSearchType.value)
|
||||
}
|
||||
}
|
||||
mDisplayType = type
|
||||
|
||||
@ -11,11 +11,9 @@ import com.gh.gamecenter.room.AppDatabase
|
||||
import com.halo.assistant.HaloApp
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
object PackageFilterManager {
|
||||
class PackageFilterManager {
|
||||
|
||||
private var mPackageKey = "" // 用于下次获取包名-游戏信息的 key
|
||||
private val mPendingPackageNameSet by lazy { hashSetOf<String>() } // 因遇到异常而等待下次操作更新的包名列表
|
||||
private val mValidPackageNameSet by lazy { hashSetOf<String>() } // 已被收录的游戏包名列表
|
||||
|
||||
val packageKey: String
|
||||
get() = mPackageKey
|
||||
@ -34,7 +32,7 @@ object PackageFilterManager {
|
||||
) {
|
||||
if (appendOnly) {
|
||||
// 添加因为异常而没能正常更新的包名列表
|
||||
packageList.addAll(mPendingPackageNameSet)
|
||||
packageList.addAll(PackageRepository.mPendingPackageNameSet)
|
||||
}
|
||||
|
||||
RetrofitManager.getInstance()
|
||||
@ -44,12 +42,12 @@ object PackageFilterManager {
|
||||
.subscribe(object : BiResponse<PackageFilter>() {
|
||||
override fun onSuccess(data: PackageFilter) {
|
||||
mPackageKey = data.key
|
||||
mPendingPackageNameSet.clear()
|
||||
PackageRepository.mPendingPackageNameSet.clear()
|
||||
|
||||
val partialPackageList = arrayListOf<String>()
|
||||
|
||||
if (!appendOnly) {
|
||||
mValidPackageNameSet.clear()
|
||||
PackageRepository.mValidPackageNameSet.clear()
|
||||
tryWithDefaultCatch {
|
||||
AppDatabase.getInstance().packageFilterDao().deleteAllPackageName()
|
||||
}
|
||||
@ -63,13 +61,13 @@ object PackageFilterManager {
|
||||
}
|
||||
|
||||
partialPackageList.add(packageName)
|
||||
mValidPackageNameSet.add(packageName)
|
||||
PackageRepository.mValidPackageNameSet.add(packageName)
|
||||
}
|
||||
|
||||
if (appendOnly) {
|
||||
callbackClosure?.invoke(ArrayList(partialPackageList))
|
||||
} else {
|
||||
callbackClosure?.invoke(ArrayList(mValidPackageNameSet))
|
||||
callbackClosure?.invoke(ArrayList(PackageRepository.mValidPackageNameSet))
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,7 +75,7 @@ object PackageFilterManager {
|
||||
super.onFailure(exception)
|
||||
|
||||
if (appendOnly) {
|
||||
mPendingPackageNameSet.addAll(packageList)
|
||||
PackageRepository.mPendingPackageNameSet.addAll(packageList)
|
||||
} else {
|
||||
if (exception is retrofit2.HttpException && exception.code() == 403) {
|
||||
// 403 代表 key 过期,需要重新获取
|
||||
@ -91,28 +89,13 @@ object PackageFilterManager {
|
||||
for (packageEntity in packageEntityList) {
|
||||
// 依然为已安装状态才加入到有效包名列表中
|
||||
if (PackageUtils.isInstalled(HaloApp.getInstance(), packageEntity.packageName)) {
|
||||
mValidPackageNameSet.add(packageEntity.packageName)
|
||||
PackageRepository.mValidPackageNameSet.add(packageEntity.packageName)
|
||||
}
|
||||
}
|
||||
|
||||
callbackClosure?.invoke(ArrayList(mValidPackageNameSet))
|
||||
callbackClosure?.invoke(ArrayList(PackageRepository.mValidPackageNameSet))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 该包名是否有效 (即是否已被光环收录)
|
||||
*/
|
||||
fun isPackageValid(packageName: String): Boolean {
|
||||
return mValidPackageNameSet.contains(packageName)
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存在因为接口异常而导致没有查询收录情况的包名列表
|
||||
*/
|
||||
fun hasPendingPackage(): Boolean {
|
||||
return mPendingPackageNameSet.isEmpty()
|
||||
}
|
||||
|
||||
}
|
||||
@ -6,7 +6,6 @@ import android.text.TextUtils
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.gh.common.filter.RegionSettingHelper
|
||||
import com.gh.gamecenter.feature.utils.ApkActiveUtils
|
||||
import com.gh.common.util.GameUtils
|
||||
import com.gh.common.util.PackageUtils
|
||||
import com.gh.gamecenter.R
|
||||
@ -16,19 +15,29 @@ import com.gh.gamecenter.common.retrofit.BiResponse
|
||||
import com.gh.gamecenter.common.retrofit.ObservableUtil
|
||||
import com.gh.gamecenter.common.retrofit.Response
|
||||
import com.gh.gamecenter.common.utils.secondOrNull
|
||||
import com.gh.gamecenter.common.utils.toArrayList
|
||||
import com.gh.gamecenter.common.utils.tryCatchInRelease
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.entity.*
|
||||
import com.gh.gamecenter.entity.AppEntity
|
||||
import com.gh.gamecenter.entity.GameUpdateEntity
|
||||
import com.gh.gamecenter.entity.PackageGame
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.GameInstall
|
||||
import com.gh.gamecenter.manager.PackagesManager
|
||||
import com.gh.gamecenter.feature.utils.ApkActiveUtils
|
||||
import com.gh.gamecenter.login.user.UserManager
|
||||
import com.gh.gamecenter.manager.PackagesManager
|
||||
import com.gh.gamecenter.packagehelper.PackageRepository.gameInstalled
|
||||
import com.gh.gamecenter.packagehelper.PackageRepository.gameUpdate
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.vspace.VHelper
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.json.JSONException
|
||||
@ -74,6 +83,10 @@ object PackageRepository {
|
||||
fun changeRecentVaPlayed() {
|
||||
_recentVaPlayedChanged.postValue(Unit)
|
||||
}
|
||||
val packageFilterManager = PackageFilterManager()
|
||||
var mPendingPackageNameSet = hashSetOf<String>() // 因遇到异常而等待下次操作更新的包名列表
|
||||
var mValidPackageNameSet = hashSetOf<String>() // 已被收录的游戏包名列表
|
||||
|
||||
|
||||
/**
|
||||
* 预留方法,如果想手动初始化可以调用
|
||||
@ -89,18 +102,51 @@ object PackageRepository {
|
||||
if (gameUpdate.isNotEmpty()) gameUpdate.clear()
|
||||
if (mInstalledPkgSet.isNotEmpty()) mInstalledPkgSet.clear()
|
||||
|
||||
val list = PackageUtils.getAllPackageName(mApplication)
|
||||
Single.zip<Result<Any?>, Result<Any?>, Result<Any?>>(
|
||||
Single.create { emitter ->
|
||||
val list = PackageUtils.getAllPackageName(mApplication)
|
||||
uploadAppList()
|
||||
initFilterPackage(list) { filteredList ->
|
||||
emitter.onSuccess(Result.success(null))
|
||||
|
||||
uploadAppList()
|
||||
mInstalledPkgSet.addAll(filteredList)
|
||||
notifyInstallPkgData()
|
||||
loadInstalledGameDigestAndNotifyData(packageFilterManager.packageKey, filteredList)
|
||||
}
|
||||
|
||||
initFilterPackage(list) { filteredList ->
|
||||
mIsInitialisingData = false
|
||||
|
||||
mInstalledPkgSet.addAll(filteredList)
|
||||
notifyInstallPkgData()
|
||||
},
|
||||
Single.create { emitter ->
|
||||
// 畅玩游戏更新
|
||||
var allGames = VHelper.getAllVGameSnapshots()
|
||||
if (allGames.isEmpty()) {
|
||||
VHelper.refreshVGameSnapshot()
|
||||
allGames = VHelper.getAllVGameSnapshots()
|
||||
}
|
||||
val allGamePkgNames = allGames.map { it.packageName }.toArrayList()
|
||||
if (allGamePkgNames.isNotEmpty()) {
|
||||
val packageFilterManager = PackageFilterManager()
|
||||
updateFilterPackage(packageFilterManager, allGamePkgNames) {
|
||||
emitter.onSuccess(Result.success(null))
|
||||
loadInstalledGameDigestAndNotifyData(
|
||||
packageKey = packageFilterManager.packageKey,
|
||||
filteredList = allGamePkgNames,
|
||||
isVGame = true
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
) { t1, t2 -> Result.success(null) }.subscribe(object : SingleObserver<Result<Any?>> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
}
|
||||
|
||||
loadInstalledGameDigestAndNotifyData(filteredList)
|
||||
}
|
||||
override fun onSuccess(t: Result<Any?>) {
|
||||
mIsInitialisingData = false
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
}
|
||||
})
|
||||
|
||||
loadGhzsUpdate()
|
||||
}
|
||||
@ -113,18 +159,15 @@ object PackageRepository {
|
||||
list: MutableList<String>,
|
||||
callbackClosure: ((list: ArrayList<String>) -> Unit)? = null
|
||||
) {
|
||||
PackageFilterManager.updateFilterPackages(list, false) {
|
||||
callbackClosure?.invoke(it)
|
||||
}
|
||||
packageFilterManager.updateFilterPackages(list, false, callbackClosure)
|
||||
}
|
||||
|
||||
private fun updateFilterPackage(
|
||||
packageFilterManager: PackageFilterManager,
|
||||
list: MutableList<String>,
|
||||
callbackClosure: ((list: ArrayList<String>) -> Unit)? = null
|
||||
) {
|
||||
PackageFilterManager.updateFilterPackages(list, true) {
|
||||
callbackClosure?.invoke(it)
|
||||
}
|
||||
packageFilterManager.updateFilterPackages(list, true, callbackClosure)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -135,7 +178,8 @@ object PackageRepository {
|
||||
PackageUtils.getGhVersionName(),
|
||||
PackageUtils.getGhVersionCode(),
|
||||
HaloApp.getInstance().channel,
|
||||
Build.VERSION.SDK_INT)
|
||||
Build.VERSION.SDK_INT
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Response<AppEntity>() {
|
||||
@ -208,6 +252,7 @@ object PackageRepository {
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
private fun loadInstalledGameDigestAndNotifyData(
|
||||
packageKey: String,
|
||||
filteredList: ArrayList<String>,
|
||||
isVGame: Boolean = false,
|
||||
updateInstallStatus: Boolean = false
|
||||
@ -222,7 +267,7 @@ object PackageRepository {
|
||||
}, Any())
|
||||
|
||||
while (++page <= maxPageCount) {
|
||||
var observable = mNewApi.getPackageGames(PackageFilterManager.packageKey, page, PAGE_SIZE)
|
||||
var observable = mNewApi.getPackageGames(packageKey, page, PAGE_SIZE)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
observable.subscribe(object : BiResponse<List<PackageGame>>() {
|
||||
@ -238,7 +283,8 @@ object PackageRepository {
|
||||
}
|
||||
|
||||
for (game in validGames) {
|
||||
val shouldNotifyChanges = validateGameAndPostChanges(gh_id, game, pkgName, isVGame, updateInstallStatus)
|
||||
val shouldNotifyChanges =
|
||||
validateGameAndPostChanges(gh_id, game, pkgName, isVGame, updateInstallStatus)
|
||||
if (!isNotifyUpdate && shouldNotifyChanges) {
|
||||
isNotifyUpdate = true
|
||||
}
|
||||
@ -259,11 +305,13 @@ object PackageRepository {
|
||||
/**
|
||||
* 验证游戏并且更新数据
|
||||
*/
|
||||
private fun validateGameAndPostChanges(ghId: Any?,
|
||||
game: GameEntity,
|
||||
pkgName: String,
|
||||
isVGame: Boolean,
|
||||
updateInstallStatus: Boolean): Boolean {
|
||||
private fun validateGameAndPostChanges(
|
||||
ghId: Any?,
|
||||
game: GameEntity,
|
||||
pkgName: String,
|
||||
isVGame: Boolean,
|
||||
updateInstallStatus: Boolean
|
||||
): Boolean {
|
||||
if (ghId == null || ghId == game.id) {
|
||||
gameInstalled.add(GameInstall.transformGameInstall(game, pkgName, isVGame))
|
||||
mInstalledGameList.add(game)
|
||||
@ -272,7 +320,8 @@ object PackageRepository {
|
||||
addCurrentlyInstalledVersionIfValid(game)
|
||||
|
||||
if (updateInstallStatus) {
|
||||
EventBus.getDefault().post(EBPackage(EBPackage.TYPE_INSTALLED, pkgName, game.getApk().firstOrNull()?.version))
|
||||
EventBus.getDefault()
|
||||
.post(EBPackage(EBPackage.TYPE_INSTALLED, pkgName, game.getApk().firstOrNull()?.version))
|
||||
}
|
||||
|
||||
if (isCanUpdate || isCanPluggable) {
|
||||
@ -356,7 +405,8 @@ object PackageRepository {
|
||||
) {
|
||||
// 使用了镜像的游戏;插件化关闭的游戏;无需插件化
|
||||
if (game.shouldUseMirrorInfo()
|
||||
|| apk.plugin == "close") {
|
||||
|| apk.plugin == "close"
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -416,8 +466,11 @@ object PackageRepository {
|
||||
* @param pkgName 已安装的游戏包名
|
||||
* @param cachedGameEntity 缓存的游戏实体,若存在免去再请求接口的过程
|
||||
*/
|
||||
fun addInstalledGame(pkgName: String,
|
||||
cachedGameEntity: GameEntity? = null) {
|
||||
fun addInstalledGame(
|
||||
packageFilterManager: PackageFilterManager,
|
||||
pkgName: String,
|
||||
cachedGameEntity: GameEntity? = null
|
||||
) {
|
||||
mInstalledPkgSet.add(pkgName)
|
||||
notifyInstallPkgData()
|
||||
|
||||
@ -428,7 +481,8 @@ object PackageRepository {
|
||||
game = cachedGameEntity,
|
||||
pkgName = pkgName,
|
||||
isVGame = false,
|
||||
updateInstallStatus = false)
|
||||
updateInstallStatus = false
|
||||
)
|
||||
|
||||
if (containsUpdate) {
|
||||
notifyGameUpdateData()
|
||||
@ -436,8 +490,9 @@ object PackageRepository {
|
||||
} else {
|
||||
val list = arrayListOf(pkgName)
|
||||
|
||||
updateFilterPackage(list) {
|
||||
updateFilterPackage(packageFilterManager, list) {
|
||||
loadInstalledGameDigestAndNotifyData(
|
||||
packageKey = packageFilterManager.packageKey,
|
||||
filteredList = list,
|
||||
updateInstallStatus = false
|
||||
)
|
||||
@ -453,9 +508,11 @@ object PackageRepository {
|
||||
* @param isVGame 是否为畅玩游戏
|
||||
* @param updateInstallStatus 是否更新安装状态
|
||||
*/
|
||||
fun addInstalledGames(pkgNameList: ArrayList<String>,
|
||||
isVGame: Boolean = false,
|
||||
updateInstallStatus: Boolean = false,
|
||||
fun addInstalledGames(
|
||||
packageFilterManager: PackageFilterManager,
|
||||
pkgNameList: ArrayList<String>,
|
||||
isVGame: Boolean = false,
|
||||
updateInstallStatus: Boolean = false,
|
||||
) {
|
||||
// 畅玩游戏不添加至本地的已安装包名列表中
|
||||
if (!isVGame) {
|
||||
@ -465,8 +522,9 @@ object PackageRepository {
|
||||
}
|
||||
notifyInstallPkgData()
|
||||
|
||||
updateFilterPackage(pkgNameList) {
|
||||
updateFilterPackage(packageFilterManager, pkgNameList) {
|
||||
loadInstalledGameDigestAndNotifyData(
|
||||
packageKey = packageFilterManager.packageKey,
|
||||
filteredList = pkgNameList,
|
||||
isVGame = isVGame,
|
||||
updateInstallStatus = updateInstallStatus
|
||||
@ -526,6 +584,13 @@ object PackageRepository {
|
||||
changeRecentVaPlayed()
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存在因为接口异常而导致没有查询收录情况的包名列表
|
||||
*/
|
||||
fun hasPendingPackage(): Boolean {
|
||||
return mPendingPackageNameSet.isEmpty()
|
||||
}
|
||||
|
||||
private fun notifyGameInstallData() {
|
||||
PackagesManager.initGameInstall(ArrayList(gameInstalled))
|
||||
gameInstalledLiveData.postValue(ArrayList(gameInstalled))
|
||||
|
||||
@ -63,7 +63,13 @@ class PackageViewModel(
|
||||
* @param cachedGameEntity 缓存的游戏实体
|
||||
*/
|
||||
fun addInstalledGame(pkgName: String?, cachedGameEntity: GameEntity? = null) {
|
||||
if (!TextUtils.isEmpty(pkgName)) mRepository.addInstalledGame(pkgName!!, cachedGameEntity)
|
||||
if (!TextUtils.isEmpty(pkgName)) {
|
||||
mRepository.addInstalledGame(
|
||||
mRepository.packageFilterManager,
|
||||
pkgName!!,
|
||||
cachedGameEntity
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -81,9 +87,7 @@ class PackageViewModel(
|
||||
// 未同意获取已安装应用权限时不进行数据初始化
|
||||
if (!PackageHelper.isGetInstalledPackagesAgreed()) return
|
||||
|
||||
if (mRepository.gameInstalled.size == 0
|
||||
|| PackageFilterManager.hasPendingPackage()
|
||||
) {
|
||||
if (mRepository.gameInstalled.size == 0 || mRepository.hasPendingPackage()) {
|
||||
PackageHelper.initPackageRelatedData();
|
||||
}
|
||||
}
|
||||
|
||||
@ -855,7 +855,7 @@ class HaloPersonalFragment : BaseLazyFragment() {
|
||||
}
|
||||
})
|
||||
addOnScrollListener(ScrollEventListener(this).apply {
|
||||
setOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
|
||||
super.onPageScrolled(position, positionOffset, positionOffsetPixels)
|
||||
mStubBinding.bannerIndicator.onPageScrolled(
|
||||
|
||||
@ -10,20 +10,20 @@ import android.view.View
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.gh.common.util.*
|
||||
import com.gh.gamecenter.CropImageActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
|
||||
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.entity.ErrorEntity
|
||||
import com.gh.gamecenter.feature.selector.LocalMediaActivity
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.utils.*
|
||||
import com.gh.gamecenter.databinding.FragmentBackgroundPreviewBinding
|
||||
import com.gh.gamecenter.feature.entity.BackgroundImageEntity
|
||||
import com.gh.gamecenter.feature.selector.ChooseType
|
||||
import com.gh.gamecenter.login.user.UserManager
|
||||
import com.gh.gamecenter.login.user.UserViewModel
|
||||
import com.gh.gamecenter.qa.editor.LocalMediaActivity
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.zhihu.matisse.Matisse
|
||||
import io.reactivex.Single
|
||||
@ -282,7 +282,7 @@ class BackgroundPreviewFragment : ToolbarFragment() {
|
||||
startActivityForResult(
|
||||
LocalMediaActivity.getIntent(
|
||||
requireContext(),
|
||||
LocalMediaActivity.ChooseType.IMAGE,
|
||||
ChooseType.IMAGE,
|
||||
1,
|
||||
"个性背景"
|
||||
), MEDIA_STORE_REQUEST
|
||||
|
||||
@ -12,12 +12,13 @@ import com.gh.gamecenter.CropImageActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
|
||||
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
|
||||
import com.gh.gamecenter.feature.selector.LocalMediaActivity
|
||||
import com.gh.gamecenter.common.utils.PermissionHelper
|
||||
import com.gh.gamecenter.common.utils.viewModelProvider
|
||||
import com.gh.gamecenter.common.view.GridSpacingItemColorDecoration
|
||||
import com.gh.gamecenter.databinding.PersonalityBackgroundFragmentBinding
|
||||
import com.gh.gamecenter.feature.selector.ChooseType
|
||||
import com.gh.gamecenter.login.user.UserViewModel
|
||||
import com.gh.gamecenter.qa.editor.LocalMediaActivity
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.zhihu.matisse.Matisse
|
||||
|
||||
@ -75,7 +76,7 @@ class PersonalityBackgroundFragment : ToolbarFragment() {
|
||||
startActivityForResult(
|
||||
LocalMediaActivity.getIntent(
|
||||
requireContext(),
|
||||
LocalMediaActivity.ChooseType.IMAGE,
|
||||
ChooseType.IMAGE,
|
||||
1,
|
||||
"个性背景"
|
||||
), MEDIA_STORE_REQUEST
|
||||
|
||||
@ -28,6 +28,7 @@ import com.gh.gamecenter.common.baselist.ListAdapter
|
||||
import com.gh.gamecenter.common.baselist.ListFragment
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts.KEY_COMMENT_ID
|
||||
import com.gh.gamecenter.common.eventbus.EBReuse
|
||||
import com.gh.gamecenter.feature.selector.LocalMediaActivity
|
||||
import com.gh.gamecenter.common.syncpage.SyncDataEntity
|
||||
import com.gh.gamecenter.common.syncpage.SyncFieldConstants
|
||||
import com.gh.gamecenter.common.syncpage.SyncPageRepository
|
||||
@ -38,10 +39,10 @@ import com.gh.gamecenter.databinding.ItemCommentEditImageBinding
|
||||
import com.gh.gamecenter.eventbus.EBCommentSuccess
|
||||
import com.gh.gamecenter.feature.entity.CommentEntity
|
||||
import com.gh.gamecenter.feature.eventbus.EBDeleteComment
|
||||
import com.gh.gamecenter.feature.selector.ChooseType
|
||||
import com.gh.gamecenter.qa.comment.CommentActivity.Companion.GAME_COLLECTION_ID
|
||||
import com.gh.gamecenter.qa.comment.CommentActivity.Companion.GAME_COLLECTION_TITLE
|
||||
import com.gh.gamecenter.qa.comment.CommentActivity.Companion.QUESTION_ID
|
||||
import com.gh.gamecenter.qa.editor.LocalMediaActivity
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Util_System_Keyboard
|
||||
import com.lightgame.utils.Utils
|
||||
@ -494,7 +495,7 @@ open class NewCommentFragment : ListFragment<CommentEntity, NewCommentViewModel>
|
||||
val maxChooseCount = 9 - mViewModel.pictureList.size
|
||||
val intent = LocalMediaActivity.getIntent(
|
||||
requireContext(),
|
||||
LocalMediaActivity.ChooseType.IMAGE,
|
||||
ChooseType.IMAGE,
|
||||
maxChooseCount,
|
||||
"评论列表"
|
||||
)
|
||||
@ -521,11 +522,6 @@ open class NewCommentFragment : ListFragment<CommentEntity, NewCommentViewModel>
|
||||
return
|
||||
}
|
||||
|
||||
if (mShowInputOnly) {
|
||||
// Fuck pm
|
||||
MtaHelper.onEvent("帖子详情", "评论详情-全部回复", "发送")
|
||||
}
|
||||
|
||||
mViewModel.postPictureAndComment(content, mCommentEntity)
|
||||
}
|
||||
|
||||
|
||||
@ -1,148 +0,0 @@
|
||||
package com.gh.gamecenter.qa.editor
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.database.Cursor
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ImageView
|
||||
import android.widget.PopupWindow
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.gh.gamecenter.common.base.activity.ToolBarActivity
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.utils.updateStatusBarColor
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.zhihu.matisse.Matisse
|
||||
import com.zhihu.matisse.MimeType
|
||||
import com.zhihu.matisse.internal.entity.Album
|
||||
import com.zhihu.matisse.internal.entity.SelectionSpec
|
||||
import com.zhihu.matisse.internal.model.AlbumCollection
|
||||
|
||||
/**
|
||||
* 选择本地视频/图片
|
||||
*/
|
||||
class LocalMediaActivity : ToolBarActivity(), AlbumCollection.AlbumCallbacks {
|
||||
private var mLocalMediaFragment: LocalMediaFragment? = null
|
||||
private lateinit var mAlbumsSpinner: VideoAlbumsSpanner
|
||||
private lateinit var mAlbumsAdapter: VideoAlbumsAdapter
|
||||
private val mAlbumCollection = AlbumCollection()
|
||||
private var mIsFirstAlbumLoad = true
|
||||
private var mChooseType = ""
|
||||
|
||||
override fun getLayoutId(): Int = R.layout.activity_video_tablayout_viewpager
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
updateStatusBarColor(R.color.ui_surface, R.color.ui_surface)
|
||||
mChooseType = intent.getStringExtra(EntranceConsts.KEY_TYPE) ?: ""
|
||||
if (mChooseType == ChooseType.VIDEO.value) {
|
||||
setNavigationTitle("本地视频")
|
||||
} else {
|
||||
setNavigationTitle("本地图片")
|
||||
}
|
||||
mLocalMediaFragment = LocalMediaFragment().apply { arguments = intent.extras }
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.container, mLocalMediaFragment!!, LocalMediaFragment::class.java.name)
|
||||
.commitAllowingStateLoss()
|
||||
initAlbumsSpinner()
|
||||
mTitleTv.setOnClickListener {
|
||||
mAlbumsSpinner.show(findViewById<View>(R.id.container).height)
|
||||
setPhotoNavigationTitle(true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun initAlbumsSpinner() {
|
||||
mAlbumsSpinner = VideoAlbumsSpanner(this)
|
||||
mAlbumsAdapter = VideoAlbumsAdapter(this)
|
||||
|
||||
mAlbumsSpinner.setPopupAnchorView(findViewById(R.id.normal_toolbar))
|
||||
mAlbumsSpinner.setAdapter(mAlbumsAdapter)
|
||||
mAlbumsSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||
mAlbumCollection.setStateCurrentSelection(position)
|
||||
mAlbumsAdapter.cursor.moveToPosition(position)
|
||||
val album = Album.valueOf(mAlbumsAdapter.cursor)
|
||||
if (album.isAll && SelectionSpec.getInstance().capture) {
|
||||
album.addCaptureCount()
|
||||
}
|
||||
if (mLocalMediaFragment?.isAdded == true) {
|
||||
mLocalMediaFragment?.loadVideos(album)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mAlbumsSpinner.setDismissListener(PopupWindow.OnDismissListener {
|
||||
setPhotoNavigationTitle(false)
|
||||
})
|
||||
//必须加这行代码,[SelectionSpec]是单例模式,下次使用必须先更新MimeType
|
||||
val mimeType = if (mChooseType == ChooseType.VIDEO.value) {
|
||||
MimeType.ofVideo()
|
||||
} else {
|
||||
MimeType.ofImage()
|
||||
}
|
||||
val maxChooseCount = intent.getIntExtra(EntranceConsts.KEY_CHOOSE_MAX_COUNT, 1)
|
||||
Matisse.from(this).choose(mimeType).showSingleMediaType(true).maxSelectable(maxChooseCount)
|
||||
mAlbumCollection.onCreate(this, this)
|
||||
mAlbumCollection.loadAlbums()
|
||||
}
|
||||
|
||||
override fun onAlbumLoad(cursor: Cursor?) {
|
||||
if (mIsFirstAlbumLoad) {
|
||||
mIsFirstAlbumLoad = false
|
||||
mAlbumsAdapter.swapCursor(cursor)
|
||||
mBaseHandler.post {
|
||||
cursor?.moveToPosition(mAlbumCollection.currentSelection)
|
||||
val album = Album.valueOf(cursor)
|
||||
if (album.isAll && SelectionSpec.getInstance().capture) {
|
||||
album.addCaptureCount()
|
||||
}
|
||||
if (mLocalMediaFragment?.isAdded == true) {
|
||||
mLocalMediaFragment?.loadVideos(album)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onAlbumReset() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
private fun setPhotoNavigationTitle(up: Boolean) {
|
||||
val drawable = ContextCompat.getDrawable(
|
||||
HaloApp.getInstance().application,
|
||||
if (up) R.drawable.ic_video_arrow_up else R.drawable.ic_video_arrow_down
|
||||
)
|
||||
val arrowIv = findViewById<ImageView>(R.id.arrowIv)
|
||||
arrowIv?.setImageDrawable(drawable)
|
||||
}
|
||||
|
||||
override fun isAutoResetViewBackgroundEnabled(): Boolean = true
|
||||
|
||||
override fun onDarkModeChanged() {
|
||||
super.onDarkModeChanged()
|
||||
updateStatusBarColor(R.color.ui_surface, R.color.ui_surface)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getIntent(context: Context, chooseType: ChooseType, maxChooseCount: Int = 1, entrance: String): Intent {
|
||||
return Intent(context, LocalMediaActivity::class.java).apply {
|
||||
putExtra(EntranceConsts.KEY_TYPE, chooseType.value)
|
||||
putExtra(EntranceConsts.KEY_CHOOSE_MAX_COUNT, maxChooseCount)
|
||||
putExtra(EntranceConsts.KEY_ENTRANCE, entrance)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class ChooseType(val value: String) {
|
||||
VIDEO("video"),
|
||||
IMAGE("image")
|
||||
}
|
||||
}
|
||||
@ -1,95 +0,0 @@
|
||||
package com.gh.gamecenter.qa.editor
|
||||
|
||||
import android.content.Context
|
||||
import android.database.Cursor
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
|
||||
import com.gh.common.util.*
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.core.utils.TimeUtils
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.common.utils.goneIf
|
||||
import com.gh.gamecenter.common.utils.toDrawable
|
||||
import com.gh.gamecenter.common.utils.ImageUtils
|
||||
import com.gh.gamecenter.databinding.LocalVideoItemBinding
|
||||
import com.zhihu.matisse.internal.entity.Item
|
||||
import com.zhihu.matisse.internal.ui.adapter.RecyclerViewCursorAdapter
|
||||
import com.zhihu.matisse.internal.utils.PathUtils
|
||||
|
||||
class LocalMediaAdapter(
|
||||
val context: Context,
|
||||
val mChooseType: String,
|
||||
val maxChooseSize: Int,
|
||||
val entrance: String,
|
||||
val callback: (ArrayList<Item>) -> Unit
|
||||
) : RecyclerViewCursorAdapter<LocalVideoPreviewViewHolder>(null) {
|
||||
private val mSelectedMediaList = arrayListOf<Item>()
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LocalVideoPreviewViewHolder {
|
||||
val view = LayoutInflater.from(parent.context).inflate(R.layout.local_video_item, parent, false)
|
||||
return LocalVideoPreviewViewHolder(LocalVideoItemBinding.bind(view))
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: LocalVideoPreviewViewHolder, cursor: Cursor?, position: Int) {
|
||||
val item = Item.valueOf(cursor)
|
||||
holder.binding.durationTv.goneIf(mChooseType == LocalMediaActivity.ChooseType.IMAGE.value)
|
||||
val path = "file:///${PathUtils.getPath(context, item.contentUri)}"
|
||||
ImageUtils.displayResizeMedia(holder.binding.preview, path, 200, 200)
|
||||
holder.binding.durationTv.text = TimeUtils.formatVideoDuration(item.duration / 1000)
|
||||
val drawable = if (mSelectedMediaList.contains(item)) {
|
||||
if (maxChooseSize == 1) {
|
||||
R.drawable.ic_choose_media_selected.toDrawable()
|
||||
} else {
|
||||
R.drawable.ic_choose_media_bg.toDrawable()
|
||||
}
|
||||
} else {
|
||||
R.drawable.ic_choose_media_normal.toDrawable()
|
||||
}
|
||||
holder.binding.checkImageView.setImageDrawable(drawable)
|
||||
if (mSelectedMediaList.contains(item) && maxChooseSize > 1) {
|
||||
holder.binding.chooseCountTv.visibility = View.VISIBLE
|
||||
holder.binding.chooseCountTv.text = (mSelectedMediaList.indexOf(item) + 1).toString()
|
||||
} else {
|
||||
holder.binding.chooseCountTv.visibility = View.GONE
|
||||
}
|
||||
holder.itemView.setOnClickListener {
|
||||
if (mSelectedMediaList.contains(item)) {
|
||||
mSelectedMediaList.remove(item)
|
||||
notifyDataSetChanged()
|
||||
callback.invoke(mSelectedMediaList)
|
||||
} else {
|
||||
if (maxChooseSize == 1) {
|
||||
mSelectedMediaList.clear()
|
||||
}
|
||||
if (mSelectedMediaList.size < maxChooseSize) {
|
||||
mSelectedMediaList.add(item)
|
||||
notifyDataSetChanged()
|
||||
callback.invoke(mSelectedMediaList)
|
||||
} else {
|
||||
if (mChooseType == LocalMediaActivity.ChooseType.IMAGE.value) {
|
||||
ToastUtils.showToast("至多选择${maxChooseSize}张图片")
|
||||
} else {
|
||||
ToastUtils.showToast("至多选择${maxChooseSize}条视频")
|
||||
}
|
||||
}
|
||||
}
|
||||
if (entrance == "发帖子" || entrance == "发提问帖" || entrance == "发视频帖") {
|
||||
val publishContentType = if (entrance == "发帖子") "帖子" else if (entrance == "发提问帖") "提问帖" else "视频帖"
|
||||
val publishMediaType = if (mChooseType == LocalMediaActivity.ChooseType.IMAGE.value) "图片" else "视频"
|
||||
NewLogUtils.logChooseMedia("click_radio_button", publishContentType, publishMediaType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int, cursor: Cursor?): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
fun getSelectedMediaList(): ArrayList<Item> {
|
||||
return mSelectedMediaList
|
||||
}
|
||||
}
|
||||
|
||||
class LocalVideoPreviewViewHolder(val binding: LocalVideoItemBinding) : BaseRecyclerViewHolder<Any>(binding.root)
|
||||
@ -1,191 +0,0 @@
|
||||
package com.gh.gamecenter.qa.editor
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.database.Cursor
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.gh.common.util.NewLogUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.fragment.BaseFragment
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.common.utils.toColor
|
||||
import com.gh.gamecenter.common.utils.tryWithDefaultCatch
|
||||
import com.gh.gamecenter.common.view.GridSpacingItemDecoration
|
||||
import com.gh.gamecenter.core.utils.MD5Utils
|
||||
import com.gh.gamecenter.databinding.FragmentLocalMediaBinding
|
||||
import com.gh.gamecenter.entity.LocalVideoEntity
|
||||
import com.zhihu.matisse.internal.entity.Album
|
||||
import com.zhihu.matisse.internal.entity.Item
|
||||
import com.zhihu.matisse.internal.model.AlbumMediaCollection
|
||||
import com.zhihu.matisse.internal.model.SelectedItemCollection
|
||||
import com.zhihu.matisse.internal.ui.BasePreviewActivity
|
||||
import com.zhihu.matisse.internal.ui.SelectedPreviewActivity
|
||||
import com.zhihu.matisse.internal.utils.PathUtils
|
||||
import com.zhihu.matisse.ui.MatisseActivity
|
||||
|
||||
class LocalMediaFragment : BaseFragment<Any>(), AlbumMediaCollection.AlbumMediaCallbacks {
|
||||
private lateinit var mBinding: FragmentLocalMediaBinding
|
||||
private lateinit var mAdapter: LocalMediaAdapter
|
||||
private var mAlbumMediaCollection: AlbumMediaCollection? = null
|
||||
private var mChooseType = ""
|
||||
|
||||
override fun getLayoutId(): Int = 0
|
||||
|
||||
override fun getInflatedLayout(): View {
|
||||
mBinding = FragmentLocalMediaBinding.inflate(LayoutInflater.from(requireContext()), null, false)
|
||||
return mBinding.root
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
mChooseType = arguments?.getString(EntranceConsts.KEY_TYPE) ?: ""
|
||||
// mBinding.reuseNoneData.reuseNoneDataTv.text = "暂无数据~"
|
||||
mBinding.listRv.layoutManager = GridLayoutManager(requireContext(), 3)
|
||||
mBinding.listRv.addItemDecoration(GridSpacingItemDecoration(3, 4F.dip2px(), false))
|
||||
val maxChooseCount = arguments?.getInt(EntranceConsts.KEY_CHOOSE_MAX_COUNT, 1)
|
||||
mAdapter = LocalMediaAdapter(
|
||||
requireContext(), mChooseType, maxChooseCount
|
||||
?: 1, mEntrance
|
||||
) {
|
||||
mBinding.previewTv.isEnabled = it.isNotEmpty()
|
||||
mBinding.confirmTv.isEnabled = it.isNotEmpty()
|
||||
if (it.isEmpty()) {
|
||||
mBinding.previewTv.setTextColor(R.color.text_instance.toColor(requireContext()))
|
||||
mBinding.confirmTv.alpha = 0.6f
|
||||
} else {
|
||||
mBinding.previewTv.setTextColor(R.color.text_secondary.toColor(requireContext()))
|
||||
mBinding.confirmTv.alpha = 1f
|
||||
}
|
||||
mBinding.numTv.text = "(${it.size}/${mAdapter.maxChooseSize})"
|
||||
}
|
||||
mBinding.numTv.text = "(0/${mAdapter.maxChooseSize})"
|
||||
mBinding.listRv.adapter = mAdapter
|
||||
mBinding.listRefresh.isEnabled = false
|
||||
|
||||
val publishContentType = if (mEntrance == "发帖子") "帖子" else if (mEntrance == "发提问帖") "提问帖" else "视频帖"
|
||||
val publishMediaType = if (mChooseType == LocalMediaActivity.ChooseType.IMAGE.value) "图片" else "视频"
|
||||
mBinding.previewTv.setOnClickListener {
|
||||
if (mChooseType == LocalMediaActivity.ChooseType.VIDEO.value) {
|
||||
val intent = PreviewVideoActivity.getIntent(requireContext(), mAdapter.getSelectedMediaList())
|
||||
requireActivity().startActivityForResult(intent, PREVIEW_VIDEO)
|
||||
NewLogUtils.logChooseMedia("click_preview", publishContentType, publishMediaType)
|
||||
} else {
|
||||
val intent = Intent(requireContext(), SelectedPreviewActivity::class.java)
|
||||
val bundle = bundleOf(
|
||||
SelectedItemCollection.STATE_SELECTION to mAdapter.getSelectedMediaList(),
|
||||
SelectedItemCollection.STATE_COLLECTION_TYPE to SelectedItemCollection.COLLECTION_IMAGE
|
||||
)
|
||||
intent.putExtra(BasePreviewActivity.EXTRA_DEFAULT_BUNDLE, bundle)
|
||||
startActivityForResult(intent, PREVIEW_IMAGE)
|
||||
}
|
||||
|
||||
}
|
||||
mBinding.confirmTv.setOnClickListener {
|
||||
NewLogUtils.logChooseMedia("click_confirm", publishContentType, publishMediaType)
|
||||
val intent = Intent()
|
||||
if (mChooseType == LocalMediaActivity.ChooseType.VIDEO.value) {
|
||||
val localVideoList = arrayListOf<LocalVideoEntity>()
|
||||
mAdapter.getSelectedMediaList().forEach {
|
||||
val path = PathUtils.getPath(requireContext(), it.contentUri)
|
||||
if (path == null) {
|
||||
toast("视频已不存在,请重新选择")
|
||||
return@forEach
|
||||
}
|
||||
val id = MD5Utils.getUrlMD5(path) + System.currentTimeMillis()
|
||||
val format = getFileFormat(it.mimeType)
|
||||
localVideoList.add(
|
||||
LocalVideoEntity(
|
||||
id,
|
||||
path,
|
||||
contentUri = it.contentUri,
|
||||
duration = it.duration,
|
||||
format = format,
|
||||
size = it.size
|
||||
)
|
||||
)
|
||||
}
|
||||
intent.putExtra(LocalVideoEntity::class.java.name, localVideoList)
|
||||
} else {
|
||||
val data = mAdapter.getSelectedMediaList().map { it.contentUri }.toList()
|
||||
val path = data.map { PathUtils.getPath(requireContext(), it) }.toList()
|
||||
intent.putParcelableArrayListExtra(MatisseActivity.EXTRA_RESULT_SELECTION, ArrayList<Uri>(data))
|
||||
intent.putStringArrayListExtra(MatisseActivity.EXTRA_RESULT_SELECTION_PATH, ArrayList<String>(path))
|
||||
}
|
||||
requireActivity().setResult(Activity.RESULT_OK, intent)
|
||||
requireActivity().finish()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getFileFormat(mimeType: String?): String {
|
||||
var format = ""
|
||||
tryWithDefaultCatch {
|
||||
if (mimeType != null) {
|
||||
val split = mimeType.split("/")
|
||||
format = if (split.count() >= 2) {
|
||||
split[1]
|
||||
} else {
|
||||
mimeType
|
||||
}
|
||||
}
|
||||
}
|
||||
return format
|
||||
}
|
||||
|
||||
override fun onAlbumMediaReset() {
|
||||
mAdapter.swapCursor(null)
|
||||
}
|
||||
|
||||
override fun onAlbumMediaLoad(cursor: Cursor?) {
|
||||
mAdapter.swapCursor(cursor)
|
||||
mBinding.reuseNoneData.reuseNoneData.visibility = View.GONE
|
||||
mBinding.reuseLlLoading.root.visibility = View.GONE
|
||||
mBinding.reuseNoConnection.root.visibility = View.GONE
|
||||
mBinding.listRefresh.isRefreshing = false
|
||||
}
|
||||
|
||||
fun loadVideos(album: Album) {
|
||||
mAlbumMediaCollection?.onDestroy()
|
||||
|
||||
mAlbumMediaCollection = AlbumMediaCollection()
|
||||
mAlbumMediaCollection?.onCreate(requireActivity(), this@LocalMediaFragment)
|
||||
|
||||
mAlbumMediaCollection?.load(album)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (data == null) return
|
||||
if (requestCode == PREVIEW_IMAGE) {
|
||||
val bundleExtra = data.getBundleExtra(BasePreviewActivity.EXTRA_RESULT_BUNDLE)
|
||||
val resultApply = data.getBooleanExtra(BasePreviewActivity.EXTRA_RESULT_APPLY, false)
|
||||
val items = bundleExtra?.getParcelableArrayList<Item>(SelectedItemCollection.STATE_SELECTION)
|
||||
if (resultApply && !items.isNullOrEmpty()) {
|
||||
mAdapter.getSelectedMediaList().clear()
|
||||
mAdapter.getSelectedMediaList().addAll(items)
|
||||
mAdapter.notifyDataSetChanged()
|
||||
mBinding.numTv.text = "(${items.size}/${mAdapter.maxChooseSize})"
|
||||
}
|
||||
|
||||
} else if (requestCode == PREVIEW_VIDEO) {
|
||||
requireActivity().setResult(Activity.RESULT_OK, data)
|
||||
requireActivity().finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mAlbumMediaCollection?.onDestroy()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val PREVIEW_VIDEO = 100
|
||||
const val PREVIEW_IMAGE = 101
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
package com.gh.gamecenter.qa.editor
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.R
|
||||
import com.zhihu.matisse.internal.entity.Item
|
||||
|
||||
class PreviewVideoActivity : BaseActivity() {
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_amway
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
DisplayUtils.transparentStatusBar(this)
|
||||
|
||||
val containerFragment = supportFragmentManager.findFragmentByTag(PreviewVideoFragment::class.java.name)
|
||||
?: PreviewVideoFragment().with(intent.extras)
|
||||
// 若 placeholder 外层为 RelativeLayout 的话,会出现莫名的偏移
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.placeholder, containerFragment, PreviewVideoFragment::class.java.name)
|
||||
.commitAllowingStateLoss()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getIntent(context: Context, videos: ArrayList<Item>): Intent {
|
||||
val intent = Intent(context, PreviewVideoActivity::class.java)
|
||||
intent.putExtra(EntranceConsts.KEY_VIDEO_LIST, videos)
|
||||
return intent
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,229 +0,0 @@
|
||||
package com.gh.gamecenter.qa.editor
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder
|
||||
import com.facebook.drawee.generic.RoundingParams
|
||||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
import com.gh.gamecenter.common.base.fragment.BaseFragment
|
||||
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
|
||||
import com.gh.gamecenter.common.view.GridSpacingItemColorDecoration
|
||||
import com.gh.gamecenter.CropImageActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.utils.*
|
||||
import com.gh.gamecenter.databinding.FragmentPreviewVideoBinding
|
||||
import com.gh.gamecenter.databinding.ItemVideoSelectorBinding
|
||||
import com.gh.gamecenter.entity.LocalVideoEntity
|
||||
import com.gh.gamecenter.video.poster.PosterEditActivity
|
||||
import com.gh.gamecenter.video.upload.view.UploadVideoActivity
|
||||
import com.lightgame.adapter.BaseRecyclerAdapter
|
||||
import com.shuyu.gsyvideoplayer.GSYVideoManager
|
||||
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
|
||||
import com.zhihu.matisse.internal.entity.Item
|
||||
import com.zhihu.matisse.internal.utils.PathUtils
|
||||
|
||||
class PreviewVideoFragment : BaseFragment<Any>() {
|
||||
private lateinit var mBinding: FragmentPreviewVideoBinding
|
||||
private var mVideoItems: ArrayList<Item> = arrayListOf()
|
||||
private var mProcessingDialog: WaitingDialogFragment? = null
|
||||
private lateinit var mVideoSelectorAdapter: VideoSelectorAdapter
|
||||
private val mLocalVideoList = arrayListOf<LocalVideoEntity>()
|
||||
override fun getLayoutId(): Int = 0
|
||||
|
||||
override fun getInflatedLayout(): View {
|
||||
mBinding = FragmentPreviewVideoBinding.inflate(LayoutInflater.from(requireContext()), null, false)
|
||||
return mBinding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
mVideoItems = arguments?.getParcelableArrayList<Item>(EntranceConsts.KEY_VIDEO_LIST)
|
||||
?: arrayListOf()
|
||||
if (mVideoItems.isNotEmpty()) {
|
||||
mVideoItems.forEach {
|
||||
val path = PathUtils.getPath(requireContext(), it.contentUri)
|
||||
val id = MD5Utils.getUrlMD5(path) + System.currentTimeMillis()
|
||||
val format = getFileFormat(it.mimeType)
|
||||
val localVideoEntity = LocalVideoEntity(
|
||||
id = id,
|
||||
filePath = path,
|
||||
contentUri = it.contentUri,
|
||||
duration = it.duration,
|
||||
format = format,
|
||||
size = it.size
|
||||
)
|
||||
mLocalVideoList.add(localVideoEntity)
|
||||
}
|
||||
initVideo(mLocalVideoList[0])
|
||||
}
|
||||
mBinding.numTv.text = "(1/${mVideoItems.size})"
|
||||
mVideoSelectorAdapter = VideoSelectorAdapter(requireContext(), mLocalVideoList) { entity, position ->
|
||||
mBinding.videoView.release()
|
||||
mBinding.numTv.text = "(${position + 1}/${mVideoItems.size})"
|
||||
initVideo(entity)
|
||||
}
|
||||
mBinding.videoSelectorRv.adapter = mVideoSelectorAdapter
|
||||
mBinding.videoSelectorRv.layoutManager =
|
||||
LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
|
||||
mBinding.videoSelectorRv.addItemDecoration(
|
||||
GridSpacingItemColorDecoration(
|
||||
requireContext(),
|
||||
4,
|
||||
0,
|
||||
R.color.transparent
|
||||
)
|
||||
)
|
||||
mBinding.confirmTv.setOnClickListener {
|
||||
val intent = Intent()
|
||||
intent.putExtra(LocalVideoEntity::class.java.name, mLocalVideoList)
|
||||
requireActivity().setResult(Activity.RESULT_OK, intent)
|
||||
requireActivity().finish()
|
||||
}
|
||||
|
||||
mBinding.changeCoverTv.setOnClickListener {
|
||||
val item = mVideoItems[mVideoSelectorAdapter.selectPosition]
|
||||
val intent =
|
||||
PosterEditActivity.getIntentByPath(requireContext(), PathUtils.getPath(requireContext(), item.uri))
|
||||
startActivityForResult(intent, UploadVideoActivity.REQUEST_CODE_IMAGE_CROP)
|
||||
}
|
||||
mBinding.backBtn.setOnClickListener { requireActivity().finish() }
|
||||
}
|
||||
|
||||
private fun getFileFormat(mimeType: String?): String {
|
||||
var format = ""
|
||||
tryWithDefaultCatch {
|
||||
if (mimeType != null) {
|
||||
val split = mimeType.split("/")
|
||||
format = if (split.count() >= 2) {
|
||||
split[1]
|
||||
} else {
|
||||
mimeType
|
||||
}
|
||||
}
|
||||
}
|
||||
return format
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (data == null || resultCode != Activity.RESULT_OK) return
|
||||
if (requestCode == UploadVideoActivity.REQUEST_CODE_IMAGE_CROP) {
|
||||
val imagePath = data.getStringExtra(CropImageActivity.RESULT_CLIP_PATH) ?: ""
|
||||
if (imagePath.isNotEmpty()) {
|
||||
uploadImage(imagePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun uploadImage(imagePath: String) {
|
||||
mProcessingDialog = WaitingDialogFragment.newInstance("图片上传中...", false)
|
||||
mProcessingDialog?.show(requireActivity().supportFragmentManager, WaitingDialogFragment::class.java.name)
|
||||
UploadImageUtils.uploadImage(
|
||||
UploadImageUtils.UploadType.poster,
|
||||
imagePath,
|
||||
object : UploadImageUtils.OnUploadImageListener {
|
||||
override fun onSuccess(imageUrl: String) {
|
||||
mProcessingDialog?.dismiss()
|
||||
mLocalVideoList[mVideoSelectorAdapter.selectPosition].poster = imageUrl
|
||||
mBinding.videoView.updateThumb(imageUrl)
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable?) {
|
||||
mProcessingDialog?.dismiss()
|
||||
ToastUtils.showToast("上传失败")
|
||||
}
|
||||
|
||||
override fun onProgress(total: Long, progress: Long) {}
|
||||
})
|
||||
}
|
||||
|
||||
private fun initVideo(entity: LocalVideoEntity) {
|
||||
GSYVideoOptionBuilder()
|
||||
.setIsTouchWiget(false)
|
||||
.setUrl(entity.filePath)
|
||||
.setRotateViewAuto(false)
|
||||
.setCacheWithPlay(false)
|
||||
.setRotateWithSystem(false)
|
||||
.setReleaseWhenLossAudio(true)
|
||||
.setLooping(false)
|
||||
.setShowFullAnimation(false)
|
||||
.build(mBinding.videoView)
|
||||
if (entity.poster.isNotEmpty()) {
|
||||
mBinding.videoView.updateThumb(entity.poster)
|
||||
} else {
|
||||
mBinding.videoView.updateThumb("file:///${PathUtils.getPath(requireContext(), entity.contentUri)}")
|
||||
}
|
||||
}
|
||||
|
||||
class VideoSelectorAdapter(
|
||||
context: Context,
|
||||
val localVideoList: ArrayList<LocalVideoEntity>,
|
||||
val callback: (LocalVideoEntity, Int) -> Unit
|
||||
) : BaseRecyclerAdapter<RecyclerView.ViewHolder>(context) {
|
||||
var selectPosition: Int = 0
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
return VideoSelectorViewHolder(
|
||||
ItemVideoSelectorBinding.inflate(
|
||||
LayoutInflater.from(mContext),
|
||||
parent,
|
||||
false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = localVideoList.size
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
if (holder is VideoSelectorViewHolder) {
|
||||
val item = localVideoList[position]
|
||||
holder.binding.previewBorder.goneIf(selectPosition != position)
|
||||
setPreviewBorder(holder.binding.preview, selectPosition == position)
|
||||
ImageUtils.display(holder.binding.preview, "file:///${PathUtils.getPath(mContext, item.contentUri)}")
|
||||
holder.binding.root.setOnClickListener {
|
||||
selectPosition = position
|
||||
callback.invoke(localVideoList[selectPosition], selectPosition)
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setPreviewBorder(view: SimpleDraweeView, isSelected: Boolean) {
|
||||
val params = RoundingParams()
|
||||
params.setBorder(
|
||||
if (isSelected) R.color.black.toColor() else R.color.transparent.toColor(),
|
||||
if (isSelected) 1f.dip2px().toFloat() else 0f
|
||||
)
|
||||
params.setCornersRadius(4f.dip2px().toFloat())
|
||||
val build = GenericDraweeHierarchyBuilder.newInstance(mContext.resources)
|
||||
.setRoundingParams(params)
|
||||
.build()
|
||||
view.hierarchy = build
|
||||
}
|
||||
}
|
||||
|
||||
class VideoSelectorViewHolder(val binding: ItemVideoSelectorBinding) : RecyclerView.ViewHolder(binding.root)
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
GSYVideoManager.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
GSYVideoManager.onPause()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
GSYVideoManager.releaseAllVideos()
|
||||
}
|
||||
}
|
||||
@ -24,8 +24,10 @@ import com.gh.gamecenter.common.base.fragment.ToolbarFragment
|
||||
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.entity.CommunityEntity
|
||||
import com.gh.gamecenter.common.entity.LocalVideoEntity
|
||||
import com.gh.gamecenter.common.entity.NotificationUgc
|
||||
import com.gh.gamecenter.common.mvvm.Status
|
||||
import com.gh.gamecenter.feature.selector.LocalMediaActivity
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.runOnUiThread
|
||||
@ -34,6 +36,7 @@ import com.gh.gamecenter.databinding.FragmentVideoPublishBinding
|
||||
import com.gh.gamecenter.entity.*
|
||||
import com.gh.gamecenter.feature.entity.ForumVideoEntity
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.selector.ChooseType
|
||||
import com.gh.gamecenter.login.user.UserManager
|
||||
import com.gh.gamecenter.qa.BbsType
|
||||
import com.gh.gamecenter.qa.dialog.ChooseActivityDialogFragment
|
||||
@ -41,7 +44,6 @@ import com.gh.gamecenter.qa.dialog.ChooseForumActivity
|
||||
import com.gh.gamecenter.qa.dialog.ChooseSectionDialogFragment
|
||||
import com.gh.gamecenter.qa.dialog.InputUrlDialogFragment
|
||||
import com.gh.gamecenter.qa.editor.GameActivity
|
||||
import com.gh.gamecenter.qa.editor.LocalMediaActivity
|
||||
import com.gh.gamecenter.video.poster.PosterEditActivity
|
||||
import com.gh.gamecenter.video.upload.OnUploadListener
|
||||
import com.gh.gamecenter.video.upload.UploadManager
|
||||
@ -117,7 +119,7 @@ class VideoPublishFragment : ToolbarFragment(), KeyboardHeightObserver {
|
||||
startActivityForResult(
|
||||
LocalMediaActivity.getIntent(
|
||||
requireContext(),
|
||||
LocalMediaActivity.ChooseType.VIDEO,
|
||||
ChooseType.VIDEO,
|
||||
1,
|
||||
"发视频帖"
|
||||
), BaseRichEditorActivity.INSERT_MEDIA_VIDEO_CODE
|
||||
@ -285,7 +287,7 @@ class VideoPublishFragment : ToolbarFragment(), KeyboardHeightObserver {
|
||||
startActivityForResult(
|
||||
LocalMediaActivity.getIntent(
|
||||
requireContext(),
|
||||
LocalMediaActivity.ChooseType.VIDEO,
|
||||
ChooseType.VIDEO,
|
||||
1,
|
||||
"发视频帖"
|
||||
), BaseRichEditorActivity.INSERT_MEDIA_VIDEO_CODE
|
||||
|
||||
@ -29,6 +29,7 @@ import com.gh.gamecenter.entity.DeviceDialogEntity;
|
||||
import com.gh.gamecenter.entity.DialogEntity;
|
||||
import com.gh.gamecenter.entity.DiscoveryGameCardEntity;
|
||||
import com.gh.gamecenter.entity.DiscoveryGameCardLabel;
|
||||
import com.gh.gamecenter.entity.DiverterEntity;
|
||||
import com.gh.gamecenter.entity.FollowCommonContentCollection;
|
||||
import com.gh.gamecenter.entity.FollowDynamicEntity;
|
||||
import com.gh.gamecenter.entity.FollowUserEntity;
|
||||
@ -107,6 +108,7 @@ import com.gh.gamecenter.feature.entity.BackgroundImageEntity;
|
||||
import com.gh.gamecenter.feature.entity.CommentEntity;
|
||||
import com.gh.gamecenter.feature.entity.CommentnumEntity;
|
||||
import com.gh.gamecenter.feature.entity.ConcernEntity;
|
||||
import com.gh.gamecenter.feature.entity.FloatingWindowEntity;
|
||||
import com.gh.gamecenter.feature.entity.ForumVideoEntity;
|
||||
import com.gh.gamecenter.feature.entity.GameEntity;
|
||||
import com.gh.gamecenter.feature.entity.LibaoEntity;
|
||||
@ -126,7 +128,6 @@ import com.gh.gamecenter.feature.entity.SimulatorEntity;
|
||||
import com.gh.gamecenter.feature.entity.UserEntity;
|
||||
import com.gh.gamecenter.feature.entity.ViewsEntity;
|
||||
import com.gh.gamecenter.feature.entity.WXSubscribeMsgConfig;
|
||||
import com.gh.gamecenter.feature.entity.FloatingWindowEntity;
|
||||
import com.gh.gamecenter.gamedetail.entity.BigEvent;
|
||||
import com.gh.gamecenter.gamedetail.entity.NewGameDetailEntity;
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageData;
|
||||
@ -3358,7 +3359,7 @@ public interface ApiService {
|
||||
* 页面数据聚合[底部tab+多tab导航页+默认数据]
|
||||
*/
|
||||
@GET("app/data_union")
|
||||
Single<DataUnionEntity> getDataUnion();
|
||||
Single<DataUnionEntity> getDataUnion(@Query("diverter") String diverter);
|
||||
|
||||
/**
|
||||
* 底部tab
|
||||
@ -3390,4 +3391,16 @@ public interface ApiService {
|
||||
*/
|
||||
@GET("game_lists/hot_columns")
|
||||
Single<List<SubjectEntity>> getHotColumns();
|
||||
|
||||
/**
|
||||
* 分流器列表信息
|
||||
*/
|
||||
@GET("app/{module}/diverter")
|
||||
Single<List<DiverterEntity>> getDiverterList(@Header("Install-First-Access") String isInstallFirstAccess, @Path("module") String module);
|
||||
|
||||
/**
|
||||
* 访问分流页面,更新分流访问次数
|
||||
*/
|
||||
@PATCH("app/{module}/diverter_visit_time")
|
||||
Single<ResponseBody> patchDiverterVisitTime(@Path("module") String module, @Body RequestBody body);
|
||||
}
|
||||
@ -1,9 +1,6 @@
|
||||
package com.gh.gamecenter.search
|
||||
|
||||
import android.graphics.Color
|
||||
import android.graphics.LinearGradient
|
||||
import android.graphics.Shader
|
||||
import android.graphics.Typeface
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
@ -18,7 +15,6 @@ import androidx.viewpager.widget.PagerAdapter
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.exposure.ExposureManager
|
||||
import com.gh.common.filter.RegionSettingHelper
|
||||
import com.gh.common.util.DirectUtils
|
||||
import com.gh.common.util.NewFlatLogUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.fragment.BaseFragment
|
||||
@ -34,7 +30,7 @@ import com.gh.gamecenter.databinding.TabItemSearchDefaultRankBinding
|
||||
import com.gh.gamecenter.db.ISearchHistoryDao
|
||||
import com.gh.gamecenter.db.SearchHistoryDao
|
||||
import com.gh.gamecenter.eventbus.EBSearch
|
||||
import com.gh.gamecenter.feature.entity.HotTagEntity
|
||||
import com.gh.gamecenter.feature.entity.DiscoveryTagEntity
|
||||
import com.gh.gamecenter.feature.entity.SettingsEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.google.android.flexbox.FlexboxLayout
|
||||
@ -46,7 +42,7 @@ import org.json.JSONObject
|
||||
|
||||
open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
|
||||
private var mHotTagList: List<HotTagEntity>? = null
|
||||
private var mSearchDiscoveryTagList: List<DiscoveryTagEntity>? = null
|
||||
protected var mRankList: List<SettingsEntity.Search.RankList>? = null
|
||||
|
||||
protected lateinit var mBinding: FragmentSearchDefaultBinding
|
||||
@ -63,28 +59,28 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
// FlexboxLayout:maxLine 不符合需求
|
||||
protected val mFlexMaxHeight = DisplayUtils.dip2px(57F)
|
||||
|
||||
private val mHotTagClickListener: (Int) -> Unit = {
|
||||
val tag = mHotTagList!![it]
|
||||
NewFlatLogUtils.logSearchHotTagClick(
|
||||
tag.name ?: "",
|
||||
tag.type ?: "",
|
||||
tag.link ?: "",
|
||||
tag.text ?: ""
|
||||
)
|
||||
DataLogUtils.uploadHotTagLog(context, tag.name)
|
||||
PageSwitchDataHelper.pushCurrentPageData(
|
||||
hashMapOf(
|
||||
Pair(PageSwitchDataHelper.PAGE_BUSINESS_TYPE, "游戏搜索-热门标签"),
|
||||
Pair(PageSwitchDataHelper.PAGE_BUSINESS_ID, tag.id ?: ""),
|
||||
Pair(PageSwitchDataHelper.PAGE_BUSINESS_NAME, tag.name ?: " ")
|
||||
private val mSearchDiscoveryTagClickListener: (Int) -> Unit = {
|
||||
val tag = mSearchDiscoveryTagList!![it]
|
||||
val keyword = tag.keyword
|
||||
if (keyword.isNotEmpty()) {
|
||||
PageSwitchDataHelper.pushCurrentPageData(
|
||||
hashMapOf(
|
||||
Pair(PageSwitchDataHelper.PAGE_BUSINESS_TYPE, "游戏搜索-搜索发现"),
|
||||
Pair(PageSwitchDataHelper.PAGE_BUSINESS_ID, tag.id ?: ""),
|
||||
Pair(PageSwitchDataHelper.PAGE_BUSINESS_NAME, tag.text ?: " ")
|
||||
)
|
||||
)
|
||||
)
|
||||
SensorsBridge.trackEvent("SearchLabelClick", "label_name", tag.name ?: "", "label_id", tag.id ?: "")
|
||||
val exposureEvent = ExposureEvent.createEvent(
|
||||
null,
|
||||
source = listOf(ExposureSource("首页搜索", ""), ExposureSource("热门标签", tag.name ?: ""))
|
||||
)
|
||||
DirectUtils.directToLinkPage(requireContext(), tag, "(搜索-${tag.name})", "", exposureEvent) // 不需要path
|
||||
SensorsBridge.trackEvent("SearchLabelClick", "label_name", tag.text ?: "", "label_id", tag.id ?: "")
|
||||
SensorsBridge.trackSearchDiscoveryClick(
|
||||
labelName = tag.text ?: "",
|
||||
labelId = tag.id ?: "",
|
||||
searchContent = keyword,
|
||||
position = it
|
||||
)
|
||||
mViewModel?.add(keyword)
|
||||
EventBus.getDefault().post(EBSearch("history", keyword))
|
||||
Util_System_Keyboard.hideSoftKeyboardByIBinder(context, mBinding.historyFlex.windowToken)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
@ -137,16 +133,16 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
}
|
||||
mViewModel?.isExistRankList = mRankList?.isNotEmpty() == true
|
||||
|
||||
mHotTagList = Config.getSettings()?.search?.hotTag
|
||||
mViewModel?.isExistHotTag = mHotTagList?.isNotEmpty() == true
|
||||
mSearchDiscoveryTagList = Config.getSettings()?.search?.discoveryTag
|
||||
mViewModel?.isExistSearchDiscoveryTag = mSearchDiscoveryTagList?.isNotEmpty() == true
|
||||
|
||||
updateHistorySearchView(null)
|
||||
mViewModel?.historySearchLiveData?.observe(viewLifecycleOwner) {
|
||||
updateHistorySearchView(it)
|
||||
}
|
||||
|
||||
mBinding.hotTagFlexContainer.setLimitHeight(mFlexMaxHeight)
|
||||
createFlexContent(mBinding.hotTagFlex, getTagListString(), true, clickListener = mHotTagClickListener)
|
||||
mBinding.searchDiscoveryTagFlexContainer.setLimitHeight(mFlexMaxHeight)
|
||||
createFlexContent(mBinding.searchDiscoveryTagFlex, getTagListString(), clickListener = mSearchDiscoveryTagClickListener)
|
||||
initHeadView()
|
||||
initRankViewPager()
|
||||
}
|
||||
@ -175,12 +171,12 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
})
|
||||
}
|
||||
}
|
||||
mBinding.hotHeadContainer.headTitle.text = getString(R.string.search_hot)
|
||||
mBinding.hotHeadContainer.headTitle.textSize = 16F
|
||||
mBinding.hotHeadContainer.headActionTv.visibility = View.GONE
|
||||
mBinding.hotTagHeadContainer.headTitle.text = getString(R.string.search_hot_tag)
|
||||
mBinding.hotTagHeadContainer.headTitle.textSize = 16F
|
||||
mBinding.hotTagHeadContainer.headActionTv.visibility = View.GONE
|
||||
mBinding.searchDiscoveryHeadContainer.headTitle.text = getString(R.string.search_hot)
|
||||
mBinding.searchDiscoveryHeadContainer.headTitle.textSize = 16F
|
||||
mBinding.searchDiscoveryHeadContainer.headActionTv.visibility = View.GONE
|
||||
mBinding.searchDiscoveryTagHeadContainer.headTitle.text = getString(R.string.search_discovery_tag)
|
||||
mBinding.searchDiscoveryTagHeadContainer.headTitle.textSize = 16F
|
||||
mBinding.searchDiscoveryTagHeadContainer.headActionTv.visibility = View.GONE
|
||||
}
|
||||
|
||||
protected open fun initRankViewPager() {
|
||||
@ -315,8 +311,8 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
mBinding.historyHeadContainer.root.visibility =
|
||||
if (mViewModel?.isExistHistory == true) View.VISIBLE else View.GONE
|
||||
mBinding.historyFlex.visibility = if (mViewModel?.isExistHistory == true) View.VISIBLE else View.GONE
|
||||
mBinding.hotTagHeadContainer.root.layoutParams =
|
||||
(mBinding.hotTagHeadContainer.root.layoutParams as ConstraintLayout.LayoutParams).apply {
|
||||
mBinding.searchDiscoveryTagHeadContainer.root.layoutParams =
|
||||
(mBinding.searchDiscoveryTagHeadContainer.root.layoutParams as ConstraintLayout.LayoutParams).apply {
|
||||
setMargins(
|
||||
0,
|
||||
if (mViewModel?.isExistHistory == true) 16F.dip2px() else 0,
|
||||
@ -324,21 +320,21 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
0
|
||||
)
|
||||
}
|
||||
mBinding.hotHeadContainer.root.layoutParams =
|
||||
(mBinding.hotHeadContainer.root.layoutParams as ConstraintLayout.LayoutParams).apply {
|
||||
mBinding.searchDiscoveryHeadContainer.root.layoutParams =
|
||||
(mBinding.searchDiscoveryHeadContainer.root.layoutParams as ConstraintLayout.LayoutParams).apply {
|
||||
setMargins(
|
||||
0,
|
||||
if (mViewModel?.isExistHistory == false && mViewModel?.isExistHotTag == false) 16F.dip2px() else 0,
|
||||
if (mViewModel?.isExistHistory == false && mViewModel?.isExistSearchDiscoveryTag == false) 16F.dip2px() else 0,
|
||||
0,
|
||||
0
|
||||
)
|
||||
}
|
||||
mBinding.hotTagHeadContainer.root.visibility =
|
||||
if (mViewModel?.isExistHotTag == true) View.VISIBLE else View.GONE
|
||||
mBinding.hotTagFlex.visibility = if (mViewModel?.isExistHotTag == true) View.VISIBLE else View.GONE
|
||||
mBinding.hotHeadContainer.root.visibility =
|
||||
mBinding.searchDiscoveryTagHeadContainer.root.visibility =
|
||||
if (mViewModel?.isExistSearchDiscoveryTag == true) View.VISIBLE else View.GONE
|
||||
mBinding.searchDiscoveryTagFlex.visibility = if (mViewModel?.isExistSearchDiscoveryTag == true) View.VISIBLE else View.GONE
|
||||
mBinding.searchDiscoveryHeadContainer.root.visibility =
|
||||
if (mViewModel?.isExistHotSearch == true) View.VISIBLE else View.GONE
|
||||
mBinding.hotList.visibility = if (mViewModel?.isExistHotSearch == true) View.VISIBLE else View.GONE
|
||||
mBinding.searchDiscoveryList.visibility = if (mViewModel?.isExistHotSearch == true) View.VISIBLE else View.GONE
|
||||
mBinding.rankTabLayout.visibility = if (mViewModel?.isExistRankList == true) View.VISIBLE else View.GONE
|
||||
mBinding.rankTabIndicator.visibility = if (mViewModel?.isExistRankList == true) View.VISIBLE else View.GONE
|
||||
mBinding.rankViewPager.visibility = if (mViewModel?.isExistRankList == true) View.VISIBLE else View.GONE
|
||||
@ -360,9 +356,9 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
|
||||
private fun getTagListString(): List<String> {
|
||||
val list = ArrayList<String>()
|
||||
if (mHotTagList != null) {
|
||||
for (entity in mHotTagList!!) {
|
||||
entity.name?.let { list.add(it) }
|
||||
if (mSearchDiscoveryTagList != null) {
|
||||
for (entity in mSearchDiscoveryTagList!!) {
|
||||
entity.text?.let { list.add(it) }
|
||||
}
|
||||
}
|
||||
return list
|
||||
@ -371,7 +367,6 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
fun createFlexContent(
|
||||
flexView: FlexboxLayout,
|
||||
contentList: List<String>?,
|
||||
isHotTag: Boolean = false,
|
||||
clickListener: (Int) -> Unit
|
||||
) {
|
||||
|
||||
@ -385,16 +380,12 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
val params = FlexboxLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 24F.dip2px())
|
||||
flexCell.layoutParams = params
|
||||
|
||||
if (isHotTag && !mHotTagList.isNullOrEmpty() && mHotTagList!![index].isGuessSearch) {
|
||||
createSmartHotTagStyle(flexCell, contentList[index])
|
||||
} else {
|
||||
flexCell.setSingleLine()
|
||||
flexCell.ellipsize = TextUtils.TruncateAt.END
|
||||
flexCell.gravity = Gravity.CENTER
|
||||
flexCell.textSize = 12F
|
||||
flexCell.text = StringUtils.shrinkStringWithDot(contentList[index], 6)
|
||||
flexCell.setTextColor(R.color.text_secondary.toColor(requireContext()))
|
||||
}
|
||||
flexCell.setSingleLine()
|
||||
flexCell.ellipsize = TextUtils.TruncateAt.END
|
||||
flexCell.gravity = Gravity.CENTER
|
||||
flexCell.textSize = 12F
|
||||
flexCell.text = StringUtils.shrinkStringWithDot(contentList[index], 6)
|
||||
flexCell.setTextColor(R.color.text_secondary.toColor(requireContext()))
|
||||
flexCell.setPadding(8F.dip2px(), 0, 8F.dip2px(), 0)
|
||||
flexCell.background = if (mIsDarkModeOn) GradientDrawable().apply {
|
||||
setStroke(0.5F.dip2px(), Color.parseColor("#21FFFFFF"))
|
||||
@ -406,30 +397,6 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun createSmartHotTagStyle(flexCell: TextView, name: String) {
|
||||
flexCell.setDrawableStart(R.drawable.ic_smart_search)
|
||||
flexCell.compoundDrawablePadding = 4F.dip2px()
|
||||
flexCell.gravity = Gravity.CENTER_VERTICAL
|
||||
flexCell.typeface = Typeface.DEFAULT_BOLD
|
||||
flexCell.textSize = 12F
|
||||
flexCell.text = StringUtils.shrinkStringWithDot(name, 6)
|
||||
flexCell.setTextColor(Color.WHITE)
|
||||
val colors =
|
||||
intArrayOf(R.color.text_FFB749.toColor(requireContext()), R.color.text_FF6D3C.toColor(requireContext()))
|
||||
val position = floatArrayOf(0F, 1F)
|
||||
val linearGradient = LinearGradient(
|
||||
0F,
|
||||
0F,
|
||||
flexCell.paint.textSize * flexCell.text.length,
|
||||
0F,
|
||||
colors,
|
||||
position,
|
||||
Shader.TileMode.CLAMP
|
||||
)
|
||||
flexCell.paint.shader = linearGradient
|
||||
flexCell.invalidate()
|
||||
}
|
||||
|
||||
private fun postExposureEvent(index: Int) {
|
||||
mRankList?.safelyGetInRelease(index)?.content?.forEach {
|
||||
if (it.link.type == "game") {
|
||||
@ -444,17 +411,24 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
|
||||
super.onDarkModeChanged()
|
||||
initHeadView()
|
||||
mBinding.rootContainer.setBackgroundColor(R.color.ui_surface.toColor(requireContext()))
|
||||
mBinding.hotList.adapter?.run {
|
||||
mBinding.searchDiscoveryList.adapter?.run {
|
||||
notifyItemRangeChanged(0, itemCount)
|
||||
}
|
||||
mViewModel?.historySearchLiveData?.value?.let { updateHistorySearchView(it) }
|
||||
createFlexContent(mBinding.hotTagFlex, getTagListString(), true, clickListener = mHotTagClickListener)
|
||||
createFlexContent(mBinding.searchDiscoveryTagFlex, getTagListString(), clickListener = mSearchDiscoveryTagClickListener)
|
||||
}
|
||||
|
||||
protected open fun provideDao(): ISearchHistoryDao = SearchHistoryDao(requireContext().applicationContext)
|
||||
|
||||
protected open fun provideAdapter(pageRatio: Float): PagerAdapter =
|
||||
SearchDefaultRankListAdapter(requireContext(), mRankList!!, pageRatio, mIsGameSearch, mSourceEntrance)
|
||||
SearchDefaultRankListAdapter(
|
||||
requireContext(),
|
||||
mViewModel!!,
|
||||
mRankList!!,
|
||||
pageRatio,
|
||||
mIsGameSearch,
|
||||
mSourceEntrance
|
||||
)
|
||||
|
||||
private fun provideViewModel(): SearchDefaultViewModel {
|
||||
val factory = SearchDefaultViewModel.Factory(provideDao())
|
||||
|
||||
@ -6,23 +6,27 @@ import android.view.ViewGroup
|
||||
import com.gh.common.util.DirectUtils
|
||||
import com.gh.common.util.NewFlatLogUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.SearchType
|
||||
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.databinding.SearchDefaultRankItemBinding
|
||||
import com.gh.gamecenter.eventbus.EBSearch
|
||||
import com.gh.gamecenter.feature.entity.SettingsEntity
|
||||
import com.lightgame.adapter.BaseRecyclerAdapter
|
||||
import com.lightgame.utils.Util_System_Keyboard
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
|
||||
class SearchDefaultRankAdapter(
|
||||
context: Context,
|
||||
private val mViewModel: SearchDefaultViewModel,
|
||||
private val mRankList: SettingsEntity.Search.RankList,
|
||||
private val mIsGameSearch: Boolean,
|
||||
private val mIsGameSearch: Boolean
|
||||
) : BaseRecyclerAdapter<SearchDefaultRankAdapter.SearchDefaultRankItemViewHolder>(context) {
|
||||
|
||||
override fun getItemCount() = minOf(mRankList.content.size, 10)
|
||||
override fun getItemCount() = minOf(mRankList.content.size, 20)
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
|
||||
SearchDefaultRankItemViewHolder(parent.toBinding())
|
||||
@ -34,7 +38,8 @@ class SearchDefaultRankAdapter(
|
||||
icon.goneIf(!mRankList.isShowIcon) {
|
||||
icon.display(if (rank.link.type == "game") gameEntity?.icon else rank.icon)
|
||||
}
|
||||
name.text = if (rank.link.type == "game") gameEntity?.name else rank.name.ifBlank { rank.link.text }
|
||||
val labelName = if (rank.link.type == "game") gameEntity?.name else rank.name.ifBlank { rank.link.text }
|
||||
name.text = labelName
|
||||
index.run {
|
||||
typeface = Typeface.createFromAsset(mContext.assets, Constants.DIN_FONT_PATH)
|
||||
text = (position + 1).toString()
|
||||
@ -60,18 +65,31 @@ class SearchDefaultRankAdapter(
|
||||
root.setOnClickListener {
|
||||
val linkEntity = rank.link
|
||||
|
||||
DirectUtils.directToLinkPage(
|
||||
mContext,
|
||||
linkEntity,
|
||||
"游戏搜索-搜索榜单",
|
||||
"${mRankList.title}-${rank.name}",
|
||||
rank.exposureEvent
|
||||
)
|
||||
if (linkEntity.type == "game_search") {
|
||||
mViewModel.add(linkEntity.text ?: "")
|
||||
EventBus.getDefault().post(EBSearch(SearchType.RANK.value, linkEntity.text))
|
||||
} else {
|
||||
DirectUtils.directToLinkPage(
|
||||
mContext,
|
||||
linkEntity,
|
||||
"游戏搜索-搜索榜单",
|
||||
"${mRankList.title}-${rank.name}",
|
||||
rank.exposureEvent
|
||||
)
|
||||
}
|
||||
|
||||
Util_System_Keyboard.hideSoftKeyboardByIBinder(mContext, it.windowToken)
|
||||
|
||||
// 是否来源于游戏搜索
|
||||
if (mIsGameSearch) {
|
||||
val searchType = if (linkEntity.type == "game_search") {
|
||||
SearchType.RANK.toChinese()
|
||||
} else {
|
||||
""
|
||||
}
|
||||
NewFlatLogUtils.logSearchClickRankDetail(
|
||||
linkEntity.link ?: "",
|
||||
searchType,
|
||||
rank.name,
|
||||
(position + 1).toString(),
|
||||
linkEntity.link ?: "",
|
||||
@ -89,6 +107,8 @@ class SearchDefaultRankAdapter(
|
||||
|
||||
val trackEvent = JSONObject()
|
||||
try {
|
||||
trackEvent.put("text", labelName)
|
||||
trackEvent.put("search_content", linkEntity.link)
|
||||
trackEvent.put("game_name", gameEntity?.name)
|
||||
trackEvent.put("game_id", gameEntity?.id)
|
||||
trackEvent.put("list_name", mRankList.title)
|
||||
|
||||
@ -11,6 +11,7 @@ import com.gh.gamecenter.feature.entity.SettingsEntity
|
||||
|
||||
class SearchDefaultRankListAdapter(
|
||||
private val mContext: Context,
|
||||
private val mViewModel: SearchDefaultViewModel,
|
||||
private val mRankList: List<SettingsEntity.Search.RankList>,
|
||||
private val mPageWidth: Float,
|
||||
private val mIsGameSearch: Boolean,
|
||||
@ -31,7 +32,7 @@ class SearchDefaultRankListAdapter(
|
||||
|
||||
view!!.findViewById<RecyclerView>(R.id.rankContainer).run {
|
||||
layoutManager = LinearLayoutManager(mContext)
|
||||
adapter = SearchDefaultRankAdapter(mContext, mRankList[position], mIsGameSearch)
|
||||
adapter = SearchDefaultRankAdapter(mContext, mViewModel, mRankList[position], mIsGameSearch)
|
||||
}
|
||||
return view
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ class SearchDefaultViewModel(private val dao: ISearchHistoryDao) : ViewModel() {
|
||||
|
||||
val historySearchLiveData = MutableLiveData<List<String>>()
|
||||
var isExistHotSearch: Boolean = false
|
||||
var isExistHotTag: Boolean = false
|
||||
var isExistSearchDiscoveryTag: Boolean = false
|
||||
var isExistHistory: Boolean = false
|
||||
var isExistRankList: Boolean = false
|
||||
|
||||
|
||||
@ -76,7 +76,7 @@ class SearchSubjectItemViewHolder(var binding: SearchSubjectItemBinding) : Recyc
|
||||
val exposureSources = arrayListOf<ExposureSource>().apply {
|
||||
add(ExposureSource("首页搜索"))
|
||||
add(ExposureSource(type, key))
|
||||
add(ExposureSource("专题", entity.name))
|
||||
add(ExposureSource("专题", "${entity.name}+${entity.columnId}"))
|
||||
}
|
||||
val exposureEvent = ExposureEvent.createEvent(game, exposureSources)
|
||||
exposureList.add(exposureEvent)
|
||||
|
||||
@ -68,6 +68,12 @@ class SearchGameResultAdapter(
|
||||
|
||||
val positionAndPackageMap = HashMap<String, Int>()
|
||||
|
||||
private val adIdSet = hashSetOf<String>() // 记录展示过的广告id
|
||||
|
||||
fun clearAdIdSet() {
|
||||
adIdSet.clear()
|
||||
}
|
||||
|
||||
override fun setListData(updateData: MutableList<SearchItemData>?) {
|
||||
exposureEventArray = SparseArray(updateData?.size ?: 0)
|
||||
// 记录游戏位置
|
||||
@ -216,6 +222,7 @@ class SearchGameResultAdapter(
|
||||
|
||||
is SearchGameAdItemViewHolder -> {
|
||||
val adEntity = mEntityList[position].ad
|
||||
val adConfig = mEntityList[position].adConfig
|
||||
val slotId = adEntity?.slotId ?: ""
|
||||
val adContainer = holder.binding.adContainer
|
||||
val screenWidthInDp = DisplayUtils.getScreenWidthInDp(fragment.activity)
|
||||
@ -224,7 +231,36 @@ class SearchGameResultAdapter(
|
||||
// 广告 slotId 没有变,不管它
|
||||
} else {
|
||||
adContainer.tag = slotId
|
||||
AdDelegateHelper.requestThirdPartyFlowAd(fragment, slotId, adContainer, screenWidthInDp) {
|
||||
val onAdShowAction: () -> Unit = {
|
||||
if (!adIdSet.contains(adConfig?.id)) {
|
||||
SensorsBridge.trackEvent("ThirdPartyAdShow",
|
||||
json {
|
||||
"ad_source" to adEntity?.sourceName
|
||||
"ad_id" to slotId
|
||||
"ad_format" to adConfig?.typeChinese
|
||||
"ad_placement" to "搜索结果"
|
||||
"ad_space_id" to adConfig?.id
|
||||
"ad_space_name" to adConfig?.name
|
||||
"position" to adConfig?.position
|
||||
}
|
||||
)
|
||||
}
|
||||
adIdSet.add(adConfig?.id ?: "")
|
||||
}
|
||||
val onAdClickAction = {
|
||||
SensorsBridge.trackEvent("ThirdPartyAdClick",
|
||||
json {
|
||||
"ad_source" to adEntity?.sourceName
|
||||
"ad_id" to slotId
|
||||
"ad_format" to adConfig?.typeChinese
|
||||
"ad_placement" to "搜索结果"
|
||||
"ad_space_id" to adConfig?.id
|
||||
"ad_space_name" to adConfig?.name
|
||||
"position" to adConfig?.position
|
||||
}
|
||||
)
|
||||
}
|
||||
AdDelegateHelper.requestThirdPartyFlowAd(fragment, slotId, adContainer, screenWidthInDp, onAdShowAction, onAdClickAction) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -354,6 +354,7 @@ open class SearchGameResultFragment : ListFragment<GameEntity, SearchGameResultV
|
||||
this.mKey = key
|
||||
this.mType = type
|
||||
mAdapter?.key = key
|
||||
mAdapter?.clearAdIdSet()
|
||||
mListViewModel?.updateSearchKeyWithType(key, type)
|
||||
mListViewModel?.clearSearchSubjects()
|
||||
mListViewModel?.load(LoadType.REFRESH)
|
||||
|
||||
@ -188,7 +188,7 @@ class SearchGameResultViewModel(
|
||||
list: List<GameEntity>
|
||||
) {
|
||||
thirdPartyAdList.forEach {
|
||||
decoratedItemDataList.add(it.position - 1, SearchItemData(ad = it.thirdPartyAd))
|
||||
decoratedItemDataList.add(it.position - 1, SearchItemData(ad = it.thirdPartyAd, adConfig = it))
|
||||
SPUtils.setLong(Constants.SP_LAST_GAME_SEARCH_AD_SHOW_TIME + it.position, System.currentTimeMillis())
|
||||
}
|
||||
postResultList(decoratedItemDataList, list)
|
||||
@ -209,7 +209,7 @@ class SearchGameResultViewModel(
|
||||
if ((showThirdPartyAd && adConfig?.thirdPartyAd != null)
|
||||
|| (showOwnerAd && adConfig?.ownerAd == null && adConfig?.thirdPartyAd != null && showOnFailed)
|
||||
) {
|
||||
decoratedItemDataList.add(position - 1, SearchItemData(ad = adConfig.thirdPartyAd))
|
||||
decoratedItemDataList.add(position - 1, SearchItemData(ad = adConfig.thirdPartyAd, adConfig = adConfig))
|
||||
SPUtils.setLong(
|
||||
Constants.SP_LAST_GAME_SEARCH_AD_SHOW_TIME + adConfig.position,
|
||||
System.currentTimeMillis()
|
||||
@ -254,7 +254,7 @@ class SearchGameResultViewModel(
|
||||
)
|
||||
} else if (showOnFailed && adConfig.thirdPartyAd != null) {
|
||||
// 自有广告为空时,显示第三方广告
|
||||
decoratedItemDataList.add(position - 1, SearchItemData(ad = adConfig.thirdPartyAd))
|
||||
decoratedItemDataList.add(position - 1, SearchItemData(ad = adConfig.thirdPartyAd, adConfig = adConfig))
|
||||
SPUtils.setLong(
|
||||
Constants.SP_LAST_GAME_SEARCH_AD_SHOW_TIME + adConfig.position,
|
||||
System.currentTimeMillis()
|
||||
|
||||
@ -9,20 +9,18 @@ import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.PopupWindow
|
||||
import android.widget.TextView
|
||||
import androidx.core.view.isVisible
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.fragment.LazyFragment
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.common.view.BugFixedPopupWindow
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.core.utils.doOnEnd
|
||||
import com.gh.gamecenter.core.utils.doOnStart
|
||||
import com.gh.gamecenter.databinding.FragmentGameServerTestV2Binding
|
||||
import com.gh.gamecenter.databinding.LayoutGameServerTestV2SettingBinding
|
||||
import com.gh.gamecenter.databinding.LayoutGameServerTestV2SettingGuideBinding
|
||||
import com.gh.gamecenter.feature.entity.PageLocation
|
||||
import com.gh.gamecenter.mygame.MyGameActivity
|
||||
|
||||
@ -70,7 +68,7 @@ class GameServerTestV2Fragment : LazyFragment() {
|
||||
if (SPUtils.getBoolean(Constants.SP_SHOW_GAME_SERVER_TEST_V2_SETTING_GUIDE, true)) {
|
||||
mBaseHandler.post {
|
||||
showSettingView {
|
||||
showGuidePopupWindow()
|
||||
showGuide()
|
||||
}
|
||||
}
|
||||
SPUtils.setBoolean(Constants.SP_SHOW_GAME_SERVER_TEST_V2_SETTING_GUIDE, false)
|
||||
@ -293,6 +291,19 @@ class GameServerTestV2Fragment : LazyFragment() {
|
||||
}.start()
|
||||
}
|
||||
|
||||
private fun showGuide() {
|
||||
mBinding?.settingGuideContainer?.setOnClickListener {
|
||||
dismissGuide()
|
||||
}
|
||||
mBinding?.settingGuideContainer?.isVisible = true
|
||||
}
|
||||
|
||||
private fun dismissGuide() {
|
||||
mBinding?.settingGuideIv?.animate()?.alpha(0F)?.setDuration(200L)?.doOnEnd {
|
||||
mBinding?.settingGuideContainer?.isVisible = false
|
||||
}?.start()
|
||||
}
|
||||
|
||||
private fun getItemTextView(type: String): TextView {
|
||||
return TextView(requireContext()).apply {
|
||||
text = type
|
||||
@ -332,22 +343,11 @@ class GameServerTestV2Fragment : LazyFragment() {
|
||||
.commitAllowingStateLoss()
|
||||
}
|
||||
|
||||
private fun showGuidePopupWindow(): PopupWindow {
|
||||
val guideBinding = LayoutGameServerTestV2SettingGuideBinding.inflate(layoutInflater)
|
||||
return BugFixedPopupWindow(
|
||||
guideBinding.root,
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT,
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT
|
||||
).apply {
|
||||
isFocusable = true
|
||||
isTouchable = true
|
||||
isOutsideTouchable = true
|
||||
animationStyle = R.style.popup_window_ease_in_and_out_anim_style
|
||||
showAsDropDown(mBinding?.optionIv, 0, (-4F).dip2px())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBackPressed(): Boolean {
|
||||
if (mBinding?.settingGuideContainer?.isVisible == true) {
|
||||
dismissGuide()
|
||||
return true
|
||||
}
|
||||
if (mSettingBinding != null) {
|
||||
dismissSettingView()
|
||||
return true
|
||||
|
||||
@ -16,11 +16,12 @@ import com.gh.gamecenter.common.utils.ImageUtils
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.databinding.PieceBottomTabBinding
|
||||
import com.gh.gamecenter.entity.BottomTab
|
||||
import com.gh.gamecenter.feature.utils.SentryHelper
|
||||
|
||||
/**
|
||||
* 底部Tab 基类
|
||||
*/
|
||||
abstract class BaseBottomTabFragment<T: ViewBinding>: ToolbarFragment() {
|
||||
abstract class BaseBottomTabFragment<T : ViewBinding> : ToolbarFragment() {
|
||||
|
||||
protected var mViewPager: ViewPager2? = null
|
||||
protected var mBottomTabContainer: LinearLayout? = null
|
||||
@ -44,6 +45,7 @@ abstract class BaseBottomTabFragment<T: ViewBinding>: ToolbarFragment() {
|
||||
protected fun initBottomTab(bottomTabList: List<BottomTab>) {
|
||||
mBottomTabBindingList.clear()
|
||||
mBottomTabContainer?.run {
|
||||
visibility = View.VISIBLE
|
||||
removeAllViews()
|
||||
bottomTabList.forEachIndexed { index, bottomTab ->
|
||||
addView(
|
||||
@ -61,6 +63,13 @@ abstract class BaseBottomTabFragment<T: ViewBinding>: ToolbarFragment() {
|
||||
.apply {
|
||||
tabTv.text = bottomTab.name
|
||||
if (!TextUtils.isEmpty(bottomTab.jsCode)) {
|
||||
tabLottie.setFailureListener {
|
||||
SentryHelper.onEvent(
|
||||
SENTRY_ID_BOTTOM_TAB_LOTTIE_LOAD_FAILED,
|
||||
BOTTOM_TAB_ID, bottomTab.id,
|
||||
BOTTOM_TAB_NAME, bottomTab.name
|
||||
)
|
||||
}
|
||||
tabLottie.setAnimationFromJson(bottomTab.jsCode, bottomTab.id + bottomTab.name)
|
||||
}
|
||||
if (bottomTab.iconSelector != 0) {
|
||||
@ -78,6 +87,11 @@ abstract class BaseBottomTabFragment<T: ViewBinding>: ToolbarFragment() {
|
||||
protected fun initViewPager() {
|
||||
mViewPager?.run {
|
||||
isUserInputEnabled = false
|
||||
// 去掉默认动画
|
||||
setPageTransformer { page, _ ->
|
||||
page.translationX = 0F
|
||||
page.alpha = 1F
|
||||
}
|
||||
adapter = provideAdapter()
|
||||
registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
|
||||
@ -122,6 +136,13 @@ abstract class BaseBottomTabFragment<T: ViewBinding>: ToolbarFragment() {
|
||||
protected open fun onPageSelected(position: Int) {
|
||||
checkIndex(position)
|
||||
}
|
||||
|
||||
protected open fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
|
||||
protected open fun onPageScrollStateChanged(state: Int) {}
|
||||
|
||||
companion object {
|
||||
private const val SENTRY_ID_BOTTOM_TAB_LOTTIE_LOAD_FAILED = "bottom_tab_lottie_load_failed"
|
||||
private const val BOTTOM_TAB_ID = "bottom_tab_id"
|
||||
private const val BOTTOM_TAB_NAME = "bottom_tab_name"
|
||||
}
|
||||
}
|
||||
@ -14,32 +14,45 @@ import com.gh.gamecenter.fragment.ReloadFragment
|
||||
|
||||
class MainFragmentStateAdapter(private val mFragment: Fragment) : BaseDiffFragmentStateAdapter<BottomTab>(mFragment) {
|
||||
override fun createFragment(data: BottomTab?, position: Int): Fragment {
|
||||
if (data != null) {
|
||||
val bundle = Bundle()
|
||||
val superiorChain = if (mFragment is ISuperiorChain) mFragment else null
|
||||
mFragment.arguments?.let { bundle.putAll(it) }
|
||||
if (data.link == null) return ReloadFragment()
|
||||
bundle.putBoolean(EntranceConsts.KEY_IS_HOME, true)
|
||||
bundle.putString(EntranceConsts.KEY_BOTTOM_TAB_ID, data.id)
|
||||
bundle.putString(EntranceConsts.KEY_BOTTOM_TAB_NAME, data.name)
|
||||
bundle.putInt(EntranceConsts.KEY_POSITION, position)
|
||||
bundle.putParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST, arrayListOf(ExposureSource("底部tab", data.name)))
|
||||
bundle.putBoolean(EntranceConsts.KEY_IS_FROM_MAIN_WRAPPER, true)
|
||||
return when (data.link.type) {
|
||||
if (data == null) return ReloadFragment()
|
||||
|
||||
val bundle = Bundle()
|
||||
val superiorChain = if (mFragment is ISuperiorChain) mFragment else null
|
||||
mFragment.arguments?.let { bundle.putAll(it) }
|
||||
bundle.putBoolean(EntranceConsts.KEY_IS_HOME, true)
|
||||
bundle.putString(EntranceConsts.KEY_BOTTOM_TAB_ID, data.id)
|
||||
bundle.putString(EntranceConsts.KEY_BOTTOM_TAB_NAME, data.name)
|
||||
bundle.putInt(EntranceConsts.KEY_POSITION, position)
|
||||
|
||||
val exposureSourceList = arrayListOf(ExposureSource("底部tab", data.name))
|
||||
data.diverter?.let {
|
||||
exposureSourceList.add(
|
||||
ExposureSource(
|
||||
"分流器",
|
||||
"${it.diverterData.diverterName}+${it.diverterData.diverterId}"
|
||||
)
|
||||
)
|
||||
}
|
||||
bundle.putParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST, exposureSourceList)
|
||||
bundle.putBoolean(EntranceConsts.KEY_IS_FROM_MAIN_WRAPPER, true)
|
||||
return if (data.link == null) {
|
||||
ReloadFragment()
|
||||
} else {
|
||||
when (data.link!!.type) {
|
||||
ViewPagerFragmentHelper.TYPE_CUSTOM_PAGE -> {
|
||||
bundle.putParcelable(LinkEntity::class.java.simpleName, data.link)
|
||||
SearchToolbarTabWrapperFragment().setSuperiorChain(superiorChain).apply { arguments = bundle }
|
||||
}
|
||||
|
||||
ViewPagerFragmentHelper.TYPE_MULTI_TAB_NAV -> {
|
||||
bundle.putParcelable(BottomTab.SearchStyle::class.java.simpleName, data.searchStyle)
|
||||
bundle.putString(EntranceConsts.KEY_MULTI_TAB_NAV_ID, data.link.link)
|
||||
bundle.putString(EntranceConsts.KEY_MULTI_TAB_NAV_NAME, data.link.text)
|
||||
bundle.putString(EntranceConsts.KEY_MULTI_TAB_NAV_ID, data.link!!.link)
|
||||
bundle.putString(EntranceConsts.KEY_MULTI_TAB_NAV_NAME, data.link!!.text)
|
||||
SearchToolbarTabWrapperFragment().setSuperiorChain(superiorChain).apply { arguments = bundle }
|
||||
}
|
||||
else -> ViewPagerFragmentHelper.createFragment(mFragment, bundle, data.link, false)
|
||||
|
||||
else -> ViewPagerFragmentHelper.createFragment(mFragment, bundle, data.link!!, false)
|
||||
}
|
||||
} else {
|
||||
return ReloadFragment()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -13,6 +13,8 @@ import androidx.constraintlayout.widget.ConstraintSet
|
||||
import androidx.core.text.color
|
||||
import androidx.core.view.doOnNextLayout
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import com.ethanhua.skeleton.Skeleton
|
||||
import com.ethanhua.skeleton.SkeletonScreen
|
||||
import com.gh.common.iinterface.ISuperiorChain
|
||||
import com.gh.common.prioritychain.BottomTabGuideHandler
|
||||
import com.gh.common.prioritychain.GlobalPriorityChainHelper
|
||||
@ -48,6 +50,8 @@ class MainWrapperFragment : BaseBottomTabFragment<PieceBottomTabBinding>(), OnBa
|
||||
private var mBottomTabGuideHandler: BottomTabGuideHandler? = null
|
||||
private var mBottomTabGuidePopupWindow: PopupWindow? = null
|
||||
|
||||
private var mSkeletonScreen: SkeletonScreen? = null
|
||||
|
||||
override fun getLayoutId(): Int = 0
|
||||
override fun getInflatedLayout(): View = mBinding.root
|
||||
override fun provideAdapter(): FragmentStateAdapter = mAdapter
|
||||
@ -63,18 +67,24 @@ class MainWrapperFragment : BaseBottomTabFragment<PieceBottomTabBinding>(), OnBa
|
||||
super.onCreate(savedInstanceState)
|
||||
DisplayUtils.transparentStatusBar(requireActivity())
|
||||
|
||||
initSkeleton()
|
||||
|
||||
mBinding.viewShadow.visibility = if (mIsDarkModeOn) View.GONE else View.VISIBLE
|
||||
buildPriorityChain()
|
||||
|
||||
mViewModel?.bottomTabListLiveData?.observe(this) {
|
||||
mSkeletonScreen?.hide()
|
||||
mBottomTabList.clear()
|
||||
mBottomTabList.addAll(it)
|
||||
mViewPager?.offscreenPageLimit = it.size
|
||||
initBottomTab(mBottomTabList)
|
||||
showBottomTabGuideIfExists()
|
||||
mAdapter.submitList(mBottomTabList)
|
||||
val defaultBottomTabIndex = mViewModel!!.defaultBottomTabIndex
|
||||
val defaultBottomTab = mBottomTabList.getOrNull(defaultBottomTabIndex) ?: return@observe
|
||||
mViewPager?.doOnNextLayout {
|
||||
setCurrentItem(mViewModel!!.defaultBottomTabIndex)
|
||||
mViewModel?.handleBypassVisit(defaultBottomTab)
|
||||
setCurrentItem(defaultBottomTabIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -84,6 +94,18 @@ class MainWrapperFragment : BaseBottomTabFragment<PieceBottomTabBinding>(), OnBa
|
||||
mPriorityChain.addHandler(mBottomTabGuideHandler!!)
|
||||
}
|
||||
|
||||
private fun initSkeleton() {
|
||||
mSkeletonScreen = Skeleton.bind(mBinding.skeleton)
|
||||
.shimmer(true)
|
||||
.angle(Constants.SHIMMER_ANGLE)
|
||||
.color(R.color.ui_skeleton_highlight)
|
||||
.duration(Constants.SHIMMER_DURATION)
|
||||
.maskWidth(Constants.MASK_WIDTH)
|
||||
.gradientCenterColorWidth(Constants.GRADIENT_CENTER_COLOR_WIDTH)
|
||||
.load(R.layout.fragment_main_skeleton)
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun showBottomTabGuideIfExists() {
|
||||
val guidePosition = mBottomTabList.indexOfFirst { it.guide != null }
|
||||
if (guidePosition != -1) {
|
||||
@ -194,6 +216,9 @@ class MainWrapperFragment : BaseBottomTabFragment<PieceBottomTabBinding>(), OnBa
|
||||
if (bottomTab?.guide != null) {
|
||||
dismissBottomTabGuide()
|
||||
}
|
||||
bottomTab?.let {
|
||||
mViewModel?.handleBypassVisit(it)
|
||||
}
|
||||
playTabAnimation(toCheck)
|
||||
changeBottomTabStyle(toCheck)
|
||||
EventBus.getDefault().post(EBReuse(Constants.FINISH_PULL_DOWN_PUSH))
|
||||
|
||||
@ -3,23 +3,31 @@ package com.gh.gamecenter.wrapper
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.gh.common.util.HomeBottomBarHelper
|
||||
import com.gh.common.util.NewFlatLogUtils
|
||||
import com.gh.common.util.ViewPagerFragmentHelper
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.entity.LaunchRedirect
|
||||
import com.gh.gamecenter.common.retrofit.BiResponse
|
||||
import com.gh.gamecenter.common.utils.singleToMain
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge
|
||||
import com.gh.gamecenter.core.utils.GsonUtils
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.core.utils.SingletonHolder
|
||||
import com.gh.gamecenter.core.utils.TimeUtils
|
||||
import com.gh.gamecenter.entity.BottomTab
|
||||
import com.gh.gamecenter.entity.DataUnionEntity
|
||||
import com.gh.gamecenter.entity.DiverterEntity
|
||||
import com.gh.gamecenter.entity.MultiTabNav
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageData
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.TimeoutException
|
||||
|
||||
class MainWrapperRepository {
|
||||
private val mNewApi = RetrofitManager.getInstance().newApi
|
||||
@ -45,9 +53,17 @@ class MainWrapperRepository {
|
||||
val customPageLiveData = MutableLiveData<CustomPageData?>()
|
||||
val errorLiveData = MutableLiveData<Exception>()
|
||||
|
||||
val diverterList = arrayListOf<DiverterEntity>()
|
||||
|
||||
private val mTabSelectEventFlow = MutableSharedFlow<MainSelectedEvent>()
|
||||
val tabSelectEventFlow = mTabSelectEventFlow as SharedFlow<MainSelectedEvent>
|
||||
|
||||
fun init() {
|
||||
// 若 timeout 后数据未加载完成,则即便还没有回调也使用默认数据生成底部 tab
|
||||
emitDefaultTabDataAfterTimeout()
|
||||
getBypassList()
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送首次启动跳转事件的选中事件
|
||||
*/
|
||||
@ -132,10 +148,37 @@ class MainWrapperRepository {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
fun getBypassList() {
|
||||
val isInstallFirstAccess = TimeUtils.isToday(SPUtils.getLong(Constants.SP_BRAND_NEW_FIRST_LAUNCH_TIME) / 1000).toString()
|
||||
mNewApi.getDiverterList(isInstallFirstAccess, BYPASS_TYPE_BOTTOM_TAB)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.timeout(BYPASS_TIME_OUT, TimeUnit.MILLISECONDS)
|
||||
.subscribe(object : BiResponse<List<DiverterEntity>>() {
|
||||
override fun onSuccess(data: List<DiverterEntity>) {
|
||||
diverterList.clear()
|
||||
diverterList.addAll(data)
|
||||
getDataUnion()
|
||||
}
|
||||
|
||||
override fun onFailure(exception: Exception) {
|
||||
super.onFailure(exception)
|
||||
getDataUnion()
|
||||
|
||||
val reasonString = if (exception is TimeoutException) "分流判断超时" else "分流页面返回为空"
|
||||
SensorsBridge.trackFailByPass("底部tab", "", "", reasonString)
|
||||
NewFlatLogUtils.logFailByPass("底部tab", "", "", reasonString)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
fun getDataUnion() {
|
||||
processBottomTabData(emptyList())
|
||||
mNewApi.dataUnion
|
||||
var diverter = ""
|
||||
diverterList.forEach {
|
||||
diverter += "${it.moduleIndex}:${it.diverterData.branchId},"
|
||||
}
|
||||
mNewApi.getDataUnion(diverter)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(object : BiResponse<DataUnionEntity>() {
|
||||
override fun onSuccess(data: DataUnionEntity) {
|
||||
@ -156,7 +199,9 @@ class MainWrapperRepository {
|
||||
|
||||
private fun processBottomTabData(bottomTabList: List<BottomTab>) {
|
||||
if (bottomTabList.isNotEmpty()) {
|
||||
HomeBottomBarHelper.updateDefaultHomeBottomTabData(bottomTabList)
|
||||
diverterList.forEach {
|
||||
bottomTabList.getOrNull(it.moduleIndex)?.diverter = it
|
||||
}
|
||||
|
||||
var preSelectedTab: BottomTab? = null
|
||||
|
||||
@ -199,11 +244,16 @@ class MainWrapperRepository {
|
||||
}
|
||||
}
|
||||
|
||||
HomeBottomBarHelper.updateDefaultHomeBottomTabData(bottomTabList)
|
||||
bottomTabListLiveData.postValue(bottomTabList)
|
||||
defaultNavId = bottomTabList.find { it.link?.type == ViewPagerFragmentHelper.TYPE_MULTI_TAB_NAV && it.default }?.link?.link ?: ""
|
||||
defaultCustomPageId = bottomTabList.find { it.link?.type == ViewPagerFragmentHelper.TYPE_CUSTOM_PAGE && it.default }?.link?.link ?: ""
|
||||
} else {
|
||||
HomeBottomBarHelper.getDefaultHomeBottomTabData().run {
|
||||
val defaultIndex = indexOfFirst { it.default }
|
||||
if (defaultIndex != -1) {
|
||||
defaultBottomTabIndex = defaultIndex
|
||||
}
|
||||
bottomTabListLiveData.postValue(this)
|
||||
defaultNavId = find { it.link?.type == ViewPagerFragmentHelper.TYPE_MULTI_TAB_NAV && it.default }?.link?.link ?: ""
|
||||
defaultCustomPageId = find { it.link?.type == ViewPagerFragmentHelper.TYPE_CUSTOM_PAGE && it.default }?.link?.link ?: ""
|
||||
@ -232,7 +282,19 @@ class MainWrapperRepository {
|
||||
multiTabNavLiveData.postValue(multiTabNav)
|
||||
}
|
||||
|
||||
companion object : SingletonHolder<MainWrapperRepository>({ MainWrapperRepository() })
|
||||
private fun emitDefaultTabDataAfterTimeout() {
|
||||
CoroutineScope(SupervisorJob()).launch {
|
||||
delay(3000)
|
||||
if (!mMainDataIsLoaded) {
|
||||
processBottomTabData(emptyList())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object : SingletonHolder<MainWrapperRepository>({ MainWrapperRepository() }) {
|
||||
private const val BYPASS_TIME_OUT = 1000L
|
||||
const val BYPASS_TYPE_BOTTOM_TAB = "bottom_tab"
|
||||
}
|
||||
}
|
||||
|
||||
sealed class MainSelectedEvent {
|
||||
|
||||
@ -1,15 +1,22 @@
|
||||
package com.gh.gamecenter.wrapper
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.*
|
||||
import com.gh.common.util.CheckLoginUtils
|
||||
import com.gh.common.util.NewFlatLogUtils
|
||||
import com.gh.common.util.RealNameHelper
|
||||
import com.gh.gamecenter.common.retrofit.Response
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge
|
||||
import com.gh.gamecenter.common.utils.singleToMain
|
||||
import com.gh.gamecenter.common.utils.toRequestBody
|
||||
import com.gh.gamecenter.entity.BottomTab
|
||||
import com.gh.gamecenter.entity.DiverterEntity
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.livedata.Event
|
||||
import com.gh.gamecenter.login.user.UserManager
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.coroutines.flow.map
|
||||
@ -23,6 +30,7 @@ import retrofit2.HttpException
|
||||
class MainWrapperViewModel(application: Application, private val mRepository: MainWrapperRepository) :
|
||||
AndroidViewModel(application) {
|
||||
private val mApi = RetrofitManager.getInstance().api
|
||||
private val mNewApi = RetrofitManager.getInstance().newApi
|
||||
|
||||
val defaultBottomTabIndex
|
||||
get() = mRepository.defaultBottomTabIndex
|
||||
@ -45,6 +53,8 @@ class MainWrapperViewModel(application: Application, private val mRepository: Ma
|
||||
|
||||
val bottomDoubleTabAction = MutableLiveData<BottomTab>()
|
||||
|
||||
private val byPassVisitBottomTabIdSet = hashSetOf<String>()
|
||||
|
||||
/**
|
||||
* 请求各种弹窗的数据
|
||||
*/
|
||||
@ -91,6 +101,57 @@ class MainWrapperViewModel(application: Application, private val mRepository: Ma
|
||||
})
|
||||
}
|
||||
|
||||
fun handleBypassVisit(bottomTab: BottomTab) {
|
||||
if (byPassVisitBottomTabIdSet.contains(bottomTab.id)) return
|
||||
|
||||
bottomTab.diverter?.let {
|
||||
val source = "底部tab:${bottomTab.name}"
|
||||
SensorsBridge.trackByPassBrowsing(
|
||||
source,
|
||||
it.diverterData.diverterName,
|
||||
it.diverterData.diverterId,
|
||||
it.diverterData.branchId,
|
||||
it.diverterData.branchName,
|
||||
it.diverterData.inprocessTime,
|
||||
it.diverterData.bypassVisitTime,
|
||||
it.diverterData.linkType,
|
||||
it.diverterData.linkId,
|
||||
it.diverterData.linkText,
|
||||
it.diverterData.bypassStatus,
|
||||
)
|
||||
NewFlatLogUtils.logByPassBrowsing(
|
||||
source,
|
||||
it.diverterData.diverterName,
|
||||
it.diverterData.diverterId,
|
||||
it.diverterData.branchId,
|
||||
it.diverterData.branchName,
|
||||
it.diverterData.inprocessTime,
|
||||
it.diverterData.bypassVisitTime,
|
||||
it.diverterData.linkType,
|
||||
it.diverterData.linkId,
|
||||
it.diverterData.linkText,
|
||||
it.diverterData.bypassStatus,
|
||||
)
|
||||
patchBypassVisitTime(it)
|
||||
byPassVisitBottomTabIdSet.add(bottomTab.id)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private fun patchBypassVisitTime(diverterEntity: DiverterEntity) {
|
||||
val data = mapOf(
|
||||
"module_id" to diverterEntity.moduleId,
|
||||
"diverter_id" to diverterEntity.diverterData.diverterId
|
||||
)
|
||||
mNewApi.patchDiverterVisitTime(MainWrapperRepository.BYPASS_TYPE_BOTTOM_TAB, data.toRequestBody())
|
||||
.compose(singleToMain())
|
||||
.subscribe({
|
||||
Utils.log(TAG, "patchDiverterVisitTime onSuccess: ${it.string()}")
|
||||
}, {
|
||||
Utils.log(TAG, "patchDiverterVisitTime onError: ${it.message}")
|
||||
})
|
||||
}
|
||||
|
||||
class Factory(
|
||||
private val mApplication: Application,
|
||||
) : ViewModelProvider.NewInstanceFactory() {
|
||||
@ -100,6 +161,7 @@ class MainWrapperViewModel(application: Application, private val mRepository: Ma
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "MainWrapperViewModel"
|
||||
const val SHOULD_SHOW_OPENING_DIALOG = "show_opening_dialog"
|
||||
}
|
||||
}
|
||||
@ -58,6 +58,7 @@ import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.time.TimeUtil
|
||||
import com.gh.gamecenter.feature.game.GameItemViewHolder
|
||||
import com.gh.gamecenter.feature.utils.SentryHelper
|
||||
import com.gh.gamecenter.gamecollection.square.GameCollectionSquareFragment
|
||||
import com.gh.gamecenter.home.custom.CustomPageFragment
|
||||
import com.gh.gamecenter.home.video.ScrollCalculatorHelper
|
||||
@ -89,7 +90,18 @@ import kotlin.math.roundToInt
|
||||
* @see Style
|
||||
*/
|
||||
class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbarTab, ISmartRefresh, ISuperiorChain {
|
||||
private val mBinding by lazy { FragmentSearchToolbarTabWrapperBinding.inflate(layoutInflater) }
|
||||
private val mBinding by lazy {
|
||||
try {
|
||||
FragmentSearchToolbarTabWrapperBinding.inflate(layoutInflater)
|
||||
} catch (e: Exception) {
|
||||
SentryHelper.onEvent("VIEW_BINDING_BIND_ERROR",
|
||||
"digest", e.localizedMessage,
|
||||
"gid", HaloApp.getInstance().gid
|
||||
)
|
||||
// 玄学,重试一次,该闪退闪退
|
||||
FragmentSearchToolbarTabWrapperBinding.inflate(layoutInflater)
|
||||
}
|
||||
}
|
||||
private val mViewModel: SearchToolbarTabWrapperViewModel by lazy {
|
||||
viewModelProviderFromParent(
|
||||
SearchToolbarTabWrapperViewModel.Factory(mMultiTabNavId, mNoTabLinkEntity?.link ?: ""),
|
||||
|
||||
@ -14,9 +14,11 @@ import android.text.TextUtils;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
|
||||
import com.blankj.utilcode.util.ThreadUtils;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.gamecenter.SplashScreenActivity;
|
||||
import com.gh.gamecenter.common.base.GlobalActivityManager;
|
||||
import com.gh.gamecenter.core.AppExecutor;
|
||||
import com.gh.ndownload.suspendwindow.NDownloadDrawOverlayPermissionWindowController;
|
||||
import com.gh.ndownload.suspendwindow.NDownloadSuspendWindowController;
|
||||
import com.gh.ndownload.suspendwindow.utils.NDownloadSuspendWindowHelper;
|
||||
@ -282,6 +284,14 @@ public class NDownloadService extends Service {
|
||||
}
|
||||
|
||||
private void showDownloadSuspendWindowIfNeeded(DownloadEntity entry) {
|
||||
if (ThreadUtils.isMainThread()) {
|
||||
showDownloadSuspendWindowIfNeededInner(entry);
|
||||
} else {
|
||||
AppExecutor.getUiExecutor().execute(() -> showDownloadSuspendWindowIfNeededInner(entry));
|
||||
}
|
||||
}
|
||||
|
||||
private void showDownloadSuspendWindowIfNeededInner(DownloadEntity entry) {
|
||||
if (!NDownloadSuspendWindowHelper.shouldSkipDownloadEntity(getApplicationContext(), entry)) {
|
||||
if (NDownloadSuspendWindowHelper.canDrawOverLayer(getApplicationContext())) {// 已开启悬浮窗权限,直接显示悬浮窗
|
||||
showDownloadSuspendWindow();
|
||||
|
||||
@ -3,7 +3,9 @@ package com.gh.ndownload.suspendwindow
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.app.Application.ActivityLifecycleCallbacks
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.core.view.ViewCompat
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge
|
||||
import com.gh.gamecenter.common.utils.asVGame
|
||||
@ -45,7 +47,9 @@ class NDownloadDrawOverlayPermissionWindowController(val application: Applicatio
|
||||
}
|
||||
|
||||
fun show(activity: Activity) {
|
||||
if (isStarted) return
|
||||
val decorView = activity.window.decorView
|
||||
val isAttachedToWindow = ViewCompat.isAttachedToWindow(decorView)
|
||||
if (isStarted || !isAttachedToWindow) return
|
||||
isStarted = true
|
||||
currentActivityRef = WeakReference(activity)
|
||||
onAttachToUi(activity)
|
||||
@ -124,10 +128,10 @@ class NDownloadDrawOverlayPermissionWindowController(val application: Applicatio
|
||||
SensorsBridge.trackDownloadSuspendedWindowGuideShow(
|
||||
gameId = downloadEntity.gameId,
|
||||
gameName = downloadEntity.name,
|
||||
gameSchemeType = if(downloadEntity.getMetaExtra(Constants.KEY_BIT) == "32") "32位" else "64位",
|
||||
gameSchemeType = if (downloadEntity.getMetaExtra(Constants.KEY_BIT) == "32") "32位" else "64位",
|
||||
gameType = downloadEntity.categoryChinese,
|
||||
downloadStatus = downloadEntity.getMetaExtra(Constants.DOWNLOAD_STATUS_IN_CHINESE),
|
||||
downloadType = if(downloadEntity.asVGame()) "畅玩下载" else "本地下载"
|
||||
downloadType = if (downloadEntity.asVGame()) "畅玩下载" else "本地下载"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user