Compare commits
131 Commits
pack/updat
...
hotfix/va-
| Author | SHA1 | Date | |
|---|---|---|---|
| c6f70d1b4c | |||
| 0cd281a53c | |||
| e92d89d498 | |||
| a22858389b | |||
| e9d091043d | |||
| db4ac95094 | |||
| 13be47d440 | |||
| beee098cfe | |||
| d67aaf956b | |||
| 1ed9151b1f | |||
| 13f20f6883 | |||
| 78e320a192 | |||
| e51db47fad | |||
| ac02ea88b9 | |||
| f60004fc81 | |||
| 0cf39a82e2 | |||
| 315f244153 | |||
| f4bdc02d70 | |||
| aef39eb481 | |||
| dc2e7147d9 | |||
| fdcb6342bf | |||
| b0da4f8986 | |||
| f7cc906cc5 | |||
| 795fbabd90 | |||
| e770f8a359 | |||
| dd12b103be | |||
| 21f4a398d5 | |||
| 8dfb1644a8 | |||
| 9744b95126 | |||
| 009608165c | |||
| 98356a7dd7 | |||
| 8389041379 | |||
| 2e63257523 | |||
| fa663cd2f6 | |||
| 19af061311 | |||
| d643795fa3 | |||
| b1f2d0a303 | |||
| bb906f0bb8 | |||
| 6f242dcc95 | |||
| b47a64c63d | |||
| 948df2582c | |||
| 35edcf1d68 | |||
| 286d7650f2 | |||
| e566ab838f | |||
| cae720d4ec | |||
| 925516724f | |||
| a5f807c038 | |||
| f442a70bd3 | |||
| 9b3dab9897 | |||
| d939aae901 | |||
| 028974ec0d | |||
| ecd4610186 | |||
| 21e5f2c98d | |||
| 71c0cfe350 | |||
| 3b8b60bc6b | |||
| ac59158dbb | |||
| 5becdf2095 | |||
| a88b49344f | |||
| f34646cde8 | |||
| 9e8ffce772 | |||
| 008985489a | |||
| 2f3fbd3e7c | |||
| abef224830 | |||
| 8feb9b788e | |||
| 0a059deb44 | |||
| 448160d255 | |||
| 533f93a340 | |||
| d80b8a97a3 | |||
| f2e6d98788 | |||
| 238a83c5fe | |||
| ca71f23363 | |||
| c96b41c621 | |||
| e8ee63d52c | |||
| 90359cfffd | |||
| a3da883033 | |||
| a9f1437a52 | |||
| 8c95286fe5 | |||
| 8a835a94e3 | |||
| 14ec4aed3a | |||
| 07f956a1f0 | |||
| 6ef8d04e57 | |||
| 30248ef205 | |||
| 87b9bb0bf3 | |||
| b346882bfa | |||
| eeddb5ea51 | |||
| 78f9aa3ee4 | |||
| f34ad0675d | |||
| 36abcc9f19 | |||
| ae878eddf1 | |||
| ece519115b | |||
| b9e0a8e37a | |||
| 34ca8896ae | |||
| d6e19bfaff | |||
| 943fb4d4e0 | |||
| 2c5471d524 | |||
| cf527db60e | |||
| f261991a55 | |||
| ab66621751 | |||
| af262c624a | |||
| d2813ecbda | |||
| 0ea932e36d | |||
| 68151ed6f9 | |||
| e6d2361008 | |||
| 570b777c8e | |||
| 0e557b2246 | |||
| f155440814 | |||
| 62ba9fc7bf | |||
| 4637aa8808 | |||
| 81998e3aad | |||
| 82a8aa03ba | |||
| c876711578 | |||
| 41fcee7f4d | |||
| 0ccbc4d581 | |||
| f05fc73e3a | |||
| ca3c545f26 | |||
| 226539328e | |||
| bb7db78b0c | |||
| ede62c5363 | |||
| 12bb6824ea | |||
| 15c0950754 | |||
| f86b7fe12a | |||
| d12cdbd34b | |||
| 8436d4eda3 | |||
| be832037a7 | |||
| b620257825 | |||
| 6c88cace99 | |||
| f875fa1b14 | |||
| 8076c3a70a | |||
| bebab317a3 | |||
| c450ca570d | |||
| d239b0755f |
@ -72,7 +72,6 @@ android_build:
|
||||
only:
|
||||
- dev
|
||||
- release
|
||||
- pack/update_sentry_plugin_cache
|
||||
|
||||
# 代码检查
|
||||
sonarqube_analysis:
|
||||
@ -158,4 +157,3 @@ oss-upload&send-email:
|
||||
only:
|
||||
- dev
|
||||
- release
|
||||
- pack/update_sentry_plugin_cache
|
||||
|
||||
@ -663,7 +663,8 @@
|
||||
android:name=".authorization.AuthorizationActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="portrait">
|
||||
android:screenOrientation="portrait"
|
||||
android:taskAffinity=".auth">
|
||||
<intent-filter>
|
||||
<data android:scheme="ghzhushou_authorization" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
@ -864,10 +865,6 @@
|
||||
<!-- tools:node="remove" />-->
|
||||
<!-- </provider>-->
|
||||
|
||||
<service android:name="com.gh.gamecenter.install.InstallService" />
|
||||
|
||||
<service android:name="com.gh.download.suspendwindow.DownloadSuspendWindowService" />
|
||||
|
||||
<receiver
|
||||
android:name="com.gh.gamecenter.receiver.DownloadReceiver"
|
||||
android:exported="false">
|
||||
|
||||
@ -4,6 +4,7 @@ import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.graphics.drawable.Animatable
|
||||
import android.os.Message
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
@ -13,11 +14,13 @@ import android.widget.TextView
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.facebook.drawee.controller.BaseControllerListener
|
||||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
import com.facebook.imagepipeline.image.ImageInfo
|
||||
import com.gh.common.exposure.ExposureManager
|
||||
import com.gh.common.util.DirectUtils.directToLinkPage
|
||||
import com.gh.common.util.LogUtils
|
||||
import com.gh.common.util.NewFlatLogUtils.logOpenScreenAdSkip
|
||||
import com.gh.common.util.NewFlatLogUtils
|
||||
import com.gh.common.util.PackageUtils
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.MainActivity
|
||||
@ -59,6 +62,8 @@ object AdDelegateHelper {
|
||||
private val mGameSearchAdList: ArrayList<AdConfig> by lazy { arrayListOf() }
|
||||
private var mVGameLaunchAd: AdConfig? = null
|
||||
|
||||
private var ownerSplashAdLoadTime = 0L
|
||||
|
||||
val vGameLaunchAd: AdConfig?
|
||||
get() = mVGameLaunchAd
|
||||
|
||||
@ -76,6 +81,7 @@ object AdDelegateHelper {
|
||||
}
|
||||
|
||||
var isShowingSplashAd = false // 是否正在显示开屏广告
|
||||
var isOwnerSplashAdShown = false // 自有开屏广告是否展示
|
||||
var gameSearchKeyword = ""
|
||||
|
||||
fun initAdSdk(context: Context) {
|
||||
@ -303,6 +309,7 @@ object AdDelegateHelper {
|
||||
) {
|
||||
val hideCallback = {
|
||||
isShowingSplashAd = false
|
||||
isOwnerSplashAdShown = false
|
||||
hideAction.invoke()
|
||||
}
|
||||
if (mSplashAd != null) {
|
||||
@ -575,6 +582,8 @@ object AdDelegateHelper {
|
||||
handler: BaseActivity.BaseHandler,
|
||||
hideCallback: () -> Unit
|
||||
) {
|
||||
isOwnerSplashAdShown = false
|
||||
|
||||
val jumpBtn = startAdContainer.findViewById<TextView>(R.id.jumpBtn)
|
||||
val jumpDetailBtn: TextView = startAdContainer.findViewById(R.id.jumpDetailBtn)
|
||||
val adImage: SimpleDraweeView = startAdContainer.findViewById(R.id.adImage)
|
||||
@ -593,38 +602,62 @@ object AdDelegateHelper {
|
||||
)
|
||||
|
||||
adImage.visibleIf(true)
|
||||
ImageUtils.display(adImage, ad.img)
|
||||
ImageUtils.displayWithCallback(adImage, ad.img, true, object : BaseControllerListener<ImageInfo>() {
|
||||
override fun onSubmit(id: String?, callerContext: Any?) {
|
||||
super.onSubmit(id, callerContext)
|
||||
adImage.post {
|
||||
ownerSplashAdLoadTime = System.currentTimeMillis()
|
||||
NewFlatLogUtils.logSplashAdLoad(ad.id)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFinalImageSet(id: String?, imageInfo: ImageInfo?, animatable: Animatable?) {
|
||||
isOwnerSplashAdShown = true
|
||||
adImage.post {
|
||||
NewFlatLogUtils.logSplashAdShow(ad.id, System.currentTimeMillis() - ownerSplashAdLoadTime)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(id: String?, throwable: Throwable?) {
|
||||
super.onFailure(id, throwable)
|
||||
NewFlatLogUtils.logSplashAdFail(ad.id, "启动广告图加载失败")
|
||||
}
|
||||
})
|
||||
|
||||
if (ad.isImageType) {
|
||||
adVideo.visibleIf(false)
|
||||
} else {
|
||||
adVideo.visibleIf(true)
|
||||
adVideo.startPlay(ad.video.url)
|
||||
}
|
||||
startAdContainer.setOnClickListener {
|
||||
// 拦截点击事件传递
|
||||
}
|
||||
jumpBtn.setOnClickListener {
|
||||
handler.removeMessages(MainActivity.COUNTDOWN_AD)
|
||||
hideCallback.invoke()
|
||||
val linkEntity = ad.jump
|
||||
logOpenScreenAdSkip(
|
||||
ad.id,
|
||||
(if (linkEntity.text != null) linkEntity.text else "")!!,
|
||||
(if (linkEntity.type != null) linkEntity.type else "")!!,
|
||||
(if (linkEntity.link != null) linkEntity.link else "")!!
|
||||
)
|
||||
SensorsBridge.trackEvent(
|
||||
"SplashAdOwnSkip",
|
||||
"splash_ad_id",
|
||||
ad.id,
|
||||
"link_type",
|
||||
linkEntity.type ?: "",
|
||||
"link_id",
|
||||
linkEntity.link ?: "",
|
||||
"link_text",
|
||||
linkEntity.text ?: ""
|
||||
)
|
||||
it.debounceActionWithInterval(1000L) {
|
||||
if (!isOwnerSplashAdShown) {
|
||||
NewFlatLogUtils.logSplashAdFail(ad.id, "加载过程中点击跳过广告")
|
||||
}
|
||||
handler.removeMessages(MainActivity.COUNTDOWN_AD)
|
||||
hideCallback.invoke()
|
||||
val linkEntity = ad.jump
|
||||
NewFlatLogUtils.logOpenScreenAdSkip(
|
||||
ad.id,
|
||||
(if (linkEntity.text != null) linkEntity.text else "")!!,
|
||||
(if (linkEntity.type != null) linkEntity.type else "")!!,
|
||||
(if (linkEntity.link != null) linkEntity.link else "")!!
|
||||
)
|
||||
SensorsBridge.trackEvent(
|
||||
"SplashAdOwnSkip",
|
||||
"splash_ad_id",
|
||||
ad.id,
|
||||
"link_type",
|
||||
linkEntity.type ?: "",
|
||||
"link_id",
|
||||
linkEntity.link ?: "",
|
||||
"link_text",
|
||||
linkEntity.text ?: ""
|
||||
)
|
||||
}
|
||||
}
|
||||
val sources: MutableList<ExposureSource> = ArrayList()
|
||||
sources.add(ExposureSource("开屏广告", ad.id))
|
||||
|
||||
@ -44,6 +44,16 @@ class SplashAdVideoView @JvmOverloads constructor(
|
||||
return R.layout.layout_splash_ad_video
|
||||
}
|
||||
|
||||
override fun touchSurfaceMoveFullLogic(absDeltaX: Float, absDeltaY: Float) {
|
||||
// no nothing
|
||||
}
|
||||
|
||||
override fun onPrepared() {
|
||||
super.onPrepared()
|
||||
|
||||
visibility = VISIBLE
|
||||
}
|
||||
|
||||
override fun onAutoCompletion() {
|
||||
setStateAndUi(CURRENT_STATE_AUTO_COMPLETE);
|
||||
|
||||
|
||||
@ -114,8 +114,6 @@ public class Config {
|
||||
if (!TextUtils.isEmpty(json)) {
|
||||
mSettingsEntity = GsonUtils.fromJson(json, SettingsEntity.class);
|
||||
}
|
||||
|
||||
mSettingsEntity.setGameSmooth("off");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@ -287,19 +287,11 @@ public class BindingAdapters {
|
||||
});
|
||||
break;
|
||||
case RESERVED:
|
||||
if ("download".equals(gameEntity.getReserveStatus())) {
|
||||
ReservationHelper.showDeleteReservationDialog(progressBar.getContext(), () -> {
|
||||
ReservationHelper.deleteReservation(gameEntity, () -> {
|
||||
updateReservation(progressBar, gameEntity);
|
||||
});
|
||||
ReservationHelper.showCancelReservationDialog(progressBar.getContext(),gameEntity, () -> {
|
||||
ReservationHelper.cancelReservation(gameEntity, () -> {
|
||||
updateReservation(progressBar, gameEntity);
|
||||
});
|
||||
} else {
|
||||
ReservationHelper.showCancelReservationDialog(progressBar.getContext(),gameEntity, () -> {
|
||||
ReservationHelper.cancelReservation(gameEntity, () -> {
|
||||
updateReservation(progressBar, gameEntity);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
break;
|
||||
case H5_GAME:
|
||||
LinkEntity linkEntity = gameEntity.getH5Link();
|
||||
|
||||
@ -17,7 +17,7 @@ import com.gh.gamecenter.common.entity.ErrorEntity
|
||||
import com.gh.gamecenter.core.utils.CurrentActivityHolder
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.databinding.DialogWechatBindingFailedBinding
|
||||
import com.gh.gamecenter.login.user.UserRepository
|
||||
import com.gh.gamecenter.login.user.UserManager
|
||||
import com.lightgame.utils.Utils
|
||||
|
||||
class WechatBindingFailedDialogFragment : BaseDialogFragment() {
|
||||
@ -48,10 +48,10 @@ class WechatBindingFailedDialogFragment : BaseDialogFragment() {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
UserRepository.getInstance().loginUserInfo.observe(viewLifecycleOwner) {
|
||||
currentUserId = it.data.getShortUserId()
|
||||
binding.tvCurrentName.text = it.data.name
|
||||
binding.ivCurrentAvatar.displayAvatar(it.data.icon)
|
||||
UserManager.getInstance().userInfoEntity?.let {
|
||||
currentUserId = it.getShortUserId()
|
||||
binding.tvCurrentName.text = it.name ?: ""
|
||||
binding.ivCurrentAvatar.displayAvatar(it.icon)
|
||||
binding.tvUserId.text = getString(R.string.user_id, currentUserId)
|
||||
}
|
||||
|
||||
|
||||
@ -31,6 +31,7 @@ class ExposureListener(var fragment: Fragment, var exposable: IExposable) : Recy
|
||||
override fun onFragmentPaused(fm: FragmentManager, f: Fragment) {
|
||||
if (fragment == f) {
|
||||
visibleState?.let { commitExposure(it) }
|
||||
visibleState?.let { commitWXCPMExposure(it) }
|
||||
throttleBus.clear()
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
package com.gh.common.fragment
|
||||
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import java.lang.reflect.Field
|
||||
|
||||
fun FragmentManager.popBackStackAllowStateLoss() {
|
||||
popBackStackAllowStateLoss(-1, 0)
|
||||
}
|
||||
|
||||
fun FragmentManager.popBackStackAllowStateLoss(id: Int, flags: Int) {
|
||||
if (!isStateSaved) {
|
||||
popBackStack(id, flags)
|
||||
}
|
||||
}
|
||||
|
||||
fun FragmentManager.popBackStackAllowStateLoss(name: String?, flags: Int) {
|
||||
if (!isStateSaved) {
|
||||
popBackStack(name, flags)
|
||||
}
|
||||
}
|
||||
|
||||
fun FragmentManager.popBackStackImmediateAllowStateLoss() = popBackStackAllowStateLoss(-1, 0)
|
||||
|
||||
fun FragmentManager.popBackStackImmediateAllowStateLoss(id: Int, flags: Int) =
|
||||
if (!isStateSaved) {
|
||||
popBackStackImmediate(id, flags)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
@Throws(NoSuchFieldException::class)
|
||||
private fun getField(clazz: Class<*>, name: String): Field {
|
||||
var cls: Class<*>? = clazz
|
||||
while (cls != null) {
|
||||
try {
|
||||
val declaredField = cls.getDeclaredField(name)
|
||||
declaredField.isAccessible = true
|
||||
return declaredField
|
||||
} catch (e: NoSuchFieldException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
cls = cls.superclass
|
||||
}
|
||||
throw NoSuchFieldException()
|
||||
}
|
||||
@ -1,12 +1,9 @@
|
||||
package com.gh.common.iinterface
|
||||
|
||||
interface ISmartRefreshContent {
|
||||
/**
|
||||
* 启用/关闭 页面滑动
|
||||
* @param isScrollEnabled 是否启用
|
||||
*/
|
||||
fun setScrollEnabled(isScrollEnabled: Boolean)
|
||||
import com.scwang.smartrefresh.layout.api.RefreshLayout
|
||||
import com.scwang.smartrefresh.layout.constant.RefreshState
|
||||
|
||||
interface ISmartRefreshContent {
|
||||
fun onRefresh()
|
||||
|
||||
/**
|
||||
@ -14,4 +11,6 @@ interface ISmartRefreshContent {
|
||||
* @param isSwipeRefreshEnabled 是否启用
|
||||
*/
|
||||
fun setSwipeRefreshEnabled(isSwipeRefreshEnabled: Boolean)
|
||||
|
||||
fun onStateChanged(refreshLayout: RefreshLayout, oldState: RefreshState, newState: RefreshState)
|
||||
}
|
||||
@ -115,6 +115,12 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
|
||||
"本地下载"
|
||||
}
|
||||
|
||||
// 小游戏的启动不需要上报下载点击事件
|
||||
// @see https://jira.shanqu.cc/browse/GHZSCY-7013
|
||||
if (boundedObject is GameEntity && boundedObject.isMiniGame()) {
|
||||
return
|
||||
}
|
||||
|
||||
// 上报神策点击事件
|
||||
val customPageKV = customPageTrackData?.toKV() ?: arrayOf()
|
||||
SensorsBridge.trackEventWithExposureSource(
|
||||
@ -124,7 +130,7 @@ class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
|
||||
"game_name", gameName,
|
||||
"game_type", gameTypeInChinese,
|
||||
"download_status", downloadStatusInChinese,
|
||||
"button_name", downloadButton.text,
|
||||
"button_name", text,
|
||||
"game_schema_type", gameSchemaType,
|
||||
"download_type", downloadType,
|
||||
"page_name", GlobalActivityManager.getCurrentPageEntity().pageName,
|
||||
|
||||
@ -4,6 +4,8 @@ import android.annotation.SuppressLint
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.database.sqlite.SQLiteDiskIOException
|
||||
import android.database.sqlite.SQLiteException
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.text.TextUtils
|
||||
@ -284,7 +286,11 @@ object SimulatorGameManager {
|
||||
entity.isRecentlyPlayed = it.id == gameId
|
||||
simulatorGameRecordList.add(entity)
|
||||
}
|
||||
simulatorGameDao.addSimulatorGameList(simulatorGameRecordList)
|
||||
try {
|
||||
simulatorGameDao.addSimulatorGameList(simulatorGameRecordList)
|
||||
} catch (e: SQLiteException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@ import com.gh.gamecenter.common.constant.Constants;
|
||||
import com.gh.gamecenter.common.constant.RouteConsts;
|
||||
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
|
||||
import com.gh.gamecenter.common.retrofit.BiResponse;
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge;
|
||||
import com.gh.gamecenter.core.AppExecutor;
|
||||
import com.gh.gamecenter.core.provider.ISentryProvider;
|
||||
import com.gh.gamecenter.core.utils.GsonUtils;
|
||||
@ -39,6 +40,11 @@ import io.reactivex.schedulers.Schedulers;
|
||||
*/
|
||||
public class DataUtils {
|
||||
|
||||
// 神策 OAID 是否已绑定
|
||||
private static boolean isSensorOAIDBounded = false;
|
||||
// 原始的 OAID 是否已成功获取
|
||||
private static boolean originalOAIDIsReceived = false;
|
||||
|
||||
private DataUtils() {
|
||||
throw new IllegalStateException("Utility class");
|
||||
}
|
||||
@ -65,7 +71,6 @@ public class DataUtils {
|
||||
// 默认用 APP 级已存储的 GID 来使用,不使用外部 GID
|
||||
String savedGid = SPUtils.getString(Constants.GID);
|
||||
if (!TextUtils.isEmpty(savedGid)) {
|
||||
HaloApp.getInstance().setGid(savedGid);
|
||||
onGidReceived(savedGid);
|
||||
} else {
|
||||
GidHelper.getInstance().registerDevice(HaloApp.getInstance().getApplication(), new GidCallback() {
|
||||
@ -89,6 +94,8 @@ public class DataUtils {
|
||||
}
|
||||
|
||||
private static void onGidReceived(String gid) {
|
||||
bindValidOaidToSensor(false);
|
||||
|
||||
HaloApp.getInstance().setGid(gid);
|
||||
// 更新广告配置
|
||||
AdDelegateHelper.INSTANCE.requestAdConfig(false, "", null);
|
||||
@ -111,6 +118,35 @@ public class DataUtils {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 为神策绑定有效的 OAID
|
||||
*/
|
||||
public static void bindValidOaidToSensor(boolean fromOaidResult) {
|
||||
if (isSensorOAIDBounded) return;
|
||||
|
||||
String oaid = HaloApp.getInstance().getOAID();
|
||||
|
||||
// 来自于 oaid 获取回调,或者说原始 oaid 已经获取成功
|
||||
if (fromOaidResult || originalOAIDIsReceived) {
|
||||
originalOAIDIsReceived = true;
|
||||
// 遇到异常的 OAID
|
||||
if (Constants.INVALID_OAID_1.equals(oaid)
|
||||
|| Constants.INVALID_OAID_2.equals(oaid)
|
||||
|| Constants.INVALID_OAID_3.equals(oaid)
|
||||
|| TextUtils.isEmpty(oaid)) {
|
||||
// 若 gid 不为空,那么整合 gid 作为 oaid https://jira.shanqu.cc/browse/GHZSCY-7004
|
||||
if (HaloApp.getInstance().getGid() != null) {
|
||||
oaid = "GID" + HaloApp.getInstance().getGid();
|
||||
SensorsBridge.INSTANCE.setOAID(oaid);
|
||||
isSensorOAIDBounded = true;
|
||||
}
|
||||
} else {
|
||||
SensorsBridge.INSTANCE.setOAID(oaid);
|
||||
isSensorOAIDBounded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取应用 gid 绑定的实名信息
|
||||
*/
|
||||
|
||||
@ -139,6 +139,7 @@ public class DetailDownloadUtils {
|
||||
// 游戏包含多 APK 的情况
|
||||
viewHolder.getMultiVersionDownloadTv().setText("选择下载你的版本" + (TextUtils.isEmpty(downloadAddWord) ? "" : "-" + downloadAddWord));
|
||||
viewHolder.getMultiVersionDownloadTv().setVisibility(View.VISIBLE);
|
||||
viewHolder.getDownloadPb().setTag(com.gh.gamecenter.feature.R.string.download, viewHolder.getMultiVersionDownloadTv().getText());
|
||||
viewHolder.getDownloadPb().setText("");
|
||||
viewHolder.getDownloadPb().setButtonStyle(DownloadButton.ButtonStyle.NORMAL);
|
||||
DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity);
|
||||
|
||||
@ -839,34 +839,25 @@ object DownloadItemUtils {
|
||||
} else {
|
||||
allStateClickCallback?.onCallback()
|
||||
clickCallback?.onCallback()
|
||||
if ("download" == gameEntity.reserveStatus) {
|
||||
ReservationHelper.showDeleteReservationDialog(context) {
|
||||
ReservationHelper.deleteReservation(gameEntity) {
|
||||
adapter?.notifyItemChanged(position)
|
||||
refreshCallback?.onCallback()
|
||||
}
|
||||
ReservationHelper.showCancelReservationDialog(context, gameEntity, {
|
||||
NewFlatLogUtils.logMyGameCancelReserveDialogClick(
|
||||
"确定取消",
|
||||
gameEntity.id,
|
||||
gameEntity.name ?: ""
|
||||
)
|
||||
ReservationHelper.cancelReservation(gameEntity) {
|
||||
adapter?.notifyItemChanged(position)
|
||||
refreshCallback?.onCallback()
|
||||
}
|
||||
} else {
|
||||
ReservationHelper.showCancelReservationDialog(context, gameEntity,{
|
||||
}, object : CancelListener {
|
||||
override fun onCancel() {
|
||||
NewFlatLogUtils.logMyGameCancelReserveDialogClick(
|
||||
"确定取消",
|
||||
"关闭弹窗",
|
||||
gameEntity.id,
|
||||
gameEntity.name ?: ""
|
||||
)
|
||||
ReservationHelper.cancelReservation(gameEntity) {
|
||||
adapter?.notifyItemChanged(position)
|
||||
refreshCallback?.onCallback()
|
||||
}
|
||||
}, object : CancelListener {
|
||||
override fun onCancel() {
|
||||
NewFlatLogUtils.logMyGameCancelReserveDialogClick(
|
||||
"关闭弹窗",
|
||||
gameEntity.id,
|
||||
gameEntity.name ?: ""
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
@ -53,6 +53,7 @@ object DownloadObserver {
|
||||
private const val CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED = "CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED"
|
||||
|
||||
private val mRetryableHashMap = hashMapOf<String, Boolean>()
|
||||
private val mRetryableProgressMap = hashMapOf<String, Long>()
|
||||
|
||||
/**
|
||||
* 当下载任务是 预约上线提醒 触发的,则所有弹窗均不显示
|
||||
@ -146,7 +147,8 @@ object DownloadObserver {
|
||||
|| DownloadStatus.timeout == status
|
||||
) {
|
||||
if (mRetryableHashMap[downloadEntity.url] == true
|
||||
&& NetworkUtils.isWifiConnected(HaloApp.getInstance().application)
|
||||
&& (NetworkUtils.isWifiConnected(HaloApp.getInstance().application)
|
||||
|| NDownloadBridge.isDownloadViaTrafficAllowed(downloadEntity))
|
||||
) {
|
||||
downloadManager.resumeDownload(downloadEntity.url)
|
||||
mRetryableHashMap[downloadEntity.url] = false
|
||||
@ -257,6 +259,7 @@ object DownloadObserver {
|
||||
}
|
||||
|
||||
mRetryableHashMap.remove(downloadEntity.url)
|
||||
mRetryableProgressMap.remove(downloadEntity.url)
|
||||
|
||||
EventBus.getDefault().post(EBDownloadStatus("done", "", "", "", downloadEntity.packageName, ""))
|
||||
}
|
||||
@ -264,7 +267,9 @@ object DownloadObserver {
|
||||
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
|
||||
|
||||
// 如果已下载大小发生变化,表示成功恢复下载,则重置重试标记
|
||||
if (status == DownloadStatus.downloading) {
|
||||
if (status == DownloadStatus.downloading
|
||||
&& downloadEntity.progress != mRetryableProgressMap[downloadEntity.url]) {
|
||||
mRetryableProgressMap[downloadEntity.url] = downloadEntity.progress
|
||||
mRetryableHashMap[downloadEntity.url] = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -2778,4 +2778,34 @@ object NewFlatLogUtils {
|
||||
parseAndPutMeta()(this)
|
||||
}.let(::log)
|
||||
}
|
||||
|
||||
// 自有开屏广告加载
|
||||
fun logSplashAdLoad(id: String) {
|
||||
json {
|
||||
KEY_EVENT to "splash_ad_load"
|
||||
"ad_id" to id
|
||||
parseAndPutMeta()(this)
|
||||
}.let(::log)
|
||||
}
|
||||
|
||||
// 自有开屏广告展示
|
||||
fun logSplashAdShow(id: String, duration: Long) {
|
||||
json {
|
||||
KEY_EVENT to "splash_ad_show"
|
||||
"ad_id" to id
|
||||
"duration" to duration
|
||||
parseAndPutMeta()(this)
|
||||
}.let(::log)
|
||||
}
|
||||
|
||||
// 自有开屏广告加载/展示失败
|
||||
@JvmStatic
|
||||
fun logSplashAdFail(id: String, error: String) {
|
||||
json {
|
||||
KEY_EVENT to "splash_ad_fail"
|
||||
"ad_id" to id
|
||||
"error" to error
|
||||
parseAndPutMeta()(this)
|
||||
}.let(::log)
|
||||
}
|
||||
}
|
||||
@ -18,7 +18,6 @@ import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.utils.MD5Utils
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.install.InstallService
|
||||
import com.gh.vspace.VHelper
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.DownloadEntity
|
||||
@ -194,12 +193,6 @@ object PackageInstaller {
|
||||
private fun install(context: Context, pkgPath: String, pkgName: String?) {
|
||||
HaloApp.put(Constants.LAST_INSTALL_GAME, pkgPath)
|
||||
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU && Build.MANUFACTURER.lowercase().contains("xiaomi")) {
|
||||
val foregroundServiceIntent = Intent(context, InstallService::class.java)
|
||||
foregroundServiceIntent.putExtra(InstallService.KEY_SERVICE_ACTION, InstallService.START_FOREGROUND)
|
||||
context.startForegroundService(foregroundServiceIntent)
|
||||
}
|
||||
|
||||
val installIntent = getInstallIntent(context, pkgPath)
|
||||
context.startActivity(installIntent)
|
||||
|
||||
@ -284,7 +277,12 @@ object PackageInstaller {
|
||||
installIntent.setDataAndType(uri, "application/vnd.android.package-archive")
|
||||
}
|
||||
|
||||
updateSystemInstallerIfAvailable(context, installIntent)
|
||||
// 优选系统的安装器(遇到 Exception 就回落到正常的安装器)
|
||||
try {
|
||||
updateSystemInstallerIfAvailable(context, installIntent)
|
||||
} catch (ignored: Exception) {
|
||||
// ignored
|
||||
}
|
||||
|
||||
InstallUtils.getInstance()
|
||||
.addInstall(PackageUtils.getPackageNameByPath(context, path))
|
||||
|
||||
@ -7,7 +7,7 @@ import com.gh.gamecenter.common.utils.isVGameDownloadInDualDownloadMode
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.GameInstall
|
||||
import com.gh.gamecenter.packagehelper.PackageRepository
|
||||
import com.gh.gamecenter.manager.PackagesManager
|
||||
import com.gh.vspace.VHelper
|
||||
|
||||
object PackageLauncher {
|
||||
@ -81,28 +81,11 @@ object PackageLauncher {
|
||||
gameEntity: GameEntity? = null,
|
||||
packageName: String?
|
||||
) {
|
||||
|
||||
if (packageName.isNullOrEmpty()) {
|
||||
ToastUtils.toast("启动失败")
|
||||
return
|
||||
}
|
||||
|
||||
// 获取 GameInstall 实体,用于记录启动日志用
|
||||
val gameInstall = if (gameEntity != null) {
|
||||
GameInstall.transformGameInstall(gameEntity, packageName)
|
||||
} else {
|
||||
PackageRepository.gameInstalled.find { it.packageName == packageName }
|
||||
}
|
||||
|
||||
if (gameInstall != null) {
|
||||
NewFlatLogUtils.logGameLaunch(
|
||||
gameId = gameInstall.id ?: "unknown",
|
||||
gameName = gameInstall.name ?: "unknown",
|
||||
gameCategory = gameInstall.category ?: "unknown",
|
||||
downloadStatus = if (gameInstall.downloadStatus == "demo") "试玩" else "下载"
|
||||
)
|
||||
}
|
||||
|
||||
try {
|
||||
val intent = context.applicationContext.packageManager.getLaunchIntentForPackage(packageName)
|
||||
if (intent != null) {
|
||||
@ -113,6 +96,26 @@ object PackageLauncher {
|
||||
} catch (e: Exception) {
|
||||
ToastUtils.toast( "启动失败")
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取 GameInstall 实体,用于记录启动日志用
|
||||
val gameInstall = if (gameEntity != null) {
|
||||
GameInstall.transformGameInstall(gameEntity, packageName)
|
||||
} else {
|
||||
PackagesManager.getInstalledList().find { it.packageName == packageName }
|
||||
}
|
||||
|
||||
if (gameInstall != null) {
|
||||
NewFlatLogUtils.logGameLaunch(
|
||||
gameId = gameInstall.id ?: "unknown",
|
||||
gameName = gameInstall.name ?: "unknown",
|
||||
gameCategory = gameInstall.category ?: "unknown",
|
||||
downloadStatus = if (gameInstall.downloadStatus == "demo") "试玩" else "下载"
|
||||
)
|
||||
}
|
||||
} catch (e: RuntimeException) {
|
||||
// 都 DeadSystemException 了,还想啥日志上报
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -14,7 +14,6 @@ import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AndroidException;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@ -29,9 +28,9 @@ import com.gh.gamecenter.BuildConfig;
|
||||
import com.gh.gamecenter.common.constant.Constants;
|
||||
import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.core.utils.MD5Utils;
|
||||
import com.gh.gamecenter.entity.GameUpdateEntity;
|
||||
import com.gh.gamecenter.feature.entity.ApkEntity;
|
||||
import com.gh.gamecenter.feature.entity.GameEntity;
|
||||
import com.gh.gamecenter.entity.GameUpdateEntity;
|
||||
import com.gh.gamecenter.feature.utils.SentryHelper;
|
||||
import com.gh.gamecenter.manager.PackagesManager;
|
||||
import com.gh.vspace.VHelper;
|
||||
@ -302,7 +301,7 @@ public class PackageUtils {
|
||||
Signature[] signatures = packageInfo.signatures;
|
||||
|
||||
// 使用幸运破解器破解安卓签名认证可能会出现不用签名也能装的情况,这里有可能是空的
|
||||
if (signatures[0] != null) {
|
||||
if (signatures.length > 0 && signatures[0] != null) {
|
||||
return parseSignature(signatures[0].toByteArray());
|
||||
} else {
|
||||
return new String[]{null, null};
|
||||
@ -542,10 +541,8 @@ public class PackageUtils {
|
||||
try {
|
||||
Intent intent = context.getApplicationContext().getPackageManager().getLaunchIntentForPackage(packageName);
|
||||
return intent != null;
|
||||
} catch (IllegalArgumentException exception) {
|
||||
// 一些设备调用获取 intent 的时候会触发 Parcel.readException !
|
||||
exception.printStackTrace();
|
||||
return false;
|
||||
} catch (Exception exception) {
|
||||
return PackageHelper.INSTANCE.getLocalPackageNameSet().contains(packageName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -645,6 +642,19 @@ public class PackageUtils {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 获取应用的名称
|
||||
*/
|
||||
public static CharSequence getNameByPackageName(Context context, String packageName) {
|
||||
try {
|
||||
PackageManager packageManager = context.getApplicationContext().getPackageManager();
|
||||
return packageManager.getApplicationLabel(packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 获取应用的 icon
|
||||
|
||||
@ -29,53 +29,31 @@ import okhttp3.ResponseBody
|
||||
|
||||
object ReservationHelper {
|
||||
|
||||
@JvmStatic
|
||||
fun deleteReservation(game: GameEntity, refreshCallback: EmptyCallback) {
|
||||
deleteOrCancelReservation(game, true, refreshCallback)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun cancelReservation(game: GameEntity, refreshCallback: EmptyCallback) {
|
||||
deleteOrCancelReservation(game, false, refreshCallback)
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private fun deleteOrCancelReservation(
|
||||
@JvmStatic
|
||||
fun cancelReservation(
|
||||
game: GameEntity,
|
||||
deleteReservation: Boolean,
|
||||
refreshCallback: EmptyCallback
|
||||
) {
|
||||
|
||||
val retrofit = RetrofitManager.getInstance()
|
||||
val single = if (deleteReservation) {
|
||||
retrofit.newApi
|
||||
.deleteGameReservation(
|
||||
game.id,
|
||||
getReserveRequestBody(game, context = HaloApp.getInstance().application)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
} else {
|
||||
retrofit.newApi
|
||||
.cancelGameReservation(
|
||||
game.id,
|
||||
getReserveRequestBody(game, context = HaloApp.getInstance().application)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
}
|
||||
retrofit.newApi
|
||||
.cancelGameReservation(
|
||||
game.id,
|
||||
getReserveRequestBody(game, context = HaloApp.getInstance().application)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BiResponse<ResponseBody>() {
|
||||
override fun onSuccess(data: ResponseBody) {
|
||||
ReservationRepository.removeReservationFromMemoryAndRefresh(game.id)
|
||||
refreshCallback.onCallback()
|
||||
}
|
||||
|
||||
single.subscribe(object : BiResponse<ResponseBody>() {
|
||||
override fun onSuccess(data: ResponseBody) {
|
||||
ReservationRepository.removeReservationFromMemoryAndRefresh(game.id)
|
||||
refreshCallback.onCallback()
|
||||
}
|
||||
|
||||
override fun onFailure(exception: Exception) {
|
||||
Utils.toast(HaloApp.getInstance().application, exception.message)
|
||||
exception.printStackTrace()
|
||||
}
|
||||
})
|
||||
override fun onFailure(exception: Exception) {
|
||||
Utils.toast(HaloApp.getInstance().application, exception.message)
|
||||
exception.printStackTrace()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@ -146,21 +124,6 @@ object ReservationHelper {
|
||||
})
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun showDeleteReservationDialog(context: Context, emptyCallback: EmptyCallback) {
|
||||
DialogUtils.showCancelOrDeleteReservationDialog(
|
||||
context,
|
||||
"删除预约",
|
||||
"游戏已上线,你可以删除此预约记录,确定删除吗?",
|
||||
"确定删除",
|
||||
"暂不删除", object : ConfirmListener {
|
||||
override fun onConfirm() {
|
||||
emptyCallback.onCallback()
|
||||
}
|
||||
}, null
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun showCancelReservationDialog(context: Context, game: GameEntity?, emptyCallback: EmptyCallback) {
|
||||
showCancelReservationDialog(context, game, emptyCallback, null)
|
||||
|
||||
@ -2,6 +2,7 @@ package com.gh.download.simple
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.database.sqlite.SQLiteException
|
||||
import android.database.sqlite.SQLiteFullException
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.lg.download.*
|
||||
import com.lg.download.listener.InnerDownloadListener
|
||||
@ -174,6 +175,9 @@ object DownloadMessageHandler : InnerDownloadListener {
|
||||
DownloadError.CONTENT_LENGTH_IS_ZERO -> {
|
||||
ToastUtils.toast("下载链接异常,请检查")
|
||||
}
|
||||
DownloadError.DISK_IS_FULL -> {
|
||||
ToastUtils.toast("磁盘已满,请清理空间后获得更好的体验")
|
||||
}
|
||||
else -> {
|
||||
// 想怎么处理就怎么处理
|
||||
}
|
||||
@ -264,18 +268,30 @@ object DownloadMessageHandler : InnerDownloadListener {
|
||||
}
|
||||
|
||||
fun insertDownloadToDatabase(downloadEntity: SimpleDownloadEntity) {
|
||||
mDownloadDao.insertDownloadEntity(downloadEntity)
|
||||
updateDownloadList()
|
||||
try {
|
||||
mDownloadDao.insertDownloadEntity(downloadEntity)
|
||||
updateDownloadList()
|
||||
} catch (e: SQLiteException) {
|
||||
if (e is SQLiteFullException) {
|
||||
ToastUtils.showToast("磁盘已满,请清理空间获得更好的体验")
|
||||
}
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
fun updateDownloadToDatabase(
|
||||
downloadEntity: SimpleDownloadEntity,
|
||||
updateDownloadList: Boolean = false
|
||||
) {
|
||||
mDownloadDao.updateDownloadEntity(downloadEntity)
|
||||
try {
|
||||
mDownloadDao.updateDownloadEntity(downloadEntity)
|
||||
|
||||
if (updateDownloadList) {
|
||||
updateDownloadList()
|
||||
if (updateDownloadList) {
|
||||
updateDownloadList()
|
||||
}
|
||||
} catch (e: SQLiteFullException) {
|
||||
// 底层的下载服务遇到 SQLiteFullException 时会自动暂停下载任务,上层这里就不用纠结处理方式了
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -166,8 +166,13 @@ public class MainActivity extends BaseActivity {
|
||||
private final Handler handler = new Handler();
|
||||
private boolean mShouldShowAd = false; // 是否显示广告
|
||||
|
||||
private Bundle mTempSavedInstanceState;
|
||||
private boolean mFragmentIsCreated = false;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
mTempSavedInstanceState = savedInstanceState;
|
||||
|
||||
mShouldShowAd = getIntent().getBooleanExtra(SHOW_AD, false) && savedInstanceState == null
|
||||
&& !HaloApp.getInstance().isAlreadyUpAndRunning;
|
||||
HaloApp.getInstance().isAlreadyUpAndRunning = true;
|
||||
@ -175,21 +180,12 @@ public class MainActivity extends BaseActivity {
|
||||
mMainWrapperViewModel = new ViewModelProvider(this, new MainWrapperViewModel.Factory(HaloApp.getInstance()))
|
||||
.get(MainWrapperViewModel.class);
|
||||
|
||||
DisplayUtils.transparentStatusBar(this);
|
||||
DisplayUtils.updateGlobalScreen(this);
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setStatusBarColor(Color.TRANSPARENT);
|
||||
|
||||
Fragment fragmentFromFM = getSupportFragmentManager().findFragmentById(com.gh.gamecenter.selector.R.id.layout_activity_content);
|
||||
|
||||
mMainWrapperFragment = fragmentFromFM != null ? (MainWrapperFragment) fragmentFromFM : new MainWrapperFragment();
|
||||
if (savedInstanceState != null) {
|
||||
mMainWrapperFragment.setArguments(savedInstanceState);
|
||||
} else if (getIntent() != null) {
|
||||
mMainWrapperFragment.setArguments(getIntent().getExtras());
|
||||
}
|
||||
replaceFragment(mMainWrapperFragment);
|
||||
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
if (HaloApp.getInstance().isNewForThisVersion) {
|
||||
LunchType lunchType = HaloApp.getInstance().getLaunchType();
|
||||
@ -215,7 +211,6 @@ public class MainActivity extends BaseActivity {
|
||||
DataUtils.getGid();
|
||||
}
|
||||
|
||||
|
||||
mPackageViewModel = ViewModelProviders.of(this, new PackageViewModel.Factory()).get(PackageViewModel.class);
|
||||
|
||||
final boolean containsErrorMsg = com.gh.gamecenter.common.constant.Config.isContainsErrorMsg();
|
||||
@ -273,6 +268,7 @@ public class MainActivity extends BaseActivity {
|
||||
if (mShouldShowAd) {
|
||||
showAd();
|
||||
} else {
|
||||
doInitMainFragment(mTempSavedInstanceState);
|
||||
hideTextAd();
|
||||
hideSplashAd();
|
||||
}
|
||||
@ -328,6 +324,23 @@ public class MainActivity extends BaseActivity {
|
||||
CertificationSwitchHelper.getCertificationSwitch();
|
||||
}
|
||||
|
||||
private void doInitMainFragment(Bundle savedInstanceState) {
|
||||
if (mFragmentIsCreated) return;
|
||||
|
||||
mTempSavedInstanceState = null;
|
||||
Fragment fragmentFromFM = getSupportFragmentManager().findFragmentById(com.gh.gamecenter.selector.R.id.layout_activity_content);
|
||||
|
||||
mMainWrapperFragment = fragmentFromFM != null ? (MainWrapperFragment) fragmentFromFM : new MainWrapperFragment();
|
||||
if (savedInstanceState != null) {
|
||||
mMainWrapperFragment.setArguments(savedInstanceState);
|
||||
} else if (getIntent() != null) {
|
||||
mMainWrapperFragment.setArguments(getIntent().getExtras());
|
||||
}
|
||||
replaceFragment(mMainWrapperFragment);
|
||||
|
||||
mFragmentIsCreated = true;
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private void getTeenagerMode() {
|
||||
RetrofitManager.getInstance()
|
||||
@ -541,19 +554,31 @@ public class MainActivity extends BaseActivity {
|
||||
protected void handleMessage(Message msg) {
|
||||
super.handleMessage(msg);
|
||||
if (msg.what == COUNTDOWN_AD || msg.what == COUNTDOWN_SDK_AD) {
|
||||
mCountdownCount++;
|
||||
int maxCount;
|
||||
|
||||
if (msg.what == COUNTDOWN_AD) {
|
||||
maxCount = mCountdownMaxCount;
|
||||
} else {
|
||||
maxCount = COUNTDOWN_SDK_MAX_COUNT;
|
||||
}
|
||||
|
||||
// 读秒到一半的时候初始化 MainWrapperFragment
|
||||
if (mCountdownCount == maxCount / 2) {
|
||||
doInitMainFragment(mTempSavedInstanceState);
|
||||
}
|
||||
|
||||
mCountdownCount++;
|
||||
|
||||
if (maxCount < mCountdownCount) {
|
||||
AdDelegateHelper.INSTANCE.setShowingSplashAd(false);
|
||||
hideSplashAd();
|
||||
|
||||
if (msg.what == COUNTDOWN_AD && msg.obj instanceof StartupAdEntity) {
|
||||
StartupAdEntity ad = (StartupAdEntity) msg.obj;
|
||||
if (!AdDelegateHelper.INSTANCE.isOwnerSplashAdShown()) {
|
||||
com.gh.common.util.NewFlatLogUtils.logSplashAdFail(ad.getId(), "广告加载超时");
|
||||
}
|
||||
AdDelegateHelper.INSTANCE.setOwnerSplashAdShown(false);
|
||||
LinkEntity linkEntity = ad.getJump();
|
||||
SensorsBridge.trackEvent(
|
||||
"SplashAdOwnSkip",
|
||||
@ -633,10 +658,11 @@ public class MainActivity extends BaseActivity {
|
||||
ExtensionsKt.removeFromParent(startSdkAdIcpContainer, true);
|
||||
}
|
||||
|
||||
onSplashHidden();
|
||||
onAdHidden();
|
||||
}
|
||||
|
||||
private void onSplashHidden() {
|
||||
private void onAdHidden() {
|
||||
doInitMainFragment(mTempSavedInstanceState);
|
||||
// 通知全局弹窗可以进行显示
|
||||
AppExecutor.getUiExecutor().execute(GlobalPriorityChainHelper.INSTANCE::start);
|
||||
}
|
||||
@ -854,7 +880,9 @@ public class MainActivity extends BaseActivity {
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0 && !mMainWrapperFragment.onHandleBackPressed()) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0
|
||||
&& mMainWrapperFragment != null
|
||||
&& !mMainWrapperFragment.onHandleBackPressed()) {
|
||||
DownloadEntity downloadEntity = null;
|
||||
for (DownloadEntity entity : DownloadManager.getInstance().getAllDownloadEntityExcludeSilentTask()) {
|
||||
if (entity.getStatus().equals(DownloadStatus.done)) {
|
||||
@ -1045,6 +1073,7 @@ public class MainActivity extends BaseActivity {
|
||||
blackList.add(R.id.historyTv);
|
||||
blackList.add(R.id.myCollectionTv);
|
||||
blackList.add(R.id.searchTv);
|
||||
blackList.add(R.id.subject_tab);
|
||||
updateStaticView(view, blackList);
|
||||
|
||||
View communityHomeWrapper = view.findViewById(R.id.communityHomeContainer);
|
||||
|
||||
@ -15,6 +15,7 @@ import androidx.core.widget.doAfterTextChanged
|
||||
import androidx.core.widget.doOnTextChanged
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import com.gh.common.fragment.popBackStackAllowStateLoss
|
||||
import com.gh.common.util.DataCollectionUtils
|
||||
import com.gh.common.util.LogUtils
|
||||
import com.gh.gamecenter.DisplayType.*
|
||||
@ -311,6 +312,19 @@ open class SearchActivity : BaseActivity() {
|
||||
// MtaHelper.onEvent("游戏搜索", "主动搜索", newSearchKey)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
val newSearchKey = searchEt.text.toString().trim { it <= ' ' }
|
||||
if (newSearchKey.isBlank()) {
|
||||
try {
|
||||
popBackToFragment(SearchDefaultFragment::class.java.name)
|
||||
} catch (e: Exception) {
|
||||
// no implement
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun provideDao(): ISearchHistoryDao = SearchHistoryDao(this)
|
||||
|
||||
open fun updateDisplayType(type: DisplayType) {
|
||||
@ -381,7 +395,7 @@ open class SearchActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
protected fun popBackToFragment(tag: String) {
|
||||
supportFragmentManager.popBackStack(tag, 0)
|
||||
supportFragmentManager.popBackStackAllowStateLoss(tag, 0)
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
|
||||
@ -282,11 +282,11 @@ 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)
|
||||
}
|
||||
// val pushProvider = ARouter.getInstance().build(RouteConsts.provider.push).navigation() as? IPushProvider
|
||||
// val registrationId = pushProvider?.getRegistrationId(this)
|
||||
// if (!registrationId.isNullOrEmpty()) {
|
||||
// SensorsBridge.profileSet(KEY_REGISTRATION_ID, registrationId)
|
||||
// }
|
||||
}
|
||||
|
||||
private fun prefetchData() {
|
||||
|
||||
@ -455,17 +455,9 @@ class DetailViewHolder(
|
||||
}
|
||||
|
||||
ButtonStyle.RESERVED -> {
|
||||
if ("download" == mGameEntity.reserveStatus) {
|
||||
ReservationHelper.showDeleteReservationDialog(mViewHolder.context) {
|
||||
ReservationHelper.deleteReservation(mGameEntity) {
|
||||
DetailDownloadUtils.updateViewHolder(mViewHolder)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ReservationHelper.showCancelReservationDialog(mViewHolder.context, mGameEntity) {
|
||||
ReservationHelper.cancelReservation(mGameEntity) {
|
||||
DetailDownloadUtils.updateViewHolder(mViewHolder)
|
||||
}
|
||||
ReservationHelper.showCancelReservationDialog(mViewHolder.context, mGameEntity) {
|
||||
ReservationHelper.cancelReservation(mGameEntity) {
|
||||
DetailDownloadUtils.updateViewHolder(mViewHolder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
package com.gh.gamecenter.authorization
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import com.gh.common.util.CheckLoginUtils
|
||||
import com.gh.common.util.DialogUtils
|
||||
import com.gh.common.util.NewFlatLogUtils
|
||||
import com.gh.common.util.PackageUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.activity.ToolBarActivity
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
@ -16,6 +18,7 @@ import com.gh.gamecenter.common.utils.viewModelProvider
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.databinding.ActivityAuthorizationBinding
|
||||
import com.gh.gamecenter.login.user.UserManager
|
||||
import com.gh.gamecenter.login.user.UserRepository
|
||||
import com.gh.gamecenter.login.view.LoginActivity
|
||||
import com.gh.vspace.VHelper
|
||||
import com.lightgame.utils.Utils
|
||||
@ -68,6 +71,8 @@ class AuthorizationActivity : ToolBarActivity() {
|
||||
//授权token
|
||||
private var mToken = ""
|
||||
|
||||
private var loadingDialog: Dialog? = null
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_authorization
|
||||
}
|
||||
@ -80,11 +85,16 @@ class AuthorizationActivity : ToolBarActivity() {
|
||||
mBinding = ActivityAuthorizationBinding.bind(mContentView)
|
||||
checkParam()
|
||||
initView()
|
||||
mBinding.authorizeBtn.postDelayed({
|
||||
mBaseHandler.post {
|
||||
if (loadingDialog == null) {
|
||||
loadingDialog = DialogUtils.showWaitDialog(this, "请稍后...")
|
||||
}
|
||||
}
|
||||
UserRepository.getInstance().loginUserInfo.observe(this) {
|
||||
checkLogin {
|
||||
initUserInfo()
|
||||
}
|
||||
}, 500)
|
||||
}
|
||||
NewFlatLogUtils.logLoginFromGHZSShow(
|
||||
gameId = gameId,
|
||||
gameName = gameName
|
||||
@ -97,14 +107,21 @@ class AuthorizationActivity : ToolBarActivity() {
|
||||
}
|
||||
|
||||
private fun initData() {
|
||||
if (mToken.isNotEmpty() || isFinishing) return
|
||||
val loadingDialog = DialogUtils.showWaitDialog(this, "请稍后...")
|
||||
if (mToken.isNotEmpty() || isFinishing) {
|
||||
loadingDialog?.dismiss()
|
||||
return
|
||||
}
|
||||
if (loadingDialog == null) {
|
||||
loadingDialog = DialogUtils.showWaitDialog(this, "请稍后...")
|
||||
} else if (loadingDialog?.isShowing == false) {
|
||||
loadingDialog?.show()
|
||||
}
|
||||
mViewModel.getAccessToken(listOf(mContent), {
|
||||
mToken = it
|
||||
loadingDialog.dismiss()
|
||||
loadingDialog?.dismiss()
|
||||
}, {
|
||||
toast("获取token失败")
|
||||
loadingDialog.dismiss()
|
||||
loadingDialog?.dismiss()
|
||||
})
|
||||
}
|
||||
|
||||
@ -152,8 +169,8 @@ class AuthorizationActivity : ToolBarActivity() {
|
||||
private fun initView() {
|
||||
//通过包名获取app图标和名称
|
||||
val pkgName = mRemotePkgName ?: return
|
||||
val icon = packageManager.getApplicationIcon(pkgName)
|
||||
val name = packageManager.getApplicationLabel(packageManager.getApplicationInfo(pkgName, 0))
|
||||
val icon = PackageUtils.getIconByPackageName(this, pkgName)
|
||||
val name = PackageUtils.getNameByPackageName(this, pkgName)
|
||||
mBinding.authorizeAppIcon.setImageDrawable(icon)
|
||||
mBinding.authorizeAppName.text = name
|
||||
mBinding.authorizeBtn.setOnClickListener {
|
||||
@ -242,10 +259,10 @@ class AuthorizationActivity : ToolBarActivity() {
|
||||
VHelper.launch(this, gamePkg, ignoreGApps = true, showLoading = showLoading)
|
||||
return
|
||||
}
|
||||
val remotePkgName = this.mRemotePkgName
|
||||
if (remotePkgName != null) {// 跳转回其他授权app
|
||||
startActivity(packageManager.getLaunchIntentForPackage(remotePkgName))
|
||||
}
|
||||
// val remotePkgName = this.mRemotePkgName
|
||||
// if (remotePkgName != null) {// 跳转回其他授权app
|
||||
// startActivity(packageManager.getLaunchIntentForPackage(remotePkgName))
|
||||
// }
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
|
||||
@ -18,7 +18,13 @@ data class SearchSubjectEntity(
|
||||
@SerializedName("ad_icon_active")
|
||||
val adIconActive: Boolean = false,
|
||||
// 本地字段,标记是否为微信小游戏CPM专题
|
||||
var isWGameSubjectCPM: Boolean = false
|
||||
var isWGameSubjectCPM: Boolean = false,
|
||||
val type: String = ""
|
||||
) : Parcelable {
|
||||
|
||||
companion object {
|
||||
const val TYPE_WECHAT_GAME_CPM_COLUMN = "wechat_game_cpm_column"
|
||||
}
|
||||
|
||||
fun getFilterGame() = RegionSettingHelper.filterGame(games)
|
||||
}
|
||||
@ -209,7 +209,7 @@ class GameCollectionSquareFragment : LazyListFragment<GamesCollectionEntity, Gam
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (data == null || resultCode != Activity.RESULT_OK) return
|
||||
if (data == null || resultCode != Activity.RESULT_OK || !::mViewModel.isInitialized) return
|
||||
if (requestCode == REQUEST_SELECT_TAG) {
|
||||
val tagInfoEntity = data.getParcelableExtra<TagInfoEntity>(GameCollectionTagSelectFragment.SELECTED_TAG)
|
||||
val tagCategory = data.getStringExtra(GameCollectionTagSelectFragment.SELECTED_TAG_CATEGORY)
|
||||
|
||||
@ -866,10 +866,11 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
|
||||
showConcernIconAtBottomBarIfAvailable()
|
||||
|
||||
val downloadEntitySnapshot = DownloadManager.getInstance().getDownloadEntitySnapshot(mGameEntity)
|
||||
val downloadEntitySnapshot = DownloadManager.getInstance().getDownloadEntitySnapshot(mGameEntity)
|
||||
|
||||
if (isSpecialDownloadDialogAvailable(downloadEntitySnapshot)
|
||||
&& downloadEntitySnapshot != null) {
|
||||
&& downloadEntitySnapshot != null
|
||||
) {
|
||||
updateSpecialDownloadDialogIcon(true)
|
||||
}
|
||||
|
||||
@ -1855,19 +1856,10 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
|
||||
|
||||
)
|
||||
} else {
|
||||
if ("download" == mGameEntity?.reserveStatus) {
|
||||
ReservationHelper.showDeleteReservationDialog(requireContext()) {
|
||||
ReservationHelper.deleteReservation(mGameEntity!!) {
|
||||
DetailDownloadUtils.updateViewHolder(detailViewHolder)
|
||||
showReserveBtn(isShowReserveBtn())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ReservationHelper.showCancelReservationDialog(requireContext(), mGameEntity) {
|
||||
ReservationHelper.cancelReservation(mGameEntity!!) {
|
||||
DetailDownloadUtils.updateViewHolder(detailViewHolder)
|
||||
showReserveBtn(isShowReserveBtn())
|
||||
}
|
||||
ReservationHelper.showCancelReservationDialog(requireContext(), mGameEntity) {
|
||||
ReservationHelper.cancelReservation(mGameEntity!!) {
|
||||
DetailDownloadUtils.updateViewHolder(detailViewHolder)
|
||||
showReserveBtn(isShowReserveBtn())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -983,14 +983,17 @@ class DescAdapter(
|
||||
setExpandMaxLines(maxDesLines)
|
||||
setIsExpanded(Int.MAX_VALUE == maxDesLines)
|
||||
if (customColumn.isHtmlDes == true) {
|
||||
val decoratedDesBrief = (customColumn.desBrief ?: "").dropFontColorInDarkMode(contentTv.context)
|
||||
val decoratedDes = (customColumn.des ?: "").dropFontColorInDarkMode(contentTv.context)
|
||||
|
||||
shrankSpanned = HtmlCompat.fromHtml(
|
||||
customColumn.desBrief ?: "",
|
||||
decoratedDesBrief,
|
||||
HtmlCompat.FROM_HTML_MODE_COMPACT,
|
||||
PicassoImageGetter(contentTv),
|
||||
ExtraTagHandler()
|
||||
)
|
||||
expandedSpanned = HtmlCompat.fromHtml(
|
||||
customColumn.des ?: "",
|
||||
decoratedDes,
|
||||
HtmlCompat.FROM_HTML_MODE_COMPACT,
|
||||
PicassoImageGetter(contentTv),
|
||||
ExtraTagHandler()
|
||||
|
||||
@ -25,10 +25,10 @@ import com.gh.gamecenter.common.utils.toPx
|
||||
import com.gh.gamecenter.core.iinterface.IScrollable
|
||||
import com.gh.gamecenter.core.utils.MtaHelper
|
||||
import com.gh.gamecenter.core.utils.SpanBuilder
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.RatingComment
|
||||
import com.gh.gamecenter.eventbus.EBStar
|
||||
import com.gh.gamecenter.eventbus.EBTypeChange
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.gamedetail.GameDetailFragment
|
||||
import com.halo.assistant.HaloApp
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
@ -60,7 +60,7 @@ class RatingFragment : LazyListFragment<RatingComment, RatingViewModel>(), IScro
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (requestCode == RATING_EDIT_REQUEST && resultCode == Activity.RESULT_OK) {
|
||||
mListViewModel.initData()
|
||||
mListViewModel?.initData()
|
||||
} else if (
|
||||
(requestCode == RATING_REPLAY_REQUEST || requestCode == RATING_PATCH_REQUEST)
|
||||
&& resultCode == Activity.RESULT_OK
|
||||
|
||||
@ -3,7 +3,11 @@ package com.gh.gamecenter.home.custom
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@ -54,6 +58,7 @@ import com.gh.gamecenter.feature.entity.PageLocation
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.ExposureType
|
||||
import com.gh.gamecenter.feature.minigame.MiniGameItemHelper
|
||||
import com.gh.gamecenter.feature.utils.SentryHelper
|
||||
import com.gh.gamecenter.game.commoncollection.detail.CustomCommonCollectionDetailActivity
|
||||
import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity
|
||||
import com.gh.gamecenter.home.PageConfigure
|
||||
@ -69,6 +74,9 @@ import com.gh.gamecenter.wrapper.SearchToolbarTabWrapperViewModel
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.DataWatcher
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.scwang.smartrefresh.layout.api.RefreshLayout
|
||||
import com.scwang.smartrefresh.layout.constant.RefreshState
|
||||
import com.shuyu.gsyvideoplayer.video.base.GSYVideoView
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
|
||||
@ -179,6 +187,22 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
viewModel.init(pageConfigure, searchToolbarTabWrapperViewModel, pageLocation)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
binding = try {
|
||||
FragmentCustomBinding.inflate(layoutInflater)
|
||||
} catch (e: Exception) {
|
||||
SentryHelper.onEvent(
|
||||
"VIEW_BINDING_BIND_ERROR",
|
||||
"digest", e.localizedMessage,
|
||||
"gid", HaloApp.getInstance().gid
|
||||
)
|
||||
// 玄学,重试一次,该闪退闪退
|
||||
FragmentCustomBinding.inflate(layoutInflater)
|
||||
}
|
||||
mCachedView = binding.root
|
||||
return mCachedView
|
||||
}
|
||||
|
||||
override fun getRealLayoutId() = R.layout.fragment_custom
|
||||
|
||||
override fun onFragmentFirstVisible() {
|
||||
@ -215,7 +239,7 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
viewModel.loadFirst(false)
|
||||
}
|
||||
}
|
||||
binding.reuseNoConnectionStub.inflate()
|
||||
binding.reuseNoConnectionStub.inflateOrShow()
|
||||
} else {
|
||||
noConnectionBinding?.root?.visibility = View.VISIBLE
|
||||
}
|
||||
@ -225,7 +249,7 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
noDataBinding = ReuseNoneDataBinding.bind(inflated)
|
||||
noDataBinding?.root?.visibility = View.VISIBLE
|
||||
}
|
||||
binding.reuseNoDataStub.inflate()
|
||||
binding.reuseNoDataStub.inflateOrShow()
|
||||
} else {
|
||||
noDataBinding?.root?.visibility = View.VISIBLE
|
||||
}
|
||||
@ -275,9 +299,12 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
if (searchBarBinding == null) {
|
||||
binding.reuseSearchBarStub.setOnInflateListener { _, inflated ->
|
||||
searchBarBinding = LayoutSearchBarBinding.bind(inflated)
|
||||
binding.gameRefresh.updateLayoutParams<RelativeLayout.LayoutParams> {
|
||||
addRule(RelativeLayout.BELOW, R.id.reuseSearchBar)
|
||||
}
|
||||
initSearchBar(it)
|
||||
}
|
||||
binding.reuseSearchBarStub.inflate()
|
||||
binding.reuseSearchBarStub.inflateOrShow()
|
||||
} else {
|
||||
initSearchBar(it)
|
||||
}
|
||||
@ -490,8 +517,6 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
override fun initRealView() {
|
||||
super.initRealView()
|
||||
|
||||
binding = FragmentCustomBinding.bind(mCachedView)
|
||||
|
||||
scrollCalculatorHelper = ScrollCalculatorHelper(binding.gameList, R.id.autoVideoView, 0, false)
|
||||
|
||||
buildPriorityChain()
|
||||
@ -745,7 +770,7 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
}
|
||||
}
|
||||
|
||||
override fun setScrollEnabled(isScrollEnabled: Boolean) {
|
||||
private fun setScrollEnabled(isScrollEnabled: Boolean) {
|
||||
if (::layoutManager.isInitialized) {
|
||||
layoutManager.isScrollVerticallyEnabled = isScrollEnabled
|
||||
}
|
||||
@ -761,6 +786,32 @@ class CustomPageFragment : LazyFragment(), ISmartRefreshContent, IScrollable {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStateChanged(refreshLayout: RefreshLayout, oldState: RefreshState, newState: RefreshState) {
|
||||
if (oldState == RefreshState.None && newState == RefreshState.PullDownToRefresh) {
|
||||
pauseVideo()
|
||||
} else if ((oldState == RefreshState.TwoLevelFinish || oldState == RefreshState.RefreshFinish) && newState == RefreshState.None) {
|
||||
val currentPlayer = scrollCalculatorHelper.currentPlayer
|
||||
if (currentPlayer == null) {
|
||||
scrollCalculatorHelper.playIfValid()
|
||||
} else if (currentPlayer.currentState == GSYVideoView.CURRENT_STATE_PAUSE) {
|
||||
resumeVideo()
|
||||
}
|
||||
}
|
||||
|
||||
when (newState) {
|
||||
RefreshState.TwoLevel -> {
|
||||
setScrollEnabled(false)
|
||||
}
|
||||
RefreshState.None -> {
|
||||
setScrollEnabled(true)
|
||||
}
|
||||
|
||||
else -> {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun scrollToTop() {
|
||||
if (::binding.isInitialized) {
|
||||
binding.gameList.stopScroll()
|
||||
|
||||
@ -6,6 +6,8 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.utils.goneIf
|
||||
import com.gh.gamecenter.common.utils.toBinding
|
||||
import com.gh.gamecenter.common.utils.toColor
|
||||
import com.gh.gamecenter.common.utils.toDrawable
|
||||
import com.gh.gamecenter.databinding.RecyclerContentLabelLaneItemBinding
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageData
|
||||
|
||||
@ -28,6 +30,10 @@ class ContentLabelLaneAdapter(
|
||||
override fun onBindViewHolder(holder: ContentLabelChildViewHolder, position: Int) {
|
||||
val item = getItem(position)
|
||||
with(holder.binding) {
|
||||
vBackground.background = R.drawable.bg_shape_content_label_lane_item.toDrawable(context)
|
||||
tvTitle.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(context))
|
||||
tvSubTitle.setTextColor(com.gh.gamecenter.common.R.color.primary_theme.toColor(context))
|
||||
|
||||
ivIcon.goneIf(item.image.isBlank()){
|
||||
ivIcon.displayGameIcon(item.image, null, null)
|
||||
}
|
||||
|
||||
@ -806,7 +806,7 @@ class CustomPageRepository private constructor(
|
||||
|
||||
fun loadChangeSubjectGame(subjectEntity: SubjectEntity): Observable<List<GameEntity>> =
|
||||
if (subjectEntity.isWechatColumnCPM) {// 微信小游戏CPM专题的“换一批”接口
|
||||
wGameSubjectCPMRemoteDataSource.getRecommendCPMList(2, 10).toObservable()
|
||||
wGameSubjectCPMRemoteDataSource.getEditorRecommendCPMList(2, 10).toObservable()
|
||||
} else {
|
||||
remoteDataSource.loadChangeSubjectGame(subjectEntity)
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ class SubjectTracker(private val pageLocation: PageLocation) {
|
||||
pageLocation.pageName,
|
||||
subject?.id ?: "",
|
||||
subject?.name ?: "",
|
||||
"最近在玩",
|
||||
"自定义页面",
|
||||
item.componentStyle,
|
||||
"",
|
||||
)
|
||||
|
||||
@ -363,7 +363,7 @@ class CommonContentHomeSlideWithCardsUi(
|
||||
homeSlideCardItemBinding.cardIv.visibility = View.VISIBLE
|
||||
// 防止重复加载图片导致闪烁
|
||||
if (homeSubSlide.image != cardIv.getTag(R.string.tag_img_url_id)) {
|
||||
ImageUtils.display(cardIv, homeSubSlide.image, false, AlphaGradientProcess())
|
||||
ImageUtils.display(cardIv, homeSubSlide.image, true, AlphaGradientProcess())
|
||||
cardIv.setTag(R.string.tag_img_url_id, homeSubSlide.image)
|
||||
}
|
||||
ConstraintSet().apply {
|
||||
@ -398,7 +398,7 @@ class CommonContentHomeSlideWithCardsUi(
|
||||
descTv.text = homeSubSlide.cardDesc
|
||||
// 防止重复加载图片导致闪烁
|
||||
if (homeSubSlide.image != cardIv.getTag(R.string.tag_img_url_id)) {
|
||||
ImageUtils.display(cardIv, homeSubSlide.image, false, AlphaGradientProcess())
|
||||
ImageUtils.display(cardIv, homeSubSlide.image, true, AlphaGradientProcess())
|
||||
cardIv.setTag(R.string.tag_img_url_id, homeSubSlide.image)
|
||||
}
|
||||
ConstraintSet().apply {
|
||||
|
||||
@ -40,7 +40,7 @@ class CustomGameGallerySlideViewHolder(
|
||||
override fun bindView(item: CustomPageItem) {
|
||||
super.bindView(item)
|
||||
if (item is CustomSubjectItem) {
|
||||
|
||||
binding.cardView.setCardBackgroundColor(com.gh.gamecenter.common.R.color.ui_container_1.toColor(binding.root.context))
|
||||
if (item.data == cachedSubject) return
|
||||
|
||||
cachedSubject = item.data
|
||||
@ -77,7 +77,6 @@ class CustomGameGallerySlideViewHolder(
|
||||
val gameList = item.data.data ?: emptyList()
|
||||
(recyclerView.adapter as? GameGallerySlideAdapter)?.submitList(gameList)
|
||||
}
|
||||
binding.cardView.setCardBackgroundColor(com.gh.gamecenter.common.R.color.text_FAFAFA.toColor(binding.root.context))
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -193,9 +193,6 @@ class CustomGameItemViewHolder(
|
||||
adLabelTv: TextView? = null,
|
||||
canShowSubTitle: Boolean
|
||||
) {
|
||||
if (entity.id == gameSubtitleTv.getTag(com.gh.gamecenter.common.R.string.tag_game_name_id)) return
|
||||
gameSubtitleTv.setTag(com.gh.gamecenter.common.R.string.tag_game_name_id, entity.id)
|
||||
|
||||
var showSubtitle = false
|
||||
var showAdvancedDownload = false
|
||||
if (canShowSubTitle && entity.serverLabel == null && entity.subtitle.isNotEmpty() && !entity.advanceDownload) {
|
||||
@ -215,6 +212,9 @@ class CustomGameItemViewHolder(
|
||||
setColor("#${entity.subtitleStyle?.background}".hexStringToIntColor())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(context))
|
||||
background = R.drawable.bg_advance_download_game_subtitle.toDrawable(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -227,6 +227,10 @@ class CustomGameItemViewHolder(
|
||||
background = R.drawable.bg_advance_download_game_subtitle.toDrawable(context)
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.id == gameSubtitleTv.getTag(com.gh.gamecenter.common.R.string.tag_game_name_id)) return
|
||||
gameSubtitleTv.setTag(com.gh.gamecenter.common.R.string.tag_game_name_id, entity.id)
|
||||
|
||||
if (showSubtitle || showAdvancedDownload) {
|
||||
val minWidth =
|
||||
if (showSubtitle) SUBTITLE_MIN_WIDTH.dip2px() else if (showAdvancedDownload) ADVANCED_DOWNLOAD_WIDTH.dip2px() else 0
|
||||
|
||||
@ -109,7 +109,9 @@ class CustomHomeGameItemViewHolder(
|
||||
item.linkColumn?.id ?: ""
|
||||
)
|
||||
}
|
||||
binding.gameBrief.text = game.recommendText
|
||||
binding.gameBrief.goneIf(game.recommendText.isEmpty()) {
|
||||
binding.gameBrief.text = game.recommendText
|
||||
}
|
||||
binding.gameImage.visibleIf(game.showImage) {
|
||||
if (game.isWechatMiniGame()) {
|
||||
ImageUtils.display(binding.gameImage, game.banner)
|
||||
|
||||
@ -53,6 +53,7 @@ class CustomHomeSlideListItemViewHolder(val binding: HomeSlideListItemCustomBind
|
||||
ImageUtils.displayWithCallback(
|
||||
binding.slideBackground,
|
||||
homeSlide.image,
|
||||
false,
|
||||
object : BaseControllerListener<ImageInfo>() {
|
||||
override fun onFinalImageSet(id: String?, imageInfo: ImageInfo?, animatable: Animatable?) {
|
||||
binding.bottomGradient.visibility = View.VISIBLE
|
||||
|
||||
@ -67,6 +67,7 @@ class CustomHomeSubSlideListItemViewHolder(val binding: HomeSubSlideListItemCust
|
||||
ImageUtils.displayWithCallback(
|
||||
binding.slideBackground,
|
||||
homeSlide.image,
|
||||
false,
|
||||
object : BaseControllerListener<ImageInfo>() {
|
||||
override fun onFinalImageSet(id: String?, imageInfo: ImageInfo?, animatable: Animatable?) {
|
||||
if (homeSlide.placeholderColor.isNotEmpty() && homeSlide.linkGame != null) {
|
||||
|
||||
@ -41,6 +41,8 @@ class AutomaticVideoView @JvmOverloads constructor(context: Context, attrs: Attr
|
||||
var thumbImage: SimpleDraweeView = findViewById(R.id.thumbImage)
|
||||
var containerView: RadiusCardView = findViewById(R.id.container)
|
||||
var detailBtn: TextView? = null
|
||||
var isMute = true
|
||||
private var mIsFirstPlay = true
|
||||
private var mMuteDisposable: Disposable? = null
|
||||
private var mMaskDisposable: Disposable? = null
|
||||
private val mUUID = UUID.randomUUID().toString()
|
||||
@ -89,10 +91,11 @@ class AutomaticVideoView @JvmOverloads constructor(context: Context, attrs: Attr
|
||||
mVideoAllCallBack.onClickStartThumb(mOriginUrl, mTitle, this)
|
||||
}
|
||||
prepareVideo()
|
||||
val topVideoVoiceStatus = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
|
||||
if (topVideoVoiceStatus) {
|
||||
violenceUpdateMuteStatus()
|
||||
if (mIsFirstPlay) {
|
||||
isMute = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
|
||||
mIsFirstPlay = false
|
||||
}
|
||||
violenceUpdateMuteStatus()
|
||||
resetDetailMask()
|
||||
}
|
||||
|
||||
@ -106,15 +109,21 @@ class AutomaticVideoView @JvmOverloads constructor(context: Context, attrs: Attr
|
||||
mMuteDisposable?.dispose()
|
||||
mMuteDisposable = null
|
||||
}
|
||||
mute()
|
||||
if (isMute) {
|
||||
mute()
|
||||
} else {
|
||||
unMute()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun mute() {
|
||||
isMute = true
|
||||
CustomManager.getCustomManager(getKey()).isNeedMute = true
|
||||
}
|
||||
|
||||
fun unMute() {
|
||||
isMute = false
|
||||
CustomManager.getCustomManager(getKey()).isNeedMute = false
|
||||
}
|
||||
|
||||
|
||||
@ -29,7 +29,10 @@ class ScrollCalculatorHelper(
|
||||
|
||||
fun enableAndPlayIfValid() {
|
||||
isEnabled = true
|
||||
playIfValid()
|
||||
}
|
||||
|
||||
fun playIfValid() {
|
||||
if (mListRv.isAttachedToWindow
|
||||
&& mListRv.scrollState == RecyclerView.SCROLL_STATE_IDLE) {
|
||||
playVideo(mListRv)
|
||||
|
||||
@ -1,93 +0,0 @@
|
||||
package com.gh.gamecenter.install
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.Service
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
import androidx.core.app.NotificationCompat
|
||||
import com.lightgame.download.ForegroundNotificationManager
|
||||
import com.lightgame.utils.Utils
|
||||
import java.util.*
|
||||
|
||||
class InstallService : Service() {
|
||||
|
||||
private var mForegroundTimer: Timer? = null
|
||||
private var mForegroundNotificationManager: ForegroundNotificationManager? = null
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
mForegroundNotificationManager = ForegroundNotificationManager(this, this.application)
|
||||
Utils.log(InstallService::class.java.simpleName, "onCreate")
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
Utils.log(InstallService::class.java.simpleName, "onStartCommand")
|
||||
val notificationId = 9999
|
||||
if (intent != null && intent.extras != null) {
|
||||
val serviceAction = intent.getStringExtra(KEY_SERVICE_ACTION)
|
||||
if (START_FOREGROUND == serviceAction) {
|
||||
startForegroundIfNeeded(notificationId)
|
||||
} else if (STOP_FOREGROUND == serviceAction) {
|
||||
startForegroundIfNeeded(notificationId)
|
||||
stopForegroundIfNeeded(notificationId)
|
||||
}
|
||||
} else {
|
||||
startForegroundIfNeeded(notificationId)
|
||||
stopForegroundIfNeeded(notificationId)
|
||||
}
|
||||
|
||||
// 不需要 intent 为空的重建
|
||||
return START_NOT_STICKY
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder? {
|
||||
return null
|
||||
}
|
||||
|
||||
private fun startForegroundIfNeeded(notificationId: Int) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val channel =
|
||||
NotificationChannel(SERVICE_CHANNEL_ID, SERVICE_CHANNEL_ID, NotificationManager.IMPORTANCE_LOW)
|
||||
val manager = applicationContext.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
||||
manager.createNotificationChannel(channel)
|
||||
val notification: Notification = NotificationCompat.Builder(this, SERVICE_CHANNEL_ID)
|
||||
.setSmallIcon(com.lightgame.R.drawable.ic_download_notification)
|
||||
.setContentTitle("光环助手安装服务")
|
||||
.build()
|
||||
mForegroundNotificationManager?.notify(notificationId, notification)
|
||||
|
||||
mForegroundTimer?.cancel()
|
||||
mForegroundTimer = Timer()
|
||||
|
||||
val task: TimerTask = object : TimerTask() {
|
||||
override fun run() {
|
||||
stopForegroundIfNeeded(notificationId)
|
||||
}
|
||||
}
|
||||
|
||||
mForegroundTimer?.schedule(task, FOREGROUND_COUNT_DOWN_TIME)
|
||||
}
|
||||
}
|
||||
|
||||
private fun stopForegroundIfNeeded(notificationId: Int) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
mForegroundNotificationManager?.cancel(notificationId)
|
||||
|
||||
mForegroundTimer?.cancel()
|
||||
mForegroundTimer = null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
private const val SERVICE_CHANNEL_ID = "安装服务"
|
||||
private const val FOREGROUND_COUNT_DOWN_TIME = 20 * 1000L
|
||||
|
||||
const val START_FOREGROUND = "start_foreground"
|
||||
const val STOP_FOREGROUND = "stop_foreground"
|
||||
const val KEY_SERVICE_ACTION = "service_action"
|
||||
}
|
||||
}
|
||||
@ -59,7 +59,7 @@ class MiniGameSearchDefaultRankAdapter(
|
||||
_id = rank.id,
|
||||
mName = rank.name,
|
||||
miniGameAppId = rank.link.link ?: "",
|
||||
miniGameType = Constants.WECHAT_MINI_GAME,
|
||||
miniGameCategory = Constants.WECHAT_MINI_GAME,
|
||||
usage = rank.usage ?: 0
|
||||
)
|
||||
holder.binding.playCount.visibility = View.VISIBLE
|
||||
|
||||
@ -21,11 +21,15 @@ class MiniGameSearchResultRepository(
|
||||
return api.getSearchMiniGameList(key, page, 20)
|
||||
}
|
||||
|
||||
override fun getSearchMiniGameCPM(key: String?): Observable<List<GameEntity>> {
|
||||
return Observable.just(emptyList())
|
||||
}
|
||||
|
||||
override fun getSearchSubject(key: String?, page: Int): Observable<List<SearchSubjectEntity>> {
|
||||
return Observable.just(emptyList())
|
||||
}
|
||||
|
||||
override fun getWGameCPMGameList(): Single<MutableList<GameEntity>> {
|
||||
return mWGameSubjectCPMDataSource.getRecommendCPMList(1)
|
||||
return mWGameSubjectCPMDataSource.getUserRecommendCPMList()
|
||||
}
|
||||
}
|
||||
@ -11,7 +11,7 @@ class WGameSubjectCPMListRepository(
|
||||
) : ISubjectListRepository {
|
||||
|
||||
override fun getColumn(column_id: String?, page: Int, sort: String?, order: String?): Single<MutableList<GameEntity>> {
|
||||
return dataSource.getRecommendCPMList(page)
|
||||
return dataSource.getEditorRecommendCPMList(page)
|
||||
}
|
||||
|
||||
override fun getColumnSettings(column_id: String?): Observable<SubjectSettingEntity> {
|
||||
|
||||
@ -14,7 +14,51 @@ class WGameSubjectCPMRemoteDataSource(
|
||||
private val api: WGameCPMApiService = RetrofitManager.getInstance().wGameCPMApi
|
||||
) {
|
||||
|
||||
fun getRecommendCPMList(page: Int, pageSize: Int = 10): Single<MutableList<GameEntity>> {
|
||||
fun getEditorRecommendCPMList(page: Int, pageSize: Int = 10): Single<MutableList<GameEntity>> {
|
||||
val meta = MetaUtil.getMeta()
|
||||
val request = mapOf(
|
||||
"head" to mapOf(
|
||||
"busiAppid" to Config.WGAME_CPM_BUSIAPPID,
|
||||
"oaid" to (meta.oaid ?: ""),
|
||||
"manufacturer" to (meta.manufacturer ?: ""),
|
||||
"mode" to (meta.model ?: ""),
|
||||
"androidId" to (MetaUtil.getAndroidId()),
|
||||
"imei" to (MetaUtil.getIMEI())
|
||||
),
|
||||
"body" to mapOf(
|
||||
"page" to page - 1,
|
||||
"pageSize" to pageSize,
|
||||
)
|
||||
)
|
||||
return api.getEditorRecommendList(request.toRequestBody())
|
||||
.map {
|
||||
if (it.ret == 0) {
|
||||
it.appInfoList.map { info ->
|
||||
GameEntity(
|
||||
mName = info.appName,
|
||||
mIcon = info.logo,
|
||||
mBrief = info.briefIntro,
|
||||
miniGameUid = info.appID,
|
||||
miniGameAppId = info.userName,
|
||||
miniGameCategory = Constants.WECHAT_MINI_GAME,
|
||||
profit = Constants.WECHAT_MINI_GAME_PROFIT_CPM,
|
||||
miniGameAppStatus = 2,
|
||||
miniGameAppPath = info.wechatAppPath,
|
||||
miniGameExtData = info.extData,
|
||||
miniGameRecommendId = info.recommendID,
|
||||
mTagStyle = arrayListOf(
|
||||
TagStyleEntity(name = info.categoryName),
|
||||
TagStyleEntity(name = info.subcategoryName)
|
||||
)
|
||||
)
|
||||
}.toMutableList()
|
||||
} else {
|
||||
mutableListOf()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getUserRecommendCPMList(page: Int = 1, pageSize: Int = 10): Single<MutableList<GameEntity>> {
|
||||
val meta = MetaUtil.getMeta()
|
||||
val request = mapOf(
|
||||
"head" to mapOf(
|
||||
@ -40,7 +84,8 @@ class WGameSubjectCPMRemoteDataSource(
|
||||
mBrief = info.briefIntro,
|
||||
miniGameUid = info.appID,
|
||||
miniGameAppId = info.userName,
|
||||
miniGameType = Constants.WECHAT_MINI_GAME_CPM,
|
||||
miniGameCategory = Constants.WECHAT_MINI_GAME,
|
||||
profit = Constants.WECHAT_MINI_GAME_PROFIT_CPM,
|
||||
miniGameAppStatus = 2,
|
||||
miniGameAppPath = info.wechatAppPath,
|
||||
miniGameExtData = info.extData,
|
||||
|
||||
@ -35,17 +35,21 @@ class PackageFilterManager {
|
||||
|
||||
if (appendOnly) {
|
||||
// 添加因为异常而没能正常更新的包名列表
|
||||
finalPackageList.addAll(PackageRepository.mPendingPackageNameSet)
|
||||
synchronized(PackageRepository.mPendingPackageNameSet) {
|
||||
finalPackageList.addAll(PackageRepository.mPendingPackageNameSet)
|
||||
}
|
||||
}
|
||||
|
||||
RetrofitManager.getInstance()
|
||||
.newApi
|
||||
.postInstalledAppList(packageList.toRequestBody())
|
||||
.postInstalledAppList(finalPackageList.toRequestBody())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(object : BiResponse<PackageFilter>() {
|
||||
override fun onSuccess(data: PackageFilter) {
|
||||
mPackageKey = data.key
|
||||
PackageRepository.mPendingPackageNameSet.clear()
|
||||
synchronized(PackageRepository.mPendingPackageNameSet) {
|
||||
PackageRepository.mPendingPackageNameSet.removeAll(finalPackageList)
|
||||
}
|
||||
|
||||
val partialPackageList = arrayListOf<String>()
|
||||
|
||||
@ -78,7 +82,9 @@ class PackageFilterManager {
|
||||
super.onFailure(exception)
|
||||
|
||||
if (appendOnly) {
|
||||
PackageRepository.mPendingPackageNameSet.addAll(packageList)
|
||||
synchronized(PackageRepository.mPendingPackageNameSet) {
|
||||
PackageRepository.mPendingPackageNameSet.addAll(finalPackageList)
|
||||
}
|
||||
} else {
|
||||
if (exception is retrofit2.HttpException && exception.code() == 403) {
|
||||
// 403 代表 key 过期,需要重新获取
|
||||
|
||||
@ -85,7 +85,7 @@ object PackageRepository {
|
||||
_recentVaPlayedChanged.postValue(Unit)
|
||||
}
|
||||
val packageFilterManager = PackageFilterManager()
|
||||
var mPendingPackageNameSet = hashSetOf<String>() // 因遇到异常而等待下次操作更新的包名列表
|
||||
var mPendingPackageNameSet = Collections.synchronizedSet<String>(hashSetOf<String>()) // 因遇到异常而等待下次操作更新的包名列表
|
||||
var mValidPackageNameSet = hashSetOf<String>() // 已被收录的游戏包名列表
|
||||
|
||||
|
||||
|
||||
@ -701,7 +701,7 @@ class HaloPersonalFragment : BaseLazyFragment() {
|
||||
}
|
||||
|
||||
private fun inflateRealView() {
|
||||
mBinding.stub.inflate()
|
||||
mBinding.stub.inflateOrShow()
|
||||
|
||||
mStubBinding.statusBar.goneIf(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
|
||||
mStubBinding.darkModeIv.goneIf(!(Config.getNightModeSetting()?.icon ?: false))
|
||||
|
||||
@ -3,6 +3,7 @@ package com.gh.gamecenter.provider
|
||||
import android.content.*
|
||||
import android.database.Cursor
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.database.sqlite.SQLiteException
|
||||
import android.database.sqlite.SQLiteFullException
|
||||
import android.database.sqlite.SQLiteOpenHelper
|
||||
import android.net.Uri
|
||||
@ -12,6 +13,7 @@ import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.core.utils.GsonUtils
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.login.entity.UserInfoEntity
|
||||
import com.gh.gamecenter.login.user.UserRepository
|
||||
import com.halo.assistant.HaloApp
|
||||
@ -77,7 +79,12 @@ class GhContentProvider : ContentProvider() {
|
||||
}
|
||||
|
||||
override fun onCreate(): Boolean {
|
||||
initProviderSqliteHelper(context);
|
||||
try {
|
||||
val context = context ?: return false
|
||||
initProviderSqliteHelper(context)
|
||||
} catch (e: SQLiteException) {
|
||||
ToastUtils.toast("数据库内存已满,无法同步")
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@ -19,7 +19,6 @@ import com.gh.gamecenter.core.utils.SPUtils;
|
||||
import com.gh.gamecenter.entity.NewApiSettingsEntity;
|
||||
import com.gh.gamecenter.eventbus.EBPackage;
|
||||
import com.gh.gamecenter.feature.entity.GameInstall;
|
||||
import com.gh.gamecenter.install.InstallService;
|
||||
import com.gh.gamecenter.manager.PackagesManager;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
@ -27,8 +26,6 @@ import com.lightgame.utils.Utils;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* 监听安装包变更
|
||||
*/
|
||||
@ -49,14 +46,6 @@ public class PackageChangeBroadcastReceiver extends BroadcastReceiver {
|
||||
PackageHelper.INSTANCE.dumpInstalledListCache();
|
||||
ExtensionsKt.doOnMainProcessOnly(() -> {
|
||||
Utils.log(TAG, "onReceive->" + intent.getAction() + "==" + intent.getDataString());
|
||||
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU
|
||||
&& Build.MANUFACTURER.toLowerCase(Locale.CHINA).contains("xiaomi")) {
|
||||
Intent foregroundServiceIntent = new Intent(context, InstallService.class);
|
||||
foregroundServiceIntent.putExtra(InstallService.KEY_SERVICE_ACTION, InstallService.STOP_FOREGROUND);
|
||||
context.startForegroundService(foregroundServiceIntent);
|
||||
}
|
||||
|
||||
// 接收安装广播
|
||||
if (intent.getAction().equals(mActions.getAdd())) {
|
||||
String packageName = intent.getDataString();
|
||||
|
||||
@ -318,6 +318,12 @@ public interface ApiService {
|
||||
@GET
|
||||
Observable<List<GameEntity>> getSearchGame(@Url String url);
|
||||
|
||||
/**
|
||||
* 搜索CPM微信小游戏
|
||||
*/
|
||||
@GET("mini_game/search/configs")
|
||||
Observable<List<GameEntity>> getSearchWechatMiniCPMGame(@Query("keyword") String key);
|
||||
|
||||
/**
|
||||
* 游戏搜索的专题数据
|
||||
*/
|
||||
|
||||
@ -8,6 +8,8 @@ import io.reactivex.Single
|
||||
interface ISearchGameResultRepository {
|
||||
fun getSearchGame(key: String?, page: Int): Observable<List<GameEntity>>
|
||||
|
||||
fun getSearchMiniGameCPM(key: String?): Observable<List<GameEntity>>
|
||||
|
||||
fun getSearchSubject(key: String?, page: Int): Observable<List<SearchSubjectEntity>>
|
||||
|
||||
fun getWGameCPMGameList(): Single<MutableList<GameEntity>>
|
||||
|
||||
@ -86,7 +86,7 @@ class SearchSubjectItemViewHolder(var binding: SearchSubjectItemBinding) : Recyc
|
||||
|
||||
binding.run {
|
||||
subjectRv.layoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
|
||||
subjectRv.adapter = SearchSubjectAdapter(context, entity.getFilterGame(), "($type-专题)", key) {
|
||||
subjectRv.adapter = SearchSubjectAdapter(context, entity.getFilterGame(), entity.columnId, entity.name, "($type-专题)", key) {
|
||||
dao?.add(key)
|
||||
if (itemData.adConfig != null) {
|
||||
NewFlatLogUtils.logClickGameAd(
|
||||
|
||||
@ -107,6 +107,7 @@ class SearchGameResultAdapter(
|
||||
return when {
|
||||
oldItem?.subject != null && newItem?.subject != null -> {
|
||||
oldItem.subject.columnId == newItem.subject.columnId
|
||||
&& oldItem.subject.games == newItem.subject.games
|
||||
}
|
||||
|
||||
oldItem?.game != null && newItem?.game != null -> {
|
||||
@ -121,6 +122,7 @@ class SearchGameResultAdapter(
|
||||
return when {
|
||||
oldItem?.subject != null && newItem?.subject != null -> {
|
||||
oldItem.subject.columnId == newItem.subject.columnId
|
||||
&& oldItem.subject.games == newItem.subject.games
|
||||
}
|
||||
|
||||
oldItem?.game != null && newItem?.game != null -> {
|
||||
@ -169,39 +171,50 @@ class SearchGameResultAdapter(
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
when (holder) {
|
||||
is SearchSubjectItemViewHolder -> {
|
||||
holder.binding.run {
|
||||
when {
|
||||
position == 0 -> topDivider.visibility = View.GONE
|
||||
position > 0 -> {
|
||||
val gameEntity = mEntityList[position - 1].game
|
||||
if (gameEntity != null) {
|
||||
val isShowTag = gameEntity.contentTag != null
|
||||
&& (gameEntity.contentTag!!.custom.isNotEmpty()
|
||||
|| gameEntity.contentTag!!.zone.link.isNotEmpty()
|
||||
|| gameEntity.contentTag!!.isLibaoExists
|
||||
|| gameEntity.contentTag!!.server)
|
||||
val isShowTagByMirror =
|
||||
if (gameEntity.shouldUseMirrorInfo()) isShowTag && gameEntity.obtainMirrorData()?.contentTagStatus == "on" else isShowTag
|
||||
if (isShowTagByMirror) {
|
||||
topDivider.visibility = View.GONE
|
||||
val itemData = mEntityList[position]
|
||||
if (itemData.subject == null || itemData.subject.games.isEmpty()) {
|
||||
holder.binding.topDivider.visibility = View.GONE
|
||||
holder.binding.bottomDivider.visibility = View.GONE
|
||||
holder.binding.headContainer.root.visibility = View.GONE
|
||||
holder.binding.subjectRv.visibility = View.GONE
|
||||
} else {
|
||||
holder.binding.headContainer.root.visibility = View.VISIBLE
|
||||
holder.binding.subjectRv.visibility = View.VISIBLE
|
||||
|
||||
holder.binding.run {
|
||||
when {
|
||||
position == 0 -> topDivider.visibility = View.GONE
|
||||
position > 0 -> {
|
||||
val gameEntity = mEntityList[position - 1].game
|
||||
if (gameEntity != null) {
|
||||
val isShowTag = gameEntity.contentTag != null
|
||||
&& (gameEntity.contentTag!!.custom.isNotEmpty()
|
||||
|| gameEntity.contentTag!!.zone.link.isNotEmpty()
|
||||
|| gameEntity.contentTag!!.isLibaoExists
|
||||
|| gameEntity.contentTag!!.server)
|
||||
val isShowTagByMirror =
|
||||
if (gameEntity.shouldUseMirrorInfo()) isShowTag && gameEntity.obtainMirrorData()?.contentTagStatus == "on" else isShowTag
|
||||
if (isShowTagByMirror) {
|
||||
topDivider.visibility = View.GONE
|
||||
} else {
|
||||
topDivider.visibility = View.VISIBLE
|
||||
}
|
||||
} else {
|
||||
topDivider.visibility = View.VISIBLE
|
||||
topDivider.visibility = View.GONE
|
||||
}
|
||||
} else {
|
||||
topDivider.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
bottomDivider.visibility = View.VISIBLE
|
||||
}
|
||||
bottomDivider.visibility = View.VISIBLE
|
||||
holder.bindSubjectItem(
|
||||
mContext,
|
||||
itemData,
|
||||
SearchType.fromString(type).toChinese(),
|
||||
key,
|
||||
dao,
|
||||
sourceEntrance = sourceEntrance
|
||||
)
|
||||
}
|
||||
holder.bindSubjectItem(
|
||||
mContext,
|
||||
mEntityList[position],
|
||||
SearchType.fromString(type).toChinese(),
|
||||
key,
|
||||
dao,
|
||||
sourceEntrance = sourceEntrance
|
||||
)
|
||||
}
|
||||
|
||||
is SearchGameFirstItemViewHolder -> {
|
||||
|
||||
@ -373,12 +373,15 @@ open class SearchGameResultFragment : ListFragment<GameEntity, SearchGameResultV
|
||||
}
|
||||
|
||||
fun setParams(key: String, type: String) {
|
||||
this.mKey = key
|
||||
this.mType = type
|
||||
mAdapter?.key = key
|
||||
mAdapter?.type = type
|
||||
mAdapter?.clearAdIdSet()
|
||||
mListViewModel?.updateSearchKeyWithType(key, type)
|
||||
|
||||
if (this.mKey == key) return
|
||||
|
||||
this.mKey = key
|
||||
mAdapter?.key = key
|
||||
mAdapter?.clearAdIdSet()
|
||||
mListViewModel?.clearSearchSubjects()
|
||||
mListViewModel?.load(LoadType.REFRESH)
|
||||
}
|
||||
|
||||
@ -10,13 +10,20 @@ import com.gh.gamecenter.retrofit.service.ApiService
|
||||
import com.halo.assistant.HaloApp
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import java.net.URLEncoder
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class SearchGameResultRepository(
|
||||
private val mApi: ApiService = RetrofitManager.getInstance().api,
|
||||
private val mNewApi: ApiService = RetrofitManager.getInstance().newApi,
|
||||
private val mWGameSubjectCPMDataSource: WGameSubjectCPMRemoteDataSource = WGameSubjectCPMRemoteDataSource()
|
||||
) : ISearchGameResultRepository {
|
||||
|
||||
private var currentSearchKey: String? = null
|
||||
|
||||
private var currentMiniGameCPMSearchList: MutableList<GameEntity>? = null
|
||||
|
||||
override fun getSearchGame(
|
||||
key: String?,
|
||||
page: Int
|
||||
@ -31,11 +38,26 @@ class SearchGameResultRepository(
|
||||
)
|
||||
}
|
||||
|
||||
override fun getSearchMiniGameCPM(key: String?): Observable<List<GameEntity>> {
|
||||
val currentMiniGameCPMSearchList = currentMiniGameCPMSearchList
|
||||
if (key == currentSearchKey && currentMiniGameCPMSearchList != null) {
|
||||
return Observable.just(currentMiniGameCPMSearchList)
|
||||
}
|
||||
return mNewApi.getSearchWechatMiniCPMGame(key)
|
||||
.timeout(5, TimeUnit.SECONDS)
|
||||
.onErrorReturnItem(emptyList())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doOnNext {
|
||||
this.currentSearchKey = key
|
||||
this.currentMiniGameCPMSearchList = it
|
||||
}
|
||||
}
|
||||
|
||||
override fun getSearchSubject(key: String?, page: Int): Observable<List<SearchSubjectEntity>> {
|
||||
return mApi.getSearchSubject(key, page)
|
||||
}
|
||||
|
||||
override fun getWGameCPMGameList(): Single<MutableList<GameEntity>> {
|
||||
return mWGameSubjectCPMDataSource.getRecommendCPMList(1)
|
||||
return mWGameSubjectCPMDataSource.getUserRecommendCPMList()
|
||||
}
|
||||
}
|
||||
@ -67,49 +67,60 @@ class SearchGameResultViewModel(
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private fun decorateListAndPost(list: MutableList<GameEntity>) {
|
||||
val itemDataList = ArrayList(
|
||||
list.mapIndexed { index, game ->
|
||||
SearchItemData(game = game, gamePosition = index, isFirst = index == 0)
|
||||
}
|
||||
)
|
||||
val itemDataList = ArrayList<SearchItemData>()
|
||||
val combineGameList = list.toMutableList()
|
||||
|
||||
refreshWrongInstallStatus()
|
||||
|
||||
repository.getSearchSubject(mSearchKey, mPage)
|
||||
.map { dataList ->
|
||||
mSearchSubjects.addAll(dataList)
|
||||
var cpmSearchSubject: SearchSubjectEntity? = null
|
||||
mSearchSubjects.forEach {
|
||||
// 微信小游戏CPM专题需要等搜索广告位插入完成后再插入
|
||||
if (it.location == WGAME_CPM_SUBJECT_POSITION) {
|
||||
cpmSearchSubject = it.apply { isWGameSubjectCPM = true }
|
||||
repository.getSearchMiniGameCPM(mSearchKey)
|
||||
.zipWith(repository.getSearchSubject(mSearchKey, mPage)) { cpmGameList, subjectList -> // CPM游戏搜索结果列表合并
|
||||
for (cpmGame in cpmGameList) {
|
||||
if (cpmGame.location <= 0 || cpmGame.location > list.size) {
|
||||
combineGameList.add(cpmGame)
|
||||
} else {
|
||||
val item = SearchItemData(subject = it)
|
||||
if (it.location <= 0 || it.location > itemDataList.size) {
|
||||
itemDataList.add(item)
|
||||
} else {
|
||||
itemDataList.add(it.location - 1, item)
|
||||
}
|
||||
combineGameList.add(cpmGame.location - 1, cpmGame)
|
||||
}
|
||||
}
|
||||
cpmSearchSubject to dataList
|
||||
itemDataList.addAll(
|
||||
combineGameList.mapIndexed { index, game ->
|
||||
SearchItemData(game = game, gamePosition = index, isFirst = index == 0)
|
||||
}
|
||||
)
|
||||
subjectList
|
||||
}
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({ result ->
|
||||
.subscribe({ mutableList ->
|
||||
val cpmSearchSubjects = mutableListOf<SearchSubjectEntity>()
|
||||
mSearchSubjects.addAll(mutableList)
|
||||
mSearchSubjects.forEach {
|
||||
if (it.type == SearchSubjectEntity.TYPE_WECHAT_GAME_CPM_COLUMN) {
|
||||
cpmSearchSubjects.add(it.apply { isWGameSubjectCPM = true })
|
||||
}
|
||||
val item = SearchItemData(subject = it)
|
||||
if (it.location <= 0 || it.location > itemDataList.size) {
|
||||
itemDataList.add(item)
|
||||
} else {
|
||||
itemDataList.add(it.location - 1, item)
|
||||
}
|
||||
}
|
||||
// 处理初始化列表且游戏列表size为0的情况
|
||||
handleLoadStatusWhenGameListIsEmpty(list, itemDataList)
|
||||
|
||||
if (mIsManuallySearch) {
|
||||
if (mSearchKey == AdDelegateHelper.gameSearchKeyword) {
|
||||
updateAdConfigAndDecorateList(itemDataList, list, result.first)
|
||||
updateAdConfigAndDecorateList(itemDataList, list)
|
||||
} else {
|
||||
AdDelegateHelper.requestAdConfig(false, mSearchKey ?: "") {
|
||||
updateAdConfigAndDecorateList(itemDataList, list, result.first)
|
||||
updateAdConfigAndDecorateList(itemDataList, list)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
decorateWithWGameSubjectCPM(itemDataList, list, result.first)
|
||||
postResultList(itemDataList, list)
|
||||
}
|
||||
|
||||
if (cpmSearchSubjects.isNotEmpty()) {
|
||||
decorateListWithWGameCPM(cpmSearchSubjects, itemDataList, list)
|
||||
}
|
||||
}, {
|
||||
it.printStackTrace()
|
||||
@ -118,12 +129,50 @@ class SearchGameResultViewModel(
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求微信小游戏CPM接口获取专题游戏数据,并插入对应的专题项中,相关需求如下:
|
||||
* @see <a href="https://jira.shanqu.cc/browse/GHZSCY-6710">【光环助手】CPM微信小游戏API接入工作</a>
|
||||
* @see <a href="https://jira.shanqu.cc/browse/GHZSCY-6827">【光环助手】CPM微信小游戏一期优化</a>
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
private fun updateAdConfigAndDecorateList(
|
||||
private fun decorateListWithWGameCPM(
|
||||
subjects: List<SearchSubjectEntity>,
|
||||
itemDataList: ArrayList<SearchItemData>,
|
||||
list: MutableList<GameEntity>,
|
||||
cpmSubjectEntity: SearchSubjectEntity?
|
||||
list: MutableList<GameEntity>
|
||||
) {
|
||||
val subjectList = subjects.filterNot {
|
||||
it.games.isNotEmpty()
|
||||
}
|
||||
if (subjectList.isEmpty()) return
|
||||
val subjectSingleList = subjectList.map { subject ->
|
||||
repository.getWGameCPMGameList()
|
||||
.onErrorReturnItem(mutableListOf())
|
||||
.map { subject.columnId to it }
|
||||
}
|
||||
Single.zip(subjectSingleList) { it.map { item -> item as Pair<String, MutableList<GameEntity>> } }
|
||||
.map { dataList ->
|
||||
for (index in itemDataList.indices) {
|
||||
val itemData = itemDataList[index]
|
||||
val subject = itemData.subject ?: continue
|
||||
if (subject.games.isNotEmpty()) continue
|
||||
val pair = dataList.firstOrNull { data ->
|
||||
data.first == subject.columnId
|
||||
} ?: continue
|
||||
val newItemData = SearchItemData(
|
||||
subject = subject.copy(games = pair.second)
|
||||
)
|
||||
itemDataList[index] = newItemData
|
||||
}
|
||||
itemDataList
|
||||
}
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({ dataList -> postResultList(dataList, list) }, {})
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private fun updateAdConfigAndDecorateList(itemDataList: ArrayList<SearchItemData>, list: MutableList<GameEntity>) {
|
||||
mGameSearchAdList =
|
||||
AdDelegateHelper.getGameSearchAdList().filter { AdDelegateHelper.shouldShowGameSearchAd(it) }.toArrayList()
|
||||
.apply { sortBy { it.position } }
|
||||
@ -137,7 +186,6 @@ class SearchGameResultViewModel(
|
||||
mAdPositionSet = adPositionSet
|
||||
|
||||
if (adPositionSet.isNotEmpty()) {
|
||||
val decoratedItemDataList = ArrayList(itemDataList)
|
||||
val ownerAdList = arrayListOf<AdConfig>()
|
||||
val thirdPartyAdList = arrayListOf<AdConfig>()
|
||||
|
||||
@ -175,18 +223,18 @@ class SearchGameResultViewModel(
|
||||
Single.zip(requestSingleList) {}
|
||||
.compose(singleToMain())
|
||||
.subscribe({
|
||||
decorateListWithAd(itemDataList, decoratedItemDataList, list, cpmSubjectEntity)
|
||||
decorateListWithAd(itemDataList, list)
|
||||
}, {
|
||||
decorateListWithAd(itemDataList, decoratedItemDataList, list, cpmSubjectEntity)
|
||||
decorateListWithAd(itemDataList, list)
|
||||
})
|
||||
} else {
|
||||
decorateListWithAd(itemDataList, decoratedItemDataList, list, cpmSubjectEntity)
|
||||
decorateListWithAd(itemDataList, list)
|
||||
}
|
||||
} else {
|
||||
decorateListWithThirdPartyAdOnly(decoratedItemDataList, thirdPartyAdList, list, cpmSubjectEntity)
|
||||
decorateListWithThirdPartyAdOnly(itemDataList, thirdPartyAdList, list)
|
||||
}
|
||||
} else {
|
||||
decorateWithWGameSubjectCPM(itemDataList, list, cpmSubjectEntity)
|
||||
postResultList(itemDataList, list)
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,27 +245,25 @@ class SearchGameResultViewModel(
|
||||
}
|
||||
|
||||
private fun decorateListWithThirdPartyAdOnly(
|
||||
decoratedItemDataList: ArrayList<SearchItemData>,
|
||||
itemDataList: ArrayList<SearchItemData>,
|
||||
thirdPartyAdList: List<AdConfig>,
|
||||
list: List<GameEntity>,
|
||||
cpmSubjectEntity: SearchSubjectEntity?
|
||||
list: List<GameEntity>
|
||||
) {
|
||||
thirdPartyAdList.forEach {
|
||||
decoratedItemDataList.add(it.position - 1, SearchItemData(ad = it.thirdPartyAd, adConfig = it))
|
||||
itemDataList.add(it.position - 1, SearchItemData(ad = it.thirdPartyAd, adConfig = it))
|
||||
SPUtils.setLong(Constants.SP_LAST_GAME_SEARCH_AD_SHOW_TIME + it.position, System.currentTimeMillis())
|
||||
}
|
||||
decorateWithWGameSubjectCPM(decoratedItemDataList, list, cpmSubjectEntity)
|
||||
postResultList(itemDataList, list)
|
||||
}
|
||||
|
||||
private fun decorateListWithAd(
|
||||
itemDataList: ArrayList<SearchItemData>,
|
||||
decoratedItemDataList: ArrayList<SearchItemData>,
|
||||
list: List<GameEntity>,
|
||||
cpmSubjectEntity: SearchSubjectEntity?
|
||||
list: List<GameEntity>
|
||||
) {
|
||||
val adGameOneIdSet = HashSet<String>() // 展示样式为单个游戏时记录游戏ID,避免重复
|
||||
val decoratedItemDataSize = itemDataList.size
|
||||
for ((index, position) in mAdPositionSet!!.withIndex()) {
|
||||
if (position < itemDataList.size + index + 1) {
|
||||
if (position < decoratedItemDataSize + index + 1) {
|
||||
val adConfig = mGameSearchAdList!!.safelyGetInRelease(index)
|
||||
val showThirdPartyAd = adConfig?.displayRule?.adSource == AdDelegateHelper.AD_TYPE_SDK
|
||||
val showOwnerAd = adConfig?.displayRule?.adSource == AdDelegateHelper.AD_TYPE_OWNER
|
||||
@ -225,7 +271,7 @@ class SearchGameResultViewModel(
|
||||
if ((showThirdPartyAd && adConfig?.thirdPartyAd != null)
|
||||
|| (showOwnerAd && adConfig?.ownerAd == null && adConfig?.thirdPartyAd != null && showOnFailed)
|
||||
) {
|
||||
decoratedItemDataList.add(position - 1, SearchItemData(ad = adConfig.thirdPartyAd, adConfig = adConfig))
|
||||
itemDataList.add(position - 1, SearchItemData(ad = adConfig.thirdPartyAd, adConfig = adConfig))
|
||||
SPUtils.setLong(
|
||||
Constants.SP_LAST_GAME_SEARCH_AD_SHOW_TIME + adConfig.position,
|
||||
System.currentTimeMillis()
|
||||
@ -237,7 +283,7 @@ class SearchGameResultViewModel(
|
||||
if (!gameList.isNullOrEmpty()) {
|
||||
if (adConfig.ownerAd.adSource?.displayStyle == "game_zone") {
|
||||
// 游戏专题
|
||||
decoratedItemDataList.add(
|
||||
itemDataList.add(
|
||||
position - 1,
|
||||
SearchItemData(
|
||||
subject = SearchSubjectEntity(
|
||||
@ -259,7 +305,7 @@ class SearchGameResultViewModel(
|
||||
}
|
||||
randomGameEntity?.id?.let { adGameOneIdSet.add(it) }
|
||||
|
||||
decoratedItemDataList.add(
|
||||
itemDataList.add(
|
||||
position - 1,
|
||||
SearchItemData(game = randomGameEntity, adConfig = adConfig)
|
||||
)
|
||||
@ -270,7 +316,7 @@ class SearchGameResultViewModel(
|
||||
)
|
||||
} else if (showOnFailed && adConfig.thirdPartyAd != null) {
|
||||
// 自有广告为空时,显示第三方广告
|
||||
decoratedItemDataList.add(position - 1, SearchItemData(ad = adConfig.thirdPartyAd, adConfig = adConfig))
|
||||
itemDataList.add(position - 1, SearchItemData(ad = adConfig.thirdPartyAd, adConfig = adConfig))
|
||||
SPUtils.setLong(
|
||||
Constants.SP_LAST_GAME_SEARCH_AD_SHOW_TIME + adConfig.position,
|
||||
System.currentTimeMillis()
|
||||
@ -281,41 +327,7 @@ class SearchGameResultViewModel(
|
||||
break
|
||||
}
|
||||
}
|
||||
decorateWithWGameSubjectCPM(decoratedItemDataList, list, cpmSubjectEntity)
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private fun decorateWithWGameSubjectCPM(
|
||||
resultList: ArrayList<SearchItemData>,
|
||||
list: List<GameEntity>,
|
||||
cpmSubjectEntity: SearchSubjectEntity?
|
||||
) {
|
||||
// 微信小游戏CPM专题搜索结果存在,则请求CPM接口获取微信小游戏列表数据,并将列表数据插入缓存的CPM专题中,
|
||||
// 再根据location的值(固定为4)将CPM专题插入搜索结果列表中
|
||||
// 相关需求:https://jira.shanqu.cc/browse/GHZSCY-6710
|
||||
cpmSubjectEntity?.let { subject ->
|
||||
if (subject.games.isNotEmpty()) {
|
||||
Single.just(subject.games.toMutableList())
|
||||
} else {
|
||||
repository.getWGameCPMGameList()
|
||||
.onErrorReturnItem(mutableListOf())
|
||||
}
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
val cpmSearchItemData = SearchItemData(subject = subject.apply { games = it })
|
||||
if (subject.location <= 0 || subject.location > resultList.size) {
|
||||
resultList.add(cpmSearchItemData)
|
||||
} else {
|
||||
resultList.add(subject.location - 1, cpmSearchItemData)
|
||||
}
|
||||
postResultList(resultList, list)
|
||||
},
|
||||
{
|
||||
postResultList(resultList, list)
|
||||
})
|
||||
} ?: postResultList(resultList, list)
|
||||
postResultList(itemDataList, list)
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
@ -343,7 +355,7 @@ class SearchGameResultViewModel(
|
||||
}
|
||||
|
||||
private fun postResultList(resultList: ArrayList<SearchItemData>, list: List<GameEntity>) {
|
||||
mResultLiveData.postValue(resultList)
|
||||
mResultLiveData.postValue(resultList.toMutableList())
|
||||
if (mPage == 1) {
|
||||
if (repository is MiniGameSearchResultRepository) {
|
||||
SensorsBridge.trackMiniGameSearchResultReturn(
|
||||
@ -362,7 +374,6 @@ class SearchGameResultViewModel(
|
||||
mSearchKey ?: "",
|
||||
SearchActivity.toTrackSearchType(mSearchType),
|
||||
list.isNotEmpty()
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
@ -431,7 +442,6 @@ class SearchGameResultViewModel(
|
||||
|
||||
companion object {
|
||||
const val AD_SUBJECT_GAME_MAX_COUNT = 8
|
||||
const val WGAME_CPM_SUBJECT_POSITION = 4
|
||||
}
|
||||
|
||||
}
|
||||
@ -13,6 +13,8 @@ import com.lightgame.adapter.BaseRecyclerAdapter
|
||||
class SearchSubjectAdapter(
|
||||
context: Context,
|
||||
private val mList: List<GameEntity>,
|
||||
private val mColumnId: String,
|
||||
private val mColumnName: String,
|
||||
private val mEntrance: String,
|
||||
private val mKey: String,
|
||||
private val clickCallback: ((GameEntity) -> Unit)
|
||||
@ -40,7 +42,10 @@ class SearchSubjectAdapter(
|
||||
MiniGameItemHelper.launchMiniGame(gameEntity)
|
||||
MiniGameItemHelper.trackMiniGameClick(
|
||||
gameEntity = gameEntity,
|
||||
gameColumnId = mColumnId,
|
||||
gameColumnName = mColumnName,
|
||||
location = "小游戏搜索结果列表",
|
||||
position = position,
|
||||
searchContent = mKey,
|
||||
)
|
||||
} else {
|
||||
|
||||
@ -9,6 +9,7 @@ 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.goneIf
|
||||
import com.gh.gamecenter.common.utils.toColor
|
||||
import com.gh.gamecenter.databinding.FragmentSearchTabBinding
|
||||
import com.gh.gamecenter.feature.entity.SettingsEntity
|
||||
import com.gh.gamecenter.search.SearchGameResultFragment
|
||||
@ -43,7 +44,7 @@ class SearchTabFragment : BaseFragment<Any>() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
|
||||
location = arguments?.getString(EntranceConsts.KEY_LOCATION) ?: ""
|
||||
with(activityViewModel) {
|
||||
searchKeyAndType.observe(this@SearchTabFragment) { (key, type) ->
|
||||
@ -121,6 +122,17 @@ class SearchTabFragment : BaseFragment<Any>() {
|
||||
|
||||
}
|
||||
|
||||
override fun onDarkModeChanged() {
|
||||
super.onDarkModeChanged()
|
||||
if (::binding.isInitialized) {
|
||||
binding.tabLayout.setTabTextColors(
|
||||
com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext()),
|
||||
com.gh.gamecenter.common.R.color.text_theme.toColor(requireContext())
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance(location: String) =
|
||||
|
||||
@ -9,6 +9,7 @@ import com.gh.gamecenter.common.baselist.LoadStatus
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.common.retrofit.BiResponse
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge
|
||||
import com.gh.gamecenter.common.utils.clearHtmlFormatCompletely
|
||||
import com.gh.gamecenter.common.utils.singleToMain
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageData
|
||||
import com.gh.gamecenter.livedata.Event
|
||||
@ -141,7 +142,7 @@ class SearchGameListViewModel : ViewModel() {
|
||||
SearchActivity.toTrackSearchType(type),
|
||||
location,
|
||||
collection.id,
|
||||
collection.title
|
||||
collection.title.clearHtmlFormatCompletely()
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
package com.gh.gamecenter.simulatorgame
|
||||
|
||||
import android.app.Application
|
||||
import android.database.sqlite.SQLiteException
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.gh.common.simulator.SimulatorGameManager
|
||||
@ -46,8 +47,12 @@ class SimulatorGameListViewModel(application: Application, var type: String) :
|
||||
simulatorGameRecordList.add(gameEntity.convertSimulatorGameRecordEntity())
|
||||
}
|
||||
}
|
||||
mSimulatorGameDao.addSimulatorGameList(simulatorGameRecordList)
|
||||
mResultLiveData.postValue(newList)
|
||||
try {
|
||||
mSimulatorGameDao.addSimulatorGameList(simulatorGameRecordList)
|
||||
mResultLiveData.postValue(newList)
|
||||
} catch (e: SQLiteException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -102,6 +102,7 @@ abstract class BaseTabWrapperFragment : BaseLazyFragment(), IMultiTab {
|
||||
noDataStub = mCachedView.findViewById(R.id.reuse_no_data_stub)
|
||||
noConnectionStub = mCachedView.findViewById(R.id.reuse_no_connection_stub)
|
||||
loadingStub = mCachedView.findViewById(R.id.reuse_loading_stub)
|
||||
showLoading(true)
|
||||
|
||||
backgroundColor = com.gh.gamecenter.common.R.color.ui_background.toColor(requireContext())
|
||||
backgroundWhiteColor = com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext())
|
||||
@ -159,7 +160,7 @@ abstract class BaseTabWrapperFragment : BaseLazyFragment(), IMultiTab {
|
||||
showLoading(true)
|
||||
}
|
||||
}
|
||||
noConnectionStub?.inflate()
|
||||
noConnectionStub?.inflateOrShow()
|
||||
} else {
|
||||
noConnectionBinding?.root?.visibility = View.VISIBLE
|
||||
}
|
||||
@ -175,7 +176,7 @@ abstract class BaseTabWrapperFragment : BaseLazyFragment(), IMultiTab {
|
||||
noDataBinding = ReuseNoneDataBinding.bind(inflated)
|
||||
noDataBinding?.root?.visibility = View.VISIBLE
|
||||
}
|
||||
noDataStub?.inflate()
|
||||
noDataStub?.inflateOrShow()
|
||||
} else {
|
||||
noDataBinding?.root?.visibility = View.VISIBLE
|
||||
}
|
||||
@ -191,7 +192,7 @@ abstract class BaseTabWrapperFragment : BaseLazyFragment(), IMultiTab {
|
||||
loadingBinding = ReuseLoadingBinding.bind(inflated)
|
||||
loadingBinding?.root?.visibility = View.VISIBLE
|
||||
}
|
||||
loadingStub?.inflate()
|
||||
loadingStub?.inflateOrShow()
|
||||
} else {
|
||||
loadingBinding?.root?.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
@ -65,7 +65,6 @@ class MainWrapperFragment : BaseBottomTabFragment<PieceBottomTabBinding>(), OnBa
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
mViewModel = viewModelProviderFromParent(MainWrapperViewModel.Factory(HaloApp.getInstance()))
|
||||
super.onCreate(savedInstanceState)
|
||||
DisplayUtils.transparentStatusBar(requireActivity())
|
||||
|
||||
initSkeleton()
|
||||
|
||||
|
||||
@ -43,6 +43,8 @@ import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.gh.gamecenter.common.eventbus.EBReuse
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.common.json.json
|
||||
import com.gh.gamecenter.common.observer.MuteCallback
|
||||
import com.gh.gamecenter.common.observer.VolumeObserver
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.common.view.TabIndicatorView
|
||||
import com.gh.gamecenter.core.iinterface.IScrollable
|
||||
@ -61,6 +63,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.AutomaticVideoView
|
||||
@ -162,6 +165,20 @@ class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbar
|
||||
private val twoLinesTabToolbarHeight = 48F.dip2px()
|
||||
|
||||
private var autoVideoView: AutomaticVideoView? = null
|
||||
private val volumeObserver by lazy {
|
||||
VolumeObserver(object : MuteCallback {
|
||||
override fun onMute(isMute: Boolean) {
|
||||
if (::binding.isInitialized) {
|
||||
binding.muteIv.setImageResource(if (isMute) R.drawable.ic_basic_offsound else R.drawable.ic_basic_onsound)
|
||||
}
|
||||
if (isMute) {
|
||||
autoVideoView?.mute()
|
||||
} else {
|
||||
autoVideoView?.unMute()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private var searchStyle: BottomTab.SearchStyle? = null
|
||||
set(value) {
|
||||
@ -214,7 +231,16 @@ class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbar
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
binding = FragmentSearchToolbarTabWrapperBinding.inflate(layoutInflater)
|
||||
binding = try {
|
||||
FragmentSearchToolbarTabWrapperBinding.inflate(layoutInflater)
|
||||
} catch (e: Exception) {
|
||||
SentryHelper.onEvent("VIEW_BINDING_BIND_ERROR",
|
||||
"digest", e.localizedMessage,
|
||||
"gid", HaloApp.getInstance().gid
|
||||
)
|
||||
// 玄学,重试一次,该闪退闪退
|
||||
FragmentSearchToolbarTabWrapperBinding.inflate(layoutInflater)
|
||||
}
|
||||
mCachedView = binding.root
|
||||
return mCachedView
|
||||
}
|
||||
@ -557,6 +583,8 @@ class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbar
|
||||
oldState: RefreshState,
|
||||
newState: RefreshState
|
||||
) {
|
||||
getValidSmartRefreshContent()?.onStateChanged(refreshLayout, oldState, newState)
|
||||
|
||||
val isAutoScrollToTwoLevel = oldState == RefreshState.None && newState == RefreshState.TwoLevel
|
||||
val isDragToTwoLevel =
|
||||
oldState == RefreshState.ReleaseToRefresh && newState == RefreshState.ReleaseToTwoLevel
|
||||
@ -654,49 +682,17 @@ class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbar
|
||||
|
||||
if (isFinishTwoLevel) {
|
||||
pausePullDownPushVideo()
|
||||
showTwoLevel = false
|
||||
|
||||
if (isDragging) {
|
||||
autoFinishTwoLevelHandler?.removeMessages(KEY_AUTO_FINISH_TWO_LEVEL)
|
||||
elapsedHelper.pauseCounting()
|
||||
pullDownPush?.run {
|
||||
SensorsBridge.trackEvent(
|
||||
"DropDownPushClick",
|
||||
json {
|
||||
"action" to pullDownPushAction
|
||||
"button_name" to "关闭推送"
|
||||
"drop_down_push_id" to id
|
||||
"game_name" to game?.name
|
||||
"game_id" to game?.id
|
||||
"bottom_tab" to bottomTabName
|
||||
"several_tab_page_name" to multiTabNavName
|
||||
"several_tab_page_id" to multiTabNavId
|
||||
"position" to lastSelectedPosition
|
||||
"tab_content" to currentTabEntity?.name
|
||||
"custom_page_name" to currentTabEntity?.link?.text
|
||||
"custom_page_id" to currentTabEntity?.link?.link
|
||||
}
|
||||
)
|
||||
com.gh.common.util.NewFlatLogUtils.logHomePushClose(
|
||||
id,
|
||||
"主动收起",
|
||||
twoLevelOpenCount,
|
||||
game?.id ?: "",
|
||||
game?.name ?: "",
|
||||
elapsedHelper.elapsedTime
|
||||
)
|
||||
}
|
||||
finishTwoLevel("主动收起")
|
||||
}
|
||||
showTwoLevel = false
|
||||
}
|
||||
|
||||
when (newState) {
|
||||
RefreshState.TwoLevel -> {
|
||||
getValidSmartRefreshContent()?.setScrollEnabled(false)
|
||||
binding.refreshLayout.isDisableContent = false
|
||||
}
|
||||
RefreshState.None -> {
|
||||
getValidSmartRefreshContent()?.setScrollEnabled(true)
|
||||
|
||||
showTwoLevel = false
|
||||
isDragging = false
|
||||
twoLevelHeader.setFloorDuration(1000)
|
||||
@ -940,6 +936,7 @@ class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbar
|
||||
classicsHeader.visibility = View.INVISIBLE
|
||||
pullDownPushSet.add(id)
|
||||
SPUtils.setStringSet(Constants.SP_PULL_DOWN_PUSH_POP_UP_SET, pullDownPushSet)
|
||||
autoFinishTwoLevelCallback = finishCallback
|
||||
autoFinishTwoLevelHandler = object : Handler(Looper.getMainLooper()) {
|
||||
override fun handleMessage(msg: Message) {
|
||||
super.handleMessage(msg)
|
||||
@ -961,9 +958,6 @@ class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbar
|
||||
val autoFinishDelayTime = putAwaySwitch.toInt() * 1000L
|
||||
autoFinishTwoLevelHandler?.sendEmptyMessageDelayed(KEY_AUTO_FINISH_TWO_LEVEL, autoFinishDelayTime)
|
||||
}
|
||||
else -> {
|
||||
autoFinishTwoLevelCallback = finishCallback
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -971,12 +965,18 @@ class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbar
|
||||
}
|
||||
|
||||
override fun setPullDownPush(pullDownPush: PullDownPush?, pullDownPushHandler: PullDownPushHandler?) {
|
||||
if (!isAdded) return
|
||||
|
||||
if (autoVideoView == null) {
|
||||
binding.autoVideoViewStub.setOnInflateListener { _, inflated ->
|
||||
autoVideoView = LayoutAutoVideoViewBinding.bind(inflated).root
|
||||
setPullDownPushInternal(pullDownPush, pullDownPushHandler)
|
||||
}
|
||||
binding.autoVideoViewStub.inflate()
|
||||
try {
|
||||
binding.autoVideoViewStub.inflateOrShow()
|
||||
} catch (e: Exception) {
|
||||
SentryHelper.onEvent("VIEW_STUB_INFLATE_ERROR", "digest", e.localizedMessage)
|
||||
}
|
||||
} else {
|
||||
setPullDownPushInternal(pullDownPush, pullDownPushHandler)
|
||||
}
|
||||
@ -1038,6 +1038,7 @@ class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbar
|
||||
ImageUtils.display(gameImageIv, imgUrl)
|
||||
}
|
||||
autoVideoView?.onVideoReset()
|
||||
muteIv.isVisible = video != null
|
||||
autoVideoView?.goneIf(video == null) {
|
||||
if (autoVideoView?.isInPlayingState == false) {
|
||||
GSYVideoOptionBuilder()
|
||||
@ -1056,6 +1057,17 @@ class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbar
|
||||
headerContainer.performClick()
|
||||
}
|
||||
}
|
||||
var videoVoiceStatus = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
|
||||
muteIv.setImageResource(if (videoVoiceStatus) R.drawable.ic_basic_offsound else R.drawable.ic_basic_onsound)
|
||||
muteIv.setDebouncedClickListener {
|
||||
videoVoiceStatus = !videoVoiceStatus
|
||||
muteIv.setImageResource(if (videoVoiceStatus) R.drawable.ic_basic_offsound else R.drawable.ic_basic_onsound)
|
||||
if (videoVoiceStatus) {
|
||||
autoVideoView?.mute()
|
||||
} else {
|
||||
autoVideoView?.unMute()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1070,6 +1082,19 @@ class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbar
|
||||
pullDownPushHandler?.doPreProcess(this as? ISmartRefresh, popupPush)
|
||||
}
|
||||
|
||||
private fun observeVolume() {
|
||||
context?.applicationContext?.contentResolver?.registerContentObserver(
|
||||
android.provider.Settings.System.CONTENT_URI,
|
||||
true,
|
||||
volumeObserver
|
||||
)
|
||||
}
|
||||
|
||||
private fun unObserveVolume() {
|
||||
context?.applicationContext?.contentResolver?.unregisterContentObserver(volumeObserver)
|
||||
}
|
||||
|
||||
|
||||
private fun updateRefreshHeaderStyle(force: Boolean = false) {
|
||||
if (lightRefreshHeaderStyle == isDisplayingLightContent && !force) return
|
||||
lightRefreshHeaderStyle = isDisplayingLightContent
|
||||
@ -1114,6 +1139,7 @@ class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbar
|
||||
} else {
|
||||
resumePullDownPushVideo()
|
||||
}
|
||||
observeVolume()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1127,6 +1153,7 @@ class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbar
|
||||
if (!videoUrl.isNullOrEmpty()) {
|
||||
ScrollCalculatorHelper.savePlaySchedule(MD5Utils.getContentMD5(videoUrl), currentPosition)
|
||||
}
|
||||
unObserveVolume()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1142,8 +1169,7 @@ class SearchToolbarTabWrapperFragment : BaseTabWrapperFragment(), ISearchToolbar
|
||||
if (position != 0L) {
|
||||
autoVideoView?.seekTo(position)
|
||||
autoVideoView?.onVideoResume(false)
|
||||
val topVideoVoiceStatus = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
|
||||
if (topVideoVoiceStatus) {
|
||||
if (autoVideoView?.isMute == true) {
|
||||
autoVideoView?.mute()
|
||||
} else {
|
||||
autoVideoView?.unMute()
|
||||
|
||||
@ -21,6 +21,8 @@ import com.gh.gamecenter.entity.MultiTabNav
|
||||
import com.gh.gamecenter.entity.PullDownPush
|
||||
import com.gh.gamecenter.feature.utils.SentryHelper
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.scwang.smartrefresh.layout.api.RefreshLayout
|
||||
import com.scwang.smartrefresh.layout.constant.RefreshState
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
@ -148,10 +150,6 @@ class TabWrapperFragment: BaseTabWrapperFragment(), ISmartRefresh, ISmartRefresh
|
||||
}
|
||||
}
|
||||
|
||||
override fun setScrollEnabled(isScrollEnabled: Boolean) {
|
||||
getValidSmartRefreshContent()?.setScrollEnabled(isScrollEnabled)
|
||||
}
|
||||
|
||||
override fun onRefresh() {
|
||||
getValidSmartRefreshContent()?.onRefresh()
|
||||
}
|
||||
@ -161,6 +159,10 @@ class TabWrapperFragment: BaseTabWrapperFragment(), ISmartRefresh, ISmartRefresh
|
||||
getCurrentTabEntity()?.showPullDownPush = !isSwipeRefreshEnabled
|
||||
}
|
||||
|
||||
override fun onStateChanged(refreshLayout: RefreshLayout, oldState: RefreshState, newState: RefreshState) {
|
||||
getValidSmartRefreshContent()?.onStateChanged(refreshLayout, oldState, newState)
|
||||
}
|
||||
|
||||
override fun setSmartRefreshEnabled(isEnable: Boolean) {
|
||||
(parentFragment as? ISmartRefresh)?.setSmartRefreshEnabled(isEnable)
|
||||
}
|
||||
|
||||
@ -41,6 +41,8 @@ import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.eventbus.EBReuse
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.common.json.json
|
||||
import com.gh.gamecenter.common.observer.MuteCallback
|
||||
import com.gh.gamecenter.common.observer.VolumeObserver
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.core.utils.MD5Utils
|
||||
@ -108,6 +110,20 @@ class ToolbarWrapperFragment : LazyFragment(), ToolbarController, ISmartRefresh,
|
||||
private var mLightToolbar = false
|
||||
private var mAutoFinishTwoLevelHandler: Handler? = null
|
||||
private var mAutoFinishTwoLevelCallback: (() -> Unit)? = null
|
||||
private val mVolumeObserver by lazy {
|
||||
VolumeObserver(object : MuteCallback {
|
||||
override fun onMute(isMute: Boolean) {
|
||||
if (::mBinding.isInitialized) {
|
||||
mBinding.muteIv.setImageResource(if (isMute) R.drawable.ic_basic_offsound else R.drawable.ic_basic_onsound)
|
||||
if (isMute) {
|
||||
mBinding.autoVideoView.mute()
|
||||
} else {
|
||||
mBinding.autoVideoView.unMute()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private lateinit var mElapsedHelper: TimeElapsedHelper
|
||||
|
||||
@ -227,6 +243,7 @@ class ToolbarWrapperFragment : LazyFragment(), ToolbarController, ISmartRefresh,
|
||||
gameImageIv.goneIf(video != null) {
|
||||
ImageUtils.display(gameImageIv, imgUrl)
|
||||
}
|
||||
muteIv.isVisible = video != null
|
||||
autoVideoView.goneIf(video == null) {
|
||||
if (!autoVideoView.isInPlayingState) {
|
||||
GSYVideoOptionBuilder()
|
||||
@ -258,6 +275,17 @@ class ToolbarWrapperFragment : LazyFragment(), ToolbarController, ISmartRefresh,
|
||||
headerContainer.performClick()
|
||||
}
|
||||
}
|
||||
var videoVoiceStatus = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
|
||||
muteIv.setImageResource(if (videoVoiceStatus) R.drawable.ic_basic_offsound else R.drawable.ic_basic_onsound)
|
||||
muteIv.setDebouncedClickListener {
|
||||
videoVoiceStatus = !videoVoiceStatus
|
||||
muteIv.setImageResource(if (videoVoiceStatus) R.drawable.ic_basic_offsound else R.drawable.ic_basic_onsound)
|
||||
if (videoVoiceStatus) {
|
||||
autoVideoView.mute()
|
||||
} else {
|
||||
autoVideoView.unMute()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -271,6 +299,18 @@ class ToolbarWrapperFragment : LazyFragment(), ToolbarController, ISmartRefresh,
|
||||
pullDownPushHandler?.doPreProcess(this as? ISmartRefresh, popupPush)
|
||||
}
|
||||
|
||||
private fun observeVolume() {
|
||||
context?.applicationContext?.contentResolver?.registerContentObserver(
|
||||
android.provider.Settings.System.CONTENT_URI,
|
||||
true,
|
||||
mVolumeObserver
|
||||
)
|
||||
}
|
||||
|
||||
private fun unObserveVolume() {
|
||||
context?.applicationContext?.contentResolver?.unregisterContentObserver(mVolumeObserver)
|
||||
}
|
||||
|
||||
override fun onFragmentPause() {
|
||||
super.onFragmentPause()
|
||||
DownloadManager.getInstance().removeObserver(mDataWatcher)
|
||||
@ -434,6 +474,8 @@ class ToolbarWrapperFragment : LazyFragment(), ToolbarController, ISmartRefresh,
|
||||
oldState: RefreshState,
|
||||
newState: RefreshState
|
||||
) {
|
||||
(mContentFragment as? ISmartRefreshContent)?.onStateChanged(refreshLayout, oldState, newState)
|
||||
|
||||
val isAutoScrollToTwoLevel = oldState == RefreshState.None && newState == RefreshState.TwoLevel
|
||||
val isDragToTwoLevel =
|
||||
oldState == RefreshState.ReleaseToRefresh && newState == RefreshState.ReleaseToTwoLevel
|
||||
@ -550,12 +592,9 @@ class ToolbarWrapperFragment : LazyFragment(), ToolbarController, ISmartRefresh,
|
||||
|
||||
when (newState) {
|
||||
RefreshState.TwoLevel -> {
|
||||
(mContentFragment as? ISmartRefreshContent)?.setScrollEnabled(false)
|
||||
mBinding.refreshLayout.isDisableContent = false
|
||||
}
|
||||
RefreshState.None -> {
|
||||
(mContentFragment as? ISmartRefreshContent)?.setScrollEnabled(true)
|
||||
|
||||
mShowTwoLevel = false
|
||||
mIsDragging = false
|
||||
twoLevelHeader.setFloorDuration(1000)
|
||||
@ -739,6 +778,7 @@ class ToolbarWrapperFragment : LazyFragment(), ToolbarController, ISmartRefresh,
|
||||
} else {
|
||||
resumePullDownPushVideo()
|
||||
}
|
||||
observeVolume()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -752,6 +792,7 @@ class ToolbarWrapperFragment : LazyFragment(), ToolbarController, ISmartRefresh,
|
||||
if (videoUrl.isNotEmpty()) {
|
||||
ScrollCalculatorHelper.savePlaySchedule(MD5Utils.getContentMD5(videoUrl), currentPosition)
|
||||
}
|
||||
unObserveVolume()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -767,8 +808,7 @@ class ToolbarWrapperFragment : LazyFragment(), ToolbarController, ISmartRefresh,
|
||||
if (position != 0L) {
|
||||
autoVideoView.seekTo(position)
|
||||
autoVideoView.onVideoResume(false)
|
||||
val topVideoVoiceStatus = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
|
||||
if (topVideoVoiceStatus) {
|
||||
if (autoVideoView.isMute) {
|
||||
autoVideoView.mute()
|
||||
} else {
|
||||
autoVideoView.unMute()
|
||||
|
||||
@ -416,7 +416,7 @@ object NDownloadBridge : InnerDownloadListener, IErrorRetryHandler {
|
||||
}, GlobalDownloadConfig.ERROR_RETRY_INTERVAL)
|
||||
}
|
||||
|
||||
private fun isDownloadViaTrafficAllowed(downloadEntity: DownloadEntity?): Boolean {
|
||||
fun isDownloadViaTrafficAllowed(downloadEntity: DownloadEntity?): Boolean {
|
||||
val mNetworkMobileStatus = "2G3G4G5G"
|
||||
val networkStatus: String? = downloadEntity?.meta?.get(DownloadEntity.NETWORK_STATUS_KEY)
|
||||
Utils.log("download network status$networkStatus")
|
||||
|
||||
@ -9,6 +9,8 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.recyclerview.widget.*
|
||||
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
|
||||
import androidx.viewpager2.widget.ViewPager2.PageTransformer
|
||||
@ -17,6 +19,7 @@ import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.utils.ImageUtils
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.common.utils.layoutInflater
|
||||
import com.gh.gamecenter.common.utils.safelyGetInRelease
|
||||
import com.gh.gamecenter.common.view.PageControllerAdapter
|
||||
import com.gh.gamecenter.common.view.PageTransformerAdapter
|
||||
import com.gh.gamecenter.common.view.ScrollEventListener
|
||||
@ -76,9 +79,7 @@ class VGameInstalledLaunchDialog : DialogFragment() {
|
||||
val newInstalledList = (installAdapter.currentList + installGameEntity).sortedWith { o1, o2 ->
|
||||
(o1.installTime - o2.installTime).toInt()
|
||||
}
|
||||
installAdapter.submitList(newInstalledList) {
|
||||
updateGameDesc(newInstalledList.size)
|
||||
}
|
||||
installAdapter.submitList(newInstalledList)
|
||||
}
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
@ -122,7 +123,7 @@ class VGameInstalledLaunchDialog : DialogFragment() {
|
||||
val horizontalPadding = ((DIALOG_WIDTH - VIEW_PAGER_WIDTH) / 2).dip2px()
|
||||
setPadding(horizontalPadding, 0, horizontalPadding, 0)
|
||||
|
||||
adapter = installAdapter
|
||||
adapter = installAdapter.apply { setOnCommitCallback { updateGameDesc(it) } }
|
||||
|
||||
layoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
|
||||
|
||||
@ -139,7 +140,8 @@ class VGameInstalledLaunchDialog : DialogFragment() {
|
||||
it.registerOnPageChangeCallback(object : OnPageChangeCallback() {
|
||||
override fun onPageSelected(position: Int) {
|
||||
val currentList = installAdapter.currentList
|
||||
gameName.text = currentList[position].gameName
|
||||
val item = currentList.safelyGetInRelease(position) ?: return
|
||||
gameName.text = item.gameName
|
||||
}
|
||||
})
|
||||
|
||||
@ -151,7 +153,8 @@ class VGameInstalledLaunchDialog : DialogFragment() {
|
||||
|
||||
launch.setOnClickListener { view ->
|
||||
val currentItem = pageControllerAdapter.currentItem
|
||||
val installedGame = installAdapter.currentList[currentItem]
|
||||
val installedGame =
|
||||
installAdapter.currentList.safelyGetInRelease(currentItem) ?: return@setOnClickListener
|
||||
val vDownloadEntity =
|
||||
VHelper.getVDownloadEntitySnapshot(installedGame.gameId, installedGame.packageName)
|
||||
?: return@setOnClickListener
|
||||
@ -178,6 +181,11 @@ class VGameInstalledLaunchDialog : DialogFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
installAdapter.setOnCommitCallback(null)
|
||||
}
|
||||
|
||||
private fun updateGameDesc(size: Int) {
|
||||
binding?.gameDesc?.text = if (size == 1) {
|
||||
getString(R.string.dialog_vgame_installed_launch_desc_1)
|
||||
@ -186,9 +194,7 @@ class VGameInstalledLaunchDialog : DialogFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
class VInstalledGameListAdapter(
|
||||
|
||||
) : ListAdapter<InstallGameEntity, VInstalledGameItemViewHolder>(COMPARATOR) {
|
||||
class VInstalledGameListAdapter: ListAdapter<InstallGameEntity, VInstalledGameItemViewHolder>(COMPARATOR) {
|
||||
|
||||
companion object {
|
||||
private val COMPARATOR = object : DiffUtil.ItemCallback<InstallGameEntity>() {
|
||||
@ -210,12 +216,18 @@ class VGameInstalledLaunchDialog : DialogFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private var onCommitCallback: ((Int) -> Unit)? = null
|
||||
|
||||
private var onItemClickListener: ((View, Int) -> Unit)? = null
|
||||
|
||||
fun setOnItemClickListener(onItemClick: (View, Int) -> Unit) {
|
||||
this.onItemClickListener = onItemClick
|
||||
}
|
||||
|
||||
fun setOnCommitCallback(onCommitCallback: ((Int) -> Unit)?) {
|
||||
this.onCommitCallback = onCommitCallback
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VInstalledGameItemViewHolder =
|
||||
VInstalledGameItemViewHolder(
|
||||
ItemVgameInstalledLaunchBinding.inflate(
|
||||
@ -233,6 +245,12 @@ class VGameInstalledLaunchDialog : DialogFragment() {
|
||||
onItemClickListener?.invoke(it, position)
|
||||
}
|
||||
}
|
||||
|
||||
override fun submitList(list: List<InstallGameEntity>?) {
|
||||
super.submitList(list) {
|
||||
onCommitCallback?.invoke(itemCount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VInstalledGameItemViewHolder(val binding: ItemVgameInstalledLaunchBinding) :
|
||||
|
||||
@ -6,6 +6,7 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.database.sqlite.SQLiteDiskIOException
|
||||
import android.database.sqlite.SQLiteException
|
||||
import android.database.sqlite.SQLiteFullException
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
@ -2321,17 +2322,25 @@ object VHelper {
|
||||
LOG_TAG,
|
||||
"登录成功,插入用户信息:token=${token},userName=${userName}, uri=${va.getUriAuthorizationString()}"
|
||||
)
|
||||
HaloApp.getInstance().contentResolver.insert(
|
||||
Uri.parse(va.getUriAuthorizationString()),
|
||||
va.getAuthContentValue(token, userName, userAvatar)
|
||||
)
|
||||
try {
|
||||
HaloApp.getInstance().contentResolver.insert(
|
||||
Uri.parse(va.getUriAuthorizationString()),
|
||||
va.getAuthContentValue(token, userName, userAvatar)
|
||||
)
|
||||
} catch (e: SQLiteException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
} else {
|
||||
Utils.log(LOG_TAG, "登出,删除用户信息")
|
||||
HaloApp.getInstance().contentResolver.delete(
|
||||
Uri.parse(va.getUriAuthorizationString()),
|
||||
null,
|
||||
null
|
||||
)
|
||||
try {
|
||||
HaloApp.getInstance().contentResolver.delete(
|
||||
Uri.parse(va.getUriAuthorizationString()),
|
||||
null,
|
||||
null
|
||||
)
|
||||
} catch (e: SQLiteException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,7 +25,6 @@ import com.facebook.imagepipeline.core.ImageTranscoderType;
|
||||
import com.facebook.imagepipeline.core.MemoryChunkType;
|
||||
import com.facebook.imagepipeline.decoder.ImageDecoderConfig;
|
||||
import com.gh.ad.AdDelegateHelper;
|
||||
import com.gh.ad.AdPluginDownloadHelper;
|
||||
import com.gh.base.GlobalActivityLifecycleObserver;
|
||||
import com.gh.common.FixedRateJobHelper;
|
||||
import com.gh.common.filter.RegionSettingHelper;
|
||||
@ -57,7 +56,6 @@ import com.gh.gamecenter.common.utils.DeviceUtils;
|
||||
import com.gh.gamecenter.common.utils.EnvHelper;
|
||||
import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.common.utils.ImageUtils;
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge;
|
||||
import com.gh.gamecenter.core.AppExecutor;
|
||||
import com.gh.gamecenter.core.iinterface.IApplication;
|
||||
import com.gh.gamecenter.core.provider.IFlavorProvider;
|
||||
@ -331,7 +329,8 @@ public class HaloApp extends MultiDexApplication {
|
||||
OAIDHelper.INSTANCE.getOAID(HaloApp.this, (s, isSuccess) -> {
|
||||
setOAID(s);
|
||||
MetaUtil.INSTANCE.refreshMeta();
|
||||
SensorsBridge.INSTANCE.setOAID(s);
|
||||
|
||||
DataUtils.bindValidOaidToSensor(true);
|
||||
|
||||
if (getGid() != null) {
|
||||
DataUtils.getDeviceCertification(getGid());
|
||||
|
||||
@ -2,5 +2,5 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="6dp" />
|
||||
<solid android:color="@color/text_f9f9f9" />
|
||||
<solid android:color="@color/ui_container_1" />
|
||||
</shape>
|
||||
19
app/src/main/res/drawable/ic_basic_offsound.xml
Normal file
19
app/src/main/res/drawable/ic_basic_offsound.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M11.183,5.778C11.51,5.511 12,5.744 12,6.165V8.909C12,9.461 12.448,9.909 13,9.909C13.552,9.909 14,9.461 14,8.909V6.165C14,4.056 11.549,2.895 9.917,4.23L8.756,5.181C8.328,5.53 8.265,6.16 8.615,6.588C8.965,7.015 9.595,7.078 10.022,6.728L11.183,5.778Z"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M20.66,7C20.384,6.522 19.772,6.358 19.294,6.634C18.816,6.91 18.652,7.522 18.928,8C19.63,9.216 20,10.596 20,12C20,12.92 19.841,13.83 19.534,14.69C19.349,15.21 19.62,15.782 20.14,15.968C20.66,16.153 21.232,15.882 21.418,15.362C21.802,14.287 22,13.15 22,12C22,10.245 21.538,8.52 20.66,7Z"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M17.796,10.447C17.653,9.914 17.104,9.597 16.571,9.74C16.037,9.883 15.721,10.431 15.864,10.965C15.967,11.35 16.012,11.748 15.998,12.143C15.978,12.695 16.409,13.159 16.961,13.179C17.513,13.198 17.976,12.767 17.996,12.215C18.017,11.622 17.951,11.026 17.796,10.447Z"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M2.224,4.869C2.572,4.441 3.202,4.376 3.631,4.724L19.631,17.724C20.059,18.072 20.124,18.702 19.776,19.131C19.428,19.559 18.798,19.624 18.369,19.276L14,15.726V17.835C14,19.944 11.549,21.105 9.917,19.77L7.143,17.5H5C3.343,17.5 2,16.157 2,14.5V9.5C2,8.476 2.513,7.571 3.297,7.03L2.369,6.276C1.941,5.928 1.876,5.298 2.224,4.869ZM5.106,8.5L12,14.101V17.835C12,18.256 11.51,18.489 11.183,18.222L8.133,15.726C7.955,15.58 7.731,15.5 7.5,15.5H5C4.448,15.5 4,15.052 4,14.5V9.5C4,8.948 4.448,8.5 5,8.5H5.106Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
16
app/src/main/res/drawable/ic_basic_onsound.xml
Normal file
16
app/src/main/res/drawable/ic_basic_onsound.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M9.917,4.23C11.549,2.895 14,4.056 14,6.165V17.835C14,19.944 11.549,21.105 9.917,19.77L7.143,17.5H5C3.343,17.5 2,16.157 2,14.5V9.5C2,7.843 3.343,6.5 5,6.5H7.143L9.917,4.23ZM12,6.165C12,5.744 11.51,5.511 11.183,5.778L8.133,8.274C7.955,8.42 7.731,8.5 7.5,8.5H5C4.448,8.5 4,8.948 4,9.5V14.5C4,15.052 4.448,15.5 5,15.5H7.5C7.731,15.5 7.955,15.58 8.133,15.726L11.183,18.222C11.51,18.489 12,18.257 12,17.835V6.165Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M16.571,9.74C17.104,9.597 17.653,9.914 17.796,10.447C18.068,11.464 18.068,12.536 17.796,13.553C17.653,14.086 17.104,14.403 16.571,14.26C16.037,14.117 15.721,13.569 15.864,13.035C16.045,12.357 16.045,11.643 15.864,10.965C15.721,10.431 16.037,9.883 16.571,9.74Z"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M20.66,7C20.384,6.522 19.772,6.358 19.294,6.634C18.816,6.91 18.652,7.522 18.928,8C19.63,9.216 20,10.596 20,12C20,13.404 19.63,14.784 18.928,16C18.652,16.478 18.816,17.09 19.294,17.366C19.772,17.642 20.384,17.478 20.66,17C21.538,15.48 22,13.755 22,12C22,10.245 21.538,8.52 20.66,7Z"
|
||||
android:fillColor="#000000"/>
|
||||
</vector>
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
<item android:id="@android:id/background">
|
||||
<shape>
|
||||
<solid android:color="@color/text_f9f9f9" />
|
||||
<solid android:color="@color/ui_container_1" />
|
||||
|
||||
<corners
|
||||
android:bottomLeftRadius="0dp"
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.gh.gamecenter.common.view.MaterializedRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<FrameLayout
|
||||
<com.gh.gamecenter.common.view.MaterializedFrameLayout
|
||||
android:id="@id/layout_activity_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
@ -97,4 +97,4 @@
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
</com.gh.gamecenter.common.view.MaterializedRelativeLayout>
|
||||
@ -62,16 +62,16 @@
|
||||
android:id="@+id/gameSubtitleTv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:layout_marginStart="4dp"
|
||||
android:paddingLeft="2dp"
|
||||
android:paddingRight="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
tools:text="副标题" />
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题"
|
||||
tools:textColor="@color/text_secondary"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
|
||||
@ -76,15 +76,14 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:text="副标题" />
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题"
|
||||
tools:textColor="@color/text_secondary" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/recent_played_tag"
|
||||
|
||||
@ -79,15 +79,14 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题"
|
||||
tools:textColor="@color/text_secondary"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@ -38,15 +37,14 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题"
|
||||
tools:textColor="@color/text_secondary"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
|
||||
@ -13,11 +13,11 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:tabBackground="@color/ui_surface"
|
||||
app:tabIndicator="@drawable/search_tab_indicator"
|
||||
app:tabIndicatorHeight="3dp"
|
||||
app:tabPaddingEnd="12dp"
|
||||
app:tabPaddingStart="12dp"
|
||||
app:tabTextColor="@color/text_primary"
|
||||
app:tabSelectedTextColor="@color/text_theme" />
|
||||
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
|
||||
@ -102,15 +102,14 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题"
|
||||
tools:textColor="@color/text_secondary"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
|
||||
@ -164,6 +163,19 @@
|
||||
app:lottie_loop="true"
|
||||
app:lottie_repeatMode="restart" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/muteIv"
|
||||
android:layout_width="28dp"
|
||||
android:layout_height="28dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:padding="4dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:srcCompat="@drawable/ic_basic_offsound"
|
||||
app:tint="@color/text_instance" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/headerBackground"
|
||||
android:layout_width="0dp"
|
||||
|
||||
@ -107,15 +107,14 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题"
|
||||
tools:textColor="@color/text_secondary"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
|
||||
@ -169,6 +168,19 @@
|
||||
app:lottie_loop="true"
|
||||
app:lottie_repeatMode="restart" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/muteIv"
|
||||
android:layout_width="28dp"
|
||||
android:layout_height="28dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:padding="4dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:srcCompat="@drawable/ic_basic_offsound"
|
||||
app:tint="@color/text_instance" />
|
||||
|
||||
<View
|
||||
android:id="@+id/headerBackground"
|
||||
android:layout_width="0dp"
|
||||
|
||||
@ -53,16 +53,15 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
tools:text="副标题" />
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题"
|
||||
tools:textColor="@color/text_secondary"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
|
||||
@ -88,15 +88,14 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题副标题副标题"
|
||||
tools:textColor="@color/text_secondary"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
|
||||
@ -56,16 +56,14 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_toRightOf="@id/home2_game_nameAndsize"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题"
|
||||
tools:textColor="@color/text_secondary"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
|
||||
@ -57,15 +57,15 @@
|
||||
android:id="@+id/gameSubtitleTv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:layout_marginStart="8dp"
|
||||
android:paddingLeft="2dp"
|
||||
android:paddingRight="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题"
|
||||
tools:textColor="@color/text_secondary"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@ -57,15 +57,15 @@
|
||||
android:id="@+id/gameSubtitleTv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:layout_marginStart="8dp"
|
||||
android:paddingLeft="2dp"
|
||||
android:paddingRight="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题"
|
||||
tools:textColor="@color/text_secondary"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@ -63,15 +63,14 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题"
|
||||
tools:textColor="@color/text_secondary"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
|
||||
@ -103,15 +103,14 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题"
|
||||
tools:textColor="@color/text_secondary"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
|
||||
@ -66,15 +66,14 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题"
|
||||
tools:textColor="@color/text_secondary"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@ -43,14 +43,14 @@
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题"
|
||||
tools:textColor="@color/text_secondary"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@ -103,15 +103,14 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题"
|
||||
tools:textColor="@color/text_secondary"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@ -56,15 +56,14 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题"
|
||||
tools:textColor="@color/text_secondary"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@ -76,15 +76,14 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:text="副标题" />
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题"
|
||||
tools:textColor="@color/text_secondary" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/recent_played_tag"
|
||||
|
||||
@ -75,15 +75,14 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题"
|
||||
tools:textColor="@color/text_secondary"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@ -74,15 +74,14 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:background="@drawable/bg_advance_download_game_subtitle"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:visibility="gone"
|
||||
tools:background="@drawable/bg_advance_download_game_subtitle"
|
||||
tools:text="副标题"
|
||||
tools:textColor="@color/text_secondary"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user