Compare commits

...

48 Commits

Author SHA1 Message Date
49a610deee feat: 动态java方法注册 2023-10-11 19:41:28 +08:00
61f43d53b2 feat: 文章详情WebView预加载 2023-10-11 15:52:35 +08:00
0dcf5d2097 Merge branch 'fix/GHZS-3596' into 'dev'
fix: 【光环助手】APP内图片显示问题 https://jira.shanqu.cc/browse/GHZS-3596

See merge request halo/android/assistant-android!1375
2023-10-09 15:08:09 +08:00
32e584c04c Merge remote-tracking branch 'origin/dev' into dev-5.32.0
# Conflicts:
#	dependencies.gradle
2023-10-09 10:45:04 +08:00
f726a4629f chore: 版本更新至 5.31.1 2023-10-09 10:40:01 +08:00
fbe29d82be fix: 【光环助手】APP内图片显示问题 https://jira.shanqu.cc/browse/GHZS-3596 2023-10-08 16:54:13 +08:00
a6c2254db3 Merge branch 'fix/GHZS-3600' into 'dev'
fix: 光环助手使用微信登录问题 https://jira.shanqu.cc/browse/GHZS-3600

See merge request halo/android/assistant-android!1374
2023-10-08 16:16:21 +08:00
3d4977dc87 Merge branch 'feature-GHZS-3462' into 'dev-5.32.0'
feat: 帖子加载问题优化—客户端 https://jira.shanqu.cc/browse/GHZS-3462

See merge request halo/android/assistant-android!1373
2023-10-08 16:14:05 +08:00
4d0fda6157 feat: 帖子加载问题优化—客户端 https://jira.shanqu.cc/browse/GHZS-3462 2023-10-08 16:14:05 +08:00
34fb8ccf93 fix: 光环助手使用微信登录问题 https://jira.shanqu.cc/browse/GHZS-3600 2023-10-08 16:07:48 +08:00
49b9c3a135 Merge branch 'release' into 'dev'
Release

See merge request halo/android/assistant-android!1372
2023-10-08 09:23:54 +08:00
bc04dcc94b Merge branch 'feature-article-detail-comment-no-data' into 'dev'
feat: 文章详情评论列表缺省图修改

See merge request halo/android/assistant-android!1371
2023-10-08 09:16:48 +08:00
eb0bba47f9 feat: 文章详情评论列表缺省图修改 2023-10-08 09:16:48 +08:00
9ba4e9c2cf Merge branch 'fix/GHZS-3532' into 'dev'
fix:【光环助手】同步正式环境问题-帮助视频问题 https://jira.shanqu.cc/browse/GHZS-3532

See merge request halo/android/assistant-android!1370
2023-10-07 14:06:48 +08:00
3a69bb4452 fix:【光环助手】同步正式环境问题-帮助视频问题 https://jira.shanqu.cc/browse/GHZS-3532 2023-10-07 14:06:48 +08:00
0581ebf409 Merge branch 'hotfix/v5.30.6-956/vivo_culprit' into 'release'
fix: 特殊处理 vivo 设备获取已安装列表权限的异常问题

See merge request halo/android/assistant-android!1369
2023-09-27 15:11:30 +08:00
44607a9039 fix: 特殊处理 vivo 设备获取已安装列表权限的异常问题 2023-09-27 15:06:23 +08:00
00db8c00c6 Merge branch 'feature-GHZS-3528' into 'dev'
fix 【光环助手】同步正式环境问题—帖子详情页相关问题 https://jira.shanqu.cc/browse/GHZS-3528

See merge request halo/android/assistant-android!1367
2023-09-26 11:14:31 +08:00
c64713117e fix 【光环助手】同步正式环境问题—帖子详情页相关问题 https://jira.shanqu.cc/browse/GHZS-3528 2023-09-26 11:14:31 +08:00
f2b965b447 Merge branch 'fix/GHZS-3513' into 'dev'
fix:【光环助手】同步正式环境问题-新游开测相关 https://jira.shanqu.cc/browse/GHZS-3513

See merge request halo/android/assistant-android!1365
2023-09-21 10:18:58 +08:00
0ae4f745ee fix:【光环助手】同步正式环境问题-新游开测相关 https://jira.shanqu.cc/browse/GHZS-3513 2023-09-21 10:10:05 +08:00
bcfd9cdfef Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2023-09-20 16:32:53 +08:00
94ffe5a86f chore: 版本更新至 5.30.6 2023-09-20 11:03:34 +08:00
c3ddd28bad Merge branch 'pack/v5.29.2-932/remove_storage_permission_and_change_to_v5.30.4-954_rebased' into 'release'
feat: 合规代码合并 https://jira.shanqu.cc/browse/GHZS-3510

See merge request halo/android/assistant-android!1364
2023-09-20 11:01:41 +08:00
eab8bc846c feat: 合规代码合并 https://jira.shanqu.cc/browse/GHZS-3510 2023-09-20 11:01:41 +08:00
455ed32ac6 Merge branch 'hotfix/v5.30.3-953/GHZS-3484' into 'dev'
修复普通微信登录也会触发 QQ 小游戏的微信登录异常 toast 问题

See merge request halo/android/assistant-android!1360
2023-09-18 09:39:47 +08:00
fd92979481 fix: 微信登录提示问题 https://jira.shanqu.cc/browse/GHZS-3484 2023-09-18 09:39:47 +08:00
3d322b29c1 Merge branch 'hotfix/v5.30.3-953/GHZS-3484' into 'release'
修复普通微信登录也会触发 QQ 小游戏的微信登录异常 toast 问题

See merge request halo/android/assistant-android!1359
2023-09-18 09:34:12 +08:00
dcfc2f44cb fix: 微信登录提示问题 https://jira.shanqu.cc/browse/GHZS-3484 2023-09-18 09:34:12 +08:00
4008c7fa4d Merge branch 'feature-GHZS-3424-patch-2' into 'dev'
fix: 神策数据埋点第二期-0914测试...

See merge request halo/android/assistant-android!1357
2023-09-14 17:08:30 +08:00
f2d714280b fix: 神策数据埋点第二期-0914测试... 2023-09-14 17:08:30 +08:00
6862609bba Merge branch 'release' into 'dev'
Release

See merge request halo/android/assistant-android!1356
2023-09-14 16:31:22 +08:00
3afae78477 Merge branch 'hotfix/GHZS-3479' into 'release'
fix:【光环助手】通用内容合集首页显示问题 https://jira.shanqu.cc/browse/GHZS-3479

See merge request halo/android/assistant-android!1355
2023-09-14 16:26:20 +08:00
b03df595bc fix:【光环助手】通用内容合集首页显示问题 https://jira.shanqu.cc/browse/GHZS-3479 2023-09-14 16:15:52 +08:00
c6f0825fb5 Merge branch 'feature-GHZS-3432-patch-1' into 'dev'
fix: 神策数据埋点第二期—0912测试...

See merge request halo/android/assistant-android!1353
2023-09-14 09:08:08 +08:00
cbc2902613 fix: 神策数据埋点第二期—0912测试... 2023-09-14 09:08:08 +08:00
db725a417d Merge branch 'chen/202309/fix-upload-archive-crash' into 'dev'
存档上传bug

See merge request halo/android/assistant-android!1352
2023-09-13 12:09:08 +08:00
4270924d0f fix:登陆光环账号,然后断网,在光环助手游戏详情页上传存档,有的手机是上传存档弹窗一闪而过没有任何提示,有的手机是弹窗一闪而过后提示‘当前页面未捕获的异常....’ 2023-09-13 11:58:57 +08:00
69fc206377 Merge branch 'feature-GHZs-3038-patch' into 'dev'
fix: 帖子详情页UI优化 https://jira.shanqu.cc/browse/GHZS-3038

See merge request halo/android/assistant-android!1350
2023-09-13 11:07:47 +08:00
8468ec45c2 fix: 帖子详情页UI优化 https://jira.shanqu.cc/browse/GHZS-3038 2023-09-13 11:07:47 +08:00
256a4c2b0a Merge branch 'feature-GHZS-3424-patch' into 'dev'
feat: 【光环助手】帖子详情页UI优化 https://jira.shanqu.cc/browse/GHZS-3038

See merge request halo/android/assistant-android!1349
2023-09-12 17:37:46 +08:00
7d01e47c26 feat: 【光环助手】帖子详情页UI优化 https://jira.shanqu.cc/browse/GHZS-3038 2023-09-12 17:37:46 +08:00
5814f468b3 Merge branch 'feature-GHZS-3432-patch' into 'dev'
fix: 神策数据埋点第二期—0907测试(2) https://jira.shanqu.cc/browse/GHZS-3432

See merge request halo/android/assistant-android!1348
2023-09-12 16:24:01 +08:00
a5730e0ffd fix: 神策数据埋点第二期—0907测试(2) https://jira.shanqu.cc/browse/GHZS-3432 2023-09-12 16:24:00 +08:00
0dfd87db25 Merge branch 'feature-GHZS-3420' into 'dev'
fix: 帖子详情页UI优化—0906UI测试 https://jira.shanqu.cc/browse/GHZS-3420

See merge request halo/android/assistant-android!1347
2023-09-12 14:49:18 +08:00
31aa16f155 fix: 帖子详情页UI优化—0906UI测试 https://jira.shanqu.cc/browse/GHZS-3420 2023-09-12 14:49:18 +08:00
b22c6b9a5b Merge branch 'feature-GHZS-3432' into 'dev'
fix: 神策数据埋点第二期—0907测试(2) https://jira.shanqu.cc/browse/GHZS-3432

See merge request halo/android/assistant-android!1344
2023-09-12 14:46:11 +08:00
f1c0155379 fix: 神策数据埋点第二期—0907测试(2) https://jira.shanqu.cc/browse/GHZS-3432 2023-09-12 11:38:30 +08:00
78 changed files with 1251 additions and 352 deletions

View File

@ -352,9 +352,9 @@ RE.ImageClickListener = function() {
var img = imgs[i];
var imageClassName = img.className;
if (imageClassName == "image-link"|| img.className == "poster") continue;
window.imagelistener.imageArr(img.src);
window.NativeCallBack.invokeMethod("imageArr", img.src);
img.onclick = function() {
window.imagelistener.imageClick(this.src);
window.NativeCallBack.invokeMethod("imageClick", this.src);
}
}
}

View File

@ -39,7 +39,8 @@ class VersionNumberHandler : ChainHandler() {
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
}, {
},
cancelClickCallback = {
SensorsBridge.trackGameDemoDialogClick(
buttonName = R.string.cancel.toResString(),
gameId = gameEntity.id,
@ -47,6 +48,14 @@ class VersionNumberHandler : ChainHandler() {
gameType = gameEntity.categoryChinese
)
},
touchOutsideCallback = {
SensorsBridge.trackGameDemoDialogClick(
buttonName = "关闭弹窗",
gameId = gameEntity.id,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
},
extraConfig = DialogHelper.Config(titleIcon = R.drawable.ic_dialog_tips)
)
}

View File

@ -1,6 +1,7 @@
package com.gh.common.dialog
import android.app.Activity.RESULT_OK
import android.content.DialogInterface
import android.content.Intent
import android.os.Build
import android.os.Bundle
@ -34,6 +35,8 @@ class InstallPermissionDialogFragment : BaseDialogFragment() {
var gameType: String = ""
var mCallBack: ((isFromPermissionGrantedCallback: Boolean) -> Unit)? = null
private var dismissByTouchInside = false
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
mView = inflater.inflate(R.layout.dialog_install_permission, null, false)
return mView
@ -68,6 +71,7 @@ class InstallPermissionDialogFragment : BaseDialogFragment() {
}
closeTv.setOnClickListener {
dismissByTouchInside = true
if (isXapk) {
NewFlatLogUtils.logXApkInstallPermissionDialogClick("尝试解压", false, gameId, gameName)
mCallBack?.invoke(false)
@ -81,6 +85,7 @@ class InstallPermissionDialogFragment : BaseDialogFragment() {
dismiss()
}
closeIv.setOnClickListener {
dismissByTouchInside = true
if (isXapk) NewFlatLogUtils.logXApkInstallPermissionDialogClick("关闭", false, gameId, gameName)
SensorsBridge.trackInstallPermissionDialogClick(
buttonName = "关闭",
@ -106,17 +111,24 @@ class InstallPermissionDialogFragment : BaseDialogFragment() {
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK && requestCode == INSTALL_PERMISSION_CODE) {
NewFlatLogUtils.logXApkInstallPermissionDialogClick("立即开启", true, gameId, gameName)
override fun onDismiss(dialog: DialogInterface) {
if (!dismissByTouchInside) {
SensorsBridge.trackInstallPermissionDialogClick(
buttonName = "立即开启",
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameType
)
}
super.onDismiss(dialog)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK && requestCode == INSTALL_PERMISSION_CODE) {
dismissByTouchInside = true
NewFlatLogUtils.logXApkInstallPermissionDialogClick("立即开启", true, gameId, gameName)
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, "")
@ -176,6 +188,7 @@ class InstallPermissionDialogFragment : BaseDialogFragment() {
this.url = downloadEntity.url
this.gameId = downloadEntity.gameId
this.gameName = downloadEntity.name
this.gameType = downloadEntity.categoryChinese
}
installPermissionDialogFragment.show(
activity.supportFragmentManager,

View File

@ -2,6 +2,7 @@ package com.gh.common.dialog
import android.animation.ValueAnimator
import android.content.Context
import android.content.DialogInterface
import android.content.pm.PackageInfo
import android.os.Bundle
import android.view.LayoutInflater
@ -11,6 +12,7 @@ import android.view.animation.LinearInterpolator
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.Lifecycle
import androidx.recyclerview.widget.LinearLayoutManager
@ -61,6 +63,8 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
var gameEntity: GameEntity? = null
var callBack: ConfirmListener? = null
private var mDismissByTouchInside = false
private val dataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
val packageName = downloadEntity.packageName
@ -137,7 +141,13 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
buttonName = "点击链接",
gameId = gameEntity?.id ?: "",
gameName = gameEntity?.name ?: "",
gameType = gameEntity?.categoryChinese ?: ""
gameType = gameEntity?.categoryChinese ?: "",
isNotPrompt = if (binding.noRemindAgainCb.isVisible) {
binding.noRemindAgainCb.isChecked
} else null,
linkId = link.link ?: "",
linkType = link.type ?: "",
linkText = link.linkText ?: ""
)
DirectUtils.directToLinkPage(requireContext(), link, "包名检测弹窗", "")
}.build()
@ -187,6 +197,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
}
val isAllPackageInstalled = isAllPackageInstalled(mAllInstalledPackages, entity)
if (isAllPackageInstalled) {
mDismissByTouchInside = true
callBack?.onConfirm()
dismissAllowingStateLoss()
} else {
@ -208,7 +219,10 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
buttonName = "点击前往下载",
gameId = gameEntity?.id ?: "",
gameName = gameEntity?.name ?: "",
gameType = gameEntity?.categoryChinese ?: ""
gameType = gameEntity?.categoryChinese ?: "",
isNotPrompt = if (binding.noRemindAgainCb.isVisible) {
binding.noRemindAgainCb.isChecked
} else null
)
DirectUtils.directToLinkPage(requireContext(), packageLink, "包名检测弹窗", "")
}
@ -222,13 +236,20 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
if (binding.noRemindAgainCb.isChecked) {
saveRecord(entity)
LogUtils.uploadPackageCheck("pkg_check_pop_click", "不再提示", gameEntity, "", "", "", "")
SensorsBridge.trackPkgCheckDialogClick(
buttonName = "不再提示",
gameId = gameEntity?.id ?: "",
gameName = gameEntity?.name ?: "",
gameType = gameEntity?.categoryChinese ?: ""
)
}
mDismissByTouchInside = true
SensorsBridge.trackPkgCheckDialogClick(
buttonName = binding.cancelTv.text.toString(),
gameId = gameEntity?.id ?: "",
gameName = gameEntity?.name ?: "",
gameType = gameEntity?.categoryChinese ?: "",
isNotPrompt = if (binding.noRemindAgainCb.isVisible) {
binding.noRemindAgainCb.isChecked
} else null
)
dismissAllowingStateLoss()
}
}
@ -320,15 +341,24 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
mDisposable?.dispose()
}
LogUtils.uploadPackageCheck("pkg_check_pop_click", "关闭弹窗", gameEntity, "", "", "", "")
SensorsBridge.trackPkgCheckDialogClick(
buttonName = "关闭弹窗",
gameId = gameEntity?.id ?: "",
gameName = gameEntity?.name ?: "",
gameType = gameEntity?.categoryChinese ?: ""
)
DownloadManager.getInstance().removeObserver(dataWatcher)
}
override fun onDismiss(dialog: DialogInterface) {
if (!mDismissByTouchInside) {
SensorsBridge.trackPkgCheckDialogClick(
buttonName = "关闭弹窗",
gameId = gameEntity?.id ?: "",
gameName = gameEntity?.name ?: "",
gameType = gameEntity?.categoryChinese ?: "",
isNotPrompt = if (binding.noRemindAgainCb.isVisible) {
binding.noRemindAgainCb.isChecked
} else null
)
}
super.onDismiss(dialog)
}
//安装、卸载事件
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(busFour: EBPackage) {

View File

@ -263,7 +263,7 @@ class SimulatorDownloadManager private constructor() {
}
},
confirmClickCallback = {
showDownloadingDialog(context, simulator)
showDownloadingDialog(context, simulator, gameId, gameName, gameCategoryChinese)
NewFlatLogUtils.logSimulatorUpdateAlertClick("更新")
MtaHelper.onEvent(
trackableEntity.event,
@ -292,6 +292,29 @@ class SimulatorDownloadManager private constructor() {
)
}
},
touchOutsideCallback = {
if (shouldShowUpdate && isInstalled) {
SensorsBridge.trackSimulatorUpdateDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
} else {
SensorsBridge.trackSimulatorInstallDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameCategoryChinese,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
},
mtaEvent = trackableEntity.event, mtaKey = trackableEntity.key,
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
)

View File

@ -54,7 +54,7 @@ object ArchiveDownloadButtonHelper {
!VHelper.isInstalled(packageName) -> {
// 检查游戏是否在安装中
if (!VHelper.isInstalling(packageName)) {
showDownloadTipDialog(context, gameEntity)
showDownloadTipDialog(context)
} else {
ToastUtils.toast("游戏正在安装中,请稍候")
}
@ -101,37 +101,20 @@ object ArchiveDownloadButtonHelper {
)
}
private fun showDownloadTipDialog(context: Context, gameEntity: GameEntity?) {
private fun showDownloadTipDialog(context: Context) {
NewFlatLogUtils.logCloudArchiveGameDownloadDialogShow()
SensorsBridge.trackGameDownloadDialogShow(
gameId = gameEntity?.id ?: "",
gameName = gameEntity?.name ?: "",
gameType = gameEntity?.categoryChinese ?: ""
)
DialogHelper.showDialog(
context,
R.string.archive_dialog_title.toResString(),
R.string.archive_download_dialog_content.toResString(),
R.string.archive_download_dialog_confirm.toResString(),
R.string.cancel.toResString(),
{
confirmClickCallback = {
NewFlatLogUtils.logCloudArchiveGameDownloadDialogClick(R.string.archive_download_dialog_confirm.toResString())
SensorsBridge.trackGameDownloadDialogClick(
buttonName = R.string.archive_download_dialog_confirm.toResString(),
gameId = gameEntity?.id ?: "",
gameName = gameEntity?.name ?: "",
gameType = gameEntity?.categoryChinese ?: ""
)
VHelper.disableLaunchGameAfterInstallation()
EventBus.getDefault().post(EBReuse("download"))
},
{
SensorsBridge.trackGameDownloadDialogClick(
buttonName = R.string.cancel.toResString(),
gameId = gameEntity?.id ?: "",
gameName = gameEntity?.name ?: "",
gameType = gameEntity?.categoryChinese ?: ""
)
cancelClickCallback = {
NewFlatLogUtils.logCloudArchiveGameDownloadDialogClick(R.string.cancel.toResString())
},
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)

View File

@ -178,6 +178,7 @@ public class CommentUtils {
},
null,
null,
null,
new DialogHelper.Config("", false, true, true, false, -1)
);
break;

View File

@ -4,6 +4,7 @@ import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
@ -33,6 +34,7 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@ -754,9 +756,13 @@ public class DialogUtils {
View contentView = binding.getRoot();
binding.gameIcon.displayGameIcon(gameEntity);
AtomicBoolean dismissByTouchInside = new AtomicBoolean(false);
binding.closeIv.setOnClickListener(v -> {
dismissByTouchInside.set(true);
SensorsBridge.trackOverseasAddressDialogClick(
"关闭弹窗",
"取消",
gameEntity.getId(),
gameEntity.getName() != null ? gameEntity.getName() : "",
gameEntity.getCategoryChinese()
@ -770,6 +776,7 @@ public class DialogUtils {
binding.urlTv.setText(gameEntity.getOverseasAddressDialog().getLink());
binding.downloadBtn.setText("下载(" + gameEntity.getApk().get(0).getSize() + "");
binding.downloadBtn.setOnClickListener(v -> {
dismissByTouchInside.set(true);
SensorsBridge.trackOverseasAddressDialogClick(
"下载",
gameEntity.getId(),
@ -785,6 +792,17 @@ public class DialogUtils {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
dialog.setOnDismissListener(dialog1 -> {
if (!dismissByTouchInside.get()) {
SensorsBridge.trackOverseasAddressDialogClick(
"关闭弹窗",
gameEntity.getId(),
gameEntity.getName() != null ? gameEntity.getName() : "",
gameEntity.getCategoryChinese()
);
}
});
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(contentView);
dialog.show();

View File

@ -227,6 +227,7 @@ object DirectUtils {
linkEntity.link!!.contains("v.douyin") && PackageHelper.localPackageNameSet.contains("com.ss.android.ugc.aweme") -> {
directDouyin(context, "1402577827140941")
}
else -> directToWebView(
context,
url = linkEntity.link!!,
@ -280,7 +281,16 @@ object DirectUtils {
)
}
"column_collection", "专题合集" -> directToColumnCollection(context, linkEntity.link!!, -1, entrance, "", exposureEvent)
"column_collection", "专题合集" -> directToColumnCollection(
context,
linkEntity.link!!,
-1,
entrance,
"",
linkEntity.blockId,
linkEntity.blockName,
exposureEvent
)
"server", "game_server", "开服表" -> directToGameServers(context, entrance, path, exposureEvent)
@ -310,7 +320,12 @@ object DirectUtils {
?: ""
)
"anliwall", "安利墙" -> directToAmway(context, fixedTopAmwayCommentId = null, entrance = entrance, path = path)
"anliwall", "安利墙" -> directToAmway(
context,
fixedTopAmwayCommentId = null,
entrance = entrance,
path = path
)
"game_detail_comment" -> directToGameDetail(context, linkEntity.link ?: "", entrance)
@ -432,6 +447,7 @@ object DirectUtils {
"" -> {
// do nothing
}
else -> {
if (unknownCallback != null) {
unknownCallback.invoke()
@ -480,6 +496,8 @@ object DirectUtils {
position: Int = -1,
entrance: String,
columnName: String = "",
blockId: String = "",
blockName: String = "",
exposureEvent: ExposureEvent? = null
) {
if (id.isEmpty()) return
@ -488,9 +506,11 @@ object DirectUtils {
bundle.putString(KEY_ENTRANCE, entrance)
bundle.putString(KEY_COLLECTION_ID, id)
bundle.putString(KEY_COLUMNNAME, columnName)
bundle.putString(KEY_BLOCK_ID, blockId)
bundle.putString(KEY_BLOCK_NAME, blockName)
bundle.putInt(KEY_POSITION, position)
if (exposureEvent != null) {
bundle.putParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST ,ArrayList(exposureEvent.source))
bundle.putParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureEvent.source))
}
jumpActivity(context, bundle)
}
@ -723,7 +743,8 @@ object DirectUtils {
) {
if (id.isEmpty()) return
val bundle = Bundle()
val subjectData = SubjectData(subjectId = id, subjectName = subjectName, isOrder = false, isQQMiniGame = isQQMiniGame)
val subjectData =
SubjectData(subjectId = id, subjectName = subjectName, isOrder = false, isQQMiniGame = isQQMiniGame)
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_TO, SubjectActivity::class.java.name)
bundle.putParcelable(EntranceConsts.KEY_SUBJECT_DATA, subjectData)

View File

@ -2,7 +2,10 @@ package com.gh.common.util
import android.content.Context
import android.os.Build
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.toResString
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.feature.entity.ApkEntity
import com.gh.gamecenter.feature.entity.GameEntity
@ -21,7 +24,43 @@ object DownloadDialogHelper {
) {
val dialog = retrieveAvailableDialog(gameEntity, apkEntity)
if (dialog != null) {
showDownloadDialog(context, dialog, callback)
SensorsBridge.trackGameDownloadDialogShow(
gameId = gameEntity.id,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
DialogHelper.showDialogWithHtmlContent(
context,
dialog.title,
dialog.content,
"继续下载",
"取消",
confirmClickCallback = {
SensorsBridge.trackGameDownloadDialogClick(
buttonName = "继续下载",
gameId = gameEntity.id ,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
},
cancelClickCallback = {
SensorsBridge.trackGameDownloadDialogClick(
buttonName = "取消",
gameId = gameEntity.id ,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
callback.onCallback()
},
touchOutsideCallback = {
SensorsBridge.trackGameDownloadDialogClick(
buttonName = "关闭弹窗",
gameId = gameEntity.id ,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
}
)
} else {
callback.onCallback()
}
@ -109,14 +148,4 @@ object DownloadDialogHelper {
return null
}
private fun showDownloadDialog(context: Context, dialog: GameEntity.Dialog, callback: EmptyCallback) {
DialogHelper.showDialogWithHtmlContent(
context,
dialog.title,
dialog.content,
"继续下载",
"取消",
{ callback.onCallback() })
}
}

View File

@ -647,7 +647,7 @@ object DownloadItemUtils {
"当前处于儿童/青少年模式, \n暂不提供游戏下载",
"退出青少年模式",
"关闭",
{
confirmClickCallback = {
context.startActivity(TeenagerModeActivity.getIntent(context))
SensorsBridge.trackAdolescentModeDialogClick(
buttonName = "退出青少年模式",
@ -656,7 +656,7 @@ object DownloadItemUtils {
gameType = gameEntity.categoryChinese
)
},
{
cancelClickCallback = {
SensorsBridge.trackAdolescentModeDialogClick(
buttonName = "关闭",
gameId = gameEntity.id,
@ -664,6 +664,14 @@ object DownloadItemUtils {
gameType = gameEntity.categoryChinese
)
},
touchOutsideCallback = {
SensorsBridge.trackAdolescentModeDialogClick(
buttonName = "关闭弹窗",
gameId = gameEntity.id,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
},
extraConfig = DialogHelper.Config(
centerTitle = true,
centerContent = true

View File

@ -90,7 +90,7 @@ object DownloadObserver {
"下载链接已失效,建议提交反馈",
"立即反馈",
"取消",
{
confirmClickCallback = {
HelpAndFeedbackBridge.startSuggestionActivity(
currentActivity,
SuggestType.GAME, "notfound",
@ -104,7 +104,7 @@ object DownloadObserver {
gameType = downloadEntity.categoryChinese
)
},
{
cancelClickCallback = {
SensorsBridge.trackDownloadLinkRotDialogClick(
buttonName = "取消",
gameId = downloadEntity.gameId,
@ -112,6 +112,14 @@ object DownloadObserver {
gameType = downloadEntity.categoryChinese
)
},
touchOutsideCallback = {
SensorsBridge.trackDownloadLinkRotDialogClick(
buttonName = "关闭弹窗",
gameId = downloadEntity.gameId,
gameName = downloadEntity.name,
gameType = downloadEntity.categoryChinese
)
},
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
)
return

View File

@ -120,7 +120,7 @@ object GameActivityDownloadHelper {
"当前处于儿童/青少年模式, \n暂不提供游戏下载",
"退出青少年模式",
"关闭",
{
confirmClickCallback = {
context.startActivity(TeenagerModeActivity.getIntent(context))
SensorsBridge.trackAdolescentModeDialogClick(
buttonName = "退出青少年模式",
@ -129,7 +129,7 @@ object GameActivityDownloadHelper {
gameType = mGameEntity?.categoryChinese ?: ""
)
},
{
cancelClickCallback = {
SensorsBridge.trackAdolescentModeDialogClick(
buttonName = "关闭",
gameId = mGameEntity?.id ?: "",
@ -137,6 +137,14 @@ object GameActivityDownloadHelper {
gameType = mGameEntity?.categoryChinese ?: ""
)
},
touchOutsideCallback = {
SensorsBridge.trackAdolescentModeDialogClick(
buttonName = "关闭弹窗",
gameId = mGameEntity?.id ?: "",
gameName = mGameEntity?.name ?: "",
gameType = mGameEntity?.categoryChinese ?: ""
)
},
extraConfig = DialogHelper.Config(
centerTitle = true,
centerContent = true

View File

@ -330,11 +330,13 @@ object PackageInstaller {
showCloseIcon = true,
showAlternativeCancelStyle = !isTheFirstTimeToShowVpnHintDialog
),
uiModificationCallback = { binding, dialog ->
uiModificationCallback = { binding ->
binding.cancelTv.visibility = View.GONE
binding.closeContainer.setOnClickListener {
binding.markDismissByTouchInside()
install(currentActivity, pkgPath)
dialog.dismiss()
binding.dismiss()
downloadEntity?.let {
NewFlatLogUtils.logVpnHintDialogClick(it.gameId, it.name, "关闭按钮")

View File

@ -11,9 +11,12 @@ import android.util.AttributeSet;
import android.view.Gravity;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.annotation.Nullable;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.common.constant.Config;
@ -40,8 +43,10 @@ import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
/**
* Copyright (C) 2017 Wasabeef
@ -74,6 +79,8 @@ public class RichEditor extends WebView {
private EmptyCallback mInitialLayoutCallback;
private Map<String, DynamicJsInterface> mDynamicJsInterfaces = new HashMap<>();
private String mCurrentContent = "";
public enum Type {
@ -122,6 +129,7 @@ public class RichEditor extends WebView {
private OnDecorationStateListener mDecorationStateListener;
private AfterInitialLoadListener mLoadListener;
private WebChromeClientListener mChromeClientListener;
private WebResourceRequestInterceptor mWebResourceRequestInterceptor;
private PageFinishedListener mPageFinishedListener;
public RichEditor(Context context) {
@ -179,6 +187,10 @@ public class RichEditor extends WebView {
mChromeClientListener = chromeClientListener;
}
public void setWebResourceRequestInterceptor(WebResourceRequestInterceptor interceptor) {
mWebResourceRequestInterceptor = interceptor;
}
public void setPageFinishedListener(PageFinishedListener pageFinishedListener) {
mPageFinishedListener = pageFinishedListener;
}
@ -597,6 +609,14 @@ public class RichEditor extends WebView {
exec("javascript:RE.formatBlock();");
}
public void registerDynamicJsInterface(String method, DynamicJsInterface jsInterface) {
mDynamicJsInterfaces.put(method, jsInterface);
}
public void unregisterDynamicJsInterface(String method) {
mDynamicJsInterfaces.remove(method);
}
/**
* 调用 JS 方法,告诉网页端该 url 对应视频播放的进度
*/
@ -683,6 +703,16 @@ public class RichEditor extends WebView {
return super.shouldOverrideUrlLoading(view, url);
}
@Nullable
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
if (mWebResourceRequestInterceptor != null) {
return mWebResourceRequestInterceptor.shouldInterceptRequest(view, url);
}
return super.shouldInterceptRequest(view, url);
}
}
public void setContentOwner(boolean contentOwner) {
@ -699,6 +729,10 @@ public class RichEditor extends WebView {
boolean shouldOverrideUrlLoading(WebView view, String url);
}
public interface WebResourceRequestInterceptor {
WebResourceResponse shouldInterceptRequest(WebView view, String url);
}
public interface PageFinishedListener {
void onPageFinished();
}
@ -840,6 +874,14 @@ public class RichEditor extends WebView {
public void logMtaEvent(String event) {
// do nothing, mta is deprecated
}
@JavascriptInterface
public void invokeMethod(String method, String data) {
DynamicJsInterface jsInterface = mDynamicJsInterfaces.get(method);
if (jsInterface != null) {
jsInterface.invoke(data);
}
}
}
@Override
@ -852,4 +894,8 @@ public class RichEditor extends WebView {
mInitialLayoutCallback = null;
}
}
public interface DynamicJsInterface {
void invoke(String data);
}
}

View File

@ -82,13 +82,6 @@ object XapkDialogHelper {
downloadEntity.name
)
SensorsBridge.trackGameDecompressionFailedDialogClick(
buttonName = "开启权限",
downloadEntity.gameId,
downloadEntity.name,
downloadEntity.categoryChinese
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
val pm = context.packageManager
val restartIntent = pm.getLaunchIntentForPackage(context.packageName)
@ -129,13 +122,15 @@ object XapkDialogHelper {
downloadEntity.categoryChinese
)
},
uiModificationCallback = { binding, dialog ->
uiModificationCallback = { binding ->
binding.headIv.setBackgroundResource(R.drawable.dialog_unzip_failure_head_background)
binding.titleTv.visibility = View.GONE
// VectorDrawable 的动态颜色设置只在支持 Vector 的系统版本上生效,为了能方便复用资源不支持的就用默认颜色,又不是不能用!
binding.closeIv.setColorFilter(Color.WHITE)
binding.contentTv.setLineSpacing(5.0F.dip2px().toFloat(), 1.0F)
binding.closeContainer.setOnClickListener {
binding.markDismissByTouchInside()
NewFlatLogUtils.logXApkUnzipFailedDialogClick(
"关闭",
false,
@ -149,9 +144,17 @@ object XapkDialogHelper {
downloadEntity.name,
downloadEntity.categoryChinese
)
dialog.dismiss()
binding.dismiss()
}
},
touchOutsideCallback = {
SensorsBridge.trackGameDecompressionFailedDialogClick(
buttonName = "关闭弹窗",
downloadEntity.gameId,
downloadEntity.name,
downloadEntity.categoryChinese
)
},
extraConfig = DialogHelper.Config(showCloseIcon = true)
)

View File

@ -100,6 +100,7 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
)
it.markDismissByTouchInside()
it.dismiss()
} else {
ToastUtils.showToast(context.getString(R.string.miui_open_adb_hint))

View File

@ -189,6 +189,14 @@ object BrowserInstallHelper {
gameType = gameEntity.categoryChinese
)
},
touchOutsideCallback = {
SensorsBridge.trackSwitchInstallDialogClick(
buttonName = "关闭弹窗",
gameId = gameEntity.id,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese
)
},
extraConfig = DialogHelper.Config(hint = "修改路径:我的光环-设置-切换安装方式")
)
}

View File

@ -336,7 +336,7 @@ public class SkipActivity extends BaseActivity {
DirectUtils.directCategoryDirectory(this, path, title, ENTRANCE_BROWSER, "浏览器");
break;
case HOST_COLUMN_COLLECTION:
DirectUtils.directToColumnCollection(this, path, -1, ENTRANCE_BROWSER, "", null);
DirectUtils.directToColumnCollection(this, path, -1, ENTRANCE_BROWSER, "", "", "", null);
break;
case EntranceConsts.HOST_BLOCK:
name = uri.getQueryParameter("name");

View File

@ -66,8 +66,6 @@ class SplashScreenActivity : BaseActivity() {
private var mShouldPrefetchData = true
private val mPermissions = arrayOf(
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
PermissionHelper.PERMISSION_GET_INSTALLED_LIST
)

View File

@ -458,6 +458,14 @@ public class DetailViewHolder {
mGameEntity.getName() != null ? mGameEntity.getName() : "",
mGameEntity.getCategoryChinese()
);
},
() -> {
SensorsBridge.trackAdolescentModeDialogClick(
"关闭弹窗",
mGameEntity.getId(),
mGameEntity.getName() != null ? mGameEntity.getName() : "",
mGameEntity.getCategoryChinese()
);
}
);
break;

View File

@ -156,7 +156,13 @@ class SpecialCatalogAdapter(
mExposureEventSparseArray.append(position, exposureEvent)
}
root.setOnClickListener {
DirectUtils.directToLinkPage(mContext, imageEntity.link, "新分类-精选分类", "图片", exposureEvent)
DirectUtils.directToLinkPage(
mContext,
imageEntity.link,
"新分类-精选分类",
"图片",
exposureEvent
)
mCatalogViewModel.logSpecialCatalogContentClick(
"图片",
imageEntity.image.title,
@ -176,7 +182,10 @@ class SpecialCatalogAdapter(
headMore.setOnClickListener {
if (entity.type == "专题合集") {
DirectUtils.directToColumnCollection(
mContext, specialLink.link ?: "", -1, "(游戏-专题:" + specialLink.text + "-全部)"
mContext,
specialLink.link ?: "",
-1,
"(游戏-专题:" + specialLink.text + "-全部)"
)
} else {
startSubjectActivity(
@ -275,6 +284,7 @@ class SpecialCatalogAdapter(
banners,
lastPageDataMap
)
banners.isNotEmpty() && pagerAdapter != null -> (pagerAdapter as BannerAdapter).checkResetData(itemData)
banners.isEmpty() -> binding.viewPager.adapter = null
}

View File

@ -278,7 +278,7 @@ class CloudArchiveManagerActivity : BaseActivity_TabLayout() {
}
override fun onError(e: Throwable?) {
toast("上传失败")
toast("存档上传失败")
}
},
null,

View File

@ -10,6 +10,7 @@ data class CommonCollectionEntity(
val name: String = "",
val type: String = "",
val style: String = "",
val more: Int = 0,
@SerializedName("home_page_style")
val homePageStyle: String = "horizontal_sliding", //首页样式 横排滑动horizontal_sliding 竖排一行两个1-2
@SerializedName("vertical_line")

View File

@ -19,26 +19,15 @@ class PrivacyPolicyEntity(
data.title = "欢迎来到光环助手"
data.topContent = "为提供完整的功能与稳定的服务,光环助手将向你申请开启以下权限:"
data.bottomContent =
"点击<a href=\"https://resource.ghzs.com/page/permissions/android.html\">查看权限应用场景</a>,你可以在系统设置中关闭授权,但可能会影响部分功能的正常使用"
"点击<a href=\"https://resource.ghzs.com/page/privacy_policies/permissions.html\">查看权限应用场景</a>,你可以在系统设置中关闭授权,但可能会影响部分功能的正常使用"
val permissions = arrayListOf<PermissionsEntity>()
permissions.add(
PermissionsEntity(
icon = "res:///" + R.drawable.permission_storage,
name = "存储权限",
intro = "用于下载游戏,以及实现内容缓存提升浏览体验"
icon = "res:///" + R.drawable.permission_installed_list,
name = "已安装应用列表",
intro = "提供检测您所安装游戏的版本更新功能"
)
)
// permissions.add(
// PermissionsEntity(
// icon = "res:///" + R.drawable.permission_phone_state,
// name = "设备信息",
// intro = "为保障您的账号安全及使用软件与服务可安全运行"
// )
// )
// permissions.add(PermissionsEntity(
// icon = "res:///" + R.drawable.permission_sdk,
// name = "第三方SDK使用信息提醒",
// intro = "向北京有竹居网络技术有限公司北京字节跳动科技有限公司提供您的以下信息设备品牌、型号、软件系统相关信息、安卓oaid、无线网SSID名称、WiFi路由器MAC地址、设备MAC地址、IMEI、地理位置用于广告流量统计相关服务。"))
data.permissions = permissions
return data
}

View File

@ -32,6 +32,7 @@ import com.gh.gamecenter.feature.entity.ArticleEntity
import com.gh.gamecenter.feature.entity.ForumVideoEntity
import com.gh.gamecenter.forum.search.ForumOrUserSearchActivity
import com.gh.gamecenter.fragment.MainWrapperFragment
import com.gh.gamecenter.qa.article.detail.ArticleWebCacheManager
import com.gh.gamecenter.qa.article.edit.ArticleEditActivity
import com.gh.gamecenter.qa.questions.edit.QuestionEditActivity
import com.gh.gamecenter.qa.video.publish.VideoPublishActivity
@ -60,6 +61,9 @@ class CommunityHomeFragment : LazyFragment() {
}
override fun onFragmentFirstVisible() {
ArticleWebCacheManager.init(requireContext().applicationContext)
mViewModel = viewModelProvider()
super.onFragmentFirstVisible()

View File

@ -103,7 +103,7 @@ class HomeGameWrapperFragment : HomeTabWrapperFragment() {
mDefaultSelectedTab = mViewModel?.defaultTabPosition ?: 0
}
mHomeTabPosition = mViewModel?.getHomeTabPosition() ?: 0
initViewPager(it, "游戏库")
initViewPager(it, "游戏库", "游戏库顶部tab栏")
mBinding?.toolbarContainer?.visibility = View.VISIBLE
mBinding?.noConnectionContainer?.reuseNoConnection?.visibility = View.GONE

View File

@ -121,7 +121,7 @@ class HomeSearchToolWrapperFragment : HomeTabWrapperFragment() {
mDefaultSelectedTab = mViewModel?.defaultTabPosition ?: 0
}
mHomeTabPosition = mViewModel?.getHomeTabPosition() ?: 0
initViewPager(it, "首页")
initViewPager(it, "首页", "首页顶部tab栏")
// 当 tab 只有一个的时候隐藏顶部 tab 栏,停用 nestedScroll
if (it.size == 1) {

View File

@ -105,8 +105,8 @@ abstract class HomeTabWrapperFragment : SearchToolWrapperFragment() {
return super.onBackPressed()
}
protected open fun initViewPager(tabEntityList: ArrayList<SubjectRecommendEntity>, entrance: String) {
val fragmentList = generateFragments(tabEntityList, entrance).apply { mFragmentList = this }
protected open fun initViewPager(tabEntityList: ArrayList<SubjectRecommendEntity>, entrance: String, location: String) {
val fragmentList = generateFragments(tabEntityList, entrance, location).apply { mFragmentList = this }
val tabTitleList = arrayListOf<String>()
tabEntityList.forEach { tabTitleList.add(it.name ?: "") }
@ -136,7 +136,8 @@ abstract class HomeTabWrapperFragment : SearchToolWrapperFragment() {
protected open fun generateFragments(
tabEntityList: ArrayList<SubjectRecommendEntity>,
entrance: String
entrance: String,
location: String
): ArrayList<Fragment> {
val fragmentList = arrayListOf<Fragment>()
for ((index, tabEntity) in tabEntityList.withIndex()) {
@ -180,6 +181,7 @@ abstract class HomeTabWrapperFragment : SearchToolWrapperFragment() {
putString(EntranceConsts.KEY_COLUMNNAME, tabEntity.text)
putBoolean(EntranceConsts.KEY_IS_COLUMN_COLLECTION, true)
putInt(EntranceConsts.KEY_TAB_INDEX, index)
putString(EntranceConsts.KEY_LOCATION, location)
putParcelableArrayList(
EntranceConsts.KEY_EXPOSURE_SOURCE_LIST,
arrayListOf(ExposureSource("顶部tab", tabEntity.name ?: ""))
@ -208,6 +210,7 @@ abstract class HomeTabWrapperFragment : SearchToolWrapperFragment() {
putString(EntranceConsts.KEY_ENTRANCE, "${entrance}顶部Tab栏")
putString(EntranceConsts.KEY_COLLECTION_ID, tabEntity.link)
putString(EntranceConsts.KEY_COLUMNNAME, tabEntity.text)
putString(EntranceConsts.KEY_LOCATION, location)
putInt(EntranceConsts.KEY_TAB_INDEX, index)
putParcelableArrayList(
EntranceConsts.KEY_EXPOSURE_SOURCE_LIST,

View File

@ -146,6 +146,7 @@ class MainWrapperFragment : BaseFragment_ViewPager_Checkable(), OnBackPressedLis
homeArgs.putString(EntranceConsts.KEY_COLLECTION_ID, entity.link)
homeArgs.putInt(EntranceConsts.KEY_POSITION, 0)
homeArgs.putString(EntranceConsts.KEY_COLUMNNAME, entity.text)
homeArgs.putString(EntranceConsts.KEY_LOCATION, "游戏库")
homeArgs.putBoolean(EntranceConsts.KEY_IS_COLUMN_COLLECTION, true)
}
@ -170,6 +171,7 @@ class MainWrapperFragment : BaseFragment_ViewPager_Checkable(), OnBackPressedLis
homeArgs.putString(EntranceConsts.KEY_ENTRANCE, "游戏库")
homeArgs.putString(EntranceConsts.KEY_COLLECTION_ID, entity.link)
homeArgs.putString(EntranceConsts.KEY_COLUMNNAME, entity.text)
homeArgs.putString(EntranceConsts.KEY_LOCATION, "游戏库")
}
"game_list" -> {

View File

@ -303,14 +303,25 @@ class GameFragmentAdapter(
// 类型为排行榜时点击处理不一样
if (columnCollection.style == "top") {
DirectUtils.directToColumnCollection(
mContext, columnCollection.id
?: "", prefixedPosition, "(首页游戏)"
mContext,
columnCollection.id
?: "",
prefixedPosition,
"(首页游戏)",
"",
mViewModel.blockData?.link ?: "",
mViewModel.blockData?.text ?: ""
)
} else {
setPageSwitchData()
DirectUtils.directToLinkPage(
mContext,
LinkEntity(link = gameEntity.link, type = gameEntity.type),
LinkEntity(
link = gameEntity.link,
type = gameEntity.type,
blockId = mViewModel.blockData?.link ?: "",
blockName = mViewModel.blockData?.text ?: ""
),
"(首页游戏)",
"游戏-专题",
gameEntity.exposureEvent
@ -322,14 +333,15 @@ class GameFragmentAdapter(
mViewModel.blockData?.name ?: ""
)
SensorsBridge.trackColumnCollectionClick(
location = "",
blockName = mViewModel.blockData?.name ?: "",
location = "",
blockName = mViewModel.blockData?.text ?: "",
blockId = mViewModel.blockData?.link ?: "",
columnCollectionName = columnCollection.name ?: "",
columnCollectionId = columnCollection.id ?: "",
position = position,
position = prefixedPosition,
gameColumnName = gameEntity.name ?: "",
gameColumnId = gameEntity.id
gameColumnId = gameEntity.link ?: "",
text = "游戏专题"
)
}
@ -344,15 +356,25 @@ class GameFragmentAdapter(
holder.binding.columnCollectionImage.setOnClickListener {
if (columnCollection.style == "top") {
DirectUtils.directToColumnCollection(
mContext, columnCollection.id
?: "", 0, "(首页游戏)"
mContext,
columnCollection.id
?: "",
0, "(首页游戏)",
"",
mViewModel.blockData?.link ?: "",
mViewModel.blockData?.text ?: ""
)
} else {
MtaHelper.onEvent("游戏专题合集", "首页合集图片", data.name)
setPageSwitchData()
DirectUtils.directToLinkPage(
mContext,
LinkEntity(link = data.link, type = data.type),
LinkEntity(
link = data.link,
type = data.type,
blockId = mViewModel.blockData?.link ?: "",
blockName = mViewModel.blockData?.text ?: ""
),
"(首页游戏)",
"游戏-专题"
)
@ -409,15 +431,16 @@ class GameFragmentAdapter(
blockData?.name ?: ""
)
SensorsBridge.trackLinkContentCollectionClick(
location = "合集首页",
blockName = blockData?.name ?: "",
blockId = blockData?.link ?: "",
location = "版块",
blockName = mViewModel.blockData?.text ?: "",
blockId = mViewModel.blockData?.link ?: "",
linkContentCollectionId = commonLinkCollection.id ?: "",
linkContentCollectionName = commonLinkCollection.name ?: "",
position = position,
position = sequence,
linkType = linkEntity.type ?: "",
linkId = linkEntity.link ?: "",
linkText = linkEntity.text ?: "",
text = "通用内容"
)
}
@ -473,20 +496,21 @@ class GameFragmentAdapter(
}
val rankCollection = mItemDataList[position].rankCollection
val rankCollectionAdapter = holder.bindRankCollection(rankCollection!!) {
val rankCollectionAdapter = holder.bindRankCollection(rankCollection!!) { subject, sequence ->
NewLogUtils.logColumnCategoryHomeContentClick(
it.name ?: "", it.id ?: "", rankCollection.name ?: "",
subject.name ?: "", subject.id ?: "", rankCollection.name ?: "",
rankCollection.id ?: "", "版块", mViewModel.blockData?.name ?: ""
)
SensorsBridge.trackColumnCollectionClick(
location = "",
blockName = mViewModel.blockData?.name ?: "",
location = "",
blockName = mViewModel.blockData?.text ?: "",
blockId = mViewModel.blockData?.link ?: "",
columnCollectionName = rankCollection.name ?: "",
columnCollectionId = rankCollection.id ?: "",
position = position,
gameColumnName = it.name ?: "",
gameColumnId = it.id ?: ""
position = sequence,
gameColumnName = subject.name ?: "",
gameColumnId = subject.id ?: "",
text = "游戏专题"
)
}
@ -727,7 +751,12 @@ class GameFragmentAdapter(
"more" -> {
setPageSwitchData()
subject.moreLink?.let { link ->
DirectUtils.directToLinkPage(it.context, link, "(板块)", "(游戏-专题:" + subject.name + "-全部)")
DirectUtils.directToLinkPage(
it.context,
link,
"(板块)",
"(游戏-专题:" + subject.name + "-全部)"
)
}
}
@ -859,6 +888,8 @@ class GameFragmentAdapter(
-1,
entrance,
"",
mViewModel.blockData?.link ?: "",
mViewModel.blockData?.text ?: "",
exposureEvent
)
@ -919,7 +950,7 @@ class GameFragmentAdapter(
type = entity.type,
display = entity.display,
blockId = blockData?.link ?: "",
blockName = blockData?.name ?: ""
blockName = blockData?.text ?: ""
)
DirectUtils.directToLinkPage(mContext, linkEntity, "板块推荐入口", "", exposureEvent)
NewLogUtils.logAccessToCommonCollectionDetail(
@ -1280,11 +1311,31 @@ class GameFragmentAdapter(
setPageSwitchData()
when (column.type) {
"column_collection" -> {
val blockData = mViewModel.blockData
MtaHelper.onEvent("游戏专题合集", "全部", column.name)
DirectUtils.directToColumnCollection(mContext, column.id!!, -1, "(推荐入口)")
DirectUtils.directToColumnCollection(
mContext,
column.id!!,
-1,
"(推荐入口)",
"",
blockData?.link ?: "",
blockData?.text ?: "",
)
NewLogUtils.logColumnCategoryHomeButtonClick(
buttonType, column.name ?: "", column.id ?: "", "板块", mViewModel.blockData?.name ?: ""
)
SensorsBridge.trackColumnCollectionClick(
location = "版块",
blockName = mViewModel.blockData?.text ?: "",
blockId = mViewModel.blockData?.link ?: "",
columnCollectionName = column.name ?: "",
columnCollectionId = column.id ?: "",
position = -1,
gameColumnName = "",
gameColumnId = "",
text = "全部"
)
}
"common_collection" -> {
@ -1294,7 +1345,7 @@ class GameFragmentAdapter(
mContext,
column.id ?: "",
blockData?.link ?: "",
blockData?.name ?: "",
blockData?.text ?: "",
"板块内容列表"
)
)
@ -1312,6 +1363,18 @@ class GameFragmentAdapter(
"板块",
blockData?.name ?: ""
)
SensorsBridge.trackLinkContentCollectionClick(
location = "版块",
blockName = blockData?.text ?: "",
blockId = blockData?.link ?: "",
linkContentCollectionId = column.id ?: "",
linkContentCollectionName = column.name ?: "",
position = -1,
linkType = "",
linkId = "",
linkText = "",
text = "全部"
)
}
"game_list_collection" -> {

View File

@ -21,7 +21,8 @@ class ColumnCollectionDetailActivity : ToolBarActivity() {
return getTargetIntent(
this,
ColumnCollectionDetailActivity::class.java,
ColumnCollectionDetailFragment::class.java
ColumnCollectionDetailFragment::class.java,
intent.putExtra(EntranceConsts.KEY_LOCATION, "合集详情").extras
)
}

View File

@ -21,6 +21,7 @@ import com.gh.gamecenter.databinding.GameColumnCollectionItemBinding
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.SensorsBridge
class ColumnCollectionDetailAdapter(
context: Context,
@ -28,6 +29,9 @@ class ColumnCollectionDetailAdapter(
private var mTabIndex: Int,
private val mBasicExposureSourceList: ArrayList<ExposureSource>?,
private val mEntrance: String,
private val mBlockId: String,
private val mBlockName: String,
private val mLocation: String
) : ListAdapter<LinkEntity>(context), IExposable {
private var mExposureSparseArray = SparseArray<ExposureEvent>()
@ -79,6 +83,17 @@ class ColumnCollectionDetailAdapter(
data.name ?: "", data?.link ?: "",
mViewModel.columnCollection.value?.name ?: "", mViewModel.collectionId
)
SensorsBridge.trackColumnCollectionClick(
location = mLocation,
blockName = mBlockName,
blockId = mBlockId,
columnCollectionName = mViewModel.columnCollection.value?.name ?: "",
columnCollectionId = mViewModel.collectionId,
position = position,
gameColumnName = data.name ?: "",
gameColumnId = data.link ?: "",
text = "游戏专题"
)
}
val exposureEvent = ExposureEvent.createEventWithSourceConcat(
null,

View File

@ -28,7 +28,11 @@ class ColumnCollectionDetailFragment : LazyListFragment<LinkEntity, ColumnCollec
private var mExposureListener: ExposureListener? = null
private var mTabIndex = -1
private var mBasicExposureSourceList : ArrayList<ExposureSource>? = null
private var mBasicExposureSourceList: ArrayList<ExposureSource>? = null
private var mLocation = ""
private var mBlockId = ""
private var mBlockName = ""
override fun getItemDecoration() = null
@ -43,6 +47,9 @@ class ColumnCollectionDetailFragment : LazyListFragment<LinkEntity, ColumnCollec
super.onCreate(savedInstanceState)
mTabIndex = arguments?.getInt(EntranceConsts.KEY_TAB_INDEX) ?: -1
mLocation = arguments?.getString(EntranceConsts.KEY_LOCATION, "") ?: ""
mBlockId = requireArguments().getString(EntranceConsts.KEY_BLOCK_ID, "")
mBlockName = requireArguments().getString(EntranceConsts.KEY_BLOCK_NAME, "")
mBasicExposureSourceList = arguments?.getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST)
}
@ -132,7 +139,16 @@ class ColumnCollectionDetailFragment : LazyListFragment<LinkEntity, ColumnCollec
override fun provideListAdapter(): ColumnCollectionDetailAdapter {
if (mAdapter == null) {
mAdapter = ColumnCollectionDetailAdapter(requireContext(), mListViewModel, mTabIndex, mBasicExposureSourceList, mEntrance)
mAdapter = ColumnCollectionDetailAdapter(
requireContext(),
mListViewModel,
mTabIndex,
mBasicExposureSourceList,
mEntrance,
mBlockId,
mBlockName,
mLocation
)
}
return mAdapter!!
}

View File

@ -15,7 +15,7 @@ class CommonCollectionDetailActivity : ToolBarActivity() {
this,
CommonCollectionDetailActivity::class.java,
CommonCollectionDetailFragment::class.java,
intent?.extras
intent.putExtra(EntranceConsts.KEY_LOCATION, "合集详情").extras
)
}
@ -52,6 +52,7 @@ class CommonCollectionDetailActivity : ToolBarActivity() {
bundle.putString(EntranceConsts.KEY_BLOCK_ID, blockId)
bundle.putString(EntranceConsts.KEY_BLOCK_NAME, blockName)
bundle.putString(EntranceConsts.KEY_COLLECTION_ID, collectionId)
bundle.putString(EntranceConsts.KEY_LOCATION, "合集详情")
return getTargetIntent(
context,
CommonCollectionDetailActivity::class.java,

View File

@ -29,6 +29,7 @@ class CommonCollectionDetailAdapter(
val mViewModel: CommonCollectionDetailViewModel,
val mBlockId: String,
val mBlockName: String,
val mLocation: String,
val mTabIndex: Int,
val mEntrance: String,
private val mBasicExposureSource: List<ExposureSource>?
@ -103,7 +104,7 @@ class CommonCollectionDetailAdapter(
commonLinkCollection?.id ?: ""
)
SensorsBridge.trackLinkContentCollectionClick(
location = "合集详情",
location = mLocation,
blockName = mBlockName,
blockId = mBlockId,
linkContentCollectionId = commonLinkCollection?.id ?: "",
@ -112,6 +113,7 @@ class CommonCollectionDetailAdapter(
linkType = linkEntity.type ?: "",
linkId = linkEntity.link ?: "",
linkText = linkEntity.text ?: "",
text = "通用内容"
)
}

View File

@ -32,6 +32,7 @@ class CommonCollectionDetailFragment : LazyListFragment<LinkEntity, CommonCollec
private lateinit var mBinding: FragmentListBaseSkeletonBinding
private var mBlockId = ""
private var mBlockName = ""
private var mLocation = ""
private var mTabIndexValue = 0 // 在首页的 tab 位置
override fun getRealLayoutId(): Int = R.layout.fragment_list_base_skeleton
@ -40,6 +41,7 @@ class CommonCollectionDetailFragment : LazyListFragment<LinkEntity, CommonCollec
super.onCreate(savedInstanceState)
mBlockId = requireArguments().getString(EntranceConsts.KEY_BLOCK_ID, "")
mBlockName = requireArguments().getString(EntranceConsts.KEY_BLOCK_NAME, "")
mLocation = requireArguments().getString(EntranceConsts.KEY_LOCATION, "")
mTabIndexValue = requireArguments().getInt(EntranceConsts.KEY_TAB_INDEX, -1)
}
@ -58,6 +60,7 @@ class CommonCollectionDetailFragment : LazyListFragment<LinkEntity, CommonCollec
mViewModel,
mBlockId,
mBlockName,
mLocation,
mTabIndexValue,
mEntrance,
exposureEvent

View File

@ -3,7 +3,10 @@ package com.gh.gamecenter.game.doublecard
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.display
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.StringUtils
import com.gh.gamecenter.databinding.GameDoubleCardItemAlBinding
import com.gh.gamecenter.databinding.GameDoubleCardItemBinding
@ -11,6 +14,7 @@ import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.game.GameItemViewHolder
class DoubleCardViewHolder(val binding: GameDoubleCardItemAlBinding) : RecyclerView.ViewHolder(binding.root) {
private val mPosterWidth = (DisplayUtils.getScreenWidth() - 40F.dip2px()) / 2
fun bindView(gameList: MutableList<GameEntity>, subjectName: String, positionInOriginSubject: Int) {
bindSubView(
@ -40,6 +44,7 @@ class DoubleCardViewHolder(val binding: GameDoubleCardItemAlBinding) : RecyclerV
positionInOriginSubject: Int
) {
subBinding.run {
poster.setTag(ImageUtils.TAG_TARGET_WIDTH, mPosterWidth)
poster.post { poster.display(gameEntity.columnImage) }
gameName.text = gameEntity.name
brief.text =

View File

@ -22,7 +22,7 @@ import com.lightgame.download.DownloadEntity
class RankCollectionAdapter(
context: Context,
private var mSubjectEntity: SubjectEntity,
private var clickClosure: (SubjectEntity) -> Unit
private var clickClosure: (SubjectEntity, Int) -> Unit
) : BaseRecyclerAdapter<RankCollectionAdapter.RankCollectionItemViewHolder>(context) {
private val mViewHolderList = SparseArray<RankCollectionItemViewHolder>()
@ -59,7 +59,7 @@ class RankCollectionAdapter(
}
rankTitle.text = column.name
rankTitle.setOnClickListener {
clickClosure.invoke(column)
clickClosure.invoke(column, position)
DirectUtils.directToColumnCollection(
mContext,
mSubjectEntity.id ?: "",

View File

@ -7,7 +7,7 @@ import com.gh.gamecenter.entity.SubjectEntity
class RankCollectionViewHolder(val binding: RankCollectionListBinding) : BaseRecyclerViewHolder<Any>(binding.root) {
fun bindRankCollection(collection: SubjectEntity, clickClosure: (SubjectEntity) -> Unit): RankCollectionAdapter {
fun bindRankCollection(collection: SubjectEntity, clickClosure: (SubjectEntity, Int) -> Unit): RankCollectionAdapter {
binding.recyclerView.apply {
isNestedScrollingEnabled = false
if (adapter is RankCollectionAdapter) {

View File

@ -1179,8 +1179,12 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
if (!isVisible) return
MtaHelper.onEvent("游戏详情_新", "标签展开", mViewModel.game?.name ?: "")
GameTagsDialog.showGameTagsDialog(
requireActivity(), mNewGameDetailEntity?.tagStyle!!, mGameEntity?.id
?: "", mGameEntity?.name ?: ""
requireActivity(),
mNewGameDetailEntity?.tagStyle!!,
mGameEntity?.id ?: "",
mGameEntity?.name ?: "",
mGameEntity?.downloadStatusChinese ?: "",
mGameEntity?.categoryChinese ?: ""
)
}
@ -1204,7 +1208,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
downloadStatus = mGameEntity?.downloadStatusChinese ?: "",
gameType = mGameEntity?.categoryChinese ?: "",
position = position,
gameTag = tag.name,
gameTag = listOf(tag.name),
gameTagId = tag.id,
)
MtaHelper.onEvent("游戏详情_新", "点击标签", mViewModel.game?.name ?: "")
@ -1273,7 +1277,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
requireContext(),
ranking.collectionId,
entrance = mEntrance,
columnName = ranking.columnName
columnName = ranking.columnName,
)
}
}
@ -2418,20 +2422,6 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
else -> "下载"
}
NewFlatLogUtils.logHaloFunGameDetailJumpClick(downloadStatus, simpleGame.id ?: "")
SensorsBridge.trackGameDetailPageRelatedGameClick(
gameId = gameEntity.id,
gameName = gameEntity.name ?: "",
pageName = getCurrentPageEntity().pageName,
pageId = getCurrentPageEntity().pageId,
pageBusinessId = getCurrentPageEntity().pageBusinessId,
lastPageName = getLastPageEntity().pageName,
lastPageId = getLastPageEntity().pageId,
lastPageBusinessId = getLastPageEntity().pageBusinessId,
downloadStatus = downloadStatus,
gameType = gameEntity.categoryChinese,
clickGameId = simpleGame.id ?: "",
clickGameName = simpleGame.name ?: ""
)
DirectUtils.directToGameDetail(requireContext(), it.id ?: "", entrance = mEntrance)
}
}

View File

@ -294,6 +294,7 @@ class DescAdapter(
subjectAdapter =
GameHorizontalAdapter(mContext, subjectEntity, GameHorizontalListType.GameDetailHorizontalType)
subjectAdapter.gameName = mGameName
subjectAdapter.game = mViewModel.game
subjectAdapter.gameId = mViewModel.gameId ?: ""
subjectAdapter.entrance = mEntrance
subjectAdapter.path = "大家都在玩"
@ -358,7 +359,7 @@ class DescAdapter(
containerWrapper.setPadding(0, itemData.paddingTop, 0, itemData.paddingBottom)
galleryRv.isNestedScrollingEnabled = false
if (galleryRv.adapter == null) {
val relatedVersionAdapter = GameRelatedVersionAdapter(mContext, mGameName, relatedVersion, mEntrance)
val relatedVersionAdapter = GameRelatedVersionAdapter(mContext, mGameId, mGameName, mGame, relatedVersion, mEntrance)
galleryRv.run {
background = R.drawable.background_shape_white_radius_5.toDrawable(mContext)
setPadding(0F.dip2px(), 8F.dip2px(), 0F.dip2px(), 8F.dip2px())
@ -754,9 +755,11 @@ class DescAdapter(
lastPageId = GlobalActivityManager.getCurrentPageEntity().pageId,
lastPageName = GlobalActivityManager.getCurrentPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getCurrentPageEntity().pageBusinessId,
downloadStatus = mGame?.downloadStatusChinese ?: "",
gameType = mGame?.categoryChinese ?: "",
text = "游戏单广场",
gameCollectId = itemData.columnId,
gameCollectTitle = itemData.columnTitle
gameCollectId = "",
gameCollectTitle = ""
)
DirectUtils.directToGameCollectionSquare(it.context, mEntrance)
}
@ -789,8 +792,7 @@ class DescAdapter(
recommendGameList,
mViewModel.gameId ?: "",
mGameName,
itemData.columnId,
itemData.columnTitle,
mViewModel.game,
mEntrance,
"游戏详情[${mGameName}]:游戏单推荐",
listOf(ExposureSource("游戏详情", "$mGameName+$mGameId"))

View File

@ -11,13 +11,13 @@ import com.gh.gamecenter.databinding.GamedetailItemGameCollectionBinding
import com.gh.gamecenter.entity.GameDetailRecommendGameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.feature.entity.GameEntity
class GameCollectionAdapter(
private val mRecommendGameList: ArrayList<GameDetailRecommendGameEntity>,
private val mGameId: String,
private val mGameName: String,
private val mColumnId: String,
private val mColumnTitle: String,
private val mGame: GameEntity?,
private val mEntrance: String,
private val mPath: String,
private val mBasicExposureSource: List<ExposureSource>
@ -60,9 +60,11 @@ class GameCollectionAdapter(
lastPageId = GlobalActivityManager.getCurrentPageEntity().pageId,
lastPageName = GlobalActivityManager.getCurrentPageEntity().pageName,
lastPageBusinessId = GlobalActivityManager.getCurrentPageEntity().pageBusinessId,
downloadStatus = mGame?.downloadStatusChinese ?: "",
gameType = mGame?.categoryChinese ?: "",
text = "游戏单",
gameCollectId = mColumnId,
gameCollectTitle = mColumnTitle
gameCollectId = entity.id,
gameCollectTitle = entity.title
)
DirectUtils.directToGameCollectionDetail(
it.context,

View File

@ -6,17 +6,21 @@ import androidx.recyclerview.widget.RecyclerView
import com.gh.common.databind.BindingAdapters
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.MtaHelper
import com.gh.gamecenter.core.utils.StringUtils
import com.gh.gamecenter.databinding.ItemGameDetailRelatedVersionBinding
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.gh.gamecenter.gamedetail.entity.RelatedVersion
class GameRelatedVersionAdapter(
private val mContext: Context,
private val mGameId: String,
private val mGameName: String,
private val mGame: GameEntity?,
private val mDatas: ArrayList<RelatedVersion>,
private val mEntrance: String
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
@ -71,6 +75,21 @@ class GameRelatedVersionAdapter(
),
exposureEventList.safelyGetInRelease(position)
)
SensorsBridge.trackGameDetailPageRelatedGameClick(
gameId = mGameId,
gameName = mGameName,
pageName = GlobalActivityManager.getCurrentPageEntity().pageName,
pageId = GlobalActivityManager.getCurrentPageEntity().pageId,
pageBusinessId = GlobalActivityManager.getCurrentPageEntity().pageBusinessId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId,
downloadStatus = mGame?.downloadStatusChinese ?: "",
gameType = mGame?.categoryChinese ?: "",
clickGameId = gameEntity.id,
clickGameName = gameEntity.name ?: "",
clickGameType = gameEntity.categoryChinese
)
}
GameItemViewHolder.initGameSubtitleAndAdLabel(gameEntity, holder.binding.gameSubtitleTv)
}

View File

@ -12,7 +12,7 @@ import com.lightgame.adapter.BaseRecyclerAdapter
class GameTagsAdapter(context: Context, private val tags: ArrayList<TagStyleEntity>) :
BaseRecyclerAdapter<RecyclerView.ViewHolder>(context) {
var onClickListener: ((tagEntity: TagStyleEntity) -> Unit)? = null
var onClickListener: ((tagEntity: TagStyleEntity, position: Int) -> Unit)? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view = LayoutInflater.from(mContext).inflate(R.layout.item_game_detail_game_tag, parent, false)
return object : RecyclerView.ViewHolder(view) {}
@ -26,7 +26,7 @@ class GameTagsAdapter(context: Context, private val tags: ArrayList<TagStyleEnti
// 就一个简单的文字列表弹窗,就不麻烦去用 ViewBinding 了
findViewById<TextView>(R.id.tagNameTv).text = tagEntity.name
setOnClickListener {
onClickListener?.invoke(tagEntity)
onClickListener?.invoke(tagEntity, position)
}
}
}

View File

@ -13,12 +13,15 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.gh.common.util.NewLogUtils
import com.gh.download.dialog.DownloadDialog
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.view.divider.HorizontalDividerItemDecoration
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.MtaHelper
import com.gh.gamecenter.databinding.DialogGameTagsBinding
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.TagStyleEntity
import com.gh.gamecenter.tag.TagsActivity
import com.halo.assistant.HaloApp
@ -28,12 +31,16 @@ class GameTagsDialog : BaseDialogFragment() {
private lateinit var mTagStyles: ArrayList<TagStyleEntity>
private lateinit var mGameId: String
private lateinit var mGameName: String
private lateinit var mDownloadStatus: String
private lateinit var mGameType: String
private val mBinding by lazy { DialogGameTagsBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mGameId = requireArguments().getString(EntranceConsts.KEY_GAME_ID) ?: ""
mGameName = requireArguments().getString(EntranceConsts.KEY_GAME_NAME) ?: ""
mDownloadStatus = requireArguments().getString(EntranceConsts.KEY_DOWNLOAD_STATUS) ?: ""
mGameType = requireArguments().getString(EntranceConsts.KEY_GAME_TYPE) ?: ""
mTagStyles = requireArguments().getParcelableArrayList(EntranceConsts.KEY_TAGTYPE)
?: ArrayList()
}
@ -70,15 +77,30 @@ class GameTagsDialog : BaseDialogFragment() {
addItemDecoration(itemDecoration)
val gameTagsAdapter = GameTagsAdapter(requireContext(), mTagStyles)
adapter = gameTagsAdapter
gameTagsAdapter.onClickListener = {
gameTagsAdapter.onClickListener = { tag, position ->
requireContext().startActivity(
TagsActivity.getIntent(
requireContext(),
it.name, it.name, "", "游戏介绍"
tag.name, tag.name, "", "游戏介绍"
)
)
NewLogUtils.logGameDetailTagClick(mGameId, mGameName, it.id, it.name, it.isTop)
MtaHelper.onEvent("游戏标签弹窗", "进入标签", "${mGameName}+${it.name}")
SensorsBridge.trackGameDetailPageGameTagClick(
gameId = mGameId,
gameName = mGameName,
pageName = GlobalActivityManager.getCurrentPageEntity().pageName,
pageId = GlobalActivityManager.getCurrentPageEntity().pageId,
pageBusinessId = GlobalActivityManager.getCurrentPageEntity().pageBusinessId,
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
lastPageBusinessId = GlobalActivityManager.getLastPageEntity().pageBusinessId,
downloadStatus = mDownloadStatus,
gameType = mGameType,
position = position,
gameTag = listOf(tag.name),
gameTagId = tag.id,
)
NewLogUtils.logGameDetailTagClick(mGameId, mGameName, tag.id, tag.name, tag.isTop)
MtaHelper.onEvent("游戏标签弹窗", "进入标签", "${mGameName}+${tag.name}")
}
}
}
@ -88,13 +110,17 @@ class GameTagsDialog : BaseDialogFragment() {
context: FragmentActivity,
tagStyles: ArrayList<TagStyleEntity>,
gameId: String,
gameName: String
gameName: String,
downloadStatus: String,
gameType: String,
) {
val dialog = GameTagsDialog().apply {
arguments = bundleOf(
EntranceConsts.KEY_GAME_ID to gameId,
EntranceConsts.KEY_GAME_NAME to gameName,
EntranceConsts.KEY_TAGTYPE to tagStyles
EntranceConsts.KEY_TAGTYPE to tagStyles,
EntranceConsts.KEY_DOWNLOAD_STATUS to downloadStatus,
EntranceConsts.KEY_GAME_TYPE to gameType
)
}
dialog.show(context.supportFragmentManager, DownloadDialog::class.java.name)

View File

@ -841,6 +841,7 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
id = homeContent.linkId
name = homeContent.linkText
style = homeContent.commonCollection?.style
more = homeContent.commonCollection?.more
homePageStyle = homeContent.commonCollection?.homePageStyle ?: ""
verticalLine = homeContent.commonCollection?.verticalLine ?: ""
commonCollectionList = homeContent.commonCollection?.collectionList

View File

@ -150,7 +150,7 @@ class LegacyHomeFragmentAdapterAssistant(
scrollCalculatorHelper: ScrollCalculatorHelper? = null,
) {
when (holder) {
is GameHeadViewHolder -> bindHeadView(holder, item)
is GameHeadViewHolder -> bindHeadView(holder, item, position)
is GamePluginViewHolder -> bindPluginView(holder, item)
is GameItemViewHolder -> bindGameItemView(holder, item, position)
is GameImageViewHolder -> bindGameImageView(holder, item)
@ -311,7 +311,12 @@ class LegacyHomeFragmentAdapterAssistant(
// 类型为排行榜时点击处理不一样
setPageSwitchData()
if (columnCollection.style == "top") {
DirectUtils.directToColumnCollection(mContext, columnCollection.id ?: "", prefixedPosition, "(首页游戏)")
DirectUtils.directToColumnCollection(
mContext,
columnCollection.id ?: "",
prefixedPosition,
"(首页游戏)",
)
} else {
DirectUtils.directToLinkPage(
mContext,
@ -331,14 +336,15 @@ class LegacyHomeFragmentAdapterAssistant(
)
SensorsBridge.trackColumnCollectionClick(
location = "首页",
location = "首页",
blockName = "",
blockId = "",
columnCollectionName = columnCollection.name ?: "",
columnCollectionId = columnCollection.id ?: "",
position = holder.bindingAdapterPosition,
position = prefixedPosition,
gameColumnName = gameEntity.name ?: "",
gameColumnId = gameEntity.id
gameColumnId = gameEntity.link ?: "",
text = "游戏专题"
)
}
@ -353,7 +359,12 @@ class LegacyHomeFragmentAdapterAssistant(
holder.binding.columnCollectionImage.setOnClickListener {
setPageSwitchData()
if (columnCollection.style == "top") {
DirectUtils.directToColumnCollection(mContext, columnCollection.id ?: "", 0, "(首页游戏)")
DirectUtils.directToColumnCollection(
mContext,
columnCollection.id ?: "",
0,
"(首页游戏)"
)
} else {
DirectUtils.directToLinkPage(
mContext,
@ -390,7 +401,13 @@ class LegacyHomeFragmentAdapterAssistant(
GameDetailActivity.startGameDetailActivity(
mContext,
gameEntity.id,
StringUtils.buildString("(游戏-专题:", subjectData?.name, "-列表[", (subjectData?.position).toString(), "])"),
StringUtils.buildString(
"(游戏-专题:",
subjectData?.name,
"-列表[",
(subjectData?.position).toString(),
"])"
),
traceEvent = gameEntity.exposureEvent
)
}
@ -574,7 +591,14 @@ class LegacyHomeFragmentAdapterAssistant(
""
)
} else {
BindingAdapters.setDownloadButton(holder.binding.progressBar, entity, null, null, "(游戏-专题:$name-大图)", "")
BindingAdapters.setDownloadButton(
holder.binding.progressBar,
entity,
null,
null,
"(游戏-专题:$name-大图)",
""
)
}
holder.binding.gameImageIcon.setOnClickListener {
DataCollectionUtils.uploadClick(mContext, "$name-大图", "游戏-专题")
@ -660,7 +684,7 @@ class LegacyHomeFragmentAdapterAssistant(
holder.binding.gameName.setTextColor(R.color.text_title.toColor(holder.binding.root.context))
}
private fun bindHeadView(holder: GameHeadViewHolder, item: LegacyHomeItemData) {
private fun bindHeadView(holder: GameHeadViewHolder, item: LegacyHomeItemData, position: Int) {
if (mMakeItemBackgroundTransparent) holder.itemView.setBackgroundColor(R.color.transparent.toColor(mContext))
val column = item.columnHead
@ -691,10 +715,26 @@ class LegacyHomeFragmentAdapterAssistant(
} else {
setPageSwitchData()
if (column.type == "column_collection") {
DirectUtils.directToColumnCollection(mContext, column.id!!, -1, "(游戏-专题:" + column.name + "-全部)")
DirectUtils.directToColumnCollection(
mContext,
column.id!!,
-1,
"(游戏-专题:" + column.name + "-全部)"
)
NewLogUtils.logColumnCategoryHomeButtonClick(
buttonType, column.name ?: "", column.id ?: "", "首页", ""
)
SensorsBridge.trackColumnCollectionClick(
location = "首页",
blockName = "",
blockId = "",
columnCollectionName = column.name ?: "",
columnCollectionId = column.id ?: "",
position = -1,
gameColumnName = "",
gameColumnId = "",
text = "全部"
)
} else if (column.type == "top_game_comment") {
DirectUtils.directToAmway(mContext, null, "(游戏-专题:" + column.name + "-全部)", "")
NewLogUtils.logHomeShareWallButtonClick("右上角")
@ -709,7 +749,24 @@ class LegacyHomeFragmentAdapterAssistant(
)
)
NewLogUtils.logAccessToCommonCollectionDetail(column.id ?: "", column.name ?: "", "首页内容列表")
NewLogUtils.logCommonCategoryHomeButtonClick(buttonType, column.name ?: "", column.id ?: "", "新首页")
NewLogUtils.logCommonCategoryHomeButtonClick(
buttonType,
column.name ?: "",
column.id ?: "",
"新首页"
)
SensorsBridge.trackLinkContentCollectionClick(
location = "首页",
blockName = "",
blockId = "",
linkContentCollectionId = column.id ?: "",
linkContentCollectionName = column.name ?: "",
position = -1,
linkType = "",
linkId = "",
linkText = "",
text = "全部"
)
} else if (column.type == "game_list_collection") {
NewFlatLogUtils.logGameListCollectionClick(
"首页内容列表",
@ -910,7 +967,13 @@ class LegacyHomeFragmentAdapterAssistant(
val clickClosure: (position: Int, contentEntity: CommonCollectionContentEntity) -> Unit =
{ sequence, contentEntity ->
val linkEntity = contentEntity.linkEntity
DirectUtils.directToLinkPage(mContext, linkEntity, "(首页游戏)", "通用链接合集", linkEntity.exposureEvent)
DirectUtils.directToLinkPage(
mContext,
linkEntity,
"(首页游戏)",
"通用链接合集",
linkEntity.exposureEvent
)
NewLogUtils.logCommonCollectionClick(
commonCollection?.id ?: "",
commonCollection?.name ?: "",
@ -935,15 +998,16 @@ class LegacyHomeFragmentAdapterAssistant(
"新首页"
)
SensorsBridge.trackLinkContentCollectionClick(
location = "合集首页",
location = "首页",
blockName = "",
blockId = "",
linkContentCollectionId = commonCollection?.id ?: "",
linkContentCollectionName = commonCollection?.name ?: "",
position = holder.bindingAdapterPosition,
position = sequence,
linkType = linkEntity.type ?: "",
linkId = linkEntity.link ?: "",
linkText = linkEntity.text ?: "",
text = "通用内容"
)
}
@ -994,20 +1058,21 @@ class LegacyHomeFragmentAdapterAssistant(
private fun bindRankCollection(holder: RankCollectionViewHolder, item: LegacyHomeItemData) {
val rankCollection = item.rankCollection
val rankCollectionAdapter = holder.bindRankCollection(rankCollection!!) {
val rankCollectionAdapter = holder.bindRankCollection(rankCollection!!) { subject, sequence ->
NewLogUtils.logColumnCategoryHomeContentClick(
it.name ?: "", it.id ?: "", rankCollection.name ?: "",
subject.name ?: "", subject.id ?: "", rankCollection.name ?: "",
rankCollection.id ?: "", "新首页", ""
)
SensorsBridge.trackColumnCollectionClick(
location = "首页",
location = "首页",
blockName = "",
blockId = "",
columnCollectionName = rankCollection.name ?: "",
columnCollectionId = rankCollection.id ?: "",
position = holder.bindingAdapterPosition,
gameColumnName = it.name ?: "",
gameColumnId = it.id ?: ""
position = sequence,
gameColumnName = subject.name ?: "",
gameColumnId = subject.id ?: "",
text = "游戏专题"
)
}

View File

@ -92,6 +92,7 @@ class HomeGameTestV2GameListViewHolder(
val timeText = getTimeText(time)
val typeText = when (gameEntity.eventType) {
"test" -> "开启测试"
"update" -> "游戏更新"
else -> "首发上线"
}
return "$timeText $typeText"

View File

@ -62,6 +62,7 @@ import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
@ -320,12 +321,17 @@ public class UpdateManager {
private void showUpdateDialog(final String md5) {
Context context = getValidContext();
AtomicBoolean dismissByTouchInside = new AtomicBoolean(false);
updateDialog = new Dialog(context);
updateDialog.setOnDismissListener(dialog -> {
invokeDismissCallback();
if (!isShowDownload) {
DownloadManager.getInstance().removeObserver(dataWatcher);
}
if (!dismissByTouchInside.get()) {
SensorsBridge.trackVersionUpdateDialogClick("关闭弹窗");
}
});
Window window = updateDialog.getWindow();
if (window != null) {
@ -378,14 +384,31 @@ public class UpdateManager {
TextView size = view.findViewById(R.id.size);
size.setText(String.format("大小 %s", appEntity.getSize()));
view.setOnClickListener(v -> dismissDialog("关闭弹窗"));
view.setOnClickListener(v -> {
if (appEntity.isForce()) {
exitApp();
} else {
updateDialog.dismiss();
}
});
cancelUpdateTextView.setOnClickListener(v -> dismissDialog(cancelUpdateTextView.getText().toString()));
cancelUpdateTextView.setOnClickListener(v -> {
if (appEntity.isForce()) {
exitApp();
} else {
updateDialog.dismiss();
}
dismissByTouchInside.set(true);
String cancelText = cancelUpdateTextView.getText().toString();
SensorsBridge.trackVersionUpdateDialogClick(cancelText);
});
confirmTextView.setOnClickListener(v -> {
if (!isUpdateFileDownloaded(md5)) {
dismissByTouchInside.set(true);
updateDialog.dismiss();
} else if (isUpdateFileDownloaded(md5) && !appEntity.isForce()) {
dismissByTouchInside.set(true);
updateDialog.dismiss();
}
String path = FileUtils.getDownloadPath(context, "光环助手V" + appEntity.getVersion() + "_" + md5 + ".apk");
@ -415,15 +438,6 @@ public class UpdateManager {
DataLogUtils.uploadUpgradeLog(context, "notice"); //上传更新通知弹窗数据
}
private void dismissDialog(String buttonName) {
if (appEntity.isForce()) {
exitApp();
} else {
updateDialog.dismiss();
}
SensorsBridge.trackVersionUpdateDialogClick(buttonName);
}
private void exitApp() {
NotificationManagerCompat.from(mApplicationContext).cancelAll();
AppManager.getInstance().finishAllActivity();

View File

@ -1,7 +1,6 @@
package com.gh.gamecenter.qa.answer.edit
import android.app.Activity
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.os.Bundle
@ -46,7 +45,7 @@ class AnswerEditActivity : BaseRichEditorActivity<AnswerEditViewModel>(), Keyboa
private lateinit var mMenuPost: MenuItem
private lateinit var mBinding: FragmentAnswerEditBinding
private var mProcessingDialog: WaitingDialogFragment? = null
private var mUploadImageCancelDialog: Dialog? = null
private var mUploadImageCancelDialog: DialogHelper.DialogAlertDefaultBindingWrapper? = null
private var mCommunityName: String? = null
private var mOpenAnswerInNewPage: Boolean = false
private var mImageViewList: ArrayList<SimpleDraweeView>? = null

View File

@ -8,14 +8,12 @@ import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager.widget.ViewPager.LayoutParams
import androidx.viewpager.widget.ViewPager.OnPageChangeListener
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.UnAvaliableWebviewViewHolder
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.databinding.TabItemBinding
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.common.utils.visibleIf
import com.gh.gamecenter.core.utils.MtaHelper
@ -53,6 +51,7 @@ class ArticleDetailAdapter(
ITEM_ARTICLE_DETAIL -> {
val isWebViewInstalled = PackageUtils.checkWebViewIsAvailable(mContext)
if (isWebViewInstalled) {
ArticleDetailContentViewHolder.wvLoadTimeInMills = System.currentTimeMillis()
val binding: ItemArticleDetailContentBinding =
ItemArticleDetailContentBinding.inflate(mLayoutInflater, parent, false)
ArticleDetailContentViewHolder(binding, mViewModel).apply { articleDetailVH = this }
@ -190,11 +189,6 @@ class ArticleDetailAdapter(
private fun initTabLayout(pagerAdapter: ArticleDetailCommentPagerAdapter, tabLayout: TabLayout) {
for (i in 0 until tabLayout.tabCount) {
val tab: TabLayout.Tab = tabLayout.getTabAt(i) ?: continue
val layoutParams = tab.view.layoutParams
tab.view.layoutParams = layoutParams.apply {
width = LayoutParams.WRAP_CONTENT
}
tab.view.setPadding(16F.dip2px(), 0, 16F.dip2px(), 0)
val binding = TabItemBinding.inflate(LayoutInflater.from(binding.root.context), tab.view, false)
if (i == 0) commentTab = binding.tabTitle
binding.tabTitle.text = pagerAdapter.tabList[i]

View File

@ -34,6 +34,10 @@ class ArticleDetailCommentListFragment : ListFragment<CommentItemData, ArticleDe
}
}
override fun getLayoutId(): Int {
return R.layout.fragment_list_article_detail_comment
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mListRefresh?.isEnabled = false

View File

@ -5,6 +5,7 @@ import android.app.Activity
import android.graphics.Bitmap
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.util.Log
import android.view.Gravity
import android.view.View
import android.webkit.JavascriptInterface
@ -28,7 +29,6 @@ import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.databinding.ItemArticleDetailContentBinding
import com.gh.gamecenter.feature.entity.Auth
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.qa.editor.OnLinkClickListener
import com.gh.gamecenter.qa.entity.ArticleDetailEntity
@ -42,6 +42,33 @@ class ArticleDetailContentViewHolder(
var viewModel: ArticleDetailViewModel
) : RecyclerView.ViewHolder(binding.root) {
companion object {
var wvLoadTimeInMills = 0L
}
val richEditor = ArticleWebCacheManager
.attachToRichEditor(binding.richEditorContainer)
.apply {
setInputEnabled(false)
setPadding(16, 4, 16, 4)
enableForceDark(DarkModeUtils.isDarkModeOn(binding.root.context))
setTransparentBackground()
setLayoutCallback { viewModel.articleRenderedLiveData.postValue(true) }
setPageFinishedListener {
Log.d("ArticleDetail", "pageFinished->${System.currentTimeMillis() - wvLoadTimeInMills}")
viewModel.articlePageFinishedLiveData.postValue(true)
}
setChromeClientListener(object : RichEditor.WebChromeClientListener {
override fun onPageFinished(view: WebView?, url: String?) {
Log.d("ArticleDetail", "onPageFinished: $url->${System.currentTimeMillis() - wvLoadTimeInMills}")
}
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
return DefaultUrlHandler.interceptUrl(binding.root.context, url ?: "", "帖子详情")
}
})
}
private var mEntrance = ""
val articleImgUrlList = ArrayList<String>()
@ -59,11 +86,41 @@ class ArticleDetailContentViewHolder(
titleTv.setTextColor(R.color.text_title.toColor(binding.root.context))
gameName.setTextColor(R.color.text_subtitleDesc.toColor(binding.root.context))
richEditor.enableForceDark(DarkModeUtils.isDarkModeOn(binding.root.context))
richEditor.setTransparentBackground()
richEditor.setInputEnabled(false)
richEditor.setPadding(16, 4, 16, 4)
richEditor.addJavascriptInterface(JsInterface(article.status ?: ""), "imagelistener")
richEditor.registerDynamicJsInterface("imageArr") { url ->
val defUrl = url.split("\\?".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0]
if (!articleImgUrlList.contains(defUrl) && !url.contains("web_load_dfimg_icon.png")) {
articleImgUrlList.add(defUrl)
}
}
richEditor.registerDynamicJsInterface("imageClick") { url ->
when {
url.contains("web_load_dfimg_icon.png") -> {
runOnUiThread { richEditor.replaceAllDfImageExcludeGif() }
}
else -> {
val status = article.status ?: ""
clickToastByStatus(status) {
var current = 0
var i = 0
val size = articleImgUrlList.size
while (i < size) {
if (url.contains(articleImgUrlList.get(i))) {
current = i
}
i++
}
val intent = ImageViewerActivity.getIntent(
binding.root.context, articleImgUrlList, current,
mEntrance + "+(帖子详情[" + binding.titleTv.text.toString() + "])"
)
(binding.root.context as Activity).startActivityForResult(
intent,
ImageViewerActivity.REQUEST_FOR_VIEWED_IMAGE
)
}
}
}
}
richEditor.addJavascriptInterface(
OnLinkClickListener(
root.context,
@ -73,23 +130,7 @@ class ArticleDetailContentViewHolder(
"帖子详情"
), "OnLinkClickListener"
)
richEditor.setLayoutCallback(object : EmptyCallback {
override fun onCallback() {
viewModel.articleRenderedLiveData.postValue(true)
}
})
richEditor.setPageFinishedListener {
viewModel.articlePageFinishedLiveData.postValue(true)
}
richEditor.setChromeClientListener(object : RichEditor.WebChromeClientListener {
override fun onPageFinished(view: WebView?, url: String?) {
}
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
return DefaultUrlHandler.interceptUrl(binding.root.context, url ?: "", "帖子详情")
}
})
approvalStatusTv.goneIf(article.status == "pass")
statusContainer.goneIf(article.status == "pass")
when (article.status) {
@ -99,6 +140,7 @@ class ArticleDetailContentViewHolder(
approvalStatusTv.background =
R.drawable.bg_approval_status_pending.toDrawable(approvalStatusTv.context)
}
"fail" -> {
approvalStatusTv.text = "审核不通过"
approvalStatusTv.setTextColor(R.color.theme_red.toColor(approvalStatusTv.context))
@ -211,7 +253,7 @@ class ArticleDetailContentViewHolder(
richEditor.visibility = View.VISIBLE
article.community.let { entity ->
gameName.text = entity.name
gameName.text = binding.root.context.getString(R.string.article_detail_content_forum_name, entity.name)
val icon = if (!entity.icon.isNullOrEmpty()) entity.icon else entity.game?.getIcon()
val iconSubscript =
if (!entity.iconSubscript.isNullOrEmpty()) entity.iconSubscript else entity.game?.iconSubscript
@ -238,11 +280,7 @@ class ArticleDetailContentViewHolder(
tagContainer.isVisible = article.sections.isNotEmpty() || article.activityTag != null
if (article.sections.isNotEmpty() && article.sections[0].id.isNotEmpty() && article.sections[0].name.isNotEmpty()) {
sectionNameTv.text =
binding.root.context.getString(
R.string.article_detail_content_section_name,
article.sections[0].name
)
sectionNameTv.text = article.sections[0].name
sectionNameTv.visibility = View.VISIBLE
sectionNameTv.setOnClickListener {
DirectUtils.directForumDetailSection(
@ -324,7 +362,7 @@ class ArticleDetailContentViewHolder(
* 回调列表视频播放结束时的时间
*/
fun onVideoPlayedCallback(url: String, position: Int) {
binding.richEditor.onVideoPlayedCallback(url, position)
richEditor.onVideoPlayedCallback(url, position)
}
fun updateFollowBtn(isFollowed: Boolean) {
@ -348,7 +386,7 @@ class ArticleDetailContentViewHolder(
fun imageClick(url: String) {
when {
url.contains("web_load_dfimg_icon.png") -> {
runOnUiThread { binding.richEditor.replaceAllDfImageExcludeGif() }
runOnUiThread { richEditor.replaceAllDfImageExcludeGif() }
}
// url.contains(RichEditor.IMAGE_FLAG_THUMBNAIL) -> {
// runOnUiThread { binding.richEditor.replaceDfImageByUrl(url) }
@ -385,4 +423,14 @@ class ArticleDetailContentViewHolder(
}
}
}
fun destroy() {
richEditor.setLayoutCallback(null)
richEditor.removeJavascriptInterface("imagelistener")
richEditor.removeJavascriptInterface("OnLinkClickListener")
richEditor.setChromeClientListener(null)
richEditor.setContentOwner(false)
richEditor.setPageFinishedListener(null)
ArticleWebCacheManager.detachFromRichEditor(binding.richEditorContainer)
}
}

View File

@ -26,7 +26,6 @@ import com.gh.gamecenter.common.baselist.LoadType
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.entity.AdditionalParamsEntity
import com.gh.gamecenter.feature.entity.CommentEntity
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.entity.NormalShareEntity
import com.gh.gamecenter.common.eventbus.EBReuse
@ -41,6 +40,7 @@ import com.gh.gamecenter.eventbus.EBDeleteCommentDetail
import com.gh.gamecenter.eventbus.EBDeleteDetail
import com.gh.gamecenter.eventbus.EBTopCommunityChanged
import com.gh.gamecenter.feature.entity.ArticleDraftEntity
import com.gh.gamecenter.feature.entity.CommentEntity
import com.gh.gamecenter.feature.entity.Permissions
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.qa.article.edit.ArticleEditActivity
@ -119,11 +119,11 @@ class ArticleDetailFragment : BaseCommentFragment<CommentItemData, ArticleDetail
mAdapter?.articleDetailVH?.run {
if (articleImgUrlList.size > 0) {
if (imageSet.size == articleImgUrlList.size) {
binding.richEditor.replaceAllDfImage()
richEditor.replaceAllDfImage()
} else {
for (i in imageSet) {
val url = articleImgUrlList[i.toInt()]
binding.richEditor.replaceDfImageByUrl(url)
richEditor.replaceDfImageByUrl(url)
}
}
}
@ -165,6 +165,9 @@ class ArticleDetailFragment : BaseCommentFragment<CommentItemData, ArticleDetail
override fun onDestroyView() {
super.onDestroyView()
mAdapter?.articleDetailVH?.destroy()
if (mViewModel.detailEntity != null) {
HistoryHelper.insertArticleEntity(mViewModel.detailEntity!!)

View File

@ -68,7 +68,7 @@ class ArticleDetailRelatedContentListAdapter(
}
else -> {
val communityId = item.community.id
val intent = ArticleDetailActivity.getCommentIntent(
val intent = ArticleDetailActivity.getIntent(
it.context,
CommunityEntity(communityId, item.community.name),
item.id,

View File

@ -0,0 +1,146 @@
package com.gh.gamecenter.qa.article.detail
import android.annotation.SuppressLint
import android.content.Context
import android.content.MutableContextWrapper
import android.view.ViewGroup
import android.webkit.WebResourceResponse
import android.webkit.WebView
import com.gh.common.view.RichEditor
import com.gh.gamecenter.common.utils.EnvHelper
import com.gh.gamecenter.core.utils.MD5Utils
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.OkHttpClient
import okhttp3.ResponseBody
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
import retrofit2.http.Query
import retrofit2.http.Streaming
import retrofit2.http.Url
import java.io.BufferedInputStream
import java.io.File
import java.io.FileOutputStream
import java.util.concurrent.TimeUnit
/**
* 社区文章详情-Web资源缓存管理类
*/
@SuppressLint("StaticFieldLeak")
object ArticleWebCacheManager {
private lateinit var cacheDir: File
private lateinit var cacheRichEditor: RichEditor
private var isInit = false
@SuppressLint("CheckResult")
fun init(applicationContext: Context) {
if (isInit) return
isInit = true
this.cacheRichEditor = RichEditor(
MutableContextWrapper(applicationContext)
)
this.cacheDir = File(applicationContext.cacheDir, "article/web").apply {
if (!exists()) mkdirs()
}
val cacheUrlList = mutableListOf(
"https://static-web.ghzs.com/website-static/lib/polyfill.min.js",
"https://and-static.ghzs.com/web/dplayer/DPlayer.min.js"
)
if (EnvHelper.isDevEnv) {
cacheUrlList.add("https://resource.ghzs.com/js/halo_app_test.js")
cacheUrlList.add("https://resource.ghzs.com/css/halo_app_test.css")
} else {
cacheUrlList.add("https://resource.ghzs.com/js/halo.js")
cacheUrlList.add("https://resource.ghzs.com/css/halo.css")
}
val okHttpClient = OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build()
val retrofit = Retrofit.Builder()
.client(okHttpClient)
.baseUrl("https://resource.ghzs.com")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
val apiService = retrofit.create(ApiService::class.java)
val requestSingleList = cacheUrlList.map { url ->
apiService.downloadFile(url, System.currentTimeMillis() / 1000)
.map {
val file = File(cacheDir, MD5Utils.getUrlMD5(url)).apply {
if (!exists()) createNewFile()
}
val inputStream = it.byteStream()
val outputStream = FileOutputStream(file)
inputStream.copyTo(outputStream, DEFAULT_BUFFER_SIZE)
file
}
}
Single.zip(requestSingleList) {}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({}, {})
}
fun attachToRichEditor(parent: ViewGroup): RichEditor {
val richEditor = this.cacheRichEditor.apply {
(this.context as MutableContextWrapper).baseContext = parent.context
setWebResourceRequestInterceptor { view, url -> shouldInterceptRequest(view, url) }
}
parent.addView(
richEditor,
ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
)
return cacheRichEditor
}
fun detachFromRichEditor(parent: ViewGroup) {
this.cacheRichEditor.setHtml("", false)
this.cacheRichEditor.setWebResourceRequestInterceptor(null)
(this.cacheRichEditor.context as MutableContextWrapper).baseContext = parent.context.applicationContext
parent.removeView(this.cacheRichEditor)
}
/**
* 拦截WebView的资源请求并返回URL对应的缓存数据
*/
fun shouldInterceptRequest(view: WebView, url: String): WebResourceResponse? {
val urlWithoutQueryParams = url.split("?")[0]
val cacheFile = File(cacheDir, MD5Utils.getUrlMD5(urlWithoutQueryParams))
if (!cacheFile.exists()) {
return null
}
val mimeType = if (urlWithoutQueryParams.endsWith(".js")) {
"text/javascript"
} else if (urlWithoutQueryParams.endsWith(".css")) {
"text/css"
} else null
return WebResourceResponse(mimeType, "utf-8", cacheFile.inputStream())
}
interface ApiService {
@GET
@Streaming
fun downloadFile(@Url url: String, @Query("timestamp") timestamp: Long): Single<ResponseBody>
}
}

View File

@ -2,7 +2,6 @@ package com.gh.gamecenter.qa.article.edit
import android.annotation.SuppressLint
import android.app.Activity
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.os.Bundle
@ -50,7 +49,7 @@ class ArticleEditActivity : BaseRichEditorActivity<ArticleEditViewModel>(), Keyb
private lateinit var mMenuDraft: MenuItem
private lateinit var mMenuPost: MenuItem
private var mProcessingDialog: WaitingDialogFragment? = null
private var mUploadImageCancelDialog: Dialog? = null
private var mUploadImageCancelDialog: DialogHelper.DialogAlertDefaultBindingWrapper? = null
private var mPostDraftsCount: Int = 0
private var mArticleTagsSelectFragment: ArticleTagsSelectFragment? = null
private lateinit var mBinding: ActivityCommunityArticleEditBinding
@ -132,7 +131,7 @@ class ArticleEditActivity : BaseRichEditorActivity<ArticleEditViewModel>(), Keyb
checkPostButtonEnable()
initListener()
mRichEditor.setOnTextChangeListener { t ->
if (t.contains("<img src") || !TextUtils.isEmpty(mRichEditor.text) || mViewModel.localVideoList.isNotEmpty()) {
if (t.contains("<blockquote>") || t.contains("<img src") || !TextUtils.isEmpty(mRichEditor.text) || mViewModel.localVideoList.isNotEmpty()) {
mBinding.articlePlaceholder.visibility = View.GONE
} else {
mBinding.articlePlaceholder.visibility = View.VISIBLE
@ -220,6 +219,7 @@ class ArticleEditActivity : BaseRichEditorActivity<ArticleEditViewModel>(), Keyb
finish()
}
}
SaveDraftType.AUTO -> {
if (pair.second) {
if (mPostDraftsCount >= AnswerEditActivity.SAVE_DRAFTS_TOAST_COUNT) {
@ -230,6 +230,7 @@ class ArticleEditActivity : BaseRichEditorActivity<ArticleEditViewModel>(), Keyb
}
}
}
SaveDraftType.SKIP -> {
if (pair.second) {
Utils.toast(this, "帖子已保存到草稿箱")
@ -287,14 +288,17 @@ class ArticleEditActivity : BaseRichEditorActivity<ArticleEditViewModel>(), Keyb
setNavigationTitle("修改帖子")
showPatchDraftDialogIfExisted()
}
!mViewModel.draftEntity?.articleId.isNullOrEmpty() && mViewModel.detailEntity == null -> {
setNavigationTitle("修改帖子")
mViewModel.getArticleDetail(mViewModel.draftEntity?.articleId ?: "")
}
mViewModel.draftEntity != null -> {
setNavigationTitle("发布帖子")
setArticleDraft()
}
else -> {// 启动自动保存草稿
setNavigationTitle("发布帖子")
mViewModel.mSelectCommunityData = intent.getParcelableExtra(CommunityEntity::class.java.simpleName)
@ -676,7 +680,8 @@ class ArticleEditActivity : BaseRichEditorActivity<ArticleEditViewModel>(), Keyb
if (item?.itemId == R.id.menu_answer_post) {
debounceActionWithInterval(R.id.menu_answer_post, 2000L) {
ifLogin("社区文章编辑-[发布]") {
val bbsType = if (mViewModel.mSelectCommunityData?.type == "official_bbs") "综合论坛" else "游戏论坛"
val bbsType =
if (mViewModel.mSelectCommunityData?.type == "official_bbs") "综合论坛" else "游戏论坛"
SensorsBridge.trackEvent(
"ArticlePostClick",
"bbs_id",

View File

@ -2,7 +2,6 @@ package com.gh.gamecenter.qa.questions.edit
import android.annotation.SuppressLint
import android.app.Activity
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.os.Bundle
@ -66,7 +65,7 @@ class QuestionEditActivity : BaseRichEditorActivity<QuestionEditViewModel>(),
private lateinit var mBinding: ActivityQuestionsEditBinding
private var mProcessingDialog: WaitingDialogFragment? = null
private var mUploadImageCancelDialog: Dialog? = null
private var mUploadImageCancelDialog: DialogHelper.DialogAlertDefaultBindingWrapper? = null
private lateinit var mMenuDraft: MenuItem
private lateinit var mMenuPost: MenuItem
private var mTagsSelectFragment: TagsSelectFragment? = null

View File

@ -108,11 +108,11 @@ class NewQuestionDetailFragment :
mAdapter?.questionDetailVH?.run {
if (questionImgUrlList.size > 0) {
if (imageSet.size == questionImgUrlList.size) {
binding.richEditor.replaceAllDfImage()
richEditor.replaceAllDfImage()
} else {
for (i in imageSet) {
val url = questionImgUrlList[i.toInt()]
binding.richEditor.replaceDfImageByUrl(url)
richEditor.replaceDfImageByUrl(url)
}
}
}
@ -742,6 +742,11 @@ class NewQuestionDetailFragment :
mBinding.root.setBackgroundColor(Color.TRANSPARENT)
}
override fun onDestroyView() {
super.onDestroyView()
mAdapter?.questionDetailVH?.destroy()
}
override fun onDarkModeChanged() {
super.onDarkModeChanged()
mAdapter?.let { it.notifyItemRangeChanged(0, it.itemCount) }

View File

@ -26,6 +26,7 @@ import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.databinding.ItemArticleDetailContentBinding
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.qa.article.detail.ArticleWebCacheManager
import com.gh.gamecenter.qa.article.detail.EditHistoryDialog
import com.gh.gamecenter.qa.editor.OnLinkClickListener
import com.gh.gamecenter.qa.entity.QuestionsDetailEntity
@ -36,40 +37,39 @@ class QuestionDetailContentViewHolder(
var viewModel: NewQuestionDetailViewModel
) : RecyclerView.ViewHolder(binding.root) {
val richEditor = ArticleWebCacheManager
.attachToRichEditor(binding.richEditorContainer)
.apply {
setInputEnabled(false)
setPadding(16, 4, 16, 4)
enableForceDark(DarkModeUtils.isDarkModeOn(binding.root.context))
setTransparentBackground()
setLayoutCallback { viewModel.questionRenderedLiveData.postValue(true) }
setPageFinishedListener { viewModel.questionPageFinishedLiveData.postValue(true) }
setChromeClientListener(object : RichEditor.WebChromeClientListener {
override fun onPageFinished(view: WebView?, url: String?) {}
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
return DefaultUrlHandler.interceptUrl(binding.root.context, url ?: "", "问题详情")
}
})
}
private var mEntrance = ""
val questionImgUrlList = ArrayList<String>()
@SuppressLint("AddJavascriptInterface")
fun bindView(question: QuestionsDetailEntity) {
binding.run {
richEditor.setInputEnabled(false)
richEditor.enableForceDark(DarkModeUtils.isDarkModeOn(binding.root.context))
richEditor.setTransparentBackground()
richEditor.setPadding(16, 4, 16, 4)
richEditor.removeJavascriptInterface("imagelistener")
richEditor.addJavascriptInterface(JsInterface(question.status), "imagelistener")
richEditor.removeJavascriptInterface("OnLinkClickListener")
richEditor.addJavascriptInterface(
OnLinkClickListener(
root.context, question.title
?: "", question.status, mEntrance, "问题详情"
), "OnLinkClickListener"
)
richEditor.setLayoutCallback(object : EmptyCallback {
override fun onCallback() {
viewModel.questionRenderedLiveData.postValue(true)
}
})
richEditor.setPageFinishedListener {
viewModel.questionPageFinishedLiveData.postValue(true)
}
richEditor.setChromeClientListener(object : RichEditor.WebChromeClientListener {
override fun onPageFinished(view: WebView?, url: String?) {
}
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
return DefaultUrlHandler.interceptUrl(binding.root.context, url ?: "", "问题详情")
}
})
approvalStatusTv.goneIf(question.status == "pass")
statusContainer.goneIf(question.status == "pass")
when (question.status) {
@ -205,7 +205,7 @@ class QuestionDetailContentViewHolder(
if (question.sections.isNotEmpty() && question.sections[0].id.isNotEmpty() && question.sections[0].name.isNotEmpty()) {
sectionNameTv.text =
binding.root.context.getString(
R.string.article_detail_content_section_name,
R.string.article_detail_content_forum_name,
question.sections[0].name
)
sectionNameTv.visibility = View.VISIBLE
@ -275,7 +275,7 @@ class QuestionDetailContentViewHolder(
* 回调列表视频播放结束时的时间
*/
fun onVideoPlayedCallback(url: String, position: Int) {
binding.richEditor.onVideoPlayedCallback(url, position)
richEditor.onVideoPlayedCallback(url, position)
}
inner class JsInterface(val status: String) {
@ -283,7 +283,7 @@ class QuestionDetailContentViewHolder(
fun imageClick(url: String) {
when {
url.contains("web_load_dfimg_icon.png") -> {
runOnUiThread { binding.richEditor.replaceAllDfImageExcludeGif() }
runOnUiThread { richEditor.replaceAllDfImageExcludeGif() }
}
// url.contains(RichEditor.IMAGE_FLAG_THUMBNAIL) -> {
// runOnUiThread { binding.richEditor.replaceDfImageByUrl(url) }
@ -320,4 +320,14 @@ class QuestionDetailContentViewHolder(
}
}
}
fun destroy() {
richEditor.setLayoutCallback(null)
richEditor.removeJavascriptInterface("imagelistener")
richEditor.removeJavascriptInterface("OnLinkClickListener")
richEditor.setChromeClientListener(null)
richEditor.setContentOwner(false)
richEditor.setPageFinishedListener(null)
ArticleWebCacheManager.detachFromRichEditor(binding.richEditorContainer)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 949 B

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="14dp" />
<solid android:color="@color/background" />
</shape>

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/background">
<FrameLayout
android:id="@+id/skeleton"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/list_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list_rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<include
android:id="@+id/reuse_ll_loading"
layout="@layout/reuse_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
<include
android:id="@+id/reuse_no_connection"
layout="@layout/item_article_detail_comment_empty" />
<include
android:id="@+id/reuse_none_data"
layout="@layout/item_article_detail_comment_empty" />
<include
android:id="@+id/reuse_data_exception"
layout="@layout/item_article_detail_comment_empty" />
</RelativeLayout>

View File

@ -27,10 +27,12 @@
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/orderSfv"
app:tabPaddingEnd="0dp"
app:tabPaddingStart="0dp"
app:tabPaddingEnd="16dp"
app:tabPaddingStart="16dp"
app:tabIndicator="@null"
app:tabMode="scrollable"
app:tabMaxWidth="0dp"
app:tabMinWidth="0dp"
app:tabRippleColor="@color/transparent"
app:tabTextAppearance="@style/TabLayoutTextAppearance" />

View File

@ -217,8 +217,8 @@
android:textStyle="bold"
tools:text="这是一个很长很长很长很长很长很长很长很长很长很长的标题" />
<com.gh.common.view.RichEditor
android:id="@+id/richEditor"
<FrameLayout
android:id="@+id/richEditorContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="13dp" />
@ -253,7 +253,7 @@
android:layout_height="28dp"
android:layout_marginLeft="16dp"
android:layout_marginBottom="24dp"
android:background="@drawable/bg_shape_f5_radius_14"
android:background="@drawable/bg_shape_f8_radius_8"
android:gravity="center_vertical"
android:orientation="horizontal"
android:layout_marginStart="16dp">

View File

@ -466,7 +466,7 @@
<string name="update_all_has_land_page_address_dialog_content">部分游戏下载资源由第三方提供,此类游戏无法自动更新,请手动点击游戏【更新】按钮前往第三方网址更新游戏</string>
<string name="update_all_has_land_page_address_dialog_confirm">我知道了</string>
<string name="miui_open_adb_hint">请查看关闭教程,先开启开发者模式</string>
<string name="article_detail_content_section_name">%1$s论坛</string>
<string name="article_detail_content_forum_name">%1$s论坛</string>
<string name="article_detail_content_edit_time">发布于%1$s</string>
<string name="article_detail_comment_list_tab_title">评论 %1$d</string>
<string name="article_detail_related_content_vote_and_comment">点赞 %1$d · 评论 %2$d</string>

View File

@ -82,7 +82,7 @@ class HelpVideoAdapter(
}
}
override fun getItemCount(): Int = if (mHelpVideoList.size < 2) mHelpVideoList.size else Int.MAX_VALUE
override fun getItemCount(): Int = if (mHelpVideoList.size < 3) mHelpVideoList.size else Int.MAX_VALUE
fun getActualPosition(position: Int): Int {
var actualPosition = position
@ -103,10 +103,12 @@ class HelpVideoAdapter(
class HelpVideoItemViewHolder(val binding: ItemHelpVideoBinding) : BaseRecyclerViewHolder<Any>(binding.root)
fun scrollToNextPage() {
mSnapHelper.findSnapView(mLayoutManager)?.let {
val position = mLayoutManager.getPosition(it)
mLayoutManager.smoothScrollToPosition(mRecyclerView, null, position + 1)
startScroll()
if (itemCount > 2) {
mSnapHelper.findSnapView(mLayoutManager)?.let {
val position = mLayoutManager.getPosition(it)
mRecyclerView.scrollToPositionWithTop(position + 1)
startScroll()
}
}
}

View File

@ -303,7 +303,7 @@ public class Constants {
public static final String FORUM_REGULATIONS_NEWS_ID = "5f4db9cc34d44d01b92fd670";
// 权限使用场景地址
public static final String PERMISSION_SCENARIO_ADDRESS = "https://resource.ghzs.com/page/permissions/android.html";
public static final String PERMISSION_SCENARIO_ADDRESS = "https://resource.ghzs.com/page/privacy_policies/permissions.html";
//帮助内容详情
public static final String HELP_ADDRESS_DEV = "https://static-web.ghzs.com/ghzs_help_dev/help.html?content=";

View File

@ -115,6 +115,9 @@ public class EntranceConsts {
public static final String KEY_GAME_INFO = "game_info";
public static final String KEY_GAME_TYPE = "game_type";
public static final String KEY_DOWNLOAD_STATUS = "download_status";
//畅玩助手的版本
public static final String KEY_PLATFORM_VERSION = "platform_version";
public static final String KEY_VERSION = "version";

View File

@ -3,6 +3,7 @@ package com.gh.gamecenter.common.utils
import android.app.Activity
import android.app.Dialog
import android.content.Context
import android.content.DialogInterface.OnCancelListener
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Typeface
@ -13,10 +14,12 @@ import android.text.Spannable
import android.text.SpannableStringBuilder
import android.text.style.StyleSpan
import android.view.*
import android.widget.ImageView
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import androidx.viewbinding.ViewBinding
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.gamecenter.common.R
import com.gh.gamecenter.common.base.TrackableDialog
@ -31,6 +34,7 @@ import com.gh.gamecenter.core.provider.ISettingProvider
import com.gh.gamecenter.core.provider.IUpdateManagerProvider
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.core.utils.MtaHelper
import com.google.android.material.imageview.ShapeableImageView
import com.lightgame.download.DownloadEntity
import com.lightgame.utils.AppManager
import splitties.systemservices.layoutInflater
@ -54,12 +58,13 @@ object DialogHelper {
confirmClickCallback: (() -> Unit)? = null,
cancelClickCallback: (() -> Unit)? = null,
dialogCancelCallback: (() -> Unit)? = null,
touchOutsideCallback: (() -> Unit)? = null,
extraConfig: Config? = null,
uiModificationCallback: ((binding: DefaultDialogAlertDefaultBindingWrapper) -> Unit)? = null,
uiModificationCallback: ((binding: DialogAlertDefaultBindingWrapper) -> Unit)? = null,
trackMtaEvent: Boolean = false,
mtaEvent: String = "",
mtaKey: String = ""
): Dialog? {
): DialogAlertDefaultBindingWrapper? {
val solidContext = checkDialogContext(context) ?: return null
if (solidContext is Activity && solidContext.isFinishing) return null
@ -70,7 +75,10 @@ object DialogHelper {
Dialog(solidContext, R.style.GhAlertDialog)
}
val binding = DialogAlertDefaultBinding.inflate(LayoutInflater.from(solidContext))
val binding = DialogAlertDefaultBindingWrapper(
dialog = dialog,
binding = DialogAlertDefaultBinding.inflate(LayoutInflater.from(solidContext))
)
val contentView = binding.root
binding.contentTv.text = content
binding.titleTv.text = title
@ -92,7 +100,10 @@ object DialogHelper {
if (it.showCloseIcon) {
binding.closeContainer.visibility = View.VISIBLE
binding.closeContainer.enlargeTouchArea()
binding.closeContainer.setOnClickListener { dialog.dismiss() }
binding.closeContainer.setOnClickListener {
binding.markDismissByTouchInside()
dialog.dismiss()
}
}
if (it.titleIcon != -1) {
@ -109,20 +120,32 @@ object DialogHelper {
binding.confirmTv.text = confirmText
binding.cancelTv.setOnClickListener {
if (trackMtaEvent) MtaHelper.onEvent(mtaEvent, mtaKey, "点击$cancelText")
binding.markDismissByTouchInside()
if (trackMtaEvent) {
MtaHelper.onEvent(mtaEvent, mtaKey, "点击$cancelText")
}
cancelClickCallback?.invoke()
dialog.dismiss()
}
binding.confirmTv.setOnClickListener {
if (trackMtaEvent) MtaHelper.onEvent(mtaEvent, mtaKey, "点击$confirmText")
binding.markDismissByTouchInside()
if (trackMtaEvent) {
MtaHelper.onEvent(mtaEvent, mtaKey, "点击$confirmText")
}
confirmClickCallback?.invoke()
dialog.dismiss()
}
uiModificationCallback?.invoke(DefaultDialogAlertDefaultBindingWrapper(dialog, binding))
binding.setOnTouchOutsideListener {
touchOutsideCallback?.invoke()
}
uiModificationCallback?.invoke(binding)
dialog.setOnCancelListener {
dialogCancelCallback?.invoke()
@ -132,7 +155,7 @@ object DialogHelper {
dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
dialog.show()
return dialog
return binding
}
/**
@ -150,12 +173,14 @@ object DialogHelper {
cancelText: String,
confirmClickCallback: (() -> Unit)? = null,
cancelClickCallback: (() -> Unit)? = null,
touchOutsideCallback: (() -> Unit)? = null,
extraConfig: Config? = null,
uiModificationCallback: ((binding: DialogGuideBinding, dialog: Dialog) -> Unit)? = null,
uiModificationCallback: ((binding: DialogGuideBindingWrapper) -> Unit)? = null,
trackMtaEvent: Boolean = false,
mtaEvent: String = "",
mtaKey: String = ""
): Dialog? {
val solidContext = checkDialogContext(context) ?: return null
if (solidContext is Activity && solidContext.isFinishing) return null
@ -166,12 +191,15 @@ object DialogHelper {
Dialog(solidContext, R.style.GhAlertDialog)
}
val binding = DialogGuideBinding.inflate(LayoutInflater.from(solidContext))
val binding = DialogGuideBindingWrapper(
dialog = dialog,
binding = DialogGuideBinding.inflate(LayoutInflater.from(solidContext))
)
val contentView = binding.root
binding.contentTv.text = content
binding.titleTv.text = title
initGuideDialogExtraConfig(dialog, binding, extraConfig)
initGuideDialogExtraConfig(binding, extraConfig)
if (cancelText.isEmpty()) {
binding.cancelTv.visibility = View.GONE
@ -181,6 +209,8 @@ object DialogHelper {
binding.confirmTv.text = confirmText
binding.cancelTv.setOnClickListener {
binding.markDismissByTouchInside()
if (trackMtaEvent) MtaHelper.onEvent(mtaEvent, mtaKey, "点击$cancelText")
cancelClickCallback?.invoke()
@ -188,13 +218,18 @@ object DialogHelper {
}
binding.confirmTv.setOnClickListener {
binding.markDismissByTouchInside()
if (trackMtaEvent) MtaHelper.onEvent(mtaEvent, mtaKey, "点击$confirmText")
confirmClickCallback?.invoke()
dialog.dismiss()
}
uiModificationCallback?.invoke(binding, dialog)
uiModificationCallback?.invoke(binding)
binding.setOnTouchOutsideListener {
touchOutsideCallback?.invoke()
}
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
dialog.setContentView(contentView)
@ -204,7 +239,7 @@ object DialogHelper {
return dialog
}
private fun initGuideDialogExtraConfig(dialog: Dialog, binding: DialogGuideBinding, extraConfig: Config?) {
private fun initGuideDialogExtraConfig(binding: DialogGuideBindingWrapper, extraConfig: Config?) {
extraConfig?.let {
if (it.hint.isNotEmpty()) {
binding.hintTv.visibility = View.VISIBLE
@ -222,7 +257,10 @@ object DialogHelper {
if (it.showCloseIcon) {
binding.closeContainer.visibility = View.VISIBLE
binding.closeContainer.enlargeTouchArea()
binding.closeContainer.setOnClickListener { dialog.dismiss() }
binding.closeContainer.setOnClickListener {
binding.markDismissByTouchInside()
binding.dismiss()
}
}
if (it.showAlternativeCancelStyle) {
@ -275,6 +313,7 @@ object DialogHelper {
* For legacy java invocation
*/
@JvmStatic
@JvmOverloads
@Deprecated("Kotlin 中请使用其它方法调用")
fun showCenterDialog(
context: Context,
@ -283,7 +322,8 @@ object DialogHelper {
positiveText: String,
negativeText: String,
positiveClickCallback: EmptyCallback,
negativeClickCallback: EmptyCallback
negativeClickCallback: EmptyCallback,
touchOutsideCallback: EmptyCallback? = null,
) {
showDialog(
context = context,
@ -293,6 +333,7 @@ object DialogHelper {
cancelText = negativeText,
confirmClickCallback = { positiveClickCallback.onCallback() },
cancelClickCallback = { negativeClickCallback.onCallback() },
touchOutsideCallback = { touchOutsideCallback?.onCallback() },
extraConfig = Config(centerTitle = true, centerContent = true)
)
}
@ -342,7 +383,7 @@ object DialogHelper {
"检测到安装包与已安装应用的签名不一致,需要卸载后才能安装,是否立即卸载",
"卸载",
"取消",
{
confirmClickCallback = {
confirmClickCallback?.invoke()
SensorsBridge.trackConflictSignatureInstallDialogClick(
buttonName = "卸载",
@ -351,7 +392,7 @@ object DialogHelper {
gameType = gameType
)
},
{
cancelClickCallback = {
SensorsBridge.trackConflictSignatureInstallDialogClick(
buttonName = "取消",
gameId = gameId,
@ -359,6 +400,14 @@ object DialogHelper {
gameType = gameType
)
},
touchOutsideCallback = {
SensorsBridge.trackConflictSignatureInstallDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameType
)
},
extraConfig = Config(hint = "注意:卸载会让游戏数据丢失,请提前做好备份"),
uiModificationCallback = { binding -> binding.hintTv.setTextColor(R.color.theme_font.toColor(context)) }
)
@ -402,7 +451,7 @@ object DialogHelper {
"您将进行${pluginDescNonNull}化安装以实现${pluginDescNonNull}功能,此过程将卸载当前使用的版本并安装${pluginDescNonNull}版本",
"确认,开始${pluginDescNonNull}",
"取消",
{
confirmClickCallback = {
confirmClickCallback?.invoke()
MtaHelper.onEvent("插件化", "插件化安装弹窗", "确认并开始")
SensorsBridge.trackPluginInstallDialogClick(
@ -419,7 +468,7 @@ object DialogHelper {
platform = platform
)
},
{
cancelClickCallback = {
MtaHelper.onEvent("插件化", "插件化安装弹窗", "取消")
SensorsBridge.trackPluginInstallDialogClick(
buttonName = "取消",
@ -435,6 +484,21 @@ object DialogHelper {
platform = platform
)
},
touchOutsideCallback = {
SensorsBridge.trackPluginInstallDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameType,
platform = platform
)
NewFlatLogUtils.logPluginInstallPopClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
platform = platform
)
},
extraConfig = Config(hint = "注意:卸载前请妥善保存游戏账号与密码"),
uiModificationCallback = { binding -> binding.hintTv.setTextColor(R.color.text_FF0000.toColor()) }
)
@ -580,7 +644,8 @@ object DialogHelper {
confirmText: String,
cancelText: String,
confirmClickCallback: (() -> Unit)? = null,
cancelClickCallback: (() -> Unit)? = null
cancelClickCallback: (() -> Unit)? = null,
touchOutsideCallback: (() -> Unit)? = null
) {
val webContent = Html.fromHtml(content)
showDialog(
@ -590,7 +655,8 @@ object DialogHelper {
confirmText,
cancelText,
confirmClickCallback,
cancelClickCallback
cancelClickCallback,
touchOutsideCallback = touchOutsideCallback
)
}
@ -742,7 +808,7 @@ object DialogHelper {
context: Context,
downloadEntity: DownloadEntity,
onHintClick: () -> Unit,
onConfirmClick: (DefaultDialogAlertDefaultBindingWrapper) -> Unit,
onConfirmClick: (DialogAlertDefaultBindingWrapper) -> Unit,
) {
SensorsBridge.trackMiuiOptimizeCloseDialogShow(
gameId = downloadEntity.gameId,
@ -777,7 +843,7 @@ object DialogHelper {
}
binding.confirmTv.setOnClickListener {
SensorsBridge.trackMiuiOptimizeCloseDialogClick(
buttonName = "关闭MIUI优化",
buttonName = "立即关闭",
gameId = downloadEntity.gameId,
gameName = downloadEntity.name,
gameType = downloadEntity.categoryChinese
@ -792,6 +858,14 @@ object DialogHelper {
gameName = downloadEntity.name,
gameType = downloadEntity.categoryChinese
)
},
touchOutsideCallback = {
SensorsBridge.trackMiuiOptimizeCloseDialogClick(
buttonName = "关闭弹窗",
gameId = downloadEntity.gameId,
gameName = downloadEntity.name,
gameType = downloadEntity.categoryChinese
)
}
)
}
@ -819,14 +893,29 @@ object DialogHelper {
val titleIcon: Int = -1
)
class DialogGuideBindingWrapper(
dialog: Dialog,
binding: DialogGuideBinding
) : DialogBindingWrapper<DialogGuideBinding>(dialog, binding) {
val rootContainer: View get() = binding.rootContainer
val titleTv: TextView get() = binding.titleTv
val hintTv: TextView get() = binding.hintTv
val cancelTv: TextView get() = binding.cancelTv
val confirmTv: TextView get() = binding.confirmTv
val closeContainer: View get() = binding.closeContainer
val headIv: ShapeableImageView get() = binding.headIv
val closeIv: ImageView get() = binding.closeIv
val contentTv: TextView get() = binding.contentTv
val alternativeCancelTv: TextView get() = binding.alternativeCancelTv
}
/**
* 通用Alert弹窗包装类可通过该类代理一些Dialog相关的方法
* 通用Alert弹窗包装类
*/
class DefaultDialogAlertDefaultBindingWrapper(
private val dialog: Dialog,
private val binding: DialogAlertDefaultBinding
) {
val root: View = binding.root
class DialogAlertDefaultBindingWrapper(
dialog: Dialog,
binding: DialogAlertDefaultBinding
) : DialogBindingWrapper<DialogAlertDefaultBinding>(dialog, binding) {
val titleTv: TextView get() = binding.titleTv
val contentTv: TextView get() = binding.contentTv
val hintTv: TextView get() = binding.hintTv
@ -835,6 +924,52 @@ object DialogHelper {
val cancelTv: TextView get() = binding.cancelTv
val confirmTv: TextView get() = binding.confirmTv
val lineView: View get() = binding.lineView
}
/**
* 通用弹窗Binding包装类可通过该类代理一些Dialog相关的方法
*/
abstract class DialogBindingWrapper<T: ViewBinding>(
protected val dialog: Dialog,
protected val binding: T
) {
val root: View = binding.root
private var dismissByTouchInside: Boolean = false
private var onDismissListener: ((DialogBindingWrapper<T>) -> Unit)? = null
private var onTouchOutsideListener: ((DialogBindingWrapper<T>) -> Unit)? = null
init {
dialog.setOnDismissListener {
if (!dismissByTouchInside) {
onTouchOutsideListener?.invoke(this)
}
onDismissListener?.invoke(this)
}
}
fun markDismissByTouchInside() {
dismissByTouchInside = true
}
fun setOnCancelListener(listener: OnCancelListener) {
dialog.setOnCancelListener(listener)
}
fun setOnDismissListener(listener: ((DialogBindingWrapper<T>) -> Unit)?) {
onDismissListener = listener
}
fun setOnTouchOutsideListener(listener: ((DialogBindingWrapper<T>) -> Unit)?) {
onTouchOutsideListener = listener
}
fun setCancelable(cancelable: Boolean) {
dialog.setCancelable(cancelable)
}
fun dismiss() = dialog.dismiss()
}

View File

@ -4,6 +4,7 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.OrientationHelper;
import androidx.recyclerview.widget.PagerSnapHelper;
import androidx.recyclerview.widget.RecyclerView;
@ -61,4 +62,29 @@ public class LeftPagerSnapHelper extends PagerSnapHelper {
}
return mHorizontalHelper;
}
@Nullable
@Override
public View findSnapView(RecyclerView.LayoutManager layoutManager) {
OrientationHelper helper = layoutManager.canScrollHorizontally() ? getHorizontalHelper(layoutManager) : getVerticalHelper(layoutManager);
if (layoutManager instanceof LinearLayoutManager) {
int firstChildPosition = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
if (firstChildPosition == RecyclerView.NO_POSITION) {
return null;
}
if (((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition() == layoutManager.getItemCount() - 1) {
return null;
}
View firstChildView = layoutManager.findViewByPosition(firstChildPosition);
if (helper.getDecoratedEnd(firstChildView) >= helper.getDecoratedMeasurement(firstChildView) / 2 && helper.getDecoratedEnd(firstChildView) > 0) {
return firstChildView;
} else {
return layoutManager.findViewByPosition(firstChildPosition + 1);
}
} else {
return null;
}
}
}

View File

@ -48,7 +48,7 @@ object OssUploadUtils {
return getOssUpdateConfig(uploadType)
.subscribeOn(Schedulers.io())
.flatMap { mOssEntity ->
Single.create<String> {
Single.create<String?> {
val conf = ClientConfiguration()
conf.connectionTimeout = 15 * 1000
conf.socketTimeout = 15 * 1000
@ -92,8 +92,8 @@ object OssUploadUtils {
}
}.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { url, throwable ->
if (url.isNotEmpty()) {
.subscribe { url:String?, throwable ->
if (!url.isNullOrBlank()) {
listener?.onSuccess(url)
return@subscribe
}

View File

@ -296,11 +296,10 @@ object PermissionHelper {
DialogHelper.showDialog(
context,
title = "权限申请",
content = "光环助手将向您申请开启设备的存储权限,以保证能正常使用相关功能。拒绝授权将无法正常使用部分功能。",
content = "光环助手将向您申请开启设备的存储权限,以保证游戏下载/图片/视频上传等功能的正常使用。拒绝授权将无法使用部分功能。",
cancelText = "放弃",
confirmText = "去授权",
cancelClickCallback = {
isCanceledByClickingOutside = false
NewFlatLogUtils.logExternalStoragePermissionDialogAction("放弃")
SensorsBridge.trackGainStoragePermissionsDialogClick(
buttonName = "放弃",
@ -310,7 +309,6 @@ object PermissionHelper {
)
},
confirmClickCallback = {
isCanceledByClickingOutside = false
checkStoragePermissionBeforeAction(context, emptyCallback)
NewFlatLogUtils.logExternalStoragePermissionDialogAction("去授权")
SensorsBridge.trackGainStoragePermissionsDialogClick(
@ -320,6 +318,15 @@ object PermissionHelper {
gameType = gameType
)
},
touchOutsideCallback = {
NewFlatLogUtils.logExternalStoragePermissionDialogAction("点击弹窗以外空白区域")
SensorsBridge.trackGainStoragePermissionsDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameType
)
},
extraConfig = DialogHelper.Config(hint = HINT_CHECK_USAGE),
uiModificationCallback = {
it.hintTv.setTextColor(ContextCompat.getColor(context, R.color.theme_font))
@ -337,17 +344,7 @@ object PermissionHelper {
}
it.contentTv.setTextColor(ContextCompat.getColor(context, R.color.text_title))
}
)?.setOnDismissListener {
if (isCanceledByClickingOutside) {
NewFlatLogUtils.logExternalStoragePermissionDialogAction("点击弹窗以外空白区域")
SensorsBridge.trackGainStoragePermissionsDialogClick(
buttonName = "关闭弹窗",
gameId = gameId,
gameName = gameName,
gameType = gameType
)
}
}
)
}
private fun showDialogBeforeRequestingGetInstalledListDialog(
@ -379,6 +376,8 @@ object PermissionHelper {
fun isGetInstalledListPermissionDisabled(context: Context): Boolean {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false
if (Build.MANUFACTURER.contains("vivo")) return false
val permissionInfo: PermissionInfo?
return try {
permissionInfo = context.packageManager.getPermissionInfo(PERMISSION_GET_INSTALLED_LIST, 0)

View File

@ -49,6 +49,7 @@ object SensorsBridge {
private const val KEY_COLUMN_COLLECTION_ID = "column_collection_id"
private const val KEY_GAME_COLUMN_NAME = "game_column_name"
private const val KEY_GAME_COLUMN_ID = "game_column_id"
private const val KEY_IS_NOT_PROMPT = "is_not_prompt"
private const val EVENT_GAME_DETAIL_PAGE_TAB_SELECT = "GameDetailPageTabSelect"
private const val EVENT_GAME_DETAIL_PAGE_TAG_CLICK = "GameDetailPageGameTagClick"
@ -262,7 +263,7 @@ object SensorsBridge {
downloadStatus: String,
gameType: String,
position: Int,
gameTag: String,
gameTag: List<String>,
gameTagId: String
) {
val json = json {
@ -417,6 +418,7 @@ object SensorsBridge {
* @param gameType 游戏类型
* @param clickGameId 点击游戏ID
* @param clickGameName 点击游戏名称
* @param clickGameType 点击游戏类型
* @see EVENT_GAME_DETAIL_PAGE_RELATED_GAME_CLICK
*/
@JvmStatic
@ -432,7 +434,8 @@ object SensorsBridge {
downloadStatus: String,
gameType: String,
clickGameId: String,
clickGameName: String
clickGameName: String,
clickGameType: String
) {
val json = json {
KEY_GAME_ID to gameId
@ -447,6 +450,7 @@ object SensorsBridge {
KEY_GAME_TYPE to gameType
KEY_CLICK_GAME_ID to clickGameId
KEY_CLICK_GAME_NAME to clickGameName
KEY_CLICK_GAME_TYPE to clickGameType
}
trackEvent(EVENT_GAME_DETAIL_PAGE_RELATED_GAME_CLICK, json)
@ -520,9 +524,6 @@ object SensorsBridge {
* @param lastPageBusinessId 上一页页面业务ID
* @param downloadStatus 下载状态
* @param gameType 游戏类型
* @param clickGameId 点击游戏ID
* @param clickGameName 点击游戏名称
* @param clickGameType 点击游戏类型
* @param text 点击内容
* @param gameCollectTitle 游戏单标题
* @param gameCollectId 游戏单ID
@ -538,6 +539,8 @@ object SensorsBridge {
lastPageName: String,
lastPageId: String,
lastPageBusinessId: String,
downloadStatus: String,
gameType: String,
text: String,
gameCollectTitle: String,
gameCollectId: String
@ -551,6 +554,8 @@ object SensorsBridge {
KEY_LAST_PAGE_ID to lastPageId
KEY_LAST_PAGE_NAME to lastPageName
KEY_LAST_PAGE_BUSINESS_ID to lastPageBusinessId
KEY_DOWNLOAD_STATUS to downloadStatus
KEY_GAME_TYPE to gameType
KEY_TEXT to text
KEY_GAME_COLLECT_TITLE to gameCollectTitle
KEY_GAME_COLLECT_ID to gameCollectId
@ -744,6 +749,10 @@ object SensorsBridge {
* @param gameId 游戏ID
* @param gameName 游戏名称
* @param gameType 游戏类型
* @param isNotPrompt 是否不再提示
* @param linkId 跳转链接,仅点击“跳转链接”按钮时上报
* @param linkType 链接类型,仅点击“跳转链接”按钮时上报
* @param linkText 链接文案,仅点击“跳转链接”按钮时上报
* @see EVENT_PKG_CHECK_DIALOG_CLICK
*/
@JvmStatic
@ -751,13 +760,23 @@ object SensorsBridge {
buttonName: String,
gameId: String,
gameName: String,
gameType: String
gameType: String,
isNotPrompt: Boolean?,
linkId: String = "",
linkType: String = "",
linkText: String = "",
) {
val json = json {
KEY_BUTTON_NAME to buttonName
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
KEY_GAME_TYPE to gameType
KEY_LINK_ID to linkId
KEY_LINK_TYPE to linkType
KEY_LINK_TEXT to linkText
isNotPrompt?.let {
KEY_IS_NOT_PROMPT to it
}
}
trackEvent(EVENT_PKG_CHECK_DIALOG_CLICK, json)
@ -1646,6 +1665,7 @@ object SensorsBridge {
* @param linkType 链接类型
* @param linkId 跳转链接
* @param linkText 链接文案
* @param text 点击位置 1.全部 2.通用内容
* @see EVENT_LINK_CONTENT_COLLECTION_CLICK
*/
@JvmStatic
@ -1658,7 +1678,8 @@ object SensorsBridge {
position: Int,
linkType: String,
linkId: String,
linkText: String
linkText: String,
text: String
) {
val json = json {
KEY_LOCATION to location
@ -1670,6 +1691,7 @@ object SensorsBridge {
KEY_LINK_TYPE to linkType
KEY_LINK_ID to linkId
KEY_LINK_TEXT to linkText
KEY_TEXT to text
}
trackEvent(EVENT_LINK_CONTENT_COLLECTION_CLICK, json)
@ -1687,6 +1709,7 @@ object SensorsBridge {
* @param position 序号
* @param gameColumnName 游戏专题名称
* @param gameColumnId 游戏专题ID
* @param text 点击位置 1.全部 2.游戏专题
* @see EVENT_COLUMN_COLLECTION_CLICK
*/
@JvmStatic
@ -1698,7 +1721,8 @@ object SensorsBridge {
columnCollectionId: String,
position: Int,
gameColumnName: String,
gameColumnId: String
gameColumnId: String,
text: String
) {
val json = json {
KEY_LOCATION to location
@ -1709,6 +1733,7 @@ object SensorsBridge {
KEY_POSITION to position
KEY_GAME_COLUMN_NAME to gameColumnName
KEY_GAME_COLUMN_ID to gameColumnId
KEY_TEXT to text
}
trackEvent(EVENT_COLUMN_COLLECTION_CLICK, json)

View File

@ -36,7 +36,7 @@ object DialogHelper {
{
NewFlatLogUtils.logLoginPrivacyPolicyPopClick("不同意")
},
uiModificationCallback = { binding, _ ->
uiModificationCallback = { binding ->
binding.run {
rootContainer.background = R.drawable.background_shape_white_radius_8.toDrawable(context)
titleTv.setTextColor(R.color.text_title.toColor(context))

View File

@ -90,7 +90,11 @@ public class WXEntryActivity extends Activity implements IWXAPIEventHandler, WeC
break;
}
}
} else if (baseResp.getType() == ConstantsAPI.COMMAND_SENDAUTH && baseResp instanceof SendAuth.Resp) {
} else if (baseResp.getType() == ConstantsAPI.COMMAND_SENDAUTH
&& baseResp instanceof SendAuth.Resp
&& ((SendAuth.Resp) baseResp).state != null
&& ((SendAuth.Resp) baseResp).state.contains("qqminigame")
) {
IQGameProvider<SendAuth.Resp> iqGameProvider = (IQGameProvider<SendAuth.Resp>) ARouter.getInstance().build(RouteConsts.provider.qGame).navigation();
if (iqGameProvider != null) {

View File

@ -2,6 +2,7 @@ package com.gh.gamecenter.sensorsdata.provider
import android.app.Application
import android.content.Context
import android.util.Log
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.ISensorsProvider