Compare commits

..

48 Commits

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

View File

@ -72,7 +72,6 @@ android_build:
only:
- dev
- dev-5.32.0
- feature-GHZS-3350
# 代码检查
sonarqube_analysis:
@ -137,7 +136,7 @@ oss-upload&send-email:
BUCKET: "shanqu" # 固定值
FILE_PATH: "app/build/tmp/" # APK 存放路径
Email_To_List: $EMAIL_TO_LIST # 邮件接受人列表
Email_Title: "光环助手】游戏开服/开测消息通知 $CI_COMMIT_BRANCH" # 邮件标题
Email_Title: "光环助手 $CI_COMMIT_BRANCH" # 邮件标题
PIPELINE_ID: $CI_PIPELINE_ID # 流水线id
COMMIT_BRANCH: $CI_COMMIT_BRANCH # 提交分支
MAIL_MESSAGE: "[$CI_COMMIT_AUTHOR] $CI_COMMIT_MESSAGE"
@ -153,5 +152,4 @@ oss-upload&send-email:
- /usr/local/bin/python /ci-android-mail.py
only:
- dev
- dev-5.32.0
- feature-GHZS-3350
- dev-5.32.0

View File

@ -474,14 +474,6 @@
android:name="com.gh.gamecenter.gamedetail.fuli.kaifu.ServersCalendarActivity"
android:screenOrientation="portrait" />
<activity
android:name=".gamedetail.fuli.kaifu.ServersCalendarManagementActivity"
android:screenOrientation="portrait" />
<activity
android:name=".gamedetail.fuli.kaifu.ServersSubscribedGameListActivity"
android:screenOrientation="portrait" />
<activity
android:name=".qa.answer.draft.AnswerDraftActivity"
android:screenOrientation="portrait" />
@ -761,6 +753,10 @@
android:name="com.gh.gamecenter.qgame.QGameSearchActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qgame.QGameSubjectActivity"
android:screenOrientation="portrait" />
<!-- <activity-->
<!-- android:name="${applicationId}.douyinapi.DouYinEntryActivity"-->

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -61,8 +61,6 @@ import com.gh.gamecenter.gamecollection.hotlist.GameCollectionHotListActivity
import com.gh.gamecenter.gamecollection.square.GameCollectionSquareActivity
import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersCalendarActivity
import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersCalendarManagementActivity
import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersSubscribedGameListActivity
import com.gh.gamecenter.gamedetail.history.HistoryApkListActivity
import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity
import com.gh.gamecenter.help.HelpAndFeedbackBridge
@ -191,8 +189,6 @@ object DirectUtils {
}
}
"game_server_calendar" -> directToGameServerCalendar(context, linkEntity.link)
"column", "游戏专题" -> directToSubject(
context, linkEntity.link
?: "", linkEntity.text, BaseActivity.mergeEntranceAndPath(entrance, path), exposureEvent
@ -231,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!!,
@ -284,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)
@ -314,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)
@ -436,6 +447,7 @@ object DirectUtils {
"" -> {
// do nothing
}
else -> {
if (unknownCallback != null) {
unknownCallback.invoke()
@ -484,6 +496,8 @@ object DirectUtils {
position: Int = -1,
entrance: String,
columnName: String = "",
blockId: String = "",
blockName: String = "",
exposureEvent: ExposureEvent? = null
) {
if (id.isEmpty()) return
@ -492,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)
}
@ -516,13 +532,12 @@ object DirectUtils {
* 跳转至游戏日历表
*/
@JvmStatic
fun directToGameServerCalendar(context: Context, gameId: String?, kaifuTime: Long = 0) {
fun directToGameServerCalendar(context: Context, gameId: String?) {
val bundle = Bundle()
bundle.putString(KEY_TO, ServersCalendarActivity::class.java.name)
bundle.putParcelable(GameEntity::class.java.simpleName, GameEntity().apply {
id = gameId ?: ""
})
bundle.putLong(KEY_KAIFU_TIME, kaifuTime)
bundle.putParcelable(GameDetailServer::class.java.simpleName, GameDetailServer())
bundle.putParcelable(MeEntity::class.java.simpleName, MeEntity())
jumpActivity(context, bundle)
@ -728,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)
@ -2085,24 +2101,4 @@ object DirectUtils {
.withInt(BaseActivity_TabLayout.PAGE_INDEX, defaultTabIndex)
.navigation()
}
/**
* 跳转到游戏订阅页面
* @param context 上下文
*/
@JvmStatic
fun directToServersSubscribedGameList(context: Context) {
context.startActivity(ServersSubscribedGameListActivity.getIntent(context))
}
/**
* 跳转到开服订阅页面
* @param context 上下文
*/
@JvmStatic
fun directToServersCalendarManagement(context: Context, entrance: String) {
CheckLoginUtils.checkLogin(context, entrance) {
context.startActivity(ServersCalendarManagementActivity.getIntent(context))
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -2486,181 +2486,4 @@ object NewLogUtils {
}
log(json, LOG_STORE_EVENT)
}
/**
* 埋点序号118
* 事件IDlaunch_server_subscribe_add
* 事件名称:加入开服订阅事件
* 触发时机:点击开服表加入订阅
* @param gameId 游戏ID
* @param gameName 游戏名称
*/
@JvmStatic
fun logLaunchServerSubscribeAdd(
gameId: String,
gameName: String
) {
val json = json {
KEY_EVENT to "launch_server_subscribe_add"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
parseAndPutMeta().invoke(this)
}
log(json, LOG_STORE_EVENT)
}
/**
* 埋点序号119
* 事件IDlaunch_server_subscribe_cancel
* 事件名称:取消开服订阅事件
* 触发时机:点击开服表取消订阅
* @param gameId 游戏ID
* @param gameName 游戏名称
*/
@JvmStatic
fun logLaunchServerSubscribeCancel(
gameId: String,
gameName: String
) {
val json = json {
KEY_EVENT to "launch_server_subscribe_cancel"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
parseAndPutMeta().invoke(this)
}
log(json, LOG_STORE_EVENT)
}
/**
* 埋点序号120
* 事件IDlaunch_server_subscribe_click
* 事件名称:点击开服订阅事件
* 触发时机:点击开服管理的开服记录
* @param gameId 游戏ID
* @param gameName 游戏名称
* @param launchServerTime 以秒为单位的时间戳,若为日期则是当天0点的时间戳
*/
@JvmStatic
fun logLaunchServerSubscribeClick(
gameId: String,
gameName: String,
launchServerTime: Int
) {
val json = json {
KEY_EVENT to "launch_server_subscribe_click"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
"launch_server_time" to launchServerTime
parseAndPutMeta().invoke(this)
}
log(json, LOG_STORE_EVENT)
}
/**
* 埋点序号121
* 事件IDlaunch_server_reminder_add
* 事件名称:添加开服提醒事件
* 触发时机:点击开服表的添加提醒
* @param gameId 游戏ID
* @param gameName 游戏名称
* @param reminderTime 设置提醒时间: 已知服是上传以秒为单位的时间戳未知服则是当天0点的时间戳
* @param reminderType 提醒类型: 已知服/未知服
* @param launchServerTime 设置开服时间: 已知服是上传以秒为单位的时间戳未知服则是当天0点的时间戳
* @param serverName 服务器名字
* @param isWechat 是否微信提醒
* @param isApp 是否APP提醒
*/
@JvmStatic
fun logLaunchServerReminderAdd(
gameId: String,
gameName: String,
reminderTime: Int,
reminderType: String,
launchServerTime: Int,
serverName: String,
isWechat: Boolean,
isApp: Boolean
) {
val json = json {
KEY_EVENT to "launch_server_reminder_add"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
"reminder_time" to reminderTime
"reminder_type" to reminderType
"launch_server_time" to launchServerTime
"server_name" to serverName
"is_wechat" to isWechat
"is_app" to isApp
parseAndPutMeta().invoke(this)
}
log(json, LOG_STORE_EVENT)
}
/**
* 埋点序号122
* 事件IDlaunch_server_reminder_cancel
* 事件名称:取消开服提醒事件
* 触发时机:点击开服表的取消提醒
* @param gameId 游戏ID
* @param gameName 游戏名称
* @param reminderTime 设置提醒时间: 已知服是上传以秒为单位的时间戳未知服则是当天0点的时间戳
* @param reminderType 提醒类型: 已知服/未知服
* @param launchServerTime 设置开服时间: 已知服是上传以秒为单位的时间戳未知服则是当天0点的时间戳
* @param serverName 服务器名字
* @param isWechat 是否微信提醒
* @param isApp 是否APP提醒
*/
@JvmStatic
fun logLaunchServerReminderCancel(
gameId: String,
gameName: String,
reminderTime: Int,
reminderType: String,
launchServerTime: Int,
serverName: String,
isWechat: Boolean,
isApp: Boolean
) {
val json = json {
KEY_EVENT to "launch_server_reminder_cancel"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
"reminder_time" to reminderTime
"reminder_type" to reminderType
"launch_server_time" to launchServerTime
"server_name" to serverName
"is_wechat" to isWechat
"is_app" to isApp
parseAndPutMeta().invoke(this)
}
log(json, LOG_STORE_EVENT)
}
/**
* 埋点序号123
* 事件IDlaunch_server_reminder_click
* 事件名称:点击开服提醒事件
* 触发时机:点击开服管理的提醒记录
* @param gameId 游戏ID
* @param gameName 游戏名称
* @param reminderTime 设置提醒时间: 已知服是上传以秒为单位的时间戳未知服则是当天0点的时间戳
* @param status 记录状态: todo 待提醒 coming 即将开服 opened 已开服 has_new 有新服 expired 已过期
*/
@JvmStatic
fun logLaunchServerReminderClick(
gameId: String,
gameName: String,
reminderTime: Int,
status: String,
) {
val json = json {
KEY_EVENT to "launch_server_reminder_cancel"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
"reminder_time" to reminderTime
"status" to status
parseAndPutMeta().invoke(this)
}
log(json, LOG_STORE_EVENT)
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,16 +1,15 @@
package com.gh.gamecenter.entity
import android.os.Parcelable
import com.gh.gamecenter.feature.entity.ServerCalendarEntity
import kotlinx.parcelize.Parcelize
/**
* Created by khy on 2017/3/28.
*/
@Parcelize
class CalendarEntity(
var day: Int = 0,
var month: Int = 0,
var year: Int = 0,
class CalendarEntity {
var day: Int = 0
var month: Int = 0
var year: Int = 0
var server: MutableList<ServerCalendarEntity> = ArrayList()
) : Parcelable
}

View File

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

View File

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

View File

@ -1,10 +0,0 @@
package com.gh.gamecenter.entity
import com.google.gson.annotations.SerializedName
class ServerSubscriptionEntity(
@SerializedName("by_app")
val byApp: Boolean = false,
@SerializedName("by_wechat")
val byWeChat: Boolean = false
)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -37,7 +37,6 @@ import com.gh.gamecenter.common.base.fragment.BaseLazyFragment;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.constant.EntranceConsts;
import com.gh.gamecenter.common.eventbus.EBReuse;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.iinterface.SearchBarHint;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.core.utils.MtaHelper;
@ -327,7 +326,7 @@ public class SearchToolbarFragment extends BaseLazyFragment implements View.OnCl
CheckLoginUtils.checkLogin(requireContext(), "(工具栏)", () -> {
NewLogUtils.logMessageInformBellClick(mMessageUnread.getVisibility() == View.VISIBLE, mLocation);
SensorsBridge.trackMessageCenterClick();
// 优先进入有数字提醒的消息tab其次是有红点提醒的游戏动态最后是没有提醒的消息tab
int defaultTabIndex = 1;
MessageUnreadCount messageUnreadCount = mUnreadViewModel.getMessageUnreadCountLiveData().getValue();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1179,8 +1179,12 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
if (!isVisible) return
MtaHelper.onEvent("游戏详情_新", "标签展开", mViewModel.game?.name ?: "")
GameTagsDialog.showGameTagsDialog(
requireActivity(), mNewGameDetailEntity?.tagStyle!!, mGameEntity?.id
?: "", mGameEntity?.name ?: ""
requireActivity(),
mNewGameDetailEntity?.tagStyle!!,
mGameEntity?.id ?: "",
mGameEntity?.name ?: "",
mGameEntity?.downloadStatusChinese ?: "",
mGameEntity?.categoryChinese ?: ""
)
}
@ -1204,7 +1208,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
downloadStatus = mGameEntity?.downloadStatusChinese ?: "",
gameType = mGameEntity?.categoryChinese ?: "",
position = position,
gameTag = tag.name,
gameTag = listOf(tag.name),
gameTagId = tag.id,
)
MtaHelper.onEvent("游戏详情_新", "点击标签", mViewModel.game?.name ?: "")
@ -1273,7 +1277,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
requireContext(),
ranking.collectionId,
entrance = mEntrance,
columnName = ranking.columnName
columnName = ranking.columnName,
)
}
}
@ -1641,7 +1645,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
true
)
updateConcernMenuIcon(mNewGameDetailEntity?.me?.isGameConcerned ?: false)
mMoreMenuItem?.setIcon(if (!mIsDarkModeOn && isToolbarWhite) R.drawable.ic_menu_more else R.drawable.ic_menu_more_light)
mMoreMenuItem?.setIcon(if (!mIsDarkModeOn && isToolbarWhite) R.drawable.ic_menu_gamedetail_more else R.drawable.ic_menu_gamedetail_more_light)
mSearchMenuItem?.setIcon(if (!mIsDarkModeOn && isToolbarWhite) R.drawable.ic_column_search else R.drawable.ic_column_search_light)
mDownloadMenuIcon?.setImageResource(if (!mIsDarkModeOn && isToolbarWhite) R.drawable.toolbar_download else R.drawable.toolbar_download_light)
DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn && isToolbarWhite)
@ -2418,20 +2422,6 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
else -> "下载"
}
NewFlatLogUtils.logHaloFunGameDetailJumpClick(downloadStatus, simpleGame.id ?: "")
SensorsBridge.trackGameDetailPageRelatedGameClick(
gameId = gameEntity.id,
gameName = gameEntity.name ?: "",
pageName = getCurrentPageEntity().pageName,
pageId = getCurrentPageEntity().pageId,
pageBusinessId = getCurrentPageEntity().pageBusinessId,
lastPageName = getLastPageEntity().pageName,
lastPageId = getLastPageEntity().pageId,
lastPageBusinessId = getLastPageEntity().pageBusinessId,
downloadStatus = downloadStatus,
gameType = gameEntity.categoryChinese,
clickGameId = simpleGame.id ?: "",
clickGameName = simpleGame.name ?: ""
)
DirectUtils.directToGameDetail(requireContext(), it.id ?: "", entrance = mEntrance)
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,33 +5,36 @@ import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.Paint
import android.os.Bundle
import android.text.TextUtils
import android.view.Gravity
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.GridLayoutManager
import com.gh.common.util.CheckLoginUtils
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.activity.ToolBarActivity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.exposure.meta.MetaUtil.refreshMeta
import com.gh.gamecenter.common.entity.SuggestType
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.databinding.ActivityServersCalendarBinding
import com.gh.gamecenter.databinding.DialogServersCalendearDetailItemBinding
import com.gh.gamecenter.entity.CalendarEntity
import com.gh.gamecenter.feature.entity.GameDetailServer
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.MeEntity
import com.gh.gamecenter.feature.entity.ServerCalendarEntity
import com.gh.gamecenter.help.HelpAndFeedbackBridge
import com.gh.gamecenter.servers.add.AddKaiFuActivity
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.halo.assistant.HaloApp
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import com.lightgame.adapter.BaseRecyclerAdapter
import java.text.SimpleDateFormat
import java.util.*
@ -43,13 +46,6 @@ class ServersCalendarActivity : ToolBarActivity() {
NewLogUtils.logGameDetailOpenCalendarView(mViewModel.game.name ?: "", mViewModel.game.id)
}
private val mMoreDialog by lazy { ServersCalendarMoreDialog() }
private val mWeChatSubscriptionSuccessDialog by lazy { ServersCalendarWeChatSubscriptionSuccessDialog() }
private val mSubscriptionSuccessDialog by lazy { ServersCalendarSubscriptionSuccessDialog() }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
val serverCalendars = mViewModel.serverCalendarLiveData.value ?: return
@ -110,8 +106,6 @@ class ServersCalendarActivity : ToolBarActivity() {
val factory = ServersCalendarViewModel.Factory(HaloApp.getInstance().application, game, serverList, meEntity)
mViewModel = ViewModelProviders.of(this, factory).get(ServersCalendarViewModel::class.java)
mViewModel.setKaifuTime(intent.getLongExtra(EntranceConsts.KEY_KAIFU_TIME, 0))
mViewModel.calendarLiveData.observeNonNull(this, callback = {
val adapter = ServersCalendarAdapter(this, mViewModel, it)
mBinding.recyclerView.isNestedScrollingEnabled = false
@ -119,7 +113,7 @@ class ServersCalendarActivity : ToolBarActivity() {
mBinding.recyclerView.adapter = adapter
})
mViewModel.serversDetailLiveData.observeNonNull(this, callback = {
showServersCalendarDetailDialog(it)
showServersDetailDialog(it)
NewLogUtils.logGameDetailOpenCalendarClick(mViewModel.game.name ?: "", mViewModel.game.id)
})
mViewModel.serverCalendarLiveData.observe(this) {
@ -131,49 +125,6 @@ class ServersCalendarActivity : ToolBarActivity() {
mBinding.includeNoConnection.root.visibility = View.VISIBLE
}
}
mViewModel.serverSubscriptionLiveData.observe(this) {
// 用户订阅状态
if (it?.byApp == true) {// 用户已登录并处于已订阅状态
clearMenu()
setToolbarMenu(R.menu.menu_server_calendar_more)
mBinding.subscribe.visibility = View.GONE
mBinding.subscribeHint1.visibility = View.GONE
mBinding.subscribeHint2.visibility = View.GONE
mBinding.subscribe.setOnClickListener(null)
} else {// 用户已登录并处于未订阅状态
clearMenu()
mBinding.subscribe.visibility = View.VISIBLE
mBinding.subscribeHint1.visibility = View.VISIBLE
mBinding.subscribeHint2.visibility = View.VISIBLE
mBinding.subscribe.setOnClickListener {
CheckLoginUtils.checkLogin(this, "游戏详情-开服日历表-开启订阅") {
mViewModel.subscribeServer()
NewLogUtils.logLaunchServerSubscribeAdd(
gameId = mViewModel.game.id,
gameName = mViewModel.game.name ?: ""
)
SensorsBridge.trackLaunchServerSubscribeClick(
gameId = mViewModel.game.id,
gameName = mViewModel.game.name ?: ""
)
}
}
}
}
mViewModel.subscribeServerSuccessEvent.observe(this) {
val serverSubscription = mViewModel.serverSubscriptionLiveData.value
if (serverSubscription?.byWeChat != true && !mWeChatSubscriptionSuccessDialog.isAdded) {// 开启微信提醒弹窗
mWeChatSubscriptionSuccessDialog.showNow(
supportFragmentManager,
SERVERS_CALENDAR_WECHAT_SUBSCRIPTION_DIALOG_TAG
)
} else if (!mSubscriptionSuccessDialog.isAdded) {// 开启订阅成功提醒弹窗
mSubscriptionSuccessDialog.showNow(
supportFragmentManager,
SERVERS_CALENDAR_SUBSCRIPTION_DIALOG_TAG
)
}
}
mBaseHandler.postDelayed(mDelayLogRunnable, 3000)
}
@ -182,15 +133,6 @@ class ServersCalendarActivity : ToolBarActivity() {
mBaseHandler.removeCallbacks(mDelayLogRunnable)
}
override fun onMenuItemClick(item: MenuItem?): Boolean {
if (item?.itemId == R.id.menu_more) {
if (!mMoreDialog.isAdded) {
mMoreDialog.showNow(supportFragmentManager, SERVERS_CALENDAR_MORE_DIALOG_TAG)
}
}
return super.onMenuItemClick(item)
}
fun initView() {
mBinding.contentContainer.visibility = View.VISIBLE
mBinding.includeLoading.root.visibility = View.GONE
@ -334,52 +276,129 @@ class ServersCalendarActivity : ToolBarActivity() {
}
private fun showServersCalendarDetailDialog(calendarEntity: CalendarEntity) {
val subscriptionStatus = mViewModel.serverSubscriptionLiveData.value
val currentCalendar = Calendar.getInstance().apply {
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}
val serverCalendar = Calendar.getInstance().apply {
set(calendarEntity.year, calendarEntity.month - 1, calendarEntity.day, 0, 0, 0)
}
private fun showServersDetailDialog(calendarEntity: CalendarEntity) {
val contentView = LayoutInflater.from(this).inflate(R.layout.dialog_servers_calendear_detail, null)
val params = ViewGroup.LayoutParams(resources.displayMetrics.widthPixels, ViewGroup.LayoutParams.WRAP_CONTENT)
val dialog = Dialog(this, R.style.DialogWindowTransparent)
val window = dialog.window
window?.setGravity(Gravity.BOTTOM)
window?.setWindowAnimations(R.style.community_publication_animation)
dialog.setContentView(contentView, params)
dialog.show()
// 开服表详情是否显示提醒按钮,条件如下:
// 2. 当前开服表日期大于当天日期
val isRemindFeatureSupported = serverCalendar >= currentCalendar
val calendarHint = contentView.findViewById<TextView>(R.id.calendar_hint)
calendarHint.text = (calendarEntity.server.first().getFormatTime("MM-dd") + "详细开服")
if (!isRemindFeatureSupported && calendarEntity.server.isEmpty()) {
// 小于当前时间的未知服不显示弹窗
return
}
val dialog = if (calendarEntity.server.isEmpty()) {
ServersCalendarDetailNoDataDialog().apply {
arguments = Bundle().apply {
putInt(EntranceConsts.KEY_CALENDAR_YEAR, calendarEntity.year)
putInt(EntranceConsts.KEY_CALENDAR_MONTH, calendarEntity.month)
putInt(EntranceConsts.KEY_CALENDAR_DAY, calendarEntity.day)
}
}
val addBtn = contentView.findViewById<View>(R.id.add)
if (mViewModel.meEntity?.isPartTime == true) {
addBtn.visibility = View.INVISIBLE
} else {
ServersCalendarDetailDialog().apply {
arguments = Bundle().apply {
putInt(EntranceConsts.KEY_CALENDAR_YEAR, calendarEntity.year)
putInt(EntranceConsts.KEY_CALENDAR_MONTH, calendarEntity.month)
putInt(EntranceConsts.KEY_CALENDAR_DAY, calendarEntity.day)
putBoolean(EntranceConsts.KEY_SHOW_REMIND, isRemindFeatureSupported)
addBtn.visibility = View.GONE
}
val feedback = contentView.findViewById<TextView>(R.id.feedback)
feedback.paint.flags = Paint.UNDERLINE_TEXT_FLAG
feedback.paint.isAntiAlias = true
if (mViewModel.meEntity?.isPartTime == true) {
feedback.text = "新增"
} else {
feedback.text = "意见反馈"
}
feedback.setOnClickListener {
if (mViewModel.meEntity?.isPartTime == true) {
startActivityForResult(
AddKaiFuActivity.getIntent(
this,
mViewModel.serverCalendarLiveData.value!!.last(),
mViewModel.serverCalendarLiveData.value as ArrayList<ServerCalendarEntity>,
mViewModel.game.id, calendarEntity.server.first().getTime() * 1000
), GAME_DETAIL_ADD_KAIFU_REQUEST
)
} else {
dialog.dismiss()
showServersDetailReportDialog(calendarEntity)
}
}
contentView.findViewById<View>(R.id.close).setOnClickListener {
dialog.dismiss()
}
val recyclerView = contentView.findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = object : BaseRecyclerAdapter<ServersDetailViewHolder>(this) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ServersDetailViewHolder {
val view = mLayoutInflater.inflate(R.layout.dialog_servers_calendear_detail_item, parent, false)
return ServersDetailViewHolder(DialogServersCalendearDetailItemBinding.bind(view))
}
override fun getItemCount(): Int {
return calendarEntity.server.size
}
override fun onBindViewHolder(holder: ServersDetailViewHolder, position: Int) {
val data = calendarEntity.server[position]
holder.bindItem(data, mViewModel.meEntity, mViewModel.game)
if (mViewModel.meEntity?.isPartTime == true) {
holder.binding.add.visibility = View.VISIBLE
} else {
holder.binding.add.visibility = View.GONE
}
holder.binding.add.setOnClickListener {
startActivityForResult(
AddKaiFuActivity.getIntent(
this@ServersCalendarActivity,
data,
mViewModel.serverCalendarLiveData.value as ArrayList<ServerCalendarEntity>,
mViewModel.game.id,
mViewModel.getSelectTime(calendarEntity.day, calendarEntity.month, calendarEntity.year)
), ServersCalendarActivity.GAME_DETAIL_ADD_KAIFU_REQUEST
)
}
if (itemCount == position + 1) {
holder.itemView.setPadding(0, 10F.dip2px(), 0, 19F.dip2px())
} else {
holder.itemView.setPadding(0, 10F.dip2px(), 0, 10F.dip2px())
}
}
}
dialog.showNow(supportFragmentManager, null)
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(reuse: EBReuse) {
if (reuse.type == Constants.LOGIN_TAG || reuse.type == Constants.LOGOUT_TAG) {
mViewModel.loadServerData()
private fun showServersDetailReportDialog(calendarEntity: CalendarEntity) {
val contentView = LayoutInflater.from(this).inflate(R.layout.dialog_servers_calendear_detail_report, null)
val params = ViewGroup.LayoutParams(resources.displayMetrics.widthPixels, ViewGroup.LayoutParams.WRAP_CONTENT)
val dialog = BottomSheetDialog(this, R.style.DialogWindowTransparent)
val window = dialog.window
window?.setGravity(Gravity.BOTTOM)
window?.setWindowAnimations(R.style.community_publication_animation)
dialog.setContentView(contentView, params)
dialog.show()
val recyclerView = contentView.findViewById<RecyclerView>(R.id.recycler_view)
val adapter = ServersDetailReportAdapter(this, calendarEntity.server)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = adapter
contentView.findViewById<TextView>(R.id.submit).setOnClickListener {
val builder = StringBuilder()
val serverCalendarList = adapter.selectedServerCalendarList
serverCalendarList.forEachIndexed { index, entity ->
if (index != 0) builder.append("")
builder.append("${entity.getFormatTime("YYYY年MM月dd日")}开服信息有误:${entity.getNote()}")
}
HelpAndFeedbackBridge.startSuggestionActivity(
this,
SuggestType.GAME,
"service",
builder.toString()
)
dialog.dismiss()
}
contentView.findViewById<View>(R.id.close).setOnClickListener {
dialog.dismiss()
}
}
@ -404,10 +423,6 @@ class ServersCalendarActivity : ToolBarActivity() {
const val GAME_DETAIL_ADD_KAIFU_KEY = "GAME_DETAIL_ADD_KAIFU_KEY"
const val GAME_DETAIL_PATCH_KAIFU_KEY = "GAME_DETAIL_PATCH_KAIFU_KEY"
const val SERVERS_CALENDAR_MORE_DIALOG_TAG = "ServersCalendarMoreDialog"
const val SERVERS_CALENDAR_WECHAT_SUBSCRIPTION_DIALOG_TAG = "ServersCalendarWeChatSubscriptionDialog"
const val SERVERS_CALENDAR_SUBSCRIPTION_DIALOG_TAG = "ServersCalendarSubscriptionDialog"
fun getIntent(context: Context, game: GameEntity, gameServer: GameDetailServer, me: MeEntity?): Intent {
val intent = Intent(context, ServersCalendarActivity::class.java)
intent.putExtra(GameEntity::class.java.simpleName, game)

View File

@ -119,8 +119,6 @@ class ServersCalendarAdapter(
),
ServersCalendarActivity.GAME_DETAIL_ADD_KAIFU_REQUEST
)
} else {
viewModel.serversDetailLiveData.postValue(entity)
}
} else {
MtaHelper.onEvent("开服日历表", "详情", "${viewModel.game.name}+${holder.binding.calendarKaifu.text}")

View File

@ -1,18 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
enum class ServersCalendarAdvancedTime(val value: Int, val text: String) {
IN_TIME(0, "准时提醒"),
FIVE_MINUTES_IN_ADVANCE(300, "提前5分钟"),
FIFTEEN_MINUTES_IN_ADVANCE(900, "提前15分钟"),
THIRTY_MINUTES_IN_ADVANCE(1800, "提前30分钟");
companion object {
fun valueOf(value: Int?): ServersCalendarAdvancedTime {
if (value == null) return IN_TIME
return ServersCalendarAdvancedTime.values().firstOrNull {
it.value == value
} ?: IN_TIME
}
}
}

View File

@ -1,149 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.app.Activity
import android.graphics.Paint
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import com.gh.common.util.CheckLoginUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.layoutInflater
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.databinding.DialogServersCalendearDetailItemBinding
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.MeEntity
import com.gh.gamecenter.feature.entity.ServerCalendarEntity
import com.gh.gamecenter.servers.add.AddKaiFuActivity
import com.gh.gamecenter.servers.patch.PatchKaifuActivity
import com.lightgame.utils.Utils
import java.util.*
class ServersCalendarDetailAdapter(
private val fragment: Fragment,
private val viewModel: ServersCalendarDetailViewModel,
private val parentViewModel: ServersCalendarViewModel
) :
ListAdapter<ServerCalendarEntity, ServersCalendarDetailAdapter.ServersCalendarDetailViewHolder>(COMPARATOR) {
companion object {
private val COMPARATOR = object : DiffUtil.ItemCallback<ServerCalendarEntity>() {
override fun areItemsTheSame(oldItem: ServerCalendarEntity, newItem: ServerCalendarEntity): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: ServerCalendarEntity, newItem: ServerCalendarEntity): Boolean {
return oldItem.id == newItem.id
&& oldItem.getFirstName() == newItem.getFirstName()
&& oldItem.getServerName() == newItem.getServerName()
&& oldItem.getNote() == newItem.getNote()
&& oldItem.getTime() == newItem.getTime()
&& oldItem.remark == newItem.remark
&& oldItem.type == newItem.type
&& oldItem.notifySetting?.notifyTime == newItem.notifySetting?.notifyTime
&& oldItem.notifySetting?.secondsAdvance == newItem.notifySetting?.secondsAdvance
&& oldItem.notifySetting?.byApp == newItem.notifySetting?.byApp
&& oldItem.notifySetting?.byWechat == newItem.notifySetting?.byWechat
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ServersCalendarDetailViewHolder {
return ServersCalendarDetailViewHolder(
DialogServersCalendearDetailItemBinding.inflate(
parent.layoutInflater,
parent,
false
)
)
}
override fun onBindViewHolder(holder: ServersCalendarDetailViewHolder, position: Int) {
val data = getItem(position)
holder.bindItem(data, parentViewModel.meEntity, parentViewModel.game)
if (parentViewModel.meEntity?.isPartTime == true) {
holder.binding.add.visibility = View.VISIBLE
} else {
holder.binding.add.visibility = View.GONE
}
holder.binding.add.setOnClickListener {
fragment.startActivityForResult(
AddKaiFuActivity.getIntent(
it.context,
data,
parentViewModel.serverCalendarLiveData.value as ArrayList<ServerCalendarEntity>,
parentViewModel.game.id,
parentViewModel.getSelectTime(
viewModel.year,
viewModel.month,
viewModel.day
)
), ServersCalendarActivity.GAME_DETAIL_ADD_KAIFU_REQUEST
)
}
holder.itemView.layoutParams = (holder.itemView.layoutParams as ViewGroup.MarginLayoutParams).apply {
bottomMargin = if (itemCount == position + 1) 7F.dip2px() else 0
}
holder.binding.remindTitle.visibility = View.GONE
holder.binding.remind.visibility = if (viewModel.showRemind) View.VISIBLE else View.GONE
holder.binding.remind.isSelected = data.notifySetting != null
holder.binding.remind.setOnClickListener {
CheckLoginUtils.checkLogin(it.context, "游戏详情-开服日历表-开服详情-开服提醒") {
ServersCalendarDetailsRemindDialog().apply {
arguments = Bundle().apply {
putString(EntranceConsts.KEY_SERVER_CALENDAR_ID, data.id)
}
showNow(fragment.childFragmentManager, null)
}
}
}
}
class ServersCalendarDetailViewHolder(val binding: DialogServersCalendearDetailItemBinding) :
BaseRecyclerViewHolder<Any>(binding.root) {
fun bindItem(data: ServerCalendarEntity, meEntity: MeEntity?, gameEntity: GameEntity) {
binding.name.text = data.getNote()
binding.time.text = data.getFormatTime("HH:mm")
binding.remark.text = data.remark
binding.name.setTextColor(R.color.text_title.toColor(binding.root.context))
binding.time.setTextColor(R.color.text_title.toColor(binding.root.context))
binding.remark.setTextColor(R.color.text_title.toColor(binding.root.context))
if (meEntity?.isPartTime == true) {
binding.name.paint.flags = Paint.UNDERLINE_TEXT_FLAG
binding.name.paint.isAntiAlias = true
binding.name.setOnClickListener {
val context = binding.root.context
if ("删档内测" == data.type || "不删档内测" == data.type || "公测" == data.type) {
Utils.toast(context, "开测信息不可编辑");
} else {
(context as Activity).startActivityForResult(
PatchKaifuActivity.getIntent(
context,
data,
gameEntity.id
),
ServersCalendarActivity.GAME_DETAIL_PATCH_KAIFU_REQUEST
)
}
}
}
}
}
}

View File

@ -1,168 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.app.Dialog
import android.graphics.Paint
import android.os.Bundle
import android.view.*
import android.widget.TextView
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.entity.SuggestType
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.databinding.DialogServersCalendearDetailBinding
import com.gh.gamecenter.databinding.DialogServersCalendearDetailItemBinding
import com.gh.gamecenter.databinding.LayoutServersCalendarDetailListBinding
import com.gh.gamecenter.entity.CalendarEntity
import com.gh.gamecenter.feature.entity.ServerCalendarEntity
import com.gh.gamecenter.help.HelpAndFeedbackBridge
import com.gh.gamecenter.servers.add.AddKaiFuActivity
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.lightgame.adapter.BaseRecyclerAdapter
import java.text.SimpleDateFormat
import java.util.*
/**
* 游戏开服-开服表详情弹窗
*/
class ServersCalendarDetailDialog : DialogFragment() {
private lateinit var detailViewBinding: DialogServersCalendearDetailBinding
private lateinit var listViewBinding: LayoutServersCalendarDetailListBinding
private val titleFormat = SimpleDateFormat("MM-dd", Locale.CHINA)
private val parentViewModel by activityViewModels<ServersCalendarViewModel>()
private lateinit var viewModel: ServersCalendarDetailViewModel
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return super.onCreateDialog(savedInstanceState).apply {
window?.setWindowAnimations(R.style.community_publication_animation)
window?.setGravity(Gravity.BOTTOM)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, R.style.DialogWindowTransparent)
viewModel = viewModelProvider(
ServersCalendarDetailViewModel.Factory(
source = parentViewModel.calendarLiveData,
year = requireArguments().getInt(EntranceConsts.KEY_CALENDAR_YEAR, 0),
month = requireArguments().getInt(EntranceConsts.KEY_CALENDAR_MONTH, 0),
day = requireArguments().getInt(EntranceConsts.KEY_CALENDAR_DAY, 0),
showRemind = requireArguments().getBoolean(EntranceConsts.KEY_SHOW_REMIND, false)
)
)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return DialogServersCalendearDetailBinding.inflate(inflater, container, false)
.also {
detailViewBinding = it.apply {
content.layoutResource = R.layout.layout_servers_calendar_detail_list
listViewBinding = LayoutServersCalendarDetailListBinding.bind(content.inflate())
}
}.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// 在这里加这句代码,才能保证弹窗宽度占满屏幕
// 如果在弹窗的Theme里面加<item name="android:windowIsFloating">false</item>,那么这句代码可以去掉
dialog?.window?.setLayout(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT
)
val isPartTime = parentViewModel.meEntity?.isPartTime == true
listViewBinding.titleInclude.add.visibility = if (isPartTime) View.VISIBLE else View.GONE
listViewBinding.titleInclude.remindTitle.visibility = if (viewModel.showRemind) View.VISIBLE else View.GONE
detailViewBinding.close.setOnClickListener { dismissAllowingStateLoss() }
detailViewBinding.feedback.paint.flags = Paint.UNDERLINE_TEXT_FLAG
detailViewBinding.feedback.paint.isAntiAlias = true
detailViewBinding.feedback.text = if (isPartTime) "新增" else "意见反馈"
detailViewBinding.feedback.setOnClickListener {
val calendarEntity = viewModel.calendarEntityLiveData.value ?: return@setOnClickListener
if (isPartTime) {
startActivityForResult(
AddKaiFuActivity.getIntent(
it.context,
parentViewModel.serverCalendarLiveData.value!!.last(),
parentViewModel.serverCalendarLiveData.value as ArrayList<ServerCalendarEntity>,
parentViewModel.game.id, calendarEntity.server.first().getTime() * 1000
), ServersCalendarActivity.GAME_DETAIL_ADD_KAIFU_REQUEST
)
} else {
showServersDetailReportDialog(calendarEntity)
dismissAllowingStateLoss()
}
}
val adapter = ServersCalendarDetailAdapter(this@ServersCalendarDetailDialog, viewModel, parentViewModel)
listViewBinding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
listViewBinding.recyclerView.adapter = adapter
viewModel.calendarEntityLiveData.observe(viewLifecycleOwner) { calendarEntity ->
calendarEntity?.let {
val calendar = Calendar.getInstance().apply {
set(it.year, it.month - 1, it.day)
}
detailViewBinding.calendarHint.text = "${titleFormat.format(calendar.time)}详细开服"
adapter.submitList(calendarEntity.server)
}
}
}
private fun showServersDetailReportDialog(calendarEntity: CalendarEntity) {
val contentView =
LayoutInflater.from(requireContext()).inflate(R.layout.dialog_servers_calendear_detail_report, null)
val params = ViewGroup.LayoutParams(resources.displayMetrics.widthPixels, ViewGroup.LayoutParams.WRAP_CONTENT)
val dialog = BottomSheetDialog(requireContext(), R.style.DialogWindowTransparent)
val window = dialog.window
window?.setGravity(Gravity.BOTTOM)
window?.setWindowAnimations(R.style.community_publication_animation)
dialog.setContentView(contentView, params)
dialog.show()
val recyclerView = contentView.findViewById<RecyclerView>(R.id.recycler_view)
val adapter = ServersCalendarDetailReportAdapter(requireContext(), calendarEntity.server)
recyclerView.layoutManager = LinearLayoutManager(requireContext())
recyclerView.adapter = adapter
contentView.findViewById<TextView>(R.id.submit).setOnClickListener {
val builder = StringBuilder()
val serverCalendarList = adapter.selectedServerCalendarList
serverCalendarList.forEachIndexed { index, entity ->
if (index != 0) builder.append("")
builder.append("${entity.getFormatTime("YYYY年MM月dd日")}开服信息有误:${entity.getNote()}")
}
HelpAndFeedbackBridge.startSuggestionActivity(
it.context,
SuggestType.GAME,
"service",
builder.toString()
)
dialog.dismiss()
}
contentView.findViewById<View>(R.id.close).setOnClickListener {
dialog.dismiss()
}
}
}

View File

@ -1,263 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.app.Dialog
import android.graphics.Paint
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.activityViewModels
import com.gh.common.constant.Config
import com.gh.common.util.CheckLoginUtils
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.entity.SuggestType
import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.WXAPIProxyFactory
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.common.view.DrawableView
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.databinding.DialogServersCalendearDetailBinding
import com.gh.gamecenter.databinding.LayoutServersCalendarDetailNoDataBinding
import com.gh.gamecenter.feature.entity.ServerCalendarNotifySetting
import com.gh.gamecenter.help.HelpAndFeedbackBridge
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.tencent.mm.opensdk.modelbase.BaseResp
import com.tencent.mm.opensdk.modelbiz.SubscribeMessage
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.text.SimpleDateFormat
import java.util.*
/**
* 游戏开服-未知服详情弹窗
*/
class ServersCalendarDetailNoDataDialog : BottomSheetDialogFragment() {
private val titleFormat = SimpleDateFormat("MM-dd", Locale.CHINA)
private lateinit var detailViewBinding: DialogServersCalendearDetailBinding
private lateinit var noDataViewBinding: LayoutServersCalendarDetailNoDataBinding
private val parentViewModel by activityViewModels<ServersCalendarViewModel>()
private lateinit var viewModel: ServersCalendarDetailNoDataViewModel
private lateinit var wxApi: WXAPIProxyFactory.WXAPIProxy<SubscribeMessage.Req, SubscribeMessage.Resp>
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return super.onCreateDialog(savedInstanceState).apply {
window?.setWindowAnimations(R.style.community_publication_animation)
window?.setGravity(Gravity.BOTTOM)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
EventBus.getDefault().register(this)
setStyle(DialogFragment.STYLE_NO_TITLE, R.style.DialogWindowTransparent)
Calendar.getInstance().apply {
set(
requireArguments().getInt(EntranceConsts.KEY_CALENDAR_YEAR, 0),
requireArguments().getInt(EntranceConsts.KEY_CALENDAR_MONTH, 0) - 1,
requireArguments().getInt(EntranceConsts.KEY_CALENDAR_DAY, 0),
0, 0, 0
)
set(Calendar.MILLISECOND, 0)
viewModel = viewModelProvider(ServersCalendarDetailNoDataViewModel.Factory(timeInMillis))
}
wxApi = WXAPIProxyFactory.createWXAPI(
requireContext(),
Config.WECHAT_APPID,
object: WXAPIProxyFactory.WXHandler<SubscribeMessage.Req, SubscribeMessage.Resp> {
private val reserved = System.currentTimeMillis().toString()
override fun handleOnReq(req: SubscribeMessage.Req) {
req.reserved = reserved
}
override fun handleOnResp(resp: BaseResp): SubscribeMessage.Resp? {
if (resp is SubscribeMessage.Resp && reserved == resp.reserved) {
return resp
}
return null
}
}
)
}
override fun onDestroy() {
super.onDestroy()
EventBus.getDefault().unregister(this)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return DialogServersCalendearDetailBinding.inflate(inflater, container, false)
.also {
detailViewBinding = it.apply {
content.layoutResource = R.layout.layout_servers_calendar_detail_no_data
noDataViewBinding = LayoutServersCalendarDetailNoDataBinding.bind(content.inflate())
}
}.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
detailViewBinding.calendarHint.text = "${titleFormat.format(viewModel.serverTimeInMills)}详细开服"
detailViewBinding.feedback.paint.flags = Paint.UNDERLINE_TEXT_FLAG
detailViewBinding.feedback.paint.isAntiAlias = true
detailViewBinding.feedback.text = "意见反馈"
detailViewBinding.feedback.setOnClickListener {
HelpAndFeedbackBridge.startSuggestionActivity(
it.context,
SuggestType.GAME,
"service"
)
}
detailViewBinding.close.setOnClickListener {
dismissAllowingStateLoss()
}
noDataViewBinding.appRemindCheckIv.setImageDrawable(DrawableView.getCheckSelectorDrawable(requireContext()))
noDataViewBinding.wechatRemindCheckIv.setImageDrawable(DrawableView.getCheckSelectorDrawable(requireContext()))
viewModel.getServerCalenderRemind(parentViewModel.game.id)
viewModel.serverCalendarRemindLiveData.observe(viewLifecycleOwner) {
bindNoDataView(it)
}
viewModel.wxSubscribeMsgConfigLiveData.observe(viewLifecycleOwner) {
wxApi.sendReq(
SubscribeMessage.Req().apply {
scene = it.scene
templateID = it.templateId
reserved = it.reserved
}
)
}
wxApi.liveData.observe(viewLifecycleOwner) {
if (it.action == "confirm") {
viewModel.addServerCalendarRemindWithWechat(
gameId = parentViewModel.game.id,
openId = it.openId,
templateId = it.templateID,
action = it.action,
reserved = it.reserved,
scene = it.scene
)
}
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(reuse: EBReuse) {
if (reuse.type == Constants.LOGIN_TAG || reuse.type == Constants.LOGOUT_TAG) {
viewModel.getServerCalenderRemind(parentViewModel.game.id)
}
}
private fun bindNoDataView(notifySetting: ServerCalendarNotifySetting?) {
viewModel.initData(notifySetting)
noDataViewBinding.run {
appRemindCheckIv.isChecked = viewModel.appRemind
wechatRemindCheckIv.isChecked = viewModel.wechatRemind
if (notifySetting != null) {
appRemind.isEnabled = false
appRemind.alpha = 0.4F
appRemind.setOnClickListener(null)
wechatRemind.isEnabled = false
wechatRemind.alpha = 0.4F
wechatRemind.setOnClickListener(null)
addOrCancelRemind.text = getString(R.string.servers_detail_cancel_remind)
addOrCancelRemind.background =
ContextCompat.getDrawable(requireContext(), R.drawable.bg_servers_detail_cancel_remind)
addOrCancelRemind.setTextColor(
ContextCompat.getColor(
requireContext(),
R.color.text_subtitle
)
)
addOrCancelRemind.setOnClickListener {
CheckLoginUtils.checkLogin(it.context, "游戏详情-开服日历表-未知服详情") {
viewModel.removeServerCalendarRemind(parentViewModel.game.id)
NewLogUtils.logLaunchServerReminderCancel(
gameId = parentViewModel.game.id,
gameName = parentViewModel.game.name ?: "",
reminderTime = viewModel.timeInSeconds,
reminderType = "未知服",
serverName = "",
launchServerTime = viewModel.timeInSeconds,
isApp = viewModel.appRemind,
isWechat = viewModel.wechatRemind
)
SensorsBridge.trackLaunchServerReminderCancelClick(
gameId = parentViewModel.game.id,
gameName = parentViewModel.game.name ?: "",
reminderType = "未知服",
)
}
}
} else {
appRemind.isEnabled = true
appRemind.alpha = 1.0F
appRemind.setOnClickListener {
appRemindCheckIv.isChecked = !appRemindCheckIv.isChecked
viewModel.appRemind = appRemindCheckIv.isChecked
SPUtils.setBoolean(Constants.SP_SERVERS_CALENDAR_BY_APP, appRemindCheckIv.isChecked)
}
wechatRemind.isEnabled = true
wechatRemind.alpha = 1.0F
wechatRemind.setOnClickListener {
wechatRemindCheckIv.isChecked = !wechatRemindCheckIv.isChecked
viewModel.wechatRemind = wechatRemindCheckIv.isChecked
SPUtils.setBoolean(Constants.SP_SERVERS_CALENDAR_BY_WECHAT, wechatRemindCheckIv.isChecked)
}
addOrCancelRemind.text = getString(R.string.servers_detail_add_remind)
addOrCancelRemind.setTextColor(ContextCompat.getColor(requireContext(), R.color.white))
addOrCancelRemind.background =
ContextCompat.getDrawable(requireContext(), R.drawable.download_button_normal_style)
addOrCancelRemind.setOnClickListener {
CheckLoginUtils.checkLogin(it.context, "游戏详情-开服日历表-未知服详情") {
NewLogUtils.logLaunchServerReminderAdd(
gameId = parentViewModel.game.id,
gameName = parentViewModel.game.name ?: "",
reminderTime = viewModel.timeInSeconds,
reminderType = "未知服",
serverName = "",
launchServerTime = viewModel.timeInSeconds,
isApp = viewModel.appRemind,
isWechat = viewModel.wechatRemind
)
SensorsBridge.trackLaunchServerReminderClick(
gameId = parentViewModel.game.id,
gameName = parentViewModel.game.name ?: "",
reminderType = "未知服",
)
}
if (viewModel.wechatRemind) {// 勾选微信订阅后需要微信授权一次性订阅消息
viewModel.getWXSubscribeMsgConfig()
} else {
viewModel.addServerCalendarRemind(parentViewModel.game.id)
}
}
}
}
}
}

View File

@ -1,131 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.annotation.SuppressLint
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.common.util.CheckLoginUtils
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.toRequestBody
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.UrlFilterUtils
import com.gh.gamecenter.feature.entity.ServerCalendarNotifySetting
import com.gh.gamecenter.feature.entity.WXSubscribeMsgConfig
import com.gh.gamecenter.retrofit.RetrofitManager
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
class ServersCalendarDetailNoDataViewModel(
val serverTimeInMills: Long
) : ViewModel() {
val wxSubscribeMsgConfigLiveData = MutableLiveData<WXSubscribeMsgConfig>()
val serverCalendarRemindLiveData: MutableLiveData<ServerCalendarNotifySetting?> = MutableLiveData()
private var isDataInit = false
var appRemind: Boolean = false
var wechatRemind: Boolean = false
val timeInSeconds: Int = (serverTimeInMills / 1000).toInt()
fun initData(notifySetting: ServerCalendarNotifySetting?) {
if (isDataInit) return
appRemind = notifySetting?.byApp ?: SPUtils.getBoolean(Constants.SP_SERVERS_CALENDAR_BY_APP, true)
wechatRemind = notifySetting?.byWechat ?: SPUtils.getBoolean(Constants.SP_SERVERS_CALENDAR_BY_WECHAT, true)
isDataInit = true
}
@SuppressLint("CheckResult")
fun getServerCalenderRemind(gameId: String) {
if (!CheckLoginUtils.isLogin()) {
serverCalendarRemindLiveData.postValue(null)
return
}
RetrofitManager.getInstance().newApi
.getServerCalendarRemind(gameId, timeInSeconds.toString())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
serverCalendarRemindLiveData.postValue(it)
}, {
serverCalendarRemindLiveData.postValue(null)
})
}
@SuppressLint("CheckResult")
fun addServerCalendarRemind(gameId: String) {
val requestBody = mapOf(
"by_app" to appRemind,
"by_wechat" to wechatRemind
).toRequestBody()
RetrofitManager.getInstance().newApi
.addServerCalendarRemind(gameId, timeInSeconds.toString(), requestBody)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
getServerCalenderRemind(gameId)
}, {})
}
@SuppressLint("CheckResult")
fun removeServerCalendarRemind(gameId: String) {
RetrofitManager.getInstance().newApi
.removeServerCalendarRemind(gameId, timeInSeconds.toString())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
getServerCalenderRemind(gameId)
}, {
it.printStackTrace()
})
}
@SuppressLint("CheckResult")
fun getWXSubscribeMsgConfig() {
RetrofitManager.getInstance().testApi
.getWxSubscribeMsgConfig(UrlFilterUtils.getFilterQuery("type", "server_new"))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
wxSubscribeMsgConfigLiveData.postValue(it)
}, {})
}
@SuppressLint("CheckResult")
fun addServerCalendarRemindWithWechat(
gameId: String,
openId: String?,
templateId: String?,
action: String,
reserved: String,
scene: Int,
) {
val requestBody = mapOf(
"openid" to openId,
"template_id" to templateId,
"action" to action,
"scene" to scene,
"user_id" to reserved
).toRequestBody()
RetrofitManager.getInstance().newApi
.postWxSubscribeMsgCallback(UrlFilterUtils.getFilterQuery("type", "server_new"), requestBody)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
addServerCalendarRemind(gameId)
}, {})
}
class Factory(
private val serverTimeInMills: Long
) : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return ServersCalendarDetailNoDataViewModel(serverTimeInMills) as T
}
}
}

View File

@ -1,38 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import androidx.lifecycle.*
import com.gh.gamecenter.entity.CalendarEntity
class ServersCalendarDetailViewModel(
source: LiveData<List<CalendarEntity>>,
val year: Int,
val month: Int,
val day: Int,
val showRemind: Boolean
) : ViewModel() {
var calendarEntityLiveData = Transformations.switchMap(source) {
Transformations.distinctUntilChanged(
MutableLiveData(
it.find { calendar ->
calendar.year == year
&& calendar.month == month
&& calendar.day == day
}
)
)
}
class Factory(
private val source: LiveData<List<CalendarEntity>>,
private val year: Int,
private val month: Int,
private val day: Int,
private val showRemind: Boolean
) : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return ServersCalendarDetailViewModel(source, year, month, day, showRemind) as T
}
}
}

View File

@ -1,305 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.app.Dialog
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import com.gh.common.constant.Config
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.WXAPIProxyFactory
import com.gh.gamecenter.common.utils.WXAPIProxyFactory.WXAPIProxy
import com.gh.gamecenter.common.utils.WXAPIProxyFactory.WXHandler
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.setDrawableEnd
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.common.view.DrawableView
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.databinding.DialogServersDetailRemindBinding
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.tencent.mm.opensdk.modelbase.BaseResp
import com.tencent.mm.opensdk.modelbiz.SubscribeMessage
import com.tencent.mm.opensdk.openapi.IWXAPI
import com.tencent.mm.opensdk.openapi.WXAPIFactory
import java.text.SimpleDateFormat
import java.util.*
/**
* 游戏开服-开服表详情-提醒详情弹窗
*/
class ServersCalendarDetailsRemindDialog : BottomSheetDialogFragment() {
private lateinit var viewBinding: DialogServersDetailRemindBinding
private lateinit var viewModel: ServersCalendarDetailsRemindViewModel
private lateinit var wxApi: WXAPIProxy<SubscribeMessage.Req, SubscribeMessage.Resp>
private val parentViewModel by viewModels<ServersCalendarDetailViewModel>({
parentFragment ?: this
})
private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault())
private val activityViewModel by activityViewModels<ServersCalendarViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NORMAL, R.style.DialogWindowTransparent)
wxApi = WXAPIProxyFactory.createWXAPI(
requireContext(),
Config.WECHAT_APPID,
object: WXHandler<SubscribeMessage.Req, SubscribeMessage.Resp> {
private val reserved = System.currentTimeMillis().toString()
override fun handleOnReq(req: SubscribeMessage.Req) {
req.reserved = reserved
}
override fun handleOnResp(resp: BaseResp): SubscribeMessage.Resp? {
if (resp is SubscribeMessage.Resp && reserved == resp.reserved) {
return resp
}
return null
}
}
)
viewModel = viewModelProvider(
ServersCalendarDetailsRemindViewModel.Factory(
arguments?.getString(EntranceConsts.KEY_SERVER_CALENDAR_ID, "") ?: ""
)
)
viewModel.initCalendarLiveData(parentViewModel.calendarEntityLiveData)
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return super.onCreateDialog(savedInstanceState).apply {
window?.setWindowAnimations(R.style.community_publication_animation)
window?.setGravity(Gravity.BOTTOM)
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return DialogServersDetailRemindBinding.inflate(inflater, container, false).also {
viewBinding = it
}.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewBinding.appRemindCheckIv.setImageDrawable(DrawableView.getCheckSelectorDrawable(requireContext()))
viewBinding.wechatRemindCheckIv.setImageDrawable(DrawableView.getCheckSelectorDrawable(requireContext()))
viewModel.serverCalendarEntityLiveData.observe(viewLifecycleOwner) { entity ->
entity?.let {
val serverName = if (it.getNote().isNullOrEmpty()) it.remark else it.getNote()
viewModel.initData(it)
viewBinding.serverName.text = serverName
viewBinding.serverTime.text = dateFormat.format(viewModel.selectedNotifyTime)
viewBinding.serverRemindTime.text = viewModel.selectedAdvancedTime.text
viewBinding.appRemindCheckIv.isChecked = viewModel.appRemind
viewBinding.wechatRemindCheckIv.isChecked = viewModel.wechatRemind
val notifySetting = it.notifySetting
if (notifySetting != null) {
viewBinding.serverTime.isEnabled = false
viewBinding.serverTime.setPadding(12F.dip2px(), 0, 0, 0)
viewBinding.serverTime.setDrawableEnd(null)
viewBinding.serverTime.background =
ContextCompat.getDrawable(requireContext(), R.drawable.bg_server_detail_remind_time_disabled)
viewBinding.serverTime.setTextColor(
ContextCompat.getColor(
requireContext(),
R.color.text_subtitleDesc
)
)
viewBinding.serverRemindTime.isEnabled = false
viewBinding.serverRemindTime.setPadding(12F.dip2px(), 0, 0, 0)
viewBinding.serverRemindTime.setDrawableEnd(null)
viewBinding.serverRemindTime.background =
ContextCompat.getDrawable(requireContext(), R.drawable.bg_server_detail_remind_time_disabled)
viewBinding.serverRemindTime.setTextColor(
ContextCompat.getColor(
requireContext(),
R.color.text_subtitleDesc
)
)
viewBinding.appRemind.alpha = 0.4F
viewBinding.appRemind.isEnabled = false
viewBinding.wechatRemind.alpha = 0.4F
viewBinding.wechatRemind.isEnabled = false
viewBinding.addOrCancelRemind.text = getString(R.string.servers_detail_cancel_remind)
viewBinding.addOrCancelRemind.background =
ContextCompat.getDrawable(requireContext(), R.drawable.bg_servers_detail_cancel_remind)
viewBinding.addOrCancelRemind.setTextColor(
ContextCompat.getColor(
requireContext(),
R.color.text_subtitle
)
)
viewBinding.addOrCancelRemind.setOnClickListener {
viewModel.removeServerCalendarRemind(activityViewModel.game.id)
NewLogUtils.logLaunchServerReminderCancel(
gameId = activityViewModel.game.id,
gameName = activityViewModel.game.name ?: "",
reminderTime = viewModel.selectedNotifySeconds - viewModel.selectedAdvancedTime.value,
reminderType = "已知服",
serverName = serverName ?: "",
launchServerTime = viewModel.selectedNotifySeconds,
isApp = viewModel.appRemind,
isWechat = viewModel.wechatRemind
)
SensorsBridge.trackLaunchServerReminderCancelClick(
gameId = activityViewModel.game.id,
gameName = activityViewModel.game.name ?: "",
reminderType = "已知服"
)
}
} else {
viewBinding.serverTime.isEnabled = true
viewBinding.serverTime.setPadding(12F.dip2px(), 0, 12F.dip2px(), 0)
viewBinding.serverTime.background =
ContextCompat.getDrawable(requireContext(), R.drawable.bg_server_detail_remind_time)
viewBinding.serverTime.setDrawableEnd(R.drawable.ic_arrow_gray)
viewBinding.serverTime.setTextColor(ContextCompat.getColor(requireContext(), R.color.text_subtitle))
viewBinding.serverRemindTime.isEnabled = true
viewBinding.serverRemindTime.setPadding(12F.dip2px(), 0, 12F.dip2px(), 0)
viewBinding.serverRemindTime.background =
ContextCompat.getDrawable(requireContext(), R.drawable.bg_server_detail_remind_time)
viewBinding.serverRemindTime.setDrawableEnd(R.drawable.ic_arrow_gray)
viewBinding.serverRemindTime.setTextColor(
ContextCompat.getColor(
requireContext(),
R.color.text_subtitle
)
)
viewBinding.appRemind.alpha = 1.0F
viewBinding.appRemind.isEnabled = true
viewBinding.wechatRemind.alpha = 1.0F
viewBinding.wechatRemind.isEnabled = true
viewBinding.addOrCancelRemind.text = getString(R.string.servers_detail_add_remind)
viewBinding.addOrCancelRemind.setTextColor(ContextCompat.getColor(requireContext(), R.color.white))
viewBinding.addOrCancelRemind.background =
ContextCompat.getDrawable(requireContext(), R.drawable.download_button_normal_style)
viewBinding.addOrCancelRemind.setOnClickListener {
val selectedNotifyTime = viewModel.selectedNotifyTime
val selectedAdvancedTime = viewModel.selectedAdvancedTime.value
if (selectedNotifyTime - selectedAdvancedTime * 1000 < System.currentTimeMillis()) {
ToastUtils.showToast(getString(R.string.servers_calendar_remind_time_out_of_date))
return@setOnClickListener
}
NewLogUtils.logLaunchServerReminderAdd(
gameId = activityViewModel.game.id,
gameName = activityViewModel.game.name ?: "",
reminderTime = viewModel.selectedNotifySeconds - viewModel.selectedAdvancedTime.value,
reminderType = "已知服",
serverName = serverName ?: "",
launchServerTime = viewModel.selectedNotifySeconds,
isApp = viewModel.appRemind,
isWechat = viewModel.wechatRemind
)
SensorsBridge.trackLaunchServerReminderClick(
gameId = activityViewModel.game.id,
gameName = activityViewModel.game.name ?: "",
reminderType = "已知服"
)
if (viewModel.wechatRemind) {// 勾选微信订阅后需要微信授权一次性订阅消息
viewModel.getWXSubscribeMsgConfig()
} else {
viewModel.addServerCalendarRemind(activityViewModel.game.id)
}
}
}
}
}
viewModel.wxSubscribeMsgConfigLiveData.observe(viewLifecycleOwner) {
wxApi.sendReq(
SubscribeMessage.Req().apply {
scene = it.scene
templateID = it.templateId
reserved = it.reserved
}
)
}
wxApi.liveData.observe(viewLifecycleOwner) {
if (it.action == "confirm") {
viewModel.addServerCalendarRemindWithWechat(
gameId = activityViewModel.game.id,
openId = it.openId,
templateId = it.templateID,
action = it.action,
reserved = it.reserved,
scene = it.scene
)
}
}
viewBinding.close.setOnClickListener {
dismissAllowingStateLoss()
}
viewBinding.serverTime.setOnClickListener {
val entity = viewModel.serverCalendarEntityLiveData.value ?: return@setOnClickListener
ServersCalendarTimeSettingDialog
.create(viewModel.selectedNotifyTime, entity.getTime() * 1000) {
viewModel.selectedNotifyTime = it
viewBinding.serverTime.text = dateFormat.format(it)
}
.showNow(childFragmentManager, null)
}
viewBinding.serverRemindTime.setOnClickListener {
ServersCalendarRemindTimeSettingDialog().also {
it.setSelectCallback { time ->
viewModel.selectedAdvancedTime = time
viewBinding.serverRemindTime.text = time.text
}
it.showNow(childFragmentManager, null)
}
}
viewBinding.appRemind.setOnClickListener {
viewBinding.appRemindCheckIv.isChecked = !viewBinding.appRemindCheckIv.isChecked
viewModel.appRemind = viewBinding.appRemindCheckIv.isChecked
SPUtils.setBoolean(Constants.SP_SERVERS_CALENDAR_BY_APP, viewBinding.appRemindCheckIv.isChecked)
}
viewBinding.wechatRemind.setOnClickListener {
viewBinding.wechatRemindCheckIv.isChecked = !viewBinding.wechatRemindCheckIv.isChecked
viewModel.wechatRemind = viewBinding.wechatRemindCheckIv.isChecked
SPUtils.setBoolean(Constants.SP_SERVERS_CALENDAR_BY_WECHAT, viewBinding.wechatRemindCheckIv.isChecked)
}
viewModel.notifySettingChangeLiveData.observe(viewLifecycleOwner) {
activityViewModel.dispatchNotifySettingChange(it.first, it.second)
}
}
}

View File

@ -1,149 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.annotation.SuppressLint
import androidx.lifecycle.*
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.toRequestBody
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.UrlFilterUtils
import com.gh.gamecenter.entity.CalendarEntity
import com.gh.gamecenter.feature.entity.ServerCalendarEntity
import com.gh.gamecenter.feature.entity.ServerCalendarNotifySetting
import com.gh.gamecenter.feature.entity.WXSubscribeMsgConfig
import com.gh.gamecenter.retrofit.RetrofitManager
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
class ServersCalendarDetailsRemindViewModel(
val id: String
) : ViewModel() {
lateinit var serverCalendarEntityLiveData: LiveData<ServerCalendarEntity?>
private set
val notifySettingChangeLiveData = MutableLiveData<Pair<String, ServerCalendarNotifySetting?>>()
val wxSubscribeMsgConfigLiveData = MutableLiveData<WXSubscribeMsgConfig>()
private var isDataInit = false
var selectedNotifyTime: Long = 0L
var selectedAdvancedTime: ServersCalendarAdvancedTime = ServersCalendarAdvancedTime.IN_TIME
var appRemind: Boolean = false
var wechatRemind: Boolean = false
val selectedNotifySeconds: Int get() = (selectedNotifyTime / 1000).toInt()
fun initCalendarLiveData(source: LiveData<CalendarEntity?>) {
serverCalendarEntityLiveData = Transformations.switchMap(source) {
Transformations.distinctUntilChanged(
MutableLiveData(
it?.server?.find { calendar ->
calendar.id == id
}
)
)
}
}
fun initData(calendarEntity: ServerCalendarEntity) {
if (isDataInit) return
val notifySetting = calendarEntity.notifySetting
selectedAdvancedTime = ServersCalendarAdvancedTime.valueOf(notifySetting?.secondsAdvance)
selectedNotifyTime = (notifySetting?.notifyTime ?: calendarEntity.getTime()) * 1000
appRemind = notifySetting?.byApp ?: SPUtils.getBoolean(Constants.SP_SERVERS_CALENDAR_BY_APP, true)
wechatRemind = notifySetting?.byWechat ?: SPUtils.getBoolean(Constants.SP_SERVERS_CALENDAR_BY_WECHAT, true)
isDataInit = true
}
@SuppressLint("CheckResult")
fun getServerCalenderRemind(gameId: String) {
RetrofitManager.getInstance().newApi
.getServerCalendarRemind(gameId, id)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
notifySettingChangeLiveData.postValue(id to it)
}, {
notifySettingChangeLiveData.postValue(id to null)
})
}
@SuppressLint("CheckResult")
fun getWXSubscribeMsgConfig() {
RetrofitManager.getInstance().testApi
.getWxSubscribeMsgConfig(UrlFilterUtils.getFilterQuery("type", "server_open"))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
wxSubscribeMsgConfigLiveData.postValue(it)
}, {})
}
@SuppressLint("CheckResult")
fun addServerCalendarRemind(gameId: String) {
val requestBody = mapOf(
"notify_time" to selectedNotifySeconds,
"seconds_advance" to selectedAdvancedTime.value,
"by_app" to appRemind,
"by_wechat" to wechatRemind
).toRequestBody()
RetrofitManager.getInstance().newApi
.addServerCalendarRemind(gameId, id, requestBody)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
getServerCalenderRemind(gameId)
}, {})
}
@SuppressLint("CheckResult")
fun addServerCalendarRemindWithWechat(
gameId: String,
openId: String?,
templateId: String?,
action: String,
reserved: String,
scene: Int,
) {
val requestBody = mapOf(
"openid" to openId,
"template_id" to templateId,
"action" to action,
"scene" to scene,
"user_id" to reserved
).toRequestBody()
RetrofitManager.getInstance().newApi
.postWxSubscribeMsgCallback(UrlFilterUtils.getFilterQuery("type", "server_open"), requestBody)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
addServerCalendarRemind(gameId)
}, {})
}
@SuppressLint("CheckResult")
fun removeServerCalendarRemind(gameId: String) {
RetrofitManager.getInstance().newApi
.removeServerCalendarRemind(gameId, id)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
getServerCalenderRemind(gameId)
}, {})
}
class Factory(
private val id: String
) : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return ServersCalendarDetailsRemindViewModel(id) as T
}
}
}

View File

@ -1,164 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.gh.common.util.DirectUtils
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.baselist.LoadType
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.common.viewholder.FooterViewHolder
import com.gh.gamecenter.databinding.ItemGameServerTestTimeBinding
import com.gh.gamecenter.databinding.ItemServerCalendarServerBinding
import com.gh.gamecenter.databinding.ItemServersCalendarBinding
import com.gh.gamecenter.feature.game.GameItemViewHolder
class ServersCalendarListAdapter(
context: Context,
private val viewModel: ServersCalendarListViewModel
) : ListAdapter<ServersCalendarListViewModel.ItemData>(context) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return when (viewType) {
ITEM_TYPE_FOOTER -> FooterViewHolder(mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false))
ITEM_TYPE_DATA_ITEM -> ServersCalendarViewHolder(parent.toBinding())
else -> ServersCalendarTimeViewHolder(parent.toBinding())
}
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
when (holder) {
is ServersCalendarViewHolder -> {
val game = mEntityList[position].game!!
holder.binding.icon.displayGameIcon(game.toGameEntity())
holder.binding.gameName.text = game.name
// 副标题
GameItemViewHolder.initGameSubtitleAndAdLabel(
game.toGameEntity(),
holder.binding.subtitle
)
// 如果开服表总数超过3个显示开服表总数
if (game.serversTotal > MAX_DISPLAY_SERVER_LIST_SIZE) {
holder.binding.serverCount.visibility = View.VISIBLE
holder.binding.serverCount.text =
holder.binding.root.context.getString(
R.string.servers_calendar_list_server_count,
game.serversTotal
)
} else {
holder.binding.serverCount.visibility = View.GONE
}
// 最多显示3条开服列表数据
val serverList = if (game.servers.size > MAX_DISPLAY_SERVER_LIST_SIZE) {
game.servers.subList(0, MAX_DISPLAY_SERVER_LIST_SIZE)
} else {
game.servers
}
holder.binding.servers.removeAllViews()
serverList.forEachIndexed { index, server ->
ItemServerCalendarServerBinding.inflate(
mLayoutInflater,
holder.binding.servers,
true
).apply {
// 优先展示服务器名字,若服务器名字为空则展示备注
val note = server.getNote()
val remark = server.remark
val name = if (note.isNullOrEmpty()) remark else note
this.name.text = name
this.time.text = server.getFormatTime("hh:mm")
root.layoutParams = (root.layoutParams as ViewGroup.MarginLayoutParams).apply {
bottomMargin = if (index < serverList.size - 1) 8F.dip2px() else 0
}
}
}
holder.binding.root.setOnClickListener {
DirectUtils.directToGameServerCalendar(
context = it.context,
gameId = game.id,
kaifuTime = game.startMidnight
)
NewLogUtils.logLaunchServerSubscribeClick(
gameId = game.id,
gameName = game.name,
launchServerTime = game.startMidnight.toInt()
)
}
}
is ServersCalendarTimeViewHolder -> {
holder.binding.timeTv.text =
ServersCalendarListFragment.formatTime(mContext, mEntityList[position].time!! * 1000)
}
is FooterViewHolder -> initFooterViewHolder(holder, mIsLoading, mIsNetworkError, mIsOver)
}
}
fun initFooterViewHolder(
viewHolder: FooterViewHolder,
isLoading: Boolean,
isNetworkError: Boolean,
isOver: Boolean
) {
viewHolder.run {
if (isNetworkError) {
loading.visibility = View.GONE
hint.setText(R.string.loading_failed_retry)
itemView.isClickable = true
itemView.setOnClickListener { viewModel.load(LoadType.RETRY) }
} else if (isOver) {
loading.visibility = View.GONE
hint.setText(R.string.load_over_hint)
itemView.isClickable = false
itemView.setOnClickListener(null)
} else if (isLoading) {
loading.visibility = View.VISIBLE
hint.setText(R.string.loading)
itemView.isClickable = false
itemView.setOnClickListener(null)
} else {
loading.visibility = View.GONE
hint.setText(R.string.loading_more_hint)
itemView.isClickable = false
itemView.setOnClickListener(null)
}
}
}
override fun getItemViewType(position: Int): Int {
return if (mEntityList[position].footer) {
ITEM_TYPE_FOOTER
} else if(mEntityList[position].time != null) {
ITEM_TYPE_DATE_HEADER
} else {
ITEM_TYPE_DATA_ITEM
}
}
override fun getItemCount(): Int = mEntityList.size
class ServersCalendarViewHolder(val binding: ItemServersCalendarBinding) : ViewHolder(binding.root)
class ServersCalendarTimeViewHolder(var binding: ItemGameServerTestTimeBinding) : ViewHolder(binding.root)
companion object {
private const val ITEM_TYPE_FOOTER = 100
private const val ITEM_TYPE_DATE_HEADER = 200
private const val ITEM_TYPE_DATA_ITEM = 300
private const val MAX_DISPLAY_SERVER_LIST_SIZE = 3
}
}

