From 614a57580c70c5e33ad8ae66ecd4c2728a43f186 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Mon, 11 Apr 2022 17:10:13 +0800 Subject: [PATCH 001/217] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20vspace=20submodule?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitmodules | 3 ++ app/build.gradle | 4 +- app/src/main/java/com/gh/vspace/VHelper.kt | 46 ++++++++++++++++++++++ build.gradle | 1 + dependencies.gradle | 2 +- settings.gradle | 8 +--- 6 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 app/src/main/java/com/gh/vspace/VHelper.kt diff --git a/.gitmodules b/.gitmodules index 07ed87e91f..02337707d1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,3 +5,6 @@ [submodule "assistant_flutter"] path = assistant_flutter url = git@git.shanqu.cc:halo/android/flutter-module.git +[submodule "vspace-bridge"] + path = vspace-bridge + url = git@git.shanqu.cc:cwzs/android/vspace-bridge.git diff --git a/app/build.gradle b/app/build.gradle index 732c8e0c22..565d47e728 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -264,7 +264,9 @@ dependencies { compileOnly "com.github.axen1314.lancet:lancet-base:${lancet_version}" kapt "com.alibaba:arouter-compiler:$arouterVersion" - implementation(project(':module_common')) { + implementation project(':vspace-bridge:vspace') + + implementation (project(':module_common')) { exclude group: 'androidx.swiperefreshlayout' } } diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt new file mode 100644 index 0000000000..2899087a8e --- /dev/null +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -0,0 +1,46 @@ +package com.gh.vspace + +import com.lg.vspace.VirtualAppManager +import com.lg.vspace.remote.listener.RemoteConnectListener +import com.lg.vspace.remote.model.AppInstallerInfo +import com.lightgame.utils.Utils + +object VHelper { + + const val LOG_TAG = "VSPACE" + + fun connectService() { + VirtualAppManager.get().connectService(object : RemoteConnectListener { + override fun onServiceConnectionSuccessed() { + Utils.log(LOG_TAG, "V connect successful") + } + + override fun onServiceConnectionFailed(failCode: Int) { + Utils.log(LOG_TAG, "V connect failed") + } + }) + } + + /** + * 获取已安装列表 + */ + fun getInstalledList(): List? { + return VirtualAppManager.get().installedGamesInfo + } + + /** + * 检查存储权限 + */ + fun checkStoragePermission() { + + } + + + /** + * 安装新应用 + */ + fun install() { + + } + +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 7800a60303..b826e6fa10 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. apply from: 'dependencies.gradle' +apply from: 'vspace-bridge/config.gradle' buildscript { ext.kotlin_version = '1.6.21' diff --git a/dependencies.gradle b/dependencies.gradle index 968f8ab8f3..881b2f1bb6 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,7 +1,7 @@ ext { //Android buildToolsVersion = "30.0.2" - compileSdkVersion = 30 + compileSdkVersion = 31 minSdkVersion = 16 targetSdkVersion = 28 diff --git a/settings.gradle b/settings.gradle index e0cf03553b..e8f501e9cb 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,12 +1,8 @@ include ':app' -//include ':libraries:im' include ':libraries:LGLibrary' -//include ':libraries:MTA' -include ':libraries:QQShare' -//include ':libraries:TalkingData' -//include ':libraries:UmengPush' -//include ':libraries:WechatShare' +include ':libraries:QQShare' include ':libraries:Matisse' +include ':vspace-bridge:vspace' //setBinding(new Binding([gradle: this])) //evaluate(new File(settingsDir, "assistant_flutter/.android/include_flutter.groovy")) include ':module_core' From 92cab5ae6af3eed470bed48a39cec643d07a98f1 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Mon, 11 Apr 2022 17:20:53 +0800 Subject: [PATCH 002/217] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20VSPACE=20submodule?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vspace-bridge | 1 + 1 file changed, 1 insertion(+) create mode 160000 vspace-bridge diff --git a/vspace-bridge b/vspace-bridge new file mode 160000 index 0000000000..26d0e88ae6 --- /dev/null +++ b/vspace-bridge @@ -0,0 +1 @@ +Subproject commit 26d0e88ae675a5bcc1ffa1eae1efd1f666d28432 From 670f840be1c0a081a9bc73311f91c2a1a75c07f0 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Tue, 12 Apr 2022 09:38:09 +0800 Subject: [PATCH 003/217] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=AE=80=E5=8D=95?= =?UTF-8?q?=E7=9A=84=20V=20=E7=A9=BA=E9=97=B4=E5=B7=A5=E5=85=B7=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VHelper.kt | 48 +++++++++++++++++----- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 2899087a8e..5bf956f5e9 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -1,5 +1,8 @@ package com.gh.vspace +import android.Manifest +import android.app.Activity +import com.gh.common.util.EmptyCallback import com.lg.vspace.VirtualAppManager import com.lg.vspace.remote.listener.RemoteConnectListener import com.lg.vspace.remote.model.AppInstallerInfo @@ -9,38 +12,63 @@ object VHelper { const val LOG_TAG = "VSPACE" + private val mDelegateManager by lazy { VirtualAppManager.get() } + + /** + * 连接服务 + */ fun connectService() { - VirtualAppManager.get().connectService(object : RemoteConnectListener { + mDelegateManager.connectService(object : RemoteConnectListener { override fun onServiceConnectionSuccessed() { - Utils.log(LOG_TAG, "V connect successful") + Utils.log(LOG_TAG, "V 服务连接成功") } override fun onServiceConnectionFailed(failCode: Int) { - Utils.log(LOG_TAG, "V connect failed") + Utils.log(LOG_TAG, "V 服务连接失败") } }) } /** - * 获取已安装列表 + * 获取已安装列表信息 */ fun getInstalledList(): List? { - return VirtualAppManager.get().installedGamesInfo + try { + return mDelegateManager.installedGamesInfo + } catch (e: RuntimeException) { + Utils.log(LOG_TAG, "获取安装列表信息失败") + return null + } } /** - * 检查存储权限 + * 检查存储权限,若已授予直接执行后续逻辑 */ - fun checkStoragePermission() { - + fun checkStoragePermissionBeforeAction(activity: Activity, emptyCallback: EmptyCallback) { + try { + val isStoragePermissionGranted = mDelegateManager.checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE) + if (isStoragePermissionGranted) { + emptyCallback.onCallback() + } else { + activity.startActivity(mDelegateManager.requestPermissionIntent) + } + } catch (e: RuntimeException) { + Utils.log(LOG_TAG, "检查存储权限失败") + } } - /** * 安装新应用 */ - fun install() { + fun install(filePath: String) { + VirtualAppManager.get().installGame(filePath) + } + /** + * 卸载已有应用 + */ + fun uninstall(packageName: String) { + VirtualAppManager.get().uninstallGame(packageName) } } \ No newline at end of file From 49091b7a72949407246f45b1d94986e619b23c25 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Wed, 13 Apr 2022 18:15:42 +0800 Subject: [PATCH 004/217] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=AE=80=E5=8D=95?= =?UTF-8?q?=E7=9A=84=E4=BA=A4=E4=BA=92=E5=B7=A5=E5=85=B7=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/common/databind/BindingAdapters.java | 43 ++--- .../java/com/gh/common/util/DataUtils.java | 2 +- .../gh/common/util/DetailDownloadUtils.java | 4 + .../com/gh/common/util/DownloadItemUtils.kt | 177 ++++++++---------- .../common/util/GameActivityDownloadHelper.kt | 67 +++---- .../java/com/gh/common/util/GameUtils.java | 3 +- .../com/gh/common/util/PackageInstaller.kt | 4 + .../java/com/gh/common/util/RealNameHelper.kt | 5 - .../java/com/gh/download/DownloadManager.java | 5 + .../adapter/viewholder/DetailViewHolder.java | 8 +- .../gh/gamecenter/entity/GameDetailEntity.kt | 3 + app/src/main/java/com/gh/vspace/VHelper.kt | 148 +++++++++++++-- .../main/java/com/halo/assistant/HaloApp.java | 9 + .../res/layout/fragment_main_home_wrapper.xml | 1 + app/src/main/res/values/strings.xml | 2 + .../gamecenter/common/constant/Constants.java | 5 +- 16 files changed, 300 insertions(+), 186 deletions(-) diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java index b162c974ea..2904df851c 100644 --- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java +++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java @@ -29,7 +29,6 @@ import com.gh.common.repository.ReservationRepository; import com.gh.common.simulator.SimulatorDownloadManager; import com.gh.common.simulator.SimulatorGameManager; import com.gh.common.util.CheckLoginUtils; -import com.gh.common.util.DataUtils; import com.gh.common.util.DialogUtils; import com.gh.gamecenter.common.utils.ExtensionsKt; import com.gh.gamecenter.common.utils.NightModeUtils; @@ -45,7 +44,6 @@ import com.gh.gamecenter.core.utils.NumberUtils; import com.gh.common.util.PackageInstaller; import com.gh.common.util.PackageUtils; import com.gh.common.util.PlatformUtils; -import com.gh.common.util.RealNameHelper; import com.gh.common.util.ReservationHelper; import com.gh.common.view.DownloadProgressBar; import com.gh.gamecenter.common.view.DrawableView; @@ -69,6 +67,7 @@ import com.gh.gamecenter.eventbus.EBReuse; import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment; import com.gh.gamecenter.manager.PackagesManager; import com.gh.gamecenter.qa.entity.CommunityVideoEntity; +import com.gh.vspace.VHelper; import com.lightgame.download.DownloadEntity; import com.lightgame.download.FileUtils; import com.lightgame.utils.Utils; @@ -378,7 +377,7 @@ public class BindingAdapters { return; } } - RealNameHelper.checkIfAuth(v.getContext(), gameEntity, () -> { + VHelper.checkVSpaceBeforeAction(v.getContext(), gameEntity, () -> { GamePermissionDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, gameEntity.getInfo(), () -> { BrowserInstallHelper.showBrowserInstallHintDialog(v.getContext(), () -> { PackageCheckDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, () -> { @@ -397,17 +396,15 @@ public class BindingAdapters { }); }); } else { - RealNameHelper.checkIfAuth(v.getContext(), gameEntity, () -> { - GamePermissionDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, gameEntity.getInfo(), () -> { - CertificationDialog.showCertificationDialog(v.getContext(), gameEntity, () -> { - DialogUtils.showVersionNumberDialog(v.getContext(), gameEntity, () -> { - DownloadDialog.showDownloadDialog( - v.getContext(), - gameEntity, - traceEvent, - entrance, - location + ":" + gameEntity.getName()); - }); + GamePermissionDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, gameEntity.getInfo(), () -> { + CertificationDialog.showCertificationDialog(v.getContext(), gameEntity, () -> { + DialogUtils.showVersionNumberDialog(v.getContext(), gameEntity, () -> { + DownloadDialog.showDownloadDialog( + v.getContext(), + gameEntity, + traceEvent, + entrance, + location + ":" + gameEntity.getName()); }); }); }); @@ -429,6 +426,12 @@ public class BindingAdapters { } return; } + + if (VHelper.isSGame(gameEntity)) { + VHelper.launch((AppCompatActivity) v.getContext(), gameEntity.getApk().get(0).getPackageName()); + return; + } + PackageUtils.launchApplicationByPackageName(v.getContext(), gameEntity.getApk().get(0).getPackageName()); } else { DownloadDialog.showDownloadDialog( @@ -449,13 +452,11 @@ public class BindingAdapters { } break; case RESERVABLE: - RealNameHelper.checkIfAuth(v.getContext(), gameEntity, () -> { - GamePermissionDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, gameEntity.getInfo(), () -> { - CheckLoginUtils.checkLogin(progressBar.getContext(), "", () -> { - ReservationHelper.reserve(v.getContext(), gameEntity.getId(), () -> { - LogUtils.logReservation(gameEntity, traceEvent); - updateReservation(progressBar, gameEntity); - }); + GamePermissionDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, gameEntity.getInfo(), () -> { + CheckLoginUtils.checkLogin(progressBar.getContext(), "", () -> { + ReservationHelper.reserve(v.getContext(), gameEntity.getId(), () -> { + LogUtils.logReservation(gameEntity, traceEvent); + updateReservation(progressBar, gameEntity); }); }); }); diff --git a/app/src/main/java/com/gh/common/util/DataUtils.java b/app/src/main/java/com/gh/common/util/DataUtils.java index fc42f3f726..3326e562ff 100644 --- a/app/src/main/java/com/gh/common/util/DataUtils.java +++ b/app/src/main/java/com/gh/common/util/DataUtils.java @@ -43,7 +43,7 @@ import kotlin.Pair; /** * Created by LGT on 2016/6/15. - * 数据收集 工具类 (TalkingData、MTA) + * 数据收集工具类 */ public class DataUtils { diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index dd1d3586dd..d67b9dc674 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -17,6 +17,7 @@ import com.gh.gamecenter.core.utils.SPUtils; import com.gh.gamecenter.entity.LinkEntity; import com.gh.gamecenter.entity.PluginLocation; import com.gh.gamecenter.manager.PackagesManager; +import com.gh.vspace.VHelper; import com.lightgame.download.DownloadEntity; /** @@ -181,6 +182,9 @@ public class DetailDownloadUtils { } viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL); } + } else if (VHelper.isSGame(viewHolder.gameEntity)) { + viewHolder.mDownloadPb.setText(R.string.smooth_launch); + viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.LAUNCH_OR_OPEN); } else { if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL)) { viewHolder.mDownloadPb.setText(R.string.browser_install_install); diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index 55f51c09fb..b5bf14e78b 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -38,6 +38,7 @@ import com.gh.gamecenter.entity.PluginLocation import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment import com.gh.gamecenter.manager.PackagesManager import com.gh.gamecenter.teenagermode.TeenagerModeActivity +import com.gh.vspace.VHelper import com.lightgame.download.DownloadConfig import com.lightgame.download.DownloadEntity import com.lightgame.download.DownloadStatus @@ -611,27 +612,17 @@ object DownloadItemUtils { downloadBtn.setOnClickListener { view: View -> allStateClickCallback?.onCallback() clickCallback?.onCallback() - RealNameHelper.checkIfAuth(view.context, gameEntity, object : EmptyCallback { - override fun onCallback() { - GamePermissionDialogFragment.show(context, gameEntity, gameEntity.info, object : ConfirmListener { - override fun onConfirm() { - PermissionHelper.checkStoragePermissionBeforeAction(context, object : EmptyCallback { - override fun onCallback() { - CertificationDialog.showCertificationDialog(context, gameEntity, object : ConfirmListener { - override fun onConfirm() { - DialogUtils.showVersionNumberDialog(context, gameEntity, object : ConfirmListener { - override fun onConfirm() { - DownloadDialog.showDownloadDialog(view.context, gameEntity, traceEvent, entrance, location) - } - }) - } - }) - } - }) - } - }) - } - }) + GamePermissionDialogFragment.show(context, gameEntity, gameEntity.info) { + PermissionHelper.checkStoragePermissionBeforeAction(context, object : EmptyCallback { + override fun onCallback() { + CertificationDialog.showCertificationDialog(context, gameEntity) { + DialogUtils.showVersionNumberDialog(context, gameEntity) { + DownloadDialog.showDownloadDialog(view.context, gameEntity, traceEvent, entrance, location) + } + } + } + }) + } } } } @@ -652,96 +643,69 @@ object DownloadItemUtils { if (gameEntity.getApk().isEmpty()) return val apk = gameEntity.getApk().safelyGetInRelease(0) ?: return if (str == context.getString(R.string.download)) { - // 先弹下载弹窗(如果需要的话) - RealNameHelper.checkIfAuth(context, gameEntity, object : EmptyCallback { - override fun onCallback() { - GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info, object : ConfirmListener { - override fun onConfirm() { - BrowserInstallHelper.showBrowserInstallHintDialog(context, object : EmptyCallback { + GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) { + BrowserInstallHelper.showBrowserInstallHintDialog(context, object : EmptyCallback { + override fun onCallback() { + PackageCheckDialogFragment.show(context, gameEntity) { + DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, object : EmptyCallback { override fun onCallback() { - PackageCheckDialogFragment.show(context, gameEntity, object : ConfirmListener { - override fun onConfirm() { - DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, object : EmptyCallback { - override fun onCallback() { - CertificationDialog.showCertificationDialog(context, gameEntity, object : ConfirmListener { - override fun onConfirm() { - DialogUtils.showOverseaDownloadDialog(context, gameEntity, object : ConfirmListener { - override fun onConfirm() { - DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> - download( - context, - gameEntity, - downloadBtn, - entrance, - location, - isSubscribe, - traceEvent - ) - } - } - }) - } - }) - } - }) + CertificationDialog.showCertificationDialog(context, gameEntity) { + DialogUtils.showOverseaDownloadDialog(context, gameEntity) { + DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> + download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent) + } } - }) + } } }) - } - }) - } - }) + } + }) + } DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance) } else if (str == context.getString(R.string.attempt)) { - RealNameHelper.checkIfAuth(context, gameEntity, object : EmptyCallback { - override fun onCallback() { - GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info, object : ConfirmListener { - override fun onConfirm() { - BrowserInstallHelper.showBrowserInstallHintDialog(context, object : EmptyCallback { + GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) { + BrowserInstallHelper.showBrowserInstallHintDialog(context, object : EmptyCallback { + override fun onCallback() { + PackageCheckDialogFragment.show(context, gameEntity) { + DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, object : EmptyCallback { override fun onCallback() { - PackageCheckDialogFragment.show(context, gameEntity, object : ConfirmListener { - override fun onConfirm() { - DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, object : EmptyCallback { - override fun onCallback() { - CertificationDialog.showCertificationDialog(context, gameEntity, object : ConfirmListener { - override fun onConfirm() { - DialogUtils.showVersionNumberDialog(context, gameEntity, object : ConfirmListener { - override fun onConfirm() { - DialogUtils.showOverseaDownloadDialog( - context, - gameEntity, - object : ConfirmListener { - override fun onConfirm() { - DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> - download( - context, - gameEntity, - downloadBtn, - entrance, - location, - isSubscribe, - traceEvent - ) - } - } - }) - } - }) - } - }) + CertificationDialog.showCertificationDialog(context, gameEntity) { + DialogUtils.showVersionNumberDialog(context, gameEntity) { + DialogUtils.showOverseaDownloadDialog(context, gameEntity) { + DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> + download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent) } - }) + } } - }) + } } }) } - }) - } - }) + } + }) + } DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance) + } else if (str == context.getString(R.string.smooth)) { + VHelper.checkVSpaceBeforeAction(context, gameEntity) { + GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) { + PackageCheckDialogFragment.show(context, gameEntity) { + DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, object : EmptyCallback { + override fun onCallback() { + CertificationDialog.showCertificationDialog(context, gameEntity) { + DialogUtils.showVersionNumberDialog(context, gameEntity) { + DialogUtils.showOverseaDownloadDialog(context, gameEntity) { + DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> + download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent) + } + } + } + } + } + }) + } + } + } } else if (str.contains("化")) { if (entrance.contains("我的游戏")) { MtaHelper.onEvent("我的游戏_启动", "插件化", gameEntity.name) @@ -751,13 +715,11 @@ object DownloadItemUtils { } else { DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, object : EmptyCallback { override fun onCallback() { - CertificationDialog.showCertificationDialog(context, gameEntity, object : ConfirmListener { - override fun onConfirm() { - DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> - plugin(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent) - } + CertificationDialog.showCertificationDialog(context, gameEntity) { + DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> + plugin(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent) } - }) + } } }) } @@ -775,6 +737,8 @@ object DownloadItemUtils { } install(context, gameEntity, position, adapter, refreshCallback) } else if (str == context.getString(R.string.launch)) { + EnergyTaskHelper.postEnergyTask("play_game", gameEntity.id, gameEntity.getApk()[0].packageName) + //启动模拟器游戏 if (SimulatorGameManager.isSimulatorGame(gameEntity)) { val downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk()[0].url) @@ -788,11 +752,16 @@ object DownloadItemUtils { } return } + + if (VHelper.isSGame(gameEntity)) { + VHelper.launch((context as AppCompatActivity), gameEntity.getApk()[0].packageName) + return + } + if (entrance.contains("我的游戏")) { MtaHelper.onEvent("我的游戏_启动", "启动", gameEntity.name) } PackageUtils.launchApplicationByPackageName(context, gameEntity.getApk()[0].packageName) - EnergyTaskHelper.postEnergyTask("play_game", gameEntity.id, gameEntity.getApk()[0].packageName) } else if (str == context.getString(R.string.update)) { if (entrance.contains("我的游戏")) { MtaHelper.onEvent("我的游戏_启动", "更新", gameEntity.name) diff --git a/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt b/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt index ff45a0a046..d095393fec 100644 --- a/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt +++ b/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt @@ -34,6 +34,7 @@ import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.retrofit.RetrofitManager import com.gh.gamecenter.teenagermode.TeenagerModeActivity import com.gh.gamecenter.common.retrofit.ApiResponse +import com.gh.vspace.VHelper import com.gh.gamecenter.common.utils.DataLogUtils import com.lightgame.download.FileUtils @@ -171,46 +172,42 @@ object GameActivityDownloadHelper { } else { val str = GameUtils.getDownloadBtnText(context, gameEntity, PluginLocation.only_game) if (str == context.getString(R.string.download)) { - GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info, object : ConfirmListener { - override fun onConfirm() { - CertificationDialog.showCertificationDialog(context, gameEntity, object : ConfirmListener { - override fun onConfirm() { - DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> - download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent) - } - } - }) + GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) { + CertificationDialog.showCertificationDialog(context, gameEntity) { + DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> + download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent) + } } - }) + } DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance) } else if (str == context.getString(R.string.attempt)) { - RealNameHelper.checkIfAuth(context, gameEntity, object : EmptyCallback { - override fun onCallback() { - GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info, object : ConfirmListener { - override fun onConfirm() { - CertificationDialog.showCertificationDialog(context, gameEntity, object : ConfirmListener { - override fun onConfirm() { - DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> - download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent) - } - } - }) - } - }) + GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) { + CertificationDialog.showCertificationDialog(context, gameEntity) { + DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> + download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent) + } } - }) + } DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance) + } else if (str == context.getString(R.string.smooth)) { + VHelper.checkVSpaceBeforeAction(context, gameEntity) { + GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) { + CertificationDialog.showCertificationDialog(context, gameEntity) { + DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> + download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent) + } + } + } + } } else if (str.contains("化")) { if (gameEntity.pluggableCollection != null) { DownloadDialog.showDownloadDialog(context, gameEntity, traceEvent, entrance, location) } else { - CertificationDialog.showCertificationDialog(context, gameEntity, object : ConfirmListener { - override fun onConfirm() { - DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> - plugin(context, gameEntity, apk, entrance, location, isSubscribe, traceEvent) - } + CertificationDialog.showCertificationDialog(context, gameEntity) { + DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> + plugin(context, gameEntity, apk, entrance, location, isSubscribe, traceEvent) } - }) + } } } else if (str == context.getString(R.string.install) || str == context.getString(R.string.launch)) { ToastUtils.toast("${gameEntity.name}已加入下载队列") @@ -275,11 +272,8 @@ object GameActivityDownloadHelper { ) { val msg = FileUtils.isCanDownload(context, apk.size) if (TextUtils.isEmpty(msg)) { - DownloadManager.createDownload( - context, apk, gameEntity, context.getString( - R.string.download - ), entrance, location, isSubscribe, traceEvent - ) + DownloadManager.createDownload(context, apk, gameEntity, context.getString( + R.string.download), entrance, location, isSubscribe, traceEvent) ToastUtils.toast("${gameEntity.name}已加入下载队列") } else { ToastUtils.toast(msg) @@ -383,8 +377,7 @@ object GameActivityDownloadHelper { if (PackageUtils.isInstalled(context, apk.packageName)) { // 是否可更新 if (PackageUtils.isCanUpdate(apk, event.gameId) - || PackageUtils.isNonPluginUpdatable(apk, gameEntity) - ) { + || PackageUtils.isNonPluginUpdatable(apk, gameEntity)) { handler.complete(false) } else { // 已安装且无更新 diff --git a/app/src/main/java/com/gh/common/util/GameUtils.java b/app/src/main/java/com/gh/common/util/GameUtils.java index 0593b34e7c..b56a9f1fd8 100644 --- a/app/src/main/java/com/gh/common/util/GameUtils.java +++ b/app/src/main/java/com/gh/common/util/GameUtils.java @@ -59,7 +59,6 @@ public class GameUtils { AppExecutor.getLightWeightIoExecutor().execute(() -> { String status = getDownloadBtnText(context, gameEntity, pluginLocation); AppExecutor.getUiExecutor().execute(() -> { - // TODO 切换线程时可能存在页面已销毁 view 已不存在这些乱七八糟的问题 downloadBtn.setTextColor(Color.WHITE); downloadBtn.setText(status); if (context.getString(R.string.pluggable).equals(status)) { @@ -159,6 +158,8 @@ public class GameUtils { return context.getString(R.string.launch); } else if ("demo".equals(gameEntity.getDownloadStatus())) { return context.getString(R.string.attempt); + } else if ("smooth".equals(gameEntity.getDownloadStatus())) { + return context.getString(R.string.smooth); } else { return context.getString(R.string.download); } diff --git a/app/src/main/java/com/gh/common/util/PackageInstaller.kt b/app/src/main/java/com/gh/common/util/PackageInstaller.kt index 7e86761029..bc74ad50cb 100644 --- a/app/src/main/java/com/gh/common/util/PackageInstaller.kt +++ b/app/src/main/java/com/gh/common/util/PackageInstaller.kt @@ -22,6 +22,7 @@ import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.common.retrofit.BiResponse import com.gh.gamecenter.retrofit.RetrofitManager +import com.gh.vspace.VHelper import com.halo.assistant.HaloApp import com.lightgame.download.DownloadEntity import com.lightgame.download.FileUtils @@ -53,6 +54,7 @@ object PackageInstaller { fun install(context: Context, downloadEntity: DownloadEntity, showUnzipToast: Boolean) { val pkgPath = downloadEntity.path val isXapk = XapkInstaller.XAPK_EXTENSION_NAME == pkgPath.getExtension() + val isSmoothGame = downloadEntity.getMetaExtra(Constants.SMOOTH_GAME) == "true" val currentActivity = CurrentActivityHolder.getCurrentActivity() ?: return @@ -70,6 +72,8 @@ object PackageInstaller { val mainIntent = Intent.makeRestartActivityTask(intent!!.component) context.startActivity(mainIntent) Runtime.getRuntime().exit(0) + } else if (isSmoothGame) { + VHelper.install(currentActivity, downloadEntity.path) } else { if (isXapk) { XapkInstaller.install(context, downloadEntity, showUnzipToast) diff --git a/app/src/main/java/com/gh/common/util/RealNameHelper.kt b/app/src/main/java/com/gh/common/util/RealNameHelper.kt index 13239ee8cb..4f2ecbb397 100644 --- a/app/src/main/java/com/gh/common/util/RealNameHelper.kt +++ b/app/src/main/java/com/gh/common/util/RealNameHelper.kt @@ -17,11 +17,6 @@ object RealNameHelper { var pendingInstallPkgPath = "" - @JvmStatic - fun checkIfAuth(context: Context, gameEntity: GameEntity, callback: EmptyCallback) { - callback.onCallback() - } - /** * 弹未成年人不能下载游戏弹窗 */ diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index 875166a613..b08fa4e3e8 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -44,6 +44,7 @@ import com.gh.gamecenter.eventbus.EBDownloadStatus; import com.gh.gamecenter.manager.PackagesManager; import com.gh.gamecenter.manager.UserManager; import com.gh.gamecenter.packagehelper.PackageRepository; +import com.gh.vspace.VHelper; import com.halo.assistant.HaloApp; import com.lightgame.download.ConnectionUtils; import com.lightgame.download.DataChanger; @@ -319,6 +320,10 @@ public class DownloadManager implements DownloadStatusListener { ExtensionsKt.addMetaExtra(downloadEntity, Constants.SIMULATOR, GsonUtils.toJson(gameEntity.getSimulator())); } + if (VHelper.isSGame(gameEntity)) { + ExtensionsKt.addMetaExtra(downloadEntity, Constants.SMOOTH_GAME, "true"); + } + HashMap map = PageSwitchDataHelper.popLastPageData(); if (map != null && map.containsKey(PageSwitchDataHelper.PAGE_GAME_DETAIL_RECOMMEND)) { ExtensionsKt.addMetaExtra(downloadEntity, PageSwitchDataHelper.PAGE_GAME_DETAIL_RECOMMEND, "true"); diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java index 69c81c68d2..facb87f3a1 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java @@ -49,6 +49,7 @@ import com.gh.gamecenter.eventbus.EBScroll; import com.gh.gamecenter.gamedetail.GameDetailFragment; import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment; import com.gh.gamecenter.teenagermode.TeenagerModeActivity; +import com.gh.vspace.VHelper; import com.lightgame.download.DownloadEntity; import com.lightgame.download.FileUtils; import com.lightgame.utils.Utils; @@ -186,7 +187,7 @@ public class DetailViewHolder { case NORMAL: DataLogUtils.uploadGameLog(mViewHolder.context, mGameEntity.getId(), mGameEntity.getName(), mEntrance); case PLUGIN: - RealNameHelper.checkIfAuth(v.getContext(), mGameEntity, () -> { + VHelper.checkVSpaceBeforeAction(mViewHolder.context, mGameEntity, () -> { GamePermissionDialogFragment.show((AppCompatActivity) mViewHolder.context, mGameEntity, mGameEntity.getInfo(), () -> { PermissionHelper.checkStoragePermissionBeforeAction(mViewHolder.context, () -> { if (mGameEntity.getApk().size() == 1) { @@ -236,6 +237,11 @@ public class DetailViewHolder { return; } + if (VHelper.isSGame(mGameEntity)) { + VHelper.launch((AppCompatActivity) mViewHolder.context, mGameEntity.getApk().get(0).getPackageName()); + return; + } + PackageUtils.launchApplicationByPackageName(mViewHolder.context, mGameEntity.getApk().get(0).getPackageName()); } else { GamePermissionDialogFragment.show((AppCompatActivity) mViewHolder.context, mGameEntity, mGameEntity.getInfo(), () -> { diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameDetailEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/GameDetailEntity.kt index 127dcaf72e..95ae0c7d25 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameDetailEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameDetailEntity.kt @@ -81,6 +81,9 @@ class GameDetailEntity( @SerializedName("top_video") var topVideo: Video? = null, + @SerializedName("smooth_relation_game") + var smoothRelatedGame: SimpleGame? = null, + @SerializedName("intro_video") var introVideo: Video? = null, diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 5bf956f5e9..17452dc39a 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -2,7 +2,13 @@ package com.gh.vspace import android.Manifest import android.app.Activity +import android.content.Context +import android.content.Intent +import com.gh.common.AppExecutor import com.gh.common.util.EmptyCallback +import com.gh.common.util.PackageUtils +import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.packagehelper.PackageRepository import com.lg.vspace.VirtualAppManager import com.lg.vspace.remote.listener.RemoteConnectListener import com.lg.vspace.remote.model.AppInstallerInfo @@ -10,49 +16,138 @@ import com.lightgame.utils.Utils object VHelper { - const val LOG_TAG = "VSPACE" + private const val LOG_TAG = "VSPACE" + private const val VSPACE_PACKAGE_NAME = "com.lg.vspace" + private val mDelegateManager by lazy { VirtualAppManager.get() } + private var mInstalledInfoList: List = arrayListOf() + + @JvmStatic + fun init() { + connectService() + } /** * 连接服务 */ - fun connectService() { + private fun connectService() { mDelegateManager.connectService(object : RemoteConnectListener { override fun onServiceConnectionSuccessed() { Utils.log(LOG_TAG, "V 服务连接成功") + mInstalledInfoList = getInstalledList() } override fun onServiceConnectionFailed(failCode: Int) { Utils.log(LOG_TAG, "V 服务连接失败") + // TODO 重试? } }) } - /** - * 获取已安装列表信息 - */ - fun getInstalledList(): List? { - try { - return mDelegateManager.installedGamesInfo + private fun updateInstalledList() { + mInstalledInfoList = try { + mDelegateManager.installedGamesInfo } catch (e: RuntimeException) { Utils.log(LOG_TAG, "获取安装列表信息失败") - return null + mInstalledInfoList } } + /** + * 是否是使用畅玩启动类型的游戏 + */ + @JvmStatic + fun isSGame(gameEntity: GameEntity?): Boolean { + return gameEntity?.downloadStatus == "smooth" + } + + /** + * 在执行 callback 前先检查组件是否已安装,是否可下载 + */ + @JvmStatic + fun checkVSpaceBeforeAction(context: Context, gameEntity: GameEntity?, callback: EmptyCallback) { + checkVSpaceBeforeAction(context, gameEntity) { + callback.onCallback() + } + } + + /** + * 在执行 callback 前先检查组件是否已安装,是否可下载 + */ + fun checkVSpaceBeforeAction(context: Context, gameEntity: GameEntity?, callback: () -> Unit) { + // 仅下载类型为畅玩的类型才执行判断 + if (gameEntity?.downloadStatus == "smooth") { + // TODO 区分 32 位的组件和 64 位的组件 + val isInstalled = PackageUtils.isInstalled(context, VSPACE_PACKAGE_NAME) + + if (!isInstalled) { + // TODO 触发下载弹窗 + return + } + + val containsUpdate = PackageRepository.gameUpdate.any { + it.packageName == VSPACE_PACKAGE_NAME + } + + if (containsUpdate) { + // TODO 触发更新弹窗 + return + } + + callback.invoke() + } else { + callback.invoke() + } + } + + /** + * 获取已安装的包名列表 + */ + fun getInstalledPackageList(): ArrayList { + val installedList = getInstalledList() + val installedPackageList = arrayListOf() + + for (info in installedList) { + installedPackageList.add(info.packageName) + } + + Utils.log(LOG_TAG, "获取已安装包名列表数量${installedPackageList.size}") + + return installedPackageList + } + + /** + * 获取已安装列表信息 (每次调用都会生成一份新的副本,放心使用) + */ + fun getInstalledList(): ArrayList { + val list = mDelegateManager.installedGamesInfo + Utils.log(LOG_TAG, "获取已安装列表数量${list.size}") + + return ArrayList(mDelegateManager.installedGamesInfo) + } + + /** + * 是否已经授予了游戏空间存储权限 + */ + fun isStoragePermissionGranted(): Boolean { + return mDelegateManager.checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE) + } + /** * 检查存储权限,若已授予直接执行后续逻辑 */ - fun checkStoragePermissionBeforeAction(activity: Activity, emptyCallback: EmptyCallback) { + private fun checkStoragePermissionBeforeAction(activity: Activity, callback: () -> Unit) { try { - val isStoragePermissionGranted = mDelegateManager.checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE) + val isStoragePermissionGranted = + mDelegateManager.checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE) if (isStoragePermissionGranted) { - emptyCallback.onCallback() + callback.invoke() } else { activity.startActivity(mDelegateManager.requestPermissionIntent) } } catch (e: RuntimeException) { + e.printStackTrace() Utils.log(LOG_TAG, "检查存储权限失败") } } @@ -60,15 +155,38 @@ object VHelper { /** * 安装新应用 */ - fun install(filePath: String) { - VirtualAppManager.get().installGame(filePath) + fun install(activity: Activity, filePath: String) { + checkStoragePermissionBeforeAction(activity) { + // 安装过程会比较漫长,所以得放在工作线程运行 + AppExecutor.ioExecutor.execute { + val result = VirtualAppManager.get().installGame(filePath) + if (result.status == 0) { + updateInstalledList() + } + Utils.log(LOG_TAG, "安装新应用结果 -> " + result.status) + } + } + } + + /** + * 启动应用 + */ + @JvmStatic + fun launch(activity: Activity, packageName: String) { + val intent = mDelegateManager.getStartGameIntent(packageName) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + activity.startActivity(intent) } /** * 卸载已有应用 */ fun uninstall(packageName: String) { - VirtualAppManager.get().uninstallGame(packageName) + val result = VirtualAppManager.get().uninstallGame(packageName) + if (result) { + updateInstalledList() + } + Utils.log(LOG_TAG, "安装新应用结果 -> $result") } } \ No newline at end of file diff --git a/app/src/main/java/com/halo/assistant/HaloApp.java b/app/src/main/java/com/halo/assistant/HaloApp.java index deef8cae70..8f69479444 100644 --- a/app/src/main/java/com/halo/assistant/HaloApp.java +++ b/app/src/main/java/com/halo/assistant/HaloApp.java @@ -63,6 +63,7 @@ import com.gh.gamecenter.receiver.InstallAndUninstallReceiver; import com.gh.gamecenter.receiver.InstallReceiver; import com.gh.gamecenter.receiver.NetworkStateReceiver; import com.gh.gamecenter.user.UserRepository; +import com.gh.vspace.VHelper; import com.github.piasy.biv.BigImageViewer; import com.github.piasy.biv.loader.fresco.FrescoImageLoader; import com.lightgame.utils.Utils; @@ -270,6 +271,8 @@ public class HaloApp extends MultiDexApplication implements Configuration.Provid AppExecutor.getUiExecutor().executeWithDelay(() -> { initThirdPartySdk(); + retrieveVGameInfoIfNeeded(); + FixedRateJobHelper.begin(); RegionSettingHelper.getRegionSetting(); @@ -436,6 +439,12 @@ public class HaloApp extends MultiDexApplication implements Configuration.Provid } } + private void retrieveVGameInfoIfNeeded() { +// if (SPUtils.getBoolean(Constants.SP_IS_VSPACE_USED)) { + VHelper.init(); +// } + } + public boolean isEmulator() { return mIsEmulator; } diff --git a/app/src/main/res/layout/fragment_main_home_wrapper.xml b/app/src/main/res/layout/fragment_main_home_wrapper.xml index d26d8077a4..cde90ea6d4 100644 --- a/app/src/main/res/layout/fragment_main_home_wrapper.xml +++ b/app/src/main/res/layout/fragment_main_home_wrapper.xml @@ -68,6 +68,7 @@ android:layout_height="match_parent" app:tabMaxWidth="0dp" app:tabMode="scrollable" + app:tabIndicator="@null" app:tabTextAppearance="@style/TabLayoutTextAppearance" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2c42aa51a3..7672fd2079 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -378,6 +378,8 @@ 等待中 打开 试玩 + 畅玩 + 启动(畅玩) 展开 > 解压中 查看 diff --git a/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java b/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java index e739f1f507..9d1f9959fa 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java +++ b/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java @@ -50,7 +50,7 @@ public class Constants { // 最近显示的弹窗信息 public static final String SP_LAST_OPENING_ID = "last_opening_dialog_id"; public static final String SP_LAST_OPENING_TIME = "last_opening_dialog_time"; - + public static final String SP_LAST_ACCEPTED_PRIVACY_DIALOG_ID = "last_accepted_privacy_dialog_id"; // 游戏图标和图标角标 @@ -69,6 +69,7 @@ public class Constants { public static final String SIMULATOR_DOWNLOAD = "下载模拟器"; public static final String SIMULATOR_GAME = "simulator_game"; public static final String SIMULATOR = "simulator"; + public static final String SMOOTH_GAME = "smooth_game"; // 畅玩类型的游戏 public static final String GAME_NAME = "game_name"; public static final String SIMULATOR_DOWNLOAD_START_TIME = "simulator_download_start_time"; public static final String LAST_GHZS_UPDATE_FILE_SIZE = "last_ghzs_update_file_size"; @@ -250,6 +251,8 @@ public class Constants { public static final String SP_WECHAT_CONFIG = "wechat_config"; //游戏库导航栏小红点提示 public static final String SP_GAME_NAVIGATION = "game_navigation"; + // V游戏空间是否被使用过 + public static final String SP_IS_VSPACE_USED = "is_vspace_used"; //手机号码匹配规则 public static final String REGEX_MOBILE = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$"; From 898f72a218ffff893d51058b46cc9e8c6c8930df Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 14 Apr 2022 18:28:57 +0800 Subject: [PATCH 005/217] =?UTF-8?q?=E7=AE=80=E5=8D=95=E5=AF=B9=E6=8E=A5?= =?UTF-8?q?=E7=A9=BA=E9=97=B4=E5=8A=A9=E6=89=8B=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/common/util/DetailDownloadUtils.java | 6 +- .../java/com/gh/download/DownloadManager.java | 23 +-- .../gamecenter/DownloadManagerActivity.java | 8 + .../java/com/gh/gamecenter/MainActivity.java | 2 +- .../gamecenter/download/DownloadFragment.kt | 2 +- .../download/GameDownloadFragment.java | 10 +- .../download/GameDownloadFragmentAdapter.java | 145 ++++++++++-------- .../com/gh/gamecenter/entity/ApkEntity.kt | 1 + .../packagehelper/PackageRepository.kt | 18 ++- .../packagehelper/PackageViewModel.kt | 4 +- .../com/gh/vspace/VDownloadManagerActivity.kt | 19 +++ .../com/gh/vspace/VDownloadManagerAdapter.kt | 23 +++ .../com/gh/vspace/VDownloadManagerFragment.kt | 13 ++ .../gh/vspace/VDownloadManagerViewModel.kt | 19 +++ app/src/main/java/com/gh/vspace/VHelper.kt | 17 +- .../main/java/com/halo/assistant/HaloApp.java | 9 +- .../drawable-xxxhdpi/ic_smooth_manager.png | Bin 0 -> 1375 bytes .../layout/layout_menu_download_manager.xml | 31 ++++ .../main/res/menu/menu_download_manager.xml | 10 ++ .../gh/gamecenter/common/utils/Extensions.kt | 4 + 20 files changed, 264 insertions(+), 100 deletions(-) create mode 100644 app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt create mode 100644 app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt create mode 100644 app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt create mode 100644 app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_smooth_manager.png create mode 100644 app/src/main/res/layout/layout_menu_download_manager.xml create mode 100644 app/src/main/res/menu/menu_download_manager.xml diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index d67b9dc674..319dc5600b 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -102,7 +102,11 @@ public class DetailDownloadUtils { } else if (viewHolder.context.getString(R.string.pluggable).equals(status)) { downloadText = "升级" + (TextUtils.isEmpty(downloadAddWord) ? "" : "至" + downloadAddWord) + getDownloadSizeText(viewHolder); } else if (viewHolder.context.getString(R.string.launch).equals(status)) { - downloadText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : "-" + downloadAddWord); + if (VHelper.isSGame(viewHolder.gameEntity)) { + downloadText = viewHolder.context.getString(R.string.smooth_launch); + } else { + downloadText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : "-" + downloadAddWord); + } } else if (viewHolder.context.getString(R.string.attempt).equals(status)) { downloadText = status + getDownloadSizeText(viewHolder); } else if (viewHolder.context.getString(R.string.install).equals(status)) { diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index b08fa4e3e8..b0234a3124 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -322,6 +322,7 @@ public class DownloadManager implements DownloadStatusListener { if (VHelper.isSGame(gameEntity)) { ExtensionsKt.addMetaExtra(downloadEntity, Constants.SMOOTH_GAME, "true"); + ExtensionsKt.addMetaExtra(downloadEntity, Constants.EXTRA_DOWNLOAD_TYPE, Constants.SMOOTH_GAME); } HashMap map = PageSwitchDataHelper.popLastPageData(); @@ -628,9 +629,9 @@ public class DownloadManager implements DownloadStatusListener { } /** - * 获取所有下载列表中的任务排除静默更新 + * 获取下载列表中除静默下载、模拟器下载、畅玩下载以外的任务 */ - public List getAllDownloadEntityExcludeSilentUpdate() { + public List getAllDownloadEntityExcludeSilentTask() { List all = getAllDownloadEntity(); return filterSilentDownloadTask(all); } @@ -642,9 +643,10 @@ public class DownloadManager implements DownloadStatusListener { for (DownloadEntity downloadEntity : downloadEntityList) { if (!ExtensionsKt.isSimulatorGame(downloadEntity)) { - if (!Constants.SILENT_UPDATE.equals(ExtensionsKt.getMetaExtra(downloadEntity, Constants.EXTRA_DOWNLOAD_TYPE)) && - !Constants.SIMULATOR_DOWNLOAD.equals(ExtensionsKt.getMetaExtra(downloadEntity, Constants.EXTRA_DOWNLOAD_TYPE))) { - + if (!Constants.SILENT_UPDATE.equals(ExtensionsKt.getMetaExtra(downloadEntity, Constants.EXTRA_DOWNLOAD_TYPE)) + && !Constants.SIMULATOR_DOWNLOAD.equals(ExtensionsKt.getMetaExtra(downloadEntity, Constants.EXTRA_DOWNLOAD_TYPE)) + && !Constants.SMOOTH_GAME.equals(ExtensionsKt.getMetaExtra(downloadEntity, Constants.EXTRA_DOWNLOAD_TYPE)) + ) { filteredDownloadEntityList.add(downloadEntity); } } else { @@ -652,7 +654,6 @@ public class DownloadManager implements DownloadStatusListener { filteredDownloadEntityList.add(downloadEntity); } } - } return filteredDownloadEntityList; @@ -872,7 +873,7 @@ public class DownloadManager implements DownloadStatusListener { public void checkAndRetryDownload() { if (!NetworkUtils.isWifiConnected(mContext)) return; - for (DownloadEntity downloadEntity : DownloadManager.getInstance().getAllDownloadEntityExcludeSilentUpdate()) { + for (DownloadEntity downloadEntity : DownloadManager.getInstance().getAllDownloadEntityExcludeSilentTask()) { if (DownloadStatus.neterror.equals(downloadEntity.getStatus()) || DownloadStatus.timeout.equals(downloadEntity.getStatus()) || DownloadStatus.subscribe.equals(downloadEntity.getStatus())) { @@ -898,7 +899,7 @@ public class DownloadManager implements DownloadStatusListener { boolean showRedPoint = false; int downloadingSize = 0; - for (DownloadEntity downloadEntity : getAllDownloadEntityExcludeSilentUpdate()) { + for (DownloadEntity downloadEntity : getAllDownloadEntityExcludeSilentTask()) { if (DownloadStatus.done.equals(downloadEntity.getStatus())) { String mark = downloadEntity.getMeta().get(DOWNLOADED_IS_READ_MARK); if (TextUtils.isEmpty(mark)) showRedPoint = true; @@ -965,7 +966,7 @@ public class DownloadManager implements DownloadStatusListener { * @return 是否存在未读的下载完成任务 */ public boolean isContainsUnreadDownloadedTask() { - for (DownloadEntity downloadEntity : getAllDownloadEntityExcludeSilentUpdate()) { + for (DownloadEntity downloadEntity : getAllDownloadEntityExcludeSilentTask()) { if (DownloadStatus.done.equals(downloadEntity.getStatus())) { String mark = downloadEntity.getMeta().get(DOWNLOADED_IS_READ_MARK); if (TextUtils.isEmpty(mark)) { @@ -983,7 +984,7 @@ public class DownloadManager implements DownloadStatusListener { AppExecutor.getIoExecutor().execute(() -> { boolean markHasChanged = false; - List all = getAllDownloadEntityExcludeSilentUpdate(); + List all = getAllDownloadEntityExcludeSilentTask(); for (DownloadEntity downloadEntity : all) { DownloadStatus status = downloadEntity.getStatus(); if (status == DownloadStatus.done) { @@ -1023,7 +1024,7 @@ public class DownloadManager implements DownloadStatusListener { AppExecutor.getIoExecutor().execute(() -> { boolean markHasChanged = false; - List all = getAllDownloadEntityExcludeSilentUpdate(); + List all = getAllDownloadEntityExcludeSilentTask(); for (DownloadEntity downloadEntity : all) { if (downloadEntity.getStatus() != DownloadStatus.done) { if (isRead) { diff --git a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java index e804703ad3..4b03c64e78 100644 --- a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java +++ b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java @@ -3,6 +3,7 @@ package com.gh.gamecenter; import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.view.MenuItem; import com.gh.gamecenter.common.base.activity.ToolBarActivity; import com.gh.gamecenter.common.base.fragment.BaseFragment_TabLayout; @@ -26,6 +27,7 @@ public class DownloadManagerActivity extends ToolBarActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); + setToolbarMenu(R.menu.menu_download_manager); } @Override @@ -57,6 +59,12 @@ public class DownloadManagerActivity extends ToolBarActivity { return getTargetIntent(context, DownloadManagerActivity.class, DownloadFragment.class, bundle); } + @Override + public boolean onMenuItemClick(MenuItem item) { + return super.onMenuItemClick(item); + } + + @Override protected void onNightModeChange() { super.onNightModeChange(); diff --git a/app/src/main/java/com/gh/gamecenter/MainActivity.java b/app/src/main/java/com/gh/gamecenter/MainActivity.java index a223df298c..4d04f6e32e 100644 --- a/app/src/main/java/com/gh/gamecenter/MainActivity.java +++ b/app/src/main/java/com/gh/gamecenter/MainActivity.java @@ -701,7 +701,7 @@ public class MainActivity extends BaseActivity { public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0 && !mMainWrapperFragment.onHandleBackPressed()) { DownloadEntity downloadEntity = null; - for (DownloadEntity entity : DownloadManager.getInstance().getAllDownloadEntityExcludeSilentUpdate()) { + for (DownloadEntity entity : DownloadManager.getInstance().getAllDownloadEntityExcludeSilentTask()) { if (entity.getStatus().equals(DownloadStatus.done)) { if (PackageUtils.isInstalled(getApplicationContext(), entity.getPackageName()) && (!entity.isPlugin() diff --git a/app/src/main/java/com/gh/gamecenter/download/DownloadFragment.kt b/app/src/main/java/com/gh/gamecenter/download/DownloadFragment.kt index 6e7d87a6fa..e94e5e0db3 100644 --- a/app/src/main/java/com/gh/gamecenter/download/DownloadFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/download/DownloadFragment.kt @@ -148,7 +148,7 @@ class DownloadFragment : BaseFragment_TabLayout() { private fun updateDownloadHint() { if (!::mDownloadNumberTv.isInitialized || !isAdded) return - val downloadData = DownloadManager.getInstance().allDownloadEntityExcludeSilentUpdate + val downloadData = DownloadManager.getInstance().allDownloadEntityExcludeSilentTask if (downloadData.size > 0) { mDownloadNumberTv.visibility = View.VISIBLE } else { diff --git a/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragment.java b/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragment.java index ac1f1aef3a..f95e7e0fdd 100644 --- a/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragment.java +++ b/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragment.java @@ -169,12 +169,10 @@ public class GameDownloadFragment extends BaseFragment implements View.OnClickLi if (status.equals(DownloadStatus.downloading) || status.equals(DownloadStatus.waiting) || status.equals(DownloadStatus.subscribe)) { - // 静默更新任务不需要添加 - if (ExtensionsKt.isSilentUpdate(downloadEntity)) { - return; - } - //下载模拟器任务不需要添加 - if (ExtensionsKt.isSimulatorDownload(downloadEntity)) { + // 静默更新任务,下载模拟器任务,畅玩游戏不需要添加 + if (ExtensionsKt.isSilentUpdate(downloadEntity) + || ExtensionsKt.isSimulatorDownload(downloadEntity) + || ExtensionsKt.isSmoothGame(downloadEntity)) { return; } diff --git a/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java b/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java index 123dd4d8df..aa53cef2d6 100644 --- a/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java +++ b/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java @@ -47,6 +47,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import androidx.annotation.NonNull; import androidx.collection.ArrayMap; import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.RecyclerView; @@ -57,19 +58,19 @@ import androidx.recyclerview.widget.RecyclerView.ViewHolder; */ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { - private LinearLayout mNoDataSkip; + private final LinearLayout mNoDataSkip; - private List downloadingList; - private List doneList; + private final List mDownloadingList; + private final List mDownloadedList; // 1、此处的所有MAP只是对DownloadManager内部Map的引用, // 2、任何对下载器任务的操作,通过DownloadManager处理,由DownloadManager处理之后抛出对应的状态变化事件 // 3、监听下载任务状态变化,刷新界面 // 4、对状态只读不写。 - private ArrayMap locationMap; - private ArrayMap statusMap; - private ArrayMap urlMap; - private ArrayList deleteList; + private final ArrayMap locationMap; + private final ArrayMap statusMap; + private final ArrayMap urlMap; + private final ArrayList deleteList; private String url; @@ -80,21 +81,19 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { mNoDataSkip = textView; -// statusMap = DownloadManager.getInstance().getStatusMap(); -// downloadingList = new ArrayList<>(DownloadManager.getInstance().getDownloadingMap().values()); - statusMap = new ArrayMap<>(); - downloadingList = new ArrayList<>(); + mDownloadingList = new ArrayList<>(); locationMap = new ArrayMap<>(); urlMap = new ArrayMap<>(); deleteList = new ArrayList<>(); - doneList = new ArrayList<>(); + mDownloadedList = new ArrayList<>(); } + @NonNull @Override - public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { if (viewType == 0) { return new DownloadHeadViewHolder(DownloadmanagerItemHeadBinding.inflate(mLayoutInflater, parent, false)); } else { @@ -103,7 +102,7 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { } @Override - public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) { if (holder instanceof GameDownloadViewHolder) { final GameDownloadViewHolder viewHolder = (GameDownloadViewHolder) holder; @@ -116,12 +115,12 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { viewHolder.binding.dmItemTvSpeed.setTextColor(ContextCompat.getColor(mContext, R.color.text_9a9a9a)); final DownloadEntity downloadEntity; - if (doneList.size() != 0 && position > 0 && position <= doneList.size()) { - downloadEntity = doneList.get(position - 1); - } else if (doneList.isEmpty()) { - downloadEntity = downloadingList.get(position - 1); + if (mDownloadedList.size() != 0 && position > 0 && position <= mDownloadedList.size()) { + downloadEntity = mDownloadedList.get(position - 1); + } else if (mDownloadedList.isEmpty()) { + downloadEntity = mDownloadingList.get(position - 1); } else { - downloadEntity = downloadingList.get(position - doneList.size() - 2); + downloadEntity = mDownloadingList.get(position - mDownloadedList.size() - 2); } String icon = downloadEntity.getIcon(); String rawIcon = ExtensionsKt.getMetaExtra(downloadEntity, Constants.RAW_GAME_ICON); @@ -172,7 +171,7 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { viewHolder.binding.dmItemTvStartorpause.setTextColor(Color.WHITE); if (downloadEntity.isPluggable() - && PackagesManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) { + && PackagesManager.isInstalled(downloadEntity.getPackageName())) { viewHolder.binding.dmItemTvStartorpause.setText("安装"); viewHolder.binding.dmItemTvStartorpause.setBackgroundResource(R.drawable.download_button_pluggable_style); } else { @@ -281,7 +280,8 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { if (isSubscribe) { DownloadManager.getInstance().subscribe(downloadEntity); statusMap.put(url, DownloadStatus.subscribe.getStatus()); - notifyItemChanged(doneList.isEmpty() ? 0 : 1 + doneList.size()); + notifyItemChanged(mDownloadedList.isEmpty() ? 0 : 1 + mDownloadedList + .size()); } else { LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams( 0, LinearLayout.LayoutParams.WRAP_CONTENT); @@ -298,7 +298,8 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { viewHolder.binding.dmItemTvStartorpause.setText("暂停"); viewHolder.binding.dmItemTvStartorpause.setTextColor(ContextCompat.getColor(mContext, R.color.theme_font)); statusMap.put(url, DownloadStatus.downloading.getStatus()); - notifyItemChanged(doneList.isEmpty() ? 0 : 1 + doneList.size()); + notifyItemChanged(mDownloadedList.isEmpty() ? 0 : 1 + mDownloadedList + .size()); Message msg = Message.obtain(); msg.what = DownloadConfig.CONTINUE_DOWNLOAD_TASK; @@ -312,7 +313,7 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { PermissionHelper.checkStoragePermissionBeforeAction(mContext, () -> { final String path = downloadEntity.getPath(); if (downloadEntity.isPluggable() - && PackagesManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) { + && PackagesManager.isInstalled(downloadEntity.getPackageName())) { showPluginDialog(downloadEntity.getPath()); } else { if (FileUtils.isEmptyFile(path)) { @@ -335,7 +336,7 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { viewHolder.binding.dmItemTvDownloads.setText("已暂停"); viewHolder.binding.dmItemIvDelete.setVisibility(View.VISIBLE); statusMap.put(url, DownloadStatus.pause.getStatus()); - notifyItemChanged(doneList.isEmpty() ? 0 : 1 + doneList.size()); + notifyItemChanged(mDownloadedList.isEmpty() ? 0 : 1 + mDownloadedList.size()); Message msg = Message.obtain(); msg.what = DownloadConfig.PAUSE_DOWNLOAD_TASK; msg.obj = url; @@ -398,7 +399,7 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { viewHolder.binding.dmItemHeadTvTask.setTextColor(ContextCompat.getColor(mContext, R.color.text_6c6c6c)); viewHolder.binding.dmItemHeadTvAllstart.setTextColor(ContextCompat.getColor(mContext, R.color.theme_font)); - if (position == 0 && doneList.size() != 0) { + if (position == 0 && mDownloadedList.size() != 0) { viewHolder.binding.dmItemHeadTvTask.setText("已完成"); viewHolder.binding.dmItemHeadTvAllstart.setVisibility(View.GONE); } else { @@ -407,14 +408,14 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { int dlNumber = 0; int wtNumber = 0; - for (DownloadEntity downloadEntity : downloadingList) { + for (DownloadEntity downloadEntity : mDownloadingList) { if (DownloadStatus.downloading.equals(downloadEntity.getStatus())) { dlNumber++; } else if (DownloadStatus.waiting.equals(downloadEntity.getStatus())) { wtNumber++; } } - if ((dlNumber + wtNumber) == downloadingList.size()) { + if ((dlNumber + wtNumber) == mDownloadingList.size()) { viewHolder.binding.dmItemHeadTvAllstart.setText(R.string.download_all_push); viewHolder.binding.dmItemHeadTvAllstart.setTextColor(ContextCompat.getColor(mContext, R.color.btn_gray)); } else { @@ -439,7 +440,7 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { } public void startAll(DownloadHeadViewHolder viewHolder) { - for (DownloadEntity downloadEntity : downloadingList) { + for (DownloadEntity downloadEntity : mDownloadingList) { DownloadManager.getInstance().put(downloadEntity.getUrl(), System.currentTimeMillis()); Message msg = Message.obtain(); @@ -457,7 +458,7 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { } public void pauseAll(DownloadHeadViewHolder viewHolder) { - for (DownloadEntity downloadEntity : downloadingList) { + for (DownloadEntity downloadEntity : mDownloadingList) { DownloadManager.getInstance().put(downloadEntity.getUrl(), System.currentTimeMillis()); Message msg = Message.obtain(); @@ -476,7 +477,7 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { @Override public int getItemViewType(int position) { - if (position == 0 || (doneList.size() > 0 && position == 1 + doneList.size())) { + if (position == 0 || (mDownloadedList.size() > 0 && position == 1 + mDownloadedList.size())) { return 0; } return 1; @@ -484,21 +485,31 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { @Override public int getItemCount() { - if (doneList.isEmpty() && downloadingList.isEmpty()) { + if (mDownloadedList.isEmpty() && mDownloadingList.isEmpty()) { return 0; } - if (doneList.isEmpty()) { - return 1 + downloadingList.size(); + if (mDownloadedList.isEmpty()) { + return 1 + mDownloadingList.size(); } - if (downloadingList.isEmpty()) { - return 1 + doneList.size(); + if (mDownloadingList.isEmpty()) { + return 1 + mDownloadedList.size(); } - return 1 + doneList.size() + 1 + downloadingList.size(); + return 1 + mDownloadedList.size() + 1 + mDownloadingList.size(); } // 显示插件化 void showPluginDialog(final String path) { DialogHelper.showPluginDialog(mContext, () -> { + for (DownloadEntity downloadEntity : DownloadManager.getInstance().getAllDownloadEntityExcludeSilentTask()) { + if (downloadEntity.isPluggable() + && downloadEntity.getPath().equals(path)) { + Map kv6 = new HashMap<>(); + kv6.put("操作", "点击插件化安装完成"); + DataUtils.onEvent(mContext, "插件化", downloadEntity.getName(), kv6); + break; + } + } + if (FileUtils.isEmptyFile(path)) { Utils.toast(mContext, R.string.install_failure_hint); } else { @@ -516,62 +527,62 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { return; } boolean isDone = false; - for (DownloadEntity downloadEntity : doneList) { + for (DownloadEntity downloadEntity : mDownloadedList) { if (entry.getUrl().equals(downloadEntity.getUrl())) { isDone = true; break; } } if (isDone) { - if (downloadingList.isEmpty() && doneList.size() == 1) { - doneList.remove(location.intValue()); + if (mDownloadingList.isEmpty() && mDownloadedList.size() == 1) { + mDownloadedList.remove(location.intValue()); locationMap.clear(); notifyDataSetChanged(); EventBus.getDefault().post(new EBDownloadChanged("download", View.GONE, 0)); if (mNoDataSkip.getVisibility() == View.GONE) { mNoDataSkip.setVisibility(View.VISIBLE); } - } else if (doneList.size() == 1) { - doneList.remove(location.intValue()); + } else if (mDownloadedList.size() == 1) { + mDownloadedList.remove(location.intValue()); initLocationMap(); notifyItemRangeRemoved(0, 2); EventBus.getDefault().post(new EBDownloadChanged("download", View.VISIBLE, - downloadingList.size())); + mDownloadingList.size())); } else { - doneList.remove(location.intValue()); + mDownloadedList.remove(location.intValue()); initLocationMap(); notifyItemRemoved(location + 1); EventBus.getDefault().post(new EBDownloadChanged("download", View.VISIBLE, - downloadingList.size())); + mDownloadingList.size())); } } else { - if (doneList.isEmpty() && downloadingList.size() == 1) { - downloadingList.remove(location.intValue()); + if (mDownloadedList.isEmpty() && mDownloadingList.size() == 1) { + mDownloadingList.remove(location.intValue()); locationMap.clear(); notifyDataSetChanged(); EventBus.getDefault().post(new EBDownloadChanged("download", View.GONE, 0)); if (mNoDataSkip.getVisibility() == View.GONE) { mNoDataSkip.setVisibility(View.VISIBLE); } - } else if (downloadingList.size() == 1) { - downloadingList.remove(location.intValue()); + } else if (mDownloadingList.size() == 1) { + mDownloadingList.remove(location.intValue()); initLocationMap(); notifyItemRangeRemoved(getBase(), 2); EventBus.getDefault().post(new EBDownloadChanged("download", View.VISIBLE, - downloadingList.size())); + mDownloadingList.size())); } else { - downloadingList.remove(location.intValue()); + mDownloadingList.remove(location.intValue()); initLocationMap(); notifyDataSetChanged(); EventBus.getDefault().post(new EBDownloadChanged("download", View.VISIBLE, - downloadingList.size())); + mDownloadingList.size())); } } deleteList.add(entry.getUrl()); statusMap.remove(entry.getUrl()); - notifyItemChanged(doneList.isEmpty() ? 0 : 1 + doneList.size()); + notifyItemChanged(mDownloadedList.isEmpty() ? 0 : 1 + mDownloadedList.size()); } // 显示删除提示框 @@ -580,7 +591,7 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { String msg; if (XapkUnzipStatus.UNZIPPING.name().equals(xapkStatus)) { msg = "游戏正在解压安装哦,确定删除?"; - } else if (doneList.size() != 0 && position <= doneList.size()) { + } else if (mDownloadedList.size() != 0 && position <= mDownloadedList.size()) { msg = "游戏还没安装哦,确定删除?"; } else { msg = "游戏还没下载完,确定删除?"; @@ -596,24 +607,24 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { public void initLocationMap() { locationMap.clear(); - for (int i = 0; i < doneList.size(); i++) { - locationMap.put(doneList.get(i).getUrl(), i); + for (int i = 0; i < mDownloadedList.size(); i++) { + locationMap.put(mDownloadedList.get(i).getUrl(), i); } - for (int i = 0; i < downloadingList.size(); i++) { - locationMap.put(downloadingList.get(i).getUrl(), i); + for (int i = 0; i < mDownloadingList.size(); i++) { + locationMap.put(mDownloadingList.get(i).getUrl(), i); } } public int getBase() { - return doneList.isEmpty() ? 0 : 1 + doneList.size(); + return mDownloadedList.isEmpty() ? 0 : 1 + mDownloadedList.size(); } List getDownloadingList() { - return downloadingList; + return mDownloadingList; } List getDoneList() { - return doneList; + return mDownloadedList; } public ArrayMap getLocationMap() { @@ -641,20 +652,20 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { } void initMap() { - downloadingList.clear(); - doneList.clear(); + mDownloadingList.clear(); + mDownloadedList.clear(); statusMap.clear(); urlMap.clear(); - for (DownloadEntity downloadEntity : DownloadManager.getInstance().getAllDownloadEntityExcludeSilentUpdate()) { + for (DownloadEntity downloadEntity : DownloadManager.getInstance().getAllDownloadEntityExcludeSilentTask()) { statusMap.put(downloadEntity.getUrl(), downloadEntity.getStatus().name()); if (DownloadStatus.done.equals(downloadEntity.getStatus())) { if (!ExtensionsKt.isSimulatorGame(downloadEntity)) { urlMap.put(PackageUtils.getPackageNameByPath(mContext, downloadEntity.getPath()), downloadEntity.getUrl()); - doneList.add(downloadEntity); + mDownloadedList.add(downloadEntity); } } else { - downloadingList.add(downloadEntity); + mDownloadingList.add(downloadEntity); } } // 排序 @@ -667,7 +678,7 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { return 0; } }; - Collections.sort(downloadingList, comparator); + Collections.sort(mDownloadingList, comparator); comparator = (lhs, rhs) -> { if (rhs.getEnd() > lhs.getEnd()) { @@ -678,7 +689,7 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { return 0; } }; - Collections.sort(doneList, comparator); + Collections.sort(mDownloadedList, comparator); initLocationMap(); } diff --git a/app/src/main/java/com/gh/gamecenter/entity/ApkEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/ApkEntity.kt index 1c8db5a4e4..b599df9036 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/ApkEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/ApkEntity.kt @@ -25,6 +25,7 @@ data class ApkEntity(@SerializedName("package") var apkLink: ApkLink? = null, var plugin: String? = "",/*控制是否显示插件化 默认:open,取值有:open/only_index/only_game/close*/ var time: Long? = null, + var md5: String? = null, // 包体的 MD5 用于内型为畅玩的游戏使用用来更新 @SerializedName("platform_name") private var platformName: String = "", val remark: String = "", diff --git a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt index 61ca65d860..8fd07c9c0b 100644 --- a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt +++ b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt @@ -28,6 +28,7 @@ import io.reactivex.schedulers.Schedulers import org.json.JSONException import org.json.JSONObject import java.util.* +import kotlin.collections.ArrayList /** * 该类存储的是已安装的所有游戏(助手后台已收录的)和所有更新(包括插件化)数据 @@ -343,7 +344,7 @@ object PackageRepository { * 新增已安装的游戏 * @param pkgName 已安装的游戏包名 */ - fun installedGame(pkgName: String) { + fun addInstalledGame(pkgName: String) { mInstalledPkgList.add(pkgName) notifyInstallPkgData() @@ -354,11 +355,24 @@ object PackageRepository { } } + /** + * 批量新增已安装的游戏数量 + * @param pkgNameList 数组列表 + */ + fun addInstalledGames(pkgNameList: ArrayList) { + mInstalledPkgList.addAll(pkgNameList) + notifyInstallPkgData() + + updateFilterPackage(pkgNameList) { + loadInstalledGameDigestAndNotifyData(pkgNameList, true) + } + } + /** * 新增卸载游戏 * @param pkgName 已安装的游戏包名 */ - fun uninstalledGame(pkgName: String) { + fun addUninstalledGame(pkgName: String) { // TODO 检查为什么会有两个相同的包名添加到 mInstalledPkgList 里 mInstalledPkgList.removeAll { it == pkgName } // 尝试从临时的当前版本列表里移除已卸载的条目 diff --git a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageViewModel.kt b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageViewModel.kt index 8acf514491..fa72d37602 100644 --- a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageViewModel.kt @@ -65,7 +65,7 @@ class PackageViewModel(application: Application, * 只在收到安装广播时调用,不建议手动调用 */ fun addInstalledGame(pkgName: String?) { - if (!TextUtils.isEmpty(pkgName)) mRepository.installedGame(pkgName!!) + if (!TextUtils.isEmpty(pkgName)) mRepository.addInstalledGame(pkgName!!) } /** @@ -73,7 +73,7 @@ class PackageViewModel(application: Application, * 只在收到卸载广播时调用,不建议手动调用 */ fun addUninstalledGame(pkgName: String?) { - if (!TextUtils.isEmpty(pkgName)) mRepository.uninstalledGame(pkgName!!) + if (!TextUtils.isEmpty(pkgName)) mRepository.addUninstalledGame(pkgName!!) } /** diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt new file mode 100644 index 0000000000..603f350732 --- /dev/null +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt @@ -0,0 +1,19 @@ +package com.gh.vspace + +import android.os.Bundle +import com.gh.base.BaseActivity +import com.gh.gamecenter.R + +class VDownloadManagerActivity: BaseActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + if (savedInstanceState == null) { + supportFragmentManager.beginTransaction().replace(R.id.placeholder, VDownloadManagerFragment()).commitAllowingStateLoss() + } + } + + override fun getLayoutId() = R.layout.activity_shell + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt new file mode 100644 index 0000000000..73e5353a0c --- /dev/null +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -0,0 +1,23 @@ +package com.gh.vspace + +import android.content.Context +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.gh.gamecenter.baselist.ListAdapter +import com.gh.gamecenter.entity.GameEntity + +class VDownloadManagerAdapter(context: Context) : ListAdapter(context) { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + TODO("Not yet implemented") + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + TODO("Not yet implemented") + } + + override fun getItemCount(): Int { + TODO("Not yet implemented") + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt new file mode 100644 index 0000000000..9769590ae4 --- /dev/null +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -0,0 +1,13 @@ +package com.gh.vspace + +import com.gh.gamecenter.baselist.ListAdapter +import com.gh.gamecenter.baselist.ListFragment +import com.gh.gamecenter.entity.GameEntity + +class VDownloadManagerFragment: ListFragment() { + + private val mAdapter by lazy { VDownloadManagerAdapter(requireContext()) } + + override fun provideListAdapter(): ListAdapter<*> = mAdapter + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt new file mode 100644 index 0000000000..75ae89f950 --- /dev/null +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -0,0 +1,19 @@ +package com.gh.vspace + +import android.app.Application +import com.gh.gamecenter.baselist.ListViewModel +import com.gh.gamecenter.entity.GameEntity +import io.reactivex.Observable + +class VDownloadManagerViewModel(application: Application) + : ListViewModel(application) { + + override fun mergeResultLiveData() { + TODO("Not yet implemented") + } + + override fun provideDataObservable(page: Int): Observable> { + TODO("Not yet implemented") + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 17452dc39a..833bf0ae61 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -7,7 +7,9 @@ import android.content.Intent import com.gh.common.AppExecutor import com.gh.common.util.EmptyCallback import com.gh.common.util.PackageUtils +import com.gh.download.PackageObserver import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.eventbus.EBPackage import com.gh.gamecenter.packagehelper.PackageRepository import com.lg.vspace.VirtualAppManager import com.lg.vspace.remote.listener.RemoteConnectListener @@ -36,6 +38,7 @@ object VHelper { override fun onServiceConnectionSuccessed() { Utils.log(LOG_TAG, "V 服务连接成功") mInstalledInfoList = getInstalledList() + PackageRepository.addInstalledGames(getInstalledPackageList()) } override fun onServiceConnectionFailed(failCode: Int) { @@ -59,7 +62,7 @@ object VHelper { */ @JvmStatic fun isSGame(gameEntity: GameEntity?): Boolean { - return gameEntity?.downloadStatus == "smooth" + return gameEntity?.downloadStatus != "smooth" } /** @@ -105,14 +108,14 @@ object VHelper { * 获取已安装的包名列表 */ fun getInstalledPackageList(): ArrayList { - val installedList = getInstalledList() + val installedList = mInstalledInfoList val installedPackageList = arrayListOf() for (info in installedList) { installedPackageList.add(info.packageName) } - Utils.log(LOG_TAG, "获取已安装包名列表数量${installedPackageList.size}") + Utils.log(LOG_TAG, "已安装包名列表$installedPackageList") return installedPackageList } @@ -122,7 +125,7 @@ object VHelper { */ fun getInstalledList(): ArrayList { val list = mDelegateManager.installedGamesInfo - Utils.log(LOG_TAG, "获取已安装列表数量${list.size}") + Utils.log(LOG_TAG, "已安装应用数量${list.size}") return ArrayList(mDelegateManager.installedGamesInfo) } @@ -162,6 +165,7 @@ object VHelper { val result = VirtualAppManager.get().installGame(filePath) if (result.status == 0) { updateInstalledList() + PackageObserver.onPackageChanged(EBPackage("安装", result.packageName, "unknown")) } Utils.log(LOG_TAG, "安装新应用结果 -> " + result.status) } @@ -173,18 +177,21 @@ object VHelper { */ @JvmStatic fun launch(activity: Activity, packageName: String) { + Utils.log(LOG_TAG, "打开应用$packageName") + val intent = mDelegateManager.getStartGameIntent(packageName) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) activity.startActivity(intent) } /** - * 卸载已有应用 + * 卸载应用 */ fun uninstall(packageName: String) { val result = VirtualAppManager.get().uninstallGame(packageName) if (result) { updateInstalledList() + PackageObserver.onPackageChanged(EBPackage("卸载", packageName, "unknown")) } Utils.log(LOG_TAG, "安装新应用结果 -> $result") } diff --git a/app/src/main/java/com/halo/assistant/HaloApp.java b/app/src/main/java/com/halo/assistant/HaloApp.java index 8f69479444..22bfe9e74d 100644 --- a/app/src/main/java/com/halo/assistant/HaloApp.java +++ b/app/src/main/java/com/halo/assistant/HaloApp.java @@ -271,13 +271,14 @@ public class HaloApp extends MultiDexApplication implements Configuration.Provid AppExecutor.getUiExecutor().executeWithDelay(() -> { initThirdPartySdk(); - retrieveVGameInfoIfNeeded(); - FixedRateJobHelper.begin(); RegionSettingHelper.getRegionSetting(); - - ExtensionsKt.doOnMainProcessOnly(this, PackageRepository::initData); + + ExtensionsKt.doOnMainProcessOnly(this, () -> { + retrieveVGameInfoIfNeeded(); + PackageRepository.initData(); + }); checkIfDeviceIsEmulator(); diff --git a/app/src/main/res/drawable-xxxhdpi/ic_smooth_manager.png b/app/src/main/res/drawable-xxxhdpi/ic_smooth_manager.png new file mode 100644 index 0000000000000000000000000000000000000000..89bf5f1f62dc00f12cb7240c74bc2d59bf53f2a5 GIT binary patch literal 1375 zcmV-l1)%zgP)@~0drDELIAGL9O(c600d`2O+f$vv5yP{2Ol6F zIX6^Cj$OCvmdg$(%8?LYm#ga3eP5gCH^-cI;O_43#^dAT;oRI@hn@*oe>y)ue|d9r z(;E(lQ_V9i&7hr~ofN+=K#rahSbq&9)1{@QHvWC3d1hWS2ot}fmxcD$*4Bn*pqC(| z$ETIh3jpNwC#wN%og%Pp~SMmzO2a zot>VZ4oL~04O$7}WIt1bFw#rOzILAi;3T-PuwZpC@L*$V5K#Y)bPszPQvjRbqIvX8F~Rfi^IlezAc*{9yAJ#NL=6E|LP~LH;~*}$w3}TJ z34(|e0~?bdPJfN+!GE(qtOU7&;M&V_YYOojSqZs3JIC&OE)P!JSn3)BCvrt{otow2 zWl4h1SwUz3a-8LeML4wYbv|B}Bv@Ak!3Tu{*}!Qg_;+%0auQuT8gfUDA-&=rZ7LdF zL2$rEOdC-y<-+DNt^`6#ox+^FuOr8hJ`QnEyjW7vIx2`FIfI0QFsk$mljo{o4(y|2 z$R)@f*>02w##Ru%E}ZFWj!aUmf^c9nWGgExo6@tkFp<~>YAXmwo8hN5w9@n(SjJ9e zFc^p-Mb-EI+$4w%ZG=#Q#{LVJtH?N$IU!MFUllw;_LKu;y*%!u>sCV zy7}=TIcyba=BxA&)b>VmdwaWsO^+cnWPy)nbFDNp)qpRf?5G zu*$)S9Ae{LMeKFjvkj`REPUWJ%Jv0@uSsP*Be(bxdLmZ2-4X3%v~Qtcr-$%>Txod8&5{Wevae!$ zInfgIy@fIf0NYtxGasuX=G?676?rs4DZs002ovPDHLkV1jMBbD97E literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/layout_menu_download_manager.xml b/app/src/main/res/layout/layout_menu_download_manager.xml new file mode 100644 index 0000000000..20b0184492 --- /dev/null +++ b/app/src/main/res/layout/layout_menu_download_manager.xml @@ -0,0 +1,31 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_download_manager.xml b/app/src/main/res/menu/menu_download_manager.xml new file mode 100644 index 0000000000..4d88b08cfb --- /dev/null +++ b/app/src/main/res/menu/menu_download_manager.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt b/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt index c26d08c247..62bbeae0b7 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt @@ -973,6 +973,10 @@ fun DownloadEntity.isSimulatorGame(): Boolean { return getMetaExtra(Constants.SIMULATOR_GAME).isNotEmpty() } +fun DownloadEntity.isSmoothGame(): Boolean { + return Constants.SMOOTH_GAME == getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) +} + /** * Process related */ From 3ef9a38342afdc30b98454325edcdb2d5d42db3a Mon Sep 17 00:00:00 2001 From: leafwai Date: Wed, 20 Apr 2022 14:54:51 +0800 Subject: [PATCH 006/217] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B8=B8=E6=88=8F?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E5=AE=8C=E6=88=90=E6=8F=90=E9=86=92=E6=B5=AE?= =?UTF-8?q?=E7=AA=97=E5=B7=A5=E5=85=B7=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/vspace/LoadCompleteWindowHelper.kt | 263 ++++++++++++++++++ .../ic_float_load_complete.webp | Bin 0 -> 376 bytes .../ic_float_load_complete_close.webp | Bin 0 -> 198 bytes .../res/drawable/bg_float_load_complete.xml | 5 + .../layout/item_float_game_load_complete.xml | 42 +++ .../res/layout/layout_float_load_complete.xml | 46 +++ 6 files changed, 356 insertions(+) create mode 100644 app/src/main/java/com/gh/vspace/LoadCompleteWindowHelper.kt create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_float_load_complete.webp create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_float_load_complete_close.webp create mode 100644 app/src/main/res/drawable/bg_float_load_complete.xml create mode 100644 app/src/main/res/layout/item_float_game_load_complete.xml create mode 100644 app/src/main/res/layout/layout_float_load_complete.xml diff --git a/app/src/main/java/com/gh/vspace/LoadCompleteWindowHelper.kt b/app/src/main/java/com/gh/vspace/LoadCompleteWindowHelper.kt new file mode 100644 index 0000000000..898efae85a --- /dev/null +++ b/app/src/main/java/com/gh/vspace/LoadCompleteWindowHelper.kt @@ -0,0 +1,263 @@ +package com.gh.vspace + +import android.animation.* +import android.app.Activity +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.view.WindowManager +import android.view.animation.AccelerateDecelerateInterpolator +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.get +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import androidx.viewpager2.widget.ViewPager2 +import com.gh.common.util.ClickUtils +import com.gh.common.util.dip2px +import com.gh.common.util.doOnEnd +import com.gh.common.util.toBinding +import com.gh.gamecenter.R +import com.gh.gamecenter.databinding.ItemFloatGameLoadCompleteBinding +import com.gh.gamecenter.databinding.LayoutFloatLoadCompleteBinding +import com.gh.gamecenter.entity.GameEntity +import com.lightgame.adapter.BaseRecyclerAdapter +import com.lzf.easyfloat.EasyFloat +import com.lzf.easyfloat.enums.SidePattern +import com.lzf.easyfloat.interfaces.OnFloatAnimator +import java.lang.ref.WeakReference + +object LoadCompleteWindowHelper { + private const val LOAD_COMPLETE_WINDOW = "load_complete_window" + private const val LOOP_TIME = 2000L + private const val LOOP_DURATION = 200L + private const val AUTO_DISMISS_TIME = 3000L + + private val mDismissTask = Runnable { EasyFloat.dismiss(LOAD_COMPLETE_WINDOW) } + + fun showFloatingWindow(activity: Activity, gameEntity: GameEntity) = showFloatingWindow(activity, listOf(gameEntity)) + + fun showFloatingWindow(activity: Activity, gameEntityList: List = emptyList()) { + val floatingView = EasyFloat.getFloatView(LOAD_COMPLETE_WINDOW) + if (floatingView != null) { + if (!EasyFloat.isShow(LOAD_COMPLETE_WINDOW)) EasyFloat.show(LOAD_COMPLETE_WINDOW) + floatingView.findViewById(R.id.container)?.let { + val binding = LayoutFloatLoadCompleteBinding.bind(it) + binding.viewPager.run { + val adapter = adapter + var isLastItem = false + if (adapter is GameLoadCompleteAdapter) { + if (currentItem == adapter.gameEntityList.size - 1) isLastItem = true + adapter.submitList(gameEntityList) + } + removeCallbacks(mDismissTask) + if (isLastItem) { + val mLoopTask = object : Runnable { + private val reference: WeakReference = WeakReference(binding.viewPager) + + override fun run() { + val vp: ViewPager2? = reference.get() + if (vp != null) { + val count = binding.viewPager.adapter?.itemCount ?: 0 + if (count == 0) return + val next = vp.currentItem + 1 + if (next < count) { + vp.setCurrentItem(next, LOOP_DURATION) + vp.postDelayed(this, LOOP_TIME) + } else { + vp.postDelayed(mDismissTask, AUTO_DISMISS_TIME) + } + } + } + } + post(mLoopTask) + } + } + } + return + } + + EasyFloat.with(activity) + .setLayout(R.layout.layout_float_load_complete) + .setTag(LOAD_COMPLETE_WINDOW) + .setDragEnable(false) + .setMatchParent(widthMatch = true, heightMatch = false) + .setGravity(Gravity.BOTTOM, 0, (-70F).dip2px()) + .setAnimator(LoadCompleteFloatAnimator()) + .registerCallback { + createResult { _, _, view -> + view?.findViewById(R.id.container)?.let { + initFloatingView(it, activity, gameEntityList) + } + } + } + .show() + } + + private fun initFloatingView(view: ConstraintLayout, activity: Activity, entityList: List) { + val mBinding = LayoutFloatLoadCompleteBinding.bind(view) + val mAdapter = GameLoadCompleteAdapter(activity, entityList) + val mLoopTask = object : Runnable { + private val reference: WeakReference = WeakReference(mBinding.viewPager) + + override fun run() { + val vp: ViewPager2? = reference.get() + if (vp != null) { + val count = mBinding.viewPager.adapter?.itemCount ?: 0 + if (count == 0) return + val next = vp.currentItem + 1 + if (next < count) { + vp.setCurrentItem(next, LOOP_DURATION) + vp.postDelayed(this, LOOP_TIME) + } else { + vp.postDelayed(mDismissTask, AUTO_DISMISS_TIME) + } + } + } + } + mBinding.viewPager.run { + adapter = mAdapter + isUserInputEnabled = false + orientation = ViewPager2.ORIENTATION_VERTICAL + offscreenPageLimit = entityList.size + registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { + override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { + super.onPageScrolled(position, positionOffset, positionOffsetPixels) + val layoutManager = (get(0) as RecyclerView).layoutManager as LinearLayoutManager + layoutManager.findViewByPosition(position)?.alpha = 1 - positionOffset + layoutManager.findViewByPosition(position + 1)?.alpha = positionOffset + } + }) + if (entityList.size > 1) { + postDelayed(mLoopTask, LOOP_TIME) + } else { + postDelayed(mDismissTask, AUTO_DISMISS_TIME) + } + } + mBinding.closeIv.setOnClickListener { + if (!ClickUtils.isFastDoubleClick(it.id)) { + mBinding.viewPager.removeCallbacks(mLoopTask) + mBinding.viewPager.removeCallbacks(mDismissTask) + EasyFloat.dismiss(LOAD_COMPLETE_WINDOW) + } + } + mBinding.launchTv.setOnClickListener { + VHelper.launch(activity, mAdapter.gameEntityList[mBinding.viewPager.currentItem].getApk()[0].packageName) + } + } +} + +class LoadCompleteFloatAnimator : OnFloatAnimator { + override fun enterAnim( + view: View, + params: WindowManager.LayoutParams, + windowManager: WindowManager, + sidePattern: SidePattern + ): Animator = getEnterAnimator(view) + + override fun exitAnim( + view: View, + params: WindowManager.LayoutParams, + windowManager: WindowManager, + sidePattern: SidePattern + ): Animator = getExitAnimator(view) + + private fun getEnterAnimator(view: View): Animator { + val alphaAnimator = ObjectAnimator.ofFloat(view, "alpha", 0F, 1F).apply { + duration = DURATION + interpolator = AccelerateDecelerateInterpolator() + } + val scaleXAnimator = ObjectAnimator.ofFloat(view, "scaleX", 0.8F, 1F).apply { + duration = DURATION + interpolator = AccelerateDecelerateInterpolator() + } + val scaleYAnimator = ObjectAnimator.ofFloat(view, "scaleY", 0.8F, 1F).apply { + duration = DURATION + interpolator = AccelerateDecelerateInterpolator() + } + view.pivotX = view.width / 2F + view.pivotY = view.height / 2F + return AnimatorSet().apply { playTogether(alphaAnimator, scaleXAnimator, scaleYAnimator) } + } + + private fun getExitAnimator(view: View): Animator { + val alphaAnimator = ObjectAnimator.ofFloat(view, "alpha", 1F, 0F).apply { + duration = DURATION + interpolator = AccelerateDecelerateInterpolator() + } + val scaleXAnimator = ObjectAnimator.ofFloat(view, "scaleX", 1F, 0.8F).apply { + duration = DURATION + interpolator = AccelerateDecelerateInterpolator() + } + val scaleYAnimator = ObjectAnimator.ofFloat(view, "scaleY", 1F, 0.8F).apply { + duration = DURATION + interpolator = AccelerateDecelerateInterpolator() + } + view.pivotX = view.width / 2F + view.pivotY = view.height / 2F + return AnimatorSet().apply { + playTogether(alphaAnimator, scaleXAnimator, scaleYAnimator) + doOnEnd { + view.visibility = View.GONE + } + } + } + + companion object { + const val DURATION = 200L + } +} + +class GameLoadCompleteAdapter(context: Context, var gameEntityList: List = emptyList()): BaseRecyclerAdapter(context) { + + fun submitList(entityList: List) { + if (entityList.isNotEmpty()) { + gameEntityList = arrayListOf().apply { + addAll(gameEntityList) + addAll(entityList) + } + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = GameLoadCompleteViewHolder(parent.toBinding()) + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + if (holder is GameLoadCompleteViewHolder) { + val gameEntity = gameEntityList[position] + holder.binding.gameIconIv.displayGameIcon(gameEntity) + holder.binding.gameNameTv.text = gameEntity.name + } + } + + override fun getItemCount() = gameEntityList.size + + class GameLoadCompleteViewHolder(val binding: ItemFloatGameLoadCompleteBinding): RecyclerView.ViewHolder(binding.root) + +} + +private fun ViewPager2.setCurrentItem( + item: Int, + duration: Long, + interpolator: TimeInterpolator = AccelerateDecelerateInterpolator(), + pagePxHeight: Int = height +) { + val pxToDrag: Int = pagePxHeight * (item - currentItem) + val animator = ValueAnimator.ofInt(0, pxToDrag) + var previousValue = 0 + animator.addUpdateListener { valueAnimator -> + val currentValue = valueAnimator.animatedValue as Int + val currentPxToDrag = (currentValue - previousValue).toFloat() + fakeDragBy(-currentPxToDrag) + previousValue = currentValue + } + animator.addListener(object : Animator.AnimatorListener { + override fun onAnimationStart(animation: Animator?) { beginFakeDrag() } + override fun onAnimationEnd(animation: Animator?) { endFakeDrag() } + override fun onAnimationCancel(animation: Animator?) { } + override fun onAnimationRepeat(animation: Animator?) { } + }) + animator.interpolator = interpolator + animator.duration = duration + animator.start() +} \ No newline at end of file diff --git a/app/src/main/res/drawable-xxxhdpi/ic_float_load_complete.webp b/app/src/main/res/drawable-xxxhdpi/ic_float_load_complete.webp new file mode 100644 index 0000000000000000000000000000000000000000..cb6cc0891e51cfcda9e5037ca1d5f2acad755700 GIT binary patch literal 376 zcmV-;0f+ulNk&F+0RRA3MM6+kP&iCv0RR9mC%_31$6z3BoA@`q?Kd(1^RKpT8#V_! zRT{^+c<^2t0!vL z`vU*~0000*vz!-s9ZO#T0000`U$XupNs=VVbIzSl6G@Wx2iHSuv=9v{$>6K+VHC|) z(vKsv%0Z@J)wSuB6`6`QV1A~TJ7_bL50XE9ck&;|-ur(_4 + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_float_game_load_complete.xml b/app/src/main/res/layout/item_float_game_load_complete.xml new file mode 100644 index 0000000000..5f44e00757 --- /dev/null +++ b/app/src/main/res/layout/item_float_game_load_complete.xml @@ -0,0 +1,42 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_float_load_complete.xml b/app/src/main/res/layout/layout_float_load_complete.xml new file mode 100644 index 0000000000..9f24e539f7 --- /dev/null +++ b/app/src/main/res/layout/layout_float_load_complete.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + \ No newline at end of file From 9d00e53b73ea5baff07061298bd3f744f253d84d Mon Sep 17 00:00:00 2001 From: juntao Date: Fri, 22 Apr 2022 16:52:04 +0800 Subject: [PATCH 007/217] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=95=85=E7=8E=A9?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 3 + .../gh/common/databind/BindingAdapters.java | 2 +- .../gh/common/util/DetailDownloadUtils.java | 4 +- .../java/com/gh/common/util/DirectUtils.kt | 6 + .../com/gh/common/util/DownloadItemUtils.kt | 11 +- .../java/com/gh/download/DownloadManager.java | 19 +- .../gamecenter/DownloadManagerActivity.java | 3 +- .../adapter/viewholder/DetailViewHolder.java | 2 +- .../com/gh/gamecenter/entity/GameInstall.kt | 3 + .../packagehelper/PackageRepository.kt | 25 +- .../gamecenter/personal/PersonalFragment.kt | 2 +- .../com/gh/vspace/VDownloadManagerActivity.kt | 6 +- .../com/gh/vspace/VDownloadManagerAdapter.kt | 262 +++++++++++++++++- .../com/gh/vspace/VDownloadManagerFragment.kt | 105 ++++++- .../gh/vspace/VDownloadManagerViewModel.kt | 68 ++++- app/src/main/java/com/gh/vspace/VHelper.kt | 3 +- .../res/layout/activity_vdownload_manager.xml | 16 ++ app/src/main/res/values/strings.xml | 2 + 18 files changed, 507 insertions(+), 35 deletions(-) create mode 100644 app/src/main/res/layout/activity_vdownload_manager.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 74faeb16ad..9d85ffe3cc 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -732,6 +732,9 @@ android:name="com.gh.gamecenter.toolbox.ToolBoxBlockActivity" android:screenOrientation="portrait" /> + + diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java index 2904df851c..5e451a812e 100644 --- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java +++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java @@ -427,7 +427,7 @@ public class BindingAdapters { return; } - if (VHelper.isSGame(gameEntity)) { + if (VHelper.isVGame(gameEntity)) { VHelper.launch((AppCompatActivity) v.getContext(), gameEntity.getApk().get(0).getPackageName()); return; } diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index 319dc5600b..a497ff04f1 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -102,7 +102,7 @@ public class DetailDownloadUtils { } else if (viewHolder.context.getString(R.string.pluggable).equals(status)) { downloadText = "升级" + (TextUtils.isEmpty(downloadAddWord) ? "" : "至" + downloadAddWord) + getDownloadSizeText(viewHolder); } else if (viewHolder.context.getString(R.string.launch).equals(status)) { - if (VHelper.isSGame(viewHolder.gameEntity)) { + if (VHelper.isVGame(viewHolder.gameEntity)) { downloadText = viewHolder.context.getString(R.string.smooth_launch); } else { downloadText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : "-" + downloadAddWord); @@ -186,7 +186,7 @@ public class DetailDownloadUtils { } viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL); } - } else if (VHelper.isSGame(viewHolder.gameEntity)) { + } else if (VHelper.isVGame(viewHolder.gameEntity)) { viewHolder.mDownloadPb.setText(R.string.smooth_launch); viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.LAUNCH_OR_OPEN); } else { diff --git a/app/src/main/java/com/gh/common/util/DirectUtils.kt b/app/src/main/java/com/gh/common/util/DirectUtils.kt index a64044aa6b..0e260b928c 100644 --- a/app/src/main/java/com/gh/common/util/DirectUtils.kt +++ b/app/src/main/java/com/gh/common/util/DirectUtils.kt @@ -71,6 +71,7 @@ import com.gh.gamecenter.video.detail.VideoDetailActivity import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel import com.gh.gamecenter.video.game.GameVideoActivity import com.gh.gamecenter.video.videomanager.VideoManagerActivity +import com.gh.vspace.VDownloadManagerActivity import com.halo.assistant.HaloApp import com.halo.assistant.fragment.WebFragment import com.lightgame.utils.Utils @@ -1761,6 +1762,11 @@ object DirectUtils { } } + @JvmStatic + fun directToVGameDownload(context: Context) { + context.startActivity(Intent(context, VDownloadManagerActivity::class.java)) + } + @JvmStatic fun directToSuggestion(context: Context, type: SuggestType) { directToSuggestion(context = context, type = type, requestCode = null) diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index b5bf14e78b..5eac0c5f2b 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -141,8 +141,11 @@ object DownloadItemUtils { @JvmStatic @JvmOverloads fun updateItem( - context: Context, gameEntity: GameEntity, holder: GameViewHolder, - isShowPlatform: Boolean, pluginLocation: PluginLocation? = PluginLocation.only_game, + context: Context, + gameEntity: GameEntity, + holder: GameViewHolder, + isShowPlatform: Boolean, + pluginLocation: PluginLocation? = PluginLocation.only_game, hideDownloadBtnIfNoAvailableContent: Boolean = false, briefStyle: String? = null, isShowRecommendStar: Boolean = false @@ -272,7 +275,7 @@ object DownloadItemUtils { } // 更新正常的条目,只有一个apk包 - private fun updateNormalItem( + fun updateNormalItem( context: Context, holder: GameViewHolder, gameEntity: GameEntity, isShowPlatform: Boolean, briefStyle: String?, isShowRecommendStar: Boolean = false @@ -753,7 +756,7 @@ object DownloadItemUtils { return } - if (VHelper.isSGame(gameEntity)) { + if (VHelper.isVGame(gameEntity)) { VHelper.launch((context as AppCompatActivity), gameEntity.getApk()[0].packageName) return } diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index b0234a3124..8ee62f9746 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -320,7 +320,7 @@ public class DownloadManager implements DownloadStatusListener { ExtensionsKt.addMetaExtra(downloadEntity, Constants.SIMULATOR, GsonUtils.toJson(gameEntity.getSimulator())); } - if (VHelper.isSGame(gameEntity)) { + if (VHelper.isVGame(gameEntity)) { ExtensionsKt.addMetaExtra(downloadEntity, Constants.SMOOTH_GAME, "true"); ExtensionsKt.addMetaExtra(downloadEntity, Constants.EXTRA_DOWNLOAD_TYPE, Constants.SMOOTH_GAME); } @@ -636,6 +636,23 @@ public class DownloadManager implements DownloadStatusListener { return filterSilentDownloadTask(all); } + /** + * 获取下载列表中的畅玩下载任务 + */ + public List getAllSmoothDownloadTask() { + List downloadList = getAllDownloadEntity(); + + ArrayList filteredDownloadEntityList = new ArrayList<>(); + + for (DownloadEntity downloadEntity : downloadList) { + if (Constants.SMOOTH_GAME.equals(ExtensionsKt.getMetaExtra(downloadEntity, Constants.EXTRA_DOWNLOAD_TYPE))) { + filteredDownloadEntityList.add(downloadEntity); + } + } + + return filteredDownloadEntityList; + } + private ArrayList filterSilentDownloadTask(List downloadEntityList) { ArrayList filteredDownloadEntityList = new ArrayList<>(); diff --git a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java index 4b03c64e78..460320c555 100644 --- a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java +++ b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java @@ -61,7 +61,8 @@ public class DownloadManagerActivity extends ToolBarActivity { @Override public boolean onMenuItemClick(MenuItem item) { - return super.onMenuItemClick(item); + DirectUtils.directToVGameDownload(this); + return true; } diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java index facb87f3a1..4442384116 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java @@ -237,7 +237,7 @@ public class DetailViewHolder { return; } - if (VHelper.isSGame(mGameEntity)) { + if (VHelper.isVGame(mGameEntity)) { VHelper.launch((AppCompatActivity) mViewHolder.context, mGameEntity.getApk().get(0).getPackageName()); return; } diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt b/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt index b7ba454688..571baf54d8 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt @@ -1,6 +1,7 @@ package com.gh.gamecenter.entity import com.gh.common.util.PackageUtils +import com.gh.vspace.VHelper import com.google.gson.annotations.SerializedName import com.halo.assistant.HaloApp @@ -14,6 +15,7 @@ data class GameInstall( var isSignByGh: Boolean = false, var installTime: Long = 0, var version: String = "", + var isSmoothGame: Boolean = false, // 是否是畅玩游戏 var tag: Any? = null) { companion object { @@ -28,6 +30,7 @@ data class GameInstall( gameInstall.iconSubScript = game.iconSubscript gameInstall.version = PackageUtils.getVersionNameByPackageName(installedPkgName) ?: "unknown" gameInstall.packageName = installedPkgName + gameInstall.isSmoothGame = VHelper.isVGame(game) return gameInstall } } diff --git a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt index 8fd07c9c0b..3de5380269 100644 --- a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt +++ b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt @@ -21,6 +21,7 @@ import com.gh.gamecenter.common.retrofit.BiResponse import com.gh.gamecenter.common.retrofit.ObservableUtil import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.retrofit.RetrofitManager +import com.gh.vspace.VHelper import com.halo.assistant.HaloApp import com.lightgame.utils.Utils import io.reactivex.android.schedulers.AndroidSchedulers @@ -28,7 +29,6 @@ import io.reactivex.schedulers.Schedulers import org.json.JSONException import org.json.JSONObject import java.util.* -import kotlin.collections.ArrayList /** * 该类存储的是已安装的所有游戏(助手后台已收录的)和所有更新(包括插件化)数据 @@ -54,6 +54,9 @@ object PackageRepository { val gameUpdateLiveData = MutableLiveData>() val gameInstalledLiveData = MutableLiveData>() + val installedGameListLiveData = MutableLiveData>() // 已安装的游戏列表 (信息比 GameInstall 更全) + + private val mInstalledGameList = Collections.synchronizedList(ArrayList()) val gameInstalled = Collections.synchronizedList(ArrayList()) val gameUpdate = ArrayList() @@ -66,6 +69,7 @@ object PackageRepository { fun initData() { runOnIoThread { if (gameInstalled.isNotEmpty()) gameInstalled.clear() + if (mInstalledGameList.isNotEmpty()) mInstalledGameList.clear() if (gameUpdate.isNotEmpty()) gameUpdate.clear() if (mInstalledPkgList.isNotEmpty()) mInstalledPkgList.clear() @@ -169,11 +173,14 @@ object PackageRepository { * 如果有数据变动会调用[gameUpdateLiveData] [gameInstalledLiveData]实现相关页面刷新 * * @param filteredList 已安装的游戏包名集合 (仅已收录部分) + * @param onWorkerThreadOnly 是否在工作线程执行 + * @param matchSmoothGameOnly 是否仅匹配畅玩游戏 */ @SuppressLint("CheckResult") private fun loadInstalledGameDigestAndNotifyData( filteredList: ArrayList, - onWorkerThreadOnly: Boolean = false + onWorkerThreadOnly: Boolean = false, + matchSmoothGameOnly: Boolean = false, ) { var isNotifyUpdate = false val maxPageCount = (filteredList.size / PAGE_SIZE) + 1 @@ -207,13 +214,16 @@ object PackageRepository { } for (game in validGames) { + // 仅匹配畅玩游戏时,非畅玩游戏直接跳过 + if (matchSmoothGameOnly && !VHelper.isVGame(game)) { + continue + } + if (gh_id == null || gh_id == game.id) { gameInstalled.add( - GameInstall.transformGameInstall( - game, - pkgName - ) + GameInstall.transformGameInstall(game, pkgName) ) + mInstalledGameList.add(game) val isCanPluggable = checkGamePlugin(game, pkgName) val isCanUpdate = checkGameUpdate(game) addCurrentlyInstalledVersionIfValid(game) @@ -402,8 +412,10 @@ object PackageRepository { var i = 0 while (i < gameInstalled.size) { val game = gameInstalled[i] + val gameEntity = mInstalledGameList[i] if (game.packageName == pkgName) { gameInstalled.remove(game) + mInstalledGameList.remove(gameEntity) } else { i++ } @@ -414,6 +426,7 @@ object PackageRepository { private fun notifyGameInstallData() { PackagesManager.initGameInstall(ArrayList(gameInstalled)) gameInstalledLiveData.postValue(ArrayList(gameInstalled)) + installedGameListLiveData.postValue(ArrayList(mInstalledGameList)) } private fun notifyGameUpdateData() { diff --git a/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.kt b/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.kt index a69555868c..b27f514bda 100644 --- a/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.kt @@ -222,7 +222,7 @@ class PersonalFragment : BaseLazyFragment() { .decorView .findViewById(android.R.id.content) .findViewById(BaseActivity.ID_ROOT_INDICATOR) - indicator.setOnClickListener { + indicator?.setOnClickListener { requireContext().startActivity( getIntent(requireContext()) ) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt index 603f350732..4db3f9d99d 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt @@ -1,10 +1,10 @@ package com.gh.vspace import android.os.Bundle -import com.gh.base.BaseActivity +import com.gh.base.ToolBarActivity import com.gh.gamecenter.R -class VDownloadManagerActivity: BaseActivity() { +class VDownloadManagerActivity: ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -14,6 +14,6 @@ class VDownloadManagerActivity: BaseActivity() { } } - override fun getLayoutId() = R.layout.activity_shell + override fun getLayoutId() = R.layout.activity_vdownload_manager } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index 73e5353a0c..16dd35b2ab 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -1,23 +1,273 @@ package com.gh.vspace import android.content.Context +import android.view.Gravity +import android.view.LayoutInflater import android.view.ViewGroup +import android.widget.LinearLayout +import android.widget.PopupWindow +import android.widget.TextView +import androidx.appcompat.app.AppCompatActivity +import androidx.constraintlayout.widget.ConstraintLayout import androidx.recyclerview.widget.RecyclerView +import com.gh.base.CurrentActivityHolder +import com.gh.common.constant.Constants +import com.gh.common.constant.ItemViewType +import com.gh.common.util.* +import com.gh.download.DownloadManager +import com.gh.gamecenter.GameDetailActivity +import com.gh.gamecenter.R +import com.gh.gamecenter.adapter.viewholder.FooterViewHolder +import com.gh.gamecenter.adapter.viewholder.GameViewHolder import com.gh.gamecenter.baselist.ListAdapter +import com.gh.gamecenter.databinding.PopupHistoryOptionBinding import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.entity.PluginLocation +import com.gh.gamecenter.game.GameItemViewHolder +import com.gh.gamecenter.history.ManageOption +import com.lightgame.download.DownloadEntity +import com.lightgame.download.DownloadStatus +import com.lightgame.utils.Utils -class VDownloadManagerAdapter(context: Context) : ListAdapter(context) { +class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloadManagerViewModel) : + ListAdapter(context) { + + private var mPopWindow: PopupWindow? = null + private var mCurrentOption = ManageOption.OPTION_MANAGER + private var mPopupBinding: PopupHistoryOptionBinding? = null + + var selectItems = arrayListOf() + + private val mPositionAndPackageMap = HashMap() + + override fun setListData(updateData: MutableList?) { + mPositionAndPackageMap.clear() + // 记录游戏位置 + if (updateData != null) { + for (i in 0 until updateData.size) { + val gameEntity = updateData[i] + var packages = gameEntity.id + for (apkEntity in gameEntity.getApk()) { + packages += apkEntity.packageName + } + mPositionAndPackageMap[packages + i] = i + } + } + super.setListData(updateData) + } + + override fun areItemsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean { + return oldItem?.id == newItem?.id + } + + override fun getItemViewType(position: Int) = ItemViewType.GAME_NORMAL override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { - TODO("Not yet implemented") + return GameItemViewHolder(parent.toBinding()) } - override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - TODO("Not yet implemented") + override fun getItemCount(): Int = if (mEntityList == null || mEntityList.isEmpty()) 0 else mEntityList.size + + fun changeOption(option: ManageOption) { + mCurrentOption = option + when (mCurrentOption) { + ManageOption.OPTION_MANAGER -> { + selectItems.clear() + mPopWindow?.dismiss() + mPopWindow = null + } + else -> { + if (mPopWindow == null || mPopWindow?.isShowing == false) { + showOptionWindow() + } + } + } + notifyItemRangeChanged(0, mEntityList.size) } - override fun getItemCount(): Int { - TODO("Not yet implemented") + override fun onBindViewHolder( + holder: RecyclerView.ViewHolder, + position: Int + ) { + when (holder) { + is GameItemViewHolder -> { + val gameEntity = mEntityList[position] + + holder.bindGameItem(gameEntity) + holder.initServerType(gameEntity) + + (holder.binding.selectIv.layoutParams as ConstraintLayout.LayoutParams).apply { + width = 20F.dip2px() + height = 20F.dip2px() + holder.binding.selectIv.layoutParams = this + } + holder.binding.selectIv.setImageDrawable(R.drawable.selector_ic_history.toDrawable()) + holder.binding.selectIv.goneIf(mCurrentOption == ManageOption.OPTION_MANAGER) + holder.binding.selectIv.isChecked = selectItems.contains(gameEntity.id) + + holder.itemView.setOnClickListener { + if (mCurrentOption == ManageOption.OPTION_MANAGER) { + GameDetailActivity.startGameDetailActivity( + mContext, + gameEntity.id, + "(畅玩游戏管理)" + ) + } else { + if (selectItems.contains(gameEntity.id)) { + selectItems.remove(gameEntity.id) + } else { + selectItems.add(gameEntity.id) + } + checkSelectItems() + notifyItemChanged(position) + } + } + + DownloadItemUtils.updateNormalItem(mContext, GameViewHolder(holder.binding), gameEntity, true, null) + updateDownloadBtn(mContext, holder.binding.downloadBtn, gameEntity) + + holder.itemView.setOnLongClickListener { + consume { + DialogHelper.showDialog(holder.binding.root.context, + "删除记录", + "删除浏览记录将不可恢复,确定删除吗?", + "确定", + "取消", { + mViewModel.removeItem() + }) + } + } + } + is FooterViewHolder -> { + holder.initItemPadding() + holder.initFooterViewHolder(mViewModel, mIsLoading, mIsNetworkError, mIsOver) + } + } + } + + private fun showOptionWindow() { + mPopupBinding = PopupHistoryOptionBinding.inflate(LayoutInflater.from(mContext)) + mPopupBinding?.root?.isFocusable = true + mPopupBinding?.root?.isFocusableInTouchMode = true + + mPopWindow = + PopupWindow(mPopupBinding?.root, LinearLayout.LayoutParams.MATCH_PARENT, 56F.dip2px()) + mPopWindow?.showAtLocation( + (mContext as AppCompatActivity).window.decorView, + Gravity.BOTTOM, + 0, + 0 + ) + + mPopupBinding?.itemDelete?.setOnClickListener { + DialogHelper.showDialog( + mContext, + "是否删除${selectItems.size}条记录?", + "提示:删除记录将不可恢复", + "删除", + "取消", + { + mViewModel.removeItems() + selectItems.clear() + checkSelectItems() + }, + extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true) + ) + } + mPopupBinding?.checkAllCb?.setOnClickListener { + if (mPopupBinding?.checkAllCb?.isChecked == true) { + selectItems.clear() + selectItems.addAll(mEntityList.map { it.id }.toList()) + } else { + selectItems.clear() + } + checkSelectItems() + notifyItemRangeChanged(0, mEntityList.size) + } + checkSelectItems() + } + + private fun checkSelectItems() { + mPopupBinding?.run { + selectNumTv.text = if (selectItems.isEmpty()) "" else "(${selectItems.size})" + itemDelete.background = + if (selectItems.isEmpty()) R.drawable.bg_shape_f5_radius_999.toDrawable() else R.drawable.download_button_normal_style.toDrawable() + itemDelete.setTextColor(if (selectItems.isEmpty()) R.color.text_body.toColor() else R.color.white.toColor()) + itemDelete.isEnabled = selectItems.isNotEmpty() + checkAllCb.isChecked = selectItems.size == mEntityList.size + } + } + + fun notifyItemByDownload(download: DownloadEntity) { + for (key in mPositionAndPackageMap.keys) { + if (key.contains(download.packageName) && key.contains(download.gameId)) { + val position = mPositionAndPackageMap[key] + if (position != null && mEntityList != null && position < mEntityList.size) { + mEntityList[position].getEntryMap()[download.platform] = download + notifyItemChanged(position) + } + } + } + } + + private fun updateDownloadBtn(context: Context, + downloadBtn: TextView, + gameEntity: GameEntity) { + // 青少年模式显示查看 + if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) { + downloadBtn.text = "查看" + return + } + + if (gameEntity.getApk().size == 1) { + val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByUrl(gameEntity.getApk()[0].url) + if (downloadEntity != null) { + val status = downloadEntity.status + var btnText = R.string.downloading + var btnColor = R.color.white + var btnBackground = R.drawable.download_button_normal_style + + downloadBtn.apply { + if (status == DownloadStatus.downloading) { + btnText = R.string.pause + btnBackground = R.drawable.button_normal_round_border + btnColor = R.color.theme_font + setOnClickListener { DownloadManager.getInstance().pause(downloadEntity.url) } + } else if (status == DownloadStatus.waiting) { + btnText = R.string.waiting + setOnClickListener { Utils.toast(mContext, "最多只能同时启动3个下载任务"); } + } else if (status == DownloadStatus.pause + || status == DownloadStatus.timeout + || status == DownloadStatus.neterror + || status == DownloadStatus.subscribe + || status == DownloadStatus.overflow + ) { + btnText = R.string.resume + setOnClickListener { + DownloadManager.getInstance().resume(downloadEntity, true) + } + } else if (status == DownloadStatus.done) { + if (downloadEntity.isSmoothGame()) { + GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, PluginLocation.only_index) + } + + setOnClickListener { + CurrentActivityHolder.getCurrentActivity()?.let { + VHelper.launch(it, downloadEntity.packageName) + } + } + } + + setText(btnText) + setTextColor(btnColor.toColor()) + setBackgroundResource(btnBackground) + } + } else { + GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, PluginLocation.only_index) + } + } else { + GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, PluginLocation.only_index) + } } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index 9769590ae4..4b838f58ca 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -1,13 +1,114 @@ package com.gh.vspace +import android.os.Bundle +import android.view.MenuItem +import android.view.View +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.ethanhua.skeleton.Skeleton +import com.gh.common.util.toColor +import com.gh.common.util.toDrawable +import com.gh.common.util.viewModelProvider +import com.gh.common.view.CustomDividerItemDecoration +import com.gh.download.DownloadManager +import com.gh.gamecenter.R import com.gh.gamecenter.baselist.ListAdapter import com.gh.gamecenter.baselist.ListFragment +import com.gh.gamecenter.databinding.FragmentListBaseSkeletonBinding import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.history.IBatchDelete +import com.gh.gamecenter.history.ManageOption +import com.lightgame.download.DataWatcher +import com.lightgame.download.DownloadEntity -class VDownloadManagerFragment: ListFragment() { +class VDownloadManagerFragment : + ListFragment(), IBatchDelete { - private val mAdapter by lazy { VDownloadManagerAdapter(requireContext()) } + private var mManageMenu: MenuItem? = null + + private val mAdapter by lazy { VDownloadManagerAdapter(requireContext(), provideListViewModel()) } + private val mViewModel: VDownloadManagerViewModel by lazy { viewModelProvider() } + private val mBinding by lazy { FragmentListBaseSkeletonBinding.inflate(layoutInflater) } + + private val dataWatcher: DataWatcher = object : DataWatcher() { + override fun onDataChanged(downloadEntity: DownloadEntity) { + mAdapter.notifyItemByDownload(downloadEntity) + } + } override fun provideListAdapter(): ListAdapter<*> = mAdapter + override fun provideListViewModel(): VDownloadManagerViewModel = mViewModel + + override fun getLayoutId() = R.layout.fragment_list_base_skeleton + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + initMenu(R.menu.menu_manage) + mManageMenu = getItemMenu(R.id.layout_menu_manage) + mManageMenu?.actionView?.setOnClickListener { + when (mViewModel.currentOptionLiveData.value) { + ManageOption.OPTION_MANAGER -> { + mViewModel.currentOptionLiveData.value = ManageOption.OPTION_CANCEL_SELECT + } + ManageOption.OPTION_CANCEL_SELECT -> { + mViewModel.currentOptionLiveData.value = ManageOption.OPTION_MANAGER + } + } + changeOption(mViewModel.currentOptionLiveData.value ?: ManageOption.OPTION_MANAGER) + } + changeMenuTextByOption() + + mViewModel.currentOptionLiveData.observe(this) { + changeMenuTextByOption() + } + } + + override fun onResume() { + super.onResume() + setNavigationTitle("畅玩游戏管理") + DownloadManager.getInstance().addObserver(dataWatcher) + } + + override fun onPause() { + super.onPause() + DownloadManager.getInstance().removeObserver(dataWatcher) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + mCachedView.setBackgroundColor(R.color.white.toColor()) + mSkeletonScreen = Skeleton.bind(mBinding.listSkeleton).shimmer(false) + .load(R.layout.fragment_subject_skeleton).show() + } + + override fun changeOption(option: ManageOption) { + mAdapter.changeOption(option) + changeMenuTextByOption() + } + + override fun getItemDecoration(): RecyclerView.ItemDecoration { + val itemDecoration = CustomDividerItemDecoration( + requireContext(), + onlyDecorateTheFirstItem = false, + notDecorateTheFirstItem = false, + notDecorateTheLastItem = true, + notDecorateTheFirstTwoItems = false + ) + itemDecoration.setDrawable(R.drawable.divider_item_line_space_16.toDrawable()!!) + return itemDecoration + } + + override fun shouldLoadMore() = false + + private fun changeMenuTextByOption() { + (mManageMenu?.actionView as? TextView)?.apply { + text = when (mViewModel.currentOptionLiveData.value) { + ManageOption.OPTION_MANAGER -> "编辑" + ManageOption.OPTION_CANCEL_SELECT -> "取消" + else -> "" + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index 75ae89f950..d6bce66586 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -1,19 +1,77 @@ package com.gh.vspace import android.app.Application +import androidx.lifecycle.MutableLiveData +import com.gh.download.DownloadManager import com.gh.gamecenter.baselist.ListViewModel +import com.gh.gamecenter.entity.ApkEntity import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.history.ManageOption +import com.gh.gamecenter.packagehelper.PackageRepository +import com.lightgame.download.DownloadEntity import io.reactivex.Observable +import io.reactivex.Single -class VDownloadManagerViewModel(application: Application) - : ListViewModel(application) { +class VDownloadManagerViewModel(application: Application) : + ListViewModel(application) { + + var currentOptionLiveData = MutableLiveData(ManageOption.OPTION_MANAGER) override fun mergeResultLiveData() { - TODO("Not yet implemented") + mResultLiveData.addSource(mListLiveData) { + mResultLiveData.postValue(it) + } } - override fun provideDataObservable(page: Int): Observable> { - TODO("Not yet implemented") + override fun provideDataObservable(page: Int): Observable>? = null + + override fun provideDataSingle(page: Int): Single> { + return Single.create { emitter -> + val installedGameList = + PackageRepository.installedGameListLiveData.value ?: arrayListOf() + val vDownloadList = DownloadManager.getInstance().allSmoothDownloadTask + val gameIdSet = hashSetOf() // 游戏 id set,避免下载任务和已安装任务同时出现 + + val vGameList = arrayListOf() + + for (downloadEntity in vDownloadList) { + gameIdSet.add(downloadEntity.gameId) + vGameList.add(toGameEntity(downloadEntity)) + } + + for (game in installedGameList) { + if (VHelper.isVGame(game) && !gameIdSet.contains(game.id)) { + vGameList.add(game) + } + } + + emitter.onSuccess(vGameList) + } + } + + private fun toGameEntity(downloadEntity: DownloadEntity): GameEntity { + return GameEntity(id = downloadEntity.gameId, name = downloadEntity.name).apply { + setApk( + arrayListOf( + ApkEntity( + packageName = downloadEntity.packageName, + url = downloadEntity.url, + platform = downloadEntity.platform + ) + ) + ) + icon = downloadEntity.icon + downloadStatus = "smooth" + setEntryMap(DownloadManager.getInstance().getEntryMap(name)) + } + } + + fun removeItem() { + // TODO 移除下载任务 and 卸载 VA 安装 + } + + fun removeItems() { + // TODO 移除下载任务 and 卸载 VA 安装 } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 833bf0ae61..6645e5c0fb 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -21,7 +21,6 @@ object VHelper { private const val LOG_TAG = "VSPACE" private const val VSPACE_PACKAGE_NAME = "com.lg.vspace" - private val mDelegateManager by lazy { VirtualAppManager.get() } private var mInstalledInfoList: List = arrayListOf() @@ -61,7 +60,7 @@ object VHelper { * 是否是使用畅玩启动类型的游戏 */ @JvmStatic - fun isSGame(gameEntity: GameEntity?): Boolean { + fun isVGame(gameEntity: GameEntity?): Boolean { return gameEntity?.downloadStatus != "smooth" } diff --git a/app/src/main/res/layout/activity_vdownload_manager.xml b/app/src/main/res/layout/activity_vdownload_manager.xml new file mode 100644 index 0000000000..1b659a5a1e --- /dev/null +++ b/app/src/main/res/layout/activity_vdownload_manager.xml @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7672fd2079..972723e9bf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -372,6 +372,8 @@ 下载中 插件化 安装 + 继续 + 暂停 启动 更新 更新中 From 25768d8caef5cfd42af10aec99f138dc393642f5 Mon Sep 17 00:00:00 2001 From: juntao Date: Sun, 24 Apr 2022 18:25:05 +0800 Subject: [PATCH 008/217] =?UTF-8?q?=E5=AE=8C=E6=88=90=E7=B2=97=E7=B3=99?= =?UTF-8?q?=E7=9A=84=E7=95=85=E7=8E=A9=E6=B8=B8=E6=88=8F=E8=AF=A6=E6=83=85?= =?UTF-8?q?=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 3 + .../gh/gamecenter/entity/GameDetailEntity.kt | 3 - .../gamedetail/GameDetailFragment.kt | 56 +++++- .../gamedetail/GameDetailViewModel.kt | 2 +- .../gamedetail/dialog/GameDetailMoreDialog.kt | 70 +++++++- .../gamedetail/entity/NewGameDetailEntity.kt | 4 + .../com/gh/vspace/VDownloadManagerAdapter.kt | 8 +- app/src/main/java/com/gh/vspace/VHelper.kt | 2 +- .../com/gh/vspace/VSpaceDialogFragment.kt | 59 +++++++ .../com/gh/vspace/VSpaceLoadingActivity.kt | 31 ++++ .../com/gh/vspace/VSpaceLoadingFragment.kt | 16 ++ .../ic_gamedetail_menu_follow.webp | Bin 0 -> 1754 bytes .../ic_gamedetail_menu_followed.webp | Bin 0 -> 1550 bytes .../ic_smooth_feature_no_password.webp | Bin 0 -> 8526 bytes .../ic_smooth_feature_snap.webp | Bin 0 -> 8878 bytes .../ic_smooth_feature_tool.webp | Bin 0 -> 8054 bytes .../ic_smooth_load_in_background.webp | Bin 0 -> 684 bytes .../drawable-xxxhdpi/ic_smooth_manager.png | Bin 1375 -> 0 bytes .../drawable-xxxhdpi/ic_smooth_manager.webp | Bin 0 -> 616 bytes .../res/drawable-xxxhdpi/ic_smooth_title.webp | Bin 0 -> 7638 bytes .../ic_switch_game_download.webp | Bin 0 -> 1246 bytes .../ic_switch_game_smooth.webp | Bin 0 -> 1300 bytes .../drawable/bg_horizontal_progressbar.xml | 30 ++++ .../main/res/drawable/border_eee_round_16.xml | 12 ++ .../drawable/vspace_dialog_top_background.xml | 13 ++ .../vspace_loading_top_background.xml | 9 + .../main/res/layout/detail_download_item.xml | 55 +++++- .../res/layout/dialog_game_detail_more.xml | 11 ++ app/src/main/res/layout/dialog_vspace.xml | 148 ++++++++++++++++ .../res/layout/fragment_vspace_loading.xml | 159 ++++++++++++++++++ dependencies.gradle | 2 +- 31 files changed, 672 insertions(+), 21 deletions(-) create mode 100644 app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt create mode 100644 app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt create mode 100644 app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_gamedetail_menu_follow.webp create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_gamedetail_menu_followed.webp create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_smooth_feature_no_password.webp create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_smooth_feature_snap.webp create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_smooth_feature_tool.webp create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_smooth_load_in_background.webp delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_smooth_manager.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_smooth_manager.webp create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_smooth_title.webp create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_switch_game_download.webp create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_switch_game_smooth.webp create mode 100644 app/src/main/res/drawable/bg_horizontal_progressbar.xml create mode 100644 app/src/main/res/drawable/border_eee_round_16.xml create mode 100644 app/src/main/res/drawable/vspace_dialog_top_background.xml create mode 100644 app/src/main/res/drawable/vspace_loading_top_background.xml create mode 100644 app/src/main/res/layout/dialog_vspace.xml create mode 100644 app/src/main/res/layout/fragment_vspace_loading.xml diff --git a/app/build.gradle b/app/build.gradle index 565d47e728..c56662d891 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -399,6 +399,9 @@ andResGuard { "R.id.bottomShareTv", "R.id.recommendStarPref", "R.id.recommendStar", + "R.id.iv_vmode_badge", + "R.id.tv_vmode", + "R.id.iv_vmode", "R.drawable.help_search_delete", "R.drawable.suggest_type_normal", "R.drawable.suggest_type_crash", diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameDetailEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/GameDetailEntity.kt index 95ae0c7d25..127dcaf72e 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameDetailEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameDetailEntity.kt @@ -81,9 +81,6 @@ class GameDetailEntity( @SerializedName("top_video") var topVideo: Video? = null, - @SerializedName("smooth_relation_game") - var smoothRelatedGame: SimpleGame? = null, - @SerializedName("intro_video") var introVideo: Video? = null, diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt index 78d381cd8c..750deabf35 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt @@ -21,6 +21,7 @@ import androidx.core.content.ContextCompat import androidx.core.view.ViewCompat import androidx.core.view.children import androidx.core.widget.TextViewCompat +import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.lifecycle.Observer import com.ethanhua.skeleton.Skeleton @@ -69,6 +70,7 @@ import com.gh.gamecenter.simulatorgame.SimulatorGameActivity import com.gh.gamecenter.tag.TagsActivity import com.gh.gamecenter.user.UserViewModel import com.gh.gamecenter.video.detail.CustomManager +import com.gh.vspace.VHelper import com.google.android.material.appbar.AppBarLayout import com.halo.assistant.HaloApp import com.halo.assistant.fragment.WebFragment @@ -127,6 +129,8 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { private lateinit var mPackageViewModel: PackageViewModel private lateinit var mUserViewModel: UserViewModel + private var mShowConcernOnMenu = false + private val mFragmentsList = ArrayList() private val mTabTitleList = ArrayList() @@ -204,7 +208,6 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { ) override fun getLayoutId(): Int = 0 - override fun getInflatedLayout(): View { return FragmentGamedetailBinding.inflate(LayoutInflater.from(requireContext())).apply { mBinding = this @@ -234,7 +237,9 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { GameDetailMoreDialog.showMoreDialog( requireActivity() as AppCompatActivity, mGameEntity, - mNewGameDetailEntity?.shortId ?: "" + mNewGameDetailEntity?.shortId ?: "", + mShowConcernOnMenu, + mNewGameDetailEntity!!.me.isGameConcerned ) MtaHelper.onEvent("游戏详情_新", "更多按钮", mViewModel.game?.name ?: "") } @@ -253,7 +258,6 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { mSearchMenuItem?.setOnMenuItemClickListener(menuItemClickListener) mDownloadMenuItem?.actionView?.setOnClickListener { MtaHelper.onEvent("游戏详情_新", "下载管理图标", mViewModel.game?.name ?: "") -// MtaHelper.onEvent("下载管理", "下载管理入口", (requireActivity() as BaseActivity).activityNameInChinese) val intent = DownloadManagerActivity.getDownloadMangerIntent(requireContext(), mEntrance) startActivity(intent) } @@ -528,8 +532,6 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { } mBodyBinding.toolbar.setNavigationOnClickListener { requireActivity().finish() } - mDownloadBinding.ivConcern.visibility = View.VISIBLE - mDownloadBinding.tvConcern.visibility = View.VISIBLE } @Subscribe(threadMode = ThreadMode.MAIN) @@ -592,8 +594,11 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { mBinding.errorToolbarContainer.visibility = View.GONE controlReserveBtn() - mSkeleton?.hide() + showVModeIconAtBottomBarIfNeeded(data.smoothRelatedGame, mGameEntity!!) + showConcernIconAtBottomBarIfAvailable() + + mSkeleton?.hide() } else if (detailResource.status == Status.ERROR) { loadErrorControl(detailResource.exception) } @@ -1598,6 +1603,45 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { } } + /** + * 当其它三个按钮不显示的时候才显示收藏按钮 + */ + private fun showConcernIconAtBottomBarIfAvailable() { + val installSwitchViewIsNotVisible = !mDownloadBinding.ivSwitch.isVisible + val reserveBtnIsNotVisible = !mDownloadBinding.ivReserve.isVisible + val vmodeViewIsNotVisible = !mDownloadBinding.ivVmode.isVisible + + if (installSwitchViewIsNotVisible || reserveBtnIsNotVisible || vmodeViewIsNotVisible) { + mDownloadBinding.ivConcern.visibility = View.VISIBLE + mDownloadBinding.tvConcern.visibility = View.VISIBLE + } else { + mDownloadBinding.ivConcern.visibility = View.GONE + mDownloadBinding.tvConcern.visibility = View.GONE + + mShowConcernOnMenu = true + } + } + + private fun showVModeIconAtBottomBarIfNeeded(simpleGame: SimpleGame?, gameEntity: GameEntity) { + mDownloadBinding.groupVmode.goneIf(simpleGame == null) + simpleGame?.let { + mDownloadBinding.ivVmode.displayGameIcon(simpleGame.getIcon(), simpleGame.iconSubscript) + if (VHelper.isVGame(gameEntity)) { + mDownloadBinding.tvVmode.text = "下载 >" + mDownloadBinding.ivVmodeBadge.setImageResource(R.drawable.ic_switch_game_download) + } else { + mDownloadBinding.tvVmode.text = "畅玩 >" + mDownloadBinding.ivVmodeBadge.setImageResource(R.drawable.ic_switch_game_smooth) + } + + mDownloadBinding.tvVmode.setOnClickListener { mDownloadBinding.ivVmode.performClick() } + mDownloadBinding.ivVmode.enlargeTouchArea() + mDownloadBinding.ivVmode.setOnClickListener { _ -> + DirectUtils.directToGameDetail(requireContext(), it.id ?: "", mEntrance) + } + } + } + override fun onSaveInstanceState(outState: Bundle) { mBodyBinding.gamedetailVp.let { outState.putInt(LAST_SELECTED_POSITION, it.currentItem) } super.onSaveInstanceState(outState) diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt index a86ba4a5fd..7356c768ea 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt @@ -41,7 +41,7 @@ class GameDetailViewModel(application: Application, var game: GameEntity?) : AndroidViewModel(application) { init { - runOnUiThread { + runOnIoThread { loadData() } } diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/dialog/GameDetailMoreDialog.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/dialog/GameDetailMoreDialog.kt index b306030f1d..a7b8a3926e 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/dialog/GameDetailMoreDialog.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/dialog/GameDetailMoreDialog.kt @@ -20,6 +20,9 @@ import com.gh.gamecenter.common.utils.toDrawable import com.gh.gamecenter.core.utils.MtaHelper import com.gh.gamecenter.databinding.DialogGameDetailMoreBinding import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.entity.SimpleGameEntity +import com.gh.gamecenter.gamedetail.GameDetailViewModel +import com.gh.gamecenter.suggest.SuggestType class GameDetailMoreDialog : BaseDraggableDialogFragment() { @@ -27,15 +30,26 @@ class GameDetailMoreDialog : BaseDraggableDialogFragment() { private var mGameEntity: GameEntity? = null private var mShortId = "" + private var mGameEntity: GameEntity? = null + private var mShowConcernIcon = false + private var mIsConcerned = false + private val mViewModel: GameDetailViewModel by lazy { viewModelProviderFromParent() } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) requireArguments().run { mGameEntity = getParcelable(KEY_GAME) mShortId = getString(KEY_SHORT_ID) ?: "" + mShowConcernIcon = getBoolean(KEY_SHOW_CONCERN_ICON) + mIsConcerned = getBoolean(KEY_IS_CONCERNED) } } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { binding = DialogGameDetailMoreBinding.inflate(inflater, container, false) return binding.root } @@ -46,6 +60,13 @@ class GameDetailMoreDialog : BaseDraggableDialogFragment() { binding.gameIconView.displayGameIcon(it) binding.gameNameTv.text = it.name } + + updateConcernView() + mViewModel.concernLiveData.observeNonNull(this) { response -> + mIsConcerned = response.isConcern + updateConcernView() + } + binding.shareWechatTv.setOnClickListener { getShareUtils().wechatShare() MtaHelper.onEvent("内容分享", "微信好友", mGameEntity?.name) @@ -122,6 +143,41 @@ class GameDetailMoreDialog : BaseDraggableDialogFragment() { return requireContext().getString(R.string.share_game_url, mShortId) } + private fun updateConcernView() { + if (mShowConcernIcon) { + binding.concernTv.visibility = View.VISIBLE + if (mIsConcerned) { + binding.concernTv.text = "取消关注" + binding.concernTv.setCompoundDrawablesWithIntrinsicBounds( + null, + R.drawable.ic_gamedetail_menu_followed.toDrawable(), + null, + null + ) + binding.concernTv.setOnClickListener { + ifLogin("游戏详情-[关注]") { + DialogHelper.showCancelDialog(requireContext(), { + mViewModel.concernCommand(false) + }) + } + } + } else { + binding.concernTv.text = "关注游戏" + binding.concernTv.setCompoundDrawablesWithIntrinsicBounds( + null, + R.drawable.ic_gamedetail_menu_follow.toDrawable(), + null, + null + ) + binding.concernTv.setOnClickListener { + ifLogin("游戏详情-[关注]") { + mViewModel.concernCommand(true) + } + } + } + } + } + override fun getRootView(): View = binding.root override fun getDragCloseView(): View = binding.dragClose @@ -156,16 +212,26 @@ class GameDetailMoreDialog : BaseDraggableDialogFragment() { } companion object { + const val KEY_SHOW_CONCERN_ICON = "displayed_concern_icon" + const val KEY_IS_CONCERNED = "concerned" private const val KEY_GAME = "game" private const val KEY_SHORT_ID = "short_id" @JvmStatic - fun showMoreDialog(activity: AppCompatActivity, gameEntity: GameEntity?, shortId: String) { + fun showMoreDialog( + activity: AppCompatActivity, + gameEntity: GameEntity?, + shortId: String, + showConcernIcon: Boolean = false, + isConcerned: Boolean = false, + ) { if (gameEntity == null) return GameDetailMoreDialog().apply { arguments = Bundle().apply { putParcelable(KEY_GAME, gameEntity) putString(KEY_SHORT_ID, shortId) + putBoolean(KEY_SHOW_CONCERN_ICON, showConcernIcon) + putBoolean(KEY_IS_CONCERNED, isConcerned) } }.show(activity.supportFragmentManager, GameDetailMoreDialog::class.java.name) } diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/entity/NewGameDetailEntity.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/entity/NewGameDetailEntity.kt index 1bdd9cb435..535fc8a9bc 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/entity/NewGameDetailEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/entity/NewGameDetailEntity.kt @@ -46,6 +46,10 @@ data class NewGameDetailEntity( var bbsTab: LinkEntity? = null, @SerializedName("certification_tag") var certificateTag: Screenshot? = null + var bbsTab: LinkEntity? = null, + + @SerializedName("smooth_relation_game") + var smoothRelatedGame: SimpleGame? = null, ) @Keep diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index 16dd35b2ab..270dc729ee 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -129,10 +129,10 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa holder.itemView.setOnLongClickListener { consume { DialogHelper.showDialog(holder.binding.root.context, - "删除记录", - "删除浏览记录将不可恢复,确定删除吗?", - "确定", - "取消", { + "删除游戏", + "单机类游戏被删除将可能导致本地存档、充值数据丢失,请确认后操作(网游类游戏删除不会影响游戏存档和充值数据)", + "删除", + "再等等", { mViewModel.removeItem() }) } diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 6645e5c0fb..bcf0cacd2f 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -61,7 +61,7 @@ object VHelper { */ @JvmStatic fun isVGame(gameEntity: GameEntity?): Boolean { - return gameEntity?.downloadStatus != "smooth" + return gameEntity?.downloadStatus == "smooth" } /** diff --git a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt new file mode 100644 index 0000000000..3c0d4487c0 --- /dev/null +++ b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt @@ -0,0 +1,59 @@ +package com.gh.vspace + +import android.content.Context +import android.os.Bundle +import android.view.View +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentActivity +import com.gh.common.dialog.BaseDraggableDialogFragment +import com.gh.common.exposure.ExposureEvent +import com.gh.common.util.EntranceUtils +import com.gh.gamecenter.databinding.DialogVspaceBinding +import com.gh.gamecenter.entity.GameEntity +import com.lightgame.utils.AppManager + +class VSpaceDialogFragment: BaseDraggableDialogFragment() { + + private val mBinding by lazy { DialogVspaceBinding.inflate(layoutInflater) } + + override fun getRootView(): View = mBinding.root + override fun getDragCloseView(): View = mBinding.dragClose + + companion object { + @JvmStatic + fun showDownloadDialog(context: Context?, gameEntity: GameEntity, traceEvent: ExposureEvent?, entrance: String?, location: String?) { + val fragmentActivity: FragmentActivity = if (context is FragmentActivity) { + context + } else { + val currentActivity = AppManager.getInstance().currentActivity() + if (currentActivity is FragmentActivity) { + currentActivity + } else { + throw IllegalStateException("current activity context must be FragmentActivity") + } + } + + // 防止重复弹出 + if (hasDialogDisplayedInCurrentActivity(fragmentActivity)) return + + val downloadDialog = VSpaceDialogFragment().apply { + val bundle = Bundle() + bundle.putString(EntranceUtils.KEY_ENTRANCE, entrance) + bundle.putString(EntranceUtils.KEY_LOCATION, location) + bundle.putParcelable(GameEntity::class.java.simpleName, gameEntity) + bundle.putParcelable(EntranceUtils.KEY_TRACE_EVENT, traceEvent) + arguments = bundle + } + downloadDialog.show(fragmentActivity.supportFragmentManager, VSpaceDialogFragment::class.java.name) + } + + private fun hasDialogDisplayedInCurrentActivity(fragmentActivity: FragmentActivity): Boolean { + val fragments: List = fragmentActivity.supportFragmentManager.fragments + fragments.forEach { fragment -> + if (fragment is VSpaceDialogFragment) return true + } + return false + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt b/app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt new file mode 100644 index 0000000000..e5caa2c138 --- /dev/null +++ b/app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt @@ -0,0 +1,31 @@ +package com.gh.vspace + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import com.gh.base.BaseActivity +import com.gh.common.util.EntranceUtils +import com.gh.gamecenter.R +import com.lightgame.download.DownloadEntity + +class VSpaceLoadingActivity: BaseActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + if (savedInstanceState == null) { + supportFragmentManager.beginTransaction().replace(R.id.placeholder, VSpaceLoadingFragment()).commitAllowingStateLoss() + } + } + + override fun getLayoutId() = R.layout.activity_shell + + companion object { + fun getIntent(context: Context, downloadEntity: DownloadEntity) : Intent { + val intent = Intent(context, VSpaceLoadingActivity::class.java) + intent.putExtra(EntranceUtils.KEY_DATA, downloadEntity) + return intent + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt new file mode 100644 index 0000000000..3db76c9ad7 --- /dev/null +++ b/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt @@ -0,0 +1,16 @@ +package com.gh.vspace + +import com.gh.base.fragment.BaseFragment +import com.gh.gamecenter.databinding.FragmentVspaceLoadingBinding + +class VSpaceLoadingFragment: BaseFragment() { + + private val mBinding: FragmentVspaceLoadingBinding by lazy { FragmentVspaceLoadingBinding.inflate(layoutInflater) } + + override fun getLayoutId() = 0 + override fun getInflatedLayout() = mBinding.root + + + + +} \ No newline at end of file diff --git a/app/src/main/res/drawable-xxxhdpi/ic_gamedetail_menu_follow.webp b/app/src/main/res/drawable-xxxhdpi/ic_gamedetail_menu_follow.webp new file mode 100644 index 0000000000000000000000000000000000000000..6fbc4b83338d2363f7d98f8230eeec3c837ea9fe GIT binary patch literal 1754 zcmV<01||7YNk&G}1^@t8MM6+kP&il$0000G0002L006%L06|PpNX!8M00DqjZExM? zgCGco5D11)1`&gbNx~py;4(0TKoA5&(5|^S>-TewhzUTal5Hxhw|I%oYndzy{!G!u z<0Y?)rawTe#!Ii7u9a&LSZ%(bd&^w-V4}$HKdr)jAj6w2v*bp=i2PNmJr9;GnXqO|Vpn5t$gY0ov za<*F9vjp8`hX&z!n=|H{G$^+%&RLV+G)TAKoHhUD7PRM|3UBp?6vWFnWzN1;<|=>` z)C-{8DX?(204sM63GyYgmyJD}*_#V{&&uBF?0I9a#oPaH|G)kJ_W!@Y8+*;!^Oe0? z*n7_G&BmT(_Oh@iaPC&%!QBEVcM1r12|#780)R26--NmJ4VAYie$2exeuA^+_|;g` z-=uNo*l3*T7C2*$&6zRXhQil^ovE?qX%Cbw#r~PA83&3p<#Gg4+aDH-TJfTOKd6@;Bs&mp5{iX*aC829|Haw$ybtanOlIkqD z39fo84AhKEC#|oon&A3LAM0!KMFoGRWSdL%_8OY6WwtEn6jo3;Am9W505B#1odGJq z0Kfn~F&K(Nq9LIZ$>bCu0|d0UaJlvT9q;;UqHHOb(EnS1r+z4Ym-#>bO1q!+In1~C z2pV;N=l^E>?EM4m3;N;JPxlYlul8g`$IGl!$2@hrUNL4r%yR|6JDB;8MV2PqEzeSE zz2ZuCMX|M{*+cOwSc@uLMe+1Nm&q3LoC|ON%qs-q7K+RY>%%CK>2l{wP^*l(4!`oQ z6ZLKR{=eWFUtNxJ({eCH+iWrm7WnwF6YqrH=}An`Uu=}x5L9#FhqZ7CoG^LF)X>br zbws~mZaJ=^Fzf_T5XzF2AzuLMU8$3@AWd$S_B=p8!qM0H;&`gp)Z0C(n?TCRJ@S(} z5}WIA1Y|gW+c+JOY^1)nuQ|jKwLE80ormD>m|;{%6(NWa!KTIy9z&QZl>@K<{&O)u z4k`=I_9v#{DdPxSr5}-q!5jcN3eW?BS+%~ZKPDRcn^;Z&aSUQR?4 z$6>q!a8x_xJvvLHTE_;)Qtnx4HnZWZ7i;GKKon%kC?#dL-;4@I{8f^-ua=*!D36PI zm?2&A(oftE&(7Ky6~_@vf*;g9)m^>IX=b@Tz=#L7yhk9c`;FgH~V)h^m=2Q;4^sx9p5CBZ0%JBc-)Az zFv9W+EV+!tz%g$Nx+d0t&!^_`@zv_7q8U0u^nXBTJv=lm+w{_??EeNuQ2}AQhuH;) zh;j=vb3LF;Fxr4h&01WZ08X+`jHaK#ZPH*I_6~qY+l^~3dlmyF1!H|yGQe@p7Ra3R z%7VEpyE`YRK_WRwkv6}`M|vOKFx4?ZA(7teVPMl<<~;yTp1zo^zl^@I z9b}LHVG=NG!x^ph9P}IaOQ3zpYY-PYpu!cHBZ3}@F-YNceXm_ka0J5a*jEL1w(a7W zWHJtxYuZ?-`6uk=CAoLx{GD)>GyCCA3_P-fN)Mw|VY^w#Y5qQVun#Ii{dd1v!D=if z-gr20LEJj>a+$;^gI>ATLW}5W?$S9VQXY<<5vm|dbVUE3fd3dVZ)t9EB} zrF3nYpftjYsIm-!9ENEb7qE78QIU|Cd3}H;+1*^J&vp$UpUer6 w8|u&i<|Pz%zRDdZINp!+yBL8~iJm#Hh;a3JMS<#T+2m{fAI2Z}e*gdg0O0Li0{{R3 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_gamedetail_menu_followed.webp b/app/src/main/res/drawable-xxxhdpi/ic_gamedetail_menu_followed.webp new file mode 100644 index 0000000000000000000000000000000000000000..32ea16b9a42433c0d80494bfa9bc13d25cf95fd2 GIT binary patch literal 1550 zcmV+p2J!h)Nk&En1^@t8MM6+kP&il$0000G0002L006%L06|PpNX!8M00DqjZExM? zgCGco5D11)1`&gbNx~py;4(0TKoA5&(5|^S>-TewhzUTal5Hxhw|I%oYndzy{!G!u z<0Y?)rawTe#!Ii7u9a&LSZ%(bd&^w-V4}$HKdr)jAj6w2v*bp=i2PNmJr9;GnXqO|Vpn5t$gY0ov za<*F9vjp8`hX&z!n=|H{G$^+%&RLV+G)TAKoHhUD7PRM|3UBp?6vWFnWzN1;<|=>` z)C-{8DX?(204sM63GyYgmyJD}*_#V{&&uBF?0I9a#oPaH|G)kJ_W!@Y8+*;!^Oe0? z*n7_G&BmT(_Oh@iaPC&%!QBEVcM1r12|#780)R26--NmJ4VAYie$2exeuA^+_|;g` z-=uNo*l3*T7C2*$&6zRXhQil^ovE?qX%Cbw#r~PA83&3p<#Gg4+aDH-TJfTOKd6@;Bs&mp5{iX*aC829|Haw$ybtanOlIkqD z39fo84AhKEC#|oon&A3LAM0!KMFoGRWSdL%_8OY6WwtEn6jo3;AQS`u0B|AzodGJq z0Kfn~F&K$Mq9KXRVhRuef?8X+T%&RN|Zc%lm{{S0;Vqx#$100xtdo1a1|x z?GZUOpaTy9P)JFe*-ZMhYvx=v_4~-TBKa;snYP1w)8wV$G-*R6<2YJaSpQ&4|Nj3g z(YTPm`Q`_&*ci1N>Y(>6?(;Xl%DVA|a8g46xGXjpX z!Km!+PeTkoI@@~$c0>oxjv^$sF&c^CpL1Mz#ygDJ;6Y=|7Sw@Nm3-X#={oXn#kefj zAIvzBfao;5mNnNI!-{|x^>!zdvm|ShUNUY7Ah2<`U&STKFB(?7C8)E4XH|;d5^Vbl z+E5Yv1Qr1N!pdag3aN`D0092|hvI+uaWp<$rgE_iQ?asl*@zk{0A7HU0vH6J^7rUu zyUI0M%l(R<|MjQ8|657_|5}J&jm-wR!UrjGF_;!0HTR6{*{O!ge_lms<-NH9DFO`y z?dl6kE!cxqYLlVNt_YYuHyq+RzQ9ppPw8O3#Gihw6PU$>Ap6`p6H>4}k*HPz0cKeS z1T;n29bu7K=^y|&+VkvE>(H(RHUww{blPX^!_`096}5gkd^r3vJkY=|bLHz`dgfoG z(R5Lcx@3=m#k=3#HjAzGmok1oWFnOAiHebXK=Y(CmSdrZ()Q(JIu>n_{09)r5Qu8e zql^wHrN7|@Pk(0v+n6GQkeDjFCcEe(^I^GG=e>wZ#?X$RsU~nlZ?<)548#VT_ET>!l3a9S!ezOS>zG_hD{2MLg89;LO#T1iOeCjIL$#W2_Lo??Y}7`t42L?(&q7;l=Y z@XGgPL@35mF;C}oSu0}GPCo!i6Giv#_zt^6RwoGj?~xz;w#(z#6RMmn$fF%Z|I+Y^02u3104T!s>GMC)7aqBXBmc6K|NgZ1|LZ-!|LY_G0MmEz AjQ{`u literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_smooth_feature_no_password.webp b/app/src/main/res/drawable-xxxhdpi/ic_smooth_feature_no_password.webp new file mode 100644 index 0000000000000000000000000000000000000000..f3234c90d151814f7496f16d898235b16ab57e50 GIT binary patch literal 8526 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 IGynhq0OVE`8~^|S literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_smooth_feature_snap.webp b/app/src/main/res/drawable-xxxhdpi/ic_smooth_feature_snap.webp new file mode 100644 index 0000000000000000000000000000000000000000..7e3ed5f5e33c3fb7ef9aa3756cb2ba397a906385 GIT binary patch literal 8878 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_smooth_feature_tool.webp b/app/src/main/res/drawable-xxxhdpi/ic_smooth_feature_tool.webp new file mode 100644 index 0000000000000000000000000000000000000000..d647c60ad647ed659d2bedfec53e067a32d76f64 GIT binary patch literal 8054 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 Sgy=uXry}+sG=97Q00002i$=8o literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_smooth_manager.png b/app/src/main/res/drawable-xxxhdpi/ic_smooth_manager.png deleted file mode 100644 index 89bf5f1f62dc00f12cb7240c74bc2d59bf53f2a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1375 zcmV-l1)%zgP)@~0drDELIAGL9O(c600d`2O+f$vv5yP{2Ol6F zIX6^Cj$OCvmdg$(%8?LYm#ga3eP5gCH^-cI;O_43#^dAT;oRI@hn@*oe>y)ue|d9r z(;E(lQ_V9i&7hr~ofN+=K#rahSbq&9)1{@QHvWC3d1hWS2ot}fmxcD$*4Bn*pqC(| z$ETIh3jpNwC#wN%og%Pp~SMmzO2a zot>VZ4oL~04O$7}WIt1bFw#rOzILAi;3T-PuwZpC@L*$V5K#Y)bPszPQvjRbqIvX8F~Rfi^IlezAc*{9yAJ#NL=6E|LP~LH;~*}$w3}TJ z34(|e0~?bdPJfN+!GE(qtOU7&;M&V_YYOojSqZs3JIC&OE)P!JSn3)BCvrt{otow2 zWl4h1SwUz3a-8LeML4wYbv|B}Bv@Ak!3Tu{*}!Qg_;+%0auQuT8gfUDA-&=rZ7LdF zL2$rEOdC-y<-+DNt^`6#ox+^FuOr8hJ`QnEyjW7vIx2`FIfI0QFsk$mljo{o4(y|2 z$R)@f*>02w##Ru%E}ZFWj!aUmf^c9nWGgExo6@tkFp<~>YAXmwo8hN5w9@n(SjJ9e zFc^p-Mb-EI+$4w%ZG=#Q#{LVJtH?N$IU!MFUllw;_LKu;y*%!u>sCV zy7}=TIcyba=BxA&)b>VmdwaWsO^+cnWPy)nbFDNp)qpRf?5G zu*$)S9Ae{LMeKFjvkj`REPUWJ%Jv0@uSsP*Be(bxdLmZ2-4X3%v~Qtcr-$%>Txod8&5{Wevae!$ zInfgIy@fIf0NYtxGasuX=G?676?rs4DZs002ovPDHLkV1jMBbD97E diff --git a/app/src/main/res/drawable-xxxhdpi/ic_smooth_manager.webp b/app/src/main/res/drawable-xxxhdpi/ic_smooth_manager.webp new file mode 100644 index 0000000000000000000000000000000000000000..1b7da4827b82dc5f062ef53c9067f6bf9d10416c GIT binary patch literal 616 zcmV-u0+;<#Nk&Fs0ssJ4MM6+kP&il$0000G0000t001`t06|PpNTvY*00Dqd+g2S1 z2{)1p0w@?|Z8PB7%Y2wvE)=`;sdCgZl^Vs6*TO z=_%r{Xb(j*VH^b8u%R&fMr4B1h(Pcxaid$Es1DESX$4!4E|7&WIgQ#k=$}p`6=sft*{Cx04l=jH%b zP&goz0000G1pu7^DmVZ*06r}eheDyD4Ek0K0b*J~iU0sCjvE&lILVljQLiN85_dcr zWoO=i0RH&DKmU1O|L&q+|J@-*?YsZ~nSmP6Urf4B|Nk+XEzW+6;bP2!Mp7z3HNXN$ z7XSsw?6v>>u>b#kQUCtfnK{l_G-;f2!pn}HpxvMUvph9y;6MRyHOyKMKmD070001h CRTuIA literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_smooth_title.webp b/app/src/main/res/drawable-xxxhdpi/ic_smooth_title.webp new file mode 100644 index 0000000000000000000000000000000000000000..e56eb1a400ed7b113d3ff681eede45c4355a7e1f GIT binary patch literal 7638 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

EI&|2X^M1HS zv$*$Gx{Y5*NYg(~Uez7G^Uuf0d0W85M#3#`sA{TjnnGWL}EgV39ai`Dl&$va*<;!!t9}TXA zI+We9({keJwYIuF6WNq$_vOe<-Y4{scf9;9ZgToY^>wcPcu8&**S~+`OWrSNNG(0+ z5}|=XAB*bbP@}i5UnZ(Qz7MJ_E_#D`;Hk{S2mr$`VAp`qu|ecg_=NlC%2Rzk^4T3P zfASfl4*Sg7b>;FLmFOth*90%!GXDEcFEf_Mhh12dZ*KV7sJf_r4rEeP&m!%NnZla3 z&Up2{E6V9F55-sfVJTN}jJ;+ZKa*g^VHc4ky+pj66+*OG_^alv$Xo|TQq$@)4SH{~ zq;)*fb#wLA@|zDUn#m_=&8A_eO+wT2^Eh_#%U)LBRYD)TT$80R*_Zu8L^Yy+!Gv3{ z*XGRKNUx&%o{SH~N?66d;*yQh|8{Wdd>BqF>A0c$&o^1f7^&e^>ghP|-WkIzCF$ar z4*wYlv1T>Hb-zqXcMG&4Zk^Xkdqat;g5$?FKDTI*tk$WW-X&Fj0!LXjD>89>udZ}x ztT?@(6iVjAxD?=+c*Qee=>}F!Wyxz&SP$@qm{JH za+xUgzjY#orULvYD&-8?hg0g#sOF>5@-l)!>j59IBd>k?r0m__J{Qrsms#{1Oi@yf zb}toTD14O0>Tf9QUdrD&uwtK9zB?rCpeKXLs`Tub_IpCG!@P<3)9vz>L;j`Ht2e=$ zT^ai}MKVDI!nEVFmK^`7GBICI^t;Pe@@C?ZK>ZQ>UJ9Vg|m$6U)H~*dU2sHHFTmZat)AoIlNT#$_u+hO$Gx8*Hwm9W{WmF z@3rlj=CRcn*3}J;oiXiN6V1Q;?y@-F7fOBddd|6%vAv%wk*ro7FaDLk!@G+EU*bBU z6cv%5e&t(KzMaf!d{JfzV;+lbXO6)2pZ71d`=>+i_x+1%t^Wl4tnqGaU2)pvrh^E_@UvWIQ$9g|AeB>7x zYP>-U1=iI# zGPqqN!Gdg$P_AR`^x3hs=8w3wwpN8Uyk6KiU$Lf1`)i6E#XppGXjQ2=SIkh42YpYO sma|sT_33dhe3!qnz<)PY%l@mt)1jd@#wWjQ32CA7%YUE$-7+xz4-G(|$^ZZW literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_switch_game_download.webp b/app/src/main/res/drawable-xxxhdpi/ic_switch_game_download.webp new file mode 100644 index 0000000000000000000000000000000000000000..d264c2ca0c7421f0877497c3604ac1b9a7f9e283 GIT binary patch literal 1246 zcmV<41R?uUNk&H21ONb6MM6+kP&il$0000G0000l001ul06|PpNZSAa00DqdTW{Xx zgCGck6b2O&i$TpGWzaD&1VbwQFKj&?Q0ZYeD%yXg)oktk#+|KIwrXr9Y>LL!0p~J6f=U56(+L0)MEVBj zaeVG9179^bLchT{4*cp2j^BNsWA=zWVVKvkqbrvBvT&@{+mdj>MzucET(DcMwvm}J z?$reI09H^qAk+f@0Pq$7odGH^05AYPF&2nJA|W9YoCeq+0|d4JPMJbIuh=}nDo@J3 z`En0p#I{{?z~f_nH6ydG>g^=F@h@>@E8kc;T$Kv1Pdr z|E%~7J#O9Z+Cb4N>2}`}dSan*P8ULi##88^c2w+j#W;S%JSs+6Epi4!TKrOjKmh*# z{$fh&$cCB)h#1pMK4qEkkLg`M?F62*>KM(6I3RVX>uHT$|1pThBQyf^bUlx!(xsn; z)V90OkM1<~%sRq_5sjwyBwIGsz4ym8(|;ZE?EuB$TEVy4f8gQ>cU7pD$c)!kSX6*a zj^O@UX%JN!aLoJ9(qFS}YWci{aA7(8OMib%^L~FL&Adku#yH_AUe*2uRa0DsBXVc* zjGmWN0p7MLr=biVnD0OQkZ52B{!NFhylSNQn0k=9pw~u)0J+yy(`i_r{1B9g`j$e; zj>^tQbjL4y_Uy;ZZM!)owj}bw4GgY=TjpM6b>gnxc7K{(Ol_@$ zG%{zKi8)jOb#xkgzwR-UI&2H{G_-$Ls8G2cR?AKezH% zHM747;mFd)bsf$*oRyxRG9I4ft-_==Z+T<$_7J)`k&ZH9Ipu*5?m~iufo$2RO?|mU z$emf5CI8?9lZGc)v-s%LfBXP8DcBA|zs;B!-LC21mWgLmjkn=y$SELJ=G;beX(Com zC*c>}wk`99ydwTyrRMam`pGLj5ABA@P*bdjirK&T1k2Z1yr5JwXmK2%mDFm39RJnW z;gJmtb{MykF|*nh>3LkIW3 z`#8#X@7wRgH!kN7r54~EkC_k!=O+2C&pQ**IVNnI`1H6deLYE`y<+74=jQMBV>s;& zM`m5~T8Z6T7$6Wx@FGmPAL_ylNO`;t-EsE$Ox;hBGVP_eQ%S#H)(8V4F)dg_2VUf37`)L8@n~gY&uKsG!P`h)kbK~QsxlcJ8BARXT*{N(fioN96sZwBb zcZIbpPhVcYYX@HKy=R{#5`;&6I3a8)^^_NbiVJC*@8F;dzQJu{;e3t40aU)EME3}} I)}e3!05p+mCjbBd literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_switch_game_smooth.webp b/app/src/main/res/drawable-xxxhdpi/ic_switch_game_smooth.webp new file mode 100644 index 0000000000000000000000000000000000000000..5026c38c39467493e96c01b04bb392e17977f9b3 GIT binary patch literal 1300 zcmV+v1?&1!Nk&Et1pok7MM6+kP&il$0000G0000l001ul06|PpNZSAa00DqdTW{Xx zgCGck6b2O&i$TpGWzaD&1VbwQFKj&?Q0ZYeD%yXg)oktk#+|KIwrXr9Y>LL!0p~J6f=U56(+L0)MEVBj zaeVG9179^bLchT{4*cp2j^BNsWA=zWVVKvkqbrvBvT&@{+mdj>MzucET(DcMwvm}J z?$reI09H^qAPNKk08kYGodGH^05AYPF%*eIq9Gv@oCUNX0|d4JPMJbIuhcxjDSy>| z?tax}81YB^4v-&(ztQ`EexCGz^8x&0{2#90p?{zckPp~Sun*SnU=P|4Oy6Ta*?-#4 zali8SdjE>$Bz0}`G@#7i$M4d9!2ikmhyKy~3ox#6&|pq6VVLfdK#cZxWTFPXt`iC7 zX9<{f95JKUKxE6kpM-jAtfo_>VnhV}$=d*gx4@U)}~rOrpJ z@AX{^jsHqyRUu<8(O9qsnS5_(+kS?DXQ$&;@`~oGJ6Y)S!@+QLDKE-;W22IT2*PV_ zFCW_GK87tEUp4G~*JYS?5!nq*6==f(3QY^PW(_EX@3WRLaWB#PO<4<7ee(lpBg7QX zZV`I?i_494=FmY}!Uf-TdeQn}usBaSOKN_&cVjY7?ETIhEKjGhML!+=hIJAbko!Cr zMwI<>DPw|(4GCzGA4%`Sg~$IwNGu}a85;$qsoTPPyhEKIQFISXTWA!*`@hpbiO^8V zApbrGg%fh4?fMx_VOuA1fDb#=OQ@B=qa(TosEhW?#kUeG$x;#~f*^0mOA-bO$|oyi z2`@flE7E006UI^(c=#HF6LGKwMcd3h>B0J0Fvdr;!lq%9KbEGo+wq_9yDWEV%r1Sq z8R!h3Xg>IAbH2nn9S8B<6W|Ne+mL=8vYmPZ2g#+NF?f2ScwduKst4rL-=ESVUzMN9 z_Sc?UpzDX}Jkm@5`#&>j2J`m~NM5_VwKA_)O>S8Y_3;l~_^zD|_&PSi`-L8E7-upb zP4CH-&iUBS|LKVPbn0)sge=X$5#6{|1GwH$cfq|MqBR-LN8VMBu%{n@ZumkfZZjQR z`*;_Gqxx$@ziFRSSJ^hSxR}a=H?D8&8j{w0$Q|P~Goc6}wX`dOgbVBMtvjd^GvD8v zzkdnE>DQ5))zaIG5I`*8LCFcqb_O1iaoEw!9yfllo~dFM=-Z?XC=Y(g)s))XHCG$~hq}SMA{pHi!uZ!niD@9Q+By3tpD+%<+#PLj z&b2i%DF;T}KyzcbiW37hj1-Vv`m=xdK{iR;S7pe!NkR^ua5RBStr^nu;m9!f#h6xV Klq#>~U;qHM-E(UI literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/bg_horizontal_progressbar.xml b/app/src/main/res/drawable/bg_horizontal_progressbar.xml new file mode 100644 index 0000000000..600ae42f41 --- /dev/null +++ b/app/src/main/res/drawable/bg_horizontal_progressbar.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/border_eee_round_16.xml b/app/src/main/res/drawable/border_eee_round_16.xml new file mode 100644 index 0000000000..e7ecd984db --- /dev/null +++ b/app/src/main/res/drawable/border_eee_round_16.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/vspace_dialog_top_background.xml b/app/src/main/res/drawable/vspace_dialog_top_background.xml new file mode 100644 index 0000000000..8f8ee605c3 --- /dev/null +++ b/app/src/main/res/drawable/vspace_dialog_top_background.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/vspace_loading_top_background.xml b/app/src/main/res/drawable/vspace_loading_top_background.xml new file mode 100644 index 0000000000..cafd5724c0 --- /dev/null +++ b/app/src/main/res/drawable/vspace_loading_top_background.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/detail_download_item.xml b/app/src/main/res/layout/detail_download_item.xml index e7272d0f63..a602061fe1 100644 --- a/app/src/main/res/layout/detail_download_item.xml +++ b/app/src/main/res/layout/detail_download_item.xml @@ -140,14 +140,60 @@ android:paddingEnd="20dp" android:paddingBottom="10dp"> + + + + + + + + @@ -171,10 +217,11 @@ android:layout_width="24dp" android:layout_height="24dp" android:layout_marginStart="20dp" + android:layout_marginTop="10dp" android:background="@drawable/ic_gamedetail_reserve" android:visibility="gone" app:layout_constraintStart_toEndOf="@id/iv_concern" - app:layout_constraintTop_toTopOf="@+id/iv_concern" + app:layout_constraintTop_toTopOf="parent" tools:visibility="visible" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_vspace_loading.xml b/app/src/main/res/layout/fragment_vspace_loading.xml new file mode 100644 index 0000000000..4d4dfa7e56 --- /dev/null +++ b/app/src/main/res/layout/fragment_vspace_loading.xml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dependencies.gradle b/dependencies.gradle index 881b2f1bb6..0192db3f3d 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -19,7 +19,7 @@ ext { fragment = "1.2.5" annotation = "1.1.0" percentLayout = "1.0.0" - constraintLayout = "2.0.4" + constraintLayout = "2.1.3" databinding = "3.4.1" recyclerView = "1.1.0" lifeCycle = "2.2.0" From 331e4fc4107589a802511af935110a24b3b72fdb Mon Sep 17 00:00:00 2001 From: juntao Date: Wed, 27 Apr 2022 17:47:36 +0800 Subject: [PATCH 009/217] =?UTF-8?q?=E5=AF=B9=E6=8E=A5=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 6 +- .../java/com/gh/common/constant/Config.java | 30 ++++ .../com/gh/common/util/DownloadItemUtils.kt | 20 +-- .../java/com/gh/common/util/GameUtils.java | 8 +- .../java/com/gh/gamecenter/entity/VSetting.kt | 25 +++ .../gamedetail/entity/NewGameDetailEntity.kt | 3 +- .../gamecenter/retrofit/RetrofitManager.java | 5 + .../retrofit/service/VApiService.kt | 28 ++++ .../com/gh/vspace/VDownloadManagerAdapter.kt | 3 +- .../gh/vspace/VDownloadManagerViewModel.kt | 5 +- app/src/main/java/com/gh/vspace/VHelper.kt | 24 +-- .../com/gh/vspace/VSpaceDialogFragment.kt | 144 +++++++++++++++++- .../ic_gamedetail_smooth_download_hint.xml | 20 +++ app/src/main/res/layout/dialog_vspace.xml | 10 +- gradle.properties | 2 + .../gamecenter/common/constant/Constants.java | 3 + 16 files changed, 298 insertions(+), 38 deletions(-) create mode 100644 app/src/main/java/com/gh/gamecenter/entity/VSetting.kt create mode 100644 app/src/main/java/com/gh/gamecenter/retrofit/service/VApiService.kt create mode 100644 app/src/main/res/drawable/ic_gamedetail_smooth_download_hint.xml diff --git a/app/build.gradle b/app/build.gradle index c56662d891..116386b511 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -74,6 +74,7 @@ android { */ buildConfigField "String", "API_HOST", "\"${API_HOST}\"" buildConfigField "String", "NEW_API_HOST", "\"${NEW_API_HOST}\"" + buildConfigField "String", "VAPI_HOST", "\"${VAPI_HOST}\"" buildConfigField "String", "WECHAT_APPID", "\"${WECHAT_APPID}\"" buildConfigField "String", "WECHAT_SECRET", "\"${WECHAT_SECRET}\"" buildConfigField "String", "TENCENT_APPID", "\"${TENCENT_APPID}\"" @@ -157,14 +158,16 @@ android { buildConfigField "String", "DEV_API_HOST", "\"${DEV_API_HOST}\"" buildConfigField "String", "NEW_DEV_API_HOST", "\"${NEW_DEV_API_HOST}\"" + buildConfigField "String", "DEV_VAPI_HOST", "\"${DEV_VAPI_HOST}\"" } - // publish release host˛ + // publish release host publish { dimension "env" buildConfigField "String", "DEV_API_HOST", "\"${API_HOST}\"" buildConfigField "String", "NEW_DEV_API_HOST", "\"${NEW_API_HOST}\"" + buildConfigField "String", "DEV_VAPI_HOST", "\"${API_HOST}\"" } tea { @@ -172,6 +175,7 @@ android { buildConfigField "String", "DEV_API_HOST", "\"${API_HOST}\"" buildConfigField "String", "NEW_DEV_API_HOST", "\"${NEW_API_HOST}\"" + buildConfigField "String", "DEV_VAPI_HOST", "\"${API_HOST}\"" manifestPlaceholders.put("APPLOG_SCHEME", "rangersapplog.byAx6uYt".toLowerCase()) } diff --git a/app/src/main/java/com/gh/common/constant/Config.java b/app/src/main/java/com/gh/common/constant/Config.java index c0f7371ed5..20c8e6e6da 100644 --- a/app/src/main/java/com/gh/common/constant/Config.java +++ b/app/src/main/java/com/gh/common/constant/Config.java @@ -20,6 +20,7 @@ import com.gh.gamecenter.entity.GameGuidePopupEntity; import com.gh.gamecenter.entity.NewSettingsEntity; import com.gh.gamecenter.entity.NewsEntity; import com.gh.gamecenter.entity.SettingsEntity; +import com.gh.gamecenter.entity.VSetting; import com.gh.gamecenter.eventbus.EBReuse; import com.gh.gamecenter.common.retrofit.BiResponse; import com.gh.gamecenter.common.retrofit.Response; @@ -44,6 +45,7 @@ public class Config { // 这个 API_HOST 在测试包里会随着选择的环境切换,正式包里会一直保持正式 host public static final String API_HOST = EnvHelper.getHost(); public static final String NEW_API_HOST = EnvHelper.getNewHost(); + public static final String VAPI_HOST = EnvHelper.getVHost(); // Third-Party confs public static final String WECHAT_APPID = BuildConfig.WECHAT_APPID; @@ -59,6 +61,7 @@ public class Config { private static SettingsEntity mSettingsEntity; private static NewSettingsEntity mNewSettingsEntity; + private static VSetting mVSetting; private static GameGuidePopupEntity mGameGuidePopupEntity; private static SharedPreferences mDefaultSharedPreferences; @@ -214,6 +217,21 @@ public class Config { return mNewSettingsEntity; } + @Nullable + public static VSetting getVSettingEntity() { + if (mVSetting == null) { + try { + String json = SPUtils.getString(Constants.SP_V_SETTINGS); + if (!TextUtils.isEmpty(json)) { + mVSetting = GsonUtils.fromJson(json, VSetting.class); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + return mVSetting; + } + @Nullable public static GameGuidePopupEntity getGameGuidePopupEntity() { return mGameGuidePopupEntity; @@ -307,6 +325,18 @@ public class Config { } }); + RetrofitManager.getInstance() + .getVApi().getSettings(BuildConfig.VERSION_NAME) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BiResponse() { + @Override + public void onSuccess(VSetting data) { + mVSetting = data; + SPUtils.setString(Constants.SP_V_SETTINGS, GsonUtils.toJson(data)); + } + }); + RetrofitManager.getInstance() .getApi().getGameGuidePopup(Build.MANUFACTURER, Build.VERSION.RELEASE, Build.MODEL, channel, BuildConfig.VERSION_NAME) .subscribeOn(Schedulers.io()) diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index 5eac0c5f2b..9728b26a24 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -690,14 +690,14 @@ object DownloadItemUtils { } DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance) } else if (str == context.getString(R.string.smooth)) { - VHelper.checkVSpaceBeforeAction(context, gameEntity) { - GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) { - PackageCheckDialogFragment.show(context, gameEntity) { - DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, object : EmptyCallback { - override fun onCallback() { - CertificationDialog.showCertificationDialog(context, gameEntity) { - DialogUtils.showVersionNumberDialog(context, gameEntity) { - DialogUtils.showOverseaDownloadDialog(context, gameEntity) { + GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) { + PackageCheckDialogFragment.show(context, gameEntity) { + DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, object : EmptyCallback { + override fun onCallback() { + CertificationDialog.showCertificationDialog(context, gameEntity) { + DialogUtils.showVersionNumberDialog(context, gameEntity) { + DialogUtils.showOverseaDownloadDialog(context, gameEntity) { + VHelper.checkVSpaceBeforeAction(context, gameEntity) { DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent) } @@ -705,8 +705,8 @@ object DownloadItemUtils { } } } - }) - } + } + }) } } } else if (str.contains("化")) { diff --git a/app/src/main/java/com/gh/common/util/GameUtils.java b/app/src/main/java/com/gh/common/util/GameUtils.java index b56a9f1fd8..a4c707635d 100644 --- a/app/src/main/java/com/gh/common/util/GameUtils.java +++ b/app/src/main/java/com/gh/common/util/GameUtils.java @@ -148,6 +148,10 @@ public class GameUtils { return context.getString(R.string.launch); } + if ("smooth".equals(gameEntity.getDownloadStatus())) { + return context.getString(R.string.smooth); + } + if (doneCount != 0) { return context.getString(R.string.install); } else if (pluginCount != 0 && !SimulatorGameManager.isSimulatorGame(gameEntity)) { @@ -158,9 +162,7 @@ public class GameUtils { return context.getString(R.string.launch); } else if ("demo".equals(gameEntity.getDownloadStatus())) { return context.getString(R.string.attempt); - } else if ("smooth".equals(gameEntity.getDownloadStatus())) { - return context.getString(R.string.smooth); - } else { + } else { return context.getString(R.string.download); } } diff --git a/app/src/main/java/com/gh/gamecenter/entity/VSetting.kt b/app/src/main/java/com/gh/gamecenter/entity/VSetting.kt new file mode 100644 index 0000000000..c5df59740f --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/entity/VSetting.kt @@ -0,0 +1,25 @@ +package com.gh.gamecenter.entity + +import com.google.gson.annotations.SerializedName + +class VSetting { + @SerializedName("va") + var va: Va? = null + + data class Va( + @SerializedName("32-bit") + val arch32: VaArch? = null, + val arch64: VaArch? = null, + ) + + data class VaArch( + val size: String, + @SerializedName("package") + val packageName: String, + @SerializedName("version") + val versionName: String, + @SerializedName("version_code") + val versionCode: Int, + val url: String + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/entity/NewGameDetailEntity.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/entity/NewGameDetailEntity.kt index 535fc8a9bc..83a11dcbb2 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/entity/NewGameDetailEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/entity/NewGameDetailEntity.kt @@ -45,8 +45,7 @@ data class NewGameDetailEntity( @SerializedName("bbs_tab") var bbsTab: LinkEntity? = null, @SerializedName("certification_tag") - var certificateTag: Screenshot? = null - var bbsTab: LinkEntity? = null, + var certificateTag: Screenshot? = null, @SerializedName("smooth_relation_game") var smoothRelatedGame: SimpleGame? = null, diff --git a/app/src/main/java/com/gh/gamecenter/retrofit/RetrofitManager.java b/app/src/main/java/com/gh/gamecenter/retrofit/RetrofitManager.java index ac685b35e9..f9da389367 100644 --- a/app/src/main/java/com/gh/gamecenter/retrofit/RetrofitManager.java +++ b/app/src/main/java/com/gh/gamecenter/retrofit/RetrofitManager.java @@ -4,6 +4,7 @@ import android.content.Context; import com.gh.common.constant.Config; import com.gh.gamecenter.common.retrofit.BaseRetrofitManager; import com.gh.gamecenter.retrofit.service.ApiService; +import com.gh.gamecenter.retrofit.service.VApiService; import com.halo.assistant.HaloApp; import okhttp3.OkHttpClient; @@ -16,6 +17,7 @@ public class RetrofitManager extends BaseRetrofitManager { private final ApiService mApiService; private final ApiService mNewApiService; private final ApiService mUploadApiService; + private final VApiService mVApiService; private RetrofitManager() { Context context = HaloApp.getInstance().getApplicationContext(); @@ -23,6 +25,7 @@ public class RetrofitManager extends BaseRetrofitManager { mApiService = provideService(okHttpNormalConfig, Config.API_HOST, ApiService.class); mNewApiService = provideService(okHttpNormalConfig, Config.NEW_API_HOST, ApiService.class); mUploadApiService = provideService(getOkHttpConfig(context, UPLOAD_CALL_TIME_OUT, 1), Config.API_HOST, ApiService.class); + mVApiService = provideService(okHttpNormalConfig, Config.VAPI_HOST, VApiService.class); } public static RetrofitManager getInstance() { @@ -41,6 +44,8 @@ public class RetrofitManager extends BaseRetrofitManager { return mUploadApiService; } + public VApiService getVApi() { return mVApiService; } + private static class SingletonHolder { private static final RetrofitManager INSTANCE = new RetrofitManager(); } diff --git a/app/src/main/java/com/gh/gamecenter/retrofit/service/VApiService.kt b/app/src/main/java/com/gh/gamecenter/retrofit/service/VApiService.kt new file mode 100644 index 0000000000..188b84e960 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/retrofit/service/VApiService.kt @@ -0,0 +1,28 @@ +package com.gh.gamecenter.retrofit.service + +import com.gh.gamecenter.entity.AppEntity +import com.gh.gamecenter.entity.VSetting +import io.reactivex.Observable +import io.reactivex.Single +import retrofit2.http.GET +import retrofit2.http.Query + +interface VApiService { + + /** + * 获取对应包名匹配的更新 + */ + @GET("upgrade") + fun getPackageUpdate( + @Query("version") version: String?, + @Query("version_code") code: Int, + @Query("package") packageName: String? + ): Observable + + /** + * 获取设置 + */ + @GET("setting") + fun getSettings(@Query("version") version: String?): Single + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index 270dc729ee..36f8ee220c 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -133,7 +133,8 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa "单机类游戏被删除将可能导致本地存档、充值数据丢失,请确认后操作(网游类游戏删除不会影响游戏存档和充值数据)", "删除", "再等等", { - mViewModel.removeItem() + val apk = gameEntity.getApk().firstOrNull() + mViewModel.removeItem(apk?.url, apk?.packageName) }) } } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index d6bce66586..beee4dfc74 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -66,8 +66,9 @@ class VDownloadManagerViewModel(application: Application) : } } - fun removeItem() { - // TODO 移除下载任务 and 卸载 VA 安装 + fun removeItem(url: String? , packageName: String?) { + DownloadManager.getInstance().cancel(url) + VHelper.uninstall(packageName ?: "") } fun removeItems() { diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index bcf0cacd2f..f125748bd4 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -5,8 +5,10 @@ import android.app.Activity import android.content.Context import android.content.Intent import com.gh.common.AppExecutor +import com.gh.common.constant.Config import com.gh.common.util.EmptyCallback import com.gh.common.util.PackageUtils +import com.gh.common.util.ToastUtils import com.gh.download.PackageObserver import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.eventbus.EBPackage @@ -19,7 +21,6 @@ import com.lightgame.utils.Utils object VHelper { private const val LOG_TAG = "VSPACE" - private const val VSPACE_PACKAGE_NAME = "com.lg.vspace" private val mDelegateManager by lazy { VirtualAppManager.get() } private var mInstalledInfoList: List = arrayListOf() @@ -81,15 +82,17 @@ object VHelper { // 仅下载类型为畅玩的类型才执行判断 if (gameEntity?.downloadStatus == "smooth") { // TODO 区分 32 位的组件和 64 位的组件 - val isInstalled = PackageUtils.isInstalled(context, VSPACE_PACKAGE_NAME) + val isArch32Installed = PackageUtils.isInstalled(context, Config.getVSettingEntity()?.va?.arch32?.packageName) +// val isArch64Installed = PackageUtils.isInstalled(context, Config.getVSettingEntity()?.va?.arch64?.packageName) - if (!isInstalled) { - // TODO 触发下载弹窗 + if (!isArch32Installed) { + VSpaceDialogFragment.showDownloadDialog(context, gameEntity) return } + // TODO 检查更新 val containsUpdate = PackageRepository.gameUpdate.any { - it.packageName == VSPACE_PACKAGE_NAME + it.packageName == Config.getVSettingEntity()?.va?.arch32?.packageName } if (containsUpdate) { @@ -177,10 +180,13 @@ object VHelper { @JvmStatic fun launch(activity: Activity, packageName: String) { Utils.log(LOG_TAG, "打开应用$packageName") - - val intent = mDelegateManager.getStartGameIntent(packageName) - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - activity.startActivity(intent) + try { + val intent = mDelegateManager.getStartGameIntent(packageName) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + activity.startActivity(intent) + } catch (e: Exception) { + ToastUtils.toast(e.localizedMessage ?: "") + } } /** diff --git a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt index 3c0d4487c0..2d9f6af0c7 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt @@ -1,27 +1,156 @@ package com.gh.vspace +import android.annotation.SuppressLint import android.content.Context import android.os.Bundle +import android.text.SpannableStringBuilder +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup +import androidx.core.text.bold +import androidx.core.text.color import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity +import com.gh.common.AppExecutor +import com.gh.common.constant.Config +import com.gh.common.constant.Constants import com.gh.common.dialog.BaseDraggableDialogFragment -import com.gh.common.exposure.ExposureEvent import com.gh.common.util.EntranceUtils +import com.gh.common.util.PackageInstaller +import com.gh.common.util.SPUtils +import com.gh.common.util.toColor +import com.gh.common.view.DownloadProgressBar +import com.gh.download.DownloadManager +import com.gh.gamecenter.R import com.gh.gamecenter.databinding.DialogVspaceBinding import com.gh.gamecenter.entity.GameEntity +import com.lightgame.download.DataWatcher +import com.lightgame.download.DownloadEntity +import com.lightgame.download.DownloadStatus.* +import com.lightgame.download.FileUtils import com.lightgame.utils.AppManager -class VSpaceDialogFragment: BaseDraggableDialogFragment() { +class VSpaceDialogFragment : BaseDraggableDialogFragment() { + private val mDownloadUrl by lazy { Config.getVSettingEntity()?.va?.arch32?.url } // TODO 支持 64 位地址 private val mBinding by lazy { DialogVspaceBinding.inflate(layoutInflater) } + private val mDataWatcher = object : DataWatcher() { + override fun onDataChanged(downloadEntity: DownloadEntity) { + if (downloadEntity.url == mDownloadUrl) { + val downloadBtn = mBinding.downloadBtn + downloadBtn.progress = (downloadEntity.progress * 10).toInt() + when (downloadEntity.status) { + downloading, + pause, + overflow -> { + if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL)) { + downloadBtn.setText(R.string.browser_install_downloading) + } else { + downloadBtn.setText(R.string.downloading) + } + downloadBtn.downloadType = DownloadProgressBar.DownloadType.DOWNLOADING_NORMAL + downloadBtn.setOnClickListener { + DownloadManager.getInstance().pause(mDownloadUrl) + } + } + timeout, + neterror, + waiting, + subscribe -> { + downloadBtn.setText(R.string.waiting) + downloadBtn.downloadType = DownloadProgressBar.DownloadType.DOWNLOADING_NORMAL + downloadBtn.setOnClickListener { + DownloadManager.getInstance().resume(downloadEntity, false) + } + } + done -> { + if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL)) { + downloadBtn.setText(R.string.browser_install_install) + } else { + downloadBtn.setText(R.string.install) + } + downloadBtn.downloadType = DownloadProgressBar.DownloadType.INSTALL_NORMAL + downloadBtn.setOnClickListener { + PackageInstaller.install(requireContext(), downloadEntity) + } + } + + cancel, + hijack, + notfound, + uncertificated, + unqualified -> { + downloadBtn.text = "下载畅玩助手服务组件" + downloadBtn.downloadType = DownloadProgressBar.DownloadType.NORMAL + downloadBtn.setOnClickListener { + DownloadManager.getInstance().resume(downloadEntity, true) + } + } + else -> { + // do nothing + } + } + } + } + } override fun getRootView(): View = mBinding.root override fun getDragCloseView(): View = mBinding.dragClose + @SuppressLint("ClickableViewAccessibility") + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + return mBinding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val spanBuilder = SpannableStringBuilder() + .append("畅玩是一种更灵活、轻便的游戏方式\n") + .append("下载") + .color(R.color.text_subtitle.toColor()) { bold { append(" 畅玩助手服务组件 ") } } + .append("即可快速畅玩游戏~") + + mBinding.downloadBtn.text = "下载畅玩助手服务组件" + mBinding.downloadBtn.downloadType = DownloadProgressBar.DownloadType.NORMAL + mBinding.descTv.text = spanBuilder + mBinding.downloadBtn.setOnClickListener { + val vSpaceInfo = Config.getVSettingEntity()?.va?.arch32!! + + val downloadEntity = DownloadEntity() + downloadEntity.url = mDownloadUrl + downloadEntity.name = "畅玩助手V" + vSpaceInfo.versionName + downloadEntity.path = FileUtils.getDownloadPath(requireContext(), "畅玩助手V" + vSpaceInfo.versionName + ".apk"); + downloadEntity.platform = "官方版" + downloadEntity.gameId = "" + downloadEntity.packageName = vSpaceInfo.packageName + + DownloadManager.getInstance().cancel(mDownloadUrl, true, true) + DownloadManager.getInstance().pauseAll() + + AppExecutor.uiExecutor.executeWithDelay({ + DownloadManager.getInstance().add(downloadEntity) + }, 200) + } + } + + override fun onResume() { + super.onResume() + DownloadManager.getInstance().addObserver(mDataWatcher) + } + + override fun onPause() { + super.onPause() + DownloadManager.getInstance().removeObserver(mDataWatcher) + } + companion object { @JvmStatic - fun showDownloadDialog(context: Context?, gameEntity: GameEntity, traceEvent: ExposureEvent?, entrance: String?, location: String?) { + fun showDownloadDialog(context: Context?, gameEntity: GameEntity) { val fragmentActivity: FragmentActivity = if (context is FragmentActivity) { context } else { @@ -38,13 +167,14 @@ class VSpaceDialogFragment: BaseDraggableDialogFragment() { val downloadDialog = VSpaceDialogFragment().apply { val bundle = Bundle() - bundle.putString(EntranceUtils.KEY_ENTRANCE, entrance) - bundle.putString(EntranceUtils.KEY_LOCATION, location) bundle.putParcelable(GameEntity::class.java.simpleName, gameEntity) - bundle.putParcelable(EntranceUtils.KEY_TRACE_EVENT, traceEvent) + bundle.putParcelable(EntranceUtils.KEY_TRACE_EVENT, gameEntity.exposureEvent) arguments = bundle } - downloadDialog.show(fragmentActivity.supportFragmentManager, VSpaceDialogFragment::class.java.name) + downloadDialog.show( + fragmentActivity.supportFragmentManager, + VSpaceDialogFragment::class.java.name + ) } private fun hasDialogDisplayedInCurrentActivity(fragmentActivity: FragmentActivity): Boolean { diff --git a/app/src/main/res/drawable/ic_gamedetail_smooth_download_hint.xml b/app/src/main/res/drawable/ic_gamedetail_smooth_download_hint.xml new file mode 100644 index 0000000000..438e44856a --- /dev/null +++ b/app/src/main/res/drawable/ic_gamedetail_smooth_download_hint.xml @@ -0,0 +1,20 @@ + + + + diff --git a/app/src/main/res/layout/dialog_vspace.xml b/app/src/main/res/layout/dialog_vspace.xml index 09ccd94986..a5da088365 100644 --- a/app/src/main/res/layout/dialog_vspace.xml +++ b/app/src/main/res/layout/dialog_vspace.xml @@ -36,6 +36,7 @@ android:lineSpacingExtra="4dp" android:textColor="@color/text_subtitleDesc" android:textSize="14sp" + android:includeFontPadding="false" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/bgView" @@ -65,9 +66,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" + android:includeFontPadding="false" android:text="即点即玩" android:textColor="@color/smooth_feature_font_color" - android:textSize="12sp" /> + android:textSize="@dimen/secondary_size" /> @@ -86,9 +88,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" + android:includeFontPadding="false" android:text="免密安装" android:textColor="@color/smooth_feature_font_color" - android:textSize="12sp" /> + android:textSize="@dimen/secondary_size" /> @@ -107,9 +110,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" + android:includeFontPadding="false" android:text="游戏工具" android:textColor="@color/smooth_feature_font_color" - android:textSize="12sp" /> + android:textSize="@dimen/secondary_size" /> diff --git a/gradle.properties b/gradle.properties index c1170209d7..3a7e9c4aaa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -55,6 +55,8 @@ DEV_API_HOST=https\://dev-and-api.ghzs.com/v5d5d0/ API_HOST=https\://and-api.ghzs.com/v5d5d0/ NEW_DEV_API_HOST=https\://dev-app-api.ghzs.com/ NEW_API_HOST=https\://app-api.ghzs.com/ +DEV_VAPI_HOST=https://dev-app-api.796697.com +VAPI_HOST=https://app-api.796697.com android.useAndroidX=true android.enableJetifier=true diff --git a/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java b/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java index 9d1f9959fa..f7cea9d1d7 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java +++ b/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java @@ -205,6 +205,9 @@ public class Constants { // 补充配置项 public static final String SP_NEW_SETTINGS = "new_settings"; + // 畅玩组件的配置 + public static final String SP_V_SETTINGS = "v_settings"; + // 头像挂件ID public static final String SP_CHOOSE_AVATAR_ID = "choose_avatar_id"; From 2f35e6ac56fa5c03cb0b7d49c4b7235cb6fff324 Mon Sep 17 00:00:00 2001 From: juntao Date: Mon, 16 May 2022 14:48:44 +0800 Subject: [PATCH 010/217] =?UTF-8?q?rebase=20to=205.10.0=20=E5=88=86?= =?UTF-8?q?=E6=94=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/provider/BuildConfigImpl.kt | 3 + .../com/gh/common/util/PackageInstaller.kt | 1 + .../gamecenter/DownloadManagerActivity.java | 1 + .../download/GameDownloadFragmentAdapter.java | 10 ---- .../gamedetail/GameDetailViewModel.kt | 1 + .../com/gh/vspace/LoadCompleteWindowHelper.kt | 8 +-- .../com/gh/vspace/VDownloadManagerAdapter.kt | 11 ++-- .../com/gh/vspace/VDownloadManagerFragment.kt | 10 ++-- .../gh/vspace/VDownloadManagerViewModel.kt | 5 ++ app/src/main/java/com/gh/vspace/VHelper.kt | 57 +++++++++++++------ .../com/gh/vspace/VSpaceDialogFragment.kt | 16 +++--- .../com/gh/vspace/VSpaceLoadingActivity.kt | 4 +- .../com/gh/vspace/VSpaceLoadingFragment.kt | 2 +- .../halo/assistant/fragment/AboutFragment.kt | 1 - .../res/layout/fragment_vspace_loading.xml | 2 +- .../common/callback/ConfirmListener.kt | 2 +- .../gh/gamecenter/common/utils/EnvHelper.kt | 15 +++++ module_common/src/main/res/values/colors.xml | 9 +++ .../core/provider/IBuildConfigProvider.kt | 4 ++ 19 files changed, 108 insertions(+), 54 deletions(-) diff --git a/app/src/main/java/com/gh/common/provider/BuildConfigImpl.kt b/app/src/main/java/com/gh/common/provider/BuildConfigImpl.kt index 9ce6c309f8..d90113b6a4 100644 --- a/app/src/main/java/com/gh/common/provider/BuildConfigImpl.kt +++ b/app/src/main/java/com/gh/common/provider/BuildConfigImpl.kt @@ -28,4 +28,7 @@ class BuildConfigImpl : IBuildConfigProvider { override fun getNewDevApiHost(): String = BuildConfig.NEW_DEV_API_HOST + override fun getVApiHost(): String = BuildConfig.VAPI_HOST + + override fun getVDevApiHost(): String = BuildConfig.DEV_VAPI_HOST } \ No newline at end of file diff --git a/app/src/main/java/com/gh/common/util/PackageInstaller.kt b/app/src/main/java/com/gh/common/util/PackageInstaller.kt index bc74ad50cb..d39b51c0ee 100644 --- a/app/src/main/java/com/gh/common/util/PackageInstaller.kt +++ b/app/src/main/java/com/gh/common/util/PackageInstaller.kt @@ -15,6 +15,7 @@ import com.gh.gamecenter.BuildConfig import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.utils.DialogHelper import com.gh.gamecenter.common.utils.getExtension +import com.gh.gamecenter.common.utils.getMetaExtra import com.gh.gamecenter.common.utils.toRequestBody import com.gh.gamecenter.core.utils.CurrentActivityHolder import com.gh.gamecenter.core.utils.MD5Utils diff --git a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java index 460320c555..d45323822c 100644 --- a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java +++ b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java @@ -5,6 +5,7 @@ import android.content.Intent; import android.os.Bundle; import android.view.MenuItem; +import com.gh.common.util.DirectUtils; import com.gh.gamecenter.common.base.activity.ToolBarActivity; import com.gh.gamecenter.common.base.fragment.BaseFragment_TabLayout; import com.gh.gamecenter.common.constant.EntranceConsts; diff --git a/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java b/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java index aa53cef2d6..cc2db4a942 100644 --- a/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java +++ b/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java @@ -500,16 +500,6 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { // 显示插件化 void showPluginDialog(final String path) { DialogHelper.showPluginDialog(mContext, () -> { - for (DownloadEntity downloadEntity : DownloadManager.getInstance().getAllDownloadEntityExcludeSilentTask()) { - if (downloadEntity.isPluggable() - && downloadEntity.getPath().equals(path)) { - Map kv6 = new HashMap<>(); - kv6.put("操作", "点击插件化安装完成"); - DataUtils.onEvent(mContext, "插件化", downloadEntity.getName(), kv6); - break; - } - } - if (FileUtils.isEmptyFile(path)) { Utils.toast(mContext, R.string.install_failure_hint); } else { diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt index 7356c768ea..3fe77c0435 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt @@ -18,6 +18,7 @@ import com.gh.gamecenter.core.utils.GsonUtils import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.common.utils.singleToMain import com.gh.gamecenter.common.utils.toRequestBody +import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.core.utils.UrlFilterUtils import com.gh.gamecenter.entity.* import com.gh.gamecenter.gamedetail.entity.BigEvent diff --git a/app/src/main/java/com/gh/vspace/LoadCompleteWindowHelper.kt b/app/src/main/java/com/gh/vspace/LoadCompleteWindowHelper.kt index 898efae85a..ac0b2ceaa5 100644 --- a/app/src/main/java/com/gh/vspace/LoadCompleteWindowHelper.kt +++ b/app/src/main/java/com/gh/vspace/LoadCompleteWindowHelper.kt @@ -13,11 +13,11 @@ import androidx.core.view.get import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.widget.ViewPager2 -import com.gh.common.util.ClickUtils -import com.gh.common.util.dip2px -import com.gh.common.util.doOnEnd -import com.gh.common.util.toBinding import com.gh.gamecenter.R +import com.gh.gamecenter.common.utils.dip2px +import com.gh.gamecenter.common.utils.toBinding +import com.gh.gamecenter.core.utils.ClickUtils +import com.gh.gamecenter.core.utils.doOnEnd import com.gh.gamecenter.databinding.ItemFloatGameLoadCompleteBinding import com.gh.gamecenter.databinding.LayoutFloatLoadCompleteBinding import com.gh.gamecenter.entity.GameEntity diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index 36f8ee220c..93f57e9bc4 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -10,16 +10,19 @@ import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.constraintlayout.widget.ConstraintLayout import androidx.recyclerview.widget.RecyclerView -import com.gh.base.CurrentActivityHolder -import com.gh.common.constant.Constants -import com.gh.common.constant.ItemViewType -import com.gh.common.util.* +import com.gh.common.util.DownloadItemUtils +import com.gh.common.util.GameUtils import com.gh.download.DownloadManager import com.gh.gamecenter.GameDetailActivity import com.gh.gamecenter.R import com.gh.gamecenter.adapter.viewholder.FooterViewHolder import com.gh.gamecenter.adapter.viewholder.GameViewHolder import com.gh.gamecenter.baselist.ListAdapter +import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.constant.ItemViewType +import com.gh.gamecenter.common.utils.* +import com.gh.gamecenter.core.utils.CurrentActivityHolder +import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.databinding.PopupHistoryOptionBinding import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.entity.PluginLocation diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index 4b838f58ca..4f658d4a4c 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -6,14 +6,14 @@ import android.view.View import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import com.ethanhua.skeleton.Skeleton -import com.gh.common.util.toColor -import com.gh.common.util.toDrawable -import com.gh.common.util.viewModelProvider -import com.gh.common.view.CustomDividerItemDecoration import com.gh.download.DownloadManager import com.gh.gamecenter.R import com.gh.gamecenter.baselist.ListAdapter import com.gh.gamecenter.baselist.ListFragment +import com.gh.gamecenter.common.utils.toColor +import com.gh.gamecenter.common.utils.toDrawable +import com.gh.gamecenter.common.utils.viewModelProvider +import com.gh.gamecenter.common.view.CustomDividerItemDecoration import com.gh.gamecenter.databinding.FragmentListBaseSkeletonBinding import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.history.IBatchDelete @@ -77,7 +77,7 @@ class VDownloadManagerFragment : override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - mCachedView.setBackgroundColor(R.color.white.toColor()) + mCachedView.setBackgroundColor(R.color.background_white.toColor(requireContext())) mSkeletonScreen = Skeleton.bind(mBinding.listSkeleton).shimmer(false) .load(R.layout.fragment_subject_skeleton).show() } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index beee4dfc74..508bd4169d 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -4,6 +4,7 @@ import android.app.Application import androidx.lifecycle.MutableLiveData import com.gh.download.DownloadManager import com.gh.gamecenter.baselist.ListViewModel +import com.gh.gamecenter.baselist.LoadType import com.gh.gamecenter.entity.ApkEntity import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.history.ManageOption @@ -69,9 +70,13 @@ class VDownloadManagerViewModel(application: Application) : fun removeItem(url: String? , packageName: String?) { DownloadManager.getInstance().cancel(url) VHelper.uninstall(packageName ?: "") + + load(LoadType.REFRESH) } fun removeItems() { + load(LoadType.REFRESH) + // TODO 移除下载任务 and 卸载 VA 安装 } diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index f125748bd4..6b4646f0d1 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -4,12 +4,12 @@ import android.Manifest import android.app.Activity import android.content.Context import android.content.Intent -import com.gh.common.AppExecutor import com.gh.common.constant.Config -import com.gh.common.util.EmptyCallback import com.gh.common.util.PackageUtils -import com.gh.common.util.ToastUtils import com.gh.download.PackageObserver +import com.gh.gamecenter.core.AppExecutor +import com.gh.gamecenter.core.utils.EmptyCallback +import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.eventbus.EBPackage import com.gh.gamecenter.packagehelper.PackageRepository @@ -22,6 +22,7 @@ object VHelper { private const val LOG_TAG = "VSPACE" + private var mIsServiceConnected = false private val mDelegateManager by lazy { VirtualAppManager.get() } private var mInstalledInfoList: List = arrayListOf() @@ -33,15 +34,19 @@ object VHelper { /** * 连接服务 */ - private fun connectService() { + private fun connectService(callbackClosure: (() -> Unit)? = null) { mDelegateManager.connectService(object : RemoteConnectListener { override fun onServiceConnectionSuccessed() { Utils.log(LOG_TAG, "V 服务连接成功") + mIsServiceConnected = true mInstalledInfoList = getInstalledList() PackageRepository.addInstalledGames(getInstalledPackageList()) + + callbackClosure?.invoke() } override fun onServiceConnectionFailed(failCode: Int) { + mIsServiceConnected = false Utils.log(LOG_TAG, "V 服务连接失败") // TODO 重试? } @@ -161,17 +166,31 @@ object VHelper { * 安装新应用 */ fun install(activity: Activity, filePath: String) { - checkStoragePermissionBeforeAction(activity) { - // 安装过程会比较漫长,所以得放在工作线程运行 - AppExecutor.ioExecutor.execute { - val result = VirtualAppManager.get().installGame(filePath) - if (result.status == 0) { - updateInstalledList() - PackageObserver.onPackageChanged(EBPackage("安装", result.packageName, "unknown")) + val installClosure: () -> Unit = { + checkStoragePermissionBeforeAction(activity) { + // 安装过程会比较漫长,所以得放在工作线程运行 + AppExecutor.ioExecutor.execute { + val result = VirtualAppManager.get().installGame(filePath) + if (result.status == 0) { + updateInstalledList() + PackageObserver.onPackageChanged( + EBPackage( + "安装", + result.packageName, + "unknown" + ) + ) + } + Utils.log(LOG_TAG, "安装新应用结果 -> " + result.status) } - Utils.log(LOG_TAG, "安装新应用结果 -> " + result.status) } } + + if (mIsServiceConnected) { + installClosure.invoke() + } else { + connectService(installClosure) + } } /** @@ -193,12 +212,16 @@ object VHelper { * 卸载应用 */ fun uninstall(packageName: String) { - val result = VirtualAppManager.get().uninstallGame(packageName) - if (result) { - updateInstalledList() - PackageObserver.onPackageChanged(EBPackage("卸载", packageName, "unknown")) + try { + val result = VirtualAppManager.get().uninstallGame(packageName) + if (result) { + updateInstalledList() + PackageObserver.onPackageChanged(EBPackage("卸载", packageName, "unknown")) + } + Utils.log(LOG_TAG, "安装新应用结果 -> $result") + } catch (e: Exception) { + ToastUtils.toast(e.localizedMessage ?: "") } - Utils.log(LOG_TAG, "安装新应用结果 -> $result") } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt index 2d9f6af0c7..f756b9c3b3 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt @@ -11,17 +11,17 @@ import androidx.core.text.bold import androidx.core.text.color import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity -import com.gh.common.AppExecutor import com.gh.common.constant.Config -import com.gh.common.constant.Constants -import com.gh.common.dialog.BaseDraggableDialogFragment -import com.gh.common.util.EntranceUtils import com.gh.common.util.PackageInstaller -import com.gh.common.util.SPUtils -import com.gh.common.util.toColor import com.gh.common.view.DownloadProgressBar import com.gh.download.DownloadManager import com.gh.gamecenter.R +import com.gh.gamecenter.common.base.fragment.BaseDraggableDialogFragment +import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.constant.EntranceConsts +import com.gh.gamecenter.common.utils.toColor +import com.gh.gamecenter.core.AppExecutor +import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.databinding.DialogVspaceBinding import com.gh.gamecenter.entity.GameEntity import com.lightgame.download.DataWatcher @@ -112,7 +112,7 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { val spanBuilder = SpannableStringBuilder() .append("畅玩是一种更灵活、轻便的游戏方式\n") .append("下载") - .color(R.color.text_subtitle.toColor()) { bold { append(" 畅玩助手服务组件 ") } } + .color(R.color.text_subtitle.toColor(requireContext())) { bold { append(" 畅玩助手服务组件 ") } } .append("即可快速畅玩游戏~") mBinding.downloadBtn.text = "下载畅玩助手服务组件" @@ -168,7 +168,7 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { val downloadDialog = VSpaceDialogFragment().apply { val bundle = Bundle() bundle.putParcelable(GameEntity::class.java.simpleName, gameEntity) - bundle.putParcelable(EntranceUtils.KEY_TRACE_EVENT, gameEntity.exposureEvent) + bundle.putParcelable(EntranceConsts.KEY_TRACE_EVENT, gameEntity.exposureEvent) arguments = bundle } downloadDialog.show( diff --git a/app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt b/app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt index e5caa2c138..c1dab7be5c 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt @@ -4,8 +4,8 @@ import android.content.Context import android.content.Intent import android.os.Bundle import com.gh.base.BaseActivity -import com.gh.common.util.EntranceUtils import com.gh.gamecenter.R +import com.gh.gamecenter.common.constant.EntranceConsts import com.lightgame.download.DownloadEntity class VSpaceLoadingActivity: BaseActivity() { @@ -23,7 +23,7 @@ class VSpaceLoadingActivity: BaseActivity() { companion object { fun getIntent(context: Context, downloadEntity: DownloadEntity) : Intent { val intent = Intent(context, VSpaceLoadingActivity::class.java) - intent.putExtra(EntranceUtils.KEY_DATA, downloadEntity) + intent.putExtra(EntranceConsts.KEY_DATA, downloadEntity) return intent } } diff --git a/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt index 3db76c9ad7..43c245e26b 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt @@ -1,6 +1,6 @@ package com.gh.vspace -import com.gh.base.fragment.BaseFragment +import com.gh.gamecenter.common.base.fragment.BaseFragment import com.gh.gamecenter.databinding.FragmentVspaceLoadingBinding class VSpaceLoadingFragment: BaseFragment() { diff --git a/app/src/main/java/com/halo/assistant/fragment/AboutFragment.kt b/app/src/main/java/com/halo/assistant/fragment/AboutFragment.kt index 139c2bc836..6f5da8e0f6 100644 --- a/app/src/main/java/com/halo/assistant/fragment/AboutFragment.kt +++ b/app/src/main/java/com/halo/assistant/fragment/AboutFragment.kt @@ -26,7 +26,6 @@ import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.MtaHelper.onEvent import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.core.utils.StringUtils -import com.gh.gamecenter.core.utils.TimeUtils.getFormatTime import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.databinding.FragmentAboutBinding import com.gh.gamecenter.manager.UpdateManager diff --git a/app/src/main/res/layout/fragment_vspace_loading.xml b/app/src/main/res/layout/fragment_vspace_loading.xml index 4d4dfa7e56..fd280053bf 100644 --- a/app/src/main/res/layout/fragment_vspace_loading.xml +++ b/app/src/main/res/layout/fragment_vspace_loading.xml @@ -6,7 +6,7 @@ android:layout_height="match_parent" android:background="@color/white"> - #33000000 + + #1A2496FF + #0D000000 + @color/theme + @color/text_4BC7FF + #0D000000 + @color/white @@ -176,6 +183,8 @@ #b3b3b3 + #8CA0B8 + #aaaaaa #AAAAAA diff --git a/module_core/src/main/java/com/gh/gamecenter/core/provider/IBuildConfigProvider.kt b/module_core/src/main/java/com/gh/gamecenter/core/provider/IBuildConfigProvider.kt index f073666036..03a7aeab64 100644 --- a/module_core/src/main/java/com/gh/gamecenter/core/provider/IBuildConfigProvider.kt +++ b/module_core/src/main/java/com/gh/gamecenter/core/provider/IBuildConfigProvider.kt @@ -18,4 +18,8 @@ interface IBuildConfigProvider : IProvider { fun getNewApiHost(): String fun getNewDevApiHost(): String + + fun getVApiHost(): String + + fun getVDevApiHost(): String } \ No newline at end of file From 417633b6237de6e2f842e91e296ee14dfe5a59dd Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 17 May 2022 18:24:27 +0800 Subject: [PATCH 011/217] =?UTF-8?q?=E8=B0=83=E6=95=B4=E9=83=A8=E5=88=86?= =?UTF-8?q?=E7=82=B9=E5=87=BB=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/common/util/DetailDownloadUtils.java | 12 ++- .../java/com/gh/common/util/GameUtils.java | 4 - .../java/com/gh/download/PackageObserver.kt | 20 +++++ .../com/gh/vspace/VDownloadManagerActivity.kt | 2 +- .../com/gh/vspace/VDownloadManagerFragment.kt | 34 -------- .../gh/vspace/VDownloadManagerViewModel.kt | 4 - .../vspace/VDownloadManagerWrapperFragment.kt | 82 +++++++++++++++++++ .../VDownloadManagerWrapperViewModel.kt | 11 +++ app/src/main/java/com/gh/vspace/VHelper.kt | 61 ++++++++++---- .../com/gh/vspace/VSpaceDialogFragment.kt | 58 +++++++++---- .../com/gh/vspace/VSpaceLoadingFragment.kt | 1 - .../res/layout/activity_help_and_feedback.xml | 1 + .../main/res/layout/activity_poster_edit.xml | 1 + .../main/res/layout/activity_video_game.xml | 1 + .../main/res/layout/dialog_choose_forum.xml | 1 + .../res/layout/fragment_ask_questions.xml | 1 + .../res/layout/fragment_avatar_border.xml | 1 + .../main/res/layout/fragment_community.xml | 1 + .../res/layout/fragment_community_home.xml | 1 + .../res/layout/fragment_energy_center.xml | 1 + .../main/res/layout/fragment_energy_house.xml | 1 + .../layout/fragment_forum_video_detail.xml | 1 + app/src/main/res/layout/fragment_home.xml | 1 + .../main/res/layout/fragment_home_video.xml | 1 + .../res/layout/fragment_libao_wrapper.xml | 1 + ...ragment_no_padding_tablayout_viewpager.xml | 1 + .../res/layout/fragment_simulator_game.xml | 1 + .../main/res/layout/fragment_subject_tab.xml | 1 + app/src/main/res/layout/gamedetail_body.xml | 1 + .../activity_tablayout_no_title_viewpager.xml | 1 + .../layout/activity_tablayout_viewpager.xml | 1 + .../layout/fragment_tablayout_viewpager.xml | 1 + 32 files changed, 232 insertions(+), 78 deletions(-) create mode 100644 app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt create mode 100644 app/src/main/java/com/gh/vspace/VDownloadManagerWrapperViewModel.kt diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index a497ff04f1..bc7807a2ab 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -111,6 +111,9 @@ public class DetailDownloadUtils { downloadText = status + getDownloadSizeText(viewHolder); } else if (viewHolder.context.getString(R.string.install).equals(status)) { downloadText = viewHolder.context.getString(R.string.install); + } else if (viewHolder.context.getString(R.string.download).equals(status) + && VHelper.isVGame(viewHolder.gameEntity)) { + downloadText = viewHolder.context.getString(R.string.smooth_launch); } else { downloadText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : downloadAddWord) + getDownloadSizeText(viewHolder); } @@ -187,8 +190,13 @@ public class DetailDownloadUtils { viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL); } } else if (VHelper.isVGame(viewHolder.gameEntity)) { - viewHolder.mDownloadPb.setText(R.string.smooth_launch); - viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.LAUNCH_OR_OPEN); + if (VHelper.isInstalled(downloadEntity.getPackageName())) { + viewHolder.mDownloadPb.setText(R.string.smooth_launch); + viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.LAUNCH_OR_OPEN); + } else { + viewHolder.mDownloadPb.setText(R.string.smooth_launch); + viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL); + } } else { if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL)) { viewHolder.mDownloadPb.setText(R.string.browser_install_install); diff --git a/app/src/main/java/com/gh/common/util/GameUtils.java b/app/src/main/java/com/gh/common/util/GameUtils.java index a4c707635d..4d32d6935b 100644 --- a/app/src/main/java/com/gh/common/util/GameUtils.java +++ b/app/src/main/java/com/gh/common/util/GameUtils.java @@ -148,10 +148,6 @@ public class GameUtils { return context.getString(R.string.launch); } - if ("smooth".equals(gameEntity.getDownloadStatus())) { - return context.getString(R.string.smooth); - } - if (doneCount != 0) { return context.getString(R.string.install); } else if (pluginCount != 0 && !SimulatorGameManager.isSimulatorGame(gameEntity)) { diff --git a/app/src/main/java/com/gh/download/PackageObserver.kt b/app/src/main/java/com/gh/download/PackageObserver.kt index cbed3f39c2..04a8c93dd8 100644 --- a/app/src/main/java/com/gh/download/PackageObserver.kt +++ b/app/src/main/java/com/gh/download/PackageObserver.kt @@ -8,6 +8,8 @@ import com.gh.gamecenter.common.loghub.LoghubUtils import com.gh.gamecenter.core.runOnIoThread import com.gh.common.util.* import com.gh.download.server.BrowserInstallHelper +import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.core.utils.ThirdPartyPackageHelper import com.gh.gamecenter.core.utils.UrlFilterUtils import com.gh.gamecenter.entity.GameDigestEntity @@ -34,6 +36,16 @@ object PackageObserver { private val mPackageViewModel: PackageViewModel by lazy { PackageViewModel(HaloApp.getInstance().application, PackageRepository) } + private val mPackageChangeListenerList: ArrayList = arrayListOf() + + fun registerPackageChangeChangeListener(listener: PackageChangeListener) { + mPackageChangeListenerList.add(listener) + } + + fun unregisterPackageChangeChangeListener(listener: PackageChangeListener) { + mPackageChangeListenerList.remove(listener) + } + @JvmStatic fun onPackageChanged(busFour: EBPackage) { val application = HaloApp.getInstance().application @@ -121,6 +133,11 @@ object PackageObserver { // 更新已安装游戏 deleteInstalledPackage(packageName) } + + for (packageChangeListener in mPackageChangeListenerList) { + packageChangeListener.onChanged(busFour) + } + DataCollectionUtils.uploadInorunstall(application, busFour.type, busFour.packageName) } @@ -181,6 +198,9 @@ object PackageObserver { e.printStackTrace() } LoghubUtils.log(wrapperObject, "halo-api-device-installed", true) + } + fun interface PackageChangeListener { + fun onChanged(data:EBPackage) } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt index 4db3f9d99d..5bbd5ed6b3 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt @@ -10,7 +10,7 @@ class VDownloadManagerActivity: ToolBarActivity() { super.onCreate(savedInstanceState) if (savedInstanceState == null) { - supportFragmentManager.beginTransaction().replace(R.id.placeholder, VDownloadManagerFragment()).commitAllowingStateLoss() + supportFragmentManager.beginTransaction().replace(R.id.placeholder, VDownloadManagerWrapperFragment()).commitAllowingStateLoss() } } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index 4f658d4a4c..cb1c7cc091 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -1,9 +1,7 @@ package com.gh.vspace import android.os.Bundle -import android.view.MenuItem import android.view.View -import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import com.ethanhua.skeleton.Skeleton import com.gh.download.DownloadManager @@ -24,8 +22,6 @@ import com.lightgame.download.DownloadEntity class VDownloadManagerFragment : ListFragment(), IBatchDelete { - private var mManageMenu: MenuItem? = null - private val mAdapter by lazy { VDownloadManagerAdapter(requireContext(), provideListViewModel()) } private val mViewModel: VDownloadManagerViewModel by lazy { viewModelProvider() } private val mBinding by lazy { FragmentListBaseSkeletonBinding.inflate(layoutInflater) } @@ -43,25 +39,6 @@ class VDownloadManagerFragment : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - - initMenu(R.menu.menu_manage) - mManageMenu = getItemMenu(R.id.layout_menu_manage) - mManageMenu?.actionView?.setOnClickListener { - when (mViewModel.currentOptionLiveData.value) { - ManageOption.OPTION_MANAGER -> { - mViewModel.currentOptionLiveData.value = ManageOption.OPTION_CANCEL_SELECT - } - ManageOption.OPTION_CANCEL_SELECT -> { - mViewModel.currentOptionLiveData.value = ManageOption.OPTION_MANAGER - } - } - changeOption(mViewModel.currentOptionLiveData.value ?: ManageOption.OPTION_MANAGER) - } - changeMenuTextByOption() - - mViewModel.currentOptionLiveData.observe(this) { - changeMenuTextByOption() - } } override fun onResume() { @@ -84,7 +61,6 @@ class VDownloadManagerFragment : override fun changeOption(option: ManageOption) { mAdapter.changeOption(option) - changeMenuTextByOption() } override fun getItemDecoration(): RecyclerView.ItemDecoration { @@ -101,14 +77,4 @@ class VDownloadManagerFragment : override fun shouldLoadMore() = false - private fun changeMenuTextByOption() { - (mManageMenu?.actionView as? TextView)?.apply { - text = when (mViewModel.currentOptionLiveData.value) { - ManageOption.OPTION_MANAGER -> "编辑" - ManageOption.OPTION_CANCEL_SELECT -> "取消" - else -> "" - } - } - } - } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index 508bd4169d..fcd1646b58 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -1,13 +1,11 @@ package com.gh.vspace import android.app.Application -import androidx.lifecycle.MutableLiveData import com.gh.download.DownloadManager import com.gh.gamecenter.baselist.ListViewModel import com.gh.gamecenter.baselist.LoadType import com.gh.gamecenter.entity.ApkEntity import com.gh.gamecenter.entity.GameEntity -import com.gh.gamecenter.history.ManageOption import com.gh.gamecenter.packagehelper.PackageRepository import com.lightgame.download.DownloadEntity import io.reactivex.Observable @@ -16,8 +14,6 @@ import io.reactivex.Single class VDownloadManagerViewModel(application: Application) : ListViewModel(application) { - var currentOptionLiveData = MutableLiveData(ManageOption.OPTION_MANAGER) - override fun mergeResultLiveData() { mResultLiveData.addSource(mListLiveData) { mResultLiveData.postValue(it) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt new file mode 100644 index 0000000000..b224ffe9cc --- /dev/null +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt @@ -0,0 +1,82 @@ +package com.gh.vspace + +import android.os.Bundle +import android.view.MenuItem +import android.view.View +import android.widget.TextView +import androidx.fragment.app.Fragment +import com.gh.gamecenter.R +import com.gh.gamecenter.common.base.fragment.BaseLazyTabFragment +import com.gh.gamecenter.common.utils.viewModelProvider +import com.gh.gamecenter.history.IBatchDelete +import com.gh.gamecenter.history.ManageOption + +class VDownloadManagerWrapperFragment: BaseLazyTabFragment() { + + private var mLastPosition = 0 + private var mManageMenu: MenuItem? = null + private val mViewModel: VDownloadManagerWrapperViewModel by lazy { viewModelProvider() } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + initMenu(R.menu.menu_manage) + mManageMenu = getItemMenu(R.id.layout_menu_manage) + mManageMenu?.actionView?.setOnClickListener { + when (mViewModel.currentOptionLiveData.value) { + ManageOption.OPTION_MANAGER -> { + mViewModel.currentOptionLiveData.value = ManageOption.OPTION_CANCEL_SELECT + } + ManageOption.OPTION_CANCEL_SELECT -> { + mViewModel.currentOptionLiveData.value = ManageOption.OPTION_MANAGER + } + } + changeOption() + } + changeMenuTextByOption() + } + + override fun initFragmentList(fragments: MutableList) { + fragments.add(VDownloadManagerFragment()) + fragments.add(VDownloadManagerFragment()) + } + + override fun initTabTitleList(tabTitleList: MutableList) { + tabTitleList.add("在玩") + tabTitleList.add("下载") + } + + override fun onPageSelected(position: Int) { + super.onPageSelected(position) + mViewModel.currentOptionLiveData.value = ManageOption.OPTION_MANAGER + changeOption() + mLastPosition = position + } + + private fun changeMenuTextByOption() { + (mManageMenu?.actionView as? TextView)?.apply { + text = when (mViewModel.currentOptionLiveData.value) { + ManageOption.OPTION_MANAGER -> "管理" + ManageOption.OPTION_CANCEL_SELECT -> "取消" + else -> "" + } + } + } + + fun changeOption() { + val fragments = childFragmentManager.fragments + mViewModel.currentOptionLiveData.value?.let { + fragments.forEachIndexed { index, fragment -> + if (fragment is IBatchDelete) { + if (index == mViewPager.currentItem) { + fragment.changeOption(it) + } else if (index == mLastPosition) { + fragment.changeOption(ManageOption.OPTION_MANAGER) + } + } + } + } + changeMenuTextByOption() + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperViewModel.kt new file mode 100644 index 0000000000..81245de082 --- /dev/null +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperViewModel.kt @@ -0,0 +1,11 @@ +package com.gh.vspace + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.gh.gamecenter.history.ManageOption + +class VDownloadManagerWrapperViewModel : ViewModel() { + + var currentOptionLiveData = MutableLiveData(ManageOption.OPTION_MANAGER) + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 6b4646f0d1..e07b0b6e1d 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -22,13 +22,27 @@ object VHelper { private const val LOG_TAG = "VSPACE" - private var mIsServiceConnected = false private val mDelegateManager by lazy { VirtualAppManager.get() } private var mInstalledInfoList: List = arrayListOf() + private val mPackageObserver by lazy { + PackageObserver.PackageChangeListener { + val vaConfig = Config.getVSettingEntity()?.va ?: return@PackageChangeListener + val isVSpace = it.packageName == vaConfig.arch32?.packageName || it.packageName == vaConfig.arch64?.packageName + + if (!isVSpace) return@PackageChangeListener + + if (it.type == "安装") { + connectService() + } else if (it.type == "卸载") { + // TODO 执行卸载逻辑 + } + } + } @JvmStatic fun init() { connectService() + PackageObserver.registerPackageChangeChangeListener(mPackageObserver) } /** @@ -38,7 +52,6 @@ object VHelper { mDelegateManager.connectService(object : RemoteConnectListener { override fun onServiceConnectionSuccessed() { Utils.log(LOG_TAG, "V 服务连接成功") - mIsServiceConnected = true mInstalledInfoList = getInstalledList() PackageRepository.addInstalledGames(getInstalledPackageList()) @@ -46,7 +59,6 @@ object VHelper { } override fun onServiceConnectionFailed(failCode: Int) { - mIsServiceConnected = false Utils.log(LOG_TAG, "V 服务连接失败") // TODO 重试? } @@ -70,6 +82,14 @@ object VHelper { return gameEntity?.downloadStatus == "smooth" } + /** + * 是否在 V 空间里已安装此包名游戏 + */ + @JvmStatic + fun isInstalled(packageName: String?): Boolean { + return mInstalledInfoList.any { it.packageName == packageName } + } + /** * 在执行 callback 前先检查组件是否已安装,是否可下载 */ @@ -91,7 +111,7 @@ object VHelper { // val isArch64Installed = PackageUtils.isInstalled(context, Config.getVSettingEntity()?.va?.arch64?.packageName) if (!isArch32Installed) { - VSpaceDialogFragment.showDownloadDialog(context, gameEntity) + VSpaceDialogFragment.showDownloadDialog(context) return } @@ -131,10 +151,17 @@ object VHelper { * 获取已安装列表信息 (每次调用都会生成一份新的副本,放心使用) */ fun getInstalledList(): ArrayList { - val list = mDelegateManager.installedGamesInfo - Utils.log(LOG_TAG, "已安装应用数量${list.size}") + var list: List = arrayListOf() - return ArrayList(mDelegateManager.installedGamesInfo) + try { + list = mDelegateManager.installedGamesInfo + + Utils.log(LOG_TAG, "已安装应用数量${list.size}") + } catch (e: Exception) { + Utils.log(LOG_TAG, "获取已安装应用数量异常 ${e.localizedMessage}") + } + + return ArrayList(list) } /** @@ -158,7 +185,7 @@ object VHelper { } } catch (e: RuntimeException) { e.printStackTrace() - Utils.log(LOG_TAG, "检查存储权限失败") + Utils.log(LOG_TAG, "检查存储权限失败 ${e.localizedMessage}") } } @@ -173,20 +200,13 @@ object VHelper { val result = VirtualAppManager.get().installGame(filePath) if (result.status == 0) { updateInstalledList() - PackageObserver.onPackageChanged( - EBPackage( - "安装", - result.packageName, - "unknown" - ) - ) } Utils.log(LOG_TAG, "安装新应用结果 -> " + result.status) } } } - if (mIsServiceConnected) { + if (mDelegateManager.isConnectAidlInterface) { installClosure.invoke() } else { connectService(installClosure) @@ -199,6 +219,15 @@ object VHelper { @JvmStatic fun launch(activity: Activity, packageName: String) { Utils.log(LOG_TAG, "打开应用$packageName") + + val vaConfig = Config.getVSettingEntity()?.va ?: return + + // TODO 检测 64 位 + if (!PackageUtils.isInstalled(activity, vaConfig.arch32?.packageName)) { + VSpaceDialogFragment.showDownloadDialog(activity) + return + } + try { val intent = mDelegateManager.getStartGameIntent(packageName) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) diff --git a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt index f756b9c3b3..284bfbb234 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt @@ -11,19 +11,22 @@ import androidx.core.text.bold import androidx.core.text.color import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel import com.gh.common.constant.Config import com.gh.common.util.PackageInstaller import com.gh.common.view.DownloadProgressBar import com.gh.download.DownloadManager +import com.gh.download.PackageObserver import com.gh.gamecenter.R import com.gh.gamecenter.common.base.fragment.BaseDraggableDialogFragment import com.gh.gamecenter.common.constant.Constants -import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.toColor +import com.gh.gamecenter.common.utils.viewModelProvider import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.databinding.DialogVspaceBinding -import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.eventbus.EBPackage import com.lightgame.download.DataWatcher import com.lightgame.download.DownloadEntity import com.lightgame.download.DownloadStatus.* @@ -109,6 +112,15 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + val mViewModel = viewModelProvider() + mViewModel.packageLiveData.observe(this) { + if (it.packageName == Config.getVSettingEntity()?.va?.arch32?.packageName + && it.type == "安装" + ) { + dismissAllowingStateLoss() + } + } + val spanBuilder = SpannableStringBuilder() .append("畅玩是一种更灵活、轻便的游戏方式\n") .append("下载") @@ -120,6 +132,8 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { mBinding.descTv.text = spanBuilder mBinding.downloadBtn.setOnClickListener { val vSpaceInfo = Config.getVSettingEntity()?.va?.arch32!! + val name = "畅玩助手V" + vSpaceInfo.versionName + val downloadId = PackageInstaller.createDownloadId(name) val downloadEntity = DownloadEntity() downloadEntity.url = mDownloadUrl @@ -127,30 +141,28 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { downloadEntity.path = FileUtils.getDownloadPath(requireContext(), "畅玩助手V" + vSpaceInfo.versionName + ".apk"); downloadEntity.platform = "官方版" downloadEntity.gameId = "" + downloadEntity.path = PackageInstaller.getDownloadPathWithId(downloadId, "apk") downloadEntity.packageName = vSpaceInfo.packageName - DownloadManager.getInstance().cancel(mDownloadUrl, true, true) - DownloadManager.getInstance().pauseAll() - AppExecutor.uiExecutor.executeWithDelay({ DownloadManager.getInstance().add(downloadEntity) }, 200) } } - override fun onResume() { - super.onResume() + override fun onStart() { + super.onStart() DownloadManager.getInstance().addObserver(mDataWatcher) } - override fun onPause() { - super.onPause() + override fun onStop() { + super.onStop() DownloadManager.getInstance().removeObserver(mDataWatcher) } companion object { @JvmStatic - fun showDownloadDialog(context: Context?, gameEntity: GameEntity) { + fun showDownloadDialog(context: Context?) { val fragmentActivity: FragmentActivity = if (context is FragmentActivity) { context } else { @@ -165,12 +177,7 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { // 防止重复弹出 if (hasDialogDisplayedInCurrentActivity(fragmentActivity)) return - val downloadDialog = VSpaceDialogFragment().apply { - val bundle = Bundle() - bundle.putParcelable(GameEntity::class.java.simpleName, gameEntity) - bundle.putParcelable(EntranceConsts.KEY_TRACE_EVENT, gameEntity.exposureEvent) - arguments = bundle - } + val downloadDialog = VSpaceDialogFragment() downloadDialog.show( fragmentActivity.supportFragmentManager, VSpaceDialogFragment::class.java.name @@ -186,4 +193,23 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { } } + internal class VSpaceDialogViewModel: ViewModel() { + val packageLiveData = MutableLiveData() + private val mPackageChangedListener by lazy { + PackageObserver.PackageChangeListener { + packageLiveData.postValue(it) + } + } + + init { + PackageObserver.registerPackageChangeChangeListener(mPackageChangedListener) + } + + override fun onCleared() { + super.onCleared() + + PackageObserver.unregisterPackageChangeChangeListener(mPackageChangedListener) + } + } + } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt index 43c245e26b..9ccc033c17 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt @@ -12,5 +12,4 @@ class VSpaceLoadingFragment: BaseFragment() { - } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_help_and_feedback.xml b/app/src/main/res/layout/activity_help_and_feedback.xml index 62dbbcd688..eae7fd61a1 100644 --- a/app/src/main/res/layout/activity_help_and_feedback.xml +++ b/app/src/main/res/layout/activity_help_and_feedback.xml @@ -31,6 +31,7 @@ android:id="@+id/activity_tab_layout" android:layout_width="match_parent" android:layout_height="@dimen/tab_layout_height" + app:tabIndicator="@null" app:tabTextAppearance="@style/TabLayoutTextAppearance" /> diff --git a/app/src/main/res/layout/activity_poster_edit.xml b/app/src/main/res/layout/activity_poster_edit.xml index 540417a7a9..61047d1d48 100644 --- a/app/src/main/res/layout/activity_poster_edit.xml +++ b/app/src/main/res/layout/activity_poster_edit.xml @@ -89,6 +89,7 @@ android:id="@+id/activity_tab_layout" android:layout_width="match_parent" android:layout_height="match_parent" + app:tabIndicator="@null" app:tabTextAppearance="@style/TabLayoutTextAppearance" /> diff --git a/app/src/main/res/layout/activity_video_game.xml b/app/src/main/res/layout/activity_video_game.xml index 13a8c7d922..fa7940f7a1 100644 --- a/app/src/main/res/layout/activity_video_game.xml +++ b/app/src/main/res/layout/activity_video_game.xml @@ -153,6 +153,7 @@ app:tabIndicatorHeight="0dp" app:tabMode="fixed" app:tabSelectedTextColor="@color/theme_font" + app:tabIndicator="@null" app:tabTextAppearance="@style/TabLayoutTextAppearance" /> diff --git a/app/src/main/res/layout/dialog_choose_forum.xml b/app/src/main/res/layout/dialog_choose_forum.xml index a06364832f..782fba54dd 100644 --- a/app/src/main/res/layout/dialog_choose_forum.xml +++ b/app/src/main/res/layout/dialog_choose_forum.xml @@ -90,6 +90,7 @@ android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="@dimen/tab_layout_height" + app:tabIndicator="@null" app:tabTextAppearance="@style/TabLayoutNormalTextAppearance" /> diff --git a/app/src/main/res/layout/fragment_ask_questions.xml b/app/src/main/res/layout/fragment_ask_questions.xml index 7efa64b9db..2bb5bfc4e4 100644 --- a/app/src/main/res/layout/fragment_ask_questions.xml +++ b/app/src/main/res/layout/fragment_ask_questions.xml @@ -19,6 +19,7 @@ diff --git a/app/src/main/res/layout/fragment_avatar_border.xml b/app/src/main/res/layout/fragment_avatar_border.xml index a7b2bf458e..9650609eb0 100644 --- a/app/src/main/res/layout/fragment_avatar_border.xml +++ b/app/src/main/res/layout/fragment_avatar_border.xml @@ -136,6 +136,7 @@ app:tabPaddingEnd="0dp" app:tabIndicatorHeight="0dp" app:tabMode="scrollable" + app:tabIndicator="@null" app:tabRippleColor="@color/transparent" /> diff --git a/app/src/main/res/layout/fragment_community.xml b/app/src/main/res/layout/fragment_community.xml index 025a625ef7..42db6872ed 100644 --- a/app/src/main/res/layout/fragment_community.xml +++ b/app/src/main/res/layout/fragment_community.xml @@ -108,6 +108,7 @@ android:id="@+id/fragment_tab_layout" android:layout_width="match_parent" android:layout_height="match_parent" + app:tabIndicator="@null" app:tabTextAppearance="@style/TabLayoutTextAppearance" /> diff --git a/app/src/main/res/layout/fragment_community_home.xml b/app/src/main/res/layout/fragment_community_home.xml index 0819f27234..4f2d34ac78 100644 --- a/app/src/main/res/layout/fragment_community_home.xml +++ b/app/src/main/res/layout/fragment_community_home.xml @@ -57,6 +57,7 @@ app:tabMaxWidth="0dp" app:tabMinWidth="0dp" app:tabMode="scrollable" + app:tabIndicator="@null" app:tabTextAppearance="@style/TabLayoutTextAppearance" /> diff --git a/app/src/main/res/layout/fragment_energy_center.xml b/app/src/main/res/layout/fragment_energy_center.xml index df89218e7f..2c70744875 100644 --- a/app/src/main/res/layout/fragment_energy_center.xml +++ b/app/src/main/res/layout/fragment_energy_center.xml @@ -118,6 +118,7 @@ android:layout_height="44dp" app:tabMaxWidth="0dp" app:tabMode="fixed" + app:tabIndicator="@null" app:tabTextAppearance="@style/TabLayoutTextAppearance" /> diff --git a/app/src/main/res/layout/fragment_energy_house.xml b/app/src/main/res/layout/fragment_energy_house.xml index 89207c0c33..1386295fb5 100644 --- a/app/src/main/res/layout/fragment_energy_house.xml +++ b/app/src/main/res/layout/fragment_energy_house.xml @@ -216,6 +216,7 @@ app:tabMaxWidth="0dp" app:tabMinWidth="0dp" app:tabMode="scrollable" + app:tabIndicator="@null" app:tabTextAppearance="@style/TabLayoutTextAppearance" /> diff --git a/app/src/main/res/layout/fragment_forum_video_detail.xml b/app/src/main/res/layout/fragment_forum_video_detail.xml index d2220a6710..3e4548f505 100644 --- a/app/src/main/res/layout/fragment_forum_video_detail.xml +++ b/app/src/main/res/layout/fragment_forum_video_detail.xml @@ -161,6 +161,7 @@ android:id="@+id/fragment_tab_layout" android:layout_width="match_parent" android:layout_height="@dimen/tab_layout_height" + app:tabIndicator="@null" app:tabTextAppearance="@style/TabLayoutTextAppearance" /> diff --git a/app/src/main/res/layout/fragment_no_padding_tablayout_viewpager.xml b/app/src/main/res/layout/fragment_no_padding_tablayout_viewpager.xml index 2aaa165b03..1086fe34d1 100644 --- a/app/src/main/res/layout/fragment_no_padding_tablayout_viewpager.xml +++ b/app/src/main/res/layout/fragment_no_padding_tablayout_viewpager.xml @@ -23,6 +23,7 @@ android:layout_height="@dimen/tab_layout_height" app:tabPaddingEnd="0dp" app:tabPaddingStart="0dp" + app:tabIndicator="@null" app:tabTextAppearance="@style/TabLayoutTextAppearance" /> diff --git a/app/src/main/res/layout/fragment_simulator_game.xml b/app/src/main/res/layout/fragment_simulator_game.xml index ad72db0dc6..47075daf76 100644 --- a/app/src/main/res/layout/fragment_simulator_game.xml +++ b/app/src/main/res/layout/fragment_simulator_game.xml @@ -27,6 +27,7 @@ android:layout_width="match_parent" android:layout_height="@dimen/tab_layout_height" app:tabMode="scrollable" + app:tabIndicator="@null" app:tabTextAppearance="@style/TabLayoutTextAppearance" /> diff --git a/app/src/main/res/layout/fragment_subject_tab.xml b/app/src/main/res/layout/fragment_subject_tab.xml index 87fb7d4f7a..097340550d 100644 --- a/app/src/main/res/layout/fragment_subject_tab.xml +++ b/app/src/main/res/layout/fragment_subject_tab.xml @@ -35,6 +35,7 @@ app:tabIndicatorHeight="0dp" app:tabRippleColor="@color/transparent" app:tabSelectedTextColor="@color/theme" + app:tabIndicator="@null" app:tabTextAppearance="@style/TabLayoutTextAppearance" /> diff --git a/app/src/main/res/layout/gamedetail_body.xml b/app/src/main/res/layout/gamedetail_body.xml index d731de90e6..c030b1acd1 100644 --- a/app/src/main/res/layout/gamedetail_body.xml +++ b/app/src/main/res/layout/gamedetail_body.xml @@ -283,6 +283,7 @@ android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="@dimen/tab_layout_height" + app:tabIndicator="@null" app:tabTextAppearance="@style/TabLayoutTextAppearance" /> diff --git a/module_common/src/main/res/layout/activity_tablayout_no_title_viewpager.xml b/module_common/src/main/res/layout/activity_tablayout_no_title_viewpager.xml index 683509cfdd..b998419b5c 100644 --- a/module_common/src/main/res/layout/activity_tablayout_no_title_viewpager.xml +++ b/module_common/src/main/res/layout/activity_tablayout_no_title_viewpager.xml @@ -52,6 +52,7 @@ android:id="@+id/activity_tab_layout" android:layout_width="match_parent" android:layout_height="match_parent" + app:tabIndicator="@null" app:tabTextAppearance="@style/TabLayoutTextAppearance" /> diff --git a/module_common/src/main/res/layout/activity_tablayout_viewpager.xml b/module_common/src/main/res/layout/activity_tablayout_viewpager.xml index 90564023b4..adefd87de9 100644 --- a/module_common/src/main/res/layout/activity_tablayout_viewpager.xml +++ b/module_common/src/main/res/layout/activity_tablayout_viewpager.xml @@ -23,6 +23,7 @@ android:id="@+id/activity_tab_layout" android:layout_width="match_parent" android:layout_height="@dimen/tab_layout_height" + app:tabIndicator="@null" app:tabTextAppearance="@style/TabLayoutTextAppearance" /> diff --git a/module_common/src/main/res/layout/fragment_tablayout_viewpager.xml b/module_common/src/main/res/layout/fragment_tablayout_viewpager.xml index 3013f31f6c..52571a97de 100644 --- a/module_common/src/main/res/layout/fragment_tablayout_viewpager.xml +++ b/module_common/src/main/res/layout/fragment_tablayout_viewpager.xml @@ -21,6 +21,7 @@ android:id="@+id/fragment_tab_layout" android:layout_width="match_parent" android:layout_height="@dimen/tab_layout_height" + app:tabIndicator="@null" app:tabTextAppearance="@style/TabLayoutTextAppearance" /> From 97219323d3f5e3cfba3542a633fcf77d42c2d408 Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 19 May 2022 17:23:19 +0800 Subject: [PATCH 012/217] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=83=A8=E5=88=86?= =?UTF-8?q?=E7=AE=80=E9=99=8B=E7=9A=84=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/util/DownloadItemUtils.kt | 5 +- .../java/com/gh/common/util/GameUtils.java | 9 +- .../gamedetail/GameDetailViewModel.kt | 16 +- .../com/gh/vspace/VDownloadManagerAdapter.kt | 5 +- .../com/gh/vspace/VDownloadManagerFragment.kt | 34 +++- .../gh/vspace/VDownloadManagerViewModel.kt | 73 +++++--- .../vspace/VDownloadManagerWrapperFragment.kt | 17 +- .../com/gh/vspace/VFeedbackDialogFragment.kt | 165 ++++++++++++++++++ .../gh/vspace/VFeedbackSuppressedSimpleDao.kt | 11 ++ app/src/main/java/com/gh/vspace/VHelper.kt | 2 +- .../res/drawable-xxxhdpi/bg_vspace_banner.png | Bin 0 -> 17521 bytes .../ic_vgame_dialog_close.png | Bin 0 -> 710 bytes .../drawable-xxxhdpi/ic_vgame_recent_hint.png | Bin 0 -> 1541 bytes .../drawable-xxxhdpi/ic_vgame_update_hint.png | Bin 0 -> 5861 bytes .../res/drawable-xxxhdpi/ic_vspace_logo.png | Bin 0 -> 29511 bytes .../bg_game_collection_tag_select.xml | 2 +- .../main/res/drawable/bg_original_label.xml | 2 +- .../main/res/drawable/bg_vfeedback_label.xml | 6 + .../drawable/bg_vfeedback_label_selected.xml | 5 + .../drawable/button_round_2496ff_alpha_10.xml | 2 +- .../main/res/layout/dialog_vgame_feedback.xml | 140 +++++++++++++++ .../res/layout/fragment_vdownload_manager.xml | 77 ++++++++ .../fragment_vdownload_manager_wrapper.xml | 58 ++++++ app/src/main/res/layout/item_home_vgame.xml | 6 + .../main/res/layout/item_vfeedback_option.xml | 24 +++ .../gamecenter/common/constant/Constants.java | 3 + module_common/src/main/res/values/colors.xml | 1 + 27 files changed, 615 insertions(+), 48 deletions(-) create mode 100644 app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt create mode 100644 app/src/main/java/com/gh/vspace/VFeedbackSuppressedSimpleDao.kt create mode 100644 app/src/main/res/drawable-xxxhdpi/bg_vspace_banner.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_vgame_dialog_close.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_vgame_recent_hint.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_vgame_update_hint.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_vspace_logo.png create mode 100644 app/src/main/res/drawable/bg_vfeedback_label.xml create mode 100644 app/src/main/res/drawable/bg_vfeedback_label_selected.xml create mode 100644 app/src/main/res/layout/dialog_vgame_feedback.xml create mode 100644 app/src/main/res/layout/fragment_vdownload_manager.xml create mode 100644 app/src/main/res/layout/fragment_vdownload_manager_wrapper.xml create mode 100644 app/src/main/res/layout/item_home_vgame.xml create mode 100644 app/src/main/res/layout/item_vfeedback_option.xml diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index 9728b26a24..f9ee2f0353 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -11,7 +11,6 @@ import androidx.collection.ArrayMap import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView import com.gh.common.constant.Config -import com.gh.gamecenter.common.constant.Constants import com.gh.common.dialog.CertificationDialog import com.gh.common.dialog.DeviceRemindDialog import com.gh.common.dialog.PackageCheckDialogFragment @@ -29,7 +28,7 @@ import com.gh.gamecenter.DownloadManagerActivity import com.gh.gamecenter.R import com.gh.gamecenter.WebActivity import com.gh.gamecenter.adapter.viewholder.GameViewHolder -import com.gh.gamecenter.common.callback.ConfirmListener +import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.* import com.gh.gamecenter.entity.GameEntity @@ -275,7 +274,7 @@ object DownloadItemUtils { } // 更新正常的条目,只有一个apk包 - fun updateNormalItem( + private fun updateNormalItem( context: Context, holder: GameViewHolder, gameEntity: GameEntity, isShowPlatform: Boolean, briefStyle: String?, isShowRecommendStar: Boolean = false diff --git a/app/src/main/java/com/gh/common/util/GameUtils.java b/app/src/main/java/com/gh/common/util/GameUtils.java index 4d32d6935b..0eb043815d 100644 --- a/app/src/main/java/com/gh/common/util/GameUtils.java +++ b/app/src/main/java/com/gh/common/util/GameUtils.java @@ -148,6 +148,13 @@ public class GameUtils { return context.getString(R.string.launch); } + if ("smooth".equals(gameEntity.getDownloadStatus())) { + if (doneCount != 0) { + doneCount = 0; + installCount = 1; + } + } + if (doneCount != 0) { return context.getString(R.string.install); } else if (pluginCount != 0 && !SimulatorGameManager.isSimulatorGame(gameEntity)) { @@ -158,7 +165,7 @@ public class GameUtils { return context.getString(R.string.launch); } else if ("demo".equals(gameEntity.getDownloadStatus())) { return context.getString(R.string.attempt); - } else { + } else { return context.getString(R.string.download); } } diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt index 3fe77c0435..426a489329 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt @@ -9,16 +9,18 @@ import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider -import com.gh.gamecenter.common.constant.Constants import com.gh.common.filter.RegionSettingHelper import com.gh.common.history.HistoryHelper -import com.gh.gamecenter.core.runOnUiThread -import com.gh.common.util.* -import com.gh.gamecenter.core.utils.GsonUtils -import com.gh.gamecenter.core.utils.SPUtils +import com.gh.common.util.ApkActiveUtils +import com.gh.common.util.CheckLoginUtils +import com.gh.common.util.ConcernUtils +import com.gh.common.util.LibaoUtils +import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.utils.singleToMain import com.gh.gamecenter.common.utils.toRequestBody import com.gh.gamecenter.core.runOnIoThread +import com.gh.gamecenter.core.utils.GsonUtils +import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.core.utils.UrlFilterUtils import com.gh.gamecenter.entity.* import com.gh.gamecenter.gamedetail.entity.BigEvent @@ -51,7 +53,7 @@ class GameDetailViewModel(application: Application, private val mSensitiveApi = RetrofitManager.getInstance().api val concernLiveData = MutableLiveData() - val gameLiveData = MutableLiveData>() + val gameLiveData = MutableLiveData?>() val gameDetailLiveData = MutableLiveData>() val bigEventLiveData = MutableLiveData>() val recommendPopupLiveData = MutableLiveData>() @@ -73,7 +75,7 @@ class GameDetailViewModel(application: Application, when { game != null -> { - gameLiveData.value = Resource.success(game) + gameLiveData.postValue(Resource.success(game)) getGameDetailNew() getRecommendPopup(game?.id ?: "") } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index 93f57e9bc4..236e8529a6 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -10,13 +10,11 @@ import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.constraintlayout.widget.ConstraintLayout import androidx.recyclerview.widget.RecyclerView -import com.gh.common.util.DownloadItemUtils import com.gh.common.util.GameUtils import com.gh.download.DownloadManager import com.gh.gamecenter.GameDetailActivity import com.gh.gamecenter.R import com.gh.gamecenter.adapter.viewholder.FooterViewHolder -import com.gh.gamecenter.adapter.viewholder.GameViewHolder import com.gh.gamecenter.baselist.ListAdapter import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.constant.ItemViewType @@ -126,7 +124,6 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa } } - DownloadItemUtils.updateNormalItem(mContext, GameViewHolder(holder.binding), gameEntity, true, null) updateDownloadBtn(mContext, holder.binding.downloadBtn, gameEntity) holder.itemView.setOnLongClickListener { @@ -171,7 +168,7 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa "删除", "取消", { - mViewModel.removeItems() + mViewModel.removeItems(selectItems) selectItems.clear() checkSelectItems() }, diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index cb1c7cc091..1fba4516d9 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -8,11 +8,11 @@ import com.gh.download.DownloadManager import com.gh.gamecenter.R import com.gh.gamecenter.baselist.ListAdapter import com.gh.gamecenter.baselist.ListFragment -import com.gh.gamecenter.common.utils.toColor -import com.gh.gamecenter.common.utils.toDrawable -import com.gh.gamecenter.common.utils.viewModelProvider +import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.common.view.CustomDividerItemDecoration -import com.gh.gamecenter.databinding.FragmentListBaseSkeletonBinding +import com.gh.gamecenter.core.utils.SPUtils +import com.gh.gamecenter.databinding.FragmentVdownloadManagerBinding import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.history.IBatchDelete import com.gh.gamecenter.history.ManageOption @@ -22,9 +22,14 @@ import com.lightgame.download.DownloadEntity class VDownloadManagerFragment : ListFragment(), IBatchDelete { - private val mAdapter by lazy { VDownloadManagerAdapter(requireContext(), provideListViewModel()) } + private val mAdapter by lazy { + VDownloadManagerAdapter( + requireContext(), + provideListViewModel() + ) + } private val mViewModel: VDownloadManagerViewModel by lazy { viewModelProvider() } - private val mBinding by lazy { FragmentListBaseSkeletonBinding.inflate(layoutInflater) } + private val mBinding by lazy { FragmentVdownloadManagerBinding.inflate(layoutInflater) } private val dataWatcher: DataWatcher = object : DataWatcher() { override fun onDataChanged(downloadEntity: DownloadEntity) { @@ -35,9 +40,12 @@ class VDownloadManagerFragment : override fun provideListAdapter(): ListAdapter<*> = mAdapter override fun provideListViewModel(): VDownloadManagerViewModel = mViewModel - override fun getLayoutId() = R.layout.fragment_list_base_skeleton + override fun getLayoutId() = 0 + override fun getInflatedLayout() = mBinding.root override fun onCreate(savedInstanceState: Bundle?) { + mViewModel.type = arguments?.get(VDownloadManagerViewModel.TYPE) as String + super.onCreate(savedInstanceState) } @@ -57,6 +65,18 @@ class VDownloadManagerFragment : mCachedView.setBackgroundColor(R.color.background_white.toColor(requireContext())) mSkeletonScreen = Skeleton.bind(mBinding.listSkeleton).shimmer(false) .load(R.layout.fragment_subject_skeleton).show() + + mBinding.headerContainer.goneIf(mViewModel.type != VDownloadManagerViewModel.TYPE_DOWNLOADED) + mBinding.switchIv.enlargeTouchArea() + mBinding.switchIv.isSelected = SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, false) + mBinding.switchIv.setOnClickListener { + if (mBinding.switchLottie.isAnimating) return@setOnClickListener + val status = SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, false) + val anime = if (status) "lottie/switch_turnoff.json" else "lottie/switch_turnon.json" + mBinding.switchLottie.setAnimation(anime) + mBinding.switchLottie.playAnimation() + SPUtils.setBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, !status) + } } override fun changeOption(option: ManageOption) { diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index fcd1646b58..f9d97112e3 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -8,12 +8,15 @@ import com.gh.gamecenter.entity.ApkEntity import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.packagehelper.PackageRepository import com.lightgame.download.DownloadEntity +import com.lightgame.download.DownloadStatus import io.reactivex.Observable import io.reactivex.Single class VDownloadManagerViewModel(application: Application) : ListViewModel(application) { + var type = "" + override fun mergeResultLiveData() { mResultLiveData.addSource(mListLiveData) { mResultLiveData.postValue(it) @@ -23,26 +26,46 @@ class VDownloadManagerViewModel(application: Application) : override fun provideDataObservable(page: Int): Observable>? = null override fun provideDataSingle(page: Int): Single> { - return Single.create { emitter -> - val installedGameList = - PackageRepository.installedGameListLiveData.value ?: arrayListOf() - val vDownloadList = DownloadManager.getInstance().allSmoothDownloadTask - val gameIdSet = hashSetOf() // 游戏 id set,避免下载任务和已安装任务同时出现 + if (type == TYPE_DOWNLOADED) { + return Single.create { emitter -> + val installedGameList = + PackageRepository.installedGameListLiveData.value ?: arrayListOf() + val vDownloadList = DownloadManager.getInstance().allSmoothDownloadTask + val gameIdSet = hashSetOf() // 游戏 id set,避免下载任务和已安装任务同时出现 - val vGameList = arrayListOf() + val vGameList = arrayListOf() - for (downloadEntity in vDownloadList) { - gameIdSet.add(downloadEntity.gameId) - vGameList.add(toGameEntity(downloadEntity)) - } - - for (game in installedGameList) { - if (VHelper.isVGame(game) && !gameIdSet.contains(game.id)) { - vGameList.add(game) + for (downloadEntity in vDownloadList) { + if (downloadEntity.status == DownloadStatus.done) { + gameIdSet.add(downloadEntity.gameId) + vGameList.add(toGameEntity(downloadEntity)) + } } - } - emitter.onSuccess(vGameList) + for (game in installedGameList) { + if (VHelper.isVGame(game) && !gameIdSet.contains(game.id)) { + vGameList.add(game) + } + } + + emitter.onSuccess(vGameList) + } + } else { + return Single.create { emitter -> + val vDownloadList = DownloadManager.getInstance().allSmoothDownloadTask + val gameIdSet = hashSetOf() // 游戏 id set,避免下载任务和已安装任务同时出现 + + val vGameList = arrayListOf() + + for (downloadEntity in vDownloadList) { + if (downloadEntity.status != DownloadStatus.done) { + gameIdSet.add(downloadEntity.gameId) + vGameList.add(toGameEntity(downloadEntity)) + } + } + + emitter.onSuccess(vGameList) + } } } @@ -63,17 +86,27 @@ class VDownloadManagerViewModel(application: Application) : } } - fun removeItem(url: String? , packageName: String?) { + fun removeItem(url: String?, packageName: String?) { DownloadManager.getInstance().cancel(url) VHelper.uninstall(packageName ?: "") load(LoadType.REFRESH) } - fun removeItems() { - load(LoadType.REFRESH) + fun removeItems(idList: ArrayList) { + for (id in idList) { + val apkEntity = mResultLiveData.value?.firstOrNull { id == it.id }?.getApk()?.firstOrNull() + DownloadManager.getInstance().cancel(apkEntity?.url) + VHelper.uninstall(apkEntity?.packageName) + } - // TODO 移除下载任务 and 卸载 VA 安装 + load(LoadType.REFRESH) + } + + companion object { + const val TYPE = "type" + const val TYPE_DOWNLOADED = "type_downloaded" + const val TYPE_DOWNLOADING = "type_downloading" } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt index b224ffe9cc..fa14fac92b 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt @@ -8,6 +8,7 @@ import androidx.fragment.app.Fragment import com.gh.gamecenter.R import com.gh.gamecenter.common.base.fragment.BaseLazyTabFragment import com.gh.gamecenter.common.utils.viewModelProvider +import com.gh.gamecenter.databinding.FragmentVdownloadManagerWrapperBinding import com.gh.gamecenter.history.IBatchDelete import com.gh.gamecenter.history.ManageOption @@ -16,11 +17,19 @@ class VDownloadManagerWrapperFragment: BaseLazyTabFragment() { private var mLastPosition = 0 private var mManageMenu: MenuItem? = null private val mViewModel: VDownloadManagerWrapperViewModel by lazy { viewModelProvider() } + private val mBinding by lazy { FragmentVdownloadManagerWrapperBinding.inflate(layoutInflater) } + + override fun getLayoutId() = 0 + override fun getInflatedLayout() = mBinding.root override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) initMenu(R.menu.menu_manage) + mBinding.bottomContainer.setOnClickListener { + toast("打开畅玩广场") + } + mManageMenu = getItemMenu(R.id.layout_menu_manage) mManageMenu?.actionView?.setOnClickListener { when (mViewModel.currentOptionLiveData.value) { @@ -37,8 +46,12 @@ class VDownloadManagerWrapperFragment: BaseLazyTabFragment() { } override fun initFragmentList(fragments: MutableList) { - fragments.add(VDownloadManagerFragment()) - fragments.add(VDownloadManagerFragment()) + fragments.add(VDownloadManagerFragment().with(Bundle().apply { + putString(VDownloadManagerViewModel.TYPE, VDownloadManagerViewModel.TYPE_DOWNLOADED) + })) + fragments.add(VDownloadManagerFragment().with(Bundle().apply { + putString(VDownloadManagerViewModel.TYPE, VDownloadManagerViewModel.TYPE_DOWNLOADING) + })) } override fun initTabTitleList(tabTitleList: MutableList) { diff --git a/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt b/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt new file mode 100644 index 0000000000..1f359a7bec --- /dev/null +++ b/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt @@ -0,0 +1,165 @@ +package com.gh.vspace + +import android.os.Bundle +import android.os.Parcelable +import android.view.Gravity +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.appcompat.app.AppCompatActivity +import androidx.core.widget.doOnTextChanged +import com.gh.gamecenter.R +import com.gh.gamecenter.common.base.fragment.BaseDialogFragment +import com.gh.gamecenter.common.utils.dip2px +import com.gh.gamecenter.common.utils.toColor +import com.gh.gamecenter.core.utils.DisplayUtils +import com.gh.gamecenter.databinding.DialogVgameFeedbackBinding +import com.gh.gamecenter.databinding.ItemVfeedbackOptionBinding +import com.gh.gamecenter.entity.GameEntity +import com.lightgame.utils.toast.ToastHelper +import kotlinx.parcelize.Parcelize + +class VFeedbackDialogFragment : BaseDialogFragment() { + + private var mGame: GameEntity? = null + private var mTagList: List? = null + private val mBinding by lazy { DialogVgameFeedbackBinding.inflate(layoutInflater) } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + return mBinding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + mTagList = arguments?.getParcelableArrayList(KEY_TAG_LIST) + + mGame = arguments?.getParcelable(KEY_GAME) + mGame?.let { + mBinding.gameIconIv.displayGameIcon(it) + mBinding.gameNameTv.text = it.name + } + mBinding.closeIv.setOnClickListener { + dismissAllowingStateLoss() + } + mBinding.feedbackEt.doOnTextChanged { _, _, _, count -> + if (count == 500) { + ToastHelper.showToast(requireContext(), "最多输入500个字") + } + + updateSubmitButton() + } + mBinding.dontShowAgainTv.setOnClickListener { + VFeedbackSuppressedSimpleDao().add(mGame?.id ?: "") + dismissAllowingStateLoss() + } + mBinding.submitTv.setOnClickListener { + dismissAllowingStateLoss() + } + checkLabel() + + updateSubmitButton() + } + + private fun getSelectedTagString(): String { + val builder = StringBuilder() + mTagList?.forEachIndexed { index, tag -> + if (tag.checked) { + if (index != 0) { + builder.append(",") + } + builder.append(tag.tagName) + } + } + return builder.toString() + } + + override fun onStart() { + super.onStart() + dialog?.window?.attributes?.gravity = Gravity.BOTTOM + val width = DisplayUtils.getScreenWidth() + val height = ViewGroup.LayoutParams.WRAP_CONTENT + dialog?.window?.setLayout(width, height) + dialog?.setCanceledOnTouchOutside(false) + } + + private fun addChildToFlexboxLayout(feedbackTag: FeedbackTag) { + val binding = ItemVfeedbackOptionBinding.inflate(layoutInflater) + binding.feedbackTagTv.width = (DisplayUtils.getScreenWidth() - 58F.dip2px()) / 2 + binding.feedbackTagTv.text = feedbackTag.tagName + if (feedbackTag.checked) { + binding.feedbackTagTv.setTextColor(R.color.text_title.toColor(requireContext())) + binding.feedbackTagTv.setBackgroundResource(R.drawable.bg_vfeedback_label_selected) + } else { + binding.feedbackTagTv.setTextColor(R.color.text_subtitle.toColor(requireContext())) + binding.feedbackTagTv.setBackgroundResource(R.drawable.bg_vfeedback_label) + } + binding.root.setOnClickListener { + feedbackTag.checked = !feedbackTag.checked + checkLabel() + } + mBinding.feedbackFlexbox.addView(binding.root) + } + + private fun updateSubmitButton() { + val isTagSelected = mTagList?.any { it.checked } ?: false + + if (mBinding.feedbackEt.text.count() != 0 || isTagSelected) { + mBinding.submitTv.isEnabled = true + mBinding.submitTv.alpha = 1F + } else { + mBinding.submitTv.isEnabled = false + mBinding.submitTv.alpha = 0.6F + } + } + + private fun checkLabel() { + mBinding.feedbackFlexbox.removeAllViews() + for (tag in mTagList!!) { + addChildToFlexboxLayout(tag) + } + updateSubmitButton() + } + + companion object { + private const val KEY_GAME = "game" + private const val KEY_TAG_LIST = "tag_list" + + @JvmStatic + fun show( + activity: AppCompatActivity, + game: GameEntity? + ) { + VFeedbackDialogFragment().apply { + arguments = Bundle().apply { + putParcelable(KEY_GAME, game) + putParcelableArrayList( + KEY_TAG_LIST, + arrayListOf( + FeedbackTag(tagName = "游戏卡顿", tagType = "game_lag"), + FeedbackTag(tagName = "游戏闪退", tagType = "game_crash"), + FeedbackTag(tagName = "游戏不好玩", tagType = "game_not_fun"), + FeedbackTag(tagName = "广告太多了", tagType = "to_many_ad"), + FeedbackTag(tagName = "游戏需要更新", tagType = "game_need_update"), + FeedbackTag(tagName = "需要实名认证", tagType = "need_name_verification"), + FeedbackTag(tagName = "需要登录", tagType = "need_login"), + FeedbackTag(tagName = "登录不了", tagType = "can_not_login") + ) + ) + } + }.show(activity.supportFragmentManager, VFeedbackDialogFragment::class.java.simpleName) + } + } + + @Parcelize + data class FeedbackTag( + val tagName: String = "", + val tagType: String = "", // 对应后台的 key + var checked: Boolean = false + ) : Parcelable + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VFeedbackSuppressedSimpleDao.kt b/app/src/main/java/com/gh/vspace/VFeedbackSuppressedSimpleDao.kt new file mode 100644 index 0000000000..fdede504b8 --- /dev/null +++ b/app/src/main/java/com/gh/vspace/VFeedbackSuppressedSimpleDao.kt @@ -0,0 +1,11 @@ +package com.gh.vspace + +import com.gh.gamecenter.common.base.BaseSimpleDao + +class VFeedbackSuppressedSimpleDao: BaseSimpleDao() { + + override fun getSPKey(): String { + return "v_feedback_suppressed" + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index e07b0b6e1d..a3e9e6f051 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -240,7 +240,7 @@ object VHelper { /** * 卸载应用 */ - fun uninstall(packageName: String) { + fun uninstall(packageName: String?) { try { val result = VirtualAppManager.get().uninstallGame(packageName) if (result) { diff --git a/app/src/main/res/drawable-xxxhdpi/bg_vspace_banner.png b/app/src/main/res/drawable-xxxhdpi/bg_vspace_banner.png new file mode 100644 index 0000000000000000000000000000000000000000..cef12f776a8a5b590691fdec0488bd512b930e61 GIT binary patch literal 17521 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Ð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 L`njxgN@xNA;iA*# literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_vgame_dialog_close.png b/app/src/main/res/drawable-xxxhdpi/ic_vgame_dialog_close.png new file mode 100644 index 0000000000000000000000000000000000000000..8c49e487b1c0d1185933ee01384582d08d79f47a GIT binary patch literal 710 zcmV;%0y+JOP)@~0drDELIAGL9O(c600d`2O+f$vv5yPHDN0A*$xtiT_YN z|1JSy$oqbPoj6u15{X12k%&|h-GPZ4&U>{4tX8Wp+6*sV&W^|9Xg;5RtAH#Pi+c*cqldlo*XfJeOeT{N_x_Y? zfNx&?4i8{`hXPa}{t6H1*D$PVuZ0!R>2$_5yL+J|)P+Amzk(t6IjjH;yi3ptUvb0i z=LHl+u~$6aBp8HO)M;mI8?FKUmp*87P(02hn1ol=NX0c`1z@P7-hQA0OE3(7zzC%? zOlzM9G$>$TYlw7tY;6Iq3kh{hBLO}N@_j600lo_JCAyIS;IcrUzp};xfQv$X_cN^o z0GkDe=ww?905%E_HOyKO0NMlyd5&RC0B8~f4?=|pRs{f43Dq`8cwk)sFqEK!lkmWa z0ANvqv+%%~0AN9a)9}El0MJ5$^YFmA0MI~!m+-*GoZ!DE{sojnM0bLshe6RNLZVNF zMPCewz8n@kAtHK8O!TCv=xK4$H%3I?8WVkURP^ofkl|g|zzV=3#57HD;J)Hpfc+hn;;k|Zx&Bb_O+zD65wb9jal?zjdz0=NTt3xC2;LM^O- zJkPf^yS;}$p(CLz%e7)?vsgM<_;ad`5%u*ic5SB9DZ5zOXt_LfD&y+u9t$Y1X}LUY s-l)D?+8(I3t?qL9NF)-8L?Uwe0WRvR3C@APDgXcg07*qoM6N<$g14S8*8l(j literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_vgame_recent_hint.png b/app/src/main/res/drawable-xxxhdpi/ic_vgame_recent_hint.png new file mode 100644 index 0000000000000000000000000000000000000000..d5142c99d32e61074d221c15300741ca1c0943e8 GIT binary patch literal 1541 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_vspace_logo.png b/app/src/main/res/drawable-xxxhdpi/ic_vspace_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6dc0af924845cc38a845f07ab74a2d2ae0991f45 GIT binary patch literal 29511 zcmV)6K*+y|P)@~0drDELIAGL9O(c600d`2O+f$vv5yPF<_Fmon z>t1Vr=UnMt<5lHPWgXO15~e)s38qJ5JG&k9f5+uPG$J#I8oY{fc8IHPH&$YFKAv7{^-%8wA$L5 zP+weurYr|&dRFj&z@aQCrYUSx)}Y6uW~JR((9EdJu`bQ9sMHIg&l1lBZ4JFuQ1USm z3wpaDJaP~jg;I<3ATiBdOvbRgyGwg}dnl}PTdUQ3PoF;h0s1PXuZjU&xNzY|_t)$9 zmd0+XLfqO~Nr?lw{HZ@h^s@v~?G!zwxjc!L?>^ zqk&QE?d=vr*eS6he${MIqT z)tw#M+ufb=m1yGqW#Ih2>-Avmx)?wWc~+~f-z~M>UI>(e`h4W*(GCs{B19l_MwF4V zsnU1RERS6)B>-+2c!M(Ljt_(F+?iOOVne(Hji{iM5O~l|4p(~E?F~f3L7_Z;LRo@` z5?SPFp{Z0R%MxUa{Xzr2$mtcOqcRr7yR99sVv2aY41Z?-JH@JN1 zQu(cg>0B{_`-%}fL@y$(=tZO&?-%6%bRqEUR(W`J>eR_PuRrTPlXs@fd?jV(_8X92 ze^aN69&3HA6V%Sc%E1qyl3rv~eyuyBGgQL(OG%*`0iLJvf@qld;6Rr|OG1Uz>(F)t z5wAN!ja#EBb*&ebaJtU19cr?f4v2}#< zWr;a-5~>=3(A2k@i=FPd5pn8d4yofd-J_)}CFrHc*)*&_4e`IA)36DAWic+#%*DwYQTOp-=WUyLegeLAI%z6CrVo0ry7jqsz`bO2-y^GAq^h|oh5p6D)?+j2YiL)23EY_msL!L|l zvJps}#*IdU?Sc{F021jnBc+b!;7v@9iFj=&$$_*ec^&HUge1i5W7Lji``@I_Xo#V4 z1PAQ1feckQt`<+QTRefx%WUo`PmVuBhfIea1JtR`GU}dI>s94HT9sd8NmW8ggFbP- z+JFyHORtAn2Z;g^ka`dbAUJD`86rWqP`yNVT zS@2Tz(xuCnxjZDRcOF~s@4xmi56cea0aoP+Z)xQAD*a=}kF!Yvlmy~XbX7CCfUeY| z>U_qItcq3EnSRY?9jqiEP(x?Q*Ms8vT{3h|NFxy#d1++FcKAooUV6Xk=d{#?Ps=$_tZf3)HagQ*|#`{i!mqIUtv}s$YEn>8y z7iX&pJTeH@;j`6y{Md1QkE85UB)4rdh0p^Zyn z?of4Kj0i<7~9~`H91y;H`YjZumlK zOyk7ZA2XPhDbf<1REEpLvUeZm83Av)X-gc6MIAqJd|Jb=Bu|oxr6tsdd4$ki&3D0j ztRd`JC26-hbi9$+hL$zoe4bG)kKoL8wvfeYVb9yufpmw2fB>OJ9yo^b!LNmok(_Y~ zat!fQMnjaX${^R3WzEubQ(2hI+Ke)SN~#}{46MV>9N z-r3pVt5>ep>(3lLdgPu>uUu~Q0Od*Bd!)LPBS+}S_7RWp2^3qD6GGQG5yBxlbU{f% zzZFxc5=zKQ1qO=m@DB>ja0w}Gf2;*L&}s^xu6r%u&Ac56r<~dZ<;QceT+}~wO2(Aq z4(#Y=95_&q15X@`QUZ#IwX<@@P%0)wV4@txV5wP7Or7I`$pLf|ZkSqc42ie_2{Yli zp41cItRW3Nn$cUHOUd^3RxN$g)!p5V&jxtu#`))-`~G4b|68GoPn|xc9>zMEqg@hF zoNZIfMg$4vTI*qiE0L;tZ^d!YNE!Qj#0%4R_Dcj9K>^Lg4J1s{cGim}1(p$T>|Dy% zqNf>DJm5=`I2cL_70Is><{B$P{@0OQ=)@!C%*WJujSla6sO&0X*~UbB~sv+fU4)kJijxX-Uj-5?1CHh3_{*7MMn` z&I=t9Acgv=B8h_U=#9!5>FJf*nu0+;QD^?thgE3w)EVMPkcTk z%lD$7UZHcJB7a0Zgv7HjJ|qMrOyCWJQGgCiuAo&H#+cF>DdfQfk-zoGVqR}8nJGfn!;hb}Gxx{1~ubNA5r_r4?##iX>K)%C) zVw^1&MF(;^up<56rt)|Y49wFT?#?G+VLtI03ln~(ilOPO{Cb>2M{1~++GsS1XMy}# z;n*a?gscNScHntqSj12!^`}4>BjR`jMeQD;7j6NZNP6}osc&WBdJvB16ba9tSaq^I z9}upyLPeLKefHTOr9tA+#b=+J(Z5bBRrC+Yu>mpL{j5w3NG0K%BEqOaXC>!8oWcJy zeIZQiya~l!A=J<%iQuEdq?rSJi?mbgN zp*!-kfzAUw_uO;uDnGYZ4vri>B3ZG6@;W-|w3wonTe=zx2c?-AB1c+k0v<7>h#}g^ z?DN8*BOq^<5DdBmLKy8lEsrxX8nbg~zva=6RP<>`omZp^dJurfd1*LN_I@~>Xeev# zKpg@`9(Z(Ns3*|%JT@kyBx6-ThWgh6%dKUe98elnZu-~i4ofduUQt01N7{+ZCkQL8 zE(ZfeMe`;H*9m9`0Sp1JUauQ494QZP%k?uw-M^nw>O4S0|J&+I>__Hx*Ba^!ty(Cc zyB~2k7I4%92GpRkH5-A5E&{U2h>%dcLpujiJ3HQg?1dNc?Vb`nzIM;X+ z<4zO;D1SgAP)<>_Q|5C$2_?w9m9`Pvo7&9xL^-C2Lh4Nb(F_4mCnS41O2!Fj7`z8u zhq#=rZO=zo-jqjNZswU~E$viOtX- z^>=%FdwvE|o^4@!Mpt|4`)F6({aCGjDlMX$lE*xjf^8Pmfh*{vR-6j zV0fd%8}e=7k33MC?~CB&zJA^ivO&ta5ol@c%;(;gfS?@}2O-=-y^7~^$U|1Y_1mbd z8J3KfxGd?zLFZk6(>Sa`+Re*S7w&}q!Ll{erArsf;{jn=@1NDdFnEBiH`f}=w5O=@ zw~CNxsBl4%DU20nYxEePLpDSfaHm7JiL~G^0d0twBMn&STZ9GI6dqY~;5q)6Rl)q|$?Xb2RPz+li`y{@nB z3a{VpWY8S`a0!3v@k?HEnlg4K<|@I%xq4M{*&K?vULKrxkq%}@2@$%cwB(Wxs&mOL zXTBHepAHYAVH2H$BtTbI(9ScV;$Dl~k(NWs8z77}hdcv-!)zL73XNq0Nc||w90Ha9-c()E*4B0i zUua-;@S72bGLuMbx~B>dLXcb+GMTJgavq}bk_OF|xyi_rJls&BQ7$4~xp=;e-U8)w z`;5w(QlJk2%9Ir9!jLBz0rp{_ujf;crU5mQK!}kZT24c#O7zQyds$`y5C{Dj$`l=M z4^Y={uIH<{5Z_Z{zP4?7s0fuI|Bi?{=sK%b{*fjcJ5ug_}F1&uyIo+wlbE7 z7se*J{mdTzb{=RU7Ny8LqO9dz;6sofaZj6hUsOKKBg^!8UXF-A;1AJOke-l}V(bqx zA1XEtJP0q|9rK}{oKmV^AL5z+H%cU>ybYf9|$L zF@nO&5`CKMVj3;84c-UOH^hSnC!}?A`7C5UpfSIVDg*6Oue_Yv=<0;)nfIJ$lN^wA z3(Goy%S1()tD^BZ>q2`o-!X5KMHe}Y!kb%NfF^>@JB>ley!UxNXTdkw%~<3<4pC3Hbp_kd5$4Q`>9o}Hh3|DzUR%b z!$3`baX+j|l`NS}3B5Ua*n{H%rE_w+(?=J}jOX_D-K)Lz{yme`%r6rwQg@IvYvxkZ zgcz4DrF`kW^v2?`sPYxZ9$J)XK#{&dmKs`&ORd8GejAGsk&Km62_eOc-T;wCCJ0;b z8dhbY8PcR3tFnl4K!eK5HZo8I#BWS-4jmG26Db<5X<4g-T^vH4Aqr+DN^*|c<2aIl zL~`!FPR-b9q3I43T(tu0HQ!UTe*cboQsRFVY=;!hvSh%RF*{jZPa8o#^8%ZgplxvE{Nd|b&kyN|`fjRE&glHkYAD$bEMcS3J32-AqaqD1;g!uO4bq|(Af>CO77sL#=1SP4lVcg z?y3^swo2bR^!eTl={dkWT>K;HycDoH={nw6M745!DvIHjf3;% zLP==HM;*4k57E4Pl}!H3SwE~6>V3dF?4O{GH9r~mp?fm zXdkI}5@VeL32EXY1DaZpcgG;)YC4CrS?Mg~=BUhXr^BFGdSS6g1j&Q47wroARY`h!*k< zqS)5-%jkTXqaSV)U%5rc5EClcwig8(IDCK`GcAz!|X%o1Rz zX&S@bmPct+#Ssk&lzfQ|*TWSk2N;ixcw;j323f!WDUXQsAcD{)~pQs-n+N+yr=m1ut-m+GmP z$TYUjMe9cdK%zn0+xeRC9b$w`HBi@UcH|0msX?q7L#}k@2HSN)UJTs?PiX*SjXZX= zmzj2_H7fPotaP&~!^LYNV9P>^+UAgi0wHym4}Fa?D3W$G3>lFGs3r&F(=KZBZoKvkB$FcwC9mES3UAElgr>8F2^UwQKx zLs1h>L&4wwqtDWN-v3LqA@L!Ohv|Lq{yzHVzjl}JazRNk;sdd9eFDlMZlr4T(?XYW z{r(^O=k&zW=jj0Y56#1W{e9m~-~F~XC-U@A!P$^ zu+a2GCnIc?!8R!E(gH2Nrj)3_wKfVTui6N@}x9 zNH-$_!k}xR^QkKTMCY3FAa*)^^6B#jD)I|WFFADrwP0aKDruVyYnP)QflJ^?S5~ur2wPtnXc9T-f+x3Mt5TvqsxhpT zFaoR9nwfm?*GZ6_c{Smth!R}6w0d+Jkm0(9Gy;rqY%2{Qac#Y*vX1J^wwKc@Z$9fr zLQU8@&}^SMzTU_g+P~$jpNK2X6HmRkHeYqiSsRzt-;0;8zY(84d2H@q=$m%v18@&F zFiOx~4)056{c2vtW{wn0Es6DgP-tryjT731zBU54+d+roIxx{f((&qNs&QaKgbJ*U+Q;3fWZcak;3O=l8j6pa<(t8?YoFly=bkf9bYYQEsQv zABd~QR1NU3=@l*fVTet&(hDy#WGV5vxqc<`?r*$foEdmJ)P0_n{}ngCEc6d#u?Yp@ zq&E;wsA_4bW&`QDJs!mJb6Qb;SHX@^=_MNoflfP5Qdj?MYc^&WS-bKo()NN1s-4JD z^cT3p(PcuF>h}B%BuR@FgxPGW97gE5R~0dA}UZpfcBiM+d2e9D9Y5FK|5kPzj*oj zc!1NVjyrvArUFsA3c7|VA8Lw!n3#Q1{I|V9-to5AtAb|Zo;fX7|HVK2L3}PDr5*mc z5B}R>y?^ifzJtE)TkfS+A)=!*iCFDXVK@$vke zqJm74LifLED)!WDtmdV&tX1i!%&6p;9P9w{Iu+HvmmHHDNP&S7pm^X^D8D|+;eYh| zs4+3Og-vaY86VVwNtvv<=T`G>6IQ~J;bt~QB*zeiKw!E6sZnot@!=Ibnjv>{>K4Tn zo}+CC*R9vst$q^h^_sDnLWu&(;{nJl9NpC3^f1k3 z6qJcw;vUBEjIPf(IBlDGcB(e^7DIuuDs|p!t6!=7)gA!sL5FJ>9F-*xH1QDWm zUqC?#F~0X8()f2nY<1Nes};r9W@p*COtrezyofN#U^c`i=xy>rOrDYO=}u(<1jVyQ z5JY}trU^-c3x!TntEJ>&h(O?+P>9^%QfE0*7TW&A2C3< z`x{?va(m*b8@Gs0Q(Z`?;Rl04YNx3#*B=OPoi4T)h^AUh?*t+TOtY~#0%K$#u;hHE z30H>tE`FAw<(1h0ydjM52*w3O5qTA{$nwpX6X7ruL|8ANIjMjQ-J5XCfFvw}BBA)+ z0X0j%m}2Eqb9k^ALY$hPW_D>B1oMqu2UOZ{aX>6vFFf?QN98^5|KOn%_#gcD|EnF> z>C?OKyhHcE9D2R$ni%?#!>nKQT++sLeyRsJ(`UfxwFlSX&l-d}fW$@{h|?MY7{e_H z_v`Pp+$dNG6TaXLHwYgy2M=M$oh(rQP#}1sbp$tI;d3Uybtw1{_Wsp&PORS{S)Q zTR31zgkl@G5>(4iX@u5wozE{U#KF~A{`xzAYIv`Dj)P`jUTm7Y6Hy1%_4tK`UawGt zFEV=a26`_|_{7;#40$Pqz*EWyJQpK^@q_6Y5BeJ05;Ct4Lm$O`pus|HG9#PP3gdlk z5fFWZ^2QvL6}--rHcFL<>aC65M>_%#dIY=I1R>ZKU*A=mItYI9IxVdjr8)p_hu&3< z&*xttFQ?`u5uKjgsB}7pkfs9&QsQVlOy(gV2*=1`a84njQ11bTCO9^54};-Q(A8~D zAxDVk!c|hY6=VB^;^Lmd8c7JA+X$XvFaVmZwmC+P`?04lUMI9Zt;>8%-T%!Ge~*O{ zlIY~j1I20G`rmus|4T!|tZfK-(FiKV@Lm{tzvR?$b0&2<_U=1hJ)QsD2Y+*Mq27Dn zeSc8oTHy1KeUbjhUm7pHc>U|{v{xa&zDywlMCUI|PS@}pql8W$JT}j=kt{1HW8>AN zui@cq2868J+c1FLJd?xJeFlj~qjmE7LOu%0jb$d)Rz@JS!uv272(E1s{PP#D()CCU zMJEDENWnF%fX?H@7s|-;5ygSmQX9rYQ(NWxg^WFP0iVjGdYE#J4=VSDd+$VACLT7e zs;x?|?@EYt?#B8MLt0dF8t9e`CQXzcOnMGLYji;Qdf)4dRb<_n(l!hhy3Cxs!GK^| zDi7_u#Y(&YbqvP?BOz%Xtmb-ofLGpf#%Q|#$Nzcv5bX^G0pI(h_fN<7{m4JYtwx8bA$m%9C#Mg4jQY;X}i{q;MMt;iuc$qlLa1@|=x8FKe0H{zy^V zZ#Hr}WbSl|2kj5TtJP9tOUyt8xJhY#=q37JD}y8Pjdh!1aJ(L}Vi?7}tE;Ilb9luq zXNPUo8I0EqUJ_AMTtZDM4Mi%=)WLAe;KCZiw83%w4B;nBgSkwoY*uua5}v= zFjdBz2jO)^EA(IYX(j~7d=Jwh0B$MCp)xg4&hi-1v&w|EUngz@mZ6sz#&Tf&aBmdf zjXH5O^JEm6kxGwpwR8W~Kl%Ig&bPmXM(HPi=pFPgf9eN2VW?6pg;ck;sm8|_2CAp# z0d9@s7p0~~qWqW#P3TmQ5AbaIY$U|BAWPX48tQuw8ZzkdrZT5a9GlMGgG?PaJ z)I|@#D<#jZ$Fe+*l#y=aa4+#q1D)$+tHT0%_abF|%*C{Z83WukLK&Xo%*6F9h* zzkY6YXtw%aMmh~emR^#12`nOuDi#O1 zoMub(@+Lmo^Nud0+0^E#lP8JXqx*Nw+Igd_ykZs((XItWSzVFczdK!l=1J%VJo(hWGL4X%=mBWK)9P%?QfQ$|pf}B=v^D(J3?gt#9iokC@jZ=~+&gWkqRnt!Qy2nmGNsT~ zukrwStpprr6d&r99~knB53niFK;uC!01WC3X??4vlvz@iIk+^AbhS!yhjP9TZZe~k z*4Kk-6p&sTwcRUZV|poss3<&IBxf=H0t#yQQp%3&Jz--6T1qER97kmhlLQnym=Ewo zAz=v8>XJ=pj?7~pUPGImCnul8=y`Mtk3yq!)(+kA4jO{#gWqH+e;|6SbyC?&I^#egRmUlS@?rpr=;qg&LCJ! zAHs5J2HGjBfdqwDyO^H14qEGvOtr@36;ZUYw{GN84hBD%e@Dk(E{PlPLt z`f4M4h-HIXRPez4s4k{B0B#1>W?VXY>jR`s`}8cmEb_{RtV`3Jue|wX6RC@{L@z(X z&GRfO-mN#cFH$8w9K2?kUEHvzXWcqQ6YGECrz*dL)<~JrG$7lwiWKC}1UfV7d-71n z&pnKt(z*xFQ8IpbKuaEbBDk(}z^lgBsHk+~mqb@so{|YHQWeaA@)qBdlCHr(D7i}= zQ{)>mXtawdJY<>R!VvV$)LHZNtK#`rkIin(GUM5~iARG)Au6qeB z^b~r0J-0B|S)ipwY>~Q{blkxQ8o+Vu_rRCOt7|0UE z7xG<>+Mbn*j+HdC+OX-JzZ4Jo*2&(of({hcV$UXg#>Utg!)PqOK4%1yGh%j#4Ixbu z?cxQeHpMs9HBw-mH?IUeIhZMFuToBQTs&a?P3{~<7$MEFoId`kho`?xAGML!^j!?u zTt_uT?GbHy;~qrg_5V|NE2!k{j)uCZT*i)@nePxDdfc$v+ySP(ix*Nbv>{qNF35t-3!RwgWr$HstUhhmV#fuEl z*xZx=LpbtgKoCwuz-&jHdTskV0%EX4gUI0(z5{Fkph$A+)CsyCY1#<40l{KeH8(t5 z2&ZxRrOOARsBV1%Vx5hy4%|QS|9o~r_iI_;ryBs&zNn$mC;sSR`b-IpmeMrc3!YQ^ z;!Cq<<1y{?3pWI6vd)83>QGoeeB$6XXEJZ_%bz9w<HPw@MF&3XpUF<(8UOqzRG4m<~c-yP;!rC=71DOp1P*} zU;M)#^i`~_gFgS*7kTtzM_ol(|6I&-mD39zviv!rDF!YAeCXjv7Zs!`?R($^}lU^}zQ8ICUn0F)IdEZ;z+cwY;+WbwlYE)`ifW{0L)SJ0J;f!639L%Yg@Mlh~ zreP4kBaGq`w&xj}=EFnlNYiujq zrajeW)tW;B&!JORP6&~qH5goUhi-UNY<+QINiw{T8|Smj;ifms>b^TqZdfKzzxeo> zGApwwg|#$FGhNg2gJJqhw|$)*A2j#>&S~4mGh!i%kJ}FYO|(<+E&&2a7Pv+Stf8-j zzH@*}W>>ky1s>Td{vY|tXzs2Q#sTrHtz4YOWz=NcN&D{U6Vm)GBWC#yn!>44Cu?nYP9KaAzr z`^2_}-;ly|sH3lXXofo;zsFAo>t`oYOX8A>`rV_2?hp`#zaI6-!_Cmx7KCEpn&)_ z%TerH2aG>*|94JRkHVCy5P$o=x5^`57#j!Xv+WSgDbF+<^l^{6+w|A}g;z~4rN91l zcj3C6Ad?Lb@TLuW?`to#Yj~pQsA0luikJKCk9~S0Eo}zL)Q(5ii&NgMLGm&RaDGR+ z@>8ltP&>8^jA!uVVK#lPK>o4>_?+F(Fyah57SnNcvJ z_oVP1<+}$FQ(QbW>p?|F!HM6@R!=^}7K}sVd-mfAss588=pG;o3ZN6zZ-@Uf)6frs93Rp&dXQj)zWBU@|(;s9N3T`PsaAw_Uj< zyk0W@n}_F0zxU2aI;B46R7C((ws1;7hvyIol{|zc5Pw1Ku9F-TFlZ};6?zX9S30i) zhBMIu)1A%oRpGmhaXESryElHAb(~IC1X~ABV?5UN{8gzd(!S=-S5LDgP$hqTQN$;o zdWOHL+<(LC{>r==Rcm{+ok?x4*71{n=N(hstwG;qdv3PAKQM(cci%Y=(5vFMaLL@d z3a&YM4=0rWb)DV$I{CZb_wAf%hm1PlHBX$-SN{2b`-A+8zxvVQ3I1p}FrQ|!76*i(w%cpN0nb) zYbE3#fPcly&!UXth6ey_i46(HuRvBVe(#4V2y!GN{jKAH$p|1PJZq2ukWnU?M|uAF z=cn`jJHbpLcOZlk>O({Db(!#jN9Z+bvq2zz3yUCE9;AT~EnasGrQD-ao>M1|hjlld zkx?)lAG0b_P0C-}r~^pda2NVbt&bK=$jCQCOG=H?7WJn-e7d|xv|H3@w{-k^ zKgxH+EBt0!!cd%YZ&BfAeu2mMeCl$@g{`!fjoZh#t7bq$hn7@1Y=#5SFd;q z2ztJTyxMe>A?*}}f4GUvs>b(5}f5*bxKujsnG%xkuPJgrQW(D{p+4kJoWG7P3H69FNkk#sjJZ-Rc!slH zVrPTDFNRLMeM_<&@?B7m>;i4S`1Y^YpPLPq4fW0Ajm`G2y}*;)Wc-37>fhjM0I1UlFiWA&RSZ} zs6`j90(S#hVfbeEnxp_AkSml6(w>1$1vxtw_` znJ|Nhn1kVjvYx9cYk$`b14W-Py2*wq4*u)c3BjmB_b_yvq##68a_zUG-2OgAByGln z3M^pc)SG7j4y7Ev`-}NG8?4@AN)m!XL{Wbv-Ndn`0!>ofam6TSNZ<7hL?^dF&k*Xc z<@!G?qX3yt*H(tWFr5WNhbrs&T6%ZS$-#;E+8;#K=89Fc8d`=S;;gw*1e`lTD1=#} zEd!!Xd;?F`u6L6S=C!=JN;ek!vY-w6fqnuZD{lfFK0^3phyG=gb`cPDDz~$y-1+l( zovp8wN27y;x*hpO-p!UOD?dVvURcm5o6K-Lpz=(z)%wYCm(bhvN=lTW$A1NWTdKvTU&bb=&+8D7=Trh@5#`DA zfOjo`&dmr-92i0XKjb{wFVJC=80?-ncmnjqVjbu_**QZW3_P9j<^~zJO$3h_H3|h0 zQ&s-&`paF|GfE<;DemPbI`nv(DUVsn9%_gX#`)1kn{`_j_OcYq+PpqtCDDB|8aoh+ zMW&}QYeYP)heLhZK7QL^F3+(}FzBTr+;m0X5eQp43%ue8CDw@!l}QR&CaMjQAalJ2 zpY;r~R0HpTip-Om;?;DiJjl8GgUBo(hx%sP5B-CGoJr;Z8>4F*)3eezRXzFS^?mVWx5{Df9Id$N`;UtZo<=sKmj zdm>-KnJE}Z9ABy|HYcFGKJ;oazpEVRBt#Xn%0{n4Ku_2HwxVc25b{t2lq~0o?j&7H z;g2b42v-cwBdSpvhXA9B+D2mV5Fk_(aNX+gSAP2wTz8CXi{v&TVffwj63iz)_3*|w zz-a6(r}WPI-pbRPX^NB-!hOWThn?gXt>rgSWGUZMNtE!F0;Pi5@iqr6+iRmXVZDlA$$GBrza0y;a(e`5E?L;+dR5T({md`ju&>Cxn0i6(8A&JQSAL&b_-s-20Gblq zPoG$#8v>lueZSFyiE_XXZA=%)!Z%wW5?(vD4#0-R3Yf4_WwXP4m5Zf{hC#Nm_ZU8x2S^b z?$01_dBZjv6gOFQ07G`@oWlxcT>S8xe z&7g`pYVA||QhW|i6u~hr&o0{8>|=fC3ym`s@4759}5G= zuc>r8y_b-~z5TYy)uussH2@4fr+#bR^W@1Bbmw2bgAPh{w&=0{_&6OlRpr0=W#QfC zjt`0BzHFo+1SwB*d0NxcILC)vSSQgqtWrAgd=w&+dsx55gMERPlr$l)y@4Y%G!9i& zba9;Sg;*j3n+7`oefqHQ9Yt#T1~jV3)2P+ZOX*4v4{>CeyiPaSFf=X`YEBMyAQ ztXb!Iq|;d|CN1yDBe*RJH@z2%uLnkJ8WNBR4;+h>S&`-$`oSL z9-Y7VFMqP4ungR0Hz@%SGw;kG{b1F+)lx!Z4A&xZ+AD&{`|h5%S3JP71w_vmX;NB2 zt{?k@Ptk{ez@;%@6R#8Kf7{eRVGDR6_bkIn2rS_OTAofX&L%dI2`5|@) z;gnx9eQGrM_a~q%h>eeIP45Eu7(kIIAba}7*h(aXHAWu_%IZdir!F>=PIz-=HnqtV z6~_!OF{aEfA%>>- zSo|1j5@OgzIV|*S-e-C>vZn5xVATJdP)T@$qH!FJJ8_iIj;VVYeOL!Y#W4Z2kRiDJ zR%X-ePZ)sq3^O24j#;}TxqVIwkwGDag%%b-o;_U*&71e^$L9b>4z%46pAW70-*86> zb>6CjXAb>C6hmBBwwM5Y5g@V8-8pzER89m7^ynl}o)CewMo<#e>6DhK$bWQu=51*Z zES&%nF$j7(InKNOv}bk4C$vzozvMg$qY`YIjW8}B68CU zGKF98d9^JP%8&VF}j>{>*42rqI7Vs4IH7>lVf+Ia{GG#K)(dQY=l zJD~4{OUs`avNb#)=!V4RLWdr%r$aY=qVT;d4z^&vqoHC9sTv^ERF`V}pC3Q`)a_>{ z1$QN{NMDt*R(CDRKb0-BO;3ID@Xt)@+N3wV{$31O+k5@w-~!3KHygTS1?@hP!G4g( zgTV_(Y$vP==u*jlWK|{_TAeFNH$@v9x%_6=+L4snk%8eD-)$@)>3$-P6b;tPO6ZL; zxq7klP=795THfeZH>t(2hEv^PSu+#PUIki6Jw^NFw#raFA}8}+F~sQ2P}qFuM(8*& z6>l)f`RT9R_=kTr{K`mfyny|4)+K3KIv+uy51G;f)=^(m)48OnBDAPu$4l(LwQ|3_ z0xH5lECy%^pNV2fW4t*7fo?Xm^LlweVha-t79@pJ&DxovK|}@+&xK7-LfMOx$;)`v zUkq^~%sAbgnHLGY>TfKy4$R@wTKpY{C!cy|5x5SM>T`iw|K+d3^zX^}qZ}F%&S8qC zJV2Fn&-DX$0r%Rxtb2;6)EazXzX_vvp|L)esZU0)vhpyCY^%N%x|PAGTpLD9L&cOB zpGkL4mbwmKOAw02Rzhf)66pv`whNmE!LOJHkHH0d3Dhwdt-COs)GzPg ztFRVTl%G2Fxn-@p2bc}b2W8QPc-#seDt4UFErExrUXeh!g%*kol9*FEte(aIlk2B6 z7LcYOEUug5E-S$+Z$0Y+B{WK>m4WX#<=13l^ieWGM89}@CS53QBM$Xlx^z|OMWmbC zSLiQa`D%E86BgnC5OGjs8_GBNI!G~&8|T;{^ueqA&Qfh@wnpBS!T@1wgKX$=ZQD`3hk&0`n#dSqh=Bxb;d(18w^ zeWK*9co2u$Z3GUz=mTBdSj@c|G%?Y<;oHE6NvE1pUc7kY7Q$Iu$B#RZ5%r3IQbN#k z+1h)#4Rrl|0=E0E!VS$8)y+WI0U6t(1X>m8j~|H!TMxF)Ei?Ix;ImT9o&h>g>*IK? zDSRw1AOeR6B5q}P-OJ5J!i37lEgbO|Wl?z~DAGjurWaZCBhf8hXCs~>;;Ydr|6mZo z2z=KrB9lz70QPc*UPF1+^f%t}db;aBzsr#A(&a1i)Boy&L!W%V{tqz#gC?=xncg#wB zKk@q10q+!8|0*A@>|vJ?CIUQjj&j8 z=uc&!<#A6yhA1@nI)}9nF-~}3(G)!(0dgcR6&<65m&6S{T(~CC%^u)5xl945l3}xx z4t-z+`~`iG1B~oO@5@>zQfjXb;P%ubwK^_d-mnz9gdm6toW>r%_0f+{%O7(3r$6=g z>9*NZ@DKlZcxiqr`?|aDMBLJ6D3Cf0wymCUnC z4olI~5ye?X>Yt@Z4S!l)ida^cZj1%mKOGOP4YPpw!f1PzpxLsv)0b*@nxZM=HWQ!< z=#7|{W+?8Jrh)5H=e19jT0saMMBCAe8m3^Is%(wU9LIP3NeutsPMiVT-4DPq{axDN z0ooFXxlvs_*J!F`mln~TIyEcqQwyI&)p{%6mo~qRX1YH8X5@px=p@5+#GL@VDx+oy z#9>kbbUo;zHmlwgjmG-5gg*KyR5J~zn|w7WgY|Ln3YItxW|di%Fy1i>W{G1I@sLHQ zNKrZL>)iygAEhvYlMp6k5f^B^wh6iHDX`W}LxY;*#}(xmHsnPF3{{{-c|PMoq_1RW zO&B*%*Ph<+EMr>DsxnzQKxnNcejh6MiKe(q?*g2f>z(+2dcz{R6DN)Z7A8KS57<>f zCsHWM8q_D2Cy)>0@_Z;efe?fKH2v+yr_y$jrVtv{kBm%pY-fZs<+S3##iIiHnrjMu z=~hV*K_PT7l)-z5tkcG=YmbVsUOXRps)ODGW>968;1KkFG`whaOvr1a72LM^XPr3; zbgRp^kg|1R-3GCtq~+d(!1bxGA)R*?L-8(|*Wl&xMV;SQ7%lBDRaHXClXFeZr_;h6 z1`Lzx2Tn3*c}6cnp$kMj#&G{2umuXae$>5H+w$_@aWC%9c~|K2t+PC*j-ZZuiTcMFg`nmhi zoB;H>K15UmBdTeC-U4Ojl|A3a_km9yM}xKg(WamJaz6=h>f~`SuJQPyhBo4AwU}N$ zzboKjqS6BNlhYF_!~4=^{7~L{U1f;%hpHIrAb%j1Gm20b$>{wRH7i6HrGucU@l`-{ zY~CM@5pA~hS=o#kBT9N9s|PT}6o}6glD2SxvvF+dx%Qn~R^D0xGeWHKUdx8QV;R3a?8h zCk79xawI=zxX|jJPIvZaibAN!v~g!Edk=uJP0jy}!Y4F<#rPh2aVbyTaYC8E!Dy|9|!_4NNJ^4s}WUYh~a#0wdJ0uxems zN*b9%qsUind_d%bkExXqFf|2VXLU_vH6%^RKt;qD)p{dE>};ZX zL(x6dpW@M^+H-xajKKB4H;3!f|DgOf$ksXYP1}}yA#Ipj!xCR%|zeduVX`mHbl`t+5^@Tw!B zt8e#+VM>p|>RpYUQ3>cBcPxOAfCQ$rTW4$>Y2)9PONU6x&@LePQaOED%}%#t#f$U z=qPDhD+g-gr;z{!wU4JfWXj(+!riecU1Ne_Rs+_c7%Y(=E zBv_z6Z3!Qwu#*~SochU(C;BV(P%+^EPjiy-#r3Q26-eq%44=Ek7uhjQ%b#0+EXMcq zAb8?aQWT7-*oZ;y4JDRP_uz@%*bcl>ypoRJ|m) z9v-?vZZppMyB*%pYNW#GUSHvx3N)se7-JbQ7(`aJO)vol1`u&68&NbMAGAo|(7^YP zKlcdLouJDf*WaZyO@Sgs1T-*ph=DG77QlSGS_MzULFkcsB~(!?AXh!#YaaONFTc3$ z%uo0fCoivqI&La)X)sgNrb(y!PjC3Z#;rGj0QGKBK;W+}mX1@Q~h<@v+E z`8)iP-(B7`_tu-+JJqcZjuvllq&`tPGB4@AxHB6A>dTY>fo*{r`L*d6WP;-}q7Gyw zMG}-Ega}5aJVE#77h-@oTXWx86}$2g!@wB40Rl955z*#t#0+GqQnjfhC3+NIVW?zQ z_Q)3wzqR+@c;mf5p}R9i9X)e=Hh|}L!e?GNl{ZDk`yfxfCRm2OO!vO|NUw;Z7eH{TO>Kt`g=iIAKZZE2 z{N#kPBc(_rgoL_*Dq-1tig|5Z;EH2o5*5~AcYuETx4oX~H@QTDP;mAuCvm$34}lqI z7GjF~vnw9*Tkq>0pc|(gOKktwUUMgXV^Q`yzv0zWsN=4rH3)4ig;K98UZV1_>EYV9 zzv*@I?>_ek(*dcDqf}-L%`-gKtZ!hIFo`agLH>oEMyD!aESNVL#!oDDUe(57paW1| z`;(I)QPSc08bJtzt{of3Mlu3I#hSMhUS=*a%sI5cUlVe&c%<(zTYyx>zyIxTCE$gj zZlyERj>v|a+h#;V4>eaMy&G3V!??A@|J4A@U}{)%+n;+Cz3!eni_-p;d4t-4B4jye zolDCX>Ykr9U0w*a>L*`sz4;7({Ez-$+LY>(^jF?;mNIbIxqJSJz7yNi8(H$~)xvN4 z>J4%4*}HEItJM3Emmo8uJ_^nE<0P)FBJxrU@U;pOU4v{q* zH~|pU*AeTW`Qq-hHea;dh-U6141~~;XU)J6JP6~e1`6Z7sjPn`5-NdX!h%{c5)K`p zmS{wxq9m`8clMRs$pm2vNvJOfA%{R!>FZ$kuNKs=zo*ith(;a>1c*YFj3`8Lyc7Vz z-Fx%WF(p?$AGh-wpWpwtzJpSm82+JaSHukHU(-|R33v^ke&}z%W7^2pyp>s834v(@SpmGkBMh$2xg2*@^J{wJE@!1G!h*K5*?mJ&i zf3?KQJW|jBFG7T49t^!yco~H}Hcf_us1n-bC{LBm&N={wmg8(F1J8?SMnL1V9O89% z-${S*&wt&t#d-M?koT18F3@j&{k?SWT{A$OK4srYsLxMiw2-dK_nYp$lkR)l8$!DX z3L~&k+L50+S@iOPNtgDf*&^qm^@Yhc0#)xxO>%Zd8h}tV4x9{?L}QtMKL6Y_6gzeL zC82?gK7&TBX?7wvmnZNtzJE?ce()hosSapAGlG;245|~VDOzhMmmL8>R`!v+&|@(U z+)^FSl$dyDFM7h92iwXt4cgcI!P_MHOzphvgl!RcZ~}gY{89vgAmfwV5QZY_hI4s|oo-x)QW>eh;Z-(>I^-ST%4oM{$ z2nLF6@<0V+ACT(A%%lUy+ZG{77P-FQ^^m$N1-aWpFHU?i9Ea5I<=L`IhrIj*$*H5= zWQWT+DL;lUl!d2q$zD?c>=>dLnrDG(;CQCxP&XW7PZz!u#p6!0PVjp)B9w@_CB`5u zb!THV2g@dj<=XWyU5dy=&Pxs{LOpsz858OUo=sw%ksH19f3TU|tOPsz?v)aPNu~$I z*6!M~7#>V8kRyGR(R|EJ*@6)(FWDPvdg5XUkIG-2&fHr&&()Z2D&fo>HxV6!>69hZ z6&VP&(sX40WKr>oyk2)8qzcTG>RW1yAw<>lCX?3eyg;LL%ro_cm}kqyv*F2sqrPDr zx@hVdV+<**8z`WX&upOLfgnI}SY^bVlzTxCK+Bwu38N_q_ozoHr-C}8YIOFBDveg| z^D_)q2|QW7wxmLZ~zFQF7A<1G$~QjY^NV_%k88~NOq!#sX4 zp2-_rBzf`z@$JP3ZaYJ|VVQ4m3>FoDGWM$!y10!EM8^iBuyT<6#iV2`$WuHwGkB&v zk>+RYViX-JiL@-agRP7k7xfg56l#>sU7x5W3=zbLuwPs=-n+l~jvFZ;1@h6non+qZ z*u#n}U~>NnAyw-PMQN>fcaQp57mw#o@50CcFx1^=0^XYV&^u3vZSobHw#AJBjGwCX z4?S6wf48GEbc51%?pdNg{Qrrs?9Xj!Un)OB6gMCMgva`-H<-pKE0BxJPNk#W$i_PX z?=e*DG*Z@Wy~Uc&t=25(rsMUxS78Rb!zS3g1VN0zaBne%7%p|D5#9t%<2WyxB_1xd z+iI1uaR%X;A~fEBP6-s@IEcyj^N|=5=C-Y8(0mT-JFjF2ar{5J~wJ<6F65cqB9c zssWRr=t}><)glIsLlCV8JrhA#Ldofj6tNE@(Ws|QnnbCDwhizTq7S^5PYF9;dVSI- z5?{llR&ji*(UWOpBW*gWq0iHo-6Q+$Tp}2@Bw9$lK@E+9co@bU3b2h;8hB5AihN?* zsb;8)#@;B*_BdqCKkH@y#j;8Ww72`2nq_Zq-_bp}deS&6hbYQNQuHoRG=2v}^;t|2 zvoOR3*daD3&O~cdTtryPJeVQ&C@k6Y*mYMf9->e%GjbDbHSezBK6eJmsie7Fldbn=1pfaFy05r{Xx>{))%@}nBXs0f@9WBL# zUrKTLa*x1Z7=nCMG~7SJj zgK7*)TX5EB7(rrM;e58g-k)+7x*l4cJ$tt9qI#~DTCevt=8ar{i!*wgu<<*-IDicB z;aW%FDiw5m7P-m&;qNFPXIIHgzg7x=JF zL60*E#r)WLRleAi)eyfMi@?1qyX`jk)xmN5o-v_Px5niByklZ`7$xXk)WZtAhnrMd z;;-F(OlOMr$ivNnf{x@t;I+!wKwf@wnmP^bD)+fv0z=y0-=F(VG;5{@ z*VD~4x}A1N0-a`Y;W`W5^BdY}`}!hC^r@Z?v=YNFAFYe(rgK)S)9?UYeYPkwRPf>d4n%b17!|gMbfw>gChq_oYoXoZ%_xyc0)nV z{WsFrWVmkq!w*rbr}zZ=z527ayX%`vNkB7qgjyqK;HKzwqEfhEqU$y#G6Pdx5d$pc zEu%LRb_7QuX(RAq>Mp6$U@R$=6i9{Fq<~`zn9?biq0UX)d|J8bRf34dTckPD`BceQe zfo|GeGZ~5n_iUC92!KkMl{m}K!EF|X06jMKs(A(>4Yq-X)_PUHiirb12KVD803Y-q z2ptmw61K_lmLV&IiRK&$l}9`##%2^l%uL0~TAMipYIy>})x)PQxiMl0)OZW_3w;Qv z7!62|Kqi8}my7cMK{0~Io&zue#xy#>zEPb*+19Z^eTsZ?+i4q(cWS3<2(-1k|6si~ ziKdPNN(&Fx9Q*rwX1Pr;h>qQ;8$p~>!wq$qQEk}f=PlbB(Vj!y)<>-lLrT*AZ24Ad zXcVj@&@0|f2nmcmh)KD1E~oP1a$ur3O*>NlAPj0q)mm#7g9dDU$H+HD6jW3u&qHdA zXl(VkzM8lSm1HryEb0p@0Sw^2@|=v=cIIX<2H*!-N24|x>R$K%uK7gzD^Waxy zLI^_S9ia8saHuY>t218tg@*%Mx@BuPI z!^)L$U*7toghKoWWq@2lBThSwh{=S_as-I6VOG6Y*A&%|=w$mY7y`on-rlUYYx;l| z2LsrhF4j3xeJYHFfnx6<>5U{+zs1im*0O z)f+tatk-A#)G{kL2(@TJD10TR-kaVxDBj?7d2X=Y({&m0Yp?#g6OSp~D`cWfgubs9 z+}quAH!1@}BA*(>a0bxdl&L{sx9*=|mO%(mQ&QYZ0l68P$!$sMBt#nTB{7?GEltfw2n8n+ZKk|TWhl_>3-gSUkt^<)!g|8y!Zk? zg9BsNd(`)q>UJbAJsN4i zy7ffo=0_>#4c9$1#Oo6m254hF$pQ=jhiz!~+ioH*f0;Jat*#F=&+hInUA=mxF8F-x z)|cIM2i{+${In(X{`$MKb9JVPl}xZewXW1!y3Xhcv=aTZN|Ol9opaBLb-DzGy@MGL za!LClz1{5z^|*h&kh~jbzL8HwP4o`Pdqt%7ZK^4Y^4$J3I|DzR&IHoMJPN+5THmr_ zm5W#Ev}r9Dc9*RPX7T1K1Zd#+YAi$dGDQ?l^3wd)uK-~7adp%;U18d0iYV8sd8yaQ zqRTszv96fkn@H&mV6|F*pfvtWoif_n-!nm*Yr+{3R22N5f^tvz!Eg^d3hR_;D?u1Q zqOJq786hydpcn=pYu97&-(lRM%Gx^C=rqNTp_2{JD5ls4;IXj1N_c&Mlh6y>nLBFZ`Ue|cw+|6fS`T z-G=H=4wZ1ANDSkHZv4>jsM|py8)<7RdIqO5AXq>XA7IB>5D1@go5ok96RM=}C7t6( z<`+~FU|Bm_xlSM?&x8gj(75x@Q~d(`FcO1lS^y^_vO7NApgAJG^@;bFV0Dt}PM~HL zao;?SJti5}u|au&#_+xY_KJIsa&`CW)w%FKzmLXzjnkLTKl^CWklT(NIm$A_i(6F?xgj9|0$`2zEr#;*Sa-{9$nB+7&#g{uz}kh@81fA$^-k7Su%e!i zj#Fd~ltIp4DN_$?;9()9v5WJYD{rY9*O}wq5JzJO{Quq;Tn0igI|TKHYnY-OdZ~FG zb`N=lF1B-{bGdJAd~y33lG|Sz!AJXI_v#K`t)YBD|69+-*k99%7838Rf1tKd2N2Uc zeCaWCZG+R=?Dm^&SW(HC^s6QqQ$V~cj%xFtN-EB_5TKIRBjKrSXwr%Diy5H@-5CF; z-qR3~Z`-jV{RoFyMy8>Xd*;|YTO+}A$xTk_%O13~VFs8KGtB=t<3Z(D0-n7JJfyzF z2AgN{{%G`JNW`JZKwD5>p^le8{d5fjYgPH{2)eb+pp>+T^xU5{XmMes*b)(ez_p`*6bZuY1E`G<1(+F-C8LWi zp;2i&5yVrDz<_rcwO?O9#LG04skv$dwB_&XPI>f$Zp0)5K$-q91j=E}vDpATd_ScgU zlnSrvt7LJrD<=1gC^SUN=++6&P<6W(FqnJcQdC|=$($se$8|*#mlcGJKAqSl?M;V6 z@@+W)*>G$@SyqE;TbXHXd;LH~86X>^w6KGSk{ked5NWGH)%ZV!aUlt`dtoP10;rGK z{e|@wS{fX&#pu(OCL#woUbmT~GCb<_Oj!(HJq*^Os{dEMpFc4}*6}wEHYhyl%%e6naTp$5J2RAJP4B zoM$luYn82&s<-9OrZBk;ZMDw-?;$)%TREEH0~9PNF`0*SMYXoGaS|oZBAozijh964 zrF`28+JP?BcU^er>g8#NlP^3gKXdC~+A}AnL!|TP&!5?m)u-#M(AM@gpEz+M`nPc{ zt`d#WFc@0MzoEWyp@Z_zE!v(p1VSIt1NFJU2Xz`hu`@y$oaz|VzmX?$8mCL`Ym(D< zg{@rz7TLn5$!NCB)MLWgr1}E<=bk2iRBOEziy+-7AGn{lhr}{6;7>mqNTarhe0m(h zVq;a?Tei*ttz55ui*RQ?rwPz3f^5CIW?eX*HZ{J#PeY%vm>B!Nee5_85 zHev^LX2nu9w9Z0BP)Q(@Sy3Plcwpjmy*Hpn2`?a<__GSKuRk`Wh7MGowCNGucD`Cs z7Y+{S8-hWW%aXC6BIhb-L%$-;pZoH>=jTDR3=Gmr6S>%tBgXioL7^~o!AsQ4f_K6vu5z|zX++9~H5 zbRr@qH5x++nm$Kz>h0`JzuZyJFN28bZ7&p>Fn9lpDFGCKs_$gOeNmBiiBV%+Q%@kyrIM@ z7>53-L0Nr7oqQP3)I^b#sJ97@zZtnR%0e4@ZiT{XkLvhv*v8H5ounbzre4^5eC^t5(3k z0?*M|dg@q)Jks*6#6ormuVXP4AbLyt^KkaA;aNIzqVM7NcV0I3OZlL~HNtUZJ^N zFz+GMjR6?E5+%27A&7=$2_@AtSs6qjff!UfBy_AKg^xT*l8Mn`;RK8s1dNLaLNcdE z&})eU0tJrX=$XsGOBlkM{GuE)&EZ*10wn8`r0n*qf5^LX#-0~DI zcO4j(Qu3n6pM-PvU+6;~)a9X?xGW8LWY})>4khhexolxiDgOg6RQWq1Ur0KC{=(fm zQnyv%+lplQ#HmxVve(ibkpW#5X_%9nrPiT@(|pN`gnZQ3jU1_h)%^dR0IvnMNu~0YVC?k`@_8ItC&EDz3$0$zMaxdT9PpOa0 zOQ4*PE<$b*Yu(dpr$%SdX(3%mHNcE z5P0>9Cd5&O?RC9ZfQ*fGJGtK{zL) zyjFw6`UJ{iF?BgvF%2S&f(2iB$V3MZye`iM|0oeoZNaKL7QRo%6ZB*a` z9-LPQ*97~IlEKilO9@}Sa;c0puTD>RtB$pYT<7RIB&O?}9)J3|?_aItJ*Dc~Yp)$W zc9f1DJ=(e1>^3{9r0e{k@GYOeoKMtkz>6-vE1UA6;EgtR#lp^38ZoND`UK@FA>?wy z9o?f8DaFBY3=M~jIB*QE8;|wtFV9|e3XNXrcd1lmOku7`MCi!dh7bL z{oQGNafUaY@E*=2Wt8RYj12rTn;m`-9d4r1=FVg=0o~>cYXh576 zp9v8n7O5~}Sb=Yok^FzwhFvyg*) zwWJ8)PH}{Ojj2avTB4UjNEt$|3p;?k=%qN;FYYeBNH!T$Ks$>JhfL_2W;DOd&2- z;*zlST0poMVNxtJJX)D z>-}}hFVF0+>3!e(+7~{(dD!$-F#t_pI{)0e3d8R$>UO)fzP-IYd4#R)ElQj3_@{T4 zI-5*sHhG9SMHB_cOT+k6s92M)86^LnJOssU(v z^6B$$r`6WGiZI?j5z!E9YioHX5t59RF-;E4)meQYz0cfgAtZ9Gi&E?_DyUNJ#%`{VF$iCXD#=s?1+M46y zl97vXsE-ZGY{5#4Wwnv4cq2u0B^-uFslM)<#%UPZ5zoB@f3X zQnwNL!#_<3y%cgSF|}x@(-bAozw7#6{qpD(&)3_i@XgX5=kf!|-@psp@I^=);Y zDJp&TOhd02_@PMCmrMNr@K>lC0n?^%YmmArP$OZ;Su=P!SD@>`ViLc%+NWRrvs8La zUo!@f)1&9lpE@{#jIU%aq^2D~-^9-Im42fpPiUjpI{8=t0000 - + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_original_label.xml b/app/src/main/res/drawable/bg_original_label.xml index 42a21d8681..da49c23a8b 100644 --- a/app/src/main/res/drawable/bg_original_label.xml +++ b/app/src/main/res/drawable/bg_original_label.xml @@ -3,6 +3,6 @@ android:shape = "rectangle" > - + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_vfeedback_label.xml b/app/src/main/res/drawable/bg_vfeedback_label.xml new file mode 100644 index 0000000000..2ae7cc065d --- /dev/null +++ b/app/src/main/res/drawable/bg_vfeedback_label.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_vfeedback_label_selected.xml b/app/src/main/res/drawable/bg_vfeedback_label_selected.xml new file mode 100644 index 0000000000..e0442f404b --- /dev/null +++ b/app/src/main/res/drawable/bg_vfeedback_label_selected.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/button_round_2496ff_alpha_10.xml b/app/src/main/res/drawable/button_round_2496ff_alpha_10.xml index 59dd042258..eac647bcc8 100644 --- a/app/src/main/res/drawable/button_round_2496ff_alpha_10.xml +++ b/app/src/main/res/drawable/button_round_2496ff_alpha_10.xml @@ -4,6 +4,6 @@ - + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_vgame_feedback.xml b/app/src/main/res/layout/dialog_vgame_feedback.xml new file mode 100644 index 0000000000..a1788574f6 --- /dev/null +++ b/app/src/main/res/layout/dialog_vgame_feedback.xml @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_vdownload_manager.xml b/app/src/main/res/layout/fragment_vdownload_manager.xml new file mode 100644 index 0000000000..95422d7a5f --- /dev/null +++ b/app/src/main/res/layout/fragment_vdownload_manager.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_vdownload_manager_wrapper.xml b/app/src/main/res/layout/fragment_vdownload_manager_wrapper.xml new file mode 100644 index 0000000000..ddefad4f63 --- /dev/null +++ b/app/src/main/res/layout/fragment_vdownload_manager_wrapper.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_vgame.xml b/app/src/main/res/layout/item_home_vgame.xml new file mode 100644 index 0000000000..77d9ef65f8 --- /dev/null +++ b/app/src/main/res/layout/item_home_vgame.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_vfeedback_option.xml b/app/src/main/res/layout/item_vfeedback_option.xml new file mode 100644 index 0000000000..7d8a7f3fc6 --- /dev/null +++ b/app/src/main/res/layout/item_vfeedback_option.xml @@ -0,0 +1,24 @@ + + + + + + \ No newline at end of file diff --git a/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java b/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java index f7cea9d1d7..3ca4ec85b2 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java +++ b/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java @@ -420,6 +420,9 @@ public class Constants { // 工具箱历史记录(最多4个) public static final String TOOLBOX_HISTORY = "toolbox_history"; + // 首页畅玩广场最近在玩的区域是否显示的 SP_KEY + public static final String SP_HOME_VGAME_AREA_ENABLED = "home_vgame_area_enabled"; + // 浏览器安装说明url public static final String SP_BROWSER_HINT_URL = "browser_hint_url"; public static final String DEFAULT_OPPO_BROWSER_HINT_URL = "https://static-web.ghzs.com/ghzs_help/help.html?content=5fa90fe143d91a022e0d33ff"; diff --git a/module_common/src/main/res/values/colors.xml b/module_common/src/main/res/values/colors.xml index a49a463c76..669ac8a7e3 100644 --- a/module_common/src/main/res/values/colors.xml +++ b/module_common/src/main/res/values/colors.xml @@ -4,6 +4,7 @@ #2496FF #332496FF #CC2496FF + #1A2496FF #FFA142 From c7143a6f89464b7d784e4e9d57e22bbb2dcca683 Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 19 May 2022 18:25:09 +0800 Subject: [PATCH 013/217] =?UTF-8?q?=E5=AE=8C=E6=88=90=E7=AE=80=E9=99=8B?= =?UTF-8?q?=E7=9A=84=E9=A6=96=E9=A1=B5=E6=9C=80=E8=BF=91=E7=95=85=E7=8E=A9?= =?UTF-8?q?=20item=20UI=20&=20=E8=B0=83=E6=95=B4=E5=8E=9F=E6=9C=89?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E7=9A=84=E9=A2=9C=E8=89=B2=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/common/databind/BindingAdapters.java | 2 +- .../search/ForumContentSearchListAdapter.kt | 2 +- .../qa/answer/detail/AnswerDetailFragment.kt | 2 +- .../qa/answer/edit/AnswerEditActivity.kt | 2 +- .../qa/editor/VideoAlbumsSpanner.kt | 2 +- .../qa/questions/detail/AnswerViewHolder.java | 2 +- .../res/drawable-xxhdpi/bg_video_control.xml | 2 +- .../main/res/drawable/bg_forum_game_zone.xml | 2 +- app/src/main/res/drawable/bg_forum_rule.xml | 2 +- .../bg_game_collection_user_container.xml | 2 +- .../bg_game_collectionchange_poster.xml | 2 +- .../bg_home_vgame_progress_active.xml | 24 +++++++ .../bg_home_vgame_progress_inactive.xml | 24 +++++++ .../main/res/drawable/bg_pic_count_label.xml | 2 +- .../bg_shape_black_alpha_40_radius_2.xml | 2 +- .../main/res/drawable/bg_vgame_icon_mask.xml | 10 +++ .../drawable/button_round_black_alpha_60.xml | 2 +- .../drawable/game_collection_poster_mask.xml | 2 +- .../drawable/game_detail_video_bottom_bg.xml | 2 +- .../drawable/oval_hint_accent_stroke_bg.xml | 11 ++++ .../visit_history_video_bottom_bg.xml | 2 +- .../res/layout/activity_background_clip.xml | 2 +- app/src/main/res/layout/activity_comment.xml | 2 +- .../main/res/layout/dialog_choose_forum.xml | 2 +- app/src/main/res/layout/fragment_comment.xml | 2 +- .../main/res/layout/fragment_forum_home.xml | 2 +- .../fragment_game_collection_poster.xml | 2 +- .../res/layout/fragment_preview_video.xml | 6 +- .../main/res/layout/item_community_image.xml | 2 +- app/src/main/res/layout/item_home_vgame.xml | 66 ++++++++++++++++++- .../res/layout/layout_article_item_video.xml | 4 +- ..._forum_video_detail_videoview_portrait.xml | 2 +- .../src/main/res/values-night/colors.xml | 6 +- module_common/src/main/res/values/colors.xml | 28 +++++++- 34 files changed, 191 insertions(+), 38 deletions(-) create mode 100644 app/src/main/res/drawable/bg_home_vgame_progress_active.xml create mode 100644 app/src/main/res/drawable/bg_home_vgame_progress_inactive.xml create mode 100644 app/src/main/res/drawable/bg_vgame_icon_mask.xml create mode 100644 app/src/main/res/drawable/oval_hint_accent_stroke_bg.xml diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java index 5e451a812e..61fca9c2f7 100644 --- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java +++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java @@ -777,7 +777,7 @@ public class BindingAdapters { public static void setCommunityVideoDuration(TextView mVideoDuration, List videos) { if (videos != null && videos.size() > 0) { CommunityVideoEntity videoEntity = videos.get(0); - mVideoDuration.setBackground(DrawableView.getOvalDrawable(R.color.black_alpha_80, 999F)); + mVideoDuration.setBackground(DrawableView.getOvalDrawable(R.color.black_alpha_50, 999F)); mVideoDuration.setText(videoEntity.getDuration()); mVideoDuration.setVisibility(View.VISIBLE); } else { diff --git a/app/src/main/java/com/gh/gamecenter/forum/search/ForumContentSearchListAdapter.kt b/app/src/main/java/com/gh/gamecenter/forum/search/ForumContentSearchListAdapter.kt index bcca9352cf..dcc4dd7e91 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/search/ForumContentSearchListAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/search/ForumContentSearchListAdapter.kt @@ -212,7 +212,7 @@ class ForumContentSearchListAdapter(context: Context, val mListViewModel: ForumC durationTv.goneIf(answer.getPassVideos().isEmpty()) durationTv.text = if (answer.getPassVideos().isNotEmpty()) answer.getPassVideos()[0].duration else "00:00" durationTv.background = GradientDrawable().apply { - setColor(R.color.black_alpha_40.toColor(mContext)) + setColor(R.color.black_alpha_60.toColor(mContext)) cornerRadius = 2F.dip2px().toFloat() } countTv.text = "${answer.count.comment}评论 · ${answer.count.vote}点赞" diff --git a/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailFragment.kt index 9b7fb9d457..8eedb1e820 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailFragment.kt @@ -1029,7 +1029,7 @@ open class AnswerDetailFragment : ToolbarFragment() { mQuestionBinding.videoStatus.visibleIf(video != null && video.status != "pass") mQuestionBinding.videoDuration.visibleIf(video?.status == "pass") if (video?.status == "pass") { - mQuestionBinding.videoDuration.background = DrawableView.getOvalDrawable(R.color.black_alpha_80, 999f) + mQuestionBinding.videoDuration.background = DrawableView.getOvalDrawable(R.color.black_alpha_50, 999f) mQuestionBinding.videoDuration.text = video.duration } else { val status = if (!question.me.isContentOwner && !question.me.isModerator && video?.status == "fail") { diff --git a/app/src/main/java/com/gh/gamecenter/qa/answer/edit/AnswerEditActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/answer/edit/AnswerEditActivity.kt index e75f5de0ec..c067aabcf0 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/answer/edit/AnswerEditActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/answer/edit/AnswerEditActivity.kt @@ -293,7 +293,7 @@ class AnswerEditActivity : BaseRichEditorActivity(), Keyboa mBinding.videoStatus.visibleIf(video != null && video.status != "pass") mBinding.videoDuration.visibleIf(video?.status == "pass") if (video?.status == "pass") { - mBinding.videoDuration.background = DrawableView.getOvalDrawable(R.color.black_alpha_80, 999f) + mBinding.videoDuration.background = DrawableView.getOvalDrawable(R.color.black_alpha_50, 999f) mBinding.videoDuration.text = video.duration } else { val status = if (!question.me.isContentOwner && !question.me.isModerator && video?.status == "fail") { diff --git a/app/src/main/java/com/gh/gamecenter/qa/editor/VideoAlbumsSpanner.kt b/app/src/main/java/com/gh/gamecenter/qa/editor/VideoAlbumsSpanner.kt index f033d07d5a..83d6df9f11 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/editor/VideoAlbumsSpanner.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/editor/VideoAlbumsSpanner.kt @@ -60,7 +60,7 @@ class VideoAlbumsSpanner(val context: Context) { //添加半透明maskView val maskView = View(context) val maskViewParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, popupHeight) - maskView.background = ColorDrawable(ContextCompat.getColor(context, R.color.black_alpha_60)) + maskView.background = ColorDrawable(ContextCompat.getColor(context, R.color.black_alpha_40)) maskView.layoutParams = maskViewParams parentContainer.addView(maskView, 0) maskView.setOnClickListener { diff --git a/app/src/main/java/com/gh/gamecenter/qa/questions/detail/AnswerViewHolder.java b/app/src/main/java/com/gh/gamecenter/qa/questions/detail/AnswerViewHolder.java index 1fd5026fc4..f2dd0dd312 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/questions/detail/AnswerViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/qa/questions/detail/AnswerViewHolder.java @@ -154,7 +154,7 @@ public class AnswerViewHolder extends BaseRecyclerViewHolder { if (videos.size() > 0) { CommunityVideoEntity videoEntity = videos.get(0); ImageUtils.display(binding.askAnswerItemImg, videoEntity.getPoster()); - binding.askAnswerItemVideoDuration.setBackground(DrawableView.getOvalDrawable(R.color.black_alpha_80, 999F)); + binding.askAnswerItemVideoDuration.setBackground(DrawableView.getOvalDrawable(R.color.black_alpha_50, 999F)); binding.askAnswerItemVideoDuration.setText(videoEntity.getDuration()); binding.askAnswerItemVideoDuration.setVisibility(View.VISIBLE); binding.askAnswerItemVideoPlay.setVisibility(View.VISIBLE); diff --git a/app/src/main/res/drawable-xxhdpi/bg_video_control.xml b/app/src/main/res/drawable-xxhdpi/bg_video_control.xml index 5e78703298..e23cb35da6 100644 --- a/app/src/main/res/drawable-xxhdpi/bg_video_control.xml +++ b/app/src/main/res/drawable-xxhdpi/bg_video_control.xml @@ -2,6 +2,6 @@ diff --git a/app/src/main/res/drawable/bg_forum_game_zone.xml b/app/src/main/res/drawable/bg_forum_game_zone.xml index 3582e13a59..4bfa5a5ea3 100644 --- a/app/src/main/res/drawable/bg_forum_game_zone.xml +++ b/app/src/main/res/drawable/bg_forum_game_zone.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_forum_rule.xml b/app/src/main/res/drawable/bg_forum_rule.xml index a67f7c8bba..3c8cdeadd6 100644 --- a/app/src/main/res/drawable/bg_forum_rule.xml +++ b/app/src/main/res/drawable/bg_forum_rule.xml @@ -8,6 +8,6 @@ android:width="1dp" android:color="@color/white_alpha_20" /> - + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_game_collection_user_container.xml b/app/src/main/res/drawable/bg_game_collection_user_container.xml index fa06805b62..6256437e4a 100644 --- a/app/src/main/res/drawable/bg_game_collection_user_container.xml +++ b/app/src/main/res/drawable/bg_game_collection_user_container.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_game_collectionchange_poster.xml b/app/src/main/res/drawable/bg_game_collectionchange_poster.xml index fa06805b62..6256437e4a 100644 --- a/app/src/main/res/drawable/bg_game_collectionchange_poster.xml +++ b/app/src/main/res/drawable/bg_game_collectionchange_poster.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_home_vgame_progress_active.xml b/app/src/main/res/drawable/bg_home_vgame_progress_active.xml new file mode 100644 index 0000000000..7b7b58ed9e --- /dev/null +++ b/app/src/main/res/drawable/bg_home_vgame_progress_active.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_home_vgame_progress_inactive.xml b/app/src/main/res/drawable/bg_home_vgame_progress_inactive.xml new file mode 100644 index 0000000000..2b643c6188 --- /dev/null +++ b/app/src/main/res/drawable/bg_home_vgame_progress_inactive.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_pic_count_label.xml b/app/src/main/res/drawable/bg_pic_count_label.xml index e918ee8da8..04c5f13230 100644 --- a/app/src/main/res/drawable/bg_pic_count_label.xml +++ b/app/src/main/res/drawable/bg_pic_count_label.xml @@ -2,5 +2,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_shape_black_alpha_40_radius_2.xml b/app/src/main/res/drawable/bg_shape_black_alpha_40_radius_2.xml index da35f81358..8c1adb483d 100644 --- a/app/src/main/res/drawable/bg_shape_black_alpha_40_radius_2.xml +++ b/app/src/main/res/drawable/bg_shape_black_alpha_40_radius_2.xml @@ -2,5 +2,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_vgame_icon_mask.xml b/app/src/main/res/drawable/bg_vgame_icon_mask.xml new file mode 100644 index 0000000000..1a21fffb10 --- /dev/null +++ b/app/src/main/res/drawable/bg_vgame_icon_mask.xml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/button_round_black_alpha_60.xml b/app/src/main/res/drawable/button_round_black_alpha_60.xml index 2131b51661..e3597ca745 100644 --- a/app/src/main/res/drawable/button_round_black_alpha_60.xml +++ b/app/src/main/res/drawable/button_round_black_alpha_60.xml @@ -4,6 +4,6 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/game_collection_poster_mask.xml b/app/src/main/res/drawable/game_collection_poster_mask.xml index 7227ba3990..6f3766673f 100644 --- a/app/src/main/res/drawable/game_collection_poster_mask.xml +++ b/app/src/main/res/drawable/game_collection_poster_mask.xml @@ -5,6 +5,6 @@ \ No newline at end of file diff --git a/app/src/main/res/drawable/game_detail_video_bottom_bg.xml b/app/src/main/res/drawable/game_detail_video_bottom_bg.xml index 83ed383b91..569bad62d9 100644 --- a/app/src/main/res/drawable/game_detail_video_bottom_bg.xml +++ b/app/src/main/res/drawable/game_detail_video_bottom_bg.xml @@ -7,7 +7,7 @@ android:topRightRadius="0dp" /> \ No newline at end of file diff --git a/app/src/main/res/drawable/oval_hint_accent_stroke_bg.xml b/app/src/main/res/drawable/oval_hint_accent_stroke_bg.xml new file mode 100644 index 0000000000..941f8e3052 --- /dev/null +++ b/app/src/main/res/drawable/oval_hint_accent_stroke_bg.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/visit_history_video_bottom_bg.xml b/app/src/main/res/drawable/visit_history_video_bottom_bg.xml index 1cc116bec2..8e20ea5d51 100644 --- a/app/src/main/res/drawable/visit_history_video_bottom_bg.xml +++ b/app/src/main/res/drawable/visit_history_video_bottom_bg.xml @@ -3,7 +3,7 @@ \ No newline at end of file diff --git a/app/src/main/res/layout/activity_background_clip.xml b/app/src/main/res/layout/activity_background_clip.xml index 49c8ca158b..9a80012f5e 100644 --- a/app/src/main/res/layout/activity_background_clip.xml +++ b/app/src/main/res/layout/activity_background_clip.xml @@ -23,7 +23,7 @@ diff --git a/app/src/main/res/layout/activity_comment.xml b/app/src/main/res/layout/activity_comment.xml index c2abaa65f0..46b2fb1679 100644 --- a/app/src/main/res/layout/activity_comment.xml +++ b/app/src/main/res/layout/activity_comment.xml @@ -8,7 +8,7 @@ android:id="@+id/maskView" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/black_alpha_60"/> + android:background="@color/black_alpha_40"/> + android:background="@color/black_alpha_40" /> diff --git a/app/src/main/res/layout/fragment_forum_home.xml b/app/src/main/res/layout/fragment_forum_home.xml index 9c53e3889d..fc8e4b0a7c 100644 --- a/app/src/main/res/layout/fragment_forum_home.xml +++ b/app/src/main/res/layout/fragment_forum_home.xml @@ -226,7 +226,7 @@ android:id="@+id/guideMaskView" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/black_alpha_80" + android:background="@color/black_alpha_50" android:visibility="gone"> + android:background="@color/black_alpha_60" /> @@ -28,7 +28,7 @@ @@ -44,7 +44,7 @@ diff --git a/app/src/main/res/layout/item_community_image.xml b/app/src/main/res/layout/item_community_image.xml index 790df8a964..22ebc7bc46 100644 --- a/app/src/main/res/layout/item_community_image.xml +++ b/app/src/main/res/layout/item_community_image.xml @@ -44,7 +44,7 @@ android:id="@+id/pendingView" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/black_alpha_40" + android:background="@color/black_alpha_60" android:gravity="center" android:lineSpacingExtra="4dp" android:paddingLeft="16dp" diff --git a/app/src/main/res/layout/item_home_vgame.xml b/app/src/main/res/layout/item_home_vgame.xml index 77d9ef65f8..8e868d823f 100644 --- a/app/src/main/res/layout/item_home_vgame.xml +++ b/app/src/main/res/layout/item_home_vgame.xml @@ -1,6 +1,68 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_article_item_video.xml b/app/src/main/res/layout/layout_article_item_video.xml index c9e6bbf129..37452bf0f1 100644 --- a/app/src/main/res/layout/layout_article_item_video.xml +++ b/app/src/main/res/layout/layout_article_item_video.xml @@ -59,7 +59,7 @@ android:id="@+id/pendingView" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/black_alpha_40" + android:background="@color/black_alpha_60" android:gravity="center" android:textColor="@color/white_alpha_80" android:textSize="12sp" @@ -107,7 +107,7 @@ android:id="@+id/completeContainer" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/black_alpha_40" + android:background="@color/black_alpha_60" android:gravity="center" android:orientation="horizontal" android:visibility="gone" diff --git a/app/src/main/res/layout/layout_forum_video_detail_videoview_portrait.xml b/app/src/main/res/layout/layout_forum_video_detail_videoview_portrait.xml index 78cd422789..4786795e6b 100644 --- a/app/src/main/res/layout/layout_forum_video_detail_videoview_portrait.xml +++ b/app/src/main/res/layout/layout_forum_video_detail_videoview_portrait.xml @@ -54,7 +54,7 @@ android:id="@+id/pendingView" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/black_alpha_40" + android:background="@color/black_alpha_60" android:gravity="center" android:text="@string/pending_status" android:textColor="@color/white_alpha_80" diff --git a/module_common/src/main/res/values-night/colors.xml b/module_common/src/main/res/values-night/colors.xml index f259427c39..20f3897d06 100644 --- a/module_common/src/main/res/values-night/colors.xml +++ b/module_common/src/main/res/values-night/colors.xml @@ -159,9 +159,9 @@ #1A000000 #33000000 #4D000000 - #99000000 - #66000000 - #80000000 + #99000000 + #66000000 + #80000000 #1AFFFFFF #33FFFFFF diff --git a/module_common/src/main/res/values/colors.xml b/module_common/src/main/res/values/colors.xml index 669ac8a7e3..cbe8913539 100644 --- a/module_common/src/main/res/values/colors.xml +++ b/module_common/src/main/res/values/colors.xml @@ -167,9 +167,31 @@ #1A000000 #33000000 #4D000000 - #99000000 - #66000000 - #80000000 + #66000000 + #80000000 + #99000000 + + #CC000000 #1AFFFFFF #33FFFFFF From 7837318390f6cac0cb25bbb2ea1860c1a649a8e1 Mon Sep 17 00:00:00 2001 From: juntao Date: Fri, 20 May 2022 18:01:56 +0800 Subject: [PATCH 014/217] =?UTF-8?q?=E9=A6=96=E9=A1=B5=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=9C=80=E8=BF=91=E5=9C=A8=E7=8E=A9=E5=8D=A0=E4=BD=8D=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/download/DownloadManager.java | 41 ++++++------ .../gh/gamecenter/home/HomeFragmentAdapter.kt | 46 ++++++-------- .../com/gh/gamecenter/home/HomeItemData.kt | 1 + .../com/gh/gamecenter/home/HomeViewModel.kt | 43 +++++++++++++ .../gh/vspace/HomeRecentVGameViewHolder.kt | 14 +++++ .../gh/vspace/VDownloadManagerViewModel.kt | 38 ++++++------ .../res/drawable/bg_home_recent_vgame.xml | 10 +++ .../res/layout/item_home_recent_vgame.xml | 62 +++++++++++++++++++ module_common/src/main/res/values/colors.xml | 1 + 9 files changed, 187 insertions(+), 69 deletions(-) create mode 100644 app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt create mode 100644 app/src/main/res/drawable/bg_home_recent_vgame.xml create mode 100644 app/src/main/res/layout/item_home_recent_vgame.xml diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index 8ee62f9746..e353b71afc 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -12,6 +12,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; import androidx.collection.ArrayMap; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; import com.gh.gamecenter.common.utils.ExtensionsKt; import com.gh.gamecenter.core.AppExecutor; @@ -89,13 +91,15 @@ public class DownloadManager implements DownloadStatusListener { // 下载任务列表快照,非完全实时状态,只保证数量和基础状态,不保证下载进度和速度匹配 // TODO 使用 mDownloadSnapshotList 来服务 getDownloadEntityByUrl - // private final List mDownloadSnapshotList; +// private final List mDownloadSnapshotList; private ArrayList mInvisiblePendingTaskList; // 用户不可见的 pending 任务 private final DownloadDao mDownloadDao; private final DownloadedGameIdAndPackageNameDao mDownloadedGameIdAndPackageNameDao; + private final MutableLiveData> mDownloadEntityListLiveData; // 下载任务变更 (主要还是数量变更) 的 LiveData + private final Set mUpdateMarks; @Override @@ -108,6 +112,8 @@ public class DownloadManager implements DownloadStatusListener { DownloadManager.getInstance().putStatus(entity.getUrl(), DownloadStatus.delete); downloadingMap.remove(entity.getUrl()); + + AppExecutor.getIoExecutor().execute(() -> mDownloadEntityListLiveData.postValue(getAllDownloadEntity())); } @Override @@ -118,6 +124,8 @@ public class DownloadManager implements DownloadStatusListener { downloadingMap.put(entity.getUrl(), entity); DownloadWorkManager.addWorker(); + + AppExecutor.getIoExecutor().execute(() -> mDownloadEntityListLiveData.postValue(getAllDownloadEntity())); } @Override @@ -126,6 +134,8 @@ public class DownloadManager implements DownloadStatusListener { if (entity.getStatus() != DownloadStatus.overflow) { downloadingMap.remove(entity.getUrl()); } + + AppExecutor.getIoExecutor().execute(() -> mDownloadEntityListLiveData.postValue(getAllDownloadEntity())); } @Override @@ -143,6 +153,8 @@ public class DownloadManager implements DownloadStatusListener { if (downloadingMap.isEmpty()) { DownloadWorkManager.cancelWorker(); } + + AppExecutor.getIoExecutor().execute(() -> mDownloadEntityListLiveData.postValue(getAllDownloadEntity())); } @Override @@ -154,6 +166,7 @@ public class DownloadManager implements DownloadStatusListener { mContext = HaloApp.getInstance().getApplicationContext(); mDownloadDao = DownloadDao.getInstance(mContext); mDownloadedGameIdAndPackageNameDao = new DownloadedGameIdAndPackageNameDao(); + mDownloadEntityListLiveData = new MutableLiveData<>(); mUpdateMarks = SPUtils.getStringSet(UPDATE_IS_READ_MARK); @@ -639,7 +652,7 @@ public class DownloadManager implements DownloadStatusListener { /** * 获取下载列表中的畅玩下载任务 */ - public List getAllSmoothDownloadTask() { + public List getAllVDownloadTask() { List downloadList = getAllDownloadEntity(); ArrayList filteredDownloadEntityList = new ArrayList<>(); @@ -747,26 +760,6 @@ public class DownloadManager implements DownloadStatusListener { } } - /** - * 取消并删除所有下载任务(包括下载中、等待、暂停状态的任务) - */ - public void cancelAll() { - for (DownloadEntity entry : DataChanger.INSTANCE.getDownloadEntries().values()) { - cancel(entry.getUrl(), true, false); - } - Utils.log(DownloadManager.class.getSimpleName(), "cancel all"); - } - - /** - * 开始所有下载任务 - */ - public void startAll() { - for (DownloadEntity entry : downloadingMap.values()) { - add(entry); - } - Utils.log(DownloadManager.class.getSimpleName(), "start all"); - } - /** * 暂停所有正在下载的任务 */ @@ -1156,6 +1149,10 @@ public class DownloadManager implements DownloadStatusListener { mInvisiblePendingTaskList.clear(); } + public LiveData> getDownloadEntityLiveData() { + return mDownloadEntityListLiveData; + } + /** * 更新下载请求头的相关信息 */ diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt index e56f00bd62..81f80a3b2b 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt @@ -6,13 +6,13 @@ import android.view.ViewGroup import androidx.constraintlayout.widget.ConstraintLayout import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.gh.gamecenter.common.constant.ItemViewType import com.gh.common.exposure.ExposureEvent import com.gh.common.exposure.ExposureSource import com.gh.common.exposure.IExposable import com.gh.gamecenter.core.runOnIoThread import com.gh.common.util.* import com.gh.common.util.NewLogUtils +import com.gh.common.util.DirectUtils import com.gh.gamecenter.AboutActivity import com.gh.gamecenter.GameDetailActivity import com.gh.gamecenter.R @@ -20,9 +20,12 @@ import com.gh.gamecenter.adapter.viewholder.FooterViewHolder import com.gh.gamecenter.adapter.viewholder.ReuseViewHolder import com.gh.gamecenter.baselist.DiffUtilAdapter import com.gh.gamecenter.baselist.LoadStatus +import com.gh.gamecenter.common.constant.ItemViewType +import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.* +import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.core.utils.MtaHelper -import com.gh.gamecenter.databinding.* +import com.gh.gamecenter.databinding.HomeDividerItemBinding import com.gh.gamecenter.entity.AmwayCommentEntity import com.gh.gamecenter.eventbus.EBDownloadStatus import com.gh.gamecenter.game.GameAndPosition @@ -34,6 +37,7 @@ import com.gh.gamecenter.home.gamecollection.HomeGameCollectionViewHolder import com.gh.gamecenter.home.slide.HomeSlideListAdapter import com.gh.gamecenter.home.slide.HomeSlideListViewHolder import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel +import com.gh.vspace.HomeRecentVGameViewHolder import com.halo.assistant.fragment.game.GamePluginAdapter import com.lightgame.download.DownloadEntity import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder @@ -64,6 +68,7 @@ class HomeFragmentAdapter( if (oldItem?.pluginList != null && newItem?.pluginList != null) return true if (oldItem?.verticalSlide != null && newItem?.verticalSlide != null) return true if (oldItem?.horizontalColumn != null && newItem?.horizontalColumn != null) return true + if (oldItem?.recentVGame != null && newItem?.recentVGame != null) return true if (oldItem?.columnHead != null && newItem?.columnHead != null) return true if (oldItem?.horizontalSlide != null && newItem?.horizontalSlide != null) return true return super.areItemsTheSame(oldItem, newItem) @@ -76,6 +81,7 @@ class HomeFragmentAdapter( if (oldItem?.game?.id != newItem?.game?.id) return false if (oldItem?.verticalSlide != null && newItem?.verticalSlide != null) return false if (oldItem?.horizontalColumn != null && newItem?.horizontalColumn != null) return false + if (oldItem?.recentVGame != null && newItem?.recentVGame != null) return false if (oldItem?.columnHead != null && newItem?.columnHead != null) return false if (oldItem?.horizontalSlide != null && newItem?.horizontalSlide != null) return false return super.areContentsTheSame(oldItem, newItem) @@ -100,6 +106,7 @@ class HomeFragmentAdapter( if (itemData.attachGame != null) return GAME_ITEM if (itemData.amway != null) return AMWAY_ITEM if (itemData.gameCollection != null) return GAME_COLLECTION_ITEM + if (itemData.recentVGame != null) return RECENT_V_GAME if (itemData.lineDivider != null) return DIVIDER_ITEM if (itemData.unknownData != null) return UNKNOWN_ITEM @@ -109,30 +116,13 @@ class HomeFragmentAdapter( override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { val view: View return when (viewType) { - SLIDE_ITEM -> { - view = mLayoutInflater.inflate(R.layout.home_slide_list, parent, false) - HomeSlideListViewHolder(HomeSlideListBinding.bind(view), callback) - } - RECOMMENDS_ITEM -> { - view = mLayoutInflater.inflate(R.layout.home_recommend_item, parent, false) - HomeRecommendItemViewHolder(HomeRecommendItemBinding.bind(view)) - } - GAME_ITEM -> { - view = mLayoutInflater.inflate(R.layout.home_game_item, parent, false) - HomeGameItemViewHolder(HomeGameItemBinding.bind(view)) - } - AMWAY_ITEM -> { - view = mLayoutInflater.inflate(R.layout.home_amway_list, parent, false) - HomeAmwayListViewHolder(HomeAmwayListBinding.bind(view)) - } - GAME_COLLECTION_ITEM -> { - view = mLayoutInflater.inflate(R.layout.home_game_collection_item, parent, false) - HomeGameCollectionViewHolder(HomeGameCollectionItemBinding.bind(view)) - } - DIVIDER_ITEM -> { - view = mLayoutInflater.inflate(R.layout.home_divider_item, parent, false) - HomeDividerViewHolder(HomeDividerItemBinding.bind(view)) - } + SLIDE_ITEM -> HomeSlideListViewHolder(parent.toBinding(), callback) + RECOMMENDS_ITEM -> HomeRecommendItemViewHolder(parent.toBinding()) + GAME_ITEM -> HomeGameItemViewHolder(parent.toBinding()) + AMWAY_ITEM -> HomeAmwayListViewHolder(parent.toBinding()) + GAME_COLLECTION_ITEM -> HomeGameCollectionViewHolder(parent.toBinding()) + DIVIDER_ITEM -> HomeDividerViewHolder(parent.toBinding()) + RECENT_V_GAME -> HomeRecentVGameViewHolder(parent.toBinding()) FOOTER_ITEM -> { view = mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false) FooterViewHolder(view) @@ -259,8 +249,7 @@ class HomeFragmentAdapter( }, basicSource = mBasicExposureSource, source = gameCollectionSource - ) - ) + )) } gameCollectionItemData.exposureEventList = gameExposureList exposureList.addAll(gameExposureList) @@ -510,5 +499,6 @@ class HomeFragmentAdapter( const val UNKNOWN_ITEM: Int = 111 const val COMMON_ITEM: Int = 115 const val GAME_COLLECTION_ITEM: Int = 116 + const val RECENT_V_GAME: Int = 117 } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeItemData.kt b/app/src/main/java/com/gh/gamecenter/home/HomeItemData.kt index 6c35cae520..9101a31e34 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeItemData.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeItemData.kt @@ -8,5 +8,6 @@ data class HomeItemData(var slides: List? = null, var amway: List? = null, var gameCollection: List? = null, var attachGame: HomeContent? = null, + var recentVGame: List? = null, var lineDivider: Float? = null, var unknownData: Any? = null) : LegacyHomeItemData() \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index 531e7c418f..47600925b8 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -17,6 +17,7 @@ import com.gh.gamecenter.BuildConfig import com.gh.gamecenter.baselist.LoadStatus import com.gh.gamecenter.common.retrofit.BiResponse import com.gh.gamecenter.common.retrofit.Response +import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.core.utils.RandomUtils import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.entity.* @@ -24,6 +25,7 @@ import com.gh.gamecenter.game.rank.RankCollectionAdapter import com.gh.gamecenter.gamecollection.square.GameCollectionListItemData import com.gh.gamecenter.packagehelper.PackageRepository import com.gh.gamecenter.retrofit.RetrofitManager +import com.gh.vspace.VDownloadManagerViewModel import com.halo.assistant.HaloApp import com.halo.assistant.fragment.SettingsFragment import com.lightgame.utils.Utils @@ -44,6 +46,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { private var mHomeContents = ArrayList() private var mPluginList: List? = null // 插件化 private var mSmartSubject: SubjectEntity? = null // 智能推荐专题 + private var mVGameList: List? = null // 最近的畅玩游戏 private var mContentPage = 1 // 专题分页 private var mIsLoading = false @@ -64,9 +67,14 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { itemDataList.addSource(PackageRepository.gameUpdateLiveData) { initPlugin(it) } + itemDataList.addSource(DownloadManager.getInstance().downloadEntityLiveData) { + refreshRecentVGameIfNeeded() + } loadStatus.postValue(LoadStatus.INIT_LOADING) initData() + + refreshRecentVGameIfNeeded() } fun initData() { @@ -84,6 +92,30 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { } } + fun refreshRecentVGameIfNeeded() { + runOnIoThread { + // TODO VA 安装完成的时候刷新列表 + // TODO 根据开关判断是否隐藏下面的数据 + // TODO 排序 + // TODO 避免多线程异常 + val entityList = DownloadManager.getInstance().allVDownloadTask + + if (!entityList.isNullOrEmpty()) { + val vGameList = arrayListOf() + + for (entity in entityList) { + vGameList.add(VDownloadManagerViewModel.toGameEntity(entity)) + } + + mVGameList = vGameList + + if (mHomeSlides.isNotEmpty() || mHomeRecommends.isNotEmpty()) { + transformationItemData() + } + } + } + } + private fun initPlugin(updateList: List?) { if (updateList == null) return @@ -315,6 +347,17 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { mSnapshotItemList.add(recommend) } + // 最近在玩的畅玩游戏 + if (mVGameList != null && !mVGameList.isNullOrEmpty()) { + val item = HomeItemData() + item.recentVGame = mVGameList + mSnapshotItemList.add(item) + + for (entity in mVGameList!!) { + addGamePositionAndPackage(entity) + } + } + // 插件化 if (mPluginList != null && mPluginList!!.isNotEmpty()) { val plugin = HomeItemData() diff --git a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt new file mode 100644 index 0000000000..0aec76c579 --- /dev/null +++ b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt @@ -0,0 +1,14 @@ +package com.gh.vspace + +import androidx.recyclerview.widget.RecyclerView +import com.gh.gamecenter.databinding.ItemHomeRecentVgameBinding +import com.gh.gamecenter.entity.GameEntity + +class HomeRecentVGameViewHolder(var binding: ItemHomeRecentVgameBinding) : + RecyclerView.ViewHolder(binding.root) { + + fun bindView(gameList: ArrayList) { + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index f9d97112e3..0223e39747 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -30,7 +30,7 @@ class VDownloadManagerViewModel(application: Application) : return Single.create { emitter -> val installedGameList = PackageRepository.installedGameListLiveData.value ?: arrayListOf() - val vDownloadList = DownloadManager.getInstance().allSmoothDownloadTask + val vDownloadList = DownloadManager.getInstance().allVDownloadTask val gameIdSet = hashSetOf() // 游戏 id set,避免下载任务和已安装任务同时出现 val vGameList = arrayListOf() @@ -52,7 +52,7 @@ class VDownloadManagerViewModel(application: Application) : } } else { return Single.create { emitter -> - val vDownloadList = DownloadManager.getInstance().allSmoothDownloadTask + val vDownloadList = DownloadManager.getInstance().allVDownloadTask val gameIdSet = hashSetOf() // 游戏 id set,避免下载任务和已安装任务同时出现 val vGameList = arrayListOf() @@ -69,23 +69,6 @@ class VDownloadManagerViewModel(application: Application) : } } - private fun toGameEntity(downloadEntity: DownloadEntity): GameEntity { - return GameEntity(id = downloadEntity.gameId, name = downloadEntity.name).apply { - setApk( - arrayListOf( - ApkEntity( - packageName = downloadEntity.packageName, - url = downloadEntity.url, - platform = downloadEntity.platform - ) - ) - ) - icon = downloadEntity.icon - downloadStatus = "smooth" - setEntryMap(DownloadManager.getInstance().getEntryMap(name)) - } - } - fun removeItem(url: String?, packageName: String?) { DownloadManager.getInstance().cancel(url) VHelper.uninstall(packageName ?: "") @@ -107,6 +90,23 @@ class VDownloadManagerViewModel(application: Application) : const val TYPE = "type" const val TYPE_DOWNLOADED = "type_downloaded" const val TYPE_DOWNLOADING = "type_downloading" + + fun toGameEntity(downloadEntity: DownloadEntity): GameEntity { + return GameEntity(id = downloadEntity.gameId, name = downloadEntity.name).apply { + setApk( + arrayListOf( + ApkEntity( + packageName = downloadEntity.packageName, + url = downloadEntity.url, + platform = downloadEntity.platform + ) + ) + ) + icon = downloadEntity.icon + downloadStatus = "smooth" + setEntryMap(DownloadManager.getInstance().getEntryMap(name)) + } + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_home_recent_vgame.xml b/app/src/main/res/drawable/bg_home_recent_vgame.xml new file mode 100644 index 0000000000..e68bf5e2a7 --- /dev/null +++ b/app/src/main/res/drawable/bg_home_recent_vgame.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recent_vgame.xml b/app/src/main/res/layout/item_home_recent_vgame.xml new file mode 100644 index 0000000000..88914e7ddb --- /dev/null +++ b/app/src/main/res/layout/item_home_recent_vgame.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/module_common/src/main/res/values/colors.xml b/module_common/src/main/res/values/colors.xml index cbe8913539..b72811d038 100644 --- a/module_common/src/main/res/values/colors.xml +++ b/module_common/src/main/res/values/colors.xml @@ -234,6 +234,7 @@ #F7F7F7 #FFF6E6 #EBF5FF + #F5F8FA #3797FF #EFF7FF #806F9CEF From b0647bf3a94f587c17f5adfc54fe621a6dc4153f Mon Sep 17 00:00:00 2001 From: juntao Date: Fri, 20 May 2022 18:34:15 +0800 Subject: [PATCH 015/217] =?UTF-8?q?=E5=90=88=E5=B9=B6=205.10.0=20=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/download/PackageObserver.kt | 2 -- app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt | 2 +- app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt | 2 +- app/src/main/java/com/halo/assistant/fragment/AboutFragment.kt | 1 + 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/gh/download/PackageObserver.kt b/app/src/main/java/com/gh/download/PackageObserver.kt index 04a8c93dd8..3b5840a4db 100644 --- a/app/src/main/java/com/gh/download/PackageObserver.kt +++ b/app/src/main/java/com/gh/download/PackageObserver.kt @@ -8,8 +8,6 @@ import com.gh.gamecenter.common.loghub.LoghubUtils import com.gh.gamecenter.core.runOnIoThread import com.gh.common.util.* import com.gh.download.server.BrowserInstallHelper -import com.gh.gamecenter.common.constant.Constants -import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.core.utils.ThirdPartyPackageHelper import com.gh.gamecenter.core.utils.UrlFilterUtils import com.gh.gamecenter.entity.GameDigestEntity diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt index 5bbd5ed6b3..7588d26502 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt @@ -1,8 +1,8 @@ package com.gh.vspace import android.os.Bundle -import com.gh.base.ToolBarActivity import com.gh.gamecenter.R +import com.gh.gamecenter.common.base.ToolBarActivity class VDownloadManagerActivity: ToolBarActivity() { diff --git a/app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt b/app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt index c1dab7be5c..4e14d8a869 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt @@ -3,8 +3,8 @@ package com.gh.vspace import android.content.Context import android.content.Intent import android.os.Bundle -import com.gh.base.BaseActivity import com.gh.gamecenter.R +import com.gh.gamecenter.common.base.BaseActivity import com.gh.gamecenter.common.constant.EntranceConsts import com.lightgame.download.DownloadEntity diff --git a/app/src/main/java/com/halo/assistant/fragment/AboutFragment.kt b/app/src/main/java/com/halo/assistant/fragment/AboutFragment.kt index 6f5da8e0f6..139c2bc836 100644 --- a/app/src/main/java/com/halo/assistant/fragment/AboutFragment.kt +++ b/app/src/main/java/com/halo/assistant/fragment/AboutFragment.kt @@ -26,6 +26,7 @@ import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.MtaHelper.onEvent import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.core.utils.StringUtils +import com.gh.gamecenter.core.utils.TimeUtils.getFormatTime import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.databinding.FragmentAboutBinding import com.gh.gamecenter.manager.UpdateManager From 88842de6c74aed41a4a60d932cfc505fc28b572c Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 24 May 2022 18:34:01 +0800 Subject: [PATCH 016/217] =?UTF-8?q?=E5=AE=8C=E6=88=90=E7=B2=97=E6=9A=B4?= =?UTF-8?q?=E7=9A=84=E5=AE=89=E8=A3=85=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 3 + .../gh/common/databind/BindingAdapters.java | 13 +- .../gh/common/util/DetailDownloadUtils.java | 6 +- .../com/gh/common/util/DownloadItemUtils.kt | 20 +- .../java/com/gh/common/util/GameUtils.java | 7 +- .../com/gh/common/util/PackageInstaller.kt | 2 +- .../java/com/gh/download/DownloadManager.java | 17 +- .../adapter/viewholder/DetailViewHolder.java | 12 +- .../com/gh/gamecenter/entity/GameEntity.kt | 6 +- .../com/gh/gamecenter/entity/GameInstall.kt | 3 +- .../gamedetail/GameDetailFragment.kt | 2 +- .../gh/gamecenter/home/HomeFragmentAdapter.kt | 7 + .../com/gh/gamecenter/home/HomeItemData.kt | 2 +- .../com/gh/gamecenter/home/HomeViewModel.kt | 369 +++++++++--------- .../packagehelper/PackageRepository.kt | 21 +- .../gh/vspace/HomeRecentVGameViewHolder.kt | 2 +- .../com/gh/vspace/VDownloadManagerActivity.kt | 7 +- .../com/gh/vspace/VDownloadManagerFragment.kt | 7 +- .../gh/vspace/VDownloadManagerViewModel.kt | 25 +- app/src/main/java/com/gh/vspace/VHelper.kt | 120 ++++-- ...Helper.kt => VLoadCompleteWindowHelper.kt} | 6 +- .../com/gh/vspace/VSpaceLoadingActivity.kt | 19 +- .../com/gh/vspace/VSpaceLoadingFragment.kt | 87 ++++- .../res/layout/fragment_vdownload_manager.xml | 26 +- .../res/layout/fragment_vspace_loading.xml | 33 +- .../common/base/activity/ToolBarActivity.java | 8 + 26 files changed, 517 insertions(+), 313 deletions(-) rename app/src/main/java/com/gh/vspace/{LoadCompleteWindowHelper.kt => VLoadCompleteWindowHelper.kt} (99%) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9d85ffe3cc..9068beac4c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -735,6 +735,9 @@ + + diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java index 61fca9c2f7..0040d7351c 100644 --- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java +++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java @@ -67,6 +67,7 @@ import com.gh.gamecenter.eventbus.EBReuse; import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment; import com.gh.gamecenter.manager.PackagesManager; import com.gh.gamecenter.qa.entity.CommunityVideoEntity; +import com.gh.vspace.VDownloadManagerActivity; import com.gh.vspace.VHelper; import com.lightgame.download.DownloadEntity; import com.lightgame.download.FileUtils; @@ -357,9 +358,13 @@ public class BindingAdapters { switch (progressBar.getDownloadType()) { case DOWNLOADING_PLUGIN: case DOWNLOADING_NORMAL: - Intent intent = DownloadManagerActivity.getDownloadMangerIntent(v.getContext(), - gameEntity.getApk().get(0).getUrl(), entrance); - v.getContext().startActivity(intent); + if (gameEntity.isVGame()) { + v.getContext().startActivity(new Intent(v.getContext(), VDownloadManagerActivity.class)); + } else { + Intent intent = DownloadManagerActivity.getDownloadMangerIntent(v.getContext(), + gameEntity.getApk().get(0).getUrl(), entrance); + v.getContext().startActivity(intent); + } break; case NONE: Utils.toast(v.getContext(), "该游戏已关闭下载"); @@ -427,7 +432,7 @@ public class BindingAdapters { return; } - if (VHelper.isVGame(gameEntity)) { + if (gameEntity.isVGame()) { VHelper.launch((AppCompatActivity) v.getContext(), gameEntity.getApk().get(0).getPackageName()); return; } diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index bc7807a2ab..da62befa1e 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -102,7 +102,7 @@ public class DetailDownloadUtils { } else if (viewHolder.context.getString(R.string.pluggable).equals(status)) { downloadText = "升级" + (TextUtils.isEmpty(downloadAddWord) ? "" : "至" + downloadAddWord) + getDownloadSizeText(viewHolder); } else if (viewHolder.context.getString(R.string.launch).equals(status)) { - if (VHelper.isVGame(viewHolder.gameEntity)) { + if (viewHolder.gameEntity.isVGame()) { downloadText = viewHolder.context.getString(R.string.smooth_launch); } else { downloadText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : "-" + downloadAddWord); @@ -112,7 +112,7 @@ public class DetailDownloadUtils { } else if (viewHolder.context.getString(R.string.install).equals(status)) { downloadText = viewHolder.context.getString(R.string.install); } else if (viewHolder.context.getString(R.string.download).equals(status) - && VHelper.isVGame(viewHolder.gameEntity)) { + && viewHolder.gameEntity.isVGame()) { downloadText = viewHolder.context.getString(R.string.smooth_launch); } else { downloadText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : downloadAddWord) + getDownloadSizeText(viewHolder); @@ -189,7 +189,7 @@ public class DetailDownloadUtils { } viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL); } - } else if (VHelper.isVGame(viewHolder.gameEntity)) { + } else if (viewHolder.gameEntity.isVGame()) { if (VHelper.isInstalled(downloadEntity.getPackageName())) { viewHolder.mDownloadPb.setText(R.string.smooth_launch); viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.LAUNCH_OR_OPEN); diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index f9ee2f0353..199154b3d6 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -1,6 +1,7 @@ package com.gh.common.util import android.content.Context +import android.content.Intent import android.graphics.Color import android.os.Message import android.text.TextUtils @@ -37,6 +38,7 @@ import com.gh.gamecenter.entity.PluginLocation import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment import com.gh.gamecenter.manager.PackagesManager import com.gh.gamecenter.teenagermode.TeenagerModeActivity +import com.gh.vspace.VDownloadManagerActivity import com.gh.vspace.VHelper import com.lightgame.download.DownloadConfig import com.lightgame.download.DownloadEntity @@ -755,7 +757,7 @@ object DownloadItemUtils { return } - if (VHelper.isVGame(gameEntity)) { + if (gameEntity.isVGame()) { VHelper.launch((context as AppCompatActivity), gameEntity.getApk()[0].packageName) return } @@ -776,12 +778,18 @@ object DownloadItemUtils { } }) } else { - context.startActivity( - DownloadManagerActivity.getDownloadMangerIntent( - context, - apk.url, entrance + "+(" + location.split(":").toTypedArray()[0] + ")" + if (gameEntity.isVGame()) { + context.startActivity( + Intent(context, VDownloadManagerActivity::class.java) ) - ) + } else { + context.startActivity( + DownloadManagerActivity.getDownloadMangerIntent( + context, + apk.url, entrance + "+(" + location.split(":").toTypedArray()[0] + ")" + ) + ) + } } } diff --git a/app/src/main/java/com/gh/common/util/GameUtils.java b/app/src/main/java/com/gh/common/util/GameUtils.java index 0eb043815d..b395f21722 100644 --- a/app/src/main/java/com/gh/common/util/GameUtils.java +++ b/app/src/main/java/com/gh/common/util/GameUtils.java @@ -148,8 +148,11 @@ public class GameUtils { return context.getString(R.string.launch); } - if ("smooth".equals(gameEntity.getDownloadStatus())) { - if (doneCount != 0) { + if (gameEntity.isVGame()) { + // 如果 doneCount 为 0 表明本地并没有此游戏的数据库数据,需要重新下载 + if (doneCount == 0) { + installCount = 0; + } else { doneCount = 0; installCount = 1; } diff --git a/app/src/main/java/com/gh/common/util/PackageInstaller.kt b/app/src/main/java/com/gh/common/util/PackageInstaller.kt index d39b51c0ee..67c0fca76f 100644 --- a/app/src/main/java/com/gh/common/util/PackageInstaller.kt +++ b/app/src/main/java/com/gh/common/util/PackageInstaller.kt @@ -13,6 +13,7 @@ import com.gh.common.xapk.XapkInstaller import com.gh.download.server.BrowserInstallHelper import com.gh.gamecenter.BuildConfig import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.retrofit.BiResponse import com.gh.gamecenter.common.utils.DialogHelper import com.gh.gamecenter.common.utils.getExtension import com.gh.gamecenter.common.utils.getMetaExtra @@ -21,7 +22,6 @@ import com.gh.gamecenter.core.utils.CurrentActivityHolder import com.gh.gamecenter.core.utils.MD5Utils import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.core.utils.ToastUtils -import com.gh.gamecenter.common.retrofit.BiResponse import com.gh.gamecenter.retrofit.RetrofitManager import com.gh.vspace.VHelper import com.halo.assistant.HaloApp diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index e353b71afc..bae549f65f 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -113,7 +113,7 @@ public class DownloadManager implements DownloadStatusListener { downloadingMap.remove(entity.getUrl()); - AppExecutor.getIoExecutor().execute(() -> mDownloadEntityListLiveData.postValue(getAllDownloadEntity())); + notifyDownloadLiveDataChanged(); } @Override @@ -125,7 +125,7 @@ public class DownloadManager implements DownloadStatusListener { DownloadWorkManager.addWorker(); - AppExecutor.getIoExecutor().execute(() -> mDownloadEntityListLiveData.postValue(getAllDownloadEntity())); + notifyDownloadLiveDataChanged(); } @Override @@ -135,7 +135,7 @@ public class DownloadManager implements DownloadStatusListener { downloadingMap.remove(entity.getUrl()); } - AppExecutor.getIoExecutor().execute(() -> mDownloadEntityListLiveData.postValue(getAllDownloadEntity())); + notifyDownloadLiveDataChanged(); } @Override @@ -154,7 +154,7 @@ public class DownloadManager implements DownloadStatusListener { DownloadWorkManager.cancelWorker(); } - AppExecutor.getIoExecutor().execute(() -> mDownloadEntityListLiveData.postValue(getAllDownloadEntity())); + notifyDownloadLiveDataChanged(); } @Override @@ -333,7 +333,7 @@ public class DownloadManager implements DownloadStatusListener { ExtensionsKt.addMetaExtra(downloadEntity, Constants.SIMULATOR, GsonUtils.toJson(gameEntity.getSimulator())); } - if (VHelper.isVGame(gameEntity)) { + if (gameEntity.isVGame()) { ExtensionsKt.addMetaExtra(downloadEntity, Constants.SMOOTH_GAME, "true"); ExtensionsKt.addMetaExtra(downloadEntity, Constants.EXTRA_DOWNLOAD_TYPE, Constants.SMOOTH_GAME); } @@ -1153,6 +1153,13 @@ public class DownloadManager implements DownloadStatusListener { return mDownloadEntityListLiveData; } + /** + * 手动触发下载 LiveData 变更 + */ + public void notifyDownloadLiveDataChanged() { + AppExecutor.getIoExecutor().execute(() -> mDownloadEntityListLiveData.postValue(getAllDownloadEntity())); + } + /** * 更新下载请求头的相关信息 */ diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java index 4442384116..0c2139c09b 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java @@ -49,7 +49,9 @@ import com.gh.gamecenter.eventbus.EBScroll; import com.gh.gamecenter.gamedetail.GameDetailFragment; import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment; import com.gh.gamecenter.teenagermode.TeenagerModeActivity; +import com.gh.vspace.VDownloadManagerActivity; import com.gh.vspace.VHelper; +import com.gh.vspace.VSpaceLoadingActivity; import com.lightgame.download.DownloadEntity; import com.lightgame.download.FileUtils; import com.lightgame.utils.Utils; @@ -237,7 +239,7 @@ public class DetailViewHolder { return; } - if (VHelper.isVGame(mGameEntity)) { + if (mGameEntity.isVGame()) { VHelper.launch((AppCompatActivity) mViewHolder.context, mGameEntity.getApk().get(0).getPackageName()); return; } @@ -336,7 +338,9 @@ public class DetailViewHolder { ); break; default: - if (!mGameEntity.getApk().isEmpty()) { + if (mGameEntity.isVGame()) { + mViewHolder.context.startActivity(new Intent(mViewHolder.context, VDownloadManagerActivity.class)); + } else if (!mGameEntity.getApk().isEmpty()) { Intent intent = DownloadManagerActivity.getDownloadMangerIntent(mViewHolder.context, mGameEntity.getApk().get(0).getUrl(), StringUtils.buildString(mEntrance, "+(", mName, "[", mTitle, "])")); @@ -389,6 +393,10 @@ public class DetailViewHolder { mViewHolder.mDownloadPb.setDownloadType("插件化".equals(method) ? DownloadProgressBar.DownloadType.DOWNLOADING_PLUGIN : DownloadProgressBar.DownloadType.DOWNLOADING_NORMAL); DeviceRemindDialog.Companion.showDeviceRemindDialog(mViewHolder.context, mGameEntity); + + if (mViewHolder.context.getString(R.string.download).equals(method)) { + mViewHolder.context.startActivity(VSpaceLoadingActivity.getIntent(mViewHolder.context, mGameEntity)); + } } else { Utils.toast(mViewHolder.context, msg); } diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt index cdfeebcf25..aeae42bd13 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt @@ -3,10 +3,10 @@ package com.gh.gamecenter.entity import android.os.Parcelable import android.text.TextUtils import com.gh.common.constant.Config -import com.gh.gamecenter.common.constant.Constants import com.gh.common.exposure.ExposureEvent import com.gh.common.filter.RegionSettingHelper import com.gh.gamecenter.R +import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.game.data.GameSubjectData import com.gh.gamecenter.gamedetail.entity.GameInfo import com.gh.gamecenter.gamedetail.entity.ZoneEntity @@ -563,6 +563,10 @@ data class GameEntity( && (useMirrorInfo || RegionSettingHelper.shouldThisGameDisplayMirrorInfo(id))) } + fun isVGame(): Boolean { + return downloadStatus == "smooth" + } + fun toSimpleGame(): SimpleGame { val simpleGame = SimpleGame() simpleGame.id = id diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt b/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt index 571baf54d8..1d27db820e 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameInstall.kt @@ -1,7 +1,6 @@ package com.gh.gamecenter.entity import com.gh.common.util.PackageUtils -import com.gh.vspace.VHelper import com.google.gson.annotations.SerializedName import com.halo.assistant.HaloApp @@ -30,7 +29,7 @@ data class GameInstall( gameInstall.iconSubScript = game.iconSubscript gameInstall.version = PackageUtils.getVersionNameByPackageName(installedPkgName) ?: "unknown" gameInstall.packageName = installedPkgName - gameInstall.isSmoothGame = VHelper.isVGame(game) + gameInstall.isSmoothGame = game.isVGame() return gameInstall } } diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt index 750deabf35..8d4c38088b 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt @@ -1626,7 +1626,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { mDownloadBinding.groupVmode.goneIf(simpleGame == null) simpleGame?.let { mDownloadBinding.ivVmode.displayGameIcon(simpleGame.getIcon(), simpleGame.iconSubscript) - if (VHelper.isVGame(gameEntity)) { + if (gameEntity.isVGame()) { mDownloadBinding.tvVmode.text = "下载 >" mDownloadBinding.ivVmodeBadge.setImageResource(R.drawable.ic_switch_game_download) } else { diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt index 81f80a3b2b..597995012a 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt @@ -159,6 +159,7 @@ class HomeFragmentAdapter( is ReuseViewHolder -> bindUnknown(holder) is HomeDividerViewHolder -> holder.bindView(mDataList[position].lineDivider ?: 1F) is HomeGameCollectionViewHolder -> bindGameCollection(holder, position) + is HomeRecentVGameViewHolder -> bindRecentVGame(holder, position) else -> mLegacyHomeFragmentAdapterAssistant.bindLegacyViewHolder( holder, @@ -259,6 +260,12 @@ class HomeFragmentAdapter( holder.bindGameCollectionList(gameCollectionItemDataList, "首页内容列表") } + private fun bindRecentVGame(holder: HomeRecentVGameViewHolder, position: Int) { + val homeItemData = mDataList[position] + + holder.bindView(homeItemData.recentVGame!!) + } + private fun bindAttachGame(holder: HomeGameItemViewHolder, position: Int) { val homeItemData = mDataList[position] val game = homeItemData.attachGame?.linkGame!! diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeItemData.kt b/app/src/main/java/com/gh/gamecenter/home/HomeItemData.kt index 9101a31e34..8b4e6fb9f9 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeItemData.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeItemData.kt @@ -8,6 +8,6 @@ data class HomeItemData(var slides: List? = null, var amway: List? = null, var gameCollection: List? = null, var attachGame: HomeContent? = null, - var recentVGame: List? = null, + var recentVGame: ArrayList? = null, var lineDivider: Float? = null, var unknownData: Any? = null) : LegacyHomeItemData() \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index 47600925b8..e8e6f97043 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -15,6 +15,7 @@ import com.gh.common.util.HomePluggableHelper import com.gh.download.DownloadManager import com.gh.gamecenter.BuildConfig import com.gh.gamecenter.baselist.LoadStatus +import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.retrofit.BiResponse import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.core.runOnIoThread @@ -25,7 +26,7 @@ import com.gh.gamecenter.game.rank.RankCollectionAdapter import com.gh.gamecenter.gamecollection.square.GameCollectionListItemData import com.gh.gamecenter.packagehelper.PackageRepository import com.gh.gamecenter.retrofit.RetrofitManager -import com.gh.vspace.VDownloadManagerViewModel +import com.gh.vspace.VHelper import com.halo.assistant.HaloApp import com.halo.assistant.fragment.SettingsFragment import com.lightgame.utils.Utils @@ -46,7 +47,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { private var mHomeContents = ArrayList() private var mPluginList: List? = null // 插件化 private var mSmartSubject: SubjectEntity? = null // 智能推荐专题 - private var mVGameList: List? = null // 最近的畅玩游戏 + private var mVGameList: ArrayList? = null // 最近的畅玩游戏 private var mContentPage = 1 // 专题分页 private var mIsLoading = false @@ -93,18 +94,18 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { } fun refreshRecentVGameIfNeeded() { - runOnIoThread { - // TODO VA 安装完成的时候刷新列表 - // TODO 根据开关判断是否隐藏下面的数据 - // TODO 排序 - // TODO 避免多线程异常 + // TODO VA 安装完成的时候刷新列表 + // TODO 根据开关判断是否隐藏下面的数据 + // TODO 排序 + // TODO 避免多线程异常 + if (SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, true)) { val entityList = DownloadManager.getInstance().allVDownloadTask if (!entityList.isNullOrEmpty()) { val vGameList = arrayListOf() for (entity in entityList) { - vGameList.add(VDownloadManagerViewModel.toGameEntity(entity)) + vGameList.add(VHelper.toGameEntity(entity)) } mVGameList = vGameList @@ -305,196 +306,198 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { } fun transformationItemData() { - mSnapshotItemList.clear() + runOnIoThread { + mSnapshotItemList.clear() - // 是否使用带特别高的带分割线的 item - var useUltraHeightDivider = false - var shouldShowDivider = false + // 是否使用带特别高的带分割线的 item + var useUltraHeightDivider = false + var shouldShowDivider = false - val iterator = mHomeContents.iterator() - while (iterator.hasNext()) { - val item = iterator.next() - // 裁剪排行榜数据数量 - if (item.linkType == "column_collection" && item.linkColumn?.style == "top") { - item.linkColumn.columns.let { columns -> - for (column in columns) { - column.data = ArrayList(column.data?.take(RankCollectionAdapter.MAX_RANK_ITEM_COUNT) ?: listOf()) - } - } - } - } - - if (mSmartSubject != null && mHomeContents.size > mSmartSubject!!.sort) { - val element = HomeContent( - linkType = "smart_subject", - linkId = mSmartSubject?.id ?: "", - linkText = mSmartSubject?.name ?: "", - linkColumn = mSmartSubject - ) - mHomeContents.add(mSmartSubject!!.sort, element) - mSmartSubject = null // 防止重复插入 - } - - if (mHomeSlides.isNotEmpty()) { - val slideItem = HomeItemData() - slideItem.slides = mHomeSlides - mSnapshotItemList.add(slideItem) - } - - if (mHomeRecommends.isNotEmpty()) { - val recommend = HomeItemData() - recommend.recommends = mHomeRecommends - mSnapshotItemList.add(recommend) - } - - // 最近在玩的畅玩游戏 - if (mVGameList != null && !mVGameList.isNullOrEmpty()) { - val item = HomeItemData() - item.recentVGame = mVGameList - mSnapshotItemList.add(item) - - for (entity in mVGameList!!) { - addGamePositionAndPackage(entity) - } - } - - // 插件化 - if (mPluginList != null && mPluginList!!.isNotEmpty()) { - val plugin = HomeItemData() - plugin.pluginList = mPluginList - mSnapshotItemList.add(plugin) - - for (entity in mPluginList!!) { - addGamePositionAndPackage(entity) - } - } - - for (i in 0 until mHomeContents.size) { - val homeContent = mHomeContents[i] - val linkType = homeContent.linkType - val linkStyle = homeContent.linkColumn?.style ?: "" - - if (i + 1 < mHomeContents.size) { - val nextItem = mHomeContents[i + 1] - shouldShowDivider = nextItem.linkType == "game" || nextItem.linkType == "video" - } - - if (linkType == "game" || linkType == "video") { - val attachGame = HomeItemData() - attachGame.blockPosition = i - attachGame.attachGame = homeContent - attachGame.attachGame?.linkGame?.outerSequence = attachGame.blockPosition - attachGame.attachGame?.linkGame?.sequence = attachGame.blockPosition - mSnapshotItemList.add(attachGame) - } else if (linkType == "top_game_comment") { - val head = HomeItemData() - head.columnHead = SubjectEntity(type = linkType, name = "安利墙") - mSnapshotItemList.add(LegacyHomeSubjectTransformer.getBlankSpacingItem(HomeItemData()) as HomeItemData) - mSnapshotItemList.add(head) - - val amway = HomeItemData() - amway.blockPosition = i - amway.amway = homeContent.linkTopGameComment?.apply { - for ((index, amwayEntity) in this.withIndex()) { - amwayEntity.game.sequence = index - amwayEntity.game.outerSequence = i - } - } - mSnapshotItemList.add(amway) - } else if (linkType == "column" - || linkType == "column_collection" && linkStyle != "top" - || linkType == "smart_subject" - || linkType == "column_test" - ) { - - homeContent.linkColumn?.data = RegionSettingHelper.filterGame(homeContent.linkColumn?.data) - - homeContent.linkColumn?.let { subjectEntity -> - subjectEntity.data?.let { data -> - // 这个 for 循环主要功能是用来标识替换已安装的游戏 - for (game in data) { - mSubjectGameIdList.add(game.id) - // 应用专题是否显示游戏名后缀的配置 - game.shouldShowNameSuffix = subjectEntity.showSuffix - } - - subjectEntity.relatedColumnId?.let { - GameSubstituteRepositoryHelper.replaceGames(data, mSubjectGameIdList, it, mShouldLogReplaceEvent) - mShouldLogReplaceEvent = false + val iterator = mHomeContents.iterator() + while (iterator.hasNext()) { + val item = iterator.next() + // 裁剪排行榜数据数量 + if (item.linkType == "column_collection" && item.linkColumn?.style == "top") { + item.linkColumn.columns.let { columns -> + for (column in columns) { + column.data = ArrayList(column.data?.take(RankCollectionAdapter.MAX_RANK_ITEM_COUNT) ?: listOf()) } } } + } - // 仅普通纵向专题需要特别高的分割线 - useUltraHeightDivider = homeContent.linkColumn?.type == "game_vertical" - - LegacyHomeSubjectTransformer.transform( - mSnapshotItemList as ArrayList, - homeContent.linkColumn, - i, - { HomeItemData() }, - { addGamePositionAndPackage(it) } + if (mSmartSubject != null && mHomeContents.size > mSmartSubject!!.sort) { + val element = HomeContent( + linkType = "smart_subject", + linkId = mSmartSubject?.id ?: "", + linkText = mSmartSubject?.name ?: "", + linkColumn = mSmartSubject ) - } else if (linkType == "column_collection" && linkStyle == "top") { - val rankItem = HomeItemData().apply { - blockPosition = i - rankCollection = homeContent.linkColumn - } - mSnapshotItemList.add(rankItem) - appendAdditionalInfoToRankSubjectGame(homeContent.linkColumn, i) - } else if (linkType == "common_collection") { - val commonCollectionItem = HomeItemData() - val subjectEntity = SubjectEntity().apply { - type = homeContent.linkType - id = homeContent.linkId - name = homeContent.linkText - style = homeContent.commonCollection?.style - commonCollectionList = homeContent.commonCollection?.collectionList - } - val head = HomeItemData() - head.columnHead = subjectEntity - mSnapshotItemList.add(LegacyHomeSubjectTransformer.getBlankSpacingItem(HomeItemData()) as HomeItemData) - mSnapshotItemList.add(head) - commonCollectionItem.commonCollection = subjectEntity - commonCollectionItem.blockPosition = i - mSnapshotItemList.add(commonCollectionItem) - } else if (linkType == "game_list_collection") { - val head = HomeItemData() - head.columnHead = SubjectEntity(type = linkType, name = homeContent.linkText) - mSnapshotItemList.add(LegacyHomeSubjectTransformer.getBlankSpacingItem(HomeItemData()) as HomeItemData) - mSnapshotItemList.add(head) + mHomeContents.add(mSmartSubject!!.sort, element) + mSmartSubject = null // 防止重复插入 + } - val gameCollection = HomeItemData() - gameCollection.blockPosition = i - val itemDataList = arrayListOf().apply { - if (!homeContent.linkGameCollection.isNullOrEmpty()) { - var position = 0 - for (item in homeContent.linkGameCollection) { - add(GameCollectionListItemData(gameCollectionItem = item, gameStartPosition = position)) - position += if (item.count?.game!! > 2) 3 else if (item.games?.size == 0) 0 else item.count?.game ?: 0 + if (mHomeSlides.isNotEmpty()) { + val slideItem = HomeItemData() + slideItem.slides = mHomeSlides + mSnapshotItemList.add(slideItem) + } + + if (mHomeRecommends.isNotEmpty()) { + val recommend = HomeItemData() + recommend.recommends = mHomeRecommends + mSnapshotItemList.add(recommend) + } + + // 最近在玩的畅玩游戏 + if (mVGameList != null && !mVGameList.isNullOrEmpty()) { + val item = HomeItemData() + item.recentVGame = mVGameList + mSnapshotItemList.add(item) + + for (entity in mVGameList!!) { + addGamePositionAndPackage(entity) + } + } + + // 插件化 + if (mPluginList != null && mPluginList!!.isNotEmpty()) { + val plugin = HomeItemData() + plugin.pluginList = mPluginList + mSnapshotItemList.add(plugin) + + for (entity in mPluginList!!) { + addGamePositionAndPackage(entity) + } + } + + for (i in 0 until mHomeContents.size) { + val homeContent = mHomeContents[i] + val linkType = homeContent.linkType + val linkStyle = homeContent.linkColumn?.style ?: "" + + if (i + 1 < mHomeContents.size) { + val nextItem = mHomeContents[i + 1] + shouldShowDivider = nextItem.linkType == "game" || nextItem.linkType == "video" + } + + if (linkType == "game" || linkType == "video") { + val attachGame = HomeItemData() + attachGame.blockPosition = i + attachGame.attachGame = homeContent + attachGame.attachGame?.linkGame?.outerSequence = attachGame.blockPosition + attachGame.attachGame?.linkGame?.sequence = attachGame.blockPosition + mSnapshotItemList.add(attachGame) + } else if (linkType == "top_game_comment") { + val head = HomeItemData() + head.columnHead = SubjectEntity(type = linkType, name = "安利墙") + mSnapshotItemList.add(LegacyHomeSubjectTransformer.getBlankSpacingItem(HomeItemData()) as HomeItemData) + mSnapshotItemList.add(head) + + val amway = HomeItemData() + amway.blockPosition = i + amway.amway = homeContent.linkTopGameComment?.apply { + for ((index, amwayEntity) in this.withIndex()) { + amwayEntity.game.sequence = index + amwayEntity.game.outerSequence = i } } - } - gameCollection.gameCollection = itemDataList - mSnapshotItemList.add(gameCollection) - } else { - val unknown = HomeItemData() - unknown.blockPosition = i + 1 - unknown.unknownData = "" - mSnapshotItemList.add(unknown) - } + mSnapshotItemList.add(amway) + } else if (linkType == "column" + || linkType == "column_collection" && linkStyle != "top" + || linkType == "smart_subject" + || linkType == "column_test" + ) { - if (i != 0 && shouldShowDivider) { - if (useUltraHeightDivider) { - useUltraHeightDivider = false - mSnapshotItemList.add(HomeItemData(lineDivider = ULTRA_HEIGHT_DIVIDER)) + homeContent.linkColumn?.data = RegionSettingHelper.filterGame(homeContent.linkColumn?.data) + + homeContent.linkColumn?.let { subjectEntity -> + subjectEntity.data?.let { data -> + // 这个 for 循环主要功能是用来标识替换已安装的游戏 + for (game in data) { + mSubjectGameIdList.add(game.id) + // 应用专题是否显示游戏名后缀的配置 + game.shouldShowNameSuffix = subjectEntity.showSuffix + } + + subjectEntity.relatedColumnId?.let { + GameSubstituteRepositoryHelper.replaceGames(data, mSubjectGameIdList, it, mShouldLogReplaceEvent) + mShouldLogReplaceEvent = false + } + } + } + + // 仅普通纵向专题需要特别高的分割线 + useUltraHeightDivider = homeContent.linkColumn?.type == "game_vertical" + + LegacyHomeSubjectTransformer.transform( + mSnapshotItemList as ArrayList, + homeContent.linkColumn, + i, + { HomeItemData() }, + { addGamePositionAndPackage(it) } + ) + } else if (linkType == "column_collection" && linkStyle == "top") { + val rankItem = HomeItemData().apply { + blockPosition = i + rankCollection = homeContent.linkColumn + } + mSnapshotItemList.add(rankItem) + appendAdditionalInfoToRankSubjectGame(homeContent.linkColumn, i) + } else if (linkType == "common_collection") { + val commonCollectionItem = HomeItemData() + val subjectEntity = SubjectEntity().apply { + type = homeContent.linkType + id = homeContent.linkId + name = homeContent.linkText + style = homeContent.commonCollection?.style + commonCollectionList = homeContent.commonCollection?.collectionList + } + val head = HomeItemData() + head.columnHead = subjectEntity + mSnapshotItemList.add(LegacyHomeSubjectTransformer.getBlankSpacingItem(HomeItemData()) as HomeItemData) + mSnapshotItemList.add(head) + commonCollectionItem.commonCollection = subjectEntity + commonCollectionItem.blockPosition = i + mSnapshotItemList.add(commonCollectionItem) + } else if (linkType == "game_list_collection") { + val head = HomeItemData() + head.columnHead = SubjectEntity(type = linkType, name = homeContent.linkText) + mSnapshotItemList.add(LegacyHomeSubjectTransformer.getBlankSpacingItem(HomeItemData()) as HomeItemData) + mSnapshotItemList.add(head) + + val gameCollection = HomeItemData() + gameCollection.blockPosition = i + val itemDataList = arrayListOf().apply { + if (!homeContent.linkGameCollection.isNullOrEmpty()) { + var position = 0 + for (item in homeContent.linkGameCollection) { + add(GameCollectionListItemData(gameCollectionItem = item, gameStartPosition = position)) + position += if (item.count?.game!! > 2) 3 else if (item.games?.size == 0) 0 else item.count?.game ?: 0 + } + } + } + gameCollection.gameCollection = itemDataList + mSnapshotItemList.add(gameCollection) } else { - mSnapshotItemList.add(HomeItemData(lineDivider = DEFAULT_DIVIDER)) + val unknown = HomeItemData() + unknown.blockPosition = i + 1 + unknown.unknownData = "" + mSnapshotItemList.add(unknown) + } + + if (i != 0 && shouldShowDivider) { + if (useUltraHeightDivider) { + useUltraHeightDivider = false + mSnapshotItemList.add(HomeItemData(lineDivider = ULTRA_HEIGHT_DIVIDER)) + } else { + mSnapshotItemList.add(HomeItemData(lineDivider = DEFAULT_DIVIDER)) + } + shouldShowDivider = false } - shouldShowDivider = false } + itemDataList.postValue(mSnapshotItemList) } - itemDataList.postValue(mSnapshotItemList) } private fun addGamePositionAndPackage(game: GameEntity) { diff --git a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt index 3de5380269..20786987f0 100644 --- a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt +++ b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt @@ -3,25 +3,26 @@ package com.gh.gamecenter.packagehelper import android.annotation.SuppressLint import android.text.TextUtils import androidx.lifecycle.MutableLiveData -import com.gh.gamecenter.common.exposure.meta.MetaUtil import com.gh.common.filter.RegionSettingHelper -import com.gh.gamecenter.common.loghub.LoghubUtils -import com.gh.common.util.* +import com.gh.common.util.ApkActiveUtils +import com.gh.common.util.GameUtils +import com.gh.common.util.PackageUtils import com.gh.gamecenter.R -import com.gh.gamecenter.core.runOnIoThread -import com.gh.gamecenter.core.utils.SPUtils +import com.gh.gamecenter.common.exposure.meta.MetaUtil +import com.gh.gamecenter.common.loghub.LoghubUtils +import com.gh.gamecenter.common.retrofit.BiResponse +import com.gh.gamecenter.common.retrofit.ObservableUtil +import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.common.utils.secondOrNull import com.gh.gamecenter.common.utils.tryCatchInRelease +import com.gh.gamecenter.core.runOnIoThread +import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.entity.* import com.gh.gamecenter.manager.PackagesManager import com.gh.gamecenter.manager.UserManager import com.gh.gamecenter.packagehelper.PackageRepository.gameInstalled import com.gh.gamecenter.packagehelper.PackageRepository.gameUpdate -import com.gh.gamecenter.common.retrofit.BiResponse -import com.gh.gamecenter.common.retrofit.ObservableUtil -import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.retrofit.RetrofitManager -import com.gh.vspace.VHelper import com.halo.assistant.HaloApp import com.lightgame.utils.Utils import io.reactivex.android.schedulers.AndroidSchedulers @@ -215,7 +216,7 @@ object PackageRepository { for (game in validGames) { // 仅匹配畅玩游戏时,非畅玩游戏直接跳过 - if (matchSmoothGameOnly && !VHelper.isVGame(game)) { + if (matchSmoothGameOnly && !game.isVGame()) { continue } diff --git a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt index 0aec76c579..e852de82e4 100644 --- a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt +++ b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt @@ -8,7 +8,7 @@ class HomeRecentVGameViewHolder(var binding: ItemHomeRecentVgameBinding) : RecyclerView.ViewHolder(binding.root) { fun bindView(gameList: ArrayList) { - + // TODO 实现列表 } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt index 7588d26502..a85357cd82 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt @@ -2,7 +2,8 @@ package com.gh.vspace import android.os.Bundle import com.gh.gamecenter.R -import com.gh.gamecenter.common.base.ToolBarActivity +import com.gh.gamecenter.common.base.activity.ToolBarActivity +import com.gh.gamecenter.core.utils.DisplayUtils class VDownloadManagerActivity: ToolBarActivity() { @@ -10,7 +11,9 @@ class VDownloadManagerActivity: ToolBarActivity() { super.onCreate(savedInstanceState) if (savedInstanceState == null) { - supportFragmentManager.beginTransaction().replace(R.id.placeholder, VDownloadManagerWrapperFragment()).commitAllowingStateLoss() + val fragment = VDownloadManagerWrapperFragment() + supportFragmentManager.beginTransaction().replace(R.id.placeholder, fragment).commitAllowingStateLoss() + updateTargetFragment(fragment) } } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index 1fba4516d9..9bcf4b8b05 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -68,14 +68,17 @@ class VDownloadManagerFragment : mBinding.headerContainer.goneIf(mViewModel.type != VDownloadManagerViewModel.TYPE_DOWNLOADED) mBinding.switchIv.enlargeTouchArea() - mBinding.switchIv.isSelected = SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, false) + mBinding.switchIv.isSelected = SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, true) mBinding.switchIv.setOnClickListener { if (mBinding.switchLottie.isAnimating) return@setOnClickListener - val status = SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, false) + val status = mBinding.switchIv.isSelected val anime = if (status) "lottie/switch_turnoff.json" else "lottie/switch_turnon.json" mBinding.switchLottie.setAnimation(anime) mBinding.switchLottie.playAnimation() + mBinding.switchIv.isSelected = !status SPUtils.setBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, !status) + + DownloadManager.getInstance().notifyDownloadLiveDataChanged() } } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index 0223e39747..4177c93609 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -4,10 +4,8 @@ import android.app.Application import com.gh.download.DownloadManager import com.gh.gamecenter.baselist.ListViewModel import com.gh.gamecenter.baselist.LoadType -import com.gh.gamecenter.entity.ApkEntity import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.packagehelper.PackageRepository -import com.lightgame.download.DownloadEntity import com.lightgame.download.DownloadStatus import io.reactivex.Observable import io.reactivex.Single @@ -38,12 +36,12 @@ class VDownloadManagerViewModel(application: Application) : for (downloadEntity in vDownloadList) { if (downloadEntity.status == DownloadStatus.done) { gameIdSet.add(downloadEntity.gameId) - vGameList.add(toGameEntity(downloadEntity)) + vGameList.add(VHelper.toGameEntity(downloadEntity)) } } for (game in installedGameList) { - if (VHelper.isVGame(game) && !gameIdSet.contains(game.id)) { + if (game.isVGame() && !gameIdSet.contains(game.id)) { vGameList.add(game) } } @@ -60,7 +58,7 @@ class VDownloadManagerViewModel(application: Application) : for (downloadEntity in vDownloadList) { if (downloadEntity.status != DownloadStatus.done) { gameIdSet.add(downloadEntity.gameId) - vGameList.add(toGameEntity(downloadEntity)) + vGameList.add(VHelper.toGameEntity(downloadEntity)) } } @@ -90,23 +88,6 @@ class VDownloadManagerViewModel(application: Application) : const val TYPE = "type" const val TYPE_DOWNLOADED = "type_downloaded" const val TYPE_DOWNLOADING = "type_downloading" - - fun toGameEntity(downloadEntity: DownloadEntity): GameEntity { - return GameEntity(id = downloadEntity.gameId, name = downloadEntity.name).apply { - setApk( - arrayListOf( - ApkEntity( - packageName = downloadEntity.packageName, - url = downloadEntity.url, - platform = downloadEntity.platform - ) - ) - ) - icon = downloadEntity.icon - downloadStatus = "smooth" - setEntryMap(DownloadManager.getInstance().getEntryMap(name)) - } - } } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index a3e9e6f051..4eecf39110 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -4,18 +4,25 @@ import android.Manifest import android.app.Activity import android.content.Context import android.content.Intent +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData import com.gh.common.constant.Config import com.gh.common.util.PackageUtils +import com.gh.download.DownloadManager import com.gh.download.PackageObserver +import com.gh.gamecenter.common.utils.DialogHelper import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.core.utils.EmptyCallback import com.gh.gamecenter.core.utils.ToastUtils +import com.gh.gamecenter.entity.ApkEntity import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.eventbus.EBPackage import com.gh.gamecenter.packagehelper.PackageRepository import com.lg.vspace.VirtualAppManager import com.lg.vspace.remote.listener.RemoteConnectListener import com.lg.vspace.remote.model.AppInstallerInfo +import com.lightgame.download.DownloadEntity +import com.lightgame.utils.AppManager import com.lightgame.utils.Utils object VHelper { @@ -24,10 +31,12 @@ object VHelper { private val mDelegateManager by lazy { VirtualAppManager.get() } private var mInstalledInfoList: List = arrayListOf() + private val mInstallationLiveData by lazy { MutableLiveData() } private val mPackageObserver by lazy { PackageObserver.PackageChangeListener { val vaConfig = Config.getVSettingEntity()?.va ?: return@PackageChangeListener - val isVSpace = it.packageName == vaConfig.arch32?.packageName || it.packageName == vaConfig.arch64?.packageName + val isVSpace = + it.packageName == vaConfig.arch32?.packageName || it.packageName == vaConfig.arch64?.packageName if (!isVSpace) return@PackageChangeListener @@ -74,14 +83,6 @@ object VHelper { } } - /** - * 是否是使用畅玩启动类型的游戏 - */ - @JvmStatic - fun isVGame(gameEntity: GameEntity?): Boolean { - return gameEntity?.downloadStatus == "smooth" - } - /** * 是否在 V 空间里已安装此包名游戏 */ @@ -94,7 +95,11 @@ object VHelper { * 在执行 callback 前先检查组件是否已安装,是否可下载 */ @JvmStatic - fun checkVSpaceBeforeAction(context: Context, gameEntity: GameEntity?, callback: EmptyCallback) { + fun checkVSpaceBeforeAction( + context: Context, + gameEntity: GameEntity?, + callback: EmptyCallback + ) { checkVSpaceBeforeAction(context, gameEntity) { callback.onCallback() } @@ -105,23 +110,31 @@ object VHelper { */ fun checkVSpaceBeforeAction(context: Context, gameEntity: GameEntity?, callback: () -> Unit) { // 仅下载类型为畅玩的类型才执行判断 - if (gameEntity?.downloadStatus == "smooth") { - // TODO 区分 32 位的组件和 64 位的组件 - val isArch32Installed = PackageUtils.isInstalled(context, Config.getVSettingEntity()?.va?.arch32?.packageName) -// val isArch64Installed = PackageUtils.isInstalled(context, Config.getVSettingEntity()?.va?.arch64?.packageName) - - if (!isArch32Installed) { - VSpaceDialogFragment.showDownloadDialog(context) + if (gameEntity?.isVGame() == true) { + if (showDialogIfVSpaceIsNeeded(context)) { return } + val vaConfig32 = Config.getVSettingEntity()?.va?.arch32 - // TODO 检查更新 - val containsUpdate = PackageRepository.gameUpdate.any { - it.packageName == Config.getVSettingEntity()?.va?.arch32?.packageName - } + // 检查更新 + val containsUpdate = + vaConfig32?.versionCode ?: 0 > PackageUtils.getVersionCodeByPackageName(vaConfig32?.packageName) if (containsUpdate) { - // TODO 触发更新弹窗 + // 触发更新弹窗 + DialogHelper.showDialog( + context = context, + title = "服务工具更新提示", + content = "单机类游戏被删除将可能导致本地存档、充值数据丢失,请确认后操作(网游类游戏删除不会影响游戏存档和充值数据)", + confirmText = "立即更新", + cancelText = "继续游戏", + confirmClickCallback = { + VSpaceDialogFragment.showDownloadDialog(context) + }, + cancelClickCallback = { + callback.invoke() + } + ) return } @@ -193,6 +206,12 @@ object VHelper { * 安装新应用 */ fun install(activity: Activity, filePath: String) { + Utils.log(LOG_TAG, "尝试安装新应用") + + if (showDialogIfVSpaceIsNeeded(activity)) { + return + } + val installClosure: () -> Unit = { checkStoragePermissionBeforeAction(activity) { // 安装过程会比较漫长,所以得放在工作线程运行 @@ -200,7 +219,10 @@ object VHelper { val result = VirtualAppManager.get().installGame(filePath) if (result.status == 0) { updateInstalledList() + showFloatingWindow(result.packageName) + PackageObserver.onPackageChanged(EBPackage("安装", result.packageName, "unknown")) } + mInstallationLiveData.postValue(result.packageName) Utils.log(LOG_TAG, "安装新应用结果 -> " + result.status) } } @@ -220,11 +242,7 @@ object VHelper { fun launch(activity: Activity, packageName: String) { Utils.log(LOG_TAG, "打开应用$packageName") - val vaConfig = Config.getVSettingEntity()?.va ?: return - - // TODO 检测 64 位 - if (!PackageUtils.isInstalled(activity, vaConfig.arch32?.packageName)) { - VSpaceDialogFragment.showDownloadDialog(activity) + if (showDialogIfVSpaceIsNeeded(activity)) { return } @@ -253,4 +271,52 @@ object VHelper { } } + fun getInstallationLiveData(): LiveData { + return mInstallationLiveData + } + + private fun showFloatingWindow(packageName: String) { + val vDownloadList = DownloadManager.getInstance().allVDownloadTask + vDownloadList.firstOrNull { + it.packageName == packageName + }?.let { + val topActivity = AppManager.getInstance().currentActivity() ?: return + VLoadCompleteWindowHelper.showFloatingWindow(topActivity, toGameEntity(it)) + } + } + + /** + * 畅玩空间是否已安装 + * 如果已安装或配置为空返回 true + * 未安装的情况下会弹弹窗 + */ + private fun showDialogIfVSpaceIsNeeded(context: Context) : Boolean { + val vaConfig = Config.getVSettingEntity()?.va ?: return true + + // TODO 检测 64 位 + if (!PackageUtils.isInstalled(context, vaConfig.arch32?.packageName)) { + VSpaceDialogFragment.showDownloadDialog(context) + return true + } + + return false + } + + fun toGameEntity(downloadEntity: DownloadEntity): GameEntity { + return GameEntity(id = downloadEntity.gameId, name = downloadEntity.name).apply { + setApk( + arrayListOf( + ApkEntity( + packageName = downloadEntity.packageName, + url = downloadEntity.url, + platform = downloadEntity.platform + ) + ) + ) + icon = downloadEntity.icon + downloadStatus = "smooth" + setEntryMap(DownloadManager.getInstance().getEntryMap(name)) + } + } + } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/LoadCompleteWindowHelper.kt b/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt similarity index 99% rename from app/src/main/java/com/gh/vspace/LoadCompleteWindowHelper.kt rename to app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt index ac0b2ceaa5..ecc8044d32 100644 --- a/app/src/main/java/com/gh/vspace/LoadCompleteWindowHelper.kt +++ b/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt @@ -27,7 +27,7 @@ import com.lzf.easyfloat.enums.SidePattern import com.lzf.easyfloat.interfaces.OnFloatAnimator import java.lang.ref.WeakReference -object LoadCompleteWindowHelper { +object VLoadCompleteWindowHelper { private const val LOAD_COMPLETE_WINDOW = "load_complete_window" private const val LOOP_TIME = 2000L private const val LOOP_DURATION = 200L @@ -35,7 +35,9 @@ object LoadCompleteWindowHelper { private val mDismissTask = Runnable { EasyFloat.dismiss(LOAD_COMPLETE_WINDOW) } - fun showFloatingWindow(activity: Activity, gameEntity: GameEntity) = showFloatingWindow(activity, listOf(gameEntity)) + fun showFloatingWindow(activity: Activity, gameEntity: GameEntity) { + showFloatingWindow(activity, listOf(gameEntity)) + } fun showFloatingWindow(activity: Activity, gameEntityList: List = emptyList()) { val floatingView = EasyFloat.getFloatView(LOAD_COMPLETE_WINDOW) diff --git a/app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt b/app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt index 4e14d8a869..276f322a59 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt @@ -4,26 +4,33 @@ import android.content.Context import android.content.Intent import android.os.Bundle import com.gh.gamecenter.R -import com.gh.gamecenter.common.base.BaseActivity +import com.gh.gamecenter.common.base.activity.BaseActivity import com.gh.gamecenter.common.constant.EntranceConsts -import com.lightgame.download.DownloadEntity +import com.gh.gamecenter.core.utils.DisplayUtils +import com.gh.gamecenter.entity.GameEntity -class VSpaceLoadingActivity: BaseActivity() { +class VSpaceLoadingActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + DisplayUtils.transparentStatusBar(this) + DisplayUtils.setLightStatusBar(this, true) + if (savedInstanceState == null) { - supportFragmentManager.beginTransaction().replace(R.id.placeholder, VSpaceLoadingFragment()).commitAllowingStateLoss() + val fragment = VSpaceLoadingFragment().apply { arguments = intent?.extras } + supportFragmentManager.beginTransaction() + .replace(R.id.placeholder, fragment).commitAllowingStateLoss() } } override fun getLayoutId() = R.layout.activity_shell companion object { - fun getIntent(context: Context, downloadEntity: DownloadEntity) : Intent { + @JvmStatic + fun getIntent(context: Context, game: GameEntity): Intent { val intent = Intent(context, VSpaceLoadingActivity::class.java) - intent.putExtra(EntranceConsts.KEY_DATA, downloadEntity) + intent.putExtra(EntranceConsts.KEY_DATA, game) return intent } } diff --git a/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt index 9ccc033c17..a064913d39 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt @@ -1,15 +1,98 @@ package com.gh.vspace +import android.os.Bundle +import android.view.View import com.gh.gamecenter.common.base.fragment.BaseFragment +import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.databinding.FragmentVspaceLoadingBinding +import com.gh.gamecenter.entity.GameEntity +import com.lightgame.download.DataChanger +import com.lightgame.download.DataWatcher +import com.lightgame.download.DownloadEntity +import com.lightgame.download.DownloadStatus.* -class VSpaceLoadingFragment: BaseFragment() { +class VSpaceLoadingFragment : BaseFragment() { - private val mBinding: FragmentVspaceLoadingBinding by lazy { FragmentVspaceLoadingBinding.inflate(layoutInflater) } + private var mGame: GameEntity? = null + private val mBinding: FragmentVspaceLoadingBinding by lazy { + FragmentVspaceLoadingBinding.inflate( + layoutInflater + ) + } + private val mDataWatcher by lazy { + object : DataWatcher() { + override fun onDataChanged(downloadEntity: DownloadEntity?) { + if (downloadEntity == null) return + if (downloadEntity.gameId != mGame?.id) return + + when (downloadEntity.status) { + add, + download, + downloading -> { + mBinding.progressBar.progress = downloadEntity.percent.toInt() + mBinding.progressTv.text = "加载中...${(downloadEntity.percent)}%" + } + + done -> { + mBinding.progressBar.progress = 100 + mBinding.progressTv.text = "启动中...${downloadEntity.percent}%" + } + + pause, + delete, + timeout, + hijack, + notfound, + neterror, + overflow -> { + requireActivity().finish() + } + + else -> { + // do nothing + } + } + } + } + } override fun getLayoutId() = 0 override fun getInflatedLayout() = mBinding.root + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + mGame = arguments?.get(EntranceConsts.KEY_DATA) as GameEntity? + mGame?.let { initView(it, mBinding) } + VHelper.getInstallationLiveData().observe(viewLifecycleOwner) { + val currentPackageName = mGame?.getApk()?.firstOrNull()?.packageName + if (it == currentPackageName) { + VHelper.launch(requireActivity(), currentPackageName!!) + requireActivity().finish() + } + } + } + + private fun initView(gameEntity: GameEntity, binding: FragmentVspaceLoadingBinding) { + binding.gameIconIv.displayGameIcon(gameEntity) + binding.hideLoadingContainer.setOnClickListener { requireActivity().finish() } + binding.nameTv.text = gameEntity.name + } + + private fun showFakeLaunchProgress() { + + } + + override fun onResume() { + super.onResume() + + DataChanger.addObserver(mDataWatcher) + } + + override fun onPause() { + super.onPause() + + DataChanger.deleteObserver(mDataWatcher) + } } \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_vdownload_manager.xml b/app/src/main/res/layout/fragment_vdownload_manager.xml index 95422d7a5f..a8d28c6c6c 100644 --- a/app/src/main/res/layout/fragment_vdownload_manager.xml +++ b/app/src/main/res/layout/fragment_vdownload_manager.xml @@ -70,7 +70,31 @@ - + + + + + + diff --git a/app/src/main/res/layout/fragment_vspace_loading.xml b/app/src/main/res/layout/fragment_vspace_loading.xml index fd280053bf..1fc08039ee 100644 --- a/app/src/main/res/layout/fragment_vspace_loading.xml +++ b/app/src/main/res/layout/fragment_vspace_loading.xml @@ -6,6 +6,12 @@ android:layout_height="match_parent" android:background="@color/white"> + + - - - - - - Date: Wed, 25 May 2022 15:11:05 +0800 Subject: [PATCH 017/217] =?UTF-8?q?=E8=A1=A5=E5=85=85=E5=90=AF=E5=8A=A8(?= =?UTF-8?q?=E7=95=85=E7=8E=A9)=E7=9A=84=E5=88=A4=E6=96=AD=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/common/util/GameUtils.java | 10 ++++++--- app/src/main/java/com/gh/vspace/VHelper.kt | 22 ++++++++++++------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/GameUtils.java b/app/src/main/java/com/gh/common/util/GameUtils.java index b395f21722..8c44b8b309 100644 --- a/app/src/main/java/com/gh/common/util/GameUtils.java +++ b/app/src/main/java/com/gh/common/util/GameUtils.java @@ -18,6 +18,7 @@ import com.gh.gamecenter.entity.GameUpdateEntity; import com.gh.gamecenter.entity.PluginLocation; import com.gh.gamecenter.entity.SettingsEntity; import com.gh.gamecenter.manager.PackagesManager; +import com.gh.vspace.VHelper; import com.lightgame.download.DownloadEntity; import com.lightgame.download.DownloadStatus; @@ -89,7 +90,7 @@ public class GameUtils { boolean isRelatedEmulatorInstalled = false; // 若该游戏是模拟器游戏时其对应的模拟器是否已经安装 - DownloadEntity downloadEntity; + DownloadEntity downloadEntity = null; Object gh_id; apkFor: for (ApkEntity apkEntity : gameEntity.getApk()) { @@ -149,8 +150,11 @@ public class GameUtils { } if (gameEntity.isVGame()) { - // 如果 doneCount 为 0 表明本地并没有此游戏的数据库数据,需要重新下载 - if (doneCount == 0) { + // 如果 doneCount 为 0 或者数据库为空 + // 表明本地并没有此游戏的数据库数据,需要重新下载 + if (doneCount == 0 + || downloadEntity == null + || !VHelper.isInstalled(downloadEntity.getPackageName())) { installCount = 0; } else { doneCount = 0; diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 4eecf39110..0bbf5b8750 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -10,7 +10,9 @@ import com.gh.common.constant.Config import com.gh.common.util.PackageUtils import com.gh.download.DownloadManager import com.gh.download.PackageObserver +import com.gh.gamecenter.R import com.gh.gamecenter.common.utils.DialogHelper +import com.gh.gamecenter.common.utils.toColor import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.core.utils.EmptyCallback import com.gh.gamecenter.core.utils.ToastUtils @@ -118,7 +120,7 @@ object VHelper { // 检查更新 val containsUpdate = - vaConfig32?.versionCode ?: 0 > PackageUtils.getVersionCodeByPackageName(vaConfig32?.packageName) + vaConfig32?.versionCode ?: 0 == PackageUtils.getVersionCodeByPackageName(vaConfig32?.packageName) if (containsUpdate) { // 触发更新弹窗 @@ -126,19 +128,23 @@ object VHelper { context = context, title = "服务工具更新提示", content = "单机类游戏被删除将可能导致本地存档、充值数据丢失,请确认后操作(网游类游戏删除不会影响游戏存档和充值数据)", - confirmText = "立即更新", - cancelText = "继续游戏", - confirmClickCallback = { + cancelText = "立即更新", + confirmText = "继续游戏", + cancelClickCallback = { VSpaceDialogFragment.showDownloadDialog(context) }, - cancelClickCallback = { + confirmClickCallback = { callback.invoke() + }, + extraConfig = DialogHelper.Config(centerTitle = true), + uiModificationCallback = { + it.confirmTv.setTextColor(R.color.text_subtitle.toColor(context)) } ) return } - callback.invoke() + checkStoragePermissionBeforeAction(context, callback) } else { callback.invoke() } @@ -187,14 +193,14 @@ object VHelper { /** * 检查存储权限,若已授予直接执行后续逻辑 */ - private fun checkStoragePermissionBeforeAction(activity: Activity, callback: () -> Unit) { + private fun checkStoragePermissionBeforeAction(context: Context, callback: () -> Unit) { try { val isStoragePermissionGranted = mDelegateManager.checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE) if (isStoragePermissionGranted) { callback.invoke() } else { - activity.startActivity(mDelegateManager.requestPermissionIntent) + context.startActivity(mDelegateManager.requestPermissionIntent) } } catch (e: RuntimeException) { e.printStackTrace() From 26b0f33f1c5f2af52bf1d7783b51df6b8efb52ce Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 26 May 2022 16:56:28 +0800 Subject: [PATCH 018/217] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=AE=80=E5=8D=95?= =?UTF-8?q?=E7=9A=84=E6=9B=B4=E6=96=B0=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/common/util/PackageUtils.java | 20 +++ .../java/com/gh/download/DownloadManager.java | 3 +- .../download/UpdatableGameViewModel.kt | 20 +-- .../gh/gamecenter/entity/GameUpdateEntity.kt | 4 +- app/src/main/java/com/gh/vspace/VHelper.kt | 128 +++++++++++++----- .../main/java/com/halo/assistant/HaloApp.java | 4 +- .../gamecenter/common/constant/Constants.java | 2 + 7 files changed, 131 insertions(+), 50 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/PackageUtils.java b/app/src/main/java/com/gh/common/util/PackageUtils.java index 0b6332d43d..24e6114bae 100644 --- a/app/src/main/java/com/gh/common/util/PackageUtils.java +++ b/app/src/main/java/com/gh/common/util/PackageUtils.java @@ -22,13 +22,18 @@ import com.android.apksig.ApkVerifier; import com.android.apksig.internal.apk.ApkSigningBlockUtilsLite; import com.g00fy2.versioncompare.Version; import com.gh.common.xapk.XapkInstaller; +import com.gh.download.DownloadManager; 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.SentryHelper; import com.gh.gamecenter.entity.ApkEntity; import com.gh.gamecenter.entity.GameEntity; import com.gh.gamecenter.entity.GameUpdateEntity; import com.gh.gamecenter.manager.PackagesManager; +import com.gh.vspace.VHelper; import com.halo.assistant.HaloApp; +import com.lightgame.download.DownloadEntity; import com.lightgame.utils.Utils; import net.dongliu.apk.parser.ApkFile; @@ -113,6 +118,19 @@ public class PackageUtils { // 根据版本判断是否需要更新 shouldShowUpdate = new Version(versionFromRequest).isHigherThan(versionFromInstalledApp); + // 畅玩游戏根据 md5 是否一致确定是否需要更新 + if (gameEntity.isVGame()) { + DownloadEntity entity = VHelper.getVGameSnapshot(apkEntity.getPackageName()); + if (entity != null) { + String md5FromInstalledVGame = ExtensionsKt.getMetaExtra(entity, Constants.APK_MD5); + String md5FromRequest = apkEntity.getMd5(); + + if (md5FromRequest!= null && md5FromRequest.equals(md5FromInstalledVGame)) { + shouldShowUpdate = true; + } + } + } + // versionName 没法判定的时候尝试使用 versionCode 去判断 if (!shouldShowUpdate && versionCodeFromRequest != 0) { shouldShowUpdate = versionCodeFromRequest > versionCodeFromInstalledApp; @@ -130,6 +148,8 @@ public class PackageUtils { updateEntity.setUrl(apkEntity.getUrl()); updateEntity.setPlatform(apkEntity.getPlatform()); updateEntity.setEtag(apkEntity.getEtag()); + updateEntity.setMd5(apkEntity.getMd5()); + updateEntity.setDownloadStatus(gameEntity.getDownloadStatus()); updateEntity.setBrief(gameEntity.getBrief()); updateEntity.setTagStyle(gameEntity.getTagStyle()); updateEntity.setIndexPlugin(gameEntity.getIndexPlugin()); diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index bae549f65f..da61f615f6 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -323,6 +323,7 @@ public class DownloadManager implements DownloadStatusListener { downloadEntity.setEntrance(entrance); downloadEntity.setLocation(location); downloadEntity.setVersionName(apkEntity.getVersion()); + ExtensionsKt.addMetaExtra(downloadEntity, Constants.APK_MD5, apkEntity.getMd5()); ExtensionsKt.addMetaExtra(downloadEntity, Constants.DOWNLOAD_ID, downloadId); ExtensionsKt.addMetaExtra(downloadEntity, Constants.RAW_GAME_ICON, gameEntity.getRawIcon()); ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_SUBSCRIPT, gameEntity.getIconSubscript()); @@ -652,7 +653,7 @@ public class DownloadManager implements DownloadStatusListener { /** * 获取下载列表中的畅玩下载任务 */ - public List getAllVDownloadTask() { + public ArrayList getAllVDownloadTask() { List downloadList = getAllDownloadEntity(); ArrayList filteredDownloadEntityList = new ArrayList<>(); diff --git a/app/src/main/java/com/gh/gamecenter/download/UpdatableGameViewModel.kt b/app/src/main/java/com/gh/gamecenter/download/UpdatableGameViewModel.kt index b82a313e66..bb242a8edb 100644 --- a/app/src/main/java/com/gh/gamecenter/download/UpdatableGameViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/download/UpdatableGameViewModel.kt @@ -3,27 +3,31 @@ package com.gh.gamecenter.download import android.app.Application import android.view.View import androidx.lifecycle.* -import com.gh.gamecenter.common.base.BaseSimpleDao -import com.gh.gamecenter.common.constant.Constants import com.gh.common.exposure.ExposureUtils import com.gh.common.exposure.ExposureUtils.logADownloadExposureEvent import com.gh.common.history.HistoryHelper.insertGameEntity -import com.gh.common.util.* -import com.gh.gamecenter.core.utils.GsonUtils.toJson +import com.gh.common.util.ApkActiveUtils +import com.gh.common.util.DataCollectionUtils import com.gh.common.util.PackageInstaller.createDownloadId import com.gh.common.util.PackageInstaller.getDownloadPathWithId +import com.gh.common.util.PackageUtils +import com.gh.common.util.PlatformUtils import com.gh.download.DownloadManager +import com.gh.gamecenter.common.base.BaseSimpleDao +import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.common.utils.addMetaExtra import com.gh.gamecenter.common.utils.secondOrNull import com.gh.gamecenter.common.utils.toProperReadableSize import com.gh.gamecenter.common.utils.tryCatchInRelease -import com.gh.gamecenter.core.utils.* +import com.gh.gamecenter.core.utils.GsonUtils.toJson +import com.gh.gamecenter.core.utils.SPUtils +import com.gh.gamecenter.core.utils.UrlFilterUtils import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.entity.GameUpdateEntity import com.gh.gamecenter.entity.PluginLocation import com.gh.gamecenter.eventbus.EBDownloadChanged import com.gh.gamecenter.manager.PackagesManager -import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.retrofit.RetrofitManager import com.halo.assistant.HaloApp import com.lightgame.download.DownloadEntity @@ -32,7 +36,6 @@ import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers import org.greenrobot.eventbus.EventBus import java.util.* -import kotlin.collections.ArrayList class UpdatableGameViewModel( application: Application, @@ -72,7 +75,7 @@ class UpdatableGameViewModel( // 有闪退日志说这个 update 实体可能为空,实在看不原因 :( if (update == null) continue // 筛选仅下载管理出现的插件化更新 - if (update.isShowPlugin(PluginLocation.only_index)) { + if (update.isShowPlugin(PluginLocation.only_index) && update.downloadStatus != "smooth") { val platform = PlatformUtils.getInstance(getApplication()).getPlatformName(update.platform) if (!platform.isNullOrEmpty() && "官方版" != platform) { @@ -580,6 +583,7 @@ class UpdatableGameViewModel( downloadEntity.addMetaExtra(Constants.RAW_GAME_ICON, update.rawIcon) downloadEntity.addMetaExtra(Constants.GAME_ICON_SUBSCRIPT, update.iconSubscript) downloadEntity.addMetaExtra(Constants.DOWNLOAD_ID, downloadId) + downloadEntity.addMetaExtra(Constants.APK_MD5, update.md5) val platform = PlatformUtils.getInstance(getApplication()).getPlatformName(update.platform) if ("官方版" != platform) { diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameUpdateEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/GameUpdateEntity.kt index eead9177dd..579f42a0bf 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameUpdateEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameUpdateEntity.kt @@ -40,7 +40,9 @@ data class GameUpdateEntity( var pluggableCollection: GameCollectionEntity? = null, // 插件化包所在的合集 var format: String = "", var signature: String? = "", - var category: String? = "" + var category: String? = "", + var md5: String? = "", + var downloadStatus: String? = "" ) { fun isShowPlugin(location: PluginLocation): Boolean { diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 0bbf5b8750..09ad351d17 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -14,6 +14,7 @@ import com.gh.gamecenter.R import com.gh.gamecenter.common.utils.DialogHelper import com.gh.gamecenter.common.utils.toColor import com.gh.gamecenter.core.AppExecutor +import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.core.utils.EmptyCallback import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.entity.ApkEntity @@ -34,6 +35,7 @@ object VHelper { private val mDelegateManager by lazy { VirtualAppManager.get() } private var mInstalledInfoList: List = arrayListOf() private val mInstallationLiveData by lazy { MutableLiveData() } + private var mInstalledEntitySnapshotList: ArrayList? = null // 畅玩游戏的列表快照,不保证完全即时,但获取信息应该够用了 private val mPackageObserver by lazy { PackageObserver.PackageChangeListener { val vaConfig = Config.getVSettingEntity()?.va ?: return@PackageChangeListener @@ -43,7 +45,8 @@ object VHelper { if (!isVSpace) return@PackageChangeListener if (it.type == "安装") { - connectService() + // 即时调用大概率调不起来,我也不知道为什么,只能延迟大法了 + AppExecutor.uiExecutor.executeWithDelay({ connectService() }, 500) } else if (it.type == "卸载") { // TODO 执行卸载逻辑 } @@ -51,8 +54,13 @@ object VHelper { } @JvmStatic - fun init() { - connectService() + fun init(context: Context) { + val config = Config.getVSettingEntity()?.va + if (config != null + && PackageUtils.isInstalled(context, config.arch32?.packageName) + ) { + connectService() + } PackageObserver.registerPackageChangeChangeListener(mPackageObserver) } @@ -64,6 +72,9 @@ object VHelper { override fun onServiceConnectionSuccessed() { Utils.log(LOG_TAG, "V 服务连接成功") mInstalledInfoList = getInstalledList() + + updateVGameSnapshot() + PackageRepository.addInstalledGames(getInstalledPackageList()) callbackClosure?.invoke() @@ -120,7 +131,7 @@ object VHelper { // 检查更新 val containsUpdate = - vaConfig32?.versionCode ?: 0 == PackageUtils.getVersionCodeByPackageName(vaConfig32?.packageName) + vaConfig32?.versionCode ?: 0 > PackageUtils.getVersionCodeByPackageName(vaConfig32?.packageName) if (containsUpdate) { // 触发更新弹窗 @@ -183,28 +194,29 @@ object VHelper { return ArrayList(list) } - /** - * 是否已经授予了游戏空间存储权限 - */ - fun isStoragePermissionGranted(): Boolean { - return mDelegateManager.checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE) - } - /** * 检查存储权限,若已授予直接执行后续逻辑 */ private fun checkStoragePermissionBeforeAction(context: Context, callback: () -> Unit) { - try { - val isStoragePermissionGranted = - mDelegateManager.checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE) - if (isStoragePermissionGranted) { - callback.invoke() - } else { - context.startActivity(mDelegateManager.requestPermissionIntent) + val checkClosure: () -> Unit = { + try { + val isStoragePermissionGranted = + mDelegateManager.checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE) + if (isStoragePermissionGranted) { + callback.invoke() + } else { + context.startActivity(mDelegateManager.requestPermissionIntent) + } + } catch (e: RuntimeException) { + e.printStackTrace() + Utils.log(LOG_TAG, "检查存储权限失败 ${e.localizedMessage}") } - } catch (e: RuntimeException) { - e.printStackTrace() - Utils.log(LOG_TAG, "检查存储权限失败 ${e.localizedMessage}") + } + + if (mDelegateManager.isConnectAidlInterface) { + checkClosure.invoke() + } else { + connectService(checkClosure) } } @@ -224,10 +236,18 @@ object VHelper { AppExecutor.ioExecutor.execute { val result = VirtualAppManager.get().installGame(filePath) if (result.status == 0) { + updateVGameSnapshot() updateInstalledList() showFloatingWindow(result.packageName) - PackageObserver.onPackageChanged(EBPackage("安装", result.packageName, "unknown")) + PackageObserver.onPackageChanged( + EBPackage( + "安装", + result.packageName, + "unknown" + ) + ) } + mInstallationLiveData.postValue(result.packageName) Utils.log(LOG_TAG, "安装新应用结果 -> " + result.status) } @@ -252,12 +272,20 @@ object VHelper { return } - try { - val intent = mDelegateManager.getStartGameIntent(packageName) - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - activity.startActivity(intent) - } catch (e: Exception) { - ToastUtils.toast(e.localizedMessage ?: "") + val launchClosure: () -> Unit = { + try { + val intent = mDelegateManager.getStartGameIntent(packageName) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + activity.startActivity(intent) + } catch (e: Exception) { + ToastUtils.toast(e.localizedMessage ?: "") + } + } + + if (mDelegateManager.isConnectAidlInterface) { + launchClosure.invoke() + } else { + connectService(launchClosure) } } @@ -265,15 +293,25 @@ object VHelper { * 卸载应用 */ fun uninstall(packageName: String?) { - try { - val result = VirtualAppManager.get().uninstallGame(packageName) - if (result) { - updateInstalledList() - PackageObserver.onPackageChanged(EBPackage("卸载", packageName, "unknown")) + val uninstallClosure: () -> Unit = { + try { + val result = VirtualAppManager.get().uninstallGame(packageName) + if (result) { + updateVGameSnapshot() + updateInstalledList() + PackageObserver.onPackageChanged(EBPackage("卸载", packageName, "unknown")) + } + + Utils.log(LOG_TAG, "安装新应用结果 -> $result") + } catch (e: Exception) { + ToastUtils.toast(e.localizedMessage ?: "") } - Utils.log(LOG_TAG, "安装新应用结果 -> $result") - } catch (e: Exception) { - ToastUtils.toast(e.localizedMessage ?: "") + } + + if (mDelegateManager.isConnectAidlInterface) { + uninstallClosure.invoke() + } else { + connectService(uninstallClosure) } } @@ -296,7 +334,7 @@ object VHelper { * 如果已安装或配置为空返回 true * 未安装的情况下会弹弹窗 */ - private fun showDialogIfVSpaceIsNeeded(context: Context) : Boolean { + private fun showDialogIfVSpaceIsNeeded(context: Context): Boolean { val vaConfig = Config.getVSettingEntity()?.va ?: return true // TODO 检测 64 位 @@ -308,6 +346,22 @@ object VHelper { return false } + private fun updateVGameSnapshot() { + runOnIoThread { + mInstalledEntitySnapshotList = ArrayList(DownloadManager.getInstance().allVDownloadTask) + } + } + + /** + * 获取数据库中已安装的畅玩游戏的快照 + */ + @JvmStatic + fun getVGameSnapshot(packageName: String): DownloadEntity? { + return mInstalledEntitySnapshotList?.firstOrNull { + it.packageName == packageName + } + } + fun toGameEntity(downloadEntity: DownloadEntity): GameEntity { return GameEntity(id = downloadEntity.gameId, name = downloadEntity.name).apply { setApk( diff --git a/app/src/main/java/com/halo/assistant/HaloApp.java b/app/src/main/java/com/halo/assistant/HaloApp.java index 22bfe9e74d..d75de03014 100644 --- a/app/src/main/java/com/halo/assistant/HaloApp.java +++ b/app/src/main/java/com/halo/assistant/HaloApp.java @@ -441,9 +441,7 @@ public class HaloApp extends MultiDexApplication implements Configuration.Provid } private void retrieveVGameInfoIfNeeded() { -// if (SPUtils.getBoolean(Constants.SP_IS_VSPACE_USED)) { - VHelper.init(); -// } + VHelper.init(this); } public boolean isEmulator() { diff --git a/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java b/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java index 3ca4ec85b2..1a9c1fde57 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java +++ b/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java @@ -59,6 +59,8 @@ public class Constants { public static final String IS_PLATFORM_RECOMMEND = "isPlatformRecommend"; + public static final String APK_MD5 = "apk_md5"; + // 下载 id,一般来说跟下载文件名一样 public static final String DOWNLOAD_ID = "download_id"; From 57668ec97daf0d065fe9594c1a255c06fae142b8 Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 31 May 2022 11:36:23 +0800 Subject: [PATCH 019/217] =?UTF-8?q?=E5=90=88=E5=B9=B6=E6=9C=AA=E6=8E=A5?= =?UTF-8?q?=E5=85=A5=E9=98=B2=E6=B2=89=E8=BF=B7=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/util/DownloadObserver.kt | 27 ++++++++++++++----- .../com/gh/vspace/VSpaceLoadingFragment.kt | 17 +++++++++--- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/DownloadObserver.kt b/app/src/main/java/com/gh/common/util/DownloadObserver.kt index f0c577ca65..e4b59509aa 100644 --- a/app/src/main/java/com/gh/common/util/DownloadObserver.kt +++ b/app/src/main/java/com/gh/common/util/DownloadObserver.kt @@ -14,10 +14,18 @@ import com.gh.gamecenter.common.callback.ConfirmListener import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.eventbus.EBShowDialog import com.gh.gamecenter.common.retrofit.Response +import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.eventbus.EBShowDialog +import com.gh.gamecenter.common.exposure.meta.MetaUtil +import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.GsonUtils import com.gh.gamecenter.core.utils.MtaHelper import com.gh.gamecenter.core.utils.StringUtils +import com.gh.gamecenter.core.utils.GsonUtils +import com.gh.gamecenter.core.utils.MtaHelper +import com.gh.gamecenter.core.utils.StringUtils +import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.entity.SimpleGameEntity import com.gh.gamecenter.entity.SimulatorEntity @@ -115,14 +123,19 @@ object DownloadObserver { downloadManager.cancel(downloadEntity.url) } else if (DownloadStatus.unavailable == downloadEntity.status) { // 未接入防沉迷系统 - val currentActivity = AppManager.getInstance().currentActivity() ?: return + val currentActivity = AppManager.getInstance().currentActivity() - DialogHelper.showDialog( - context = currentActivity, - title = "温馨提示", - content = "该游戏未接入防沉迷系统,暂不支持下载", - confirmText = "知道了", - cancelText = "") + if (currentActivity != null) { + DialogHelper.showDialog( + context = currentActivity, + title = "温馨提示", + content = "该游戏未接入防沉迷系统,暂不支持下载", + confirmText = "知道了", + cancelText = "" + ) + } else { + ToastUtils.toast("该游戏未接入防沉迷系统,暂不支持下载") + } // 删除任务 downloadEntity.status = DownloadStatus.cancel diff --git a/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt index a064913d39..f0a498df98 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt @@ -4,6 +4,7 @@ import android.os.Bundle import android.view.View import com.gh.gamecenter.common.base.fragment.BaseFragment import com.gh.gamecenter.common.constant.EntranceConsts +import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.databinding.FragmentVspaceLoadingBinding import com.gh.gamecenter.entity.GameEntity import com.lightgame.download.DataChanger @@ -30,7 +31,7 @@ class VSpaceLoadingFragment : BaseFragment() { download, downloading -> { mBinding.progressBar.progress = downloadEntity.percent.toInt() - mBinding.progressTv.text = "加载中...${(downloadEntity.percent)}%" + mBinding.progressTv.text = "加载中...${downloadEntity.percent}%" } done -> { @@ -44,7 +45,17 @@ class VSpaceLoadingFragment : BaseFragment() { hijack, notfound, neterror, - overflow -> { + overflow -> requireActivity().finish() + unqualified -> { + ToastUtils.toast("该游戏未接入防沉迷系统,暂不支持下载") + requireActivity().finish() + } + uncertificated -> { + ToastUtils.toast("该游戏未接入防沉迷系统,暂不支持下载") + requireActivity().finish() + } + unavailable -> { + ToastUtils.toast("该游戏未接入防沉迷系统,暂不支持下载") requireActivity().finish() } @@ -80,7 +91,7 @@ class VSpaceLoadingFragment : BaseFragment() { } private fun showFakeLaunchProgress() { - + // TODO 显示假的启动进度 } override fun onResume() { From 477ffa0c330d0289ad2fe3341dabd782feb4f9d1 Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 31 May 2022 18:06:30 +0800 Subject: [PATCH 020/217] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=AE=80=E5=8D=95?= =?UTF-8?q?=E9=A6=96=E9=A1=B5=E5=88=97=E8=A1=A8=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 1 + .../com/gh/common/util/DownloadObserver.kt | 2 +- .../java/com/gh/download/PackageObserver.kt | 18 +++++--- .../adapter/viewholder/DetailViewHolder.java | 2 +- .../com/gh/gamecenter/entity/GameEntity.kt | 4 ++ .../com/gh/gamecenter/home/HomeFragment.kt | 4 ++ .../com/gh/gamecenter/home/HomeViewModel.kt | 5 ++- .../gh/vspace/HomeRecentVGameViewHolder.kt | 42 ++++++++++++++++++- .../com/gh/vspace/VDownloadManagerActivity.kt | 13 +++++- .../com/gh/vspace/VDownloadManagerFragment.kt | 6 +-- .../vspace/VDownloadManagerWrapperFragment.kt | 5 +++ app/src/main/java/com/gh/vspace/VHelper.kt | 6 +-- .../res/layout/item_home_recent_vgame.xml | 3 ++ 13 files changed, 92 insertions(+), 19 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9068beac4c..3bf65fa8db 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -733,6 +733,7 @@ android:screenOrientation="portrait" /> { if (apk == null) apk = ArrayList() return apk!! diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt b/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt index f9e8ce0ec0..94f04f613d 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt @@ -273,6 +273,8 @@ class HomeFragment : LazyFragment() { @Subscribe(threadMode = ThreadMode.MAIN) fun onEventMainThread(status: EBDownloadStatus) { if ("delete" == status.status) { + // TODO 看看能不能避免粗暴地更新列表 + mViewModel.refreshRecentVGameIfNeeded() mListAdapter.notifyItemAndRemoveDownload(status) } } @@ -284,6 +286,7 @@ class HomeFragment : LazyFragment() { for (gameAndPosition in data) { mListAdapter.notifyChildItem(gameAndPosition.position, busFour.packageName) } + mViewModel.refreshRecentVGameIfNeeded() } @Subscribe(threadMode = ThreadMode.MAIN) @@ -291,6 +294,7 @@ class HomeFragment : LazyFragment() { if (::mListAdapter.isInitialized && "Refresh" == reuse.type) { mListAdapter.notifyDataSetChanged() } + mViewModel.refreshRecentVGameIfNeeded() } @Subscribe(threadMode = ThreadMode.MAIN) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index e8e6f97043..775a9334ed 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -94,8 +94,6 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { } fun refreshRecentVGameIfNeeded() { - // TODO VA 安装完成的时候刷新列表 - // TODO 根据开关判断是否隐藏下面的数据 // TODO 排序 // TODO 避免多线程异常 if (SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, true)) { @@ -113,6 +111,9 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { if (mHomeSlides.isNotEmpty() || mHomeRecommends.isNotEmpty()) { transformationItemData() } + } else { + mVGameList?.clear() + transformationItemData() } } } diff --git a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt index e852de82e4..e033e55382 100644 --- a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt +++ b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt @@ -1,14 +1,52 @@ package com.gh.vspace +import android.content.Context +import android.view.ViewGroup +import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.gh.gamecenter.baselist.DiffUtilAdapter +import com.gh.gamecenter.common.utils.toBinding import com.gh.gamecenter.databinding.ItemHomeRecentVgameBinding +import com.gh.gamecenter.databinding.ItemHomeVgameBinding import com.gh.gamecenter.entity.GameEntity class HomeRecentVGameViewHolder(var binding: ItemHomeRecentVgameBinding) : RecyclerView.ViewHolder(binding.root) { fun bindView(gameList: ArrayList) { - // TODO 实现列表 + if (binding.recyclerview.adapter == null) { + binding.recyclerview.layoutManager = LinearLayoutManager(binding.root.context) + binding.recyclerview.adapter = HomeRecentVGameAdapter(binding.root.context) + } + + (binding.recyclerview.adapter as? HomeRecentVGameAdapter)?.submitList(gameList) } -} \ No newline at end of file + class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter(context) { + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): HomeRecentVGameItemViewHolder { + return HomeRecentVGameItemViewHolder(parent.toBinding()) + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + (holder as HomeRecentVGameItemViewHolder).bindView(mDataList[position]) + } + + override fun getItemCount() = mDataList.size + } + + class HomeRecentVGameItemViewHolder(private var mBinding: ItemHomeVgameBinding) : + RecyclerView.ViewHolder(mBinding.root) { + + fun bindView(gameEntity: GameEntity) { + mBinding.gameIconIv.displayGameIcon(gameEntity) + mBinding.root.setOnClickListener { + VHelper.launch(mBinding.root.context, gameEntity.getUniquePackageName() ?: "") + } + } + } + +} + diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt index a85357cd82..b283142558 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt @@ -1,9 +1,11 @@ package com.gh.vspace +import android.content.Context +import android.content.Intent import android.os.Bundle import com.gh.gamecenter.R import com.gh.gamecenter.common.base.activity.ToolBarActivity -import com.gh.gamecenter.core.utils.DisplayUtils +import com.gh.gamecenter.common.constant.EntranceConsts class VDownloadManagerActivity: ToolBarActivity() { @@ -12,6 +14,7 @@ class VDownloadManagerActivity: ToolBarActivity() { if (savedInstanceState == null) { val fragment = VDownloadManagerWrapperFragment() + fragment.arguments = intent.extras supportFragmentManager.beginTransaction().replace(R.id.placeholder, fragment).commitAllowingStateLoss() updateTargetFragment(fragment) } @@ -19,4 +22,12 @@ class VDownloadManagerActivity: ToolBarActivity() { override fun getLayoutId() = R.layout.activity_vdownload_manager + companion object { + fun getIntent(context: Context, switchToDownloadingTab: Boolean = false): Intent { + val intent = Intent(context, VDownloadManagerActivity::class.java) + intent.putExtra(EntranceConsts.KEY_POSITION, if (switchToDownloadingTab) 1 else 0) + return intent + } + } + } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index 9bcf4b8b05..d569e17137 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -68,14 +68,14 @@ class VDownloadManagerFragment : mBinding.headerContainer.goneIf(mViewModel.type != VDownloadManagerViewModel.TYPE_DOWNLOADED) mBinding.switchIv.enlargeTouchArea() - mBinding.switchIv.isSelected = SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, true) + mBinding.switchIv.isChecked = SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, true) mBinding.switchIv.setOnClickListener { if (mBinding.switchLottie.isAnimating) return@setOnClickListener - val status = mBinding.switchIv.isSelected + val status = mBinding.switchIv.isChecked val anime = if (status) "lottie/switch_turnoff.json" else "lottie/switch_turnon.json" mBinding.switchLottie.setAnimation(anime) mBinding.switchLottie.playAnimation() - mBinding.switchIv.isSelected = !status + mBinding.switchIv.isChecked = !status SPUtils.setBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, !status) DownloadManager.getInstance().notifyDownloadLiveDataChanged() diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt index fa14fac92b..05a59651e1 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt @@ -7,6 +7,7 @@ import android.widget.TextView import androidx.fragment.app.Fragment import com.gh.gamecenter.R import com.gh.gamecenter.common.base.fragment.BaseLazyTabFragment +import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.viewModelProvider import com.gh.gamecenter.databinding.FragmentVdownloadManagerWrapperBinding import com.gh.gamecenter.history.IBatchDelete @@ -30,6 +31,10 @@ class VDownloadManagerWrapperFragment: BaseLazyTabFragment() { toast("打开畅玩广场") } + arguments?.getInt(EntranceConsts.KEY_POSITION)?.let { + mViewPager.currentItem = it + } + mManageMenu = getItemMenu(R.id.layout_menu_manage) mManageMenu?.actionView?.setOnClickListener { when (mViewModel.currentOptionLiveData.value) { diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 09ad351d17..0227eb61bd 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -265,10 +265,10 @@ object VHelper { * 启动应用 */ @JvmStatic - fun launch(activity: Activity, packageName: String) { + fun launch(context: Context, packageName: String) { Utils.log(LOG_TAG, "打开应用$packageName") - if (showDialogIfVSpaceIsNeeded(activity)) { + if (showDialogIfVSpaceIsNeeded(context)) { return } @@ -276,7 +276,7 @@ object VHelper { try { val intent = mDelegateManager.getStartGameIntent(packageName) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - activity.startActivity(intent) + context.startActivity(intent) } catch (e: Exception) { ToastUtils.toast(e.localizedMessage ?: "") } diff --git a/app/src/main/res/layout/item_home_recent_vgame.xml b/app/src/main/res/layout/item_home_recent_vgame.xml index 88914e7ddb..264e66fdfc 100644 --- a/app/src/main/res/layout/item_home_recent_vgame.xml +++ b/app/src/main/res/layout/item_home_recent_vgame.xml @@ -46,6 +46,9 @@ android:layout_width="0dp" android:layout_height="48dp" android:layout_marginEnd="8dp" + android:clipToPadding="false" + android:paddingStart="16dp" + android:paddingEnd="16dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@id/vspaceIv" app:layout_constraintStart_toStartOf="parent" /> From 83afd7448f7a01e30c3fb45d260fe59d031aa69c Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 31 May 2022 20:44:41 +0800 Subject: [PATCH 021/217] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=AE=80=E5=8D=95?= =?UTF-8?q?=E9=A6=96=E9=A1=B5=E5=88=97=E8=A1=A8=E9=A1=B9=E5=8D=A0=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gamecenter/DownloadManagerActivity.java | 1 - .../com/gh/gamecenter/home/HomeFragment.kt | 1 - .../gh/gamecenter/home/HomeFragmentAdapter.kt | 16 +++--- .../com/gh/gamecenter/home/HomeViewModel.kt | 2 +- .../gh/vspace/HomeRecentVGameViewHolder.kt | 54 +++++++++++++------ .../res/layout/item_home_recent_vgame.xml | 2 +- 6 files changed, 48 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java index d45323822c..ee754f03f1 100644 --- a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java +++ b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java @@ -66,7 +66,6 @@ public class DownloadManagerActivity extends ToolBarActivity { return true; } - @Override protected void onNightModeChange() { super.onNightModeChange(); diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt b/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt index 94f04f613d..9854fbb8c3 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt @@ -273,7 +273,6 @@ class HomeFragment : LazyFragment() { @Subscribe(threadMode = ThreadMode.MAIN) fun onEventMainThread(status: EBDownloadStatus) { if ("delete" == status.status) { - // TODO 看看能不能避免粗暴地更新列表 mViewModel.refreshRecentVGameIfNeeded() mListAdapter.notifyItemAndRemoveDownload(status) } diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt index 597995012a..e8f06bce6f 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt @@ -9,10 +9,8 @@ import androidx.recyclerview.widget.RecyclerView import com.gh.common.exposure.ExposureEvent import com.gh.common.exposure.ExposureSource import com.gh.common.exposure.IExposable -import com.gh.gamecenter.core.runOnIoThread -import com.gh.common.util.* -import com.gh.common.util.NewLogUtils import com.gh.common.util.DirectUtils +import com.gh.common.util.NewLogUtils import com.gh.gamecenter.AboutActivity import com.gh.gamecenter.GameDetailActivity import com.gh.gamecenter.R @@ -21,7 +19,6 @@ import com.gh.gamecenter.adapter.viewholder.ReuseViewHolder import com.gh.gamecenter.baselist.DiffUtilAdapter import com.gh.gamecenter.baselist.LoadStatus import com.gh.gamecenter.common.constant.ItemViewType -import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.core.utils.MtaHelper @@ -37,6 +34,7 @@ import com.gh.gamecenter.home.gamecollection.HomeGameCollectionViewHolder import com.gh.gamecenter.home.slide.HomeSlideListAdapter import com.gh.gamecenter.home.slide.HomeSlideListViewHolder import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel +import com.gh.vspace.HomeRecentVGameAdapter import com.gh.vspace.HomeRecentVGameViewHolder import com.halo.assistant.fragment.game.GamePluginAdapter import com.lightgame.download.DownloadEntity @@ -387,10 +385,11 @@ class HomeFragmentAdapter( val entryMap = gameAndPosition.entity.getEntryMap() entryMap[download.platform] = download } - if (getItemViewType(gameAndPosition.position) == ItemViewType.VERTICAL_SLIDE_ITEM || - getItemViewType(gameAndPosition.position) == ItemViewType.GAME_PLUGIN || - getItemViewType(gameAndPosition.position) == SLIDE_ITEM || - getItemViewType(gameAndPosition.position) == ItemViewType.RANK_COLLECTION + if (getItemViewType(gameAndPosition.position) == ItemViewType.VERTICAL_SLIDE_ITEM + || getItemViewType(gameAndPosition.position) == ItemViewType.GAME_PLUGIN + || getItemViewType(gameAndPosition.position) == SLIDE_ITEM + || getItemViewType(gameAndPosition.position) == ItemViewType.RANK_COLLECTION + || getItemViewType(gameAndPosition.position) == RECENT_V_GAME ) { val view = layoutManager.findViewByPosition(gameAndPosition.position) val recyclerView = view?.findViewById(R.id.recycler_view) @@ -399,6 +398,7 @@ class HomeFragmentAdapter( is GamePluginAdapter -> adapter.notifyItemByDownload(download) is HomeSlideListAdapter -> adapter.notifyItemByDownload(download) is RankCollectionAdapter -> adapter.notifyItemByDownload(download) + is HomeRecentVGameAdapter -> adapter.notifyItemByDownload(download) } } else { notifyItemChanged(gameAndPosition.position) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index 775a9334ed..4276731e16 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -307,7 +307,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { } fun transformationItemData() { - runOnIoThread { + runOnIoThread(true) { mSnapshotItemList.clear() // 是否使用带特别高的带分割线的 item diff --git a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt index e033e55382..1d5be23ee4 100644 --- a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt +++ b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt @@ -4,37 +4,52 @@ import android.content.Context import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.gh.download.DownloadManager import com.gh.gamecenter.baselist.DiffUtilAdapter import com.gh.gamecenter.common.utils.toBinding +import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.databinding.ItemHomeRecentVgameBinding import com.gh.gamecenter.databinding.ItemHomeVgameBinding import com.gh.gamecenter.entity.GameEntity +import com.lightgame.download.DownloadEntity class HomeRecentVGameViewHolder(var binding: ItemHomeRecentVgameBinding) : RecyclerView.ViewHolder(binding.root) { fun bindView(gameList: ArrayList) { - if (binding.recyclerview.adapter == null) { - binding.recyclerview.layoutManager = LinearLayoutManager(binding.root.context) - binding.recyclerview.adapter = HomeRecentVGameAdapter(binding.root.context) + if (binding.recyclerView.adapter == null) { + binding.recyclerView.layoutManager = LinearLayoutManager(binding.root.context) + binding.recyclerView.adapter = HomeRecentVGameAdapter(binding.root.context) } - (binding.recyclerview.adapter as? HomeRecentVGameAdapter)?.submitList(gameList) + (binding.recyclerView.adapter as? HomeRecentVGameAdapter)?.submitList(gameList) + } +} + +class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter(context) { + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): HomeRecentVGameItemViewHolder { + return HomeRecentVGameItemViewHolder(parent.toBinding()) } - class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter(context) { - override fun onCreateViewHolder( - parent: ViewGroup, - viewType: Int - ): HomeRecentVGameItemViewHolder { - return HomeRecentVGameItemViewHolder(parent.toBinding()) - } + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + (holder as HomeRecentVGameItemViewHolder).bindView(mDataList[position]) + } - override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - (holder as HomeRecentVGameItemViewHolder).bindView(mDataList[position]) - } + override fun getItemCount() = mDataList.size - override fun getItemCount() = mDataList.size + fun notifyItemByDownload(downloadEntity: DownloadEntity?) { + if (downloadEntity == null) { + notifyDataSetChanged() + } else { + for (position in mDataList.indices) { + if (downloadEntity.name == mDataList[position].name) { + notifyItemChanged(position) + } + } + } } class HomeRecentVGameItemViewHolder(private var mBinding: ItemHomeVgameBinding) : @@ -42,11 +57,18 @@ class HomeRecentVGameViewHolder(var binding: ItemHomeRecentVgameBinding) : fun bindView(gameEntity: GameEntity) { mBinding.gameIconIv.displayGameIcon(gameEntity) + runOnIoThread(true) { + DownloadManager.getInstance().allVDownloadTask.find { + it.gameId == gameEntity.id + } + // TODO 添加 item 下载更新逻辑 + } mBinding.root.setOnClickListener { VHelper.launch(mBinding.root.context, gameEntity.getUniquePackageName() ?: "") } } } - } + + diff --git a/app/src/main/res/layout/item_home_recent_vgame.xml b/app/src/main/res/layout/item_home_recent_vgame.xml index 264e66fdfc..f8009904d4 100644 --- a/app/src/main/res/layout/item_home_recent_vgame.xml +++ b/app/src/main/res/layout/item_home_recent_vgame.xml @@ -42,7 +42,7 @@ app:layout_constraintTop_toTopOf="parent" /> Date: Mon, 6 Jun 2022 16:40:28 +0800 Subject: [PATCH 022/217] =?UTF-8?q?fix:=20=E5=A4=84=E7=90=86=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/common/util/DownloadObserver.kt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/DownloadObserver.kt b/app/src/main/java/com/gh/common/util/DownloadObserver.kt index 02bf0e298c..3c2d86c516 100644 --- a/app/src/main/java/com/gh/common/util/DownloadObserver.kt +++ b/app/src/main/java/com/gh/common/util/DownloadObserver.kt @@ -14,17 +14,10 @@ import com.gh.gamecenter.common.callback.ConfirmListener import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.eventbus.EBShowDialog import com.gh.gamecenter.common.retrofit.Response -import com.gh.gamecenter.common.constant.Constants -import com.gh.gamecenter.common.eventbus.EBShowDialog -import com.gh.gamecenter.common.exposure.meta.MetaUtil -import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.GsonUtils -import com.gh.gamecenter.core.utils.MtaHelper import com.gh.gamecenter.core.utils.StringUtils -import com.gh.gamecenter.core.utils.GsonUtils import com.gh.gamecenter.core.utils.MtaHelper -import com.gh.gamecenter.core.utils.StringUtils import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.entity.SimpleGameEntity From ab202abe0a20e76e628531c7fd03d39c84687a46 Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 7 Jun 2022 17:42:15 +0800 Subject: [PATCH 023/217] =?UTF-8?q?feat:=20=E9=A6=96=E9=A1=B5=E7=AE=80?= =?UTF-8?q?=E5=8D=95=E5=AF=B9=E6=8E=A5=E4=B8=8B=E8=BD=BD=E8=BF=9B=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/common/view/GameIconView.kt | 15 +-- .../gh/gamecenter/home/HomeFragmentAdapter.kt | 4 +- .../gh/vspace/HomeRecentVGameViewHolder.kt | 107 ++++++++++++++++-- app/src/main/java/com/gh/vspace/VHelper.kt | 17 +++ .../res/layout/item_home_recent_vgame.xml | 3 +- app/src/main/res/layout/item_home_vgame.xml | 39 ++++--- 6 files changed, 155 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/com/gh/common/view/GameIconView.kt b/app/src/main/java/com/gh/common/view/GameIconView.kt index 459a69984b..90898bcf47 100644 --- a/app/src/main/java/com/gh/common/view/GameIconView.kt +++ b/app/src/main/java/com/gh/common/view/GameIconView.kt @@ -10,12 +10,8 @@ import androidx.cardview.widget.CardView import com.facebook.drawee.generic.RoundingParams import com.facebook.drawee.view.SimpleDraweeView import com.gh.gamecenter.R -import com.gh.gamecenter.common.utils.dip2px -import com.gh.gamecenter.common.utils.display -import com.gh.gamecenter.common.utils.goneIf -import com.gh.gamecenter.common.utils.toColor +import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.DisplayUtils -import com.gh.gamecenter.common.utils.ImageUtils import com.gh.gamecenter.entity.GameEntity import splitties.views.dsl.core.add import splitties.views.dsl.core.lParams @@ -56,7 +52,7 @@ class GameIconView : CardView { val ta = context.obtainStyledAttributes(attrs, R.styleable.GameIconView) mCornerRadius = ta.getDimensionPixelSize( R.styleable.GameIconView_gameIconCornerRadius, - DisplayUtils.dip2px(0F) + DisplayUtils.dip2px(context, 0F) ) mBorderColor = ta.getColor(R.styleable.GameIconView_gameIconBorderColor, 0) mGameIconOverlayColor = ta.getColor(R.styleable.GameIconView_gameIconOverlayColor, 0) @@ -115,7 +111,12 @@ class GameIconView : CardView { override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { super.onSizeChanged(w, h, oldw, oldh) - val cornerRadius = getCornerRadius(w) + val cornerRadius = if (!isInEditMode) { + getCornerRadius(w) + } else { + 0F + } + radius = cornerRadius cardElevation = 0F diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt index e8f06bce6f..1bde409645 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt @@ -461,7 +461,9 @@ class HomeFragmentAdapter( } val attachGame = itemData.attachGame?.linkGame - if (attachGame != null) { + val recentVGame = itemData.recentVGame + + if (attachGame != null || recentVGame != null) { positionList.add(GameAndPosition(attachGame, position)) continue } diff --git a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt index 1d5be23ee4..78726f1e0f 100644 --- a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt +++ b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt @@ -5,21 +5,39 @@ import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.gh.download.DownloadManager +import com.gh.gamecenter.R import com.gh.gamecenter.baselist.DiffUtilAdapter +import com.gh.gamecenter.common.utils.goneIf import com.gh.gamecenter.common.utils.toBinding +import com.gh.gamecenter.common.utils.toDrawable +import com.gh.gamecenter.common.view.GridSpacingItemColorDecoration import com.gh.gamecenter.core.runOnIoThread +import com.gh.gamecenter.core.runOnUiThread +import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.databinding.ItemHomeRecentVgameBinding import com.gh.gamecenter.databinding.ItemHomeVgameBinding import com.gh.gamecenter.entity.GameEntity import com.lightgame.download.DownloadEntity +import com.lightgame.download.DownloadStatus class HomeRecentVGameViewHolder(var binding: ItemHomeRecentVgameBinding) : RecyclerView.ViewHolder(binding.root) { fun bindView(gameList: ArrayList) { if (binding.recyclerView.adapter == null) { - binding.recyclerView.layoutManager = LinearLayoutManager(binding.root.context) + binding.recyclerView.layoutManager = + LinearLayoutManager(binding.root.context, RecyclerView.HORIZONTAL, false) + binding.recyclerView.itemAnimator = null binding.recyclerView.adapter = HomeRecentVGameAdapter(binding.root.context) + binding.recyclerView.addItemDecoration( + GridSpacingItemColorDecoration(binding.root.context, 4, 0, R.color.transparent) + ) + + binding.moreTv.setOnClickListener { + binding.root.context.startActivity( + VDownloadManagerActivity.getIntent(binding.root.context, false) + ) + } } (binding.recyclerView.adapter as? HomeRecentVGameAdapter)?.submitList(gameList) @@ -27,6 +45,7 @@ class HomeRecentVGameViewHolder(var binding: ItemHomeRecentVgameBinding) : } class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter(context) { + override fun onCreateViewHolder( parent: ViewGroup, viewType: Int @@ -38,7 +57,9 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter(con (holder as HomeRecentVGameItemViewHolder).bindView(mDataList[position]) } - override fun getItemCount() = mDataList.size + override fun getItemCount(): Int { + return mDataList.size + } fun notifyItemByDownload(downloadEntity: DownloadEntity?) { if (downloadEntity == null) { @@ -56,16 +77,88 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter(con RecyclerView.ViewHolder(mBinding.root) { fun bindView(gameEntity: GameEntity) { - mBinding.gameIconIv.displayGameIcon(gameEntity) + if (mBinding.gameIconIv.getTag(R.string.app_name) != gameEntity.id) { + mBinding.gameIconIv.displayGameIcon(gameEntity) + mBinding.gameIconIv.setTag(R.string.app_name, gameEntity.id) + } runOnIoThread(true) { - DownloadManager.getInstance().allVDownloadTask.find { + val downloadEntity = DownloadManager.getInstance().allVDownloadTask.find { it.gameId == gameEntity.id } - // TODO 添加 item 下载更新逻辑 + + // TODO 处理页面被 detach 时候的回调 + if (downloadEntity != null) { + runOnUiThread { + updateViewByStatus(mBinding, downloadEntity) + } + } } - mBinding.root.setOnClickListener { - VHelper.launch(mBinding.root.context, gameEntity.getUniquePackageName() ?: "") + } + + private fun updateViewByStatus( + binding: ItemHomeVgameBinding, + downloadEntity: DownloadEntity + ) { + var shouldShowMask = false + var shouldShowProgressBar = false + var shouldShowUpdate = false + var shouldShowControlTv = false + var shouldShowDot = false + var controlText = "继续" + + when (downloadEntity.status) { + DownloadStatus.done -> { + binding.root.setOnClickListener { + VHelper.launch(binding.root.context, downloadEntity.packageName) + } + } + DownloadStatus.pause, + DownloadStatus.subscribe, + DownloadStatus.waiting -> { + shouldShowMask = true + shouldShowProgressBar = true + shouldShowControlTv = true + binding.progressBar.progressDrawable = + R.drawable.bg_home_vgame_progress_inactive.toDrawable() + binding.root.setOnClickListener { + DownloadManager.getInstance().resume(downloadEntity, false) + } + } + DownloadStatus.downloading -> { + shouldShowMask = true + shouldShowProgressBar = true + binding.progressBar.progressDrawable = + R.drawable.bg_home_vgame_progress_active.toDrawable() + binding.root.setOnClickListener { + DownloadManager.getInstance().pause(downloadEntity.url) + } + } + + DownloadStatus.timeout, + DownloadStatus.neterror, + DownloadStatus.hijack, + DownloadStatus.uncertificated, + DownloadStatus.unqualified, + DownloadStatus.notfound, + DownloadStatus.unavailable, + DownloadStatus.overflow -> { + controlText = "重试" + binding.root.setOnClickListener { + DownloadManager.getInstance().resume(downloadEntity, false) + } + } + else -> { + binding.root.setOnClickListener { + ToastUtils.showToast(downloadEntity.status.toString()) + } + } } + + mBinding.maskView.goneIf(!shouldShowMask) + mBinding.controlTv.goneIf(!shouldShowControlTv) + mBinding.progressBar.goneIf(!shouldShowProgressBar) + mBinding.controlTv.text = controlText + mBinding.progressBar.progress = downloadEntity.percent.toInt() } } } diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 0227eb61bd..e75c1ccfa3 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -4,6 +4,7 @@ import android.Manifest import android.app.Activity import android.content.Context import android.content.Intent +import android.text.TextUtils import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import com.gh.common.constant.Config @@ -12,6 +13,7 @@ import com.gh.download.DownloadManager import com.gh.download.PackageObserver import com.gh.gamecenter.R import com.gh.gamecenter.common.utils.DialogHelper +import com.gh.gamecenter.common.utils.getMetaExtra import com.gh.gamecenter.common.utils.toColor import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.core.runOnIoThread @@ -32,6 +34,8 @@ object VHelper { private const val LOG_TAG = "VSPACE" + const val KEY_LAST_PLAYED_TIME = "last_played_time" + private val mDelegateManager by lazy { VirtualAppManager.get() } private var mInstalledInfoList: List = arrayListOf() private val mInstallationLiveData by lazy { MutableLiveData() } @@ -315,6 +319,19 @@ object VHelper { } } + /** + * 获取游戏最后打开的时间 + * @return 最后打开的时间戳 + */ + fun getLastPlayedTime(downloadEntity: DownloadEntity): Long { + val lastPlayedTimeString = downloadEntity.getMetaExtra(KEY_LAST_PLAYED_TIME) + return if (TextUtils.isEmpty(lastPlayedTimeString)) { + 0 + } else { + lastPlayedTimeString.toLong() + } + } + fun getInstallationLiveData(): LiveData { return mInstallationLiveData } diff --git a/app/src/main/res/layout/item_home_recent_vgame.xml b/app/src/main/res/layout/item_home_recent_vgame.xml index f8009904d4..5175c90a77 100644 --- a/app/src/main/res/layout/item_home_recent_vgame.xml +++ b/app/src/main/res/layout/item_home_recent_vgame.xml @@ -27,7 +27,8 @@ android:textColor="@color/title" android:textSize="@dimen/primary_text_size" app:layout_constraintStart_toEndOf="@id/hintIv" - app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toTopOf="@id/hintIv" + app:layout_constraintBottom_toBottomOf="@id/hintIv"/> + app:layout_constraintEnd_toEndOf="@id/gameIconIv" + tools:visibility="visible" /> - - + tools:visibility="visible" /> + + + app:layout_constraintTop_toTopOf="@id/gameIconIv" + tools:visibility="visible" /> + app:layout_constraintStart_toStartOf="@id/gameIconIv" + tools:visibility="visible" /> \ No newline at end of file From 4d06707fabdb59419bbbd95f447513c2f8c207a6 Mon Sep 17 00:00:00 2001 From: juntao Date: Wed, 8 Jun 2022 14:43:49 +0800 Subject: [PATCH 024/217] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E6=9C=80=E8=BF=91=E5=9C=A8=E7=8E=A9=E7=AE=80=E5=8D=95?= =?UTF-8?q?=E7=9A=84=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/gamecenter/home/HomeViewModel.kt | 60 +++++++++++++++++-- app/src/main/java/com/gh/vspace/VHelper.kt | 21 ++++++- 2 files changed, 76 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index 4276731e16..f2ef038921 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -29,6 +29,7 @@ import com.gh.gamecenter.retrofit.RetrofitManager import com.gh.vspace.VHelper import com.halo.assistant.HaloApp import com.halo.assistant.fragment.SettingsFragment +import com.lightgame.download.DownloadEntity import com.lightgame.utils.Utils import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers @@ -94,12 +95,11 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { } fun refreshRecentVGameIfNeeded() { - // TODO 排序 // TODO 避免多线程异常 if (SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, true)) { - val entityList = DownloadManager.getInstance().allVDownloadTask + val entityList = getSortedVEntityList() - if (!entityList.isNullOrEmpty()) { + if (entityList.isNotEmpty()) { val vGameList = arrayListOf() for (entity in entityList) { @@ -118,6 +118,58 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { } } + /** + * 获取排好序的最近在玩列表 + * + * 首位:固定展示最近一次点击过下载\启动的游戏 + * 后续位置-优先级:完成下载但未启动过的游戏 > 完成下载且已启动过的游戏 + * 完成下载但未启动过的游戏:按照点击下载的时间倒序排列 + * 完成下载且已启动过的游戏:按照游戏的畅玩时长从左(长)向右(短)排列 + */ + private fun getSortedVEntityList() : List { + val rawEntityList = DownloadManager.getInstance().allVDownloadTask + var fixedTopEntity: DownloadEntity? = null + val unplayedEntityList = arrayListOf() + val playedEntityList = arrayListOf() + val sortedEntityList = arrayListOf() + + for (entity in rawEntityList) { + val lastPlayedTime = VHelper.getLastPlayedTime(entity) + val latestModifiedTime = maxOf(entity.start, VHelper.getLastPlayedTime(entity)) + + if (fixedTopEntity == null) { + fixedTopEntity = entity + } else { + val fixedTopLatestModifiedTime = maxOf(fixedTopEntity.start, VHelper.getLastPlayedTime(fixedTopEntity)) + if (latestModifiedTime > fixedTopLatestModifiedTime) { + fixedTopEntity = entity + } + } + + if (lastPlayedTime == 0L) { + unplayedEntityList.add(entity) + } else { + playedEntityList.add(entity) + } + } + + unplayedEntityList.removeAll { it.packageName == fixedTopEntity?.packageName } + unplayedEntityList.sortedByDescending { + it.start + } + + playedEntityList.removeAll { it.packageName == fixedTopEntity?.packageName } + playedEntityList.sortedByDescending { + VHelper.getLastPlayedTime(it) + } + + fixedTopEntity?.let { sortedEntityList.add(it) } + sortedEntityList.addAll(unplayedEntityList) + sortedEntityList.addAll(playedEntityList) + + return sortedEntityList.take(8) + } + private fun initPlugin(updateList: List?) { if (updateList == null) return @@ -275,7 +327,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { private fun initRandomGame(subjectId: String, sourceList: List?) { var rawList: MutableList? = null for (entity in mHomeContents) { - if (entity.linkColumn?.id == subjectId) rawList = entity.linkColumn?.data + if (entity.linkColumn?.id == subjectId) rawList = entity.linkColumn.data } if (rawList == null) return diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index e75c1ccfa3..2ea588fb71 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -13,6 +13,7 @@ import com.gh.download.DownloadManager import com.gh.download.PackageObserver import com.gh.gamecenter.R import com.gh.gamecenter.common.utils.DialogHelper +import com.gh.gamecenter.common.utils.addMetaExtra import com.gh.gamecenter.common.utils.getMetaExtra import com.gh.gamecenter.common.utils.toColor import com.gh.gamecenter.core.AppExecutor @@ -22,6 +23,7 @@ import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.entity.ApkEntity import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.eventbus.EBPackage +import com.gh.gamecenter.eventbus.EBReuse import com.gh.gamecenter.packagehelper.PackageRepository import com.lg.vspace.VirtualAppManager import com.lg.vspace.remote.listener.RemoteConnectListener @@ -29,12 +31,13 @@ import com.lg.vspace.remote.model.AppInstallerInfo import com.lightgame.download.DownloadEntity import com.lightgame.utils.AppManager import com.lightgame.utils.Utils +import org.greenrobot.eventbus.EventBus object VHelper { private const val LOG_TAG = "VSPACE" - const val KEY_LAST_PLAYED_TIME = "last_played_time" + private const val KEY_LAST_PLAYED_TIME = "last_played_time" private val mDelegateManager by lazy { VirtualAppManager.get() } private var mInstalledInfoList: List = arrayListOf() @@ -281,6 +284,8 @@ object VHelper { val intent = mDelegateManager.getStartGameIntent(packageName) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(intent) + + updateLastPlayedTime(packageName) } catch (e: Exception) { ToastUtils.toast(e.localizedMessage ?: "") } @@ -332,6 +337,20 @@ object VHelper { } } + /** + * 更新游戏最后打开的时间 + */ + private fun updateLastPlayedTime(packageName: String) { + runOnIoThread { + val entity = DownloadManager.getInstance().allVDownloadTask.find { it.packageName == packageName } + entity?.addMetaExtra(KEY_LAST_PLAYED_TIME, System.currentTimeMillis().toString()) + DownloadManager.getInstance().updateDownloadEntity(entity) + + // 更新首页排序 + EventBus.getDefault().post(EBReuse("vgame")) + } + } + fun getInstallationLiveData(): LiveData { return mInstallationLiveData } From a96fe9144a31053a309a6f2e261c89926cc1429d Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 9 Jun 2022 10:39:41 +0800 Subject: [PATCH 025/217] =?UTF-8?q?=E5=88=87=E6=8D=A2=E5=88=B0=2064=20?= =?UTF-8?q?=E4=BD=8D=E7=95=85=E7=8E=A9=E7=A9=BA=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../base/GlobalActivityLifecycleObserver.kt | 5 + .../java/com/gh/download/DownloadManager.java | 26 ++++- .../java/com/gh/gamecenter/entity/VSetting.kt | 1 + .../com/gh/gamecenter/home/HomeViewModel.kt | 4 +- .../com/gh/vspace/VDownloadManagerAdapter.kt | 10 ++ .../com/gh/vspace/VDownloadManagerFragment.kt | 5 + .../gh/vspace/VDownloadManagerViewModel.kt | 5 - .../com/gh/vspace/VFeedbackDialogFragment.kt | 2 +- .../gh/vspace/VFeedbackSuppressedSimpleDao.kt | 2 +- app/src/main/java/com/gh/vspace/VHelper.kt | 99 ++++++++++++++----- .../com/gh/vspace/VSpaceDialogFragment.kt | 2 +- vspace-bridge | 2 +- 12 files changed, 125 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/com/gh/base/GlobalActivityLifecycleObserver.kt b/app/src/main/java/com/gh/base/GlobalActivityLifecycleObserver.kt index ef4524f652..f81a48f2f9 100644 --- a/app/src/main/java/com/gh/base/GlobalActivityLifecycleObserver.kt +++ b/app/src/main/java/com/gh/base/GlobalActivityLifecycleObserver.kt @@ -15,6 +15,7 @@ import com.gh.gamecenter.forum.list.ForumListActivity import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity import com.gh.gamecenter.qa.questions.newdetail.NewQuestionDetailActivity import com.gh.gamecenter.qa.video.detail.ForumVideoDetailActivity +import com.gh.vspace.VHelper import com.halo.assistant.HaloApp // TODO:移动到对应的模块 @@ -59,6 +60,10 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks { if (PackageFlavorHelper.IS_TEST_FLAVOR && activity is AppCompatActivity) { NightModeSwitchHelper.showNightModeSwitchFloatingView(activity) } + + if (activity is AppCompatActivity) { + VHelper.showFeedbackDialogIfLastSuccessfulLaunchedGameExitUnexpectedly(activity) + } } private fun shouldShowActivityBackView(activity: Activity): Boolean { diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index da61f615f6..14af3c7c56 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -551,7 +551,7 @@ public class DownloadManager implements DownloadStatusListener { } /** - * 根据 url 获取下载任务 (仅保证下载状态一致) + * 根据 url 获取下载任务快照 (仅保证下载状态一致) * * @param url 下载链接 * @return null表示下载列表中不存在该任务,否则返回下载任务 @@ -562,6 +562,30 @@ public class DownloadManager implements DownloadStatusListener { return mDownloadDao.getSnapshot(url); } + /** + * 根据 url 获取下载任务快照 (仅保证下载状态一致) + * + * @param packageName 包名 (多包名一样时取第一个,若使用场景里有多包名,请使用 url 获取下载任务) + * @return null 表示下载列表中不存在该任务,否则返回下载任务 + */ + @Nullable + public DownloadEntity getDownloadEntitySnapshotByPackageName(String packageName) { + if (TextUtils.isEmpty(packageName)) return null; + return mDownloadDao.getSnapshotByPackageName(packageName); + } + + /** + * 根据 url 获取下载任务快照 (仅保证下载状态一致) + * + * @param gameId 游戏名 (若使用场景里有多包名,请使用 url 获取下载任务) + * @return null 表示下载列表中不存在该任务,否则返回下载任务 + */ + @Nullable + public DownloadEntity getDownloadEntitySnapshotByGameId(String gameId) { + if (TextUtils.isEmpty(gameId)) return null; + return mDownloadDao.getSnapshotByGameId(gameId); + } + /** * 根据包名获取某一个下载任务 (涉及数据库查询,请优先在子线程调用) * diff --git a/app/src/main/java/com/gh/gamecenter/entity/VSetting.kt b/app/src/main/java/com/gh/gamecenter/entity/VSetting.kt index c5df59740f..905ac2573d 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/VSetting.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/VSetting.kt @@ -9,6 +9,7 @@ class VSetting { data class Va( @SerializedName("32-bit") val arch32: VaArch? = null, + @SerializedName("64-bit") val arch64: VaArch? = null, ) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index f2ef038921..756abb675d 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -75,8 +75,6 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { loadStatus.postValue(LoadStatus.INIT_LOADING) initData() - - refreshRecentVGameIfNeeded() } fun initData() { @@ -92,6 +90,8 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { if (SPUtils.getBoolean(SettingsFragment.PERSONAL_RECOMMEND_SP_KEY, true)) { getSmartColumn() } + + refreshRecentVGameIfNeeded() } fun refreshRecentVGameIfNeeded() { diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index 236e8529a6..5496d8ec71 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -16,9 +16,11 @@ import com.gh.gamecenter.GameDetailActivity import com.gh.gamecenter.R import com.gh.gamecenter.adapter.viewholder.FooterViewHolder import com.gh.gamecenter.baselist.ListAdapter +import com.gh.gamecenter.baselist.LoadType import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.constant.ItemViewType import com.gh.gamecenter.common.utils.* +import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.core.utils.CurrentActivityHolder import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.databinding.PopupHistoryOptionBinding @@ -135,6 +137,10 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa "再等等", { val apk = gameEntity.getApk().firstOrNull() mViewModel.removeItem(apk?.url, apk?.packageName) + + AppExecutor.uiExecutor.executeWithDelay({ + mViewModel.load(LoadType.REFRESH) + }, 200) }) } } @@ -171,6 +177,10 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa mViewModel.removeItems(selectItems) selectItems.clear() checkSelectItems() + + AppExecutor.uiExecutor.executeWithDelay({ + mViewModel.load(LoadType.REFRESH) + }, 200) }, extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true) ) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index d569e17137..90bb4ad953 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -18,6 +18,7 @@ import com.gh.gamecenter.history.IBatchDelete import com.gh.gamecenter.history.ManageOption import com.lightgame.download.DataWatcher import com.lightgame.download.DownloadEntity +import com.lightgame.download.DownloadStatus class VDownloadManagerFragment : ListFragment(), IBatchDelete { @@ -34,6 +35,10 @@ class VDownloadManagerFragment : private val dataWatcher: DataWatcher = object : DataWatcher() { override fun onDataChanged(downloadEntity: DownloadEntity) { mAdapter.notifyItemByDownload(downloadEntity) + + if (downloadEntity.status == DownloadStatus.done) { + onLoadRefresh() + } } } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index 4177c93609..2e25eee87f 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -3,7 +3,6 @@ package com.gh.vspace import android.app.Application import com.gh.download.DownloadManager import com.gh.gamecenter.baselist.ListViewModel -import com.gh.gamecenter.baselist.LoadType import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.packagehelper.PackageRepository import com.lightgame.download.DownloadStatus @@ -70,8 +69,6 @@ class VDownloadManagerViewModel(application: Application) : fun removeItem(url: String?, packageName: String?) { DownloadManager.getInstance().cancel(url) VHelper.uninstall(packageName ?: "") - - load(LoadType.REFRESH) } fun removeItems(idList: ArrayList) { @@ -80,8 +77,6 @@ class VDownloadManagerViewModel(application: Application) : DownloadManager.getInstance().cancel(apkEntity?.url) VHelper.uninstall(apkEntity?.packageName) } - - load(LoadType.REFRESH) } companion object { diff --git a/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt b/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt index 1f359a7bec..9428676275 100644 --- a/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt +++ b/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt @@ -108,7 +108,7 @@ class VFeedbackDialogFragment : BaseDialogFragment() { private fun updateSubmitButton() { val isTagSelected = mTagList?.any { it.checked } ?: false - if (mBinding.feedbackEt.text.count() != 0 || isTagSelected) { + if (mBinding.feedbackEt.text.isNotEmpty() || isTagSelected) { mBinding.submitTv.isEnabled = true mBinding.submitTv.alpha = 1F } else { diff --git a/app/src/main/java/com/gh/vspace/VFeedbackSuppressedSimpleDao.kt b/app/src/main/java/com/gh/vspace/VFeedbackSuppressedSimpleDao.kt index fdede504b8..c175e20618 100644 --- a/app/src/main/java/com/gh/vspace/VFeedbackSuppressedSimpleDao.kt +++ b/app/src/main/java/com/gh/vspace/VFeedbackSuppressedSimpleDao.kt @@ -2,7 +2,7 @@ package com.gh.vspace import com.gh.gamecenter.common.base.BaseSimpleDao -class VFeedbackSuppressedSimpleDao: BaseSimpleDao() { +class VFeedbackSuppressedSimpleDao : BaseSimpleDao() { override fun getSPKey(): String { return "v_feedback_suppressed" diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 2ea588fb71..e76ff35c00 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -4,7 +4,9 @@ import android.Manifest import android.app.Activity import android.content.Context import android.content.Intent +import android.net.Uri import android.text.TextUtils +import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import com.gh.common.constant.Config @@ -12,12 +14,11 @@ import com.gh.common.util.PackageUtils import com.gh.download.DownloadManager import com.gh.download.PackageObserver import com.gh.gamecenter.R -import com.gh.gamecenter.common.utils.DialogHelper -import com.gh.gamecenter.common.utils.addMetaExtra -import com.gh.gamecenter.common.utils.getMetaExtra -import com.gh.gamecenter.common.utils.toColor +import com.gh.gamecenter.SplashScreenActivity +import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.core.runOnIoThread +import com.gh.gamecenter.core.runOnUiThread import com.gh.gamecenter.core.utils.EmptyCallback import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.entity.ApkEntity @@ -25,6 +26,7 @@ import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.eventbus.EBPackage import com.gh.gamecenter.eventbus.EBReuse import com.gh.gamecenter.packagehelper.PackageRepository +import com.halo.assistant.HaloApp import com.lg.vspace.VirtualAppManager import com.lg.vspace.remote.listener.RemoteConnectListener import com.lg.vspace.remote.model.AppInstallerInfo @@ -42,7 +44,10 @@ object VHelper { private val mDelegateManager by lazy { VirtualAppManager.get() } private var mInstalledInfoList: List = arrayListOf() private val mInstallationLiveData by lazy { MutableLiveData() } - private var mInstalledEntitySnapshotList: ArrayList? = null // 畅玩游戏的列表快照,不保证完全即时,但获取信息应该够用了 + private var mLastSuccessfullyLaunchedGame: Pair? = null + + // 畅玩游戏的列表快照,不保证完全即时,但获取信息应该够用了 + private var mInstalledEntitySnapshotList: ArrayList? = null private val mPackageObserver by lazy { PackageObserver.PackageChangeListener { val vaConfig = Config.getVSettingEntity()?.va ?: return@PackageChangeListener @@ -53,7 +58,9 @@ object VHelper { if (it.type == "安装") { // 即时调用大概率调不起来,我也不知道为什么,只能延迟大法了 - AppExecutor.uiExecutor.executeWithDelay({ connectService() }, 500) + AppExecutor.uiExecutor.executeWithDelay({ + connectService() + }, 500) } else if (it.type == "卸载") { // TODO 执行卸载逻辑 } @@ -64,7 +71,7 @@ object VHelper { fun init(context: Context) { val config = Config.getVSettingEntity()?.va if (config != null - && PackageUtils.isInstalled(context, config.arch32?.packageName) + && PackageUtils.isInstalled(context, config.arch64?.packageName) ) { connectService() } @@ -75,6 +82,8 @@ object VHelper { * 连接服务 */ private fun connectService(callbackClosure: (() -> Unit)? = null) { + invokeVSpace() + mDelegateManager.connectService(object : RemoteConnectListener { override fun onServiceConnectionSuccessed() { Utils.log(LOG_TAG, "V 服务连接成功") @@ -94,6 +103,14 @@ object VHelper { }) } + private fun invokeVSpace() { + tryWithDefaultCatch { + val intent = Intent(Intent.ACTION_VIEW, Uri.parse("vsserver://invoke_only")) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + HaloApp.getInstance().startActivity(intent) + } + } + private fun updateInstalledList() { mInstalledInfoList = try { mDelegateManager.installedGamesInfo @@ -125,6 +142,25 @@ object VHelper { } } + /**** + * 启动成功,五秒内退出才显示反馈弹框 + */ + fun showFeedbackDialogIfLastSuccessfulLaunchedGameExitUnexpectedly(activity: AppCompatActivity) { + val timeOfLastSuccessfullyLaunchedGame = mLastSuccessfullyLaunchedGame?.first + val gameIdOfLastSuccessfullyLaunchedGame = mLastSuccessfullyLaunchedGame?.second + if (activity !is SplashScreenActivity) { + if (timeOfLastSuccessfullyLaunchedGame != null + && gameIdOfLastSuccessfullyLaunchedGame != null + && System.currentTimeMillis() - timeOfLastSuccessfullyLaunchedGame < 5000 + && !VFeedbackSuppressedSimpleDao().contains(gameIdOfLastSuccessfullyLaunchedGame) + ) { + DownloadManager.getInstance().getDownloadEntitySnapshotByGameId(gameIdOfLastSuccessfullyLaunchedGame)?.let { + VFeedbackDialogFragment.show(activity, toGameEntity(it)) + } + } + } + } + /** * 在执行 callback 前先检查组件是否已安装,是否可下载 */ @@ -134,11 +170,11 @@ object VHelper { if (showDialogIfVSpaceIsNeeded(context)) { return } - val vaConfig32 = Config.getVSettingEntity()?.va?.arch32 + val vaConfig64 = Config.getVSettingEntity()?.va?.arch64 // 检查更新 val containsUpdate = - vaConfig32?.versionCode ?: 0 > PackageUtils.getVersionCodeByPackageName(vaConfig32?.packageName) + vaConfig64?.versionCode ?: 0 > PackageUtils.getVersionCodeByPackageName(vaConfig64?.packageName) if (containsUpdate) { // 触发更新弹窗 @@ -241,22 +277,28 @@ object VHelper { checkStoragePermissionBeforeAction(activity) { // 安装过程会比较漫长,所以得放在工作线程运行 AppExecutor.ioExecutor.execute { - val result = VirtualAppManager.get().installGame(filePath) - if (result.status == 0) { - updateVGameSnapshot() - updateInstalledList() - showFloatingWindow(result.packageName) - PackageObserver.onPackageChanged( - EBPackage( - "安装", - result.packageName, - "unknown" + try { + val result = VirtualAppManager.get().installGame(filePath) + if (result.status == 0) { + updateVGameSnapshot() + updateInstalledList() + showFloatingWindow(result.packageName) + PackageObserver.onPackageChanged( + EBPackage( + "安装", + result.packageName, + "unknown" + ) ) - ) - } + } - mInstallationLiveData.postValue(result.packageName) - Utils.log(LOG_TAG, "安装新应用结果 -> " + result.status) + mInstallationLiveData.postValue(result.packageName) + Utils.log(LOG_TAG, "安装新应用结果 -> " + result.status) + } catch (e: Exception) { + runOnUiThread { + ToastUtils.toast(e.localizedMessage ?: "") + } + } } } } @@ -275,6 +317,10 @@ object VHelper { fun launch(context: Context, packageName: String) { Utils.log(LOG_TAG, "打开应用$packageName") + DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName)?.let { + mLastSuccessfullyLaunchedGame = Pair(System.currentTimeMillis(), it.gameId) + } + if (showDialogIfVSpaceIsNeeded(context)) { return } @@ -342,7 +388,8 @@ object VHelper { */ private fun updateLastPlayedTime(packageName: String) { runOnIoThread { - val entity = DownloadManager.getInstance().allVDownloadTask.find { it.packageName == packageName } + val entity = + DownloadManager.getInstance().allVDownloadTask.find { it.packageName == packageName } entity?.addMetaExtra(KEY_LAST_PLAYED_TIME, System.currentTimeMillis().toString()) DownloadManager.getInstance().updateDownloadEntity(entity) @@ -373,8 +420,8 @@ object VHelper { private fun showDialogIfVSpaceIsNeeded(context: Context): Boolean { val vaConfig = Config.getVSettingEntity()?.va ?: return true - // TODO 检测 64 位 - if (!PackageUtils.isInstalled(context, vaConfig.arch32?.packageName)) { + // TODO 检测 32 位 + if (!PackageUtils.isInstalled(context, vaConfig.arch64?.packageName)) { VSpaceDialogFragment.showDownloadDialog(context) return true } diff --git a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt index 284bfbb234..ff39040337 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt @@ -35,7 +35,7 @@ import com.lightgame.utils.AppManager class VSpaceDialogFragment : BaseDraggableDialogFragment() { - private val mDownloadUrl by lazy { Config.getVSettingEntity()?.va?.arch32?.url } // TODO 支持 64 位地址 + private val mDownloadUrl by lazy { Config.getVSettingEntity()?.va?.arch64?.url } // TODO 支持 32 位地址 private val mBinding by lazy { DialogVspaceBinding.inflate(layoutInflater) } private val mDataWatcher = object : DataWatcher() { override fun onDataChanged(downloadEntity: DownloadEntity) { diff --git a/vspace-bridge b/vspace-bridge index 26d0e88ae6..b8f5b2e7b4 160000 --- a/vspace-bridge +++ b/vspace-bridge @@ -1 +1 @@ -Subproject commit 26d0e88ae675a5bcc1ffa1eae1efd1f666d28432 +Subproject commit b8f5b2e7b42cf6af0da8b696556a003cd9b1845e From 90e947b65d7599f407d9ed64c390e34147c89a78 Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 9 Jun 2022 14:52:14 +0800 Subject: [PATCH 026/217] =?UTF-8?q?fix:=20=E6=B8=B8=E6=88=8F=E5=88=97?= =?UTF-8?q?=E8=A1=A8=20item=20=E6=A0=B7=E5=BC=8F=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/util/DownloadItemUtils.kt | 28 +++++++++---------- .../download/InstalledGameViewModel.kt | 7 +++-- .../gh/vspace/VDownloadManagerViewModel.kt | 9 ------ 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index 199154b3d6..db3595fc5b 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -239,15 +239,9 @@ object DownloadItemUtils { setBackgroundResource(R.drawable.button_round_border_eeeeee) setTextColor(ContextCompat.getColorStateList(context, R.color.text_subtitleDesc)) } else if (status == DownloadStatus.pause || status == DownloadStatus.timeout || status == DownloadStatus.neterror || status == DownloadStatus.subscribe || status == DownloadStatus.overflow) { - if (status == DownloadStatus.waiting) { - setText(R.string.waiting) - setBackgroundResource(R.drawable.button_round_border_eeeeee) - setTextColor(ContextCompat.getColorStateList(context, R.color.text_subtitleDesc)) - } else { - setText(R.string.downloading) - setBackgroundResource(R.drawable.game_item_btn_downloading_style) - setTextColor(ContextCompat.getColorStateList(context, R.color.text_downloading_style)) - } + setText(R.string.downloading) + setBackgroundResource(R.drawable.game_item_btn_downloading_style) + setTextColor(ContextCompat.getColorStateList(context, R.color.text_downloading_style)) } else if (status == DownloadStatus.done) { val xapkStatus = downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS] if (XapkUnzipStatus.UNZIPPING.name == xapkStatus) { @@ -256,6 +250,8 @@ object DownloadItemUtils { } if (downloadEntity.isSimulatorGame() && gameEntity.simulator != null) { GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, pluginLocation) + } else if (downloadEntity.isSmoothGame()) { + setText(R.string.launch) } else { setText(R.string.install) } @@ -330,10 +326,14 @@ object DownloadItemUtils { context: Context, holder: GameViewHolder, downloadEntity: DownloadEntity, isShowPlatform: Boolean, isNormal: Boolean, isShowRecommendStar: Boolean = false ) { - updateItemViewStatus(holder, true, null, null, isShowRecommendStar) - holder.gameProgressbar.progressDrawable = R.drawable.progressbar_bg_style.toDrawable() - val platform = PlatformUtils.getInstance(context).getPlatformName(downloadEntity.platform) val status = downloadEntity.status + // 畅玩游戏下载完成时不再需要显示进度条 + val shouldShowDownload = !(downloadEntity.isSmoothGame() && status == DownloadStatus.done) + val platform = PlatformUtils.getInstance(context).getPlatformName(downloadEntity.platform) + + updateItemViewStatus(holder, shouldShowDownload, null, null, isShowRecommendStar) + holder.gameProgressbar.progressDrawable = R.drawable.progressbar_bg_style.toDrawable() + if (status == DownloadStatus.downloading) { if (DownloadStatus.pause != DownloadManager.getInstance().getStatus(downloadEntity.url)) { holder.gameProgressbar.progress = (downloadEntity.percent * 10).toInt() @@ -389,12 +389,12 @@ object DownloadItemUtils { private fun updateItemViewStatus( holder: GameViewHolder, - hasDownload: Boolean, + showDownload: Boolean, briefStyle: String?, recommendStyle: LinkEntity?, isShowRecommendStar: Boolean = false ) { - if (hasDownload) { + if (showDownload) { if (holder.gameRating != null) holder.gameRating!!.visibility = View.GONE holder.gameDes.visibility = View.GONE holder.gameProgressbar.visibility = View.VISIBLE diff --git a/app/src/main/java/com/gh/gamecenter/download/InstalledGameViewModel.kt b/app/src/main/java/com/gh/gamecenter/download/InstalledGameViewModel.kt index 48a52632df..8e3738f2c0 100644 --- a/app/src/main/java/com/gh/gamecenter/download/InstalledGameViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/download/InstalledGameViewModel.kt @@ -9,12 +9,12 @@ import com.gh.common.filter.RegionSettingHelper.shouldThisGameBeFiltered import com.gh.common.util.ApkActiveUtils import com.gh.common.util.GameUtils import com.gh.common.util.PackageUtils -import com.gh.gamecenter.core.utils.ThirdPartyPackageHelper.getGameId import com.gh.download.DownloadManager +import com.gh.gamecenter.common.retrofit.Response +import com.gh.gamecenter.core.utils.ThirdPartyPackageHelper.getGameId import com.gh.gamecenter.entity.ApkEntity import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.entity.GameInstall -import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.retrofit.RetrofitManager import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers @@ -35,6 +35,9 @@ class InstalledGameViewModel(application: Application) : AndroidViewModel(applic list.add(GameInstall(id = entity.gameId)) } for (gameInstall in list) { + // 畅玩游戏不出现在常规的下载管理里 + if (gameInstall.isSmoothGame) continue + val ghId = PackageUtils.getMetaData(getApplication(), gameInstall.packageName, "gh_id") if (ghId != null && ghId != gameInstall.id) { gameInstall.id = ghId.toString() diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index 2e25eee87f..f953ff9298 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -4,7 +4,6 @@ import android.app.Application import com.gh.download.DownloadManager import com.gh.gamecenter.baselist.ListViewModel import com.gh.gamecenter.entity.GameEntity -import com.gh.gamecenter.packagehelper.PackageRepository import com.lightgame.download.DownloadStatus import io.reactivex.Observable import io.reactivex.Single @@ -25,8 +24,6 @@ class VDownloadManagerViewModel(application: Application) : override fun provideDataSingle(page: Int): Single> { if (type == TYPE_DOWNLOADED) { return Single.create { emitter -> - val installedGameList = - PackageRepository.installedGameListLiveData.value ?: arrayListOf() val vDownloadList = DownloadManager.getInstance().allVDownloadTask val gameIdSet = hashSetOf() // 游戏 id set,避免下载任务和已安装任务同时出现 @@ -39,12 +36,6 @@ class VDownloadManagerViewModel(application: Application) : } } - for (game in installedGameList) { - if (game.isVGame() && !gameIdSet.contains(game.id)) { - vGameList.add(game) - } - } - emitter.onSuccess(vGameList) } } else { From 1eeec1c89b773c8693582ef15cf97a7e1d1b13fe Mon Sep 17 00:00:00 2001 From: juntao Date: Fri, 10 Jun 2022 17:21:56 +0800 Subject: [PATCH 027/217] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E6=B8=B8=E6=88=8F=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/util/DownloadItemUtils.kt | 21 +++-- .../java/com/gh/common/util/GameUtils.java | 6 +- .../java/com/gh/common/util/PackageUtils.java | 10 ++- .../java/com/gh/download/DownloadManager.java | 15 +++- .../java/com/gh/download/PackageObserver.kt | 7 +- .../com/gh/gamecenter/entity/GameEntity.kt | 3 + .../com/gh/gamecenter/home/HomeViewModel.kt | 2 +- .../packagehelper/PackageRepository.kt | 4 +- .../gh/vspace/HomeRecentVGameViewHolder.kt | 25 +++++- .../com/gh/vspace/VDownloadManagerAdapter.kt | 16 ++-- .../gh/vspace/VDownloadManagerViewModel.kt | 4 +- app/src/main/java/com/gh/vspace/VHelper.kt | 81 ++++++++++++++----- .../com/gh/vspace/VSpaceLoadingFragment.kt | 4 +- 13 files changed, 145 insertions(+), 53 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index db3595fc5b..07ef630aae 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -1,7 +1,6 @@ package com.gh.common.util import android.content.Context -import android.content.Intent import android.graphics.Color import android.os.Message import android.text.TextUtils @@ -251,7 +250,11 @@ object DownloadItemUtils { if (downloadEntity.isSimulatorGame() && gameEntity.simulator != null) { GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, pluginLocation) } else if (downloadEntity.isSmoothGame()) { - setText(R.string.launch) + if (PackagesManager.isCanUpdate(downloadEntity.gameId, downloadEntity.packageName)) { + setText(R.string.update) + } else { + setText(R.string.launch) + } } else { setText(R.string.install) } @@ -758,7 +761,7 @@ object DownloadItemUtils { } if (gameEntity.isVGame()) { - VHelper.launch((context as AppCompatActivity), gameEntity.getApk()[0].packageName) + VHelper.launch((context as AppCompatActivity), gameEntity.getUniquePackageName() ?: "") return } @@ -770,6 +773,14 @@ object DownloadItemUtils { if (entrance.contains("我的游戏")) { MtaHelper.onEvent("我的游戏_启动", "更新", gameEntity.name) } + if (gameEntity.isVGame()) { + PackagesManager.getUpdateList().firstOrNull { it.id == gameEntity.id }?.let { updateEntity -> + VHelper.getDownloadEntitySnapshotByPackageName(gameEntity.getUniquePackageName() ?: "")?.let { downloadEntity -> + VHelper.update(downloadEntity, updateEntity) + } + } + return + } DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, object : EmptyCallback { override fun onCallback() { DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> @@ -779,9 +790,7 @@ object DownloadItemUtils { }) } else { if (gameEntity.isVGame()) { - context.startActivity( - Intent(context, VDownloadManagerActivity::class.java) - ) + context.startActivity(VDownloadManagerActivity.getIntent(context, true)) } else { context.startActivity( DownloadManagerActivity.getDownloadMangerIntent( diff --git a/app/src/main/java/com/gh/common/util/GameUtils.java b/app/src/main/java/com/gh/common/util/GameUtils.java index 8c44b8b309..ec0c604f56 100644 --- a/app/src/main/java/com/gh/common/util/GameUtils.java +++ b/app/src/main/java/com/gh/common/util/GameUtils.java @@ -173,7 +173,11 @@ public class GameUtils { } else if ("demo".equals(gameEntity.getDownloadStatus())) { return context.getString(R.string.attempt); } else { - return context.getString(R.string.download); + if (gameEntity.isVGame()) { + return context.getString(R.string.smooth); + } else { + return context.getString(R.string.download); + } } } diff --git a/app/src/main/java/com/gh/common/util/PackageUtils.java b/app/src/main/java/com/gh/common/util/PackageUtils.java index 24e6114bae..4cac0e49b5 100644 --- a/app/src/main/java/com/gh/common/util/PackageUtils.java +++ b/app/src/main/java/com/gh/common/util/PackageUtils.java @@ -31,7 +31,6 @@ import com.gh.gamecenter.entity.ApkEntity; import com.gh.gamecenter.entity.GameEntity; import com.gh.gamecenter.entity.GameUpdateEntity; import com.gh.gamecenter.manager.PackagesManager; -import com.gh.vspace.VHelper; import com.halo.assistant.HaloApp; import com.lightgame.download.DownloadEntity; import com.lightgame.utils.Utils; @@ -112,20 +111,23 @@ public class PackageUtils { // 是否需要显示更新 boolean shouldShowUpdate = apkEntity.getForce(); + // 普通游戏根据本地是否有安装来确定是否 qualified,畅玩游戏直接进判断 + boolean isUpdateQualified = + gameEntity.isVGame() || (!TextUtils.isEmpty(versionFromRequest) && !TextUtils.isEmpty(versionFromInstalledApp)); - if (shouldShowUpdate && !TextUtils.isEmpty(versionFromRequest) && !TextUtils.isEmpty(versionFromInstalledApp)) { + if (shouldShowUpdate && isUpdateQualified) { // 根据版本判断是否需要更新 shouldShowUpdate = new Version(versionFromRequest).isHigherThan(versionFromInstalledApp); // 畅玩游戏根据 md5 是否一致确定是否需要更新 if (gameEntity.isVGame()) { - DownloadEntity entity = VHelper.getVGameSnapshot(apkEntity.getPackageName()); + DownloadEntity entity = DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(apkEntity.getPackageName()); if (entity != null) { String md5FromInstalledVGame = ExtensionsKt.getMetaExtra(entity, Constants.APK_MD5); String md5FromRequest = apkEntity.getMd5(); - if (md5FromRequest!= null && md5FromRequest.equals(md5FromInstalledVGame)) { + if (md5FromRequest != null && !md5FromRequest.equals(md5FromInstalledVGame)) { shouldShowUpdate = true; } } diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index 14af3c7c56..6d03bb3bf8 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -46,7 +46,6 @@ import com.gh.gamecenter.eventbus.EBDownloadStatus; import com.gh.gamecenter.manager.PackagesManager; import com.gh.gamecenter.manager.UserManager; import com.gh.gamecenter.packagehelper.PackageRepository; -import com.gh.vspace.VHelper; import com.halo.assistant.HaloApp; import com.lightgame.download.ConnectionUtils; import com.lightgame.download.DataChanger; @@ -550,6 +549,16 @@ public class DownloadManager implements DownloadStatusListener { return mDownloadDao.get(url); } + /** + * 获取所有的下载任务快照 + * + * @return 下载任务快照列表 + */ + @NonNull + private ArrayList getAllDownloadEntitySnapshots() { + return mDownloadDao.getAllSnapshots(); + } + /** * 根据 url 获取下载任务快照 (仅保证下载状态一致) * @@ -677,8 +686,8 @@ public class DownloadManager implements DownloadStatusListener { /** * 获取下载列表中的畅玩下载任务 */ - public ArrayList getAllVDownloadTask() { - List downloadList = getAllDownloadEntity(); + public ArrayList getAllVDownloadTaskSnapshots() { + List downloadList = getAllDownloadEntitySnapshots(); ArrayList filteredDownloadEntityList = new ArrayList<>(); diff --git a/app/src/main/java/com/gh/download/PackageObserver.kt b/app/src/main/java/com/gh/download/PackageObserver.kt index 8a14508216..b6d515980d 100644 --- a/app/src/main/java/com/gh/download/PackageObserver.kt +++ b/app/src/main/java/com/gh/download/PackageObserver.kt @@ -25,6 +25,7 @@ import com.gh.gamecenter.retrofit.RetrofitManager import com.gh.gamecenter.setting.GameDownloadSettingFragment.Companion.CONCERN_GAME_SP_KEY import com.halo.assistant.HaloApp import com.lightgame.download.DownloadEntity +import com.lightgame.download.FileUtils import com.lightgame.utils.Utils import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers @@ -98,9 +99,11 @@ object PackageObserver { if (gh_id == null) { ThirdPartyPackageHelper.saveGameId(mDownloadEntity.packageName, mDownloadEntity.gameId) } - if (mDownloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) != Constants.SMOOTH_GAME) { + if (mDownloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) == Constants.SMOOTH_GAME) { + // 畅玩游戏安装完成的同时直接删除文件 + runOnIoThread { FileUtils.deleteFile(mDownloadEntity.path) } + } else { DownloadManager.getInstance().cancel(mDownloadEntity.url, false, true) - // 默认不删除安装包 mSp.getBoolean("autodelete", true) } } if (sp.getBoolean(CONCERN_GAME_SP_KEY, true)) { //设置页面控制是否安装后自动关注 diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt index 9bae2be111..dd558324db 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt @@ -483,6 +483,9 @@ data class GameEntity( return apk!! } + /** + * 获取唯一的包名,仅单版本游戏有效,多版本的游戏请不要调用 + */ fun getUniquePackageName(): String? { return getApk().firstOrNull()?.packageName } diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index 756abb675d..a8d7bb6c63 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -127,7 +127,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { * 完成下载且已启动过的游戏:按照游戏的畅玩时长从左(长)向右(短)排列 */ private fun getSortedVEntityList() : List { - val rawEntityList = DownloadManager.getInstance().allVDownloadTask + val rawEntityList = DownloadManager.getInstance().allVDownloadTaskSnapshots var fixedTopEntity: DownloadEntity? = null val unplayedEntityList = arrayListOf() val playedEntityList = arrayListOf() diff --git a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt index 20786987f0..90f9847d26 100644 --- a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt +++ b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt @@ -370,12 +370,12 @@ object PackageRepository { * 批量新增已安装的游戏数量 * @param pkgNameList 数组列表 */ - fun addInstalledGames(pkgNameList: ArrayList) { + fun addInstalledGames(pkgNameList: ArrayList, isVGameOnly: Boolean = false) { mInstalledPkgList.addAll(pkgNameList) notifyInstallPkgData() updateFilterPackage(pkgNameList) { - loadInstalledGameDigestAndNotifyData(pkgNameList, true) + loadInstalledGameDigestAndNotifyData(pkgNameList, true, isVGameOnly) } } diff --git a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt index 78726f1e0f..7f215aa74a 100644 --- a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt +++ b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt @@ -17,6 +17,7 @@ import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.databinding.ItemHomeRecentVgameBinding import com.gh.gamecenter.databinding.ItemHomeVgameBinding import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.manager.PackagesManager import com.lightgame.download.DownloadEntity import com.lightgame.download.DownloadStatus @@ -82,7 +83,7 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter(con mBinding.gameIconIv.setTag(R.string.app_name, gameEntity.id) } runOnIoThread(true) { - val downloadEntity = DownloadManager.getInstance().allVDownloadTask.find { + val downloadEntity = DownloadManager.getInstance().allVDownloadTaskSnapshots.find { it.gameId == gameEntity.id } @@ -106,6 +107,15 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter(con var shouldShowDot = false var controlText = "继续" + if (downloadEntity.status == DownloadStatus.done + && VHelper.getLastPlayedTime(downloadEntity) == 0L) { + shouldShowDot = true + } + + if (PackagesManager.isCanUpdate(downloadEntity.gameId, downloadEntity.packageName)) { + shouldShowUpdate = true + } + when (downloadEntity.status) { DownloadStatus.done -> { binding.root.setOnClickListener { @@ -157,11 +167,18 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter(con mBinding.maskView.goneIf(!shouldShowMask) mBinding.controlTv.goneIf(!shouldShowControlTv) mBinding.progressBar.goneIf(!shouldShowProgressBar) + mBinding.dotView.goneIf(!shouldShowDot) + mBinding.updateHintIv.goneIf(!shouldShowUpdate) + + if (shouldShowUpdate) { + binding.root.setOnClickListener { + PackagesManager.getUpdateList().firstOrNull { it.id == downloadEntity.gameId }?.let { + VHelper.update(downloadEntity, it) + } + } + } mBinding.controlTv.text = controlText mBinding.progressBar.progress = downloadEntity.percent.toInt() } } } - - - diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index 5496d8ec71..601f7fc11d 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -28,6 +28,8 @@ import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.entity.PluginLocation import com.gh.gamecenter.game.GameItemViewHolder import com.gh.gamecenter.history.ManageOption +import com.gh.gamecenter.manager.PackagesManager +import com.gh.gamecenter.manager.PackagesManager.isCanUpdate import com.lightgame.download.DownloadEntity import com.lightgame.download.DownloadStatus import com.lightgame.utils.Utils @@ -258,13 +260,17 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa DownloadManager.getInstance().resume(downloadEntity, true) } } else if (status == DownloadStatus.done) { - if (downloadEntity.isSmoothGame()) { - GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, PluginLocation.only_index) - } + GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, PluginLocation.only_index) setOnClickListener { - CurrentActivityHolder.getCurrentActivity()?.let { - VHelper.launch(it, downloadEntity.packageName) + if (isCanUpdate(gameEntity.id, gameEntity.getApk().firstOrNull()?.packageName)) { + PackagesManager.getUpdateList().firstOrNull { it.id == downloadEntity.gameId }?.let { + VHelper.update(downloadEntity, it) + } + } else { + CurrentActivityHolder.getCurrentActivity()?.let { + VHelper.launch(it, downloadEntity.packageName) + } } } } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index f953ff9298..f168f810a6 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -24,7 +24,7 @@ class VDownloadManagerViewModel(application: Application) : override fun provideDataSingle(page: Int): Single> { if (type == TYPE_DOWNLOADED) { return Single.create { emitter -> - val vDownloadList = DownloadManager.getInstance().allVDownloadTask + val vDownloadList = DownloadManager.getInstance().allVDownloadTaskSnapshots val gameIdSet = hashSetOf() // 游戏 id set,避免下载任务和已安装任务同时出现 val vGameList = arrayListOf() @@ -40,7 +40,7 @@ class VDownloadManagerViewModel(application: Application) : } } else { return Single.create { emitter -> - val vDownloadList = DownloadManager.getInstance().allVDownloadTask + val vDownloadList = DownloadManager.getInstance().allVDownloadTaskSnapshots val gameIdSet = hashSetOf() // 游戏 id set,避免下载任务和已安装任务同时出现 val vGameList = arrayListOf() diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index e76ff35c00..c0f72c84ae 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -10,19 +10,25 @@ import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import com.gh.common.constant.Config +import com.gh.common.exposure.ExposureUtils +import com.gh.common.history.HistoryHelper +import com.gh.common.util.DataCollectionUtils import com.gh.common.util.PackageUtils import com.gh.download.DownloadManager import com.gh.download.PackageObserver import com.gh.gamecenter.R import com.gh.gamecenter.SplashScreenActivity +import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.core.runOnUiThread import com.gh.gamecenter.core.utils.EmptyCallback +import com.gh.gamecenter.core.utils.GsonUtils import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.entity.ApkEntity import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.entity.GameUpdateEntity import com.gh.gamecenter.eventbus.EBPackage import com.gh.gamecenter.eventbus.EBReuse import com.gh.gamecenter.packagehelper.PackageRepository @@ -46,8 +52,6 @@ object VHelper { private val mInstallationLiveData by lazy { MutableLiveData() } private var mLastSuccessfullyLaunchedGame: Pair? = null - // 畅玩游戏的列表快照,不保证完全即时,但获取信息应该够用了 - private var mInstalledEntitySnapshotList: ArrayList? = null private val mPackageObserver by lazy { PackageObserver.PackageChangeListener { val vaConfig = Config.getVSettingEntity()?.va ?: return@PackageChangeListener @@ -89,9 +93,7 @@ object VHelper { Utils.log(LOG_TAG, "V 服务连接成功") mInstalledInfoList = getInstalledList() - updateVGameSnapshot() - - PackageRepository.addInstalledGames(getInstalledPackageList()) + PackageRepository.addInstalledGames(getInstalledPackageList(), true) callbackClosure?.invoke() } @@ -156,6 +158,7 @@ object VHelper { ) { DownloadManager.getInstance().getDownloadEntitySnapshotByGameId(gameIdOfLastSuccessfullyLaunchedGame)?.let { VFeedbackDialogFragment.show(activity, toGameEntity(it)) + mLastSuccessfullyLaunchedGame = null } } } @@ -280,7 +283,6 @@ object VHelper { try { val result = VirtualAppManager.get().installGame(filePath) if (result.status == 0) { - updateVGameSnapshot() updateInstalledList() showFloatingWindow(result.packageName) PackageObserver.onPackageChanged( @@ -352,7 +354,6 @@ object VHelper { try { val result = VirtualAppManager.get().uninstallGame(packageName) if (result) { - updateVGameSnapshot() updateInstalledList() PackageObserver.onPackageChanged(EBPackage("卸载", packageName, "unknown")) } @@ -383,13 +384,20 @@ object VHelper { } } + /** + * 根据包名获取 `下载实例` + */ + fun getDownloadEntitySnapshotByPackageName(packageName: String): DownloadEntity? { + return DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName) + } + /** * 更新游戏最后打开的时间 */ private fun updateLastPlayedTime(packageName: String) { runOnIoThread { val entity = - DownloadManager.getInstance().allVDownloadTask.find { it.packageName == packageName } + DownloadManager.getInstance().allVDownloadTaskSnapshots.find { it.packageName == packageName } entity?.addMetaExtra(KEY_LAST_PLAYED_TIME, System.currentTimeMillis().toString()) DownloadManager.getInstance().updateDownloadEntity(entity) @@ -403,7 +411,7 @@ object VHelper { } private fun showFloatingWindow(packageName: String) { - val vDownloadList = DownloadManager.getInstance().allVDownloadTask + val vDownloadList = DownloadManager.getInstance().allVDownloadTaskSnapshots vDownloadList.firstOrNull { it.packageName == packageName }?.let { @@ -429,20 +437,51 @@ object VHelper { return false } - private fun updateVGameSnapshot() { - runOnIoThread { - mInstalledEntitySnapshotList = ArrayList(DownloadManager.getInstance().allVDownloadTask) - } - } - /** - * 获取数据库中已安装的畅玩游戏的快照 + * 执行单个更新 + * + * @param originDownloadEntity 旧的下载实体 + * @param update 更新内容 */ - @JvmStatic - fun getVGameSnapshot(packageName: String): DownloadEntity? { - return mInstalledEntitySnapshotList?.firstOrNull { - it.packageName == packageName - } + fun update(originDownloadEntity: DownloadEntity, update: GameUpdateEntity) { + Utils.log(LOG_TAG, "更新应用${originDownloadEntity.packageName}") + + DownloadManager.getInstance().cancel(originDownloadEntity.url) + + originDownloadEntity.url = update.url + originDownloadEntity.name = update.name + originDownloadEntity.eTag = update.etag + originDownloadEntity.icon = update.icon + originDownloadEntity.platform = update.platform + originDownloadEntity.packageName = update.packageName + originDownloadEntity.versionName = update.version + originDownloadEntity.addMetaExtra(Constants.RAW_GAME_ICON, update.rawIcon) + originDownloadEntity.addMetaExtra(Constants.GAME_ICON_SUBSCRIPT, update.iconSubscript) + originDownloadEntity.addMetaExtra(Constants.APK_MD5, update.md5) + originDownloadEntity.isUpdate = true + originDownloadEntity.progress = 0 + originDownloadEntity.finalRedirectedUrl = "" + originDownloadEntity.percent = 0.0 + + // 确定下载类型 + val downloadType = ExposureUtils.DownloadType.UPDATE + val gameEntity = GameEntity(update.id, update.name) + gameEntity.gameVersion = update.version ?: "" + + val event = ExposureUtils.logADownloadExposureEvent( + gameEntity, + update.platform, + update.exposureEvent, + downloadType + ) + + originDownloadEntity.exposureTrace = GsonUtils.toJson(event) + + HistoryHelper.insertGameEntity(update) + DownloadManager.getInstance().add(originDownloadEntity) + + // 收集下载数据 + DataCollectionUtils.uploadDownload(HaloApp.getInstance(), originDownloadEntity, "开始") } fun toGameEntity(downloadEntity: DownloadEntity): GameEntity { diff --git a/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt index f0a498df98..bf5b32d1d6 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt @@ -47,11 +47,11 @@ class VSpaceLoadingFragment : BaseFragment() { neterror, overflow -> requireActivity().finish() unqualified -> { - ToastUtils.toast("该游戏未接入防沉迷系统,暂不支持下载") + ToastUtils.toast("暂不支持未成年人下载") requireActivity().finish() } uncertificated -> { - ToastUtils.toast("该游戏未接入防沉迷系统,暂不支持下载") + ToastUtils.toast("未实名,暂不支持下载") requireActivity().finish() } unavailable -> { From e59e1c1e65800fa38daf60dade6ba412ac1e29bd Mon Sep 17 00:00:00 2001 From: juntao Date: Mon, 13 Jun 2022 11:09:33 +0800 Subject: [PATCH 028/217] =?UTF-8?q?feat:=20=E5=AF=B9=E6=8E=A5=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E5=8F=8D=E9=A6=88=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/vspace/VFeedbackDialogFragment.kt | 75 ++++++++++++++++--- 1 file changed, 65 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt b/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt index 9428676275..4f15d22bd7 100644 --- a/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt +++ b/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt @@ -1,5 +1,6 @@ package com.gh.vspace +import android.os.Build import android.os.Bundle import android.os.Parcelable import android.view.Gravity @@ -8,22 +9,36 @@ import android.view.View import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.core.widget.doOnTextChanged +import androidx.lifecycle.ViewModel +import com.gh.common.util.PackageUtils import com.gh.gamecenter.R import com.gh.gamecenter.common.base.fragment.BaseDialogFragment -import com.gh.gamecenter.common.utils.dip2px -import com.gh.gamecenter.common.utils.toColor +import com.gh.gamecenter.common.exposure.meta.MetaUtil +import com.gh.gamecenter.common.json.json +import com.gh.gamecenter.common.retrofit.Response +import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.DisplayUtils +import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.databinding.DialogVgameFeedbackBinding import com.gh.gamecenter.databinding.ItemVfeedbackOptionBinding import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.retrofit.RetrofitManager +import com.halo.assistant.HaloApp +import com.lightgame.utils.Utils import com.lightgame.utils.toast.ToastHelper +import com.walkud.rom.checker.RomIdentifier +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.schedulers.Schedulers import kotlinx.parcelize.Parcelize +import okhttp3.ResponseBody +import org.json.JSONArray class VFeedbackDialogFragment : BaseDialogFragment() { private var mGame: GameEntity? = null private var mTagList: List? = null private val mBinding by lazy { DialogVgameFeedbackBinding.inflate(layoutInflater) } + private val mViewModel: VFeedbackViewModel by lazy { viewModelProvider() } override fun onCreateView( inflater: LayoutInflater, @@ -39,10 +54,17 @@ class VFeedbackDialogFragment : BaseDialogFragment() { mTagList = arguments?.getParcelableArrayList(KEY_TAG_LIST) mGame = arguments?.getParcelable(KEY_GAME) - mGame?.let { + + if (mGame == null) { + Utils.log("遇到内部异常") + dismissAllowingStateLoss() + } + + mGame!!.let { mBinding.gameIconIv.displayGameIcon(it) mBinding.gameNameTv.text = it.name } + mBinding.closeIv.enlargeTouchArea() mBinding.closeIv.setOnClickListener { dismissAllowingStateLoss() } @@ -58,6 +80,7 @@ class VFeedbackDialogFragment : BaseDialogFragment() { dismissAllowingStateLoss() } mBinding.submitTv.setOnClickListener { + mViewModel.postFeedback(mGame!!.id, mBinding.feedbackEt.text.toString(), getSelectedTagString()) dismissAllowingStateLoss() } checkLabel() @@ -65,17 +88,14 @@ class VFeedbackDialogFragment : BaseDialogFragment() { updateSubmitButton() } - private fun getSelectedTagString(): String { - val builder = StringBuilder() + private fun getSelectedTagString(): ArrayList { + val selectedTagList = arrayListOf() mTagList?.forEachIndexed { index, tag -> if (tag.checked) { - if (index != 0) { - builder.append(",") - } - builder.append(tag.tagName) + selectedTagList.add(mTagList!![index].tagName) } } - return builder.toString() + return selectedTagList } override fun onStart() { @@ -162,4 +182,39 @@ class VFeedbackDialogFragment : BaseDialogFragment() { var checked: Boolean = false ) : Parcelable + class VFeedbackViewModel : ViewModel() { + + fun postFeedback(gameId: String, message: String, tags: ArrayList) { + val json = json { + "from" to "" + "ghversion" to PackageUtils.getGhVersionName() + "channel" to HaloApp.getInstance().channel + "type" to Build.MODEL + "sdk" to Build.VERSION.SDK_INT.toString() + "version" to Build.VERSION.RELEASE + "source" to HaloApp.getInstance().application.getString(R.string.app_name) + "jnfj" to MetaUtil.getBase64EncodedIMEI() + "manufacturer" to Build.MANUFACTURER + "rom" to RomIdentifier.getRom().name + " " + RomIdentifier.getRom().versionName + + "suggestion_type" to "畅玩问题" + "game_id" to gameId + "message" to message + "tags" to JSONArray(tags) + } + + val requestBody = json.toRequestBody() + RetrofitManager.getInstance().api.postSuggestion(requestBody) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(object : Response() { + override fun onResponse(response: ResponseBody?) { + super.onResponse(response) + ToastUtils.showToast("感谢您的反馈信息,我们将尽快处理~") + } + }) + } + + } + } \ No newline at end of file From 27471cbf61ec32530e1c92272e0c5e770f04cde4 Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 14 Jun 2022 11:43:15 +0800 Subject: [PATCH 029/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E6=9C=80=E8=BF=91=E5=9C=A8=E7=8E=A9=20item=20?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E7=82=B9=E5=87=BB=E5=90=8E=E4=B8=8D=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/gamecenter/entity/GameEntity.kt | 2 +- .../gamecenter/gamedetail/GameDetailViewModel.kt | 15 ++++++--------- .../com/gh/vspace/HomeRecentVGameViewHolder.kt | 4 ++++ app/src/main/java/com/gh/vspace/VHelper.kt | 3 +++ vspace-bridge | 2 +- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt index dd558324db..477050f79a 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt @@ -212,7 +212,7 @@ data class GameEntity( private var mH5Link: LinkEntity? = null, val visit: Int = 0, @SerializedName("played_time") - val playedTime: Long = 0, + var playedTime: Long = 0, @SerializedName("played_game_id") val playedGameId: String = "", @SerializedName("mutex_package") diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt index 426a489329..ba28149f44 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt @@ -16,9 +16,10 @@ import com.gh.common.util.CheckLoginUtils import com.gh.common.util.ConcernUtils import com.gh.common.util.LibaoUtils import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.retrofit.BiResponse +import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.common.utils.singleToMain import com.gh.gamecenter.common.utils.toRequestBody -import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.core.utils.GsonUtils import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.core.utils.UrlFilterUtils @@ -29,8 +30,6 @@ import com.gh.gamecenter.gamedetail.entity.DetailEntity import com.gh.gamecenter.gamedetail.entity.NewGameDetailEntity import com.gh.gamecenter.manager.UserManager import com.gh.gamecenter.mvvm.Resource -import com.gh.gamecenter.common.retrofit.BiResponse -import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.retrofit.RetrofitManager import com.halo.assistant.HaloApp import io.reactivex.android.schedulers.AndroidSchedulers @@ -43,12 +42,6 @@ class GameDetailViewModel(application: Application, var gameId: String?, var game: GameEntity?) : AndroidViewModel(application) { - init { - runOnIoThread { - loadData() - } - } - private val mApi = RetrofitManager.getInstance().api private val mSensitiveApi = RetrofitManager.getInstance().api @@ -67,6 +60,10 @@ class GameDetailViewModel(application: Application, var videoIsMuted = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true) var displayTopVideo: Boolean = false + init { + loadData() + } + fun loadData() { if (RegionSettingHelper.shouldThisGameBeFiltered(gameId)) { gameId = "invalid" diff --git a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt index 7f215aa74a..757f1518b3 100644 --- a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt +++ b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt @@ -74,6 +74,10 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter(con } } + override fun areContentsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean { + return oldItem?.id == newItem?.id && oldItem?.playedTime == newItem?.playedTime + } + class HomeRecentVGameItemViewHolder(private var mBinding: ItemHomeVgameBinding) : RecyclerView.ViewHolder(mBinding.root) { diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index c0f72c84ae..9644df5481 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -485,6 +485,8 @@ object VHelper { } fun toGameEntity(downloadEntity: DownloadEntity): GameEntity { + val lastPlayedTimeString = downloadEntity.getMetaExtra(KEY_LAST_PLAYED_TIME) + return GameEntity(id = downloadEntity.gameId, name = downloadEntity.name).apply { setApk( arrayListOf( @@ -496,6 +498,7 @@ object VHelper { ) ) icon = downloadEntity.icon + playedTime = if (lastPlayedTimeString == "") 0L else lastPlayedTimeString.toLong() downloadStatus = "smooth" setEntryMap(DownloadManager.getInstance().getEntryMap(name)) } diff --git a/vspace-bridge b/vspace-bridge index b8f5b2e7b4..6d91ee7416 160000 --- a/vspace-bridge +++ b/vspace-bridge @@ -1 +1 @@ -Subproject commit b8f5b2e7b42cf6af0da8b696556a003cd9b1845e +Subproject commit 6d91ee74165c98fa2e8d65e5d3f0589a95774137 From eb1def1768001a93c40f9d92d181d84671dd3786 Mon Sep 17 00:00:00 2001 From: juntao Date: Wed, 15 Jun 2022 14:18:56 +0800 Subject: [PATCH 030/217] =?UTF-8?q?feature:=20=E5=AE=8C=E6=88=90=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E9=A1=B5=E7=AE=80=E5=8D=95=E7=9A=84=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/common/databind/BindingAdapters.java | 2 +- .../java/com/gh/common/util/DirectUtils.kt | 22 ++-- .../java/com/gh/common/view/GameIconView.kt | 2 +- .../gamecenter/DownloadManagerActivity.java | 2 +- .../adapter/viewholder/DetailViewHolder.java | 2 +- .../com/gh/vspace/VDownloadManagerActivity.kt | 1 + .../com/gh/vspace/VDownloadManagerAdapter.kt | 119 ++++++++++-------- .../gh/vspace/VDownloadManagerViewModel.kt | 2 + .../com/gh/vspace/VSpaceDialogFragment.kt | 119 +++++++++--------- .../layout/item_vgame_download_manager.xml | 81 ++++++++++++ 10 files changed, 230 insertions(+), 122 deletions(-) create mode 100644 app/src/main/res/layout/item_vgame_download_manager.xml diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java index 0040d7351c..4eba8180da 100644 --- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java +++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java @@ -359,7 +359,7 @@ public class BindingAdapters { case DOWNLOADING_PLUGIN: case DOWNLOADING_NORMAL: if (gameEntity.isVGame()) { - v.getContext().startActivity(new Intent(v.getContext(), VDownloadManagerActivity.class)); + v.getContext().startActivity(VDownloadManagerActivity.getIntent(v.getContext(), true)); } else { Intent intent = DownloadManagerActivity.getDownloadMangerIntent(v.getContext(), gameEntity.getApk().get(0).getUrl(), entrance); diff --git a/app/src/main/java/com/gh/common/util/DirectUtils.kt b/app/src/main/java/com/gh/common/util/DirectUtils.kt index 0e260b928c..bf60d6c72d 100644 --- a/app/src/main/java/com/gh/common/util/DirectUtils.kt +++ b/app/src/main/java/com/gh/common/util/DirectUtils.kt @@ -9,27 +9,28 @@ import android.os.Build import android.os.Bundle import android.text.TextUtils import androidx.appcompat.app.AppCompatActivity -import com.gh.gamecenter.common.base.activity.BaseActivity -import com.gh.gamecenter.common.base.activity.BaseActivity_TabLayout -import com.gh.gamecenter.common.base.activity.ToolBarActivity -import com.gh.gamecenter.common.base.fragment.BaseFragment_TabLayout -import com.gh.gamecenter.core.AppExecutor import com.gh.common.constant.Config -import com.gh.gamecenter.common.constant.Constants import com.gh.common.exposure.ExposureEvent import com.gh.common.exposure.ExposureEvent.Companion.createEvent import com.gh.common.exposure.ExposureManager.log import com.gh.common.exposure.ExposureTraceUtils.appendTrace import com.gh.common.exposure.ExposureType -import com.gh.gamecenter.common.constant.EntranceConsts.* -import com.gh.common.util.EntranceUtils.* +import com.gh.common.util.EntranceUtils.jumpActivity import com.gh.gamecenter.* import com.gh.gamecenter.amway.AmwayActivity import com.gh.gamecenter.catalog.CatalogActivity import com.gh.gamecenter.category.CategoryDirectoryActivity import com.gh.gamecenter.category2.CategoryV2Activity +import com.gh.gamecenter.common.base.activity.BaseActivity +import com.gh.gamecenter.common.base.activity.BaseActivity_TabLayout +import com.gh.gamecenter.common.base.activity.ToolBarActivity +import com.gh.gamecenter.common.base.fragment.BaseFragment_TabLayout +import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.constant.EntranceConsts +import com.gh.gamecenter.common.constant.EntranceConsts.* +import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.common.utils.* +import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.core.utils.RunningUtils import com.gh.gamecenter.download.DownloadFragment.Companion.INDEX_UPDATE import com.gh.gamecenter.entity.* @@ -57,7 +58,6 @@ import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity import com.gh.gamecenter.qa.questions.newdetail.NewQuestionDetailActivity import com.gh.gamecenter.qa.subject.CommunitySubjectActivity import com.gh.gamecenter.qa.video.detail.ForumVideoDetailActivity -import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.retrofit.RetrofitManager import com.gh.gamecenter.security.BindPhoneActivity import com.gh.gamecenter.servers.GameServerTestActivity @@ -1763,8 +1763,8 @@ object DirectUtils { } @JvmStatic - fun directToVGameDownload(context: Context) { - context.startActivity(Intent(context, VDownloadManagerActivity::class.java)) + fun directToVGameDownload(context: Context, switchToDownloadingTab: Boolean = false) { + context.startActivity(VDownloadManagerActivity.getIntent(context, false)) } @JvmStatic diff --git a/app/src/main/java/com/gh/common/view/GameIconView.kt b/app/src/main/java/com/gh/common/view/GameIconView.kt index 90898bcf47..75de6c5d99 100644 --- a/app/src/main/java/com/gh/common/view/GameIconView.kt +++ b/app/src/main/java/com/gh/common/view/GameIconView.kt @@ -48,7 +48,7 @@ class GameIconView : CardView { fun initView(attrs: AttributeSet?) { val gameIconUi = GameIconUi(context) - if (attrs != null) { + if (attrs != null && !isInEditMode) { val ta = context.obtainStyledAttributes(attrs, R.styleable.GameIconView) mCornerRadius = ta.getDimensionPixelSize( R.styleable.GameIconView_gameIconCornerRadius, diff --git a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java index ee754f03f1..6a6d529adc 100644 --- a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java +++ b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java @@ -62,7 +62,7 @@ public class DownloadManagerActivity extends ToolBarActivity { @Override public boolean onMenuItemClick(MenuItem item) { - DirectUtils.directToVGameDownload(this); + DirectUtils.directToVGameDownload(this, false); return true; } diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java index 24501f06bd..7cd9483e1d 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java @@ -339,7 +339,7 @@ public class DetailViewHolder { break; default: if (mGameEntity.isVGame()) { - mViewHolder.context.startActivity(new Intent(mViewHolder.context, VDownloadManagerActivity.class)); + mViewHolder.context.startActivity(VDownloadManagerActivity.getIntent(mViewHolder.context, true)); } else if (!mGameEntity.getApk().isEmpty()) { Intent intent = DownloadManagerActivity.getDownloadMangerIntent(mViewHolder.context, mGameEntity.getApk().get(0).getUrl(), diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt index b283142558..cc8ab96bb0 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt @@ -23,6 +23,7 @@ class VDownloadManagerActivity: ToolBarActivity() { override fun getLayoutId() = R.layout.activity_vdownload_manager companion object { + @JvmStatic fun getIntent(context: Context, switchToDownloadingTab: Boolean = false): Intent { val intent = Intent(context, VDownloadManagerActivity::class.java) intent.putExtra(EntranceConsts.KEY_POSITION, if (switchToDownloadingTab) 1 else 0) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index 601f7fc11d..35d400c386 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -6,11 +6,11 @@ import android.view.LayoutInflater import android.view.ViewGroup import android.widget.LinearLayout import android.widget.PopupWindow -import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.constraintlayout.widget.ConstraintLayout import androidx.recyclerview.widget.RecyclerView -import com.gh.common.util.GameUtils +import com.gh.common.databind.BindingAdapters +import com.gh.common.view.DownloadProgressBar import com.gh.download.DownloadManager import com.gh.gamecenter.GameDetailActivity import com.gh.gamecenter.R @@ -23,13 +23,12 @@ import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.core.utils.CurrentActivityHolder import com.gh.gamecenter.core.utils.SPUtils +import com.gh.gamecenter.core.utils.ToastUtils +import com.gh.gamecenter.databinding.ItemVgameDownloadManagerBinding import com.gh.gamecenter.databinding.PopupHistoryOptionBinding import com.gh.gamecenter.entity.GameEntity -import com.gh.gamecenter.entity.PluginLocation -import com.gh.gamecenter.game.GameItemViewHolder import com.gh.gamecenter.history.ManageOption import com.gh.gamecenter.manager.PackagesManager -import com.gh.gamecenter.manager.PackagesManager.isCanUpdate import com.lightgame.download.DownloadEntity import com.lightgame.download.DownloadStatus import com.lightgame.utils.Utils @@ -68,10 +67,11 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa override fun getItemViewType(position: Int) = ItemViewType.GAME_NORMAL override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { - return GameItemViewHolder(parent.toBinding()) + return VGameItemViewHolder(parent.toBinding()) } - override fun getItemCount(): Int = if (mEntityList == null || mEntityList.isEmpty()) 0 else mEntityList.size + override fun getItemCount(): Int = + if (mEntityList == null || mEntityList.isEmpty()) 0 else mEntityList.size fun changeOption(option: ManageOption) { mCurrentOption = option @@ -95,11 +95,12 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa position: Int ) { when (holder) { - is GameItemViewHolder -> { + is VGameItemViewHolder -> { val gameEntity = mEntityList[position] - holder.bindGameItem(gameEntity) - holder.initServerType(gameEntity) + BindingAdapters.setGameName(holder.binding.nameTv, gameEntity, false, true) + holder.binding.iconIv.displayGameIcon(gameEntity) + holder.binding.descTv.text = "已畅玩999分钟" (holder.binding.selectIv.layoutParams as ConstraintLayout.LayoutParams).apply { width = 20F.dip2px() @@ -223,68 +224,84 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa } } - private fun updateDownloadBtn(context: Context, - downloadBtn: TextView, - gameEntity: GameEntity) { + private fun updateDownloadBtn( + context: Context, + downloadBtn: DownloadProgressBar, + gameEntity: GameEntity + ) { // 青少年模式显示查看 if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) { downloadBtn.text = "查看" return } - if (gameEntity.getApk().size == 1) { - val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByUrl(gameEntity.getApk()[0].url) - if (downloadEntity != null) { - val status = downloadEntity.status - var btnText = R.string.downloading - var btnColor = R.color.white - var btnBackground = R.drawable.download_button_normal_style + val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByUrl(gameEntity.getApk()[0].url) + if (downloadEntity != null) { + val status = downloadEntity.status + var btnText = context.getText(R.string.downloading) + var backgroundType = DownloadProgressBar.DownloadType.NORMAL - downloadBtn.apply { - if (status == DownloadStatus.downloading) { - btnText = R.string.pause - btnBackground = R.drawable.button_normal_round_border - btnColor = R.color.theme_font - setOnClickListener { DownloadManager.getInstance().pause(downloadEntity.url) } - } else if (status == DownloadStatus.waiting) { - btnText = R.string.waiting + downloadBtn.apply { + when (status) { + DownloadStatus.downloading -> { + btnText = "${downloadEntity.percent}%" + backgroundType = DownloadProgressBar.DownloadType.DOWNLOADING_NORMAL + progress = (downloadEntity.percent * 10).toInt() + setOnClickListener { + DownloadManager.getInstance().pause(downloadEntity.url) + } + } + DownloadStatus.waiting -> { + btnText = context.getString(R.string.waiting) setOnClickListener { Utils.toast(mContext, "最多只能同时启动3个下载任务"); } - } else if (status == DownloadStatus.pause - || status == DownloadStatus.timeout - || status == DownloadStatus.neterror - || status == DownloadStatus.subscribe - || status == DownloadStatus.overflow - ) { - btnText = R.string.resume + } + DownloadStatus.pause, + DownloadStatus.timeout, + DownloadStatus.neterror, + DownloadStatus.subscribe, + DownloadStatus.overflow -> { + btnText = context.getString(R.string.resume) setOnClickListener { DownloadManager.getInstance().resume(downloadEntity, true) } - } else if (status == DownloadStatus.done) { - GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, PluginLocation.only_index) - - setOnClickListener { - if (isCanUpdate(gameEntity.id, gameEntity.getApk().firstOrNull()?.packageName)) { - PackagesManager.getUpdateList().firstOrNull { it.id == downloadEntity.gameId }?.let { - VHelper.update(downloadEntity, it) - } - } else { + } + DownloadStatus.done -> { + if (PackagesManager.isCanUpdate(gameEntity.id, + gameEntity.getApk().firstOrNull()?.packageName)) { + btnText = context.getString(R.string.update) + setOnClickListener { + PackagesManager.getUpdateList() + .firstOrNull { it.id == downloadEntity.gameId }?.let { + VHelper.update(downloadEntity, it) + } + } + } else { + btnText = context.getString(R.string.launch) + setOnClickListener { CurrentActivityHolder.getCurrentActivity()?.let { VHelper.launch(it, downloadEntity.packageName) } } } } - - setText(btnText) - setTextColor(btnColor.toColor()) - setBackgroundResource(btnBackground) + else -> { + // do nothing + } } - } else { - GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, PluginLocation.only_index) + + text = btnText.toString() + downloadType = backgroundType } } else { - GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, PluginLocation.only_index) + downloadBtn.downloadType = DownloadProgressBar.DownloadType.NORMAL + downloadBtn.text = "下载" + downloadBtn.setOnClickListener { + ToastUtils.toast("不应该出现状态为'下载'的按钮") + } } } + class VGameItemViewHolder(var binding: ItemVgameDownloadManagerBinding) : + RecyclerView.ViewHolder(binding.root) + } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index f168f810a6..97d7fbc572 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -58,6 +58,7 @@ class VDownloadManagerViewModel(application: Application) : } fun removeItem(url: String?, packageName: String?) { + DownloadManager.getInstance().pause(url) DownloadManager.getInstance().cancel(url) VHelper.uninstall(packageName ?: "") } @@ -65,6 +66,7 @@ class VDownloadManagerViewModel(application: Application) : fun removeItems(idList: ArrayList) { for (id in idList) { val apkEntity = mResultLiveData.value?.firstOrNull { id == it.id }?.getApk()?.firstOrNull() + DownloadManager.getInstance().pause(apkEntity?.url) DownloadManager.getInstance().cancel(apkEntity?.url) VHelper.uninstall(apkEntity?.packageName) } diff --git a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt index ff39040337..d8246c0cb1 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt @@ -39,60 +39,8 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { private val mBinding by lazy { DialogVspaceBinding.inflate(layoutInflater) } private val mDataWatcher = object : DataWatcher() { override fun onDataChanged(downloadEntity: DownloadEntity) { - if (downloadEntity.url == mDownloadUrl) { - val downloadBtn = mBinding.downloadBtn - downloadBtn.progress = (downloadEntity.progress * 10).toInt() - when (downloadEntity.status) { - downloading, - pause, - overflow -> { - if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL)) { - downloadBtn.setText(R.string.browser_install_downloading) - } else { - downloadBtn.setText(R.string.downloading) - } - downloadBtn.downloadType = DownloadProgressBar.DownloadType.DOWNLOADING_NORMAL - downloadBtn.setOnClickListener { - DownloadManager.getInstance().pause(mDownloadUrl) - } - } - timeout, - neterror, - waiting, - subscribe -> { - downloadBtn.setText(R.string.waiting) - downloadBtn.downloadType = DownloadProgressBar.DownloadType.DOWNLOADING_NORMAL - downloadBtn.setOnClickListener { - DownloadManager.getInstance().resume(downloadEntity, false) - } - } - done -> { - if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL)) { - downloadBtn.setText(R.string.browser_install_install) - } else { - downloadBtn.setText(R.string.install) - } - downloadBtn.downloadType = DownloadProgressBar.DownloadType.INSTALL_NORMAL - downloadBtn.setOnClickListener { - PackageInstaller.install(requireContext(), downloadEntity) - } - } - - cancel, - hijack, - notfound, - uncertificated, - unqualified -> { - downloadBtn.text = "下载畅玩助手服务组件" - downloadBtn.downloadType = DownloadProgressBar.DownloadType.NORMAL - downloadBtn.setOnClickListener { - DownloadManager.getInstance().resume(downloadEntity, true) - } - } - else -> { - // do nothing - } - } + if (downloadEntity.url == mDownloadUrl && isAdded) { + updateDownloadButton(downloadEntity) } } } @@ -138,7 +86,10 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { val downloadEntity = DownloadEntity() downloadEntity.url = mDownloadUrl downloadEntity.name = "畅玩助手V" + vSpaceInfo.versionName - downloadEntity.path = FileUtils.getDownloadPath(requireContext(), "畅玩助手V" + vSpaceInfo.versionName + ".apk"); + downloadEntity.path = FileUtils.getDownloadPath( + requireContext(), + "畅玩助手V" + vSpaceInfo.versionName + ".apk" + ) downloadEntity.platform = "官方版" downloadEntity.gameId = "" downloadEntity.path = PackageInstaller.getDownloadPathWithId(downloadId, "apk") @@ -160,6 +111,62 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { DownloadManager.getInstance().removeObserver(mDataWatcher) } + private fun updateDownloadButton(downloadEntity: DownloadEntity) { + val downloadBtn = mBinding.downloadBtn + downloadBtn.progress = (downloadEntity.progress * 10).toInt() + when (downloadEntity.status) { + downloading -> { + downloadBtn.setText(R.string.pause) + downloadBtn.progress = downloadEntity.percent.toInt() + downloadBtn.downloadType = DownloadProgressBar.DownloadType.DOWNLOADING_NORMAL + downloadBtn.setOnClickListener { + DownloadManager.getInstance().pause(mDownloadUrl) + } + } + + pause -> { + downloadBtn.setText(R.string.resume) + downloadBtn.setOnClickListener { + DownloadManager.getInstance().resume(downloadEntity, true) + } + } + + overflow, + timeout, + neterror, + waiting, + subscribe ->{ + downloadBtn.setText(R.string.waiting) + downloadBtn.downloadType = DownloadProgressBar.DownloadType.DOWNLOADING_NORMAL + downloadBtn.setOnClickListener { + DownloadManager.getInstance().resume(downloadEntity, false) + } + } + done -> { + downloadBtn.setText(R.string.install) + downloadBtn.downloadType = DownloadProgressBar.DownloadType.INSTALL_NORMAL + downloadBtn.setOnClickListener { + PackageInstaller.install(requireContext(), downloadEntity) + } + } + + cancel, + hijack, + notfound, + uncertificated, + unqualified -> { + downloadBtn.text = "下载畅玩助手服务组件" + downloadBtn.downloadType = DownloadProgressBar.DownloadType.NORMAL + downloadBtn.setOnClickListener { + DownloadManager.getInstance().resume(downloadEntity, true) + } + } + else -> { + // do nothing + } + } + } + companion object { @JvmStatic fun showDownloadDialog(context: Context?) { @@ -193,7 +200,7 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { } } - internal class VSpaceDialogViewModel: ViewModel() { + internal class VSpaceDialogViewModel : ViewModel() { val packageLiveData = MutableLiveData() private val mPackageChangedListener by lazy { PackageObserver.PackageChangeListener { diff --git a/app/src/main/res/layout/item_vgame_download_manager.xml b/app/src/main/res/layout/item_vgame_download_manager.xml new file mode 100644 index 0000000000..c88e5866a8 --- /dev/null +++ b/app/src/main/res/layout/item_vgame_download_manager.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + From c646251b34e12d173ffccf6f2326e6e2a68084fe Mon Sep 17 00:00:00 2001 From: juntao Date: Wed, 15 Jun 2022 17:01:23 +0800 Subject: [PATCH 031/217] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E9=80=9A=E7=9F=A5=E6=A0=8F=E8=B7=B3=E8=BD=AC=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E4=B8=8B=E8=BD=BD=E7=AE=A1=E7=90=86=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/gh/common/util/DirectUtils.kt | 6 +++++- .../gh/common/util/DownloadNotificationHelper.kt | 14 +++++++------- .../gh/gamecenter/receiver/DownloadReceiver.java | 7 ++++++- .../gh/vspace/VDownloadManagerWrapperFragment.kt | 2 +- app/src/main/java/com/halo/assistant/HaloApp.java | 1 + 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/DirectUtils.kt b/app/src/main/java/com/gh/common/util/DirectUtils.kt index bf60d6c72d..2a2bcf23d4 100644 --- a/app/src/main/java/com/gh/common/util/DirectUtils.kt +++ b/app/src/main/java/com/gh/common/util/DirectUtils.kt @@ -1764,7 +1764,11 @@ object DirectUtils { @JvmStatic fun directToVGameDownload(context: Context, switchToDownloadingTab: Boolean = false) { - context.startActivity(VDownloadManagerActivity.getIntent(context, false)) + val bundle = Bundle() + bundle.putString(KEY_ENTRANCE, ENTRANCE_BROWSER) + bundle.putString(KEY_TO, VDownloadManagerActivity::class.java.name) + bundle.putInt(KEY_POSITION, if (switchToDownloadingTab) 1 else 0) + jumpActivity(context, bundle) } @JvmStatic diff --git a/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt b/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt index af208da26f..ddd36d1516 100644 --- a/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt +++ b/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt @@ -8,17 +8,14 @@ import android.content.Context import android.content.Intent import android.os.Build import androidx.core.app.NotificationCompat -import com.gh.gamecenter.core.AppExecutor -import com.gh.gamecenter.common.constant.Constants import com.gh.common.xapk.XapkInstaller import com.gh.common.xapk.XapkUnzipStatus import com.gh.gamecenter.R +import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.constant.EntranceConsts -import com.gh.gamecenter.common.utils.getMetaExtra -import com.gh.gamecenter.common.utils.isSimulatorGame -import com.gh.gamecenter.common.utils.toJson -import com.gh.gamecenter.common.utils.tryCatchInRelease -import com.gh.gamecenter.core.utils.* +import com.gh.gamecenter.common.utils.* +import com.gh.gamecenter.core.AppExecutor +import com.gh.gamecenter.core.utils.SpeedUtils import com.halo.assistant.HaloApp import com.lightgame.download.DownloadEntity import com.lightgame.download.DownloadStatus @@ -34,6 +31,7 @@ object DownloadNotificationHelper { const val ACTION_INSTALL = "com.gh.gamecenter.INSTALL" const val ACTION_DOWNLOAD = "com.gh.gamecenter.DOWNLOAD" + const val ACTION_VDOWNLOAD = "com.gh.gamecenter.VDOWNLOAD" private val mNotifyMap: MutableMap = mutableMapOf() private val mShouldUseAlternativeNotificationIcon by lazy { RomIdentifier.getRom().versionName == null } @@ -58,6 +56,8 @@ object DownloadNotificationHelper { intent.putExtra(EntranceConsts.KEY_DATA, entity.toJson()) intent.putExtra(EntranceConsts.KEY_PATH, entity.path) intent.action = ACTION_INSTALL + } else if (entity.isSmoothGame()) { + intent.action = ACTION_VDOWNLOAD } else { intent.action = ACTION_DOWNLOAD } diff --git a/app/src/main/java/com/gh/gamecenter/receiver/DownloadReceiver.java b/app/src/main/java/com/gh/gamecenter/receiver/DownloadReceiver.java index d92eb6f11d..0a158c70b3 100644 --- a/app/src/main/java/com/gh/gamecenter/receiver/DownloadReceiver.java +++ b/app/src/main/java/com/gh/gamecenter/receiver/DownloadReceiver.java @@ -7,6 +7,7 @@ import android.content.Context; import android.content.Intent; import com.gh.common.util.DirectUtils; +import com.gh.common.util.DownloadNotificationHelper; import com.gh.gamecenter.common.utils.ExtensionsKt; /** @@ -18,7 +19,11 @@ public class DownloadReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { ExtensionsKt.doOnMainProcessOnly(context, () -> { - DirectUtils.directToDownloadManager(context, ENTRANCE_DOWNLOAD); + if (DownloadNotificationHelper.ACTION_VDOWNLOAD.equals(intent.getAction())) { + DirectUtils.directToVGameDownload(context, true); + } else { + DirectUtils.directToDownloadManager(context, ENTRANCE_DOWNLOAD); + } }); } } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt index 05a59651e1..eb328cdf9d 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt @@ -32,7 +32,7 @@ class VDownloadManagerWrapperFragment: BaseLazyTabFragment() { } arguments?.getInt(EntranceConsts.KEY_POSITION)?.let { - mViewPager.currentItem = it + mViewPager.post { mViewPager.currentItem = it } } mManageMenu = getItemMenu(R.id.layout_menu_manage) diff --git a/app/src/main/java/com/halo/assistant/HaloApp.java b/app/src/main/java/com/halo/assistant/HaloApp.java index d75de03014..477287c995 100644 --- a/app/src/main/java/com/halo/assistant/HaloApp.java +++ b/app/src/main/java/com/halo/assistant/HaloApp.java @@ -329,6 +329,7 @@ public class HaloApp extends MultiDexApplication implements Configuration.Provid DownloadReceiver downloadReceiver = new DownloadReceiver(); IntentFilter downloadFilter = new IntentFilter(); downloadFilter.addAction(DownloadNotificationHelper.ACTION_DOWNLOAD); + downloadFilter.addAction(DownloadNotificationHelper.ACTION_VDOWNLOAD); this.registerReceiver(downloadReceiver, downloadFilter); InstallReceiver installReceiver = new InstallReceiver(); From 3dc65fb415d90710ba35d23afd4dffae05de46d3 Mon Sep 17 00:00:00 2001 From: juntao Date: Wed, 15 Jun 2022 17:48:23 +0800 Subject: [PATCH 032/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E5=8A=A9=E6=89=8B=E4=B8=8B=E8=BD=BD=E8=BF=9B=E5=BA=A6?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt index d8246c0cb1..f38501cb4e 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt @@ -20,11 +20,9 @@ import com.gh.download.DownloadManager import com.gh.download.PackageObserver import com.gh.gamecenter.R import com.gh.gamecenter.common.base.fragment.BaseDraggableDialogFragment -import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.utils.toColor import com.gh.gamecenter.common.utils.viewModelProvider import com.gh.gamecenter.core.AppExecutor -import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.databinding.DialogVspaceBinding import com.gh.gamecenter.eventbus.EBPackage import com.lightgame.download.DataWatcher @@ -117,7 +115,7 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { when (downloadEntity.status) { downloading -> { downloadBtn.setText(R.string.pause) - downloadBtn.progress = downloadEntity.percent.toInt() + downloadBtn.progress = (downloadEntity.percent * 10).toInt() downloadBtn.downloadType = DownloadProgressBar.DownloadType.DOWNLOADING_NORMAL downloadBtn.setOnClickListener { DownloadManager.getInstance().pause(mDownloadUrl) From f37200f9020fd040b751ccb21161c9b0185bdf3e Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 16 Jun 2022 17:18:37 +0800 Subject: [PATCH 033/217] =?UTF-8?q?feat:=20=E7=95=85=E7=8E=A9=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E7=BB=95=E8=BF=87=E6=B5=8F=E8=A7=88=E5=99=A8=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/databind/BindingAdapters.java | 2 +- .../java/com/gh/common/util/DownloadItemUtils.kt | 4 ++-- .../download/dialog/DownloadDialogItemViewHolder.kt | 13 ++++++++----- .../com/gh/download/server/BrowserInstallHelper.kt | 4 ++-- .../adapter/viewholder/DetailViewHolder.java | 2 +- .../java/com/gh/gamecenter/home/HomeViewModel.kt | 3 +++ app/src/main/java/com/gh/vspace/VHelper.kt | 6 ++++-- 7 files changed, 21 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java index 4eba8180da..a34c4f298f 100644 --- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java +++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java @@ -384,7 +384,7 @@ public class BindingAdapters { } VHelper.checkVSpaceBeforeAction(v.getContext(), gameEntity, () -> { GamePermissionDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, gameEntity.getInfo(), () -> { - BrowserInstallHelper.showBrowserInstallHintDialog(v.getContext(), () -> { + BrowserInstallHelper.showBrowserInstallHintDialog(v.getContext(), gameEntity.isVGame(), () -> { PackageCheckDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, () -> { DownloadDialogHelper.findAvailableDialogAndShow(v.getContext(), gameEntity, apk, () -> { CertificationDialog.showCertificationDialog(v.getContext(), gameEntity, () -> { diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index 07ef630aae..d56fd3465c 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -651,7 +651,7 @@ object DownloadItemUtils { val apk = gameEntity.getApk().safelyGetInRelease(0) ?: return if (str == context.getString(R.string.download)) { GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) { - BrowserInstallHelper.showBrowserInstallHintDialog(context, object : EmptyCallback { + BrowserInstallHelper.showBrowserInstallHintDialog(context, gameEntity.isVGame(), object : EmptyCallback { override fun onCallback() { PackageCheckDialogFragment.show(context, gameEntity) { DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, object : EmptyCallback { @@ -672,7 +672,7 @@ object DownloadItemUtils { DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance) } else if (str == context.getString(R.string.attempt)) { GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) { - BrowserInstallHelper.showBrowserInstallHintDialog(context, object : EmptyCallback { + BrowserInstallHelper.showBrowserInstallHintDialog(context, gameEntity.isVGame(), object : EmptyCallback { override fun onCallback() { PackageCheckDialogFragment.show(context, gameEntity) { DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, object : EmptyCallback { diff --git a/app/src/main/java/com/gh/download/dialog/DownloadDialogItemViewHolder.kt b/app/src/main/java/com/gh/download/dialog/DownloadDialogItemViewHolder.kt index 6b75fae923..56a458969b 100644 --- a/app/src/main/java/com/gh/download/dialog/DownloadDialogItemViewHolder.kt +++ b/app/src/main/java/com/gh/download/dialog/DownloadDialogItemViewHolder.kt @@ -6,23 +6,26 @@ import android.widget.RelativeLayout import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView -import com.gh.gamecenter.common.base.activity.BaseActivity -import com.gh.gamecenter.common.base.BaseRecyclerViewHolder import com.gh.common.constant.Config import com.gh.common.dialog.CertificationDialog import com.gh.common.dialog.DeviceRemindDialog import com.gh.common.dialog.PackageCheckDialogFragment import com.gh.common.exposure.ExposureEvent -import com.gh.common.util.* import com.gh.common.util.DialogUtils import com.gh.common.util.DirectUtils.directToLinkPage +import com.gh.common.util.DownloadDialogHelper +import com.gh.common.util.PackageInstaller +import com.gh.common.util.PackageUtils import com.gh.download.DownloadManager import com.gh.download.server.BrowserInstallHelper import com.gh.gamecenter.DownloadManagerActivity import com.gh.gamecenter.R +import com.gh.gamecenter.common.base.BaseRecyclerViewHolder +import com.gh.gamecenter.common.base.activity.BaseActivity import com.gh.gamecenter.common.callback.ConfirmListener import com.gh.gamecenter.common.utils.* -import com.gh.gamecenter.core.utils.* +import com.gh.gamecenter.core.utils.EmptyCallback +import com.gh.gamecenter.core.utils.SpeedUtils import com.gh.gamecenter.databinding.DownloadDialogItemBinding import com.gh.gamecenter.entity.ApkEntity import com.gh.gamecenter.entity.GameCollectionEntity @@ -351,7 +354,7 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas // todo 有时间存储判断统一处理 val msg = FileUtils.isCanDownload(context, apkEntity.size) if (msg.isNullOrEmpty()) { - BrowserInstallHelper.showBrowserInstallHintDialog(context, object : EmptyCallback { + BrowserInstallHelper.showBrowserInstallHintDialog(context, gameEntity.isVGame(), object : EmptyCallback { override fun onCallback() { DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apkEntity, object : EmptyCallback { override fun onCallback() { diff --git a/app/src/main/java/com/gh/download/server/BrowserInstallHelper.kt b/app/src/main/java/com/gh/download/server/BrowserInstallHelper.kt index c5993f66bd..2415efd587 100644 --- a/app/src/main/java/com/gh/download/server/BrowserInstallHelper.kt +++ b/app/src/main/java/com/gh/download/server/BrowserInstallHelper.kt @@ -123,8 +123,8 @@ object BrowserInstallHelper { } @JvmStatic - fun showBrowserInstallHintDialog(context: Context, callback: EmptyCallback) { - if (!shouldShowUseBrowserToInstallHint()) { + fun showBrowserInstallHintDialog(context: Context, skipBrowserInstallDialog: Boolean = false, callback: EmptyCallback) { + if (skipBrowserInstallDialog || !shouldShowUseBrowserToInstallHint()) { callback.onCallback() return } diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java index 7cd9483e1d..4cba7b8c0f 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java @@ -194,7 +194,7 @@ public class DetailViewHolder { PermissionHelper.checkStoragePermissionBeforeAction(mViewHolder.context, () -> { if (mGameEntity.getApk().size() == 1) { ApkEntity apk = mGameEntity.getApk().get(0); - BrowserInstallHelper.showBrowserInstallHintDialog(mViewHolder.context, () -> { + BrowserInstallHelper.showBrowserInstallHintDialog(mViewHolder.context, mGameEntity.isVGame(), () -> { PackageCheckDialogFragment.show((AppCompatActivity) mViewHolder.context, mGameEntity, () -> { DownloadDialogHelper.findAvailableDialogAndShow(mViewHolder.context, mGameEntity, apk, () -> { CertificationDialog.showCertificationDialog(mViewHolder.context, mGameEntity, () -> { diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index a8d7bb6c63..9080ffe9f6 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -115,6 +115,9 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { mVGameList?.clear() transformationItemData() } + } else { + mVGameList?.clear() + transformationItemData() } } diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 9644df5481..0ec094a0ee 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -127,7 +127,7 @@ object VHelper { */ @JvmStatic fun isInstalled(packageName: String?): Boolean { - return mInstalledInfoList.any { it.packageName == packageName } + return mInstalledInfoList.any { it?.packageName == packageName } } /** @@ -215,7 +215,9 @@ object VHelper { val installedPackageList = arrayListOf() for (info in installedList) { - installedPackageList.add(info.packageName) + info.packageName?.let { + installedPackageList.add(info.packageName) + } } Utils.log(LOG_TAG, "已安装包名列表$installedPackageList") From c4035d319ee8fcd6fef1613f4b751ab402adf221 Mon Sep 17 00:00:00 2001 From: juntao Date: Fri, 17 Jun 2022 15:37:24 +0800 Subject: [PATCH 034/217] =?UTF-8?q?feat:=20=E5=B0=86=E7=95=85=E7=8E=A9?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E6=9D=83=E9=99=90=E6=A3=80=E6=B5=8B=E7=A7=BB?= =?UTF-8?q?=E5=88=B0=E5=AE=89=E8=A3=85=E6=97=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/common/databind/BindingAdapters.java | 22 ++++---- .../com/gh/common/util/DownloadItemUtils.kt | 2 +- .../adapter/viewholder/DetailViewHolder.java | 51 +++++++++---------- .../com/gh/gamecenter/entity/GameEntity.kt | 4 ++ .../gh/vspace/HomeRecentVGameViewHolder.kt | 2 +- .../com/gh/vspace/VDownloadManagerAdapter.kt | 8 ++- .../gh/vspace/VDownloadManagerViewModel.kt | 4 ++ app/src/main/java/com/gh/vspace/VHelper.kt | 51 +++++++++++++------ .../gh/vspace/VLoadCompleteWindowHelper.kt | 2 +- .../com/gh/vspace/VSpaceLoadingFragment.kt | 2 +- vspace-bridge | 2 +- 11 files changed, 88 insertions(+), 62 deletions(-) diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java index a34c4f298f..b7c6fece4a 100644 --- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java +++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java @@ -382,17 +382,15 @@ public class BindingAdapters { return; } } - VHelper.checkVSpaceBeforeAction(v.getContext(), gameEntity, () -> { - GamePermissionDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, gameEntity.getInfo(), () -> { - BrowserInstallHelper.showBrowserInstallHintDialog(v.getContext(), gameEntity.isVGame(), () -> { - PackageCheckDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, () -> { - DownloadDialogHelper.findAvailableDialogAndShow(v.getContext(), gameEntity, apk, () -> { - CertificationDialog.showCertificationDialog(v.getContext(), gameEntity, () -> { - DialogUtils.showVersionNumberDialog(v.getContext(), gameEntity, () -> { - DialogUtils.showOverseaDownloadDialog(v.getContext(), gameEntity, () -> { - DialogUtils.checkDownload(v.getContext(), apk.getSize(), - isSubscribe -> download(progressBar, gameEntity, traceEvent, isSubscribe, entrance, location)); - }); + GamePermissionDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, gameEntity.getInfo(), () -> { + BrowserInstallHelper.showBrowserInstallHintDialog(v.getContext(), gameEntity.isVGame(), () -> { + PackageCheckDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, () -> { + DownloadDialogHelper.findAvailableDialogAndShow(v.getContext(), gameEntity, apk, () -> { + CertificationDialog.showCertificationDialog(v.getContext(), gameEntity, () -> { + DialogUtils.showVersionNumberDialog(v.getContext(), gameEntity, () -> { + DialogUtils.showOverseaDownloadDialog(v.getContext(), gameEntity, () -> { + DialogUtils.checkDownload(v.getContext(), apk.getSize(), + isSubscribe -> download(progressBar, gameEntity, traceEvent, isSubscribe, entrance, location)); }); }); }); @@ -433,7 +431,7 @@ public class BindingAdapters { } if (gameEntity.isVGame()) { - VHelper.launch((AppCompatActivity) v.getContext(), gameEntity.getApk().get(0).getPackageName()); + VHelper.installOrLaunch((AppCompatActivity) v.getContext(), gameEntity.getApk().get(0).getPackageName()); return; } diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index d56fd3465c..286aa1a621 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -761,7 +761,7 @@ object DownloadItemUtils { } if (gameEntity.isVGame()) { - VHelper.launch((context as AppCompatActivity), gameEntity.getUniquePackageName() ?: "") + VHelper.installOrLaunch((context as AppCompatActivity), gameEntity.getUniquePackageName() ?: "") return } diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java index 4cba7b8c0f..f8417ed863 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java @@ -31,7 +31,6 @@ import com.gh.gamecenter.core.utils.MtaHelper; import com.gh.common.util.PackageInstaller; import com.gh.common.util.PackageUtils; import com.gh.gamecenter.common.utils.PermissionHelper; -import com.gh.common.util.RealNameHelper; import com.gh.common.util.ReservationHelper; import com.gh.gamecenter.core.utils.StringUtils; import com.gh.common.view.DownloadProgressBar; @@ -189,37 +188,35 @@ public class DetailViewHolder { case NORMAL: DataLogUtils.uploadGameLog(mViewHolder.context, mGameEntity.getId(), mGameEntity.getName(), mEntrance); case PLUGIN: - VHelper.checkVSpaceBeforeAction(mViewHolder.context, mGameEntity, () -> { - GamePermissionDialogFragment.show((AppCompatActivity) mViewHolder.context, mGameEntity, mGameEntity.getInfo(), () -> { - PermissionHelper.checkStoragePermissionBeforeAction(mViewHolder.context, () -> { - if (mGameEntity.getApk().size() == 1) { - ApkEntity apk = mGameEntity.getApk().get(0); - BrowserInstallHelper.showBrowserInstallHintDialog(mViewHolder.context, mGameEntity.isVGame(), () -> { - PackageCheckDialogFragment.show((AppCompatActivity) mViewHolder.context, mGameEntity, () -> { - DownloadDialogHelper.findAvailableDialogAndShow(mViewHolder.context, mGameEntity, apk, () -> { - CertificationDialog.showCertificationDialog(mViewHolder.context, mGameEntity, () -> { - DialogUtils.showVersionNumberDialog(mViewHolder.context, mGameEntity, () -> { - DialogUtils.showOverseaDownloadDialog(mViewHolder.context, mGameEntity, () -> { - DialogUtils.checkDownload(mViewHolder.context, apk.getSize(), this::download); - }); + GamePermissionDialogFragment.show((AppCompatActivity) mViewHolder.context, mGameEntity, mGameEntity.getInfo(), () -> { + PermissionHelper.checkStoragePermissionBeforeAction(mViewHolder.context, () -> { + if (mGameEntity.getApk().size() == 1) { + ApkEntity apk = mGameEntity.getApk().get(0); + BrowserInstallHelper.showBrowserInstallHintDialog(mViewHolder.context, mGameEntity.isVGame(), () -> { + PackageCheckDialogFragment.show((AppCompatActivity) mViewHolder.context, mGameEntity, () -> { + DownloadDialogHelper.findAvailableDialogAndShow(mViewHolder.context, mGameEntity, apk, () -> { + CertificationDialog.showCertificationDialog(mViewHolder.context, mGameEntity, () -> { + DialogUtils.showVersionNumberDialog(mViewHolder.context, mGameEntity, () -> { + DialogUtils.showOverseaDownloadDialog(mViewHolder.context, mGameEntity, () -> { + DialogUtils.checkDownload(mViewHolder.context, apk.getSize(), this::download); }); }); }); }); }); - } else { - CertificationDialog.showCertificationDialog(mViewHolder.context, mGameEntity, () -> { - DialogUtils.showVersionNumberDialog(mViewHolder.context, mGameEntity, () -> { - DownloadDialog.showDownloadDialog( - mViewHolder.context, - mGameEntity, - mTraceEvent, - StringUtils.buildString(mEntrance, "+(", mName, "[", mTitle, "])"), - mName + ":" + mTitle); - }); + }); + } else { + CertificationDialog.showCertificationDialog(mViewHolder.context, mGameEntity, () -> { + DialogUtils.showVersionNumberDialog(mViewHolder.context, mGameEntity, () -> { + DownloadDialog.showDownloadDialog( + mViewHolder.context, + mGameEntity, + mTraceEvent, + StringUtils.buildString(mEntrance, "+(", mName, "[", mTitle, "])"), + mName + ":" + mTitle); }); - } - }); + }); + } }); }); break; @@ -240,7 +237,7 @@ public class DetailViewHolder { } if (mGameEntity.isVGame()) { - VHelper.launch((AppCompatActivity) mViewHolder.context, mGameEntity.getApk().get(0).getPackageName()); + VHelper.installOrLaunch((AppCompatActivity) mViewHolder.context, mGameEntity.getApk().get(0).getPackageName()); return; } diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt index 477050f79a..0827a7f402 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt @@ -268,6 +268,10 @@ data class GameEntity( // 本地字段,使用镜像信息 var useMirrorInfo: Boolean = false, + + // 本地字段,最后打开时间 + var lastPlayedTime: Long = 0, + // 本地字段,曝光用 var displayContent: String = "", var isPlatformRecommend: Boolean = false, diff --git a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt index 757f1518b3..e40f8bbfe3 100644 --- a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt +++ b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt @@ -123,7 +123,7 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter(con when (downloadEntity.status) { DownloadStatus.done -> { binding.root.setOnClickListener { - VHelper.launch(binding.root.context, downloadEntity.packageName) + VHelper.installOrLaunch(binding.root.context, downloadEntity.packageName) } } DownloadStatus.pause, diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index 35d400c386..299bd32412 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -22,6 +22,7 @@ import com.gh.gamecenter.common.constant.ItemViewType import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.core.utils.CurrentActivityHolder +import com.gh.gamecenter.core.utils.NumberUtils import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.databinding.ItemVgameDownloadManagerBinding @@ -97,10 +98,13 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa when (holder) { is VGameItemViewHolder -> { val gameEntity = mEntityList[position] + val totalPlayedTimeString = NumberUtils.transSimpleUsageTime(gameEntity.playedTime) BindingAdapters.setGameName(holder.binding.nameTv, gameEntity, false, true) holder.binding.iconIv.displayGameIcon(gameEntity) - holder.binding.descTv.text = "已畅玩999分钟" + + holder.binding.descTv.goneIf(mViewModel.isTypeDownloaded()) + holder.binding.descTv.text = "已畅玩$totalPlayedTimeString" (holder.binding.selectIv.layoutParams as ConstraintLayout.LayoutParams).apply { width = 20F.dip2px() @@ -279,7 +283,7 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa btnText = context.getString(R.string.launch) setOnClickListener { CurrentActivityHolder.getCurrentActivity()?.let { - VHelper.launch(it, downloadEntity.packageName) + VHelper.installOrLaunch(it, downloadEntity.packageName) } } } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index 97d7fbc572..ff0a4012c8 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -72,6 +72,10 @@ class VDownloadManagerViewModel(application: Application) : } } + fun isTypeDownloaded() : Boolean { + return type == TYPE_DOWNLOADED + } + companion object { const val TYPE = "type" const val TYPE_DOWNLOADED = "type_downloaded" diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 0ec094a0ee..da3c1388c8 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -1,7 +1,6 @@ package com.gh.vspace import android.Manifest -import android.app.Activity import android.content.Context import android.content.Intent import android.net.Uri @@ -201,7 +200,7 @@ object VHelper { return } - checkStoragePermissionBeforeAction(context, callback) + callback.invoke() } else { callback.invoke() } @@ -271,15 +270,15 @@ object VHelper { /** * 安装新应用 */ - fun install(activity: Activity, filePath: String) { - Utils.log(LOG_TAG, "尝试安装新应用") + fun install(context: Context, filePath: String) { + Utils.log(LOG_TAG, "尝试安装新应用 $filePath") - if (showDialogIfVSpaceIsNeeded(activity)) { + if (showDialogIfVSpaceIsNeeded(context)) { return } val installClosure: () -> Unit = { - checkStoragePermissionBeforeAction(activity) { + checkStoragePermissionBeforeAction(context) { // 安装过程会比较漫长,所以得放在工作线程运行 AppExecutor.ioExecutor.execute { try { @@ -315,16 +314,29 @@ object VHelper { } /** - * 启动应用 + * 安装或启动应用 */ @JvmStatic - fun launch(context: Context, packageName: String) { - Utils.log(LOG_TAG, "打开应用$packageName") + fun installOrLaunch(context: Context, packageName: String) { + Utils.log(LOG_TAG, "检测是需要安装还是启动 $packageName") - DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName)?.let { - mLastSuccessfullyLaunchedGame = Pair(System.currentTimeMillis(), it.gameId) + if (showDialogIfVSpaceIsNeeded(context)) { + return } + if (isInstalled(packageName)) { + launch(context, packageName) + } else { + install(context, getDownloadEntitySnapshotByPackageName(packageName)?.path ?: "") + } + } + + /** + * 启动应用 + */ + fun launch(context: Context, packageName: String) { + Utils.log(LOG_TAG, "打开应用 $packageName") + if (showDialogIfVSpaceIsNeeded(context)) { return } @@ -335,6 +347,10 @@ object VHelper { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(intent) + DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName)?.let { + mLastSuccessfullyLaunchedGame = Pair(System.currentTimeMillis(), it.gameId) + } + updateLastPlayedTime(packageName) } catch (e: Exception) { ToastUtils.toast(e.localizedMessage ?: "") @@ -342,9 +358,11 @@ object VHelper { } if (mDelegateManager.isConnectAidlInterface) { - launchClosure.invoke() + checkStoragePermissionBeforeAction(context, launchClosure) } else { - connectService(launchClosure) + checkStoragePermissionBeforeAction(context) { + connectService(launchClosure) + } } } @@ -360,7 +378,7 @@ object VHelper { PackageObserver.onPackageChanged(EBPackage("卸载", packageName, "unknown")) } - Utils.log(LOG_TAG, "安装新应用结果 -> $result") + Utils.log(LOG_TAG, "卸载应用结果 -> $result") } catch (e: Exception) { ToastUtils.toast(e.localizedMessage ?: "") } @@ -387,7 +405,7 @@ object VHelper { } /** - * 根据包名获取 `下载实例` + * 根据包名获取下载快照 */ fun getDownloadEntitySnapshotByPackageName(packageName: String): DownloadEntity? { return DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName) @@ -500,7 +518,8 @@ object VHelper { ) ) icon = downloadEntity.icon - playedTime = if (lastPlayedTimeString == "") 0L else lastPlayedTimeString.toLong() + lastPlayedTime = if (lastPlayedTimeString == "") 0L else lastPlayedTimeString.toLong() + playedTime = mInstalledInfoList.firstOrNull { it.packageName == getUniquePackageName() }?.appTotalPlayTime ?: 0 downloadStatus = "smooth" setEntryMap(DownloadManager.getInstance().getEntryMap(name)) } diff --git a/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt b/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt index ecc8044d32..48cb01fa16 100644 --- a/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt +++ b/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt @@ -144,7 +144,7 @@ object VLoadCompleteWindowHelper { } } mBinding.launchTv.setOnClickListener { - VHelper.launch(activity, mAdapter.gameEntityList[mBinding.viewPager.currentItem].getApk()[0].packageName) + VHelper.installOrLaunch(activity, mAdapter.gameEntityList[mBinding.viewPager.currentItem].getApk()[0].packageName) } } } diff --git a/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt index bf5b32d1d6..982bc49af8 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt @@ -78,7 +78,7 @@ class VSpaceLoadingFragment : BaseFragment() { VHelper.getInstallationLiveData().observe(viewLifecycleOwner) { val currentPackageName = mGame?.getApk()?.firstOrNull()?.packageName if (it == currentPackageName) { - VHelper.launch(requireActivity(), currentPackageName!!) + VHelper.installOrLaunch(requireActivity(), currentPackageName!!) requireActivity().finish() } } diff --git a/vspace-bridge b/vspace-bridge index 6d91ee7416..4ad237b602 160000 --- a/vspace-bridge +++ b/vspace-bridge @@ -1 +1 @@ -Subproject commit 6d91ee74165c98fa2e8d65e5d3f0589a95774137 +Subproject commit 4ad237b60276f1f9bc9d6e7e0eeb0f1e12ad0fe6 From dce756e53f17ec118e1046a0220d6299fa9943ae Mon Sep 17 00:00:00 2001 From: juntao Date: Fri, 17 Jun 2022 17:14:34 +0800 Subject: [PATCH 035/217] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=81=87?= =?UTF-8?q?=E7=9A=84=E7=95=85=E7=8E=A9=E5=AE=89=E8=A3=85=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 1 + .../com/gh/common/util/PackageInstaller.kt | 2 +- .../adapter/viewholder/DetailViewHolder.java | 2 +- app/src/main/java/com/gh/vspace/VHelper.kt | 26 +++++++++++-- .../com/gh/vspace/VSpaceLoadingActivity.kt | 22 +++++++++-- .../com/gh/vspace/VSpaceLoadingFragment.kt | 37 ++++++++++++++++--- 6 files changed, 75 insertions(+), 15 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3bf65fa8db..d262639539 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -737,6 +737,7 @@ android:screenOrientation="portrait" /> Unit = { checkStoragePermissionBeforeAction(context) { + if (isManualInstall) { + val gameEntity = toGameEntity(downloadEntity) + context.startActivity( + VSpaceLoadingActivity.getIntent( + context, + gameEntity, + true + ) + ) + } + // 安装过程会比较漫长,所以得放在工作线程运行 AppExecutor.ioExecutor.execute { try { - val result = VirtualAppManager.get().installGame(filePath) + val result = VirtualAppManager.get().installGame(downloadEntity.path) if (result.status == 0) { updateInstalledList() showFloatingWindow(result.packageName) @@ -327,7 +338,12 @@ object VHelper { if (isInstalled(packageName)) { launch(context, packageName) } else { - install(context, getDownloadEntitySnapshotByPackageName(packageName)?.path ?: "") + val downloadEntity = getDownloadEntitySnapshotByPackageName(packageName) + if (downloadEntity != null) { + install(context, downloadEntity, true) + } else { + ToastUtils.toast("找不到下载文件") + } } } @@ -370,6 +386,8 @@ object VHelper { * 卸载应用 */ fun uninstall(packageName: String?) { + Utils.log(LOG_TAG, "卸载游戏 $packageName") + val uninstallClosure: () -> Unit = { try { val result = VirtualAppManager.get().uninstallGame(packageName) diff --git a/app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt b/app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt index 276f322a59..d01f2739e7 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceLoadingActivity.kt @@ -18,19 +18,33 @@ class VSpaceLoadingActivity : BaseActivity() { DisplayUtils.setLightStatusBar(this, true) if (savedInstanceState == null) { - val fragment = VSpaceLoadingFragment().apply { arguments = intent?.extras } - supportFragmentManager.beginTransaction() - .replace(R.id.placeholder, fragment).commitAllowingStateLoss() + resetFragment() } } override fun getLayoutId() = R.layout.activity_shell + override fun onNewIntent(intent: Intent?) { + super.onNewIntent(intent) + + resetFragment() + } + + private fun resetFragment() { + val fragment = VSpaceLoadingFragment().apply { arguments = intent?.extras } + supportFragmentManager.beginTransaction() + .replace(R.id.placeholder, fragment, VSpaceLoadingFragment::class.java.name) + .commitAllowingStateLoss() + } + companion object { + const val IS_INSTALLATION = "is_installation" + @JvmStatic - fun getIntent(context: Context, game: GameEntity): Intent { + fun getIntent(context: Context, game: GameEntity, isInstall: Boolean): Intent { val intent = Intent(context, VSpaceLoadingActivity::class.java) intent.putExtra(EntranceConsts.KEY_DATA, game) + intent.putExtra(IS_INSTALLATION, isInstall) return intent } } diff --git a/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt index 982bc49af8..f42bbbd5f6 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt @@ -1,7 +1,9 @@ package com.gh.vspace +import android.animation.ValueAnimator import android.os.Bundle import android.view.View +import android.view.animation.DecelerateInterpolator import com.gh.gamecenter.common.base.fragment.BaseFragment import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.core.utils.ToastUtils @@ -14,6 +16,7 @@ import com.lightgame.download.DownloadStatus.* class VSpaceLoadingFragment : BaseFragment() { + private var mIsInstallation = false private var mGame: GameEntity? = null private val mBinding: FragmentVspaceLoadingBinding by lazy { FragmentVspaceLoadingBinding.inflate( @@ -74,11 +77,18 @@ class VSpaceLoadingFragment : BaseFragment() { super.onViewCreated(view, savedInstanceState) mGame = arguments?.get(EntranceConsts.KEY_DATA) as GameEntity? + mIsInstallation = arguments?.get(VSpaceLoadingActivity.IS_INSTALLATION) as Boolean mGame?.let { initView(it, mBinding) } + + // 安装状态显示虚假的进度动画 + if (mIsInstallation) { + showFakeInstallationProgress(mBinding) + } + VHelper.getInstallationLiveData().observe(viewLifecycleOwner) { val currentPackageName = mGame?.getApk()?.firstOrNull()?.packageName if (it == currentPackageName) { - VHelper.installOrLaunch(requireActivity(), currentPackageName!!) + VHelper.launch(requireActivity(), currentPackageName!!) requireActivity().finish() } } @@ -90,20 +100,37 @@ class VSpaceLoadingFragment : BaseFragment() { binding.nameTv.text = gameEntity.name } - private fun showFakeLaunchProgress() { - // TODO 显示假的启动进度 + private fun showFakeInstallationProgress(binding: FragmentVspaceLoadingBinding) { + ValueAnimator.ofInt(0, 99).apply { + duration = 5000L + interpolator = DecelerateInterpolator() + addUpdateListener { + if (!isAdded) { + removeAllUpdateListeners() + return@addUpdateListener + } + + val progress = it.animatedValue as Int + binding.progressBar.progress = progress + binding.progressTv.text = "启动中${progress}%" + } + }.start() } override fun onResume() { super.onResume() - DataChanger.addObserver(mDataWatcher) + if (!mIsInstallation) { + DataChanger.addObserver(mDataWatcher) + } } override fun onPause() { super.onPause() - DataChanger.deleteObserver(mDataWatcher) + if (!mIsInstallation) { + DataChanger.deleteObserver(mDataWatcher) + } } } \ No newline at end of file From 6ae44c34d11aac5541ee75b40c6adf5c2965fc67 Mon Sep 17 00:00:00 2001 From: juntao Date: Mon, 20 Jun 2022 11:27:15 +0800 Subject: [PATCH 036/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E6=9B=B4=E6=96=B0=E4=B8=8D=E5=8F=8A=E6=97=B6=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/common/databind/BindingAdapters.java | 20 +++---- .../adapter/viewholder/DetailViewHolder.java | 52 ++++++++++--------- .../gh/vspace/HomeRecentVGameViewHolder.kt | 6 ++- 3 files changed, 43 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java index b7c6fece4a..aee9dd86ac 100644 --- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java +++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java @@ -382,15 +382,17 @@ public class BindingAdapters { return; } } - GamePermissionDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, gameEntity.getInfo(), () -> { - BrowserInstallHelper.showBrowserInstallHintDialog(v.getContext(), gameEntity.isVGame(), () -> { - PackageCheckDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, () -> { - DownloadDialogHelper.findAvailableDialogAndShow(v.getContext(), gameEntity, apk, () -> { - CertificationDialog.showCertificationDialog(v.getContext(), gameEntity, () -> { - DialogUtils.showVersionNumberDialog(v.getContext(), gameEntity, () -> { - DialogUtils.showOverseaDownloadDialog(v.getContext(), gameEntity, () -> { - DialogUtils.checkDownload(v.getContext(), apk.getSize(), - isSubscribe -> download(progressBar, gameEntity, traceEvent, isSubscribe, entrance, location)); + VHelper.checkVSpaceBeforeAction(v.getContext(), gameEntity, () -> { + GamePermissionDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, gameEntity.getInfo(), () -> { + BrowserInstallHelper.showBrowserInstallHintDialog(v.getContext(), gameEntity.isVGame(), () -> { + PackageCheckDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, () -> { + DownloadDialogHelper.findAvailableDialogAndShow(v.getContext(), gameEntity, apk, () -> { + CertificationDialog.showCertificationDialog(v.getContext(), gameEntity, () -> { + DialogUtils.showVersionNumberDialog(v.getContext(), gameEntity, () -> { + DialogUtils.showOverseaDownloadDialog(v.getContext(), gameEntity, () -> { + DialogUtils.checkDownload(v.getContext(), apk.getSize(), + isSubscribe -> download(progressBar, gameEntity, traceEvent, isSubscribe, entrance, location)); + }); }); }); }); diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java index 8d1a4ecb5d..302c6879d7 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java @@ -188,35 +188,37 @@ public class DetailViewHolder { case NORMAL: DataLogUtils.uploadGameLog(mViewHolder.context, mGameEntity.getId(), mGameEntity.getName(), mEntrance); case PLUGIN: - GamePermissionDialogFragment.show((AppCompatActivity) mViewHolder.context, mGameEntity, mGameEntity.getInfo(), () -> { - PermissionHelper.checkStoragePermissionBeforeAction(mViewHolder.context, () -> { - if (mGameEntity.getApk().size() == 1) { - ApkEntity apk = mGameEntity.getApk().get(0); - BrowserInstallHelper.showBrowserInstallHintDialog(mViewHolder.context, mGameEntity.isVGame(), () -> { - PackageCheckDialogFragment.show((AppCompatActivity) mViewHolder.context, mGameEntity, () -> { - DownloadDialogHelper.findAvailableDialogAndShow(mViewHolder.context, mGameEntity, apk, () -> { - CertificationDialog.showCertificationDialog(mViewHolder.context, mGameEntity, () -> { - DialogUtils.showVersionNumberDialog(mViewHolder.context, mGameEntity, () -> { - DialogUtils.showOverseaDownloadDialog(mViewHolder.context, mGameEntity, () -> { - DialogUtils.checkDownload(mViewHolder.context, apk.getSize(), this::download); + VHelper.checkVSpaceBeforeAction(mViewHolder.context, mGameEntity, () -> { + GamePermissionDialogFragment.show((AppCompatActivity) mViewHolder.context, mGameEntity, mGameEntity.getInfo(), () -> { + PermissionHelper.checkStoragePermissionBeforeAction(mViewHolder.context, () -> { + if (mGameEntity.getApk().size() == 1) { + ApkEntity apk = mGameEntity.getApk().get(0); + BrowserInstallHelper.showBrowserInstallHintDialog(mViewHolder.context, mGameEntity.isVGame(), () -> { + PackageCheckDialogFragment.show((AppCompatActivity) mViewHolder.context, mGameEntity, () -> { + DownloadDialogHelper.findAvailableDialogAndShow(mViewHolder.context, mGameEntity, apk, () -> { + CertificationDialog.showCertificationDialog(mViewHolder.context, mGameEntity, () -> { + DialogUtils.showVersionNumberDialog(mViewHolder.context, mGameEntity, () -> { + DialogUtils.showOverseaDownloadDialog(mViewHolder.context, mGameEntity, () -> { + DialogUtils.checkDownload(mViewHolder.context, apk.getSize(), this::download); + }); }); }); }); }); }); - }); - } else { - CertificationDialog.showCertificationDialog(mViewHolder.context, mGameEntity, () -> { - DialogUtils.showVersionNumberDialog(mViewHolder.context, mGameEntity, () -> { - DownloadDialog.showDownloadDialog( - mViewHolder.context, - mGameEntity, - mTraceEvent, - StringUtils.buildString(mEntrance, "+(", mName, "[", mTitle, "])"), - mName + ":" + mTitle); + } else { + CertificationDialog.showCertificationDialog(mViewHolder.context, mGameEntity, () -> { + DialogUtils.showVersionNumberDialog(mViewHolder.context, mGameEntity, () -> { + DownloadDialog.showDownloadDialog( + mViewHolder.context, + mGameEntity, + mTraceEvent, + StringUtils.buildString(mEntrance, "+(", mName, "[", mTitle, "])"), + mName + ":" + mTitle); + }); }); - }); - } + } + }); }); }); break; @@ -368,12 +370,12 @@ public class DetailViewHolder { } else { method = mViewHolder.context.getString(R.string.download); } - + if (mGameEntity.getApk().size() == 0) { Utils.toast(mViewHolder.context, "暂时无法下载,请稍后再试"); return; } - + ApkEntity apkEntity = mGameEntity.getApk().get(0); String msg = FileUtils.isCanDownload(mViewHolder.context, apkEntity.getSize()); if (TextUtils.isEmpty(msg)) { diff --git a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt index e40f8bbfe3..fa227c2314 100644 --- a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt +++ b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt @@ -74,8 +74,12 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter(con } } + override fun areItemsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean { + return false + } + override fun areContentsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean { - return oldItem?.id == newItem?.id && oldItem?.playedTime == newItem?.playedTime + return false } class HomeRecentVGameItemViewHolder(private var mBinding: ItemHomeVgameBinding) : From 36704af5314cea2d3b228a85e9e2ca644590219b Mon Sep 17 00:00:00 2001 From: juntao Date: Mon, 20 Jun 2022 14:41:37 +0800 Subject: [PATCH 037/217] =?UTF-8?q?feat:=20UI=20=E7=BB=86=E8=8A=82?= =?UTF-8?q?=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/common/util/DetailDownloadUtils.java | 11 ++++++++--- .../adapter/viewholder/DetailViewHolder.java | 3 +++ .../com/gh/vspace/VDownloadManagerFragment.kt | 4 +++- .../ic_smooth_game_button_hint.png | Bin 0 -> 1178 bytes .../main/res/layout/detail_download_item.xml | 17 ++++++++++++++++- 5 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_smooth_game_button_hint.png diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index da62befa1e..7338f07690 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -30,6 +30,8 @@ public class DetailDownloadUtils { public static void detailInitDownload(DetailViewHolder viewHolder, boolean isCheck) { String downloadAddWord = viewHolder.gameEntity.getDownloadAddWord(); + viewHolder.overlayTv.setVisibility(View.GONE); + if (viewHolder.gameEntity != null && Config.isShowDownload(viewHolder.gameEntity.getId()) && !"光环助手".equals(viewHolder.gameEntity.getName())) { @@ -103,7 +105,8 @@ public class DetailDownloadUtils { downloadText = "升级" + (TextUtils.isEmpty(downloadAddWord) ? "" : "至" + downloadAddWord) + getDownloadSizeText(viewHolder); } else if (viewHolder.context.getString(R.string.launch).equals(status)) { if (viewHolder.gameEntity.isVGame()) { - downloadText = viewHolder.context.getString(R.string.smooth_launch); + downloadText = ""; + viewHolder.overlayTv.setVisibility(View.VISIBLE); } else { downloadText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : "-" + downloadAddWord); } @@ -149,6 +152,7 @@ public class DetailDownloadUtils { } viewHolder.mDownloadPb.setProgress((int) (viewHolder.downloadEntity.getPercent() * 10)); + viewHolder.overlayTv.setVisibility(View.GONE); switch (downloadEntity.getStatus()) { case downloading: case pause: @@ -191,12 +195,13 @@ public class DetailDownloadUtils { } } else if (viewHolder.gameEntity.isVGame()) { if (VHelper.isInstalled(downloadEntity.getPackageName())) { - viewHolder.mDownloadPb.setText(R.string.smooth_launch); viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.LAUNCH_OR_OPEN); } else { - viewHolder.mDownloadPb.setText(R.string.smooth_launch); viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL); } + + viewHolder.mDownloadPb.setText(""); + viewHolder.overlayTv.setVisibility(View.VISIBLE); } else { if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL)) { viewHolder.mDownloadPb.setText(R.string.browser_install_install); diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java index 302c6879d7..3fce0dca45 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java @@ -4,6 +4,7 @@ import android.content.Context; import android.content.Intent; import android.text.TextUtils; import android.view.View; +import android.widget.TextView; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; @@ -77,12 +78,14 @@ public class DetailViewHolder { public View downloadBottom; public DownloadProgressBar mDownloadPb; + public TextView overlayTv; // 额外的文字 (用于一些含图片的情况) // 注意View的命名 public DetailViewHolder(View view, GameEntity gameEntity, DownloadEntity downloadEntity, boolean isNewsDetail, String entrance, String name, String title, @Nullable ExposureEvent traceEvent) { downloadBottom = view.findViewById(R.id.detail_ll_bottom); mDownloadPb = view.findViewById(R.id.detail_progressbar); + overlayTv = view.findViewById(R.id.overlayTv); this.gameEntity = gameEntity; this.downloadEntity = downloadEntity; diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index 90bb4ad953..5a5395283d 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -79,8 +79,10 @@ class VDownloadManagerFragment : val status = mBinding.switchIv.isChecked val anime = if (status) "lottie/switch_turnoff.json" else "lottie/switch_turnon.json" mBinding.switchLottie.setAnimation(anime) + mBinding.switchLottie.doOnAnimationEnd { + mBinding.switchIv.isChecked = !status + } mBinding.switchLottie.playAnimation() - mBinding.switchIv.isChecked = !status SPUtils.setBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, !status) DownloadManager.getInstance().notifyDownloadLiveDataChanged() diff --git a/app/src/main/res/drawable-xxxhdpi/ic_smooth_game_button_hint.png b/app/src/main/res/drawable-xxxhdpi/ic_smooth_game_button_hint.png new file mode 100644 index 0000000000000000000000000000000000000000..1ebef1cc35985c8f375edc8a45c80afff165927f GIT binary patch literal 1178 zcmV;L1ZDe)P)Px(R7pfZRA@upTK`cMK@3hhfDWJnr30xzsX(a!sX(kitw1^uE07MP1F!<=AkOz@ z@6Ek?$tJnoyT`bHF>^~c-{#ks>|^@R7f11l$U7psBBD3Z|5;$)GZEbp(KR#UZ+C?N zipU2d`tC|wZ^HvKpGA&~0(>N*lZe0-_gpYDtXW+yKoNOOM87>j2l)PtnLm2xMgYDv z_Z%>NX6Bn701^5 zAt-c%5hb)eB7&rb^1<;~Np&l%&$s`UD7I4+KMupV4k8E+S+>^b?oc@mV3!V}ToiaL+8&StcYfjl6cG>H z9!J&yHg^!EV55$X2UTzxj2S|G+!SnJHl&U)G=R+=goxCpZ~zEp+;PJI(zvkk9o#YV zh2{Yoz@`o&aMREuWliV8APeL}9RzCt#fXJa2O%Psi)&(CYdROUlQE+fv;c-0O%btN z+{z(UYdQd3+L&?CK|#0z3hA|`vExp)L}^;nn6Ay6izW!~-T@uj9o3peE@ne0JGfw+ z9U7Tv7DQ?XQ_wnzu?6;scdbcApH^C-$Qy?nn_kTvzFSl+k|;EQR=cy|u*DK!A@2hU zrZTN1uhtKGAoqxOg(L1v!OPqQtYmR(dQ&whfE#}`8s8%Z0B(m5W;yH(Yl4QQ>7M&G z5pbo=77>}nVUyNO&trQ6wB{-96g*)~cn|7v==oZ0m!cL^$gnk}3g3FMCdxrAgS*9j ztXoeDHVvtY6){Qhe&mpvs&@g{GNdZW3G-KEZLjvGUY5GKXoX-`hg5|az$GK)0{W&O zU3*#3BG@WlEEyMd&~wKjobb?tSWeGldjSmfki{JV%>8vlK?XK6tNvA~S|*c5U!g<< zafVXj#Tky@kO_*=BD3UT@<5*NO#^X?XL~c>-wQj*R;PjK$HPwQH@J3lJ-{xSPDJBjoX|>)BfrJ shXYH=IO@efvOui;O-ZJg5=+YY2PEVvS6 @@ -279,6 +279,21 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/iv_switch" app:layout_constraintTop_toTopOf="parent" /> + + From 0f9b3c94f00ae507b845c5218955bccfb33e1928 Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 21 Jun 2022 10:48:06 +0800 Subject: [PATCH 038/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=83=A8?= =?UTF-8?q?=E5=88=86=20UI=20=E9=97=AE=E9=A2=98=20https://git.shanqu.cc/pm/?= =?UTF-8?q?halo/halo-app-issues/-/issues/1923#note=5F154774?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/view/SimpleToggleView.kt | 26 ++++++++++ .../gamedetail/video/TopVideoView.kt | 26 +++++----- .../gh/gamecenter/mygame/PlayedGameAdapter.kt | 4 +- .../gh/vspace/HomeRecentVGameViewHolder.kt | 24 +++++++--- .../com/gh/vspace/VDownloadManagerFragment.kt | 45 ++++++++---------- .../com/gh/vspace/VFeedbackDialogFragment.kt | 5 +- .../ic_smooth_load_in_background.png | Bin 0 -> 974 bytes .../ic_smooth_load_in_background.webp | Bin 684 -> 0 bytes .../bg_home_vgame_progress_active.xml | 5 +- .../bg_home_vgame_progress_inactive.xml | 4 +- ...d_16.xml => border_10p_black_round_16.xml} | 4 +- .../main/res/layout/detail_download_item.xml | 5 +- .../main/res/layout/dialog_vgame_feedback.xml | 23 ++++++--- app/src/main/res/layout/dialog_vspace.xml | 2 +- .../res/layout/fragment_vdownload_manager.xml | 39 +-------------- .../fragment_vdownload_manager_wrapper.xml | 7 +++ .../res/layout/fragment_vspace_loading.xml | 24 +++++----- .../res/layout/item_home_recent_vgame.xml | 42 ++++++++++++---- .../layout/item_vgame_download_manager.xml | 15 ++++-- .../layout/layout_menu_download_manager.xml | 2 +- ...usage_stats.xml => view_simple_toggle.xml} | 22 +++++++-- 21 files changed, 191 insertions(+), 133 deletions(-) create mode 100644 app/src/main/java/com/gh/common/view/SimpleToggleView.kt create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_smooth_load_in_background.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_smooth_load_in_background.webp rename app/src/main/res/drawable/{border_eee_round_16.xml => border_10p_black_round_16.xml} (73%) rename app/src/main/res/layout/{item_usage_stats.xml => view_simple_toggle.xml} (61%) diff --git a/app/src/main/java/com/gh/common/view/SimpleToggleView.kt b/app/src/main/java/com/gh/common/view/SimpleToggleView.kt new file mode 100644 index 0000000000..68474e6ec3 --- /dev/null +++ b/app/src/main/java/com/gh/common/view/SimpleToggleView.kt @@ -0,0 +1,26 @@ +package com.gh.common.view + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import android.widget.TextView +import androidx.constraintlayout.widget.ConstraintLayout +import com.airbnb.lottie.LottieAnimationView +import com.gh.gamecenter.R +import com.lightgame.view.CheckableImageView + +class SimpleToggleView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : ConstraintLayout(context, attrs, defStyleAttr) { + + val switchIv by lazy { findViewById(R.id.switchIv) } + val hintTv by lazy { findViewById(R.id.hintTv) } + val lottieView by lazy { findViewById(R.id.lottieView)} + + init { + View.inflate(context, R.layout.view_simple_toggle, this) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/video/TopVideoView.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/video/TopVideoView.kt index 307101cd83..757dd31b6c 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/video/TopVideoView.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/video/TopVideoView.kt @@ -11,20 +11,20 @@ import android.widget.SeekBar import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager -import com.gh.gamecenter.common.observer.MuteCallback -import com.gh.gamecenter.common.observer.VolumeObserver -import com.gh.gamecenter.core.runOnIoThread -import com.gh.gamecenter.core.runOnUiThread -import com.gh.common.util.* +import com.gh.common.util.LogUtils import com.gh.download.cache.ExoCacheManager import com.gh.gamecenter.R -import com.gh.gamecenter.core.utils.StringUtils -import com.gh.gamecenter.common.utils.debounceActionWithInterval -import com.gh.gamecenter.common.utils.rxTimer +import com.gh.gamecenter.common.observer.MuteCallback +import com.gh.gamecenter.common.observer.VolumeObserver import com.gh.gamecenter.common.utils.ImageUtils import com.gh.gamecenter.common.utils.NetworkUtils +import com.gh.gamecenter.common.utils.debounceActionWithInterval +import com.gh.gamecenter.common.utils.rxTimer +import com.gh.gamecenter.core.runOnIoThread +import com.gh.gamecenter.core.runOnUiThread import com.gh.gamecenter.core.utils.MD5Utils import com.gh.gamecenter.core.utils.MtaHelper +import com.gh.gamecenter.core.utils.StringUtils import com.gh.gamecenter.entity.GameDetailEntity import com.gh.gamecenter.gamedetail.GameDetailViewModel import com.gh.gamecenter.home.video.ScrollCalculatorHelper @@ -41,7 +41,7 @@ import java.util.* class TopVideoView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : StandardGSYVideoPlayer(context, attrs) { private var mMuteCallback: MuteCallback - private var mVolumeObserver: VolumeObserver + private var mVolumeObserver: VolumeObserver? = null var gameName = "" var video: GameDetailEntity.Video? = null @@ -84,7 +84,9 @@ class TopVideoView @JvmOverloads constructor(context: Context, attrs: AttributeS } } - mVolumeObserver = VolumeObserver(mMuteCallback) + if (!isInEditMode) { + mVolumeObserver = VolumeObserver(mMuteCallback) + } setBackFromFullScreenListener { if (it.id == R.id.fullscreen) { @@ -115,14 +117,14 @@ class TopVideoView @JvmOverloads constructor(context: Context, attrs: AttributeS fun observeVolume(fragment: Fragment?) { fragment?.context?.applicationContext?.contentResolver?.registerContentObserver( - android.provider.Settings.System.CONTENT_URI, true, mVolumeObserver + android.provider.Settings.System.CONTENT_URI, true, mVolumeObserver!! ) fragment?.fragmentManager?.registerFragmentLifecycleCallbacks( object : FragmentManager.FragmentLifecycleCallbacks() { override fun onFragmentPaused(fm: FragmentManager, f: Fragment) { if (f === fragment) { - fragment.context?.applicationContext?.contentResolver?.unregisterContentObserver(mVolumeObserver) + fragment.context?.applicationContext?.contentResolver?.unregisterContentObserver(mVolumeObserver!!) fragment.fragmentManager?.unregisterFragmentLifecycleCallbacks(this) } } diff --git a/app/src/main/java/com/gh/gamecenter/mygame/PlayedGameAdapter.kt b/app/src/main/java/com/gh/gamecenter/mygame/PlayedGameAdapter.kt index 6ea5d76125..7010c26614 100644 --- a/app/src/main/java/com/gh/gamecenter/mygame/PlayedGameAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/mygame/PlayedGameAdapter.kt @@ -33,7 +33,7 @@ import com.gh.gamecenter.common.callback.ConfirmListener import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.* import com.gh.gamecenter.databinding.ItemPlayedGameBinding -import com.gh.gamecenter.databinding.ItemUsageStatsBinding +import com.gh.gamecenter.databinding.ViewSimpleToggleBinding import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.eventbus.EBDownloadStatus import com.lightgame.download.DownloadEntity @@ -340,7 +340,7 @@ open class PlayedGameAdapter( } } - class UsageStatsViewHolder(var binding: ItemUsageStatsBinding) : RecyclerView.ViewHolder(binding.root) + class UsageStatsViewHolder(var binding: ViewSimpleToggleBinding) : RecyclerView.ViewHolder(binding.root) fun resetListData() { if (!hasHeader()) EnergyTaskHelper.postEnergyTask("open_game_time") diff --git a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt index fa227c2314..5d190c7cbd 100644 --- a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt +++ b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt @@ -4,12 +4,14 @@ import android.content.Context import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.RecyclerView.OnScrollListener import com.gh.download.DownloadManager import com.gh.gamecenter.R import com.gh.gamecenter.baselist.DiffUtilAdapter import com.gh.gamecenter.common.utils.goneIf import com.gh.gamecenter.common.utils.toBinding import com.gh.gamecenter.common.utils.toDrawable +import com.gh.gamecenter.common.utils.visibleIf import com.gh.gamecenter.common.view.GridSpacingItemColorDecoration import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.core.runOnUiThread @@ -26,14 +28,22 @@ class HomeRecentVGameViewHolder(var binding: ItemHomeRecentVgameBinding) : fun bindView(gameList: ArrayList) { if (binding.recyclerView.adapter == null) { - binding.recyclerView.layoutManager = - LinearLayoutManager(binding.root.context, RecyclerView.HORIZONTAL, false) + val layoutManager = LinearLayoutManager(binding.root.context, RecyclerView.HORIZONTAL, false) + + binding.recyclerView.layoutManager = layoutManager binding.recyclerView.itemAnimator = null binding.recyclerView.adapter = HomeRecentVGameAdapter(binding.root.context) binding.recyclerView.addItemDecoration( GridSpacingItemColorDecoration(binding.root.context, 4, 0, R.color.transparent) ) + binding.recyclerView.addOnScrollListener(object: OnScrollListener() { + override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { + val scrollToEnd = layoutManager.findLastCompletelyVisibleItemPosition() == (binding.recyclerView.adapter!!.itemCount - 1) + binding.divider.visibleIf(scrollToEnd) + } + }) + binding.moreTv.setOnClickListener { binding.root.context.startActivity( VDownloadManagerActivity.getIntent(binding.root.context, false) @@ -116,7 +126,8 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter(con var controlText = "继续" if (downloadEntity.status == DownloadStatus.done - && VHelper.getLastPlayedTime(downloadEntity) == 0L) { + && VHelper.getLastPlayedTime(downloadEntity) == 0L + ) { shouldShowDot = true } @@ -180,9 +191,10 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter(con if (shouldShowUpdate) { binding.root.setOnClickListener { - PackagesManager.getUpdateList().firstOrNull { it.id == downloadEntity.gameId }?.let { - VHelper.update(downloadEntity, it) - } + PackagesManager.getUpdateList().firstOrNull { it.id == downloadEntity.gameId } + ?.let { + VHelper.update(downloadEntity, it) + } } } mBinding.controlTv.text = controlText diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index 5a5395283d..7b3aec3722 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -10,7 +10,6 @@ import com.gh.gamecenter.baselist.ListAdapter import com.gh.gamecenter.baselist.ListFragment import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.utils.* -import com.gh.gamecenter.common.view.CustomDividerItemDecoration import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.databinding.FragmentVdownloadManagerBinding import com.gh.gamecenter.entity.GameEntity @@ -71,21 +70,25 @@ class VDownloadManagerFragment : mSkeletonScreen = Skeleton.bind(mBinding.listSkeleton).shimmer(false) .load(R.layout.fragment_subject_skeleton).show() - mBinding.headerContainer.goneIf(mViewModel.type != VDownloadManagerViewModel.TYPE_DOWNLOADED) - mBinding.switchIv.enlargeTouchArea() - mBinding.switchIv.isChecked = SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, true) - mBinding.switchIv.setOnClickListener { - if (mBinding.switchLottie.isAnimating) return@setOnClickListener - val status = mBinding.switchIv.isChecked - val anime = if (status) "lottie/switch_turnoff.json" else "lottie/switch_turnon.json" - mBinding.switchLottie.setAnimation(anime) - mBinding.switchLottie.doOnAnimationEnd { - mBinding.switchIv.isChecked = !status - } - mBinding.switchLottie.playAnimation() - SPUtils.setBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, !status) + mBinding.headerContainer.run { + goneIf(mViewModel.type != VDownloadManagerViewModel.TYPE_DOWNLOADED) + switchIv.enlargeTouchArea() + hintTv.text = "首页展示“最近在玩”板块" + switchIv.isChecked = SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, true) + switchIv.enlargeTouchArea() + switchIv.setOnClickListener { + if (lottieView.isAnimating) return@setOnClickListener + val status = switchIv.isChecked + val anime = if (status) "lottie/switch_turnoff.json" else "lottie/switch_turnon.json" + lottieView.setAnimation(anime) + lottieView.doOnAnimationEnd { + switchIv.isChecked = !status + } + lottieView.playAnimation() + SPUtils.setBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, !status) - DownloadManager.getInstance().notifyDownloadLiveDataChanged() + DownloadManager.getInstance().notifyDownloadLiveDataChanged() + } } } @@ -93,17 +96,7 @@ class VDownloadManagerFragment : mAdapter.changeOption(option) } - override fun getItemDecoration(): RecyclerView.ItemDecoration { - val itemDecoration = CustomDividerItemDecoration( - requireContext(), - onlyDecorateTheFirstItem = false, - notDecorateTheFirstItem = false, - notDecorateTheLastItem = true, - notDecorateTheFirstTwoItems = false - ) - itemDecoration.setDrawable(R.drawable.divider_item_line_space_16.toDrawable()!!) - return itemDecoration - } + override fun getItemDecoration(): RecyclerView.ItemDecoration? = null override fun shouldLoadMore() = false diff --git a/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt b/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt index 4f15d22bd7..ea98f074cd 100644 --- a/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt +++ b/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt @@ -75,6 +75,7 @@ class VFeedbackDialogFragment : BaseDialogFragment() { updateSubmitButton() } + mBinding.dontShowAgainTv.enlargeTouchArea() mBinding.dontShowAgainTv.setOnClickListener { VFeedbackSuppressedSimpleDao().add(mGame?.id ?: "") dismissAllowingStateLoss() @@ -104,7 +105,7 @@ class VFeedbackDialogFragment : BaseDialogFragment() { val width = DisplayUtils.getScreenWidth() val height = ViewGroup.LayoutParams.WRAP_CONTENT dialog?.window?.setLayout(width, height) - dialog?.setCanceledOnTouchOutside(false) + dialog?.setCanceledOnTouchOutside(true) } private fun addChildToFlexboxLayout(feedbackTag: FeedbackTag) { @@ -112,7 +113,7 @@ class VFeedbackDialogFragment : BaseDialogFragment() { binding.feedbackTagTv.width = (DisplayUtils.getScreenWidth() - 58F.dip2px()) / 2 binding.feedbackTagTv.text = feedbackTag.tagName if (feedbackTag.checked) { - binding.feedbackTagTv.setTextColor(R.color.text_title.toColor(requireContext())) + binding.feedbackTagTv.setTextColor(R.color.theme_font.toColor(requireContext())) binding.feedbackTagTv.setBackgroundResource(R.drawable.bg_vfeedback_label_selected) } else { binding.feedbackTagTv.setTextColor(R.color.text_subtitle.toColor(requireContext())) diff --git a/app/src/main/res/drawable-xxxhdpi/ic_smooth_load_in_background.png b/app/src/main/res/drawable-xxxhdpi/ic_smooth_load_in_background.png new file mode 100644 index 0000000000000000000000000000000000000000..245ee7f7b82691ff0f144c108fa2b7d67ce10bb0 GIT binary patch literal 974 zcmV;<12O!GP)@~0drDELIAGL9O(c600d`2O+f$vv5yPlAS&5)m*fPc%dSEei6UhYastc=;z)^;AkA@hs@2fLC#2^qifJkQLVH`w1`P)HPu#oXH3TER5Uy~$*f$Hy`ZBS#Sc zb9FG6i%)wz9)BMWhmBgT)(N9)%(?)ETN@i2=a{${mBC?vd)4~=eg%%Wf!FB-9P#z_ z^)kMeC|)>&!JwjB5zzsTI*k8@uNEZ(E}S@!R>Pbgfbsc+8PD(ndVGAGpB6k@fdoc= z8ZTDjp93oAA1T0it`?|5_0ee5L`7=f-rl+t0XVWK5>_UYDd6;Q#^vn9uD>U;{;1lp zR)At-dwcuHahy=)Z5~vs)iw_NX`G&(+Hl4uy(5;g^@2~l6;P@3GvFQ<_xJY>tq>XM9YH~GO#5~5T-P(pyJ z)YOdU*#S!uZfeHm^U{!zbGLHNadVK|2a|z;zsH~+(;dW8>s_v zBXuBdqz=T5)PcB>r3HbP?J{15O3O0VidwIMg}7Kmf1wqC@s~K*QPAybj*{Ym=7yoa+PuQdT#7_4X6 zVxaPHRkC$*pSLxhC^#5A4^Rlz_FNW;Qi^)@fBbeZUOPK1cEDdyJ zEao{e_g;v8w7a#nwd;3^3}K=~H~COH51vwu&mJXMfXH&yaVdH5Y@6mu#YT4mSK>wF zePpDoTdh`SXJ@Alr8mgO4-_MK!=gL-`TF|$w-6xSN|>|9xG)=@(y!=)VKEkrb)D%zSlU zfLc3l=gZIDa~s?AP%}L=^Gr>m?GKtd`nbJl>@8#><7zuM7M}!L$cp%T|Q9dkrlf9Bg|X6d?(D4y8H@VUWP881B(9x zI#y6PAf^ET01yoTodGI105||XDG-H1p`i}=3;{w~Km~FK;0Jp@+dl?BU@T?+75+D8 zkYbtn0Q&*{tL)F>kNQ6Z-%;P?f84(HVA$DjW&27@GfxwR}tbYRsU6KEcmA znNv>nn-ZUY{`o)bk7e=ZG`|_W71pr7_TT2*N7e53O$>F-zt4WOp~<2OcdKUaiPhe2 zp+U;s=KeIzZ~T$s{3G3HM{bqRC5*f1djqu7=bXO$49f zJ)jpZq@LI<==>LTA^UwEcl}WseE@ND=w-!pCXOp8YMAF_z=1aCI{KhT$ibb~#kiq{D9yMt1!IQ^1bx6iv zj{t=a|K~yJKfVGJyN-+a?{&ZN01su4e+Q&Vh})&z!s@U|b+ Sgy=uXry}+sG=97Q00002i$=8o diff --git a/app/src/main/res/drawable/bg_home_vgame_progress_active.xml b/app/src/main/res/drawable/bg_home_vgame_progress_active.xml index 7b7b58ed9e..41008d3c83 100644 --- a/app/src/main/res/drawable/bg_home_vgame_progress_active.xml +++ b/app/src/main/res/drawable/bg_home_vgame_progress_active.xml @@ -10,7 +10,8 @@ - + @@ -18,7 +19,7 @@ android:width="1dp" android:color="@color/white" /> - + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_home_vgame_progress_inactive.xml b/app/src/main/res/drawable/bg_home_vgame_progress_inactive.xml index 2b643c6188..895d0ddab5 100644 --- a/app/src/main/res/drawable/bg_home_vgame_progress_inactive.xml +++ b/app/src/main/res/drawable/bg_home_vgame_progress_inactive.xml @@ -10,7 +10,7 @@ - + @@ -18,7 +18,7 @@ android:width="2dp" android:color="@color/transparent" /> - + \ No newline at end of file diff --git a/app/src/main/res/drawable/border_eee_round_16.xml b/app/src/main/res/drawable/border_10p_black_round_16.xml similarity index 73% rename from app/src/main/res/drawable/border_eee_round_16.xml rename to app/src/main/res/drawable/border_10p_black_round_16.xml index e7ecd984db..375f02f27f 100644 --- a/app/src/main/res/drawable/border_eee_round_16.xml +++ b/app/src/main/res/drawable/border_10p_black_round_16.xml @@ -4,9 +4,9 @@ + android:color="@color/black_alpha_10" /> - + \ No newline at end of file diff --git a/app/src/main/res/layout/detail_download_item.xml b/app/src/main/res/layout/detail_download_item.xml index 528ac5bd39..6109b9811e 100644 --- a/app/src/main/res/layout/detail_download_item.xml +++ b/app/src/main/res/layout/detail_download_item.xml @@ -155,8 +155,8 @@ android:id="@+id/iv_vmode_badge" android:layout_width="12dp" android:layout_height="12dp" - android:layout_marginStart="-6dp" - android:layout_marginBottom="-6dp" + android:layout_marginStart="-8dp" + android:layout_marginBottom="-8dp" android:src="@drawable/ic_switch_game_smooth" android:visibility="gone" app:layout_constraintBottom_toTopOf="@id/iv_vmode" @@ -183,6 +183,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="gone" + tools:visibility="visible" app:constraint_referenced_ids="iv_vmode,tv_vmode,iv_vmode_badge" /> - + app:cardCornerRadius="12dp" + app:cardElevation="0dp" + app:layout_constraintTop_toTopOf="parent"> - \ No newline at end of file + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_vspace.xml b/app/src/main/res/layout/dialog_vspace.xml index a5da088365..34b417a5f2 100644 --- a/app/src/main/res/layout/dialog_vspace.xml +++ b/app/src/main/res/layout/dialog_vspace.xml @@ -44,7 +44,7 @@ - - - - - - - - - + app:layout_constraintTop_toTopOf="parent" /> + + + android:fitsSystemWindows="true"> + + + - - @@ -41,7 +41,7 @@ android:layout_width="14dp" android:layout_height="14dp" android:layout_centerVertical="true" - android:layout_marginStart="10dp" + android:layout_marginStart="12dp" android:src="@drawable/ic_smooth_load_in_background" /> diff --git a/app/src/main/res/layout/item_home_recent_vgame.xml b/app/src/main/res/layout/item_home_recent_vgame.xml index 5175c90a77..f3373cad1c 100644 --- a/app/src/main/res/layout/item_home_recent_vgame.xml +++ b/app/src/main/res/layout/item_home_recent_vgame.xml @@ -1,6 +1,7 @@ + app:layout_constraintTop_toTopOf="@id/hintIv" /> - + app:layout_constraintStart_toStartOf="parent"> + + + + + + + android:padding="@dimen/home_item_padding" + android:paddingStart="16dp" + android:paddingTop="8dp" + android:paddingEnd="16dp" + android:paddingBottom="8dp"> + app:layout_constraintTop_toTopOf="parent" + app:layout_goneMarginStart="0dp" /> + app:layout_constraintTop_toTopOf="parent" + app:textSize="12sp" /> diff --git a/app/src/main/res/layout/layout_menu_download_manager.xml b/app/src/main/res/layout/layout_menu_download_manager.xml index 20b0184492..20a70e2b9f 100644 --- a/app/src/main/res/layout/layout_menu_download_manager.xml +++ b/app/src/main/res/layout/layout_menu_download_manager.xml @@ -19,7 +19,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@id/iconIv" - android:layout_marginRight="8dp" + android:layout_marginEnd="16dp" android:includeFontPadding="false" android:text="畅玩管理" android:textColor="@color/text_subtitle" diff --git a/app/src/main/res/layout/item_usage_stats.xml b/app/src/main/res/layout/view_simple_toggle.xml similarity index 61% rename from app/src/main/res/layout/item_usage_stats.xml rename to app/src/main/res/layout/view_simple_toggle.xml index 4be08254e5..da1cffb28f 100644 --- a/app/src/main/res/layout/item_usage_stats.xml +++ b/app/src/main/res/layout/view_simple_toggle.xml @@ -3,11 +3,12 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="40dp" - android:paddingLeft="16dp" - android:background="@color/text_FAFAFA" - android:paddingRight="16dp"> + android:background="@color/bg_F8F8F8" + android:paddingStart="16dp" + android:paddingEnd="16dp"> + + \ No newline at end of file From ee21dbc643453d28dcb68349aa0bfdaf7d9bf2c8 Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 21 Jun 2022 16:52:11 +0800 Subject: [PATCH 039/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=83=A8?= =?UTF-8?q?=E5=88=86=E4=BB=A3=E7=A0=81=E9=97=AE=E9=A2=98=20https://git.sha?= =?UTF-8?q?nqu.cc/pm/halo/halo-app-issues/-/issues/1923#note=5F154823?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/common/constant/Config.java | 2 +- .../gh/common/databind/BindingAdapters.java | 2 +- .../com/gh/common/util/DownloadItemUtils.kt | 2 +- .../com/gh/common/util/DownloadObserver.kt | 17 ++- .../common/util/GameActivityDownloadHelper.kt | 23 +-- .../adapter/viewholder/DetailViewHolder.java | 2 +- .../com/gh/gamecenter/entity/AppEntity.kt | 26 ++-- .../retrofit/service/VApiService.kt | 3 +- app/src/main/java/com/gh/vspace/VHelper.kt | 144 +++++++++++++----- .../com/gh/vspace/VSpaceDialogFragment.kt | 45 ++++-- 10 files changed, 180 insertions(+), 86 deletions(-) diff --git a/app/src/main/java/com/gh/common/constant/Config.java b/app/src/main/java/com/gh/common/constant/Config.java index 20c8e6e6da..1f4b0583d5 100644 --- a/app/src/main/java/com/gh/common/constant/Config.java +++ b/app/src/main/java/com/gh/common/constant/Config.java @@ -25,6 +25,7 @@ import com.gh.gamecenter.eventbus.EBReuse; import com.gh.gamecenter.common.retrofit.BiResponse; import com.gh.gamecenter.common.retrofit.Response; import com.gh.gamecenter.retrofit.RetrofitManager; +import com.gh.vspace.VHelper; import com.halo.assistant.HaloApp; import com.lightgame.utils.Utils; @@ -328,7 +329,6 @@ public class Config { RetrofitManager.getInstance() .getVApi().getSettings(BuildConfig.VERSION_NAME) .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) .subscribe(new BiResponse() { @Override public void onSuccess(VSetting data) { diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java index aee9dd86ac..e711f27034 100644 --- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java +++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java @@ -382,7 +382,7 @@ public class BindingAdapters { return; } } - VHelper.checkVSpaceBeforeAction(v.getContext(), gameEntity, () -> { + VHelper.checkVSpaceBeforeAction(v.getContext(), gameEntity, true, () -> { GamePermissionDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, gameEntity.getInfo(), () -> { BrowserInstallHelper.showBrowserInstallHintDialog(v.getContext(), gameEntity.isVGame(), () -> { PackageCheckDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, () -> { diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index 286aa1a621..a6b8f85a3a 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -701,7 +701,7 @@ object DownloadItemUtils { CertificationDialog.showCertificationDialog(context, gameEntity) { DialogUtils.showVersionNumberDialog(context, gameEntity) { DialogUtils.showOverseaDownloadDialog(context, gameEntity) { - VHelper.checkVSpaceBeforeAction(context, gameEntity) { + VHelper.checkVSpaceBeforeAction(context, gameEntity, true) { DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent) } diff --git a/app/src/main/java/com/gh/common/util/DownloadObserver.kt b/app/src/main/java/com/gh/common/util/DownloadObserver.kt index 3c2d86c516..4b6c65be44 100644 --- a/app/src/main/java/com/gh/common/util/DownloadObserver.kt +++ b/app/src/main/java/com/gh/common/util/DownloadObserver.kt @@ -16,8 +16,8 @@ import com.gh.gamecenter.common.eventbus.EBShowDialog import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.GsonUtils -import com.gh.gamecenter.core.utils.StringUtils import com.gh.gamecenter.core.utils.MtaHelper +import com.gh.gamecenter.core.utils.StringUtils import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.entity.SimpleGameEntity @@ -26,6 +26,7 @@ import com.gh.gamecenter.eventbus.EBDownloadStatus import com.gh.gamecenter.retrofit.RetrofitManager import com.gh.gamecenter.setting.GameDownloadSettingFragment import com.gh.gamecenter.suggest.SuggestType +import com.gh.vspace.VHelper import com.halo.assistant.HaloApp import com.lightgame.download.DataWatcher import com.lightgame.download.DownloadEntity @@ -216,10 +217,20 @@ object DownloadObserver { ) ) downloadEntity.isPlugin -> Utils.toast(mApplication, downloadEntity.name + " - " + platform + " - 下载完成") - else -> Utils.toast(mApplication, downloadEntity.name + " - 下载完成") + else -> { + if (downloadEntity.isSmoothGame()) { + VHelper.showFloatingWindow(downloadEntity.packageName) + } else { + Utils.toast(mApplication, downloadEntity.name + " - 下载完成") + } + } } } else { - Utils.toast(mApplication, downloadEntity.name + " - 下载完成") + if (downloadEntity.isSmoothGame()) { + VHelper.showFloatingWindow(downloadEntity.packageName) + } else { + Utils.toast(mApplication, downloadEntity.name + " - 下载完成") + } } if (!downloadEntity.isPluggable) { if (downloadEntity.isSimulatorGame()) { diff --git a/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt b/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt index d095393fec..c06a748d01 100644 --- a/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt +++ b/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt @@ -5,7 +5,6 @@ import android.content.Context import android.text.TextUtils import androidx.appcompat.app.AppCompatActivity import com.gh.common.DefaultJsApi -import com.gh.gamecenter.common.constant.Constants import com.gh.common.dialog.CertificationDialog import com.gh.common.exposure.ExposureEvent import com.gh.common.exposure.ExposureManager @@ -13,29 +12,31 @@ import com.gh.common.exposure.ExposureSource import com.gh.common.exposure.ExposureType import com.gh.common.history.HistoryHelper import com.gh.common.repository.ReservationRepository -import com.gh.gamecenter.core.runOnUiThread -import com.gh.gamecenter.common.view.dsbridge.CompletionHandler import com.gh.download.DownloadManager import com.gh.download.dialog.DownloadDialog import com.gh.gamecenter.R import com.gh.gamecenter.WebActivity -import com.gh.gamecenter.common.callback.ConfirmListener +import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.retrofit.ApiResponse +import com.gh.gamecenter.common.retrofit.EmptyResponse +import com.gh.gamecenter.common.retrofit.Response +import com.gh.gamecenter.common.utils.DataLogUtils +import com.gh.gamecenter.common.utils.DialogHelper import com.gh.gamecenter.common.utils.observableToMain import com.gh.gamecenter.common.utils.singleToMain -import com.gh.gamecenter.common.utils.DialogHelper -import com.gh.gamecenter.core.utils.* +import com.gh.gamecenter.common.view.dsbridge.CompletionHandler +import com.gh.gamecenter.core.runOnUiThread +import com.gh.gamecenter.core.utils.EmptyCallback +import com.gh.gamecenter.core.utils.SPUtils +import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.entity.ApkEntity import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.entity.PluginLocation import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment import com.gh.gamecenter.manager.UserManager -import com.gh.gamecenter.common.retrofit.EmptyResponse -import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.retrofit.RetrofitManager import com.gh.gamecenter.teenagermode.TeenagerModeActivity -import com.gh.gamecenter.common.retrofit.ApiResponse import com.gh.vspace.VHelper -import com.gh.gamecenter.common.utils.DataLogUtils import com.lightgame.download.FileUtils /** @@ -190,7 +191,7 @@ object GameActivityDownloadHelper { } DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance) } else if (str == context.getString(R.string.smooth)) { - VHelper.checkVSpaceBeforeAction(context, gameEntity) { + VHelper.checkVSpaceBeforeAction(context, gameEntity, true) { GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) { CertificationDialog.showCertificationDialog(context, gameEntity) { DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java index 3fce0dca45..0690b83a84 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java @@ -191,7 +191,7 @@ public class DetailViewHolder { case NORMAL: DataLogUtils.uploadGameLog(mViewHolder.context, mGameEntity.getId(), mGameEntity.getName(), mEntrance); case PLUGIN: - VHelper.checkVSpaceBeforeAction(mViewHolder.context, mGameEntity, () -> { + VHelper.checkVSpaceBeforeAction(mViewHolder.context, mGameEntity, true, () -> { GamePermissionDialogFragment.show((AppCompatActivity) mViewHolder.context, mGameEntity, mGameEntity.getInfo(), () -> { PermissionHelper.checkStoragePermissionBeforeAction(mViewHolder.context, () -> { if (mGameEntity.getApk().size() == 1) { diff --git a/app/src/main/java/com/gh/gamecenter/entity/AppEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/AppEntity.kt index 9e84ad9f36..65fd42ffc6 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/AppEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/AppEntity.kt @@ -1,25 +1,27 @@ package com.gh.gamecenter.entity +import android.os.Parcelable import com.google.gson.annotations.SerializedName +import kotlinx.parcelize.Parcelize -class AppEntity { - - var version: String? = null +@Parcelize +data class AppEntity( + var version: String? = null, @SerializedName("version_code") - var versionCode: Int = 0 + var versionCode: Int = 0, - var url: String? = null + var url: String? = null, - var size: String? = null + var size: String? = null, - var content: String? = null + var content: String? = null, @SerializedName("force") - var isForce: Boolean = false + var isForce: Boolean = false, @SerializedName("spare_link") - var spareLink: String? = "" + var spareLink: String? = "", /** * NEVER(从不) @@ -28,5 +30,7 @@ class AppEntity { * ONCE_A_DAY(每天一次) * EVERY_TIME_OPEN(每次打开) */ - var alert: String? = null -} + var alert: String? = null, +) : Parcelable + + diff --git a/app/src/main/java/com/gh/gamecenter/retrofit/service/VApiService.kt b/app/src/main/java/com/gh/gamecenter/retrofit/service/VApiService.kt index 188b84e960..f0693ff570 100644 --- a/app/src/main/java/com/gh/gamecenter/retrofit/service/VApiService.kt +++ b/app/src/main/java/com/gh/gamecenter/retrofit/service/VApiService.kt @@ -2,7 +2,6 @@ package com.gh.gamecenter.retrofit.service import com.gh.gamecenter.entity.AppEntity import com.gh.gamecenter.entity.VSetting -import io.reactivex.Observable import io.reactivex.Single import retrofit2.http.GET import retrofit2.http.Query @@ -17,7 +16,7 @@ interface VApiService { @Query("version") version: String?, @Query("version_code") code: Int, @Query("package") packageName: String? - ): Observable + ): Single /** * 获取设置 diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index edeae13393..3f955271ef 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -5,6 +5,7 @@ import android.content.Context import android.content.Intent import android.net.Uri import android.text.TextUtils +import android.view.View import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData @@ -18,6 +19,7 @@ import com.gh.download.PackageObserver import com.gh.gamecenter.R import com.gh.gamecenter.SplashScreenActivity import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.retrofit.BiResponse import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.core.runOnIoThread @@ -26,11 +28,13 @@ import com.gh.gamecenter.core.utils.EmptyCallback import com.gh.gamecenter.core.utils.GsonUtils import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.entity.ApkEntity +import com.gh.gamecenter.entity.AppEntity import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.entity.GameUpdateEntity import com.gh.gamecenter.eventbus.EBPackage import com.gh.gamecenter.eventbus.EBReuse import com.gh.gamecenter.packagehelper.PackageRepository +import com.gh.gamecenter.retrofit.RetrofitManager import com.halo.assistant.HaloApp import com.lg.vspace.VirtualAppManager import com.lg.vspace.remote.listener.RemoteConnectListener @@ -38,6 +42,7 @@ import com.lg.vspace.remote.model.AppInstallerInfo import com.lightgame.download.DownloadEntity import com.lightgame.utils.AppManager import com.lightgame.utils.Utils +import io.reactivex.schedulers.Schedulers import org.greenrobot.eventbus.EventBus object VHelper { @@ -51,6 +56,8 @@ object VHelper { private val mInstallationLiveData by lazy { MutableLiveData() } private var mLastSuccessfullyLaunchedGame: Pair? = null + private var mUpdateEntity: AppEntity? = null + private val mPackageObserver by lazy { PackageObserver.PackageChangeListener { val vaConfig = Config.getVSettingEntity()?.va ?: return@PackageChangeListener @@ -77,6 +84,24 @@ object VHelper { && PackageUtils.isInstalled(context, config.arch64?.packageName) ) { connectService() + + val installedVersionName = + PackageUtils.getVersionNameByPackageName(config.arch64?.packageName) + val installedVersionCode = + PackageUtils.getVersionCodeByPackageName(config.arch64?.packageName) + RetrofitManager.getInstance() + .vApi + .getPackageUpdate( + installedVersionName, + installedVersionCode, + config.arch64?.packageName + ) + .subscribeOn(Schedulers.io()) + .subscribe(object : BiResponse() { + override fun onSuccess(data: AppEntity) { + mUpdateEntity = data + } + }) } PackageObserver.registerPackageChangeChangeListener(mPackageObserver) } @@ -85,8 +110,6 @@ object VHelper { * 连接服务 */ private fun connectService(callbackClosure: (() -> Unit)? = null) { - invokeVSpace() - mDelegateManager.connectService(object : RemoteConnectListener { override fun onServiceConnectionSuccessed() { Utils.log(LOG_TAG, "V 服务连接成功") @@ -126,7 +149,7 @@ object VHelper { */ @JvmStatic fun isInstalled(packageName: String?): Boolean { - return mInstalledInfoList.any { it?.packageName == packageName } + return mInstalledInfoList.any { it.packageName == packageName } } /** @@ -136,9 +159,10 @@ object VHelper { fun checkVSpaceBeforeAction( context: Context, gameEntity: GameEntity?, + requireStoragePermission: Boolean, callback: EmptyCallback ) { - checkVSpaceBeforeAction(context, gameEntity) { + checkVSpaceBeforeAction(context, gameEntity, requireStoragePermission) { callback.onCallback() } } @@ -155,10 +179,11 @@ object VHelper { && System.currentTimeMillis() - timeOfLastSuccessfullyLaunchedGame < 5000 && !VFeedbackSuppressedSimpleDao().contains(gameIdOfLastSuccessfullyLaunchedGame) ) { - DownloadManager.getInstance().getDownloadEntitySnapshotByGameId(gameIdOfLastSuccessfullyLaunchedGame)?.let { - VFeedbackDialogFragment.show(activity, toGameEntity(it)) - mLastSuccessfullyLaunchedGame = null - } + DownloadManager.getInstance() + .getDownloadEntitySnapshotByGameId(gameIdOfLastSuccessfullyLaunchedGame)?.let { + VFeedbackDialogFragment.show(activity, toGameEntity(it)) + mLastSuccessfullyLaunchedGame = null + } } } } @@ -166,41 +191,59 @@ object VHelper { /** * 在执行 callback 前先检查组件是否已安装,是否可下载 */ - fun checkVSpaceBeforeAction(context: Context, gameEntity: GameEntity?, callback: () -> Unit) { + fun checkVSpaceBeforeAction( + context: Context, + gameEntity: GameEntity?, + requireStoragePermission: Boolean, + callback: () -> Unit + ) { // 仅下载类型为畅玩的类型才执行判断 if (gameEntity?.isVGame() == true) { if (showDialogIfVSpaceIsNeeded(context)) { return } + val vaConfig64 = Config.getVSettingEntity()?.va?.arch64 + val installedSpaceVersionCode = + PackageUtils.getVersionCodeByPackageName(vaConfig64?.packageName) // 检查更新 val containsUpdate = - vaConfig64?.versionCode ?: 0 > PackageUtils.getVersionCodeByPackageName(vaConfig64?.packageName) + mUpdateEntity != null && installedSpaceVersionCode < mUpdateEntity!!.versionCode if (containsUpdate) { - // 触发更新弹窗 DialogHelper.showDialog( context = context, title = "服务工具更新提示", - content = "单机类游戏被删除将可能导致本地存档、充值数据丢失,请确认后操作(网游类游戏删除不会影响游戏存档和充值数据)", + content = mUpdateEntity!!.content.toString(), cancelText = "立即更新", confirmText = "继续游戏", cancelClickCallback = { - VSpaceDialogFragment.showDownloadDialog(context) + VSpaceDialogFragment.showDownloadDialog(context, getVSpaceDownloadEntity(true), true) }, confirmClickCallback = { callback.invoke() }, extraConfig = DialogHelper.Config(centerTitle = true), uiModificationCallback = { + if (mUpdateEntity!!.isForce) { + it.confirmTv.visibility = View.GONE + it.cancelTv.setTextColor(R.color.theme_font.toColor(context)) + } + it.confirmTv.setTextColor(R.color.text_subtitle.toColor(context)) } ) return } - callback.invoke() + if (requireStoragePermission) { + checkStoragePermissionBeforeAction(context) { + callback.invoke() + } + } else { + callback.invoke() + } } else { callback.invoke() } @@ -270,7 +313,11 @@ object VHelper { /** * 安装新应用 */ - fun install(context: Context, downloadEntity: DownloadEntity, isManualInstall: Boolean = false) { + fun install( + context: Context, + downloadEntity: DownloadEntity, + isManualInstall: Boolean = false + ) { Utils.log(LOG_TAG, "尝试安装新应用 ${downloadEntity.path}") if (showDialogIfVSpaceIsNeeded(context)) { @@ -296,7 +343,6 @@ object VHelper { val result = VirtualAppManager.get().installGame(downloadEntity.path) if (result.status == 0) { updateInstalledList() - showFloatingWindow(result.packageName) PackageObserver.onPackageChanged( EBPackage( "安装", @@ -357,29 +403,29 @@ object VHelper { return } - val launchClosure: () -> Unit = { - try { - val intent = mDelegateManager.getStartGameIntent(packageName) - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - context.startActivity(intent) +// val launchClosure: () -> Unit = { + try { + val intent = mDelegateManager.getStartGameIntent(packageName) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + context.startActivity(intent) - DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName)?.let { - mLastSuccessfullyLaunchedGame = Pair(System.currentTimeMillis(), it.gameId) - } - - updateLastPlayedTime(packageName) - } catch (e: Exception) { - ToastUtils.toast(e.localizedMessage ?: "") + DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName)?.let { + mLastSuccessfullyLaunchedGame = Pair(System.currentTimeMillis(), it.gameId) } - } - if (mDelegateManager.isConnectAidlInterface) { - checkStoragePermissionBeforeAction(context, launchClosure) - } else { - checkStoragePermissionBeforeAction(context) { - connectService(launchClosure) - } + updateLastPlayedTime(packageName) + } catch (e: Exception) { + ToastUtils.toast(e.localizedMessage ?: "") } +// } + +// if (mDelegateManager.isConnectAidlInterface) { +// context, launchClosure) +// } else { +// checkStoragePermissionBeforeAction(context) { +// connectService(launchClosure) +// } +// } } /** @@ -448,12 +494,14 @@ object VHelper { return mInstallationLiveData } - private fun showFloatingWindow(packageName: String) { + fun showFloatingWindow(packageName: String) { val vDownloadList = DownloadManager.getInstance().allVDownloadTaskSnapshots vDownloadList.firstOrNull { it.packageName == packageName }?.let { val topActivity = AppManager.getInstance().currentActivity() ?: return + if (topActivity.isFinishing || topActivity is VSpaceLoadingActivity) return + VLoadCompleteWindowHelper.showFloatingWindow(topActivity, toGameEntity(it)) } } @@ -462,19 +510,35 @@ object VHelper { * 畅玩空间是否已安装 * 如果已安装或配置为空返回 true * 未安装的情况下会弹弹窗 + * + * @param forUpdate 是不是为了更新而来,是更新的时候用更新的数据 */ - private fun showDialogIfVSpaceIsNeeded(context: Context): Boolean { + private fun showDialogIfVSpaceIsNeeded(context: Context, forUpdate: Boolean = false): Boolean { val vaConfig = Config.getVSettingEntity()?.va ?: return true // TODO 检测 32 位 if (!PackageUtils.isInstalled(context, vaConfig.arch64?.packageName)) { - VSpaceDialogFragment.showDownloadDialog(context) + VSpaceDialogFragment.showDownloadDialog(context, getVSpaceDownloadEntity(false)) return true } return false } + private fun getVSpaceDownloadEntity(forUpdate: Boolean): AppEntity { + if (!forUpdate) { + val appEntity = AppEntity() + val vaConfig64 = Config.getVSettingEntity()?.va?.arch64 + appEntity.versionCode = vaConfig64?.versionCode ?: 0 + appEntity.version = vaConfig64?.versionName + appEntity.url = vaConfig64?.url + + return appEntity + } else { + return mUpdateEntity!! + } + } + /** * 执行单个更新 * @@ -537,7 +601,9 @@ object VHelper { ) icon = downloadEntity.icon lastPlayedTime = if (lastPlayedTimeString == "") 0L else lastPlayedTimeString.toLong() - playedTime = mInstalledInfoList.firstOrNull { it.packageName == getUniquePackageName() }?.appTotalPlayTime ?: 0 + playedTime = + mInstalledInfoList.firstOrNull { it.packageName == getUniquePackageName() }?.appTotalPlayTime + ?: 0 downloadStatus = "smooth" setEntryMap(DownloadManager.getInstance().getEntryMap(name)) } diff --git a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt index f38501cb4e..5e3597acd3 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt @@ -13,7 +13,6 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel -import com.gh.common.constant.Config import com.gh.common.util.PackageInstaller import com.gh.common.view.DownloadProgressBar import com.gh.download.DownloadManager @@ -24,16 +23,18 @@ import com.gh.gamecenter.common.utils.toColor import com.gh.gamecenter.common.utils.viewModelProvider import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.databinding.DialogVspaceBinding +import com.gh.gamecenter.entity.AppEntity import com.gh.gamecenter.eventbus.EBPackage import com.lightgame.download.DataWatcher import com.lightgame.download.DownloadEntity import com.lightgame.download.DownloadStatus.* -import com.lightgame.download.FileUtils import com.lightgame.utils.AppManager +import splitties.bundle.put class VSpaceDialogFragment : BaseDraggableDialogFragment() { - private val mDownloadUrl by lazy { Config.getVSettingEntity()?.va?.arch64?.url } // TODO 支持 32 位地址 + private var mAppEntity: AppEntity? = null + private val mDownloadUrl by lazy { mAppEntity?.url ?: "" } private val mBinding by lazy { DialogVspaceBinding.inflate(layoutInflater) } private val mDataWatcher = object : DataWatcher() { override fun onDataChanged(downloadEntity: DownloadEntity) { @@ -46,6 +47,12 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { override fun getRootView(): View = mBinding.root override fun getDragCloseView(): View = mBinding.dragClose + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + mAppEntity = arguments?.get(KEY_ENTITY) as AppEntity + } + @SuppressLint("ClickableViewAccessibility") override fun onCreateView( inflater: LayoutInflater, @@ -60,9 +67,7 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { val mViewModel = viewModelProvider() mViewModel.packageLiveData.observe(this) { - if (it.packageName == Config.getVSettingEntity()?.va?.arch32?.packageName - && it.type == "安装" - ) { + if (it.packageName == "com.lg.vspace") { dismissAllowingStateLoss() } } @@ -77,26 +82,26 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { mBinding.downloadBtn.downloadType = DownloadProgressBar.DownloadType.NORMAL mBinding.descTv.text = spanBuilder mBinding.downloadBtn.setOnClickListener { - val vSpaceInfo = Config.getVSettingEntity()?.va?.arch32!! - val name = "畅玩助手V" + vSpaceInfo.versionName + val name = "畅玩助手V" + mAppEntity?.version val downloadId = PackageInstaller.createDownloadId(name) val downloadEntity = DownloadEntity() downloadEntity.url = mDownloadUrl - downloadEntity.name = "畅玩助手V" + vSpaceInfo.versionName - downloadEntity.path = FileUtils.getDownloadPath( - requireContext(), - "畅玩助手V" + vSpaceInfo.versionName + ".apk" - ) + downloadEntity.name = name downloadEntity.platform = "官方版" downloadEntity.gameId = "" downloadEntity.path = PackageInstaller.getDownloadPathWithId(downloadId, "apk") - downloadEntity.packageName = vSpaceInfo.packageName + downloadEntity.packageName = "com.lg.vspace" AppExecutor.uiExecutor.executeWithDelay({ + DownloadManager.getInstance().cancel(mDownloadUrl) DownloadManager.getInstance().add(downloadEntity) }, 200) } + + if (arguments?.getBoolean(KEY_AUTO_DOWNLOAD) == true) { + mBinding.downloadBtn.performClick() + } } override fun onStart() { @@ -166,8 +171,11 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { } companion object { + const val KEY_ENTITY = "entity" + const val KEY_AUTO_DOWNLOAD = "auto_download" + @JvmStatic - fun showDownloadDialog(context: Context?) { + fun showDownloadDialog(context: Context?, appEntity: AppEntity, autoDownload: Boolean = false) { val fragmentActivity: FragmentActivity = if (context is FragmentActivity) { context } else { @@ -182,7 +190,12 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { // 防止重复弹出 if (hasDialogDisplayedInCurrentActivity(fragmentActivity)) return - val downloadDialog = VSpaceDialogFragment() + val downloadDialog = VSpaceDialogFragment().apply { + arguments = Bundle().apply { + put(KEY_ENTITY, appEntity) + put(KEY_AUTO_DOWNLOAD, autoDownload) + } + } downloadDialog.show( fragmentActivity.supportFragmentManager, VSpaceDialogFragment::class.java.name From 72926f504688a9a3de096c5fc3d26a4c08fde93c Mon Sep 17 00:00:00 2001 From: juntao Date: Wed, 22 Jun 2022 14:39:57 +0800 Subject: [PATCH 040/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=83=A8?= =?UTF-8?q?=E5=88=86=20UI=20=E9=97=AE=E9=A2=98=20https://git.shanqu.cc/pm/?= =?UTF-8?q?halo/halo-app-issues/-/issues/1923#note=5F155108?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/vspace/VDownloadManagerViewModel.kt | 13 ++++++++++++ app/src/main/java/com/gh/vspace/VHelper.kt | 1 - .../gh/vspace/VLoadCompleteWindowHelper.kt | 2 +- app/src/main/res/layout/activity_shell.xml | 4 ++-- .../res/layout/fragment_vspace_loading.xml | 21 ++++++++++--------- .../layout/item_float_game_load_complete.xml | 7 ++++--- .../res/layout/item_home_recent_vgame.xml | 4 +++- .../layout/item_vgame_download_manager.xml | 1 - .../res/layout/layout_float_load_complete.xml | 2 +- 9 files changed, 35 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index ff0a4012c8..b32c6e81f7 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -2,11 +2,14 @@ package com.gh.vspace import android.app.Application import com.gh.download.DownloadManager +import com.gh.download.PackageObserver import com.gh.gamecenter.baselist.ListViewModel import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.eventbus.EBPackage import com.lightgame.download.DownloadStatus import io.reactivex.Observable import io.reactivex.Single +import org.greenrobot.eventbus.EventBus class VDownloadManagerViewModel(application: Application) : ListViewModel(application) { @@ -60,6 +63,11 @@ class VDownloadManagerViewModel(application: Application) : fun removeItem(url: String?, packageName: String?) { DownloadManager.getInstance().pause(url) DownloadManager.getInstance().cancel(url) + + val event = EBPackage("卸载", packageName, "unknown") + EventBus.getDefault().post(event) + PackageObserver.onPackageChanged(event) + VHelper.uninstall(packageName ?: "") } @@ -68,6 +76,11 @@ class VDownloadManagerViewModel(application: Application) : val apkEntity = mResultLiveData.value?.firstOrNull { id == it.id }?.getApk()?.firstOrNull() DownloadManager.getInstance().pause(apkEntity?.url) DownloadManager.getInstance().cancel(apkEntity?.url) + + val event = EBPackage("卸载", apkEntity?.packageName, "unknown") + EventBus.getDefault().post(event) + PackageObserver.onPackageChanged(event) + VHelper.uninstall(apkEntity?.packageName) } } diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 3f955271ef..4db8f1f19a 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -439,7 +439,6 @@ object VHelper { val result = VirtualAppManager.get().uninstallGame(packageName) if (result) { updateInstalledList() - PackageObserver.onPackageChanged(EBPackage("卸载", packageName, "unknown")) } Utils.log(LOG_TAG, "卸载应用结果 -> $result") diff --git a/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt b/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt index 48cb01fa16..8ad64896fe 100644 --- a/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt +++ b/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt @@ -84,7 +84,7 @@ object VLoadCompleteWindowHelper { .setTag(LOAD_COMPLETE_WINDOW) .setDragEnable(false) .setMatchParent(widthMatch = true, heightMatch = false) - .setGravity(Gravity.BOTTOM, 0, (-70F).dip2px()) + .setGravity(Gravity.BOTTOM, 0, (-78F).dip2px()) .setAnimator(LoadCompleteFloatAnimator()) .registerCallback { createResult { _, _, view -> diff --git a/app/src/main/res/layout/activity_shell.xml b/app/src/main/res/layout/activity_shell.xml index a8aa0da184..198715a30b 100644 --- a/app/src/main/res/layout/activity_shell.xml +++ b/app/src/main/res/layout/activity_shell.xml @@ -1,7 +1,7 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_vspace_loading.xml b/app/src/main/res/layout/fragment_vspace_loading.xml index 8bbf6fa8b5..c155933fbd 100644 --- a/app/src/main/res/layout/fragment_vspace_loading.xml +++ b/app/src/main/res/layout/fragment_vspace_loading.xml @@ -6,17 +6,18 @@ android:layout_height="match_parent" android:background="@color/white"> + + - - - + android:layout_height="0dp" + android:fitsSystemWindows="true" + app:layout_constraintTop_toTopOf="parent" /> diff --git a/app/src/main/res/layout/item_float_game_load_complete.xml b/app/src/main/res/layout/item_float_game_load_complete.xml index 5f44e00757..be9a28e5d9 100644 --- a/app/src/main/res/layout/item_float_game_load_complete.xml +++ b/app/src/main/res/layout/item_float_game_load_complete.xml @@ -15,14 +15,16 @@ - Date: Wed, 22 Jun 2022 14:40:36 +0800 Subject: [PATCH 041/217] =?UTF-8?q?fix:=20=E7=95=85=E7=8E=A9=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E8=BF=9E=E6=8E=A5=E5=BC=82=E5=B8=B8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vspace-bridge | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vspace-bridge b/vspace-bridge index 4ad237b602..e1f929b730 160000 --- a/vspace-bridge +++ b/vspace-bridge @@ -1 +1 @@ -Subproject commit 4ad237b60276f1f9bc9d6e7e0eeb0f1e12ad0fe6 +Subproject commit e1f929b730625fd04ace2622ebdcd7dce5a809ef From 9f694085fdbbbae1d9f9f0b1dc406a55b2ce641b Mon Sep 17 00:00:00 2001 From: juntao Date: Wed, 22 Jun 2022 17:12:20 +0800 Subject: [PATCH 042/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=83=A8?= =?UTF-8?q?=E5=88=86=E9=80=BB=E8=BE=91=E9=97=AE=E9=A2=98=E5=92=8C=20UI=20?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20https://git.shanqu.cc/pm/halo/halo-app-iss?= =?UTF-8?q?ues/-/issues/1923#note=5F155241?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/common/databind/BindingAdapters.java | 2 +- .../com/gh/common/util/DownloadItemUtils.kt | 4 +- .../common/util/GameActivityDownloadHelper.kt | 2 +- .../adapter/viewholder/DetailViewHolder.java | 2 +- .../gh/vspace/HomeRecentVGameViewHolder.kt | 2 +- .../com/gh/vspace/VDownloadManagerAdapter.kt | 10 +- .../gh/vspace/VDownloadManagerViewModel.kt | 12 +- app/src/main/java/com/gh/vspace/VHelper.kt | 128 +++++++++++------- .../res/layout/item_home_recent_vgame.xml | 2 +- 9 files changed, 101 insertions(+), 63 deletions(-) diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java index e711f27034..d7259e9052 100644 --- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java +++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java @@ -382,7 +382,7 @@ public class BindingAdapters { return; } } - VHelper.checkVSpaceBeforeAction(v.getContext(), gameEntity, true, () -> { + VHelper.validateVSpaceBeforeAction(v.getContext(), gameEntity, true, () -> { GamePermissionDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, gameEntity.getInfo(), () -> { BrowserInstallHelper.showBrowserInstallHintDialog(v.getContext(), gameEntity.isVGame(), () -> { PackageCheckDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, () -> { diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index a6b8f85a3a..6ea6538a29 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -701,7 +701,7 @@ object DownloadItemUtils { CertificationDialog.showCertificationDialog(context, gameEntity) { DialogUtils.showVersionNumberDialog(context, gameEntity) { DialogUtils.showOverseaDownloadDialog(context, gameEntity) { - VHelper.checkVSpaceBeforeAction(context, gameEntity, true) { + VHelper.validateVSpaceBeforeAction(context, gameEntity, true) { DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent) } @@ -776,7 +776,7 @@ object DownloadItemUtils { if (gameEntity.isVGame()) { PackagesManager.getUpdateList().firstOrNull { it.id == gameEntity.id }?.let { updateEntity -> VHelper.getDownloadEntitySnapshotByPackageName(gameEntity.getUniquePackageName() ?: "")?.let { downloadEntity -> - VHelper.update(downloadEntity, updateEntity) + VHelper.updateOrReDownload(downloadEntity, updateEntity) } } return diff --git a/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt b/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt index c06a748d01..e0624c7c30 100644 --- a/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt +++ b/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt @@ -191,7 +191,7 @@ object GameActivityDownloadHelper { } DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance) } else if (str == context.getString(R.string.smooth)) { - VHelper.checkVSpaceBeforeAction(context, gameEntity, true) { + VHelper.validateVSpaceBeforeAction(context, gameEntity, true) { GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) { CertificationDialog.showCertificationDialog(context, gameEntity) { DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java index 0690b83a84..dbbe28da84 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java @@ -191,7 +191,7 @@ public class DetailViewHolder { case NORMAL: DataLogUtils.uploadGameLog(mViewHolder.context, mGameEntity.getId(), mGameEntity.getName(), mEntrance); case PLUGIN: - VHelper.checkVSpaceBeforeAction(mViewHolder.context, mGameEntity, true, () -> { + VHelper.validateVSpaceBeforeAction(mViewHolder.context, mGameEntity, true, () -> { GamePermissionDialogFragment.show((AppCompatActivity) mViewHolder.context, mGameEntity, mGameEntity.getInfo(), () -> { PermissionHelper.checkStoragePermissionBeforeAction(mViewHolder.context, () -> { if (mGameEntity.getApk().size() == 1) { diff --git a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt index 5d190c7cbd..b24a06bb00 100644 --- a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt +++ b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt @@ -193,7 +193,7 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter(con binding.root.setOnClickListener { PackagesManager.getUpdateList().firstOrNull { it.id == downloadEntity.gameId } ?.let { - VHelper.update(downloadEntity, it) + VHelper.updateOrReDownload(downloadEntity, it) } } } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index 299bd32412..ad9bdcb048 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -22,7 +22,6 @@ import com.gh.gamecenter.common.constant.ItemViewType import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.core.utils.CurrentActivityHolder -import com.gh.gamecenter.core.utils.NumberUtils import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.databinding.ItemVgameDownloadManagerBinding @@ -98,13 +97,12 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa when (holder) { is VGameItemViewHolder -> { val gameEntity = mEntityList[position] - val totalPlayedTimeString = NumberUtils.transSimpleUsageTime(gameEntity.playedTime) BindingAdapters.setGameName(holder.binding.nameTv, gameEntity, false, true) holder.binding.iconIv.displayGameIcon(gameEntity) - holder.binding.descTv.goneIf(mViewModel.isTypeDownloaded()) - holder.binding.descTv.text = "已畅玩$totalPlayedTimeString" + holder.binding.descTv.goneIf(!mViewModel.isTypeDownloaded()) + holder.binding.descTv.text = gameEntity.des (holder.binding.selectIv.layoutParams as ConstraintLayout.LayoutParams).apply { width = 20F.dip2px() @@ -239,6 +237,8 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa return } + downloadBtn.goneIf(mCurrentOption != ManageOption.OPTION_MANAGER) + val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByUrl(gameEntity.getApk()[0].url) if (downloadEntity != null) { val status = downloadEntity.status @@ -276,7 +276,7 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa setOnClickListener { PackagesManager.getUpdateList() .firstOrNull { it.id == downloadEntity.gameId }?.let { - VHelper.update(downloadEntity, it) + VHelper.updateOrReDownload(downloadEntity, it) } } } else { diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index b32c6e81f7..c39130afda 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -4,6 +4,8 @@ import android.app.Application import com.gh.download.DownloadManager import com.gh.download.PackageObserver import com.gh.gamecenter.baselist.ListViewModel +import com.gh.gamecenter.common.utils.toProperReadableSize +import com.gh.gamecenter.core.utils.NumberUtils import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.eventbus.EBPackage import com.lightgame.download.DownloadStatus @@ -35,7 +37,15 @@ class VDownloadManagerViewModel(application: Application) : for (downloadEntity in vDownloadList) { if (downloadEntity.status == DownloadStatus.done) { gameIdSet.add(downloadEntity.gameId) - vGameList.add(VHelper.toGameEntity(downloadEntity)) + + val gameEntity = VHelper.toGameEntity(downloadEntity) + if (gameEntity.playedTime != 0L) { + gameEntity.des = "已畅玩${NumberUtils.transSimpleUsageTime(gameEntity.playedTime)}" + } else { + gameEntity.des = VHelper.getAppOccupiedSpace(downloadEntity.packageName).toProperReadableSize() + } + + vGameList.add(gameEntity) } } diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 4db8f1f19a..b93b8f25dd 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -44,6 +44,7 @@ import com.lightgame.utils.AppManager import com.lightgame.utils.Utils import io.reactivex.schedulers.Schedulers import org.greenrobot.eventbus.EventBus +import java.io.File object VHelper { @@ -156,13 +157,13 @@ object VHelper { * 在执行 callback 前先检查组件是否已安装,是否可下载 */ @JvmStatic - fun checkVSpaceBeforeAction( + fun validateVSpaceBeforeAction( context: Context, gameEntity: GameEntity?, requireStoragePermission: Boolean, callback: EmptyCallback ) { - checkVSpaceBeforeAction(context, gameEntity, requireStoragePermission) { + validateVSpaceBeforeAction(context, gameEntity, requireStoragePermission) { callback.onCallback() } } @@ -188,17 +189,29 @@ object VHelper { } } + /** + * 获取游戏占用的空间 + */ + fun getAppOccupiedSpace(packageName: String): Long { + return try { + mDelegateManager.getAppOccupiedSpace(packageName) + } catch (e: Exception) { + e.printStackTrace() + 0 + } + } + /** * 在执行 callback 前先检查组件是否已安装,是否可下载 */ - fun checkVSpaceBeforeAction( + fun validateVSpaceBeforeAction( context: Context, gameEntity: GameEntity?, requireStoragePermission: Boolean, callback: () -> Unit ) { // 仅下载类型为畅玩的类型才执行判断 - if (gameEntity?.isVGame() == true) { + if (gameEntity == null || gameEntity.isVGame()) { if (showDialogIfVSpaceIsNeeded(context)) { return } @@ -219,7 +232,11 @@ object VHelper { cancelText = "立即更新", confirmText = "继续游戏", cancelClickCallback = { - VSpaceDialogFragment.showDownloadDialog(context, getVSpaceDownloadEntity(true), true) + VSpaceDialogFragment.showDownloadDialog( + context, + getVSpaceDownloadEntity(true), + true + ) }, confirmClickCallback = { callback.invoke() @@ -381,14 +398,26 @@ object VHelper { return } - if (isInstalled(packageName)) { - launch(context, packageName) - } else { - val downloadEntity = getDownloadEntitySnapshotByPackageName(packageName) - if (downloadEntity != null) { - install(context, downloadEntity, true) + checkStoragePermissionBeforeAction(context) { + if (isInstalled(packageName)) { + launch(context, packageName) } else { - ToastUtils.toast("找不到下载文件") + val downloadEntity = getDownloadEntitySnapshotByPackageName(packageName) + if (downloadEntity != null) { + runOnIoThread { + if (File(downloadEntity.path).exists()) { + install(context, downloadEntity, true) + } else { + // 重新下载 + runOnUiThread { + ToastUtils.toast("检测到数据异常,将会为你重新下载安装") + updateOrReDownload(downloadEntity, null) + } + } + } + } else { + ToastUtils.toast("找不到下载文件") + } } } } @@ -403,29 +432,22 @@ object VHelper { return } -// val launchClosure: () -> Unit = { - try { - val intent = mDelegateManager.getStartGameIntent(packageName) - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - context.startActivity(intent) + validateVSpaceBeforeAction(context, null, false) { + try { + val intent = mDelegateManager.getStartGameIntent(packageName) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + context.startActivity(intent) - DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName)?.let { - mLastSuccessfullyLaunchedGame = Pair(System.currentTimeMillis(), it.gameId) + DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName) + ?.let { + mLastSuccessfullyLaunchedGame = Pair(System.currentTimeMillis(), it.gameId) + } + + updateLastPlayedTime(packageName) + } catch (e: Exception) { + ToastUtils.toast(e.localizedMessage ?: "") } - - updateLastPlayedTime(packageName) - } catch (e: Exception) { - ToastUtils.toast(e.localizedMessage ?: "") } -// } - -// if (mDelegateManager.isConnectAidlInterface) { -// context, launchClosure) -// } else { -// checkStoragePermissionBeforeAction(context) { -// connectService(launchClosure) -// } -// } } /** @@ -539,26 +561,32 @@ object VHelper { } /** - * 执行单个更新 + * 更新或重下载 * * @param originDownloadEntity 旧的下载实体 - * @param update 更新内容 + * @param updateEntity 更新内容,当 updateEntity 为空时重新下载 */ - fun update(originDownloadEntity: DownloadEntity, update: GameUpdateEntity) { + fun updateOrReDownload(originDownloadEntity: DownloadEntity, updateEntity: GameUpdateEntity? = null) { Utils.log(LOG_TAG, "更新应用${originDownloadEntity.packageName}") DownloadManager.getInstance().cancel(originDownloadEntity.url) - originDownloadEntity.url = update.url - originDownloadEntity.name = update.name - originDownloadEntity.eTag = update.etag - originDownloadEntity.icon = update.icon - originDownloadEntity.platform = update.platform - originDownloadEntity.packageName = update.packageName - originDownloadEntity.versionName = update.version - originDownloadEntity.addMetaExtra(Constants.RAW_GAME_ICON, update.rawIcon) - originDownloadEntity.addMetaExtra(Constants.GAME_ICON_SUBSCRIPT, update.iconSubscript) - originDownloadEntity.addMetaExtra(Constants.APK_MD5, update.md5) + if (updateEntity != null) { + originDownloadEntity.url = updateEntity.url + originDownloadEntity.name = updateEntity.name + originDownloadEntity.eTag = updateEntity.etag + originDownloadEntity.icon = updateEntity.icon + originDownloadEntity.platform = updateEntity.platform + originDownloadEntity.packageName = updateEntity.packageName + originDownloadEntity.versionName = updateEntity.version + originDownloadEntity.addMetaExtra(Constants.RAW_GAME_ICON, updateEntity.rawIcon) + originDownloadEntity.addMetaExtra( + Constants.GAME_ICON_SUBSCRIPT, + updateEntity.iconSubscript + ) + originDownloadEntity.addMetaExtra(Constants.APK_MD5, updateEntity.md5) + } + originDownloadEntity.isUpdate = true originDownloadEntity.progress = 0 originDownloadEntity.finalRedirectedUrl = "" @@ -566,19 +594,19 @@ object VHelper { // 确定下载类型 val downloadType = ExposureUtils.DownloadType.UPDATE - val gameEntity = GameEntity(update.id, update.name) - gameEntity.gameVersion = update.version ?: "" + val gameEntity = GameEntity(originDownloadEntity.gameId, originDownloadEntity.name) + gameEntity.gameVersion = originDownloadEntity.versionName ?: "" val event = ExposureUtils.logADownloadExposureEvent( gameEntity, - update.platform, - update.exposureEvent, + originDownloadEntity.platform, + null, downloadType ) originDownloadEntity.exposureTrace = GsonUtils.toJson(event) - HistoryHelper.insertGameEntity(update) + HistoryHelper.insertGameEntity(gameEntity) DownloadManager.getInstance().add(originDownloadEntity) // 收集下载数据 diff --git a/app/src/main/res/layout/item_home_recent_vgame.xml b/app/src/main/res/layout/item_home_recent_vgame.xml index 68d5797a26..9cf65a1b3b 100644 --- a/app/src/main/res/layout/item_home_recent_vgame.xml +++ b/app/src/main/res/layout/item_home_recent_vgame.xml @@ -59,7 +59,7 @@ app:layout_constraintStart_toStartOf="parent"> Date: Wed, 22 Jun 2022 17:28:14 +0800 Subject: [PATCH 043/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=83=A8?= =?UTF-8?q?=E5=88=86=20UI=20=E9=97=AE=E9=A2=98=20https://git.shanqu.cc/pm/?= =?UTF-8?q?halo/halo-app-issues/-/issues/1923#note=5F154774?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/item_home_recent_vgame.xml | 8 ++++---- vspace-bridge | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/res/layout/item_home_recent_vgame.xml b/app/src/main/res/layout/item_home_recent_vgame.xml index 9cf65a1b3b..179488578e 100644 --- a/app/src/main/res/layout/item_home_recent_vgame.xml +++ b/app/src/main/res/layout/item_home_recent_vgame.xml @@ -48,11 +48,11 @@ android:id="@+id/recyclerViewContainer" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginStart="-8dp" - android:layout_marginEnd="16dp" - android:scrollX="-8dp" + android:layout_marginStart="-2dp" + android:layout_marginEnd="10dp" + android:scrollX="-2dp" app:cardBackgroundColor="@color/transparent" - app:cardCornerRadius="12dp" + app:cardCornerRadius="4dp" app:cardElevation="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@id/vspaceIv" diff --git a/vspace-bridge b/vspace-bridge index e1f929b730..4c1f17d7b8 160000 --- a/vspace-bridge +++ b/vspace-bridge @@ -1 +1 @@ -Subproject commit e1f929b730625fd04ace2622ebdcd7dce5a809ef +Subproject commit 4c1f17d7b8554ef42489e6cb928b2564b966b09d From 0af479e441d9f144a220bf31d366f4de79e55b0a Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 23 Jun 2022 14:13:31 +0800 Subject: [PATCH 044/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=AF=AF?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E9=80=A0=E6=88=90=E7=9A=84=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/gamecenter/home/HomeViewModel.kt | 1 + .../gh/vspace/VDownloadManagerViewModel.kt | 4 +- app/src/main/java/com/gh/vspace/VHelper.kt | 89 +++++++++++-------- 3 files changed, 55 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index 9080ffe9f6..d694c4f487 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -103,6 +103,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { val vGameList = arrayListOf() for (entity in entityList) { + // TODO 添加更多的信息供页面确定是否有更新 vGameList.add(VHelper.toGameEntity(entity)) } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index c39130afda..95bbc0ef18 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -40,9 +40,9 @@ class VDownloadManagerViewModel(application: Application) : val gameEntity = VHelper.toGameEntity(downloadEntity) if (gameEntity.playedTime != 0L) { - gameEntity.des = "已畅玩${NumberUtils.transSimpleUsageTime(gameEntity.playedTime)}" + gameEntity.des = "已畅玩${NumberUtils.transSimpleUsageTime(gameEntity.playedTime / 1000 / 1000)}" } else { - gameEntity.des = VHelper.getAppOccupiedSpace(downloadEntity.packageName).toProperReadableSize() + gameEntity.des = "已占用${VHelper.getAppOccupiedSpace(downloadEntity.packageName).toProperReadableSize()}" } vGameList.add(gameEntity) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index b93b8f25dd..da83fbb4a0 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -1,6 +1,7 @@ package com.gh.vspace import android.Manifest +import android.annotation.SuppressLint import android.content.Context import android.content.Intent import android.net.Uri @@ -27,10 +28,7 @@ import com.gh.gamecenter.core.runOnUiThread import com.gh.gamecenter.core.utils.EmptyCallback import com.gh.gamecenter.core.utils.GsonUtils import com.gh.gamecenter.core.utils.ToastUtils -import com.gh.gamecenter.entity.ApkEntity -import com.gh.gamecenter.entity.AppEntity -import com.gh.gamecenter.entity.GameEntity -import com.gh.gamecenter.entity.GameUpdateEntity +import com.gh.gamecenter.entity.* import com.gh.gamecenter.eventbus.EBPackage import com.gh.gamecenter.eventbus.EBReuse import com.gh.gamecenter.packagehelper.PackageRepository @@ -45,6 +43,7 @@ import com.lightgame.utils.Utils import io.reactivex.schedulers.Schedulers import org.greenrobot.eventbus.EventBus import java.io.File +import java.util.* object VHelper { @@ -59,6 +58,9 @@ object VHelper { private var mUpdateEntity: AppEntity? = null + // 当前正卡在安装中的 VA 游戏,避免重复调用安装 + private val mInstallingVaPathSet by lazy { Collections.synchronizedSet(hashSetOf()) } + private val mPackageObserver by lazy { PackageObserver.PackageChangeListener { val vaConfig = Config.getVSettingEntity()?.va ?: return@PackageChangeListener @@ -78,6 +80,7 @@ object VHelper { } } + @SuppressLint("CheckResult") @JvmStatic fun init(context: Context) { val config = Config.getVSettingEntity()?.va @@ -86,23 +89,8 @@ object VHelper { ) { connectService() - val installedVersionName = - PackageUtils.getVersionNameByPackageName(config.arch64?.packageName) - val installedVersionCode = - PackageUtils.getVersionCodeByPackageName(config.arch64?.packageName) - RetrofitManager.getInstance() - .vApi - .getPackageUpdate( - installedVersionName, - installedVersionCode, - config.arch64?.packageName - ) - .subscribeOn(Schedulers.io()) - .subscribe(object : BiResponse() { - override fun onSuccess(data: AppEntity) { - mUpdateEntity = data - } - }) + // 检查畅玩助手组件更新 + checkVSpaceUpdate(config.arch64!!) } PackageObserver.registerPackageChangeChangeListener(mPackageObserver) } @@ -335,6 +323,9 @@ object VHelper { downloadEntity: DownloadEntity, isManualInstall: Boolean = false ) { + // 正在安装中,忽略重复调用 + if (mInstallingVaPathSet.contains(downloadEntity.path)) return + Utils.log(LOG_TAG, "尝试安装新应用 ${downloadEntity.path}") if (showDialogIfVSpaceIsNeeded(context)) { @@ -357,6 +348,8 @@ object VHelper { // 安装过程会比较漫长,所以得放在工作线程运行 AppExecutor.ioExecutor.execute { try { + mInstallingVaPathSet.add(downloadEntity.path) + val result = VirtualAppManager.get().installGame(downloadEntity.path) if (result.status == 0) { updateInstalledList() @@ -369,6 +362,8 @@ object VHelper { ) } + mInstallingVaPathSet.remove(downloadEntity.path) + mInstallationLiveData.postValue(result.packageName) Utils.log(LOG_TAG, "安装新应用结果 -> " + result.status) } catch (e: Exception) { @@ -398,25 +393,20 @@ object VHelper { return } - checkStoragePermissionBeforeAction(context) { - if (isInstalled(packageName)) { - launch(context, packageName) - } else { + if (isInstalled(packageName)) { + launch(context, packageName) + } else { + checkStoragePermissionBeforeAction(context) { val downloadEntity = getDownloadEntitySnapshotByPackageName(packageName) if (downloadEntity != null) { - runOnIoThread { - if (File(downloadEntity.path).exists()) { - install(context, downloadEntity, true) - } else { - // 重新下载 - runOnUiThread { - ToastUtils.toast("检测到数据异常,将会为你重新下载安装") - updateOrReDownload(downloadEntity, null) - } - } + if (File(downloadEntity.path).exists()) { + install(context, downloadEntity, true) + } else { + // 重新下载 + updateOrReDownload(downloadEntity, null) } } else { - ToastUtils.toast("找不到下载文件") + ToastUtils.toast("该游戏已损坏,请重新下载") } } } @@ -566,7 +556,10 @@ object VHelper { * @param originDownloadEntity 旧的下载实体 * @param updateEntity 更新内容,当 updateEntity 为空时重新下载 */ - fun updateOrReDownload(originDownloadEntity: DownloadEntity, updateEntity: GameUpdateEntity? = null) { + fun updateOrReDownload( + originDownloadEntity: DownloadEntity, + updateEntity: GameUpdateEntity? = null + ) { Utils.log(LOG_TAG, "更新应用${originDownloadEntity.packageName}") DownloadManager.getInstance().cancel(originDownloadEntity.url) @@ -636,4 +629,26 @@ object VHelper { } } + @SuppressLint("CheckResult") + private fun checkVSpaceUpdate(config: VSetting.VaArch) { + val installedVersionName = + PackageUtils.getVersionNameByPackageName(config.packageName) + val installedVersionCode = + PackageUtils.getVersionCodeByPackageName(config.packageName) + + RetrofitManager.getInstance() + .vApi + .getPackageUpdate( + installedVersionName, + installedVersionCode, + config.packageName + ) + .subscribeOn(Schedulers.io()) + .subscribe(object : BiResponse() { + override fun onSuccess(data: AppEntity) { + mUpdateEntity = data + } + }) + } + } \ No newline at end of file From 4e53b1fb91cbdcdfb8aebe32dc74de053b267149 Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 23 Jun 2022 17:20:53 +0800 Subject: [PATCH 045/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=88=A4=E6=96=AD=E5=BC=82=E5=B8=B8=E5=92=8C=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E6=9C=80=E8=BF=91=E5=9C=A8=E7=8E=A9=E7=9A=84=E6=8E=92?= =?UTF-8?q?=E5=BA=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/util/DetailDownloadUtils.java | 16 +++++++++------- .../java/com/gh/common/util/PackageUtils.java | 14 ++++++-------- .../java/com/gh/gamecenter/home/HomeViewModel.kt | 8 ++------ .../packagehelper/PackageRepository.kt | 12 ++++++++++++ app/src/main/java/com/gh/vspace/VHelper.kt | 9 +++++++++ 5 files changed, 38 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index 7338f07690..b3e235472a 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -194,14 +194,16 @@ public class DetailDownloadUtils { viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL); } } else if (viewHolder.gameEntity.isVGame()) { - if (VHelper.isInstalled(downloadEntity.getPackageName())) { - viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.LAUNCH_OR_OPEN); - } else { - viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL); - } + if (!viewHolder.mDownloadPb.getText().contains("更新")) { + if (VHelper.isInstalled(downloadEntity.getPackageName())) { + viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.LAUNCH_OR_OPEN); + } else { + viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL); + } - viewHolder.mDownloadPb.setText(""); - viewHolder.overlayTv.setVisibility(View.VISIBLE); + viewHolder.mDownloadPb.setText(""); + viewHolder.overlayTv.setVisibility(View.VISIBLE); + } } else { if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL)) { viewHolder.mDownloadPb.setText(R.string.browser_install_install); diff --git a/app/src/main/java/com/gh/common/util/PackageUtils.java b/app/src/main/java/com/gh/common/util/PackageUtils.java index 4cac0e49b5..a272b3b028 100644 --- a/app/src/main/java/com/gh/common/util/PackageUtils.java +++ b/app/src/main/java/com/gh/common/util/PackageUtils.java @@ -120,6 +120,11 @@ public class PackageUtils { // 根据版本判断是否需要更新 shouldShowUpdate = new Version(versionFromRequest).isHigherThan(versionFromInstalledApp); + // versionName 没法判定的时候尝试使用 versionCode 去判断 + if (!shouldShowUpdate && versionCodeFromRequest != 0) { + shouldShowUpdate = versionCodeFromRequest > versionCodeFromInstalledApp; + } + // 畅玩游戏根据 md5 是否一致确定是否需要更新 if (gameEntity.isVGame()) { DownloadEntity entity = DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(apkEntity.getPackageName()); @@ -127,17 +132,10 @@ public class PackageUtils { String md5FromInstalledVGame = ExtensionsKt.getMetaExtra(entity, Constants.APK_MD5); String md5FromRequest = apkEntity.getMd5(); - if (md5FromRequest != null && !md5FromRequest.equals(md5FromInstalledVGame)) { - shouldShowUpdate = true; - } + shouldShowUpdate = md5FromRequest != null && !md5FromRequest.equals(md5FromInstalledVGame); } } - // versionName 没法判定的时候尝试使用 versionCode 去判断 - if (!shouldShowUpdate && versionCodeFromRequest != 0) { - shouldShowUpdate = versionCodeFromRequest > versionCodeFromInstalledApp; - } - if (shouldShowUpdate) { GameUpdateEntity updateEntity = new GameUpdateEntity(); updateEntity.setId(gameEntity.getId()); diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index d694c4f487..69de770f82 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -158,14 +158,10 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { } unplayedEntityList.removeAll { it.packageName == fixedTopEntity?.packageName } - unplayedEntityList.sortedByDescending { - it.start - } + unplayedEntityList.sortedBy { it.start } playedEntityList.removeAll { it.packageName == fixedTopEntity?.packageName } - playedEntityList.sortedByDescending { - VHelper.getLastPlayedTime(it) - } + playedEntityList.sortedBy { VHelper.getTotalPlayedTime(it.packageName) } fixedTopEntity?.let { sortedEntityList.add(it) } sortedEntityList.addAll(unplayedEntityList) diff --git a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt index 90f9847d26..9e3977741d 100644 --- a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt +++ b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt @@ -258,7 +258,11 @@ object PackageRepository { addUpdateOrPluggable(updateEntity) } return true + } else if (game.isVGame()) { + // 畅玩游戏移除更新,避免死循环更新 + removeUpdate(game.id) } + return false } @@ -351,6 +355,14 @@ object PackageRepository { if (!isExist) gameUpdate.add(data) } + /** + * 移除更新 + * @param gameId 游戏 ID + */ + private fun removeUpdate(gameId: String) { + gameUpdate.removeAll { it.id == gameId } + } + /** * 新增已安装的游戏 * @param pkgName 已安装的游戏包名 diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index da83fbb4a0..8d72fc7b93 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -479,6 +479,15 @@ object VHelper { } } + /** + * 获取游戏的游玩时长 + */ + fun getTotalPlayedTime(packageName: String): Long { + return mInstalledInfoList.firstOrNull { + it.packageName == packageName + }?.appTotalPlayTime ?: 0L + } + /** * 根据包名获取下载快照 */ From dc8280c025330624107e5ace5eb9b42b6d9e8e6e Mon Sep 17 00:00:00 2001 From: juntao Date: Fri, 24 Jun 2022 10:47:19 +0800 Subject: [PATCH 046/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=9C=80?= =?UTF-8?q?=E8=BF=91=E5=9C=A8=E7=8E=A9=E5=8C=BA=E5=9F=9F=E9=97=AA=E7=83=81?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/gamecenter/home/HomeItemData.kt | 8 ++- .../com/gh/gamecenter/home/HomeViewModel.kt | 50 ++++++-------- .../gh/vspace/HomeRecentVGameViewHolder.kt | 66 +++++++++--------- .../main/java/com/gh/vspace/VGameItemData.kt | 67 +++++++++++++++++++ .../res/layout/layout_float_load_complete.xml | 7 +- 5 files changed, 131 insertions(+), 67 deletions(-) create mode 100644 app/src/main/java/com/gh/vspace/VGameItemData.kt diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeItemData.kt b/app/src/main/java/com/gh/gamecenter/home/HomeItemData.kt index 8b4e6fb9f9..89717b960a 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeItemData.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeItemData.kt @@ -1,13 +1,17 @@ package com.gh.gamecenter.home -import com.gh.gamecenter.entity.* +import com.gh.gamecenter.entity.AmwayCommentEntity +import com.gh.gamecenter.entity.HomeContent +import com.gh.gamecenter.entity.HomeRecommend +import com.gh.gamecenter.entity.HomeSlide import com.gh.gamecenter.gamecollection.square.GameCollectionListItemData +import com.gh.vspace.VGameItemData data class HomeItemData(var slides: List? = null, var recommends: List? = null, var amway: List? = null, var gameCollection: List? = null, var attachGame: HomeContent? = null, - var recentVGame: ArrayList? = null, + var recentVGame: ArrayList? = null, var lineDivider: Float? = null, var unknownData: Any? = null) : LegacyHomeItemData() \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index 69de770f82..a6cb36cefe 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -26,10 +26,10 @@ import com.gh.gamecenter.game.rank.RankCollectionAdapter import com.gh.gamecenter.gamecollection.square.GameCollectionListItemData import com.gh.gamecenter.packagehelper.PackageRepository import com.gh.gamecenter.retrofit.RetrofitManager +import com.gh.vspace.VGameItemData import com.gh.vspace.VHelper import com.halo.assistant.HaloApp import com.halo.assistant.fragment.SettingsFragment -import com.lightgame.download.DownloadEntity import com.lightgame.utils.Utils import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers @@ -48,7 +48,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { private var mHomeContents = ArrayList() private var mPluginList: List? = null // 插件化 private var mSmartSubject: SubjectEntity? = null // 智能推荐专题 - private var mVGameList: ArrayList? = null // 最近的畅玩游戏 + private var mVGameList: ArrayList? = null // 最近的畅玩游戏 private var mContentPage = 1 // 专题分页 private var mIsLoading = false @@ -100,14 +100,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { val entityList = getSortedVEntityList() if (entityList.isNotEmpty()) { - val vGameList = arrayListOf() - - for (entity in entityList) { - // TODO 添加更多的信息供页面确定是否有更新 - vGameList.add(VHelper.toGameEntity(entity)) - } - - mVGameList = vGameList + mVGameList = ArrayList(entityList) if (mHomeSlides.isNotEmpty() || mHomeRecommends.isNotEmpty()) { transformationItemData() @@ -130,38 +123,38 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { * 完成下载但未启动过的游戏:按照点击下载的时间倒序排列 * 完成下载且已启动过的游戏:按照游戏的畅玩时长从左(长)向右(短)排列 */ - private fun getSortedVEntityList() : List { + private fun getSortedVEntityList() : List { val rawEntityList = DownloadManager.getInstance().allVDownloadTaskSnapshots - var fixedTopEntity: DownloadEntity? = null - val unplayedEntityList = arrayListOf() - val playedEntityList = arrayListOf() - val sortedEntityList = arrayListOf() + var fixedTopEntity: VGameItemData? = null + val unplayedEntityList = arrayListOf() + val playedEntityList = arrayListOf() + val sortedEntityList = arrayListOf() - for (entity in rawEntityList) { - val lastPlayedTime = VHelper.getLastPlayedTime(entity) - val latestModifiedTime = maxOf(entity.start, VHelper.getLastPlayedTime(entity)) + for (rawEntity in rawEntityList) { + val lastPlayedTime = VHelper.getLastPlayedTime(rawEntity) + val latestModifiedTime = maxOf(rawEntity.start, VHelper.getLastPlayedTime(rawEntity)) if (fixedTopEntity == null) { - fixedTopEntity = entity + fixedTopEntity = VGameItemData.fromDownloadEntity(rawEntity) } else { - val fixedTopLatestModifiedTime = maxOf(fixedTopEntity.start, VHelper.getLastPlayedTime(fixedTopEntity)) + val fixedTopLatestModifiedTime = maxOf(fixedTopEntity.downloadEntity.start, VHelper.getLastPlayedTime(fixedTopEntity.downloadEntity)) if (latestModifiedTime > fixedTopLatestModifiedTime) { - fixedTopEntity = entity + fixedTopEntity = VGameItemData.fromDownloadEntity(rawEntity) } } if (lastPlayedTime == 0L) { - unplayedEntityList.add(entity) + unplayedEntityList.add(VGameItemData.fromDownloadEntity(rawEntity)) } else { - playedEntityList.add(entity) + playedEntityList.add(VGameItemData.fromDownloadEntity(rawEntity)) } } - unplayedEntityList.removeAll { it.packageName == fixedTopEntity?.packageName } - unplayedEntityList.sortedBy { it.start } + unplayedEntityList.removeAll { it.downloadEntity.packageName == fixedTopEntity?.downloadEntity?.packageName } + unplayedEntityList.sortedBy { it.downloadEntity.start } - playedEntityList.removeAll { it.packageName == fixedTopEntity?.packageName } - playedEntityList.sortedBy { VHelper.getTotalPlayedTime(it.packageName) } + playedEntityList.removeAll { it.downloadEntity.packageName == fixedTopEntity?.downloadEntity?.packageName } + playedEntityList.sortedBy { VHelper.getTotalPlayedTime(it.downloadEntity.packageName) } fixedTopEntity?.let { sortedEntityList.add(it) } sortedEntityList.addAll(unplayedEntityList) @@ -409,7 +402,8 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { mSnapshotItemList.add(item) for (entity in mVGameList!!) { - addGamePositionAndPackage(entity) + val packageName = entity.downloadEntity.packageName + positionAndPackageMap[packageName + (mSnapshotItemList.size - 1)] = mSnapshotItemList.size - 1 } } diff --git a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt index b24a06bb00..7072affd47 100644 --- a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt +++ b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt @@ -8,17 +8,12 @@ import androidx.recyclerview.widget.RecyclerView.OnScrollListener import com.gh.download.DownloadManager import com.gh.gamecenter.R import com.gh.gamecenter.baselist.DiffUtilAdapter -import com.gh.gamecenter.common.utils.goneIf -import com.gh.gamecenter.common.utils.toBinding -import com.gh.gamecenter.common.utils.toDrawable -import com.gh.gamecenter.common.utils.visibleIf +import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.common.view.GridSpacingItemColorDecoration -import com.gh.gamecenter.core.runOnIoThread -import com.gh.gamecenter.core.runOnUiThread import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.databinding.ItemHomeRecentVgameBinding import com.gh.gamecenter.databinding.ItemHomeVgameBinding -import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.manager.PackagesManager import com.lightgame.download.DownloadEntity import com.lightgame.download.DownloadStatus @@ -26,9 +21,10 @@ import com.lightgame.download.DownloadStatus class HomeRecentVGameViewHolder(var binding: ItemHomeRecentVgameBinding) : RecyclerView.ViewHolder(binding.root) { - fun bindView(gameList: ArrayList) { + fun bindView(entityList: ArrayList) { if (binding.recyclerView.adapter == null) { - val layoutManager = LinearLayoutManager(binding.root.context, RecyclerView.HORIZONTAL, false) + val layoutManager = + LinearLayoutManager(binding.root.context, RecyclerView.HORIZONTAL, false) binding.recyclerView.layoutManager = layoutManager binding.recyclerView.itemAnimator = null @@ -37,9 +33,10 @@ class HomeRecentVGameViewHolder(var binding: ItemHomeRecentVgameBinding) : GridSpacingItemColorDecoration(binding.root.context, 4, 0, R.color.transparent) ) - binding.recyclerView.addOnScrollListener(object: OnScrollListener() { + binding.recyclerView.addOnScrollListener(object : OnScrollListener() { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { - val scrollToEnd = layoutManager.findLastCompletelyVisibleItemPosition() == (binding.recyclerView.adapter!!.itemCount - 1) + val scrollToEnd = + layoutManager.findLastCompletelyVisibleItemPosition() == (binding.recyclerView.adapter!!.itemCount - 1) binding.divider.visibleIf(scrollToEnd) } }) @@ -51,11 +48,11 @@ class HomeRecentVGameViewHolder(var binding: ItemHomeRecentVgameBinding) : } } - (binding.recyclerView.adapter as? HomeRecentVGameAdapter)?.submitList(gameList) + (binding.recyclerView.adapter as? HomeRecentVGameAdapter)?.submitList(entityList) } } -class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter(context) { +class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter(context) { override fun onCreateViewHolder( parent: ViewGroup, @@ -77,41 +74,44 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter(con notifyDataSetChanged() } else { for (position in mDataList.indices) { - if (downloadEntity.name == mDataList[position].name) { + if (downloadEntity.name == mDataList[position].downloadEntity.name) { + mDataList[position].downloadEntity = downloadEntity notifyItemChanged(position) } } } } - override fun areItemsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean { - return false + override fun areItemsTheSame(oldItem: VGameItemData?, newItem: VGameItemData?): Boolean { + return oldItem == newItem } - override fun areContentsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean { - return false + override fun areContentsTheSame(oldItem: VGameItemData?, newItem: VGameItemData?): Boolean { + // VGameItemData 里除了 downloadEntity 以外的内容仅作是否内容发生变更的判断, + // 并不应用到实际状态当中,最后还是得从 downloadEntity 里实时获取判断, + // 别问,问就是下载管理跟实际列表更新两边很难扯在一起 + + return oldItem?.downloadEntity == newItem?.downloadEntity + && oldItem?.shouldShowControlTv == newItem?.shouldShowControlTv + && oldItem?.shouldShowDot == newItem?.shouldShowDot + && oldItem?.shouldShowMask == newItem?.shouldShowMask + && oldItem?.shouldShowUpdate == newItem?.shouldShowUpdate + && oldItem?.shouldShowProgressBar == newItem?.shouldShowProgressBar } class HomeRecentVGameItemViewHolder(private var mBinding: ItemHomeVgameBinding) : RecyclerView.ViewHolder(mBinding.root) { - fun bindView(gameEntity: GameEntity) { - if (mBinding.gameIconIv.getTag(R.string.app_name) != gameEntity.id) { - mBinding.gameIconIv.displayGameIcon(gameEntity) - mBinding.gameIconIv.setTag(R.string.app_name, gameEntity.id) + fun bindView(entity: VGameItemData) { + if (mBinding.gameIconIv.getTag(R.string.app_name) != entity.downloadEntity.packageName) { + mBinding.gameIconIv.displayGameIcon( + entity.downloadEntity.getMetaExtra(Constants.RAW_GAME_ICON), + entity.downloadEntity.getMetaExtra(Constants.GAME_ICON_SUBSCRIPT) + ) + mBinding.gameIconIv.setTag(R.string.app_name, entity.downloadEntity.packageName) } - runOnIoThread(true) { - val downloadEntity = DownloadManager.getInstance().allVDownloadTaskSnapshots.find { - it.gameId == gameEntity.id - } - // TODO 处理页面被 detach 时候的回调 - if (downloadEntity != null) { - runOnUiThread { - updateViewByStatus(mBinding, downloadEntity) - } - } - } + updateViewByStatus(mBinding, entity.downloadEntity) } private fun updateViewByStatus( diff --git a/app/src/main/java/com/gh/vspace/VGameItemData.kt b/app/src/main/java/com/gh/vspace/VGameItemData.kt new file mode 100644 index 0000000000..8d78e6a45b --- /dev/null +++ b/app/src/main/java/com/gh/vspace/VGameItemData.kt @@ -0,0 +1,67 @@ +package com.gh.vspace + +import com.gh.gamecenter.manager.PackagesManager +import com.lightgame.download.DownloadEntity +import com.lightgame.download.DownloadStatus + +data class VGameItemData( + var downloadEntity: DownloadEntity, + + var shouldShowMask: Boolean = false, + var shouldShowProgressBar: Boolean = false, + var shouldShowUpdate: Boolean = false, + var shouldShowControlTv: Boolean = false, + var shouldShowDot: Boolean = false, + var controlText: String = "继续" +) { + companion object { + fun fromDownloadEntity(downloadEntity: DownloadEntity): VGameItemData { + return VGameItemData(downloadEntity).apply { + if (downloadEntity.status == DownloadStatus.done + && VHelper.getLastPlayedTime(downloadEntity) == 0L + ) { + shouldShowDot = true + } + + if (PackagesManager.isCanUpdate( + downloadEntity.gameId, + downloadEntity.packageName + ) + ) { + shouldShowUpdate = true + } + + when (downloadEntity.status) { + DownloadStatus.done -> { + // do nothing + } + DownloadStatus.pause, + DownloadStatus.subscribe, + DownloadStatus.waiting -> { + shouldShowMask = true + shouldShowProgressBar = true + shouldShowControlTv = true + } + DownloadStatus.downloading -> { + shouldShowMask = true + shouldShowProgressBar = true + } + + DownloadStatus.timeout, + DownloadStatus.neterror, + DownloadStatus.hijack, + DownloadStatus.uncertificated, + DownloadStatus.unqualified, + DownloadStatus.notfound, + DownloadStatus.unavailable, + DownloadStatus.overflow -> { + controlText = "重试" + } + else -> { + // do nothing + } + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/layout_float_load_complete.xml b/app/src/main/res/layout/layout_float_load_complete.xml index f2ffac0b28..a492126422 100644 --- a/app/src/main/res/layout/layout_float_load_complete.xml +++ b/app/src/main/res/layout/layout_float_load_complete.xml @@ -1,11 +1,10 @@ Date: Fri, 24 Jun 2022 11:59:24 +0800 Subject: [PATCH 047/217] =?UTF-8?q?fix:=20=E8=B0=83=E6=95=B4=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E6=B8=B8=E6=88=8F=E4=B8=8B=E8=BD=BD=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E5=BC=B9=E7=AA=97=E9=AB=98=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt b/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt index 8ad64896fe..2b48b95332 100644 --- a/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt +++ b/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt @@ -84,7 +84,7 @@ object VLoadCompleteWindowHelper { .setTag(LOAD_COMPLETE_WINDOW) .setDragEnable(false) .setMatchParent(widthMatch = true, heightMatch = false) - .setGravity(Gravity.BOTTOM, 0, (-78F).dip2px()) + .setGravity(Gravity.BOTTOM, 0, (-62F).dip2px()) .setAnimator(LoadCompleteFloatAnimator()) .registerCallback { createResult { _, _, view -> From e715a4628545901e39c4dbcf990cdc9e81410caa Mon Sep 17 00:00:00 2001 From: juntao Date: Fri, 24 Jun 2022 16:29:30 +0800 Subject: [PATCH 048/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=83=A8?= =?UTF-8?q?=E5=88=86=E4=BD=8D=E7=BD=AE=E6=97=A0=E6=B3=95=E8=A7=A6=E5=8F=91?= =?UTF-8?q?=E7=95=85=E7=8E=A9=E6=B8=B8=E6=88=8F=E4=B8=A2=E5=A4=B1=E9=87=8D?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/gh/common/databind/BindingAdapters.java | 5 +++++ app/src/main/java/com/gh/common/util/DownloadItemUtils.kt | 7 ++++++- .../gh/gamecenter/adapter/viewholder/DetailViewHolder.java | 5 +++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java index d7259e9052..c2b71add36 100644 --- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java +++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java @@ -451,6 +451,11 @@ public class BindingAdapters { case INSTALL_NORMAL: if (gameEntity.getApk().size() == 1) { DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByUrl(gameEntity.getApk().get(0).getUrl()); + if (gameEntity.isVGame()) { + VHelper.installOrLaunch((AppCompatActivity) v.getContext(), gameEntity.getApk().get(0).getPackageName()); + return; + } + if (downloadEntity != null) { PackageInstaller.install(v.getContext(), downloadEntity); } diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index 6ea6538a29..bfd99d3a99 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -742,7 +742,12 @@ object DownloadItemUtils { return } } - install(context, gameEntity, position, adapter, refreshCallback) + + if (gameEntity.isVGame()) { + VHelper.installOrLaunch((context as AppCompatActivity), gameEntity.getUniquePackageName() ?: "") + } else { + install(context, gameEntity, position, adapter, refreshCallback) + } } else if (str == context.getString(R.string.launch)) { EnergyTaskHelper.postEnergyTask("play_game", gameEntity.id, gameEntity.getApk()[0].packageName) diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java index dbbe28da84..157d25d656 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java @@ -278,6 +278,11 @@ public class DetailViewHolder { mDownloadEntity = DownloadManager.getInstance().getDownloadEntityByUrl(mGameEntity.getApk().get(0).getUrl()); } if (mDownloadEntity != null) { + if (mGameEntity.isVGame()) { + VHelper.installOrLaunch((AppCompatActivity) v.getContext(), mGameEntity.getApk().get(0).getPackageName()); + return; + } + final String path = mDownloadEntity.getPath(); if (FileUtils.isEmptyFile(path)) { Utils.toast(mViewHolder.context, R.string.install_failure_hint); From a488608969b454b8496116ba6e78b7519a9bda19 Mon Sep 17 00:00:00 2001 From: juntao Date: Fri, 24 Jun 2022 17:35:50 +0800 Subject: [PATCH 049/217] =?UTF-8?q?fix:=20=E8=B0=83=E6=95=B4=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E8=AF=A6=E6=83=85=E9=A1=B5=E6=8C=89=E9=92=AE=E6=96=87?= =?UTF-8?q?=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/common/util/DetailDownloadUtils.java | 92 +++++++++++++++++-- .../com/gh/vspace/VDownloadManagerAdapter.kt | 2 +- .../gh/vspace/VDownloadManagerViewModel.kt | 5 +- .../vspace/VDownloadManagerWrapperFragment.kt | 7 ++ app/src/main/java/com/gh/vspace/VHelper.kt | 2 +- 5 files changed, 95 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index b3e235472a..96c15ce359 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -49,7 +49,6 @@ public class DetailDownloadUtils { if (viewHolder.gameEntity.isReservable()) { if (!ReservationRepository.thisGameHasBeenReserved(viewHolder.gameEntity.getId())) { - if (TextUtils.isEmpty(downloadAddWord)) { viewHolder.mDownloadPb.setText(String.format("预约" + "《%s》", viewHolder.gameEntity.getName())); } else { @@ -63,6 +62,37 @@ public class DetailDownloadUtils { return; } + if (viewHolder.gameEntity.isVGame()) { + String status = GameUtils.getDownloadBtnText(viewHolder.context, viewHolder.gameEntity, PluginLocation.only_game); + if (viewHolder.context.getString(R.string.launch).equals(status)) { + viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.LAUNCH_OR_OPEN); + } else if (viewHolder.context.getString(R.string.install).equals(status)) { + viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL); + } else { + viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.NORMAL); + } + + String downloadText; + if (viewHolder.context.getString(R.string.launch).equals(status) || viewHolder.context.getString(R.string.install).equals(status) || viewHolder.context.getString(R.string.download).equals(status)) { + downloadText = ""; + viewHolder.overlayTv.setVisibility(View.VISIBLE); + } else if (viewHolder.context.getString(R.string.attempt).equals(status)) { + downloadText = status + getDownloadSizeText(viewHolder); + } else { + downloadText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : downloadAddWord) + getDownloadSizeText(viewHolder); + } + viewHolder.mDownloadPb.setText(downloadText); + + String url = viewHolder.gameEntity.getApk().get(0).getUrl(); + DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntityByUrl(url); + if (downloadEntity != null) { + viewHolder.downloadEntity = downloadEntity; + detailInvalidate(viewHolder); + } + + return; + } + if (viewHolder.gameEntity.getApk().isEmpty() || viewHolder.gameEntity.getDownloadOffStatus() != null) { LinkEntity h5LinkEntity = viewHolder.gameEntity.getH5Link(); @@ -104,19 +134,11 @@ public class DetailDownloadUtils { } else if (viewHolder.context.getString(R.string.pluggable).equals(status)) { downloadText = "升级" + (TextUtils.isEmpty(downloadAddWord) ? "" : "至" + downloadAddWord) + getDownloadSizeText(viewHolder); } else if (viewHolder.context.getString(R.string.launch).equals(status)) { - if (viewHolder.gameEntity.isVGame()) { - downloadText = ""; - viewHolder.overlayTv.setVisibility(View.VISIBLE); - } else { - downloadText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : "-" + downloadAddWord); - } + downloadText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : "-" + downloadAddWord); } else if (viewHolder.context.getString(R.string.attempt).equals(status)) { downloadText = status + getDownloadSizeText(viewHolder); } else if (viewHolder.context.getString(R.string.install).equals(status)) { downloadText = viewHolder.context.getString(R.string.install); - } else if (viewHolder.context.getString(R.string.download).equals(status) - && viewHolder.gameEntity.isVGame()) { - downloadText = viewHolder.context.getString(R.string.smooth_launch); } else { downloadText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : downloadAddWord) + getDownloadSizeText(viewHolder); } @@ -125,6 +147,7 @@ public class DetailDownloadUtils { viewHolder.mDownloadPb.setText("选择下载你的版本" + (TextUtils.isEmpty(downloadAddWord) ? "" : "-" + downloadAddWord) + " >"); viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.NORMAL); } + if (isCheck && viewHolder.gameEntity.getApk().size() == 1) { String url = viewHolder.gameEntity.getApk().get(0).getUrl(); DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntityByUrl(url); @@ -153,6 +176,12 @@ public class DetailDownloadUtils { viewHolder.mDownloadPb.setProgress((int) (viewHolder.downloadEntity.getPercent() * 10)); viewHolder.overlayTv.setVisibility(View.GONE); + + if (viewHolder.gameEntity.isVGame()) { + updateVStyleButton(viewHolder); + return; + } + switch (downloadEntity.getStatus()) { case downloading: case pause: @@ -231,4 +260,47 @@ public class DetailDownloadUtils { break; } } + + private static void updateVStyleButton(DetailViewHolder viewHolder) { + switch (viewHolder.downloadEntity.getStatus()) { + case downloading: + case overflow: + viewHolder.mDownloadPb.setText("游戏加载中 " + viewHolder.downloadEntity.getPercent() + "%"); + viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.DOWNLOADING_NORMAL); + break; + case timeout: + case neterror: + case waiting: + case subscribe: + viewHolder.mDownloadPb.setText(R.string.waiting); + viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.DOWNLOADING_NORMAL); + break; + case pause: + viewHolder.mDownloadPb.setText("继续加载 " + viewHolder.downloadEntity.getPercent() + "%"); + viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.DOWNLOADING_NORMAL); + break; + case done: + if (!viewHolder.mDownloadPb.getText().contains("更新")) { + if (VHelper.isInstalled(viewHolder.downloadEntity.getPackageName())) { + viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.LAUNCH_OR_OPEN); + } else { + viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL); + } + + viewHolder.mDownloadPb.setText(""); + viewHolder.overlayTv.setVisibility(View.VISIBLE); + break; + } + case cancel: + case hijack: + case notfound: + case uncertificated: + case unqualified: + case unavailable: + detailInitDownload(viewHolder, false); + break; + default: + break; + } + } } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index ad9bdcb048..394fa2b84c 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -101,7 +101,7 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa BindingAdapters.setGameName(holder.binding.nameTv, gameEntity, false, true) holder.binding.iconIv.displayGameIcon(gameEntity) - holder.binding.descTv.goneIf(!mViewModel.isTypeDownloaded()) + holder.binding.descTv.goneIf(!mViewModel.isTypeDownloaded() || gameEntity.des?.isEmpty() == true) holder.binding.descTv.text = gameEntity.des (holder.binding.selectIv.layoutParams as ConstraintLayout.LayoutParams).apply { diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index 95bbc0ef18..6f8cf7d13e 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -42,7 +42,10 @@ class VDownloadManagerViewModel(application: Application) : if (gameEntity.playedTime != 0L) { gameEntity.des = "已畅玩${NumberUtils.transSimpleUsageTime(gameEntity.playedTime / 1000 / 1000)}" } else { - gameEntity.des = "已占用${VHelper.getAppOccupiedSpace(downloadEntity.packageName).toProperReadableSize()}" + val occupiedSpace = VHelper.getAppOccupiedSpace(downloadEntity.packageName) + if (occupiedSpace > 0 ) { + gameEntity.des = "已占用 ${occupiedSpace.toProperReadableSize()}" + } } vGameList.add(gameEntity) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt index eb328cdf9d..31475e91b0 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt @@ -23,6 +23,13 @@ class VDownloadManagerWrapperFragment: BaseLazyTabFragment() { override fun getLayoutId() = 0 override fun getInflatedLayout() = mBinding.root + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + // 进入的时候再连接一遍服务,尽量保证能用 + VHelper.connectService() + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 8d72fc7b93..e7c8bf30e4 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -98,7 +98,7 @@ object VHelper { /** * 连接服务 */ - private fun connectService(callbackClosure: (() -> Unit)? = null) { + fun connectService(callbackClosure: (() -> Unit)? = null) { mDelegateManager.connectService(object : RemoteConnectListener { override fun onServiceConnectionSuccessed() { Utils.log(LOG_TAG, "V 服务连接成功") From c091a479000e31421703671e7212988920453d3c Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 28 Jun 2022 17:44:39 +0800 Subject: [PATCH 050/217] =?UTF-8?q?fix:=20=E5=BE=AE=E8=B0=83=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt | 7 ++++++- app/src/main/java/com/gh/vspace/VHelper.kt | 6 ++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index 394fa2b84c..b76946b56a 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -138,14 +138,19 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa DialogHelper.showDialog(holder.binding.root.context, "删除游戏", "单机类游戏被删除将可能导致本地存档、充值数据丢失,请确认后操作(网游类游戏删除不会影响游戏存档和充值数据)", + "再等等", "删除", - "再等等", { + {}, + { val apk = gameEntity.getApk().firstOrNull() mViewModel.removeItem(apk?.url, apk?.packageName) AppExecutor.uiExecutor.executeWithDelay({ mViewModel.load(LoadType.REFRESH) }, 200) + }, uiModificationCallback = { + it.cancelTv.setTextColor(R.color.theme_red.toColor(it.root.context)) + it.confirmTv.setTextColor(R.color.text_subtitle.toColor(it.root.context)) }) } } diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index e7c8bf30e4..bc8b8f624e 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -4,7 +4,6 @@ import android.Manifest import android.annotation.SuppressLint import android.content.Context import android.content.Intent -import android.net.Uri import android.text.TextUtils import android.view.View import androidx.appcompat.app.AppCompatActivity @@ -21,7 +20,10 @@ import com.gh.gamecenter.R import com.gh.gamecenter.SplashScreenActivity import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.retrofit.BiResponse -import com.gh.gamecenter.common.utils.* +import com.gh.gamecenter.common.utils.DialogHelper +import com.gh.gamecenter.common.utils.addMetaExtra +import com.gh.gamecenter.common.utils.getMetaExtra +import com.gh.gamecenter.common.utils.toColor import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.core.runOnUiThread From d4a651ce63b77e3d8733d53509c5053964104e29 Mon Sep 17 00:00:00 2001 From: juntao Date: Wed, 29 Jun 2022 09:35:47 +0800 Subject: [PATCH 051/217] =?UTF-8?q?fix:=20=E7=BC=96=E8=AF=91=E5=BC=82?= =?UTF-8?q?=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VHelper.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index bc8b8f624e..c37358ab04 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -119,11 +119,11 @@ object VHelper { } private fun invokeVSpace() { - tryWithDefaultCatch { - val intent = Intent(Intent.ACTION_VIEW, Uri.parse("vsserver://invoke_only")) - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - HaloApp.getInstance().startActivity(intent) - } +// tryWithDefaultCatch { +// val intent = Intent(Intent.ACTION_VIEW, Uri.parse("vsserver://invoke_only")) +// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) +// HaloApp.getInstance().startActivity(intent) +// } } private fun updateInstalledList() { From 983bbfc3093835e6289a29ceb15aec9eeaa3dfdc Mon Sep 17 00:00:00 2001 From: juntao Date: Wed, 29 Jun 2022 14:41:41 +0800 Subject: [PATCH 052/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E7=8A=B6=E6=80=81=E6=9B=B4=E6=96=B0=E4=B8=8D=E5=8F=8A?= =?UTF-8?q?=E6=97=B6=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/download/DownloadManager.java | 14 ++++++++++++++ .../com/gh/gamecenter/LibaoDetailActivity.java | 5 +++++ .../com/gh/gamecenter/NewsDetailActivity.java | 5 +++++ .../com/gh/gamecenter/amway/AmwayFragment.kt | 13 +++++++++---- .../gamecenter/catalog/NewCatalogListFragment.kt | 16 +++++++++++----- .../category/NewCategoryListFragment.kt | 8 ++++++-- .../category2/CategoryV2ListFragment.kt | 7 +++++-- .../java/com/gh/gamecenter/game/GameFragment.kt | 12 ++++++++---- .../detail/GameCollectionDetailFragment.kt | 4 ++++ .../gamecenter/gamedetail/GameDetailFragment.kt | 4 ++++ .../gamedetail/rating/RatingReplyActivity.kt | 6 +++++- .../java/com/gh/gamecenter/home/HomeFragment.kt | 4 ++++ .../qa/video/detail/ForumVideoDetailFragment.kt | 4 ++++ .../gamecenter/search/SearchGameIndexFragment.kt | 6 +++++- .../search/SearchGameResultFragment.kt | 4 ++++ .../simulatorgame/SimulatorGameListFragment.kt | 13 ++++++++----- .../gh/gamecenter/subject/SubjectListFragment.kt | 10 +++++++--- .../com/gh/gamecenter/tag/TagsListFragment.kt | 12 ++++++++---- .../com/gh/vspace/VDownloadManagerFragment.kt | 4 ++++ .../java/com/gh/vspace/VSpaceLoadingFragment.kt | 6 +++--- 20 files changed, 123 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index 6d03bb3bf8..c85d1568e9 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -846,6 +846,8 @@ public class DownloadManager implements DownloadStatusListener { public void addObserver(DataWatcher dataWatcher) { Utils.log(DownloadManager.class.getSimpleName(), "addObserver"); DataChanger.INSTANCE.addObserver(dataWatcher); + + notifyDownloadedStatusASAP(dataWatcher); } /** @@ -856,6 +858,18 @@ public class DownloadManager implements DownloadStatusListener { DataChanger.INSTANCE.deleteObserver(dataWatcher); } + /** + * 立马通知 dataWatcher 更新已下载完的任务状态,这里的下载完成是持久状态,不是瞬时状态 + * + */ + private void notifyDownloadedStatusASAP(DataWatcher dataWatcher) { + for (DownloadEntity downloadEntity : getAllDownloadEntitySnapshots()) { + if (downloadEntity.getStatus() == DownloadStatus.done) { + dataWatcher.onDataInit(downloadEntity); + } + } + } + /** * 初始化下载服务 */ diff --git a/app/src/main/java/com/gh/gamecenter/LibaoDetailActivity.java b/app/src/main/java/com/gh/gamecenter/LibaoDetailActivity.java index 12650cb58e..6ed2dd08f5 100644 --- a/app/src/main/java/com/gh/gamecenter/LibaoDetailActivity.java +++ b/app/src/main/java/com/gh/gamecenter/LibaoDetailActivity.java @@ -142,6 +142,11 @@ public class LibaoDetailActivity extends ToolBarActivity implements LibaoDetailA } } } + + @Override + public void onDataInit(@NonNull DownloadEntity downloadEntity) { + onDataChanged(downloadEntity); + } }; diff --git a/app/src/main/java/com/gh/gamecenter/NewsDetailActivity.java b/app/src/main/java/com/gh/gamecenter/NewsDetailActivity.java index 6d1ec9dcd3..2a528c0daa 100644 --- a/app/src/main/java/com/gh/gamecenter/NewsDetailActivity.java +++ b/app/src/main/java/com/gh/gamecenter/NewsDetailActivity.java @@ -140,6 +140,11 @@ public class NewsDetailActivity extends DownloadToolbarActivity implements OnCli } } } + + @Override + public void onDataInit(@NonNull DownloadEntity downloadEntity) { + onDataChanged(downloadEntity); + } }; Runnable runnable = new Runnable() { diff --git a/app/src/main/java/com/gh/gamecenter/amway/AmwayFragment.kt b/app/src/main/java/com/gh/gamecenter/amway/AmwayFragment.kt index cc7ac99b15..a1514979d0 100644 --- a/app/src/main/java/com/gh/gamecenter/amway/AmwayFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/amway/AmwayFragment.kt @@ -9,12 +9,9 @@ import androidx.core.content.ContextCompat import androidx.core.view.ViewCompat import androidx.recyclerview.widget.RecyclerView import com.ethanhua.skeleton.Skeleton -import com.gh.gamecenter.core.utils.TimeElapsedHelper import com.gh.common.exposure.ExposureListener import com.gh.common.exposure.ExposureSource -import com.gh.common.util.* import com.gh.common.util.DialogUtils -import com.gh.gamecenter.common.view.VerticalItemDecoration import com.gh.common.xapk.XapkInstaller import com.gh.common.xapk.XapkUnzipStatus import com.gh.download.DownloadManager @@ -24,7 +21,11 @@ import com.gh.gamecenter.baselist.LazyListFragment import com.gh.gamecenter.baselist.ListAdapter import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.* -import com.gh.gamecenter.core.utils.* +import com.gh.gamecenter.common.view.VerticalItemDecoration +import com.gh.gamecenter.core.utils.ClickUtils +import com.gh.gamecenter.core.utils.DisplayUtils +import com.gh.gamecenter.core.utils.MtaHelper +import com.gh.gamecenter.core.utils.TimeElapsedHelper import com.gh.gamecenter.databinding.FragmentAmwayAlBinding import com.gh.gamecenter.databinding.FragmentAmwayBinding import com.gh.gamecenter.entity.RatingComment @@ -64,6 +65,10 @@ class AmwayFragment : LazyListFragment() { showUnzipFailureDialog(downloadEntity) } } + + override fun onDataInit(downloadEntity: DownloadEntity) { + mAdapter?.notifyItemByDownload(downloadEntity) + } } override fun onCreate(savedInstanceState: Bundle?) { diff --git a/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListFragment.kt b/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListFragment.kt index 979389be63..0c94c8485a 100644 --- a/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListFragment.kt @@ -3,22 +3,24 @@ package com.gh.gamecenter.catalog import android.os.Bundle import android.view.View import com.ethanhua.skeleton.Skeleton -import com.gh.gamecenter.common.constant.Constants import com.gh.common.exposure.ExposureListener import com.gh.common.exposure.ExposureSource import com.gh.common.util.DialogUtils -import com.gh.gamecenter.common.constant.EntranceConsts -import com.gh.gamecenter.common.utils.observeNonNull -import com.gh.gamecenter.common.utils.viewModelProvider import com.gh.common.view.CatalogFilterView import com.gh.common.xapk.XapkInstaller import com.gh.common.xapk.XapkUnzipStatus import com.gh.download.DownloadManager import com.gh.gamecenter.R import com.gh.gamecenter.baselist.ListFragment +import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.constant.EntranceConsts +import com.gh.gamecenter.common.utils.observeNonNull import com.gh.gamecenter.common.utils.toColor +import com.gh.gamecenter.common.utils.viewModelProvider import com.gh.gamecenter.databinding.FragmentCatalogListBinding -import com.gh.gamecenter.entity.* +import com.gh.gamecenter.entity.CatalogEntity +import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.entity.SubjectSettingEntity import com.gh.gamecenter.eventbus.EBDownloadStatus import com.gh.gamecenter.eventbus.EBPackage import com.lightgame.download.DataWatcher @@ -42,6 +44,10 @@ class NewCatalogListFragment : ListFragment showUnzipFailureDialog(downloadEntity) } } + + override fun onDataInit(downloadEntity: DownloadEntity) { + mAdapter?.notifyItemByDownload(downloadEntity) + } } private var mBinding: FragmentCatalogListBinding? = null diff --git a/app/src/main/java/com/gh/gamecenter/category/NewCategoryListFragment.kt b/app/src/main/java/com/gh/gamecenter/category/NewCategoryListFragment.kt index 0cede00121..15acd24cf0 100644 --- a/app/src/main/java/com/gh/gamecenter/category/NewCategoryListFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/category/NewCategoryListFragment.kt @@ -4,9 +4,8 @@ import android.os.Bundle import android.view.View import androidx.recyclerview.widget.LinearLayoutManager import com.ethanhua.skeleton.Skeleton -import com.gh.gamecenter.common.constant.Constants import com.gh.common.exposure.ExposureListener -import com.gh.common.util.* +import com.gh.common.util.DialogUtils import com.gh.common.view.ConfigFilterView import com.gh.common.xapk.XapkInstaller import com.gh.common.xapk.XapkUnzipStatus @@ -14,6 +13,7 @@ import com.gh.download.DownloadManager import com.gh.gamecenter.R import com.gh.gamecenter.baselist.ListAdapter import com.gh.gamecenter.baselist.ListFragment +import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.observeNonNull import com.gh.gamecenter.common.utils.toColor @@ -45,6 +45,10 @@ class NewCategoryListFragment : ListFragment showUnzipFailureDialog(downloadEntity) } } + + override fun onDataInit(downloadEntity: DownloadEntity) { + mAdapter?.notifyItemByDownload(downloadEntity) + } } override fun getLayoutId() = 0 diff --git a/app/src/main/java/com/gh/gamecenter/game/GameFragment.kt b/app/src/main/java/com/gh/gamecenter/game/GameFragment.kt index 488be43ddd..d2304afa3f 100644 --- a/app/src/main/java/com/gh/gamecenter/game/GameFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/game/GameFragment.kt @@ -10,22 +10,22 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.ethanhua.skeleton.Skeleton import com.ethanhua.skeleton.ViewSkeletonScreen -import com.gh.gamecenter.common.base.fragment.LazyFragment -import com.gh.gamecenter.common.constant.Constants import com.gh.common.exposure.ExposureListener import com.gh.common.exposure.ExposureSource -import com.gh.common.util.* -import com.gh.gamecenter.common.view.FixLinearLayoutManager +import com.gh.common.util.DialogUtils import com.gh.common.xapk.XapkInstaller import com.gh.common.xapk.XapkUnzipStatus import com.gh.download.DownloadManager import com.gh.gamecenter.R import com.gh.gamecenter.baselist.LoadStatus +import com.gh.gamecenter.common.base.fragment.LazyFragment +import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.dip2px import com.gh.gamecenter.common.utils.goneIf import com.gh.gamecenter.common.utils.toColor import com.gh.gamecenter.common.utils.visibleIf +import com.gh.gamecenter.common.view.FixLinearLayoutManager import com.gh.gamecenter.databinding.FragmentGameBinding import com.gh.gamecenter.eventbus.EBDownloadStatus import com.gh.gamecenter.eventbus.EBPackage @@ -58,6 +58,10 @@ class GameFragment : LazyFragment() { showUnzipFailureDialog(downloadEntity) } } + + override fun onDataInit(downloadEntity: DownloadEntity) { + mListAdapter.notifyItemByDownload(downloadEntity) + } } override fun getRealLayoutId() = R.layout.fragment_game diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailFragment.kt index ecf8a068aa..5352a83b4b 100644 --- a/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailFragment.kt @@ -87,6 +87,10 @@ class GameCollectionDetailFragment : showUnzipFailureDialog(downloadEntity) } } + + override fun onDataInit(downloadEntity: DownloadEntity) { + mAdapter?.notifyItemByDownload(downloadEntity) + } } override fun getLayoutId() = 0 diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt index 8d4c38088b..7e985ddb29 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt @@ -190,6 +190,10 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { } } } + + override fun onDataInit(downloadEntity: DownloadEntity) { + onDataChanged(downloadEntity) + } } // 下载按钮ViewHolder diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingReplyActivity.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingReplyActivity.kt index 033562faea..4d580f32c1 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingReplyActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingReplyActivity.kt @@ -12,8 +12,8 @@ import androidx.core.widget.doOnTextChanged import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.RecyclerView import com.gh.common.exposure.ExposureManager -import com.gh.common.util.* import com.gh.common.util.NewLogUtils +import com.gh.common.util.SyncDataBetweenPageHelper import com.gh.download.DownloadManager import com.gh.gamecenter.R import com.gh.gamecenter.baselist.ListActivity @@ -65,6 +65,10 @@ class RatingReplyActivity : ListActivity() { @@ -36,6 +35,10 @@ class SimulatorGameListFragment : ListFragment { diff --git a/app/src/main/java/com/gh/gamecenter/subject/SubjectListFragment.kt b/app/src/main/java/com/gh/gamecenter/subject/SubjectListFragment.kt index 7fabb2fdb1..bd73d54e78 100644 --- a/app/src/main/java/com/gh/gamecenter/subject/SubjectListFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/subject/SubjectListFragment.kt @@ -4,19 +4,19 @@ import android.view.View import androidx.lifecycle.ViewModelProviders import androidx.recyclerview.widget.RecyclerView import com.ethanhua.skeleton.Skeleton -import com.gh.gamecenter.common.constant.Constants import com.gh.common.exposure.ExposureListener -import com.gh.common.util.* -import com.gh.gamecenter.common.view.SpacingItemDecoration +import com.gh.common.util.DialogUtils import com.gh.common.xapk.XapkInstaller import com.gh.common.xapk.XapkUnzipStatus import com.gh.download.DownloadManager import com.gh.gamecenter.R import com.gh.gamecenter.baselist.LazyListFragment import com.gh.gamecenter.baselist.LoadType +import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.toColor import com.gh.gamecenter.common.utils.viewModelProviderFromParent +import com.gh.gamecenter.common.view.SpacingItemDecoration import com.gh.gamecenter.core.utils.DisplayUtils import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.entity.SubjectData @@ -50,6 +50,10 @@ class SubjectListFragment : LazyListFragment() showUnzipFailureDialog(downloadEntity) } } + + override fun onDataInit(downloadEntity: DownloadEntity) { + mAdapter?.notifyItemByDownload(downloadEntity) + } } override fun getStubLayoutId() = R.layout.fragment_list_base_skeleton_stub diff --git a/app/src/main/java/com/gh/gamecenter/tag/TagsListFragment.kt b/app/src/main/java/com/gh/gamecenter/tag/TagsListFragment.kt index b12721769c..e581c5090a 100644 --- a/app/src/main/java/com/gh/gamecenter/tag/TagsListFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/tag/TagsListFragment.kt @@ -4,13 +4,9 @@ import android.os.Bundle import android.view.View import androidx.recyclerview.widget.LinearLayoutManager import com.ethanhua.skeleton.Skeleton -import com.gh.gamecenter.common.constant.Constants import com.gh.common.exposure.ExposureListener import com.gh.common.exposure.ExposureSource import com.gh.common.util.DialogUtils -import com.gh.gamecenter.common.utils.observeNonNull -import com.gh.gamecenter.common.utils.toColor -import com.gh.gamecenter.common.utils.viewModelProvider import com.gh.common.view.ConfigFilterView import com.gh.common.xapk.XapkInstaller import com.gh.common.xapk.XapkUnzipStatus @@ -19,6 +15,10 @@ import com.gh.gamecenter.R import com.gh.gamecenter.baselist.ListAdapter import com.gh.gamecenter.baselist.ListFragment import com.gh.gamecenter.baselist.LoadType +import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.utils.observeNonNull +import com.gh.gamecenter.common.utils.toColor +import com.gh.gamecenter.common.utils.viewModelProvider import com.gh.gamecenter.databinding.FragmentTagsBinding import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.entity.SubjectSettingEntity @@ -46,6 +46,10 @@ class TagsListFragment : ListFragment() { showUnzipFailureDialog(downloadEntity) } } + + override fun onDataInit(downloadEntity: DownloadEntity) { + mAdapter?.notifyItemByDownload(downloadEntity) + } } private lateinit var mViewModel: TagsListViewModel diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index 7b3aec3722..1ff5950bd3 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -39,6 +39,10 @@ class VDownloadManagerFragment : onLoadRefresh() } } + + override fun onDataInit(downloadEntity: DownloadEntity) { + mAdapter.notifyItemByDownload(downloadEntity) + } } override fun provideListAdapter(): ListAdapter<*> = mAdapter diff --git a/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt index f42bbbd5f6..fc6cfea806 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceLoadingFragment.kt @@ -4,12 +4,12 @@ import android.animation.ValueAnimator import android.os.Bundle import android.view.View import android.view.animation.DecelerateInterpolator +import com.gh.download.DownloadManager import com.gh.gamecenter.common.base.fragment.BaseFragment import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.databinding.FragmentVspaceLoadingBinding import com.gh.gamecenter.entity.GameEntity -import com.lightgame.download.DataChanger import com.lightgame.download.DataWatcher import com.lightgame.download.DownloadEntity import com.lightgame.download.DownloadStatus.* @@ -121,7 +121,7 @@ class VSpaceLoadingFragment : BaseFragment() { super.onResume() if (!mIsInstallation) { - DataChanger.addObserver(mDataWatcher) + DownloadManager.getInstance().addObserver(mDataWatcher) } } @@ -129,7 +129,7 @@ class VSpaceLoadingFragment : BaseFragment() { super.onPause() if (!mIsInstallation) { - DataChanger.deleteObserver(mDataWatcher) + DownloadManager.getInstance().removeObserver(mDataWatcher) } } From 2c3a395b50a9d2c46a68a3c62989286b39b6d272 Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 30 Jun 2022 14:14:16 +0800 Subject: [PATCH 053/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E7=A9=BA=E9=97=B4=E5=92=8C=E7=95=85=E7=8E=A9=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E7=9A=84=E6=9B=B4=E6=96=B0=E9=97=AE=E9=A2=98=20feat:?= =?UTF-8?q?=20=E6=B7=BB=E5=8A=A0=E6=9A=B4=E5=8A=9B=E7=9A=84=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E6=B8=B8=E6=88=8F=E5=A4=87=E4=BB=BD/=E6=81=A2?= =?UTF-8?q?=E5=A4=8D=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../simulator/SimulatorDownloadManager.kt | 16 ++-- .../gh/common/util/DetailDownloadUtils.java | 5 +- .../com/gh/common/util/DownloadObserver.kt | 2 +- .../java/com/gh/download/DownloadManager.java | 14 ++-- .../java/com/gh/download/PackageObserver.kt | 2 +- .../com/gh/gamecenter/entity/AppEntity.kt | 6 +- .../com/gh/gamecenter/home/HomeViewModel.kt | 1 + .../gh/gamecenter/manager/UpdateManager.java | 4 +- .../packagehelper/PackageRepository.kt | 3 +- .../main/java/com/gh/vspace/VBackupHelper.kt | 77 +++++++++++++++++++ .../vspace/VDownloadManagerWrapperFragment.kt | 2 +- app/src/main/java/com/gh/vspace/VHelper.kt | 75 +++++++++++++++--- 12 files changed, 176 insertions(+), 31 deletions(-) create mode 100644 app/src/main/java/com/gh/vspace/VBackupHelper.kt diff --git a/app/src/main/java/com/gh/common/simulator/SimulatorDownloadManager.kt b/app/src/main/java/com/gh/common/simulator/SimulatorDownloadManager.kt index 7c5bd38bab..95df4144ce 100644 --- a/app/src/main/java/com/gh/common/simulator/SimulatorDownloadManager.kt +++ b/app/src/main/java/com/gh/common/simulator/SimulatorDownloadManager.kt @@ -9,15 +9,19 @@ import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.constraintlayout.widget.ConstraintLayout import com.g00fy2.versioncompare.Version -import com.gh.gamecenter.core.AppExecutor.uiExecutor -import com.gh.gamecenter.common.constant.Constants -import com.gh.gamecenter.common.base.TrackableDialog -import com.gh.common.util.* import com.gh.common.util.LogUtils +import com.gh.common.util.PackageInstaller +import com.gh.common.util.PackageUtils import com.gh.download.DownloadManager import com.gh.gamecenter.R +import com.gh.gamecenter.common.base.TrackableDialog +import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.utils.* -import com.gh.gamecenter.core.utils.* +import com.gh.gamecenter.core.AppExecutor.uiExecutor +import com.gh.gamecenter.core.utils.DisplayUtils +import com.gh.gamecenter.core.utils.MtaHelper +import com.gh.gamecenter.core.utils.SpeedUtils +import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.entity.ApkEntity import com.gh.gamecenter.entity.SimulatorEntity import com.gh.gamecenter.entity.TrackableEntity @@ -73,7 +77,7 @@ class SimulatorDownloadManager private constructor() { val fileName = downloadEntity.path.substring(downloadEntity.path.lastIndexOf('/') + 1).removeSuffix(".apk") val startTime = downloadEntity.getMetaExtra(Constants.SIMULATOR_DOWNLOAD_START_TIME) LogUtils.uploadSimulatorDownload("simulator_download_complete", fileName, simulator?.id, downloadEntity.name, gameId, locationStr, downloadType, startTime) - DownloadManager.getInstance().cancel(downloadEntity.url, false, true) + DownloadManager.getInstance().cancel(downloadEntity.url, false, true, false) val activity = mContextRef?.get() as? AppCompatActivity if (activity?.isFinishing == false) { downloadDialog?.dismiss() diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index 96c15ce359..2012b6bfc2 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -297,8 +297,9 @@ public class DetailDownloadUtils { case uncertificated: case unqualified: case unavailable: - detailInitDownload(viewHolder, false); - break; + // TODO 检查不调用 detailInitDownload 会有什么影响 +// detailInitDownload(viewHolder, false); +// break; default: break; } diff --git a/app/src/main/java/com/gh/common/util/DownloadObserver.kt b/app/src/main/java/com/gh/common/util/DownloadObserver.kt index 4b6c65be44..4bb52dab5b 100644 --- a/app/src/main/java/com/gh/common/util/DownloadObserver.kt +++ b/app/src/main/java/com/gh/common/util/DownloadObserver.kt @@ -312,7 +312,7 @@ object DownloadObserver { override fun onConfirm() { val simulator = HaloApp.get(downloadEntity.name, true) as? SimulatorEntity ?: return - DownloadManager.getInstance().cancel(downloadEntity.url, true, true) + DownloadManager.getInstance().cancel(downloadEntity.url, true, true, false) SimulatorDownloadManager.getInstance() .showDownloadDialog(currentActivity, simulator, SimulatorDownloadManager.SimulatorLocation.SIMULATOR_GAME) } diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index c85d1568e9..e69b047974 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -747,7 +747,7 @@ public class DownloadManager implements DownloadStatusListener { * 根据url取消下载,并删除已下载的文件 */ public void cancel(String url) { - cancel(url, true, false); + cancel(url, true, false, false); } /** @@ -755,7 +755,7 @@ public class DownloadManager implements DownloadStatusListener { * * @param automatic 是否是安装完自动删除 */ - public void cancel(String url, boolean isDeleteFile, boolean automatic) { + public void cancel(String url, boolean isDeleteFile, boolean automatic, boolean cancelSilently) { DownloadEntity entry = mDownloadDao.get(url); if (entry != null) { AppExecutor.getIoExecutor().execute(() -> { @@ -783,11 +783,15 @@ public class DownloadManager implements DownloadStatusListener { task.cancel(); // 改任务队列的状态 DataChanger.INSTANCE.getDownloadingTasks().remove(entry.getUrl()); - DataChanger.INSTANCE.notifyDataChanged(entry); + if (!cancelSilently) { + DataChanger.INSTANCE.notifyDataChanged(entry); + } } DataChanger.INSTANCE.getDownloadEntries().remove(entry.getUrl()); - DataChanger.INSTANCE.notifyDataChanged(entry); - DownloadStatusManager.getInstance().onTaskCancelled(entry); + if (!cancelSilently) { + DataChanger.INSTANCE.notifyDataChanged(entry); + DownloadStatusManager.getInstance().onTaskCancelled(entry); + } Utils.log(DownloadManager.class.getSimpleName(), "cancel"); }, 0); diff --git a/app/src/main/java/com/gh/download/PackageObserver.kt b/app/src/main/java/com/gh/download/PackageObserver.kt index b6d515980d..ab51b38e2c 100644 --- a/app/src/main/java/com/gh/download/PackageObserver.kt +++ b/app/src/main/java/com/gh/download/PackageObserver.kt @@ -103,7 +103,7 @@ object PackageObserver { // 畅玩游戏安装完成的同时直接删除文件 runOnIoThread { FileUtils.deleteFile(mDownloadEntity.path) } } else { - DownloadManager.getInstance().cancel(mDownloadEntity.url, false, true) + DownloadManager.getInstance().cancel(mDownloadEntity.url, false, true, false) } } if (sp.getBoolean(CONCERN_GAME_SP_KEY, true)) { //设置页面控制是否安装后自动关注 diff --git a/app/src/main/java/com/gh/gamecenter/entity/AppEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/AppEntity.kt index 65fd42ffc6..70b391b6fd 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/AppEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/AppEntity.kt @@ -31,6 +31,10 @@ data class AppEntity( * EVERY_TIME_OPEN(每次打开) */ var alert: String? = null, -) : Parcelable +) : Parcelable { + fun isAlertEveryTime() = alert == "EVERY_TIME_OPEN" + + fun isAlertOnceADay() = alert == "ONCE_A_DAY" +} diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index a6cb36cefe..c4e5099c26 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -68,6 +68,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { init { itemDataList.addSource(PackageRepository.gameUpdateLiveData) { initPlugin(it) + refreshRecentVGameIfNeeded() } itemDataList.addSource(DownloadManager.getInstance().downloadEntityLiveData) { refreshRecentVGameIfNeeded() diff --git a/app/src/main/java/com/gh/gamecenter/manager/UpdateManager.java b/app/src/main/java/com/gh/gamecenter/manager/UpdateManager.java index 488465bb49..0b0403e01c 100644 --- a/app/src/main/java/com/gh/gamecenter/manager/UpdateManager.java +++ b/app/src/main/java/com/gh/gamecenter/manager/UpdateManager.java @@ -144,7 +144,7 @@ public class UpdateManager { } if (DownloadStatus.done.equals(downloadEntity.getStatus())) { - DownloadManager.getInstance().cancel(downloadEntity.getUrl(), false, true); + DownloadManager.getInstance().cancel(downloadEntity.getUrl(), false, true, false); if (downloadDialog != null) { try { downloadDialog.dismiss(); @@ -517,7 +517,7 @@ public class UpdateManager { } downloadEntity.setPackageName(mApplicationContext.getPackageName()); - DownloadManager.getInstance().cancel(appEntity.getUrl(), true, true); + DownloadManager.getInstance().cancel(appEntity.getUrl(), true, true, false); DownloadManager.getInstance().pauseAll(); AppExecutor.getUiExecutor().executeWithDelay(() -> { diff --git a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt index 9e3977741d..bd11cde67b 100644 --- a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt +++ b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt @@ -261,6 +261,7 @@ object PackageRepository { } else if (game.isVGame()) { // 畅玩游戏移除更新,避免死循环更新 removeUpdate(game.id) + return true } return false @@ -359,7 +360,7 @@ object PackageRepository { * 移除更新 * @param gameId 游戏 ID */ - private fun removeUpdate(gameId: String) { + fun removeUpdate(gameId: String) { gameUpdate.removeAll { it.id == gameId } } diff --git a/app/src/main/java/com/gh/vspace/VBackupHelper.kt b/app/src/main/java/com/gh/vspace/VBackupHelper.kt new file mode 100644 index 0000000000..65449fbbab --- /dev/null +++ b/app/src/main/java/com/gh/vspace/VBackupHelper.kt @@ -0,0 +1,77 @@ +package com.gh.vspace + +import android.content.Context +import android.os.Environment +import com.gh.download.DownloadManager +import com.gh.gamecenter.common.utils.isSmoothGame +import com.gh.gamecenter.core.runOnIoThread +import com.lightgame.download.DBHelper +import com.lightgame.download.DownloadStatus +import com.lightgame.utils.Utils +import java.io.File +import java.io.FileInputStream +import java.io.FileOutputStream +import java.nio.channels.FileChannel + +object VBackupHelper { + + fun recoverValidData(context: Context) { + runOnIoThread { + recoverFromBackupDb(context) + + val entityList = DownloadManager.getInstance().allDownloadEntity + + for (entity in entityList) { + if (!entity.isSmoothGame() || entity.status != DownloadStatus.done) { + DownloadManager.getInstance().cancel(entity.url) + } + } + } + } + + private fun recoverFromBackupDb(context: Context) { + try { + val rootDir: File = Environment.getExternalStorageDirectory() + if (rootDir.canWrite()) { + val appDB: File = context.getDatabasePath(DBHelper.DB_NAME) + val backupDBPath = String.format("/gh-files/%s.bak", DBHelper.DB_NAME) + val externalDB = File(rootDir, backupDBPath) + val src: FileChannel = FileInputStream(externalDB).channel + val dst: FileChannel = FileOutputStream(appDB).channel + dst.transferFrom(src, 0, src.size()) + src.close() + dst.close() + + externalDB.delete() + + Utils.log("Import Download DB Successful!") + } + } catch (e: Exception) { + e.printStackTrace() + } + } + + /** + * 备份现有数据库到 SD 卡 + */ + fun backupDBToExternalStorage(context: Context) { + try { + val rootDir: File = Environment.getExternalStorageDirectory() + if (rootDir.canWrite()) { + val appDB: File = context.getDatabasePath(DBHelper.DB_NAME) + val externalDBPath = String.format("/gh-files/%s.bak", DBHelper.DB_NAME) + val externalDB = File(rootDir, externalDBPath) + val src: FileChannel = FileInputStream(appDB).channel + val dst: FileChannel = FileOutputStream(externalDB).channel + dst.transferFrom(src, 0, src.size()) + src.close() + dst.close() + + Utils.log("Export Download DB Successful!") + } + } catch (e: Exception) { + e.printStackTrace() + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt index 31475e91b0..459e7db978 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt @@ -27,7 +27,7 @@ class VDownloadManagerWrapperFragment: BaseLazyTabFragment() { super.onCreate(savedInstanceState) // 进入的时候再连接一遍服务,尽量保证能用 - VHelper.connectService() + VHelper.connectService(true) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index c37358ab04..33c50eb316 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -29,6 +29,7 @@ import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.core.runOnUiThread import com.gh.gamecenter.core.utils.EmptyCallback 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.entity.* import com.gh.gamecenter.eventbus.EBPackage @@ -52,6 +53,7 @@ object VHelper { private const val LOG_TAG = "VSPACE" private const val KEY_LAST_PLAYED_TIME = "last_played_time" + private const val KEY_LAST_ALERT_UPDATE_URL = "last_alert_update_url" private val mDelegateManager by lazy { VirtualAppManager.get() } private var mInstalledInfoList: List = arrayListOf() @@ -89,7 +91,7 @@ object VHelper { if (config != null && PackageUtils.isInstalled(context, config.arch64?.packageName) ) { - connectService() + connectService(true) // 检查畅玩助手组件更新 checkVSpaceUpdate(config.arch64!!) @@ -100,13 +102,16 @@ object VHelper { /** * 连接服务 */ - fun connectService(callbackClosure: (() -> Unit)? = null) { + fun connectService(shouldCheckUpdate: Boolean = false, callbackClosure: (() -> Unit)? = null) { mDelegateManager.connectService(object : RemoteConnectListener { override fun onServiceConnectionSuccessed() { Utils.log(LOG_TAG, "V 服务连接成功") + mInstalledInfoList = getInstalledList() - PackageRepository.addInstalledGames(getInstalledPackageList(), true) + if (shouldCheckUpdate) { + checkUpdateViaPackageRepository() + } callbackClosure?.invoke() } @@ -211,10 +216,10 @@ object VHelper { PackageUtils.getVersionCodeByPackageName(vaConfig64?.packageName) // 检查更新 - val containsUpdate = - mUpdateEntity != null && installedSpaceVersionCode < mUpdateEntity!!.versionCode + val containsUpdate = shouldShowVSpaceUpdate(mUpdateEntity, installedSpaceVersionCode) if (containsUpdate) { + SPUtils.setString(KEY_LAST_ALERT_UPDATE_URL, mUpdateEntity!!.url ?: "") DialogHelper.showDialog( context = context, title = "服务工具更新提示", @@ -233,7 +238,7 @@ object VHelper { }, extraConfig = DialogHelper.Config(centerTitle = true), uiModificationCallback = { - if (mUpdateEntity!!.isForce) { + if (mUpdateEntity!!.isAlertEveryTime()) { it.confirmTv.visibility = View.GONE it.cancelTv.setTextColor(R.color.theme_font.toColor(context)) } @@ -283,7 +288,7 @@ object VHelper { try { list = mDelegateManager.installedGamesInfo - Utils.log(LOG_TAG, "已安装应用数量${list.size}") + Utils.log(LOG_TAG, "已安装应用数量${list.size}" + list) } catch (e: Exception) { Utils.log(LOG_TAG, "获取已安装应用数量异常 ${e.localizedMessage}") } @@ -313,7 +318,7 @@ object VHelper { if (mDelegateManager.isConnectAidlInterface) { checkClosure.invoke() } else { - connectService(checkClosure) + connectService(false, checkClosure) } } @@ -368,6 +373,8 @@ object VHelper { mInstallationLiveData.postValue(result.packageName) Utils.log(LOG_TAG, "安装新应用结果 -> " + result.status) + + VBackupHelper.backupDBToExternalStorage(HaloApp.getInstance()) } catch (e: Exception) { runOnUiThread { ToastUtils.toast(e.localizedMessage ?: "") @@ -380,7 +387,7 @@ object VHelper { if (mDelegateManager.isConnectAidlInterface) { installClosure.invoke() } else { - connectService(installClosure) + connectService(false, installClosure) } } @@ -464,7 +471,7 @@ object VHelper { if (mDelegateManager.isConnectAidlInterface) { uninstallClosure.invoke() } else { - connectService(uninstallClosure) + connectService(false, uninstallClosure) } } @@ -573,7 +580,7 @@ object VHelper { ) { Utils.log(LOG_TAG, "更新应用${originDownloadEntity.packageName}") - DownloadManager.getInstance().cancel(originDownloadEntity.url) + DownloadManager.getInstance().cancel(originDownloadEntity.url, false, false, true) if (updateEntity != null) { originDownloadEntity.url = updateEntity.url @@ -589,6 +596,8 @@ object VHelper { updateEntity.iconSubscript ) originDownloadEntity.addMetaExtra(Constants.APK_MD5, updateEntity.md5) + + PackageRepository.removeUpdate(updateEntity.id) } originDownloadEntity.isUpdate = true @@ -662,4 +671,48 @@ object VHelper { }) } + /** + * 通过 PackageRepository 检查更新 + */ + private fun checkUpdateViaPackageRepository() { + val rawInstalledPackageList = getInstalledPackageList() + val validInstalledPackageList = arrayListOf() + for (packageName in rawInstalledPackageList) { + if (getDownloadEntitySnapshotByPackageName(packageName) != null) { + validInstalledPackageList.add(packageName) + } + } + PackageRepository.addInstalledGames(validInstalledPackageList, true) + } + + /** + * 是否需要显示畅玩助手更新 + */ + private fun shouldShowVSpaceUpdate( + updateEntity: AppEntity?, + installedSpaceVersionCode: Int + ): Boolean { + if (updateEntity == null) return false + + val hasNewerVersion = installedSpaceVersionCode < updateEntity.versionCode + + if (!hasNewerVersion) return false + + if (updateEntity.isAlertEveryTime()) return true + + if (updateEntity.isAlertOnceADay() + && SPUtils.getString(KEY_LAST_ALERT_UPDATE_URL) != updateEntity.url + ) { + return true + } + + return false + } + + @JvmStatic + fun recoverVDataIfPossible() { + VBackupHelper.recoverValidData(HaloApp.getInstance()) + connectService() + } + } \ No newline at end of file From 27350c5c7069a389fee0f71da3d53aecaad59ea7 Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 30 Jun 2022 15:16:57 +0800 Subject: [PATCH 054/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E8=AF=A6=E6=83=85=E9=A1=B5=E7=82=B9=E5=87=BB=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E4=B8=8E=E5=85=B6=E5=AE=83=E4=BD=8D=E7=BD=AE=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E6=9B=B4=E6=96=B0=E6=95=88=E6=9E=9C=E4=B8=8D=E4=B8=80?= =?UTF-8?q?=E6=A0=B7=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/util/DownloadItemUtils.kt | 6 +- .../adapter/viewholder/DetailViewHolder.java | 20 +++-- app/src/main/java/com/gh/vspace/VHelper.kt | 78 +++++++++++-------- 3 files changed, 57 insertions(+), 47 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index bfd99d3a99..bf8b0e5bc6 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -779,11 +779,7 @@ object DownloadItemUtils { MtaHelper.onEvent("我的游戏_启动", "更新", gameEntity.name) } if (gameEntity.isVGame()) { - PackagesManager.getUpdateList().firstOrNull { it.id == gameEntity.id }?.let { updateEntity -> - VHelper.getDownloadEntitySnapshotByPackageName(gameEntity.getUniquePackageName() ?: "")?.let { downloadEntity -> - VHelper.updateOrReDownload(downloadEntity, updateEntity) - } - } + VHelper.updateOrReDownload(gameEntity) return } DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, object : EmptyCallback { diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java index 157d25d656..532855f230 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java @@ -387,14 +387,18 @@ public class DetailViewHolder { ApkEntity apkEntity = mGameEntity.getApk().get(0); String msg = FileUtils.isCanDownload(mViewHolder.context, apkEntity.getSize()); if (TextUtils.isEmpty(msg)) { - DownloadManager.createDownload(mViewHolder.context, - apkEntity, - mGameEntity, - method, - StringUtils.buildString(mEntrance, "+(", mName, "[", mTitle, "])"), - mName + ":" + mTitle, - isSubscribe, - mTraceEvent); + if (mGameEntity.isVGame() && "更新".equals(method)) { + VHelper.updateOrReDownload(mGameEntity); + } else { + DownloadManager.createDownload(mViewHolder.context, + apkEntity, + mGameEntity, + method, + StringUtils.buildString(mEntrance, "+(", mName, "[", mTitle, "])"), + mName + ":" + mTitle, + isSubscribe, + mTraceEvent); + } mViewHolder.mDownloadPb.setProgress(0); mViewHolder.mDownloadPb.setDownloadType("插件化".equals(method) ? diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 33c50eb316..2cbcae2ad5 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -34,6 +34,7 @@ import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.entity.* import com.gh.gamecenter.eventbus.EBPackage import com.gh.gamecenter.eventbus.EBReuse +import com.gh.gamecenter.manager.PackagesManager import com.gh.gamecenter.packagehelper.PackageRepository import com.gh.gamecenter.retrofit.RetrofitManager import com.halo.assistant.HaloApp @@ -219,7 +220,7 @@ object VHelper { val containsUpdate = shouldShowVSpaceUpdate(mUpdateEntity, installedSpaceVersionCode) if (containsUpdate) { - SPUtils.setString(KEY_LAST_ALERT_UPDATE_URL, mUpdateEntity!!.url ?: "") + SPUtils.setString(KEY_LAST_ALERT_UPDATE_URL, mUpdateEntity!!.url + mUpdateEntity!!.alert) DialogHelper.showDialog( context = context, title = "服务工具更新提示", @@ -398,24 +399,22 @@ object VHelper { fun installOrLaunch(context: Context, packageName: String) { Utils.log(LOG_TAG, "检测是需要安装还是启动 $packageName") - if (showDialogIfVSpaceIsNeeded(context)) { - return - } - - if (isInstalled(packageName)) { - launch(context, packageName) - } else { - checkStoragePermissionBeforeAction(context) { - val downloadEntity = getDownloadEntitySnapshotByPackageName(packageName) - if (downloadEntity != null) { - if (File(downloadEntity.path).exists()) { - install(context, downloadEntity, true) + validateVSpaceBeforeAction(context, null, false) { + if (isInstalled(packageName)) { + launch(context, packageName) + } else { + checkStoragePermissionBeforeAction(context) { + val downloadEntity = getDownloadEntitySnapshotByPackageName(packageName) + if (downloadEntity != null) { + if (File(downloadEntity.path).exists()) { + install(context, downloadEntity, true) + } else { + // 重新下载 + updateOrReDownload(downloadEntity, null) + } } else { - // 重新下载 - updateOrReDownload(downloadEntity, null) + ToastUtils.toast("该游戏已损坏,请重新下载") } - } else { - ToastUtils.toast("该游戏已损坏,请重新下载") } } } @@ -431,21 +430,19 @@ object VHelper { return } - validateVSpaceBeforeAction(context, null, false) { - try { - val intent = mDelegateManager.getStartGameIntent(packageName) - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - context.startActivity(intent) + try { + val intent = mDelegateManager.getStartGameIntent(packageName) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + context.startActivity(intent) - DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName) - ?.let { - mLastSuccessfullyLaunchedGame = Pair(System.currentTimeMillis(), it.gameId) - } + DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName) + ?.let { + mLastSuccessfullyLaunchedGame = Pair(System.currentTimeMillis(), it.gameId) + } - updateLastPlayedTime(packageName) - } catch (e: Exception) { - ToastUtils.toast(e.localizedMessage ?: "") - } + updateLastPlayedTime(packageName) + } catch (e: Exception) { + ToastUtils.toast(e.localizedMessage ?: "") } } @@ -539,15 +536,16 @@ object VHelper { * 畅玩空间是否已安装 * 如果已安装或配置为空返回 true * 未安装的情况下会弹弹窗 - * - * @param forUpdate 是不是为了更新而来,是更新的时候用更新的数据 */ - private fun showDialogIfVSpaceIsNeeded(context: Context, forUpdate: Boolean = false): Boolean { + private fun showDialogIfVSpaceIsNeeded(context: Context): Boolean { + Utils.log(LOG_TAG, "检测是否已安装畅玩空间") + val vaConfig = Config.getVSettingEntity()?.va ?: return true // TODO 检测 32 位 if (!PackageUtils.isInstalled(context, vaConfig.arch64?.packageName)) { VSpaceDialogFragment.showDownloadDialog(context, getVSpaceDownloadEntity(false)) + Utils.log(LOG_TAG, "显示下载畅玩空间弹窗") return true } @@ -568,6 +566,18 @@ object VHelper { } } + /** + * 更新或重下载 + */ + @JvmStatic + fun updateOrReDownload(gameEntity: GameEntity) { + PackagesManager.getUpdateList().firstOrNull { it.id == gameEntity.id }?.let { updateEntity -> + getDownloadEntitySnapshotByPackageName(gameEntity.getUniquePackageName() ?: "")?.let { downloadEntity -> + updateOrReDownload(downloadEntity, updateEntity) + } + } + } + /** * 更新或重下载 * @@ -701,7 +711,7 @@ object VHelper { if (updateEntity.isAlertEveryTime()) return true if (updateEntity.isAlertOnceADay() - && SPUtils.getString(KEY_LAST_ALERT_UPDATE_URL) != updateEntity.url + && SPUtils.getString(KEY_LAST_ALERT_UPDATE_URL) != (mUpdateEntity!!.url + mUpdateEntity!!.alert) ) { return true } From 8114e2a74ab74369a6580a22fcade64b5974e189 Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 30 Jun 2022 15:54:44 +0800 Subject: [PATCH 055/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E6=9C=80=E8=BF=91=E5=9C=A8=E7=8E=A9=E7=9A=84=E6=8E=92?= =?UTF-8?q?=E5=BA=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/gamecenter/home/HomeViewModel.kt | 20 ++++++++++--------- .../gh/vspace/VDownloadManagerViewModel.kt | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index c4e5099c26..ae54cab3f0 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -151,15 +151,17 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { } } - unplayedEntityList.removeAll { it.downloadEntity.packageName == fixedTopEntity?.downloadEntity?.packageName } - unplayedEntityList.sortedBy { it.downloadEntity.start } - - playedEntityList.removeAll { it.downloadEntity.packageName == fixedTopEntity?.downloadEntity?.packageName } - playedEntityList.sortedBy { VHelper.getTotalPlayedTime(it.downloadEntity.packageName) } - - fixedTopEntity?.let { sortedEntityList.add(it) } - sortedEntityList.addAll(unplayedEntityList) - sortedEntityList.addAll(playedEntityList) + fixedTopEntity?.let { + sortedEntityList.add(it) + unplayedEntityList.removeAll { entity -> + entity.downloadEntity.packageName == fixedTopEntity.downloadEntity.packageName + } + playedEntityList.removeAll { entity -> + entity.downloadEntity.packageName == fixedTopEntity.downloadEntity.packageName + } + } + sortedEntityList.addAll(unplayedEntityList.sortedByDescending { it.downloadEntity.start }) + sortedEntityList.addAll(playedEntityList.sortedByDescending { VHelper.getTotalPlayedTime(it.downloadEntity.packageName) }) return sortedEntityList.take(8) } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index 6f8cf7d13e..10713828dd 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -40,7 +40,7 @@ class VDownloadManagerViewModel(application: Application) : val gameEntity = VHelper.toGameEntity(downloadEntity) if (gameEntity.playedTime != 0L) { - gameEntity.des = "已畅玩${NumberUtils.transSimpleUsageTime(gameEntity.playedTime / 1000 / 1000)}" + gameEntity.des = "已畅玩${NumberUtils.transSimpleUsageTime(gameEntity.playedTime / 1000)}" } else { val occupiedSpace = VHelper.getAppOccupiedSpace(downloadEntity.packageName) if (occupiedSpace > 0 ) { From 541ebe8a294e96d42c0815202ceb728f8cc262f6 Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 30 Jun 2022 16:51:47 +0800 Subject: [PATCH 056/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=BF=9B?= =?UTF-8?q?=E5=85=A5=E7=95=85=E7=8E=A9=E6=B8=B8=E6=88=8F=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E8=BF=87=E6=85=A2=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/gh/vspace/VDownloadManagerFragment.kt | 1 - .../com/gh/vspace/VDownloadManagerWrapperFragment.kt | 9 ++------- .../com/gh/vspace/VDownloadManagerWrapperViewModel.kt | 8 ++++++++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index 1ff5950bd3..9575064730 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -59,7 +59,6 @@ class VDownloadManagerFragment : override fun onResume() { super.onResume() - setNavigationTitle("畅玩游戏管理") DownloadManager.getInstance().addObserver(dataWatcher) } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt index 459e7db978..f94077cde3 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt @@ -23,16 +23,11 @@ class VDownloadManagerWrapperFragment: BaseLazyTabFragment() { override fun getLayoutId() = 0 override fun getInflatedLayout() = mBinding.root - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - // 进入的时候再连接一遍服务,尽量保证能用 - VHelper.connectService(true) - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + setNavigationTitle("畅玩游戏管理") + initMenu(R.menu.menu_manage) mBinding.bottomContainer.setOnClickListener { toast("打开畅玩广场") diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperViewModel.kt index 81245de082..c97dffdb0b 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperViewModel.kt @@ -2,10 +2,18 @@ package com.gh.vspace import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.history.ManageOption class VDownloadManagerWrapperViewModel : ViewModel() { + init { + runOnIoThread { + // 进入的时候再连接一遍服务,尽量保证能用 + VHelper.connectService(true) + } + } + var currentOptionLiveData = MutableLiveData(ManageOption.OPTION_MANAGER) } \ No newline at end of file From 034db094e166596f3409289297da4d4ae57d1ba0 Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 30 Jun 2022 19:29:44 +0800 Subject: [PATCH 057/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=9B=A0?= =?UTF-8?q?=E4=B8=BA=E8=8E=B7=E5=8F=96=E5=B7=B2=E5=AE=89=E8=A3=85=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E5=BC=82=E5=B8=B8=E9=80=A0=E6=88=90=E7=9A=84=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E9=87=8D=E4=B8=8B=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VHelper.kt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 2cbcae2ad5..bea99e9868 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -146,6 +146,7 @@ object VHelper { */ @JvmStatic fun isInstalled(packageName: String?): Boolean { + Utils.log(LOG_TAG, "检查 $packageName 是否在已安装列表 $mInstalledInfoList 里") return mInstalledInfoList.any { it.packageName == packageName } } @@ -265,7 +266,7 @@ object VHelper { /** * 获取已安装的包名列表 */ - fun getInstalledPackageList(): ArrayList { + private fun getInstalledPackageList(): ArrayList { val installedList = mInstalledInfoList val installedPackageList = arrayListOf() @@ -404,6 +405,12 @@ object VHelper { launch(context, packageName) } else { checkStoragePermissionBeforeAction(context) { + // 这里重新检查一遍是否已安装,因为有可能因为上一次更新列表失败而出现重新下载的情况 + if (isInstalled(packageName)) { + launch(context, packageName) + return@checkStoragePermissionBeforeAction + } + val downloadEntity = getDownloadEntitySnapshotByPackageName(packageName) if (downloadEntity != null) { if (File(downloadEntity.path).exists()) { @@ -426,10 +433,6 @@ object VHelper { fun launch(context: Context, packageName: String) { Utils.log(LOG_TAG, "打开应用 $packageName") - if (showDialogIfVSpaceIsNeeded(context)) { - return - } - try { val intent = mDelegateManager.getStartGameIntent(packageName) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) From 8e5ceb1e0ee95b23494a4a6f316ad9358f7bd149 Mon Sep 17 00:00:00 2001 From: lyr Date: Thu, 30 Jun 2022 17:07:41 +0800 Subject: [PATCH 058/217] =?UTF-8?q?feat:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.10.0=E3=80=91=E7=95=85=E7=8E=A9=E5=8A=A9?= =?UTF-8?q?=E6=89=8B=E6=95=B0=E6=8D=AE=E5=9F=8B=E7=82=B9=20https://git.sha?= =?UTF-8?q?nqu.cc/pm/halo/halo-app-issues/-/issues/1872?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/exposure/ExposureUtils.kt | 17 +++- .../com/gh/common/util/DownloadObserver.kt | 16 +++- .../java/com/gh/common/util/NewLogUtils.kt | 94 +++++++++++++++++++ .../java/com/gh/download/DownloadManager.java | 2 +- .../gamecenter/DownloadManagerActivity.java | 2 + .../com/gh/gamecenter/entity/GameEntity.kt | 3 + .../gamedetail/GameDetailFragment.kt | 6 ++ .../gh/gamecenter/home/HomeFragmentAdapter.kt | 14 +++ .../gh/vspace/HomeRecentVGameViewHolder.kt | 12 ++- .../com/gh/vspace/VDownloadManagerActivity.kt | 4 +- .../com/gh/vspace/VDownloadManagerAdapter.kt | 34 ++++++- .../com/gh/vspace/VDownloadManagerFragment.kt | 10 ++ .../gh/vspace/VDownloadManagerViewModel.kt | 1 + .../vspace/VDownloadManagerWrapperFragment.kt | 1 + .../com/gh/vspace/VFeedbackDialogFragment.kt | 3 + app/src/main/java/com/gh/vspace/VHelper.kt | 11 ++- .../gh/vspace/VLoadCompleteWindowHelper.kt | 3 + .../com/gh/vspace/VSpaceDialogFragment.kt | 38 +++++++- .../common/constant/EntranceConsts.java | 1 + 19 files changed, 256 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/gh/common/exposure/ExposureUtils.kt b/app/src/main/java/com/gh/common/exposure/ExposureUtils.kt index 63e0018513..afc40dc81c 100644 --- a/app/src/main/java/com/gh/common/exposure/ExposureUtils.kt +++ b/app/src/main/java/com/gh/common/exposure/ExposureUtils.kt @@ -7,6 +7,7 @@ import com.gh.gamecenter.common.utils.FixedSizeLinkedHashSet import com.gh.gamecenter.common.utils.toObject import com.gh.gamecenter.entity.ApkEntity import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.manager.PackagesManager import com.halo.assistant.HaloApp import com.lightgame.download.DownloadEntity @@ -79,8 +80,14 @@ object ExposureUtils { } @JvmStatic - fun getDownloadType(apkEntity: ApkEntity, gameId: String): DownloadType { - return if (PackageUtils.isInstalled( + fun getDownloadType(apkEntity: ApkEntity, gameId: String, isVGame: Boolean): DownloadType { + return if (isVGame) { + if (PackagesManager.isCanUpdate(gameId, apkEntity.packageName)) { + DownloadType.FUN_UPDATE + } else { + DownloadType.FUN_DOWNLOAD + } + } else if (PackageUtils.isInstalled( HaloApp.getInstance().application, apkEntity.packageName ) @@ -143,6 +150,10 @@ object ExposureUtils { PLUGIN_UPDATE, - PLUGIN_DOWNLOAD + PLUGIN_DOWNLOAD, + + FUN_DOWNLOAD, + + FUN_UPDATE } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/common/util/DownloadObserver.kt b/app/src/main/java/com/gh/common/util/DownloadObserver.kt index 4bb52dab5b..78fa86a1f3 100644 --- a/app/src/main/java/com/gh/common/util/DownloadObserver.kt +++ b/app/src/main/java/com/gh/common/util/DownloadObserver.kt @@ -325,12 +325,20 @@ object DownloadObserver { private fun statDoneEvent(downloadEntity: DownloadEntity) { var type: ExposureUtils.DownloadType if (downloadEntity.isUpdate) { - type = ExposureUtils.DownloadType.UPDATE - if (downloadEntity.isPlugin) { - type = ExposureUtils.DownloadType.PLUGIN_UPDATE + if (downloadEntity.isSmoothGame()) { + type = ExposureUtils.DownloadType.FUN_UPDATE + } else { + type = ExposureUtils.DownloadType.UPDATE + if (downloadEntity.isPlugin) { + type = ExposureUtils.DownloadType.PLUGIN_UPDATE + } } } else { - type = ExposureUtils.DownloadType.DOWNLOAD + type = if (downloadEntity.isSmoothGame()) { + ExposureUtils.DownloadType.FUN_DOWNLOAD + } else { + ExposureUtils.DownloadType.DOWNLOAD + } } if (downloadEntity.isPluggable) { diff --git a/app/src/main/java/com/gh/common/util/NewLogUtils.kt b/app/src/main/java/com/gh/common/util/NewLogUtils.kt index f296679267..13d971f754 100644 --- a/app/src/main/java/com/gh/common/util/NewLogUtils.kt +++ b/app/src/main/java/com/gh/common/util/NewLogUtils.kt @@ -13,6 +13,7 @@ import com.gh.gamecenter.retrofit.RetrofitManager import com.lightgame.utils.Utils import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody +import org.json.JSONArray import org.json.JSONObject object NewLogUtils { @@ -2435,4 +2436,97 @@ object NewLogUtils { } log(json, "event", false) } + + // 畅玩助手相关事件(下载弹窗展示事件/隐私政策点击事件/下载点击事件/授权弹窗展示事件/更新弹窗展示事件) + // 畅玩管理删除游戏弹窗展示事件/畅玩管理-畅玩广场入口点击事件/退出畅玩助手提示弹窗展示事件 + @JvmStatic + fun logHaloFunEvent(event: String) { + val json = json { + "event" to event + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + // 关联游戏跳转icon点击事件 + @JvmStatic + fun logHaloFunGameDetailJumpClick(downloadStatus: String, gameId: String) { + val json = json { + "event" to "halo_fun_game_detail_jump_click" + "download_state" to downloadStatus + "game_id" to gameId + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + // 下载完成提示条点击事件 + @JvmStatic + fun logHaloFunDownloadCompleteTipClick(buttonType: String, gameId: String) { + val json = json { + "event" to "halo_fun_download_complete_tip_click" + "button_type" to buttonType + "game_id" to gameId + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + // 畅玩助手更新弹窗点击事件 + @JvmStatic + fun logHaloFunUpdateDialogClick(dialogType: String, buttonType: String) { + val json = json { + "event" to "halo_fun_update_dialog_click" + "dialog_type" to dialogType + "button_type" to buttonType + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + // 畅玩管理展示事件 + @JvmStatic + fun logHaloFunManageShow(entrance: String) { + val json = json { + "event" to "halo_fun_manage_show" + "entrance" to entrance + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + // 畅玩管理-最近在玩板块展示管理事件 + @JvmStatic + fun logHaloFunManageRecentGameSwitch(isOn: Boolean) { + val json = json { + "event" to "halo_fun_manage_recent_game_switch" + "is_on" to isOn + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + // 畅玩管理删除游戏弹窗点击事件 + @JvmStatic + fun logHaloFunManageGameDeleteDialogClick(buttonType: String, gamesArray: JSONArray) { + val json = json { + "event" to "halo_fun_manage_game_delete_dialog_click" + "button_type" to buttonType + "games_array" to gamesArray + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + // 退出畅玩助手提示弹窗反馈收集事件 + @JvmStatic + fun logHaloFunGameExitDialogSubmitClick(detail: String, typeTags: JSONArray) { + val json = json { + "event" to "halo_fun_game_exit_dialog_submit_click" + "detail" to detail + "type_tags" to typeTags + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index e69b047974..b7923b15f1 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -361,7 +361,7 @@ public class DownloadManager implements DownloadStatusListener { downloadEntity.setPlugin(!TextUtils.isEmpty(apkEntity.getGhVersion())); - ExposureUtils.DownloadType downloadType = ExposureUtils.getDownloadType(apkEntity, gameEntity.getId()); + ExposureUtils.DownloadType downloadType = ExposureUtils.getDownloadType(apkEntity, gameEntity.getId(), gameEntity.isVGame()); gameEntity.setIsPlatformRecommend(apkEntity.getRecommend() != null); ExposureEvent downloadExposureEvent = ExposureUtils.logADownloadExposureEvent(gameEntity, apkEntity.getPlatform(), traceEvent, downloadType); diff --git a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java index 6a6d529adc..fb44002ccb 100644 --- a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java +++ b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java @@ -6,6 +6,7 @@ import android.os.Bundle; import android.view.MenuItem; import com.gh.common.util.DirectUtils; +import com.gh.common.util.NewLogUtils; import com.gh.gamecenter.common.base.activity.ToolBarActivity; import com.gh.gamecenter.common.base.fragment.BaseFragment_TabLayout; import com.gh.gamecenter.common.constant.EntranceConsts; @@ -62,6 +63,7 @@ public class DownloadManagerActivity extends ToolBarActivity { @Override public boolean onMenuItemClick(MenuItem item) { + NewLogUtils.logHaloFunManageShow("下载管理"); DirectUtils.directToVGameDownload(this, false); return true; } diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt index 0827a7f402..e0f4acd91c 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt @@ -833,6 +833,8 @@ data class SimpleGame( //游戏单推荐理由 @SerializedName("recommend_text") var recommendText: String = "", + @SerializedName("download_status") + var downloadStatus: String = "" ) : Parcelable { @IgnoredOnParcel @@ -857,6 +859,7 @@ data class SimpleGame( gameEntity.mirrorData = mirrorData?.toGameEntity() gameEntity.recommendStar = recommendStar gameEntity.recommendText = recommendText + gameEntity.downloadStatus = downloadStatus return gameEntity } } diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt index 7e985ddb29..e6ce249938 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt @@ -1641,6 +1641,12 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { mDownloadBinding.tvVmode.setOnClickListener { mDownloadBinding.ivVmode.performClick() } mDownloadBinding.ivVmode.enlargeTouchArea() mDownloadBinding.ivVmode.setOnClickListener { _ -> + val downloadStatus = when (simpleGame.downloadStatus) { + "smooth" -> "畅玩" + "demo" -> "试玩" + else -> "下载" + } + NewLogUtils.logHaloFunGameDetailJumpClick(downloadStatus, simpleGame.id ?: "") DirectUtils.directToGameDetail(requireContext(), it.id ?: "", mEntrance) } } diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt index 1bde409645..d3944e6586 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt @@ -36,6 +36,7 @@ import com.gh.gamecenter.home.slide.HomeSlideListViewHolder import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel import com.gh.vspace.HomeRecentVGameAdapter import com.gh.vspace.HomeRecentVGameViewHolder +import com.gh.vspace.VHelper import com.halo.assistant.fragment.game.GamePluginAdapter import com.lightgame.download.DownloadEntity import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder @@ -261,6 +262,19 @@ class HomeFragmentAdapter( private fun bindRecentVGame(holder: HomeRecentVGameViewHolder, position: Int) { val homeItemData = mDataList[position] + val exposureEventList = arrayListOf() + runOnIoThread(true) { + homeItemData.recentVGame?.forEach { + val event = ExposureEvent.createEventWithSourceConcat( + gameEntity = VHelper.toGameEntity(it.downloadEntity), + basicSource = mBasicExposureSource, + source = listOf(ExposureSource("最近在玩", "")) + ) + exposureEventList.add(event) + } + } + homeItemData.exposureEventList = exposureEventList + holder.bindView(homeItemData.recentVGame!!) } diff --git a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt index 7072affd47..29a6993e40 100644 --- a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt +++ b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt @@ -5,6 +5,7 @@ import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView.OnScrollListener +import com.gh.common.util.NewLogUtils import com.gh.download.DownloadManager import com.gh.gamecenter.R import com.gh.gamecenter.baselist.DiffUtilAdapter @@ -42,10 +43,19 @@ class HomeRecentVGameViewHolder(var binding: ItemHomeRecentVgameBinding) : }) binding.moreTv.setOnClickListener { + NewLogUtils.logHaloFunManageShow("最近在玩") binding.root.context.startActivity( - VDownloadManagerActivity.getIntent(binding.root.context, false) + VDownloadManagerActivity.getIntent( + binding.root.context, + switchToDownloadingTab = false, + isFromHomeRecent = true + ) ) } + + binding.vspaceIv.setOnClickListener { + NewLogUtils.logHaloFunEvent("halo_fun_manage_square_entrance_click") + } } (binding.recyclerView.adapter as? HomeRecentVGameAdapter)?.submitList(entityList) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt index cc8ab96bb0..c7d66a0f8b 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt @@ -24,9 +24,11 @@ class VDownloadManagerActivity: ToolBarActivity() { companion object { @JvmStatic - fun getIntent(context: Context, switchToDownloadingTab: Boolean = false): Intent { + @JvmOverloads + fun getIntent(context: Context, switchToDownloadingTab: Boolean = false, isFromHomeRecent: Boolean = false): Intent { val intent = Intent(context, VDownloadManagerActivity::class.java) intent.putExtra(EntranceConsts.KEY_POSITION, if (switchToDownloadingTab) 1 else 0) + intent.putExtra(EntranceConsts.KEY_IS_FROM_HOME_RECENT, isFromHomeRecent) return intent } } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index b76946b56a..1b8a09c05f 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -10,6 +10,10 @@ import androidx.appcompat.app.AppCompatActivity import androidx.constraintlayout.widget.ConstraintLayout import androidx.recyclerview.widget.RecyclerView import com.gh.common.databind.BindingAdapters +import com.gh.common.exposure.ExposureEvent +import com.gh.common.exposure.ExposureSource +import com.gh.common.exposure.IExposable +import com.gh.common.util.NewLogUtils import com.gh.common.view.DownloadProgressBar import com.gh.download.DownloadManager import com.gh.gamecenter.GameDetailActivity @@ -21,6 +25,7 @@ import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.constant.ItemViewType import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.AppExecutor +import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.core.utils.CurrentActivityHolder import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.core.utils.ToastUtils @@ -32,9 +37,17 @@ import com.gh.gamecenter.manager.PackagesManager import com.lightgame.download.DownloadEntity import com.lightgame.download.DownloadStatus import com.lightgame.utils.Utils +import org.json.JSONArray -class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloadManagerViewModel) : - ListAdapter(context) { +class VDownloadManagerAdapter( + context: Context, + private val mViewModel: VDownloadManagerViewModel, +) : ListAdapter(context), IExposable { + + private val mBasicExposureSource by lazy { + if (mViewModel.isFromHomeRecent) listOf(ExposureSource("新首页"), ExposureSource("最近在玩")) + else listOf() + } private var mPopWindow: PopupWindow? = null private var mCurrentOption = ManageOption.OPTION_MANAGER @@ -98,6 +111,16 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa is VGameItemViewHolder -> { val gameEntity = mEntityList[position] + if (mViewModel.isTypeDownloaded()) { + runOnIoThread(true) { + gameEntity.exposureEvent = ExposureEvent.createEventWithSourceConcat( + gameEntity = gameEntity, + basicSource = mBasicExposureSource, + source = listOf(ExposureSource("畅玩游戏管理")) + ) + } + } + BindingAdapters.setGameName(holder.binding.nameTv, gameEntity, false, true) holder.binding.iconIv.displayGameIcon(gameEntity) @@ -177,6 +200,7 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa ) mPopupBinding?.itemDelete?.setOnClickListener { + NewLogUtils.logHaloFunEvent("halo_fun_manage_game_delete_dialog_show") DialogHelper.showDialog( mContext, "是否删除${selectItems.size}条记录?", @@ -187,11 +211,13 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa mViewModel.removeItems(selectItems) selectItems.clear() checkSelectItems() + NewLogUtils.logHaloFunManageGameDeleteDialogClick("删除", JSONArray(selectItems)) AppExecutor.uiExecutor.executeWithDelay({ mViewModel.load(LoadType.REFRESH) }, 200) }, + { NewLogUtils.logHaloFunManageGameDeleteDialogClick("再看看", JSONArray(selectItems)) }, extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true) ) } @@ -310,6 +336,10 @@ class VDownloadManagerAdapter(context: Context, private val mViewModel: VDownloa } } + override fun getEventByPosition(pos: Int) = mEntityList[pos].exposureEvent + + override fun getEventListByPosition(pos: Int): List? = null + class VGameItemViewHolder(var binding: ItemVgameDownloadManagerBinding) : RecyclerView.ViewHolder(binding.root) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index 9575064730..31f8db9a11 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -4,11 +4,14 @@ import android.os.Bundle import android.view.View import androidx.recyclerview.widget.RecyclerView import com.ethanhua.skeleton.Skeleton +import com.gh.common.exposure.ExposureListener +import com.gh.common.util.NewLogUtils import com.gh.download.DownloadManager import com.gh.gamecenter.R import com.gh.gamecenter.baselist.ListAdapter import com.gh.gamecenter.baselist.ListFragment import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.databinding.FragmentVdownloadManagerBinding @@ -30,6 +33,7 @@ class VDownloadManagerFragment : } private val mViewModel: VDownloadManagerViewModel by lazy { viewModelProvider() } private val mBinding by lazy { FragmentVdownloadManagerBinding.inflate(layoutInflater) } + private val mExposureListener by lazy { ExposureListener(this, mAdapter) } private val dataWatcher: DataWatcher = object : DataWatcher() { override fun onDataChanged(downloadEntity: DownloadEntity) { @@ -53,6 +57,7 @@ class VDownloadManagerFragment : override fun onCreate(savedInstanceState: Bundle?) { mViewModel.type = arguments?.get(VDownloadManagerViewModel.TYPE) as String + mViewModel.isFromHomeRecent = arguments?.getBoolean(EntranceConsts.KEY_IS_FROM_HOME_RECENT) ?: false super.onCreate(savedInstanceState) } @@ -89,10 +94,15 @@ class VDownloadManagerFragment : } lottieView.playAnimation() SPUtils.setBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, !status) + NewLogUtils.logHaloFunManageRecentGameSwitch(!status) DownloadManager.getInstance().notifyDownloadLiveDataChanged() } } + + if (mViewModel.isTypeDownloaded()) { + mListRv.addOnScrollListener(mExposureListener) + } } override fun changeOption(option: ManageOption) { diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index 10713828dd..67a509e4ef 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -17,6 +17,7 @@ class VDownloadManagerViewModel(application: Application) : ListViewModel(application) { var type = "" + var isFromHomeRecent = false override fun mergeResultLiveData() { mResultLiveData.addSource(mListLiveData) { diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt index f94077cde3..a5d4251e03 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt @@ -55,6 +55,7 @@ class VDownloadManagerWrapperFragment: BaseLazyTabFragment() { override fun initFragmentList(fragments: MutableList) { fragments.add(VDownloadManagerFragment().with(Bundle().apply { putString(VDownloadManagerViewModel.TYPE, VDownloadManagerViewModel.TYPE_DOWNLOADED) + putBoolean(EntranceConsts.KEY_IS_FROM_HOME_RECENT, arguments?.getBoolean(EntranceConsts.KEY_IS_FROM_HOME_RECENT) ?: false) })) fragments.add(VDownloadManagerFragment().with(Bundle().apply { putString(VDownloadManagerViewModel.TYPE, VDownloadManagerViewModel.TYPE_DOWNLOADING) diff --git a/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt b/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt index ea98f074cd..e319c1c413 100644 --- a/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt +++ b/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt @@ -10,6 +10,7 @@ import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.core.widget.doOnTextChanged import androidx.lifecycle.ViewModel +import com.gh.common.util.NewLogUtils import com.gh.common.util.PackageUtils import com.gh.gamecenter.R import com.gh.gamecenter.common.base.fragment.BaseDialogFragment @@ -82,6 +83,7 @@ class VFeedbackDialogFragment : BaseDialogFragment() { } mBinding.submitTv.setOnClickListener { mViewModel.postFeedback(mGame!!.id, mBinding.feedbackEt.text.toString(), getSelectedTagString()) + NewLogUtils.logHaloFunGameExitDialogSubmitClick(mBinding.feedbackEt.text.toString(), JSONArray(getSelectedTagString())) dismissAllowingStateLoss() } checkLabel() @@ -155,6 +157,7 @@ class VFeedbackDialogFragment : BaseDialogFragment() { activity: AppCompatActivity, game: GameEntity? ) { + NewLogUtils.logHaloFunEvent("halo_fun_game_exit_dialog_show") VFeedbackDialogFragment().apply { arguments = Bundle().apply { putParcelable(KEY_GAME, game) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index bea99e9868..67d564bfb8 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -13,6 +13,7 @@ import com.gh.common.constant.Config import com.gh.common.exposure.ExposureUtils import com.gh.common.history.HistoryHelper import com.gh.common.util.DataCollectionUtils +import com.gh.common.util.NewLogUtils import com.gh.common.util.PackageUtils import com.gh.download.DownloadManager import com.gh.download.PackageObserver @@ -221,6 +222,8 @@ object VHelper { val containsUpdate = shouldShowVSpaceUpdate(mUpdateEntity, installedSpaceVersionCode) if (containsUpdate) { + val dialogType = if (mUpdateEntity!!.isForce) "强制更新" else "提示更新" + NewLogUtils.logHaloFunEvent("halo_fun_update_dialog_show") SPUtils.setString(KEY_LAST_ALERT_UPDATE_URL, mUpdateEntity!!.url + mUpdateEntity!!.alert) DialogHelper.showDialog( context = context, @@ -229,13 +232,16 @@ object VHelper { cancelText = "立即更新", confirmText = "继续游戏", cancelClickCallback = { + NewLogUtils.logHaloFunUpdateDialogClick(dialogType, "立即更新") VSpaceDialogFragment.showDownloadDialog( context, getVSpaceDownloadEntity(true), - true + autoDownload = true, + isUpdate = true ) }, confirmClickCallback = { + NewLogUtils.logHaloFunUpdateDialogClick(dialogType, "继续游戏") callback.invoke() }, extraConfig = DialogHelper.Config(centerTitle = true), @@ -309,6 +315,7 @@ object VHelper { if (isStoragePermissionGranted) { callback.invoke() } else { + NewLogUtils.logHaloFunEvent("halo_fun_access_dialog_show") context.startActivity(mDelegateManager.requestPermissionIntent) } } catch (e: RuntimeException) { @@ -619,7 +626,7 @@ object VHelper { originDownloadEntity.percent = 0.0 // 确定下载类型 - val downloadType = ExposureUtils.DownloadType.UPDATE + val downloadType = if (updateEntity == null) ExposureUtils.DownloadType.FUN_DOWNLOAD else ExposureUtils.DownloadType.FUN_UPDATE val gameEntity = GameEntity(originDownloadEntity.gameId, originDownloadEntity.name) gameEntity.gameVersion = originDownloadEntity.versionName ?: "" diff --git a/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt b/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt index 2b48b95332..811b748ce0 100644 --- a/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt +++ b/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt @@ -13,6 +13,7 @@ import androidx.core.view.get import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.widget.ViewPager2 +import com.gh.common.util.NewLogUtils import com.gh.gamecenter.R import com.gh.gamecenter.common.utils.dip2px import com.gh.gamecenter.common.utils.toBinding @@ -138,12 +139,14 @@ object VLoadCompleteWindowHelper { } mBinding.closeIv.setOnClickListener { if (!ClickUtils.isFastDoubleClick(it.id)) { + NewLogUtils.logHaloFunDownloadCompleteTipClick("关闭", mAdapter.gameEntityList[mBinding.viewPager.currentItem].id) mBinding.viewPager.removeCallbacks(mLoopTask) mBinding.viewPager.removeCallbacks(mDismissTask) EasyFloat.dismiss(LOAD_COMPLETE_WINDOW) } } mBinding.launchTv.setOnClickListener { + NewLogUtils.logHaloFunDownloadCompleteTipClick("启动", mAdapter.gameEntityList[mBinding.viewPager.currentItem].id) VHelper.installOrLaunch(activity, mAdapter.gameEntityList[mBinding.viewPager.currentItem].getApk()[0].packageName) } } diff --git a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt index 5e3597acd3..6d8c750198 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt @@ -13,6 +13,11 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import com.gh.common.exposure.ExposureUtils +import com.gh.common.exposure.ExposureUtils.DownloadType.UPDATE +import com.gh.common.exposure.ExposureUtils.DownloadType.DOWNLOAD +import com.gh.common.util.DataCollectionUtils +import com.gh.common.util.NewLogUtils import com.gh.common.util.PackageInstaller import com.gh.common.view.DownloadProgressBar import com.gh.download.DownloadManager @@ -20,11 +25,14 @@ import com.gh.download.PackageObserver import com.gh.gamecenter.R import com.gh.gamecenter.common.base.fragment.BaseDraggableDialogFragment import com.gh.gamecenter.common.utils.toColor +import com.gh.gamecenter.common.utils.toJson import com.gh.gamecenter.common.utils.viewModelProvider import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.databinding.DialogVspaceBinding import com.gh.gamecenter.entity.AppEntity +import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.eventbus.EBPackage +import com.halo.assistant.HaloApp import com.lightgame.download.DataWatcher import com.lightgame.download.DownloadEntity import com.lightgame.download.DownloadStatus.* @@ -81,7 +89,12 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { mBinding.downloadBtn.text = "下载畅玩助手服务组件" mBinding.downloadBtn.downloadType = DownloadProgressBar.DownloadType.NORMAL mBinding.descTv.text = spanBuilder + mBinding.privacyPolicyTv.setOnClickListener { + NewLogUtils.logHaloFunEvent("halo_fun_download_dialog_privacy_click") + } mBinding.downloadBtn.setOnClickListener { + NewLogUtils.logHaloFunEvent("halo_fun_download_dialog_download_click") + val name = "畅玩助手V" + mAppEntity?.version val downloadId = PackageInstaller.createDownloadId(name) @@ -89,14 +102,31 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { downloadEntity.url = mDownloadUrl downloadEntity.name = name downloadEntity.platform = "官方版" - downloadEntity.gameId = "" + downloadEntity.gameId = "62bd412bbbf04747cd3de539" downloadEntity.path = PackageInstaller.getDownloadPathWithId(downloadId, "apk") downloadEntity.packageName = "com.lg.vspace" + // 确定下载类型 + val downloadType = if (arguments?.getBoolean(KEY_IS_UPDATE) == true) UPDATE else DOWNLOAD + val gameEntity = GameEntity(downloadEntity.gameId, downloadEntity.name) + gameEntity.gameVersion = mAppEntity?.version ?: "" + + val event = ExposureUtils.logADownloadExposureEvent( + gameEntity, + downloadEntity.platform, + null, + downloadType + ) + + downloadEntity.exposureTrace = event.toJson() + AppExecutor.uiExecutor.executeWithDelay({ DownloadManager.getInstance().cancel(mDownloadUrl) DownloadManager.getInstance().add(downloadEntity) }, 200) + + // 收集下载数据 + DataCollectionUtils.uploadDownload(HaloApp.getInstance(), downloadEntity, "开始") } if (arguments?.getBoolean(KEY_AUTO_DOWNLOAD) == true) { @@ -173,9 +203,10 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { companion object { const val KEY_ENTITY = "entity" const val KEY_AUTO_DOWNLOAD = "auto_download" + const val KEY_IS_UPDATE = "is_update" @JvmStatic - fun showDownloadDialog(context: Context?, appEntity: AppEntity, autoDownload: Boolean = false) { + fun showDownloadDialog(context: Context?, appEntity: AppEntity, autoDownload: Boolean = false, isUpdate: Boolean = false) { val fragmentActivity: FragmentActivity = if (context is FragmentActivity) { context } else { @@ -190,10 +221,13 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { // 防止重复弹出 if (hasDialogDisplayedInCurrentActivity(fragmentActivity)) return + NewLogUtils.logHaloFunEvent("halo_fun_download_dialog_show") + val downloadDialog = VSpaceDialogFragment().apply { arguments = Bundle().apply { put(KEY_ENTITY, appEntity) put(KEY_AUTO_DOWNLOAD, autoDownload) + put(KEY_IS_UPDATE, isUpdate) } } downloadDialog.show( diff --git a/module_common/src/main/java/com/gh/gamecenter/common/constant/EntranceConsts.java b/module_common/src/main/java/com/gh/gamecenter/common/constant/EntranceConsts.java index c66deae246..26a2e7f358 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/constant/EntranceConsts.java +++ b/module_common/src/main/java/com/gh/gamecenter/common/constant/EntranceConsts.java @@ -248,6 +248,7 @@ public class EntranceConsts { public static final String KET_TYPE = "KET_TYPE"; public static final String KET_SUMMARY = "KET_SUMMARY"; public static final String KEY_ACTIVITY_ID = "activity_id"; + public static final String KEY_IS_FROM_HOME_RECENT = "is_from_home_recent"; public static final String KEY_FORMAT = "format"; public static final String KEY_VERSION_CODE = "version_code"; public static final String KEY_PLATFORM_REQUESTS_ID = "platform_requests_id"; From 5a377913bb33abf3941548122b400a26658c47d0 Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 30 Jun 2022 21:14:44 +0800 Subject: [PATCH 059/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=9D=9E?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E6=9B=B4=E6=96=B0=E4=BC=9A=E4=B8=A2=E5=A4=B1?= =?UTF-8?q?=E8=A7=92=E6=A0=87=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/common/util/PackageUtils.java | 2 + .../java/com/gh/download/DownloadManager.java | 47 +++++++++++-------- .../packagehelper/PackageRepository.kt | 7 ++- .../gh/vspace/HomeRecentVGameViewHolder.kt | 35 ++++++++------ app/src/main/java/com/gh/vspace/VHelper.kt | 9 +++- 5 files changed, 63 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/PackageUtils.java b/app/src/main/java/com/gh/common/util/PackageUtils.java index a272b3b028..7b24cfaf06 100644 --- a/app/src/main/java/com/gh/common/util/PackageUtils.java +++ b/app/src/main/java/com/gh/common/util/PackageUtils.java @@ -141,6 +141,8 @@ public class PackageUtils { updateEntity.setId(gameEntity.getId()); updateEntity.setName(gameEntity.getName()); updateEntity.setIcon(gameEntity.getIcon()); + updateEntity.setRawIcon(gameEntity.getRawIcon()); + updateEntity.setIconSubscript(gameEntity.getIconSubscript()); updateEntity.setPackageName(apkEntity.getPackageName()); updateEntity.setSize(apkEntity.getSize()); updateEntity.setVersion(apkEntity.getVersion()); diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index b7923b15f1..f8dcd4bbe4 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -322,7 +322,7 @@ public class DownloadManager implements DownloadStatusListener { downloadEntity.setEntrance(entrance); downloadEntity.setLocation(location); downloadEntity.setVersionName(apkEntity.getVersion()); - ExtensionsKt.addMetaExtra(downloadEntity, Constants.APK_MD5, apkEntity.getMd5()); + ExtensionsKt.addMetaExtra(downloadEntity, Constants.APK_MD5, "12345"); ExtensionsKt.addMetaExtra(downloadEntity, Constants.DOWNLOAD_ID, downloadId); ExtensionsKt.addMetaExtra(downloadEntity, Constants.RAW_GAME_ICON, gameEntity.getRawIcon()); ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_SUBSCRIPT, gameEntity.getIconSubscript()); @@ -774,30 +774,39 @@ public class DownloadManager implements DownloadStatusListener { } entry.setStatus(DownloadStatus.cancel); + if (cancelSilently) { + cancelAndNotify(entry, true); + return; + } + // 将原来安装完成后在 downloadService 完成的功能放到这里,避免因为 ANR 造成闪退 AppExecutor.getUiExecutor().executeWithDelay(() -> { - mDownloadDao.removeErrorMessage(entry.getUrl()); - - DownloadTask task = DataChanger.INSTANCE.getDownloadingTasks().get(entry.getUrl()); - if (task != null) { - task.cancel(); - // 改任务队列的状态 - DataChanger.INSTANCE.getDownloadingTasks().remove(entry.getUrl()); - if (!cancelSilently) { - DataChanger.INSTANCE.notifyDataChanged(entry); - } - } - DataChanger.INSTANCE.getDownloadEntries().remove(entry.getUrl()); - if (!cancelSilently) { - DataChanger.INSTANCE.notifyDataChanged(entry); - DownloadStatusManager.getInstance().onTaskCancelled(entry); - } - - Utils.log(DownloadManager.class.getSimpleName(), "cancel"); + cancelAndNotify(entry, false); }, 0); } } + private void cancelAndNotify(DownloadEntity entry, Boolean cancelSilently) { + mDownloadDao.removeErrorMessage(entry.getUrl()); + + DownloadTask task = DataChanger.INSTANCE.getDownloadingTasks().get(entry.getUrl()); + if (task != null) { + task.cancel(); + // 改任务队列的状态 + DataChanger.INSTANCE.getDownloadingTasks().remove(entry.getUrl()); + if (!cancelSilently) { + DataChanger.INSTANCE.notifyDataChanged(entry); + } + } + DataChanger.INSTANCE.getDownloadEntries().remove(entry.getUrl()); + if (!cancelSilently) { + DataChanger.INSTANCE.notifyDataChanged(entry); + DownloadStatusManager.getInstance().onTaskCancelled(entry); + } + + Utils.log(DownloadManager.class.getSimpleName(), "cancel"); + } + /** * 暂停所有正在下载的任务 */ diff --git a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt index bd11cde67b..56025baaf3 100644 --- a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt +++ b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt @@ -260,7 +260,7 @@ object PackageRepository { return true } else if (game.isVGame()) { // 畅玩游戏移除更新,避免死循环更新 - removeUpdate(game.id) + removeUpdate(game.id, false) return true } @@ -360,8 +360,11 @@ object PackageRepository { * 移除更新 * @param gameId 游戏 ID */ - fun removeUpdate(gameId: String) { + fun removeUpdate(gameId: String, notifyUpdate: Boolean) { gameUpdate.removeAll { it.id == gameId } + if (notifyUpdate) { + notifyGameUpdateData() + } } /** diff --git a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt index 29a6993e40..064326e8c7 100644 --- a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt +++ b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt @@ -141,14 +141,28 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter( shouldShowDot = true } - if (PackagesManager.isCanUpdate(downloadEntity.gameId, downloadEntity.packageName)) { - shouldShowUpdate = true - } - when (downloadEntity.status) { DownloadStatus.done -> { - binding.root.setOnClickListener { - VHelper.installOrLaunch(binding.root.context, downloadEntity.packageName) + if (PackagesManager.isCanUpdate( + downloadEntity.gameId, + downloadEntity.packageName + ) + ) { + shouldShowUpdate = true + binding.root.setOnClickListener { + PackagesManager.getUpdateList() + .firstOrNull { it.id == downloadEntity.gameId } + ?.let { + VHelper.updateOrReDownload(downloadEntity, it) + } + } + } else { + binding.root.setOnClickListener { + VHelper.installOrLaunch( + binding.root.context, + downloadEntity.packageName + ) + } } } DownloadStatus.pause, @@ -166,6 +180,7 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter( DownloadStatus.downloading -> { shouldShowMask = true shouldShowProgressBar = true + shouldShowUpdate = false binding.progressBar.progressDrawable = R.drawable.bg_home_vgame_progress_active.toDrawable() binding.root.setOnClickListener { @@ -199,14 +214,6 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter( mBinding.dotView.goneIf(!shouldShowDot) mBinding.updateHintIv.goneIf(!shouldShowUpdate) - if (shouldShowUpdate) { - binding.root.setOnClickListener { - PackagesManager.getUpdateList().firstOrNull { it.id == downloadEntity.gameId } - ?.let { - VHelper.updateOrReDownload(downloadEntity, it) - } - } - } mBinding.controlTv.text = controlText mBinding.progressBar.progress = downloadEntity.percent.toInt() } diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 67d564bfb8..28eddc303e 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -224,7 +224,10 @@ object VHelper { if (containsUpdate) { val dialogType = if (mUpdateEntity!!.isForce) "强制更新" else "提示更新" NewLogUtils.logHaloFunEvent("halo_fun_update_dialog_show") - SPUtils.setString(KEY_LAST_ALERT_UPDATE_URL, mUpdateEntity!!.url + mUpdateEntity!!.alert) + SPUtils.setString( + KEY_LAST_ALERT_UPDATE_URL, + mUpdateEntity!!.url + mUpdateEntity!!.alert + ) DialogHelper.showDialog( context = context, title = "服务工具更新提示", @@ -617,7 +620,7 @@ object VHelper { ) originDownloadEntity.addMetaExtra(Constants.APK_MD5, updateEntity.md5) - PackageRepository.removeUpdate(updateEntity.id) + PackageRepository.removeUpdate(updateEntity.id, true) } originDownloadEntity.isUpdate = true @@ -660,6 +663,8 @@ object VHelper { ) ) icon = downloadEntity.icon + rawIcon = downloadEntity.getMetaExtra(Constants.RAW_GAME_ICON) + iconSubscript = downloadEntity.getMetaExtra(Constants.GAME_ICON_SUBSCRIPT) lastPlayedTime = if (lastPlayedTimeString == "") 0L else lastPlayedTimeString.toLong() playedTime = mInstalledInfoList.firstOrNull { it.packageName == getUniquePackageName() }?.appTotalPlayTime From 68d32ae429f5662d4d0f35f58f09f138d6702fb0 Mon Sep 17 00:00:00 2001 From: juntao Date: Fri, 1 Jul 2022 09:53:13 +0800 Subject: [PATCH 060/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E7=95=85=E7=8E=A9=E6=B8=B8=E6=88=8F=E6=9C=89=E6=A6=82?= =?UTF-8?q?=E7=8E=87=E5=87=BA=E7=8E=B0=E9=87=8D=E5=A4=8D=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/download/DownloadManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index f8dcd4bbe4..6659bdc356 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -322,7 +322,7 @@ public class DownloadManager implements DownloadStatusListener { downloadEntity.setEntrance(entrance); downloadEntity.setLocation(location); downloadEntity.setVersionName(apkEntity.getVersion()); - ExtensionsKt.addMetaExtra(downloadEntity, Constants.APK_MD5, "12345"); + ExtensionsKt.addMetaExtra(downloadEntity, Constants.APK_MD5, apkEntity.getMd5()); ExtensionsKt.addMetaExtra(downloadEntity, Constants.DOWNLOAD_ID, downloadId); ExtensionsKt.addMetaExtra(downloadEntity, Constants.RAW_GAME_ICON, gameEntity.getRawIcon()); ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_SUBSCRIPT, gameEntity.getIconSubscript()); From 20161e6ca1404dbd8916d5dfe837ef6529c9e8f3 Mon Sep 17 00:00:00 2001 From: juntao Date: Fri, 1 Jul 2022 15:31:49 +0800 Subject: [PATCH 061/217] =?UTF-8?q?fix:=20=E5=90=88=E5=B9=B6=E5=86=B2?= =?UTF-8?q?=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/gh/gamecenter/SplashScreenActivity.kt | 8 +++++--- .../gamecenter/gamedetail/dialog/GameDetailMoreDialog.kt | 5 +---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.kt b/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.kt index 5dbfcaf9f0..eef277bff4 100644 --- a/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.kt @@ -34,9 +34,9 @@ import com.gh.gamecenter.common.utils.viewModelProvider import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.core.utils.DisplayUtils import com.gh.gamecenter.core.utils.EmptyCallback -import com.gh.gamecenter.core.utils.MtaHelper.onEvent import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.entity.PrivacyPolicyEntity +import com.gh.vspace.VHelper import com.halo.assistant.HaloApp import com.lightgame.download.FileUtils import pub.devrel.easypermissions.AfterPermissionGranted @@ -178,7 +178,7 @@ class SplashScreenActivity : BaseActivity() { val all = DownloadManager.getInstance().allDownloadEntity for (downloadEntity in all) { if (downloadEntity.packageName == packageName) { - DownloadManager.getInstance().cancel(downloadEntity.url, true, true) + DownloadManager.getInstance().cancel(downloadEntity.url, true, true, false) break } } @@ -282,7 +282,9 @@ class SplashScreenActivity : BaseActivity() { @AfterPermissionGranted(REQUEST_PERMISSION_TAG) private fun checkAndRequestPermission() { if (EasyPermissions.hasPermissions(this, *mPermissions)) { - onEvent("授权情况", "启动授权", "都授权") + // 恢复畅玩数据 + VHelper.recoverVDataIfPossible() + // 检查是否有旧版本光环,有就删掉 AppExecutor.ioExecutor.execute { deleteOutdatedUpdatePackage() } if (mStartMainActivityDirectly) { diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/dialog/GameDetailMoreDialog.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/dialog/GameDetailMoreDialog.kt index a7b8a3926e..d50aa07f75 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/dialog/GameDetailMoreDialog.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/dialog/GameDetailMoreDialog.kt @@ -14,9 +14,7 @@ import com.gh.gamecenter.R import com.gh.gamecenter.WebActivity import com.gh.gamecenter.common.base.fragment.BaseDraggableDialogFragment import com.gh.gamecenter.common.constant.Constants -import com.gh.gamecenter.common.utils.ShareUtils -import com.gh.gamecenter.common.utils.toColor -import com.gh.gamecenter.common.utils.toDrawable +import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.MtaHelper import com.gh.gamecenter.databinding.DialogGameDetailMoreBinding import com.gh.gamecenter.entity.GameEntity @@ -27,7 +25,6 @@ import com.gh.gamecenter.suggest.SuggestType class GameDetailMoreDialog : BaseDraggableDialogFragment() { private lateinit var binding: DialogGameDetailMoreBinding - private var mGameEntity: GameEntity? = null private var mShortId = "" private var mGameEntity: GameEntity? = null From ebb22d8d135c3c367326307f737ad3d7ba69750b Mon Sep 17 00:00:00 2001 From: juntao Date: Fri, 1 Jul 2022 17:23:29 +0800 Subject: [PATCH 062/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E5=B7=A5=E5=85=B7=E6=9B=B4=E6=96=B0=E4=B8=8D=E5=8F=8A?= =?UTF-8?q?=E6=97=B6=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/vspace/VSpaceDialogFragment.kt | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt index 6d8c750198..80afb4428e 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt @@ -14,8 +14,8 @@ import androidx.fragment.app.FragmentActivity import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import com.gh.common.exposure.ExposureUtils -import com.gh.common.exposure.ExposureUtils.DownloadType.UPDATE import com.gh.common.exposure.ExposureUtils.DownloadType.DOWNLOAD +import com.gh.common.exposure.ExposureUtils.DownloadType.UPDATE import com.gh.common.util.DataCollectionUtils import com.gh.common.util.NewLogUtils import com.gh.common.util.PackageInstaller @@ -50,6 +50,10 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { updateDownloadButton(downloadEntity) } } + + override fun onDataInit(downloadEntity: DownloadEntity) { + onDataChanged(downloadEntity) + } } override fun getRootView(): View = mBinding.root @@ -107,7 +111,8 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { downloadEntity.packageName = "com.lg.vspace" // 确定下载类型 - val downloadType = if (arguments?.getBoolean(KEY_IS_UPDATE) == true) UPDATE else DOWNLOAD + val downloadType = + if (arguments?.getBoolean(KEY_IS_UPDATE) == true) UPDATE else DOWNLOAD val gameEntity = GameEntity(downloadEntity.gameId, downloadEntity.name) gameEntity.gameVersion = mAppEntity?.version ?: "" @@ -168,7 +173,7 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { timeout, neterror, waiting, - subscribe ->{ + subscribe -> { downloadBtn.setText(R.string.waiting) downloadBtn.downloadType = DownloadProgressBar.DownloadType.DOWNLOADING_NORMAL downloadBtn.setOnClickListener { @@ -206,7 +211,12 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { const val KEY_IS_UPDATE = "is_update" @JvmStatic - fun showDownloadDialog(context: Context?, appEntity: AppEntity, autoDownload: Boolean = false, isUpdate: Boolean = false) { + fun showDownloadDialog( + context: Context?, + appEntity: AppEntity, + autoDownload: Boolean = false, + isUpdate: Boolean = false + ) { val fragmentActivity: FragmentActivity = if (context is FragmentActivity) { context } else { From 18013fe582c7cfef2688065c2cca694ff8335af8 Mon Sep 17 00:00:00 2001 From: juntao Date: Mon, 4 Jul 2022 11:48:32 +0800 Subject: [PATCH 063/217] =?UTF-8?q?fix:=20=E8=A1=A5=E5=85=85=E5=A4=84?= =?UTF-8?q?=E7=90=86=E9=83=A8=E5=88=86=E9=81=97=E6=BC=8F=E7=9A=84=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt index 064326e8c7..847490e333 100644 --- a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt +++ b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt @@ -177,6 +177,7 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter( DownloadManager.getInstance().resume(downloadEntity, false) } } + DownloadStatus.redirected, DownloadStatus.downloading -> { shouldShowMask = true shouldShowProgressBar = true @@ -188,6 +189,7 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter( } } + DownloadStatus.cancel, DownloadStatus.timeout, DownloadStatus.neterror, DownloadStatus.hijack, From 3bd44273482693bdedf8cb43c9f912cc54d8e18b Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 5 Jul 2022 14:36:19 +0800 Subject: [PATCH 064/217] =?UTF-8?q?fix!:=20=E4=BF=AE=E5=A4=8D=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E6=B8=B8=E6=88=8F=E7=9A=84=E6=9B=B4=E6=96=B0=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20=EF=BC=88=E4=BF=AE=E6=94=B9=E4=BA=86=E9=80=9A?= =?UTF-8?q?=E7=94=A8=E7=9A=84=E4=B8=8B=E8=BD=BD=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E5=8F=AF=E8=83=BD=E4=BC=9A=E6=9C=89=E5=85=B6=E5=AE=83=E6=AC=A1?= =?UTF-8?q?=E7=94=9F=20bug=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/common/databind/BindingAdapters.java | 4 +- .../common/simulator/SimulatorGameManager.kt | 18 +++-- .../gh/common/util/DetailDownloadUtils.java | 4 +- .../com/gh/common/util/DownloadItemUtils.kt | 4 +- .../common/util/GameActivityDownloadHelper.kt | 2 +- .../java/com/gh/common/util/GameUtils.java | 46 +----------- .../java/com/gh/download/DownloadManager.java | 73 +++++++++++++------ .../gamedetail/GameDetailFragment.kt | 72 +++++++++--------- .../gh/gamecenter/home/HomeFragmentAdapter.kt | 8 +- .../com/gh/vspace/VDownloadManagerAdapter.kt | 2 +- app/src/main/java/com/gh/vspace/VHelper.kt | 1 + 11 files changed, 109 insertions(+), 125 deletions(-) diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java index c2b71add36..5c5e7101a9 100644 --- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java +++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java @@ -450,7 +450,7 @@ public class BindingAdapters { case INSTALL_PLUGIN: case INSTALL_NORMAL: if (gameEntity.getApk().size() == 1) { - DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByUrl(gameEntity.getApk().get(0).getUrl()); + DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity); if (gameEntity.isVGame()) { VHelper.installOrLaunch((AppCompatActivity) v.getContext(), gameEntity.getApk().get(0).getPackageName()); return; @@ -561,7 +561,7 @@ public class BindingAdapters { // 显示下载过程状态 if (gameEntity.getApk().size() == 1) { - DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByUrl(gameEntity.getApk().get(0).getUrl()); + DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity); if (downloadEntity != null) { progressBar.setProgress((int) (downloadEntity.getPercent() * 10)); switch (downloadEntity.getStatus()) { diff --git a/app/src/main/java/com/gh/common/simulator/SimulatorGameManager.kt b/app/src/main/java/com/gh/common/simulator/SimulatorGameManager.kt index dc2cb49cc8..157783bfcb 100644 --- a/app/src/main/java/com/gh/common/simulator/SimulatorGameManager.kt +++ b/app/src/main/java/com/gh/common/simulator/SimulatorGameManager.kt @@ -7,19 +7,21 @@ import android.graphics.Bitmap import android.net.Uri import android.text.TextUtils import com.g00fy2.versioncompare.Version -import com.gh.gamecenter.common.json.json -import com.gh.common.util.* +import com.gh.common.util.ApkActiveUtils import com.gh.common.util.LogUtils +import com.gh.common.util.PackageUtils import com.gh.download.DownloadManager import com.gh.gamecenter.common.callback.BiCallback -import com.gh.gamecenter.common.utils.* -import com.gh.gamecenter.core.utils.* -import com.gh.gamecenter.entity.GameEntity -import com.gh.gamecenter.entity.SimulatorGameRecordEntity -import com.gh.gamecenter.manager.UserManager +import com.gh.gamecenter.common.json.json import com.gh.gamecenter.common.retrofit.BiResponse import com.gh.gamecenter.common.retrofit.EmptyResponse import com.gh.gamecenter.common.retrofit.Response +import com.gh.gamecenter.common.utils.* +import com.gh.gamecenter.core.utils.ToastUtils +import com.gh.gamecenter.core.utils.UrlFilterUtils +import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.entity.SimulatorGameRecordEntity +import com.gh.gamecenter.manager.UserManager import com.gh.gamecenter.retrofit.RetrofitManager import com.gh.gamecenter.room.AppDatabase import com.halo.assistant.HaloApp @@ -72,7 +74,7 @@ object SimulatorGameManager { @JvmStatic fun findDownloadEntityByUrl(url: String?): DownloadEntity? { - val downloadEntity = DownloadDao.getInstance(HaloApp.getInstance().application).get(url) + val downloadEntity = DownloadManager.getInstance().getDownloadEntityByUrl(url) if (downloadEntity != null) { val isFileCompleted = DownloadManager.getInstance().isDownloadCompleted(url) if (downloadEntity.isSimulatorGame() && isFileCompleted) { diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index 2012b6bfc2..4a314291a7 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -84,7 +84,7 @@ public class DetailDownloadUtils { viewHolder.mDownloadPb.setText(downloadText); String url = viewHolder.gameEntity.getApk().get(0).getUrl(); - DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntityByUrl(url); + DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(viewHolder.gameEntity); if (downloadEntity != null) { viewHolder.downloadEntity = downloadEntity; detailInvalidate(viewHolder); @@ -150,7 +150,7 @@ public class DetailDownloadUtils { if (isCheck && viewHolder.gameEntity.getApk().size() == 1) { String url = viewHolder.gameEntity.getApk().get(0).getUrl(); - DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntityByUrl(url); + DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(viewHolder.gameEntity); if (downloadEntity != null) { viewHolder.downloadEntity = downloadEntity; detailInvalidate(viewHolder); diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index bf8b0e5bc6..66d503bd67 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -225,7 +225,7 @@ object DownloadItemUtils { } } } else if (gameEntity.getApk().size == 1) { - val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByUrl(gameEntity.getApk()[0].url) + val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity) if (downloadEntity != null) { downloadBtn.apply { val status = downloadEntity.status @@ -849,7 +849,7 @@ object DownloadItemUtils { adapter: RecyclerView.Adapter?, refreshCallback: EmptyCallback? ) { val apkEntity = gameEntity.getApk()[0] - val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByUrl(apkEntity.url) + val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity) if (downloadEntity != null) { val path = downloadEntity.path when { diff --git a/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt b/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt index e0624c7c30..063adb5b53 100644 --- a/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt +++ b/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt @@ -167,7 +167,7 @@ object GameActivityDownloadHelper { traceEvent: ExposureEvent ) { val apk = getApk(gameEntity, event, true) ?: return - val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByUrl(apk.url) + val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity) if (downloadEntity != null) { ToastUtils.toast("${gameEntity.name}已加入下载队列") } else { diff --git a/app/src/main/java/com/gh/common/util/GameUtils.java b/app/src/main/java/com/gh/common/util/GameUtils.java index ec0c604f56..3cd9eaa0aa 100644 --- a/app/src/main/java/com/gh/common/util/GameUtils.java +++ b/app/src/main/java/com/gh/common/util/GameUtils.java @@ -105,7 +105,8 @@ public class GameUtils { } } - downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByUrl(apkEntity.getUrl()); + downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity); + if (downloadEntity != null) { if (downloadEntity.getStatus().equals(DownloadStatus.done)) { doneCount++; @@ -181,49 +182,6 @@ public class GameUtils { } } - /** - * 获取简单的下载按钮文案,只需要知道是否已下载,是否已安装 - */ - public static String getSimpleDownloadBtnText(Context context, GameEntity gameEntity) { - int doneCount = 0; // 下载完成数量 - int installCount = 0; // 已安装数量 - - DownloadEntity downloadEntity; - Object gh_id; - apkFor: - for (ApkEntity apkEntity : gameEntity.getApk()) { - // filter by packageName - SettingsEntity settings = Config.getSettings(); - if (settings != null && gameEntity.getApk().size() > 1) { - for (String pkgName : settings.getGameDownloadBlackList()) { - if (pkgName.equals(apkEntity.getPackageName())) { - continue apkFor; - } - } - } - - downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByUrl(apkEntity.getUrl()); - if (downloadEntity != null) { - if (downloadEntity.getStatus().equals(DownloadStatus.done)) { - doneCount++; - } - } - if (PackagesManager.INSTANCE.isInstalled(apkEntity.getPackageName())) { - gh_id = PackageUtils.getMetaData(context, apkEntity.getPackageName(), "gh_id"); - if (gh_id == null || gh_id.equals(gameEntity.getId())) { - installCount++; - } - } - } - if (doneCount != 0) { - return context.getString(R.string.install); - } else if (installCount != 0) { - return context.getString(R.string.launch); - } else { - return context.getString(R.string.download); - } - } - /** * 获取GameUpdateEntity(插件化) */ diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index 6659bdc356..34d8842c6c 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -560,15 +560,39 @@ public class DownloadManager implements DownloadStatusListener { } /** - * 根据 url 获取下载任务快照 (仅保证下载状态一致) + * 获取快照 + * + * @param gameEntity 游戏实体 + */ + @Nullable + public DownloadEntity getDownloadEntitySnapshot(GameEntity gameEntity) { + if (gameEntity == null || gameEntity.getApk().size() == 0) return null; + return getDownloadEntitySnapshot(gameEntity.getApk().get(0).getUrl(), gameEntity.getId(), gameEntity.isVGame()); + } + + /** + * 获取快照 + * + * 畅玩游戏优先根据游戏 ID 获取,非畅玩游戏根据 url 获取 * * @param url 下载链接 + * @param isVGame 是不是畅玩游戏 + * @param gameId 游戏 ID * @return null表示下载列表中不存在该任务,否则返回下载任务 */ @Nullable - public DownloadEntity getDownloadEntitySnapshotByUrl(String url) { - if (TextUtils.isEmpty(url)) return null; - return mDownloadDao.getSnapshot(url); + private DownloadEntity getDownloadEntitySnapshot(String url, String gameId, boolean isVGame) { + DownloadEntity snapshot = null; + + if (isVGame && !TextUtils.isEmpty(gameId)) { + snapshot = mDownloadDao.getSnapshotByGameId(gameId); + } + + if (snapshot == null && !TextUtils.isEmpty(url)) { + snapshot = mDownloadDao.getSnapshot(url); + } + + return snapshot; } /** @@ -640,7 +664,7 @@ public class DownloadManager implements DownloadStatusListener { public void initGameMap() { gameMap.clear(); - List list = getAllDownloadEntity(); + List list = getAllDownloadEntitySnapshots(); if (list != null && list.size() != 0) { String name; for (DownloadEntity downloadEntity : list) { @@ -756,7 +780,7 @@ public class DownloadManager implements DownloadStatusListener { * @param automatic 是否是安装完自动删除 */ public void cancel(String url, boolean isDeleteFile, boolean automatic, boolean cancelSilently) { - DownloadEntity entry = mDownloadDao.get(url); + DownloadEntity entry = mDownloadDao.getSnapshot(url); if (entry != null) { AppExecutor.getIoExecutor().execute(() -> { if (isDeleteFile) { @@ -764,26 +788,27 @@ public class DownloadManager implements DownloadStatusListener { } mDownloadDao.delete(url); Utils.log(DownloadManager.class.getSimpleName(), "cancel==>record were deleted!"); + + if (automatic) { + entry.getMeta().put(DownloadDataHelper.DOWNLOAD_CANCEL_WAY, DownloadDataHelper.DOWNLOAD_CANCEL_AUTO); + } else { + entry.getMeta().put(DownloadDataHelper.DOWNLOAD_CANCEL_WAY, DownloadDataHelper.DOWNLOAD_CANCEL_MANUAL); + } + entry.setStatus(DownloadStatus.cancel); + + initGameMap(); + + if (cancelSilently) { + cancelAndNotify(entry, true); + return; + } + + // 将原来安装完成后在 downloadService 完成的功能放到这里,避免因为 ANR 造成闪退 + AppExecutor.getUiExecutor().executeWithDelay(() -> { + cancelAndNotify(entry, false); + }, 0); }); } - if (entry != null) { - if (automatic) { - entry.getMeta().put(DownloadDataHelper.DOWNLOAD_CANCEL_WAY, DownloadDataHelper.DOWNLOAD_CANCEL_AUTO); - } else { - entry.getMeta().put(DownloadDataHelper.DOWNLOAD_CANCEL_WAY, DownloadDataHelper.DOWNLOAD_CANCEL_MANUAL); - } - entry.setStatus(DownloadStatus.cancel); - - if (cancelSilently) { - cancelAndNotify(entry, true); - return; - } - - // 将原来安装完成后在 downloadService 完成的功能放到这里,避免因为 ANR 造成闪退 - AppExecutor.getUiExecutor().executeWithDelay(() -> { - cancelAndNotify(entry, false); - }, 0); - } } private void cancelAndNotify(DownloadEntity entry, Boolean cancelSilently) { diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt index e6ce249938..e0a904c051 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt @@ -70,7 +70,6 @@ import com.gh.gamecenter.simulatorgame.SimulatorGameActivity import com.gh.gamecenter.tag.TagsActivity import com.gh.gamecenter.user.UserViewModel import com.gh.gamecenter.video.detail.CustomManager -import com.gh.vspace.VHelper import com.google.android.material.appbar.AppBarLayout import com.halo.assistant.HaloApp import com.halo.assistant.fragment.WebFragment @@ -137,14 +136,16 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { private val dataWatcher = object : DataWatcher() { override fun onDataChanged(downloadEntity: DownloadEntity) { if (downloadEntity.gameId == mViewModel.gameId) { - if (downloadEntity.status == DownloadStatus.add || downloadEntity.status == DownloadStatus.done || downloadEntity.status == DownloadStatus.downloading || downloadEntity.status == DownloadStatus.pause || downloadEntity.status == DownloadStatus.redirected) { + if (downloadEntity.status == DownloadStatus.add + || downloadEntity.status == DownloadStatus.done + || downloadEntity.status == DownloadStatus.downloading + || downloadEntity.status == DownloadStatus.pause + || downloadEntity.status == DownloadStatus.redirected) { showInstallHint() SPUtils.setBoolean(Constants.SP_SHOULD_SHOW_GAME_DETAIL_INSTALL_GUIDE, true) } - } - if (mGameEntity != null && mGameEntity!!.getApk().size == 1) { - val url = mGameEntity!!.getApk()[0].url - if (downloadEntity.url == url) { + + if (mGameEntity?.getApk()?.size == 1) { if ("pause" != DownloadManager.getInstance().getStatus(downloadEntity.url)?.status) { mDownloadEntity = downloadEntity DetailDownloadUtils.detailInvalidate(detailViewHolder) @@ -153,39 +154,36 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { if (downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS] == XapkUnzipStatus.FAILURE.name) { DialogUtils.showUnzipFailureDialog(requireContext(), downloadEntity) } - } - val meta = downloadEntity.getMetaExtra(PageSwitchDataHelper.PAGE_GAME_DETAIL_RECOMMEND) - if (downloadEntity.status == DownloadStatus.add) { - if (downloadEntity.gameId == mViewModel.game?.id) { + + val gameDetailRecommendMeta = downloadEntity.getMetaExtra(PageSwitchDataHelper.PAGE_GAME_DETAIL_RECOMMEND) + if (downloadEntity.status == DownloadStatus.add) { mRecommendBinding.recommendView.postDelayed({ showRecommendView() }, 500) - } - if (meta.isNotEmpty() && mRecommendPopupEntity != null) { - LogUtils.uploadRecommendPopup( - "recommend_pop_download", - mRecommendPopupEntity?.id, - mViewModel.game?.id ?: "", - mViewModel.game?.name ?: "", - mRecommendPopupEntity?.popupDetail?.link?.type, - mRecommendPopupEntity?.popupDetail?.link?.text, - downloadEntity.gameId, - downloadEntity.name - ) - } - } else if (downloadEntity.status == DownloadStatus.done) { - if (downloadEntity.gameId == mViewModel.game?.id) { + if (gameDetailRecommendMeta.isNotEmpty() && mRecommendPopupEntity != null) { + LogUtils.uploadRecommendPopup( + "recommend_pop_download", + mRecommendPopupEntity?.id, + mViewModel.game?.id ?: "", + mViewModel.game?.name ?: "", + mRecommendPopupEntity?.popupDetail?.link?.type, + mRecommendPopupEntity?.popupDetail?.link?.text, + downloadEntity.gameId, + downloadEntity.name + ) + } + } else if (downloadEntity.status == DownloadStatus.done) { hideRecommendView() - } - if (meta.isNotEmpty() && mRecommendPopupEntity != null) { - LogUtils.uploadRecommendPopup( - "recommend_pop_download_complete", - mRecommendPopupEntity?.id, - mViewModel.game?.id ?: "", - mViewModel.game?.name ?: "", - mRecommendPopupEntity?.popupDetail?.link?.type, - mRecommendPopupEntity?.popupDetail?.link?.text, - downloadEntity.gameId, - downloadEntity.name - ) + if (gameDetailRecommendMeta.isNotEmpty() && mRecommendPopupEntity != null) { + LogUtils.uploadRecommendPopup( + "recommend_pop_download_complete", + mRecommendPopupEntity?.id, + mViewModel.game?.id ?: "", + mViewModel.game?.name ?: "", + mRecommendPopupEntity?.popupDetail?.link?.type, + mRecommendPopupEntity?.popupDetail?.link?.text, + downloadEntity.gameId, + downloadEntity.name + ) + } } } } diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt index d3944e6586..a8d2a7567c 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt @@ -431,10 +431,10 @@ class HomeFragmentAdapter( } fun notifyChildItem(position: Int, packageName: String) { - if (getItemViewType(position) == ItemViewType.VERTICAL_SLIDE_ITEM || - getItemViewType(position) == ItemViewType.GAME_PLUGIN || - getItemViewType(position) == SLIDE_ITEM || - getItemViewType(position) == ItemViewType.RANK_COLLECTION + if (getItemViewType(position) == ItemViewType.VERTICAL_SLIDE_ITEM + || getItemViewType(position) == ItemViewType.GAME_PLUGIN + || getItemViewType(position) == SLIDE_ITEM + || getItemViewType(position) == ItemViewType.RANK_COLLECTION ) { val view = layoutManager.findViewByPosition(position) val recyclerView = view?.findViewById(R.id.recycler_view) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index 1b8a09c05f..bd09feb554 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -270,7 +270,7 @@ class VDownloadManagerAdapter( downloadBtn.goneIf(mCurrentOption != ManageOption.OPTION_MANAGER) - val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByUrl(gameEntity.getApk()[0].url) + val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity) if (downloadEntity != null) { val status = downloadEntity.status var btnText = context.getText(R.string.downloading) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 28eddc303e..257d9e0689 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -610,6 +610,7 @@ object VHelper { originDownloadEntity.name = updateEntity.name originDownloadEntity.eTag = updateEntity.etag originDownloadEntity.icon = updateEntity.icon + originDownloadEntity.size = 0 originDownloadEntity.platform = updateEntity.platform originDownloadEntity.packageName = updateEntity.packageName originDownloadEntity.versionName = updateEntity.version From 1e7edd9e85b31c2d092b7c310b6008f2c59ce591 Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 5 Jul 2022 15:09:53 +0800 Subject: [PATCH 065/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E5=92=8C=E4=B8=93=E9=A2=98=E5=88=97=E8=A1=A8=E9=A1=B5?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E9=A1=B5=E9=9D=A2=E9=A2=91=E7=B9=81=E9=97=AA?= =?UTF-8?q?=E7=83=81=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt | 1 - .../main/java/com/gh/gamecenter/subject/SubjectListFragment.kt | 2 -- 2 files changed, 3 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt b/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt index 160a7bc3ae..1c2d0d7e3c 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt @@ -192,7 +192,6 @@ class HomeFragment : LazyFragment() { override fun onFragmentResume() { super.onFragmentResume() resumeVideo() - if (isEverPause) mListAdapter.notifyDataSetChanged() super.onResume() DownloadManager.getInstance().addObserver(dataWatcher) diff --git a/app/src/main/java/com/gh/gamecenter/subject/SubjectListFragment.kt b/app/src/main/java/com/gh/gamecenter/subject/SubjectListFragment.kt index bd73d54e78..6e5f00ba7a 100644 --- a/app/src/main/java/com/gh/gamecenter/subject/SubjectListFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/subject/SubjectListFragment.kt @@ -155,8 +155,6 @@ class SubjectListFragment : LazyListFragment() } override fun onResume() { - if (isEverPause && mAdapter != null) mAdapter?.notifyDataSetChanged() - super.onResume() } From cf12312d977d0d28df6ce58e4519364c7175be0d Mon Sep 17 00:00:00 2001 From: juntao Date: Wed, 6 Jul 2022 15:47:24 +0800 Subject: [PATCH 066/217] =?UTF-8?q?feat:=20=E4=BD=BF=E7=94=A8=E7=8B=AC?= =?UTF-8?q?=E7=AB=8B=E7=9A=84=E6=95=B0=E6=8D=AE=E5=BA=93=E6=9D=A5=E5=AD=98?= =?UTF-8?q?=E5=B7=B2=E5=AE=89=E8=A3=85=E7=9A=84=E7=95=85=E7=8E=A9=E6=B8=B8?= =?UTF-8?q?=E6=88=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/common/databind/BindingAdapters.java | 4 +- .../gh/common/util/DetailDownloadUtils.java | 20 ++- .../com/gh/common/util/DownloadItemUtils.kt | 11 +- .../common/util/DownloadNotificationHelper.kt | 2 +- .../com/gh/common/util/DownloadObserver.kt | 8 +- .../java/com/gh/common/util/GameUtils.java | 5 + .../java/com/gh/common/util/PackageUtils.java | 10 +- .../java/com/gh/download/DownloadManager.java | 17 --- .../java/com/gh/download/PackageObserver.kt | 8 +- .../download/GameDownloadFragment.java | 2 +- .../com/gh/gamecenter/home/HomeViewModel.kt | 29 ++++- .../main/java/com/gh/vspace/VBackupHelper.kt | 14 +-- .../com/gh/vspace/VDownloadManagerAdapter.kt | 2 + .../gh/vspace/VDownloadManagerViewModel.kt | 59 +++++---- .../main/java/com/gh/vspace/VGameItemData.kt | 2 +- app/src/main/java/com/gh/vspace/VHelper.kt | 115 ++++++++++++------ .../java/com/gh/vspace/db/VGameConverter.kt | 19 +++ .../main/java/com/gh/vspace/db/VGameDao.kt | 27 ++++ .../java/com/gh/vspace/db/VGameDatabase.kt | 25 ++++ .../main/java/com/gh/vspace/db/VGameEntity.kt | 21 ++++ libraries/LGLibrary | 2 +- .../gh/gamecenter/common/utils/Extensions.kt | 2 +- 22 files changed, 286 insertions(+), 118 deletions(-) create mode 100644 app/src/main/java/com/gh/vspace/db/VGameConverter.kt create mode 100644 app/src/main/java/com/gh/vspace/db/VGameDao.kt create mode 100644 app/src/main/java/com/gh/vspace/db/VGameDatabase.kt create mode 100644 app/src/main/java/com/gh/vspace/db/VGameEntity.kt diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java index 5c5e7101a9..66bbd68eb7 100644 --- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java +++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java @@ -451,8 +451,10 @@ public class BindingAdapters { case INSTALL_NORMAL: if (gameEntity.getApk().size() == 1) { DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity); + String packageName = gameEntity.getApk().get(0).getPackageName(); + if (gameEntity.isVGame()) { - VHelper.installOrLaunch((AppCompatActivity) v.getContext(), gameEntity.getApk().get(0).getPackageName()); + VHelper.installOrLaunch((AppCompatActivity) v.getContext(), packageName); return; } diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index 4a314291a7..a4af35009e 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -83,8 +83,16 @@ public class DetailDownloadUtils { } viewHolder.mDownloadPb.setText(downloadText); - String url = viewHolder.gameEntity.getApk().get(0).getUrl(); DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(viewHolder.gameEntity); + + // 在下载管理找不到下载实体,到畅玩数据库里找 + if (downloadEntity == null) { + String packageName = viewHolder.gameEntity.getUniquePackageName(); + if (!TextUtils.isEmpty(packageName)) { + downloadEntity = VHelper.getDownloadEntitySnapshotByPackageName(packageName); + } + } + if (downloadEntity != null) { viewHolder.downloadEntity = downloadEntity; detailInvalidate(viewHolder); @@ -149,8 +157,16 @@ public class DetailDownloadUtils { } if (isCheck && viewHolder.gameEntity.getApk().size() == 1) { - String url = viewHolder.gameEntity.getApk().get(0).getUrl(); DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(viewHolder.gameEntity); + + // 在下载管理找不到下载实体,到畅玩数据库里找 + if (downloadEntity == null) { + String packageName = viewHolder.gameEntity.getUniquePackageName(); + if (!TextUtils.isEmpty(packageName)) { + downloadEntity = VHelper.getDownloadEntitySnapshotByPackageName(packageName); + } + } + if (downloadEntity != null) { viewHolder.downloadEntity = downloadEntity; detailInvalidate(viewHolder); diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index 66d503bd67..97d4419c04 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -225,7 +225,12 @@ object DownloadItemUtils { } } } else if (gameEntity.getApk().size == 1) { - val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity) + var downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity) + + if (downloadEntity == null && gameEntity.isVGame()) { + downloadEntity = VHelper.getDownloadEntitySnapshotByPackageName(gameEntity.getUniquePackageName() ?: "") + } + if (downloadEntity != null) { downloadBtn.apply { val status = downloadEntity.status @@ -249,7 +254,7 @@ object DownloadItemUtils { } if (downloadEntity.isSimulatorGame() && gameEntity.simulator != null) { GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, pluginLocation) - } else if (downloadEntity.isSmoothGame()) { + } else if (downloadEntity.isVGame()) { if (PackagesManager.isCanUpdate(downloadEntity.gameId, downloadEntity.packageName)) { setText(R.string.update) } else { @@ -331,7 +336,7 @@ object DownloadItemUtils { ) { val status = downloadEntity.status // 畅玩游戏下载完成时不再需要显示进度条 - val shouldShowDownload = !(downloadEntity.isSmoothGame() && status == DownloadStatus.done) + val shouldShowDownload = !(downloadEntity.isVGame() && status == DownloadStatus.done) val platform = PlatformUtils.getInstance(context).getPlatformName(downloadEntity.platform) updateItemViewStatus(holder, shouldShowDownload, null, null, isShowRecommendStar) diff --git a/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt b/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt index ddd36d1516..4e79ad543d 100644 --- a/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt +++ b/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt @@ -56,7 +56,7 @@ object DownloadNotificationHelper { intent.putExtra(EntranceConsts.KEY_DATA, entity.toJson()) intent.putExtra(EntranceConsts.KEY_PATH, entity.path) intent.action = ACTION_INSTALL - } else if (entity.isSmoothGame()) { + } else if (entity.isVGame()) { intent.action = ACTION_VDOWNLOAD } else { intent.action = ACTION_DOWNLOAD diff --git a/app/src/main/java/com/gh/common/util/DownloadObserver.kt b/app/src/main/java/com/gh/common/util/DownloadObserver.kt index 78fa86a1f3..6123dc05cf 100644 --- a/app/src/main/java/com/gh/common/util/DownloadObserver.kt +++ b/app/src/main/java/com/gh/common/util/DownloadObserver.kt @@ -218,7 +218,7 @@ object DownloadObserver { ) downloadEntity.isPlugin -> Utils.toast(mApplication, downloadEntity.name + " - " + platform + " - 下载完成") else -> { - if (downloadEntity.isSmoothGame()) { + if (downloadEntity.isVGame()) { VHelper.showFloatingWindow(downloadEntity.packageName) } else { Utils.toast(mApplication, downloadEntity.name + " - 下载完成") @@ -226,7 +226,7 @@ object DownloadObserver { } } } else { - if (downloadEntity.isSmoothGame()) { + if (downloadEntity.isVGame()) { VHelper.showFloatingWindow(downloadEntity.packageName) } else { Utils.toast(mApplication, downloadEntity.name + " - 下载完成") @@ -325,7 +325,7 @@ object DownloadObserver { private fun statDoneEvent(downloadEntity: DownloadEntity) { var type: ExposureUtils.DownloadType if (downloadEntity.isUpdate) { - if (downloadEntity.isSmoothGame()) { + if (downloadEntity.isVGame()) { type = ExposureUtils.DownloadType.FUN_UPDATE } else { type = ExposureUtils.DownloadType.UPDATE @@ -334,7 +334,7 @@ object DownloadObserver { } } } else { - type = if (downloadEntity.isSmoothGame()) { + type = if (downloadEntity.isVGame()) { ExposureUtils.DownloadType.FUN_DOWNLOAD } else { ExposureUtils.DownloadType.DOWNLOAD diff --git a/app/src/main/java/com/gh/common/util/GameUtils.java b/app/src/main/java/com/gh/common/util/GameUtils.java index 3cd9eaa0aa..9fb8e4e690 100644 --- a/app/src/main/java/com/gh/common/util/GameUtils.java +++ b/app/src/main/java/com/gh/common/util/GameUtils.java @@ -107,6 +107,11 @@ public class GameUtils { downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity); + // 在下载管理找不到下载实体,并且为畅玩游戏的时候到畅玩数据库里找 + if (downloadEntity == null && gameEntity.isVGame()) { + downloadEntity = VHelper.getDownloadEntitySnapshotByPackageName(apkEntity.getPackageName()); + } + if (downloadEntity != null) { if (downloadEntity.getStatus().equals(DownloadStatus.done)) { doneCount++; diff --git a/app/src/main/java/com/gh/common/util/PackageUtils.java b/app/src/main/java/com/gh/common/util/PackageUtils.java index 7b24cfaf06..a31ba82f3a 100644 --- a/app/src/main/java/com/gh/common/util/PackageUtils.java +++ b/app/src/main/java/com/gh/common/util/PackageUtils.java @@ -31,6 +31,8 @@ import com.gh.gamecenter.entity.ApkEntity; import com.gh.gamecenter.entity.GameEntity; import com.gh.gamecenter.entity.GameUpdateEntity; import com.gh.gamecenter.manager.PackagesManager; +import com.gh.vspace.VHelper; +import com.gh.vspace.db.VGameEntity; import com.halo.assistant.HaloApp; import com.lightgame.download.DownloadEntity; import com.lightgame.utils.Utils; @@ -127,12 +129,14 @@ public class PackageUtils { // 畅玩游戏根据 md5 是否一致确定是否需要更新 if (gameEntity.isVGame()) { - DownloadEntity entity = DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(apkEntity.getPackageName()); - if (entity != null) { - String md5FromInstalledVGame = ExtensionsKt.getMetaExtra(entity, Constants.APK_MD5); + VGameEntity vGameEntity = VHelper.getVGameSnapshot(apkEntity.getPackageName()); + if (vGameEntity != null) { + String md5FromInstalledVGame = ExtensionsKt.getMetaExtra(vGameEntity.getDownloadEntity(), Constants.APK_MD5); String md5FromRequest = apkEntity.getMd5(); shouldShowUpdate = md5FromRequest != null && !md5FromRequest.equals(md5FromInstalledVGame); + } else { + shouldShowUpdate = false; } } diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index 34d8842c6c..f102aba568 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -88,12 +88,7 @@ public class DownloadManager implements DownloadStatusListener { private final ArrayMap statusMap; private final ArrayMap downloadingMap; - // 下载任务列表快照,非完全实时状态,只保证数量和基础状态,不保证下载进度和速度匹配 - // TODO 使用 mDownloadSnapshotList 来服务 getDownloadEntityByUrl -// private final List mDownloadSnapshotList; - private ArrayList mInvisiblePendingTaskList; // 用户不可见的 pending 任务 - private final DownloadDao mDownloadDao; private final DownloadedGameIdAndPackageNameDao mDownloadedGameIdAndPackageNameDao; @@ -607,18 +602,6 @@ public class DownloadManager implements DownloadStatusListener { return mDownloadDao.getSnapshotByPackageName(packageName); } - /** - * 根据 url 获取下载任务快照 (仅保证下载状态一致) - * - * @param gameId 游戏名 (若使用场景里有多包名,请使用 url 获取下载任务) - * @return null 表示下载列表中不存在该任务,否则返回下载任务 - */ - @Nullable - public DownloadEntity getDownloadEntitySnapshotByGameId(String gameId) { - if (TextUtils.isEmpty(gameId)) return null; - return mDownloadDao.getSnapshotByGameId(gameId); - } - /** * 根据包名获取某一个下载任务 (涉及数据库查询,请优先在子线程调用) * diff --git a/app/src/main/java/com/gh/download/PackageObserver.kt b/app/src/main/java/com/gh/download/PackageObserver.kt index ab51b38e2c..2c3cd125dc 100644 --- a/app/src/main/java/com/gh/download/PackageObserver.kt +++ b/app/src/main/java/com/gh/download/PackageObserver.kt @@ -12,7 +12,7 @@ import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.loghub.LoghubUtils import com.gh.gamecenter.common.retrofit.EmptyResponse import com.gh.gamecenter.common.retrofit.Response -import com.gh.gamecenter.common.utils.getMetaExtra +import com.gh.gamecenter.common.utils.isVGame import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.core.utils.ThirdPartyPackageHelper import com.gh.gamecenter.core.utils.UrlFilterUtils @@ -99,12 +99,12 @@ object PackageObserver { if (gh_id == null) { ThirdPartyPackageHelper.saveGameId(mDownloadEntity.packageName, mDownloadEntity.gameId) } - if (mDownloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) == Constants.SMOOTH_GAME) { + if (mDownloadEntity.isVGame()) { // 畅玩游戏安装完成的同时直接删除文件 runOnIoThread { FileUtils.deleteFile(mDownloadEntity.path) } - } else { - DownloadManager.getInstance().cancel(mDownloadEntity.url, false, true, false) } + + DownloadManager.getInstance().cancel(mDownloadEntity.url, false, true, false) } if (sp.getBoolean(CONCERN_GAME_SP_KEY, true)) { //设置页面控制是否安装后自动关注 // 安装后关注游戏 diff --git a/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragment.java b/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragment.java index f95e7e0fdd..6d303ed94b 100644 --- a/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragment.java +++ b/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragment.java @@ -172,7 +172,7 @@ public class GameDownloadFragment extends BaseFragment implements View.OnClickLi // 静默更新任务,下载模拟器任务,畅玩游戏不需要添加 if (ExtensionsKt.isSilentUpdate(downloadEntity) || ExtensionsKt.isSimulatorDownload(downloadEntity) - || ExtensionsKt.isSmoothGame(downloadEntity)) { + || ExtensionsKt.isVGame(downloadEntity)) { return; } diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index ae54cab3f0..b361daa700 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -30,6 +30,7 @@ import com.gh.vspace.VGameItemData import com.gh.vspace.VHelper import com.halo.assistant.HaloApp import com.halo.assistant.fragment.SettingsFragment +import com.lightgame.download.DownloadEntity import com.lightgame.utils.Utils import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers @@ -125,29 +126,47 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { * 完成下载且已启动过的游戏:按照游戏的畅玩时长从左(长)向右(短)排列 */ private fun getSortedVEntityList() : List { - val rawEntityList = DownloadManager.getInstance().allVDownloadTaskSnapshots + val rawDownloadEntityList = DownloadManager.getInstance().allVDownloadTaskSnapshots + val rawInstalledEntityList = VHelper.getAllVGameSnapshots() + val rawEntityList = arrayListOf() + var fixedTopEntity: VGameItemData? = null val unplayedEntityList = arrayListOf() val playedEntityList = arrayListOf() val sortedEntityList = arrayListOf() + val distinctIdSet = hashSetOf() + // 将下载任务的实体放进待排序列表里 + for (rawDownloadEntity in rawDownloadEntityList) { + distinctIdSet.add(rawDownloadEntity.gameId) + rawEntityList.add(rawDownloadEntity) + } + // 将已安装任务的实体放进待排序列表里 + for (rawInstalledEntity in rawInstalledEntityList) { + if (distinctIdSet.contains(rawInstalledEntity.downloadEntity.gameId)) { + continue + } + rawEntityList.add(rawInstalledEntity.downloadEntity) + } + distinctIdSet.clear() + for (rawEntity in rawEntityList) { val lastPlayedTime = VHelper.getLastPlayedTime(rawEntity) val latestModifiedTime = maxOf(rawEntity.start, VHelper.getLastPlayedTime(rawEntity)) if (fixedTopEntity == null) { - fixedTopEntity = VGameItemData.fromDownloadEntity(rawEntity) + fixedTopEntity = VGameItemData.from(rawEntity) } else { val fixedTopLatestModifiedTime = maxOf(fixedTopEntity.downloadEntity.start, VHelper.getLastPlayedTime(fixedTopEntity.downloadEntity)) if (latestModifiedTime > fixedTopLatestModifiedTime) { - fixedTopEntity = VGameItemData.fromDownloadEntity(rawEntity) + fixedTopEntity = VGameItemData.from(rawEntity) } } if (lastPlayedTime == 0L) { - unplayedEntityList.add(VGameItemData.fromDownloadEntity(rawEntity)) + unplayedEntityList.add(VGameItemData.from(rawEntity)) } else { - playedEntityList.add(VGameItemData.fromDownloadEntity(rawEntity)) + playedEntityList.add(VGameItemData.from(rawEntity)) } } diff --git a/app/src/main/java/com/gh/vspace/VBackupHelper.kt b/app/src/main/java/com/gh/vspace/VBackupHelper.kt index 65449fbbab..a4cade8519 100644 --- a/app/src/main/java/com/gh/vspace/VBackupHelper.kt +++ b/app/src/main/java/com/gh/vspace/VBackupHelper.kt @@ -3,9 +3,9 @@ package com.gh.vspace import android.content.Context import android.os.Environment import com.gh.download.DownloadManager -import com.gh.gamecenter.common.utils.isSmoothGame +import com.gh.gamecenter.common.utils.isVGame import com.gh.gamecenter.core.runOnIoThread -import com.lightgame.download.DBHelper +import com.gh.vspace.db.VGameDatabase import com.lightgame.download.DownloadStatus import com.lightgame.utils.Utils import java.io.File @@ -22,7 +22,7 @@ object VBackupHelper { val entityList = DownloadManager.getInstance().allDownloadEntity for (entity in entityList) { - if (!entity.isSmoothGame() || entity.status != DownloadStatus.done) { + if (!entity.isVGame() || entity.status != DownloadStatus.done) { DownloadManager.getInstance().cancel(entity.url) } } @@ -33,8 +33,8 @@ object VBackupHelper { try { val rootDir: File = Environment.getExternalStorageDirectory() if (rootDir.canWrite()) { - val appDB: File = context.getDatabasePath(DBHelper.DB_NAME) - val backupDBPath = String.format("/gh-files/%s.bak", DBHelper.DB_NAME) + val appDB: File = context.getDatabasePath(VGameDatabase.DATABASE) + val backupDBPath = String.format("/gh-files/%s.bak", VGameDatabase.DATABASE) val externalDB = File(rootDir, backupDBPath) val src: FileChannel = FileInputStream(externalDB).channel val dst: FileChannel = FileOutputStream(appDB).channel @@ -58,8 +58,8 @@ object VBackupHelper { try { val rootDir: File = Environment.getExternalStorageDirectory() if (rootDir.canWrite()) { - val appDB: File = context.getDatabasePath(DBHelper.DB_NAME) - val externalDBPath = String.format("/gh-files/%s.bak", DBHelper.DB_NAME) + val appDB: File = context.getDatabasePath(VGameDatabase.DATABASE) + val externalDBPath = String.format("/gh-files/%s.bak", VGameDatabase.DATABASE) val externalDB = File(rootDir, externalDBPath) val src: FileChannel = FileInputStream(appDB).channel val dst: FileChannel = FileOutputStream(externalDB).channel diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index bd09feb554..43ea3fc825 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -271,6 +271,8 @@ class VDownloadManagerAdapter( downloadBtn.goneIf(mCurrentOption != ManageOption.OPTION_MANAGER) val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity) + ?: VHelper.getDownloadEntitySnapshotByPackageName(gameEntity.getUniquePackageName() ?: "") + if (downloadEntity != null) { val status = downloadEntity.status var btnText = context.getText(R.string.downloading) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index 67a509e4ef..965e507913 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -8,7 +8,6 @@ import com.gh.gamecenter.common.utils.toProperReadableSize import com.gh.gamecenter.core.utils.NumberUtils import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.eventbus.EBPackage -import com.lightgame.download.DownloadStatus import io.reactivex.Observable import io.reactivex.Single import org.greenrobot.eventbus.EventBus @@ -30,46 +29,44 @@ class VDownloadManagerViewModel(application: Application) : override fun provideDataSingle(page: Int): Single> { if (type == TYPE_DOWNLOADED) { return Single.create { emitter -> - val vDownloadList = DownloadManager.getInstance().allVDownloadTaskSnapshots - val gameIdSet = hashSetOf() // 游戏 id set,避免下载任务和已安装任务同时出现 + val vGameList = VHelper.getAllVGame() + val gameList = arrayListOf() - val vGameList = arrayListOf() - - for (downloadEntity in vDownloadList) { - if (downloadEntity.status == DownloadStatus.done) { - gameIdSet.add(downloadEntity.gameId) - - val gameEntity = VHelper.toGameEntity(downloadEntity) - if (gameEntity.playedTime != 0L) { - gameEntity.des = "已畅玩${NumberUtils.transSimpleUsageTime(gameEntity.playedTime / 1000)}" - } else { - val occupiedSpace = VHelper.getAppOccupiedSpace(downloadEntity.packageName) - if (occupiedSpace > 0 ) { - gameEntity.des = "已占用 ${occupiedSpace.toProperReadableSize()}" - } - } - - vGameList.add(gameEntity) - } + // 为空直接返回 + if (vGameList.isEmpty()) { + emitter.onSuccess(gameList) + return@create } - emitter.onSuccess(vGameList) + for (vGame in vGameList) { + val gameEntity = VHelper.toGameEntity(vGame.downloadEntity) + if (gameEntity.playedTime != 0L) { + gameEntity.des = + "已畅玩${NumberUtils.transSimpleUsageTime(gameEntity.playedTime / 1000)}" + } else { + val occupiedSpace = + VHelper.getAppOccupiedSpace(vGame.downloadEntity.packageName) + if (occupiedSpace > 0) { + gameEntity.des = "已占用 ${occupiedSpace.toProperReadableSize()}" + } + } + + gameList.add(gameEntity) + } + + emitter.onSuccess(gameList) } } else { return Single.create { emitter -> - val vDownloadList = DownloadManager.getInstance().allVDownloadTaskSnapshots - val gameIdSet = hashSetOf() // 游戏 id set,避免下载任务和已安装任务同时出现 + val downloadList = DownloadManager.getInstance().allVDownloadTaskSnapshots - val vGameList = arrayListOf() + val gameList = arrayListOf() - for (downloadEntity in vDownloadList) { - if (downloadEntity.status != DownloadStatus.done) { - gameIdSet.add(downloadEntity.gameId) - vGameList.add(VHelper.toGameEntity(downloadEntity)) - } + for (downloadEntity in downloadList) { + gameList.add(VHelper.toGameEntity(downloadEntity)) } - emitter.onSuccess(vGameList) + emitter.onSuccess(gameList) } } } diff --git a/app/src/main/java/com/gh/vspace/VGameItemData.kt b/app/src/main/java/com/gh/vspace/VGameItemData.kt index 8d78e6a45b..7de042db50 100644 --- a/app/src/main/java/com/gh/vspace/VGameItemData.kt +++ b/app/src/main/java/com/gh/vspace/VGameItemData.kt @@ -15,7 +15,7 @@ data class VGameItemData( var controlText: String = "继续" ) { companion object { - fun fromDownloadEntity(downloadEntity: DownloadEntity): VGameItemData { + fun from(downloadEntity: DownloadEntity): VGameItemData { return VGameItemData(downloadEntity).apply { if (downloadEntity.status == DownloadStatus.done && VHelper.getLastPlayedTime(downloadEntity) == 0L diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 257d9e0689..499f0813bc 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -6,6 +6,7 @@ import android.content.Context import android.content.Intent import android.text.TextUtils import android.view.View +import androidx.annotation.WorkerThread import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData @@ -38,6 +39,8 @@ import com.gh.gamecenter.eventbus.EBReuse import com.gh.gamecenter.manager.PackagesManager import com.gh.gamecenter.packagehelper.PackageRepository import com.gh.gamecenter.retrofit.RetrofitManager +import com.gh.vspace.db.VGameDatabase +import com.gh.vspace.db.VGameEntity import com.halo.assistant.HaloApp import com.lg.vspace.VirtualAppManager import com.lg.vspace.remote.listener.RemoteConnectListener @@ -49,6 +52,7 @@ import io.reactivex.schedulers.Schedulers import org.greenrobot.eventbus.EventBus import java.io.File import java.util.* +import kotlin.collections.ArrayList object VHelper { @@ -62,11 +66,18 @@ object VHelper { private val mInstallationLiveData by lazy { MutableLiveData() } private var mLastSuccessfullyLaunchedGame: Pair? = null + private val mVGameDao by lazy { + VGameDatabase.buildDatabase(HaloApp.getInstance().application).vGameDao() + } + private var mVGameSnapshotList = arrayListOf() + private var mUpdateEntity: AppEntity? = null // 当前正卡在安装中的 VA 游戏,避免重复调用安装 private val mInstallingVaPathSet by lazy { Collections.synchronizedSet(hashSetOf()) } + val vGameLiveData by lazy { mVGameDao.getAllLiveData() } + private val mPackageObserver by lazy { PackageObserver.PackageChangeListener { val vaConfig = Config.getVSettingEntity()?.va ?: return@PackageChangeListener @@ -99,6 +110,10 @@ object VHelper { checkVSpaceUpdate(config.arch64!!) } PackageObserver.registerPackageChangeChangeListener(mPackageObserver) + + vGameLiveData.observeForever { + mVGameSnapshotList = ArrayList(it) + } } /** @@ -125,12 +140,28 @@ object VHelper { }) } - private fun invokeVSpace() { -// tryWithDefaultCatch { -// val intent = Intent(Intent.ACTION_VIEW, Uri.parse("vsserver://invoke_only")) -// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) -// HaloApp.getInstance().startActivity(intent) -// } + /** + * 获取数据库里所有的畅玩游戏 + * + * (查询数据库,请在工作线程调用) + */ + @WorkerThread + fun getAllVGame(): List { + return mVGameDao.getAll() + } + + fun getAllVGameSnapshots(): ArrayList { + return ArrayList(mVGameSnapshotList) + } + + /** + * 获取内存里的畅玩游戏快照 + * + * @param packageName 需要获取的畅玩游戏的包名 + */ + @JvmStatic + fun getVGameSnapshot(packageName: String): VGameEntity? { + return mVGameSnapshotList.find { it.packageName == packageName } } private fun updateInstalledList() { @@ -170,19 +201,18 @@ object VHelper { * 启动成功,五秒内退出才显示反馈弹框 */ fun showFeedbackDialogIfLastSuccessfulLaunchedGameExitUnexpectedly(activity: AppCompatActivity) { - val timeOfLastSuccessfullyLaunchedGame = mLastSuccessfullyLaunchedGame?.first - val gameIdOfLastSuccessfullyLaunchedGame = mLastSuccessfullyLaunchedGame?.second + val time = mLastSuccessfullyLaunchedGame?.first + val packageName = mLastSuccessfullyLaunchedGame?.second if (activity !is SplashScreenActivity) { - if (timeOfLastSuccessfullyLaunchedGame != null - && gameIdOfLastSuccessfullyLaunchedGame != null - && System.currentTimeMillis() - timeOfLastSuccessfullyLaunchedGame < 5000 - && !VFeedbackSuppressedSimpleDao().contains(gameIdOfLastSuccessfullyLaunchedGame) + if (time != null + && packageName != null + && System.currentTimeMillis() - time < 5000 + && !VFeedbackSuppressedSimpleDao().contains(packageName) ) { - DownloadManager.getInstance() - .getDownloadEntitySnapshotByGameId(gameIdOfLastSuccessfullyLaunchedGame)?.let { - VFeedbackDialogFragment.show(activity, toGameEntity(it)) - mLastSuccessfullyLaunchedGame = null - } + getVGameSnapshot(packageName)?.let { + VFeedbackDialogFragment.show(activity, toGameEntity(it.downloadEntity)) + mLastSuccessfullyLaunchedGame = null + } } } } @@ -365,13 +395,15 @@ object VHelper { } // 安装过程会比较漫长,所以得放在工作线程运行 - AppExecutor.ioExecutor.execute { + runOnIoThread { try { mInstallingVaPathSet.add(downloadEntity.path) val result = VirtualAppManager.get().installGame(downloadEntity.path) + if (result.status == 0) { updateInstalledList() + mVGameDao.insert(VGameEntity.from(downloadEntity)) PackageObserver.onPackageChanged( EBPackage( "安装", @@ -421,7 +453,10 @@ object VHelper { return@checkStoragePermissionBeforeAction } - val downloadEntity = getDownloadEntitySnapshotByPackageName(packageName) + // 检查下载管理是否有下载实体,有实体表明未安装成功 + val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName) + ?: getDownloadEntitySnapshotByPackageName(packageName) + if (downloadEntity != null) { if (File(downloadEntity.path).exists()) { install(context, downloadEntity, true) @@ -448,10 +483,7 @@ object VHelper { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(intent) - DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName) - ?.let { - mLastSuccessfullyLaunchedGame = Pair(System.currentTimeMillis(), it.gameId) - } + mLastSuccessfullyLaunchedGame = Pair(System.currentTimeMillis(), packageName) updateLastPlayedTime(packageName) } catch (e: Exception) { @@ -465,6 +497,12 @@ object VHelper { fun uninstall(packageName: String?) { Utils.log(LOG_TAG, "卸载游戏 $packageName") + if (packageName.isNullOrBlank()) return + + runOnIoThread { + mVGameDao.delete(packageName) + } + val uninstallClosure: () -> Unit = { try { val result = VirtualAppManager.get().uninstallGame(packageName) @@ -510,8 +548,9 @@ object VHelper { /** * 根据包名获取下载快照 */ + @JvmStatic fun getDownloadEntitySnapshotByPackageName(packageName: String): DownloadEntity? { - return DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName) + return getVGameSnapshot(packageName)?.downloadEntity } /** @@ -519,10 +558,13 @@ object VHelper { */ private fun updateLastPlayedTime(packageName: String) { runOnIoThread { - val entity = - DownloadManager.getInstance().allVDownloadTaskSnapshots.find { it.packageName == packageName } - entity?.addMetaExtra(KEY_LAST_PLAYED_TIME, System.currentTimeMillis().toString()) - DownloadManager.getInstance().updateDownloadEntity(entity) + getVGameSnapshot(packageName)?.let { + it.downloadEntity.addMetaExtra( + KEY_LAST_PLAYED_TIME, + System.currentTimeMillis().toString() + ) + mVGameDao.insert(it) + } // 更新首页排序 EventBus.getDefault().post(EBReuse("vgame")) @@ -584,11 +626,13 @@ object VHelper { */ @JvmStatic fun updateOrReDownload(gameEntity: GameEntity) { - PackagesManager.getUpdateList().firstOrNull { it.id == gameEntity.id }?.let { updateEntity -> - getDownloadEntitySnapshotByPackageName(gameEntity.getUniquePackageName() ?: "")?.let { downloadEntity -> - updateOrReDownload(downloadEntity, updateEntity) + PackagesManager.getUpdateList().firstOrNull { it.id == gameEntity.id } + ?.let { updateEntity -> + getVGameSnapshot(updateEntity.packageName) + ?.let { vGame -> + updateOrReDownload(vGame.downloadEntity, updateEntity) + } } - } } /** @@ -603,8 +647,6 @@ object VHelper { ) { Utils.log(LOG_TAG, "更新应用${originDownloadEntity.packageName}") - DownloadManager.getInstance().cancel(originDownloadEntity.url, false, false, true) - if (updateEntity != null) { originDownloadEntity.url = updateEntity.url originDownloadEntity.name = updateEntity.name @@ -630,7 +672,8 @@ object VHelper { originDownloadEntity.percent = 0.0 // 确定下载类型 - val downloadType = if (updateEntity == null) ExposureUtils.DownloadType.FUN_DOWNLOAD else ExposureUtils.DownloadType.FUN_UPDATE + val downloadType = + if (updateEntity == null) ExposureUtils.DownloadType.FUN_DOWNLOAD else ExposureUtils.DownloadType.FUN_UPDATE val gameEntity = GameEntity(originDownloadEntity.gameId, originDownloadEntity.name) gameEntity.gameVersion = originDownloadEntity.versionName ?: "" @@ -704,7 +747,7 @@ object VHelper { val rawInstalledPackageList = getInstalledPackageList() val validInstalledPackageList = arrayListOf() for (packageName in rawInstalledPackageList) { - if (getDownloadEntitySnapshotByPackageName(packageName) != null) { + if (getVGameSnapshot(packageName) != null) { validInstalledPackageList.add(packageName) } } diff --git a/app/src/main/java/com/gh/vspace/db/VGameConverter.kt b/app/src/main/java/com/gh/vspace/db/VGameConverter.kt new file mode 100644 index 0000000000..25c1608785 --- /dev/null +++ b/app/src/main/java/com/gh/vspace/db/VGameConverter.kt @@ -0,0 +1,19 @@ +package com.gh.vspace.db + +import androidx.room.TypeConverter +import com.gh.gamecenter.core.utils.GsonUtils +import com.lightgame.download.DownloadEntity + +class VGameConverter { + + @TypeConverter + fun convertDownload2String(any: DownloadEntity): String { + return GsonUtils.toJson(any) + } + + @TypeConverter + fun convertString2DownloadEntity(string: String): DownloadEntity { + return GsonUtils.fromJson(string, DownloadEntity::class.java) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/db/VGameDao.kt b/app/src/main/java/com/gh/vspace/db/VGameDao.kt new file mode 100644 index 0000000000..fb79e7cbbc --- /dev/null +++ b/app/src/main/java/com/gh/vspace/db/VGameDao.kt @@ -0,0 +1,27 @@ +package com.gh.vspace.db + +import androidx.lifecycle.LiveData +import androidx.room.* + +@Dao +interface VGameDao { + + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun insert(game: VGameEntity) + + @Query("SELECT * FROM v_game") + fun getAll(): List + + @Query("SELECT * FROM v_game") + fun getAllLiveData(): LiveData> + + @Delete + fun delete(gameList: List) + + @Delete + fun delete(game: VGameEntity) + + @Query("DELETE FROM v_game WHERE packageName = :packageName") + fun delete(packageName: String) + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/db/VGameDatabase.kt b/app/src/main/java/com/gh/vspace/db/VGameDatabase.kt new file mode 100644 index 0000000000..105fb4564f --- /dev/null +++ b/app/src/main/java/com/gh/vspace/db/VGameDatabase.kt @@ -0,0 +1,25 @@ +package com.gh.vspace.db + +import android.content.Context +import androidx.room.Database +import androidx.room.Room +import androidx.room.RoomDatabase +import androidx.room.TypeConverters + +@TypeConverters(VGameConverter::class) +@Database(entities = [VGameEntity::class], version = 1, exportSchema = false) +abstract class VGameDatabase : RoomDatabase() { + + abstract fun vGameDao(): VGameDao + + companion object { + const val DATABASE = "v_game_database" + + fun buildDatabase(context: Context): VGameDatabase { + return Room.databaseBuilder(context, VGameDatabase::class.java, DATABASE) + .fallbackToDestructiveMigration() + .build() + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/db/VGameEntity.kt b/app/src/main/java/com/gh/vspace/db/VGameEntity.kt new file mode 100644 index 0000000000..f7b067b01d --- /dev/null +++ b/app/src/main/java/com/gh/vspace/db/VGameEntity.kt @@ -0,0 +1,21 @@ +package com.gh.vspace.db + +import android.os.Parcelable +import androidx.room.Entity +import androidx.room.PrimaryKey +import com.lightgame.download.DownloadEntity +import kotlinx.parcelize.Parcelize + +@Parcelize +@Entity(tableName = "v_game") +data class VGameEntity( + @PrimaryKey + var packageName: String, + var downloadEntity: DownloadEntity, +) : Parcelable { + companion object { + fun from(downloadEntity: DownloadEntity): VGameEntity { + return VGameEntity(downloadEntity.packageName, downloadEntity) + } + } +} \ No newline at end of file diff --git a/libraries/LGLibrary b/libraries/LGLibrary index aa56298ed0..2fb219f6c0 160000 --- a/libraries/LGLibrary +++ b/libraries/LGLibrary @@ -1 +1 @@ -Subproject commit aa56298ed01b07adbad83fcc4d5175f3b3ac59f7 +Subproject commit 2fb219f6c06a14cb78341c14f5b8c847484df6cf diff --git a/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt b/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt index 62bbeae0b7..037ca77214 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt @@ -973,7 +973,7 @@ fun DownloadEntity.isSimulatorGame(): Boolean { return getMetaExtra(Constants.SIMULATOR_GAME).isNotEmpty() } -fun DownloadEntity.isSmoothGame(): Boolean { +fun DownloadEntity.isVGame(): Boolean { return Constants.SMOOTH_GAME == getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) } From 877490ce01a54a273e148a83996f9ee8daeca8e4 Mon Sep 17 00:00:00 2001 From: juntao Date: Wed, 6 Jul 2022 16:57:55 +0800 Subject: [PATCH 067/217] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E6=B8=B8=E6=88=8F=E7=AE=A1=E7=90=86=E7=9A=84=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E6=95=B0=E6=8D=AE=E6=98=BE=E7=A4=BA=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/download/DownloadManager.java | 2 +- .../com/gh/vspace/VDownloadManagerFragment.kt | 12 +++++++++--- .../com/gh/vspace/VDownloadManagerViewModel.kt | 17 +++++++++++++++-- app/src/main/java/com/gh/vspace/VHelper.kt | 3 ++- 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index f102aba568..1c0382c86e 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -691,7 +691,7 @@ public class DownloadManager implements DownloadStatusListener { } /** - * 获取下载列表中的畅玩下载任务 + * 获取下载列表中的畅玩下载任务快照 */ public ArrayList getAllVDownloadTaskSnapshots() { List downloadList = getAllDownloadEntitySnapshots(); diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index 31f8db9a11..c178fbc2e8 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -39,7 +39,7 @@ class VDownloadManagerFragment : override fun onDataChanged(downloadEntity: DownloadEntity) { mAdapter.notifyItemByDownload(downloadEntity) - if (downloadEntity.status == DownloadStatus.done) { + if (downloadEntity.status == DownloadStatus.done && mViewModel.isTypeDownloaded()) { onLoadRefresh() } } @@ -57,7 +57,8 @@ class VDownloadManagerFragment : override fun onCreate(savedInstanceState: Bundle?) { mViewModel.type = arguments?.get(VDownloadManagerViewModel.TYPE) as String - mViewModel.isFromHomeRecent = arguments?.getBoolean(EntranceConsts.KEY_IS_FROM_HOME_RECENT) ?: false + mViewModel.isFromHomeRecent = + arguments?.getBoolean(EntranceConsts.KEY_IS_FROM_HOME_RECENT) ?: false super.onCreate(savedInstanceState) } @@ -87,7 +88,8 @@ class VDownloadManagerFragment : switchIv.setOnClickListener { if (lottieView.isAnimating) return@setOnClickListener val status = switchIv.isChecked - val anime = if (status) "lottie/switch_turnoff.json" else "lottie/switch_turnon.json" + val anime = + if (status) "lottie/switch_turnoff.json" else "lottie/switch_turnon.json" lottieView.setAnimation(anime) lottieView.doOnAnimationEnd { switchIv.isChecked = !status @@ -102,6 +104,10 @@ class VDownloadManagerFragment : if (mViewModel.isTypeDownloaded()) { mListRv.addOnScrollListener(mExposureListener) + } else { + VHelper.vGameLiveData.observe(viewLifecycleOwner) { + onLoadRefresh() + } } } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index 965e507913..fded53593c 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -8,6 +8,7 @@ import com.gh.gamecenter.common.utils.toProperReadableSize import com.gh.gamecenter.core.utils.NumberUtils import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.eventbus.EBPackage +import com.lightgame.download.DownloadStatus import io.reactivex.Observable import io.reactivex.Single import org.greenrobot.eventbus.EventBus @@ -39,6 +40,13 @@ class VDownloadManagerViewModel(application: Application) : } for (vGame in vGameList) { + // 过滤部分不需要的 + if (DownloadManager.getInstance().allVDownloadTaskSnapshots.any { + it.gameId == vGame.downloadEntity.gameId && it.status != DownloadStatus.done + }) { + continue + } + val gameEntity = VHelper.toGameEntity(vGame.downloadEntity) if (gameEntity.playedTime != 0L) { gameEntity.des = @@ -63,6 +71,10 @@ class VDownloadManagerViewModel(application: Application) : val gameList = arrayListOf() for (downloadEntity in downloadList) { + // 过滤下载完成的部分 + if (downloadEntity.status == DownloadStatus.done) { + continue + } gameList.add(VHelper.toGameEntity(downloadEntity)) } @@ -84,7 +96,8 @@ class VDownloadManagerViewModel(application: Application) : fun removeItems(idList: ArrayList) { for (id in idList) { - val apkEntity = mResultLiveData.value?.firstOrNull { id == it.id }?.getApk()?.firstOrNull() + val apkEntity = + mResultLiveData.value?.firstOrNull { id == it.id }?.getApk()?.firstOrNull() DownloadManager.getInstance().pause(apkEntity?.url) DownloadManager.getInstance().cancel(apkEntity?.url) @@ -96,7 +109,7 @@ class VDownloadManagerViewModel(application: Application) : } } - fun isTypeDownloaded() : Boolean { + fun isTypeDownloaded(): Boolean { return type == TYPE_DOWNLOADED } diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 499f0813bc..07ad40ca8b 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -401,9 +401,10 @@ object VHelper { val result = VirtualAppManager.get().installGame(downloadEntity.path) + mVGameDao.insert(VGameEntity.from(downloadEntity)) + if (result.status == 0) { updateInstalledList() - mVGameDao.insert(VGameEntity.from(downloadEntity)) PackageObserver.onPackageChanged( EBPackage( "安装", From 66d0dba9c619bbcf8ec3e5aec12400e6a068e812 Mon Sep 17 00:00:00 2001 From: juntao Date: Wed, 6 Jul 2022 17:44:31 +0800 Subject: [PATCH 068/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E9=A1=B5=E5=BA=95=E6=A0=8F=E9=AB=98=E5=BA=A6=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/detail_download_item.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/res/layout/detail_download_item.xml b/app/src/main/res/layout/detail_download_item.xml index 6109b9811e..6289b52417 100644 --- a/app/src/main/res/layout/detail_download_item.xml +++ b/app/src/main/res/layout/detail_download_item.xml @@ -136,7 +136,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/background_white" - android:paddingTop="10dp" android:paddingEnd="20dp" android:paddingBottom="10dp"> From 59e913c5299da945ae31b0758c96c956a3ebec03 Mon Sep 17 00:00:00 2001 From: lyr Date: Thu, 7 Jul 2022 10:26:29 +0800 Subject: [PATCH 069/217] =?UTF-8?q?feat:=E5=A2=9E=E5=8A=A0=E5=B9=B3?= =?UTF-8?q?=E9=93=BA=E5=9F=8B=E7=82=B9=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 040de6d4581cf8cdea2877868b1035f128e1231f) --- .../java/com/gh/common/util/LogUtils.java | 29 ++++++++++++++++ .../com/gh/common/util/NewFlatLogUtils.kt | 28 +++++++++++++++ .../java/com/gh/common/util/NewLogUtils.kt | 1 + .../gamecenter/common/loghub/LoghubEvent.kt | 13 ++++--- .../gamecenter/common/loghub/LoghubUtils.kt | 34 +++++++++++++++---- 5 files changed, 94 insertions(+), 11 deletions(-) create mode 100644 app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt diff --git a/app/src/main/java/com/gh/common/util/LogUtils.java b/app/src/main/java/com/gh/common/util/LogUtils.java index c71a5c614b..97c380cfca 100644 --- a/app/src/main/java/com/gh/common/util/LogUtils.java +++ b/app/src/main/java/com/gh/common/util/LogUtils.java @@ -486,6 +486,10 @@ public class LogUtils { LoghubUtils.log(GsonUtils.toJsonIgnoreNull(entity), "event", false); } + /** + * 因存在部分驼峰命名的字段(appVersion和userId),需要全部转换为下划线风格,请使用新方法{@link #getNewMetaObject} + */ + @Deprecated public static JSONObject getMetaObject() { Meta meta = MetaUtil.INSTANCE.getMeta(); JSONObject metaObject = new JSONObject(); @@ -511,6 +515,31 @@ public class LogUtils { return metaObject; } + public static JSONObject getNewMetaObject() { + Meta meta = MetaUtil.INSTANCE.getMeta(); + JSONObject metaObject = new JSONObject(); + try { + metaObject.put("dia", MetaUtil.getBase64EncodedAndroidId()); + metaObject.put("android_sdk", meta.getAndroid_sdk()); + metaObject.put("android_version", meta.getAndroid_version()); + metaObject.put("app_version", meta.getAppVersion()); + metaObject.put("channel", meta.getChannel()); + metaObject.put("gid", meta.getGid()); + metaObject.put("jnfj", MetaUtil.getBase64EncodedIMEI()); + metaObject.put("mac", meta.getMac()); + metaObject.put("manufacturer", meta.getManufacturer()); + metaObject.put("model", meta.getModel()); + metaObject.put("network", meta.getNetwork()); + metaObject.put("os", meta.getOs()); + metaObject.put("user_id", meta.getUserId()); + metaObject.put("oaid", HaloApp.getInstance().getOAID()); + + } catch (JSONException e) { + e.printStackTrace(); + } + return metaObject; + } + private static void uploadCommunity(JSONObject object) { try { object.put("meta", getMetaObject()); diff --git a/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt b/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt new file mode 100644 index 0000000000..bc1c3494dd --- /dev/null +++ b/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt @@ -0,0 +1,28 @@ +package com.gh.common.util + +import com.gh.gamecenter.common.json.JsonObjectBuilder +import com.gh.gamecenter.common.loghub.LoghubUtils +import com.lightgame.utils.Utils +import org.json.JSONObject + +/** + * 新平铺埋点工具类 + * 因为新的埋点都要平铺字段,所以新建此类,新埋点在此类添加即可 + */ +object NewFlatLogUtils { + + private fun log(jsonObject: JSONObject, logStore: String, uploadImmediately: Boolean) { + Utils.log("NewFlatLogUtils", jsonObject.toString(4)) + LoghubUtils.log(jsonObject, logStore, uploadImmediately, true) + } + + private fun parseAndPutMeta(): JsonObjectBuilder.() -> Unit = { + val meta = LogUtils.getNewMetaObject() + val metaKeys = meta.keys() + while (metaKeys.hasNext()) { + val key: String = metaKeys.next().toString() + val value = meta.getString(key) + key to value + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/common/util/NewLogUtils.kt b/app/src/main/java/com/gh/common/util/NewLogUtils.kt index f296679267..da1aeb639d 100644 --- a/app/src/main/java/com/gh/common/util/NewLogUtils.kt +++ b/app/src/main/java/com/gh/common/util/NewLogUtils.kt @@ -15,6 +15,7 @@ import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody import org.json.JSONObject +@Deprecated("新埋点请添加至 NewFlatLogUtils") object NewLogUtils { private fun log(jsonObject: JSONObject, logStore: String, uploadImmediately: Boolean) { diff --git a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubEvent.kt b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubEvent.kt index 8c2a057985..11d49f6164 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubEvent.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubEvent.kt @@ -10,8 +10,11 @@ import java.util.* @Keep @Parcelize @Entity(tableName = "loghubEvent") -data class LoghubEvent(@PrimaryKey - val id: String = UUID.randomUUID().toString(), - var time: String, - var content: String, - var logStore: String) : Parcelable \ No newline at end of file +data class LoghubEvent( + @PrimaryKey + val id: String = UUID.randomUUID().toString(), + var time: String, + var content: String, + var logStore: String, + var isFlat: Boolean // 是否平铺数据字段 +) : Parcelable \ No newline at end of file diff --git a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubUtils.kt b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubUtils.kt index a86331aafd..bba448ea39 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubUtils.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubUtils.kt @@ -32,10 +32,16 @@ object LoghubUtils { } @JvmStatic - fun log(logJson: JSONObject, logStore: String, forcedUpload: Boolean) { + @JvmOverloads + fun log(logJson: JSONObject, logStore: String, forcedUpload: Boolean, isFlat: Boolean = false) { loghubEventExecutor?.execute { try { - val event = LoghubEvent(time = (System.currentTimeMillis() / 1000L).toString(), content = logJson.toString(), logStore = logStore) + val event = LoghubEvent( + time = (System.currentTimeMillis() / 1000L).toString(), + content = logJson.toString(), + logStore = logStore, + isFlat = isFlat + ) loghubEventSet.add(event) loghubEventDao.insert(event) } catch (e: Exception) { @@ -49,10 +55,16 @@ object LoghubUtils { } @JvmStatic - fun log(jsonString: String, logStore: String, forcedUpload: Boolean) { + @JvmOverloads + fun log(jsonString: String, logStore: String, forcedUpload: Boolean, isFlat: Boolean = false) { loghubEventExecutor?.execute { try { - val event = LoghubEvent(time = (System.currentTimeMillis() / 1000L).toString(), content = jsonString, logStore = logStore) + val event = LoghubEvent( + time = (System.currentTimeMillis() / 1000L).toString(), + content = jsonString, + logStore = logStore, + isFlat = isFlat + ) loghubEventSet.add(event) loghubEventDao.insert(event) } catch (e: Exception) { @@ -91,8 +103,18 @@ object LoghubUtils { log.putContent(key, contentJson.get(key).toString()) } } else { - log.putContent("current time ", event.time) - log.putContent("content", event.content) + // isFlat为true代表仍需要平铺数据 + if (event.isFlat) { + val contentJson = JSONObject(event.content) + for (key in contentJson.keys()) { + log.putContent(key, contentJson.get(key).toString()) + } + // 新数据使用timestamp字段记录时间 + log.putContent("timestamp", event.time) + } else { + log.putContent("current time", event.time) + log.putContent("content", event.content) + } } LoghubHelper.uploadLog(log, event.logStore) From ad4ca04db3d947a32a362a7807a683108477603a Mon Sep 17 00:00:00 2001 From: lyr Date: Thu, 7 Jul 2022 10:26:29 +0800 Subject: [PATCH 070/217] =?UTF-8?q?feat:=E5=A2=9E=E5=8A=A0=E5=B9=B3?= =?UTF-8?q?=E9=93=BA=E5=9F=8B=E7=82=B9=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 040de6d4581cf8cdea2877868b1035f128e1231f) --- .../java/com/gh/common/util/LogUtils.java | 29 ++++++++++++++++ .../com/gh/common/util/NewFlatLogUtils.kt | 28 +++++++++++++++ .../java/com/gh/common/util/NewLogUtils.kt | 1 + .../gamecenter/common/loghub/LoghubEvent.kt | 13 ++++--- .../gamecenter/common/loghub/LoghubUtils.kt | 34 +++++++++++++++---- 5 files changed, 94 insertions(+), 11 deletions(-) create mode 100644 app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt diff --git a/app/src/main/java/com/gh/common/util/LogUtils.java b/app/src/main/java/com/gh/common/util/LogUtils.java index c71a5c614b..97c380cfca 100644 --- a/app/src/main/java/com/gh/common/util/LogUtils.java +++ b/app/src/main/java/com/gh/common/util/LogUtils.java @@ -486,6 +486,10 @@ public class LogUtils { LoghubUtils.log(GsonUtils.toJsonIgnoreNull(entity), "event", false); } + /** + * 因存在部分驼峰命名的字段(appVersion和userId),需要全部转换为下划线风格,请使用新方法{@link #getNewMetaObject} + */ + @Deprecated public static JSONObject getMetaObject() { Meta meta = MetaUtil.INSTANCE.getMeta(); JSONObject metaObject = new JSONObject(); @@ -511,6 +515,31 @@ public class LogUtils { return metaObject; } + public static JSONObject getNewMetaObject() { + Meta meta = MetaUtil.INSTANCE.getMeta(); + JSONObject metaObject = new JSONObject(); + try { + metaObject.put("dia", MetaUtil.getBase64EncodedAndroidId()); + metaObject.put("android_sdk", meta.getAndroid_sdk()); + metaObject.put("android_version", meta.getAndroid_version()); + metaObject.put("app_version", meta.getAppVersion()); + metaObject.put("channel", meta.getChannel()); + metaObject.put("gid", meta.getGid()); + metaObject.put("jnfj", MetaUtil.getBase64EncodedIMEI()); + metaObject.put("mac", meta.getMac()); + metaObject.put("manufacturer", meta.getManufacturer()); + metaObject.put("model", meta.getModel()); + metaObject.put("network", meta.getNetwork()); + metaObject.put("os", meta.getOs()); + metaObject.put("user_id", meta.getUserId()); + metaObject.put("oaid", HaloApp.getInstance().getOAID()); + + } catch (JSONException e) { + e.printStackTrace(); + } + return metaObject; + } + private static void uploadCommunity(JSONObject object) { try { object.put("meta", getMetaObject()); diff --git a/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt b/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt new file mode 100644 index 0000000000..bc1c3494dd --- /dev/null +++ b/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt @@ -0,0 +1,28 @@ +package com.gh.common.util + +import com.gh.gamecenter.common.json.JsonObjectBuilder +import com.gh.gamecenter.common.loghub.LoghubUtils +import com.lightgame.utils.Utils +import org.json.JSONObject + +/** + * 新平铺埋点工具类 + * 因为新的埋点都要平铺字段,所以新建此类,新埋点在此类添加即可 + */ +object NewFlatLogUtils { + + private fun log(jsonObject: JSONObject, logStore: String, uploadImmediately: Boolean) { + Utils.log("NewFlatLogUtils", jsonObject.toString(4)) + LoghubUtils.log(jsonObject, logStore, uploadImmediately, true) + } + + private fun parseAndPutMeta(): JsonObjectBuilder.() -> Unit = { + val meta = LogUtils.getNewMetaObject() + val metaKeys = meta.keys() + while (metaKeys.hasNext()) { + val key: String = metaKeys.next().toString() + val value = meta.getString(key) + key to value + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/common/util/NewLogUtils.kt b/app/src/main/java/com/gh/common/util/NewLogUtils.kt index 13d971f754..db9e98a443 100644 --- a/app/src/main/java/com/gh/common/util/NewLogUtils.kt +++ b/app/src/main/java/com/gh/common/util/NewLogUtils.kt @@ -16,6 +16,7 @@ import okhttp3.ResponseBody import org.json.JSONArray import org.json.JSONObject +@Deprecated("新埋点请添加至 NewFlatLogUtils") object NewLogUtils { private fun log(jsonObject: JSONObject, logStore: String, uploadImmediately: Boolean) { diff --git a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubEvent.kt b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubEvent.kt index 8c2a057985..11d49f6164 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubEvent.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubEvent.kt @@ -10,8 +10,11 @@ import java.util.* @Keep @Parcelize @Entity(tableName = "loghubEvent") -data class LoghubEvent(@PrimaryKey - val id: String = UUID.randomUUID().toString(), - var time: String, - var content: String, - var logStore: String) : Parcelable \ No newline at end of file +data class LoghubEvent( + @PrimaryKey + val id: String = UUID.randomUUID().toString(), + var time: String, + var content: String, + var logStore: String, + var isFlat: Boolean // 是否平铺数据字段 +) : Parcelable \ No newline at end of file diff --git a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubUtils.kt b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubUtils.kt index a86331aafd..bba448ea39 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubUtils.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubUtils.kt @@ -32,10 +32,16 @@ object LoghubUtils { } @JvmStatic - fun log(logJson: JSONObject, logStore: String, forcedUpload: Boolean) { + @JvmOverloads + fun log(logJson: JSONObject, logStore: String, forcedUpload: Boolean, isFlat: Boolean = false) { loghubEventExecutor?.execute { try { - val event = LoghubEvent(time = (System.currentTimeMillis() / 1000L).toString(), content = logJson.toString(), logStore = logStore) + val event = LoghubEvent( + time = (System.currentTimeMillis() / 1000L).toString(), + content = logJson.toString(), + logStore = logStore, + isFlat = isFlat + ) loghubEventSet.add(event) loghubEventDao.insert(event) } catch (e: Exception) { @@ -49,10 +55,16 @@ object LoghubUtils { } @JvmStatic - fun log(jsonString: String, logStore: String, forcedUpload: Boolean) { + @JvmOverloads + fun log(jsonString: String, logStore: String, forcedUpload: Boolean, isFlat: Boolean = false) { loghubEventExecutor?.execute { try { - val event = LoghubEvent(time = (System.currentTimeMillis() / 1000L).toString(), content = jsonString, logStore = logStore) + val event = LoghubEvent( + time = (System.currentTimeMillis() / 1000L).toString(), + content = jsonString, + logStore = logStore, + isFlat = isFlat + ) loghubEventSet.add(event) loghubEventDao.insert(event) } catch (e: Exception) { @@ -91,8 +103,18 @@ object LoghubUtils { log.putContent(key, contentJson.get(key).toString()) } } else { - log.putContent("current time ", event.time) - log.putContent("content", event.content) + // isFlat为true代表仍需要平铺数据 + if (event.isFlat) { + val contentJson = JSONObject(event.content) + for (key in contentJson.keys()) { + log.putContent(key, contentJson.get(key).toString()) + } + // 新数据使用timestamp字段记录时间 + log.putContent("timestamp", event.time) + } else { + log.putContent("current time", event.time) + log.putContent("content", event.content) + } } LoghubHelper.uploadLog(log, event.logStore) From d2b2f5e3062a49b636088b02dc400342662d0435 Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 7 Jul 2022 11:18:57 +0800 Subject: [PATCH 071/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E7=AE=A1=E7=90=86=E4=B8=8B=E8=BD=BD=E9=A1=B5=E8=BF=9B?= =?UTF-8?q?=E5=85=A5=E6=97=B6=E5=A4=9A=E6=AC=A1=E5=88=B7=E6=96=B0=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index c178fbc2e8..f3a7c42ae0 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -119,4 +119,5 @@ class VDownloadManagerFragment : override fun shouldLoadMore() = false + override fun isAutomaticLoad(): Boolean = mViewModel.isTypeDownloaded() } \ No newline at end of file From 14e2784ab843e6693a56c7c8994020868f731707 Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 7 Jul 2022 11:19:22 +0800 Subject: [PATCH 072/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E5=AE=89=E8=A3=85=E5=BC=82=E5=B8=B8=E6=97=B6=E6=97=A0?= =?UTF-8?q?=E4=BB=BB=E4=BD=95=E5=8F=8D=E9=A6=88=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VHelper.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 07ad40ca8b..41db293700 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -52,7 +52,6 @@ import io.reactivex.schedulers.Schedulers import org.greenrobot.eventbus.EventBus import java.io.File import java.util.* -import kotlin.collections.ArrayList object VHelper { @@ -412,6 +411,10 @@ object VHelper { "unknown" ) ) + } else { + runOnUiThread { + ToastUtils.toast("安装出现异常, ${result.status}") + } } mInstallingVaPathSet.remove(downloadEntity.path) From 32f583825ab18ba857921fc32cc642a056586d6c Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 7 Jul 2022 11:33:51 +0800 Subject: [PATCH 073/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E6=B8=B8=E6=88=8F=E7=AE=A1=E7=90=86=E5=9C=A8=E7=8E=A9?= =?UTF-8?q?=E9=A1=B5=E6=9B=B4=E6=96=B0=E4=B8=8D=E5=8F=8A=E6=97=B6=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/gh/vspace/VDownloadManagerFragment.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index f3a7c42ae0..7d173b0ed3 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -104,10 +104,10 @@ class VDownloadManagerFragment : if (mViewModel.isTypeDownloaded()) { mListRv.addOnScrollListener(mExposureListener) - } else { - VHelper.vGameLiveData.observe(viewLifecycleOwner) { - onLoadRefresh() - } + } + + VHelper.vGameLiveData.observe(viewLifecycleOwner) { + onLoadRefresh() } } From 0b511551779b8d0262f7ce5c5360975f5cc184c9 Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 7 Jul 2022 11:36:49 +0800 Subject: [PATCH 074/217] =?UTF-8?q?fix:=20=E5=B0=9D=E8=AF=95=E6=8F=90?= =?UTF-8?q?=E9=AB=98=E4=B8=8B=E8=BD=BD=E5=9B=9E=E8=B0=83=E5=88=B7=E6=96=B0?= =?UTF-8?q?=E9=A2=91=E7=8E=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libraries/LGLibrary | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/LGLibrary b/libraries/LGLibrary index 2fb219f6c0..8d6d01465b 160000 --- a/libraries/LGLibrary +++ b/libraries/LGLibrary @@ -1 +1 @@ -Subproject commit 2fb219f6c06a14cb78341c14f5b8c847484df6cf +Subproject commit 8d6d01465b2c5ab6a97b453fedaef7c8c9129f6f From 2747857db3de84c7d96cc884b1fc42423d03b9e6 Mon Sep 17 00:00:00 2001 From: lyr Date: Thu, 7 Jul 2022 14:09:20 +0800 Subject: [PATCH 075/217] =?UTF-8?q?feat:=E5=8D=87=E7=BA=A7Loghub=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 78d5d4b39fce3b5eb698128971178da48ff5390d) --- .../gh/gamecenter/common/loghub/LoghubDatabase.kt | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt index 6974bd69c2..210821d835 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt @@ -4,16 +4,24 @@ import android.content.Context import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase -@Database(entities = [LoghubEvent::class], version = 1, exportSchema = false) +@Database(entities = [LoghubEvent::class], version = 2, exportSchema = false) abstract class LoghubDatabase : RoomDatabase() { companion object { private const val DATABASE = "gh_loghub_database" + private val MIGRATION_1_2: Migration = object : Migration(1, 2) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("Alter TABLE loghubEvent add isFlat INTEGER NOT NULL") + } + } + fun buildDatabase(context: Context): LoghubDatabase { return Room.databaseBuilder(context, LoghubDatabase::class.java, DATABASE) - .fallbackToDestructiveMigration() - .build() + .addMigrations(MIGRATION_1_2) + .build() } } From 6f01610d10904593cecc706778bfe59d8177df95 Mon Sep 17 00:00:00 2001 From: lyr Date: Thu, 7 Jul 2022 14:09:20 +0800 Subject: [PATCH 076/217] =?UTF-8?q?feat:=E5=8D=87=E7=BA=A7Loghub=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 78d5d4b39fce3b5eb698128971178da48ff5390d) --- .../gh/gamecenter/common/loghub/LoghubDatabase.kt | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt index 6974bd69c2..210821d835 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt @@ -4,16 +4,24 @@ import android.content.Context import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase -@Database(entities = [LoghubEvent::class], version = 1, exportSchema = false) +@Database(entities = [LoghubEvent::class], version = 2, exportSchema = false) abstract class LoghubDatabase : RoomDatabase() { companion object { private const val DATABASE = "gh_loghub_database" + private val MIGRATION_1_2: Migration = object : Migration(1, 2) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("Alter TABLE loghubEvent add isFlat INTEGER NOT NULL") + } + } + fun buildDatabase(context: Context): LoghubDatabase { return Room.databaseBuilder(context, LoghubDatabase::class.java, DATABASE) - .fallbackToDestructiveMigration() - .build() + .addMigrations(MIGRATION_1_2) + .build() } } From 36e99a4a7ea4ed1e0d582ea59a00b89587f4ba55 Mon Sep 17 00:00:00 2001 From: lyr Date: Thu, 7 Jul 2022 14:27:59 +0800 Subject: [PATCH 077/217] =?UTF-8?q?fix:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.10.0=E3=80=91=E7=95=85=E7=8E=A9=E5=8A=A9?= =?UTF-8?q?=E6=89=8B=E6=95=B0=E6=8D=AE=E5=9F=8B=E7=82=B9(=E5=9F=8B?= =?UTF-8?q?=E7=82=B9=E5=AD=97=E6=AE=B5=E4=BD=BF=E7=94=A8=E5=B9=B3=E9=93=BA?= =?UTF-8?q?=E6=96=B9=E5=BC=8F=E4=B8=8A=E4=BC=A0)=20https://git.shanqu.cc/p?= =?UTF-8?q?m/halo/halo-app-issues/-/issues/1872#note=5F157925?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/util/NewFlatLogUtils.kt | 95 +++++++++++++++++++ .../java/com/gh/common/util/NewLogUtils.kt | 93 ------------------ .../gamecenter/DownloadManagerActivity.java | 4 +- .../gamedetail/GameDetailFragment.kt | 2 +- .../gh/vspace/HomeRecentVGameViewHolder.kt | 6 +- .../com/gh/vspace/VDownloadManagerAdapter.kt | 8 +- .../com/gh/vspace/VDownloadManagerFragment.kt | 4 +- .../com/gh/vspace/VFeedbackDialogFragment.kt | 6 +- app/src/main/java/com/gh/vspace/VHelper.kt | 10 +- .../gh/vspace/VLoadCompleteWindowHelper.kt | 6 +- .../com/gh/vspace/VSpaceDialogFragment.kt | 8 +- 11 files changed, 122 insertions(+), 120 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt b/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt index bc1c3494dd..ec49bdd34d 100644 --- a/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt +++ b/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt @@ -1,8 +1,10 @@ package com.gh.common.util import com.gh.gamecenter.common.json.JsonObjectBuilder +import com.gh.gamecenter.common.json.json import com.gh.gamecenter.common.loghub.LoghubUtils import com.lightgame.utils.Utils +import org.json.JSONArray import org.json.JSONObject /** @@ -25,4 +27,97 @@ object NewFlatLogUtils { key to value } } + + // 畅玩助手相关事件(下载弹窗展示事件/隐私政策点击事件/下载点击事件/授权弹窗展示事件/更新弹窗展示事件) + // 畅玩管理删除游戏弹窗展示事件/畅玩管理-畅玩广场入口点击事件/退出畅玩助手提示弹窗展示事件 + @JvmStatic + fun logHaloFunEvent(event: String) { + val json = json { + "event" to event + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + // 关联游戏跳转icon点击事件 + @JvmStatic + fun logHaloFunGameDetailJumpClick(downloadStatus: String, gameId: String) { + val json = json { + "event" to "halo_fun_game_detail_jump_click" + "download_state" to downloadStatus + "game_id" to gameId + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + // 下载完成提示条点击事件 + @JvmStatic + fun logHaloFunDownloadCompleteTipClick(buttonType: String, gameId: String) { + val json = json { + "event" to "halo_fun_download_complete_tip_click" + "button_type" to buttonType + "game_id" to gameId + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + // 畅玩助手更新弹窗点击事件 + @JvmStatic + fun logHaloFunUpdateDialogClick(dialogType: String, buttonType: String) { + val json = json { + "event" to "halo_fun_update_dialog_click" + "dialog_type" to dialogType + "button_type" to buttonType + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + // 畅玩管理展示事件 + @JvmStatic + fun logHaloFunManageShow(entrance: String) { + val json = json { + "event" to "halo_fun_manage_show" + "entrance" to entrance + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + // 畅玩管理-最近在玩板块展示管理事件 + @JvmStatic + fun logHaloFunManageRecentGameSwitch(isOn: Boolean) { + val json = json { + "event" to "halo_fun_manage_recent_game_switch" + "is_on" to isOn + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + // 畅玩管理删除游戏弹窗点击事件 + @JvmStatic + fun logHaloFunManageGameDeleteDialogClick(buttonType: String, gamesArray: JSONArray) { + val json = json { + "event" to "halo_fun_manage_game_delete_dialog_click" + "button_type" to buttonType + "games_array" to gamesArray + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + // 退出畅玩助手提示弹窗反馈收集事件 + @JvmStatic + fun logHaloFunGameExitDialogSubmitClick(detail: String, typeTags: JSONArray) { + val json = json { + "event" to "halo_fun_game_exit_dialog_submit_click" + "detail" to detail + "type_tags" to typeTags + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/common/util/NewLogUtils.kt b/app/src/main/java/com/gh/common/util/NewLogUtils.kt index db9e98a443..8356c34eff 100644 --- a/app/src/main/java/com/gh/common/util/NewLogUtils.kt +++ b/app/src/main/java/com/gh/common/util/NewLogUtils.kt @@ -2437,97 +2437,4 @@ object NewLogUtils { } log(json, "event", false) } - - // 畅玩助手相关事件(下载弹窗展示事件/隐私政策点击事件/下载点击事件/授权弹窗展示事件/更新弹窗展示事件) - // 畅玩管理删除游戏弹窗展示事件/畅玩管理-畅玩广场入口点击事件/退出畅玩助手提示弹窗展示事件 - @JvmStatic - fun logHaloFunEvent(event: String) { - val json = json { - "event" to event - parseAndPutMeta().invoke(this) - } - log(json, "event", false) - } - - // 关联游戏跳转icon点击事件 - @JvmStatic - fun logHaloFunGameDetailJumpClick(downloadStatus: String, gameId: String) { - val json = json { - "event" to "halo_fun_game_detail_jump_click" - "download_state" to downloadStatus - "game_id" to gameId - parseAndPutMeta().invoke(this) - } - log(json, "event", false) - } - - // 下载完成提示条点击事件 - @JvmStatic - fun logHaloFunDownloadCompleteTipClick(buttonType: String, gameId: String) { - val json = json { - "event" to "halo_fun_download_complete_tip_click" - "button_type" to buttonType - "game_id" to gameId - parseAndPutMeta().invoke(this) - } - log(json, "event", false) - } - - // 畅玩助手更新弹窗点击事件 - @JvmStatic - fun logHaloFunUpdateDialogClick(dialogType: String, buttonType: String) { - val json = json { - "event" to "halo_fun_update_dialog_click" - "dialog_type" to dialogType - "button_type" to buttonType - parseAndPutMeta().invoke(this) - } - log(json, "event", false) - } - - // 畅玩管理展示事件 - @JvmStatic - fun logHaloFunManageShow(entrance: String) { - val json = json { - "event" to "halo_fun_manage_show" - "entrance" to entrance - parseAndPutMeta().invoke(this) - } - log(json, "event", false) - } - - // 畅玩管理-最近在玩板块展示管理事件 - @JvmStatic - fun logHaloFunManageRecentGameSwitch(isOn: Boolean) { - val json = json { - "event" to "halo_fun_manage_recent_game_switch" - "is_on" to isOn - parseAndPutMeta().invoke(this) - } - log(json, "event", false) - } - - // 畅玩管理删除游戏弹窗点击事件 - @JvmStatic - fun logHaloFunManageGameDeleteDialogClick(buttonType: String, gamesArray: JSONArray) { - val json = json { - "event" to "halo_fun_manage_game_delete_dialog_click" - "button_type" to buttonType - "games_array" to gamesArray - parseAndPutMeta().invoke(this) - } - log(json, "event", false) - } - - // 退出畅玩助手提示弹窗反馈收集事件 - @JvmStatic - fun logHaloFunGameExitDialogSubmitClick(detail: String, typeTags: JSONArray) { - val json = json { - "event" to "halo_fun_game_exit_dialog_submit_click" - "detail" to detail - "type_tags" to typeTags - parseAndPutMeta().invoke(this) - } - log(json, "event", false) - } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java index fb44002ccb..4c9520c5e9 100644 --- a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java +++ b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java @@ -6,7 +6,7 @@ import android.os.Bundle; import android.view.MenuItem; import com.gh.common.util.DirectUtils; -import com.gh.common.util.NewLogUtils; +import com.gh.common.util.NewFlatLogUtils; import com.gh.gamecenter.common.base.activity.ToolBarActivity; import com.gh.gamecenter.common.base.fragment.BaseFragment_TabLayout; import com.gh.gamecenter.common.constant.EntranceConsts; @@ -63,7 +63,7 @@ public class DownloadManagerActivity extends ToolBarActivity { @Override public boolean onMenuItemClick(MenuItem item) { - NewLogUtils.logHaloFunManageShow("下载管理"); + NewFlatLogUtils.logHaloFunManageShow("下载管理"); DirectUtils.directToVGameDownload(this, false); return true; } diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt index e0a904c051..ca7622142e 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt @@ -1644,7 +1644,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { "demo" -> "试玩" else -> "下载" } - NewLogUtils.logHaloFunGameDetailJumpClick(downloadStatus, simpleGame.id ?: "") + NewFlatLogUtils.logHaloFunGameDetailJumpClick(downloadStatus, simpleGame.id ?: "") DirectUtils.directToGameDetail(requireContext(), it.id ?: "", mEntrance) } } diff --git a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt index 847490e333..4132606046 100644 --- a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt +++ b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt @@ -5,7 +5,7 @@ import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView.OnScrollListener -import com.gh.common.util.NewLogUtils +import com.gh.common.util.NewFlatLogUtils import com.gh.download.DownloadManager import com.gh.gamecenter.R import com.gh.gamecenter.baselist.DiffUtilAdapter @@ -43,7 +43,7 @@ class HomeRecentVGameViewHolder(var binding: ItemHomeRecentVgameBinding) : }) binding.moreTv.setOnClickListener { - NewLogUtils.logHaloFunManageShow("最近在玩") + NewFlatLogUtils.logHaloFunManageShow("最近在玩") binding.root.context.startActivity( VDownloadManagerActivity.getIntent( binding.root.context, @@ -54,7 +54,7 @@ class HomeRecentVGameViewHolder(var binding: ItemHomeRecentVgameBinding) : } binding.vspaceIv.setOnClickListener { - NewLogUtils.logHaloFunEvent("halo_fun_manage_square_entrance_click") + NewFlatLogUtils.logHaloFunEvent("halo_fun_manage_square_entrance_click") } } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index 43ea3fc825..0c0c4ed6c4 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -13,7 +13,7 @@ import com.gh.common.databind.BindingAdapters import com.gh.common.exposure.ExposureEvent import com.gh.common.exposure.ExposureSource import com.gh.common.exposure.IExposable -import com.gh.common.util.NewLogUtils +import com.gh.common.util.NewFlatLogUtils import com.gh.common.view.DownloadProgressBar import com.gh.download.DownloadManager import com.gh.gamecenter.GameDetailActivity @@ -200,7 +200,7 @@ class VDownloadManagerAdapter( ) mPopupBinding?.itemDelete?.setOnClickListener { - NewLogUtils.logHaloFunEvent("halo_fun_manage_game_delete_dialog_show") + NewFlatLogUtils.logHaloFunEvent("halo_fun_manage_game_delete_dialog_show") DialogHelper.showDialog( mContext, "是否删除${selectItems.size}条记录?", @@ -211,13 +211,13 @@ class VDownloadManagerAdapter( mViewModel.removeItems(selectItems) selectItems.clear() checkSelectItems() - NewLogUtils.logHaloFunManageGameDeleteDialogClick("删除", JSONArray(selectItems)) + NewFlatLogUtils.logHaloFunManageGameDeleteDialogClick("删除", JSONArray(selectItems)) AppExecutor.uiExecutor.executeWithDelay({ mViewModel.load(LoadType.REFRESH) }, 200) }, - { NewLogUtils.logHaloFunManageGameDeleteDialogClick("再看看", JSONArray(selectItems)) }, + { NewFlatLogUtils.logHaloFunManageGameDeleteDialogClick("再看看", JSONArray(selectItems)) }, extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true) ) } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index 7d173b0ed3..655630083d 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -5,7 +5,7 @@ import android.view.View import androidx.recyclerview.widget.RecyclerView import com.ethanhua.skeleton.Skeleton import com.gh.common.exposure.ExposureListener -import com.gh.common.util.NewLogUtils +import com.gh.common.util.NewFlatLogUtils import com.gh.download.DownloadManager import com.gh.gamecenter.R import com.gh.gamecenter.baselist.ListAdapter @@ -96,7 +96,7 @@ class VDownloadManagerFragment : } lottieView.playAnimation() SPUtils.setBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, !status) - NewLogUtils.logHaloFunManageRecentGameSwitch(!status) + NewFlatLogUtils.logHaloFunManageRecentGameSwitch(!status) DownloadManager.getInstance().notifyDownloadLiveDataChanged() } diff --git a/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt b/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt index e319c1c413..bb75cdd47e 100644 --- a/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt +++ b/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt @@ -10,7 +10,7 @@ import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.core.widget.doOnTextChanged import androidx.lifecycle.ViewModel -import com.gh.common.util.NewLogUtils +import com.gh.common.util.NewFlatLogUtils import com.gh.common.util.PackageUtils import com.gh.gamecenter.R import com.gh.gamecenter.common.base.fragment.BaseDialogFragment @@ -83,7 +83,7 @@ class VFeedbackDialogFragment : BaseDialogFragment() { } mBinding.submitTv.setOnClickListener { mViewModel.postFeedback(mGame!!.id, mBinding.feedbackEt.text.toString(), getSelectedTagString()) - NewLogUtils.logHaloFunGameExitDialogSubmitClick(mBinding.feedbackEt.text.toString(), JSONArray(getSelectedTagString())) + NewFlatLogUtils.logHaloFunGameExitDialogSubmitClick(mBinding.feedbackEt.text.toString(), JSONArray(getSelectedTagString())) dismissAllowingStateLoss() } checkLabel() @@ -157,7 +157,7 @@ class VFeedbackDialogFragment : BaseDialogFragment() { activity: AppCompatActivity, game: GameEntity? ) { - NewLogUtils.logHaloFunEvent("halo_fun_game_exit_dialog_show") + NewFlatLogUtils.logHaloFunEvent("halo_fun_game_exit_dialog_show") VFeedbackDialogFragment().apply { arguments = Bundle().apply { putParcelable(KEY_GAME, game) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 41db293700..07f9d9f162 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -14,7 +14,7 @@ import com.gh.common.constant.Config import com.gh.common.exposure.ExposureUtils import com.gh.common.history.HistoryHelper import com.gh.common.util.DataCollectionUtils -import com.gh.common.util.NewLogUtils +import com.gh.common.util.NewFlatLogUtils import com.gh.common.util.PackageUtils import com.gh.download.DownloadManager import com.gh.download.PackageObserver @@ -252,7 +252,7 @@ object VHelper { if (containsUpdate) { val dialogType = if (mUpdateEntity!!.isForce) "强制更新" else "提示更新" - NewLogUtils.logHaloFunEvent("halo_fun_update_dialog_show") + NewFlatLogUtils.logHaloFunEvent("halo_fun_update_dialog_show") SPUtils.setString( KEY_LAST_ALERT_UPDATE_URL, mUpdateEntity!!.url + mUpdateEntity!!.alert @@ -264,7 +264,7 @@ object VHelper { cancelText = "立即更新", confirmText = "继续游戏", cancelClickCallback = { - NewLogUtils.logHaloFunUpdateDialogClick(dialogType, "立即更新") + NewFlatLogUtils.logHaloFunUpdateDialogClick(dialogType, "立即更新") VSpaceDialogFragment.showDownloadDialog( context, getVSpaceDownloadEntity(true), @@ -273,7 +273,7 @@ object VHelper { ) }, confirmClickCallback = { - NewLogUtils.logHaloFunUpdateDialogClick(dialogType, "继续游戏") + NewFlatLogUtils.logHaloFunUpdateDialogClick(dialogType, "继续游戏") callback.invoke() }, extraConfig = DialogHelper.Config(centerTitle = true), @@ -347,7 +347,7 @@ object VHelper { if (isStoragePermissionGranted) { callback.invoke() } else { - NewLogUtils.logHaloFunEvent("halo_fun_access_dialog_show") + NewFlatLogUtils.logHaloFunEvent("halo_fun_access_dialog_show") context.startActivity(mDelegateManager.requestPermissionIntent) } } catch (e: RuntimeException) { diff --git a/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt b/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt index 811b748ce0..dfe4b2f4ad 100644 --- a/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt +++ b/app/src/main/java/com/gh/vspace/VLoadCompleteWindowHelper.kt @@ -13,7 +13,7 @@ import androidx.core.view.get import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.widget.ViewPager2 -import com.gh.common.util.NewLogUtils +import com.gh.common.util.NewFlatLogUtils import com.gh.gamecenter.R import com.gh.gamecenter.common.utils.dip2px import com.gh.gamecenter.common.utils.toBinding @@ -139,14 +139,14 @@ object VLoadCompleteWindowHelper { } mBinding.closeIv.setOnClickListener { if (!ClickUtils.isFastDoubleClick(it.id)) { - NewLogUtils.logHaloFunDownloadCompleteTipClick("关闭", mAdapter.gameEntityList[mBinding.viewPager.currentItem].id) + NewFlatLogUtils.logHaloFunDownloadCompleteTipClick("关闭", mAdapter.gameEntityList[mBinding.viewPager.currentItem].id) mBinding.viewPager.removeCallbacks(mLoopTask) mBinding.viewPager.removeCallbacks(mDismissTask) EasyFloat.dismiss(LOAD_COMPLETE_WINDOW) } } mBinding.launchTv.setOnClickListener { - NewLogUtils.logHaloFunDownloadCompleteTipClick("启动", mAdapter.gameEntityList[mBinding.viewPager.currentItem].id) + NewFlatLogUtils.logHaloFunDownloadCompleteTipClick("启动", mAdapter.gameEntityList[mBinding.viewPager.currentItem].id) VHelper.installOrLaunch(activity, mAdapter.gameEntityList[mBinding.viewPager.currentItem].getApk()[0].packageName) } } diff --git a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt index 80afb4428e..1ef23fcf72 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt @@ -17,7 +17,7 @@ import com.gh.common.exposure.ExposureUtils import com.gh.common.exposure.ExposureUtils.DownloadType.DOWNLOAD import com.gh.common.exposure.ExposureUtils.DownloadType.UPDATE import com.gh.common.util.DataCollectionUtils -import com.gh.common.util.NewLogUtils +import com.gh.common.util.NewFlatLogUtils import com.gh.common.util.PackageInstaller import com.gh.common.view.DownloadProgressBar import com.gh.download.DownloadManager @@ -94,10 +94,10 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { mBinding.downloadBtn.downloadType = DownloadProgressBar.DownloadType.NORMAL mBinding.descTv.text = spanBuilder mBinding.privacyPolicyTv.setOnClickListener { - NewLogUtils.logHaloFunEvent("halo_fun_download_dialog_privacy_click") + NewFlatLogUtils.logHaloFunEvent("halo_fun_download_dialog_privacy_click") } mBinding.downloadBtn.setOnClickListener { - NewLogUtils.logHaloFunEvent("halo_fun_download_dialog_download_click") + NewFlatLogUtils.logHaloFunEvent("halo_fun_download_dialog_download_click") val name = "畅玩助手V" + mAppEntity?.version val downloadId = PackageInstaller.createDownloadId(name) @@ -231,7 +231,7 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { // 防止重复弹出 if (hasDialogDisplayedInCurrentActivity(fragmentActivity)) return - NewLogUtils.logHaloFunEvent("halo_fun_download_dialog_show") + NewFlatLogUtils.logHaloFunEvent("halo_fun_download_dialog_show") val downloadDialog = VSpaceDialogFragment().apply { arguments = Bundle().apply { From 5e36bd795557fe6c7c400c21ae572f1b006b2bee Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 7 Jul 2022 16:18:10 +0800 Subject: [PATCH 078/217] =?UTF-8?q?style:=20=E6=95=B4=E7=90=86=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E6=9C=80=E8=BF=91=E5=9C=A8=E7=8E=A9=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../download/GameDownloadFragmentAdapter.java | 2 +- .../gh/vspace/HomeRecentVGameViewHolder.kt | 61 +++++------- .../com/gh/vspace/VDownloadManagerAdapter.kt | 2 +- .../com/gh/vspace/VFeedbackDialogFragment.kt | 2 +- .../main/java/com/gh/vspace/VGameItemData.kt | 96 ++++++++++--------- 5 files changed, 78 insertions(+), 85 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java b/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java index cc2db4a942..d3de316826 100644 --- a/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java +++ b/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragmentAdapter.java @@ -345,7 +345,7 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter { // DownloadManager.getInstance().pause(downloadEntity); break; case "等待": - Utils.toast(mContext, "最多只能同时启动3个下载任务"); + Utils.toast(mContext, "最多只能同时下载三个任务,请稍等"); break; case "启动": PackageUtils.launchApplicationByPackageName(mContext, downloadEntity.getPackageName()); diff --git a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt index 847490e333..a7128ae654 100644 --- a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt +++ b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt @@ -121,34 +121,17 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter( mBinding.gameIconIv.setTag(R.string.app_name, entity.downloadEntity.packageName) } - updateViewByStatus(mBinding, entity.downloadEntity) + updateViewByStatus(mBinding, entity) } - private fun updateViewByStatus( - binding: ItemHomeVgameBinding, - downloadEntity: DownloadEntity - ) { - var shouldShowMask = false - var shouldShowProgressBar = false - var shouldShowUpdate = false - var shouldShowControlTv = false - var shouldShowDot = false - var controlText = "继续" + private fun updateViewByStatus(binding: ItemHomeVgameBinding, itemData: VGameItemData) { + val downloadEntity = itemData.downloadEntity - if (downloadEntity.status == DownloadStatus.done - && VHelper.getLastPlayedTime(downloadEntity) == 0L - ) { - shouldShowDot = true - } + itemData.refresh() when (downloadEntity.status) { DownloadStatus.done -> { - if (PackagesManager.isCanUpdate( - downloadEntity.gameId, - downloadEntity.packageName - ) - ) { - shouldShowUpdate = true + if (itemData.shouldShowUpdate) { binding.root.setOnClickListener { PackagesManager.getUpdateList() .firstOrNull { it.id == downloadEntity.gameId } @@ -165,23 +148,24 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter( } } } - DownloadStatus.pause, DownloadStatus.subscribe, - DownloadStatus.waiting -> { - shouldShowMask = true - shouldShowProgressBar = true - shouldShowControlTv = true + DownloadStatus.waiting, + DownloadStatus.pause -> { binding.progressBar.progressDrawable = R.drawable.bg_home_vgame_progress_inactive.toDrawable() - binding.root.setOnClickListener { - DownloadManager.getInstance().resume(downloadEntity, false) + + if (downloadEntity.status == DownloadStatus.waiting) { + binding.root.setOnClickListener { + ToastUtils.toast("最多只能同时下载三个任务,请稍等") + } + } else { + binding.root.setOnClickListener { + DownloadManager.getInstance().resume(downloadEntity, false) + } } } DownloadStatus.redirected, DownloadStatus.downloading -> { - shouldShowMask = true - shouldShowProgressBar = true - shouldShowUpdate = false binding.progressBar.progressDrawable = R.drawable.bg_home_vgame_progress_active.toDrawable() binding.root.setOnClickListener { @@ -198,7 +182,6 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter( DownloadStatus.notfound, DownloadStatus.unavailable, DownloadStatus.overflow -> { - controlText = "重试" binding.root.setOnClickListener { DownloadManager.getInstance().resume(downloadEntity, false) } @@ -210,13 +193,13 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter( } } - mBinding.maskView.goneIf(!shouldShowMask) - mBinding.controlTv.goneIf(!shouldShowControlTv) - mBinding.progressBar.goneIf(!shouldShowProgressBar) - mBinding.dotView.goneIf(!shouldShowDot) - mBinding.updateHintIv.goneIf(!shouldShowUpdate) + mBinding.maskView.goneIf(!itemData.shouldShowMask) + mBinding.controlTv.goneIf(!itemData.shouldShowControlTv) + mBinding.progressBar.goneIf(!itemData.shouldShowProgressBar) + mBinding.dotView.goneIf(!itemData.shouldShowDot) + mBinding.updateHintIv.goneIf(!itemData.shouldShowUpdate) - mBinding.controlTv.text = controlText + mBinding.controlTv.text = itemData.controlText mBinding.progressBar.progress = downloadEntity.percent.toInt() } } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index 43ea3fc825..1fe12af870 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -290,7 +290,7 @@ class VDownloadManagerAdapter( } DownloadStatus.waiting -> { btnText = context.getString(R.string.waiting) - setOnClickListener { Utils.toast(mContext, "最多只能同时启动3个下载任务"); } + setOnClickListener { Utils.toast(mContext, "最多只能同时下载三个任务,请稍等"); } } DownloadStatus.pause, DownloadStatus.timeout, diff --git a/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt b/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt index e319c1c413..730b2cb6a9 100644 --- a/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt +++ b/app/src/main/java/com/gh/vspace/VFeedbackDialogFragment.kt @@ -78,7 +78,7 @@ class VFeedbackDialogFragment : BaseDialogFragment() { } mBinding.dontShowAgainTv.enlargeTouchArea() mBinding.dontShowAgainTv.setOnClickListener { - VFeedbackSuppressedSimpleDao().add(mGame?.id ?: "") + VFeedbackSuppressedSimpleDao().add(mGame?.getUniquePackageName() ?: "") dismissAllowingStateLoss() } mBinding.submitTv.setOnClickListener { diff --git a/app/src/main/java/com/gh/vspace/VGameItemData.kt b/app/src/main/java/com/gh/vspace/VGameItemData.kt index 7de042db50..2b97be3b77 100644 --- a/app/src/main/java/com/gh/vspace/VGameItemData.kt +++ b/app/src/main/java/com/gh/vspace/VGameItemData.kt @@ -14,54 +14,64 @@ data class VGameItemData( var shouldShowDot: Boolean = false, var controlText: String = "继续" ) { - companion object { - fun from(downloadEntity: DownloadEntity): VGameItemData { - return VGameItemData(downloadEntity).apply { - if (downloadEntity.status == DownloadStatus.done - && VHelper.getLastPlayedTime(downloadEntity) == 0L - ) { - shouldShowDot = true - } + fun refresh() { + if (downloadEntity.status == DownloadStatus.done + && VHelper.getLastPlayedTime(downloadEntity) == 0L + ) { + shouldShowDot = true + } - if (PackagesManager.isCanUpdate( - downloadEntity.gameId, - downloadEntity.packageName - ) - ) { - shouldShowUpdate = true - } + if (PackagesManager.isCanUpdate( + downloadEntity.gameId, + downloadEntity.packageName + ) + ) { + shouldShowUpdate = true + } - when (downloadEntity.status) { - DownloadStatus.done -> { - // do nothing - } - DownloadStatus.pause, - DownloadStatus.subscribe, - DownloadStatus.waiting -> { - shouldShowMask = true - shouldShowProgressBar = true - shouldShowControlTv = true - } - DownloadStatus.downloading -> { - shouldShowMask = true - shouldShowProgressBar = true - } + when (downloadEntity.status) { + DownloadStatus.done -> { + controlText = "" + } + DownloadStatus.pause, + DownloadStatus.subscribe, + DownloadStatus.waiting -> { + shouldShowMask = true + shouldShowProgressBar = true + shouldShowControlTv = true - DownloadStatus.timeout, - DownloadStatus.neterror, - DownloadStatus.hijack, - DownloadStatus.uncertificated, - DownloadStatus.unqualified, - DownloadStatus.notfound, - DownloadStatus.unavailable, - DownloadStatus.overflow -> { - controlText = "重试" - } - else -> { - // do nothing - } + controlText = if (downloadEntity.status == DownloadStatus.waiting) { + "等待中" + } else { + "继续" } } + DownloadStatus.downloading -> { + shouldShowMask = true + shouldShowProgressBar = true + controlText = "" + } + + DownloadStatus.cancel, + DownloadStatus.timeout, + DownloadStatus.neterror, + DownloadStatus.hijack, + DownloadStatus.uncertificated, + DownloadStatus.unqualified, + DownloadStatus.notfound, + DownloadStatus.unavailable, + DownloadStatus.overflow -> { + controlText = "重试" + } + else -> { + // do nothing + } + } + } + + companion object { + fun from(downloadEntity: DownloadEntity): VGameItemData { + return VGameItemData(downloadEntity).also { it.refresh() } } } } \ No newline at end of file From 35506c75f5ed73b3d75e26a537ffa2867971cc8a Mon Sep 17 00:00:00 2001 From: lyr Date: Fri, 8 Jul 2022 09:28:07 +0800 Subject: [PATCH 079/217] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E5=8D=87?= =?UTF-8?q?=E7=BA=A7Loghub=E6=95=B0=E6=8D=AE=E5=BA=93=E6=97=B6=E6=9C=AA?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=BB=98=E8=AE=A4=E5=80=BC=E7=9A=84=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 919db31ec3d31550fce9ac1c2c0815f12873c332) --- .../main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt index 210821d835..2d98c8d10b 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt @@ -14,7 +14,7 @@ abstract class LoghubDatabase : RoomDatabase() { private val MIGRATION_1_2: Migration = object : Migration(1, 2) { override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL("Alter TABLE loghubEvent add isFlat INTEGER NOT NULL") + database.execSQL("Alter TABLE loghubEvent add isFlat INTEGER NOT NULL DEFAULT 0") } } From 28266cd06d66fbd669a0dea5e8908a4ac4c6c7c5 Mon Sep 17 00:00:00 2001 From: lyr Date: Fri, 8 Jul 2022 09:28:07 +0800 Subject: [PATCH 080/217] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E5=8D=87?= =?UTF-8?q?=E7=BA=A7Loghub=E6=95=B0=E6=8D=AE=E5=BA=93=E6=97=B6=E6=9C=AA?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=BB=98=E8=AE=A4=E5=80=BC=E7=9A=84=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 919db31ec3d31550fce9ac1c2c0815f12873c332) --- .../main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt index 210821d835..2d98c8d10b 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt @@ -14,7 +14,7 @@ abstract class LoghubDatabase : RoomDatabase() { private val MIGRATION_1_2: Migration = object : Migration(1, 2) { override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL("Alter TABLE loghubEvent add isFlat INTEGER NOT NULL") + database.execSQL("Alter TABLE loghubEvent add isFlat INTEGER NOT NULL DEFAULT 0") } } From 3deb83ac8d276744ef9cb24c29ee773997df2921 Mon Sep 17 00:00:00 2001 From: leafwai Date: Wed, 6 Jul 2022 09:31:07 +0800 Subject: [PATCH 081/217] =?UTF-8?q?fix:=E3=80=90=E5=A4=9C=E9=97=B4?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E3=80=91UI=E6=B5=8B=E8=AF=95=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E9=97=AE=E9=A2=98=E6=B1=87=E6=80=BB=EF=BC=887?= =?UTF-8?q?=E6=9C=88=E7=AC=AC1=E5=91=A8=EF=BC=89https://git.shanqu.cc/pm/h?= =?UTF-8?q?alo/halo-app-issues/-/issues/1957?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/base/BaseRichEditorActivity.kt | 2 +- .../java/com/gh/gamecenter/AboutActivity.java | 4 +-- .../com/gh/gamecenter/CollectionActivity.java | 4 +-- .../com/gh/gamecenter/ConcernActivity.java | 4 +-- .../gh/gamecenter/ConcernInfoActivity.java | 4 +-- .../gamecenter/DownloadManagerActivity.java | 4 +-- .../gh/gamecenter/HelpAndFeedbackActivity.kt | 4 +-- .../java/com/gh/gamecenter/InfoActivity.java | 4 +-- .../gh/gamecenter/LibaoDetailActivity.java | 4 +-- .../java/com/gh/gamecenter/LoginActivity.java | 16 ++++++++++-- .../com/gh/gamecenter/MessageActivity.java | 4 +-- .../gh/gamecenter/MessageInviteActivity.java | 4 +-- .../gh/gamecenter/MessageKeFuActivity.java | 4 +-- .../gh/gamecenter/MessageVoteActivity.java | 4 +-- .../com/gh/gamecenter/NewsDetailActivity.java | 4 +-- .../main/java/com/gh/gamecenter/QaActivity.kt | 4 +-- .../java/com/gh/gamecenter/SearchActivity.kt | 21 ++-------------- .../java/com/gh/gamecenter/SettingActivity.kt | 4 +-- .../java/com/gh/gamecenter/ShellActivity.kt | 7 ++++++ .../com/gh/gamecenter/SuggestionActivity.java | 23 ++---------------- .../com/gh/gamecenter/UserInfoActivity.kt | 2 +- .../java/com/gh/gamecenter/VoteActivity.java | 11 ++------- .../java/com/gh/gamecenter/WebActivity.kt | 4 +-- .../gh/gamecenter/catalog/CatalogActivity.kt | 4 +-- .../catalog/NewCatalogListActivity.kt | 4 +-- .../category/CategoryDirectoryActivity.kt | 4 +-- .../category/CategoryListActivity.kt | 4 +-- .../category2/CategoryV2Activity.kt | 4 +-- .../forum/home/ForumActivityAdapter.kt | 10 ++++---- .../forum/list/ForumListActivity.kt | 2 +- .../forum/moderator/ApplyModeratorActivity.kt | 2 +- .../forum/moderator/ModeratorListActivity.kt | 4 +-- .../detail/ColumnCollectionDetailActivity.kt | 7 +++++- .../detail/CommonCollectionDetailActivity.kt | 2 +- .../game/upload/GameSubmissionActivity.kt | 2 +- .../gamecollection/choose/AddGamesActivity.kt | 4 +-- .../choose/ChooseGamesActivity.kt | 4 +-- .../detail/GameCollectionDetailAdapter.kt | 4 +-- .../detail/GameCollectionDetailFragment.kt | 2 +- ...meCollectionCommentConversationFragment.kt | 4 +-- .../mine/MyGameCollectionActivity.kt | 4 +-- .../publish/GameCollectionEditActivity.kt | 4 +-- .../tag/GameCollectionTagSelectActivity.kt | 4 +-- .../rating/edit/RatingEditActivity.kt | 2 +- .../gh/gamecenter/history/HistoryActivity.kt | 4 +-- .../message/MessageItemViewHolder.java | 2 +- .../gh/gamecenter/mygame/MyGameActivity.kt | 4 +-- .../personal/DeliveryInfoActivity.kt | 4 +-- .../PersonalityBackgroundActivity.kt | 4 +-- .../personalhome/fans/FansActivity.kt | 4 +-- .../followers/FollowersActivity.kt | 4 +-- .../personalhome/rating/RatingActivity.kt | 4 +-- .../qa/answer/detail/AnswerDetailFragment.kt | 2 +- .../detail/SimpleAnswerDetailActivity.kt | 4 +-- .../article/detail/ArticleDetailActivity.kt | 4 +-- .../article/detail/ArticleDetailFragment.kt | 2 +- .../qa/article/draft/ArticleDraftActivity.kt | 4 +-- .../qa/comment/base/BaseCommentAdapter.kt | 2 +- .../CommentConversationFragment.kt | 2 +- .../qa/draft/CommunityDraftWrapperActivity.kt | 4 +-- .../gh/gamecenter/qa/editor/GameActivity.kt | 4 +-- .../qa/editor/InsertAnswerWrapperActivity.kt | 4 +-- .../qa/editor/InsertArticleWrapperActivity.kt | 4 +-- .../InsertGameCollectionWrapperActivity.kt | 4 +-- .../qa/editor/InsertVideoWrapperActivity.kt | 4 +-- .../qa/editor/LocalMediaActivity.kt | 2 +- .../gh/gamecenter/qa/myqa/MyAskActivity.java | 4 +-- .../questions/draft/QuestionDraftActivity.kt | 4 +-- .../invite/QuestionsInviteActivity.java | 2 +- .../newdetail/NewQuestionDetailActivity.kt | 2 +- .../newdetail/NewQuestionDetailFragment.kt | 4 +-- .../qa/video/publish/VideoPublishActivity.kt | 2 +- .../gamecenter/security/BindPhoneActivity.kt | 4 +-- .../gamecenter/security/SecurityActivity.kt | 4 +-- .../servers/GameServerTestActivity.kt | 4 +-- .../gamecenter/servers/GameServersActivity.kt | 4 +-- .../servers/add/AddKaiFuActivity.kt | 4 +-- .../servers/patch/PatchKaifuActivity.kt | 4 +-- .../setting/GameDownloadSettingActivity.kt | 4 +-- .../setting/VideoSettingActivity.kt | 4 +-- .../simulatorgame/SimulatorGameActivity.kt | 4 +-- .../SimulatorManagementActivity.kt | 4 +-- .../gh/gamecenter/subject/SubjectActivity.kt | 4 +-- .../com/gh/gamecenter/tag/TagsActivity.kt | 4 +-- .../teenagermode/TeenagerModeActivity.kt | 4 +-- .../toolbox/ToolBoxBlockActivity.kt | 22 +++-------------- .../gamecenter/toolbox/ToolBoxItemAdapter.kt | 2 +- .../video/videomanager/VideoDraftActivity.kt | 4 +-- .../com/gh/gamecenter/vote/VoteFragment.kt | 16 ------------ .../fragment/SwitchInstallMethodFragment.kt | 12 +++++++++ .../community_edit_article.webp | Bin 7496 -> 0 bytes .../community_edit_question.webp | Bin 7224 -> 0 bytes .../drawable-xxhdpi/community_edit_video.webp | Bin 6944 -> 0 bytes .../community_edit_article.webp | Bin 0 -> 5450 bytes .../community_edit_question.webp | Bin 0 -> 5996 bytes .../community_edit_video.webp | Bin 0 -> 5446 bytes .../main/res/drawable/actionbar_search_bg.xml | 2 +- .../res/drawable/bg_shape_space2_radius_4.xml | 6 +++++ .../drawable/bg_shape_space2_radius_999.xml | 6 +++++ .../drawable/download_dialog_background.xml | 2 +- .../download_dialog_item_background.xml | 2 +- .../drawable/home_amway_rating_unselect.xml | 2 +- .../main/res/drawable/home_amway_unselect.xml | 2 +- app/src/main/res/layout/activity_suggest.xml | 1 + .../res/layout/activity_toolbox_block.xml | 1 + .../res/layout/common_collection_item.xml | 2 +- .../res/layout/fm_search_history_item.xml | 2 +- .../main/res/layout/forum_activity_item.xml | 2 +- app/src/main/res/layout/fragment_login.xml | 6 ++--- .../layout/fragment_switch_install_method.xml | 2 +- .../main/res/layout/imprint_content_item.xml | 6 ++--- app/src/main/res/layout/item_toolbox.xml | 2 +- .../layout/layout_search_game_content_tag.xml | 2 +- app/src/main/res/layout/message_item.xml | 2 +- .../layout/piece_article_input_container.xml | 2 +- .../res/layout/search_game_index_item.xml | 2 +- app/src/main/res/layout/user_history_item.xml | 2 +- .../base/CustomLayoutInflaterFactory.kt | 4 ++- .../common/base/activity/BaseActivity.java | 21 ++++++++++++++++ .../src/main/res/values-night/colors.xml | 9 ++++--- module_common/src/main/res/values/colors.xml | 5 ++-- module_common/src/main/res/values/strings.xml | 1 + 122 files changed, 264 insertions(+), 261 deletions(-) delete mode 100644 app/src/main/res/drawable-xxhdpi/community_edit_article.webp delete mode 100644 app/src/main/res/drawable-xxhdpi/community_edit_question.webp delete mode 100644 app/src/main/res/drawable-xxhdpi/community_edit_video.webp create mode 100644 app/src/main/res/drawable-xxxhdpi/community_edit_article.webp create mode 100644 app/src/main/res/drawable-xxxhdpi/community_edit_question.webp create mode 100644 app/src/main/res/drawable-xxxhdpi/community_edit_video.webp create mode 100644 app/src/main/res/drawable/bg_shape_space2_radius_4.xml create mode 100644 app/src/main/res/drawable/bg_shape_space2_radius_999.xml diff --git a/app/src/main/java/com/gh/base/BaseRichEditorActivity.kt b/app/src/main/java/com/gh/base/BaseRichEditorActivity.kt index f1059e3064..04e4013af9 100644 --- a/app/src/main/java/com/gh/base/BaseRichEditorActivity.kt +++ b/app/src/main/java/com/gh/base/BaseRichEditorActivity.kt @@ -745,7 +745,7 @@ abstract class BaseRichEditorActivity : ToolBarAct override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) mRichEditor.enableForceDark(NightModeUtils.isNightMode(this)) } diff --git a/app/src/main/java/com/gh/gamecenter/AboutActivity.java b/app/src/main/java/com/gh/gamecenter/AboutActivity.java index 40ce8b3265..ce35159eba 100644 --- a/app/src/main/java/com/gh/gamecenter/AboutActivity.java +++ b/app/src/main/java/com/gh/gamecenter/AboutActivity.java @@ -22,7 +22,7 @@ public class AboutActivity extends ToolBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } @NonNull @@ -40,6 +40,6 @@ public class AboutActivity extends ToolBarActivity { @Override protected void onNightModeChange() { super.onNightModeChange(); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } } diff --git a/app/src/main/java/com/gh/gamecenter/CollectionActivity.java b/app/src/main/java/com/gh/gamecenter/CollectionActivity.java index de2ec619d2..62d1873e94 100644 --- a/app/src/main/java/com/gh/gamecenter/CollectionActivity.java +++ b/app/src/main/java/com/gh/gamecenter/CollectionActivity.java @@ -16,7 +16,7 @@ public class CollectionActivity extends ToolBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } @Override @@ -27,7 +27,7 @@ public class CollectionActivity extends ToolBarActivity { @Override protected void onNightModeChange() { super.onNightModeChange(); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } @NonNull diff --git a/app/src/main/java/com/gh/gamecenter/ConcernActivity.java b/app/src/main/java/com/gh/gamecenter/ConcernActivity.java index 3ed660a896..61bb637da7 100644 --- a/app/src/main/java/com/gh/gamecenter/ConcernActivity.java +++ b/app/src/main/java/com/gh/gamecenter/ConcernActivity.java @@ -17,7 +17,7 @@ public class ConcernActivity extends ToolBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } @Override @@ -28,7 +28,7 @@ public class ConcernActivity extends ToolBarActivity { @Override protected void onNightModeChange() { super.onNightModeChange(); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } @NonNull diff --git a/app/src/main/java/com/gh/gamecenter/ConcernInfoActivity.java b/app/src/main/java/com/gh/gamecenter/ConcernInfoActivity.java index 3c75f7f8b2..85b0bcb60e 100644 --- a/app/src/main/java/com/gh/gamecenter/ConcernInfoActivity.java +++ b/app/src/main/java/com/gh/gamecenter/ConcernInfoActivity.java @@ -17,7 +17,7 @@ public class ConcernInfoActivity extends ToolBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } public static Intent getIntent(Context context) { @@ -27,6 +27,6 @@ public class ConcernInfoActivity extends ToolBarActivity { @Override protected void onNightModeChange() { super.onNightModeChange(); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } } diff --git a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java index 68ab338e1c..e804703ad3 100644 --- a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java +++ b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java @@ -25,7 +25,7 @@ public class DownloadManagerActivity extends ToolBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } @Override @@ -60,6 +60,6 @@ public class DownloadManagerActivity extends ToolBarActivity { @Override protected void onNightModeChange() { super.onNightModeChange(); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/HelpAndFeedbackActivity.kt b/app/src/main/java/com/gh/gamecenter/HelpAndFeedbackActivity.kt index ff7188d0df..2b47a3978e 100644 --- a/app/src/main/java/com/gh/gamecenter/HelpAndFeedbackActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/HelpAndFeedbackActivity.kt @@ -39,7 +39,7 @@ class HelpAndFeedbackActivity : BaseActivity_TabLayout() { setNavigationTitle("帮助与反馈") val defaultPosition = intent.getIntExtra(PAGE_INDEX, HELP_ITEM) setCurrentItem(defaultPosition) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun onPageSelected(position: Int) { @@ -57,7 +57,7 @@ class HelpAndFeedbackActivity : BaseActivity_TabLayout() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/InfoActivity.java b/app/src/main/java/com/gh/gamecenter/InfoActivity.java index 2185c26fe9..5b1788ccfe 100644 --- a/app/src/main/java/com/gh/gamecenter/InfoActivity.java +++ b/app/src/main/java/com/gh/gamecenter/InfoActivity.java @@ -17,7 +17,7 @@ public class InfoActivity extends ToolBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } public static Intent getIntent(Context context) { @@ -27,6 +27,6 @@ public class InfoActivity extends ToolBarActivity { @Override protected void onNightModeChange() { super.onNightModeChange(); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } } diff --git a/app/src/main/java/com/gh/gamecenter/LibaoDetailActivity.java b/app/src/main/java/com/gh/gamecenter/LibaoDetailActivity.java index 995e15ed31..12650cb58e 100644 --- a/app/src/main/java/com/gh/gamecenter/LibaoDetailActivity.java +++ b/app/src/main/java/com/gh/gamecenter/LibaoDetailActivity.java @@ -198,7 +198,7 @@ public class LibaoDetailActivity extends ToolBarActivity implements LibaoDetailA if (mLibaoEntity != null) { mLibaoEntity.setClickReceiveBtnIn(isClickReceiveBtnIn); } - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); mIsScroll = true; mSkeleton = Skeleton.bind(mListSkeleton).shimmer(false).load(R.layout.activity_libaodetail_skeleton).show(); @@ -567,7 +567,7 @@ public class LibaoDetailActivity extends ToolBarActivity implements LibaoDetailA mLibaoDetailRv.removeItemDecorationAt(0); mLibaoDetailRv.addItemDecoration(getItemDecoration()); } - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } @Override diff --git a/app/src/main/java/com/gh/gamecenter/LoginActivity.java b/app/src/main/java/com/gh/gamecenter/LoginActivity.java index d522095612..a653b68c31 100644 --- a/app/src/main/java/com/gh/gamecenter/LoginActivity.java +++ b/app/src/main/java/com/gh/gamecenter/LoginActivity.java @@ -11,6 +11,7 @@ import com.gh.gamecenter.common.base.activity.ToolBarActivity; import com.gh.common.util.QuickLoginHelper; import com.gh.gamecenter.common.constant.EntranceConsts; import com.gh.gamecenter.common.constant.RouteConsts; +import com.gh.gamecenter.common.utils.ExtensionsKt; import com.gh.gamecenter.core.utils.DisplayUtils; import com.gh.gamecenter.fragment.LoginFragment; @@ -42,7 +43,18 @@ public class LoginActivity extends ToolBarActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); hideToolbar(true); - DisplayUtils.setLightStatusBar(this, true); - DisplayUtils.setStatusBarColor(this, R.color.transparent, true); + DisplayUtils.setLightStatusBar(this, !mNightMode); + DisplayUtils.setStatusBarColor(this, R.color.transparent, !mNightMode); + } + + @Override + protected boolean isAutoResetViewBackgroundEnabled() { + return true; + } + + @Override + protected void onNightModeChange() { + super.onNightModeChange(); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } } diff --git a/app/src/main/java/com/gh/gamecenter/MessageActivity.java b/app/src/main/java/com/gh/gamecenter/MessageActivity.java index 54e067b910..e014a34a71 100644 --- a/app/src/main/java/com/gh/gamecenter/MessageActivity.java +++ b/app/src/main/java/com/gh/gamecenter/MessageActivity.java @@ -18,7 +18,7 @@ public class MessageActivity extends ToolBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } public static Intent getIntent(Context context, String entrance) { @@ -30,6 +30,6 @@ public class MessageActivity extends ToolBarActivity { @Override protected void onNightModeChange() { super.onNightModeChange(); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } } diff --git a/app/src/main/java/com/gh/gamecenter/MessageInviteActivity.java b/app/src/main/java/com/gh/gamecenter/MessageInviteActivity.java index 66eccff915..5a85535069 100644 --- a/app/src/main/java/com/gh/gamecenter/MessageInviteActivity.java +++ b/app/src/main/java/com/gh/gamecenter/MessageInviteActivity.java @@ -26,12 +26,12 @@ public class MessageInviteActivity extends ToolBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } @Override protected void onNightModeChange() { super.onNightModeChange(); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } } diff --git a/app/src/main/java/com/gh/gamecenter/MessageKeFuActivity.java b/app/src/main/java/com/gh/gamecenter/MessageKeFuActivity.java index e15c64fb9e..4ee5ea6c0e 100644 --- a/app/src/main/java/com/gh/gamecenter/MessageKeFuActivity.java +++ b/app/src/main/java/com/gh/gamecenter/MessageKeFuActivity.java @@ -29,12 +29,12 @@ public class MessageKeFuActivity extends ToolBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } @Override protected void onNightModeChange() { super.onNightModeChange(); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } } diff --git a/app/src/main/java/com/gh/gamecenter/MessageVoteActivity.java b/app/src/main/java/com/gh/gamecenter/MessageVoteActivity.java index 5bc84cddb0..364b433133 100644 --- a/app/src/main/java/com/gh/gamecenter/MessageVoteActivity.java +++ b/app/src/main/java/com/gh/gamecenter/MessageVoteActivity.java @@ -26,12 +26,12 @@ public class MessageVoteActivity extends ToolBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } @Override protected void onNightModeChange() { super.onNightModeChange(); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } } diff --git a/app/src/main/java/com/gh/gamecenter/NewsDetailActivity.java b/app/src/main/java/com/gh/gamecenter/NewsDetailActivity.java index 77080593e0..6d1ec9dcd3 100644 --- a/app/src/main/java/com/gh/gamecenter/NewsDetailActivity.java +++ b/app/src/main/java/com/gh/gamecenter/NewsDetailActivity.java @@ -237,7 +237,7 @@ public class NewsDetailActivity extends DownloadToolbarActivity implements OnCli @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); mDetailRv = findViewById(R.id.news_detail_rv_show); mDetailBottomLl = findViewById(R.id.news_detail_ll_bottom); @@ -710,7 +710,7 @@ public class NewsDetailActivity extends DownloadToolbarActivity implements OnCli @Override protected void onNightModeChange() { super.onNightModeChange(); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); mNewsShare.setIcon(R.drawable.icon_share_black); mNewsCollection.setIcon(R.drawable.community_content_detail_collect_unselect); mDetailRv.removeItemDecoration(mItemDecoration); diff --git a/app/src/main/java/com/gh/gamecenter/QaActivity.kt b/app/src/main/java/com/gh/gamecenter/QaActivity.kt index 8fb1bc954a..0aa246d757 100644 --- a/app/src/main/java/com/gh/gamecenter/QaActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/QaActivity.kt @@ -31,13 +31,13 @@ class QaActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun isAutoResetViewBackgroundEnabled() = true override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/SearchActivity.kt b/app/src/main/java/com/gh/gamecenter/SearchActivity.kt index ecff66ef81..132bdaa258 100644 --- a/app/src/main/java/com/gh/gamecenter/SearchActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/SearchActivity.kt @@ -61,7 +61,7 @@ open class SearchActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) searchEt = findViewById(R.id.searchEt) searchBtn = findViewById(R.id.searchBtn) @@ -266,28 +266,11 @@ open class SearchActivity : BaseActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) - findViewById(R.id.searchContainer)?.run { - setBackgroundColor(R.color.background_white.toColor(this@SearchActivity)) - findViewById(R.id.searchBackground)?.background = R.drawable.actionbar_search_bg.toDrawable(this@SearchActivity) - searchEt.setTextColor(R.color.text_title.toColor(this@SearchActivity)) - searchBtn.setTextColor(R.color.text_title.toColor(this@SearchActivity)) - searchEt.setHintTextColor(R.color.text_body.toColor(this@SearchActivity)) - findViewById(R.id.iv_search)?.setImageDrawable(R.drawable.toolbar_search_icon.toDrawable(this@SearchActivity)) - findViewById(R.id.backIv)?.setImageDrawable(R.drawable.ic_bar_back.toDrawable(this@SearchActivity)) - deleteIv.setImageDrawable(R.drawable.ic_search_bar_clear.toDrawable(this@SearchActivity)) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - searchEt.textCursorDrawable = R.drawable.cursor_color.toDrawable(this@SearchActivity) - } - } + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun isAutoResetViewBackgroundEnabled() = true - override fun updateStaticViewBackground(view: View?) { - updateStaticView(view, listOf(R.id.searchContainer)) - } - companion object { const val KEY_SEARCH_TYPE = "search_type" private const val KEY_DISPLAY_TYPE = "display_type" diff --git a/app/src/main/java/com/gh/gamecenter/SettingActivity.kt b/app/src/main/java/com/gh/gamecenter/SettingActivity.kt index 5122da43ea..a5d7f5cee6 100644 --- a/app/src/main/java/com/gh/gamecenter/SettingActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/SettingActivity.kt @@ -11,14 +11,14 @@ import com.halo.assistant.fragment.SettingsFragment class SettingActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun isAutoResetViewBackgroundEnabled() = true override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/ShellActivity.kt b/app/src/main/java/com/gh/gamecenter/ShellActivity.kt index 97aaee7045..57471af449 100644 --- a/app/src/main/java/com/gh/gamecenter/ShellActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/ShellActivity.kt @@ -4,6 +4,7 @@ import android.content.Context import android.content.Intent import android.os.Bundle import android.os.Parcelable +import android.view.View import com.gh.gamecenter.common.base.activity.ToolBarActivity import com.gh.gamecenter.common.base.fragment.BaseFragment import com.gh.gamecenter.common.constant.EntranceConsts @@ -44,6 +45,12 @@ class ShellActivity : ToolBarActivity() { supportFragmentManager.beginTransaction().replace(R.id.placeholder, fragment).commitAllowingStateLoss() } + override fun isAutoResetViewBackgroundEnabled(): Boolean = true + + override fun updateStaticViewBackground(view: View?) { + updateStaticView(view, listOf(R.id.selectedIv)) + } + companion object { const val INTENT_TYPE = "intent_type" diff --git a/app/src/main/java/com/gh/gamecenter/SuggestionActivity.java b/app/src/main/java/com/gh/gamecenter/SuggestionActivity.java index a6452de30a..9a61e7c236 100644 --- a/app/src/main/java/com/gh/gamecenter/SuggestionActivity.java +++ b/app/src/main/java/com/gh/gamecenter/SuggestionActivity.java @@ -328,7 +328,7 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); initView(); Bundle extras = getIntent().getExtras(); @@ -1529,7 +1529,7 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall @Override protected void onNightModeChange() { super.onNightModeChange(); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); ActivitySuggestBinding binding = ActivitySuggestBinding.bind(mContentView); binding.divider1.setBackgroundColor(ContextCompat.getColor(this, R.color.cutting_line)); binding.divider2.setBackgroundColor(ContextCompat.getColor(this, R.color.cutting_line)); @@ -1540,24 +1540,5 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall binding.divider7.setBackgroundColor(ContextCompat.getColor(this, R.color.background)); binding.divider8.setBackgroundColor(ContextCompat.getColor(this, R.color.background)); binding.divider9.setBackgroundColor(ContextCompat.getColor(this, R.color.background)); - - binding.suggestPlatformEt.setTextColor(ContextCompat.getColor(this, R.color.text_title)); - binding.suggestPlatformEt.setHintTextColor(ContextCompat.getColor(this, R.color.text_body)); - binding.typeOtherName.setTextColor(ContextCompat.getColor(this, R.color.text_title)); - binding.typeOtherName.setHintTextColor(ContextCompat.getColor(this, R.color.text_body)); - binding.suggestContentEt.setTextColor(ContextCompat.getColor(this, R.color.text_title)); - binding.suggestContentEt.setHintTextColor(ContextCompat.getColor(this, R.color.text_body)); - binding.suggestLinkEt.setTextColor(ContextCompat.getColor(this, R.color.text_title)); - binding.suggestLinkEt.setHintTextColor(ContextCompat.getColor(this, R.color.text_body)); - binding.suggestEmailEt.setTextColor(ContextCompat.getColor(this, R.color.text_title)); - binding.suggestEmailEt.setHintTextColor(ContextCompat.getColor(this, R.color.text_body)); - binding.credentialsCodeEt.setTextColor(ContextCompat.getColor(this, R.color.text_title)); - binding.credentialsCodeEt.setHintTextColor(ContextCompat.getColor(this, R.color.text_body)); - binding.appNameEt.setTextColor(ContextCompat.getColor(this, R.color.text_title)); - binding.appNameEt.setHintTextColor(ContextCompat.getColor(this, R.color.text_body)); - binding.explanationEt.setTextColor(ContextCompat.getColor(this, R.color.text_title)); - binding.explanationEt.setHintTextColor(ContextCompat.getColor(this, R.color.text_body)); - binding.contactMethodEt.setTextColor(ContextCompat.getColor(this, R.color.text_title)); - binding.contactMethodEt.setHintTextColor(ContextCompat.getColor(this, R.color.text_body)); } } diff --git a/app/src/main/java/com/gh/gamecenter/UserInfoActivity.kt b/app/src/main/java/com/gh/gamecenter/UserInfoActivity.kt index 9961bbfdbf..4cc024f881 100644 --- a/app/src/main/java/com/gh/gamecenter/UserInfoActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/UserInfoActivity.kt @@ -21,6 +21,6 @@ class UserInfoActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/VoteActivity.java b/app/src/main/java/com/gh/gamecenter/VoteActivity.java index 7bc6ed4b5e..e4b2173e18 100644 --- a/app/src/main/java/com/gh/gamecenter/VoteActivity.java +++ b/app/src/main/java/com/gh/gamecenter/VoteActivity.java @@ -32,24 +32,17 @@ public class VoteActivity extends ToolBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } @Override protected void onNightModeChange() { super.onNightModeChange(); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } @Override protected boolean isAutoResetViewBackgroundEnabled() { return true; } - - @Override - protected void updateStaticViewBackground(View view) { - ArrayList blackList = new ArrayList<>(); - blackList.add(R.id.searchBarInclude); - updateStaticView(view, blackList); - } } diff --git a/app/src/main/java/com/gh/gamecenter/WebActivity.kt b/app/src/main/java/com/gh/gamecenter/WebActivity.kt index f37a6ba6c6..fc1439692e 100644 --- a/app/src/main/java/com/gh/gamecenter/WebActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/WebActivity.kt @@ -41,7 +41,7 @@ open class WebActivity : ToolBarActivity() { } else { super.onCreate(savedInstanceState) } - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun provideNormalIntent(): Intent { @@ -74,7 +74,7 @@ open class WebActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/catalog/CatalogActivity.kt b/app/src/main/java/com/gh/gamecenter/catalog/CatalogActivity.kt index d87a1a5b51..12b02b5831 100644 --- a/app/src/main/java/com/gh/gamecenter/catalog/CatalogActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/catalog/CatalogActivity.kt @@ -13,7 +13,7 @@ class CatalogActivity : DownloadToolbarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setToolbarMenu(R.menu.menu_download) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun showDownloadMenu(): Boolean { @@ -26,7 +26,7 @@ class CatalogActivity : DownloadToolbarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun isAutoResetViewBackgroundEnabled() = true diff --git a/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListActivity.kt b/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListActivity.kt index 3e1aaa9848..bbbbf1179c 100644 --- a/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/catalog/NewCatalogListActivity.kt @@ -14,7 +14,7 @@ class NewCatalogListActivity : DownloadToolbarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setToolbarMenu(R.menu.menu_download) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun showDownloadMenu(): Boolean { @@ -23,7 +23,7 @@ class NewCatalogListActivity : DownloadToolbarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun isAutoResetViewBackgroundEnabled() = true diff --git a/app/src/main/java/com/gh/gamecenter/category/CategoryDirectoryActivity.kt b/app/src/main/java/com/gh/gamecenter/category/CategoryDirectoryActivity.kt index 4b99dc1893..f64adc30df 100644 --- a/app/src/main/java/com/gh/gamecenter/category/CategoryDirectoryActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/category/CategoryDirectoryActivity.kt @@ -22,7 +22,7 @@ class CategoryDirectoryActivity : DownloadToolbarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setToolbarMenu(R.menu.menu_download) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun showDownloadMenu(): Boolean { @@ -41,6 +41,6 @@ class CategoryDirectoryActivity : DownloadToolbarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/category/CategoryListActivity.kt b/app/src/main/java/com/gh/gamecenter/category/CategoryListActivity.kt index 55460926d9..c5d91ea32b 100644 --- a/app/src/main/java/com/gh/gamecenter/category/CategoryListActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/category/CategoryListActivity.kt @@ -30,7 +30,7 @@ class CategoryListActivity : DownloadToolbarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setToolbarMenu(R.menu.menu_download) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun showDownloadMenu(): Boolean { @@ -43,6 +43,6 @@ class CategoryListActivity : DownloadToolbarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/category2/CategoryV2Activity.kt b/app/src/main/java/com/gh/gamecenter/category2/CategoryV2Activity.kt index 04681f2611..19510ba56b 100644 --- a/app/src/main/java/com/gh/gamecenter/category2/CategoryV2Activity.kt +++ b/app/src/main/java/com/gh/gamecenter/category2/CategoryV2Activity.kt @@ -13,7 +13,7 @@ class CategoryV2Activity : DownloadToolbarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setToolbarMenu(R.menu.menu_search) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun showDownloadMenu(): Boolean { @@ -28,7 +28,7 @@ class CategoryV2Activity : DownloadToolbarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/ForumActivityAdapter.kt b/app/src/main/java/com/gh/gamecenter/forum/home/ForumActivityAdapter.kt index cf52f66b0e..b689767ad1 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/home/ForumActivityAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumActivityAdapter.kt @@ -71,7 +71,7 @@ class ForumActivityAdapter( // 未开始 currentTime < activityEntity.effectTime.start -> { status = "未开始" - statusContainer.setCardBackgroundColor(R.color.bg_F5F6F7.toColor(mContext)) + statusContainer.setCardBackgroundColor(R.color.background_space.toColor(mContext)) statusIv.setImageResource(R.drawable.ic_activity_waiting) statusTv.text = "未开始" statusTv.setTextColor(R.color.text_subtitleDesc.toColor(mContext)) @@ -89,7 +89,7 @@ class ForumActivityAdapter( || activityEntity.effectTime.end == null || activityEntity.effectTime.end == 0L) -> { status = "进行中" - statusContainer.setCardBackgroundColor(R.color.bg_FFF3EB.toColor(mContext)) + statusContainer.setCardBackgroundColor(R.color.bg_1AFA8850.toColor(mContext)) statusIv.setImageResource(R.drawable.ic_activity_ongoing) statusTv.text = "进行中" statusTv.setTextColor(R.color.text_FA8850.toColor(mContext)) @@ -111,7 +111,7 @@ class ForumActivityAdapter( currentTime > activityEntity.effectTime.end && currentTime < activityEntity.awardTime.start -> { status = "正在评奖" - statusContainer.setCardBackgroundColor(R.color.bg_FFF3EB.toColor(mContext)) + statusContainer.setCardBackgroundColor(R.color.bg_1AFA8850.toColor(mContext)) statusIv.setImageResource(R.drawable.ic_activity_selection) statusTv.text = "正在评奖" statusTv.setTextColor(R.color.text_FA8850.toColor(mContext)) @@ -127,7 +127,7 @@ class ForumActivityAdapter( currentTime > activityEntity.awardTime.start && currentTime < activityEntity.awardTime.end -> { status = "奖励发放中" - statusContainer.setCardBackgroundColor(R.color.bg_FFF3EB.toColor(mContext)) + statusContainer.setCardBackgroundColor(R.color.bg_1AFA8850.toColor(mContext)) statusIv.setImageResource(R.drawable.ic_activity_award) statusTv.text = "奖励发放中" statusTv.setTextColor(R.color.text_FA8850.toColor(mContext)) @@ -142,7 +142,7 @@ class ForumActivityAdapter( // 已结束 currentTime > activityEntity.awardTime.end -> { status = "已结束" - statusContainer.setCardBackgroundColor(R.color.f8f8f8.toColor(mContext)) + statusContainer.setCardBackgroundColor(R.color.background_space.toColor(mContext)) statusIv.setImageResource(R.drawable.ic_activity_end) statusTv.text = "已结束" statusTv.setTextColor(R.color.text_body.toColor(mContext)) diff --git a/app/src/main/java/com/gh/gamecenter/forum/list/ForumListActivity.kt b/app/src/main/java/com/gh/gamecenter/forum/list/ForumListActivity.kt index 8e2d642a46..14e3632ad6 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/list/ForumListActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/list/ForumListActivity.kt @@ -14,7 +14,7 @@ class ForumListActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/forum/moderator/ApplyModeratorActivity.kt b/app/src/main/java/com/gh/gamecenter/forum/moderator/ApplyModeratorActivity.kt index 3ba676af22..d5fc9acbd5 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/moderator/ApplyModeratorActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/moderator/ApplyModeratorActivity.kt @@ -42,7 +42,7 @@ class ApplyModeratorActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } private fun setStatusBarTransparent() { DisplayUtils.transparentStatusBar(this) diff --git a/app/src/main/java/com/gh/gamecenter/forum/moderator/ModeratorListActivity.kt b/app/src/main/java/com/gh/gamecenter/forum/moderator/ModeratorListActivity.kt index 609f62bc98..34ad02ec72 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/moderator/ModeratorListActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/moderator/ModeratorListActivity.kt @@ -25,7 +25,7 @@ class ModeratorListActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) hideToolbar(true) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun isAutoResetViewBackgroundEnabled(): Boolean = true @@ -33,6 +33,6 @@ class ModeratorListActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailActivity.kt b/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailActivity.kt index ed4ead37d8..ab96085e46 100644 --- a/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/game/columncollection/detail/ColumnCollectionDetailActivity.kt @@ -11,6 +11,11 @@ import com.gh.gamecenter.common.utils.updateStatusBarColor class ColumnCollectionDetailActivity : ToolBarActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + updateStatusBarColor(R.color.background_white, R.color.background_white) + } + override fun provideNormalIntent(): Intent { return getTargetIntent(this, ColumnCollectionDetailActivity::class.java, ColumnCollectionDetailFragment::class.java) } @@ -19,7 +24,7 @@ class ColumnCollectionDetailActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun getBusinessId(): Pair { diff --git a/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CommonCollectionDetailActivity.kt b/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CommonCollectionDetailActivity.kt index bcb4e99bd5..503464bfd1 100644 --- a/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CommonCollectionDetailActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/game/commoncollection/detail/CommonCollectionDetailActivity.kt @@ -18,7 +18,7 @@ class CommonCollectionDetailActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun getBusinessId(): Pair { diff --git a/app/src/main/java/com/gh/gamecenter/game/upload/GameSubmissionActivity.kt b/app/src/main/java/com/gh/gamecenter/game/upload/GameSubmissionActivity.kt index f1452d1583..0c6a128f9e 100644 --- a/app/src/main/java/com/gh/gamecenter/game/upload/GameSubmissionActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/game/upload/GameSubmissionActivity.kt @@ -29,6 +29,6 @@ class GameSubmissionActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesActivity.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesActivity.kt index d278145a80..cc8642a103 100644 --- a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesActivity.kt @@ -11,7 +11,7 @@ class AddGamesActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun provideNormalIntent(): Intent { @@ -20,7 +20,7 @@ class AddGamesActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesActivity.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesActivity.kt index af8ac5779d..da8abe0a20 100644 --- a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesActivity.kt @@ -11,7 +11,7 @@ class ChooseGamesActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setNavigationTitle("选择游戏") - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun provideNormalIntent(): Intent { @@ -20,7 +20,7 @@ class ChooseGamesActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailAdapter.kt index 22f43ca14f..36f4615d73 100644 --- a/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailAdapter.kt @@ -293,7 +293,7 @@ open class GameCollectionDetailAdapter( ) { binding.run { root.setBackgroundColor(R.color.background_white.toColor(mContext)) - subCommentContainer.setBackgroundColor(R.color.background_space.toColor(mContext)) + subCommentContainer.setBackgroundColor(R.color.background_space_2.toColor(mContext)) divider.setBackgroundColor(R.color.text_F8F8F8.toColor(mContext)) bottomDivider.setBackgroundColor(R.color.divider.toColor(mContext)) userNameTv.setTextColor(R.color.text_subtitle.toColor(mContext)) @@ -486,7 +486,7 @@ open class GameCollectionDetailAdapter( binding.subCommentContainer.goneIf(subCommentList.isNullOrEmpty()) binding.firstSubCommentTv.goneIf(subCommentList?.firstOrNull() == null) binding.secondSubCommentTv.goneIf(subCommentList?.secondOrNull() == null) - binding.subCommentContainer.setRoundedColorBackground(R.color.background_space, 5F) + binding.subCommentContainer.setRoundedColorBackground(R.color.background_space_2, 5F) subCommentList?.firstOrNull()?.let { binding.firstSubCommentTv.text = getSubCommentSpanned( diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailFragment.kt index fd2968c54f..ecf8a068aa 100644 --- a/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionDetailFragment.kt @@ -155,7 +155,7 @@ class GameCollectionDetailFragment : inputContainer.run { bottomShareGroup.visibility = View.VISIBLE - replyTv.setBackgroundResource(R.drawable.button_round_f5f5f5) + replyTv.setBackgroundResource(R.drawable.bg_shape_space2_radius_999) replyTv.text = "说点什么吧" (bottomLikeIv.layoutParams as ConstraintLayout.LayoutParams).apply { rightMargin = 28f.dip2px() diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/detail/conversation/GameCollectionCommentConversationFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/detail/conversation/GameCollectionCommentConversationFragment.kt index 4b45b1bb84..25a7f929b3 100644 --- a/app/src/main/java/com/gh/gamecenter/gamecollection/detail/conversation/GameCollectionCommentConversationFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/detail/conversation/GameCollectionCommentConversationFragment.kt @@ -112,7 +112,7 @@ class GameCollectionCommentConversationFragment : inputContainer.bottomStarIv.visibility = View.GONE inputContainer.bottomStarTv.visibility = View.GONE - inputContainer.replyTv.setRoundedColorBackground(R.color.text_F0F0F0, 19F) + inputContainer.replyTv.setRoundedColorBackground(R.color.background_space_2, 19F) inputContainer.replyTv.setDebouncedClickListener { mViewModel.commentDetail?.let { startCommentActivity(it) } } @@ -259,7 +259,7 @@ class GameCollectionCommentConversationFragment : ) mBinding.inputContainer.run { bottomContainer.setBackgroundColor(R.color.background_white.toColor(requireContext())) - replyTv.setBackgroundColor(R.color.background.toColor(requireContext())) + replyTv.setRoundedColorBackground(R.color.background_space_2, 19F) replyTv.setTextColor(R.color.text_body.toColor(requireContext())) bottomShareTv.setTextColor(R.color.text_subtitle.toColor(requireContext())) bottomLikeTv.setTextColor(R.color.text_subtitle.toColor(requireContext())) diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/mine/MyGameCollectionActivity.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/mine/MyGameCollectionActivity.kt index 826f83d9e8..fe3425279e 100644 --- a/app/src/main/java/com/gh/gamecenter/gamecollection/mine/MyGameCollectionActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/mine/MyGameCollectionActivity.kt @@ -11,7 +11,7 @@ class MyGameCollectionActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun provideNormalIntent(): Intent { @@ -20,7 +20,7 @@ class MyGameCollectionActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt index 2d8e8222d0..427615d338 100644 --- a/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt @@ -49,7 +49,7 @@ class GameCollectionEditActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) mBinding = ActivityGameCollectionEditBinding.bind(mContentView) mViewModel = viewModelProvider() mChooseGamesViewModel = viewModelProvider(ChooseGamesViewModel.Factory()) @@ -496,7 +496,7 @@ class GameCollectionEditActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) mMenuPost.actionView.findViewById(R.id.postTv)?.background = R.drawable.textview_concern_red_up_round.toDrawable(this) if (::mBinding.isInitialized) { mBinding.run { diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/tag/GameCollectionTagSelectActivity.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/tag/GameCollectionTagSelectActivity.kt index 9980f9778d..92344b17a2 100644 --- a/app/src/main/java/com/gh/gamecenter/gamecollection/tag/GameCollectionTagSelectActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/tag/GameCollectionTagSelectActivity.kt @@ -12,7 +12,7 @@ class GameCollectionTagSelectActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) setNavigationTitle("选择标签") if (intent.getBundleExtra(NORMAL_FRAGMENT_BUNDLE)?.getBoolean(KEY_IS_SINGLE_CHOICE) == false) { setToolbarMenu(R.menu.menu_save) @@ -23,7 +23,7 @@ class GameCollectionTagSelectActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/rating/edit/RatingEditActivity.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/rating/edit/RatingEditActivity.kt index 540be63dca..2ec81b16a8 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/rating/edit/RatingEditActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/rating/edit/RatingEditActivity.kt @@ -493,7 +493,7 @@ class RatingEditActivity : ToolBarActivity(), KeyboardHeightObserver { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) mBinding.mWebView.enableForceDark(NightModeUtils.isNightMode(this)) } diff --git a/app/src/main/java/com/gh/gamecenter/history/HistoryActivity.kt b/app/src/main/java/com/gh/gamecenter/history/HistoryActivity.kt index 03c1b9e1b6..2b651447ac 100644 --- a/app/src/main/java/com/gh/gamecenter/history/HistoryActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/history/HistoryActivity.kt @@ -12,14 +12,14 @@ class HistoryActivity: ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun isAutoResetViewBackgroundEnabled() = true override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/message/MessageItemViewHolder.java b/app/src/main/java/com/gh/gamecenter/message/MessageItemViewHolder.java index c7db815e62..655d226c49 100644 --- a/app/src/main/java/com/gh/gamecenter/message/MessageItemViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/message/MessageItemViewHolder.java @@ -84,7 +84,7 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder public void setMessageItem(MessageEntity messageEntity, Context context, String entrance) { mBinding.messageItem.setBackground(ContextCompat.getDrawable(mBinding.getRoot().getContext(), R.drawable.reuse_listview_item_style)); - mBinding.messageOriginal.setBackground(ContextCompat.getDrawable(mBinding.getRoot().getContext(), R.drawable.bg_shape_f8_radius_8)); + mBinding.messageOriginal.setBackground(ContextCompat.getDrawable(mBinding.getRoot().getContext(), R.drawable.bg_shape_space_radius_8)); mBinding.messageUserName.setTextColor(ContextCompat.getColor(mBinding.getRoot().getContext(), R.color.text_title)); mBinding.messageUserMore.setTextColor(ContextCompat.getColor(mBinding.getRoot().getContext(), R.color.theme_font)); mBinding.messageCommand.setTextColor(ContextCompat.getColor(mBinding.getRoot().getContext(), R.color.text_title)); diff --git a/app/src/main/java/com/gh/gamecenter/mygame/MyGameActivity.kt b/app/src/main/java/com/gh/gamecenter/mygame/MyGameActivity.kt index 6821c8c146..74ec9b9189 100644 --- a/app/src/main/java/com/gh/gamecenter/mygame/MyGameActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/mygame/MyGameActivity.kt @@ -29,7 +29,7 @@ class MyGameActivity : BaseActivity_TabLayout() { setToolbarMenu(R.menu.menu_my_game) mDividerLineView?.visibility = View.VISIBLE showGuide() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun initFragmentList(fragments: MutableList?) { @@ -63,7 +63,7 @@ class MyGameActivity : BaseActivity_TabLayout() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } private fun showGuide() { diff --git a/app/src/main/java/com/gh/gamecenter/personal/DeliveryInfoActivity.kt b/app/src/main/java/com/gh/gamecenter/personal/DeliveryInfoActivity.kt index a42012f331..3ec7b92529 100644 --- a/app/src/main/java/com/gh/gamecenter/personal/DeliveryInfoActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/personal/DeliveryInfoActivity.kt @@ -12,12 +12,12 @@ class DeliveryInfoActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setNavigationTitle(R.string.delivery_info) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/background/PersonalityBackgroundActivity.kt b/app/src/main/java/com/gh/gamecenter/personalhome/background/PersonalityBackgroundActivity.kt index c91c2303db..011e53649c 100644 --- a/app/src/main/java/com/gh/gamecenter/personalhome/background/PersonalityBackgroundActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/personalhome/background/PersonalityBackgroundActivity.kt @@ -12,14 +12,14 @@ class PersonalityBackgroundActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setNavigationTitle("个性背景") - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun isAutoResetViewBackgroundEnabled(): Boolean = true override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/fans/FansActivity.kt b/app/src/main/java/com/gh/gamecenter/personalhome/fans/FansActivity.kt index 3342ddd42a..186756810b 100644 --- a/app/src/main/java/com/gh/gamecenter/personalhome/fans/FansActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/personalhome/fans/FansActivity.kt @@ -14,14 +14,14 @@ class FansActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun isAutoResetViewBackgroundEnabled(): Boolean = true override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/followers/FollowersActivity.kt b/app/src/main/java/com/gh/gamecenter/personalhome/followers/FollowersActivity.kt index 1b4c874cb7..b850058484 100644 --- a/app/src/main/java/com/gh/gamecenter/personalhome/followers/FollowersActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/personalhome/followers/FollowersActivity.kt @@ -14,14 +14,14 @@ class FollowersActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun isAutoResetViewBackgroundEnabled(): Boolean = true override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { fun getIntent(context: Context, userId: String, entrance: String, path: String): Intent { diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/rating/RatingActivity.kt b/app/src/main/java/com/gh/gamecenter/personalhome/rating/RatingActivity.kt index b206d535b2..1261aef6b2 100644 --- a/app/src/main/java/com/gh/gamecenter/personalhome/rating/RatingActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/personalhome/rating/RatingActivity.kt @@ -28,7 +28,7 @@ class RatingActivity : ListActivity>() { } else { setNavigationTitle("Ta的评分") } - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun provideListAdapter(): RatingAdapter { @@ -49,7 +49,7 @@ class RatingActivity : ListActivity>() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } diff --git a/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailFragment.kt index 1469f85510..9b7fb9d457 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailFragment.kt @@ -110,7 +110,7 @@ open class AnswerDetailFragment : ToolbarFragment() { mBinding.richEditor.setInputEnabled(false) mBinding.richEditor.setPadding(20, 15, 20, 15) mBinding.bottomController.replyTv.text = "说点什么吧" - mBinding.bottomController.replyTv.setRoundedColorBackground(R.color.background, 19F) + mBinding.bottomController.replyTv.setRoundedColorBackground(R.color.background_space_2, 19F) mElapsedHelper = TimeElapsedHelper(this) // 只对显示在屏幕上的 fragment 计时 diff --git a/app/src/main/java/com/gh/gamecenter/qa/answer/detail/SimpleAnswerDetailActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/answer/detail/SimpleAnswerDetailActivity.kt index 2c68d4c775..98e944c544 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/answer/detail/SimpleAnswerDetailActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/answer/detail/SimpleAnswerDetailActivity.kt @@ -13,7 +13,7 @@ class SimpleAnswerDetailActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun provideNormalIntent(): Intent? { @@ -28,7 +28,7 @@ class SimpleAnswerDetailActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailActivity.kt index 7060dff0e4..42a9c35dc3 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailActivity.kt @@ -21,7 +21,7 @@ class ArticleDetailActivity : ToolBarActivity() { // TODO 让状态栏透明 // DisplayUtils.transparentStatusBar(this) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun provideNormalIntent(): Intent { @@ -39,7 +39,7 @@ class ArticleDetailActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } diff --git a/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailFragment.kt index 22390da594..92822f1224 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailFragment.kt @@ -278,7 +278,7 @@ class ArticleDetailFragment : BaseCommentFragment) { @@ -35,7 +35,7 @@ class CommunityDraftWrapperActivity : BaseActivity_TabLayout() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/qa/editor/GameActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/editor/GameActivity.kt index 2519f418da..dbba7c0a1f 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/editor/GameActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/editor/GameActivity.kt @@ -12,7 +12,7 @@ import com.gh.gamecenter.common.utils.updateStatusBarColor class GameActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun provideNormalIntent(): Intent { @@ -23,7 +23,7 @@ class GameActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/qa/editor/InsertAnswerWrapperActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/editor/InsertAnswerWrapperActivity.kt index 3a6d71c2d5..781d4ff69a 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/editor/InsertAnswerWrapperActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/editor/InsertAnswerWrapperActivity.kt @@ -13,7 +13,7 @@ class InsertAnswerWrapperActivity : BaseActivity_TabLayout() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun getLayoutId(): Int = R.layout.activity_tablayout_no_title_viewpager @@ -32,7 +32,7 @@ class InsertAnswerWrapperActivity : BaseActivity_TabLayout() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/qa/editor/InsertArticleWrapperActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/editor/InsertArticleWrapperActivity.kt index 796535ea25..2355f9e700 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/editor/InsertArticleWrapperActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/editor/InsertArticleWrapperActivity.kt @@ -13,7 +13,7 @@ class InsertArticleWrapperActivity : BaseActivity_TabLayout() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun getLayoutId(): Int = R.layout.activity_tablayout_no_title_viewpager @@ -31,7 +31,7 @@ class InsertArticleWrapperActivity : BaseActivity_TabLayout() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/qa/editor/InsertGameCollectionWrapperActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/editor/InsertGameCollectionWrapperActivity.kt index b86ad35b50..f645632665 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/editor/InsertGameCollectionWrapperActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/editor/InsertGameCollectionWrapperActivity.kt @@ -16,7 +16,7 @@ class InsertGameCollectionWrapperActivity : BaseActivity_TabLayout() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun getLayoutId(): Int = R.layout.activity_tablayout_no_title_viewpager @@ -52,7 +52,7 @@ class InsertGameCollectionWrapperActivity : BaseActivity_TabLayout() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/qa/editor/InsertVideoWrapperActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/editor/InsertVideoWrapperActivity.kt index d7f156c8f2..8f56d9f32e 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/editor/InsertVideoWrapperActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/editor/InsertVideoWrapperActivity.kt @@ -15,7 +15,7 @@ class InsertVideoWrapperActivity : BaseActivity_TabLayout() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun getLayoutId(): Int = R.layout.activity_tablayout_no_title_viewpager @@ -48,7 +48,7 @@ class InsertVideoWrapperActivity : BaseActivity_TabLayout() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/qa/editor/LocalMediaActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/editor/LocalMediaActivity.kt index 991ab8d344..eb16d71e39 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/editor/LocalMediaActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/editor/LocalMediaActivity.kt @@ -119,7 +119,7 @@ class LocalMediaActivity : ToolBarActivity(), AlbumCollection.AlbumCallbacks { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/qa/myqa/MyAskActivity.java b/app/src/main/java/com/gh/gamecenter/qa/myqa/MyAskActivity.java index d6180c0cdf..3d6edab778 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/myqa/MyAskActivity.java +++ b/app/src/main/java/com/gh/gamecenter/qa/myqa/MyAskActivity.java @@ -17,7 +17,7 @@ public class MyAskActivity extends ToolBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } @Override @@ -28,7 +28,7 @@ public class MyAskActivity extends ToolBarActivity { @Override protected void onNightModeChange() { super.onNightModeChange(); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } public static Intent getIntent(Context context) { diff --git a/app/src/main/java/com/gh/gamecenter/qa/questions/draft/QuestionDraftActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/questions/draft/QuestionDraftActivity.kt index ab218c4281..ab409c59e9 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/questions/draft/QuestionDraftActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/questions/draft/QuestionDraftActivity.kt @@ -11,14 +11,14 @@ class QuestionDraftActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun isAutoResetViewBackgroundEnabled(): Boolean = true override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/qa/questions/invite/QuestionsInviteActivity.java b/app/src/main/java/com/gh/gamecenter/qa/questions/invite/QuestionsInviteActivity.java index 8ece9290fa..50dedf9d3c 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/questions/invite/QuestionsInviteActivity.java +++ b/app/src/main/java/com/gh/gamecenter/qa/questions/invite/QuestionsInviteActivity.java @@ -24,7 +24,7 @@ public class QuestionsInviteActivity extends ToolBarActivity { @Override protected void onNightModeChange() { super.onNightModeChange(); - ExtensionsKt.updateStatusBarColor(this, R.color.text_292929, R.color.white); + ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); } public static Intent getIntent(Context context, QuestionsDetailEntity entity, String entrance) { diff --git a/app/src/main/java/com/gh/gamecenter/qa/questions/newdetail/NewQuestionDetailActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/questions/newdetail/NewQuestionDetailActivity.kt index c171c4790d..a4b2b961f9 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/questions/newdetail/NewQuestionDetailActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/questions/newdetail/NewQuestionDetailActivity.kt @@ -39,7 +39,7 @@ class NewQuestionDetailActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/qa/questions/newdetail/NewQuestionDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/questions/newdetail/NewQuestionDetailFragment.kt index 0e1a795eeb..1bb5773235 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/questions/newdetail/NewQuestionDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/questions/newdetail/NewQuestionDetailFragment.kt @@ -163,7 +163,7 @@ class NewQuestionDetailFragment : insets.systemWindowInsetTop insets.consumeSystemWindowInsets() } - mBinding.root.setBackgroundColor(Color.WHITE) + mBinding.root.setBackgroundColor(R.color.background_white.toColor(requireContext())) mSkeletonScreen = Skeleton.bind(skeletonView) .shimmer(true) .angle(Constants.SHIMMER_ANGLE) @@ -176,7 +176,7 @@ class NewQuestionDetailFragment : val bbsType = if (mViewModel.questionDetail?.type == "game_bbs") "游戏论坛" else "综合论坛" mBinding.inputContainer.replyTv.text = "说点什么吧" - mBinding.inputContainer.replyTv.setRoundedColorBackground(R.color.background, 19F) + mBinding.inputContainer.replyTv.setRoundedColorBackground(R.color.background_space_2, 19F) mBinding.inputContainer.replyTv.setDebouncedClickListener { clickToastByStatus(mViewModel.questionDetail?.status ?: "") { startCommentActivity() diff --git a/app/src/main/java/com/gh/gamecenter/qa/video/publish/VideoPublishActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/video/publish/VideoPublishActivity.kt index e3e3bfdc6a..f5f7df308f 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/video/publish/VideoPublishActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/video/publish/VideoPublishActivity.kt @@ -24,7 +24,7 @@ class VideoPublishActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/security/BindPhoneActivity.kt b/app/src/main/java/com/gh/gamecenter/security/BindPhoneActivity.kt index 2ac79ae8c3..3472ddd864 100644 --- a/app/src/main/java/com/gh/gamecenter/security/BindPhoneActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/security/BindPhoneActivity.kt @@ -15,14 +15,14 @@ class BindPhoneActivity : ToolBarActivity() { super.onCreate(savedInstanceState) hideToolbar(intent.extras?.getBundle(NORMAL_FRAGMENT_BUNDLE)?.getBoolean(EntranceConsts.KEY_FROM_LOGIN) == true) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun isAutoResetViewBackgroundEnabled() = true override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/security/SecurityActivity.kt b/app/src/main/java/com/gh/gamecenter/security/SecurityActivity.kt index 96eec2edd5..0be29fe608 100644 --- a/app/src/main/java/com/gh/gamecenter/security/SecurityActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/security/SecurityActivity.kt @@ -13,14 +13,14 @@ class SecurityActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setNavigationTitle(R.string.setting_security) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun isAutoResetViewBackgroundEnabled() = true override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/servers/GameServerTestActivity.kt b/app/src/main/java/com/gh/gamecenter/servers/GameServerTestActivity.kt index e1a558c5c9..c901674760 100644 --- a/app/src/main/java/com/gh/gamecenter/servers/GameServerTestActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/servers/GameServerTestActivity.kt @@ -13,7 +13,7 @@ class GameServerTestActivity : DownloadToolbarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setToolbarMenu(R.menu.menu_download) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun showDownloadMenu() = true @@ -24,7 +24,7 @@ class GameServerTestActivity : DownloadToolbarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/servers/GameServersActivity.kt b/app/src/main/java/com/gh/gamecenter/servers/GameServersActivity.kt index 398c35c456..558bbc75be 100644 --- a/app/src/main/java/com/gh/gamecenter/servers/GameServersActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/servers/GameServersActivity.kt @@ -47,7 +47,7 @@ class GameServersActivity : DownloadToolbarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) mServersTest = findViewById(R.id.server_test) mServersPublish = findViewById(R.id.server_publish) mViewpager = findViewById(R.id.viewpager) @@ -154,7 +154,7 @@ class GameServersActivity : DownloadToolbarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) mServersTest?.setTextColor(DrawableView.getSelectorColorStyle(R.color.text_black, R.color.theme_font, this)) mServersPublish?.setTextColor(DrawableView.getSelectorColorStyle(R.color.text_black, R.color.theme_font, this)) } diff --git a/app/src/main/java/com/gh/gamecenter/servers/add/AddKaiFuActivity.kt b/app/src/main/java/com/gh/gamecenter/servers/add/AddKaiFuActivity.kt index 98fbf87e7a..43511f53db 100644 --- a/app/src/main/java/com/gh/gamecenter/servers/add/AddKaiFuActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/servers/add/AddKaiFuActivity.kt @@ -52,7 +52,7 @@ class AddKaiFuActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) setNavigationTitle("新增开服") mSelectTime = intent.getLongExtra(EntranceConsts.KEY_KAIFU_SELECT_TIME, 0) @@ -202,7 +202,7 @@ class AddKaiFuActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) mBinding?.run { root.setBackgroundColor(R.color.background.toColor(this@AddKaiFuActivity)) container.setBackgroundColor(R.color.background_white.toColor(this@AddKaiFuActivity)) diff --git a/app/src/main/java/com/gh/gamecenter/servers/patch/PatchKaifuActivity.kt b/app/src/main/java/com/gh/gamecenter/servers/patch/PatchKaifuActivity.kt index e2f22b39c0..a82998e02c 100644 --- a/app/src/main/java/com/gh/gamecenter/servers/patch/PatchKaifuActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/servers/patch/PatchKaifuActivity.kt @@ -29,7 +29,7 @@ class PatchKaifuActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) setNavigationTitle("修改开服") mViewModel = ViewModelProviders.of(this).get(PatchKaifuViewModel::class.java) @@ -106,7 +106,7 @@ class PatchKaifuActivity : ToolBarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) mBinding?.run { root.setBackgroundColor(R.color.background.toColor(this@PatchKaifuActivity)) kaifuAddItemTitle.root.setBackgroundColor(R.color.title.toColor(this@PatchKaifuActivity)) diff --git a/app/src/main/java/com/gh/gamecenter/setting/GameDownloadSettingActivity.kt b/app/src/main/java/com/gh/gamecenter/setting/GameDownloadSettingActivity.kt index c523531e11..2e5ae3066b 100644 --- a/app/src/main/java/com/gh/gamecenter/setting/GameDownloadSettingActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/setting/GameDownloadSettingActivity.kt @@ -23,13 +23,13 @@ class GameDownloadSettingActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setNavigationTitle(R.string.setting_game_download) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun isAutoResetViewBackgroundEnabled() = true override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/setting/VideoSettingActivity.kt b/app/src/main/java/com/gh/gamecenter/setting/VideoSettingActivity.kt index dcfed7c348..42406841a2 100644 --- a/app/src/main/java/com/gh/gamecenter/setting/VideoSettingActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/setting/VideoSettingActivity.kt @@ -23,13 +23,13 @@ class VideoSettingActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setNavigationTitle(R.string.setting_video) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun isAutoResetViewBackgroundEnabled() = true override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/simulatorgame/SimulatorGameActivity.kt b/app/src/main/java/com/gh/gamecenter/simulatorgame/SimulatorGameActivity.kt index 1bf7891290..951c3da60f 100644 --- a/app/src/main/java/com/gh/gamecenter/simulatorgame/SimulatorGameActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/simulatorgame/SimulatorGameActivity.kt @@ -12,14 +12,14 @@ class SimulatorGameActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setNavigationTitle("模拟器游戏") - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun isAutoResetViewBackgroundEnabled() = true override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/simulatorgame/SimulatorManagementActivity.kt b/app/src/main/java/com/gh/gamecenter/simulatorgame/SimulatorManagementActivity.kt index ed687165f5..3610c18b23 100644 --- a/app/src/main/java/com/gh/gamecenter/simulatorgame/SimulatorManagementActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/simulatorgame/SimulatorManagementActivity.kt @@ -12,14 +12,14 @@ class SimulatorManagementActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setNavigationTitle("模拟器管理") - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun isAutoResetViewBackgroundEnabled() = true override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/subject/SubjectActivity.kt b/app/src/main/java/com/gh/gamecenter/subject/SubjectActivity.kt index 9364886ac1..6dc193ea99 100644 --- a/app/src/main/java/com/gh/gamecenter/subject/SubjectActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/subject/SubjectActivity.kt @@ -20,7 +20,7 @@ class SubjectActivity : DownloadToolbarActivity() { super.onCreate(savedInstanceState) val factory = SubjectViewModel.Factory(HaloApp.getInstance().application, intent.getParcelableExtra(EntranceConsts.KEY_SUBJECT_DATA)) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) mViewModel = ViewModelProviders.of(this, factory).get(SubjectViewModel::class.java) } @@ -39,7 +39,7 @@ class SubjectActivity : DownloadToolbarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/tag/TagsActivity.kt b/app/src/main/java/com/gh/gamecenter/tag/TagsActivity.kt index e4d68906e6..f9307065d3 100644 --- a/app/src/main/java/com/gh/gamecenter/tag/TagsActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/tag/TagsActivity.kt @@ -39,7 +39,7 @@ class TagsActivity : DownloadToolbarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setToolbarMenu(R.menu.menu_download) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun showDownloadMenu(): Boolean { @@ -52,7 +52,7 @@ class TagsActivity : DownloadToolbarActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } enum class From(val value: String) { diff --git a/app/src/main/java/com/gh/gamecenter/teenagermode/TeenagerModeActivity.kt b/app/src/main/java/com/gh/gamecenter/teenagermode/TeenagerModeActivity.kt index a24cb1240e..c145469c4b 100644 --- a/app/src/main/java/com/gh/gamecenter/teenagermode/TeenagerModeActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/teenagermode/TeenagerModeActivity.kt @@ -16,7 +16,7 @@ class TeenagerModeActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) mContainerFragment = supportFragmentManager.findFragmentByTag(TeenagerModeFragment::class.java.simpleName) ?: TeenagerModeFragment().with(intent.extras) if (mContainerFragment?.isAdded == false) { @@ -28,7 +28,7 @@ class TeenagerModeActivity : BaseActivity() { override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/toolbox/ToolBoxBlockActivity.kt b/app/src/main/java/com/gh/gamecenter/toolbox/ToolBoxBlockActivity.kt index f84ca17fea..42d44b27bb 100644 --- a/app/src/main/java/com/gh/gamecenter/toolbox/ToolBoxBlockActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/toolbox/ToolBoxBlockActivity.kt @@ -50,7 +50,7 @@ class ToolBoxBlockActivity : ToolBarActivity() { mSearchAdapter = ToolBoxItemAdapter(this, false, mViewModel) mLayoutManager = LinearLayoutManager(this@ToolBoxBlockActivity) setNavigationTitle("光环工具箱") - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) // 跳转到工具箱 https://gitlab.ghzs.com/pm/halo-app-issues/issues/636 val gameId = intent.getStringExtra(EntranceConsts.KEY_GAMEID) @@ -261,29 +261,15 @@ class ToolBoxBlockActivity : ToolBarActivity() { } } + override fun isAutoResetViewBackgroundEnabled(): Boolean = true + override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) if (::mBinding.isInitialized) { mBinding.run { toolboxRv.adapter?.run { notifyItemRangeChanged(0, itemCount) } - root.setBackgroundColor(R.color.background.toColor(this@ToolBoxBlockActivity)) - toolboxAppbar.setBackgroundColor(R.color.background.toColor(this@ToolBoxBlockActivity)) - toolboxRv.setBackgroundColor(R.color.background_white.toColor(this@ToolBoxBlockActivity)) feedbackCv.setCardBackgroundColor(R.color.background_white.toColor(this@ToolBoxBlockActivity)) - feedbackTv.setTextColor(R.color.text_subtitleDesc.toColor(this@ToolBoxBlockActivity)) - reuseSearchBar.run { - root.setBackgroundColor(R.color.background_white.toColor(this@ToolBoxBlockActivity)) - searchBackground.background = R.drawable.actionbar_search_bg.toDrawable(this@ToolBoxBlockActivity) - tvSearch.setTextColor(R.color.theme_font.toColor(this@ToolBoxBlockActivity)) - etSearch.setTextColor(R.color.text_title.toColor(this@ToolBoxBlockActivity)) - etSearch.setHintTextColor(R.color.text_body.toColor(this@ToolBoxBlockActivity)) - searchIv.setImageDrawable(R.drawable.toolbar_search_icon.toDrawable(this@ToolBoxBlockActivity)) - tvBack.setImageDrawable(R.drawable.ic_search_bar_clear.toDrawable(this@ToolBoxBlockActivity)) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - etSearch.textCursorDrawable = R.drawable.cursor_color.toDrawable(this@ToolBoxBlockActivity) - } - } } } } diff --git a/app/src/main/java/com/gh/gamecenter/toolbox/ToolBoxItemAdapter.kt b/app/src/main/java/com/gh/gamecenter/toolbox/ToolBoxItemAdapter.kt index b7603ab6c7..e87ba903be 100644 --- a/app/src/main/java/com/gh/gamecenter/toolbox/ToolBoxItemAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/toolbox/ToolBoxItemAdapter.kt @@ -83,7 +83,7 @@ class ToolBoxItemAdapter(context: Context, private val isBlockInside: Boolean = private fun initToolBoxViewHolder(viewHolder: ToolBoxViewHolder, toolBoxEntity: ToolBoxEntity) { viewHolder.binding.run { - divider.setBackgroundColor(R.color.F2F2F2.toColor(mContext)) + divider.setBackgroundColor(R.color.divider.toColor(mContext)) toolboxItemTitle.setTextColor(R.color.text_title.toColor(mContext)) toolboxItemDes.setTextColor(R.color.text_subtitleDesc.toColor(mContext)) } diff --git a/app/src/main/java/com/gh/gamecenter/video/videomanager/VideoDraftActivity.kt b/app/src/main/java/com/gh/gamecenter/video/videomanager/VideoDraftActivity.kt index c3e1b170ab..97f2922635 100644 --- a/app/src/main/java/com/gh/gamecenter/video/videomanager/VideoDraftActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/video/videomanager/VideoDraftActivity.kt @@ -12,14 +12,14 @@ class VideoDraftActivity : ToolBarActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setNavigationTitle("视频草稿") - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } override fun isAutoResetViewBackgroundEnabled(): Boolean =true override fun onNightModeChange() { super.onNightModeChange() - updateStatusBarColor(R.color.text_292929, R.color.white) + updateStatusBarColor(R.color.background_white, R.color.background_white) } companion object { fun getIntent(context: Context): Intent { diff --git a/app/src/main/java/com/gh/gamecenter/vote/VoteFragment.kt b/app/src/main/java/com/gh/gamecenter/vote/VoteFragment.kt index 512f4a5d67..a4db73b2ce 100644 --- a/app/src/main/java/com/gh/gamecenter/vote/VoteFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/vote/VoteFragment.kt @@ -355,20 +355,4 @@ class VoteFragment: ListFragment() { false } } - - override fun onNightModeChange() { - super.onNightModeChange() - mBinding.searchBarInclude.run { - root.setBackgroundColor(R.color.background_white.toColor(requireContext())) - searchBackground.background = R.drawable.actionbar_search_bg.toDrawable(requireContext()) - tvSearch.setTextColor(R.color.theme_font.toColor(requireContext())) - etSearch.setTextColor(R.color.text_title.toColor(requireContext())) - etSearch.setHintTextColor(R.color.text_body.toColor(requireContext())) - searchIv.setImageDrawable(R.drawable.toolbar_search_icon.toDrawable(requireContext())) - tvBack.setImageDrawable(R.drawable.ic_search_bar_clear.toDrawable(requireContext())) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - etSearch.textCursorDrawable = R.drawable.cursor_color.toDrawable(requireContext()) - } - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/halo/assistant/fragment/SwitchInstallMethodFragment.kt b/app/src/main/java/com/halo/assistant/fragment/SwitchInstallMethodFragment.kt index 4be91395d1..738d0f96e0 100644 --- a/app/src/main/java/com/halo/assistant/fragment/SwitchInstallMethodFragment.kt +++ b/app/src/main/java/com/halo/assistant/fragment/SwitchInstallMethodFragment.kt @@ -14,6 +14,8 @@ import com.gh.gamecenter.R import com.gh.gamecenter.WebActivity import com.gh.gamecenter.databinding.FragmentSwitchInstallMethodBinding import com.gh.gamecenter.common.base.fragment.ToolbarFragment +import com.gh.gamecenter.common.utils.toColor +import com.gh.gamecenter.common.utils.updateStatusBarColor import java.util.* /** @@ -29,6 +31,7 @@ class SwitchInstallMethodFragment : ToolbarFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + requireActivity().updateStatusBarColor(R.color.background_white, R.color.background_white) initView() changeSwitch(SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL)) @@ -115,4 +118,13 @@ class SwitchInstallMethodFragment : ToolbarFragment() { } } + override fun onNightModeChange() { + super.onNightModeChange() + requireActivity().updateStatusBarColor(R.color.background_white, R.color.background_white) + mBinding?.toolbar?.run { + normalToolbar.setBackgroundColor(R.color.background_white.toColor(requireContext())) + backBtn.setImageResource(R.drawable.ic_bar_back) + normalTitle.setTextColor(R.color.text_title.toColor(requireContext())) + } + } } \ No newline at end of file diff --git a/app/src/main/res/drawable-xxhdpi/community_edit_article.webp b/app/src/main/res/drawable-xxhdpi/community_edit_article.webp deleted file mode 100644 index 5fb8624587ee1de8eb52699ee3d2a4e7a91ca90e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7496 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 G5r6=_y(m=x diff --git a/app/src/main/res/drawable-xxhdpi/community_edit_video.webp b/app/src/main/res/drawable-xxhdpi/community_edit_video.webp deleted file mode 100644 index 2a7459bff8e36b368c6aa808a4f1bbba79428c26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6944 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 A{r~^~ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/community_edit_question.webp b/app/src/main/res/drawable-xxxhdpi/community_edit_question.webp new file mode 100644 index 0000000000000000000000000000000000000000..d3233ba9a84062a54757df75629d7722f445ed66 GIT binary patch literal 5996 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/actionbar_search_bg.xml b/app/src/main/res/drawable/actionbar_search_bg.xml index 8d70c7fe6d..963cd94d81 100644 --- a/app/src/main/res/drawable/actionbar_search_bg.xml +++ b/app/src/main/res/drawable/actionbar_search_bg.xml @@ -4,6 +4,6 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_shape_space2_radius_4.xml b/app/src/main/res/drawable/bg_shape_space2_radius_4.xml new file mode 100644 index 0000000000..4d7009e867 --- /dev/null +++ b/app/src/main/res/drawable/bg_shape_space2_radius_4.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_shape_space2_radius_999.xml b/app/src/main/res/drawable/bg_shape_space2_radius_999.xml new file mode 100644 index 0000000000..6d5ba0aaa9 --- /dev/null +++ b/app/src/main/res/drawable/bg_shape_space2_radius_999.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/download_dialog_background.xml b/app/src/main/res/drawable/download_dialog_background.xml index 503ee0fcb5..434b7cee5e 100644 --- a/app/src/main/res/drawable/download_dialog_background.xml +++ b/app/src/main/res/drawable/download_dialog_background.xml @@ -1,6 +1,6 @@ - + - + \ No newline at end of file diff --git a/app/src/main/res/drawable/home_amway_rating_unselect.xml b/app/src/main/res/drawable/home_amway_rating_unselect.xml index 708ae6b901..f20e7234cf 100644 --- a/app/src/main/res/drawable/home_amway_rating_unselect.xml +++ b/app/src/main/res/drawable/home_amway_rating_unselect.xml @@ -2,7 +2,7 @@ - + - + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_suggest.xml b/app/src/main/res/layout/activity_suggest.xml index 955b097e57..d2f9071368 100644 --- a/app/src/main/res/layout/activity_suggest.xml +++ b/app/src/main/res/layout/activity_suggest.xml @@ -4,6 +4,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="@color/background" android:orientation="vertical"> diff --git a/app/src/main/res/layout/activity_toolbox_block.xml b/app/src/main/res/layout/activity_toolbox_block.xml index 22785e7e0e..5666d3581f 100644 --- a/app/src/main/res/layout/activity_toolbox_block.xml +++ b/app/src/main/res/layout/activity_toolbox_block.xml @@ -3,6 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="@color/background" android:orientation="vertical"> diff --git a/app/src/main/res/layout/common_collection_item.xml b/app/src/main/res/layout/common_collection_item.xml index 11838098b6..9846ba5df8 100644 --- a/app/src/main/res/layout/common_collection_item.xml +++ b/app/src/main/res/layout/common_collection_item.xml @@ -86,7 +86,7 @@ android:layout_marginTop="8dp" android:ellipsize="end" android:maxLines="1" - android:textColor="@color/black" + android:textColor="@color/text_title" android:textSize="14sp" android:visibility="gone" /> diff --git a/app/src/main/res/layout/fm_search_history_item.xml b/app/src/main/res/layout/fm_search_history_item.xml index 3d60cd91ea..949f4d2ca7 100644 --- a/app/src/main/res/layout/fm_search_history_item.xml +++ b/app/src/main/res/layout/fm_search_history_item.xml @@ -21,7 +21,7 @@ android:gravity="center_vertical" android:padding="16dp" android:singleLine="true" - android:textColor="@color/bg_303030" + android:textColor="@color/text_title" android:textSize="14sp" /> diff --git a/app/src/main/res/layout/forum_activity_item.xml b/app/src/main/res/layout/forum_activity_item.xml index b5652380a7..e72226b1c1 100644 --- a/app/src/main/res/layout/forum_activity_item.xml +++ b/app/src/main/res/layout/forum_activity_item.xml @@ -46,7 +46,7 @@ android:layout_height="16dp" android:layout_marginTop="8dp" android:layout_marginLeft="16dp" - app:cardBackgroundColor="@color/bg_FFF3EB" + app:cardBackgroundColor="@color/bg_1AFA8850" app:contentPaddingRight="4dp" app:cardCornerRadius="3dp" app:cardElevation="0dp" diff --git a/app/src/main/res/layout/fragment_login.xml b/app/src/main/res/layout/fragment_login.xml index 2bae70aa61..61e84029cf 100644 --- a/app/src/main/res/layout/fragment_login.xml +++ b/app/src/main/res/layout/fragment_login.xml @@ -46,7 +46,7 @@ android:paddingTop="10dp" android:paddingBottom="10dp" android:paddingRight="16dp" - android:textColor="@color/black" + android:textColor="@color/text_title" android:textColorHint="@color/text_body" android:textCursorDrawable="@drawable/cursor_color" android:textSize="14sp" /> @@ -73,7 +73,7 @@ android:maxLength="8" android:paddingTop="10dp" android:paddingBottom="10dp" - android:textColor="@color/black" + android:textColor="@color/text_title" android:textColorHint="@color/text_body" android:textCursorDrawable="@drawable/cursor_color" android:textSize="14sp" /> @@ -111,7 +111,7 @@ android:hint="@string/input_invite_code_hint" android:paddingTop="10dp" android:paddingBottom="10dp" - android:textColor="@color/black" + android:textColor="@color/text_title" android:textColorHint="@color/text_body" android:textCursorDrawable="@drawable/cursor_color" android:textSize="14sp" /> diff --git a/app/src/main/res/layout/fragment_switch_install_method.xml b/app/src/main/res/layout/fragment_switch_install_method.xml index 16abbe2bc3..25938e7fe9 100644 --- a/app/src/main/res/layout/fragment_switch_install_method.xml +++ b/app/src/main/res/layout/fragment_switch_install_method.xml @@ -3,7 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/bg_F7F7F7"> + android:background="@color/background"> \ No newline at end of file diff --git a/app/src/main/res/layout/layout_search_game_content_tag.xml b/app/src/main/res/layout/layout_search_game_content_tag.xml index f62cc69e74..a532c8bf9b 100644 --- a/app/src/main/res/layout/layout_search_game_content_tag.xml +++ b/app/src/main/res/layout/layout_search_game_content_tag.xml @@ -5,7 +5,7 @@ android:layout_width="76dp" android:layout_height="28dp" android:gravity="center" - android:background="@drawable/bg_shape_f5_radius_4"> + android:background="@drawable/bg_shape_space2_radius_4"> diff --git a/app/src/main/res/layout/piece_article_input_container.xml b/app/src/main/res/layout/piece_article_input_container.xml index f515f2a7f8..a5158f521d 100644 --- a/app/src/main/res/layout/piece_article_input_container.xml +++ b/app/src/main/res/layout/piece_article_input_container.xml @@ -17,7 +17,7 @@ android:layout_height="32dp" android:layout_marginLeft="16dp" android:layout_marginRight="28dp" - android:background="@drawable/bg_shape_f5_radius_999" + android:background="@drawable/bg_shape_space2_radius_999" android:gravity="center_vertical" android:includeFontPadding="false" android:maxLines="1" diff --git a/app/src/main/res/layout/search_game_index_item.xml b/app/src/main/res/layout/search_game_index_item.xml index 5778505776..d81781de5e 100644 --- a/app/src/main/res/layout/search_game_index_item.xml +++ b/app/src/main/res/layout/search_game_index_item.xml @@ -34,6 +34,6 @@ android:layout_height="1dp" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" - android:background="@color/background" + android:background="@color/divider" android:visibility="gone" /> \ No newline at end of file diff --git a/app/src/main/res/layout/user_history_item.xml b/app/src/main/res/layout/user_history_item.xml index 9c8b8062b0..b250869275 100644 --- a/app/src/main/res/layout/user_history_item.xml +++ b/app/src/main/res/layout/user_history_item.xml @@ -164,7 +164,7 @@ android:paddingLeft="12dp" android:paddingRight="12dp" android:paddingBottom="10dp" - android:background="@drawable/bg_shape_f8_radius_8" + android:background="@drawable/bg_shape_space_radius_8" android:ellipsize="end" android:includeFontPadding="false" android:lineSpacingExtra="6dp" diff --git a/module_common/src/main/java/com/gh/gamecenter/common/base/CustomLayoutInflaterFactory.kt b/module_common/src/main/java/com/gh/gamecenter/common/base/CustomLayoutInflaterFactory.kt index 6ef4461e3a..05751f14c5 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/base/CustomLayoutInflaterFactory.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/base/CustomLayoutInflaterFactory.kt @@ -33,7 +33,8 @@ class CustomLayoutInflaterFactory( val attributeName = attrs.getAttributeName(i).toString() when { attributeName.contains("background") -> view?.setTag(TAG_BACKGROUND_ID, attrs.getAttributeValue(i)) - attributeName.contains("textColor") -> view?.setTag(TAG_TEXT_COLOR_ID, attrs.getAttributeValue(i)) + attributeName == "textColor" -> view?.setTag(TAG_TEXT_COLOR_ID, attrs.getAttributeValue(i)) + attributeName == "textColorHint" -> view?.setTag(TAG_TEXT_COLOR_HINT_ID, attrs.getAttributeValue(i)) attributeName.contains("src") -> view?.setTag(TAG_SRC_ID, attrs.getAttributeValue(i)) attributeName.contains("drawableLeft") || attributeName.contains("drawableStart") -> view?.setTag(TAG_DRAWABLE_LEFT_ID, attrs.getAttributeValue(i)) attributeName.contains("drawableTop") -> view?.setTag(TAG_DRAWABLE_TOP_ID, attrs.getAttributeValue(i)) @@ -52,6 +53,7 @@ class CustomLayoutInflaterFactory( companion object { var TAG_BACKGROUND_ID = R.string.background_id var TAG_TEXT_COLOR_ID = R.string.text_color_id + var TAG_TEXT_COLOR_HINT_ID = R.string.text_color_hint_id var TAG_SRC_ID = R.string.src_id var TAG_DRAWABLE_LEFT_ID = R.string.drawable_left_id var TAG_DRAWABLE_TOP_ID = R.string.drawable_top_id diff --git a/module_common/src/main/java/com/gh/gamecenter/common/base/activity/BaseActivity.java b/module_common/src/main/java/com/gh/gamecenter/common/base/activity/BaseActivity.java index 6b77e51dd1..e94163dd4a 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/base/activity/BaseActivity.java +++ b/module_common/src/main/java/com/gh/gamecenter/common/base/activity/BaseActivity.java @@ -22,6 +22,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; +import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; @@ -67,6 +68,7 @@ import com.lightgame.BaseAppCompatActivity; import com.lightgame.download.DownloadEntity; import com.lightgame.download.FileUtils; import com.lightgame.utils.Utils; +import com.lightgame.view.CheckableImageView; import com.tencent.tauth.Tencent; import org.greenrobot.eventbus.EventBus; @@ -570,6 +572,7 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy String backgroundString = (String) view.getTag(CustomLayoutInflaterFactory.Companion.getTAG_BACKGROUND_ID()); String textColorString = (String) view.getTag(CustomLayoutInflaterFactory.Companion.getTAG_TEXT_COLOR_ID()); + String textColorHintString = (String) view.getTag(CustomLayoutInflaterFactory.Companion.getTAG_TEXT_COLOR_HINT_ID()); String srcString = (String) view.getTag(CustomLayoutInflaterFactory.Companion.getTAG_SRC_ID()); String drawableLeftString = (String) view.getTag(CustomLayoutInflaterFactory.Companion.getTAG_DRAWABLE_LEFT_ID()); String drawableTopString = (String) view.getTag(CustomLayoutInflaterFactory.Companion.getTAG_DRAWABLE_TOP_ID()); @@ -619,6 +622,24 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy } } + if (textColorHintString != null && view instanceof EditText) { + if (textColorHintString.startsWith("#")) return; + int textColorHintId = Integer.parseInt( + textColorHintString + .replace("@", "") + .replace("?", "") + ); + + if (textColorHintId != 0) { + try { + final ColorStateList colorStateList = ContextCompat.getColorStateList(context, textColorHintId); + ((EditText) view).setHintTextColor(colorStateList); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + if (view instanceof ImageView && srcString != null) { if (srcString.startsWith("#")) return; int srcId = Integer.parseInt( diff --git a/module_common/src/main/res/values-night/colors.xml b/module_common/src/main/res/values-night/colors.xml index 07dc9b9fac..f259427c39 100644 --- a/module_common/src/main/res/values-night/colors.xml +++ b/module_common/src/main/res/values-night/colors.xml @@ -36,11 +36,12 @@ #7AFFFFFF - #121212 + #1A1A1A - #08FFFFFF + #2C2C2C + #0AFFFFFF - #292929 + #232323 #00121212 #333333 @@ -98,7 +99,7 @@ #2EC991 - #ECECEC + @color/transparent #30000000 diff --git a/module_common/src/main/res/values/colors.xml b/module_common/src/main/res/values/colors.xml index a4b140d4de..7568981473 100644 --- a/module_common/src/main/res/values/colors.xml +++ b/module_common/src/main/res/values/colors.xml @@ -40,6 +40,7 @@ #F5F5F5 @color/bg_F8F8F8 + @color/background #FFFFFF #00F5F5F5 @@ -99,7 +100,7 @@ #2EC991 - #ECECEC + @color/transparent #30000000 @@ -324,7 +325,7 @@ #07B896 #279BFE #C4C4C4 - #FFF3EB + #1AFA8850 #F5F6F7 #46DBAA #FA8850 diff --git a/module_common/src/main/res/values/strings.xml b/module_common/src/main/res/values/strings.xml index 5c7244421b..3b293bb516 100644 --- a/module_common/src/main/res/values/strings.xml +++ b/module_common/src/main/res/values/strings.xml @@ -26,6 +26,7 @@ background_id text_color_id + text_color_hint_id src_id drawable_left_id drawable_top_id From dfba5cdf99c25e5aaa69654413e59ce907e056a9 Mon Sep 17 00:00:00 2001 From: leafwai Date: Wed, 6 Jul 2022 14:54:30 +0800 Subject: [PATCH 082/217] =?UTF-8?q?fix:=E3=80=90=E5=A4=9C=E9=97=B4?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E3=80=91UI=E6=B5=8B=E8=AF=95=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E9=97=AE=E9=A2=98=E6=B1=87=E6=80=BB=EF=BC=887?= =?UTF-8?q?=E6=9C=88=E7=AC=AC1=E5=91=A8=EF=BC=89=EF=BC=88=E7=AC=AC6?= =?UTF-8?q?=E7=82=B9=E9=81=97=E6=BC=8F=EF=BC=89https://git.shanqu.cc/pm/ha?= =?UTF-8?q?lo/halo-app-issues/-/issues/1957?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/search_subject_item.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/layout/search_subject_item.xml b/app/src/main/res/layout/search_subject_item.xml index 8effa1127d..934e162298 100644 --- a/app/src/main/res/layout/search_subject_item.xml +++ b/app/src/main/res/layout/search_subject_item.xml @@ -60,6 +60,6 @@ android:layout_height="1dp" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" - android:background="@color/background" + android:background="@color/divider" android:visibility="gone" /> From 8756144018a6d87a1a9361292bde3c13c6de4b08 Mon Sep 17 00:00:00 2001 From: leafwai Date: Wed, 6 Jul 2022 15:11:39 +0800 Subject: [PATCH 083/217] =?UTF-8?q?fix:=E3=80=90=E5=A4=9C=E9=97=B4?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E3=80=91UI=E6=B5=8B=E8=AF=95=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E9=97=AE=E9=A2=98=E6=B1=87=E6=80=BB=EF=BC=887?= =?UTF-8?q?=E6=9C=88=E7=AC=AC1=E5=91=A8=EF=BC=89=EF=BC=88=E7=AC=AC6?= =?UTF-8?q?=E7=82=B9=E9=81=97=E6=BC=8F=EF=BC=89https://git.shanqu.cc/pm/ha?= =?UTF-8?q?lo/halo-app-issues/-/issues/1957?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/search_subject_item.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/layout/search_subject_item.xml b/app/src/main/res/layout/search_subject_item.xml index 934e162298..f3efe56640 100644 --- a/app/src/main/res/layout/search_subject_item.xml +++ b/app/src/main/res/layout/search_subject_item.xml @@ -12,7 +12,7 @@ android:layout_height="1dp" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" - android:background="@color/background" + android:background="@color/divider" android:visibility="gone" /> Date: Mon, 11 Jul 2022 10:16:23 +0800 Subject: [PATCH 084/217] =?UTF-8?q?fix:=E3=80=90=E5=A4=9C=E9=97=B4?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E3=80=91UI=E6=B5=8B=E8=AF=95=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E9=97=AE=E9=A2=98=E6=B1=87=E6=80=BB=EF=BC=887?= =?UTF-8?q?=E6=9C=88=E7=AC=AC1=E5=91=A8=EF=BC=89=EF=BC=880706=E8=A1=A5?= =?UTF-8?q?=E5=85=85=EF=BC=89https://git.shanqu.cc/pm/halo/halo-app-issues?= =?UTF-8?q?/-/issues/1957?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assets/lottie/switch_turnoff_dark.json | 1 + .../assets/lottie/switch_turnoff_light.json | 1 + app/src/main/assets/lottie/switch_turnon.json | 1 - .../assets/lottie/switch_turnon_dark.json | 1 + .../assets/lottie/switch_turnon_light.json | 1 + .../download/dialog/DownloadDialogAdapter.kt | 4 +- .../forum/detail/ForumDetailFragment.kt | 2 +- ...meCollectionCommentConversationFragment.kt | 2 +- .../square/GameCollectionSquareFragment.kt | 2 +- .../qa/comment/base/BaseCommentAdapter.kt | 2 +- .../setting/GameDownloadSettingFragment.kt | 10 ++- .../setting/VideoSettingActivity.kt | 5 ++ .../setting/VideoSettingFragment.kt | 64 +++++++++++------- .../assistant/fragment/SettingsFragment.kt | 17 ++--- .../fragment/SwitchInstallMethodFragment.kt | 7 +- .../download_dialog_installed_background.xml | 8 +++ ...download_dialog_status_collection_gray.xml | 10 +++ .../download_dialog_status_download_gray.xml | 10 +++ .../download_dialog_version_note.xml | 11 +++ .../download_recommend_des_bg.xml | 10 +++ .../drawable-night/ic_selector_default.xml | 11 +++ app/src/main/res/drawable-night/icon_more.xml | 13 ++++ .../download_dialog_status_collection.png | Bin 407 -> 0 bytes ...download_dialog_status_collection_gray.png | Bin 411 -> 0 bytes .../download_dialog_status_download.png | Bin 457 -> 0 bytes .../download_dialog_status_download_gray.png | Bin 437 -> 0 bytes .../download_dialog_status_pause.png | Bin 572 -> 0 bytes .../main/res/drawable-xxxhdpi/icon_more.png | Bin 527 -> 0 bytes .../bg_download_dialog_item_recommend.xml | 7 +- .../res/drawable/bg_forum_welfare_item.xml | 2 +- .../bg_game_collection_sfv_indicator.xml | 5 ++ .../download_dialog_item_progress.xml | 10 +-- .../download_dialog_status_collection.xml | 10 +++ ...download_dialog_status_collection_gray.xml | 10 +++ .../download_dialog_status_download.xml | 10 +++ .../download_dialog_status_download_gray.xml | 10 +++ .../drawable/download_dialog_status_pause.xml | 10 +++ .../drawable/download_dialog_version_note.xml | 2 +- .../main/res/drawable/ic_selector_default.xml | 11 +++ app/src/main/res/drawable/icon_more.xml | 13 ++++ .../progressbar_game_collection_primary.xml | 2 +- .../main/res/layout/download_dialog_item.xml | 6 +- app/src/main/res/layout/forum_my_follow.xml | 3 +- .../main/res/layout/fragment_forum_detail.xml | 4 +- .../fragment_game_collection_square.xml | 2 +- .../layout/fragment_video_comment_list.xml | 2 +- .../layout/item_article_detail_comment.xml | 2 +- .../main/res/layout/layout_setting_item.xml | 4 +- .../piece_article_detail_comment_filter.xml | 2 +- .../gh/gamecenter/common/utils/Extensions.kt | 14 ++++ 50 files changed, 261 insertions(+), 73 deletions(-) create mode 100644 app/src/main/assets/lottie/switch_turnoff_dark.json create mode 100644 app/src/main/assets/lottie/switch_turnoff_light.json delete mode 100644 app/src/main/assets/lottie/switch_turnon.json create mode 100644 app/src/main/assets/lottie/switch_turnon_dark.json create mode 100644 app/src/main/assets/lottie/switch_turnon_light.json create mode 100644 app/src/main/res/drawable-night/download_dialog_installed_background.xml create mode 100644 app/src/main/res/drawable-night/download_dialog_status_collection_gray.xml create mode 100644 app/src/main/res/drawable-night/download_dialog_status_download_gray.xml create mode 100644 app/src/main/res/drawable-night/download_dialog_version_note.xml create mode 100644 app/src/main/res/drawable-night/download_recommend_des_bg.xml create mode 100644 app/src/main/res/drawable-night/ic_selector_default.xml create mode 100644 app/src/main/res/drawable-night/icon_more.xml delete mode 100644 app/src/main/res/drawable-xxhdpi/download_dialog_status_collection.png delete mode 100644 app/src/main/res/drawable-xxhdpi/download_dialog_status_collection_gray.png delete mode 100644 app/src/main/res/drawable-xxhdpi/download_dialog_status_download.png delete mode 100644 app/src/main/res/drawable-xxhdpi/download_dialog_status_download_gray.png delete mode 100644 app/src/main/res/drawable-xxhdpi/download_dialog_status_pause.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/icon_more.png create mode 100644 app/src/main/res/drawable/bg_game_collection_sfv_indicator.xml create mode 100644 app/src/main/res/drawable/download_dialog_status_collection.xml create mode 100644 app/src/main/res/drawable/download_dialog_status_collection_gray.xml create mode 100644 app/src/main/res/drawable/download_dialog_status_download.xml create mode 100644 app/src/main/res/drawable/download_dialog_status_download_gray.xml create mode 100644 app/src/main/res/drawable/download_dialog_status_pause.xml create mode 100644 app/src/main/res/drawable/ic_selector_default.xml create mode 100644 app/src/main/res/drawable/icon_more.xml diff --git a/app/src/main/assets/lottie/switch_turnoff_dark.json b/app/src/main/assets/lottie/switch_turnoff_dark.json new file mode 100644 index 0000000000..4e0290ccb4 --- /dev/null +++ b/app/src/main/assets/lottie/switch_turnoff_dark.json @@ -0,0 +1 @@ +{"v":"5.9.1","fr":60,"ip":0,"op":36,"w":120,"h":66,"nm":"开关动画-关闭","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"按钮手柄","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.667,"y":0},"t":0,"s":[87,33,0],"to":[7.682,0,0],"ti":[-13.443,0,0]},{"i":{"x":0.333,"y":1},"o":{"x":0.333,"y":0},"t":18,"s":[31,33,0],"to":[2.306,0,0],"ti":[-1.318,0,0]},{"t":24,"s":[33,33,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"指示器-on","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.667],"y":[0]},"t":0,"s":[100]},{"t":18,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.667,0.667],"y":[0,0]},"t":0,"s":[6.5,6.5]},{"t":18,"s":[4.5,4.5]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":40,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"指示器-off","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[87,33,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.667,0.667],"y":[0,0]},"t":0,"s":[1.5,4]},{"t":18,"s":[1.5,6]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0.75,"ix":4},"nm":"矩形路径 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":20,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":90,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.667],"y":[0]},"t":0,"s":[0]},{"t":18,"s":[100]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"按钮背景","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[60,33,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[40,22],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12,"ix":4},"nm":"矩形路径 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.667],"y":[0]},"t":0,"s":[0.156862750649,0.533333361149,0.878431379795,1]},{"t":18,"s":[1,1,1,1]}],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.667],"y":[0]},"t":0,"s":[100]},{"t":18,"s":[8]}],"ix":5},"r":1,"bm":0,"nm":"filling","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0.118,0.006],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/app/src/main/assets/lottie/switch_turnoff_light.json b/app/src/main/assets/lottie/switch_turnoff_light.json new file mode 100644 index 0000000000..7b0d088767 --- /dev/null +++ b/app/src/main/assets/lottie/switch_turnoff_light.json @@ -0,0 +1 @@ +{"v":"5.9.1","fr":60,"ip":0,"op":36,"w":120,"h":66,"nm":"开关动画-关闭","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"按钮手柄","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.667,"y":0},"t":0,"s":[87,33,0],"to":[7.682,0,0],"ti":[-13.443,0,0]},{"i":{"x":0.333,"y":1},"o":{"x":0.333,"y":0},"t":18,"s":[31,33,0],"to":[2.306,0,0],"ti":[-1.318,0,0]},{"t":24,"s":[33,33,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"指示器-on","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.667],"y":[0]},"t":0,"s":[100]},{"t":18,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.667,0.667],"y":[0,0]},"t":0,"s":[6.5,6.5]},{"t":18,"s":[4.5,4.5]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":40,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"指示器-off","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[87,33,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.667,0.667],"y":[0,0]},"t":0,"s":[1.5,4]},{"t":18,"s":[1.5,6]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0.75,"ix":4},"nm":"矩形路径 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":5,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":90,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.667],"y":[0]},"t":0,"s":[0]},{"t":18,"s":[100]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"按钮背景","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[60,33,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[40,22],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12,"ix":4},"nm":"矩形路径 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.667],"y":[0]},"t":0,"s":[0.141176477075,0.588235318661,1,1]},{"t":18,"s":[0.933333337307,0.933333337307,0.933333337307,1]}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"filling","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0.118,0.006],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/app/src/main/assets/lottie/switch_turnon.json b/app/src/main/assets/lottie/switch_turnon.json deleted file mode 100644 index ae34bc0d48..0000000000 --- a/app/src/main/assets/lottie/switch_turnon.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.6.9","fr":60,"ip":0,"op":36,"w":120,"h":66,"nm":"开关动画-打开","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"按钮手柄","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.667,"y":0},"t":0,"s":[33,33,0],"to":[7.682,0,0],"ti":[-13.443,0,0]},{"i":{"x":0.333,"y":1},"o":{"x":0.333,"y":0},"t":18,"s":[89,33,0],"to":[2.306,0,0],"ti":[-1.318,0,0]},{"t":24,"s":[87,33,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"指示器-on","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.667],"y":[0]},"t":0,"s":[0]},{"t":18,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.667,0.667],"y":[0,0]},"t":0,"s":[4.5,4.5]},{"t":18,"s":[6.5,6.5]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.966666666667,0.966666666667,0.966666666667,0.420000005762],"ix":3},"o":{"a":0,"k":40,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"指示器-off","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[87,33,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.667,0.667],"y":[0,0]},"t":0,"s":[1.5,6]},{"t":18,"s":[1.5,4]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0.75,"ix":4},"nm":"矩形路径 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":5,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":90,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.667],"y":[0]},"t":0,"s":[100]},{"t":18,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"按钮背景","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[60,33,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"sy":[{"c":{"a":0,"k":[0,0,0,1],"ix":2},"o":{"a":0,"k":5,"ix":3},"a":{"a":0,"k":120,"ix":5},"s":{"a":0,"k":1,"ix":8},"d":{"a":0,"k":0,"ix":6},"ch":{"a":0,"k":100,"ix":7},"bm":{"a":0,"k":5,"ix":1},"no":{"a":0,"k":0,"ix":9},"ty":2,"nm":"内阴影"}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[40,22],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12,"ix":4},"nm":"矩形路径 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.667],"y":[0]},"t":0,"s":[0.933332979679,0.933332979679,0.933332979679,1]},{"t":18,"s":[0.141176477075,0.588235318661,1,1]}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"filling","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0.118,0.006],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/app/src/main/assets/lottie/switch_turnon_dark.json b/app/src/main/assets/lottie/switch_turnon_dark.json new file mode 100644 index 0000000000..a897cea988 --- /dev/null +++ b/app/src/main/assets/lottie/switch_turnon_dark.json @@ -0,0 +1 @@ +{"v":"5.9.1","fr":60,"ip":0,"op":36,"w":120,"h":66,"nm":"开关动画-打开","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"按钮手柄","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.667,"y":0},"t":0,"s":[33,33,0],"to":[7.682,0,0],"ti":[-13.443,0,0]},{"i":{"x":0.333,"y":1},"o":{"x":0.333,"y":0},"t":18,"s":[89,33,0],"to":[2.306,0,0],"ti":[-1.318,0,0]},{"t":24,"s":[87,33,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"指示器-on","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.667],"y":[0]},"t":0,"s":[0]},{"t":18,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.667,0.667],"y":[0,0]},"t":0,"s":[4.5,4.5]},{"t":18,"s":[6.5,6.5]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":40,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"指示器-off","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[87,33,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.667,0.667],"y":[0,0]},"t":0,"s":[1.5,6]},{"t":18,"s":[1.5,4]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0.75,"ix":4},"nm":"矩形路径 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":20,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":90,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.667],"y":[0]},"t":0,"s":[100]},{"t":18,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"按钮背景","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[60,33,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[40,22],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12,"ix":4},"nm":"矩形路径 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.667],"y":[0]},"t":0,"s":[1,1,1,1]},{"t":18,"s":[0.156862750649,0.533333361149,0.878431379795,1]}],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.667],"y":[0]},"t":0,"s":[8]},{"t":18,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"filling","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0.118,0.006],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/app/src/main/assets/lottie/switch_turnon_light.json b/app/src/main/assets/lottie/switch_turnon_light.json new file mode 100644 index 0000000000..31f139b617 --- /dev/null +++ b/app/src/main/assets/lottie/switch_turnon_light.json @@ -0,0 +1 @@ +{"v":"5.9.1","fr":60,"ip":0,"op":36,"w":120,"h":66,"nm":"开关动画-打开","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"按钮手柄","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.667,"y":0},"t":0,"s":[33,33,0],"to":[7.682,0,0],"ti":[-13.443,0,0]},{"i":{"x":0.333,"y":1},"o":{"x":0.333,"y":0},"t":18,"s":[89,33,0],"to":[2.306,0,0],"ti":[-1.318,0,0]},{"t":24,"s":[87,33,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[16,16],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"指示器-on","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.667],"y":[0]},"t":0,"s":[0]},{"t":18,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.667,0.667],"y":[0,0]},"t":0,"s":[4.5,4.5]},{"t":18,"s":[6.5,6.5]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":40,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"指示器-off","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[87,33,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.667,0.667],"y":[0,0]},"t":0,"s":[1.5,6]},{"t":18,"s":[1.5,4]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0.75,"ix":4},"nm":"矩形路径 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":5,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":90,"ix":6},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.667],"y":[0]},"t":0,"s":[100]},{"t":18,"s":[0]}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"按钮背景","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[60,33,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[40,22],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":12,"ix":4},"nm":"矩形路径 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.667],"y":[0]},"t":0,"s":[0.933332979679,0.933332979679,0.933332979679,1]},{"t":18,"s":[0.141176477075,0.588235318661,1,1]}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"filling","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0.118,0.006],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":37,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/app/src/main/java/com/gh/download/dialog/DownloadDialogAdapter.kt b/app/src/main/java/com/gh/download/dialog/DownloadDialogAdapter.kt index 8ddb08ae09..cf2ec826d9 100644 --- a/app/src/main/java/com/gh/download/dialog/DownloadDialogAdapter.kt +++ b/app/src/main/java/com/gh/download/dialog/DownloadDialogAdapter.kt @@ -125,11 +125,11 @@ class DownloadDialogAdapter( rightLink.text = if (links?.size ?: 0 > 1) links?.get(1)?.title else "" leftLink.background = GradientDrawable().apply { cornerRadius = 8F.dip2px().toFloat() - setStroke(0.5F.dip2px(), R.color.divider.toColor()) + setStroke(0.5F.dip2px(), R.color.divider.toColor(mContext)) } rightLink.background = GradientDrawable().apply { cornerRadius = 8F.dip2px().toFloat() - setStroke(0.5F.dip2px(), R.color.divider.toColor()) + setStroke(0.5F.dip2px(), R.color.divider.toColor(mContext)) } } } diff --git a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailFragment.kt index cc1ab90948..1033114957 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailFragment.kt @@ -798,7 +798,7 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable { updateToolbarStyle(mIsToolbarWhite) mBinding.allOrderSfv.run { setContainerBackground(R.drawable.button_round_f5f5f5.toDrawable(requireContext())) - setIndicatorBackground(R.drawable.progressbar_game_collection_primary.toDrawable(requireContext())) + setIndicatorBackground(R.drawable.bg_game_collection_sfv_indicator.toDrawable(requireContext())) setTextColor(ContextCompat.getColorStateList(context, R.color.game_collection_rg_button_selector)) } } diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/detail/conversation/GameCollectionCommentConversationFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/detail/conversation/GameCollectionCommentConversationFragment.kt index 25a7f929b3..4cf9cc0d2e 100644 --- a/app/src/main/java/com/gh/gamecenter/gamecollection/detail/conversation/GameCollectionCommentConversationFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/detail/conversation/GameCollectionCommentConversationFragment.kt @@ -274,7 +274,7 @@ class GameCollectionCommentConversationFragment : orderSfv.run { setContainerBackground(R.drawable.button_round_f5f5f5.toDrawable(requireContext())) setIndicatorBackground( - R.drawable.progressbar_game_collection_primary.toDrawable( + R.drawable.bg_game_collection_sfv_indicator.toDrawable( requireContext() ) ) diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/square/GameCollectionSquareFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/square/GameCollectionSquareFragment.kt index 76fc6ed563..e982211152 100644 --- a/app/src/main/java/com/gh/gamecenter/gamecollection/square/GameCollectionSquareFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/square/GameCollectionSquareFragment.kt @@ -568,7 +568,7 @@ class GameCollectionSquareFragment : LazyListFragment= Build.VERSION_CODES.N) { @@ -129,7 +128,12 @@ class GameDownloadSettingFragment: ToolbarFragment() { override fun onNightModeChange() { super.onNightModeChange() - mBinding?.root?.setBackgroundColor(R.color.background.toColor(requireContext())) + mBinding?.run { + root.setBackgroundColor(R.color.background.toColor(requireContext())) + autoInstallItem.switchLottie.setSwitchAnimation(SPUtils.getBoolean(AUTO_INSTALL_SP_KEY, true)) + concernGameItem.switchLottie.setSwitchAnimation(SPUtils.getBoolean(CONCERN_GAME_SP_KEY, true)) + trafficItem.switchLottie.setSwitchAnimation(SPUtils.getBoolean(getTrafficDownloadHintKey(), false)) + } } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/setting/VideoSettingActivity.kt b/app/src/main/java/com/gh/gamecenter/setting/VideoSettingActivity.kt index 42406841a2..0c6a84200c 100644 --- a/app/src/main/java/com/gh/gamecenter/setting/VideoSettingActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/setting/VideoSettingActivity.kt @@ -2,6 +2,7 @@ package com.gh.gamecenter.setting import android.content.Context import android.content.Intent import android.os.Bundle +import android.view.View import com.gh.gamecenter.common.base.activity.ToolBarActivity import com.gh.gamecenter.R import com.gh.gamecenter.common.constant.EntranceConsts @@ -32,4 +33,8 @@ class VideoSettingActivity : ToolBarActivity() { super.onNightModeChange() updateStatusBarColor(R.color.background_white, R.color.background_white) } + + override fun updateStaticViewBackground(view: View?) { + updateStaticView(view, listOf(R.id.selectedIv)) + } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/setting/VideoSettingFragment.kt b/app/src/main/java/com/gh/gamecenter/setting/VideoSettingFragment.kt index 068551b625..442e60c54d 100644 --- a/app/src/main/java/com/gh/gamecenter/setting/VideoSettingFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/setting/VideoSettingFragment.kt @@ -2,17 +2,20 @@ package com.gh.gamecenter.setting import android.os.Bundle import android.view.View -import com.airbnb.lottie.LottieAnimationView -import com.gh.gamecenter.common.constant.Constants -import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.R -import com.gh.gamecenter.databinding.FragmentVideoSettingBinding import com.gh.gamecenter.common.base.fragment.ToolbarFragment +import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.utils.setSwitchAnimation import com.gh.gamecenter.common.utils.toColor +import com.gh.gamecenter.common.utils.toDrawable +import com.gh.gamecenter.core.utils.SPUtils +import com.gh.gamecenter.databinding.FragmentVideoSettingBinding class VideoSettingFragment: ToolbarFragment() { private var mBinding: FragmentVideoSettingBinding? = null + private var mContentVideoOptionSelected = "" + private var mHomeOrDetailVideoOptionSelected = "" override fun getLayoutId() = 0 @@ -29,6 +32,7 @@ class VideoSettingFragment: ToolbarFragment() { mBinding?.homeOrDetailVideoTitle?.root?.text = "首页/游戏详情页视频" mBinding?.contentVideoOptionAllItem?.run { titleTv.text = getString(R.string.all_network_auto_play) + selectedIv.visibility = View.VISIBLE root.setOnClickListener { if (!isCurrentContentStatus(VIDEO_OPTION_ALL)) { setContentVideoOption(VIDEO_OPTION_ALL) @@ -38,6 +42,7 @@ class VideoSettingFragment: ToolbarFragment() { } mBinding?.contentVideoOptionWifiItem?.run { titleTv.text = getString(R.string.only_wifi_auto_play) + selectedIv.visibility = View.VISIBLE root.setOnClickListener { if (!isCurrentContentStatus(VIDEO_OPTION_WIFI)) { setContentVideoOption(VIDEO_OPTION_WIFI) @@ -47,6 +52,7 @@ class VideoSettingFragment: ToolbarFragment() { } mBinding?.contentVideoOptionCloseItem?.run { titleTv.text = getString(R.string.close_auto_play) + selectedIv.visibility = View.VISIBLE root.setOnClickListener { if (!isCurrentContentStatus(VIDEO_OPTION_CLOSE)) { setContentVideoOption(VIDEO_OPTION_CLOSE) @@ -56,6 +62,7 @@ class VideoSettingFragment: ToolbarFragment() { } mBinding?.homeOrDetailVideoOptionAllItem?.run { titleTv.text = getString(R.string.all_network_auto_play) + selectedIv.visibility = View.VISIBLE root.setOnClickListener { if (!isCurrentHomeOrDetailStatus(VIDEO_OPTION_ALL)) { setHomeOrDetailVideoOption(VIDEO_OPTION_ALL) @@ -65,6 +72,7 @@ class VideoSettingFragment: ToolbarFragment() { } mBinding?.homeOrDetailVideoOptionWifiItem?.run { titleTv.text = getString(R.string.only_wifi_auto_play) + selectedIv.visibility = View.VISIBLE root.setOnClickListener { if (!isCurrentHomeOrDetailStatus(VIDEO_OPTION_WIFI)) { setHomeOrDetailVideoOption(VIDEO_OPTION_WIFI) @@ -74,6 +82,7 @@ class VideoSettingFragment: ToolbarFragment() { } mBinding?.homeOrDetailVideoOptionCloseItem?.run { titleTv.text = getString(R.string.close_auto_play) + selectedIv.visibility = View.VISIBLE root.setOnClickListener { if (!isCurrentHomeOrDetailStatus(VIDEO_OPTION_CLOSE)) { setHomeOrDetailVideoOption(VIDEO_OPTION_CLOSE) @@ -96,11 +105,11 @@ class VideoSettingFragment: ToolbarFragment() { } } - private fun LottieAnimationView.setSwitchAnimation(turnOff: Boolean) = setAnimation(if (turnOff) "lottie/switch_turnoff.json" else "lottie/switch_turnon.json") - private fun initStatus() { - setContentVideoOption(SPUtils.getString(SP_CONTENT_VIDEO_OPTION, VIDEO_OPTION_WIFI) ?: VIDEO_OPTION_WIFI) - setHomeOrDetailVideoOption(SPUtils.getString(SP_HOME_OR_DETAIL_VIDEO_OPTION, VIDEO_OPTION_WIFI) ?: VIDEO_OPTION_WIFI) + mContentVideoOptionSelected = SPUtils.getString(SP_CONTENT_VIDEO_OPTION, VIDEO_OPTION_WIFI) ?: VIDEO_OPTION_WIFI + mHomeOrDetailVideoOptionSelected = SPUtils.getString(SP_HOME_OR_DETAIL_VIDEO_OPTION, VIDEO_OPTION_WIFI) ?: VIDEO_OPTION_WIFI + setContentVideoOption(mContentVideoOptionSelected) + setHomeOrDetailVideoOption(mHomeOrDetailVideoOptionSelected) mBinding?.muteItem?.switchLottie?.setSwitchAnimation(SPUtils.getBoolean(SP_VIDEO_PLAY_MUTE, true)) } @@ -108,21 +117,21 @@ class VideoSettingFragment: ToolbarFragment() { mBinding?.run { when (status) { VIDEO_OPTION_ALL -> { - contentVideoOptionAllItem.selectedIv.visibility = View.VISIBLE - contentVideoOptionWifiItem.selectedIv.visibility = View.GONE - contentVideoOptionCloseItem.selectedIv.visibility = View.GONE + contentVideoOptionAllItem.selectedIv.setImageDrawable(R.drawable.ic_video_setting_select.toDrawable(requireContext())) + contentVideoOptionWifiItem.selectedIv.setImageDrawable(R.drawable.ic_selector_default.toDrawable(requireContext())) + contentVideoOptionCloseItem.selectedIv.setImageDrawable(R.drawable.ic_selector_default.toDrawable(requireContext())) } VIDEO_OPTION_WIFI -> { - contentVideoOptionAllItem.selectedIv.visibility = View.GONE - contentVideoOptionWifiItem.selectedIv.visibility = View.VISIBLE - contentVideoOptionCloseItem.selectedIv.visibility = View.GONE + contentVideoOptionAllItem.selectedIv.setImageDrawable(R.drawable.ic_selector_default.toDrawable(requireContext())) + contentVideoOptionWifiItem.selectedIv.setImageDrawable(R.drawable.ic_video_setting_select.toDrawable(requireContext())) + contentVideoOptionCloseItem.selectedIv.setImageDrawable(R.drawable.ic_selector_default.toDrawable(requireContext())) } VIDEO_OPTION_CLOSE -> { - contentVideoOptionAllItem.selectedIv.visibility = View.GONE - contentVideoOptionWifiItem.selectedIv.visibility = View.GONE - contentVideoOptionCloseItem.selectedIv.visibility = View.VISIBLE + contentVideoOptionAllItem.selectedIv.setImageDrawable(R.drawable.ic_selector_default.toDrawable(requireContext())) + contentVideoOptionWifiItem.selectedIv.setImageDrawable(R.drawable.ic_selector_default.toDrawable(requireContext())) + contentVideoOptionCloseItem.selectedIv.setImageDrawable(R.drawable.ic_video_setting_select.toDrawable(requireContext())) } } } @@ -132,21 +141,21 @@ class VideoSettingFragment: ToolbarFragment() { mBinding?.run { when (status) { VIDEO_OPTION_ALL -> { - homeOrDetailVideoOptionAllItem.selectedIv.visibility = View.VISIBLE - homeOrDetailVideoOptionWifiItem.selectedIv.visibility = View.GONE - homeOrDetailVideoOptionCloseItem.selectedIv.visibility = View.GONE + homeOrDetailVideoOptionAllItem.selectedIv.setImageDrawable(R.drawable.ic_video_setting_select.toDrawable(requireContext())) + homeOrDetailVideoOptionWifiItem.selectedIv.setImageDrawable(R.drawable.ic_selector_default.toDrawable(requireContext())) + homeOrDetailVideoOptionCloseItem.selectedIv.setImageDrawable(R.drawable.ic_selector_default.toDrawable(requireContext())) } VIDEO_OPTION_WIFI -> { - homeOrDetailVideoOptionAllItem.selectedIv.visibility = View.GONE - homeOrDetailVideoOptionWifiItem.selectedIv.visibility = View.VISIBLE - homeOrDetailVideoOptionCloseItem.selectedIv.visibility = View.GONE + homeOrDetailVideoOptionAllItem.selectedIv.setImageDrawable(R.drawable.ic_selector_default.toDrawable(requireContext())) + homeOrDetailVideoOptionWifiItem.selectedIv.setImageDrawable(R.drawable.ic_video_setting_select.toDrawable(requireContext())) + homeOrDetailVideoOptionCloseItem.selectedIv.setImageDrawable(R.drawable.ic_selector_default.toDrawable(requireContext())) } VIDEO_OPTION_CLOSE -> { - homeOrDetailVideoOptionAllItem.selectedIv.visibility = View.GONE - homeOrDetailVideoOptionWifiItem.selectedIv.visibility = View.GONE - homeOrDetailVideoOptionCloseItem.selectedIv.visibility = View.VISIBLE + homeOrDetailVideoOptionAllItem.selectedIv.setImageDrawable(R.drawable.ic_selector_default.toDrawable(requireContext())) + homeOrDetailVideoOptionWifiItem.selectedIv.setImageDrawable(R.drawable.ic_selector_default.toDrawable(requireContext())) + homeOrDetailVideoOptionCloseItem.selectedIv.setImageDrawable(R.drawable.ic_video_setting_select.toDrawable(requireContext())) } } } @@ -163,6 +172,9 @@ class VideoSettingFragment: ToolbarFragment() { override fun onNightModeChange() { super.onNightModeChange() mBinding?.root?.setBackgroundColor(R.color.background.toColor(requireContext())) + mBinding?.muteItem?.switchLottie?.setSwitchAnimation(SPUtils.getBoolean(SP_VIDEO_PLAY_MUTE, true)) + setContentVideoOption(mContentVideoOptionSelected) + setHomeOrDetailVideoOption(mHomeOrDetailVideoOptionSelected) } companion object { diff --git a/app/src/main/java/com/halo/assistant/fragment/SettingsFragment.kt b/app/src/main/java/com/halo/assistant/fragment/SettingsFragment.kt index 97cf15fd4c..84059104ac 100644 --- a/app/src/main/java/com/halo/assistant/fragment/SettingsFragment.kt +++ b/app/src/main/java/com/halo/assistant/fragment/SettingsFragment.kt @@ -179,13 +179,11 @@ class SettingsFragment : ToolbarFragment() { } if (UsageStatsHelper.checkForPermission() && SPUtils.getBoolean(UsageStatsHelper.USAGE_STATUS_SP_KEY, true)) { mUsageStatus = true - mBinding.usageStatsItem.switchIv.isChecked = true EnergyTaskHelper.postEnergyTask("open_game_time") } else { mUsageStatus = false - mBinding.usageStatsItem.switchIv.isChecked = false - mBinding.usageStatsItem.switchLottie.setSwitchAnimation(mUsageStatus) } + mBinding.usageStatsItem.switchLottie.setSwitchAnimation(mUsageStatus) } private fun initView() { @@ -243,7 +241,7 @@ class SettingsFragment : ToolbarFragment() { } mBinding.usageStatsItem.run { titleTv.text = getString(R.string.setting_usage_stats) - switchIv.visibility = View.VISIBLE + switchLottie.visibility = View.VISIBLE if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { root.setOnClickListener { if (UsageStatsHelper.checkForPermission()) { @@ -286,7 +284,7 @@ class SettingsFragment : ToolbarFragment() { mBinding.notificationAuthorityItem.run { titleTv.text = getString(R.string.setting_notification_authority) tipsTv.text = getString(R.string.setting_notification_authority_hint) - switchIv.visibility = View.VISIBLE + switchLottie.visibility = View.VISIBLE tipsTv.visibility = View.VISIBLE root.setOnClickListener { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { @@ -483,10 +481,6 @@ class SettingsFragment : ToolbarFragment() { }.show() } - - private fun LottieAnimationView.setSwitchAnimation(turnOff: Boolean) = - setAnimation(if (turnOff) "lottie/switch_turnoff.json" else "lottie/switch_turnon.json") - // 清除缓存 private fun clearCache() { Observable.create { emitter: ObservableEmitter -> @@ -547,7 +541,7 @@ class SettingsFragment : ToolbarFragment() { super.onResume() setNavigationTitle(getString(R.string.title_settings)) - mBinding.notificationAuthorityItem.switchIv.isChecked = NotificationHelper.notificationIsEnable() + mBinding.notificationAuthorityItem.switchLottie.setSwitchAnimation(NotificationHelper.notificationIsEnable()) if (BrowserInstallHelper.isUseBrowserToInstallEnabled()) { if (BrowserInstallHelper.shouldUseBrowserToInstall()) { @@ -628,6 +622,9 @@ class SettingsFragment : ToolbarFragment() { override fun onNightModeChange() { super.onNightModeChange() mBinding.root.setBackgroundColor(R.color.background.toColor(requireContext())) + mBinding.personalRecommendItem.switchLottie.setSwitchAnimation(SPUtils.getBoolean(PERSONAL_RECOMMEND_SP_KEY, true)) + mBinding.usageStatsItem.switchLottie.setSwitchAnimation(mUsageStatus) + mBinding.notificationAuthorityItem.switchLottie.setSwitchAnimation(NotificationHelper.notificationIsEnable()) } companion object { diff --git a/app/src/main/java/com/halo/assistant/fragment/SwitchInstallMethodFragment.kt b/app/src/main/java/com/halo/assistant/fragment/SwitchInstallMethodFragment.kt index 738d0f96e0..e316a63da8 100644 --- a/app/src/main/java/com/halo/assistant/fragment/SwitchInstallMethodFragment.kt +++ b/app/src/main/java/com/halo/assistant/fragment/SwitchInstallMethodFragment.kt @@ -24,6 +24,7 @@ import java.util.* class SwitchInstallMethodFragment : ToolbarFragment() { private var mBinding: FragmentSwitchInstallMethodBinding? = null + private var mUseBrowserToInstall = false override fun getLayoutId() = 0 @@ -90,12 +91,13 @@ class SwitchInstallMethodFragment : ToolbarFragment() { } private fun changeSwitch(useBrowserToInstall: Boolean) { + mUseBrowserToInstall = useBrowserToInstall if (useBrowserToInstall) { - mBinding?.defaultInstallItem?.selectedIv?.setImageResource(R.drawable.ic_install_method_select) + mBinding?.defaultInstallItem?.selectedIv?.setImageResource(R.drawable.ic_selector_default) mBinding?.browserInstallItem?.selectedIv?.setImageResource(R.drawable.ic_video_setting_select) } else { mBinding?.defaultInstallItem?.selectedIv?.setImageResource(R.drawable.ic_video_setting_select) - mBinding?.browserInstallItem?.selectedIv?.setImageResource(R.drawable.ic_install_method_select) + mBinding?.browserInstallItem?.selectedIv?.setImageResource(R.drawable.ic_selector_default) } if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL) != useBrowserToInstall) { @@ -126,5 +128,6 @@ class SwitchInstallMethodFragment : ToolbarFragment() { backBtn.setImageResource(R.drawable.ic_bar_back) normalTitle.setTextColor(R.color.text_title.toColor(requireContext())) } + changeSwitch(mUseBrowserToInstall) } } \ No newline at end of file diff --git a/app/src/main/res/drawable-night/download_dialog_installed_background.xml b/app/src/main/res/drawable-night/download_dialog_installed_background.xml new file mode 100644 index 0000000000..e92c6c72e3 --- /dev/null +++ b/app/src/main/res/drawable-night/download_dialog_installed_background.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-night/download_dialog_status_collection_gray.xml b/app/src/main/res/drawable-night/download_dialog_status_collection_gray.xml new file mode 100644 index 0000000000..db1863ed0a --- /dev/null +++ b/app/src/main/res/drawable-night/download_dialog_status_collection_gray.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable-night/download_dialog_status_download_gray.xml b/app/src/main/res/drawable-night/download_dialog_status_download_gray.xml new file mode 100644 index 0000000000..f0d8c91414 --- /dev/null +++ b/app/src/main/res/drawable-night/download_dialog_status_download_gray.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable-night/download_dialog_version_note.xml b/app/src/main/res/drawable-night/download_dialog_version_note.xml new file mode 100644 index 0000000000..07969eac72 --- /dev/null +++ b/app/src/main/res/drawable-night/download_dialog_version_note.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-night/download_recommend_des_bg.xml b/app/src/main/res/drawable-night/download_recommend_des_bg.xml new file mode 100644 index 0000000000..868ef0f4a3 --- /dev/null +++ b/app/src/main/res/drawable-night/download_recommend_des_bg.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-night/ic_selector_default.xml b/app/src/main/res/drawable-night/ic_selector_default.xml new file mode 100644 index 0000000000..8dc87fc414 --- /dev/null +++ b/app/src/main/res/drawable-night/ic_selector_default.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable-night/icon_more.xml b/app/src/main/res/drawable-night/icon_more.xml new file mode 100644 index 0000000000..e961c16f9d --- /dev/null +++ b/app/src/main/res/drawable-night/icon_more.xml @@ -0,0 +1,13 @@ + + + diff --git a/app/src/main/res/drawable-xxhdpi/download_dialog_status_collection.png b/app/src/main/res/drawable-xxhdpi/download_dialog_status_collection.png deleted file mode 100644 index 0efe5baa30e3878204f443ce57c6d4e7e728771e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 407 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(-uv49!D1}S`GTDlgfjM3A@F~oy+ z>r_L&CIgYSXs?ol;?G=uRqXD%Rq@%=WsqpV*w@ z<^Nw_R$uA$Rc6-9_xV46eBIDpkvnaiEUCj|LuaC}_+qe2x-;Mnwxw`nN=7aBv zfh#UX-wf7hVd^nkc}b#u6PXRdNxXWYQKvF40g#Jn43sbA-wYv|Y>XOr*HVNv#! zl|%G9lgE*{3@aJi6tSMHaLQ%k-svDTRVSIGB1Pm1q;zSmFx ZGOwAmYr3P(8c-B4c)I$ztaD0e0s!KPhgARo diff --git a/app/src/main/res/drawable-xxhdpi/download_dialog_status_collection_gray.png b/app/src/main/res/drawable-xxhdpi/download_dialog_status_collection_gray.png deleted file mode 100644 index 4290dd16e331c500ba5328d11ca1a6fae3ac7b4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 411 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbB7>k44ofy`glX(f`xTHpSruq6Z zXaU(A42G$TlC0TWzSWdSpS4N|DZ_xKM`8LOv@V@L$& z+v^8;n+i<;TeD@3t2bQQI?KZFMg3*b%aIF@ELiLF zmv6Jv%1eDlxiepu-T0;VHTSk%#QP~+EG?#9yqnxq8+8ItDrkp@onV^Eo3vO%L9L4| zY2k_m$|0el-8%(ZVAkj+)M2{s)V^W^n!T<=4gomDAPR&)-ve_5ApwBO;9VOwLN3 zf0bI!ooK(~i>&tE-q60hiUM}W7e%W&4+-AB?_uH)rM1jDc1}{#!Glb~domj4TwlI< z^-48Mi-@ZJ`9XLBXD-iq{N?32>$!;ytfyN#&7F$+ zzLxa7m)Uc9k@>9Dq!VrrFYpIVaq?12whlkHg3-lNm|y0jEA#0i+~v|MI;Z{j{}-O{ bH|sY`Rp9#>HSbcZK*8wg>gTe~DWM4fLwBo8 diff --git a/app/src/main/res/drawable-xxhdpi/download_dialog_status_download_gray.png b/app/src/main/res/drawable-xxhdpi/download_dialog_status_download_gray.png deleted file mode 100644 index b70b8342220c993bb54390ee01fd606e2df13c00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 437 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(-uv49!D1}S`GTDlgfOy1MQF~o!S z?UaMOhYWaJvyVv0?3|u=kV{6eTH%|6Eu*x;HjTTDma87fn}%jgx+PfPa46`u$-jU4 zrBg+YPH*1w@0di^tTg7@&`@zDqgl6hy0P${kt}+3ykbt_&EEY*F9aAFCL412-~SnZC3_Y}*PKn5XBjv#%* zRK7%^h9xW$&$u2CaY|k1|%Oc%$NbB7>k44ofy`glX(f`xTHpSruq6Z zXaU(A42G$TlC0TWzSWdSpS4N|DZ_xKM`*)mTT$B+ol zx6}7}F*^zzPoK14#dN!^YhO&fW;8Wnq3a%}`v*_?eQ?;g`IPmI7%6U1#}nEr;Wx6R zUw5~*S)7Zxu^~Ij;7Dx88&m7uZ{Gg-X8+ri;a{`?Yryl|ZJWKFEEE^1?!7y$w?p2e zpfo^tzLq>|s)wh?@pTDB^)`hcR~kz=c-#=k+S}|~y+Xh&=huhiYSukWagD9v2kxg< zaXh{ErF`bPj_v=KG9BBt-SY5~zuUSwBKX7K|4jV$bF#j=1Cz7C4pEM_OkMGh1^LDm zb6HYt64gt8yf(9|&U(-MN+mOFw#hc(1uJ%y9Y1wM$6rpXZI!^mWaG0*+j!a36@$H= ztP+Ufo{;rh&WSnW-ku(I`O}-HB!{Z`@8$a9xxh{F@&8>7OW$h5R2n{+Wv-vBo?Jee zDKK@5V9E8v3GLI%SKV?kTy${X72XAvpEoUZy8Kxu@P*}D+kz-5ErmdijTOqJ$|qH)78&qol`;+00Qsdp8x;= diff --git a/app/src/main/res/drawable-xxxhdpi/icon_more.png b/app/src/main/res/drawable-xxxhdpi/icon_more.png deleted file mode 100644 index f673f1502f821fd5bf6c62c36dc1bd4d1744a6bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 527 zcmV+q0`UEbP)5WAF^(3EU`n1jVIW@d#p=LLl0W7qGak7Z6;Ql92o) zV4+C=`hXw<>S(R?0e}}D5Ul_{AzA}`L39H6fanZxjW7ami7*Cmg)jMpyxGBCG+p5LN*k2f)&sZQ3gS97>41f$=R44Fhf*Tl?fqw zOCoRMIKK26uQ_W6i=;7 RPW1o)002ovPDHLkV1mYa - + android:endColor="#002496FF" + android:startColor="#1F2496FF" /> \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_forum_welfare_item.xml b/app/src/main/res/drawable/bg_forum_welfare_item.xml index 16ecf7b9b6..f5a001ed3e 100644 --- a/app/src/main/res/drawable/bg_forum_welfare_item.xml +++ b/app/src/main/res/drawable/bg_forum_welfare_item.xml @@ -2,5 +2,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_game_collection_sfv_indicator.xml b/app/src/main/res/drawable/bg_game_collection_sfv_indicator.xml new file mode 100644 index 0000000000..9ab1c3f4b7 --- /dev/null +++ b/app/src/main/res/drawable/bg_game_collection_sfv_indicator.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/download_dialog_item_progress.xml b/app/src/main/res/drawable/download_dialog_item_progress.xml index 8b81d5f24f..04e7ff13a0 100644 --- a/app/src/main/res/drawable/download_dialog_item_progress.xml +++ b/app/src/main/res/drawable/download_dialog_item_progress.xml @@ -4,14 +4,14 @@ + android:endColor="#142496FF" + android:startColor="#142496FF" /> + android:color="#142496FF" /> @@ -21,12 +21,12 @@ - + + android:color="#2970BBFF" /> diff --git a/app/src/main/res/drawable/download_dialog_status_collection.xml b/app/src/main/res/drawable/download_dialog_status_collection.xml new file mode 100644 index 0000000000..8c910d2b23 --- /dev/null +++ b/app/src/main/res/drawable/download_dialog_status_collection.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/download_dialog_status_collection_gray.xml b/app/src/main/res/drawable/download_dialog_status_collection_gray.xml new file mode 100644 index 0000000000..e75288d5a1 --- /dev/null +++ b/app/src/main/res/drawable/download_dialog_status_collection_gray.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/download_dialog_status_download.xml b/app/src/main/res/drawable/download_dialog_status_download.xml new file mode 100644 index 0000000000..32c3a4ec95 --- /dev/null +++ b/app/src/main/res/drawable/download_dialog_status_download.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/download_dialog_status_download_gray.xml b/app/src/main/res/drawable/download_dialog_status_download_gray.xml new file mode 100644 index 0000000000..2f1a29b6e1 --- /dev/null +++ b/app/src/main/res/drawable/download_dialog_status_download_gray.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/download_dialog_status_pause.xml b/app/src/main/res/drawable/download_dialog_status_pause.xml new file mode 100644 index 0000000000..d513061f6f --- /dev/null +++ b/app/src/main/res/drawable/download_dialog_status_pause.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/download_dialog_version_note.xml b/app/src/main/res/drawable/download_dialog_version_note.xml index c8a7eef482..855830a0c8 100644 --- a/app/src/main/res/drawable/download_dialog_version_note.xml +++ b/app/src/main/res/drawable/download_dialog_version_note.xml @@ -4,7 +4,7 @@ + android:color="@color/divider" /> diff --git a/app/src/main/res/drawable/ic_selector_default.xml b/app/src/main/res/drawable/ic_selector_default.xml new file mode 100644 index 0000000000..edc57afcbf --- /dev/null +++ b/app/src/main/res/drawable/ic_selector_default.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/icon_more.xml b/app/src/main/res/drawable/icon_more.xml new file mode 100644 index 0000000000..5efd89f935 --- /dev/null +++ b/app/src/main/res/drawable/icon_more.xml @@ -0,0 +1,13 @@ + + + diff --git a/app/src/main/res/drawable/progressbar_game_collection_primary.xml b/app/src/main/res/drawable/progressbar_game_collection_primary.xml index 9ab1c3f4b7..7f44f970bd 100644 --- a/app/src/main/res/drawable/progressbar_game_collection_primary.xml +++ b/app/src/main/res/drawable/progressbar_game_collection_primary.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/layout/download_dialog_item.xml b/app/src/main/res/layout/download_dialog_item.xml index 326f0ccb25..38bd201966 100644 --- a/app/src/main/res/layout/download_dialog_item.xml +++ b/app/src/main/res/layout/download_dialog_item.xml @@ -100,7 +100,7 @@ android:layout_width="8dp" android:layout_height="8dp" android:layout_marginRight="8dp" - android:src="@drawable/download_dialog_status_download_gray" + app:srcCompat="@drawable/download_dialog_status_download_gray" app:layout_constraintBottom_toBottomOf="@+id/icon" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="@+id/icon" /> @@ -158,7 +158,7 @@ + app:srcCompat="@drawable/ic_recommend_label_left" /> + app:srcCompat="@drawable/ic_recommend_label_right" /> diff --git a/app/src/main/res/layout/forum_my_follow.xml b/app/src/main/res/layout/forum_my_follow.xml index 1a8ff3f591..240d700816 100644 --- a/app/src/main/res/layout/forum_my_follow.xml +++ b/app/src/main/res/layout/forum_my_follow.xml @@ -2,6 +2,7 @@ @@ -43,7 +44,7 @@ android:id="@+id/moreIv" android:layout_width="12dp" android:layout_height="12dp" - android:src="@drawable/icon_more" /> + app:srcCompat="@drawable/icon_more" /> + app:layout_constraintTop_toTopOf="parent" + app:srcCompat="@drawable/ic_video_setting_select" /> \ No newline at end of file diff --git a/app/src/main/res/layout/piece_article_detail_comment_filter.xml b/app/src/main/res/layout/piece_article_detail_comment_filter.xml index 211ed47be8..f741b61a8f 100644 --- a/app/src/main/res/layout/piece_article_detail_comment_filter.xml +++ b/app/src/main/res/layout/piece_article_detail_comment_filter.xml @@ -79,7 +79,7 @@ android:layout_marginRight="16dp" app:containerBackground="@drawable/button_round_f5f5f5" app:containerPadding="1dp" - app:indicatorBackground="@drawable/progressbar_game_collection_primary" + app:indicatorBackground="@drawable/bg_game_collection_sfv_indicator" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" diff --git a/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt b/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt index c26d08c247..970ce1209d 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt @@ -1259,4 +1259,18 @@ fun Activity.updateStatusBarColor(@ColorRes nightColor: Int, @ColorRes dayColor: if (NightModeUtils.isNightMode(this)) nightColor else dayColor ) } +} + +/** + * 设置开关Lottie动画 + */ +fun LottieAnimationView.setSwitchAnimation(turnOff: Boolean) { + cancelAnimation() + when { + turnOff && NightModeUtils.isNightMode(context) -> setAnimation("lottie/switch_turnoff_dark.json") + !turnOff && NightModeUtils.isNightMode(context) -> setAnimation("lottie/switch_turnon_dark.json") + turnOff && !NightModeUtils.isNightMode(context) -> setAnimation("lottie/switch_turnoff_light.json") + !turnOff && !NightModeUtils.isNightMode(context) -> setAnimation("lottie/switch_turnon_light.json") + } + progress = 0F } \ No newline at end of file From c1fd2e48db5b95ec656a310f8baba866424e6768 Mon Sep 17 00:00:00 2001 From: lyr Date: Mon, 11 Jul 2022 14:24:50 +0800 Subject: [PATCH 085/217] =?UTF-8?q?feat:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E7=A4=BE=E5=8C=BA=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E4=BC=98=E5=8C=96-=E7=AC=AC=E5=85=AB=E6=9C=9F(1?= =?UTF-8?q?=E3=80=812=E3=80=813)=20https://git.shanqu.cc/pm/halo/halo-app-?= =?UTF-8?q?issues/-/issues/1943?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/gamecenter/entity/CommentEntity.kt | 2 +- .../personalhome/UserHomeFragment.kt | 71 +++++++++++++------ .../article/detail/ArticleDetailViewModel.kt | 4 +- .../qa/comment/base/BaseCommentViewModel.kt | 9 --- .../newdetail/NewQuestionDetailViewModel.kt | 4 +- .../detail/comment/VideoCommentViewModel.kt | 3 - .../halo/assistant/fragment/WebFragment.kt | 33 ++++++++- .../common/base/activity/BaseActivity.java | 16 ++++- 8 files changed, 101 insertions(+), 41 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/entity/CommentEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/CommentEntity.kt index 470985fb90..d0b60ec451 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/CommentEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/CommentEntity.kt @@ -30,7 +30,7 @@ data class CommentEntity( var choiceness: Boolean = false,//是否已加精,问题评论用 var images: ArrayList? = arrayListOf(), - // 楼数,本地字段 + // 楼层 var floor: Int = 0, var isExpand: Boolean = false, @SerializedName("attached") // 楼中楼 diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt b/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt index 9146c4feee..15702c4464 100644 --- a/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt @@ -1,10 +1,12 @@ package com.gh.gamecenter.personalhome +import android.annotation.SuppressLint import android.graphics.Bitmap import android.graphics.drawable.BitmapDrawable import android.os.Build import android.os.Bundle import android.view.LayoutInflater +import android.view.MotionEvent import android.view.View import android.widget.CheckedTextView import android.widget.LinearLayout @@ -44,6 +46,7 @@ import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout.OnOffsetChangedListener import com.halo.assistant.HaloApp import com.lightgame.utils.Utils +import io.reactivex.disposables.Disposable import kotlin.math.abs class UserHomeFragment : ToolbarFragment() { @@ -61,6 +64,7 @@ class UserHomeFragment : ToolbarFragment() { private var mBadgeCount = 0 private var mPlayGameCount = 0 private var mFragmentList = listOf() + private var mTimerDisposable: Disposable? = null override fun getLayoutId() = 0 override fun getInflatedLayout() = @@ -661,29 +665,48 @@ class UserHomeFragment : ToolbarFragment() { } } -// userBadge.setOnClickListener { -// MtaHelper.onEvent("个人主页详情", "个人主页详情", if (mUserHomeViewModel.userId == UserManager.getInstance().userId) "我的徽章" else "TA的徽章") -// MtaHelper.onEvent("进入徽章墙_用户记录", if (mUserHomeViewModel.userId == UserManager.getInstance().userId) "个人主页-我的徽章" else "个人主页-Ta的徽章", -// "${mUserHomeViewModel.userInfo.value?.name}(${mUserHomeViewModel.userId})") -// MtaHelper.onEvent("徽章中心", "进入徽章中心", if (mUserHomeViewModel.userId == UserManager.getInstance().userId) "个人主页-我的徽章" else "个人主页-Ta的徽章") -// directToBadgeWall(requireContext(), -// mUserHomeViewModel.userId, mUserHomeViewModel.userInfo.value?.name -// ?: "", mUserHomeViewModel.userInfo.value?.icon ?: "") -// } + setUserNameLongClick() } } -// private fun updateUserBadge(badges: List) { -// mHomeBinding?.userBadgeList?.removeAllViews() -// for (badge in badges.take(6)) { -// val badgeView = SimpleDraweeView(context) -// val params = LinearLayout.LayoutParams(24F.dip2px(), 24F.dip2px()) -// params.setMargins(2F.dip2px(), 0, 2F.dip2px(), 0) -// badgeView.layoutParams = params -// ImageUtils.display(badgeView, badge.icon) -// mHomeBinding?.userBadgeList?.addView(badgeView) -// } -// } + @SuppressLint("ClickableViewAccessibility") + private fun setUserNameLongClick() { + mHomeBinding?.userName?.setOnTouchListener(object : View.OnTouchListener { + + private val TOUCH_MAX = 50 + private var mLastMotionX = 0 + private var mLastMotionY = 0 + + override fun onTouch(v: View, event: MotionEvent): Boolean { + val x = event.x.toInt() + val y = event.y.toInt() + when (event.action) { + MotionEvent.ACTION_DOWN -> { + mTimerDisposable?.dispose() + mLastMotionX = x + mLastMotionY = y + mTimerDisposable = countDownTimer(3) { finish, _ -> + if (finish) { + mHomeBinding?.userName?.text?.toString()?.copyTextAndToast("用户昵称已复制~") + + } + } + } + MotionEvent.ACTION_MOVE -> { + if (abs(mLastMotionX - x) > TOUCH_MAX || abs(mLastMotionY - y) > TOUCH_MAX) { + // 移动超过阈值,判断为不是长按,取消任务 + mTimerDisposable?.dispose() + } + } + else -> { + mTimerDisposable?.dispose() + } + } + return true + } + + }) + } override fun onClick(v: View) { super.onClick(v) @@ -781,6 +804,14 @@ class UserHomeFragment : ToolbarFragment() { return super.onBackPressed() } + override fun onDestroy() { + super.onDestroy() + if (mTimerDisposable != null && !mTimerDisposable!!.isDisposed) { + mTimerDisposable!!.dispose() + mTimerDisposable = null + } + } + companion object { const val LOCATION = "个人主页" } diff --git a/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailViewModel.kt index 5742528cb2..9852651d3a 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailViewModel.kt @@ -76,7 +76,7 @@ class ArticleDetailViewModel( } override fun mergeResultLiveData() { - mResultLiveData.addSource(mListLiveData) { mergeListData(it, displayFloor = true) } + mResultLiveData.addSource(mListLiveData) { mergeListData(it) } } fun getArticleDetail() { @@ -89,7 +89,7 @@ class ArticleDetailViewModel( topItemData = CommentItemData(articleDetail = response) commentCount = response?.count?.comment ?: 0 loadResultLiveData.postValue(LoadResult.SUCCESS) - mergeListData(mListLiveData.value, displayFloor = true) + mergeListData(mListLiveData.value) NewLogUtils.logForumContentBrowser(articleId, "bbs_article", recommendId) } diff --git a/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt index dbf33ad7b9..da00e63019 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt @@ -94,7 +94,6 @@ abstract class BaseCommentViewModel( fun mergeListData( commentList: List?, - displayFloor: Boolean = false, hasFilter: Boolean = true, ) { topItemData?.let { @@ -116,21 +115,13 @@ abstract class BaseCommentViewModel( } else if (commentList.isNullOrEmpty() && mLoadStatusLiveData.value == LoadStatus.INIT_FAILED) { add(CommentItemData(errorConnection = true)) } else { - //从第二楼开始 - var floor = 2 commentList?.forEachIndexed { index, entity -> - if (displayFloor) { - entity.floor = floor - } // 没有 me 会导致不能跨页面更新点赞 if (entity.me == null) { entity.me = MeEntity() } handleTopComment(index, entity) add(CommentItemData(commentNormal = entity)) - if (displayFloor) { - floor++ - } } add(CommentItemData(footer = true)) } diff --git a/app/src/main/java/com/gh/gamecenter/qa/questions/newdetail/NewQuestionDetailViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/questions/newdetail/NewQuestionDetailViewModel.kt index 6d17108941..78b8dfd901 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/questions/newdetail/NewQuestionDetailViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/questions/newdetail/NewQuestionDetailViewModel.kt @@ -70,7 +70,7 @@ class NewQuestionDetailViewModel( topItemData = CommentItemData(questionDetail = response) commentCount = response?.count?.answer ?: 0 loadResultLiveData.postValue(LoadResult.SUCCESS) - mergeListData(mListLiveData.value, displayFloor = true) + mergeListData(mListLiveData.value) NewLogUtils.logForumContentBrowser(questionId, "bbs_question", recommendId) } @@ -96,7 +96,7 @@ class NewQuestionDetailViewModel( } override fun mergeResultLiveData() { - mResultLiveData.addSource(mListLiveData) { mergeListData(it, displayFloor = true) } + mResultLiveData.addSource(mListLiveData) { mergeListData(it) } } override fun hideCommentSuccess() { diff --git a/app/src/main/java/com/gh/gamecenter/qa/video/detail/comment/VideoCommentViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/video/detail/comment/VideoCommentViewModel.kt index d40121b8e6..3170ff58cb 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/video/detail/comment/VideoCommentViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/video/detail/comment/VideoCommentViewModel.kt @@ -39,12 +39,9 @@ class VideoCommentViewModel( } else if (list.isNullOrEmpty() && mLoadStatusLiveData.value == LoadStatus.INIT_FAILED) { itemDataList.add(CommentItemData(errorConnection = true)) } else { - var floor = 1 list.forEachIndexed { index, entity -> - entity.floor = floor handleTopComment(index, entity) itemDataList.add(CommentItemData(commentNormal = entity)) - floor++ } itemDataList.add(CommentItemData(footer = true)) } diff --git a/app/src/main/java/com/halo/assistant/fragment/WebFragment.kt b/app/src/main/java/com/halo/assistant/fragment/WebFragment.kt index a0f70c7d38..3e5a72c84f 100644 --- a/app/src/main/java/com/halo/assistant/fragment/WebFragment.kt +++ b/app/src/main/java/com/halo/assistant/fragment/WebFragment.kt @@ -37,6 +37,7 @@ import com.gh.gamecenter.MessageDetailActivity import com.gh.gamecenter.R import com.gh.gamecenter.WebActivity import com.gh.gamecenter.common.constant.EntranceConsts +import com.gh.gamecenter.common.eventbus.EBShare import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.EmptyCallback import com.gh.gamecenter.databinding.FragmentWebBinding @@ -101,6 +102,18 @@ class WebFragment : LazyFragment(), IScrollable { private var mShareEntity: WebShareEntity? = null private var mSelectPicCallback: ValueCallback? = null private var mSelectPicCallbackAboveL: ValueCallback>? = null + private val mShareResultCallback by lazy { + object : ShareUtils.ShareCallBack { + + override fun onSuccess(label: String) { + if ("短信" == label || "复制链接" == label) { + onShareSuccess() + } + } + + override fun onCancel() {} + } + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -256,7 +269,7 @@ class WebFragment : LazyFragment(), IScrollable { toast("分享实体为空") return } - curActivity.showShare( + curActivity.showShareWithCallback( if (TextUtils.isEmpty(mShareEntity?.url)) requireArguments().getString( EntranceConsts.KEY_URL ) else mShareEntity?.url, @@ -264,7 +277,8 @@ class WebFragment : LazyFragment(), IScrollable { mShareEntity?.title, mShareEntity?.description, if (mQaType >= 0) ShareUtils.ShareEntrance.qaDetail else ShareUtils.ShareEntrance.web, - "" + "", + mShareResultCallback ) if (mQaType == 0) { onEvent("QA", "QA内容详情", "点击分享+" + mShareEntity?.title) @@ -749,6 +763,17 @@ class WebFragment : LazyFragment(), IScrollable { } } + @Subscribe(threadMode = ThreadMode.MAIN) + fun onEventMainThread(share: EBShare?) { + postDelayedRunnable({ + tryCatchInRelease { + if (share != null && share.shareEntrance == ShareUtils.ShareEntrance.web && isSupportVisible) { + onShareSuccess() + } + } + }, 200) + } + override fun onNightModeChange() { super.onNightModeChange() mMenuShare?.setIcon(R.drawable.icon_share_black) @@ -756,6 +781,10 @@ class WebFragment : LazyFragment(), IScrollable { mBinding?.newsWebview?.enableForceDark(NightModeUtils.isNightMode(requireContext())) } + private fun onShareSuccess() { + mBinding?.newsWebview?.callHandler("onShareSuccess", arrayOf(mShareEntity?.url)) { _: Any? -> } + } + companion object { const val KEY_ISTOOLS = "isTools" const val KEY_IS_BIND_WECHAT = "is_bind_wechat" diff --git a/module_common/src/main/java/com/gh/gamecenter/common/base/activity/BaseActivity.java b/module_common/src/main/java/com/gh/gamecenter/common/base/activity/BaseActivity.java index e94163dd4a..970f21babb 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/base/activity/BaseActivity.java +++ b/module_common/src/main/java/com/gh/gamecenter/common/base/activity/BaseActivity.java @@ -235,13 +235,25 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy String shareTitle, String shareSummary, ShareUtils.ShareEntrance shareEntrance, String id) { - ShareUtils.getInstance(this).showShareWindows(this, + showShareWithCallback(url, icon, shareTitle, shareSummary, shareEntrance, id, null); + } + + public void showShareWithCallback(String url, + String icon, + String shareTitle, + String shareSummary, + ShareUtils.ShareEntrance shareEntrance, + String id, + ShareUtils.ShareCallBack callBack) { + ShareUtils.getInstance(this).showShareWindowsCallback(this, getWindow().getDecorView(), url, icon, shareTitle, shareSummary, - shareEntrance, id); + shareEntrance, + id, + callBack); if (shareEntrance == ShareUtils.ShareEntrance.game || shareEntrance == ShareUtils.ShareEntrance.plugin) { MtaHelper.onEvent("内容分享", "内容分享", shareTitle + shareSummary); } else { From adb6691818d673d76adea8d9e115656b40caee27 Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 12 Jul 2022 10:49:20 +0800 Subject: [PATCH 086/217] =?UTF-8?q?=E6=9B=9D=E5=85=89=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=AF=AB=E7=A7=92=E6=97=B6=E9=97=B4=E6=88=B3?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=20https://git.shanqu.cc/pm/halo/halo-app-iss?= =?UTF-8?q?ues/-/issues/1953?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/exposure/ExposureDatabase.kt | 17 +++++++++++++---- .../com/gh/common/exposure/ExposureEvent.kt | 10 +++++----- .../com/gh/common/exposure/ExposureManager.kt | 5 +++-- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/gh/common/exposure/ExposureDatabase.kt b/app/src/main/java/com/gh/common/exposure/ExposureDatabase.kt index 9bd3cad34d..bc8724fb1c 100644 --- a/app/src/main/java/com/gh/common/exposure/ExposureDatabase.kt +++ b/app/src/main/java/com/gh/common/exposure/ExposureDatabase.kt @@ -1,21 +1,30 @@ package com.gh.common.exposure +import android.content.Context import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase import androidx.room.TypeConverters -import android.content.Context +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase @TypeConverters(ExposureConverters::class) -@Database(entities = [ExposureEvent::class], version = 1, exportSchema = false) +@Database(entities = [ExposureEvent::class], version = 2, exportSchema = false) abstract class ExposureDatabase : RoomDatabase() { companion object { private const val DATABASE = "exposure_database" fun buildDatabase(context: Context): ExposureDatabase { return Room.databaseBuilder(context, ExposureDatabase::class.java, DATABASE) - .fallbackToDestructiveMigration() - .build() + .fallbackToDestructiveMigration() + .addMigrations(MIGRATION_1_2) + .build() + } + + private val MIGRATION_1_2: Migration = object : Migration(1, 2) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("Alter TABLE ExposureEvent add timeInMillisecond INTEGER NOT NULL DEFAULT 0") + } } } diff --git a/app/src/main/java/com/gh/common/exposure/ExposureEvent.kt b/app/src/main/java/com/gh/common/exposure/ExposureEvent.kt index 9b5ff1cc4d..f46f806cec 100644 --- a/app/src/main/java/com/gh/common/exposure/ExposureEvent.kt +++ b/app/src/main/java/com/gh/common/exposure/ExposureEvent.kt @@ -4,18 +4,17 @@ import android.os.Parcelable import androidx.annotation.Keep import androidx.room.Entity import androidx.room.PrimaryKey +import com.gh.common.exposure.time.TimeUtil +import com.gh.download.server.BrowserInstallHelper import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.entity.ExposureEntity import com.gh.gamecenter.common.exposure.meta.Meta import com.gh.gamecenter.common.exposure.meta.MetaUtil -import com.gh.common.exposure.time.TimeUtil import com.gh.gamecenter.common.utils.getFirstElementDividedByDivider -import com.gh.download.server.BrowserInstallHelper -import com.gh.gamecenter.common.entity.ExposureEntity import com.gh.gamecenter.entity.GameEntity import com.lightgame.download.DownloadEntity import kotlinx.parcelize.Parcelize import java.util.* -import kotlin.collections.ArrayList @Keep @Parcelize @@ -27,8 +26,9 @@ data class ExposureEvent( val event: ExposureType, val meta: Meta = MetaUtil.getMeta(), val time: Int = TimeUtil.currentTime(), + val timeInMillisecond: Long = System.currentTimeMillis(), @PrimaryKey - val id: String = UUID.randomUUID().toString() + val id: String = UUID.randomUUID().toString(), ) : Parcelable { companion object { diff --git a/app/src/main/java/com/gh/common/exposure/ExposureManager.kt b/app/src/main/java/com/gh/common/exposure/ExposureManager.kt index 2251c86967..736f906782 100644 --- a/app/src/main/java/com/gh/common/exposure/ExposureManager.kt +++ b/app/src/main/java/com/gh/common/exposure/ExposureManager.kt @@ -1,11 +1,11 @@ package com.gh.common.exposure import com.aliyun.sls.android.producer.Log +import com.gh.gamecenter.BuildConfig import com.gh.gamecenter.common.loghub.LoghubHelper +import com.gh.gamecenter.common.utils.FixedSizeLinkedHashSet import com.gh.gamecenter.common.utils.toJson import com.gh.gamecenter.common.utils.tryWithDefaultCatch -import com.gh.gamecenter.BuildConfig -import com.gh.gamecenter.common.utils.FixedSizeLinkedHashSet import com.halo.assistant.HaloApp import com.lightgame.utils.Utils import java.util.concurrent.ExecutorService @@ -121,6 +121,7 @@ object ExposureManager { putContent("event", event.event.toString()) putContent("source", eliminateMultipleBrackets(event.source.toJson())) putContent("meta", event.meta.toJson()) + putContent("real_millisecond", event.timeInMillisecond.toString()) putContent("e-traces", if (event.eTrace != null) { eliminateMultipleBrackets(event.eTrace?.toJson() ?: "") } else "") From aa0f27c61b2704d3d671108b8b5e6e784d633b3c Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 12 Jul 2022 10:59:40 +0800 Subject: [PATCH 087/217] =?UTF-8?q?ci:=20suppress=20SonarQube=20=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/common/util/NewLogUtils.kt | 3 +-- .../main/java/com/gh/gamecenter/common/utils/NewLogUtils.kt | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/NewLogUtils.kt b/app/src/main/java/com/gh/common/util/NewLogUtils.kt index da1aeb639d..e79deaf547 100644 --- a/app/src/main/java/com/gh/common/util/NewLogUtils.kt +++ b/app/src/main/java/com/gh/common/util/NewLogUtils.kt @@ -4,18 +4,17 @@ import android.annotation.SuppressLint import com.gh.gamecenter.common.json.JsonObjectBuilder import com.gh.gamecenter.common.json.json import com.gh.gamecenter.common.loghub.LoghubUtils +import com.gh.gamecenter.common.retrofit.EmptyResponse import com.gh.gamecenter.common.tracker.Tracker import com.gh.gamecenter.common.utils.toRequestBody import com.gh.gamecenter.entity.QuoteCountEntity import com.gh.gamecenter.entity.WechatConfigEntity -import com.gh.gamecenter.common.retrofit.EmptyResponse import com.gh.gamecenter.retrofit.RetrofitManager import com.lightgame.utils.Utils import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody import org.json.JSONObject -@Deprecated("新埋点请添加至 NewFlatLogUtils") object NewLogUtils { private fun log(jsonObject: JSONObject, logStore: String, uploadImmediately: Boolean) { diff --git a/module_common/src/main/java/com/gh/gamecenter/common/utils/NewLogUtils.kt b/module_common/src/main/java/com/gh/gamecenter/common/utils/NewLogUtils.kt index 71d7d8c8a4..5f49fcef3f 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/utils/NewLogUtils.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/utils/NewLogUtils.kt @@ -8,13 +8,15 @@ import com.gh.gamecenter.common.tracker.Tracker import com.lightgame.utils.Utils import org.json.JSONObject +// 使用平铺内容的新埋点请添加至 NewFlatLogUtils + object NewLogUtils { private fun log(jsonObject: JSONObject, logStore: String, uploadImmediately: Boolean) { Utils.log("NewLogUtils", jsonObject.toString(4)) LoghubUtils.log(jsonObject, logStore, uploadImmediately) } - fun parseAndPutMeta(): JsonObjectBuilder.() -> Unit = { + private fun parseAndPutMeta(): JsonObjectBuilder.() -> Unit = { val meta = LogUtils.getMetaObject() val metaKeys = meta.keys() while (metaKeys.hasNext()) { From 762c43bd6f6bd56a52c40cccf37d7b8caf7abf88 Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 12 Jul 2022 15:39:00 +0800 Subject: [PATCH 088/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=87=8D?= =?UTF-8?q?=E6=96=B0=E4=B8=8B=E8=BD=BD=E5=8F=96=E6=B6=88=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E6=97=B6=E4=BC=9A=E8=A7=A6=E5=8F=91=E5=BC=82=E5=B8=B8=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=9C=AA=E4=B8=8B=E8=BD=BD=E5=AE=8C=E6=88=90=E7=9A=84=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E4=B9=9F=E5=8F=AF=E8=83=BD=E8=A7=A6=E5=8F=91=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/databind/BindingAdapters.java | 2 +- .../adapter/viewholder/DetailViewHolder.java | 13 +++++++------ .../java/com/gh/vspace/VDownloadManagerFragment.kt | 2 +- app/src/main/java/com/gh/vspace/VHelper.kt | 12 ++++++++---- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java index 66bbd68eb7..afc82d5c94 100644 --- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java +++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java @@ -454,7 +454,7 @@ public class BindingAdapters { String packageName = gameEntity.getApk().get(0).getPackageName(); if (gameEntity.isVGame()) { - VHelper.installOrLaunch((AppCompatActivity) v.getContext(), packageName); + VHelper.installOrLaunch(v.getContext(), packageName); return; } diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java index 532855f230..22f1dbf0d2 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java @@ -242,7 +242,7 @@ public class DetailViewHolder { } if (mGameEntity.isVGame()) { - VHelper.installOrLaunch((AppCompatActivity) mViewHolder.context, mGameEntity.getApk().get(0).getPackageName()); + VHelper.installOrLaunch(mViewHolder.context, mGameEntity.getApk().get(0).getPackageName()); return; } @@ -273,16 +273,17 @@ public class DetailViewHolder { } } + if (mGameEntity.isVGame()) { + VHelper.installOrLaunch(v.getContext(), mGameEntity.getApk().get(0).getPackageName()); + return; + } + PermissionHelper.checkStoragePermissionBeforeAction(mViewHolder.context, () -> { if (mDownloadEntity == null) { mDownloadEntity = DownloadManager.getInstance().getDownloadEntityByUrl(mGameEntity.getApk().get(0).getUrl()); } - if (mDownloadEntity != null) { - if (mGameEntity.isVGame()) { - VHelper.installOrLaunch((AppCompatActivity) v.getContext(), mGameEntity.getApk().get(0).getPackageName()); - return; - } + if (mDownloadEntity != null) { final String path = mDownloadEntity.getPath(); if (FileUtils.isEmptyFile(path)) { Utils.toast(mViewHolder.context, R.string.install_failure_hint); diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index 655630083d..457f1b25f8 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -119,5 +119,5 @@ class VDownloadManagerFragment : override fun shouldLoadMore() = false - override fun isAutomaticLoad(): Boolean = mViewModel.isTypeDownloaded() + override fun isAutomaticLoad(): Boolean = false } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 07f9d9f162..63910661c8 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -159,7 +159,7 @@ object VHelper { * @param packageName 需要获取的畅玩游戏的包名 */ @JvmStatic - fun getVGameSnapshot(packageName: String): VGameEntity? { + fun getVGameSnapshot(packageName: String?): VGameEntity? { return mVGameSnapshotList.find { it.packageName == packageName } } @@ -400,6 +400,8 @@ object VHelper { val result = VirtualAppManager.get().installGame(downloadEntity.path) + // 去掉更新标记 + downloadEntity.isUpdate = false mVGameDao.insert(VGameEntity.from(downloadEntity)) if (result.status == 0) { @@ -462,7 +464,9 @@ object VHelper { ?: getDownloadEntitySnapshotByPackageName(packageName) if (downloadEntity != null) { - if (File(downloadEntity.path).exists()) { + val downloadedFile = File(downloadEntity.path) + if (downloadedFile.exists() + && downloadedFile.length() == downloadEntity.size) { install(context, downloadEntity, true) } else { // 重新下载 @@ -553,7 +557,7 @@ object VHelper { * 根据包名获取下载快照 */ @JvmStatic - fun getDownloadEntitySnapshotByPackageName(packageName: String): DownloadEntity? { + fun getDownloadEntitySnapshotByPackageName(packageName: String?): DownloadEntity? { return getVGameSnapshot(packageName)?.downloadEntity } @@ -660,6 +664,7 @@ object VHelper { originDownloadEntity.platform = updateEntity.platform originDownloadEntity.packageName = updateEntity.packageName originDownloadEntity.versionName = updateEntity.version + originDownloadEntity.isUpdate = true originDownloadEntity.addMetaExtra(Constants.RAW_GAME_ICON, updateEntity.rawIcon) originDownloadEntity.addMetaExtra( Constants.GAME_ICON_SUBSCRIPT, @@ -670,7 +675,6 @@ object VHelper { PackageRepository.removeUpdate(updateEntity.id, true) } - originDownloadEntity.isUpdate = true originDownloadEntity.progress = 0 originDownloadEntity.finalRedirectedUrl = "" originDownloadEntity.percent = 0.0 From f72095efc134fe5389231275ed3dcedcccb3a59a Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 12 Jul 2022 16:52:03 +0800 Subject: [PATCH 089/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=9C=AA?= =?UTF-8?q?=E5=AE=89=E8=A3=85=E7=95=85=E7=8E=A9=E6=9B=B4=E6=96=B0=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E8=BF=9B=E5=85=A5=E6=97=B6=E5=87=BA=E7=8E=B0=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E6=8F=90=E7=A4=BA=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VHelper.kt | 2 ++ app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 63910661c8..55703ac33b 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -60,6 +60,8 @@ object VHelper { private const val KEY_LAST_PLAYED_TIME = "last_played_time" private const val KEY_LAST_ALERT_UPDATE_URL = "last_alert_update_url" + const val DEFAULT_VSPACE_PACKAGENAME = "com.lg.vspace" + private val mDelegateManager by lazy { VirtualAppManager.get() } private var mInstalledInfoList: List = arrayListOf() private val mInstallationLiveData by lazy { MutableLiveData() } diff --git a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt index 1ef23fcf72..62358e0480 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt @@ -96,6 +96,10 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { mBinding.privacyPolicyTv.setOnClickListener { NewFlatLogUtils.logHaloFunEvent("halo_fun_download_dialog_privacy_click") } + + val downloadSnapshot = DownloadManager.getInstance() + .getDownloadEntitySnapshotByPackageName(VHelper.DEFAULT_VSPACE_PACKAGENAME) + mBinding.downloadBtn.setOnClickListener { NewFlatLogUtils.logHaloFunEvent("halo_fun_download_dialog_download_click") @@ -108,7 +112,7 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { downloadEntity.platform = "官方版" downloadEntity.gameId = "62bd412bbbf04747cd3de539" downloadEntity.path = PackageInstaller.getDownloadPathWithId(downloadId, "apk") - downloadEntity.packageName = "com.lg.vspace" + downloadEntity.packageName = VHelper.DEFAULT_VSPACE_PACKAGENAME // 确定下载类型 val downloadType = @@ -134,7 +138,7 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { DataCollectionUtils.uploadDownload(HaloApp.getInstance(), downloadEntity, "开始") } - if (arguments?.getBoolean(KEY_AUTO_DOWNLOAD) == true) { + if (arguments?.getBoolean(KEY_AUTO_DOWNLOAD) == true && downloadSnapshot == null) { mBinding.downloadBtn.performClick() } } From e41b6e4430a99ba6d03bb9006a1d20cb0faf02b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Tue, 12 Jul 2022 17:07:10 +0800 Subject: [PATCH 090/217] =?UTF-8?q?feat:=20=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E7=AB=AF=E5=86=85=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E9=80=82=E9=85=8D=E7=9F=AD=E9=93=BE=E6=8E=A5=20https:?= =?UTF-8?q?//git.shanqu.cc/pm/halo/halo-app-issues/-/issues/1945?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/common/DefaultUrlHandler.kt | 60 ++- .../java/com/gh/common/util/CommentHelper.kt | 3 +- .../com/gh/common/util/PostCommentUtils.java | 8 +- .../collection/CommunityArticleViewModel.kt | 2 +- .../forum/detail/ForumDetailFragment.kt | 4 +- .../forum/detail/ForumDetailViewModel.kt | 129 +++--- .../forum/home/CommunityHomeFragment.kt | 46 +- .../forum/home/CommunityHomeViewModel.kt | 4 +- .../BaseAnswerOrArticleItemViewHolder.kt | 433 +++++++++--------- .../article/detail/ArticleDetailFragment.kt | 10 +- .../article/detail/ArticleDetailViewModel.kt | 24 +- .../qa/comment/NewCommentViewModel.kt | 6 +- .../qa/comment/base/BaseCommentViewModel.kt | 6 +- .../retrofit/service/ApiService.java | 73 ++- 14 files changed, 450 insertions(+), 358 deletions(-) diff --git a/app/src/main/java/com/gh/common/DefaultUrlHandler.kt b/app/src/main/java/com/gh/common/DefaultUrlHandler.kt index b02bf3d072..c93dfdec95 100644 --- a/app/src/main/java/com/gh/common/DefaultUrlHandler.kt +++ b/app/src/main/java/com/gh/common/DefaultUrlHandler.kt @@ -502,6 +502,13 @@ object DefaultUrlHandler { @JvmStatic fun transformNormalScheme(context: Context, url: String, entrance: String): Boolean { + val b = transformNewNormalScheme(context, url, entrance) + if (b) return b + return transformOldNormalScheme(context, url, entrance) + } + + @JvmStatic + fun transformOldNormalScheme(context: Context, url: String, entrance: String): Boolean { val uri = Uri.parse(url) if (uri.host == "www.ghzs666.com" || uri.host == "www.ghzs.com" @@ -513,8 +520,7 @@ object DefaultUrlHandler { uri.path?.apply { when { contains("game") -> { - val gameId = uri.getQueryParameter("gameId") ?: uri.pathSegments.last() - ?: "" + val gameId = uri.getQueryParameter("gameId") ?: uri.pathSegments.last() ?: "" DirectUtils.directToGameDetail(context, gameId, entrance, autoDownload = false, traceEvent = null) } contains("question") -> { @@ -580,6 +586,56 @@ object DefaultUrlHandler { return false } + @JvmStatic + fun transformNewNormalScheme(context: Context, url: String, entrance: String): Boolean { + val uri = Uri.parse(url) + if (uri.host == "www.ghzs666.com" + || uri.host == "www.ghzs.com" + || uri.host == "ask.ghzs.com" + || uri.host == "m.ghzs.com" + || uri.host == "m.ghzs666.com" + || uri.host == "dev-bbs-mobile.ghzs.com" + ) { + Utils.log(uri.path) + uri.path?.apply { + val splits = split("/") + when { + //https://m.ghzs666.com/bbs/thread-帖子ID + splits.size >= 3 && splits[1] == "bbs" && splits[2].startsWith("thread-") -> { + val articleId = splits[2].substring(7) + DirectUtils.directToCommunityArticle( + context, articleId, "", + entrance, "文章链接" + ) + } + //https://m.ghzs666.com/article/文章ID + splits.size >= 3 && splits[1] == "article" -> { + val articleId = splits[2] + DirectUtils.directToArticle(context, articleId, entrance) + } + //https://m.ghzs666.com/column/专题ID + splits.size >= 3 && splits[1] == "column" -> { + val columnId = splits[2] + DirectUtils.directToSubject(context, columnId, "", entrance) + } + //https://m.ghzs666.com/zone/游戏ID + splits.size >= 3 && splits[1] == "zone" -> { + val gameId = splits[2] + DirectUtils.directGameZone(context, gameId, url, entrance) + } + //https://m.ghzs666.com/bbs/video-视频ID + splits.size >= 3 && splits[1] == "bbs" && splits[2].startsWith("video-") -> { + val videoId = splits[2].substring(6) + DirectUtils.directToVideoDetail(context, videoId, entrance) + } + else -> return false + } + } + return true + } + return false + } + /** * 将 url 转换为 LinkEntity (实际只有 type 和 link 两个字段,仅供日志,不保证能用) */ diff --git a/app/src/main/java/com/gh/common/util/CommentHelper.kt b/app/src/main/java/com/gh/common/util/CommentHelper.kt index 4ecfc6f8b1..4f7d036674 100644 --- a/app/src/main/java/com/gh/common/util/CommentHelper.kt +++ b/app/src/main/java/com/gh/common/util/CommentHelper.kt @@ -441,7 +441,6 @@ object CommentHelper { "确定", "取消", { RetrofitManager.getInstance().api .highlightCommunityArticleComment( - communityId, articleId, comment.id ) @@ -502,7 +501,7 @@ object CommentHelper { context, hide, hideDialogHintContent, "确定", "取消", { RetrofitManager.getInstance().api - .hideCommunityArticleComment(communityId, articleId, comment.id) + .hideCommunityArticleComment(articleId, comment.id) .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) .subscribe(hideObserver) diff --git a/app/src/main/java/com/gh/common/util/PostCommentUtils.java b/app/src/main/java/com/gh/common/util/PostCommentUtils.java index 897bbe4b08..10cc2fd356 100644 --- a/app/src/main/java/com/gh/common/util/PostCommentUtils.java +++ b/app/src/main/java/com/gh/common/util/PostCommentUtils.java @@ -81,7 +81,7 @@ public class PostCommentUtils { observable = RetrofitManager.getInstance().getApi().postReplyToCommunityArticleComment(articleCommunityId, articleId, commentEntity.getId(), body); } else { - observable = RetrofitManager.getInstance().getApi().postCommentToCommunityArticle(articleCommunityId, articleId, body); + observable = RetrofitManager.getInstance().getApi().postCommentToCommunityArticle(articleId, body); } } else { if (commentEntity != null) { @@ -122,7 +122,7 @@ public class PostCommentUtils { if (!TextUtils.isEmpty(answerId)) { observable = RetrofitManager.getInstance().getApi().postVoteAnswerComment(answerId, commentId); } else if (!TextUtils.isEmpty(articleId)) { - observable = RetrofitManager.getInstance().getApi().postVoteCommunityArticleComment(articleCommunityId, articleId, commentId); + observable = RetrofitManager.getInstance().getApi().postVoteCommunityArticleComment(articleId, commentId); } else if (!TextUtils.isEmpty(questionId)) { observable = RetrofitManager.getInstance().getApi().postVoteQuestionComment(questionId, commentId); } else { @@ -159,8 +159,8 @@ public class PostCommentUtils { if (!TextUtils.isEmpty(questionId)) { observable = RetrofitManager.getInstance().getApi().postUnVoteQuestionComment(questionId, commentId); - } else if (!TextUtils.isEmpty(articleCommunityId) && !TextUtils.isEmpty(articleId)) { - observable = RetrofitManager.getInstance().getApi().postUnVoteArticleComment(articleCommunityId, articleId, commentId); + } else if (!TextUtils.isEmpty(articleId)) { + observable = RetrofitManager.getInstance().getApi().postUnVoteArticleComment(articleId, commentId); } else { observable = RetrofitManager.getInstance().getApi().postUnVoteVideoComment(videoId, commentId); } diff --git a/app/src/main/java/com/gh/gamecenter/collection/CommunityArticleViewModel.kt b/app/src/main/java/com/gh/gamecenter/collection/CommunityArticleViewModel.kt index 5e2daac106..5ce2af0ed5 100644 --- a/app/src/main/java/com/gh/gamecenter/collection/CommunityArticleViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/collection/CommunityArticleViewModel.kt @@ -88,7 +88,7 @@ class CommunityArticleViewModel(application: Application) : ListViewModel() { diff --git a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailFragment.kt index 1033114957..230214d725 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailFragment.kt @@ -739,8 +739,8 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable { when (requestCode) { CommunityHomeFragment.ARTICLE_REQUEST_CODE -> { val articleId = data?.getStringExtra("article_id") ?: return - val communityId = data?.getStringExtra("community_id") ?: return - mViewModel?.getArticleData(communityId, articleId) +// val communityId = data?.getStringExtra("community_id") ?: return + mViewModel?.getArticleData(articleId) } CommunityHomeFragment.QUESTION_REQUEST_CODE -> { diff --git a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailViewModel.kt b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailViewModel.kt index a12da10a59..532cbd6714 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailViewModel.kt @@ -40,29 +40,29 @@ class ForumDetailViewModel(application: Application, val bbsId: String) : Androi @SuppressLint("CheckResult") fun postForumRead() { mApi.postForumRead(bbsId) - .compose(singleToMain()) - .subscribe(EmptyResponse()) + .compose(singleToMain()) + .subscribe(EmptyResponse()) } fun getForumDetail() { mApi.getForumDetail(bbsId) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(object : Response() { - override fun onResponse(response: ForumDetailEntity?) { - super.onResponse(response) - forumDetail.postValue(Resource.success(response)) - response?.run { - mForumDao.addForum(convertForumDetailEntityToForumEntity()) - EventBus.getDefault().post(EBForumRecordChange(convertForumDetailEntityToForumEntity())) - } + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(object : Response() { + override fun onResponse(response: ForumDetailEntity?) { + super.onResponse(response) + forumDetail.postValue(Resource.success(response)) + response?.run { + mForumDao.addForum(convertForumDetailEntityToForumEntity()) + EventBus.getDefault().post(EBForumRecordChange(convertForumDetailEntityToForumEntity())) } + } - override fun onFailure(e: HttpException?) { - super.onFailure(e) - forumDetail.postValue(Resource.error(e)) - } - }) + override fun onFailure(e: HttpException?) { + super.onFailure(e) + forumDetail.postValue(Resource.error(e)) + } + }) } fun getModeratorsApplyStatus() { @@ -85,64 +85,64 @@ class ForumDetailViewModel(application: Application, val bbsId: String) : Androi @SuppressLint("CheckResult") fun followForum(onSuccess: () -> Unit) { RetrofitManager.getInstance().api - .followForum(bbsId) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(object : BiResponse() { - override fun onSuccess(data: ResponseBody) { - onSuccess.invoke() - } - }) + .followForum(bbsId) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(object : BiResponse() { + override fun onSuccess(data: ResponseBody) { + onSuccess.invoke() + } + }) } @SuppressLint("CheckResult") fun unFollowForum(onSuccess: () -> Unit) { RetrofitManager.getInstance().api - .unFollowForum(bbsId) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(object : BiResponse() { - override fun onSuccess(data: ResponseBody) { - onSuccess.invoke() - } - }) + .unFollowForum(bbsId) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(object : BiResponse() { + override fun onSuccess(data: ResponseBody) { + onSuccess.invoke() + } + }) } - fun getArticleData(communityId: String, articleId: String) { - mApi.getCommunityArticleDetail(communityId, articleId) - .compose(observableToMain()) - .subscribe(object : Response() { - override fun onResponse(response: ArticleDetailEntity?) { - response?.run { - answerLiveData.postValue(convertArticleDetailToAnswer(response)) - } - + fun getArticleData(articleId: String) { + mApi.getCommunityArticleDetail(articleId) + .compose(observableToMain()) + .subscribe(object : Response() { + override fun onResponse(response: ArticleDetailEntity?) { + response?.run { + answerLiveData.postValue(convertArticleDetailToAnswer(response)) } - }) + + } + }) } fun getQuestionDetail(questionId: String) { mApi.getQuestionsById(questionId) - .compose(observableToMain()) - .subscribe(object : Response() { - override fun onResponse(response: QuestionsDetailEntity?) { - response?.run { - answerLiveData.postValue(convertQuestionDetailToAnswer(response)) - } + .compose(observableToMain()) + .subscribe(object : Response() { + override fun onResponse(response: QuestionsDetailEntity?) { + response?.run { + answerLiveData.postValue(convertQuestionDetailToAnswer(response)) } - }) + } + }) } fun getVideoDetail(videoId: String) { mApi.getBbsVideoDetail(videoId) - .compose(observableToMain()) - .subscribe(object : Response() { - override fun onResponse(response: ForumVideoEntity?) { - response?.run { - answerLiveData.postValue(convertVideoDetailToAnswer(response)) - } + .compose(observableToMain()) + .subscribe(object : Response() { + override fun onResponse(response: ForumVideoEntity?) { + response?.run { + answerLiveData.postValue(convertVideoDetailToAnswer(response)) } - }) + } + }) } fun convertArticleDetailToAnswer(articleDetailEntity: ArticleDetailEntity): AnswerEntity { @@ -159,7 +159,7 @@ class ForumDetailViewModel(application: Application, val bbsId: String) : Androi answerEntity.images = articleDetailEntity.images answerEntity.imagesInfo = articleDetailEntity.imagesInfo answerEntity.videos = articleDetailEntity.videos - answerEntity.status = articleDetailEntity.status ?:"" + answerEntity.status = articleDetailEntity.status ?: "" answerEntity.type = "community_article" return answerEntity @@ -201,12 +201,13 @@ class ForumDetailViewModel(application: Application, val bbsId: String) : Androi answerEntity.time = forumVideoEntity.time.upload forumVideoEntity.user.run { answerEntity.user = UserEntity( - id = id, - name = name, - icon = icon, - auth = auth, - badge = badge, - border = border) + id = id, + name = name, + icon = icon, + auth = auth, + badge = badge, + border = border + ) } answerEntity.type = "video" diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/CommunityHomeFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/home/CommunityHomeFragment.kt index 2e3f334b12..20ce0dc489 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/home/CommunityHomeFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/home/CommunityHomeFragment.kt @@ -141,15 +141,15 @@ class CommunityHomeFragment : LazyFragment() { mFragmentList.clear() val tag = "android:switcher:${viewPager.id}:" val forumArticleListFragment = childFragmentManager.findFragmentByTag("${tag}0") - ?: ForumArticleListFragment().with(bundleOf(EntranceConsts.KEY_ENTRANCE to "社区", EntranceConsts.KEY_PATH to "推荐")) + ?: ForumArticleListFragment().with(bundleOf(EntranceConsts.KEY_ENTRANCE to "社区", EntranceConsts.KEY_PATH to "推荐")) mFragmentList.add(forumArticleListFragment) val forumFragment = childFragmentManager.findFragmentByTag("${tag}1") - ?: ForumFragment().with(bundleOf(EntranceConsts.KEY_ENTRANCE to "社区")) + ?: ForumFragment().with(bundleOf(EntranceConsts.KEY_ENTRANCE to "社区")) mFragmentList.add(forumFragment) val activityFragment = childFragmentManager.findFragmentByTag("${tag}2") - ?: ForumActivityFragment().with(bundleOf(EntranceConsts.KEY_ENTRANCE to "活动")) + ?: ForumActivityFragment().with(bundleOf(EntranceConsts.KEY_ENTRANCE to "活动")) mFragmentList.add(activityFragment) viewPager.run { @@ -195,13 +195,25 @@ class CommunityHomeFragment : LazyFragment() { (mTabList[position] as TextView).run { layoutParams.width = (DEFAULT_TAB_TEXT_WIDTH + ((1 - positionOffset) * 4F.dip2px())).roundToInt() textSize = (DEFAULT_TAB_TEXT_SIZE + ((1 - positionOffset) * 4)).roundTo(1) - setTextColor(ColorUtils.blendARGB(TAB_DEFAULT_COLOR.toColor(requireContext()), TAB_SELECTED_COLOR.toColor(requireContext()), 1 - positionOffset)) + setTextColor( + ColorUtils.blendARGB( + TAB_DEFAULT_COLOR.toColor(requireContext()), + TAB_SELECTED_COLOR.toColor(requireContext()), + 1 - positionOffset + ) + ) } if (mTabList[position + 1] is TextView) { (mTabList[position + 1] as TextView).run { layoutParams.width = (DEFAULT_TAB_TEXT_WIDTH + ((positionOffset) * 4F.dip2px())).roundToInt() textSize = (DEFAULT_TAB_TEXT_SIZE + ((positionOffset) * 4)).roundTo(1) - setTextColor(ColorUtils.blendARGB(TAB_DEFAULT_COLOR.toColor(requireContext()), TAB_SELECTED_COLOR.toColor(requireContext()), positionOffset)) + setTextColor( + ColorUtils.blendARGB( + TAB_DEFAULT_COLOR.toColor(requireContext()), + TAB_SELECTED_COLOR.toColor(requireContext()), + positionOffset + ) + ) } } else { (mTabList[position + 1] as TabItemCommunityBinding).run { @@ -211,7 +223,13 @@ class CommunityHomeFragment : LazyFragment() { tabImg.scaleY = (DEFAULT_TAB_IMG_HEIGHT + ((positionOffset) * 4)).roundTo(1) / DEFAULT_TAB_IMG_HEIGHT if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { tabImg.imageTintList = - ColorStateList.valueOf(ColorUtils.blendARGB(TAB_DEFAULT_COLOR.toColor(requireContext()), TAB_SELECTED_COLOR.toColor(requireContext()), positionOffset)) + ColorStateList.valueOf( + ColorUtils.blendARGB( + TAB_DEFAULT_COLOR.toColor(requireContext()), + TAB_SELECTED_COLOR.toColor(requireContext()), + positionOffset + ) + ) } } } @@ -433,8 +451,8 @@ class CommunityHomeFragment : LazyFragment() { when (requestCode) { ARTICLE_REQUEST_CODE -> { val articleId = data?.getStringExtra("article_id") ?: return - val communityId = data?.getStringExtra("community_id") ?: return - mViewModel?.getArticleData(communityId, articleId) +// val communityId = data?.getStringExtra("community_id") ?: return + mViewModel?.getArticleData(articleId) } QUESTION_REQUEST_CODE -> { @@ -531,7 +549,11 @@ class CommunityHomeFragment : LazyFragment() { navigationBg.setBackgroundColor(R.color.transparent.toColor(requireContext())) navigationBg.setImageDrawable(null) } else if (viewPager.currentItem == TAB_RECOMMEND_INDEX) { - navigationBg.setBackgroundColor(if (mNightMode && y > 0) R.color.background_white.toColor(requireContext()) else if (mNightMode && y == 0) R.color.background.toColor(requireContext()) else R.color.transparent.toColor(requireContext())) + navigationBg.setBackgroundColor( + if (mNightMode && y > 0) R.color.background_white.toColor(requireContext()) else if (mNightMode && y == 0) R.color.background.toColor( + requireContext() + ) else R.color.transparent.toColor(requireContext()) + ) navigationBg.setImageDrawable(null) } else if (mNightMode) { navigationBg.setBackgroundColor(R.color.background_white.toColor(requireContext())) @@ -552,7 +574,11 @@ class CommunityHomeFragment : LazyFragment() { } } mBinding?.run { - root.setBackgroundColor(if (viewPager.currentItem == TAB_FORUM_INDEX) R.color.background_white.toColor(requireContext()) else R.color.background.toColor(requireContext())) + root.setBackgroundColor( + if (viewPager.currentItem == TAB_FORUM_INDEX) R.color.background_white.toColor(requireContext()) else R.color.background.toColor( + requireContext() + ) + ) topBg.run { visibleIf(!mNightMode) post { diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/CommunityHomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/forum/home/CommunityHomeViewModel.kt index 4fa40e2284..3daf5fad05 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/home/CommunityHomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/home/CommunityHomeViewModel.kt @@ -19,8 +19,8 @@ class CommunityHomeViewModel(application: Application) : AndroidViewModel(applic private val mApi = RetrofitManager.getInstance().api val articleLiveData = MediatorLiveData() - fun getArticleData(communityId: String, articleId: String) { - mApi.getCommunityArticleDetail(communityId, articleId) + fun getArticleData(articleId: String) { + mApi.getCommunityArticleDetail(articleId) .compose(observableToMain()) .subscribe(object : Response() { override fun onResponse(response: ArticleDetailEntity?) { diff --git a/app/src/main/java/com/gh/gamecenter/qa/answer/BaseAnswerOrArticleItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/qa/answer/BaseAnswerOrArticleItemViewHolder.kt index 42c5ff3e9d..2e84e8ca0d 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/answer/BaseAnswerOrArticleItemViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/answer/BaseAnswerOrArticleItemViewHolder.kt @@ -60,28 +60,38 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH when (entity.type) { "community_article" -> { val communityId = if (!entity.communityId.isNullOrEmpty()) entity.communityId - ?: "" else entity.bbs.id - val intent = ArticleDetailActivity.getCommentIntent(itemView.context, - CommunityEntity(communityId, entity.communityName ?: ""), - entity.id ?: "", entrance, "") + ?: "" else entity.bbs.id + val intent = ArticleDetailActivity.getCommentIntent( + itemView.context, + CommunityEntity(communityId, entity.communityName ?: ""), + entity.id ?: "", entrance, "" + ) itemView.context.startActivity(intent) } "video" -> { val communityId = if (!entity.communityId.isNullOrEmpty()) entity.communityId ?: "" else entity.bbs.id - itemView.context.startActivity(ForumVideoDetailActivity.getIntent(itemView.context, entity.id - ?: "", communityId, true)) + itemView.context.startActivity( + ForumVideoDetailActivity.getIntent( + itemView.context, entity.id + ?: "", communityId, true + ) + ) } "answer" -> { - val intent = CommentActivity.getAnswerCommentIntent(itemView.context, - entity.id ?: "", - entity.count.comment, - false) + val intent = CommentActivity.getAnswerCommentIntent( + itemView.context, + entity.id ?: "", + entity.count.comment, + false + ) itemView.context.startActivity(intent) } else -> { - val intent = NewQuestionDetailActivity.getCommentIntent(itemView.context, entity.id - ?: "", entrance, "") + val intent = NewQuestionDetailActivity.getCommentIntent( + itemView.context, entity.id + ?: "", entrance, "" + ) itemView.context.startActivity(intent) } } @@ -156,10 +166,15 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH id = entity.id, title = entity.title, images = entity.images, - description = entity.brief) - it.context.startActivity(QuestionsInviteActivity.getIntent(it.context, - questionsDetailEntity, - entrance)) + description = entity.brief + ) + it.context.startActivity( + QuestionsInviteActivity.getIntent( + it.context, + questionsDetailEntity, + entrance + ) + ) } } @@ -173,7 +188,16 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH "video" -> "视频帖评论" else -> "提问帖评论" } - NewLogUtils.logRecommendFeedContentClick("click_for_you_comment", contentType, id, (position + 1), bbs.id, bbsType, user.id ?: "", commentType) + NewLogUtils.logRecommendFeedContentClick( + "click_for_you_comment", + contentType, + id, + (position + 1), + bbs.id, + bbsType, + user.id ?: "", + commentType + ) } } @@ -192,10 +216,12 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH else -> { val communityId = if (entity.community.id.isNotEmpty()) entity.community.id else UserManager.getInstance().community.id - val intent = ArticleDetailActivity.getCommentIntent(itemView.context, - CommunityEntity(communityId, entity.community.name), - entity.id, - entrance, "") + val intent = ArticleDetailActivity.getCommentIntent( + itemView.context, + CommunityEntity(communityId, entity.community.name), + entity.id, + entrance, "" + ) itemView.context.startActivity(intent) MtaHelper.onEvent(getEventId(entrance), getKey(entrance), "评论图标") } @@ -209,7 +235,15 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH CheckLoginUtils.checkLogin(itemView.context, entrance) { if (entrance == "社区+(推荐)" && position != null) { entity.run { - NewLogUtils.logRecommendFeedContentClick("click_for_you_like", contentType, id, position + 1, bbs.id, bbsType, user.id ?: "") + NewLogUtils.logRecommendFeedContentClick( + "click_for_you_like", + contentType, + id, + position + 1, + bbs.id, + bbsType, + user.id ?: "" + ) } } @@ -281,75 +315,72 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH } if (entity.type == "video") { RetrofitManager.getInstance() - .api.voteVideo(entity.id) - .subscribeOn(Schedulers.io()) - .subscribe(object : BiResponse() { - override fun onSuccess(data: ResponseBody) { - //Utils.toast(getApplication(), "已点赞") - EnergyTaskHelper.postEnergyTask("vote_video", entity.id) - } + .api.voteVideo(entity.id) + .subscribeOn(Schedulers.io()) + .subscribe(object : BiResponse() { + override fun onSuccess(data: ResponseBody) { + //Utils.toast(getApplication(), "已点赞") + EnergyTaskHelper.postEnergyTask("vote_video", entity.id) + } - override fun onFailure(exception: Exception) { - super.onFailure(exception) - entity.count.vote = entity.count.vote - 1 - entity.me.isVoted = false - voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同" - setVoteAndCommentStyle(entity) - } - }) + override fun onFailure(exception: Exception) { + super.onFailure(exception) + entity.count.vote = entity.count.vote - 1 + entity.me.isVoted = false + voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同" + setVoteAndCommentStyle(entity) + } + }) } else { val voteObservable = if (entity.type == "community_article") { - val communityId = if (entity.articleCommunityId.isNotEmpty()) entity.articleCommunityId - else entity.bbs.id - RetrofitManager.getInstance().api - .postCommunityArticleVote(communityId, entity.id) + RetrofitManager.getInstance().api.postCommunityArticleVote(entity.id) } else { RetrofitManager.getInstance().api - .postVoteQuestionComment(entity.questions.id, entity.id) - .map { GsonUtils.fromJson(it.string(), VoteEntity::class.java) } + .postVoteQuestionComment(entity.questions.id, entity.id) + .map { GsonUtils.fromJson(it.string(), VoteEntity::class.java) } } voteObservable - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(object : Response() { - override fun onResponse(response: VoteEntity?) { - if (entity.type == "community_article") { - entity.me.isCommunityArticleVote = true - EnergyTaskHelper.postEnergyTask("vote_community_article", entity.id) - } else { - entity.me.isAnswerVoted = true - EnergyTaskHelper.postEnergyTask("vote_answer", entity.id) - } - ToastUtils.showToast("已赞同") + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(object : Response() { + override fun onResponse(response: VoteEntity?) { + if (entity.type == "community_article") { + entity.me.isCommunityArticleVote = true + EnergyTaskHelper.postEnergyTask("vote_community_article", entity.id) + } else { + entity.me.isAnswerVoted = true + EnergyTaskHelper.postEnergyTask("vote_answer", entity.id) } + ToastUtils.showToast("已赞同") + } - override fun onFailure(e: HttpException?) { - ErrorHelper.handleErrorWithCustomizedHandler(itemView.context, e?.response()?.errorBody()?.string(), false) { - if (403008 == it) { - Utils.toast(itemView.context, R.string.ask_vote_hint) - true - } else if (403036 == it) { - Utils.toast(itemView.context, R.string.ask_vote_limit_hint) - true - } else if (404001 == it) { - Utils.toast(itemView.context, "内容可能已被删除") - entity.active = false - setVoteAndCommentStyle(entity) - true + override fun onFailure(e: HttpException?) { + ErrorHelper.handleErrorWithCustomizedHandler(itemView.context, e?.response()?.errorBody()?.string(), false) { + if (403008 == it) { + Utils.toast(itemView.context, R.string.ask_vote_hint) + true + } else if (403036 == it) { + Utils.toast(itemView.context, R.string.ask_vote_limit_hint) + true + } else if (404001 == it) { + Utils.toast(itemView.context, "内容可能已被删除") + entity.active = false + setVoteAndCommentStyle(entity) + true + } else { + entity.count.vote = entity.count.vote - 1 + if (entity.type == "community_article") { + entity.me.isCommunityArticleVote = true } else { - entity.count.vote = entity.count.vote - 1 - if (entity.type == "community_article") { - entity.me.isCommunityArticleVote = true - } else { - entity.me.isAnswerVoted = true - } - voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同" - setVoteAndCommentStyle(entity) - false + entity.me.isAnswerVoted = true } + voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同" + setVoteAndCommentStyle(entity) + false } } - }) + } + }) } entity.count.vote = entity.count.vote + 1 voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同" @@ -366,127 +397,32 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH if (entity.type == "video") { RetrofitManager.getInstance() - .api.undoVoteVideo(entity.id) - .subscribeOn(Schedulers.io()) - .subscribe(object : BiResponse() { - override fun onSuccess(data: ResponseBody) { - Utils.toast(itemView.context, "取消点赞") - } + .api.undoVoteVideo(entity.id) + .subscribeOn(Schedulers.io()) + .subscribe(object : BiResponse() { + override fun onSuccess(data: ResponseBody) { + Utils.toast(itemView.context, "取消点赞") + } - override fun onFailure(exception: Exception) { - super.onFailure(exception) - entity.count.vote = entity.count.vote + 1 - entity.me.isVoted = true - voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同" - setVoteAndCommentStyle(entity) - } - }) + override fun onFailure(exception: Exception) { + super.onFailure(exception) + entity.count.vote = entity.count.vote + 1 + entity.me.isVoted = true + voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同" + setVoteAndCommentStyle(entity) + } + }) } else { val unVoteObservable = if (entity.type == "community_article") { entity.me.isCommunityArticleVote = false - - val communityId = if (entity.articleCommunityId.isNotEmpty()) entity.articleCommunityId - else entity.bbs.id - RetrofitManager.getInstance().api - .postCommunityArticleUnVote(communityId, entity.id) + RetrofitManager.getInstance().api.postCommunityArticleUnVote(entity.id) } else { entity.me.isAnswerVoted = false RetrofitManager.getInstance().api - .postAnswerUnvote(entity.id) + .postAnswerUnvote(entity.id) } unVoteObservable - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(object : Response() { - override fun onResponse(response: VoteEntity?) { - Utils.toast(itemView.context, "取消赞同") - } - - override fun onFailure(e: HttpException?) { - ErrorHelper.handleErrorWithCustomizedHandler(itemView.context, e?.response()?.errorBody()?.string(), false) { - if (403008 == it) { - Utils.toast(itemView.context, R.string.ask_vote_hint) - true - } else if (403036 == it) { - Utils.toast(itemView.context, R.string.ask_vote_limit_hint) - true - } else if (404001 == it) { - Utils.toast(itemView.context, "内容可能已被删除") - entity.active = false - setVoteAndCommentStyle(entity) - true - } else { - entity.count.vote = entity.count.vote + 1 - if (entity.type == "community_article") { - entity.me.isCommunityArticleVote = true - } else { - entity.me.isAnswerVoted = true - } - voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同" - setVoteAndCommentStyle(entity) - false - } - } - } - }) - } - } - - fun voteArticle(entity: ArticleEntity) { - entity.count.vote = entity.count.vote + 1 - voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同" - playVoteAnimation() - - val communityId = if (entity.community.id.isEmpty()) entity.bbs.id - else entity.community.id - RetrofitManager.getInstance().api - .postCommunityArticleVote(communityId, entity.id) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(object : Response() { - override fun onResponse(response: VoteEntity?) { - entity.me.isCommunityArticleVote = true - ToastUtils.showToast("已赞同") - EnergyTaskHelper.postEnergyTask("vote_community_article", entity.id) - } - - override fun onFailure(e: HttpException?) { - ErrorHelper.handleErrorWithCustomizedHandler(itemView.context, e?.response()?.errorBody()?.string(), false) { - if (403008 == it) { - Utils.toast(itemView.context, R.string.ask_vote_hint) - true - } else if (403036 == it) { - Utils.toast(itemView.context, R.string.ask_vote_limit_hint) - true - } else if (404001 == it) { - Utils.toast(itemView.context, "内容可能已被删除") - entity.active = false - setVoteAndCommentStyle(entity.transformAnswerEntity()) - true - } else { - entity.count.vote = entity.count.vote - 1 - entity.me.isCommunityArticleVote = false - voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同" - setVoteAndCommentStyle(entity.transformAnswerEntity()) - false - } - } - } - }) - } - - fun cancelArticleVote(entity: ArticleEntity) { - entity.count.vote = entity.count.vote - 1 - entity.me.isCommunityArticleVote = false - voteIcon.isChecked = false - voteCount.setTextColor(R.color.text_subtitleDesc.toColor()) - voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同" - - val communityId = if (entity.community.id.isEmpty()) entity.bbs.id - else entity.community.id - RetrofitManager.getInstance().api - .postCommunityArticleUnVote(communityId, entity.id) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(object : Response() { @@ -505,36 +441,123 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH } else if (404001 == it) { Utils.toast(itemView.context, "内容可能已被删除") entity.active = false - setVoteAndCommentStyle(entity.transformAnswerEntity()) + setVoteAndCommentStyle(entity) true } else { entity.count.vote = entity.count.vote + 1 - entity.me.isCommunityArticleVote = true + if (entity.type == "community_article") { + entity.me.isCommunityArticleVote = true + } else { + entity.me.isAnswerVoted = true + } voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同" - setVoteAndCommentStyle(entity.transformAnswerEntity()) + setVoteAndCommentStyle(entity) false } } } }) + } + } + + fun voteArticle(entity: ArticleEntity) { + entity.count.vote = entity.count.vote + 1 + voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同" + playVoteAnimation() + + RetrofitManager.getInstance().api + .postCommunityArticleVote(entity.id) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(object : Response() { + override fun onResponse(response: VoteEntity?) { + entity.me.isCommunityArticleVote = true + ToastUtils.showToast("已赞同") + EnergyTaskHelper.postEnergyTask("vote_community_article", entity.id) + } + + override fun onFailure(e: HttpException?) { + ErrorHelper.handleErrorWithCustomizedHandler(itemView.context, e?.response()?.errorBody()?.string(), false) { + if (403008 == it) { + Utils.toast(itemView.context, R.string.ask_vote_hint) + true + } else if (403036 == it) { + Utils.toast(itemView.context, R.string.ask_vote_limit_hint) + true + } else if (404001 == it) { + Utils.toast(itemView.context, "内容可能已被删除") + entity.active = false + setVoteAndCommentStyle(entity.transformAnswerEntity()) + true + } else { + entity.count.vote = entity.count.vote - 1 + entity.me.isCommunityArticleVote = false + voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同" + setVoteAndCommentStyle(entity.transformAnswerEntity()) + false + } + } + } + }) + } + + fun cancelArticleVote(entity: ArticleEntity) { + entity.count.vote = entity.count.vote - 1 + entity.me.isCommunityArticleVote = false + voteIcon.isChecked = false + voteCount.setTextColor(R.color.text_subtitleDesc.toColor()) + voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同" + + RetrofitManager.getInstance().api + .postCommunityArticleUnVote(entity.id) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(object : Response() { + override fun onResponse(response: VoteEntity?) { + Utils.toast(itemView.context, "取消赞同") + } + + override fun onFailure(e: HttpException?) { + ErrorHelper.handleErrorWithCustomizedHandler(itemView.context, e?.response()?.errorBody()?.string(), false) { + if (403008 == it) { + Utils.toast(itemView.context, R.string.ask_vote_hint) + true + } else if (403036 == it) { + Utils.toast(itemView.context, R.string.ask_vote_limit_hint) + true + } else if (404001 == it) { + Utils.toast(itemView.context, "内容可能已被删除") + entity.active = false + setVoteAndCommentStyle(entity.transformAnswerEntity()) + true + } else { + entity.count.vote = entity.count.vote + 1 + entity.me.isCommunityArticleVote = true + voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同" + setVoteAndCommentStyle(entity.transformAnswerEntity()) + false + } + } + } + }) } fun followUser(entity: AnswerEntity, callback: EmptyCallback?) { RetrofitManager.getInstance().api - .postFollowing(entity.user.id) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(object : Response() { - override fun onResponse(response: ResponseBody?) { - super.onResponse(response) - callback?.onCallback() - } + .postFollowing(entity.user.id) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(object : Response() { + override fun onResponse(response: ResponseBody?) { + super.onResponse(response) + callback?.onCallback() + } - override fun onFailure(e: HttpException?) { - super.onFailure(e) - Utils.toast(itemView.context, R.string.loading_failed_hint) - } - }) + override fun onFailure(e: HttpException?) { + super.onFailure(e) + Utils.toast(itemView.context, R.string.loading_failed_hint) + } + }) } private fun playVoteAnimation() { diff --git a/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailFragment.kt index 92822f1224..e2672d90ef 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailFragment.kt @@ -676,10 +676,7 @@ class ArticleDetailFragment : BaseCommentFragment() { @@ -105,7 +104,7 @@ class ArticleDetailViewModel( } fun cancelLikeArticle() { - mApi.postCommunityArticleUnVote(communityId, articleId) + mApi.postCommunityArticleUnVote(articleId) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(object : Response() { @@ -126,7 +125,7 @@ class ArticleDetailViewModel( } fun likeArticle() { - mApi.postCommunityArticleVote(communityId, articleId) + mApi.postCommunityArticleVote(articleId) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(object : Response() { @@ -227,13 +226,11 @@ class ArticleDetailViewModel( val observable = if (isCollection) { mApi.postCommunityArticleFavorites( UserManager.getInstance().userId, - communityId, articleId ) } else { mApi.deleteCommunityArticleFavorites( UserManager.getInstance().userId, - communityId, articleId ) } @@ -309,8 +306,8 @@ class ArticleDetailViewModel( }) } - fun doHighlightThisArticle(communityId: String, articleId: String?) { - mApi.highlightCommunityArticle(communityId, articleId) + fun doHighlightThisArticle(articleId: String?) { + mApi.highlightCommunityArticle(articleId) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(object : Response() { @@ -326,8 +323,8 @@ class ArticleDetailViewModel( }) } - fun cancelHighlightThisArticle(communityId: String, articleId: String){ - mApi.cancelHighlightCommunityArticle(communityId, articleId) + fun cancelHighlightThisArticle(articleId: String) { + mApi.cancelHighlightCommunityArticle(articleId) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(object : Response() { @@ -359,8 +356,8 @@ class ArticleDetailViewModel( }) } - fun doHideThisArticle(communityId: String, articleId: String?) { - mApi.hideCommunityArticle(communityId, articleId) + fun doHideThisArticle(articleId: String?) { + mApi.hideCommunityArticle(articleId) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(object : Response() { @@ -377,12 +374,11 @@ class ArticleDetailViewModel( } fun modifyArticleActivityTag( - communityId: String, articleId: String, label: ActivityLabelEntity? ) { val body = json { "tag_activity_id" to label?.id }.toRequestBody() - mApi.modifyArticleActivityTag(communityId, articleId, body) + mApi.modifyArticleActivityTag(articleId, body) .compose(observableToMain()) .subscribe(object : Response() { override fun onResponse(response: ResponseBody?) { diff --git a/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt index 228d125dc6..2e1ed23db3 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt @@ -56,7 +56,7 @@ open class NewCommentViewModel( val pictureLiveData = MutableLiveData>() init { - commentDraftDao = AppDatabase.getInstance().commentDraftDao() + commentDraftDao = AppDatabase.getInstance().commentDraftDao() } override fun provideDataObservable(page: Int): Observable>? { @@ -66,7 +66,7 @@ open class NewCommentViewModel( CommentType.ANSWER -> api.getAnswerCommentList(answerId, page) CommentType.ANSWER_CONVERSATION -> api.getAnswerCommentConversationList(answerId, commentId, page) - CommentType.COMMUNITY_ARTICLE -> api.getCommunityArticleCommentList(communityId, articleId, "time.create:1", page, mapOf()) + CommentType.COMMUNITY_ARTICLE -> api.getCommunityArticleCommentList(articleId, "time.create:1", page, mapOf()) CommentType.COMMUNITY_ARTICLE_CONVERSATION -> api.getCommunityArticleCommentConversation(communityId, articleId, commentId, page) CommentType.VIDEO -> api.getVideoCommentList(videoId, page, mapOf()) @@ -141,7 +141,7 @@ open class NewCommentViewModel( CommentType.COMMUNITY_ARTICLE, CommentType.COMMUNITY_ARTICLE_CONVERSATION -> { if (commentEntity == null) { - api.postCommentToCommunityArticle(communityId, articleId, body) + api.postCommentToCommunityArticle(articleId, body) } else { api.postReplyToCommunityArticleComment(communityId, articleId, commentEntity.id, body) } diff --git a/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt index da00e63019..f1edf16a47 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt @@ -262,7 +262,7 @@ abstract class BaseCommentViewModel( mApi.deleteQuestionComment(questionId, entity.id).toObservable() } articleId.isNotEmpty() -> { - mApi.hideCommunityArticleComment(communityId, articleId, entity.id) + mApi.hideCommunityArticleComment(articleId, entity.id) } else -> null } ?: return @@ -305,7 +305,7 @@ abstract class BaseCommentViewModel( } when { articleId.isNotEmpty() -> { - mApi.postArticleCommentTop(communityId, articleId, commentId, map) + mApi.postArticleCommentTop(articleId, commentId, map) } questionId.isNotEmpty() -> { mApi.postQuestionCommentTop(questionId, commentId, map) @@ -318,7 +318,7 @@ abstract class BaseCommentViewModel( } else { when { articleId.isNotEmpty() -> { - mApi.postArticleCommentUnTop(communityId, articleId, commentId) + mApi.postArticleCommentUnTop(articleId, commentId) } questionId.isNotEmpty() -> { mApi.postQuestionCommentUnTop(questionId, commentId) diff --git a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java index 1a6154a056..f451679903 100644 --- a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java +++ b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java @@ -1299,8 +1299,8 @@ public interface ApiService { */ @GET("users/{user_id}/histories") Single> getPersonalHistoryCount(@Path("user_id") String userId, - @Query("channel") String channel, - @Query("filter") String filter); + @Query("channel") String channel, + @Query("filter") String filter); /** * 检测游戏是否开启社区,用在游戏详情页的答案列表。如果有可用答案,将会返回社区ID和专题ID @@ -1413,20 +1413,20 @@ public interface ApiService { /** * 获取社区文章详情 */ - @GET("communities/{community_id}/articles/{article_id}?view=detail") - Observable getCommunityArticleDetail(@Path("community_id") String communityId, @Path("article_id") String articleId); + @GET("communities/articles/{article_id}?view=detail") + Observable getCommunityArticleDetail(@Path("article_id") String articleId); /** * 点赞社区文章 */ - @POST("communities/{community_id}/articles/{article_id}:vote") - Observable postCommunityArticleVote(@Path("community_id") String communityId, @Path("article_id") String articleId); + @POST("communities/articles/{article_id}:vote") + Observable postCommunityArticleVote(@Path("article_id") String articleId); /** * 取消点赞社区文章 */ - @POST("communities/{community_id}/articles/{article_id}:unvote") - Observable postCommunityArticleUnVote(@Path("community_id") String communityId, @Path("article_id") String articleId); + @POST("communities/articles/{article_id}:unvote") + Observable postCommunityArticleUnVote(@Path("article_id") String articleId); /** * 踩社区文章 @@ -1461,25 +1461,22 @@ public interface ApiService { /** * 收藏社区文章 */ - @POST("users/{user_id}/favorites/communities/{community_id}/articles/{article_id}") + @POST("users/{user_id}/favorites/communities/articles/{article_id}") Observable postCommunityArticleFavorites(@Path("user_id") String userId, - @Path("community_id") String communityId, @Path("article_id") String articleId); /** * 取消收藏社区文章 */ - @DELETE("users/{user_id}/favorites/communities/{community_id}/articles/{article_id}") + @DELETE("users/{user_id}/favorites/communities/articles/{article_id}") Observable deleteCommunityArticleFavorites(@Path("user_id") String userId, - @Path("community_id") String communityId, @Path("article_id") String articleId); /** * 获取社区文章评论列表.可以分页 */ - @GET("communities/{community_id}/articles/{article_id}/comments") - Observable> getCommunityArticleCommentList(@Path("community_id") String communityId, - @Path("article_id") String articleId, + @GET("communities/articles/{article_id}/comments") + Observable> getCommunityArticleCommentList(@Path("article_id") String articleId, @Query("sort") String type, @Query("page") int page, @QueryMap Map params); @@ -1515,9 +1512,8 @@ public interface ApiService { /** * 评论社区文章评论 */ - @POST("communities/{community_id}/articles/{article_id}/comments") - Observable postCommentToCommunityArticle(@Path("community_id") String communityId, - @Path("article_id") String articleId, + @POST("communities/articles/{article_id}/comments") + Observable postCommentToCommunityArticle(@Path("article_id") String articleId, @Body RequestBody body); /** @@ -1532,9 +1528,8 @@ public interface ApiService { /** * 对社区文章评论的点赞 */ - @POST("communities/{community_id}/articles/{article_id}/comments/{comment_id}:vote") - Observable postVoteCommunityArticleComment(@Path("community_id") String communityId, - @Path("article_id") String articled, + @POST("communities/articles/{article_id}/comments/{comment_id}:vote") + Observable postVoteCommunityArticleComment(@Path("article_id") String articled, @Path("comment_id") String commentId); /** @@ -1738,33 +1733,33 @@ public interface ApiService { /** * 加精社区文章 */ - @POST("communities/{community_id}/articles/{article_id}:choiceness") - Observable highlightCommunityArticle(@Path("community_id") String communityId, @Path("article_id") String articleId); + @POST("communities/articles/{article_id}:choiceness") + Observable highlightCommunityArticle(@Path("article_id") String articleId); /** * 取消加精社区文章 */ - @POST("communities/{bbs_id}/articles/{article_id}:cancel_choiceness") - Observable cancelHighlightCommunityArticle(@Path("bbs_id") String bbsId, @Path("article_id") String articleId); + @POST("communities/articles/{article_id}:cancel_choiceness") + Observable cancelHighlightCommunityArticle(@Path("article_id") String articleId); /** * 隐藏社区文章 */ - @POST("communities/{community_id}/articles/{article_id}:hide") - Observable hideCommunityArticle(@Path("community_id") String communityId, @Path("article_id") String articleId); + @POST("communities/articles/{article_id}:hide") + Observable hideCommunityArticle(@Path("article_id") String articleId); /** * 置顶社区文章评论 */ - @POST("communities/{community_id}/articles/{article_id}/comments/{comment_id}:set-top") - Observable highlightCommunityArticleComment(@Path("community_id") String communityId, @Path("article_id") String articleId, @Path("comment_id") String commendId); + @POST("communities/articles/{article_id}/comments/{comment_id}:set-top") + Observable highlightCommunityArticleComment(@Path("article_id") String articleId, @Path("comment_id") String commendId); /** * 隐藏社区文章评论 */ - @POST("communities/{community_id}/articles/{article_id}/comments/{comment_id}:hide") - Observable hideCommunityArticleComment(@Path("community_id") String communityId, @Path("article_id") String articleId, @Path("comment_id") String commendId); + @POST("communities/articles/{article_id}/comments/{comment_id}:hide") + Observable hideCommunityArticleComment(@Path("article_id") String articleId, @Path("comment_id") String commendId); /** * 设置回答详情的的评论区域是否开启 @@ -2815,14 +2810,14 @@ public interface ApiService { /** * 置顶评论 */ - @POST("communities/{community_id}/articles/{article_id}/comments/{comment_id}:set-top") - Observable postArticleCommentTop(@Path("community_id") String communityId, @Path("article_id") String articleId, @Path("comment_id") String commentId, @QueryMap Map params); + @POST("communities/articles/{article_id}/comments/{comment_id}:set-top") + Observable postArticleCommentTop(@Path("article_id") String articleId, @Path("comment_id") String commentId, @QueryMap Map params); /** * 取消置顶评论 */ - @POST("communities/{community_id}/articles/{article_id}/comments/{comment_id}:unset-top") - Observable postArticleCommentUnTop(@Path("community_id") String communityId, @Path("article_id") String articleId, @Path("comment_id") String commentId); + @POST("communities/articles/{article_id}/comments/{comment_id}:unset-top") + Observable postArticleCommentUnTop(@Path("article_id") String articleId, @Path("comment_id") String commentId); /** * 获取推荐的论坛 @@ -3212,8 +3207,8 @@ public interface ApiService { /** * 版主修改社区文章活动标签 */ - @POST("communities/{community_id}/articles/{article_id}/activity_tags") - Observable modifyArticleActivityTag(@Path("community_id") String communityId, @Path("article_id") String articleId, @Body RequestBody body); + @POST("communities/articles/{article_id}/activity_tags") + Observable modifyArticleActivityTag(@Path("article_id") String articleId, @Body RequestBody body); /** * 版主修改视频帖活动标签 @@ -3528,8 +3523,8 @@ public interface ApiService { /** * 取消帖子评论点赞 */ - @POST("communities/{community_id}/articles/{article_id}/comments/{comment_id}:unvote") - Observable postUnVoteArticleComment(@Path("community_id") String communityId, @Path("article_id") String articleId, @Path("comment_id") String commentId); + @POST("communities/articles/{article_id}/comments/{comment_id}:unvote") + Observable postUnVoteArticleComment(@Path("article_id") String articleId, @Path("comment_id") String commentId); /** * 置顶视频评论 From 47beb3eeb2f52bd00c5efd20fa776b0f7785a2bc Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 12 Jul 2022 17:35:24 +0800 Subject: [PATCH 091/217] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4=E5=86=97?= =?UTF-8?q?=E4=BD=99=E5=88=B7=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt b/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt index 1c2d0d7e3c..a1eb8f58de 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt @@ -276,7 +276,6 @@ class HomeFragment : LazyFragment() { @Subscribe(threadMode = ThreadMode.MAIN) fun onEventMainThread(status: EBDownloadStatus) { if ("delete" == status.status) { - mViewModel.refreshRecentVGameIfNeeded() mListAdapter.notifyItemAndRemoveDownload(status) } } From 00f90d3617e6caa695ba13bc80e613b862cfcfa9 Mon Sep 17 00:00:00 2001 From: juntao Date: Wed, 13 Jul 2022 10:10:32 +0800 Subject: [PATCH 092/217] =?UTF-8?q?fix:=20block=20focus=20=E9=81=BF?= =?UTF-8?q?=E5=85=8D=E6=9B=B4=E6=96=B0=E6=97=B6=E5=87=BA=E7=8E=B0=E5=A5=87?= =?UTF-8?q?=E6=80=AA=E6=BB=9A=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/item_home_recent_vgame.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/layout/item_home_recent_vgame.xml b/app/src/main/res/layout/item_home_recent_vgame.xml index 179488578e..4e3f6ca6d4 100644 --- a/app/src/main/res/layout/item_home_recent_vgame.xml +++ b/app/src/main/res/layout/item_home_recent_vgame.xml @@ -1,12 +1,12 @@ @@ -50,6 +50,7 @@ android:layout_height="wrap_content" android:layout_marginStart="-2dp" android:layout_marginEnd="10dp" + android:descendantFocusability="blocksDescendants" android:scrollX="-2dp" app:cardBackgroundColor="@color/transparent" app:cardCornerRadius="4dp" From 15885fa6b0be4203b86379f2494144744a4a0888 Mon Sep 17 00:00:00 2001 From: leafwai Date: Wed, 13 Jul 2022 11:56:21 +0800 Subject: [PATCH 093/217] =?UTF-8?q?fix:=E3=80=90=E5=A4=9C=E9=97=B4?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E3=80=91UI=E6=B5=8B=E8=AF=95=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E9=97=AE=E9=A2=98=E6=B1=87=E6=80=BB=EF=BC=887?= =?UTF-8?q?=E6=9C=88=E7=AC=AC1=E5=91=A8=EF=BC=89=EF=BC=880706=E8=A1=A5?= =?UTF-8?q?=E5=85=8513=E3=80=8115=E3=80=8116=EF=BC=89https://git.shanqu.cc?= =?UTF-8?q?/pm/halo/halo-app-issues/-/issues/1957?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/gamecenter/forum/home/ForumFragment.kt | 10 +--------- .../res/drawable-night/download_recommend_des_bg.xml | 5 +---- .../res/drawable/download_dialog_item_progress.xml | 4 ++-- app/src/main/res/layout/community_answer_item.xml | 1 + .../main/res/layout/item_article_detail_comment.xml | 2 +- 5 files changed, 6 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/ForumFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/home/ForumFragment.kt index b87c82739f..788c5c03be 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/home/ForumFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumFragment.kt @@ -381,7 +381,7 @@ class ForumFragment: LazyFragment(), SwipeRefreshLayout.OnRefreshListener { cornerRadius = 12F.dip2px().toFloat() setColor(color) } - } else { + } else if (bannerBg.background is GradientDrawable) { (bannerBg.background as GradientDrawable).setColor(color) } } @@ -458,14 +458,6 @@ class ForumFragment: LazyFragment(), SwipeRefreshLayout.OnRefreshListener { otherWelfareContainer.visibility = View.VISIBLE otherWelfareRv.layoutManager = GridLayoutManager(requireContext(), 2) otherWelfareRv.adapter = WelfaresAdapter(requireContext(), welfareLists) - otherWelfareRv.addItemDecoration( - GridSpacingItemColorDecoration( - requireContext(), - 0, - 16, - R.color.transparent - ) - ) otherWelfareRv.addItemDecoration(GridSpacingItemColorDecoration(requireContext(), 8, 8, R.color.transparent)) } } diff --git a/app/src/main/res/drawable-night/download_recommend_des_bg.xml b/app/src/main/res/drawable-night/download_recommend_des_bg.xml index 868ef0f4a3..260a61226c 100644 --- a/app/src/main/res/drawable-night/download_recommend_des_bg.xml +++ b/app/src/main/res/drawable-night/download_recommend_des_bg.xml @@ -1,9 +1,6 @@ - + diff --git a/app/src/main/res/drawable/download_dialog_item_progress.xml b/app/src/main/res/drawable/download_dialog_item_progress.xml index 04e7ff13a0..3b67680ce7 100644 --- a/app/src/main/res/drawable/download_dialog_item_progress.xml +++ b/app/src/main/res/drawable/download_dialog_item_progress.xml @@ -7,7 +7,7 @@ android:endColor="#142496FF" android:startColor="#142496FF" /> - + --> - + diff --git a/app/src/main/res/layout/community_answer_item.xml b/app/src/main/res/layout/community_answer_item.xml index bbb7e5fea6..160d8879bc 100644 --- a/app/src/main/res/layout/community_answer_item.xml +++ b/app/src/main/res/layout/community_answer_item.xml @@ -4,6 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" + android:background="@color/background_white" android:orientation="horizontal"> Date: Wed, 13 Jul 2022 14:03:53 +0800 Subject: [PATCH 094/217] =?UTF-8?q?chore:=20=E7=89=88=E6=9C=AC=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E8=87=B3=205.12.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dependencies.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 968f8ab8f3..7b6af1623b 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -7,8 +7,8 @@ ext { targetSdkVersion = 28 // application info (每个大版本之间的 versionCode 增加 20) - versionCode = 570 - versionName = "5.11.0" + versionCode = 590 + versionName = "5.12.0" applicationId = "com.gh.gamecenter" // AndroidX From d695eefbe8ec1efc57ac4fe29e39ff076c05a8b8 Mon Sep 17 00:00:00 2001 From: juntao Date: Wed, 13 Jul 2022 14:59:51 +0800 Subject: [PATCH 095/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E7=AE=A1=E7=90=86=E9=A1=B5=E7=9A=84=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=88=B7=E6=96=B0=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/gamecenter/home/HomeViewModel.kt | 1 - .../com/gh/vspace/VDownloadManagerAdapter.kt | 101 +++++++++++------- .../com/gh/vspace/VDownloadManagerFragment.kt | 14 ++- .../gh/vspace/VDownloadManagerViewModel.kt | 45 ++++++-- app/src/main/java/com/gh/vspace/VHelper.kt | 8 +- .../res/layout/fragment_vdownload_manager.xml | 5 - 6 files changed, 107 insertions(+), 67 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index b361daa700..38838e08d1 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -97,7 +97,6 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { } fun refreshRecentVGameIfNeeded() { - // TODO 避免多线程异常 if (SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, true)) { val entityList = getSortedVEntityList() diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index 51d6df2d8b..151715326c 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -74,6 +74,10 @@ class VDownloadManagerAdapter( } override fun areItemsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean { + return oldItem == newItem + } + + override fun areContentsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean { return oldItem?.id == newItem?.id } @@ -103,10 +107,7 @@ class VDownloadManagerAdapter( notifyItemRangeChanged(0, mEntityList.size) } - override fun onBindViewHolder( - holder: RecyclerView.ViewHolder, - position: Int - ) { + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { when (holder) { is VGameItemViewHolder -> { val gameEntity = mEntityList[position] @@ -139,9 +140,7 @@ class VDownloadManagerAdapter( holder.itemView.setOnClickListener { if (mCurrentOption == ManageOption.OPTION_MANAGER) { GameDetailActivity.startGameDetailActivity( - mContext, - gameEntity.id, - "(畅玩游戏管理)" + mContext, gameEntity.id, "(畅玩游戏管理)" ) } else { if (selectItems.contains(gameEntity.id)) { @@ -157,25 +156,30 @@ class VDownloadManagerAdapter( updateDownloadBtn(mContext, holder.binding.downloadBtn, gameEntity) holder.itemView.setOnLongClickListener { - consume { - DialogHelper.showDialog(holder.binding.root.context, - "删除游戏", - "单机类游戏被删除将可能导致本地存档、充值数据丢失,请确认后操作(网游类游戏删除不会影响游戏存档和充值数据)", - "再等等", - "删除", - {}, - { + DialogHelper.showDialog( + holder.binding.root.context, + "删除游戏", + "单机类游戏被删除将可能导致本地存档、充值数据丢失,请确认后操作(网游类游戏删除不会影响游戏存档和充值数据)", + "再等等", + "删除", + {}, + { + runOnIoThread { val apk = gameEntity.getApk().firstOrNull() mViewModel.removeItem(apk?.url, apk?.packageName) AppExecutor.uiExecutor.executeWithDelay({ mViewModel.load(LoadType.REFRESH) }, 200) - }, uiModificationCallback = { - it.cancelTv.setTextColor(R.color.theme_red.toColor(it.root.context)) - it.confirmTv.setTextColor(R.color.text_subtitle.toColor(it.root.context)) - }) - } + } + }, + uiModificationCallback = { + it.cancelTv.setTextColor(R.color.theme_red.toColor(it.root.context)) + it.confirmTv.setTextColor(R.color.text_subtitle.toColor(it.root.context)) + }, + extraConfig = DialogHelper.Config(centerTitle = true) + ) + return@setOnLongClickListener false } } is FooterViewHolder -> { @@ -193,32 +197,46 @@ class VDownloadManagerAdapter( mPopWindow = PopupWindow(mPopupBinding?.root, LinearLayout.LayoutParams.MATCH_PARENT, 56F.dip2px()) mPopWindow?.showAtLocation( - (mContext as AppCompatActivity).window.decorView, - Gravity.BOTTOM, - 0, - 0 + (mContext as AppCompatActivity).window.decorView, Gravity.BOTTOM, 0, 0 ) mPopupBinding?.itemDelete?.setOnClickListener { NewFlatLogUtils.logHaloFunEvent("halo_fun_manage_game_delete_dialog_show") + mViewModel.pauseItems(ArrayList(selectItems)) DialogHelper.showDialog( mContext, - "是否删除${selectItems.size}条记录?", - "提示:删除记录将不可恢复", + "删除游戏", + "单机类游戏被删除将可能导致本地存档、充值数据丢失,请确认后操作(网游类游戏删除不会影响游戏存档和充值数据)", + "再等等", "删除", - "取消", { - mViewModel.removeItems(selectItems) + NewFlatLogUtils.logHaloFunManageGameDeleteDialogClick( + "再看看", JSONArray(selectItems) + ) + }, + { + NewFlatLogUtils.logHaloFunManageGameDeleteDialogClick( + "删除", JSONArray(selectItems) + ) + + val selectItemCopy = ArrayList(selectItems) + selectItems.clear() checkSelectItems() - NewFlatLogUtils.logHaloFunManageGameDeleteDialogClick("删除", JSONArray(selectItems)) + changeOption(ManageOption.OPTION_MANAGER) - AppExecutor.uiExecutor.executeWithDelay({ - mViewModel.load(LoadType.REFRESH) - }, 200) + runOnIoThread { + mViewModel.removeItems(selectItemCopy) + AppExecutor.uiExecutor.executeWithDelay({ + mViewModel.load(LoadType.REFRESH) + }, 200) + } }, - { NewFlatLogUtils.logHaloFunManageGameDeleteDialogClick("再看看", JSONArray(selectItems)) }, - extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true) + uiModificationCallback = { + it.cancelTv.setTextColor(R.color.theme_red.toColor(it.root.context)) + it.confirmTv.setTextColor(R.color.text_subtitle.toColor(it.root.context)) + }, + extraConfig = DialogHelper.Config(centerTitle = true) ) } mPopupBinding?.checkAllCb?.setOnClickListener { @@ -258,9 +276,7 @@ class VDownloadManagerAdapter( } private fun updateDownloadBtn( - context: Context, - downloadBtn: DownloadProgressBar, - gameEntity: GameEntity + context: Context, downloadBtn: DownloadProgressBar, gameEntity: GameEntity ) { // 青少年模式显示查看 if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) { @@ -271,7 +287,9 @@ class VDownloadManagerAdapter( downloadBtn.goneIf(mCurrentOption != ManageOption.OPTION_MANAGER) val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity) - ?: VHelper.getDownloadEntitySnapshotByPackageName(gameEntity.getUniquePackageName() ?: "") + ?: VHelper.getDownloadEntitySnapshotByPackageName( + gameEntity.getUniquePackageName() ?: "" + ) if (downloadEntity != null) { val status = downloadEntity.status @@ -303,8 +321,11 @@ class VDownloadManagerAdapter( } } DownloadStatus.done -> { - if (PackagesManager.isCanUpdate(gameEntity.id, - gameEntity.getApk().firstOrNull()?.packageName)) { + if (PackagesManager.isCanUpdate( + gameEntity.id, + gameEntity.getApk().firstOrNull()?.packageName + ) + ) { btnText = context.getString(R.string.update) setOnClickListener { PackagesManager.getUpdateList() diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index 457f1b25f8..2a67d89ad1 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -3,13 +3,13 @@ package com.gh.vspace import android.os.Bundle import android.view.View import androidx.recyclerview.widget.RecyclerView -import com.ethanhua.skeleton.Skeleton import com.gh.common.exposure.ExposureListener import com.gh.common.util.NewFlatLogUtils import com.gh.download.DownloadManager import com.gh.gamecenter.R import com.gh.gamecenter.baselist.ListAdapter import com.gh.gamecenter.baselist.ListFragment +import com.gh.gamecenter.baselist.LoadType import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.* @@ -20,7 +20,6 @@ import com.gh.gamecenter.history.IBatchDelete import com.gh.gamecenter.history.ManageOption import com.lightgame.download.DataWatcher import com.lightgame.download.DownloadEntity -import com.lightgame.download.DownloadStatus class VDownloadManagerFragment : ListFragment(), IBatchDelete { @@ -38,10 +37,6 @@ class VDownloadManagerFragment : private val dataWatcher: DataWatcher = object : DataWatcher() { override fun onDataChanged(downloadEntity: DownloadEntity) { mAdapter.notifyItemByDownload(downloadEntity) - - if (downloadEntity.status == DownloadStatus.done && mViewModel.isTypeDownloaded()) { - onLoadRefresh() - } } override fun onDataInit(downloadEntity: DownloadEntity) { @@ -76,8 +71,6 @@ class VDownloadManagerFragment : override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) mCachedView.setBackgroundColor(R.color.background_white.toColor(requireContext())) - mSkeletonScreen = Skeleton.bind(mBinding.listSkeleton).shimmer(false) - .load(R.layout.fragment_subject_skeleton).show() mBinding.headerContainer.run { goneIf(mViewModel.type != VDownloadManagerViewModel.TYPE_DOWNLOADED) @@ -120,4 +113,9 @@ class VDownloadManagerFragment : override fun shouldLoadMore() = false override fun isAutomaticLoad(): Boolean = false + + override fun onLoadRefresh() { + mReuseNoData?.visibility = View.GONE + mListViewModel.load(LoadType.REFRESH) + } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index fded53593c..b37ff0a39d 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -1,11 +1,14 @@ package com.gh.vspace import android.app.Application +import androidx.annotation.WorkerThread import com.gh.download.DownloadManager import com.gh.download.PackageObserver import com.gh.gamecenter.baselist.ListViewModel import com.gh.gamecenter.common.utils.toProperReadableSize +import com.gh.gamecenter.core.runOnUiThread import com.gh.gamecenter.core.utils.NumberUtils +import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.eventbus.EBPackage import com.lightgame.download.DownloadStatus @@ -30,7 +33,7 @@ class VDownloadManagerViewModel(application: Application) : override fun provideDataSingle(page: Int): Single> { if (type == TYPE_DOWNLOADED) { return Single.create { emitter -> - val vGameList = VHelper.getAllVGame() + val vGameList = VHelper.getAllVGame().sortedByDescending { it.downloadEntity.start } val gameList = arrayListOf() // 为空直接返回 @@ -83,30 +86,54 @@ class VDownloadManagerViewModel(application: Application) : } } + @WorkerThread fun removeItem(url: String?, packageName: String?) { DownloadManager.getInstance().pause(url) DownloadManager.getInstance().cancel(url) - val event = EBPackage("卸载", packageName, "unknown") - EventBus.getDefault().post(event) - PackageObserver.onPackageChanged(event) - VHelper.uninstall(packageName ?: "") + + runOnUiThread { + val event = EBPackage("卸载", packageName, "unknown") + EventBus.getDefault().post(event) + PackageObserver.onPackageChanged(event) + + ToastUtils.toast("已删除 1 款游戏") + } } + @WorkerThread fun removeItems(idList: ArrayList) { + val size = idList.size.coerceAtMost(99) + val packageList = arrayListOf() + for (id in idList) { val apkEntity = mResultLiveData.value?.firstOrNull { id == it.id }?.getApk()?.firstOrNull() DownloadManager.getInstance().pause(apkEntity?.url) DownloadManager.getInstance().cancel(apkEntity?.url) - - val event = EBPackage("卸载", apkEntity?.packageName, "unknown") - EventBus.getDefault().post(event) - PackageObserver.onPackageChanged(event) + packageList.add(apkEntity?.packageName ?: "") VHelper.uninstall(apkEntity?.packageName) } + + runOnUiThread { + for (packageName in packageList) { + val event = EBPackage("卸载", packageName, "unknown") + EventBus.getDefault().post(event) + PackageObserver.onPackageChanged(event) + } + + ToastUtils.toast("已删除 ${size} 款游戏") + } + } + + fun pauseItems(idList: ArrayList) { + for (id in idList) { + val apkEntity = + mResultLiveData.value?.firstOrNull { id == it.id }?.getApk()?.firstOrNull() + DownloadManager.getInstance().pause(apkEntity?.url) + } } fun isTypeDownloaded(): Boolean { diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 55703ac33b..8c6b7adeca 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -509,9 +509,7 @@ object VHelper { if (packageName.isNullOrBlank()) return - runOnIoThread { - mVGameDao.delete(packageName) - } + mVGameDao.delete(packageName) val uninstallClosure: () -> Unit = { try { @@ -522,7 +520,9 @@ object VHelper { Utils.log(LOG_TAG, "卸载应用结果 -> $result") } catch (e: Exception) { - ToastUtils.toast(e.localizedMessage ?: "") + runOnUiThread { + ToastUtils.toast(e.localizedMessage ?: "") + } } } diff --git a/app/src/main/res/layout/fragment_vdownload_manager.xml b/app/src/main/res/layout/fragment_vdownload_manager.xml index ab6f9ebd74..fadac3a3bb 100644 --- a/app/src/main/res/layout/fragment_vdownload_manager.xml +++ b/app/src/main/res/layout/fragment_vdownload_manager.xml @@ -17,11 +17,6 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toBottomOf="@id/headerContainer"> - - Date: Wed, 13 Jul 2022 15:08:07 +0800 Subject: [PATCH 096/217] =?UTF-8?q?fix:=E3=80=90=E5=A4=9C=E9=97=B4?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E3=80=91UI=E6=B5=8B=E8=AF=95=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E9=97=AE=E9=A2=98=E6=B1=87=E6=80=BB=EF=BC=887?= =?UTF-8?q?=E6=9C=88=E7=AC=AC1=E5=91=A8=EF=BC=89=EF=BC=880706=E8=A1=A5?= =?UTF-8?q?=E5=85=8515=EF=BC=89https://git.shanqu.cc/pm/halo/halo-app-issu?= =?UTF-8?q?es/-/issues/1957?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/download/dialog/DownloadDialogItemViewHolder.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/download/dialog/DownloadDialogItemViewHolder.kt b/app/src/main/java/com/gh/download/dialog/DownloadDialogItemViewHolder.kt index 6b75fae923..25d4bfdf29 100644 --- a/app/src/main/java/com/gh/download/dialog/DownloadDialogItemViewHolder.kt +++ b/app/src/main/java/com/gh/download/dialog/DownloadDialogItemViewHolder.kt @@ -211,8 +211,10 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas } else 8f.dip2px() binding.root.layoutParams = this } - if (apkEntity.recommend != null) { + if (apkEntity.recommend != null && binding.progressbar.visibility == View.GONE) { binding.containerView.background = ContextCompat.getDrawable(binding.root.context, R.drawable.bg_download_dialog_item_recommend) + } else { + binding.containerView.background = ContextCompat.getDrawable(binding.root.context, R.drawable.download_dialog_item_background) } } From 1a734c32a4624ce803f31e91b733986768d3634e Mon Sep 17 00:00:00 2001 From: lyr Date: Wed, 13 Jul 2022 16:35:36 +0800 Subject: [PATCH 097/217] =?UTF-8?q?feat:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=B8=B8=E6=88=8F=E4=B8=93?= =?UTF-8?q?=E9=A2=98=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96(=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E9=83=A8=E5=88=86(=E5=A4=A7=E8=87=B4=E5=AE=8C?= =?UTF-8?q?=E6=88=90))=20https://git.shanqu.cc/pm/halo/halo-app-issues/-/i?= =?UTF-8?q?ssues/1950?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/gamecenter/entity/GameEntity.kt | 4 + .../com/gh/gamecenter/entity/SubjectEntity.kt | 4 + .../gh/gamecenter/game/GameFragmentAdapter.kt | 30 ++++++ .../com/gh/gamecenter/game/GameViewModel.kt | 21 +++++ .../gh/gamecenter/game/data/GameItemData.kt | 2 + .../game/doublecard/DoubleCardListAdapter.kt | 94 +++++++++++++++++++ .../doublecard/DoubleCardListViewHolder.kt | 29 ++++++ .../horizontal/GameHorizontalSlideAdapter.kt | 27 +++++- .../com/gh/gamecenter/home/HomeViewModel.kt | 9 ++ .../LegacyHomeFragmentAdapterAssistant.kt | 28 ++++++ .../gh/gamecenter/home/LegacyHomeItemData.kt | 1 + .../home/LegacyHomeSubjectTransformer.kt | 9 ++ .../main/res/layout/game_double_card_item.xml | 83 ++++++++++++++++ .../main/res/layout/game_double_card_list.xml | 6 ++ .../layout/game_horizontal_simple_item.xml | 13 ++- .../common/constant/ItemViewType.java | 1 + 16 files changed, 356 insertions(+), 5 deletions(-) create mode 100644 app/src/main/java/com/gh/gamecenter/game/doublecard/DoubleCardListAdapter.kt create mode 100644 app/src/main/java/com/gh/gamecenter/game/doublecard/DoubleCardListViewHolder.kt create mode 100644 app/src/main/res/layout/game_double_card_item.xml create mode 100644 app/src/main/res/layout/game_double_card_list.xml diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt index cdfeebcf25..2af5a1ac6d 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt @@ -266,6 +266,10 @@ data class GameEntity( @SerializedName("recommend_text") var recommendText: String = "", + // 专题封面图 + @SerializedName("column_image") + var columnImage: String = "", + // 本地字段,使用镜像信息 var useMirrorInfo: Boolean = false, // 本地字段,曝光用 diff --git a/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt index 0017bb9298..ee6869ddff 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt @@ -56,6 +56,10 @@ data class SubjectEntity( // 专题背景,用于首页专题合集-排行榜样式 var background: String = "", + // 专题内游戏item是否显示下载按钮(目前只针对横向专题) + @SerializedName("show_download") + var showDownload: Boolean = true, + // 本地字段,用来标记在外部页面中的序号,仅用于曝光记录,具体细节可见 https://git.ghzs.com/pm/halo-app-issues/-/issues/1087 var outerSequence: Int = -1 ) : Parcelable { diff --git a/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt index a9c76ae845..482c9092bb 100644 --- a/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt @@ -46,6 +46,7 @@ import com.gh.gamecenter.game.columncollection.GameColumnCollectionViewHolder import com.gh.gamecenter.game.commoncollection.CommonCollectionViewHolder import com.gh.gamecenter.game.commoncollection.detail.CommonCollectionDetailActivity import com.gh.gamecenter.game.data.GameItemData +import com.gh.gamecenter.game.doublecard.DoubleCardListViewHolder import com.gh.gamecenter.game.gallery.GameGallerySlideViewHolder import com.gh.gamecenter.game.gallery.GameGalleryViewHolder import com.gh.gamecenter.game.horizontal.GameHorizontalListViewHolder @@ -114,6 +115,7 @@ class GameFragmentAdapter( if (itemData.blankDivider != null) return ItemViewType.BLANK_DIVIDER if (itemData.rankCollection != null) return ItemViewType.RANK_COLLECTION if (itemData.gameCollection != null) return ItemViewType.GAME_COLLECTION_ITEM + if (itemData.doubleCardColumn != null) return ItemViewType.DOUBLE_CARD_COLUMN return ItemViewType.LOADING } @@ -206,6 +208,9 @@ class GameFragmentAdapter( ) ) } + ItemViewType.DOUBLE_CARD_COLUMN -> { + DoubleCardListViewHolder(parent.toBinding()) + } else -> GameItemViewHolder(GameItemBinding.bind(mLayoutInflater.inflate(R.layout.game_item, parent, false))) } } @@ -228,6 +233,7 @@ class GameFragmentAdapter( is CommonCollectionViewHolder -> bindCommonCollection(holder, position) is RankCollectionViewHolder -> bindRankCollection(holder, position) is HomeGameCollectionViewHolder -> bindGameCollection(holder, position) + is DoubleCardListViewHolder -> bindGameDoubleCardList(holder, position) } } @@ -1105,6 +1111,30 @@ class GameFragmentAdapter( holder.bindGameCollectionList(gameCollectionItemDataList, "版块内容列表") } + private fun bindGameDoubleCardList(holder: DoubleCardListViewHolder, position: Int) { + mItemDataList[position].doubleCardColumn?.data?.run { + val subjectEntity = mItemDataList[position].doubleCardColumn!! + val subjectAdapter = holder.bindDoubleCardList(subjectEntity) + + val exposureEventList = arrayListOf() + runOnIoThread(true) { + for (i in 0 until subjectAdapter.itemCount) { + if (i >= size) break + + get(i).sequence = i + val event = ExposureEvent.createEventWithSourceConcat( + gameEntity = get(i), + basicSource = mBasicExposureSource, + source = listOf(ExposureSource("专题", subjectEntity.name ?: "")) + ) + exposureEventList.add(event) + } + } + mItemDataList[position].exposureEventList = exposureEventList + subjectAdapter.exposureEventList = exposureEventList + } + } + override fun getItemCount(): Int { return if (mItemDataList.size > 0) mItemDataList.size + 1 else mItemDataList.size } diff --git a/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt b/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt index a74ac8df51..4ad8ff0db3 100644 --- a/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt @@ -487,6 +487,19 @@ class GameViewModel(application: Application, var blockData: SubjectRecommendEnt mSmartSubject = null // 防止重复插入 } + val iterator = mSubjectList.iterator() + while (iterator.hasNext()) { + val item = iterator.next() + // 双列卡片专题过滤掉无封面图游戏 + if (item.type == "game_double_card") { + item.data = item.data?.filter { it.columnImage.isNotBlank() }?.toMutableList() + // 游戏数量小于2个不显示专题,所以直接去掉 + if ((item.data?.size ?: 0) < 2) { + iterator.remove() + } + } + } + // 专题 "type": "image/game_vertical/game_horizontal" for ((index, subjectEntity) in mSubjectList.withIndex()) { var containsImageBeforeHead = false // 在专题名上面是否有大图 @@ -678,6 +691,14 @@ class GameViewModel(application: Application, var blockData: SubjectRecommendEnt continue } + if (subjectEntity.type == "game_double_card") { + val itemDataSubject = GameItemData() + itemDataSubject.doubleCardColumn = subjectEntity + appendAdditionalInfoToSubjectGame(subjectEntity, index) + mItemDataListCache.add(itemDataSubject) + continue + } + if (!data.isNullOrEmpty()) { for (i in 0 until data.size) { val game = data[i] diff --git a/app/src/main/java/com/gh/gamecenter/game/data/GameItemData.kt b/app/src/main/java/com/gh/gamecenter/game/data/GameItemData.kt index 18b9be3ab3..1561818bb9 100644 --- a/app/src/main/java/com/gh/gamecenter/game/data/GameItemData.kt +++ b/app/src/main/java/com/gh/gamecenter/game/data/GameItemData.kt @@ -25,6 +25,8 @@ class GameItemData { var gameCollection: List? = null + var doubleCardColumn: SubjectEntity? = null // 双列卡片专题 + var blankDivider: Float? = null // 空白的空间补全item var exposureEvent: ExposureEvent? = null diff --git a/app/src/main/java/com/gh/gamecenter/game/doublecard/DoubleCardListAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/doublecard/DoubleCardListAdapter.kt new file mode 100644 index 0000000000..a71b3b0fb8 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/game/doublecard/DoubleCardListAdapter.kt @@ -0,0 +1,94 @@ +package com.gh.gamecenter.game.doublecard + +import android.content.Context +import android.graphics.Color +import android.graphics.drawable.GradientDrawable +import android.view.ViewGroup +import com.gh.common.exposure.ExposureEvent +import com.gh.gamecenter.core.utils.StringUtils +import com.gh.gamecenter.GameDetailActivity +import com.gh.gamecenter.common.base.BaseRecyclerViewHolder +import com.gh.gamecenter.common.utils.* +import com.gh.gamecenter.databinding.GameDoubleCardItemBinding +import com.gh.gamecenter.entity.GameEntity +import com.gh.gamecenter.entity.SubjectEntity +import com.lightgame.adapter.BaseRecyclerAdapter + +class DoubleCardListAdapter( + context: Context, + private var mSubjectEntity: SubjectEntity +) : BaseRecyclerAdapter(context) { + + var exposureEventList: ArrayList? = null + + private var countAndKey: Pair? = null + + init { + var dataIds = "" + mSubjectEntity.data?.forEach { + dataIds += it.id + } + if (dataIds.isNotEmpty()) countAndKey = Pair(mSubjectEntity.data?.size ?: 0, dataIds) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = DoubleCardItemViewHolder(parent.toBinding()) + + override fun getItemCount() = if (mSubjectEntity.data?.isNotEmpty() == true) mSubjectEntity.data!!.size else 0 + + override fun onBindViewHolder(holder: DoubleCardItemViewHolder, position: Int) { + val gameEntity = mSubjectEntity.data!![position] + holder.binding.run { + poster.display(gameEntity.columnImage) + gameName.text = gameEntity.name + brief.text = + if (gameEntity.columnRecommend?.text.isNullOrBlank()) gameEntity.brief + else gameEntity.columnRecommend!!.text + gameSubtitle.run { + goneIf(gameEntity.subtitle.isBlank()) + text = gameEntity.subtitle + if (gameEntity.subtitleStyle != null) { + setTextColor(Color.parseColor("#${gameEntity.subtitleStyle?.color}")) + background = GradientDrawable().apply { + cornerRadius = 2F.dip2px().toFloat() + if (gameEntity.subtitleStyle?.style == "border") { + setColor(Color.TRANSPARENT) + setStroke(0.5F.dip2px(), Color.parseColor("#${gameEntity.subtitleStyle?.background}")) + } else { + shape = GradientDrawable.RECTANGLE + setColor(Color.parseColor("#${gameEntity.subtitleStyle?.background}")) + } + } + } + } + + root.setOnClickListener { + GameDetailActivity.startGameDetailActivity( + mContext, + gameEntity, + StringUtils.buildString("(游戏-专题:", mSubjectEntity.name, "-列表[", (position + 1).toString(), "])"), + traceEvent = exposureEventList?.get(position) + ) + } + } + } + + // notifyDataSetChanged 会出现页面抖动情况 + fun checkResetData(subjectEntity: SubjectEntity) { + var dataIds = "" + subjectEntity.data?.forEach { + dataIds += it.id + } + + mSubjectEntity = subjectEntity + if (countAndKey?.first == subjectEntity.data?.size && countAndKey?.second != dataIds) { // 数量不变,内容发生改变 + notifyItemRangeChanged(0, itemCount) + } else if (countAndKey?.first != subjectEntity.data?.size) { // 数量发生改变 + notifyDataSetChanged() + } + + // 重新刷新数据标识 + countAndKey = Pair(subjectEntity.data?.size ?: 0, dataIds) + } + + inner class DoubleCardItemViewHolder(val binding: GameDoubleCardItemBinding): BaseRecyclerViewHolder(binding.root) +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/game/doublecard/DoubleCardListViewHolder.kt b/app/src/main/java/com/gh/gamecenter/game/doublecard/DoubleCardListViewHolder.kt new file mode 100644 index 0000000000..9a6872a9d3 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/game/doublecard/DoubleCardListViewHolder.kt @@ -0,0 +1,29 @@ +package com.gh.gamecenter.game.doublecard + +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.GridLayoutManager +import com.gh.gamecenter.R +import com.gh.gamecenter.common.base.BaseRecyclerViewHolder +import com.gh.gamecenter.common.view.GridSpacingItemColorDecoration +import com.gh.gamecenter.databinding.GameDoubleCardListBinding +import com.gh.gamecenter.entity.SubjectEntity + +class DoubleCardListViewHolder(val binding: GameDoubleCardListBinding) : BaseRecyclerViewHolder(binding.root) { + + fun bindDoubleCardList(subject: SubjectEntity): DoubleCardListAdapter { + return binding.doubleCardList.run { + var subjectAdapter = adapter + if (subjectAdapter is DoubleCardListAdapter) { + subjectAdapter.checkResetData(subject) + } else { + (itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false + isNestedScrollingEnabled = false + layoutManager = GridLayoutManager(context, 2) + subjectAdapter = DoubleCardListAdapter(context, subject) + adapter = subjectAdapter + addItemDecoration(GridSpacingItemColorDecoration(context, 8, 8, R.color.transparent)) + } + subjectAdapter + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideAdapter.kt index 3c2141b251..68c043f464 100644 --- a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideAdapter.kt @@ -3,12 +3,10 @@ package com.gh.gamecenter.game.horizontal import android.content.Context import android.view.ViewGroup import com.gh.common.exposure.ExposureEvent +import com.gh.common.util.DownloadItemUtils import com.gh.gamecenter.GameDetailActivity import com.gh.gamecenter.R -import com.gh.gamecenter.common.utils.dip2px -import com.gh.gamecenter.common.utils.safelyGetInRelease -import com.gh.gamecenter.common.utils.toBinding -import com.gh.gamecenter.common.utils.toColor +import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.* import com.gh.gamecenter.databinding.GameHorizontalItemBinding import com.gh.gamecenter.entity.SubjectEntity @@ -56,6 +54,8 @@ class GameHorizontalSlideAdapter( holder.binding.simpleGameContainer.root.setPadding(8F.dip2px(), 0, 8F.dip2px(), 0) holder.binding.root.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) + holder.binding.simpleGameContainer.downloadBtn.goneIf(!mSubjectEntity.showDownload) + holder.binding.simpleGameContainer.gameName.maxLines = if (mSubjectEntity.showDownload) 1 else 2 val gameEntity = mSubjectEntity.data!![position + getIndex()] holder.binding.simpleGameContainer.run { @@ -78,6 +78,25 @@ class GameHorizontalSlideAdapter( ) } } + + if (mSubjectEntity.showDownload) { + DownloadItemUtils.setOnClickListener( + mContext, + holder.binding.simpleGameContainer.downloadBtn, + gameEntity, + position, + this, + "", + "", + null + ) + + DownloadItemUtils.updateDownloadButton( + mContext, + holder.binding.simpleGameContainer.downloadBtn, + gameEntity + ) + } } // notifyDataSetChanged 会出现页面抖动情况 diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index 531e7c418f..c917521cd5 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -290,6 +290,15 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { } } } + + // 双列卡片专题过滤掉无封面图游戏 + if (item.linkType == "column" && item.linkColumn?.type == "game_double_card") { + item.linkColumn.data = item.linkColumn.data?.filter { it.columnImage.isNotBlank() }?.toMutableList() + // 游戏数量小于2个不显示专题,所以直接去掉 + if ((item.linkColumn.data?.size ?: 0) < 2) { + iterator.remove() + } + } } if (mSmartSubject != null && mHomeContents.size > mSmartSubject!!.sort) { diff --git a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt index bd5ec69a75..9901558166 100644 --- a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt +++ b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt @@ -34,6 +34,7 @@ import com.gh.gamecenter.game.GameItemViewHolder import com.gh.gamecenter.game.columncollection.GameColumnCollectionViewHolder import com.gh.gamecenter.game.commoncollection.CommonCollectionViewHolder import com.gh.gamecenter.game.commoncollection.detail.CommonCollectionDetailActivity +import com.gh.gamecenter.game.doublecard.DoubleCardListViewHolder import com.gh.gamecenter.game.gallery.GameGallerySlideViewHolder import com.gh.gamecenter.game.gallery.GameGalleryViewHolder import com.gh.gamecenter.game.horizontal.GameHorizontalListViewHolder @@ -81,6 +82,7 @@ class LegacyHomeFragmentAdapterAssistant( if (itemData.blankDivider != null) return ItemViewType.BLANK_DIVIDER if (itemData.commonCollection != null) return ItemViewType.COMMON_LINK_COLLECTION if (itemData.rankCollection != null) return ItemViewType.RANK_COLLECTION + if (itemData.doubleCardColumn != null) return ItemViewType.DOUBLE_CARD_COLUMN return 0 } @@ -103,6 +105,7 @@ class LegacyHomeFragmentAdapterAssistant( ItemViewType.BLANK_DIVIDER -> BlankDividerViewHolder(parent.toBinding()) ItemViewType.COMMON_LINK_COLLECTION -> CommonCollectionViewHolder(parent.toBinding()) ItemViewType.RANK_COLLECTION -> RankCollectionViewHolder(parent.toBinding()) + ItemViewType.DOUBLE_CARD_COLUMN -> DoubleCardListViewHolder(parent.toBinding()) else -> throw NullPointerException() } @@ -131,6 +134,7 @@ class LegacyHomeFragmentAdapterAssistant( ) is CommonCollectionViewHolder -> bindCommonCollection(holder, item) is RankCollectionViewHolder -> bindRankCollection(holder, item) + is DoubleCardListViewHolder -> bindGameDoubleCardList(holder, item) } } @@ -839,6 +843,30 @@ class LegacyHomeFragmentAdapterAssistant( } } + private fun bindGameDoubleCardList(holder: DoubleCardListViewHolder, item: LegacyHomeItemData) { + item.doubleCardColumn?.data?.run { + val subjectEntity = item.doubleCardColumn!! + val subjectAdapter = holder.bindDoubleCardList(subjectEntity) + + val exposureEventList = arrayListOf() + runOnIoThread(true) { + for (i in 0 until subjectAdapter.itemCount) { + if (i >= size) break + + get(i).sequence = i + val event = ExposureEvent.createEventWithSourceConcat( + gameEntity = get(i), + basicSource = mBasicExposureSources, + source = listOf(ExposureSource("专题", subjectEntity.name ?: "")) + ) + exposureEventList.add(event) + } + } + item.exposureEventList = exposureEventList + subjectAdapter.exposureEventList = exposureEventList + } + } + private fun setPageSwitchData() { PageSwitchDataHelper.pushCurrentPageData( hashMapOf( diff --git a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeItemData.kt b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeItemData.kt index 7a1bcb222e..33e0373231 100644 --- a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeItemData.kt +++ b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeItemData.kt @@ -28,5 +28,6 @@ open class LegacyHomeItemData( var columnCollection: SubjectEntity? = null, var commonCollection: SubjectEntity? = null, var rankCollection: SubjectEntity? = null, // 排行榜样式专题合集 + var doubleCardColumn: SubjectEntity? = null, // 双列卡片专题 var blankDivider: Float? = null // 空白填充内容 ) \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeSubjectTransformer.kt b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeSubjectTransformer.kt index 9b11983b2a..da79e435a6 100644 --- a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeSubjectTransformer.kt +++ b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeSubjectTransformer.kt @@ -166,6 +166,15 @@ object LegacyHomeSubjectTransformer { return } + if (subjectEntity.type == "game_double_card") { + val itemDataSubject = newItemInstance() + itemDataSubject.blockPosition = blockPosition + 1 + itemDataSubject.doubleCardColumn = subjectEntity + appendAdditionalInfoToSubjectGame(subjectEntity, blockPosition) + itemList.add(itemDataSubject) + return + } + for (i in 0 until data.size) { val game = data[i] game.sequence = i diff --git a/app/src/main/res/layout/game_double_card_item.xml b/app/src/main/res/layout/game_double_card_item.xml new file mode 100644 index 0000000000..fbd3f544b1 --- /dev/null +++ b/app/src/main/res/layout/game_double_card_item.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/game_double_card_list.xml b/app/src/main/res/layout/game_double_card_list.xml new file mode 100644 index 0000000000..2c9a62b04f --- /dev/null +++ b/app/src/main/res/layout/game_double_card_list.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/game_horizontal_simple_item.xml b/app/src/main/res/layout/game_horizontal_simple_item.xml index c2b7f33bf0..cebe72b33a 100644 --- a/app/src/main/res/layout/game_horizontal_simple_item.xml +++ b/app/src/main/res/layout/game_horizontal_simple_item.xml @@ -18,11 +18,22 @@ android:layout_marginTop="8dp" android:ellipsize="end" android:gravity="center" - android:includeFontPadding="false" android:lineSpacingExtra="4dp" android:maxLines="2" android:textColor="@color/text_title" android:textSize="12sp" tools:text="超杀默示录" /> + + diff --git a/module_common/src/main/java/com/gh/gamecenter/common/constant/ItemViewType.java b/module_common/src/main/java/com/gh/gamecenter/common/constant/ItemViewType.java index 0efe7c0e2a..3e241642dc 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/constant/ItemViewType.java +++ b/module_common/src/main/java/com/gh/gamecenter/common/constant/ItemViewType.java @@ -38,6 +38,7 @@ public class ItemViewType { public static final int COMMON_LINK_COLLECTION = 30; // 通用链接合集 public static final int RANK_COLLECTION = 31; // 排行榜样式专题合集 public static final int GAME_COLLECTION_ITEM = 32; // 游戏单 + public static final int DOUBLE_CARD_COLUMN = 33; // 双列卡片专题 /** * 普通列表 From 32574ba33ae768d27f3354a5101ef45e7f47e744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Wed, 13 Jul 2022 16:40:29 +0800 Subject: [PATCH 098/217] =?UTF-8?q?fix:=20=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E7=AB=AF=E5=86=85=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E9=80=82=E9=85=8D=E7=9F=AD=E9=93=BE=E6=8E=A5(0713?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=8F=8D=E9=A6=88)=20https://git.shanqu.cc/p?= =?UTF-8?q?m/halo/halo-app-issues/-/issues/1945?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/common/util/CommentHelper.kt | 7 +-- .../com/gh/common/util/PostCommentUtils.java | 16 ++++--- .../collection/CommunityArticleViewModel.kt | 2 +- .../article/detail/ArticleDetailViewModel.kt | 10 +---- .../comment/ArticleDetailCommentViewModel.kt | 2 +- .../qa/comment/NewCommentViewModel.kt | 2 +- .../qa/comment/base/BaseCommentViewModel.kt | 2 +- .../CommentConversationViewModel.kt | 2 - .../retrofit/service/ApiService.java | 45 ++++++++----------- 9 files changed, 35 insertions(+), 53 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/CommentHelper.kt b/app/src/main/java/com/gh/common/util/CommentHelper.kt index 4f7d036674..0a9f2b2f1b 100644 --- a/app/src/main/java/com/gh/common/util/CommentHelper.kt +++ b/app/src/main/java/com/gh/common/util/CommentHelper.kt @@ -440,10 +440,7 @@ object CommentHelper { context, highlight, highlightDialogHintContent, "确定", "取消", { RetrofitManager.getInstance().api - .highlightCommunityArticleComment( - articleId, - comment.id - ) + .highlightCommunityArticleComment(comment.id) .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) .subscribe(highlightObserver) @@ -501,7 +498,7 @@ object CommentHelper { context, hide, hideDialogHintContent, "确定", "取消", { RetrofitManager.getInstance().api - .hideCommunityArticleComment(articleId, comment.id) + .hideCommunityArticleComment(comment.id) .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) .subscribe(hideObserver) diff --git a/app/src/main/java/com/gh/common/util/PostCommentUtils.java b/app/src/main/java/com/gh/common/util/PostCommentUtils.java index 10cc2fd356..ac8a944976 100644 --- a/app/src/main/java/com/gh/common/util/PostCommentUtils.java +++ b/app/src/main/java/com/gh/common/util/PostCommentUtils.java @@ -3,6 +3,7 @@ package com.gh.common.util; import android.content.Context; import android.os.Build; import android.text.TextUtils; + import com.gh.gamecenter.R; import com.gh.gamecenter.common.retrofit.JSONObjectResponse; import com.gh.gamecenter.common.retrofit.Response; @@ -10,7 +11,9 @@ import com.gh.gamecenter.entity.CommentEntity; import com.gh.gamecenter.retrofit.RetrofitManager; import com.lightgame.utils.Utils; import com.walkud.rom.checker.RomIdentifier; + import org.json.JSONObject; + import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.schedulers.Schedulers; @@ -78,8 +81,7 @@ public class PostCommentUtils { Observable observable; if (!TextUtils.isEmpty(articleId)) { if (commentEntity != null) { - observable = RetrofitManager.getInstance().getApi().postReplyToCommunityArticleComment(articleCommunityId, - articleId, commentEntity.getId(), body); + observable = RetrofitManager.getInstance().getApi().postReplyToCommunityArticleComment(commentEntity.getId(), body); } else { observable = RetrofitManager.getInstance().getApi().postCommentToCommunityArticle(articleId, body); } @@ -121,8 +123,8 @@ public class PostCommentUtils { if (!TextUtils.isEmpty(answerId)) { observable = RetrofitManager.getInstance().getApi().postVoteAnswerComment(answerId, commentId); - } else if (!TextUtils.isEmpty(articleId)) { - observable = RetrofitManager.getInstance().getApi().postVoteCommunityArticleComment(articleId, commentId); + } else if (!TextUtils.isEmpty(commentId)) { + observable = RetrofitManager.getInstance().getApi().postVoteCommunityArticleComment(commentId); } else if (!TextUtils.isEmpty(questionId)) { observable = RetrofitManager.getInstance().getApi().postVoteQuestionComment(questionId, commentId); } else { @@ -159,8 +161,8 @@ public class PostCommentUtils { if (!TextUtils.isEmpty(questionId)) { observable = RetrofitManager.getInstance().getApi().postUnVoteQuestionComment(questionId, commentId); - } else if (!TextUtils.isEmpty(articleId)) { - observable = RetrofitManager.getInstance().getApi().postUnVoteArticleComment(articleId, commentId); + } else if (!TextUtils.isEmpty(commentId)) { + observable = RetrofitManager.getInstance().getApi().postUnVoteArticleComment(commentId); } else { observable = RetrofitManager.getInstance().getApi().postUnVoteVideoComment(videoId, commentId); } @@ -257,7 +259,7 @@ public class PostCommentUtils { final PostCommentListener listener) { RequestBody body = RequestBody.create(MediaType.parse("application/json"), reportData); RetrofitManager.getInstance().getApi() - .postCommunityArticleCommentReport(communityId, articleId, commentId, body) + .postCommunityArticleCommentReport(commentId, body) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Response() { diff --git a/app/src/main/java/com/gh/gamecenter/collection/CommunityArticleViewModel.kt b/app/src/main/java/com/gh/gamecenter/collection/CommunityArticleViewModel.kt index 5ce2af0ed5..d3a958dda0 100644 --- a/app/src/main/java/com/gh/gamecenter/collection/CommunityArticleViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/collection/CommunityArticleViewModel.kt @@ -88,7 +88,7 @@ class CommunityArticleViewModel(application: Application) : ListViewModel() { diff --git a/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailViewModel.kt index 71dff9cc40..83ce387533 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailViewModel.kt @@ -224,15 +224,9 @@ class ArticleDetailViewModel( fun collectionCommand(isCollection: Boolean, callback: (isFollow: Boolean) -> Unit) { val observable = if (isCollection) { - mApi.postCommunityArticleFavorites( - UserManager.getInstance().userId, - articleId - ) + mApi.postCommunityArticleFavorites(articleId) } else { - mApi.deleteCommunityArticleFavorites( - UserManager.getInstance().userId, - articleId - ) + mApi.deleteCommunityArticleFavorites(articleId) } observable .subscribeOn(Schedulers.io()) diff --git a/app/src/main/java/com/gh/gamecenter/qa/article/detail/comment/ArticleDetailCommentViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/article/detail/comment/ArticleDetailCommentViewModel.kt index e8e920496d..19d7cc7d0a 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/article/detail/comment/ArticleDetailCommentViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/article/detail/comment/ArticleDetailCommentViewModel.kt @@ -31,7 +31,7 @@ class ArticleDetailCommentViewModel(application: Application, } override fun provideDataSingle(page: Int): Single> { - return RetrofitManager.getInstance().api.getCommunityArticleCommentReply(communityId, articleId, commentId, currentSortType.value, page, mapOf()) + return RetrofitManager.getInstance().api.getCommunityArticleCommentReply(commentId, currentSortType.value, page, mapOf()) } @SuppressLint("CheckResult") diff --git a/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt index 2e1ed23db3..bbfa72f789 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt @@ -143,7 +143,7 @@ open class NewCommentViewModel( if (commentEntity == null) { api.postCommentToCommunityArticle(articleId, body) } else { - api.postReplyToCommunityArticleComment(communityId, articleId, commentEntity.id, body) + api.postReplyToCommunityArticleComment(commentEntity.id, body) } } diff --git a/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt index f1edf16a47..e8b4b6e1c1 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt @@ -262,7 +262,7 @@ abstract class BaseCommentViewModel( mApi.deleteQuestionComment(questionId, entity.id).toObservable() } articleId.isNotEmpty() -> { - mApi.hideCommunityArticleComment(articleId, entity.id) + mApi.hideCommunityArticleComment(entity.id) } else -> null } ?: return diff --git a/app/src/main/java/com/gh/gamecenter/qa/comment/conversation/CommentConversationViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/comment/conversation/CommentConversationViewModel.kt index 822410cecd..70fbc5e93c 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/comment/conversation/CommentConversationViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/comment/conversation/CommentConversationViewModel.kt @@ -36,8 +36,6 @@ class CommentConversationViewModel( return when { articleId.isNotEmpty() -> { mApi.getCommunityArticleCommentReply( - communityId, - articleId, commentId, currentSortType.value, page, diff --git a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java index f451679903..1756869d71 100644 --- a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java +++ b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java @@ -1461,16 +1461,14 @@ public interface ApiService { /** * 收藏社区文章 */ - @POST("users/{user_id}/favorites/communities/articles/{article_id}") - Observable postCommunityArticleFavorites(@Path("user_id") String userId, - @Path("article_id") String articleId); + @POST("users/favorites/communities/articles/{article_id}") + Observable postCommunityArticleFavorites(@Path("article_id") String articleId); /** * 取消收藏社区文章 */ - @DELETE("users/{user_id}/favorites/communities/articles/{article_id}") - Observable deleteCommunityArticleFavorites(@Path("user_id") String userId, - @Path("article_id") String articleId); + @DELETE("users/favorites/communities/articles/{article_id}") + Observable deleteCommunityArticleFavorites(@Path("article_id") String articleId); /** * 获取社区文章评论列表.可以分页 @@ -1501,10 +1499,8 @@ public interface ApiService { /** * 获取社区文章评论回复 */ - @GET("communities/{community_id}/articles/{article_id}/comments/{comment_id}/replies") - Single> getCommunityArticleCommentReply(@Path("community_id") String communityId, - @Path("article_id") String articleId, - @Path("comment_id") String commentId, + @GET("communities/articles/comments/{comment_id}/replies") + Single> getCommunityArticleCommentReply(@Path("comment_id") String commentId, @Query("sort") String sort, @Query("page") int page, @QueryMap Map params); @@ -1519,26 +1515,21 @@ public interface ApiService { /** * 在评论列表回复某一条评论 */ - @POST("communities/{community_id}/articles/{article_id}/comments/{comment_id}:reply") - Observable postReplyToCommunityArticleComment(@Path("community_id") String communityId, - @Path("article_id") String articleId, - @Path("comment_id") String commentId, + @POST("communities/articles/comments/{comment_id}:reply") + Observable postReplyToCommunityArticleComment(@Path("comment_id") String commentId, @Body RequestBody body); /** * 对社区文章评论的点赞 */ - @POST("communities/articles/{article_id}/comments/{comment_id}:vote") - Observable postVoteCommunityArticleComment(@Path("article_id") String articled, - @Path("comment_id") String commentId); + @POST("communities/articles/comments/{comment_id}:vote") + Observable postVoteCommunityArticleComment(@Path("comment_id") String commentId); /** * 投诉社区文章评论 */ - @POST("communities/{community_id}/articles/{article_id}/comments/{comment_id}:report") - Observable postCommunityArticleCommentReport(@Path("community_id") String communityId, - @Path("article_id") String articleId, - @Path("comment_id") String commentId, + @POST("communities/articles/comments/{comment_id}:report") + Observable postCommunityArticleCommentReport(@Path("comment_id") String commentId, @Body RequestBody reportData); /** @@ -1751,15 +1742,15 @@ public interface ApiService { /** * 置顶社区文章评论 */ - @POST("communities/articles/{article_id}/comments/{comment_id}:set-top") - Observable highlightCommunityArticleComment(@Path("article_id") String articleId, @Path("comment_id") String commendId); + @POST("communities/articles/comments/{comment_id}:set-top") + Observable highlightCommunityArticleComment(@Path("comment_id") String commendId); /** * 隐藏社区文章评论 */ - @POST("communities/articles/{article_id}/comments/{comment_id}:hide") - Observable hideCommunityArticleComment(@Path("article_id") String articleId, @Path("comment_id") String commendId); + @POST("communities/articles/comments/{comment_id}:hide") + Observable hideCommunityArticleComment(@Path("comment_id") String commendId); /** * 设置回答详情的的评论区域是否开启 @@ -3523,8 +3514,8 @@ public interface ApiService { /** * 取消帖子评论点赞 */ - @POST("communities/articles/{article_id}/comments/{comment_id}:unvote") - Observable postUnVoteArticleComment(@Path("article_id") String articleId, @Path("comment_id") String commentId); + @POST("communities/articles/comments/{comment_id}:unvote") + Observable postUnVoteArticleComment(@Path("comment_id") String commentId); /** * 置顶视频评论 From e42fb2ab66bc8abe02ea03d3dd67ea9c7370ad75 Mon Sep 17 00:00:00 2001 From: lyr Date: Wed, 13 Jul 2022 16:45:37 +0800 Subject: [PATCH 099/217] =?UTF-8?q?fix:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=B8=B8=E6=88=8F=E4=B8=93?= =?UTF-8?q?=E9=A2=98=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96(=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E4=B8=93=E9=A2=98=E9=BB=98=E8=AE=A4=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E6=8C=89=E9=92=AE=E7=9A=84=E5=80=BC)=20https?= =?UTF-8?q?://git.shanqu.cc/pm/halo/halo-app-issues/-/issues/1950?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt index ee6869ddff..130b54108d 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt @@ -58,7 +58,7 @@ data class SubjectEntity( // 专题内游戏item是否显示下载按钮(目前只针对横向专题) @SerializedName("show_download") - var showDownload: Boolean = true, + var showDownload: Boolean = false, // 本地字段,用来标记在外部页面中的序号,仅用于曝光记录,具体细节可见 https://git.ghzs.com/pm/halo-app-issues/-/issues/1087 var outerSequence: Int = -1 From b16fcb6725aa0bac5b5edb64364c49d79bb76b1c Mon Sep 17 00:00:00 2001 From: juntao Date: Wed, 13 Jul 2022 17:09:16 +0800 Subject: [PATCH 100/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E4=B8=8B=E8=BD=BD=E5=AE=8C=E6=88=90=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E6=82=AC=E6=B5=AE=E7=AA=97=E6=97=A0=E6=B3=95=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E6=B8=B8=E6=88=8F=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/gamecenter/baselist/ListAdapter.java | 4 ++++ .../java/com/gh/vspace/VDownloadManagerAdapter.kt | 11 +++++++++-- app/src/main/java/com/gh/vspace/VHelper.kt | 6 +++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/baselist/ListAdapter.java b/app/src/main/java/com/gh/gamecenter/baselist/ListAdapter.java index 9e65c7ab71..a11051f56b 100644 --- a/app/src/main/java/com/gh/gamecenter/baselist/ListAdapter.java +++ b/app/src/main/java/com/gh/gamecenter/baselist/ListAdapter.java @@ -46,6 +46,10 @@ public abstract class ListAdapter extends BaseRecyclerAdapter { return; } + calculateDiff(updateData); + } + + protected void calculateDiff(List updateData) { // 若直接传 updateData 给 DiffUtils 可能因为其它地方操作 updateData 这个列表而出现 ArrayIndexOutOfBounds 异常 // 这里用新的数组包裹原数据 ArrayList updateDataCopy = new ArrayList<>(updateData); diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index 151715326c..e63a0ba9ad 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -70,11 +70,18 @@ class VDownloadManagerAdapter( mPositionAndPackageMap[packages + i] = i } } - super.setListData(updateData) + + if (updateData == null) { + mEntityList = ArrayList() + notifyDataSetChanged() + return + } + + calculateDiff(updateData) } override fun areItemsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean { - return oldItem == newItem + return oldItem != null && oldItem.id == newItem?.id } override fun areContentsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean { diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 8c6b7adeca..ac7d0a234c 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -373,9 +373,6 @@ object VHelper { downloadEntity: DownloadEntity, isManualInstall: Boolean = false ) { - // 正在安装中,忽略重复调用 - if (mInstallingVaPathSet.contains(downloadEntity.path)) return - Utils.log(LOG_TAG, "尝试安装新应用 ${downloadEntity.path}") if (showDialogIfVSpaceIsNeeded(context)) { @@ -395,6 +392,9 @@ object VHelper { ) } + // 正在安装中,忽略重复调用 + if (mInstallingVaPathSet.contains(downloadEntity.path)) return@checkStoragePermissionBeforeAction + // 安装过程会比较漫长,所以得放在工作线程运行 runOnIoThread { try { From e8553116b64b69928c7c4f8f6258143c88ac66e5 Mon Sep 17 00:00:00 2001 From: leafwai Date: Wed, 13 Jul 2022 17:38:13 +0800 Subject: [PATCH 101/217] =?UTF-8?q?fix:=E3=80=90=E5=A4=9C=E9=97=B4?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E3=80=91UI=E6=B5=8B=E8=AF=95=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E9=97=AE=E9=A2=98=E6=B1=87=E6=80=BB=EF=BC=887?= =?UTF-8?q?=E6=9C=88=E7=AC=AC1=E5=91=A8=EF=BC=89=EF=BC=880706=E8=A1=A5?= =?UTF-8?q?=E5=85=8515=EF=BC=89https://git.shanqu.cc/pm/halo/halo-app-issu?= =?UTF-8?q?es/-/issues/1957?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/download/dialog/DownloadDialogItemViewHolder.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/download/dialog/DownloadDialogItemViewHolder.kt b/app/src/main/java/com/gh/download/dialog/DownloadDialogItemViewHolder.kt index 25d4bfdf29..04ed43adc9 100644 --- a/app/src/main/java/com/gh/download/dialog/DownloadDialogItemViewHolder.kt +++ b/app/src/main/java/com/gh/download/dialog/DownloadDialogItemViewHolder.kt @@ -211,7 +211,8 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas } else 8f.dip2px() binding.root.layoutParams = this } - if (apkEntity.recommend != null && binding.progressbar.visibility == View.GONE) { + val downloadEntity = DownloadManager.getInstance().getDownloadEntityByUrl(apkEntity.url) + if (apkEntity.recommend != null && downloadEntity == null) { binding.containerView.background = ContextCompat.getDrawable(binding.root.context, R.drawable.bg_download_dialog_item_recommend) } else { binding.containerView.background = ContextCompat.getDrawable(binding.root.context, R.drawable.download_dialog_item_background) From 5f014f6f6b127bd8df317de03308f3c8fe0e7ae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Thu, 14 Jul 2022 16:13:07 +0800 Subject: [PATCH 102/217] =?UTF-8?q?feat:=20=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E9=A6=96=E9=A1=B5=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E9=80=9F=E5=BA=A6=E4=BC=98=E5=8C=96(=E6=95=B4?= =?UTF-8?q?=E5=90=88=E6=8E=A5=E5=8F=A3)=20https://git.shanqu.cc/pm/halo/ha?= =?UTF-8?q?lo-app-issues/-/issues/1919?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/gamecenter/entity/HomeDataEntity.kt | 16 +++++ .../fragment/HomeSearchToolWrapperFragment.kt | 2 +- .../HomeSearchToolWrapperViewModel.kt | 62 +++++++++++-------- .../com/gh/gamecenter/home/HomeFragment.kt | 17 +++-- .../com/gh/gamecenter/home/HomeViewModel.kt | 49 ++++----------- .../retrofit/service/ApiService.java | 6 ++ 6 files changed, 81 insertions(+), 71 deletions(-) create mode 100644 app/src/main/java/com/gh/gamecenter/entity/HomeDataEntity.kt diff --git a/app/src/main/java/com/gh/gamecenter/entity/HomeDataEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/HomeDataEntity.kt new file mode 100644 index 0000000000..b440818656 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/entity/HomeDataEntity.kt @@ -0,0 +1,16 @@ +package com.gh.gamecenter.entity + +import com.google.gson.annotations.SerializedName + +data class HomeDataEntity( + @SerializedName("home_tab") + val homeTab: ArrayList = arrayListOf(), + @SerializedName("home_slide") + val homeSlide: ArrayList = arrayListOf(), + @SerializedName("home_recommend") + val homeRecommend: ArrayList = arrayListOf(), + @SerializedName("home_content") + val homeContent: ArrayList = arrayListOf(), + @SerializedName("home_navbar_v2") + val homeNavbarV2: SubjectRecommendEntity? = null +) diff --git a/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperFragment.kt b/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperFragment.kt index 20f78112d8..620ccd075f 100644 --- a/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperFragment.kt @@ -116,7 +116,7 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() { mBinding?.noConnectionContainer?.reuseNoConnection?.visibility = View.VISIBLE mBinding?.loadingContainer?.reuseLlLoading?.visibility = View.GONE mBinding?.noConnectionContainer?.reuseNoConnection?.setOnClickListener { - mViewModel?.getTabs() + mViewModel?.getHomeContentUnion() mBinding?.noConnectionContainer?.reuseNoConnection?.visibility = View.GONE mBinding?.loadingContainer?.reuseLlLoading?.visibility = View.VISIBLE } diff --git a/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperViewModel.kt b/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperViewModel.kt index 31440871ac..098dd02eed 100644 --- a/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/fragment/HomeSearchToolWrapperViewModel.kt @@ -9,6 +9,8 @@ import com.gh.gamecenter.BuildConfig import com.gh.gamecenter.R import com.gh.gamecenter.entity.SubjectRecommendEntity import com.gh.gamecenter.common.retrofit.BiResponse +import com.gh.gamecenter.common.utils.singleToMain +import com.gh.gamecenter.entity.HomeDataEntity import com.gh.gamecenter.retrofit.RetrofitManager import com.halo.assistant.HaloApp import io.reactivex.android.schedulers.AndroidSchedulers @@ -21,49 +23,57 @@ class HomeSearchToolWrapperViewModel(application: Application) : AndroidViewMode var forumTabPairs: ArrayList> = arrayListOf() val tabs = MutableLiveData>() + val homeDataLiveData = MutableLiveData() val error = MutableLiveData() var appBarOffset = 0 init { - getTabs() + getHomeContentUnion() } @SuppressLint("CheckResult") - fun getTabs() { + fun getHomeContentUnion(isRefresh: Boolean = false) { RetrofitManager.getInstance().api - .getHomeTabs(HaloApp.getInstance().channel, BuildConfig.VERSION_NAME) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(object : BiResponse>() { - override fun onSuccess(data: ArrayList) { - forumTabPairs.clear() - for ((index, tab) in data.withIndex()) { - if (tab.type == "top_game_comment") { - tab.primaryColor = R.color.amway_primary_color.toColor() - tab.useLightStyle = true - tab.currentSelectColor = tab.primaryColor - } + .getHomeContentUnion(BuildConfig.VERSION_NAME, HaloApp.getInstance().channel) + .compose(singleToMain()) + .subscribe(object : BiResponse() { + override fun onSuccess(data: HomeDataEntity) { + val homeTab = data.homeTab + if (homeTab.isNotEmpty()) { + forumTabPairs.clear() + for ((index, tab) in homeTab.withIndex()) { + if (tab.type == "top_game_comment") { + tab.primaryColor = R.color.amway_primary_color.toColor() + tab.useLightStyle = true + tab.currentSelectColor = tab.primaryColor + } - if (tab.type == "home") { - tab.useLightStyle = true - } + if (tab.type == "home") { + tab.useLightStyle = true + } - if (tab.type == "bbs") { - forumTabPairs.add(Pair(index, tab.link ?: "")) - } + if (tab.type == "bbs") { + forumTabPairs.add(Pair(index, tab.link ?: "")) + } - if (tab.default) defaultTabPosition = index + if (tab.default) defaultTabPosition = index + } + if (homeTab.size == 0) { + homeTab.add(SubjectRecommendEntity(type = "home")) + } + if (!isRefresh) { + tabs.postValue(homeTab) + } } - if (data.size == 0) { - data.add(SubjectRecommendEntity(type = "home")) - } - tabs.postValue(data) + homeDataLiveData.postValue(data) } override fun onFailure(exception: Exception) { super.onFailure(exception) - error.postValue(exception) + if (!isRefresh) { + error.postValue(exception) + } } }) } diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt b/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt index f9e8ce0ec0..ba0b06ea67 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt @@ -16,10 +16,7 @@ import com.gh.gamecenter.baselist.LoadStatus import com.gh.gamecenter.common.base.fragment.LazyFragment import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.constant.EntranceConsts -import com.gh.gamecenter.common.utils.goneIf -import com.gh.gamecenter.common.utils.observeNonNull -import com.gh.gamecenter.common.utils.safelyGetInRelease -import com.gh.gamecenter.common.utils.viewModelProvider +import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.common.view.OffsetLinearLayoutManager import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.core.utils.MD5Utils @@ -31,6 +28,7 @@ import com.gh.gamecenter.eventbus.EBPackage import com.gh.gamecenter.eventbus.EBReuse import com.gh.gamecenter.eventbus.EBUISwitch import com.gh.gamecenter.fragment.HomeSearchToolWrapperFragment +import com.gh.gamecenter.fragment.HomeSearchToolWrapperViewModel import com.gh.gamecenter.fragment.MainWrapperFragment import com.gh.gamecenter.game.gallery.GameGallerySlideViewHolder import com.gh.gamecenter.home.slide.HomeSlideListAdapter @@ -43,6 +41,7 @@ import org.greenrobot.eventbus.ThreadMode class HomeFragment : LazyFragment() { private lateinit var mViewModel: HomeViewModel + private lateinit var mHomeSearchViewModel: HomeSearchToolWrapperViewModel private lateinit var mBinding: FragmentMainHomeBinding private lateinit var mLayoutManager: LinearLayoutManager private lateinit var mListAdapter: HomeFragmentAdapter @@ -65,7 +64,10 @@ class HomeFragment : LazyFragment() { override fun onFragmentFirstVisible() { mViewModel = viewModelProvider() + mHomeSearchViewModel = viewModelProviderFromParent() mViewModel.homeOnlyWithoutOtherTab = arguments?.getInt(EntranceConsts.KEY_TAB_COUNT) == 1 + val homeDataEntity = mHomeSearchViewModel.homeDataLiveData.value + mViewModel.initData(homeDataEntity) super.onFragmentFirstVisible() @@ -94,6 +96,9 @@ class HomeFragment : LazyFragment() { }, 100) } }) + mHomeSearchViewModel.homeDataLiveData.observe(this){ + mViewModel.initData(it) + } mScrollCalculatorHelper = ScrollCalculatorHelper(R.id.autoVideoView, 0) } @@ -157,12 +162,12 @@ class HomeFragment : LazyFragment() { mBinding.gameRefresh.setOnRefreshListener { MtaHelper.onEvent("首页_新", "刷新") mViewModel.loadStatus.postValue(LoadStatus.LIST_LOADING) - mViewModel.initData() + mHomeSearchViewModel.getHomeContentUnion(true) } mBinding.reuseNoConnection.root.setOnClickListener { mViewModel.loadStatus.postValue(LoadStatus.INIT_LOADING) - mViewModel.initData() + mHomeSearchViewModel.getHomeContentUnion(true) } } diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index c917521cd5..3dc3b8147e 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -66,19 +66,26 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { } loadStatus.postValue(LoadStatus.INIT_LOADING) - initData() } - fun initData() { + fun initData(homeDataEntity: HomeDataEntity?) { mHomeSlides = arrayListOf() mHomeRecommends = arrayListOf() mHomeContents = arrayListOf() mSubjectGameIdList = hashSetOf() + homeDataEntity?.let { + mHomeSlides.addAll(it.homeSlide) + mHomeRecommends.addAll(it.homeRecommend) + mHomeContents.addAll(it.homeContent) + transformationItemData() + mContentPage = 2 + loadStatus.postValue(LoadStatus.INIT_LOADED) + } + // 触发列表刷新行为时亦刷新内存中的备用游戏库列表 GameSubstituteRepositoryHelper.refreshRepositoryFromLocal() - getHomeSlides() if (SPUtils.getBoolean(SettingsFragment.PERSONAL_RECOMMEND_SP_KEY, true)) { getSmartColumn() } @@ -101,7 +108,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { } // 下载7天排序 - list.sortWith(Comparator { o1, o2 -> o2.download - o1.download }) + list.sortWith { o1, o2 -> o2.download - o1.download } mPluginList = list if (mHomeSlides.isNotEmpty() || mHomeRecommends.isNotEmpty()) { @@ -109,40 +116,6 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { } } - @SuppressLint("CheckResult") - private fun getHomeSlides() { - mApi.getHomeSlides(HaloApp.getInstance().channel, BuildConfig.VERSION_NAME) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(object : BiResponse>() { - override fun onSuccess(data: List) { - mHomeSlides.addAll(data) - getHomeRecommends() - } - - override fun onFailure(exception: Exception) { - getHomeRecommends() - } - }) - } - - @SuppressLint("CheckResult") - private fun getHomeRecommends() { - mApi.getHomeRecommends(HaloApp.getInstance().channel, BuildConfig.VERSION_NAME) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(object : BiResponse>() { - override fun onSuccess(data: List) { - mHomeRecommends.addAll(data) - getHomeContent(true) - } - - override fun onFailure(exception: Exception) { - getHomeContent(true) - } - }) - } - @SuppressLint("CheckResult") fun getHomeContent(initData: Boolean) { if (mIsLoading && !initData || loadStatus.value == LoadStatus.LIST_OVER) return diff --git a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java index 1756869d71..d504682e2d 100644 --- a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java +++ b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java @@ -3547,4 +3547,10 @@ public interface ApiService { @POST("./certification:sync") Observable postSyncCertification(@Body RequestBody body); + /** + * 整合首页接口 + */ + @GET("home/union") + Single getHomeContentUnion(@Query("version") String version, @Query("channel") String channel); + } \ No newline at end of file From 89ead6b348ed96df1b47dc0f53887de2719562c8 Mon Sep 17 00:00:00 2001 From: lyr Date: Fri, 15 Jul 2022 09:13:03 +0800 Subject: [PATCH 103/217] =?UTF-8?q?feat:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=90=9C=E7=B4=A2=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96=EF=BC=88=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E9=83=A8=E5=88=86=202=EF=BC=89https://git.shanqu.cc/p?= =?UTF-8?q?m/halo/halo-app-issues/-/issues/1951?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/util/NewFlatLogUtils.kt | 20 +++++++++++++++++++ .../search/SearchDefaultFragment.kt | 6 ++++++ 2 files changed, 26 insertions(+) diff --git a/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt b/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt index bc1c3494dd..b74b744a96 100644 --- a/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt +++ b/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt @@ -1,6 +1,7 @@ package com.gh.common.util import com.gh.gamecenter.common.json.JsonObjectBuilder +import com.gh.gamecenter.common.json.json import com.gh.gamecenter.common.loghub.LoghubUtils import com.lightgame.utils.Utils import org.json.JSONObject @@ -25,4 +26,23 @@ object NewFlatLogUtils { key to value } } + + // 搜索-点击热门标签 + @JvmStatic + fun logSearchHotTagClick( + tag: String, + linkType: String, + linkId: String, + linkText: String + ) { + val json = json { + "event" to "search_click_hot_tag" + "tag" to tag + "link_type" to linkType + "link_id" to linkId + "link_text" to linkText + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/search/SearchDefaultFragment.kt b/app/src/main/java/com/gh/gamecenter/search/SearchDefaultFragment.kt index 406c7cc29d..fd392fd692 100644 --- a/app/src/main/java/com/gh/gamecenter/search/SearchDefaultFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/search/SearchDefaultFragment.kt @@ -93,6 +93,12 @@ open class SearchDefaultFragment : BaseFragment() { mBinding.hotTagFlexContainer.setLimitHeight(mFlexMaxHeight) createFlexContent(mBinding.hotTagFlex, getTagListString(), clickListener = { val tag = mHotTagList!![it] + NewFlatLogUtils.logSearchHotTagClick( + tag.name ?: "", + tag.type ?: "", + tag.link ?: "", + tag.text ?: "" + ) DataLogUtils.uploadHotTagLog(context, tag.name) PageSwitchDataHelper.pushCurrentPageData( hashMapOf( From d4a9f2ab412ce3526f91e25712a041c4d99bdd3f Mon Sep 17 00:00:00 2001 From: lyr Date: Fri, 15 Jul 2022 14:58:16 +0800 Subject: [PATCH 104/217] =?UTF-8?q?feat:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=B8=B8=E6=88=8F=E4=B8=93?= =?UTF-8?q?=E9=A2=98=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96(=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E9=83=A8=E5=88=86=201)=20https://git.shanqu.cc/pm/hal?= =?UTF-8?q?o/halo-app-issues/-/issues/1950?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../game/horizontal/GameHorizontalAdapter.kt | 39 +++++++++++++++++-- .../horizontal/GameHorizontalSlideAdapter.kt | 6 +-- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalAdapter.kt index 8b46636ea6..c9bb605e40 100644 --- a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalAdapter.kt @@ -5,11 +5,13 @@ import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.gh.common.exposure.ExposureEvent import com.gh.common.util.DataCollectionUtils +import com.gh.common.util.DownloadItemUtils import com.gh.common.util.NewLogUtils import com.gh.gamecenter.core.utils.MtaHelper import com.gh.gamecenter.core.utils.StringUtils import com.gh.gamecenter.common.utils.toBinding import com.gh.gamecenter.GameDetailActivity +import com.gh.gamecenter.common.utils.goneIf import com.gh.gamecenter.databinding.GameHorizontalItemBinding import com.gh.gamecenter.entity.SubjectEntity import com.lightgame.adapter.BaseRecyclerAdapter @@ -66,8 +68,19 @@ class GameHorizontalAdapter( holder.binding.simpleGameContainer.run { gameIcon.displayGameIcon(gameEntity) GameHorizontalSimpleItemViewHolder.setHorizontalNameAndGravity(gameName, gameEntity.name) + downloadBtn.goneIf(!mSubjectEntity.showDownload) + gameName.maxLines = if (mSubjectEntity.showDownload) 1 else 2 } holder.bindGameHorizontalItem(gameEntity, mSubjectEntity) + var entranceResult = "" + var locationResult = "" + if (exposureEventList.isNullOrEmpty()) { + entranceResult = StringUtils.buildString(entrance, "+(", "游戏详情", "[", gameName, "]:大家都在玩[", (position + 1).toString(), "])") + locationResult = StringUtils.buildString("游戏详情-", gameName, "-大家都在玩", ":", gameEntity.name) + } else { + entranceResult = StringUtils.buildString("(游戏-专题:", mSubjectEntity.name, "-列表[", (position + 1).toString(), "])") + locationResult = StringUtils.buildString("游戏-专题-", mSubjectEntity.name, ":", gameEntity.name) + } holder.itemView.setOnClickListener { if (exposureEventList.isNullOrEmpty()) { DataCollectionUtils.uploadClick(mContext, "大家都在玩", "游戏详情", gameEntity.name) @@ -75,19 +88,39 @@ class GameHorizontalAdapter( MtaHelper.onEvent("游戏详情_新", "大家都在玩", gameName + "+" + gameEntity.name) GameDetailActivity.startGameDetailActivity( - mContext, gameEntity, - StringUtils.buildString(entrance, "+(", "游戏详情", "[", gameName, "]:大家都在玩[", (position + 1).toString(), "])") + mContext, + gameEntity, + entranceResult ) } else { GameDetailActivity.startGameDetailActivity( mContext, gameEntity, - StringUtils.buildString("(游戏-专题:", mSubjectEntity.name, "-列表[", (position + 1).toString(), "])"), + entranceResult, traceEvent = exposureEventList!![position] ) } NewLogUtils.logGameDetailPopularClick(gameName, gameId, "game", gameEntity.name ?: "") } + + if (mSubjectEntity.showDownload) { + DownloadItemUtils.setOnClickListener( + mContext, + holder.binding.simpleGameContainer.downloadBtn, + gameEntity, + position, + this, + entranceResult, + locationResult, + exposureEventList!![position] + ) + + DownloadItemUtils.updateDownloadButton( + mContext, + holder.binding.simpleGameContainer.downloadBtn, + gameEntity + ) + } } // notifyDataSetChanged 会出现页面抖动情况 diff --git a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideAdapter.kt index 68c043f464..7bb9557289 100644 --- a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideAdapter.kt @@ -86,9 +86,9 @@ class GameHorizontalSlideAdapter( gameEntity, position, this, - "", - "", - null + StringUtils.buildString("(游戏-专题:", mSubjectEntity.name, "-列表[", (position + 1).toString(), "])"), + StringUtils.buildString("游戏-专题-", mSubjectEntity.name, ":", gameEntity.name), + exposureEventList?.safelyGetInRelease(position) ) DownloadItemUtils.updateDownloadButton( From 47b0361401f1a2e366b1214775fcd7ff1152b92b Mon Sep 17 00:00:00 2001 From: lyr Date: Fri, 15 Jul 2022 17:36:04 +0800 Subject: [PATCH 105/217] =?UTF-8?q?feat:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E7=A4=BE=E5=8C=BA=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E4=BC=98=E5=8C=96-=E7=AC=AC=E5=85=AB=E6=9C=9F(3(?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=80=BB=E8=BE=91))=20https://git.shanqu.cc/?= =?UTF-8?q?pm/halo/halo-app-issues/-/issues/1943?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/halo/assistant/fragment/WebFragment.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/halo/assistant/fragment/WebFragment.kt b/app/src/main/java/com/halo/assistant/fragment/WebFragment.kt index 3e5a72c84f..3158e03941 100644 --- a/app/src/main/java/com/halo/assistant/fragment/WebFragment.kt +++ b/app/src/main/java/com/halo/assistant/fragment/WebFragment.kt @@ -782,6 +782,7 @@ class WebFragment : LazyFragment(), IScrollable { } private fun onShareSuccess() { + if (mShareEntity == null) return mBinding?.newsWebview?.callHandler("onShareSuccess", arrayOf(mShareEntity?.url)) { _: Any? -> } } From e6191e8c375120ba6c67de248a2969408c8240f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Fri, 15 Jul 2022 18:09:56 +0800 Subject: [PATCH 106/217] =?UTF-8?q?feat:=20=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E7=89=88=E5=9D=97=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E5=88=97=E8=A1=A8=E4=BC=98=E5=8C=96(1)=20https://git.?= =?UTF-8?q?shanqu.cc/pm/halo/halo-app-issues/-/issues/1948?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/gamecenter/entity/SubjectEntity.kt | 8 ++ .../gh/gamecenter/game/GameFragmentAdapter.kt | 21 ++++- .../com/gh/gamecenter/game/GameViewModel.kt | 20 ++++- .../BigImageRecommendViewHolder.kt | 27 +++++++ .../gh/gamecenter/game/data/GameItemData.kt | 2 + .../bg_shape_black_alpha_40_radius_3.xml | 6 ++ .../res/layout/big_image_recommend_item.xml | 81 +++++++++++++++++++ .../common/constant/ItemViewType.java | 1 + 8 files changed, 160 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/com/gh/gamecenter/game/bigimagerecommend/BigImageRecommendViewHolder.kt create mode 100644 app/src/main/res/drawable/bg_shape_black_alpha_40_radius_3.xml create mode 100644 app/src/main/res/layout/big_image_recommend_item.xml diff --git a/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt index 130b54108d..94556e1615 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt @@ -51,6 +51,14 @@ data class SubjectEntity( var indexRightTopLink: LinkEntity? = null, var remark: String? = null, // 开测表备注 + var image: String = "", + @SerializedName("first_line_recommend") + var firstLineRecommend: String = "", + @SerializedName("second_line_recommend") + var secondLineRecommend: String = "", + @SerializedName("recommend_tag") + var recommendTag: String = "", + // 专题合集,用于首页专题合集-排行榜样式 var columns: MutableList = mutableListOf(), // 专题背景,用于首页专题合集-排行榜样式 diff --git a/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt index 482c9092bb..c02dccf567 100644 --- a/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt @@ -7,7 +7,6 @@ import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.LinearLayout -import android.widget.TextView import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.gh.common.constant.Config @@ -42,6 +41,7 @@ import com.gh.gamecenter.core.utils.StringUtils import com.gh.gamecenter.databinding.* import com.gh.gamecenter.entity.* import com.gh.gamecenter.eventbus.EBDownloadStatus +import com.gh.gamecenter.game.bigimagerecommend.BigImageRecommendViewHolder import com.gh.gamecenter.game.columncollection.GameColumnCollectionViewHolder import com.gh.gamecenter.game.commoncollection.CommonCollectionViewHolder import com.gh.gamecenter.game.commoncollection.detail.CommonCollectionDetailActivity @@ -116,6 +116,7 @@ class GameFragmentAdapter( if (itemData.rankCollection != null) return ItemViewType.RANK_COLLECTION if (itemData.gameCollection != null) return ItemViewType.GAME_COLLECTION_ITEM if (itemData.doubleCardColumn != null) return ItemViewType.DOUBLE_CARD_COLUMN + if (itemData.bigImageRecommend != null) return ItemViewType.BIG_IMAGE_RECOMMEND return ItemViewType.LOADING } @@ -211,6 +212,9 @@ class GameFragmentAdapter( ItemViewType.DOUBLE_CARD_COLUMN -> { DoubleCardListViewHolder(parent.toBinding()) } + ItemViewType.BIG_IMAGE_RECOMMEND -> { + BigImageRecommendViewHolder(parent.toBinding()) + } else -> GameItemViewHolder(GameItemBinding.bind(mLayoutInflater.inflate(R.layout.game_item, parent, false))) } } @@ -234,6 +238,7 @@ class GameFragmentAdapter( is RankCollectionViewHolder -> bindRankCollection(holder, position) is HomeGameCollectionViewHolder -> bindGameCollection(holder, position) is DoubleCardListViewHolder -> bindGameDoubleCardList(holder, position) + is BigImageRecommendViewHolder -> bindBigImageRecommend(holder, position) } } @@ -395,8 +400,10 @@ class GameFragmentAdapter( val rankCollection = mItemDataList[position].rankCollection val rankCollectionAdapter = holder.bindRankCollection(rankCollection!!) { - NewLogUtils.logColumnCategoryHomeContentClick(it.name ?: "", it.id ?: "", rankCollection.name ?: "", - rankCollection.id ?: "","版块",mViewModel.blockData?.name?:"") + NewLogUtils.logColumnCategoryHomeContentClick( + it.name ?: "", it.id ?: "", rankCollection.name ?: "", + rankCollection.id ?: "", "版块", mViewModel.blockData?.name ?: "" + ) } val exposureEventList = arrayListOf() @@ -655,7 +662,7 @@ class GameFragmentAdapter( LogUtils.logRecommendClick( "版块:${blockData?.text ?: ""}", - entity.name, entity.type, entity.text,entity.link, clickedPosition + entity.name, entity.type, entity.text, entity.link, clickedPosition ) val entrance = "(推荐入口)" @@ -1135,6 +1142,12 @@ class GameFragmentAdapter( } } + private fun bindBigImageRecommend(holder: BigImageRecommendViewHolder, position: Int) { + mItemDataList[position].bigImageRecommend?.run { + holder.bindBigImageRecommend(this, "(板块)") + } + } + override fun getItemCount(): Int { return if (mItemDataList.size > 0) mItemDataList.size + 1 else mItemDataList.size } diff --git a/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt b/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt index 4ad8ff0db3..83d21c32cd 100644 --- a/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt @@ -472,7 +472,7 @@ class GameViewModel(application: Application, var blockData: SubjectRecommendEnt var isTopItemShown = false // 轮播图+导航栏+专题入口 - if (blockData == null || blockData?.display?.recommend!! || blockData?.display?.slide!!|| blockData?.display?.navigation!!) { + if (blockData == null || blockData?.display?.recommend!! || blockData?.display?.slide!! || blockData?.display?.navigation!!) { isTopItemShown = true val itemDataTop = GameItemData() itemDataTop.slideList = mSlideList @@ -565,7 +565,12 @@ class GameViewModel(application: Application, var blockData: SubjectRecommendEnt if (subjectEntity.type == "image" || subjectEntity.type == "image_slide") continue } - if ((subjectEntity.type != "gallery" && subjectEntity.type != "column_collection") + if ((subjectEntity.type != "gallery" + && subjectEntity.type != "column_collection" + && subjectEntity.type != "community_article" + && subjectEntity.type != "question" + && subjectEntity.type != "video" + && subjectEntity.type != "news") || (subjectEntity.type == "column_collection" && subjectEntity.style != "top") ) { val itemDataHead = GameItemData() @@ -699,6 +704,17 @@ class GameViewModel(application: Application, var blockData: SubjectRecommendEnt continue } + if (subjectEntity.type == "community_article" + || subjectEntity.type == "question" + || subjectEntity.type == "video" + || subjectEntity.type == "news" + ) { + val itemDataSubject = GameItemData() + itemDataSubject.bigImageRecommend = subjectEntity + mItemDataListCache.add(itemDataSubject) + continue + } + if (!data.isNullOrEmpty()) { for (i in 0 until data.size) { val game = data[i] diff --git a/app/src/main/java/com/gh/gamecenter/game/bigimagerecommend/BigImageRecommendViewHolder.kt b/app/src/main/java/com/gh/gamecenter/game/bigimagerecommend/BigImageRecommendViewHolder.kt new file mode 100644 index 0000000000..702f89e86e --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/game/bigimagerecommend/BigImageRecommendViewHolder.kt @@ -0,0 +1,27 @@ +package com.gh.gamecenter.game.bigimagerecommend + +import com.gh.common.util.DirectUtils +import com.gh.gamecenter.common.base.BaseRecyclerViewHolder +import com.gh.gamecenter.common.utils.ImageUtils +import com.gh.gamecenter.common.utils.goneIf +import com.gh.gamecenter.databinding.BigImageRecommendItemBinding +import com.gh.gamecenter.entity.LinkEntity +import com.gh.gamecenter.entity.SubjectEntity + +class BigImageRecommendViewHolder(val binding: BigImageRecommendItemBinding) : BaseRecyclerViewHolder(binding.root) { + + fun bindBigImageRecommend(subjectEntity: SubjectEntity, entrance: String) { + + binding.run { + ImageUtils.display(poster, subjectEntity.image) + recommendTag.goneIf(subjectEntity.recommendTag.isEmpty()) + recommendTextTwo.goneIf(subjectEntity.secondLineRecommend.isEmpty()) + recommendTag.text = subjectEntity.recommendTag + recommendTextOne.text = subjectEntity.firstLineRecommend + recommendTextTwo.text = subjectEntity.secondLineRecommend + root.setOnClickListener { + DirectUtils.directToLinkPage(root.context, LinkEntity(link = subjectEntity.id, type = subjectEntity.type), entrance, "") + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/game/data/GameItemData.kt b/app/src/main/java/com/gh/gamecenter/game/data/GameItemData.kt index 1561818bb9..a86c73932a 100644 --- a/app/src/main/java/com/gh/gamecenter/game/data/GameItemData.kt +++ b/app/src/main/java/com/gh/gamecenter/game/data/GameItemData.kt @@ -27,6 +27,8 @@ class GameItemData { var doubleCardColumn: SubjectEntity? = null // 双列卡片专题 + var bigImageRecommend: SubjectEntity? = null //提问、帖子、视频帖、文章 + var blankDivider: Float? = null // 空白的空间补全item var exposureEvent: ExposureEvent? = null diff --git a/app/src/main/res/drawable/bg_shape_black_alpha_40_radius_3.xml b/app/src/main/res/drawable/bg_shape_black_alpha_40_radius_3.xml new file mode 100644 index 0000000000..24fd3312ac --- /dev/null +++ b/app/src/main/res/drawable/bg_shape_black_alpha_40_radius_3.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/big_image_recommend_item.xml b/app/src/main/res/layout/big_image_recommend_item.xml new file mode 100644 index 0000000000..a74d24ddea --- /dev/null +++ b/app/src/main/res/layout/big_image_recommend_item.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/module_common/src/main/java/com/gh/gamecenter/common/constant/ItemViewType.java b/module_common/src/main/java/com/gh/gamecenter/common/constant/ItemViewType.java index 3e241642dc..791857d269 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/constant/ItemViewType.java +++ b/module_common/src/main/java/com/gh/gamecenter/common/constant/ItemViewType.java @@ -39,6 +39,7 @@ public class ItemViewType { public static final int RANK_COLLECTION = 31; // 排行榜样式专题合集 public static final int GAME_COLLECTION_ITEM = 32; // 游戏单 public static final int DOUBLE_CARD_COLUMN = 33; // 双列卡片专题 + public static final int BIG_IMAGE_RECOMMEND = 34; // 大图推荐专题 /** * 普通列表 From 20eb18d3f0cdc974436016889579c3b2da05fd1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Mon, 18 Jul 2022 10:28:59 +0800 Subject: [PATCH 107/217] =?UTF-8?q?feat:=20=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E7=89=88=E5=9D=97=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E5=88=97=E8=A1=A8=E4=BC=98=E5=8C=96(2)=20https://git.?= =?UTF-8?q?shanqu.cc/pm/halo/halo-app-issues/-/issues/1948?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/util/NewFlatLogUtils.kt | 21 +++++++++++++++++++ .../gh/gamecenter/game/GameFragmentAdapter.kt | 9 +++++++- .../BigImageRecommendViewHolder.kt | 7 ++++--- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt b/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt index b74b744a96..d45aa52610 100644 --- a/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt +++ b/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt @@ -45,4 +45,25 @@ object NewFlatLogUtils { } log(json, "event", false) } + + //版块点击内容卡片 + @JvmStatic + fun logBlockGameContentCardClick( + blockId: String, + blockName: String, + linkType: String, + linkId: String, + linkText: String + ) { + val json = json { + "event" to "block_game_content_card_click" + "block_id" to blockId + "block_name" to blockName + "link_type" to linkType + "link_id" to linkId + "link_text" to linkText + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt index c02dccf567..f35623eb6e 100644 --- a/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt @@ -1144,7 +1144,14 @@ class GameFragmentAdapter( private fun bindBigImageRecommend(holder: BigImageRecommendViewHolder, position: Int) { mItemDataList[position].bigImageRecommend?.run { - holder.bindBigImageRecommend(this, "(板块)") + holder.bindBigImageRecommend(this, "(板块)") { + mViewModel.blockData?.let { blockData -> + NewFlatLogUtils.logBlockGameContentCardClick( + blockData.link ?: "", blockData.name ?: "", + it.type ?: "", it.link ?: "", "" + ) + } + } } } diff --git a/app/src/main/java/com/gh/gamecenter/game/bigimagerecommend/BigImageRecommendViewHolder.kt b/app/src/main/java/com/gh/gamecenter/game/bigimagerecommend/BigImageRecommendViewHolder.kt index 702f89e86e..f7c9d43070 100644 --- a/app/src/main/java/com/gh/gamecenter/game/bigimagerecommend/BigImageRecommendViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/game/bigimagerecommend/BigImageRecommendViewHolder.kt @@ -10,8 +10,7 @@ import com.gh.gamecenter.entity.SubjectEntity class BigImageRecommendViewHolder(val binding: BigImageRecommendItemBinding) : BaseRecyclerViewHolder(binding.root) { - fun bindBigImageRecommend(subjectEntity: SubjectEntity, entrance: String) { - + fun bindBigImageRecommend(subjectEntity: SubjectEntity, entrance: String, clickCallback: (LinkEntity) -> Unit) { binding.run { ImageUtils.display(poster, subjectEntity.image) recommendTag.goneIf(subjectEntity.recommendTag.isEmpty()) @@ -20,7 +19,9 @@ class BigImageRecommendViewHolder(val binding: BigImageRecommendItemBinding) : B recommendTextOne.text = subjectEntity.firstLineRecommend recommendTextTwo.text = subjectEntity.secondLineRecommend root.setOnClickListener { - DirectUtils.directToLinkPage(root.context, LinkEntity(link = subjectEntity.id, type = subjectEntity.type), entrance, "") + val linkEntity = LinkEntity(link = subjectEntity.id, type = subjectEntity.type) + clickCallback.invoke(linkEntity) + DirectUtils.directToLinkPage(root.context, linkEntity, entrance, "") } } } From 5f337e3905fc34d8daca00b6ed03c6d258e8ab3b Mon Sep 17 00:00:00 2001 From: lyr Date: Mon, 18 Jul 2022 13:56:34 +0800 Subject: [PATCH 108/217] =?UTF-8?q?chore:=20=E6=9B=B4=E6=96=B0Loghub=20SDK?= =?UTF-8?q?=E8=87=B32.6.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dependencies.gradle | 2 +- .../gamecenter/common/loghub/LoghubHelper.kt | 59 +++++++++++++++---- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 7b6af1623b..954a9f7cb6 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -109,7 +109,7 @@ ext { whatTheStack = "0.1.0_rt" apkParser = "v2.6.10" nanohttpd = "2.3.1" - aliyunLog = "2.5.14" + aliyunLog = "2.6.4" easyFloat = "2.0.4" shapeOfView = "1.4.7" splitties = "3.0.0" diff --git a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubHelper.kt b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubHelper.kt index 621a643502..ed88f6c5af 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubHelper.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubHelper.kt @@ -44,19 +44,21 @@ object LoghubHelper { ACCESS_KEY_ID, ACCESS_KEY_SECRET ).apply { - // 1 开启断点续传功能, 0 关闭 - // 每次发送前会把日志保存到本地的binlog文件,只有发送成功才会删除,保证日志上传At Least Once - setPersistent(1) - // 持久化的文件名,需要保证文件所在的文件夹已创建。配置多个客户端时,不应设置相同文件 - setPersistentFilePath(HaloApp.getInstance().filesDir.absolutePath + "/${logStore}.dat") - // 是否每次AddLog强制刷新,高可靠性场景建议打开 - setPersistentForceFlush(1) - // 持久化文件滚动个数,建议设置成10。 - setPersistentMaxFileCount(10) - // 每个持久化文件的大小,建议设置成1-10M - setPersistentMaxFileSize(1024 * 1024) - // 本地最多缓存的日志数,不建议超过1M,通常设置为65536即可 - setPersistentMaxLogCount(65536) +// // 设置主题 +// setTopic("topic") +// // 设置tag信息,此tag会附加在每条日志上 +// addTag("key", "value") + // 每个缓存的日志包的大小上限,取值为1~5242880,单位为字节。默认为1024 * 1024 + setPacketLogBytes(1024 * 1024) + // 每个缓存的日志包中包含日志数量的最大值,取值为1~4096,默认为1024 + setPacketLogCount(1024) + // 被缓存日志的发送超时时间,如果缓存超时,则会被立即发送,单位为毫秒,默认为3000 + setPacketTimeout(3000) + // 单个Producer Client实例可以使用的内存的上限,超出缓存时add_log接口会立即返回失败 + // 默认为64 * 1024 * 1024 + setMaxBufferLimit(64 * 1024 * 1024) + // 发送线程数,默认为1 + setSendThreadCount(1) //网络连接超时时间,整数,单位秒,默认为10 setConnectTimeoutSec(15) @@ -66,6 +68,11 @@ object LoghubHelper { setDestroyFlusherWaitSec(2) //sender线程池销毁最大等待时间,整数,单位秒,默认为1 setDestroySenderWaitSec(2) + //数据上传时的压缩类型,默认为LZ4压缩,0 不压缩,1 LZ4压缩,默认为1 + setCompressType(1) + //设备时间与标准时间之差,值为标准时间-设备时间,一般此种情况用于客户端设备时间不同步的场景 + //整数,单位秒,默认为0;比如当前设备时间为1607064208, 标准时间为1607064308,则值设置为 1607064308 - 1607064208 = 10 + setNtpTimeOffset(0) //日志时间与本机时间之差,超过该大小后会根据 `drop_delay_log` 选项进行处理。 //一般此种情况只会在设置persistent的情况下出现,即设备下线后,超过几天/数月启动,发送退出前未发出的日志 //整数,单位秒,默认为7*24*3600,即7天 @@ -76,8 +83,34 @@ object LoghubHelper { //是否丢弃鉴权失败的日志,0 不丢弃,1丢弃 //默认为 0,即不丢弃 setDropUnauthorizedLog(0) + // 是否使用主线程回调 + // false: 使用主线程回调。回调会在主线程上执行,且每个 client 都有自己单独的回调。 + // true: 使用 sender 线程回调。回调会在 sender 线程上执行,每次执行回调时都会 attach 一个新的 java 线程,所有 client 共用一个回调。 + // 注意:默认使用 sender 线程回调。 + setCallbackFromSenderThread(true) + + /** + * 以下为开启断点续传的配置, 按照如下配置开启断点续传功能后, 日志会先缓存到本地 + */ + // 1 开启断点续传功能, 0 关闭 + // 每次发送前会把日志保存到本地的binlog文件,只有发送成功才会删除,保证日志上传At Least Once + setPersistent(1) + // 持久化的文件名,需要保证文件所在的文件夹已创建。 + // !!!!!!!!!!!!!!!!!!!注意!!!!!!!!!!!!!!!!!!! + // 配置多个客户端时,不应设置相同文件 + setPersistentFilePath(HaloApp.getInstance().filesDir.absolutePath + "/${logStore}.dat") + // 是否每次AddLog强制刷新,高可靠性场景建议打开 + setPersistentForceFlush(1) + // 持久化文件滚动个数,建议设置成10。 + setPersistentMaxFileCount(10) + // 每个持久化文件的大小,建议设置成1-10M + setPersistentMaxFileSize(1024 * 1024) + // 本地最多缓存的日志数,不建议超过1M,通常设置为65536即可 + setPersistentMaxLogCount(65536) } + // 通过 LogProducerConfig 构造一个 LogProducerClient 实例 + // callback为可选配置, 如果不需要关注日志的发送成功或失败状态, 可以不注册 callback(正式环境不注册callback) return if (!PackageFlavorHelper.IS_TEST_FLAVOR) { LogProducerClient(config) } else { From cbc65e4ccd9a491cdf1b7678cae5aa9992a86749 Mon Sep 17 00:00:00 2001 From: lyr Date: Mon, 18 Jul 2022 14:41:37 +0800 Subject: [PATCH 109/217] =?UTF-8?q?fix:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.10.0=E3=80=91=E7=95=85=E7=8E=A9=E5=8A=A9?= =?UTF-8?q?=E6=89=8B=E6=95=B0=E6=8D=AE=E5=9F=8B=E7=82=B9(20220713=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E8=A1=A5=E5=85=85=201)=20https://git.shanqu.cc/pm/hal?= =?UTF-8?q?o/halo-app-issues/-/issues/1872#note=5F159670?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VHelper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index ac7d0a234c..737815c097 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -253,7 +253,7 @@ object VHelper { val containsUpdate = shouldShowVSpaceUpdate(mUpdateEntity, installedSpaceVersionCode) if (containsUpdate) { - val dialogType = if (mUpdateEntity!!.isForce) "强制更新" else "提示更新" + val dialogType = if (mUpdateEntity!!.isAlertEveryTime()) "强制更新" else "提示更新" NewFlatLogUtils.logHaloFunEvent("halo_fun_update_dialog_show") SPUtils.setString( KEY_LAST_ALERT_UPDATE_URL, From 59cc581645ccea81750ff09981b59f889a6c37ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Mon, 18 Jul 2022 17:07:48 +0800 Subject: [PATCH 110/217] =?UTF-8?q?fix:=20=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E7=AB=AF=E5=86=85=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E9=80=82=E9=85=8D=E7=9F=AD=E9=93=BE=E6=8E=A5(0718?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=8F=8D=E9=A6=88)=20https://git.shanqu.cc/p?= =?UTF-8?q?m/halo/halo-app-issues/-/issues/1945?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../comment/ArticleDetailCommentViewModel.kt | 2 +- .../qa/comment/base/BaseCommentViewModel.kt | 4 ++-- .../CommentConversationViewModel.kt | 2 +- .../retrofit/service/ApiService.java | 18 ++++++++---------- 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/qa/article/detail/comment/ArticleDetailCommentViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/article/detail/comment/ArticleDetailCommentViewModel.kt index 19d7cc7d0a..7d04485fbb 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/article/detail/comment/ArticleDetailCommentViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/article/detail/comment/ArticleDetailCommentViewModel.kt @@ -37,7 +37,7 @@ class ArticleDetailCommentViewModel(application: Application, @SuppressLint("CheckResult") fun getComment() { RetrofitManager.getInstance().api - .getCommunityArticleComment(communityId, articleId, commentId) + .getCommunityArticleComment(articleId, commentId) .subscribeOn(Schedulers.io()) .subscribe(object : BiResponse() { @SuppressLint("CheckResult") diff --git a/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt index e8b4b6e1c1..2c7e390003 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt @@ -305,7 +305,7 @@ abstract class BaseCommentViewModel( } when { articleId.isNotEmpty() -> { - mApi.postArticleCommentTop(articleId, commentId, map) + mApi.postArticleCommentTop(commentId, map) } questionId.isNotEmpty() -> { mApi.postQuestionCommentTop(questionId, commentId, map) @@ -318,7 +318,7 @@ abstract class BaseCommentViewModel( } else { when { articleId.isNotEmpty() -> { - mApi.postArticleCommentUnTop(articleId, commentId) + mApi.postArticleCommentUnTop(commentId) } questionId.isNotEmpty() -> { mApi.postQuestionCommentUnTop(questionId, commentId) diff --git a/app/src/main/java/com/gh/gamecenter/qa/comment/conversation/CommentConversationViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/comment/conversation/CommentConversationViewModel.kt index 70fbc5e93c..2e23e4a8b4 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/comment/conversation/CommentConversationViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/comment/conversation/CommentConversationViewModel.kt @@ -59,7 +59,7 @@ class CommentConversationViewModel( fun getComment() { val single = when { articleId.isNotEmpty() -> { - mApi.getCommunityArticleComment(communityId, articleId, commentId) + mApi.getCommunityArticleComment(articleId, commentId) } videoId.isNotEmpty() -> { mApi.getCommunityVideoComment(videoId, commentId) diff --git a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java index d504682e2d..837353b573 100644 --- a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java +++ b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java @@ -1482,18 +1482,16 @@ public interface ApiService { /** * 获取社区文章评论的对话列表. */ - @GET("communities/{community_id}/articles/{article_id}/comments/{comment_id}/trace") - Observable> getCommunityArticleCommentConversation(@Path("community_id") String communityId, - @Path("article_id") String articleId, + @GET("communities/articles/{article_id}/comments/{comment_id}/trace") + Observable> getCommunityArticleCommentConversation(@Path("article_id") String articleId, @Path("comment_id") String commentId, @Query("page") int page); /** * 获取单条社区文章评论 */ - @GET("communities/{community_id}/articles/{article_id}/comments/{comment_id}") - Single getCommunityArticleComment(@Path("community_id") String communityId, - @Path("article_id") String articleId, + @GET("communities/articles/{article_id}/comments/{comment_id}") + Single getCommunityArticleComment(@Path("article_id") String articleId, @Path("comment_id") String commentId); /** @@ -2801,14 +2799,14 @@ public interface ApiService { /** * 置顶评论 */ - @POST("communities/articles/{article_id}/comments/{comment_id}:set-top") - Observable postArticleCommentTop(@Path("article_id") String articleId, @Path("comment_id") String commentId, @QueryMap Map params); + @POST("communities/articles/comments/{comment_id}:set-top") + Observable postArticleCommentTop(@Path("comment_id") String commentId, @QueryMap Map params); /** * 取消置顶评论 */ - @POST("communities/articles/{article_id}/comments/{comment_id}:unset-top") - Observable postArticleCommentUnTop(@Path("article_id") String articleId, @Path("comment_id") String commentId); + @POST("communities/articles/comments/{comment_id}:unset-top") + Observable postArticleCommentUnTop(@Path("comment_id") String commentId); /** * 获取推荐的论坛 From 2d5420efecfeca73e32eea8b7c168e3fb2a0e248 Mon Sep 17 00:00:00 2001 From: lyr Date: Mon, 18 Jul 2022 18:34:54 +0800 Subject: [PATCH 111/217] =?UTF-8?q?feat:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=B8=B8=E6=88=8F=E4=B8=93?= =?UTF-8?q?=E9=A2=98=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96(=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E9=83=A8=E5=88=86=201(=E5=A2=9E=E5=8A=A0=E5=88=97?= =?UTF-8?q?=E8=A1=A8Item=E5=88=B7=E6=96=B0=E9=80=BB=E8=BE=91))=20https://g?= =?UTF-8?q?it.shanqu.cc/pm/halo/halo-app-issues/-/issues/1950?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/gamecenter/game/GameFragmentAdapter.kt | 2 +- .../game/horizontal/GameHorizontalAdapter.kt | 35 +++++++++++++++--- .../GameHorizontalListViewHolder.kt | 12 +++--- .../horizontal/GameHorizontalSlideAdapter.kt | 27 +++++++++++++- .../GameHorizontalSlideListViewHolder.kt | 26 ++++++------- .../gh/gamecenter/home/HomeFragmentAdapter.kt | 20 +++++++--- .../LegacyHomeFragmentAdapterAssistant.kt | 30 +++++++++++++-- .../home/LegacyHomeSubjectTransformer.kt | 37 ++++++++++++++++++- .../main/res/layout/game_horizontal_list.xml | 4 +- 9 files changed, 153 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt index f35623eb6e..6a5a8fb43f 100644 --- a/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt @@ -531,7 +531,7 @@ class GameFragmentAdapter( val subjectAdapter = holder.bindHorizontalList(subjectEntity!!) if (subjectEntity.type != "game_horizontal") { - holder.binding.horizontalRv.doOnScrolledSpecificDistance(distanceX = DisplayUtils.dip2px(24f), singleTimeEvent = true) { + holder.binding.recyclerView.doOnScrolledSpecificDistance(distanceX = DisplayUtils.dip2px(24f), singleTimeEvent = true) { MtaHelper.onEvent("游戏专题", "滑动", subjectEntity.name) } } diff --git a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalAdapter.kt index c9bb605e40..6c8687b98d 100644 --- a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalAdapter.kt @@ -15,6 +15,7 @@ import com.gh.gamecenter.common.utils.goneIf import com.gh.gamecenter.databinding.GameHorizontalItemBinding import com.gh.gamecenter.entity.SubjectEntity import com.lightgame.adapter.BaseRecyclerAdapter +import com.lightgame.download.DownloadEntity class GameHorizontalAdapter( context: Context, @@ -58,11 +59,9 @@ class GameHorizontalAdapter( } override fun onBindViewHolder(holder: GameHorizontalItemViewHolder, position: Int) { - if (exposureEventList.isNullOrEmpty()) { - val params = holder.binding.root.layoutParams as RecyclerView.LayoutParams - params.width = RecyclerView.LayoutParams.WRAP_CONTENT - holder.binding.root.layoutParams = params - } + val params = holder.binding.root.layoutParams as RecyclerView.LayoutParams + params.width = if (gameName.isNotBlank()) RecyclerView.LayoutParams.WRAP_CONTENT else RecyclerView.LayoutParams.MATCH_PARENT + holder.binding.root.layoutParams = params val gameEntity = mSubjectEntity.data!![position + getIndex()] holder.binding.simpleGameContainer.run { @@ -112,7 +111,7 @@ class GameHorizontalAdapter( this, entranceResult, locationResult, - exposureEventList!![position] + if (position < (exposureEventList?.size ?: 0)) exposureEventList!![position] else null ) DownloadItemUtils.updateDownloadButton( @@ -123,6 +122,30 @@ class GameHorizontalAdapter( } } + fun notifyItemByDownload(downloadEntity: DownloadEntity?) { + if (downloadEntity == null) { + notifyDataSetChanged() + } else { + mSubjectEntity.data?.forEachIndexed { position, gameEntity -> + if (downloadEntity.gameId == gameEntity.id) { + notifyItemChanged(position - getIndex()) + return + } + } + } + } + + fun notifyChildItem(packageName: String) { + mSubjectEntity.data?.forEachIndexed { position, gameEntity -> + gameEntity.getApk().forEach { apkEntity -> + if (apkEntity.packageName == packageName) { + notifyItemChanged(position - getIndex()) + return + } + } + } + } + // notifyDataSetChanged 会出现页面抖动情况 fun checkResetData(subjectEntity: SubjectEntity) { var dataIds = "" diff --git a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalListViewHolder.kt b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalListViewHolder.kt index ddcf3077a1..3b0a98826b 100644 --- a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalListViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalListViewHolder.kt @@ -12,14 +12,14 @@ class GameHorizontalListViewHolder(val binding: GameHorizontalListBinding) : Bas fun bindHorizontalList(subjectEntity: SubjectEntity): GameHorizontalAdapter { val context = binding.root.context - var subjectAdapter = binding.horizontalRv.adapter + var subjectAdapter = binding.recyclerView.adapter if (subjectAdapter == null) { - binding.horizontalRv.setPadding(5F.dip2px(), 8F.dip2px(), 5F.dip2px(), 8F.dip2px()) - binding.horizontalRv.layoutManager = GridLayoutManager(context, 4) + binding.recyclerView.setPadding(5F.dip2px(), 8F.dip2px(), 5F.dip2px(), 8F.dip2px()) + binding.recyclerView.layoutManager = GridLayoutManager(context, 4) subjectAdapter = GameHorizontalAdapter(context, subjectEntity) - (binding.horizontalRv.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false - binding.horizontalRv.adapter = subjectAdapter - binding.horizontalRv.isNestedScrollingEnabled = false + (binding.recyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false + binding.recyclerView.adapter = subjectAdapter + binding.recyclerView.isNestedScrollingEnabled = false } else { (subjectAdapter as GameHorizontalAdapter).checkResetData(subjectEntity) } diff --git a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideAdapter.kt index 7bb9557289..6173fa362d 100644 --- a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideAdapter.kt @@ -11,6 +11,7 @@ import com.gh.gamecenter.core.utils.* import com.gh.gamecenter.databinding.GameHorizontalItemBinding import com.gh.gamecenter.entity.SubjectEntity import com.lightgame.adapter.BaseRecyclerAdapter +import com.lightgame.download.DownloadEntity class GameHorizontalSlideAdapter( context: Context, @@ -88,7 +89,7 @@ class GameHorizontalSlideAdapter( this, StringUtils.buildString("(游戏-专题:", mSubjectEntity.name, "-列表[", (position + 1).toString(), "])"), StringUtils.buildString("游戏-专题-", mSubjectEntity.name, ":", gameEntity.name), - exposureEventList?.safelyGetInRelease(position) + if (position < (exposureEventList?.size ?: 0)) exposureEventList!![position] else null ) DownloadItemUtils.updateDownloadButton( @@ -99,6 +100,30 @@ class GameHorizontalSlideAdapter( } } + fun notifyItemByDownload(downloadEntity: DownloadEntity?) { + if (downloadEntity == null) { + notifyDataSetChanged() + } else { + mSubjectEntity.data?.forEachIndexed { position, gameEntity -> + if (downloadEntity.gameId == gameEntity.id) { + notifyItemChanged(position - getIndex()) + return + } + } + } + } + fun notifyChildItem(packageName: String) { + mSubjectEntity.data?.forEachIndexed { position, gameEntity -> + gameEntity.getApk().forEach { apkEntity -> + if (apkEntity.packageName == packageName) { + notifyItemChanged(position - getIndex()) + return + } + } + } + } + + // notifyDataSetChanged 会出现页面抖动情况 fun checkResetData(subjectEntity: SubjectEntity) { var dataIds = "" diff --git a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideListViewHolder.kt b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideListViewHolder.kt index dc13aadd1b..33d39c2006 100644 --- a/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideListViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/game/horizontal/GameHorizontalSlideListViewHolder.kt @@ -27,17 +27,17 @@ class GameHorizontalSlideListViewHolder(val binding: GameHorizontalListBinding) offsetable: IOffsetable ): GameHorizontalSlideAdapter { val context = binding.root.context - var subjectAdapter = binding.horizontalRv.adapter + var subjectAdapter = binding.recyclerView.adapter binding.fakeRemarkLine.setBackgroundColor(R.color.btn_gray_light.toColor(context)) if (subjectAdapter == null) { - binding.horizontalRv.setPadding(10F.dip2px(), 8F.dip2px(), 10F.dip2px(), 8F.dip2px()) - binding.horizontalRv.layoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false) - binding.horizontalRv.clipToPadding = false + binding.recyclerView.setPadding(10F.dip2px(), 8F.dip2px(), 10F.dip2px(), 8F.dip2px()) + binding.recyclerView.layoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false) + binding.recyclerView.clipToPadding = false subjectAdapter = GameHorizontalSlideAdapter(context, subjectEntity) - (binding.horizontalRv.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false - binding.horizontalRv.adapter = subjectAdapter - binding.horizontalRv.setScrollingTouchSlop(RecyclerView.TOUCH_SLOP_PAGING) - binding.horizontalRv.isNestedScrollingEnabled = false + (binding.recyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false + binding.recyclerView.adapter = subjectAdapter + binding.recyclerView.setScrollingTouchSlop(RecyclerView.TOUCH_SLOP_PAGING) + binding.recyclerView.isNestedScrollingEnabled = false if (subjectEntity.data?.firstOrNull()?.test?.testTime != null && mLastScrolledPosition == 0) { scrollToSpecificItemForTheFirstTime(subjectEntity) @@ -52,12 +52,12 @@ class GameHorizontalSlideListViewHolder(val binding: GameHorizontalListBinding) if (subjectEntity.data?.firstOrNull()?.test?.testTime != null && mLastScrolledPosition == 0) { scrollToSpecificItemForTheFirstTime(subjectEntity) } else { - binding.horizontalRv.scrollToPosition(0) + binding.recyclerView.scrollToPosition(0) } } else { // 可能会因为上下复用数据变化而出现 IndexOutOfBoundsException 异常,毕竟有局部更新功能... tryCatchInRelease { - binding.horizontalRv.scrollBy(offset, offset) + binding.recyclerView.scrollBy(offset, offset) } } } @@ -77,7 +77,7 @@ class GameHorizontalSlideListViewHolder(val binding: GameHorizontalListBinding) } } - binding.horizontalRv.addOnScrollListener(mScrollListener!!) + binding.recyclerView.addOnScrollListener(mScrollListener!!) } return subjectAdapter @@ -85,7 +85,7 @@ class GameHorizontalSlideListViewHolder(val binding: GameHorizontalListBinding) private fun scrollToSpecificItemForTheFirstTime(subjectEntity: SubjectEntity) { val position = findTheLatestTestGamePosition(subjectEntity) - binding.horizontalRv.scrollToPosition(position) + binding.recyclerView.scrollToPosition(position) } /** @@ -136,7 +136,7 @@ class GameHorizontalSlideListViewHolder(val binding: GameHorizontalListBinding) // 这里显示一条假的线供上层 recyclerView 列表使用,因为写在 item 里面很复杂 binding.root.post { binding.fakeRemarkLine.layoutParams = (binding.fakeRemarkLine.layoutParams as ConstraintLayout.LayoutParams).apply { - topMargin = getTopOfLineContainer(binding.horizontalRv) + 2F.dip2px() // 这里加上的2F是点的边距 + topMargin = getTopOfLineContainer(binding.recyclerView) + 2F.dip2px() // 这里加上的2F是点的边距 } } binding.fakeRemarkLine.visibility = View.VISIBLE diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt index e56f00bd62..825ea14578 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt @@ -26,6 +26,8 @@ import com.gh.gamecenter.databinding.* import com.gh.gamecenter.entity.AmwayCommentEntity import com.gh.gamecenter.eventbus.EBDownloadStatus import com.gh.gamecenter.game.GameAndPosition +import com.gh.gamecenter.game.horizontal.GameHorizontalAdapter +import com.gh.gamecenter.game.horizontal.GameHorizontalSlideAdapter import com.gh.gamecenter.game.rank.RankCollectionAdapter import com.gh.gamecenter.game.vertical.GameVerticalAdapter import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity @@ -394,7 +396,9 @@ class HomeFragmentAdapter( if (getItemViewType(gameAndPosition.position) == ItemViewType.VERTICAL_SLIDE_ITEM || getItemViewType(gameAndPosition.position) == ItemViewType.GAME_PLUGIN || getItemViewType(gameAndPosition.position) == SLIDE_ITEM || - getItemViewType(gameAndPosition.position) == ItemViewType.RANK_COLLECTION + getItemViewType(gameAndPosition.position) == ItemViewType.RANK_COLLECTION || + getItemViewType(gameAndPosition.position) == ItemViewType.GAME_SUBJECT || + getItemViewType(gameAndPosition.position) == ItemViewType.GAME_SUBJECT_SLIDE ) { val view = layoutManager.findViewByPosition(gameAndPosition.position) val recyclerView = view?.findViewById(R.id.recycler_view) @@ -403,6 +407,8 @@ class HomeFragmentAdapter( is GamePluginAdapter -> adapter.notifyItemByDownload(download) is HomeSlideListAdapter -> adapter.notifyItemByDownload(download) is RankCollectionAdapter -> adapter.notifyItemByDownload(download) + is GameHorizontalAdapter -> adapter.notifyItemByDownload(download) + is GameHorizontalSlideAdapter -> adapter.notifyItemByDownload(download) } } else { notifyItemChanged(gameAndPosition.position) @@ -424,13 +430,17 @@ class HomeFragmentAdapter( if (getItemViewType(position) == ItemViewType.VERTICAL_SLIDE_ITEM || getItemViewType(position) == ItemViewType.GAME_PLUGIN || getItemViewType(position) == SLIDE_ITEM || - getItemViewType(position) == ItemViewType.RANK_COLLECTION + getItemViewType(position) == ItemViewType.RANK_COLLECTION || + getItemViewType(position) == ItemViewType.GAME_SUBJECT || + getItemViewType(position) == ItemViewType.GAME_SUBJECT_SLIDE ) { val view = layoutManager.findViewByPosition(position) val recyclerView = view?.findViewById(R.id.recycler_view) - when (recyclerView?.adapter) { - is RankCollectionAdapter -> (recyclerView.adapter as RankCollectionAdapter).notifyChildItem() - is GameVerticalAdapter -> (recyclerView.adapter as GameVerticalAdapter).notifyChildItem(packageName) + when (val adapter = recyclerView?.adapter) { + is RankCollectionAdapter -> adapter.notifyChildItem() + is GameVerticalAdapter -> adapter.notifyChildItem(packageName) + is GameHorizontalAdapter -> adapter.notifyChildItem(packageName) + is GameHorizontalSlideAdapter -> adapter.notifyChildItem(packageName) else -> recyclerView?.adapter?.notifyDataSetChanged() } } else { diff --git a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt index 9901558166..96629096f5 100644 --- a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt +++ b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt @@ -162,7 +162,29 @@ class LegacyHomeFragmentAdapterAssistant( val horizontalColumn = itemData.horizontalColumn if (horizontalColumn != null) { - positionList.add(GameAndPosition(null, position)) + for (i in horizontalColumn.data!!.indices) { + val entity = horizontalColumn.data!![i] + if (!entity.image.isNullOrEmpty()) continue + for (apkEntity in entity.getApk()) { + if (apkEntity.packageName == packageName) { + positionList.add(GameAndPosition(entity, position)) + } + } + } + return + } + + val horizontalSlide = itemData.horizontalSlide + if (horizontalSlide != null) { + for (i in horizontalSlide.data!!.indices) { + val entity = horizontalSlide.data!![i] + if (!entity.image.isNullOrEmpty()) continue + for (apkEntity in entity.getApk()) { + if (apkEntity.packageName == packageName) { + positionList.add(GameAndPosition(entity, position)) + } + } + } return } @@ -376,7 +398,7 @@ class LegacyHomeFragmentAdapterAssistant( val subjectAdapter = holder.bindHorizontalList(subjectEntity!!) if (mOuterType == OuterType.AMWAY) { - holder.binding.horizontalRv.isNestedScrollingEnabled = false + holder.binding.recyclerView.isNestedScrollingEnabled = false } val exposureEventList = arrayListOf() @@ -408,7 +430,7 @@ class LegacyHomeFragmentAdapterAssistant( val subjectAdapter = holder.bindHorizontalSlideList(subjectEntity!!, this) if (mOuterType == OuterType.AMWAY) { - holder.binding.horizontalRv.isNestedScrollingEnabled = false + holder.binding.recyclerView.isNestedScrollingEnabled = false } val exposureEventList = arrayListOf() @@ -438,7 +460,7 @@ class LegacyHomeFragmentAdapterAssistant( } if (subjectEntity.type != "game_horizontal") { - holder.binding.horizontalRv.doOnScrolledSpecificDistance(distanceX = DisplayUtils.dip2px(24f), singleTimeEvent = true) { + holder.binding.recyclerView.doOnScrolledSpecificDistance(distanceX = DisplayUtils.dip2px(24f), singleTimeEvent = true) { if (mOuterType == OuterType.NEW_HOME) { MtaHelper.onEvent("游戏专题", "新首页专题滑动", "内容" + item.blockPosition + "_" + subjectEntity.name) } else { diff --git a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeSubjectTransformer.kt b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeSubjectTransformer.kt index da79e435a6..45b6005acd 100644 --- a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeSubjectTransformer.kt +++ b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeSubjectTransformer.kt @@ -115,13 +115,29 @@ object LegacyHomeSubjectTransformer { val itemHorizontalSlide = newItemInstance() itemHorizontalSlide.blockPosition = blockPosition + 1 itemHorizontalSlide.horizontalSlide = subjectEntity - appendAdditionalInfoToSubjectGame(subjectEntity, blockPosition) if (subjectEntity.indexRightTop == "all") { subjectEntity.indexRightTopLink = LinkEntity(text = subjectEntity.name, link = subjectEntity.id, type = "column_test") } itemList.add(itemHorizontalSlide) + + for (i in 0 until data.size) { + val game = data[i] + if (!game.image.isNullOrEmpty()) continue + game.subjectData = GameSubjectData( + id = subjectEntity.id, + name = subjectEntity.name, + tag = subjectEntity.tag, + position = i + if (data[0].image.isNullOrEmpty()) 1 else 0, + isOrder = subjectEntity.isOrder, + briefStyle = subjectEntity.briefStyle, + isShowSuffix = subjectEntity.showSuffix) + game.outerSequence = blockPosition + game.sequence = i + + addGamePositionAndPackage(game) + } return } @@ -129,8 +145,25 @@ object LegacyHomeSubjectTransformer { val itemDataSubject = newItemInstance() itemDataSubject.blockPosition = blockPosition + 1 itemDataSubject.horizontalColumn = subjectEntity - appendAdditionalInfoToSubjectGame(subjectEntity, blockPosition) itemList.add(itemDataSubject) + + for (i in 0 until data.size) { + val game = data[i] + if (!game.image.isNullOrEmpty()) continue + game.subjectData = GameSubjectData( + id = subjectEntity.id, + name = subjectEntity.name, + tag = subjectEntity.tag, + position = i + if (data[0].image.isNullOrEmpty()) 1 else 0, + isOrder = subjectEntity.isOrder, + briefStyle = subjectEntity.briefStyle, + isShowSuffix = subjectEntity.showSuffix) + game.outerSequence = blockPosition + game.sequence = i + + addGamePositionAndPackage(game) + } + return } diff --git a/app/src/main/res/layout/game_horizontal_list.xml b/app/src/main/res/layout/game_horizontal_list.xml index f9de76c4af..a2d69d7245 100644 --- a/app/src/main/res/layout/game_horizontal_list.xml +++ b/app/src/main/res/layout/game_horizontal_list.xml @@ -12,10 +12,10 @@ android:layout_marginTop="37dp" android:background="@color/btn_gray_light" android:visibility="gone" - app:layout_constraintTop_toTopOf="@id/horizontal_rv" /> + app:layout_constraintTop_toTopOf="@id/recycler_view" /> Date: Tue, 19 Jul 2022 09:39:12 +0800 Subject: [PATCH 112/217] =?UTF-8?q?feat:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=B8=B8=E6=88=8F=E4=B8=93?= =?UTF-8?q?=E9=A2=98=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96(=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E9=83=A8=E5=88=86=201(=E4=BC=98=E5=8C=96=E5=88=97?= =?UTF-8?q?=E8=A1=A8Item=E5=88=B7=E6=96=B0=E9=80=BB=E8=BE=91))=20https://g?= =?UTF-8?q?it.shanqu.cc/pm/halo/halo-app-issues/-/issues/1950?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/LegacyHomeSubjectTransformer.kt | 69 ++++++++++--------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeSubjectTransformer.kt b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeSubjectTransformer.kt index 45b6005acd..3f1203dd1f 100644 --- a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeSubjectTransformer.kt +++ b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeSubjectTransformer.kt @@ -115,28 +115,31 @@ object LegacyHomeSubjectTransformer { val itemHorizontalSlide = newItemInstance() itemHorizontalSlide.blockPosition = blockPosition + 1 itemHorizontalSlide.horizontalSlide = subjectEntity - if (subjectEntity.indexRightTop == "all") { subjectEntity.indexRightTopLink = LinkEntity(text = subjectEntity.name, link = subjectEntity.id, type = "column_test") } - itemList.add(itemHorizontalSlide) - for (i in 0 until data.size) { - val game = data[i] - if (!game.image.isNullOrEmpty()) continue - game.subjectData = GameSubjectData( - id = subjectEntity.id, - name = subjectEntity.name, - tag = subjectEntity.tag, - position = i + if (data[0].image.isNullOrEmpty()) 1 else 0, - isOrder = subjectEntity.isOrder, - briefStyle = subjectEntity.briefStyle, - isShowSuffix = subjectEntity.showSuffix) - game.outerSequence = blockPosition - game.sequence = i + if (!subjectEntity.showDownload) { + appendAdditionalInfoToSubjectGame(subjectEntity, blockPosition) + } else { + for (i in 0 until data.size) { + val game = data[i] + if (!game.image.isNullOrEmpty()) continue + game.subjectData = GameSubjectData( + id = subjectEntity.id, + name = subjectEntity.name, + tag = subjectEntity.tag, + position = i + if (data[0].image.isNullOrEmpty()) 1 else 0, + isOrder = subjectEntity.isOrder, + briefStyle = subjectEntity.briefStyle, + isShowSuffix = subjectEntity.showSuffix + ) + game.outerSequence = blockPosition + game.sequence = i - addGamePositionAndPackage(game) + addGamePositionAndPackage(game) + } } return } @@ -147,23 +150,27 @@ object LegacyHomeSubjectTransformer { itemDataSubject.horizontalColumn = subjectEntity itemList.add(itemDataSubject) - for (i in 0 until data.size) { - val game = data[i] - if (!game.image.isNullOrEmpty()) continue - game.subjectData = GameSubjectData( - id = subjectEntity.id, - name = subjectEntity.name, - tag = subjectEntity.tag, - position = i + if (data[0].image.isNullOrEmpty()) 1 else 0, - isOrder = subjectEntity.isOrder, - briefStyle = subjectEntity.briefStyle, - isShowSuffix = subjectEntity.showSuffix) - game.outerSequence = blockPosition - game.sequence = i + if (!subjectEntity.showDownload) { + appendAdditionalInfoToSubjectGame(subjectEntity, blockPosition) + } else { + for (i in 0 until data.size) { + val game = data[i] + if (!game.image.isNullOrEmpty()) continue + game.subjectData = GameSubjectData( + id = subjectEntity.id, + name = subjectEntity.name, + tag = subjectEntity.tag, + position = i + if (data[0].image.isNullOrEmpty()) 1 else 0, + isOrder = subjectEntity.isOrder, + briefStyle = subjectEntity.briefStyle, + isShowSuffix = subjectEntity.showSuffix + ) + game.outerSequence = blockPosition + game.sequence = i - addGamePositionAndPackage(game) + addGamePositionAndPackage(game) + } } - return } From ef72119a489e7b39a797db84133e83ded3a3414d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Tue, 19 Jul 2022 09:59:49 +0800 Subject: [PATCH 113/217] =?UTF-8?q?fix:=20=E6=8F=90=E4=BA=A4=E9=81=97?= =?UTF-8?q?=E6=BC=8F=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt index bbfa72f789..73fc4b3c36 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt @@ -51,7 +51,7 @@ open class NewCommentViewModel( val postCommentLiveData: LiveData> get() = mPostCommentLiveData - val deleteVideoCommentLiveData = MutableLiveData() + val deleteVideoCommentLiveData = MutableLiveData() val pictureList = ArrayList() val pictureLiveData = MutableLiveData>() @@ -67,7 +67,7 @@ open class NewCommentViewModel( CommentType.ANSWER_CONVERSATION -> api.getAnswerCommentConversationList(answerId, commentId, page) CommentType.COMMUNITY_ARTICLE -> api.getCommunityArticleCommentList(articleId, "time.create:1", page, mapOf()) - CommentType.COMMUNITY_ARTICLE_CONVERSATION -> api.getCommunityArticleCommentConversation(communityId, articleId, commentId, page) + CommentType.COMMUNITY_ARTICLE_CONVERSATION -> api.getCommunityArticleCommentConversation(articleId, commentId, page) CommentType.VIDEO -> api.getVideoCommentList(videoId, page, mapOf()) CommentType.VIDEO_CONVERSATION -> api.getVideoCommentConversationList(videoId, commentId, page) From 96d60fefd4ea82e486f391964e319062b1ec4b9c Mon Sep 17 00:00:00 2001 From: lyr Date: Tue, 19 Jul 2022 13:47:32 +0800 Subject: [PATCH 114/217] =?UTF-8?q?fix:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E7=A4=BE=E5=8C=BA=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E4=BC=98=E5=8C=96-=E7=AC=AC=E5=85=AB=E6=9C=9F(?= =?UTF-8?q?=E7=AC=AC2=E7=82=B9=20=E9=95=BF=E6=8C=89=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=BA1=E7=A7=92)=20https://git.shanqu.cc/?= =?UTF-8?q?pm/halo/halo-app-issues/-/issues/1943#note=5F159827?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../personalhome/UserHomeFragment.kt | 53 ++----------------- 1 file changed, 4 insertions(+), 49 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt b/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt index 15702c4464..a20dc06167 100644 --- a/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt @@ -64,7 +64,6 @@ class UserHomeFragment : ToolbarFragment() { private var mBadgeCount = 0 private var mPlayGameCount = 0 private var mFragmentList = listOf() - private var mTimerDisposable: Disposable? = null override fun getLayoutId() = 0 override fun getInflatedLayout() = @@ -665,47 +664,11 @@ class UserHomeFragment : ToolbarFragment() { } } - setUserNameLongClick() - } - } - - @SuppressLint("ClickableViewAccessibility") - private fun setUserNameLongClick() { - mHomeBinding?.userName?.setOnTouchListener(object : View.OnTouchListener { - - private val TOUCH_MAX = 50 - private var mLastMotionX = 0 - private var mLastMotionY = 0 - - override fun onTouch(v: View, event: MotionEvent): Boolean { - val x = event.x.toInt() - val y = event.y.toInt() - when (event.action) { - MotionEvent.ACTION_DOWN -> { - mTimerDisposable?.dispose() - mLastMotionX = x - mLastMotionY = y - mTimerDisposable = countDownTimer(3) { finish, _ -> - if (finish) { - mHomeBinding?.userName?.text?.toString()?.copyTextAndToast("用户昵称已复制~") - - } - } - } - MotionEvent.ACTION_MOVE -> { - if (abs(mLastMotionX - x) > TOUCH_MAX || abs(mLastMotionY - y) > TOUCH_MAX) { - // 移动超过阈值,判断为不是长按,取消任务 - mTimerDisposable?.dispose() - } - } - else -> { - mTimerDisposable?.dispose() - } - } - return true + userName.setOnLongClickListener { + userName.text.toString().copyTextAndToast("用户昵称已复制~") + return@setOnLongClickListener true } - - }) + } } override fun onClick(v: View) { @@ -804,14 +767,6 @@ class UserHomeFragment : ToolbarFragment() { return super.onBackPressed() } - override fun onDestroy() { - super.onDestroy() - if (mTimerDisposable != null && !mTimerDisposable!!.isDisposed) { - mTimerDisposable!!.dispose() - mTimerDisposable = null - } - } - companion object { const val LOCATION = "个人主页" } From abd854ac3ba97686a784e4bcab6215d5412c6361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Tue, 19 Jul 2022 15:03:34 +0800 Subject: [PATCH 115/217] =?UTF-8?q?fix:=20=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E7=AB=AF=E5=86=85=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E9=80=82=E9=85=8D=E7=9F=AD=E9=93=BE=E6=8E=A5(0718?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=8F=8D=E9=A6=88)=20https://git.shanqu.cc/p?= =?UTF-8?q?m/halo/halo-app-issues/-/issues/1945?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/comment/ArticleDetailCommentViewModel.kt | 2 +- .../gh/gamecenter/qa/comment/NewCommentViewModel.kt | 2 +- .../conversation/CommentConversationViewModel.kt | 2 +- .../gh/gamecenter/retrofit/service/ApiService.java | 12 +++++------- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/qa/article/detail/comment/ArticleDetailCommentViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/article/detail/comment/ArticleDetailCommentViewModel.kt index 7d04485fbb..e8cc4ef967 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/article/detail/comment/ArticleDetailCommentViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/article/detail/comment/ArticleDetailCommentViewModel.kt @@ -37,7 +37,7 @@ class ArticleDetailCommentViewModel(application: Application, @SuppressLint("CheckResult") fun getComment() { RetrofitManager.getInstance().api - .getCommunityArticleComment(articleId, commentId) + .getCommunityArticleComment(commentId) .subscribeOn(Schedulers.io()) .subscribe(object : BiResponse() { @SuppressLint("CheckResult") diff --git a/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt index 73fc4b3c36..8970e221f2 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt @@ -67,7 +67,7 @@ open class NewCommentViewModel( CommentType.ANSWER_CONVERSATION -> api.getAnswerCommentConversationList(answerId, commentId, page) CommentType.COMMUNITY_ARTICLE -> api.getCommunityArticleCommentList(articleId, "time.create:1", page, mapOf()) - CommentType.COMMUNITY_ARTICLE_CONVERSATION -> api.getCommunityArticleCommentConversation(articleId, commentId, page) + CommentType.COMMUNITY_ARTICLE_CONVERSATION -> api.getCommunityArticleCommentConversation(commentId, page) CommentType.VIDEO -> api.getVideoCommentList(videoId, page, mapOf()) CommentType.VIDEO_CONVERSATION -> api.getVideoCommentConversationList(videoId, commentId, page) diff --git a/app/src/main/java/com/gh/gamecenter/qa/comment/conversation/CommentConversationViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/comment/conversation/CommentConversationViewModel.kt index 2e23e4a8b4..7993a1a3d3 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/comment/conversation/CommentConversationViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/comment/conversation/CommentConversationViewModel.kt @@ -59,7 +59,7 @@ class CommentConversationViewModel( fun getComment() { val single = when { articleId.isNotEmpty() -> { - mApi.getCommunityArticleComment(articleId, commentId) + mApi.getCommunityArticleComment(commentId) } videoId.isNotEmpty() -> { mApi.getCommunityVideoComment(videoId, commentId) diff --git a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java index 837353b573..3517a32422 100644 --- a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java +++ b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java @@ -1482,17 +1482,15 @@ public interface ApiService { /** * 获取社区文章评论的对话列表. */ - @GET("communities/articles/{article_id}/comments/{comment_id}/trace") - Observable> getCommunityArticleCommentConversation(@Path("article_id") String articleId, - @Path("comment_id") String commentId, + @GET("communities/articles/comments/{comment_id}/trace") + Observable> getCommunityArticleCommentConversation(@Path("comment_id") String commentId, @Query("page") int page); /** * 获取单条社区文章评论 */ - @GET("communities/articles/{article_id}/comments/{comment_id}") - Single getCommunityArticleComment(@Path("article_id") String articleId, - @Path("comment_id") String commentId); + @GET("communities/articles/comments/{comment_id}") + Single getCommunityArticleComment(@Path("comment_id") String commentId); /** * 获取社区文章评论回复 @@ -1722,7 +1720,7 @@ public interface ApiService { /** * 加精社区文章 */ - @POST("communities/articles/{article_id}:choiceness") + @POST("communities/articles/{article_id}:moderator_choiceness") Observable highlightCommunityArticle(@Path("article_id") String articleId); /** From 7786a1b2a6770937acd5ab30a718038b73896331 Mon Sep 17 00:00:00 2001 From: lyr Date: Tue, 19 Jul 2022 16:56:40 +0800 Subject: [PATCH 116/217] =?UTF-8?q?feat:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8Bv5.12.0=E3=80=91=E5=89=8D=E7=AB=AF=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=B1=87=E6=80=BB7=E6=9C=88=E7=AC=AC3=E5=91=A8?= =?UTF-8?q?=EF=BC=886=EF=BC=89https://git.shanqu.cc/pm/halo/halo-app-issue?= =?UTF-8?q?s/-/issues/1976?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../search/SearchGameResultFragment.kt | 9 ++++- .../search/SearchGameResultViewModel.kt | 40 ++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/search/SearchGameResultFragment.kt b/app/src/main/java/com/gh/gamecenter/search/SearchGameResultFragment.kt index 0f28b5fc91..2ccb8acb81 100644 --- a/app/src/main/java/com/gh/gamecenter/search/SearchGameResultFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/search/SearchGameResultFragment.kt @@ -123,6 +123,13 @@ class SearchGameResultFragment : ListFragment -DisplayUtils.dip2px(50F) && mAdapter?.isLoadOver() == true) { + return + } + } mBinding.containerMenuOpen.visibility = View.VISIBLE mBinding.seekGameBtn.visibility = View.VISIBLE mBinding.seekFunctionBtn.visibility = View.VISIBLE @@ -134,7 +141,7 @@ class SearchGameResultFragment : ListFragment -DisplayUtils.dip2px(50f) && mAdapter?.isLoadOver() == true) { + if (child != null && recyclerView.bottom - child.bottom > -DisplayUtils.dip2px(50F) && mAdapter?.isLoadOver() == true) { mBinding.containerMenuClose.visibility = View.GONE } else { mBinding.containerMenuClose.visibility = View.VISIBLE diff --git a/app/src/main/java/com/gh/gamecenter/search/SearchGameResultViewModel.kt b/app/src/main/java/com/gh/gamecenter/search/SearchGameResultViewModel.kt index 968a073975..d0cb654afd 100644 --- a/app/src/main/java/com/gh/gamecenter/search/SearchGameResultViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/search/SearchGameResultViewModel.kt @@ -5,6 +5,8 @@ import android.app.Application import com.gh.common.constant.Config import com.gh.gamecenter.BuildConfig import com.gh.gamecenter.baselist.ListViewModel +import com.gh.gamecenter.baselist.LoadParams +import com.gh.gamecenter.baselist.LoadStatus import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.entity.SearchSubjectEntity import com.gh.gamecenter.retrofit.RetrofitManager @@ -33,18 +35,54 @@ class SearchGameResultViewModel(application: Application) : ListViewModel 0) it.location - 1 else 0, + if (it.location <= 0 || it.location >= itemDataList.size) 0 else it.location - 1, SearchItemData(subject = it) ) } + // 处理初始化列表且游戏列表size为0的情况 + if (mPage == 1 && list.isEmpty()) { + mLoadStatusLiveData.value = if (itemDataList.isEmpty()) LoadStatus.INIT_EMPTY else LoadStatus.INIT_OVER + } mResultLiveData.postValue(itemDataList) }, { it.printStackTrace() + if (mPage == 1 && list.isEmpty()) { + mLoadStatusLiveData.value = if (itemDataList.isEmpty()) LoadStatus.INIT_EMPTY else LoadStatus.INIT_OVER + } mResultLiveData.postValue(itemDataList) }) } } + override fun loadStatusControl(size: Int) { + if (mCurLoadParams.loadOffset == LoadParams.DEFAULT_OFFSET) { // 初始化列表 + if (size == 0) { +// 初始化列表size为0情况放到mergeResultLiveData方法处理 + } else if (size == REQUEST_FAILURE_SIZE) { + mLoadStatusLiveData.setValue(LoadStatus.INIT_FAILED) + } else if (size < mOverLimitSize) { // 避免一个屏幕出现两次分页 + mLoadStatusLiveData.setValue(LoadStatus.INIT_OVER) + } else { + mLoadStatusLiveData.setValue(LoadStatus.INIT_OVER) + } + } else { + if (size == REQUEST_FAILURE_SIZE) { + mLoadStatusLiveData.setValue(LoadStatus.LIST_FAILED) + } else if (size == 0) { + mLoadStatusLiveData.setValue(LoadStatus.LIST_OVER) + } else { + mLoadStatusLiveData.setValue(LoadStatus.LIST_LOADED) + } + } + + if (size == REQUEST_FAILURE_SIZE) { + mRetryParams = mCurLoadParams + } else { + mRetryParams = null + mCurLoadParams.setLoadOffset(mCurLoadParams.getLoadOffset() + 1) // 页数 + 1 + } + } + override fun provideDataObservable(page: Int): Observable> { // 可能会有特殊字符,需要 encode 处理 val encodedKey = URLEncoder.encode(key, "utf-8") From 75e032b1f99496d99bb9871abc46895636c85a39 Mon Sep 17 00:00:00 2001 From: leafwai Date: Wed, 20 Jul 2022 15:12:08 +0800 Subject: [PATCH 117/217] =?UTF-8?q?feat:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8Bv5.12.0=E3=80=91=E5=89=8D=E7=AB=AF=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=B1=87=E6=80=BB7=E6=9C=88=E7=AC=AC3=E5=91=A8?= =?UTF-8?q?=EF=BC=887=EF=BC=89https://git.shanqu.cc/pm/halo/halo-app-issue?= =?UTF-8?q?s/-/issues/1976?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/gamecenter/gamedetail/desc/DescViewModel.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescViewModel.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescViewModel.kt index 4381d820e7..e9c4784768 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescViewModel.kt @@ -31,6 +31,7 @@ import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody +import org.json.JSONObject import retrofit2.HttpException class DescViewModel(application: Application, @@ -215,6 +216,16 @@ class DescViewModel(application: Application, super.onResponse(response) ToastUtils.showToast("感谢您的反馈信息,我们将尽快处理~") } + + override fun onFailure(e: HttpException?) { + super.onFailure(e) + e?.response()?.errorBody()?.let { + val content = JSONObject(it.string()) + if (content.getInt("code") == 403208) { + ToastUtils.showToast("您已经提交过反馈信息,我们将尽快处理~") + } + } + } }) } From 8af97a44c8864f18d3c962fe24919a07caee98cf Mon Sep 17 00:00:00 2001 From: lyr Date: Wed, 20 Jul 2022 18:07:16 +0800 Subject: [PATCH 118/217] =?UTF-8?q?feat:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=90=9C=E7=B4=A2=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96=EF=BC=88=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E9=83=A8=E5=88=86=201=EF=BC=89https://git.shanqu.cc/p?= =?UTF-8?q?m/halo/halo-app-issues/-/issues/1951?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/gamecenter/entity/SettingsEntity.kt | 2 +- .../gamecenter/search/SearchDefaultHotAdapter.kt | 10 ++-------- .../main/res/drawable-xxhdpi/ic_search_hot.png | Bin 2904 -> 0 bytes .../main/res/drawable-xxhdpi/ic_search_new.png | Bin 2152 -> 0 bytes .../main/res/drawable-xxhdpi/ic_search_surge.png | Bin 2319 -> 0 bytes .../main/res/drawable-xxxhdpi/ic_search_hot.png | Bin 3926 -> 0 bytes .../main/res/drawable-xxxhdpi/ic_search_hot.webp | Bin 0 -> 1290 bytes .../main/res/drawable-xxxhdpi/ic_search_new.png | Bin 3000 -> 0 bytes .../main/res/drawable-xxxhdpi/ic_search_new.webp | Bin 0 -> 1290 bytes .../res/drawable-xxxhdpi/ic_search_rise.webp | Bin 0 -> 1148 bytes .../res/drawable-xxxhdpi/ic_search_surge.png | Bin 3189 -> 0 bytes .../res/drawable-xxxhdpi/ic_search_update.webp | Bin 0 -> 1182 bytes .../main/res/layout/search_default_hot_item.xml | 3 ++- 13 files changed, 5 insertions(+), 10 deletions(-) delete mode 100755 app/src/main/res/drawable-xxhdpi/ic_search_hot.png delete mode 100755 app/src/main/res/drawable-xxhdpi/ic_search_new.png delete mode 100755 app/src/main/res/drawable-xxhdpi/ic_search_surge.png delete mode 100755 app/src/main/res/drawable-xxxhdpi/ic_search_hot.png create mode 100755 app/src/main/res/drawable-xxxhdpi/ic_search_hot.webp delete mode 100755 app/src/main/res/drawable-xxxhdpi/ic_search_new.png create mode 100755 app/src/main/res/drawable-xxxhdpi/ic_search_new.webp create mode 100755 app/src/main/res/drawable-xxxhdpi/ic_search_rise.webp delete mode 100755 app/src/main/res/drawable-xxxhdpi/ic_search_surge.png create mode 100755 app/src/main/res/drawable-xxxhdpi/ic_search_update.webp diff --git a/app/src/main/java/com/gh/gamecenter/entity/SettingsEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/SettingsEntity.kt index 0195e44f3f..a8e8a55ee1 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/SettingsEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/SettingsEntity.kt @@ -180,7 +180,7 @@ data class SettingsEntity( @SerializedName("icon_subscript") var iconSubscript: String? = null, @SerializedName("recommend_type") - var recommendType: String? = "none",//none:无、hot: 热门、new: 上新、surge: 飙升 + var recommendType: String? = "none",//none:无、hot: 热门、new: 上新、surge: 飙升、update: 更新 var type: String? = ""//论坛类型 ) { var exposureEvent: ExposureEvent? = null diff --git a/app/src/main/java/com/gh/gamecenter/search/SearchDefaultHotAdapter.kt b/app/src/main/java/com/gh/gamecenter/search/SearchDefaultHotAdapter.kt index 51ba8e32c6..a07cc54971 100644 --- a/app/src/main/java/com/gh/gamecenter/search/SearchDefaultHotAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/search/SearchDefaultHotAdapter.kt @@ -43,17 +43,11 @@ class SearchDefaultHotAdapter( val drawableId = mContext.resources.getIdentifier(drawableRes, "drawable", mContext.packageName) index.setImageDrawable(drawableId.toDrawable()) } - val textColor = when (position) { - 0 -> R.color.text_ff5151.toColor(mContext) - 1 -> R.color.text_F67722.toColor(mContext) - 2 -> R.color.text_ffbf00.toColor(mContext) - else -> R.color.text_title.toColor(mContext) - } - name.setTextColor(textColor) val labelIcon = when (hotSearch.recommendType) { "hot" -> R.drawable.ic_search_hot "new" -> R.drawable.ic_search_new - "surge", "rise" -> R.drawable.ic_search_surge + "surge", "rise" -> R.drawable.ic_search_rise + "update" -> R.drawable.ic_search_update else -> -1 } if (labelIcon != -1) { diff --git a/app/src/main/res/drawable-xxhdpi/ic_search_hot.png b/app/src/main/res/drawable-xxhdpi/ic_search_hot.png deleted file mode 100755 index 6b61320008785c843fdc703ff543df18dcacfcbe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2904 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 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_search_hot.webp b/app/src/main/res/drawable-xxxhdpi/ic_search_hot.webp new file mode 100755 index 0000000000000000000000000000000000000000..c7f93bdfd1dcd92415f9d49271fe8241314763bb GIT binary patch literal 1290 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 j-JahUH~;%z{yTj;?;ic9;`e^OJLjw2r literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_search_rise.webp b/app/src/main/res/drawable-xxxhdpi/ic_search_rise.webp new file mode 100755 index 0000000000000000000000000000000000000000..33b2f87e0d3648a73fbabd7cd05b84a881a855bf GIT binary patch literal 1148 zcmWIYbaN|VVPFV%bqWXzu!!JdU|=u+VskL^baoDqU;=U(m?S_X3s5RIucRo*-AN%L zGD-m?1_O!7#RV`n7MhWP;oCI^Aj!aRSr>~uAtBC`)Z%2Iq7Oh^QUtV|fq^jv$QDV5 zuq#09BnZ0)#4ZX6at5kd0Ay>VBe9c^*ySY!B|tSNKIgA?khp~qQ(3^k zz~92auHONbIsmN;1 zJhR!cJ(^2D|9t!S@tHsu7Z-4 zJN^Fs`|V0U=3TN|*U@!s)vqT!O|R!1(@g*PzTnY&%Y*W@E?sTR|B9N{cO6^4>FEXi zU;m?T7QGPvt8r?Y^ZqCOTf24tHY))^TgMiqS*w>ZO_eT7H4(@S-g6~6T(slX-?sHr zyIz$~zmntf&~v}^dQCNUYp&W)u0|oNb3?wD@=QCw!fLsv<%@Gy16L&75en1f+OM}l zc*nPWQ(sKcUH(s=H|OfN-W`THlBd?4*>`KzQsvy$+wzzAq(`$~Y)`xS$#c>~OrXrRpMN)Z~R5TAGiH~TN#>6E87Putr14V(|W$&bVrhDdePtRpdQn~-Y&YkH# z=j-o$=j)!U_#b?t<#Pwn-8~6`g9&o63`c$3#nE{AaEj)xhyXH~uxs@^l z6XZ%6(lV%Ea9+?(qB>v!mSv2yx zNxWzxNppFh3|=PcgCZ#$NH_+~AIqCFR8symrCNFgK(u`BNDg#9M^rv7UK9saF|hB{>nVQVY5;svP3!Fu1t&kB)B z1=Lr3ZE94Ig>{r04Dh-Y^i0f%R@SyAixaS`f^E2^_BqmthCqs04ta{Yxm-KklQB;PpoQ>^*@M^xI=4PoRU$QQHG6Cx|xb3L)HP*<;W<#MbZpd)WfAP*~4j6NQw)@Q@6xF0&&gg6D- zl?^;CgOaJ~gOs2n(pLNe-N=leG9Y$%yLWCzso`T&2kkY}JJyLE@c3#h1}{_Ch{gL9BkxSy87S$1ZcTw-M6wYXDY2G^gU; zzR0yrnUygh24HfIhvg4q3HX$-I?62nIxyw!x&Qn7Jv|)V*swrLTxe(us+PM&qU{{hMMt(#%%`Z6HdvV|KrQB zZ=b6mG(JmI2`A@vte@Po>_Je zeDtyF#Vz8sbuIu627uf=!VcTk_3caH^i%Vz|G|gQv?}2G{KYJ2?a8A5A_Kth-wv&8 z-H5?%TmUskCV}m2frp!f`x14g$F1`i(9oC}A$@CbhM99gn;ZSn0W~dx zk3R~(*VDm_se>6p1AG9aY0+aIc_hr90f&p@34MKkC;adkc>6umZG>JOOiwH$vbpv$ zaKI21ExN%-h3TE4^8jlos{6r=n_&1z(b9egKYQM7fBs%TGhl{fz_O$SLRvGlAbG9$ z8(x52dJkdV_V~bA=jwDYr|rpC^UtYA7hIyEMK>k@NCacFB&8G#8wuaI0)`%yCI8_L zSp6UzFoz(%{j`6_0Em*&3~1|c-}hTEZl4D=#&c+Ipf@*velxMVMeQz*-)cZ0;oNTu zbbh6))VlePB>*@g6zHF4o(o^Oz}=U3cEZXP(AFw`{17lxRs^q+04#%64S@GbOeZ+* zMCd8QKX*af?tH6E#oF@}aeus+g(o~c+fOm$WnNn4Cr&@E{ zqWH<^KFxrD*!lJOg)hN{m%>|bz=mhcZqDnu(sup_0PZy<;2;-z|EA#BF|g$yqHjy|JrHGZg9d><+q19G zUwa+)>HWI5@rgHKqL!tY`udWBEkX3&V>q47+*eZ9skQT0+to+_(3ExBh#uWjT4|K5 z+Ezk37_iSYx$QPC(1KvQQTl#A@XAcKwxXZW$c0e6##igkP?ufSBLKK5D}mk&Ql#{i z=ors-kdxY+5PO?4=Xqh7i-2}Y*igT^|L4^s^PE!~72P8M@K-r+9>R+6sCht79FY|( z9qc~dxn0rO-ob=ZdI6>OQ^h%I^#Z+Jbv`OucynfiY(NqSS!=#O$e|z50pFp8%#UP< z14@NcDt{cwKqr1(;Z;-B+S{J=lTSo21|YPb_I_Y!fsm`|GbCPI(*n}~1zkh$_d~8N z)`0-c6BW-3r4y55;Pz9BW~#Nf2a`_#xclZP>%+ZlL2+_IBpm>KvGO`fPPhX45Y!WU zUx9G??A7hA#3doxOD3pj;hZS@(NaMDE2_EI#vCth+gZUcxI%4Avc|F{#4;I^Ws7EB zT5h~Xp8*&9f)_4$Q! z>$X8jTmLorK~0Cy5a(1$p34aq`GEQ6B^jd&RoX*O)PX8(CgN{Ym0qNO|6i#U^Yq#J bfA#q{mdPdgSs@fN00000NkvXXu0mjfsf`xw diff --git a/app/src/main/res/drawable-xxxhdpi/ic_search_update.webp b/app/src/main/res/drawable-xxxhdpi/ic_search_update.webp new file mode 100755 index 0000000000000000000000000000000000000000..41cb71d47e0f799f8e780b202c2acbcbf8cbdda1 GIT binary patch literal 1182 zcmWIYbaR`=!oU#j>J$(bU=hK^z`$St#O7e+>FgXJ!35+oFiC(&7NAsaUP)1qyOTmh zWRwC(34~0|Rd)1B37d1_rKZm_reI5pjXTuL?jtGC+Uk z17SKt4nrz~0)r<*9z!yN9*|`OOeBU3X22BV69G&g`sN3C1*R|Dk$c;tY~8#45!YX? zj%+Txy{+-dzF({M{GYP@z(KCt+j6HQF8*(S!9TeEMDRuH8o&Ci<^>&#zI$d5!F9E3L+X_5yBgmwU{;r za4cd{opNCjlSiM5=A@#unHQ@ivMaZ-OHcVP4u%PfUz$CM+2e5TQ&s94DTVdLcfTsu@62+aaqUd6 zy3+Q5MK&iir)V~x4%(3^5v)<8*{Ti;QXF(c(DkpYSD}K>8E+;Bx+>r7yBJpae((2t z)$jiv%rV+A^?gN;+v1BECQ`j_izmLnrMP42F7Jh}_Dg-7@A5|_VHU^qhM7;@pNNTZ z-nh|jC)0OOH)5OW1Ldi?nt#mFqt}MDUl98?Emu=ma-GF2L~X`656n9V+$wkLY^r<88<)1tc%gvZbFGfSy;ghjPL-&@x98s@B`^1JSWe%%>C7S}`MkEfKUo04C}iIN literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/search_default_hot_item.xml b/app/src/main/res/layout/search_default_hot_item.xml index 702d6893e4..955cd63e9b 100644 --- a/app/src/main/res/layout/search_default_hot_item.xml +++ b/app/src/main/res/layout/search_default_hot_item.xml @@ -33,6 +33,7 @@ android:ellipsize="end" android:maxLines="1" android:textSize="12sp" + android:textColor="@color/text_title" app:layout_constrainedWidth="true" app:layout_constraintBottom_toBottomOf="@+id/icon" app:layout_constraintEnd_toStartOf="@+id/labelIv" @@ -46,7 +47,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="4dp" - android:layout_marginRight="4dp" + android:layout_marginRight="12dp" app:layout_constraintBottom_toBottomOf="@+id/name" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/name" From 563d9123c8dda27acb42dc7a72fe313681398988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Wed, 20 Jul 2022 19:44:34 +0800 Subject: [PATCH 119/217] =?UTF-8?q?fix:=20=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E7=AB=AF=E5=86=85=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E9=80=82=E9=85=8D=E7=9F=AD=E9=93=BE=E6=8E=A5(0720?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=8F=8D=E9=A6=88)=20https://git.shanqu.cc/p?= =?UTF-8?q?m/halo/halo-app-issues/-/issues/1945?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/util/PostCommentUtils.java | 4 ++-- .../qa/comment/NewCommentViewModel.kt | 2 +- .../qa/comment/base/BaseCommentViewModel.kt | 6 ++--- .../CommentConversationViewModel.kt | 2 +- .../video/detail/ForumVideoDetailFragment.kt | 7 ++---- .../video/detail/ForumVideoDetailViewModel.kt | 8 +++---- .../retrofit/service/ApiService.java | 24 +++++++++---------- 7 files changed, 25 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/PostCommentUtils.java b/app/src/main/java/com/gh/common/util/PostCommentUtils.java index ac8a944976..c4f4383381 100644 --- a/app/src/main/java/com/gh/common/util/PostCommentUtils.java +++ b/app/src/main/java/com/gh/common/util/PostCommentUtils.java @@ -123,7 +123,7 @@ public class PostCommentUtils { if (!TextUtils.isEmpty(answerId)) { observable = RetrofitManager.getInstance().getApi().postVoteAnswerComment(answerId, commentId); - } else if (!TextUtils.isEmpty(commentId)) { + } else if (!TextUtils.isEmpty(articleId)) { observable = RetrofitManager.getInstance().getApi().postVoteCommunityArticleComment(commentId); } else if (!TextUtils.isEmpty(questionId)) { observable = RetrofitManager.getInstance().getApi().postVoteQuestionComment(questionId, commentId); @@ -161,7 +161,7 @@ public class PostCommentUtils { if (!TextUtils.isEmpty(questionId)) { observable = RetrofitManager.getInstance().getApi().postUnVoteQuestionComment(questionId, commentId); - } else if (!TextUtils.isEmpty(commentId)) { + } else if (!TextUtils.isEmpty(articleId)) { observable = RetrofitManager.getInstance().getApi().postUnVoteArticleComment(commentId); } else { observable = RetrofitManager.getInstance().getApi().postUnVoteVideoComment(videoId, commentId); diff --git a/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt index 8970e221f2..a19d1766ec 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentViewModel.kt @@ -317,7 +317,7 @@ open class NewCommentViewModel( @SuppressLint("CheckResult") fun deleteVideoComment(entity: CommentEntity) { RetrofitManager.getInstance().api - .deleteVideoComment(videoId, entity.id) + .deleteVideoComment(entity.id) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(object : BiResponse() { diff --git a/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt index 2c7e390003..62b3a1096e 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt @@ -255,7 +255,7 @@ abstract class BaseCommentViewModel( if (entity.me?.isModerator == true) { mApi.moderatorsHideVideoComment(communityId, videoId, entity.id).toObservable() } else { - mApi.deleteVideoComment(videoId, entity.id).toObservable() + mApi.deleteVideoComment(entity.id).toObservable() } } questionId.isNotEmpty() -> { @@ -311,7 +311,7 @@ abstract class BaseCommentViewModel( mApi.postQuestionCommentTop(questionId, commentId, map) } videoId.isNotEmpty() -> { - mApi.postVideoCommentTop(videoId, commentId, map) + mApi.postVideoCommentTop(commentId, map) } else -> null } @@ -324,7 +324,7 @@ abstract class BaseCommentViewModel( mApi.postQuestionCommentUnTop(questionId, commentId) } videoId.isNotEmpty() -> { - mApi.postVideoCommentUnTop(videoId, commentId) + mApi.postVideoCommentUnTop(commentId) } else -> null } diff --git a/app/src/main/java/com/gh/gamecenter/qa/comment/conversation/CommentConversationViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/comment/conversation/CommentConversationViewModel.kt index 7993a1a3d3..a273a670f6 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/comment/conversation/CommentConversationViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/comment/conversation/CommentConversationViewModel.kt @@ -62,7 +62,7 @@ class CommentConversationViewModel( mApi.getCommunityArticleComment(commentId) } videoId.isNotEmpty() -> { - mApi.getCommunityVideoComment(videoId, commentId) + mApi.getCommunityVideoComment(commentId) } questionId.isNotEmpty() -> { mApi.getCommunityQuestionComment(questionId, commentId) diff --git a/app/src/main/java/com/gh/gamecenter/qa/video/detail/ForumVideoDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/video/detail/ForumVideoDetailFragment.kt index d3293b1f98..b8b614ac3b 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/video/detail/ForumVideoDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/video/detail/ForumVideoDetailFragment.kt @@ -696,12 +696,9 @@ class ForumVideoDetailFragment : BaseFragment_TabLayout() { "取消", { if (isHighlight) { - mViewModel.doHighlightThisVideo(mForumVideoEntity?.bbsId ?: "", mVideoId) + mViewModel.doHighlightThisVideo(mVideoId) } else { - mViewModel.cancelHighlightThisVideo( - mForumVideoEntity?.bbsId - ?: "", mVideoId - ) + mViewModel.cancelHighlightThisVideo(mVideoId) } }, extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true) ) diff --git a/app/src/main/java/com/gh/gamecenter/qa/video/detail/ForumVideoDetailViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/video/detail/ForumVideoDetailViewModel.kt index dd739ed0d5..5447a94053 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/video/detail/ForumVideoDetailViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/video/detail/ForumVideoDetailViewModel.kt @@ -103,8 +103,8 @@ class ForumVideoDetailViewModel( //版主加精 - fun doHighlightThisVideo(bbsId: String, videoId: String) { - mApi.highlightCommunityVideo(bbsId, videoId) + fun doHighlightThisVideo(videoId: String) { + mApi.highlightCommunityVideo(videoId) .compose(observableToMain()) .subscribe(object : Response() { override fun onResponse(response: ResponseBody?) { @@ -120,8 +120,8 @@ class ForumVideoDetailViewModel( } //版主取消精选 - fun cancelHighlightThisVideo(bbsId: String, videoId: String) { - mApi.cancelHighlightCommunityVideo(bbsId, videoId) + fun cancelHighlightThisVideo(videoId: String) { + mApi.cancelHighlightCommunityVideo(videoId) .compose(observableToMain()) .subscribe(object : Response() { override fun onResponse(response: ResponseBody?) { diff --git a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java index 3517a32422..7f2c419d3e 100644 --- a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java +++ b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java @@ -2532,8 +2532,8 @@ public interface ApiService { /** * 删除视频评论 */ - @POST("videos/{video_id}/comments/{comment_id}:inactivate") - Single deleteVideoComment(@Path("video_id") String videoId, @Path("comment_id") String commentId); + @POST("videos/comments/{comment_id}:inactivate") + Single deleteVideoComment(@Path("comment_id") String commentId); /** * 版主删除视频评论 @@ -3154,8 +3154,8 @@ public interface ApiService { /** * 获取单条视频评论 */ - @GET("videos/{video_id}/comments/{comment_id}") - Single getCommunityVideoComment(@Path("video_id") String videoId, @Path("comment_id") String commentId); + @GET("videos/comments/{comment_id}") + Single getCommunityVideoComment(@Path("comment_id") String commentId); /** * 获取视频评论回复 @@ -3170,14 +3170,14 @@ public interface ApiService { /** * 加精视频贴 */ - @POST("bbses/{bbs_id}/videos/{video_id}:choiceness") - Observable highlightCommunityVideo(@Path("bbs_id") String bbsId, @Path("video_id") String videoId); + @POST("bbses/videos/{video_id}:moderator_choiceness") + Observable highlightCommunityVideo(@Path("video_id") String videoId); /** * 取消加精视频贴 */ - @POST("bbses/{bbs_id}/videos/{video_id}:cancel_choiceness") - Observable cancelHighlightCommunityVideo(@Path("bbs_id") String bbsId, @Path("video_id") String videoId); + @POST("bbses/videos/{video_id}:cancel_choiceness") + Observable cancelHighlightCommunityVideo(@Path("video_id") String videoId); /** * 申请加精视频贴 @@ -3516,14 +3516,14 @@ public interface ApiService { /** * 置顶视频评论 */ - @POST("videos/{video_id}/comments/{comment_id}:set-top") - Observable postVideoCommentTop(@Path("video_id") String videoId, @Path("comment_id") String commentId, @QueryMap Map params); + @POST("videos/comments/{comment_id}:set-top") + Observable postVideoCommentTop(@Path("comment_id") String commentId, @QueryMap Map params); /** * 取消视频置顶评论 */ - @POST("videos/{video_id}/comments/{comment_id}:unset-top") - Observable postVideoCommentUnTop(@Path("video_id") String videoId, @Path("comment_id") String commentId); + @POST("videos/comments/{comment_id}:unset-top") + Observable postVideoCommentUnTop(@Path("comment_id") String commentId); /** * 求版本上传apk后回调 From 74fda1fc17e14ce4b2103dfa048e1df4ba94ffcf Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 21 Jul 2022 16:18:43 +0800 Subject: [PATCH 120/217] =?UTF-8?q?feat:=20ToastUtils=20=E7=9A=84=20toast?= =?UTF-8?q?=20=E9=BB=98=E8=AE=A4=E5=88=87=E6=8D=A2=E5=88=B0=E4=B8=BB?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B=E6=89=A7=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/gh/gamecenter/core/utils/ToastUtils.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/module_core/src/main/java/com/gh/gamecenter/core/utils/ToastUtils.kt b/module_core/src/main/java/com/gh/gamecenter/core/utils/ToastUtils.kt index 950a243502..d7d2da3cd3 100644 --- a/module_core/src/main/java/com/gh/gamecenter/core/utils/ToastUtils.kt +++ b/module_core/src/main/java/com/gh/gamecenter/core/utils/ToastUtils.kt @@ -1,6 +1,7 @@ package com.gh.gamecenter.core.utils import com.gh.gamecenter.core.HaloApp +import com.gh.gamecenter.core.runOnUiThread import com.lightgame.utils.toast.ToastHelper object ToastUtils { @@ -12,12 +13,16 @@ object ToastUtils { @JvmStatic fun showToast(message: String) { - ToastHelper.showToast(HaloApp.getInstance(), message) + runOnUiThread { + ToastHelper.showToast(HaloApp.getInstance(), message) + } } @JvmStatic fun showToast(message: String, gravity: Int = -1, yOffset: Int = 0) { - ToastHelper.showToast(HaloApp.getInstance(), message, gravity, yOffset) + runOnUiThread { + ToastHelper.showToast(HaloApp.getInstance(), message, gravity, yOffset) + } } } From 16614ac2d133fdb7adaca4afb176a7cdaaebaf7f Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 21 Jul 2022 16:22:42 +0800 Subject: [PATCH 121/217] =?UTF-8?q?feat:=20=E6=9B=B4=E9=A2=91=E7=B9=81?= =?UTF-8?q?=E5=9C=B0=E5=A4=87=E4=BB=BD=E7=95=85=E7=8E=A9=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VHelper.kt | 48 ++++++++++------------ 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 737815c097..8974fc4fbc 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -28,7 +28,6 @@ import com.gh.gamecenter.common.utils.getMetaExtra import com.gh.gamecenter.common.utils.toColor import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.core.runOnIoThread -import com.gh.gamecenter.core.runOnUiThread import com.gh.gamecenter.core.utils.EmptyCallback import com.gh.gamecenter.core.utils.GsonUtils import com.gh.gamecenter.core.utils.SPUtils @@ -375,9 +374,7 @@ object VHelper { ) { Utils.log(LOG_TAG, "尝试安装新应用 ${downloadEntity.path}") - if (showDialogIfVSpaceIsNeeded(context)) { - return - } + if (showDialogIfVSpaceIsNeeded(context)) return val installClosure: () -> Unit = { checkStoragePermissionBeforeAction(context) { @@ -416,9 +413,7 @@ object VHelper { ) ) } else { - runOnUiThread { - ToastUtils.toast("安装出现异常, ${result.status}") - } + ToastUtils.toast("安装出现异常, ${result.status}") } mInstallingVaPathSet.remove(downloadEntity.path) @@ -428,9 +423,7 @@ object VHelper { VBackupHelper.backupDBToExternalStorage(HaloApp.getInstance()) } catch (e: Exception) { - runOnUiThread { - ToastUtils.toast(e.localizedMessage ?: "") - } + ToastUtils.toast(e.localizedMessage ?: "") } } } @@ -462,13 +455,15 @@ object VHelper { } // 检查下载管理是否有下载实体,有实体表明未安装成功 - val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName) + val downloadEntity = DownloadManager.getInstance() + .getDownloadEntitySnapshotByPackageName(packageName) ?: getDownloadEntitySnapshotByPackageName(packageName) if (downloadEntity != null) { val downloadedFile = File(downloadEntity.path) if (downloadedFile.exists() - && downloadedFile.length() == downloadEntity.size) { + && downloadedFile.length() == downloadEntity.size + ) { install(context, downloadEntity, true) } else { // 重新下载 @@ -495,7 +490,10 @@ object VHelper { mLastSuccessfullyLaunchedGame = Pair(System.currentTimeMillis(), packageName) - updateLastPlayedTime(packageName) + runOnIoThread { + updateLastPlayedTime(packageName) + VBackupHelper.backupDBToExternalStorage(HaloApp.getInstance()) + } } catch (e: Exception) { ToastUtils.toast(e.localizedMessage ?: "") } @@ -520,9 +518,7 @@ object VHelper { Utils.log(LOG_TAG, "卸载应用结果 -> $result") } catch (e: Exception) { - runOnUiThread { - ToastUtils.toast(e.localizedMessage ?: "") - } + ToastUtils.toast(e.localizedMessage ?: "") } } @@ -567,18 +563,16 @@ object VHelper { * 更新游戏最后打开的时间 */ private fun updateLastPlayedTime(packageName: String) { - runOnIoThread { - getVGameSnapshot(packageName)?.let { - it.downloadEntity.addMetaExtra( - KEY_LAST_PLAYED_TIME, - System.currentTimeMillis().toString() - ) - mVGameDao.insert(it) - } - - // 更新首页排序 - EventBus.getDefault().post(EBReuse("vgame")) + getVGameSnapshot(packageName)?.let { + it.downloadEntity.addMetaExtra( + KEY_LAST_PLAYED_TIME, + System.currentTimeMillis().toString() + ) + mVGameDao.insert(it) } + + // 更新首页排序 + EventBus.getDefault().post(EBReuse("vgame")) } fun getInstallationLiveData(): LiveData { From 6afe9b2f3c1e58b97d4dc17a6b0e077d693f650f Mon Sep 17 00:00:00 2001 From: guotao Date: Thu, 21 Jul 2022 17:59:45 +0800 Subject: [PATCH 122/217] =?UTF-8?q?feat:=20=E5=B0=86=E5=AE=89=E8=A3=85?= =?UTF-8?q?=E5=A5=BD=E7=9A=84=E7=95=85=E7=8E=A9=E6=B8=B8=E6=88=8F=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=8F=92=E5=85=A5=E5=88=B0=E7=95=85=E7=8E=A9=E5=8A=A9?= =?UTF-8?q?=E6=89=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 4 +++- app/src/main/java/com/gh/vspace/VHelper.kt | 22 +++++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d262639539..76e630ff53 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,7 +2,9 @@ - + + + diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 8974fc4fbc..a0725af71d 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -2,8 +2,10 @@ package com.gh.vspace import android.Manifest import android.annotation.SuppressLint +import android.content.ContentValues import android.content.Context import android.content.Intent +import android.net.Uri import android.text.TextUtils import android.view.View import androidx.annotation.WorkerThread @@ -412,14 +414,16 @@ object VHelper { "unknown" ) ) + insertInstalledGameToProvider(downloadEntity) } else { ToastUtils.toast("安装出现异常, ${result.status}") } + Utils.log(LOG_TAG, "安装新应用结果 -> " + result.status) + mInstallingVaPathSet.remove(downloadEntity.path) mInstallationLiveData.postValue(result.packageName) - Utils.log(LOG_TAG, "安装新应用结果 -> " + result.status) VBackupHelper.backupDBToExternalStorage(HaloApp.getInstance()) } catch (e: Exception) { @@ -436,6 +440,22 @@ object VHelper { } } + fun insertInstalledGameToProvider(downloadEntity: DownloadEntity) { + val values = ContentValues() + val packageName = downloadEntity.packageName + if (packageName.isEmpty()) { + return + } + //主键 + values.put("package_name", packageName) + values.put("url", downloadEntity.url) + values.put("name", downloadEntity.name) + values.put("size", downloadEntity.size) + values.put("meta", GsonUtils.toJson(downloadEntity.meta)) + val uri = Uri.parse("content://com.lg.vspace.provider/download_game") + HaloApp.getInstance().contentResolver.insert(uri, values) + } + /** * 安装或启动应用 */ From 7029c170a4bd5f820f764f866628d243b10db4e3 Mon Sep 17 00:00:00 2001 From: guotao Date: Fri, 22 Jul 2022 11:05:15 +0800 Subject: [PATCH 123/217] =?UTF-8?q?feat:=E6=B8=B8=E6=88=8F=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=8F=92=E5=85=A5=E7=95=85=E7=8E=A9=E5=8A=A9=E6=89=8B?= =?UTF-8?q?ContentProvider=20URI=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VHelper.kt | 25 ++++++++++------------ 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index a0725af71d..1ffbff613b 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -406,6 +406,7 @@ object VHelper { mVGameDao.insert(VGameEntity.from(downloadEntity)) if (result.status == 0) { + insertInstalledGameToProvider(downloadEntity) updateInstalledList() PackageObserver.onPackageChanged( EBPackage( @@ -414,16 +415,14 @@ object VHelper { "unknown" ) ) - insertInstalledGameToProvider(downloadEntity) } else { ToastUtils.toast("安装出现异常, ${result.status}") } - Utils.log(LOG_TAG, "安装新应用结果 -> " + result.status) - mInstallingVaPathSet.remove(downloadEntity.path) mInstallationLiveData.postValue(result.packageName) + Utils.log(LOG_TAG, "安装新应用结果 -> " + result.status) VBackupHelper.backupDBToExternalStorage(HaloApp.getInstance()) } catch (e: Exception) { @@ -439,23 +438,21 @@ object VHelper { connectService(false, installClosure) } } - - fun insertInstalledGameToProvider(downloadEntity: DownloadEntity) { + private fun insertInstalledGameToProvider(downloadEntity: DownloadEntity){ val values = ContentValues() val packageName = downloadEntity.packageName - if (packageName.isEmpty()) { + if (packageName.isEmpty()){ return } //主键 - values.put("package_name", packageName) - values.put("url", downloadEntity.url) - values.put("name", downloadEntity.name) - values.put("size", downloadEntity.size) - values.put("meta", GsonUtils.toJson(downloadEntity.meta)) - val uri = Uri.parse("content://com.lg.vspace.provider/download_game") - HaloApp.getInstance().contentResolver.insert(uri, values) + values.put("package_name",packageName) + values.put("url",downloadEntity.url) + values.put("name",downloadEntity.name) + values.put("size",downloadEntity.size) + values.put("meta",GsonUtils.toJson(downloadEntity.meta)) + val uri = Uri.parse("content://com.lg.core.provider/download_game") + HaloApp.getInstance().contentResolver.insert(uri,values) } - /** * 安装或启动应用 */ From d02bdf9a8ae08a19944868c1ce72ad2edb8adf33 Mon Sep 17 00:00:00 2001 From: leafwai Date: Fri, 22 Jul 2022 11:04:40 +0800 Subject: [PATCH 124/217] =?UTF-8?q?feat:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=96=B0=E5=A2=9E=20?= =?UTF-8?q?=E5=8F=91=E5=B8=83=E5=86=85=E5=AE=B9=E9=9C=80=E5=AE=9E=E5=90=8D?= =?UTF-8?q?=E8=AE=A4=E8=AF=81=20https://git.shanqu.cc/pm/halo/halo-app-iss?= =?UTF-8?q?ues/-/issues/1982?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/common/util/CommentUtils.java | 2 +- .../java/com/gh/common/util/ErrorHelper.kt | 63 +++++++++++++++++-- .../java/com/gh/gamecenter/MainActivity.java | 2 +- .../com/gh/gamecenter/entity/ErrorEntity.kt | 18 +++++- .../publish/GameCollectionEditActivity.kt | 9 ++- .../rating/edit/RatingEditActivity.kt | 6 +- .../message/MessageDetailFragment.java | 3 +- .../qa/article/edit/ArticleEditActivity.kt | 8 ++- .../qa/column/AskColumnRepository.java | 2 +- .../qa/comment/NewCommentFragment.kt | 7 ++- .../qa/questions/edit/QuestionEditActivity.kt | 9 +++ .../qa/tags/AskQuestionsNewRepository.java | 2 +- .../qa/video/publish/VideoPublishFragment.kt | 11 +++- .../comment/CommentDetailFragment.java | 2 +- 14 files changed, 128 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/CommentUtils.java b/app/src/main/java/com/gh/common/util/CommentUtils.java index 93a1721937..6fdfe9e954 100644 --- a/app/src/main/java/com/gh/common/util/CommentUtils.java +++ b/app/src/main/java/com/gh/common/util/CommentUtils.java @@ -420,7 +420,7 @@ public class CommentUtils { commentLikeCountTv.setVisibility(View.VISIBLE); try { if (e != null && e.response().errorBody() != null) { - ErrorHelper.handleError(context, e.response().errorBody().string(), false); + ErrorHelper.handleError(context, e.response().errorBody().string(), false, null); } } catch (IOException ex) { ex.printStackTrace(); diff --git a/app/src/main/java/com/gh/common/util/ErrorHelper.kt b/app/src/main/java/com/gh/common/util/ErrorHelper.kt index 65456ed0f4..9349cded95 100644 --- a/app/src/main/java/com/gh/common/util/ErrorHelper.kt +++ b/app/src/main/java/com/gh/common/util/ErrorHelper.kt @@ -1,13 +1,26 @@ package com.gh.common.util +import android.app.Activity import android.content.Context +import android.content.Intent +import android.view.View +import android.view.ViewGroup +import androidx.appcompat.app.AppCompatActivity import com.gh.common.constant.Config import com.gh.gamecenter.R +import com.gh.gamecenter.ShellActivity import com.gh.gamecenter.WebActivity +import com.gh.gamecenter.common.avoidcallback.AvoidOnResultManager +import com.gh.gamecenter.common.avoidcallback.Callback +import com.gh.gamecenter.common.callback.ConfirmListener import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.utils.DialogHelper +import com.gh.gamecenter.common.utils.dip2px +import com.gh.gamecenter.common.utils.toColor import com.gh.gamecenter.common.utils.toObject import com.gh.gamecenter.entity.ErrorEntity +import com.halo.assistant.fragment.user.UserInfoEditFragment +import com.lightgame.utils.AppManager import com.lightgame.utils.Utils import retrofit2.HttpException @@ -26,6 +39,7 @@ object ErrorHelper { context: Context, errorString: String?, showHighPriorityHint: Boolean = false, + realNameConfirmListener: ConfirmListener? = null, customizedHandler: (code: Int) -> Boolean ) { val errorEntity = errorString?.toObject() @@ -44,14 +58,14 @@ object ErrorHelper { return } - handleError(context, showHighPriorityHint, errorEntity) + handleError(context, showHighPriorityHint, errorEntity, realNameConfirmListener) } /** * [showHighPriorityHint] 用来标识有同样错误码可以触发两种处理时,为 true 时选择重要的 */ @JvmStatic - fun handleError(context: Context, errorString: String?, showHighPriorityHint: Boolean = false) { + fun handleError(context: Context, errorString: String?, showHighPriorityHint: Boolean = false, realNameConfirmListener: ConfirmListener? = null) { val errorEntity = errorString?.toObject() if (errorEntity == null) { @@ -64,7 +78,7 @@ object ErrorHelper { return } - handleError(context, showHighPriorityHint, errorEntity) + handleError(context, showHighPriorityHint, errorEntity, realNameConfirmListener) } /*** @@ -87,7 +101,8 @@ object ErrorHelper { private fun handleError( context: Context, showHighPriorityHint: Boolean = false, - errorEntity: ErrorEntity + errorEntity: ErrorEntity, + realNameConfirmListener: ConfirmListener? = null ) { when (errorEntity.code) { 403050, @@ -163,6 +178,46 @@ object ErrorHelper { 400802 -> { // 多设备登录同一帐号,不需要这里处理 } + + 403209 -> { + DialogHelper.showDialog( + context, + "实名提醒", + errorEntity.data?.title ?: "", + "前往实名认证", "以后再说", + uiModificationCallback = { binding -> + binding.hintTv.visibility = View.VISIBLE + binding.hintTv.layoutParams = (binding.hintTv.layoutParams as ViewGroup.MarginLayoutParams).apply { setMargins(0, 8F.dip2px(), 0, 0) } + binding.lineView.layoutParams = (binding.lineView.layoutParams as ViewGroup.MarginLayoutParams).apply { setMargins(0, 23F.dip2px(), 0, 0) } + binding.hintTv.text = errorEntity.data?.text + binding.hintTv.setTextColor(R.color.theme_font.toColor(context)) + binding.hintTv.setOnClickListener { + errorEntity.data?.toLinkEntity()?.let { entity -> + DirectUtils.directToLinkPage(context, entity, "实名提醒弹窗", "") + } + } + }, + confirmClickCallback = { + val currentActivity = AppManager.getInstance().currentActivity() ?: return@showDialog + AvoidOnResultManager.getInstance(currentActivity as AppCompatActivity) + .startForResult( + ShellActivity.getIntent( + context, + ShellActivity.Type.REAL_NAME_INFO, + ), object : Callback { + override fun onActivityResult(resultCode: Int, data: Intent?) { + if (resultCode == Activity.RESULT_OK && data != null) { + val isAuthSuccess = + data.getBooleanExtra(UserInfoEditFragment.AUTH_SUCCESS, false) + if (isAuthSuccess) { + realNameConfirmListener?.onConfirm() + } + } + } + }) + } + ) + } else -> Utils.toast(context, R.string.post_failure_hint) } } diff --git a/app/src/main/java/com/gh/gamecenter/MainActivity.java b/app/src/main/java/com/gh/gamecenter/MainActivity.java index a223df298c..1f8a847f65 100644 --- a/app/src/main/java/com/gh/gamecenter/MainActivity.java +++ b/app/src/main/java/com/gh/gamecenter/MainActivity.java @@ -665,7 +665,7 @@ public class MainActivity extends BaseActivity { public void onFailure(@Nullable HttpException e) { super.onFailure(e); try { - ErrorHelper.handleErrorWithCustomizedHandler(MainActivity.this, e.response().errorBody().string(), false, new Function1() { + ErrorHelper.handleErrorWithCustomizedHandler(MainActivity.this, e.response().errorBody().string(), false, null, new Function1() { @Override public Boolean invoke(Integer code) { if (code == 404001) { diff --git a/app/src/main/java/com/gh/gamecenter/entity/ErrorEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/ErrorEntity.kt index 82950e6a2f..4ee0c1cd5b 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/ErrorEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/ErrorEntity.kt @@ -24,12 +24,28 @@ data class ErrorEntity(var code: Int? = 0, var answerCount: Int = 0, @SerializedName("follow_count") private var followCount: Int = 0, - val content: String = "" + val content: String = "", + val title: String = "", + val type: String = "", + val link: String = "", + val text: String = "", + @SerializedName("link_community", alternate = ["community"]) + var community: CommunityEntity? = CommunityEntity() ) { // 问题关注数默认是1 fun getFollowCount(): Int { if (followCount > 0) return followCount return 1 } + + fun toLinkEntity(): LinkEntity { + return LinkEntity( + title = title, + link = link, + type = type, + text = text, + community = community + ) + } } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt index 70c43a1e89..d09138edf5 100644 --- a/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt @@ -17,6 +17,7 @@ import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.CropImageActivity import com.gh.gamecenter.R import com.gh.gamecenter.WebActivity +import com.gh.gamecenter.common.callback.ConfirmListener import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.PatternUtils @@ -228,7 +229,13 @@ class GameCollectionEditActivity : ToolBarActivity() { } finish() } else { - ErrorHelper.handleError(this, it.exception?.response()?.errorBody()?.string()) + ErrorHelper.handleError(this, it.exception?.response()?.errorBody()?.string(), false, object : ConfirmListener { + override fun onConfirm() { + if (::mMenuPost.isInitialized) { + onMenuItemClick(mMenuPost) + } + } + }) } } mViewModel.detailLiveData.observe(this) { diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/rating/edit/RatingEditActivity.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/rating/edit/RatingEditActivity.kt index 2ec81b16a8..1a2676c9cb 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/rating/edit/RatingEditActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/rating/edit/RatingEditActivity.kt @@ -348,7 +348,11 @@ class RatingEditActivity : ToolBarActivity(), KeyboardHeightObserver { }, TrackableEntity(event = "游戏评论跳转", key = "意见反馈弹窗") ) } - else -> ErrorHelper.handleError(this@RatingEditActivity, errorString) + else -> ErrorHelper.handleError(this@RatingEditActivity, errorString, false, object : ConfirmListener { + override fun onConfirm() { + postGameComment(again = false) + } + }) } } }) diff --git a/app/src/main/java/com/gh/gamecenter/message/MessageDetailFragment.java b/app/src/main/java/com/gh/gamecenter/message/MessageDetailFragment.java index 77e0f634ee..cba0cf2ac1 100644 --- a/app/src/main/java/com/gh/gamecenter/message/MessageDetailFragment.java +++ b/app/src/main/java/com/gh/gamecenter/message/MessageDetailFragment.java @@ -21,6 +21,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.gh.common.constant.Config; import com.gh.common.util.CheckLoginUtils; import com.gh.common.util.DialogUtils; +import com.gh.gamecenter.common.callback.ConfirmListener; import com.gh.gamecenter.core.utils.DisplayUtils; import com.gh.gamecenter.common.constant.EntranceConsts; import com.gh.common.util.ErrorHelper; @@ -399,7 +400,7 @@ public class MessageDetailFragment extends ToolbarFragment implements OnCommentC e1.printStackTrace(); } } - ErrorHelper.handleError(requireContext(), errorString, false); + ErrorHelper.handleError(requireContext(), errorString, false, () -> mBinding.pieceCommentTypingContainer.answerCommentSendBtn.performClick()); } }); }); diff --git a/app/src/main/java/com/gh/gamecenter/qa/article/edit/ArticleEditActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/article/edit/ArticleEditActivity.kt index c784489c61..f6b9ae2520 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/article/edit/ArticleEditActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/article/edit/ArticleEditActivity.kt @@ -243,7 +243,13 @@ class ArticleEditActivity : BaseRichEditorActivity(), Keyb }) mViewModel.error.observeNonNull(this) { - ErrorHelper.handleError(this, it) + ErrorHelper.handleError(this, it, false, object : ConfirmListener { + override fun onConfirm() { + if (::mMenuPost.isInitialized) { + onMenuItemClick(mMenuPost) + } + } + }) } when { diff --git a/app/src/main/java/com/gh/gamecenter/qa/column/AskColumnRepository.java b/app/src/main/java/com/gh/gamecenter/qa/column/AskColumnRepository.java index a350eeb5fb..70e2f83131 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/column/AskColumnRepository.java +++ b/app/src/main/java/com/gh/gamecenter/qa/column/AskColumnRepository.java @@ -126,7 +126,7 @@ public class AskColumnRepository { } catch (Exception e1) { e1.printStackTrace(); } - ErrorHelper.handleError(mContext, errorString, false); + ErrorHelper.handleError(mContext, errorString, false, null); } }); diff --git a/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentFragment.kt index c765106154..577d747583 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/comment/NewCommentFragment.kt @@ -29,6 +29,7 @@ import com.gh.gamecenter.R import com.gh.gamecenter.adapter.OnCommentCallBackListener import com.gh.gamecenter.baselist.ListAdapter import com.gh.gamecenter.baselist.ListFragment +import com.gh.gamecenter.common.callback.ConfirmListener import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.* import com.gh.gamecenter.databinding.ItemCommentEditImageBinding @@ -201,7 +202,11 @@ open class NewCommentFragment : ListFragment e1.printStackTrace() } - ErrorHelper.handleError(requireContext(), errorString, false) + ErrorHelper.handleError(requireContext(), errorString, false, object : ConfirmListener { + override fun onConfirm() { + commentSendBtn.performClick() + } + }) } else -> { mSendingDialog?.dismiss() diff --git a/app/src/main/java/com/gh/gamecenter/qa/questions/edit/QuestionEditActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/questions/edit/QuestionEditActivity.kt index fc9095ab5c..f5f5efef63 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/questions/edit/QuestionEditActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/questions/edit/QuestionEditActivity.kt @@ -19,6 +19,7 @@ import androidx.core.widget.addTextChangedListener import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders import com.gh.base.BaseRichEditorActivity +import com.gh.common.util.ErrorHelper import com.gh.common.util.NewLogUtils import com.gh.gamecenter.common.utils.NotificationHelper import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment @@ -388,6 +389,14 @@ class QuestionEditActivity : BaseRichEditorActivity(), extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true) ) return@Observer + } else if (errorCode == 403209) { + ErrorHelper.handleError(this, string, false, object : ConfirmListener { + override fun onConfirm() { + if (::mMenuPost.isInitialized) { + onMenuItemClick(mMenuPost) + } + } + }) } } toast(R.string.post_failure_hint) diff --git a/app/src/main/java/com/gh/gamecenter/qa/tags/AskQuestionsNewRepository.java b/app/src/main/java/com/gh/gamecenter/qa/tags/AskQuestionsNewRepository.java index ec4c42f1cd..f16af22f09 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/tags/AskQuestionsNewRepository.java +++ b/app/src/main/java/com/gh/gamecenter/qa/tags/AskQuestionsNewRepository.java @@ -132,7 +132,7 @@ public class AskQuestionsNewRepository { } catch (Exception e1) { e1.printStackTrace(); } - ErrorHelper.handleError(mContext, errorString, false); + ErrorHelper.handleError(mContext, errorString, false, null); } }); diff --git a/app/src/main/java/com/gh/gamecenter/qa/video/publish/VideoPublishFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/video/publish/VideoPublishFragment.kt index 77dbbf8739..34f94fd356 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/video/publish/VideoPublishFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/video/publish/VideoPublishFragment.kt @@ -29,6 +29,7 @@ import com.gh.gamecenter.entity.* import com.gh.gamecenter.manager.UserManager import com.gh.gamecenter.mvvm.Status import com.gh.gamecenter.common.base.fragment.ToolbarFragment +import com.gh.gamecenter.common.callback.ConfirmListener import com.gh.gamecenter.common.entity.NotificationUgc import com.gh.gamecenter.qa.BbsType import com.gh.gamecenter.qa.dialog.ChooseActivityDialogFragment @@ -300,7 +301,15 @@ class VideoPublishFragment : ToolbarFragment(), KeyboardHeightObserver { } else if (it.status == Status.ERROR) { ErrorHelper.handleError( requireContext(), - it.exception?.response()?.errorBody()?.string() + it.exception?.response()?.errorBody()?.string(), + false, + object : ConfirmListener { + override fun onConfirm() { + if (::mMenuPost.isInitialized) { + onMenuItemClick(mMenuPost) + } + } + } ) } } diff --git a/app/src/main/java/com/halo/assistant/fragment/comment/CommentDetailFragment.java b/app/src/main/java/com/halo/assistant/fragment/comment/CommentDetailFragment.java index 58134c4189..e3d8917668 100644 --- a/app/src/main/java/com/halo/assistant/fragment/comment/CommentDetailFragment.java +++ b/app/src/main/java/com/halo/assistant/fragment/comment/CommentDetailFragment.java @@ -228,7 +228,7 @@ public class CommentDetailFragment extends ToolbarFragment implements OnCommentC e1.printStackTrace(); } } - ErrorHelper.handleError(requireContext(), errorString, false); + ErrorHelper.handleError(requireContext(), errorString, false, () -> mCommentSend.performClick()); } }); } From 495070a14e8801f7c9cfb52f025de51885be8f63 Mon Sep 17 00:00:00 2001 From: juntao Date: Fri, 22 Jul 2022 15:14:55 +0800 Subject: [PATCH 125/217] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E5=8A=A9=E6=89=8B=E9=9A=90=E7=A7=81=E6=94=BF=E7=AD=96?= =?UTF-8?q?=E8=B7=B3=E8=BD=AC=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VHelper.kt | 5 +++-- app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt | 3 +++ .../java/com/gh/gamecenter/common/constant/Constants.java | 3 +++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 1ffbff613b..eefd6b1878 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -406,7 +406,6 @@ object VHelper { mVGameDao.insert(VGameEntity.from(downloadEntity)) if (result.status == 0) { - insertInstalledGameToProvider(downloadEntity) updateInstalledList() PackageObserver.onPackageChanged( EBPackage( @@ -415,14 +414,16 @@ object VHelper { "unknown" ) ) + insertInstalledGameToProvider(downloadEntity) } else { ToastUtils.toast("安装出现异常, ${result.status}") } + Utils.log(LOG_TAG, "安装新应用结果 -> " + result.status) + mInstallingVaPathSet.remove(downloadEntity.path) mInstallationLiveData.postValue(result.packageName) - Utils.log(LOG_TAG, "安装新应用结果 -> " + result.status) VBackupHelper.backupDBToExternalStorage(HaloApp.getInstance()) } catch (e: Exception) { diff --git a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt index 62358e0480..49407e0a73 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt @@ -17,6 +17,7 @@ import com.gh.common.exposure.ExposureUtils import com.gh.common.exposure.ExposureUtils.DownloadType.DOWNLOAD import com.gh.common.exposure.ExposureUtils.DownloadType.UPDATE import com.gh.common.util.DataCollectionUtils +import com.gh.common.util.DirectUtils import com.gh.common.util.NewFlatLogUtils import com.gh.common.util.PackageInstaller import com.gh.common.view.DownloadProgressBar @@ -24,6 +25,7 @@ import com.gh.download.DownloadManager import com.gh.download.PackageObserver import com.gh.gamecenter.R import com.gh.gamecenter.common.base.fragment.BaseDraggableDialogFragment +import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.utils.toColor import com.gh.gamecenter.common.utils.toJson import com.gh.gamecenter.common.utils.viewModelProvider @@ -95,6 +97,7 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { mBinding.descTv.text = spanBuilder mBinding.privacyPolicyTv.setOnClickListener { NewFlatLogUtils.logHaloFunEvent("halo_fun_download_dialog_privacy_click") + DirectUtils.directToWebView(requireContext(), Constants.SMOOTH_GAME_PRIVACY_POLICY_ADDRESS) } val downloadSnapshot = DownloadManager.getInstance() diff --git a/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java b/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java index 1a9c1fde57..6583454b4b 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java +++ b/module_common/src/main/java/com/gh/gamecenter/common/constant/Constants.java @@ -300,6 +300,9 @@ public class Constants { public static final String HELP_ADDRESS_DEV = "https://static-web.ghzs.com/ghzs_help_dev/help.html?content="; public static final String HELP_ADDRESS = "https://static-web.ghzs.com/ghzs_help/help.html?content="; + // 畅玩助手相关 + public static final String SMOOTH_GAME_PRIVACY_POLICY_ADDRESS = "https://sdg-static.79887.com/misc/privacy_CW.html"; + // 注销页面 public static final String LOGOUT_ADDRESS_DEV = "https://static-web.ghzs.com/ghzs_help_dev/help.html?content=5f6b1f02786564003944a693&from=ghzs"; public static final String LOGOUT_ADDRESS = "https://static-web.ghzs.com/ghzs_help/help.html?content=5f534111b1f72909fc225672&from=ghzs"; From f98726fa18558e9f57c4af37354a937ce6e13e85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Fri, 22 Jul 2022 16:11:52 +0800 Subject: [PATCH 126/217] =?UTF-8?q?feat:=20=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E9=A6=96=E9=A1=B5=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E5=88=97=E8=A1=A8=E4=BC=98=E5=8C=96=20https://git.sha?= =?UTF-8?q?nqu.cc/pm/halo/halo-app-issues/-/issues/1949?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/util/NewFlatLogUtils.kt | 17 ++++++ .../com/gh/gamecenter/entity/HomeContent.kt | 9 ++- .../com/gh/gamecenter/entity/HomeSetting.kt | 14 +++-- .../gh/gamecenter/home/HomeFragmentAdapter.kt | 2 +- .../gamecenter/home/HomeGameItemViewHolder.kt | 30 ++++++++-- .../com/gh/gamecenter/home/HomeViewModel.kt | 17 ++++++ .../LegacyHomeFragmentAdapterAssistant.kt | 12 ++++ .../gh/gamecenter/home/LegacyHomeItemData.kt | 1 + app/src/main/res/layout/home_game_item.xml | 58 +++++++++++++------ 9 files changed, 129 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt b/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt index d45aa52610..4ffc0a4fc6 100644 --- a/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt +++ b/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt @@ -66,4 +66,21 @@ object NewFlatLogUtils { } log(json, "event", false) } + + //首页点击内容卡片 + @JvmStatic + fun logHomeGameContentCardClick( + linkType: String, + linkId: String, + linkText: String + ) { + val json = json { + "event" to "home_game_content_card_click" + "link_type" to linkType + "link_id" to linkId + "link_text" to linkText + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/entity/HomeContent.kt b/app/src/main/java/com/gh/gamecenter/entity/HomeContent.kt index cb7ece6001..7a8e58bacf 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/HomeContent.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/HomeContent.kt @@ -22,5 +22,12 @@ data class HomeContent( @SerializedName("recommend_text") val recommendText: String = "", @SerializedName("common_collection") - val commonCollection: CommonCollectionEntity? = null + val commonCollection: CommonCollectionEntity? = null, + val image: String = "", + @SerializedName("first_line_recommend") + val firstLineRecommend: String = "", + @SerializedName("second_line_recommend") + val secondLineRecommend: String = "", + @SerializedName("recommend_tag") + val recommendTag: String = "", ) \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/entity/HomeSetting.kt b/app/src/main/java/com/gh/gamecenter/entity/HomeSetting.kt index 4371691f53..c09c00259d 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/HomeSetting.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/HomeSetting.kt @@ -5,8 +5,12 @@ import com.google.gson.annotations.SerializedName import kotlinx.parcelize.Parcelize @Parcelize -data class HomeSetting(var image: String = "", - @SerializedName("text_color") - val textColor: String = "#FFFFFF", - @SerializedName("placeholder_color") - val placeholderColor: String = "#5C9599") : Parcelable \ No newline at end of file +data class HomeSetting( + var image: String = "", + @SerializedName("text_color") + val textColor: String = "#FFFFFF", + @SerializedName("placeholder_color") + val placeholderColor: String = "#5C9599", + @SerializedName("download_btn_switch") + val downloadBtnSwitch: String = ""//下载按钮是否显示,on 显示 +) : Parcelable \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt index 825ea14578..d7ae4808d6 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt @@ -277,7 +277,7 @@ class HomeFragmentAdapter( val game = homeItemData.attachGame?.linkGame!! val displayContent = homeItemData.attachGame?.displayContent ?: "" game.displayContent = displayContent - holder.bindGame(game) + holder.bindGame(homeItemData, this, position) runOnIoThread(true) { homeItemData.exposureEvent = ExposureEvent.createEventWithSourceConcat( diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt index e902dc5892..b724c6b42c 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt @@ -5,16 +5,18 @@ import android.graphics.drawable.ColorDrawable import android.graphics.drawable.GradientDrawable import android.view.View import androidx.constraintlayout.widget.ConstraintSet -import com.gh.gamecenter.common.base.BaseRecyclerViewHolder -import com.gh.gamecenter.core.utils.RandomUtils +import androidx.recyclerview.widget.RecyclerView +import com.gh.common.util.DownloadItemUtils import com.gh.gamecenter.R +import com.gh.gamecenter.common.base.BaseRecyclerViewHolder import com.gh.gamecenter.common.utils.* +import com.gh.gamecenter.core.utils.RandomUtils import com.gh.gamecenter.databinding.HomeGameItemBinding -import com.gh.gamecenter.entity.GameEntity class HomeGameItemViewHolder(val binding: HomeGameItemBinding) : BaseRecyclerViewHolder(binding.root) { - fun bindGame(game: GameEntity) { + fun bindGame(homeItemData: HomeItemData, adapter: RecyclerView.Adapter, position: Int) { + val game = homeItemData.attachGame?.linkGame!! binding.gameIcon.displayGameIcon(game) binding.gameName.text = game.name binding.gameName.setTextColor(R.color.text_title.toColor(binding.root.context)) @@ -61,7 +63,12 @@ class HomeGameItemViewHolder(val binding: HomeGameItemBinding) : BaseRecyclerVie } ConstraintSet().apply { clone(binding.root) - connect(R.id.game_name, ConstraintSet.END, if (game.serverLabel != null && !game.advanceDownload) R.id.recent_played_tag else R.id.gameSubtitleTv, ConstraintSet.START) + connect( + R.id.game_name, + ConstraintSet.END, + if (game.serverLabel != null && !game.advanceDownload) R.id.recent_played_tag else R.id.gameSubtitleTv, + ConstraintSet.START + ) }.applyTo(binding.root) val hierarchy = binding.gameImage.hierarchy @@ -70,5 +77,18 @@ class HomeGameItemViewHolder(val binding: HomeGameItemBinding) : BaseRecyclerVie } catch (ignore: Throwable) { hierarchy.setPlaceholderImage(RandomUtils.getRandomPlaceholderColor()) } + + DownloadItemUtils.setOnClickListener( + binding.root.context, + binding.downloadBtn, + game, + position, + adapter, + "新首页", + "", + homeItemData.exposureEvent + ) + DownloadItemUtils.updateDownloadButton(binding.root.context, binding.downloadBtn, game) + binding.downloadBtn.goneIf(game.homeSetting.downloadBtnSwitch != "on") } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index 3dc3b8147e..71ca22871b 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -416,6 +416,23 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { } gameCollection.gameCollection = itemDataList mSnapshotItemList.add(gameCollection) + } else if (linkType == "community_article" + || linkType == "question" + || linkType == "video" + || linkType == "news" + ) { + val homeItemData = HomeItemData().apply { + blockPosition = i + bigImageRecommend = SubjectEntity( + id = homeContent.linkId, + type = homeContent.linkType, + image = homeContent.image, + firstLineRecommend = homeContent.firstLineRecommend, + secondLineRecommend = homeContent.secondLineRecommend, + recommendTag = homeContent.recommendTag + ) + } + mSnapshotItemList.add(homeItemData) } else { val unknown = HomeItemData() unknown.blockPosition = i + 1 diff --git a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt index 96629096f5..58a5b3fda5 100644 --- a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt +++ b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt @@ -31,6 +31,7 @@ import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.entity.LinkEntity import com.gh.gamecenter.game.GameAndPosition import com.gh.gamecenter.game.GameItemViewHolder +import com.gh.gamecenter.game.bigimagerecommend.BigImageRecommendViewHolder import com.gh.gamecenter.game.columncollection.GameColumnCollectionViewHolder import com.gh.gamecenter.game.commoncollection.CommonCollectionViewHolder import com.gh.gamecenter.game.commoncollection.detail.CommonCollectionDetailActivity @@ -83,6 +84,7 @@ class LegacyHomeFragmentAdapterAssistant( if (itemData.commonCollection != null) return ItemViewType.COMMON_LINK_COLLECTION if (itemData.rankCollection != null) return ItemViewType.RANK_COLLECTION if (itemData.doubleCardColumn != null) return ItemViewType.DOUBLE_CARD_COLUMN + if (itemData.bigImageRecommend != null) return ItemViewType.BIG_IMAGE_RECOMMEND return 0 } @@ -106,6 +108,7 @@ class LegacyHomeFragmentAdapterAssistant( ItemViewType.COMMON_LINK_COLLECTION -> CommonCollectionViewHolder(parent.toBinding()) ItemViewType.RANK_COLLECTION -> RankCollectionViewHolder(parent.toBinding()) ItemViewType.DOUBLE_CARD_COLUMN -> DoubleCardListViewHolder(parent.toBinding()) + ItemViewType.BIG_IMAGE_RECOMMEND -> BigImageRecommendViewHolder(parent.toBinding()) else -> throw NullPointerException() } @@ -135,6 +138,7 @@ class LegacyHomeFragmentAdapterAssistant( is CommonCollectionViewHolder -> bindCommonCollection(holder, item) is RankCollectionViewHolder -> bindRankCollection(holder, item) is DoubleCardListViewHolder -> bindGameDoubleCardList(holder, item) + is BigImageRecommendViewHolder -> bindBigImageRecommend(holder, item) } } @@ -889,6 +893,14 @@ class LegacyHomeFragmentAdapterAssistant( } } + private fun bindBigImageRecommend(holder: BigImageRecommendViewHolder, item: LegacyHomeItemData) { + item.bigImageRecommend?.run { + holder.bindBigImageRecommend(this, "新首页") { + NewFlatLogUtils.logHomeGameContentCardClick(it.type ?: "", it.link ?: "", "") + } + } + } + private fun setPageSwitchData() { PageSwitchDataHelper.pushCurrentPageData( hashMapOf( diff --git a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeItemData.kt b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeItemData.kt index 33e0373231..5b96ea2ad1 100644 --- a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeItemData.kt +++ b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeItemData.kt @@ -29,5 +29,6 @@ open class LegacyHomeItemData( var commonCollection: SubjectEntity? = null, var rankCollection: SubjectEntity? = null, // 排行榜样式专题合集 var doubleCardColumn: SubjectEntity? = null, // 双列卡片专题 + var bigImageRecommend: SubjectEntity? = null, //提问、帖子、视频帖、文章 var blankDivider: Float? = null // 空白填充内容 ) \ No newline at end of file diff --git a/app/src/main/res/layout/home_game_item.xml b/app/src/main/res/layout/home_game_item.xml index 941666cac7..d7026feb4c 100644 --- a/app/src/main/res/layout/home_game_item.xml +++ b/app/src/main/res/layout/home_game_item.xml @@ -68,37 +68,57 @@ android:textSize="@dimen/tag_text_size" android:visibility="gone" app:layout_constraintBottom_toBottomOf="@+id/game_name" - app:layout_constraintEnd_toStartOf="@+id/game_rating" + app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/game_name" app:layout_constraintTop_toTopOf="@+id/game_name" app:layout_goneMarginStart="0dp" tools:text="副标题" /> - + app:layout_constraintTop_toBottomOf="@+id/game_name"> + + + + + + app:layout_constraintTop_toTopOf="parent" + tools:visibility="visible" /> From d00f50bcf8d82021aa97652c9886d286704aef19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Mon, 25 Jul 2022 15:48:20 +0800 Subject: [PATCH 127/217] =?UTF-8?q?feat:=20=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E8=BF=9D=E8=A7=84=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E6=95=B4=E5=90=88=20https://git.shanqu.cc/pm/halo/hal?= =?UTF-8?q?o-app-issues/-/issues/1946?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/databind/BindingAdapters.java | 1 + .../common/simulator/SimulatorDownloadManager.kt | 3 +++ .../com/gh/common/util/DetailDownloadUtils.java | 1 + .../gh/common/util/DownloadNotificationHelper.kt | 1 + .../java/com/gh/common/util/DownloadObserver.kt | 6 ++++++ .../main/java/com/gh/common/util/ErrorHelper.kt | 9 +++++++-- .../java/com/gh/download/DownloadDataHelper.kt | 2 ++ .../com/gh/gamecenter/manager/UserManager.java | 16 +++++++++++----- libraries/LGLibrary | 2 +- 9 files changed, 33 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java index a306ceecd8..7d8b3acaad 100644 --- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java +++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java @@ -580,6 +580,7 @@ public class BindingAdapters { case uncertificated: case unqualified: case unavailable: + case banned: break; default: break; diff --git a/app/src/main/java/com/gh/common/simulator/SimulatorDownloadManager.kt b/app/src/main/java/com/gh/common/simulator/SimulatorDownloadManager.kt index 7c5bd38bab..5d2f7bad6f 100644 --- a/app/src/main/java/com/gh/common/simulator/SimulatorDownloadManager.kt +++ b/app/src/main/java/com/gh/common/simulator/SimulatorDownloadManager.kt @@ -97,6 +97,9 @@ class SimulatorDownloadManager private constructor() { DownloadStatus.unavailable == downloadEntity.status -> { ToastUtils.showToast("该游戏未接入防沉迷系统,暂不支持下载") } + DownloadStatus.banned == downloadEntity.status -> { + ToastUtils.showToast("网络异常") + } DownloadStatus.hijack == downloadEntity.status -> { ToastUtils.showToast("网络劫持,请稍后重试") } diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index dd1d3586dd..d331b0e362 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -202,6 +202,7 @@ public class DetailDownloadUtils { case uncertificated: case unqualified: case unavailable: + case banned: detailInitDownload(viewHolder, false); break; default: diff --git a/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt b/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt index af208da26f..e5cbafa9bb 100644 --- a/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt +++ b/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt @@ -119,6 +119,7 @@ object DownloadNotificationHelper { || entity.status == DownloadStatus.hijack || entity.status == DownloadStatus.unqualified || entity.status == DownloadStatus.unavailable + || entity.status == DownloadStatus.banned || entity.status == DownloadStatus.uncertificated || entity.status == DownloadStatus.notfound || entity.status == DownloadStatus.overflow diff --git a/app/src/main/java/com/gh/common/util/DownloadObserver.kt b/app/src/main/java/com/gh/common/util/DownloadObserver.kt index f0c577ca65..3868df9878 100644 --- a/app/src/main/java/com/gh/common/util/DownloadObserver.kt +++ b/app/src/main/java/com/gh/common/util/DownloadObserver.kt @@ -18,6 +18,7 @@ import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.GsonUtils import com.gh.gamecenter.core.utils.MtaHelper import com.gh.gamecenter.core.utils.StringUtils +import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.entity.SimpleGameEntity import com.gh.gamecenter.entity.SimulatorEntity @@ -131,6 +132,11 @@ object DownloadObserver { // 未实名 RealNameHelper.showRealNameUncertificatedDialog(downloadEntity) + // 删除任务 + downloadEntity.status = DownloadStatus.cancel + downloadManager.cancel(downloadEntity.url) + }else if (DownloadStatus.banned == downloadEntity.status) { + ToastUtils.showToast("网络异常") // 删除任务 downloadEntity.status = DownloadStatus.cancel downloadManager.cancel(downloadEntity.url) diff --git a/app/src/main/java/com/gh/common/util/ErrorHelper.kt b/app/src/main/java/com/gh/common/util/ErrorHelper.kt index 9349cded95..8448d49842 100644 --- a/app/src/main/java/com/gh/common/util/ErrorHelper.kt +++ b/app/src/main/java/com/gh/common/util/ErrorHelper.kt @@ -187,8 +187,10 @@ object ErrorHelper { "前往实名认证", "以后再说", uiModificationCallback = { binding -> binding.hintTv.visibility = View.VISIBLE - binding.hintTv.layoutParams = (binding.hintTv.layoutParams as ViewGroup.MarginLayoutParams).apply { setMargins(0, 8F.dip2px(), 0, 0) } - binding.lineView.layoutParams = (binding.lineView.layoutParams as ViewGroup.MarginLayoutParams).apply { setMargins(0, 23F.dip2px(), 0, 0) } + binding.hintTv.layoutParams = + (binding.hintTv.layoutParams as ViewGroup.MarginLayoutParams).apply { setMargins(0, 8F.dip2px(), 0, 0) } + binding.lineView.layoutParams = + (binding.lineView.layoutParams as ViewGroup.MarginLayoutParams).apply { setMargins(0, 23F.dip2px(), 0, 0) } binding.hintTv.text = errorEntity.data?.text binding.hintTv.setTextColor(R.color.theme_font.toColor(context)) binding.hintTv.setOnClickListener { @@ -303,6 +305,9 @@ object ErrorHelper { errorEntity?.code == 403099 -> { Utils.toast(context, "当前账号正在注销,禁止登录") } + errorEntity?.code == 403401 -> {//禁止登录 + Utils.toast(context, "网络异常") + } errorEntity?.toast?.isNotEmpty() == true -> { Utils.toast(context, errorEntity.toast) } diff --git a/app/src/main/java/com/gh/download/DownloadDataHelper.kt b/app/src/main/java/com/gh/download/DownloadDataHelper.kt index 4e1a6b2649..5624883246 100644 --- a/app/src/main/java/com/gh/download/DownloadDataHelper.kt +++ b/app/src/main/java/com/gh/download/DownloadDataHelper.kt @@ -88,6 +88,8 @@ object DownloadDataHelper { "未成年" } else if (status == DownloadStatus.unavailable) { "未接入防沉迷系统,暂不支持下载" + }else if (status == DownloadStatus.banned) { + "网络异常" } else if (status == DownloadStatus.redirected) { "重定向至最终地址" } else { diff --git a/app/src/main/java/com/gh/gamecenter/manager/UserManager.java b/app/src/main/java/com/gh/gamecenter/manager/UserManager.java index 051a08c94e..e2b4e6bc15 100644 --- a/app/src/main/java/com/gh/gamecenter/manager/UserManager.java +++ b/app/src/main/java/com/gh/gamecenter/manager/UserManager.java @@ -7,10 +7,14 @@ import android.text.TextUtils; import androidx.annotation.Nullable; +import com.gh.common.repository.ReservationRepository; +import com.gh.common.util.ErrorHelper; import com.gh.gamecenter.common.base.activity.BaseActivity; import com.gh.gamecenter.common.constant.Constants; +import com.gh.gamecenter.common.eventbus.EBShowDialog; import com.gh.gamecenter.common.exposure.meta.MetaUtil; -import com.gh.common.repository.ReservationRepository; +import com.gh.gamecenter.common.retrofit.BiResponse; +import com.gh.gamecenter.common.retrofit.Response; import com.gh.gamecenter.common.utils.DeviceUtils; import com.gh.gamecenter.common.utils.EnvHelper; import com.gh.gamecenter.core.utils.GsonUtils; @@ -19,9 +23,6 @@ import com.gh.gamecenter.entity.CommunityEntity; import com.gh.gamecenter.entity.LoginTokenEntity; import com.gh.gamecenter.entity.TokenEntity; import com.gh.gamecenter.entity.UserInfoEntity; -import com.gh.gamecenter.common.eventbus.EBShowDialog; -import com.gh.gamecenter.common.retrofit.BiResponse; -import com.gh.gamecenter.common.retrofit.Response; import com.gh.gamecenter.retrofit.RetrofitManager; import com.gh.gamecenter.retrofit.service.ApiService; import com.gh.gamecenter.user.UserRepository; @@ -187,7 +188,7 @@ public class UserManager { public void onFailure(HttpException e) { super.onFailure(e); String errorMessage = "null"; - if (e != null && (e.code() == 401 || e.code() == 400)) { + if (e != null && (e.code() == 401 || e.code() == 403 || e.code() == 400)) { int code = -1; try { errorMessage = e.response().errorBody().string(); @@ -200,6 +201,11 @@ public class UserManager { if (code == 400401 || code == 400802) { // 自动注销 UserRepository.getInstance().logout(); } + + if (code == 403401) { + UserRepository.getInstance().logout(); + ErrorHelper.handleLoginError(HaloApp.getInstance().getApplicationContext(), e); + } } catch (Exception e1) { e1.printStackTrace(); } diff --git a/libraries/LGLibrary b/libraries/LGLibrary index 2fb219f6c0..753db733db 160000 --- a/libraries/LGLibrary +++ b/libraries/LGLibrary @@ -1 +1 @@ -Subproject commit 2fb219f6c06a14cb78341c14f5b8c847484df6cf +Subproject commit 753db733dbcda292bb4eed40a1cb6cf0b595cc76 From 8d1f300241b7f5eaa458c7047e9c47aa42d77cfb Mon Sep 17 00:00:00 2001 From: guotao Date: Tue, 26 Jul 2022 10:00:00 +0800 Subject: [PATCH 128/217] =?UTF-8?q?fix:=E5=AE=89=E8=A3=85=E5=AE=8C?= =?UTF-8?q?=E7=95=85=E7=8E=A9=E6=B8=B8=E6=88=8F=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=8F=92=E5=85=A5=E5=BD=93=E5=89=8D=E6=8E=A5=E5=8F=A3=E7=8E=AF?= =?UTF-8?q?=E5=A2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VHelper.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index eefd6b1878..629cd7156e 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -20,6 +20,7 @@ import com.gh.common.util.NewFlatLogUtils import com.gh.common.util.PackageUtils import com.gh.download.DownloadManager import com.gh.download.PackageObserver +import com.gh.gamecenter.BuildConfig import com.gh.gamecenter.R import com.gh.gamecenter.SplashScreenActivity import com.gh.gamecenter.common.constant.Constants @@ -451,6 +452,7 @@ object VHelper { values.put("name",downloadEntity.name) values.put("size",downloadEntity.size) values.put("meta",GsonUtils.toJson(downloadEntity.meta)) + values.put("debug",BuildConfig.DEBUG) val uri = Uri.parse("content://com.lg.core.provider/download_game") HaloApp.getInstance().contentResolver.insert(uri,values) } From 3ab322958078d4c1ec6e5c05216fb589e25b6880 Mon Sep 17 00:00:00 2001 From: guotao Date: Tue, 26 Jul 2022 11:06:37 +0800 Subject: [PATCH 129/217] =?UTF-8?q?fix:=E5=AE=89=E8=A3=85=E5=AE=8C?= =?UTF-8?q?=E7=95=85=E7=8E=A9=E6=B8=B8=E6=88=8F=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=8F=92=E5=85=A5=E5=BD=93=E5=89=8D=E6=98=AF=E5=90=A6=E6=98=AF?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=8C=85=E4=BE=9D=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VHelper.kt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 629cd7156e..ab499d2a78 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -20,15 +20,12 @@ import com.gh.common.util.NewFlatLogUtils import com.gh.common.util.PackageUtils import com.gh.download.DownloadManager import com.gh.download.PackageObserver -import com.gh.gamecenter.BuildConfig + import com.gh.gamecenter.R import com.gh.gamecenter.SplashScreenActivity import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.retrofit.BiResponse -import com.gh.gamecenter.common.utils.DialogHelper -import com.gh.gamecenter.common.utils.addMetaExtra -import com.gh.gamecenter.common.utils.getMetaExtra -import com.gh.gamecenter.common.utils.toColor +import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.core.utils.EmptyCallback @@ -452,7 +449,8 @@ object VHelper { values.put("name",downloadEntity.name) values.put("size",downloadEntity.size) values.put("meta",GsonUtils.toJson(downloadEntity.meta)) - values.put("debug",BuildConfig.DEBUG) + val type = if(PackageFlavorHelper.IS_TEST_FLAVOR) "test_flavor" else "" + values.put("type",type) val uri = Uri.parse("content://com.lg.core.provider/download_game") HaloApp.getInstance().contentResolver.insert(uri,values) } From 5609a953829520e89954df7369008e4fd8eaa5df Mon Sep 17 00:00:00 2001 From: leafwai Date: Tue, 26 Jul 2022 14:05:08 +0800 Subject: [PATCH 130/217] =?UTF-8?q?feat:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=B8=B8=E6=88=8F=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E6=96=B0=E5=A2=9E=E2=80=9C=E5=86=85=E5=AE=B9=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E2=80=9D=E5=8A=9F=E8=83=BD=20https://git.shanqu.cc/pm?= =?UTF-8?q?/halo/halo-app-issues/-/issues/1953?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/common/util/DirectUtils.kt | 10 +- .../com/gh/common/util/NewFlatLogUtils.kt | 40 ++++ .../com/gh/gamecenter/GameDetailActivity.kt | 2 +- .../java/com/gh/gamecenter/SkipActivity.java | 2 +- .../catalog/SpecialCatalogFragment.kt | 2 +- .../catalog/SpecialCatalogViewModel.kt | 10 +- .../category2/CategoryV2Fragment.kt | 24 +- .../category2/CategoryV2ListAdapter.kt | 4 +- .../category2/CategoryV2ListFragment.kt | 5 +- .../category2/CategoryV2ListViewModel.kt | 6 +- .../GameDetailContentCardContentAdapter.kt | 46 ++++ .../gamedetail/GameDetailFragment.kt | 208 +++++++++++++++++- .../gamedetail/GameDetailViewModel.kt | 12 + .../gamecenter/gamedetail/desc/DescAdapter.kt | 10 +- .../gamedetail/desc/DescFragment.kt | 12 + .../gamedetail/desc/DescViewModel.kt | 15 ++ .../gamedetail/entity/ContentCardEntity.kt | 69 ++++++ .../gamedetail/entity/NewGameDetailEntity.kt | 4 +- .../gh/gamecenter/subject/SubjectAdapter.kt | 4 +- .../gamecenter/subject/SubjectListFragment.kt | 2 +- .../subject/SubjectListViewModel.kt | 6 +- .../bg_content_card_large.webp | Bin 0 -> 956 bytes .../bg_content_card_large_primary.webp | Bin 0 -> 20864 bytes .../bg_content_card_large_right.webp | Bin 0 -> 1010 bytes .../bg_content_card_small.webp | Bin 0 -> 594 bytes .../bg_content_card_small_right.webp | Bin 0 -> 858 bytes .../bg_content_card_large.webp | Bin 0 -> 1084 bytes .../bg_content_card_large_primary.webp | Bin 0 -> 99046 bytes .../bg_content_card_large_right.webp | Bin 0 -> 1078 bytes .../bg_content_card_small.webp | Bin 0 -> 516 bytes .../bg_content_card_small_right.webp | Bin 0 -> 890 bytes .../res/drawable/bg_hint_red_radius_999.xml | 5 + app/src/main/res/layout/gamedetail_body.xml | 10 + .../item_game_detail_content_card_content.xml | 8 + .../layout_game_detail_content_card_large.xml | 99 +++++++++ .../layout_game_detail_content_card_small.xml | 60 +++++ .../common/constant/EntranceConsts.java | 1 + .../com/gh/gamecenter/core/utils/TimeUtils.kt | 12 + 38 files changed, 646 insertions(+), 42 deletions(-) create mode 100644 app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailContentCardContentAdapter.kt create mode 100644 app/src/main/java/com/gh/gamecenter/gamedetail/entity/ContentCardEntity.kt create mode 100644 app/src/main/res/drawable-night-xxxhdpi/bg_content_card_large.webp create mode 100644 app/src/main/res/drawable-night-xxxhdpi/bg_content_card_large_primary.webp create mode 100644 app/src/main/res/drawable-night-xxxhdpi/bg_content_card_large_right.webp create mode 100644 app/src/main/res/drawable-night-xxxhdpi/bg_content_card_small.webp create mode 100644 app/src/main/res/drawable-night-xxxhdpi/bg_content_card_small_right.webp create mode 100644 app/src/main/res/drawable-xxxhdpi/bg_content_card_large.webp create mode 100644 app/src/main/res/drawable-xxxhdpi/bg_content_card_large_primary.webp create mode 100644 app/src/main/res/drawable-xxxhdpi/bg_content_card_large_right.webp create mode 100644 app/src/main/res/drawable-xxxhdpi/bg_content_card_small.webp create mode 100644 app/src/main/res/drawable-xxxhdpi/bg_content_card_small_right.webp create mode 100644 app/src/main/res/drawable/bg_hint_red_radius_999.xml create mode 100644 app/src/main/res/layout/item_game_detail_content_card_content.xml create mode 100644 app/src/main/res/layout/layout_game_detail_content_card_large.xml create mode 100644 app/src/main/res/layout/layout_game_detail_content_card_small.xml diff --git a/app/src/main/java/com/gh/common/util/DirectUtils.kt b/app/src/main/java/com/gh/common/util/DirectUtils.kt index a64044aa6b..01ef948439 100644 --- a/app/src/main/java/com/gh/common/util/DirectUtils.kt +++ b/app/src/main/java/com/gh/common/util/DirectUtils.kt @@ -80,6 +80,7 @@ import org.greenrobot.eventbus.EventBus import retrofit2.HttpException import java.net.URLEncoder import java.util.* +import kotlin.collections.ArrayList import kotlin.math.roundToInt /** @@ -189,7 +190,7 @@ object DirectUtils { "column", "游戏专题" -> directToSubject( context, linkEntity.link - ?: "", linkEntity.text, BaseActivity.mergeEntranceAndPath(entrance, path) + ?: "", linkEntity.text, BaseActivity.mergeEntranceAndPath(entrance, path), exposureEvent ) "question", "社区问题" -> directToQuestionDetail( @@ -239,7 +240,7 @@ object DirectUtils { "catalog" -> directCatalog(context, linkEntity.link!!, linkEntity.text!!, entrance, path) - "category_v2" -> directCategoryV2(context, linkEntity.link!!, linkEntity.text!!, entrance, path) + "category_v2" -> directCategoryV2(context, linkEntity.link!!, linkEntity.text!!, entrance, path, exposureEvent) "block", "版块" -> { if (linkEntity.link.isNullOrEmpty()) return @@ -629,13 +630,14 @@ object DirectUtils { // 专栏 @JvmStatic - fun directToSubject(context: Context, id: String, subjectName: String? = "", entrance: String? = null) { + fun directToSubject(context: Context, id: String, subjectName: String? = "", entrance: String? = null, exposureEvent: ExposureEvent? = null) { if (id.isEmpty()) return val bundle = Bundle() val subjectData = SubjectData(subjectId = id, subjectName = subjectName, isOrder = false) bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER) bundle.putString(KEY_TO, SubjectActivity::class.java.name) bundle.putParcelable(EntranceConsts.KEY_SUBJECT_DATA, subjectData) + if (exposureEvent != null) bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureEvent.source)) jumpActivity(context, bundle) } @@ -1179,6 +1181,7 @@ object DirectUtils { categoryTitle: String, entrance: String? = null, path: String? = "", + exposureEvent: ExposureEvent? = null, ) { if (categoryId.isEmpty()) return val bundle = Bundle() @@ -1186,6 +1189,7 @@ object DirectUtils { bundle.putString(KEY_CATEGORY_ID, categoryId) bundle.putString(KEY_CATEGORY_TITLE, categoryTitle) bundle.putString(KEY_ENTRANCE, BaseActivity.mergeEntranceAndPath(entrance, path)) + if (exposureEvent != null) bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureEvent.source)) jumpActivity(context, bundle) } diff --git a/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt b/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt index 4ffc0a4fc6..bafc34af00 100644 --- a/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt +++ b/app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt @@ -83,4 +83,44 @@ object NewFlatLogUtils { } log(json, "event", false) } + + //游戏详情点击内容卡片 + @JvmStatic + fun logGameDetailGameContentCardClick( + title: String, + gameName: String, + gameId: String, + linkType: String, + linkId: String, + linkText: String + ) { + val json = json { + "event" to "game_detail_game_content_card_click" + "title" to title + "game_name" to gameName + "game_id" to gameId + "link_type" to linkType + "link_id" to linkId + "link_text" to linkText + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } + + //浏览自定义栏目 + @JvmStatic + fun logGameDetailColumnOrderingView( + title: String, + gameName: String, + gameId: String + ) { + val json = json { + "event" to "game_detail_column_ordering_view" + "title" to title + "game_name" to gameName + "game_id" to gameId + parseAndPutMeta().invoke(this) + } + log(json, "event", false) + } } \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/GameDetailActivity.kt b/app/src/main/java/com/gh/gamecenter/GameDetailActivity.kt index 7c11a0424c..c94897e465 100644 --- a/app/src/main/java/com/gh/gamecenter/GameDetailActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/GameDetailActivity.kt @@ -80,7 +80,7 @@ class GameDetailActivity : DownloadToolbarActivity() { override fun isAutoResetViewBackgroundEnabled(): Boolean = true override fun updateStaticViewBackground(view: View?) { - updateStaticView(view, listOf(R.id.menu_download_iv, R.id.gameBigEvent)) + updateStaticView(view, listOf(R.id.menu_download_iv, R.id.gameBigEvent, R.id.backgroundIv)) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/SkipActivity.java b/app/src/main/java/com/gh/gamecenter/SkipActivity.java index c98d7e6b82..e815ac95e5 100644 --- a/app/src/main/java/com/gh/gamecenter/SkipActivity.java +++ b/app/src/main/java/com/gh/gamecenter/SkipActivity.java @@ -112,7 +112,7 @@ public class SkipActivity extends BaseActivity { DirectUtils.directToGameDetail(this, path, ENTRANCE_BROWSER, "true".equals(uri.getQueryParameter("auto_download")), to, null); break; case HOST_COLUMN: - DirectUtils.directToSubject(this, path, uri.getQueryParameter(KEY_NAME), ENTRANCE_BROWSER); + DirectUtils.directToSubject(this, path, uri.getQueryParameter(KEY_NAME), ENTRANCE_BROWSER, null); break; case HOST_SUGGESTION: String platform = uri.getQueryParameter(KEY_PLATFORM); diff --git a/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogFragment.kt b/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogFragment.kt index 20093e678d..7c9788fbc6 100644 --- a/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/catalog/SpecialCatalogFragment.kt @@ -32,7 +32,7 @@ class SpecialCatalogFragment : ListFragment(application) { + private val mExposureSourceList: List?) : ListViewModel(application) { private val mApi = RetrofitManager.getInstance().api val basicExposureSource by lazy { arrayListOf().apply { - mExposureSource?.let { add(it) } + if (!mExposureSourceList.isNullOrEmpty()) { + addAll(mExposureSourceList) + } add(ExposureSource("分类", mCatalogTitle)) } } @@ -98,7 +100,7 @@ class SpecialCatalogViewModel(application: Application, class Factory(private val mCatalogId: String, private val mCatalogTitle: String, private val mIsCategoryV2: Boolean, - private val mExposureSource: ExposureSource? + private val mExposureSourceList: List? ) : ViewModelProvider.NewInstanceFactory() { override fun create(modelClass: Class): T { return SpecialCatalogViewModel( @@ -106,7 +108,7 @@ class SpecialCatalogViewModel(application: Application, mCatalogId, mCatalogTitle, mIsCategoryV2, - mExposureSource + mExposureSourceList ) as T } } diff --git a/app/src/main/java/com/gh/gamecenter/category2/CategoryV2Fragment.kt b/app/src/main/java/com/gh/gamecenter/category2/CategoryV2Fragment.kt index f8d25cbe8d..b90527d491 100644 --- a/app/src/main/java/com/gh/gamecenter/category2/CategoryV2Fragment.kt +++ b/app/src/main/java/com/gh/gamecenter/category2/CategoryV2Fragment.kt @@ -1,6 +1,5 @@ package com.gh.gamecenter.category2 -import android.graphics.Color import android.os.Bundle import android.view.MenuItem import android.view.View @@ -10,17 +9,18 @@ import androidx.core.view.GravityCompat import androidx.drawerlayout.widget.DrawerLayout import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager -import com.gh.gamecenter.common.base.fragment.LazyFragment -import com.gh.gamecenter.common.constant.Constants -import com.gh.common.util.* +import com.gh.common.exposure.ExposureSource import com.gh.common.util.LogUtils -import com.gh.gamecenter.common.view.FixLinearLayoutManager import com.gh.gamecenter.R import com.gh.gamecenter.SearchActivity import com.gh.gamecenter.catalog.SpecialCatalogFragment +import com.gh.gamecenter.common.base.fragment.LazyFragment +import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.* -import com.gh.gamecenter.core.utils.* +import com.gh.gamecenter.common.view.FixLinearLayoutManager +import com.gh.gamecenter.core.utils.PageSwitchDataHelper +import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.databinding.FragmentCategoryBinding import com.gh.gamecenter.entity.CategoryEntity import com.gh.gamecenter.entity.SidebarsEntity @@ -307,7 +307,7 @@ class CategoryV2Fragment : LazyFragment() { EntranceConsts.KEY_IS_CATEGORY_V2 to true, EntranceConsts.KEY_CATALOG_ID to id, EntranceConsts.KEY_CATALOG_TITLE to mCategoryTitle, - EntranceConsts.KEY_EXPOSURE_SOURCE to arguments?.getParcelable(EntranceConsts.KEY_EXPOSURE_SOURCE), + EntranceConsts.KEY_EXPOSURE_SOURCE_LIST to arguments?.getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST), EntranceConsts.KEY_LAST_PAGE_DATA to mLastPageDataMap ) childFragmentManager @@ -331,7 +331,7 @@ class CategoryV2Fragment : LazyFragment() { EntranceConsts.KEY_CATEGORY_ID to id, EntranceConsts.KEY_SUB_CATEGORY_ID to sidebars[selectedCategoryPosition].categoryId, EntranceConsts.KEY_CATEGORY_TITLE to mCategoryTitle, - EntranceConsts.KEY_EXPOSURE_SOURCE to arguments?.getParcelable(EntranceConsts.KEY_EXPOSURE_SOURCE), + EntranceConsts.KEY_EXPOSURE_SOURCE_LIST to arguments?.getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST), EntranceConsts.KEY_LAST_PAGE_DATA to mLastPageDataMap ) childFragmentManager @@ -360,7 +360,7 @@ class CategoryV2Fragment : LazyFragment() { EntranceConsts.KEY_CATEGORY_ID to id, EntranceConsts.KEY_SUB_CATEGORY_ID to sidebars[position].categoryId, EntranceConsts.KEY_CATALOG_TITLE to mCategoryTitle, - EntranceConsts.KEY_EXPOSURE_SOURCE to arguments?.getParcelable(EntranceConsts.KEY_EXPOSURE_SOURCE), + EntranceConsts.KEY_EXPOSURE_SOURCE_LIST to arguments?.getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST), EntranceConsts.KEY_LAST_PAGE_DATA to mLastPageDataMap ) childFragmentManager @@ -378,7 +378,7 @@ class CategoryV2Fragment : LazyFragment() { EntranceConsts.KEY_IS_CATEGORY_V2 to true, EntranceConsts.KEY_CATALOG_ID to id, EntranceConsts.KEY_CATALOG_TITLE to mCategoryTitle, - EntranceConsts.KEY_EXPOSURE_SOURCE to arguments?.getParcelable(EntranceConsts.KEY_EXPOSURE_SOURCE), + EntranceConsts.KEY_EXPOSURE_SOURCE_LIST to arguments?.getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST), EntranceConsts.KEY_LAST_PAGE_DATA to mLastPageDataMap ) childFragmentManager @@ -391,7 +391,7 @@ class CategoryV2Fragment : LazyFragment() { EntranceConsts.KEY_CATEGORY_ID to id, EntranceConsts.KEY_SUB_CATEGORY_ID to sidebars[position].categoryId, EntranceConsts.KEY_CATALOG_TITLE to mCategoryTitle, - EntranceConsts.KEY_EXPOSURE_SOURCE to arguments?.getParcelable(EntranceConsts.KEY_EXPOSURE_SOURCE), + EntranceConsts.KEY_EXPOSURE_SOURCE_LIST to arguments?.getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST), EntranceConsts.KEY_LAST_PAGE_DATA to mLastPageDataMap ) } @@ -413,7 +413,7 @@ class CategoryV2Fragment : LazyFragment() { EntranceConsts.KEY_CATEGORY_ID to id, EntranceConsts.KEY_SUB_CATEGORY_ID to sidebars[position].categoryId, EntranceConsts.KEY_CATALOG_TITLE to mCategoryTitle, - EntranceConsts.KEY_EXPOSURE_SOURCE to arguments?.getParcelable(EntranceConsts.KEY_EXPOSURE_SOURCE), + EntranceConsts.KEY_EXPOSURE_SOURCE_LIST to arguments?.getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST), EntranceConsts.KEY_LAST_PAGE_DATA to mLastPageDataMap ) } diff --git a/app/src/main/java/com/gh/gamecenter/category2/CategoryV2ListAdapter.kt b/app/src/main/java/com/gh/gamecenter/category2/CategoryV2ListAdapter.kt index 36459ce123..d612c7b9c3 100644 --- a/app/src/main/java/com/gh/gamecenter/category2/CategoryV2ListAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/category2/CategoryV2ListAdapter.kt @@ -110,7 +110,9 @@ class CategoryV2ListAdapter( val sortSize = mViewModel.sortSize.text val exposureSources = ArrayList() - mViewModel.exposureSource?.let { exposureSources.add(it) } + if (!mViewModel.exposureSourceList.isNullOrEmpty()) { + exposureSources.addAll(mViewModel.exposureSourceList!!) + } exposureSources.add(ExposureSource("分类", categoryTitle)) exposureSources.add(ExposureSource(selectedCategoryName)) exposureSources.add(ExposureSource("二级分类详情", "$selectedSubCatalogName+$sortType+$sortSize")) diff --git a/app/src/main/java/com/gh/gamecenter/category2/CategoryV2ListFragment.kt b/app/src/main/java/com/gh/gamecenter/category2/CategoryV2ListFragment.kt index c0ba61b88f..dee785e6b3 100644 --- a/app/src/main/java/com/gh/gamecenter/category2/CategoryV2ListFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/category2/CategoryV2ListFragment.kt @@ -4,9 +4,7 @@ import android.os.Bundle import android.view.View import android.view.ViewGroup import com.ethanhua.skeleton.Skeleton -import com.gh.gamecenter.common.constant.Constants import com.gh.common.exposure.ExposureListener -import com.gh.common.util.* import com.gh.common.util.DialogUtils import com.gh.common.view.CategoryFilterView import com.gh.common.xapk.XapkInstaller @@ -14,6 +12,7 @@ import com.gh.common.xapk.XapkUnzipStatus import com.gh.download.DownloadManager import com.gh.gamecenter.R import com.gh.gamecenter.baselist.ListFragment +import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.databinding.FragmentCategoryListBinding @@ -57,7 +56,7 @@ class CategoryV2ListFragment : ListFragment viewModelProvider(CategoryV2ListViewModel.Factory( mCategoryId, mSubCategoryId, - arguments?.getParcelable(EntranceConsts.KEY_EXPOSURE_SOURCE))) + arguments?.getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST))) override fun provideListAdapter() = mAdapter ?: CategoryV2ListAdapter( diff --git a/app/src/main/java/com/gh/gamecenter/category2/CategoryV2ListViewModel.kt b/app/src/main/java/com/gh/gamecenter/category2/CategoryV2ListViewModel.kt index 10c19a6b3b..afc2bce771 100644 --- a/app/src/main/java/com/gh/gamecenter/category2/CategoryV2ListViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/category2/CategoryV2ListViewModel.kt @@ -20,7 +20,7 @@ import io.reactivex.Single class CategoryV2ListViewModel(application: Application, val categoryId: String, var categoryIds: String, - var exposureSource: ExposureSource?) : ListViewModel(application) { + var exposureSourceList: List?) : ListViewModel(application) { val refresh = MutableLiveData() @@ -85,13 +85,13 @@ class CategoryV2ListViewModel(application: Application, } } - class Factory(val categoryId: String, val categoryIds: String, val exposureSource: ExposureSource?): ViewModelProvider.NewInstanceFactory() { + class Factory(val categoryId: String, val categoryIds: String, val exposureSourceList: List?): ViewModelProvider.NewInstanceFactory() { override fun create(modelClass: Class): T { return CategoryV2ListViewModel( HaloApp.getInstance().application, categoryId, categoryIds, - exposureSource + exposureSourceList ) as T } } diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailContentCardContentAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailContentCardContentAdapter.kt new file mode 100644 index 0000000000..70a10a569e --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailContentCardContentAdapter.kt @@ -0,0 +1,46 @@ +package com.gh.gamecenter.gamedetail + +import android.content.Context +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.gh.gamecenter.R +import com.gh.gamecenter.common.utils.safelyGetInRelease +import com.gh.gamecenter.common.utils.toBinding +import com.gh.gamecenter.common.utils.toColor +import com.gh.gamecenter.core.utils.TimeUtils +import com.gh.gamecenter.databinding.ItemGameDetailContentCardContentBinding +import com.gh.gamecenter.gamedetail.entity.ContentCardEntity +import com.lightgame.adapter.BaseRecyclerAdapter + +class GameDetailContentCardContentAdapter(context: Context, private val linkEntity: ContentCardEntity, private val isHighlightBg: Boolean = false): BaseRecyclerAdapter(context) { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder = GameDetailContentCardContentItemViewHolder(parent.toBinding()) + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + if (holder is GameDetailContentCardContentItemViewHolder) { + holder.binding.root.setTextColor(if (isHighlightBg) R.color.text_subtitle.toColor(mContext) else R.color.text_subtitleDesc.toColor(mContext)) + if (linkEntity.type == "func_server" && linkEntity.server != null && linkEntity.server?.calendar?.isNotEmpty() == true) { + val calendarList = linkEntity.server!!.calendar.take(10) + val realPosition = position % calendarList.size + calendarList.safelyGetInRelease(realPosition)?.let { + val serverTime = + if (TimeUtils.isToday(it.getTime())) + it.getFormatTime("今天 HH:mm") + else if (TimeUtils.isTomorrow(it.getTime())) + it.getFormatTime("明天 HH:mm") + else + it.getFormatTime("MM-dd HH:mm") + val serverText = "$serverTime ${it.remark}" + holder.binding.root.text = serverText + } + } + if (linkEntity.type == "func_libao" && linkEntity.libao != null) { + holder.binding.root.text = "${linkEntity.libao!!.total}个游戏礼包" + } + } + } + + override fun getItemCount(): Int = Int.MAX_VALUE + + class GameDetailContentCardContentItemViewHolder(var binding: ItemGameDetailContentCardContentBinding) : RecyclerView.ViewHolder(binding.root) +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt index 5804ea8272..242f470faa 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt @@ -1,19 +1,22 @@ package com.gh.gamecenter.gamedetail +import android.animation.Animator +import android.animation.ValueAnimator import android.annotation.SuppressLint import android.content.Intent import android.graphics.Bitmap import android.graphics.Canvas import android.graphics.Color import android.graphics.drawable.GradientDrawable -import android.os.Build -import android.os.Bundle +import android.os.* import android.text.SpannableStringBuilder import android.text.Spanned import android.text.TextUtils import android.view.* +import android.view.animation.AccelerateDecelerateInterpolator import android.widget.FrameLayout import android.widget.ImageView +import android.widget.LinearLayout import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.constraintlayout.widget.ConstraintLayout @@ -23,11 +26,13 @@ import androidx.core.view.children import androidx.core.widget.TextViewCompat import androidx.fragment.app.Fragment import androidx.lifecycle.Observer +import androidx.viewpager2.widget.ViewPager2 import com.ethanhua.skeleton.Skeleton import com.ethanhua.skeleton.ViewSkeletonScreen import com.gh.common.constant.Config import com.gh.common.databind.BindingAdapters import com.gh.common.exposure.ExposureEvent +import com.gh.common.exposure.ExposureSource import com.gh.common.repository.ReservationRepository import com.gh.common.simulator.SimulatorGameManager import com.gh.common.util.* @@ -57,8 +62,10 @@ import com.gh.gamecenter.gamedetail.desc.DescFragment import com.gh.gamecenter.gamedetail.dialog.GameBigEventDialog import com.gh.gamecenter.gamedetail.dialog.GameDetailMoreDialog import com.gh.gamecenter.gamedetail.dialog.GameTagsDialog +import com.gh.gamecenter.gamedetail.entity.ContentCardEntity import com.gh.gamecenter.gamedetail.entity.NewGameDetailEntity import com.gh.gamecenter.gamedetail.fuli.FuLiFragment +import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersCalendarActivity import com.gh.gamecenter.gamedetail.rating.RatingFragment import com.gh.gamecenter.gamedetail.video.TopVideoView import com.gh.gamecenter.home.video.ScrollCalculatorHelper @@ -84,6 +91,7 @@ import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode import retrofit2.HttpException +import java.lang.ref.WeakReference import java.util.* import kotlin.math.abs @@ -116,6 +124,8 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { private var mRecommendDisposable: Disposable? = null private var mRecommendPopupEntity: RecommendPopupEntity? = null private var mTabClickEvent: Pair = Pair(0L, "") + private var mContentCardServerVp: ViewPager2? = null + private var mContentCardLibaoVp: ViewPager2? = null private lateinit var mBinding: FragmentGamedetailBinding private lateinit var mVideoBinding: PieceGameDetailVideoBinding @@ -129,6 +139,9 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { private val mFragmentsList = ArrayList() private val mTabTitleList = ArrayList() + private val mLooperHandle = LooperHandle(this) + private val mServerLooperKey = 123 + private val mLibaoLooperKey = 124 private val dataWatcher = object : DataWatcher() { override fun onDataChanged(downloadEntity: DownloadEntity) { @@ -203,6 +216,66 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { mTraceEvent ) + private val contentCardClick: (contentCard: ContentCardEntity) -> Unit = { contentCardEntity -> + NewFlatLogUtils.logGameDetailGameContentCardClick(contentCardEntity.title ?: "", mGameEntity?.name ?: "", mGameEntity?.id ?: "", contentCardEntity.type ?: "", contentCardEntity.link ?: "", contentCardEntity.text ?: "") + when (contentCardEntity.type) { + "func_server" -> { + if (contentCardEntity.server != null) { + requireContext().startActivity( + ServersCalendarActivity.getIntent( + requireContext(), + mViewModel.game!!, contentCardEntity.server!!, + mNewGameDetailEntity?.me + ) + ) + } + } + "func_libao" -> { + tabPerformClick(0) + mBodyBinding.gamedetailAppbar.setExpanded(false, true) + val fragment = mFragmentsList[0] + if (fragment is DescFragment && fragment.isAdded) { + fragment.scrollToLibao() + } + } + "func_related_version" -> { + tabPerformClick(0) + mBodyBinding.gamedetailAppbar.setExpanded(false, true) + val fragment = mFragmentsList[0] + if (fragment is DescFragment && fragment.isAdded) { + fragment.scrollToRelatedVersion() + } + } + "func_zone" -> { + val gameDetailEntity = mViewModel.gameDetailLiveData.value?.data + if (contentCardEntity.zoneTab && gameDetailEntity?.zone != null && gameDetailEntity.zone!!.style == "link") { + requireContext().startActivity(WebActivity.getIntent(requireContext(), gameDetailEntity.zone!!.link, true)) + } + } + "func_tool_kit" -> { + if (contentCardEntity.toolkit.isNotEmpty()) { + contentCardEntity.toolkit.safelyGetInRelease(0)?.let { + val url = it.url + if (url != null && url.contains(Config.URL_ARTICLE)) { + val newsId = url.substring(url.lastIndexOf("/") + 1, url.length - 5) // 5: ".html" + val intent = NewsDetailActivity.getIntentById(requireContext(), newsId, "游戏详情->内容卡片") + requireContext().startActivity(intent) + } else { + requireContext().startActivity( + WebActivity.getWebByCollectionTools( + requireContext(), + it, + false + ) + ) + } + } + } + } + else -> DirectUtils.directToLinkPage(requireContext(), contentCardEntity.toLinkEntity(), mEntrance, "游戏详情->内容卡片", ExposureEvent.createEvent(null, listOf(ExposureSource("游戏详情", mGameEntity?.id ?: ""), ExposureSource("内容卡片", contentCardEntity.id)))) + } + } + override fun getLayoutId(): Int = 0 override fun getInflatedLayout(): View { @@ -443,7 +516,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { var changeDisplayName = false if ((lineCount == 2 && layout.getEllipsisCount(1) > 0) || (lineCount == 2 && tagView.measuredWidth > remainWidth)) { val textCount = calculateTextCountByWidth(this, 2 * gameTitleTv.width - tagView.measuredWidth) - 1 - if (textCount < text.length) { + if (textCount in text.indices) { displayName = text.substring(0, textCount) + "…" changeDisplayName = true } @@ -576,6 +649,11 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { showAlertDialogIfNeeded(data) initViewPage(data) + + if (data.contentCard.size > 1) { + initGameContentCard(data.contentCard) + } + updateGameDetailTopArea() val viewHolder = detailViewHolder @@ -701,6 +779,9 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { mTabTitleList.add(getString(R.string.game_detail_desc)) data.zone?.let { + data.contentCard.forEach { contentCard -> + if (data.contentCard.size > 1 && contentCard.type == "func_zone") return@let + } if (it.style == "link") {//显示web页面 val webFragment = childFragmentManager.findFragmentByTag("${tag}${INDEX_TRENDES}") ?: WebFragment() val webBundle = Bundle() @@ -959,6 +1040,103 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { } } + private fun initGameContentCard(linkEntityList: List) { + mBodyBinding.contentCardContainer.removeAllViews() + mBodyBinding.contentCardContainer.visibility = View.VISIBLE + if (linkEntityList.size >= 3) { + linkEntityList.safelyGetInRelease(0)?.let { + mBodyBinding.contentCardContainer.addView(getLargeContentCardView(it, true), LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 2F)) + } + linkEntityList.safelyGetInRelease(1)?.let { + mBodyBinding.contentCardContainer.addView(getSmallContentCardView(it), LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1F)) + } + linkEntityList.safelyGetInRelease(2)?.let { + mBodyBinding.contentCardContainer.addView(getSmallContentCardView(it, true), LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1F)) + } + } else if (linkEntityList.size == 2) { + linkEntityList.safelyGetInRelease(0)?.let { + mBodyBinding.contentCardContainer.addView(getLargeContentCardView(it), LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1F)) + } + linkEntityList.safelyGetInRelease(1)?.let { + mBodyBinding.contentCardContainer.addView(getLargeContentCardView(it, isLastView = true), LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1F)) + } + } + } + + private fun getLargeContentCardView(contentCardEntity: ContentCardEntity, isHighlightBg: Boolean = false, isLastView: Boolean = false) = LayoutGameDetailContentCardLargeBinding.inflate(layoutInflater).apply { + when { + isHighlightBg && !isLastView -> backgroundIv.setImageDrawable(R.drawable.bg_content_card_large_primary.toDrawable(requireContext())) + !isHighlightBg && !isLastView -> backgroundIv.setImageDrawable(R.drawable.bg_content_card_large.toDrawable(requireContext())) + !isHighlightBg && isLastView -> backgroundIv.setImageDrawable(R.drawable.bg_content_card_large_right.toDrawable(requireContext())) + } + spaceStart.layoutParams = spaceStart.layoutParams.apply { width = if (isLastView) 20F.dip2px() else 12F.dip2px()} + spaceEnd.layoutParams = spaceEnd.layoutParams.apply { width = if (isLastView) 8F.dip2px() else 12F.dip2px()} + titleTv.text = contentCardEntity.title + ImageUtils.display(iconIv, contentCardEntity.icon) + if (contentCardEntity.des.isNotEmpty()) { + contentTv.visibility = View.VISIBLE + contentVp.visibility = View.GONE + contentTv.text = contentCardEntity.des + contentTv.setTextColor(if (isHighlightBg) R.color.text_subtitle.toColor(requireContext()) else R.color.text_subtitleDesc.toColor(requireContext())) + } else if (contentCardEntity.type == "func_server" || contentCardEntity.type == "func_libao") { + contentTv.visibility = View.GONE + contentVp.visibility = View.VISIBLE + if (contentCardEntity.type == "func_server") mContentCardServerVp = contentVp else mContentCardLibaoVp = contentVp + contentVp.run { + isUserInputEnabled = false + orientation = ViewPager2.ORIENTATION_VERTICAL + adapter = GameDetailContentCardContentAdapter(requireContext(), contentCardEntity, isHighlightBg) + startAutoPlay(if (contentCardEntity.type == "func_server") mServerLooperKey else mLibaoLooperKey) + } + } + redDotTv.goneIf(!(contentCardEntity.type == "func_server" || contentCardEntity.type == "func_libao")) + if ((contentCardEntity.type == "func_server") && (contentCardEntity.server?.calendar?.isNotEmpty() == true)) redDotTv.text = contentCardEntity.server?.calendar?.size.toString() + if ((contentCardEntity.type == "func_libao") && (contentCardEntity.libao != null)) redDotTv.text = contentCardEntity.libao?.total.toString() + root.setOnClickListener { + contentCardClick.invoke(contentCardEntity) + } + }.root + + private fun getSmallContentCardView(contentCardEntity: ContentCardEntity, isLastView: Boolean = false) = LayoutGameDetailContentCardSmallBinding.inflate(layoutInflater).apply { + backgroundIv.setImageDrawable(if (isLastView) R.drawable.bg_content_card_small_right.toDrawable(requireContext()) else R.drawable.bg_content_card_small.toDrawable(requireContext())) + titleTv.text = contentCardEntity.title + ImageUtils.display(iconIv, contentCardEntity.icon) + redDotTv.goneIf(!(contentCardEntity.type == "func_server" || contentCardEntity.type == "func_libao")) + if ((contentCardEntity.type == "func_server") && (contentCardEntity.server?.calendar?.isNotEmpty() == true)) redDotTv.text = contentCardEntity.server?.calendar?.size.toString() + if ((contentCardEntity.type == "func_libao") && (contentCardEntity.libao != null)) redDotTv.text = contentCardEntity.libao?.total.toString() + root.setOnClickListener { + contentCardClick.invoke(contentCardEntity) + } + }.root + + private fun scrollToNextContent(viewPager: ViewPager2? = null) { + viewPager?.run { + val pxToDrag: Int = height + val animator = ValueAnimator.ofInt(0, pxToDrag) + var previousValue = 0 + animator.addUpdateListener { valueAnimator -> + val currentValue = valueAnimator.animatedValue as Int + val currentPxToDrag = (currentValue - previousValue).toFloat() + fakeDragBy(-currentPxToDrag) + previousValue = currentValue + } + animator.addListener(object : Animator.AnimatorListener { + override fun onAnimationStart(animation: Animator?) { beginFakeDrag() } + override fun onAnimationEnd(animation: Animator?) { endFakeDrag() } + override fun onAnimationCancel(animation: Animator?) { } + override fun onAnimationRepeat(animation: Animator?) { } + }) + animator.interpolator = AccelerateDecelerateInterpolator() + animator.duration = 1000 + animator.start() + } + } + + private fun startAutoPlay(key: Int) { + mLooperHandle.removeMessages(key) + mLooperHandle.sendEmptyMessageDelayed(key, CONTENT_CARD_LOOP_TIME) + } + private fun setUpTopVideo(topVideo: GameDetailEntity.Video) { GSYVideoOptionBuilder() .setIsTouchWigetFull(false) @@ -1643,6 +1821,11 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { } mBinding.detailLlBottom.detailLlBottom.setBackgroundColor(R.color.background.toColor(requireContext())) updateToolbarStyle(mBodyBinding.gamedetailThumbSmall.visibility == View.VISIBLE) + mViewModel.gameDetailLiveData.value?.data?.let { + if (it.contentCard.size > 1) { + initGameContentCard(it.contentCard) + } + } } override fun scrollToTop() { @@ -1667,8 +1850,27 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { const val SCROLL_TO_KAIFU = "scrollToKaiFu" const val EB_SCROLLING = "EB_SCROLLING" const val INITIAL_DELAY = 500L + const val CONTENT_CARD_LOOP_TIME = 3000L private const val SP_OPENED_DIALOG_TIME_PREFIX = "opened_dialog_time_prefix_" private const val LAST_SELECTED_POSITION = "last_selected_position" } + + class LooperHandle(fragment: GameDetailFragment): Handler( + Looper.getMainLooper()) { + private val mWeakReference: WeakReference = WeakReference(fragment) + + override fun handleMessage(msg: Message) { + super.handleMessage(msg) + val fragment = mWeakReference.get() + if (fragment != null) { + if (msg.what == fragment.mServerLooperKey) { + fragment.scrollToNextContent(fragment.mContentCardServerVp) + } else if (msg.what == fragment.mLibaoLooperKey) { + fragment.scrollToNextContent(fragment.mContentCardLibaoVp) + } + fragment.startAutoPlay(msg.what) + } + } + } } diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt index a86ba4a5fd..7a7e4410c3 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt @@ -127,6 +127,18 @@ class GameDetailViewModel(application: Application, // 4.4以下设备不显示顶部视频 displayTopVideo = data.topVideo != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT + + data.contentCard.forEach { + if (data.contentCard.size > 1 && it.type == "func_server") { + data.detailEntity.forEach detail@{ detailEntity -> + if (detailEntity.type == DetailEntity.Type.LATEST_SERVER.value) { + data.detailEntity.remove(detailEntity) + return@detail + } + } + } + } + gameDetailLiveData.postValue(Resource.success(data)) if (CheckLoginUtils.isLogin()) { getUserRelatedInfo(data) diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescAdapter.kt index ab25b5c479..8c2186c235 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescAdapter.kt @@ -26,15 +26,14 @@ import com.gh.common.databind.BindingAdapters import com.gh.common.exposure.ExposureEvent import com.gh.common.exposure.ExposureManager import com.gh.common.exposure.ExposureSource +import com.gh.common.util.* import com.gh.common.util.DialogUtils -import com.gh.common.util.DirectUtils import com.gh.common.util.LogUtils import com.gh.common.util.NewLogUtils import com.gh.gamecenter.GameNewsActivity import com.gh.gamecenter.R import com.gh.gamecenter.SuggestionActivity import com.gh.gamecenter.adapter.viewholder.FooterViewHolder -import com.gh.gamecenter.common.base.activity.BaseActivity import com.gh.gamecenter.common.callback.OnListClickListener import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.utils.* @@ -966,8 +965,11 @@ class DescAdapter( } } - class GameDetailCustomColumnViewHolder(var binding: GamedetailItemCustomColumnBinding, handler: Handler) : - ExposureViewHolder(binding.root, handler) + inner class GameDetailCustomColumnViewHolder(var binding: GamedetailItemCustomColumnBinding, handler: Handler) : ExposureViewHolder(binding.root, handler) { + override fun exposureLog() { + NewFlatLogUtils.logGameDetailColumnOrderingView(binding.titleTv.text.toString(), mViewModel.game?.name ?: "", mViewModel.game?.id ?: "") + } + } class GameDetailRelatedVersionViewHolder(var binding: GameGalleryListBinding, handler: Handler) : ExposureViewHolder(binding.root, handler) class GameVideoGalleryViewHolder(var binding: GameGalleryListBinding, handler: Handler) : ExposureViewHolder(binding.root, handler) diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescFragment.kt index 63941da7c3..679fa5e95f 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescFragment.kt @@ -270,6 +270,18 @@ class DescFragment : BaseFragment(), IScrollable { } } + fun scrollToRelatedVersion() { + if (mViewModel.getRelatedVersionPosition() != -1) { + mLayoutManager?.scrollToPositionWithOffset(mViewModel.getRelatedVersionPosition(), 0) + } + } + + fun scrollToLibao() { + if (mViewModel.getDetailLibaoPosition() != -1) { + mLayoutManager?.scrollToPositionWithOffset(mViewModel.getDetailLibaoPosition(), 0) + } + } + override fun onNightModeChange() { super.onNightModeChange() mBinding.recyclerview.setBackgroundColor(R.color.background.toColor(requireContext())) diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescViewModel.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescViewModel.kt index e9c4784768..b2eb183847 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/desc/DescViewModel.kt @@ -43,6 +43,8 @@ class DescViewModel(application: Application, private var mGameInfoPosition = 0 private var mLibaoPosition = -1 private var mServerPosition = -1 + private var mDetailLibaoPosition = -1 + private var mRelatedVersionPosition = -1 private var mGameInfo: GameInfo? = null var list = MutableLiveData>() @@ -360,6 +362,15 @@ class DescViewModel(application: Application, } } + for ((index, entity) in detailEntityList.withIndex()) { + if (entity.libao != null) { + mDetailLibaoPosition = index + } + if (entity.relatedVersion != null) { + mRelatedVersionPosition = index + } + } + if (containsFirstTimeExpandCustomColumnTags) { SPUtils.setBoolean(Constants.SP_HAS_EXPANDED_GAME_DETAIL_TAGS, true) } @@ -375,6 +386,10 @@ class DescViewModel(application: Application, fun getGameInfoPosition() = mGameInfoPosition + fun getDetailLibaoPosition() = mDetailLibaoPosition + + fun getRelatedVersionPosition() = mRelatedVersionPosition + fun getGameInfo() = mGameInfo /** diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/entity/ContentCardEntity.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/entity/ContentCardEntity.kt new file mode 100644 index 0000000000..21f1485e49 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/entity/ContentCardEntity.kt @@ -0,0 +1,69 @@ +package com.gh.gamecenter.gamedetail.entity + +import com.gh.gamecenter.entity.* +import com.google.gson.annotations.SerializedName + +data class ContentCardEntity( + @SerializedName("_id") + var id: String = "", + var name: String? = "", // tag + var title: String? = "", + var image: String? = "", + @SerializedName("target", alternate = ["link", "link_id"]) + var link: String? = "", + @SerializedName("type", alternate = ["link_type"]) + var type: String? = "", + var icon: String = "", + @SerializedName("game_icon") + var gameIcon: String? = "", + @SerializedName("game_icon_subscript") + var gameIconSubscript: String? = "", + var text: String? = "", + @SerializedName("link_text") + var linkText: String? = "",//游戏详情弹窗,兼容旧版本用 + var value: String? = "", + @SerializedName("community_id") + var communityId: String? = "", + @SerializedName("link_community", alternate = ["community"]) + var community: CommunityEntity? = CommunityEntity(), + var display: Display? = null, // 板块 + @SerializedName("close_button") + var closeButton: String = "open",//用户判断h5游戏关闭按钮是否显示,hide(隐藏)、open(开启) + @SerializedName("button_link") + var buttonLink: Boolean = false, + @SerializedName("activity_id") + var activityId: String = "", + var style: String = "", + + var des: String = "", + var server: GameDetailServer? = null, + var libao: LibaoEntity? = null, + @SerializedName("zone_tab") + var zoneTab: Boolean = false, + @SerializedName("related_version") + var relatedVersion: Boolean = false, + var toolkit: ArrayList = ArrayList() +) { + fun toLinkEntity(): LinkEntity { + return LinkEntity( + name = name, + title = title, + image = image, + link = link, + type = type, + icon = icon, + gameIcon = gameIcon, + gameIconSubscript = gameIconSubscript, + text = text, + linkText = linkText, + value = value, + communityId = communityId, + community = community, + display = display, + closeButton = closeButton, + buttonLink = buttonLink, + activityId = activityId, + style = style + ) + } +} diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/entity/NewGameDetailEntity.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/entity/NewGameDetailEntity.kt index 1bdd9cb435..bcd5b27511 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/entity/NewGameDetailEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/entity/NewGameDetailEntity.kt @@ -45,7 +45,9 @@ data class NewGameDetailEntity( @SerializedName("bbs_tab") var bbsTab: LinkEntity? = null, @SerializedName("certification_tag") - var certificateTag: Screenshot? = null + var certificateTag: Screenshot? = null, + @SerializedName("content_card") + var contentCard: ArrayList = ArrayList() ) @Keep diff --git a/app/src/main/java/com/gh/gamecenter/subject/SubjectAdapter.kt b/app/src/main/java/com/gh/gamecenter/subject/SubjectAdapter.kt index e2943488dc..a65df62988 100644 --- a/app/src/main/java/com/gh/gamecenter/subject/SubjectAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/subject/SubjectAdapter.kt @@ -312,7 +312,9 @@ class SubjectAdapter( private fun generateExposureEvent(gameEntity: GameEntity, subjectStyle: String, isFilterOn: Boolean): ExposureEvent { val exposureSourceList = arrayListOf() - mViewModel.exposureSource?.let { exposureSourceList.add(it) } + if (!mViewModel.exposureSourceList.isNullOrEmpty()) { + exposureSourceList.addAll(mViewModel.exposureSourceList!!) + } if (mIsColumnCollection) { exposureSourceList.add(ExposureSource("排行榜")) exposureSourceList.add(ExposureSource("专题", subjectData.subjectName.toString())) diff --git a/app/src/main/java/com/gh/gamecenter/subject/SubjectListFragment.kt b/app/src/main/java/com/gh/gamecenter/subject/SubjectListFragment.kt index 7fabb2fdb1..9642304e6a 100644 --- a/app/src/main/java/com/gh/gamecenter/subject/SubjectListFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/subject/SubjectListFragment.kt @@ -77,7 +77,7 @@ class SubjectListFragment : LazyListFragment() val factory = SubjectListViewModel.Factory( HaloApp.getInstance().application, arguments?.getParcelable(EntranceConsts.KEY_SUBJECT_DATA)!!, - arguments?.getParcelable(EntranceConsts.KEY_EXPOSURE_SOURCE)) + arguments?.getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST)) if (requireContext() is SubjectActivity) { requireActivity().intent.getParcelableExtra(EntranceConsts.KEY_SUBJECT_DATA)?.let { val f = SubjectViewModel.Factory(HaloApp.getInstance().application, it) diff --git a/app/src/main/java/com/gh/gamecenter/subject/SubjectListViewModel.kt b/app/src/main/java/com/gh/gamecenter/subject/SubjectListViewModel.kt index 9016c9b951..f74d606fcb 100644 --- a/app/src/main/java/com/gh/gamecenter/subject/SubjectListViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/subject/SubjectListViewModel.kt @@ -23,7 +23,7 @@ import retrofit2.HttpException class SubjectListViewModel(application: Application, var subjectData: SubjectData, - var exposureSource: ExposureSource?) : ListViewModel(application) { + var exposureSourceList: List?) : ListViewModel(application) { // 供专题类型为 rows 时统计用 var selectedLabelList = arrayListOf() @@ -104,9 +104,9 @@ class SubjectListViewModel(application: Application, } } - class Factory(private val mApplication: Application, private val subjectData: SubjectData, private val exposureSource: ExposureSource? = null) : ViewModelProvider.NewInstanceFactory() { + class Factory(private val mApplication: Application, private val subjectData: SubjectData, private val exposureSourceList: List? = null) : ViewModelProvider.NewInstanceFactory() { override fun create(modelClass: Class): T { - return SubjectListViewModel(mApplication, subjectData, exposureSource) as T + return SubjectListViewModel(mApplication, subjectData, exposureSourceList) as T } } diff --git a/app/src/main/res/drawable-night-xxxhdpi/bg_content_card_large.webp b/app/src/main/res/drawable-night-xxxhdpi/bg_content_card_large.webp new file mode 100644 index 0000000000000000000000000000000000000000..9f0fe20aa9ae7d6273dff56c06bac7613d168ba2 GIT binary patch literal 956 zcmWIYbaUIn%)k)t>J$(bU=hK^z`!5?#QjVR_Zb)*eF8lEm>3us^A!X+rBu zvAliH<5d35#|I~!+`!~r%b(K8J)@*4uGuGT=Jb~w)1EQOD5OtQd;ZSKx7`2go4CKL zJO24MaBZ zTFtz_?yP)+-?}++40XFc&0BD=>jcxn+=;814+TE4cJ_Rt@9dh!d^q%6;+E!%SBL6v0Nns3}!uV)GpN$)za`(iAE4W>KWkY+o+$0yb1Rl{?q1-?5@QI`pjaN>A z!S14qn*xt%B#Ibvy*iQn#9)(zWY?~MD^~)Ku1J_-=q2IW(`5BY!m>xlt!h-qnv zp_W8ykC2<-;^AfdsTr!~m1mk}n>^DuFFYfkcW6fZot*xk$9iQqH~UWCSe!Gj$7;(G zwf;%>ue21tU$OD=vkNv8ImOS+neoWhI68Qa^RiP*_IG}~e5P@w(MR{VKOvi0b(g1n zveemrw&WAT)U;H6{Xfs2Oq#fN?%k@k6RX>gr)B}unSui&1A~Dg!(2wK2}}=w>5V~k z>F(CMExED>Cm);bLMh7Pd}+AsA_}^oerBG@Ej0wXZF1|&PZZ0}_RTk{xSTNq54svQ zcT4g!f2mwy7?NLGRde#O@1kTFiV$~P%Z98%SgL6MwjNYP9T)p&+GK9=fuq!22i~=kgTGlCN>ZdFgAE%35Q5H;tzZ>1#!_Ysv*$c z$G^1`k=v{0j7T@P!l|X9qYuM}0b)Ten2lDWth?}Sd?;jQVBkC1o;#EKA@6=tA^~xH z2*Yd+^$C2|uitXWq$E@livC1gsVFwq$rMNhH%8z7HZrL+GO5;5-Pg(AUn_n+@cz`u zVLq0|%FcX}K~&StBr>TaQEPdIVQEnPuurLs-Y9sR-Hn&B=~mn9l#+8H%tI>pd-h+I zfhkV?sX2;<7P=NP%G!8>v@jA7oElr9EQN2PmzVdsez@jqcev%2wJbOa{D1_aZ(~Ej zN~Z~>GFe)A(mkGX=D`}UT8JDrG^AETbWB8h3EZXwN@VS1F(7E7 zTad%F?!qnb-Jh?a-%;47&+N_ZkFD`VamJ9R+liER_iqC22+T6OW(_xZcy2}#L*F`j z*ej>N#yl2`R$+E8dD^fkd;gE;+jqkE(3^`^0}Bhrs(g8sHb6YDoYj<)>}9_!NmdFd z2}-2BoLA3wJh;r>YoFimYlG8?dEcNHBkpiK4JyE4bK98K?z~|5`}};7`H^?S09J9>J7&i6$Wz(sZs-Alar;D5 z!fRcILsk_gsUGBFPW7YiN(nBRjB?I@E z8_ZJ;4_ImrZyc2_Q)gBIwYbQu?Jd$+XbxX=pC1n8W&V+u2KN?GI(Xg+y2ZuLi0knI zKJ0EBsh>7!+}JLu^Nof+&v1Y?-6J%yw#LODq=PH=)RWN5{l*g;Gnich}sAp){Q z1%qjI53yJX_%La{-Js;XLsbM#oDBr{I&>S1EqgL8!4aS`>=<5uxgr0{q_4hMh!-zX zGQ~|`2`Y|%7&|0OY)W?wg0L5p+=xH*s#B?kxO&|i9m)(j4Z zkOSsKiQ!*&AQD*6Y(K}2FlmW^!K4FJY?_iQRT({dLC+9PRb<8v^wn^aQPZZHF2@};~tQM`ND8{&HrqjoPL!B-1c=^k?N z;|qI;Dw33RW6nd?sjFp#S2ZX*yB2j}*=QD6ZXXP3WuVZbF zPC>8iGxIkr!9fZ;gMBTeN-brn+jl?*DdJ^PfGl{pFL*l$$X7n_I-x9o{ciI(?w^w+ zAJU}S(Zj8Nq^VkN#J$5npgwl5a5NNcm&mRQ!DCRslRU@*$x~QlM6pR2>@N9;9z3s* zCkwr*3Fguo;@lAR(&!(dg4KKVHB)$3X2r128NT{yO29wFg8EzR*d*xq6A;~V=}j7@ z6Bl;UN|}9uvlNH5gVUW9{o6|p=`0gRZnxHyRZX?Rl7<%wK@O)|;BAlW=m@dWQPNHn zNnGJvtT@vEm!RSXyI_IvXW|oSK!>I=9rQxf3Vz)eaM)EVdYrE}&aH3#3(CD{9N^26L zIKC|xbGSs#vOVq1mxMdmKxDRvgAO^>HZnNqq2W7Rw;k9-V0dy|-`>Es#-S zzeWi!)9S7DD#3HsZTjPpf$tr^3A?KrTK?@Io_m38MS^5l~|TPL634VjDJuWTkDyk;9O#f~#fSK|xzD z=&$TiLg6vkO2P{_6JA4i+a%5UI$UQM{*3h6Fc-6u;_0l39hRmEslf*vP!7&i=kKR> zsejs<46I$9M-L)g=x0o`Wtw*D+{GfsBLD_gokSv);Y6Su(hO6XjO0%*`>g$Qaa9SuU%mwo+#0DUit+LQj zvI9pP6sZb)E%|pTnq*G0c!0rB-HbVh0aUjCzgHJbxzj-@57~@Ya3?AF%*LDs`w4jJ zZIY_>e__qt1)y+{29!Pj8aYC*HX4EOnlZu#0*D60$Vibh8R1)IwEo;j#Cu?p10s82Tf3w{j)4bw%czjg9$(abgE@j*VuYGh zMhGMWn6HHZkL(Qal%fbZhVrwR8S{35;&~_Y+_!$3HV$cF`c}WzAUN7#Bbs@kbT=HO zMu0WPmbZ4T2PDayAXD%PH9M%W%grv@E$i>(S%F`VzU9$$1OLm=2J_X+0(HxbJn9^O zFDJ-R$SHHKHtdh`jA>QjY%dt1cijHTEADUCXk1I z*|BwfPOC%PCeQ1;nip;qdQ~XPJP!ogMyVOBfT zm7g}k8LS^@=A8J3P=WgBRDG&f@wX^+xbxTGc^$O*_=tkxdN3lR0HLOO_w46SG^{aa>Z1Ebx5n}7xt0}++z zenYHuM?U<*#NIWHwoFl_(BiAcZwjk46N41(;}gA zHYd*T87GbtL+wT=qiTaS#W|y{5WXQNg`P9EukS|%-nf3aYhMUrMCvsHnIk~1(;ixbS*Fn`)HXw}90jjf<)d1&T{_G* z(sUBB1rp+tM3RT2x5_wu!s=jnjey}+rJ)3OftnMTyg9Mom~s1bNfa0G6;La^YUEEh zE$`kipMm@d$J)H5x3tV|dk9&_tlb-#0xpeYa2?78)_>g;qC#CjV{J` zRgDw+?{xJ(z-r+%k+U(aNtbU>Dwf9Z@lcbs6HiU&2 zis>iAx%2=D4fc2)PC>bpi7nX>f>ujJ|M4DG6Eyd%Qrw_WMXXYttL9X2;RD}#atdVd zghKht3U16jJd9?C1}rN}87al&8klttQ1D5C`DCpc zTWD)y)In*+flBgP8dKq|Wj(x#<b}D|h&S=wm~wpB#FcL-c^^q-;~dgXbV$yvQW zcdyK+sKR}+N#nt~M%LErlq#hrGUxBlJaNt&a#qtku!M$tBv54|@IxKrk~Fw-oM2lO zPM`9V`>ZZHKZopZGLU`4mEovbru!9J` z^@PK)yVP4zVR0dSchQMfqCX*y{rmCuYl)n{p z>pbU&0idTsOvY^cb8O!HTZX{v_6;Fd213cpr%SEm$>+oMDd53HA)DVU^1F>0^K-KG zqG4tslifwEh>tjV%#UX6d#ekk)tK zWRJt4W#cZtw+g+;xzz!z_nFXGDImkJUJbL8*giDlhZ%oYDJ45HbtHYH+djp96#^*Q zyiDkmH%KH&vy@`5SlQ!`6jeq-C99`tdqkya^n=r%NCQfWs9;$g{?Rf*oh7M_N0EHG$ zO7jm&H010EngK%XH)=SOjKxs@=-`}JQsW=W9GZi9!Ua3WrxQBGa$$0G(ezLx^_m3WDrwP?Qj?vQl=H`-XxC2M0LeunWdD+X zad$wX4APu;BB6nb!KBwPGA3ga6K_a{0-v90*%{5nM+g36tpd#F0Yi89l6z6-bP&9@ zf4i?54G(qdnIQA`9UC^?Yl+581B=Ty!qX-zOv)-4V+;2F^x_WN4FpgRB{2qukTum$ z+Q={@a=?xuc(1GQ=#A%;mS!h=mvC25tV>&3 zueIXLpdeII0mjU!S=Kz6YT{LzLBbn^$l`Ly%2mcGYjPTl^~eX6fP~&Qm9i@;96XRk zdD+oth(T85$!v7Wn%042st9x9brXZ-z)GV_`7Mb^j@v_6g(_60a4)SeP&#XL4 zYMEqfR}F$tKO=zb#M03ubr|1JwC_UmO03|&wzxenSnC^K1kKF`bN3`@UeC2Dl(S1w z?xR+Xh6|)nuR8chVUG+^V*1a^nV#SHpI`UgYl*>{tU*J)u2N}wuy0&uagcm+1&sU- zpn47ZTDTe0v4%36E|WO$q8!cR$Y~*B?*d1pATD-Erjn=SJ$Fzk;c_t&)>8(n$0AAf zRu5`Ua(lyZv#aV3oHGf72ja?u`u z85vP&{sPDzkX0O?C1vtcGB1(4FEu<~@X;X9?o*++8nlZk4}$R4S`e8@mhO508ol`W zAp<*@MNyzKjaNWS_&yj8maD|*|UnUI#{sl{F^|S0(dX9vl1>u>=LM1SDkxf@LbXAlZtlqERc$f!`>m@ z?}+8W%gM!0z>=QcKGd>hV(?->OA#fJ$`#Da4e;tq3@suqrIOe7H4Of47yKZJNZs;9 zEd-rju<+-ZSX6h^3KUw@bTa8yx>1+NiiI#nOs4ruJiWq%fzRIU7@P)vFM2XZ8h>8Q z@w-EWijr?}80qH1)jNfjrl8J@wM)3r1q|D^OzN7GYqi;sff9i2SZga<+)Q=|9B?1G zQONKJgPEHnd%b$OQ|DMK$vd%H5R&y1RS_`C%?%PB*MumWVBh~Y?r^PiMfq#3J~B|W z_{q@>gH1X~>tDB`6zu!KnX+X5DgL}tL;~||HhcU4s;LX}P1v1idfqYd`BBzF@^MFk zO*;Y1#G_N>o!Hqkcd1f8cx#C{64({;c#b!f(ofDt-6n3fQC|?`ij213uI`JQy{ zkOh<0y4Jq~a=dQ3`dNSfmaIB9XO25wgTUi)F$b4o0ey`WPEijHEb;!%zgb~~bORI` zMI@7;$cdujNW#*$#IToeVSlr&#j%!Jkowvh-iz@t#CH>vsJq+ueGg4CnarFAHC>Y4 z#V_LWPltLYJ;&S-WfWNY9Fu3evNx%kepf{ClG`9AkG88kV?!3NGEcC7Zc%z++$8gcWu}t8`A72vmnx`AE_)it2ya*Gw&-Vns({~1s2CZX*Kp= zoZB1Duv5t%O11rJhljPp?+nN)?V2zFt7o>qdFyWVj(6-jKsn5rKt9Zwll^+!+9;C>fu7XJX8~$U@KtE>R>A#Fd zlm(Di5;gYU`JaMEKd62Ezg53AKk2VSXPEDGPycn|yT8A`0fb-twSoa&S-(KvkFSDf zV~@8(b*=T8%!_KLZbAkDv#2_uGeG!%LWJf|r7nzDK{H^>wztnP=cP z?mOMv=EzTR1p)&8|L)+wFu!IE5i#t}__Kc2e=&da+Xb)Ozx-zu?)`s%TK#|gSKh!s zoqrF1{0Dch1izh|6u7A?#k8)~>dn5)cVU&na?LLNw_4x@T+F_QMlr{Zo8s<*EPkcf zU|!tl5q-L&nXJINt(s;3N8-l$?%~BNy!8E-_iappScl|>F@4%-7N!GoUiwI?IYR2y z=X(pxFBCTIHc00MKQaU|;`LkblycE9d2AaL|5wZCk@dGJZg#S2E zF%V>B{s^i4r&m-_ih2QplEJnoGf%zrqaNHag1{V?2?5JmY!$I!9CZQH!9Dcf#+cTW zyNxFhFv^TpO9xB_RtnR`AIyS*`;n`3o=dhi?tO(29VCBHNzA(mC^wdNb$)``+)43K z)w{pTyr%}^4DZ}+N-i9*{^+t^J|P05n8+3VABDX3xGNO!~TL7P62eoY>+Nm@j1X_J$N`+4+E&f#l0f254%h>Ycs&}_3F>9TxU5RIgQ zvt!a*rb3VdXf=>!*Ga7@?L!FvmXV!piT&gjj355bg66~(s@k_t$_zXa0O*#UX5Af1 z3Jdq_fsD9cI!~9zzR!67Qo=H<`S?t}{{c&O=F_iU=^=a)A>Ol3bF^Hy(RKrV*k6lc zsPxEG4il{1(`NBR0ml~ge@nZag487czM1CVoUAnOV?=4Ah{6uVyXV0FxBJi6`OESA zC&ka7&Mf~p-R)sS`Tw!=A3l~DXUN^TUJ=ay!{q;gvvL^L9RT$6+h!NlUp`{dS3~7@ z2{=bX4tq&6#~t*(xEnT#k{^7tk~p+xzCHlIqq?F_$e6h5BHg zx)tHY7({rn-J|V~xK83>T5nZ&1eQAd=dK|bL1}v1DB11zn_GZ&>ZbfwU4ly@XKdyD zJgYy~VRFoVJ@W70a^zp>UG9CLKj89BBy34D41RA35>ba_0=SYB*$VXFLZyydK+?M- zDid_X)fnnH8Ckb7%&+#x_?|cNNupOW7xA^TXP0nQ41nJHzxehngrJfhW5fN9TKX*6 z8t`|HgK4!Q7eU@BdtL)nU$K3X6oLnJn!o>>!P`UYwN z60?7m!~~$=L5sF;%3kfSTKK~bBqW+8qiu0*H6`QB;Yz{v2s_#g7qSyvVYOP)TrUu* zqakeZPvkbMDVaf!q}%fB4_WEa{xaqS#X@U?<%W%VIVQi!=rr!y6xQ|h&M+sasf#|I z+Jgv`)$xSl9R}7^2kw>gyk(M`L?H zn~U0^4Z~>&nm#x)JYvq)Z@5Z})G!tofzw`9C_=^{J#a_Imt2YXuV3{UEjo@P ztUg2;RDZ6c+k*_>w~M2Y&GP{}jy079`&ypZ<cufF{KZx%ASCN=jPB6 zW>=Sa=>-1074wkBAHKbaQKj!JsOPx$HLN-2ZZ^UFRR^ro~ z>dOIoJ<&3;L}Dg%b3o3=^rl_nngBfrw=zH3WdJwX306| z9}L20B6cShItLJ)+2;@X4?_|@;zR^@4KV8n4iPB=xd?6+)QR8{#2W;)-%-5|+t!nL zGL1H9)?1p`C&!eeiSS?uKjQ5CC^vu0MGLDP|3hrM;UO0heY<rtK7-!5B1kcF3-ze9$sp7tnsafDo`a7Rc=(^KOy zQQ|GjwfBg7)T5|kyO&S{-U@2=Q2zKs9DCzxPY|3>xBVH0cmvq*{ZP&Rf5WYCR0HrB z?$*a{guU_GS5i!lx`7t8tUJ>Q;Z#$EO2SLuUhR9sm^=*w0froI)M8>T1E44z3B&2@!pwi!RT&EFf2g%G6^O;Rej5Slr)JAkFw>A~eHnrzR*6*4;& z5UGL@%5O}L2KXX;L}A|y&3=91Zmu{#%02iW6`G%I|Cw_|l=0Oi?}1<3r+Q*f#8QWk zOfNsjk?d9AQ%m?nPRCUL_;whEk7Yr6M#NMyJBnHWo{W#*Rfz+UG)ps;c5G;S9K2@< z-gk;l`yg=al_ril(XgU1Bq}M?+BUt!cNaxb%F_1Ys_IzEUyF?n>a6k5!vcy$fgi<` zzjY{zFAVw%sa0Dy0ZN!*YUeu}>CV^Y-9`pV{f*g{S>lmUm_{u!ZMHE7lPBywOZM5K ztQjJ>f9D)xz@Oogy|STxz&`s7Yq?G`iE=}WN}6(EfuHT2R@8m)THmIv%poOWy~)qR zB-I_MPro&o(h?E#Hlk4Tz9Bvdq>3c6pc=ZM2txVdw0U$qwe7$%&yf^r(ymq}?#FWH zr?Tky{=_ivOZaTB*|DNZ_eIG;Wz~OOlo@;I?Du|)`zu3Io-l)-D8q8LuZFN+TsL2b z`-o&cmlSy}xN78s8~v{NfBC1PuqQ#ZK1OXiKO?^c4$i@?swxFxQfn!SS!$q)PTpPF zJTNI{n$)gF5R3_II&UV#|Lr49N!^A4lp3)`4eJ(s>Ccj1(U8T13tgtxfQBetrlbsZ z`tx8rd|6=uk9r#JD3&?fD zt%O2Lh_{P?s*i0(m=_gA(|I4)H zm)hGOo(D!u5ce~qacxv`QzmZ`Vx*?Dp~{yWdoLe=cQMitikYbVl7Fu(mQx9*^2Uc@ z=_)!T^Uj-02lk67jiUSzS4Czb0Ah??VZ!EyDGG}|vI{{-t!O4l$-=)84y+e`Qzb4@ z60EcDRdXAI#Gg5y@M8QjPBGVbA;=1G7izR`26u|174ELfDygO%o-&i3ouZ zi9yUt+$Zfd!oy2#kmUudwbSq?^B#}^_wJ}A$(E8bWqhdWZhmCR>=S4_5n*erALiry z8P@SV2GgAFm`c4%irOo~PVb-B4_&dYS|A;!Y#-t?ZGG@$`>b@1B?wwlt_|U(bAEl( zKn8nhh*#9RMpj{Hr5vjC@o2eLwPGXi9Dp$!AvS*1KEWNIyXckv%g!q^OwAY{`Bi2< zQ3`}1$!zn3p{Zpl!J!HvS#B!sD*_W-CeUJQt-8dmMehdrC58cy1Up4+Z~{G|hX`kX?ig;X0ZADPlWQ4KHI7!XjJB5opo;jQ$(M&+7N}*C-~4ITug5%;yDDX2{Kf4QTKQC=%B6k z8ps3Cz3C`(e2bG@);DUGu6Axnm5L@rLqO{4e7m5b3sQ1hjAP`wh7GSz*N`Zb#-oBX z!|f?r=|sRm_~eBpLv^m*p_uNC-g^g+PC4mmym`6_yFtNXCW01=pRv&q>-NQ9$V3N0 zI{S)Q@^y4LpvX>J{CYYW1fih|1%;1x5HD zYbzl--2IV-6cMKFB^|mmiIBQO!jWoa@J5?G&l8=5t{a@x(RQI&!4$x$gZu3!yLr!B9 ziXWo}byeR)Ry+txr1pZeY#)#9&(dkBP@Cw3-pZ_`{byrAd44L2 z9`UaNz!XL5_ni9-iHfzNcf=-``HDe_abz|BqViWKuUq5#<;43W{u|PPe>;Lp3%(K@ zQ&>f>P2EW5>I4}a2)9W=zoF4c@~r53_OwBnuGElvpdKnR_2dpF3^r^A^@MLxa#B85 zX7^-oeOi3``lFX2%aGqld!{%T+sipxJ=zU zcyHbdCJS7qJ;2S#nRE#nqCn+FArjSBs-+jo(A_kpOH|xoCeWvB)VSLHn>}yIDv3N3 zO|+2BZovgYNY^Xe?Z5}cuem8V{K3Ti(NVmCg)MzzZ0GMXdfB`2PqiL`oJI90$_Q9N z#?z$Nf9z+=$*aEBiGf22J$GI$2_I5mQ7t%2di&;{CAcv4{ifcUK(+r^Z&N+JygUKh z-e4A8x|$l7bNi4$ts_B1QG{-HVa0~b$VNKj(*$~fW!$Qiq~PS^m=#!){H3o?cMH=Keif)Gnh0jl{Xq0Yl$nP!ATeW=*&#;m#abt6}QJHH^HRJ&ED_wF`f0S$H)h! zABii`HEQEONvDR4=)93bW%;u0)}1-(Hc2<`AzCWPS zI)uLo8Bjyy9=oM+CW_KX&);_{|0dUf1Cg zE1BX@$M@$CiV;(<8D>KFEx|*7V)NY7qdMrM8KRRHicgJ2hV|pme*kqI0TR%SJ<2Po z=?4~1HiG2FF+DspERAR`J0?ESd`P$!yT`h`Wf%xpx2sZ4aj#_f(c@wM)|alBAlKqO zJ9!*atIreLVf^*a-{oX~2WtRvjqnT2lCUYjWXxA|Em6&E{`yzVm_3dBUb!9`b+=^1 z(pb7P!Bp|$wNkku+~T+Qu!8H<$yc0sGPZk|4c$zA*{z14yZdcO6=A)R_}ZI$9DmbJ zui53R0kl?x{(;N$ix4x@dxgTU71jSvww*m5AG5etp0^>LDcs9Rv7Ih1C4Lq{)0<5W z9v@iko!w1IznJqk+1|Bn`#S6>0~KtN+V(vl{+Uz%UKUW-@GUj?l_?XmS(fZFM4gZ> zd0t!%8Dj&@(@Um&*C7sPl<+*2x!$LF`nX% zjYz5$QNCp~t>gmb4cQ#L3~;|V=I7<*g#t~2qq(4dWp<=w1kAZQGWpB#%7A5iq#s4^ zBYRlL=>`zZZ;|XAr~(T3+tPhY8j=h+y|FeO&U+zl#AaKy9Chi6$dNbGtUpLajEM;|ZR> zOVSsF4GlsnBYumj*}YgUe|W_qwrZ$z^^dqs&1Ex}W+ETg5Yb{kez0np6s>`N)eF>Z z^+bH@Q%nhbe=c?9>umSXK?QaO!&CU&7LV5BhZgr|mg_~>$NK9(Sxfif3@+$G$Rzt} zmGTX)@EaNW6E`*C7zj?=o)!dB5P|sEya`4KN_=`*wMq_`^u{S9c|b)2_e3T8d{VsG z%L#Fu%|%ZWGr-PuxV09*cp5b%g~d_utM_*>Jvej$dwPGpT4yJx1-utXaF6n?K@4_n z!EWfnEsCZnZLWC(v^g{>oW)13H65a8f?QY-Ive^OLU$U__j7Je^obu$Yw41&z!WN8 zN~h2~J>6?^aoG(Tfz^i$%5^^~DgvQj32(y?M9!9Go&*&Te)v zT?m^!D*ao0g(2Lb0iId-+~4z6F`{^MSBo*1hznpD+DtsO`2R2{+M&f|DSmkUfSCe4 z@~!Ks4(}Yz`7Uymb8sMH!b;NSW+TVvvO0QVw^!l_YR>IEcUbO5%Gr>0*RCZI z3j7DingK~gyS$%Rce_bG;^1TF5!HsnxNU>YR!}R$uCfS zQSu^VGv{%hS1!?{j+|U#?^o1qdp*|0Vt0A4M$#6sa9NsOmyAv7h(rArQgLQDA4Vf)@F<*@S>q_&-+biCHPjKT=rgIQDX{I{v^gbQ z!LnH=4#^u;tHlwk%d@dqgc+aq`shRpiUf*XRQxjk*dR4k^f6%IT(UFg@Xb&llq&yMn6`M zWmlwfKTo(Q1frLFfyuKKwR&i&;oHzgU}3a=@gED0nX-ktGdN;!!UJs;Y3`|0$EA@Y zw3Pm>w;aY-ml&$OGHL@#t>MB89a1*}04v|S^wd83`BV1~IBgrqexi_m`dj#FAk4y5 z!Tz*Wv%Za&lY8yZn?Rs(k1Gd0J%DbqOaFLvp+_evV^2Iz%vP0uJu>xoP%tXOl} zl*Wp~_!33!A0v#ZD@#>Z_a<$%@ckX$&|1ZKkj#()s9w(9+Ml-f+y}~|tP7ZxSFixh zovYK+jpTOhCWW#6;9JW&|G5#wKU|TM;`svmF*ikN)Un2Foar*LOEuuI%k)vW3Du-O zs9yNslKX`0QPLY01dmg^AOO|yf1lEA(dU#jS7UB5|2p9lk~ARUGOqqsq@tA4?T4S8 z%?8t?&)y76cX*9$_kyTDn_7))gIa*{XDWPA3eH}WmL9<9D9Y~4Gkm24@VCZ2pk^mjEKW>`C_H~6_V+D_}qUNrWNRw6@@bwHVxB8EK=e$9v{ za~bnkOP$kqfcduRd;c)dX5sG`u}Y;C;>#SG3Z@&Fc%CNlGx=?@E*g56oUxv%10Tyv zT1h=ZHv8vXl7YEtApc3e%v_T**8ApZbT~}RF~b{vA(3 zzsK#!cG{sSN{6*8+XoWGn#JHE$Oq~v9ZP>aT9p=g`LlxV+F0!qBxNa<69Fua)*K|_ zCTuTMj?$xawpay?YsIB3?zvB3yG-Kn%i8NhG8434&6KBeu8>pk2Zqylv>>+yDA;GB zVZ-jbJi6@0*nh9zi{M)w^w#H^&v>99u2q~Q{)>erU@KNkg^7jzI7HU!z_kbni9QHl zDu7j_ip52xu`-gQodv%*zO*S}c1CEjn1&@vsYOdZ-Hxt^C!Ci2X-M94itJ}y8I}H! zR42k|*tO5#?qTd}gL!CFcIQn(f%}p?CRDgluZJ?CUlbC$PRGEaM=J2gBO6&!E_v$l znM&H+a)Ifnz2?oYo$`!BiB2=)V1L^*o zyPgtVUDK32(!ZZaE9NZ0178r!fwO0k+4ILs{>vtAtuh^8;wR0Vr3Hvn*D>TZ!`aQ# zSj3ARTm$xaFs(0d2-$G~QY^bq1rsME^Col9!v(%)_NmU!J_Deji@}#~J<21RP)4eE z7Imu%e1~JBT3Cc{hWrsGIOr?xRjGtFsfAg&gYel&3z7!-0cgZxA^z~;Cm#D1Mv)IN z`66_aA;;9QK1p&gmd^LR&76ghw(~utbSHAoU8pZd;+Pz})@XA?%>|^K_~k}yNdGRc zgC(-B#UW9V&B~FuCyjdnrU06hF zC%==oz04HV1|tyL1XjipJASz|*i(RTxeSt`<8$Ny0_Fdu-`(yt1Mvw7NNr0gyp%BE zcuEHUBDugUVo@NkeLTUu|F7Wg-&E7hlT}PBX zjbD)CgG4h&uWF-4NY{rUUFL`*M!t}%r}RdBz-*H|nl@KVp0?F;x0HiOeI%6Zt?-I{ zo;m2OieOMS4+c+yTe(NB%nCyUC+K|e=0MEOJLUD;KTS&7Y*-=2pjUPiOn@WK#8Yc$ z03;hU<x z>8JrJ$iV5}v@-)i+nv^CHD+#uBI=v-XVo>q{Ca+~LvJUl0gJ&6@bZJE5(0+4GmxrF zPU_HXMh`YTvU2#v`{y9*gPRJ%9z$?|>`dziJ1ljj1;N)B9K(s?vA$|#`A;Mf&eXW$5rM8}3HO1&fRU?Yf(Xn5@VYc#;`={IwpY`7 zCHxVPdxLY{HQi}xGucoy!lgXB>CE5sle+^d@U_uj%yMUof((1kD(iGUHcDueu!bQ8 z|8*$!hE2T3ng2yA>#iCATN+B|^c|V*1e(qt9un04%C3gLIkejDvqYZiGX4Ty^5wEi zf6}F_)POs4O*{h1Su9bui?VBio-|lMNWKKiNM_Tu`Wo|@V4jMKGVkb8>4HJH>WR0} zcIFOy>UheJTN*#2;hj(bLt_;2u5SG+=0I}eKjP-@; zPXPbJxlTIQH8^fNdKFy4ya=;d(rw@(weWk%sZQ((oznJDr~kPNYp8DFn6`sJby9h!127}p z@%|BmD(shiDScnVj<%`j%5r(GB#4ypL5yEI_>K18ol#01YLY0V3l(>g8_V?%Be0tJ z^92^s_xhNhA3t+{X~CeKOwEu?AY&5xLec!?=VV9^(*z*_``I;fB` zea`)8(;djCTrxJ+{4WIv)Gbbd#U+(v`lApzuj}ds_d-SwTFDDTspt~nk+aBS>zBy8 zQ)^PcvMJEGX^Y?v)SB@$)gY7v(wW%ZFv!n&0r+=N5w-F0zAw0n@Wm9FI&YS5WqJ~f z^ih7G9VQq1DXGd~g(iD(CXp)T@6r_RG+fefnCDd@?#bm1R_S;>#$unxzYT=g(p_eJ z)DAi#A*kfEY5&4<=AVYSNKXo!fk=esC6{Jy~tYZB@FEi6ZQ8qG*q1@R&^*6 zD-;I<4jX}r__~HZgTV_+di?{++6uw<2GovNtZ{0b^lPQ%Bh2{>i+a) zPgFVog#=z-kcD+@8{)+I_w@ykOMui<%LmGEHRPc; z&Ce!cd{ph0_cJcpMYK8SbzGe9#+f&5aD@bL6q;x(JV{f+ux||m-+-Dic%^9@-pY7* zYuMt@!ww(>HF4oBNt zT)XBd4EdLVu&XTGH2hoQ3i0o-HWmJp27@Gl(Z$p8zuu&#cKTRS{AgZLa1sVWpY+?M zm(04Vn5${(!kTVUwtUGLQKTSyNJ|vTOzeo&5tngbnE)pa{Dm8JFbJ%;COuAJ1xE z`XhJ$a$C2Nh)BOH$)sP#swYtaFPJV0R~jPF-3mpugJX)Pad4PgR^oO_T{(Jzbc;OK3kG86lP%l>UUjPKE8-=)W*$!^Wa1tWB2`R ziKWkHRAK4R0m>jD5D5jImX37nCEmVMAonFxgS{Fk&JOgZ%EPtYmf&wGbT#XIKJh1e z6@#WM-!N4^;A?=Ibf>x87y(@GwN|7OpfF$Wl&F8 z3;gIRl>h>$252jC1Wl$Vjb=@9S^wvPg9`Sra+N`ktm!YLy$=Da0uAxMqzQm7GK5-= zMuZ{cW8$A+^;MHT>7b`fe6sd9;fcaC%9|7)bki_9XfRpqNI#k^FlghhuV6U<^`uJa zjE~dXX<`jj8!QFi%DjH^W^m7n;y&_e`M zSFT@MGBIAQ2!sb?dWUx8r@1neKZ72#%pPG_p!AMvq6G+ZdC4;D-OA|E9W)hgPodRO^x=Qv?n|c`bpja*))k%oK`0R#p1O31&^!nsIz`qlxiI3^lDeyA& z@8X*$;Wv%tlA*>bU)QP}gEc`K>oGt#A|ef3vT9)+$u^p?@>a<_WK{KS?N2PjY{r`V zoI+w^4Nq*$Llg=AcG3CG@HU)W6}bgzMAzMrZ8`T)!tA1zv?%O^ql+PtHOq+dhgIk& zBVi&3O`_Ya)p8rNA?VEoV_i?CqfIyJ&}WD{?7sM? ztm8eOM2kAj!e5c5Jm;~{8`uR2nNv%X()F5-fTA;Z+EfYZdY-ABh_i;cL&$0xOix(m!ig|gR(c%Dl!&r=xFky!QQtAr)L8&Meq&+V3E zl;@3QWQx)7ewi*C;qV78ZgJ*=GM#bquWOI8tl}l_9C!8^o6tD|*(@yFv)0fl8@{67 zLgs2+E1jG@-Txae@)K!G;NY3KrIz-c54P4~LktngxB!8)Nq}C#QpSH-gYLhjh%+(U z%K6oIkOAhC3K#{>kuvn?s1@Nm2j-@R&9h4f7P()DjCgI`*%QDYT%i@zMYnd`xo=*lCVV?W$-~b9w|NY-()=klDiYrx_)u|+V_C`$WW zu*6H-`DF8rlo5={a=-;9q)0*M3*BC-{?bRa{IzIgRe?Mrrm)fHn1{uR2OrA!h%1|w zw%s^35XMkmDP+6>fQ*e4v21dWyc7<5ewn!*0dvpl1chTuoia%*`vH8Xqq7jCVA!&O zI($SyHr4pRUrEja`wRjKV)VH)gPbw4@KJ$*H+G&z$rjlRyPN6e6e_{8tQ6Wrqp#;YlVC)TPKc1 zZapTK0-u9O3$4cwjl!K6edNXsEXc3_9M6r1EL!KfhlLPIpn9n_7i6r_ZPhU5Z!N`k z6)d`PEm&4kRt3^fx3&zEpM+ z^hZXG3po3jhJwn~d3v6sJ#bVj8_JH`0U?$%; zoBjl<%>aYDVtIMTRx3XjC_em&6z~E|vPy7<{4`oi15UJs8&rX^3GXj9$haB=n1XUz zx|{rRj5&$aYWll9hb$oQ$E`h$0Pb(2zZ$&!OD|d{et7ZZSAKJAqcSFOg%6k`7`ya@&60Gy+O^GGG@oZ~TX}V+HI28vQH+ zzkz5f+m{Ad=@*m-fB*ns|5J18S^!gb%ZKJ_q?#zsGxOtmG#HkfF-huxj zoq;P2u9c}@;@+e&2xd`Zqgtwf+;o@V>u$Bh3+CJqParfFhq^`^{g#mpb6dV!A{q$7 zsd+?IIS3SUiJsBwvbHf^!8(8?o*4WHK2}Vn%5zfP;Mg8eWQRcOtH=6-t>yH}dC7Nr zBZuy%h-B9aR!-k_@&~|wjV=i&i6PJgzkX5Z{9qT$95@fUnbK&8Q$#2w--&nsxqFH} zQi|TJO3Egtv#Y=*ggd%I)@>tN(|@a)OxetI75j&M7jj&ex#d|Sj5wjo-wcX4HH1+L znuPGp#PdKXCUv#6`c4P-Rfs#3qG+}5g=^&LNfz#MxW>*u6!`t^H}Z?Yt%GFqY=5#g zIW|ETcHDE0D5*q#Pfw0m@N%S;s$Valg))ZNYVMhE?IUdwhA`S3lR6eN-OP`h__-9> z*p&lqXnnLy*rt|&!;#%5Dg%BO^&oHaj|xDe(;3#EdJ@x+wJHY-qv& z&+h>(!{{}V|2&EJ12K>B$1j8Y>farTCm6Yo?Yz4}MqVEcwgzO+Lysk0>jGg~(XcQL zrbbb?VDB(? zH&;R6!4{C1U+g5!(2v{NcBM^`nsvV1Tiii}Z@*er%wJQ-XV@Rx>S)&=CRSt3R_Zu; zMiHJ(uYClLx!#H6LEHmHW7mUnv$&^WJbN#G5QAwdn?n}Yb?IAu^SU4*ZW(La5f4-9 zz*U4SIuzl26olrGIa7ej!e^%sVCNt2w#$r--Sq|_8pZ@!^de!q-J3I(Q0Hp!Szr;A zu5y?(l|TRn@ZXJ*36(tyt=y5|QK6eUT@tfWGdX|X>)5e&haw9>QF4XRk31)eTo(~`ZLfpiHI3P8ErQv{#u!Pn*zKmZw2+InA zjX>mOkFrNKCwu4oWEai=P%-8EAm$0f<&dih&(qVN-)T;oDa*EDbPX8u1Kn(_=uP(r z?YeYz8`LA1Mlsxf{>tWU%2wa5(cn;Cg=uFdih@M#jP?t7STH$s!@-^9uV@rqQ{8bH zFhtqZlh@fD#?s(5w7@U`f7N&%XF|E5z}(}<{1F@o(R6q^qnvUm zw@5a3;`u{SpRvSW9&dgmV(9dH+cbP+1)0=%unDvM?*mC?N*t0a+4Mt+Dv*PMe}J^HVjM?_MU+OdC%p{?Cba z?>K2r5!9dsvsB&pm9hIHeQ9V`Up2!ra*42{na3u&M+AF<;hz^9*0r6LBZuku$% zk5~Xmw$9vyCVd}~7;P*1KU6Ds!tB+aC0AUHca>znXgA@fI=(1pdflQf)Sf-%f|=#; zLk<`=f|6(BkeB7o^J+13`}CVBgC1?_CO=KB`^7uRoOi5?JKI)U$Wo^Bz-!DMZG5p< zS^POqrpp0h_3sTs6q{&kTo^&`2u))I4b(6rJnDM!3_BR3@;=*gGw+4G>f-HVYA3gKKM^;nG(@$syRNN z(alH~QaW_if;`RXyqP{ml#_j+$l&dA6UM2 zgeMmvYP9aHnWhvz=hPu7b>H4nReZw&L~u!tkZ8O^z)ZV^VC@$5?*QO?)0Egf;#N%v=5)zAph$`6ul!qsEly<_-7z`h_+g;Z z;Qr66gZ2F~>Z1^piuB`=4p9Yhd(l=Yn6}If5>wWgaJ%`?f;Z7*{Wb%*0m7K34zfxoxiBi#?p3NdLA#mZO|Nj)k9 zC06}}znH+?hWB--{B#tr$G_~86<%u&9dNXJ%{Tx603qQu)=BV)1FjBF_nHn9V=90L TV)0Km&QJgV319!x>3{$LRp?e1 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-night-xxxhdpi/bg_content_card_large_right.webp b/app/src/main/res/drawable-night-xxxhdpi/bg_content_card_large_right.webp new file mode 100644 index 0000000000000000000000000000000000000000..18c3726129099aa729893aefb604c4a03f1ed626 GIT binary patch literal 1010 zcmWIYbaQ*f%)k)t>J$(bU=hK^z`!5?#QjVR_Zb)*eF8ixnHU%t^A!X+rCB zvg6vl8)x6o$+dcJTfn)Q;kZ`&&4xp4EE~-4>=Hh3FSd_g;g0$&6W0$P<9k)kuh^aH z@?YKI*}ngkD_izeZt(whttQAvT>SeHGu5xB zHm|wf9J7f&@?xRoJIzhz&nixzN$NY*BR4Ni^p^Bx8&mDeLZNG?5*WRhT#^u*wk1Z$6y z8|UJlz)>j*LZd@WNb%MbmWypE9rHXJU#PjM8(6hmwEKDdg7(DyJaR-7^%G z#1={`DfKRBzFo(#Md|i?#*zy5n}?pSeDmf-?<8lTH zdLjJGUn*A^3C+r_syX@CcTqA7gut@weUVQa&!bXb3|t z8OP7eGr6S(N4CjxY__843(Z8=^y~U^R849fmEY75hQduJnK6xl;otv%zss)H|NpBi qcK-i;4F?7WX8HgBFI@x$lE?ou-~a!AKPL>xUh)6`y$+Bd5C8y0anH8^ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-night-xxxhdpi/bg_content_card_small.webp b/app/src/main/res/drawable-night-xxxhdpi/bg_content_card_small.webp new file mode 100644 index 0000000000000000000000000000000000000000..6c0308686d038c48945fe1cfd83dd6e6836fddd8 GIT binary patch literal 594 zcmWIYbaV4!Vqge&bqWXzu!!JdU|!Kj0_Bn`3eFax9(TBb$Hl5 zxVCL=lx4lfJC_gD6_&Re${gO9By3!oa;;%^^t-&>v+a-B%16HJePOS>Jy)ji*R

GKor85R6k`ak|$+odqCmDU0-mZzsF{1kDs^#1+)J(K3-JZmS-R6pUQjSs%CIa?kG z%uTfzvta!|~DBr1*!&l*@Vok8D<8%)$ zM}Ci09QLQR_^aH$bg8)S*sCf0rBlUs2dlQ|pVtaX<{gHKnk%F)DkR;R)fsSn?Th+5 zUH^{jdS3j$Lsj#a{B{*x(e8g>;Zw@T)|xDoR^HOELitVW2j6OynoD||?{Bb75Nl`g zxOUL4(P{N@)AKX$EuCLrQk^Vy(@!(^neKWOwcxyy;wKU#ZaC8<>BvKVW~s{``G?$L|^E>QA1N zi~90&@^OdxMirMcW?atrn|=A2zf`WUWZnkr72>zu>{321JzBSH>MfpmCb!f~!<=sv zq!_ObiT+`3eFax9(TBb$Hl5 zvABKz+gbg+>OSww9|)E-Tv;g|d*CS(+Ya`~&5{r1tqo^%`F3o=Le76*t$W{k_*Fjd z_~+knruO$=r~lve-@TbM*Yv%}!-6vRoZv3;vI8McD-!mFa~0h%y}oME9<%Fg+_nbi zR~?F(o!;E`ZuaA8kM>GqwHQ{4~)QQ#0qCxU|LP$?J8VQ#;*IjVJO zb#U0snE8)puJPscxwhOz?eLT%PhL+sqtb#>&xUI%%vCC^7eZa!1>QPu z@vi$=srG5|`Ot|6()XXxn&;@EGf!JdsrTGH-}nbQC!a+Ze9Kpq&X7BGt?$f+Y-!Dy zeeb5fecN>Edhw^-+r@mYoj>{h_H%BT`1$v4s@`T|0H!>JGr&|gL5N{4qm~Eb10b70 zb?NTbTSszbBYeJmnQ=J-gsz6o-IDywUn*C`t*7SXW8X!|UTYk-ck#?Kxus@uOQTof z=j3CvU5?FJ|8}vwQN`tqnHw*IR0~U$<;X>S0ZF>Qj++mXK^VpVqHM+vi1GNyFb0Ny y|Nnk_yXyb{Us1aA|L+TEV6dESy$i_k3=9C29(Pgz literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/bg_content_card_large.webp b/app/src/main/res/drawable-xxxhdpi/bg_content_card_large.webp new file mode 100644 index 0000000000000000000000000000000000000000..3df87fcc26d7e5f2eda864c90523656909dac784 GIT binary patch literal 1084 zcmWIYbaOLdVPFV%bqWXzu!!JdU|z&85tOO8^UsLPkCY5X!2n; z%Y_5y*?gE38U2_P8Yeh-D)6?jU0{&5;JkBV-}(CUI{q#e6I4v|9JZhMvCZ%tcS@A( z{m^-jIZkbP{c4p|H=)*DN?{xBJk!TeWgBb9!&? ziuz=GW|M9HBcW!U`&HQ)$I}EC>qPs!eay~qdYZlbQgzmKtgYX|ON1RxYsqs~L~YfY zq`St>Z`u1@)77{3*|;3Nx4C>>@znUO&$U>UZ)abgHZ44qfdLr%3R+AI3!~^U*mqGf325QTf=}0%pP6TJ zOAU&yojv$=0h%#wM~-vd%)b20Un*A^hJ?PanzIu_jN1h0bQE>`31Ym9<&7#XXUu@1 zjxv6Ai%Mj5d|$&pF1u)mjQFf7UD5PS&kE5HDgSELtln$Zi9iBbj5E~y4PM3^tlg4~ zuv=)4hg#d728MtC|8G8#BOEw>hD?>5{=!gj_5c6QT;kzf2X;=~%0K1J&)yf&Dpyht zF+A>&{lNG8yz8Hr96Zg}mS@Lj|CiSCJT85S;s2s=HiP{qg5tiOivRy_%?q|qCzmAr zFj#K3zqRIwgo5T<)uYC$3e(=d_|nML_x#+O^>=SBu>b!e(dpI42yvrr3qQ@BZ@8B` zWmeDZBeQ1OUgh%m6yf;F$gvD~dp-*&Zrhdw%X&HW|$%Jlrg)Jug9sv8mg9X=&ZmKi`oEMh%!$;E*mwZ_130;&EUYjKziGl9tpyd;o?#&XAkj%m zNlB(7m4V^(csy}y8#b5cmGu_J^i%1wo9ah>p9Fj+H`ev0=OjI472 z@Y(;(?)Jy)Myegr5ZRNbQ7O3>-rfCpy}*qkDp}01Cr?$XZ30%BZvVX1<7o8Ny*oSK za~Nh58`zZ$^4`zdY;=!EKf*+Z9Z?-Ost4gbeP5D>gu{u|aPcVL#Vf0X^pdIha#V5r z?*66uoeQ%)p-cXg+|o)Fa)V{%GLmGZz$z?Y{4w6hwEq4Nnz=|86KC5Vgab7L6}NRhtVj2%-J0X zf$Gb6;dGhwoc@g?Ft|mtZ%!*+OJE!vKA~t}3h-!v#iTOPZ#a^^?OYulC!v$H7wV^{ zV9`>}9xHDD7O&7sHOlr@wTz$6_=7K00*&6|%@)*RTdzFrxWSH!aJ-ew`?4;PfVZ;5 z@Dsu#ia)8S%r{8^NOA(NofCm`28b?LSJRvguT0Iz^6O;&l|R>d+$PFefd|^}?-sc2 zzwgDj-V-%-R%PcTSci7kxH7C}7Ya|PJN-3ejcd*t{2s!AzdnB(9^Bxu+NbBeUVz5N zGli}f%HPEZ7LnMhzJQY#%{=^6PCD$+!ZA%E8pa`&$d8@uf!`e`LeQvXBlpp#qS$gC z5K#?>tQNT9RyAyl4)C*MzXAjo)iCe|GHn(sbv=`H}JYZSi%( zFtO~yR1n^a;8kJdMTlP>q1R?4>h1_ERZ7lPreM-YBp-z@q!>;r<_Rr{epW_APQ46R z7PL(bfH%t`(@HcORvcSUJ4}~Ss2HybX~L8izgJAfNBLZ`@*(s$$gom z?oLHjBv7beMUl1vthf}gJOP$F!*DBbT5U5GB(Nx?(gnK^0EW|}r6Z`WvjkZD1g(#p z4G9MkKtKoQO7IuE4IOYumGyk5&P~%o821$1&aJckT0uptu*FPmFT=5iBKaj`EGxk6 zuXSvUy9T3$JFChS<=VM@hPnWpC(wYq>W9VV8b*3aLW851cwbEGf0v>QUghfYqT%(m z)nUZBUW)jj+glJ(n? zNzRsGcLR!E_~Wi$xB4&s{{Ew9&%%s)&*G=q@uhR0N0xq>FU?o{SUrQI5N<@oJS(8X zyPA{y2sd=86qjC%B8rf8p>+Nr+AmCDaTvy{=Mkw^RkjzVFc_8zv@Giu|h&G5-p?T_J;3>2Ny4aF730ibytY8$V@5U zDRZcXKx2s{na}3G_9@_E^M&c5r7u^n-upc=Vh>O%5}x_h^+;K33`mClNYvT8&dAeh zXm~LI+0?I@>z@zL(NzfmtOE;At>>|FhF05cTvoXuEPN&&vqL=jb(<&)NP+@%0FbCS zmM}rD+2br-I$!|rZsv%b!c?B=x}AKhY@GNfn z?SM${mwUYvAuqu*26bXZ3^b5u%purP1;$;?!AdQdWt%b4YBD;-DaR?G zV?B9wI{dGA{QlMMl$7|6SxNqtKXo=25e!W}Vs928Nm?+l>>uJ%1!AXwgVXHauFmrJ zSL%6Gmjvq*YMU_EoLE?F#J*Pzj#j6l580^+CsS(ZU#LvB@wts`fDtXT5Tp?lCV*bI zI)T}@jD4WrWO&%@o)eDq&&Bzn#i6Bzxu%{)!VrKpdQBg^Pb+guK!zD@YLia?EwH@-NsnvbCH5X; z7CP$Q^tfzepA95t>x$`#p{mY<1YGcn>KB6)V-*u^{1l%nnHdP5$-&~g*mJdXSgIu^ zuoJbN#%#LqG%l1&M+Pwm+s(Qlrrgy6Z7u^K#xEC!Ji~Nq0HY4RaOqcn>Eh41?}wIt zH}CFElw&Qkhc4UfNk%6to+>#WZv@wbMya|CCDbS-!V^tJ%Eg!hcr% z2?3;Z{pP2k8=yDQVF?n>FIEMdlSOHb!}!Ix;t}C0%b(k2@IR!g)!RqvX^npd8V>S?s~_%e*|i}t{2QDOS@2|^ev}IVZKn^&O z6l8*7n2o!Yr4JJ*|5ZDaL&2RTN&uF(iXx#;$D?I^WwYr+Oj2PS%hQrGairf2i|x|G zds>mKd@e<7g0VvRWF)DRjr6f)mL*73+b@*by1-NvfMgh4JkTqEzixIR;Dxq3mP734_YI@XWiu z4O)@!NUez8W{n^=y&YASfCqZFm?)W(HQgv}Ps~=1%w6QI07&>v=gcQOPv^amVbJ|9 z6=>+o<~C7xAa6T(3B62Df$tl$V+|tVksAp@f-Q~L>lbn z@hJ8|gT^d4>E+3&tG>)|jhR&>D-G zi*x^5?NM;Ghf2+*bvVns2fgem@ZMjTQi)}(itex`8E4F*!3eOz8*=(ggJBbnL{#9E zq-7aEL}XG#zP40-?6T>{Hzda*-E0T#dbtjWup zB|)<#m6|C(iz|MYg z_W07mjv-SFTu$$tSZq=-##H!Ax?;WZh)pjGx_z!lbMd50?II^Wq~E2DTJY6G!OEq= z40nuNF#mY+0kTseml0fwx3;@+0ss;ZAZ`+r%Ir-2sf*rZ}b77#=$7a0&&3e}2$w5#?Jl zdg{4Mby)@7afbz!FybJSCVGwGf`gkq3FKYQGCN5o;|kfp|D5ImF@Mjeyh3O=I>R- z#C?9R7k{U9XyN;hy1Kcu3q8kMt}abqT&lY_RNI;X?w&CET&+E;KTCL_bd8kE#N0$D zI`uUtT8)VMguU!y-|;A07n()CXB`_{TWZ>r^5kW=)pR>AB&m&@!cb%s*}m)wv!O{^ z!oo3tvhVawCB#q)XW7?i!?^mvCs7t{Qv)oKjt-?a6H;jGK=irn2+RZ@C^RB)>c#YU zVV0AuF*v-eXR3DL&G9Amo`vb!y7L$B>Ef2b8hGI$AiM#f1Ts>ZVz%p3=Z)2CUK*_k zCggY7;a?l{&#W*Jp94_tcRoJdqa)A4w$V;UrkiiBWBeY#Zrr!cj}=1j>@*=6Jl2NU zy0B;zm=q-Z_z@=7CrrwhC?{%u#4A8xr$u3LDcp1;A40YcahnZ8p(RRytB+3%z9t!T zsnZalMUEC?+o0z|q>+%3#w~Y5vBwu@);LtbyRJQUqvYi3jAP-aEPP};`pOb)LTALe zfTeEz`dB>y(9!!=FV{)6(lq)WUU9N*K^5@e%v(LYMbUVNz?y9c*K_u`q@vOD9B;?> z=*@~V=9`0`z2wgCJN(PoqlK1zWZj`ZVbLTTJXmZ2rI&iAMqz(r2<@AR%> zb`(@?EZ7TS0V8%1Ai5`3caRK~uS~i1RRsy{@A*MGBU{gB5g{uz2h9HJk1=grb!mWc z>|D%;)u(@rj1E5QuT!KJ&>Oi_N-tCjac>ZH^U)|6NN6O9361P<8MtT^eXo8`5Z-Qi zX(XdoVA}@cPLzcp87PA+5sTcQ)yGTZ_inc(@Fj}Rv(4Xgu(H<$S!nQC081$eao3}U z%i`)?dlvAY4HH6tgN;}&q|u!{({1Qz7_%9j>x;c4UtIb+Fm&-Z z5k@D<<;?&&0enQ=E~80a6~Ed-fS&2dZG9F(E}2>I;NMMNF_vx34#c+RVD8xi8-au~ zZaWKm4L&C560?AEYCmV@8^4#VFon*R)f81LS+WT|YQtU??aJ*tH&S>jR(}Pg-ck#W zT&fMR$aZR9G2Ek>4#F6O!5!oFOM6)7E6tWVp^hI*A>83yD%xj@$|V^>0H~&(6pJ$= zy`bcPl>u(Z^_)HEPuIQg6Ih!#$-GY{!J7f9+h;8uZf}O^V8^M9E?#xE|7R}Pt6o&E4(-h6jDy~>wnK|~tyA?^n*JBG#o1A-=fHH8Y| zW;a6N=o-BXrM=}&6i*UJqnG&wT`sxhQITun&P|8R_sY?87Oa1I9%u_%I$jP`Z?!6PqYOwh9;~x6Y4l|` zK8Uz|yJlq4?n(5N$!0X_M~h=x#qWL7gH?HV)t#pl_cZIJ?LQj^@Ml+k-0EA^z-dgj zmy!FR_Rb9pXNVDuuxtWmv)ZXDD6ppnTl@aXu8GL%jr|XG6Y9Z#r!`gkd*WAPR%)#A zTJ-?H7_kFZww4NxsJE;r)Qz09Ufa<$Ie!Azzx1PSacSe6Daqttv7X8qxA32W-i<5% zib+$l$Q4UJKg|r(^X!7ZSX@bK=c7USY=FgDBg}Cg`I#~WDxA78Nc$i=kzi6m*GF+> zavAwt(ANg#lr7E+mSD@xU^vZ$?|AN=r;U4L3+u*{k;{VO1+ktDC=B51D>B7pdThxa z8h_@M*AC1)8I?NPh2g6fzO-Ik%Bx%YS#xXx`Qbd zv6H)lcUzl;!1$mDBr_V)-`ypi^M@%p3b(taHd+X-T?c1F*{&g5=y`4qu3-`Q3kesb ztqLp2cm4e6vN_Zhc}ji?4h!f|hE$ImN7UtHOyQSr5D@vc7!D+0J#C?iLGzW>*!VE&an?p58sbr?9{nl_3G!pxJSA$BE#V-wG((@+7V^truPmTRp3#@ z99vc(M6%IZVcbMzWh%Z$J^j>lxbb|~rFWXo!x}z`Z}Rt|g#uP`YanF3v*vfr;vjp^ zZa*OUufO8AU8-%P0FP*becR+HOfV?5W^vGAO-3DkFGJfno`psRk4#yX29IBW@)*X4 z?#UEn6%F7?colnGo^#pDM+o!twVDYZxMZaTU$YOHSkDtc3T^#73h9=pZ^0c0#s#pg zl~ljw(*yCsHL#26=)i8U+*6ohdqhyN#0cj%y~(Ojy3jgw0W9F>Ce6)K!{y$q5^@0}lw8GYcDhf^ba`E3nV9J0gGlOq*GEs_pMMAk3Z}vm z(}IYm?@rXU0+v3=FqtSvXQ95*s;Nl>;9kqb^s~BXmOcep@WM#BH+tlJ<$-&vlR~Ju zWP+bCBB&RN^hIziJ}Uir+XW!~L=aCew-0{(JJfLJl@F0Pfel>GD{wGOVCI9-&y2&Bf2E{B^#FW zemz?+iv6_pk0R!6dwO~3Ax%Js#qdT=+3$mIWkD{%_9S5-kgJ#w$!AF9I5FAvugUwh{jR)@sQpU#h3M6q8OWRGB*T zFw9W0Z4-OyZeCnk1$>z`pI3J>;i$sVn(mHBE2-6WKFc=M$cwrEgD7NxOd%u~`86D| zDmdcYuYmg`#5G_*K~jJXT5 z_C2Tc7@1>=$Z^q49M<2?*hR8hW&x)S9E;G>>T)+7C*c@GGBKotjML&X( zD29w{)7P{`g^jr1aDnZln{EzjKdlJxQ~5J)4O9H84@EeYbSBBDsz`OfiR#eJewshR z5wmH9*Ee67D+2f1TR?j&UE|z3PLKu~Ao?Q6)b}}W2)%di}ENt>wcd}wj z)GqSUS3Cla4$tHp8%Q(x!tL#NTNhD;%bnq>^Qy-*nZWf@B;39xkL9jlQBWK-_b!@4 zOC7o#Q5ey^kJ&VSWw(|UX?d(RPe{?BRA@t97TEgrXo?M?uB5ZBz4b$<{o^-wZVy-vQkn5FLhm2sNAGE{LNOVOktI^^`I%;)RKAB65{E!y zy)wX5qsplHCmY<5xJ?E5$aTi@@(Ors2vBspSMa#e9*1kZTwUm3o&)|J)aYC#RY*mqc?)`-+()1h7h3r=&|;$kaaN8Y@)@JYq_;NjR5R-!E6}7*X z?z%hjiRY>qs|PVi#MNGM{IW)1WusPwwo56kLNd^inODJ3VmbIj=U7=T6+ik+6SMR? z2X0r)FUrZAzU=GTKMYbd!ih77V%lz8pK`Rkv(6Bk{|RfER;T}2nqTrDS?ES#?qgWG z2)w>Mfm?JwyXTifbARDbeWD<8vTY-Koz(L-Q6DObbsdBc4^;)Zfc-hTifuI+Ys%@6 z%5UB1OA;Jad)aVDIaJjuc2~~)m2CH8;I0KlvFL(7V!nTleX}64|3LJ(QuVr|9OK?- z`S)JO@aA2<7MWwT51-%P{iC9qnWt;Sy=c}102k*6?+FH+hJ;R%7jB#ov5WvQAaeuO zJ>L0M{|xD6#s*4*l&6~rG<)06hSI;=6nXYrJHiI*iNtoM3YNX6ND=syInH>dB>eF~H;$6FO~ z6^t_Q99Eu4DG2yl7yIum^?{lhsF5-S?GrVQs_k;6z$jbE_w6MM6NOKobWvJ~5N{XDC38}5PeQ#%2@#q7@es75;184p-2+4D9 z5K!BSc>Y&o|9-AGWRz8!5lpK+$#~J70_4lvj_~!is(zl33J%i+ou4UvE;JYUlfQ7+ z3t&7axhQshtQ?*jtI$96?fqRPk`4NxnvG;P7!{~cd&HbO9v{7bfoG2mwwQR|yav5< zqla$ro$@Fr;JN0n)TKR9><%q|u8v#I>z4VyF9k62tX88_^Cqm-O**aH-@E&@0DMA( zf6d8zAE#cMa@AGbtp+93Ur&Avz&T1*FXv6qy)@#}w3$NNzg4W9^G|hB${<4?Fs^oF zwB5}iJ5*q?Z9GR97g}r_SQ-Zt!J9MMQJ|rXp;9H0tz`qfSVJ3kOs6z&QldwtBFHGz zGO=EnwkJOO#lyUVeh!f0wtBwDMixvT2Bg~j3?u9e3a^v{L_bBr;qb~0hE<-KGjmfH zf4{5y{lO1p%I9TWSQIuWs(t3syEcDp*D})n#g*rL@XdMlS>}-rW>}B`WV}>kBzL5` zaJdu(Jf?-K$RoHZ=I&=yz?7@H^ZxhZ&>(IZFE(BNO%B&eA&SzvpX*tG;s|S1ApF(s zYZw(pW*Cjo3Qg2^AE(bMS?-t{?NICx_zhwp!LJR@azlVm2JFj!(8UvS6Fqv!Zvv5sdF&0bipza@wm^Y(zxWhf7H{jjtT@e!mXr z7bnX^lD8NBv)?zZQ9rc6&t(>RD?7nAEeESTg z2djkwt-axLxpRYnl)aM$db6H zMCC4g+((7em?6%?k`@OqLgx|76Ls76EJR9_qJ)Y!I>r%9 z$805w27WVo5R$CV+1Ja8u&rPS8ld}_J|epQ>w;eLX(kX9F4lV^_4dk=kVScm0bS3X z+pvdzo*-4nRKVd0e5V_kfu88X7aTL=rrbEAo4I3Ij&rRez7K3%wZ^wvRaxtA6^dDv z+1CfEBT<%w4t*%M;}qODXaWlPP6fEGfXi2A)vkKs)yFU54RK-mB!r#1ESKuT7>7Rj zOV+h7K*M;V>_&qAR=WC)edfBOI*7ZZlD%g<-m^bwILS3GuraL|qngX>&W&8Dr*80% zX@_st_?=3>*zFx?tph)4tM*!W>+>Ih!?*X2>B(p;3|ev0iGh3(Fnzb_7aG|8Ea7cx z!~x7Qw1uc>v&goA=pv#ve81Dg1g-h%? zXmrdqjd;oOaa^`W8>Y{(p)t!G#c#4BPhb_S<-)8_<&pE*WC8+dfyp-x26s0ofFBde zAzc{n{NAYnD<}MD`yJ)Bej4RBT@0t9c%JJ*r#b;oOqS&S#(B}7= zHA_=EY7R#D{DRIFeSa%Z%7hLchhfy9lb!`eFUMy4e4|^TOowF)HA77u))!@&`#v_W z?pKPk1g{%GhXcP85x47k5vQz;c2M`Ez4n_hS^5qCtD_Ogz4qscJ>$-z2#d;C!0)o+ zq;T3ao$;utct^l7?KM`?%FR4u;+*;5KOcKdOK3!{py>~COG}R1-Mo$Nzp`CQ*S;$` z9~n!c1UcGt?njVVp8F~PwulIEHdE?*JrbQ+o2#CjP>;*Mr4T$s=(p4BsfzPDpKi@N`)l_5#J(+2q}ksgy$D!0n^s?+zxH*m z$H~(02n_!Xs+hI^q(`Trpi$#pb55~vW&#Gx3>cxbU3w|_EJS-3UuYx>AJ2Dbx?O6L zL@yqlcn@*=VDVKxfcFoTkjz(w+In z`cO{*?Ii0COAT`2tdjZAEOwq2IlfW?*rY^>>R62g_hc*?Ugoo>BhHPTpvX!4oV8!taHlOsf6}zZUoErnX&@nelQT=|0U3vwfP@mTNa5!PP1id`lo+5a9 zWoqE&FoaPsHY~^LXSP9|Y2ycug(4m?$%?GR=Z7)&TB!V5Jwq7)Y>P1cLd9=*cQ!Of z4nW@zYRkB32UPCs?x1yXs80uA%k!>l^YUY>g1DrQcIrdBc+TG?3V6wjo;)sU{5j^W*ym7K1P6_nC3zF*yZe&-4O+59Z%`w`h4SKMf3! zJkvfnA2!B{^h8)?cqJ9J4(oB}KaUbkexCXa{W1k=B|F0nI=(ra?f z47Wn`W)-0(8iCvXmG>oxsi^%#>U<^kA@+siubRi7qtbZzkl0j zqqUtI7LR`^v7fzZytXZ>^^hFaH@5PqR)RnQ4~~s)Z?uhQwT+<4V#(8Y{JsV{KdoBZ z!iWwVYis+xweB3iDQ(LRAQB|~&pM`TJEva2i5x2}T%s_-5`zNMF@5V7eG0z5X*0=c z$MZem^b^Z}U_=A7;jwUium@urlghd~?EElVaW?p9`$EZU>BUrMNX94$aWo|*O zym%nX{b<)7A69W}<6H!shl}?E6h>7$hr|9;y3nTM6-j74xC<)*jtYS`Ui^J(J`(LC zTO8R4*66w^FeLgJ)T|@`?xpfM*{UH@36ztoh|w)6jsTd*yvULU>x<$>c5Ab zbVRlkRH0LWkt#FG5)+J62B&^H(>z4-YJd|#WGsg_;v4Wx!{-3dn^*yY6c)tCK!y>r z;tOvoEm9Tg&SCwoKrjy~{b2?^$VpCAL_q>4FQU%vBjYA_>|(0pe?Qik(L=W$j#*xF z<7vx=l@@2FKR>}UAU@YgxFl--nnu>qPzH_L0AHDtUedvM2{%Sl1=rp!+GULYu+XkD?mpon44{d zK!;F<$&!|?X00}Umbc=CGO?UdZo8kJ%wYI#nvbMO{0IhNVh+vpbRBy>GC?xY=j{1^ zK10(~-2}L@Lu@oJ0ErS%xD=QyjNW-xD&dt$LIPFd#9nysv2k}e>yuHm!^oG<{?s#%MMS{fMm8lzaz!*H<%4kdt74+i^Z=TJyvd2AlWr7 zmc65qhum1tf9J$wb;2-4ftC2-x%VX}qxOKdLF=`us3HE#fA{cfI$xO%zB=!|RUO3s z%08i{tg~r5b6$`F%w9x*nEHv83D`NT%ycKjlO?WzeOT z#j+>Z#0L>pRRJ?yv9Hz?0#_dP-!2PcG;Mt zpZc|D)oG8X&9$rIu3o1_FOA=7L_5P6JL>Lii@!foVZtX2IRBK)AEWiVD^iv2<8PlB zf7Lx5BSbVBCBb`@{Gtb0x_aTVEI`C?Vlf%X3cLi3dkn!N9)^jp1;UgLuWHUuXLVfKgw zny0C2Ky1Q;WO)e^043#aV}P-I=JkL@Yc!kFln+YCwJ}prH{3^T65J`^f}(b-Pv^#} z5AF2<6&};8X0I8z?cY_^biBjc=pEO-F-z)+ePt)$jD>9Z@Vz@Ih?Z3V0>|m+Zs4uF0S$ZsC81 z5Goqy=#~U^bS8G%2`x++m>3M~3`8b!Gj=uq3n2QvSCAZMr}ZDK`A`F#n|NlDM}tujvfsz%BOT-FzS5j800-anl>gVALVi;L-LHN*@UL0W zKoW#Dydoi%m+!a}h&4UHb)w+~Z}#O}!6UO@1*A)@8L_}&3SKp;dG~0wCTzK8U-6TC z^qCJD=%1TBZXb_nU8&c)OYn!<^zH77Ps#HRrLTQ7CZ-y{#5-MiQhxk5>f7B1sWGiv zd@AkAaE)1(NBg7%pDx|dw`MgB&pA1eh&v27*yHDCMl@{>-)&1Bo6JLC)Q3)|_ij_O zfZ(|Do>d4Bpsbs(3$c7Y69t>Br-QBmexE@>RyUY`U-pKT31$3>q=>TgS)w7PrB?%4 zL36>)1K*gI#in5rJ9%jP0BGBYwd+mw!ZrLz zb?)=RzN-8yuu+m>8;STB$v&E;e#EhiTTQ`=nyT-)>F%R$+KCWQ@GdLrdfYt(#()aN zQEJs(dY9n8ZbTk#83puOJNdm?D^q@p4;?m7R?M`Ca%r$I%P;Xd^w#_XUe&Z*h?Yv= z!unsh^x&;C@7t$rZ+IXdjn*)-?jv}_^Rs3YBwnD*@`R(D1oVP99JAf7b0GCZGpjq0 z%a|N%+gR^z8(J*c;4U<_LdR3Mw!ku#g_L9U#eC1gm!ZYqM?rOIVe$8GEGltL%6Xr$ zP$IJ|Bwk?K?`6H7kr(!I?#y@at$5Z%JRm#JdBHs$fu|Hy)DHV=@B-2O= zbfI|3N)$C!$6FwxVXs>1;6w}ty`D;EXB*-AXH@&FBJ)((Te?gIT%q)SG}#MKk=^RO z4i)AmS`@;-T+`Z;R|OANiHIzUEtydG%0cyetqJ|F{p)^;4l?c}-k$!2EAWE;O+-{T zu9E-tx!E>ZZ;WBbrP+DG?{;kvf;p@XtHceCRY5SHFCyz%;tBN)>)Dp~gL^d>E>u6% z<{o_XPsOMs@ATVeHMRSBn>0oFd#afx>Z3zXP99p3aal_J;x9(SJ4r+Y)gQ^ey=6A6 zvPd3-uIF{Y$rvk4g#QCOU^A!@=eV7`YLR|x{>_id6P}qF?@SG=PZHX|C)gW_9jlq` z3vjCut(kFH14|&+RCIqEfGSw-0E{3BI`k%Q6;nEbslHfg zw6dV0oPlPjR2G)c3w$e-o+|gtx+0|of>+L2^TF6 zI>f~EAFRDFIZJ8;ZF|Fl0SE$e;IeSYUYd1bidTMn6`WM|hY_lN?&>`$xQDla@mcoL z&!2kqVq3q=8+ZrCZj|pyv@KJmmPxSx2}h5saw*b>=EpmKUZJNK`N9UTtr#>tDf#qf zeKtPDAjeEon3tkvEicgyr*qD1dCrMkTDU+=`r+BO-;q>en*GWFU`F(Dj4*M9N&-`P zmX2tI%e+rA6~Xm9c>0GlvmLwElbS9}?5>RKHr#?FF(Wm)aGvhMnP(}_e^*ScjB`J% zbt=Q?y=R9pIaU@67q)y@-*Wz~9wrgZ5u@6fuNuD(0>L62VXXUtV3P;YwIa`kEc z8jL`=T5bN}HRSA_ErhWPUE#KR9wyt-=;yH~ed--Uet(_sv~cNP{%h1=$4aWLEU}VC zDGc*9M$~U-k~g{ayI)?5_IrqJt?HsG@p_+w3 zv?{)ewtNQ;AS?$S^V+eel5fO}Us~m}eCwkZM$u&rZFdx4C?gk3f^*XJ7Hi@1gEup` zNNeLNAPNAUEawUMpu(7iwUVaOFX<+u1tOufwo4<9$~1j_?2wNWQ{~K+Oz*ik->_$C zq4j@*GQDi`-oE=bSiH};Z0=PA)7CQyJF3&bBkG789qZZuD!OG{Ve!|^#UGYPE zXYbB6PR^Tnuj~cmcR_M6_b%&7^HJb8anNRc#-}B5CEgeULM#TdnX}nu0X0L>GJ|aq z%h7{J{!#zyS!oq3pHOl2aUtn6CQQ zGrW#b4uH}yUey7wjw*4(a-2$IK=UTST0g@pz6W0@rh&>KJiXyORCq{(Z|27T(?k91 ziO3YvhiYH0`6Ili$bNIkKF77e|brnvhj zve}42$V8JD?)qBzP3nboLL-;|`hKD+MHq6k@JPkf-61A?20!f>Hoc;*@_*jkEI95m z^Wnp4eNH;vb4%1dp2z)^?f7&CC)~b!hHsxc=?gpb$rLW9DuC~sj5)o6x49t&GLGad z2%)ld>HXK0H6=Pf{a|1~oB(zaNZ04Nk0Q@4#7Z+1!(xQxoe#50S4^+>tFV#W`GYi4 z4tU4N;8OO&@9F1ptc~2KoRII1T^y<|M=0W{p4P<5F2eqNP&v2CoAzT}dVL(Zq3AuPcp=*S)-ZCm z{n^v#J$<8R)SG_8CTjiC>jpeS{a>%w z8`5Q9^dAjaV4igQw$p&bvWE{K;7r(KP9oJ4|M=Es7GT7$P3eEC7u?C8gox>RaUQ27 zxW}|i%H7|2z9S*V*sDGvw}{z($#oW=oNlT_k~j4Kyxp0&m+gU9SBV&GaChPhdz1Fy zIqXeaPw7LM0vZDLP%Y zrx|uG9h`q#RQnClr_jofs?t?ww||IE@l;*!iS_*Fs4i<$HG48G{*u>+O{dL50vo6C;=x2M`AgxyDEv#j}eyuw9Z@Vc~W zBiXUao_qWL+S~7TZ~OWBe4o1^d-9j$jWeByYyNTysm0HF7Js2MZ7rT9&;9a5n07Ue zt-I8T`hxg~MI<>{_*-3av{Hy52v`Fg0?vd@IN~tDs_@DwI2sq0HB~v=XR1Y@QADie z7RUxEBzp+?Gt$=OExqD!gHmx!Z=Fp>rD=SEpZ{*zWKIQqIZl>nTk+5~kESA4=p^(a z%VG&_D^&ZKQYCNq#rAIl#V?Zdwu3g$m9fN(h+NP`zxqGtbpq59w^0&~+-0?i@Z(9_ z`8D06E;=nWcT*Qm#)TeyH%D}*Rxze(6Np^vx|5&MYSSAWtwY4xS55_A_k7+s=6(P6 zK`Jkr-&;?lg457=tIR3yE&bRX$7@~A9K2ggjW2wgyelYr>cM8Av8YZpFhgPQyk@JH z*RyOQ_DVFPx?;^Ow^H3rEJ7?~6 z8cn>{+Z9Msm=+}bGMqJ5D;7ZH6!2{ai9_*}=)grO;S3wexgBUsk^t~0XqDU8a&uXw z0}@sNqgct3oSPkaODDn*(e~FS-PfOufu?mS-#arFw`v<)2AR>iM?i& z%V-MWW*UU-wgvTlpgw$uK^S%j>OuhuOmPN@PBb!;r%Q#kfkpXcQZk*-udp>B!yXQb zn$@7rJdsNa5VOy{0RCZ0SrW_)u_5lmUdOv%U%Q&e3ar`|C+;mR?gydM1@Olk%w6;g z;NQeHts`6|MF)UV05MekV`_&j=F@4j-)45Kocki9t(l)1uWb-r-Z&P)XbwWLWfBD^ zJ*#JCnDWd|N@?)l_5KUc_j*=wSNpW6n`?|iXBPP)@mNw!EDzn$JOczWgZ3Wp;rf@J zPkDs8NxnMsb?n6SrL;5Ns`DcxN1vn5Y|?{`{*3tPkG37eBg`yaD_7Nn!-juP-k;A3 zsO1;D$-F$CSt$BMpU1@!acR~~K=)ef7j8935m-6E*k+#+`Te;l2AIFtYX$H$oC zP$JB+gA~&ownF64M+ZbHX-*p%vrW!IDEPX}ODFY;_rCMWNl)wMcHY;eVlgTeU$4hr}ax2HE=8Q%o+f%{ojw z!rq8n_Cu6bmpjvn5{o;zNV{?uK<}0K=%&VTV>_JSjF}2Z;CYHgr|8ZPU_2C4aZw+Uh3Xw4M=)p*W~>qFX4R*_5PplP zuw0ZhH|(dknNy=5jG6>Ag8_lH4%7VKn^aFHyg!Aek+0p?sQl;do6Kj{s`%H}O=N`* z*o3Ez$+Ttt;JOorY>yM^abe-wg0Ssa%GF>kSZp;OfD$;EptLxWLJ4)aF-gIHTm5P~ zH}CBB14>0!H2*Q_ksZP3+sC{nc=l^O`PT07yf_P`Sqftdfy8{nz1ZJdIXo&3=+!uV zB~8)FFAXC{zU7Fhv#oMX>hak`G!a(MBHN|nTl}(HK0C4IIy#inxg<70DcShX0{OBF zmhZf3#Mi!W)Ve~ZAGpO1;ruMfI?|2xbN zf#bWrwVwV#6(DLYw-1_M77^?yIx|V7vfJ_$FL1r zO0IJ-8dA4ZsFj~$R-Mll$nE*lZW^|qcQ00%by=vCG-#na4GETq59(Q7IaRyV>LNnk zQHppXinul{S(;!X8m{p5Q>!kJs9=8<5bc!YKX5c8Ss58BJ0BdE3qL2T!>yn1ot^PG zP3sLkAS|k=bpm*ah68~-;1V)rzQU{kxrfW@sv>K>H=`)R5aK$Yrw&4jU;~JNC>*nn zlR$sG+lfnx$cD)FlrHl9F;}<(0Vf`&bEtw2%~4G8wKQQU zIR{-U(BJLQ=JW6SWE)`4Mga#hdZnm2Lz7~Snw0RR+&57e9_z2UkGWW5cG^*sp(O~Sq!k32>Bv}arQm0@@S+aoaY@*4r7y4y_{0bhlPf6aMS8C zkR_!|YjN;M*C61qr>7(Y3Oj8`^XbiJPBK~&vjgnAZ0aO)K30lJ4P^N7D)INvKM>E+ zd)=3l0f|La;!n;sD`|Sv?5uvLyza9DjwZmX86}I|6gmB%kZ57hzU>uULYdOXXi83# z(mdR~?SXNL2CfZlXq0f*-ENZG=K2A&jhZ;jmV2`WOXewD2$v*q*Umsze^e0sfa1J~ zL0|+~7Uv8$F{RJM{8hi5sm|OJRl)=mup5~AJqK#{5%-OUM^RL!#{T?+j~Do}`<`P^ zT2V4%`p+KsXmuqvDZM!?^8VkSweWvyLmpf9|8D!JDWUAIX+XR!E$(dF6SauFFnGI_ zv|j@F5lNPBxO7UB!+x%8ZHOr`A+P0l?)2BmW{-H5B^OoY2G{Vn z4v7P&0$t_-bifxU0g+xikU-1H=^=5qO9%vxx}XqXjgUQ~sukb1Jr$nS(uERBB0>}d zS;jBFG}S%ioVn+G4UfP}hcyy#YDd5jTf?p<)v)urr>)YEfip&^;~odZ9-EvjcdbvA zQcrod*gF5RKia+TGZf$unDb<}e&5^CwT3YhqmHw(Vf?;%A16e0XU1 zWw!>x!fK$d$gwzf!(Ed=9|0?j?l&MRuD8(pcCO%dDXP-Ge&e4%&9HfqxzOS>!obdH1w?)6{>)YBCyzt&=5mP1Oovm1ERiC z-sMOlTNbW0R-o=#E-d^%1Oquo#!$36u6815r@Hqe8~CfDw@&BY`M2E*++aPnfEz48 zbm_`GW032lEuPyR3H3Cq$!v&3Nx04@a%ENSSBz#9FlL3i847Ht+jRAzme`umDMKX5k0u1M`$9w~#7K?P5 zBNTig59o}e7TTR_UuMl4(x$(C4ZUzEEdLi{xN}ssLSmd|C|Vl)nmQT+hqFdLdA5Jm zEY-aaK7cxx_N=>fjQQGzJlF(z38xGy&yQ+VU$6m>wkxk5;pGe1X4SpD^-aEQ^lq0* zrUK6|%5^ND6h1dR&cRX>OniCM^7eOJpThXJ8xo@c431cMY$uxcder(j2RmrkSmdg# z#B#OK)b5I4Z~2sb?J%v4UpUM^sU7N(^L<@4#`&70U>qMAs=riG7cio$lgha2qPOcO(WwzYDzj}8UTY;V zCXS@yG+95uz>{pjvdalrEDPppi2^=reV8q1Liy|Cchhyr&}4=EQD)aiX8zR80d6X9 z0^KF)ha>+XNY=gX#vy+AKkkc&xw*Te*7mEnw;oUs>m}by*2N3BFeDX#NqA#qI8-tH zprJW9ERNkJe6x=m8id#+H}vq41V}7aFaYHc9Q76@Dh?x7-BGgG*E3!bNAW)BsHCm( ze2M1Lg+aT#^IH>DOZik5S*;Q;OwO?_|A!?y$lOpRKD+$+)s6Z`N?z4!&0Pru9r}q5 zBnI?soF)XKN`>O`4>!H=HoB4}j4>C4={$x&EMRlo(Da}aZsc*AN_TJe)z8y%=W@m4 zD@QYbe2SUYP0WmK%6#hNga5SKI5DN~aF>wi>9_K?or@{wAT6$DyL0Mg);_d+P~HRR zO8fZFkhtYL!QtwGV7GqtDsI^r$CyK--5br~AYIk7wTC&}QaM|8uv=hn5cmGWqo#cY zE_O0scltNn>cct^pycGv>~@tWKXi3sC|? z-dSGnzcR5g$!ziz@HISTL$W?W$snj%5lGCFr~bGT1|k2mv}i0tb>b_gEhwQACy{;e z=lsRn3QBd*4nIa>Qu{y=(48cpWZrm}PmIS;42(-|9%8~30!HSwqKI&~7Qkbnqm{1p ze19}E^qW`>$okNxUZQPo5(e}CQ}9Yv8y`qJ;Uoy3pn?hQr59nZ{wvtd)~FGF)4aa5 zndY5|f*Rb?#Iz3+85uJ_>sdarnTJ2p)mcIh06_%APGI{A!3Mtf`1~-S<4#DQO84CM zOas3ZR6<9riDNTGJ{S~KcrScSmvgYu6AUVE=<19< z_+&rFf^&vcgeN*2j_?l8jcEzCKb%7M=UkGqt4uO+BCin^J|OKX4KcnOrR}|pp-`7x zPDE-w(?Eo&yIK@C;_~IzhK#&F3JzFjjNu%0PzSMtsIGv*2*UO!V`@o?pTgw6bKQd( zwhgs<4yg8VPeD4e*5ZFYj;@8VI#C}hBTEI!ihel1EpC(j#}7wUU(2jELwUiwfy7|9&)9U(Zvp)b7?FBM}l9|$?C*6_vaW-|JO8mFZS38LuBy4u%Rzc%P zh2GM-F2yDR`fjN1O4#*^-ihw6jquo0l^E%0s&of0=Z z1$y63G%3yxd}OchSt}PTq6jrZHBW78Dh}}`NjG1fAPj~~w3LhueSh>q7jK*e$)rDg zG3bzeLrjZu{nNqlTW(oSlVjCzCb4zGSvf~JHfBmNZ7yj|*W1#|w*2C|*$Mj7u|ppdsrUvd-wO|Y z4L18*IzKg59URPVHiQq?C*+G6g4a%^4>AMNg~3!HDd-^0t_~lM?<~T~xa7JU2GGv{ z-B+}gEy$9_;&j|_xrAD)+4e`~wyK%KQSYA-D5Kv03m5`j^Wk{+{;&0Lz);0oOo5$5 zXAKOCRWHqFh7k}hYvwEs`1?c5wJq-N76{r3i$Uz8XJic?2K^ud^gFAmaxU>9^;=-w zD|yKQh_DRkdYp=P!kWjOzt#V9Wq14Uv`T>u$O0JSv2do;H*OQtxpj;6`G!X7)!C8Q zHEM1qyBj%o!@zsbxDuojLN=H(WEcL2Rn^cDjFAR-EN^(s5tMMrul-?lUMI_aIc@WFDU?W z!(;g-u^pY!p}$o44AV*|Bnj%2o8bj#M59`~Z4BSO{&u~&-|6RToCN;?)<;ZsWclWL zRiXbC5vikyPjM_iy*QlDi2r)-q*6Q6_!VvQ!V)K@$^cqO254eJ!s;c@TH=_%Lk#xA zP3!2~Lj1rWd|L#fd|}z(;+~au46_+O_X!OGtkqbY69q0blXJ}Lxw-FW$9{p*X zFru657&PmWfHqGR`(5u5!~cI%$E-DJy66#3WX&w5V+);N_aAVa-wvsTApREQ*fM}@ z+gRQgUaOoh32br#YxKGAWad)NBsH$XLK?;#*rFCA!sRHEW(iZw8?bf=4YfG!SYBg_ ziK286x!)HGjuQJp68h!_AOcD=Feu~i3p)vVuo+8200XiWYes+iE8&D(k#yI`*!|a7 zhP-akTUsZ1$twRPn&)$DV^P-aNfv5YQPL8aq0%%M`FrKZ2e)NUT+^is$AtuEtX}Kl zzP~4a;&ae!D)O(L zl=w}GhZml^z;?yMVUe=O*MB8ZK$uFf+Vi<`^o44qI30+zSET35=P0tL2XKj`7oHkawQn1QPhN2bV#r2 zhRvS@`tQRT?+(&**Wy8R-K9M}yQUn+(2zseCX}{(%txNi6KzrcsSZ(hgb&%l88H_h zcySYmilc!$&VEvGyA)4sjcoFqQr(Pb+Y_PL zXrcjT=v+Mx2qoF#e6w-d>e#7R*`Tt_)`|JvF$;zg0KCXyw#Oo=Qwng_Fd3>em{gRK zA7=p>L)*TZs_PpklhSY~hU(&yV>lkya$ZA5=UpjMayo6RtHUZF0V~o1&*^5xo92fq zC`e*D{x=@;?rcvEtrlE27*nm;&>^v;kZ;?tGcOf|;*zV|h1MJ19J!K9CS*@a2Aghu z>CW~bBx9O0s;pnsvx@1x7eW2K||Zeml`>Jsr@ z3Dn}rMj%~y@8Vp5J%J80^6RO5X?o|4naA{})=Lg+QZF3$N-`gBflyC5j~D%yNMlMt zy>!12Lgl~Y9p}ZQW~UQ8vNFQQC3Fvux}Ve0;pX*UQyx?pgBZNX`*OA<4wE;QXpt1f z8xjs$S`Fq%H|IWeY%uXSn@(5-rXfiZKFQ7i3|Nh|e&1iwF40L=r3KXM=ZLuS>tMz> z6|X{PBHHOp)k9znx`0Bw1+^GcI%^Vcb9(!coej`+G^n~>3$3%lq*+lY{u^9N-LK?Y z5b%nWmlT(n(2aU@cIZZt({+6sE^4c2@NuF`GeZ&3UlTvvw|TW#KfHjwsJ8g~Wq@?< zMifIH(4QqGt{X^HbZ-&SJG`G!&>BpKl>sv978<4?zH;Z!ZaL6vKF++;O1ot&vma+i zO^zF2N-!3#>+%DFQbf$n#H(;P5c*LbHw|_CMZ>Q8|dpOgf~ z5ILOJ&-2+E=YC&;*Y2FEgUTy85tgtC#r31xQ{~`gmj(FE%z*iKKbGx=<%{*2+0##+ z*ph6{tK9a<^|H(BfJ|kF-(@>_s6&vjlUU)tdRz}h#8+Oc5{sKwbfL3zzF#TM)|@*!mSgq{P}u2#FW~ zfg@p~7X$S5CkD9_4uh|#WqJZ*WHE-j@8rDOjTl_efC1&H0A{Z7H65KC(=31hNaw35a2&Bka&0rm+r7W!wV@NcjEovq%< zvt^X1n<9|38J6_L#A)SNT!~ik+5p72!mwuliDLqOKu4UiW!|%JP>&AMmj=rW#9|CU zahb@r86ydp&B;z7FYpvoaH!&0+=KTXH^;Jt!R%k>M5U7Bt>TW%oDzsuT`yL-c`4NY zeMMh|K-6mM`T*W|q|q?EK#@17e;)CQfPYyX;khCSwEixX#55?zQL_a;ZYbYzI zZZx^S<5cV8J}{ry*ghs1FGHL@IVK-ZDk(e@!cyN)0#_Omc%k}ApE}*xqxGlun!L!7 z)xUaJgfEn&@HyhwC7~i1OUs5tmgBU4Zn!?=6FTaKxYws}hq{Pa_%OPh zk?ZR-c8YAlkOWE!coyjM2bG?G3an|`l}43eC0~mv^yM(U-}1L=dw!+MBSs#P_9Ndu zmYC3obHJ5!O0HsxB#Ss({RTyWyX0^drt;PRvP%W<cg5$G|eVvsd8(-9>9;abmuh74~9x%Q5USSqo;4?XT!#wJ`k8gj` zx1+(NRnhnkkiwF{^0J7%5Igz5s>Lsg*;Xc=wbxw1$XdNBqui8xNG#g6mzUwJ2$jt? zmZ(XB+}HDn_e{Kv-x2-fs|Q}kR~ zlup==7w)A!_FQ24#h@UOy9Ph%;G7c|@&i4(kNA(pE*k?mK?|};n8Tq-?vI#&aHuM3 zVBnF_G{VPO_eeNt*l>B+dhFuetHV#d$2QotRh;g6wf1#(#rDyNKm9@GtO;tx%&?f4 zmh20lHW^M52r`X#v7tdeH?^L0ly}rb>H=NW)ug;(t`i5;1?eIQc8WmEc8mPAELqLyKqkO6rbYB|O9l<<=hCdRBo z0E)m6z=~`Js4tM6h z4QNA}gs?4t&-Ti;I(ky{;CJ$-Z#vgYq?*+qzi-*H$SV zq2Hg%K%SM_>uZ%~RyzT6kb5GbAOl}f!{Ye1^tru~XsXm!&iH!m6S zPfpsJi~X4klLCSa%>m)0+q1_mKcv5!x7{?%!;jwH-P-+a6!We$U-rD}&~_99=QuPmD8{t5!h53>3 z6>1H9r`3Q}=_avyrt2R)xsy5Q_10===wBUg;9<5jvg%nJlpTCvx3pf}2~-DUnFd2Z zqnox5t`;y7um;Gk;yptO4f;M$*n!?Tq?S%GA= z?fx#LRqIRhc)#J@OvF$%>_m{+?ho-O5Yv*VYm^1@R#TtinHEMX@o2crEW6j=D&czZe2e5 z;?}liSDs7rWn=s;IHgPFe5W9yK@68Ckp!VSq%Z%ZB8v9&z9Xf#Hqib%Ly0jdsv(h)#Ez_$nFwLz>~}>F6uQJR9!BR20QmlXhcG6QK`P5n%kyZWw|39_ zv%fq=?ICJn!zG zMF5R)s=xK)Rn z84-VwTkyMWD&w67is1mKqoev3ndU3RwLYClLE_SyX#TZZNziJNMYy@@7=Rj{J|M|7 z?*OQ?n$BK7??HT_peS1qKt#Xu+hg~q?3FJ15mlbd&yl}SmMI+Ph*v8-{rknln`2`V zy2p^{uD6SgxqC0RZDCAKj=x#*)xP1`fd+zqIT!`6Qwt%^<#Amy4*;YqnvEdtBZ?dV zdRE5oQR9xmaUwFJ1rc<(sWmoX?Os9s+pDH?VXLhkNl45v`sknk4D<{71r4P!__?AT zKk6BvX9~`48F&2Va75Gu1n?~pkPBfiS)y^e{JO&(>ia6Rvv)umY<}25x8^dS8$NJb zD%`8!-|mJ~RQ`@@G%xdW_UFH03tcLgAB&KTjYOD_`#vzLs-%a!ly9bQbuGi8*`*m# zA5PB|8-W56n+^6!mTa6V_`B?(784Z{sru(z1TVdMV*vwo{LMsQ^eV9l+*;1cYw4Y0?&g)VO5p_~R%^W^(^YYlr>|P9!V!_doJT zQK+d4S2SaxOtPH~7%bxwAieyq`J;=h>2r z?Hqr=GYT;*$c(A;32OPRyoZNPpw*P+`%Klaf1RTd8;J+bd=1YzluTaK0e#>LPKzj&YcC@NbhKb+&Lx?dDAm zh}7D4o6j#?-`NV}{|o{*hA7^n3y?g+nhn@%S(xanQBR@C+ z!=9D7cGnhKd)kirX)nLMD_E7WNN;LV#%QRiKHJgTK}5N|5$8YqqNY+hJIB z3uhf*ofwMRLF8p2xsck(tCO5?<%AGugSBUFpYc;C-#Dxd0B!+Ob@9WaU(w`6|2GY_ zhAfO55HpcNms#^>0h#}gIZkJH`!`eIW!$iF>w5F)!mUOdp20=q%Bht}PED$WeDluF zpM6)qthcqAZ3UXVowZkDn5GJqUaavbaDUj-_U~`?avZ7>qi||xJw3hEU3b<@cRKlk zJ}9}fVKlZL>dK7t3O~Z{HEKsniZ?Hh)P)93W*SiP7@B3jqH@PPc;(7xH-mh^iwE$A zz%cfZeaKhSm$w+GLbrhP``1FE!4M!FTHC@z1G>P3AliUt`9MC_9EAK1K){v9m3kBe z@q^>O)obqaUM>IH!kf*0x3-mIT+$2Svf`&s-zbxz;Z>#rm{Ogu_cL z7@ffT)uCbxa%)zr3J}4~9$4Qe$*@*g+eVrGeb^I!4V+n88<_QJ=BS>w>P5b-xH4xqt@?E5Iwue99>tR-X~vl?0SWq>aJjpwRtp{WQN)uz67L#n~z=L^_F%nY4M{m zV7I)Y)|-EKdilFQqx)J2Da{miabJ$6=+XK@o$Wbp(ETwE%1Q6QE6u67KXo10kSR;mlY%hV26rav%j5sCW~wP*`Vi*?vD}58 zO9`7w2!oZ%XN4iun)vh_C<0q1T28@>^?zzaNhoKJ{%lMXd~4>-7r@Rgwds*pMgs2^mDbZ)hbs58>M z3xW^RG^Dhqde=H4_Bf|9j6?zkmGz2|IaCdR_IhPS{grUozm@N^JKGiwZPY46N#CiR z9=$7dmKuw7xcrP1l*GM>;=@?ZMuP-B^s=ol=83V+pSUmNn^cMR%%|ftsY7t*{aSI* z5aH1x&@@iYhp}Rzx17zG2_9hPZ;QelkS1ppg+T4PpObHUQ(Fscoc@f{69t??NB!C;{b+)5p2A)*J z7}5!+<`_K)7cke-QK;FUh^AVi4S;P;aj{|o_NGxQB`U=C4zlC1t&S#`t6_lPzmWO* z#C5^g$2QJ)#afs|OjHjYDHAIQXT{nPN+VX7{_b@$6RZ4!w&=pKferJKxZiDc=VK+t z={!68CrsiM>2ZVu>*CJ%xVu6&V|>@KrX2yRCk9_E=h%>NV?c?z>3Iq?xh7&YW_~y( zqB8KErI*`4|9;{y_}l-O#5jqh{R_pTaU zt;e!i)t+A25Dn$I(XX+WNw+3^2l5#I@%cPu&=(yB)*`@bxjXGkIVd- z<{p8F4;w%65sLoLv-a%ApcBtc3U>h%;<>8zote`f>$|tVrbWqJQRY;Wc54T(B}S<7 zvW^c$a|X@)kB~sb%Q7PTA6>pYrFr*f+e2Nu{J&jUE8O~YiMx`9a$#bI$io+gA@LnH znWh|CoCe+{E4q-@EryEpY9RE>*}}3G&2HKArk4Z-NT=gA9~Q}rn!ujgfsH1IvycDb z3AFh*fwJYb9)}@-95zA=SPPZA=PjIRa)WCeCbJL4=?dfi+I*9K{C1{+Ab4$#@djI- zzf^E&LjDbMz*RnkWLi_FC*ce%nxG}eVO^Tv2gng~D&j1x(2BrrF;e$aCpr>bw*Pi_ z2i>3wkoOalS;h&`H!p;trV2hrGIi{olG@cJ2bLPXrL6#${+|>kp&C`0HTwd=ofW!|JM$M5?S4cYCh~HF{6P5U{wu{?jVEm zlC3K30cuK*a0xLCjJ1K|!rr6%Yiw^n)){$By)yT359|!u>T;4~*tfYRt&eNta$#@G zWbuto7t|^UZWt9%TxiFtxGv0Y+Nr#FUC*6<2{Vv<)h#AP*f=W@+QgAl3nAUkGf^&u z3WME>?zA%h{oedpwa(V&N1Fxu`oTZ+hfz9Nvju7~yT2Fve_EF`9=Q&Re%Rb^KidkN z(F~86zby8GXuK;u?|4VH0ZBl#?|751CEoo3urmqHS5~wA>V=dGCk5NFA6*q$=eXh9 z=kPH<;6gD~ikqUM<5cK`r%Q>q`1PnRVVL!FhhwUqCdkJR5b@>mF6MHBowexl?DmH7 zEIjFY*5&?ls>G~)M!9#aEL7#r*D}dd>d@gD*~hJpwM;76MGk_8RON`NqeKzXak|&c z-n2DJwCkpQr@|cwsO&YIt;yCYxo!z<>%=um_B2qt1BL*prT8?;uLZd1}sCsfSCl7VfVXY!kDakW_q57$AN?XwW4G^B^qBGc_I1b6}xcbKBMK(uzJ$( z-Au7AsBJ0<1Zy`mn2NW9L>Tp2HP|{syI6+)`=-;55?x3NCa;7$+jUR2{jBriPiWFJ z9$xX>Gk1Lmju;zDH8JZ3u=~`mt6Qq`$ONURm2U$|Q0Hr`PyRNBPfoXu?}30jDyJ}a zCG;#aP~6pZ!ufpes5VTyX2V2-LAO(4<3siOr4tZM4@FV-MX`eCUm1ZvSVI;cUZ}mw zROP5#`v;uU%Z`QpFg~q$uRK;Og>E#KNtphTbgE(d3wtu=*Qv<1LUOZJhJ)a z?4TAql;Ws8pwLvig-d~J)XQvZxaAz5j4h|(FyFV=oxuAco80oLj{=bjtoJhS-Pdpu zMTq~k-2ulTAs#an=M1~x!}1%-wj6u5ziOD~X8c3n>r~__<95SFMAqRrB_PUE$C`FB zabz#|kbttZAL&E*d-;p5@OAIARKFQE0n5c$<8taGQ>&<;wv0v z3(bzevck4As$;Ugx@5;3_^ICI`%>Gd;qKy6D7|3tBH`(dv%wMK(yOI?P;7#_?c^u` zz@$rE>lplam2siB6tM4xX_W()Lqec6US-ed+vBB20qgIC5PR1D*@LW|u(_^i9I^4B z`fCFW?_*(A_#LyKjp{c!*Axf;fDA8axuhY=l&zxgMBHjCoLMhhEO6cjam8M%gbIE% zo^4q8a{AwI&SZbfO|@&HnyP(%7Z<4SvaGRPkmDTWM--HwXFm7I-N@ovfAj*^P{hiG z=99{iP1%b6DXH%Xp2^O~K>?bqJB7hq1Laz$iou+xeg+C(bEk^xlc54k0t5)T1Hmf^B@%40&X)rFFSt`xczKQv)kL|^+ZT87#Dg&2R! z`u69bSHtvb$szJ#qC9$!i$ksafaQkqIQ^7$0IQA}kD(URi{}vURbi4|N!!36AGf|m z#wLLB;6%helr3<7o3_|#X*@hZxg*OG%`Lx?Jt=5!KMTLYebmrmR8jqDsPrch_MKqc z5s3On>k*c8IZ2u7)JHlnrdTYdqy=C+XC`&G{KE}b>YgyCza66g8{mD$`b73XrR`30 zL6Zi&!z|_-TDZ2SRZbc|ox*s@E9Z}6J)An3Wa!Y98822+Li@3!4X zkJ>Er+it8sD?oGzK3f+!0%Szgmpi$_S1I}(#t)lA*1NM@82XC7Z9Y zRz(mBg3%}1CN-gMUz;qsAFl2voO1ke@uXXJ5=!dJ>Swkt?Z+PgoVy>=nGAYry2h%@ zHC-#J3^(EVzY=a*BVX$afxZkN<7h7Kzp$^x7GGDvuNwF|Y94bKy`EWJFtU5C8xABJ+HPvQz%> z4L=vpiImO(HI@`NktY!5v62kLAyOH3uXx$&UEpj=gSRJZ|EN=;Z0ygKjx5ZO0VNna$Y~2ZMUw2K;NC zT>jo@t`bFpcbmF%rSdTE8kU}mq0;wAg#G#bdu<_XE9Nvlc+tHvnEG>gBhoOb88yiH zv%YiIqcZEJ+GHJ#Q~$)P@tWVqPVQljKw?8!Ksp}DAHUe`G3g{1X5P zb(R*uS$$f1Fi`&b0fT++JOfvX{+NQ(G*!dd!3Q6A=zVfapi9bQseR`{Le75$%6Jeb zgSE@otV$Fnxgob_0hzP;PP9i~PiEMC;NV25@})Y}sme=YBDp*Ktlm1{{*z|KR!$FY zG;SnF01JEL-P3x`Sb;`A#jgQp^X|shojcnx^!p~$4O#Q5!eFoq?=iDW zMLVjv_c#f_j|8d+QC-I%Ep;`+i6dLWy5ZwwycZ8kaE^G`3hc0v1oGT69}?pM??B$g z4${t}BG~O&-(ZPK^8u!RxmXc^#i9A_X+QviA^-#HQKahouG=URHG0-_1Zc2=h|k+# zM=%(ypin1fgTidIF6x$DZx4HgLq$pSpo%GBGLo#%sg8G=+Og+z8K!+cKIv2Jg2856 zwY&FlV--_NW=Qk$K=l8kGzrQB(^uD9em<;sdCpW43RfQs_-sc^k+(}bJk}hsgg1&1I3Cs;n`Xo{^M~?o9PMg{<<&oxs}@$Gqa74J zO-CEvHjsrBSq`^~5j0x~eY0*d(=qm{{u^lg39T z{(Y72_H)UC<$Wym6@E=z7e1+?%%d9SYm{^~aV9xicaixo&nH-zaK?(L#WM}|^8bRa zX^IeY&;MH)S{pi&Zm=2I2>?yk$eKdF#Ftj93Yg%eHw7F1z}4pq@C0u)j07|WgpWW3 z4g$mNQbtPDg&t(w^2RD4TK~UP=@0PWKM7%NG@-&*?GB0iZk{3&x>W-2?JW_LZ81py ztn^7K0C{hetTcAuw~h{47xjAiazp0Jp(3nm1yVt_1G^aC;HU7!-%kZmIJ209(vU5;BhVEj5a(dLi<5Ut6GojP`+ zR6Ts3kd-1M@ktXi?&~>onL79R)|T@#RY8oG!+4JGQo#B#yU8b13sIf(TtQs;Ddfd~ z`&840b&eToHDTvMT;40hzuPS>rqc^Lk1!hIH(X!mU_Pqg-EZtwaPBo}TCS?HUkCPW z-YzIkilSdSi5ZNws?FGWr}Od{U>7glnLT~G(S7&Z@%tu}V4KC_-BCrOzL&*nG zE^>YX@KU!cKTMFe3Zg|ybPX9?a70?N*qCQ7{5=GDSfuAGe*mY`Gd*n11_rAB`<4EI z$IA@g0={$DA#DG(j=2N$ZlQPMN(1y>n}07K0gJ(#e=3_uCx~>ZBV0iAP5sP27mNHh zbwt4!9`yY2t=TJSEuW4WRi4g{(7PK!UA`bQRNT3sBHg{2WjTLL>}+4PDRaQLb4w?F zl9z>Mk*@R-(mR_fJ@35Qh}!liW1B11?hQr>4SmXMtcsGLJIcna`a`gqg0r{Kl4Q8= zNyQF`m0MfX$H@nyO6|@_7&p}9q3SpKHxZP0*}WT5FnVRA2dl2j-nuCa{Dt>@765~<~L0$(dAP$ zVugKvx8%ZMv4+6f8c|3tX+auoD>~let4D0vM8SHVN@@m(&-WX}3_VyMCvN6gEHp=G zYCU&iw3uN&DC#VHi7#~1*yo%X*?rr^3?Q;^o!t9bPevEC)50=msVj_=O|?Wfot4S6 z#E8$QZj}GqRY`wR0&I;LFpGU=nhS;>`OnqRy&*ZFveWNf?~apya%hNDR8^00x=Sr% z>F5CsU|qRwmdI?vJ9Ur*MCOX@cWzxaxdV}=f@=*GvO5;y_+kM!`QaXv8T92vvlir% z$^?yT)VT#B02C z!q?CS%nYyS`Q5+XGpc8AN-JM7#VBn=)E)J2n0CL}3 zL8&r13ZfLWxOs5_C z;erf|#TZGdTofdZY*IRC#(9VU?!t`5SHdCksfHFom@Wi6v zEMV_WyOTs@?lN*9s(hw*QP=2Zz5uYcWeYQScHhHxWZ2#jfOW>C&A9zKaZkb91Ur}E zxW*^T1$>>F{U}brEH$b3*NJ`*71yK;7QGmJBsI=F6oj*mlX^FX#Zrr(7$cg!URqt9 zEIM>$uX)yIV%C4g+8CJ=QfK;94u{`pAXvu@+9D3EJaw8>Huibk$jb@XP&~IhC$b@ETf;1AWuc#&$NtPksKS5Y|eNa4@aYQ~<-u^CaFcMyN& z(r+1h9BYeBfSCcfI8Zo~n=4Uu*nsM>^G4`(4>U-oYJn+!_o#vi?_t9D$f~_gkU}=! zo78pu;7Tli<+#`{4j*yLAes}fI;vcDBAYFx_5;athpOIL>E<022P`5(_qL`__`y71iFTi84kAIU8@f|x7B(!< z`%jtXz=kJc^pc@drknjH zht%|{J;!Yx!}@-dm?kwZv+=2JcFTBegLja^!f?8_gJm$9fFu*&+2Ri5U{{HcgcWOv zpYK~aPpt zT5THX5`3WbZ)kAVzjp$LC-XX}X_xv)pIa|!`N1`bcH$qPN%m>9mtBrQIp6@=bcHzO zl_uO|(jX)9$PTghrJ~V%?*FFwAY=*4gfxg;X*^id+SLME#4t`a#)y%er6I_y+|}j=>#+6qc!ltDF7i|ZZ>MymK#;m{OBa) zY4v0bMt{K21Q`AXi$7qksYf!^w)TM@f1^$y&6=LE*7B+`XSjI}-op6!vxcu$-6R7c z@LFWx3lZjrLLl7tdZCYX>*+0o#7Vs&JnV+|h&~=YgWd885?aV@Mgrl0n$>S-ER!IW z@SJI!8w<#3l&W9t@KGC`Y^9dRc+0RwZShuC=NN#Gc2T4PE6G?pZe*iltbn)_nvynq zr%|__?hi9wOs4Srhz(uP#H?B>=H^uJ3+ycpp#LHEPy9Ad$yWM{Pijao@RNtE4r!k+ z#StMRaxH52&6gckF z0I5Hd@VZ2syPF{<<`BZJe-);B%a7weU)(z^KJuj0VUhtHUB0sJ0!S$I;2A-lgLk6J zGq=pTwq;7oEy{db;$dsRci7Y1OWr!rJl#lweR4o&Fw3P`dnlo$7d|vUUNkeQ?LBYR z8zm#xUF^@dS4g{YNdW>|goXwspp_lna@||M8}Dce>V5*u$gn93p2Ved+>c7}TYa7^ z{{HYxZ_!SGtvV3yB0Uw-c%tgxiNLW_V#<2J2cA3$Gi-CDu0FjXnKdXl(_3u#(;=tS zNv3k4ze{<=-1mDWK@3v324W8A=sVVe`N-N3k3|v5oF=iRi{CtkMq8J&YH$dsY*R zj|_}vY9_If^A@$}IR1$7&&g&?U95r9pjEn##(0R)qw2e5<@acQdkpc_fAoL7@L_e) zuEhYvH>ub*#5r$IUzv`T2q{{Yqz_1pp2V6difdsR9c=ZQqahlcIsRB%=t8EdqJP#W;nNCx^CCtA(9@FbWAd zJWLD7+5JJRL+b!O;d!3b4*X#)Wl(tR?+m5kTqh&+2>vK3bQo`or-Siux3M?Kf?%>9 zm%J?F(IbUCw!@p7d}`vX*wU_eho5=PP0E3|if+pl0~QqB4gq3{diU-``60jsi^Uh- zI>$1sc!(cpwI|i%wC%=w-oUpR8f%d1G=fp|WbPf8ANNy|)V~POTR`~I{ip-VfJQAY zhKLLJf%g6VCF!XBs8P-L_*je9dHNQ66DRCYUHL3@tOn3R5mHIPQJ9i{ z#EW!z1sbg@jJPpvjpX_ggGRrt9b(yC*rZftU~;8Gai}-%VpP$~X=hMMgJ$3s{cXD! zbi`X(*YV-#3n9t}SJOU0VF0iquFviYyJ=5b5pM*NdftCo^-Sf;c1VK1pJ`;S{egti z67`*fr(ZdE>CM4x8bSC^BGGv|zB6;g;pjp1SliijnO47ioLZowu<}%~g6_!?#UHD4 zlia=53a=VFZu01tA0C^5nl-F3W&sNMjmB<4>8nqhIJG##Q$rLHgo}*05$wWAz1Do{ z!sh}MBB`Ub&f3nXr1MsQIj4w5o^erj_5K|37`6xD3KsDTbw^xTFp#_NPoREqQ&wng zby3Ds1#R)dZrvX%)Z+!DbExN3qP2n8ftdHQ&E1%p1Q$N+yLwt#P)nWjm`Q~77sajZU z2SZg4IX7IAg2CHngBXhI0!8<1%vt}OCwtaEntZ<*g|~bMT5;lcl{fJ)@}t+jn>#S( zW~G+H)1i~1rz{kcngh<%$Y9A+=FG{l1G}Qf&9crL&ilx;$t!=F%%A5ykrg=rS`LZ# z-ktT*Nw!x$43<6$-?!RSBEkvR8;bdy7L5TUqDAPyln(CReoAESRYIFFmG1nMk-QZ&q63xhU$dIo>pLP z$0-5~tGa!CFGS`AACjag97tUC7!rr@&bqMoV>AoUfNZ2hzPCG!9xH{TE5x-@oh}nTd+}boZIa+a3ae5_#YJUp9ZqxQ%D}6X;^&!SXAL_BTg8#6?(cy_ka< z?<53aFPW#h@wOJ5zzaUZ?p6Gzt%d?knSNRNYQt6aqhi=YQ!8ebQLi^-o6Kz@S6agd zBg+O|EYgKh*D9 z7u!p`U)n(cAHaV;_uX{4`z=YeGfHtmM!4^G>c``E9XeA|*1wJmH8p%ec$VLae)&Zu zUu#s5yfk_c@vmS{GD7M)4%NAfh9HeoBLAB|IzHVJsL7xk@?*PL@%efi06lGR4Ze=% zK%x4sMrw)G4ttC54z!>QqFJw0kle+IB%+HlV9VArNZg=^(7G=7ne*kLs%{pXmPqYs zsvgLA7venxsFJANUl|tZYG@CY`>5;nFT?d5 z+E^Oe9^4{i2bc6(F)Kp34qKXcwZ_9Ia5Z)_S2lXOZai`#v+Y5SyX6Uhe2qpUB>i&A zfn!Y&V9x?1Xt%D4Vadnju*NOL6U|${=qrDHjVV@7e#IvD>K$d?ympxosfpD9Ks6dG zFKPM3Myg$%w@2nNwZEEy-cx)$3xFLcTNvG1F@kz~;tyYYz^&isW{ z%B9CtqceiD279f~dZbw|r8Omn;HPV@{fB-P=<5(%IE){jQixtLD7>ys`Z3IY0Tux$ zB~;YP4X3aebwODtY15QDXE_|Sl8zT}D3M=CB-_sOso!n^cF`YqPXLj36~~dD=G;NC zZ|`vHz-r1!f(^0V&4X(24q2;s5G=MB*ZXzC_QTockPnXZENx*1JNyI>sixT%{^F zF*LXSF=5vu5#IpIs6a-Mgd+fpu$^pV@3D`mj)B{Dy{_Dl$R+Q~*YifnAa>zB)gi!q z0Tydhx>)u6YuzP%695Hu7)-V?YBO*$K;tC9+xaRW!R_`JPq)r>uil(CA!?Vy4%S2< z-m#R|O74rZflg4dNv%8LHu2s$Dl^7Hu@Wvx224+?aPH)S<=Sr)ZX9jYdb0Fl)XlgJ zPSgj%jot*yJB2p2Wk+gB$Ipzduyl2g42Ohz7`#15hdu9hVsiL`| ztH6Bt69%&kjr)Edny{7Cs5_B{kYr!JNU2Kmw=4ocs0%^%81uF|nL>bIAWL#uE$J_n z@DLnY|9eMZ)qmbwX%i|*Am=thaz~yLs6fO~oK_Tj1jFTeNAb=Frldnm8#(|DT+R<= zUR_YIvwEBk!RmaA`}NI@kTPn}bZ!4sBRCPKOBx6Gi=ajZk2~I8DwVSg7k*X=+a?-C z4w7xr@?O8K)byLKbg3*<=kYF<+wm;sE@r~1ug(lvtfu`u@e)P&d+bBi#uDj@1+e`z0S@Y?sC9u7dj&8VZj z&0}v!4a1$B>#x=Yce;>V|Lo2_)vy0wmd8K-&}x0rAUCs^pIPY?ETR7Z7nt&AVO$Pa zp05d1bxEnDdV}Om!DGO!B%>BGo1bq}|4v@N&P+N9$*sbYq`Q;w2n-hrAK0o7*tMt}r47?g` z6fI(BlyfjQDFa)|pBcPw>^rGfma}>w41Y!SUT=ANaNX(zn(T=#%~$ZxTW!OGVmYnQ zcM#qXX>TtIb3QE8&h_8=!X*1R@a+1eu{9%G)$t*N~DMmF=QUyidvEN zWNHR?FYc_v9;xok1?slfNh(eyAarXq5(v?*PHul_@0K$$Fc`5p0xtho&VLq9BAonN z_JX?LS9V^;$RMRU0kkp*mgEq2!IR9buK?qJhl&bj(0j55|J`8M<0MFlO~*OUD;%0F zOMau>ij@!R(|PP!BYS#|*iq6Sb3*fl@8tTdM(4rI{;D1`g2*WaM!8)tW8_`)OX1dR z!a#cbUY>fVl~PljpGFYjHytj#4I%(jrmc>G$oGe;3g!fpZC20rbXsZuUNn96uN9Fe zBV2Fk$E9_}#}*;M0O~2I5Uzm8DO-M?9bwQR4cwo3a~+e8d{Co`_}H>oI3_EPGt)b# zA_%;vtcI%9sR`JojkY1kipB1V*K=$Z;Y@=7i*ovqI+*DM;si*bWTfjjMr02=++n^k z8^V@FsO{>K1|pucn5F+Lub4G|%!T3iKVmdDodNc|?|TJ5e(wOc67}|0W*BR;6hqbC zYhEwd{JoarX0Z^gBOfEAK=!T^_Ru$}2%9#L3rzV%xdZ4gZu2>I*`un1~x zGR)fyY&)rFj=}pkYKRgQ%Pgl*Vb`_w$1)0f5Qw#lH)@n!>yN_A`#@pX)pbOwl$!LE zqA6mR7$wi~BLEV=rnKMq%0#yJ`_G@xBBN&y*n9*AL_kTsCZ6d&lP$&z(PO z+wb$yaXlI`*d;DXiQ?V-e^Oi`=mnu)pGUV^stcBlr7#g~Pz_z+)7av^=5XeUk=w`D zK?MNyRM_2^TQqYcmb)2Mk?B-CNoFE?qYj(JNAmDuQ47S)>HsYR^hizR_~=SoTq*WI zMV>82LlnKr0gA9aPxR1n*V7+Wj_uLXF5 z3`I;E6n4~WN5^FUD2<7yN?prTCeG-8yz$%F?Q#6E=9BI@A_W`zdvzHD&h?Dia|G?Z z5$@`RE&T7WM zfK%ALNG*M2Q_Ad{fib(nc;GkSVhB0{e~(*l6v9rW9;W=CdTU5m7v%?MDLs8X64owe zTxt7C@4Ysl^2p&2NZ)absdk6L2Qo~(x zE1kX;zkqMPBIgOq!W4Tn1jvgVqVzSvULTqcX1wXsh-JgQ{^PL(w|2#v}IUs38YnSVZ^qP<~SY|*#)7jCO&5|efN>-mG% z_DtQ{hj+0kWjm7Z)#rF2`-m&m;k<7b$%+n-S;J{;z$XYa15ca)t`T(=bS_K;yZuI19qS0xwstbAhFi^}Wm=9Y zB6Hk+^{b1Urz#1QL0jwP1L}=yAEyqJ2-?;;?ic*Wv;Kd7Zq>iu zQetV%SGUU|@|^vY7L8{sf6&R-9dl&Au1tI*B3>F9E;p+eNP!&-S1Y4ovEmpYxuWJb z@iPpBgW&tf6DN^)`9ZIMYM4eP-vtoUxj1}9XAz!H;}+X6XeR2rKkF|3mk;n7R{&Qy z$_C2pT8N8N_gWTu_3Z{yaadf^6XCTLPY}%5@0_g9 z?h@d!0s9;GB@4N6iho%}RUM{w8(Tq#K=-T>VZU60bVpDDGJ&?DzCyj1-MY^yP;dIZ zBZ)AeP{&_mj;Y>lDgqjPwp%&-W?b{DcR1Z=yC3O3AeIk^7k4VgoXlKE8|N> zXmgu|zp#{tIoac?(eQyvk-}x4vUZcww_`4bs?+;L$l>M*CBiuygC8{1Y_r0zpev`y zHkPovNVd|HAL~<1UD5EKdle4P9VVO3Rp9*7MoV>Rn@C5aCW%5@IbeaMcAE&!3@`OB zrTv&mhF#`ygFmP@^tnC!$&&xxvGjTS?z#H{s9*X#{V_tdH!6K+ht-_m)8xwqZueN` zaufg`aRbsE{fnM2G)8iK#x{eT`Me$vls@-VUBi-}IoFTcSUj-NQYz`QE;giU(H`~~ z)W(U$-Kdqn^Zng!apY>gwX!6!Xxw~TL^_asQEj;X+AfYNwN@M@UmyN~>Z&{C+*;dr z2b=wo4wqE>;3KNXJR4UI=h{Z@iyohFbdi+v7w@oIaRGT7)5$6=)|4V(@HdE*K))mc zd*0P~r1NtCNL;tcH($RZ!2<|1#LPJE?ZE0ABYld>H|`$XipoEtmgD9cf{*z7>lYn( zthdgKlQDz9B;ItSud!BJQ!nAOu&?elb9AB4|1BzL)t;f+efj*dH&-t;$^7SI06-&& zh>oGxRErO)UbVRYoc>Um0Ote%rEmYEZ|#5AJqu;ue!W z_ZBFRi+=c32Yt=AQ29rk=(rl|oKtgf_r6~d&J!D#MpROOx0+%+W{9ZiEfk_F^v2_(;_ zI4n89f0IA?UoE|DM~>r2z?q@NCudF`xN4-9MP=i0zvh;UPqehO2IT1}i`op-CP;J` zbFVcB_x7*eFouGS$*P%nm1Kz8`lMK-j`2|y!x(lyxq#p8&oi?&Nn;5d>?JI#@h*q= zm~a#K-wJ{t&;iG+&L!_ZQoH4JPzWbzKL|ET>)lhOxnx?6GRtWZ1SosPmSI}$ij&D! z@7l4-{Omyc(@Oto3hsJUDr|qQoC{4COEY(o_S$SnREr;Ra+b+}#D>QVTYIE4592T7 z#TXl0@&!ncP5nNN6KeM))=dL>J5CjSC`dU@YSSlyc3!Qzkv}%d^L_Q$ne4*?viU%j zN?Gjtvr-w7vNYp(DDT86ZfIV-5uO5Ud4Rx?YF<`^k4<&-%&$w~8t*HYycpo+~wr$D48bl(9I9GLwRql^G(dx34@C1^()FPJHI@nskvZqLxH?tD(~yiob3C&L3~8WF;btaQ$CC z^-0UIhn|@ktlY7ur?>`Yd0ybeR{?gj zl0mRmTdVU?&F)*b8*{er%(fVH##t~93srBK%}j3@90ct{muL&Ulott;|#T2L1Jo(6(T=#`v-DB19-eh;&sd+gpk z15Xflw$`B zz;FsA2~&d{d1#HXmCGp?XZuWs#!ypyhib!92`ofmn_}$5Z_5ws4yzsy|NVaN!YULW zkQwjy;ur$>+$@_dICR*L=rz)rJT8%s{Od9o%pDh0%%^T;oKxxDbc_cIWyAf5e;8;@m~wMUfn)>6Jga;kA@Z+ zIbNIutYr71>Q7}>?Kj7y_F5&qBc|9jfJ;OJcS+|Ef6PsDHGDBztj(s991F`V9VO+A zQt3HO-2qz(VZHtK#&#SL3TgDqK^$!etpBvj1l?FlZNA9=SmhLkyy`S{LH){KC@FI` z|E%PzPxq>XOP!gpAoN=A*4=tl#vn4s5PA%QtEQ*5%hEa^GxB)JI%nv_$NR}l(B-nclHq8N? zP?ut*dLOAGTMAqWlp9TeQM@FqE>^oxrNQOrx3C8>aGnI<=q^(Ydy&<_x&4RvyqH!!daeDN*LTmok{CU$qO3dqJQMpna8Pa;ll5X;!;4=E< zL#sam9GOP=LZc&Bl`i?(_dH=#0sd}}yd(y*MBD)sD&o&D=uBt+J~1uGpy&0t3JOMq z1djZr@xr>}q~j#Chc)uO{#7&Hv++@xftPn8M*|0nV_<61kf}9a&H8i*!o}$+EyjK6 zz@B+1_W*~ry?u9cd!g;x_qdtmg}*IPJVCIVPU%6~-8QTKCpu8+VN0t*eidFw6SC8cFXOG+AG*X%lK7p(q`T4jCfxbn+QmN^vt>iGsf5+0 zhy}r8R zx2rGW#GRh)?SWJYwAz-GTV$zz#jzy|Z`;G$wEXu2x7QB}8j9zW z(Y8kk9)%|gx`D!~x}umwT9ja7DWFlURP88UZ(*D>J$D-a$EjO@u6Iu#-RkD5)q_AO>8~?;$9tn@MtHTV?hR%2r|leg zeL&(nV|nLSoCE6YbP69XEO`67<=!{<`7PrD$HB0pn73_Ay#_qepaD;@VT@1qtP6~$ zC7~!i0*?51CU5ucE2DcBFuya!>-)P9uC;j`@f?n*khT!~4nzjc=R19GtpR^q+{->9 z(t$l$y1#+W>-Yj2%YA+9CM>?UA@D9XL8D7O9$-d0BBrUA-};t|*h&^!8T=MfV8l-% z#o}795;zy>qO*$!`oUuAhuyw}x_9^P>cGGN-H_5|1c!PXLCQ`>W8^max^DTzyiT64 zN*M{;`qSre)czNuj04?x=|sWcZW|YnbdSnr(e$K@VCi%Ynr$BX?VXt}=52_5sFUg& z*aI6%TP>ka&IgRcj(FjS1A?GMwJ3mFhO`o_{}n^$+XP4T|ip(!EaO!))=BHcZz7?f5a+3U%(9gt5~V z$>@5U<&G%I@a)Yo?mkoQpSLXo!se*yjHfH1Df_a9AE_6WzV)-RMxFCoFX`l~l+cfk zNB$otvNe+KmXfY{Jh0A(4w*fEV^8*h^#FRX+ux^*+-9rqVCA zf1yLk{>xqJ;NzVhIYHy5jlM-=2+6+p{p_4mMW2aWk4f&?wF}pc2O2ddG@a%h8dskB1lx0w&k?vy$T=&8G0$+}TJ+ zYPRFDLCe{}?O2(tnY*CUn5nn!TpzhfpApq)G&SF-^w><_7La4A{WKnE*uH8Jv)i^T z35V5Uxv(4=l$`zzXwt-`k+bc(%FK#?_|5IU==q5Au7N0EeFpMzEjC*r1|#IZ4Ct}1 z`4jR<2URjIgS?}6#^hfd->Y@C<_|}GlhYi-5jA+Zn^@`!r6kR`%$#pwTHNjzZ8LUc z0k^;Y;y4imOTY2k@jraE{!(#lZz+9T;Jue9XOe^K=&a~c=`)f`n9v&M+J0+*C?mWB zRq<8`iR|5HdasNK8ItX1SUlUi<3s)LUpmXQU4y$z&B+Ms^o84H70k)PMD-;Jfk#@J z0kYknczPmeyzcjUV^ZFacK-ZO_P(akifP9i!S-9<)~L`EOP)ak|J`2tYnrnC`QM3{ zeP4-U@sS>Ufo_AZ`Ba?`dv6^%^2__2$S=1r`YN$3^_EST=9Gf1a*mtcS6Viu2x%Lm zsD^6o3h-+89jiK!$OcVYQ8ON*C$F*V+MdFe>1Z5Ge6sDx6Ht93?S0BbmMDr^gmD4n zCqP}UkH(xCU2i0pPUmmM%0or9v)llNhGQ0xgV`$38e6IQv@K3;*3;4rn8NmmC$6z& zzk&5QcrZGfAQN(9&$yLk!EQ7)yzB*`#<%!e_jm$uaQP*BsW#7pi!?%6Kx%s|qgOwe zXrR%dn65dm(%D<8xW(N?anMn7I-a6>0RNRzgnqd@7As6j%d)U@(eZnpZ!vc>p-0Zt z%eJjhaUCh!{zmPV{tj+l*}Vh*_`AUrI}tTiNSs!d$9Igvo+ocPQLt>~tF=#fduP?; z@#7(eT-C@R=div+%-UL-oBe+xp;e@*GwY3G;<8iM@MrN9-LAy>ku>dED|yNyj{I9XuPx`u+W1?hb`plKqWgkx9Isn%jB~3(mtB?T93AUPZdh)ef3HD-~IK8s~wG`|)aP!2+;aN>^^U@rWmtScSHWza$o-n9i5$2G`&F2QW94@{=I!2Fa ztFmAkgk|jvbkhU$C~Z}Jx1!&_!i@Bl!mn~Qa(!?Q|239GUG_HWp17bU zI}L*yhQvS{a$dFEFJZ0G_fsvTKb=Zkb?5XPEGVpAdUQ-x=W2(02N9Mv1a0jXj{}_V zDzDQzN~Kz73>YH27Eg9XX}tlrGcHz{m{opR-!D*o(;s}=?Fib)W)~t_+-eoe(71XJ zvJz+)E%JJzx#FF6YW-n?PIcDTS5l%(+0XKQv&XNzm${J>qV=^Y9QNgi9`lfDX|1tN zSDLvw+P?{~EM!MGHxAC;{c+NN_}1uSW33{Y_4cSQns0(hj{rZ0wVXax-QVr*Ry$vo zv(Tn4i{NeT=-7VgGXw&%aR77U$lvUP>);dLGnQX zM}9mYB?X{!uY2;oh<160Mv4Bc4g6Izxb-W|-kR_cWbN^^ImZeuAp#vXcQtxR&sbxx z(G`oc%i%}7UF|RiiRExG43Z?YEMNUk8))uO!GLw?J&PF2G)CfH@+yPd;`N!?5fKirWeRCS|C^mEa+glaUNOmr!s zvVp-qtP(d7cK-Inh##!o9?+ZTFUwps;yORAQIKk!6HA;o*rR*J`(3 zmCbXO;3~7;o}nhy9v7<@<51tOJHM1-(#Kkh*i*g%jHx5aH2)Y{4*!CI4^b0&E&i*i zaf2c{;M%)rfS(8Kf!q&wMZ3rw@9*|eM(Aa&GfRsC*nnfsZp7=mVN-gO32|!Tm-r0F zOT!2^#nEr&eB*#1vEqZY)c)ZwQ212L6YUp|JtBd!QVbw$lq}(rC%6%K;e2Cg$!SL7;__w^#K+$Fs!ax4bA9^gHf z7&q{-n42ot!(b~A%AEfpT8C8~*Iu{?9-_73i|j4|S6bD;I*C=5XgQ&G)1r6diHz1) zP>5Oa)|5t{rBH&4hk8$K_@wWR3;Y~-+W%!X#vC(GJqumCMu%13P(2*b7Js{Rm->IW z2_wX=$$4z81>;3#EfY3sKEkk2U34Gtk=iMpB|rK`JK$gym9IiILm7+~x2nBiHiYi~ z0?A7IOgx8o&}lPA#dR(SjK!I?3x7{i$EwuLWNrh+#Yqi z2u{je$RCzJ;~G5v)EE(c^Z%tWZco&eZ}Yb>@E(7#JK3fRZ9s4_U@aYrwDa(fg&S#{ zUXt=zriwz?!SfyE@9lhAr+2&pLKFDS_egEo5<)@puD_G{mOpLw&?0_J!ID0dFUkBX_w3zR0nFa+=f_v zi`Mwq{o&bP0=T|mM>TjOh6~d9Jo?_D5wX0yD8j{j7liau8#YAYT z*jUHft?r8Z9=rAOhKXR%vtqQZd82V@D8wvy5)GCh5fD9aF0mu(_b>ppd4c|ED)MLb zjY-!LKNJ|tA@*iPE}7cHnZ7hCN^<%WwIDoSfJZfE)JT8*kWAI2OJwewBTpZai zGs(lDs5a<;XIL3YwV7DhBveQaTza5*pQgQtNyxGW{%i`wf%LVTHo7vJvT-vmkKOcY zL^VDm6D=UKR|dtzS@Odyjf83jp7u1+WSd6uCKe8wZ1?kNnHMS1*UG zKkLlgY5f?MOAW8kEctc`Q+W7!#HVMq9hvWwpX8ZVUIzEcC5gP<4r1bz789o?Ql-S& zPXdK+13yqjc)ZhLE?gDCA||AL&U9hLYgfFEXd_;EqSSGyL+;3L?e6C$p>S zmJXQ__e9~)=aLoD@~_lr+2*hG-5V*py7Tw?Edcq^N>dh3$WrdA9rj-P)o3n9SVr6+6b(e{m5vG4_zL-%g zplVP*Q<^*!x*$mc4IUO)=n4<}cPPJ|Z%F?Z=zH5v^ zkaRpQtgC~5m}{28X5C_8mG&Vm{x6y4j2A<_Ox`afk& zx18Ai^(#De$Q&hvTPmqi#E1tEL;bOpu4>qmGurY7iXn{6{KNW{hMb!6*{`i`Gf!*A zaeUL}#=rsVv56>=@@xRGTx&zi&R8%;Zk}yJb;Qb#p0isDs6+)S=TvMXn|=<~j|&u@ zyYKJFtNHP+w~-pv`kHX}76XYo6#BWt>I-1~)V@+&J1-(Js$%3k_Xanm`^HOB4t(th zApO=&g6%yTUh_}KxC??ELjFHJxusyhkNQz4n)6EpRR~YS$RHBP<~#hJ{!2P3v10Wo z05C*c#g#&Q#sJbDB%7iF1E{%q=porwU?LcYbTpvF_p&j_)>Chomw;LbTtO_OrXGUD zqnoZ=&)TWn^f*da>}KvM8ODv596;|yQ{fcC52DG8M?++)1WAKqxuS!qA77)df76L? zm{GOEDT9RS!1;QEFM*;`32Gu#GH`%u2ci6Co@A+{!eV3fa7}OT-JBCkJ=<5M%PZ3` z?lZz+LA4pWcUrb>63p+dOa;g>FqY>O-y5gx0Ndy(54L6*=b0hyo$q??_H&SnXJu=6pc(@9QRy?e!gyI$f?Ew5q zt;q_hdwolGi3=h;Kj#|qha!I7s?Z@O?j6{nR?^S;{^ux;wAw_DnO6=p2_qSbb>%Tp?Urm%o4 zHCDq9Ru~;o7>*!)?|6k~-mwlnfKSo1oA3q*>GwItO#4`vbu#%ES7;AB5sXQYkZn8( zWEWNaAjzCN@a`AgtbF%yz1_=Rh{cSmwAo8jO7qZY52NA9&$k@8k52kj5gczO~s#NNMd2?Uo*LEV#uF= zv-z(GpXNP@WqRZ11=;N#>LL#i@(^j#O5sPrir?Vq&Qxj@ve|c^L798!!b6pimc#_167$62Sy1+~w*ayr(G|k)x3^h39r!|B z^zJe0iwRNy5g=Ioa<2GniR4lLS^WN@Gd_1orpD++ZO=@MJ|_(=`$H0fJ=T5p=KC`v zg}s2BVN*=p+)b}I4cvU~?oGEY+UCQz1ZF|P#MhbRu(L>kcj_aj@iN-+o=-`t6Wtv+sN3AV`UuE&oLeKUC($zbxNm4LVrw8+%?@`spb2! zhpGM0=5Ub%%8IXyUdlWjg{Ly~tLmM=Gts=ZHR>|M3p1GI(g|!N4;ijlw-qK?(Xi*Pdz#0`^%$f7J}p zoEf6IO*HWu-BKP?>@p*;qMC=T2zst|a3fVa3s5f<41Fr1 zConrUz(yo-C>oE8fg6~3@`K5)hS7WF@4ZZA1H3d5lwMitFUcU;a`Rn=?lm_Eznii7 z1dIPZ22R%l$EXdy@gNXILW1z&Q57+-v?t%rxL*n_jgN^zf7P1LhGFO_dXhxAxa7@; z#z?RRUS;FLT|vKO6&Vpq?%4QjB~I$Is58j<>n*qWYhL7;z$ zIOq0Ca${kD`Ut0rZz6f?FHdpuqb1R~@c6mpZ}+^4_ys|uc+ zxE?f}J`*3gIe<@?RZk4>QGaW-bvu0PrW|`X#6OGBx#p=?_$^Ph!P@B4fwC*3G;zek zPq$Mq$RhxV&H*)`i6o6N$lC39J(3qmI2%NQ-TaydGya2 z+|tSK-i9p|Yb`4&uLtlT(HKQ^;>AFbq#G?Pyi?-etlGwf`v*X6^5|9v00y!sSxAL@Q# z_*b@gb7)6;x8U)^rP4hWU4qoBV)4h4rz7Hz*UQo^1s9)%R+zxDhGijS7Z(L6yRWW0 z(^Mgjw?WPOhN-&8c{U{{s690}|6oZMq_N@i<8fK?XvlOQZ$WlG-wxQCe+PCDjRneR z(HL1F5Zm?E_#9%tKV03Q=!NDIN7J3j3`!};&>@)!QbG-*L`FlLjgRw;L{3TwKTGdq z_9~yQJKHHGP4+N0;5>M(hFUVTbyvzXxk%WY1j2qq0Ox&}KsFnh|NZO#KF2HdfbvFp zRGnC_lJk}nt>+4^JLU*W7XkcHd+Y?%mHL{9tjjs4@5}UdUqB4jhO6{jMJ7_QIf~*I z(P1dB*J7+v4?pJA;M1H!Olu+=A5~w^d;pD|I^}N_!$3Ofv0#3AFE_r*LKcUeGZ#&d z5|(%PE2C>598v)L|0Bm$*JX{6fMfCyWb&!oj*xyJwJGF}Rnl47jp&bBv*L7|0yccs)X6Ib4nhV%a)d}mgSIr(5xK1$$jdeNfs1WkG-Rc@jk94~~ z`}duHgKa7G*0grf#q$As=neGRJB^q~Dxq%~)Y&lVN>yo&T73DZQ*eND>aDU^<-I7b zYV(qjhG)d*i+R6JydUMX*01)_OY!&p!x2eeRijj8{a556E_F4 z@I8!e+GLD}L!?6L_t1e$QH`jO_8V9H+nRv5;Errv;ok1w;=*uyw{MgT$=;~lxw-nL zEFgGnF1b$$uUt5LK;X}w=D{r*Z~(oGm^mWX2qG+~>$keMd(1@`6QcJ9=-$`ZGuU;b z&#;sY7fEhk1Nd zJ`5)2>=T9%&Vk1=FJlzWaGsSp`*lgfP* zIUAEQ+T3PI$`R`8%zYoZ6XrgKT)EG=*&MmAsl<|w-{<%L{@M7vKkwJ`^?W{_n78R@ zb!8uyGf-^28;U=i#aj4TBbdnAd>?hQPWCJ;=UqYVC`bv;EsY$gT=#hJEbTpdPKC!j zwXO)ZKOjFk@prhcfA=Hfv(;Fb%hG80RlS!4bVrL9d&gV~_#;JzhI^W!w$DY*rzpf5 zt1#nd>lnLx+DPiy0Q-#99JtiN;EXu~YdyL4^JM*I>=kMzP8QI2+ZD4}H@vr- z3;+ar9ydXTS=4^sw~yF4)5ORe5t44V3a5vH>kxrG7yI{K&KOO~2G&+=5P=FI6%ck5 z9nwbo+AQV$g8!TiP&|YV^z!1M?+^@^nUl13l%IJ}zQj4JAgIudN^Ip^d(n` z$PHqLs408#eLeGVfAC0wzaeKRPprZ2?C8h{Fdgu^!ou8l!przvDR4H0PcyDA7#8w@ zg38-N_s)lLkuvMD1g1A52{eYviaTC;%hWm+V^5jAm(6;5^a4Op$1@BEG^|;rYXB!? zqlAP$^c{NX&hKjDT5L5Z`euUkC`>64`Kiv55nMaXPa15%-Gmbz(JJZl5}TvKSrii> zcKTyw)YD<%kmBpU7wxNg=Y9GO~EXfolKno0N(wsezRPYAQ_C!v}6rp+)Xu z-J8sA(G=jan9gOKcy0e7`0WSM54`)wCcT0?A~uiXQP-*7dxO;7q~vFpI7p}+2Ctmr6aYbq+jt+UU(*h1suX~ElGY@#QhnQBg=Q1gMk?0 zk*y+Lq6}~sQX}hZ_Ny6DRTRB9s7i{kMEB|AaT-TlU{Dj7k&ywQ$*K)+>9QXU$cL-$S>#bl;&cTld02?Kg?genV?+T<)dX7Tc_Ri zBA}}?598J%E7K!*F)QD=C|?o;+P=A(Voh~pcdz`qL5(ka!?+{OBEXOUn(@iy48BgT z@Px7ZF)j|bko(k#WMoH7;9I2yZMDdHKzT>sdNl&)rv@x#l)${)6P7?##Hp~T~!rJ_q{h8%YKf<&zZY}C7C+`KUen+y9F1G@khTr4kw~-Riv8}0;F7TX~7$N+&4ElD(ol>9FM=SO!Wv30s9IWcHYq&vgyqd%pT|bSrQ~hF7q_8A6^Mi z4CZTH#tdLDiA9uC?GPW9*bv67Pl|Csr@ zdpbH!^=CGcnx;(U4TgCB29$goh_6CzECQLJ`hyetf_yb5Ba7(mNW@TAdf}=~!fw5r z4rt|ZCF_L`%2+v#&x6*cF#CkT&q03GVP|U(M;p-dHN*9a7w|kLm+{z)oW9ewY4^)< z2Ist;Fk1${7x>KUV0q~}sN_@s+U73sU~9TcFlb%WhtOj}Jp#P!c3ZZ0MpIX^ zcZ#1OEW>16wU;j3Eo6Ql60@zyWZbWDD2~imFJ3qa3rT=KDn0{APkdtNxHyZ&F9i4bc1KG_ z+j8xn7*VT2WS_o3JMWvpuH}3}b$m^Fl)|Qr&FB<3e(fG#tT-(7!$s1*VjiO5uhkaR z{jGsu=YoGc(aKokhWKki)G~}vQ(en(^4}8B@_)5aBS3kBvQw}#uh7}1BZNgyGG{uiBFQ0=&!uhk}M` zvc%z_($R_pXK~<0IC&8QE5}?X6GJzbsOzz?>3Re*%!Tj$Y5qZh&+?sipJkLN*=dD~ zJQNr7Swk(>C#XlkluF)0iaq`*@!hxK-Ift`LHtK|o)hS)!}m@&n3eX^c3NS3$=`>- z2dJPk>Bp3(uosO0V;=H7P`Ean{tX>*I^qu9(CO!1 zLy{RW7r+&OQn}g5zjaG3v*}e=x6q=~UL(k3{A|yL^Fl+AdfWzfHfo=eVYf)@TSaZ7 zQxOH%62EK4NU_N6m0SKnlw zjo#*=E-Gw4ad1r*-|tk+NLR9b!Ru}F>?hw1Y)p4kr>oRv`>%lDNry8A^&i;oIuY<$ zzsVFChKpFV#!!VFS<0? z6umj~@CPSnur|2b_EC(GKR}v+&<0K&Q^+I8l&NM8Bf;E>&09=Si{jh*Z7s{n3Y`c!F>no zYkwEuz}_fud+C$YDgC(_g7ksA+rC#U(;dof^on;SKPfgs0w?9tPOhkaxisPO^n@pi zGI6r~D&rA6`=q!NcyvUN-P%ZeGx(6DbdU7wty&6en=l!V>&}9$_?VSnYc``FYvNw; z8N0CB%0ouKkE6KV3a*%#3J0$G6x!;3M*I2;3UP3vUrL8)xE zE~;UnGa?j=DsEKyNweEC#@~}!tqJFK9UpcJL*;Kq8Z&F#$F|M8p#`eA=VLFr+~)3m zEi~LA(nxxh@$fEgo?tg!$l~9)5}3lOBO4@F%j2D}EiM@c)WD`=z5+Nc~Dp$gXRN*tvv{BX~D&IXe1` z1F84L@5VjE4_Ko^+hB92*)CZO@P;pP{Ljj z_sC~6(;J^)KZQfJES?&oQ5ET z(^$zlXMAmOkn8jwN6No~qM{Fv+;_W!zI;|=xvJpx^Ol^CG7~-B$5;g1Rcc=exz3xs znH*>bN;zqP6zvR()R0%#WuG()OY|iM+GR_$c{!qenlT--Eb52kwf!!g*e^n5myQ>u zK&TOTNGiTFo=s)cJkijT`tEP{pSjhLr^IW3+(8GLwD~5_$CZ>gG=St9z6c4qv*QyK zHoNQr8M6cPuC+@3t#j`g*ZBQxY?D~=c`7)F_N#4CGx6n68{-(sW>_}#*S7!l^5fyy z_Wv@9{ze>ha!<=vwJ*&L-6n$*Js+qmVF+}V;hbaPMqo6Lm}A!yW;tx`~@ zMf~ozi`iD@z}JMY6)3_i6~@d4;Tz#cEel?-5Bx5q03HaF05RZu*SuFZ+U<>8`S1{2 z139L^nY2q!=%w7a{3T<#o1(82I`R?va2E79HJq+l%#(asu)y+Qs#lwxQ8lcwq&C3E zEDZ2sbO+U3RD9AYS)c7fcTIDwDVpNOO$|saE}ADkY%+6@V>5l=(n|W zBmHZ|{cEcZL&3#uKMVC^@zmqLH@kyInf=>vGYq%z@%^ngl~Ak*qSKe_$-fup)ZPOS zSZ7vwPyE5{YEjquw z|JSz{1Q$a2`ka53uIhDEC4U7U!z{fVd){BO1Gf1kXIkeI0oS`8h+4&wd71xW-Id_Y z$If_rnUy8ZwNs<8e4b|@TCm(k#=AZv_eue$?n9TmFgb6%b z=Btol-()J}@Tx~*U#f(Bta^tj(pF~1L+n-4VvCboFnRWk-Q>R4GHA|g`S>odDSomJ zT}nN(CEd6toI^&xNhX4=7ao$j-8t>kD@0A^t>(#Q#Km@C;U)K*i!7F4UCz#<&*e`D zcngpreSvC3_bK<%u(JiqfCid@cqlexQ{xtb#YFf!FNZiD?svO%oKR{0kFm`fgp^2e zdbKfLm#~^?Rbz#@e6`4mc#BECXJI)Tb6FKYpZz#=PFr6AG(VXUBg3G+^p}Wx<)ZAp zbQ;Go{6SHg%N0fZiVqNmgr|>tR{ni`G<}*WDwS4N#CJ2d+DT>EgpDe3PnhSp@oZA-@rGYhNKm9^ z?1~rL%0f_hSjso2St`ac=;Z6n78t%IL_5aTdtBT*(?PQ>Irgea^re8Cp7!Otlry<~ z_Lnh16U5VWiw)Vb#SqbkYyc>(Q#Wj#tsA@UhIVC&s`N)D=V`p{>ve2^Wf>);WOFx@ zxt3=WP~%rs9GdU}t4kN54(NgIN>=?{&bY#+$esashp%a((kgX-y>gX5A<5pik9%W% zrTrehNsn`Svnwd)pc8IC73npb0#3R5o|SfCN2P8fq0!~nTSsh2r=4y^`m@B@ijMYb z8CNElG;}^IU~TeZ?%k1*^)R}}Y5cg~2et39^>r@37`t+Ts&g)ZuB=t4%8{vzviaL0 zG7aMdps;xUmj*4{E-W}CBt3&}*e+nA_TV0qdQc!w88l6O`176Sf{=G&8f3NLijt+r zVNYR4lwXT99^fQ=tr&4ZfZ%pO#BGn4aJRyI1%JE*$tjI+crmZE?P7|rCD~HP2j%je zfTNZd9o*qqIiMP{cxg0HF#t7VlV1&-+tJ+Ekp@LOwaJ%DMdQI}Ru{~-UT#QM#Lv~< zAlJ_(G=iJr33V>$*(?7~*H@~~?q5Y0Uxw0 znA@f{I|cFPruEO(k#8?k&Q!_DArp#FdJ>4am{onk(_UJ#;&xxySu|cv$g_5-e|lp{ z!X!i1M{6`D0?UuxmJt1A+P`HrtC|oAV>MVz>;JSxy~n#A8*-6`>@lNSe7TVQGr;dN zQf!iXqP4D~$I9>e@X#s;#W~)0d4|_(z8J{_Z?^&x$aZW!11O1v9 zoqabKgb21Y@^Q#)s5=K3dQadic;37g&eBBYyb(;-Nu@g|x3EjTeat*emQCF;nVx!MeWJUL3r z(|XjxZmGoTnQ)Jpxxm>gErDywW5>zoAZ$mT8dbepj zoaF)p0$_zs)Y&YVe42BDc`_Oc-PG{|fu#i1|uU9b)N=f8uqvNh1lix!~ zPhsyeClxeDo6qvamqczJd|!;3Qe*=idI99F(hY*~K<_U4BL5pk*1e4{xvU+Pc zmG>P1b5X4k-^WFmL(@^th05}C zKcp^*U}btecFw`+pNsz#kKxJQztm!(wBbOsfM9E@h++ro9L7iI-(I^D z7vd&TvBI5{*$G;xK3k`Yqa5~6ot;{uX<~z~Bw01NrX;s}ZVeZQ!wuz;%S{z-(xFcL zdFcbeE2`MnPc4(4ckSnLUrgJ;v2C-(3HZPCTGp|o_OsFu<6&pU4*>4GP-2HP`#FK{ zD@z-`L!}E#Znb20gKGk9WG92K4>y0WsELxBFMn{L)|P$i4QluUC+jSs1HG4(?UU~) zzKeqN@=1=^u@SFTF|ficb@tkqb6N4J)x=Fr*>Q&i&!z(QpFNj(JLoG2wbNLMFa?Xh zw&;p2*D=hy%o{qu@}`d zHKhIv>F9M#lsJ?o6WE3; zE!>U*4;m7vEE>xp(UM?+$B3|u7@g*OUxcD?ci+mC-@G#r#QOrJ4Sa=8V|Sw7u*2YC zQyP+w4>VP|Uyrd=v}z2HebG>vevda!>ZewCwfiat$;(LfEUWWyzV>0W{=NXe^- zSP8bbW?}B4mzC)nuKeR;w#Hg{globlH^2slf+%gm&1O+UUUB^;=cxo%{8v6|yipUz zoMBZlchB&XM%&A7C>=bdBlu&Z zxfvRo|8mfuR0E`lc6+52zgO3vDxCo+Lj{rT6E)+)P}r}rA1g{Q-a)IV076Rns_Kh> zc{GHSxo;_V5|Bjz{J&`_hk$D9m=`kOnxVkH_`QI3@S7&Wsw?x?6P!Nj}F(7d*#p0qodR+p%<~|L)&~0_5BRMoe~wzik}i;uxWRL$iM|P zS-J)us*Si_U${5T-m&gN;OgMH`^B*|yGbLT= zGhB_wwQ37xo&KdgSYkME`c)^Do%>y*m?CGCRgRfFo3MDNQuL@B?$Ws?TcACvF`pq3{Ukf zb^+Bej$;Al$($Y+#tPXJOe6WIjy{Pc{$KT)T!_{ZppDJdl?u%vma={Vd)6eW8D-j+- zrM6&u%y|8o!_j`b%o`o(u*XBW;{G|o$f5{IQ0IZgVpY%y5x4ZifADHV#pwN}LnrI! z8V`R*atOpA|S3(151zYM{GWDVJF0~!shDB^X-sZ1h zVro#Cc>&pcFi!lEEb+q23Rc@Zy5q^-c=R*VCD19Rq|0BegK5sR>-PdY^IPs*kOAyu zI3t}OQ{@gcs8qbGSA1OlC}ioxE^wbs?P*Q+efD&_U^h$DUPt%{kFE*BDMt@$zZ|nR z^DqOynxfDAFyjzUHtoX0*=ltKq#vlX|m(hcvHS%y;CRKBs~Te zF#7ACHP!2FrS^MWi9Yqc^6s`M>lYYF%soF`^R<6%WMZqAUKf%JOW4=*7TzM?7I4EB1fgk!+w^*ftTeTzgC9O zozO>a&0VWb$Ggte9MJfOrxv822j;|`x3a1}r4|69htqs0-PfG_SZ0@&vuuAx8Fhem zJ9>|v)v=;Gje|MDWdSFPYN%J5)oN_I6XbDOtnI^$C^8cti@#{CyS^E&=znA{P zmesHf{pTRBwFnMNpbqBdA3t{Di`33Pw40wKdHuxJ9YYM)qGKUKx#UR*&Vbc6|4ofx zL4upAM$@&iBsEDs`j#%XFyozfJk&tv=RVd0ubQ2~A}nDMj7DoYkCu6wom)`jd3Euz zY&MOeTHbN#n2f-|Dpm8+erN|D1Y&|nHSlZJtB$PsfS@59`cf37i5CZ{B4~SR8{OXz zqxSjPPxv6Byf)tWE7U!8Zv6l0!CgKw0aADdy^M_1reMn{Mit z7{YWQP!XU>X$rd3Ry*pOyI!l~aZauC*H?-iOx8+$GNsQ=3)=A%8h8-|#@JLCH%hPk zxKQaaMZYO}Z;ntOVLS4r`s|PI+E~t2LyS^|yZV1H`n(jNi$Q8m)G)V}vrkH!>x;u8 z_IyrmF4xmM@;6lPse)w7y*Ze-4*K&inqo8F4{4WrwrQ^i{d9v7Q|y<_(9*$y;f=fW zJNeAT;5tp#O_rvTzGp_p|IF?(BN)PDX~t2bC&mUu-|PDiSMs2ZUR9MVpD7QTJoz5Kh<;=G^-sE1br?zt zD}*OvTH28=)+Dk09lPiGq?_M7)d!ZG!vmkO&*2j5I43N$!hm35d@-x^ zL6C>wMJ{KHZ6!ZbiSD(>KL|+wS1;QbWu}?!K5$^C@1wODGHdlY>rN7>9;t{qRdv|b z*7vHzIKQwCmbMNfFd^TmD14-lVfW0A-VmJkdKJsN`Rww*59>*X*}RIFd^q-+`7z}< zK>{aJW<=Vzf9hrD6nb!$rK~jI)~wJUooVr8E0!fQXTfbd9-9TDJh}_oO2zo5G5D+?)y-UXM6Qxq zBE+LlCo&z6+eDz-<*e=L2Z@%Z1{=RC;kiMlzM zz$Ud--GP=??`4j4jSgmM7NLc(v!B{e$+9#>!R02;{iEj_>M(-^@to6uwGIvl%=oQIdCKVK zb%??~r&}i~JA2-bwPd~b>oRGsR^hWtzK zfZMig{+O}_#Pq534IcmlDavfc1oi9SU}jY^kok<}c(`D`Fy(V-H+%PKW5E|zTBU@0 zz6sOL=tvtpErYaZoGCe)yd3>*?Uf%ivjQSZ8+H3R|DA{`Vw7ZfRCqp|F+nxZ=kRN+ z`9`}!=c>mGC3lB@9%_Tg6Vt5;q2h39n(e~I6sx<@yTA`u9KZFp0rD27IhrQhXlB_t zp$bDZlZN0ayb6>l<>3u4I4HSzty9AtX-{nzXbvkJqLj==9{30od}g;F@W=Rlvt@1d z)w^A}dFkEM>943yJ}=)L(x~_Z|VRd_tONJC`)OmCVi|cARTjlCq9Ivl4e-ovt zW)zkeQaI}6ges*(TBQHy)HGHx8bUP$o9hjDOJCZ`p%@QsTi~s(a+zUATGWQ`OGpo7^8O zACwP7)V{kCb4g(f*{MS)EUe((J~*FEQoozFsw2mva*!2Bn(l)h>8METJ$C~OBrIPU z|NP0~_T7IQK6q7=K-X-i-(xoV{Ls+gfXXPnf#49-W%9Y^Y5A`+gG%fLKm0$$V_6*& z|0WYzE;8>*uVNX2M7RO+qeJ^6lv<6}$2)1;P(uh@qAzJDUM;w2{@b_{{o=+Fos&aT zrWoB&P{BsznFtAhcqRPqk)l09Qr%jSD-+146#(u&`A^=b)!5=ovfiPBaQ%!?k$)3` zK$3M;LXEu`HL?HaHt=bjE!7_Xn~9qFp_Qzs4J^!v&uiLM*00|Q88ev$#S>>Bn=xlv zj=6Dv){finUU&^>-~fR~Q&rgsvIeDq8I)CW=)zDZZ$?K&N<}e=Y27+-iAY1^+6{xW(Rg`!c#13@y6;YNZ+k!QJS8Ny=Hb$^cyO5+kV z>S!s%-KEBMw<*}@-A7;3w))2Q5-_?cGz;V>o~g%_G0{dItG+5oAxhRX(+6U#(?+$G zIiQS20*Jkn9P+=YSAYMFeLABF#MlM)2b?S12@R23Q_U4siveq=t~=>EbsO%6hDY-h z+6@+vOjgVm`u7W-7!rV}*TaX|PT6;U_FsA0RxK0d^N2ho$|6EZdG7UGhox|6D}}F0 zwzQ6u`;#dvtWznr^nfLW`^)<$@sM3RyWF$=u`O`ol)IJIfiz!lPOP7;N-g(==Vy|s zkzrau5l+ht-#Po#I&B_iZMoXBQO=)VT&2n#_P~rLr@cOLBlT`T_3dX{T;6h`lwZ5K3cN~E^GB{zvrEoI zX4YeMRED&gJQG$s|E!ZIZ-uEQs1{S)lU$pZwV&DLO|sQ!c^xLzt$tX2DLpkrnXRS# z2_@Q2-Xmc-SA3RZJb`qqpNuH2e)_?8JEK?BoJS%AR-wWI^M~z zSk8$cq)V?&CrL`-Q(qmpA(*c-wAJAvGM1?Gm8MY!lN-K!V_TS9VoS<7fk$62vD_b6 zx!;^!Dro=lP3F{RZmm^;s#77mNzGI!og72h{@tH=kb|R_0$k}%8|cWpU2V~yKFqIF z$rPgVc9a7O8c@Y$AT@9*M3X*kLK0kbV4+Y z;!#+6YC*LZ&)+AjW~7jZ^fY^8E%y5q&0^5BWdQ={iXL4_}A67*lr`}V~R9H}Xypj|8=U3h+z2T4=NyHpj?Br%1Vnkr)Qogd)p!)O; zF+o9VFJ0w$^~+h$-5N)*-=l0e|GlNX(88)VS2}6RG2$h*>$^3!Wkg>%y%C+@nkEYX zC|bn{e06S#vMF64W4oowQ1C2d>7nT~i?}bWR;|F95E-#!$C;v|ku+oVUcuc(dOc?f z6Eg^Vo++5~S%R256g#su%nBEwQZ+DN;A?4Mj^)=BVs;Rf)LoKVa zb~AN{qdpH@0c@#wX4g!-`6!I z=yS+wu?cIJsgjq~IkQaXBo)|b7CcqDR5uB_rcu)7N)126aWGs-&ma_nb0O-kFVznP zDMSt-k2~)9w0fBx&7I%>+G} z#(%LaUTJcE^~=A@CL&Qr_I60~wA*&bGcrBP-gxfiuaA0##Iuc=_R0H8Z0-JV%hcQV zXGxGwQ=ZRkZFNq2=O6<$tRFD1G;{yH$l((YLrQ>yJ4qdKT=w}&4Mt__d_`qO$=giWqB9Bi zOj*E4r!da=JsOH*=ItGv$&rObw~gUqcoqa<7GLQ^7?*Ry?LQeeZ`k&-Lw4^b6k|+j z$b^p<(zp}0*OLfLDe1I5RKmKRQ10xpzpug#pj6g5uO#;?rEFc_ffJiN(d+)w(kH8R z{u*9t!n?Votx^tkVUYFfQ{I2KNa$)>#1iR&Z?hI9)6Sc0MLv|20xf+ zbwGOGBKo>U(_*q_$!Ok2yOty#b|U{#QPHufgfUa>aX)-!;Kvp)Cp-PRWMa($n1PbW zct|oa;%!tJj=x@n9muQTWOmM|Ri93;)i}`me524LSR#UD4Sod(cqoo$oHGb3RNU&4 zEBtclcB^iu`7=?GGFEyoC$PC4r4!{l2$qvZakCd%r?TbAvA{4<5Z9;v6Q=~WW47lf zPNmKs{(W_-O3uOAqUNc$FJAye7htH5a9D^h;5obg_f!JOF|}ctS)Y24aY6}km}RaI zD+BVxx}q!RubSCgZ}Q9Kv2N=Nd=N89t<-VLLonZE@t93WIM}40OwHy^*fI9x_9)qf zXSXJa*rM|kn41QyNwTmO+U|^-$#i7Gs@L*6PscxR?vZYd3$(CF#ot?~lYXj!?82GY zR0`0!?Irxb=B*a#Dm>!U(|Tv&vG$}PU;nDd`1*5cb0%(jqgsdA)tv2ZeLut9;TWOO zQyo>5Ise=*_TA*@C{NXu7`0xaz&ayA=Y=0cIic;eZ>#CzcKcNXwx8Yx63 z0zxfm_2oWm*f)6Ona${RvV36A`YP2jar>MA!YWLwUZI=N&wJJ95ZY-tZ0_A8<`&kN z{p=F%uk`pu8|s=WocbYI81Mk>X}9@Wi=O^mEI*1CXIBdr2c`7AB4;w(>^^*)xi4}p zDW{c|u0>2akpuB__5X{7g=x>}@S-&i9{k&U)dLaT2^W8XbRVyls-vpvN>pJuw9m-9 zU%)|Wx07cT)5p@fmpm&)ZLQ&iw)UA({Y8~?6I&j+XIGJM78^T}ih%_W%uTDPy#`Sz zeKQyB%3aiNs0id=9a+hHRW-aa!Ra8RXXZ;z6QvT9VLM(XH9>cBK{T$Ter^2iey0kj z>Zp5mj&I?Ai0u5x>`CX6o-#tHpFtu+i+COad7%X_BNOek^f((X5%#>%1VnWfNBbAmqA){TcbiMqPsbVNQ@?0ibh(F2Zojixg(fj{X- z9lQHO6sEZHnl-P(1-md$ay4isOwEqJ+YcFr!hb+W7maHibmCOV6YH^zDC9>YVhQv7 z>Rl?AAz`v)=MpW^@qqVZ>RB^bx7n=V)P%Trit1|hS+?(%KMFSZcyGRO+z3F zDQ8yJNoR=P7V<*1#8i{t^V~4tR|QtfMq7H+Er|7aU)5i2_LRZ|FXXoLukx1cDn;_;6P6L*e$ z*^A3mV*D~2y?!*~5+2K}PcZvCkQ8oC@U15OxncAm$lNH+iXb4(`L0ou6=E|FCwq)MK*rFnrYM__sA!W{7ej?A`H*)^2bzdg`jflHq_U9;JRJJiuw&A^6{L46lp_0+SJOACdurq6F!qUZeERYzZ1 ze?{e5C=)7$$YvQ|eauir8g=4Ze;!{JT7EKnx)3%wMJizkNclLi5Y=9Becz@6?JfVQw7pW5$qg?@U-LGO1tI@sqhsjeJktBP37!vUh&VPlX6GqyPT!% z#hcbo_0?QqW^573wbw^8OT(UvtV-V3XBxK4e+%3Ueh#St=OvF6T?=YYJET%NI|e{F z-am9)&Mk9X_@+N$FpIJvF8-ZR3>$PS3W=O?x~=MN^}4>^?)yT(HTS+U{jht2x!fc= z5_ZO&y*H2^{a>YEkJ-X>|DbG^H>W{yLig6w>XFe1pt=C(mtvzke74vy4ceBL>=9u; zca3E?;l%$*Klgi|t|dYRIUnYLMf-w+wHNl@OZ>M}N4{tlV!E~B+Yv&q(c~WCpv$GW zS*DgJOAyy<21s(GFaQE^LXZ9(5gbD6V@ptNa6JWV zOY>~RIB6L7IU{|pmVY6EcFHPLf+($SAgD*OTw!W7QY6^B{^tg@dZ72w3$I-NM!!g+ zFDyx0;^ncOc9d`EqpL_!%Z$o^60I9^!6ohD+}hnU6jBE&FtBNhn$gFpM$d|N z@HtD8IO^5Mf6g7UaCEVSUDIwORlO2T9Ia|$?&o4 z&FcK33DGvP+0FJLHQL4N*(IWiu`|VpeQ81rw};{LrJi?H+Q{y_68Zl^Uu-qd-CPsP z?ljfh?AeO1b9w)@#d!8z;P;guTD<{BTPpsK_Vlk!Y;*=K4-azkd~csmmq{gdH=^m6 zf7X%D2g{VzW`|zK&jD|x>rKlUiE*^#DLPe7J3~)0tYGkQZIW-^Eb{B~Cbia#H)$cG zGvkU-XonD)%MBbga+eNHI|}zO2ir|MSohWj>~(-g``I11g=iFN4?w< z03&(Zs>O}%3Jh-g4u<*<^rSVkgdxFFyxJmxSsFpPzvGeW6_rKPxHN_Z$lj=e@*Ph5 zYHc(5owJt0*uqLW8?*tkB|5z=2pi_2CmC^rNU>#7y6_R>mNyo3N``Gb1F8e%&SIsm zWy|+!-Y6$gi(W_0*z!N)y^!>}aOX?SPuUr<9=`~`3GSnPb~hbR1(%?DQ(a3+9b-&i zmu3O{u};3icy@^7K-8jQ)lXT@1q}s3YdN>!%f-`tq;!(v+}qoDgI(zuvKq(ouU`y- z1ExQoucKvo1rMDwQa{r?J+X-B!VcgBiRDs9A65kFQ1zQuKF_jXVNTw zAXnd{5+_Mj)vOns1XES&fT}Jof@GXbOisIxqz>&>R@~}_q!7UZ!GDG|j#X13g^WdQ z-AFU%m{IS4AD#XgQTKkT)j3jmF9!2xE^;-ZTYao)C>2iQzSWn#cT&IRs~TZ)ng=&D z|D1S5zOWKD+@93-;$7c1xi<&ARc|x--;E;eUIOys28(s|CKrrjzx$Z6(!t$uu%PV7 zjo*v^fJxf{?_}gxsG5ALqsLi{DbvPF53l+9YKq3oZnAK~GbhJuv;ThKppS-Ydzq)o zj;k2F>(x+C`=0J?zpufpPw$!?0*HDEv(1RLem6tEyrSuP75092ZTF@C$#;gu3kes!lpS~y^5)x8bWZS*;be9)uH>(n8+saz0Fz3eah6{1Z*Abvi+^l)h z)skXW6I-W?GobIUCUVZjBR~eXM22U^o4D632Arn&e7}3W^?fQhg(VQi&^@BS9DYz2 zTleFh|7ij@>b>rHsgB(*VUAsS2pvG@C=SWiGaw)G0x66r9}eDH&^fT=*NOo-nqmx2DZkN#pq@&?^jn<9@4>N@#_rU zE|1j7Tq{1b5PuV!0q^JZ{GV2Glw6xUiGe=KT!~gZpnO0_jaX2;F+{o9nBISg0d$nP z1Znrl`BJlWO~dt#N+*cXwUGUa^uN^bar3#BuxS;`_hQ~R5T)Yd67N8AQe{Tp$6I7# zTL-vvy zOj$riyB}Gtwi1BXYX6@%l#lL^B1V!!%^}7O*V!R57N{X$gi%I4+=ycAmZmLwZl$LU z!Xc!F2g8l>qlp}&Ip+@R&IW7$%;`9V@~N2V-GWGyoxZd{_d|&j(<&1a>C!N(16mb z3fAYB3JGZ`Ox-m#?&5mmFGEKP#WCUxzzXpR9~2m_T`}Py0|wKiVzvH(m$**9CpZO} zsnG;z-9jJ5(TwH7wg&{+!$RuF^Dv?}!2H^a5c$uInDW}-l$<)HYSiTijK*~RBPP*X zMT~oojFn{&%;4@kNlmH^qVLUA?5%7#n&h{6&r8M$Tm(2!vMag|C0UV2Zgi4?NxAav zg^MA$53x7@+gEokK1Y?}TgmHDT}&+F$`Ff2%e`9Fl-Ij#rB{jgTYlLj(#f1xqFzpl zW#%Hce!0$Nw%je51y$UOM_gsQuFGGzhX0o^&ES`Zl5$TO0I8&% zW$}}Y?H&qAd43lgp;0s&nf9LM6vUZHtL(p>N zYN+1jy0yiBzvBKvxY)lfqmZOqpauq|o&ib$M(QCMvB8ReHlS)$m>!gx6`K7D=T{%j zS-cwYQvi>Zv0I&2fbE8>#S;}b{aF&p?)Hto{u0EUS1uzR+->@OGL{%_Xl+& zR)-)em-HfwI7^p$_PSds_X)?f7-j39<+E3#j?)T(qzLlGjdp<1kixAra$C3auC5xO zN~T)9$IQ5OxyJcJ2%>pLq|Im~@Wb>$?jw?01YW~n5z+rGzPfdQ%=ng?bl&WEb%8N z2UtDTe}xpnubOmW*v(7XbdMc?OIhH%YmRLAxnljssZcUr8-HFkbSA_GF=WH8R5&EA zV-^)wf=TE=f%AaFD-7jO#&)4Ykh*X*ZG`2i>$6kgVzNY#30cRzBLlNj7`@T=;&WiTpt)An?xLJxnFCj=t;Ro=12! zXaAZ|IU&vIJeHt2Yno}jBd!jZt_T&oKYD_(aJSEi?z=`iLKH?28})v6wbdfBMd4gD zb-pXl{>Ra|$20l=Z+w`|aYQ+<6e2~+c_@d<`B2HRF%d22*^E%m@+qe|ALfu#a%knW z1LcrYj?I}l<$Rh#R8qhD`}@;Bd+f2>ec$ib>$K`Q%xB3Hz@|`MCYN*Js+|B2768|=J*m%bi@r0BZsah7MDwu zd8XpMf_A<*S$VsyYL`?-Q->ANI7I~&p1?Jng7Mq~&)dOKak0#I!55be$G^xlp9Lxn zNDBw6dzW-J!363U<;%slrJnA}oVuhs04G-C4f4PI?#tyMV-PD+3B)EK{%KD2yWnrF z#kZ$8Y1Gfx->zb1&nU>0c^Zqy&xNrqt5sYLVFwR4WEbi~*UTQ)68|G7uJ^ALO^=aA%b;q~!Mvp-ux! zbX{1uW<;tf47fq(?PL@doj5z8&^AH&zEXos7e?iAGN2KYcb0hRwdJ)c`_(D;aC zF2?&xyJfcY!U1uEF>mHNWeQ^7q$+0vY=u8Od_J@`DGE)mjGEaceoSM@5l?6%ZLycQkuRkE2F`@sn$bR7}!J1){c|+KG zN@;zvU~o0Ky;)J$m<>TKXWQ4j%lot(og2RA zhyNvd$yru{*rNamVPUY&3P}LYuL)N)grlm3-rLhE-Ry>+=zsoT-mT?X_p~`SiYPiZ zs#fn>(}VPttMCLSW|AJ#Y}_Th-B>vDb0Ks!3GG~&bcSi$^IV&}`B(G!I%V*&cf#c@ zemmfL?Th-dS8%HSz6=6(9R=NS!I|JSBam0}J05dWK0j4PqkAOdoY=j?ii`PkWt=*Wy+ZmRtb#W$ivddEcuwGNRXiukkzXK|(7`KM#}qiA;3L60s| zXE8@;3*qSRlrU2Z^1-iB?Q?_jq8=JJMHRwSzobAQsE~`L%B$6vn5{b1HCnavRH146 zglU71PpTa_Y2nPa8qc-TYPOA8;+|1!D^ff|Bb|8mz)r)3On{eC~F zw6?#{7{Y=rVYkM}J&beNWF_dbLO?c|CDKFwX*_8APjHh!_pWMEP;u}C;r^HOraBOq zkhtSVE(cu3eLLsyTUHpu$;yOZ)G~*+XL+Ohd;H07Blg;ms)CmkK3$UCie}nDoq_huWXFsYgXa0{*;W`7{4?n%H|UT)!3;;1JvH9yIs;drZi9 zYx|$>?4G6;2*-KVeyQdtl)o6)1HXF7?c+xnTC=`BURtuju;J5>{eF z9X(u8HY;&G?Yz0LRFC_Gop*Hvi9dNm3;SC%3j%W;Pz9(vWU@s|ajc_>E!^3GC@<+FjPx3}}607b)fx*e&>lSKEBd}vBY3_>~ zHo?)Y1YF6wSe0`3DG?+NCtU$=pLx2jyqKi~+z|1Vk0+`=Qg(eU|G;pCdi)14{Ctr~ z2F>8V6wXCvrdER@8m`r7x=T>93oN~j3HrpH#_RsJ!=61yZ77|Azqrw^(}M>inU48~ zO=;|W;fW3ctZ66A+K&24*Ib5!W^>jXXf=S+q|Wr+_CZ=^>LS8R*1c>znga^<7c3dW zd5iGBWr?GCH}z_JlZIrB1Dx1IBTCmVC0x(oT6dTV*qx1QDv9y@T>9d?oEn&&cs{-) zMkFE4aq2wzE?l=_-G=|DkC~ttAK7aQ@iP%Sd+%%eSlh(;T|RVchFBgK9SeB(o}dy{KJb2`+}-~x_F8A+qa-f zH%*4Owd2K~J&*KgI2RetT z+dgEP$jR7Ur{<@&YI5F0@9)xVZrA9q!%Q@5zdwidcV6@QNzES0i|b^MpTcp>X8Rir ztFFFOd1M9Txsp%q`_i5GL|A8xrzdyU4@ebB?)&~_&2iNSn(IRw+!{yHrhpPyGe9Bz zwcg(l3m<2XoKG99Ia4H+B_tMpR>^FfFm?v%F((!y5*|A$<1O`g(xrV2#6|>q&UABX zB5LNT8IWO_luqRrdT8BMkXNOF)_hQ0-75L|N8Qqij67?n%LaQGux~pE$h<9z)Gj1`?5DJ3kk-!v*4sVQk{|OvStF2< z@08JHjOFMgS-J6=6kUcBQqelyl*4d=1EF8N9vp&k1{Zn4juk=-`qaZGM`_qSz$fTj+q7K?-bd?`WFXJ zUZ-}Bu}A5(Tn&=5-(PC_7fjiSU+oM;Fuow@k>y3yS8EqSwq==*(?nqGJB;DjtPyjk z)u)FJVUOP=4$!@xv^_JOPT`QbKv7P7zbRey;2UK$0%cmM)s^-sh8IV7nH#5vI-9bg zjFBiS52R@%uG(`w9i#*{W-DzQ!%?L?Ao`+GrtjH^&lQ(!*FkB!EK7r{7ga3tp7U<- zG`ngCN|F-m#woz&PZ1pjECtard}9~D`^Eys#8%U3AFH6!yAy>fAuW$> zYYGwPb>3J>_WOH;BTr#7(xNk3S{T~iZsIHIg)kBA#T|J0bqkrcdsl-bzGV~VDD5vV zMo3R=%&1Tkl?246R&BZfvvD;oV=R%w>|k4ch~_zY+Ua%E@3;Odpw1bmd~bOW%VB;=(Qd;DT9!8y!yuw7Zje;oK5MEGRzH;ZYvhII$12_eTuJO8 zfwAXCP7e9^cx#X5J;RgE|CsPo_CDIbcN@+RJj_vdT}IvCbp>jqTn<9hDi^c_?8>B3 zg;HNSl520Na!FriX|+ZZ&%gGcjOce@TCLjj%%ijpKksWXosy)KJ92vPs?b@9?vp<> z8O=3-e8baP(vN4zcq5Y&Rg7%W^p?ANk=r9{8$9H-CwcBWQ{ab2(nWJ6P%5K7dyq%f zd?`f);rSAVU-QHNhhTVIc;)RnvuJ;Bj~nR0vlCrf&WEG}R=1W&(O8y&_Z&u*Y}(|v z4}&R|i5smmqFQKg=j*c<4`+O5t6H`29N6=RZk1QG>bs~C%*vynh z{h%<{Mb_7K(;PqCklB`tTtm{O`Q1y#VNY{6RI$o471Pub1IF(wFN@avaWdC+oS9^mccMnd1z zCg_N6c8;k6r*_b;6$UVg(8oG-;RKs;mmzvf|Ii9YDu^g^0B#=GBq?Uyb4IJRnvU^` zk*xa?J|z)aCqAmDPp~%+6uN<$0lVPz!qW#|a#}ra`tXPPK3c*U0!FAQ$9Nsvi~it$ z=t60;oEn#+ZRABqUhc?bMdK_%SPMN!H)25GHLwUS;$*EFC4Q3{e2~4&1benoJ?#X4 zG(q*FTQ{dLcz)yXfpsBQ(+x8PpK{qlID6(1DiBL%xMbC_6#Q9VNQ^M8?8Vr|<%XaA zIDaiCPMtX|+iCoz-iTFX1dSK^@8HbkLo_~9YsGJ;W>fXQ8q6D^9F7k z@CyID|2BZX&(~`K{G0xZF;3tIwSpq61&tu4s7)R=D}Ju6s6y?h2gZ=H$%&yGXPY0R zL9f&y#IAp{ngEa&uw`zF)fK4~lSrEKaj@vKE}%@Is@gg#1{V9vYOKDImLVhtS^vp! zC>@m-wJwl85bq9>)6`Zfhl=}Wv#c47rGUpNbxS^|Gm%s#2D+&IQ&sFw%gntKNS95X z2znv4U$eOPwk_7U4QnhO9pO!#<(xb*esUe+Bhe3-^C-OC1lyxFs_r2iBK*ly7l_i38B- zr%hlgX5-jKL}KmHBRssz!Q7NdjOYzRiMO_tJv_hYJ%nlO(IYndL!Y#vS+WW~{iBQe z_4?z#6?nD0C5ut`&dqs zo<#{yG*2F}-_`YqAMnoa&WtvtmI^Gv-m(=UOov5BM6vJBOb`&t7nT>*BuX|HiL`S! z`pv(R_mvbxo)BfW#kSjzH)7|=<<-5*%-`SIj|<*@_`6$h?jC;LWcUJSnK@)HzPmzN zZ=elfMyJ+aj6cw0FGSgK;Zwua3>(j$zoPf*Vy@&H(>qWuRyjK{a0X=hZ>l?dNZ$PN z;!R@25>C_Dt~xxug)-Z6HQT!Y(UX5#|P<(1ZX zItqQuyJ~?!LIO{`6|-=0+u>V4gR%cfZKv)>ukVYcxaXfq93J|rV#p9#cYm|bYE58VQry1j;Pvtb7C{c>& z`<|02(ca`rw{>ZJ$Cu0_*kVnYW7PwIT2NAR{vvq-a0yWznL zAL9oYHS;^Vx}&JJLcsbtGodtd-X2b1o$^BG^q%;{lIz?npr zeQIRs_hXlKav_5z=0`2q`};@jGFYh~SCL3DG1(N-{4X3F&BDQ2&dU~&5T;>?@Y7Fq z$4PWa3w-W-c}>=Z3i2Wi=t+7j?ISkDn%v6XAlU3$hLcO#aS96Ly26s0R{Ge(El$J2 zPpbn3gL@<88bX^DICEDn#M$*4dOjFfDvCDMi2q8{gqn$Y#oilKtdw)+62}afM67?7 z^$pK{U?;ChM^GOb3JHf=R9PAaT{UBk#hR#vndeIJHdLS;36D@i*hECEhB!_sAbRxb1=L7BU2_X(Z z^nG&%&TME-gyOx1YTOFWo#SI_O`T?Q$#L+)J8R%eu-dk7C6gdjwOI4+#<0G{sJ#H#pp4`8SyLPkA|Y4aoe`ZTk53h@lVEwq~l#=TO!c1E7KVd11Q< zk3ty7d*zcn+$GI5rMzS5_PkQsKpX5W8AGvU7Q_|wS$?$%goCWaOUXo-;yrthu6-*9 z6RXb0LlIG=xIl*hF^-IAJroIfV`UAzxpf1P=M9)Q{Qpz?rKCk?MV9t2O|J}EJ|q#h z|7aUeDB@qdls-E#REpcfD7vrxFR}r_6;fG==2yUXD?H20hf_itO(W+6K~7rcgY^N- zzWKyFQXIxCj%@0H9Ij-3g%5bus;@G#O@IKe8>xn#lk(l~Fs?{NUb7H-SnXTKxJT2Q zs946H8R4{CUjsIlv3EzJj!urMi-qfgbSDT(91Vc^z8rdt4$!E5I0CU#JS<+)J-dU0FYKkkOBN(>s zzXrm}NV11BeXIDlqk>{!(?xS|pmD9`1rM7`K0&zQ3$#$XBMxz}dFMb~D1snu(qJMJ4k#Ky4&^ap7> zoQf-V+n#!Nj%tF1(4BH>epwaOJtQS7a>{6ADJE}bw`hKEl@mX>D=rn|;bdGJItIyK zt|qo_ilv=Th%$%PT~;;d<;GVj7UaS>Dr>)|R!xu@_@cvntyMqg>>8V;&p(!YIEUbC zO{N0LAS6LayyC-e?(V+xm#XcpLKvTWn>|4$5WR_TOA$Hy%mF=)1{Km31t&`7QqaN& z-eXKxtdm$4J12p=8 z?G->3zpiiSpv3XserM;gvq>sMJo-nNCZqM74gY(_jP$e5(Qu{}J&BP5kNz{^^sNrj z?zQ|^ooQ%$*a?4{c;?!(BSVh{qE3U7rys3N zJy0?d=6O@QR4v{9FfKO}KefXJ+aNU5079+87fwhiZ;7`MqDE`}*cGq9DV_%A=g1&j z8`{+P0n;)Nb&J|QP9FUEAgM!t*zT&r#jAXdjY$SKO+#awT@$wW(Y}VDNKE{KyeLm8 zu{1iq#(iJ;V71~bmDhNKT5<#0P#3tIQE^qBY_@Uff@lt8@k%fPrNprT>e)0Z>+ya$ zXw0rp0=m!)@26@fAD|v(&G~hK_UR?-z}z9#wl(~l4IlORZ=19iM~3pF_sx1&`!&)A zUv(Oo{=7Et5*q72m5Xt9NjdLy_4Tl-5PoJ%{IHy`_&oTX9$+E-+HoUOg;WES>WN)a zsQpvCq`^2woF<)>+i^afYmz9;oak#SA{BwExOt|y$}om}vv+$^R{RPo#+pvmZ4Yq1 zYVZEE{DBhQyw&No+7JbVaj|4u9Y~Bquo9)f1FQP(#~F$*%yaPl-$usp(U0-BrA~r+ zE(T^7aqy;^i0D`98a!%X#~fon^f1l#?UazUFrPKKD<7+9<|s_Ap~SYhQ|=HZKhIq{ zb|}wy6uY^`I<}y3H}7_6x65L{{C5hQ=@<*;cWLi6lGM)BKQqe#RlE2Bkdf0@=@6@~ z2P%8-vo9d6!U9DgqbZ#otV9Cf~lH4hX@rF@tLtV^KdJ@R` zjv--}yM0FM{?Bh4^+gEi+uD)=gi@zJ!gM3t3cbl=ywSIHB|K`pUIl(2reWqW%Rc@c zeK2vR;ggQxJFaZ_63<7)!yo*EVqBlxQCY7&k#tr#00`lnSa`ZJjhw8e3I=tbt#d=h z(stb4tJRsV;m4nJ*3)T_49AbHK-s~ej5qDv7L?iY9Kc2(t4*N_!^XP!@mTO#&r{Atk7B}DFLeUtsfyS8KzyFO} zQ5ZzTP;NJK*=MWSvv`TjkTn80E4z+yM~wKRoxi1@(KK$h%#kmm(eS>Dxn){tD!{!` z+EFcH3s-rqGQ*1!$d&NJZ2T|rgIhVfSX6_`x?#J>8yumeI7AofnN8d-p z;Z|Pqz6nMMhaXV*PFCIZNbbxkznrB|X8lv9_5K_eHP*i~64#=wf6*orY_p4+uj-4S z>(lk4s?YW6h3rK?g)QcH$*xbG2&)d)JvHYLq19prn&On$m=H|%`YzTU)05bf3O425 zKI;3^`=jD8mR}9>;eu{Cv`z&Xu~ab_^9w78h|`QqzKxASi4V6Vx1M;2Qg(>MTpnLw zq7SH%;U9iDuv%mTNPo~IRNS?28w31q@|rNb2$+)f{-}P!s8Vecf3dJfLx4;6yEf8L3*%A@jrAC z4$!}MF#j`tQOei3GSt8;!`@F9V1W0yAaML96OE8a)xMx>JE4T$ycFEIewOW3V`V!G zza;>edC*Zhl+7N?|Mt}xx9#{LknwG{KflXcs3>K(5mlfhwp5~V`p(+`eaj7_fHZC? z%=eeEz#h;ya&B|!SK1o3Ny`9u_?!1|oabBzM`=EKMaM=A=>jnb%)jK+gq&^$VpLx9 z8lKK3y_v;3sgj7g7Lf{u#CWIiD86J8uxS!qjBP~KKw2=(X27vE0%u%%lVk>o8lbn0 zaY~A40RNwpRTr><`cz%gjm89mfh#NOtkT^r;(Bgiy3&I3=5gY}!$Z~C$lo6Z#56-@ z&E7)21Uee3;s|VPE^J6(hA_fHqVkGqSWUi3I!i@+M`Tw)2ZXQYq8HQs?-C3;mN%rC zM(eWoOAWLZ0~M9(0WOb)JuA$kd*?R^UPMAg0FL7OH#l9wy_t|mV2eQUF+qFtHI!>N zTWY#SM5C((#agiN5&yB17PoE3pNIQ6%5<$y7>#Ef`J-(GyniB@fd*@r99uK?!)Dg( zpMITX*G`w1X2(lD!{Fsbn2I)A;RsM##`UTH<qJ9-v<3wt9Xu^W7*hsq1vgJO z&S-iRAyR3vlYoQkzcUQO!e9!XsPXp~HEGUp;r4G?BJR}l-8!LZXOqD1g(T@cR@Q3QDE{?{m+B6NNt^YSu^5vEB1%&3 zRaKG!AZKRu!D_$)$gXQ@Pd%)ApR@K8gc`PtJ6Sny9t+_jLQk1~iIdrXJd=`jA~;m+1)UF}J6HG4V{s8|$9$%6P3L#`Q*of$2qFGtRZujGJE6 z1Gd9D>V4*PaM`P|i+DeZmj34%RrRDab5 z<;c;AiJYZecit3~g*d_qW!Rj7!uW#9AAntO_})}#-pOlom9?y_qcXg#dqZE50?15o zly>xi8&VZN46?(QuJf2U3cHyJ_M(5^qGjAt|84fnRpc=nP7w(>=r_KNKXIu1LJo-Y zePGk4p_U)jgYDPSR7p&47@%V&T|FwGD0GxSmY}k6WQ%*d*MX9m$2U?DRI-{&(e)882Q+|s)kojl8d9dA1 zWcEdAyn*OhI_-LQUEU8i3X8?$WE!&404b z(7a3(FnLN>m=Y=l1tco~jgwT`7CxvG#spUU!1e+wVqvT($8LXfBHsx~2@vbv$$jN% zhl+Ztod38QZ=4$4kJ=6XEgA6YRGbEQG2&w?0!X+JqIvaES&FaI%gs@t={1f;{bxVP zGGYv4`HnvD-F1?`mEo^7c)Mpk)yJRSL@(iY$P3s*6w* zNp7&X%;L>41PVGV0MkV09D=dDWd}AL288mX zKii%i*CTN0YK1{;ieK&la4AJ|LwRWh5hHHca8Zd|PXar&L=Qkz^z&rMo(4oJk(sQE zjY7@W;Pj5l?C6(-*5_xrGPr8F^}Q9*Rw7`>JHIcbe_z(TQQtu^JKeswsXpbu`~1bd zt0j}1t1lrF2pPmMFcp%NZZ%hn`!tEMkW!=&+8gXI|s{zhx-m4<}(iEuI`;uYVuQ8jaG2M|8GD6>Qpemtl~5dNI8a6 z2V+vt{s}IWuCpplG^KKSm8acql%c}Rwr-RL~)0vS=c5IJ3h=`RM93jjRRCxuR**mZ;DbzFz?02`)QURKhL za>Xo|@|X$98UqB<*9j1PHZ;y$25Q6|t7qC)h%WC>@j7UU+Jqr(j~FevdjZgPJ5Re|Vb9u)TgY@lRC9`<)kzB5;eEAqUn$ zW#-)Bad3I)03X98j<%}4Mt}rTd=vLD<7f8%iq7kf>w186Idvqu`NO(WX}`a!WNL-O zUu zH!dsPSetV4J98%zsBI8CJ88Rk&t!)5gLt2ua_`p0GVuCed)vk&FD z9@DWBr*G*cm*AODVYQ*voV zCmCEB+T@b{)j0?#FL9_HBD0xgvE&TrOdiShWJP6xNAB&0_j5)8_X!Ux8ps{%0THQQ zYN&A>r8)cNaEP3pZG39V=z~VOfEpZLt?|w3Y8CtIzVW8pV)gDy(2^Q6w}=~tIXk9b z10q`kMy_S+7n+Az1jyjMJI!BcohTx)$Z@vN8w85HP4>F|XUS5z?=xw}UDEBhbE3*L zUDj~M;!Vp;Q20Z_2_3I*sI}H2Kqh{$+dxrgT1dN=707WzAijL;>Wt%r`9R9%LQS4I z6Ae4Gw+*DYw#NeKmVtbeMCjpNajnp1q=H^Dsg~Xm+Wo?4Mtc@bSGUYtWVVD9ZHb?$5q)E$TO^OAf=LcfRnJ`8pLZ<`- z)2dRJzv$(^374E6_mY&4Zwd!gF5oAjyv1u|3&GD?xQ9{*)=8{Gr% zuRYuB_tBE(+-Soj)_FOT+pRIE#>Evr#yCWiamEBj!N;bA=rdtaR$?M6F|-rC3N3(Z zAmYndIuQJRD+A=6z>qX)!Ygjb+NrviWoc7_kxoQDajqy1G_63kK!Uk!|EmM_8k2)ymU7HMy|7Emnox;D9H)ZJLVqP7N1_aFW3&&vB8TrrhL#%RM@V zc|YfIEZ?+KzfKH@zsdG1c&aC>@i8~04x08VB9Ue~JNaYgXHI|te1=D&-Wx$23rp?n+nn@P|^h0llc*RIzTl7X+uirTx< zqq}N#neq0ATexh$_@V1@_e|{;Ja<8u(f_X`0vfUaGti-w$6!U7j`ceL5~i>wimLd9 z#ge)D_BI(U-YywLlxYF7;;b@FV@AN;Eatr9w{r>jB;}-ho&OXMYv{3b3V9m_EL-@) zvBC28)F2@v@Yu3lz0rG}{=J>OG`O5dneskxS3n|E__c$K#wmgYnpeGMfqI~#@HeJn zK}7GD?GH0Q*q^DFuTgykZ?~FhUD^Gr7+*7AST}^AVVk;NQ7{P=H>^ofgF`%BHQtx4%bR-`qpfB#o}AX;P89-LiaIY|880L( zr1{VF-1+zEL_6xfd{s?*o`LnmGGpE~YGmLkGM7tmO!7xhQtPj57VxH>uS>aGSd>K% z0{W})6#S!>6&itJhKG;dWP)IUWCLAh7O~t?oT2VMBChE%;waNDbRF=(09NjN6PO0b zB}$E1VVi&w2q5qD9tUh50eCSvQEQL(`EAjIm$wRHR>j6Shay@+FlXF1BmRC03yZ#u zc_jCF<^(JXtEMSWp|OACW7yWegMT`+nS=YJOFyia_Ttp2>xHu^&5h5J%VS{LO)WE81}|c&66;STn#?U_$S;mQ|ia*KLd(8G&zNjo_`A7&$yDobGX? zoQUM5b2NQ)wACuolzYHZV%pYywX9c7{racX&O6ag&Kjg7&&dQ2l^1l7^abzKC2ht6 zy&)J}-o5N2YI9lI1_}a>iXNCQ>6QE2S|Lovw>BMsvcNL5pqpF<>^D#ML4ReojIs0P zJWA;P_=fC+!ahL@k4(3C##-h zoACqYKb@P`+&zdVu1YjXDb|iiMDvz(jNqm_b_EYtT1*NCoh4of1xcNrUu$ObNo~+*nyBq$? zLy(99heu5p0pedtJ6`2hwrF^X=4ky#*E`Tl)dMnme9Wg`Z0|nrrpay)_CM=$fpILlmppAl^w<@Y0ts6MM*xUJLJdXsuV45f4JKcGa*`}?P^}rzrZ^N zy~pyJb>+i!_YglkL$AHB5>S;(S>k9ijsT>vG-8$_eiO+=q$zbVRWLhS2}g@X=X6s| za1$LlfYjVC|6YYCV}43Er3D=%dN32~7d_nh=d6~jiA)sVx&0!ya6LaX?)+*t_@(DL zJHH+hgY`Tw-9=X^%mE!fHmrRv->~Xmz|`9sW0|R=m>sw%8*`u zrjWoAYdma!$JWp0?u|`dwfaH=00N1I>e1~CfS}z*-`&ZIB~Sx&cpW+R30J{EfPA0N zE)RNVc=`G)SM=34loW@-iQ=NGSBx`-@a|{KD|>HGncwj zmy{0vLjp_i9|K`+kFF6qG_B(q!>oWY+myTh*5dMPhhQ}})W~>W+ z1BK<9__ctUbBh=y0RdAg69~S~Wi6Hl?k(q!usaHS*>QSb26p_y%p6%q^$ou+NxS)g z;boDe)1gDCyx4Ezhwu-HhVKfPe$PDd0qR_dQydWGD-x?WgewhzeX-omzR-q*JPEhI0=UwpLl z%D%iv`K>Sg{tDdp-a}x4zQa=S^lMFfEX&6QAJ`9Bro&03X{zo@)8pJt<-Y)@O-TeHU__KI>&DLrEi)sl zSH-}o8D(|VkBkTHBjWVE6L*^|>*}h~50&xK>#Z}V(lZRg&r3hF{sZ^|hORpwe$V_@ zbIph2j7-$Ug+gY@xV&g*h+VDe3#dYM4K97{>--Wq2`QkK7S*0DkGB~*w&`(sR3c?Q zWe`;=>npw+L?+#cJ39WErFhs8_*?r*Q1Q^Tkh^MX$D%c+5QS`KMFPL(r34#e6Aw}y z!c=E#WWrmtP)fP8a73=k-pl*BX3|J(4%|(WPl#<5vj?Vg0y9fZVM(G&*|#A*rJ)p~ zC^B2alZnKVyW!TtN-WU9P@WOMmI#FHT~LMG4Ru~TTxm81$8Uh$hb1@4z-5-ai9lu6 z3H`l*9=kW?9m{MD)5$V7eC^hv*1Pj#kY%j>Q!yE*#4WPZ!c0*%%?;@FTRtIfvOy}OUQI7epl^FX%H2E z+8f42K{An~vmWj2&Np2(dqz*fUAeUi`d;mP?B>QrVKbVniD!-4M%{_Qq4z%_Rfjix z)_Egv3K4C9J5#GCs`VgZy6@s?8mrz}0BcAiMJT8|%4+3T(v^u&vBB%l4_(8v47nKL z*&YiTY3iMx+X3e#5%d=Apd;B{E6@_uZL#U z%3hDGfSlE+J>f@A!%cJ>E<@=k(}lQ3t~-vIj%G?G2c zwx!ag0*@b1QnK!HSAY4cyg4DtVoo*tw-rV=6|+}L!YP>3*UYrHn_8doaIqoGdRh82 zRg}*Jk+Y!q%N*yuk!SrD$GgLl@L&1aOi>b2meT(cj=oN^ICVWFJ4eY^gL$M5iO?~Z zAdIu`O(s$Ae}t{E$jN)R;*P-WOU%Xb*=4y!(I+!>*e+0D#?WV~B`1DbsM)*rt&0gX|s`9W=6- zWm_SoKgum_mTvZd^xo71d%;2%O9i92cXQ>0c0rW{f{SYjpNxS3AR-y{QscX>+~lLx z2mnYkCW_Ze>12aK>ce9-ctRb2nt!7kQM0<;G^+2!ilx6jPiJ_VZ-3V_&4;y?i+kmL z;-uRp>*0xZCn`7Tv-}9hzxrrECh-Unwo>c3cXh3&q?*knb)??@pU)v&wl#nG&S&6A zb(5)f7MY|NVj42b|9jyB^p%6%@Tq5A$Rm=J{i?b9?*srKpk?YLw(Us~kGbgrJ4Cua z=&n`XM}#cqV=1}k(zK!rm4N@z$~v4kh2~ZxC29jO>(IFHg&N%4cgkef?&|u_Ky4)R zBKbOFr}yW5uP-5f>M=i-K15KUhsgN{eCt~nXngx|*5^t$f3>y86ab;e25h&Ya+h5U zyo)3=^|emDUP=zJ^+UhiEDZiH_TzE!-(oUM(?|Zx%_GG@y&0Va)B zJ-KjR+Z+oKktZZ3Ky33c20Dasye2@Efw;@?C%qydTYNwf2V%22RhyPwZM;PfL66fO%S)EyYLL}el0qdJwbGLOChXd|-US`FN8vPju5pEJw)M%02paDgXt z)|&mF)oGDqG&8;ct>rk10Us0De%c{tfDXZm;Pul(Y|GVRW#uM5^)EA@bvP^z-*#mS z5PUy3|Gm30lja{&M>V8P?#}ZU z{6%m9me>G)URL6ra=9TS_1gnGT7EbKweZi|k1ChGcPR9Y7}z zaz624@0B7?;FD~5O^`{o2jR=Q3V-yjVpsKV7Cu-EFRv5S2FkjZ^T3J*Wb@?nwX_w6 z*daLHDsSvcS>lztEv zyLL%O77x5bfcfzy;|hP-i-dpw{Tz?J68c=MdUav;-V|N;bvxYg%>q+z;S1?d3NIKF zr=`|?DaGki=b5|3>cGfTKrk zp&$KHfA(_}EfO(%0{aRwu!W{JB!vzs&JW1By4U3oYrj%!rNJAQyfZe| zF=W>$Ku5%o1x@Aq#1DZj1GG>D9eZ@|DpsLC(FEh{in;#Y1mb2&KFxfN4;Va3qq^VL+`Eu3!aR6>;xtk9+6!Mw(jz@f z9W;Fg(-m|p+g0P$xV?i>=6Y=TJBk#i*jCKZ_C)-bEY0&ha0KH}gn1ofS*gq+!94wf zvyi%FP@vM5Dip0&uC8SQ`xe5K^uGIh3)480u(A8rO=5-yZ-++jPAi^P6u|16rmDS` zs@|cop_S0UN*S=piftjMLmtjjY<-l#xtle|d_X|N(`Sz@Y7^9R#NZ7Nix#)3yc!+B z>gemD^%omxSU#W|H}3AP@vpj85Tohz<#dIf;Aw>fQ+85RRH4fJ36WUS;Zx@oz#9Ze z1oW-|Z)r@)`kI8h_XY9xx)s5lT6d(!UrZ?pX^QYT$bRzZw5RXqGu7`r^Sw;_5$4-+ zSK_{q8a=5J#np>;8}R^+8NsIO4BDVptG~04>uolj+VmnH^$6NH0g6l;%($`^5QsZ( z@*cXhpFbS1LbpRU5pw;XtwYa!%hckEYBReu`DHf!187Wj<}qbQ_wPV+D&x2+j+Pqm zKR`w)3x?uKQ9&~K8=!}RlHd?bIPh^3g^PKmUoJ!*^lT2q%5FM$Bax2dfLUYQ_0?B^ zLA~I7yp6^aLofD7o-t2g3c;zNkL!mY29l$*LuI)>Zb-!Nf_jV9gEZe2 zSq=CjqwLXK#@wwxRXa&Q=y4F*WNhd(qm`HZ%Re*ucwWVfX+Ljj|#7 zYFs}+Fi0tLW-v1x#mT{5NShMQcfRhKxhJ0keKM=GmL-pr3c*_^=%u;C@J}8-|ea%R9>Dr~OxUJShYAUH4 zC|(5slEVP=rpe#ZkyUrCH4WE2lPTcvwP@*^WarUK{l>4o@|sINwAxb%*1ARUj4tgI z8lLZ{bB2Wjm(k{x^Sw^X3t6brLd4@AXfTRC+T9R>4-@9$6MlT+bWt!Jo8FXI2k=tg zc&^7_8>0HBlm{B0JCirvZ@cpxZc~4=HN%3GUOG5__SR~(OLs`?-$ zXU4++eNlvoTHZn=<`gT}E`=m(@1-_AE4e-SpTdRe`d3YVtN@uZZ&Oe4=1iUc#Bs-=wyhg;{x!^w-t_Fyu@%e035r`$rx%CKa7MNg z)J=J+2U(y1;6#aYOZTgsCIRs2J)r{do)DnV)9P}-=hg~=dyf}bAEjS<;lvEVk7NRs zwK!g?Ni49XHHl?^+J1aAm3rjozkPQ+_2|kQk7t~FsmPG!YyVf$dB;=z{{R12$2tyC zSsf#@cZIUDNo9``8J!{(vX66|BzvWVjy;YQN|~AG99tR5-W;p!afCRw-}U+a{;I#Y z-Of4A>$;xL$K!tQe=9-VDE}^Z@_-WVXsf55#`$p&Vl!e9R|(x_#YV+^9nhYql3p#M^ z&MT%^3*i)au0=UZPI6;NP$_k3J@@icklUeaGpEIGU)36g0NxX1-lnA{+BWYs^gqoJ zp;%~RNE1=h)VlrYg@<2Dr`_HqGJ~HSI~er(@pkPKBu;taQk&17B z4#eT+D~IVn_w7|zo0)xHXyOabpn>Hm*gyc%(JdmE?6g`dY&l}5tg`xVh8PTjWc%M$ zg?TIIEfZ;}Q0ulpxzs@hI!+{D_F|wRn01s19hjnjSh`XqkejT^!#bY!g z@1{B%6+NM{kn0MC)t6xMupgm9eLsMWX+(^@@MIZJVq7u;p|cB=?Hjay2Ka{$NMuFw zelvm=Ab#_TSiO-3_BS_BkEgdirhBqP&$|tO=tN)$J&6*-95rNf)S9C0Cil00%c|jg z<^h4l%Gyd5Arx8_hBc#Cd=-I3qMB(!%!yDTh~9wMRr-WNS%(l_xWca)Wh;7#A2IH4 zMy4Ajcu17D3k2?#oWoM^xqG@5^LI;9>5jfv@N61h_HF6K)qTux$*q57cL8B^HODD& z*S1v3NhtQY`RMSQploGal5RRFR(awzS__jOxrn__qpb8E%Z6?QStBnmx*J$(=6}V| zGELe>A)czx4^Q4#PVoAPe?I*2!}XdbAv0>!N@YmtY?UYzf1nT;oc6C=ITxB6q~Itl zeD=HoQ{2-E`W4zdS47I#)E$vqI1=5Fx5#=3DX1e)`JZo zxu`eZq`&&4%aJXlxc}yM$?;kn3RKFM5XWs*;)v<$zPWr)pY$!48aQwZj#N zi3?G7QsRBe^ySyOX6qR^)_m}IUAJmsMEmR%8;H2Hr8OMd-1`PU>mqnU;9?ylTvK)F zWS@fxd+v-p=O>9LRUdZ|QJzkD`}h_Ji*AEqxg4 zs9ndm!l}QUR>w15OmNgjpM=)nON3mULYARmSyn6-DnX zg)&T#RrOB4+mrR3Cnt$ixvo;@IbHR-W@4+MBvQ_Zk%ga6(+>MZ&6@w_kJ&4qMm@Kq z4`!MWkJ|2DZGK-40Z7BXCoDOoD7}r@N zX*vDN)OceLJ)Zj`j~8MZ4#MzxUwtvQ0Fy18&ve%bz0!Zb#!7164K!FlmRl zjDpcYNbDR&imfs6{OJDCQ(S)&pc>GE5v49&2u8Gub}Hpa{3`nTzMc#dTC_DpDMvP; zhTo!$KfpNvt@r0nkdv6zC8F#{BC^z}(l++m zY|lfv>z7;bk0vV@s*B6_3qI0r@%}3L_2PPuilXb4g)0by8xYLsiQhkV6**-ZY*r~o zUjckBDKQMR zDC%X@9cTN|S-kN77zZil70BmoL{acINV?#)bW@8#nk-y&+4@Q2VwF@u9;*#E6FSji z+!R9NL~Q1nZ4xSF&Yon@_dsO$XkAsmLHJ-LD#1QzO)z6|+xUG;uW99rT&ta_!{TgX z(e~m&+MM00H79)tCLt7(3}3N$cb+j{_NAjxk<|FssHqbePT$NcGH@Wq{!w$;RQ&3Q zzPg@0!u!`liDk&NT&&M0a?Xhd4b>6?U}Di>mxtK#U^UZJI2xts@~z93@b&3S5A2Vo zdAIy$tlf_&%+;ADnkRJPY`=siE>p)=cEeN@Ol;o0jAstGlhla-uwRp}28@uyB4uX- zbQKx#A5N{NMFvGx>I`th#vA-(vmwA908EgY(e<7!nepx7~~=7YQd* z=^2xJ6+xy8oC8=R{stg(5u)M&w6uaHK|%aN1)gV%VC6AB{{&8XAxUE&@DU-^nTaQ*q#z;!Fe zlxE|XQCN@fv^)lg+~qHsstLLq^|)Ar4&l@)2Oj7Xg|&}|MwMDMX>GOtol`zyKt$F>Sc|~C zwmj>S*}_Y-9L@qTNUW4|bHVlCM*Yz$WSysmK2(rxj5?1R`FC6EK?jZMQu{#z*l@8k zB$4#PTP8gS&kAj;T6&74m@UB~;T9u+`lO05=#}EX&DGPEBaY|lBMPm-mZg}A?(~u7s@Ebl6(gshawoo5CgWa`D6usI>VgeD}FpE6o3w#plmnL%*<#%0m$Z#o9pp zi<=_b*I6ghmCpDt><|dM3Db?6tW@)v_Q`i}1f}&g2@1x8dT8&OQ|{BF)6CP~I=_1{ z&CtA+DJ?zCk1y>j@0<`9povwF;<-#xrJS_ww58ct!q~EGO>yW(3N>Gyb zNUyF_*)A6A7r4HiX*Rk{DHZMc@*%L1uoix0CU2R3q~nz%!f|vJeN-gM0~@dle`JP@ zs__euI)Y}E=Vq@?FiQ4XjmsWH@Vxzj*0bR@cCWQSFuO0oX;Cb` z8?C_7xaIot=+JuiuA~ATRj1zs!17IbG|j7z$339<4}F>Fstl9SLsrMUJ8e?4T5M8~ zM%Q39OE>o()tF>hP}B`Q813I*bomR%ewMvLPnSVvi_{?4+yxO8*LjZzRroWbDhtZC<$(Qp>v6VMus1A-6WLTdjRDV+M3xz}D{||-M%M&(2`?IbuiV&iw0Bjv z8NT%Dl9IB0&n~O0eDahlqlQzA#cArH!oeIEWE+{FU9RF0i zT7#w7i1~aQ^Z#X(-hhf&$cWvoRwduwol|eP{qQVS(g@DU+nY1$@b4op&cP^^~zn@ zc?O?bEydZpDZ(T}2HM5QP)$dKNTS*wK9>B6NtzHl<4PPo6gu!PsG95Ft8c`&u~R$V zd+V0vyIo~KeX`9@Hu44IU>KYq76*zh7hMrA-2-aBRtPup%3c-y;GuW{q8%%TK;Cx~ zvujy!7{@Gq67x(@&br~d&MZBq==4Zo z9aId*iNP2GSy6J`_GGTueS0qB-%N2HJCdUB_j-Y4l{dY_;Lu|OcV5>f37mX8z?aqM z6hXp79j@2RCw&Qr9$C~iD=+g;n&QPh_N3L>%5Uo!^>+m-Fr?Z<&HZ z-d|%i#=%7khb%8s?kH#1AlG9LMcaRLSUJ~qxm}N6alRwC((H(Ewmz;6-L=iJn1Z?P zO`F(WdSD~zM64zp!W@%G-&ot_2ZRbfmiH7fQeEG%F(P2HBFk-*>1uS+Cz8CWt<*6G<3C{= zmdpE0>1;Q0X>|ESp4@RiTl7Rsd;-08=kux@pKu_}U$A8fr{QTwgb)wNE2x_g9n?xVjKiSyI!j(H7Ei9>bVHgoJ&?5naz*U)69Urr zPAA?-fDmH{TbB2;j}=_`;&w=b5Zf$zRZ9nJ0f>8D^w;5^F$?m^_mHVrHiOc zK0|PSy#gvB=o*ul8(+W4$PC6EQWUmCu$DR(X~5rqk=eIyT(xWhSxknSRwOQe^#&n^ zds!1hu>apKB+hryG)ZO2g&-)59>K{##%#w2->J6;UR#ull+#1TsnpIE%YA)!-iWiR zc!on&Fo3GFSn^kKREwD@mkpvidnmMSXtwWxM2InZkLz<$1|oD>`CkFcx(ux97BKoS ztJb1cQb>=!!FzZ5K`DM2r(h@nRCPpAred>HsVq7}#(s0aF0vy%cEmXR6^iw^jbBV^ z6yUp4f{>5d96zh$;FMLT6onTsp1?09f7InOLwE=Up>y-fWp0)XfVKncSn=;eAZ03- zGZSy=D03G7M9jyAiI(pF+8_BcrjuDWyW=WD)WjRy^o}VRYZ;hv=7!)G*9#1ia+6}0 zE-a<_3`H&9Ljsj`bu*rsq9$VxucytnOAamxbKW zTTPS371KYy$B{ak8L55B^_~xsKP((t-^*dWknjB0TWOk?+W(O9MNta7gvyM|XrF|a zQ_Ekp5XnuKsl{wqXQVex={CO@J5;*h9ns6V<5#ecLp=R?<-(LeS1h8K)#B%S#1rdw zk!!}t3@{Ac-Ny#x`g!~5p`%JX6%?8o3~orG*@i1O(|^si5NmQLP5;Ur*zbXFcfFNh zt$W>1Vkd?d2K|*2 zhqqJSZcl!7f%Lld%+(?`w}~Q^UBTB6jU<@>yJ3)PWdqF?z8u(FYKmkJXS0-ogo|R< z|9e}}Y3kc7HWHQo>*mNqKbk=}4|P(hIkUPa%=5Y=^eIWR{yVcqcK>JA_1=vTz)R;d zAHF7OTTD3>!%EQ2pN&u{WPLa?LxjFg6B#QD3j*#H{Q)I4

SSfRl^Zb>~s8qn(+8tTTj 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 OKQ?=DM7!$(1_l6qpAnt_ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/bg_content_card_small.webp b/app/src/main/res/drawable-xxxhdpi/bg_content_card_small.webp new file mode 100644 index 0000000000000000000000000000000000000000..c067ffd380e6103838033bb29ee2847653e2c764 GIT binary patch literal 516 zcmWIYbaVT|$iNWp>J$(bVBzx~$kum1XfAMmfm*^LwFL|Q`F^{b;Ou*##n-{{@9a0b z9TCh%h1+IZg>yLg8!Xe4c^IxoG0#)Ez4ffwBp)MBwVAmpGgG$x{eOO&!=w!92`abP zI49+<4%=K<{`P0TNISENb(Qk3_Z_*??naZ=M#k&Uy#HdRisvL0bn@H3n`dMz39#&a*{I$OzJoT+}bxatYNw&>Ao4ePuv-8-^NMV5EY`oMD2%!K`} zbFVD9yKuF3))KqAWoo%~Cg$@tEw;;AvuS_hvb(cNekRIZeNnpc&-bW*)w=)pPWvBs zx_Ni literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/bg_content_card_small_right.webp b/app/src/main/res/drawable-xxxhdpi/bg_content_card_small_right.webp new file mode 100644 index 0000000000000000000000000000000000000000..ae0417fe795cba346c12f6e45125bf9624172a31 GIT binary patch literal 890 zcmV-=1BLujNk&F;0{{S5MM6+kP&il$0000G0000-0RZ0s06|PpNRa^m01bdpTYKB) z3j;w=5m-eKm4So6HUhT@WFd%+U?6B9I1Cg7RT-E;_psdYWhx>Rxoz9nNV4feHVRBwm3pwVRD@BW!@23~483bm;wrld-DxyP zvAnmNu(1Fw7Ok@s27v0xau`7M(1*GXCD?IYhk?lq^hmU;Fnu7%Dy>31SS3S3*^d;K zfXM6VB>)bK3?Q*cSrV384%>isM3wU%7zt5QQ+Gv_+n4fg*Hr8hHW?Hmv5zBN`8jM(LK6vumJ#8P&gpE0RR9n833IDDo6p~00000 zC8fKC-GpzL1E2b#2BDlFz?B2rTfhV@;q!ZiFos zXU9;V@z~#d}uGWjC{%CO`xhezE;sOrqMB`(Jw4;=*P^SG}B>hWI9q8I#7FM8=y$y5J_WR%1<~V@;xCOnJ8kZu2LNHi?Zk ziG9O(^Jfn&dVI;_O^QurVDi_e%$_u|W{J7G*RARECyh3VjVc*n0092~{`+>-fB(;x z2mkMG>30~nWklN$-6U9SVD4QMV5YEXWbH)Qd@#x3e# zJ3Dz@2M?%!5F5FxZ~y2;+>s0BK{>?(NC7S3 zB8{{pXNEHFhFYAoJ&ajR34mMP4)?Fe~{t(&7iY?J$^W^W72g05 Q!FP{fjzFn5wyrn;07KZLzW@LL literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/bg_hint_red_radius_999.xml b/app/src/main/res/drawable/bg_hint_red_radius_999.xml new file mode 100644 index 0000000000..f9c6f807c0 --- /dev/null +++ b/app/src/main/res/drawable/bg_hint_red_radius_999.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/gamedetail_body.xml b/app/src/main/res/layout/gamedetail_body.xml index d731de90e6..a1e2b50e0d 100644 --- a/app/src/main/res/layout/gamedetail_body.xml +++ b/app/src/main/res/layout/gamedetail_body.xml @@ -223,6 +223,16 @@ tools:text="游戏大事件游戏大事件" tools:visibility="visible" /> + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_game_detail_content_card_large.xml b/app/src/main/res/layout/layout_game_detail_content_card_large.xml new file mode 100644 index 0000000000..f3b249d5b3 --- /dev/null +++ b/app/src/main/res/layout/layout_game_detail_content_card_large.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_game_detail_content_card_small.xml b/app/src/main/res/layout/layout_game_detail_content_card_small.xml new file mode 100644 index 0000000000..a878f69ec8 --- /dev/null +++ b/app/src/main/res/layout/layout_game_detail_content_card_small.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/module_common/src/main/java/com/gh/gamecenter/common/constant/EntranceConsts.java b/module_common/src/main/java/com/gh/gamecenter/common/constant/EntranceConsts.java index c66deae246..dcf7feef6f 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/constant/EntranceConsts.java +++ b/module_common/src/main/java/com/gh/gamecenter/common/constant/EntranceConsts.java @@ -202,6 +202,7 @@ public class EntranceConsts { public static final String KEY_CONFLICT_PHONE = "conflictPhone"; public static final String KEY_CONFLICT_USER = "conflictUser"; public static final String KEY_EXPOSURE_SOURCE = "exposure_source"; + public static final String KEY_EXPOSURE_SOURCE_LIST = "exposure_source_list"; public static final String KEY_BBS_ID = "bbs_id"; public static final String KEY_DIAGNOSIS = "diagnosis"; public static final String KEY_SIMULATOR = "simulator"; diff --git a/module_core/src/main/java/com/gh/gamecenter/core/utils/TimeUtils.kt b/module_core/src/main/java/com/gh/gamecenter/core/utils/TimeUtils.kt index ebe195fc93..ee11a81c11 100644 --- a/module_core/src/main/java/com/gh/gamecenter/core/utils/TimeUtils.kt +++ b/module_core/src/main/java/com/gh/gamecenter/core/utils/TimeUtils.kt @@ -66,6 +66,18 @@ object TimeUtils { return false } + //判断是不是明天 + fun isTomorrow(timestamp: Long): Boolean { + val format = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA) + format.timeZone = TimeZone.getTimeZone("Asia/Shanghai") + val today = format.parse(format.format(Date())).time + val day = timestamp * 1000 + if (day >= today + 86400 * 1000 && day < today + 86400 * 1000 * 2) { + return true + } + return false + } + //判断是不是本周 fun isThisWeek(timestamp: Long): Boolean { val calendar = Calendar.getInstance() From 54131d507bad1231d21df7d6410ea90ce5f635c7 Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 26 Jul 2022 16:38:16 +0800 Subject: [PATCH 131/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=99=AE?= =?UTF-8?q?=E9=80=9A=E6=B8=B8=E6=88=8F=E4=B8=8B=E8=BD=BD=E8=BF=9B=E5=BA=A6?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=A2=91=E7=8E=87=E4=B9=9F=E6=8F=90=E9=AB=98?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/download/DownloadManager.java | 1 + app/src/main/java/com/gh/vspace/VHelper.kt | 8 ++++++-- app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt | 3 +++ libraries/LGLibrary | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index c0119661c3..bd68a69ae9 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -331,6 +331,7 @@ public class DownloadManager implements DownloadStatusListener { if (gameEntity.isVGame()) { ExtensionsKt.addMetaExtra(downloadEntity, Constants.SMOOTH_GAME, "true"); ExtensionsKt.addMetaExtra(downloadEntity, Constants.EXTRA_DOWNLOAD_TYPE, Constants.SMOOTH_GAME); + ExtensionsKt.addMetaExtra(downloadEntity, DownloadConfig.KEY_PROGRESS_CALLBACK_INTERVAL, "200"); } HashMap map = PageSwitchDataHelper.popLastPageData(); diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index eefd6b1878..b6f2609746 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -617,10 +617,14 @@ object VHelper { private fun showDialogIfVSpaceIsNeeded(context: Context): Boolean { Utils.log(LOG_TAG, "检测是否已安装畅玩空间") - val vaConfig = Config.getVSettingEntity()?.va ?: return true + val vaConfig = Config.getVSettingEntity()?.va + + if (vaConfig == null) { + ToastUtils.toast("畅玩空间暂未上线") + } // TODO 检测 32 位 - if (!PackageUtils.isInstalled(context, vaConfig.arch64?.packageName)) { + if (!PackageUtils.isInstalled(context, vaConfig!!.arch64?.packageName)) { VSpaceDialogFragment.showDownloadDialog(context, getVSpaceDownloadEntity(false)) Utils.log(LOG_TAG, "显示下载畅玩空间弹窗") return true diff --git a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt index 49407e0a73..d97d8dffe0 100644 --- a/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt +++ b/app/src/main/java/com/gh/vspace/VSpaceDialogFragment.kt @@ -26,6 +26,7 @@ import com.gh.download.PackageObserver import com.gh.gamecenter.R import com.gh.gamecenter.common.base.fragment.BaseDraggableDialogFragment import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.utils.addMetaExtra import com.gh.gamecenter.common.utils.toColor import com.gh.gamecenter.common.utils.toJson import com.gh.gamecenter.common.utils.viewModelProvider @@ -36,6 +37,7 @@ import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.eventbus.EBPackage import com.halo.assistant.HaloApp import com.lightgame.download.DataWatcher +import com.lightgame.download.DownloadConfig import com.lightgame.download.DownloadEntity import com.lightgame.download.DownloadStatus.* import com.lightgame.utils.AppManager @@ -116,6 +118,7 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() { downloadEntity.gameId = "62bd412bbbf04747cd3de539" downloadEntity.path = PackageInstaller.getDownloadPathWithId(downloadId, "apk") downloadEntity.packageName = VHelper.DEFAULT_VSPACE_PACKAGENAME + downloadEntity.addMetaExtra(DownloadConfig.KEY_PROGRESS_CALLBACK_INTERVAL, "200") // 确定下载类型 val downloadType = diff --git a/libraries/LGLibrary b/libraries/LGLibrary index 692d58bc9b..8306e2fe0a 160000 --- a/libraries/LGLibrary +++ b/libraries/LGLibrary @@ -1 +1 @@ -Subproject commit 692d58bc9b494bf1d04db7809d43acbedaeb326c +Subproject commit 8306e2fe0a0f10c3e7464d63971a8e7874ab4cdf From e8645cd717b42c348af741a80ac3dee7afea528e Mon Sep 17 00:00:00 2001 From: lyr Date: Wed, 27 Jul 2022 11:19:27 +0800 Subject: [PATCH 132/217] =?UTF-8?q?fix:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=B8=B8=E6=88=8F=E4=B8=93?= =?UTF-8?q?=E9=A2=98=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96=EF=BC=880727UI?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E9=97=AE=E9=A2=98=201=EF=BC=89https://git.sh?= =?UTF-8?q?anqu.cc/pm/halo/halo-app-issues/-/issues/1950#note=5F161351?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/res/layout/game_double_card_item.xml | 152 +++++++++--------- 1 file changed, 80 insertions(+), 72 deletions(-) diff --git a/app/src/main/res/layout/game_double_card_item.xml b/app/src/main/res/layout/game_double_card_item.xml index fbd3f544b1..9e3a174ed4 100644 --- a/app/src/main/res/layout/game_double_card_item.xml +++ b/app/src/main/res/layout/game_double_card_item.xml @@ -1,83 +1,91 @@ - + app:cardCornerRadius="8dp" + app:cardElevation="0dp"> - + android:background="@drawable/bg_shape_space_radius_8" + android:paddingBottom="12dp"> - + - + - + - \ No newline at end of file + + + + \ No newline at end of file From 6efe9328b1c63d9cc1614448de00313af658326b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Wed, 27 Jul 2022 11:43:56 +0800 Subject: [PATCH 133/217] =?UTF-8?q?fix:=20=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E7=89=88=E5=9D=97=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E5=88=97=E8=A1=A8=E4=BC=98(0727=E6=B5=8B=E8=AF=951)?= =?UTF-8?q?=20https://git.shanqu.cc/pm/halo/halo-app-issues/-/issues/1948?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/common/util/DirectUtils.kt | 10 ++++++++-- .../java/com/gh/gamecenter/entity/SubjectEntity.kt | 2 ++ .../java/com/gh/gamecenter/game/GameFragmentAdapter.kt | 2 +- .../main/java/com/gh/gamecenter/game/GameViewModel.kt | 4 ++-- .../bigimagerecommend/BigImageRecommendViewHolder.kt | 2 +- .../main/java/com/gh/gamecenter/home/HomeViewModel.kt | 5 +++-- .../home/LegacyHomeFragmentAdapterAssistant.kt | 2 +- 7 files changed, 18 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/DirectUtils.kt b/app/src/main/java/com/gh/common/util/DirectUtils.kt index 01ef948439..41c354f2ff 100644 --- a/app/src/main/java/com/gh/common/util/DirectUtils.kt +++ b/app/src/main/java/com/gh/common/util/DirectUtils.kt @@ -264,7 +264,7 @@ object DirectUtils { "wechat_bind" -> context.startActivity(WebActivity.getBindWechatIntent(context)) - "video", "video_stream", "视频" -> directToVideoDetail( + "video", "bbs_video", "video_stream", "视频" -> directToVideoDetail( context, videoId = linkEntity.link!!, fromLocation = VideoDetailContainerViewModel.Location.VIDEO_CHOICENESS.value, @@ -1703,7 +1703,13 @@ object DirectUtils { * 跳转至游戏单广场 */ @JvmStatic - fun directToGameCollectionSquare(context: Context, entrance: String = "", forumName: String = "", gameCollectionTitle: String = "", gameCollectionId: String = "") { + fun directToGameCollectionSquare( + context: Context, + entrance: String = "", + forumName: String = "", + gameCollectionTitle: String = "", + gameCollectionId: String = "" + ) { val bundle = Bundle() bundle.putString(KEY_TO, GameCollectionSquareActivity::class.java.name) bundle.putString(KEY_ENTRANCE, entrance) diff --git a/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt index 94556e1615..fc7c25be3a 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt @@ -58,6 +58,8 @@ data class SubjectEntity( var secondLineRecommend: String = "", @SerializedName("recommend_tag") var recommendTag: String = "", + @SerializedName("link_text") + var linkText: String = "", // 专题合集,用于首页专题合集-排行榜样式 var columns: MutableList = mutableListOf(), diff --git a/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt index 6a5a8fb43f..ddc5408f03 100644 --- a/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/game/GameFragmentAdapter.kt @@ -1148,7 +1148,7 @@ class GameFragmentAdapter( mViewModel.blockData?.let { blockData -> NewFlatLogUtils.logBlockGameContentCardClick( blockData.link ?: "", blockData.name ?: "", - it.type ?: "", it.link ?: "", "" + it.type ?: "", it.link ?: "", it.linkText ?: "" ) } } diff --git a/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt b/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt index 83d21c32cd..a0f2a37b4a 100644 --- a/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/game/GameViewModel.kt @@ -569,7 +569,7 @@ class GameViewModel(application: Application, var blockData: SubjectRecommendEnt && subjectEntity.type != "column_collection" && subjectEntity.type != "community_article" && subjectEntity.type != "question" - && subjectEntity.type != "video" + && subjectEntity.type != "bbs_video" && subjectEntity.type != "news") || (subjectEntity.type == "column_collection" && subjectEntity.style != "top") ) { @@ -706,7 +706,7 @@ class GameViewModel(application: Application, var blockData: SubjectRecommendEnt if (subjectEntity.type == "community_article" || subjectEntity.type == "question" - || subjectEntity.type == "video" + || subjectEntity.type == "bbs_video" || subjectEntity.type == "news" ) { val itemDataSubject = GameItemData() diff --git a/app/src/main/java/com/gh/gamecenter/game/bigimagerecommend/BigImageRecommendViewHolder.kt b/app/src/main/java/com/gh/gamecenter/game/bigimagerecommend/BigImageRecommendViewHolder.kt index f7c9d43070..2c83611a50 100644 --- a/app/src/main/java/com/gh/gamecenter/game/bigimagerecommend/BigImageRecommendViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/game/bigimagerecommend/BigImageRecommendViewHolder.kt @@ -19,7 +19,7 @@ class BigImageRecommendViewHolder(val binding: BigImageRecommendItemBinding) : B recommendTextOne.text = subjectEntity.firstLineRecommend recommendTextTwo.text = subjectEntity.secondLineRecommend root.setOnClickListener { - val linkEntity = LinkEntity(link = subjectEntity.id, type = subjectEntity.type) + val linkEntity = LinkEntity(link = subjectEntity.id, type = subjectEntity.type, linkText = subjectEntity.linkText) clickCallback.invoke(linkEntity) DirectUtils.directToLinkPage(root.context, linkEntity, entrance, "") } diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index 71ca22871b..33dd068a11 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -418,7 +418,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { mSnapshotItemList.add(gameCollection) } else if (linkType == "community_article" || linkType == "question" - || linkType == "video" + || linkType == "bbs_video" || linkType == "news" ) { val homeItemData = HomeItemData().apply { @@ -429,7 +429,8 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { image = homeContent.image, firstLineRecommend = homeContent.firstLineRecommend, secondLineRecommend = homeContent.secondLineRecommend, - recommendTag = homeContent.recommendTag + recommendTag = homeContent.recommendTag, + linkText = homeContent.linkText ) } mSnapshotItemList.add(homeItemData) diff --git a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt index 58a5b3fda5..043923d254 100644 --- a/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt +++ b/app/src/main/java/com/gh/gamecenter/home/LegacyHomeFragmentAdapterAssistant.kt @@ -896,7 +896,7 @@ class LegacyHomeFragmentAdapterAssistant( private fun bindBigImageRecommend(holder: BigImageRecommendViewHolder, item: LegacyHomeItemData) { item.bigImageRecommend?.run { holder.bindBigImageRecommend(this, "新首页") { - NewFlatLogUtils.logHomeGameContentCardClick(it.type ?: "", it.link ?: "", "") + NewFlatLogUtils.logHomeGameContentCardClick(it.type ?: "", it.link ?: "", it.linkText ?: "") } } } From a1d182a82cc35b4d1cf0e03487ef074026778063 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Wed, 27 Jul 2022 13:59:03 +0800 Subject: [PATCH 134/217] =?UTF-8?q?fix:=20=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=B8=B8=E6=88=8F=E4=B8=93?= =?UTF-8?q?=E9=A2=98=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96(0727UI=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E9=97=AE=E9=A2=982)=20https://git.shanqu.cc/pm/halo/h?= =?UTF-8?q?alo-app-issues/-/issues/1950?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/drawable/bg_shape_f8_radius_6.xml | 2 +- app/src/main/res/layout/big_image_recommend_item.xml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/drawable/bg_shape_f8_radius_6.xml b/app/src/main/res/drawable/bg_shape_f8_radius_6.xml index 4427662808..b7bd6cc341 100644 --- a/app/src/main/res/drawable/bg_shape_f8_radius_6.xml +++ b/app/src/main/res/drawable/bg_shape_f8_radius_6.xml @@ -2,5 +2,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/layout/big_image_recommend_item.xml b/app/src/main/res/layout/big_image_recommend_item.xml index a74d24ddea..b1694aa9bc 100644 --- a/app/src/main/res/layout/big_image_recommend_item.xml +++ b/app/src/main/res/layout/big_image_recommend_item.xml @@ -57,6 +57,7 @@ app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@+id/poster" + android:textStyle="bold" app:layout_goneMarginRight="12dp" tools:text="火炬之光:无限" /> @@ -65,7 +66,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginLeft="16dp" - android:layout_marginTop="8dp" + android:layout_marginTop="6dp" android:layout_marginRight="16dp" android:ellipsize="end" android:includeFontPadding="false" From 4e9d5357c874adf58c43d1f6b13637f44b73f209 Mon Sep 17 00:00:00 2001 From: leafwai Date: Wed, 27 Jul 2022 16:23:15 +0800 Subject: [PATCH 135/217] =?UTF-8?q?fix:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=96=B0=E5=A2=9E=20?= =?UTF-8?q?=E5=8F=91=E5=B8=83=E5=86=85=E5=AE=B9=E9=9C=80=E5=AE=9E=E5=90=8D?= =?UTF-8?q?=E8=AE=A4=E8=AF=81(0727=E6=B5=8B=E8=AF=952)=20https://git.shanq?= =?UTF-8?q?u.cc/pm/halo/halo-app-issues/-/issues/1982?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/gamecenter/gamedetail/rating/RatingReplyActivity.kt | 5 +++++ .../gh/gamecenter/gamedetail/rating/RatingReplyViewModel.kt | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingReplyActivity.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingReplyActivity.kt index d895cb4cfa..6d401b7267 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingReplyActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingReplyActivity.kt @@ -18,6 +18,7 @@ import com.gh.download.DownloadManager import com.gh.gamecenter.R import com.gh.gamecenter.baselist.ListActivity import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment +import com.gh.gamecenter.common.callback.ConfirmListener import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.common.view.VerticalItemDecoration @@ -187,6 +188,10 @@ class RatingReplyActivity : ListActivity Unit) { + fun replyComment(replyId: String?, content: String, successCallback: () -> Unit, realNameConfirmListener: ConfirmListener) { processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", true)) val json = json { @@ -224,7 +225,7 @@ class RatingReplyViewModel( false ) ) - ErrorHelper.handleError(getApplication(), e?.response()?.errorBody()?.string()) + ErrorHelper.handleError(getApplication(), e?.response()?.errorBody()?.string(), false, realNameConfirmListener) } }) } From dc3ae1d36d095fe0f4a22c04a3811fcfc2f55062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Thu, 28 Jul 2022 09:22:31 +0800 Subject: [PATCH 136/217] =?UTF-8?q?fix:=20=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E7=89=88=E5=9D=97=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E5=88=97=E8=A1=A8=E4=BC=98=E5=8C=96(0727=E6=B5=8B?= =?UTF-8?q?=E8=AF=952)=20https://git.shanqu.cc/pm/halo/halo-app-issues/-/i?= =?UTF-8?q?ssues/1948?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt | 4 ++-- .../game/bigimagerecommend/BigImageRecommendViewHolder.kt | 2 +- app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt index fc7c25be3a..5f2b5e2e8f 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/SubjectEntity.kt @@ -58,8 +58,8 @@ data class SubjectEntity( var secondLineRecommend: String = "", @SerializedName("recommend_tag") var recommendTag: String = "", - @SerializedName("link_text") - var linkText: String = "", + @SerializedName("column_name") + var columnName: String = "", // 专题合集,用于首页专题合集-排行榜样式 var columns: MutableList = mutableListOf(), diff --git a/app/src/main/java/com/gh/gamecenter/game/bigimagerecommend/BigImageRecommendViewHolder.kt b/app/src/main/java/com/gh/gamecenter/game/bigimagerecommend/BigImageRecommendViewHolder.kt index 2c83611a50..724f2cde0a 100644 --- a/app/src/main/java/com/gh/gamecenter/game/bigimagerecommend/BigImageRecommendViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/game/bigimagerecommend/BigImageRecommendViewHolder.kt @@ -19,7 +19,7 @@ class BigImageRecommendViewHolder(val binding: BigImageRecommendItemBinding) : B recommendTextOne.text = subjectEntity.firstLineRecommend recommendTextTwo.text = subjectEntity.secondLineRecommend root.setOnClickListener { - val linkEntity = LinkEntity(link = subjectEntity.id, type = subjectEntity.type, linkText = subjectEntity.linkText) + val linkEntity = LinkEntity(link = subjectEntity.id, type = subjectEntity.type, linkText = subjectEntity.columnName) clickCallback.invoke(linkEntity) DirectUtils.directToLinkPage(root.context, linkEntity, entrance, "") } diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index 33dd068a11..f797f95bf9 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -430,7 +430,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { firstLineRecommend = homeContent.firstLineRecommend, secondLineRecommend = homeContent.secondLineRecommend, recommendTag = homeContent.recommendTag, - linkText = homeContent.linkText + columnName = homeContent.linkText ) } mSnapshotItemList.add(homeItemData) From 3d56da3b6f605905ef91ed512e873aedb3c17c17 Mon Sep 17 00:00:00 2001 From: leafwai Date: Thu, 28 Jul 2022 14:29:20 +0800 Subject: [PATCH 137/217] =?UTF-8?q?fix:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=B8=B8=E6=88=8F=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E6=96=B0=E5=A2=9E=E2=80=9C=E5=86=85=E5=AE=B9=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E2=80=9D=E5=8A=9F=E8=83=BD(0727=E6=B5=8B=E8=AF=952-4?= =?UTF-8?q?=E3=80=818(3))=20https://git.shanqu.cc/pm/halo/halo-app-issues/?= =?UTF-8?q?-/issues/1953?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/gamecenter/GameDetailActivity.kt | 2 +- .../gamedetail/GameDetailFragment.kt | 25 +++++------ .../gamedetail/GameDetailViewModel.kt | 20 ++++++--- .../layout_game_detail_content_card_large.xml | 44 +++++-------------- .../layout_game_detail_content_card_small.xml | 26 ++++------- 5 files changed, 47 insertions(+), 70 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/GameDetailActivity.kt b/app/src/main/java/com/gh/gamecenter/GameDetailActivity.kt index c94897e465..5767fc9c48 100644 --- a/app/src/main/java/com/gh/gamecenter/GameDetailActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/GameDetailActivity.kt @@ -80,7 +80,7 @@ class GameDetailActivity : DownloadToolbarActivity() { override fun isAutoResetViewBackgroundEnabled(): Boolean = true override fun updateStaticViewBackground(view: View?) { - updateStaticView(view, listOf(R.id.menu_download_iv, R.id.gameBigEvent, R.id.backgroundIv)) + updateStaticView(view, listOf(R.id.menu_download_iv, R.id.gameBigEvent, R.id.cardContainer)) } companion object { diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt index 242f470faa..9d42b2c9b2 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt @@ -650,7 +650,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { initViewPage(data) - if (data.contentCard.size > 1) { + if (data.contentCard.size > 1 && data.mirrorStatus == "off") { initGameContentCard(data.contentCard) } @@ -1045,32 +1045,31 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { mBodyBinding.contentCardContainer.visibility = View.VISIBLE if (linkEntityList.size >= 3) { linkEntityList.safelyGetInRelease(0)?.let { - mBodyBinding.contentCardContainer.addView(getLargeContentCardView(it, true), LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 2F)) + mBodyBinding.contentCardContainer.addView(getLargeContentCardView(it, true), LinearLayout.LayoutParams(0, 56F.dip2px(), 2F)) } linkEntityList.safelyGetInRelease(1)?.let { - mBodyBinding.contentCardContainer.addView(getSmallContentCardView(it), LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1F)) + mBodyBinding.contentCardContainer.addView(getSmallContentCardView(it), LinearLayout.LayoutParams(0, 56F.dip2px(), 1F)) } linkEntityList.safelyGetInRelease(2)?.let { - mBodyBinding.contentCardContainer.addView(getSmallContentCardView(it, true), LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1F)) + mBodyBinding.contentCardContainer.addView(getSmallContentCardView(it, true), LinearLayout.LayoutParams(0, 56F.dip2px(), 1F)) } } else if (linkEntityList.size == 2) { linkEntityList.safelyGetInRelease(0)?.let { - mBodyBinding.contentCardContainer.addView(getLargeContentCardView(it), LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1F)) + mBodyBinding.contentCardContainer.addView(getLargeContentCardView(it), LinearLayout.LayoutParams(0, 56F.dip2px(), 1F)) } linkEntityList.safelyGetInRelease(1)?.let { - mBodyBinding.contentCardContainer.addView(getLargeContentCardView(it, isLastView = true), LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1F)) + mBodyBinding.contentCardContainer.addView(getLargeContentCardView(it, isLastView = true), LinearLayout.LayoutParams(0, 56F.dip2px(), 1F)) } } } private fun getLargeContentCardView(contentCardEntity: ContentCardEntity, isHighlightBg: Boolean = false, isLastView: Boolean = false) = LayoutGameDetailContentCardLargeBinding.inflate(layoutInflater).apply { when { - isHighlightBg && !isLastView -> backgroundIv.setImageDrawable(R.drawable.bg_content_card_large_primary.toDrawable(requireContext())) - !isHighlightBg && !isLastView -> backgroundIv.setImageDrawable(R.drawable.bg_content_card_large.toDrawable(requireContext())) - !isHighlightBg && isLastView -> backgroundIv.setImageDrawable(R.drawable.bg_content_card_large_right.toDrawable(requireContext())) + isHighlightBg && !isLastView -> root.background = R.drawable.bg_content_card_large_primary.toDrawable(requireContext()) + !isHighlightBg && !isLastView -> root.background = R.drawable.bg_content_card_large.toDrawable(requireContext()) + !isHighlightBg && isLastView -> root.background = R.drawable.bg_content_card_large_right.toDrawable(requireContext()) } - spaceStart.layoutParams = spaceStart.layoutParams.apply { width = if (isLastView) 20F.dip2px() else 12F.dip2px()} - spaceEnd.layoutParams = spaceEnd.layoutParams.apply { width = if (isLastView) 8F.dip2px() else 12F.dip2px()} + root.setPadding(if (isLastView) 20F.dip2px() else 12F.dip2px(), 0, if (isLastView) 8F.dip2px() else 12F.dip2px(), 0) titleTv.text = contentCardEntity.title ImageUtils.display(iconIv, contentCardEntity.icon) if (contentCardEntity.des.isNotEmpty()) { @@ -1098,7 +1097,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { }.root private fun getSmallContentCardView(contentCardEntity: ContentCardEntity, isLastView: Boolean = false) = LayoutGameDetailContentCardSmallBinding.inflate(layoutInflater).apply { - backgroundIv.setImageDrawable(if (isLastView) R.drawable.bg_content_card_small_right.toDrawable(requireContext()) else R.drawable.bg_content_card_small.toDrawable(requireContext())) + root.background = if (isLastView) R.drawable.bg_content_card_small_right.toDrawable(requireContext()) else R.drawable.bg_content_card_small.toDrawable(requireContext()) titleTv.text = contentCardEntity.title ImageUtils.display(iconIv, contentCardEntity.icon) redDotTv.goneIf(!(contentCardEntity.type == "func_server" || contentCardEntity.type == "func_libao")) @@ -1822,7 +1821,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { mBinding.detailLlBottom.detailLlBottom.setBackgroundColor(R.color.background.toColor(requireContext())) updateToolbarStyle(mBodyBinding.gamedetailThumbSmall.visibility == View.VISIBLE) mViewModel.gameDetailLiveData.value?.data?.let { - if (it.contentCard.size > 1) { + if (it.contentCard.size > 1 && it.mirrorStatus == "off") { initGameContentCard(it.contentCard) } } diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt index 7a7e4410c3..f8197f989f 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt @@ -115,6 +115,17 @@ class GameDetailViewModel(application: Application, } } + private fun removeLatestServerIfNeeded(data: NewGameDetailEntity) { + var i = 0 + while (i < data.detailEntity.size) { + if (data.detailEntity[i].type == DetailEntity.Type.LATEST_SERVER.value) { + data.detailEntity.removeAt(i) + return + } + i++ + } + } + @SuppressLint("CheckResult") fun getGameDetailNew() { mSensitiveApi.getGameDetailNew(game?.id) @@ -129,13 +140,10 @@ class GameDetailViewModel(application: Application, && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT data.contentCard.forEach { + // 显示开服内容卡片时,游戏详情-详情tab不显示“最新开服” if (data.contentCard.size > 1 && it.type == "func_server") { - data.detailEntity.forEach detail@{ detailEntity -> - if (detailEntity.type == DetailEntity.Type.LATEST_SERVER.value) { - data.detailEntity.remove(detailEntity) - return@detail - } - } + removeLatestServerIfNeeded(data) + return@forEach } } diff --git a/app/src/main/res/layout/layout_game_detail_content_card_large.xml b/app/src/main/res/layout/layout_game_detail_content_card_large.xml index f3b249d5b3..0a939628f9 100644 --- a/app/src/main/res/layout/layout_game_detail_content_card_large.xml +++ b/app/src/main/res/layout/layout_game_detail_content_card_large.xml @@ -2,33 +2,19 @@ - - - - + android:layout_height="56dp" + android:background="@drawable/bg_content_card_large_primary" + android:paddingStart="12dp" + android:paddingEnd="12dp"> @@ -73,8 +59,8 @@ android:ellipsize="end" android:lines="1" android:textSize="@dimen/tag_text_size" - app:layout_constraintEnd_toStartOf="@+id/spaceEnd" - app:layout_constraintStart_toEndOf="@+id/spaceStart" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/iconIv" tools:text="文案内容" /> @@ -84,16 +70,8 @@ android:layout_height="14dp" android:layout_marginTop="4dp" android:visibility="gone" - app:layout_constraintEnd_toStartOf="@+id/spaceEnd" - app:layout_constraintStart_toEndOf="@+id/spaceStart" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/iconIv" /> - - \ No newline at end of file diff --git a/app/src/main/res/layout/layout_game_detail_content_card_small.xml b/app/src/main/res/layout/layout_game_detail_content_card_small.xml index a878f69ec8..25c7e7b27b 100644 --- a/app/src/main/res/layout/layout_game_detail_content_card_small.xml +++ b/app/src/main/res/layout/layout_game_detail_content_card_small.xml @@ -1,27 +1,19 @@ - - + android:layout_height="56dp" + android:background="@drawable/bg_content_card_small"> From 99ffde9b6763355a4b59c30e7f5fd2f383f71185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Thu, 28 Jul 2022 14:31:35 +0800 Subject: [PATCH 138/217] =?UTF-8?q?fix:=20=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E9=A6=96=E9=A1=B5=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E5=88=97=E8=A1=A8=E4=BC=98=E5=8C=96(0728=E6=B5=8B?= =?UTF-8?q?=E8=AF=951)=20https://git.shanqu.cc/pm/halo/halo-app-issues/-/i?= =?UTF-8?q?ssues/1949?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index f797f95bf9..f8cf74fc42 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -433,6 +433,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { columnName = homeContent.linkText ) } + mSnapshotItemList.add(LegacyHomeSubjectTransformer.getBlankSpacingItem(HomeItemData()) as HomeItemData) mSnapshotItemList.add(homeItemData) } else { val unknown = HomeItemData() From 1ae905b0b438fae54d5a9c2b7d9fdb3b911e89a2 Mon Sep 17 00:00:00 2001 From: leafwai Date: Thu, 28 Jul 2022 15:11:45 +0800 Subject: [PATCH 139/217] =?UTF-8?q?fix:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=B8=B8=E6=88=8F=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E6=96=B0=E5=A2=9E=E2=80=9C=E5=86=85=E5=AE=B9=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E2=80=9D=E5=8A=9F=E8=83=BD(0727=E6=B5=8B=E8=AF=952?= =?UTF-8?q?=E3=80=818(3))=20https://git.shanqu.cc/pm/halo/halo-app-issues/?= =?UTF-8?q?-/issues/1953?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/gamecenter/gamedetail/entity/ContentCardEntity.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/entity/ContentCardEntity.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/entity/ContentCardEntity.kt index 21f1485e49..a2c0be817c 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/entity/ContentCardEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/entity/ContentCardEntity.kt @@ -1,8 +1,10 @@ package com.gh.gamecenter.gamedetail.entity +import androidx.annotation.Keep import com.gh.gamecenter.entity.* import com.google.gson.annotations.SerializedName +@Keep data class ContentCardEntity( @SerializedName("_id") var id: String = "", From c58db04155d482c37cebf9df2b074cb860f637e7 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Thu, 28 Jul 2022 17:42:04 +0800 Subject: [PATCH 140/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=9C=A8?= =?UTF-8?q?=E9=82=A3=E6=97=A0=E4=B8=8B=E8=BD=BD=E7=9A=84=E6=B8=B8=E6=88=8F?= =?UTF-8?q?=E6=89=93=E5=BC=80=E8=AF=A6=E6=83=85=E9=A1=B5=E9=97=AA=E9=80=80?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/common/util/DetailDownloadUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index a4af35009e..4790728cf9 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -62,7 +62,7 @@ public class DetailDownloadUtils { return; } - if (viewHolder.gameEntity.isVGame()) { + if (viewHolder.gameEntity.isVGame() && !viewHolder.gameEntity.getApk().isEmpty()) { String status = GameUtils.getDownloadBtnText(viewHolder.context, viewHolder.gameEntity, PluginLocation.only_game); if (viewHolder.context.getString(R.string.launch).equals(status)) { viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.LAUNCH_OR_OPEN); From 4ce17aa6a35d0d800de12234026a712a8136c1fa Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Fri, 29 Jul 2022 10:48:14 +0800 Subject: [PATCH 141/217] =?UTF-8?q?feat:=20=E7=A7=BB=E9=99=A4=20x86=20?= =?UTF-8?q?=E6=9E=B6=E6=9E=84=E6=94=AF=E6=8C=81=EF=BC=8C=E6=8D=95=E6=8A=93?= =?UTF-8?q?=20RenderScript=20=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 10 ++++---- .../detail/GameCollectionPosterFragment.kt | 18 +++++++------- .../background/BackgroundPreviewFragment.kt | 24 ++++++++++++------- 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 732c8e0c22..e5ff83ce5c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -47,12 +47,10 @@ android { multiDexEnabled true ndk { - // 如果不添加 `arm64` 调用系统的 PackageManager 的方法读取安装包信息的时候会出现 native 层闪退,草 - // 添加了 `arm64` 以后部分 5.0 的设备会报用错 so 的问题, - // couldn't find DSO to load: libimagepipeline.so caused by: dlopen failed: "/data/data/com.gh.gamecenter/lib-main/libimagepipeline.so" is 64-bit instead of 32-bit result: 0 - // 以 OPPO R7PLUS 为例,明明设备是骁龙 615,ARMv8-64 bit 的设备却不支持 arm64 的 abi,限制了只使用 java 后还是报错,只有 5.0,5.1 设备无法复现 : ( - // 惊了 - abiFilters "armeabi-v7a", "arm64-v8a", "x86" + // x86 本来是为了模拟器用户使用 RenderScript 用的,但是其实用到 RenderScript 的人本来就不多 (一天不到 100),用模拟器的人就更少了 + // 加了 x86 反而会导致用户没法使用微博登录,因为微博没有提供 x86 的 SO ... + // 还会增大 APK 体积,所以还是去掉吧。数据可见 https://sentry.shanqu.cc/organizations/lightgame/issues/144232/?project=22 + abiFilters "armeabi-v7a", "arm64-v8a" } renderscriptTargetApi 18 diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionPosterFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionPosterFragment.kt index 86f2f2cabc..e509b8afbc 100644 --- a/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionPosterFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamecollection/detail/GameCollectionPosterFragment.kt @@ -5,19 +5,17 @@ import android.os.Build import android.os.Bundle import android.view.View import androidx.annotation.RequiresApi -import com.gh.gamecenter.core.runOnUiThread -import com.gh.common.util.* +import com.gh.common.util.DirectUtils import com.gh.gamecenter.R +import com.gh.gamecenter.common.base.fragment.ToolbarFragment import com.gh.gamecenter.common.callback.BiCallback import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.* -import com.gh.gamecenter.common.utils.ImageUtils -import com.gh.gamecenter.common.utils.BitmapUtils +import com.gh.gamecenter.core.runOnUiThread import com.gh.gamecenter.databinding.FragmentGameCollectionPosterBinding import com.gh.gamecenter.databinding.LayoutGameCollectionTagBinding import com.gh.gamecenter.entity.GamesCollectionDetailEntity import com.gh.gamecenter.manager.UserManager -import com.gh.gamecenter.common.base.fragment.ToolbarFragment class GameCollectionPosterFragment : ToolbarFragment() { @@ -62,9 +60,13 @@ class GameCollectionPosterFragment : ToolbarFragment() { ImageUtils.getBitmap(cover, object : BiCallback { @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR1) override fun onFirst(first: Bitmap) { - val blurBitmap = BitmapUtils.getBlurBitmap(requireContext(), first, 16) - runOnUiThread { - posterBg.setImageBitmap(blurBitmap) + try { + val blurBitmap = BitmapUtils.getBlurBitmap(requireContext(), first, 16) + runOnUiThread { + posterBg.setImageBitmap(blurBitmap) + } + } catch (t: Throwable) { + posterBg.setImageBitmap(first) } } diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/background/BackgroundPreviewFragment.kt b/app/src/main/java/com/gh/gamecenter/personalhome/background/BackgroundPreviewFragment.kt index 1096c623ec..233804eadc 100644 --- a/app/src/main/java/com/gh/gamecenter/personalhome/background/BackgroundPreviewFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/personalhome/background/BackgroundPreviewFragment.kt @@ -11,10 +11,12 @@ import android.view.View import androidx.annotation.RequiresApi import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.content.ContextCompat -import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment -import com.gh.common.util.* +import com.gh.common.util.EnergyTaskHelper +import com.gh.common.util.GhMatisseFilter import com.gh.gamecenter.CropImageActivity import com.gh.gamecenter.R +import com.gh.gamecenter.common.base.fragment.ToolbarFragment +import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.* @@ -22,7 +24,6 @@ import com.gh.gamecenter.databinding.FragmentBackgroundPreviewBinding import com.gh.gamecenter.entity.BackgroundImageEntity import com.gh.gamecenter.entity.ErrorEntity import com.gh.gamecenter.manager.UserManager -import com.gh.gamecenter.common.base.fragment.ToolbarFragment import com.gh.gamecenter.user.UserViewModel import com.halo.assistant.HaloApp import com.zhihu.matisse.Matisse @@ -214,13 +215,18 @@ class BackgroundPreviewFragment : ToolbarFragment() { private fun changeAmbiguity() { if (mOriginBitmap == null) return val progress = mBinding.blurSeek.progress - mTempBitmap = if (progress == 0) { - Bitmap.createBitmap(mOriginBitmap!!) - } else { - BitmapUtils.getBlurBitmap(requireContext(), mOriginBitmap, progress) + + try { + mTempBitmap = if (progress == 0) { + Bitmap.createBitmap(mOriginBitmap!!) + } else { + BitmapUtils.getBlurBitmap(requireContext(), mOriginBitmap, progress) + } + mBinding.mineGhIv.setImageBitmap(mTempBitmap) + mBinding.personalHomeIv.setImageBitmap(mTempBitmap) + } catch (t: Throwable) { + ToastUtils.toast("您的设备暂不支持调整模糊度") } - mBinding.mineGhIv.setImageBitmap(mTempBitmap) - mBinding.personalHomeIv.setImageBitmap(mTempBitmap) } private fun changeCommitButton() { From 6c0f7f8cb36831c6c41741274f4ec6583c06954d Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Fri, 29 Jul 2022 11:17:13 +0800 Subject: [PATCH 142/217] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E7=94=A8=E8=B5=84=E6=BA=90=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../res/drawable-xxhdpi/forum_more_guide.webp | Bin 23150 -> 0 bytes .../forum_more_guide_rectangle.webp | Bin 4574 -> 0 bytes .../fragment_ask_recommends_wrapper.xml | 40 --- .../main/res/layout/fragment_forum_home.xml | 252 ------------------ 4 files changed, 292 deletions(-) delete mode 100644 app/src/main/res/drawable-xxhdpi/forum_more_guide.webp delete mode 100644 app/src/main/res/drawable-xxhdpi/forum_more_guide_rectangle.webp delete mode 100644 app/src/main/res/layout/fragment_ask_recommends_wrapper.xml delete mode 100644 app/src/main/res/layout/fragment_forum_home.xml diff --git a/app/src/main/res/drawable-xxhdpi/forum_more_guide.webp b/app/src/main/res/drawable-xxhdpi/forum_more_guide.webp deleted file mode 100644 index 4a99a299f08f7ebfc8785981245d0d5ceefcfa0b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23150 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 Cnig>Y diff --git a/app/src/main/res/drawable-xxhdpi/forum_more_guide_rectangle.webp b/app/src/main/res/drawable-xxhdpi/forum_more_guide_rectangle.webp deleted file mode 100644 index adb49da0004f96d0befb0020356150f99cafb8c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4574 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 IPZlwt0ECsi+W-In diff --git a/app/src/main/res/layout/fragment_ask_recommends_wrapper.xml b/app/src/main/res/layout/fragment_ask_recommends_wrapper.xml deleted file mode 100644 index 362f88c591..0000000000 --- a/app/src/main/res/layout/fragment_ask_recommends_wrapper.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_forum_home.xml b/app/src/main/res/layout/fragment_forum_home.xml deleted file mode 100644 index 9c53e3889d..0000000000 --- a/app/src/main/res/layout/fragment_forum_home.xml +++ /dev/null @@ -1,252 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From a14ea13dd726384c2c62d8017902673fef3c930b Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Fri, 29 Jul 2022 11:27:19 +0800 Subject: [PATCH 143/217] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E7=94=A8=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/halo/assistant/TinkerApp.java | 19 ------- .../com/halo/assistant/TinkerAppLike.java | 49 ----------------- .../common/view/DumbRefreshLayout.java | 26 ---------- .../gamecenter/common/view/EmptyDrawable.java | 52 ------------------- 4 files changed, 146 deletions(-) delete mode 100644 app/src/main/java/com/halo/assistant/TinkerApp.java delete mode 100644 app/src/main/java/com/halo/assistant/TinkerAppLike.java delete mode 100644 module_common/src/main/java/com/gh/gamecenter/common/view/DumbRefreshLayout.java delete mode 100644 module_common/src/main/java/com/gh/gamecenter/common/view/EmptyDrawable.java diff --git a/app/src/main/java/com/halo/assistant/TinkerApp.java b/app/src/main/java/com/halo/assistant/TinkerApp.java deleted file mode 100644 index 6fd7c23640..0000000000 --- a/app/src/main/java/com/halo/assistant/TinkerApp.java +++ /dev/null @@ -1,19 +0,0 @@ -//package com.halo.assistant; -// -//import com.tencent.tinker.loader.app.TinkerApplication; -//import com.tencent.tinker.loader.shareutil.ShareConstants; -// -///** -// * 这个类不要加任何应用逻辑,有意义的东西都放在{@link HaloApp} -// * -// * @author CsHeng -// * @Date 13/09/2017 -// * @Time 6:12 PM -// */ -//public class TinkerApp extends TinkerApplication { -// -// public TinkerApp() { -// super(ShareConstants.TINKER_ENABLE_ALL, "com.halo.assistant.HaloApp", "com.tencent.tinker.loader.TinkerLoader", false); -// } -// -//} diff --git a/app/src/main/java/com/halo/assistant/TinkerAppLike.java b/app/src/main/java/com/halo/assistant/TinkerAppLike.java deleted file mode 100644 index 921b052a31..0000000000 --- a/app/src/main/java/com/halo/assistant/TinkerAppLike.java +++ /dev/null @@ -1,49 +0,0 @@ -//package com.halo.assistant; -// -//import android.annotation.TargetApi; -//import android.app.Application; -//import android.content.Context; -//import android.content.Intent; -//import android.os.Build; -// -//import androidx.multidex.MultiDex; -// -//import com.tencent.tinker.loader.app.DefaultApplicationLike; -// -//public class TinkerAppLike extends DefaultApplicationLike { -// -// public TinkerAppLike(Application application, int tinkerFlags, -// boolean tinkerLoadVerifyFlag, long applicationStartElapsedTime, -// long applicationStartMillisTime, Intent tinkerResultIntent) { -// super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent); -// } -// -// @Override -// public void onCreate() { -// super.onCreate(); -// -//// if (HaloApp.isUserAcceptPrivacyPolicy(getApplication())) { -//// Bugly.init(getApplication(), Config.BUGLY_APPID, BuildConfig.DEBUG); -//// } -// } -// -// -// @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) -// @Override -// public void onBaseContextAttached(Context base) { -// super.onBaseContextAttached(base); -// // you must install multiDex whatever tinker is installed! -// MultiDex.install(base); -// -// // 安装tinker -//// if (HaloApp.isUserAcceptPrivacyPolicy(base)) { -//// Beta.installTinker(this); -//// } -// } -// -// @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) -// public void registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callbacks) { -// getApplication().registerActivityLifecycleCallbacks(callbacks); -// } -// -//} \ No newline at end of file diff --git a/module_common/src/main/java/com/gh/gamecenter/common/view/DumbRefreshLayout.java b/module_common/src/main/java/com/gh/gamecenter/common/view/DumbRefreshLayout.java deleted file mode 100644 index 00a5cca5b5..0000000000 --- a/module_common/src/main/java/com/gh/gamecenter/common/view/DumbRefreshLayout.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.gh.gamecenter.common.view; - -import android.content.Context; -import android.util.AttributeSet; - -import com.scwang.smartrefresh.layout.SmartRefreshLayout; -import com.scwang.smartrefresh.layout.constant.RefreshState; - -public class DumbRefreshLayout extends SmartRefreshLayout { - - public DumbRefreshLayout(Context context) { - super(context); - } - - public DumbRefreshLayout(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public DumbRefreshLayout(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - public boolean isRefreshing() { - return mState != RefreshState.None; - } -} diff --git a/module_common/src/main/java/com/gh/gamecenter/common/view/EmptyDrawable.java b/module_common/src/main/java/com/gh/gamecenter/common/view/EmptyDrawable.java deleted file mode 100644 index f5d690acae..0000000000 --- a/module_common/src/main/java/com/gh/gamecenter/common/view/EmptyDrawable.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.gh.gamecenter.common.view; - -import android.annotation.SuppressLint; -import android.graphics.Canvas; -import android.graphics.ColorFilter; -import android.graphics.drawable.Drawable; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -/** - * 一个空的类 主要是用来回调 onLevelChange(加载进度)的内容 - */ - -public class EmptyDrawable extends Drawable { - private OnLoadingListener mLoadingListener; - - public EmptyDrawable(OnLoadingListener listener) { - this.mLoadingListener = listener; - } - - @Override - public void draw(@NonNull Canvas canvas) { - - } - - @Override - public void setAlpha(int alpha) { - - } - - @Override - public void setColorFilter(@Nullable ColorFilter colorFilter) { - - } - - @SuppressLint("WrongConstant") - @Override - public int getOpacity() { - return 0; - } - - //Default Max:10000 - @Override - protected boolean onLevelChange(int level) { - if (mLoadingListener != null) mLoadingListener.onProgress(level); - return false; - } - - public interface OnLoadingListener { - void onProgress(int progress); - } -} From 493a44499042d88d4bf04563dd22d135c99ccae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E5=AD=90=E7=BB=B4?= Date: Fri, 29 Jul 2022 15:51:49 +0800 Subject: [PATCH 144/217] =?UTF-8?q?fix:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=B8=B8=E6=88=8F=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E6=96=B0=E5=A2=9E=E2=80=9C=E5=86=85=E5=AE=B9=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E2=80=9D=E5=8A=9F=E8=83=BD(0729=E6=B5=8B=E8=AF=951-2)?= =?UTF-8?q?=20https://git.shanqu.cc/pm/halo/halo-app-issues/-/issues/1953?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GameDetailContentCardContentAdapter.kt | 8 ++--- .../gamedetail/GameDetailFragment.kt | 31 ++++++++++++------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailContentCardContentAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailContentCardContentAdapter.kt index 70a10a569e..c885d8d2de 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailContentCardContentAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailContentCardContentAdapter.kt @@ -20,7 +20,7 @@ class GameDetailContentCardContentAdapter(context: Context, private val linkEnti if (holder is GameDetailContentCardContentItemViewHolder) { holder.binding.root.setTextColor(if (isHighlightBg) R.color.text_subtitle.toColor(mContext) else R.color.text_subtitleDesc.toColor(mContext)) if (linkEntity.type == "func_server" && linkEntity.server != null && linkEntity.server?.calendar?.isNotEmpty() == true) { - val calendarList = linkEntity.server!!.calendar.take(10) + val calendarList = linkEntity.server!!.calendar val realPosition = position % calendarList.size calendarList.safelyGetInRelease(realPosition)?.let { val serverTime = @@ -30,13 +30,9 @@ class GameDetailContentCardContentAdapter(context: Context, private val linkEnti it.getFormatTime("明天 HH:mm") else it.getFormatTime("MM-dd HH:mm") - val serverText = "$serverTime ${it.remark}" - holder.binding.root.text = serverText + holder.binding.root.text = "$serverTime ${it.type}" } } - if (linkEntity.type == "func_libao" && linkEntity.libao != null) { - holder.binding.root.text = "${linkEntity.libao!!.total}个游戏礼包" - } } } diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt index 3e24e6e2de..962c8f63cd 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt @@ -125,7 +125,6 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { private var mRecommendPopupEntity: RecommendPopupEntity? = null private var mTabClickEvent: Pair = Pair(0L, "") private var mContentCardServerVp: ViewPager2? = null - private var mContentCardLibaoVp: ViewPager2? = null private lateinit var mBinding: FragmentGamedetailBinding private lateinit var mVideoBinding: PieceGameDetailVideoBinding @@ -141,7 +140,6 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { private val mTabTitleList = ArrayList() private val mLooperHandle = LooperHandle(this) private val mServerLooperKey = 123 - private val mLibaoLooperKey = 124 private val dataWatcher = object : DataWatcher() { override fun onDataChanged(downloadEntity: DownloadEntity) { @@ -1073,24 +1071,37 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { root.setPadding(if (isLastView) 20F.dip2px() else 12F.dip2px(), 0, if (isLastView) 8F.dip2px() else 12F.dip2px(), 0) titleTv.text = contentCardEntity.title ImageUtils.display(iconIv, contentCardEntity.icon) - if (contentCardEntity.des.isNotEmpty()) { + if (contentCardEntity.des.isNotEmpty() || contentCardEntity.type == "func_libao") { contentTv.visibility = View.VISIBLE contentVp.visibility = View.GONE - contentTv.text = contentCardEntity.des + contentTv.text = if (contentCardEntity.type == "func_libao" && contentCardEntity.des.isEmpty()) "${contentCardEntity.libao?.total}个游戏礼包" else contentCardEntity.des contentTv.setTextColor(if (isHighlightBg) R.color.text_subtitle.toColor(requireContext()) else R.color.text_subtitleDesc.toColor(requireContext())) - } else if (contentCardEntity.type == "func_server" || contentCardEntity.type == "func_libao") { + } else if (contentCardEntity.type == "func_server") { contentTv.visibility = View.GONE contentVp.visibility = View.VISIBLE - if (contentCardEntity.type == "func_server") mContentCardServerVp = contentVp else mContentCardLibaoVp = contentVp + if (contentCardEntity.type == "func_server") mContentCardServerVp = contentVp contentVp.run { isUserInputEnabled = false orientation = ViewPager2.ORIENTATION_VERTICAL adapter = GameDetailContentCardContentAdapter(requireContext(), contentCardEntity, isHighlightBg) - startAutoPlay(if (contentCardEntity.type == "func_server") mServerLooperKey else mLibaoLooperKey) + if (contentCardEntity.type == "func_server") { + val nowTime = System.currentTimeMillis() + var timeDiff = 0L + var closestIndex = 0 + contentCardEntity.server!!.calendar.forEachIndexed { index, serverCalendarEntity -> + val diff = abs(nowTime - serverCalendarEntity.getTime() * 1000L) + if (diff < timeDiff || index == 0) { + timeDiff = diff + closestIndex = index + } + } + currentItem = closestIndex + startAutoPlay(mServerLooperKey) + } } } redDotTv.goneIf(!(contentCardEntity.type == "func_server" || contentCardEntity.type == "func_libao")) - if ((contentCardEntity.type == "func_server") && (contentCardEntity.server?.calendar?.isNotEmpty() == true)) redDotTv.text = contentCardEntity.server?.calendar?.size.toString() + if ((contentCardEntity.type == "func_server") && (contentCardEntity.server?.calendar?.isNotEmpty() == true)) redDotTv.text = contentCardEntity.server?.total.toString() if ((contentCardEntity.type == "func_libao") && (contentCardEntity.libao != null)) redDotTv.text = contentCardEntity.libao?.total.toString() root.setOnClickListener { contentCardClick.invoke(contentCardEntity) @@ -1102,7 +1113,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { titleTv.text = contentCardEntity.title ImageUtils.display(iconIv, contentCardEntity.icon) redDotTv.goneIf(!(contentCardEntity.type == "func_server" || contentCardEntity.type == "func_libao")) - if ((contentCardEntity.type == "func_server") && (contentCardEntity.server?.calendar?.isNotEmpty() == true)) redDotTv.text = contentCardEntity.server?.calendar?.size.toString() + if ((contentCardEntity.type == "func_server") && (contentCardEntity.server?.calendar?.isNotEmpty() == true)) redDotTv.text = contentCardEntity.server?.total.toString() if ((contentCardEntity.type == "func_libao") && (contentCardEntity.libao != null)) redDotTv.text = contentCardEntity.libao?.total.toString() root.setOnClickListener { contentCardClick.invoke(contentCardEntity) @@ -1866,8 +1877,6 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { if (fragment != null) { if (msg.what == fragment.mServerLooperKey) { fragment.scrollToNextContent(fragment.mContentCardServerVp) - } else if (msg.what == fragment.mLibaoLooperKey) { - fragment.scrollToNextContent(fragment.mContentCardLibaoVp) } fragment.startAutoPlay(msg.what) } From faa9d5042696f5a055a19d221a673809a4118470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E5=AD=90=E7=BB=B4?= Date: Mon, 1 Aug 2022 10:20:45 +0800 Subject: [PATCH 145/217] =?UTF-8?q?fix:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=B8=B8=E6=88=8F=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E6=96=B0=E5=A2=9E=E2=80=9C=E5=86=85=E5=AE=B9=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E2=80=9D=E5=8A=9F=E8=83=BD(0729=E6=B5=8B=E8=AF=951)?= =?UTF-8?q?=20https://git.shanqu.cc/pm/halo/halo-app-issues/-/issues/1953?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/gamecenter/gamedetail/GameDetailFragment.kt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt index 962c8f63cd..065484afe2 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt @@ -229,7 +229,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { } } "func_libao" -> { - tabPerformClick(0) + mBodyBinding.gamedetailVp.currentItem = 0 mBodyBinding.gamedetailAppbar.setExpanded(false, true) val fragment = mFragmentsList[0] if (fragment is DescFragment && fragment.isAdded) { @@ -237,7 +237,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { } } "func_related_version" -> { - tabPerformClick(0) + mBodyBinding.gamedetailVp.currentItem = 0 mBodyBinding.gamedetailAppbar.setExpanded(false, true) val fragment = mFragmentsList[0] if (fragment is DescFragment && fragment.isAdded) { @@ -1096,11 +1096,13 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { } } currentItem = closestIndex - startAutoPlay(mServerLooperKey) + if (contentCardEntity.server!!.calendar.size > 1) { + startAutoPlay(mServerLooperKey) + } } } } - redDotTv.goneIf(!(contentCardEntity.type == "func_server" || contentCardEntity.type == "func_libao")) + redDotTv.goneIf(!((contentCardEntity.type == "func_server" && contentCardEntity.server?.total != 0) || contentCardEntity.type == "func_libao")) if ((contentCardEntity.type == "func_server") && (contentCardEntity.server?.calendar?.isNotEmpty() == true)) redDotTv.text = contentCardEntity.server?.total.toString() if ((contentCardEntity.type == "func_libao") && (contentCardEntity.libao != null)) redDotTv.text = contentCardEntity.libao?.total.toString() root.setOnClickListener { @@ -1112,7 +1114,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { root.background = if (isLastView) R.drawable.bg_content_card_small_right.toDrawable(requireContext()) else R.drawable.bg_content_card_small.toDrawable(requireContext()) titleTv.text = contentCardEntity.title ImageUtils.display(iconIv, contentCardEntity.icon) - redDotTv.goneIf(!(contentCardEntity.type == "func_server" || contentCardEntity.type == "func_libao")) + redDotTv.goneIf(!((contentCardEntity.type == "func_server" && contentCardEntity.server?.total != 0) || contentCardEntity.type == "func_libao")) if ((contentCardEntity.type == "func_server") && (contentCardEntity.server?.calendar?.isNotEmpty() == true)) redDotTv.text = contentCardEntity.server?.total.toString() if ((contentCardEntity.type == "func_libao") && (contentCardEntity.libao != null)) redDotTv.text = contentCardEntity.libao?.total.toString() root.setOnClickListener { From 08a7491fa7e4ed9f652bcd4ad465ee5ced0512d5 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Mon, 1 Aug 2022 11:17:28 +0800 Subject: [PATCH 146/217] =?UTF-8?q?feat:=20=E4=BF=AE=E5=A4=8D=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E6=B8=B8=E6=88=8F=E5=92=8C=E6=99=AE=E9=80=9A=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E5=90=8C=E4=B8=80=E4=B8=8B=E8=BD=BD=E5=9C=B0=E5=9D=80?= =?UTF-8?q?=E5=9B=9E=E5=BC=95=E8=B5=B7=E9=94=99=E8=AF=AF=E5=9B=9E=E8=B0=83?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/gamecenter/entity/GameEntity.kt | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt index e0f4acd91c..a09ba4e339 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt @@ -16,6 +16,7 @@ import com.lightgame.download.DownloadEntity import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.Parcelize import java.util.* +import kotlin.collections.ArrayList @Parcelize data class GameEntity( @@ -479,12 +480,30 @@ data class GameEntity( fun getApk(): ArrayList { if (shouldUseMirrorInfo()) return mirrorData?.getApk() ?: arrayListOf() - if (apk == null) apk = ArrayList() - if (!Config.isShowPlugin(id)) return getApkNormal() - if (gameLocation == GameLocation.INDEX && apkIndex != null) return apkIndex!! - if (gameLocation == GameLocation.SEARCH && apkSearch != null) return apkSearch!! + var rawApk = apk ?: ArrayList() - return apk!! + if (!Config.isShowPlugin(id)) { + rawApk = getApkNormal() + } else if (gameLocation == GameLocation.INDEX && apkIndex != null) { + rawApk = apkIndex!! + } else if (gameLocation == GameLocation.SEARCH && apkSearch != null) { + rawApk = apkSearch!! + } + + if (isVGame()) { + rawApk.forEach { + it.setPlatform("畅玩版") + if (it.url?.endsWith("type=v") == false) { + if (it.url?.contains("?") == true) { + it.url = it.url + "&type=v" + } else { + it.url = it.url + "?type=v" + } + } + } + } + + return rawApk } /** From 06f008d577d9c2761c27378abe186302f2737190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E5=AD=90=E7=BB=B4?= Date: Mon, 1 Aug 2022 11:49:39 +0800 Subject: [PATCH 147/217] =?UTF-8?q?fix:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=B8=B8=E6=88=8F=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E6=96=B0=E5=A2=9E=E2=80=9C=E5=86=85=E5=AE=B9=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E2=80=9D=E5=8A=9F=E8=83=BD(0727=E6=B5=8B=E8=AF=954)?= =?UTF-8?q?=20https://git.shanqu.cc/pm/halo/halo-app-issues/-/issues/1953?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt index 065484afe2..0841f2bb6b 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt @@ -649,7 +649,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { initViewPage(data) - if (data.contentCard.size > 1 && data.mirrorStatus == "off") { + if (data.contentCard.size > 1 && mGameEntity?.shouldUseMirrorInfo() == false) { initGameContentCard(data.contentCard) } @@ -1835,7 +1835,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { mBinding.detailLlBottom.detailLlBottom.setBackgroundColor(R.color.background.toColor(requireContext())) updateToolbarStyle(mBodyBinding.gamedetailThumbSmall.visibility == View.VISIBLE) mViewModel.gameDetailLiveData.value?.data?.let { - if (it.contentCard.size > 1 && it.mirrorStatus == "off") { + if (it.contentCard.size > 1 && mGameEntity?.shouldUseMirrorInfo() == false) { initGameContentCard(it.contentCard) } } From a0286391387da87ca416119277f3805c977607e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E5=AD=90=E7=BB=B4?= Date: Mon, 1 Aug 2022 14:58:07 +0800 Subject: [PATCH 148/217] =?UTF-8?q?fix:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=B8=B8=E6=88=8F=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E6=96=B0=E5=A2=9E=E2=80=9C=E5=86=85=E5=AE=B9=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E2=80=9D=E5=8A=9F=E8=83=BD(UI=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E6=B1=87=E6=80=BB1)=20https://git.shanqu.cc/?= =?UTF-8?q?pm/halo/halo-app-issues/-/issues/1953?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt index 0841f2bb6b..852e9af6ec 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt @@ -1040,6 +1040,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { } private fun initGameContentCard(linkEntityList: List) { + mBodyBinding.toolbarGapView.visibility = View.GONE mBodyBinding.contentCardContainer.removeAllViews() mBodyBinding.contentCardContainer.visibility = View.VISIBLE if (linkEntityList.size >= 3) { From 449836cbd0960b3128a17040b92f83c572b4aac7 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Mon, 1 Aug 2022 15:08:56 +0800 Subject: [PATCH 149/217] =?UTF-8?q?fix:=20=E5=A4=84=E7=90=86=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gamedetail/entity/NewGameDetailEntity.kt | 2 +- .../com/gh/gamecenter/home/HomeViewModel.kt | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/entity/NewGameDetailEntity.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/entity/NewGameDetailEntity.kt index 49cec86984..8cdd272a4f 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/entity/NewGameDetailEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/entity/NewGameDetailEntity.kt @@ -47,7 +47,7 @@ data class NewGameDetailEntity( @SerializedName("certification_tag") var certificateTag: Screenshot? = null, @SerializedName("content_card") - var contentCard: ArrayList = ArrayList() + var contentCard: ArrayList = ArrayList(), @SerializedName("smooth_relation_game") var smoothRelatedGame: SimpleGame? = null, diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index b4558378ce..5794055b0a 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -15,8 +15,10 @@ import com.gh.common.util.HomePluggableHelper import com.gh.download.DownloadManager import com.gh.gamecenter.BuildConfig import com.gh.gamecenter.baselist.LoadStatus +import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.retrofit.BiResponse import com.gh.gamecenter.common.retrofit.Response +import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.core.utils.RandomUtils import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.entity.* @@ -24,8 +26,11 @@ import com.gh.gamecenter.game.rank.RankCollectionAdapter import com.gh.gamecenter.gamecollection.square.GameCollectionListItemData import com.gh.gamecenter.packagehelper.PackageRepository import com.gh.gamecenter.retrofit.RetrofitManager +import com.gh.vspace.VGameItemData +import com.gh.vspace.VHelper import com.halo.assistant.HaloApp import com.halo.assistant.fragment.SettingsFragment +import com.lightgame.download.DownloadEntity import com.lightgame.utils.Utils import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers @@ -360,15 +365,15 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { } } - // 双列卡片专题过滤掉无封面图游戏 - if (item.linkType == "column" && item.linkColumn?.type == "game_double_card") { - item.linkColumn.data = item.linkColumn.data?.filter { it.columnImage.isNotBlank() }?.toMutableList() - // 游戏数量小于2个不显示专题,所以直接去掉 - if ((item.linkColumn.data?.size ?: 0) < 2) { - iterator.remove() + // 双列卡片专题过滤掉无封面图游戏 + if (item.linkType == "column" && item.linkColumn?.type == "game_double_card") { + item.linkColumn.data = item.linkColumn.data?.filter { it.columnImage.isNotBlank() }?.toMutableList() + // 游戏数量小于2个不显示专题,所以直接去掉 + if ((item.linkColumn.data?.size ?: 0) < 2) { + iterator.remove() + } } } - } if (mSmartSubject != null && mHomeContents.size > mSmartSubject!!.sort) { val element = HomeContent( From cb4b83ddb41f14f818f279651369f99de2fa9379 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Mon, 1 Aug 2022 15:10:17 +0800 Subject: [PATCH 150/217] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=20LGLibrary?= =?UTF-8?q?=20=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libraries/LGLibrary | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/LGLibrary b/libraries/LGLibrary index 8306e2fe0a..fbc7818022 160000 --- a/libraries/LGLibrary +++ b/libraries/LGLibrary @@ -1 +1 @@ -Subproject commit 8306e2fe0a0f10c3e7464d63971a8e7874ab4cdf +Subproject commit fbc7818022c42b7823b54ece34d6c9a094d9896f From 13ab6f7b38c7f7d1fa7fb1b144f69fe7c431fa8c Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Mon, 1 Aug 2022 17:45:29 +0800 Subject: [PATCH 151/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E6=B8=B8=E6=88=8F=E4=B8=8B=E8=BD=BD=E8=BF=9B=E5=BA=A6?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E5=90=8C=E6=AD=A5=E9=97=AE=E9=A2=98(20220729?= =?UTF-8?q?=E9=9C=80=E6=B1=82=E8=A1=A5=E5=85=85=EF=BC=9A=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E5=8F=8D=E9=A6=88)=20https://git.shanqu.cc/pm/halo/halo-app-is?= =?UTF-8?q?sues/-/issues/1955?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/util/DetailDownloadUtils.java | 4 ++-- .../java/com/gh/common/util/PlatformUtils.java | 5 +++++ .../main/java/com/gh/download/PackageObserver.kt | 2 ++ .../java/com/gh/gamecenter/entity/GameEntity.kt | 9 ++------- .../com/gh/gamecenter/manager/PackagesManager.kt | 6 +++--- app/src/main/java/com/gh/vspace/VHelper.kt | 14 +++++++++++++- 6 files changed, 27 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index f2f3fa55a7..2772bd1e9d 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -86,7 +86,7 @@ public class DetailDownloadUtils { DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(viewHolder.gameEntity); // 在下载管理找不到下载实体,到畅玩数据库里找 - if (downloadEntity == null) { + if (downloadEntity == null && viewHolder.gameEntity.isVGame()) { String packageName = viewHolder.gameEntity.getUniquePackageName(); if (!TextUtils.isEmpty(packageName)) { downloadEntity = VHelper.getDownloadEntitySnapshotByPackageName(packageName); @@ -160,7 +160,7 @@ public class DetailDownloadUtils { DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(viewHolder.gameEntity); // 在下载管理找不到下载实体,到畅玩数据库里找 - if (downloadEntity == null) { + if (downloadEntity == null && viewHolder.gameEntity.isVGame()) { String packageName = viewHolder.gameEntity.getUniquePackageName(); if (!TextUtils.isEmpty(packageName)) { downloadEntity = VHelper.getDownloadEntitySnapshotByPackageName(packageName); diff --git a/app/src/main/java/com/gh/common/util/PlatformUtils.java b/app/src/main/java/com/gh/common/util/PlatformUtils.java index 1d5ccc7f4b..a32c2cc62b 100644 --- a/app/src/main/java/com/gh/common/util/PlatformUtils.java +++ b/app/src/main/java/com/gh/common/util/PlatformUtils.java @@ -186,6 +186,11 @@ public class PlatformUtils { if ("".equals(platform) || "官方版".equals(platform)) { return "官方版"; } + + if ("畅玩版".equals(platform)) { + return "畅玩版"; + } + String platformName = platformMap.get(platform); if (TextUtils.isEmpty(platformName)) { getPlatform(); diff --git a/app/src/main/java/com/gh/download/PackageObserver.kt b/app/src/main/java/com/gh/download/PackageObserver.kt index 2c3cd125dc..39472e8b06 100644 --- a/app/src/main/java/com/gh/download/PackageObserver.kt +++ b/app/src/main/java/com/gh/download/PackageObserver.kt @@ -132,6 +132,8 @@ object PackageObserver { if ("卸载" == busFour.type) { mPackageViewModel.addUninstalledGame(packageName) mDownloadEntity?.let { + if (it.isVGame()) return@let + if (it.isPluggable || it.isUpdate) { PackageInstaller.install(application, mDownloadEntity) } diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt index c738e8d7ee..74e2caa7a5 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt @@ -10,6 +10,7 @@ import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.game.data.GameSubjectData import com.gh.gamecenter.gamedetail.entity.GameInfo import com.gh.gamecenter.gamedetail.entity.ZoneEntity +import com.gh.vspace.VHelper import com.google.gson.annotations.SerializedName import com.halo.assistant.HaloApp import com.lightgame.download.DownloadEntity @@ -497,13 +498,7 @@ data class GameEntity( if (isVGame()) { rawApk.forEach { it.setPlatform("畅玩版") - if (it.url?.endsWith("type=v") == false) { - if (it.url?.contains("?") == true) { - it.url = it.url + "&type=v" - } else { - it.url = it.url + "?type=v" - } - } + it.url = VHelper.getVUrl(it.url) } } diff --git a/app/src/main/java/com/gh/gamecenter/manager/PackagesManager.kt b/app/src/main/java/com/gh/gamecenter/manager/PackagesManager.kt index ede57e2cb8..95bc5e6402 100644 --- a/app/src/main/java/com/gh/gamecenter/manager/PackagesManager.kt +++ b/app/src/main/java/com/gh/gamecenter/manager/PackagesManager.kt @@ -2,11 +2,11 @@ package com.gh.gamecenter.manager import android.text.TextUtils import com.gh.common.constant.Config +import com.gh.common.util.PackageUtils import com.gh.gamecenter.entity.GameInstall import com.gh.gamecenter.entity.GameUpdateEntity +import com.halo.assistant.HaloApp import java.util.* -import kotlin.collections.ArrayList -import kotlin.collections.HashMap /** * todo 整理部分与[PackageUtils]冲突的方法 @@ -109,7 +109,7 @@ object PackagesManager { // TODO 检查为什么 4.3.0 以后 arrayList.contains 也会触发 outOfBounds 异常,而以前不会,因为 kotlin 版本更新? // 先简单改成 SynchronizedList - return installedPkgList.contains(packageName) + return installedPkgList.contains(packageName) && PackageUtils.isInstalled(HaloApp.getInstance(), packageName) } /** diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 054702b9cd..9472a053cd 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -674,7 +674,8 @@ object VHelper { Utils.log(LOG_TAG, "更新应用${originDownloadEntity.packageName}") if (updateEntity != null) { - originDownloadEntity.url = updateEntity.url + originDownloadEntity.url = getVUrl(updateEntity.url) + originDownloadEntity.gameId = updateEntity.id originDownloadEntity.name = updateEntity.name originDownloadEntity.eTag = updateEntity.etag originDownloadEntity.icon = updateEntity.icon @@ -810,4 +811,15 @@ object VHelper { connectService() } + fun getVUrl(originUrl: String?): String { + if (originUrl?.endsWith("type=v") == false) { + if (originUrl?.contains("?") == true) { + return "$originUrl&type=v" + } else { + return "$originUrl?type=v" + } + } + return originUrl ?: "" + } + } \ No newline at end of file From c3eba42b17e5a1cb3cb67ed3e9c8edc168828d24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E5=AD=90=E7=BB=B4?= Date: Tue, 2 Aug 2022 10:29:25 +0800 Subject: [PATCH 152/217] =?UTF-8?q?fix:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=B8=B8=E6=88=8F=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E6=96=B0=E5=A2=9E=E2=80=9C=E5=86=85=E5=AE=B9=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E2=80=9D=E5=8A=9F=E8=83=BD(UI=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E6=B1=87=E6=80=BB0802=E8=A1=A5=E5=85=852)=20?= =?UTF-8?q?https://git.shanqu.cc/pm/halo/halo-app-issues/-/issues/1953?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt | 1 + .../main/res/layout/layout_game_detail_content_card_small.xml | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt index 15147feaf5..071342468b 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt @@ -1123,6 +1123,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { titleTv.text = contentCardEntity.title ImageUtils.display(iconIv, contentCardEntity.icon) redDotTv.goneIf(!((contentCardEntity.type == "func_server" && contentCardEntity.server?.total != 0) || contentCardEntity.type == "func_libao")) + redDotTv.layoutParams = (redDotTv.layoutParams as ViewGroup.MarginLayoutParams).apply { setMargins(0, 8F.dip2px(), if (isLastView) 8F.dip2px() else 12F.dip2px(), 0) } if ((contentCardEntity.type == "func_server") && (contentCardEntity.server?.calendar?.isNotEmpty() == true)) redDotTv.text = contentCardEntity.server?.total.toString() if ((contentCardEntity.type == "func_libao") && (contentCardEntity.libao != null)) redDotTv.text = contentCardEntity.libao?.total.toString() root.setOnClickListener { diff --git a/app/src/main/res/layout/layout_game_detail_content_card_small.xml b/app/src/main/res/layout/layout_game_detail_content_card_small.xml index 25c7e7b27b..6f6e5cc99a 100644 --- a/app/src/main/res/layout/layout_game_detail_content_card_small.xml +++ b/app/src/main/res/layout/layout_game_detail_content_card_small.xml @@ -36,8 +36,6 @@ android:layout_width="wrap_content" android:layout_height="12dp" android:layout_marginTop="8dp" - android:layout_marginEnd="10dp" - android:layout_marginRight="10dp" android:background="@drawable/bg_hint_red_radius_999" android:minWidth="12dp" android:paddingStart="4dp" From 3e74b39b45f5af83dc5813407bf01e193fc8cd46 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Tue, 2 Aug 2022 11:13:11 +0800 Subject: [PATCH 153/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E6=B8=B8=E6=88=8F=E5=AE=89=E8=A3=85=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E5=90=8E=E4=BC=9A=E5=8F=96=E6=B6=88=E7=9B=B8=E5=90=8C=E5=8C=85?= =?UTF-8?q?=E5=90=8D=E6=B8=B8=E6=88=8F=E4=B8=8B=E8=BD=BD=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98(20220729=E9=9C=80=E6=B1=82=E8=A1=A5?= =?UTF-8?q?=E5=85=85=EF=BC=9A=E6=B5=8B=E8=AF=95=E5=8F=8D=E9=A6=88)=20https?= =?UTF-8?q?://git.shanqu.cc/pm/halo/halo-app-issues/-/issues/1955?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/common/util/DetailDownloadUtils.java | 4 +- .../com/gh/common/util/DownloadItemUtils.kt | 2 +- .../java/com/gh/common/util/GameUtils.java | 2 +- .../java/com/gh/common/util/PackageUtils.java | 2 +- .../java/com/gh/download/PackageObserver.kt | 18 ++++--- .../com/gh/gamecenter/eventbus/EBPackage.java | 38 --------------- .../com/gh/gamecenter/eventbus/EBPackage.kt | 6 +++ .../receiver/InstallAndUninstallReceiver.java | 1 - .../com/gh/vspace/VDownloadManagerAdapter.kt | 4 +- .../gh/vspace/VDownloadManagerViewModel.kt | 2 +- app/src/main/java/com/gh/vspace/VHelper.kt | 47 ++++++++++--------- 11 files changed, 50 insertions(+), 76 deletions(-) delete mode 100644 app/src/main/java/com/gh/gamecenter/eventbus/EBPackage.java create mode 100644 app/src/main/java/com/gh/gamecenter/eventbus/EBPackage.kt diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index 2772bd1e9d..ee2af4122e 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -89,7 +89,7 @@ public class DetailDownloadUtils { if (downloadEntity == null && viewHolder.gameEntity.isVGame()) { String packageName = viewHolder.gameEntity.getUniquePackageName(); if (!TextUtils.isEmpty(packageName)) { - downloadEntity = VHelper.getDownloadEntitySnapshotByPackageName(packageName); + downloadEntity = VHelper.getDownloadEntitySnapshot(viewHolder.gameEntity.getId(), packageName); } } @@ -163,7 +163,7 @@ public class DetailDownloadUtils { if (downloadEntity == null && viewHolder.gameEntity.isVGame()) { String packageName = viewHolder.gameEntity.getUniquePackageName(); if (!TextUtils.isEmpty(packageName)) { - downloadEntity = VHelper.getDownloadEntitySnapshotByPackageName(packageName); + downloadEntity = VHelper.getDownloadEntitySnapshot(viewHolder.gameEntity.getId(), packageName); } } diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index 4229c0df8c..a2c97ed398 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -228,7 +228,7 @@ object DownloadItemUtils { var downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity) if (downloadEntity == null && gameEntity.isVGame()) { - downloadEntity = VHelper.getDownloadEntitySnapshotByPackageName(gameEntity.getUniquePackageName() ?: "") + downloadEntity = VHelper.getDownloadEntitySnapshot(gameEntity.id, gameEntity.getUniquePackageName()) } if (downloadEntity != null) { diff --git a/app/src/main/java/com/gh/common/util/GameUtils.java b/app/src/main/java/com/gh/common/util/GameUtils.java index 9fb8e4e690..ef51cfa23c 100644 --- a/app/src/main/java/com/gh/common/util/GameUtils.java +++ b/app/src/main/java/com/gh/common/util/GameUtils.java @@ -109,7 +109,7 @@ public class GameUtils { // 在下载管理找不到下载实体,并且为畅玩游戏的时候到畅玩数据库里找 if (downloadEntity == null && gameEntity.isVGame()) { - downloadEntity = VHelper.getDownloadEntitySnapshotByPackageName(apkEntity.getPackageName()); + downloadEntity = VHelper.getDownloadEntitySnapshot(gameEntity.getId(), apkEntity.getPackageName()); } if (downloadEntity != null) { diff --git a/app/src/main/java/com/gh/common/util/PackageUtils.java b/app/src/main/java/com/gh/common/util/PackageUtils.java index a31ba82f3a..82d7518633 100644 --- a/app/src/main/java/com/gh/common/util/PackageUtils.java +++ b/app/src/main/java/com/gh/common/util/PackageUtils.java @@ -129,7 +129,7 @@ public class PackageUtils { // 畅玩游戏根据 md5 是否一致确定是否需要更新 if (gameEntity.isVGame()) { - VGameEntity vGameEntity = VHelper.getVGameSnapshot(apkEntity.getPackageName()); + VGameEntity vGameEntity = VHelper.getVGameSnapshot(gameEntity.getId(), apkEntity.getPackageName()); if (vGameEntity != null) { String md5FromInstalledVGame = ExtensionsKt.getMetaExtra(vGameEntity.getDownloadEntity(), Constants.APK_MD5); String md5FromRequest = apkEntity.getMd5(); diff --git a/app/src/main/java/com/gh/download/PackageObserver.kt b/app/src/main/java/com/gh/download/PackageObserver.kt index 39472e8b06..8c2c1a29b2 100644 --- a/app/src/main/java/com/gh/download/PackageObserver.kt +++ b/app/src/main/java/com/gh/download/PackageObserver.kt @@ -54,6 +54,8 @@ object PackageObserver { val application = HaloApp.getInstance().application val packageName = busFour.packageName val versionName = busFour.versionName + val preciseGameId = busFour.gameId + var gameId = "" var mDownloadEntity: DownloadEntity? = null val sp = PreferenceManager.getDefaultSharedPreferences(application) @@ -62,7 +64,8 @@ object PackageObserver { var foundMatchedGame = false // 是否找到準確的遊戲 (有可能出現同包名同版本的情況) for (downloadEntity in DownloadManager.getInstance().allDownloadEntity) { - if (packageName == downloadEntity.packageName) { + if (packageName == downloadEntity.packageName + && (preciseGameId == null || preciseGameId == downloadEntity.gameId)) { mDownloadEntity = downloadEntity gameId = mDownloadEntity.gameId if (TextUtils.isEmpty(busFour.versionName)) { @@ -105,11 +108,11 @@ object PackageObserver { } DownloadManager.getInstance().cancel(mDownloadEntity.url, false, true, false) - } - if (sp.getBoolean(CONCERN_GAME_SP_KEY, true)) { //设置页面控制是否安装后自动关注 - // 安装后关注游戏 - val finalDownloadEntity = mDownloadEntity - RetrofitManager.getInstance().api + + if (sp.getBoolean(CONCERN_GAME_SP_KEY, true)) { //设置页面控制是否安装后自动关注 + // 安装后关注游戏 + val finalDownloadEntity = mDownloadEntity + RetrofitManager.getInstance().api .getGameDigestByPackageName(UrlFilterUtils.getFilterQuery("package", packageName)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) @@ -117,13 +120,14 @@ object PackageObserver { override fun onResponse(response: List?) { for (gameDigestEntity in response!!) { if (!TextUtils.isEmpty(gameDigestEntity?.id)) { // 关注游戏 - if (finalDownloadEntity != null && gameDigestEntity?.id == finalDownloadEntity.gameId) { + if (gameDigestEntity?.id == finalDownloadEntity.gameId) { ConcernUtils.postConcernGameId(application, gameDigestEntity?.id ?: "", null, false) } } } } }) + } } runOnIoThread { postNewlyInstalledApp(gameId, packageName) } diff --git a/app/src/main/java/com/gh/gamecenter/eventbus/EBPackage.java b/app/src/main/java/com/gh/gamecenter/eventbus/EBPackage.java deleted file mode 100644 index 79b5736e40..0000000000 --- a/app/src/main/java/com/gh/gamecenter/eventbus/EBPackage.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.gh.gamecenter.eventbus; - -public class EBPackage { - - private String type; - private String packageName; - private String versionName; - - public EBPackage(String type, String packageName, String versionName) { - this.type = type; - this.packageName = packageName; - this.versionName = versionName; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getPackageName() { - return packageName; - } - - public void setPackageName(String packageName) { - this.packageName = packageName; - } - - public String getVersionName() { - return versionName; - } - - public void setVersionName(String versionName) { - this.versionName = versionName; - } -} diff --git a/app/src/main/java/com/gh/gamecenter/eventbus/EBPackage.kt b/app/src/main/java/com/gh/gamecenter/eventbus/EBPackage.kt new file mode 100644 index 0000000000..0505633b0e --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/eventbus/EBPackage.kt @@ -0,0 +1,6 @@ +package com.gh.gamecenter.eventbus + +class EBPackage(var type: String, var packageName: String, var versionName: String) { + var gameId: String? = null +} + diff --git a/app/src/main/java/com/gh/gamecenter/receiver/InstallAndUninstallReceiver.java b/app/src/main/java/com/gh/gamecenter/receiver/InstallAndUninstallReceiver.java index d32a7e7735..86fd57a50c 100644 --- a/app/src/main/java/com/gh/gamecenter/receiver/InstallAndUninstallReceiver.java +++ b/app/src/main/java/com/gh/gamecenter/receiver/InstallAndUninstallReceiver.java @@ -6,7 +6,6 @@ import android.content.Intent; import com.gh.gamecenter.common.utils.ExtensionsKt; import com.gh.gamecenter.core.AppExecutor; -import com.gh.common.util.DataUtils; import com.gh.common.util.InstallUtils; import com.gh.common.util.PackageHelper; import com.gh.common.util.PackageUtils; diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index e63a0ba9ad..c3e115ed94 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -294,9 +294,7 @@ class VDownloadManagerAdapter( downloadBtn.goneIf(mCurrentOption != ManageOption.OPTION_MANAGER) val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity) - ?: VHelper.getDownloadEntitySnapshotByPackageName( - gameEntity.getUniquePackageName() ?: "" - ) + ?: VHelper.getDownloadEntitySnapshot(gameEntity.id, gameEntity.getUniquePackageName()) if (downloadEntity != null) { val status = downloadEntity.status diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index b37ff0a39d..f15dac52c8 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -94,7 +94,7 @@ class VDownloadManagerViewModel(application: Application) : VHelper.uninstall(packageName ?: "") runOnUiThread { - val event = EBPackage("卸载", packageName, "unknown") + val event = EBPackage("卸载", packageName ?: "", "unknown") EventBus.getDefault().post(event) PackageObserver.onPackageChanged(event) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 9472a053cd..40dfacfec5 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -157,11 +157,14 @@ object VHelper { /** * 获取内存里的畅玩游戏快照 * + * @param gameId 游戏 ID * @param packageName 需要获取的畅玩游戏的包名 + * */ @JvmStatic - fun getVGameSnapshot(packageName: String?): VGameEntity? { - return mVGameSnapshotList.find { it.packageName == packageName } + fun getVGameSnapshot(gameId: String?, packageName: String?): VGameEntity? { + return mVGameSnapshotList.find { + it.packageName == packageName && (gameId == null || it.downloadEntity.gameId == gameId) } } private fun updateInstalledList() { @@ -209,7 +212,7 @@ object VHelper { && System.currentTimeMillis() - time < 5000 && !VFeedbackSuppressedSimpleDao().contains(packageName) ) { - getVGameSnapshot(packageName)?.let { + getVGameSnapshot(null, packageName)?.let { VFeedbackDialogFragment.show(activity, toGameEntity(it.downloadEntity)) mLastSuccessfullyLaunchedGame = null } @@ -410,7 +413,7 @@ object VHelper { "安装", result.packageName, "unknown" - ) + ).also { it.gameId = downloadEntity.gameId } ) insertInstalledGameToProvider(downloadEntity) } else { @@ -437,23 +440,25 @@ object VHelper { connectService(false, installClosure) } } - private fun insertInstalledGameToProvider(downloadEntity: DownloadEntity){ + + private fun insertInstalledGameToProvider(downloadEntity: DownloadEntity) { val values = ContentValues() val packageName = downloadEntity.packageName - if (packageName.isEmpty()){ + if (packageName.isEmpty()) { return } //主键 - values.put("package_name",packageName) - values.put("url",downloadEntity.url) - values.put("name",downloadEntity.name) - values.put("size",downloadEntity.size) - values.put("meta",GsonUtils.toJson(downloadEntity.meta)) - val type = if(PackageFlavorHelper.IS_TEST_FLAVOR) "test_flavor" else "" - values.put("type",type) + values.put("package_name", packageName) + values.put("url", downloadEntity.url) + values.put("name", downloadEntity.name) + values.put("size", downloadEntity.size) + values.put("meta", GsonUtils.toJson(downloadEntity.meta)) + val type = if (PackageFlavorHelper.IS_TEST_FLAVOR) "test_flavor" else "" + values.put("type", type) val uri = Uri.parse("content://com.lg.core.provider/download_game") - HaloApp.getInstance().contentResolver.insert(uri,values) + HaloApp.getInstance().contentResolver.insert(uri, values) } + /** * 安装或启动应用 */ @@ -475,7 +480,7 @@ object VHelper { // 检查下载管理是否有下载实体,有实体表明未安装成功 val downloadEntity = DownloadManager.getInstance() .getDownloadEntitySnapshotByPackageName(packageName) - ?: getDownloadEntitySnapshotByPackageName(packageName) + ?: getDownloadEntitySnapshot(gameId = null, packageName = packageName) if (downloadEntity != null) { val downloadedFile = File(downloadEntity.path) @@ -570,18 +575,18 @@ object VHelper { } /** - * 根据包名获取下载快照 + * 根据游戏 ID 和包名获取下载快照 */ @JvmStatic - fun getDownloadEntitySnapshotByPackageName(packageName: String?): DownloadEntity? { - return getVGameSnapshot(packageName)?.downloadEntity + fun getDownloadEntitySnapshot(gameId: String?, packageName: String?): DownloadEntity? { + return getVGameSnapshot(gameId, packageName)?.downloadEntity } /** * 更新游戏最后打开的时间 */ private fun updateLastPlayedTime(packageName: String) { - getVGameSnapshot(packageName)?.let { + getVGameSnapshot(null, packageName)?.let { it.downloadEntity.addMetaExtra( KEY_LAST_PLAYED_TIME, System.currentTimeMillis().toString() @@ -654,7 +659,7 @@ object VHelper { fun updateOrReDownload(gameEntity: GameEntity) { PackagesManager.getUpdateList().firstOrNull { it.id == gameEntity.id } ?.let { updateEntity -> - getVGameSnapshot(updateEntity.packageName) + getVGameSnapshot(gameEntity.id, updateEntity.packageName) ?.let { vGame -> updateOrReDownload(vGame.downloadEntity, updateEntity) } @@ -774,7 +779,7 @@ object VHelper { val rawInstalledPackageList = getInstalledPackageList() val validInstalledPackageList = arrayListOf() for (packageName in rawInstalledPackageList) { - if (getVGameSnapshot(packageName) != null) { + if (getVGameSnapshot(null, packageName) != null) { validInstalledPackageList.add(packageName) } } From f8c61b5d53b2ec2e7a835946734fb5805c5c037f Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Tue, 2 Aug 2022 13:45:37 +0800 Subject: [PATCH 154/217] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E7=95=85=E7=8E=A9=E6=B8=B8=E6=88=8F=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=BC=80=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/common/constant/Config.java | 1 - .../gamecenter/DownloadManagerActivity.java | 5 +- .../com/gh/gamecenter/entity/GameEntity.kt | 6 +- .../com/gh/gamecenter/home/HomeViewModel.kt | 3 +- app/src/main/java/com/gh/vspace/VHelper.kt | 58 ++++++++++--------- module_common/build.gradle | 1 + scripts/build_with_simple_backup.sh | 1 + 7 files changed, 45 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/com/gh/common/constant/Config.java b/app/src/main/java/com/gh/common/constant/Config.java index 1f4b0583d5..c3991a0a3a 100644 --- a/app/src/main/java/com/gh/common/constant/Config.java +++ b/app/src/main/java/com/gh/common/constant/Config.java @@ -25,7 +25,6 @@ import com.gh.gamecenter.eventbus.EBReuse; import com.gh.gamecenter.common.retrofit.BiResponse; import com.gh.gamecenter.common.retrofit.Response; import com.gh.gamecenter.retrofit.RetrofitManager; -import com.gh.vspace.VHelper; import com.halo.assistant.HaloApp; import com.lightgame.utils.Utils; diff --git a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java index 4c9520c5e9..aa82ffe434 100644 --- a/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java +++ b/app/src/main/java/com/gh/gamecenter/DownloadManagerActivity.java @@ -12,6 +12,7 @@ import com.gh.gamecenter.common.base.fragment.BaseFragment_TabLayout; import com.gh.gamecenter.common.constant.EntranceConsts; import com.gh.gamecenter.common.utils.ExtensionsKt; import com.gh.gamecenter.download.DownloadFragment; +import com.gh.vspace.VHelper; /** * 下载更新管理页面 @@ -29,7 +30,9 @@ public class DownloadManagerActivity extends ToolBarActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ExtensionsKt.updateStatusBarColor(this, R.color.background_white, R.color.background_white); - setToolbarMenu(R.menu.menu_download_manager); + if (VHelper.isVGameOn()) { + setToolbarMenu(R.menu.menu_download_manager); + } } @Override diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt index 74e2caa7a5..053666cc1b 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt @@ -593,7 +593,11 @@ data class GameEntity( } fun isVGame(): Boolean { - return downloadStatus == "smooth" + return if (!VHelper.isVGameOn()) { + false + } else { + downloadStatus == "smooth" + } } fun toSimpleGame(): SimpleGame { diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index 5794055b0a..efd1efdca4 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -104,7 +104,8 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { } fun refreshRecentVGameIfNeeded() { - if (SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, true)) { + if (VHelper.isVGameOn() + && SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, true)) { val entityList = getSortedVEntityList() if (entityList.isNotEmpty()) { diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 40dfacfec5..3ccad1b101 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -23,6 +23,7 @@ import com.gh.download.PackageObserver import com.gh.gamecenter.R import com.gh.gamecenter.SplashScreenActivity +import com.gh.gamecenter.common.BuildConfig import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.retrofit.BiResponse import com.gh.gamecenter.common.utils.* @@ -92,7 +93,7 @@ object VHelper { connectService() }, 500) } else if (it.type == "卸载") { - // TODO 执行卸载逻辑 + // 执行卸载逻辑 } } } @@ -100,19 +101,19 @@ object VHelper { @SuppressLint("CheckResult") @JvmStatic fun init(context: Context) { - val config = Config.getVSettingEntity()?.va - if (config != null - && PackageUtils.isInstalled(context, config.arch64?.packageName) - ) { - connectService(true) + if (isVGameOn()) { + val config = Config.getVSettingEntity()?.va + if (config != null && PackageUtils.isInstalled(context, config.arch64?.packageName)) { + connectService(true) - // 检查畅玩助手组件更新 - checkVSpaceUpdate(config.arch64!!) - } - PackageObserver.registerPackageChangeChangeListener(mPackageObserver) + // 检查畅玩助手组件更新 + checkVSpaceUpdate(config.arch64!!) + } + PackageObserver.registerPackageChangeChangeListener(mPackageObserver) - vGameLiveData.observeForever { - mVGameSnapshotList = ArrayList(it) + vGameLiveData.observeForever { + mVGameSnapshotList = ArrayList(it) + } } } @@ -204,17 +205,19 @@ object VHelper { * 启动成功,五秒内退出才显示反馈弹框 */ fun showFeedbackDialogIfLastSuccessfulLaunchedGameExitUnexpectedly(activity: AppCompatActivity) { - val time = mLastSuccessfullyLaunchedGame?.first - val packageName = mLastSuccessfullyLaunchedGame?.second - if (activity !is SplashScreenActivity) { - if (time != null - && packageName != null - && System.currentTimeMillis() - time < 5000 - && !VFeedbackSuppressedSimpleDao().contains(packageName) - ) { - getVGameSnapshot(null, packageName)?.let { - VFeedbackDialogFragment.show(activity, toGameEntity(it.downloadEntity)) - mLastSuccessfullyLaunchedGame = null + if (isVGameOn()) { + val time = mLastSuccessfullyLaunchedGame?.first + val packageName = mLastSuccessfullyLaunchedGame?.second + if (activity !is SplashScreenActivity) { + if (time != null + && packageName != null + && System.currentTimeMillis() - time < 5000 + && !VFeedbackSuppressedSimpleDao().contains(packageName) + ) { + getVGameSnapshot(null, packageName)?.let { + VFeedbackDialogFragment.show(activity, toGameEntity(it.downloadEntity)) + mLastSuccessfullyLaunchedGame = null + } } } } @@ -818,13 +821,16 @@ object VHelper { fun getVUrl(originUrl: String?): String { if (originUrl?.endsWith("type=v") == false) { - if (originUrl?.contains("?") == true) { - return "$originUrl&type=v" + return if (originUrl.contains("?")) { + "$originUrl&type=v" } else { - return "$originUrl?type=v" + "$originUrl?type=v" } } return originUrl ?: "" } + @JvmStatic + fun isVGameOn() = BuildConfig.IS_VGAME_ON + } \ No newline at end of file diff --git a/module_common/build.gradle b/module_common/build.gradle index b37fd4b0bd..a25e4f8581 100644 --- a/module_common/build.gradle +++ b/module_common/build.gradle @@ -31,6 +31,7 @@ android { */ buildConfigField "long", "BUILD_TIME", "0" buildConfigField "boolean", "IS_NIGHT_MODE_ON", "true" + buildConfigField "boolean", "IS_VGAME_ON", "true" } buildFeatures { diff --git a/scripts/build_with_simple_backup.sh b/scripts/build_with_simple_backup.sh index b8c3a4c1be..2ac6f67e4e 100755 --- a/scripts/build_with_simple_backup.sh +++ b/scripts/build_with_simple_backup.sh @@ -31,6 +31,7 @@ rm -r module_common/src/main/res/drawable-night-xxxhdpi rm -r module_common/src/main/res/drawable-night-nodpi rm -r module_common/src/main/res/drawable-night sed -i 's/buildConfigField "boolean", "IS_NIGHT_MODE_ON", "true"/buildConfigField "boolean", "IS_NIGHT_MODE_ON", "false"/g' module_common/build.gradle +sed -i 's/buildConfigField "boolean", "IS_VGAME_ON", "true"/buildConfigField "boolean", "IS_VGAME_ON", "false"/g' module_common/build.gradle ./gradlew --stop ./gradlew clean From 07f68f050b9d1d8f21d1d231f06b5cf74e032b9c Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Tue, 2 Aug 2022 13:59:40 +0800 Subject: [PATCH 155/217] =?UTF-8?q?fix:=20=E8=B0=83=E6=95=B4=E9=83=A8?= =?UTF-8?q?=E5=88=86=20sentry=20=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/gamecenter/MainActivity.java | 6 +++--- .../personalhome/background/BackgroundPreviewFragment.kt | 6 ------ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/MainActivity.java b/app/src/main/java/com/gh/gamecenter/MainActivity.java index d87cf65a58..c90a427976 100644 --- a/app/src/main/java/com/gh/gamecenter/MainActivity.java +++ b/app/src/main/java/com/gh/gamecenter/MainActivity.java @@ -609,7 +609,7 @@ public class MainActivity extends BaseActivity { if (downloadEntity != null) { File file = new File(downloadEntity.getPath()); if (!file.exists()) { - ToastUtils.INSTANCE.showToast("文件已被删除,无法启动"); + ToastUtils.showToast("文件已被删除,无法启动"); return; } @@ -620,8 +620,8 @@ public class MainActivity extends BaseActivity { toast("模拟器游戏启动失败,请联系客服反馈相关信息"); SentryHelper.INSTANCE.onEvent( "SIMULATOR_SHORTCUT_LAUNCH_ERROR", - "raw_json", - json + "error_digest", + exception.getLocalizedMessage() ); } break; diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/background/BackgroundPreviewFragment.kt b/app/src/main/java/com/gh/gamecenter/personalhome/background/BackgroundPreviewFragment.kt index 233804eadc..4bdf9ab1de 100644 --- a/app/src/main/java/com/gh/gamecenter/personalhome/background/BackgroundPreviewFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/personalhome/background/BackgroundPreviewFragment.kt @@ -44,8 +44,6 @@ class BackgroundPreviewFragment : ToolbarFragment() { private var mLocalPath: String = "" private var backgroundImageEntity: BackgroundImageEntity? = null//如果为空,则是本地选择的 - private var mIsTheFirstTimeUserChangeBlurriness = true // 用户是否进入页面来第一次更改模糊度 - private lateinit var mUserViewModel: UserViewModel override fun getLayoutId(): Int = 0 @@ -177,10 +175,6 @@ class BackgroundPreviewFragment : ToolbarFragment() { }, { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { changeAmbiguity() - if (mIsTheFirstTimeUserChangeBlurriness) { - SentryHelper.onEvent("USER_CHANGE_BLURRINESS", "isEmulator", "${HaloApp.getInstance().isEmulator}") - mIsTheFirstTimeUserChangeBlurriness = false - } } else { ToastUtils.showToast("系统版本太低") } From 8b241ec569f83a1d5804fbca7bc75c8846458111 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E5=AD=90=E7=BB=B4?= Date: Tue, 2 Aug 2022 14:46:01 +0800 Subject: [PATCH 156/217] =?UTF-8?q?fix:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E6=B8=B8=E6=88=8F=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E6=96=B0=E5=A2=9E=E2=80=9C=E5=86=85=E5=AE=B9=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E2=80=9D=E5=8A=9F=E8=83=BD(UI=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E6=B1=87=E6=80=BB0802=E8=A1=A5=E5=85=853)=20?= =?UTF-8?q?https://git.shanqu.cc/pm/halo/halo-app-issues/-/issues/1953?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/res/layout/layout_game_detail_content_card_small.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/layout/layout_game_detail_content_card_small.xml b/app/src/main/res/layout/layout_game_detail_content_card_small.xml index 6f6e5cc99a..89b6ea1752 100644 --- a/app/src/main/res/layout/layout_game_detail_content_card_small.xml +++ b/app/src/main/res/layout/layout_game_detail_content_card_small.xml @@ -24,7 +24,7 @@ android:ellipsize="end" android:lines="1" android:textAlignment="center" - android:textColor="@color/text_title" + android:textColor="@color/text_subtitle" android:textSize="@dimen/tag_text_size" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" From c8cd753022763e9152863efa538c1f3a75ebf900 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Tue, 2 Aug 2022 16:21:01 +0800 Subject: [PATCH 157/217] =?UTF-8?q?feat:=20Android=208.0=20=E4=BB=A5?= =?UTF-8?q?=E4=B8=8B=E8=AE=BE=E5=A4=87=E5=81=9C=E7=94=A8=E7=95=85=E7=8E=A9?= =?UTF-8?q?=E6=B8=B8=E6=88=8F=20https://git.shanqu.cc/pm/halo/halo-app-iss?= =?UTF-8?q?ues/-/issues/2000?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VHelper.kt | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 3ccad1b101..8bc998661f 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -6,6 +6,7 @@ import android.content.ContentValues import android.content.Context import android.content.Intent import android.net.Uri +import android.os.Build import android.text.TextUtils import android.view.View import androidx.annotation.WorkerThread @@ -136,7 +137,6 @@ object VHelper { override fun onServiceConnectionFailed(failCode: Int) { Utils.log(LOG_TAG, "V 服务连接失败") - // TODO 重试? } }) } @@ -165,7 +165,8 @@ object VHelper { @JvmStatic fun getVGameSnapshot(gameId: String?, packageName: String?): VGameEntity? { return mVGameSnapshotList.find { - it.packageName == packageName && (gameId == null || it.downloadEntity.gameId == gameId) } + it.packageName == packageName && (gameId == null || it.downloadEntity.gameId == gameId) + } } private fun updateInstalledList() { @@ -208,16 +209,15 @@ object VHelper { if (isVGameOn()) { val time = mLastSuccessfullyLaunchedGame?.first val packageName = mLastSuccessfullyLaunchedGame?.second - if (activity !is SplashScreenActivity) { - if (time != null - && packageName != null - && System.currentTimeMillis() - time < 5000 - && !VFeedbackSuppressedSimpleDao().contains(packageName) - ) { - getVGameSnapshot(null, packageName)?.let { - VFeedbackDialogFragment.show(activity, toGameEntity(it.downloadEntity)) - mLastSuccessfullyLaunchedGame = null - } + if (activity !is SplashScreenActivity + && time != null + && packageName != null + && System.currentTimeMillis() - time < 5000 + && !VFeedbackSuppressedSimpleDao().contains(packageName) + ) { + getVGameSnapshot(null, packageName)?.let { + VFeedbackDialogFragment.show(activity, toGameEntity(it.downloadEntity)) + mLastSuccessfullyLaunchedGame = null } } } @@ -831,6 +831,6 @@ object VHelper { } @JvmStatic - fun isVGameOn() = BuildConfig.IS_VGAME_ON + fun isVGameOn() = BuildConfig.IS_VGAME_ON && Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1 } \ No newline at end of file From 9c11f7f70edf83ea14d0e63d6dbafe4ee3a14aaf Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Tue, 2 Aug 2022 16:22:45 +0800 Subject: [PATCH 158/217] =?UTF-8?q?fix:=20=E5=A4=84=E7=90=86=E9=83=A8?= =?UTF-8?q?=E5=88=86=20SonarQube=20=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/common/util/CommentHelper.kt | 10 +- .../java/com/gh/common/util/CommentUtils.java | 4 +- .../gh/common/util/DetailDownloadUtils.java | 21 ++-- .../common/util/GameActivityDownloadHelper.kt | 11 +- .../com/gh/common/util/PostCommentUtils.java | 43 +------- .../java/com/gh/common/util/RealNameHelper.kt | 3 - .../java/com/gh/download/DownloadManager.java | 2 +- .../adapter/viewholder/DetailViewHolder.java | 8 +- .../game/vertical/GameVerticalAdapter.kt | 1 - .../gamedetail/dialog/GameDetailMoreDialog.kt | 2 - .../packagehelper/PackageRepository.kt | 1 - .../qa/comment/base/BaseCommentViewModel.kt | 1 - .../gh/vspace/VDownloadManagerViewModel.kt | 100 ++++++++++-------- 13 files changed, 75 insertions(+), 132 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/CommentHelper.kt b/app/src/main/java/com/gh/common/util/CommentHelper.kt index 0a9f2b2f1b..c95b80b8c6 100644 --- a/app/src/main/java/com/gh/common/util/CommentHelper.kt +++ b/app/src/main/java/com/gh/common/util/CommentHelper.kt @@ -5,21 +5,21 @@ import android.view.LayoutInflater import android.view.View import android.widget.LinearLayout import android.widget.TextView -import com.gh.gamecenter.common.constant.Constants -import com.gh.gamecenter.common.json.json import com.gh.common.util.CommentUtils.copyText -import com.gh.gamecenter.common.view.BugFixedPopupWindow import com.gh.gamecenter.CommentDetailActivity import com.gh.gamecenter.R +import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.json.json +import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.common.utils.DialogHelper import com.gh.gamecenter.common.utils.ifLogin import com.gh.gamecenter.common.utils.showAutoOrientation +import com.gh.gamecenter.common.view.BugFixedPopupWindow import com.gh.gamecenter.entity.CommentEntity import com.gh.gamecenter.entity.MeEntity import com.gh.gamecenter.entity.Permissions import com.gh.gamecenter.manager.UserManager import com.gh.gamecenter.qa.comment.OnCommentOptionClickListener -import com.gh.gamecenter.common.retrofit.Response import com.gh.gamecenter.retrofit.RetrofitManager import com.halo.assistant.HaloApp import com.lightgame.utils.Utils @@ -237,8 +237,6 @@ object CommentHelper { } articleId != null -> { PostCommentUtils.reportCommunityArticleComment( - communityId, - articleId, commentEntity.id, reportType, commentListener diff --git a/app/src/main/java/com/gh/common/util/CommentUtils.java b/app/src/main/java/com/gh/common/util/CommentUtils.java index 6fdfe9e954..d809b4b562 100644 --- a/app/src/main/java/com/gh/common/util/CommentUtils.java +++ b/app/src/main/java/com/gh/common/util/CommentUtils.java @@ -298,7 +298,7 @@ public class CommentUtils { commentLikeCountTv.setText(NumberUtils.transSimpleCount(commentEntity.getVote())); commentLikeCountTv.setVisibility(View.VISIBLE); - PostCommentUtils.likeComment(answerId, articleId, articleCommunityId, videoId, questionId, commentEntity.getId(), + PostCommentUtils.likeComment(answerId, articleId, videoId, questionId, commentEntity.getId(), new PostCommentUtils.PostCommentListener() { @Override public void postSuccess(JSONObject response) { @@ -352,7 +352,7 @@ public class CommentUtils { String entrance = "视频流-评论-点赞"; CheckLoginUtils.checkLogin(context, entrance, () -> { - PostCommentUtils.likeComment(answerId, articleId, articleCommunityId, videoId, "", commentEntity.getId(), + PostCommentUtils.likeComment(answerId, articleId, videoId, "", commentEntity.getId(), new PostCommentUtils.PostCommentListener() { @Override public void postSuccess(JSONObject response) { diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index ee2af4122e..be60b4b179 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -30,7 +30,7 @@ public class DetailDownloadUtils { public static void detailInitDownload(DetailViewHolder viewHolder, boolean isCheck) { String downloadAddWord = viewHolder.gameEntity.getDownloadAddWord(); - viewHolder.overlayTv.setVisibility(View.GONE); + viewHolder.getOverlayTv().setVisibility(View.GONE); if (viewHolder.gameEntity != null && Config.isShowDownload(viewHolder.gameEntity.getId()) @@ -75,7 +75,7 @@ public class DetailDownloadUtils { String downloadText; if (viewHolder.context.getString(R.string.launch).equals(status) || viewHolder.context.getString(R.string.install).equals(status) || viewHolder.context.getString(R.string.download).equals(status)) { downloadText = ""; - viewHolder.overlayTv.setVisibility(View.VISIBLE); + viewHolder.getOverlayTv().setVisibility(View.VISIBLE); } else if (viewHolder.context.getString(R.string.attempt).equals(status)) { downloadText = status + getDownloadSizeText(viewHolder); } else { @@ -191,7 +191,7 @@ public class DetailDownloadUtils { } viewHolder.mDownloadPb.setProgress((int) (viewHolder.downloadEntity.getPercent() * 10)); - viewHolder.overlayTv.setVisibility(View.GONE); + viewHolder.getOverlayTv().setVisibility(View.GONE); if (viewHolder.gameEntity.isVGame()) { updateVStyleButton(viewHolder); @@ -247,7 +247,7 @@ public class DetailDownloadUtils { } viewHolder.mDownloadPb.setText(""); - viewHolder.overlayTv.setVisibility(View.VISIBLE); + viewHolder.getOverlayTv().setVisibility(View.VISIBLE); } } else { if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL)) { @@ -305,18 +305,9 @@ public class DetailDownloadUtils { } viewHolder.mDownloadPb.setText(""); - viewHolder.overlayTv.setVisibility(View.VISIBLE); - break; + viewHolder.getOverlayTv().setVisibility(View.VISIBLE); } - case cancel: - case hijack: - case notfound: - case uncertificated: - case unqualified: - case unavailable: - // TODO 检查不调用 detailInitDownload 会有什么影响 -// detailInitDownload(viewHolder, false); -// break; + break; default: break; } diff --git a/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt b/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt index 063adb5b53..b889ef6919 100644 --- a/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt +++ b/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt @@ -172,16 +172,7 @@ object GameActivityDownloadHelper { ToastUtils.toast("${gameEntity.name}已加入下载队列") } else { val str = GameUtils.getDownloadBtnText(context, gameEntity, PluginLocation.only_game) - if (str == context.getString(R.string.download)) { - GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) { - CertificationDialog.showCertificationDialog(context, gameEntity) { - DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> - download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent) - } - } - } - DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance) - } else if (str == context.getString(R.string.attempt)) { + if (str == context.getString(R.string.download) || str == context.getString(R.string.attempt)) { GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) { CertificationDialog.showCertificationDialog(context, gameEntity) { DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean -> diff --git a/app/src/main/java/com/gh/common/util/PostCommentUtils.java b/app/src/main/java/com/gh/common/util/PostCommentUtils.java index c4f4383381..bc55a53b97 100644 --- a/app/src/main/java/com/gh/common/util/PostCommentUtils.java +++ b/app/src/main/java/com/gh/common/util/PostCommentUtils.java @@ -73,47 +73,8 @@ public class PostCommentUtils { }); } - public static void addAnswerComment(final String answerId, final String articleId, - final String articleCommunityId, final String content, - final CommentEntity commentEntity, - final PostCommentListener listener) { - RequestBody body = RequestBody.create(MediaType.parse("application/json"), content); - Observable observable; - if (!TextUtils.isEmpty(articleId)) { - if (commentEntity != null) { - observable = RetrofitManager.getInstance().getApi().postReplyToCommunityArticleComment(commentEntity.getId(), body); - } else { - observable = RetrofitManager.getInstance().getApi().postCommentToCommunityArticle(articleId, body); - } - } else { - if (commentEntity != null) { - observable = RetrofitManager.getInstance().getApi().postReplyToAnswerComment(answerId, commentEntity.getId(), body); - } else { - observable = RetrofitManager.getInstance().getApi().postNewCommentToAnswer(answerId, body); - } - } - observable.subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Response() { - @Override - public void onResponse(ResponseBody response) { - if (listener != null) { - listener.postSuccess(new JSONObject());// 不需要返回 - } - } - - @Override - public void onFailure(HttpException e) { - if (listener != null) { - listener.postFailed(e); - } - } - }); - } - public static void likeComment(final String answerId, String articleId, - String articleCommunityId, String videoId, String questionId, final String commentId, @@ -252,9 +213,7 @@ public class PostCommentUtils { }); } - public static void reportCommunityArticleComment(final String communityId, - final String articleId, - final String commentId, + public static void reportCommunityArticleComment(final String commentId, final String reportData, final PostCommentListener listener) { RequestBody body = RequestBody.create(MediaType.parse("application/json"), reportData); diff --git a/app/src/main/java/com/gh/common/util/RealNameHelper.kt b/app/src/main/java/com/gh/common/util/RealNameHelper.kt index 4f2ecbb397..05720cc4aa 100644 --- a/app/src/main/java/com/gh/common/util/RealNameHelper.kt +++ b/app/src/main/java/com/gh/common/util/RealNameHelper.kt @@ -1,15 +1,12 @@ package com.gh.common.util -import android.content.Context import com.gh.gamecenter.core.utils.CurrentActivityHolder import com.gh.download.DownloadManager import com.gh.gamecenter.ShellActivity import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.DialogHelper -import com.gh.gamecenter.core.utils.EmptyCallback import com.gh.gamecenter.core.utils.ToastUtils import com.gh.gamecenter.common.utils.getMetaExtra -import com.gh.gamecenter.entity.GameEntity import com.lightgame.download.DownloadEntity import com.lightgame.download.DownloadStatus diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index bd68a69ae9..880653dded 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -796,7 +796,7 @@ public class DownloadManager implements DownloadStatusListener { } } - private void cancelAndNotify(DownloadEntity entry, Boolean cancelSilently) { + private void cancelAndNotify(DownloadEntity entry, boolean cancelSilently) { mDownloadDao.removeErrorMessage(entry.getUrl()); DownloadTask task = DataChanger.INSTANCE.getDownloadingTasks().get(entry.getUrl()); diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java index 51a0e188d6..c69e98b776 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java @@ -78,14 +78,14 @@ public class DetailViewHolder { public View downloadBottom; public DownloadProgressBar mDownloadPb; - public TextView overlayTv; // 额外的文字 (用于一些含图片的情况) + public TextView mOverlayTv; // 额外的文字 (用于一些含图片的情况) // 注意View的命名 public DetailViewHolder(View view, GameEntity gameEntity, DownloadEntity downloadEntity, boolean isNewsDetail, String entrance, String name, String title, @Nullable ExposureEvent traceEvent) { downloadBottom = view.findViewById(R.id.detail_ll_bottom); mDownloadPb = view.findViewById(R.id.detail_progressbar); - overlayTv = view.findViewById(R.id.overlayTv); + mOverlayTv = view.findViewById(R.id.overlayTv); this.gameEntity = gameEntity; this.downloadEntity = downloadEntity; @@ -99,6 +99,10 @@ public class DetailViewHolder { restoreDialogFragment(); } + public TextView getOverlayTv() { + return mOverlayTv; + } + private void restoreDialogFragment() { DialogFragment gamePermissionDialogFragment = (DialogFragment) ((AppCompatActivity) context).getSupportFragmentManager().findFragmentByTag(GamePermissionDialogFragment.class.getName()); diff --git a/app/src/main/java/com/gh/gamecenter/game/vertical/GameVerticalAdapter.kt b/app/src/main/java/com/gh/gamecenter/game/vertical/GameVerticalAdapter.kt index 911a6d9ab9..9e7f21be1c 100644 --- a/app/src/main/java/com/gh/gamecenter/game/vertical/GameVerticalAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/game/vertical/GameVerticalAdapter.kt @@ -49,7 +49,6 @@ class GameVerticalAdapter( override fun onBindViewHolder(holder: SimpleGameItemViewHolder, position: Int) { if (mTransparentBackground) holder.itemView.setBackgroundColor(R.color.transparent.toColor()) - val isStartOfRow = mSubjectEntity.list > position val paddingStart = 16F.dip2px() val isEndOfRow = position >= if (itemCount % mSubjectEntity.list == 0) { itemCount - mSubjectEntity.list diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/dialog/GameDetailMoreDialog.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/dialog/GameDetailMoreDialog.kt index d50aa07f75..b8a220f590 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/dialog/GameDetailMoreDialog.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/dialog/GameDetailMoreDialog.kt @@ -18,9 +18,7 @@ import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.MtaHelper import com.gh.gamecenter.databinding.DialogGameDetailMoreBinding import com.gh.gamecenter.entity.GameEntity -import com.gh.gamecenter.entity.SimpleGameEntity import com.gh.gamecenter.gamedetail.GameDetailViewModel -import com.gh.gamecenter.suggest.SuggestType class GameDetailMoreDialog : BaseDraggableDialogFragment() { diff --git a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt index 9bc4c1146c..56025baaf3 100644 --- a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt +++ b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt @@ -66,7 +66,6 @@ object PackageRepository { /** * 预留方法,如果想手动初始化可以调用 */ - // TODO 在获取到页面数据以后刷新 @JvmStatic fun initData() { runOnIoThread { diff --git a/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt index 62b3a1096e..c14fcfffe0 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/comment/base/BaseCommentViewModel.kt @@ -157,7 +157,6 @@ abstract class BaseCommentViewModel( PostCommentUtils.likeComment( null, articleId, - communityId, videoId, questionId, comment.id, diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index f15dac52c8..e083c4f340 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -31,58 +31,66 @@ class VDownloadManagerViewModel(application: Application) : override fun provideDataObservable(page: Int): Observable>? = null override fun provideDataSingle(page: Int): Single> { - if (type == TYPE_DOWNLOADED) { - return Single.create { emitter -> - val vGameList = VHelper.getAllVGame().sortedByDescending { it.downloadEntity.start } - val gameList = arrayListOf() - - // 为空直接返回 - if (vGameList.isEmpty()) { - emitter.onSuccess(gameList) - return@create - } - - for (vGame in vGameList) { - // 过滤部分不需要的 - if (DownloadManager.getInstance().allVDownloadTaskSnapshots.any { - it.gameId == vGame.downloadEntity.gameId && it.status != DownloadStatus.done - }) { - continue - } - - val gameEntity = VHelper.toGameEntity(vGame.downloadEntity) - if (gameEntity.playedTime != 0L) { - gameEntity.des = - "已畅玩${NumberUtils.transSimpleUsageTime(gameEntity.playedTime / 1000)}" - } else { - val occupiedSpace = - VHelper.getAppOccupiedSpace(vGame.downloadEntity.packageName) - if (occupiedSpace > 0) { - gameEntity.des = "已占用 ${occupiedSpace.toProperReadableSize()}" - } - } - - gameList.add(gameEntity) - } - - emitter.onSuccess(gameList) - } + return if (type == TYPE_DOWNLOADED) { + provideDownloadedSingle() } else { - return Single.create { emitter -> - val downloadList = DownloadManager.getInstance().allVDownloadTaskSnapshots + provideDownloadingSingle() + } + } - val gameList = arrayListOf() + private fun provideDownloadedSingle(): Single> { + return Single.create { emitter -> + val vGameList = VHelper.getAllVGame().sortedByDescending { it.downloadEntity.start } + val gameList = arrayListOf() - for (downloadEntity in downloadList) { - // 过滤下载完成的部分 - if (downloadEntity.status == DownloadStatus.done) { - continue - } - gameList.add(VHelper.toGameEntity(downloadEntity)) + // 为空直接返回 + if (vGameList.isEmpty()) { + emitter.onSuccess(gameList) + return@create + } + + for (vGame in vGameList) { + // 过滤部分不需要的 + if (DownloadManager.getInstance().allVDownloadTaskSnapshots.any { + it.gameId == vGame.downloadEntity.gameId && it.status != DownloadStatus.done + }) { + continue } - emitter.onSuccess(gameList) + val gameEntity = VHelper.toGameEntity(vGame.downloadEntity) + if (gameEntity.playedTime != 0L) { + gameEntity.des = + "已畅玩${NumberUtils.transSimpleUsageTime(gameEntity.playedTime / 1000)}" + } else { + val occupiedSpace = + VHelper.getAppOccupiedSpace(vGame.downloadEntity.packageName) + if (occupiedSpace > 0) { + gameEntity.des = "已占用 ${occupiedSpace.toProperReadableSize()}" + } + } + + gameList.add(gameEntity) } + + emitter.onSuccess(gameList) + } + } + + private fun provideDownloadingSingle(): Single> { + return Single.create { emitter -> + val downloadList = DownloadManager.getInstance().allVDownloadTaskSnapshots + + val gameList = arrayListOf() + + for (downloadEntity in downloadList) { + // 过滤下载完成的部分 + if (downloadEntity.status == DownloadStatus.done) { + continue + } + gameList.add(VHelper.toGameEntity(downloadEntity)) + } + + emitter.onSuccess(gameList) } } From 6fa4bf75bf235936d313128339f166dc49881164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Tue, 2 Aug 2022 16:25:38 +0800 Subject: [PATCH 159/217] =?UTF-8?q?fix:=20=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E9=A6=96=E9=A1=B5=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E5=88=97=E8=A1=A8=E4=BC=98=E5=8C=96(0802=E6=B5=8B?= =?UTF-8?q?=E8=AF=955)=20https://git.shanqu.cc/pm/halo/halo-app-issues/-/i?= =?UTF-8?q?ssues/1949?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/common/util/DirectUtils.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/common/util/DirectUtils.kt b/app/src/main/java/com/gh/common/util/DirectUtils.kt index 839cb7dfff..fe58c6f34f 100644 --- a/app/src/main/java/com/gh/common/util/DirectUtils.kt +++ b/app/src/main/java/com/gh/common/util/DirectUtils.kt @@ -156,7 +156,8 @@ object DirectUtils { "category_v2", "common_collection", "game_list", - "game_list_detail" + "game_list_detail", + "bbs_video" ) fun directToLinkPage( From 8ff396e05bce36c5c852c8b9add9250432463efd Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Wed, 3 Aug 2022 15:16:00 +0800 Subject: [PATCH 160/217] =?UTF-8?q?feat:=20=E8=B0=83=E6=95=B4=E4=B8=BB=20I?= =?UTF-8?q?O=20=E7=BA=BF=E7=A8=8B=E6=B1=A0=E7=9A=84=E6=A0=B8=E5=BF=83?= =?UTF-8?q?=E6=95=B0=E5=92=8C=E6=9C=80=E5=A4=A7=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/gamecenter/core/AppExecutor.kt | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/module_core/src/main/java/com/gh/gamecenter/core/AppExecutor.kt b/module_core/src/main/java/com/gh/gamecenter/core/AppExecutor.kt index 6a4c7519af..3a4d93cb46 100644 --- a/module_core/src/main/java/com/gh/gamecenter/core/AppExecutor.kt +++ b/module_core/src/main/java/com/gh/gamecenter/core/AppExecutor.kt @@ -5,8 +5,8 @@ import android.os.Looper import com.gh.gamecenter.core.AppExecutor.heavyWeightIoExecutor import com.gh.gamecenter.core.AppExecutor.ioExecutor import com.gh.gamecenter.core.AppExecutor.lightWeightIoExecutor +import com.gh.gamecenter.core.AppExecutor.logExecutor import com.gh.gamecenter.core.AppExecutor.uiExecutor - import io.reactivex.schedulers.Schedulers import java.util.concurrent.* @@ -16,20 +16,23 @@ import java.util.concurrent.* * [ioExecutor] 是一个最大线程数固定的线程池,较为繁重的 IO 任务可以交给它 * [uiExecutor] 是主线程的包裹,需要切换至主线程执行可以用它 * [lightWeightIoExecutor] 是一个单线程的线程池,轻量级且需要保证同一线程的 IO 任务可以交给它 - * [heavyWeightIoExecutor] 重量级的线程池,一些高频调用但不用保证结果的任务可以交给它 + * [heavyWeightIoExecutor] 是一个重量级任务的线程池,一些高频调用但不用保证结果的任务可以交给它 * [logExecutor] 只为上传 log 而使用的线程池 */ object AppExecutor { - private val mCoreSize = Runtime.getRuntime().availableProcessors() - private val mMinimumPoolSize = 6.coerceAtLeast(mCoreSize) - private val mMaximumPoolSize = 24.coerceAtLeast(mCoreSize * 3) + private const val CORE_POOL_SIZE = 3 + private const val MAX_POOL_SIZE = 24 @JvmStatic val uiExecutor by lazy { MainThreadExecutor() } @JvmStatic - val lightWeightIoExecutor: ExecutorService by lazy { Executors.newSingleThreadExecutor(GHThreadFactory("GH_LIGHT_WEIGHT_IO_THREAD")) } + val lightWeightIoExecutor: ExecutorService by lazy { + Executors.newSingleThreadExecutor( + GHThreadFactory("GH_LIGHT_WEIGHT_IO_THREAD") + ) + } @JvmStatic val heavyWeightIoExecutor: ExecutorService by lazy { Executors.newFixedThreadPool(2, GHThreadFactory("GH_HEAVY_WEIGHT_IO_THREAD")) } @@ -39,11 +42,12 @@ object AppExecutor { @JvmStatic val ioExecutor = ThreadPoolExecutor( - mMinimumPoolSize, - mMaximumPoolSize, - 20L, TimeUnit.SECONDS, - LinkedBlockingQueue(256), - GHThreadFactory("GH_IO_THREAD")) + CORE_POOL_SIZE, + MAX_POOL_SIZE, + 20L, TimeUnit.SECONDS, + LinkedBlockingQueue(256), + GHThreadFactory("GH_IO_THREAD") + ) val cachedScheduler by lazy { Schedulers.from(ioExecutor) } @@ -60,7 +64,11 @@ object AppExecutor { } } -fun runOnIoThread(isLightWeightTask: Boolean = false, isHeavyWightTask: Boolean = false, f: () -> Unit) { +fun runOnIoThread( + isLightWeightTask: Boolean = false, + isHeavyWightTask: Boolean = false, + f: () -> Unit +) { when { isLightWeightTask -> lightWeightIoExecutor.execute(f) isHeavyWightTask -> heavyWeightIoExecutor.execute(f) From 6f5f72194a3301b9f9ecabfe01dd9ec5bbc9582a Mon Sep 17 00:00:00 2001 From: juntao Date: Wed, 3 Aug 2022 16:15:16 +0800 Subject: [PATCH 161/217] =?UTF-8?q?feat:=20=E7=A7=BB=E9=99=A4=20log=20?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B=EF=BC=8C=E5=8F=96=E6=B6=88=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=20log=20=E6=95=B0=E6=8D=AE=E5=BA=93=EF=BC=88=E7=94=B1=20loghub?= =?UTF-8?q?=20sdk=20=E5=AE=9E=E7=8E=B0=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/common/FixedRateJobHelper.kt | 2 +- .../gh/common/exposure/ExposureConverters.kt | 62 ------------ .../gh/common/exposure/ExposureDatabase.kt | 32 ------- .../com/gh/common/exposure/ExposureEvent.kt | 1 - .../gh/common/exposure/ExposureEventDao.kt | 18 ---- .../com/gh/common/exposure/ExposureManager.kt | 89 +++++------------ .../com/gh/common/exposure/ExposureUtils.kt | 2 +- .../manager/DataCollectionManager.java | 6 +- .../main/java/com/halo/assistant/HaloApp.java | 9 +- .../common/loghub/LoghubDatabase.kt | 29 ------ .../gamecenter/common/loghub/LoghubEvent.kt | 1 - .../common/loghub/LoghubEventDao.kt | 18 ---- .../gamecenter/common/loghub/LoghubHelper.kt | 10 +- .../gamecenter/common/loghub/LoghubUtils.kt | 95 ++++++------------- .../com/gh/gamecenter/core/AppExecutor.kt | 7 +- 15 files changed, 67 insertions(+), 314 deletions(-) delete mode 100644 app/src/main/java/com/gh/common/exposure/ExposureConverters.kt delete mode 100644 app/src/main/java/com/gh/common/exposure/ExposureDatabase.kt delete mode 100644 app/src/main/java/com/gh/common/exposure/ExposureEventDao.kt delete mode 100644 module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt delete mode 100644 module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubEventDao.kt diff --git a/app/src/main/java/com/gh/common/FixedRateJobHelper.kt b/app/src/main/java/com/gh/common/FixedRateJobHelper.kt index 4f39d60084..6835758b5c 100644 --- a/app/src/main/java/com/gh/common/FixedRateJobHelper.kt +++ b/app/src/main/java/com/gh/common/FixedRateJobHelper.kt @@ -60,7 +60,7 @@ object FixedRateJobHelper { // 提交普通 loghub 数据 if ((mExecuteCount * CHECKER_PERIOD) % LOGHUB_PERIOD == 0L) { - LoghubUtils.commitSavedLoghubEvents() + LoghubUtils.commitSavedLoghubEvents(true) } // 更新游戏屏蔽信息 diff --git a/app/src/main/java/com/gh/common/exposure/ExposureConverters.kt b/app/src/main/java/com/gh/common/exposure/ExposureConverters.kt deleted file mode 100644 index 8b3392b110..0000000000 --- a/app/src/main/java/com/gh/common/exposure/ExposureConverters.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.gh.common.exposure - -import androidx.room.TypeConverter -import com.gh.gamecenter.common.entity.ExposureEntity -import com.gh.gamecenter.common.exposure.meta.Meta -import com.gh.gamecenter.core.utils.GsonUtils -import java.util.* -import kotlin.collections.ArrayList - -class ExposureConverters { - - @TypeConverter - fun convertPayload2String(any: ExposureEntity): String { - return GsonUtils.toJson(any) - } - - @TypeConverter - fun convertString2Payload(string: String): ExposureEntity { - return GsonUtils.fromJson(string, ExposureEntity::class.java) - } - - @TypeConverter - fun convertSource2String(sourceList: List): String { - return GsonUtils.toJson(sourceList) - } - - @TypeConverter - fun convertString2Source(sourceList: String): List { - return ArrayList(Arrays.asList(GsonUtils.fromJson(sourceList, Array::class.java))) as List - } - - @TypeConverter - fun convertETrace2String(sourceList: List?): String { - return GsonUtils.toJson(sourceList) - } - - @TypeConverter - fun convertStringToETrace(sourceList: String): List { - return ArrayList(Arrays.asList(GsonUtils.fromJson(sourceList, Array::class.java))) as List - } - - @TypeConverter - fun convertExposeType2String(exposureType: ExposureType): String { - return exposureType.toString() - } - - @TypeConverter - fun convertStringToExposeType(exposureType: String): ExposureType { - return ExposureType.valueOf(exposureType) - } - - @TypeConverter - fun convertMeta2String(any: Meta): String { - return GsonUtils.toJson(any) - } - - @TypeConverter - fun convertString2Meta(string: String): Meta { - return GsonUtils.fromJson(string, Meta::class.java) - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/gh/common/exposure/ExposureDatabase.kt b/app/src/main/java/com/gh/common/exposure/ExposureDatabase.kt deleted file mode 100644 index bc8724fb1c..0000000000 --- a/app/src/main/java/com/gh/common/exposure/ExposureDatabase.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.gh.common.exposure - -import android.content.Context -import androidx.room.Database -import androidx.room.Room -import androidx.room.RoomDatabase -import androidx.room.TypeConverters -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -@TypeConverters(ExposureConverters::class) -@Database(entities = [ExposureEvent::class], version = 2, exportSchema = false) -abstract class ExposureDatabase : RoomDatabase() { - companion object { - private const val DATABASE = "exposure_database" - - fun buildDatabase(context: Context): ExposureDatabase { - return Room.databaseBuilder(context, ExposureDatabase::class.java, DATABASE) - .fallbackToDestructiveMigration() - .addMigrations(MIGRATION_1_2) - .build() - } - - private val MIGRATION_1_2: Migration = object : Migration(1, 2) { - override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL("Alter TABLE ExposureEvent add timeInMillisecond INTEGER NOT NULL DEFAULT 0") - } - } - } - - abstract fun logHubEventDao(): ExposureEventDao -} \ No newline at end of file diff --git a/app/src/main/java/com/gh/common/exposure/ExposureEvent.kt b/app/src/main/java/com/gh/common/exposure/ExposureEvent.kt index f46f806cec..9b582f938e 100644 --- a/app/src/main/java/com/gh/common/exposure/ExposureEvent.kt +++ b/app/src/main/java/com/gh/common/exposure/ExposureEvent.kt @@ -18,7 +18,6 @@ import java.util.* @Keep @Parcelize -@Entity(tableName = "exposureEvent") data class ExposureEvent( var payload: ExposureEntity, val source: List, diff --git a/app/src/main/java/com/gh/common/exposure/ExposureEventDao.kt b/app/src/main/java/com/gh/common/exposure/ExposureEventDao.kt deleted file mode 100644 index 03c16aa0f9..0000000000 --- a/app/src/main/java/com/gh/common/exposure/ExposureEventDao.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.gh.common.exposure - -import androidx.room.* - -@Dao -interface ExposureEventDao { - @Insert(onConflict = OnConflictStrategy.REPLACE) - fun insertMany(eventList: List) - - @Insert(onConflict = OnConflictStrategy.REPLACE) - fun insert(event: ExposureEvent) - - @Query("SELECT * FROM exposureEvent") - fun getAll(): List - - @Delete - fun deleteMany(eventList: List) -} \ No newline at end of file diff --git a/app/src/main/java/com/gh/common/exposure/ExposureManager.kt b/app/src/main/java/com/gh/common/exposure/ExposureManager.kt index 736f906782..9d8244ab91 100644 --- a/app/src/main/java/com/gh/common/exposure/ExposureManager.kt +++ b/app/src/main/java/com/gh/common/exposure/ExposureManager.kt @@ -5,10 +5,7 @@ import com.gh.gamecenter.BuildConfig import com.gh.gamecenter.common.loghub.LoghubHelper import com.gh.gamecenter.common.utils.FixedSizeLinkedHashSet import com.gh.gamecenter.common.utils.toJson -import com.gh.gamecenter.common.utils.tryWithDefaultCatch -import com.halo.assistant.HaloApp import com.lightgame.utils.Utils -import java.util.concurrent.ExecutorService /** * A handful tool for committing logs to aliyun loghub. @@ -26,40 +23,17 @@ object ExposureManager { // exposureCache 用来过滤掉具有相同 id 的曝光事件,避免重复发送事件 private val exposureSet by lazy { hashSetOf() } - private var exposureExecutor: ExecutorService? = null private val exposureCache by lazy { FixedSizeLinkedHashSet(300) } - private val exposureDao by lazy { ExposureDatabase.buildDatabase(HaloApp.getInstance().application).logHubEventDao() } - - @JvmStatic - fun init(excutor: ExecutorService) { - exposureExecutor = excutor - exposureExecutor?.execute { - tryWithDefaultCatch { - val eventList = exposureDao.getAll() - exposureSet.addAll(eventList) - } - } - } /** * Log a single exposure event. */ fun log(event: ExposureEvent) { - exposureExecutor?.execute { - try { - if (!exposureCache.contains(event.id)) { - // Catch `android.database.sqlite.SQLiteFullException: database or disk is full` exception. - - exposureSet.add(event) - exposureDao.insert(event) - exposureCache.add(event.id) - - } else { - Utils.log("Exposure", "遇到重复曝光事件,自动过滤 (${event.id} - ${event.payload.gameName})") - } - } catch (e: Exception) { - e.printStackTrace() - } + if (!exposureCache.contains(event.id)) { + exposureSet.add(event) + exposureCache.add(event.id) + } else { + Utils.log("Exposure", "遇到重复曝光事件,自动过滤 (${event.id} - ${event.payload.gameName})") } } @@ -67,51 +41,36 @@ object ExposureManager { * Log a collection of exposure event. */ fun log(eventList: List) { - exposureExecutor?.execute { - for (event in eventList) { - try { - if (!exposureCache.contains(event.id)) { - // Catch `android.database.sqlite.SQLiteFullException: database or disk is full` exception. - exposureSet.add(event) - exposureDao.insert(event) - exposureCache.add(event.id) - } else { - Utils.log("Exposure", "遇到重复曝光事件,自动过滤 (${event.id} - ${event.payload.gameName})") - } - } catch (e: Exception) { - e.printStackTrace() - } + for (event in eventList) { + if (!exposureCache.contains(event.id)) { + exposureSet.add(event) + exposureCache.add(event.id) + } else { + Utils.log("Exposure", "遇到重复曝光事件,自动过滤 (${event.id} - ${event.payload.gameName})") } - commitSavedExposureEvents() } + commitSavedExposureEvents() } /** - * @param forced Ignore all restrictions. + * @param forcedUpload Ignore all restrictions. */ - fun commitSavedExposureEvents(forced: Boolean = false) { - exposureExecutor?.execute { - tryWithDefaultCatch { - // TODO 初始化 loghubHelper 去掉这个 tryCatch 块 - if (exposureSet.size < STORE_SIZE && !forced || exposureSet.size == 0) return@execute + fun commitSavedExposureEvents(forcedUpload: Boolean = false) { + if (exposureSet.size < STORE_SIZE && !forcedUpload || exposureSet.size == 0) return - val exposureList = exposureSet.toList() - uploadExposures(exposureList) + uploadExposures(exposureSet.toList(), forcedUpload) - Utils.log("Exposure", "提交了${exposureList.size}条曝光记录") - exposureSet.removeAll(exposureList) - exposureDao.deleteMany(exposureList) - } - } + Utils.log("Exposure", "提交了${exposureSet.size}条曝光记录") + exposureSet.clear() } private fun eliminateMultipleBrackets(jsonWithMultipleBracket: String): String { return jsonWithMultipleBracket.replace("[[", "[").replace("]]", "]") } - private fun uploadExposures(eventList: List) { + private fun uploadExposures(eventList: List, forced: Boolean) { eventList.forEach { - LoghubHelper.uploadLog(buildLog(it), LOG_STORE) + LoghubHelper.uploadLog(buildLog(it), LOG_STORE, forced) } } @@ -122,9 +81,11 @@ object ExposureManager { putContent("source", eliminateMultipleBrackets(event.source.toJson())) putContent("meta", event.meta.toJson()) putContent("real_millisecond", event.timeInMillisecond.toString()) - putContent("e-traces", if (event.eTrace != null) { - eliminateMultipleBrackets(event.eTrace?.toJson() ?: "") - } else "") + putContent( + "e-traces", if (event.eTrace != null) { + eliminateMultipleBrackets(event.eTrace?.toJson() ?: "") + } else "" + ) logTime = event.time.toLong() } diff --git a/app/src/main/java/com/gh/common/exposure/ExposureUtils.kt b/app/src/main/java/com/gh/common/exposure/ExposureUtils.kt index afc40dc81c..72f92e2a25 100644 --- a/app/src/main/java/com/gh/common/exposure/ExposureUtils.kt +++ b/app/src/main/java/com/gh/common/exposure/ExposureUtils.kt @@ -76,7 +76,7 @@ object ExposureUtils { exposureEvent.payload.host = host exposureEvent.payload.path = path ExposureManager.log(exposureEvent) - ExposureManager.commitSavedExposureEvents(forced = true) + ExposureManager.commitSavedExposureEvents(forcedUpload = true) } @JvmStatic diff --git a/app/src/main/java/com/gh/gamecenter/manager/DataCollectionManager.java b/app/src/main/java/com/gh/gamecenter/manager/DataCollectionManager.java index d9fef20e7c..613262c8b8 100644 --- a/app/src/main/java/com/gh/gamecenter/manager/DataCollectionManager.java +++ b/app/src/main/java/com/gh/gamecenter/manager/DataCollectionManager.java @@ -36,7 +36,7 @@ public class DataCollectionManager { } public static void onEvent(Context context, String type, Map map, boolean isUpload) { - AppExecutor.getLogExecutor().execute(() -> { + AppExecutor.getIoExecutor().execute(() -> { map.put("createdOn", Utils.getTime(context)); if (isUpload) { DataCollectionManager.getInstance().realTimeUpload(type, map); @@ -183,7 +183,7 @@ public class DataCollectionManager { * 统计点击数据 */ public void statClickData() { - AppExecutor.getLogExecutor().execute(() -> { + AppExecutor.getIoExecutor().execute(() -> { List list = dao.getClickData(); if (list != null && !list.isEmpty()) { List ids = new ArrayList<>(); @@ -207,7 +207,7 @@ public class DataCollectionManager { } public static void onEvent(Context context, String type, Map map) { - AppExecutor.getLogExecutor().execute(() -> { + AppExecutor.getIoExecutor().execute(() -> { map.put("createdOn", Utils.getTime(context)); if ("news".equals(type) || "download".equals(type) || "search".equals(type)) { DataCollectionManager.getInstance().realTimeUpload(type, map); diff --git a/app/src/main/java/com/halo/assistant/HaloApp.java b/app/src/main/java/com/halo/assistant/HaloApp.java index 477287c995..9ef89f9f38 100644 --- a/app/src/main/java/com/halo/assistant/HaloApp.java +++ b/app/src/main/java/com/halo/assistant/HaloApp.java @@ -197,7 +197,7 @@ public class HaloApp extends MultiDexApplication implements Configuration.Provid AppExecutor.getIoExecutor().execute(() -> { initDataHelper(); - Tracker.init(this); + ExtensionsKt.doOnMainProcessOnly(this, () -> Tracker.init(this)); initFresco(); @@ -315,12 +315,7 @@ public class HaloApp extends MultiDexApplication implements Configuration.Provid } private void initDataHelper() { - AppExecutor.getIoExecutor().execute(() -> { - ExecutorService logExecutor = AppExecutor.getLogExecutor(); - ExposureManager.init(logExecutor); - LoghubUtils.init(this, logExecutor); - VideoRecordUtils.init(this, logExecutor); - }); + VideoRecordUtils.init(this, AppExecutor.getIoExecutor()); } // todo 动态注册和静态注册并行的话会触发多次回调 diff --git a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt deleted file mode 100644 index 2d98c8d10b..0000000000 --- a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubDatabase.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.gh.gamecenter.common.loghub - -import android.content.Context -import androidx.room.Database -import androidx.room.Room -import androidx.room.RoomDatabase -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -@Database(entities = [LoghubEvent::class], version = 2, exportSchema = false) -abstract class LoghubDatabase : RoomDatabase() { - companion object { - private const val DATABASE = "gh_loghub_database" - - private val MIGRATION_1_2: Migration = object : Migration(1, 2) { - override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL("Alter TABLE loghubEvent add isFlat INTEGER NOT NULL DEFAULT 0") - } - } - - fun buildDatabase(context: Context): LoghubDatabase { - return Room.databaseBuilder(context, LoghubDatabase::class.java, DATABASE) - .addMigrations(MIGRATION_1_2) - .build() - } - } - - abstract fun logHubEventDao(): LoghubEventDao -} \ No newline at end of file diff --git a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubEvent.kt b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubEvent.kt index 11d49f6164..c503c06ee8 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubEvent.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubEvent.kt @@ -9,7 +9,6 @@ import java.util.* @Keep @Parcelize -@Entity(tableName = "loghubEvent") data class LoghubEvent( @PrimaryKey val id: String = UUID.randomUUID().toString(), diff --git a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubEventDao.kt b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubEventDao.kt deleted file mode 100644 index 07b0f2f73a..0000000000 --- a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubEventDao.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.gh.gamecenter.common.loghub - -import androidx.room.* - -@Dao -interface LoghubEventDao { - @Insert(onConflict = OnConflictStrategy.REPLACE) - fun insertMany(eventList: List) - - @Insert(onConflict = OnConflictStrategy.REPLACE) - fun insert(event: LoghubEvent) - - @Query("SELECT * FROM LoghubEvent") - fun getAll(): List - - @Delete - fun deleteMany(eventList: List) -} \ No newline at end of file diff --git a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubHelper.kt b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubHelper.kt index ed88f6c5af..4153bc2800 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubHelper.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubHelper.kt @@ -17,13 +17,17 @@ object LoghubHelper { private val mClientMaps by lazy { hashMapOf() } - fun uploadLog(log: Log, logStore: String) { - getClient(logStore)?.addLog(log) + /** + * 上传日志至阿里云 loghub + * @param uploadImmediately 马上上传日志 + */ + fun uploadLog(log: Log, logStore: String, uploadImmediately: Boolean) { + getClient(logStore)?.addLog(log, if (uploadImmediately) 1 else 0) } fun uploadLogs(logs: List, logStore: String) { logs.forEach { - uploadLog(it, logStore) + uploadLog(it, logStore, false) } } diff --git a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubUtils.kt b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubUtils.kt index bba448ea39..fa0a16a945 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubUtils.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubUtils.kt @@ -1,100 +1,58 @@ package com.gh.gamecenter.common.loghub -import android.app.Application import androidx.annotation.Keep import com.aliyun.sls.android.producer.Log import com.gh.gamecenter.common.entity.ExposureEntity import com.gh.gamecenter.common.exposure.meta.Meta -import com.gh.gamecenter.common.utils.tryWithDefaultCatch import org.json.JSONObject -import java.util.concurrent.ExecutorService object LoghubUtils { private const val STORE_SIZE = 100 - private lateinit var mApplication: Application private val loghubEventSet by lazy { hashSetOf() } - private var loghubEventExecutor: ExecutorService? = null - private val loghubEventDao by lazy { LoghubDatabase.buildDatabase(mApplication).logHubEventDao() } - - @JvmStatic - fun init(application: Application, executor: ExecutorService) { - mApplication = application - - loghubEventExecutor = executor - loghubEventExecutor?.execute { - tryWithDefaultCatch { - val eventList = loghubEventDao.getAll() - loghubEventSet.addAll(eventList) - } - } - } @JvmStatic @JvmOverloads fun log(logJson: JSONObject, logStore: String, forcedUpload: Boolean, isFlat: Boolean = false) { - loghubEventExecutor?.execute { - try { - val event = LoghubEvent( - time = (System.currentTimeMillis() / 1000L).toString(), - content = logJson.toString(), - logStore = logStore, - isFlat = isFlat - ) - loghubEventSet.add(event) - loghubEventDao.insert(event) - } catch (e: Exception) { - e.printStackTrace() - } + val event = LoghubEvent( + time = (System.currentTimeMillis() / 1000L).toString(), + content = logJson.toString(), + logStore = logStore, + isFlat = isFlat + ) + loghubEventSet.add(event) - if (forcedUpload || loghubEventSet.size >= STORE_SIZE) { - commitSavedLoghubEvents() - } + if (forcedUpload || loghubEventSet.size >= STORE_SIZE) { + commitSavedLoghubEvents(forcedUpload) } } @JvmStatic @JvmOverloads fun log(jsonString: String, logStore: String, forcedUpload: Boolean, isFlat: Boolean = false) { - loghubEventExecutor?.execute { - try { - val event = LoghubEvent( - time = (System.currentTimeMillis() / 1000L).toString(), - content = jsonString, - logStore = logStore, - isFlat = isFlat - ) - loghubEventSet.add(event) - loghubEventDao.insert(event) - } catch (e: Exception) { - e.printStackTrace() - } + val event = LoghubEvent( + time = (System.currentTimeMillis() / 1000L).toString(), + content = jsonString, + logStore = logStore, + isFlat = isFlat + ) + loghubEventSet.add(event) - if (forcedUpload || loghubEventSet.size >= STORE_SIZE) { - commitSavedLoghubEvents() - } + if (forcedUpload || loghubEventSet.size >= STORE_SIZE) { + commitSavedLoghubEvents(forcedUpload) } } - fun commitSavedLoghubEvents() { - loghubEventExecutor?.execute { - // TODO 初始化 loghubHelper 去掉这个 tryCatch 块 - tryWithDefaultCatch { - if (loghubEventSet.isEmpty()) return@execute + fun commitSavedLoghubEvents(forcedUpload: Boolean) { + if (loghubEventSet.isEmpty()) return - val exposureList = loghubEventSet.toList() - - uploadEvents() - loghubEventSet.removeAll(exposureList) - loghubEventDao.deleteMany(exposureList) - } - } + uploadEvents(loghubEventSet.toList(), forcedUpload) + loghubEventSet.clear() } - private fun uploadEvents() { - for (event in loghubEventSet) { - + private fun uploadEvents(eventList: List, forcedUpload: Boolean) { + for (event in eventList) { val log = Log() // 特殊处理,以下logStore不需要用content包裹数据 if (event.logStore == "collection" || event.logStore == "common" || event.logStore == "halo-api-device-installed") { @@ -117,7 +75,7 @@ object LoghubUtils { } } - LoghubHelper.uploadLog(log, event.logStore) + LoghubHelper.uploadLog(log, event.logStore, forcedUpload) } } @@ -129,4 +87,5 @@ data class SimpleLogContainerEntity( var action: String? = null, var meta: Meta? = null, var payload: ExposureEntity? = null, - var timestamp: Long? = 0) \ No newline at end of file + var timestamp: Long? = 0 +) \ No newline at end of file diff --git a/module_core/src/main/java/com/gh/gamecenter/core/AppExecutor.kt b/module_core/src/main/java/com/gh/gamecenter/core/AppExecutor.kt index 3a4d93cb46..66f0cb3cf9 100644 --- a/module_core/src/main/java/com/gh/gamecenter/core/AppExecutor.kt +++ b/module_core/src/main/java/com/gh/gamecenter/core/AppExecutor.kt @@ -5,7 +5,6 @@ import android.os.Looper import com.gh.gamecenter.core.AppExecutor.heavyWeightIoExecutor import com.gh.gamecenter.core.AppExecutor.ioExecutor import com.gh.gamecenter.core.AppExecutor.lightWeightIoExecutor -import com.gh.gamecenter.core.AppExecutor.logExecutor import com.gh.gamecenter.core.AppExecutor.uiExecutor import io.reactivex.schedulers.Schedulers import java.util.concurrent.* @@ -17,7 +16,6 @@ import java.util.concurrent.* * [uiExecutor] 是主线程的包裹,需要切换至主线程执行可以用它 * [lightWeightIoExecutor] 是一个单线程的线程池,轻量级且需要保证同一线程的 IO 任务可以交给它 * [heavyWeightIoExecutor] 是一个重量级任务的线程池,一些高频调用但不用保证结果的任务可以交给它 - * [logExecutor] 只为上传 log 而使用的线程池 */ object AppExecutor { @@ -35,10 +33,7 @@ object AppExecutor { } @JvmStatic - val heavyWeightIoExecutor: ExecutorService by lazy { Executors.newFixedThreadPool(2, GHThreadFactory("GH_HEAVY_WEIGHT_IO_THREAD")) } - - @JvmStatic - val logExecutor: ExecutorService by lazy { Executors.newSingleThreadExecutor(GHThreadFactory("GH_LOG_THREAD")) } + val heavyWeightIoExecutor: ExecutorService by lazy { Executors.newSingleThreadExecutor(GHThreadFactory("GH_HEAVY_WEIGHT_IO_THREAD")) } @JvmStatic val ioExecutor = ThreadPoolExecutor( From 5d21f4e29f2bd4359465ba77de2385be9b2e234d Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Mon, 8 Aug 2022 15:38:27 +0800 Subject: [PATCH 162/217] =?UTF-8?q?feat:=20=E7=95=85=E7=8E=A9=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E5=8F=91=E5=B8=83=E7=9B=B8=E5=85=B3=E5=87=86=E5=A4=87?= =?UTF-8?q?=20https://git.shanqu.cc/pm/halo/halo-app-issues/-/issues/2000?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/base/GlobalActivityLifecycleObserver.kt | 2 +- .../main/java/com/gh/common/constant/Config.java | 15 +++++++++++++++ .../com/gh/gamecenter/entity/SettingsEntity.kt | 4 +++- app/src/main/java/com/gh/vspace/VHelper.kt | 14 ++++++++++++-- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/gh/base/GlobalActivityLifecycleObserver.kt b/app/src/main/java/com/gh/base/GlobalActivityLifecycleObserver.kt index f81a48f2f9..9ece998764 100644 --- a/app/src/main/java/com/gh/base/GlobalActivityLifecycleObserver.kt +++ b/app/src/main/java/com/gh/base/GlobalActivityLifecycleObserver.kt @@ -61,7 +61,7 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks { NightModeSwitchHelper.showNightModeSwitchFloatingView(activity) } - if (activity is AppCompatActivity) { + if (activity is AppCompatActivity && activity !is SplashScreenActivity) { VHelper.showFeedbackDialogIfLastSuccessfulLaunchedGameExitUnexpectedly(activity) } } diff --git a/app/src/main/java/com/gh/common/constant/Config.java b/app/src/main/java/com/gh/common/constant/Config.java index c3991a0a3a..3f1b7c0955 100644 --- a/app/src/main/java/com/gh/common/constant/Config.java +++ b/app/src/main/java/com/gh/common/constant/Config.java @@ -25,6 +25,7 @@ import com.gh.gamecenter.eventbus.EBReuse; import com.gh.gamecenter.common.retrofit.BiResponse; import com.gh.gamecenter.common.retrofit.Response; import com.gh.gamecenter.retrofit.RetrofitManager; +import com.gh.vspace.VHelper; import com.halo.assistant.HaloApp; import com.lightgame.utils.Utils; @@ -115,6 +116,17 @@ public class Config { return false; } + /** + * 是否启用畅玩游戏 + */ + public static boolean isVGameEnabled() { + if (getSettings() == null) { + return false; + } + + return !"off".equals(getSettings().getGameSmooth()); + } + public static boolean isShowPlugin(String gameId) { SharedPreferences preferences = getPreferences(); @@ -185,6 +197,9 @@ public class Config { // 加载完设置后刷新下 PackageHelper.initList(); + + // 初始化畅玩相关的东西 + VHelper.init(HaloApp.getInstance()); } @Nullable diff --git a/app/src/main/java/com/gh/gamecenter/entity/SettingsEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/SettingsEntity.kt index a8e8a55ee1..38162da908 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/SettingsEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/SettingsEntity.kt @@ -32,7 +32,9 @@ data class SettingsEntity( @SerializedName("permission_popup_switch") var permissionPopupSwitch: String = "off",//权限引导弹窗开关,on/off @SerializedName("permission_popup_applied_versions") - var permissionPopupAppliedVersions: PermissionPopupAppliedVersions = PermissionPopupAppliedVersions() + var permissionPopupAppliedVersions: PermissionPopupAppliedVersions = PermissionPopupAppliedVersions(), + @SerializedName("game_smooth") + var gameSmooth: String = "off" // 畅玩功能,on/off,默认off ) { fun setCommunityEntrance(communityEntrance: String) { diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 8bc998661f..897899b6cd 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -75,6 +75,8 @@ object VHelper { private var mUpdateEntity: AppEntity? = null + private var mIsInitialized = false // 是否已初始化 + // 当前正卡在安装中的 VA 游戏,避免重复调用安装 private val mInstallingVaPathSet by lazy { Collections.synchronizedSet(hashSetOf()) } @@ -102,7 +104,9 @@ object VHelper { @SuppressLint("CheckResult") @JvmStatic fun init(context: Context) { - if (isVGameOn()) { + if (isVGameOn() && !mIsInitialized) { + mIsInitialized = true + val config = Config.getVSettingEntity()?.va if (config != null && PackageUtils.isInstalled(context, config.arch64?.packageName)) { connectService(true) @@ -543,6 +547,10 @@ object VHelper { } Utils.log(LOG_TAG, "卸载应用结果 -> $result") + + runOnIoThread { + VBackupHelper.backupDBToExternalStorage(HaloApp.getInstance()) + } } catch (e: Exception) { ToastUtils.toast(e.localizedMessage ?: "") } @@ -831,6 +839,8 @@ object VHelper { } @JvmStatic - fun isVGameOn() = BuildConfig.IS_VGAME_ON && Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1 + fun isVGameOn() = BuildConfig.IS_VGAME_ON + && Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1 + && Config.isVGameEnabled() } \ No newline at end of file From 90095672268b636f4c8b5d0c7f3d9260a70eef3f Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Mon, 8 Aug 2022 17:25:25 +0800 Subject: [PATCH 163/217] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E5=BE=AE?= =?UTF-8?q?=E5=8D=9A=20SDK=20(=E9=81=BF=E5=85=8D=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E8=8E=B7=E5=8F=96=20MAC=20=E5=9C=B0=E5=9D=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/common/util/LoginHelper.kt | 10 +++---- .../java/com/gh/gamecenter/MainActivity.java | 14 ++------- .../com/gh/gamecenter/WeiBoShareActivity.java | 4 +-- .../gh/gamecenter/fragment/LoginFragment.java | 2 +- .../personal/NewPersonalFragment.kt | 2 +- .../gamecenter/personal/PersonalFragment.kt | 30 +++++++++---------- dependencies.gradle | 2 +- 7 files changed, 27 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/LoginHelper.kt b/app/src/main/java/com/gh/common/util/LoginHelper.kt index 8270127af1..5c0067d830 100644 --- a/app/src/main/java/com/gh/common/util/LoginHelper.kt +++ b/app/src/main/java/com/gh/common/util/LoginHelper.kt @@ -3,10 +3,10 @@ package com.gh.common.util import android.app.Activity import android.content.Intent import com.gh.common.constant.Config -import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.R -import com.gh.gamecenter.core.utils.SPUtils +import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.utils.tryWithDefaultCatch +import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.core.utils.SentryHelper import com.gh.gamecenter.user.LoginTag import com.halo.assistant.HaloApp @@ -130,8 +130,8 @@ object LoginHelper { } @JvmStatic - fun onWeiboLoginCallback(requestCode: Int, resultCode: Int, data: Intent?) { - mWBAPI.authorizeCallback(requestCode, resultCode, data) + fun onWeiboLoginCallback(activity: Activity, requestCode: Int, resultCode: Int, data: Intent?) { + mWBAPI.authorizeCallback(activity, requestCode, resultCode, data) } // QQ登录 @@ -186,7 +186,7 @@ object LoginHelper { context, AuthInfo(context, Config.WEIBO_APPKEY, "http://www.sina.com", WEIBO_SCOPE) ) - mWBAPI.authorizeClient(object : WbAuthListener { + mWBAPI.authorizeClient(context, object : WbAuthListener { override fun onComplete(token: Oauth2AccessToken?) { token?.let { RuntimeUtils.getInstance().runOnUiThread { diff --git a/app/src/main/java/com/gh/gamecenter/MainActivity.java b/app/src/main/java/com/gh/gamecenter/MainActivity.java index c90a427976..1c5f59eb8f 100644 --- a/app/src/main/java/com/gh/gamecenter/MainActivity.java +++ b/app/src/main/java/com/gh/gamecenter/MainActivity.java @@ -1012,18 +1012,8 @@ public class MainActivity extends BaseActivity { //需要提前初始化微博sdk,否则第一次分享或授权登录会失败 private void initWBSDK() { - try { - IWBAPI mWBAPI = WBAPIFactory.createWBAPI(this); - mWBAPI.registerApp(this, new AuthInfo(this, Config.WEIBO_APPKEY, "http://www.sina.com", WEIBO_SCOPE)); - } catch (Throwable e) { - // 微博 SDK 缺少 x86 的 so - // 所以 x86 的 AS 模拟器/ Genymotion 会初始化失败,但实测部分硬性需要提供 x86 SO 的模拟器 (如雷电) 却又能正常使用 - // 这里加个简单日志,看看到底有没有(有多少)真实设备出现初始化失败的问题 - if (!BuildConfig.DEBUG) { - SPUtils.setBoolean(Constants.SP_USER_NEED_WEIBO_X86_SO, true); - e.printStackTrace(); - } - } + IWBAPI mWBAPI = WBAPIFactory.createWBAPI(this); + mWBAPI.registerApp(this, new AuthInfo(this, Config.WEIBO_APPKEY, "http://www.sina.com", WEIBO_SCOPE)); } /** diff --git a/app/src/main/java/com/gh/gamecenter/WeiBoShareActivity.java b/app/src/main/java/com/gh/gamecenter/WeiBoShareActivity.java index bfcced577b..7d05b14748 100644 --- a/app/src/main/java/com/gh/gamecenter/WeiBoShareActivity.java +++ b/app/src/main/java/com/gh/gamecenter/WeiBoShareActivity.java @@ -204,7 +204,7 @@ public class WeiBoShareActivity extends Activity implements WbShareCallback { } // weiboMessage.mediaObject = webObject; - mWBAPI.shareMessage(weiboMessage, false); + mWBAPI.shareMessage(WeiBoShareActivity.this, weiboMessage, false); } @Override @@ -227,7 +227,7 @@ public class WeiBoShareActivity extends Activity implements WbShareCallback { WeiboMultiMessage weiboMessage = new WeiboMultiMessage();//初始化微博的分享消息 weiboMessage.imageObject = imageObject; - mWBAPI.shareMessage(weiboMessage, false); + mWBAPI.shareMessage(WeiBoShareActivity.this, weiboMessage, false); } public Bitmap compressBitmap(Bitmap bitmap) { diff --git a/app/src/main/java/com/gh/gamecenter/fragment/LoginFragment.java b/app/src/main/java/com/gh/gamecenter/fragment/LoginFragment.java index c8e314bef4..b82a1adc79 100644 --- a/app/src/main/java/com/gh/gamecenter/fragment/LoginFragment.java +++ b/app/src/main/java/com/gh/gamecenter/fragment/LoginFragment.java @@ -117,7 +117,7 @@ public class LoginFragment if (requestCode == com.tencent.connect.common.Constants.REQUEST_LOGIN) { // QQ Login callback LoginHelper.onQQLoginCallback(requestCode, resultCode, data); } else if (requestCode == 32973) { // WeiBo Login callback - LoginHelper.onWeiboLoginCallback(requestCode, resultCode, data); + LoginHelper.onWeiboLoginCallback(requireActivity(), requestCode, resultCode, data); } } diff --git a/app/src/main/java/com/gh/gamecenter/personal/NewPersonalFragment.kt b/app/src/main/java/com/gh/gamecenter/personal/NewPersonalFragment.kt index a4d5870858..5f8fd219a0 100644 --- a/app/src/main/java/com/gh/gamecenter/personal/NewPersonalFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/personal/NewPersonalFragment.kt @@ -93,7 +93,7 @@ class NewPersonalFragment : BaseLazyFragment() { onQQLoginCallback(requestCode, resultCode, data) } 32973 -> { - onWeiboLoginCallback(requestCode, resultCode, data) + onWeiboLoginCallback(requireActivity(), requestCode, resultCode, data) } REQUEST_MESSAGE -> { mUnreadViewModel.retry() diff --git a/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.kt b/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.kt index b27f514bda..33064af33c 100644 --- a/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/personal/PersonalFragment.kt @@ -12,31 +12,32 @@ import androidx.core.content.ContextCompat import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.gh.gamecenter.common.base.activity.BaseActivity -import com.gh.gamecenter.common.base.fragment.BaseLazyFragment import com.gh.common.databind.BindingAdapters import com.gh.common.util.* import com.gh.common.util.DirectUtils.directToBadgeDetail import com.gh.common.util.DirectUtils.directToBadgeWall import com.gh.common.util.DirectUtils.directToHomeActivity -import com.gh.gamecenter.common.utils.ImageUtils.display -import com.gh.gamecenter.common.utils.ImageUtils.displayIcon import com.gh.common.util.LoginHelper.onQQLoginCallback import com.gh.common.util.LoginHelper.onWeiboLoginCallback +import com.gh.gamecenter.MessageActivity +import com.gh.gamecenter.R +import com.gh.gamecenter.common.base.activity.BaseActivity +import com.gh.gamecenter.common.base.fragment.BaseLazyFragment +import com.gh.gamecenter.common.callback.ConfirmListener +import com.gh.gamecenter.common.retrofit.ApiResponse +import com.gh.gamecenter.common.utils.ImageUtils.display +import com.gh.gamecenter.common.utils.ImageUtils.displayIcon +import com.gh.gamecenter.common.utils.NetworkUtils +import com.gh.gamecenter.common.utils.PackageFlavorHelper +import com.gh.gamecenter.common.utils.toColor +import com.gh.gamecenter.common.utils.tryCatchInRelease +import com.gh.gamecenter.common.view.VerticalItemDecoration +import com.gh.gamecenter.core.utils.DisplayUtils import com.gh.gamecenter.core.utils.MtaHelper.onEvent import com.gh.gamecenter.core.utils.SPUtils.getLong import com.gh.gamecenter.core.utils.SPUtils.setLong import com.gh.gamecenter.core.utils.TimeUtils.getStartTimeOfDay import com.gh.gamecenter.core.utils.ToastUtils.showToast -import com.gh.gamecenter.common.view.VerticalItemDecoration -import com.gh.gamecenter.MessageActivity -import com.gh.gamecenter.R -import com.gh.gamecenter.common.callback.ConfirmListener -import com.gh.gamecenter.common.utils.NetworkUtils -import com.gh.gamecenter.common.utils.toColor -import com.gh.gamecenter.common.utils.tryCatchInRelease -import com.gh.gamecenter.common.utils.PackageFlavorHelper -import com.gh.gamecenter.core.utils.DisplayUtils import com.gh.gamecenter.databinding.FragmentPersonalBinding import com.gh.gamecenter.databinding.FragmentPersonalStubBinding import com.gh.gamecenter.entity.* @@ -50,7 +51,6 @@ import com.gh.gamecenter.message.MessageUnreadViewModel import com.gh.gamecenter.personal.NewPersonalActivity.Companion.getIntent import com.gh.gamecenter.personalhome.UserHomeViewModel import com.gh.gamecenter.room.AppDatabase -import com.gh.gamecenter.common.retrofit.ApiResponse import com.gh.gamecenter.user.UserViewModel import com.google.android.material.appbar.AppBarLayout import com.halo.assistant.HaloApp @@ -97,7 +97,7 @@ class PersonalFragment : BaseLazyFragment() { onQQLoginCallback(requestCode, resultCode, data) } 32973 -> { - onWeiboLoginCallback(requestCode, resultCode, data) + onWeiboLoginCallback(requireActivity(), requestCode, resultCode, data) } REQUEST_MESSAGE -> { mUnreadViewModel.retry() diff --git a/dependencies.gradle b/dependencies.gradle index d226e25735..6ca1a5d343 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -54,7 +54,7 @@ ext { switchButton = "1.4.5" swipeLayout = "1.2.0@aar" autoScrollViewPager = "1.1.2" - weiboSDK = "11.6.0@aar" + weiboSDK = "12.5.0@aar" apkChannelPackage = "1.0.5" //Test From 8d6628404c897fa10b26a39c16c09c0b3b92653c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Tue, 9 Aug 2022 16:26:32 +0800 Subject: [PATCH 164/217] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E4=B8=93?= =?UTF-8?q?=E5=8C=BA=E7=9F=AD=E9=93=BE=E6=8E=A5=E4=BD=BF=E7=94=A8webview?= =?UTF-8?q?=E6=89=93=E5=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/common/DefaultUrlHandler.kt | 3 +-- .../main/java/com/halo/assistant/fragment/WebFragment.kt | 7 ++----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/gh/common/DefaultUrlHandler.kt b/app/src/main/java/com/gh/common/DefaultUrlHandler.kt index c93dfdec95..31a5a16ff9 100644 --- a/app/src/main/java/com/gh/common/DefaultUrlHandler.kt +++ b/app/src/main/java/com/gh/common/DefaultUrlHandler.kt @@ -620,8 +620,7 @@ object DefaultUrlHandler { } //https://m.ghzs666.com/zone/游戏ID splits.size >= 3 && splits[1] == "zone" -> { - val gameId = splits[2] - DirectUtils.directGameZone(context, gameId, url, entrance) + DirectUtils.directToWebView(context, url, entrance) } //https://m.ghzs666.com/bbs/video-视频ID splits.size >= 3 && splits[1] == "bbs" && splits[2].startsWith("video-") -> { diff --git a/app/src/main/java/com/halo/assistant/fragment/WebFragment.kt b/app/src/main/java/com/halo/assistant/fragment/WebFragment.kt index 3158e03941..97fe420d1b 100644 --- a/app/src/main/java/com/halo/assistant/fragment/WebFragment.kt +++ b/app/src/main/java/com/halo/assistant/fragment/WebFragment.kt @@ -356,11 +356,8 @@ class WebFragment : LazyFragment(), IScrollable { newsWebview.webViewClient = object : WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean { return if (isAdded) { - // return DefaultWebViewUrlHandler.interceptUrl(requireContext(), url, mEntrance + "+(光环浏览器)"); - val b = interceptUrl( - requireContext(), url, - "$mEntrance+(光环浏览器)" - ) + val originalUrl = requireArguments().getString(EntranceConsts.KEY_URL, "") + val b = if (Uri.parse(originalUrl).path != Uri.parse(url).path) interceptUrl(requireContext(), url, "$mEntrance+(光环浏览器)") else false if (mIsOpenNativePage && !b) { startActivity( WebActivity.getIntent( From a4c7aa6338f978d1eb0b769667ed289cdb1d54d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Tue, 9 Aug 2022 16:42:34 +0800 Subject: [PATCH 165/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=B5=84?= =?UTF-8?q?=E8=AE=AF=E8=AF=A6=E6=83=85=E9=97=AA=E9=80=80=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/common/util/DetailDownloadUtils.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index be60b4b179..d7c7078d82 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -29,8 +29,9 @@ public class DetailDownloadUtils { public static void detailInitDownload(DetailViewHolder viewHolder, boolean isCheck) { String downloadAddWord = viewHolder.gameEntity.getDownloadAddWord(); - - viewHolder.getOverlayTv().setVisibility(View.GONE); + if (viewHolder.getOverlayTv() != null) { + viewHolder.getOverlayTv().setVisibility(View.GONE); + } if (viewHolder.gameEntity != null && Config.isShowDownload(viewHolder.gameEntity.getId()) @@ -75,7 +76,9 @@ public class DetailDownloadUtils { String downloadText; if (viewHolder.context.getString(R.string.launch).equals(status) || viewHolder.context.getString(R.string.install).equals(status) || viewHolder.context.getString(R.string.download).equals(status)) { downloadText = ""; - viewHolder.getOverlayTv().setVisibility(View.VISIBLE); + if (viewHolder.getOverlayTv() != null) { + viewHolder.getOverlayTv().setVisibility(View.VISIBLE); + } } else if (viewHolder.context.getString(R.string.attempt).equals(status)) { downloadText = status + getDownloadSizeText(viewHolder); } else { @@ -191,7 +194,9 @@ public class DetailDownloadUtils { } viewHolder.mDownloadPb.setProgress((int) (viewHolder.downloadEntity.getPercent() * 10)); - viewHolder.getOverlayTv().setVisibility(View.GONE); + if (viewHolder.getOverlayTv() != null) { + viewHolder.getOverlayTv().setVisibility(View.GONE); + } if (viewHolder.gameEntity.isVGame()) { updateVStyleButton(viewHolder); @@ -247,7 +252,9 @@ public class DetailDownloadUtils { } viewHolder.mDownloadPb.setText(""); - viewHolder.getOverlayTv().setVisibility(View.VISIBLE); + if (viewHolder.getOverlayTv() != null) { + viewHolder.getOverlayTv().setVisibility(View.VISIBLE); + } } } else { if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL)) { @@ -305,7 +312,9 @@ public class DetailDownloadUtils { } viewHolder.mDownloadPb.setText(""); - viewHolder.getOverlayTv().setVisibility(View.VISIBLE); + if (viewHolder.getOverlayTv() != null) { + viewHolder.getOverlayTv().setVisibility(View.VISIBLE); + } } break; default: From 2bf662ee27188080b778c969d9511df5d627dd04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E5=AD=90=E7=BB=B4?= Date: Thu, 11 Aug 2022 16:00:40 +0800 Subject: [PATCH 166/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E6=B8=B8=E6=88=8F=E5=A4=A7=E5=9B=BE=E5=8D=A1=E7=89=87?= =?UTF-8?q?=E5=89=AF=E6=A0=87=E9=A2=98=E8=B6=85=E9=95=BF=E6=97=B6=E4=B8=8E?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E6=8C=89=E9=92=AE=E9=87=8D=E5=8F=A0=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt | 4 ++-- app/src/main/res/layout/home_game_item.xml | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt index b724c6b42c..860a4ddced 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt @@ -49,8 +49,8 @@ class HomeGameItemViewHolder(val binding: HomeGameItemBinding) : BaseRecyclerVie } } } - binding.gameTags.post { - binding.gameSubtitleTv.maxWidth = binding.gameTags.width + 24F.dip2px() + binding.ratingAndTagContainer.post { + binding.gameSubtitleTv.maxWidth = binding.ratingAndTagContainer.width + 32F.dip2px() } } if (game.advanceDownload) { diff --git a/app/src/main/res/layout/home_game_item.xml b/app/src/main/res/layout/home_game_item.xml index d7026feb4c..8c20b64789 100644 --- a/app/src/main/res/layout/home_game_item.xml +++ b/app/src/main/res/layout/home_game_item.xml @@ -60,6 +60,7 @@ android:layout_marginStart="4dp" android:layout_marginLeft="4dp" android:layout_marginEnd="8dp" + android:layout_marginRight="8dp" android:background="@drawable/bg_advance_download_game_subtitle" android:paddingStart="2dp" android:paddingEnd="2dp" @@ -68,13 +69,14 @@ android:textSize="@dimen/tag_text_size" android:visibility="gone" app:layout_constraintBottom_toBottomOf="@+id/game_name" - app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintEnd_toStartOf="@+id/download_btn" app:layout_constraintStart_toEndOf="@+id/game_name" app:layout_constraintTop_toTopOf="@+id/game_name" app:layout_goneMarginStart="0dp" tools:text="副标题" /> Date: Mon, 15 Aug 2022 09:53:30 +0800 Subject: [PATCH 167/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E8=B7=AF=E5=BE=84=E4=B8=BA=E7=A9=BA=E6=97=B6=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E4=B8=8B=E8=BD=BD=E8=A7=A6=E5=8F=91=E7=9A=84=E9=97=AA?= =?UTF-8?q?=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/common/util/PackageInstaller.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/PackageInstaller.kt b/app/src/main/java/com/gh/common/util/PackageInstaller.kt index 7e86761029..ed6e585c6f 100644 --- a/app/src/main/java/com/gh/common/util/PackageInstaller.kt +++ b/app/src/main/java/com/gh/common/util/PackageInstaller.kt @@ -13,6 +13,7 @@ import com.gh.common.xapk.XapkInstaller import com.gh.download.server.BrowserInstallHelper import com.gh.gamecenter.BuildConfig import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.retrofit.BiResponse import com.gh.gamecenter.common.utils.DialogHelper import com.gh.gamecenter.common.utils.getExtension import com.gh.gamecenter.common.utils.toRequestBody @@ -20,7 +21,6 @@ import com.gh.gamecenter.core.utils.CurrentActivityHolder import com.gh.gamecenter.core.utils.MD5Utils import com.gh.gamecenter.core.utils.SPUtils import com.gh.gamecenter.core.utils.ToastUtils -import com.gh.gamecenter.common.retrofit.BiResponse import com.gh.gamecenter.retrofit.RetrofitManager import com.halo.assistant.HaloApp import com.lightgame.download.DownloadEntity @@ -88,7 +88,12 @@ object PackageInstaller { * 除非你已经确定该文件一定是Apk */ @JvmStatic - fun install(context: Context, isPluggin: Boolean = false, pkgPath: String) { + fun install(context: Context, isPluggin: Boolean = false, pkgPath: String?) { + if (pkgPath.isNullOrEmpty()) { + ToastUtils.toast("下载文件异常") + return + } + try { // 判断是否需要使用浏览器来进行安装 if (BrowserInstallHelper.isUseBrowserToInstallEnabled() From b169ce66b43290a68009380fec37c30b07a5f65a Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Mon, 15 Aug 2022 09:56:10 +0800 Subject: [PATCH 168/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=83=A8?= =?UTF-8?q?=E5=88=86=E8=AE=BE=E5=A4=87=E8=8E=B7=E5=8F=96=E5=B7=B2=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E4=BF=A1=E6=81=AF=E6=97=B6=E4=BC=9A=E9=97=AA=E9=80=80?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/common/util/PackageUtils.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/PackageUtils.java b/app/src/main/java/com/gh/common/util/PackageUtils.java index 0b6332d43d..1c47212c0c 100644 --- a/app/src/main/java/com/gh/common/util/PackageUtils.java +++ b/app/src/main/java/com/gh/common/util/PackageUtils.java @@ -472,8 +472,14 @@ public class PackageUtils { * 注意:目测只对能启动的app有效(有桌面图标),对一些没有桌面图标的应用无效(参考应用:魅族游戏框架) */ public static boolean isInstalled(Context context, String packageName) { - Intent intent = context.getApplicationContext().getPackageManager().getLaunchIntentForPackage(packageName); - return intent != null; + try { + Intent intent = context.getApplicationContext().getPackageManager().getLaunchIntentForPackage(packageName); + return intent != null; + } catch (IllegalArgumentException exception) { + // 一些设备调用获取 intent 的时候会触发 Parcel.readException ! + exception.printStackTrace(); + return false; + } } public static boolean isInstalledFromAllPackage(Context context, String packageName) { From 17ad25aff373831b7153e0f5396b4303ca84111a Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Mon, 15 Aug 2022 10:00:42 +0800 Subject: [PATCH 169/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E8=AF=A6=E6=83=85=E9=A1=B5=E7=82=B9=E5=87=BB=E5=85=B3?= =?UTF-8?q?=E9=97=AD=E4=B8=8B=E8=BD=BD=E7=9A=84=E4=B8=8B=E8=BD=BD=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E4=BC=9A=E9=97=AA=E9=80=80=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/gamecenter/adapter/viewholder/DetailViewHolder.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java index 3eca397f7b..4c037b002c 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java @@ -151,7 +151,9 @@ public class DetailViewHolder { MtaHelper.onEvent("游戏详情_新", "预约", mGameEntity.getName()); break; case LAUNCH_OR_OPEN: - EnergyTaskHelper.postEnergyTask("play_game", mGameEntity.getId(), mGameEntity.getApk().get(0).getPackageName()); + if (!mGameEntity.getApk().isEmpty()) { + EnergyTaskHelper.postEnergyTask("play_game", mGameEntity.getId(), mGameEntity.getApk().get(0).getPackageName()); + } break; } // 由于部分状态不包含在 downloadType 里,所以还是需要手动获取下载按钮文字判断点击时的状态 From 61f77a6fcc94592cbb16559d32d48bb61d9c5a7a Mon Sep 17 00:00:00 2001 From: guotao Date: Mon, 15 Aug 2022 11:32:02 +0800 Subject: [PATCH 170/217] =?UTF-8?q?fix:=E6=9C=AC=E5=9C=B0=E5=AE=9E?= =?UTF-8?q?=E5=90=8D=E8=AE=A4=E8=AF=81=E6=8F=92=E5=85=A5=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E6=94=B9=E4=B8=BAcontentProvider=E6=8F=92=E5=85=A5?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E5=9C=A8Manifest=E5=8A=A0=E5=85=A5queries?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 3 ++ .../java/com/gh/common/util/DataUtils.java | 4 +-- .../gamecenter/provider/GhContentProvider.kt | 33 ++++++++++--------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 09b9b95b80..d2212b15bf 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,9 @@ xmlns:tools="http://schemas.android.com/tools" package="com.gh.gamecenter"> + + + diff --git a/app/src/main/java/com/gh/common/util/DataUtils.java b/app/src/main/java/com/gh/common/util/DataUtils.java index 065b1bb468..c0eb1c61a6 100644 --- a/app/src/main/java/com/gh/common/util/DataUtils.java +++ b/app/src/main/java/com/gh/common/util/DataUtils.java @@ -161,8 +161,8 @@ public class DataUtils { values.put(GhContentProvider.KEY_IS_ADULT, false); } - new GhContentProvider().localInsert( HaloApp.getInstance().getApplication(),values); -// HaloApp.getInstance().getContentResolver().insert(Uri.parse("content://com.gh.gamecenter.provider/certification"), values); +// new GhContentProvider().localInsert( HaloApp.getInstance().getApplication(),values); + HaloApp.getInstance().getContentResolver().insert(Uri.parse("content://com.gh.gamecenter.provider/certification"), values); } }); } diff --git a/app/src/main/java/com/gh/gamecenter/provider/GhContentProvider.kt b/app/src/main/java/com/gh/gamecenter/provider/GhContentProvider.kt index 91129dcc8b..006c56e97a 100644 --- a/app/src/main/java/com/gh/gamecenter/provider/GhContentProvider.kt +++ b/app/src/main/java/com/gh/gamecenter/provider/GhContentProvider.kt @@ -28,6 +28,7 @@ class GhContentProvider : ContentProvider() { } private fun initProviderSqliteHelper(context: Context?){ + val helper: SQLiteOpenHelper = object : SQLiteOpenHelper(context, CERTIFICATION_DATABASE_NAME, null, 1) { override fun onCreate(db: SQLiteDatabase) { @@ -94,22 +95,22 @@ class GhContentProvider : ContentProvider() { - fun localInsert(context: Context,values: ContentValues?){ - initProviderSqliteHelper(context) - try { - values?.put(KEY_PRIMARY_KEY, 1) - // 如果已存在则直接替换 - mSqLiteDatabase?.insertWithOnConflict( - CERTIFICATION_TABLE_NAME, - null, - values, - SQLiteDatabase.CONFLICT_REPLACE - ) - - } catch (e: SQLiteFullException) { - Utils.toast(context,"数据库内存已满,无法同步") - } - } +// fun localInsert(context: Context,values: ContentValues?){ +// initProviderSqliteHelper(context) +// try { +// values?.put(KEY_PRIMARY_KEY, 1) +// // 如果已存在则直接替换 +// mSqLiteDatabase?.insertWithOnConflict( +// CERTIFICATION_TABLE_NAME, +// null, +// values, +// SQLiteDatabase.CONFLICT_REPLACE +// ) +// +// } catch (e: SQLiteFullException) { +// Utils.toast(context,"数据库内存已满,无法同步") +// } +// } override fun insert(uri: Uri, values: ContentValues?): Uri? { val context = context ?: return null From 2920ca4975c57aa5b3a2630fc4e6689a099127e6 Mon Sep 17 00:00:00 2001 From: liuyirong Date: Mon, 15 Aug 2022 16:12:08 +0800 Subject: [PATCH 171/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=94=B3?= =?UTF-8?q?=E8=AF=B7=E6=9D=83=E9=99=90=E5=90=8E=E9=97=AA=E9=80=80=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/gh/common/provider/ActivationProviderImpl.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/common/provider/ActivationProviderImpl.kt b/app/src/main/java/com/gh/common/provider/ActivationProviderImpl.kt index 4c7fa2f3b8..a172d9cc2e 100644 --- a/app/src/main/java/com/gh/common/provider/ActivationProviderImpl.kt +++ b/app/src/main/java/com/gh/common/provider/ActivationProviderImpl.kt @@ -7,7 +7,7 @@ import com.gh.gamecenter.common.constant.RouteConsts import com.gh.gamecenter.core.provider.IActivationProvider @Route(path = RouteConsts.provider.activation, name = "ActivationHelper暴露服务") -interface ActivationProviderImpl : IActivationProvider { +class ActivationProviderImpl : IActivationProvider { override fun init(context: Context?) { } From 9780aa532af75d46304aeba01249f14ab5944540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Tue, 16 Aug 2022 10:02:02 +0800 Subject: [PATCH 172/217] =?UTF-8?q?fix:=20=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E5=90=8C=E6=AD=A5=E6=AD=A3?= =?UTF-8?q?=E5=BC=8F=E7=8E=AF=E5=A2=83=E5=90=8E=E6=B5=8B=E8=AF=95=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E6=B1=87=E6=80=BB(5)=20https://git.shanqu.cc/pm/halo/?= =?UTF-8?q?halo-app-issues/-/issues/2021?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/home_game_item.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/layout/home_game_item.xml b/app/src/main/res/layout/home_game_item.xml index 8c20b64789..c6fc553004 100644 --- a/app/src/main/res/layout/home_game_item.xml +++ b/app/src/main/res/layout/home_game_item.xml @@ -96,7 +96,8 @@ android:drawablePadding="4dp" android:includeFontPadding="false" android:textColor="@color/theme" - android:textSize="18sp" + android:textSize="12sp" + android:gravity="center" android:textStyle="bold" tools:text="9.3" /> From 28744ce9ced52cc586a5061f40151cddf7c6e53d Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Tue, 16 Aug 2022 17:07:33 +0800 Subject: [PATCH 173/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E6=B8=B8=E6=88=8F=E6=9B=B4=E6=96=B0=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E5=9C=A8=E5=88=97=E8=A1=A8=E6=98=BE=E7=A4=BA=E8=BF=9B=E5=BA=A6?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20https://git.shanqu.cc/pm/halo/hal?= =?UTF-8?q?o-app-issues/-/issues/2027?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/common/util/PackageUtils.java | 1 + app/src/main/java/com/gh/common/util/PlatformUtils.java | 5 +++-- app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt | 2 +- app/src/main/java/com/gh/vspace/VHelper.kt | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/PackageUtils.java b/app/src/main/java/com/gh/common/util/PackageUtils.java index 5cf9c236ce..b053bab97f 100644 --- a/app/src/main/java/com/gh/common/util/PackageUtils.java +++ b/app/src/main/java/com/gh/common/util/PackageUtils.java @@ -133,6 +133,7 @@ public class PackageUtils { if (vGameEntity != null) { String md5FromInstalledVGame = ExtensionsKt.getMetaExtra(vGameEntity.getDownloadEntity(), Constants.APK_MD5); String md5FromRequest = apkEntity.getMd5(); + apkEntity.setPlatform(VHelper.PLATFORM_V); shouldShowUpdate = md5FromRequest != null && !md5FromRequest.equals(md5FromInstalledVGame); } else { diff --git a/app/src/main/java/com/gh/common/util/PlatformUtils.java b/app/src/main/java/com/gh/common/util/PlatformUtils.java index a32c2cc62b..b80a7223dd 100644 --- a/app/src/main/java/com/gh/common/util/PlatformUtils.java +++ b/app/src/main/java/com/gh/common/util/PlatformUtils.java @@ -12,6 +12,7 @@ import com.gh.gamecenter.entity.PlatformEntity; import com.gh.gamecenter.eventbus.EBReuse; import com.gh.gamecenter.common.retrofit.Response; import com.gh.gamecenter.retrofit.RetrofitManager; +import com.gh.vspace.VHelper; import com.halo.assistant.HaloApp; import com.lightgame.download.FileUtils; @@ -187,8 +188,8 @@ public class PlatformUtils { return "官方版"; } - if ("畅玩版".equals(platform)) { - return "畅玩版"; + if (VHelper.PLATFORM_V.equals(platform)) { + return VHelper.PLATFORM_V; } String platformName = platformMap.get(platform); diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt index 053666cc1b..50487a0be9 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt @@ -497,7 +497,7 @@ data class GameEntity( if (isVGame()) { rawApk.forEach { - it.setPlatform("畅玩版") + it.setPlatform(VHelper.PLATFORM_V) it.url = VHelper.getVUrl(it.url) } } diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 897899b6cd..166711ac34 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -62,6 +62,7 @@ object VHelper { private const val KEY_LAST_ALERT_UPDATE_URL = "last_alert_update_url" const val DEFAULT_VSPACE_PACKAGENAME = "com.lg.vspace" + const val PLATFORM_V = "畅玩版" private val mDelegateManager by lazy { VirtualAppManager.get() } private var mInstalledInfoList: List = arrayListOf() From 0752813c0954d3835532a3cfc009bc3da8c7faf8 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Tue, 16 Aug 2022 17:33:37 +0800 Subject: [PATCH 174/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E9=85=8D=E7=BD=AE=E4=B8=BA=E7=A9=BA=E6=97=B6=E7=9A=84?= =?UTF-8?q?=E9=97=AA=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VHelper.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 166711ac34..5842936380 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -46,6 +46,7 @@ import com.halo.assistant.HaloApp import com.lg.vspace.VirtualAppManager import com.lg.vspace.remote.listener.RemoteConnectListener import com.lg.vspace.remote.model.AppInstallerInfo +import com.lg.vspace.remote.BinderPool import com.lightgame.download.DownloadEntity import com.lightgame.utils.AppManager import com.lightgame.utils.Utils @@ -109,7 +110,9 @@ object VHelper { mIsInitialized = true val config = Config.getVSettingEntity()?.va - if (config != null && PackageUtils.isInstalled(context, config.arch64?.packageName)) { + if (config != null + && config.arch64 != null + && PackageUtils.isInstalled(context, config.arch64?.packageName)) { connectService(true) // 检查畅玩助手组件更新 @@ -141,6 +144,9 @@ object VHelper { } override fun onServiceConnectionFailed(failCode: Int) { + if (failCode == BinderPool.CONNECT_STATE_NOT_INSTALLED) { + ToastUtils.toast("请先安装畅玩助手") + } Utils.log(LOG_TAG, "V 服务连接失败") } }) From d9665a8464a6a177f129f0cf0c99dd902bd21d29 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Wed, 17 Aug 2022 10:46:36 +0800 Subject: [PATCH 175/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E5=90=AF=E5=8A=A8=E6=97=B6=E6=B2=A1=E6=9C=89=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E7=95=85=E7=8E=A9=E5=8A=A9=E6=89=8B=E4=B9=9F=E4=BC=9A?= =?UTF-8?q?=E5=87=BA=E5=8F=91=E8=BF=9E=E6=8E=A5=E5=B0=9D=E8=AF=95=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/vspace/VDownloadManagerWrapperFragment.kt | 3 +++ app/src/main/java/com/gh/vspace/VHelper.kt | 8 +++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt index a5d4251e03..540afb99b1 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt @@ -46,6 +46,9 @@ class VDownloadManagerWrapperFragment: BaseLazyTabFragment() { ManageOption.OPTION_CANCEL_SELECT -> { mViewModel.currentOptionLiveData.value = ManageOption.OPTION_MANAGER } + else -> { + // do nothing + } } changeOption() } diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 5842936380..f57bc6cc1b 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -110,13 +110,12 @@ object VHelper { mIsInitialized = true val config = Config.getVSettingEntity()?.va - if (config != null - && config.arch64 != null - && PackageUtils.isInstalled(context, config.arch64?.packageName)) { + if (config?.arch64 != null + && PackageUtils.isInstalled(context, config.arch64.packageName)) { connectService(true) // 检查畅玩助手组件更新 - checkVSpaceUpdate(config.arch64!!) + checkVSpaceUpdate(config.arch64) } PackageObserver.registerPackageChangeChangeListener(mPackageObserver) @@ -831,7 +830,6 @@ object VHelper { @JvmStatic fun recoverVDataIfPossible() { VBackupHelper.recoverValidData(HaloApp.getInstance()) - connectService() } fun getVUrl(originUrl: String?): String { From 3f2b59aecf50bcf355cce48f1d9a435aa242241e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Wed, 17 Aug 2022 15:48:51 +0800 Subject: [PATCH 176/217] =?UTF-8?q?fix:=20=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8BV5.12.0=E3=80=91=E5=90=8C=E6=AD=A5=E6=AD=A3?= =?UTF-8?q?=E5=BC=8F=E7=8E=AF=E5=A2=83=E5=90=8E=E6=B5=8B=E8=AF=95=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E6=B1=87=E6=80=BB(5)=20https://git.shanqu.cc/pm/halo/?= =?UTF-8?q?halo-app-issues/-/issues/2021?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gamecenter/home/HomeGameItemViewHolder.kt | 7 ++++++- app/src/main/res/layout/home_game_item.xml | 21 +++++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt index 860a4ddced..35d252c13e 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt @@ -21,8 +21,11 @@ class HomeGameItemViewHolder(val binding: HomeGameItemBinding) : BaseRecyclerVie binding.gameName.text = game.name binding.gameName.setTextColor(R.color.text_title.toColor(binding.root.context)) binding.gameBrief.setTextColor(R.color.text_title.toColor(binding.root.context)) - binding.gameRating.goneIf(!(game.showComment && game.commentCount >= 3 && game.star >= 7)) binding.gameRating.text = game.star.toString() + binding.gameRating2.text = game.star.toString() + val drawable = R.drawable.home_game_rating.toDrawable(binding.root.context) + drawable?.setBounds(0, 0, 12F.dip2px(), 12F.dip2px()) + binding.gameRating.setCompoundDrawables(drawable, null, null, null) ImageUtils.display(binding.gameImage, game.homeSetting.image) binding.gameTags.postDelayed({ binding.gameTags.visibility = if (game.tagStyle.isNotEmpty()) { @@ -90,5 +93,7 @@ class HomeGameItemViewHolder(val binding: HomeGameItemBinding) : BaseRecyclerVie ) DownloadItemUtils.updateDownloadButton(binding.root.context, binding.downloadBtn, game) binding.downloadBtn.goneIf(game.homeSetting.downloadBtnSwitch != "on") + binding.gameRating.goneIf(!(game.showComment && game.commentCount >= 3 && game.star >= 7 && game.homeSetting.downloadBtnSwitch == "on")) + binding.gameRating2.goneIf(!(game.showComment && game.commentCount >= 3 && game.star >= 7 && game.homeSetting.downloadBtnSwitch != "on")) } } \ No newline at end of file diff --git a/app/src/main/res/layout/home_game_item.xml b/app/src/main/res/layout/home_game_item.xml index c6fc553004..0d05579e62 100644 --- a/app/src/main/res/layout/home_game_item.xml +++ b/app/src/main/res/layout/home_game_item.xml @@ -92,12 +92,11 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="8dp" - android:drawableLeft="@drawable/home_game_rating" android:drawablePadding="4dp" + android:gravity="center" android:includeFontPadding="false" android:textColor="@color/theme" android:textSize="12sp" - android:gravity="center" android:textStyle="bold" tools:text="9.3" /> @@ -123,6 +122,24 @@ app:layout_constraintTop_toTopOf="parent" tools:visibility="visible" /> + + Date: Wed, 17 Aug 2022 16:57:00 +0800 Subject: [PATCH 177/217] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E6=B8=B8=E6=88=8F=E5=8D=A1=E7=89=87=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E4=B8=8D=E4=BC=9A=E6=A0=B9=E6=8D=AE=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E7=8A=B6=E6=80=81=E5=8F=98=E6=9B=B4=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index efd1efdca4..5833ba6f28 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -105,7 +105,8 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { fun refreshRecentVGameIfNeeded() { if (VHelper.isVGameOn() - && SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, true)) { + && SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, true) + ) { val entityList = getSortedVEntityList() if (entityList.isNotEmpty()) { @@ -132,7 +133,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { * 完成下载但未启动过的游戏:按照点击下载的时间倒序排列 * 完成下载且已启动过的游戏:按照游戏的畅玩时长从左(长)向右(短)排列 */ - private fun getSortedVEntityList() : List { + private fun getSortedVEntityList(): List { val rawDownloadEntityList = DownloadManager.getInstance().allVDownloadTaskSnapshots val rawInstalledEntityList = VHelper.getAllVGameSnapshots() val rawEntityList = arrayListOf() @@ -439,6 +440,9 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { attachGame.attachGame?.linkGame?.outerSequence = attachGame.blockPosition attachGame.attachGame?.linkGame?.sequence = attachGame.blockPosition mSnapshotItemList.add(attachGame) + homeContent.linkGame?.let { + addGamePositionAndPackage(it) + } } else if (linkType == "top_game_comment") { val head = HomeItemData() head.columnHead = SubjectEntity(type = linkType, name = "安利墙") From 6b6a7dd81e8fd3f10ffe51958a4cd089d35008c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E5=AD=90=E7=BB=B4?= Date: Wed, 17 Aug 2022 17:43:56 +0800 Subject: [PATCH 178/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E6=B8=B8=E6=88=8F=E7=AE=A1=E7=90=86=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?lottie=E5=BC=80=E5=85=B3=E5=8A=A8=E7=94=BB=E9=97=AA=E9=80=80?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index 2a67d89ad1..f0333cabab 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -81,9 +81,7 @@ class VDownloadManagerFragment : switchIv.setOnClickListener { if (lottieView.isAnimating) return@setOnClickListener val status = switchIv.isChecked - val anime = - if (status) "lottie/switch_turnoff.json" else "lottie/switch_turnon.json" - lottieView.setAnimation(anime) + lottieView.setSwitchAnimation(status) lottieView.doOnAnimationEnd { switchIv.isChecked = !status } From 793f2f241abfb6ce3017f8a1ba40422a07e7af13 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Wed, 17 Aug 2022 17:59:44 +0800 Subject: [PATCH 179/217] =?UTF-8?q?fix:=20=E6=B8=85=E7=90=86=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E7=AE=A1=E7=90=86=E5=86=97=E4=BD=99=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt index f0333cabab..e3a1b0b5c1 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerFragment.kt @@ -77,7 +77,6 @@ class VDownloadManagerFragment : switchIv.enlargeTouchArea() hintTv.text = "首页展示“最近在玩”板块" switchIv.isChecked = SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, true) - switchIv.enlargeTouchArea() switchIv.setOnClickListener { if (lottieView.isAnimating) return@setOnClickListener val status = switchIv.isChecked From 6e2ec70434e6830bd0c87614144675b93e19d1c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Wed, 17 Aug 2022 18:43:09 +0800 Subject: [PATCH 180/217] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E6=B8=B8=E6=88=8F=E5=8D=A1=E7=89=87=E6=A0=87=E9=A2=98?= =?UTF-8?q?=E5=B8=83=E5=B1=80=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/gamecenter/home/HomeGameItemViewHolder.kt | 14 ++++++++++++++ app/src/main/res/layout/home_game_item.xml | 1 - 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt index 35d252c13e..a163d4af31 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeGameItemViewHolder.kt @@ -4,6 +4,7 @@ import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.graphics.drawable.GradientDrawable import android.view.View +import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet import androidx.recyclerview.widget.RecyclerView import com.gh.common.util.DownloadItemUtils @@ -95,5 +96,18 @@ class HomeGameItemViewHolder(val binding: HomeGameItemBinding) : BaseRecyclerVie binding.downloadBtn.goneIf(game.homeSetting.downloadBtnSwitch != "on") binding.gameRating.goneIf(!(game.showComment && game.commentCount >= 3 && game.star >= 7 && game.homeSetting.downloadBtnSwitch == "on")) binding.gameRating2.goneIf(!(game.showComment && game.commentCount >= 3 && game.star >= 7 && game.homeSetting.downloadBtnSwitch != "on")) + ConstraintSet().apply { + clone(binding.gameSubtitleTv.parent as ConstraintLayout) + clear(binding.gameSubtitleTv.id, ConstraintSet.END) + if (binding.downloadBtn.visibility == View.VISIBLE) { + connect(binding.gameSubtitleTv.id, ConstraintSet.END, binding.downloadBtn.id, ConstraintSet.START) + } else if (binding.gameRating2.visibility == View.VISIBLE) { + connect(binding.gameSubtitleTv.id, ConstraintSet.END, binding.gameRating2.id, ConstraintSet.START) + } else { + connect(binding.gameSubtitleTv.id, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END) + } + setMargin(binding.gameSubtitleTv.id, ConstraintSet.END, 8F.dip2px()) + applyTo(binding.gameSubtitleTv.parent as ConstraintLayout) + } } } \ No newline at end of file diff --git a/app/src/main/res/layout/home_game_item.xml b/app/src/main/res/layout/home_game_item.xml index 0d05579e62..dc149733d6 100644 --- a/app/src/main/res/layout/home_game_item.xml +++ b/app/src/main/res/layout/home_game_item.xml @@ -112,7 +112,6 @@ style="@style/PrimaryGradientButton" android:layout_width="60dp" android:layout_height="28dp" - android:layout_marginLeft="8dp" android:gravity="center" android:text="@string/download" android:textSize="12sp" From 19bb89b6f118d6531aa71274be8bd59e551f9ad7 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Thu, 18 Aug 2022 11:31:10 +0800 Subject: [PATCH 181/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E5=88=97=E8=A1=A8=E5=88=B7=E6=96=B0=E6=97=B6=E5=81=B6?= =?UTF-8?q?=E5=8F=91=E7=9A=84=E5=BC=82=E5=B8=B8=E9=97=AA=E7=83=81=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/gamecenter/baselist/DiffUtilAdapter.kt | 22 +------------------ 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/baselist/DiffUtilAdapter.kt b/app/src/main/java/com/gh/gamecenter/baselist/DiffUtilAdapter.kt index 45c2b59719..bda46c9035 100644 --- a/app/src/main/java/com/gh/gamecenter/baselist/DiffUtilAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/baselist/DiffUtilAdapter.kt @@ -24,12 +24,6 @@ abstract class DiffUtilAdapter(context: Context) : // 这里用新的数组包裹原数据 val updateDataCopy = ArrayList(updateData) - if (mDataList.size > updateData.size) { - mDataList = updateDataCopy - notifyDataSetChanged() - return - } - ListExecutor.workerExecutor.execute { val diffResult = DiffUtil.calculateDiff(object : DiffUtil.Callback() { override fun getOldListSize(): Int { @@ -41,13 +35,6 @@ abstract class DiffUtilAdapter(context: Context) : } override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { - if (oldItemPosition != newItemPosition - || oldItemPosition >= mDataList.size - || newItemPosition >= updateDataCopy.size - ) { - return false - } - val oldItem = mDataList.safelyGetInRelease(oldItemPosition) val newItem = updateDataCopy.safelyGetInRelease(newItemPosition) return areItemsTheSame(oldItem, newItem) @@ -57,9 +44,6 @@ abstract class DiffUtilAdapter(context: Context) : oldItemPosition: Int, newItemPosition: Int ): Boolean { - if (oldItemPosition >= mDataList.size) return false - if (newItemPosition >= updateDataCopy.size) return false - val oldItem = mDataList.safelyGetInRelease(oldItemPosition) val newItem = updateDataCopy.safelyGetInRelease(newItemPosition) return areContentsTheSame(oldItem, newItem) @@ -67,11 +51,7 @@ abstract class DiffUtilAdapter(context: Context) : }) ListExecutor.uiExecutor.execute { mDataList = ArrayList(updateData) - if (diffResult != null) { - diffResult.dispatchUpdatesTo(this@DiffUtilAdapter) - } else { - notifyDataSetChanged() - } + diffResult.dispatchUpdatesTo(this@DiffUtilAdapter) } } } From 51c75947c94f1f55bb70a24522010f396732b47a Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Thu, 18 Aug 2022 11:38:32 +0800 Subject: [PATCH 182/217] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E9=83=A8=E5=88=86=E5=86=97=E4=BD=99=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt b/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt index 2ed211ed8b..b7efd9ebed 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt @@ -88,10 +88,8 @@ class HomeFragment : LazyFragment() { reuseLoading.root.goneIf(loadStatus != LoadStatus.INIT_LOADING) } mListAdapter.setLoadStatus(it) - mBinding.reuseNoConnection.root.visibility = if (it == LoadStatus.INIT_FAILED) View.VISIBLE else View.GONE - mBinding.reuseLoading.root.visibility = if (it == LoadStatus.INIT_LOADING) View.VISIBLE else View.GONE if (it == LoadStatus.INIT_LOADED) { - AppExecutor.uiExecutor.executeWithDelay(Runnable { + AppExecutor.uiExecutor.executeWithDelay({ scroll() mScrollCalculatorHelper.onScrollStateChanged( mBinding.gameList, @@ -117,13 +115,8 @@ class HomeFragment : LazyFragment() { R.color.theme ) ) - val loadStatus = LoadStatus.LIST_LOADED mBinding.run { BindingAdapters.isRefreshing(gameRefresh, LoadStatus.LIST_LOADED) - gameRefresh.goneIf(loadStatus == LoadStatus.INIT_FAILED) - gameList.goneIf(loadStatus == LoadStatus.INIT_LOADING) - reuseNoConnection.root.goneIf(loadStatus != LoadStatus.INIT_FAILED) - reuseLoading.root.goneIf(loadStatus != LoadStatus.INIT_LOADING) } mAutomaticLayoutManager = OffsetLinearLayoutManager(requireContext()) mLayoutManager = mAutomaticLayoutManager From 3a4b3326e78c2f3495e024f8ff749b86efd0fccc Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Thu, 18 Aug 2022 11:39:08 +0800 Subject: [PATCH 183/217] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E6=9C=80=E8=BF=91=E5=9C=A8=E7=8E=A9=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E7=9A=84=E5=86=97=E4=BD=99=E5=88=B7=E6=96=B0=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt index ae78ad606e..e81c92248d 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt @@ -277,7 +277,9 @@ class HomeFragmentAdapter( } homeItemData.exposureEventList = exposureEventList - holder.bindView(homeItemData.recentVGame!!) + if (!homeItemData.recentVGame.isNullOrEmpty()) { + holder.bindView(homeItemData.recentVGame!!) + } } private fun bindAttachGame(holder: HomeGameItemViewHolder, position: Int) { From 6cc2f3af264dd881364792af072b5e08f81b87d3 Mon Sep 17 00:00:00 2001 From: liuyirong Date: Thu, 18 Aug 2022 14:23:23 +0800 Subject: [PATCH 184/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=A4=BE?= =?UTF-8?q?=E5=8C=BA-=E8=AE=BA=E5=9D=9B-=E7=83=AD=E9=97=A8=E8=AE=BA?= =?UTF-8?q?=E5=9D=9B=E7=9A=84Item=E9=9C=80=E8=A6=81=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E4=B8=A4=E6=AC=A1=E6=89=8D=E8=83=BD=E8=B7=B3=E8=BD=AC=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../forum/home/HorizontalForumsAdapter.kt | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/HorizontalForumsAdapter.kt b/app/src/main/java/com/gh/gamecenter/forum/home/HorizontalForumsAdapter.kt index 2351160541..c56f3bc671 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/home/HorizontalForumsAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/home/HorizontalForumsAdapter.kt @@ -74,7 +74,7 @@ class HorizontalForumsAdapter( } root.setOnClickListener { - handleItemViewClick(this, forumEntity) + handleItemViewClick(forumEntity) } } } @@ -107,14 +107,12 @@ class HorizontalForumsAdapter( } } - private fun handleItemViewClick(binding: HorizontalForumItemBinding, forumEntity: ForumEntity) { - binding.root.setOnClickListener { - val bbsType = if (forumEntity.type == "official_bbs") "综合论坛" else "游戏论坛" - val event = if (mEntrance.contains("最近浏览")) "click_recent_forum" else "click_following_forum" - val location = if (mEntrance.contains("最近浏览")) "推荐信息流" else "论坛页" - NewLogUtils.logForumClick(event, location, forumEntity.id, bbsType) - mContext.startActivity(ForumDetailActivity.getIntent(mContext, forumEntity.id, mEntrance)) - } + private fun handleItemViewClick(forumEntity: ForumEntity) { + val bbsType = if (forumEntity.type == "official_bbs") "综合论坛" else "游戏论坛" + val event = if (mEntrance.contains("最近浏览")) "click_recent_forum" else "click_following_forum" + val location = if (mEntrance.contains("最近浏览")) "推荐信息流" else "论坛页" + NewLogUtils.logForumClick(event, location, forumEntity.id, bbsType) + mContext.startActivity(ForumDetailActivity.getIntent(mContext, forumEntity.id, mEntrance)) } fun checkResetData(update: List) { From 4999ba6563c23601263c142460afafadaf91abfa Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Fri, 19 Aug 2022 10:45:32 +0800 Subject: [PATCH 185/217] =?UTF-8?q?style:=20=E6=B7=BB=E5=8A=A0=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E7=9B=B8=E5=85=B3=E7=9A=84=20editorConfig?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shanqu.andorid.editorconfig | 555 ++++++++++++++++++++++++++++++++++++ 1 file changed, 555 insertions(+) create mode 100644 shanqu.andorid.editorconfig diff --git a/shanqu.andorid.editorconfig b/shanqu.andorid.editorconfig new file mode 100644 index 0000000000..ce8cd12235 --- /dev/null +++ b/shanqu.andorid.editorconfig @@ -0,0 +1,555 @@ +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = false +max_line_length = 120 +tab_width = 4 +ij_continuation_indent_size = 8 +ij_formatter_off_tag = @formatter:off +ij_formatter_on_tag = @formatter:on +ij_formatter_tags_enabled = false +ij_smart_tabs = false +ij_visual_guides = none +ij_wrap_on_typing = false + +[*.java] +ij_java_align_consecutive_assignments = false +ij_java_align_consecutive_variable_declarations = false +ij_java_align_group_field_declarations = false +ij_java_align_multiline_annotation_parameters = false +ij_java_align_multiline_array_initializer_expression = false +ij_java_align_multiline_assignment = false +ij_java_align_multiline_binary_operation = false +ij_java_align_multiline_chained_methods = false +ij_java_align_multiline_extends_list = false +ij_java_align_multiline_for = true +ij_java_align_multiline_method_parentheses = false +ij_java_align_multiline_parameters = true +ij_java_align_multiline_parameters_in_calls = false +ij_java_align_multiline_parenthesized_expression = false +ij_java_align_multiline_records = true +ij_java_align_multiline_resources = true +ij_java_align_multiline_ternary_operation = false +ij_java_align_multiline_text_blocks = false +ij_java_align_multiline_throws_list = false +ij_java_align_subsequent_simple_methods = false +ij_java_align_throws_keyword = false +ij_java_align_types_in_multi_catch = true +ij_java_annotation_parameter_wrap = off +ij_java_array_initializer_new_line_after_left_brace = false +ij_java_array_initializer_right_brace_on_new_line = false +ij_java_array_initializer_wrap = off +ij_java_assert_statement_colon_on_next_line = false +ij_java_assert_statement_wrap = off +ij_java_assignment_wrap = off +ij_java_binary_operation_sign_on_next_line = false +ij_java_binary_operation_wrap = off +ij_java_blank_lines_after_anonymous_class_header = 0 +ij_java_blank_lines_after_class_header = 0 +ij_java_blank_lines_after_imports = 1 +ij_java_blank_lines_after_package = 1 +ij_java_blank_lines_around_class = 1 +ij_java_blank_lines_around_field = 0 +ij_java_blank_lines_around_field_in_interface = 0 +ij_java_blank_lines_around_initializer = 1 +ij_java_blank_lines_around_method = 1 +ij_java_blank_lines_around_method_in_interface = 1 +ij_java_blank_lines_before_class_end = 0 +ij_java_blank_lines_before_imports = 1 +ij_java_blank_lines_before_method_body = 0 +ij_java_blank_lines_before_package = 0 +ij_java_block_brace_style = end_of_line +ij_java_block_comment_add_space = false +ij_java_block_comment_at_first_column = true +ij_java_builder_methods = none +ij_java_call_parameters_new_line_after_left_paren = false +ij_java_call_parameters_right_paren_on_new_line = false +ij_java_call_parameters_wrap = off +ij_java_case_statement_on_separate_line = true +ij_java_catch_on_new_line = false +ij_java_class_annotation_wrap = split_into_lines +ij_java_class_brace_style = end_of_line +ij_java_class_count_to_use_import_on_demand = 99 +ij_java_class_names_in_javadoc = 1 +ij_java_do_not_indent_top_level_class_members = false +ij_java_do_not_wrap_after_single_annotation = false +ij_java_do_not_wrap_after_single_annotation_in_parameter = false +ij_java_do_while_brace_force = never +ij_java_doc_add_blank_line_after_description = true +ij_java_doc_add_blank_line_after_param_comments = false +ij_java_doc_add_blank_line_after_return = false +ij_java_doc_add_p_tag_on_empty_lines = true +ij_java_doc_align_exception_comments = true +ij_java_doc_align_param_comments = true +ij_java_doc_do_not_wrap_if_one_line = false +ij_java_doc_enable_formatting = true +ij_java_doc_enable_leading_asterisks = true +ij_java_doc_indent_on_continuation = false +ij_java_doc_keep_empty_lines = true +ij_java_doc_keep_empty_parameter_tag = true +ij_java_doc_keep_empty_return_tag = true +ij_java_doc_keep_empty_throws_tag = true +ij_java_doc_keep_invalid_tags = true +ij_java_doc_param_description_on_new_line = false +ij_java_doc_preserve_line_breaks = false +ij_java_doc_use_throws_not_exception_tag = true +ij_java_else_on_new_line = false +ij_java_enum_constants_wrap = off +ij_java_extends_keyword_wrap = off +ij_java_extends_list_wrap = off +ij_java_field_annotation_wrap = split_into_lines +ij_java_finally_on_new_line = false +ij_java_for_brace_force = never +ij_java_for_statement_new_line_after_left_paren = false +ij_java_for_statement_right_paren_on_new_line = false +ij_java_for_statement_wrap = off +ij_java_generate_final_locals = false +ij_java_generate_final_parameters = false +ij_java_if_brace_force = never +ij_java_imports_layout = $android.**,$androidx.**,$com.**,$junit.**,$net.**,$org.**,$java.**,$javax.**,$*,|,android.**,|,androidx.**,|,com.**,|,junit.**,|,net.**,|,org.**,|,java.**,|,javax.**,|,*,| +ij_java_indent_case_from_switch = true +ij_java_insert_inner_class_imports = false +ij_java_insert_override_annotation = true +ij_java_keep_blank_lines_before_right_brace = 2 +ij_java_keep_blank_lines_between_package_declaration_and_header = 2 +ij_java_keep_blank_lines_in_code = 2 +ij_java_keep_blank_lines_in_declarations = 2 +ij_java_keep_builder_methods_indents = false +ij_java_keep_control_statement_in_one_line = true +ij_java_keep_first_column_comment = true +ij_java_keep_indents_on_empty_lines = false +ij_java_keep_line_breaks = true +ij_java_keep_multiple_expressions_in_one_line = false +ij_java_keep_simple_blocks_in_one_line = false +ij_java_keep_simple_classes_in_one_line = false +ij_java_keep_simple_lambdas_in_one_line = false +ij_java_keep_simple_methods_in_one_line = false +ij_java_label_indent_absolute = false +ij_java_label_indent_size = 0 +ij_java_lambda_brace_style = end_of_line +ij_java_layout_static_imports_separately = true +ij_java_line_comment_add_space = false +ij_java_line_comment_add_space_on_reformat = false +ij_java_line_comment_at_first_column = true +ij_java_method_annotation_wrap = split_into_lines +ij_java_method_brace_style = end_of_line +ij_java_method_call_chain_wrap = off +ij_java_method_parameters_new_line_after_left_paren = false +ij_java_method_parameters_right_paren_on_new_line = false +ij_java_method_parameters_wrap = off +ij_java_modifier_list_wrap = false +ij_java_multi_catch_types_wrap = normal +ij_java_names_count_to_use_import_on_demand = 99 +ij_java_new_line_after_lparen_in_annotation = false +ij_java_new_line_after_lparen_in_record_header = false +ij_java_parameter_annotation_wrap = off +ij_java_parentheses_expression_new_line_after_left_paren = false +ij_java_parentheses_expression_right_paren_on_new_line = false +ij_java_place_assignment_sign_on_next_line = false +ij_java_prefer_longer_names = true +ij_java_prefer_parameters_wrap = false +ij_java_record_components_wrap = normal +ij_java_repeat_synchronized = true +ij_java_replace_instanceof_and_cast = false +ij_java_replace_null_check = true +ij_java_replace_sum_lambda_with_method_ref = true +ij_java_resource_list_new_line_after_left_paren = false +ij_java_resource_list_right_paren_on_new_line = false +ij_java_resource_list_wrap = off +ij_java_rparen_on_new_line_in_annotation = false +ij_java_rparen_on_new_line_in_record_header = false +ij_java_space_after_closing_angle_bracket_in_type_argument = false +ij_java_space_after_colon = true +ij_java_space_after_comma = true +ij_java_space_after_comma_in_type_arguments = true +ij_java_space_after_for_semicolon = true +ij_java_space_after_quest = true +ij_java_space_after_type_cast = true +ij_java_space_before_annotation_array_initializer_left_brace = false +ij_java_space_before_annotation_parameter_list = false +ij_java_space_before_array_initializer_left_brace = false +ij_java_space_before_catch_keyword = true +ij_java_space_before_catch_left_brace = true +ij_java_space_before_catch_parentheses = true +ij_java_space_before_class_left_brace = true +ij_java_space_before_colon = true +ij_java_space_before_colon_in_foreach = true +ij_java_space_before_comma = false +ij_java_space_before_do_left_brace = true +ij_java_space_before_else_keyword = true +ij_java_space_before_else_left_brace = true +ij_java_space_before_finally_keyword = true +ij_java_space_before_finally_left_brace = true +ij_java_space_before_for_left_brace = true +ij_java_space_before_for_parentheses = true +ij_java_space_before_for_semicolon = false +ij_java_space_before_if_left_brace = true +ij_java_space_before_if_parentheses = true +ij_java_space_before_method_call_parentheses = false +ij_java_space_before_method_left_brace = true +ij_java_space_before_method_parentheses = false +ij_java_space_before_opening_angle_bracket_in_type_parameter = false +ij_java_space_before_quest = true +ij_java_space_before_switch_left_brace = true +ij_java_space_before_switch_parentheses = true +ij_java_space_before_synchronized_left_brace = true +ij_java_space_before_synchronized_parentheses = true +ij_java_space_before_try_left_brace = true +ij_java_space_before_try_parentheses = true +ij_java_space_before_type_parameter_list = false +ij_java_space_before_while_keyword = true +ij_java_space_before_while_left_brace = true +ij_java_space_before_while_parentheses = true +ij_java_space_inside_one_line_enum_braces = false +ij_java_space_within_empty_array_initializer_braces = false +ij_java_space_within_empty_method_call_parentheses = false +ij_java_space_within_empty_method_parentheses = false +ij_java_spaces_around_additive_operators = true +ij_java_spaces_around_annotation_eq = true +ij_java_spaces_around_assignment_operators = true +ij_java_spaces_around_bitwise_operators = true +ij_java_spaces_around_equality_operators = true +ij_java_spaces_around_lambda_arrow = true +ij_java_spaces_around_logical_operators = true +ij_java_spaces_around_method_ref_dbl_colon = false +ij_java_spaces_around_multiplicative_operators = true +ij_java_spaces_around_relational_operators = true +ij_java_spaces_around_shift_operators = true +ij_java_spaces_around_type_bounds_in_type_parameters = true +ij_java_spaces_around_unary_operator = false +ij_java_spaces_within_angle_brackets = false +ij_java_spaces_within_annotation_parentheses = false +ij_java_spaces_within_array_initializer_braces = false +ij_java_spaces_within_braces = false +ij_java_spaces_within_brackets = false +ij_java_spaces_within_cast_parentheses = false +ij_java_spaces_within_catch_parentheses = false +ij_java_spaces_within_for_parentheses = false +ij_java_spaces_within_if_parentheses = false +ij_java_spaces_within_method_call_parentheses = false +ij_java_spaces_within_method_parentheses = false +ij_java_spaces_within_parentheses = false +ij_java_spaces_within_record_header = false +ij_java_spaces_within_switch_parentheses = false +ij_java_spaces_within_synchronized_parentheses = false +ij_java_spaces_within_try_parentheses = false +ij_java_spaces_within_while_parentheses = false +ij_java_special_else_if_treatment = true +ij_java_subclass_name_suffix = Impl +ij_java_ternary_operation_signs_on_next_line = false +ij_java_ternary_operation_wrap = off +ij_java_test_name_suffix = Test +ij_java_throws_keyword_wrap = off +ij_java_throws_list_wrap = off +ij_java_use_external_annotations = false +ij_java_use_fq_class_names = false +ij_java_use_relative_indents = false +ij_java_use_single_class_imports = true +ij_java_variable_annotation_wrap = off +ij_java_visibility = public +ij_java_while_brace_force = never +ij_java_while_on_new_line = false +ij_java_wrap_comments = false +ij_java_wrap_first_method_in_call_chain = false +ij_java_wrap_long_lines = false + +[.editorconfig] +ij_editorconfig_align_group_field_declarations = false +ij_editorconfig_space_after_colon = false +ij_editorconfig_space_after_comma = true +ij_editorconfig_space_before_colon = false +ij_editorconfig_space_before_comma = false +ij_editorconfig_spaces_around_assignment_operators = true + +[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.rng,*.tld,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul}] +ij_continuation_indent_size = 4 +ij_xml_align_attributes = false +ij_xml_align_text = false +ij_xml_attribute_wrap = normal +ij_xml_block_comment_add_space = false +ij_xml_block_comment_at_first_column = true +ij_xml_keep_blank_lines = 2 +ij_xml_keep_indents_on_empty_lines = false +ij_xml_keep_line_breaks = false +ij_xml_keep_line_breaks_in_text = true +ij_xml_keep_whitespaces = false +ij_xml_keep_whitespaces_around_cdata = preserve +ij_xml_keep_whitespaces_inside_cdata = false +ij_xml_line_comment_at_first_column = true +ij_xml_space_after_tag_name = false +ij_xml_space_around_equals_in_attribute = false +ij_xml_space_inside_empty_tag = true +ij_xml_text_wrap = normal +ij_xml_use_custom_settings = true + +[{*.gant,*.groovy,*.gy}] +ij_groovy_align_group_field_declarations = false +ij_groovy_align_multiline_array_initializer_expression = false +ij_groovy_align_multiline_assignment = false +ij_groovy_align_multiline_binary_operation = false +ij_groovy_align_multiline_chained_methods = false +ij_groovy_align_multiline_extends_list = false +ij_groovy_align_multiline_for = true +ij_groovy_align_multiline_list_or_map = true +ij_groovy_align_multiline_method_parentheses = false +ij_groovy_align_multiline_parameters = true +ij_groovy_align_multiline_parameters_in_calls = false +ij_groovy_align_multiline_resources = true +ij_groovy_align_multiline_ternary_operation = false +ij_groovy_align_multiline_throws_list = false +ij_groovy_align_named_args_in_map = true +ij_groovy_align_throws_keyword = false +ij_groovy_array_initializer_new_line_after_left_brace = false +ij_groovy_array_initializer_right_brace_on_new_line = false +ij_groovy_array_initializer_wrap = off +ij_groovy_assert_statement_wrap = off +ij_groovy_assignment_wrap = off +ij_groovy_binary_operation_wrap = off +ij_groovy_blank_lines_after_class_header = 0 +ij_groovy_blank_lines_after_imports = 1 +ij_groovy_blank_lines_after_package = 1 +ij_groovy_blank_lines_around_class = 1 +ij_groovy_blank_lines_around_field = 0 +ij_groovy_blank_lines_around_field_in_interface = 0 +ij_groovy_blank_lines_around_method = 1 +ij_groovy_blank_lines_around_method_in_interface = 1 +ij_groovy_blank_lines_before_imports = 1 +ij_groovy_blank_lines_before_method_body = 0 +ij_groovy_blank_lines_before_package = 0 +ij_groovy_block_brace_style = end_of_line +ij_groovy_block_comment_add_space = false +ij_groovy_block_comment_at_first_column = true +ij_groovy_call_parameters_new_line_after_left_paren = false +ij_groovy_call_parameters_right_paren_on_new_line = false +ij_groovy_call_parameters_wrap = off +ij_groovy_catch_on_new_line = false +ij_groovy_class_annotation_wrap = split_into_lines +ij_groovy_class_brace_style = end_of_line +ij_groovy_class_count_to_use_import_on_demand = 5 +ij_groovy_do_while_brace_force = never +ij_groovy_else_on_new_line = false +ij_groovy_enable_groovydoc_formatting = true +ij_groovy_enum_constants_wrap = off +ij_groovy_extends_keyword_wrap = off +ij_groovy_extends_list_wrap = off +ij_groovy_field_annotation_wrap = split_into_lines +ij_groovy_finally_on_new_line = false +ij_groovy_for_brace_force = never +ij_groovy_for_statement_new_line_after_left_paren = false +ij_groovy_for_statement_right_paren_on_new_line = false +ij_groovy_for_statement_wrap = off +ij_groovy_if_brace_force = never +ij_groovy_import_annotation_wrap = 2 +ij_groovy_imports_layout = *,|,javax.**,java.**,|,$* +ij_groovy_indent_case_from_switch = true +ij_groovy_indent_label_blocks = true +ij_groovy_insert_inner_class_imports = false +ij_groovy_keep_blank_lines_before_right_brace = 2 +ij_groovy_keep_blank_lines_in_code = 2 +ij_groovy_keep_blank_lines_in_declarations = 2 +ij_groovy_keep_control_statement_in_one_line = true +ij_groovy_keep_first_column_comment = true +ij_groovy_keep_indents_on_empty_lines = false +ij_groovy_keep_line_breaks = true +ij_groovy_keep_multiple_expressions_in_one_line = false +ij_groovy_keep_simple_blocks_in_one_line = false +ij_groovy_keep_simple_classes_in_one_line = true +ij_groovy_keep_simple_lambdas_in_one_line = true +ij_groovy_keep_simple_methods_in_one_line = true +ij_groovy_label_indent_absolute = false +ij_groovy_label_indent_size = 0 +ij_groovy_lambda_brace_style = end_of_line +ij_groovy_layout_static_imports_separately = true +ij_groovy_line_comment_add_space = false +ij_groovy_line_comment_add_space_on_reformat = false +ij_groovy_line_comment_at_first_column = true +ij_groovy_method_annotation_wrap = split_into_lines +ij_groovy_method_brace_style = end_of_line +ij_groovy_method_call_chain_wrap = off +ij_groovy_method_parameters_new_line_after_left_paren = false +ij_groovy_method_parameters_right_paren_on_new_line = false +ij_groovy_method_parameters_wrap = off +ij_groovy_modifier_list_wrap = false +ij_groovy_names_count_to_use_import_on_demand = 3 +ij_groovy_packages_to_use_import_on_demand = java.awt.*,javax.swing.* +ij_groovy_parameter_annotation_wrap = off +ij_groovy_parentheses_expression_new_line_after_left_paren = false +ij_groovy_parentheses_expression_right_paren_on_new_line = false +ij_groovy_prefer_parameters_wrap = false +ij_groovy_resource_list_new_line_after_left_paren = false +ij_groovy_resource_list_right_paren_on_new_line = false +ij_groovy_resource_list_wrap = off +ij_groovy_space_after_assert_separator = true +ij_groovy_space_after_colon = true +ij_groovy_space_after_comma = true +ij_groovy_space_after_comma_in_type_arguments = true +ij_groovy_space_after_for_semicolon = true +ij_groovy_space_after_quest = true +ij_groovy_space_after_type_cast = true +ij_groovy_space_before_annotation_parameter_list = false +ij_groovy_space_before_array_initializer_left_brace = false +ij_groovy_space_before_assert_separator = false +ij_groovy_space_before_catch_keyword = true +ij_groovy_space_before_catch_left_brace = true +ij_groovy_space_before_catch_parentheses = true +ij_groovy_space_before_class_left_brace = true +ij_groovy_space_before_closure_left_brace = true +ij_groovy_space_before_colon = true +ij_groovy_space_before_comma = false +ij_groovy_space_before_do_left_brace = true +ij_groovy_space_before_else_keyword = true +ij_groovy_space_before_else_left_brace = true +ij_groovy_space_before_finally_keyword = true +ij_groovy_space_before_finally_left_brace = true +ij_groovy_space_before_for_left_brace = true +ij_groovy_space_before_for_parentheses = true +ij_groovy_space_before_for_semicolon = false +ij_groovy_space_before_if_left_brace = true +ij_groovy_space_before_if_parentheses = true +ij_groovy_space_before_method_call_parentheses = false +ij_groovy_space_before_method_left_brace = true +ij_groovy_space_before_method_parentheses = false +ij_groovy_space_before_quest = true +ij_groovy_space_before_record_parentheses = false +ij_groovy_space_before_switch_left_brace = true +ij_groovy_space_before_switch_parentheses = true +ij_groovy_space_before_synchronized_left_brace = true +ij_groovy_space_before_synchronized_parentheses = true +ij_groovy_space_before_try_left_brace = true +ij_groovy_space_before_try_parentheses = true +ij_groovy_space_before_while_keyword = true +ij_groovy_space_before_while_left_brace = true +ij_groovy_space_before_while_parentheses = true +ij_groovy_space_in_named_argument = true +ij_groovy_space_in_named_argument_before_colon = false +ij_groovy_space_within_empty_array_initializer_braces = false +ij_groovy_space_within_empty_method_call_parentheses = false +ij_groovy_spaces_around_additive_operators = true +ij_groovy_spaces_around_assignment_operators = true +ij_groovy_spaces_around_bitwise_operators = true +ij_groovy_spaces_around_equality_operators = true +ij_groovy_spaces_around_lambda_arrow = true +ij_groovy_spaces_around_logical_operators = true +ij_groovy_spaces_around_multiplicative_operators = true +ij_groovy_spaces_around_regex_operators = true +ij_groovy_spaces_around_relational_operators = true +ij_groovy_spaces_around_shift_operators = true +ij_groovy_spaces_within_annotation_parentheses = false +ij_groovy_spaces_within_array_initializer_braces = false +ij_groovy_spaces_within_braces = true +ij_groovy_spaces_within_brackets = false +ij_groovy_spaces_within_cast_parentheses = false +ij_groovy_spaces_within_catch_parentheses = false +ij_groovy_spaces_within_for_parentheses = false +ij_groovy_spaces_within_gstring_injection_braces = false +ij_groovy_spaces_within_if_parentheses = false +ij_groovy_spaces_within_list_or_map = false +ij_groovy_spaces_within_method_call_parentheses = false +ij_groovy_spaces_within_method_parentheses = false +ij_groovy_spaces_within_parentheses = false +ij_groovy_spaces_within_switch_parentheses = false +ij_groovy_spaces_within_synchronized_parentheses = false +ij_groovy_spaces_within_try_parentheses = false +ij_groovy_spaces_within_tuple_expression = false +ij_groovy_spaces_within_while_parentheses = false +ij_groovy_special_else_if_treatment = true +ij_groovy_ternary_operation_wrap = off +ij_groovy_throws_keyword_wrap = off +ij_groovy_throws_list_wrap = off +ij_groovy_use_flying_geese_braces = false +ij_groovy_use_fq_class_names = false +ij_groovy_use_fq_class_names_in_javadoc = true +ij_groovy_use_relative_indents = false +ij_groovy_use_single_class_imports = true +ij_groovy_variable_annotation_wrap = off +ij_groovy_while_brace_force = never +ij_groovy_while_on_new_line = false +ij_groovy_wrap_chain_calls_after_dot = false +ij_groovy_wrap_long_lines = false + +[{*.kt,*.kts,*.main.kts}] +ij_kotlin_align_in_columns_case_branch = false +ij_kotlin_align_multiline_binary_operation = false +ij_kotlin_align_multiline_extends_list = false +ij_kotlin_align_multiline_method_parentheses = false +ij_kotlin_align_multiline_parameters = true +ij_kotlin_align_multiline_parameters_in_calls = false +ij_kotlin_allow_trailing_comma = false +ij_kotlin_allow_trailing_comma_on_call_site = false +ij_kotlin_assignment_wrap = normal +ij_kotlin_blank_lines_after_class_header = 0 +ij_kotlin_blank_lines_around_block_when_branches = 0 +ij_kotlin_blank_lines_before_declaration_with_comment_or_annotation_on_separate_line = 1 +ij_kotlin_block_comment_add_space = false +ij_kotlin_block_comment_at_first_column = true +ij_kotlin_call_parameters_new_line_after_left_paren = true +ij_kotlin_call_parameters_right_paren_on_new_line = true +ij_kotlin_call_parameters_wrap = on_every_item +ij_kotlin_catch_on_new_line = false +ij_kotlin_class_annotation_wrap = split_into_lines +ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL +ij_kotlin_continuation_indent_for_chained_calls = false +ij_kotlin_continuation_indent_for_expression_bodies = false +ij_kotlin_continuation_indent_in_argument_lists = false +ij_kotlin_continuation_indent_in_elvis = false +ij_kotlin_continuation_indent_in_if_conditions = false +ij_kotlin_continuation_indent_in_parameter_lists = false +ij_kotlin_continuation_indent_in_supertype_lists = false +ij_kotlin_else_on_new_line = false +ij_kotlin_enum_constants_wrap = off +ij_kotlin_extends_list_wrap = normal +ij_kotlin_field_annotation_wrap = split_into_lines +ij_kotlin_finally_on_new_line = false +ij_kotlin_if_rparen_on_new_line = true +ij_kotlin_import_nested_classes = false +ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^ +ij_kotlin_insert_whitespaces_in_simple_one_line_method = true +ij_kotlin_keep_blank_lines_before_right_brace = 2 +ij_kotlin_keep_blank_lines_in_code = 2 +ij_kotlin_keep_blank_lines_in_declarations = 2 +ij_kotlin_keep_first_column_comment = true +ij_kotlin_keep_indents_on_empty_lines = false +ij_kotlin_keep_line_breaks = true +ij_kotlin_lbrace_on_next_line = false +ij_kotlin_line_comment_add_space = false +ij_kotlin_line_comment_add_space_on_reformat = false +ij_kotlin_line_comment_at_first_column = true +ij_kotlin_method_annotation_wrap = split_into_lines +ij_kotlin_method_call_chain_wrap = normal +ij_kotlin_method_parameters_new_line_after_left_paren = true +ij_kotlin_method_parameters_right_paren_on_new_line = true +ij_kotlin_method_parameters_wrap = on_every_item +ij_kotlin_name_count_to_use_star_import = 5 +ij_kotlin_name_count_to_use_star_import_for_members = 3 +ij_kotlin_packages_to_use_import_on_demand = java.util.*,kotlinx.android.synthetic.**,io.ktor.** +ij_kotlin_parameter_annotation_wrap = off +ij_kotlin_space_after_comma = true +ij_kotlin_space_after_extend_colon = true +ij_kotlin_space_after_type_colon = true +ij_kotlin_space_before_catch_parentheses = true +ij_kotlin_space_before_comma = false +ij_kotlin_space_before_extend_colon = true +ij_kotlin_space_before_for_parentheses = true +ij_kotlin_space_before_if_parentheses = true +ij_kotlin_space_before_lambda_arrow = true +ij_kotlin_space_before_type_colon = false +ij_kotlin_space_before_when_parentheses = true +ij_kotlin_space_before_while_parentheses = true +ij_kotlin_spaces_around_additive_operators = true +ij_kotlin_spaces_around_assignment_operators = true +ij_kotlin_spaces_around_equality_operators = true +ij_kotlin_spaces_around_function_type_arrow = true +ij_kotlin_spaces_around_logical_operators = true +ij_kotlin_spaces_around_multiplicative_operators = true +ij_kotlin_spaces_around_range = false +ij_kotlin_spaces_around_relational_operators = true +ij_kotlin_spaces_around_unary_operator = false +ij_kotlin_spaces_around_when_arrow = true +ij_kotlin_use_custom_formatting_for_modifiers = true +ij_kotlin_variable_annotation_wrap = off +ij_kotlin_while_on_new_line = false +ij_kotlin_wrap_elvis_expressions = 1 +ij_kotlin_wrap_expression_body_functions = 1 +ij_kotlin_wrap_first_method_in_call_chain = false \ No newline at end of file From 322da11319e952ec7959d549071f7c06e6914de3 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Fri, 19 Aug 2022 10:47:01 +0800 Subject: [PATCH 186/217] =?UTF-8?q?style:=20=E6=B7=BB=E5=8A=A0=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E7=9B=B8=E5=85=B3=E7=9A=84=20editorConfig?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shanqu.andorid.editorconfig => .editorconfig | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename shanqu.andorid.editorconfig => .editorconfig (100%) diff --git a/shanqu.andorid.editorconfig b/.editorconfig similarity index 100% rename from shanqu.andorid.editorconfig rename to .editorconfig From 443c8d7eaf2dac2aa062c66c1213f57bd9b255c7 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Fri, 19 Aug 2022 17:53:52 +0800 Subject: [PATCH 187/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=A4=87?= =?UTF-8?q?=E4=BB=BD=E7=95=85=E7=8E=A9=E6=B8=B8=E6=88=8F=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=EF=BC=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/util/PackageInstaller.kt | 7 +- .../main/java/com/gh/vspace/VBackupHelper.kt | 67 +++++++++++++------ .../gh/vspace/VDownloadManagerViewModel.kt | 2 +- app/src/main/java/com/gh/vspace/VHelper.kt | 13 ++-- .../java/com/gh/vspace/db/VGameDatabase.kt | 2 +- 5 files changed, 60 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/PackageInstaller.kt b/app/src/main/java/com/gh/common/util/PackageInstaller.kt index 40d479cfb6..2688f6a158 100644 --- a/app/src/main/java/com/gh/common/util/PackageInstaller.kt +++ b/app/src/main/java/com/gh/common/util/PackageInstaller.kt @@ -57,6 +57,11 @@ object PackageInstaller { val isXapk = XapkInstaller.XAPK_EXTENSION_NAME == pkgPath.getExtension() val isSmoothGame = downloadEntity.getMetaExtra(Constants.SMOOTH_GAME) == "true" + if (isSmoothGame) { + VHelper.install(currentActivity, downloadEntity) + return + } + val currentActivity = CurrentActivityHolder.getCurrentActivity() ?: return // TODO 此处可能遇到 activity 是 WXEntryActivity @@ -73,8 +78,6 @@ object PackageInstaller { val mainIntent = Intent.makeRestartActivityTask(intent!!.component) context.startActivity(mainIntent) Runtime.getRuntime().exit(0) - } else if (isSmoothGame) { - VHelper.install(currentActivity, downloadEntity) } else { if (isXapk) { XapkInstaller.install(context, downloadEntity, showUnzipToast) diff --git a/app/src/main/java/com/gh/vspace/VBackupHelper.kt b/app/src/main/java/com/gh/vspace/VBackupHelper.kt index a4cade8519..ef86fb0da3 100644 --- a/app/src/main/java/com/gh/vspace/VBackupHelper.kt +++ b/app/src/main/java/com/gh/vspace/VBackupHelper.kt @@ -31,20 +31,24 @@ object VBackupHelper { private fun recoverFromBackupDb(context: Context) { try { - val rootDir: File = Environment.getExternalStorageDirectory() - if (rootDir.canWrite()) { - val appDB: File = context.getDatabasePath(VGameDatabase.DATABASE) - val backupDBPath = String.format("/gh-files/%s.bak", VGameDatabase.DATABASE) - val externalDB = File(rootDir, backupDBPath) - val src: FileChannel = FileInputStream(externalDB).channel - val dst: FileChannel = FileOutputStream(appDB).channel - dst.transferFrom(src, 0, src.size()) - src.close() - dst.close() + val backupDir = File(Environment.getExternalStorageDirectory().absolutePath + "/gh-files") + val databaseDir: File? = context.getDatabasePath(VGameDatabase.DATABASE).parentFile - externalDB.delete() + if (backupDir.canWrite() && databaseDir != null) { + backupDir.listFiles()?.forEach { + if (it.name.endsWith(".bak")) { + val src: FileChannel = FileInputStream(it).channel + val dst: FileChannel = + FileOutputStream(File(databaseDir.absolutePath + "/${it.name.removeSuffix(".bak")}")).channel + dst.transferFrom(src, 0, src.size()) + src.close() + dst.close() - Utils.log("Import Download DB Successful!") + it.delete() + + Utils.log("Recover ${it.name} successful!") + } + } } } catch (e: Exception) { e.printStackTrace() @@ -55,19 +59,40 @@ object VBackupHelper { * 备份现有数据库到 SD 卡 */ fun backupDBToExternalStorage(context: Context) { + val backupDir = File(Environment.getExternalStorageDirectory().absolutePath + "/gh-files") + val databaseDir: File? = context.getDatabasePath(VGameDatabase.DATABASE).parentFile + + try { + if (backupDir.canWrite() && databaseDir != null) { + databaseDir.listFiles()?.forEach { + if (it.name.contains(VGameDatabase.DATABASE)) { + val src: FileChannel = FileInputStream(it).channel + val dst: FileChannel = + FileOutputStream(File(backupDir.absolutePath + "/${it.name}" + ".bak")).channel + dst.transferFrom(src, 0, src.size()) + src.close() + dst.close() + + Utils.log("Backup ${it.name} successful!") + } + } + } + } catch (e: Exception) { + e.printStackTrace() + } + } + + fun removeAllDatabase(context: Context) { try { val rootDir: File = Environment.getExternalStorageDirectory() if (rootDir.canWrite()) { - val appDB: File = context.getDatabasePath(VGameDatabase.DATABASE) - val externalDBPath = String.format("/gh-files/%s.bak", VGameDatabase.DATABASE) - val externalDB = File(rootDir, externalDBPath) - val src: FileChannel = FileInputStream(appDB).channel - val dst: FileChannel = FileOutputStream(externalDB).channel - dst.transferFrom(src, 0, src.size()) - src.close() - dst.close() + val backupDBPath = String.format("/gh-files/%s.bak", VGameDatabase.DATABASE) + val externalDB = File(rootDir, backupDBPath) - Utils.log("Export Download DB Successful!") + externalDB.delete() + context.deleteDatabase(VGameDatabase.DATABASE) + + Utils.log("Import Download DB Successful!") } } catch (e: Exception) { e.printStackTrace() diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index e083c4f340..10a85cbcb7 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -132,7 +132,7 @@ class VDownloadManagerViewModel(application: Application) : PackageObserver.onPackageChanged(event) } - ToastUtils.toast("已删除 ${size} 款游戏") + ToastUtils.toast("已删除 $size 款游戏") } } diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index f57bc6cc1b..1bb3366d22 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -21,7 +21,6 @@ import com.gh.common.util.NewFlatLogUtils import com.gh.common.util.PackageUtils import com.gh.download.DownloadManager import com.gh.download.PackageObserver - import com.gh.gamecenter.R import com.gh.gamecenter.SplashScreenActivity import com.gh.gamecenter.common.BuildConfig @@ -44,9 +43,9 @@ import com.gh.vspace.db.VGameDatabase import com.gh.vspace.db.VGameEntity import com.halo.assistant.HaloApp import com.lg.vspace.VirtualAppManager +import com.lg.vspace.remote.BinderPool import com.lg.vspace.remote.listener.RemoteConnectListener import com.lg.vspace.remote.model.AppInstallerInfo -import com.lg.vspace.remote.BinderPool import com.lightgame.download.DownloadEntity import com.lightgame.utils.AppManager import com.lightgame.utils.Utils @@ -545,6 +544,12 @@ object VHelper { mVGameDao.delete(packageName) + if (mVGameDao.getAll().isEmpty()) { + VBackupHelper.removeAllDatabase(HaloApp.getInstance()) + } else { + VBackupHelper.backupDBToExternalStorage(HaloApp.getInstance()) + } + val uninstallClosure: () -> Unit = { try { val result = VirtualAppManager.get().uninstallGame(packageName) @@ -553,10 +558,6 @@ object VHelper { } Utils.log(LOG_TAG, "卸载应用结果 -> $result") - - runOnIoThread { - VBackupHelper.backupDBToExternalStorage(HaloApp.getInstance()) - } } catch (e: Exception) { ToastUtils.toast(e.localizedMessage ?: "") } diff --git a/app/src/main/java/com/gh/vspace/db/VGameDatabase.kt b/app/src/main/java/com/gh/vspace/db/VGameDatabase.kt index 105fb4564f..f3b93d67f6 100644 --- a/app/src/main/java/com/gh/vspace/db/VGameDatabase.kt +++ b/app/src/main/java/com/gh/vspace/db/VGameDatabase.kt @@ -13,7 +13,7 @@ abstract class VGameDatabase : RoomDatabase() { abstract fun vGameDao(): VGameDao companion object { - const val DATABASE = "v_game_database" + const val DATABASE = "v_game_database.db" fun buildDatabase(context: Context): VGameDatabase { return Room.databaseBuilder(context, VGameDatabase::class.java, DATABASE) From 39d3c4d3c8b7ac70d01028401fb8fa6c721610aa Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Fri, 19 Aug 2022 17:59:52 +0800 Subject: [PATCH 188/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=9C=AA?= =?UTF-8?q?=E5=AE=89=E8=A3=85=E7=95=85=E7=8E=A9=E6=B8=B8=E6=88=8F=E5=9C=A8?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E4=B8=AD=E4=BC=9A=E6=89=BE=E4=B8=8D=E5=88=B0?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/common/util/PackageInstaller.kt | 4 ++-- app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/gh/common/util/PackageInstaller.kt b/app/src/main/java/com/gh/common/util/PackageInstaller.kt index 2688f6a158..42b3fb113c 100644 --- a/app/src/main/java/com/gh/common/util/PackageInstaller.kt +++ b/app/src/main/java/com/gh/common/util/PackageInstaller.kt @@ -57,13 +57,13 @@ object PackageInstaller { val isXapk = XapkInstaller.XAPK_EXTENSION_NAME == pkgPath.getExtension() val isSmoothGame = downloadEntity.getMetaExtra(Constants.SMOOTH_GAME) == "true" + val currentActivity = CurrentActivityHolder.getCurrentActivity() ?: return + if (isSmoothGame) { VHelper.install(currentActivity, downloadEntity) return } - val currentActivity = CurrentActivityHolder.getCurrentActivity() ?: return - // TODO 此处可能遇到 activity 是 WXEntryActivity // TODO 当 activity 全部出栈,但是应用还在下载游戏,下载完会唤不起安装! if (currentActivity is AppCompatActivity && !currentActivity.isFinishing) { diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index 10a85cbcb7..7fbcc843f3 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -84,7 +84,7 @@ class VDownloadManagerViewModel(application: Application) : for (downloadEntity in downloadList) { // 过滤下载完成的部分 - if (downloadEntity.status == DownloadStatus.done) { + if (downloadEntity.status == DownloadStatus.done && VHelper.isInstalled(downloadEntity.packageName)) { continue } gameList.add(VHelper.toGameEntity(downloadEntity)) From 5a7001dd66d3536374cbd848105046faa5707665 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Wed, 24 Aug 2022 17:36:12 +0800 Subject: [PATCH 189/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=83=A8?= =?UTF-8?q?=E5=88=86=E8=AE=BE=E5=A4=87=E4=B8=8D=E8=83=BD=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=B7=B2=E5=AE=89=E8=A3=85=E5=BA=94=E7=94=A8=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/gamecenter/SplashScreenActivity.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.kt b/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.kt index 1a60fdd46f..f4ec821f01 100644 --- a/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.kt @@ -30,6 +30,7 @@ import com.gh.gamecenter.common.constant.RouteConsts import com.gh.gamecenter.common.tracker.TrackerLogger import com.gh.gamecenter.common.utils.DialogHelper import com.gh.gamecenter.common.utils.PackageFlavorHelper +import com.gh.gamecenter.common.utils.PermissionHelper import com.gh.gamecenter.common.utils.viewModelProvider import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.core.utils.DisplayUtils @@ -59,7 +60,8 @@ class SplashScreenActivity : BaseActivity() { private val mPermissions = arrayOf( Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, - Manifest.permission.READ_PHONE_STATE + Manifest.permission.READ_PHONE_STATE, + PermissionHelper.PERMISSION_GET_INSTALLED_LIST ) override fun onCreate(savedInstanceState: Bundle?) { From 3319fd29deb685c1cf6f5f9e25c0baf8a51e1803 Mon Sep 17 00:00:00 2001 From: liuyirong Date: Thu, 25 Aug 2022 11:03:18 +0800 Subject: [PATCH 190/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=AE=BA?= =?UTF-8?q?=E5=9D=9B=E8=AF=A6=E6=83=85=E9=A1=B5=E7=82=B9=E5=87=BB=E6=A0=87?= =?UTF-8?q?=E9=A2=98=E6=A0=8F=E9=A1=B5=E9=9D=A2=E5=90=B8=E9=A1=B6=E6=97=B6?= =?UTF-8?q?=E7=9A=84=E9=97=AA=E9=80=80=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/gamecenter/forum/detail/ForumArticleAskListFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListFragment.kt index 31cdb894e6..5835bdaf78 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListFragment.kt @@ -269,7 +269,7 @@ class ForumArticleAskListFragment : LazyListFragment Date: Thu, 25 Aug 2022 14:36:59 +0800 Subject: [PATCH 191/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E8=AF=A6=E6=83=85=E9=A1=B5=E9=9D=A2=E3=80=81=E6=9F=A5?= =?UTF-8?q?=E7=9C=8B=E5=A4=A7=E5=9B=BE=E9=A1=B5=E9=9D=A2=E7=9A=84=E9=97=AA?= =?UTF-8?q?=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/gamecenter/ImageViewerActivity.kt | 32 +++++++++++++++---- .../gamedetail/GameDetailFragment.kt | 6 ++-- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/ImageViewerActivity.kt b/app/src/main/java/com/gh/gamecenter/ImageViewerActivity.kt index e01afdec38..b14def2324 100644 --- a/app/src/main/java/com/gh/gamecenter/ImageViewerActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/ImageViewerActivity.kt @@ -368,7 +368,7 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener { if (mUseEnterAndExitAnimation) { mBigImageView?.translationX = mTranslationX mBigImageView?.translationY = mTranslationY - if (mScaleX < Float.MAX_VALUE) { + if (!mScaleX.isNaN() && mScaleX < Float.MAX_VALUE) { mBigImageView?.scaleX = mScaleX mBigImageView?.scaleY = mScaleY } @@ -439,10 +439,18 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener { addUpdateListener { va -> mBigImageView?.y = (va.animatedValue as Float) } } val scaleYAnimator = ValueAnimator.ofFloat(1F, mScaleY).apply { - addUpdateListener { va -> mBigImageView?.scaleY = (va.animatedValue as Float) } + addUpdateListener { va -> + if (va.animatedValue is Float && !(va.animatedValue as Float).isNaN() && (va.animatedValue as Float) < Float.MAX_VALUE) { + mBigImageView?.scaleY = (va.animatedValue as Float) + } + } } val scaleXAnimator = ValueAnimator.ofFloat(1F, mScaleX).apply { - addUpdateListener { va -> mBigImageView?.scaleX = (va.animatedValue as Float) } + addUpdateListener { va -> + if (va.animatedValue is Float && !(va.animatedValue as Float).isNaN() && (va.animatedValue as Float) < Float.MAX_VALUE) { + mBigImageView?.scaleX = (va.animatedValue as Float) + } + } } val backgroundAlphaAnimation = ValueAnimator.ofFloat(1F, 0F).apply { addUpdateListener { va -> mBackgroundView.alpha = (va.animatedValue as Float) } @@ -591,10 +599,18 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener { addUpdateListener { va -> mBigImageView?.y = (va.animatedValue as Float) } } val scaleYAnimator = ValueAnimator.ofFloat(mScaleY, 1F).apply { - addUpdateListener { va -> mBigImageView?.scaleY = (va.animatedValue as Float) } + addUpdateListener { va -> + if (va.animatedValue is Float && !(va.animatedValue as Float).isNaN() && (va.animatedValue as Float) < Float.MAX_VALUE) { + mBigImageView?.scaleY = (va.animatedValue as Float) + } + } } val scaleXAnimator = ValueAnimator.ofFloat(mScaleX, 1F).apply { - addUpdateListener { va -> mBigImageView?.scaleX = (va.animatedValue as Float) } + addUpdateListener { va -> + if (va.animatedValue is Float && !(va.animatedValue as Float).isNaN() && (va.animatedValue as Float) < Float.MAX_VALUE) { + mBigImageView?.scaleX = (va.animatedValue as Float) + } + } } val backgroundAlphaAnimator = ValueAnimator.ofFloat(0F, 1F).apply { addUpdateListener { va -> mBackgroundView.alpha = (va.animatedValue as Float) } @@ -625,8 +641,10 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener { val scaleAnimator = ValueAnimator.ofFloat(scale, finalScale).apply { addUpdateListener { va -> - view.scaleX = (va.animatedValue as Float) - view.scaleY = (va.animatedValue as Float) + if (va.animatedValue is Float && !(va.animatedValue as Float).isNaN() && (va.animatedValue as Float) < Float.MAX_VALUE) { + view.scaleX = (va.animatedValue as Float) + view.scaleY = (va.animatedValue as Float) + } } } val translateXAnimator = ValueAnimator.ofFloat(view.x, finalTranslationX).apply { diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt index be22a37595..7f5ff92eb7 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt @@ -431,8 +431,8 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { } } } else { - setTextColor(R.color.text_subtitle.toColor(requireContext())) - background = R.drawable.bg_advance_download_game_subtitle.toDrawable(requireContext()) + setTextColor(R.color.text_subtitle.toColor(context)) + background = R.drawable.bg_advance_download_game_subtitle.toDrawable(context) } } tagView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED) @@ -444,7 +444,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { var changeDisplayName = false if ((lineCount == 2 && layout.getEllipsisCount(1) > 0) || (lineCount == 2 && tagView.measuredWidth > remainWidth)) { val textCount = calculateTextCountByWidth(this, 2 * gameTitleTv.width - tagView.measuredWidth) - 1 - if (textCount < text.length) { + if (textCount in text.indices) { displayName = text.substring(0, textCount) + "…" changeDisplayName = true } From ec96fc325818a01d33d04b07d1474ea091e10c36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E5=AD=90=E7=BB=B4?= Date: Thu, 25 Aug 2022 15:17:47 +0800 Subject: [PATCH 192/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E8=AF=A6=E6=83=85=E9=A1=B5=E9=9D=A2=E7=9A=84=E9=97=AA?= =?UTF-8?q?=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt index 7f5ff92eb7..4c681516f9 100644 --- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt @@ -402,6 +402,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { private fun initGameSubtitle(gameTitleTv: TextView, gameSubtitle: String, gameSubtitleStyle: TagStyleEntity? = null, advanceDownload: Boolean = false) { gameTitleTv.post { + if (!isAdded) return@post gameTitleTv.run { var lastPosX = 0F tryCatchInRelease { @@ -431,8 +432,8 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { } } } else { - setTextColor(R.color.text_subtitle.toColor(context)) - background = R.drawable.bg_advance_download_game_subtitle.toDrawable(context) + setTextColor(R.color.text_subtitle.toColor(requireContext())) + background = R.drawable.bg_advance_download_game_subtitle.toDrawable(requireContext()) } } tagView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED) @@ -475,6 +476,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable { } private fun subtractGameNameIfNeeded(textView: TextView, name: CharSequence, tagLayout: FrameLayout) { + if (!isAdded) return textView.run { if (lineCount > 2 || (layout != null && layout.getEllipsisCount(1) > 0)) { val displayName = name.substring(0, name.length - 2) + "…" From 4ab2a238409d7744b427cf8581144d633b48feab Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Mon, 29 Aug 2022 10:20:43 +0800 Subject: [PATCH 193/217] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E5=B9=BF=E5=9C=BA=E7=9A=84=E8=B7=B3=E8=BD=AC=20https:?= =?UTF-8?q?//git.shanqu.cc/pm/halo/halo-app-issues/-/issues/2000#note=5F16?= =?UTF-8?q?6886?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/vspace/VDownloadManagerWrapperFragment.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt index 540afb99b1..45b3d026dd 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt @@ -5,11 +5,13 @@ import android.view.MenuItem import android.view.View import android.widget.TextView import androidx.fragment.app.Fragment +import com.gh.common.util.DirectUtils import com.gh.gamecenter.R import com.gh.gamecenter.common.base.fragment.BaseLazyTabFragment import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.viewModelProvider import com.gh.gamecenter.databinding.FragmentVdownloadManagerWrapperBinding +import com.gh.gamecenter.entity.SubjectRecommendEntity import com.gh.gamecenter.history.IBatchDelete import com.gh.gamecenter.history.ManageOption @@ -30,7 +32,11 @@ class VDownloadManagerWrapperFragment: BaseLazyTabFragment() { initMenu(R.menu.menu_manage) mBinding.bottomContainer.setOnClickListener { - toast("打开畅玩广场") + val entity = SubjectRecommendEntity() + entity.link = "62fc8047b07e0c0bb63058c2" + entity.name = "畅玩广场" + entity.text = "畅玩广场" + DirectUtils.directToBlock(requireContext(), entity, mEntrance) } arguments?.getInt(EntranceConsts.KEY_POSITION)?.let { From 02b9d151344f6540684d30ce511252d45bcf1d60 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Mon, 29 Aug 2022 14:17:54 +0800 Subject: [PATCH 194/217] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E5=B9=BF=E5=9C=BA=E7=9A=84=E8=B7=B3=E8=BD=AC=20https:?= =?UTF-8?q?//git.shanqu.cc/pm/halo/halo-app-issues/-/issues/2000#note=5F16?= =?UTF-8?q?6886?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt | 1 + .../com/gh/vspace/VDownloadManagerWrapperFragment.kt | 8 +------- app/src/main/java/com/gh/vspace/VHelper.kt | 9 +++++++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt index ce8965c684..3d1e2a82a9 100644 --- a/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt +++ b/app/src/main/java/com/gh/vspace/HomeRecentVGameViewHolder.kt @@ -55,6 +55,7 @@ class HomeRecentVGameViewHolder(var binding: ItemHomeRecentVgameBinding) : binding.vspaceIv.setOnClickListener { NewFlatLogUtils.logHaloFunEvent("halo_fun_manage_square_entrance_click") + VHelper.startVSpaceSquare(it.context) } } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt index 45b3d026dd..d40c94c524 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt @@ -5,13 +5,11 @@ import android.view.MenuItem import android.view.View import android.widget.TextView import androidx.fragment.app.Fragment -import com.gh.common.util.DirectUtils import com.gh.gamecenter.R import com.gh.gamecenter.common.base.fragment.BaseLazyTabFragment import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.viewModelProvider import com.gh.gamecenter.databinding.FragmentVdownloadManagerWrapperBinding -import com.gh.gamecenter.entity.SubjectRecommendEntity import com.gh.gamecenter.history.IBatchDelete import com.gh.gamecenter.history.ManageOption @@ -32,11 +30,7 @@ class VDownloadManagerWrapperFragment: BaseLazyTabFragment() { initMenu(R.menu.menu_manage) mBinding.bottomContainer.setOnClickListener { - val entity = SubjectRecommendEntity() - entity.link = "62fc8047b07e0c0bb63058c2" - entity.name = "畅玩广场" - entity.text = "畅玩广场" - DirectUtils.directToBlock(requireContext(), entity, mEntrance) + VHelper.startVSpaceSquare(requireContext()) } arguments?.getInt(EntranceConsts.KEY_POSITION)?.let { diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 1bb3366d22..77fdb57db5 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -17,6 +17,7 @@ import com.gh.common.constant.Config import com.gh.common.exposure.ExposureUtils import com.gh.common.history.HistoryHelper import com.gh.common.util.DataCollectionUtils +import com.gh.common.util.DirectUtils import com.gh.common.util.NewFlatLogUtils import com.gh.common.util.PackageUtils import com.gh.download.DownloadManager @@ -828,6 +829,14 @@ object VHelper { return false } + fun startVSpaceSquare(context: Context) { + val entity = SubjectRecommendEntity() + entity.link = "62fc8047b07e0c0bb63058c2" + entity.name = "畅玩广场" + entity.text = "畅玩广场" + DirectUtils.directToBlock(context, entity, "") + } + @JvmStatic fun recoverVDataIfPossible() { VBackupHelper.recoverValidData(HaloApp.getInstance()) From 163a1a7f1fc53515ac30e18ecb32a8ceb40b75c9 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Mon, 29 Aug 2022 18:04:23 +0800 Subject: [PATCH 195/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=9B=9E?= =?UTF-8?q?=E8=B0=83=20onNewIntent=20=E5=9B=9E=E5=88=B0=E7=95=85=E7=8E=A9?= =?UTF-8?q?=E6=B8=B8=E6=88=8F=E7=AE=A1=E7=90=86=E5=88=97=E8=A1=A8=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E6=AD=A3=E5=B8=B8=E5=88=B7=E6=96=B0=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/vspace/VDownloadManagerActivity.kt | 16 ++++++++++++---- .../gh/vspace/VDownloadManagerWrapperFragment.kt | 8 ++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt index c7d66a0f8b..cf6072a0c9 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt @@ -9,19 +9,27 @@ import com.gh.gamecenter.common.constant.EntranceConsts class VDownloadManagerActivity: ToolBarActivity() { + private var mFragment : VDownloadManagerWrapperFragment? = null + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (savedInstanceState == null) { - val fragment = VDownloadManagerWrapperFragment() - fragment.arguments = intent.extras - supportFragmentManager.beginTransaction().replace(R.id.placeholder, fragment).commitAllowingStateLoss() - updateTargetFragment(fragment) + mFragment = VDownloadManagerWrapperFragment() + mFragment?.arguments = intent.extras + supportFragmentManager.beginTransaction().replace(R.id.placeholder, mFragment!!).commitAllowingStateLoss() + updateTargetFragment(mFragment) } } override fun getLayoutId() = R.layout.activity_vdownload_manager + override fun onNewIntent(intent: Intent?) { + super.onNewIntent(intent) + + mFragment?.onNewIntent() + } + companion object { @JvmStatic @JvmOverloads diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt index d40c94c524..0c08ddd315 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt @@ -70,6 +70,14 @@ class VDownloadManagerWrapperFragment: BaseLazyTabFragment() { tabTitleList.add("下载") } + fun onNewIntent() { + childFragmentManager.fragments.forEach { + if (it.isAdded && it is VDownloadManagerFragment) { + it.onLoadRefresh() + } + } + } + override fun onPageSelected(position: Int) { super.onPageSelected(position) mViewModel.currentOptionLiveData.value = ManageOption.OPTION_MANAGER From 0821f0058486f0994ea7415f6f2208ef152c7ef2 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Tue, 30 Aug 2022 13:46:09 +0800 Subject: [PATCH 196/217] =?UTF-8?q?fix:=20=E6=B7=BB=E5=8A=A0=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E5=A4=87=E4=BB=BD=E5=AE=8C=E6=95=B4=E6=80=A7=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=EF=BC=8C=E9=81=BF=E5=85=8D=E6=95=B0=E6=8D=AE=E5=BC=82?= =?UTF-8?q?=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/gh/vspace/VBackupHelper.kt | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VBackupHelper.kt b/app/src/main/java/com/gh/vspace/VBackupHelper.kt index ef86fb0da3..48693ed656 100644 --- a/app/src/main/java/com/gh/vspace/VBackupHelper.kt +++ b/app/src/main/java/com/gh/vspace/VBackupHelper.kt @@ -1,20 +1,26 @@ package com.gh.vspace import android.content.Context +import android.os.Build import android.os.Environment import com.gh.download.DownloadManager import com.gh.gamecenter.common.utils.isVGame import com.gh.gamecenter.core.runOnIoThread +import com.gh.gamecenter.core.utils.MD5Utils import com.gh.vspace.db.VGameDatabase import com.lightgame.download.DownloadStatus import com.lightgame.utils.Utils +import net.lingala.zip4j.ZipFile import java.io.File import java.io.FileInputStream import java.io.FileOutputStream import java.nio.channels.FileChannel +import java.nio.file.Files object VBackupHelper { + private const val BACKUP_FOLDER = "/gh-files/vspace_backup" + fun recoverValidData(context: Context) { runOnIoThread { recoverFromBackupDb(context) @@ -31,11 +37,25 @@ object VBackupHelper { private fun recoverFromBackupDb(context: Context) { try { - val backupDir = File(Environment.getExternalStorageDirectory().absolutePath + "/gh-files") + val backupDir = File(Environment.getExternalStorageDirectory().absolutePath + BACKUP_FOLDER) + val backupSubDir = File(Environment.getExternalStorageDirectory().absolutePath + BACKUP_FOLDER + "/files") val databaseDir: File? = context.getDatabasePath(VGameDatabase.DATABASE).parentFile if (backupDir.canWrite() && databaseDir != null) { backupDir.listFiles()?.forEach { + if (it.name.endsWith(".zip")) { + if (MD5Utils.calculateMD5(it) == it.nameWithoutExtension) { + val zipFile = ZipFile(it) + zipFile.extractAll(backupDir.absolutePath) + } else { + Utils.log("备份的压缩包 MD5 变了,可能损坏,中止还原") + return + } + } + it.delete() + } + + backupSubDir.listFiles()?.forEach { if (it.name.endsWith(".bak")) { val src: FileChannel = FileInputStream(it).channel val dst: FileChannel = @@ -49,6 +69,8 @@ object VBackupHelper { Utils.log("Recover ${it.name} successful!") } } + + backupDir.deleteRecursively() } } catch (e: Exception) { e.printStackTrace() @@ -59,16 +81,22 @@ object VBackupHelper { * 备份现有数据库到 SD 卡 */ fun backupDBToExternalStorage(context: Context) { - val backupDir = File(Environment.getExternalStorageDirectory().absolutePath + "/gh-files") + val backupDir = File(Environment.getExternalStorageDirectory().absolutePath + BACKUP_FOLDER) + val backupSubDir = File(Environment.getExternalStorageDirectory().absolutePath + BACKUP_FOLDER + "/files") val databaseDir: File? = context.getDatabasePath(VGameDatabase.DATABASE).parentFile + backupDir.deleteRecursively() + + backupDir.mkdir() + backupSubDir.mkdir() + try { - if (backupDir.canWrite() && databaseDir != null) { + if (backupSubDir.canWrite() && databaseDir != null) { databaseDir.listFiles()?.forEach { if (it.name.contains(VGameDatabase.DATABASE)) { val src: FileChannel = FileInputStream(it).channel val dst: FileChannel = - FileOutputStream(File(backupDir.absolutePath + "/${it.name}" + ".bak")).channel + FileOutputStream(File(backupSubDir.absolutePath + "/${it.name}" + ".bak")).channel dst.transferFrom(src, 0, src.size()) src.close() dst.close() @@ -77,6 +105,15 @@ object VBackupHelper { } } } + + val backupZip = ZipFile(backupDir.absolutePath + "/" + backupSubDir.name + ".zip").apply { addFolder(backupSubDir) } + + backupSubDir.deleteRecursively() + + val fileName = MD5Utils.calculateMD5(backupZip.file) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + Files.move(backupZip.file.toPath(), File(backupDir.absolutePath +"/" + fileName + ".zip").toPath()) + } } catch (e: Exception) { e.printStackTrace() } From 2ff948dab17036fb4969e2f2fab439fbdeb080e1 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Tue, 30 Aug 2022 15:33:47 +0800 Subject: [PATCH 197/217] =?UTF-8?q?fix:=20=E7=BC=93=E5=AD=98=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E6=B8=B8=E6=88=8F=E6=B8=B8=E7=8E=A9=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E5=92=8C=E5=8D=A0=E7=94=A8=E7=A9=BA=E9=97=B4=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E7=95=85=E7=8E=A9=E6=B8=B8=E6=88=8F=20newIntent=20?= =?UTF-8?q?=E6=97=B6=20tab=20=E5=AE=9A=E4=BD=8D=E4=B8=8D=E7=94=9F=E6=95=88?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/gh/vspace/VBackupHelper.kt | 11 ------- .../com/gh/vspace/VDownloadManagerActivity.kt | 2 +- .../gh/vspace/VDownloadManagerViewModel.kt | 8 +++-- .../vspace/VDownloadManagerWrapperFragment.kt | 7 ++++- app/src/main/java/com/gh/vspace/VHelper.kt | 29 ++++++++++++------- 5 files changed, 31 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/com/gh/vspace/VBackupHelper.kt b/app/src/main/java/com/gh/vspace/VBackupHelper.kt index 48693ed656..ebd2d1269d 100644 --- a/app/src/main/java/com/gh/vspace/VBackupHelper.kt +++ b/app/src/main/java/com/gh/vspace/VBackupHelper.kt @@ -3,12 +3,9 @@ package com.gh.vspace import android.content.Context import android.os.Build import android.os.Environment -import com.gh.download.DownloadManager -import com.gh.gamecenter.common.utils.isVGame import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.core.utils.MD5Utils import com.gh.vspace.db.VGameDatabase -import com.lightgame.download.DownloadStatus import com.lightgame.utils.Utils import net.lingala.zip4j.ZipFile import java.io.File @@ -24,14 +21,6 @@ object VBackupHelper { fun recoverValidData(context: Context) { runOnIoThread { recoverFromBackupDb(context) - - val entityList = DownloadManager.getInstance().allDownloadEntity - - for (entity in entityList) { - if (!entity.isVGame() || entity.status != DownloadStatus.done) { - DownloadManager.getInstance().cancel(entity.url) - } - } } } diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt index cf6072a0c9..4b8f8f1ffc 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerActivity.kt @@ -27,7 +27,7 @@ class VDownloadManagerActivity: ToolBarActivity() { override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) - mFragment?.onNewIntent() + mFragment?.onNewIntent(intent) } companion object { diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index 7fbcc843f3..001fa5a809 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -62,11 +62,13 @@ class VDownloadManagerViewModel(application: Application) : gameEntity.des = "已畅玩${NumberUtils.transSimpleUsageTime(gameEntity.playedTime / 1000)}" } else { - val occupiedSpace = + var occupiedSpace = VHelper.getAppOccupiedSpace(vGame.downloadEntity.packageName) - if (occupiedSpace > 0) { - gameEntity.des = "已占用 ${occupiedSpace.toProperReadableSize()}" + if (occupiedSpace == 0L) { + occupiedSpace = vGame.downloadEntity.size } + + gameEntity.des = "已占用 ${occupiedSpace.toProperReadableSize()}" } gameList.add(gameEntity) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt index 0c08ddd315..3fbe0d9d0a 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerWrapperFragment.kt @@ -1,5 +1,6 @@ package com.gh.vspace +import android.content.Intent import android.os.Bundle import android.view.MenuItem import android.view.View @@ -70,12 +71,16 @@ class VDownloadManagerWrapperFragment: BaseLazyTabFragment() { tabTitleList.add("下载") } - fun onNewIntent() { + fun onNewIntent(intent: Intent?) { childFragmentManager.fragments.forEach { if (it.isAdded && it is VDownloadManagerFragment) { it.onLoadRefresh() } } + + intent?.getIntExtra(EntranceConsts.KEY_POSITION, 0)?.let { + mViewPager.post { mViewPager.currentItem = it } + } } override fun onPageSelected(position: Int) { diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 77fdb57db5..7469fad256 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -61,6 +61,7 @@ object VHelper { private const val KEY_LAST_PLAYED_TIME = "last_played_time" private const val KEY_LAST_ALERT_UPDATE_URL = "last_alert_update_url" + private const val KEY_TOTAL_PLAYED_TIME = "total_played_time" const val DEFAULT_VSPACE_PACKAGENAME = "com.lg.vspace" const val PLATFORM_V = "畅玩版" @@ -527,7 +528,7 @@ object VHelper { mLastSuccessfullyLaunchedGame = Pair(System.currentTimeMillis(), packageName) runOnIoThread { - updateLastPlayedTime(packageName) + updateVGamePlayedTime(packageName, System.currentTimeMillis(), getPlayedTime(packageName)) VBackupHelper.backupDBToExternalStorage(HaloApp.getInstance()) } } catch (e: Exception) { @@ -602,14 +603,12 @@ object VHelper { } /** - * 更新游戏最后打开的时间 + * 更新数据库重中的畅玩游戏 */ - private fun updateLastPlayedTime(packageName: String) { + private fun updateVGamePlayedTime(packageName: String, lastPlayedTime: Long, totalPlayedTime: Long) { getVGameSnapshot(null, packageName)?.let { - it.downloadEntity.addMetaExtra( - KEY_LAST_PLAYED_TIME, - System.currentTimeMillis().toString() - ) + it.downloadEntity.addMetaExtra(KEY_LAST_PLAYED_TIME, totalPlayedTime.toString()) + it.downloadEntity.addMetaExtra(KEY_TOTAL_PLAYED_TIME, totalPlayedTime.toString()) mVGameDao.insert(it) } @@ -761,14 +760,24 @@ object VHelper { rawIcon = downloadEntity.getMetaExtra(Constants.RAW_GAME_ICON) iconSubscript = downloadEntity.getMetaExtra(Constants.GAME_ICON_SUBSCRIPT) lastPlayedTime = if (lastPlayedTimeString == "") 0L else lastPlayedTimeString.toLong() - playedTime = - mInstalledInfoList.firstOrNull { it.packageName == getUniquePackageName() }?.appTotalPlayTime - ?: 0 + playedTime = getPlayedTime(downloadEntity.packageName, downloadEntity) downloadStatus = "smooth" setEntryMap(DownloadManager.getInstance().getEntryMap(name)) } } + private fun getPlayedTime(packageName: String, downloadEntity: DownloadEntity? = null): Long { + var playedTime = + mInstalledInfoList.firstOrNull { it.packageName == packageName }?.appTotalPlayTime ?: 0L + + val cachedPlayedTimeString = downloadEntity?.getMetaExtra(KEY_TOTAL_PLAYED_TIME) + if (playedTime == 0L && !cachedPlayedTimeString.isNullOrEmpty()) { + playedTime = cachedPlayedTimeString.toLong() + } + + return playedTime + } + @SuppressLint("CheckResult") private fun checkVSpaceUpdate(config: VSetting.VaArch) { val installedVersionName = From 1753224cc4faf14429baffd54610a2cbcab6d282 Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 30 Aug 2022 17:17:40 +0800 Subject: [PATCH 198/217] =?UTF-8?q?build:=20=E6=AD=A3=E5=BC=8F=E5=8C=85?= =?UTF-8?q?=E7=95=85=E7=8E=A9=E5=BC=80=E5=85=B3=E9=BB=98=E8=AE=A4=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E5=BC=80=E5=90=AF=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/build_with_simple_backup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build_with_simple_backup.sh b/scripts/build_with_simple_backup.sh index 2ac6f67e4e..6b72e33d26 100755 --- a/scripts/build_with_simple_backup.sh +++ b/scripts/build_with_simple_backup.sh @@ -31,7 +31,7 @@ rm -r module_common/src/main/res/drawable-night-xxxhdpi rm -r module_common/src/main/res/drawable-night-nodpi rm -r module_common/src/main/res/drawable-night sed -i 's/buildConfigField "boolean", "IS_NIGHT_MODE_ON", "true"/buildConfigField "boolean", "IS_NIGHT_MODE_ON", "false"/g' module_common/build.gradle -sed -i 's/buildConfigField "boolean", "IS_VGAME_ON", "true"/buildConfigField "boolean", "IS_VGAME_ON", "false"/g' module_common/build.gradle +sed -i 's/buildConfigField "boolean", "IS_VGAME_ON", "true"/buildConfigField "boolean", "IS_VGAME_ON", "true"/g' module_common/build.gradle ./gradlew --stop ./gradlew clean From fa2c86c3f154e594dec7ee593f2f7a506f912a08 Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 30 Aug 2022 17:55:35 +0800 Subject: [PATCH 199/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=95=85?= =?UTF-8?q?=E7=8E=A9=E9=85=8D=E7=BD=AE=E5=8A=A0=E8=BD=BD=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E8=A7=A6=E5=8F=91=E7=9A=84=E9=97=AA=E9=80=80=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VHelper.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 7469fad256..da24481ffd 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -644,10 +644,11 @@ object VHelper { if (vaConfig == null) { ToastUtils.toast("畅玩空间暂未上线") + return true } // TODO 检测 32 位 - if (!PackageUtils.isInstalled(context, vaConfig!!.arch64?.packageName)) { + if (!PackageUtils.isInstalled(context, vaConfig.arch64?.packageName)) { VSpaceDialogFragment.showDownloadDialog(context, getVSpaceDownloadEntity(false)) Utils.log(LOG_TAG, "显示下载畅玩空间弹窗") return true From 5dd0734aad97b5b92fe9398d81ffd581e82467ad Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 30 Aug 2022 18:13:59 +0800 Subject: [PATCH 200/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=AD=A3?= =?UTF-8?q?=E5=BC=8F=E5=8C=85=E7=95=85=E7=8E=A9=E9=93=BE=E6=8E=A5=E4=B8=8D?= =?UTF-8?q?=E6=AD=A3=E7=A1=AE=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 9f24fe436b..b482fa465a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -165,7 +165,7 @@ android { buildConfigField "String", "DEV_API_HOST", "\"${API_HOST}\"" buildConfigField "String", "NEW_DEV_API_HOST", "\"${NEW_API_HOST}\"" - buildConfigField "String", "DEV_VAPI_HOST", "\"${API_HOST}\"" + buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\"" } tea { @@ -173,7 +173,7 @@ android { buildConfigField "String", "DEV_API_HOST", "\"${API_HOST}\"" buildConfigField "String", "NEW_DEV_API_HOST", "\"${NEW_API_HOST}\"" - buildConfigField "String", "DEV_VAPI_HOST", "\"${API_HOST}\"" + buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\"" manifestPlaceholders.put("APPLOG_SCHEME", "rangersapplog.byAx6uYt".toLowerCase()) } From 31d8a442a3ab63cf6448d7d3e154ca308500f039 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Thu, 1 Sep 2022 13:58:43 +0800 Subject: [PATCH 201/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E5=AE=9E=E4=BE=8B=E5=BF=AB=E7=85=A7=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E4=B8=BA=E7=A9=BA=E6=97=B6=E7=9A=84=E9=97=AA=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/download/DownloadManager.java | 2 +- libraries/LGLibrary | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index 880653dded..01df0b840d 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -649,7 +649,7 @@ public class DownloadManager implements DownloadStatusListener { public void initGameMap() { gameMap.clear(); List list = getAllDownloadEntitySnapshots(); - if (list != null && list.size() != 0) { + if (list.size() != 0) { String name; for (DownloadEntity downloadEntity : list) { name = downloadEntity.getName(); diff --git a/libraries/LGLibrary b/libraries/LGLibrary index fbc7818022..0e6ff1678f 160000 --- a/libraries/LGLibrary +++ b/libraries/LGLibrary @@ -1 +1 @@ -Subproject commit fbc7818022c42b7823b54ece34d6c9a094d9896f +Subproject commit 0e6ff1678f7b5f070bcfa19c557fa5201af6de37 From 8e068684e0c46faa487c400a8f6490cf97f7050c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Thu, 1 Sep 2022 14:45:13 +0800 Subject: [PATCH 202/217] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E5=8F=AF=E8=83=BD=E5=87=BA=E7=8E=B0=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E7=BB=84=E8=B6=8A=E7=95=8C=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt b/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt index b7efd9ebed..22d2b22161 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt @@ -70,9 +70,6 @@ class HomeFragment : LazyFragment() { mViewModel = viewModelProvider() mHomeSearchViewModel = viewModelProviderFromParent() mViewModel.homeOnlyWithoutOtherTab = arguments?.getInt(EntranceConsts.KEY_TAB_COUNT) == 1 - val homeDataEntity = mHomeSearchViewModel.homeDataLiveData.value - mViewModel.initData(homeDataEntity) - super.onFragmentFirstVisible() mViewModel.itemDataList.observeNonNull(this, callback = { From ce16ad471bd436abb42ded44cb45dbcd73dd95f8 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Thu, 1 Sep 2022 15:11:41 +0800 Subject: [PATCH 203/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E6=B8=B8=E6=88=8F=E6=97=B6=E8=8E=B7=E5=8F=96=E4=B8=8D?= =?UTF-8?q?=E5=88=B0=E7=89=88=E6=9C=AC=E7=9A=84=E9=97=AA=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/gamecenter/eventbus/EBPackage.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/gamecenter/eventbus/EBPackage.kt b/app/src/main/java/com/gh/gamecenter/eventbus/EBPackage.kt index 0505633b0e..b5806fbbd0 100644 --- a/app/src/main/java/com/gh/gamecenter/eventbus/EBPackage.kt +++ b/app/src/main/java/com/gh/gamecenter/eventbus/EBPackage.kt @@ -1,6 +1,6 @@ package com.gh.gamecenter.eventbus -class EBPackage(var type: String, var packageName: String, var versionName: String) { +class EBPackage(var type: String, var packageName: String, var versionName: String?) { var gameId: String? = null } From 15a3624e557409790367e10c3f6cca82f4e4368f Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Thu, 1 Sep 2022 15:12:09 +0800 Subject: [PATCH 204/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E5=AE=8C=E6=88=90=E6=B8=B8=E6=88=8F=E6=97=B6=E5=A4=9A?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97=E9=80=A0?= =?UTF-8?q?=E6=88=90=E7=9A=84=E9=97=AA=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/gamecenter/manager/DataCollectionManager.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/gamecenter/manager/DataCollectionManager.java b/app/src/main/java/com/gh/gamecenter/manager/DataCollectionManager.java index 613262c8b8..3ebbd5f993 100644 --- a/app/src/main/java/com/gh/gamecenter/manager/DataCollectionManager.java +++ b/app/src/main/java/com/gh/gamecenter/manager/DataCollectionManager.java @@ -68,7 +68,9 @@ public class DataCollectionManager { paramsWrapper.put("content", new JSONObject(map).toString()); paramsWrapper.put("time", Utils.getTime(HaloApp.getInstance().getApplication())); - LoghubUtils.log(new JSONObject(paramsWrapper), "collection", true); + AppExecutor.getUiExecutor().execute(() -> { + LoghubUtils.log(new JSONObject(paramsWrapper), "collection", true); + }); } public static DataCollectionManager getInstance() { From 08ac765e9c61bc102b17a4ba91cc2961e895eb3c Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Thu, 1 Sep 2022 15:12:34 +0800 Subject: [PATCH 205/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=A4=9A?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B=E6=93=8D=E4=BD=9C=E4=B8=8B=E8=BD=BD=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BC=95=E8=B5=B7=E7=9A=84=E9=97=AA=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/download/DownloadManager.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index 01df0b840d..5435c8a09d 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -69,7 +69,9 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.LinkedBlockingQueue; public class DownloadManager implements DownloadStatusListener { @@ -83,7 +85,7 @@ public class DownloadManager implements DownloadStatusListener { private final ArrayMap lastTimeMap; private final ArrayMap> platformMap; - private final ArrayMap> gameMap; + private final Map> gameMap; private final ArrayMap statusMap; private final ArrayMap downloadingMap; @@ -173,7 +175,7 @@ public class DownloadManager implements DownloadStatusListener { lastTimeMap = new ArrayMap<>(); platformMap = new ArrayMap<>(); - gameMap = new ArrayMap<>(); + gameMap = new ConcurrentHashMap<>(); statusMap = new ArrayMap<>(); downloadingMap = new ArrayMap<>(); // mDownloadSnapshotList = new ArrayList<>(); From 43c840cd945f72147992c43a5ea17867864baad8 Mon Sep 17 00:00:00 2001 From: juntao Date: Thu, 1 Sep 2022 15:19:21 +0800 Subject: [PATCH 206/217] =?UTF-8?q?chore:=20=E7=89=88=E6=9C=AC=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E8=87=B3=205.12.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dependencies.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 6ca1a5d343..3c1e4dbb72 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -7,8 +7,8 @@ ext { targetSdkVersion = 28 // application info (每个大版本之间的 versionCode 增加 20) - versionCode = 590 - versionName = "5.12.0" + versionCode = 591 + versionName = "5.12.1" applicationId = "com.gh.gamecenter" // AndroidX From e21d8a5ac5385c2ff4c907eb771641597b13b38a Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Thu, 1 Sep 2022 16:27:30 +0800 Subject: [PATCH 207/217] =?UTF-8?q?fix:=20=E5=B0=9D=E8=AF=95=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=90=AF=E5=8A=A8=E4=B8=8B=E8=BD=BD=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E6=97=B6=E7=9A=84=E9=97=AA=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libraries/LGLibrary | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/LGLibrary b/libraries/LGLibrary index 0e6ff1678f..9aa0589b2f 160000 --- a/libraries/LGLibrary +++ b/libraries/LGLibrary @@ -1 +1 @@ -Subproject commit 0e6ff1678f7b5f070bcfa19c557fa5201af6de37 +Subproject commit 9aa0589b2fe51792ca356a83796d2bf46e1608ef From 946bd39fb6fbe4ad097c11c7ff0a73b76e7c1618 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Fri, 2 Sep 2022 10:06:57 +0800 Subject: [PATCH 208/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E5=88=97=E8=A1=A8=E6=9B=B4=E6=96=B0=E6=95=B0=E7=BB=84?= =?UTF-8?q?=E8=B6=8A=E7=95=8C=E9=97=AA=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gh/gamecenter/baselist/DiffUtilAdapter.kt | 58 +++++++++++-------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/baselist/DiffUtilAdapter.kt b/app/src/main/java/com/gh/gamecenter/baselist/DiffUtilAdapter.kt index bda46c9035..788fe2f025 100644 --- a/app/src/main/java/com/gh/gamecenter/baselist/DiffUtilAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/baselist/DiffUtilAdapter.kt @@ -5,6 +5,8 @@ import android.content.Context import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import com.gh.gamecenter.common.utils.safelyGetInRelease +import com.gh.gamecenter.common.utils.testChannelOnly +import com.gh.gamecenter.core.utils.ToastUtils import com.lightgame.adapter.BaseRecyclerAdapter abstract class DiffUtilAdapter(context: Context) : @@ -24,35 +26,43 @@ abstract class DiffUtilAdapter(context: Context) : // 这里用新的数组包裹原数据 val updateDataCopy = ArrayList(updateData) - ListExecutor.workerExecutor.execute { - val diffResult = DiffUtil.calculateDiff(object : DiffUtil.Callback() { - override fun getOldListSize(): Int { - return mDataList.size - } + try { + ListExecutor.workerExecutor.execute { + val diffResult = DiffUtil.calculateDiff(object : DiffUtil.Callback() { + override fun getOldListSize(): Int { + return mDataList.size + } - override fun getNewListSize(): Int { - return updateDataCopy.size - } + override fun getNewListSize(): Int { + return updateDataCopy.size + } - override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { - val oldItem = mDataList.safelyGetInRelease(oldItemPosition) - val newItem = updateDataCopy.safelyGetInRelease(newItemPosition) - return areItemsTheSame(oldItem, newItem) - } + override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { + val oldItem = mDataList.safelyGetInRelease(oldItemPosition) + val newItem = updateDataCopy.safelyGetInRelease(newItemPosition) + return areItemsTheSame(oldItem, newItem) + } - override fun areContentsTheSame( - oldItemPosition: Int, - newItemPosition: Int - ): Boolean { - val oldItem = mDataList.safelyGetInRelease(oldItemPosition) - val newItem = updateDataCopy.safelyGetInRelease(newItemPosition) - return areContentsTheSame(oldItem, newItem) + override fun areContentsTheSame( + oldItemPosition: Int, + newItemPosition: Int + ): Boolean { + val oldItem = mDataList.safelyGetInRelease(oldItemPosition) + val newItem = updateDataCopy.safelyGetInRelease(newItemPosition) + return areContentsTheSame(oldItem, newItem) + } + }) + ListExecutor.uiExecutor.execute { + mDataList = updateDataCopy + diffResult.dispatchUpdatesTo(this@DiffUtilAdapter) } - }) - ListExecutor.uiExecutor.execute { - mDataList = ArrayList(updateData) - diffResult.dispatchUpdatesTo(this@DiffUtilAdapter) } + } catch (e: IndexOutOfBoundsException) { + testChannelOnly { + ToastUtils.toast("DiffUtilAdapter 遇到数组越界异常,请检查") + } + mDataList = updateDataCopy + notifyDataSetChanged() } } From dc4e345ea8f7072a28519b4721e1abcebc705d85 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Fri, 2 Sep 2022 11:12:58 +0800 Subject: [PATCH 209/217] =?UTF-8?q?fix:=20=E5=A4=9A=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E4=B8=8A=E6=8A=A5=E6=97=A5=E5=BF=97=E5=AF=BC=E8=87=B4=E7=9A=84?= =?UTF-8?q?=E9=97=AA=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/common/FixedRateJobHelper.kt | 13 +++--- .../manager/DataCollectionManager.java | 4 +- .../gamecenter/common/loghub/LoghubUtils.kt | 41 +++++++++++-------- .../gh/gamecenter/common/utils/Extensions.kt | 7 +++- .../com/gh/gamecenter/core/AppExecutor.kt | 6 ++- 5 files changed, 42 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/com/gh/common/FixedRateJobHelper.kt b/app/src/main/java/com/gh/common/FixedRateJobHelper.kt index 6835758b5c..6896535c4a 100644 --- a/app/src/main/java/com/gh/common/FixedRateJobHelper.kt +++ b/app/src/main/java/com/gh/common/FixedRateJobHelper.kt @@ -2,13 +2,14 @@ package com.gh.common import com.gh.common.exposure.ExposureManager import com.gh.common.filter.RegionSettingHelper -import com.gh.gamecenter.common.loghub.LoghubUtils -import com.gh.gamecenter.common.utils.doOnMainProcessOnly -import com.gh.gamecenter.common.utils.tryCatchInRelease import com.gh.common.videolog.VideoRecordUtils import com.gh.download.DownloadDataHelper -import com.gh.gamecenter.entity.TimeEntity +import com.gh.gamecenter.common.loghub.LoghubUtils import com.gh.gamecenter.common.retrofit.Response +import com.gh.gamecenter.common.utils.doOnMainProcessOnly +import com.gh.gamecenter.common.utils.tryCatchInRelease +import com.gh.gamecenter.core.runOnUiThread +import com.gh.gamecenter.entity.TimeEntity import com.gh.gamecenter.retrofit.RetrofitManager import com.halo.assistant.HaloApp import io.reactivex.schedulers.Schedulers @@ -60,7 +61,9 @@ object FixedRateJobHelper { // 提交普通 loghub 数据 if ((mExecuteCount * CHECKER_PERIOD) % LOGHUB_PERIOD == 0L) { - LoghubUtils.commitSavedLoghubEvents(true) + runOnUiThread { + LoghubUtils.commitSavedLoghubEvents(true) + } } // 更新游戏屏蔽信息 diff --git a/app/src/main/java/com/gh/gamecenter/manager/DataCollectionManager.java b/app/src/main/java/com/gh/gamecenter/manager/DataCollectionManager.java index 3ebbd5f993..613262c8b8 100644 --- a/app/src/main/java/com/gh/gamecenter/manager/DataCollectionManager.java +++ b/app/src/main/java/com/gh/gamecenter/manager/DataCollectionManager.java @@ -68,9 +68,7 @@ public class DataCollectionManager { paramsWrapper.put("content", new JSONObject(map).toString()); paramsWrapper.put("time", Utils.getTime(HaloApp.getInstance().getApplication())); - AppExecutor.getUiExecutor().execute(() -> { - LoghubUtils.log(new JSONObject(paramsWrapper), "collection", true); - }); + LoghubUtils.log(new JSONObject(paramsWrapper), "collection", true); } public static DataCollectionManager getInstance() { diff --git a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubUtils.kt b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubUtils.kt index fa0a16a945..8150b4e782 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubUtils.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/loghub/LoghubUtils.kt @@ -4,6 +4,7 @@ import androidx.annotation.Keep import com.aliyun.sls.android.producer.Log import com.gh.gamecenter.common.entity.ExposureEntity import com.gh.gamecenter.common.exposure.meta.Meta +import com.gh.gamecenter.core.runOnUiThread import org.json.JSONObject object LoghubUtils { @@ -15,32 +16,36 @@ object LoghubUtils { @JvmStatic @JvmOverloads fun log(logJson: JSONObject, logStore: String, forcedUpload: Boolean, isFlat: Boolean = false) { - val event = LoghubEvent( - time = (System.currentTimeMillis() / 1000L).toString(), - content = logJson.toString(), - logStore = logStore, - isFlat = isFlat - ) - loghubEventSet.add(event) + runOnUiThread { + val event = LoghubEvent( + time = (System.currentTimeMillis() / 1000L).toString(), + content = logJson.toString(), + logStore = logStore, + isFlat = isFlat + ) + loghubEventSet.add(event) - if (forcedUpload || loghubEventSet.size >= STORE_SIZE) { - commitSavedLoghubEvents(forcedUpload) + if (forcedUpload || loghubEventSet.size >= STORE_SIZE) { + commitSavedLoghubEvents(forcedUpload) + } } } @JvmStatic @JvmOverloads fun log(jsonString: String, logStore: String, forcedUpload: Boolean, isFlat: Boolean = false) { - val event = LoghubEvent( - time = (System.currentTimeMillis() / 1000L).toString(), - content = jsonString, - logStore = logStore, - isFlat = isFlat - ) - loghubEventSet.add(event) + runOnUiThread { + val event = LoghubEvent( + time = (System.currentTimeMillis() / 1000L).toString(), + content = jsonString, + logStore = logStore, + isFlat = isFlat + ) + loghubEventSet.add(event) - if (forcedUpload || loghubEventSet.size >= STORE_SIZE) { - commitSavedLoghubEvents(forcedUpload) + if (forcedUpload || loghubEventSet.size >= STORE_SIZE) { + commitSavedLoghubEvents(forcedUpload) + } } } diff --git a/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt b/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt index 6e78e1e60a..95f18c3c2c 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt @@ -12,6 +12,7 @@ import android.graphics.Rect import android.graphics.drawable.Drawable import android.graphics.drawable.GradientDrawable import android.os.Build +import android.os.Looper import android.text.* import android.text.format.Formatter import android.text.style.ClickableSpan @@ -44,14 +45,16 @@ import com.alibaba.android.arouter.launcher.ARouter import com.facebook.drawee.view.SimpleDraweeView import com.gh.gamecenter.common.BuildConfig import com.gh.gamecenter.common.R -import com.gh.gamecenter.common.constant.Constants -import com.gh.gamecenter.common.constant.RouteConsts import com.gh.gamecenter.common.callback.SimpleCallback import com.gh.gamecenter.common.constant.Config +import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.constant.RouteConsts import com.gh.gamecenter.common.view.CustomLinkMovementMethod import com.gh.gamecenter.common.view.ExpandTextView +import com.gh.gamecenter.core.AppExecutor import com.gh.gamecenter.core.HaloApp import com.gh.gamecenter.core.provider.* +import com.gh.gamecenter.core.runOnUiThread import com.gh.gamecenter.core.utils.* import com.google.gson.reflect.TypeToken import com.lightgame.download.DownloadEntity diff --git a/module_core/src/main/java/com/gh/gamecenter/core/AppExecutor.kt b/module_core/src/main/java/com/gh/gamecenter/core/AppExecutor.kt index 66f0cb3cf9..7cbec3dc4e 100644 --- a/module_core/src/main/java/com/gh/gamecenter/core/AppExecutor.kt +++ b/module_core/src/main/java/com/gh/gamecenter/core/AppExecutor.kt @@ -72,5 +72,9 @@ fun runOnIoThread( } fun runOnUiThread(f: () -> Unit) { - uiExecutor.execute(f) + if (Thread.currentThread() == Looper.getMainLooper().thread) { + f.invoke() + } else { + uiExecutor.execute(f) + } } \ No newline at end of file From bcba6c4230f707b2c0d02efea18192b3fd213591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=8E=89=E4=B9=85?= Date: Mon, 5 Sep 2022 10:10:50 +0800 Subject: [PATCH 210/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E5=88=97=E8=A1=A8=E6=95=B0=E6=8D=AE=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E6=92=AD=E6=94=BE=E8=A7=86=E9=A2=91=E6=95=B0?= =?UTF-8?q?=E7=BB=84=E8=B6=8A=E7=95=8C=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index 5833ba6f28..55d163ca53 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -570,7 +570,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { shouldShowDivider = false } } - itemDataList.postValue(mSnapshotItemList) + itemDataList.postValue(ArrayList(mSnapshotItemList)) } } From 125701534d75d4938da270063eb8e9aaf2e60e84 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Mon, 5 Sep 2022 10:19:29 +0800 Subject: [PATCH 211/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E4=B8=8B=E8=BD=BD=E6=9B=B4=E6=96=B0=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=81=B6=E5=8F=91=E7=9A=84=E5=A4=9A=E7=BA=BF=E7=A8=8B=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E9=97=AA=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/gh/gamecenter/home/HomeFragmentAdapter.kt | 2 +- app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt index e81c92248d..b0a546a3d0 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeFragmentAdapter.kt @@ -462,7 +462,7 @@ class HomeFragmentAdapter( fun getGameEntityByPackage(packageName: String): List { val positionList = ArrayList() - val positionMap = viewModel.positionAndPackageMap + val positionMap = viewModel.positionAndPackageMap.value ?: return positionList for (key in positionMap.keys) { if (key.contains(packageName)) { val position = positionMap[key]!! diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index 55d163ca53..12c17cd528 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -62,7 +62,8 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { var homeOnlyWithoutOtherTab = false var itemDataList: MediatorLiveData> = MediatorLiveData() - var positionAndPackageMap = HashMap() // key: packageName + position, value: position + private var mPositionAndPackageMap = HashMap() // key: packageName + position, value: position + var positionAndPackageMap = MutableLiveData>() val loadStatus = MutableLiveData() @@ -408,7 +409,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { for (entity in mVGameList!!) { val packageName = entity.downloadEntity.packageName - positionAndPackageMap[packageName + (mSnapshotItemList.size - 1)] = mSnapshotItemList.size - 1 + mPositionAndPackageMap[packageName + (mSnapshotItemList.size - 1)] = mSnapshotItemList.size - 1 } } @@ -570,6 +571,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { shouldShowDivider = false } } + positionAndPackageMap.postValue(HashMap(mPositionAndPackageMap)) itemDataList.postValue(ArrayList(mSnapshotItemList)) } } @@ -579,7 +581,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { for (apkEntity in game.getApk()) { packages += apkEntity.packageName } - positionAndPackageMap[packages + (mSnapshotItemList.size - 1)] = mSnapshotItemList.size - 1 + mPositionAndPackageMap[packages + (mSnapshotItemList.size - 1)] = mSnapshotItemList.size - 1 game.gameLocation = GameEntity.GameLocation.INDEX game.setEntryMap(DownloadManager.getInstance().getEntryMap(game.name)) } From a3ddf54afcd5b74b150ce88d9927d43bdb67d68f Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Mon, 5 Sep 2022 10:37:12 +0800 Subject: [PATCH 212/217] =?UTF-8?q?chore:=20=E7=89=88=E6=9C=AC=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E8=87=B3=205.12.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dependencies.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 3c1e4dbb72..777faa7ef4 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -7,8 +7,8 @@ ext { targetSdkVersion = 28 // application info (每个大版本之间的 versionCode 增加 20) - versionCode = 591 - versionName = "5.12.1" + versionCode = 592 + versionName = "5.12.2" applicationId = "com.gh.gamecenter" // AndroidX From aec874b3e06b0f45e5107e40a04e125f661681f5 Mon Sep 17 00:00:00 2001 From: chenjuntao Date: Tue, 6 Sep 2022 16:30:17 +0800 Subject: [PATCH 213/217] =?UTF-8?q?fix:=20=E5=B0=9D=E8=AF=95=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=90=AF=E5=8A=A8=E4=B8=8B=E8=BD=BD=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=20https://sentry.shanqu.cc/organizations/lig?= =?UTF-8?q?htgame/issues/203713/=3Fproject=3D22&query=3Ddist%3A592&sort=3D?= =?UTF-8?q?freq&statsPeriod=3D14d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libraries/LGLibrary | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/LGLibrary b/libraries/LGLibrary index 9aa0589b2f..768dcec118 160000 --- a/libraries/LGLibrary +++ b/libraries/LGLibrary @@ -1 +1 @@ -Subproject commit 9aa0589b2fe51792ca356a83796d2bf46e1608ef +Subproject commit 768dcec118e957f9ae3c64c88f2a3a282c0cc53f From aaa2c6330ec29c9bc41519b2b2d4f1fb6107a7af Mon Sep 17 00:00:00 2001 From: juntao Date: Tue, 6 Sep 2022 17:03:31 +0800 Subject: [PATCH 214/217] =?UTF-8?q?chore:=20=E7=89=88=E6=9C=AC=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E8=87=B3=205.12.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dependencies.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 777faa7ef4..f7f37b8290 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -7,8 +7,8 @@ ext { targetSdkVersion = 28 // application info (每个大版本之间的 versionCode 增加 20) - versionCode = 592 - versionName = "5.12.2" + versionCode = 593 + versionName = "5.12.3" applicationId = "com.gh.gamecenter" // AndroidX From ac72abe10543b9ab6c33c86d75680df79c27043d Mon Sep 17 00:00:00 2001 From: liuyirong Date: Tue, 6 Sep 2022 17:29:32 +0800 Subject: [PATCH 215/217] =?UTF-8?q?feat:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8B=E3=80=91=E5=9B=BD=E9=99=85=E6=9C=8D=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E5=90=88=E8=A7=84=E8=B0=83=E6=95=B4=E6=96=B9=E6=A1=88?= =?UTF-8?q?=20https://git.shanqu.cc/pm/halo/halo-app-issues/-/issues/2047?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/filter/RegionSetting.kt | 34 +++++++++++++------ .../gh/common/filter/RegionSettingHelper.kt | 10 ++++++ .../gh/common/util/DetailDownloadUtils.java | 6 ++++ .../com/gh/common/util/DownloadItemUtils.kt | 20 +++++++++-- .../gh/common/view/DownloadProgressBar.java | 2 ++ .../adapter/viewholder/DetailViewHolder.java | 17 ++++++++++ .../com/gh/gamecenter/entity/GameEntity.kt | 2 ++ .../detail/ForumArticleAskListViewModel.kt | 9 ++++- .../retrofit/service/ApiService.java | 2 +- .../common/constant/EntranceConsts.java | 1 + 10 files changed, 89 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/gh/common/filter/RegionSetting.kt b/app/src/main/java/com/gh/common/filter/RegionSetting.kt index 098ec74df9..b538e9972f 100644 --- a/app/src/main/java/com/gh/common/filter/RegionSetting.kt +++ b/app/src/main/java/com/gh/common/filter/RegionSetting.kt @@ -5,17 +5,31 @@ import com.google.gson.annotations.SerializedName @Keep data class RegionSetting( - @SerializedName("game_mirror") - var mirrorGameIdSet: HashSet, - @SerializedName("game_block") - var filterGameIdSet: HashSet, - @SerializedName("channel_control") - var channelControl: ChannelControl) { + @SerializedName("game_mirror") + var mirrorGameIdSet: HashSet, + @SerializedName("game_block") + var filterGameIdSet: HashSet, + @SerializedName("channel_control") + var channelControl: ChannelControl, + @SerializedName("game_special_download") + var gameSpecialDownload: List +) { @Keep data class ChannelControl( - @SerializedName("game_category") - var gameCategory: String, - @SerializedName("effect") - var effect: Boolean) + @SerializedName("game_category") + var gameCategory: String, + @SerializedName("effect") + var effect: Boolean + ) + + @Keep + data class GameSpecialDownload( + @SerializedName("game_id") + var gameId: String, + @SerializedName("bbs_id") + var bbsId: String, + @SerializedName("top_id") + var topId: String + ) } \ No newline at end of file diff --git a/app/src/main/java/com/gh/common/filter/RegionSettingHelper.kt b/app/src/main/java/com/gh/common/filter/RegionSettingHelper.kt index b5eae07f58..d85618fb66 100644 --- a/app/src/main/java/com/gh/common/filter/RegionSettingHelper.kt +++ b/app/src/main/java/com/gh/common/filter/RegionSettingHelper.kt @@ -19,6 +19,7 @@ object RegionSettingHelper { private var mChannelControl: RegionSetting.ChannelControl? = null private var mFilterGameIdSet: HashSet? = hashSetOf() private var mDisplayMirrorIfoGameIdSet: HashSet? = hashSetOf() + private var mGameSpecialDownloadList: List? = listOf() private const val SP_SETTING = "region_setting" @@ -31,6 +32,14 @@ object RegionSettingHelper { return mFilterGameIdSet?.contains(gameId) ?: false } + fun shouldThisGameShowSpecialDownload(gameId: String) = mGameSpecialDownloadList?.any { it.gameId == gameId } ?: false + + @JvmStatic + fun getGameSpecialDownloadBbsId(gameId: String) = mGameSpecialDownloadList?.find { it.gameId == gameId }?.bbsId ?: "" + + @JvmStatic + fun getGameSpecialDownloadTopId(gameId: String) = mGameSpecialDownloadList?.find { it.gameId == gameId }?.topId ?: "" + @JvmStatic fun filterGame(list: List?): ArrayList { if (list == null) return arrayListOf() @@ -86,6 +95,7 @@ object RegionSettingHelper { mFilterGameIdSet = data.filterGameIdSet mDisplayMirrorIfoGameIdSet = data.mirrorGameIdSet mChannelControl = data.channelControl + mGameSpecialDownloadList = data.gameSpecialDownload } /** diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index d7c7078d82..0daf6f33ff 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -48,6 +48,12 @@ public class DetailDownloadUtils { return; } + if (viewHolder.gameEntity.isSpecialDownload()) { + viewHolder.mDownloadPb.setText("前往论坛讨论"); + viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.SPECIAL_DOWNLOAD); + return; + } + if (viewHolder.gameEntity.isReservable()) { if (!ReservationRepository.thisGameHasBeenReserved(viewHolder.gameEntity.getId())) { if (TextUtils.isEmpty(downloadAddWord)) { diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index a2c97ed398..af64b340be 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -15,6 +15,7 @@ import com.gh.common.dialog.CertificationDialog import com.gh.common.dialog.DeviceRemindDialog import com.gh.common.dialog.PackageCheckDialogFragment import com.gh.common.exposure.ExposureEvent +import com.gh.common.filter.RegionSettingHelper import com.gh.common.history.HistoryHelper import com.gh.common.repository.ReservationRepository import com.gh.common.simulator.SimulatorDownloadManager @@ -29,6 +30,7 @@ import com.gh.gamecenter.R import com.gh.gamecenter.WebActivity import com.gh.gamecenter.adapter.viewholder.GameViewHolder import com.gh.gamecenter.common.constant.Constants +import com.gh.gamecenter.common.constant.EntranceConsts import com.gh.gamecenter.common.utils.* import com.gh.gamecenter.core.utils.* import com.gh.gamecenter.entity.GameEntity @@ -176,8 +178,8 @@ object DownloadItemUtils { downloadBtn.background = R.drawable.download_button_normal_style.toDrawable(context) // 控制是否显示下载按钮 downloadBtn.goneIf(!Config.isShowDownload(gameEntity.id) || context.getString(R.string.app_name) == gameEntity.name) - // 青少年模式显示查看 - if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) { + // 青少年模式或者需要特殊处理显示查看 + if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE) || gameEntity.isSpecialDownload()) { downloadBtn.text = "查看" return } @@ -545,6 +547,20 @@ object DownloadItemUtils { } return } + if (gameEntity.isSpecialDownload()) { + val bbsId = RegionSettingHelper.getGameSpecialDownloadBbsId(gameEntity.id) + val topId = RegionSettingHelper.getGameSpecialDownloadTopId(gameEntity.id) + downloadBtn.setOnClickListener { + if (bbsId.isNotBlank()) { + if (topId.isNotBlank()) { + val data = hashMapOf(EntranceConsts.KEY_TOP_ID to topId) + PageSwitchDataHelper.pushCurrentPageData(data) + } + DirectUtils.directForumDetail(context, bbsId, entrance) + } + } + return + } if (gameEntity.isReservable) { if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.id)) { downloadBtn.setOnClickListener { diff --git a/app/src/main/java/com/gh/common/view/DownloadProgressBar.java b/app/src/main/java/com/gh/common/view/DownloadProgressBar.java index 4acc1a178f..e9481040b0 100644 --- a/app/src/main/java/com/gh/common/view/DownloadProgressBar.java +++ b/app/src/main/java/com/gh/common/view/DownloadProgressBar.java @@ -41,6 +41,7 @@ public class DownloadProgressBar extends ProgressBar { H5_GAME, UPDATING, TEENAGER_MODEL, + SPECIAL_DOWNLOAD, XAPK_UNZIPPING, XAPK_SUCCESS, @@ -231,6 +232,7 @@ public class DownloadProgressBar extends ProgressBar { mDefaultColor = ContextCompat.getColor(getContext(), R.color.white); break; case TEENAGER_MODEL: + case SPECIAL_DOWNLOAD: setProgressDrawable(getResources().getDrawable(R.drawable.download_button_normal_style)); mDefaultColor = ContextCompat.getColor(getContext(), R.color.white); break; diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java index fb940b161f..342ffa2817 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java @@ -11,6 +11,8 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.DialogFragment; import androidx.fragment.app.FragmentActivity; +import com.gh.common.filter.RegionSettingHelper; +import com.gh.common.util.DirectUtils; import com.gh.gamecenter.common.constant.Constants; import com.gh.common.dialog.CertificationDialog; import com.gh.common.dialog.DeviceRemindDialog; @@ -21,6 +23,7 @@ import com.gh.common.history.HistoryHelper; import com.gh.common.simulator.SimulatorDownloadManager; import com.gh.common.simulator.SimulatorGameManager; import com.gh.common.util.CheckLoginUtils; +import com.gh.gamecenter.common.constant.EntranceConsts; import com.gh.gamecenter.common.utils.DataLogUtils; import com.gh.common.util.DetailDownloadUtils; import com.gh.gamecenter.common.utils.DialogHelper; @@ -33,6 +36,7 @@ import com.gh.common.util.PackageInstaller; import com.gh.common.util.PackageUtils; import com.gh.gamecenter.common.utils.PermissionHelper; import com.gh.common.util.ReservationHelper; +import com.gh.gamecenter.core.utils.PageSwitchDataHelper; import com.gh.gamecenter.core.utils.StringUtils; import com.gh.common.view.DownloadProgressBar; import com.gh.download.DownloadManager; @@ -59,6 +63,7 @@ import com.lightgame.utils.Utils; import org.greenrobot.eventbus.EventBus; import java.io.File; +import java.util.HashMap; /** * Created by khy on 27/06/17. @@ -351,6 +356,18 @@ public class DetailViewHolder { } ); break; + case SPECIAL_DOWNLOAD: + String bbsId = RegionSettingHelper.getGameSpecialDownloadBbsId(mGameEntity.getId()); + String topId = RegionSettingHelper.getGameSpecialDownloadTopId(mGameEntity.getId()); + if (!TextUtils.isEmpty(bbsId)) { + if (!TextUtils.isEmpty(topId)) { + HashMap map = new HashMap<>(); + map.put(EntranceConsts.KEY_TOP_ID, topId); + PageSwitchDataHelper.pushCurrentPageData(map); + } + DirectUtils.directForumDetail(mViewHolder.context, bbsId, mEntrance); + } + break; default: if (mGameEntity.isVGame()) { mViewHolder.context.startActivity(VDownloadManagerActivity.getIntent(mViewHolder.context, true)); diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt index 50487a0be9..f46300e47e 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt @@ -600,6 +600,8 @@ data class GameEntity( } } + fun isSpecialDownload() = RegionSettingHelper.shouldThisGameShowSpecialDownload(id) + fun toSimpleGame(): SimpleGame { val simpleGame = SimpleGame() simpleGame.id = id diff --git a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListViewModel.kt b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListViewModel.kt index c9defe8f2c..83064d3d73 100644 --- a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListViewModel.kt @@ -5,6 +5,8 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import com.gh.gamecenter.core.utils.UrlFilterUtils import com.gh.gamecenter.baselist.ListViewModel +import com.gh.gamecenter.common.constant.EntranceConsts +import com.gh.gamecenter.core.utils.PageSwitchDataHelper import com.gh.gamecenter.entity.ForumVideoEntity import com.gh.gamecenter.qa.entity.AnswerEntity import com.gh.gamecenter.retrofit.RetrofitManager @@ -20,7 +22,12 @@ class ForumArticleAskListViewModel(application: Application, val bbsId: String = override fun provideDataObservable(page: Int): Observable> { return when (mPath) { "全部" -> { - RetrofitManager.getInstance().api.getAllForumList(bbsId, UrlFilterUtils.getFilterQuery(sort, "-1"), page) + val data = PageSwitchDataHelper.popLastPageData() + val map = hashMapOf() + if (data != null && data.containsKey(EntranceConsts.KEY_TOP_ID)) { + map["top_id"] = data[EntranceConsts.KEY_TOP_ID] + } + RetrofitManager.getInstance().api.getAllForumList(bbsId, UrlFilterUtils.getFilterQuery(sort, "-1"), page, map) } "精华" -> { RetrofitManager.getInstance().api.getEssenceForumList(bbsId, page) diff --git a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java index 7f2c419d3e..5d97c564eb 100644 --- a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java +++ b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java @@ -2654,7 +2654,7 @@ public interface ApiService { * 获取论坛全部Tab内容(社区文章+问题) */ @GET("bbses/{bbs_id}/contents") - Observable> getAllForumList(@Path("bbs_id") String bbsId, @Query("sort") String sort, @Query("page") int page); + Observable> getAllForumList(@Path("bbs_id") String bbsId, @Query("sort") String sort, @Query("page") int page, @QueryMap Map params); /** * 获取论坛精华Tab内容(社区文章) diff --git a/module_common/src/main/java/com/gh/gamecenter/common/constant/EntranceConsts.java b/module_common/src/main/java/com/gh/gamecenter/common/constant/EntranceConsts.java index 6802e3a18e..bf5b7dc823 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/constant/EntranceConsts.java +++ b/module_common/src/main/java/com/gh/gamecenter/common/constant/EntranceConsts.java @@ -253,4 +253,5 @@ public class EntranceConsts { public static final String KEY_FORMAT = "format"; public static final String KEY_VERSION_CODE = "version_code"; public static final String KEY_PLATFORM_REQUESTS_ID = "platform_requests_id"; + public static final String KEY_TOP_ID = "top_id"; } From fa740bacb36cdf250437ec0ddfa60ecf0778dc24 Mon Sep 17 00:00:00 2001 From: juntao Date: Wed, 7 Sep 2022 15:44:27 +0800 Subject: [PATCH 216/217] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E7=9A=84=E7=95=85=E7=8E=A9=20toast=20=E6=8F=90?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/gh/vspace/VHelper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index da24481ffd..1157de9359 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -145,7 +145,7 @@ object VHelper { override fun onServiceConnectionFailed(failCode: Int) { if (failCode == BinderPool.CONNECT_STATE_NOT_INSTALLED) { - ToastUtils.toast("请先安装畅玩助手") + Utils.log(LOG_TAG, "未安装畅玩助手") } Utils.log(LOG_TAG, "V 服务连接失败") } From ce840cf33e5a0bdaddae9efc63d5985dca4e916f Mon Sep 17 00:00:00 2001 From: liuyirong Date: Wed, 7 Sep 2022 17:41:00 +0800 Subject: [PATCH 217/217] =?UTF-8?q?feat:=E3=80=90=E5=85=89=E7=8E=AF?= =?UTF-8?q?=E5=8A=A9=E6=89=8B=E3=80=91=E5=9B=BD=E9=99=85=E6=9C=8D=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E5=90=88=E8=A7=84=E8=B0=83=E6=95=B4=E6=96=B9=E6=A1=88?= =?UTF-8?q?(=E9=9C=80=E6=B1=82=E5=8F=98=E5=8A=A8)=20https://git.shanqu.cc/?= =?UTF-8?q?pm/halo/halo-app-issues/-/issues/2047#note=5F169012?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gh/common/filter/RegionSetting.kt | 12 ++++--- .../gh/common/filter/RegionSettingHelper.kt | 11 +++---- .../gh/common/util/DetailDownloadUtils.java | 2 +- .../com/gh/common/util/DownloadItemUtils.kt | 31 +++++++++++++------ .../adapter/viewholder/DetailViewHolder.java | 18 ++++++----- 5 files changed, 44 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/com/gh/common/filter/RegionSetting.kt b/app/src/main/java/com/gh/common/filter/RegionSetting.kt index b538e9972f..e59bef8148 100644 --- a/app/src/main/java/com/gh/common/filter/RegionSetting.kt +++ b/app/src/main/java/com/gh/common/filter/RegionSetting.kt @@ -12,7 +12,7 @@ data class RegionSetting( @SerializedName("channel_control") var channelControl: ChannelControl, @SerializedName("game_special_download") - var gameSpecialDownload: List + var gameSpecialDownloadInfoList: List ) { @Keep @@ -24,12 +24,14 @@ data class RegionSetting( ) @Keep - data class GameSpecialDownload( + data class GameSpecialDownloadInfo( @SerializedName("game_id") - var gameId: String, + var gameId: String = "", @SerializedName("bbs_id") - var bbsId: String, + var bbsId: String = "", @SerializedName("top_id") - var topId: String + var topId: String = "", + @SerializedName("hint_text") + var hintText: String = "" ) } \ No newline at end of file diff --git a/app/src/main/java/com/gh/common/filter/RegionSettingHelper.kt b/app/src/main/java/com/gh/common/filter/RegionSettingHelper.kt index d85618fb66..2080cc8639 100644 --- a/app/src/main/java/com/gh/common/filter/RegionSettingHelper.kt +++ b/app/src/main/java/com/gh/common/filter/RegionSettingHelper.kt @@ -19,7 +19,7 @@ object RegionSettingHelper { private var mChannelControl: RegionSetting.ChannelControl? = null private var mFilterGameIdSet: HashSet? = hashSetOf() private var mDisplayMirrorIfoGameIdSet: HashSet? = hashSetOf() - private var mGameSpecialDownloadList: List? = listOf() + private var mGameSpecialDownloadInfoList: List? = listOf() private const val SP_SETTING = "region_setting" @@ -32,13 +32,10 @@ object RegionSettingHelper { return mFilterGameIdSet?.contains(gameId) ?: false } - fun shouldThisGameShowSpecialDownload(gameId: String) = mGameSpecialDownloadList?.any { it.gameId == gameId } ?: false + fun shouldThisGameShowSpecialDownload(gameId: String) = mGameSpecialDownloadInfoList?.any { it.gameId == gameId } ?: false @JvmStatic - fun getGameSpecialDownloadBbsId(gameId: String) = mGameSpecialDownloadList?.find { it.gameId == gameId }?.bbsId ?: "" - - @JvmStatic - fun getGameSpecialDownloadTopId(gameId: String) = mGameSpecialDownloadList?.find { it.gameId == gameId }?.topId ?: "" + fun getGameSpecialDownloadInfo(gameId: String) = mGameSpecialDownloadInfoList?.find { it.gameId == gameId } @JvmStatic fun filterGame(list: List?): ArrayList { @@ -95,7 +92,7 @@ object RegionSettingHelper { mFilterGameIdSet = data.filterGameIdSet mDisplayMirrorIfoGameIdSet = data.mirrorGameIdSet mChannelControl = data.channelControl - mGameSpecialDownloadList = data.gameSpecialDownload + mGameSpecialDownloadInfoList = data.gameSpecialDownloadInfoList } /** diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index 0daf6f33ff..ceec3a579d 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -49,7 +49,7 @@ public class DetailDownloadUtils { } if (viewHolder.gameEntity.isSpecialDownload()) { - viewHolder.mDownloadPb.setText("前往论坛讨论"); + viewHolder.mDownloadPb.setText("查看下载资源"); viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.SPECIAL_DOWNLOAD); return; } diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index af64b340be..b6a9f1c569 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -548,16 +548,29 @@ object DownloadItemUtils { return } if (gameEntity.isSpecialDownload()) { - val bbsId = RegionSettingHelper.getGameSpecialDownloadBbsId(gameEntity.id) - val topId = RegionSettingHelper.getGameSpecialDownloadTopId(gameEntity.id) + val info = RegionSettingHelper.getGameSpecialDownloadInfo(gameEntity.id) ?: return downloadBtn.setOnClickListener { - if (bbsId.isNotBlank()) { - if (topId.isNotBlank()) { - val data = hashMapOf(EntranceConsts.KEY_TOP_ID to topId) - PageSwitchDataHelper.pushCurrentPageData(data) - } - DirectUtils.directForumDetail(context, bbsId, entrance) - } + DialogHelper.showDialog( + context, + "提示", + info.hintText, + "前往论坛", + "", + { + if (info.bbsId.isNotBlank()) { + if (info.topId.isNotBlank()) { + val data = hashMapOf(EntranceConsts.KEY_TOP_ID to info.topId) + PageSwitchDataHelper.pushCurrentPageData(data) + } + DirectUtils.directForumDetail(context, info.bbsId, entrance) + } + }, + {}, + DialogHelper.Config( + centerTitle = true, + centerContent = true + ) + ) } return } diff --git a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java index 342ffa2817..e7e4dd0746 100644 --- a/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java +++ b/app/src/main/java/com/gh/gamecenter/adapter/viewholder/DetailViewHolder.java @@ -11,6 +11,7 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.DialogFragment; import androidx.fragment.app.FragmentActivity; +import com.gh.common.filter.RegionSetting; import com.gh.common.filter.RegionSettingHelper; import com.gh.common.util.DirectUtils; import com.gh.gamecenter.common.constant.Constants; @@ -357,15 +358,16 @@ public class DetailViewHolder { ); break; case SPECIAL_DOWNLOAD: - String bbsId = RegionSettingHelper.getGameSpecialDownloadBbsId(mGameEntity.getId()); - String topId = RegionSettingHelper.getGameSpecialDownloadTopId(mGameEntity.getId()); - if (!TextUtils.isEmpty(bbsId)) { - if (!TextUtils.isEmpty(topId)) { - HashMap map = new HashMap<>(); - map.put(EntranceConsts.KEY_TOP_ID, topId); - PageSwitchDataHelper.pushCurrentPageData(map); + RegionSetting.GameSpecialDownloadInfo info = RegionSettingHelper.getGameSpecialDownloadInfo(mGameEntity.getId()); + if (info != null) { + if (!TextUtils.isEmpty(info.getBbsId())) { + if (!TextUtils.isEmpty(info.getTopId())) { + HashMap map = new HashMap<>(); + map.put(EntranceConsts.KEY_TOP_ID, info.getTopId()); + PageSwitchDataHelper.pushCurrentPageData(map); + } + DirectUtils.directForumDetail(mViewHolder.context, info.getBbsId(), mEntrance); } - DirectUtils.directForumDetail(mViewHolder.context, bbsId, mEntrance); } break; default: