Compare commits
48 Commits
feature-GH
...
feature-js
| Author | SHA1 | Date | |
|---|---|---|---|
| 49a610deee | |||
| 61f43d53b2 | |||
| 0dcf5d2097 | |||
| 32e584c04c | |||
| f726a4629f | |||
| fbe29d82be | |||
| a6c2254db3 | |||
| 3d4977dc87 | |||
| 4d0fda6157 | |||
| 34fb8ccf93 | |||
| 49b9c3a135 | |||
| bc04dcc94b | |||
| eb0bba47f9 | |||
| 9ba4e9c2cf | |||
| 3a69bb4452 | |||
| 0581ebf409 | |||
| 44607a9039 | |||
| 00db8c00c6 | |||
| c64713117e | |||
| f2b965b447 | |||
| 0ae4f745ee | |||
| bcfd9cdfef | |||
| 94ffe5a86f | |||
| c3ddd28bad | |||
| eab8bc846c | |||
| 455ed32ac6 | |||
| fd92979481 | |||
| 3d322b29c1 | |||
| dcfc2f44cb | |||
| 4008c7fa4d | |||
| f2d714280b | |||
| 6862609bba | |||
| 3afae78477 | |||
| b03df595bc | |||
| c6f0825fb5 | |||
| cbc2902613 | |||
| db725a417d | |||
| 4270924d0f | |||
| 69fc206377 | |||
| 8468ec45c2 | |||
| 256a4c2b0a | |||
| 7d01e47c26 | |||
| 5814f468b3 | |||
| a5730e0ffd | |||
| 0dfd87db25 | |||
| 31aa16f155 | |||
| b22c6b9a5b | |||
| f1c0155379 |
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
)
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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)
|
||||
)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -178,6 +178,7 @@ public class CommentUtils {
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new DialogHelper.Config("", false, true, true, false, -1)
|
||||
);
|
||||
break;
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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() })
|
||||
}
|
||||
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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, "关闭按钮")
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
)
|
||||
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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 = "修改路径:我的光环-设置-切换安装方式")
|
||||
)
|
||||
}
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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
|
||||
)
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -278,7 +278,7 @@ class CloudArchiveManagerActivity : BaseActivity_TabLayout() {
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable?) {
|
||||
toast("上传失败")
|
||||
toast("存档上传失败")
|
||||
}
|
||||
},
|
||||
null,
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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" -> {
|
||||
|
||||
@ -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" -> {
|
||||
|
||||
@ -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
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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!!
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 = "通用内容"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 =
|
||||
|
||||
@ -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 ?: "",
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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"))
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 = "游戏专题"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -92,6 +92,7 @@ class HomeGameTestV2GameListViewHolder(
|
||||
val timeText = getTimeText(time)
|
||||
val typeText = when (gameEntity.eventType) {
|
||||
"test" -> "开启测试"
|
||||
"update" -> "游戏更新"
|
||||
else -> "首发上线"
|
||||
}
|
||||
return "$timeText $typeText"
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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]
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
@ -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!!)
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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>
|
||||
}
|
||||
}
|
||||
@ -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",
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) }
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
BIN
app/src/main/res/drawable-xxxhdpi/permission_installed_list.png
Normal file
BIN
app/src/main/res/drawable-xxxhdpi/permission_installed_list.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 949 B |
@ -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>
|
||||
@ -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>
|
||||
@ -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" />
|
||||
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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=";
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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()
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user