View File

@ -1,144 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.content.Context
import android.os.Bundle
import android.view.View
import android.widget.FrameLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.DirectUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.LazyListFragment
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.databinding.FragmentServersCalendarListBinding
import java.text.SimpleDateFormat
import java.util.*
/**
* 开服订阅-开服表
*/
class ServersCalendarListFragment :
LazyListFragment<ServersCalendarListViewModel.ItemData, ServersCalendarListViewModel>() {
private var adapter: ServersCalendarListAdapter? = null
private lateinit var viewBinding: FragmentServersCalendarListBinding
override fun getRealLayoutId(): Int {
return R.layout.fragment_servers_calendar_list
}
override fun onRealLayoutInflated(inflatedView: View) {
super.onRealLayoutInflated(inflatedView)
viewBinding = FragmentServersCalendarListBinding.bind(inflatedView)
}
override fun onRefresh() {
super.onRefresh()
viewBinding.topDateContainer.root.visibility = View.GONE
}
override fun onLoadError() {
super.onLoadError()
viewBinding.topDateContainer.root.visibility = View.GONE
}
override fun onLoadEmpty() {
super.onLoadEmpty()
viewBinding.topDateContainer.root.visibility = View.GONE
}
override fun provideListViewModel(): ServersCalendarListViewModel {
return viewModelProvider()
}
override fun provideListAdapter(): ListAdapter<*> {
return adapter ?: ServersCalendarListAdapter(
requireContext(),
mListViewModel
).apply {
adapter = this
}
}
override fun getItemDecoration(): RecyclerView.ItemDecoration? = null
override fun onFragmentFirstVisible() {
super.onFragmentFirstVisible()
viewBinding.subscribedGameManagementLayout.setOnClickListener {
DirectUtils.directToServersSubscribedGameList(it.context)
}
mListRv.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val layoutManager = recyclerView.layoutManager
if (layoutManager is LinearLayoutManager && !mListViewModel.obsListData.value.isNullOrEmpty()) {
val firstVisiblePosition = layoutManager.findFirstVisibleItemPosition()
// 悬挂的文案
viewBinding.topDateContainer.root.visibility = View.VISIBLE
viewBinding.topDateContainer.timeTv.text =
formatTime(recyclerView.context, mListViewModel.getTimeByPosition(firstVisiblePosition) * 1000)
// 悬挂界面移动
val lp = viewBinding.topDateContainer.root.layoutParams as FrameLayout.LayoutParams
if (firstVisiblePosition != 0
&& mListViewModel?.getItemAtPosition(firstVisiblePosition + 1)?.time != null
) {
val bottom = layoutManager.findViewByPosition(firstVisiblePosition)?.bottom ?: 0
if (bottom <= viewBinding.topDateContainer.root.height) {
lp.topMargin = bottom - viewBinding.topDateContainer.root.height
} else {
lp.topMargin = 0
}
} else {
lp.topMargin = 0
}
viewBinding.topDateContainer.root.layoutParams = lp
}
}
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {}
})
}
companion object {
/**
* 将时间戳转换成开服表时间
* 开服表时间显示规则:
* 明天:目标日期=当天的下一天日期
* 今天:目标日期=当天日期
* 月日:目标日期在当前自然年以内
* 年月日:目标日期在当前自然年以外
*/
fun formatTime(context: Context, time: Long): String {
val serverCalendar = Calendar.getInstance().apply {
timeInMillis = time
}
val todayCalendar = Calendar.getInstance()
val tomorrowCalendar = Calendar.getInstance().apply {
add(Calendar.DATE, 1)
}
return if (todayCalendar.get(Calendar.YEAR) == serverCalendar.get(Calendar.YEAR)
&& todayCalendar.get(Calendar.MONTH) == serverCalendar.get(Calendar.MONTH)
&& todayCalendar.get(Calendar.DATE) == serverCalendar.get(Calendar.DATE)
) {
context.getString(R.string.servers_calendar_list_date_today)
} else if (tomorrowCalendar.get(Calendar.YEAR) == serverCalendar.get(Calendar.YEAR)
&& tomorrowCalendar.get(Calendar.MONTH) == serverCalendar.get(Calendar.MONTH)
&& tomorrowCalendar.get(Calendar.DATE) == serverCalendar.get(Calendar.DATE)
) {
context.getString(R.string.servers_calendar_list_date_tomorrow)
} else if (todayCalendar.get(Calendar.YEAR) == serverCalendar.get(Calendar.YEAR)) {
SimpleDateFormat("MM月dd日", Locale.getDefault()).format(time)
} else {
SimpleDateFormat("yyyy年MM月dd日", Locale.getDefault()).format(time)
}
}
}
}

View File

@ -1,77 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.app.Application
import com.gh.gamecenter.common.baselist.ListViewModel
import com.gh.gamecenter.entity.HaloAddonEntity
import com.gh.gamecenter.feature.entity.ServerCalendarFormEntity
import com.gh.gamecenter.feature.entity.ServerCalendarGame
import com.gh.gamecenter.retrofit.RetrofitManager
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import io.reactivex.Observable
import io.reactivex.Single
class ServersCalendarListViewModel(application: Application) :
ListViewModel<ServersCalendarListViewModel.ItemData, ServersCalendarListViewModel.ItemData>(
application
) {
override fun provideDataObservable(page: Int): Observable<List<ItemData>>? {
return null
}
override fun provideDataSingle(page: Int): Single<MutableList<ItemData>> {
return RetrofitManager.getInstance().newApi
.getServerCalendarList(page, 20)
.map { list ->
val dataList = mutableListOf<ItemData>()
for (formEntity in list) {
dataList.add(ItemData(time = formEntity.startMidnight))
dataList.addAll(formEntity.game.map { game ->
ItemData(game = game.apply {
startMidnight = formEntity.startMidnight
})
})
}
dataList
}
}
fun getTimeByPosition(position: Int): Long {
var time = 0L
val dataList = mResultLiveData.value
dataList?.let {
for ((index, value) in dataList.withIndex()) {
if (value.time != null) {
time = value.time
}
if (index == position) {
return time
}
}
}
return time
}
fun getItemAtPosition(position: Int): ItemData? {
if (position < (mResultLiveData?.value?.size ?: 0)) {
return mResultLiveData.value?.get(position)
}
return null
}
override fun mergeResultLiveData() {
mResultLiveData.addSource(mListLiveData) { list ->
mResultLiveData.postValue(
mutableListOf<ItemData>()
.also {
it.addAll(list)
it.add(ItemData(footer = true))
}
)
}
}
data class ItemData(val game: ServerCalendarGame? = null, val time: Long? = null, val footer: Boolean = false)
}

View File

@ -1,22 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.content.Context
import android.content.Intent
import com.gh.gamecenter.common.base.activity.ToolBarActivity
class ServersCalendarManagementActivity : ToolBarActivity() {
override fun provideNormalIntent(): Intent {
return getTargetIntent(
this,
ServersCalendarManagementActivity::class.java,
ServersCalendarManagementFragment::class.java
)
}
companion object {
fun getIntent(context: Context): Intent {
return Intent(context, ServersCalendarManagementActivity::class.java)
}
}
}

View File

@ -1,27 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.os.Bundle
import androidx.fragment.app.Fragment
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.BaseFragment_TabLayout
/**
* 开服订阅
*/
class ServersCalendarManagementFragment : BaseFragment_TabLayout() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setNavigationTitle(getString(R.string.servers_calendar_subscription_title))
}
override fun initFragmentList(fragments: MutableList<Fragment>) {
fragments.add(ServersCalendarListFragment())
fragments.add(ServersCalendarRemindListFragment())
}
override fun initTabTitleList(tabTitleList: MutableList<String>) {
tabTitleList.add(getString(R.string.servers_calendar_list_tab))
tabTitleList.add(getString(R.string.servers_calendar_remind_list_tab))
}
}

View File

@ -1,63 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.app.Dialog
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.activityViewModels
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.databinding.DialogServersCalendarMoreBinding
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
/**
* 开服日历表-更多菜单
*/
class ServersCalendarMoreDialog : BottomSheetDialogFragment() {
private lateinit var viewBinding: DialogServersCalendarMoreBinding
private val viewModel by activityViewModels<ServersCalendarViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NORMAL, R.style.DialogWindowTransparent)
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return super.onCreateDialog(savedInstanceState).apply {
window?.setWindowAnimations(R.style.community_publication_animation)
window?.setGravity(Gravity.BOTTOM)
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewBinding.unsubscribe.setOnClickListener {
viewModel.unsubscribeServer()
NewLogUtils.logLaunchServerSubscribeCancel(
gameId = viewModel.game.id,
gameName = viewModel.game.name ?: ""
)
SensorsBridge.trackLaunchServerSubscribeCancelClick(
gameId = viewModel.game.id,
gameName = viewModel.game.name ?: ""
)
dismissAllowingStateLoss()
}
viewBinding.cancel.setOnClickListener {
dismissAllowingStateLoss()
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return DialogServersCalendarMoreBinding.inflate(inflater, container, false).also {
viewBinding = it
}.root
}
}

View File

@ -1,184 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.gh.common.util.DirectUtils
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.baselist.LoadType
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.common.viewholder.FooterViewHolder
import com.gh.gamecenter.databinding.ItemServersCalendarRemindBinding
import com.gh.gamecenter.feature.game.GameItemViewHolder
import java.text.SimpleDateFormat
import java.util.*
class ServersCalendarRemindListAdapter(
context: Context,
private val viewModel: ServersCalendarRemindListViewModel
) : ListAdapter<ServersCalendarRemindListViewModel.ItemData>(context) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return when (viewType) {
ITEM_TYPE_FOOTER -> FooterViewHolder(mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false))
else -> ServersCalendarRemindViewHolder(parent.toBinding())
}
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
if (holder is ServersCalendarRemindViewHolder) {
val game = mEntityList[position].game!!
holder.binding.icon.displayGameIcon(game.toGameEntity())
holder.binding.gameName.text = game.name
// 副标题
GameItemViewHolder.initGameSubtitleAndAdLabel(
game.toGameEntity(),
holder.binding.subtitle
)
val context = holder.binding.root.context
// 已知服: 展示设置开服时间+服务器名字/备注
// 未知服: 展示关注开服日期
val server = game.servers.first()
val notifySetting = server.notifySetting!!
if (server.getNote().isNullOrEmpty() && server.remark.isEmpty()) {// 未知服
val format = SimpleDateFormat("MM月dd日", Locale.getDefault())
holder.binding.time.text = format.format(notifySetting.notifyTime * 1000)
} else {// 已知服
val format = SimpleDateFormat("MM月dd日 hh:mm", Locale.getDefault())
// 优先展示服务器名字,若服务器名字为空则展示备注
val note = server.getNote()
val remark = server.remark
val name = if (note.isNullOrEmpty()) remark else note
holder.binding.time.text = context.getString(
R.string.servers_calendar_remind_list_server_name,
format.format(notifySetting.notifyTime * 1000),
name
)
}
// 提醒状态
val notifyStatus = game.notifyStatus!!
// 设置提醒状态文字颜色
val statusTextColorId = if (notifyStatus == NOTIFY_STATUS_TODO || notifyStatus == NOTIFY_STATUS_COMING) {
R.color.theme_font
} else {
R.color.text_subtitleDesc
}
holder.binding.status.setTextColor(ContextCompat.getColor(context, statusTextColorId))
// 设置提醒状态文案
val statusTextId = when (notifyStatus) {
NOTIFY_STATUS_TODO -> R.string.servers_calendar_remind_status_todo
NOTIFY_STATUS_COMING -> R.string.servers_calendar_remind_status_coming
NOTIFY_STATUS_OPENED -> R.string.servers_calendar_remind_status_opened
NOTIFY_STATUS_HAS_NEW -> R.string.servers_calendar_remind_status_has_new
else -> R.string.servers_calendar_remind_status_expired
}
holder.binding.status.text = context.getString(statusTextId)
holder.binding.root.setOnClickListener {
DirectUtils.directToGameServerCalendar(
context = it.context,
gameId = game.id,
kaifuTime = server.getTime()
)
NewLogUtils.logLaunchServerReminderClick(
gameId = game.id,
gameName = game.name,
reminderTime = (notifySetting.notifyTime - notifySetting.secondsAdvance).toInt(),
status = notifyStatus
)
}
} else if(holder is FooterViewHolder) {
initFooterViewHolder(holder, mIsLoading, mIsNetworkError, mIsOver)
}
}
fun initFooterViewHolder(
viewHolder: FooterViewHolder,
isLoading: Boolean,
isNetworkError: Boolean,
isOver: Boolean
) {
viewHolder.run {
if (isNetworkError) {
loading.visibility = View.GONE
hint.setText(R.string.loading_failed_retry)
itemView.isClickable = true
itemView.setOnClickListener { viewModel.load(LoadType.RETRY) }
} else if (isOver) {
loading.visibility = View.GONE
hint.setText(R.string.load_over_hint)
itemView.isClickable = false
itemView.setOnClickListener(null)
} else if (isLoading) {
loading.visibility = View.VISIBLE
hint.setText(R.string.loading)
itemView.isClickable = false
itemView.setOnClickListener(null)
} else {
loading.visibility = View.GONE
hint.setText(R.string.loading_more_hint)
itemView.isClickable = false
itemView.setOnClickListener(null)
}
}
}
override fun getItemViewType(position: Int): Int {
return if (mEntityList[position].footer) {
ITEM_TYPE_FOOTER
} else {
ITEM_TYPE_DATA
}
}
override fun getItemCount(): Int = mEntityList.size
class ServersCalendarRemindViewHolder(val binding: ItemServersCalendarRemindBinding) : ViewHolder(binding.root)
companion object {
/**
* 待提醒
*/
private const val NOTIFY_STATUS_TODO = "todo"
/**
* 即将开服
*/
private const val NOTIFY_STATUS_COMING = "coming"
/**
* 已开服
*/
private const val NOTIFY_STATUS_OPENED = "opened"
/**
* 有新服
*/
private const val NOTIFY_STATUS_HAS_NEW = "has_new"
/**
* 已过期
*/
private const val NOTIFY_STATUS_EXPIRED = "expired"
/**
* 未知服
*/
private const val SERVER_TYPE_UNKNOWN = "未知服"
private const val ITEM_TYPE_FOOTER = 100
private const val ITEM_TYPE_DATA = 200
}
}

View File

@ -1,37 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.LazyListFragment
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.feature.entity.ServerCalendarGame
/**
* 开服订阅-开服提醒
*/
class ServersCalendarRemindListFragment : LazyListFragment<ServerCalendarGame, ServersCalendarRemindListViewModel>() {
private var adapter: ServersCalendarRemindListAdapter? = null
override fun provideListAdapter(): ListAdapter<*> {
return adapter ?: ServersCalendarRemindListAdapter(
requireContext(),
mListViewModel
).apply {
adapter = this
}
}
override fun onFragmentFirstVisible() {
super.onFragmentFirstVisible()
mCachedView.background = ContextCompat.getDrawable(requireContext(), R.color.white)
}
override fun getItemDecoration(): RecyclerView.ItemDecoration? = null
override fun provideListViewModel(): ServersCalendarRemindListViewModel {
return viewModelProvider()
}
}

View File

@ -1,36 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.app.Application
import com.gh.gamecenter.common.baselist.ListViewModel
import com.gh.gamecenter.feature.entity.ServerCalendarGame
import com.gh.gamecenter.retrofit.RetrofitManager
import io.reactivex.Observable
import io.reactivex.Single
class ServersCalendarRemindListViewModel(application: Application) :
ListViewModel<ServersCalendarRemindListViewModel.ItemData, ServersCalendarRemindListViewModel.ItemData>(application) {
override fun provideDataObservable(page: Int): Observable<List<ItemData>>? {
return null
}
override fun provideDataSingle(page: Int): Single<List<ItemData>> {
return RetrofitManager.getInstance().newApi
.getServerCalendarRemindList(page, 20)
.map { list -> list.map { ItemData(game = it) } }
}
override fun mergeResultLiveData() {
mResultLiveData.addSource(mListLiveData) { list ->
mResultLiveData.postValue(
mutableListOf<ItemData>()
.also {
it.addAll(list)
it.add(ItemData(footer = true))
}
)
}
}
data class ItemData(val game: ServerCalendarGame? = null, val footer: Boolean = false)
}

View File

@ -1,32 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.content.Context
import android.view.ViewGroup
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.gamecenter.databinding.ItemServersCalendarRemindTimeSettingBinding
import com.lightgame.adapter.BaseRecyclerAdapter
class ServersCalendarRemindTimeSettingAdapter(
context: Context,
private val itemCallback: (ServersCalendarAdvancedTime) -> Unit
) : BaseRecyclerAdapter<ServersCalendarRemindTimeSettingAdapter.ServersCalendarRemindTimeSettingViewHolder>(context) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ServersCalendarRemindTimeSettingViewHolder {
val view = mLayoutInflater.inflate(R.layout.item_servers_calendar_remind_time_setting, parent, false)
return ServersCalendarRemindTimeSettingViewHolder(ItemServersCalendarRemindTimeSettingBinding.bind(view))
}
override fun getItemCount(): Int = ServersCalendarAdvancedTime.values().size
override fun onBindViewHolder(holder: ServersCalendarRemindTimeSettingViewHolder, position: Int) {
val data = ServersCalendarAdvancedTime.values()[position]
holder.binding.nameTv.text = data.text
holder.binding.root.setOnClickListener {
itemCallback.invoke(data)
}
}
class ServersCalendarRemindTimeSettingViewHolder(val binding: ItemServersCalendarRemindTimeSettingBinding) :
BaseRecyclerViewHolder<Any>(binding.root)
}

View File

@ -1,60 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.app.Dialog
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import com.gh.gamecenter.R
import com.gh.gamecenter.common.view.VerticalItemDecoration
import com.gh.gamecenter.databinding.DialogServersCalendarRemindTimeSettingBinding
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
/**
* 设置提醒时间弹窗
*/
class ServersCalendarRemindTimeSettingDialog : BottomSheetDialogFragment() {
private lateinit var viewBinding: DialogServersCalendarRemindTimeSettingBinding
private var selectCallback: ((ServersCalendarAdvancedTime) -> Unit)? = null
fun setSelectCallback(callback: ((ServersCalendarAdvancedTime) -> Unit)?) {
this.selectCallback = callback
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NORMAL, R.style.DialogWindowTransparent)
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return super.onCreateDialog(savedInstanceState).apply {
window?.setWindowAnimations(R.style.community_publication_animation)
window?.setGravity(Gravity.BOTTOM)
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewBinding.cancel.setOnClickListener {
dismissAllowingStateLoss()
}
viewBinding.rv.adapter = ServersCalendarRemindTimeSettingAdapter(requireContext()) {
this.selectCallback?.invoke(it)
dismissAllowingStateLoss()
}
viewBinding.rv.layoutManager = LinearLayoutManager(context)
viewBinding.rv.addItemDecoration(VerticalItemDecoration(context, 1, false, R.color.divider))
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return DialogServersCalendarRemindTimeSettingBinding.inflate(inflater, container, false).also {
viewBinding = it
}.root
}
}

View File

@ -1,43 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import com.gh.gamecenter.R
import com.gh.gamecenter.common.databinding.DialogAlertDefaultBinding
import com.gh.gamecenter.common.utils.setDrawableStart
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
/**
* 游戏订阅成功-已绑定微信弹窗
*/
class ServersCalendarSubscriptionSuccessDialog : DialogFragment() {
private lateinit var viewBinding: DialogAlertDefaultBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(BottomSheetDialogFragment.STYLE_NORMAL, R.style.DialogWindowTransparent)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return DialogAlertDefaultBinding.inflate(inflater, container, false).also {
viewBinding = it
}.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewBinding.titleTv.text = getString(R.string.servers_calendar_subscription_dialog_title)
viewBinding.contentTv.text = getString(R.string.servers_calendar_subscription_dialog_content)
viewBinding.confirmTv.text = getString(R.string.servers_calendar_subscription_dialog_confirm)
viewBinding.centerDivider.visibility = View.GONE
viewBinding.cancelTv.visibility = View.GONE
viewBinding.titleTv.setDrawableStart(R.drawable.ic_reserve_success, null, null)
viewBinding.confirmTv.setOnClickListener {
dismissAllowingStateLoss()
}
}
}

View File

@ -1,204 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.app.Dialog
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import com.bigkoo.pickerview.adapter.ArrayWheelAdapter
import com.contrarywind.adapter.WheelAdapter
import com.contrarywind.view.WheelView
import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.databinding.DialogServersCalendarTimeSettingBinding
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import java.text.SimpleDateFormat
import java.util.*
/**
* 设置开服时间弹窗
*/
class ServersCalendarTimeSettingDialog private constructor() : BottomSheetDialogFragment() {
private lateinit var viewBinding: DialogServersCalendarTimeSettingBinding
private lateinit var kaifuCalendar: Calendar
private lateinit var selectKaifuCalendar: Calendar
private val currentCalendar = Calendar.getInstance()
private val dateFormat = SimpleDateFormat("yyyy-MM-dd hh时 mm分", Locale.getDefault())
private var selectCallback: ((Long) -> Unit)? = null
fun setSelectCallback(callback: ((Long) -> Unit)?) {
this.selectCallback = callback
}
private fun dispatchSelectCallback() {
val date = viewBinding.date.adapter.getItem(viewBinding.date.currentItem)
val hour = viewBinding.hour.adapter.getItem(viewBinding.hour.currentItem)
val minute = viewBinding.minute.adapter.getItem(viewBinding.minute.currentItem)
dateFormat.parse("$date $hour $minute")?.let {
selectCallback?.invoke(it.time)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NORMAL, R.style.DialogWindowTransparent)
selectKaifuCalendar = Calendar.getInstance().apply {
timeInMillis = arguments?.getLong(EntranceConsts.KEY_KAIFU_SELECT_TIME) ?: 0L
}
kaifuCalendar = Calendar.getInstance().apply {
timeInMillis = arguments?.getLong(EntranceConsts.KEY_KAIFU_TIME) ?: 0L
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return super.onCreateDialog(savedInstanceState).apply {
window?.setWindowAnimations(R.style.community_publication_animation)
window?.setGravity(Gravity.BOTTOM)
if (this is BottomSheetDialog) {
behavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
override fun onStateChanged(bottomSheet: View, newState: Int) {
if (newState == BottomSheetBehavior.STATE_DRAGGING) {
behavior.state = BottomSheetBehavior.STATE_EXPANDED
}
}
override fun onSlide(bottomSheet: View, slideOffset: Float) {
}
})
}
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return DialogServersCalendarTimeSettingBinding.inflate(inflater, container, false).also {
viewBinding = it
}.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewBinding.cancel.setOnClickListener {
dismissAllowingStateLoss()
}
viewBinding.confirm.setOnClickListener {
dispatchSelectCallback()
dismissAllowingStateLoss()
}
val dateList = buildDates(currentCalendar, kaifuCalendar)
initWheelView(
viewBinding.date,
ArrayWheelAdapter(dateList),
calculateCurrentDateItem(currentCalendar, selectKaifuCalendar)
)
initWheelView(
viewBinding.hour,
ArrayWheelAdapter(buildHours()),
selectKaifuCalendar.get(Calendar.HOUR_OF_DAY)
)
initWheelView(
viewBinding.minute,
ArrayWheelAdapter(buildMinutes()),
selectKaifuCalendar.get(Calendar.MINUTE)
)
}
companion object {
fun create(
kaifuSelectTime: Long,
kaifuTime: Long,
selectCallback: (Long) -> Unit
): ServersCalendarTimeSettingDialog =
ServersCalendarTimeSettingDialog().apply {
arguments = Bundle().apply {
putLong(EntranceConsts.KEY_KAIFU_SELECT_TIME, kaifuSelectTime)
putLong(EntranceConsts.KEY_KAIFU_TIME, kaifuTime)
}
setSelectCallback(selectCallback)
}
private fun initWheelView(
wheelView: WheelView,
adapter: WheelAdapter<*>,
currentIndex: Int
) {
wheelView.javaClass.getDeclaredField("itemsVisible").apply {
isAccessible = true
set(wheelView, 7)
}
wheelView.setLabel("")
wheelView.setGravity(Gravity.CENTER)
wheelView.adapter = adapter
wheelView.currentItem = currentIndex
wheelView.setTextSize(14F)
wheelView.setLineSpacingMultiplier(3F)
wheelView.setTextXOffset(0)
wheelView.setDividerColor(ContextCompat.getColor(wheelView.context, R.color.transparent))
wheelView.setTextColorCenter(ContextCompat.getColor(wheelView.context, R.color.text_title))
wheelView.setTextColorCenter(ContextCompat.getColor(wheelView.context, R.color.text_title))
}
private fun calculateCurrentDateItem(
currentCalendar: Calendar,
selectKaifuCalendar: Calendar
): Int {
val selectKaifuTime = selectKaifuCalendar.timeInMillis
val currentTime = currentCalendar.timeInMillis
return ((selectKaifuTime - currentTime) / (24 * 60 * 60 * 1000)).toInt()
}
private fun buildDates(currentCalendar: Calendar, kaifuCalendar: Calendar): List<String> {
val dateList = mutableListOf<String>()
val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
val calendar = Calendar.getInstance().apply {
timeInMillis = currentCalendar.timeInMillis
}
val kaifuTime = kaifuCalendar.timeInMillis
var dateTime = calendar.timeInMillis
var dateOffset = (kaifuTime - dateTime) / (24 * 60 * 60 * 1000)
while (dateOffset >= 0) {
dateList.add(dateFormat.format(dateTime))
dateTime = calendar.apply {
add(Calendar.DAY_OF_YEAR, 1)
}.timeInMillis
dateOffset = (kaifuTime - dateTime) / (24 * 60 * 60 * 1000)
}
return dateList
}
private fun buildHours(): List<String> {
val hourList = mutableListOf<String>()
for (hour in 0..23) {
hourList.add("${hour}")
}
return hourList
}
private fun buildMinutes(): List<String> {
val minuteList = mutableListOf<String>()
for (minute in 0..59) {
minuteList.add("${minute}")
}
return minuteList
}
}
}

View File

@ -7,11 +7,14 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.common.util.CheckLoginUtils
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.throwExceptionInDebug
import com.gh.gamecenter.common.utils.toRequestBody
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.feature.entity.*
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.toRequestBody
import com.gh.gamecenter.feature.entity.GameDetailServer
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.MeEntity
import com.gh.gamecenter.feature.entity.ServerCalendarEntity
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.retrofit.RetrofitManager
import io.reactivex.Single
@ -20,19 +23,18 @@ import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.ArrayList
class ServersCalendarViewModel(
application: Application,
val game: GameEntity,
val gameServer: GameDetailServer,
var meEntity: MeEntity?,
var meEntity: MeEntity?
) : AndroidViewModel(application) {
val calendarLiveData: MutableLiveData<List<CalendarEntity>> = MutableLiveData()
val serversDetailLiveData: MutableLiveData<CalendarEntity> = MutableLiveData()
val serverCalendarLiveData: MutableLiveData<MutableList<ServerCalendarEntity>?> = MutableLiveData()
val serverSubscriptionLiveData = MutableLiveData<ServerSubscriptionEntity?>()
val subscribeServerSuccessEvent = MutableLiveData<Any?>()
val serverCalendarLiveData: MutableLiveData<MutableList<ServerCalendarEntity>> = MutableLiveData()
var monthCount = 0
var curWeek = 0
@ -42,7 +44,6 @@ class ServersCalendarViewModel(
var isExistCurServer = true// 当月是否存在开服
var kaifuCalendar: Calendar? = null
init {
// checkExistCurSerer()
@ -58,138 +59,21 @@ class ServersCalendarViewModel(
}
}
/**
* 设置选中的开服表日期
* @param kaifuTime 选中日期的时间戳
*/
fun setKaifuTime(kaifuTime: Long) {
if (kaifuTime == 0L) return
val currentCalendar = Calendar.getInstance().apply {
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}
val kaifuCalendar = Calendar.getInstance().also {
this.kaifuCalendar = it
it.timeInMillis = kaifuTime * 1000
}
val kaifuYear = kaifuCalendar.get(Calendar.YEAR)
val kaifuMonth = kaifuCalendar.get(Calendar.MONTH)
val currentYear = currentCalendar.get(Calendar.YEAR)
val currentMonth = currentCalendar.get(Calendar.MONTH)
this.selectedMonth = if (kaifuYear == currentYear && kaifuMonth == currentMonth - 1) {
MonthType.PREVIOUS_MONTH
} else if (kaifuYear == currentYear && kaifuMonth == currentMonth + 1) {
MonthType.NEXT_MONTH
} else {
MonthType.CUR_MONTH
}
}
@SuppressLint("CheckResult")
fun loadServerData(isMirror: Boolean = false) {
var apiService = RetrofitManager.getInstance().api
.getGameServerCalendar(game.id, if (isMirror) "mirror" else "", true)
if (!CheckLoginUtils.isLogin()) {
serverSubscriptionLiveData.postValue(null)
} else {
apiService = RetrofitManager.getInstance().newApi
.getServerSubscription(game.id)
.onErrorReturnItem(ServerSubscriptionEntity())
.zipWith(apiService) { subscription, list ->
serverSubscriptionLiveData.postValue(subscription)
list
}
}
apiService
RetrofitManager.getInstance().api
.getGameServerCalendar(game.id, if (isMirror) "mirror" else "")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
serverCalendarLiveData.postValue(it)
},
{
.subscribe(object : BiResponse<MutableList<ServerCalendarEntity>>() {
override fun onSuccess(data: MutableList<ServerCalendarEntity>) {
serverCalendarLiveData.postValue(data)
}
override fun onFailure(exception: Exception) {
serverCalendarLiveData.postValue(null)
}
)
}
@SuppressLint("CheckResult")
fun getServerSubscription(notifySubscribeSuccess: Boolean = false) {
if (!CheckLoginUtils.isLogin()) {
serverSubscriptionLiveData.postValue(null)
return
}
// 已登录状态下检查开服表订阅状态
RetrofitManager.getInstance().newApi
.getServerSubscription(game.id)
.onErrorReturnItem(ServerSubscriptionEntity())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
serverSubscriptionLiveData.postValue(it)
if (notifySubscribeSuccess && it.byApp) {// 发送订阅成功通知
subscribeServerSuccessEvent.postValue(null)
}
},
{
serverSubscriptionLiveData.postValue(null)
}
)
}
@SuppressLint("CheckResult")
fun subscribeServer() {
RetrofitManager.getInstance().newApi
.subscribeServer(game.id)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ getServerSubscription(true) }, {})
}
@SuppressLint("CheckResult")
fun unsubscribeServer() {
RetrofitManager.getInstance().newApi
.unsubscribeServer(game.id)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
getServerSubscription()
}, {})
}
fun dispatchNotifySettingChange(id: String, notifySetting: ServerCalendarNotifySetting?) {
val serverCalendarList = serverCalendarLiveData.value ?: return
val index = serverCalendarList.indexOfFirst {
it.id == id
}
if (index != -1) {
val oldServerCalendar = serverCalendarList[index]
val newServerCalendar = ServerCalendarEntity().apply {
this.id = oldServerCalendar.id
this.setTime(oldServerCalendar.getTime())
this.setNote(oldServerCalendar.getNote())
this.remark = oldServerCalendar.remark
this.setFirstName(oldServerCalendar.getFirstName())
this.setServerName(oldServerCalendar.getServerName())
this.type = oldServerCalendar.type
this.setDataMark(oldServerCalendar.getDataMark())
this.notifySetting = notifySetting
}
serverCalendarList[index] = newServerCalendar
serverCalendarLiveData.value = serverCalendarList
}
})
}
@SuppressLint("CheckResult")
@ -197,10 +81,7 @@ class ServersCalendarViewModel(
val requestMap = hashMapOf<String, List<String>>()
requestMap["game"] = arrayListOf(game.id)
RetrofitManager.getInstance().api.getUserRelatedInfoByPost(
UserManager.getInstance().userId,
requestMap.toRequestBody()
)
RetrofitManager.getInstance().api.getUserRelatedInfoByPost(UserManager.getInstance().userId, requestMap.toRequestBody())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<UnifiedUserTrendEntity>() {
@ -308,19 +189,6 @@ class ServersCalendarViewModel(
emitter.onSuccess(curDayData)
}.subscribe(object : BiResponse<MutableList<CalendarEntity>>() {
override fun onSuccess(data: MutableList<CalendarEntity>) {
val kaifuCalendar = this@ServersCalendarViewModel.kaifuCalendar
if (kaifuCalendar != null) {// 如果指定了选中的开服表日期,则自动唤起开服详情弹窗
val index = data.indexOfFirst {
it.year == kaifuCalendar.get(Calendar.YEAR)
&& it.month == kaifuCalendar.get(Calendar.MONTH) + 1
&& it.day == kaifuCalendar.get(Calendar.DATE)
}
if (index != -1) {
serversDetailLiveData.postValue(data[index])
}
this@ServersCalendarViewModel.kaifuCalendar = null
}
calendarLiveData.postValue(data)
}

View File

@ -1,58 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatDialogFragment
import androidx.fragment.app.activityViewModels
import androidx.viewpager.widget.ViewPager.LayoutParams
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.databinding.DialogWechatReserveSuccessBinding
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
/**
* 游戏订阅成功-未绑定微信弹窗
*/
class ServersCalendarWeChatSubscriptionSuccessDialog : AppCompatDialogFragment() {
private lateinit var viewBinding: DialogWechatReserveSuccessBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(BottomSheetDialogFragment.STYLE_NORMAL, R.style.DialogWindowTransparent)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val rootView = DialogWechatReserveSuccessBinding.inflate(inflater, container, false)
.also {
viewBinding = it
}.root
return rootView.apply {
layoutParams = ViewGroup.LayoutParams(300F.dip2px(), LayoutParams.WRAP_CONTENT)
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewBinding.closeBtn.setOnClickListener {
dismissAllowingStateLoss()
}
viewBinding.closeBtn.setOnClickListener {
dismissAllowingStateLoss()
}
viewBinding.titleIv.setImageResource(R.drawable.bg_servers_calendar_reserve_success)
viewBinding.openBtn.setOnClickListener {
it.context.startActivity(WebActivity.getBindWechatIntent(context))
dismissAllowingStateLoss()
}
viewBinding.contentTv.text = getString(R.string.servers_calendar_subscription_dialog_content)
}
}

View File

@ -3,18 +3,17 @@ package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.content.Context
import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.databinding.DialogServersCalendearDetailReportItemBinding
import com.gh.gamecenter.feature.entity.ServerCalendarEntity
import com.lightgame.adapter.BaseRecyclerAdapter
class ServersCalendarDetailReportAdapter(
class ServersDetailReportAdapter(
context: Context,
private val serverList: List<ServerCalendarEntity>
) : BaseRecyclerAdapter<ServersCalendarDetailReportAdapter.ServersCalendarDetailReportViewHolder>(context) {
private val serverList: MutableList<ServerCalendarEntity>
) : BaseRecyclerAdapter<ServersDetailReportViewHolder>(context) {
private val selectedPositions = mutableListOf<Int>()
@ -22,14 +21,14 @@ class ServersCalendarDetailReportAdapter(
selectedPositions.contains(index)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ServersCalendarDetailReportViewHolder {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ServersDetailReportViewHolder {
val view = mLayoutInflater.inflate(R.layout.dialog_servers_calendear_detail_report_item, parent, false)
return ServersCalendarDetailReportViewHolder(DialogServersCalendearDetailReportItemBinding.bind(view))
return ServersDetailReportViewHolder(DialogServersCalendearDetailReportItemBinding.bind(view))
}
override fun getItemCount(): Int = serverList.size
override fun onBindViewHolder(holder: ServersCalendarDetailReportViewHolder, position: Int) {
override fun onBindViewHolder(holder: ServersDetailReportViewHolder, position: Int) {
val serverCalendarEntity = serverList[position]
holder.bindItem(serverCalendarEntity)
@ -51,18 +50,4 @@ class ServersCalendarDetailReportAdapter(
notifyItemChanged(position)
}
}
class ServersCalendarDetailReportViewHolder(val binding: DialogServersCalendearDetailReportItemBinding) :
BaseRecyclerViewHolder<Any>(binding.root) {
fun bindItem(data: ServerCalendarEntity) {
binding.name.text = data.getNote()
binding.time.text = data.getFormatTime("HH:mm")
binding.remark.text = data.remark
binding.name.setTextColor(R.color.text_title.toColor(binding.root.context))
binding.time.setTextColor(R.color.text_title.toColor(binding.root.context))
binding.remark.setTextColor(R.color.text_title.toColor(binding.root.context))
}
}
}

View File

@ -0,0 +1,28 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.app.Activity
import android.graphics.Paint
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.DialogServersCalendearDetailItemBinding
import com.gh.gamecenter.databinding.DialogServersCalendearDetailReportItemBinding
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.MeEntity
import com.gh.gamecenter.feature.entity.ServerCalendarEntity
import com.gh.gamecenter.servers.patch.PatchKaifuActivity
import com.lightgame.utils.Utils
class ServersDetailReportViewHolder(val binding: DialogServersCalendearDetailReportItemBinding) :
BaseRecyclerViewHolder<Any>(binding.root) {
fun bindItem(data: ServerCalendarEntity) {
binding.name.text = data.getNote()
binding.time.text = data.getFormatTime("HH:mm")
binding.remark.text = data.remark
binding.name.setTextColor(R.color.text_title.toColor(binding.root.context))
binding.time.setTextColor(R.color.text_title.toColor(binding.root.context))
binding.remark.setTextColor(R.color.text_title.toColor(binding.root.context))
}
}

View File

@ -0,0 +1,47 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.app.Activity
import android.graphics.Paint
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.DialogServersCalendearDetailItemBinding
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.MeEntity
import com.gh.gamecenter.feature.entity.ServerCalendarEntity
import com.gh.gamecenter.servers.patch.PatchKaifuActivity
import com.lightgame.utils.Utils
class ServersDetailViewHolder(val binding: DialogServersCalendearDetailItemBinding) :
BaseRecyclerViewHolder<Any>(binding.root) {
fun bindItem(data: ServerCalendarEntity, meEntity: MeEntity?, gameEntity: GameEntity) {
binding.name.text = data.getNote()
binding.time.text = data.getFormatTime("HH:mm")
binding.remark.text = data.remark
binding.name.setTextColor(R.color.text_title.toColor(binding.root.context))
binding.time.setTextColor(R.color.text_title.toColor(binding.root.context))
binding.remark.setTextColor(R.color.text_title.toColor(binding.root.context))
if (meEntity?.isPartTime == true) {
binding.name.paint.flags = Paint.UNDERLINE_TEXT_FLAG
binding.name.paint.isAntiAlias = true
binding.name.setOnClickListener {
val context = binding.root.context
if ("删档内测" == data.type || "不删档内测" == data.type || "公测" == data.type) {
Utils.toast(context, "开测信息不可编辑");
} else {
(context as Activity).startActivityForResult(
PatchKaifuActivity.getIntent(
context,
data,
gameEntity.id
),
ServersCalendarActivity.GAME_DETAIL_PATCH_KAIFU_REQUEST
)
}
}
}
}
}

View File

@ -1,22 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.content.Context
import android.content.Intent
import com.gh.gamecenter.common.base.activity.ToolBarActivity
class ServersSubscribedGameListActivity : ToolBarActivity() {
override fun provideNormalIntent(): Intent {
return getTargetIntent(
this,
ServersSubscribedGameListActivity::class.java,
ServersSubscribedGameListFragment::class.java
)
}
companion object {
fun getIntent(context: Context): Intent {
return Intent(context, ServersSubscribedGameListActivity::class.java)
}
}
}

View File

@ -1,64 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.content.Context
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.layoutInflater
import com.gh.gamecenter.core.utils.MtaHelper
import com.gh.gamecenter.databinding.ItemServersSubscribedGameBinding
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.game.GameItemViewHolder
class ServersSubscribedGameListAdapter(context: Context) : ListAdapter<GameEntity>(context) {
private var onUnsubscribeClickListener: OnUnsubscribeClickListener? = null
fun setOnUnsubscribeClickListener(onUnsubscribeClickListener: OnUnsubscribeClickListener) {
this.onUnsubscribeClickListener = onUnsubscribeClickListener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ServersCalendarSubscriptionViewHolder(
ItemServersSubscribedGameBinding.inflate(
parent.layoutInflater,
parent,
false
)
)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
if (holder is ServersCalendarSubscriptionViewHolder) {
val game = mEntityList[position]
holder.binding.icon.displayGameIcon(game)
holder.binding.gameName.text = game.name
GameItemViewHolder.initGameSubtitleAndAdLabel(game, holder.binding.subtitle)
val exposureEvent = ExposureEvent.createEvent(
game,
listOf(ExposureSource("开服管理", "游戏订阅"))
)
holder.binding.subscribe.setOnClickListener {
onUnsubscribeClickListener?.onUnsubscribeClick(game, position)
}
holder.binding.root.setOnClickListener {
GameDetailActivity.startGameDetailActivity(mContext, game.id, "开服管理-游戏订阅", exposureEvent)
}
}
}
override fun getItemCount(): Int = mEntityList.size
class ServersCalendarSubscriptionViewHolder(val binding: ItemServersSubscribedGameBinding) : ViewHolder(binding.root)
interface OnUnsubscribeClickListener {
fun onUnsubscribeClick(gameEntity: GameEntity, position: Int)
}
}

View File

@ -1,65 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.os.Bundle
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.baselist.ListFragment
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.common.utils.NewFlatLogUtils
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.feature.entity.GameEntity
/**
* 开服订阅-开服表-游戏订阅
*/
class ServersSubscribedGameListFragment : ListFragment<GameEntity, ServersSubscribedGameListViewModel>(),
ServersSubscribedGameListAdapter.OnUnsubscribeClickListener {
private var adapter: ServersSubscribedGameListAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setNavigationTitle(getString(R.string.servers_calendar_subscribed_game_title))
}
override fun provideListViewModel(): ServersSubscribedGameListViewModel {
return viewModelProvider()
}
override fun provideListAdapter(): ListAdapter<GameEntity> {
return adapter ?: ServersSubscribedGameListAdapter(
requireContext()
).apply {
setOnUnsubscribeClickListener(this@ServersSubscribedGameListFragment)
adapter = this
}
}
override fun onUnsubscribeClick(gameEntity: GameEntity, position: Int) {
NewLogUtils.logLaunchServerSubscribeCancel(
gameId = gameEntity.id,
gameName = gameEntity.name ?: ""
)
SensorsBridge.trackLaunchServerSubscribeCancelClick(
gameId = gameEntity.id,
gameName = gameEntity.name ?: ""
)
DialogHelper.showDialog(
context = requireContext(),
title = getString(R.string.servers_subscribed_game_unsubscribe_dialog_title),
content = getString(R.string.servers_subscribed_game_unsubscribe_dialog_content),
confirmText = getString(R.string.servers_subscribed_game_unsubscribe_dialog_confirm),
cancelText = getString(R.string.servers_subscribed_game_unsubscribe_dialog_cancel),
confirmClickCallback = {
mListViewModel.unsubscribeServer(gameEntity.id)
}
)
}
override fun getItemDecoration(): RecyclerView.ItemDecoration? = null
}

View File

@ -1,57 +0,0 @@
package com.gh.gamecenter.gamedetail.fuli.kaifu
import android.annotation.SuppressLint
import android.app.Application
import com.gh.gamecenter.common.baselist.ListViewModel
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
class ServersSubscribedGameListViewModel(application: Application) : ListViewModel<GameEntity, GameEntity>(application) {
override fun provideDataObservable(page: Int): Observable<List<GameEntity>> {
return RetrofitManager.getInstance().newApi.serversSubscribedGameList
}
override fun mergeResultLiveData() {
mResultLiveData.addSource(mListLiveData) {
mResultLiveData.postValue(it)
}
}
override fun loadStatusControl(size: Int) {
when (size) {
0 -> {
mRetryParams = null
mLoadStatusLiveData.setValue(LoadStatus.INIT_EMPTY)
}
REQUEST_FAILURE_SIZE -> {
mRetryParams = mCurLoadParams
mLoadStatusLiveData.setValue(LoadStatus.INIT_FAILED)
}
else -> {
mRetryParams = null
mLoadStatusLiveData.setValue(LoadStatus.INIT_OVER)
}
}
}
@SuppressLint("CheckResult")
fun unsubscribeServer(gameId: String) {
RetrofitManager.getInstance().newApi
.unsubscribeServer(gameId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
val dataList = mListLiveData.value ?: return@subscribe
val index = dataList.indexOfFirst { it.id == gameId }
if (index != -1) {
dataList.removeAt(index)
mListLiveData.value = dataList
}
}, {})
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -205,10 +205,6 @@ class HaloPersonalBannerAdapter(context: Context) : BaseRecyclerAdapter<Recycler
mContext.startActivity(TeenagerModeActivity.getIntent(mContext))
}
"开服管理" -> {// 开服管理
DirectUtils.directToServersCalendarManagement(mContext, "我的光环-活动位")
}
else -> {
DirectUtils.directToLinkPage(mContext, it, "我的光环banner", "")
}

View File

@ -169,7 +169,6 @@ class HaloPersonalFragment : BaseLazyFragment() {
mStubBinding.loginMessageHint.visibility == View.VISIBLE,
"我的"
)
SensorsBridge.trackMessageCenterClick()
// 优先进入有数字提醒的消息tab其次是有红点提醒的游戏动态最后是没有提醒的消息tab
val defaultTabIndex = if ((mUnreadViewModel.messageUnreadCountLiveData.value?.message

View File

@ -199,10 +199,6 @@ class HaloPersonalFunctionAdapter(context: Context) : BaseRecyclerAdapter<Recycl
mContext.startActivity(GameArchiveListActivity.getIntent(mContext))
}
"开服管理" -> {// 开服管理
DirectUtils.directToServersCalendarManagement(mContext, "我的光环-更多功能")
}
else -> {
DirectUtils.directToLinkPage(mContext, it, "我的光环", "更多功能")
}

View File

@ -233,10 +233,6 @@ class HaloPersonalRecommendAdapter(val context: Context) : BaseRecyclerAdapter<R
mContext.startActivity(GameArchiveListActivity.getIntent(mContext))
}
"开服管理" -> {// 开服管理
DirectUtils.directToServersCalendarManagement(mContext, "我的光环-推荐位")
}
else -> {
DirectUtils.directToLinkPage(mContext, it, "我的光环", "推荐位")
}

View File

@ -34,6 +34,7 @@ import org.greenrobot.eventbus.EventBus
import retrofit2.HttpException
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.ArrayList
class HaloPersonalViewModel(application: Application) : AndroidViewModel(application) {
@ -70,7 +71,6 @@ class HaloPersonalViewModel(application: Application) : AndroidViewModel(applica
recommendData.postValue(it.addons)
}
}
"activity" -> activityData.postValue(it.addons)
"more_features" -> moreFeaturesData.postValue(it.addons)
}
@ -159,11 +159,9 @@ class HaloPersonalViewModel(application: Application) : AndroidViewModel(applica
"game" -> {
GameDetailActivity.startGameDetailActivity(context, data.link, entrance)
}
"news" -> {
context.startActivity(NewsDetailActivity.getIntentById(context, data.link, entrance))
}
"column" -> {
SubjectActivity.startSubjectActivity(
context,
@ -174,7 +172,6 @@ class HaloPersonalViewModel(application: Application) : AndroidViewModel(applica
entrance
)
}
else -> {
val linkEntity = LinkEntity()
linkEntity.type = data.type

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -35,7 +35,6 @@ class ArticleDetailRecyclerView @JvmOverloads constructor(
}
override fun onStartNestedScroll(child: View, target: View, axes: Int, type: Int): Boolean {
Log.d("ArticleDetailRv", "onStartNestedScroll->child: $child, $target, axes: $axes, type: $type")
val handleNestedScroll = (axes and View.SCROLL_AXIS_VERTICAL != 0)
if (handleNestedScroll) {
if (type == ViewCompat.TYPE_TOUCH) {
@ -47,12 +46,10 @@ class ArticleDetailRecyclerView @JvmOverloads constructor(
}
override fun onNestedScrollAccepted(child: View, target: View, axes: Int, type: Int) {
Log.d("ArticleDetailRv", "onNestedScrollAccepted->child: $child, target: $target, axes: $axes, type: $type")
onNestedScrollAccepted(child, target, axes)
}
override fun onStopNestedScroll(target: View, type: Int) {
Log.d("ArticleDetailRv", "onStopNestedScroll->target: $target, type: $type")
onStopNestedScroll(target)
if (type == ViewCompat.TYPE_NON_TOUCH) {
targetNestedScrollingView = null
@ -60,15 +57,12 @@ class ArticleDetailRecyclerView @JvmOverloads constructor(
}
override fun onNestedPreScroll(target: View, dx: Int, dy: Int, consumed: IntArray, type: Int) {
Log.d("ArticleDetailRv", "onNestedPreScroll->$target, dx: $dx, dy: $dy, consumed: $consumed, type: $type")
// 该回调发生在内层RecyclerView滚动之前
// 如果是向下滚动并且外层RecyclerView未滚动到底部由外层RecyclerView进行滚动
if (dy > 0 && canScrollVertically(1)) {
Log.d("ArticleDetailRv", "onNestedPreScroll1->$target, dx: $dx, dy: $dy, consumed: $consumed, type: $type")
scrollBy(0, dy)
consumed[1] = dy
} else {
Log.d("ArticleDetailRv", "onNestedPreScroll2->$target, dx: $dx, dy: $dy, consumed: $consumed, type: $type")
onNestedPreScroll(target, dx, dy, consumed)
}
}
@ -81,25 +75,12 @@ class ArticleDetailRecyclerView @JvmOverloads constructor(
dyUnconsumed: Int,
type: Int
) {
Log.d("ArticleDetailRv", "onNestedScroll->$target, dxConsumed: $dxConsumed, dyConsumed: $dyConsumed, dxUnconsumed: $dxUnconsumed, dyUnconsumed: $dyUnconsumed, type: $type")
// 该回调发生在内层RecyclerView滚动之后
// 如果是向上滚动并且内层RecyclerView滚动到顶部由外层RecyclerView进行滚动
if (dyConsumed == 0 && dyUnconsumed < 0) {
Log.d("ArticleDetailRv", "onNestedScroll1->$target, dxConsumed: $dxConsumed, dyConsumed: $dyConsumed, dxUnconsumed: $dxUnconsumed, dyUnconsumed: $dyUnconsumed, type: $type")
scrollBy(0, dyUnconsumed)
} else {
Log.d("ArticleDetailRv", "onNestedScroll2->$target, dxConsumed: $dxConsumed, dyConsumed: $dyConsumed, dxUnconsumed: $dxUnconsumed, dyUnconsumed: $dyUnconsumed, type: $type")
onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed)
}
}
override fun onNestedPreFling(target: View, velocityX: Float, velocityY: Float): Boolean {
Log.d("ArticleDetailRv", "onNestedPreFling->$target, velocityX: $velocityX, velocityY: $velocityY")
return super.onNestedPreFling(target, velocityX, velocityY)
}
override fun onNestedFling(target: View, velocityX: Float, velocityY: Float, consumed: Boolean): Boolean {
Log.d("ArticleDetailRv", "onNestedFling->$target, velocityX: $velocityX, velocityY: $velocityY, consumed:$consumed")
return super.onNestedFling(target, velocityX, velocityY, consumed)
}
}

View File

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

Some files were not shown because too many files have changed in this diff Show More